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