diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 190929a41abd1d8d6619e27bb9391f75145ed64a..fd68ad2e27186c24cef20dd4ae20decdd6da4a2e 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -243,11 +243,26 @@ static void ti_sn65dsi86_write_u16(struct ti_sn65dsi86 *pdata, regmap_bulk_write(pdata->regmap, reg, buf, ARRAY_SIZE(buf)); } -static u32 ti_sn_bridge_get_dsi_freq(struct ti_sn65dsi86 *pdata) +static struct drm_display_mode * +get_new_adjusted_display_mode(struct drm_bridge *bridge, + struct drm_atomic_state *state) +{ + struct drm_connector *connector = + drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); + struct drm_connector_state *conn_state = + drm_atomic_get_new_connector_state(state, connector); + struct drm_crtc_state *crtc_state = + drm_atomic_get_new_crtc_state(state, conn_state->crtc); + + return &crtc_state->adjusted_mode; +} + +static u32 ti_sn_bridge_get_dsi_freq(struct ti_sn65dsi86 *pdata, + struct drm_atomic_state *state) { u32 bit_rate_khz, clk_freq_khz; struct drm_display_mode *mode = - &pdata->bridge.encoder->crtc->state->adjusted_mode; + get_new_adjusted_display_mode(&pdata->bridge, state); bit_rate_khz = mode->clock * mipi_dsi_pixel_format_to_bpp(pdata->dsi->format); @@ -274,7 +289,8 @@ static const u32 ti_sn_bridge_dsiclk_lut[] = { 460800000, }; -static void ti_sn_bridge_set_refclk_freq(struct ti_sn65dsi86 *pdata) +static void ti_sn_bridge_set_refclk_freq(struct ti_sn65dsi86 *pdata, + struct drm_atomic_state *state) { int i; u32 refclk_rate; @@ -287,7 +303,7 @@ static void ti_sn_bridge_set_refclk_freq(struct ti_sn65dsi86 *pdata) refclk_lut_size = ARRAY_SIZE(ti_sn_bridge_refclk_lut); clk_prepare_enable(pdata->refclk); } else { - refclk_rate = ti_sn_bridge_get_dsi_freq(pdata) * 1000; + refclk_rate = ti_sn_bridge_get_dsi_freq(pdata, state) * 1000; refclk_lut = ti_sn_bridge_dsiclk_lut; refclk_lut_size = ARRAY_SIZE(ti_sn_bridge_dsiclk_lut); } @@ -311,12 +327,13 @@ static void ti_sn_bridge_set_refclk_freq(struct ti_sn65dsi86 *pdata) pdata->pwm_refclk_freq = ti_sn_bridge_refclk_lut[i]; } -static void ti_sn65dsi86_enable_comms(struct ti_sn65dsi86 *pdata) +static void ti_sn65dsi86_enable_comms(struct ti_sn65dsi86 *pdata, + struct drm_atomic_state *state) { mutex_lock(&pdata->comms_mutex); /* configure bridge ref_clk */ - ti_sn_bridge_set_refclk_freq(pdata); + ti_sn_bridge_set_refclk_freq(pdata, state); /* * HPD on this bridge chip is a bit useless. This is an eDP bridge @@ -376,7 +393,7 @@ static int __maybe_unused ti_sn65dsi86_resume(struct device *dev) * clock so reading early doesn't work. */ if (pdata->refclk) - ti_sn65dsi86_enable_comms(pdata); + ti_sn65dsi86_enable_comms(pdata, NULL); return ret; } @@ -822,12 +839,13 @@ static void ti_sn_bridge_atomic_disable(struct drm_bridge *bridge, regmap_update_bits(pdata->regmap, SN_ENH_FRAME_REG, VSTREAM_ENABLE, 0); } -static void ti_sn_bridge_set_dsi_rate(struct ti_sn65dsi86 *pdata) +static void ti_sn_bridge_set_dsi_rate(struct ti_sn65dsi86 *pdata, + struct drm_atomic_state *state) { unsigned int bit_rate_mhz, clk_freq_mhz; unsigned int val; struct drm_display_mode *mode = - &pdata->bridge.encoder->crtc->state->adjusted_mode; + get_new_adjusted_display_mode(&pdata->bridge, state); /* set DSIA clk frequency */ bit_rate_mhz = (mode->clock / 1000) * @@ -857,12 +875,14 @@ static const unsigned int ti_sn_bridge_dp_rate_lut[] = { 0, 1620, 2160, 2430, 2700, 3240, 4320, 5400 }; -static int ti_sn_bridge_calc_min_dp_rate_idx(struct ti_sn65dsi86 *pdata, unsigned int bpp) +static int ti_sn_bridge_calc_min_dp_rate_idx(struct ti_sn65dsi86 *pdata, + struct drm_atomic_state *state, + unsigned int bpp) { unsigned int bit_rate_khz, dp_rate_mhz; unsigned int i; struct drm_display_mode *mode = - &pdata->bridge.encoder->crtc->state->adjusted_mode; + get_new_adjusted_display_mode(&pdata->bridge, state); /* Calculate minimum bit rate based on our pixel clock. */ bit_rate_khz = mode->clock * bpp; @@ -961,10 +981,11 @@ static unsigned int ti_sn_bridge_read_valid_rates(struct ti_sn65dsi86 *pdata) return valid_rates; } -static void ti_sn_bridge_set_video_timings(struct ti_sn65dsi86 *pdata) +static void ti_sn_bridge_set_video_timings(struct ti_sn65dsi86 *pdata, + struct drm_atomic_state *state) { struct drm_display_mode *mode = - &pdata->bridge.encoder->crtc->state->adjusted_mode; + get_new_adjusted_display_mode(&pdata->bridge, state); u8 hsync_polarity = 0, vsync_polarity = 0; if (mode->flags & DRM_MODE_FLAG_NHSYNC) @@ -1106,7 +1127,7 @@ static void ti_sn_bridge_atomic_enable(struct drm_bridge *bridge, pdata->ln_polrs << LN_POLRS_OFFSET); /* set dsi clk frequency value */ - ti_sn_bridge_set_dsi_rate(pdata); + ti_sn_bridge_set_dsi_rate(pdata, state); /* * The SN65DSI86 only supports ASSR Display Authentication method and @@ -1141,7 +1162,7 @@ static void ti_sn_bridge_atomic_enable(struct drm_bridge *bridge, valid_rates = ti_sn_bridge_read_valid_rates(pdata); /* Train until we run out of rates */ - for (dp_rate_idx = ti_sn_bridge_calc_min_dp_rate_idx(pdata, bpp); + for (dp_rate_idx = ti_sn_bridge_calc_min_dp_rate_idx(pdata, state, bpp); dp_rate_idx < ARRAY_SIZE(ti_sn_bridge_dp_rate_lut); dp_rate_idx++) { if (!(valid_rates & BIT(dp_rate_idx))) @@ -1157,7 +1178,7 @@ static void ti_sn_bridge_atomic_enable(struct drm_bridge *bridge, } /* config video parameters */ - ti_sn_bridge_set_video_timings(pdata); + ti_sn_bridge_set_video_timings(pdata, state); /* enable video stream */ regmap_update_bits(pdata->regmap, SN_ENH_FRAME_REG, VSTREAM_ENABLE, @@ -1172,7 +1193,7 @@ static void ti_sn_bridge_atomic_pre_enable(struct drm_bridge *bridge, pm_runtime_get_sync(pdata->dev); if (!pdata->refclk) - ti_sn65dsi86_enable_comms(pdata); + ti_sn65dsi86_enable_comms(pdata, state); /* td7: min 100 us after enable before DSI data */ usleep_range(100, 110);