|
@@ -1060,10 +1060,22 @@ int dsi_display_set_power(struct drm_connector *connector,
|
|
|
case SDE_MODE_DPMS_LP2:
|
|
|
rc = dsi_panel_set_lp2(display->panel);
|
|
|
break;
|
|
|
- default:
|
|
|
- rc = dsi_panel_set_nolp(display->panel);
|
|
|
+ case SDE_MODE_DPMS_ON:
|
|
|
+ if ((display->panel->power_mode == SDE_MODE_DPMS_LP1) ||
|
|
|
+ (display->panel->power_mode == SDE_MODE_DPMS_LP2))
|
|
|
+ rc = dsi_panel_set_nolp(display->panel);
|
|
|
break;
|
|
|
+ case SDE_MODE_DPMS_OFF:
|
|
|
+ default:
|
|
|
+ return rc;
|
|
|
}
|
|
|
+
|
|
|
+ DSI_DEBUG("Power mode transition from %d to %d %s",
|
|
|
+ display->panel->power_mode, power_mode,
|
|
|
+ rc ? "failed" : "successful");
|
|
|
+ if (!rc)
|
|
|
+ display->panel->power_mode = power_mode;
|
|
|
+
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
@@ -3839,7 +3851,7 @@ static int dsi_display_update_dsi_bitrate(struct dsi_display *display,
|
|
|
|
|
|
display->config.bit_clk_rate_hz = bit_clk_rate;
|
|
|
|
|
|
- for (i = 0; i < display->ctrl_count; i++) {
|
|
|
+ display_for_each_ctrl(i, display) {
|
|
|
struct dsi_display_ctrl *dsi_disp_ctrl = &display->ctrl[i];
|
|
|
struct dsi_ctrl *ctrl = dsi_disp_ctrl->ctrl;
|
|
|
u32 num_of_lanes = 0, bpp;
|
|
@@ -3967,8 +3979,7 @@ static int _dsi_display_dyn_update_clks(struct dsi_display *display,
|
|
|
goto exit;
|
|
|
}
|
|
|
|
|
|
- for (i = 0; (i < display->ctrl_count) &&
|
|
|
- (i < MAX_DSI_CTRLS_PER_DISPLAY); i++) {
|
|
|
+ display_for_each_ctrl(i, display) {
|
|
|
ctrl = &display->ctrl[i];
|
|
|
if (!ctrl->ctrl)
|
|
|
continue;
|
|
@@ -3986,8 +3997,7 @@ static int _dsi_display_dyn_update_clks(struct dsi_display *display,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- for (i = 0; (i < display->ctrl_count) &&
|
|
|
- (i < MAX_DSI_CTRLS_PER_DISPLAY); i++) {
|
|
|
+ display_for_each_ctrl(i, display) {
|
|
|
ctrl = &display->ctrl[i];
|
|
|
if (ctrl == m_ctrl)
|
|
|
continue;
|
|
@@ -3996,8 +4006,7 @@ static int _dsi_display_dyn_update_clks(struct dsi_display *display,
|
|
|
dsi_phy_dynamic_refresh_trigger(m_ctrl->phy, true);
|
|
|
|
|
|
/* wait for dynamic refresh done */
|
|
|
- for (i = 0; (i < display->ctrl_count) &&
|
|
|
- (i < MAX_DSI_CTRLS_PER_DISPLAY); i++) {
|
|
|
+ display_for_each_ctrl(i, display) {
|
|
|
ctrl = &display->ctrl[i];
|
|
|
rc = dsi_ctrl_wait4dynamic_refresh_done(ctrl->ctrl);
|
|
|
if (rc) {
|
|
@@ -4009,8 +4018,7 @@ static int _dsi_display_dyn_update_clks(struct dsi_display *display,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- for (i = 0; (i < display->ctrl_count) &&
|
|
|
- (i < MAX_DSI_CTRLS_PER_DISPLAY); i++) {
|
|
|
+ display_for_each_ctrl(i, display) {
|
|
|
ctrl = &display->ctrl[i];
|
|
|
dsi_phy_dynamic_refresh_clear(ctrl->phy);
|
|
|
}
|
|
@@ -4025,8 +4033,7 @@ static int _dsi_display_dyn_update_clks(struct dsi_display *display,
|
|
|
return rc;
|
|
|
|
|
|
recover_pix_clk:
|
|
|
- for (i = 0; (i < display->ctrl_count) &&
|
|
|
- (i < MAX_DSI_CTRLS_PER_DISPLAY); i++) {
|
|
|
+ display_for_each_ctrl(i, display) {
|
|
|
ctrl = &display->ctrl[i];
|
|
|
if (!ctrl->ctrl)
|
|
|
continue;
|
|
@@ -4035,8 +4042,7 @@ recover_pix_clk:
|
|
|
}
|
|
|
|
|
|
recover_byte_clk:
|
|
|
- for (i = 0; (i < display->ctrl_count) &&
|
|
|
- (i < MAX_DSI_CTRLS_PER_DISPLAY); i++) {
|
|
|
+ display_for_each_ctrl(i, display) {
|
|
|
ctrl = &display->ctrl[i];
|
|
|
if (!ctrl->ctrl)
|
|
|
continue;
|
|
@@ -4070,7 +4076,7 @@ static int dsi_display_dynamic_clk_switch_vid(struct dsi_display *display,
|
|
|
dsi_display_mask_ctrl_error_interrupts(display, mask, true);
|
|
|
|
|
|
/* update the phy timings based on new mode */
|
|
|
- for (i = 0; i < display->ctrl_count; i++) {
|
|
|
+ display_for_each_ctrl(i, display) {
|
|
|
ctrl = &display->ctrl[i];
|
|
|
dsi_phy_update_phy_timings(ctrl->phy, &display->config);
|
|
|
}
|
|
@@ -4090,7 +4096,7 @@ static int dsi_display_dynamic_clk_switch_vid(struct dsi_display *display,
|
|
|
_dsi_display_calc_pipe_delay(display, &delay, mode);
|
|
|
|
|
|
/* configure dynamic refresh ctrl registers */
|
|
|
- for (i = 0; i < display->ctrl_count; i++) {
|
|
|
+ display_for_each_ctrl(i, display) {
|
|
|
ctrl = &display->ctrl[i];
|
|
|
if (!ctrl->phy)
|
|
|
continue;
|
|
@@ -5756,55 +5762,17 @@ error:
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
-static int dsi_display_get_mode_count_no_lock(struct dsi_display *display,
|
|
|
- u32 *count)
|
|
|
-{
|
|
|
- struct dsi_dfps_capabilities dfps_caps;
|
|
|
- struct dsi_dyn_clk_caps *dyn_clk_caps;
|
|
|
- int num_dfps_rates, num_bit_clks, rc = 0;
|
|
|
-
|
|
|
- if (!display || !display->panel) {
|
|
|
- DSI_ERR("invalid display:%d panel:%d\n", display != NULL,
|
|
|
- display ? display->panel != NULL : 0);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
- *count = display->panel->num_timing_nodes;
|
|
|
-
|
|
|
- rc = dsi_panel_get_dfps_caps(display->panel, &dfps_caps);
|
|
|
- if (rc) {
|
|
|
- DSI_ERR("[%s] failed to get dfps caps from panel\n",
|
|
|
- display->name);
|
|
|
- return rc;
|
|
|
- }
|
|
|
-
|
|
|
- num_dfps_rates = !dfps_caps.dfps_support ? 1 : dfps_caps.dfps_list_len;
|
|
|
-
|
|
|
- dyn_clk_caps = &(display->panel->dyn_clk_caps);
|
|
|
-
|
|
|
- num_bit_clks = !dyn_clk_caps->dyn_clk_support ? 1 :
|
|
|
- dyn_clk_caps->bit_clk_list_len;
|
|
|
-
|
|
|
- /* Inflate num_of_modes by fps and bit clks in dfps */
|
|
|
- *count = display->panel->num_timing_nodes *
|
|
|
- num_dfps_rates * num_bit_clks;
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
int dsi_display_get_mode_count(struct dsi_display *display,
|
|
|
u32 *count)
|
|
|
{
|
|
|
- int rc;
|
|
|
-
|
|
|
if (!display || !display->panel) {
|
|
|
DSI_ERR("invalid display:%d panel:%d\n", display != NULL,
|
|
|
- display ? display->panel != NULL : 0);
|
|
|
+ display ? display->panel != NULL : 0);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
mutex_lock(&display->display_lock);
|
|
|
- rc = dsi_display_get_mode_count_no_lock(display, count);
|
|
|
+ *count = display->panel->num_display_modes;
|
|
|
mutex_unlock(&display->display_lock);
|
|
|
|
|
|
return 0;
|
|
@@ -5837,7 +5805,7 @@ static void _dsi_display_populate_bit_clks(struct dsi_display *display,
|
|
|
if (cfg->data_lanes & DSI_DATA_LANE_3)
|
|
|
lanes++;
|
|
|
|
|
|
- dsi_display_get_mode_count_no_lock(display, &total_modes);
|
|
|
+ total_modes = display->panel->num_display_modes;
|
|
|
|
|
|
for (i = start; i < end; i++) {
|
|
|
src = &display->modes[i];
|
|
@@ -5889,8 +5857,8 @@ 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;
|
|
|
+ bool is_split_link, is_cmd_mode;
|
|
|
+ u32 num_dfps_rates, timing_mode_count, display_mode_count;
|
|
|
u32 sublinks_count, mode_idx, array_idx = 0;
|
|
|
struct dsi_dyn_clk_caps *dyn_clk_caps;
|
|
|
int i, start, end, rc = -EINVAL;
|
|
@@ -5908,11 +5876,9 @@ int dsi_display_get_modes(struct dsi_display *display,
|
|
|
if (display->modes)
|
|
|
goto exit;
|
|
|
|
|
|
- rc = dsi_display_get_mode_count_no_lock(display, &total_mode_count);
|
|
|
- if (rc)
|
|
|
- goto error;
|
|
|
+ display_mode_count = display->panel->num_display_modes;
|
|
|
|
|
|
- display->modes = kcalloc(total_mode_count, sizeof(*display->modes),
|
|
|
+ display->modes = kcalloc(display_mode_count, sizeof(*display->modes),
|
|
|
GFP_KERNEL);
|
|
|
if (!display->modes) {
|
|
|
rc = -ENOMEM;
|
|
@@ -5930,20 +5896,20 @@ int dsi_display_get_modes(struct dsi_display *display,
|
|
|
|
|
|
num_dfps_rates = !dfps_caps.dfps_support ? 1 : dfps_caps.dfps_list_len;
|
|
|
|
|
|
- panel_mode_count = display->panel->num_timing_nodes;
|
|
|
+ timing_mode_count = display->panel->num_timing_nodes;
|
|
|
|
|
|
- for (mode_idx = 0; mode_idx < panel_mode_count; mode_idx++) {
|
|
|
- struct dsi_display_mode panel_mode;
|
|
|
+ for (mode_idx = 0; mode_idx < timing_mode_count; mode_idx++) {
|
|
|
+ struct dsi_display_mode display_mode;
|
|
|
int topology_override = NO_OVERRIDE;
|
|
|
u32 frame_threshold_us = ctrl->ctrl->frame_threshold_time_us;
|
|
|
|
|
|
if (display->cmdline_timing == mode_idx)
|
|
|
topology_override = display->cmdline_topology;
|
|
|
|
|
|
- memset(&panel_mode, 0, sizeof(panel_mode));
|
|
|
+ memset(&display_mode, 0, sizeof(display_mode));
|
|
|
|
|
|
rc = dsi_panel_get_mode(display->panel, mode_idx,
|
|
|
- &panel_mode,
|
|
|
+ &display_mode,
|
|
|
topology_override);
|
|
|
if (rc) {
|
|
|
DSI_ERR("[%s] failed to get mode idx %d from panel\n",
|
|
@@ -5951,38 +5917,43 @@ int dsi_display_get_modes(struct dsi_display *display,
|
|
|
goto error;
|
|
|
}
|
|
|
|
|
|
+ is_cmd_mode = (display_mode.panel_mode == DSI_OP_CMD_MODE);
|
|
|
+
|
|
|
/* Calculate dsi frame transfer time */
|
|
|
- if (display->panel->panel_mode == DSI_OP_CMD_MODE) {
|
|
|
+ if (is_cmd_mode) {
|
|
|
dsi_panel_calc_dsi_transfer_time(
|
|
|
&display->panel->host_config,
|
|
|
- &panel_mode, frame_threshold_us);
|
|
|
- panel_mode.priv_info->dsi_transfer_time_us =
|
|
|
- panel_mode.timing.dsi_transfer_time_us;
|
|
|
- panel_mode.priv_info->min_dsi_clk_hz =
|
|
|
- panel_mode.timing.min_dsi_clk_hz;
|
|
|
+ &display_mode, frame_threshold_us);
|
|
|
+ display_mode.priv_info->dsi_transfer_time_us =
|
|
|
+ display_mode.timing.dsi_transfer_time_us;
|
|
|
+ display_mode.priv_info->min_dsi_clk_hz =
|
|
|
+ display_mode.timing.min_dsi_clk_hz;
|
|
|
|
|
|
- panel_mode.priv_info->mdp_transfer_time_us =
|
|
|
- panel_mode.priv_info->dsi_transfer_time_us;
|
|
|
- panel_mode.timing.mdp_transfer_time_us =
|
|
|
- panel_mode.timing.dsi_transfer_time_us;
|
|
|
+ display_mode.priv_info->mdp_transfer_time_us =
|
|
|
+ display_mode.priv_info->dsi_transfer_time_us;
|
|
|
+ display_mode.timing.mdp_transfer_time_us =
|
|
|
+ display_mode.timing.dsi_transfer_time_us;
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
+ display_mode.timing.h_active *= sublinks_count;
|
|
|
+ display_mode.timing.h_front_porch *= sublinks_count;
|
|
|
+ display_mode.timing.h_sync_width *= sublinks_count;
|
|
|
+ display_mode.timing.h_back_porch *= sublinks_count;
|
|
|
+ display_mode.timing.h_skew *= sublinks_count;
|
|
|
+ display_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;
|
|
|
+ display_mode.timing.h_active *= display->ctrl_count;
|
|
|
+ display_mode.timing.h_front_porch *=
|
|
|
+ display->ctrl_count;
|
|
|
+ display_mode.timing.h_sync_width *=
|
|
|
+ display->ctrl_count;
|
|
|
+ display_mode.timing.h_back_porch *=
|
|
|
+ display->ctrl_count;
|
|
|
+ display_mode.timing.h_skew *= display->ctrl_count;
|
|
|
+ display_mode.pixel_clk_khz *= display->ctrl_count;
|
|
|
}
|
|
|
|
|
|
start = array_idx;
|
|
@@ -5997,10 +5968,10 @@ int dsi_display_get_modes(struct dsi_display *display,
|
|
|
goto error;
|
|
|
}
|
|
|
|
|
|
- memcpy(sub_mode, &panel_mode, sizeof(panel_mode));
|
|
|
+ memcpy(sub_mode, &display_mode, sizeof(display_mode));
|
|
|
array_idx++;
|
|
|
|
|
|
- if (!dfps_caps.dfps_support)
|
|
|
+ if (!dfps_caps.dfps_support || is_cmd_mode)
|
|
|
continue;
|
|
|
|
|
|
curr_refresh_rate = sub_mode->timing.refresh_rate;
|
|
@@ -6038,16 +6009,14 @@ int dsi_display_get_panel_vfp(void *dsi_display,
|
|
|
struct dsi_display *display = (struct dsi_display *)dsi_display;
|
|
|
struct dsi_host_common_cfg *host;
|
|
|
|
|
|
- if (!display)
|
|
|
+ if (!display || !display->panel)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- rc = dsi_display_get_mode_count(display, &count);
|
|
|
- if (rc)
|
|
|
- return rc;
|
|
|
-
|
|
|
mutex_lock(&display->display_lock);
|
|
|
|
|
|
- if (display->panel && display->panel->cur_mode)
|
|
|
+ count = display->panel->num_display_modes;
|
|
|
+
|
|
|
+ if (display->panel->cur_mode)
|
|
|
refresh_rate = display->panel->cur_mode->timing.refresh_rate;
|
|
|
|
|
|
dsi_panel_get_dfps_caps(display->panel, &dfps_caps);
|
|
@@ -6089,9 +6058,9 @@ int dsi_display_get_default_lms(void *dsi_display, u32 *num_lm)
|
|
|
|
|
|
*num_lm = 0;
|
|
|
|
|
|
- rc = dsi_display_get_mode_count(display, &count);
|
|
|
- if (rc)
|
|
|
- return rc;
|
|
|
+ mutex_lock(&display->display_lock);
|
|
|
+ count = display->panel->num_display_modes;
|
|
|
+ mutex_unlock(&display->display_lock);
|
|
|
|
|
|
if (!display->modes) {
|
|
|
struct dsi_display_mode *m;
|
|
@@ -6124,9 +6093,9 @@ int dsi_display_find_mode(struct dsi_display *display,
|
|
|
|
|
|
*out_mode = NULL;
|
|
|
|
|
|
- rc = dsi_display_get_mode_count(display, &count);
|
|
|
- if (rc)
|
|
|
- return rc;
|
|
|
+ mutex_lock(&display->display_lock);
|
|
|
+ count = display->panel->num_display_modes;
|
|
|
+ mutex_unlock(&display->display_lock);
|
|
|
|
|
|
if (!display->modes) {
|
|
|
struct dsi_display_mode *m;
|