提交 8fdded82 编写于 作者: V Ville Syrjälä

drm/i915: Disable L2 cache clock gating on 830 when using the overlay

BSpec says:
"Overlay Clock Gating Must be Disabled: Overlay & L2 Cache clock gating
must be disabled in order to prevent device hangs when turning off overlay.SW
must turn off Ovrunit clock gating (6200h) and L2 Cache clock gating (C8h)."

We only turned off the overlay clock gating (due to lack of docs I
presume). After a bit of experimentation it looks like the the magic
C8h register lives in the PCI config space of device 0, and the magic
bit appears to be bit 2. Or at the very least this eliminates the GPU
death after MI_OVERLAY_OFF.

L2 clock gating seems to save ~80mW, so let's keep it on unless we need
to actually use the overlay.

Also let's move the OVRUNIT clock gating to the same place since we can,
and 845 supposedly doesn't need it.
Signed-off-by: NVille Syrjälä <ville.syrjala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1481131693-27993-11-git-send-email-ville.syrjala@linux.intel.comAcked-by: NChris Wilson <chris@chris-wilson.co.uk>
上级 39ccc04e
...@@ -110,6 +110,10 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) ...@@ -110,6 +110,10 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
#define GRDOM_RESET_STATUS (1 << 1) #define GRDOM_RESET_STATUS (1 << 1)
#define GRDOM_RESET_ENABLE (1 << 0) #define GRDOM_RESET_ENABLE (1 << 0)
/* BSpec only has register offset, PCI device and bit found empirically */
#define I830_CLOCK_GATE 0xc8 /* device 0 */
#define I830_L2_CACHE_CLOCK_GATE_DISABLE (1 << 2)
#define GCDGMBUS 0xcc #define GCDGMBUS 0xcc
#define GCFGC2 0xda #define GCFGC2 0xda
......
...@@ -187,6 +187,29 @@ struct intel_overlay { ...@@ -187,6 +187,29 @@ struct intel_overlay {
struct i915_gem_active last_flip; struct i915_gem_active last_flip;
}; };
static void i830_overlay_clock_gating(struct drm_i915_private *dev_priv,
bool enable)
{
struct pci_dev *pdev = dev_priv->drm.pdev;
u8 val;
/* WA_OVERLAY_CLKGATE:alm */
if (enable)
I915_WRITE(DSPCLK_GATE_D, 0);
else
I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
/* WA_DISABLE_L2CACHE_CLOCK_GATING:alm */
pci_bus_read_config_byte(pdev->bus,
PCI_DEVFN(0, 0), I830_CLOCK_GATE, &val);
if (enable)
val &= ~I830_L2_CACHE_CLOCK_GATE_DISABLE;
else
val |= I830_L2_CACHE_CLOCK_GATE_DISABLE;
pci_bus_write_config_byte(pdev->bus,
PCI_DEVFN(0, 0), I830_CLOCK_GATE, val);
}
static struct overlay_registers __iomem * static struct overlay_registers __iomem *
intel_overlay_map_regs(struct intel_overlay *overlay) intel_overlay_map_regs(struct intel_overlay *overlay)
{ {
...@@ -262,6 +285,9 @@ static int intel_overlay_on(struct intel_overlay *overlay) ...@@ -262,6 +285,9 @@ static int intel_overlay_on(struct intel_overlay *overlay)
overlay->active = true; overlay->active = true;
if (IS_I830(dev_priv))
i830_overlay_clock_gating(dev_priv, false);
ring = req->ring; ring = req->ring;
intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON); intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON);
intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE); intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE);
...@@ -366,12 +392,16 @@ static void intel_overlay_off_tail(struct i915_gem_active *active, ...@@ -366,12 +392,16 @@ static void intel_overlay_off_tail(struct i915_gem_active *active,
{ {
struct intel_overlay *overlay = struct intel_overlay *overlay =
container_of(active, typeof(*overlay), last_flip); container_of(active, typeof(*overlay), last_flip);
struct drm_i915_private *dev_priv = overlay->i915;
intel_overlay_release_old_vma(overlay); intel_overlay_release_old_vma(overlay);
overlay->crtc->overlay = NULL; overlay->crtc->overlay = NULL;
overlay->crtc = NULL; overlay->crtc = NULL;
overlay->active = false; overlay->active = false;
if (IS_I830(dev_priv))
i830_overlay_clock_gating(dev_priv, true);
} }
/* overlay needs to be disabled in OCMD reg */ /* overlay needs to be disabled in OCMD reg */
......
...@@ -7603,8 +7603,6 @@ static void i85x_init_clock_gating(struct drm_i915_private *dev_priv) ...@@ -7603,8 +7603,6 @@ static void i85x_init_clock_gating(struct drm_i915_private *dev_priv)
static void i830_init_clock_gating(struct drm_i915_private *dev_priv) static void i830_init_clock_gating(struct drm_i915_private *dev_priv)
{ {
I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
I915_WRITE(MEM_MODE, I915_WRITE(MEM_MODE,
_MASKED_BIT_ENABLE(MEM_DISPLAY_A_TRICKLE_FEED_DISABLE) | _MASKED_BIT_ENABLE(MEM_DISPLAY_A_TRICKLE_FEED_DISABLE) |
_MASKED_BIT_ENABLE(MEM_DISPLAY_B_TRICKLE_FEED_DISABLE)); _MASKED_BIT_ENABLE(MEM_DISPLAY_B_TRICKLE_FEED_DISABLE));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册