1 /* 2 * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <config.h> 8 #include <common.h> 9 #include <errno.h> 10 #include <malloc.h> 11 #include <video.h> 12 #include <backlight.h> 13 #include <asm/gpio.h> 14 #include <dm/device.h> 15 #include <dm/read.h> 16 #include <dm/uclass.h> 17 #include <dm/uclass-id.h> 18 #include <linux/media-bus-format.h> 19 #include <power/regulator.h> 20 21 #include "rockchip_display.h" 22 #include "rockchip_crtc.h" 23 #include "rockchip_connector.h" 24 #include "rockchip_mipi_dsi.h" 25 #include "rockchip_panel.h" 26 27 struct rockchip_cmd_header { 28 u8 data_type; 29 u8 delay_ms; 30 u8 payload_length; 31 } __packed; 32 33 struct rockchip_cmd_desc { 34 struct rockchip_cmd_header header; 35 const u8 *payload; 36 }; 37 38 struct rockchip_panel_cmds { 39 struct rockchip_cmd_desc *cmds; 40 int cmd_cnt; 41 }; 42 43 struct rockchip_panel_plat { 44 bool power_invert; 45 u32 bus_format; 46 47 struct { 48 unsigned int prepare; 49 unsigned int unprepare; 50 unsigned int enable; 51 unsigned int disable; 52 unsigned int reset; 53 unsigned int init; 54 } delay; 55 56 struct rockchip_panel_cmds *on_cmds; 57 struct rockchip_panel_cmds *off_cmds; 58 }; 59 60 struct rockchip_panel_priv { 61 bool prepared; 62 bool enabled; 63 struct udevice *power_supply; 64 struct udevice *backlight; 65 struct gpio_desc enable_gpio; 66 struct gpio_desc reset_gpio; 67 68 int cmd_type; 69 struct gpio_desc spi_sdi_gpio; 70 struct gpio_desc spi_scl_gpio; 71 struct gpio_desc spi_cs_gpio; 72 }; 73 74 static inline int get_panel_cmd_type(const char *s) 75 { 76 if (!s) 77 return -EINVAL; 78 79 if (strncmp(s, "spi", 3) == 0) 80 return CMD_TYPE_SPI; 81 else if (strncmp(s, "mcu", 3) == 0) 82 return CMD_TYPE_MCU; 83 84 return CMD_TYPE_DEFAULT; 85 } 86 87 static int rockchip_panel_parse_cmds(const u8 *data, int length, 88 struct rockchip_panel_cmds *pcmds) 89 { 90 int len; 91 const u8 *buf; 92 const struct rockchip_cmd_header *header; 93 int i, cnt = 0; 94 95 /* scan commands */ 96 cnt = 0; 97 buf = data; 98 len = length; 99 while (len > sizeof(*header)) { 100 header = (const struct rockchip_cmd_header *)buf; 101 buf += sizeof(*header) + header->payload_length; 102 len -= sizeof(*header) + header->payload_length; 103 cnt++; 104 } 105 106 pcmds->cmds = calloc(cnt, sizeof(struct rockchip_cmd_desc)); 107 if (!pcmds->cmds) 108 return -ENOMEM; 109 110 pcmds->cmd_cnt = cnt; 111 112 buf = data; 113 len = length; 114 for (i = 0; i < cnt; i++) { 115 struct rockchip_cmd_desc *desc = &pcmds->cmds[i]; 116 117 header = (const struct rockchip_cmd_header *)buf; 118 length -= sizeof(*header); 119 buf += sizeof(*header); 120 desc->header.data_type = header->data_type; 121 desc->header.delay_ms = header->delay_ms; 122 desc->header.payload_length = header->payload_length; 123 desc->payload = buf; 124 buf += header->payload_length; 125 length -= header->payload_length; 126 } 127 128 return 0; 129 } 130 131 static void rockchip_panel_write_spi_cmds(struct rockchip_panel_priv *priv, 132 u8 type, int value) 133 { 134 int i; 135 136 dm_gpio_set_value(&priv->spi_cs_gpio, 0); 137 138 if (type == 0) 139 value &= (~(1 << 8)); 140 else 141 value |= (1 << 8); 142 143 for (i = 0; i < 9; i++) { 144 if (value & 0x100) 145 dm_gpio_set_value(&priv->spi_sdi_gpio, 1); 146 else 147 dm_gpio_set_value(&priv->spi_sdi_gpio, 0); 148 149 dm_gpio_set_value(&priv->spi_scl_gpio, 0); 150 udelay(10); 151 dm_gpio_set_value(&priv->spi_scl_gpio, 1); 152 value <<= 1; 153 udelay(10); 154 } 155 156 dm_gpio_set_value(&priv->spi_cs_gpio, 1); 157 } 158 159 static int rockchip_panel_send_mcu_cmds(struct display_state *state, 160 struct rockchip_panel_cmds *cmds) 161 { 162 int i; 163 164 if (!cmds) 165 return -EINVAL; 166 167 display_send_mcu_cmd(state, MCU_SETBYPASS, 1); 168 for (i = 0; i < cmds->cmd_cnt; i++) { 169 struct rockchip_cmd_desc *desc = &cmds->cmds[i]; 170 int value = 0; 171 172 value = desc->payload[0]; 173 display_send_mcu_cmd(state, desc->header.data_type, value); 174 175 if (desc->header.delay_ms) 176 mdelay(desc->header.delay_ms); 177 } 178 display_send_mcu_cmd(state, MCU_SETBYPASS, 0); 179 180 return 0; 181 } 182 183 static int rockchip_panel_send_spi_cmds(struct display_state *state, 184 struct rockchip_panel_cmds *cmds) 185 { 186 struct rockchip_panel *panel = state_get_panel(state); 187 struct rockchip_panel_priv *priv = dev_get_priv(panel->dev); 188 int i; 189 190 if (!cmds) 191 return -EINVAL; 192 193 for (i = 0; i < cmds->cmd_cnt; i++) { 194 struct rockchip_cmd_desc *desc = &cmds->cmds[i]; 195 int value = 0; 196 197 if (desc->header.payload_length == 2) 198 value = (desc->payload[0] << 8) | desc->payload[1]; 199 else 200 value = desc->payload[0]; 201 rockchip_panel_write_spi_cmds(priv, 202 desc->header.data_type, value); 203 204 if (desc->header.delay_ms) 205 mdelay(desc->header.delay_ms); 206 } 207 208 return 0; 209 } 210 211 static int rockchip_panel_send_dsi_cmds(struct display_state *state, 212 struct rockchip_panel_cmds *cmds) 213 { 214 int i, ret; 215 216 if (!cmds) 217 return -EINVAL; 218 219 for (i = 0; i < cmds->cmd_cnt; i++) { 220 struct rockchip_cmd_desc *desc = &cmds->cmds[i]; 221 222 switch (desc->header.data_type) { 223 case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM: 224 case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM: 225 case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM: 226 case MIPI_DSI_GENERIC_LONG_WRITE: 227 ret = mipi_dsi_generic_write(state, desc->payload, 228 desc->header.payload_length); 229 break; 230 case MIPI_DSI_DCS_SHORT_WRITE: 231 case MIPI_DSI_DCS_SHORT_WRITE_PARAM: 232 case MIPI_DSI_DCS_LONG_WRITE: 233 ret = mipi_dsi_dcs_write(state, desc->payload, 234 desc->header.payload_length); 235 break; 236 default: 237 printf("unsupport command data type: %d\n", 238 desc->header.data_type); 239 return -EINVAL; 240 } 241 242 if (ret < 0) { 243 printf("failed to write cmd%d: %d\n", i, ret); 244 return ret; 245 } 246 247 if (desc->header.delay_ms) 248 mdelay(desc->header.delay_ms); 249 } 250 251 return 0; 252 } 253 254 static int rockchip_panel_prepare(struct display_state *state) 255 { 256 struct rockchip_panel *panel = state_get_panel(state); 257 struct rockchip_panel_plat *plat = dev_get_platdata(panel->dev); 258 struct rockchip_panel_priv *priv = dev_get_priv(panel->dev); 259 int ret; 260 261 if (priv->prepared) 262 return 0; 263 264 if (priv->power_supply) { 265 ret = regulator_set_enable(priv->power_supply, 266 !plat->power_invert); 267 if (ret) { 268 printf("%s: failed to enable power supply", __func__); 269 return ret; 270 } 271 } 272 273 dm_gpio_set_value(&priv->enable_gpio, 1); 274 mdelay(plat->delay.prepare); 275 276 dm_gpio_set_value(&priv->reset_gpio, 1); 277 mdelay(plat->delay.reset); 278 dm_gpio_set_value(&priv->reset_gpio, 0); 279 280 mdelay(plat->delay.init); 281 282 if (plat->on_cmds) { 283 if (priv->cmd_type == CMD_TYPE_SPI) 284 ret = rockchip_panel_send_spi_cmds(state, 285 plat->on_cmds); 286 else if (priv->cmd_type == CMD_TYPE_MCU) 287 ret = rockchip_panel_send_mcu_cmds(state, plat->on_cmds); 288 else 289 ret = rockchip_panel_send_dsi_cmds(state, 290 plat->on_cmds); 291 if (ret) 292 printf("failed to send on cmds: %d\n", ret); 293 } 294 295 priv->prepared = true; 296 297 return 0; 298 } 299 300 static void rockchip_panel_unprepare(struct display_state *state) 301 { 302 struct rockchip_panel *panel = state_get_panel(state); 303 struct rockchip_panel_plat *plat = dev_get_platdata(panel->dev); 304 struct rockchip_panel_priv *priv = dev_get_priv(panel->dev); 305 int ret; 306 307 if (!priv->prepared) 308 return; 309 310 if (plat->off_cmds) { 311 if (priv->cmd_type == CMD_TYPE_SPI) 312 ret = rockchip_panel_send_spi_cmds(state, 313 plat->off_cmds); 314 else if (priv->cmd_type == CMD_TYPE_MCU) 315 ret = rockchip_panel_send_mcu_cmds(state, 316 plat->off_cmds); 317 else 318 ret = rockchip_panel_send_dsi_cmds(state, 319 plat->off_cmds); 320 if (ret) 321 printf("failed to send off cmds: %d\n", ret); 322 } 323 324 dm_gpio_set_value(&priv->reset_gpio, 1); 325 dm_gpio_set_value(&priv->enable_gpio, 0); 326 327 if (priv->power_supply) { 328 ret = regulator_set_enable(priv->power_supply, 329 plat->power_invert); 330 if (ret) 331 printf("%s: failed to disable power supply", __func__); 332 } 333 334 mdelay(plat->delay.unprepare); 335 336 priv->prepared = false; 337 } 338 339 static int rockchip_panel_enable(struct display_state *state) 340 { 341 struct rockchip_panel *panel = state_get_panel(state); 342 struct rockchip_panel_plat *plat = dev_get_platdata(panel->dev); 343 struct rockchip_panel_priv *priv = dev_get_priv(panel->dev); 344 345 if (priv->enabled) 346 return 0; 347 348 mdelay(plat->delay.enable); 349 350 if (priv->backlight) 351 backlight_enable(priv->backlight); 352 353 priv->enabled = true; 354 355 return 0; 356 } 357 358 static void rockchip_panel_disable(struct display_state *state) 359 { 360 struct rockchip_panel *panel = state_get_panel(state); 361 struct rockchip_panel_plat *plat = dev_get_platdata(panel->dev); 362 struct rockchip_panel_priv *priv = dev_get_priv(panel->dev); 363 364 if (!priv->enabled) 365 return; 366 367 if (priv->backlight) 368 backlight_disable(priv->backlight); 369 370 mdelay(plat->delay.disable); 371 372 priv->enabled = false; 373 } 374 375 static int rockchip_panel_init(struct display_state *state) 376 { 377 struct connector_state *conn_state = &state->conn_state; 378 struct rockchip_panel *panel = state_get_panel(state); 379 380 conn_state->bus_format = panel->bus_format; 381 382 return 0; 383 } 384 385 static const struct rockchip_panel_funcs rockchip_panel_funcs = { 386 .init = rockchip_panel_init, 387 .prepare = rockchip_panel_prepare, 388 .unprepare = rockchip_panel_unprepare, 389 .enable = rockchip_panel_enable, 390 .disable = rockchip_panel_disable, 391 }; 392 393 static int rockchip_panel_ofdata_to_platdata(struct udevice *dev) 394 { 395 struct rockchip_panel_plat *plat = dev_get_platdata(dev); 396 const void *data; 397 int len = 0; 398 int ret; 399 400 plat->power_invert = dev_read_bool(dev, "power-invert"); 401 402 plat->delay.prepare = dev_read_u32_default(dev, "prepare-delay-ms", 0); 403 plat->delay.unprepare = dev_read_u32_default(dev, "unprepare-delay-ms", 0); 404 plat->delay.enable = dev_read_u32_default(dev, "enable-delay-ms", 0); 405 plat->delay.disable = dev_read_u32_default(dev, "disable-delay-ms", 0); 406 plat->delay.init = dev_read_u32_default(dev, "init-delay-ms", 0); 407 plat->delay.reset = dev_read_u32_default(dev, "reset-delay-ms", 0); 408 409 plat->bus_format = dev_read_u32_default(dev, "bus-format", 410 MEDIA_BUS_FMT_RBG888_1X24); 411 412 data = dev_read_prop(dev, "panel-init-sequence", &len); 413 if (data) { 414 plat->on_cmds = calloc(1, sizeof(*plat->on_cmds)); 415 if (!plat->on_cmds) 416 return -ENOMEM; 417 418 ret = rockchip_panel_parse_cmds(data, len, plat->on_cmds); 419 if (ret) { 420 printf("failed to parse panel init sequence\n"); 421 goto free_on_cmds; 422 } 423 } 424 425 data = dev_read_prop(dev, "panel-exit-sequence", &len); 426 if (data) { 427 plat->off_cmds = calloc(1, sizeof(*plat->off_cmds)); 428 if (!plat->off_cmds) { 429 ret = -ENOMEM; 430 goto free_on_cmds; 431 } 432 433 ret = rockchip_panel_parse_cmds(data, len, plat->off_cmds); 434 if (ret) { 435 printf("failed to parse panel exit sequence\n"); 436 goto free_cmds; 437 } 438 } 439 440 return 0; 441 442 free_cmds: 443 free(plat->off_cmds); 444 free_on_cmds: 445 free(plat->on_cmds); 446 return ret; 447 } 448 449 static int rockchip_panel_probe(struct udevice *dev) 450 { 451 struct rockchip_panel_priv *priv = dev_get_priv(dev); 452 struct rockchip_panel_plat *plat = dev_get_platdata(dev); 453 struct rockchip_panel *panel = 454 (struct rockchip_panel *)dev_get_driver_data(dev); 455 int ret; 456 const char *cmd_type; 457 458 ret = gpio_request_by_name(dev, "enable-gpios", 0, 459 &priv->enable_gpio, GPIOD_IS_OUT); 460 if (ret && ret != -ENOENT) { 461 printf("%s: Cannot get enable GPIO: %d\n", __func__, ret); 462 return ret; 463 } 464 465 ret = gpio_request_by_name(dev, "reset-gpios", 0, 466 &priv->reset_gpio, GPIOD_IS_OUT); 467 if (ret && ret != -ENOENT) { 468 printf("%s: Cannot get reset GPIO: %d\n", __func__, ret); 469 return ret; 470 } 471 472 ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev, 473 "backlight", &priv->backlight); 474 if (ret && ret != -ENOENT) { 475 printf("%s: Cannot get backlight: %d\n", __func__, ret); 476 return ret; 477 } 478 479 ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, 480 "power-supply", &priv->power_supply); 481 if (ret && ret != -ENOENT) { 482 printf("%s: Cannot get power supply: %d\n", __func__, ret); 483 return ret; 484 } 485 486 ret = dev_read_string_index(dev, "rockchip,cmd-type", 0, &cmd_type); 487 if (ret) 488 priv->cmd_type = CMD_TYPE_DEFAULT; 489 else 490 priv->cmd_type = get_panel_cmd_type(cmd_type); 491 492 if (priv->cmd_type == CMD_TYPE_SPI) { 493 ret = gpio_request_by_name(dev, "spi-sdi-gpios", 0, 494 &priv->spi_sdi_gpio, GPIOD_IS_OUT); 495 if (ret && ret != -ENOENT) { 496 printf("%s: Cannot get spi sdi GPIO: %d\n", 497 __func__, ret); 498 return ret; 499 } 500 ret = gpio_request_by_name(dev, "spi-scl-gpios", 0, 501 &priv->spi_scl_gpio, GPIOD_IS_OUT); 502 if (ret && ret != -ENOENT) { 503 printf("%s: Cannot get spi scl GPIO: %d\n", 504 __func__, ret); 505 return ret; 506 } 507 ret = gpio_request_by_name(dev, "spi-cs-gpios", 0, 508 &priv->spi_cs_gpio, GPIOD_IS_OUT); 509 if (ret && ret != -ENOENT) { 510 printf("%s: Cannot get spi cs GPIO: %d\n", 511 __func__, ret); 512 return ret; 513 } 514 dm_gpio_set_value(&priv->spi_sdi_gpio, 1); 515 dm_gpio_set_value(&priv->spi_scl_gpio, 1); 516 dm_gpio_set_value(&priv->spi_cs_gpio, 1); 517 dm_gpio_set_value(&priv->reset_gpio, 0); 518 } 519 520 panel->dev = dev; 521 panel->bus_format = plat->bus_format; 522 523 return 0; 524 } 525 526 static const struct drm_display_mode auo_b125han03_mode = { 527 .clock = 146900, 528 .hdisplay = 1920, 529 .hsync_start = 1920 + 48, 530 .hsync_end = 1920 + 48 + 32, 531 .htotal = 1920 + 48 + 32 + 140, 532 .vdisplay = 1080, 533 .vsync_start = 1080 + 2, 534 .vsync_end = 1080 + 2 + 5, 535 .vtotal = 1080 + 2 + 5 + 57, 536 .vrefresh = 60, 537 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, 538 }; 539 540 static const struct rockchip_panel auo_b125han03_driver_data = { 541 .funcs = &rockchip_panel_funcs, 542 .data = &auo_b125han03_mode, 543 }; 544 545 static const struct drm_display_mode lg_lp079qx1_sp0v_mode = { 546 .clock = 200000, 547 .hdisplay = 1536, 548 .hsync_start = 1536 + 12, 549 .hsync_end = 1536 + 12 + 16, 550 .htotal = 1536 + 12 + 16 + 48, 551 .vdisplay = 2048, 552 .vsync_start = 2048 + 8, 553 .vsync_end = 2048 + 8 + 4, 554 .vtotal = 2048 + 8 + 4 + 8, 555 .vrefresh = 60, 556 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, 557 }; 558 559 static const struct rockchip_panel lg_lp079qx1_sp0v_driver_data = { 560 .funcs = &rockchip_panel_funcs, 561 .data = &lg_lp079qx1_sp0v_mode, 562 }; 563 564 static const struct rockchip_panel panel_simple_driver_data = { 565 .funcs = &rockchip_panel_funcs, 566 }; 567 568 static const struct rockchip_panel panel_simple_dsi_driver_data = { 569 .funcs = &rockchip_panel_funcs, 570 }; 571 572 static const struct udevice_id rockchip_panel_ids[] = { 573 { 574 .compatible = "auo,b125han03", 575 .data = (ulong)&auo_b125han03_driver_data, 576 }, { 577 .compatible = "lg,lp079qx1-sp0v", 578 .data = (ulong)&lg_lp079qx1_sp0v_driver_data, 579 }, { 580 .compatible = "simple-panel", 581 .data = (ulong)&panel_simple_driver_data, 582 }, { 583 .compatible = "simple-panel-dsi", 584 .data = (ulong)&panel_simple_dsi_driver_data, 585 }, 586 {} 587 }; 588 589 U_BOOT_DRIVER(rockchip_panel) = { 590 .name = "rockchip_panel", 591 .id = UCLASS_PANEL, 592 .of_match = rockchip_panel_ids, 593 .ofdata_to_platdata = rockchip_panel_ofdata_to_platdata, 594 .probe = rockchip_panel_probe, 595 .priv_auto_alloc_size = sizeof(struct rockchip_panel_priv), 596 .platdata_auto_alloc_size = sizeof(struct rockchip_panel_plat), 597 }; 598