All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Purushothaman, Vijay A" <vijay.a.purushothaman@intel.com>
To: Daniel Vetter <daniel@ffwll.ch>, Jesse Barnes <jbarnes@virtuousgeek.org>
Cc: "intel-gfx@lists.freedesktop.org" <intel-gfx@lists.freedesktop.org>
Subject: Re: [PATCH 1/7] drm/i915: ValleyView mode setting limits and PLL functions
Date: Wed, 13 Jun 2012 15:04:29 +0000	[thread overview]
Message-ID: <D13E68CE400A0B46A298335DB646F1BF16447C@BGSMSX101.gar.corp.intel.com> (raw)
In-Reply-To: <20120613080646.GB4829@phenom.ffwll.local>



> -----Original Message-----
> From: intel-gfx-
> bounces+vijay.a.purushothaman=intel.com@lists.freedesktop.org [mailto:intel-
> gfx-bounces+vijay.a.purushothaman=intel.com@lists.freedesktop.org] On
> Behalf Of Daniel Vetter
> Sent: Wednesday, June 13, 2012 1:37 PM
> To: Jesse Barnes
> Cc: intel-gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH 1/7] drm/i915: ValleyView mode setting limits
> and PLL functions
> 
> On Tue, Jun 12, 2012 at 02:47:29PM -0700, Jesse Barnes wrote:
> > Add some VLV limit structures and update the PLL code.
> >
> > v2: resolve conflicts, Vijay to re-post with PLL valid checks and
> > fixed limits
> > v3: re-add dpio write function
> >
> > Signed-off-by: Shobhit Kumar <shobhit.kumar@intel.com>
> > Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com>
> 
> Your sob-line is missing, and iirc a few people puked over that massively-nested
> pll computation loop. I dunno what we've ultimately decided about it, though.
> -Daniel
> 

We decided to rework this patch once we have a platform to test. Just today I was able to bring up my system with a test bios version - Thanks to Jesse.

I will post a cleaned up version of this patch soon.

Thanks,
Vijay

