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