Commit 8350ac8e authored by Tomi Valkeinen's avatar Tomi Valkeinen

drm/omap: dsi: send nop instead of page & column

The OMAP DSI command mode panel driver used to send page & column
address before each frame update, and this code was moved into the DSI
host driver when converting it to the DRM bridge model.

However, it's not really required to send the page & column address
before each frame. It's also something that doesn't really belong to the
DSI host driver, so we should drop the code.

That said, frame updates break if we don't send _something_ between the
frames. A NOP command does the trick.

It is not clear if this behavior is as expected from a DSI command mode
frame transfer, or is it a feature/issue with OMAP DSI driver, or a
feature/issue in the command mode panel used.

Most likely this is related to the following from the DSI spec:

"To enable PHY synchronization the host processor should periodically
end HS transmission and drive the Data Lanes to the LP state. This
transition should take place at least once per frame."
Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-62-tomi.valkeinen@ti.com
parent c50c2d2d
...@@ -3881,35 +3881,19 @@ static int _dsi_update(struct dsi_data *dsi) ...@@ -3881,35 +3881,19 @@ static int _dsi_update(struct dsi_data *dsi)
return 0; return 0;
} }
static int _dsi_update_window(struct dsi_data *dsi, int channel, static int _dsi_send_nop(struct dsi_data *dsi, int channel)
int x, int y, int w, int h) {
{ const u8 payload[] = { MIPI_DCS_NOP };
int x1 = x, x2 = (x + w - 1); const struct mipi_dsi_msg msg = {
int y1 = y, y2 = (y + h - 1); .channel = channel,
u8 payloadX[5] = { MIPI_DCS_SET_COLUMN_ADDRESS, .type = MIPI_DSI_DCS_SHORT_WRITE,
x1 >> 8, x1 & 0xff, x2 >> 8, x2 & 0xff }; .tx_len = 1,
u8 payloadY[5] = { MIPI_DCS_SET_PAGE_ADDRESS, .tx_buf = payload,
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)); WARN_ON(!dsi_bus_is_locked(dsi));
msgX.type = MIPI_DSI_DCS_LONG_WRITE; return _omap_dsi_host_transfer(dsi, &msg);
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) static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
...@@ -3941,10 +3925,14 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int channel) ...@@ -3941,10 +3925,14 @@ static int dsi_update_channel(struct omap_dss_device *dssdev, int channel)
dsi_set_ulps_auto(dsi, false); dsi_set_ulps_auto(dsi, false);
r = _dsi_update_window(dsi, channel, 0, 0, dsi->vm.hactive, /*
dsi->vm.vactive); * Send NOP between the frames. If we don't send something here, the
* updates stop working. This is probably related to DSI spec stating
* that the DSI host should transition to LP at least once per frame.
*/
r = _dsi_send_nop(dsi, channel);
if (r < 0) { if (r < 0) {
DSSWARN("window update error: %d\n", r); DSSWARN("failed to send nop between frames: %d\n", r);
goto err; goto err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment