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