Merge remote-tracking branch 'origin/upstream/linux-linaro-lsk-v3.10-android' into...
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / lcdc / rk3188_lcdc.c
1 /*
2  * drivers/video/rockchip/lcdc/rk3188_lcdc.c
3  *
4  * Copyright (C) 2013 ROCKCHIP, Inc.
5  *Author:yxj<yxj@rock-chips.com>
6  *This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/errno.h>
20 #include <linux/string.h>
21 #include <linux/mm.h>
22 #include <linux/slab.h>
23 #include <linux/device.h>
24 #include <linux/delay.h>
25 #include <linux/init.h>
26 #include <linux/interrupt.h>
27 #include <linux/platform_device.h>
28 #include <linux/clk.h>
29 #include <asm/div64.h>
30 #include <asm/uaccess.h>
31 #include "../../../arch/arm/mach-rockchip/cpu.h"
32 #include "../../../arch/arm/mach-rockchip/iomap.h"
33 #include "../../../arch/arm/mach-rockchip/grf.h"
34
35 #include "rk3188_lcdc.h"
36
37 #if defined(CONFIG_HAS_EARLYSUSPEND)
38 #include <linux/earlysuspend.h>
39 #endif
40
41 static int dbg_thresd;
42 module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
43
44 #define DBG(level, x...) do {                   \
45         if (unlikely(dbg_thresd >= level))      \
46                 printk(KERN_INFO x); } while (0)
47
48 //#define WAIT_FOR_SYNC 1
49
50 static int rk3188_lcdc_get_id(u32 phy_base)
51 {
52         if (cpu_is_rk319x()) {
53                 if (phy_base == 0xffc40000)
54                         return 0;
55                 else if (phy_base == 0xffc50000)
56                         return 1;
57                 else
58                         return -EINVAL;
59         } else if (cpu_is_rk3188()) {
60                 if (phy_base == 0x1010c000)
61                         return 0;
62                 else if (phy_base == 0x1010e000)
63                         return 1;
64                 else
65                         return -EINVAL;
66         } else if (cpu_is_rk3026()) {
67                 if (phy_base == 0x1010e000)
68                         return 0;
69                 else if (phy_base == 0x01110000)
70                         return 1;
71                 else
72                         return -EINVAL;
73         } else {
74                 pr_err("un supported platform \n");
75                 return -EINVAL;
76         }
77
78 }
79
80 static int rk3188_lcdc_set_lut(struct rk_lcdc_driver *dev_drv)
81 {
82         int i = 0;
83         int __iomem *c;
84         int v;
85         struct lcdc_device *lcdc_dev = container_of(dev_drv,
86                                                            struct
87                                                            lcdc_device,
88                                                            driver);
89         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
90         lcdc_cfg_done(lcdc_dev);
91         mdelay(25);
92         for (i = 0; i < 256; i++) {
93                 v = dev_drv->cur_screen->dsp_lut[i];
94                 c = lcdc_dev->dsp_lut_addr_base + i;
95                 writel_relaxed(v, c);
96
97         }
98         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
99
100         return 0;
101
102 }
103
104 static int rk3188_lcdc_clk_enable(struct lcdc_device *lcdc_dev)
105 {
106
107         if (!lcdc_dev->clk_on) {
108                 clk_prepare_enable(lcdc_dev->hclk);
109                 clk_prepare_enable(lcdc_dev->dclk);
110                 clk_prepare_enable(lcdc_dev->aclk);
111                 //clk_enable(lcdc_dev->pd);
112                 spin_lock(&lcdc_dev->reg_lock);
113                 lcdc_dev->clk_on = 1;
114                 spin_unlock(&lcdc_dev->reg_lock);
115         }
116
117         return 0;
118 }
119
120 static int rk3188_lcdc_clk_disable(struct lcdc_device *lcdc_dev)
121 {
122         if (lcdc_dev->clk_on) {
123                 spin_lock(&lcdc_dev->reg_lock);
124                 lcdc_dev->clk_on = 0;
125                 spin_unlock(&lcdc_dev->reg_lock);
126                 mdelay(25);
127                 clk_disable_unprepare(lcdc_dev->dclk);
128                 clk_disable_unprepare(lcdc_dev->hclk);
129                 clk_disable_unprepare(lcdc_dev->aclk);
130                 //clk_disable(lcdc_dev->pd);
131         }
132
133         return 0;
134 }
135
136 static void rk3188_lcdc_reg_dump(struct lcdc_device *lcdc_dev)
137 {
138         int *cbase = (int *)lcdc_dev->regs;
139         int *regsbak = (int *)lcdc_dev->regsbak;
140         int i, j;
141
142         printk("back up reg:\n");
143         for (i = 0; i <= (0x90 >> 4); i++) {
144                 for (j = 0; j < 4; j++)
145                         printk("%08x  ", *(regsbak + i * 4 + j));
146                 printk("\n");
147         }
148
149         printk("lcdc reg:\n");
150         for (i = 0; i <= (0x90 >> 4); i++) {
151                 for (j = 0; j < 4; j++)
152                         printk("%08x  ", readl_relaxed(cbase + i * 4 + j));
153                 printk("\n");
154         }
155
156 }
157
158 static void rk3188_lcdc_read_reg_defalut_cfg(struct lcdc_device
159                                              *lcdc_dev)
160 {
161         int reg = 0;
162         u32 value = 0;
163         struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
164         struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
165
166         spin_lock(&lcdc_dev->reg_lock);
167         for (reg = 0; reg < REG_CFG_DONE; reg += 4) {
168                 value = lcdc_readl(lcdc_dev, reg);
169                 switch (reg) {
170                 case SYS_CTRL:
171                         lcdc_dev->standby = (value & m_LCDC_STANDBY) >> 17;
172                         win0->state = (value & m_WIN0_EN) >> 0;
173                         win1->state = (value & m_WIN1_EN) >> 1;
174                         if (lcdc_dev->id == 0)
175                                 lcdc_dev->atv_layer_cnt = win0->state;
176                         else
177                                 lcdc_dev->atv_layer_cnt = win1->state;
178                         win0->swap_rb = (value & m_WIN0_RB_SWAP) >> 15;
179                         win1->swap_rb = (value & m_WIN1_RB_SWAP) >> 19;
180                         win0->fmt_cfg = (value & m_WIN0_FORMAT) >> 3;
181                         win1->fmt_cfg = (value & m_WIN1_FORMAT) >> 6;
182                         break;
183                 case WIN0_SCL_FACTOR_YRGB:
184                         win0->scale_yrgb_x = (value >> 0) & 0xffff;
185                         win0->scale_yrgb_y = (value >> 16) & 0xffff;
186                         break;
187                 case WIN0_SCL_FACTOR_CBR:
188                         win0->scale_cbcr_x = (value >> 0) & 0xffff;
189                         win0->scale_cbcr_y = (value >> 16) & 0xffff;
190                         break;
191                 case WIN0_ACT_INFO:
192                         win0->xact = (((value >> 0) & 0x1fff) + 1);
193                         win0->yact = (((value >> 16) & 0x1fff) + 1);
194                         break;
195                 case WIN0_DSP_ST:
196                         win0->dsp_stx = (value >> 0) & 0xfff;
197                         win0->dsp_sty = (value >> 16) & 0xfff;
198                         break;
199                 case WIN0_DSP_INFO:
200                         win0->xsize = (((value >> 0) & 0x7ff) + 1);
201                         win0->ysize = (((value >> 16) & 0x7ff) + 1);
202                         break;
203                 case WIN_VIR:
204                         win0->vir_stride = (value >> 0) & 0x1fff;
205                         win1->vir_stride = (value) & 0x1fff0000;
206                         break;
207                 case WIN0_YRGB_MST0:
208                         win0->y_addr = value >> 0;
209                         break;
210                 case WIN0_CBR_MST0:
211                         win0->uv_addr = value >> 0;
212                         break;
213                 case WIN1_DSP_INFO:
214                         win1->xsize = (((value >> 0) & 0x7ff) + 1);
215                         win1->ysize = (((value >> 16) & 0x7ff) + 1);
216                         break;
217                 case WIN1_DSP_ST:
218                         win1->dsp_stx = (value >> 0) & 0xfff;
219                         win1->dsp_sty = (value >> 16) & 0xfff;
220                         break;
221                 case WIN1_MST:
222                         win1->y_addr = value >> 0;
223                         break;
224                 default:
225                         DBG(2, "%s:uncare reg\n", __func__);
226                         break;
227                 }
228         }
229         spin_unlock(&lcdc_dev->reg_lock);
230 }
231
232 /********do basic init*********/
233 static int rk3188_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
234 {
235         int v;
236         struct lcdc_device *lcdc_dev = container_of(dev_drv,
237                                                            struct
238                                                            lcdc_device,
239                                                            driver);
240
241         if (lcdc_dev->pre_init)
242                 return 0;
243
244         if (lcdc_dev->id == 0) {
245                 //lcdc_dev->pd  = clk_get(NULL,"pd_lcdc0");
246                 lcdc_dev->hclk = clk_get(NULL, "g_h_lcdc0");
247                 lcdc_dev->aclk = clk_get(NULL, "aclk_lcdc0");
248                 lcdc_dev->dclk = clk_get(NULL, "dclk_lcdc0");
249         } else if (lcdc_dev->id == 1) {
250                 //lcdc_dev->pd  = clk_get(NULL,"pd_lcdc1");
251                 lcdc_dev->hclk = clk_get(NULL, "g_h_lcdc1");
252                 lcdc_dev->aclk = clk_get(NULL, "aclk_lcdc1");
253                 lcdc_dev->dclk = clk_get(NULL, "dclk_lcdc1");
254         } else {
255                 dev_err(lcdc_dev->dev, "invalid lcdc device!\n");
256                 return -EINVAL;
257         }
258         if (IS_ERR(lcdc_dev->pd) || (IS_ERR(lcdc_dev->aclk)) ||
259             (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
260                 dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
261                         lcdc_dev->id);
262         }
263
264         /*uboot display has enabled lcdc in boot */
265         if (!support_uboot_display()) {
266                 rk_disp_pwr_enable(dev_drv);
267                 rk3188_lcdc_clk_enable(lcdc_dev);
268         } else {
269                 lcdc_dev->clk_on = 1;
270         }
271
272         rk3188_lcdc_read_reg_defalut_cfg(lcdc_dev);
273
274         if (lcdc_dev->id == 0) {
275                 if (lcdc_dev->pwr18 == true) {
276                         v = 0x40004000; /*bit14: 1,1.8v;0,3.3v*/
277                         writel_relaxed(v, RK_GRF_VIRT + RK3188_GRF_IO_CON4);
278                 } else {
279                         v = 0x40000000;
280                         writel_relaxed(v, RK_GRF_VIRT + RK3188_GRF_IO_CON4);
281                 }
282         }
283
284         if (lcdc_dev->id == 1) {
285                 if (lcdc_dev->pwr18 == true) {
286                         v = 0x80008000; /*bit14: 1,1.8v;0,3.3v*/
287                         writel_relaxed(v, RK_GRF_VIRT + RK3188_GRF_IO_CON4);
288                 } else {
289                         v = 0x80000000;
290                         writel_relaxed(v, RK_GRF_VIRT + RK3188_GRF_IO_CON4);
291                 }
292                 pinctrl_select_state(lcdc_dev->dev->pins->p,
293                                      lcdc_dev->dev->pins->default_state);
294         }
295
296         lcdc_set_bit(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN);
297         lcdc_cfg_done(lcdc_dev);
298         lcdc_dev->pre_init = true;
299
300         return 0;
301 }
302
303 static void rk3188_lcdc_deint(struct lcdc_device *lcdc_dev)
304 {
305         u32 mask, val;
306         spin_lock(&lcdc_dev->reg_lock);
307         if (likely(lcdc_dev->clk_on)) {
308                 lcdc_dev->clk_on = 0;
309                 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
310                              v_FS_INT_CLEAR(1));
311                 mask = m_HS_INT_EN | m_FS_INT_EN | m_LF_INT_EN |
312                         m_BUS_ERR_INT_EN;
313                 val = v_HS_INT_EN(0) | v_FS_INT_EN(0) |
314                         v_LF_INT_EN(0) | v_BUS_ERR_INT_EN(0);
315                 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
316                 lcdc_set_bit(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY);
317                 lcdc_cfg_done(lcdc_dev);
318                 spin_unlock(&lcdc_dev->reg_lock);
319         } else {
320                 spin_unlock(&lcdc_dev->reg_lock);
321         }
322         mdelay(1);
323
324 }
325
326 static int rk3188_lcdc_alpha_cfg(struct lcdc_device *lcdc_dev)
327 {
328         int win0_top = 0;
329         u32 mask, val;
330         enum data_format win0_format = lcdc_dev->driver.win[0]->format;
331         enum data_format win1_format = lcdc_dev->driver.win[1]->format;
332
333         int win0_alpha_en = ((win0_format == ARGB888)
334                              || (win0_format == ABGR888)) ? 1 : 0;
335         int win1_alpha_en = ((win1_format == ARGB888)
336                              || (win1_format == ABGR888)) ? 1 : 0;
337         u32 *_pv = (u32 *) lcdc_dev->regsbak;
338         _pv += (DSP_CTRL0 >> 2);
339         win0_top = ((*_pv) & (m_WIN0_TOP)) >> 8;
340
341         if (win0_top && (lcdc_dev->atv_layer_cnt >= 2) && (win0_alpha_en)) {
342                 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, m_WIN0_ALPHA_EN |
343                              m_WIN1_ALPHA_EN, v_WIN0_ALPHA_EN(1) |
344                              v_WIN1_ALPHA_EN(0));
345                 mask = m_WIN0_ALPHA_MODE | m_ALPHA_MODE_SEL0 | m_ALPHA_MODE_SEL1;
346                 val = v_WIN0_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1) | v_ALPHA_MODE_SEL1(0);
347                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
348         } else if ((!win0_top) && (lcdc_dev->atv_layer_cnt >= 2)
349                    && (win1_alpha_en)) {
350                 mask =  m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
351                 val = v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(1);
352                 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
353
354                 mask = m_WIN1_ALPHA_MODE | m_ALPHA_MODE_SEL0 | m_ALPHA_MODE_SEL1;
355                 val = v_WIN1_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1) | v_ALPHA_MODE_SEL1(0);
356                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
357         } else {
358                 mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
359                 val = v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(0);
360                 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
361         }
362
363         return 0;
364 }
365
366 static int rk3188_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
367 {
368         struct lcdc_device *lcdc_dev =
369             container_of(dev_drv, struct lcdc_device, driver);
370         struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
371         struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
372         int timeout;
373         unsigned long flags;
374
375         spin_lock(&lcdc_dev->reg_lock);
376         if (likely(lcdc_dev->clk_on)) {
377                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
378                              v_LCDC_STANDBY(lcdc_dev->standby));
379                 lcdc_msk_reg(lcdc_dev, SYS_CTRL,
380                              m_WIN0_EN | m_WIN1_EN | m_WIN0_RB_SWAP |
381                              m_WIN1_RB_SWAP,
382                              v_WIN0_EN(win0->state) | v_WIN1_EN(win1->state) |
383                              v_WIN0_RB_SWAP(win0->swap_rb) |
384                              v_WIN1_RB_SWAP(win1->swap_rb));
385                 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB,
386                             v_X_SCL_FACTOR(win0->scale_yrgb_x) |
387                             v_Y_SCL_FACTOR(win0->scale_yrgb_y));
388                 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR,
389                             v_X_SCL_FACTOR(win0->scale_cbcr_x) |
390                             v_Y_SCL_FACTOR(win0->scale_cbcr_y));
391                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_FORMAT, v_WIN0_FORMAT(win0->fmt_cfg));
392                 lcdc_writel(lcdc_dev, WIN0_ACT_INFO, v_ACT_WIDTH(win0->xact) |
393                             v_ACT_HEIGHT(win0->yact));
394                 lcdc_writel(lcdc_dev, WIN0_DSP_ST, v_DSP_STX(win0->dsp_stx) |
395                             v_DSP_STY(win0->dsp_sty));
396                 lcdc_writel(lcdc_dev, WIN0_DSP_INFO, v_DSP_WIDTH(win0->xsize) |
397                             v_DSP_HEIGHT(win0->ysize));
398                 lcdc_msk_reg(lcdc_dev, WIN_VIR, m_WIN0_VIR,
399                              v_WIN0_VIR_VAL(win0->vir_stride));
400                 lcdc_writel(lcdc_dev, WIN0_YRGB_MST0, win0->y_addr);
401                 lcdc_writel(lcdc_dev, WIN0_CBR_MST0, win0->uv_addr);
402                 lcdc_writel(lcdc_dev, WIN1_DSP_INFO, v_DSP_WIDTH(win1->xsize) |
403                             v_DSP_HEIGHT(win1->ysize));
404                 lcdc_writel(lcdc_dev, WIN1_DSP_ST, v_DSP_STX(win1->dsp_stx) |
405                             v_DSP_STY(win1->dsp_sty));
406                 lcdc_msk_reg(lcdc_dev, WIN_VIR, m_WIN1_VIR, win1->vir_stride);
407                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_FORMAT,
408                              v_WIN1_FORMAT(win1->fmt_cfg));
409                 lcdc_writel(lcdc_dev, WIN1_MST, win1->y_addr);
410                 rk3188_lcdc_alpha_cfg(lcdc_dev);
411                 lcdc_cfg_done(lcdc_dev);
412
413         }
414         spin_unlock(&lcdc_dev->reg_lock);
415         if (dev_drv->wait_fs) {
416                 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
417                 init_completion(&dev_drv->frame_done);
418                 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
419                 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
420                                                       msecs_to_jiffies
421                                                       (dev_drv->cur_screen->ft +
422                                                        5));
423                 if (!timeout && (!dev_drv->frame_done.done)) {
424                         dev_warn(lcdc_dev->dev, "wait for new frame start time out!\n");
425                         return -ETIMEDOUT;
426                 }
427         }
428         DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
429         return 0;
430
431 }
432
433 static int rk3188_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
434 {
435         memcpy((u8 *) lcdc_dev->regs, (u8 *) lcdc_dev->regsbak, 0x84);
436         return 0;
437 }
438
439
440 static int rk3188_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
441 {
442         int ret = -EINVAL;
443         int fps;
444         u16 face = 0;
445         struct lcdc_device *lcdc_dev =
446             container_of(dev_drv, struct lcdc_device, driver);
447         struct rk_screen *screen = dev_drv->cur_screen;
448         u16 right_margin = screen->mode.right_margin;
449         u16 left_margin = screen->mode.left_margin;
450         u16 lower_margin = screen->mode.lower_margin;
451         u16 upper_margin = screen->mode.upper_margin;
452         u16 x_res = screen->mode.xres;
453         u16 y_res = screen->mode.yres;
454         u32 mask, val;
455
456         spin_lock(&lcdc_dev->reg_lock);
457         if (likely(lcdc_dev->clk_on)) {
458                 switch (screen->face) {
459                 case OUT_P565:
460                         face = OUT_P565;
461                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
462                             m_DITHER_DOWN_SEL;
463                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
464                             v_DITHER_DOWN_SEL(1);
465                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
466                         break;
467                 case OUT_P666:
468                         face = OUT_P666;
469                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
470                             m_DITHER_DOWN_SEL;
471                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
472                             v_DITHER_DOWN_SEL(1);
473                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
474                         break;
475                 case OUT_D888_P565:
476                         face = OUT_P888;
477                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
478                             m_DITHER_DOWN_SEL;
479                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
480                             v_DITHER_DOWN_SEL(1);
481                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
482                         break;
483                 case OUT_D888_P666:
484                         face = OUT_P888;
485                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
486                             m_DITHER_DOWN_SEL;
487                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
488                             v_DITHER_DOWN_SEL(1);
489                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
490                         break;
491                 case OUT_P888:
492                         face = OUT_P888;
493                         mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
494                         val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
495                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
496                         break;
497                 default:
498                         dev_err(lcdc_dev->dev, "un supported interface!\n");
499                         break;
500                 }
501
502                 mask = m_DSP_OUT_FORMAT | m_HSYNC_POL | m_VSYNC_POL |
503                     m_DEN_POL | m_DCLK_POL;
504                 val = v_DSP_OUT_FORMAT(face) | v_HSYNC_POL(screen->pin_hsync) |
505                     v_VSYNC_POL(screen->pin_vsync) | v_DEN_POL(screen->pin_den) |
506                     v_DCLK_POL(screen->pin_dclk);
507                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
508
509                 mask = m_BG_COLOR | m_DSP_BG_SWAP | m_DSP_RB_SWAP |
510                     m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
511                     m_DSP_DUMMY_SWAP | m_BLANK_EN;
512                 val = v_BG_COLOR(0x000000) | v_DSP_BG_SWAP(screen->swap_gb) |
513                     v_DSP_RB_SWAP(screen->swap_rb) | v_DSP_RG_SWAP(screen->
514                                                                    swap_rg) |
515                     v_DSP_DELTA_SWAP(screen->
516                                      swap_delta) | v_DSP_DUMMY_SWAP(screen->
517                                                                     swap_dumy) |
518                     v_BLANK_EN(0) | v_BLACK_EN(0);
519                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
520                 val =
521                     v_HSYNC(screen->mode.hsync_len) | v_HORPRD(screen->mode.
522                                                                hsync_len +
523                                                                left_margin +
524                                                                x_res +
525                                                                right_margin);
526                 lcdc_writel(lcdc_dev, DSP_HTOTAL_HS_END, val);
527                 val = v_HAEP(screen->mode.hsync_len + left_margin + x_res) |
528                     v_HASP(screen->mode.hsync_len + left_margin);
529                 lcdc_writel(lcdc_dev, DSP_HACT_ST_END, val);
530
531                 val =
532                     v_VSYNC(screen->mode.vsync_len) | v_VERPRD(screen->mode.
533                                                                vsync_len +
534                                                                upper_margin +
535                                                                y_res +
536                                                                lower_margin);
537                 lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, val);
538
539                 val = v_VAEP(screen->mode.vsync_len + upper_margin + y_res) |
540                     v_VASP(screen->mode.vsync_len + screen->mode.upper_margin);
541                 lcdc_writel(lcdc_dev, DSP_VACT_ST_END, val);
542         }
543         spin_unlock(&lcdc_dev->reg_lock);
544
545         ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
546         if (ret)
547                 dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
548         lcdc_dev->pixclock =
549             div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
550         lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
551
552         fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
553         screen->ft = 1000 / fps;
554         dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
555                  lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
556
557         if (screen->init)
558                 screen->init();
559
560         return 0;
561 }
562
563 /*enable layer,open:1,enable;0 disable*/
564 static int win0_open(struct lcdc_device *lcdc_dev, bool open)
565 {
566         spin_lock(&lcdc_dev->reg_lock);
567         if (likely(lcdc_dev->clk_on)) {
568                 if (open) {
569                         if (!lcdc_dev->atv_layer_cnt) {
570                                 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
571                                 lcdc_dev->standby = 0;
572                         }
573                         lcdc_dev->atv_layer_cnt++;
574                 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
575                         lcdc_dev->atv_layer_cnt--;
576                 }
577                 lcdc_dev->driver.win[0]->state = open;
578                 if (!lcdc_dev->atv_layer_cnt) {
579                         dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
580                         lcdc_dev->standby = 1;
581                 }
582         }
583         spin_unlock(&lcdc_dev->reg_lock);
584
585         return 0;
586 }
587
588 static int win1_open(struct lcdc_device *lcdc_dev, bool open)
589 {
590         spin_lock(&lcdc_dev->reg_lock);
591         if (likely(lcdc_dev->clk_on)) {
592                 if (open) {
593                         if (!lcdc_dev->atv_layer_cnt) {
594                                 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
595                                 lcdc_dev->standby = 0;
596                         }
597                         lcdc_dev->atv_layer_cnt++;
598                 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
599                         lcdc_dev->atv_layer_cnt--;
600                 }
601                 lcdc_dev->driver.win[1]->state = open;
602
603                 /*if no layer used,disable lcdc*/
604                 if (!lcdc_dev->atv_layer_cnt) {
605                         dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
606                         lcdc_dev->standby = 1;
607                 }
608         }
609         spin_unlock(&lcdc_dev->reg_lock);
610
611         return 0;
612 }
613
614 static int rk3188_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
615                             bool open)
616 {
617         struct lcdc_device *lcdc_dev = container_of(dev_drv,
618                                         struct lcdc_device, driver);
619
620         /*enable clk,when first layer open */
621         if ((open) && (!lcdc_dev->atv_layer_cnt)) {
622                 rk3188_lcdc_pre_init(dev_drv);
623                 rk3188_lcdc_clk_enable(lcdc_dev);
624                 rk3188_lcdc_reg_restore(lcdc_dev);
625                 rk3188_load_screen(dev_drv, 1);
626                 spin_lock(&lcdc_dev->reg_lock);
627                 if (dev_drv->cur_screen->dsp_lut)
628                         rk3188_lcdc_set_lut(dev_drv);
629                 spin_unlock(&lcdc_dev->reg_lock);
630         }
631
632         if (win_id == 0)
633                 win0_open(lcdc_dev, open);
634         else if (win_id == 1)
635                 win1_open(lcdc_dev, open);
636         else
637                 dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
638
639         /*when all layer closed,disable clk */
640         if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
641                 lcdc_msk_reg(lcdc_dev, INT_STATUS,
642                              m_FS_INT_CLEAR, v_FS_INT_CLEAR(1));
643                 rk3188_lcdc_reg_update(dev_drv);
644                 rk3188_lcdc_clk_disable(lcdc_dev);
645         }
646
647         return 0;
648 }
649
650 static int win0_set_par(struct lcdc_device *lcdc_dev,
651                         struct rk_screen *screen, struct rk_lcdc_win *win)
652 {
653         u32 xact, yact, xvir, yvir, xpos, ypos;
654         u32 ScaleYrgbX = 0x1000;
655         u32 ScaleYrgbY = 0x1000;
656         u32 ScaleCbrX = 0x1000;
657         u32 ScaleCbrY = 0x1000;
658         u8 fmt_cfg = 0;
659         char fmt[9] = "NULL";
660         xact = win->xact;
661         yact = win->yact;
662         xvir = win->xvir;
663         yvir = win->yvir;
664         xpos = win->xpos + screen->mode.left_margin + screen->mode.hsync_len;
665         ypos = win->ypos + screen->mode.upper_margin + screen->mode.vsync_len;
666
667         ScaleYrgbX = CalScale(xact, win->xsize);
668         ScaleYrgbY = CalScale(yact, win->ysize);
669         switch (win->format) {
670         case ARGB888:
671         case XBGR888:
672         case ABGR888:
673                 fmt_cfg = 0;
674                 break;
675         case RGB888:
676                 fmt_cfg = 1;
677                 break;
678         case RGB565:
679                 fmt_cfg = 2;
680                 break;
681         case YUV422:
682                 fmt_cfg = 5;
683                 ScaleCbrX = CalScale((xact / 2), win->xsize);
684                 ScaleCbrY = CalScale(yact, win->ysize);
685                 break;
686         case YUV420:
687                 fmt_cfg = 4;
688                 ScaleCbrX = CalScale(xact / 2, win->xsize);
689                 ScaleCbrY = CalScale(yact / 2, win->ysize);
690                 break;
691         case YUV444:
692                 fmt_cfg = 6;
693                 ScaleCbrX = CalScale(xact, win->xsize);
694                 ScaleCbrY = CalScale(yact, win->ysize);
695                 break;
696         default:
697                 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
698                         __func__);
699                 break;
700         }
701
702         DBG(1, "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
703                 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
704                 __func__, get_format_string(win->format, fmt), xact,
705                 yact, win->xsize, win->ysize, xvir, yvir, xpos, ypos);
706
707         spin_lock(&lcdc_dev->reg_lock);
708         if (likely(lcdc_dev->clk_on)) {
709                 win->scale_yrgb_x = ScaleYrgbX;
710                 win->scale_yrgb_y = ScaleYrgbY;
711                 win->scale_cbcr_x = ScaleCbrX;
712                 win->scale_cbcr_y = ScaleCbrY;
713                 win->fmt_cfg = fmt_cfg;
714                 win->dsp_stx = xpos;
715                 win->dsp_sty = ypos;
716                 switch (win->format) {
717                 case XBGR888:
718                 case ABGR888:
719                         win->vir_stride = v_ARGB888_VIRWIDTH(xvir);
720                         win->swap_rb = 1;
721                         break;
722                 case ARGB888:
723                         win->vir_stride = v_ARGB888_VIRWIDTH(xvir);
724                         win->swap_rb = 0;
725                         break;
726                 case RGB888:
727                         win->vir_stride = v_RGB888_VIRWIDTH(xvir);
728                         win->swap_rb = 0;
729                         break;
730                 case RGB565:
731                         win->vir_stride = v_RGB565_VIRWIDTH(xvir);
732                         win->swap_rb = 0;
733                         break;
734                 case YUV422:
735                 case YUV420:
736                 case YUV444:
737                         win->vir_stride = v_YUV_VIRWIDTH(xvir);
738                         win->swap_rb = 0;
739                         break;
740                 default:
741                         dev_err(lcdc_dev->driver.dev,
742                                 "%s:un supported format!\n", __func__);
743                         break;
744                 }
745
746         }
747         spin_unlock(&lcdc_dev->reg_lock);
748
749         return 0;
750
751 }
752
753 static int win1_set_par(struct lcdc_device *lcdc_dev,
754                         struct rk_screen *screen, struct rk_lcdc_win *win)
755 {
756         u32 xact, yact, xvir, yvir, xpos, ypos;
757         u8 fmt_cfg;
758         char fmt[9] = "NULL";
759         xact = win->xact;
760         yact = win->yact;
761         xvir = win->xvir;
762         yvir = win->yvir;
763         xpos = win->xpos + screen->mode.left_margin + screen->mode.hsync_len;
764         ypos = win->ypos + screen->mode.upper_margin + screen->mode.vsync_len;
765
766         DBG(1, "lcdc%d>>%s>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
767                 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
768                 __func__, get_format_string(win->format, fmt), xact, yact,
769                 win->xsize, win->ysize, xvir, yvir, xpos, ypos);
770
771         spin_lock(&lcdc_dev->reg_lock);
772         if (likely(lcdc_dev->clk_on)) {
773                 win->dsp_stx = xpos;
774                 win->dsp_sty = ypos;
775                 switch (win->format) {
776                 case XBGR888:
777                 case ABGR888:
778                         fmt_cfg = 0;
779                         win->vir_stride = v_WIN1_ARGB888_VIRWIDTH(xvir);
780                         win->swap_rb = 1;
781                         break;
782                 case ARGB888:
783                         fmt_cfg = 0;
784                         win->vir_stride = v_WIN1_ARGB888_VIRWIDTH(xvir);
785                         win->swap_rb = 0;
786
787                         break;
788                 case RGB888:
789                         fmt_cfg = 1;
790                         win->vir_stride = v_WIN1_RGB888_VIRWIDTH(xvir);
791                         win->swap_rb = 0;
792                         break;
793                 case RGB565:
794                         fmt_cfg = 2;
795                         win->vir_stride = v_WIN1_RGB565_VIRWIDTH(xvir);
796                         win->swap_rb = 0;
797                         break;
798                 default:
799                         dev_err(lcdc_dev->driver.dev,
800                                 "%s:un supported format!\n", __func__);
801                         break;
802                 }
803                 win->fmt_cfg = fmt_cfg;
804
805         }
806         spin_unlock(&lcdc_dev->reg_lock);
807
808         return 0;
809 }
810
811 static int rk3188_lcdc_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
812 {
813         struct lcdc_device *lcdc_dev =
814             container_of(dev_drv, struct lcdc_device, driver);
815         struct rk_lcdc_win *win = NULL;
816         struct rk_screen *screen = dev_drv->cur_screen;
817
818         if (!screen) {
819                 dev_err(dev_drv->dev, "screen is null!\n");
820                 return -ENOENT;
821         }
822         if (win_id == 0) {
823                 win = dev_drv->win[0];
824                 win0_set_par(lcdc_dev, screen, win);
825         } else if (win_id == 1) {
826                 win = dev_drv->win[1];
827                 win1_set_par(lcdc_dev, screen, win);
828         } else {
829                 dev_err(dev_drv->dev, "unsupported win number:%d\n", win_id);
830                 return -EINVAL;
831         }
832
833         return 0;
834 }
835
836 static int win0_display(struct lcdc_device *lcdc_dev,
837                         struct rk_lcdc_win *win)
838 {
839         u32 y_addr;
840         u32 uv_addr;
841         y_addr = win->smem_start + win->y_offset;
842         uv_addr = win->cbr_start + win->c_offset;
843         DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x\n",
844             lcdc_dev->id, __func__, y_addr, uv_addr);
845
846         spin_lock(&lcdc_dev->reg_lock);
847         if (likely(lcdc_dev->clk_on)) {
848                 win->y_addr = y_addr;
849                 win->uv_addr = uv_addr;
850         }
851         spin_unlock(&lcdc_dev->reg_lock);
852
853         return 0;
854
855 }
856
857 static int win1_display(struct lcdc_device *lcdc_dev,
858                         struct rk_lcdc_win *win)
859 {
860         u32 y_addr;
861         u32 uv_addr;
862         y_addr = win->smem_start + win->y_offset;
863         uv_addr = win->cbr_start + win->c_offset;
864         DBG(2, "lcdc%d>>%s>>y_addr:0x%x>>uv_addr:0x%x\n",
865             lcdc_dev->id, __func__, y_addr, uv_addr);
866
867         spin_lock(&lcdc_dev->reg_lock);
868         if (likely(lcdc_dev->clk_on))
869                 win->y_addr = y_addr;
870         spin_unlock(&lcdc_dev->reg_lock);
871
872         return 0;
873 }
874
875 static int rk3188_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
876 {
877         struct lcdc_device *lcdc_dev = container_of(dev_drv,
878                                 struct lcdc_device, driver);
879         struct rk_lcdc_win *win = NULL;
880         struct rk_screen *screen = dev_drv->cur_screen;
881         u32 mask, val;
882 #if defined(WAIT_FOR_SYNC)
883         int timeout;
884         unsigned long flags;
885 #endif
886         if (!screen) {
887                 dev_err(dev_drv->dev, "screen is null!\n");
888                 return -ENOENT;
889         }
890         if (win_id == 0) {
891                 win = dev_drv->win[0];
892                 win0_display(lcdc_dev, win);
893         } else if (win_id == 1) {
894                 win = dev_drv->win[1];
895                 win1_display(lcdc_dev, win);
896         } else {
897                 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
898                 return -EINVAL;
899         }
900
901         /*this is the first frame of the system ,enable frame start interrupt */
902         if ((dev_drv->first_frame)) {
903                 dev_drv->first_frame = 0;
904                 mask = m_HS_INT_CLEAR | m_HS_INT_EN | m_FS_INT_CLEAR |
905                     m_FS_INT_EN | m_LF_INT_EN | m_LF_INT_CLEAR |
906                     m_LF_INT_NUM | m_BUS_ERR_INT_CLEAR | m_BUS_ERR_INT_EN;
907                 val = v_FS_INT_CLEAR(1) | v_FS_INT_EN(1) | v_HS_INT_CLEAR(1) |
908                     v_HS_INT_EN(0) | v_LF_INT_CLEAR(1) | v_LF_INT_EN(1) |
909                     v_LF_INT_NUM(screen->mode.vsync_len + screen->mode.upper_margin +
910                     screen->mode.yres -1);
911                 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
912                 lcdc_cfg_done(lcdc_dev);
913         }
914 #if defined(WAIT_FOR_SYNC)
915         spin_lock_irqsave(&dev_drv->cpl_lock, flags);
916         init_completion(&dev_drv->frame_done);
917         spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
918         timeout = wait_for_completion_timeout(&dev_drv->frame_done,
919                                               msecs_to_jiffies(dev_drv->
920                                                                cur_screen->ft +
921                                                                5));
922         if (!timeout && (!dev_drv->frame_done.done)) {
923                 dev_info(dev_drv->dev, "wait for new frame start time out!\n");
924                 return -ETIMEDOUT;
925         }
926 #endif
927         return 0;
928 }
929
930 static int rk3188_lcdc_blank(struct rk_lcdc_driver *dev_drv,
931                              int win_id, int blank_mode)
932 {
933         struct lcdc_device *lcdc_dev =
934             container_of(dev_drv, struct lcdc_device, driver);
935
936         spin_lock(&lcdc_dev->reg_lock);
937         if (likely(lcdc_dev->clk_on)) {
938                 switch (blank_mode) {
939                 case FB_BLANK_UNBLANK:
940                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN,
941                                      v_BLANK_EN(0));
942                         break;
943                 case FB_BLANK_NORMAL:
944                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN,
945                                      v_BLANK_EN(1));
946                         break;
947                 default:
948                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN,
949                                      v_BLANK_EN(1));
950                         break;
951                 }
952                 lcdc_cfg_done(lcdc_dev);
953
954         }
955         spin_unlock(&lcdc_dev->reg_lock);
956
957         dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
958
959         return 0;
960 }
961
962 static int rk3188_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
963                              unsigned long arg, int win_id)
964 {
965         struct lcdc_device *lcdc_dev = container_of(dev_drv,
966                                                            struct
967                                                            lcdc_device,
968                                                            driver);
969         u32 panel_size[2];
970         void __user *argp = (void __user *)arg;
971         struct color_key_cfg clr_key_cfg;
972
973         switch (cmd) {
974         case RK_FBIOGET_PANEL_SIZE:
975                 panel_size[0] = lcdc_dev->screen->mode.xres;
976                 panel_size[1] = lcdc_dev->screen->mode.yres;
977                 if (copy_to_user(argp, panel_size, 8))
978                         return -EFAULT;
979                 break;
980         case RK_FBIOPUT_COLOR_KEY_CFG:
981                 if (copy_from_user(&clr_key_cfg, argp,
982                                    sizeof(struct color_key_cfg)))
983                         return -EFAULT;
984                 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
985                             clr_key_cfg.win0_color_key_cfg);
986                 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
987                             clr_key_cfg.win1_color_key_cfg);
988                 break;
989
990         default:
991                 break;
992         }
993         return 0;
994 }
995
996 static int rk3188_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
997 {
998
999         struct lcdc_device *lcdc_dev =
1000             container_of(dev_drv, struct lcdc_device, driver);
1001
1002         if (dev_drv->screen0->standby)
1003                 dev_drv->screen0->standby(1);
1004         if (dev_drv->screen_ctr_info->io_disable)
1005                 dev_drv->screen_ctr_info->io_disable();
1006
1007         spin_lock(&lcdc_dev->reg_lock);
1008         if (likely(lcdc_dev->clk_on)) {
1009                 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
1010                              v_FS_INT_CLEAR(1));
1011                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1012                              v_DSP_OUT_ZERO(1));
1013                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1014                              v_LCDC_STANDBY(1));
1015                 lcdc_cfg_done(lcdc_dev);
1016                 spin_unlock(&lcdc_dev->reg_lock);
1017         } else {
1018                 spin_unlock(&lcdc_dev->reg_lock);
1019                 return 0;
1020         }
1021         rk3188_lcdc_clk_disable(lcdc_dev);
1022 #if defined(CONFIG_ARCH_RK3026)
1023         int gpio_dclk = iomux_mode_to_gpio(LCDC0_DCLK);
1024         int ret = gpio_request(gpio_dclk, NULL);
1025         if (unlikely(ret < 0)) {
1026                 dev_info(dev_drv->dev, "Failed to request gpio:lcdc dclk\n");
1027                 return ret;
1028         }
1029         gpio_direction_output(gpio_dclk, GPIO_LOW);
1030 #endif
1031         return 0;
1032 }
1033
1034 static int rk3188_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
1035 {
1036         struct lcdc_device *lcdc_dev =
1037             container_of(dev_drv, struct lcdc_device, driver);
1038         int i = 0;
1039         int __iomem *c;
1040         int v;
1041 #if defined(CONFIG_ARCH_RK3026)
1042         int gpio_dclk = iomux_mode_to_gpio(LCDC0_DCLK);
1043         gpio_free(gpio_dclk);
1044         iomux_set(LCDC0_DCLK);
1045 #endif
1046         if (dev_drv->screen_ctr_info->io_enable)
1047                 dev_drv->screen_ctr_info->io_enable();
1048
1049         if (lcdc_dev->atv_layer_cnt) {
1050                 rk3188_lcdc_clk_enable(lcdc_dev);
1051                 rk3188_lcdc_reg_restore(lcdc_dev);
1052
1053                 spin_lock(&lcdc_dev->reg_lock);
1054                 if (dev_drv->cur_screen->dsp_lut) {
1055                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN,
1056                                      v_DSP_LUT_EN(0));
1057                         lcdc_cfg_done(lcdc_dev);
1058                         mdelay(25);
1059                         for (i = 0; i < 256; i++) {
1060                                 v = dev_drv->cur_screen->dsp_lut[i];
1061                                 c = lcdc_dev->dsp_lut_addr_base + i;
1062                                 writel_relaxed(v, c);
1063                         }
1064                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN,
1065                                      v_DSP_LUT_EN(1));
1066                 }
1067
1068                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1069                              v_DSP_OUT_ZERO(0));
1070                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1071                              v_LCDC_STANDBY(0));
1072                 lcdc_cfg_done(lcdc_dev);
1073
1074                 spin_unlock(&lcdc_dev->reg_lock);
1075         }
1076
1077         if (dev_drv->screen0->standby)
1078                 dev_drv->screen0->standby(0);
1079
1080         return 0;
1081 }
1082
1083 static int rk3188_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv, int win_id)
1084 {
1085         return 0;
1086 }
1087
1088 static int rk3188_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
1089                                bool set)
1090 {
1091         struct lcdc_device *lcdc_dev =
1092             container_of(dev_drv, struct lcdc_device, driver);
1093         int ovl;
1094         spin_lock(&lcdc_dev->reg_lock);
1095         if (lcdc_dev->clk_on) {
1096                 if (set) {
1097                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_TOP,
1098                                      v_WIN0_TOP(swap));
1099                         ovl = swap;
1100                 } else {
1101                         ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
1102                 }
1103         } else {
1104                 ovl = -EPERM;
1105         }
1106         spin_unlock(&lcdc_dev->reg_lock);
1107
1108         return ovl;
1109 }
1110
1111 static ssize_t rk3188_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
1112                                          char *buf, int win_id)
1113 {
1114         struct lcdc_device *lcdc_dev = container_of(dev_drv,
1115                                                            struct
1116                                                            lcdc_device,
1117                                                            driver);
1118
1119         char format_w0[9] = "NULL";
1120         char format_w1[9] = "NULL";
1121         char status_w0[9] = "NULL";
1122         char status_w1[9] = "NULL";
1123         u32 fmt_id, act_info, dsp_info, dsp_st, factor;
1124         u16 xvir_w0, x_act_w0, y_act_w0, x_dsp_w0, y_dsp_w0;
1125         u16 x_st_w0, y_st_w0, x_factor, y_factor;
1126         u16 xvir_w1, x_dsp_w1, y_dsp_w1, x_st_w1, y_st_w1;
1127         u16 x_scale, y_scale, ovl;
1128         spin_lock(&lcdc_dev->reg_lock);
1129         if (lcdc_dev->clk_on) {
1130                 fmt_id = lcdc_readl(lcdc_dev, SYS_CTRL);
1131                 ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
1132                 switch ((fmt_id & m_WIN0_FORMAT) >> 3) {
1133                 case 0:
1134                         strcpy(format_w0, "ARGB888");
1135                         break;
1136                 case 1:
1137                         strcpy(format_w0, "RGB888");
1138                         break;
1139                 case 2:
1140                         strcpy(format_w0, "RGB565");
1141                         break;
1142                 case 4:
1143                         strcpy(format_w0, "YCbCr420");
1144                         break;
1145                 case 5:
1146                         strcpy(format_w0, "YCbCr422");
1147                         break;
1148                 case 6:
1149                         strcpy(format_w0, "YCbCr444");
1150                         break;
1151                 default:
1152                         strcpy(format_w0, "invalid\n");
1153                         break;
1154                 }
1155
1156                 switch ((fmt_id & m_WIN1_FORMAT) >> 6) {
1157                 case 0:
1158                         strcpy(format_w1, "ARGB888");
1159                         break;
1160                 case 1:
1161                         strcpy(format_w1, "RGB888");
1162                         break;
1163                 case 2:
1164                         strcpy(format_w1, "RGB565");
1165                         break;
1166                 case 4:
1167                         strcpy(format_w1, "8bpp");
1168                         break;
1169                 case 5:
1170                         strcpy(format_w1, "4bpp");
1171                         break;
1172                 case 6:
1173                         strcpy(format_w1, "2bpp");
1174                         break;
1175                 case 7:
1176                         strcpy(format_w1, "1bpp");
1177                         break;
1178                 default:
1179                         strcpy(format_w1, "invalid\n");
1180                         break;
1181                 }
1182
1183                 if (fmt_id & m_WIN0_EN)
1184                         strcpy(status_w0, "enabled");
1185                 else
1186                         strcpy(status_w0, "disabled");
1187
1188                 if ((fmt_id & m_WIN1_EN) >> 1)
1189                         strcpy(status_w1, "enabled");
1190                 else
1191                         strcpy(status_w1, "disabled");
1192
1193                 xvir_w0 = lcdc_readl(lcdc_dev, WIN_VIR) & 0x1fff;
1194                 act_info = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
1195                 dsp_info = lcdc_readl(lcdc_dev, WIN0_DSP_INFO);
1196                 dsp_st = lcdc_readl(lcdc_dev, WIN0_DSP_ST);
1197                 factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_YRGB);
1198                 x_act_w0 = (act_info & 0x1fff) + 1;
1199                 y_act_w0 = ((act_info >> 16) & 0x1fff) + 1;
1200                 x_dsp_w0 = (dsp_info & 0x7ff) + 1;
1201                 y_dsp_w0 = ((dsp_info >> 16) & 0x7ff) + 1;
1202                 x_st_w0 = dsp_st & 0xffff;
1203                 y_st_w0 = dsp_st >> 16;
1204                 x_factor = factor & 0xffff;
1205                 y_factor = factor >> 16;
1206                 x_scale = 4096 * 100 / x_factor;
1207                 y_scale = 4096 * 100 / y_factor;
1208                 xvir_w1 = (lcdc_readl(lcdc_dev, WIN_VIR) >> 16) & 0x1fff;
1209                 dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO);
1210                 dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST);
1211                 x_dsp_w1 = (dsp_info & 0x7ff) + 1;
1212                 y_dsp_w1 = ((dsp_info >> 16) & 0x7ff) + 1;
1213                 x_st_w1 = dsp_st & 0xffff;
1214                 y_st_w1 = dsp_st >> 16;
1215         } else {
1216                 spin_unlock(&lcdc_dev->reg_lock);
1217                 return -EPERM;
1218         }
1219         spin_unlock(&lcdc_dev->reg_lock);
1220         return snprintf(buf, PAGE_SIZE,
1221                         "win0:%s\n"
1222                         "xvir:%d\n"
1223                         "xact:%d\n"
1224                         "yact:%d\n"
1225                         "xdsp:%d\n"
1226                         "ydsp:%d\n"
1227                         "x_st:%d\n"
1228                         "y_st:%d\n"
1229                         "x_scale:%d.%d\n"
1230                         "y_scale:%d.%d\n"
1231                         "format:%s\n"
1232                         "YRGB buffer addr:0x%08x\n"
1233                         "CBR buffer addr:0x%08x\n\n"
1234                         "win1:%s\n"
1235                         "xvir:%d\n"
1236                         "xdsp:%d\n"
1237                         "ydsp:%d\n"
1238                         "x_st:%d\n"
1239                         "y_st:%d\n"
1240                         "format:%s\n"
1241                         "YRGB buffer addr:0x%08x\n"
1242                         "overlay:%s\n",
1243                         status_w0,
1244                         xvir_w0,
1245                         x_act_w0,
1246                         y_act_w0,
1247                         x_dsp_w0,
1248                         y_dsp_w0,
1249                         x_st_w0,
1250                         y_st_w0,
1251                         x_scale / 100,
1252                         x_scale % 100,
1253                         y_scale / 100,
1254                         y_scale % 100,
1255                         format_w0,
1256                         lcdc_readl(lcdc_dev, WIN0_YRGB_MST0),
1257                         lcdc_readl(lcdc_dev, WIN0_CBR_MST0),
1258                         status_w1,
1259                         xvir_w1,
1260                         x_dsp_w1,
1261                         y_dsp_w1,
1262                         x_st_w1,
1263                         y_st_w1,
1264                         format_w1,
1265                         lcdc_readl(lcdc_dev, WIN1_MST),
1266                         ovl ? "win0 on the top of win1\n" :
1267                         "win1 on the top of win0\n");
1268 }
1269
1270 static int rk3188_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
1271                                bool set)
1272 {
1273         struct lcdc_device *lcdc_dev =
1274             container_of(dev_drv, struct lcdc_device, driver);
1275         struct rk_screen *screen = dev_drv->cur_screen;
1276         u64 ft = 0;
1277         u32 dotclk;
1278         int ret;
1279         u32 pixclock;
1280         u32 x_total, y_total;
1281         if (set) {
1282                 ft = div_u64(1000000000000llu, fps);
1283                 x_total =
1284                     screen->mode.upper_margin + screen->mode.lower_margin +
1285                     screen->mode.yres + screen->mode.vsync_len;
1286                 y_total =
1287                     screen->mode.left_margin + screen->mode.right_margin +
1288                     screen->mode.xres + screen->mode.hsync_len;
1289                 dev_drv->pixclock = div_u64(ft, x_total * y_total);
1290                 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
1291                 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
1292         }
1293
1294         pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
1295         dev_drv->pixclock = lcdc_dev->pixclock = pixclock;
1296         fps = rk_fb_calc_fps(lcdc_dev->screen, pixclock);
1297         screen->ft = 1000 / fps;        /*one frame time in ms */
1298
1299         if (set)
1300                 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
1301                          clk_get_rate(lcdc_dev->dclk), fps);
1302
1303         return fps;
1304 }
1305
1306 static int rk3188_fb_win_remap(struct rk_lcdc_driver *dev_drv,
1307                                enum fb_win_map_order order)
1308 {
1309         mutex_lock(&dev_drv->fb_win_id_mutex);
1310         if (order == FB_DEFAULT_ORDER)
1311                 order = FB0_WIN0_FB1_WIN1_FB2_WIN2;
1312         dev_drv->fb2_win_id = order / 100;
1313         dev_drv->fb1_win_id = (order / 10) % 10;
1314         dev_drv->fb0_win_id = order % 10;
1315         mutex_unlock(&dev_drv->fb_win_id_mutex);
1316
1317         return 0;
1318 }
1319
1320 static int rk3188_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
1321                                   const char *id)
1322 {
1323         int win_id = 0;
1324         mutex_lock(&dev_drv->fb_win_id_mutex);
1325         if (!strcmp(id, "fb0") || !strcmp(id, "fb2"))
1326                 win_id = dev_drv->fb0_win_id;
1327         else if (!strcmp(id, "fb1") || !strcmp(id, "fb3"))
1328                 win_id = dev_drv->fb1_win_id;
1329         mutex_unlock(&dev_drv->fb_win_id_mutex);
1330
1331         return win_id;
1332 }
1333
1334 static int rk3188_set_dsp_lut(struct rk_lcdc_driver *dev_drv, int *lut)
1335 {
1336         int i = 0;
1337         int __iomem *c;
1338         int v;
1339         int ret = 0;
1340
1341         struct lcdc_device *lcdc_dev =
1342             container_of(dev_drv, struct lcdc_device, driver);
1343         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
1344         lcdc_cfg_done(lcdc_dev);
1345         msleep(25);
1346         if (dev_drv->cur_screen->dsp_lut) {
1347                 for (i = 0; i < 256; i++) {
1348                         v = dev_drv->cur_screen->dsp_lut[i] = lut[i];
1349                         c = lcdc_dev->dsp_lut_addr_base + i;
1350                         writel_relaxed(v, c);
1351
1352                 }
1353         } else {
1354                 dev_err(dev_drv->dev, "no buffer to backup lut data!\n");
1355                 ret = -1;
1356         }
1357         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
1358         lcdc_cfg_done(lcdc_dev);
1359
1360         return ret;
1361 }
1362
1363 static int rk3188_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
1364 {
1365         struct lcdc_device *lcdc_dev =
1366             container_of(dev_drv, struct lcdc_device, driver);
1367         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATCH_EN,
1368                      v_DIRECT_PATCH_EN(open));
1369         lcdc_cfg_done(lcdc_dev);
1370         return 0;
1371 }
1372
1373 static int rk3188_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
1374 {
1375         struct lcdc_device *lcdc_dev = container_of(dev_drv,
1376                                         struct lcdc_device, driver);
1377         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_LAY_SEL,
1378                      v_DIRECT_PATH_LAY_SEL(win_id));
1379         lcdc_cfg_done(lcdc_dev);
1380         return 0;
1381
1382 }
1383
1384 static int rk3188_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
1385 {
1386         struct lcdc_device *lcdc_dev =
1387             container_of(dev_drv, struct lcdc_device, driver);
1388         int ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATCH_EN);
1389         return ovl;
1390 }
1391
1392 int rk3188_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
1393 {
1394         struct lcdc_device *lcdc_dev =
1395             container_of(dev_drv, struct lcdc_device, driver);
1396         u32 int_reg;
1397         int ret;
1398
1399         if (lcdc_dev->clk_on) {
1400                 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
1401                 if (int_reg & m_LF_INT_STA) {
1402                         lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
1403                                      v_LF_INT_CLEAR(1));
1404                         ret = RK_LF_STATUS_FC;
1405                 } else
1406                         ret = RK_LF_STATUS_FR;
1407         } else {
1408                 ret = RK_LF_STATUS_NC;
1409         }
1410
1411         return ret;
1412 }
1413
1414 static struct rk_lcdc_win lcdc_win[] = {
1415         [0] = {
1416                .name = "win0",
1417                .id = 0,
1418                .support_3d = true,
1419                },
1420         [1] = {
1421                .name = "win1",
1422                .id = 1,
1423                .support_3d = false,
1424                },
1425 };
1426
1427 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
1428         .open = rk3188_lcdc_open,
1429         .load_screen = rk3188_load_screen,
1430         .set_par = rk3188_lcdc_set_par,
1431         .pan_display = rk3188_lcdc_pan_display,
1432         .lcdc_reg_update = rk3188_lcdc_reg_update,
1433         .blank = rk3188_lcdc_blank,
1434         .ioctl = rk3188_lcdc_ioctl,
1435         .suspend = rk3188_lcdc_early_suspend,
1436         .resume = rk3188_lcdc_early_resume,
1437         .get_win_state = rk3188_lcdc_get_win_state,
1438         .ovl_mgr = rk3188_lcdc_ovl_mgr,
1439         .get_disp_info = rk3188_lcdc_get_disp_info,
1440         .fps_mgr = rk3188_lcdc_fps_mgr,
1441         .fb_get_win_id = rk3188_lcdc_get_win_id,
1442         .fb_win_remap = rk3188_fb_win_remap,
1443         .set_dsp_lut = rk3188_set_dsp_lut,
1444         .poll_vblank = rk3188_lcdc_poll_vblank,
1445         .dpi_open = rk3188_lcdc_dpi_open,
1446         .dpi_win_sel = rk3188_lcdc_dpi_win_sel,
1447         .dpi_status = rk3188_lcdc_dpi_status,
1448 };
1449
1450 static irqreturn_t rk3188_lcdc_isr(int irq, void *dev_id)
1451 {
1452         struct lcdc_device *lcdc_dev =
1453             (struct lcdc_device *)dev_id;
1454         ktime_t timestamp = ktime_get();
1455         u32 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
1456
1457         if (int_reg & m_FS_INT_STA) {
1458                 timestamp = ktime_get();
1459                 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
1460                              v_FS_INT_CLEAR(1));
1461                 if (lcdc_dev->driver.wait_fs) {
1462                         spin_lock(&(lcdc_dev->driver.cpl_lock));
1463                         complete(&(lcdc_dev->driver.frame_done));
1464                         spin_unlock(&(lcdc_dev->driver.cpl_lock));
1465                 }
1466                 lcdc_dev->driver.vsync_info.timestamp = timestamp;
1467                 wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
1468
1469         } else if (int_reg & m_LF_INT_STA) {
1470                 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
1471                              v_LF_INT_CLEAR(1));
1472         }
1473         return IRQ_HANDLED;
1474 }
1475
1476 #if defined(CONFIG_PM)
1477 static int rk3188_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
1478 {
1479         return 0;
1480 }
1481
1482 static int rk3188_lcdc_resume(struct platform_device *pdev)
1483 {
1484         return 0;
1485 }
1486 #else
1487 #define rk3188_lcdc_suspend NULL
1488 #define rk3188_lcdc_resume  NULL
1489 #endif
1490
1491 static int rk3188_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
1492 {
1493         struct device_node *np = lcdc_dev->dev->of_node;
1494         int val;
1495         if (of_property_read_u32(np, "rockchip,prop", &val))
1496                 lcdc_dev->prop = PRMRY; /*default set it as primary */
1497         else
1498                 lcdc_dev->prop = val;
1499
1500         if (of_property_read_u32(np, "rockchip,pwr18", &val))
1501                 lcdc_dev->pwr18 = false;        /*default set it as 3.xv power supply */
1502         else
1503                 lcdc_dev->pwr18 = (val ? true : false);
1504         return 0;
1505 }
1506
1507 static int rk3188_lcdc_probe(struct platform_device *pdev)
1508 {
1509         struct lcdc_device *lcdc_dev = NULL;
1510         struct rk_lcdc_driver *dev_drv;
1511         struct device *dev = &pdev->dev;
1512         struct resource *res;
1513         struct device_node *np = pdev->dev.of_node;
1514         int prop;
1515         int ret = 0;
1516
1517         /*if the primary lcdc has not registered ,the extend
1518            lcdc register later */
1519         of_property_read_u32(np, "rockchip,prop", &prop);
1520         if (prop == EXTEND) {
1521                 if (!is_prmry_rk_lcdc_registered())
1522                         return -EPROBE_DEFER;
1523         }
1524         lcdc_dev = devm_kzalloc(dev,
1525                                 sizeof(struct lcdc_device), GFP_KERNEL);
1526         if (!lcdc_dev) {
1527                 dev_err(&pdev->dev, "rk3188 lcdc device kmalloc fail!");
1528                 return -ENOMEM;
1529         }
1530         platform_set_drvdata(pdev, lcdc_dev);
1531         lcdc_dev->dev = dev;
1532         rk3188_lcdc_parse_dt(lcdc_dev);
1533         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1534         lcdc_dev->reg_phy_base = res->start;
1535         lcdc_dev->len = resource_size(res);
1536         lcdc_dev->regs = devm_ioremap_resource(dev, res);
1537         if (IS_ERR(lcdc_dev->regs))
1538                 return PTR_ERR(lcdc_dev->regs);
1539
1540         lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
1541         if (IS_ERR(lcdc_dev->regsbak))
1542                 return PTR_ERR(lcdc_dev->regsbak);
1543         lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + DSP_LUT_ADDR);
1544         lcdc_dev->id = rk3188_lcdc_get_id(lcdc_dev->reg_phy_base);
1545         if (lcdc_dev->id < 0) {
1546                 dev_err(&pdev->dev, "no such lcdc device!\n");
1547                 return -ENXIO;
1548         }
1549         dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
1550         dev_drv = &lcdc_dev->driver;
1551         dev_drv->dev = dev;
1552         dev_drv->prop = prop;
1553         dev_drv->id = lcdc_dev->id;
1554         dev_drv->ops = &lcdc_drv_ops;
1555         dev_drv->num_win = ARRAY_SIZE(lcdc_win);
1556         spin_lock_init(&lcdc_dev->reg_lock);
1557
1558         lcdc_dev->irq = platform_get_irq(pdev, 0);
1559         if (lcdc_dev->irq < 0) {
1560                 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
1561                         lcdc_dev->id);
1562                 return -ENXIO;
1563         }
1564
1565         ret = devm_request_irq(dev, lcdc_dev->irq, rk3188_lcdc_isr,
1566                                IRQF_DISABLED, dev_name(dev), lcdc_dev);
1567         if (ret) {
1568                 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
1569                         lcdc_dev->irq, ret);
1570                 return ret;
1571         }
1572
1573         ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
1574         if (ret < 0) {
1575                 dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
1576                 return ret;
1577         }
1578         dev_info(dev, "lcdc%d probe ok\n", lcdc_dev->id);
1579
1580         return 0;
1581 }
1582
1583 static int rk3188_lcdc_remove(struct platform_device *pdev)
1584 {
1585
1586         return 0;
1587 }
1588
1589 static void rk3188_lcdc_shutdown(struct platform_device *pdev)
1590 {
1591         struct lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
1592
1593         rk3188_lcdc_deint(lcdc_dev);
1594         rk_disp_pwr_disable(&lcdc_dev->driver);
1595 }
1596
1597 #if defined(CONFIG_OF)
1598 static const struct of_device_id rk3188_lcdc_dt_ids[] = {
1599         {.compatible = "rockchip,rk3188-lcdc",},
1600         {}
1601 };
1602 #endif
1603
1604 static struct platform_driver rk3188_lcdc_driver = {
1605         .probe = rk3188_lcdc_probe,
1606         .remove = rk3188_lcdc_remove,
1607         .driver = {
1608                    .name = "rk3188-lcdc",
1609                    .owner = THIS_MODULE,
1610                    .of_match_table = of_match_ptr(rk3188_lcdc_dt_ids),
1611                    },
1612         .suspend = rk3188_lcdc_suspend,
1613         .resume = rk3188_lcdc_resume,
1614         .shutdown = rk3188_lcdc_shutdown,
1615 };
1616
1617 static int __init rk3188_lcdc_module_init(void)
1618 {
1619         return platform_driver_register(&rk3188_lcdc_driver);
1620 }
1621
1622 static void __exit rk3188_lcdc_module_exit(void)
1623 {
1624         platform_driver_unregister(&rk3188_lcdc_driver);
1625 }
1626
1627 fs_initcall(rk3188_lcdc_module_init);
1628 module_exit(rk3188_lcdc_module_exit);