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 val |= LVDS_DUAL | LVDS_CH0_EN | LVDS_CH1_EN;
78 else if(screen->type == SCREEN_LVDS)
80 else if (screen->type == SCREEN_RGB)
81 val |= LVDS_TTL_EN | LVDS_CH0_EN | LVDS_CH1_EN;
83 h_bp = screen->mode.hsync_len + screen->mode.left_margin;
85 val |= LVDS_START_PHASE_RST_1;
87 val |= (screen->pin_dclk << 8) | (screen->pin_hsync << 9) |
88 (screen->pin_den << 10);
89 val |= (0xffff << 16);
90 grf_writel(val, RK3288_GRF_SOC_CON7);
92 if (screen->type == SCREEN_RGB) {
93 val = 0x007f007f;//0x1<<6 |0x1 <<4;
94 grf_writel(val, RK3288_GRF_GPIO1D_IOMUX);
96 lvds_writel(lvds, LVDS_CH0_REG_0, 0x7f);
97 lvds_writel(lvds, LVDS_CH0_REG_1, 0x40);
98 lvds_writel(lvds, LVDS_CH0_REG_2, 0x00);
100 lvds_writel(lvds, LVDS_CH0_REG_4, 0x3f);
101 lvds_writel(lvds, LVDS_CH0_REG_5, 0x3f);
102 lvds_writel(lvds, LVDS_CH0_REG_3, 0x46);
103 lvds_writel(lvds, LVDS_CH0_REG_d, 0x0a);
104 lvds_writel(lvds, LVDS_CH0_REG_20,0x44);/* 44:LSB 45:MSB*/
105 writel_relaxed(0x00, lvds->regs + LVDS_CFG_REG_c); /*eanble pll*/
106 writel_relaxed(0x92, lvds->regs + LVDS_CFG_REG_21); /*enable tx*/
108 lvds_writel(lvds, 0x100, 0x7f);
109 lvds_writel(lvds, 0x104, 0x40);
110 lvds_writel(lvds, 0x108, 0x00);
111 lvds_writel(lvds, 0x10c, 0x46);
112 lvds_writel(lvds, 0x110, 0x3f);
113 lvds_writel(lvds, 0x114, 0x3f);
114 lvds_writel(lvds, 0x134, 0x0a);
116 lvds_writel(lvds, LVDS_CH0_REG_0, 0xbf);
117 lvds_writel(lvds, LVDS_CH0_REG_1, 0x3f);
118 lvds_writel(lvds, LVDS_CH0_REG_2, 0xfe);
119 lvds_writel(lvds, LVDS_CH0_REG_3, 0x46);
120 lvds_writel(lvds, LVDS_CH0_REG_4, 0x00);
121 lvds_writel(lvds, LVDS_CH0_REG_d, 0x0a);
122 lvds_writel(lvds, LVDS_CH0_REG_20,0x44);/* 44:LSB 45:MSB*/
123 writel_relaxed(0x00, lvds->regs + LVDS_CFG_REG_c); /*eanble pll*/
124 writel_relaxed(0x92, lvds->regs + LVDS_CFG_REG_21); /*enable tx*/
131 static struct rk_fb_trsm_ops trsm_lvds_ops = {
132 .enable = rk32_lvds_en,
133 .disable = rk32_lvds_disable,
136 static int rk32_lvds_probe(struct platform_device *pdev)
138 struct rk32_lvds *lvds;
139 struct resource *res;
140 struct device_node *np = pdev->dev.of_node;
143 dev_err(&pdev->dev, "Missing device tree node.\n");
147 lvds = devm_kzalloc(&pdev->dev, sizeof(struct rk32_lvds), GFP_KERNEL);
149 dev_err(&pdev->dev, "no memory for state\n");
152 lvds->dev = &pdev->dev;
153 rk_fb_get_prmry_screen(&lvds->screen);
154 if ((lvds->screen.type != SCREEN_RGB) &&
155 (lvds->screen.type != SCREEN_LVDS) &&
156 (lvds->screen.type != SCREEN_DUAL_LVDS)) {
157 dev_err(&pdev->dev, "screen is not lvds/rgb!\n");
158 writel_relaxed(0xffff8000, RK_GRF_VIRT + RK3288_GRF_SOC_CON7);
161 platform_set_drvdata(pdev, lvds);
162 dev_set_name(lvds->dev, "rk32-lvds");
163 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
164 lvds->regs = devm_ioremap_resource(&pdev->dev, res);
165 if (IS_ERR(lvds->regs)) {
166 dev_err(&pdev->dev, "ioremap reg failed\n");
167 return PTR_ERR(lvds->regs);
169 lvds->pclk = devm_clk_get(&pdev->dev,"pclk_lvds");
170 if (IS_ERR(lvds->pclk)) {
171 dev_err(&pdev->dev, "get clk failed\n");
172 return PTR_ERR(lvds->pclk);
174 lvds->pd = devm_clk_get(&pdev->dev,"pd_lvds");
175 if (IS_ERR(lvds->pd)) {
176 dev_err(&pdev->dev, "get clk failed\n");
177 return PTR_ERR(lvds->pd);
179 if (support_uboot_display()) {
180 rk32_lvds_clk_enable(lvds);
184 rk_fb_trsm_ops_register(&trsm_lvds_ops,SCREEN_LVDS);
185 dev_info(&pdev->dev, "rk32 lvds driver probe success\n");
190 static void rk32_lvds_shutdown(struct platform_device *pdev)
195 #if defined(CONFIG_OF)
196 static const struct of_device_id rk32_lvds_dt_ids[] = {
197 {.compatible = "rockchip,rk32-lvds",},
201 MODULE_DEVICE_TABLE(of, rk32_lvds_dt_ids);
204 static struct platform_driver rk32_lvds_driver = {
205 .probe = rk32_lvds_probe,
208 .owner = THIS_MODULE,
209 #if defined(CONFIG_OF)
210 .of_match_table = of_match_ptr(rk32_lvds_dt_ids),
213 .shutdown = rk32_lvds_shutdown,
216 static int __init rk32_lvds_module_init(void)
218 return platform_driver_register(&rk32_lvds_driver);
221 static void __exit rk32_lvds_module_exit(void)
226 fs_initcall(rk32_lvds_module_init);
227 module_exit(rk32_lvds_module_exit);