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:

revīziju iesūtīja
Gerrit - the friendly Code Review server

vecāks
4fbdcba865
revīzija
5bba78331d
@@ -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;
|
||||
|
Atsaukties uz šo jaunā problēmā
Block a user