- Fix gvt compilation broken on a silent conflict on fixes vs next merge

- Fix runtime PM for LPE audio
 - Revert on ICL workaround
 - Interactive RPS mode
 - Fix for PSR sink status report
 -----BEGIN PGP SIGNATURE-----
 
 iQEcBAABAgAGBQJbaNnHAAoJEPpiX2QO6xPK8roIAKxWQcaVPjkfSKXYF+NiiJVE
 Ge2zjPvAumHbFoJ68lP4uzCraaTt4+b3YrOxncbYyeT/6JBoRDT1vO6MjYkERXhO
 mOmtR/Duum1Kg26Gs+GfDmX9ExFk7q/Xd/4WJ+rBBWYnpcqbg4e6kdqlp7lsUda6
 To6k/lqrMfNF8XpJowDvrAqvqC/NBk45ofda53FE+krkJTGTrRuLrpvBXc57RbpD
 1PGDOtJJBAogaIJUE7LFRnQAB+OzaDWStsSqyvfo9RJF4Z/IYzVcNwePo5Lw7Gq1
 5itpRYCgNN+KblD3RFIxFc7GxvKrbvPbg02T8vR+Qep94Jv/mWmheHFU+2jeQ+A=
 =qrZD
 -----END PGP SIGNATURE-----

Merge tag 'drm-intel-next-fixes-2018-08-06' of git://anongit.freedesktop.org/drm/drm-intel into drm-next

- Fix gvt compilation broken on a silent conflict on fixes vs next merge
- Fix runtime PM for LPE audio
- Revert on ICL workaround
- Interactive RPS mode
- Fix for PSR sink status report

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180806233034.GA20655@intel.com
This commit is contained in:
Dave Airlie 2018-08-08 06:26:09 +10:00
commit 824da016fd
10 changed files with 123 additions and 62 deletions

View File

