diff mbox series

[11/23] drm/i915/rkl: Add cdclk support

Message ID 20200501170748.358135-12-matthew.d.roper@intel.com (mailing list archive)
State New, archived
Headers show
Series Introduce Rocket Lake | expand

Commit Message

Matt Roper May 1, 2020, 5:07 p.m. UTC
Note that the 192000 clock frequencies can be achieved with different
pairs of ratio+divider, which is something we haven't encountered
before.  If any of those ratios were common with other legal cdclk
values, then it would mean we could avoid triggering full modesets if we
just needed to change the divider.  However at the moment there don't
appear to be any valid cdclks that share the same ratio so we can't take
advantage of this and it doesn't really matter which approach we use to
achieve the 192000 cdclk.  For now our driver functions that operate on
the table will just always pick the first entry (lower ratio + lower
divider).

Bspec: 49202
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/display/intel_cdclk.c | 54 +++++++++++++++++++---
 1 file changed, 48 insertions(+), 6 deletions(-)

Comments

Khor, Swee Aun May 2, 2020, 4:26 p.m. UTC | #1
Hi Matt,
The follow cdclk doesn't looked right, isn’t it should be 96000 and 540000 according to their respective divider and ratio?
....
+	{ .refclk = 19200, .cdclk = 192000, .divider = 3, .ratio = 15 },
....
+	{ .refclk = 24000, .cdclk = 552000, .divider = 2, .ratio = 45 },
....

Regards,
SweeAun

-----Original Message-----
From: Intel-gfx <intel-gfx-bounces@lists.freedesktop.org> On Behalf Of Matt Roper
Sent: Saturday, May 2, 2020 1:08 AM
To: intel-gfx@lists.freedesktop.org
Subject: [Intel-gfx] [PATCH 11/23] drm/i915/rkl: Add cdclk support

Note that the 192000 clock frequencies can be achieved with different pairs of ratio+divider, which is something we haven't encountered before.  If any of those ratios were common with other legal cdclk values, then it would mean we could avoid triggering full modesets if we just needed to change the divider.  However at the moment there don't appear to be any valid cdclks that share the same ratio so we can't take advantage of this and it doesn't really matter which approach we use to achieve the 192000 cdclk.  For now our driver functions that operate on the table will just always pick the first entry (lower ratio + lower divider).

Bspec: 49202
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/display/intel_cdclk.c | 54 +++++++++++++++++++---
 1 file changed, 48 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 979a0241fdcb..4ca87260e8ba 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -1230,6 +1230,40 @@ static const struct intel_cdclk_vals icl_cdclk_table[] = {
 	{}
 };
 
