clk: rockchip: support setting ddr clock via SCPI APIs
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / transmitter / rk31xx_lvds.c
1 /*
2  * drivers/video/rockchip/transmitter/rk31xx_lvds.c
3  *
4  * Copyright (C) 2014 ROCKCHIP, Inc.
5  * Author: zhuangwenlong<zwl@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 #include <linux/module.h>
17 #include <linux/kernel.h>
18 #include <linux/init.h>
19 #include <linux/platform_device.h>
20 #include <linux/slab.h>
21 #include <linux/io.h>
22 #include <linux/types.h>
23 #include <linux/i2c.h>
24 #include <linux/rk_fb.h>
25 #include <linux/clk.h>
26 #include <linux/delay.h>
27 #include <linux/rockchip/iomap.h>
28 #include <linux/rockchip/grf.h>
29 #include "rk31xx_lvds.h"
30
31
32 #define grf_readl(offset)       readl_relaxed(RK_GRF_VIRT + offset)
33 #define grf_writel(v,offset)                                    \
34         do {                                                    \
35                 writel_relaxed(v, RK_GRF_VIRT + offset);        \
36                 dsb(sy);                                        \
37         } while (0)
38
39
40 static struct rk_lvds_device *rk31xx_lvds;
41
42 static int rk31xx_lvds_clk_init(struct rk_lvds_device *lvds)
43 {
44         lvds->pclk = devm_clk_get(lvds->dev, "pclk_lvds");
45         if (IS_ERR(lvds->pclk)) {
46                 dev_err(lvds->dev, "get pclk failed\n");
47                 return PTR_ERR(lvds->pclk);
48         }
49
50         lvds->ctrl_pclk = devm_clk_get(lvds->dev, "pclk_lvds_ctl");
51         if (IS_ERR(lvds->ctrl_pclk)) {
52                 dev_err(lvds->dev, "get ctrl pclk failed\n");
53                 return PTR_ERR(lvds->ctrl_pclk);
54         }
55
56         if (lvds->data->soc_type == LVDS_SOC_RK312X) {
57                 lvds->ctrl_hclk = devm_clk_get(lvds->dev, "hclk_vio_h2p");
58                 if (IS_ERR(lvds->ctrl_hclk)) {
59                         dev_err(lvds->dev, "get ctrl hclk failed\n");
60                         return PTR_ERR(lvds->ctrl_hclk);
61                 }
62         } else {
63                 lvds->pd = devm_clk_get(lvds->dev, "pd_lvds");
64                 if (IS_ERR(lvds->pd)) {
65                         dev_err(lvds->dev, "get pd_lvds failed\n");
66                         lvds->pd = NULL;
67                 }
68         }
69
70         return 0;       
71 }
72
73 static int rk31xx_lvds_clk_enable(struct rk_lvds_device *lvds)
74 {
75         if (!lvds->clk_on) {
76                 clk_prepare_enable(lvds->pclk);
77                 clk_prepare_enable(lvds->ctrl_pclk);
78                 if (lvds->data->soc_type == LVDS_SOC_RK312X)
79                         clk_prepare_enable(lvds->ctrl_hclk);
80                 if (lvds->pd)
81                         clk_prepare_enable(lvds->pd);
82                 lvds->clk_on = true;
83         }
84
85         return 0;
86 }
87
88 static int rk31xx_lvds_clk_disable(struct rk_lvds_device *lvds)
89 {
90         if (lvds->clk_on) {
91                 clk_disable_unprepare(lvds->pclk);
92                 if (lvds->data->soc_type == LVDS_SOC_RK312X)
93                         clk_disable_unprepare(lvds->ctrl_hclk);
94                 if (lvds->pd)
95                         clk_disable_unprepare(lvds->pd);
96                 clk_disable_unprepare(lvds->ctrl_pclk);
97                 lvds->clk_on = false;
98         }
99
100         return 0;
101 }
102
103 static int rk31xx_lvds_pwr_on(void)
104 {
105         struct rk_lvds_device *lvds = rk31xx_lvds;
106
107         if (lvds->screen.type == SCREEN_LVDS) {
108                 /* set VOCM 900 mv and V-DIFF 350 mv */
109                 lvds_msk_reg(lvds, MIPIPHY_REGE4, m_VOCM | m_DIFF_V,
110                              v_VOCM(0) | v_DIFF_V(2));
111
112                 /* power up lvds pll and ldo */
113                 lvds_msk_reg(lvds, MIPIPHY_REG1,
114                              m_SYNC_RST | m_LDO_PWR_DOWN | m_PLL_PWR_DOWN,
115                              v_SYNC_RST(0) | v_LDO_PWR_DOWN(0) | v_PLL_PWR_DOWN(0));
116
117                 /* enable lvds lane and power on pll */
118                 lvds_writel(lvds, MIPIPHY_REGEB,
119                             v_LANE0_EN(1) | v_LANE1_EN(1) | v_LANE2_EN(1) |
120                             v_LANE3_EN(1) | v_LANECLK_EN(1) | v_PLL_PWR_OFF(0));
121
122                 /* enable lvds */
123                 lvds_msk_reg(lvds, MIPIPHY_REGE3,
124                              m_MIPI_EN | m_LVDS_EN | m_TTL_EN,
125                              v_MIPI_EN(0) | v_LVDS_EN(1) | v_TTL_EN(0));
126         } else {
127                 lvds_msk_reg(lvds, MIPIPHY_REGE3,
128                              m_MIPI_EN | m_LVDS_EN | m_TTL_EN,
129                              v_MIPI_EN(0) | v_LVDS_EN(0) | v_TTL_EN(1));
130         }
131         return 0;
132 }
133
134 static int rk31xx_lvds_pwr_off(void)
135 {
136         struct rk_lvds_device *lvds = rk31xx_lvds;
137
138         /* disable lvds lane and power off pll */
139         lvds_writel(lvds, MIPIPHY_REGEB,
140                     v_LANE0_EN(0) | v_LANE1_EN(0) | v_LANE2_EN(0) |
141                     v_LANE3_EN(0) | v_LANECLK_EN(0) | v_PLL_PWR_OFF(1));
142
143         /* power down lvds pll and bandgap */
144         lvds_msk_reg(lvds, MIPIPHY_REG1,
145                      m_SYNC_RST | m_LDO_PWR_DOWN | m_PLL_PWR_DOWN,
146                      v_SYNC_RST(1) | v_LDO_PWR_DOWN(1) | v_PLL_PWR_DOWN(1));
147
148         /* disable lvds */
149         lvds_msk_reg(lvds, MIPIPHY_REGE3, m_LVDS_EN | m_TTL_EN,
150                      v_LVDS_EN(0) | v_TTL_EN(0));
151         return 0;
152 }
153
154 static int rk31xx_lvds_disable(void)
155 {
156         struct rk_lvds_device *lvds = rk31xx_lvds;
157         u32 val;
158
159         if (unlikely(!lvds) || !lvds->sys_state)
160                 return 0;
161         if (lvds->data->soc_type == LVDS_SOC_RK3368) {
162                 val = v_RK3368_LVDSMODE_EN(0) | v_RK3368_MIPIPHY_TTL_EN(0);
163                 lvds_grf_writel(lvds, RK3368_GRF_SOC_CON7_LVDS, val);
164         } else {
165                 grf_writel(v_LVDSMODE_EN(0) | v_MIPIPHY_TTL_EN(0), RK312X_GRF_LVDS_CON0);
166         }
167
168         rk31xx_lvds_pwr_off();
169         rk31xx_lvds_clk_disable(lvds);
170
171 #if !defined(CONFIG_RK_FPGA)
172 #ifdef CONFIG_PINCTRL
173         if (lvds->screen.type == SCREEN_RGB) {
174                 if (lvds->dev->pins) {
175                         pinctrl_select_state(lvds->dev->pins->p,
176                                              lvds->dev->pins->sleep_state);
177                 } else if (lvds->pins && !IS_ERR(lvds->pins->sleep_state)) {
178                         pinctrl_select_state(lvds->pins->p,
179                                              lvds->pins->sleep_state);
180                 }
181         }
182 #endif
183 #endif
184         lvds->sys_state = false;
185         return 0;
186 }
187
188 static void rk31xx_output_lvds(struct rk_lvds_device *lvds,
189                                struct rk_screen *screen)
190 {
191         u32 val = 0;
192         u32 delay_times = 20;
193
194         /* if LVDS transmitter source from VOP, vop_dclk need get invert
195          * set iomux in dts pinctrl
196          */
197         if ((lvds->data->soc_type == LVDS_SOC_RK3368) ||
198             (lvds->data->soc_type == LVDS_SOC_RK3366)) {
199                 /* enable lvds mode */
200                 val |= v_RK3368_LVDSMODE_EN(1) | v_RK3368_MIPIPHY_TTL_EN(0);
201                 /* config data source */
202                 /*val |= v_LVDS_DATA_SEL(LVDS_DATA_FROM_LCDC); */
203                 /* config lvds_format */
204                 val |= v_RK3368_LVDS_OUTPUT_FORMAT(screen->lvds_format);
205                 /* LSB receive mode */
206                 val |= v_RK3368_LVDS_MSBSEL(LVDS_MSB_D7);
207                 val |= v_RK3368_MIPIPHY_LANE0_EN(1) |
208                        v_RK3368_MIPIDPI_FORCEX_EN(1);
209                 /*rk3368  RK3368_GRF_SOC_CON7 = 0X0041C*/
210                 /*grf_writel(val, 0x0041C);*/
211                 if (lvds->data->soc_type == LVDS_SOC_RK3368)
212                         lvds_grf_writel(lvds, RK3368_GRF_SOC_CON7_LVDS, val);
213                 else
214                         lvds_grf_writel(lvds, RK3366_GRF_SOC_CON5_LVDS, val);
215         } else {
216                 /* enable lvds mode */
217                 val |= v_LVDSMODE_EN(1) | v_MIPIPHY_TTL_EN(0);
218                 /* config data source */
219                 val |= v_LVDS_DATA_SEL(LVDS_DATA_FROM_LCDC);
220                 /* config lvds_format */
221                 val |= v_LVDS_OUTPUT_FORMAT(screen->lvds_format);
222                 /* LSB receive mode */
223                 val |= v_LVDS_MSBSEL(LVDS_MSB_D7);
224                 val |= v_MIPIPHY_LANE0_EN(1) | v_MIPIDPI_FORCEX_EN(1);
225                 /*rk312x  RK312X_GRF_LVDS_CON0 = 0X00150*/
226                 grf_writel(val, 0X00150);
227         }
228         /* digital internal disable */
229         lvds_msk_reg(lvds, MIPIPHY_REGE1, m_DIG_INTER_EN, v_DIG_INTER_EN(0));
230
231         /* set pll prediv and fbdiv */
232         lvds_writel(lvds, MIPIPHY_REG3, v_PREDIV(2) | v_FBDIV_MSB(0));
233         lvds_writel(lvds, MIPIPHY_REG4, v_FBDIV_LSB(28));
234
235         lvds_writel(lvds, MIPIPHY_REGE8, 0xfc);
236
237         /* set lvds mode and reset phy config */
238         lvds_msk_reg(lvds, MIPIPHY_REGE0,
239                      m_MSB_SEL | m_DIG_INTER_RST,
240                      v_MSB_SEL(1) | v_DIG_INTER_RST(1));
241
242         /* power on pll and enable lane */
243         rk31xx_lvds_pwr_on();
244
245         /* delay for waitting pll lock on */
246         while (delay_times--) {
247                 if (lvds_phy_lockon(lvds)) {
248                         msleep(1);
249                         break;
250                 }
251                 udelay(100);
252         }
253         /* digital internal enable */
254         lvds_msk_reg(lvds, MIPIPHY_REGE1, m_DIG_INTER_EN, v_DIG_INTER_EN(1));
255
256 #if 0
257         lvds_writel(lvds, MIPIPHY_REGE2, 0xa0); /* timing */
258         lvds_writel(lvds, MIPIPHY_REGE7, 0xfc); /* phase */
259 #endif
260
261 }
262
263 static void rk31xx_output_lvttl(struct rk_lvds_device *lvds,
264                                 struct rk_screen *screen)
265 {
266         u32 val = 0;
267
268         if ((lvds->data->soc_type == LVDS_SOC_RK3368) ||
269             (lvds->data->soc_type == LVDS_SOC_RK3366)) {
270                 /* iomux to lcdc */
271 #ifdef CONFIG_PINCTRL
272                 if (lvds->pins && !IS_ERR(lvds->pins->default_state))
273                         pinctrl_select_state(lvds->pins->p,
274                                              lvds->pins->default_state);
275 #endif
276                 lvds_dsi_writel(lvds, 0x0, 0x4);/*set clock lane enable*/
277                 /* enable lvds mode */
278                 val |= v_RK3368_LVDSMODE_EN(0) | v_RK3368_MIPIPHY_TTL_EN(1) |
279                         v_RK3368_MIPIPHY_LANE0_EN(1) |
280                         v_RK3368_MIPIDPI_FORCEX_EN(1);
281                 if (lvds->data->soc_type == LVDS_SOC_RK3368) {
282                         lvds_grf_writel(lvds, RK3368_GRF_SOC_CON7_LVDS, val);
283                         val = v_RK3368_FORCE_JETAG(0);
284                         lvds_grf_writel(lvds, RK3368_GRF_SOC_CON15_LVDS, val);
285                 } else {
286                         lvds_grf_writel(lvds, RK3366_GRF_SOC_CON5_LVDS, val);
287                         val = v_RK3368_FORCE_JETAG(0);
288                         lvds_grf_writel(lvds, RK3366_GRF_SOC_CON6_LVDS, val);
289                 }
290                 /*val = v_MIPITTL_CLK_EN(1) | v_MIPITTL_LANE0_EN(1) |
291                 v_MIPITTL_LANE1_EN(1) | v_MIPITTL_LANE2_EN(1) |
292                 v_MIPITTL_LANE3_EN(1);
293                 grf_writel(val, RK312X_GRF_SOC_CON1);*/
294         } else {
295                 /* iomux to lcdc */
296 #if defined(CONFIG_RK_FPGA)
297                 grf_writel(0xffff5555, RK312X_GRF_GPIO2B_IOMUX);
298                 grf_writel(0x00ff0055, RK312X_GRF_GPIO2C_IOMUX);
299                 grf_writel(0x77771111, 0x00e8); /* RK312X_GRF_GPIO2C_IOMUX2 */
300                 grf_writel(0x700c1004, RK312X_GRF_GPIO2D_IOMUX);
301 #else
302 #ifdef CONFIG_PINCTRL
303                 if (lvds->pins && !IS_ERR(lvds->pins->default_state))
304                         pinctrl_select_state(lvds->pins->p,
305                                              lvds->pins->default_state);
306 #endif
307 #endif
308                 /* enable lvds mode */
309                 val |= v_LVDSMODE_EN(0) | v_MIPIPHY_TTL_EN(1);
310                 /* config data source */
311                 val |= v_LVDS_DATA_SEL(LVDS_DATA_FROM_LCDC);
312                 grf_writel(0xffff0380, RK312X_GRF_LVDS_CON0);
313
314                 val = v_MIPITTL_CLK_EN(1) | v_MIPITTL_LANE0_EN(1) |
315                         v_MIPITTL_LANE1_EN(1) | v_MIPITTL_LANE2_EN(1) |
316                         v_MIPITTL_LANE3_EN(1);
317                 grf_writel(val, RK312X_GRF_SOC_CON1);
318         }
319         /* enable lane */
320         lvds_writel(lvds, MIPIPHY_REG0, 0x7f);
321         val = v_LANE0_EN(1) | v_LANE1_EN(1) | v_LANE2_EN(1) | v_LANE3_EN(1) |
322                 v_LANECLK_EN(1) | v_PLL_PWR_OFF(1);
323         lvds_writel(lvds, MIPIPHY_REGEB, val);
324
325         /* set ttl mode and reset phy config */
326         val = v_LVDS_MODE_EN(0) | v_TTL_MODE_EN(1) | v_MIPI_MODE_EN(0) |
327                 v_MSB_SEL(1) | v_DIG_INTER_RST(1);
328         lvds_writel(lvds, MIPIPHY_REGE0, val);
329
330         rk31xx_lvds_pwr_on();
331                 
332 }
333
334 static int rk31xx_lvds_en(void)
335 {
336         struct rk_lvds_device *lvds = rk31xx_lvds;
337         struct rk_screen *screen;
338
339         if (unlikely(!lvds))//|| lvds->sys_state)
340                 return 0;
341
342         screen = &lvds->screen;
343         rk_fb_get_prmry_screen(screen);
344
345         /* enable clk */
346         rk31xx_lvds_clk_enable(lvds);
347
348         switch (screen->type) {
349         case SCREEN_LVDS:
350                 rk31xx_output_lvds(lvds, screen);
351                 break;
352         case SCREEN_RGB:
353                 rk31xx_output_lvttl(lvds, screen);
354                 break;
355         default:
356                 printk("unsupport screen type\n");
357                 break;
358         }
359
360         lvds->sys_state = true;
361         return 0;
362 }
363
364 static struct rk_fb_trsm_ops trsm_lvds_ops = {
365         .enable = rk31xx_lvds_en,
366         .disable = rk31xx_lvds_disable,
367         .dsp_pwr_on = rk31xx_lvds_pwr_on,
368         .dsp_pwr_off = rk31xx_lvds_pwr_off,
369 };
370 #if defined(CONFIG_OF)
371 static struct rk_lvds_drvdata rk31xx_lvds_drvdata = {
372         .soc_type =  LVDS_SOC_RK312X,
373 };
374
375 static struct rk_lvds_drvdata rk3368_lvds_drvdata = {
376         .soc_type =  LVDS_SOC_RK3368,
377 };
378
379 static struct rk_lvds_drvdata rk3366_lvds_drvdata = {
380         .soc_type =  LVDS_SOC_RK3366,
381 };
382
383 static const struct of_device_id rk31xx_lvds_dt_ids[] = {
384         {.compatible = "rockchip,rk31xx-lvds",
385          .data = (void *)&rk31xx_lvds_drvdata,},
386         {.compatible = "rockchip,rk3368-lvds",
387          .data = (void *)&rk3368_lvds_drvdata,},
388         {.compatible = "rockchip,rk3366-lvds",
389          .data = (void *)&rk3366_lvds_drvdata,},
390         {}
391 };
392
393 /*MODULE_DEVICE_TABLE(of, rk31xx_lvds_dt_ids);*/
394
395 #endif
396
397 static int rk31xx_lvds_probe(struct platform_device *pdev)
398 {
399         struct rk_lvds_device *lvds;
400         struct resource *res;
401         struct device_node *np = pdev->dev.of_node;
402         const struct of_device_id *match;
403         int ret = 0;
404
405         if (!np) {
406                 dev_err(&pdev->dev, "Don't find lvds device tree node.\n");
407                 return -EINVAL;
408         }       
409
410         lvds = devm_kzalloc(&pdev->dev, sizeof(struct rk_lvds_device), GFP_KERNEL);
411         if (!lvds) {
412                 dev_err(&pdev->dev, "kzalloc rk31xx lvds failed\n");
413                 return -ENOMEM;
414         }
415         lvds->dev = &pdev->dev;
416         match = of_match_node(rk31xx_lvds_dt_ids, np);
417         lvds->data = (struct rk_lvds_drvdata *)match->data;
418         dev_info(lvds->dev, "%s,type=%d\n",
419                  __func__, lvds->data->soc_type);
420
421         rk_fb_get_prmry_screen(&lvds->screen);
422         if ((lvds->screen.type != SCREEN_RGB) && 
423                 (lvds->screen.type != SCREEN_LVDS)) {
424                 dev_err(&pdev->dev, "screen is not lvds/rgb!\n");
425                 ret = -EINVAL;
426                 goto err_screen_type;
427         }
428
429         platform_set_drvdata(pdev, lvds);
430         dev_set_name(lvds->dev, "rk31xx-lvds");
431
432 #ifdef CONFIG_PINCTRL
433         if (lvds->dev->pins == NULL && lvds->screen.type == SCREEN_RGB) {
434                 lvds->pins = devm_kzalloc(lvds->dev, sizeof(*(lvds->pins)),
435                                           GFP_KERNEL);
436                 if (!lvds->pins) {
437                         dev_err(lvds->dev, "kzalloc lvds pins failed\n");
438                         return -ENOMEM;
439                 }
440
441                 lvds->pins->p = devm_pinctrl_get(lvds->dev);
442                 if (IS_ERR(lvds->pins->p)) {
443                         dev_info(lvds->dev, "no pinctrl handle\n");
444                         devm_kfree(lvds->dev, lvds->pins);
445                         lvds->pins = NULL;
446                 } else {
447                         lvds->pins->default_state =
448                                 pinctrl_lookup_state(lvds->pins->p, "lcdc");
449                         lvds->pins->sleep_state =
450                                 pinctrl_lookup_state(lvds->pins->p, "sleep");
451                         if (IS_ERR(lvds->pins->default_state)) {
452                                 dev_info(lvds->dev, "no default pinctrl state\n");
453                                 devm_kfree(lvds->dev, lvds->pins);
454                                 lvds->pins = NULL;
455                         }
456                 }
457         }
458
459 #endif
460         /* lvds regs on MIPIPHY_REG */
461         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mipi_lvds_phy");
462         lvds->regbase = devm_ioremap_resource(&pdev->dev, res);
463         if (IS_ERR(lvds->regbase)) {
464                 dev_err(&pdev->dev, "ioremap mipi-lvds phy reg failed\n");
465                 return PTR_ERR(lvds->regbase);
466         }
467
468         /* pll lock on status reg that is MIPICTRL Register */
469         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mipi_lvds_ctl");
470         lvds->ctrl_reg = devm_ioremap_resource(&pdev->dev, res);
471         if (IS_ERR(lvds->ctrl_reg)) {
472                 dev_err(&pdev->dev, "ioremap mipi-lvds ctl reg failed\n");
473                 return PTR_ERR(lvds->ctrl_reg);
474         }
475 #ifdef CONFIG_MFD_SYSCON
476         if ((lvds->data->soc_type == LVDS_SOC_RK3368) ||
477             (lvds->data->soc_type == LVDS_SOC_RK3366)) {
478                 lvds->grf_lvds_base =
479                         syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
480                 if (IS_ERR(lvds->grf_lvds_base)) {
481                         dev_err(&pdev->dev, "can't find rockchip,grf property\n");
482                         return PTR_ERR(lvds->grf_lvds_base);
483                 }
484         }
485 #endif
486         ret = rk31xx_lvds_clk_init(lvds);
487         if(ret < 0)
488                 goto err_clk_init;
489
490         if (support_uboot_display()) {
491                 rk31xx_lvds_clk_enable(lvds);
492                 /*lvds->sys_state = true;*/
493         }
494
495         rk31xx_lvds = lvds;
496         rk_fb_trsm_ops_register(&trsm_lvds_ops, SCREEN_LVDS);
497         dev_info(&pdev->dev, "rk31xx lvds driver probe success\n");
498
499         return 0;
500
501 err_clk_init:
502 err_screen_type:
503         devm_kfree(&pdev->dev, lvds);
504         lvds = NULL;
505         return ret;     
506 }
507
508 static int rk31xx_lvds_remove(struct platform_device *pdev)
509 {       
510         return 0;
511 }
512
513 static void rk31xx_lvds_shutdown(struct platform_device *pdev)
514 {
515         return;
516 }
517
518
519 static struct platform_driver rk31xx_lvds_driver = {
520         .driver         = {
521                 .name   = "rk31xx-lvds",
522                 .owner  = THIS_MODULE,
523 #if defined(CONFIG_OF)
524                 .of_match_table = of_match_ptr(rk31xx_lvds_dt_ids),
525 #endif
526         },
527         .probe          = rk31xx_lvds_probe,
528         .remove         = rk31xx_lvds_remove,
529         .shutdown       = rk31xx_lvds_shutdown,
530 };
531
532 static int __init rk31xx_lvds_init(void)
533 {
534         return platform_driver_register(&rk31xx_lvds_driver);
535 }
536
537 static void __exit rk31xx_lvds_exit(void)
538 {
539         platform_driver_unregister(&rk31xx_lvds_driver);
540 }
541
542 fs_initcall(rk31xx_lvds_init);
543 module_exit(rk31xx_lvds_exit);
544