Merge "disp: msm: dsi: snapshot of dsi from 4.14 to 4.19"

This commit is contained in:
qctecmdr
2019-07-12 12:29:14 -07:00
committad av Gerrit - the friendly Code Review server
förälder 3ab9638e45 edef6ae040
incheckning b6913a5af2
21 ändrade filer med 632 tillägg och 171 borttagningar

Visa fil

@@ -78,6 +78,11 @@ static int dsi_display_config_clk_gating(struct dsi_display *display,
return -EINVAL;
}
if (display->panel->host_config.force_hs_clk_lane) {
pr_debug("no dsi clock gating for continuous clock mode\n");
return 0;
}
mctrl = &display->ctrl[display->clk_master_idx];
if (!mctrl) {
pr_err("Invalid controller\n");
@@ -586,8 +591,11 @@ static bool dsi_display_validate_reg_read(struct dsi_panel *panel)
for (j = 0; j < config->groups; ++j) {
for (i = 0; i < len; ++i) {
if (config->return_buf[i] !=
config->status_value[group + i])
config->status_value[group + i]) {
DRM_ERROR("mismatch: 0x%x\n",
config->return_buf[i]);
break;
}
}
if (i == len)
@@ -828,6 +836,11 @@ int dsi_display_check_status(struct drm_connector *connector, void *display,
if (te_check_override && gpio_is_valid(dsi_display->disp_te_gpio))
status_mode = ESD_MODE_PANEL_TE;
if (status_mode == ESD_MODE_PANEL_TE) {
rc = dsi_display_status_check_te(dsi_display);
goto exit;
}
dsi_display_clk_ctrl(dsi_display->dsi_clk_handle,
DSI_ALL_CLKS, DSI_CLK_ON);
@@ -843,23 +856,25 @@ int dsi_display_check_status(struct drm_connector *connector, void *display,
} else if (status_mode == ESD_MODE_PANEL_TE) {
rc = dsi_display_status_check_te(dsi_display);
} else {
pr_warn("unsupported check status mode\n");
pr_warn("Unsupported check status mode: %d\n", status_mode);
panel->esd_config.esd_enabled = false;
}
/* Unmask error interrupts */
/* Unmask error interrupts if check passed*/
if (rc > 0) {
dsi_display_set_ctrl_esd_check_flag(dsi_display, false);
dsi_display_mask_ctrl_error_interrupts(dsi_display, mask,
false);
} else {
/* Handle Panel failures during display disable sequence */
atomic_set(&panel->esd_recovery_pending, 1);
}
dsi_display_clk_ctrl(dsi_display->dsi_clk_handle,
DSI_ALL_CLKS, DSI_CLK_OFF);
exit:
/* Handle Panel failures during display disable sequence */
if (rc <=0)
atomic_set(&panel->esd_recovery_pending, 1);
release_panel_lock:
dsi_panel_release_panel_lock(panel);
SDE_EVT32(SDE_EVTLOG_FUNC_EXIT);
@@ -1620,12 +1635,25 @@ static int dsi_display_debugfs_deinit(struct dsi_display *display)
static void adjust_timing_by_ctrl_count(const struct dsi_display *display,
struct dsi_display_mode *mode)
{
mode->timing.h_active /= display->ctrl_count;
mode->timing.h_front_porch /= display->ctrl_count;
mode->timing.h_sync_width /= display->ctrl_count;
mode->timing.h_back_porch /= display->ctrl_count;
mode->timing.h_skew /= display->ctrl_count;
mode->pixel_clk_khz /= display->ctrl_count;
struct dsi_host_common_cfg *host = &display->panel->host_config;
bool is_split_link = host->split_link.split_link_enabled;
u32 sublinks_count = host->split_link.num_sublinks;
if (is_split_link && sublinks_count > 1) {
mode->timing.h_active /= sublinks_count;
mode->timing.h_front_porch /= sublinks_count;
mode->timing.h_sync_width /= sublinks_count;
mode->timing.h_back_porch /= sublinks_count;
mode->timing.h_skew /= sublinks_count;
mode->pixel_clk_khz /= sublinks_count;
} else {
mode->timing.h_active /= display->ctrl_count;
mode->timing.h_front_porch /= display->ctrl_count;
mode->timing.h_sync_width /= display->ctrl_count;
mode->timing.h_back_porch /= display->ctrl_count;
mode->timing.h_skew /= display->ctrl_count;
mode->pixel_clk_khz /= display->ctrl_count;
}
}
static int dsi_display_is_ulps_req_valid(struct dsi_display *display,
@@ -2366,7 +2394,9 @@ static int dsi_display_ctrl_init(struct dsi_display *display)
} else {
display_for_each_ctrl(i, display) {
ctrl = &display->ctrl[i];
rc = dsi_ctrl_update_host_init_state(ctrl->ctrl, true);
rc = dsi_ctrl_update_host_state(ctrl->ctrl,
DSI_CTRL_OP_HOST_INIT,
true);
if (rc)
pr_debug("host init update failed rc=%d\n", rc);
}
@@ -2450,6 +2480,25 @@ static int dsi_display_ctrl_host_disable(struct dsi_display *display)
struct dsi_display_ctrl *m_ctrl, *ctrl;
m_ctrl = &display->ctrl[display->cmd_master_idx];
/*
* For platforms where ULPS is controlled by DSI controller block,
* do not disable dsi controller block if lanes are to be
* kept in ULPS during suspend. So just update the SW state
* and return early.
*/
if (display->panel->ulps_suspend_enabled &&
!m_ctrl->phy->hw.ops.ulps_ops.ulps_request) {
display_for_each_ctrl(i, display) {
ctrl = &display->ctrl[i];
rc = dsi_ctrl_update_host_state(ctrl->ctrl,
DSI_CTRL_OP_HOST_ENGINE,
false);
if (rc)
pr_debug("host state update failed %d\n", rc);
}
return rc;
}
display_for_each_ctrl(i, display) {
ctrl = &display->ctrl[i];
if (!ctrl->ctrl || (ctrl == m_ctrl))
@@ -4609,6 +4658,42 @@ static int dsi_display_force_update_dsi_clk(struct dsi_display *display)
return rc;
}
static int dsi_display_validate_split_link(struct dsi_display *display)
{
int i, rc = 0;
struct dsi_display_ctrl *ctrl;
struct dsi_host_common_cfg *host = &display->panel->host_config;
if (!host->split_link.split_link_enabled)
return 0;
if (display->panel->panel_mode == DSI_OP_CMD_MODE) {
pr_err("[%s] split link is not supported in command mode\n",
display->name);
rc = -ENOTSUPP;
goto error;
}
display_for_each_ctrl(i, display) {
ctrl = &display->ctrl[i];
if (!ctrl->ctrl->split_link_supported) {
pr_err("[%s] split link is not supported by hw\n",
display->name);
rc = -ENOTSUPP;
goto error;
}
set_bit(DSI_PHY_SPLIT_LINK, ctrl->phy->hw.feature_map);
}
pr_debug("Split link is enabled\n");
return 0;
error:
host->split_link.split_link_enabled = false;
return rc;
}
/**
* dsi_display_bind - bind dsi device with controlling device
* @dev: Pointer to base of platform device
@@ -4649,8 +4734,28 @@ static int dsi_display_bind(struct device *dev,
if (!display->fw)
display->name = display->panel_node->name;
/* defer bind if ext bridge driver is not loaded */
if (display->panel && display->panel->host_config.ext_bridge_mode) {
for (i = 0; i < display->ext_bridge_cnt; i++) {
if (!of_drm_find_bridge(
display->ext_bridge[i].node_of)) {
pr_debug("defer for bridge[%d] %s\n", i,
display->ext_bridge[i].node_of->full_name);
return -EPROBE_DEFER;
}
}
}
mutex_lock(&display->display_lock);
rc = dsi_display_validate_split_link(display);
if (rc) {
pr_err("[%s] split link validation failed, rc=%d\n",
display->name, rc);
goto error;
}
rc = dsi_display_debugfs_init(display);
if (rc) {
pr_err("[%s] debugfs init failed, rc=%d\n", display->name, rc);
@@ -5276,7 +5381,7 @@ static struct dsi_display_ext_bridge *dsi_display_ext_get_bridge(
sde_conn = to_sde_connector(conn_iter);
if (sde_conn->encoder == bridge->encoder) {
display = sde_conn->display;
for (i = 0; i < display->ctrl_count; i++) {
display_for_each_ctrl(i, display) {
if (display->ext_bridge[i].bridge == bridge)
return &display->ext_bridge[i];
}
@@ -5443,6 +5548,9 @@ int dsi_display_drm_ext_bridge_init(struct dsi_display *display,
struct drm_bridge *prev_bridge = bridge;
int rc = 0, i;
if (display->panel && !display->panel->host_config.ext_bridge_mode)
return 0;
for (i = 0; i < display->ext_bridge_cnt; i++) {
struct dsi_display_ext_bridge *ext_bridge_info =
&display->ext_bridge[i];
@@ -5753,8 +5861,10 @@ int dsi_display_get_modes(struct dsi_display *display,
{
struct dsi_dfps_capabilities dfps_caps;
struct dsi_display_ctrl *ctrl;
struct dsi_host_common_cfg *host = &display->panel->host_config;
bool is_split_link;
u32 num_dfps_rates, panel_mode_count, total_mode_count;
u32 mode_idx, array_idx = 0;
u32 sublinks_count, mode_idx, array_idx = 0;
struct dsi_dyn_clk_caps *dyn_clk_caps;
int i, start, end, rc = -EINVAL;
@@ -5830,15 +5940,25 @@ int dsi_display_get_modes(struct dsi_display *display,
panel_mode.timing.dsi_transfer_time_us;
}
panel_mode.timing.h_active *= display->ctrl_count;
panel_mode.timing.h_front_porch *= display->ctrl_count;
panel_mode.timing.h_sync_width *= display->ctrl_count;
panel_mode.timing.h_back_porch *= display->ctrl_count;
panel_mode.timing.h_skew *= display->ctrl_count;
panel_mode.pixel_clk_khz *= display->ctrl_count;
is_split_link = host->split_link.split_link_enabled;
sublinks_count = host->split_link.num_sublinks;
if (is_split_link && sublinks_count > 1) {
panel_mode.timing.h_active *= sublinks_count;
panel_mode.timing.h_front_porch *= sublinks_count;
panel_mode.timing.h_sync_width *= sublinks_count;
panel_mode.timing.h_back_porch *= sublinks_count;
panel_mode.timing.h_skew *= sublinks_count;
panel_mode.pixel_clk_khz *= sublinks_count;
} else {
panel_mode.timing.h_active *= display->ctrl_count;
panel_mode.timing.h_front_porch *= display->ctrl_count;
panel_mode.timing.h_sync_width *= display->ctrl_count;
panel_mode.timing.h_back_porch *= display->ctrl_count;
panel_mode.timing.h_skew *= display->ctrl_count;
panel_mode.pixel_clk_khz *= display->ctrl_count;
}
start = array_idx;
for (i = 0; i < num_dfps_rates; i++) {
struct dsi_display_mode *sub_mode =
&display->modes[array_idx];
@@ -5889,6 +6009,7 @@ int dsi_display_get_panel_vfp(void *dsi_display,
u32 count, refresh_rate = 0;
struct dsi_dfps_capabilities dfps_caps;
struct dsi_display *display = (struct dsi_display *)dsi_display;
struct dsi_host_common_cfg *host;
if (!display)
return -EINVAL;
@@ -5912,7 +6033,11 @@ int dsi_display_get_panel_vfp(void *dsi_display,
return -EINVAL;
}
h_active *= display->ctrl_count;
host = &display->panel->host_config;
if (host->split_link.split_link_enabled)
h_active *= host->split_link.num_sublinks;
else
h_active *= display->ctrl_count;
for (i = 0; i < count; i++) {
struct dsi_display_mode *m = &display->modes[i];
@@ -6577,7 +6702,8 @@ int dsi_display_prepare(struct dsi_display *display)
if (display->is_cont_splash_enabled &&
display->config.panel_mode == DSI_OP_VIDEO_MODE) {
pr_err("DMS not supported on first frame\n");
return -EINVAL;
rc = -EINVAL;
goto error;
}
/* update dsi ctrl for new mode */
@@ -6774,8 +6900,7 @@ static int dsi_display_qsync(struct dsi_display *display, bool enable)
mutex_lock(&display->display_lock);
for (i = 0; i < display->ctrl_count; i++) {
display_for_each_ctrl(i, display) {
if (enable) {
/* send the commands to enable qsync */
rc = dsi_panel_send_qsync_on_dcs(display->panel, i);