xref: /OK3568_Linux_fs/u-boot/drivers/video/drm/dw_mipi_dsi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <drm/drm_mipi_dsi.h>
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <config.h>
10*4882a593Smuzhiyun #include <common.h>
11*4882a593Smuzhiyun #include <errno.h>
12*4882a593Smuzhiyun #include <asm/unaligned.h>
13*4882a593Smuzhiyun #include <asm/io.h>
14*4882a593Smuzhiyun #include <asm/hardware.h>
15*4882a593Smuzhiyun #include <dm/device.h>
16*4882a593Smuzhiyun #include <dm/read.h>
17*4882a593Smuzhiyun #include <dm/of_access.h>
18*4882a593Smuzhiyun #include <syscon.h>
19*4882a593Smuzhiyun #include <asm/arch-rockchip/clock.h>
20*4882a593Smuzhiyun #include <linux/iopoll.h>
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #include "rockchip_display.h"
23*4882a593Smuzhiyun #include "rockchip_crtc.h"
24*4882a593Smuzhiyun #include "rockchip_connector.h"
25*4882a593Smuzhiyun #include "rockchip_panel.h"
26*4882a593Smuzhiyun #include "rockchip_phy.h"
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #define UPDATE(v, h, l)		(((v) << (l)) & GENMASK((h), (l)))
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #define DSI_VERSION			0x00
31*4882a593Smuzhiyun #define DSI_PWR_UP			0x04
32*4882a593Smuzhiyun #define RESET				0
33*4882a593Smuzhiyun #define POWERUP				BIT(0)
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #define DSI_CLKMGR_CFG			0x08
36*4882a593Smuzhiyun #define TO_CLK_DIVIDSION(div)		(((div) & 0xff) << 8)
37*4882a593Smuzhiyun #define TX_ESC_CLK_DIVIDSION(div)	(((div) & 0xff) << 0)
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #define DSI_DPI_VCID			0x0c
40*4882a593Smuzhiyun #define DPI_VID(vid)			(((vid) & 0x3) << 0)
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun #define DSI_DPI_COLOR_CODING		0x10
43*4882a593Smuzhiyun #define EN18_LOOSELY			BIT(8)
44*4882a593Smuzhiyun #define DPI_COLOR_CODING_16BIT_1	0x0
45*4882a593Smuzhiyun #define DPI_COLOR_CODING_16BIT_2	0x1
46*4882a593Smuzhiyun #define DPI_COLOR_CODING_16BIT_3	0x2
47*4882a593Smuzhiyun #define DPI_COLOR_CODING_18BIT_1	0x3
48*4882a593Smuzhiyun #define DPI_COLOR_CODING_18BIT_2	0x4
49*4882a593Smuzhiyun #define DPI_COLOR_CODING_24BIT		0x5
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun #define DSI_DPI_CFG_POL			0x14
52*4882a593Smuzhiyun #define COLORM_ACTIVE_LOW		BIT(4)
53*4882a593Smuzhiyun #define SHUTD_ACTIVE_LOW		BIT(3)
54*4882a593Smuzhiyun #define HSYNC_ACTIVE_LOW		BIT(2)
55*4882a593Smuzhiyun #define VSYNC_ACTIVE_LOW		BIT(1)
56*4882a593Smuzhiyun #define DATAEN_ACTIVE_LOW		BIT(0)
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun #define DSI_DPI_LP_CMD_TIM		0x18
59*4882a593Smuzhiyun #define OUTVACT_LPCMD_TIME(p)		(((p) & 0xff) << 16)
60*4882a593Smuzhiyun #define INVACT_LPCMD_TIME(p)		((p) & 0xff)
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun #define DSI_DBI_VCID			0x1c
63*4882a593Smuzhiyun #define DBI_VCID(x)			UPDATE(x, 1, 0)
64*4882a593Smuzhiyun #define DSI_DBI_CFG			0x20
65*4882a593Smuzhiyun #define DSI_DBI_CMDSIZE			0x28
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun #define DSI_PCKHDL_CFG			0x2c
68*4882a593Smuzhiyun #define CRC_RX_EN			BIT(4)
69*4882a593Smuzhiyun #define ECC_RX_EN			BIT(3)
70*4882a593Smuzhiyun #define BTA_EN				BIT(2)
71*4882a593Smuzhiyun #define EOTP_RX_EN			BIT(1)
72*4882a593Smuzhiyun #define EOTP_TX_EN			BIT(0)
73*4882a593Smuzhiyun #define DSI_MODE_CFG			0x34
74*4882a593Smuzhiyun #define CMD_VIDEO_MODE			BIT(0)
75*4882a593Smuzhiyun #define COMMAND_MODE			BIT(0)
76*4882a593Smuzhiyun #define VIDEO_MODE			0
77*4882a593Smuzhiyun #define DSI_VID_MODE_CFG		0x38
78*4882a593Smuzhiyun #define VPG_EN				BIT(16)
79*4882a593Smuzhiyun #define LP_CMD_EN			BIT(15)
80*4882a593Smuzhiyun #define FRAME_BTA_ACK			BIT(14)
81*4882a593Smuzhiyun #define LP_HFP_EN			BIT(13)
82*4882a593Smuzhiyun #define LP_HBP_EN			BIT(12)
83*4882a593Smuzhiyun #define LP_VACT_EN			BIT(11)
84*4882a593Smuzhiyun #define LP_VFP_EN			BIT(10)
85*4882a593Smuzhiyun #define LP_VBP_EN			BIT(9)
86*4882a593Smuzhiyun #define LP_VSA_EN			BIT(8)
87*4882a593Smuzhiyun #define VID_MODE_TYPE_BURST_SYNC_PULSES	0x0
88*4882a593Smuzhiyun #define VID_MODE_TYPE_BURST_SYNC_EVENTS	0x1
89*4882a593Smuzhiyun #define VID_MODE_TYPE_BURST		0x2
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun #define DSI_VID_PKT_SIZE		0x3c
92*4882a593Smuzhiyun #define VID_PKT_SIZE(p)			(((p) & 0x3fff) << 0)
93*4882a593Smuzhiyun #define VID_PKT_MAX_SIZE		0x3fff
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun #define DSI_VID_NUM_CHUMKS		0x40
96*4882a593Smuzhiyun #define DSI_VID_NULL_PKT_SIZE		0x44
97*4882a593Smuzhiyun #define DSI_VID_HSA_TIME		0x48
98*4882a593Smuzhiyun #define DSI_VID_HBP_TIME		0x4c
99*4882a593Smuzhiyun #define DSI_VID_HLINE_TIME		0x50
100*4882a593Smuzhiyun #define DSI_VID_VSA_LINES		0x54
101*4882a593Smuzhiyun #define DSI_VID_VBP_LINES		0x58
102*4882a593Smuzhiyun #define DSI_VID_VFP_LINES		0x5c
103*4882a593Smuzhiyun #define DSI_VID_VACTIVE_LINES		0x60
104*4882a593Smuzhiyun #define DSI_EDPI_CMD_SIZE		0x64
105*4882a593Smuzhiyun #define DSI_CMD_MODE_CFG		0x68
106*4882a593Smuzhiyun #define MAX_RD_PKT_SIZE			BIT(24)
107*4882a593Smuzhiyun #define DCS_LW_TX			BIT(19)
108*4882a593Smuzhiyun #define DCS_SR_0P_TX			BIT(18)
109*4882a593Smuzhiyun #define DCS_SW_1P_TX			BIT(17)
110*4882a593Smuzhiyun #define DCS_SW_0P_TX			BIT(16)
111*4882a593Smuzhiyun #define GEN_LW_TX			BIT(14)
112*4882a593Smuzhiyun #define GEN_SR_2P_TX			BIT(13)
113*4882a593Smuzhiyun #define GEN_SR_1P_TX			BIT(12)
114*4882a593Smuzhiyun #define GEN_SR_0P_TX			BIT(11)
115*4882a593Smuzhiyun #define GEN_SW_2P_TX			BIT(10)
116*4882a593Smuzhiyun #define GEN_SW_1P_TX			BIT(9)
117*4882a593Smuzhiyun #define GEN_SW_0P_TX			BIT(8)
118*4882a593Smuzhiyun #define ACK_RQST_EN			BIT(1)
119*4882a593Smuzhiyun #define TEAR_FX_EN			BIT(0)
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun #define DSI_GEN_HDR			0x6c
122*4882a593Smuzhiyun #define GEN_HDATA(data)			(((data) & 0xffff) << 8)
123*4882a593Smuzhiyun #define GEN_HDATA_MASK			(0xffff << 8)
124*4882a593Smuzhiyun #define GEN_HTYPE(type)			(((type) & 0xff) << 0)
125*4882a593Smuzhiyun #define GEN_HTYPE_MASK			0xff
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun #define DSI_GEN_PLD_DATA		0x70
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun #define DSI_CMD_PKT_STATUS		0x74
130*4882a593Smuzhiyun #define GEN_CMD_EMPTY			BIT(0)
131*4882a593Smuzhiyun #define GEN_CMD_FULL			BIT(1)
132*4882a593Smuzhiyun #define GEN_PLD_W_EMPTY			BIT(2)
133*4882a593Smuzhiyun #define GEN_PLD_W_FULL			BIT(3)
134*4882a593Smuzhiyun #define GEN_PLD_R_EMPTY			BIT(4)
135*4882a593Smuzhiyun #define GEN_PLD_R_FULL			BIT(5)
136*4882a593Smuzhiyun #define GEN_RD_CMD_BUSY			BIT(6)
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun #define DSI_TO_CNT_CFG			0x78
139*4882a593Smuzhiyun #define HSTX_TO_CNT(p)			(((p) & 0xffff) << 16)
140*4882a593Smuzhiyun #define LPRX_TO_CNT(p)			((p) & 0xffff)
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun #define DSI_BTA_TO_CNT			0x8c
143*4882a593Smuzhiyun #define DSI_LPCLK_CTRL			0x94
144*4882a593Smuzhiyun #define AUTO_CLKLANE_CTRL		BIT(1)
145*4882a593Smuzhiyun #define PHY_TXREQUESTCLKHS		BIT(0)
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun #define DSI_PHY_TMR_LPCLK_CFG		0x98
148*4882a593Smuzhiyun #define PHY_CLKHS2LP_TIME(lbcc)		(((lbcc) & 0x3ff) << 16)
149*4882a593Smuzhiyun #define PHY_CLKLP2HS_TIME(lbcc)		((lbcc) & 0x3ff)
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun #define DSI_PHY_TMR_CFG			0x9c
152*4882a593Smuzhiyun #define PHY_HS2LP_TIME(lbcc)		(((lbcc) & 0xff) << 24)
153*4882a593Smuzhiyun #define PHY_LP2HS_TIME(lbcc)		(((lbcc) & 0xff) << 16)
154*4882a593Smuzhiyun #define MAX_RD_TIME(lbcc)		((lbcc) & 0x7fff)
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun #define DSI_PHY_RSTZ			0xa0
157*4882a593Smuzhiyun #define PHY_ENFORCEPLL			BIT(3)
158*4882a593Smuzhiyun #define PHY_ENABLECLK			BIT(2)
159*4882a593Smuzhiyun #define PHY_RSTZ			BIT(1)
160*4882a593Smuzhiyun #define PHY_SHUTDOWNZ			BIT(0)
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun #define DSI_PHY_IF_CFG			0xa4
163*4882a593Smuzhiyun #define N_LANES(n)			((((n) - 1) & 0x3) << 0)
164*4882a593Smuzhiyun #define PHY_STOP_WAIT_TIME(cycle)	(((cycle) & 0xff) << 8)
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun #define DSI_PHY_STATUS			0xb0
167*4882a593Smuzhiyun #define PHY_STOPSTATE0LANE		BIT(4)
168*4882a593Smuzhiyun #define PHY_STOPSTATECLKLANE		BIT(2)
169*4882a593Smuzhiyun #define PHY_LOCK			BIT(0)
170*4882a593Smuzhiyun #define PHY_STOPSTATELANE		(PHY_STOPSTATE0LANE | \
171*4882a593Smuzhiyun 					 PHY_STOPSTATECLKLANE)
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun #define DSI_PHY_TST_CTRL0		0xb4
174*4882a593Smuzhiyun #define PHY_TESTCLK			BIT(1)
175*4882a593Smuzhiyun #define PHY_TESTCLR			BIT(0)
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun #define DSI_PHY_TST_CTRL1		0xb8
178*4882a593Smuzhiyun #define PHY_TESTEN			BIT(16)
179*4882a593Smuzhiyun #define PHY_TESTDOUT_SHIFT		8
180*4882a593Smuzhiyun #define PHY_TESTDIN_MASK		GENMASK(7, 0)
181*4882a593Smuzhiyun #define PHY_TESTDIN(x)			UPDATE(x, 7, 0)
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun #define DSI_INT_ST0			0xbc
184*4882a593Smuzhiyun #define DSI_INT_ST1			0xc0
185*4882a593Smuzhiyun #define DSI_INT_MSK0			0xc4
186*4882a593Smuzhiyun #define DSI_INT_MSK1			0xc8
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun #define PHY_STATUS_TIMEOUT_US		10000
189*4882a593Smuzhiyun #define CMD_PKT_STATUS_TIMEOUT_US	20000
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun /* Test Code: 0x44 (HS RX Control of Lane 0) */
192*4882a593Smuzhiyun #define HSFREQRANGE(x)			UPDATE(x, 6, 1)
193*4882a593Smuzhiyun /* Test Code: 0x17 (PLL Input Divider Ratio) */
194*4882a593Smuzhiyun #define INPUT_DIV(x)			UPDATE(x, 6, 0)
195*4882a593Smuzhiyun /* Test Code: 0x18 (PLL Loop Divider Ratio) */
196*4882a593Smuzhiyun #define FEEDBACK_DIV_LO(x)		UPDATE(x, 4, 0)
197*4882a593Smuzhiyun #define FEEDBACK_DIV_HI(x)		(BIT(7) | UPDATE(x, 3, 0))
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun #define GRF_REG_FIELD(reg, lsb, msb)	(((reg) << 10) | ((lsb) << 5) | (msb))
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun enum grf_reg_fields {
202*4882a593Smuzhiyun 	DPIUPDATECFG,
203*4882a593Smuzhiyun 	DPISHUTDN,
204*4882a593Smuzhiyun 	DPICOLORM,
205*4882a593Smuzhiyun 	VOPSEL,
206*4882a593Smuzhiyun 	TURNREQUEST,
207*4882a593Smuzhiyun 	TURNDISABLE,
208*4882a593Smuzhiyun 	SKEWCALHS,
209*4882a593Smuzhiyun 	FORCETXSTOPMODE,
210*4882a593Smuzhiyun 	FORCERXMODE,
211*4882a593Smuzhiyun 	ENABLE_N,
212*4882a593Smuzhiyun 	MASTERSLAVEZ,
213*4882a593Smuzhiyun 	ENABLECLK,
214*4882a593Smuzhiyun 	BASEDIR,
215*4882a593Smuzhiyun 	MAX_FIELDS,
216*4882a593Smuzhiyun };
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun struct dw_mipi_dsi_plat_data {
219*4882a593Smuzhiyun 	const u32 *dsi0_grf_reg_fields;
220*4882a593Smuzhiyun 	const u32 *dsi1_grf_reg_fields;
221*4882a593Smuzhiyun 	unsigned long max_bit_rate_per_lane;
222*4882a593Smuzhiyun };
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun struct mipi_dphy {
225*4882a593Smuzhiyun 	/* Non-SNPS PHY */
226*4882a593Smuzhiyun 	struct rockchip_phy *phy;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	u16 input_div;
229*4882a593Smuzhiyun 	u16 feedback_div;
230*4882a593Smuzhiyun };
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun struct dw_mipi_dsi {
233*4882a593Smuzhiyun 	struct rockchip_connector connector;
234*4882a593Smuzhiyun 	struct udevice *dev;
235*4882a593Smuzhiyun 	void *base;
236*4882a593Smuzhiyun 	void *grf;
237*4882a593Smuzhiyun 	int id;
238*4882a593Smuzhiyun 	struct dw_mipi_dsi *master;
239*4882a593Smuzhiyun 	struct dw_mipi_dsi *slave;
240*4882a593Smuzhiyun 	bool prepared;
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 	unsigned int lane_mbps; /* per lane */
243*4882a593Smuzhiyun 	u32 channel;
244*4882a593Smuzhiyun 	u32 lanes;
245*4882a593Smuzhiyun 	u32 format;
246*4882a593Smuzhiyun 	u32 mode_flags;
247*4882a593Smuzhiyun 	struct mipi_dphy dphy;
248*4882a593Smuzhiyun 	struct drm_display_mode mode;
249*4882a593Smuzhiyun 	bool data_swap;
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun 	const struct dw_mipi_dsi_plat_data *pdata;
252*4882a593Smuzhiyun };
253*4882a593Smuzhiyun 
dsi_write(struct dw_mipi_dsi * dsi,u32 reg,u32 val)254*4882a593Smuzhiyun static inline void dsi_write(struct dw_mipi_dsi *dsi, u32 reg, u32 val)
255*4882a593Smuzhiyun {
256*4882a593Smuzhiyun 	writel(val, dsi->base + reg);
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun 
dsi_read(struct dw_mipi_dsi * dsi,u32 reg)259*4882a593Smuzhiyun static inline u32 dsi_read(struct dw_mipi_dsi *dsi, u32 reg)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun 	return readl(dsi->base + reg);
262*4882a593Smuzhiyun }
263*4882a593Smuzhiyun 
dsi_update_bits(struct dw_mipi_dsi * dsi,u32 reg,u32 mask,u32 val)264*4882a593Smuzhiyun static inline void dsi_update_bits(struct dw_mipi_dsi *dsi,
265*4882a593Smuzhiyun 				   u32 reg, u32 mask, u32 val)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun 	u32 orig, tmp;
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun 	orig = dsi_read(dsi, reg);
270*4882a593Smuzhiyun 	tmp = orig & ~mask;
271*4882a593Smuzhiyun 	tmp |= val & mask;
272*4882a593Smuzhiyun 	dsi_write(dsi, reg, tmp);
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun 
grf_field_write(struct dw_mipi_dsi * dsi,enum grf_reg_fields index,unsigned int val)275*4882a593Smuzhiyun static void grf_field_write(struct dw_mipi_dsi *dsi, enum grf_reg_fields index,
276*4882a593Smuzhiyun 			    unsigned int val)
277*4882a593Smuzhiyun {
278*4882a593Smuzhiyun 	const u32 field = dsi->id ? dsi->pdata->dsi1_grf_reg_fields[index] :
279*4882a593Smuzhiyun 			  dsi->pdata->dsi0_grf_reg_fields[index];
280*4882a593Smuzhiyun 	u16 reg;
281*4882a593Smuzhiyun 	u8 msb, lsb;
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun 	if (!field)
284*4882a593Smuzhiyun 		return;
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	reg = (field >> 10) & 0x3ffff;
287*4882a593Smuzhiyun 	lsb = (field >>  5) & 0x1f;
288*4882a593Smuzhiyun 	msb = (field >>  0) & 0x1f;
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	rk_clrsetreg(dsi->grf + reg, GENMASK(msb, lsb), val << lsb);
291*4882a593Smuzhiyun }
292*4882a593Smuzhiyun 
dpishutdn_assert(struct dw_mipi_dsi * dsi)293*4882a593Smuzhiyun static inline void dpishutdn_assert(struct dw_mipi_dsi *dsi)
294*4882a593Smuzhiyun {
295*4882a593Smuzhiyun 	grf_field_write(dsi, DPISHUTDN, 1);
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun 
dpishutdn_deassert(struct dw_mipi_dsi * dsi)298*4882a593Smuzhiyun static inline void dpishutdn_deassert(struct dw_mipi_dsi *dsi)
299*4882a593Smuzhiyun {
300*4882a593Smuzhiyun 	grf_field_write(dsi, DPISHUTDN, 0);
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun 
genif_wait_w_pld_fifo_not_full(struct dw_mipi_dsi * dsi)303*4882a593Smuzhiyun static int genif_wait_w_pld_fifo_not_full(struct dw_mipi_dsi *dsi)
304*4882a593Smuzhiyun {
305*4882a593Smuzhiyun 	u32 sts;
306*4882a593Smuzhiyun 	int ret;
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun 	ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
309*4882a593Smuzhiyun 				 sts, !(sts & GEN_PLD_W_FULL),
310*4882a593Smuzhiyun 				 CMD_PKT_STATUS_TIMEOUT_US);
311*4882a593Smuzhiyun 	if (ret < 0) {
312*4882a593Smuzhiyun 		printf("generic write payload fifo is full\n");
313*4882a593Smuzhiyun 		return ret;
314*4882a593Smuzhiyun 	}
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 	return 0;
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun 
genif_wait_cmd_fifo_not_full(struct dw_mipi_dsi * dsi)319*4882a593Smuzhiyun static int genif_wait_cmd_fifo_not_full(struct dw_mipi_dsi *dsi)
320*4882a593Smuzhiyun {
321*4882a593Smuzhiyun 	u32 sts;
322*4882a593Smuzhiyun 	int ret;
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
325*4882a593Smuzhiyun 				 sts, !(sts & GEN_CMD_FULL),
326*4882a593Smuzhiyun 				 CMD_PKT_STATUS_TIMEOUT_US);
327*4882a593Smuzhiyun 	if (ret < 0) {
328*4882a593Smuzhiyun 		printf("generic write cmd fifo is full\n");
329*4882a593Smuzhiyun 		return ret;
330*4882a593Smuzhiyun 	}
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 	return 0;
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun 
genif_wait_write_fifo_empty(struct dw_mipi_dsi * dsi)335*4882a593Smuzhiyun static int genif_wait_write_fifo_empty(struct dw_mipi_dsi *dsi)
336*4882a593Smuzhiyun {
337*4882a593Smuzhiyun 	u32 sts;
338*4882a593Smuzhiyun 	u32 mask;
339*4882a593Smuzhiyun 	int ret;
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	mask = GEN_CMD_EMPTY | GEN_PLD_W_EMPTY;
342*4882a593Smuzhiyun 	ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
343*4882a593Smuzhiyun 				 sts, (sts & mask) == mask,
344*4882a593Smuzhiyun 				 CMD_PKT_STATUS_TIMEOUT_US);
345*4882a593Smuzhiyun 	if (ret < 0) {
346*4882a593Smuzhiyun 		printf("generic write fifo is full\n");
347*4882a593Smuzhiyun 		return ret;
348*4882a593Smuzhiyun 	}
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 	return 0;
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun 
mipi_dphy_enableclk_assert(struct dw_mipi_dsi * dsi)353*4882a593Smuzhiyun static inline void mipi_dphy_enableclk_assert(struct dw_mipi_dsi *dsi)
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun 	dsi_update_bits(dsi, DSI_PHY_RSTZ, PHY_ENABLECLK, PHY_ENABLECLK);
356*4882a593Smuzhiyun 	udelay(1);
357*4882a593Smuzhiyun }
358*4882a593Smuzhiyun 
mipi_dphy_enableclk_deassert(struct dw_mipi_dsi * dsi)359*4882a593Smuzhiyun static inline void mipi_dphy_enableclk_deassert(struct dw_mipi_dsi *dsi)
360*4882a593Smuzhiyun {
361*4882a593Smuzhiyun 	dsi_update_bits(dsi, DSI_PHY_RSTZ, PHY_ENABLECLK, 0);
362*4882a593Smuzhiyun 	udelay(1);
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun 
mipi_dphy_shutdownz_assert(struct dw_mipi_dsi * dsi)365*4882a593Smuzhiyun static inline void mipi_dphy_shutdownz_assert(struct dw_mipi_dsi *dsi)
366*4882a593Smuzhiyun {
367*4882a593Smuzhiyun 	dsi_update_bits(dsi, DSI_PHY_RSTZ, PHY_SHUTDOWNZ, 0);
368*4882a593Smuzhiyun 	udelay(1);
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun 
mipi_dphy_shutdownz_deassert(struct dw_mipi_dsi * dsi)371*4882a593Smuzhiyun static inline void mipi_dphy_shutdownz_deassert(struct dw_mipi_dsi *dsi)
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun 	dsi_update_bits(dsi, DSI_PHY_RSTZ, PHY_SHUTDOWNZ, PHY_SHUTDOWNZ);
374*4882a593Smuzhiyun 	udelay(1);
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun 
mipi_dphy_rstz_assert(struct dw_mipi_dsi * dsi)377*4882a593Smuzhiyun static inline void mipi_dphy_rstz_assert(struct dw_mipi_dsi *dsi)
378*4882a593Smuzhiyun {
379*4882a593Smuzhiyun 	dsi_update_bits(dsi, DSI_PHY_RSTZ, PHY_RSTZ, 0);
380*4882a593Smuzhiyun 	udelay(1);
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun 
mipi_dphy_rstz_deassert(struct dw_mipi_dsi * dsi)383*4882a593Smuzhiyun static inline void mipi_dphy_rstz_deassert(struct dw_mipi_dsi *dsi)
384*4882a593Smuzhiyun {
385*4882a593Smuzhiyun 	dsi_update_bits(dsi, DSI_PHY_RSTZ, PHY_RSTZ, PHY_RSTZ);
386*4882a593Smuzhiyun 	udelay(1);
387*4882a593Smuzhiyun }
388*4882a593Smuzhiyun 
testif_testclk_assert(struct dw_mipi_dsi * dsi)389*4882a593Smuzhiyun static inline void testif_testclk_assert(struct dw_mipi_dsi *dsi)
390*4882a593Smuzhiyun {
391*4882a593Smuzhiyun 	dsi_update_bits(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLK, PHY_TESTCLK);
392*4882a593Smuzhiyun 	udelay(1);
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun 
testif_testclk_deassert(struct dw_mipi_dsi * dsi)395*4882a593Smuzhiyun static inline void testif_testclk_deassert(struct dw_mipi_dsi *dsi)
396*4882a593Smuzhiyun {
397*4882a593Smuzhiyun 	dsi_update_bits(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLK, 0);
398*4882a593Smuzhiyun 	udelay(1);
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun 
testif_testclr_assert(struct dw_mipi_dsi * dsi)401*4882a593Smuzhiyun static inline void testif_testclr_assert(struct dw_mipi_dsi *dsi)
402*4882a593Smuzhiyun {
403*4882a593Smuzhiyun 	dsi_update_bits(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLR, PHY_TESTCLR);
404*4882a593Smuzhiyun 	udelay(1);
405*4882a593Smuzhiyun }
406*4882a593Smuzhiyun 
testif_testclr_deassert(struct dw_mipi_dsi * dsi)407*4882a593Smuzhiyun static inline void testif_testclr_deassert(struct dw_mipi_dsi *dsi)
408*4882a593Smuzhiyun {
409*4882a593Smuzhiyun 	dsi_update_bits(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLR, 0);
410*4882a593Smuzhiyun 	udelay(1);
411*4882a593Smuzhiyun }
412*4882a593Smuzhiyun 
testif_testen_assert(struct dw_mipi_dsi * dsi)413*4882a593Smuzhiyun static inline void testif_testen_assert(struct dw_mipi_dsi *dsi)
414*4882a593Smuzhiyun {
415*4882a593Smuzhiyun 	dsi_update_bits(dsi, DSI_PHY_TST_CTRL1, PHY_TESTEN, PHY_TESTEN);
416*4882a593Smuzhiyun 	udelay(1);
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun 
testif_testen_deassert(struct dw_mipi_dsi * dsi)419*4882a593Smuzhiyun static inline void testif_testen_deassert(struct dw_mipi_dsi *dsi)
420*4882a593Smuzhiyun {
421*4882a593Smuzhiyun 	dsi_update_bits(dsi, DSI_PHY_TST_CTRL1, PHY_TESTEN, 0);
422*4882a593Smuzhiyun 	udelay(1);
423*4882a593Smuzhiyun }
424*4882a593Smuzhiyun 
testif_set_data(struct dw_mipi_dsi * dsi,u8 data)425*4882a593Smuzhiyun static inline void testif_set_data(struct dw_mipi_dsi *dsi, u8 data)
426*4882a593Smuzhiyun {
427*4882a593Smuzhiyun 	dsi_update_bits(dsi, DSI_PHY_TST_CTRL1,
428*4882a593Smuzhiyun 			PHY_TESTDIN_MASK, PHY_TESTDIN(data));
429*4882a593Smuzhiyun 	udelay(1);
430*4882a593Smuzhiyun }
431*4882a593Smuzhiyun 
testif_get_data(struct dw_mipi_dsi * dsi)432*4882a593Smuzhiyun static inline u8 testif_get_data(struct dw_mipi_dsi *dsi)
433*4882a593Smuzhiyun {
434*4882a593Smuzhiyun 	return dsi_read(dsi, DSI_PHY_TST_CTRL1) >> PHY_TESTDOUT_SHIFT;
435*4882a593Smuzhiyun }
436*4882a593Smuzhiyun 
testif_test_code_write(struct dw_mipi_dsi * dsi,u8 test_code)437*4882a593Smuzhiyun static void testif_test_code_write(struct dw_mipi_dsi *dsi, u8 test_code)
438*4882a593Smuzhiyun {
439*4882a593Smuzhiyun 	testif_testclk_assert(dsi);
440*4882a593Smuzhiyun 	testif_set_data(dsi, test_code);
441*4882a593Smuzhiyun 	testif_testen_assert(dsi);
442*4882a593Smuzhiyun 	testif_testclk_deassert(dsi);
443*4882a593Smuzhiyun 	testif_testen_deassert(dsi);
444*4882a593Smuzhiyun }
445*4882a593Smuzhiyun 
testif_test_data_write(struct dw_mipi_dsi * dsi,u8 test_data)446*4882a593Smuzhiyun static void testif_test_data_write(struct dw_mipi_dsi *dsi, u8 test_data)
447*4882a593Smuzhiyun {
448*4882a593Smuzhiyun 	testif_testclk_deassert(dsi);
449*4882a593Smuzhiyun 	testif_set_data(dsi, test_data);
450*4882a593Smuzhiyun 	testif_testclk_assert(dsi);
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun 
testif_write(struct dw_mipi_dsi * dsi,u8 test_code,u8 test_data)453*4882a593Smuzhiyun static void testif_write(struct dw_mipi_dsi *dsi, u8 test_code, u8 test_data)
454*4882a593Smuzhiyun {
455*4882a593Smuzhiyun 	testif_test_code_write(dsi, test_code);
456*4882a593Smuzhiyun 	testif_test_data_write(dsi, test_data);
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun 	dev_dbg(dsi->dev,
459*4882a593Smuzhiyun 		"test_code=0x%02x, test_data=0x%02x, monitor_data=0x%02x\n",
460*4882a593Smuzhiyun 		test_code, test_data, testif_get_data(dsi));
461*4882a593Smuzhiyun }
462*4882a593Smuzhiyun 
mipi_dphy_power_on(struct dw_mipi_dsi * dsi)463*4882a593Smuzhiyun static int mipi_dphy_power_on(struct dw_mipi_dsi *dsi)
464*4882a593Smuzhiyun {
465*4882a593Smuzhiyun 	u32 mask, val;
466*4882a593Smuzhiyun 	int ret;
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 	mipi_dphy_shutdownz_deassert(dsi);
469*4882a593Smuzhiyun 	mipi_dphy_rstz_deassert(dsi);
470*4882a593Smuzhiyun 	mdelay(2);
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun 	if (dsi->dphy.phy) {
473*4882a593Smuzhiyun 		rockchip_phy_set_mode(dsi->dphy.phy, PHY_MODE_MIPI_DPHY);
474*4882a593Smuzhiyun 		rockchip_phy_power_on(dsi->dphy.phy);
475*4882a593Smuzhiyun 	}
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
478*4882a593Smuzhiyun 				 val, val & PHY_LOCK, PHY_STATUS_TIMEOUT_US);
479*4882a593Smuzhiyun 	if (ret < 0) {
480*4882a593Smuzhiyun 		dev_err(dsi->dev, "PHY is not locked\n");
481*4882a593Smuzhiyun 		return ret;
482*4882a593Smuzhiyun 	}
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun 	udelay(200);
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun 	mask = PHY_STOPSTATELANE;
487*4882a593Smuzhiyun 	ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
488*4882a593Smuzhiyun 				 val, (val & mask) == mask,
489*4882a593Smuzhiyun 				 PHY_STATUS_TIMEOUT_US);
490*4882a593Smuzhiyun 	if (ret < 0) {
491*4882a593Smuzhiyun 		dev_err(dsi->dev, "lane module is not in stop state\n");
492*4882a593Smuzhiyun 		return ret;
493*4882a593Smuzhiyun 	}
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun 	udelay(10);
496*4882a593Smuzhiyun 
497*4882a593Smuzhiyun 	return 0;
498*4882a593Smuzhiyun }
499*4882a593Smuzhiyun 
dw_mipi_dsi_phy_init(struct dw_mipi_dsi * dsi)500*4882a593Smuzhiyun static void dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
501*4882a593Smuzhiyun {
502*4882a593Smuzhiyun 	/* Table 5-1 Frequency Ranges */
503*4882a593Smuzhiyun 	const struct {
504*4882a593Smuzhiyun 		unsigned long max_lane_mbps;
505*4882a593Smuzhiyun 		u8 hsfreqrange;
506*4882a593Smuzhiyun 	} hsfreqrange_table[] = {
507*4882a593Smuzhiyun 		{  90, 0x00}, { 100, 0x10}, { 110, 0x20}, { 130, 0x01},
508*4882a593Smuzhiyun 		{ 140, 0x11}, { 150, 0x21}, { 170, 0x02}, { 180, 0x12},
509*4882a593Smuzhiyun 		{ 200, 0x22}, { 220, 0x03}, { 240, 0x13}, { 250, 0x23},
510*4882a593Smuzhiyun 		{ 270, 0x04}, { 300, 0x14}, { 330, 0x05}, { 360, 0x15},
511*4882a593Smuzhiyun 		{ 400, 0x25}, { 450, 0x06}, { 500, 0x16}, { 550, 0x07},
512*4882a593Smuzhiyun 		{ 600, 0x17}, { 650, 0x08}, { 700, 0x18}, { 750, 0x09},
513*4882a593Smuzhiyun 		{ 800, 0x19}, { 850, 0x29}, { 900, 0x39}, { 950, 0x0a},
514*4882a593Smuzhiyun 		{1000, 0x1a}, {1050, 0x2a}, {1100, 0x3a}, {1150, 0x0b},
515*4882a593Smuzhiyun 		{1200, 0x1b}, {1250, 0x2b}, {1300, 0x3b}, {1350, 0x0c},
516*4882a593Smuzhiyun 		{1400, 0x1c}, {1450, 0x2c}, {1500, 0x3c}
517*4882a593Smuzhiyun 	};
518*4882a593Smuzhiyun 	u8 hsfreqrange, counter;
519*4882a593Smuzhiyun 	unsigned int index, txbyteclkhs;
520*4882a593Smuzhiyun 	u16 n, m;
521*4882a593Smuzhiyun 
522*4882a593Smuzhiyun 	for (index = 0; index < ARRAY_SIZE(hsfreqrange_table); index++)
523*4882a593Smuzhiyun 		if (dsi->lane_mbps <= hsfreqrange_table[index].max_lane_mbps)
524*4882a593Smuzhiyun 			break;
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun 	if (index == ARRAY_SIZE(hsfreqrange_table))
527*4882a593Smuzhiyun 		--index;
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 	hsfreqrange = hsfreqrange_table[index].hsfreqrange;
530*4882a593Smuzhiyun 	testif_write(dsi, 0x44, HSFREQRANGE(hsfreqrange));
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun 	txbyteclkhs = dsi->lane_mbps >> 3;
533*4882a593Smuzhiyun 	counter = txbyteclkhs * 60 / 1000;
534*4882a593Smuzhiyun 	testif_write(dsi, 0x60, 0x80 | counter);
535*4882a593Smuzhiyun 	testif_write(dsi, 0x70, 0x80 | counter);
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun 	n = dsi->dphy.input_div - 1;
538*4882a593Smuzhiyun 	m = dsi->dphy.feedback_div - 1;
539*4882a593Smuzhiyun 	testif_write(dsi, 0x19, 0x30);
540*4882a593Smuzhiyun 	testif_write(dsi, 0x17, INPUT_DIV(n));
541*4882a593Smuzhiyun 	testif_write(dsi, 0x18, FEEDBACK_DIV_LO(m));
542*4882a593Smuzhiyun 	testif_write(dsi, 0x18, FEEDBACK_DIV_HI(m >> 5));
543*4882a593Smuzhiyun }
544*4882a593Smuzhiyun 
dw_mipi_dsi_get_lane_rate(struct dw_mipi_dsi * dsi)545*4882a593Smuzhiyun static unsigned long dw_mipi_dsi_get_lane_rate(struct dw_mipi_dsi *dsi)
546*4882a593Smuzhiyun {
547*4882a593Smuzhiyun 	const struct drm_display_mode *mode = &dsi->mode;
548*4882a593Smuzhiyun 	unsigned long max_lane_rate = dsi->pdata->max_bit_rate_per_lane;
549*4882a593Smuzhiyun 	unsigned long lane_rate;
550*4882a593Smuzhiyun 	unsigned int value;
551*4882a593Smuzhiyun 	int bpp, lanes;
552*4882a593Smuzhiyun 	u64 tmp;
553*4882a593Smuzhiyun 
554*4882a593Smuzhiyun 	/* optional override of the desired bandwidth */
555*4882a593Smuzhiyun 	value = dev_read_u32_default(dsi->dev, "rockchip,lane-rate", 0);
556*4882a593Smuzhiyun 	if (value > 0)
557*4882a593Smuzhiyun 		return value * 1000 * 1000;
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun 	bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
560*4882a593Smuzhiyun 	if (bpp < 0)
561*4882a593Smuzhiyun 		bpp = 24;
562*4882a593Smuzhiyun 
563*4882a593Smuzhiyun 	lanes = dsi->slave ? dsi->lanes * 2 : dsi->lanes;
564*4882a593Smuzhiyun 	tmp = (u64)mode->clock * 1000 * bpp;
565*4882a593Smuzhiyun 	do_div(tmp, lanes);
566*4882a593Smuzhiyun 
567*4882a593Smuzhiyun 	/* take 1 / 0.9, since mbps must big than bandwidth of RGB */
568*4882a593Smuzhiyun 	tmp *= 10;
569*4882a593Smuzhiyun 	do_div(tmp, 9);
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun 	if (tmp > max_lane_rate)
572*4882a593Smuzhiyun 		lane_rate = max_lane_rate;
573*4882a593Smuzhiyun 	else
574*4882a593Smuzhiyun 		lane_rate = tmp;
575*4882a593Smuzhiyun 
576*4882a593Smuzhiyun 	return lane_rate;
577*4882a593Smuzhiyun }
578*4882a593Smuzhiyun 
dw_mipi_dsi_set_pll(struct dw_mipi_dsi * dsi,unsigned long rate)579*4882a593Smuzhiyun static void dw_mipi_dsi_set_pll(struct dw_mipi_dsi *dsi, unsigned long rate)
580*4882a593Smuzhiyun {
581*4882a593Smuzhiyun 	unsigned long fin, fout;
582*4882a593Smuzhiyun 	unsigned long fvco_min, fvco_max, best_freq = 984000000;
583*4882a593Smuzhiyun 	u8 min_prediv, max_prediv;
584*4882a593Smuzhiyun 	u8 _prediv, best_prediv = 2;
585*4882a593Smuzhiyun 	u16 _fbdiv, best_fbdiv = 82;
586*4882a593Smuzhiyun 	u32 min_delta = ~0U;
587*4882a593Smuzhiyun 
588*4882a593Smuzhiyun 	fin = 24000000;
589*4882a593Smuzhiyun 	fout = rate;
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun 	/* 5Mhz < Fref / N < 40MHz, 80MHz < Fvco < 1500Mhz */
592*4882a593Smuzhiyun 	min_prediv = DIV_ROUND_UP(fin, 40000000);
593*4882a593Smuzhiyun 	max_prediv = fin / 5000000;
594*4882a593Smuzhiyun 	fvco_min = 80000000;
595*4882a593Smuzhiyun 	fvco_max = 1500000000;
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun 	for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) {
598*4882a593Smuzhiyun 		u64 tmp, _fout;
599*4882a593Smuzhiyun 		u32 delta;
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun 		/* Fvco = Fref * M / N */
602*4882a593Smuzhiyun 		tmp = (u64)fout * _prediv;
603*4882a593Smuzhiyun 		do_div(tmp, fin);
604*4882a593Smuzhiyun 		_fbdiv = tmp;
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun 		/*
607*4882a593Smuzhiyun 		 * Due to the use of a "by 2 pre-scaler," the range of the
608*4882a593Smuzhiyun 		 * feedback multiplication value M is limited to even division
609*4882a593Smuzhiyun 		 * numbers, and m must be greater than 12, less than 1000.
610*4882a593Smuzhiyun 		 */
611*4882a593Smuzhiyun 		if (_fbdiv <= 12 || _fbdiv >= 1000)
612*4882a593Smuzhiyun 			continue;
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun 		if (_fbdiv % 2)
615*4882a593Smuzhiyun 			++_fbdiv;
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun 		_fout = (u64)_fbdiv * fin;
618*4882a593Smuzhiyun 		do_div(_fout, _prediv);
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun 		if (_fout < fvco_min || _fout > fvco_max)
621*4882a593Smuzhiyun 			continue;
622*4882a593Smuzhiyun 
623*4882a593Smuzhiyun 		delta = abs(fout - _fout);
624*4882a593Smuzhiyun 		if (!delta) {
625*4882a593Smuzhiyun 			best_prediv = _prediv;
626*4882a593Smuzhiyun 			best_fbdiv = _fbdiv;
627*4882a593Smuzhiyun 			best_freq = _fout;
628*4882a593Smuzhiyun 			break;
629*4882a593Smuzhiyun 		} else if (delta < min_delta) {
630*4882a593Smuzhiyun 			best_prediv = _prediv;
631*4882a593Smuzhiyun 			best_fbdiv = _fbdiv;
632*4882a593Smuzhiyun 			best_freq = _fout;
633*4882a593Smuzhiyun 			min_delta = delta;
634*4882a593Smuzhiyun 		}
635*4882a593Smuzhiyun 	}
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun 	dsi->lane_mbps = best_freq / 1000 / 1000;
638*4882a593Smuzhiyun 	dsi->dphy.input_div = best_prediv;
639*4882a593Smuzhiyun 	dsi->dphy.feedback_div = best_fbdiv;
640*4882a593Smuzhiyun 	if (dsi->slave) {
641*4882a593Smuzhiyun 		dsi->slave->lane_mbps = dsi->lane_mbps;
642*4882a593Smuzhiyun 		dsi->slave->dphy.input_div = dsi->dphy.input_div;
643*4882a593Smuzhiyun 		dsi->slave->dphy.feedback_div = dsi->dphy.feedback_div;
644*4882a593Smuzhiyun 	}
645*4882a593Smuzhiyun 	if (dsi->master) {
646*4882a593Smuzhiyun 		dsi->master->lane_mbps = dsi->lane_mbps;
647*4882a593Smuzhiyun 		dsi->master->dphy.input_div = dsi->dphy.input_div;
648*4882a593Smuzhiyun 		dsi->master->dphy.feedback_div = dsi->dphy.feedback_div;
649*4882a593Smuzhiyun 	}
650*4882a593Smuzhiyun }
651*4882a593Smuzhiyun 
dw_mipi_dsi_read_from_fifo(struct dw_mipi_dsi * dsi,const struct mipi_dsi_msg * msg)652*4882a593Smuzhiyun static int dw_mipi_dsi_read_from_fifo(struct dw_mipi_dsi *dsi,
653*4882a593Smuzhiyun 				      const struct mipi_dsi_msg *msg)
654*4882a593Smuzhiyun {
655*4882a593Smuzhiyun 	u8 *payload = msg->rx_buf;
656*4882a593Smuzhiyun 	u16 length;
657*4882a593Smuzhiyun 	u32 val;
658*4882a593Smuzhiyun 	int ret;
659*4882a593Smuzhiyun 
660*4882a593Smuzhiyun 	ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
661*4882a593Smuzhiyun 				 val, !(val & GEN_RD_CMD_BUSY), 5000);
662*4882a593Smuzhiyun 	if (ret) {
663*4882a593Smuzhiyun 		printf("entire response isn't stored in the FIFO\n");
664*4882a593Smuzhiyun 		return ret;
665*4882a593Smuzhiyun 	}
666*4882a593Smuzhiyun 
667*4882a593Smuzhiyun 	/* Receive payload */
668*4882a593Smuzhiyun 	for (length = msg->rx_len; length; length -= 4) {
669*4882a593Smuzhiyun 		ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
670*4882a593Smuzhiyun 					 val, !(val & GEN_PLD_R_EMPTY), 5000);
671*4882a593Smuzhiyun 		if (ret) {
672*4882a593Smuzhiyun 			printf("Read payload FIFO is empty\n");
673*4882a593Smuzhiyun 			return ret;
674*4882a593Smuzhiyun 		}
675*4882a593Smuzhiyun 
676*4882a593Smuzhiyun 		val = dsi_read(dsi, DSI_GEN_PLD_DATA);
677*4882a593Smuzhiyun 
678*4882a593Smuzhiyun 		switch (length) {
679*4882a593Smuzhiyun 		case 3:
680*4882a593Smuzhiyun 			payload[2] = (val >> 16) & 0xff;
681*4882a593Smuzhiyun 			/* Fall through */
682*4882a593Smuzhiyun 		case 2:
683*4882a593Smuzhiyun 			payload[1] = (val >> 8) & 0xff;
684*4882a593Smuzhiyun 			/* Fall through */
685*4882a593Smuzhiyun 		case 1:
686*4882a593Smuzhiyun 			payload[0] = val & 0xff;
687*4882a593Smuzhiyun 			return 0;
688*4882a593Smuzhiyun 		}
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun 		payload[0] = (val >>  0) & 0xff;
691*4882a593Smuzhiyun 		payload[1] = (val >>  8) & 0xff;
692*4882a593Smuzhiyun 		payload[2] = (val >> 16) & 0xff;
693*4882a593Smuzhiyun 		payload[3] = (val >> 24) & 0xff;
694*4882a593Smuzhiyun 		payload += 4;
695*4882a593Smuzhiyun 	}
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun 	return 0;
698*4882a593Smuzhiyun }
699*4882a593Smuzhiyun 
dw_mipi_dsi_turn_on_peripheral(struct dw_mipi_dsi * dsi)700*4882a593Smuzhiyun static int dw_mipi_dsi_turn_on_peripheral(struct dw_mipi_dsi *dsi)
701*4882a593Smuzhiyun {
702*4882a593Smuzhiyun 	dpishutdn_assert(dsi);
703*4882a593Smuzhiyun 	udelay(20);
704*4882a593Smuzhiyun 	dpishutdn_deassert(dsi);
705*4882a593Smuzhiyun 
706*4882a593Smuzhiyun 	return 0;
707*4882a593Smuzhiyun }
708*4882a593Smuzhiyun 
dw_mipi_dsi_shutdown_peripheral(struct dw_mipi_dsi * dsi)709*4882a593Smuzhiyun static int dw_mipi_dsi_shutdown_peripheral(struct dw_mipi_dsi *dsi)
710*4882a593Smuzhiyun {
711*4882a593Smuzhiyun 	dpishutdn_deassert(dsi);
712*4882a593Smuzhiyun 	udelay(20);
713*4882a593Smuzhiyun 	dpishutdn_assert(dsi);
714*4882a593Smuzhiyun 
715*4882a593Smuzhiyun 	return 0;
716*4882a593Smuzhiyun }
717*4882a593Smuzhiyun 
dw_mipi_dsi_transfer(struct dw_mipi_dsi * dsi,const struct mipi_dsi_msg * msg)718*4882a593Smuzhiyun static ssize_t dw_mipi_dsi_transfer(struct dw_mipi_dsi *dsi,
719*4882a593Smuzhiyun 				    const struct mipi_dsi_msg *msg)
720*4882a593Smuzhiyun {
721*4882a593Smuzhiyun 	struct mipi_dsi_packet packet;
722*4882a593Smuzhiyun 	int ret;
723*4882a593Smuzhiyun 	int val;
724*4882a593Smuzhiyun 
725*4882a593Smuzhiyun 	if (msg->flags & MIPI_DSI_MSG_USE_LPM) {
726*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_VID_MODE_CFG, LP_CMD_EN, LP_CMD_EN);
727*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS, 0);
728*4882a593Smuzhiyun 	} else {
729*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_VID_MODE_CFG, LP_CMD_EN, 0);
730*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_LPCLK_CTRL,
731*4882a593Smuzhiyun 				PHY_TXREQUESTCLKHS, PHY_TXREQUESTCLKHS);
732*4882a593Smuzhiyun 	}
733*4882a593Smuzhiyun 
734*4882a593Smuzhiyun 	switch (msg->type) {
735*4882a593Smuzhiyun 	case MIPI_DSI_SHUTDOWN_PERIPHERAL:
736*4882a593Smuzhiyun 		return dw_mipi_dsi_shutdown_peripheral(dsi);
737*4882a593Smuzhiyun 	case MIPI_DSI_TURN_ON_PERIPHERAL:
738*4882a593Smuzhiyun 		return dw_mipi_dsi_turn_on_peripheral(dsi);
739*4882a593Smuzhiyun 	case MIPI_DSI_DCS_SHORT_WRITE:
740*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_CMD_MODE_CFG, DCS_SW_0P_TX,
741*4882a593Smuzhiyun 				dsi->mode_flags & MIPI_DSI_MODE_LPM ?
742*4882a593Smuzhiyun 				DCS_SW_0P_TX : 0);
743*4882a593Smuzhiyun 		break;
744*4882a593Smuzhiyun 	case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
745*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_CMD_MODE_CFG, DCS_SW_1P_TX,
746*4882a593Smuzhiyun 				dsi->mode_flags & MIPI_DSI_MODE_LPM ?
747*4882a593Smuzhiyun 				DCS_SW_1P_TX : 0);
748*4882a593Smuzhiyun 		break;
749*4882a593Smuzhiyun 	case MIPI_DSI_DCS_LONG_WRITE:
750*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_CMD_MODE_CFG, DCS_LW_TX,
751*4882a593Smuzhiyun 				dsi->mode_flags & MIPI_DSI_MODE_LPM ?
752*4882a593Smuzhiyun 				DCS_LW_TX : 0);
753*4882a593Smuzhiyun 		break;
754*4882a593Smuzhiyun 	case MIPI_DSI_DCS_READ:
755*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_CMD_MODE_CFG, DCS_SR_0P_TX,
756*4882a593Smuzhiyun 				dsi->mode_flags & MIPI_DSI_MODE_LPM ?
757*4882a593Smuzhiyun 				DCS_SR_0P_TX : 0);
758*4882a593Smuzhiyun 		break;
759*4882a593Smuzhiyun 	case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
760*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_CMD_MODE_CFG, MAX_RD_PKT_SIZE,
761*4882a593Smuzhiyun 				dsi->mode_flags & MIPI_DSI_MODE_LPM ?
762*4882a593Smuzhiyun 				MAX_RD_PKT_SIZE : 0);
763*4882a593Smuzhiyun 		break;
764*4882a593Smuzhiyun 	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
765*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_CMD_MODE_CFG, GEN_SW_0P_TX,
766*4882a593Smuzhiyun 				dsi->mode_flags & MIPI_DSI_MODE_LPM ?
767*4882a593Smuzhiyun 				GEN_SW_0P_TX : 0);
768*4882a593Smuzhiyun 		break;
769*4882a593Smuzhiyun 	case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
770*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_CMD_MODE_CFG, GEN_SW_1P_TX,
771*4882a593Smuzhiyun 				dsi->mode_flags & MIPI_DSI_MODE_LPM ?
772*4882a593Smuzhiyun 				GEN_SW_1P_TX : 0);
773*4882a593Smuzhiyun 		break;
774*4882a593Smuzhiyun 	case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
775*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_CMD_MODE_CFG, GEN_SW_2P_TX,
776*4882a593Smuzhiyun 				dsi->mode_flags & MIPI_DSI_MODE_LPM ?
777*4882a593Smuzhiyun 				GEN_SW_2P_TX : 0);
778*4882a593Smuzhiyun 		break;
779*4882a593Smuzhiyun 	case MIPI_DSI_GENERIC_LONG_WRITE:
780*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_CMD_MODE_CFG, GEN_LW_TX,
781*4882a593Smuzhiyun 				dsi->mode_flags & MIPI_DSI_MODE_LPM ?
782*4882a593Smuzhiyun 				GEN_LW_TX : 0);
783*4882a593Smuzhiyun 		break;
784*4882a593Smuzhiyun 	case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
785*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_CMD_MODE_CFG, GEN_SR_0P_TX,
786*4882a593Smuzhiyun 				dsi->mode_flags & MIPI_DSI_MODE_LPM ?
787*4882a593Smuzhiyun 				GEN_SR_0P_TX : 0);
788*4882a593Smuzhiyun 		break;
789*4882a593Smuzhiyun 	case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
790*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_CMD_MODE_CFG, GEN_SR_1P_TX,
791*4882a593Smuzhiyun 				dsi->mode_flags & MIPI_DSI_MODE_LPM ?
792*4882a593Smuzhiyun 				GEN_SR_1P_TX : 0);
793*4882a593Smuzhiyun 		break;
794*4882a593Smuzhiyun 	case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
795*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_CMD_MODE_CFG, GEN_SR_2P_TX,
796*4882a593Smuzhiyun 				dsi->mode_flags & MIPI_DSI_MODE_LPM ?
797*4882a593Smuzhiyun 				GEN_SR_2P_TX : 0);
798*4882a593Smuzhiyun 		break;
799*4882a593Smuzhiyun 	default:
800*4882a593Smuzhiyun 		return -EINVAL;
801*4882a593Smuzhiyun 	}
802*4882a593Smuzhiyun 
803*4882a593Smuzhiyun 	if (msg->flags & MIPI_DSI_MSG_REQ_ACK)
804*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_CMD_MODE_CFG,
805*4882a593Smuzhiyun 				ACK_RQST_EN, ACK_RQST_EN);
806*4882a593Smuzhiyun 
807*4882a593Smuzhiyun 	/* create a packet to the DSI protocol */
808*4882a593Smuzhiyun 	ret = mipi_dsi_create_packet(&packet, msg);
809*4882a593Smuzhiyun 	if (ret) {
810*4882a593Smuzhiyun 		printf("failed to create packet: %d\n", ret);
811*4882a593Smuzhiyun 		return ret;
812*4882a593Smuzhiyun 	}
813*4882a593Smuzhiyun 
814*4882a593Smuzhiyun 	/* Send payload */
815*4882a593Smuzhiyun 	while (DIV_ROUND_UP(packet.payload_length, 4)) {
816*4882a593Smuzhiyun 		/*
817*4882a593Smuzhiyun 		 * Alternatively, you can always keep the FIFO
818*4882a593Smuzhiyun 		 * nearly full by monitoring the FIFO state until
819*4882a593Smuzhiyun 		 * it is not full, and then writea single word of data.
820*4882a593Smuzhiyun 		 * This solution is more resource consuming
821*4882a593Smuzhiyun 		 * but it simultaneously avoids FIFO starvation,
822*4882a593Smuzhiyun 		 * making it possible to use FIFO sizes smaller than
823*4882a593Smuzhiyun 		 * the amount of data of the longest packet to be written.
824*4882a593Smuzhiyun 		 */
825*4882a593Smuzhiyun 		ret = genif_wait_w_pld_fifo_not_full(dsi);
826*4882a593Smuzhiyun 		if (ret)
827*4882a593Smuzhiyun 			return ret;
828*4882a593Smuzhiyun 
829*4882a593Smuzhiyun 		if (packet.payload_length < 4) {
830*4882a593Smuzhiyun 			/* send residu payload */
831*4882a593Smuzhiyun 			val = 0;
832*4882a593Smuzhiyun 			memcpy(&val, packet.payload, packet.payload_length);
833*4882a593Smuzhiyun 			dsi_write(dsi, DSI_GEN_PLD_DATA, val);
834*4882a593Smuzhiyun 			packet.payload_length = 0;
835*4882a593Smuzhiyun 		} else {
836*4882a593Smuzhiyun 			val = get_unaligned_le32(packet.payload);
837*4882a593Smuzhiyun 			dsi_write(dsi, DSI_GEN_PLD_DATA, val);
838*4882a593Smuzhiyun 			packet.payload += 4;
839*4882a593Smuzhiyun 			packet.payload_length -= 4;
840*4882a593Smuzhiyun 		}
841*4882a593Smuzhiyun 	}
842*4882a593Smuzhiyun 
843*4882a593Smuzhiyun 	ret = genif_wait_cmd_fifo_not_full(dsi);
844*4882a593Smuzhiyun 	if (ret)
845*4882a593Smuzhiyun 		return ret;
846*4882a593Smuzhiyun 
847*4882a593Smuzhiyun 	/* Send packet header */
848*4882a593Smuzhiyun 	val = get_unaligned_le32(packet.header);
849*4882a593Smuzhiyun 	dsi_write(dsi, DSI_GEN_HDR, val);
850*4882a593Smuzhiyun 
851*4882a593Smuzhiyun 	ret = genif_wait_write_fifo_empty(dsi);
852*4882a593Smuzhiyun 	if (ret)
853*4882a593Smuzhiyun 		return ret;
854*4882a593Smuzhiyun 
855*4882a593Smuzhiyun 	if (msg->rx_len) {
856*4882a593Smuzhiyun 		ret = dw_mipi_dsi_read_from_fifo(dsi, msg);
857*4882a593Smuzhiyun 		if (ret < 0)
858*4882a593Smuzhiyun 			return ret;
859*4882a593Smuzhiyun 	}
860*4882a593Smuzhiyun 
861*4882a593Smuzhiyun 	if (dsi->slave) {
862*4882a593Smuzhiyun 		ret = dw_mipi_dsi_transfer(dsi->slave, msg);
863*4882a593Smuzhiyun 		if (ret < 0)
864*4882a593Smuzhiyun 			return ret;
865*4882a593Smuzhiyun 	}
866*4882a593Smuzhiyun 
867*4882a593Smuzhiyun 	return msg->rx_len ? msg->rx_len : msg->tx_len;
868*4882a593Smuzhiyun }
869*4882a593Smuzhiyun 
dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi * dsi)870*4882a593Smuzhiyun static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi)
871*4882a593Smuzhiyun {
872*4882a593Smuzhiyun 	u32 val = LP_VACT_EN | LP_VFP_EN | LP_VBP_EN | LP_VSA_EN |
873*4882a593Smuzhiyun 		  LP_HFP_EN | LP_HBP_EN;
874*4882a593Smuzhiyun 
875*4882a593Smuzhiyun 	if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_HFP)
876*4882a593Smuzhiyun 		val &= ~LP_HFP_EN;
877*4882a593Smuzhiyun 
878*4882a593Smuzhiyun 	if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_HBP)
879*4882a593Smuzhiyun 		val &= ~LP_HBP_EN;
880*4882a593Smuzhiyun 
881*4882a593Smuzhiyun 	if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
882*4882a593Smuzhiyun 		val |= VID_MODE_TYPE_BURST;
883*4882a593Smuzhiyun 	else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
884*4882a593Smuzhiyun 		val |= VID_MODE_TYPE_BURST_SYNC_PULSES;
885*4882a593Smuzhiyun 	else
886*4882a593Smuzhiyun 		val |= VID_MODE_TYPE_BURST_SYNC_EVENTS;
887*4882a593Smuzhiyun 
888*4882a593Smuzhiyun 	dsi_write(dsi, DSI_VID_MODE_CFG, val);
889*4882a593Smuzhiyun 
890*4882a593Smuzhiyun 	if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
891*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_LPCLK_CTRL,
892*4882a593Smuzhiyun 				AUTO_CLKLANE_CTRL, AUTO_CLKLANE_CTRL);
893*4882a593Smuzhiyun }
894*4882a593Smuzhiyun 
dw_mipi_dsi_enable(struct dw_mipi_dsi * dsi)895*4882a593Smuzhiyun static void dw_mipi_dsi_enable(struct dw_mipi_dsi *dsi)
896*4882a593Smuzhiyun {
897*4882a593Smuzhiyun 	const struct drm_display_mode *mode = &dsi->mode;
898*4882a593Smuzhiyun 
899*4882a593Smuzhiyun 	dsi_update_bits(dsi, DSI_LPCLK_CTRL,
900*4882a593Smuzhiyun 			PHY_TXREQUESTCLKHS, PHY_TXREQUESTCLKHS);
901*4882a593Smuzhiyun 
902*4882a593Smuzhiyun 	dsi_write(dsi, DSI_PWR_UP, RESET);
903*4882a593Smuzhiyun 
904*4882a593Smuzhiyun 	if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
905*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_MODE_CFG, CMD_VIDEO_MODE, VIDEO_MODE);
906*4882a593Smuzhiyun 	} else {
907*4882a593Smuzhiyun 		dsi_write(dsi, DSI_DBI_VCID, DBI_VCID(dsi->channel));
908*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_CMD_MODE_CFG, DCS_LW_TX, 0);
909*4882a593Smuzhiyun 		dsi_write(dsi, DSI_EDPI_CMD_SIZE, mode->hdisplay);
910*4882a593Smuzhiyun 		dsi_update_bits(dsi, DSI_MODE_CFG,
911*4882a593Smuzhiyun 				CMD_VIDEO_MODE, COMMAND_MODE);
912*4882a593Smuzhiyun 	}
913*4882a593Smuzhiyun 
914*4882a593Smuzhiyun 	dsi_write(dsi, DSI_PWR_UP, POWERUP);
915*4882a593Smuzhiyun 
916*4882a593Smuzhiyun 	if (dsi->slave)
917*4882a593Smuzhiyun 		dw_mipi_dsi_enable(dsi->slave);
918*4882a593Smuzhiyun }
919*4882a593Smuzhiyun 
dw_mipi_dsi_disable(struct dw_mipi_dsi * dsi)920*4882a593Smuzhiyun static void dw_mipi_dsi_disable(struct dw_mipi_dsi *dsi)
921*4882a593Smuzhiyun {
922*4882a593Smuzhiyun 	dsi_write(dsi, DSI_PWR_UP, RESET);
923*4882a593Smuzhiyun 	dsi_write(dsi, DSI_LPCLK_CTRL, 0);
924*4882a593Smuzhiyun 	dsi_write(dsi, DSI_EDPI_CMD_SIZE, 0);
925*4882a593Smuzhiyun 	dsi_update_bits(dsi, DSI_MODE_CFG, CMD_VIDEO_MODE, COMMAND_MODE);
926*4882a593Smuzhiyun 	dsi_write(dsi, DSI_PWR_UP, POWERUP);
927*4882a593Smuzhiyun 
928*4882a593Smuzhiyun 	if (dsi->slave)
929*4882a593Smuzhiyun 		dw_mipi_dsi_disable(dsi->slave);
930*4882a593Smuzhiyun }
931*4882a593Smuzhiyun 
dw_mipi_dsi_post_disable(struct dw_mipi_dsi * dsi)932*4882a593Smuzhiyun static void dw_mipi_dsi_post_disable(struct dw_mipi_dsi *dsi)
933*4882a593Smuzhiyun {
934*4882a593Smuzhiyun 	if (!dsi->prepared)
935*4882a593Smuzhiyun 		return;
936*4882a593Smuzhiyun 
937*4882a593Smuzhiyun 	if (dsi->master)
938*4882a593Smuzhiyun 		dw_mipi_dsi_post_disable(dsi->master);
939*4882a593Smuzhiyun 
940*4882a593Smuzhiyun 	dsi_write(dsi, DSI_PWR_UP, RESET);
941*4882a593Smuzhiyun 	dsi_write(dsi, DSI_PHY_RSTZ, 0);
942*4882a593Smuzhiyun 
943*4882a593Smuzhiyun 	if (dsi->dphy.phy)
944*4882a593Smuzhiyun 		rockchip_phy_power_off(dsi->dphy.phy);
945*4882a593Smuzhiyun 
946*4882a593Smuzhiyun 	dsi->prepared = false;
947*4882a593Smuzhiyun 
948*4882a593Smuzhiyun 	if (dsi->slave)
949*4882a593Smuzhiyun 		dw_mipi_dsi_post_disable(dsi->slave);
950*4882a593Smuzhiyun }
951*4882a593Smuzhiyun 
dw_mipi_dsi_init(struct dw_mipi_dsi * dsi)952*4882a593Smuzhiyun static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi)
953*4882a593Smuzhiyun {
954*4882a593Smuzhiyun 	u32 esc_clk_div;
955*4882a593Smuzhiyun 
956*4882a593Smuzhiyun 	dsi_write(dsi, DSI_PWR_UP, RESET);
957*4882a593Smuzhiyun 
958*4882a593Smuzhiyun 	/* The maximum value of the escape clock frequency is 20MHz */
959*4882a593Smuzhiyun 	esc_clk_div = DIV_ROUND_UP(dsi->lane_mbps >> 3, 20);
960*4882a593Smuzhiyun 	dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVIDSION(10) |
961*4882a593Smuzhiyun 		  TX_ESC_CLK_DIVIDSION(esc_clk_div));
962*4882a593Smuzhiyun }
963*4882a593Smuzhiyun 
dw_mipi_dsi_dpi_config(struct dw_mipi_dsi * dsi,struct drm_display_mode * mode)964*4882a593Smuzhiyun static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,
965*4882a593Smuzhiyun 				   struct drm_display_mode *mode)
966*4882a593Smuzhiyun {
967*4882a593Smuzhiyun 	u32 val = 0, color = 0;
968*4882a593Smuzhiyun 
969*4882a593Smuzhiyun 	switch (dsi->format) {
970*4882a593Smuzhiyun 	case MIPI_DSI_FMT_RGB888:
971*4882a593Smuzhiyun 		color = DPI_COLOR_CODING_24BIT;
972*4882a593Smuzhiyun 		break;
973*4882a593Smuzhiyun 	case MIPI_DSI_FMT_RGB666:
974*4882a593Smuzhiyun 		color = DPI_COLOR_CODING_18BIT_2 | EN18_LOOSELY;
975*4882a593Smuzhiyun 		break;
976*4882a593Smuzhiyun 	case MIPI_DSI_FMT_RGB666_PACKED:
977*4882a593Smuzhiyun 		color = DPI_COLOR_CODING_18BIT_1;
978*4882a593Smuzhiyun 		break;
979*4882a593Smuzhiyun 	case MIPI_DSI_FMT_RGB565:
980*4882a593Smuzhiyun 		color = DPI_COLOR_CODING_16BIT_1;
981*4882a593Smuzhiyun 		break;
982*4882a593Smuzhiyun 	}
983*4882a593Smuzhiyun 
984*4882a593Smuzhiyun 	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
985*4882a593Smuzhiyun 		val |= VSYNC_ACTIVE_LOW;
986*4882a593Smuzhiyun 	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
987*4882a593Smuzhiyun 		val |= HSYNC_ACTIVE_LOW;
988*4882a593Smuzhiyun 
989*4882a593Smuzhiyun 	dsi_write(dsi, DSI_DPI_VCID, DPI_VID(dsi->channel));
990*4882a593Smuzhiyun 	dsi_write(dsi, DSI_DPI_COLOR_CODING, color);
991*4882a593Smuzhiyun 	dsi_write(dsi, DSI_DPI_CFG_POL, val);
992*4882a593Smuzhiyun 	dsi_write(dsi, DSI_DPI_LP_CMD_TIM, OUTVACT_LPCMD_TIME(4)
993*4882a593Smuzhiyun 		  | INVACT_LPCMD_TIME(4));
994*4882a593Smuzhiyun }
995*4882a593Smuzhiyun 
dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi * dsi)996*4882a593Smuzhiyun static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi)
997*4882a593Smuzhiyun {
998*4882a593Smuzhiyun 	u32 val = CRC_RX_EN | ECC_RX_EN | BTA_EN | EOTP_TX_EN;
999*4882a593Smuzhiyun 
1000*4882a593Smuzhiyun 	if (dsi->mode_flags & MIPI_DSI_MODE_EOT_PACKET)
1001*4882a593Smuzhiyun 		val &= ~EOTP_TX_EN;
1002*4882a593Smuzhiyun 
1003*4882a593Smuzhiyun 	dsi_write(dsi, DSI_PCKHDL_CFG, val);
1004*4882a593Smuzhiyun }
1005*4882a593Smuzhiyun 
dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi * dsi,struct drm_display_mode * mode)1006*4882a593Smuzhiyun static void dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi,
1007*4882a593Smuzhiyun 					    struct drm_display_mode *mode)
1008*4882a593Smuzhiyun {
1009*4882a593Smuzhiyun 	dsi_write(dsi, DSI_VID_PKT_SIZE, VID_PKT_SIZE(mode->hdisplay));
1010*4882a593Smuzhiyun }
1011*4882a593Smuzhiyun 
dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi * dsi)1012*4882a593Smuzhiyun static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi)
1013*4882a593Smuzhiyun {
1014*4882a593Smuzhiyun 	dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000));
1015*4882a593Smuzhiyun 	dsi_write(dsi, DSI_BTA_TO_CNT, 0xd00);
1016*4882a593Smuzhiyun }
1017*4882a593Smuzhiyun 
1018*4882a593Smuzhiyun /* Get lane byte clock cycles. */
dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi * dsi,u32 hcomponent)1019*4882a593Smuzhiyun static int dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi *dsi,
1020*4882a593Smuzhiyun 					   u32 hcomponent)
1021*4882a593Smuzhiyun {
1022*4882a593Smuzhiyun 	u32 lbcc;
1023*4882a593Smuzhiyun 
1024*4882a593Smuzhiyun 	lbcc = hcomponent * dsi->lane_mbps * 1000 / 8;
1025*4882a593Smuzhiyun 
1026*4882a593Smuzhiyun 	if (!dsi->mode.clock)
1027*4882a593Smuzhiyun 		return 0;
1028*4882a593Smuzhiyun 
1029*4882a593Smuzhiyun 	return DIV_ROUND_CLOSEST(lbcc, dsi->mode.clock);
1030*4882a593Smuzhiyun }
1031*4882a593Smuzhiyun 
dw_mipi_dsi_line_timer_config(struct dw_mipi_dsi * dsi)1032*4882a593Smuzhiyun static void dw_mipi_dsi_line_timer_config(struct dw_mipi_dsi *dsi)
1033*4882a593Smuzhiyun {
1034*4882a593Smuzhiyun 	int htotal, hsa, hbp, lbcc;
1035*4882a593Smuzhiyun 	struct drm_display_mode *mode = &dsi->mode;
1036*4882a593Smuzhiyun 
1037*4882a593Smuzhiyun 	htotal = mode->htotal;
1038*4882a593Smuzhiyun 	hsa = mode->hsync_end - mode->hsync_start;
1039*4882a593Smuzhiyun 	hbp = mode->htotal - mode->hsync_end;
1040*4882a593Smuzhiyun 
1041*4882a593Smuzhiyun 	lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, htotal);
1042*4882a593Smuzhiyun 	dsi_write(dsi, DSI_VID_HLINE_TIME, lbcc);
1043*4882a593Smuzhiyun 
1044*4882a593Smuzhiyun 	lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, hsa);
1045*4882a593Smuzhiyun 	dsi_write(dsi, DSI_VID_HSA_TIME, lbcc);
1046*4882a593Smuzhiyun 
1047*4882a593Smuzhiyun 	lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, hbp);
1048*4882a593Smuzhiyun 	dsi_write(dsi, DSI_VID_HBP_TIME, lbcc);
1049*4882a593Smuzhiyun }
1050*4882a593Smuzhiyun 
dw_mipi_dsi_vertical_timing_config(struct dw_mipi_dsi * dsi)1051*4882a593Smuzhiyun static void dw_mipi_dsi_vertical_timing_config(struct dw_mipi_dsi *dsi)
1052*4882a593Smuzhiyun {
1053*4882a593Smuzhiyun 	u32 vactive, vsa, vfp, vbp;
1054*4882a593Smuzhiyun 	struct drm_display_mode *mode = &dsi->mode;
1055*4882a593Smuzhiyun 
1056*4882a593Smuzhiyun 	vactive = mode->vdisplay;
1057*4882a593Smuzhiyun 	vsa = mode->vsync_end - mode->vsync_start;
1058*4882a593Smuzhiyun 	vfp = mode->vsync_start - mode->vdisplay;
1059*4882a593Smuzhiyun 	vbp = mode->vtotal - mode->vsync_end;
1060*4882a593Smuzhiyun 
1061*4882a593Smuzhiyun 	dsi_write(dsi, DSI_VID_VACTIVE_LINES, vactive);
1062*4882a593Smuzhiyun 	dsi_write(dsi, DSI_VID_VSA_LINES, vsa);
1063*4882a593Smuzhiyun 	dsi_write(dsi, DSI_VID_VFP_LINES, vfp);
1064*4882a593Smuzhiyun 	dsi_write(dsi, DSI_VID_VBP_LINES, vbp);
1065*4882a593Smuzhiyun }
1066*4882a593Smuzhiyun 
dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi * dsi)1067*4882a593Smuzhiyun static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi)
1068*4882a593Smuzhiyun {
1069*4882a593Smuzhiyun 	dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME(0x14)
1070*4882a593Smuzhiyun 		  | PHY_LP2HS_TIME(0x10) | MAX_RD_TIME(10000));
1071*4882a593Smuzhiyun 
1072*4882a593Smuzhiyun 	dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG, PHY_CLKHS2LP_TIME(0x40)
1073*4882a593Smuzhiyun 		  | PHY_CLKLP2HS_TIME(0x40));
1074*4882a593Smuzhiyun }
1075*4882a593Smuzhiyun 
dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi * dsi)1076*4882a593Smuzhiyun static void dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi *dsi)
1077*4882a593Smuzhiyun {
1078*4882a593Smuzhiyun 	dsi_write(dsi, DSI_PHY_IF_CFG, PHY_STOP_WAIT_TIME(0x20) |
1079*4882a593Smuzhiyun 		  N_LANES(dsi->lanes));
1080*4882a593Smuzhiyun }
1081*4882a593Smuzhiyun 
dw_mipi_dsi_clear_err(struct dw_mipi_dsi * dsi)1082*4882a593Smuzhiyun static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi)
1083*4882a593Smuzhiyun {
1084*4882a593Smuzhiyun 	dsi_read(dsi, DSI_INT_ST0);
1085*4882a593Smuzhiyun 	dsi_read(dsi, DSI_INT_ST1);
1086*4882a593Smuzhiyun 	dsi_write(dsi, DSI_INT_MSK0, 0);
1087*4882a593Smuzhiyun 	dsi_write(dsi, DSI_INT_MSK1, 0);
1088*4882a593Smuzhiyun }
1089*4882a593Smuzhiyun 
dw_mipi_dsi_connector_init(struct rockchip_connector * conn,struct display_state * state)1090*4882a593Smuzhiyun static int dw_mipi_dsi_connector_init(struct rockchip_connector *conn, struct display_state *state)
1091*4882a593Smuzhiyun {
1092*4882a593Smuzhiyun 	struct connector_state *conn_state = &state->conn_state;
1093*4882a593Smuzhiyun 	struct dw_mipi_dsi *dsi = dev_get_priv(conn->dev);
1094*4882a593Smuzhiyun 
1095*4882a593Smuzhiyun 	conn_state->disp_info  = rockchip_get_disp_info(conn_state->type, dsi->id);
1096*4882a593Smuzhiyun 	dsi->dphy.phy = conn->phy;
1097*4882a593Smuzhiyun 
1098*4882a593Smuzhiyun 	conn_state->output_mode = ROCKCHIP_OUT_MODE_P888;
1099*4882a593Smuzhiyun 	conn_state->color_space = V4L2_COLORSPACE_DEFAULT;
1100*4882a593Smuzhiyun 	conn_state->output_if |=
1101*4882a593Smuzhiyun 		dsi->id ? VOP_OUTPUT_IF_MIPI1 : VOP_OUTPUT_IF_MIPI0;
1102*4882a593Smuzhiyun 
1103*4882a593Smuzhiyun #ifndef CONFIG_ROCKCHIP_RK3568
1104*4882a593Smuzhiyun 	if (dsi->id) {
1105*4882a593Smuzhiyun 		struct udevice *dev;
1106*4882a593Smuzhiyun 		int ret;
1107*4882a593Smuzhiyun 
1108*4882a593Smuzhiyun 		ret = uclass_get_device_by_name(UCLASS_DISPLAY, "dsi@ff960000",
1109*4882a593Smuzhiyun 						&dev);
1110*4882a593Smuzhiyun 		if (ret)
1111*4882a593Smuzhiyun 			return ret;
1112*4882a593Smuzhiyun 
1113*4882a593Smuzhiyun 		dsi->master = dev_get_priv(dev);
1114*4882a593Smuzhiyun 		if (!dsi->master)
1115*4882a593Smuzhiyun 			return -ENODEV;
1116*4882a593Smuzhiyun 
1117*4882a593Smuzhiyun 		conn_state->output_flags = ROCKCHIP_OUTPUT_DATA_SWAP;
1118*4882a593Smuzhiyun 	}
1119*4882a593Smuzhiyun #endif
1120*4882a593Smuzhiyun 
1121*4882a593Smuzhiyun 	if (dsi->lanes > 4) {
1122*4882a593Smuzhiyun 		struct udevice *dev;
1123*4882a593Smuzhiyun 		int ret;
1124*4882a593Smuzhiyun 
1125*4882a593Smuzhiyun 		ret = uclass_get_device_by_name(UCLASS_DISPLAY,
1126*4882a593Smuzhiyun #if defined(CONFIG_ROCKCHIP_RK3288)
1127*4882a593Smuzhiyun 						"dsi@ff964000",
1128*4882a593Smuzhiyun #elif defined(CONFIG_ROCKCHIP_RK3399)
1129*4882a593Smuzhiyun 						"dsi@ff968000",
1130*4882a593Smuzhiyun #else
1131*4882a593Smuzhiyun 						"dsi@fe070000",
1132*4882a593Smuzhiyun #endif
1133*4882a593Smuzhiyun 						&dev);
1134*4882a593Smuzhiyun 		if (ret)
1135*4882a593Smuzhiyun 			return ret;
1136*4882a593Smuzhiyun 
1137*4882a593Smuzhiyun 		dsi->slave = dev_get_priv(dev);
1138*4882a593Smuzhiyun 		if (!dsi->slave)
1139*4882a593Smuzhiyun 			return -ENODEV;
1140*4882a593Smuzhiyun 
1141*4882a593Smuzhiyun 		dsi->lanes /= 2;
1142*4882a593Smuzhiyun 		dsi->slave->lanes = dsi->lanes;
1143*4882a593Smuzhiyun 		dsi->slave->format = dsi->format;
1144*4882a593Smuzhiyun 		dsi->slave->mode_flags = dsi->mode_flags;
1145*4882a593Smuzhiyun 		dsi->slave->channel = dsi->channel;
1146*4882a593Smuzhiyun 		conn_state->output_flags =
1147*4882a593Smuzhiyun 				ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
1148*4882a593Smuzhiyun 		if (dsi->data_swap)
1149*4882a593Smuzhiyun 			conn_state->output_flags |= ROCKCHIP_OUTPUT_DATA_SWAP;
1150*4882a593Smuzhiyun 
1151*4882a593Smuzhiyun 		conn_state->output_if |= VOP_OUTPUT_IF_MIPI1;
1152*4882a593Smuzhiyun 
1153*4882a593Smuzhiyun #if defined(CONFIG_ROCKCHIP_RK3568)
1154*4882a593Smuzhiyun 		struct rockchip_phy *phy = NULL;
1155*4882a593Smuzhiyun 		struct udevice *phy_dev;
1156*4882a593Smuzhiyun 
1157*4882a593Smuzhiyun 		ret = uclass_get_device_by_phandle(UCLASS_PHY, dev,
1158*4882a593Smuzhiyun 						   "phys", &phy_dev);
1159*4882a593Smuzhiyun 		if (ret)
1160*4882a593Smuzhiyun 			return -ENODEV;
1161*4882a593Smuzhiyun 
1162*4882a593Smuzhiyun 		phy = (struct rockchip_phy *)dev_get_driver_data(phy_dev);
1163*4882a593Smuzhiyun 		if (!phy)
1164*4882a593Smuzhiyun 			return -ENODEV;
1165*4882a593Smuzhiyun 
1166*4882a593Smuzhiyun 		dsi->slave->dphy.phy = phy;
1167*4882a593Smuzhiyun 		if (phy->funcs && phy->funcs->init)
1168*4882a593Smuzhiyun 			return phy->funcs->init(phy);
1169*4882a593Smuzhiyun #endif
1170*4882a593Smuzhiyun 
1171*4882a593Smuzhiyun 	}
1172*4882a593Smuzhiyun 
1173*4882a593Smuzhiyun 	return 0;
1174*4882a593Smuzhiyun }
1175*4882a593Smuzhiyun 
dw_mipi_dsi_set_hs_clk(struct dw_mipi_dsi * dsi,unsigned long rate)1176*4882a593Smuzhiyun static void dw_mipi_dsi_set_hs_clk(struct dw_mipi_dsi *dsi, unsigned long rate)
1177*4882a593Smuzhiyun {
1178*4882a593Smuzhiyun 	rate = rockchip_phy_set_pll(dsi->dphy.phy, rate);
1179*4882a593Smuzhiyun 	dsi->lane_mbps = rate / 1000 / 1000;
1180*4882a593Smuzhiyun }
1181*4882a593Smuzhiyun 
dw_mipi_dsi_host_init(struct dw_mipi_dsi * dsi)1182*4882a593Smuzhiyun static void dw_mipi_dsi_host_init(struct dw_mipi_dsi *dsi)
1183*4882a593Smuzhiyun {
1184*4882a593Smuzhiyun 	dw_mipi_dsi_init(dsi);
1185*4882a593Smuzhiyun 	dw_mipi_dsi_dpi_config(dsi, &dsi->mode);
1186*4882a593Smuzhiyun 	dw_mipi_dsi_packet_handler_config(dsi);
1187*4882a593Smuzhiyun 	dw_mipi_dsi_video_mode_config(dsi);
1188*4882a593Smuzhiyun 	dw_mipi_dsi_video_packet_config(dsi, &dsi->mode);
1189*4882a593Smuzhiyun 	dw_mipi_dsi_command_mode_config(dsi);
1190*4882a593Smuzhiyun 	dsi_update_bits(dsi, DSI_MODE_CFG, CMD_VIDEO_MODE, COMMAND_MODE);
1191*4882a593Smuzhiyun 	dw_mipi_dsi_line_timer_config(dsi);
1192*4882a593Smuzhiyun 	dw_mipi_dsi_vertical_timing_config(dsi);
1193*4882a593Smuzhiyun 	dw_mipi_dsi_dphy_timing_config(dsi);
1194*4882a593Smuzhiyun 	dw_mipi_dsi_dphy_interface_config(dsi);
1195*4882a593Smuzhiyun 	dw_mipi_dsi_clear_err(dsi);
1196*4882a593Smuzhiyun }
1197*4882a593Smuzhiyun 
dw_mipi_dsi_vop_routing(struct dw_mipi_dsi * dsi,int vop_id)1198*4882a593Smuzhiyun static void dw_mipi_dsi_vop_routing(struct dw_mipi_dsi *dsi, int vop_id)
1199*4882a593Smuzhiyun {
1200*4882a593Smuzhiyun 	grf_field_write(dsi, VOPSEL, vop_id);
1201*4882a593Smuzhiyun 
1202*4882a593Smuzhiyun 	if (dsi->slave)
1203*4882a593Smuzhiyun 		grf_field_write(dsi->slave, VOPSEL, vop_id);
1204*4882a593Smuzhiyun }
1205*4882a593Smuzhiyun 
mipi_dphy_init(struct dw_mipi_dsi * dsi)1206*4882a593Smuzhiyun static void mipi_dphy_init(struct dw_mipi_dsi *dsi)
1207*4882a593Smuzhiyun {
1208*4882a593Smuzhiyun 	u32 map[] = {0x0, 0x1, 0x3, 0x7, 0xf};
1209*4882a593Smuzhiyun 
1210*4882a593Smuzhiyun 	mipi_dphy_enableclk_deassert(dsi);
1211*4882a593Smuzhiyun 	mipi_dphy_shutdownz_assert(dsi);
1212*4882a593Smuzhiyun 	mipi_dphy_rstz_assert(dsi);
1213*4882a593Smuzhiyun 	testif_testclr_assert(dsi);
1214*4882a593Smuzhiyun 
1215*4882a593Smuzhiyun 	/* Configures DPHY to work as a Master */
1216*4882a593Smuzhiyun 	grf_field_write(dsi, MASTERSLAVEZ, 1);
1217*4882a593Smuzhiyun 
1218*4882a593Smuzhiyun 	/* Configures lane as TX */
1219*4882a593Smuzhiyun 	grf_field_write(dsi, BASEDIR, 0);
1220*4882a593Smuzhiyun 
1221*4882a593Smuzhiyun 	/* Set all REQUEST inputs to zero */
1222*4882a593Smuzhiyun 	grf_field_write(dsi, TURNREQUEST, 0);
1223*4882a593Smuzhiyun 	grf_field_write(dsi, TURNDISABLE, 0);
1224*4882a593Smuzhiyun 	grf_field_write(dsi, FORCETXSTOPMODE, 0);
1225*4882a593Smuzhiyun 	grf_field_write(dsi, FORCERXMODE, 0);
1226*4882a593Smuzhiyun 	udelay(1);
1227*4882a593Smuzhiyun 
1228*4882a593Smuzhiyun 	testif_testclr_deassert(dsi);
1229*4882a593Smuzhiyun 
1230*4882a593Smuzhiyun 	if (!dsi->dphy.phy)
1231*4882a593Smuzhiyun 		dw_mipi_dsi_phy_init(dsi);
1232*4882a593Smuzhiyun 
1233*4882a593Smuzhiyun 	/* Enable Data Lane Module */
1234*4882a593Smuzhiyun 	grf_field_write(dsi, ENABLE_N, map[dsi->lanes]);
1235*4882a593Smuzhiyun 
1236*4882a593Smuzhiyun 	/* Enable Clock Lane Module */
1237*4882a593Smuzhiyun 	grf_field_write(dsi, ENABLECLK, 1);
1238*4882a593Smuzhiyun 
1239*4882a593Smuzhiyun 	mipi_dphy_enableclk_assert(dsi);
1240*4882a593Smuzhiyun }
1241*4882a593Smuzhiyun 
dw_mipi_dsi_pre_enable(struct dw_mipi_dsi * dsi)1242*4882a593Smuzhiyun static void dw_mipi_dsi_pre_enable(struct dw_mipi_dsi *dsi)
1243*4882a593Smuzhiyun {
1244*4882a593Smuzhiyun 	if (dsi->prepared)
1245*4882a593Smuzhiyun 		return;
1246*4882a593Smuzhiyun 
1247*4882a593Smuzhiyun 	if (dsi->master)
1248*4882a593Smuzhiyun 		dw_mipi_dsi_pre_enable(dsi->master);
1249*4882a593Smuzhiyun 
1250*4882a593Smuzhiyun 	dw_mipi_dsi_host_init(dsi);
1251*4882a593Smuzhiyun 	mipi_dphy_init(dsi);
1252*4882a593Smuzhiyun 	mipi_dphy_power_on(dsi);
1253*4882a593Smuzhiyun 	dsi_write(dsi, DSI_PWR_UP, POWERUP);
1254*4882a593Smuzhiyun 
1255*4882a593Smuzhiyun 	dsi->prepared = true;
1256*4882a593Smuzhiyun 
1257*4882a593Smuzhiyun 	if (dsi->slave)
1258*4882a593Smuzhiyun 		dw_mipi_dsi_pre_enable(dsi->slave);
1259*4882a593Smuzhiyun }
1260*4882a593Smuzhiyun 
dw_mipi_dsi_connector_prepare(struct rockchip_connector * conn,struct display_state * state)1261*4882a593Smuzhiyun static int dw_mipi_dsi_connector_prepare(struct rockchip_connector *conn,
1262*4882a593Smuzhiyun 					 struct display_state *state)
1263*4882a593Smuzhiyun {
1264*4882a593Smuzhiyun 	struct connector_state *conn_state = &state->conn_state;
1265*4882a593Smuzhiyun 	struct crtc_state *crtc_state = &state->crtc_state;
1266*4882a593Smuzhiyun 	struct dw_mipi_dsi *dsi = dev_get_priv(conn->dev);
1267*4882a593Smuzhiyun 	unsigned long lane_rate;
1268*4882a593Smuzhiyun 
1269*4882a593Smuzhiyun 	memcpy(&dsi->mode, &conn_state->mode, sizeof(struct drm_display_mode));
1270*4882a593Smuzhiyun 	if (dsi->slave) {
1271*4882a593Smuzhiyun 		dsi->mode.hdisplay /= 2;
1272*4882a593Smuzhiyun 		memcpy(&dsi->slave->mode, &dsi->mode,
1273*4882a593Smuzhiyun 		       sizeof(struct drm_display_mode));
1274*4882a593Smuzhiyun 	}
1275*4882a593Smuzhiyun 
1276*4882a593Smuzhiyun 	lane_rate = dw_mipi_dsi_get_lane_rate(dsi);
1277*4882a593Smuzhiyun 	if (dsi->dphy.phy)
1278*4882a593Smuzhiyun 		dw_mipi_dsi_set_hs_clk(dsi, lane_rate);
1279*4882a593Smuzhiyun 	else
1280*4882a593Smuzhiyun 		dw_mipi_dsi_set_pll(dsi, lane_rate);
1281*4882a593Smuzhiyun 
1282*4882a593Smuzhiyun 	if (dsi->slave && dsi->slave->dphy.phy)
1283*4882a593Smuzhiyun 		dw_mipi_dsi_set_hs_clk(dsi->slave, lane_rate);
1284*4882a593Smuzhiyun 
1285*4882a593Smuzhiyun 	printf("final DSI-Link bandwidth: %u Mbps x %d\n",
1286*4882a593Smuzhiyun 	       dsi->lane_mbps, dsi->slave ? dsi->lanes * 2 : dsi->lanes);
1287*4882a593Smuzhiyun 
1288*4882a593Smuzhiyun 	dw_mipi_dsi_vop_routing(dsi, crtc_state->crtc_id);
1289*4882a593Smuzhiyun 	dw_mipi_dsi_pre_enable(dsi);
1290*4882a593Smuzhiyun 
1291*4882a593Smuzhiyun 	return 0;
1292*4882a593Smuzhiyun }
1293*4882a593Smuzhiyun 
dw_mipi_dsi_connector_unprepare(struct rockchip_connector * conn,struct display_state * state)1294*4882a593Smuzhiyun static void dw_mipi_dsi_connector_unprepare(struct rockchip_connector *conn,
1295*4882a593Smuzhiyun 					    struct display_state *state)
1296*4882a593Smuzhiyun {
1297*4882a593Smuzhiyun 	struct dw_mipi_dsi *dsi = dev_get_priv(conn->dev);
1298*4882a593Smuzhiyun 
1299*4882a593Smuzhiyun 	dw_mipi_dsi_post_disable(dsi);
1300*4882a593Smuzhiyun }
1301*4882a593Smuzhiyun 
dw_mipi_dsi_connector_enable(struct rockchip_connector * conn,struct display_state * state)1302*4882a593Smuzhiyun static int dw_mipi_dsi_connector_enable(struct rockchip_connector *conn,
1303*4882a593Smuzhiyun 					struct display_state *state)
1304*4882a593Smuzhiyun {
1305*4882a593Smuzhiyun 	struct dw_mipi_dsi *dsi = dev_get_priv(conn->dev);
1306*4882a593Smuzhiyun 
1307*4882a593Smuzhiyun 	dw_mipi_dsi_enable(dsi);
1308*4882a593Smuzhiyun 
1309*4882a593Smuzhiyun 	return 0;
1310*4882a593Smuzhiyun }
1311*4882a593Smuzhiyun 
dw_mipi_dsi_connector_disable(struct rockchip_connector * conn,struct display_state * state)1312*4882a593Smuzhiyun static int dw_mipi_dsi_connector_disable(struct rockchip_connector *conn,
1313*4882a593Smuzhiyun 					 struct display_state *state)
1314*4882a593Smuzhiyun {
1315*4882a593Smuzhiyun 	struct dw_mipi_dsi *dsi = dev_get_priv(conn->dev);
1316*4882a593Smuzhiyun 
1317*4882a593Smuzhiyun 	dw_mipi_dsi_disable(dsi);
1318*4882a593Smuzhiyun 
1319*4882a593Smuzhiyun 	return 0;
1320*4882a593Smuzhiyun }
1321*4882a593Smuzhiyun 
1322*4882a593Smuzhiyun static const struct rockchip_connector_funcs dw_mipi_dsi_connector_funcs = {
1323*4882a593Smuzhiyun 	.init = dw_mipi_dsi_connector_init,
1324*4882a593Smuzhiyun 	.prepare = dw_mipi_dsi_connector_prepare,
1325*4882a593Smuzhiyun 	.unprepare = dw_mipi_dsi_connector_unprepare,
1326*4882a593Smuzhiyun 	.enable = dw_mipi_dsi_connector_enable,
1327*4882a593Smuzhiyun 	.disable = dw_mipi_dsi_connector_disable,
1328*4882a593Smuzhiyun };
1329*4882a593Smuzhiyun 
dw_mipi_dsi_probe(struct udevice * dev)1330*4882a593Smuzhiyun static int dw_mipi_dsi_probe(struct udevice *dev)
1331*4882a593Smuzhiyun {
1332*4882a593Smuzhiyun 	struct dw_mipi_dsi *dsi = dev_get_priv(dev);
1333*4882a593Smuzhiyun 	const struct dw_mipi_dsi_plat_data *pdata =
1334*4882a593Smuzhiyun 		(const struct dw_mipi_dsi_plat_data *)dev_get_driver_data(dev);
1335*4882a593Smuzhiyun 	int id;
1336*4882a593Smuzhiyun 
1337*4882a593Smuzhiyun 	dsi->base = dev_read_addr_ptr(dev);
1338*4882a593Smuzhiyun 	dsi->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
1339*4882a593Smuzhiyun 	if (IS_ERR(dsi->grf))
1340*4882a593Smuzhiyun 		return PTR_ERR(dsi->grf);
1341*4882a593Smuzhiyun 
1342*4882a593Smuzhiyun 	id = of_alias_get_id(ofnode_to_np(dev->node), "dsi");
1343*4882a593Smuzhiyun 	if (id < 0)
1344*4882a593Smuzhiyun 		id = 0;
1345*4882a593Smuzhiyun 
1346*4882a593Smuzhiyun 	dsi->dev = dev;
1347*4882a593Smuzhiyun 	dsi->pdata = pdata;
1348*4882a593Smuzhiyun 	dsi->id = id;
1349*4882a593Smuzhiyun 	dsi->data_swap = dev_read_bool(dsi->dev, "rockchip,data-swap");
1350*4882a593Smuzhiyun 
1351*4882a593Smuzhiyun 	rockchip_connector_bind(&dsi->connector, dev, dsi->id, &dw_mipi_dsi_connector_funcs, NULL,
1352*4882a593Smuzhiyun 				DRM_MODE_CONNECTOR_DSI);
1353*4882a593Smuzhiyun 
1354*4882a593Smuzhiyun 	return 0;
1355*4882a593Smuzhiyun }
1356*4882a593Smuzhiyun 
1357*4882a593Smuzhiyun static const u32 px30_dsi_grf_reg_fields[MAX_FIELDS] = {
1358*4882a593Smuzhiyun 	[DPIUPDATECFG]		= GRF_REG_FIELD(0x0434,  7,  7),
1359*4882a593Smuzhiyun 	[DPICOLORM]		= GRF_REG_FIELD(0x0434,  3,  3),
1360*4882a593Smuzhiyun 	[DPISHUTDN]		= GRF_REG_FIELD(0x0434,  2,  2),
1361*4882a593Smuzhiyun 	[FORCETXSTOPMODE]	= GRF_REG_FIELD(0x0438,  7, 10),
1362*4882a593Smuzhiyun 	[TURNDISABLE]		= GRF_REG_FIELD(0x0438,  5,  5),
1363*4882a593Smuzhiyun 	[VOPSEL]		= GRF_REG_FIELD(0x0438,  0,  0),
1364*4882a593Smuzhiyun };
1365*4882a593Smuzhiyun 
1366*4882a593Smuzhiyun static const struct dw_mipi_dsi_plat_data px30_mipi_dsi_plat_data = {
1367*4882a593Smuzhiyun 	.dsi0_grf_reg_fields = px30_dsi_grf_reg_fields,
1368*4882a593Smuzhiyun 	.max_bit_rate_per_lane = 1000000000UL,
1369*4882a593Smuzhiyun };
1370*4882a593Smuzhiyun 
1371*4882a593Smuzhiyun static const u32 rk1808_dsi_grf_reg_fields[MAX_FIELDS] = {
1372*4882a593Smuzhiyun 	[MASTERSLAVEZ]          = GRF_REG_FIELD(0x0440,  8,  8),
1373*4882a593Smuzhiyun 	[DPIUPDATECFG]          = GRF_REG_FIELD(0x0440,  7,  7),
1374*4882a593Smuzhiyun 	[DPICOLORM]             = GRF_REG_FIELD(0x0440,  3,  3),
1375*4882a593Smuzhiyun 	[DPISHUTDN]             = GRF_REG_FIELD(0x0440,  2,  2),
1376*4882a593Smuzhiyun 	[FORCETXSTOPMODE]       = GRF_REG_FIELD(0x0444,  7, 10),
1377*4882a593Smuzhiyun 	[FORCERXMODE]           = GRF_REG_FIELD(0x0444,  6,  6),
1378*4882a593Smuzhiyun 	[TURNDISABLE]           = GRF_REG_FIELD(0x0444,  5,  5),
1379*4882a593Smuzhiyun };
1380*4882a593Smuzhiyun 
1381*4882a593Smuzhiyun static const struct dw_mipi_dsi_plat_data rk1808_mipi_dsi_plat_data = {
1382*4882a593Smuzhiyun 	.dsi0_grf_reg_fields = rk1808_dsi_grf_reg_fields,
1383*4882a593Smuzhiyun 	.max_bit_rate_per_lane = 2000000000UL,
1384*4882a593Smuzhiyun };
1385*4882a593Smuzhiyun 
1386*4882a593Smuzhiyun static const u32 rk3128_dsi_grf_reg_fields[MAX_FIELDS] = {
1387*4882a593Smuzhiyun 	[FORCETXSTOPMODE]	= GRF_REG_FIELD(0x0150, 10, 13),
1388*4882a593Smuzhiyun 	[FORCERXMODE]		= GRF_REG_FIELD(0x0150,  9,  9),
1389*4882a593Smuzhiyun 	[TURNDISABLE]		= GRF_REG_FIELD(0x0150,  8,  8),
1390*4882a593Smuzhiyun 	[DPICOLORM]		= GRF_REG_FIELD(0x0150,  5,  5),
1391*4882a593Smuzhiyun 	[DPISHUTDN]		= GRF_REG_FIELD(0x0150,  4,  4),
1392*4882a593Smuzhiyun };
1393*4882a593Smuzhiyun 
1394*4882a593Smuzhiyun static const struct dw_mipi_dsi_plat_data rk3128_mipi_dsi_plat_data = {
1395*4882a593Smuzhiyun 	.dsi0_grf_reg_fields = rk3128_dsi_grf_reg_fields,
1396*4882a593Smuzhiyun 	.max_bit_rate_per_lane = 1000000000UL,
1397*4882a593Smuzhiyun };
1398*4882a593Smuzhiyun 
1399*4882a593Smuzhiyun static const u32 rk3288_dsi0_grf_reg_fields[MAX_FIELDS] = {
1400*4882a593Smuzhiyun 	[DPICOLORM]		= GRF_REG_FIELD(0x025c,  8,  8),
1401*4882a593Smuzhiyun 	[DPISHUTDN]		= GRF_REG_FIELD(0x025c,  7,  7),
1402*4882a593Smuzhiyun 	[VOPSEL]		= GRF_REG_FIELD(0x025c,  6,  6),
1403*4882a593Smuzhiyun 	[FORCETXSTOPMODE]	= GRF_REG_FIELD(0x0264,  8, 11),
1404*4882a593Smuzhiyun 	[FORCERXMODE]		= GRF_REG_FIELD(0x0264,  4,  7),
1405*4882a593Smuzhiyun 	[TURNDISABLE]		= GRF_REG_FIELD(0x0264,  0,  3),
1406*4882a593Smuzhiyun 	[TURNREQUEST]		= GRF_REG_FIELD(0x03a4,  8, 10),
1407*4882a593Smuzhiyun 	[DPIUPDATECFG]		= GRF_REG_FIELD(0x03a8,  0,  0),
1408*4882a593Smuzhiyun };
1409*4882a593Smuzhiyun 
1410*4882a593Smuzhiyun static const u32 rk3288_dsi1_grf_reg_fields[MAX_FIELDS] = {
1411*4882a593Smuzhiyun 	[DPICOLORM]		= GRF_REG_FIELD(0x025c, 11, 11),
1412*4882a593Smuzhiyun 	[DPISHUTDN]		= GRF_REG_FIELD(0x025c, 10, 10),
1413*4882a593Smuzhiyun 	[VOPSEL]		= GRF_REG_FIELD(0x025c,  9,  9),
1414*4882a593Smuzhiyun 	[ENABLE_N]		= GRF_REG_FIELD(0x0268, 12, 15),
1415*4882a593Smuzhiyun 	[FORCETXSTOPMODE]	= GRF_REG_FIELD(0x0268,  8, 11),
1416*4882a593Smuzhiyun 	[FORCERXMODE]		= GRF_REG_FIELD(0x0268,  4,  7),
1417*4882a593Smuzhiyun 	[TURNDISABLE]		= GRF_REG_FIELD(0x0268,  0,  3),
1418*4882a593Smuzhiyun 	[BASEDIR]		= GRF_REG_FIELD(0x027c, 15, 15),
1419*4882a593Smuzhiyun 	[MASTERSLAVEZ]		= GRF_REG_FIELD(0x027c, 14, 14),
1420*4882a593Smuzhiyun 	[ENABLECLK]		= GRF_REG_FIELD(0x027c, 12, 12),
1421*4882a593Smuzhiyun 	[TURNREQUEST]		= GRF_REG_FIELD(0x03a4,  4,  7),
1422*4882a593Smuzhiyun 	[DPIUPDATECFG]		= GRF_REG_FIELD(0x03a8,  1,  1),
1423*4882a593Smuzhiyun };
1424*4882a593Smuzhiyun 
1425*4882a593Smuzhiyun static const struct dw_mipi_dsi_plat_data rk3288_mipi_dsi_plat_data = {
1426*4882a593Smuzhiyun 	.dsi0_grf_reg_fields = rk3288_dsi0_grf_reg_fields,
1427*4882a593Smuzhiyun 	.dsi1_grf_reg_fields = rk3288_dsi1_grf_reg_fields,
1428*4882a593Smuzhiyun 	.max_bit_rate_per_lane = 1500000000UL,
1429*4882a593Smuzhiyun };
1430*4882a593Smuzhiyun 
1431*4882a593Smuzhiyun static const u32 rk3366_dsi_grf_reg_fields[MAX_FIELDS] = {
1432*4882a593Smuzhiyun 	[VOPSEL]		= GRF_REG_FIELD(0x0400,  2,  2),
1433*4882a593Smuzhiyun 	[DPIUPDATECFG]		= GRF_REG_FIELD(0x0410,  9,  9),
1434*4882a593Smuzhiyun 	[DPICOLORM]		= GRF_REG_FIELD(0x0410,  3,  3),
1435*4882a593Smuzhiyun 	[DPISHUTDN]		= GRF_REG_FIELD(0x0410,  2,  2),
1436*4882a593Smuzhiyun 	[FORCETXSTOPMODE]	= GRF_REG_FIELD(0x0414,  7, 10),
1437*4882a593Smuzhiyun 	[FORCERXMODE]		= GRF_REG_FIELD(0x0414,  6,  6),
1438*4882a593Smuzhiyun 	[TURNDISABLE]		= GRF_REG_FIELD(0x0414,  5,  5),
1439*4882a593Smuzhiyun };
1440*4882a593Smuzhiyun 
1441*4882a593Smuzhiyun static const struct dw_mipi_dsi_plat_data rk3366_mipi_dsi_plat_data = {
1442*4882a593Smuzhiyun 	.dsi0_grf_reg_fields = rk3366_dsi_grf_reg_fields,
1443*4882a593Smuzhiyun 	.max_bit_rate_per_lane = 1000000000UL,
1444*4882a593Smuzhiyun };
1445*4882a593Smuzhiyun 
1446*4882a593Smuzhiyun static const u32 rk3368_dsi_grf_reg_fields[MAX_FIELDS] = {
1447*4882a593Smuzhiyun 	[DPIUPDATECFG]		= GRF_REG_FIELD(0x0418,  7,  7),
1448*4882a593Smuzhiyun 	[DPICOLORM]		= GRF_REG_FIELD(0x0418,  3,  3),
1449*4882a593Smuzhiyun 	[DPISHUTDN]		= GRF_REG_FIELD(0x0418,  2,  2),
1450*4882a593Smuzhiyun 	[FORCETXSTOPMODE]	= GRF_REG_FIELD(0x041c,  7, 10),
1451*4882a593Smuzhiyun 	[FORCERXMODE]		= GRF_REG_FIELD(0x041c,  6,  6),
1452*4882a593Smuzhiyun 	[TURNDISABLE]		= GRF_REG_FIELD(0x041c,  5,  5),
1453*4882a593Smuzhiyun };
1454*4882a593Smuzhiyun 
1455*4882a593Smuzhiyun static const struct dw_mipi_dsi_plat_data rk3368_mipi_dsi_plat_data = {
1456*4882a593Smuzhiyun 	.dsi0_grf_reg_fields = rk3368_dsi_grf_reg_fields,
1457*4882a593Smuzhiyun 	.max_bit_rate_per_lane = 1000000000UL,
1458*4882a593Smuzhiyun };
1459*4882a593Smuzhiyun 
1460*4882a593Smuzhiyun static const u32 rk3399_dsi0_grf_reg_fields[MAX_FIELDS] = {
1461*4882a593Smuzhiyun 	[DPIUPDATECFG]		= GRF_REG_FIELD(0x6224, 15, 15),
1462*4882a593Smuzhiyun 	[DPISHUTDN]		= GRF_REG_FIELD(0x6224, 14, 14),
1463*4882a593Smuzhiyun 	[DPICOLORM]		= GRF_REG_FIELD(0x6224, 13, 13),
1464*4882a593Smuzhiyun 	[VOPSEL]		= GRF_REG_FIELD(0x6250,  0,  0),
1465*4882a593Smuzhiyun 	[TURNREQUEST]		= GRF_REG_FIELD(0x6258, 12, 15),
1466*4882a593Smuzhiyun 	[TURNDISABLE]		= GRF_REG_FIELD(0x6258,  8, 11),
1467*4882a593Smuzhiyun 	[FORCETXSTOPMODE]	= GRF_REG_FIELD(0x6258,  4,  7),
1468*4882a593Smuzhiyun 	[FORCERXMODE]		= GRF_REG_FIELD(0x6258,  0,  3),
1469*4882a593Smuzhiyun };
1470*4882a593Smuzhiyun 
1471*4882a593Smuzhiyun static const u32 rk3399_dsi1_grf_reg_fields[MAX_FIELDS] = {
1472*4882a593Smuzhiyun 	[VOPSEL]		= GRF_REG_FIELD(0x6250,  4,  4),
1473*4882a593Smuzhiyun 	[DPIUPDATECFG]		= GRF_REG_FIELD(0x6250,  3,  3),
1474*4882a593Smuzhiyun 	[DPISHUTDN]		= GRF_REG_FIELD(0x6250,  2,  2),
1475*4882a593Smuzhiyun 	[DPICOLORM]		= GRF_REG_FIELD(0x6250,  1,  1),
1476*4882a593Smuzhiyun 	[TURNDISABLE]		= GRF_REG_FIELD(0x625c, 12, 15),
1477*4882a593Smuzhiyun 	[FORCETXSTOPMODE]	= GRF_REG_FIELD(0x625c,  8, 11),
1478*4882a593Smuzhiyun 	[FORCERXMODE]           = GRF_REG_FIELD(0x625c,  4,  7),
1479*4882a593Smuzhiyun 	[ENABLE_N]		= GRF_REG_FIELD(0x625c,  0,  3),
1480*4882a593Smuzhiyun 	[MASTERSLAVEZ]		= GRF_REG_FIELD(0x6260,  7,  7),
1481*4882a593Smuzhiyun 	[ENABLECLK]		= GRF_REG_FIELD(0x6260,  6,  6),
1482*4882a593Smuzhiyun 	[BASEDIR]		= GRF_REG_FIELD(0x6260,  5,  5),
1483*4882a593Smuzhiyun 	[TURNREQUEST]		= GRF_REG_FIELD(0x6260,  0,  3),
1484*4882a593Smuzhiyun };
1485*4882a593Smuzhiyun 
1486*4882a593Smuzhiyun static const struct dw_mipi_dsi_plat_data rk3399_mipi_dsi_plat_data = {
1487*4882a593Smuzhiyun 	.dsi0_grf_reg_fields = rk3399_dsi0_grf_reg_fields,
1488*4882a593Smuzhiyun 	.dsi1_grf_reg_fields = rk3399_dsi1_grf_reg_fields,
1489*4882a593Smuzhiyun 	.max_bit_rate_per_lane = 1500000000UL,
1490*4882a593Smuzhiyun };
1491*4882a593Smuzhiyun 
1492*4882a593Smuzhiyun static const u32 rk3562_dsi_grf_reg_fields[MAX_FIELDS] = {
1493*4882a593Smuzhiyun 	[DPIUPDATECFG]		= GRF_REG_FIELD(0x05d0,  2,  2),
1494*4882a593Smuzhiyun 	[DPICOLORM]		= GRF_REG_FIELD(0x05d0,  1,  1),
1495*4882a593Smuzhiyun 	[DPISHUTDN]		= GRF_REG_FIELD(0x05d0,  0,  0),
1496*4882a593Smuzhiyun 	[SKEWCALHS]		= GRF_REG_FIELD(0x05d4, 11, 15),
1497*4882a593Smuzhiyun 	[FORCETXSTOPMODE]	= GRF_REG_FIELD(0x05d4,  4,  7),
1498*4882a593Smuzhiyun 	[TURNDISABLE]		= GRF_REG_FIELD(0x05d4,  2,  2),
1499*4882a593Smuzhiyun 	[FORCERXMODE]		= GRF_REG_FIELD(0x05d4,  0,  0),
1500*4882a593Smuzhiyun };
1501*4882a593Smuzhiyun 
1502*4882a593Smuzhiyun static const struct dw_mipi_dsi_plat_data rk3562_mipi_dsi_plat_data = {
1503*4882a593Smuzhiyun 	.dsi0_grf_reg_fields = rk3562_dsi_grf_reg_fields,
1504*4882a593Smuzhiyun 	.max_bit_rate_per_lane = 1200000000UL,
1505*4882a593Smuzhiyun };
1506*4882a593Smuzhiyun 
1507*4882a593Smuzhiyun static const u32 rk3568_dsi0_grf_reg_fields[MAX_FIELDS] = {
1508*4882a593Smuzhiyun 	[DPIUPDATECFG]		= GRF_REG_FIELD(0x0360,  2,  2),
1509*4882a593Smuzhiyun 	[DPICOLORM]		= GRF_REG_FIELD(0x0360,  1,  1),
1510*4882a593Smuzhiyun 	[DPISHUTDN]		= GRF_REG_FIELD(0x0360,  0,  0),
1511*4882a593Smuzhiyun 	[SKEWCALHS]		= GRF_REG_FIELD(0x0368, 11, 15),
1512*4882a593Smuzhiyun 	[FORCETXSTOPMODE]	= GRF_REG_FIELD(0x0368,  4,  7),
1513*4882a593Smuzhiyun 	[TURNDISABLE]		= GRF_REG_FIELD(0x0368,  2,  2),
1514*4882a593Smuzhiyun 	[FORCERXMODE]		= GRF_REG_FIELD(0x0368,  0,  0),
1515*4882a593Smuzhiyun };
1516*4882a593Smuzhiyun 
1517*4882a593Smuzhiyun static const u32 rk3568_dsi1_grf_reg_fields[MAX_FIELDS] = {
1518*4882a593Smuzhiyun 	[DPIUPDATECFG]		= GRF_REG_FIELD(0x0360, 10, 10),
1519*4882a593Smuzhiyun 	[DPICOLORM]		= GRF_REG_FIELD(0x0360,  9,  9),
1520*4882a593Smuzhiyun 	[DPISHUTDN]		= GRF_REG_FIELD(0x0360,  8,  8),
1521*4882a593Smuzhiyun 	[SKEWCALHS]             = GRF_REG_FIELD(0x036c, 11, 15),
1522*4882a593Smuzhiyun 	[FORCETXSTOPMODE]	= GRF_REG_FIELD(0x036c,  4,  7),
1523*4882a593Smuzhiyun 	[TURNDISABLE]		= GRF_REG_FIELD(0x036c,  2,  2),
1524*4882a593Smuzhiyun 	[FORCERXMODE]		= GRF_REG_FIELD(0x036c,  0,  0),
1525*4882a593Smuzhiyun };
1526*4882a593Smuzhiyun 
1527*4882a593Smuzhiyun static const struct dw_mipi_dsi_plat_data rk3568_mipi_dsi_plat_data = {
1528*4882a593Smuzhiyun 	.dsi0_grf_reg_fields = rk3568_dsi0_grf_reg_fields,
1529*4882a593Smuzhiyun 	.dsi1_grf_reg_fields = rk3568_dsi1_grf_reg_fields,
1530*4882a593Smuzhiyun 	.max_bit_rate_per_lane = 1200000000UL,
1531*4882a593Smuzhiyun };
1532*4882a593Smuzhiyun 
1533*4882a593Smuzhiyun static const u32 rv1108_dsi_grf_reg_fields[MAX_FIELDS] = {
1534*4882a593Smuzhiyun 	[DPICOLORM]		= GRF_REG_FIELD(0x0410,  7,  7),
1535*4882a593Smuzhiyun 	[DPISHUTDN]		= GRF_REG_FIELD(0x0410,  6,  6),
1536*4882a593Smuzhiyun 	[DPIUPDATECFG]		= GRF_REG_FIELD(0x0410,  8,  8),
1537*4882a593Smuzhiyun 	[FORCERXMODE]		= GRF_REG_FIELD(0x0414,  5,  5),
1538*4882a593Smuzhiyun 	[FORCETXSTOPMODE]	= GRF_REG_FIELD(0x0414,  6,  9),
1539*4882a593Smuzhiyun 	[TURNDISABLE]		= GRF_REG_FIELD(0x0414,  4,  4),
1540*4882a593Smuzhiyun };
1541*4882a593Smuzhiyun 
1542*4882a593Smuzhiyun static const struct dw_mipi_dsi_plat_data rv1108_mipi_dsi_plat_data = {
1543*4882a593Smuzhiyun 	.dsi0_grf_reg_fields = rv1108_dsi_grf_reg_fields,
1544*4882a593Smuzhiyun 	.max_bit_rate_per_lane = 1000000000UL,
1545*4882a593Smuzhiyun };
1546*4882a593Smuzhiyun 
1547*4882a593Smuzhiyun static const u32 rv1126_dsi_grf_reg_fields[MAX_FIELDS] = {
1548*4882a593Smuzhiyun 	[DPIUPDATECFG]		= GRF_REG_FIELD(0x0008,  5,  5),
1549*4882a593Smuzhiyun 	[DPISHUTDN]		= GRF_REG_FIELD(0x0008,  4,  4),
1550*4882a593Smuzhiyun 	[DPICOLORM]		= GRF_REG_FIELD(0x0008,  3,  3),
1551*4882a593Smuzhiyun 	[FORCETXSTOPMODE]	= GRF_REG_FIELD(0x10220,  4,  7),
1552*4882a593Smuzhiyun 	[TURNDISABLE]		= GRF_REG_FIELD(0x10220,  2,  2),
1553*4882a593Smuzhiyun 	[FORCERXMODE]		= GRF_REG_FIELD(0x10220,  0,  0),
1554*4882a593Smuzhiyun };
1555*4882a593Smuzhiyun 
1556*4882a593Smuzhiyun static const struct dw_mipi_dsi_plat_data rv1126_mipi_dsi_plat_data = {
1557*4882a593Smuzhiyun 	.dsi0_grf_reg_fields = rv1126_dsi_grf_reg_fields,
1558*4882a593Smuzhiyun 	.max_bit_rate_per_lane = 1000000000UL,
1559*4882a593Smuzhiyun };
1560*4882a593Smuzhiyun 
1561*4882a593Smuzhiyun static const struct udevice_id dw_mipi_dsi_ids[] = {
1562*4882a593Smuzhiyun 	{
1563*4882a593Smuzhiyun 		.compatible = "rockchip,px30-mipi-dsi",
1564*4882a593Smuzhiyun 		.data = (ulong)&px30_mipi_dsi_plat_data,
1565*4882a593Smuzhiyun 	},
1566*4882a593Smuzhiyun 	{
1567*4882a593Smuzhiyun 		.compatible = "rockchip,rk1808-mipi-dsi",
1568*4882a593Smuzhiyun 		.data = (ulong)&rk1808_mipi_dsi_plat_data,
1569*4882a593Smuzhiyun 	},
1570*4882a593Smuzhiyun 	{
1571*4882a593Smuzhiyun 		.compatible = "rockchip,rk3128-mipi-dsi",
1572*4882a593Smuzhiyun 		.data = (ulong)&rk3128_mipi_dsi_plat_data,
1573*4882a593Smuzhiyun 	},
1574*4882a593Smuzhiyun 	{
1575*4882a593Smuzhiyun 		.compatible = "rockchip,rk3288-mipi-dsi",
1576*4882a593Smuzhiyun 		.data = (ulong)&rk3288_mipi_dsi_plat_data,
1577*4882a593Smuzhiyun 	},
1578*4882a593Smuzhiyun 	{
1579*4882a593Smuzhiyun 		.compatible = "rockchip,rk3366-mipi-dsi",
1580*4882a593Smuzhiyun 		.data = (ulong)&rk3366_mipi_dsi_plat_data,
1581*4882a593Smuzhiyun 	},
1582*4882a593Smuzhiyun 	{
1583*4882a593Smuzhiyun 		.compatible = "rockchip,rk3368-mipi-dsi",
1584*4882a593Smuzhiyun 		.data = (ulong)&rk3368_mipi_dsi_plat_data,
1585*4882a593Smuzhiyun 	},
1586*4882a593Smuzhiyun 	{
1587*4882a593Smuzhiyun 		.compatible = "rockchip,rk3399-mipi-dsi",
1588*4882a593Smuzhiyun 		.data = (ulong)&rk3399_mipi_dsi_plat_data,
1589*4882a593Smuzhiyun 	},
1590*4882a593Smuzhiyun 	{
1591*4882a593Smuzhiyun 		.compatible = "rockchip,rk3562-mipi-dsi",
1592*4882a593Smuzhiyun 		.data = (ulong)&rk3562_mipi_dsi_plat_data,
1593*4882a593Smuzhiyun 	},
1594*4882a593Smuzhiyun 	{
1595*4882a593Smuzhiyun 		.compatible = "rockchip,rk3568-mipi-dsi",
1596*4882a593Smuzhiyun 		.data = (ulong)&rk3568_mipi_dsi_plat_data,
1597*4882a593Smuzhiyun 	},
1598*4882a593Smuzhiyun 	{
1599*4882a593Smuzhiyun 		.compatible = "rockchip,rv1108-mipi-dsi",
1600*4882a593Smuzhiyun 		.data = (ulong)&rv1108_mipi_dsi_plat_data,
1601*4882a593Smuzhiyun 	},
1602*4882a593Smuzhiyun 	{
1603*4882a593Smuzhiyun 		.compatible = "rockchip,rv1126-mipi-dsi",
1604*4882a593Smuzhiyun 		.data = (ulong)&rv1126_mipi_dsi_plat_data,
1605*4882a593Smuzhiyun 	},
1606*4882a593Smuzhiyun 	{}
1607*4882a593Smuzhiyun };
1608*4882a593Smuzhiyun 
dw_mipi_dsi_host_transfer(struct mipi_dsi_host * host,const struct mipi_dsi_msg * msg)1609*4882a593Smuzhiyun static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
1610*4882a593Smuzhiyun 					 const struct mipi_dsi_msg *msg)
1611*4882a593Smuzhiyun {
1612*4882a593Smuzhiyun 	struct dw_mipi_dsi *dsi = dev_get_priv(host->dev);
1613*4882a593Smuzhiyun 
1614*4882a593Smuzhiyun 	return dw_mipi_dsi_transfer(dsi, msg);
1615*4882a593Smuzhiyun }
1616*4882a593Smuzhiyun 
dw_mipi_dsi_host_attach(struct mipi_dsi_host * host,struct mipi_dsi_device * device)1617*4882a593Smuzhiyun static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
1618*4882a593Smuzhiyun 				   struct mipi_dsi_device *device)
1619*4882a593Smuzhiyun {
1620*4882a593Smuzhiyun 	struct dw_mipi_dsi *dsi = dev_get_priv(host->dev);
1621*4882a593Smuzhiyun 
1622*4882a593Smuzhiyun 	if (device->lanes < 1 || device->lanes > 8)
1623*4882a593Smuzhiyun 		return -EINVAL;
1624*4882a593Smuzhiyun 
1625*4882a593Smuzhiyun 	dsi->lanes = device->lanes;
1626*4882a593Smuzhiyun 	dsi->channel = device->channel;
1627*4882a593Smuzhiyun 	dsi->format = device->format;
1628*4882a593Smuzhiyun 	dsi->mode_flags = device->mode_flags;
1629*4882a593Smuzhiyun 
1630*4882a593Smuzhiyun 	return 0;
1631*4882a593Smuzhiyun }
1632*4882a593Smuzhiyun 
1633*4882a593Smuzhiyun static const struct mipi_dsi_host_ops dw_mipi_dsi_host_ops = {
1634*4882a593Smuzhiyun 	.attach = dw_mipi_dsi_host_attach,
1635*4882a593Smuzhiyun 	.transfer = dw_mipi_dsi_host_transfer,
1636*4882a593Smuzhiyun };
1637*4882a593Smuzhiyun 
dw_mipi_dsi_bind(struct udevice * dev)1638*4882a593Smuzhiyun static int dw_mipi_dsi_bind(struct udevice *dev)
1639*4882a593Smuzhiyun {
1640*4882a593Smuzhiyun 	struct mipi_dsi_host *host = dev_get_platdata(dev);
1641*4882a593Smuzhiyun 
1642*4882a593Smuzhiyun 	host->dev = dev;
1643*4882a593Smuzhiyun 	host->ops = &dw_mipi_dsi_host_ops;
1644*4882a593Smuzhiyun 
1645*4882a593Smuzhiyun 	return dm_scan_fdt_dev(dev);
1646*4882a593Smuzhiyun }
1647*4882a593Smuzhiyun 
dw_mipi_dsi_child_post_bind(struct udevice * dev)1648*4882a593Smuzhiyun static int dw_mipi_dsi_child_post_bind(struct udevice *dev)
1649*4882a593Smuzhiyun {
1650*4882a593Smuzhiyun 	struct mipi_dsi_host *host = dev_get_platdata(dev->parent);
1651*4882a593Smuzhiyun 	struct mipi_dsi_device *device = dev_get_parent_platdata(dev);
1652*4882a593Smuzhiyun 	char name[20];
1653*4882a593Smuzhiyun 
1654*4882a593Smuzhiyun 	sprintf(name, "%s.%d", host->dev->name, device->channel);
1655*4882a593Smuzhiyun 	device_set_name(dev, name);
1656*4882a593Smuzhiyun 
1657*4882a593Smuzhiyun 	device->dev = dev;
1658*4882a593Smuzhiyun 	device->host = host;
1659*4882a593Smuzhiyun 	device->lanes = dev_read_u32_default(dev, "dsi,lanes", 4);
1660*4882a593Smuzhiyun 	device->format = dev_read_u32_default(dev, "dsi,format",
1661*4882a593Smuzhiyun 					      MIPI_DSI_FMT_RGB888);
1662*4882a593Smuzhiyun 	device->mode_flags = dev_read_u32_default(dev, "dsi,flags",
1663*4882a593Smuzhiyun 						  MIPI_DSI_MODE_VIDEO |
1664*4882a593Smuzhiyun 						  MIPI_DSI_MODE_VIDEO_BURST |
1665*4882a593Smuzhiyun 						  MIPI_DSI_MODE_VIDEO_HBP |
1666*4882a593Smuzhiyun 						  MIPI_DSI_MODE_LPM |
1667*4882a593Smuzhiyun 						  MIPI_DSI_MODE_EOT_PACKET);
1668*4882a593Smuzhiyun 	device->channel = dev_read_u32_default(dev, "reg", 0);
1669*4882a593Smuzhiyun 
1670*4882a593Smuzhiyun 	return 0;
1671*4882a593Smuzhiyun }
1672*4882a593Smuzhiyun 
dw_mipi_dsi_child_pre_probe(struct udevice * dev)1673*4882a593Smuzhiyun static int dw_mipi_dsi_child_pre_probe(struct udevice *dev)
1674*4882a593Smuzhiyun {
1675*4882a593Smuzhiyun 	struct mipi_dsi_device *device = dev_get_parent_platdata(dev);
1676*4882a593Smuzhiyun 	int ret;
1677*4882a593Smuzhiyun 
1678*4882a593Smuzhiyun 	ret = mipi_dsi_attach(device);
1679*4882a593Smuzhiyun 	if (ret) {
1680*4882a593Smuzhiyun 		dev_err(dev, "mipi_dsi_attach() failed: %d\n", ret);
1681*4882a593Smuzhiyun 		return ret;
1682*4882a593Smuzhiyun 	}
1683*4882a593Smuzhiyun 
1684*4882a593Smuzhiyun 	return 0;
1685*4882a593Smuzhiyun }
1686*4882a593Smuzhiyun 
1687*4882a593Smuzhiyun U_BOOT_DRIVER(dw_mipi_dsi) = {
1688*4882a593Smuzhiyun 	.name = "dw_mipi_dsi",
1689*4882a593Smuzhiyun 	.id = UCLASS_DISPLAY,
1690*4882a593Smuzhiyun 	.of_match = dw_mipi_dsi_ids,
1691*4882a593Smuzhiyun 	.probe = dw_mipi_dsi_probe,
1692*4882a593Smuzhiyun 	.bind = dw_mipi_dsi_bind,
1693*4882a593Smuzhiyun 	.priv_auto_alloc_size = sizeof(struct dw_mipi_dsi),
1694*4882a593Smuzhiyun 	.per_child_platdata_auto_alloc_size = sizeof(struct mipi_dsi_device),
1695*4882a593Smuzhiyun 	.platdata_auto_alloc_size = sizeof(struct mipi_dsi_host),
1696*4882a593Smuzhiyun 	.child_post_bind = dw_mipi_dsi_child_post_bind,
1697*4882a593Smuzhiyun 	.child_pre_probe = dw_mipi_dsi_child_pre_probe,
1698*4882a593Smuzhiyun };
1699