diff options
Diffstat (limited to 'msm/dp/dp_panel.c')
-rw-r--r-- | msm/dp/dp_panel.c | 71 |
1 files changed, 36 insertions, 35 deletions
diff --git a/msm/dp/dp_panel.c b/msm/dp/dp_panel.c index b31103a6..1c01b0ee 100644 --- a/msm/dp/dp_panel.c +++ b/msm/dp/dp_panel.c @@ -7,6 +7,7 @@ #include <linux/unistd.h> #include <drm/drm_fixed.h> #include "dp_debug.h" +#include <drm/drm_edid.h> #define DP_KHZ_TO_HZ 1000 #define DP_PANEL_DEFAULT_BPP 24 @@ -1355,8 +1356,11 @@ static void _dp_panel_dsc_bw_overhead_calc(struct dp_panel *dp_panel, int tot_num_hor_bytes, tot_num_dummy_bytes; int dwidth_dsc_bytes, eoc_bytes; u32 num_lanes; + struct dp_panel_private *panel; + + panel = container_of(dp_panel, struct dp_panel_private, dp_panel); - num_lanes = dp_panel->link_info.num_lanes; + num_lanes = panel->link->link_params.lane_count; num_slices = dsc->slice_per_pkt; eoc_bytes = dsc_byte_cnt % num_lanes; @@ -1934,7 +1938,25 @@ static int dp_panel_set_default_link_params(struct dp_panel *dp_panel) return 0; } -static int dp_panel_set_edid(struct dp_panel *dp_panel, u8 *edid) +static bool dp_panel_validate_edid(struct edid *edid, size_t edid_size) +{ + if (!edid || (edid_size < EDID_LENGTH)) + return false; + + if (EDID_LENGTH * (edid->extensions + 1) > edid_size) { + DP_ERR("edid size does not match allocated.\n"); + return false; + } + + if (!drm_edid_is_valid(edid)) { + DP_ERR("invalid edid.\n"); + return false; + } + return true; +} + +static int dp_panel_set_edid(struct dp_panel *dp_panel, u8 *edid, + size_t edid_size) { struct dp_panel_private *panel; @@ -1945,7 +1967,7 @@ static int dp_panel_set_edid(struct dp_panel *dp_panel, u8 *edid) panel = container_of(dp_panel, struct dp_panel_private, dp_panel); - if (edid) { + if (edid && dp_panel_validate_edid((struct edid *)edid, edid_size)) { dp_panel->edid_ctrl->edid = (struct edid *)edid; panel->custom_edid = true; } else { @@ -2171,18 +2193,23 @@ end: static u32 dp_panel_get_supported_bpp(struct dp_panel *dp_panel, u32 mode_edid_bpp, u32 mode_pclk_khz) { - struct drm_dp_link *link_info; + struct dp_link_params *link_params; + struct dp_panel_private *panel; const u32 max_supported_bpp = 30; u32 min_supported_bpp = 18; u32 bpp = 0, data_rate_khz = 0, tmds_max_clock = 0; + panel = container_of(dp_panel, struct dp_panel_private, dp_panel); + if (dp_panel->dsc_en) min_supported_bpp = 24; bpp = min_t(u32, mode_edid_bpp, max_supported_bpp); - link_info = &dp_panel->link_info; - data_rate_khz = link_info->num_lanes * link_info->rate * 8; + link_params = &panel->link->link_params; + + data_rate_khz = link_params->lane_count * + drm_dp_bw_code_to_link_rate(link_params->bw_code) * 8; tmds_max_clock = dp_panel->connector->display_info.max_tmds_clock; for (; bpp > min_supported_bpp; bpp -= 6) { @@ -2680,32 +2707,6 @@ static int dp_panel_deinit_panel_info(struct dp_panel *dp_panel, u32 flags) return rc; } -static u32 dp_panel_get_min_req_link_rate(struct dp_panel *dp_panel) -{ - const u32 encoding_factx10 = 8; - u32 min_link_rate_khz = 0, lane_cnt; - struct dp_panel_info *pinfo; - - if (!dp_panel) { - DP_ERR("invalid input\n"); - goto end; - } - - lane_cnt = dp_panel->link_info.num_lanes; - pinfo = &dp_panel->pinfo; - - /* num_lanes * lane_count * 8 >= pclk * bpp * 10 */ - min_link_rate_khz = pinfo->pixel_clk_khz / - (lane_cnt * encoding_factx10); - min_link_rate_khz *= pinfo->bpp; - - DP_DEBUG("min lclk req=%d khz for pclk=%d khz, lanes=%d, bpp=%d\n", - min_link_rate_khz, pinfo->pixel_clk_khz, lane_cnt, - pinfo->bpp); -end: - return min_link_rate_khz; -} - static bool dp_panel_hdr_supported(struct dp_panel *dp_panel) { struct dp_panel_private *panel; @@ -2966,8 +2967,9 @@ cached: dp_panel_setup_dhdr_vsif(panel); input.mdp_clk = core_clk_rate; - input.lclk = dp_panel->link_info.rate; - input.nlanes = dp_panel->link_info.num_lanes; + input.lclk = drm_dp_bw_code_to_link_rate( + panel->link->link_params.bw_code); + input.nlanes = panel->link->link_params.lane_count; input.pclk = dp_panel->pinfo.pixel_clk_khz; input.h_active = dp_panel->pinfo.h_active; input.mst_target_sc = dp_panel->mst_target_sc; @@ -3371,7 +3373,6 @@ struct dp_panel *dp_panel_get(struct dp_panel_in *in) dp_panel->deinit = dp_panel_deinit_panel_info; dp_panel->hw_cfg = dp_panel_hw_cfg; dp_panel->read_sink_caps = dp_panel_read_sink_caps; - dp_panel->get_min_req_link_rate = dp_panel_get_min_req_link_rate; dp_panel->get_mode_bpp = dp_panel_get_mode_bpp; dp_panel->get_modes = dp_panel_get_modes; dp_panel->handle_sink_request = dp_panel_handle_sink_request; |