Merge branch 'firefly' into squashCM
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / panel / panel-simple.c
index cf02e19ae00fa1187ec37dc675452ed5c5c2354b..211f331b7a7d0a6e2f8aa97105eaf8d62c0a379e 100644 (file)
@@ -70,6 +70,10 @@ struct panel_desc {
        } size;
 
        /**
+        * @reset: the time (in milliseconds) indicates the delay time
+        *         after the panel to operate reset gpio
+        * @init: the time (in milliseconds) that it takes for the panel to
+        *           power on and dsi host can send command to panel
         * @prepare: the time (in milliseconds) that it takes for the panel to
         *           become ready and start receiving video data
         * @enable: the time (in milliseconds) that it takes for the panel to
@@ -81,6 +85,8 @@ struct panel_desc {
         *             to power itself down completely
         */
        struct {
+               unsigned int reset;
+               unsigned int init;
                unsigned int prepare;
                unsigned int enable;
                unsigned int disable;
@@ -105,7 +111,6 @@ struct panel_simple {
 
        struct gpio_desc *enable_gpio;
        struct gpio_desc *reset_gpio;
-       unsigned int reset_delay;
 
        struct dsi_panel_cmds *on_cmds;
        struct dsi_panel_cmds *off_cmds;
@@ -229,7 +234,7 @@ static int panel_simple_dsi_send_cmds(struct panel_simple *panel,
                        return -EINVAL;
                }
 
-               if (err)
+               if (err < 0)
                        dev_err(panel->dev, "failed to write dcs cmd: %d\n",
                                err);
 
@@ -330,6 +335,25 @@ static int panel_simple_of_get_native_mode(struct panel_simple *panel)
        return 1;
 }
 
+static int panel_simple_loader_protect(struct drm_panel *panel, bool on)
+{
+       struct panel_simple *p = to_panel_simple(panel);
+       int err;
+
+       if (on) {
+               err = regulator_enable(p->supply);
+               if (err < 0) {
+                       dev_err(panel->dev, "failed to enable supply: %d\n",
+                               err);
+                       return err;
+               }
+       } else {
+               regulator_disable(p->supply);
+       }
+
+       return 0;
+}
+
 static int panel_simple_disable(struct drm_panel *panel)
 {
        struct panel_simple *p = to_panel_simple(panel);
@@ -403,12 +427,21 @@ static int panel_simple_prepare(struct drm_panel *panel)
        if (p->reset_gpio)
                gpiod_direction_output(p->reset_gpio, 1);
 
-       if (p->reset_delay)
-               msleep(p->reset_delay);
+       if (p->desc && p->desc->delay.reset)
+               msleep(p->desc->delay.reset);
 
        if (p->reset_gpio)
                gpiod_direction_output(p->reset_gpio, 0);
 
+       if (p->desc && p->desc->delay.init)
+               msleep(p->desc->delay.init);
+
+       if (p->on_cmds) {
+               err = panel_simple_dsi_send_cmds(p, p->on_cmds);
+               if (err)
+                       dev_err(p->dev, "failed to send on cmds\n");
+       }
+
        p->prepared = true;
 
        return 0;
@@ -417,17 +450,10 @@ static int panel_simple_prepare(struct drm_panel *panel)
 static int panel_simple_enable(struct drm_panel *panel)
 {
        struct panel_simple *p = to_panel_simple(panel);
-       int err;
 
        if (p->enabled)
                return 0;
 
-       if (p->on_cmds) {
-               err = panel_simple_dsi_send_cmds(p, p->on_cmds);
-               if (err)
-                       dev_err(p->dev, "failed to send on cmds\n");
-       }
-
        if (p->desc && p->desc->delay.enable)
                msleep(p->desc->delay.enable);
 
@@ -486,6 +512,7 @@ static int panel_simple_get_timings(struct drm_panel *panel,
 }
 
 static const struct drm_panel_funcs panel_simple_funcs = {
+       .loader_protect = panel_simple_loader_protect,
        .disable = panel_simple_disable,
        .unprepare = panel_simple_unprepare,
        .prepare = panel_simple_prepare,
@@ -513,14 +540,18 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
 
        if (!of_property_read_u32(dev->of_node, "bus-format", &val))
                of_desc->bus_format = val;
-       if (!of_property_read_u32(dev->of_node, "delay,prepare", &val))
+       if (!of_property_read_u32(dev->of_node, "prepare-delay-ms", &val))
                of_desc->delay.prepare = val;
-       if (!of_property_read_u32(dev->of_node, "delay,enable", &val))
+       if (!of_property_read_u32(dev->of_node, "enable-delay-ms", &val))
                of_desc->delay.enable = val;
-       if (!of_property_read_u32(dev->of_node, "delay,disable", &val))
+       if (!of_property_read_u32(dev->of_node, "disable-delay-ms", &val))
                of_desc->delay.disable = val;
-       if (!of_property_read_u32(dev->of_node, "delay,unprepare", &val))
+       if (!of_property_read_u32(dev->of_node, "unprepare-delay-ms", &val))
                of_desc->delay.unprepare = val;
+       if (!of_property_read_u32(dev->of_node, "reset-delay-ms", &val))
+               of_desc->delay.reset = val;
+       if (!of_property_read_u32(dev->of_node, "init-delay-ms", &val))
+               of_desc->delay.init = val;
 
        panel->enabled = false;
        panel->prepared = false;
@@ -1945,9 +1976,6 @@ static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi)
        if (!of_property_read_u32(dsi->dev.of_node, "dsi,lanes", &val))
                dsi->lanes = val;
 
-       if (!of_property_read_u32(dsi->dev.of_node, "reset-delay-ms", &val))
-               panel->reset_delay = val;
-
        data = of_get_property(dsi->dev.of_node, "panel-init-sequence", &len);
        if (data) {
                panel->on_cmds = devm_kzalloc(&dsi->dev,