summaryrefslogtreecommitdiff
path: root/arch/arm/include/asm/arch-imx8/imx8_mipi_dsi.h
blob: fc93ed33ccac5b5fa69c6b3ef7d0f36bc393729b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
/*
 * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
 * Copyright 2017 NXP
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#ifndef _IMX8_MIPI_DSI_H_
#define _IMX8_MIPI_DSI_H_

#define MIPI_CSR_OFFSET 0x1000 /* Subsystem Control Status Registers (CSR) */
#define MIPI_CSR_TX_ULPS  0x0
#define MIPIv2_CSR_TX_ULPS  0x30
#define MIPI_CSR_TX_ULPS_VALUE  0x1F

#define MIPI_CSR_PXL2DPI         0x4
#define MIPIv2_CSR_PXL2DPI         0x40

#define MIPI_CSR_PXL2DPI_16_BIT_PACKED       0x0
#define MIPI_CSR_PXL2DPI_16_BIT_565_ALIGNED  0x1
#define MIPI_CSR_PXL2DPI_16_BIT_565_SHIFTED  0x2
#define MIPI_CSR_PXL2DPI_18_BIT_PACKED       0x3
#define MIPI_CSR_PXL2DPI_18_BIT_ALIGNED      0x4
#define MIPI_CSR_PXL2DPI_24_BIT              0x5

#define	DSI_CMD_BUF_MAXSIZE         (128)

#define MIPI_DSI_OFFSET 0x8000 /* MIPI DSI Controller */

/* DPI interface pixel color coding map */
enum mipi_dsi_dpi_fmt {
	MIPI_RGB565_PACKED = 0,
	MIPI_RGB565_LOOSELY,
	MIPI_RGB565_CONFIG3,
	MIPI_RGB666_PACKED,
	MIPI_RGB666_LOOSELY,
	MIPI_RGB888,
};

struct mipi_dsi_context {
	char *NAME;
	uint32_t REGS_BASE;
	uint32_t CSR_REGS_BASE;
};

struct dsi_cfg_csr_object {
	uint32_t dsi_host_cfg_num_lanes;
	uint32_t dsi_host_cfg_noncont_clk;
	uint32_t dsi_host_cfg_t_pre;
	uint32_t dsi_host_cfg_t_post;
	uint32_t dsi_host_cfg_tx_gap;
	uint32_t dsi_host_cfg_autoinsert_eotp;
	uint32_t dsi_host_cfg_extrcmd_after_eotp;
	uint32_t dsi_host_cfg_htx_to_cnt;
	uint32_t dsi_host_cfg_lrx_h_to_cnt;
	uint32_t dsi_host_cfg_bta_h_to_cnt;
	uint32_t dsi_host_cfg_twakeup;
};

struct dsi_cfg_dpi_object {
	uint32_t dsi_host_cfg_dpi_pxl_payld_size;
	uint32_t dsi_host_cfg_dpi_pxl_fifo_send_lev;
	uint32_t dsi_host_cfg_dpi_if_color_coding;
	uint32_t dsi_host_cfg_dpi_pxl_format;
	uint32_t dsi_host_cfg_dpi_vsync_pol;
	uint32_t dsi_host_cfg_dpi_hsync_pol;
	uint32_t dsi_host_cfg_dpi_video_mode;
	uint32_t dsi_host_cfg_dpi_hfp;
	uint32_t dsi_host_cfg_dpi_hbp;
	uint32_t dsi_host_cfg_dpi_hsa;
	uint32_t dsi_host_cfg_dpi_en_mult_pkt;
	uint32_t dsi_host_cfg_dpi_vbp;
	uint32_t dsi_host_cfg_dpi_vfp;
	uint32_t dsi_host_cfg_dpi_bllp_mode;
	uint32_t dsi_host_cfg_dpi_null_pkt_bllp;
	uint32_t dsi_host_cfg_dpi_vactive;
	uint32_t dsi_host_cfg_dpi_vc;
};

struct dsi_cfg_pkt_object {
	uint32_t dsi_host_pkt_ctrl;
	uint32_t dsi_host_send_pkt;
	uint32_t dsi_host_irq_mask;
	uint32_t dsi_host_irq_mask2;
};

