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