1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Generic DSI Command Mode panel driver 4 * 5 * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com/ 6 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> 7 */ 8 9 #include <linux/backlight.h> 10 #include <linux/delay.h> 11 #include <linux/gpio/consumer.h> 12 #include <linux/jiffies.h> 13 #include <linux/module.h> 14 #include <linux/of_device.h> 15 #include <linux/regulator/consumer.h> 16 17 #include <drm/drm_connector.h> 18 #include <drm/drm_mipi_dsi.h> 19 #include <drm/drm_modes.h> 20 #include <drm/drm_panel.h> 21 22 #include <video/mipi_display.h> 23 24 #define DCS_GET_ID1 0xda 25 #define DCS_GET_ID2 0xdb 26 #define DCS_GET_ID3 0xdc 27 28 #define DCS_REGULATOR_SUPPLY_NUM 2 29 30 static const struct of_device_id dsicm_of_match[]; 31 32 struct dsic_panel_data { 33 u32 xres; 34 u32 yres; 35 u32 refresh; 36 u32 width_mm; 37 u32 height_mm; 38 u32 max_hs_rate; 39 u32 max_lp_rate; 40 }; 41 42 struct panel_drv_data { 43 struct mipi_dsi_device *dsi; 44 struct drm_panel panel; 45 struct drm_display_mode mode; 46 47 struct mutex lock; 48 49 struct backlight_device *bldev; 50 struct backlight_device *extbldev; 51 52 unsigned long hw_guard_end; /* next value of jiffies when we can 53 * issue the next sleep in/out command 54 */ 55 unsigned long hw_guard_wait; /* max guard time in jiffies */ 56 57 const struct dsic_panel_data *panel_data; 58 59 struct gpio_desc *reset_gpio; 60 61 struct regulator_bulk_data supplies[DCS_REGULATOR_SUPPLY_NUM]; 62 63 bool use_dsi_backlight; 64 65 /* runtime variables */ 66 bool enabled; 67 68 bool intro_printed; 69 }; 70 71 static inline struct panel_drv_data *panel_to_ddata(struct drm_panel *panel) 72 { 73 return container_of(panel, struct panel_drv_data, panel); 74 } 75 76 static void dsicm_bl_power(struct panel_drv_data *ddata, bool enable) 77 { 78 struct backlight_device *backlight; 79 80 if (ddata->bldev) 81 backlight = ddata->bldev; 82 else if (ddata->extbldev) 83 backlight = ddata->extbldev; 84 else 85 return; 86 87 if (enable) { 88 backlight->props.fb_blank = FB_BLANK_UNBLANK; 89 backlight->props.state = ~(BL_CORE_FBBLANK | BL_CORE_SUSPENDED); 90 backlight->props.power = FB_BLANK_UNBLANK; 91 } else { 92 backlight->props.fb_blank = FB_BLANK_NORMAL; 93 backlight->props.power = FB_BLANK_POWERDOWN; 94 backlight->props.state |= BL_CORE_FBBLANK | BL_CORE_SUSPENDED; 95 } 96 97 backlight_update_status(backlight); 98 } 99 100 static void hw_guard_start(struct panel_drv_data *ddata, int guard_msec) 101 { 102 ddata->hw_guard_wait = msecs_to_jiffies(guard_msec); 103 ddata->hw_guard_end = jiffies + ddata->hw_guard_wait; 104 } 105 106 static void hw_guard_wait(struct panel_drv_data *ddata) 107 { 108 unsigned long wait = ddata->hw_guard_end - jiffies; 109 110 if ((long)wait > 0 && wait <= ddata->hw_guard_wait) { 111 set_current_state(TASK_UNINTERRUPTIBLE); 112 schedule_timeout(wait); 113 } 114 } 115 116 static int dsicm_dcs_read_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 *data) 117 { 118 return mipi_dsi_dcs_read(ddata->dsi, dcs_cmd, data, 1); 119 } 120 121 static int dsicm_dcs_write_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 param) 122 { 123 return mipi_dsi_dcs_write(ddata->dsi, dcs_cmd, ¶m, 1); 124 } 125 126 static int dsicm_sleep_in(struct panel_drv_data *ddata) 127 128 { 129 int r; 130 131 hw_guard_wait(ddata); 132 133 r = mipi_dsi_dcs_enter_sleep_mode(ddata->dsi); 134 if (r) 135 return r; 136 137 hw_guard_start(ddata, 120); 138 139 usleep_range(5000, 10000); 140 141 return 0; 142 } 143 144 static int dsicm_sleep_out(struct panel_drv_data *ddata) 145 { 146 int r; 147 148 hw_guard_wait(ddata); 149 150 r = mipi_dsi_dcs_exit_sleep_mode(ddata->dsi); 151 if (r) 152 return r; 153 154 hw_guard_start(ddata, 120); 155 156 usleep_range(5000, 10000); 157 158 return 0; 159 } 160 161 static int dsicm_get_id(struct panel_drv_data *ddata, u8 *id1, u8 *id2, u8 *id3) 162 { 163 int r; 164 165 r = dsicm_dcs_read_1(ddata, DCS_GET_ID1, id1); 166 if (r) 167 return r; 168 r = dsicm_dcs_read_1(ddata, DCS_GET_ID2, id2); 169 if (r) 170 return r; 171 r = dsicm_dcs_read_1(ddata, DCS_GET_ID3, id3); 172 if (r) 173 return r; 174 175 return 0; 176 } 177 178 static int dsicm_set_update_window(struct panel_drv_data *ddata) 179 { 180 struct mipi_dsi_device *dsi = ddata->dsi; 181 int r; 182 183 r = mipi_dsi_dcs_set_column_address(dsi, 0, ddata->mode.hdisplay - 1); 184 if (r < 0) 185 return r; 186 187 r = mipi_dsi_dcs_set_page_address(dsi, 0, ddata->mode.vdisplay - 1); 188 if (r < 0) 189 return r; 190 191 return 0; 192 } 193 194 static int dsicm_bl_update_status(struct backlight_device *dev) 195 { 196 struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev); 197 int r = 0; 198 int level; 199 200 if (dev->props.fb_blank == FB_BLANK_UNBLANK && 201 dev->props.power == FB_BLANK_UNBLANK) 202 level = dev->props.brightness; 203 else 204 level = 0; 205 206 dev_dbg(&ddata->dsi->dev, "update brightness to %d\n", level); 207 208 mutex_lock(&ddata->lock); 209 210 if (ddata->enabled) 211 r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 212 level); 213 214 mutex_unlock(&ddata->lock); 215 216 return r; 217 } 218 219 static int dsicm_bl_get_intensity(struct backlight_device *dev) 220 { 221 if (dev->props.fb_blank == FB_BLANK_UNBLANK && 222 dev->props.power == FB_BLANK_UNBLANK) 223 return dev->props.brightness; 224 225 return 0; 226 } 227 228 static const struct backlight_ops dsicm_bl_ops = { 229 .get_brightness = dsicm_bl_get_intensity, 230 .update_status = dsicm_bl_update_status, 231 }; 232 233 static ssize_t num_dsi_errors_show(struct device *dev, 234 struct device_attribute *attr, char *buf) 235 { 236 struct panel_drv_data *ddata = dev_get_drvdata(dev); 237 u8 errors = 0; 238 int r = -ENODEV; 239 240 mutex_lock(&ddata->lock); 241 242 if (ddata->enabled) 243 r = dsicm_dcs_read_1(ddata, MIPI_DCS_GET_ERROR_COUNT_ON_DSI, &errors); 244 245 mutex_unlock(&ddata->lock); 246 247 if (r) 248 return r; 249 250 return snprintf(buf, PAGE_SIZE, "%d\n", errors); 251 } 252 253 static ssize_t hw_revision_show(struct device *dev, 254 struct device_attribute *attr, char *buf) 255 { 256 struct panel_drv_data *ddata = dev_get_drvdata(dev); 257 u8 id1, id2, id3; 258 int r = -ENODEV; 259 260 mutex_lock(&ddata->lock); 261 262 if (ddata->enabled) 263 r = dsicm_get_id(ddata, &id1, &id2, &id3); 264 265 mutex_unlock(&ddata->lock); 266 267 if (r) 268 return r; 269 270 return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x\n", id1, id2, id3); 271 } 272 273 static DEVICE_ATTR_RO(num_dsi_errors); 274 static DEVICE_ATTR_RO(hw_revision); 275 276 static struct attribute *dsicm_attrs[] = { 277 &dev_attr_num_dsi_errors.attr, 278 &dev_attr_hw_revision.attr, 279 NULL, 280 }; 281 282 static const struct attribute_group dsicm_attr_group = { 283 .attrs = dsicm_attrs, 284 }; 285 286 static void dsicm_hw_reset(struct panel_drv_data *ddata) 287 { 288 gpiod_set_value(ddata->reset_gpio, 1); 289 udelay(10); 290 /* reset the panel */ 291 gpiod_set_value(ddata->reset_gpio, 0); 292 /* assert reset */ 293 udelay(10); 294 gpiod_set_value(ddata->reset_gpio, 1); 295 /* wait after releasing reset */ 296 usleep_range(5000, 10000); 297 } 298 299 static int dsicm_power_on(struct panel_drv_data *ddata) 300 { 301 u8 id1, id2, id3; 302 int r; 303 304 dsicm_hw_reset(ddata); 305 306 ddata->dsi->mode_flags |= MIPI_DSI_MODE_LPM; 307 308 r = dsicm_sleep_out(ddata); 309 if (r) 310 goto err; 311 312 r = dsicm_get_id(ddata, &id1, &id2, &id3); 313 if (r) 314 goto err; 315 316 r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 0xff); 317 if (r) 318 goto err; 319 320 r = dsicm_dcs_write_1(ddata, MIPI_DCS_WRITE_CONTROL_DISPLAY, 321 (1<<2) | (1<<5)); /* BL | BCTRL */ 322 if (r) 323 goto err; 324 325 r = mipi_dsi_dcs_set_pixel_format(ddata->dsi, MIPI_DCS_PIXEL_FMT_24BIT); 326 if (r) 327 goto err; 328 329 r = dsicm_set_update_window(ddata); 330 if (r) 331 goto err; 332 333 r = mipi_dsi_dcs_set_display_on(ddata->dsi); 334 if (r) 335 goto err; 336 337 r = mipi_dsi_dcs_set_tear_on(ddata->dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK); 338 if (r) 339 goto err; 340 341 /* possible panel bug */ 342 msleep(100); 343 344 ddata->enabled = true; 345 346 if (!ddata->intro_printed) { 347 dev_info(&ddata->dsi->dev, "panel revision %02x.%02x.%02x\n", 348 id1, id2, id3); 349 ddata->intro_printed = true; 350 } 351 352 ddata->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; 353 354 return 0; 355 err: 356 dev_err(&ddata->dsi->dev, "error while enabling panel, issuing HW reset\n"); 357 358 dsicm_hw_reset(ddata); 359 360 return r; 361 } 362 363 static int dsicm_power_off(struct panel_drv_data *ddata) 364 { 365 int r; 366 367 ddata->enabled = false; 368 369 r = mipi_dsi_dcs_set_display_off(ddata->dsi); 370 if (!r) 371 r = dsicm_sleep_in(ddata); 372 373 if (r) { 374 dev_err(&ddata->dsi->dev, 375 "error disabling panel, issuing HW reset\n"); 376 dsicm_hw_reset(ddata); 377 } 378 379 return r; 380 } 381 382 static int dsicm_prepare(struct drm_panel *panel) 383 { 384 struct panel_drv_data *ddata = panel_to_ddata(panel); 385 int r; 386 387 r = regulator_bulk_enable(ARRAY_SIZE(ddata->supplies), ddata->supplies); 388 if (r) 389 dev_err(&ddata->dsi->dev, "failed to enable supplies: %d\n", r); 390 391 return r; 392 } 393 394 static int dsicm_enable(struct drm_panel *panel) 395 { 396 struct panel_drv_data *ddata = panel_to_ddata(panel); 397 int r; 398 399 mutex_lock(&ddata->lock); 400 401 r = dsicm_power_on(ddata); 402 if (r) 403 goto err; 404 405 mutex_unlock(&ddata->lock); 406 407 dsicm_bl_power(ddata, true); 408 409 return 0; 410 err: 411 dev_err(&ddata->dsi->dev, "enable failed (%d)\n", r); 412 mutex_unlock(&ddata->lock); 413 return r; 414 } 415 416 static int dsicm_unprepare(struct drm_panel *panel) 417 { 418 struct panel_drv_data *ddata = panel_to_ddata(panel); 419 int r; 420 421 r = regulator_bulk_disable(ARRAY_SIZE(ddata->supplies), ddata->supplies); 422 if (r) 423 dev_err(&ddata->dsi->dev, "failed to disable supplies: %d\n", r); 424 425 return r; 426 } 427 428 static int dsicm_disable(struct drm_panel *panel) 429 { 430 struct panel_drv_data *ddata = panel_to_ddata(panel); 431 int r; 432 433 dsicm_bl_power(ddata, false); 434 435 mutex_lock(&ddata->lock); 436 437 r = dsicm_power_off(ddata); 438 439 mutex_unlock(&ddata->lock); 440 441 return r; 442 } 443 444 static int dsicm_get_modes(struct drm_panel *panel, 445 struct drm_connector *connector) 446 { 447 struct panel_drv_data *ddata = panel_to_ddata(panel); 448 struct drm_display_mode *mode; 449 450 mode = drm_mode_duplicate(connector->dev, &ddata->mode); 451 if (!mode) { 452 dev_err(&ddata->dsi->dev, "failed to add mode %ux%ux@%u kHz\n", 453 ddata->mode.hdisplay, ddata->mode.vdisplay, 454 ddata->mode.clock); 455 return -ENOMEM; 456 } 457 458 connector->display_info.width_mm = ddata->panel_data->width_mm; 459 connector->display_info.height_mm = ddata->panel_data->height_mm; 460 461 drm_mode_probed_add(connector, mode); 462 463 return 1; 464 } 465 466 static const struct drm_panel_funcs dsicm_panel_funcs = { 467 .unprepare = dsicm_unprepare, 468 .disable = dsicm_disable, 469 .prepare = dsicm_prepare, 470 .enable = dsicm_enable, 471 .get_modes = dsicm_get_modes, 472 }; 473 474 static int dsicm_probe_of(struct mipi_dsi_device *dsi) 475 { 476 struct backlight_device *backlight; 477 struct panel_drv_data *ddata = mipi_dsi_get_drvdata(dsi); 478 int err; 479 struct drm_display_mode *mode = &ddata->mode; 480 481 ddata->reset_gpio = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW); 482 if (IS_ERR(ddata->reset_gpio)) { 483 err = PTR_ERR(ddata->reset_gpio); 484 dev_err(&dsi->dev, "reset gpio request failed: %d", err); 485 return err; 486 } 487 488 mode->hdisplay = mode->hsync_start = mode->hsync_end = mode->htotal = 489 ddata->panel_data->xres; 490 mode->vdisplay = mode->vsync_start = mode->vsync_end = mode->vtotal = 491 ddata->panel_data->yres; 492 mode->clock = ddata->panel_data->xres * ddata->panel_data->yres * 493 ddata->panel_data->refresh / 1000; 494 mode->width_mm = ddata->panel_data->width_mm; 495 mode->height_mm = ddata->panel_data->height_mm; 496 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 497 drm_mode_set_name(mode); 498 499 ddata->supplies[0].supply = "vpnl"; 500 ddata->supplies[1].supply = "vddi"; 501 err = devm_regulator_bulk_get(&dsi->dev, ARRAY_SIZE(ddata->supplies), 502 ddata->supplies); 503 if (err) 504 return err; 505 506 backlight = devm_of_find_backlight(&dsi->dev); 507 if (IS_ERR(backlight)) 508 return PTR_ERR(backlight); 509 510 /* If no backlight device is found assume native backlight support */ 511 if (backlight) 512 ddata->extbldev = backlight; 513 else 514 ddata->use_dsi_backlight = true; 515 516 return 0; 517 } 518 519 static int dsicm_probe(struct mipi_dsi_device *dsi) 520 { 521 struct panel_drv_data *ddata; 522 struct backlight_device *bldev = NULL; 523 struct device *dev = &dsi->dev; 524 int r; 525 526 dev_dbg(dev, "probe\n"); 527 528 ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); 529 if (!ddata) 530 return -ENOMEM; 531 532 mipi_dsi_set_drvdata(dsi, ddata); 533 ddata->dsi = dsi; 534 535 ddata->panel_data = of_device_get_match_data(dev); 536 if (!ddata->panel_data) 537 return -ENODEV; 538 539 r = dsicm_probe_of(dsi); 540 if (r) 541 return r; 542 543 mutex_init(&ddata->lock); 544 545 dsicm_hw_reset(ddata); 546 547 drm_panel_init(&ddata->panel, dev, &dsicm_panel_funcs, 548 DRM_MODE_CONNECTOR_DSI); 549 550 if (ddata->use_dsi_backlight) { 551 struct backlight_properties props = { 0 }; 552 props.max_brightness = 255; 553 props.type = BACKLIGHT_RAW; 554 555 bldev = devm_backlight_device_register(dev, dev_name(dev), 556 dev, ddata, &dsicm_bl_ops, &props); 557 if (IS_ERR(bldev)) { 558 r = PTR_ERR(bldev); 559 goto err_bl; 560 } 561 562 ddata->bldev = bldev; 563 } 564 565 r = sysfs_create_group(&dev->kobj, &dsicm_attr_group); 566 if (r) { 567 dev_err(dev, "failed to create sysfs files\n"); 568 goto err_bl; 569 } 570 571 dsi->lanes = 2; 572 dsi->format = MIPI_DSI_FMT_RGB888; 573 dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS | 574 MIPI_DSI_MODE_EOT_PACKET; 575 dsi->hs_rate = ddata->panel_data->max_hs_rate; 576 dsi->lp_rate = ddata->panel_data->max_lp_rate; 577 578 drm_panel_add(&ddata->panel); 579 580 r = mipi_dsi_attach(dsi); 581 if (r < 0) 582 goto err_dsi_attach; 583 584 return 0; 585 586 err_dsi_attach: 587 drm_panel_remove(&ddata->panel); 588 sysfs_remove_group(&dsi->dev.kobj, &dsicm_attr_group); 589 err_bl: 590 if (ddata->extbldev) 591 put_device(&ddata->extbldev->dev); 592 593 return r; 594 } 595 596 static int dsicm_remove(struct mipi_dsi_device *dsi) 597 { 598 struct panel_drv_data *ddata = mipi_dsi_get_drvdata(dsi); 599 600 dev_dbg(&dsi->dev, "remove\n"); 601 602 mipi_dsi_detach(dsi); 603 604 drm_panel_remove(&ddata->panel); 605 606 sysfs_remove_group(&dsi->dev.kobj, &dsicm_attr_group); 607 608 if (ddata->extbldev) 609 put_device(&ddata->extbldev->dev); 610 611 return 0; 612 } 613 614 static const struct dsic_panel_data taal_data = { 615 .xres = 864, 616 .yres = 480, 617 .refresh = 60, 618 .width_mm = 0, 619 .height_mm = 0, 620 .max_hs_rate = 300000000, 621 .max_lp_rate = 10000000, 622 }; 623 624 static const struct dsic_panel_data himalaya_data = { 625 .xres = 480, 626 .yres = 864, 627 .refresh = 60, 628 .width_mm = 49, 629 .height_mm = 88, 630 .max_hs_rate = 300000000, 631 .max_lp_rate = 10000000, 632 }; 633 634 static const struct dsic_panel_data droid4_data = { 635 .xres = 540, 636 .yres = 960, 637 .refresh = 60, 638 .width_mm = 50, 639 .height_mm = 89, 640 .max_hs_rate = 300000000, 641 .max_lp_rate = 10000000, 642 }; 643 644 static const struct of_device_id dsicm_of_match[] = { 645 { .compatible = "tpo,taal", .data = &taal_data }, 646 { .compatible = "nokia,himalaya", &himalaya_data }, 647 { .compatible = "motorola,droid4-panel", &droid4_data }, 648 {}, 649 }; 650 651 MODULE_DEVICE_TABLE(of, dsicm_of_match); 652 653 static struct mipi_dsi_driver dsicm_driver = { 654 .probe = dsicm_probe, 655 .remove = dsicm_remove, 656 .driver = { 657 .name = "panel-dsi-cm", 658 .of_match_table = dsicm_of_match, 659 }, 660 }; 661 module_mipi_dsi_driver(dsicm_driver); 662 663 MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>"); 664 MODULE_DESCRIPTION("Generic DSI Command Mode Panel Driver"); 665 MODULE_LICENSE("GPL"); 666