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:02 +0200
committerTomi Valkeinen <tomi.valkeinen@ti.com>2020-12-15 16:08:23 +0200
commit2a4703c25f75d44ecdf0b718bbb53d4ec3170422 (patch)
tree26011cfa143f876412736d19fc1694f1871a05fb /drivers/gpu/drm/omapdrm/dss/dsi.c
parent66c6bf3af6e6838ae4ba76b6258fe4a382f00c55 (diff)
downloadlinux-2a4703c25f75d44ecdf0b718bbb53d4ec3170422.tar.bz2
drm/omap: dsi: move panel refresh function to host
This moves the panel refresh/update function from the panel driver into the DSI host driver to prepare for common drm_panel support. Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-30-tomi.valkeinen@ti.com
Diffstat (limited to 'drivers/gpu/drm/omapdrm/dss/dsi.c')
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dsi.c91
1 files changed, 81 insertions, 10 deletions
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index c7f366ae4764..56cff14061ee 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -214,6 +214,9 @@ static void dsi_display_uninit_dispc(struct dsi_data *dsi);
static int dsi_vc_send_null(struct dsi_data *dsi, int channel);
+static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi,
+ const struct mipi_dsi_msg *msg);
+
/* DSI PLL HSDIV indices */
#define HSDIV_DISPC 0
#define HSDIV_DSI 1
@@ -384,9 +387,6 @@ struct dsi_data {
struct delayed_work ulps_work;
- void (*framedone_callback)(int, void *);
- void *framedone_data;
-
struct delayed_work framedone_timeout_work;
#ifdef DSI_CATCH_MISSING_TE
@@ -3804,8 +3804,6 @@ static void dsi_handle_framedone(struct dsi_data *dsi, int error)
dsi_set_ulps_auto(dsi, true);
dsi_bus_unlock(dsi);
- dsi->framedone_callback(error, dsi->framedone_data);
-
if (!error)
dsi_perf_show(dsi, "DISPC");
}
@@ -3837,6 +3835,8 @@ static void dsi_framedone_irq_callback(void *data)
cancel_delayed_work(&dsi->framedone_timeout_work);
+ DSSDBG("Framedone received!\n");
+
dsi_handle_framedone(dsi, 0);
}
@@ -3853,17 +3853,69 @@ static int _dsi_update(struct dsi_data *dsi)
return 0;
}
-static int dsi_update(struct omap_dss_device *dssdev, int channel,
- void (*callback)(int, void *), void *data)
+static int _dsi_update_window(struct dsi_data *dsi, int channel,
+ int x, int y, int w, int h)
+{
+ int x1 = x, x2 = (x + w - 1);
+ int y1 = y, y2 = (y + h - 1);
+ u8 payloadX[5] = { MIPI_DCS_SET_COLUMN_ADDRESS,
+ x1 >> 8, x1 & 0xff, x2 >> 8, x2 & 0xff };
+ u8 payloadY[5] = { MIPI_DCS_SET_PAGE_ADDRESS,
+ y1 >> 8, y1 & 0xff, y2 >> 8, y2 & 0xff };
+ struct mipi_dsi_msg msgX = { 0 }, msgY = { 0 };
+ int ret;
+
+ WARN_ON(!dsi_bus_is_locked(dsi));
+
+ msgX.type = MIPI_DSI_DCS_LONG_WRITE;
+ msgX.channel = channel;
+ msgX.tx_buf = payloadX;
+ msgX.tx_len = sizeof(payloadX);
+
+ msgY.type = MIPI_DSI_DCS_LONG_WRITE;
+ msgY.channel = channel;
+ msgY.tx_buf = payloadY;
+ msgY.tx_len = sizeof(payloadY);
+
+ ret = _omap_dsi_host_transfer(dsi, &msgX);
+ if (ret != 0)
+ return ret;
+
+ return _omap_dsi_host_transfer(dsi, &msgY);
+}
+
+static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
{
struct dsi_data *dsi = to_dsi_data(dssdev);
+ int r;
+
+ if (channel > 3)
+ return -EINVAL;
dsi_bus_lock(dsi);
+
+ if (!dsi->vc[channel].dest) {
+ r = -ENODEV;
+ goto err;
+ }
+
+ if (dsi->vm.hactive == 0 || dsi->vm.vactive == 0) {
+ r = -EINVAL;
+ goto err;
+ }
+
+ DSSDBG("dsi_update_channel: %d", channel);
+
dsi_set_ulps_auto(dsi, false);
+ r = _dsi_update_window(dsi, channel, 0, 0, dsi->vm.hactive,
+ dsi->vm.vactive);
+ if (r < 0) {
+ DSSWARN("window update error: %d\n", r);
+ goto err;
+ }
+
dsi->update_channel = channel;
- dsi->framedone_callback = callback;
- dsi->framedone_data = data;
if (dsi->te_enabled && dsi->te_gpio) {
schedule_delayed_work(&dsi->te_timeout_work,
@@ -3874,6 +3926,25 @@ static int dsi_update(struct omap_dss_device *dssdev, int channel,
}
return 0;
+
+err:
+ dsi_set_ulps_auto(dsi, true);
+ dsi_bus_unlock(dsi);
+ return r;
+}
+
+static int dsi_update_all(struct omap_dss_device *dssdev)
+{
+ unsigned int i;
+ int r;
+
+ for (i = 0; i < 4; i++) {
+ r = dsi_update_channel(dssdev, i);
+ if (r && r != -ENODEV)
+ return r;
+ }
+
+ return r;
}
/* Display funcs */
@@ -4875,7 +4946,7 @@ static const struct omap_dss_device_ops dsi_ops = {
.enable_video_output = dsi_enable_video_output,
.disable_video_output = dsi_disable_video_output,
- .update = dsi_update,
+ .update = dsi_update_all,
},
};