struct dsi_cfg_dphy_object {
	uint32_t dphy_pd_tx;
	uint32_t dphy_m_prg_hs_prepare;
	uint32_t dphy_mc_prg_hs_prepare;
	uint32_t dphy_m_prg_hs_zero;
	uint32_t dphy_mc_prg_hs_zero;
	uint32_t dphy_m_prg_hs_trial;
	uint32_t dphy_mc_prg_hs_trial;
	uint32_t dphy_pd_pll;
	uint32_t dphy_tst;
	uint32_t dphy_cn;
	uint32_t dphy_cm;
	uint32_t dphy_co;
	uint32_t dphy_lock;
	uint32_t dphy_lock_byp;
	uint32_t dphy_tx_rcal;
	uint32_t dphy_auto_pd_en;
	uint32_t dphy_rxlprp;
	uint32_t dphy_rxcdrp;
};

/* dphy */
#define DPHY_PD_TX			0x300
#define DPHY_M_PRG_HS_PREPARE		0x304
#define DPHY_MC_PRG_HS_PREPARE		0x308
#define DPHY_M_PRG_HS_ZERO		0x30c
#define DPHY_MC_PRG_HS_ZERO		0x310
#define DPHY_M_PRG_HS_TRAIL		0x314
#define DPHY_MC_PRG_HS_TRAIL		0x318
#define DPHY_PD_PLL			0x31c
#define DPHY_TST			0x320
#define DPHY_CN				0x324
#define DPHY_CM				0x328
#define DPHY_CO				0x32c
#define DPHY_LOCK			0x330
#define DPHY_LOCK_BYP			0x334
#define DPHY_RTERM_SEL			0x338
#define DPHY_AUTO_PD_EN			0x33c
#define DPHY_RXLPRP			0x340
#define DPHY_RXCDRP			0x344

/* host */
#define HOST_CFG_NUM_LANES		0x0
#define HOST_CFG_NONCONTINUOUS_CLK	0x4
#define HOST_CFG_T_PRE			0x8
#define HOST_CFG_T_POST			0xc
#define HOST_CFG_TX_GAP			0x10
#define HOST_CFG_AUTOINSERT_EOTP	0x14
#define HOST_CFG_EXTRA_CMDS_AFTER_EOTP	0x18
#define HOST_CFG_HTX_TO_COUNT		0x1c
#define HOST_CFG_LRX_H_TO_COUNT		0x20
#define HOST_CFG_BTA_H_TO_COUNT		0x24
#define HOST_CFG_TWAKEUP		0x28
#define HOST_CFG_STATUS_OUT		0x2c
#define HOST_RX_ERROR_STATUS		0x30

/* dpi */
#define DPI_PIXEL_PAYLOAD_SIZE		0x200
#define DPI_PIXEL_FIFO_SEND_LEVEL	0x204
#define DPI_INTERFACE_COLOR_CODING	0x208
#define DPI_PIXEL_FORMAT		0x20c
#define DPI_VSYNC_POLARITY		0x210
#define DPI_HSYNC_POLARITY		0x214
#define DPI_VIDEO_MODE			0x218
#define DPI_HFP				0x21c
#define DPI_HBP				0x220
#define DPI_HSA				0x224
#define DPI_ENABLE_MULT_PKTS		0x228
#define DPI_VBP				0x22c
#define DPI_VFP				0x230
#define DPI_BLLP_MODE			0x234
#define DPI_USE_NULL_PKT_BLLP		0x238
#define DPI_VACTIVE			0x23c
#define DPI_VC				0x240

/* apb pkt */
#define HOST_TX_PAYLOAD			0x280

#define HOST_PKT_CONTROL		0x284
#define HOST_PKT_CONTROL_WC(x)		(((x) & 0xffff) << 0)
#define HOST_PKT_CONTROL_VC(x)		(((x) & 0x3) << 16)
#define HOST_PKT_CONTROL_DT(x)		(((x) & 0x3f) << 18)
#define HOST_PKT_CONTROL_HS_SEL(x)	(((x) & 0x1) << 24)
#define HOST_PKT_CONTROL_BTA_TX(x)	(((x) & 0x1) << 25)
#define HOST_PKT_CONTROL_BTA_NO_TX(x)	(((x) & 0x1) << 26)

#define HOST_SEND_PACKET		0x288
#define HOST_PKT_STATUS			0x28c
#define HOST_PKT_FIFO_WR_LEVEL		0x290
#define HOST_PKT_FIFO_RD_LEVEL		0x294
#define HOST_PKT_RX_PAYLOAD		0x298

#define HOST_PKT_RX_PKT_HEADER		0x29c
#define HOST_PKT_RX_PKT_HEADER_WC(x)	(((x) & 0xffff) << 0)
#define HOST_PKT_RX_PKT_HEADER_DT(x)	(((x) & 0x3f) << 16)
#define HOST_PKT_RX_PKT_HEADER_VC(x)	(((x) & 0x3) << 22)