@ -185,12 +185,6 @@ static int gvt_dma_map_page(struct intel_vgpu *vgpu, unsigned long gfn,
if (ret) if (ret)
return ret; return ret;
if (!pfn_valid(pfn)) {
gvt_vgpu_err("pfn 0x%lx is not mem backed\n", pfn);
vfio_unpin_pages(mdev_dev(vgpu->vdev.mdev), &gfn, 1);
return -EINVAL;
}
/* Setup DMA mapping. */ /* Setup DMA mapping. */
*dma_addr = dma_map_page(dev, page, 0, size, PCI_DMA_BIDIRECTIONAL); *dma_addr = dma_map_page(dev, page, 0, size, PCI_DMA_BIDIRECTIONAL);
ret = dma_mapping_error(dev, *dma_addr); ret = dma_mapping_error(dev, *dma_addr);

View File

@ -1218,7 +1218,8 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
rpcurup, GT_PM_INTERVAL_TO_US(dev_priv, rpcurup)); rpcurup, GT_PM_INTERVAL_TO_US(dev_priv, rpcurup));
seq_printf(m, "RP PREV UP: %d (%dus)\n", seq_printf(m, "RP PREV UP: %d (%dus)\n",
rpprevup, GT_PM_INTERVAL_TO_US(dev_priv, rpprevup)); rpprevup, GT_PM_INTERVAL_TO_US(dev_priv, rpprevup));
seq_printf(m, "Up threshold: %d%%\n", rps->up_threshold); seq_printf(m, "Up threshold: %d%%\n",
rps->power.up_threshold);
seq_printf(m, "RP CUR DOWN EI: %d (%dus)\n", seq_printf(m, "RP CUR DOWN EI: %d (%dus)\n",
rpdownei, GT_PM_INTERVAL_TO_US(dev_priv, rpdownei)); rpdownei, GT_PM_INTERVAL_TO_US(dev_priv, rpdownei));
@ -1226,7 +1227,8 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
rpcurdown, GT_PM_INTERVAL_TO_US(dev_priv, rpcurdown)); rpcurdown, GT_PM_INTERVAL_TO_US(dev_priv, rpcurdown));
seq_printf(m, "RP PREV DOWN: %d (%dus)\n", seq_printf(m, "RP PREV DOWN: %d (%dus)\n",
rpprevdown, GT_PM_INTERVAL_TO_US(dev_priv, rpprevdown)); rpprevdown, GT_PM_INTERVAL_TO_US(dev_priv, rpprevdown));
seq_printf(m, "Down threshold: %d%%\n", rps->down_threshold); seq_printf(m, "Down threshold: %d%%\n",
rps->power.down_threshold);
max_freq = (IS_GEN9_LP(dev_priv) ? rp_state_cap >> 0 : max_freq = (IS_GEN9_LP(dev_priv) ? rp_state_cap >> 0 :
rp_state_cap >> 16) & 0xff; rp_state_cap >> 16) & 0xff;
@ -2218,6 +2220,7 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
seq_printf(m, "CPU waiting? %d\n", count_irq_waiters(dev_priv)); seq_printf(m, "CPU waiting? %d\n", count_irq_waiters(dev_priv));
seq_printf(m, "Boosts outstanding? %d\n", seq_printf(m, "Boosts outstanding? %d\n",
atomic_read(&rps->num_waiters)); atomic_read(&rps->num_waiters));
seq_printf(m, "Interactive? %d\n", READ_ONCE(rps->power.interactive));
seq_printf(m, "Frequency requested %d\n", seq_printf(m, "Frequency requested %d\n",
intel_gpu_freq(dev_priv, rps->cur_freq)); intel_gpu_freq(dev_priv, rps->cur_freq));
seq_printf(m, " min hard:%d, soft:%d; max soft:%d, hard:%d\n", seq_printf(m, " min hard:%d, soft:%d; max soft:%d, hard:%d\n",
@ -2261,13 +2264,13 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
seq_printf(m, "\nRPS Autotuning (current \"%s\" window):\n", seq_printf(m, "\nRPS Autotuning (current \"%s\" window):\n",
rps_power_to_str(rps->power)); rps_power_to_str(rps->power.mode));
seq_printf(m, " Avg. up: %d%% [above threshold? %d%%]\n", seq_printf(m, " Avg. up: %d%% [above threshold? %d%%]\n",
rpup && rpupei ? 100 * rpup / rpupei : 0, rpup && rpupei ? 100 * rpup / rpupei : 0,
rps->up_threshold); rps->power.up_threshold);
seq_printf(m, " Avg. down: %d%% [below threshold? %d%%]\n", seq_printf(m, " Avg. down: %d%% [below threshold? %d%%]\n",
rpdown && rpdownei ? 100 * rpdown / rpdownei : 0, rpdown && rpdownei ? 100 * rpdown / rpdownei : 0,
rps->down_threshold); rps->power.down_threshold);
} else { } else {
seq_puts(m, "\nRPS Autotuning inactive\n"); seq_puts(m, "\nRPS Autotuning inactive\n");
} }
@ -2606,13 +2609,22 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data)
"sink internal error", "sink internal error",
}; };
struct drm_connector *connector = m->private; struct drm_connector *connector = m->private;
struct drm_i915_private *dev_priv = to_i915(connector->dev);
struct intel_dp *intel_dp = struct intel_dp *intel_dp =
enc_to_intel_dp(&intel_attached_encoder(connector)->base); enc_to_intel_dp(&intel_attached_encoder(connector)->base);
int ret;
if (!CAN_PSR(dev_priv)) {
seq_puts(m, "PSR Unsupported\n");
return -ENODEV;
}
if (connector->status != connector_status_connected) if (connector->status != connector_status_connected)
return -ENODEV; return -ENODEV;
if (drm_dp_dpcd_readb(&intel_dp->aux, DP_PSR_STATUS, &val) == 1) { ret = drm_dp_dpcd_readb(&intel_dp->aux, DP_PSR_STATUS, &val);
if (ret == 1) {
const char *str = "unknown"; const char *str = "unknown";
val &= DP_PSR_SINK_STATE_MASK; val &= DP_PSR_SINK_STATE_MASK;
@ -2620,7 +2632,7 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data)
str = sink_status[val]; str = sink_status[val];
seq_printf(m, "Sink PSR status: 0x%x [%s]\n", val, str); seq_printf(m, "Sink PSR status: 0x%x [%s]\n", val, str);
} else { } else {
DRM_ERROR("dpcd read (at %u) failed\n", DP_PSR_STATUS); return ret;
} }
return 0; return 0;

