drm/tinydrm/mipi-dbi: Add poweron-reset functions
authorNoralf Trønnes <noralf@tronnes.org>
Wed, 10 Jan 2018 18:59:37 +0000 (19:59 +0100)
committerNoralf Trønnes <noralf@tronnes.org>
Mon, 15 Jan 2018 14:13:47 +0000 (15:13 +0100)
Split out common poweron-reset functionality.

Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
Reviewed-by: David Lechner <david@lechnology.com>
Tested-by: David Lechner <david@lechnology.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180110185940.53841-5-noralf@tronnes.org
drivers/gpu/drm/tinydrm/mi0283qt.c
drivers/gpu/drm/tinydrm/mipi-dbi.c
drivers/gpu/drm/tinydrm/st7586.c
drivers/gpu/drm/tinydrm/st7735r.c
include/drm/tinydrm/mipi-dbi.h

index c69a4d958f246f13aff3dc01d0e4e9ffa3ac6d85..1617405faed4bb7d50eaae1a0f9a42f407f25d7b 100644 (file)
 
 static int mi0283qt_init(struct mipi_dbi *mipi)
 {
-       struct tinydrm_device *tdev = &mipi->tinydrm;
-       struct device *dev = tdev->drm->dev;
        u8 addr_mode;
        int ret;
 
        DRM_DEBUG_KMS("\n");
 
-       ret = regulator_enable(mipi->regulator);
-       if (ret) {
-               DRM_DEV_ERROR(dev, "Failed to enable regulator %d\n", ret);
+       ret = mipi_dbi_poweron_conditional_reset(mipi);
+       if (ret < 0)
                return ret;
-       }
-
-       /* Avoid flicker by skipping setup if the bootloader has done it */
-       if (mipi_dbi_display_is_on(mipi))
+       if (ret == 1)
                return 0;
 
-       mipi_dbi_hw_reset(mipi);
-       ret = mipi_dbi_command(mipi, MIPI_DCS_SOFT_RESET);
-       if (ret) {
-               DRM_DEV_ERROR(dev, "Error sending command %d\n", ret);
-               regulator_disable(mipi->regulator);
-               return ret;
-       }
-
-       msleep(20);
-
        mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_OFF);
 
        mipi_dbi_command(mipi, ILI9341_PWCTRLB, 0x00, 0x83, 0x30);
index 1c8ef0c4d6d43fef9ea9b2e910e7064e8d962a61..3e879d605ed3559bef815989108168ba604edabe 100644 (file)
@@ -463,6 +463,7 @@ bool mipi_dbi_display_is_on(struct mipi_dbi *mipi)
 
        val &= ~DCS_POWER_MODE_RESERVED_MASK;
 
+       /* The poweron/reset value is 08h DCS_POWER_MODE_DISPLAY_NORMAL_MODE */
        if (val != (DCS_POWER_MODE_DISPLAY |
            DCS_POWER_MODE_DISPLAY_NORMAL_MODE | DCS_POWER_MODE_SLEEP_MODE))
                return false;
@@ -473,6 +474,78 @@ bool mipi_dbi_display_is_on(struct mipi_dbi *mipi)
 }
 EXPORT_SYMBOL(mipi_dbi_display_is_on);
 
