diff mbox

drm/i915: try harder to find WR PLL clock settings

Message ID 1344603783-4386-1-git-send-email-przanoni@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Paulo Zanoni Aug. 10, 2012, 1:03 p.m. UTC
From: Paulo Zanoni <paulo.r.zanoni@intel.com>

If we don't find the exact refresh rate, go with the next one. This
makes some modes work for me. They won't have the best settings, but
will at least have something. Just returning from this function when
we don't find the perfect settings does not help us at all.

Version 2:
  - Remove duplicate lines on the clock table.
  - Add back debug message with refresh, p, n2 and r2.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 39 +++++++++++++++++----------------------
 1 file changed, 17 insertions(+), 22 deletions(-)

Comments

Jani Nikula Aug. 10, 2012, 1:18 p.m. UTC | #1
On Fri, 10 Aug 2012, Paulo Zanoni <przanoni@gmail.com> wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> If we don't find the exact refresh rate, go with the next one. This
> makes some modes work for me. They won't have the best settings, but
> will at least have something. Just returning from this function when
> we don't find the perfect settings does not help us at all.
>
> Version 2:
>   - Remove duplicate lines on the clock table.
>   - Add back debug message with refresh, p, n2 and r2.

Reviewed-by: Jani Nikula <jani.nikula@intel.com>