View File

@ -779,11 +779,17 @@ struct intel_rps {
u8 rp0_freq; /* Non-overclocked max frequency. */ u8 rp0_freq; /* Non-overclocked max frequency. */
u16 gpll_ref_freq; /* vlv/chv GPLL reference frequency */ u16 gpll_ref_freq; /* vlv/chv GPLL reference frequency */
u8 up_threshold; /* Current %busy required to uplock */
u8 down_threshold; /* Current %busy required to downclock */
int last_adj; int last_adj;
enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
struct {
struct mutex mutex;
enum { LOW_POWER, BETWEEN, HIGH_POWER } mode;
unsigned int interactive;
u8 up_threshold; /* Current %busy required to uplock */
u8 down_threshold; /* Current %busy required to downclock */
} power;
bool enabled; bool enabled;
atomic_t num_waiters; atomic_t num_waiters;
@ -3422,6 +3428,8 @@ extern void i915_redisable_vga_power_on(struct drm_i915_private *dev_priv);
extern bool ironlake_set_drps(struct drm_i915_private *dev_priv, u8 val); extern bool ironlake_set_drps(struct drm_i915_private *dev_priv, u8 val);
extern void intel_init_pch_refclk(struct drm_i915_private *dev_priv); extern void intel_init_pch_refclk(struct drm_i915_private *dev_priv);
extern int intel_set_rps(struct drm_i915_private *dev_priv, u8 val); extern int intel_set_rps(struct drm_i915_private *dev_priv, u8 val);
extern void intel_rps_mark_interactive(struct drm_i915_private *i915,
bool interactive);
extern bool intel_set_memory_cxsr(struct drm_i915_private *dev_priv, extern bool intel_set_memory_cxsr(struct drm_i915_private *dev_priv,
bool enable); bool enable);

View File

@ -1265,9 +1265,9 @@ static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir)
c0 = max(render, media); c0 = max(render, media);
c0 *= 1000 * 100 << 8; /* to usecs and scale to threshold% */ c0 *= 1000 * 100 << 8; /* to usecs and scale to threshold% */
if (c0 > time * rps->up_threshold) if (c0 > time * rps->power.up_threshold)
events = GEN6_PM_RP_UP_THRESHOLD; events = GEN6_PM_RP_UP_THRESHOLD;
else if (c0 < time * rps->down_threshold) else if (c0 < time * rps->power.down_threshold)
events = GEN6_PM_RP_DOWN_THRESHOLD; events = GEN6_PM_RP_DOWN_THRESHOLD;
} }

View File