#define HOST_IRQ_STATUS			0x2a0
#define HOST_IRQ_STATUS_SM_NOT_IDLE			(1 << 0)
#define HOST_IRQ_STATUS_TX_PKT_DONE			(1 << 1)
#define HOST_IRQ_STATUS_DPHY_DIRECTION			(1 << 2)
#define HOST_IRQ_STATUS_TX_FIFO_OVFLW			(1 << 3)
#define HOST_IRQ_STATUS_TX_FIFO_UDFLW			(1 << 4)
#define HOST_IRQ_STATUS_RX_FIFO_OVFLW			(1 << 5)
#define HOST_IRQ_STATUS_RX_FIFO_UDFLW			(1 << 6)
#define HOST_IRQ_STATUS_RX_PKT_HDR_RCVD			(1 << 7)
#define HOST_IRQ_STATUS_RX_PKT_PAYLOAD_DATA_RCVD	(1 << 8)
#define HOST_IRQ_STATUS_HOST_BTA_TIMEOUT		(1 << 29)
#define HOST_IRQ_STATUS_LP_RX_TIMEOUT			(1 << 30)
#define HOST_IRQ_STATUS_HS_TX_TIMEOUT			(1 << 31)

#define HOST_IRQ_STATUS2		0x2a4
#define HOST_IRQ_STATUS2_SINGLE_BIT_ECC_ERR		(1 << 0)
#define HOST_IRQ_STATUS2_MULTI_BIT_ECC_ERR		(1 << 1)
#define HOST_IRQ_STATUS2_CRC_ERR			(1 << 2)

#define HOST_IRQ_MASK			0x2a8
#define HOST_IRQ_MASK_SM_NOT_IDLE_MASK			(1 << 0)
#define HOST_IRQ_MASK_TX_PKT_DONE_MASK			(1 << 1)
#define HOST_IRQ_MASK_DPHY_DIRECTION_MASK		(1 << 2)
#define HOST_IRQ_MASK_TX_FIFO_OVFLW_MASK		(1 << 3)
#define HOST_IRQ_MASK_TX_FIFO_UDFLW_MASK		(1 << 4)
#define HOST_IRQ_MASK_RX_FIFO_OVFLW_MASK		(1 << 5)
#define HOST_IRQ_MASK_RX_FIFO_UDFLW_MASK		(1 << 6)
#define HOST_IRQ_MASK_RX_PKT_HDR_RCVD_MASK		(1 << 7)
#define HOST_IRQ_MASK_RX_PKT_PAYLOAD_DATA_RCVD_MASK	(1 << 8)
#define HOST_IRQ_MASK_HOST_BTA_TIMEOUT_MASK		(1 << 29)
#define HOST_IRQ_MASK_LP_RX_TIMEOUT_MASK		(1 << 30)
#define HOST_IRQ_MASK_HS_TX_TIMEOUT_MASK		(1 << 31)

#define HOST_IRQ_MASK2			0x2ac
#define HOST_IRQ_MASK2_SINGLE_BIT_ECC_ERR_MASK		(1 << 0)
#define HOST_IRQ_MASK2_MULTI_BIT_ECC_ERR_MASK		(1 << 1)
#define HOST_IRQ_MASK2_CRC_ERR_MASK			(1 << 2)

/* ------------------------------------- end -------------------------------- */
#define BITSLICE(x, a, b) (((x) >> (b)) & ((1 << ((a)-(b)+1)) - 1))

#ifdef DEBUG
#define W32(reg, val) \
do {printf("%s():%d reg 0x%p  val 0x%08x\n",\
		   __func__, __LINE__, reg, val);\
		__raw_writel(val, reg); } while (0)
#else
#define W32(reg, val) __raw_writel(val, reg)
#endif

#define R32(reg) __raw_readl(reg)

