[Intel-gfx] [PATCH 04/10] drm/i915: CHV DDR DVFS support and another watermark rewrite
Clint Taylor
clinton.a.taylor at intel.com
Fri Jun 26 13:21:44 PDT 2015
On 06/26/2015 12:48 PM, Ville Syrjälä wrote:
> On Fri, Jun 26, 2015 at 10:56:33AM -0700, Clint Taylor wrote:
>> On 06/24/2015 12:00 PM, ville.syrjala at linux.intel.com wrote:
>>> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
>>>
>>> Turns out the VLV/CHV system agent doesn't understand memory
>>> latencies, so trying to rely on the PND deadline mechanism is not
>>> going to fly especially when DDR DVFS is enabled. Currently we try to
>>> avoid the problems by lying to the system agent about the deadlines
>>> and setting the FIFO watermarks to 8 cachelines. This however leads to
>>> bad memory self refresh residency.
>>>
>>> So in order to satosfy everyone we'll just give up on the deadline
>>> scheme and program the watermarks old school based on the worst case
>>> memory latency.
>>>
>>> I've modelled this a bit on the ILK+ approach where we compute multiple
>>> sets of watermarks for each pipe (PM2,PM5,DDR DVFS) and when merge thet
>>> appropriate one later with the watermarks from other pipes. There isn't
>>> too much to merge actually since each pipe has a totally independent
>>> FIFO (well apart from the mess with the partially shared DSPARB
>>> registers), but still decopuling the pipes from each other seems like a
>>> good idea.
>>>
>>> Eventually we'll want to perform the watermark update in two phases
>>> around the plane update to avoid underruns due to the single buffered
>>> watermark registers. But that's still in limbo for ILK+ too, so I've not
>>> gone that far yet for VLV/CHV either.
>>>
>>> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
>>> ---
>>> drivers/gpu/drm/i915/i915_drv.h | 28 +--
>>> drivers/gpu/drm/i915/intel_display.c | 6 +-
>>> drivers/gpu/drm/i915/intel_drv.h | 11 ++
>>> drivers/gpu/drm/i915/intel_pm.c | 318 ++++++++++++++++++++++++++++++++++-
>>> 4 files changed, 345 insertions(+), 18 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>>> index 514adcf..37cc653 100644
>>> --- a/drivers/gpu/drm/i915/i915_drv.h
>>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>>> @@ -276,6 +276,12 @@ struct i915_hotplug {
>>> &dev->mode_config.plane_list, \
>>> base.head)
>>>
>>> +#define for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) \
>>> + list_for_each_entry(intel_plane, \
>>> + &(dev)->mode_config.plane_list, \
>>> + base.head) \
>>> + if ((intel_plane)->pipe == (intel_crtc)->pipe)
>>> +
>>> #define for_each_intel_crtc(dev, intel_crtc) \
>>> list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, base.head)
>>>
>>> @@ -1498,18 +1504,20 @@ struct ilk_wm_values {
>>> enum intel_ddb_partitioning partitioning;
>>> };
>>>
>>> -struct vlv_wm_values {
>>> - struct {
>>> - uint16_t primary;
>>> - uint16_t sprite[2];
>>> - uint8_t cursor;
>>> - } pipe[3];
>>> +struct vlv_pipe_wm {
>>> + uint16_t primary;
>>> + uint16_t sprite[2];
>>> + uint8_t cursor;
>>> +};
>>>
>>> - struct {
>>> - uint16_t plane;
>>> - uint8_t cursor;
>>> - } sr;
>>> +struct vlv_sr_wm {
>>> + uint16_t plane;
>>> + uint8_t cursor;
>>> +};
>>>
>>> +struct vlv_wm_values {
>>> + struct vlv_pipe_wm pipe[3];
>>> + struct vlv_sr_wm sr;
>>> struct {
>>> uint8_t cursor;
>>> uint8_t sprite[2];
>>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>>> index b15d57f..1424320 100644
>>> --- a/drivers/gpu/drm/i915/intel_display.c
>>> +++ b/drivers/gpu/drm/i915/intel_display.c
>>> @@ -4690,8 +4690,11 @@ intel_pre_disable_primary(struct drm_crtc *crtc)
>>> * event which is after the vblank start event, so we need to have a
>>> * wait-for-vblank between disabling the plane and the pipe.
>>> */
>>> - if (HAS_GMCH_DISPLAY(dev))
>>> + if (HAS_GMCH_DISPLAY(dev)) {
>>> intel_set_memory_cxsr(dev_priv, false);
>>> + dev_priv->wm.vlv.cxsr = false;
>>> + intel_wait_for_vblank(dev, pipe);
>>> + }
>>>
>>> /*
>>> * FIXME IPS should be fine as long as one plane is
>>> @@ -6005,7 +6008,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
>>>
>>> intel_crtc_load_lut(crtc);
>>>
>>> - intel_update_watermarks(crtc);
>>> intel_enable_pipe(intel_crtc);
>>>
>>> assert_vblank_disabled(crtc);
>>> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
>>> index 3673a71..f26a680 100644
>>> --- a/drivers/gpu/drm/i915/intel_drv.h
>>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>>> @@ -462,6 +462,15 @@ struct intel_crtc_state {
>>> enum pipe hsw_workaround_pipe;
>>> };
>>>
>>> +struct vlv_wm_state {
>>> + struct vlv_pipe_wm wm[3];
>>> + struct vlv_sr_wm sr[3];
>>> + uint8_t num_active_planes;
>>> + uint8_t num_levels;
>>> + uint8_t level;
>>> + bool cxsr;
>>> +};
>>> +
>>> struct intel_pipe_wm {
>>> struct intel_wm_level wm[5];
>>> uint32_t linetime;
>>> @@ -564,6 +573,8 @@ struct intel_crtc {
>>>
>>> /* scalers available on this crtc */
>>> int num_scalers;
>>> +
>>> + struct vlv_wm_state wm_state;
>>> };
>>>
>>> struct intel_plane_wm_parameters {
>>> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
>>> index e67548d..d046e5f 100644
>>> --- a/drivers/gpu/drm/i915/intel_pm.c
>>> +++ b/drivers/gpu/drm/i915/intel_pm.c
>>> @@ -335,8 +335,6 @@ void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable)
>>> if (IS_VALLEYVIEW(dev)) {
>>> I915_WRITE(FW_BLC_SELF_VLV, enable ? FW_CSPWRDWNEN : 0);
>>> POSTING_READ(FW_BLC_SELF_VLV);
>>> - if (IS_CHERRYVIEW(dev))
>>> - chv_set_memory_pm5(dev_priv, enable);
>>> } else if (IS_G4X(dev) || IS_CRESTLINE(dev)) {
>>> I915_WRITE(FW_BLC_SELF, enable ? FW_BLC_SELF_EN : 0);
>>> POSTING_READ(FW_BLC_SELF);
>>> @@ -929,8 +927,6 @@ static void vlv_write_wm_values(struct intel_crtc *crtc,
>>> }
>>>
>>> POSTING_READ(DSPFW1);
>>> -
>>> - dev_priv->wm.vlv = *wm;
>>> }
>>>
>>> #undef FW_WM_VLV
>>> @@ -1014,6 +1010,72 @@ enum vlv_wm_level {
>>> VLV_WM_NUM_LEVELS = 1,
>>> };
>>>
>>> +/* latency must be in 0.1us units. */
>>> +static unsigned int vlv_wm_method2(unsigned int pixel_rate,
>>> + unsigned int pipe_htotal,
>>> + unsigned int horiz_pixels,
>>> + unsigned int bytes_per_pixel,
>>> + unsigned int latency)
>>> +{
>>> + unsigned int ret;
>>> +
>>> + ret = (latency * pixel_rate) / (pipe_htotal * 10000);
>>> + ret = (ret + 1) * horiz_pixels * bytes_per_pixel;
>>> + ret = DIV_ROUND_UP(ret, 64);
>>> +
>>> + return ret;
>>> +}
>>> +
>>> +static void vlv_setup_wm_latency(struct drm_device *dev)
>>> +{
>>> + struct drm_i915_private *dev_priv = dev->dev_private;
>>> +
>>> + /* all latencies in usec */
>>> + dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM2] = 3;
>>> +
>>> + if (IS_CHERRYVIEW(dev_priv)) {
>>> + dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM5] = 12;
>>> + dev_priv->wm.pri_latency[VLV_WM_LEVEL_DDR_DVFS] = 33;
>>
>> nit #defines for these magic values please
>
> What's the point of doing that? These values are not repeated anywhere
> else.
>
>>
>>> + }
>>> +}
>>> +
>>> +static uint16_t vlv_compute_wm_level(struct intel_plane *plane,
>>> + struct intel_crtc *crtc,
>>> + const struct intel_plane_state *state,
>>> + int level)
>>> +{
>>> + struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>>> + int clock, htotal, pixel_size, width, wm;
>>> +
>>> + if (dev_priv->wm.pri_latency[level] == 0)
>>> + return USHRT_MAX;
>>> +
>>> + if (!state->visible)
>>> + return 0;
>>> +
>>> + pixel_size = drm_format_plane_cpp(state->base.fb->pixel_format, 0);
>>> + clock = crtc->config->base.adjusted_mode.crtc_clock;
>>> + htotal = crtc->config->base.adjusted_mode.crtc_htotal;
>>> + width = crtc->config->pipe_src_w;
>>> + if (WARN_ON(htotal == 0))
>>> + htotal = 1;
>>> +
>>> + if (plane->base.type == DRM_PLANE_TYPE_CURSOR) {
>>> + /*
>>> + * FIXME the formula gives values that are
>>> + * too big for the cursor FIFO, and hence we
>>> + * would never be able to use cursors. For
>>> + * now just hardcode the watermark.
>>> + */
>>> + wm = 63;
>>
>> Hard coding to maximum value of 63. Should probably be programmed to
>> worst case instead of maximum.
>
> I have no idea what's the worst case. I was too lazy to try to
> empirically deduce some kind of number/formula that works all the time.
> Since it's a very small plane usually hardcoding it like this shouldn't
> hurt too much (I hope). We can't go above 63, so if that fails we're
> screwed anyway.
>
63 gets inverted to 0 and we are screwed if that doesn't work.
>>> + } else {
>>> + wm = vlv_wm_method2(clock, htotal, width, pixel_size,
>>> + dev_priv->wm.pri_latency[level] * 10);
>>> + }
>>> +
>>> + return min_t(int, wm, USHRT_MAX);
>>> +}
>>> +
>>> static bool vlv_compute_sr_wm(struct drm_device *dev,
>>> struct vlv_wm_values *wm)
>>> {
>>> @@ -1105,6 +1167,249 @@ static void valleyview_update_wm(struct drm_crtc *crtc)
>>>
>>> if (cxsr_enabled)
>>> intel_set_memory_cxsr(dev_priv, true);
>>> +
>>> + dev_priv->wm.vlv = wm;
>>> +}
>>> +
>>> +static void vlv_invert_wms(struct intel_crtc *crtc)
>>> +{
>>> + struct vlv_wm_state *wm_state = &crtc->wm_state;
>>> + int level;
>>> +
>>> + for (level = 0; level < wm_state->num_levels; level++) {
>>> + struct drm_device *dev = crtc->base.dev;
>>> + const int sr_fifo_size = INTEL_INFO(dev)->num_pipes * 512 - 1;
>>> + struct intel_plane *plane;
>>> +
>>> + wm_state->sr[level].plane = sr_fifo_size - wm_state->sr[level].plane;
>>> + wm_state->sr[level].cursor = 63 - wm_state->sr[level].cursor;
>>> +
>>> + for_each_intel_plane_on_crtc(dev, crtc, plane) {
>>> + switch (plane->base.type) {
>>> + int sprite;
>>> + case DRM_PLANE_TYPE_CURSOR:
>>> + wm_state->wm[level].cursor = plane->wm.fifo_size -
>>> + wm_state->wm[level].cursor;
>>> + break;
>>> + case DRM_PLANE_TYPE_PRIMARY:
>>> + wm_state->wm[level].primary = plane->wm.fifo_size -
>>> + wm_state->wm[level].primary;
>>> + break;
>>> + case DRM_PLANE_TYPE_OVERLAY:
>>> + sprite = plane->plane;
>>> + wm_state->wm[level].sprite[sprite] = plane->wm.fifo_size -
>>> + wm_state->wm[level].sprite[sprite];
>>> + break;
>>> + }
>>> + }
>>> + }
>>> +}
>>> +
>>> +static void _vlv_compute_wm(struct intel_crtc *crtc)
>>> +{
>>> + struct drm_device *dev = crtc->base.dev;
>>> + struct vlv_wm_state *wm_state = &crtc->wm_state;
>>> + struct intel_plane *plane;
>>> + int sr_fifo_size = INTEL_INFO(dev)->num_pipes * 512 - 1;
>>> + int level;
>>> +
>>> + memset(wm_state, 0, sizeof(*wm_state));
>>> +
>>> + wm_state->cxsr = crtc->pipe != PIPE_C;
>>> + if (IS_CHERRYVIEW(dev))
>>> + wm_state->num_levels = CHV_WM_NUM_LEVELS;
>>> + else
>>> + wm_state->num_levels = VLV_WM_NUM_LEVELS;
>>> +
>>> + wm_state->num_active_planes = 0;
>>> + for_each_intel_plane_on_crtc(dev, crtc, plane) {
>>> + struct intel_plane_state *state =
>>> + to_intel_plane_state(plane->base.state);
>>> +
>>> + if (plane->base.type == DRM_PLANE_TYPE_CURSOR)
>>> + continue;
>>> +
>>> + if (state->visible)
>>> + wm_state->num_active_planes++;
>>> + }
>>> +
>>> + if (wm_state->num_active_planes != 1)
>>> + wm_state->cxsr = false;
>>> +
>>> + if (wm_state->cxsr) {
>>> + for (level = 0; level < wm_state->num_levels; level++) {
>>> + wm_state->sr[level].plane = sr_fifo_size;
>>> + wm_state->sr[level].cursor = 63;
>>> + }
>>> + }
>>> +
>>> + for_each_intel_plane_on_crtc(dev, crtc, plane) {
>>> + struct intel_plane_state *state =
>>> + to_intel_plane_state(plane->base.state);
>>> +
>>> + if (!state->visible)
>>> + continue;
>>> +
>>> + /* normal watermarks */
>>> + for (level = 0; level < wm_state->num_levels; level++) {
>>> + int wm = vlv_compute_wm_level(plane, crtc, state, level);
>>> + int max_wm = plane->base.type == DRM_PLANE_TYPE_CURSOR ? 63 : 511;
>>> +
>>> + /* hack */
>>> + if (WARN_ON(level == 0 && wm > max_wm))
>>> + wm = max_wm;
>>> +
>>> + if (wm > plane->wm.fifo_size)
>>> + break;
>>> +
>>> + switch (plane->base.type) {
>>> + int sprite;
>>> + case DRM_PLANE_TYPE_CURSOR:
>>> + wm_state->wm[level].cursor = wm;
>>> + break;
>>> + case DRM_PLANE_TYPE_PRIMARY:
>>> + wm_state->wm[level].primary = wm;
>>> + break;
>>> + case DRM_PLANE_TYPE_OVERLAY:
>>> + sprite = plane->plane;
>>> + wm_state->wm[level].sprite[sprite] = wm;
>>> + break;
>>> + }
>>> + }
>>> +
>>> + wm_state->num_levels = level;
>>> +
>>> + if (!wm_state->cxsr)
>>> + continue;
>>> +
>>> + /* maxfifo watermarks */
>>> + switch (plane->base.type) {
>>> + int sprite, level;
>>> + case DRM_PLANE_TYPE_CURSOR:
>>> + for (level = 0; level < wm_state->num_levels; level++)
>>> + wm_state->sr[level].cursor =
>>> + wm_state->sr[level].cursor;
>>> + break;
>>> + case DRM_PLANE_TYPE_PRIMARY:
>>> + for (level = 0; level < wm_state->num_levels; level++)
>>> + wm_state->sr[level].plane =
>>> + min(wm_state->sr[level].plane,
>>> + wm_state->wm[level].primary);
>>> + break;
>>> + case DRM_PLANE_TYPE_OVERLAY:
>>> + sprite = plane->plane;
>>> + for (level = 0; level < wm_state->num_levels; level++)
>>> + wm_state->sr[level].plane =
>>> + min(wm_state->sr[level].plane,
>>> + wm_state->wm[level].sprite[sprite]);
>>> + break;
>>> + }
>>> + }
>>> +
>>> + /* clear any (partially) filled invalid levels */
>>> + for (level = wm_state->num_levels; level < CHV_WM_NUM_LEVELS; level++) {
>>> + memset(&wm_state->wm[level], 0, sizeof(wm_state->wm[level]));
>>> + memset(&wm_state->sr[level], 0, sizeof(wm_state->sr[level]));
>>> + }
>>> +
>>> + vlv_invert_wms(crtc);
>>> +}
>>> +
>>> +static void vlv_merge_wm(struct drm_device *dev,
>>> + struct vlv_wm_values *wm)
>>> +{
>>> + struct intel_crtc *crtc;
>>> + int num_active_crtcs = 0;
>>> +
>>> + if (IS_CHERRYVIEW(dev))
>>> + wm->level = VLV_WM_LEVEL_DDR_DVFS;
>>> + else
>>> + wm->level = VLV_WM_LEVEL_PM2;
>>> + wm->cxsr = true;
>>> +
>>> + for_each_intel_crtc(dev, crtc) {
>>> + const struct vlv_wm_state *wm_state = &crtc->wm_state;
>>> +
>>> + if (!crtc->active)
>>> + continue;
>>> +
>>> + if (!wm_state->cxsr)
>>> + wm->cxsr = false;
>>> +
>>> + num_active_crtcs++;
>>> + wm->level = min_t(int, wm->level, wm_state->num_levels - 1);
>>> + }
>>> +
>>> + if (num_active_crtcs != 1)
>>> + wm->cxsr = false;
>>> +
>>> + for_each_intel_crtc(dev, crtc) {
>>> + struct vlv_wm_state *wm_state = &crtc->wm_state;
>>> + enum pipe pipe = crtc->pipe;
>>> +
>>> + if (!crtc->active)
>>> + continue;
>>> +
>>> + wm->pipe[pipe] = wm_state->wm[wm->level];
>>> + if (wm->cxsr)
>>> + wm->sr = wm_state->sr[wm->level];
>>> +
>>> + wm->ddl[pipe].primary = DDL_PRECISION_HIGH | 2;
>>> + wm->ddl[pipe].sprite[0] = DDL_PRECISION_HIGH | 2;
>>> + wm->ddl[pipe].sprite[1] = DDL_PRECISION_HIGH | 2;
>>> + wm->ddl[pipe].cursor = DDL_PRECISION_HIGH | 2;
>>
>> Did we really decide that 0x2 was the final correct value for the DL
>> registers? I figured we would be running 0x7 for CHV.
>
> I'm wary of increasing it too much. That'll give the system agent a
> better chance of making a mess of things.
>
It does appear to work at a level of 2 and gives us room for improvement
if there is a performance problem in the furture
>>
>>> + }
>>> +}
>>> +
>>> +static void vlv_update_wm(struct drm_crtc *crtc)
>>> +{
>>> + struct drm_device *dev = crtc->dev;
>>> + struct drm_i915_private *dev_priv = dev->dev_private;
>>> + struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>>> + enum pipe pipe = intel_crtc->pipe;
>>> + struct vlv_wm_values wm = {};
>>> +
>>> + _vlv_compute_wm(intel_crtc);
>>> + vlv_merge_wm(dev, &wm);
>>> +
>>> + if (memcmp(&dev_priv->wm.vlv, &wm, sizeof(wm)) == 0)
>>> + return;
>>> +
>>> + if (wm.level < VLV_WM_LEVEL_DDR_DVFS &&
>>> + dev_priv->wm.vlv.level >= VLV_WM_LEVEL_DDR_DVFS)
>>> + chv_set_memory_dvfs(dev_priv, false);
>>> +
>>> + if (wm.level < VLV_WM_LEVEL_PM5 &&
>>> + dev_priv->wm.vlv.level >= VLV_WM_LEVEL_PM5)
>>> + chv_set_memory_pm5(dev_priv, false);
>>> +
>>> + if (!wm.cxsr && dev_priv->wm.vlv.cxsr) {
>>> + intel_set_memory_cxsr(dev_priv, false);
>>> + intel_wait_for_vblank(dev, pipe);
>>> + }
>>> +
>>> + vlv_write_wm_values(intel_crtc, &wm);
>>> +
>>> + DRM_DEBUG_KMS("Setting FIFO watermarks - %c: plane=%d, cursor=%d, "
>>> + "sprite0=%d, sprite1=%d, SR: plane=%d, cursor=%d level=%d cxsr=%d\n",
>>> + pipe_name(pipe), wm.pipe[pipe].primary, wm.pipe[pipe].cursor,
>>> + wm.pipe[pipe].sprite[0], wm.pipe[pipe].sprite[1],
>>> + wm.sr.plane, wm.sr.cursor, wm.level, wm.cxsr);
>>> +
>>
>> Love the detailed DRM_DEBUG_KMS - of course its showing the only real
>> issue I have found in the series that the cursor watermark is being
>> programmed inverted. 63 when the cursor is disabled and 0 when its
>> enabled. This leads to an SRR% increase of ~10% when the cursor is
>> enabled.
>>
>> // Cursor disabled
>> [ 2662.355218] [drm:vlv_update_wm] Setting FIFO watermarks - A:
>> plane=340, cursor=63, sprite0=0, sprite1=0, SR: plane=1364, cursor=0
>> level=2 cxsr=1
>>
>> // Cursor Enabled
>> [ 2667.531049] [drm:vlv_update_wm] Setting FIFO watermarks - A:
>> plane=340, cursor=0, sprite0=0, sprite1=0, SR: plane=1364, cursor=0
>> level=2 cxsr=1
>>
>> I haven't found the line of code that actually inverts this programming.
>> I will continue to investigate during testing of this series.
>
> vlv_invert_wms()
>
> That's done on purpose since calculating the watermarks the "right way
> up" first makes makes it easier to think about them (ie. to compare with
> the FIFO size, and to merge the plane SR watermark). It also make things
> looks more ILK-like since ILK+ take the watermarks in the non-inverted
> form.
>
I wasn't aware the registers were inverted compared to ILK+. This is the
only real issue I had with the series and after testing here by writing
63 into the register I agree that this isn't really a problem.
Reviewed-by: Clint Taylor <Clinton.A.Taylor at intel.com>
Tested-by: Clint Taylor <Clinton.A.Taylor at intel.com>
>>
>>
>>> + if (wm.cxsr && !dev_priv->wm.vlv.cxsr) {
>>> + intel_wait_for_vblank(dev, pipe);
>>> + intel_set_memory_cxsr(dev_priv, true);
>>> + }
>>> +
>>> + if (wm.level >= VLV_WM_LEVEL_PM5 &&
>>> + dev_priv->wm.vlv.level < VLV_WM_LEVEL_PM5)
>>> + chv_set_memory_pm5(dev_priv, true);
>>> +
>>> + if (wm.level >= VLV_WM_LEVEL_DDR_DVFS &&
>>> + dev_priv->wm.vlv.level < VLV_WM_LEVEL_DDR_DVFS)
>>> + chv_set_memory_dvfs(dev_priv, true);
>>> +
>>> + dev_priv->wm.vlv = wm;
>>> }
>>>
>>> static void valleyview_update_sprite_wm(struct drm_plane *plane,
>>> @@ -6823,8 +7128,9 @@ void intel_init_pm(struct drm_device *dev)
>>> else if (INTEL_INFO(dev)->gen == 8)
>>> dev_priv->display.init_clock_gating = broadwell_init_clock_gating;
>>> } else if (IS_CHERRYVIEW(dev)) {
>>> - dev_priv->display.update_wm = valleyview_update_wm;
>>> - dev_priv->display.update_sprite_wm = valleyview_update_sprite_wm;
>>> + vlv_setup_wm_latency(dev);
>>> +
>>> + dev_priv->display.update_wm = vlv_update_wm;
>>> dev_priv->display.init_clock_gating =
>>> cherryview_init_clock_gating;
>>> } else if (IS_VALLEYVIEW(dev)) {
>>>
>
More information about the Intel-gfx
mailing list