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