disp: msm: dp: optimize sim function handling in dp_debug

Remove edid/dpcd simulation function from dp_debug and calls to
sim bridge instead to simplify dp_debug module. Also add mst edid
support and mst hpd simulation from aux level.

Move selected mode from dp_debug module to dp_panel module to
simplify mst handling and decouple dp_debug from main dp driver.

Remove custom edid/dpcd mode from dp_panel and dp_aux module.
Remove mst connector list handling from dp_display module.

Change-Id: Ife1d2deb0e353f0a9695b7b90e5bf3459e1c81f7
Signed-off-by: Xiaowen Wu <wxiaowen@codeaurora.org>
Signed-off-by: Karim Henain <khenain@codeaurora.org>
Signed-off-by: Sudarsan Ramesh <sudarame@codeaurora.org>
这个提交包含在:
Xiaowen Wu
2020-07-16 10:47:50 -04:00
提交者 Sudarsan Ramesh
父节点 24d245556e
当前提交 67ce55687b
修改 10 个文件,包含 328 行新增821 行删除

查看文件

@@ -29,6 +29,7 @@ struct dp_aux_private {
struct dp_aux_bridge *aux_bridge;
struct dp_aux_bridge *sim_bridge;
bool bridge_in_transfer;
bool sim_in_transfer;
bool cmd_busy;
bool native;
@@ -43,9 +44,6 @@ struct dp_aux_private {
u32 retry_cnt;
atomic_t aborted;
u8 *dpcd;
u8 *edid;
};
#ifdef CONFIG_DYNAMIC_DEBUG
@@ -477,114 +475,6 @@ static inline bool dp_aux_is_sideband_msg(u32 address, size_t size)
(address >= 0x2000 && address + size < 0x2200);
}
static ssize_t dp_aux_transfer_debug(struct drm_dp_aux *drm_aux,
struct drm_dp_aux_msg *msg)
{
u32 timeout;
ssize_t ret;
struct dp_aux_private *aux = container_of(drm_aux,
struct dp_aux_private, drm_aux);
mutex_lock(&aux->mutex);
ret = dp_aux_transfer_ready(aux, msg, false);
if (ret)
goto end;
aux->aux_error_num = DP_AUX_ERR_NONE;
if (!aux->dpcd || !aux->edid) {
DP_ERR("invalid aux/dpcd structure\n");
goto end;
}
if ((msg->address + msg->size) > SZ_4K &&
!dp_aux_is_sideband_msg(msg->address, msg->size)) {
DP_DEBUG("invalid dpcd access: addr=0x%x, size=0x%lx\n",
msg->address, msg->size);
goto address_error;
}
if (aux->native) {
mutex_lock(aux->dp_aux.access_lock);
aux->dp_aux.reg = msg->address;
aux->dp_aux.read = aux->read;
aux->dp_aux.size = msg->size;
if (!aux->read)
memcpy(aux->dpcd + msg->address,
msg->buffer, msg->size);
reinit_completion(&aux->comp);
mutex_unlock(aux->dp_aux.access_lock);
timeout = wait_for_completion_timeout(&aux->comp, HZ * 2);
if (!timeout) {
DP_ERR("%s timeout: 0x%x\n",
aux->read ? "read" : "write",
msg->address);
atomic_set(&aux->aborted, 1);
ret = -ETIMEDOUT;
goto end;
}
mutex_lock(aux->dp_aux.access_lock);
if (dp_aux_is_sideband_msg(msg->address, msg->size)) {
if (!aux->sim_bridge || !aux->sim_bridge->transfer) {
DP_ERR("no mst bridge available\n");
atomic_set(&aux->aborted, 1);
ret = -ETIMEDOUT;
goto end;
}
ret = aux->sim_bridge->transfer(aux->sim_bridge,
drm_aux, msg);
} else if (aux->read) {
memcpy(msg->buffer, aux->dpcd + msg->address,
msg->size);
}
mutex_unlock(aux->dp_aux.access_lock);
aux->aux_error_num = DP_AUX_ERR_NONE;
} else {
if (aux->read && msg->address == 0x50) {
memcpy(msg->buffer,
aux->edid + aux->offset - 16,
msg->size);
}
}
if (aux->aux_error_num == DP_AUX_ERR_NONE) {
dp_aux_hex_dump(drm_aux, msg);
if (!aux->read)
memset(msg->buffer, 0, msg->size);
msg->reply = aux->native ?
DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
} else {
/* Reply defer to retry */
msg->reply = aux->native ?
DP_AUX_NATIVE_REPLY_DEFER : DP_AUX_I2C_REPLY_DEFER;
}
ret = msg->size;
goto end;
address_error:
memset(msg->buffer, 0, msg->size);
ret = msg->size;
end:
if (ret == -ETIMEDOUT)
aux->dp_aux.state |= DP_STATE_AUX_TIMEOUT;
aux->dp_aux.reg = 0xFFFF;
aux->dp_aux.read = true;
aux->dp_aux.size = 0;
mutex_unlock(&aux->mutex);
return ret;
}
/*
* This function does the real job to process an AUX transaction.
* It will call aux_reset() function to reset the AUX channel,
@@ -664,6 +554,28 @@ static ssize_t dp_aux_bridge_transfer(struct drm_dp_aux *drm_aux,
return size;
}
static ssize_t dp_aux_transfer_debug(struct drm_dp_aux *drm_aux,
struct drm_dp_aux_msg *msg)
{
struct dp_aux_private *aux = container_of(drm_aux,
struct dp_aux_private, drm_aux);
ssize_t size;
if (aux->sim_in_transfer) {
if (aux->aux_bridge && aux->aux_bridge->transfer)
size = dp_aux_bridge_transfer(drm_aux, msg);
else
size = dp_aux_transfer(drm_aux, msg);
} else {
aux->sim_in_transfer = true;
size = aux->sim_bridge->transfer(aux->sim_bridge,
drm_aux, msg);
aux->sim_in_transfer = false;
}
return size;
}
static void dp_aux_reset_phy_config_indices(struct dp_aux_cfg *aux_cfg)
{
int i = 0;
@@ -758,24 +670,8 @@ static void dp_aux_deregister(struct dp_aux *dp_aux)
drm_dp_aux_unregister(&aux->drm_aux);
}
static void dp_aux_dpcd_updated(struct dp_aux *dp_aux)
{
struct dp_aux_private *aux;
if (!dp_aux) {
DP_ERR("invalid input\n");
return;
}
aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
/* make sure wait has started */
usleep_range(20, 30);
complete(&aux->comp);
}
static void dp_aux_set_sim_mode(struct dp_aux *dp_aux, bool en,
u8 *edid, u8 *dpcd, struct dp_aux_bridge *sim_bridge)
static void dp_aux_set_sim_mode(struct dp_aux *dp_aux,
struct dp_aux_bridge *sim_bridge)
{
struct dp_aux_private *aux;
@@ -788,11 +684,9 @@ static void dp_aux_set_sim_mode(struct dp_aux *dp_aux, bool en,
mutex_lock(&aux->mutex);
aux->edid = edid;
aux->dpcd = dpcd;
aux->sim_bridge = sim_bridge;
if (en) {
if (sim_bridge) {
atomic_set(&aux->aborted, 0);
aux->drm_aux.transfer = dp_aux_transfer_debug;
} else if (aux->aux_bridge && aux->aux_bridge->transfer) {
@@ -884,7 +778,6 @@ struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog,
aux->aux_bridge = aux_bridge;
dp_aux = &aux->dp_aux;
aux->retry_cnt = 0;
aux->dp_aux.reg = 0xFFFF;
dp_aux->isr = dp_aux_isr;
dp_aux->init = dp_aux_init;
@@ -893,7 +786,6 @@ struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog,
dp_aux->drm_aux_deregister = dp_aux_deregister;
dp_aux->reconfig = dp_aux_reconfig;
dp_aux->abort = dp_aux_abort_transaction;
dp_aux->dpcd_updated = dp_aux_dpcd_updated;
dp_aux->set_sim_mode = dp_aux_set_sim_mode;
dp_aux->aux_switch = dp_aux_configure_aux_switch;