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