import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / gpu / mt8127 / mali / mali / linux / mali_osk_low_level_mem.c
1 /*
2 * This confidential and proprietary software may be used only as
3 * authorised by a licensing agreement from ARM Limited
4 * (C) COPYRIGHT 2008-2013 ARM Limited
5 * ALL RIGHTS RESERVED
6 * The entire notice above must be reproduced on all authorised
7 * copies and copies may only be made to the extent permitted
8 * by a licensing agreement from ARM Limited.
9 */
10
11 /**
12 * @file mali_osk_low_level_mem.c
13 * Implementation of the OS abstraction layer for the kernel device driver
14 */
15
16 #include <asm/io.h>
17 #include <linux/ioport.h>
18 #include <linux/slab.h>
19
20 #include "mali_kernel_common.h"
21 #include "mali_osk.h"
22 #include "mali_ukk.h"
23
24 void _mali_osk_mem_barrier( void )
25 {
26 mb();
27 }
28
29 void _mali_osk_write_mem_barrier( void )
30 {
31 wmb();
32 }
33
34 mali_io_address _mali_osk_mem_mapioregion( u32 phys, u32 size, const char *description )
35 {
36 return (mali_io_address)ioremap_nocache(phys, size);
37 }
38
39 void _mali_osk_mem_unmapioregion( u32 phys, u32 size, mali_io_address virt )
40 {
41 iounmap((void*)virt);
42 }
43
44 _mali_osk_errcode_t inline _mali_osk_mem_reqregion( u32 phys, u32 size, const char *description )
45 {
46 #if MALI_LICENSE_IS_GPL
47 return _MALI_OSK_ERR_OK; /* GPL driver gets the mem region for the resources registered automatically */
48 #else
49 return ((NULL == request_mem_region(phys, size, description)) ? _MALI_OSK_ERR_NOMEM : _MALI_OSK_ERR_OK);
50 #endif
51 }
52
53 void inline _mali_osk_mem_unreqregion( u32 phys, u32 size )
54 {
55 #if !MALI_LICENSE_IS_GPL
56 release_mem_region(phys, size);
57 #endif
58 }
59
60 void inline _mali_osk_mem_iowrite32_relaxed( volatile mali_io_address addr, u32 offset, u32 val )
61 {
62 __raw_writel(cpu_to_le32(val),((u8*)addr) + offset);
63 }
64
65 u32 inline _mali_osk_mem_ioread32( volatile mali_io_address addr, u32 offset )
66 {
67 return ioread32(((u8*)addr) + offset);
68 }
69
70 void inline _mali_osk_mem_iowrite32( volatile mali_io_address addr, u32 offset, u32 val )
71 {
72 iowrite32(val, ((u8*)addr) + offset);
73 }
74
75 void _mali_osk_cache_flushall( void )
76 {
77 /** @note Cached memory is not currently supported in this implementation */
78 }
79
80 void _mali_osk_cache_ensure_uncached_range_flushed( void *uncached_mapping, u32 offset, u32 size )
81 {
82 _mali_osk_write_mem_barrier();
83 }
84
85 u32 _mali_osk_mem_write_safe(void *dest, const void *src, u32 size)
86 {
87 #define MALI_MEM_SAFE_COPY_BLOCK_SIZE 4096
88 u32 retval = 0;
89 void *temp_buf;
90
91 temp_buf = kmalloc(MALI_MEM_SAFE_COPY_BLOCK_SIZE, GFP_KERNEL);
92 if (NULL != temp_buf) {
93 u32 bytes_left_to_copy = size;
94 u32 i;
95 for (i = 0; i < size; i += MALI_MEM_SAFE_COPY_BLOCK_SIZE) {
96 u32 size_to_copy;
97 u32 size_copied;
98 u32 bytes_left;
99
100 if (bytes_left_to_copy > MALI_MEM_SAFE_COPY_BLOCK_SIZE) {
101 size_to_copy = MALI_MEM_SAFE_COPY_BLOCK_SIZE;
102 } else {
103 size_to_copy = bytes_left_to_copy;
104 }
105
106 bytes_left = copy_from_user(temp_buf, ((char*)src) + i, size_to_copy);
107 size_copied = size_to_copy - bytes_left;
108
109 bytes_left = copy_to_user(((char*)dest) + i, temp_buf, size_copied);
110 size_copied -= bytes_left;
111
112 bytes_left_to_copy -= size_copied;
113 retval += size_copied;
114
115 if (size_copied != size_to_copy) {
116 break; /* Early out, we was not able to copy this entire block */
117 }
118 }
119
120 kfree(temp_buf);
121 }
122
123 return retval;
124 }
125
126 _mali_osk_errcode_t _mali_ukk_mem_write_safe(_mali_uk_mem_write_safe_s *args)
127 {
128 MALI_DEBUG_ASSERT_POINTER(args);
129
130 if (NULL == args->ctx) {
131 return _MALI_OSK_ERR_INVALID_ARGS;
132 }
133
134 /* Return number of bytes actually copied */
135 args->size = _mali_osk_mem_write_safe(args->dest, args->src, args->size);
136 return _MALI_OSK_ERR_OK;
137 }