mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
drm/i915: Reduce duplicated forcewake logic
Introduce a structure to track the individual forcewake domains and use
that to eliminate duplicate logic.
v2: - Rebase on latest dinq (Mika)
- for_each_fw_domain macro (Mika)
- Handle reset atomically, keeping the timer running (Mika)
- for_each_fw_domain parameter ordering (Chris)
- defer timer on new register access (Mika)
v3: - Fix forcewake_reset/get race by waiting pending timers
v4: - cond_resched and verbose warning on timer deletion (Chris)
- need to run pending timers manually on reset
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> (v1)
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
Acked-by: Deepak S <deepak.s@linux.intel.com> (v2)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
committed by
Daniel Vetter
parent
51f6788584
commit
b2cff0dbbb
@@ -1288,14 +1288,36 @@ static int ironlake_drpc_info(struct seq_file *m)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_info_node *node = m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_uncore_forcewake_domain *fw_domain;
|
||||
const char *domain_names[] = {
|
||||
"render",
|
||||
"blitter",
|
||||
"media",
|
||||
};
|
||||
int i;
|
||||
|
||||
spin_lock_irq(&dev_priv->uncore.lock);
|
||||
for_each_fw_domain(fw_domain, dev_priv, i) {
|
||||
seq_printf(m, "%s.wake_count = %u\n",
|
||||
domain_names[i],
|
||||
fw_domain->wake_count);
|
||||
}
|
||||
spin_unlock_irq(&dev_priv->uncore.lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vlv_drpc_info(struct seq_file *m)
|
||||
{
|
||||
|
||||
struct drm_info_node *node = m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 rpmodectl1, rcctl1, pw_status;
|
||||
unsigned fw_rendercount = 0, fw_mediacount = 0;
|
||||
|
||||
intel_runtime_pm_get(dev_priv);
|
||||
|
||||
@@ -1327,22 +1349,11 @@ static int vlv_drpc_info(struct seq_file *m)
|
||||
seq_printf(m, "Media RC6 residency since boot: %u\n",
|
||||
I915_READ(VLV_GT_MEDIA_RC6));
|
||||
|
||||
spin_lock_irq(&dev_priv->uncore.lock);
|
||||
fw_rendercount = dev_priv->uncore.fw_rendercount;
|
||||
fw_mediacount = dev_priv->uncore.fw_mediacount;
|
||||
spin_unlock_irq(&dev_priv->uncore.lock);
|
||||
|
||||
seq_printf(m, "Forcewake Render Count = %u\n", fw_rendercount);
|
||||
seq_printf(m, "Forcewake Media Count = %u\n", fw_mediacount);
|
||||
|
||||
|
||||
return 0;
|
||||
return i915_gen6_forcewake_count_info(m, NULL);
|
||||
}
|
||||
|
||||
|
||||
static int gen6_drpc_info(struct seq_file *m)
|
||||
{
|
||||
|
||||
struct drm_info_node *node = m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
@@ -1356,7 +1367,7 @@ static int gen6_drpc_info(struct seq_file *m)
|
||||
intel_runtime_pm_get(dev_priv);
|
||||
|
||||
spin_lock_irq(&dev_priv->uncore.lock);
|
||||
forcewake_count = dev_priv->uncore.forcewake_count;
|
||||
forcewake_count = dev_priv->uncore.fw_domain[FW_DOMAIN_ID_RENDER].wake_count;
|
||||
spin_unlock_irq(&dev_priv->uncore.lock);
|
||||
|
||||
if (forcewake_count) {
|
||||
@@ -1984,30 +1995,6 @@ static int i915_execlists(struct seq_file *m, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_info_node *node = m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
unsigned forcewake_count = 0, fw_rendercount = 0, fw_mediacount = 0;
|
||||
|
||||
spin_lock_irq(&dev_priv->uncore.lock);
|
||||
if (IS_VALLEYVIEW(dev)) {
|
||||
fw_rendercount = dev_priv->uncore.fw_rendercount;
|
||||
fw_mediacount = dev_priv->uncore.fw_mediacount;
|
||||
} else
|
||||
forcewake_count = dev_priv->uncore.forcewake_count;
|
||||
spin_unlock_irq(&dev_priv->uncore.lock);
|
||||
|
||||
if (IS_VALLEYVIEW(dev)) {
|
||||
seq_printf(m, "fw_rendercount = %u\n", fw_rendercount);
|
||||
seq_printf(m, "fw_mediacount = %u\n", fw_mediacount);
|
||||
} else
|
||||
seq_printf(m, "forcewake count = %u\n", forcewake_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *swizzle_string(unsigned swizzle)
|
||||
{
|
||||
switch (swizzle) {
|
||||
|
||||
@@ -596,21 +596,46 @@ struct intel_uncore_funcs {
|
||||
uint64_t val, bool trace);
|
||||
};
|
||||
|
||||
enum {
|
||||
FW_DOMAIN_ID_RENDER = 0,
|
||||
FW_DOMAIN_ID_BLITTER,
|
||||
FW_DOMAIN_ID_MEDIA,
|
||||
|
||||
FW_DOMAIN_ID_COUNT
|
||||
};
|
||||
|
||||
struct intel_uncore {
|
||||
spinlock_t lock; /** lock is also taken in irq contexts. */
|
||||
|
||||
struct intel_uncore_funcs funcs;
|
||||
|
||||
unsigned fifo_count;
|
||||
unsigned forcewake_count;
|
||||
unsigned fw_domains;
|
||||
|
||||
unsigned fw_rendercount;
|
||||
unsigned fw_mediacount;
|
||||
unsigned fw_blittercount;
|
||||
|
||||
struct timer_list force_wake_timer;
|
||||
struct intel_uncore_forcewake_domain {
|
||||
struct drm_i915_private *i915;
|
||||
int id;
|
||||
unsigned wake_count;
|
||||
struct timer_list timer;
|
||||
} fw_domain[FW_DOMAIN_ID_COUNT];
|
||||
#define FORCEWAKE_RENDER (1 << FW_DOMAIN_ID_RENDER)
|
||||
#define FORCEWAKE_BLITTER (1 << FW_DOMAIN_ID_BLITTER)
|
||||
#define FORCEWAKE_MEDIA (1 << FW_DOMAIN_ID_MEDIA)
|
||||
#define FORCEWAKE_ALL (FORCEWAKE_RENDER | \
|
||||
FORCEWAKE_BLITTER | \
|
||||
FORCEWAKE_MEDIA)
|
||||
};
|
||||
|
||||
/* Iterate over initialised fw domains */
|
||||
#define for_each_fw_domain_mask(domain__, mask__, dev_priv__, i__) \
|
||||
for ((i__) = 0, (domain__) = &(dev_priv__)->uncore.fw_domain[0]; \
|
||||
(i__) < FW_DOMAIN_ID_COUNT; \
|
||||
(i__)++, (domain__) = &(dev_priv__)->uncore.fw_domain[i__]) \
|
||||
if (((mask__) & (dev_priv__)->uncore.fw_domains) & (1 << (i__)))
|
||||
|
||||
#define for_each_fw_domain(domain__, dev_priv__, i__) \
|
||||
for_each_fw_domain_mask(domain__, FORCEWAKE_ALL, dev_priv__, i__)
|
||||
|
||||
#define DEV_INFO_FOR_EACH_FLAG(func, sep) \
|
||||
func(is_mobile) sep \
|
||||
func(is_i85x) sep \
|
||||
@@ -3167,8 +3192,10 @@ extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
|
||||
* must be set to prevent GT core from power down and stale values being
|
||||
* returned.
|
||||
*/
|
||||
void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine);
|
||||
void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine);
|
||||
void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
|
||||
unsigned fw_domains);
|
||||
void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
|
||||
unsigned fw_domains);
|
||||
void assert_force_wake_inactive(struct drm_i915_private *dev_priv);
|
||||
|
||||
int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val);
|
||||
@@ -3200,13 +3227,6 @@ void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
|
||||
int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val);
|
||||
int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val);
|
||||
|
||||
#define FORCEWAKE_RENDER (1 << 0)
|
||||
#define FORCEWAKE_MEDIA (1 << 1)
|
||||
#define FORCEWAKE_BLITTER (1 << 2)
|
||||
#define FORCEWAKE_ALL (FORCEWAKE_RENDER | FORCEWAKE_MEDIA | \
|
||||
FORCEWAKE_BLITTER)
|
||||
|
||||
|
||||
#define I915_READ8(reg) dev_priv->uncore.funcs.mmio_readb(dev_priv, (reg), true)
|
||||
#define I915_WRITE8(reg, val) dev_priv->uncore.funcs.mmio_writeb(dev_priv, (reg), (val), true)
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user