aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tinydrm/mipi-dbi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/tinydrm/mipi-dbi.c')
-rw-r--r--drivers/gpu/drm/tinydrm/mipi-dbi.c101
1 files changed, 86 insertions, 15 deletions
diff --git a/drivers/gpu/drm/tinydrm/mipi-dbi.c b/drivers/gpu/drm/tinydrm/mipi-dbi.c
index aa6b6ce56891..75dd65c57e74 100644
--- a/drivers/gpu/drm/tinydrm/mipi-dbi.c
+++ b/drivers/gpu/drm/tinydrm/mipi-dbi.c
@@ -271,21 +271,16 @@ static const struct drm_framebuffer_funcs mipi_dbi_fb_funcs = {
271}; 271};
272 272
273/** 273/**
274 * mipi_dbi_pipe_enable - MIPI DBI pipe enable helper 274 * mipi_dbi_enable_flush - MIPI DBI enable helper
275 * @pipe: Display pipe 275 * @mipi: MIPI DBI structure
276 * @crtc_state: CRTC state
277 * 276 *
278 * This function enables backlight. Drivers can use this as their 277 * This function sets &mipi_dbi->enabled, flushes the whole framebuffer and
278 * enables the backlight. Drivers can use this in their
279 * &drm_simple_display_pipe_funcs->enable callback. 279 * &drm_simple_display_pipe_funcs->enable callback.
280 */ 280 */
281void mipi_dbi_pipe_enable(struct drm_simple_display_pipe *pipe, 281void mipi_dbi_enable_flush(struct mipi_dbi *mipi)
282 struct drm_crtc_state *crtc_state)
283{ 282{
284 struct tinydrm_device *tdev = pipe_to_tinydrm(pipe); 283 struct drm_framebuffer *fb = mipi->tinydrm.pipe.plane.fb;
285 struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
286 struct drm_framebuffer *fb = pipe->plane.fb;
287
288 DRM_DEBUG_KMS("\n");
289 284
290 mipi->enabled = true; 285 mipi->enabled = true;
291 if (fb) 286 if (fb)
@@ -293,7 +288,7 @@ void mipi_dbi_pipe_enable(struct drm_simple_display_pipe *pipe,
293 288
294 tinydrm_enable_backlight(mipi->backlight); 289 tinydrm_enable_backlight(mipi->backlight);
295} 290}
296EXPORT_SYMBOL(mipi_dbi_pipe_enable); 291EXPORT_SYMBOL(mipi_dbi_enable_flush);
297 292
298static void mipi_dbi_blank(struct mipi_dbi *mipi) 293static void mipi_dbi_blank(struct mipi_dbi *mipi)
299{ 294{
@@ -316,8 +311,8 @@ static void mipi_dbi_blank(struct mipi_dbi *mipi)
316 * mipi_dbi_pipe_disable - MIPI DBI pipe disable helper 311 * mipi_dbi_pipe_disable - MIPI DBI pipe disable helper
317 * @pipe: Display pipe 312 * @pipe: Display pipe
318 * 313 *
319 * This function disables backlight if present or if not the 314 * This function disables backlight if present, if not the display memory is
320 * display memory is blanked. Drivers can use this as their 315 * blanked. The regulator is disabled if in use. Drivers can use this as their
321 * &drm_simple_display_pipe_funcs->disable callback. 316 * &drm_simple_display_pipe_funcs->disable callback.
322 */ 317 */
323void mipi_dbi_pipe_disable(struct drm_simple_display_pipe *pipe) 318void mipi_dbi_pipe_disable(struct drm_simple_display_pipe *pipe)
@@ -333,6 +328,9 @@ void mipi_dbi_pipe_disable(struct drm_simple_display_pipe *pipe)
333 tinydrm_disable_backlight(mipi->backlight); 328 tinydrm_disable_backlight(mipi->backlight);
334 else 329 else
335 mipi_dbi_blank(mipi); 330 mipi_dbi_blank(mipi);
331
332 if (mipi->regulator)
333 regulator_disable(mipi->regulator);
336} 334}
337EXPORT_SYMBOL(mipi_dbi_pipe_disable); 335EXPORT_SYMBOL(mipi_dbi_pipe_disable);
338 336
@@ -416,7 +414,7 @@ void mipi_dbi_hw_reset(struct mipi_dbi *mipi)
416 return; 414 return;
417 415
418 gpiod_set_value_cansleep(mipi->reset, 0); 416 gpiod_set_value_cansleep(mipi->reset, 0);
419 msleep(20); 417 usleep_range(20, 1000);
420 gpiod_set_value_cansleep(mipi->reset, 1); 418 gpiod_set_value_cansleep(mipi->reset, 1);
421 msleep(120); 419 msleep(120);
422} 420}
@@ -443,6 +441,7 @@ bool mipi_dbi_display_is_on(struct mipi_dbi *mipi)
443 441
444 val &= ~DCS_POWER_MODE_RESERVED_MASK; 442 val &= ~DCS_POWER_MODE_RESERVED_MASK;
445 443
444 /* The poweron/reset value is 08h DCS_POWER_MODE_DISPLAY_NORMAL_MODE */
446 if (val != (DCS_POWER_MODE_DISPLAY | 445 if (val != (DCS_POWER_MODE_DISPLAY |
447 DCS_POWER_MODE_DISPLAY_NORMAL_MODE | DCS_POWER_MODE_SLEEP_MODE)) 446 DCS_POWER_MODE_DISPLAY_NORMAL_MODE | DCS_POWER_MODE_SLEEP_MODE))
448 return false; 447 return false;
@@ -453,6 +452,78 @@ bool mipi_dbi_display_is_on(struct mipi_dbi *mipi)
453} 452}
454EXPORT_SYMBOL(mipi_dbi_display_is_on); 453EXPORT_SYMBOL(mipi_dbi_display_is_on);
455 454
455static int mipi_dbi_poweron_reset_conditional(struct mipi_dbi *mipi, bool cond)
456{
457 struct device *dev = mipi->tinydrm.drm->dev;
458 int ret;
459
460 if (mipi->regulator) {
461 ret = regulator_enable(mipi->regulator);
462 if (ret) {
463 DRM_DEV_ERROR(dev, "Failed to enable regulator (%d)\n", ret);
464 return ret;
465 }
466 }
467
468 if (cond && mipi_dbi_display_is_on(mipi))
469 return 1;
470
471 mipi_dbi_hw_reset(mipi);
472 ret = mipi_dbi_command(mipi, MIPI_DCS_SOFT_RESET);
473 if (ret) {
474 DRM_DEV_ERROR(dev, "Failed to send reset command (%d)\n", ret);
475 if (mipi->regulator)
476 regulator_disable(mipi->regulator);
477 return ret;
478 }
479
480 /*
481 * If we did a hw reset, we know the controller is in Sleep mode and
482 * per MIPI DSC spec should wait 5ms after soft reset. If we didn't,
483 * we assume worst case and wait 120ms.
484 */
485 if (mipi->reset)
486 usleep_range(5000, 20000);
487 else
488 msleep(120);
489
490 return 0;
491}
492
493/**
494 * mipi_dbi_poweron_reset - MIPI DBI poweron and reset
495 * @mipi: MIPI DBI structure
496 *
497 * This function enables the regulator if used and does a hardware and software
498 * reset.
499 *
500 * Returns:
501 * Zero on success, or a negative error code.
502 */
503int mipi_dbi_poweron_reset(struct mipi_dbi *mipi)
504{
505 return mipi_dbi_poweron_reset_conditional(mipi, false);
506}
507EXPORT_SYMBOL(mipi_dbi_poweron_reset);
508
509/**
510 * mipi_dbi_poweron_conditional_reset - MIPI DBI poweron and conditional reset
511 * @mipi: MIPI DBI structure
512 *
513 * This function enables the regulator if used and if the display is off, it
514 * does a hardware and software reset. If mipi_dbi_display_is_on() determines
515 * that the display is on, no reset is performed.
516 *
517 * Returns:
518 * Zero if the controller was reset, 1 if the display was already on, or a
519 * negative error code.
520 */
521int mipi_dbi_poweron_conditional_reset(struct mipi_dbi *mipi)
522{
523 return mipi_dbi_poweron_reset_conditional(mipi, true);
524}
525EXPORT_SYMBOL(mipi_dbi_poweron_conditional_reset);
526
456#if IS_ENABLED(CONFIG_SPI) 527#if IS_ENABLED(CONFIG_SPI)
457 528
458/** 529/**