@ -2780,9 +2780,6 @@ enum i915_power_well_id {
#define GEN8_4x4_STC_OPTIMIZATION_DISABLE (1 << 6) #define GEN8_4x4_STC_OPTIMIZATION_DISABLE (1 << 6)
#define GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE (1 << 1) #define GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE (1 << 1)
#define GEN10_CACHE_MODE_SS _MMIO(0xe420)
#define FLOAT_BLEND_OPTIMIZATION_ENABLE (1 << 4)
#define GEN6_BLITTER_ECOSKPD _MMIO(0x221d0) #define GEN6_BLITTER_ECOSKPD _MMIO(0x221d0)
#define GEN6_BLITTER_LOCK_SHIFT 16 #define GEN6_BLITTER_LOCK_SHIFT 16
#define GEN6_BLITTER_FBC_NOTIFY (1 << 3) #define GEN6_BLITTER_FBC_NOTIFY (1 << 3)

View File

@ -13104,6 +13104,19 @@ intel_prepare_plane_fb(struct drm_plane *plane,
add_rps_boost_after_vblank(new_state->crtc, new_state->fence); add_rps_boost_after_vblank(new_state->crtc, new_state->fence);
} }
/*
* We declare pageflips to be interactive and so merit a small bias
* towards upclocking to deliver the frame on time. By only changing
* the RPS thresholds to sample more regularly and aim for higher
* clocks we can hopefully deliver low power workloads (like kodi)
* that are not quite steady state without resorting to forcing
* maximum clocks following a vblank miss (see do_rps_boost()).
*/
if (!intel_state->rps_interactive) {
intel_rps_mark_interactive(dev_priv, true);
intel_state->rps_interactive = true;
}
return 0; return 0;
} }
@ -13120,8 +13133,15 @@ void
intel_cleanup_plane_fb(struct drm_plane *plane, intel_cleanup_plane_fb(struct drm_plane *plane,
struct drm_plane_state *old_state) struct drm_plane_state *old_state)
{ {
struct intel_atomic_state *intel_state =
to_intel_atomic_state(old_state->state);
struct drm_i915_private *dev_priv = to_i915(plane->dev); struct drm_i915_private *dev_priv = to_i915(plane->dev);
if (intel_state->rps_interactive) {
intel_rps_mark_interactive(dev_priv, false);
intel_state->rps_interactive = false;
}
/* Should only be called after a successful intel_prepare_plane_fb()! */ /* Should only be called after a successful intel_prepare_plane_fb()! */
mutex_lock(&dev_priv->drm.struct_mutex); mutex_lock(&dev_priv->drm.struct_mutex);
intel_plane_unpin_fb(to_intel_plane_state(old_state)); intel_plane_unpin_fb(to_intel_plane_state(old_state));

View File

@ -484,6 +484,8 @@ struct intel_atomic_state {
*/ */
bool skip_intermediate_wm; bool skip_intermediate_wm;
bool rps_interactive;
/* Gen9+ only */ /* Gen9+ only */
struct skl_ddb_values wm_results; struct skl_ddb_values wm_results;

View File

@ -126,9 +126,7 @@ lpe_audio_platdev_create(struct drm_i915_private *dev_priv)
return platdev; return platdev;
} }
pm_runtime_forbid(&platdev->dev); pm_runtime_no_callbacks(&platdev->dev);
pm_runtime_set_active(&platdev->dev);
pm_runtime_enable(&platdev->dev);
return platdev; return platdev;
} }

View File

