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