diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2013-09-30 06:47:49 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2013-09-30 06:47:49 +0000 |
commit | e52f1fdae5dfd2bec14a1cc45f5e2ff5b19e6a55 (patch) | |
tree | d0e0e6e0e7160e1db153036337dbe63b81ca5e59 /sys | |
parent | 9e5c3ce91a15b3dd85ab37944b0fad7225a16c00 (diff) |
move the read/write functions and macros closer to linux
noteably this uses the gt lock and force wake in some cases
and includes a gen5/ironlake errata.
ok kettenis@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/drm/i915/i915_drv.c | 176 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915/i915_drv.h | 120 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915/i915_trace.h | 7 |
3 files changed, 272 insertions, 31 deletions
diff --git a/sys/dev/pci/drm/i915/i915_drv.c b/sys/dev/pci/drm/i915/i915_drv.c index 0987df6528d..153239999f6 100644 --- a/sys/dev/pci/drm/i915/i915_drv.c +++ b/sys/dev/pci/drm/i915/i915_drv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: i915_drv.c,v 1.38 2013/09/08 11:59:44 jsg Exp $ */ +/* $OpenBSD: i915_drv.c,v 1.39 2013/09/30 06:47:48 jsg Exp $ */ /* * Copyright (c) 2008-2009 Owain G. Ainsworth <oga@openbsd.org> * @@ -50,6 +50,7 @@ #include <dev/pci/drm/i915_drm.h> #include "i915_drv.h" #include "intel_drv.h" +#include "i915_trace.h" #include <machine/pmap.h> @@ -2266,3 +2267,176 @@ intel_detect_pch(struct inteldrm_softc *dev_priv) } } +/* We give fast paths for the really cool registers */ +#define NEEDS_FORCE_WAKE(dev, reg) \ + ((HAS_FORCE_WAKE(dev)) && \ + ((reg) < 0x40000) && \ + ((reg) != FORCEWAKE)) + +static bool IS_DISPLAYREG(u32 reg) +{ + /* + * This should make it easier to transition modules over to the + * new register block scheme, since we can do it incrementally. + */ + if (reg >= VLV_DISPLAY_BASE) + return false; + + if (reg >= RENDER_RING_BASE && + reg < RENDER_RING_BASE + 0xff) + return false; + if (reg >= GEN6_BSD_RING_BASE && + reg < GEN6_BSD_RING_BASE + 0xff) + return false; + if (reg >= BLT_RING_BASE && + reg < BLT_RING_BASE + 0xff) + return false; + + if (reg == PGTBL_ER) + return false; + + if (reg >= IPEIR_I965 && + reg < HWSTAM) + return false; + + if (reg == MI_MODE) + return false; + + if (reg == GFX_MODE_GEN7) + return false; + + if (reg == RENDER_HWS_PGA_GEN7 || + reg == BSD_HWS_PGA_GEN7 || + reg == BLT_HWS_PGA_GEN7) + return false; + + if (reg == GEN6_BSD_SLEEP_PSMI_CONTROL || + reg == GEN6_BSD_RNCID) + return false; + + if (reg == GEN6_BLITTER_ECOSKPD) + return false; + + if (reg >= 0x4000c && + reg <= 0x4002c) + return false; + + if (reg >= 0x4f000 && + reg <= 0x4f08f) + return false; + + if (reg >= 0x4f100 && + reg <= 0x4f11f) + return false; + + if (reg >= VLV_MASTER_IER && + reg <= GEN6_PMIER) + return false; + + if (reg >= FENCE_REG_SANDYBRIDGE_0 && + reg < (FENCE_REG_SANDYBRIDGE_0 + (16*8))) + return false; + + if (reg >= VLV_IIR_RW && + reg <= VLV_ISR) + return false; + + if (reg == FORCEWAKE_VLV || + reg == FORCEWAKE_ACK_VLV) + return false; + + if (reg == GEN6_GDRST) + return false; + + switch (reg) { + case _3D_CHICKEN3: + case IVB_CHICKEN3: + case GEN7_COMMON_SLICE_CHICKEN1: + case GEN7_L3CNTLREG1: + case GEN7_L3_CHICKEN_MODE_REGISTER: + case GEN7_ROW_CHICKEN2: + case GEN7_L3SQCREG4: + case GEN7_SQ_CHICKEN_MBCUNIT_CONFIG: + case GEN7_HALF_SLICE_CHICKEN1: + case GEN6_MBCTL: + case GEN6_UCGCTL2: + return false; + default: + break; + } + + return true; +} + +static void +ilk_dummy_write(struct drm_i915_private *dev_priv) +{ + /* WaIssueDummyWriteToWakeupFromRC6: Issue a dummy write to wake up the + * chip from rc6 before touching it for real. MI_MODE is masked, hence + * harmless to write 0 into. */ + I915_WRITE_NOTRACE(MI_MODE, 0); +} + +#define __i915_read(x, y) \ +u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ + struct drm_device *dev = (struct drm_device *)dev_priv->drmdev; \ + u##x val = 0; \ + mtx_enter(&dev_priv->gt_lock); \ + if (IS_GEN5(dev)) \ + ilk_dummy_write(dev_priv); \ + if (NEEDS_FORCE_WAKE((dev), (reg))) { \ + if (dev_priv->forcewake_count == 0) \ + dev_priv->gt.force_wake_get(dev_priv); \ + val = read##x(dev_priv, reg); \ + if (dev_priv->forcewake_count == 0) \ + dev_priv->gt.force_wake_put(dev_priv); \ + } else if (IS_VALLEYVIEW(dev) && IS_DISPLAYREG(reg)) { \ + val = read##x(dev_priv, reg + 0x180000); \ + } else { \ + val = read##x(dev_priv, reg); \ + } \ + mtx_leave(&dev_priv->gt_lock); \ + trace_i915_reg_rw(false, reg, val, sizeof(val)); \ + return val; \ +} + +__i915_read(8, b) +__i915_read(16, w) +__i915_read(32, l) +__i915_read(64, q) +#undef __i915_read + +#define __i915_write(x, y) \ +void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ + u32 __fifo_ret = 0; \ + struct drm_device *dev = (struct drm_device *)dev_priv->drmdev; \ + trace_i915_reg_rw(true, reg, val, sizeof(val)); \ + mtx_enter(&dev_priv->gt_lock); \ + if (NEEDS_FORCE_WAKE((dev), (reg))) { \ + __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ + } \ + if (IS_GEN5(dev)) \ + ilk_dummy_write(dev_priv); \ + if (IS_HASWELL(dev) && (I915_READ_NOTRACE(GEN7_ERR_INT) & ERR_INT_MMIO_UNCLAIMED)) { \ + DRM_ERROR("Unknown unclaimed register before writing to %x\n", reg); \ + I915_WRITE_NOTRACE(GEN7_ERR_INT, ERR_INT_MMIO_UNCLAIMED); \ + } \ + if (IS_VALLEYVIEW(dev) && IS_DISPLAYREG(reg)) { \ + write##x(dev_priv, reg + 0x180000, val); \ + } else { \ + write##x(dev_priv, reg, val); \ + } \ + if (unlikely(__fifo_ret)) { \ + gen6_gt_check_fifodbg(dev_priv); \ + } \ + if (IS_HASWELL(dev) && (I915_READ_NOTRACE(GEN7_ERR_INT) & ERR_INT_MMIO_UNCLAIMED)) { \ + DRM_ERROR("Unclaimed write to %x\n", reg); \ + write32(dev_priv, GEN7_ERR_INT, ERR_INT_MMIO_UNCLAIMED); \ + } \ + mtx_leave(&dev_priv->gt_lock); \ +} +__i915_write(8, b) +__i915_write(16, w) +__i915_write(32, l) +__i915_write(64, q) +#undef __i915_write diff --git a/sys/dev/pci/drm/i915/i915_drv.h b/sys/dev/pci/drm/i915/i915_drv.h index 9060a44a716..778c5bc7610 100644 --- a/sys/dev/pci/drm/i915/i915_drv.h +++ b/sys/dev/pci/drm/i915/i915_drv.h @@ -1,4 +1,4 @@ -/* $OpenBSD: i915_drv.h,v 1.28 2013/09/18 08:50:28 jsg Exp $ */ +/* $OpenBSD: i915_drv.h,v 1.29 2013/09/30 06:47:48 jsg Exp $ */ /* i915_drv.h -- Private header for the I915 driver -*- linux-c -*- */ /* @@ -1339,50 +1339,112 @@ int __gen6_gt_wait_for_fifo(struct inteldrm_softc *dev_priv); int sandybridge_pcode_read(struct inteldrm_softc *dev_priv, u8 mbox, u32 *val); int sandybridge_pcode_write(struct inteldrm_softc *dev_priv, u8 mbox, u32 val); +static __inline void +write8(struct inteldrm_softc *dev_priv, bus_size_t reg, uint8_t val) +{ + bus_space_write_1(dev_priv->regs->bst,dev_priv->regs->bsh, (reg), + (val)); +} + +static __inline void +write16(struct inteldrm_softc *dev_priv, bus_size_t reg, uint16_t val) +{ + bus_space_write_2(dev_priv->regs->bst,dev_priv->regs->bsh, (reg), + (val)); +} + +static __inline void +write32(struct inteldrm_softc *dev_priv, bus_size_t reg, uint32_t val) +{ + bus_space_write_4(dev_priv->regs->bst,dev_priv->regs->bsh, (reg), + (val)); +} + /* XXX need bus_space_write_8, this evaluated arguments twice */ static __inline void -write64(struct inteldrm_softc *dev_priv, bus_size_t off, u_int64_t reg) +write64(struct inteldrm_softc *dev_priv, bus_size_t reg, uint64_t val) { bus_space_write_4(dev_priv->regs->bst, dev_priv->regs->bsh, - off, (u_int32_t)reg); + reg, (u_int32_t)val); bus_space_write_4(dev_priv->regs->bst, dev_priv->regs->bsh, - off + 4, upper_32_bits(reg)); + reg + 4, upper_32_bits(val)); +} + +static __inline uint8_t +read8(struct inteldrm_softc *dev_priv, bus_size_t reg) +{ + return (bus_space_read_1(dev_priv->regs->bst, dev_priv->regs->bsh, + (reg))); } -static __inline u_int64_t -read64(struct inteldrm_softc *dev_priv, bus_size_t off) +static __inline uint16_t +read16(struct inteldrm_softc *dev_priv, bus_size_t reg) +{ + return (bus_space_read_2(dev_priv->regs->bst, dev_priv->regs->bsh, + (reg))); +} + +static __inline uint32_t +read32(struct inteldrm_softc *dev_priv, bus_size_t reg) +{ + return (bus_space_read_4(dev_priv->regs->bst, dev_priv->regs->bsh, + (reg))); +} + +static __inline uint64_t +read64(struct inteldrm_softc *dev_priv, bus_size_t reg) { u_int32_t low, high; low = bus_space_read_4(dev_priv->regs->bst, - dev_priv->regs->bsh, off); + dev_priv->regs->bsh, reg); high = bus_space_read_4(dev_priv->regs->bst, - dev_priv->regs->bsh, off + 4); + dev_priv->regs->bsh, reg + 4); return ((u_int64_t)low | ((u_int64_t)high << 32)); } -#define I915_READ64(off) read64(dev_priv, off) - -#define I915_WRITE64(off, reg) write64(dev_priv, off, reg) - -#define I915_READ(reg) bus_space_read_4(dev_priv->regs->bst, \ - dev_priv->regs->bsh, (reg)) -#define I915_READ_NOTRACE(reg) I915_READ(reg) -#define I915_WRITE(reg,val) bus_space_write_4(dev_priv->regs->bst, \ - dev_priv->regs->bsh, (reg), (val)) -#define I915_WRITE_NOTRACE(reg,val) I915_WRITE(reg, val) -#define I915_READ16(reg) bus_space_read_2(dev_priv->regs->bst, \ - dev_priv->regs->bsh, (reg)) -#define I915_WRITE16(reg,val) bus_space_write_2(dev_priv->regs->bst, \ - dev_priv->regs->bsh, (reg), (val)) -#define I915_READ8(reg) bus_space_read_1(dev_priv->regs->bst, \ - dev_priv->regs->bsh, (reg)) -#define I915_WRITE8(reg,val) bus_space_write_1(dev_priv->regs->bst, \ - dev_priv->regs->bsh, (reg), (val)) - -#define POSTING_READ(reg) (void)I915_READ(reg) -#define POSTING_READ16(reg) (void)I915_READ16(reg) + +#define __i915_read(x, y) \ + u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg); + +__i915_read(8, b) +__i915_read(16, w) +__i915_read(32, l) +__i915_read(64, q) +#undef __i915_read + +#define __i915_write(x, y) \ + void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val); + +__i915_write(8, b) +__i915_write(16, w) +__i915_write(32, l) +__i915_write(64, q) +#undef __i915_write + +#define I915_READ8(reg) i915_read8(dev_priv, (reg)) +#define I915_WRITE8(reg, val) i915_write8(dev_priv, (reg), (val)) + +#define I915_READ16(reg) i915_read16(dev_priv, (reg)) +#define I915_WRITE16(reg, val) i915_write16(dev_priv, (reg), (val)) +#define I915_READ16_NOTRACE(reg) bus_space_read_2(dev_priv->regs->bst, \ + dev_priv->regs->bsh, (reg)) +#define I915_WRITE16_NOTRACE(reg,val) bus_space_write_2(dev_priv->regs->bst, \ + dev_priv->regs->bsh, (reg), (val)) + +#define I915_READ(reg) i915_read32(dev_priv, (reg)) +#define I915_WRITE(reg, val) i915_write32(dev_priv, (reg), (val)) +#define I915_READ_NOTRACE(reg) bus_space_read_4(dev_priv->regs->bst, \ + dev_priv->regs->bsh, (reg)) +#define I915_WRITE_NOTRACE(reg,val) bus_space_write_4(dev_priv->regs->bst, \ + dev_priv->regs->bsh, (reg), (val)) + +#define I915_WRITE64(reg, val) i915_write64(dev_priv, (reg), (val)) +#define I915_READ64(reg) i915_read64(dev_priv, (reg)) + +#define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg) +#define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg) #define INTELDRM_VERBOSE 0 #if INTELDRM_VERBOSE > 0 diff --git a/sys/dev/pci/drm/i915/i915_trace.h b/sys/dev/pci/drm/i915/i915_trace.h index 6b42b889088..7df9f796aa2 100644 --- a/sys/dev/pci/drm/i915/i915_trace.h +++ b/sys/dev/pci/drm/i915/i915_trace.h @@ -1,4 +1,4 @@ -/* $OpenBSD: i915_trace.h,v 1.1 2013/08/07 19:49:07 kettenis Exp $ */ +/* $OpenBSD: i915_trace.h,v 1.2 2013/09/30 06:47:48 jsg Exp $ */ /* * Copyright (c) 2013 Mark Kettenis <kettenis@openbsd.org> * @@ -40,3 +40,8 @@ static inline void trace_i915_gem_object_unbind(struct drm_i915_gem_object *obj) { } + +static inline void +trace_i915_reg_rw(bool write, u32 reg, u64 val, int len) +{ +} |