2 * Copyright (c) 2017 Rockchip Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 #include <linux/clk.h>
15 #include <linux/delay.h>
16 #include <linux/init.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/phy/phy.h>
21 #include <linux/platform_device.h>
22 #include <linux/regmap.h>
23 #include <linux/reset.h>
25 #include <drm/drm_mipi_dsi.h>
27 #include <video/mipi_display.h>
28 #include <video/of_videomode.h>
29 #include <video/videomode.h>
31 #define DRV_NAME "inno-mipi-dphy"
33 #define INNO_PHY_LANE_CTRL 0x00000
34 #define INNO_PHY_POWER_CTRL 0x00004
35 #define INNO_PHY_PLL_CTRL_0 0x0000c
36 #define INNO_PHY_PLL_CTRL_1 0x00010
37 #define INNO_PHY_DIG_CTRL 0x00080
38 #define INNO_PHY_PIN_CTRL 0x00084
40 #define INNO_CLOCK_LANE_REG_BASE 0x00100
41 #define INNO_DATA_LANE_0_REG_BASE 0x00180
42 #define INNO_DATA_LANE_1_REG_BASE 0x00200
43 #define INNO_DATA_LANE_2_REG_BASE 0x00280
44 #define INNO_DATA_LANE_3_REG_BASE 0x00300
46 #define T_LPX_OFFSET 0x00014
47 #define T_HS_PREPARE_OFFSET 0x00018
48 #define T_HS_ZERO_OFFSET 0x0001c
49 #define T_HS_TRAIL_OFFSET 0x00020
50 #define T_HS_EXIT_OFFSET 0x00024
51 #define T_CLK_POST_OFFSET 0x00028
52 #define T_WAKUP_H_OFFSET 0x00030
53 #define T_WAKUP_L_OFFSET 0x00034
54 #define T_CLK_PRE_OFFSET 0x00038
55 #define T_TA_GO_OFFSET 0x00040
56 #define T_TA_SURE_OFFSET 0x00044
57 #define T_TA_WAIT_OFFSET 0x00048
59 #define CLK_LANE_EN_MASK BIT(6)
60 #define DATA_LANE_3_EN_MASK BIT(5)
61 #define DATA_LANE_2_EN_MASK BIT(4)
62 #define DATA_LANE_1_EN_MASK BIT(3)
63 #define DATA_LANE_0_EN_MASK BIT(2)
64 #define CLK_LANE_EN BIT(6)
65 #define DATA_LANE_3_EN BIT(5)
66 #define DATA_LANE_2_EN BIT(4)
67 #define DATA_LANE_1_EN BIT(3)
68 #define DATA_LANE_0_EN BIT(2)
69 #define FBDIV_8(x) (((x) & 0x1) << 5)
70 #define PREDIV(x) (((x) & 0x1f) << 0)
71 #define FBDIV_7_0(x) (((x) & 0xff) << 0)
72 #define T_LPX(x) (((x) & 0x3f) << 0)
73 #define T_HS_PREPARE(x) (((x) & 0x7f) << 0)
74 #define T_HS_ZERO(x) (((x) & 0x3f) << 0)
75 #define T_HS_TRAIL(x) (((x) & 0x7f) << 0)
76 #define T_HS_EXIT(x) (((x) & 0x1f) << 0)
77 #define T_CLK_POST(x) (((x) & 0xf) << 0)
78 #define T_WAKUP_H(x) (((x) & 0x3) << 0)
79 #define T_WAKUP_L(x) (((x) & 0xff) << 0)
80 #define T_CLK_PRE(x) (((x) & 0xf) << 0)
81 #define T_TA_GO(x) (((x) & 0x3f) << 0)
82 #define T_TA_SURE(x) (((x) & 0x3f) << 0)
83 #define T_TA_WAIT(x) (((x) & 0x3f) << 0)
93 static const u32 lane_reg_offset[] = {
94 [CLOCK_LANE] = INNO_CLOCK_LANE_REG_BASE,
95 [DATA_LANE_0] = INNO_DATA_LANE_0_REG_BASE,
96 [DATA_LANE_1] = INNO_DATA_LANE_1_REG_BASE,
97 [DATA_LANE_2] = INNO_DATA_LANE_2_REG_BASE,
98 [DATA_LANE_3] = INNO_DATA_LANE_3_REG_BASE,
102 HS_CLK_RANGE_80_110_MHZ,
103 HS_CLK_RANGE_110_150_MHZ,
104 HS_CLK_RANGE_150_200_MHZ,
105 HS_CLK_RANGE_200_250_MHZ,
106 HS_CLK_RANGE_250_300_MHZ,
107 HS_CLK_RANGE_300_400_MHZ,
108 HS_CLK_RANGE_400_500_MHZ,
109 HS_CLK_RANGE_500_600_MHZ,
110 HS_CLK_RANGE_600_700_MHZ,
111 HS_CLK_RANGE_700_800_MHZ,
112 HS_CLK_RANGE_800_1000_MHZ,
115 static const u8 t_hs_prepare_val[] = {
116 [HS_CLK_RANGE_80_110_MHZ] = 0x20,
117 [HS_CLK_RANGE_110_150_MHZ] = 0x06,
118 [HS_CLK_RANGE_150_200_MHZ] = 0x18,
119 [HS_CLK_RANGE_200_250_MHZ] = 0x05,
120 [HS_CLK_RANGE_250_300_MHZ] = 0x51,
121 [HS_CLK_RANGE_300_400_MHZ] = 0x64,
122 [HS_CLK_RANGE_400_500_MHZ] = 0x20,
123 [HS_CLK_RANGE_500_600_MHZ] = 0x6a,
124 [HS_CLK_RANGE_600_700_MHZ] = 0x3e,
125 [HS_CLK_RANGE_700_800_MHZ] = 0x21,
126 [HS_CLK_RANGE_800_1000_MHZ] = 0x09,
129 static const u8 clock_lane_t_hs_zero_val[] = {
130 [HS_CLK_RANGE_80_110_MHZ] = 0x16,
131 [HS_CLK_RANGE_110_150_MHZ] = 0x16,
132 [HS_CLK_RANGE_150_200_MHZ] = 0x17,
133 [HS_CLK_RANGE_200_250_MHZ] = 0x17,
134 [HS_CLK_RANGE_250_300_MHZ] = 0x18,
135 [HS_CLK_RANGE_300_400_MHZ] = 0x19,
136 [HS_CLK_RANGE_400_500_MHZ] = 0x1b,
137 [HS_CLK_RANGE_500_600_MHZ] = 0x1d,
138 [HS_CLK_RANGE_600_700_MHZ] = 0x1e,
139 [HS_CLK_RANGE_700_800_MHZ] = 0x1f,
140 [HS_CLK_RANGE_800_1000_MHZ] = 0x20,
143 static const u8 data_lane_t_hs_zero_val[] = {
144 [HS_CLK_RANGE_80_110_MHZ] = 2,
145 [HS_CLK_RANGE_110_150_MHZ] = 3,
146 [HS_CLK_RANGE_150_200_MHZ] = 4,
147 [HS_CLK_RANGE_200_250_MHZ] = 5,
148 [HS_CLK_RANGE_250_300_MHZ] = 6,
149 [HS_CLK_RANGE_300_400_MHZ] = 7,
150 [HS_CLK_RANGE_400_500_MHZ] = 7,
151 [HS_CLK_RANGE_500_600_MHZ] = 8,
152 [HS_CLK_RANGE_600_700_MHZ] = 8,
153 [HS_CLK_RANGE_700_800_MHZ] = 9,
154 [HS_CLK_RANGE_800_1000_MHZ] = 9,
157 static const u8 t_hs_trail_val[] = {
158 [HS_CLK_RANGE_80_110_MHZ] = 0x22,
159 [HS_CLK_RANGE_110_150_MHZ] = 0x45,
160 [HS_CLK_RANGE_150_200_MHZ] = 0x0b,
161 [HS_CLK_RANGE_200_250_MHZ] = 0x16,
162 [HS_CLK_RANGE_250_300_MHZ] = 0x2c,
163 [HS_CLK_RANGE_300_400_MHZ] = 0x33,
164 [HS_CLK_RANGE_400_500_MHZ] = 0x4e,
165 [HS_CLK_RANGE_500_600_MHZ] = 0x3a,
166 [HS_CLK_RANGE_600_700_MHZ] = 0x6a,
167 [HS_CLK_RANGE_700_800_MHZ] = 0x29,
168 [HS_CLK_RANGE_800_1000_MHZ] = 0x27,
171 struct mipi_dphy_timing {
172 unsigned int clkmiss;
173 unsigned int clkpost;
175 unsigned int clkprepare;
176 unsigned int clksettle;
177 unsigned int clktermen;
178 unsigned int clktrail;
179 unsigned int clkzero;
180 unsigned int dtermen;
183 unsigned int hsprepare;
185 unsigned int hssettle;
187 unsigned int hstrail;
196 struct inno_mipi_dphy_timing {
216 struct inno_mipi_dphy {
222 struct reset_control *rst;
224 struct dsi_panel *panel;
229 static inline void inno_write(struct inno_mipi_dphy *inno, u32 reg, u32 val)
231 writel_relaxed(val, inno->regs + reg);
234 static inline u32 inno_read(struct inno_mipi_dphy *inno, u32 reg)
236 return readl_relaxed(inno->regs + reg);
239 static inline void inno_update_bits(struct inno_mipi_dphy *inno, u32 reg,
244 orig = inno_read(inno, reg);
247 inno_write(inno, reg, tmp);
250 static void mipi_dphy_timing_get_default(struct mipi_dphy_timing *timing,
251 unsigned long period)
253 /* Global Operation Timing Parameters */
255 timing->clkpost = 70 + 52 * period;
257 timing->clkprepare = 65;
258 timing->clksettle = 95;
259 timing->clktermen = 0;
260 timing->clktrail = 80;
261 timing->clkzero = 260;
264 timing->hsexit = 120;
265 timing->hsprepare = 65 + 5 * period;
266 timing->hszero = 145 + 5 * period;
267 timing->hssettle = 85 + 6 * period;
269 timing->hstrail = max(4 * 8 * period, 60 + 4 * 4 * period);
270 timing->init = 100000;
272 timing->taget = 5 * timing->lpx;
273 timing->tago = 4 * timing->lpx;
274 timing->tasure = timing->lpx;
275 timing->wakeup = 1000000;
278 static void inno_mipi_dphy_timing_update(struct inno_mipi_dphy *inno,
279 enum lane_type lane_type,
280 struct inno_mipi_dphy_timing *t)
282 u32 base = lane_reg_offset[lane_type];
284 inno_write(inno, base + T_HS_PREPARE_OFFSET,
285 T_HS_PREPARE(t->t_hs_prepare));
286 inno_write(inno, base + T_HS_ZERO_OFFSET, T_HS_ZERO(t->t_hs_zero));
287 inno_write(inno, base + T_HS_TRAIL_OFFSET, T_HS_TRAIL(t->t_hs_trail));
288 inno_write(inno, base + T_HS_EXIT_OFFSET, T_HS_EXIT(t->t_hs_exit));
289 inno_write(inno, base + T_CLK_POST_OFFSET, T_CLK_POST(t->t_clk_post));
290 inno_write(inno, base + T_CLK_PRE_OFFSET, T_CLK_PRE(t->t_clk_pre));
291 inno_write(inno, base + T_WAKUP_H_OFFSET, T_WAKUP_H(t->t_wakup_h));
292 inno_write(inno, base + T_WAKUP_L_OFFSET, T_WAKUP_L(t->t_wakup_l));
293 inno_write(inno, base + T_LPX_OFFSET, T_LPX(t->t_lpx));
294 inno_write(inno, base + T_TA_GO_OFFSET, T_TA_GO(t->t_ta_go));
295 inno_write(inno, base + T_TA_SURE_OFFSET, T_TA_SURE(t->t_ta_sure));
296 inno_write(inno, base + T_TA_WAIT_OFFSET, T_TA_WAIT(t->t_ta_wait));
299 static enum hs_clk_range inno_mipi_dphy_get_hs_clk_range(u32 lane_mbps)
302 return HS_CLK_RANGE_80_110_MHZ;
303 else if (lane_mbps < 150)
304 return HS_CLK_RANGE_110_150_MHZ;
305 else if (lane_mbps < 200)
306 return HS_CLK_RANGE_150_200_MHZ;
307 else if (lane_mbps < 250)
308 return HS_CLK_RANGE_200_250_MHZ;
309 else if (lane_mbps < 300)
310 return HS_CLK_RANGE_250_300_MHZ;
311 else if (lane_mbps < 400)
312 return HS_CLK_RANGE_400_500_MHZ;
313 else if (lane_mbps < 500)
314 return HS_CLK_RANGE_400_500_MHZ;
315 else if (lane_mbps < 600)
316 return HS_CLK_RANGE_500_600_MHZ;
317 else if (lane_mbps < 700)
318 return HS_CLK_RANGE_600_700_MHZ;
319 else if (lane_mbps < 800)
320 return HS_CLK_RANGE_700_800_MHZ;
322 return HS_CLK_RANGE_800_1000_MHZ;
325 static void inno_mipi_dphy_lane_timing_init(struct inno_mipi_dphy *inno,
326 enum lane_type lane_type)
328 struct mipi_dphy_timing timing;
329 struct inno_mipi_dphy_timing data;
330 u32 txbyteclkhs = inno->lane_mbps / 8; /* MHz */
331 u32 txclkesc = 20; /* MHz */
332 u32 UI = DIV_ROUND_CLOSEST(NSEC_PER_USEC, inno->lane_mbps); /* ns */
333 enum hs_clk_range range;
335 memset(&timing, 0, sizeof(timing));
336 memset(&data, 0, sizeof(data));
338 mipi_dphy_timing_get_default(&timing, UI);
340 range = inno_mipi_dphy_get_hs_clk_range(inno->lane_mbps);
342 if (lane_type == CLOCK_LANE)
343 data.t_hs_zero = clock_lane_t_hs_zero_val[range];
345 data.t_hs_zero = data_lane_t_hs_zero_val[range];
347 data.t_hs_prepare = t_hs_prepare_val[range];
348 data.t_hs_trail = t_hs_trail_val[range];
350 /* txbyteclkhs domain */
351 data.t_hs_exit = DIV_ROUND_UP(txbyteclkhs * timing.hsexit,
353 data.t_clk_post = DIV_ROUND_UP(txbyteclkhs * timing.clkpost,
355 data.t_clk_pre = DIV_ROUND_UP(txbyteclkhs * timing.clkpre,
357 data.t_wakup_h = 0x3;
358 data.t_wakup_l = 0xff;
359 data.t_lpx = txbyteclkhs * timing.lpx / NSEC_PER_USEC;
361 /* txclkesc domain */
362 data.t_ta_go = DIV_ROUND_UP(txclkesc * timing.tago, NSEC_PER_USEC);
363 data.t_ta_sure = DIV_ROUND_UP(txclkesc * timing.tasure, NSEC_PER_USEC);
364 data.t_ta_wait = DIV_ROUND_UP(txclkesc * timing.taget, NSEC_PER_USEC);
366 inno_mipi_dphy_timing_update(inno, lane_type, &data);
369 static void inno_mipi_dphy_pll_init(struct inno_mipi_dphy *inno)
371 struct dsi_panel *panel = inno->panel;
373 unsigned int mpclk, pllref, tmp;
374 unsigned int target_mbps = 1000;
375 unsigned int max_mbps = 1000;
376 u32 fbdiv = 1, prediv = 1;
379 mpclk = DIV_ROUND_UP(panel->vm.pixelclock, USEC_PER_SEC);
381 /* take 1 / 0.9, since mbps must big than bandwidth of RGB */
382 tmp = mpclk * (panel->bpp / inno->lanes) * 10 / 9;
386 dev_err(inno->dev, "DPHY clock frequency is out of range\n");
389 pllref = DIV_ROUND_UP(clk_get_rate(inno->ref_clk) / 2, USEC_PER_SEC);
392 for (i = 1; i < 6; i++) {
394 if ((tmp > (target_mbps % pre)) && (target_mbps / pre < 512)) {
395 tmp = target_mbps % pre;
397 fbdiv = target_mbps / pre;
403 inno->lane_mbps = pllref * fbdiv / prediv;
404 phy_set_bus_width(inno->phy, inno->lane_mbps);
406 val = FBDIV_8(fbdiv >> 8) | PREDIV(prediv);
407 inno_write(inno, INNO_PHY_PLL_CTRL_0, val);
409 val = FBDIV_7_0(fbdiv);
410 inno_write(inno, INNO_PHY_PLL_CTRL_1, val);
412 dev_info(inno->dev, "fin=%d, fout=%d, prediv=%d, fbdiv=%d\n",
413 pllref, inno->lane_mbps, prediv, fbdiv);
416 static void inno_mipi_dphy_reset(struct inno_mipi_dphy *inno)
419 inno_write(inno, INNO_PHY_POWER_CTRL, 0xe0);
422 inno_write(inno, INNO_PHY_DIG_CTRL, 0x1e);
424 inno_write(inno, INNO_PHY_DIG_CTRL, 0x1f);
428 static void inno_mipi_dphy_timing_init(struct inno_mipi_dphy *inno)
430 switch (inno->lanes) {
432 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_3);
435 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_2);
438 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_1);
442 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_0);
443 inno_mipi_dphy_lane_timing_init(inno, CLOCK_LANE);
448 static inline void inno_mipi_dphy_lane_enable(struct inno_mipi_dphy *inno)
453 switch (inno->lanes) {
455 mask |= DATA_LANE_3_EN_MASK;
456 val |= DATA_LANE_3_EN;
459 mask |= DATA_LANE_2_EN_MASK;
460 val |= DATA_LANE_2_EN;
463 mask |= DATA_LANE_1_EN_MASK;
464 val |= DATA_LANE_1_EN;
468 mask |= DATA_LANE_0_EN_MASK | CLK_LANE_EN_MASK;
469 val |= DATA_LANE_0_EN | CLK_LANE_EN;
473 inno_update_bits(inno, INNO_PHY_LANE_CTRL, mask, val);
476 static inline void inno_mipi_dphy_pll_ldo_enable(struct inno_mipi_dphy *inno)
478 inno_write(inno, INNO_PHY_POWER_CTRL, 0xe4);
482 static int inno_mipi_dphy_power_on(struct phy *phy)
484 struct inno_mipi_dphy *inno = phy_get_drvdata(phy);
486 clk_prepare_enable(inno->ref_clk);
487 clk_prepare_enable(inno->pclk);
490 /* MIPI DSI PHY APB software reset request. */
491 reset_control_assert(inno->rst);
492 usleep_range(20, 40);
493 reset_control_deassert(inno->rst);
496 inno_mipi_dphy_pll_init(inno);
497 inno_mipi_dphy_pll_ldo_enable(inno);
498 inno_mipi_dphy_lane_enable(inno);
499 inno_mipi_dphy_reset(inno);
500 inno_mipi_dphy_timing_init(inno);
502 dev_info(inno->dev, "Inno MIPI-DPHY Power-On\n");
507 static inline void inno_mipi_dphy_lane_disable(struct inno_mipi_dphy *inno)
509 inno_update_bits(inno, INNO_PHY_LANE_CTRL, 0x7c, 0x00);
512 static inline void inno_mipi_dphy_pll_ldo_disable(struct inno_mipi_dphy *inno)
514 inno_write(inno, INNO_PHY_POWER_CTRL, 0xe3);
518 static int inno_mipi_dphy_power_off(struct phy *phy)
520 struct inno_mipi_dphy *inno = phy_get_drvdata(phy);
522 inno_mipi_dphy_lane_disable(inno);
523 inno_mipi_dphy_pll_ldo_disable(inno);
525 clk_disable_unprepare(inno->pclk);
526 clk_disable_unprepare(inno->ref_clk);
528 dev_info(inno->dev, "Inno MIPI-DPHY Power-Off\n");
533 static const struct phy_ops inno_mipi_dphy_ops = {
534 .power_on = inno_mipi_dphy_power_on,
535 .power_off = inno_mipi_dphy_power_off,
536 .owner = THIS_MODULE,
539 static int get_bpp(struct device_node *np)
543 if (of_property_read_u32(np, "dsi,format", &format))
547 case MIPI_DSI_FMT_RGB666_PACKED:
549 case MIPI_DSI_FMT_RGB565:
551 case MIPI_DSI_FMT_RGB888:
552 case MIPI_DSI_FMT_RGB666:
558 static int inno_mipi_dphy_parse_dt(struct device_node *np,
559 struct inno_mipi_dphy *inno)
561 struct device_node *panel_node;
562 struct dsi_panel *panel;
565 panel_node = of_parse_phandle(np, "rockchip,dsi-panel", 0);
567 dev_err(inno->dev, "Missing 'rockchip,dsi-panel' property");
571 panel = devm_kzalloc(inno->dev, sizeof(*panel), GFP_KERNEL);
577 ret = of_get_videomode(panel_node, &panel->vm, 0);
581 panel->bpp = get_bpp(panel_node);
583 if (of_property_read_u32(panel_node, "dsi,lanes", &inno->lanes))
586 of_node_put(panel_node);
593 of_node_put(panel_node);
597 static int inno_mipi_dphy_probe(struct platform_device *pdev)
599 struct device_node *np = pdev->dev.of_node;
600 struct inno_mipi_dphy *inno;
601 struct phy_provider *phy_provider;
602 struct resource *res;
605 inno = devm_kzalloc(&pdev->dev, sizeof(*inno), GFP_KERNEL);
609 inno->dev = &pdev->dev;
610 platform_set_drvdata(pdev, inno);
612 ret = inno_mipi_dphy_parse_dt(np, inno);
614 dev_err(&pdev->dev, "failed to parse DT\n");
618 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
619 inno->regs = devm_ioremap_resource(&pdev->dev, res);
620 if (IS_ERR(inno->regs))
621 return PTR_ERR(inno->regs);
623 inno->ref_clk = devm_clk_get(&pdev->dev, "ref");
624 if (IS_ERR(inno->ref_clk)) {
625 dev_err(&pdev->dev, "failed to get mipi dphy ref clk\n");
626 return PTR_ERR(inno->ref_clk);
629 clk_set_rate(inno->ref_clk, 24000000);
631 inno->pclk = devm_clk_get(&pdev->dev, "pclk");
632 if (IS_ERR(inno->pclk)) {
633 dev_err(&pdev->dev, "failed to get mipi dphy pclk\n");
634 return PTR_ERR(inno->pclk);
637 inno->rst = devm_reset_control_get_optional(&pdev->dev, "apb");
638 if (IS_ERR(inno->rst)) {
639 dev_info(&pdev->dev, "No reset control specified\n");
643 inno->phy = devm_phy_create(&pdev->dev, NULL, &inno_mipi_dphy_ops);
644 if (IS_ERR(inno->phy)) {
645 dev_err(&pdev->dev, "failed to create MIPI D-PHY\n");
646 return PTR_ERR(inno->phy);
649 phy_set_drvdata(inno->phy, inno);
651 phy_provider = devm_of_phy_provider_register(&pdev->dev,
652 of_phy_simple_xlate);
653 if (IS_ERR(phy_provider)) {
654 dev_err(&pdev->dev, "failed to register phy provider\n");
655 return PTR_ERR(phy_provider);
658 dev_info(&pdev->dev, "Inno MIPI-DPHY Driver Probe\n");
663 static const struct of_device_id inno_mipi_dphy_of_match[] = {
664 { .compatible = "rockchip,rk3368-mipi-dphy", },
667 MODULE_DEVICE_TABLE(of, inno_mipi_dphy_of_match);
669 static struct platform_driver inno_mipi_dphy_driver = {
670 .probe = inno_mipi_dphy_probe,
673 .of_match_table = inno_mipi_dphy_of_match,
677 module_platform_driver(inno_mipi_dphy_driver);
679 MODULE_DESCRIPTION("Innosilicon MIPI D-PHY Driver");
680 MODULE_LICENSE("GPL v2");