1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2014 Google, Inc. 4 * 5 * Copyright (C) 2022 Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt> 6 * 7 * Adapted from the downstream Pixel C driver written by Sean Paul 8 */ 9 10 #include <linux/backlight.h> 11 #include <linux/delay.h> 12 #include <linux/gpio/consumer.h> 13 #include <linux/module.h> 14 #include <linux/of.h> 15 #include <linux/regulator/consumer.h> 16 17 #include <video/mipi_display.h> 18 19 #include <drm/drm_crtc.h> 20 #include <drm/drm_mipi_dsi.h> 21 #include <drm/drm_panel.h> 22 23 #define MCS_CMD_ACS_PROT 0xB0 24 #define MCS_CMD_ACS_PROT_OFF (0 << 0) 25 26 #define MCS_PWR_CTRL_FUNC 0xD0 27 #define MCS_PWR_CTRL_PARAM1_DEFAULT (2 << 0) 28 #define MCS_PWR_CTRL_PARAM1_VGH_210_DIV (1 << 4) 29 #define MCS_PWR_CTRL_PARAM1_VGH_240_DIV (2 << 4) 30 #define MCS_PWR_CTRL_PARAM1_VGH_280_DIV (3 << 4) 31 #define MCS_PWR_CTRL_PARAM1_VGH_330_DIV (4 << 4) 32 #define MCS_PWR_CTRL_PARAM1_VGH_410_DIV (5 << 4) 33 #define MCS_PWR_CTRL_PARAM2_DEFAULT (9 << 4) 34 #define MCS_PWR_CTRL_PARAM2_VGL_210_DIV (1 << 0) 35 #define MCS_PWR_CTRL_PARAM2_VGL_240_DIV (2 << 0) 36 #define MCS_PWR_CTRL_PARAM2_VGL_280_DIV (3 << 0) 37 #define MCS_PWR_CTRL_PARAM2_VGL_330_DIV (4 << 0) 38 #define MCS_PWR_CTRL_PARAM2_VGL_410_DIV (5 << 0) 39 40 struct jdi_panel { 41 struct drm_panel base; 42 struct mipi_dsi_device *link1; 43 struct mipi_dsi_device *link2; 44 45 struct regulator *supply; 46 struct regulator *ddi_supply; 47 struct backlight_device *backlight; 48 49 struct gpio_desc *enable_gpio; 50 struct gpio_desc *reset_gpio; 51 52 const struct drm_display_mode *mode; 53 }; 54 55 static inline struct jdi_panel *to_panel_jdi(struct drm_panel *panel) 56 { 57 return container_of(panel, struct jdi_panel, base); 58 } 59 60 static void jdi_wait_frames(struct jdi_panel *jdi, unsigned int frames) 61 { 62 unsigned int refresh = drm_mode_vrefresh(jdi->mode); 63 64 if (WARN_ON(frames > refresh)) 65 return; 66 67 msleep(1000 / (refresh / frames)); 68 } 69 70 static int jdi_panel_disable(struct drm_panel *panel) 71 { 72 struct jdi_panel *jdi = to_panel_jdi(panel); 73 74 backlight_disable(jdi->backlight); 75 76 jdi_wait_frames(jdi, 2); 77 78 return 0; 79 } 80 81 static int jdi_panel_unprepare(struct drm_panel *panel) 82 { 83 struct jdi_panel *jdi = to_panel_jdi(panel); 84 int ret; 85 86 ret = mipi_dsi_dcs_set_display_off(jdi->link1); 87 if (ret < 0) 88 dev_err(panel->dev, "failed to set display off: %d\n", ret); 89 90 ret = mipi_dsi_dcs_set_display_off(jdi->link2); 91 if (ret < 0) 92 dev_err(panel->dev, "failed to set display off: %d\n", ret); 93 94 /* Specified by JDI @ 50ms, subject to change */ 95 msleep(50); 96 97 ret = mipi_dsi_dcs_enter_sleep_mode(jdi->link1); 98 if (ret < 0) 99 dev_err(panel->dev, "failed to enter sleep mode: %d\n", ret); 100 ret = mipi_dsi_dcs_enter_sleep_mode(jdi->link2); 101 if (ret < 0) 102 dev_err(panel->dev, "failed to enter sleep mode: %d\n", ret); 103 104 /* Specified by JDI @ 150ms, subject to change */ 105 msleep(150); 106 107 gpiod_set_value(jdi->reset_gpio, 1); 108 109 /* T4 = 1ms */ 110 usleep_range(1000, 3000); 111 112 gpiod_set_value(jdi->enable_gpio, 0); 113 114 /* T5 = 2ms */ 115 usleep_range(2000, 4000); 116 117 regulator_disable(jdi->ddi_supply); 118 119 /* T6 = 2ms plus some time to discharge capacitors */ 120 usleep_range(7000, 9000); 121 122 regulator_disable(jdi->supply); 123 /* Specified by JDI @ 20ms, subject to change */ 124 msleep(20); 125 126 return ret; 127 } 128 129 static int jdi_setup_symmetrical_split(struct mipi_dsi_device *left, 130 struct mipi_dsi_device *right, 131 const struct drm_display_mode *mode) 132 { 133 int err; 134 135 err = mipi_dsi_dcs_set_column_address(left, 0, mode->hdisplay / 2 - 1); 136 if (err < 0) { 137 dev_err(&left->dev, "failed to set column address: %d\n", err); 138 return err; 139 } 140 141 err = mipi_dsi_dcs_set_column_address(right, 0, mode->hdisplay / 2 - 1); 142 if (err < 0) { 143 dev_err(&right->dev, "failed to set column address: %d\n", err); 144 return err; 145 } 146 147 err = mipi_dsi_dcs_set_page_address(left, 0, mode->vdisplay - 1); 148 if (err < 0) { 149 dev_err(&left->dev, "failed to set page address: %d\n", err); 150 return err; 151 } 152 153 err = mipi_dsi_dcs_set_page_address(right, 0, mode->vdisplay - 1); 154 if (err < 0) { 155 dev_err(&right->dev, "failed to set page address: %d\n", err); 156 return err; 157 } 158 159 return 0; 160 } 161 162 static int jdi_write_dcdc_registers(struct jdi_panel *jdi) 163 { 164 /* Clear the manufacturer command access protection */ 165 mipi_dsi_generic_write_seq(jdi->link1, MCS_CMD_ACS_PROT, 166 MCS_CMD_ACS_PROT_OFF); 167 mipi_dsi_generic_write_seq(jdi->link2, MCS_CMD_ACS_PROT, 168 MCS_CMD_ACS_PROT_OFF); 169 /* 170 * Change the VGH/VGL divide rations to move the noise generated by the 171 * TCONN. This should hopefully avoid interaction with the backlight 172 * controller. 173 */ 174 mipi_dsi_generic_write_seq(jdi->link1, MCS_PWR_CTRL_FUNC, 175 MCS_PWR_CTRL_PARAM1_VGH_330_DIV | 176 MCS_PWR_CTRL_PARAM1_DEFAULT, 177 MCS_PWR_CTRL_PARAM2_VGL_410_DIV | 178 MCS_PWR_CTRL_PARAM2_DEFAULT); 179 180 mipi_dsi_generic_write_seq(jdi->link2, MCS_PWR_CTRL_FUNC, 181 MCS_PWR_CTRL_PARAM1_VGH_330_DIV | 182 MCS_PWR_CTRL_PARAM1_DEFAULT, 183 MCS_PWR_CTRL_PARAM2_VGL_410_DIV | 184 MCS_PWR_CTRL_PARAM2_DEFAULT); 185 186 return 0; 187 } 188 189 static int jdi_panel_prepare(struct drm_panel *panel) 190 { 191 struct jdi_panel *jdi = to_panel_jdi(panel); 192 int err; 193 194 /* Disable backlight to avoid showing random pixels 195 * with a conservative delay for it to take effect. 196 */ 197 backlight_disable(jdi->backlight); 198 jdi_wait_frames(jdi, 3); 199 200 jdi->link1->mode_flags |= MIPI_DSI_MODE_LPM; 201 jdi->link2->mode_flags |= MIPI_DSI_MODE_LPM; 202 203 err = regulator_enable(jdi->supply); 204 if (err < 0) { 205 dev_err(panel->dev, "failed to enable supply: %d\n", err); 206 return err; 207 } 208 /* T1 = 2ms */ 209 usleep_range(2000, 4000); 210 211 err = regulator_enable(jdi->ddi_supply); 212 if (err < 0) { 213 dev_err(panel->dev, "failed to enable ddi_supply: %d\n", err); 214 goto supply_off; 215 } 216 /* T2 = 1ms */ 217 usleep_range(1000, 3000); 218 219 gpiod_set_value(jdi->enable_gpio, 1); 220 /* T3 = 10ms */ 221 usleep_range(10000, 15000); 222 223 gpiod_set_value(jdi->reset_gpio, 0); 224 /* Specified by JDI @ 3ms, subject to change */ 225 usleep_range(3000, 5000); 226 227 /* 228 * TODO: The device supports both left-right and even-odd split 229 * configurations, but this driver currently supports only the left- 230 * right split. To support a different mode a mechanism needs to be 231 * put in place to communicate the configuration back to the DSI host 232 * controller. 233 */ 234 err = jdi_setup_symmetrical_split(jdi->link1, jdi->link2, 235 jdi->mode); 236 if (err < 0) { 237 dev_err(panel->dev, "failed to set up symmetrical split: %d\n", 238 err); 239 goto poweroff; 240 } 241 242 err = mipi_dsi_dcs_set_tear_scanline(jdi->link1, 243 jdi->mode->vdisplay - 16); 244 if (err < 0) { 245 dev_err(panel->dev, "failed to set tear scanline: %d\n", err); 246 goto poweroff; 247 } 248 249 err = mipi_dsi_dcs_set_tear_scanline(jdi->link2, 250 jdi->mode->vdisplay - 16); 251 if (err < 0) { 252 dev_err(panel->dev, "failed to set tear scanline: %d\n", err); 253 goto poweroff; 254 } 255 256 err = mipi_dsi_dcs_set_tear_on(jdi->link1, 257 MIPI_DSI_DCS_TEAR_MODE_VBLANK); 258 if (err < 0) { 259 dev_err(panel->dev, "failed to set tear on: %d\n", err); 260 goto poweroff; 261 } 262 263 err = mipi_dsi_dcs_set_tear_on(jdi->link2, 264 MIPI_DSI_DCS_TEAR_MODE_VBLANK); 265 if (err < 0) { 266 dev_err(panel->dev, "failed to set tear on: %d\n", err); 267 goto poweroff; 268 } 269 270 err = mipi_dsi_dcs_set_pixel_format(jdi->link1, MIPI_DCS_PIXEL_FMT_24BIT); 271 if (err < 0) { 272 dev_err(panel->dev, "failed to set pixel format: %d\n", err); 273 goto poweroff; 274 } 275 276 err = mipi_dsi_dcs_set_pixel_format(jdi->link2, MIPI_DCS_PIXEL_FMT_24BIT); 277 if (err < 0) { 278 dev_err(panel->dev, "failed to set pixel format: %d\n", err); 279 goto poweroff; 280 } 281 282 err = mipi_dsi_dcs_exit_sleep_mode(jdi->link1); 283 if (err < 0) { 284 dev_err(panel->dev, "failed to exit sleep mode: %d\n", err); 285 goto poweroff; 286 } 287 288 err = mipi_dsi_dcs_exit_sleep_mode(jdi->link2); 289 if (err < 0) { 290 dev_err(panel->dev, "failed to exit sleep mode: %d\n", err); 291 goto poweroff; 292 } 293 294 err = jdi_write_dcdc_registers(jdi); 295 if (err < 0) { 296 dev_err(panel->dev, "failed to write dcdc registers: %d\n", err); 297 goto poweroff; 298 } 299 /* 300 * We need to wait 150ms between mipi_dsi_dcs_exit_sleep_mode() and 301 * mipi_dsi_dcs_set_display_on(). 302 */ 303 msleep(150); 304 305 err = mipi_dsi_dcs_set_display_on(jdi->link1); 306 if (err < 0) { 307 dev_err(panel->dev, "failed to set display on: %d\n", err); 308 goto poweroff; 309 } 310 311 err = mipi_dsi_dcs_set_display_on(jdi->link2); 312 if (err < 0) { 313 dev_err(panel->dev, "failed to set display on: %d\n", err); 314 goto poweroff; 315 } 316 317 jdi->link1->mode_flags &= ~MIPI_DSI_MODE_LPM; 318 jdi->link2->mode_flags &= ~MIPI_DSI_MODE_LPM; 319 320 return 0; 321 322 poweroff: 323 regulator_disable(jdi->ddi_supply); 324 325 /* T6 = 2ms plus some time to discharge capacitors */ 326 usleep_range(7000, 9000); 327 supply_off: 328 regulator_disable(jdi->supply); 329 /* Specified by JDI @ 20ms, subject to change */ 330 msleep(20); 331 332 return err; 333 } 334 335 static int jdi_panel_enable(struct drm_panel *panel) 336 { 337 struct jdi_panel *jdi = to_panel_jdi(panel); 338 339 /* 340 * Ensure we send image data before turning the backlight 341 * on, to avoid the display showing random pixels. 342 */ 343 jdi_wait_frames(jdi, 3); 344 345 backlight_enable(jdi->backlight); 346 347 return 0; 348 } 349 350 static const struct drm_display_mode default_mode = { 351 .clock = (2560 + 80 + 80 + 80) * (1800 + 4 + 4 + 4) * 60 / 1000, 352 .hdisplay = 2560, 353 .hsync_start = 2560 + 80, 354 .hsync_end = 2560 + 80 + 80, 355 .htotal = 2560 + 80 + 80 + 80, 356 .vdisplay = 1800, 357 .vsync_start = 1800 + 4, 358 .vsync_end = 1800 + 4 + 4, 359 .vtotal = 1800 + 4 + 4 + 4, 360 .flags = 0, 361 }; 362 363 static int jdi_panel_get_modes(struct drm_panel *panel, 364 struct drm_connector *connector) 365 { 366 struct drm_display_mode *mode; 367 struct jdi_panel *jdi = to_panel_jdi(panel); 368 struct device *dev = &jdi->link1->dev; 369 370 mode = drm_mode_duplicate(connector->dev, &default_mode); 371 if (!mode) { 372 dev_err(dev, "failed to add mode %ux%ux@%u\n", 373 default_mode.hdisplay, default_mode.vdisplay, 374 drm_mode_vrefresh(&default_mode)); 375 return -ENOMEM; 376 } 377 378 drm_mode_set_name(mode); 379 380 drm_mode_probed_add(connector, mode); 381 382 connector->display_info.width_mm = 211; 383 connector->display_info.height_mm = 148; 384 connector->display_info.bpc = 8; 385 386 return 1; 387 } 388 389 static const struct drm_panel_funcs jdi_panel_funcs = { 390 .prepare = jdi_panel_prepare, 391 .enable = jdi_panel_enable, 392 .disable = jdi_panel_disable, 393 .unprepare = jdi_panel_unprepare, 394 .get_modes = jdi_panel_get_modes, 395 }; 396 397 static const struct of_device_id jdi_of_match[] = { 398 { .compatible = "jdi,lpm102a188a", }, 399 { } 400 }; 401 MODULE_DEVICE_TABLE(of, jdi_of_match); 402 403 static int jdi_panel_add(struct jdi_panel *jdi) 404 { 405 struct device *dev = &jdi->link1->dev; 406 407 jdi->mode = &default_mode; 408 409 jdi->supply = devm_regulator_get(dev, "power"); 410 if (IS_ERR(jdi->supply)) 411 return dev_err_probe(dev, PTR_ERR(jdi->supply), 412 "failed to get power regulator\n"); 413 414 jdi->ddi_supply = devm_regulator_get(dev, "ddi"); 415 if (IS_ERR(jdi->ddi_supply)) 416 return dev_err_probe(dev, PTR_ERR(jdi->ddi_supply), 417 "failed to get ddi regulator\n"); 418 419 jdi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); 420 if (IS_ERR(jdi->reset_gpio)) 421 return dev_err_probe(dev, PTR_ERR(jdi->reset_gpio), 422 "failed to get reset gpio\n"); 423 /* T4 = 1ms */ 424 usleep_range(1000, 3000); 425 426 jdi->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); 427 if (IS_ERR(jdi->enable_gpio)) 428 return dev_err_probe(dev, PTR_ERR(jdi->enable_gpio), 429 "failed to get enable gpio\n"); 430 /* T5 = 2ms */ 431 usleep_range(2000, 4000); 432 433 jdi->backlight = devm_of_find_backlight(dev); 434 if (IS_ERR(jdi->backlight)) 435 return dev_err_probe(dev, PTR_ERR(jdi->backlight), 436 "failed to create backlight\n"); 437 438 drm_panel_init(&jdi->base, &jdi->link1->dev, &jdi_panel_funcs, 439 DRM_MODE_CONNECTOR_DSI); 440 441 drm_panel_add(&jdi->base); 442 443 return 0; 444 } 445 446 static void jdi_panel_del(struct jdi_panel *jdi) 447 { 448 if (jdi->base.dev) 449 drm_panel_remove(&jdi->base); 450 451 if (jdi->link2) 452 put_device(&jdi->link2->dev); 453 } 454 455 static int jdi_panel_dsi_probe(struct mipi_dsi_device *dsi) 456 { 457 struct mipi_dsi_device *secondary = NULL; 458 struct jdi_panel *jdi; 459 struct device_node *np; 460 int err; 461 462 dsi->lanes = 4; 463 dsi->format = MIPI_DSI_FMT_RGB888; 464 dsi->mode_flags = 0; 465 466 /* Find DSI-LINK1 */ 467 np = of_parse_phandle(dsi->dev.of_node, "link2", 0); 468 if (np) { 469 secondary = of_find_mipi_dsi_device_by_node(np); 470 of_node_put(np); 471 472 if (!secondary) 473 return -EPROBE_DEFER; 474 } 475 476 /* register a panel for only the DSI-LINK1 interface */ 477 if (secondary) { 478 jdi = devm_kzalloc(&dsi->dev, sizeof(*jdi), GFP_KERNEL); 479 if (!jdi) { 480 put_device(&secondary->dev); 481 return -ENOMEM; 482 } 483 484 mipi_dsi_set_drvdata(dsi, jdi); 485 486 jdi->link1 = dsi; 487 jdi->link2 = secondary; 488 489 err = jdi_panel_add(jdi); 490 if (err < 0) { 491 put_device(&secondary->dev); 492 return err; 493 } 494 } 495 496 err = mipi_dsi_attach(dsi); 497 if (err < 0) { 498 if (secondary) 499 jdi_panel_del(jdi); 500 501 return err; 502 } 503 504 return 0; 505 } 506 507 static void jdi_panel_dsi_remove(struct mipi_dsi_device *dsi) 508 { 509 struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi); 510 int err; 511 512 /* only detach from host for the DSI-LINK2 interface */ 513 if (!jdi) 514 mipi_dsi_detach(dsi); 515 516 err = jdi_panel_disable(&jdi->base); 517 if (err < 0) 518 dev_err(&dsi->dev, "failed to disable panel: %d\n", err); 519 520 err = mipi_dsi_detach(dsi); 521 if (err < 0) 522 dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err); 523 524 jdi_panel_del(jdi); 525 } 526 527 static void jdi_panel_dsi_shutdown(struct mipi_dsi_device *dsi) 528 { 529 struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi); 530 531 if (!jdi) 532 return; 533 534 jdi_panel_disable(&jdi->base); 535 } 536 537 static struct mipi_dsi_driver jdi_panel_dsi_driver = { 538 .driver = { 539 .name = "panel-jdi-lpm102a188a", 540 .of_match_table = jdi_of_match, 541 }, 542 .probe = jdi_panel_dsi_probe, 543 .remove = jdi_panel_dsi_remove, 544 .shutdown = jdi_panel_dsi_shutdown, 545 }; 546 module_mipi_dsi_driver(jdi_panel_dsi_driver); 547 548 MODULE_AUTHOR("Sean Paul <seanpaul@chromium.org>"); 549 MODULE_AUTHOR("Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>"); 550 MODULE_DESCRIPTION("DRM Driver for JDI LPM102A188A DSI panel, command mode"); 551 MODULE_LICENSE("GPL"); 552