+/*
+ * RKL has multiple divider+ratio pairs that can hit cdclk=192000.  Our
+ * functions to read these tables will just always pick the first one 
+which
+ * should be fine since there's no other valid cdclk value that can be 
+achieved
+ * via the same ratio with a different divider (i.e., no opportunity to 
+avoid a
+ * full modeset).
+ */
+static const struct intel_cdclk_vals rkl_cdclk_table[] = {
+	{ .refclk = 19200, .cdclk = 172800, .divider = 3, .ratio = 27 },
+	{ .refclk = 19200, .cdclk = 192000, .divider = 2, .ratio = 20 },
+	{ .refclk = 19200, .cdclk = 192000, .divider = 3, .ratio = 15 },
+	{ .refclk = 19200, .cdclk = 307200, .divider = 2, .ratio = 32 },
+	{ .refclk = 19200, .cdclk = 326400, .divider = 4, .ratio = 68 },
+	{ .refclk = 19200, .cdclk = 556800, .divider = 2, .ratio = 58 },
+	{ .refclk = 19200, .cdclk = 652800, .divider = 2, .ratio = 68 },
+
+	{ .refclk = 24000, .cdclk = 176000, .divider = 3, .ratio = 22 },
+	{ .refclk = 24000, .cdclk = 192000, .divider = 2, .ratio = 16 },
+	{ .refclk = 24000, .cdclk = 192000, .divider = 3, .ratio = 24 },
+	{ .refclk = 24000, .cdclk = 312000, .divider = 2, .ratio = 26 },
+	{ .refclk = 24000, .cdclk = 324000, .divider = 4, .ratio = 54 },
+	{ .refclk = 24000, .cdclk = 552000, .divider = 2, .ratio = 45 },
+	{ .refclk = 24000, .cdclk = 648000, .divider = 2, .ratio = 54 },
+
+	{ .refclk = 38400, .cdclk = 179200, .divider = 3, .ratio = 14 },
+	{ .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 10 },
+	{ .refclk = 38400, .cdclk = 192000, .divider = 3, .ratio = 15 },
+	{ .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16 },
+	{ .refclk = 38400, .cdclk = 326400, .divider = 4, .ratio = 34 },
+	{ .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29 },
+	{ .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34 },
+	{}
+};
+
 static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)  {
 	const struct intel_cdclk_vals *table = dev_priv->cdclk.table; @@ -1405,8 +1439,8 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
 		div = 2;
 		break;
 	case BXT_CDCLK_CD2X_DIV_SEL_1_5:
-		drm_WARN(&dev_priv->drm,
-			 IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10,
+		drm_WARN(&dev_priv->drm, IS_GEMINILAKE(dev_priv) ||
+			 (INTEL_GEN(dev_priv) >= 10 && !IS_ROCKETLAKE(dev_priv)),
 			 "Unsupported divider\n");
 		div = 3;
 		break;
@@ -1414,7 +1448,8 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
 		div = 4;
 		break;
 	case BXT_CDCLK_CD2X_DIV_SEL_4:
-		drm_WARN(&dev_priv->drm, INTEL_GEN(dev_priv) >= 10,
+		drm_WARN(&dev_priv->drm,
+			 INTEL_GEN(dev_priv) >= 10 && !IS_ROCKETLAKE(dev_priv),
 			 "Unsupported divider\n");
 		div = 8;
 		break;
@@ -1564,7 +1599,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 		break;
 	case 3:
 		drm_WARN(&dev_priv->drm,
-			 IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10,
+			 IS_GEMINILAKE(dev_priv) ||
+			 (INTEL_GEN(dev_priv) >= 10 && !IS_ROCKETLAKE(dev_priv)),
 			 "Unsupported divider\n");
 		divider = BXT_CDCLK_CD2X_DIV_SEL_1_5;
 		break;
@@ -1572,7 +1608,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 		divider = BXT_CDCLK_CD2X_DIV_SEL_2;
 		break;
 	case 8:
-		drm_WARN(&dev_priv->drm, INTEL_GEN(dev_priv) >= 10,
+		drm_WARN(&dev_priv->drm,
+			 INTEL_GEN(dev_priv) >= 10 && !IS_ROCKETLAKE(dev_priv),
 			 "Unsupported divider\n");
 		divider = BXT_CDCLK_CD2X_DIV_SEL_4;
 		break;
@@ -2758,7 +2795,12 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv)
  */
 void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)  {
-	if (INTEL_GEN(dev_priv) >= 12) {
+	if (IS_ROCKETLAKE(dev_priv)) {
+		dev_priv->display.set_cdclk = bxt_set_cdclk;
+		dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
+		dev_priv->display.calc_voltage_level = tgl_calc_voltage_level;
+		dev_priv->cdclk.table = rkl_cdclk_table;
+	} else if (INTEL_GEN(dev_priv) >= 12) {
 		dev_priv->display.set_cdclk = bxt_set_cdclk;
 		dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
 		dev_priv->display.calc_voltage_level = tgl_calc_voltage_level;
--
2.24.1
Matt Roper May 4, 2020, 5:33 p.m. UTC | #2
On Sat, May 02, 2020 at 09:26:51AM -0700, Khor, Swee Aun wrote:
> Hi Matt,
> The follow cdclk doesn't looked right, isn’t it should be 96000 and 540000 according to their respective divider and ratio?
> ....
> +{ .refclk = 19200, .cdclk = 192000, .divider = 3, .ratio = 15 },
> ....
> +{ .refclk = 24000, .cdclk = 552000, .divider = 2, .ratio = 45 },
> ....

Yeah, you're right.  The first one appears to have been removed from the
bspec now and the second one appears to be a typo on my part (ratio
should be 46 instead of 45).

Looks like there have been a couple other recent modifications to the
bspec as well that I should update this patch to capture.  Thanks for
pointing that out!


Matt

> 
> Regards,
> SweeAun
> 
> -----Original Message-----
> From: Intel-gfx <intel-gfx-bounces@lists.freedesktop.org> On Behalf Of Matt Roper
> Sent: Saturday, May 2, 2020 1:08 AM
> To: intel-gfx@lists.freedesktop.org
> Subject: [Intel-gfx] [PATCH 11/23] drm/i915/rkl: Add cdclk support
> 
> Note that the 192000 clock frequencies can be achieved with different pairs of ratio+divider, which is something we haven't encountered before.  If any of those ratios were common with other legal cdclk values, then it would mean we could avoid triggering full modesets if we just needed to change the divider.  However at the moment there don't appear to be any valid cdclks that share the same ratio so we can't take advantage of this and it doesn't really matter which approach we use to achieve the 192000 cdclk.  For now our driver functions that operate on the table will just always pick the first entry (lower ratio + lower divider).
> 
> Bspec: 49202
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_cdclk.c | 54 +++++++++++++++++++---
>  1 file changed, 48 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
> index 979a0241fdcb..4ca87260e8ba 100644
> --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
> @@ -1230,6 +1230,40 @@ static const struct intel_cdclk_vals icl_cdclk_table[] = {
>  {}
>  };
> 
> +/*
> + * RKL has multiple divider+ratio pairs that can hit cdclk=192000.  Our
> + * functions to read these tables will just always pick the first one
> +which
> + * should be fine since there's no other valid cdclk value that can be
> +achieved
> + * via the same ratio with a different divider (i.e., no opportunity to
> +avoid a
> + * full modeset).
> + */
> +static const struct intel_cdclk_vals rkl_cdclk_table[] = {
> +{ .refclk = 19200, .cdclk = 172800, .divider = 3, .ratio = 27 },
> +{ .refclk = 19200, .cdclk = 192000, .divider = 2, .ratio = 20 },
> +{ .refclk = 19200, .cdclk = 192000, .divider = 3, .ratio = 15 },
> +{ .refclk = 19200, .cdclk = 307200, .divider = 2, .ratio = 32 },
> +{ .refclk = 19200, .cdclk = 326400, .divider = 4, .ratio = 68 },
> +{ .refclk = 19200, .cdclk = 556800, .divider = 2, .ratio = 58 },
> +{ .refclk = 19200, .cdclk = 652800, .divider = 2, .ratio = 68 },
> +
> +{ .refclk = 24000, .cdclk = 176000, .divider = 3, .ratio = 22 },
> +{ .refclk = 24000, .cdclk = 192000, .divider = 2, .ratio = 16 },
> +{ .refclk = 24000, .cdclk = 192000, .divider = 3, .ratio = 24 },
> +{ .refclk = 24000, .cdclk = 312000, .divider = 2, .ratio = 26 },
> +{ .refclk = 24000, .cdclk = 324000, .divider = 4, .ratio = 54 },
> +{ .refclk = 24000, .cdclk = 552000, .divider = 2, .ratio = 45 },
> +{ .refclk = 24000, .cdclk = 648000, .divider = 2, .ratio = 54 },
> +
> +{ .refclk = 38400, .cdclk = 179200, .divider = 3, .ratio = 14 },
> +{ .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 10 },
> +{ .refclk = 38400, .cdclk = 192000, .divider = 3, .ratio = 15 },
> +{ .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16 },
> +{ .refclk = 38400, .cdclk = 326400, .divider = 4, .ratio = 34 },
> +{ .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29 },
> +{ .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34 },
> +{}
> +};
> +
>  static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)  {
>  const struct intel_cdclk_vals *table = dev_priv->cdclk.table; @@ -1405,8 +1439,8 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
>  div = 2;
>  break;
>  case BXT_CDCLK_CD2X_DIV_SEL_1_5:
> -drm_WARN(&dev_priv->drm,
> - IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10,
> +drm_WARN(&dev_priv->drm, IS_GEMINILAKE(dev_priv) ||
> + (INTEL_GEN(dev_priv) >= 10 && !IS_ROCKETLAKE(dev_priv)),
>   "Unsupported divider\n");
>  div = 3;
>  break;
> @@ -1414,7 +1448,8 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
>  div = 4;
>  break;
>  case BXT_CDCLK_CD2X_DIV_SEL_4:
> -drm_WARN(&dev_priv->drm, INTEL_GEN(dev_priv) >= 10,
> +drm_WARN(&dev_priv->drm,
> + INTEL_GEN(dev_priv) >= 10 && !IS_ROCKETLAKE(dev_priv),
>   "Unsupported divider\n");
>  div = 8;
>  break;
> @@ -1564,7 +1599,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
>  break;
>  case 3:
>  drm_WARN(&dev_priv->drm,
> - IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10,
> + IS_GEMINILAKE(dev_priv) ||
> + (INTEL_GEN(dev_priv) >= 10 && !IS_ROCKETLAKE(dev_priv)),
>   "Unsupported divider\n");
>  divider = BXT_CDCLK_CD2X_DIV_SEL_1_5;
>  break;
> @@ -1572,7 +1608,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
>  divider = BXT_CDCLK_CD2X_DIV_SEL_2;
>  break;
>  case 8:
> -drm_WARN(&dev_priv->drm, INTEL_GEN(dev_priv) >= 10,
> +drm_WARN(&dev_priv->drm,
> + INTEL_GEN(dev_priv) >= 10 && !IS_ROCKETLAKE(dev_priv),
>   "Unsupported divider\n");
>  divider = BXT_CDCLK_CD2X_DIV_SEL_4;
>  break;
> @@ -2758,7 +2795,12 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv)
>   */
>  void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)  {
> -if (INTEL_GEN(dev_priv) >= 12) {
> +if (IS_ROCKETLAKE(dev_priv)) {
> +dev_priv->display.set_cdclk = bxt_set_cdclk;
> +dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
> +dev_priv->display.calc_voltage_level = tgl_calc_voltage_level;
> +dev_priv->cdclk.table = rkl_cdclk_table;
> +} else if (INTEL_GEN(dev_priv) >= 12) {
>  dev_priv->display.set_cdclk = bxt_set_cdclk;
>  dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
>  dev_priv->display.calc_voltage_level = tgl_calc_voltage_level;
> --
> 2.24.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Matt Roper May 4, 2020, 8:20 p.m. UTC | #3
On Mon, May 04, 2020 at 10:33:41AM -0700, Matt Roper wrote:
> On Sat, May 02, 2020 at 09:26:51AM -0700, Khor, Swee Aun wrote:
> > Hi Matt,
> > The follow cdclk doesn't looked right, isn’t it should be 96000 and 540000 according to their respective divider and ratio?
> > ....
> > +{ .refclk = 19200, .cdclk = 192000, .divider = 3, .ratio = 15 },
> > ....
> > +{ .refclk = 24000, .cdclk = 552000, .divider = 2, .ratio = 45 },
> > ....
> 
> Yeah, you're right.  The first one appears to have been removed from the
> bspec now and the second one appears to be a typo on my part (ratio
> should be 46 instead of 45).
> 
> Looks like there have been a couple other recent modifications to the
> bspec as well that I should update this patch to capture.  Thanks for
> pointing that out!

Actually, it looks like the latest updates in the bspec have now made
the RKL cdclk table identical to the TGL/ICL table.  So we should be
able to drop this patch completely now.


Matt

> 
> 
> Matt
> 
> > 
> > Regards,
> > SweeAun
> > 
> > -----Original Message-----
> > From: Intel-gfx <intel-gfx-bounces@lists.freedesktop.org> On Behalf Of Matt Roper
> > Sent: Saturday, May 2, 2020 1:08 AM
> > To: intel-gfx@lists.freedesktop.org
> > Subject: [Intel-gfx] [PATCH 11/23] drm/i915/rkl: Add cdclk support
> > 
> > Note that the 192000 clock frequencies can be achieved with different pairs of ratio+divider, which is something we haven't encountered before.  If any of those ratios were common with other legal cdclk values, then it would mean we could avoid triggering full modesets if we just needed to change the divider.  However at the moment there don't appear to be any valid cdclks that share the same ratio so we can't take advantage of this and it doesn't really matter which approach we use to achieve the 192000 cdclk.  For now our driver functions that operate on the table will just always pick the first entry (lower ratio + lower divider).
> > 
> > Bspec: 49202
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_cdclk.c | 54 +++++++++++++++++++---
> >  1 file changed, 48 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
> > index 979a0241fdcb..4ca87260e8ba 100644
> > --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
> > +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
> > @@ -1230,6 +1230,40 @@ static const struct intel_cdclk_vals icl_cdclk_table[] = {
> >  {}
> >  };
> > 
> > +/*
> > + * RKL has multiple divider+ratio pairs that can hit cdclk=192000.  Our
> > + * functions to read these tables will just always pick the first one
> > +which
> > + * should be fine since there's no other valid cdclk value that can be
> > +achieved
> > + * via the same ratio with a different divider (i.e., no opportunity to
> > +avoid a
> > + * full modeset).
> > + */
> > +static const struct intel_cdclk_vals rkl_cdclk_table[] = {
> > +{ .refclk = 19200, .cdclk = 172800, .divider = 3, .ratio = 27 },
> > +{ .refclk = 19200, .cdclk = 192000, .divider = 2, .ratio = 20 },
> > +{ .refclk = 19200, .cdclk = 192000, .divider = 3, .ratio = 15 },
> > +{ .refclk = 19200, .cdclk = 307200, .divider = 2, .ratio = 32 },
> > +{ .refclk = 19200, .cdclk = 326400, .divider = 4, .ratio = 68 },
> > +{ .refclk = 19200, .cdclk = 556800, .divider = 2, .ratio = 58 },
> > +{ .refclk = 19200, .cdclk = 652800, .divider = 2, .ratio = 68 },
> > +
> > +{ .refclk = 24000, .cdclk = 176000, .divider = 3, .ratio = 22 },
> > +{ .refclk = 24000, .cdclk = 192000, .divider = 2, .ratio = 16 },
> > +{ .refclk = 24000, .cdclk = 192000, .divider = 3, .ratio = 24 },
> > +{ .refclk = 24000, .cdclk = 312000, .divider = 2, .ratio = 26 },
> > +{ .refclk = 24000, .cdclk = 324000, .divider = 4, .ratio = 54 },
> > +{ .refclk = 24000, .cdclk = 552000, .divider = 2, .ratio = 45 },
> > +{ .refclk = 24000, .cdclk = 648000, .divider = 2, .ratio = 54 },
> > +
> > +{ .refclk = 38400, .cdclk = 179200, .divider = 3, .ratio = 14 },
> > +{ .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 10 },
> > +{ .refclk = 38400, .cdclk = 192000, .divider = 3, .ratio = 15 },
> > +{ .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16 },
> > +{ .refclk = 38400, .cdclk = 326400, .divider = 4, .ratio = 34 },
> > +{ .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29 },
> > +{ .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34 },
> > +{}
> > +};
> > +
> >  static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)  {
> >  const struct intel_cdclk_vals *table = dev_priv->cdclk.table; @@ -1405,8 +1439,8 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
> >  div = 2;
> >  break;
> >  case BXT_CDCLK_CD2X_DIV_SEL_1_5:
> > -drm_WARN(&dev_priv->drm,
> > - IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10,
> > +drm_WARN(&dev_priv->drm, IS_GEMINILAKE(dev_priv) ||
> > + (INTEL_GEN(dev_priv) >= 10 && !IS_ROCKETLAKE(dev_priv)),
> >   "Unsupported divider\n");
> >  div = 3;
> >  break;
> > @@ -1414,7 +1448,8 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
> >  div = 4;
> >  break;
> >  case BXT_CDCLK_CD2X_DIV_SEL_4:
> > -drm_WARN(&dev_priv->drm, INTEL_GEN(dev_priv) >= 10,
> > +drm_WARN(&dev_priv->drm,
> > + INTEL_GEN(dev_priv) >= 10 && !IS_ROCKETLAKE(dev_priv),
> >   "Unsupported divider\n");
> >  div = 8;
> >  break;
> > @@ -1564,7 +1599,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
> >  break;
> >  case 3:
> >  drm_WARN(&dev_priv->drm,
> > - IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10,
> > + IS_GEMINILAKE(dev_priv) ||
> > + (INTEL_GEN(dev_priv) >= 10 && !IS_ROCKETLAKE(dev_priv)),
> >   "Unsupported divider\n");
> >  divider = BXT_CDCLK_CD2X_DIV_SEL_1_5;
> >  break;
> > @@ -1572,7 +1608,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
> >  divider = BXT_CDCLK_CD2X_DIV_SEL_2;
> >  break;
> >  case 8:
> > -drm_WARN(&dev_priv->drm, INTEL_GEN(dev_priv) >= 10,
> > +drm_WARN(&dev_priv->drm,
> > + INTEL_GEN(dev_priv) >= 10 && !IS_ROCKETLAKE(dev_priv),
> >   "Unsupported divider\n");
> >  divider = BXT_CDCLK_CD2X_DIV_SEL_4;
> >  break;
> > @@ -2758,7 +2795,12 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv)
> >   */
> >  void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)  {
> > -if (INTEL_GEN(dev_priv) >= 12) {
> > +if (IS_ROCKETLAKE(dev_priv)) {
> > +dev_priv->display.set_cdclk = bxt_set_cdclk;
> > +dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
> > +dev_priv->display.calc_voltage_level = tgl_calc_voltage_level;
> > +dev_priv->cdclk.table = rkl_cdclk_table;
> > +} else if (INTEL_GEN(dev_priv) >= 12) {
> >  dev_priv->display.set_cdclk = bxt_set_cdclk;
> >  dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
> >  dev_priv->display.calc_voltage_level = tgl_calc_voltage_level;
> > --
> > 2.24.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Matt Roper
> Graphics Software Engineer
> VTT-OSGC Platform Enablement
> Intel Corporation
> (916) 356-2795
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 979a0241fdcb..4ca87260e8ba 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -1230,6 +1230,40 @@  static const struct intel_cdclk_vals icl_cdclk_table[] = {
 	{}
 };
 
+/*
+ * RKL has multiple divider+ratio pairs that can hit cdclk=192000.  Our
+ * functions to read these tables will just always pick the first one which
+ * should be fine since there's no other valid cdclk value that can be achieved
+ * via the same ratio with a different divider (i.e., no opportunity to avoid a
+ * full modeset).
+ */
+static const struct intel_cdclk_vals rkl_cdclk_table[] = {
+	{ .refclk = 19200, .cdclk = 172800, .divider = 3, .ratio = 27 },
+	{ .refclk = 19200, .cdclk = 192000, .divider = 2, .ratio = 20 },
+	{ .refclk = 19200, .cdclk = 192000, .divider = 3, .ratio = 15 },
+	{ .refclk = 19200, .cdclk = 307200, .divider = 2, .ratio = 32 },
+	{ .refclk = 19200, .cdclk = 326400, .divider = 4, .ratio = 68 },
+	{ .refclk = 19200, .cdclk = 556800, .divider = 2, .ratio = 58 },
+	{ .refclk = 19200, .cdclk = 652800, .divider = 2, .ratio = 68 },
+
+	{ .refclk = 24000, .cdclk = 176000, .divider = 3, .ratio = 22 },
+	{ .refclk = 24000, .cdclk = 192000, .divider = 2, .ratio = 16 },
+	{ .refclk = 24000, .cdclk = 192000, .divider = 3, .ratio = 24 },
+	{ .refclk = 24000, .cdclk = 312000, .divider = 2, .ratio = 26 },
+	{ .refclk = 24000, .cdclk = 324000, .divider = 4, .ratio = 54 },
+	{ .refclk = 24000, .cdclk = 552000, .divider = 2, .ratio = 45 },
+	{ .refclk = 24000, .cdclk = 648000, .divider = 2, .ratio = 54 },
+
+	{ .refclk = 38400, .cdclk = 179200, .divider = 3, .ratio = 14 },
+	{ .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 10 },
+	{ .refclk = 38400, .cdclk = 192000, .divider = 3, .ratio = 15 },
+	{ .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16 },
+	{ .refclk = 38400, .cdclk = 326400, .divider = 4, .ratio = 34 },
+	{ .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29 },
+	{ .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34 },
+	{}
+};
+
 static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)
 {
 	const struct intel_cdclk_vals *table = dev_priv->cdclk.table;
@@ -1405,8 +1439,8 @@  static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
 		div = 2;
 		break;
 	case BXT_CDCLK_CD2X_DIV_SEL_1_5:
-		drm_WARN(&dev_priv->drm,
-			 IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10,
+		drm_WARN(&dev_priv->drm, IS_GEMINILAKE(dev_priv) ||
+			 (INTEL_GEN(dev_priv) >= 10 && !IS_ROCKETLAKE(dev_priv)),
 			 "Unsupported divider\n");
 		div = 3;
 		break;
@@ -1414,7 +1448,8 @@  static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
 		div = 4;
 		break;
 	case BXT_CDCLK_CD2X_DIV_SEL_4:
-		drm_WARN(&dev_priv->drm, INTEL_GEN(dev_priv) >= 10,
+		drm_WARN(&dev_priv->drm,
+			 INTEL_GEN(dev_priv) >= 10 && !IS_ROCKETLAKE(dev_priv),
 			 "Unsupported divider\n");
 		div = 8;
 		break;
@@ -1564,7 +1599,8 @@  static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 		break;
 	case 3:
 		drm_WARN(&dev_priv->drm,
-			 IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10,
+			 IS_GEMINILAKE(dev_priv) ||
+			 (INTEL_GEN(dev_priv) >= 10 && !IS_ROCKETLAKE(dev_priv)),
 			 "Unsupported divider\n");
 		divider = BXT_CDCLK_CD2X_DIV_SEL_1_5;
 		break;
@@ -1572,7 +1608,8 @@  static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 		divider = BXT_CDCLK_CD2X_DIV_SEL_2;
 		break;
 	case 8:
-		drm_WARN(&dev_priv->drm, INTEL_GEN(dev_priv) >= 10,
+		drm_WARN(&dev_priv->drm,
+			 INTEL_GEN(dev_priv) >= 10 && !IS_ROCKETLAKE(dev_priv),
 			 "Unsupported divider\n");
 		divider = BXT_CDCLK_CD2X_DIV_SEL_4;
 		break;
@@ -2758,7 +2795,12 @@  u32 intel_read_rawclk(struct drm_i915_private *dev_priv)
  */
 void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
 {
-	if (INTEL_GEN(dev_priv) >= 12) {
+	if (IS_ROCKETLAKE(dev_priv)) {
+		dev_priv->display.set_cdclk = bxt_set_cdclk;
+		dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
+		dev_priv->display.calc_voltage_level = tgl_calc_voltage_level;
+		dev_priv->cdclk.table = rkl_cdclk_table;
+	} else if (INTEL_GEN(dev_priv) >= 12) {
 		dev_priv->display.set_cdclk = bxt_set_cdclk;
 		dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
 		dev_priv->display.calc_voltage_level = tgl_calc_voltage_level;