/* helper functions */
inline void dsi_host_ctrl_csr_setup(void __iomem *base,
	struct dsi_cfg_csr_object *dsi_config,
	uint16_t csr_setup_mask)
{
	if (BITSLICE(csr_setup_mask, 0, 0))
		W32(base + HOST_CFG_NUM_LANES,
			dsi_config->dsi_host_cfg_num_lanes);
	if (BITSLICE(csr_setup_mask, 1, 1))
		W32(base + HOST_CFG_NONCONTINUOUS_CLK,
			dsi_config->dsi_host_cfg_noncont_clk);
	if (BITSLICE(csr_setup_mask, 2, 2))
		W32(base + HOST_CFG_T_PRE, dsi_config->dsi_host_cfg_t_pre);
	if (BITSLICE(csr_setup_mask, 3, 3))
		W32(base + HOST_CFG_T_POST,
			dsi_config->dsi_host_cfg_t_post);
	if (BITSLICE(csr_setup_mask, 4, 4))
		W32(base + HOST_CFG_TX_GAP,
			dsi_config->dsi_host_cfg_tx_gap);
	if (BITSLICE(csr_setup_mask, 5, 5))
		W32(base + HOST_CFG_AUTOINSERT_EOTP,
			dsi_config->dsi_host_cfg_autoinsert_eotp);
	if (BITSLICE(csr_setup_mask, 6, 6))
		W32(base + HOST_CFG_EXTRA_CMDS_AFTER_EOTP,
			dsi_config->dsi_host_cfg_extrcmd_after_eotp);
	if (BITSLICE(csr_setup_mask, 7, 7))
		W32(base + HOST_CFG_HTX_TO_COUNT,
			dsi_config->dsi_host_cfg_htx_to_cnt);
	if (BITSLICE(csr_setup_mask, 8, 8))
		W32(base + HOST_CFG_LRX_H_TO_COUNT,
			dsi_config->dsi_host_cfg_lrx_h_to_cnt);
	if (BITSLICE(csr_setup_mask, 9, 9))
		W32(base + HOST_CFG_BTA_H_TO_COUNT,
			dsi_config->dsi_host_cfg_bta_h_to_cnt);
	if (BITSLICE(csr_setup_mask, 10, 10))
		W32(base + HOST_CFG_TWAKEUP,
			dsi_config->dsi_host_cfg_twakeup);
}

inline void dsi_host_ctrl_dpi_setup(void __iomem *base,
	struct dsi_cfg_dpi_object *dsi_config,
	uint32_t dpi_setup_mask)
{
	if (BITSLICE(dpi_setup_mask, 0, 0))
		W32(base + DPI_PIXEL_PAYLOAD_SIZE,
			dsi_config->dsi_host_cfg_dpi_pxl_payld_size);
	if (BITSLICE(dpi_setup_mask, 1, 1))
		W32(base + DPI_PIXEL_FIFO_SEND_LEVEL,
			dsi_config->dsi_host_cfg_dpi_pxl_fifo_send_lev);
	if (BITSLICE(dpi_setup_mask, 2, 2))
		W32(base + DPI_INTERFACE_COLOR_CODING,
			dsi_config->dsi_host_cfg_dpi_if_color_coding);
	if (BITSLICE(dpi_setup_mask, 3, 3))
		W32(base + DPI_PIXEL_FORMAT,
			dsi_config->dsi_host_cfg_dpi_pxl_format);
	if (BITSLICE(dpi_setup_mask, 4, 4))
		W32(base + DPI_VSYNC_POLARITY,
			dsi_config->dsi_host_cfg_dpi_vsync_pol);
	if (BITSLICE(dpi_setup_mask, 5, 5))
		W32(base + DPI_HSYNC_POLARITY,
			dsi_config->dsi_host_cfg_dpi_hsync_pol);
	if (BITSLICE(dpi_setup_mask, 6, 6))
		W32(base + DPI_VIDEO_MODE,
			dsi_config->dsi_host_cfg_dpi_video_mode);
	if (BITSLICE(dpi_setup_mask, 7, 7))
		W32(base + DPI_HFP, dsi_config->dsi_host_cfg_dpi_hfp);
	if (BITSLICE(dpi_setup_mask, 8, 8))
		W32(base + DPI_HBP, dsi_config->dsi_host_cfg_dpi_hbp);
	if (BITSLICE(dpi_setup_mask, 9, 9))
		W32(base + DPI_HSA, dsi_config->dsi_host_cfg_dpi_hsa);
	if (BITSLICE(dpi_setup_mask, 10, 10))
		W32(base + DPI_ENABLE_MULT_PKTS,
			dsi_config->dsi_host_cfg_dpi_en_mult_pkt);
	if (BITSLICE(dpi_setup_mask, 11, 11))
		W32(base + DPI_VBP, dsi_config->dsi_host_cfg_dpi_vbp);
	if (BITSLICE(dpi_setup_mask, 12, 12))
		W32(base + DPI_VFP, dsi_config->dsi_host_cfg_dpi_vfp);
	if (BITSLICE(dpi_setup_mask, 13, 13))
		W32(base + DPI_BLLP_MODE,
			dsi_config->dsi_host_cfg_dpi_bllp_mode);
	if (BITSLICE(dpi_setup_mask, 14, 14))
		W32(base + DPI_USE_NULL_PKT_BLLP,
			dsi_config->dsi_host_cfg_dpi_null_pkt_bllp);
	if (BITSLICE(dpi_setup_mask, 15, 15))
		W32(base + DPI_VACTIVE,
			dsi_config->dsi_host_cfg_dpi_vactive);
	if (BITSLICE(dpi_setup_mask, 16, 16))
		W32(base + DPI_VC, dsi_config->dsi_host_cfg_dpi_vc);
}

