xref: /rk3399_rockchip-uboot/drivers/video/rk_eink/rk_eink_display.c (revision c3e08fa050aa3e8eb31fbd76f4d1e28c00ffe0b4)
1 /*
2  * (C) Copyright 2020 Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  * Author: Wenping Zhang <wenping.zhang@rock-chips.com>
6  */
7 #include <common.h>
8 #include <dm.h>
9 #include <stdio.h>
10 #include <errno.h>
11 #include <mapmem.h>
12 #include <stdlib.h>
13 #include <asm/arch/vendor.h>
14 #include <dm/of_access.h>
15 #include <dm/uclass.h>
16 #include <dm/uclass-id.h>
17 #include <boot_rkimg.h>
18 #include <rk_eink.h>
19 #include "rk_ebc.h"
20 #include "epdlut/epd_lut.h"
21 
22 #define PART_WAVEFORM		"waveform"
23 #define EINK_LOGO_PART_MAGIC	"RKEL"
24 #define EINK_LOGO_IMAGE_MAGIC	"GR04"
25 /*
26  * grayscale logo partition format:
27  * block0:
28  * struct logo_part_header part_header;
29  * struct grayscale_header logo1_header;
30  * struct grayscale_header logo2_header;
31  * struct grayscale_header logo3_header;
32  * struct grayscale_header logo4_header;
33  * ....
34  *
35  * block 1:
36  * logo1_image
37  *
38  * .....
39  * block m:
40  * logo2_image
41  *
42  * ........
43  * block n:
44  * logo3_image
45  *
46  * ........
47  * block i:
48  * logoi_image
49  */
50 
51 //logo partition Header, 64byte
52 struct logo_part_header {
53 	char magic[4]; /* must be "RKEL" */
54 	u32  totoal_size;
55 	u32  screen_width;
56 	u32  screen_height;
57 	u32  logo_count;
58 	u8   version[4];
59 	u32  rsv[10];
60 } __packed;
61 
62 // logo image header,32 byte
63 struct grayscale_header {
64 	char magic[4]; /* must be "GR04" */
65 	u16 x;
66 	u16 y;
67 	u16 w;
68 	u16 h;
69 	u32 logo_type;
70 	u32 data_offset; /* image offset in byte */
71 	u32 data_size; /* image size in byte */
72 	u32 rsv[2];
73 } __packed;
74 
75 /*
76  * The start address of logo image in logo.img must be aligned in 512 bytes,
77  * so the header size must be times of 512 bytes. Here we fix the size to 512
78  * bytes, so the count of logo image can only support up to 14.
79  */
80 struct logo_info {
81 	struct logo_part_header part_hdr;
82 	struct grayscale_header img_hdr[14];
83 } __packed;
84 
85 struct rockchip_eink_display_priv {
86 	struct udevice *dev;
87 	struct udevice *ebc_tcon_dev;
88 	struct udevice *ebc_pwr_dev;
89 	int vcom;
90 };
91 
92 enum {
93 	EBC_PWR_DOWN = 0,
94 	EBC_PWR_ON = 1,
95 };
96 
97 #define EINK_VCOM_ID		17
98 #define EINK_VCOM_MAX		64
99 #define VCOM_DEFAULT_VALUE	1650
100 
101 static struct logo_info eink_logo_info;
102 static struct udevice *eink_dev;
103 static volatile int last_logo_type = -1;
104 static int read_vcom_from_vendor(void)
105 {
106 	int ret = 0;
107 	char vcom_str[EINK_VCOM_MAX] = {0};
108 	char vcom_args[EINK_VCOM_MAX] = {0};
109 
110 	/* Read vcom value from vendor storage part */
111 	ret = vendor_storage_read(EINK_VCOM_ID, vcom_str, (EINK_VCOM_MAX - 1));
112 	if (ret > 0) {
113 		snprintf(vcom_args, strlen(vcom_str) + 15, "ebc_pmic.vcom=%s", vcom_str);
114 		printf("eink update bootargs: %s\n", vcom_args);
115 		env_update("bootargs", vcom_args);
116 	} else {
117 		return ret;
118 	}
119 
120 	return atoi(vcom_str);
121 }
122 
123 static int read_waveform(struct udevice *dev)
124 {
125 	int cnt, start, ret;
126 	disk_partition_t part;
127 	struct blk_desc *dev_desc;
128 	struct ebc_panel *plat = dev_get_platdata(dev);
129 
130 	dev_desc = rockchip_get_bootdev();
131 	if (!dev_desc) {
132 		printf("%s: Could not find device\n", __func__);
133 		return -EIO;
134 	}
135 	if (part_get_info_by_name(dev_desc, PART_WAVEFORM, &part) < 0) {
136 		printf("Get waveform partition failed\n");
137 		return -ENODEV;
138 	}
139 	cnt = plat->lut_pbuf_size / RK_BLK_SIZE;
140 	start = part.start;
141 	ret = blk_dread(dev_desc, start, cnt, (void *)plat->lut_pbuf);
142 	if (ret != cnt)
143 		printf("Try to read %d blocks failed, only read %d\n",
144 		       cnt, ret);
145 
146 	flush_dcache_range((ulong)plat->lut_pbuf,
147 			   ALIGN((ulong)plat->lut_pbuf + cnt,
148 				 CONFIG_SYS_CACHELINE_SIZE));
149 	ret = epd_lut_from_mem_init(plat->lut_pbuf, &plat->lut_ops);
150 	if (ret < 0) {
151 		printf("lut init failed\n");
152 		return -EINVAL;
153 	}
154 
155 	return 0;
156 }
157 
158 static u32 aligned_image_size_4k(struct udevice *dev)
159 {
160 	struct ebc_panel *plat = dev_get_platdata(dev);
161 	u32 w = plat->width;
162 	u32 h = plat->height;
163 
164 	return ALIGN((w * h) >> 1, 4096);
165 }
166 
167 /*
168  * This driver load the grayscale image from flash,
169  * and put it in the reserve memory which define in dts:
170  * display_reserved: framebuffer@10000000 {
171  *	reg = <0x0 0x10000000 0x0 0x2000000>;
172  *	no-map;
173  * };
174  * Every image logo size must be aligned in 4K, make sure
175  * kernel can use it rightly, the buffer of LOGO image is
176  * put in order of below map:
177  *  |---reset logo        ---|
178  *  |---uboot logo        ---|
179  *  |---kernel logo       ---|
180  *  |---charge_0 logo   ---|
181  *  |---charge_1 logo   ---|
182  *  |---charge_2 logo   ---|
183  *  |---charge_3 logo   ---|
184  *  |---charge_4 logo   ---|
185  *  |---charge_5 logo   ---|
186  *  |---battery low logo---|
187  */
188 static int get_addr_by_type(struct udevice *dev, u32 logo_type)
189 {
190 	u32 offset, indx, img_size;
191 	struct ebc_panel *plat = dev_get_platdata(dev);
192 
193 	if (plat->disp_pbuf_size == 0 || !plat->disp_pbuf) {
194 		printf("invalid display buffer, please check dts\n");
195 		return -EINVAL;
196 	}
197 	indx = ffs(logo_type);
198 	img_size = aligned_image_size_4k(dev);
199 	offset = img_size * indx;
200 	if (offset + img_size > plat->disp_pbuf_size) {
201 		printf("reserve display memory size is not enough\n");
202 		return -EINVAL;
203 	}
204 
205 	switch (logo_type) {
206 	case EINK_LOGO_RESET:
207 	case EINK_LOGO_UBOOT:
208 	case EINK_LOGO_KERNEL:
209 	case EINK_LOGO_CHARGING_0:
210 	case EINK_LOGO_CHARGING_1:
211 	case EINK_LOGO_CHARGING_2:
212 	case EINK_LOGO_CHARGING_3:
213 	case EINK_LOGO_CHARGING_4:
214 	case EINK_LOGO_CHARGING_5:
215 	case EINK_LOGO_CHARGING_LOWPOWER:
216 		return (plat->disp_pbuf + offset);
217 	default:
218 		printf("invalid logo type[%d]\n", logo_type);
219 	}
220 
221 	return -EINVAL;
222 }
223 
224 static int read_header(struct blk_desc *dev_desc,
225 		       disk_partition_t *part,
226 		       struct logo_info *header)
227 {
228 	int i;
229 	struct logo_part_header *part_hdr = &header->part_hdr;
230 
231 	if (blk_dread(dev_desc, part->start, 1, header) != 1)
232 		return -EIO;
233 
234 	if (memcmp(part_hdr->magic, EINK_LOGO_PART_MAGIC, 4)) {
235 		printf("partition header is invalid\n");
236 		return -EINVAL;
237 	}
238 	if (part_hdr->logo_count == 0) {
239 		printf("the count of logo image is 0\n");
240 		return -EINVAL;
241 	}
242 	for (i = 0; i < part_hdr->logo_count; i++) {
243 		struct grayscale_header *img_hdr = &header->img_hdr[i];
244 
245 		if (memcmp(img_hdr->magic, EINK_LOGO_IMAGE_MAGIC, 4)) {
246 			printf("image[%d] header '%s' is invalid\n", i,
247 			       img_hdr->magic);
248 			return -EINVAL;
249 		}
250 	}
251 
252 	return 0;
253 }
254 
255 static int read_grayscale(struct blk_desc *dev_desc,
256 			  disk_partition_t *part, u32 offset,
257 			  u32 size, void *buf)
258 {
259 	u32 blk_start, blk_offset, blk_count;
260 
261 	blk_offset = DIV_ROUND_UP(offset, dev_desc->blksz);
262 	blk_start = part->start + blk_offset;
263 	blk_count = DIV_ROUND_UP(size, dev_desc->blksz);
264 
265 	debug("blk_offset=%d, blk_start=%d,blk_count=%d,out buf=%p\n",
266 	      blk_offset, blk_start, blk_count, buf);
267 	if (blk_dread(dev_desc, blk_start, blk_count, buf) != blk_count) {
268 		printf("read grayscale data failed\n");
269 		return -EIO;
270 	}
271 
272 	return 0;
273 }
274 
275 /*
276  * The eink kernel driver need last frame to do part refresh,
277  * so we need to transfer two images to kernel, which is kernel
278  * logo and the logo displayed in uboot.
279  *
280  * this function use logo type bitmap to indicate several logo.
281  * u32 needed_logo: we only load needed logo image into ram, such as
282  *                   uboot logo + kernel logo or charger logo + kernel
283  *                   logo
284  * u32 *loaded_logo: because the needed logo may not exist in logo.img,
285  *                  store the really loaded logo in para loaded_logo.
286  */
287 static int read_needed_logo_from_partition(struct udevice *dev,
288 					   u32 needed_logo,
289 					   u32 *loaded_logo)
290 {
291 	int ret, i;
292 	disk_partition_t part;
293 	struct blk_desc *dev_desc;
294 	struct logo_info *hdr = &eink_logo_info;
295 	struct logo_part_header *part_hdr = &hdr->part_hdr;
296 	struct ebc_panel *panel = dev_get_platdata(dev);
297 
298 	if (*loaded_logo & needed_logo) {
299 		printf("logo[0x%x] is already loaded, just return!\n",
300 		       needed_logo);
301 		return 0;
302 	}
303 	dev_desc = rockchip_get_bootdev();
304 	if (!dev_desc) {
305 		printf("%s: Could not find device\n", __func__);
306 		return -EIO;
307 	}
308 
309 	if (part_get_info_by_name(dev_desc, PART_LOGO, &part) < 0)
310 		return -ENODEV;
311 
312 	ret = read_header(dev_desc, &part, hdr);
313 	if (ret < 0) {
314 		printf("eink logo read header failed,ret = %d\n", ret);
315 		return -EINVAL;
316 	}
317 	if (part_hdr->screen_width != panel->width ||
318 	    part_hdr->screen_height != panel->height){
319 		printf("logo size(%dx%d) is not same as screen size(%dx%d)\n",
320 		       part_hdr->screen_width, part_hdr->screen_height,
321 			panel->width, panel->height);
322 		return -EINVAL;
323 	}
324 
325 	for (i = 0; i < part_hdr->logo_count; i++) {
326 		struct grayscale_header *img_hdr = &hdr->img_hdr[i];
327 		int pic_buf;
328 		u32 offset = img_hdr->data_offset;
329 		u32 size = img_hdr->data_size;
330 		u32 logo_type = img_hdr->logo_type;
331 
332 		debug("offset=0x%x, size=%d,logo_type=%d,w=%d,h=%d\n",
333 		      offset, size, logo_type, img_hdr->w, img_hdr->h);
334 
335 		if (needed_logo & logo_type) {
336 			pic_buf = get_addr_by_type(dev, logo_type);
337 
338 			if (pic_buf <= 0) {
339 				printf("Get buffer failed for image %d\n",
340 				       img_hdr->logo_type);
341 				return -EIO;
342 			}
343 			if (!IS_ALIGNED((ulong)pic_buf,
344 					ARCH_DMA_MINALIGN)) {
345 				printf("disp buffer is not dma aligned\n");
346 				return -EINVAL;
347 			}
348 			read_grayscale(dev_desc, &part, offset, size,
349 				       (void *)((ulong)pic_buf));
350 			flush_dcache_range((ulong)pic_buf,
351 					   ALIGN((ulong)pic_buf + size,
352 						 CONFIG_SYS_CACHELINE_SIZE));
353 			*loaded_logo |= logo_type;
354 		}
355 	}
356 
357 	return 0;
358 }
359 
360 static int ebc_power_set(struct udevice *dev, int is_on)
361 {
362 	int ret;
363 	struct rockchip_eink_display_priv *priv = dev_get_priv(dev);
364 	struct ebc_panel *panel = dev_get_platdata(dev);
365 	struct udevice *ebc_tcon_dev = priv->ebc_tcon_dev;
366 	struct rk_ebc_tcon_ops *ebc_tcon_ops = ebc_tcon_get_ops(ebc_tcon_dev);
367 	struct udevice *ebc_pwr_dev = priv->ebc_pwr_dev;
368 	struct rk_ebc_pwr_ops *pwr_ops = ebc_pwr_get_ops(ebc_pwr_dev);
369 
370 	if (is_on) {
371 		ret = ebc_tcon_ops->enable(ebc_tcon_dev, panel);
372 		if (ret) {
373 			printf("%s, ebc tcon enabled failed\n", __func__);
374 			return -1;
375 		}
376 		ret = pwr_ops->power_on(ebc_pwr_dev);
377 		if (ret) {
378 			printf("%s, power on failed\n", __func__);
379 			return -1;
380 		}
381 	} else {
382 		ret = pwr_ops->power_down(ebc_pwr_dev);
383 		if (ret) {
384 			printf("%s, power_down failed\n", __func__);
385 			return -1;
386 		}
387 		ret = ebc_tcon_ops->disable(ebc_tcon_dev);
388 		if (ret) {
389 			printf("%s, ebc tcon disable failed\n", __func__);
390 			return -1;
391 		}
392 	}
393 	return 0;
394 }
395 
396 static int eink_display(struct udevice *dev, u32 pre_img_buf,
397 			u32 cur_img_buf, u32 lut_type, int update_mode)
398 {
399 	u32 temperature, frame_num;
400 	struct rockchip_eink_display_priv *priv = dev_get_priv(dev);
401 	struct ebc_panel *plat = dev_get_platdata(dev);
402 	struct epd_lut_ops *lut_ops = &plat->lut_ops;
403 	struct udevice *ebc_pwr_dev = priv->ebc_pwr_dev;
404 	struct rk_ebc_pwr_ops *pwr_ops = ebc_pwr_get_ops(ebc_pwr_dev);
405 	struct udevice *ebc_tcon_dev = priv->ebc_tcon_dev;
406 	struct rk_ebc_tcon_ops *ebc_tcon_ops = ebc_tcon_get_ops(ebc_tcon_dev);
407 
408 	pwr_ops->temp_get(ebc_pwr_dev, &temperature);
409 	if (temperature <= 0 || temperature > 50) {
410 		printf("temperature = %d, out of range0~50 ,use 25\n",
411 		       temperature);
412 		temperature = 25;
413 	}
414 
415 	if (!lut_ops->lut_get) {
416 		printf("get lut ops failed\n");
417 		return -EIO;
418 	}
419 	lut_ops->lut_get(&plat->lut_data, lut_type, temperature);
420 	frame_num = plat->lut_data.frame_num;
421 	debug("lut_type=%d, frame num=%d, temp=%d\n", lut_type,
422 	      frame_num, temperature);
423 
424 	ebc_tcon_ops->lut_data_set(ebc_tcon_dev, plat->lut_data.data,
425 				   frame_num, 0);
426 	ebc_tcon_ops->dsp_mode_set(ebc_tcon_dev, update_mode,
427 				   LUT_MODE, !THREE_WIN_MODE, !EINK_MODE);
428 	ebc_tcon_ops->image_addr_set(ebc_tcon_dev, pre_img_buf, cur_img_buf);
429 	ebc_tcon_ops->frame_start(ebc_tcon_dev, frame_num);
430 	ebc_tcon_ops->wait_for_last_frame_complete(ebc_tcon_dev);
431 
432 	return 0;
433 }
434 
435 static int rk_eink_display_init(void)
436 {
437 	int ret;
438 	struct uclass *uc;
439 	struct udevice *dev;
440 
441 	if (eink_dev) {
442 		printf("ebc-dev is already initialized!\n");
443 		return 0;
444 	}
445 
446 	ret = uclass_get(UCLASS_EINK_DISPLAY, &uc);
447 	if (ret) {
448 		printf("can't find uclass eink\n");
449 		return -ENODEV;
450 	}
451 	for (uclass_first_device(UCLASS_EINK_DISPLAY, &dev);
452 	     dev; uclass_next_device(&dev))
453 		;
454 
455 	if (eink_dev) {
456 		printf("ebc-dev is probed success!\n");
457 		return 0;
458 	}
459 	printf("Can't find ebc-dev\n");
460 	return -ENODEV;
461 }
462 
463 /*
464  * Eink display need current and previous image buffer, We assume
465  * every type of logo has only one image, so just tell this function
466  * last logo type and current logo type, it will find the right images.
467  * last_logo_type: -1 means it's first displaying.
468  */
469 static int rockchip_eink_show_logo(int cur_logo_type, int update_mode)
470 {
471 	int ret = 0;
472 	u32 logo_addr;
473 	u32 last_logo_addr;
474 	struct ebc_panel *plat;
475 	struct udevice *dev;
476 	static u32 loaded_logo;
477 
478 	if (!eink_dev) {
479 		static bool first_init = true;
480 
481 		if (first_init) {
482 			first_init = false;
483 			ret = rk_eink_display_init();
484 			if (ret) {
485 				printf("Get ebc dev failed, check dts\n");
486 				return -ENODEV;
487 			}
488 		} else {
489 			return -ENODEV;
490 		}
491 	}
492 	dev = eink_dev;
493 
494 	/*Don't need to update display*/
495 	if (last_logo_type == cur_logo_type) {
496 		debug("Same as last picture, Don't need to display\n");
497 		return 0;
498 	}
499 
500 	plat = dev_get_platdata(dev);
501 
502 	ret = ebc_power_set(dev, EBC_PWR_ON);
503 	if (ret) {
504 		printf("Eink power on failed\n");
505 		return -1;
506 	}
507 	/*
508 	 * The last_logo_type is -1 means it's first displaying
509 	 */
510 	if (last_logo_type == -1) {
511 		int size = (plat->width * plat->height) >> 1;
512 
513 		logo_addr = get_addr_by_type(dev, EINK_LOGO_RESET);
514 		memset((u32 *)(u64)logo_addr, 0xff, size);
515 		eink_display(dev, logo_addr, logo_addr,
516 			     WF_TYPE_RESET, 0);
517 		last_logo_type = 0;
518 		last_logo_addr = logo_addr;
519 	} else {
520 		last_logo_addr = get_addr_by_type(dev, last_logo_type);
521 		if (last_logo_addr < 0) {
522 			printf("Invalid last logo addr, exit!\n");
523 			goto out;
524 		}
525 		if (cur_logo_type == EINK_LOGO_RESET) {
526 			logo_addr = get_addr_by_type(dev, EINK_LOGO_RESET);
527 			eink_display(dev, last_logo_addr,
528 				     logo_addr,
529 				     WF_TYPE_GC16, update_mode);
530 			last_logo_type = -1;
531 			goto out;
532 		}
533 	}
534 	ret = read_needed_logo_from_partition(dev, cur_logo_type,
535 					      &loaded_logo);
536 	if (ret || !(loaded_logo & cur_logo_type)) {
537 		printf("read logo[0x%x] failed, loaded_logo=0x%x\n",
538 		       cur_logo_type, loaded_logo);
539 		ret = -EIO;
540 		goto out;
541 	}
542 	logo_addr = get_addr_by_type(dev, cur_logo_type);
543 	debug("logo_addr=%x, logo_type=%d\n", logo_addr, cur_logo_type);
544 	if (logo_addr <= 0) {
545 		printf("get logo buffer failed\n");
546 		ret = -EIO;
547 		goto out;
548 	}
549 
550 	eink_display(dev, last_logo_addr, logo_addr, WF_TYPE_GC16, update_mode);
551 	last_logo_type = cur_logo_type;
552 	/*
553 	 * System will boot up to kernel only when the
554 	 * logo is uboot logo
555 	 */
556 	if (cur_logo_type == EINK_LOGO_UBOOT) {
557 		char logo_args[64] = {0};
558 
559 		printf("Transmit uboot logo addr(0x%x) to kernel\n", logo_addr);
560 		sprintf(logo_args, "ulogo_addr=0x%x", logo_addr);
561 		env_update("bootargs", logo_args);
562 		ret = read_needed_logo_from_partition(dev, EINK_LOGO_KERNEL,
563 						      &loaded_logo);
564 		if (ret || !(loaded_logo & EINK_LOGO_KERNEL)) {
565 			printf("No invalid kernel logo in logo.img\n");
566 		} else {
567 			int klogo_addr = get_addr_by_type(dev,
568 							  EINK_LOGO_KERNEL);
569 
570 			if (klogo_addr <= 0) {
571 				printf("get kernel logo buffer failed\n");
572 				ret = -EIO;
573 				goto out;
574 			}
575 			printf("Transmit kernel logo addr(0x%x) to kernel\n",
576 			       klogo_addr);
577 			sprintf(logo_args, "klogo_addr=0x%x", klogo_addr);
578 			env_update("bootargs", logo_args);
579 		}
580 	}
581 
582 out:
583 	ret = ebc_power_set(dev, EBC_PWR_DOWN);
584 	if (ret)
585 		printf("Eink power down failed\n");
586 	return ret;
587 }
588 
589 int rockchip_eink_show_uboot_logo(void)
590 {
591 	return rockchip_eink_show_logo(EINK_LOGO_UBOOT, EINK_UPDATE_DIFF);
592 }
593 
594 int rockchip_eink_show_charge_logo(int logo_type)
595 {
596 	return rockchip_eink_show_logo(logo_type, EINK_UPDATE_DIFF);
597 }
598 
599 static int rockchip_eink_display_probe(struct udevice *dev)
600 {
601 	int ret, vcom;
602 	struct rockchip_eink_display_priv *priv = dev_get_priv(dev);
603 
604 	/* Before relocation we don't need to do anything */
605 	if (!(gd->flags & GD_FLG_RELOC))
606 		return 0;
607 
608 	ret = uclass_get_device_by_phandle(UCLASS_EBC, dev,
609 					   "ebc_tcon",
610 					   &priv->ebc_tcon_dev);
611 	if (ret) {
612 		dev_err(dev, "Cannot get ebc_tcon: %d\n", ret);
613 		return ret;
614 	}
615 
616 	ret = uclass_get_device_by_phandle(UCLASS_I2C_GENERIC, dev,
617 					   "pmic",
618 					   &priv->ebc_pwr_dev);
619 	if (ret) {
620 		dev_err(dev, "Cannot get pmic: %d\n", ret);
621 		return ret;
622 	}
623 
624 	vcom = read_vcom_from_vendor();
625 	if (vcom <= 0) {
626 		printf("read vcom from vendor failed, use default vcom\n");
627 		priv->vcom = VCOM_DEFAULT_VALUE;
628 	} else {
629 		priv->vcom = vcom;
630 	}
631 
632 	if (priv->ebc_pwr_dev) {
633 		struct rk_ebc_pwr_ops *pwr_ops;
634 
635 		pwr_ops = ebc_pwr_get_ops(priv->ebc_pwr_dev);
636 		ret = pwr_ops->vcom_set(priv->ebc_pwr_dev, priv->vcom);
637 		if (ret) {
638 			printf("%s, vcom_set failed\n", __func__);
639 			return -EIO;
640 		}
641 	}
642 
643 	// read lut to ram, and get lut ops
644 	ret = read_waveform(dev);
645 	if (ret < 0) {
646 		printf("read wavform failed\n");
647 		return -EIO;
648 	}
649 
650 	eink_dev = dev;
651 	return 0;
652 }
653 
654 static int rockchip_eink_display_ofdata_to_platdata(struct udevice *dev)
655 {
656 	fdt_size_t size;
657 	fdt_addr_t tmp_addr;
658 	struct device_node *disp_mem;
659 	struct device_node *waveform_mem;
660 	struct ebc_panel *plat = dev_get_platdata(dev);
661 
662 	plat->width = dev_read_u32_default(dev, "panel,width", 0);
663 	plat->height = dev_read_u32_default(dev, "panel,height", 0);
664 	plat->sdck = dev_read_u32_default(dev, "panel,sdck", 0);
665 	plat->lsl = dev_read_u32_default(dev, "panel,lsl", 0);
666 	plat->lbl = dev_read_u32_default(dev, "panel,lbl", 0);
667 	plat->ldl = dev_read_u32_default(dev, "panel,ldl", 0);
668 	plat->lel = dev_read_u32_default(dev, "panel,lel", 0);
669 	plat->gdck_sta = dev_read_u32_default(dev, "panel,gdck-sta", 0);
670 	plat->lgonl = dev_read_u32_default(dev, "panel,lgonl", 0);
671 	plat->fsl = dev_read_u32_default(dev, "panel,fsl", 0);
672 	plat->fbl = dev_read_u32_default(dev, "panel,fbl", 0);
673 	plat->fdl = dev_read_u32_default(dev, "panel,fdl", 0);
674 	plat->fel = dev_read_u32_default(dev, "panel,fel", 0);
675 	plat->panel_16bit = dev_read_u32_default(dev, "panel,panel_16bit", 0);
676 	plat->panel_color = dev_read_u32_default(dev, "panel,panel_color", 0);
677 	plat->mirror = dev_read_u32_default(dev, "panel,mirror", 0);
678 	plat->width_mm = dev_read_u32_default(dev, "panel,width-mm", 0);
679 	plat->height_mm = dev_read_u32_default(dev, "panel,height-mm", 0);
680 
681 	disp_mem = of_parse_phandle(ofnode_to_np(dev_ofnode(dev)),
682 				    "memory-region", 0);
683 	if (!disp_mem) {
684 		dev_err(dev, "Cannot get memory-region from dts\n");
685 		return -ENODEV;
686 	}
687 	tmp_addr = ofnode_get_addr_size(np_to_ofnode(disp_mem), "reg", &size);
688 	if (tmp_addr == FDT_ADDR_T_NONE) {
689 		printf("get display memory address failed\n");
690 		return -ENODEV;
691 	}
692 
693 	plat->disp_pbuf = (u64)map_sysmem(tmp_addr, 0);
694 	plat->disp_pbuf_size = size;
695 	debug("display mem=0x%x, size=%x\n", plat->disp_pbuf,
696 	      plat->disp_pbuf_size);
697 	waveform_mem = of_parse_phandle(ofnode_to_np(dev_ofnode(dev)),
698 					"waveform-region", 0);
699 	if (!waveform_mem) {
700 		printf("Cannot get waveform-region from dts\n");
701 		return -ENODEV;
702 	}
703 	tmp_addr = ofnode_get_addr_size(np_to_ofnode(waveform_mem),
704 					"reg", &size);
705 	if (tmp_addr == FDT_ADDR_T_NONE) {
706 		printf("get waveform memory address failed\n");
707 		return -ENODEV;
708 	}
709 
710 	plat->lut_pbuf = map_sysmem(tmp_addr, 0);
711 	plat->lut_pbuf_size = size;
712 	debug("lut mem=0x%p, size=%x\n", plat->lut_pbuf, plat->lut_pbuf_size);
713 	return 0;
714 }
715 
716 static const struct udevice_id rockchip_eink_display_ids[] = {
717 	{ .compatible = "rockchip,ebc-dev", },
718 	{}
719 };
720 
721 U_BOOT_DRIVER(rk_eink_display) = {
722 	.name = "rockchip_eink_display",
723 	.id = UCLASS_EINK_DISPLAY,
724 	.of_match = rockchip_eink_display_ids,
725 	.ofdata_to_platdata = rockchip_eink_display_ofdata_to_platdata,
726 	.probe = rockchip_eink_display_probe,
727 	.priv_auto_alloc_size = sizeof(struct rockchip_eink_display_priv),
728 	.platdata_auto_alloc_size = sizeof(struct ebc_panel),
729 };
730 
731 UCLASS_DRIVER(rk_eink) = {
732 	.id	= UCLASS_EINK_DISPLAY,
733 	.name	= "rk_eink",
734 };
735 
736