disp: msm: debugfs interface for sde connector to do DSI read

This change implements a new feature to read the cmds response
of the panel from sde connector interface. Sde connector opens
debugfs interface for all the connectors those have support for
cmd receive operation.

Sde connector init module creates rx_cmd debugfs file at
/<debugfs-root>/dri/0/DSI-1/ for DSI-1 connector.
Format for DSI command transfer:
echo "command bytes" > /<debugfs-root/dri/0/DSI-1/rx_cmd
byte-0: the length of received buffer
byte-1: data-type
byte-2: last command. always 0x01
byte-3: channel number
byte-4: flags. MIPI_DSI_MSG_*, must be set to 0xa
byte-5: 0x00
byte-6 and byte-7: command payload length
byte-8 to byte-[8+payload length]: command payload
Example:
echo "0x01 0x06 0x01 0x00 0x0a 0x00 0x00 0x01 0x0a" > rx_cmd
The command receive operations are allowed only if controller
(ex. DSI controller) is in active state.
Read the value of panel response:
cat /<debugfs-root>/dri/0/DSI-1/rx_cmd
returns the value of this command.
nothing - failure, xx xx - success.

Change-Id: I912b65d606e248c7a886d219f4363bf7766ee7b6
Signed-off-by: Yuan Zhao <yzhao@codeaurora.org>
Šī revīzija ir iekļauta:
Yuan Zhao
2020-05-12 14:44:03 +08:00
revīziju iesūtīja Gerrit - the friendly Code Review server
vecāks 4fbdcba865
revīzija 5bba78331d
5 mainīti faili ar 327 papildinājumiem un 18 dzēšanām

Parādīt failu

@@ -918,6 +918,58 @@ static int dsi_display_ctrl_get_host_init_state(struct dsi_display *dsi_display,
return rc;
}
static int dsi_display_cmd_rx(struct dsi_display *display,
struct dsi_cmd_desc *cmd)
{
struct dsi_display_ctrl *m_ctrl = NULL;
u32 mask = 0, flags = 0;
int rc = 0;
if (!display || !display->panel)
return -EINVAL;
m_ctrl = &display->ctrl[display->cmd_master_idx];
if (!m_ctrl || !m_ctrl->ctrl)
return -EINVAL;
/* acquire panel_lock to make sure no commands are in progress */
dsi_panel_acquire_panel_lock(display->panel);
if (!display->panel->panel_initialized) {
DSI_DEBUG("panel not initialized\n");
goto release_panel_lock;
}
rc = dsi_display_clk_ctrl(display->dsi_clk_handle,
DSI_ALL_CLKS, DSI_CLK_ON);
if (rc)
goto release_panel_lock;
mask = BIT(DSI_FIFO_OVERFLOW) | BIT(DSI_FIFO_UNDERFLOW);
dsi_display_mask_ctrl_error_interrupts(display, mask, true);
rc = dsi_display_cmd_engine_enable(display);
if (rc) {
DSI_ERR("cmd engine enable failed rc = %d\n", rc);
goto error;
}
flags |= (DSI_CTRL_CMD_FETCH_MEMORY | DSI_CTRL_CMD_READ |
DSI_CTRL_CMD_CUSTOM_DMA_SCHED);
rc = dsi_ctrl_cmd_transfer(m_ctrl->ctrl, &cmd->msg, &flags);
if (rc <= 0)
DSI_ERR("rx cmd transfer failed rc = %d\n", rc);
dsi_display_cmd_engine_disable(display);
error:
dsi_display_mask_ctrl_error_interrupts(display, mask, false);
dsi_display_clk_ctrl(display->dsi_clk_handle,
DSI_ALL_CLKS, DSI_CLK_OFF);
release_panel_lock:
dsi_panel_release_panel_lock(display->panel);
return rc;
}
int dsi_display_cmd_transfer(struct drm_connector *connector,
void *display, const char *cmd_buf,
u32 cmd_buf_len)
@@ -984,6 +1036,48 @@ static void _dsi_display_continuous_clk_ctrl(struct dsi_display *display,
}
}
int dsi_display_cmd_receive(void *display, const char *cmd_buf,
u32 cmd_buf_len, u8 *recv_buf, u32 recv_buf_len)
{
struct dsi_display *dsi_display = display;
struct dsi_cmd_desc cmd = {};
u8 cmd_payload[MAX_CMD_PAYLOAD_SIZE] = {0};
bool state = false;
int rc = -1;
if (!dsi_display || !cmd_buf || !recv_buf) {
DSI_ERR("[DSI] invalid params\n");
return -EINVAL;
}
rc = dsi_display_cmd_prepare(cmd_buf, cmd_buf_len,
&cmd, cmd_payload, MAX_CMD_PAYLOAD_SIZE);
if (rc) {
DSI_ERR("[DSI] command prepare failed, rc = %d\n", rc);
return rc;
}
cmd.msg.rx_buf = recv_buf;
cmd.msg.rx_len = recv_buf_len;
mutex_lock(&dsi_display->display_lock);
rc = dsi_display_ctrl_get_host_init_state(dsi_display, &state);
if (rc || !state) {
DSI_ERR("[DSI] Invalid host state = %d rc = %d\n",
state, rc);
rc = -EPERM;
goto end;
}
rc = dsi_display_cmd_rx(dsi_display, &cmd);
if (rc <= 0)
DSI_ERR("[DSI] Display command receive failed, rc=%d\n", rc);
end:
mutex_unlock(&dsi_display->display_lock);
return rc;
}
int dsi_display_soft_reset(void *display)
{
struct dsi_display *dsi_display;