+static int mipi_dbi_poweron_reset_conditional(struct mipi_dbi *mipi, bool cond)
+{
+       struct device *dev = mipi->tinydrm.drm->dev;
+       int ret;
+
+       if (mipi->regulator) {
+               ret = regulator_enable(mipi->regulator);
+               if (ret) {
+                       DRM_DEV_ERROR(dev, "Failed to enable regulator (%d)\n", ret);
+                       return ret;
+               }
+       }
+
+       if (cond && mipi_dbi_display_is_on(mipi))
+               return 1;
+
+       mipi_dbi_hw_reset(mipi);
+       ret = mipi_dbi_command(mipi, MIPI_DCS_SOFT_RESET);
+       if (ret) {
+               DRM_DEV_ERROR(dev, "Failed to send reset command (%d)\n", ret);
+               if (mipi->regulator)
+                       regulator_disable(mipi->regulator);
+               return ret;
+       }
+
+       /*
+        * If we did a hw reset, we know the controller is in Sleep mode and
+        * per MIPI DSC spec should wait 5ms after soft reset. If we didn't,
+        * we assume worst case and wait 120ms.
+        */
+       if (mipi->reset)
+               usleep_range(5000, 20000);
+       else
+               msleep(120);
+
+       return 0;
+}
+
+/**
+ * mipi_dbi_poweron_reset - MIPI DBI poweron and reset
+ * @mipi: MIPI DBI structure
+ *
+ * This function enables the regulator if used and does a hardware and software
+ * reset.
+ *
+ * Returns:
+ * Zero on success, or a negative error code.
+ */
+int mipi_dbi_poweron_reset(struct mipi_dbi *mipi)
+{
+       return mipi_dbi_poweron_reset_conditional(mipi, false);
+}
+EXPORT_SYMBOL(mipi_dbi_poweron_reset);
+
+/**
+ * mipi_dbi_poweron_conditional_reset - MIPI DBI poweron and conditional reset
+ * @mipi: MIPI DBI structure
+ *
+ * This function enables the regulator if used and if the display is off, it
+ * does a hardware and software reset. If mipi_dbi_display_is_on() determines
+ * that the display is on, no reset is performed.
+ *
+ * Returns:
+ * Zero if the controller was reset, 1 if the display was already on, or a
+ * negative error code.
+ */
+int mipi_dbi_poweron_conditional_reset(struct mipi_dbi *mipi)
+{
+       return mipi_dbi_poweron_reset_conditional(mipi, true);
+}
+EXPORT_SYMBOL(mipi_dbi_poweron_conditional_reset);
+
 #if IS_ENABLED(CONFIG_SPI)
 
 /**
index 9fd4423c8e7047a2498a08bcc154c1249ec7003f..a6396ef9cc4ae7d7c58dcd51893f78005b9a022e 100644 (file)
@@ -179,19 +179,16 @@ static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe,
 {
        struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
        struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
-       struct device *dev = tdev->drm->dev;
        int ret;
        u8 addr_mode;
 
        DRM_DEBUG_KMS("\n");
 
-       mipi_dbi_hw_reset(mipi);
-       ret = mipi_dbi_command(mipi, ST7586_AUTO_READ_CTRL, 0x9f);
-       if (ret) {
-               DRM_DEV_ERROR(dev, "Error sending command %d\n", ret);
+       ret = mipi_dbi_poweron_reset(mipi);
+       if (ret)
                return;
-       }
 
+       mipi_dbi_command(mipi, ST7586_AUTO_READ_CTRL, 0x9f);
        mipi_dbi_command(mipi, ST7586_OTP_RW_CTRL, 0x00);
 
        msleep(10);
index 1f38e15da67684762e8df2216174c871036cd062..08b4fb18edb657f57df55b6cedc67bccdd11d4ee 100644 (file)
@@ -40,19 +40,14 @@ static void jd_t18003_t01_pipe_enable(struct drm_simple_display_pipe *pipe,
 {
        struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
        struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
-       struct device *dev = tdev->drm->dev;
        int ret;
        u8 addr_mode;
 
        DRM_DEBUG_KMS("\n");
 
-       mipi_dbi_hw_reset(mipi);
-
-       ret = mipi_dbi_command(mipi, MIPI_DCS_SOFT_RESET);
-       if (ret) {
-               DRM_DEV_ERROR(dev, "Error sending command %d\n", ret);
+       ret = mipi_dbi_poweron_reset(mipi);
+       if (ret)
                return;
-       }
 
        msleep(150);
 
index 6441d9a9161a7b340b493730d63d7b4686a47812..795a4a2205bb804a2a6e7b65260c91b2f3b0b9b0 100644 (file)
@@ -73,6 +73,8 @@ void mipi_dbi_pipe_enable(struct drm_simple_display_pipe *pipe,
 void mipi_dbi_pipe_disable(struct drm_simple_display_pipe *pipe);
 void mipi_dbi_hw_reset(struct mipi_dbi *mipi);
 bool mipi_dbi_display_is_on(struct mipi_dbi *mipi);
+int mipi_dbi_poweron_reset(struct mipi_dbi *mipi);
+int mipi_dbi_poweron_conditional_reset(struct mipi_dbi *mipi);
 u32 mipi_dbi_spi_cmd_max_speed(struct spi_device *spi, size_t len);
 
 int mipi_dbi_command_read(struct mipi_dbi *mipi, u8 cmd, u8 *val);