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