>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 39 +++++++++++++++++----------------------
>  1 file changed, 17 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index ff03a3a..9584226 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -267,7 +267,8 @@ struct wrpll_tmds_clock {
>  	u16 r2;		/* Reference divider */
>  };
>  
> -/* Table of matching values for WRPLL clocks programming for each frequency */
> +/* Table of matching values for WRPLL clocks programming for each frequency.
> + * The code assumes this table is sorted. */
>  static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
>  	{19750,	38,	25,	18},
>  	{20000,	48,	32,	18},
> @@ -277,7 +278,6 @@ static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
>  	{23000,	36,	23,	15},
>  	{23500,	40,	40,	23},
>  	{23750,	26,	16,	14},
> -	{23750,	26,	16,	14},
>  	{24000,	36,	24,	15},
>  	{25000,	36,	25,	15},
>  	{25175,	26,	40,	33},
> @@ -437,7 +437,6 @@ static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
>  	{108000,	8,	24,	15},
>  	{108108,	8,	173,	108},
>  	{109000,	6,	23,	19},
> -	{109000,	6,	23,	19},
>  	{110000,	6,	22,	18},
>  	{110013,	6,	22,	18},
>  	{110250,	8,	49,	30},
> @@ -614,7 +613,6 @@ static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
>  	{218250,	4,	42,	26},
>  	{218750,	4,	34,	21},
>  	{219000,	4,	47,	29},
> -	{219000,	4,	47,	29},
>  	{220000,	4,	44,	27},
>  	{220640,	4,	49,	30},
>  	{220750,	4,	36,	22},
> @@ -658,7 +656,7 @@ void intel_ddi_mode_set(struct drm_encoder *encoder,
>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
>  	int port = intel_hdmi->ddi_port;
>  	int pipe = intel_crtc->pipe;
> -	int p, n2, r2, valid=0;
> +	int p, n2, r2;
>  	u32 temp, i;
>  
>  	/* On Haswell, we need to enable the clocks and prepare DDI function to
> @@ -666,26 +664,23 @@ void intel_ddi_mode_set(struct drm_encoder *encoder,
>  	 */
>  	DRM_DEBUG_KMS("Preparing HDMI DDI mode for Haswell on port %c, pipe %c\n", port_name(port), pipe_name(pipe));
>  
> -	for (i=0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++) {
> -		if (crtc->mode.clock == wrpll_tmds_clock_table[i].clock) {
> -			p = wrpll_tmds_clock_table[i].p;
> -			n2 = wrpll_tmds_clock_table[i].n2;
> -			r2 = wrpll_tmds_clock_table[i].r2;
> +	for (i = 0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++)
> +		if (crtc->mode.clock <= wrpll_tmds_clock_table[i].clock)
> +			break;
>  
> -			DRM_DEBUG_KMS("WR PLL clock: found settings for %dKHz refresh rate: p=%d, n2=%d, r2=%d\n",
> -					crtc->mode.clock,
> -					p, n2, r2);
> +	if (i == ARRAY_SIZE(wrpll_tmds_clock_table))
> +		i--;
>  
> -			valid = 1;
> -			break;
> -		}
> -	}
> +	p = wrpll_tmds_clock_table[i].p;
> +	n2 = wrpll_tmds_clock_table[i].n2;
> +	r2 = wrpll_tmds_clock_table[i].r2;
>  
> -	if (!valid) {
> -		DRM_ERROR("Unable to find WR PLL clock settings for %dKHz refresh rate\n",
> -				crtc->mode.clock);
> -		return;
> -	}
> +	if (wrpll_tmds_clock_table[i].clock != crtc->mode.clock)
> +		DRM_INFO("WR PLL: using settings for %dKHz on %dKHz mode\n",
> +			 wrpll_tmds_clock_table[i].clock, crtc->mode.clock);
> +
> +	DRM_DEBUG_KMS("WR PLL: %dKHz refresh rate with p=%d, n2=%d r2=%d\n",
> +		      crtc->mode.clock, p, n2, r2);
>  
>  	/* Enable LCPLL if disabled */
>  	temp = I915_READ(LCPLL_CTL);
> -- 
> 1.7.11.2
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Daniel Vetter Aug. 10, 2012, 4:40 p.m. UTC | #2
On Fri, Aug 10, 2012 at 04:18:45PM +0300, Jani Nikula wrote:
> On Fri, 10 Aug 2012, Paulo Zanoni <przanoni@gmail.com> wrote:
> > From: Paulo Zanoni <paulo.r.zanoni@intel.com>
> >
> > If we don't find the exact refresh rate, go with the next one. This
> > makes some modes work for me. They won't have the best settings, but
> > will at least have something. Just returning from this function when
> > we don't find the perfect settings does not help us at all.
> >
> > Version 2:
> >   - Remove duplicate lines on the clock table.
> >   - Add back debug message with refresh, p, n2 and r2.
> 
> Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Queued for -next, thanks for the review.
-Daniel
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index ff03a3a..9584226 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -267,7 +267,8 @@  struct wrpll_tmds_clock {
 	u16 r2;		/* Reference divider */
 };
 
-/* Table of matching values for WRPLL clocks programming for each frequency */
+/* Table of matching values for WRPLL clocks programming for each frequency.
+ * The code assumes this table is sorted. */
 static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
 	{19750,	38,	25,	18},
 	{20000,	48,	32,	18},
@@ -277,7 +278,6 @@  static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
 	{23000,	36,	23,	15},
 	{23500,	40,	40,	23},
 	{23750,	26,	16,	14},
-	{23750,	26,	16,	14},
 	{24000,	36,	24,	15},
 	{25000,	36,	25,	15},
 	{25175,	26,	40,	33},
@@ -437,7 +437,6 @@  static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
 	{108000,	8,	24,	15},
 	{108108,	8,	173,	108},
 	{109000,	6,	23,	19},
-	{109000,	6,	23,	19},
 	{110000,	6,	22,	18},
 	{110013,	6,	22,	18},
 	{110250,	8,	49,	30},
@@ -614,7 +613,6 @@  static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
 	{218250,	4,	42,	26},
 	{218750,	4,	34,	21},
 	{219000,	4,	47,	29},
-	{219000,	4,	47,	29},
 	{220000,	4,	44,	27},
 	{220640,	4,	49,	30},
 	{220750,	4,	36,	22},
@@ -658,7 +656,7 @@  void intel_ddi_mode_set(struct drm_encoder *encoder,
 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
 	int port = intel_hdmi->ddi_port;
 	int pipe = intel_crtc->pipe;
-	int p, n2, r2, valid=0;
+	int p, n2, r2;
 	u32 temp, i;
 
 	/* On Haswell, we need to enable the clocks and prepare DDI function to
@@ -666,26 +664,23 @@  void intel_ddi_mode_set(struct drm_encoder *encoder,
 	 */
 	DRM_DEBUG_KMS("Preparing HDMI DDI mode for Haswell on port %c, pipe %c\n", port_name(port), pipe_name(pipe));
 
-	for (i=0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++) {
-		if (crtc->mode.clock == wrpll_tmds_clock_table[i].clock) {
-			p = wrpll_tmds_clock_table[i].p;
-			n2 = wrpll_tmds_clock_table[i].n2;
-			r2 = wrpll_tmds_clock_table[i].r2;
+	for (i = 0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++)
+		if (crtc->mode.clock <= wrpll_tmds_clock_table[i].clock)
+			break;
 
-			DRM_DEBUG_KMS("WR PLL clock: found settings for %dKHz refresh rate: p=%d, n2=%d, r2=%d\n",
-					crtc->mode.clock,
-					p, n2, r2);
+	if (i == ARRAY_SIZE(wrpll_tmds_clock_table))
+		i--;
 
-			valid = 1;
-			break;
-		}
-	}
+	p = wrpll_tmds_clock_table[i].p;
+	n2 = wrpll_tmds_clock_table[i].n2;
+	r2 = wrpll_tmds_clock_table[i].r2;
 
-	if (!valid) {
-		DRM_ERROR("Unable to find WR PLL clock settings for %dKHz refresh rate\n",
-				crtc->mode.clock);
-		return;
-	}
+	if (wrpll_tmds_clock_table[i].clock != crtc->mode.clock)
+		DRM_INFO("WR PLL: using settings for %dKHz on %dKHz mode\n",
+			 wrpll_tmds_clock_table[i].clock, crtc->mode.clock);
+
+	DRM_DEBUG_KMS("WR PLL: %dKHz refresh rate with p=%d, n2=%d r2=%d\n",
+		      crtc->mode.clock, p, n2, r2);
 
 	/* Enable LCPLL if disabled */
 	temp = I915_READ(LCPLL_CTL);