xref: /rk3399_rockchip-uboot/drivers/video/rk_eink/rk_ebc_tcon.c (revision a962a5fdb4271e59bab38d4e9b59b4839b88656d)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2020 Rockchip Electronics Co. Ltd.
4  *
5  * Author: Wenping Zhang <wenping.zhang@rock-chips.com>
6  */
7 #include <common.h>
8 #include <clk.h>
9 #include <dm.h>
10 #include <dm/pinctrl.h>
11 #include <pwm.h>
12 #include <regmap.h>
13 #include <syscon.h>
14 #include <asm/arch/clock.h>
15 #include <asm/io.h>
16 #include <syscon.h>
17 #include <linux/io.h>
18 #include "rk_ebc.h"
19 #ifdef CONFIG_IRQ
20 #include <irq-generic.h>
21 #endif
22 
23 struct ebc_tcon_priv {
24 	struct udevice *dev;
25 	void __iomem *reg;
26 	u32 *regcache;
27 	u32 reg_len;
28 	void *grf;
29 	void *pmugrf;
30 	struct clk dclk;
31 };
32 
33 #define msleep(a)		udelay((a) * 1000)
34 #define HIWORD_UPDATE(x, l, h)	(((x) << (l)) | (GENMASK(h, l) << 16))
35 #define UPDATE(x, h, l)		(((x) << (l)) & GENMASK((h), (l)))
36 
37 #define REG_LOAD_GLOBAL_EN	0x1
38 
39 /* ebc register define */
40 #define EBC_DSP_START		0x0000 //Frame statrt register
41 #define EBC_EPD_CTRL		0x0004 //EPD control register
42 #define EBC_DSP_CTRL		0x0008 //Display control register
43 #define EBC_DSP_HTIMING0	0x000c //H-Timing setting register0
44 #define EBC_DSP_HTIMING1	0x0010 //H-Timing setting register1
45 #define EBC_DSP_VTIMING0	0x0014 //V-Timing setting register0
46 #define EBC_DSP_VTIMING1	0x0018 //V-Timing setting register1
47 #define EBC_DSP_ACT_INFO	0x001c //ACTIVE width/height
48 #define EBC_WIN_CTRL		0x0020 //Window ctrl
49 #define EBC_WIN_MST0		0x0024 //Current win memory start
50 #define EBC_WIN_MST1		0x0028 //Next win memory start
51 #define EBC_WIN_VIR		0x002c //Window vir width/height
52 #define EBC_WIN_ACT		0x0030 //Window act width/height
53 #define EBC_WIN_DSP		0x0034 //Window dsp width/height
54 #define EBC_WIN_DSP_ST		0x0038 //Window display start point
55 #define EBC_INT_STATUS		0x003c //Interrupt register
56 #define EBC_VCOM0		0x0040 //VCOM setting register0
57 #define EBC_VCOM1		0x0044 //VCOM setting register1
58 #define EBC_VCOM2		0x0048 //VCOM setting register2
59 #define EBC_VCOM3		0x004c //VCOM setting register3
60 #define EBC_CONFIG_DONE		0x0050 //Config done register
61 #define EBC_VNUM		0x0054 //Line flag num
62 #define EBC_WIN_MST2		0x0058 //Framecount memory start
63 #define EBC_LUT_DATA_ADDR	0x1000 //lut data address
64 
65 #define DSP_HTOTAL(x)		UPDATE(x, 27, 16)
66 #define DSP_HS_END(x)		UPDATE(x, 7, 0)
67 #define DSP_HACT_END(x)		UPDATE(x, 26, 16)
68 #define DSP_HACT_ST(x)		UPDATE(x, 7, 0)
69 #define DSP_VTOTAL(x)		UPDATE(x, 26, 16)
70 #define DSP_VS_END(x)		UPDATE(x, 7, 0)
71 #define DSP_VACT_END(x)		UPDATE(x, 26, 16)
72 #define DSP_VACT_ST(x)		UPDATE(x, 7, 0)
73 #define DSP_HEIGHT(x)		UPDATE(x, 26, 16)
74 #define DSP_WIDTH(x)		UPDATE(x, 11, 0)
75 
76 #define WIN2_FIFO_ALMOST_FULL_LEVEL(x)	UPDATE(x, 27, 19)
77 #define WIN_EN(x)			UPDATE(x, 18, 18)
78 #define BURST_REG(x)			UPDATE(x, 12, 10)
79 #define WIN_FIFO_ALMOST_FULL_LEVEL(x)	UPDATE(x, 9, 2)
80 #define WIN_FMT(x)			UPDATE(x, 1, 0)
81 
82 #define WIN_VIR_HEIGHT(x)		UPDATE(x, 31, 16)
83 #define WIN_VIR_WIDTH(x)		UPDATE(x, 15, 0)
84 #define WIN_ACT_HEIGHT(x)		UPDATE(x, 26, 16)
85 #define WIN_ACT_WIDTH(x)		UPDATE(x, 11, 0)
86 #define WIN_DSP_HEIGHT(x)		UPDATE(x, 26, 16)
87 #define WIN_DSP_WIDTH(x)		UPDATE(x, 11, 0)
88 #define WIN_DSP_YST(x)			UPDATE(x, 26, 16)
89 #define WIN_DSP_XST(x)			UPDATE(x, 11, 0)
90 
91 #define DSP_OUT_LOW			BIT(31)
92 #define DSP_EINK_MODE(x)		UPDATE(x, 13, 13)
93 #define DSP_EINK_MODE_MASK		BIT(13)
94 #define DSP_SDCE_WIDTH(x)		UPDATE(x, 25, 16)
95 #define DSP_FRM_TOTAL(x)		UPDATE(x, 9, 2)
96 #define DSP_FRM_TOTAL_MASK		GENMASK(9, 2)
97 #define DSP_FRM_START			BIT(0)
98 #define DSP_FRM_START_MASK		BIT(0)
99 #define SW_BURST_CTRL			BIT(12)
100 
101 #define EINK_MODE_SWAP(x)		UPDATE(x, 31, 31)
102 #define EINK_MODE_FRM_SEL(x)		UPDATE(x, 30, 30)
103 #define DSP_GD_END(x)			UPDATE(x, 26, 16)
104 #define DSP_GD_ST(x)			UPDATE(x, 15, 8)
105 #define DSP_THREE_WIN_MODE(x)		UPDATE(x, 7, 7)
106 #define THREE_WIN_MODE_MASK		BIT(7)
107 #define DSP_SDDW_MODE(x)		UPDATE(x, 6, 6)
108 #define EPD_AUO(x)			UPDATE(x, 5, 5)
109 #define EPD_PWR(x)			UPDATE(x, 4, 2)
110 #define EPD_GDRL(x)			UPDATE(x, 1, 1)
111 #define EPD_SDSHR(x)			UPDATE(x, 0, 0)
112 
113 #define DSP_SWAP_MODE(x)		UPDATE(x, 31, 30)
114 #define DSP_SWAP_MODE_MASK		GENMASK(31, 30)
115 #define DSP_SDCLK_DIV(x)		UPDATE(x, 19, 16)
116 #define DSP_SDCLK_DIV_MASK		GENMASK(19, 16)
117 #define DSP_VCOM_MODE(x)		UPDATE(x, 27, 27)
118 #define DSP_VCOM_MODE_MASK		BIT(27)
119 
120 #define DSP_UPDATE_MODE(x)	UPDATE(x, 29, 29)
121 #define DSP_DISPLAY_MODE(x)	UPDATE(x, 28, 28)
122 #define UPDATE_MODE_MASK	BIT(29)
123 #define DISPLAY_MODE_MASK	BIT(28)
124 
125 #define DSP_FRM_INT_NUM(x)	UPDATE(x, 19, 12)
126 #define FRM_END_INT		BIT(0)
127 #define DSP_END_INT		BIT(1)
128 #define DSP_FRM_INT		BIT(2)
129 #define LINE_FLAG_INT		BIT(3)
130 #define FRM_END_INT_MASK	BIT(4)
131 #define DSP_END_INT_MASK	BIT(5)
132 #define DSP_FRM_INT_MASK	BIT(6)
133 #define LINE_FLAG_INT_MASK	BIT(7)
134 #define FRM_END_INT_CLR		BIT(8)
135 #define DSP_END_INT_CLR		BIT(9)
136 #define DSP_FRM_INT_CLR		BIT(10)
137 #define LINE_FLAG_INT_CLR	BIT(11)
138 
139 #define PMU_BASE_ADDR		0xfdd90000
140 #define PMU_PWR_GATE_SFTCON	0xA0
141 #define PMU_PWR_DWN_ST		0x98
142 #define RGA_PD_OFF		BIT(5)
143 #define RGA_PD_STAT		BIT(5)
144 enum ebc_win_data_fmt {
145 	Y_DATA_4BPP = 0,
146 	Y_DATA_8BPP = 1,
147 	RGB888 = 2,
148 	RGB565 = 3,
149 };
150 
151 #ifdef CONFIG_IRQ
152 #define IRQ_EBC			49
153 #endif
154 static volatile int last_frame_done = -1;
155 static inline void regs_dump(struct ebc_tcon_priv *tcon)
156 {
157 	int i;
158 
159 	printf("dump registers:\n");
160 	for (i = 0; i <= EBC_WIN_MST2; i = i + 4) {
161 		if (!(i % 16))
162 			printf("\n 0x%p:\t", tcon->reg + i);
163 		printf("0x%x\t", readl(tcon->reg + i));
164 	}
165 	printf("\nlut data:\n");
166 	for (i = 0x1000; i <= 0x1100; i = i + 4) {
167 		if (!(i % 16))
168 			printf("\n 0x%p:\t", tcon->reg + i);
169 		printf("0x%x\t", readl(tcon->reg + i));
170 	}
171 	printf("\n");
172 }
173 
174 static int ebc_power_domain(int on)
175 {
176 	u32 pd_reg;
177 	u32 pd_stat;
178 	int delay = 0;
179 
180 	if (on) {
181 		pd_reg = RGA_PD_OFF << 16;
182 		pd_stat = RGA_PD_STAT;
183 	} else {
184 		pd_reg = RGA_PD_OFF | (RGA_PD_OFF << 16);
185 		pd_stat = ~((u32)RGA_PD_STAT);
186 	}
187 
188 	/* enable rga pd for ebc tcon*/
189 	writel(pd_reg, PMU_BASE_ADDR + PMU_PWR_GATE_SFTCON);
190 	delay = 1000;
191 	do {
192 		udelay(1);
193 		delay--;
194 		if (delay == 0) {
195 			printf("Enable rga pd for ebc failed !\n");
196 			return -1;
197 		}
198 	} while (readl(PMU_BASE_ADDR + PMU_PWR_DWN_ST) & pd_stat);
199 
200 	return 0;
201 }
202 
203 static inline void tcon_write(struct ebc_tcon_priv *tcon, unsigned int reg,
204 			      unsigned int value)
205 {
206 	unsigned int *cache = tcon->regcache + (reg >> 2);
207 
208 	writel(value, tcon->reg + reg);
209 	*cache = value;
210 }
211 
212 static inline unsigned int tcon_read(struct ebc_tcon_priv *tcon,
213 				     unsigned int reg)
214 {
215 	return readl(tcon->reg + reg);
216 }
217 
218 static inline void tcon_update_bits(struct ebc_tcon_priv *tcon,
219 				    unsigned int reg, unsigned int mask,
220 				    unsigned int val)
221 {
222 	unsigned int tmp;
223 	unsigned int *cache = tcon->regcache + (reg >> 2);
224 
225 	tmp = *cache & ~mask;
226 	tmp |= val & mask;
227 
228 	writel(tmp, tcon->reg + reg);
229 	*cache = tmp;
230 }
231 
232 #ifdef CONFIG_IRQ
233 static void ebc_irq_handler(int irq, void *data)
234 {
235 	u32 intr_status;
236 	struct udevice *dev = data;
237 	struct ebc_tcon_priv *tcon = dev_get_priv(dev);
238 
239 	intr_status = readl(tcon->reg + EBC_INT_STATUS);
240 
241 	if (intr_status & DSP_END_INT) {
242 		tcon_update_bits(tcon, EBC_INT_STATUS,
243 				 DSP_END_INT_CLR, DSP_END_INT_CLR);
244 		last_frame_done = 1;
245 	}
246 }
247 #endif
248 
249 static inline void tcon_cfg_done(struct ebc_tcon_priv *tcon)
250 {
251 	writel(REG_LOAD_GLOBAL_EN, tcon->reg + EBC_CONFIG_DONE);
252 }
253 
254 static int ebc_tcon_enable(struct udevice *dev, struct ebc_panel *panel)
255 {
256 	int ret;
257 	struct ebc_tcon_priv *tcon = dev_get_priv(dev);
258 
259 	/* panel timing and win info config */
260 	tcon_write(tcon, EBC_DSP_HTIMING0,
261 		   DSP_HTOTAL(panel->lsl + panel->lbl + panel->ldl +
262 			      panel->lel) | DSP_HS_END(panel->lsl + 2));
263 	tcon_write(tcon, EBC_DSP_HTIMING1,
264 		   DSP_HACT_END(panel->lsl + panel->lbl + panel->ldl) |
265 		   DSP_HACT_ST(panel->lsl + panel->lbl - 1));
266 	tcon_write(tcon, EBC_DSP_VTIMING0,
267 		   DSP_VTOTAL(panel->fsl + panel->fbl + panel->fdl +
268 			      panel->fel) | DSP_VS_END(panel->fsl));
269 	tcon_write(tcon, EBC_DSP_VTIMING1,
270 		   DSP_VACT_END(panel->fsl + panel->fbl + panel->fdl) |
271 		   DSP_VACT_ST(panel->fsl + panel->fbl));
272 	tcon_write(tcon, EBC_DSP_ACT_INFO,
273 		   DSP_HEIGHT(panel->height) |
274 		   DSP_WIDTH(panel->width));
275 	tcon_write(tcon, EBC_WIN_VIR,
276 		   WIN_VIR_HEIGHT(panel->vir_height) |
277 		   WIN_VIR_WIDTH(panel->vir_width));
278 	tcon_write(tcon, EBC_WIN_ACT,
279 		   WIN_ACT_HEIGHT(panel->height) |
280 		   WIN_ACT_WIDTH(panel->width));
281 	tcon_write(tcon, EBC_WIN_DSP,
282 		   WIN_DSP_HEIGHT(panel->height) |
283 		   WIN_DSP_WIDTH(panel->width));
284 	tcon_write(tcon, EBC_WIN_DSP_ST,
285 		   WIN_DSP_YST(panel->fsl + panel->fbl) |
286 		   WIN_DSP_XST(panel->lsl + panel->lbl));
287 
288 	/* win2 fifo is 512x128, win fifo is 256x128,
289 	 * we set fifo almost value (fifo_size - 16)
290 	 * burst_reg = 7 mean ahb burst is incr16
291 	 */
292 	tcon_write(tcon, EBC_WIN_CTRL,
293 		   WIN2_FIFO_ALMOST_FULL_LEVEL(496) | WIN_EN(1) |
294 		   BURST_REG(7) | WIN_FIFO_ALMOST_FULL_LEVEL(240) |
295 		   WIN_FMT(Y_DATA_4BPP));
296 
297 	/*
298 	 * EBC_EPD_CTRL info:
299 	 * DSP_GD_ST: GCLK rising edge point(SCLK), which count from
300 	 *            the rasing edge of hsync(spec is wrong, count
301 	 *            from rasing edge of hsync, not falling edge of hsync)
302 	 * DSP_GD_END : GCLK falling edge point(SCLK), which count from
303 	 *              the rasing edge of hsync
304 	 * DSP_THREE_WIN_MODE: 0: lut mode or direct mode; 1: three win mode
305 	 * DSP_SDDW_MODE: 0: 8 bit data output; 1: 16 bit data output
306 	 * EPD_AUO: 0: EINK; 1:AUO
307 	 * EPD_GDRL: gate scanning direction: 1:button to top 0:top to button
308 	 * EPD_SDSHR: source scanning direction 1:right to left 0:left to right
309 	 */
310 	tcon_write(tcon, EBC_EPD_CTRL,
311 		   EINK_MODE_SWAP(1) |
312 		   DSP_GD_ST(panel->lsl + panel->gdck_sta) |
313 		   DSP_GD_END(panel->lsl + panel->gdck_sta + panel->lgonl) |
314 		   DSP_THREE_WIN_MODE(0) |
315 		   DSP_SDDW_MODE(!!panel->panel_16bit) |
316 		   EPD_AUO(0) |
317 		   EPD_GDRL(1) |
318 		   EPD_SDSHR(1));
319 	tcon_write(tcon, EBC_DSP_START,
320 		   DSP_SDCE_WIDTH(panel->ldl) | SW_BURST_CTRL);
321 
322 	tcon_write(tcon, EBC_DSP_CTRL,
323 		   DSP_SWAP_MODE(panel->panel_16bit ? 2 : 3) |
324 		   DSP_VCOM_MODE(1) |
325 		   DSP_SDCLK_DIV(panel->panel_16bit ? 7 : 3));
326 
327 	tcon_cfg_done(tcon);
328 
329 	ret = clk_set_rate(&tcon->dclk, panel->sdck * ((panel->panel_16bit ? 7 : 3) + 1));
330 	if (ret < 0) {
331 		printf("%s: set clock rate failed, %d\n", __func__, ret);
332 		return ret;
333 	}
334 
335 	return 0;
336 }
337 
338 static int ebc_tcon_disable(struct udevice *dev)
339 {
340 	return 0;
341 }
342 
343 static int ebc_tcon_dsp_mode_set(struct udevice *dev, int update_mode,
344 				 int display_mode, int three_win_mode,
345 				 int eink_mode)
346 {
347 	struct ebc_tcon_priv *tcon = dev_get_priv(dev);
348 
349 	tcon_update_bits(tcon, EBC_DSP_CTRL,
350 			 UPDATE_MODE_MASK | DISPLAY_MODE_MASK,
351 			 DSP_UPDATE_MODE(!!update_mode) |
352 			 DSP_DISPLAY_MODE(!!display_mode));
353 
354 	tcon_update_bits(tcon, EBC_EPD_CTRL, THREE_WIN_MODE_MASK,
355 			 DSP_THREE_WIN_MODE(!!three_win_mode));
356 	/* always set frm start bit 0 before real frame start */
357 	tcon_update_bits(tcon, EBC_DSP_START,
358 			 DSP_EINK_MODE_MASK | DSP_FRM_START_MASK,
359 			 DSP_EINK_MODE(!!eink_mode));
360 	tcon_cfg_done(tcon);
361 
362 	return 0;
363 }
364 
365 static int ebc_tcon_image_addr_set(struct udevice *dev, u32 pre_image_addr,
366 				   u32 cur_image_addr)
367 {
368 	struct ebc_tcon_priv *tcon = dev_get_priv(dev);
369 
370 	tcon_write(tcon, EBC_WIN_MST0, pre_image_addr);
371 	tcon_write(tcon, EBC_WIN_MST1, cur_image_addr);
372 	tcon_cfg_done(tcon);
373 
374 	return 0;
375 }
376 
377 static int ebc_tcon_frame_addr_set(struct udevice *dev, u32 frame_addr)
378 {
379 	struct ebc_tcon_priv *tcon = dev_get_priv(dev);
380 
381 	tcon_write(tcon, EBC_WIN_MST2, frame_addr);
382 	tcon_cfg_done(tcon);
383 
384 	return 0;
385 }
386 
387 static int ebc_tcon_lut_data_set(struct udevice *dev, unsigned int *lut_data,
388 				 int frame_count, int lut_32)
389 {
390 	int i, lut_size;
391 	struct ebc_tcon_priv *tcon = dev_get_priv(dev);
392 
393 	if ((!lut_32 && frame_count > 256) || (lut_32 && frame_count > 64)) {
394 		dev_err(tcon->dev, "frame count over flow\n");
395 		return -1;
396 	}
397 
398 	if (lut_32)
399 		lut_size = frame_count * 64;
400 	else
401 		lut_size = frame_count * 16;
402 
403 	for (i = 0; i < lut_size; i++)
404 		tcon_write(tcon, EBC_LUT_DATA_ADDR + (i * 4), lut_data[i]);
405 
406 	tcon_cfg_done(tcon);
407 
408 	return 0;
409 }
410 
411 static int wait_for_last_frame_complete(struct udevice *dev)
412 {
413 #ifndef CONFIG_IRQ
414 	u32 intr_status;
415 #endif
416 	struct ebc_tcon_priv *tcon = dev_get_priv(dev);
417 
418 #ifdef CONFIG_IRQ
419 	while (1) {
420 		if ((last_frame_done == -1) || (last_frame_done == 1))
421 			break;
422 		msleep(1);
423 	}
424 #else
425 	/* wait for frame display end*/
426 	while (1) {
427 		/* first frame don't need to wait*/
428 		if (last_frame_done == -1)
429 			break;
430 		intr_status = readl(tcon->reg + EBC_INT_STATUS);
431 		if (intr_status & DSP_END_INT)
432 			break;
433 		msleep(1);
434 	}
435 #endif
436 	tcon_update_bits(tcon, EBC_INT_STATUS,
437 			 DSP_END_INT_CLR, DSP_END_INT_CLR);
438 
439 	return 0;
440 }
441 
442 static int ebc_tcon_frame_start(struct udevice *dev, int frame_total)
443 {
444 	struct ebc_tcon_priv *tcon = dev_get_priv(dev);
445 
446 	tcon_write(tcon, EBC_INT_STATUS,
447 		   LINE_FLAG_INT_MASK | DSP_FRM_INT_MASK | FRM_END_INT_MASK);
448 	tcon_update_bits(tcon, EBC_DSP_START,
449 			 DSP_FRM_TOTAL_MASK, DSP_FRM_TOTAL(frame_total - 1));
450 	tcon_cfg_done(tcon);
451 
452 	tcon_update_bits(tcon, EBC_DSP_START,
453 			 DSP_FRM_START_MASK, DSP_FRM_START);
454 	last_frame_done = 0;
455 	return 0;
456 }
457 
458 static int rk_ebc_tcon_probe(struct udevice *dev)
459 {
460 	int ret;
461 	struct ebc_tcon_priv *priv = dev_get_priv(dev);
462 
463 	/*Enable PD first*/
464 	ret = ebc_power_domain(1);
465 	if (ret) {
466 		printf("%s, enable pd failed\n", __func__);
467 		return -1;
468 	}
469 
470 	priv->dev = dev;
471 	ret = clk_get_by_index(dev, 1, &priv->dclk);
472 	if (ret < 0) {
473 		printf("%s get clock fail! %d\n", __func__, ret);
474 		return -EINVAL;
475 	}
476 
477 #ifdef CONFIG_IRQ
478 	irq_install_handler(IRQ_EBC, ebc_irq_handler, dev);
479 	irq_handler_enable(IRQ_EBC);
480 #endif
481 	return 0;
482 }
483 
484 const struct rk_ebc_tcon_ops ebc_tcon_funcs = {
485 	.enable = ebc_tcon_enable,
486 	.disable = ebc_tcon_disable,
487 	.dsp_mode_set = ebc_tcon_dsp_mode_set,
488 	.image_addr_set = ebc_tcon_image_addr_set,
489 	.frame_addr_set = ebc_tcon_frame_addr_set,
490 	.lut_data_set = ebc_tcon_lut_data_set,
491 	.frame_start = ebc_tcon_frame_start,
492 	.wait_for_last_frame_complete = wait_for_last_frame_complete,
493 };
494 
495 static int rk_ebc_tcon_ofdata_to_platdata(struct udevice *dev)
496 {
497 	fdt_size_t size;
498 	fdt_addr_t addr;
499 	struct ebc_tcon_priv *priv = dev_get_priv(dev);
500 
501 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
502 	if (priv->grf <= 0) {
503 		debug("%s: Get syscon grf failed (ret=%p)\n",
504 		      __func__, priv->grf);
505 		return  -ENXIO;
506 	}
507 	priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
508 	if (priv->pmugrf <= 0) {
509 		debug("%s: Get syscon pmugrf failed (ret=%p)\n",
510 		      __func__, priv->grf);
511 		return  -ENXIO;
512 	}
513 	addr = dev_read_addr_size(dev, "reg", &size);
514 	if (addr == FDT_ADDR_T_NONE) {
515 		debug("%s: Get ebc_tcon address failed\n", __func__);
516 		return  -ENXIO;
517 	}
518 
519 	priv->reg = ioremap(addr, size);
520 	priv->reg_len = size;
521 	priv->regcache = malloc(size);
522 	memset(priv->regcache, 0, size);
523 	return 0;
524 }
525 
526 static const struct udevice_id ebc_tcon_ids[] = {
527 	{ .compatible = "rockchip,rk3568-ebc-tcon" },
528 	{ }
529 };
530 
531 U_BOOT_DRIVER(rk_ebc_tcon) = {
532 	.name	= "rk_ebc_tcon",
533 	.id	= UCLASS_EBC,
534 	.of_match = ebc_tcon_ids,
535 	.ofdata_to_platdata = rk_ebc_tcon_ofdata_to_platdata,
536 	.probe	= rk_ebc_tcon_probe,
537 	.ops	= &ebc_tcon_funcs,
538 	.priv_auto_alloc_size   = sizeof(struct ebc_tcon_priv),
539 };
540 
541 UCLASS_DRIVER(ebc_tcon) = {
542 	.id	= UCLASS_EBC,
543 	.name	= "ebc_tcon",
544 };
545 
546