} 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
* to power itself down completely
*/
struct {
+ unsigned int reset;
+ unsigned int init;
unsigned int prepare;
unsigned int enable;
unsigned int disable;
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;
return -EINVAL;
}
- if (err)
+ if (err < 0)
dev_err(panel->dev, "failed to write dcs cmd: %d\n",
err);
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);
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;
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);
}
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,
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;
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,