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 panel_state *panel_state = &state->panel_state; 187 struct rockchip_panel_priv *priv = dev_get_priv(panel_state->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 panel_state *panel_state = &state->panel_state; 257 struct rockchip_panel_plat *plat = dev_get_platdata(panel_state->dev); 258 struct rockchip_panel_priv *priv = dev_get_priv(panel_state->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 panel_state *panel_state = &state->panel_state; 303 struct rockchip_panel_plat *plat = dev_get_platdata(panel_state->dev); 304 struct rockchip_panel_priv *priv = dev_get_priv(panel_state->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 panel_state *panel_state = &state->panel_state; 342 struct rockchip_panel_plat *plat = dev_get_platdata(panel_state->dev); 343 struct rockchip_panel_priv *priv = dev_get_priv(panel_state->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 panel_state *panel_state = &state->panel_state; 361 struct rockchip_panel_plat *plat = dev_get_platdata(panel_state->dev); 362 struct rockchip_panel_priv *priv = dev_get_priv(panel_state->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 panel_state *panel_state = &state->panel_state; 379 struct rockchip_panel_plat *plat = dev_get_platdata(panel_state->dev); 380 381 conn_state->bus_format = plat->bus_format; 382 383 return 0; 384 } 385 386 static const struct rockchip_panel_funcs rockchip_panel_funcs = { 387 .init = rockchip_panel_init, 388 .prepare = rockchip_panel_prepare, 389 .unprepare = rockchip_panel_unprepare, 390 .enable = rockchip_panel_enable, 391 .disable = rockchip_panel_disable, 392 }; 393 394 static int rockchip_panel_ofdata_to_platdata(struct udevice *dev) 395 { 396 struct rockchip_panel_plat *plat = dev_get_platdata(dev); 397 const void *data; 398 int len = 0; 399 int ret; 400 401 plat->power_invert = dev_read_bool(dev, "power-invert"); 402 403 plat->delay.prepare = dev_read_u32_default(dev, "prepare-delay-ms", 0); 404 plat->delay.unprepare = dev_read_u32_default(dev, "unprepare-delay-ms", 0); 405 plat->delay.enable = dev_read_u32_default(dev, "enable-delay-ms", 0); 406 plat->delay.disable = dev_read_u32_default(dev, "disable-delay-ms", 0); 407 plat->delay.init = dev_read_u32_default(dev, "init-delay-ms", 0); 408 plat->delay.reset = dev_read_u32_default(dev, "reset-delay-ms", 0); 409 410 plat->bus_format = dev_read_u32_default(dev, "bus-format", 411 MEDIA_BUS_FMT_RBG888_1X24); 412 413 data = dev_read_prop(dev, "panel-init-sequence", &len); 414 if (data) { 415 plat->on_cmds = calloc(1, sizeof(*plat->on_cmds)); 416 if (!plat->on_cmds) 417 return -ENOMEM; 418 419 ret = rockchip_panel_parse_cmds(data, len, plat->on_cmds); 420 if (ret) { 421 printf("failed to parse panel init sequence\n"); 422 goto free_on_cmds; 423 } 424 } 425 426 data = dev_read_prop(dev, "panel-exit-sequence", &len); 427 if (data) { 428 plat->off_cmds = calloc(1, sizeof(*plat->off_cmds)); 429 if (!plat->off_cmds) { 430 ret = -ENOMEM; 431 goto free_on_cmds; 432 } 433 434 ret = rockchip_panel_parse_cmds(data, len, plat->off_cmds); 435 if (ret) { 436 printf("failed to parse panel exit sequence\n"); 437 goto free_cmds; 438 } 439 } 440 441 return 0; 442 443 free_cmds: 444 free(plat->off_cmds); 445 free_on_cmds: 446 free(plat->on_cmds); 447 return ret; 448 } 449 450 static int rockchip_panel_probe(struct udevice *dev) 451 { 452 struct rockchip_panel_priv *priv = dev_get_priv(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 return 0; 519 } 520 521 static const struct drm_display_mode auo_b125han03_mode = { 522 .clock = 146900, 523 .hdisplay = 1920, 524 .hsync_start = 1920 + 48, 525 .hsync_end = 1920 + 48 + 32, 526 .htotal = 1920 + 48 + 32 + 140, 527 .vdisplay = 1080, 528 .vsync_start = 1080 + 2, 529 .vsync_end = 1080 + 2 + 5, 530 .vtotal = 1080 + 2 + 5 + 57, 531 .vrefresh = 60, 532 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, 533 }; 534 535 static const struct rockchip_panel auo_b125han03_data = { 536 .funcs = &rockchip_panel_funcs, 537 .data = &auo_b125han03_mode, 538 }; 539 540 static const struct drm_display_mode lg_lp079qx1_sp0v_mode = { 541 .clock = 200000, 542 .hdisplay = 1536, 543 .hsync_start = 1536 + 12, 544 .hsync_end = 1536 + 12 + 16, 545 .htotal = 1536 + 12 + 16 + 48, 546 .vdisplay = 2048, 547 .vsync_start = 2048 + 8, 548 .vsync_end = 2048 + 8 + 4, 549 .vtotal = 2048 + 8 + 4 + 8, 550 .vrefresh = 60, 551 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, 552 }; 553 554 static const struct rockchip_panel lg_lp079qx1_sp0v_data = { 555 .funcs = &rockchip_panel_funcs, 556 .data = &lg_lp079qx1_sp0v_mode, 557 }; 558 559 static const struct rockchip_panel rockchip_panel_data = { 560 .funcs = &rockchip_panel_funcs, 561 }; 562 563 static const struct udevice_id rockchip_panel_ids[] = { 564 { 565 .compatible = "auo,b125han03", 566 .data = (ulong)&auo_b125han03_data, 567 }, { 568 .compatible = "lg,lp079qx1-sp0v", 569 .data = (ulong)&lg_lp079qx1_sp0v_data, 570 }, { 571 .compatible = "simple-panel", 572 .data = (ulong)&rockchip_panel_data, 573 }, { 574 .compatible = "simple-panel-dsi", 575 .data = (ulong)&rockchip_panel_data, 576 }, 577 {} 578 }; 579 580 U_BOOT_DRIVER(rockchip_panel) = { 581 .name = "rockchip_panel", 582 .id = UCLASS_PANEL, 583 .of_match = rockchip_panel_ids, 584 .ofdata_to_platdata = rockchip_panel_ofdata_to_platdata, 585 .probe = rockchip_panel_probe, 586 .priv_auto_alloc_size = sizeof(struct rockchip_panel_priv), 587 .platdata_auto_alloc_size = sizeof(struct rockchip_panel_plat), 588 }; 589