clk: rockchip: support setting ddr clock via SCPI APIs
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / transmitter / rk3026_lvds.c
1 #include <linux/kernel.h>
2 #include <linux/init.h>
3 #include <linux/platform_device.h>
4 #include <linux/slab.h>
5 #include <linux/io.h>
6 #include <linux/types.h>
7 #include <linux/i2c.h>
8 #include <linux/rk_fb.h>
9 #include <linux/clk.h>
10 #include <linux/delay.h>
11
12 #include <mach/board.h>
13 #include <mach/hardware.h>
14 #include <mach/io.h>
15 #include <mach/gpio.h>
16 #include <mach/iomux.h>
17
18 #include "rk3026_lvds.h"
19
20 #define lvds_readl(offset)      readl_relaxed(RK30_GRF_BASE + offset)
21 #define lvds_writel(v,offset)   do{ writel_relaxed(v, RK30_GRF_BASE + offset);dsb();} while (0)
22
23 static void rk3026_output_lvds(rk_screen *screen)
24 {
25         u32 val =0;
26
27         #if defined(CONFIG_LCDC0_RK3188)        
28                 val |= LVDS_DATA_SEL(0);
29         #else
30                 val |= LVDS_DATA_SEL(1);
31         #endif
32         
33         if(screen->lvds_format == 0 || screen->lvds_format == 1)
34                 val |= LVDS_CBS_COL_SEL(2);  //24bit lvds
35         else
36                 val |= LVDS_CBS_COL_SEL(1);  //16bit lvds
37
38         val |= ((LVDS_OUTPUT_FORMAT(screen->lvds_format))|LVDS_INPUT_FORMAT(1)|LVDS_OUTPUT_LOAD_SEL(0)|
39                 LVDS_CBG_PWD_EN(1)|LVDS_PLL_PWD_EN(0)|LVDS_OUTPUT_EN(0)|LVDS_SWING_SEL(0));
40
41         val |= ((m_DATA_SEL|m_CBS_COL_SEL|m_OUTPUT_FORMAT|m_INPUT_FORMAT|m_OUTPUT_LOAD_SEL|
42                 m_CBG_PWD_EN|m_PLL_PWD_EN|m_OUTPUT_EN|m_SWING_SEL)<<16);
43
44         lvds_writel(val,CRU_LVDS_CON0);
45         
46         return;
47 }
48
49 static void rk3026_output_lvttl(rk_screen *screen)
50 {
51
52         u32 val =0;
53
54         val |= (LVDS_CBG_PWD_EN(0)|LVDS_PLL_PWD_EN(1)|LVDS_OUTPUT_EN(1));
55         val |= ((m_CBG_PWD_EN|m_PLL_PWD_EN|m_OUTPUT_EN)<<16);
56         
57         lvds_writel(val,CRU_LVDS_CON0);
58
59         return;                 
60 }
61
62 static void rk3026_output_disable(void)
63 {       
64
65         u32 val =0;
66
67         val |= (LVDS_CBG_PWD_EN(1)|LVDS_PLL_PWD_EN(0)|LVDS_OUTPUT_EN(0)|LVDS_CBS_COL_SEL(0));
68         val |= ((m_CBG_PWD_EN|m_PLL_PWD_EN|m_OUTPUT_EN|m_CBS_COL_SEL)<<16);
69
70         lvds_writel(val,CRU_LVDS_CON0);
71         
72 }
73
74
75 static int rk3026_lvds_set_param(rk_screen *screen,bool enable)
76 {
77
78         if(OUT_ENABLE == enable){
79                 switch(screen->type){
80                         case SCREEN_LVDS:
81                                 rk3026_output_lvds(screen);                                       
82                                 break;
83                         case SCREEN_RGB:
84                                 rk3026_output_lvttl(screen);
85                                 break;
86                         default:
87                                 printk("%s>>>>LVDS not support this screen type %d,power down LVDS\n",__func__,screen->type);
88                                 rk3026_output_disable();
89                                 break;
90                 }
91         }else{
92                 rk3026_output_disable();
93         }
94         return 0;
95 }
96
97
98 static int rk3026_lvds_probe(struct platform_device *pdev)
99 {
100         rk_screen *screen = NULL;
101         screen = rk_fb_get_prmry_screen();
102         if(!screen)
103         {
104                 dev_err(&pdev->dev,"the fb prmry screen is null!\n");
105                 return -ENODEV;
106         }
107         
108         rk3026_lvds_set_param(screen,OUT_ENABLE);
109
110         return 0;
111         
112 }
113
114 static int rk3026_lvds_remove(struct platform_device *pdev)
115 {       
116         return 0;
117 }
118
119 static void rk3026_lvds_shutdown(struct platform_device *pdev)
120 {
121         return;
122 }
123
124 static struct platform_driver rk3026_lvds_driver = {
125         .driver         = {
126                 .name   = "rk3026-lvds",
127                 .owner  = THIS_MODULE,
128         },
129         .probe          = rk3026_lvds_probe,
130         .remove         = rk3026_lvds_remove,
131         .shutdown       = rk3026_lvds_shutdown,
132 };
133
134 static int __init rk3026_lvds_init(void)
135 {
136         return platform_driver_register(&rk3026_lvds_driver);
137 }
138 fs_initcall(rk3026_lvds_init);
139 static void __exit rk3026_lvds_exit(void)
140 {
141         platform_driver_unregister(&rk3026_lvds_driver);
142 }
143 module_exit(rk3026_lvds_exit);
144
145
146