From: Jani Nikula <jani.nikula@linux.intel.com>
To: Mika Kahola <mika.kahola@intel.com>,
intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org
Cc: imre.deak@intel.com, Mika Kahola <mika.kahola@intel.com>
Subject: Re: [PATCH 1/2] drm/i915/display: Drop crtc_state from C10/C20 pll programming
Date: Wed, 29 Jan 2025 16:40:01 +0200 [thread overview]
Message-ID: <87tt9h8z0e.fsf@intel.com> (raw)
In-Reply-To: <20250129130105.198817-2-mika.kahola@intel.com>
On Wed, 29 Jan 2025, Mika Kahola <mika.kahola@intel.com> wrote:
> For PLL programming for C10 and C20 we don't need to
> carry crtc_state but instead use only necessary parts
> of the crtc_state i.e. pll_state.
This is not a good enough justification alone. Usually we pass
crtc_state around because we're going to need more stuff from there
anyway. In that case, someone's going to have to reverse this, or pass a
bunch more parameters than just "is_dp".
I see that you're doing this because you actually need this in a context
that doens't have crtc_state. Then *that* needs to be the rationale.
Even so, there's a good chance this will bite us later.
BR,
Jani.
>
> Signed-off-by: Mika Kahola <mika.kahola@intel.com>
> ---
> drivers/gpu/drm/i915/display/intel_cx0_phy.c | 109 +++++++++++--------
> 1 file changed, 64 insertions(+), 45 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
> index 48b0b9755b2b..bffe3d4bbe8b 100644
> --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c
> +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
> @@ -2021,13 +2021,12 @@ intel_c10pll_tables_get(struct intel_crtc_state *crtc_state,
> return NULL;
> }
>
> -static void intel_cx0pll_update_ssc(struct intel_crtc_state *crtc_state,
> - struct intel_encoder *encoder)
> +static void intel_cx0pll_update_ssc(struct intel_encoder *encoder,
> + struct intel_cx0pll_state *pll_state, bool is_dp)
> {
> struct intel_display *display = to_intel_display(encoder);
> - struct intel_cx0pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll;
>
> - if (intel_crtc_has_dp_encoder(crtc_state)) {
> + if (is_dp) {
> if (intel_panel_use_ssc(display)) {
> struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> pll_state->ssc_enabled =
> @@ -2036,11 +2035,10 @@ static void intel_cx0pll_update_ssc(struct intel_crtc_state *crtc_state,
> }
> }
>
> -static void intel_c10pll_update_pll(struct intel_crtc_state *crtc_state,
> - struct intel_encoder *encoder)
> +static void intel_c10pll_update_pll(struct intel_encoder *encoder,
> + struct intel_cx0pll_state *pll_state, bool is_dp)
> {
> struct intel_display *display = to_intel_display(encoder);
> - struct intel_cx0pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll;
> int i;
>
> if (pll_state->ssc_enabled)
> @@ -2051,32 +2049,49 @@ static void intel_c10pll_update_pll(struct intel_crtc_state *crtc_state,
> pll_state->c10.pll[i] = 0;
> }
>
> +static int intel_c10pll_calc_state_from_table(struct intel_encoder *encoder,
> + const struct intel_c10pll_state * const *tables, int port_clock, bool is_dp,
> + struct intel_cx0pll_state *pll_state)
> +{
> + int i;
> +
> + for (i = 0; tables[i]; i++) {
> + if (port_clock == tables[i]->clock) {
> + pll_state->c10 = *tables[i];
> + intel_cx0pll_update_ssc(encoder, pll_state, is_dp);
> + intel_c10pll_update_pll(encoder, pll_state, is_dp);
> + pll_state->use_c10 = true;
> +
> + return 0;
> + }
> + }
> +
> + return -EINVAL;
> +}
> +
> static int intel_c10pll_calc_state(struct intel_crtc_state *crtc_state,
> struct intel_encoder *encoder)
> {
> const struct intel_c10pll_state * const *tables;
> - int i;
> + int val;
>
> tables = intel_c10pll_tables_get(crtc_state, encoder);
> if (!tables)
> return -EINVAL;
>
> - for (i = 0; tables[i]; i++) {
> - if (crtc_state->port_clock == tables[i]->clock) {
> - crtc_state->dpll_hw_state.cx0pll.c10 = *tables[i];
> - intel_cx0pll_update_ssc(crtc_state, encoder);
> - intel_c10pll_update_pll(crtc_state, encoder);
> - crtc_state->dpll_hw_state.cx0pll.use_c10 = true;
> -
> - return 0;
> - }
> - }
> + val = intel_c10pll_calc_state_from_table(encoder, tables,
> + crtc_state->port_clock, intel_crtc_has_dp_encoder(crtc_state),
> + &crtc_state->dpll_hw_state.cx0pll);
> + if (val == 0)
> + return 0;
>
> /* For HDMI PLLs try SNPS PHY algorithm, if there are no precomputed tables */
> if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
> intel_snps_hdmi_pll_compute_c10pll(&crtc_state->dpll_hw_state.cx0pll.c10,
> crtc_state->port_clock);
> - intel_c10pll_update_pll(crtc_state, encoder);
> + intel_c10pll_update_pll(encoder,
> + &crtc_state->dpll_hw_state.cx0pll,
> + intel_crtc_has_dp_encoder(crtc_state));
> crtc_state->dpll_hw_state.cx0pll.use_c10 = true;
>
> return 0;
> @@ -2112,10 +2127,9 @@ static void intel_c10pll_readout_hw_state(struct intel_encoder *encoder,
> }
>
> static void intel_c10_pll_program(struct intel_display *display,
> - const struct intel_crtc_state *crtc_state,
> - struct intel_encoder *encoder)
> + struct intel_encoder *encoder,
> + const struct intel_c10pll_state *pll_state)
> {
> - const struct intel_c10pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll.c10;
> int i;
>
> intel_cx0_rmw(encoder, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CONTROL(1),
> @@ -2334,7 +2348,9 @@ static int intel_c20pll_calc_state(struct intel_crtc_state *crtc_state,
> for (i = 0; tables[i]; i++) {
> if (crtc_state->port_clock == tables[i]->clock) {
> crtc_state->dpll_hw_state.cx0pll.c20 = *tables[i];
> - intel_cx0pll_update_ssc(crtc_state, encoder);
> + intel_cx0pll_update_ssc(encoder,
> + &crtc_state->dpll_hw_state.cx0pll,
> + intel_crtc_has_dp_encoder(crtc_state));
> crtc_state->dpll_hw_state.cx0pll.use_c10 = false;
> return 0;
> }
> @@ -2600,19 +2616,14 @@ static int intel_get_c20_custom_width(u32 clock, bool dp)
> }
>
> static void intel_c20_pll_program(struct intel_display *display,
> - const struct intel_crtc_state *crtc_state,
> - struct intel_encoder *encoder)
> + struct intel_encoder *encoder,
> + const struct intel_c20pll_state *pll_state,
> + int clock, bool dp)
> {
> - const struct intel_c20pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll.c20;
> - bool dp = false;
> u8 owned_lane_mask = intel_cx0_get_owned_lane_mask(encoder);
> - u32 clock = crtc_state->port_clock;
> bool cntx;
> int i;
>
> - if (intel_crtc_has_dp_encoder(crtc_state))
> - dp = true;
> -
> /* 1. Read current context selection */
> cntx = intel_cx0_read(encoder, INTEL_CX0_LANE0, PHY_C20_VDR_CUSTOM_SERDES_RATE) & BIT(0);
>
> @@ -2736,7 +2747,8 @@ static int intel_c10pll_calc_port_clock(struct intel_encoder *encoder,
> }
>
> static void intel_program_port_clock_ctl(struct intel_encoder *encoder,
> - const struct intel_crtc_state *crtc_state,
> + const struct intel_cx0pll_state *pll_state,
> + bool is_dp, int port_clock,
> bool lane_reversal)
> {
> struct intel_display *display = to_intel_display(encoder);
> @@ -2751,18 +2763,17 @@ static void intel_program_port_clock_ctl(struct intel_encoder *encoder,
>
> val |= XELPDP_FORWARD_CLOCK_UNGATE;
>
> - if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
> - is_hdmi_frl(crtc_state->port_clock))
> + if (!is_dp && is_hdmi_frl(port_clock))
> val |= XELPDP_DDI_CLOCK_SELECT(XELPDP_DDI_CLOCK_SELECT_DIV18CLK);
> else
> val |= XELPDP_DDI_CLOCK_SELECT(XELPDP_DDI_CLOCK_SELECT_MAXPCLK);
>
> /* TODO: HDMI FRL */
> /* DP2.0 10G and 20G rates enable MPLLA*/
> - if (crtc_state->port_clock == 1000000 || crtc_state->port_clock == 2000000)
> - val |= crtc_state->dpll_hw_state.cx0pll.ssc_enabled ? XELPDP_SSC_ENABLE_PLLA : 0;
> + if (port_clock == 1000000 || port_clock == 2000000)
> + val |= pll_state->ssc_enabled ? XELPDP_SSC_ENABLE_PLLA : 0;
> else
> - val |= crtc_state->dpll_hw_state.cx0pll.ssc_enabled ? XELPDP_SSC_ENABLE_PLLB : 0;
> + val |= pll_state->ssc_enabled ? XELPDP_SSC_ENABLE_PLLB : 0;
>
> intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
> XELPDP_LANE1_PHY_CLOCK_SELECT | XELPDP_FORWARD_CLOCK_UNGATE |
> @@ -2992,8 +3003,9 @@ static u32 intel_cx0_get_pclk_pll_ack(u8 lane_mask)
> return val;
> }
>
> -static void intel_cx0pll_enable(struct intel_encoder *encoder,
> - const struct intel_crtc_state *crtc_state)
> +static void __intel_cx0pll_enable(struct intel_encoder *encoder,
> + const struct intel_cx0pll_state *pll_state,
> + bool is_dp, int port_clock, int lane_count)
> {
> struct intel_display *display = to_intel_display(encoder);
> enum phy phy = intel_encoder_to_phy(encoder);
> @@ -3007,7 +3019,7 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
> * 1. Program PORT_CLOCK_CTL REGISTER to configure
> * clock muxes, gating and SSC
> */
> - intel_program_port_clock_ctl(encoder, crtc_state, lane_reversal);
> + intel_program_port_clock_ctl(encoder, pll_state, is_dp, port_clock, lane_reversal);
>
> /* 2. Bring PHY out of reset. */
> intel_cx0_phy_lane_reset(encoder, lane_reversal);
> @@ -3027,15 +3039,15 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
>
> /* 5. Program PHY internal PLL internal registers. */
> if (intel_encoder_is_c10phy(encoder))
> - intel_c10_pll_program(display, crtc_state, encoder);
> + intel_c10_pll_program(display, encoder, &pll_state->c10);
> else
> - intel_c20_pll_program(display, crtc_state, encoder);
> + intel_c20_pll_program(display, encoder, &pll_state->c20, port_clock, is_dp);
>
> /*
> * 6. Program the enabled and disabled owned PHY lane
> * transmitters over message bus
> */
> - intel_cx0_program_phy_lane(encoder, crtc_state->lane_count, lane_reversal);
> + intel_cx0_program_phy_lane(encoder, lane_count, lane_reversal);
>
> /*
> * 7. Follow the Display Voltage Frequency Switching - Sequence
> @@ -3046,8 +3058,7 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
> * 8. Program DDI_CLK_VALFREQ to match intended DDI
> * clock frequency.
> */
> - intel_de_write(display, DDI_CLK_VALFREQ(encoder->port),
> - crtc_state->port_clock);
> + intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), port_clock);
>
> /*
> * 9. Set PORT_CLOCK_CTL register PCLK PLL Request
> @@ -3074,6 +3085,14 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
> intel_cx0_phy_transaction_end(encoder, wakeref);
> }
>
> +static void intel_cx0pll_enable(struct intel_encoder *encoder,
> + const struct intel_crtc_state *crtc_state)
> +{
> + __intel_cx0pll_enable(encoder, &crtc_state->dpll_hw_state.cx0pll,
> + intel_crtc_has_dp_encoder(crtc_state), crtc_state->port_clock, crtc_state->lane_count);
> +
> +}
> +
> int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder)
> {
> struct intel_display *display = to_intel_display(encoder);
--
Jani Nikula, Intel
next prev parent reply other threads:[~2025-01-29 14:40 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-29 13:01 [PATCH 0/2] drm/i915/display: Allow display PHYs to reset power state Mika Kahola
2025-01-29 13:01 ` [PATCH 1/2] drm/i915/display: Drop crtc_state from C10/C20 pll programming Mika Kahola
2025-01-29 14:40 ` Jani Nikula [this message]
2025-01-30 9:26 ` Kahola, Mika
2025-01-30 13:26 ` Imre Deak
2025-01-29 13:01 ` [PATCH 2/2] drm/i915/display: Allow display PHYs to reset power state Mika Kahola
2025-01-29 14:44 ` Jani Nikula
2025-01-30 9:52 ` Kahola, Mika
2025-01-29 14:46 ` ✓ CI.Patch_applied: success for " Patchwork
2025-01-29 14:47 ` ✗ CI.checkpatch: warning " Patchwork
2025-01-29 14:48 ` ✓ CI.KUnit: success " Patchwork
2025-01-29 15:05 ` ✓ CI.Build: " Patchwork
2025-01-29 15:07 ` ✗ CI.Hooks: failure " Patchwork
2025-01-29 15:08 ` ✓ CI.checksparse: success " Patchwork
2025-01-29 15:19 ` ✗ Fi.CI.CHECKPATCH: warning " Patchwork
2025-01-29 15:35 ` ✓ Xe.CI.BAT: success " Patchwork
2025-01-29 15:36 ` ✗ i915.CI.BAT: failure " Patchwork
2025-01-29 23:00 ` ✗ Xe.CI.Full: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87tt9h8z0e.fsf@intel.com \
--to=jani.nikula@linux.intel.com \
--cc=imre.deak@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=intel-xe@lists.freedesktop.org \
--cc=mika.kahola@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.