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>
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"
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)
21 static struct rk32_lvds *rk32_lvds;
23 static int rk32_lvds_clk_enable(struct rk32_lvds *lvds)
26 clk_prepare_enable(lvds->pd);
27 clk_prepare_enable(lvds->pclk);
34 static int rk32_lvds_clk_disable(struct rk32_lvds *lvds)
37 clk_disable_unprepare(lvds->pclk);
38 clk_disable_unprepare(lvds->pd);
45 static int rk32_lvds_disable(void)
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);
55 static int rk32_lvds_en(void)
57 struct rk32_lvds *lvds = rk32_lvds;
58 struct rk_screen *screen = &lvds->screen;
62 rk_fb_get_prmry_screen(screen);
65 rk32_lvds_clk_enable(lvds);
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);
71 val = LVDS_SEL_VOP_LIT << 16;
72 grf_writel(val, RK3288_GRF_SOC_CON6);
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))
82 else if (screen->type == SCREEN_RGB)
83 val = LVDS_TTL_EN | LVDS_CH0_EN | LVDS_CH1_EN;
85 h_bp = screen->mode.hsync_len + screen->mode.left_margin;
87 val |= LVDS_START_PHASE_RST_1;
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);
94 if (screen->type == SCREEN_RGB) {
95 val = 0x007f007f;//0x1<<6 |0x1 <<4;
96 grf_writel(val, RK3288_GRF_GPIO1D_IOMUX);
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);
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*/
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);
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*/
133 static struct rk_fb_trsm_ops trsm_lvds_ops = {
134 .enable = rk32_lvds_en,
135 .disable = rk32_lvds_disable,
138 static int rk32_lvds_probe(struct platform_device *pdev)
140 struct rk32_lvds *lvds;
141 struct resource *res;
142 struct device_node *np = pdev->dev.of_node;
145 dev_err(&pdev->dev, "Missing device tree node.\n");
149 lvds = devm_kzalloc(&pdev->dev, sizeof(struct rk32_lvds), GFP_KERNEL);
151 dev_err(&pdev->dev, "no memory for state\n");
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);
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);
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);
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);
183 if (support_uboot_display()) {
184 rk32_lvds_clk_enable(lvds);
188 rk_fb_trsm_ops_register(&trsm_lvds_ops,SCREEN_LVDS);
189 dev_info(&pdev->dev, "rk32 lvds driver probe success\n");
194 static void rk32_lvds_shutdown(struct platform_device *pdev)
199 #if defined(CONFIG_OF)
200 static const struct of_device_id rk32_lvds_dt_ids[] = {
201 {.compatible = "rockchip,rk32-lvds",},
205 MODULE_DEVICE_TABLE(of, rk32_lvds_dt_ids);
208 static struct platform_driver rk32_lvds_driver = {
209 .probe = rk32_lvds_probe,
212 .owner = THIS_MODULE,
213 #if defined(CONFIG_OF)
214 .of_match_table = of_match_ptr(rk32_lvds_dt_ids),
217 .shutdown = rk32_lvds_shutdown,
220 static int __init rk32_lvds_module_init(void)
222 return platform_driver_register(&rk32_lvds_driver);
225 static void __exit rk32_lvds_module_exit(void)
230 fs_initcall(rk32_lvds_module_init);
231 module_exit(rk32_lvds_module_exit);