video: rockchip: edp: Solve the problem of write grf register failure
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / transmitter / rk32_lvds.c
1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/init.h>
4 #include <linux/device.h>
5 #include <linux/errno.h>
6 #include <linux/string.h>
7 #include <linux/mm.h>
8 #include <linux/slab.h>
9 #include <linux/delay.h>
10 #include <linux/platform_device.h>
11 #include <linux/clk.h>
12 #include <linux/rk_fb.h>
13 #include <linux/rockchip/iomap.h>
14 #include <linux/rockchip/grf.h>
15 #include "rk32_lvds.h"
16
17
18 #define grf_readl(offset)       readl_relaxed(RK_GRF_VIRT + offset)
19 #define grf_writel(v,offset)    do{ writel_relaxed(v, RK_GRF_VIRT + offset);dsb();} while (0)
20
21 static struct rk32_lvds *rk32_lvds;
22
23 static int rk32_lvds_clk_enable(struct rk32_lvds *lvds)
24 {
25         if (!lvds->clk_on) {
26                 clk_prepare_enable(lvds->pd);
27                 clk_prepare_enable(lvds->pclk);
28                 lvds->clk_on = true;
29         }
30
31         return 0;
32 }
33
34 static int rk32_lvds_clk_disable(struct rk32_lvds *lvds)
35 {
36         if (lvds->clk_on) {
37                 clk_disable_unprepare(lvds->pclk);
38                 clk_disable_unprepare(lvds->pd);
39                 lvds->clk_on = false;
40         }
41
42         return 0;
43 }
44
45 static int rk32_lvds_disable(void)
46 {
47         struct rk32_lvds *lvds = rk32_lvds;
48         grf_writel(0xffff8000, RK3288_GRF_SOC_CON7);
49         writel_relaxed(0x00, lvds->regs + LVDS_CFG_REG_21); /*disable tx*/
50         writel_relaxed(0xff, lvds->regs + LVDS_CFG_REG_c); /*disable pll*/
51         rk32_lvds_clk_disable(lvds);
52         return 0;
53 }
54
55 static int rk32_lvds_en(void)
56 {
57         struct rk32_lvds *lvds = rk32_lvds;
58         struct rk_screen *screen = &lvds->screen;
59         u32 h_bp = 0;
60         u32 val = 0;
61
62         rk_fb_get_prmry_screen(screen);
63
64         /* enable clk */
65         rk32_lvds_clk_enable(lvds);
66
67         /* select lcdc source */
68         if (screen->lcdc_id == 1) /*lcdc1 = vop little,lcdc0 = vop big*/
69                 val = LVDS_SEL_VOP_LIT | (LVDS_SEL_VOP_LIT << 16);
70         else
71                 val = LVDS_SEL_VOP_LIT << 16;
72         grf_writel(val, RK3288_GRF_SOC_CON6);
73
74         /* set lvds format */
75         val = screen->lvds_format;
76         if ((screen->type == SCREEN_DUAL_LVDS) ||
77             (screen->type == SCREEN_DUAL_LVDS_10BIT))
78                 val |= LVDS_DUAL | LVDS_CH0_EN | LVDS_CH1_EN;
79         else if((screen->type == SCREEN_LVDS) ||
80                 (screen->type == SCREEN_LVDS_10BIT))
81                 val |= LVDS_CH0_EN;
82         else if (screen->type == SCREEN_RGB)
83                 val = LVDS_TTL_EN | LVDS_CH0_EN | LVDS_CH1_EN;
84
85         h_bp = screen->mode.hsync_len + screen->mode.left_margin;
86         if (h_bp & 0x01)
87                 val |= LVDS_START_PHASE_RST_1;
88
89         val |= (screen->pin_dclk << 8) | (screen->pin_hsync << 9) |
90                 (screen->pin_den << 10);
91         val |= (0xffff << 16);
92         grf_writel(val, RK3288_GRF_SOC_CON7);
93
94         if (screen->type == SCREEN_RGB) {
95                 val = 0x007f007f;//0x1<<6 |0x1 <<4;
96                 grf_writel(val, RK3288_GRF_GPIO1D_IOMUX);
97
98                 lvds_writel(lvds, LVDS_CH0_REG_0, 0x7f);
99                 lvds_writel(lvds, LVDS_CH0_REG_1, 0x40);
100                 lvds_writel(lvds, LVDS_CH0_REG_2, 0x00);
101
102                 lvds_writel(lvds, LVDS_CH0_REG_4, 0x3f);
103                 lvds_writel(lvds, LVDS_CH0_REG_5, 0x3f);
104                 lvds_writel(lvds, LVDS_CH0_REG_3, 0x46);
105                 lvds_writel(lvds, LVDS_CH0_REG_d, 0x0a);
106                 lvds_writel(lvds, LVDS_CH0_REG_20,0x44);/* 44:LSB  45:MSB*/
107                 writel_relaxed(0x00, lvds->regs + LVDS_CFG_REG_c); /*eanble pll*/
108                 writel_relaxed(0x92, lvds->regs + LVDS_CFG_REG_21); /*enable tx*/
109
110                 lvds_writel(lvds, 0x100, 0x7f);
111                 lvds_writel(lvds, 0x104, 0x40);
112                 lvds_writel(lvds, 0x108, 0x00);
113                 lvds_writel(lvds, 0x10c, 0x46);
114                 lvds_writel(lvds, 0x110, 0x3f);
115                 lvds_writel(lvds, 0x114, 0x3f);
116                 lvds_writel(lvds, 0x134, 0x0a);
117         } else {
118                 lvds_writel(lvds, LVDS_CH0_REG_0, 0xbf);
119                 lvds_writel(lvds, LVDS_CH0_REG_1, 0x3f);
120                 lvds_writel(lvds, LVDS_CH0_REG_2, 0xfe);
121                 lvds_writel(lvds, LVDS_CH0_REG_3, 0x46);
122                 lvds_writel(lvds, LVDS_CH0_REG_4, 0x00);
123                 lvds_writel(lvds, LVDS_CH0_REG_d, 0x0a);
124                 lvds_writel(lvds, LVDS_CH0_REG_20,0x44);/* 44:LSB  45:MSB*/
125                 writel_relaxed(0x00, lvds->regs + LVDS_CFG_REG_c); /*eanble pll*/
126                 writel_relaxed(0x92, lvds->regs + LVDS_CFG_REG_21); /*enable tx*/
127         }
128
129         return 0;
130 }
131
132
133 static struct rk_fb_trsm_ops trsm_lvds_ops = {
134         .enable = rk32_lvds_en,
135         .disable = rk32_lvds_disable,
136 };
137
138 static int rk32_lvds_probe(struct platform_device *pdev)
139 {
140         struct rk32_lvds *lvds;
141         struct resource *res;
142         struct device_node *np = pdev->dev.of_node;
143
144         if (!np) {
145                 dev_err(&pdev->dev, "Missing device tree node.\n");
146                 return -EINVAL;
147         }
148
149         lvds = devm_kzalloc(&pdev->dev, sizeof(struct rk32_lvds), GFP_KERNEL);
150         if (!lvds) {
151                 dev_err(&pdev->dev, "no memory for state\n");
152                 return -ENOMEM;
153         }
154         lvds->dev = &pdev->dev;
155         rk_fb_get_prmry_screen(&lvds->screen);
156         if ((lvds->screen.type != SCREEN_RGB) && 
157                 (lvds->screen.type != SCREEN_LVDS) &&
158                 (lvds->screen.type != SCREEN_DUAL_LVDS) &&
159                 (lvds->screen.type != SCREEN_LVDS_10BIT) &&
160                 (lvds->screen.type != SCREEN_DUAL_LVDS_10BIT)) {
161                 dev_err(&pdev->dev, "screen is not lvds/rgb!\n");               
162                 writel_relaxed(0xffff8000, RK_GRF_VIRT + RK3288_GRF_SOC_CON7);
163                 return -EINVAL;
164         }
165         platform_set_drvdata(pdev, lvds);
166         dev_set_name(lvds->dev, "rk32-lvds");
167         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
168         lvds->regs = devm_ioremap_resource(&pdev->dev, res);
169         if (IS_ERR(lvds->regs)) {
170                 dev_err(&pdev->dev, "ioremap reg failed\n");
171                 return PTR_ERR(lvds->regs);
172         }
173         lvds->pclk = devm_clk_get(&pdev->dev,"pclk_lvds");
174         if (IS_ERR(lvds->pclk)) {
175                 dev_err(&pdev->dev, "get clk failed\n");
176                 return PTR_ERR(lvds->pclk);
177         }
178         lvds->pd = devm_clk_get(&pdev->dev,"pd_lvds");
179         if (IS_ERR(lvds->pd)) {
180                 dev_err(&pdev->dev, "get clk failed\n");
181                 return PTR_ERR(lvds->pd);
182         }       
183         if (support_uboot_display()) {
184                 rk32_lvds_clk_enable(lvds);
185         }
186
187         rk32_lvds = lvds;
188         rk_fb_trsm_ops_register(&trsm_lvds_ops,SCREEN_LVDS);
189         dev_info(&pdev->dev, "rk32 lvds driver probe success\n");
190
191         return 0;
192 }
193
194 static void rk32_lvds_shutdown(struct platform_device *pdev)
195 {
196
197 }
198
199 #if defined(CONFIG_OF)
200 static const struct of_device_id rk32_lvds_dt_ids[] = {
201         {.compatible = "rockchip,rk32-lvds",},
202         {}
203 };
204
205 MODULE_DEVICE_TABLE(of, rk32_lvds_dt_ids);
206 #endif
207
208 static struct platform_driver rk32_lvds_driver = {
209         .probe = rk32_lvds_probe,
210         .driver = {
211                    .name = "rk32-lvds",
212                    .owner = THIS_MODULE,
213 #if defined(CONFIG_OF)
214                    .of_match_table = of_match_ptr(rk32_lvds_dt_ids),
215 #endif
216         },
217         .shutdown = rk32_lvds_shutdown,
218 };
219
220 static int __init rk32_lvds_module_init(void)
221 {
222         return platform_driver_register(&rk32_lvds_driver);
223 }
224
225 static void __exit rk32_lvds_module_exit(void)
226 {
227
228 }
229
230 fs_initcall(rk32_lvds_module_init);
231 module_exit(rk32_lvds_module_exit);
232