xref: /rk3399_rockchip-uboot/drivers/video/rk_eink/rk_eink_display.c (revision e091b6c996a68a6a0faa2bd3ffdd90b3ba5f44ce)
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  */
190 static int get_addr_by_type(struct udevice *dev, u32 logo_type)
191 {
192 	u32 offset, indx, img_size;
193 	struct ebc_panel *plat = dev_get_platdata(dev);
194 
195 	if (plat->disp_pbuf_size == 0 || !plat->disp_pbuf) {
196 		printf("invalid display buffer, please check dts\n");
197 		return -EINVAL;
198 	}
199 	indx = ffs(logo_type);
200 	img_size = aligned_image_size_4k(dev);
201 	offset = img_size * indx;
202 	if (offset + img_size > plat->disp_pbuf_size) {
203 		printf("reserve display memory size is not enough\n");
204 		return -EINVAL;
205 	}
206 
207 	switch (logo_type) {
208 	case EINK_LOGO_RESET:
209 	case EINK_LOGO_UBOOT:
210 	case EINK_LOGO_KERNEL:
211 	case EINK_LOGO_CHARGING_0:
212 	case EINK_LOGO_CHARGING_1:
213 	case EINK_LOGO_CHARGING_2:
214 	case EINK_LOGO_CHARGING_3:
215 	case EINK_LOGO_CHARGING_4:
216 	case EINK_LOGO_CHARGING_5:
217 	case EINK_LOGO_CHARGING_LOWPOWER:
218 		return (plat->disp_pbuf + offset);
219 	default:
220 		printf("invalid logo type[%d]\n", logo_type);
221 	}
222 
223 	return -EINVAL;
224 }
225 
226 static int read_header(struct blk_desc *dev_desc,
227 		       disk_partition_t *part,
228 		       struct logo_info *header)
229 {
230 	int i;
231 	struct logo_part_header *part_hdr = &header->part_hdr;
232 
233 	if (blk_dread(dev_desc, part->start, 1, header) != 1)
234 		return -EIO;
235 
236 	if (memcmp(part_hdr->magic, EINK_LOGO_PART_MAGIC, 4)) {
237 		printf("partition header is invalid\n");
238 		return -EINVAL;
239 	}
240 	if (part_hdr->logo_count == 0) {
241 		printf("the count of logo image is 0\n");
242 		return -EINVAL;
243 	}
244 	for (i = 0; i < part_hdr->logo_count; i++) {
245 		struct grayscale_header *img_hdr = &header->img_hdr[i];
246 
247 		if (memcmp(img_hdr->magic, EINK_LOGO_IMAGE_MAGIC, 4)) {
248 			printf("image[%d] header '%s' is invalid\n", i,
249 			       img_hdr->magic);
250 			return -EINVAL;
251 		}
252 	}
253 
254 	return 0;
255 }
256 
257 static int read_grayscale(struct blk_desc *dev_desc,
258 			  disk_partition_t *part, u32 offset,
259 			  u32 size, void *buf)
260 {
261 	u32 blk_start, blk_offset, blk_count;
262 
263 	blk_offset = DIV_ROUND_UP(offset, dev_desc->blksz);
264 	blk_start = part->start + blk_offset;
265 	blk_count = DIV_ROUND_UP(size, dev_desc->blksz);
266 
267 	debug("blk_offset=%d, blk_start=%d,blk_count=%d,out buf=%p\n",
268 	      blk_offset, blk_start, blk_count, buf);
269 	if (blk_dread(dev_desc, blk_start, blk_count, buf) != blk_count) {
270 		printf("read grayscale data failed\n");
271 		return -EIO;
272 	}
273 
274 	return 0;
275 }
276 
277 /*
278  * The eink kernel driver need last frame to do part refresh,
279  * so we need to transfer two images to kernel, which is kernel
280  * logo and the logo displayed in uboot.
281  *
282  * this function use logo type bitmap to indicate several logo.
283  * u32 needed_logo: we only load needed logo image into ram, such as
284  *                   uboot logo + kernel logo or charger logo + kernel
285  *                   logo
286  * u32 *loaded_logo: because the needed logo may not exist in logo.img,
287  *                  store the really loaded logo in para loaded_logo.
288  */
289 static int read_needed_logo_from_partition(struct udevice *dev,
290 					   u32 needed_logo,
291 					   u32 *loaded_logo)
292 {
293 	int ret, i;
294 	disk_partition_t part;
295 	struct blk_desc *dev_desc;
296 	struct logo_info *hdr = &eink_logo_info;
297 	struct logo_part_header *part_hdr = &hdr->part_hdr;
298 	struct ebc_panel *panel = dev_get_platdata(dev);
299 
300 	if (*loaded_logo & needed_logo) {
301 		printf("logo[0x%x] is already loaded, just return!\n",
302 		       needed_logo);
303 		return 0;
304 	}
305 	dev_desc = rockchip_get_bootdev();
306 	if (!dev_desc) {
307 		printf("%s: Could not find device\n", __func__);
308 		return -EIO;
309 	}
310 
311 	if (part_get_info_by_name(dev_desc, PART_LOGO, &part) < 0)
312 		return -ENODEV;
313 
314 	ret = read_header(dev_desc, &part, hdr);
315 	if (ret < 0) {
316 		printf("eink logo read header failed,ret = %d\n", ret);
317 		return -EINVAL;
318 	}
319 	if (part_hdr->screen_width != panel->vir_width ||
320 	    part_hdr->screen_height != panel->vir_height){
321 		printf("logo size(%dx%d) is not same as screen size(%dx%d)\n",
322 		       part_hdr->screen_width, part_hdr->screen_height,
323 			panel->vir_width, panel->vir_height);
324 		return -EINVAL;
325 	}
326 
327 	for (i = 0; i < part_hdr->logo_count; i++) {
328 		struct grayscale_header *img_hdr = &hdr->img_hdr[i];
329 		int pic_buf;
330 		u32 offset = img_hdr->data_offset;
331 		u32 size = img_hdr->data_size;
332 		u32 logo_type = img_hdr->logo_type;
333 
334 		debug("offset=0x%x, size=%d,logo_type=%d,w=%d,h=%d\n",
335 		      offset, size, logo_type, img_hdr->w, img_hdr->h);
336 
337 		if (needed_logo & logo_type) {
338 			pic_buf = get_addr_by_type(dev, logo_type);
339 
340 			if (pic_buf <= 0) {
341 				printf("Get buffer failed for image %d\n",
342 				       img_hdr->logo_type);
343 				return -EIO;
344 			}
345 			if (!IS_ALIGNED((ulong)pic_buf,
346 					ARCH_DMA_MINALIGN)) {
347 				printf("disp buffer is not dma aligned\n");
348 				return -EINVAL;
349 			}
350 			read_grayscale(dev_desc, &part, offset, size,
351 				       (void *)((ulong)pic_buf));
352 			flush_dcache_range((ulong)pic_buf,
353 					   ALIGN((ulong)pic_buf + size,
354 						 CONFIG_SYS_CACHELINE_SIZE));
355 			*loaded_logo |= logo_type;
356 		}
357 	}
358 
359 	return 0;
360 }
361 
362 static int ebc_power_set(struct udevice *dev, int is_on)
363 {
364 	int ret;
365 	struct rockchip_eink_display_priv *priv = dev_get_priv(dev);
366 	struct ebc_panel *panel = dev_get_platdata(dev);
367 	struct udevice *ebc_tcon_dev = priv->ebc_tcon_dev;
368 	struct rk_ebc_tcon_ops *ebc_tcon_ops = ebc_tcon_get_ops(ebc_tcon_dev);
369 	struct udevice *ebc_pwr_dev = priv->ebc_pwr_dev;
370 	struct rk_ebc_pwr_ops *pwr_ops = ebc_pwr_get_ops(ebc_pwr_dev);
371 
372 	if (is_on) {
373 		ret = ebc_tcon_ops->enable(ebc_tcon_dev, panel);
374 		if (ret) {
375 			printf("%s, ebc tcon enabled failed\n", __func__);
376 			return -1;
377 		}
378 		ret = pwr_ops->power_on(ebc_pwr_dev);
379 		if (ret) {
380 			printf("%s, power on failed\n", __func__);
381 			return -1;
382 		}
383 	} else {
384 		ret = pwr_ops->power_down(ebc_pwr_dev);
385 		if (ret) {
386 			printf("%s, power_down failed\n", __func__);
387 			return -1;
388 		}
389 		ret = ebc_tcon_ops->disable(ebc_tcon_dev);
390 		if (ret) {
391 			printf("%s, ebc tcon disable failed\n", __func__);
392 			return -1;
393 		}
394 	}
395 	return 0;
396 }
397 
398 static int eink_display(struct udevice *dev, u32 pre_img_buf,
399 			u32 cur_img_buf, u32 lut_type, int update_mode)
400 {
401 	u32 temperature, frame_num;
402 	struct rockchip_eink_display_priv *priv = dev_get_priv(dev);
403 	struct ebc_panel *plat = dev_get_platdata(dev);
404 	struct epd_lut_ops *lut_ops = &plat->lut_ops;
405 	struct udevice *ebc_pwr_dev = priv->ebc_pwr_dev;
406 	struct rk_ebc_pwr_ops *pwr_ops = ebc_pwr_get_ops(ebc_pwr_dev);
407 	struct udevice *ebc_tcon_dev = priv->ebc_tcon_dev;
408 	struct rk_ebc_tcon_ops *ebc_tcon_ops = ebc_tcon_get_ops(ebc_tcon_dev);
409 
410 	pwr_ops->temp_get(ebc_pwr_dev, &temperature);
411 	if (temperature <= 0 || temperature > 50) {
412 		printf("temperature = %d, out of range0~50 ,use 25\n",
413 		       temperature);
414 		temperature = 25;
415 	}
416 
417 	if (!lut_ops->lut_get) {
418 		printf("get lut ops failed\n");
419 		return -EIO;
420 	}
421 	lut_ops->lut_get(&plat->lut_data, lut_type, temperature);
422 	frame_num = plat->lut_data.frame_num;
423 	debug("lut_type=%d, frame num=%d, temp=%d\n", lut_type,
424 	      frame_num, temperature);
425 
426 	ebc_tcon_ops->lut_data_set(ebc_tcon_dev, plat->lut_data.data,
427 				   frame_num, 0);
428 	ebc_tcon_ops->dsp_mode_set(ebc_tcon_dev, update_mode,
429 				   LUT_MODE, !THREE_WIN_MODE, !EINK_MODE);
430 	ebc_tcon_ops->image_addr_set(ebc_tcon_dev, pre_img_buf, cur_img_buf);
431 	ebc_tcon_ops->frame_start(ebc_tcon_dev, frame_num);
432 	ebc_tcon_ops->wait_for_last_frame_complete(ebc_tcon_dev);
433 
434 	return 0;
435 }
436 
437 static int rk_eink_display_init(void)
438 {
439 	int ret;
440 	struct uclass *uc;
441 	struct udevice *dev;
442 
443 	if (eink_dev) {
444 		printf("ebc-dev is already initialized!\n");
445 		return 0;
446 	}
447 
448 	ret = uclass_get(UCLASS_EINK_DISPLAY, &uc);
449 	if (ret) {
450 		printf("can't find uclass eink\n");
451 		return -ENODEV;
452 	}
453 	for (uclass_first_device(UCLASS_EINK_DISPLAY, &dev);
454 	     dev; uclass_next_device(&dev))
455 		;
456 
457 	if (eink_dev) {
458 		printf("ebc-dev is probed success!\n");
459 		return 0;
460 	}
461 	printf("Can't find ebc-dev\n");
462 	return -ENODEV;
463 }
464 
465 /*
466  * Eink display need current and previous image buffer, We assume
467  * every type of logo has only one image, so just tell this function
468  * last logo type and current logo type, it will find the right images.
469  * last_logo_type: -1 means it's first displaying.
470  */
471 static int rockchip_eink_show_logo(int cur_logo_type, int update_mode)
472 {
473 	int ret = 0;
474 	u32 logo_addr;
475 	u32 last_logo_addr;
476 	struct ebc_panel *plat;
477 	struct udevice *dev;
478 	static u32 loaded_logo;
479 	struct rockchip_eink_display_priv *priv;
480 
481 	if (!eink_dev) {
482 		static bool first_init = true;
483 
484 		if (first_init) {
485 			first_init = false;
486 			ret = rk_eink_display_init();
487 			if (ret) {
488 				printf("Get ebc dev failed, check dts\n");
489 				return -ENODEV;
490 			}
491 		} else {
492 			return -ENODEV;
493 		}
494 	}
495 	dev = eink_dev;
496 
497 	/*Don't need to update display*/
498 	if (last_logo_type == cur_logo_type) {
499 		debug("Same as last picture, Don't need to display\n");
500 		return 0;
501 	}
502 
503 	plat = dev_get_platdata(dev);
504 	priv = dev_get_priv(dev);
505 
506 	ret = ebc_power_set(dev, EBC_PWR_ON);
507 	if (ret) {
508 		printf("Eink power on failed\n");
509 		return -1;
510 	}
511 	/*
512 	 * The last_logo_type is -1 means it's first displaying
513 	 */
514 	if (last_logo_type == -1) {
515 		int size = (plat->vir_width * plat->vir_height) >> 1;
516 
517 		logo_addr = get_addr_by_type(dev, EINK_LOGO_RESET);
518 		memset((u32 *)(u64)logo_addr, 0xff, size);
519 		eink_display(dev, logo_addr, logo_addr,
520 			     WF_TYPE_RESET, 0);
521 		last_logo_type = 0;
522 		last_logo_addr = logo_addr;
523 	} else {
524 		last_logo_addr = get_addr_by_type(dev, last_logo_type);
525 		if (last_logo_addr < 0) {
526 			printf("Invalid last logo addr, exit!\n");
527 			goto out;
528 		}
529 		if (cur_logo_type == EINK_LOGO_RESET) {
530 			logo_addr = get_addr_by_type(dev, EINK_LOGO_RESET);
531 			eink_display(dev, last_logo_addr,
532 				     logo_addr,
533 				     WF_TYPE_GC16, update_mode);
534 			last_logo_type = -1;
535 			goto out;
536 		}
537 	}
538 	ret = read_needed_logo_from_partition(dev, cur_logo_type,
539 					      &loaded_logo);
540 	if (ret || !(loaded_logo & cur_logo_type)) {
541 		printf("read logo[0x%x] failed, loaded_logo=0x%x\n",
542 		       cur_logo_type, loaded_logo);
543 		ret = -EIO;
544 		goto out;
545 	}
546 	logo_addr = get_addr_by_type(dev, cur_logo_type);
547 	debug("logo_addr=%x, logo_type=%d\n", logo_addr, cur_logo_type);
548 	if (logo_addr <= 0) {
549 		printf("get logo buffer failed\n");
550 		ret = -EIO;
551 		goto out;
552 	}
553 
554 	eink_display(dev, last_logo_addr, logo_addr, WF_TYPE_GC16, update_mode);
555 
556 	if (priv->backlight)
557 		backlight_enable(priv->backlight);
558 
559 	last_logo_type = cur_logo_type;
560 	/*
561 	 * System will boot up to kernel only when the
562 	 * logo is uboot logo
563 	 */
564 	if (cur_logo_type == EINK_LOGO_UBOOT) {
565 		char logo_args[64] = {0};
566 
567 		printf("Transmit uboot logo addr(0x%x) to kernel\n", logo_addr);
568 		sprintf(logo_args, "ulogo_addr=0x%x", logo_addr);
569 		env_update("bootargs", logo_args);
570 		ret = read_needed_logo_from_partition(dev, EINK_LOGO_KERNEL,
571 						      &loaded_logo);
572 		if (ret || !(loaded_logo & EINK_LOGO_KERNEL)) {
573 			printf("No invalid kernel logo in logo.img\n");
574 		} else {
575 			int klogo_addr = get_addr_by_type(dev,
576 							  EINK_LOGO_KERNEL);
577 
578 			if (klogo_addr <= 0) {
579 				printf("get kernel logo buffer failed\n");
580 				ret = -EIO;
581 				goto out;
582 			}
583 			printf("Transmit kernel logo addr(0x%x) to kernel\n",
584 			       klogo_addr);
585 			sprintf(logo_args, "klogo_addr=0x%x", klogo_addr);
586 			env_update("bootargs", logo_args);
587 		}
588 	}
589 
590 out:
591 	ret = ebc_power_set(dev, EBC_PWR_DOWN);
592 	if (ret)
593 		printf("Eink power down failed\n");
594 	return ret;
595 }
596 
597 int rockchip_eink_show_uboot_logo(void)
598 {
599 	return rockchip_eink_show_logo(EINK_LOGO_UBOOT, EINK_UPDATE_DIFF);
600 }
601 
602 int rockchip_eink_show_charge_logo(int logo_type)
603 {
604 	return rockchip_eink_show_logo(logo_type, EINK_UPDATE_DIFF);
605 }
606 
607 static int rockchip_eink_display_probe(struct udevice *dev)
608 {
609 	int ret, vcom;
610 	struct rockchip_eink_display_priv *priv = dev_get_priv(dev);
611 
612 	/* Before relocation we don't need to do anything */
613 	if (!(gd->flags & GD_FLG_RELOC))
614 		return 0;
615 
616 	ret = uclass_get_device_by_phandle(UCLASS_EBC, dev,
617 					   "ebc_tcon",
618 					   &priv->ebc_tcon_dev);
619 	if (ret) {
620 		dev_err(dev, "Cannot get ebc_tcon: %d\n", ret);
621 		return ret;
622 	}
623 
624 	ret = uclass_get_device_by_phandle(UCLASS_I2C_GENERIC, dev,
625 					   "pmic",
626 					   &priv->ebc_pwr_dev);
627 	if (ret) {
628 		dev_err(dev, "Cannot get pmic: %d\n", ret);
629 		return ret;
630 	}
631 
632 	ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev,
633 					   "backlight", &priv->backlight);
634 	if (ret && ret != -ENOENT) {
635 		printf("%s: Cannot get backlight: %d\n", __func__, ret);
636 	}
637 
638 	vcom = read_vcom_from_vendor();
639 	if (vcom <= 0) {
640 		printf("read vcom from vendor failed, use default vcom\n");
641 		priv->vcom = VCOM_DEFAULT_VALUE;
642 	} else {
643 		priv->vcom = vcom;
644 	}
645 
646 	if (priv->ebc_pwr_dev) {
647 		struct rk_ebc_pwr_ops *pwr_ops;
648 
649 		pwr_ops = ebc_pwr_get_ops(priv->ebc_pwr_dev);
650 		ret = pwr_ops->vcom_set(priv->ebc_pwr_dev, priv->vcom);
651 		if (ret) {
652 			printf("%s, vcom_set failed\n", __func__);
653 			return -EIO;
654 		}
655 	}
656 
657 	// read lut to ram, and get lut ops
658 	ret = read_waveform(dev);
659 	if (ret < 0) {
660 		printf("read wavform failed\n");
661 		return -EIO;
662 	}
663 
664 	eink_dev = dev;
665 
666 	return 0;
667 }
668 
669 static int rockchip_eink_display_ofdata_to_platdata(struct udevice *dev)
670 {
671 	fdt_size_t size;
672 	fdt_addr_t tmp_addr;
673 	struct device_node *disp_mem;
674 	struct device_node *waveform_mem;
675 	struct ebc_panel *plat = dev_get_platdata(dev);
676 
677 	plat->width = dev_read_u32_default(dev, "panel,width", 0);
678 	plat->height = dev_read_u32_default(dev, "panel,height", 0);
679 	plat->vir_width = dev_read_u32_default(dev, "panel,vir_width", plat->width);
680 	plat->vir_height = dev_read_u32_default(dev, "panel,vir_height", plat->height);
681 	plat->sdck = dev_read_u32_default(dev, "panel,sdck", 0);
682 	plat->lsl = dev_read_u32_default(dev, "panel,lsl", 0);
683 	plat->lbl = dev_read_u32_default(dev, "panel,lbl", 0);
684 	plat->ldl = dev_read_u32_default(dev, "panel,ldl", 0);
685 	plat->lel = dev_read_u32_default(dev, "panel,lel", 0);
686 	plat->gdck_sta = dev_read_u32_default(dev, "panel,gdck-sta", 0);
687 	plat->lgonl = dev_read_u32_default(dev, "panel,lgonl", 0);
688 	plat->fsl = dev_read_u32_default(dev, "panel,fsl", 0);
689 	plat->fbl = dev_read_u32_default(dev, "panel,fbl", 0);
690 	plat->fdl = dev_read_u32_default(dev, "panel,fdl", 0);
691 	plat->fel = dev_read_u32_default(dev, "panel,fel", 0);
692 	plat->panel_16bit = dev_read_u32_default(dev, "panel,panel_16bit", 0);
693 	plat->panel_color = dev_read_u32_default(dev, "panel,panel_color", 0);
694 	plat->mirror = dev_read_u32_default(dev, "panel,mirror", 0);
695 	plat->width_mm = dev_read_u32_default(dev, "panel,width-mm", 0);
696 	plat->height_mm = dev_read_u32_default(dev, "panel,height-mm", 0);
697 
698 	disp_mem = of_parse_phandle(ofnode_to_np(dev_ofnode(dev)),
699 				    "memory-region", 0);
700 	if (!disp_mem) {
701 		dev_err(dev, "Cannot get memory-region from dts\n");
702 		return -ENODEV;
703 	}
704 	tmp_addr = ofnode_get_addr_size(np_to_ofnode(disp_mem), "reg", &size);
705 	if (tmp_addr == FDT_ADDR_T_NONE) {
706 		printf("get display memory address failed\n");
707 		return -ENODEV;
708 	}
709 
710 	plat->disp_pbuf = (u64)map_sysmem(tmp_addr, 0);
711 	plat->disp_pbuf_size = size;
712 	debug("display mem=0x%x, size=%x\n", plat->disp_pbuf,
713 	      plat->disp_pbuf_size);
714 	waveform_mem = of_parse_phandle(ofnode_to_np(dev_ofnode(dev)),
715 					"waveform-region", 0);
716 	if (!waveform_mem) {
717 		printf("Cannot get waveform-region from dts\n");
718 		return -ENODEV;
719 	}
720 	tmp_addr = ofnode_get_addr_size(np_to_ofnode(waveform_mem),
721 					"reg", &size);
722 	if (tmp_addr == FDT_ADDR_T_NONE) {
723 		printf("get waveform memory address failed\n");
724 		return -ENODEV;
725 	}
726 
727 	plat->lut_pbuf = map_sysmem(tmp_addr, 0);
728 	plat->lut_pbuf_size = size;
729 	debug("lut mem=0x%p, size=%x\n", plat->lut_pbuf, plat->lut_pbuf_size);
730 	return 0;
731 }
732 
733 static const struct udevice_id rockchip_eink_display_ids[] = {
734 	{ .compatible = "rockchip,ebc-dev", },
735 	{}
736 };
737 
738 U_BOOT_DRIVER(rk_eink_display) = {
739 	.name = "rockchip_eink_display",
740 	.id = UCLASS_EINK_DISPLAY,
741 	.of_match = rockchip_eink_display_ids,
742 	.ofdata_to_platdata = rockchip_eink_display_ofdata_to_platdata,
743 	.probe = rockchip_eink_display_probe,
744 	.priv_auto_alloc_size = sizeof(struct rockchip_eink_display_priv),
745 	.platdata_auto_alloc_size = sizeof(struct ebc_panel),
746 };
747 
748 UCLASS_DRIVER(rk_eink) = {
749 	.id	= UCLASS_EINK_DISPLAY,
750 	.name	= "rk_eink",
751 };
752 
753