On Thu, Sep 04, 2014 at 07:49:43PM +0100, Damien Lespiau wrote: > From: Pradeep Bhat <pradeep.bhat@xxxxxxxxx> > > This patch reads the memory latency values for all the 8 levels for > SKL. These values are needed for the Watermark computation. > > v2: Incorporated the review comments from Damien on register > indentation. > > v3: Updated the code to use the sandybridge_pcode_read for reading > memory latencies for GEN9. > > v4: Don't put gen 9 in the middle of an ordered list of ifs > (Damien) > > v5: take the rps.hw_lock around sandybridge_pcode_read() (Damien) > > v6: Use gen >= 9 in the pcode_read() function for data1. > Move the defines near the gen6 ones and prefix them with PCODE. > Remove unused timeout define (the pcode_read() code has a larger > timeout already). > > Signed-off-by: Pradeep Bhat <pradeep.bhat@xxxxxxxxx> > Signed-off-by: Damien Lespiau <damien.lespiau@xxxxxxxxx> With the pcode gen6 stuff handled by the followup patch this is: Reviewed-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > --- > drivers/gpu/drm/i915/i915_drv.h | 6 ++++ > drivers/gpu/drm/i915/i915_reg.h | 7 ++++ > drivers/gpu/drm/i915/intel_pm.c | 76 +++++++++++++++++++++++++++++++++++++---- > 3 files changed, 83 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index dcd1c72..32be299 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -1665,6 +1665,12 @@ struct drm_i915_private { > uint16_t spr_latency[5]; > /* cursor */ > uint16_t cur_latency[5]; > + /* > + * Raw watermark memory latency values > + * for SKL for all 8 levels > + * in 1us units. > + */ > + uint16_t skl_latency[8]; > > /* current hardware state */ > struct ilk_wm_values hw; > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 0159f2d..6785d51 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -5855,6 +5855,13 @@ enum punit_power_well { > #define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8 > #define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16 > > +#define GEN9_PCODE_DATA1 0x13812C > +#define GEN9_PCODE_READ_MEM_LATENCY 0x6 > +#define GEN9_MEM_LATENCY_LEVEL_MASK 0xFF > +#define GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT 8 > +#define GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT 16 > +#define GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT 24 > + > #define GEN6_GT_CORE_STATUS 0x138060 > #define GEN6_CORE_CPD_STATE_MASK (7<<4) > #define GEN6_RCn_MASK 7 > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c > index a236e77..2774db1 100644 > --- a/drivers/gpu/drm/i915/intel_pm.c > +++ b/drivers/gpu/drm/i915/intel_pm.c > @@ -2239,11 +2239,56 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc) > PIPE_WM_LINETIME_TIME(linetime); > } > > -static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[5]) > +static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8]) > { > struct drm_i915_private *dev_priv = dev->dev_private; > > - if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { > + if (IS_GEN9(dev)) { > + uint32_t val; > + int ret; > + > + /* read the first set of memory latencies[0:3] */ > + val = 0; /* data0 to be programmed to 0 for first set */ > + mutex_lock(&dev_priv->rps.hw_lock); > + ret = sandybridge_pcode_read(dev_priv, > + GEN9_PCODE_READ_MEM_LATENCY, > + &val); > + mutex_unlock(&dev_priv->rps.hw_lock); > + > + if (ret) { > + DRM_ERROR("SKL Mailbox read error = %d\n", ret); > + return; > + } > + > + wm[0] = val & GEN9_MEM_LATENCY_LEVEL_MASK; > + wm[1] = (val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) & > + GEN9_MEM_LATENCY_LEVEL_MASK; > + wm[2] = (val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) & > + GEN9_MEM_LATENCY_LEVEL_MASK; > + wm[3] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) & > + GEN9_MEM_LATENCY_LEVEL_MASK; > + > + /* read the second set of memory latencies[4:7] */ > + val = 1; /* data0 to be programmed to 1 for second set */ > + mutex_lock(&dev_priv->rps.hw_lock); > + ret = sandybridge_pcode_read(dev_priv, > + GEN9_PCODE_READ_MEM_LATENCY, > + &val); > + mutex_unlock(&dev_priv->rps.hw_lock); > + if (ret) { > + DRM_ERROR("SKL Mailbox read error = %d\n", ret); > + return; > + } > + > + wm[4] = val & GEN9_MEM_LATENCY_LEVEL_MASK; > + wm[5] = (val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) & > + GEN9_MEM_LATENCY_LEVEL_MASK; > + wm[6] = (val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) & > + GEN9_MEM_LATENCY_LEVEL_MASK; > + wm[7] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) & > + GEN9_MEM_LATENCY_LEVEL_MASK; > + > + } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { > uint64_t sskpd = I915_READ64(MCH_SSKPD); > > wm[0] = (sskpd >> 56) & 0xFF; > @@ -2291,7 +2336,9 @@ static void intel_fixup_cur_wm_latency(struct drm_device *dev, uint16_t wm[5]) > int ilk_wm_max_level(const struct drm_device *dev) > { > /* how many WM levels are we expecting */ > - if (IS_HASWELL(dev) || IS_BROADWELL(dev)) > + if (IS_GEN9(dev)) > + return 7; > + else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) > return 4; > else if (INTEL_INFO(dev)->gen >= 6) > return 3; > @@ -2300,7 +2347,7 @@ int ilk_wm_max_level(const struct drm_device *dev) > } > static void intel_print_wm_latency(struct drm_device *dev, > const char *name, > - const uint16_t wm[5]) > + const uint16_t wm[8]) > { > int level, max_level = ilk_wm_max_level(dev); > > @@ -2313,8 +2360,13 @@ static void intel_print_wm_latency(struct drm_device *dev, > continue; > } > > - /* WM1+ latency values in 0.5us units */ > - if (level > 0) > + /* > + * - latencies are in us on gen9. > + * - before then, WM1+ latency values are in 0.5us units > + */ > + if (IS_GEN9(dev)) > + latency *= 10; > + else if (level > 0) > latency *= 5; > > DRM_DEBUG_KMS("%s WM%d latency %u (%u.%u usec)\n", > @@ -2382,6 +2434,14 @@ static void ilk_setup_wm_latency(struct drm_device *dev) > snb_wm_latency_quirk(dev); > } > > +static void skl_setup_wm_latency(struct drm_device *dev) > +{ > + struct drm_i915_private *dev_priv = dev->dev_private; > + > + intel_read_wm_latency(dev, dev_priv->wm.skl_latency); > + intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency); > +} > + > static void ilk_compute_wm_parameters(struct drm_crtc *crtc, > struct ilk_pipe_wm_parameters *p) > { > @@ -7396,6 +7456,8 @@ void intel_init_pm(struct drm_device *dev) > > /* For FIFO watermark updates */ > if (IS_GEN9(dev)) { > + skl_setup_wm_latency(dev); > + > dev_priv->display.init_clock_gating = gen9_init_clock_gating; > } else if (HAS_PCH_SPLIT(dev)) { > ilk_setup_wm_latency(dev); > @@ -7488,6 +7550,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val) > } > > I915_WRITE(GEN6_PCODE_DATA, *val); > + if (INTEL_INFO(dev_priv)->gen >= 9) > + I915_WRITE(GEN9_PCODE_DATA1, 0); > I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox); > > if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, > -- > 1.8.3.1 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx