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;
regs_dump(struct ebc_tcon_priv * tcon)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
ebc_power_domain(int on)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
tcon_write(struct ebc_tcon_priv * tcon,unsigned int reg,unsigned int value)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
tcon_read(struct ebc_tcon_priv * tcon,unsigned int reg)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
tcon_update_bits(struct ebc_tcon_priv * tcon,unsigned int reg,unsigned int mask,unsigned int val)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
ebc_irq_handler(int irq,void * data)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
tcon_cfg_done(struct ebc_tcon_priv * tcon)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
ebc_tcon_enable(struct udevice * dev,struct ebc_panel * panel)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 u32 width, height, vir_width, vir_height;
259
260 if (panel->rearrange) {
261 width = panel->width * 2;
262 height = panel->height / 2;
263 vir_width = panel->vir_width * 2;
264 vir_height = panel->vir_height / 2;
265 } else {
266 width = panel->width;
267 height = panel->height;
268 vir_width = panel->vir_width;
269 vir_height = panel->vir_height;
270 }
271
272 /* panel timing and win info config */
273 tcon_write(tcon, EBC_DSP_HTIMING0,
274 DSP_HTOTAL(panel->lsl + panel->lbl + panel->ldl +
275 panel->lel) | DSP_HS_END(panel->lsl));
276 tcon_write(tcon, EBC_DSP_HTIMING1,
277 DSP_HACT_END(panel->lsl + panel->lbl + panel->ldl) |
278 DSP_HACT_ST(panel->lsl + panel->lbl - 1));
279 tcon_write(tcon, EBC_DSP_VTIMING0,
280 DSP_VTOTAL(panel->fsl + panel->fbl + panel->fdl +
281 panel->fel) | DSP_VS_END(panel->fsl));
282 tcon_write(tcon, EBC_DSP_VTIMING1,
283 DSP_VACT_END(panel->fsl + panel->fbl + panel->fdl) |
284 DSP_VACT_ST(panel->fsl + panel->fbl));
285 tcon_write(tcon, EBC_DSP_ACT_INFO,
286 DSP_HEIGHT(height) |
287 DSP_WIDTH(width));
288 tcon_write(tcon, EBC_WIN_VIR,
289 WIN_VIR_HEIGHT(vir_height) |
290 WIN_VIR_WIDTH(vir_width));
291 tcon_write(tcon, EBC_WIN_ACT,
292 WIN_ACT_HEIGHT(height) |
293 WIN_ACT_WIDTH(width));
294 tcon_write(tcon, EBC_WIN_DSP,
295 WIN_DSP_HEIGHT(height) |
296 WIN_DSP_WIDTH(width));
297 tcon_write(tcon, EBC_WIN_DSP_ST,
298 WIN_DSP_YST(panel->fsl + panel->fbl) |
299 WIN_DSP_XST(panel->lsl + panel->lbl));
300
301 /* win2 fifo is 512x128, win fifo is 256x128,
302 * we set fifo almost value (fifo_size - 16)
303 * burst_reg = 7 mean ahb burst is incr16
304 */
305 tcon_write(tcon, EBC_WIN_CTRL,
306 WIN2_FIFO_ALMOST_FULL_LEVEL(496) | WIN_EN(1) |
307 BURST_REG(7) | WIN_FIFO_ALMOST_FULL_LEVEL(240) |
308 WIN_FMT(Y_DATA_4BPP));
309
310 /*
311 * EBC_EPD_CTRL info:
312 * DSP_GD_ST: GCLK rising edge point(SCLK), which count from
313 * the rasing edge of hsync(spec is wrong, count
314 * from rasing edge of hsync, not falling edge of hsync)
315 * DSP_GD_END : GCLK falling edge point(SCLK), which count from
316 * the rasing edge of hsync
317 * DSP_THREE_WIN_MODE: 0: lut mode or direct mode; 1: three win mode
318 * DSP_SDDW_MODE: 0: 8 bit data output; 1: 16 bit data output
319 * EPD_AUO: 0: EINK; 1:AUO
320 * EPD_GDRL: gate scanning direction: 1:button to top 0:top to button
321 * EPD_SDSHR: source scanning direction 1:right to left 0:left to right
322 */
323 tcon_write(tcon, EBC_EPD_CTRL,
324 EINK_MODE_SWAP(1) |
325 DSP_GD_ST(panel->lsl + panel->gdck_sta) |
326 DSP_GD_END(panel->lsl + panel->gdck_sta + panel->lgonl) |
327 DSP_THREE_WIN_MODE(0) |
328 DSP_SDDW_MODE(!!panel->panel_16bit) |
329 EPD_AUO(0) |
330 EPD_GDRL(1) |
331 EPD_SDSHR(1));
332 tcon_write(tcon, EBC_DSP_START,
333 DSP_SDCE_WIDTH(panel->ldl) | SW_BURST_CTRL);
334
335 tcon_write(tcon, EBC_DSP_CTRL,
336 DSP_SWAP_MODE(panel->panel_16bit ? 2 : 3) |
337 DSP_VCOM_MODE(1) |
338 DSP_SDCLK_DIV(panel->panel_16bit ? 7 : 3));
339
340 tcon_cfg_done(tcon);
341
342 ret = clk_set_rate(&tcon->dclk, panel->sdck * ((panel->panel_16bit ? 7 : 3) + 1));
343 if (ret < 0) {
344 printf("%s: set clock rate failed, %d\n", __func__, ret);
345 return ret;
346 }
347
348 return 0;
349 }
350
ebc_tcon_disable(struct udevice * dev)351 static int ebc_tcon_disable(struct udevice *dev)
352 {
353 return 0;
354 }
355
ebc_tcon_dsp_mode_set(struct udevice * dev,int update_mode,int display_mode,int three_win_mode,int eink_mode)356 static int ebc_tcon_dsp_mode_set(struct udevice *dev, int update_mode,
357 int display_mode, int three_win_mode,
358 int eink_mode)
359 {
360 struct ebc_tcon_priv *tcon = dev_get_priv(dev);
361
362 tcon_update_bits(tcon, EBC_DSP_CTRL,
363 UPDATE_MODE_MASK | DISPLAY_MODE_MASK,
364 DSP_UPDATE_MODE(!!update_mode) |
365 DSP_DISPLAY_MODE(!!display_mode));
366
367 tcon_update_bits(tcon, EBC_EPD_CTRL, THREE_WIN_MODE_MASK,
368 DSP_THREE_WIN_MODE(!!three_win_mode));
369 /* always set frm start bit 0 before real frame start */
370 tcon_update_bits(tcon, EBC_DSP_START,
371 DSP_EINK_MODE_MASK | DSP_FRM_START_MASK,
372 DSP_EINK_MODE(!!eink_mode));
373 tcon_cfg_done(tcon);
374
375 return 0;
376 }
377
ebc_tcon_image_addr_set(struct udevice * dev,u32 pre_image_addr,u32 cur_image_addr)378 static int ebc_tcon_image_addr_set(struct udevice *dev, u32 pre_image_addr,
379 u32 cur_image_addr)
380 {
381 struct ebc_tcon_priv *tcon = dev_get_priv(dev);
382
383 tcon_write(tcon, EBC_WIN_MST0, pre_image_addr);
384 tcon_write(tcon, EBC_WIN_MST1, cur_image_addr);
385 tcon_cfg_done(tcon);
386
387 return 0;
388 }
389
ebc_tcon_frame_addr_set(struct udevice * dev,u32 frame_addr)390 static int ebc_tcon_frame_addr_set(struct udevice *dev, u32 frame_addr)
391 {
392 struct ebc_tcon_priv *tcon = dev_get_priv(dev);
393
394 tcon_write(tcon, EBC_WIN_MST2, frame_addr);
395 tcon_cfg_done(tcon);
396
397 return 0;
398 }
399
ebc_tcon_lut_data_set(struct udevice * dev,unsigned int * lut_data,int frame_count,int lut_32)400 static int ebc_tcon_lut_data_set(struct udevice *dev, unsigned int *lut_data,
401 int frame_count, int lut_32)
402 {
403 int i, lut_size;
404 struct ebc_tcon_priv *tcon = dev_get_priv(dev);
405
406 if ((!lut_32 && frame_count > 256) || (lut_32 && frame_count > 64)) {
407 dev_err(tcon->dev, "frame count over flow\n");
408 return -1;
409 }
410
411 if (lut_32)
412 lut_size = frame_count * 64;
413 else
414 lut_size = frame_count * 16;
415
416 for (i = 0; i < lut_size; i++)
417 tcon_write(tcon, EBC_LUT_DATA_ADDR + (i * 4), lut_data[i]);
418
419 tcon_cfg_done(tcon);
420
421 return 0;
422 }
423
wait_for_last_frame_complete(struct udevice * dev)424 static int wait_for_last_frame_complete(struct udevice *dev)
425 {
426 #ifndef CONFIG_IRQ
427 u32 intr_status;
428 #endif
429 struct ebc_tcon_priv *tcon = dev_get_priv(dev);
430
431 #ifdef CONFIG_IRQ
432 while (1) {
433 if ((last_frame_done == -1) || (last_frame_done == 1))
434 break;
435 msleep(1);
436 }
437 #else
438 /* wait for frame display end*/
439 while (1) {
440 /* first frame don't need to wait*/
441 if (last_frame_done == -1)
442 break;
443 intr_status = readl(tcon->reg + EBC_INT_STATUS);
444 if (intr_status & DSP_END_INT)
445 break;
446 msleep(1);
447 }
448 #endif
449 tcon_update_bits(tcon, EBC_INT_STATUS,
450 DSP_END_INT_CLR, DSP_END_INT_CLR);
451
452 return 0;
453 }
454
ebc_tcon_frame_start(struct udevice * dev,int frame_total)455 static int ebc_tcon_frame_start(struct udevice *dev, int frame_total)
456 {
457 struct ebc_tcon_priv *tcon = dev_get_priv(dev);
458
459 tcon_write(tcon, EBC_INT_STATUS,
460 LINE_FLAG_INT_MASK | DSP_FRM_INT_MASK | FRM_END_INT_MASK);
461 tcon_update_bits(tcon, EBC_DSP_START,
462 DSP_FRM_TOTAL_MASK, DSP_FRM_TOTAL(frame_total - 1));
463 tcon_cfg_done(tcon);
464
465 tcon_update_bits(tcon, EBC_DSP_START,
466 DSP_FRM_START_MASK, DSP_FRM_START);
467 last_frame_done = 0;
468 return 0;
469 }
470
rk_ebc_tcon_probe(struct udevice * dev)471 static int rk_ebc_tcon_probe(struct udevice *dev)
472 {
473 int ret;
474 struct ebc_tcon_priv *priv = dev_get_priv(dev);
475
476 /*Enable PD first*/
477 ret = ebc_power_domain(1);
478 if (ret) {
479 printf("%s, enable pd failed\n", __func__);
480 return -1;
481 }
482
483 priv->dev = dev;
484 ret = clk_get_by_index(dev, 1, &priv->dclk);
485 if (ret < 0) {
486 printf("%s get clock fail! %d\n", __func__, ret);
487 return -EINVAL;
488 }
489
490 #ifdef CONFIG_IRQ
491 irq_install_handler(IRQ_EBC, ebc_irq_handler, dev);
492 irq_handler_enable(IRQ_EBC);
493 #endif
494 return 0;
495 }
496
497 const struct rk_ebc_tcon_ops ebc_tcon_funcs = {
498 .enable = ebc_tcon_enable,
499 .disable = ebc_tcon_disable,
500 .dsp_mode_set = ebc_tcon_dsp_mode_set,
501 .image_addr_set = ebc_tcon_image_addr_set,
502 .frame_addr_set = ebc_tcon_frame_addr_set,
503 .lut_data_set = ebc_tcon_lut_data_set,
504 .frame_start = ebc_tcon_frame_start,
505 .wait_for_last_frame_complete = wait_for_last_frame_complete,
506 };
507
rk_ebc_tcon_ofdata_to_platdata(struct udevice * dev)508 static int rk_ebc_tcon_ofdata_to_platdata(struct udevice *dev)
509 {
510 fdt_size_t size;
511 fdt_addr_t addr;
512 struct ebc_tcon_priv *priv = dev_get_priv(dev);
513
514 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
515 if (priv->grf <= 0) {
516 debug("%s: Get syscon grf failed (ret=%p)\n",
517 __func__, priv->grf);
518 return -ENXIO;
519 }
520 priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
521 if (priv->pmugrf <= 0) {
522 debug("%s: Get syscon pmugrf failed (ret=%p)\n",
523 __func__, priv->grf);
524 return -ENXIO;
525 }
526 addr = dev_read_addr_size(dev, "reg", &size);
527 if (addr == FDT_ADDR_T_NONE) {
528 debug("%s: Get ebc_tcon address failed\n", __func__);
529 return -ENXIO;
530 }
531
532 priv->reg = ioremap(addr, size);
533 priv->reg_len = size;
534 priv->regcache = malloc(size);
535 memset(priv->regcache, 0, size);
536 return 0;
537 }
538
539 static const struct udevice_id ebc_tcon_ids[] = {
540 { .compatible = "rockchip,rk3568-ebc-tcon" },
541 { }
542 };
543
544 U_BOOT_DRIVER(rk_ebc_tcon) = {
545 .name = "rk_ebc_tcon",
546 .id = UCLASS_EBC,
547 .of_match = ebc_tcon_ids,
548 .ofdata_to_platdata = rk_ebc_tcon_ofdata_to_platdata,
549 .probe = rk_ebc_tcon_probe,
550 .ops = &ebc_tcon_funcs,
551 .priv_auto_alloc_size = sizeof(struct ebc_tcon_priv),
552 };
553
554 UCLASS_DRIVER(ebc_tcon) = {
555 .id = UCLASS_EBC,
556 .name = "ebc_tcon",
557 };
558
559