> > ---
> >  drivers/gpu/drm/i915/i915_reg.h      |    1 +
> >  drivers/gpu/drm/i915/intel_display.c |  250
> > +++++++++++++++++++++++++++++++++-
> >  2 files changed, 249 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h
> > b/drivers/gpu/drm/i915/i915_reg.h index 7dcc04f..281446d 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -900,6 +900,7 @@
> >  #define   DPLL_P2_CLOCK_DIV_MASK	0x03000000 /* i915 */
> >  #define   DPLL_FPA01_P1_POST_DIV_MASK	0x00ff0000 /* i915 */
> >  #define   DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW	0x00ff8000 /*
> Pineview */
> > +#define   DPLL_LOCK_VLV			(1<<15)
> >  #define   DPLL_INTEGRATED_CLOCK_VLV	(1<<13)
> >
> >  #define SRX_INDEX		0x3c4
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index 0161d94..5006928 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -98,6 +98,11 @@ intel_find_pll_ironlake_dp(const intel_limit_t *, struct
> drm_crtc *crtc,
> >  			   int target, int refclk, intel_clock_t *match_clock,
> >  			   intel_clock_t *best_clock);
> >
> > +static bool
> > +intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc,
> > +			int target, int refclk, intel_clock_t *match_clock,
> > +			intel_clock_t *best_clock);
> > +
> >  static inline u32 /* units of 100MHz */  intel_fdi_link_freq(struct
> > drm_device *dev)  { @@ -359,6 +364,48 @@ static const intel_limit_t
> > intel_limits_ironlake_display_port = {
> >  	.find_pll = intel_find_pll_ironlake_dp,  };
> >
> > +static const intel_limit_t intel_limits_vlv_dac = {
> > +	.dot = { .min = 25000, .max = 270000 },
> > +	.vco = { .min = 4000000, .max = 6000000 },
> > +	.n = { .min = 1, .max = 7 },
> > +	.m = { .min = 22, .max = 450 }, /* guess */
> > +	.m1 = { .min = 2, .max = 3 },
> > +	.m2 = { .min = 11, .max = 156 },
> > +	.p = { .min = 10, .max = 30 },
> > +	.p1 = { .min = 2, .max = 3 },
> > +	.p2 = { .dot_limit = 270000,
> > +		.p2_slow = 10, .p2_fast = 5 },
> > +	.find_pll = intel_vlv_find_best_pll, };
> > +
> > +static const intel_limit_t intel_limits_vlv_hdmi = {
> > +	.dot = { .min = 20000, .max = 165000 },
> > +	.vco = { .min = 5994000, .max = 4000000 },
> > +	.n = { .min = 1, .max = 7 },
> > +	.m = { .min = 60, .max = 300 }, /* guess */
> > +	.m1 = { .min = 2, .max = 3 },
> > +	.m2 = { .min = 11, .max = 156 },
> > +	.p = { .min = 10, .max = 30 },
> > +	.p1 = { .min = 2, .max = 3 },
> > +	.p2 = { .dot_limit = 270000,
> > +		.p2_slow = 10, .p2_fast = 5 },
> > +	.find_pll = intel_vlv_find_best_pll, };
> > +
> > +static const intel_limit_t intel_limits_vlv_dp = {
> > +	.dot = { .min = 162000, .max = 270000 },
> > +	.vco = { .min = 5994000, .max = 4000000 },
> > +	.n = { .min = 1, .max = 7 },
> > +	.m = { .min = 60, .max = 300 }, /* guess */
> > +	.m1 = { .min = 2, .max = 3 },
> > +	.m2 = { .min = 11, .max = 156 },
> > +	.p = { .min = 10, .max = 30 },
> > +	.p1 = { .min = 2, .max = 3 },
> > +	.p2 = { .dot_limit = 270000,
> > +		.p2_slow = 10, .p2_fast = 5 },
> > +	.find_pll = intel_vlv_find_best_pll, };
> > +
> >  u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg)  {
> >  	unsigned long flags;
> > @@ -384,6 +431,28 @@ out_unlock:
> >  	return val;
> >  }
> >
> > +static void intel_dpio_write(struct drm_i915_private *dev_priv, int reg,
> > +			     u32 val)
> > +{
> > +	unsigned long flags;
> > +
> > +	spin_lock_irqsave(&dev_priv->dpio_lock, flags);
> > +	if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0,
> 100)) {
> > +		DRM_ERROR("DPIO idle wait timed out\n");
> > +		goto out_unlock;
> > +	}
> > +
> > +	I915_WRITE(DPIO_DATA, val);
> > +	I915_WRITE(DPIO_REG, reg);
> > +	I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_WRITE | DPIO_PORTID |
> > +		   DPIO_BYTE);
> > +	if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0,
> 100))
> > +		DRM_ERROR("DPIO write wait timed out\n");
> > +
> > +out_unlock:
> > +       spin_unlock_irqrestore(&dev_priv->dpio_lock, flags); }
> > +
> >  static void vlv_init_dpio(struct drm_device *dev)  {
> >  	struct drm_i915_private *dev_priv = dev->dev_private; @@ -510,6
> > +579,13 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc, int
> refclk)
> >  			limit = &intel_limits_pineview_lvds;
> >  		else
> >  			limit = &intel_limits_pineview_sdvo;
> > +	} else if (IS_VALLEYVIEW(dev)) {
> > +		if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG))
> > +			limit = &intel_limits_vlv_dac;
> > +		else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI))
> > +			limit = &intel_limits_vlv_hdmi;
> > +		else
> > +			limit = &intel_limits_vlv_dp;
> >  	} else if (!IS_GEN2(dev)) {
> >  		if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
> >  			limit = &intel_limits_i9xx_lvds;
> > @@ -783,6 +859,83 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct
> drm_crtc *crtc,
> >  	memcpy(best_clock, &clock, sizeof(intel_clock_t));
> >  	return true;
> >  }
> > +static bool
> > +intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc,
> > +			int target, int refclk, intel_clock_t *match_clock,
> > +			intel_clock_t *best_clock)
> > +{
> > +	u32 p1, p2, m1, m2, vco, bestn, bestm1, bestm2, bestp1, bestp2;
> > +	u32 m, n, fastclk, minvco, maxvco;
> > +	u32 updrate, minupdate, fracbits, p;
> > +	unsigned long bestppm, ppm, absppm;
> > +	int dotclk;
> > +
> > +	dotclk = target * 1000;
> > +
> > +	bestppm = 1000000;
> > +	ppm = 0;
> > +	absppm = 0;
> > +
> > +	fastclk = dotclk / (2*100);
> > +	minvco = limit->vco.min;
> > +	maxvco = limit->vco.max;
> > +	updrate = 0;
> > +	minupdate = 19200;
> > +	fracbits = 1;
> > +
> > +	n = p = p1 = p2 = m = m1 = m2 = vco = bestn = 0;
> > +	bestm1 = bestm2 = bestp1 = bestp2 = 0;
> > +
> > +	for(n = 1; n <= ((refclk) / minupdate); n++) {
> > +		updrate = refclk / n;
> > +		for (p1 = 3; p1 > 1; p1--) {
> > +			for (p2 = 21; p2 > 0; p2--) {
> > +				if (p2 > 10)
> > +					p2 = p2 - 1;
> > +				p = p1 * p2;
> > +
> > +				for( m1=2; m1 <= 3; m1++) {
> > +					m2 = (((2*(fastclk * p * n / m1 )) +
> > +					       refclk) / (2*refclk));
> > +					m = m1 * m2;
> > +					vco = updrate * m;
> > +					if(vco >= minvco && vco < maxvco) {
> > +						ppm = 1000000 *((vco / p) -
> > +								fastclk) /
> > +							fastclk;
> > +						absppm = (ppm > 0)? ppm: (-
> ppm);
> > +						if (absppm < 100 &&
> > +						    ((p1 * p2) >
> > +						     (bestp1 * bestp2))) {
> > +							bestppm = 0;
> > +							bestn = n;
> > +							bestm1 = m1;
> > +							bestm2 = m2;
> > +							bestp1 = p1;
> > +							bestp2 = p2;
> > +						}
> > +						if (absppm < bestppm - 10) {
> > +							bestppm = absppm;
> > +							bestn = n;
> > +							bestm1 = m1;
> > +							bestm2 = m2;
> > +							bestp1 = p1;
> > +							bestp2 = p2;
> > +						}
> > +					}
> > +				}
> > +			} /* Next p2 */
> > +		} /* Next p1 */
> > +	}/* Next n */
> > +
> > +	best_clock->n = bestn;
> > +	best_clock->m1 = bestm1;
> > +	best_clock->m2 = bestm2;
> > +	best_clock->p1 = bestp1;
> > +	best_clock->p2 = bestp2;
> > +
> > +	return true;
> > +}
> >
> >  static void ironlake_wait_for_vblank(struct drm_device *dev, int
> > pipe)  { @@ -1287,7 +1440,7 @@ static void intel_enable_pll(struct
> > drm_i915_private *dev_priv, enum pipe pipe)
> >  	u32 val;
> >
> >  	/* No really, not for ILK+ */
> > -	BUG_ON(dev_priv->info->gen >= 5);
> > +	BUG_ON(!IS_VALLEYVIEW(dev_priv->dev) && dev_priv->info->gen >=
> 5);
> >
> >  	/* PLL is protected by panel, make sure we can write it */
> >  	if (IS_MOBILE(dev_priv->dev) && !IS_I830(dev_priv->dev)) @@ -3666,13
> > +3819,37 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
> >  	return display_bpc != bpc;
> >  }
> >
> > +static int vlv_get_refclk(struct drm_crtc *crtc) {
> > +	struct drm_device *dev = crtc->dev;
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	int refclk = 27000; /* for DP & HDMI */
> > +
> > +	return 100000; /* only one validated so far */
> > +
> > +	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) {
> > +		refclk = 96000;
> > +	} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
> > +		if (intel_panel_use_ssc(dev_priv))
> > +			refclk = 100000;
> > +		else
> > +			refclk = 96000;
> > +	} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) {
> > +		refclk = 100000;
> > +	}
> > +
> > +	return refclk;
> > +}
> > +
> >  static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors)
> > {
> >  	struct drm_device *dev = crtc->dev;
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	int refclk;
> >
> > -	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
> > +	if (IS_VALLEYVIEW(dev)) {
> > +		refclk = vlv_get_refclk(crtc);
> > +	} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
> >  	    intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
> >  		refclk = dev_priv->lvds_ssc_freq * 1000;
> >  		DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
> @@ -3787,6
> > +3964,72 @@ static void intel_update_lvds(struct drm_crtc *crtc, intel_clock_t
> *clock,
> >  	I915_WRITE(LVDS, temp);
> >  }
> >
> > +static void vlv_update_pll(struct drm_crtc *crtc,
> > +			   struct drm_display_mode *mode,
> > +			   struct drm_display_mode *adjusted_mode,
> > +			   intel_clock_t *clock, intel_clock_t *reduced_clock,
> > +			   int refclk, int num_connectors) {
> > +	struct drm_device *dev = crtc->dev;
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +	int pipe = intel_crtc->pipe;
> > +	u32 dpll, mdiv, pdiv;
> > +	u32 bestn, bestm1, bestm2, bestp1, bestp2;
> > +	bool is_hdmi;
> > +
> > +	is_hdmi = intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI);
> > +
> > +	bestn = clock->n;
> > +	bestm1 = clock->m1;
> > +	bestm2 = clock->m2;
> > +	bestp1 = clock->p1;
> > +	bestp2 = clock->p2;
> > +
> > +	/* Enable DPIO clock input */
> > +	dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REFA_CLK_ENABLE_VLV
> |
> > +		DPLL_VGA_MODE_DIS | DPLL_INTEGRATED_CLOCK_VLV;
> > +	I915_WRITE(DPLL(pipe), dpll);
> > +	POSTING_READ(DPLL(pipe));
> > +
> > +	mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 &
> DPIO_M2DIV_MASK));
> > +	mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT));
> > +	mdiv |= ((bestn << DPIO_N_SHIFT));
> > +	mdiv |= (1 << DPIO_POST_DIV_SHIFT);
> > +	mdiv |= (1 << DPIO_K_SHIFT);
> > +	mdiv |= DPIO_ENABLE_CALIBRATION;
> > +	intel_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv);
> > +
> > +	intel_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), 0x01000000);
> > +
> > +	pdiv = DPIO_REFSEL_OVERRIDE | (5 << DPIO_PLL_MODESEL_SHIFT) |
> > +		(3 << DPIO_BIAS_CURRENT_CTL_SHIFT) | (1<<20) |
> > +		(8 << DPIO_DRIVER_CTL_SHIFT) | (5 <<
> DPIO_CLK_BIAS_CTL_SHIFT);
> > +	intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), pdiv);
> > +
> > +	intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), 0x009f0051);
> > +
> > +	dpll |= DPLL_VCO_ENABLE;
> > +	I915_WRITE(DPLL(pipe), dpll);
> > +	POSTING_READ(DPLL(pipe));
> > +	if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) ==
> DPLL_LOCK_VLV), 1))
> > +		DRM_ERROR("DPLL %d failed to lock\n", pipe);
> > +
> > +	if (is_hdmi) {
> > +		u32 temp = intel_mode_get_pixel_multiplier(adjusted_mode);
> > +
> > +		if (temp > 1)
> > +			temp = (temp - 1) <<
> DPLL_MD_UDI_MULTIPLIER_SHIFT;
> > +		else
> > +			temp = 0;
> > +
> > +		I915_WRITE(DPLL_MD(pipe), temp);
> > +		POSTING_READ(DPLL_MD(pipe));
> > +	}
> > +
> > +	intel_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x641); /* ??? */ }
> > +
> >  static void i9xx_update_pll(struct drm_crtc *crtc,
> >  			    struct drm_display_mode *mode,
> >  			    struct drm_display_mode *adjusted_mode, @@ -
> 4044,6 +4287,9 @@
> > static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
> >
> >  	if (IS_GEN2(dev))
> >  		i8xx_update_pll(crtc, adjusted_mode, &clock, num_connectors);
> > +	else if (IS_VALLEYVIEW(dev))
> > +		vlv_update_pll(crtc, mode,adjusted_mode, &clock, NULL,
> > +			       refclk, num_connectors);
> >  	else
> >  		i9xx_update_pll(crtc, mode, adjusted_mode, &clock,
> >  				has_reduced_clock ? &reduced_clock : NULL,
> > --
> > 1.7.9.5
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> --
> Daniel Vetter
> Mail: daniel@ffwll.ch
> Mobile: +41 (0)79 365 57 48
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2012-06-13 15:04 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-12 21:47 Remaining VLV patches Jesse Barnes
2012-06-12 21:47 ` [PATCH 1/7] drm/i915: ValleyView mode setting limits and PLL functions Jesse Barnes
2012-06-13  8:06   ` Daniel Vetter
2012-06-13 15:04     ` Purushothaman, Vijay A [this message]
2012-06-12 21:47 ` [PATCH 2/7] drm/i915: Enable DP panel power sequencing for ValleyView Jesse Barnes
2012-06-13  8:05   ` Daniel Vetter
2012-06-13 16:10     ` Shobhit Kumar
2012-06-12 21:47 ` [PATCH 3/7] drm/i915: add ValleyView specific CRT detect function Jesse Barnes
2012-06-12 21:47 ` [PATCH 4/7] drm/i915: add HDMI and DP port enumeration on ValleyView Jesse Barnes
2012-06-13  8:11   ` Daniel Vetter
2012-06-13 17:19     ` Jesse Barnes
2012-06-12 21:47 ` [PATCH 5/7] drm/i915: access VLV regs through read/write switch Jesse Barnes
2012-06-13  8:14   ` Daniel Vetter
2012-06-12 21:47 ` [PATCH 6/7] drm/i915: bind driver to ValleyView chipsets Jesse Barnes
2012-06-12 21:47 ` [PATCH 7/7] drm/i915: VLV VGA port only handles on & off, like PCH VGA Jesse Barnes
2012-06-13  8:36   ` Daniel Vetter

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=D13E68CE400A0B46A298335DB646F1BF16447C@BGSMSX101.gar.corp.intel.com \
    --to=vijay.a.purushothaman@intel.com \
    --cc=daniel@ffwll.ch \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=jbarnes@virtuousgeek.org \
    /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.