@ -6264,42 +6264,15 @@ static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val)
return limits; return limits;
} }
static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) static void rps_set_power(struct drm_i915_private *dev_priv, int new_power)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps; struct intel_rps *rps = &dev_priv->gt_pm.rps;
int new_power;
u32 threshold_up = 0, threshold_down = 0; /* in % */ u32 threshold_up = 0, threshold_down = 0; /* in % */
u32 ei_up = 0, ei_down = 0; u32 ei_up = 0, ei_down = 0;
new_power = rps->power; lockdep_assert_held(&rps->power.mutex);
switch (rps->power) {
case LOW_POWER:
if (val > rps->efficient_freq + 1 &&
val > rps->cur_freq)
new_power = BETWEEN;
break;
case BETWEEN: if (new_power == rps->power.mode)
if (val <= rps->efficient_freq &&
val < rps->cur_freq)
new_power = LOW_POWER;
else if (val >= rps->rp0_freq &&
val > rps->cur_freq)
new_power = HIGH_POWER;
break;
case HIGH_POWER:
if (val < (rps->rp1_freq + rps->rp0_freq) >> 1 &&
val < rps->cur_freq)
new_power = BETWEEN;
break;
}
/* Max/min bins are special */
if (val <= rps->min_freq_softlimit)
new_power = LOW_POWER;
if (val >= rps->max_freq_softlimit)
new_power = HIGH_POWER;
if (new_power == rps->power)
return; return;
/* Note the units here are not exactly 1us, but 1280ns. */ /* Note the units here are not exactly 1us, but 1280ns. */
@ -6362,12 +6335,71 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
GEN6_RP_DOWN_IDLE_AVG); GEN6_RP_DOWN_IDLE_AVG);
skip_hw_write: skip_hw_write:
rps->power = new_power; rps->power.mode = new_power;
rps->up_threshold = threshold_up; rps->power.up_threshold = threshold_up;
rps->down_threshold = threshold_down; rps->power.down_threshold = threshold_down;
}
static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
{
struct intel_rps *rps = &dev_priv->gt_pm.rps;
int new_power;
new_power = rps->power.mode;
switch (rps->power.mode) {
case LOW_POWER:
if (val > rps->efficient_freq + 1 &&
val > rps->cur_freq)
new_power = BETWEEN;
break;
case BETWEEN:
if (val <= rps->efficient_freq &&
val < rps->cur_freq)
new_power = LOW_POWER;
else if (val >= rps->rp0_freq &&
val > rps->cur_freq)
new_power = HIGH_POWER;
break;
case HIGH_POWER:
if (val < (rps->rp1_freq + rps->rp0_freq) >> 1 &&
val < rps->cur_freq)
new_power = BETWEEN;
break;
}
/* Max/min bins are special */
if (val <= rps->min_freq_softlimit)
new_power = LOW_POWER;
if (val >= rps->max_freq_softlimit)
new_power = HIGH_POWER;
mutex_lock(&rps->power.mutex);
if (rps->power.interactive)
new_power = HIGH_POWER;
rps_set_power(dev_priv, new_power);
mutex_unlock(&rps->power.mutex);
rps->last_adj = 0; rps->last_adj = 0;
} }
void intel_rps_mark_interactive(struct drm_i915_private *i915, bool interactive)
{
struct intel_rps *rps = &i915->gt_pm.rps;
if (INTEL_GEN(i915) < 6)
return;
mutex_lock(&rps->power.mutex);
if (interactive) {
if (!rps->power.interactive++ && READ_ONCE(i915->gt.awake))
rps_set_power(i915, HIGH_POWER);
} else {
GEM_BUG_ON(!rps->power.interactive);
rps->power.interactive--;
}
mutex_unlock(&rps->power.mutex);
}
static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps; struct intel_rps *rps = &dev_priv->gt_pm.rps;
@ -6780,7 +6812,7 @@ static void reset_rps(struct drm_i915_private *dev_priv,
u8 freq = rps->cur_freq; u8 freq = rps->cur_freq;
/* force a reset */ /* force a reset */
rps->power = -1; rps->power.mode = -1;
rps->cur_freq = -1; rps->cur_freq = -1;
if (set(dev_priv, freq)) if (set(dev_priv, freq))
@ -9604,6 +9636,7 @@ int intel_freq_opcode(struct drm_i915_private *dev_priv, int val)
void intel_pm_setup(struct drm_i915_private *dev_priv) void intel_pm_setup(struct drm_i915_private *dev_priv)
{ {
mutex_init(&dev_priv->pcu_lock); mutex_init(&dev_priv->pcu_lock);
mutex_init(&dev_priv->gt_pm.rps.power.mutex);
atomic_set(&dev_priv->gt_pm.rps.num_waiters, 0); atomic_set(&dev_priv->gt_pm.rps.num_waiters, 0);

View File

@ -508,9 +508,6 @@ static int icl_ctx_workarounds_init(struct drm_i915_private *dev_priv)
WA_SET_BIT_MASKED(GEN11_COMMON_SLICE_CHICKEN3, WA_SET_BIT_MASKED(GEN11_COMMON_SLICE_CHICKEN3,
GEN11_BLEND_EMB_FIX_DISABLE_IN_RCC); GEN11_BLEND_EMB_FIX_DISABLE_IN_RCC);
/* WaEnableFloatBlendOptimization:icl */
WA_SET_BIT_MASKED(GEN10_CACHE_MODE_SS, FLOAT_BLEND_OPTIMIZATION_ENABLE);
return 0; return 0;
} }