summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/omapdrm/dss/dsi.c
diff options
context:
space:
mode:
authorSebastian Reichel <sebastian.reichel@collabora.com>2020-12-15 12:46:01 +0200
committerTomi Valkeinen <tomi.valkeinen@ti.com>2020-12-15 16:08:23 +0200
commit66c6bf3af6e6838ae4ba76b6258fe4a382f00c55 (patch)
treeeb59d6354c62ada2f1fa5b38d40a3ade1fcf5467 /drivers/gpu/drm/omapdrm/dss/dsi.c
parent9f0eb51e3c658a767c3fa89b3894f45f5319c208 (diff)
downloadlinux-66c6bf3af6e6838ae4ba76b6258fe4a382f00c55.tar.gz
linux-66c6bf3af6e6838ae4ba76b6258fe4a382f00c55.tar.bz2
linux-66c6bf3af6e6838ae4ba76b6258fe4a382f00c55.zip
drm/omap: dsi: do ULPS in host driver
Move ULPS handling into the DSI host controller, so that we no longer need a custom API for the DSI client. Note that for now ULPS is always disabled. Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-29-tomi.valkeinen@ti.com
Diffstat (limited to 'drivers/gpu/drm/omapdrm/dss/dsi.c')
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dsi.c71
1 files changed, 53 insertions, 18 deletions
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 5853f89aebbe..c7f366ae4764 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -207,6 +207,8 @@ struct dsi_reg { u16 module; u16 idx; };
typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
struct dsi_data;
+static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable);
+
static int dsi_display_init_dispc(struct dsi_data *dsi);
static void dsi_display_uninit_dispc(struct dsi_data *dsi);
@@ -378,6 +380,9 @@ struct dsi_data {
bool te_enabled;
bool ulps_enabled;
+ bool ulps_auto_idle;
+
+ struct delayed_work ulps_work;
void (*framedone_callback)(int, void *);
void *framedone_data;
@@ -3796,6 +3801,7 @@ static void dsi_handle_framedone(struct dsi_data *dsi, int error)
REG_FLD_MOD(dsi, DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
}
+ dsi_set_ulps_auto(dsi, true);
dsi_bus_unlock(dsi);
dsi->framedone_callback(error, dsi->framedone_data);
@@ -3853,6 +3859,7 @@ static int dsi_update(struct omap_dss_device *dssdev, int channel,
struct dsi_data *dsi = to_dsi_data(dssdev);
dsi_bus_lock(dsi);
+ dsi_set_ulps_auto(dsi, false);
dsi->update_channel = channel;
dsi->framedone_callback = callback;
@@ -4121,22 +4128,6 @@ static void dsi_display_disable(struct omap_dss_device *dssdev)
dsi_bus_unlock(dsi);
}
-static void dsi_ulps(struct omap_dss_device *dssdev, bool enable)
-{
- struct dsi_data *dsi = to_dsi_data(dssdev);
-
- DSSDBG("dsi_ulps %d\n", enable);
-
- dsi_bus_lock(dsi);
-
- if (enable)
- _dsi_display_disable(dsi, false, true);
- else
- _dsi_display_enable(dsi);
-
- dsi_bus_unlock(dsi);
-}
-
static int dsi_enable_te(struct dsi_data *dsi, bool enable)
{
dsi->te_enabled = enable;
@@ -4151,6 +4142,42 @@ static int dsi_enable_te(struct dsi_data *dsi, bool enable)
return 0;
}
+static void omap_dsi_ulps_work_callback(struct work_struct *work)
+{
+ struct dsi_data *dsi = container_of(work, struct dsi_data,
+ ulps_work.work);
+
+ dsi_bus_lock(dsi);
+
+ dsi_enable_te(dsi, false);
+
+ _dsi_display_disable(dsi, false, true);
+
+ dsi_bus_unlock(dsi);
+}
+
+static void dsi_set_ulps_auto(struct dsi_data *dsi, bool enable)
+{
+ WARN_ON(!dsi_bus_is_locked(dsi));
+
+ if (!dsi->ulps_auto_idle)
+ return;
+
+ if (enable) {
+ schedule_delayed_work(&dsi->ulps_work, msecs_to_jiffies(250));
+ } else {
+ cancel_delayed_work_sync(&dsi->ulps_work);
+
+ if (!dsi->ulps_enabled)
+ return;
+
+ dsi_bus_lock(dsi);
+ _dsi_display_enable(dsi);
+ dsi_enable_te(dsi, true);
+ dsi_bus_unlock(dsi);
+ }
+}
+
#ifdef PRINT_VERBOSE_VM_TIMINGS
static void print_dsi_vm(const char *str,
const struct omap_dss_dsi_videomode_timings *t)
@@ -4801,7 +4828,9 @@ static ssize_t omap_dsi_host_transfer(struct mipi_dsi_host *host,
int r;
dsi_bus_lock(dsi);
+ dsi_set_ulps_auto(dsi, false);
r = _omap_dsi_host_transfer(dsi, msg);
+ dsi_set_ulps_auto(dsi, true);
dsi_bus_unlock(dsi);
return r;
@@ -4841,8 +4870,6 @@ static const struct omap_dss_device_ops dsi_ops = {
.disable = dsi_display_disable,
.dsi = {
- .ulps = dsi_ulps,
-
.set_config = dsi_set_config,
.enable_video_output = dsi_enable_video_output,
@@ -4971,6 +4998,14 @@ static int omap_dsi_host_attach(struct mipi_dsi_host *host,
dsi->vc[channel].dest = client;
dsi->pix_fmt = client->format;
+ INIT_DEFERRABLE_WORK(&dsi->ulps_work,
+ omap_dsi_ulps_work_callback);
+
+ dsi_bus_lock(dsi);
+ dsi->ulps_auto_idle = false;
+ dsi_set_ulps_auto(dsi, true);
+ dsi_bus_unlock(dsi);
+
return 0;
}