inline void dsi_host_ctrl_pkt_setup(void __iomem *base,
	struct dsi_cfg_pkt_object *dsi_config,
	uint8_t pkt_setup_mask)
{
	if (BITSLICE(pkt_setup_mask, 0, 0))
		W32(base + HOST_PKT_CONTROL,
			dsi_config->dsi_host_pkt_ctrl);
	if (BITSLICE(pkt_setup_mask, 2, 2))
		W32(base + HOST_IRQ_MASK, dsi_config->dsi_host_irq_mask);
	if (BITSLICE(pkt_setup_mask, 3, 3))
		W32(base + HOST_IRQ_MASK2, dsi_config->dsi_host_irq_mask2);
	if (BITSLICE(pkt_setup_mask, 1, 1))
		W32(base + HOST_SEND_PACKET,
			dsi_config->dsi_host_send_pkt);
}

inline void dsi_host_ctrl_dphy_setup(void __iomem *base,
	struct dsi_cfg_dphy_object *dsi_config,
	uint32_t dphy_setup_mask)
{
	int i;

	if (BITSLICE(dphy_setup_mask, 8, 8))
		W32(base + DPHY_TST, dsi_config->dphy_tst);
	if (BITSLICE(dphy_setup_mask, 9, 9))
		W32(base + DPHY_CN, dsi_config->dphy_cn);
	if (BITSLICE(dphy_setup_mask, 10, 10))
		W32(base + DPHY_CM, dsi_config->dphy_cm);
	if (BITSLICE(dphy_setup_mask, 11, 11))
		W32(base + DPHY_CO, dsi_config->dphy_co);
	if (BITSLICE(dphy_setup_mask, 7, 7))
		W32(base + DPHY_PD_PLL, dsi_config->dphy_pd_pll);
	/* todo: disable on zebu */
	/*Polling of DPHY Lock status / wait for PLL lock */
	for (i = 0; i < 100; i++) {
		u32 lock;
		udelay(10);
		/*todo: zebu abort when reading DPHY LOCK */
		lock = R32(DPHY_LOCK);
		printf("DPHY PLL Lock = 0x%08x\n", lock);
	}
	/*todo: Need to wait for lock here */

	if (BITSLICE(dphy_setup_mask, 1, 1))
		W32(base + DPHY_M_PRG_HS_PREPARE,
			dsi_config->dphy_m_prg_hs_prepare);
	if (BITSLICE(dphy_setup_mask, 2, 2))
		W32(base + DPHY_MC_PRG_HS_PREPARE,
			dsi_config->dphy_mc_prg_hs_prepare);
	if (BITSLICE(dphy_setup_mask, 3, 3))
		W32(base + DPHY_M_PRG_HS_ZERO,
			dsi_config->dphy_m_prg_hs_zero);
	if (BITSLICE(dphy_setup_mask, 4, 4))
		W32(base + DPHY_MC_PRG_HS_ZERO,
			dsi_config->dphy_mc_prg_hs_zero);
	if (BITSLICE(dphy_setup_mask, 5, 5))
		W32(base + DPHY_M_PRG_HS_TRAIL,
			dsi_config->dphy_m_prg_hs_trial);
	if (BITSLICE(dphy_setup_mask, 6, 6))
		W32(base + DPHY_MC_PRG_HS_TRAIL,
			dsi_config->dphy_mc_prg_hs_trial);
	if (BITSLICE(dphy_setup_mask, 0, 0))
		W32(base + DPHY_PD_TX, dsi_config->dphy_pd_tx);
	if (BITSLICE(dphy_setup_mask, 12, 12))
		W32(base + DPHY_LOCK, dsi_config->dphy_lock);
	if (BITSLICE(dphy_setup_mask, 13, 13))
		W32(base + DPHY_LOCK_BYP, dsi_config->dphy_lock_byp);
}
#endif /* _IMX8_MIPI_DSI_H_ */