1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
3*4882a593Smuzhiyun * Author: Eric Gao <eric.gao@rock-chips.com>
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <common.h>
9*4882a593Smuzhiyun #include <clk.h>
10*4882a593Smuzhiyun #include <display.h>
11*4882a593Smuzhiyun #include <dm.h>
12*4882a593Smuzhiyun #include <fdtdec.h>
13*4882a593Smuzhiyun #include <panel.h>
14*4882a593Smuzhiyun #include <regmap.h>
15*4882a593Smuzhiyun #include "rk_mipi.h"
16*4882a593Smuzhiyun #include <syscon.h>
17*4882a593Smuzhiyun #include <asm/gpio.h>
18*4882a593Smuzhiyun #include <asm/hardware.h>
19*4882a593Smuzhiyun #include <asm/io.h>
20*4882a593Smuzhiyun #include <dm/uclass-internal.h>
21*4882a593Smuzhiyun #include <linux/kernel.h>
22*4882a593Smuzhiyun #include <asm/arch/clock.h>
23*4882a593Smuzhiyun #include <asm/arch/cru_rk3399.h>
24*4882a593Smuzhiyun #include <asm/arch/grf_rk3399.h>
25*4882a593Smuzhiyun #include <asm/arch/rockchip_mipi_dsi.h>
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
28*4882a593Smuzhiyun
rk_mipi_read_timing(struct udevice * dev,struct display_timing * timing)29*4882a593Smuzhiyun int rk_mipi_read_timing(struct udevice *dev,
30*4882a593Smuzhiyun struct display_timing *timing)
31*4882a593Smuzhiyun {
32*4882a593Smuzhiyun int ret;
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun ret = fdtdec_decode_display_timing(gd->fdt_blob, dev_of_offset(dev),
35*4882a593Smuzhiyun 0, timing);
36*4882a593Smuzhiyun if (ret) {
37*4882a593Smuzhiyun debug("%s: Failed to decode display timing (ret=%d)\n",
38*4882a593Smuzhiyun __func__, ret);
39*4882a593Smuzhiyun return -EINVAL;
40*4882a593Smuzhiyun }
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun return 0;
43*4882a593Smuzhiyun }
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun /*
46*4882a593Smuzhiyun * Register write function used only for mipi dsi controller.
47*4882a593Smuzhiyun * Parameter:
48*4882a593Smuzhiyun * @regs: mipi controller address
49*4882a593Smuzhiyun * @reg: combination of regaddr(16bit)|bitswidth(8bit)|offset(8bit) you can
50*4882a593Smuzhiyun * use define in rk_mipi.h directly for this parameter
51*4882a593Smuzhiyun * @val: value that will be write to specified bits of register
52*4882a593Smuzhiyun */
rk_mipi_dsi_write(uintptr_t regs,u32 reg,u32 val)53*4882a593Smuzhiyun static void rk_mipi_dsi_write(uintptr_t regs, u32 reg, u32 val)
54*4882a593Smuzhiyun {
55*4882a593Smuzhiyun u32 dat;
56*4882a593Smuzhiyun u32 mask;
57*4882a593Smuzhiyun u32 offset = (reg >> OFFSET_SHIFT) & 0xff;
58*4882a593Smuzhiyun u32 bits = (reg >> BITS_SHIFT) & 0xff;
59*4882a593Smuzhiyun uintptr_t addr = (reg >> ADDR_SHIFT) + regs;
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun /* Mask for specifiled bits,the corresponding bits will be clear */
62*4882a593Smuzhiyun mask = ~((0xffffffff << offset) & (0xffffffff >> (32 - offset - bits)));
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun /* Make sure val in the available range */
65*4882a593Smuzhiyun val &= ~(0xffffffff << bits);
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun /* Get register's original val */
68*4882a593Smuzhiyun dat = readl(addr);
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun /* Clear specified bits */
71*4882a593Smuzhiyun dat &= mask;
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun /* Fill specified bits */
74*4882a593Smuzhiyun dat |= val << offset;
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun writel(dat, addr);
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun
rk_mipi_dsi_enable(struct udevice * dev,const struct display_timing * timing)79*4882a593Smuzhiyun int rk_mipi_dsi_enable(struct udevice *dev,
80*4882a593Smuzhiyun const struct display_timing *timing)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun int node, timing_node;
83*4882a593Smuzhiyun int val;
84*4882a593Smuzhiyun struct rk_mipi_priv *priv = dev_get_priv(dev);
85*4882a593Smuzhiyun uintptr_t regs = priv->regs;
86*4882a593Smuzhiyun u32 txbyte_clk = priv->txbyte_clk;
87*4882a593Smuzhiyun u32 txesc_clk = priv->txesc_clk;
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun txesc_clk = txbyte_clk/(txbyte_clk/txesc_clk + 1);
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun /* Set Display timing parameter */
92*4882a593Smuzhiyun rk_mipi_dsi_write(regs, VID_HSA_TIME, timing->hsync_len.typ);
93*4882a593Smuzhiyun rk_mipi_dsi_write(regs, VID_HBP_TIME, timing->hback_porch.typ);
94*4882a593Smuzhiyun rk_mipi_dsi_write(regs, VID_HLINE_TIME, (timing->hsync_len.typ
95*4882a593Smuzhiyun + timing->hback_porch.typ + timing->hactive.typ
96*4882a593Smuzhiyun + timing->hfront_porch.typ));
97*4882a593Smuzhiyun rk_mipi_dsi_write(regs, VID_VSA_LINES, timing->vsync_len.typ);
98*4882a593Smuzhiyun rk_mipi_dsi_write(regs, VID_VBP_LINES, timing->vback_porch.typ);
99*4882a593Smuzhiyun rk_mipi_dsi_write(regs, VID_VFP_LINES, timing->vfront_porch.typ);
100*4882a593Smuzhiyun rk_mipi_dsi_write(regs, VID_ACTIVE_LINES, timing->vactive.typ);
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun /* Set Signal Polarity */
103*4882a593Smuzhiyun val = (timing->flags & DISPLAY_FLAGS_HSYNC_LOW) ? 1 : 0;
104*4882a593Smuzhiyun rk_mipi_dsi_write(regs, HSYNC_ACTIVE_LOW, val);
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun val = (timing->flags & DISPLAY_FLAGS_VSYNC_LOW) ? 1 : 0;
107*4882a593Smuzhiyun rk_mipi_dsi_write(regs, VSYNC_ACTIVE_LOW, val);
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun val = (timing->flags & DISPLAY_FLAGS_DE_LOW) ? 1 : 0;
110*4882a593Smuzhiyun rk_mipi_dsi_write(regs, DISPLAY_FLAGS_DE_LOW, val);
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun val = (timing->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) ? 1 : 0;
113*4882a593Smuzhiyun rk_mipi_dsi_write(regs, COLORM_ACTIVE_LOW, val);
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun /* Set video mode */
116*4882a593Smuzhiyun rk_mipi_dsi_write(regs, CMD_VIDEO_MODE, VIDEO_MODE);
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun /* Set video mode transmission type as burst mode */
119*4882a593Smuzhiyun rk_mipi_dsi_write(regs, VID_MODE_TYPE, BURST_MODE);
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun /* Set pix num in a video package */
122*4882a593Smuzhiyun rk_mipi_dsi_write(regs, VID_PKT_SIZE, 0x4b0);
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun /* Set dpi color coding depth 24 bit */
125*4882a593Smuzhiyun timing_node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(dev),
126*4882a593Smuzhiyun "display-timings");
127*4882a593Smuzhiyun node = fdt_first_subnode(gd->fdt_blob, timing_node);
128*4882a593Smuzhiyun val = fdtdec_get_int(gd->fdt_blob, node, "bits-per-pixel", -1);
129*4882a593Smuzhiyun switch (val) {
130*4882a593Smuzhiyun case 16:
131*4882a593Smuzhiyun rk_mipi_dsi_write(regs, DPI_COLOR_CODING, DPI_16BIT_CFG_1);
132*4882a593Smuzhiyun break;
133*4882a593Smuzhiyun case 24:
134*4882a593Smuzhiyun rk_mipi_dsi_write(regs, DPI_COLOR_CODING, DPI_24BIT);
135*4882a593Smuzhiyun break;
136*4882a593Smuzhiyun case 30:
137*4882a593Smuzhiyun rk_mipi_dsi_write(regs, DPI_COLOR_CODING, DPI_30BIT);
138*4882a593Smuzhiyun break;
139*4882a593Smuzhiyun default:
140*4882a593Smuzhiyun rk_mipi_dsi_write(regs, DPI_COLOR_CODING, DPI_24BIT);
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun /* Enable low power mode */
143*4882a593Smuzhiyun rk_mipi_dsi_write(regs, LP_CMD_EN, 1);
144*4882a593Smuzhiyun rk_mipi_dsi_write(regs, LP_HFP_EN, 1);
145*4882a593Smuzhiyun rk_mipi_dsi_write(regs, LP_VACT_EN, 1);
146*4882a593Smuzhiyun rk_mipi_dsi_write(regs, LP_VFP_EN, 1);
147*4882a593Smuzhiyun rk_mipi_dsi_write(regs, LP_VBP_EN, 1);
148*4882a593Smuzhiyun rk_mipi_dsi_write(regs, LP_VSA_EN, 1);
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun /* Division for timeout counter clk */
151*4882a593Smuzhiyun rk_mipi_dsi_write(regs, TO_CLK_DIVISION, 0x0a);
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun /* Tx esc clk division from txbyte clk */
154*4882a593Smuzhiyun rk_mipi_dsi_write(regs, TX_ESC_CLK_DIVISION, txbyte_clk/txesc_clk);
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun /* Timeout count for hs<->lp transation between Line period */
157*4882a593Smuzhiyun rk_mipi_dsi_write(regs, HSTX_TO_CNT, 0x3e8);
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun /* Phy State transfer timing */
160*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_STOP_WAIT_TIME, 32);
161*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_TXREQUESTCLKHS, 1);
162*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_HS2LP_TIME, 0x14);
163*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_LP2HS_TIME, 0x10);
164*4882a593Smuzhiyun rk_mipi_dsi_write(regs, MAX_RD_TIME, 0x2710);
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun /* Power on */
167*4882a593Smuzhiyun rk_mipi_dsi_write(regs, SHUTDOWNZ, 1);
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun return 0;
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun /* rk mipi dphy write function. It is used to write test data to dphy */
rk_mipi_phy_write(uintptr_t regs,unsigned char test_code,unsigned char * test_data,unsigned char size)173*4882a593Smuzhiyun static void rk_mipi_phy_write(uintptr_t regs, unsigned char test_code,
174*4882a593Smuzhiyun unsigned char *test_data, unsigned char size)
175*4882a593Smuzhiyun {
176*4882a593Smuzhiyun int i = 0;
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun /* Write Test code */
179*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_TESTCLK, 1);
180*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_TESTDIN, test_code);
181*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_TESTEN, 1);
182*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_TESTCLK, 0);
183*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_TESTEN, 0);
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun /* Write Test data */
186*4882a593Smuzhiyun for (i = 0; i < size; i++) {
187*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_TESTCLK, 0);
188*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_TESTDIN, test_data[i]);
189*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_TESTCLK, 1);
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun /*
194*4882a593Smuzhiyun * Mipi dphy config function. Calculate the suitable prediv, feedback div,
195*4882a593Smuzhiyun * fsfreqrang value ,cap ,lpf and so on according to the given pix clk rate,
196*4882a593Smuzhiyun * and then enable phy.
197*4882a593Smuzhiyun */
rk_mipi_phy_enable(struct udevice * dev)198*4882a593Smuzhiyun int rk_mipi_phy_enable(struct udevice *dev)
199*4882a593Smuzhiyun {
200*4882a593Smuzhiyun int i;
201*4882a593Smuzhiyun struct rk_mipi_priv *priv = dev_get_priv(dev);
202*4882a593Smuzhiyun uintptr_t regs = priv->regs;
203*4882a593Smuzhiyun u64 fbdiv;
204*4882a593Smuzhiyun u64 prediv = 1;
205*4882a593Smuzhiyun u32 max_fbdiv = 512;
206*4882a593Smuzhiyun u32 max_prediv, min_prediv;
207*4882a593Smuzhiyun u64 ddr_clk = priv->phy_clk;
208*4882a593Smuzhiyun u32 refclk = priv->ref_clk;
209*4882a593Smuzhiyun u32 remain = refclk;
210*4882a593Smuzhiyun unsigned char test_data[2] = {0};
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun int freq_rang[][2] = {
213*4882a593Smuzhiyun {90, 0x01}, {100, 0x10}, {110, 0x20}, {130, 0x01},
214*4882a593Smuzhiyun {140, 0x11}, {150, 0x21}, {170, 0x02}, {180, 0x12},
215*4882a593Smuzhiyun {200, 0x22}, {220, 0x03}, {240, 0x13}, {250, 0x23},
216*4882a593Smuzhiyun {270, 0x04}, {300, 0x14}, {330, 0x05}, {360, 0x15},
217*4882a593Smuzhiyun {400, 0x25}, {450, 0x06}, {500, 0x16}, {550, 0x07},
218*4882a593Smuzhiyun {600, 0x17}, {650, 0x08}, {700, 0x18}, {750, 0x09},
219*4882a593Smuzhiyun {800, 0x19}, {850, 0x29}, {900, 0x39}, {950, 0x0a},
220*4882a593Smuzhiyun {1000, 0x1a}, {1050, 0x2a}, {1100, 0x3a}, {1150, 0x0b},
221*4882a593Smuzhiyun {1200, 0x1b}, {1250, 0x2b}, {1300, 0x3b}, {1350, 0x0c},
222*4882a593Smuzhiyun {1400, 0x1c}, {1450, 0x2c}, {1500, 0x3c}
223*4882a593Smuzhiyun };
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun /* Shutdown mode */
226*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_SHUTDOWNZ, 0);
227*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_RSTZ, 0);
228*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_TESTCLR, 1);
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun /* Pll locking */
231*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_TESTCLR, 0);
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun /* config cp and lfp */
234*4882a593Smuzhiyun test_data[0] = 0x80 | (ddr_clk / (200 * MHz)) << 3 | 0x3;
235*4882a593Smuzhiyun rk_mipi_phy_write(regs, CODE_PLL_VCORANGE_VCOCAP, test_data, 1);
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun test_data[0] = 0x8;
238*4882a593Smuzhiyun rk_mipi_phy_write(regs, CODE_PLL_CPCTRL, test_data, 1);
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun test_data[0] = 0x80 | 0x40;
241*4882a593Smuzhiyun rk_mipi_phy_write(regs, CODE_PLL_LPF_CP, test_data, 1);
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun /* select the suitable value for fsfreqrang reg */
244*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(freq_rang); i++) {
245*4882a593Smuzhiyun if (ddr_clk / (MHz) >= freq_rang[i][0])
246*4882a593Smuzhiyun break;
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun if (i == ARRAY_SIZE(freq_rang)) {
249*4882a593Smuzhiyun debug("%s: Dphy freq out of range!\n", __func__);
250*4882a593Smuzhiyun return -EINVAL;
251*4882a593Smuzhiyun }
252*4882a593Smuzhiyun test_data[0] = freq_rang[i][1] << 1;
253*4882a593Smuzhiyun rk_mipi_phy_write(regs, CODE_HS_RX_LANE0, test_data, 1);
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun /*
256*4882a593Smuzhiyun * Calculate the best ddrclk and it's corresponding div value. If the
257*4882a593Smuzhiyun * given pixelclock is great than 250M, ddrclk will be fix 1500M.
258*4882a593Smuzhiyun * Otherwise,
259*4882a593Smuzhiyun * it's equal to ddr_clk= pixclk * 6. 40MHz >= refclk / prediv >= 5MHz
260*4882a593Smuzhiyun * according to spec.
261*4882a593Smuzhiyun */
262*4882a593Smuzhiyun max_prediv = (refclk / (5 * MHz));
263*4882a593Smuzhiyun min_prediv = ((refclk / (40 * MHz)) ? (refclk / (40 * MHz) + 1) : 1);
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun debug("%s: DEBUG: max_prediv=%u, min_prediv=%u\n", __func__, max_prediv,
266*4882a593Smuzhiyun min_prediv);
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun if (max_prediv < min_prediv) {
269*4882a593Smuzhiyun debug("%s: Invalid refclk value\n", __func__);
270*4882a593Smuzhiyun return -EINVAL;
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun /* Calculate the best refclk and feedback division value for dphy pll */
274*4882a593Smuzhiyun for (i = min_prediv; i < max_prediv; i++) {
275*4882a593Smuzhiyun if ((ddr_clk * i % refclk < remain) &&
276*4882a593Smuzhiyun (ddr_clk * i / refclk) < max_fbdiv) {
277*4882a593Smuzhiyun prediv = i;
278*4882a593Smuzhiyun remain = ddr_clk * i % refclk;
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun fbdiv = ddr_clk * prediv / refclk;
282*4882a593Smuzhiyun ddr_clk = refclk * fbdiv / prediv;
283*4882a593Smuzhiyun priv->phy_clk = ddr_clk;
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun debug("%s: DEBUG: refclk=%u, refclk=%llu, fbdiv=%llu, phyclk=%llu\n",
286*4882a593Smuzhiyun __func__, refclk, prediv, fbdiv, ddr_clk);
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun /* config prediv and feedback reg */
289*4882a593Smuzhiyun test_data[0] = prediv - 1;
290*4882a593Smuzhiyun rk_mipi_phy_write(regs, CODE_PLL_INPUT_DIV_RAT, test_data, 1);
291*4882a593Smuzhiyun test_data[0] = (fbdiv - 1) & 0x1f;
292*4882a593Smuzhiyun rk_mipi_phy_write(regs, CODE_PLL_LOOP_DIV_RAT, test_data, 1);
293*4882a593Smuzhiyun test_data[0] = (fbdiv - 1) >> 5 | 0x80;
294*4882a593Smuzhiyun rk_mipi_phy_write(regs, CODE_PLL_LOOP_DIV_RAT, test_data, 1);
295*4882a593Smuzhiyun test_data[0] = 0x30;
296*4882a593Smuzhiyun rk_mipi_phy_write(regs, CODE_PLL_INPUT_LOOP_DIV_RAT, test_data, 1);
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun /* rest config */
299*4882a593Smuzhiyun test_data[0] = 0x4d;
300*4882a593Smuzhiyun rk_mipi_phy_write(regs, CODE_BANDGAP_BIAS_CTRL, test_data, 1);
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun test_data[0] = 0x3d;
303*4882a593Smuzhiyun rk_mipi_phy_write(regs, CODE_TERMINATION_CTRL, test_data, 1);
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun test_data[0] = 0xdf;
306*4882a593Smuzhiyun rk_mipi_phy_write(regs, CODE_TERMINATION_CTRL, test_data, 1);
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun test_data[0] = 0x7;
309*4882a593Smuzhiyun rk_mipi_phy_write(regs, CODE_AFE_BIAS_BANDGAP_ANOLOG, test_data, 1);
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun test_data[0] = 0x80 | 0x7;
312*4882a593Smuzhiyun rk_mipi_phy_write(regs, CODE_AFE_BIAS_BANDGAP_ANOLOG, test_data, 1);
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun test_data[0] = 0x80 | 15;
315*4882a593Smuzhiyun rk_mipi_phy_write(regs, CODE_HSTXDATALANEREQUSETSTATETIME,
316*4882a593Smuzhiyun test_data, 1);
317*4882a593Smuzhiyun test_data[0] = 0x80 | 85;
318*4882a593Smuzhiyun rk_mipi_phy_write(regs, CODE_HSTXDATALANEPREPARESTATETIME,
319*4882a593Smuzhiyun test_data, 1);
320*4882a593Smuzhiyun test_data[0] = 0x40 | 10;
321*4882a593Smuzhiyun rk_mipi_phy_write(regs, CODE_HSTXDATALANEHSZEROSTATETIME,
322*4882a593Smuzhiyun test_data, 1);
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun /* enter into stop mode */
325*4882a593Smuzhiyun rk_mipi_dsi_write(regs, N_LANES, 0x03);
326*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_ENABLECLK, 1);
327*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_FORCEPLL, 1);
328*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_SHUTDOWNZ, 1);
329*4882a593Smuzhiyun rk_mipi_dsi_write(regs, PHY_RSTZ, 1);
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun return 0;
332*4882a593Smuzhiyun }
333*4882a593Smuzhiyun
334