tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / misc / sprd_vpp / sprd_dither / vpp_dither_config.c
1 /*\r
2  * Copyright (C) 2014 Spreadtrum Communications Inc.\r
3  *\r
4  * This software is licensed under the terms of the GNU General Public\r
5  * License version 2, as published by the Free Software Foundation, and\r
6  * may be copied, distributed, and modified under those terms.\r
7  *\r
8  * This program is distributed in the hope that it will be useful,\r
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
11  * GNU General Public License for more details.\r
12  */\r
13 #include <linux/init.h>\r
14 #include <linux/module.h>\r
15 #include <linux/kernel.h>\r
16 #include <linux/miscdevice.h>\r
17 #include <linux/platform_device.h>\r
18 #include <linux/proc_fs.h>\r
19 #include <linux/slab.h>\r
20 #include <linux/delay.h>\r
21 #include <asm/uaccess.h>\r
22 #include <linux/math64.h>\r
23 #include <linux/types.h>\r
24 #include <linux/interrupt.h>\r
25 #include <linux/errno.h>\r
26 #include <linux/irq.h>\r
27 #include <linux/kthread.h>\r
28 #include <linux/io.h>\r
29 #include <linux/pid.h>\r
30 \r
31 #ifdef CONFIG_OF\r
32 #include <linux/of.h>\r
33 #include <linux/of_fdt.h>\r
34 #include <linux/of_irq.h>\r
35 #include <linux/of_address.h>\r
36 #include <linux/device.h>\r
37 #endif\r
38 \r
39 #include <mach/hardware.h>\r
40 #include <mach/arch_misc.h>\r
41 #include <mach/sci.h>\r
42 #include <video/ion_sprd.h>\r
43 \r
44 #ifdef CONFIG_HAS_EARLYSUSPEND_GSP\r
45 #include <linux/earlysuspend.h>\r
46 #endif\r
47 \r
48 #include <mach/hardware.h>\r
49 #include "vpp_dither_types.h"\r
50 #include "vpp_dither_config.h"\r
51 #include "vpp_dither_reg.h"\r
52 \r
53 \r
54 extern struct vpp_dither_device *vpp_dither_ctx;\r
55 \r
56 void VPP_Dither_Early_Init()\r
57 {\r
58         const unsigned char dither_path_table[DITHER_PATH_SIZE] =\r
59         {\r
60                 0x00,0x01,0x11,0x10,0x20,0x30,0x31,0x21,0x22,0x32,0x33,0x23,0x13,0x12,0x02,0x03,0x04,0x14,0x15,0x05,0x06,0x07,0x17,0x16,0x26,0x27,0x37,0x36,0x35,0x25,0x24,0x34,\r
61                 0x44,0x54,0x55,0x45,0x46,0x47,0x57,0x56,0x66,0x67,0x77,0x76,0x75,0x65,0x64,0x74,0x73,0x72,0x62,0x63,0x53,0x43,0x42,0x52,0x51,0x41,0x40,0x50,0x60,0x61,0x71,0x70,\r
62                 0x80,0x90,0x91,0x81,0x82,0x83,0x93,0x92,0xa2,0xa3,0xb3,0xb2,0xb1,0xa1,0xa0,0xb0,0xc0,0xc1,0xd1,0xd0,0xe0,0xf0,0xf1,0xe1,0xe2,0xf2,0xf3,0xe3,0xd3,0xd2,0xc2,0xc3,\r
63                 0xc4,0xc5,0xd5,0xd4,0xe4,0xf4,0xf5,0xe5,0xe6,0xf6,0xf7,0xe7,0xd7,0xd6,0xc6,0xc7,0xb7,0xa7,0xa6,0xb6,0xb5,0xb4,0xa4,0xa5,0x95,0x94,0x84,0x85,0x86,0x96,0x97,0x87,\r
64                 0x88,0x98,0x99,0x89,0x8a,0x8b,0x9b,0x9a,0xaa,0xab,0xbb,0xba,0xb9,0xa9,0xa8,0xb8,0xc8,0xc9,0xd9,0xd8,0xe8,0xf8,0xf9,0xe9,0xea,0xfa,0xfb,0xeb,0xdb,0xda,0xca,0xcb,\r
65                 0xcc,0xcd,0xdd,0xdc,0xec,0xfc,0xfd,0xed,0xee,0xfe,0xff,0xef,0xdf,0xde,0xce,0xcf,0xbf,0xaf,0xae,0xbe,0xbd,0xbc,0xac,0xad,0x9d,0x9c,0x8c,0x8d,0x8e,0x9e,0x9f,0x8f,\r
66                 0x7f,0x7e,0x6e,0x6f,0x5f,0x4f,0x4e,0x5e,0x5d,0x4d,0x4c,0x5c,0x6c,0x6d,0x7d,0x7c,0x7b,0x6d,0x6a,0x7a,0x79,0x78,0x68,0x69,0x59,0x58,0x48,0x49,0x4a,0x5a,0x5b,0x4b,\r
67                 0x3b,0x2b,0x2a,0x3a,0x39,0x38,0x28,0x29,0x19,0x18,0x08,0x09,0x0a,0x1a,0x1b,0x0b,0x0c,0x0d,0x1d,0x1c,0x2c,0x3c,0x3d,0x2d,0x2e,0x3e,0x3f,0x2f,0x1f,0x1e,0x0e,0x0f,\r
68                 0xff,0xef,0xee,0xfe,0xfd,0xfc,0xec,0xed,0xdd,0xdc,0xcc,0xcd,0xce,0xde,0xdf,0xcf,0xbf,0xbe,0xae,0xaf,0x9f,0x8f,0x8e,0x9e,0x9d,0x8d,0x8c,0x9c,0xac,0xad,0xbd,0xbc,\r
69                 0xbb,0xba,0xaa,0xab,0x9b,0x8b,0x8a,0x9a,0x99,0x89,0x88,0x98,0xa8,0xa9,0xb9,0xb8,0xc8,0xd8,0xd9,0xc9,0xca,0xcb,0xdb,0xda,0xea,0xeb,0xfb,0xfa,0xf9,0xe9,0xe8,0xf8,\r
70                 0xf7,0xf6,0xe6,0xe7,0xd7,0xc7,0xc6,0xd6,0xd5,0xc5,0xc4,0xd4,0xe4,0xe5,0xf5,0xf4,0xf3,0xe3,0xe2,0xf2,0xf1,0xf0,0xe0,0xe1,0xd1,0xd0,0xc0,0xc1,0xc2,0xd2,0xd3,0xc3,\r
71                 0xb3,0xa3,0xa2,0xb2,0xb1,0xb0,0xa0,0xa1,0x91,0x90,0x80,0x81,0x82,0x92,0x93,0x83,0x84,0x85,0x95,0x94,0xa4,0xb4,0xb5,0xa5,0xa6,0xb6,0xb7,0xa7,0x97,0x96,0x86,0x87,\r
72                 0x77,0x76,0x66,0x67,0x57,0x47,0x46,0x56,0x55,0x45,0x44,0x54,0x64,0x65,0x75,0x74,0x73,0x63,0x62,0x72,0x71,0x70,0x60,0x61,0x51,0x50,0x40,0x41,0x42,0x52,0x53,0x43,\r
73                 0x33,0x23,0x22,0x32,0x31,0x30,0x20,0x21,0x11,0x10,0x00,0x01,0x02,0x12,0x13,0x03,0x04,0x05,0x15,0x14,0x24,0x34,0x35,0x25,0x26,0x36,0x37,0x27,0x17,0x16,0x06,0x07,\r
74                 0x08,0x18,0x19,0x09,0x0a,0x0b,0x1b,0x1a,0x2a,0x2b,0x3b,0x3a,0x39,0x29,0x28,0x38,0x48,0x49,0x59,0x58,0x68,0x78,0x79,0x69,0x6a,0x7a,0x7b,0x6b,0x5b,0x5a,0x4a,0x4b,\r
75                 0x4c,0x4d,0x5d,0x5c,0x6c,0x7c,0x7d,0x6d,0x6e,0x7e,0x7f,0x6f,0x5f,0x5e,0x4e,0x4f,0x3f,0x2f,0x2e,0x3e,0x3d,0x3c,0x2c,0x2d,0x1d,0x1c,0x0c,0x0d,0x0e,0x1e,0x1f,0x0f,\r
76                 0xff,0xfe,0xee,0xef,0xdf,0xcf,0xce,0xde,0xdd,0xcd,0xcc,0xdc,0xec,0xed,0xfd,0xfc,0xfb,0xeb,0xea,0xfa,0xf9,0xf8,0xe8,0xe9,0xd9,0xd8,0xc8,0xc9,0xca,0xda,0xdb,0xcb,\r
77                 0xbb,0xab,0xaa,0xba,0xb9,0xb8,0xa8,0xa9,0x99,0x98,0x88,0x89,0x8a,0x9a,0x9b,0x8b,0x8c,0x8d,0x9d,0x9c,0xac,0xbc,0xbd,0xad,0xae,0xbe,0xbf,0xaf,0x9f,0x9e,0x8e,0x8f,\r
78                 0x7f,0x6f,0x6e,0x7e,0x7d,0x7c,0x6c,0x6d,0x5d,0x5c,0x4c,0x4d,0x4e,0x5e,0x5f,0x4f,0x3f,0x3e,0x2e,0x2f,0x1f,0x0f,0x0e,0x1e,0x1d,0x0d,0x0c,0x1c,0x2c,0x2d,0x3d,0x3c,\r
79                 0x3b,0x3a,0x2a,0x2b,0x1b,0x0b,0x0a,0x1a,0x19,0x09,0x08,0x18,0x28,0x29,0x39,0x38,0x48,0x58,0x59,0x49,0x4a,0x4b,0x5b,0x5a,0x6a,0x6b,0x7b,0x7a,0x79,0x69,0x68,0x78,\r
80                 0x77,0x67,0x66,0x76,0x75,0x74,0x64,0x65,0x55,0x54,0x44,0x45,0x46,0x56,0x57,0x47,0x37,0x36,0x26,0x27,0x17,0x07,0x06,0x16,0x15,0x05,0x04,0x14,0x24,0x25,0x35,0x34,\r
81                 0x33,0x32,0x22,0x23,0x13,0x03,0x02,0x12,0x11,0x01,0x00,0x10,0x20,0x21,0x31,0x30,0x40,0x50,0x51,0x41,0x42,0x43,0x53,0x52,0x62,0x63,0x73,0x72,0x71,0x61,0x60,0x70,\r
82                 0x80,0x81,0x91,0x90,0xa0,0xb0,0xb1,0xa1,0xa2,0xb2,0xb3,0xa3,0x93,0x92,0x82,0x83,0x84,0x94,0x95,0x85,0x86,0x87,0x97,0x96,0xa6,0xa7,0xb7,0xb6,0xb5,0xa5,0xa4,0xb4,\r
83                 0xc4,0xd4,0xd5,0xc5,0xc6,0xc7,0xd7,0xd6,0xe6,0xe7,0xf7,0xf6,0xf5,0xe5,0xe4,0xf4,0xf3,0xf2,0xe2,0xe3,0xd3,0xc3,0xc2,0xd2,0xd1,0xc1,0xc0,0xd0,0xe0,0xe1,0xf1,0xf0,\r
84                 0x00,0x10,0x11,0x01,0x02,0x03,0x13,0x12,0x22,0x23,0x33,0x32,0x31,0x21,0x20,0x30,0x40,0x41,0x51,0x50,0x60,0x70,0x71,0x61,0x62,0x72,0x73,0x63,0x53,0x52,0x42,0x43,\r
85                 0x44,0x45,0x55,0x54,0x64,0x74,0x75,0x65,0x66,0x76,0x77,0x67,0x57,0x56,0x46,0x47,0x37,0x27,0x26,0x36,0x35,0x34,0x24,0x25,0x15,0x14,0x04,0x05,0x06,0x16,0x17,0x07,\r
86                 0x08,0x09,0x19,0x18,0x28,0x38,0x39,0x29,0x2a,0x3a,0x3b,0x2b,0x1b,0x1a,0x0a,0x0b,0x0c,0x1c,0x1d,0x0d,0x0e,0x0f,0x1f,0x1e,0x2e,0x2f,0x3f,0x3e,0x3d,0x2d,0x2c,0x3c,\r
87                 0x4c,0x5c,0x5d,0x4d,0x4e,0x4f,0x5f,0x5e,0x6e,0x6f,0x7f,0x7e,0x7d,0x6d,0x6c,0x7c,0x7b,0x7a,0x6a,0x6b,0x5b,0x4b,0x4a,0x5a,0x59,0x49,0x48,0x58,0x68,0x69,0x79,0x78,\r
88                 0x88,0x89,0x99,0x98,0xa8,0xb8,0xb9,0xa9,0xaa,0xba,0xbb,0xab,0x9b,0x9a,0x8a,0x8b,0x8c,0x9c,0x9d,0x8d,0x8e,0x8f,0x9f,0x9e,0xae,0xaf,0xbf,0xbe,0xbd,0xad,0xac,0xbc,\r
89                 0xcc,0xdc,0xdd,0xcd,0xce,0xcf,0xdf,0xde,0xee,0xef,0xff,0xfe,0xfd,0xed,0xec,0xfc,0xfb,0xfa,0xea,0xeb,0xdb,0xcb,0xca,0xda,0xd9,0xc9,0xc8,0xd8,0xe8,0xe9,0xf9,0xf8,\r
90                 0xf7,0xe7,0xe6,0xf6,0xf5,0xf4,0xe4,0xe5,0xd5,0xd4,0xc4,0xc5,0xc6,0xd6,0xd7,0xc7,0xb7,0xb6,0xa6,0xa7,0x97,0x87,0x86,0x96,0x95,0x85,0x84,0x94,0xa4,0xa5,0xb5,0xb4,\r
91                 0xb3,0xb2,0xa2,0xa3,0x93,0x83,0x82,0x92,0x91,0x81,0x80,0x90,0xa0,0xa1,0xb1,0xb0,0xc0,0xd0,0xd1,0xc1,0xc2,0xc3,0xd3,0xd2,0xe2,0xe3,0xf3,0xf2,0xf1,0xe1,0xe0,0xf0\r
92         };\r
93 \r
94         sci_glb_set(REG_AON_APB_APB_EB0, BIT(25));      //enable MM module\r
95         sci_glb_set(REG_MM_AHB_AHB_EB, BIT(8));         //enable VPP module\r
96         sci_glb_set(REG_MM_AHB_GEN_CKG_CFG, BIT(9));    //enable VPP AXI\r
97 \r
98         TB_REG_SET(DITH_MEM_SW, 0x00);\r
99         memcpy(DITH_PATH_TABLE, &dither_path_table, DITHER_PATH_SIZE);\r
100 \r
101         TB_REG_SET(RB_COEF_CFG0, 0x0);\r
102         TB_REG_SET(RB_COEF_CFG1, 0x0);\r
103         TB_REG_SET(RB_COEF_CFG2, 0xC0C0B0B0);\r
104         TB_REG_SET(RB_COEF_CFG3, 0xE0D0D0C0);\r
105         TB_REG_SET(G_COEF_CFG0, 0x0);\r
106         TB_REG_SET(G_COEF_CFG1, 0x0);\r
107         TB_REG_SET(G_COEF_CFG2, 0xC0C0B0B0);\r
108         TB_REG_SET(G_COEF_CFG3, 0xE0D0D0C0);\r
109         TB_REG_SET(DITH_MEM_SW, 0x01);\r
110 \r
111         VPP_Dither_IRQENABLE_SET(0);\r
112         VPP_Dither_IRQSTATUS_Clear();\r
113         VPP_Dither_IRQENABLE_SET(1);\r
114 }\r
115 #if 0\r
116 int VPP_Dither_Clock_Init(struct vpp_dither_device *dev)\r
117 {\r
118         int ret = 0;\r
119         struct clk *clk_mm_i;\r
120         struct clk *clk_vpp_i;\r
121         struct clk *clk_vpp_parent_i;\r
122 \r
123 #ifdef CONFIG_OF\r
124         clk_mm_i = of_clk_get_by_name(dev->of_dev->of_node, "clk_mm_i");\r
125 #else\r
126         clk_mm_i = clk_get(NULL, "clk_mm_i");\r
127 #endif\r
128         if(IS_ERR(clk_mm_i))\r
129         {\r
130                 printk(KERN_ERR "[vpp_dither] can't get clock [%s]\n", "clk_mm_i");\r
131                 ret = -EINVAL;\r
132                 goto out;\r
133         }\r
134         else\r
135         {\r
136                 dev->clk_mm = clk_mm_i;\r
137                 printk(KERN_INFO "[vpp_dither] get clk_mm ok!\n");\r
138         }\r
139 \r
140         ret = clk_enable(dev->clk_mm);\r
141         if(ret)\r
142         {\r
143                 printk(KERN_ERR "[vpp_dither] mm_clk:clk_enable failed!\n");\r
144                 return ret;\r
145         }\r
146 \r
147 #ifdef CONFIG_OF\r
148         clk_vpp_i = of_clk_get_by_name(dev->of_dev->of_node, "clk_vpp");\r
149 #else\r
150         clk_vpp_i = clk_get(NULL, "clk_vpp");\r
151 #endif\r
152         if(IS_ERR(clk_vpp_i))\r
153         {\r
154                 printk(KERN_ERR "[vpp_dither] can't get clock [%s]\n", "clk_vpp");\r
155                 ret = -EINVAL;\r
156                 goto out;\r
157         }\r
158         else\r
159         {\r
160                 dev->clk_vpp = clk_vpp_i;\r
161                 printk(KERN_INFO "[vpp_dither] get clk_vpp ok!\n");\r
162         }\r
163 \r
164         clk_vpp_parent_i = clk_get(NULL, "clk_256m");\r
165         if(IS_ERR(clk_vpp_parent_i))\r
166         {\r
167                 printk(KERN_ERR "[vpp_dither] can't get clock [%s]\n", "clk_vpp_parent");\r
168                 ret = -EINVAL;\r
169                 goto out;\r
170         }\r
171         else\r
172         {\r
173                 dev->clk_vpp_parent = clk_vpp_parent_i;\r
174                 printk(KERN_INFO "[vpp_dither] get clk_vpp_parent ok!\n");\r
175         }\r
176 \r
177         ret = clk_set_parent(dev->clk_vpp, dev->clk_vpp_parent);\r
178         if(ret)\r
179         {\r
180                 printk(KERN_ERR "[vpp_dither] clk_set_parent failed!\n");\r
181                 ret = -EINVAL;\r
182                 goto out;\r
183         }\r
184 \r
185         return 0;\r
186 \r
187 out:\r
188         if(dev->clk_mm)\r
189                 clk_put(dev->clk_mm);\r
190 \r
191         if(dev->clk_vpp)\r
192                 clk_put(dev->clk_vpp);\r
193 \r
194         if(dev->clk_vpp_parent)\r
195                 clk_put(dev->clk_vpp_parent);\r
196 \r
197         return ret;\r
198 }\r
199 \r
200 void VPP_Dither_Clock_Enable(struct vpp_dither_device *dev)\r
201 {\r
202         int ret = 0;\r
203 \r
204         if(dev->clk_vpp == NULL)\r
205         {\r
206                 printk(KERN_ERR "[vpp_dither] clk not init yet!\n");\r
207                 return;\r
208         }\r
209 \r
210         ret = clk_prepare_enable(dev->clk_vpp);\r
211         if(ret)\r
212         {\r
213                 printk(KERN_ERR "[vpp_dither] enable clock fail!\n");\r
214                 return;\r
215         }\r
216 }\r
217 \r
218 void VPP_Dither_Clock_Disable(struct vpp_dither_device *dev)\r
219 {\r
220         if(dev->clk_vpp == NULL)\r
221         {\r
222                 printk(KERN_ERR "[vpp_dither] clk not init yet!\n");\r
223                 return;\r
224         }\r
225 \r
226         clk_disable_unprepare(dev->clk_vpp);\r
227 }\r
228 #endif\r
229 void VPP_Dither_Module_Enable()\r
230 {\r
231         unsigned int reg_value = 0;\r
232 \r
233         reg_value = TB_REG_GET(VPP_CFG);\r
234         reg_value |= 0x01;\r
235         TB_REG_SET(VPP_CFG, reg_value);\r
236 }\r
237 \r
238 void VPP_Dither_Module_Disable()\r
239 {\r
240         unsigned int reg_value = 0;\r
241 \r
242         reg_value = TB_REG_GET(VPP_CFG);\r
243         reg_value &= 0xFFFFFFFE;\r
244         TB_REG_SET(VPP_CFG, reg_value);\r
245 }\r
246 \r
247 void VPP_Dither_IRQSTATUS_Clear()\r
248 {\r
249         TB_REG_SET(VPP_INT_CLR, 0x01);\r
250 }\r
251 \r
252 void VPP_Dither_IRQENABLE_SET(unsigned char irq_flag)\r
253 {\r
254         unsigned int reg_value = 0;\r
255 \r
256         reg_value = TB_REG_GET(VPP_INT_MSK);\r
257 \r
258         if(irq_flag == 1)\r
259                 reg_value |= 0x01;\r
260         else\r
261                 reg_value &= 0xFFFFFFFE;\r
262 \r
263         TB_REG_SET(VPP_INT_MSK, reg_value);\r
264 }\r
265 \r
266 void VPP_Dither_Init(struct vpp_dither_device *dev)\r
267 {\r
268         //clock enable\r
269 //      VPP_Dither_Clock_Enable(dev);\r
270 \r
271         //module enable\r
272         VPP_Dither_Module_Enable();\r
273 \r
274         //irq enable\r
275 //      VPP_Dither_IRQENABLE_SET(0);\r
276 //      VPP_Dither_IRQSTATUS_Clear();\r
277 //      VPP_Dither_IRQENABLE_SET(1);\r
278 }\r
279 \r
280 void VPP_Dither_Deinit(struct vpp_dither_device *dev)\r
281 {\r
282         //module disable\r
283         VPP_Dither_Module_Disable();\r
284 \r
285         //irq disable\r
286 //      VPP_Dither_IRQENABLE_SET(0);\r
287 //      VPP_Dither_IRQSTATUS_Clear();\r
288 \r
289         //clock disable\r
290 //      VPP_Dither_Clock_Disable(dev);\r
291 }\r
292 \r
293 void VPP_Dither_Module_Reset()\r
294 {\r
295         sci_glb_set(REG_MM_AHB_AHB_RST, BIT(15));\r
296         udelay(10);\r
297         sci_glb_clr(REG_MM_AHB_AHB_RST, BIT(15));\r
298 }\r
299 \r
300 void VPP_Dither_Info_Config(struct fb_to_vpp_info *fb_info, struct vpp_dither_device *dev)\r
301 {\r
302         dev->reg_info.output_format = fb_info->output_format;   //RGB666\r
303         dev->reg_info.pixel_type = fb_info->pixel_type;                 //one pixel one word\r
304         dev->reg_info.input_format = fb_info->input_format;             //ARGB888\r
305         dev->reg_info.block_mod = 0;\r
306         dev->reg_info.img_width = fb_info->img_width;\r
307         dev->reg_info.img_height = fb_info->img_height;\r
308         dev->reg_info.src_addr = fb_info->buf_addr;\r
309         dev->reg_info.des_addr = fb_info->buf_addr;\r
310 }\r
311 \r
312 void VPP_Dither_CFG_Config(struct vpp_dither_device *dev)\r
313 {\r
314         unsigned int reg_value = 0;\r
315 \r
316         if(NULL == dev)\r
317         {\r
318                 printk(KERN_ERR "[vpp_dither] %s, dev is null!\n",__func__);\r
319                 return 0;\r
320         }\r
321 \r
322         if(dev->reg_info.output_format == 1)            //RGB666\r
323                 dev->reg_info.pixel_type = 1;                   //one pixel one word\r
324 \r
325         reg_value |= dev->reg_info.output_format << 0;\r
326         reg_value |= dev->reg_info.pixel_type << 1;\r
327         reg_value |= dev->reg_info.input_format << 2;\r
328         reg_value |= dev->reg_info.block_mod << 3;\r
329         TB_REG_SET(DITH_PATH_CFG, reg_value);\r
330 \r
331         reg_value = 0;\r
332         reg_value |= dev->reg_info.img_width << 0;\r
333         reg_value |= dev->reg_info.img_height << 16;\r
334         TB_REG_SET(DITH_IMG_SIZE, reg_value);\r
335 \r
336         reg_value = dev->reg_info.src_addr >> 3;\r
337         TB_REG_SET(DITH_SRC_ADDR, reg_value);\r
338 \r
339         reg_value = dev->reg_info.des_addr >> 3;\r
340         TB_REG_SET(DITH_DES_ADDR, reg_value);\r
341 }\r
342 \r
343 int VPP_Dither_Map(struct vpp_dither_device *dev)\r
344 {\r
345         return 0;\r
346 }\r
347 \r
348 int VPP_Dither_Unmap(struct vpp_dither_device *dev)\r
349 {\r
350         return 0;\r
351 }\r
352 \r
353 int irq_status_get()\r
354 {\r
355         unsigned int irq_value = 0;\r
356 \r
357         irq_value = TB_REG_GET(VPP_INT_STS);\r
358         if(irq_value & 0x01)\r
359                 return 1;\r
360         else\r
361                 return 0;\r
362 }\r
363 \r
364 irqreturn_t VPP_Dither_IRQ_Handler(int irq, void *dev_id)\r
365 {\r
366         struct vpp_dither_device *dev = dev_id;\r
367 \r
368         if(1 == irq_status_get())\r
369         {\r
370                 printk(KERN_INFO "[vpp_dither] %s enter!\n",__func__);\r
371 \r
372                 VPP_Dither_IRQENABLE_SET(0);\r
373                 VPP_Dither_IRQSTATUS_Clear();\r
374                 up(&dev->wait_interrupt_sem);\r
375 \r
376                 VPP_Dither_IRQENABLE_SET(1);\r
377                 return IRQ_HANDLED;\r
378         }\r
379         else\r
380                 return IRQ_NONE;\r
381 }\r
382 \r
383 void VPP_Dither_Trigger()\r
384 {\r
385         TB_REG_SET(DITH_PATH_START, 0x01);\r
386 }\r
387 \r
388 unsigned int Dither_WORKSTATUS_Get()\r
389 {\r
390         return TB_REG_GET(AXIM_STS);\r
391 }\r
392 \r
393 void VPP_Dither_Wait_Finish()\r
394 {\r
395         volatile unsigned int i = 0;\r
396         while(1)\r
397         {\r
398                 if(Dither_WORKSTATUS_Get() == 0)\r
399                         return;\r
400                 else\r
401                 {\r
402                         msleep(1);\r
403                         i++;\r
404                         if(i >= 30)\r
405                         {\r
406                                 printk(KERN_ERR "[vpp_dither] device is hane up!\n");\r
407                                 return;\r
408                         }\r
409                 }\r
410         }\r
411 }\r
412 \r
413 /*\r
414         FB Interface\r
415 */\r
416 int Do_Dither_Work(struct fb_to_vpp_info *fb_info)\r
417 {\r
418         int ret = 0;\r
419         struct vpp_dither_device *dev = vpp_dither_ctx;\r
420 \r
421         printk(KERN_INFO "[vpp_dither] %s enter!\n",__func__);\r
422 \r
423         if(0 == dev->is_device_free)    //device busy\r
424         {\r
425                 printk(KERN_ERR "[vpp_dither] %s, device is busy!\n",__func__);\r
426                 return ret;\r
427         }\r
428 \r
429         /*VPP_DITHER_SET_PARAM*/\r
430 \r
431         ret = down_interruptible(&dev->hw_resource_sem);\r
432         dev->is_device_free = 0;\r
433         if(ret)\r
434         {\r
435                 printk(KERN_ERR "[vpp_dither] %s,wait hw sema interrupt by signal,return",__func__);\r
436                 ret = -ERESTARTSYS;\r
437                 goto exit;\r
438         }\r
439 \r
440         VPP_Dither_Init(dev);\r
441         ret = VPP_Dither_Map(dev);\r
442         if(ret)\r
443         {\r
444                 printk(KERN_ERR "[vpp_dither] %s, mmu map fail!\n",__func__);\r
445                 ret = -EFAULT;\r
446                 goto exit2;\r
447         }\r
448         VPP_Dither_Info_Config(fb_info, dev);\r
449         VPP_Dither_CFG_Config(dev);\r
450 \r
451         /*VPP_DITHER_TRIGGER_RUN*/\r
452         VPP_Dither_Trigger();\r
453 \r
454         /*VPP_DITHER_WAIT_FINISH*/\r
455         ret = down_timeout(&dev->wait_interrupt_sem, msecs_to_jiffies(30));\r
456         if(ret == 0)\r
457         {\r
458                 printk(KERN_INFO "[vpp_dither] %s,wait done sema success!\n",__func__);\r
459         }\r
460         else if(ret == -ETIME)//timeout\r
461         {\r
462                 printk(KERN_ERR "[vpp_dither] %s,wait done sema timeout!\n",__func__);\r
463                 VPP_Dither_Module_Reset();\r
464                 VPP_Dither_Early_Init();\r
465                 ret = -EFAULT;\r
466                 goto exit2;\r
467         }\r
468         else if(ret)\r
469         {\r
470                 printk(KERN_ERR "[vpp_dither] %s,wait done sema interrupted by a signal!\n",__func__);\r
471                 VPP_Dither_Module_Reset();\r
472                 VPP_Dither_Early_Init();\r
473                 ret = -EFAULT;\r
474                 goto exit2;\r
475         }\r
476 \r
477 //      VPP_Dither_Wait_Finish();\r
478         VPP_Dither_Unmap(dev);\r
479         VPP_Dither_Deinit(dev);\r
480 \r
481         up(&dev->hw_resource_sem);\r
482         dev->is_device_free = 1;\r
483 \r
484         return ret;\r
485 \r
486 exit2:\r
487         VPP_Dither_Unmap(dev);\r
488         VPP_Dither_Deinit(dev);\r
489         sema_init(&dev->wait_interrupt_sem, 0);\r
490 exit1:\r
491         up(&dev->hw_resource_sem);\r
492 \r
493 exit:\r
494         return ret;\r
495 \r
496 }\r
497 \r
498 \r
499 \r
500 \r