Merge tag 'drm-intel-next-fixes-2015-10-22' of git://anongit.freedesktop.org/drm-intel into drm-next

Bunch of -fixes for 4.4. Well not just, I've left the mmio/register work
from Ville in here since it's low-risk but lots of churn all over.

* tag 'drm-intel-next-fixes-2015-10-22' of git://anongit.freedesktop.org/drm-intel: (23 commits)
  drm/i915: Use round to closest when computing the CEA 1.001 pixel clocks
  drm/i915: Kill the leftover RMW from ivb_sprite_disable()
  drm/i915: restore ggtt double-bind avoidance
  drm/i915/skl: Enable pipe gamma for sprite planes.
  drm/i915/skl+: Enable pipe CSC on cursor planes. (v2)
  MAINTAINERS: add link to the Intel Graphics for Linux web site
  drm/i915: Move skl/bxt gt specific workarounds to ring init
  drm/i915: Drop i915_gem_obj_is_pinned() from set-cache-level
  drm/i915: revert a few more watermark commits
  drm/i915: Remove dev_priv argument from NEEDS_FORCE_WAKE
  drm/i915: Clean up LVDS register handling
  drm/i915: Throw out some useless variables
  drm/i915: Parametrize and fix SWF registers
  drm/i915: s/PIPE_FRMCOUNT_GM45/PIPE_FRMCOUNT_G4X/ etc.
  drm/i915: Turn GEN5_ASSERT_IIR_IS_ZERO() into a function
  drm/i915: Fix a few bad hex numbers in register defines
  drm/i915: Protect register macro arguments
  drm/i915: Include gpio_mmio_base in GMBUS reg defines
  drm/i915: Parametrize HSW video DIP data registers
  drm/i915: Eliminate weird parameter inversion from BXT PPS registers
  ...
This commit is contained in:
Dave Airlie 2015-10-30 09:45:33 +10:00
commit 974e59ba0b
25 changed files with 791 additions and 638 deletions

View File

@ -3584,6 +3584,7 @@ M: Daniel Vetter <daniel.vetter@intel.com>
M: Jani Nikula <jani.nikula@linux.intel.com> M: Jani Nikula <jani.nikula@linux.intel.com>
L: intel-gfx@lists.freedesktop.org L: intel-gfx@lists.freedesktop.org
L: dri-devel@lists.freedesktop.org L: dri-devel@lists.freedesktop.org
W: https://01.org/linuxgraphics/
Q: http://patchwork.freedesktop.org/project/intel-gfx/ Q: http://patchwork.freedesktop.org/project/intel-gfx/
T: git git://anongit.freedesktop.org/drm-intel T: git git://anongit.freedesktop.org/drm-intel
S: Supported S: Supported

View File

@ -1850,7 +1850,7 @@ static int i915_opregion(struct seq_file *m, void *unused)
goto out; goto out;
if (opregion->header) { if (opregion->header) {
memcpy_fromio(data, opregion->header, OPREGION_SIZE); memcpy(data, opregion->header, OPREGION_SIZE);
seq_write(m, data, OPREGION_SIZE); seq_write(m, data, OPREGION_SIZE);
} }

View File

@ -450,14 +450,14 @@ struct opregion_swsci;
struct opregion_asle; struct opregion_asle;
struct intel_opregion { struct intel_opregion {
struct opregion_header __iomem *header; struct opregion_header *header;
struct opregion_acpi __iomem *acpi; struct opregion_acpi *acpi;
struct opregion_swsci __iomem *swsci; struct opregion_swsci *swsci;
u32 swsci_gbda_sub_functions; u32 swsci_gbda_sub_functions;
u32 swsci_sbcb_sub_functions; u32 swsci_sbcb_sub_functions;
struct opregion_asle __iomem *asle; struct opregion_asle *asle;
void __iomem *vbt; void *vbt;
u32 __iomem *lid_state; u32 *lid_state;
struct work_struct asle_work; struct work_struct asle_work;
}; };
#define OPREGION_SIZE (8*1024) #define OPREGION_SIZE (8*1024)
@ -628,6 +628,10 @@ struct drm_i915_display_funcs {
struct dpll *match_clock, struct dpll *match_clock,
struct dpll *best_clock); struct dpll *best_clock);
void (*update_wm)(struct drm_crtc *crtc); void (*update_wm)(struct drm_crtc *crtc);
void (*update_sprite_wm)(struct drm_plane *plane,
struct drm_crtc *crtc,
uint32_t sprite_width, uint32_t sprite_height,
int pixel_size, bool enable, bool scaled);
int (*modeset_calc_cdclk)(struct drm_atomic_state *state); int (*modeset_calc_cdclk)(struct drm_atomic_state *state);
void (*modeset_commit_cdclk)(struct drm_atomic_state *state); void (*modeset_commit_cdclk)(struct drm_atomic_state *state);
/* Returns the active state of the crtc, and if the crtc is active, /* Returns the active state of the crtc, and if the crtc is active,
@ -1031,7 +1035,7 @@ struct i915_suspend_saved_registers {
u32 saveMI_ARB_STATE; u32 saveMI_ARB_STATE;
u32 saveSWF0[16]; u32 saveSWF0[16];
u32 saveSWF1[16]; u32 saveSWF1[16];
u32 saveSWF2[3]; u32 saveSWF3[3];
uint64_t saveFENCE[I915_MAX_NUM_FENCES]; uint64_t saveFENCE[I915_MAX_NUM_FENCES];
u32 savePCH_PORT_HOTPLUG; u32 savePCH_PORT_HOTPLUG;
u16 saveGCDGMBUS; u16 saveGCDGMBUS;

View File

@ -3657,53 +3657,106 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
return 0; return 0;
} }
/**
* Changes the cache-level of an object across all VMA.
*
* After this function returns, the object will be in the new cache-level
* across all GTT and the contents of the backing storage will be coherent,
* with respect to the new cache-level. In order to keep the backing storage
* coherent for all users, we only allow a single cache level to be set
* globally on the object and prevent it from being changed whilst the
* hardware is reading from the object. That is if the object is currently
* on the scanout it will be set to uncached (or equivalent display
* cache coherency) and all non-MOCS GPU access will also be uncached so
* that all direct access to the scanout remains coherent.
*/
int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
enum i915_cache_level cache_level) enum i915_cache_level cache_level)
{ {
struct drm_device *dev = obj->base.dev; struct drm_device *dev = obj->base.dev;
struct i915_vma *vma, *next; struct i915_vma *vma, *next;
bool bound = false;
int ret = 0; int ret = 0;
if (obj->cache_level == cache_level) if (obj->cache_level == cache_level)
goto out; goto out;
if (i915_gem_obj_is_pinned(obj)) { /* Inspect the list of currently bound VMA and unbind any that would
DRM_DEBUG("can not change the cache level of pinned objects\n"); * be invalid given the new cache-level. This is principally to
return -EBUSY; * catch the issue of the CS prefetch crossing page boundaries and
} * reading an invalid PTE on older architectures.
*/
list_for_each_entry_safe(vma, next, &obj->vma_list, vma_link) { list_for_each_entry_safe(vma, next, &obj->vma_list, vma_link) {
if (!drm_mm_node_allocated(&vma->node))
continue;
if (vma->pin_count) {
DRM_DEBUG("can not change the cache level of pinned objects\n");
return -EBUSY;
}
if (!i915_gem_valid_gtt_space(vma, cache_level)) { if (!i915_gem_valid_gtt_space(vma, cache_level)) {
ret = i915_vma_unbind(vma); ret = i915_vma_unbind(vma);
if (ret) if (ret)
return ret; return ret;
} } else
bound = true;
} }
if (i915_gem_obj_bound_any(obj)) { /* We can reuse the existing drm_mm nodes but need to change the
* cache-level on the PTE. We could simply unbind them all and
* rebind with the correct cache-level on next use. However since
* we already have a valid slot, dma mapping, pages etc, we may as
* rewrite the PTE in the belief that doing so tramples upon less
* state and so involves less work.
*/
if (bound) {
/* Before we change the PTE, the GPU must not be accessing it.
* If we wait upon the object, we know that all the bound
* VMA are no longer active.
*/
ret = i915_gem_object_wait_rendering(obj, false); ret = i915_gem_object_wait_rendering(obj, false);
if (ret) if (ret)
return ret; return ret;
i915_gem_object_finish_gtt(obj); if (!HAS_LLC(dev) && cache_level != I915_CACHE_NONE) {
/* Access to snoopable pages through the GTT is
* incoherent and on some machines causes a hard
* lockup. Relinquish the CPU mmaping to force
* userspace to refault in the pages and we can
* then double check if the GTT mapping is still
* valid for that pointer access.
*/
i915_gem_release_mmap(obj);
/* Before SandyBridge, you could not use tiling or fence /* As we no longer need a fence for GTT access,
* registers with snooped memory, so relinquish any fences * we can relinquish it now (and so prevent having
* currently pointing to our region in the aperture. * to steal a fence from someone else on the next
*/ * fence request). Note GPU activity would have
if (INTEL_INFO(dev)->gen < 6) { * dropped the fence as all snoopable access is
* supposed to be linear.
*/
ret = i915_gem_object_put_fence(obj); ret = i915_gem_object_put_fence(obj);
if (ret) if (ret)
return ret; return ret;
} else {
/* We either have incoherent backing store and
* so no GTT access or the architecture is fully
* coherent. In such cases, existing GTT mmaps
* ignore the cache bit in the PTE and we can
* rewrite it without confusing the GPU or having
* to force userspace to fault back in its mmaps.
*/
} }
list_for_each_entry(vma, &obj->vma_list, vma_link) list_for_each_entry(vma, &obj->vma_list, vma_link) {
if (drm_mm_node_allocated(&vma->node)) { if (!drm_mm_node_allocated(&vma->node))
ret = i915_vma_bind(vma, cache_level, continue;
PIN_UPDATE);
if (ret) ret = i915_vma_bind(vma, cache_level, PIN_UPDATE);
return ret; if (ret)
} return ret;
}
} }
list_for_each_entry(vma, &obj->vma_list, vma_link) list_for_each_entry(vma, &obj->vma_list, vma_link)
@ -3711,6 +3764,10 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
obj->cache_level = cache_level; obj->cache_level = cache_level;
out: out:
/* Flush the dirty CPU caches to the backing storage so that the
* object is now coherent at its new cache level (with respect
* to the access domain).
*/
if (obj->cache_dirty && if (obj->cache_dirty &&
obj->base.write_domain != I915_GEM_DOMAIN_CPU && obj->base.write_domain != I915_GEM_DOMAIN_CPU &&
cpu_write_needs_clflush(obj)) { cpu_write_needs_clflush(obj)) {

View File

@ -2501,6 +2501,36 @@ static void i915_ggtt_clear_range(struct i915_address_space *vm,
static int ggtt_bind_vma(struct i915_vma *vma, static int ggtt_bind_vma(struct i915_vma *vma,
enum i915_cache_level cache_level, enum i915_cache_level cache_level,
u32 flags) u32 flags)
{
struct drm_i915_gem_object *obj = vma->obj;
u32 pte_flags = 0;
int ret;
ret = i915_get_ggtt_vma_pages(vma);
if (ret)
return ret;
/* Currently applicable only to VLV */
if (obj->gt_ro)
pte_flags |= PTE_READ_ONLY;
vma->vm->insert_entries(vma->vm, vma->ggtt_view.pages,
vma->node.start,
cache_level, pte_flags);
/*
* Without aliasing PPGTT there's no difference between
* GLOBAL/LOCAL_BIND, it's all the same ptes. Hence unconditionally
* upgrade to both bound if we bind either to avoid double-binding.
*/
vma->bound |= GLOBAL_BIND | LOCAL_BIND;
return 0;
}
static int aliasing_gtt_bind_vma(struct i915_vma *vma,
enum i915_cache_level cache_level,
u32 flags)
{ {
struct drm_device *dev = vma->vm->dev; struct drm_device *dev = vma->vm->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
@ -2519,23 +2549,13 @@ static int ggtt_bind_vma(struct i915_vma *vma,
pte_flags |= PTE_READ_ONLY; pte_flags |= PTE_READ_ONLY;
if (!dev_priv->mm.aliasing_ppgtt || flags & GLOBAL_BIND) { if (flags & GLOBAL_BIND) {
vma->vm->insert_entries(vma->vm, pages, vma->vm->insert_entries(vma->vm, pages,
vma->node.start, vma->node.start,
cache_level, pte_flags); cache_level, pte_flags);
/* Note the inconsistency here is due to absence of the
* aliasing ppgtt on gen4 and earlier. Though we always
* request PIN_USER for execbuffer (translated to LOCAL_BIND),
* without the appgtt, we cannot honour that request and so
* must substitute it with a global binding. Since we do this
* behind the upper layers back, we need to explicitly set
* the bound flag ourselves.
*/
vma->bound |= GLOBAL_BIND;
} }
if (dev_priv->mm.aliasing_ppgtt && flags & LOCAL_BIND) { if (flags & LOCAL_BIND) {
struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt; struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt;
appgtt->base.insert_entries(&appgtt->base, pages, appgtt->base.insert_entries(&appgtt->base, pages,
vma->node.start, vma->node.start,
@ -2699,6 +2719,8 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
true); true);
dev_priv->mm.aliasing_ppgtt = ppgtt; dev_priv->mm.aliasing_ppgtt = ppgtt;
WARN_ON(dev_priv->gtt.base.bind_vma != ggtt_bind_vma);
dev_priv->gtt.base.bind_vma = aliasing_gtt_bind_vma;
} }
return 0; return 0;

View File

@ -139,27 +139,30 @@ static const u32 hpd_bxt[HPD_NUM_PINS] = {
/* /*
* We should clear IMR at preinstall/uninstall, and just check at postinstall. * We should clear IMR at preinstall/uninstall, and just check at postinstall.
*/ */
#define GEN5_ASSERT_IIR_IS_ZERO(reg) do { \ static void gen5_assert_iir_is_zero(struct drm_i915_private *dev_priv, u32 reg)
u32 val = I915_READ(reg); \ {
if (val) { \ u32 val = I915_READ(reg);
WARN(1, "Interrupt register 0x%x is not zero: 0x%08x\n", \
(reg), val); \ if (val == 0)
I915_WRITE((reg), 0xffffffff); \ return;
POSTING_READ(reg); \
I915_WRITE((reg), 0xffffffff); \ WARN(1, "Interrupt register 0x%x is not zero: 0x%08x\n",
POSTING_READ(reg); \ reg, val);
} \ I915_WRITE(reg, 0xffffffff);
} while (0) POSTING_READ(reg);
I915_WRITE(reg, 0xffffffff);
POSTING_READ(reg);
}
#define GEN8_IRQ_INIT_NDX(type, which, imr_val, ier_val) do { \ #define GEN8_IRQ_INIT_NDX(type, which, imr_val, ier_val) do { \
GEN5_ASSERT_IIR_IS_ZERO(GEN8_##type##_IIR(which)); \ gen5_assert_iir_is_zero(dev_priv, GEN8_##type##_IIR(which)); \
I915_WRITE(GEN8_##type##_IER(which), (ier_val)); \ I915_WRITE(GEN8_##type##_IER(which), (ier_val)); \
I915_WRITE(GEN8_##type##_IMR(which), (imr_val)); \ I915_WRITE(GEN8_##type##_IMR(which), (imr_val)); \
POSTING_READ(GEN8_##type##_IMR(which)); \ POSTING_READ(GEN8_##type##_IMR(which)); \
} while (0) } while (0)
#define GEN5_IRQ_INIT(type, imr_val, ier_val) do { \ #define GEN5_IRQ_INIT(type, imr_val, ier_val) do { \
GEN5_ASSERT_IIR_IS_ZERO(type##IIR); \ gen5_assert_iir_is_zero(dev_priv, type##IIR); \
I915_WRITE(type##IER, (ier_val)); \ I915_WRITE(type##IER, (ier_val)); \
I915_WRITE(type##IMR, (imr_val)); \ I915_WRITE(type##IMR, (imr_val)); \
POSTING_READ(type##IMR); \ POSTING_READ(type##IMR); \
@ -707,12 +710,11 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
return (((high1 << 8) | low) + (pixel >= vbl_start)) & 0xffffff; return (((high1 << 8) | low) + (pixel >= vbl_start)) & 0xffffff;
} }
static u32 gm45_get_vblank_counter(struct drm_device *dev, unsigned int pipe) static u32 g4x_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
int reg = PIPE_FRMCOUNT_GM45(pipe);
return I915_READ(reg); return I915_READ(PIPE_FRMCOUNT_G4X(pipe));
} }
/* raw reads, only for fast reads of display block, no need for forcewake etc. */ /* raw reads, only for fast reads of display block, no need for forcewake etc. */
@ -3365,7 +3367,7 @@ static void ibx_irq_postinstall(struct drm_device *dev)
else else
mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT; mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT;
GEN5_ASSERT_IIR_IS_ZERO(SDEIIR); gen5_assert_iir_is_zero(dev_priv, SDEIIR);
I915_WRITE(SDEIMR, ~mask); I915_WRITE(SDEIMR, ~mask);
} }
@ -4397,7 +4399,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
dev->driver->get_vblank_counter = i8xx_get_vblank_counter; dev->driver->get_vblank_counter = i8xx_get_vblank_counter;
} else if (IS_G4X(dev_priv) || INTEL_INFO(dev_priv)->gen >= 5) { } else if (IS_G4X(dev_priv) || INTEL_INFO(dev_priv)->gen >= 5) {
dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
dev->driver->get_vblank_counter = gm45_get_vblank_counter; dev->driver->get_vblank_counter = g4x_get_vblank_counter;
} else { } else {
dev->driver->get_vblank_counter = i915_get_vblank_counter; dev->driver->get_vblank_counter = i915_get_vblank_counter;
dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */

View File

@ -429,7 +429,7 @@
#define ASYNC_FLIP (1<<22) #define ASYNC_FLIP (1<<22)
#define DISPLAY_PLANE_A (0<<20) #define DISPLAY_PLANE_A (0<<20)
#define DISPLAY_PLANE_B (1<<20) #define DISPLAY_PLANE_B (1<<20)
#define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|(len-2)) #define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|((len)-2))
#define PIPE_CONTROL_FLUSH_L3 (1<<27) #define PIPE_CONTROL_FLUSH_L3 (1<<27)
#define PIPE_CONTROL_GLOBAL_GTT_IVB (1<<24) /* gen7+ */ #define PIPE_CONTROL_GLOBAL_GTT_IVB (1<<24) /* gen7+ */
#define PIPE_CONTROL_MMIO_WRITE (1<<23) #define PIPE_CONTROL_MMIO_WRITE (1<<23)
@ -1255,7 +1255,7 @@ enum skl_disp_power_wells {
#define PORT_PLL_DCO_AMP_OVR_EN_H (1<<27) #define PORT_PLL_DCO_AMP_OVR_EN_H (1<<27)
#define PORT_PLL_DCO_AMP_DEFAULT 15 #define PORT_PLL_DCO_AMP_DEFAULT 15
#define PORT_PLL_DCO_AMP_MASK 0x3c00 #define PORT_PLL_DCO_AMP_MASK 0x3c00
#define PORT_PLL_DCO_AMP(x) (x<<10) #define PORT_PLL_DCO_AMP(x) ((x)<<10)
#define _PORT_PLL_BASE(port) _PORT3(port, _PORT_PLL_0_A, \ #define _PORT_PLL_BASE(port) _PORT3(port, _PORT_PLL_0_A, \
_PORT_PLL_0_B, \ _PORT_PLL_0_B, \
_PORT_PLL_0_C) _PORT_PLL_0_C)
@ -1552,8 +1552,8 @@ enum skl_disp_power_wells {
#define RENDER_HWS_PGA_GEN7 (0x04080) #define RENDER_HWS_PGA_GEN7 (0x04080)
#define RING_FAULT_REG(ring) (0x4094 + 0x100*(ring)->id) #define RING_FAULT_REG(ring) (0x4094 + 0x100*(ring)->id)
#define RING_FAULT_GTTSEL_MASK (1<<11) #define RING_FAULT_GTTSEL_MASK (1<<11)
#define RING_FAULT_SRCID(x) ((x >> 3) & 0xff) #define RING_FAULT_SRCID(x) (((x) >> 3) & 0xff)
#define RING_FAULT_FAULT_TYPE(x) ((x >> 1) & 0x3) #define RING_FAULT_FAULT_TYPE(x) (((x) >> 1) & 0x3)
#define RING_FAULT_VALID (1<<0) #define RING_FAULT_VALID (1<<0)
#define DONE_REG 0x40b0 #define DONE_REG 0x40b0
#define GEN8_PRIVATE_PAT_LO 0x40e0 #define GEN8_PRIVATE_PAT_LO 0x40e0
@ -1641,9 +1641,9 @@ enum skl_disp_power_wells {
#define ERR_INT_PIPE_CRC_DONE_B (1<<5) #define ERR_INT_PIPE_CRC_DONE_B (1<<5)
#define ERR_INT_FIFO_UNDERRUN_B (1<<3) #define ERR_INT_FIFO_UNDERRUN_B (1<<3)
#define ERR_INT_PIPE_CRC_DONE_A (1<<2) #define ERR_INT_PIPE_CRC_DONE_A (1<<2)
#define ERR_INT_PIPE_CRC_DONE(pipe) (1<<(2 + pipe*3)) #define ERR_INT_PIPE_CRC_DONE(pipe) (1<<(2 + (pipe)*3))
#define ERR_INT_FIFO_UNDERRUN_A (1<<0) #define ERR_INT_FIFO_UNDERRUN_A (1<<0)
#define ERR_INT_FIFO_UNDERRUN(pipe) (1<<(pipe*3)) #define ERR_INT_FIFO_UNDERRUN(pipe) (1<<((pipe)*3))
#define GEN8_FAULT_TLB_DATA0 0x04b10 #define GEN8_FAULT_TLB_DATA0 0x04b10
#define GEN8_FAULT_TLB_DATA1 0x04b14 #define GEN8_FAULT_TLB_DATA1 0x04b14
@ -1704,8 +1704,8 @@ enum skl_disp_power_wells {
#define GEN6_WIZ_HASHING_16x4 GEN6_WIZ_HASHING(1, 0) #define GEN6_WIZ_HASHING_16x4 GEN6_WIZ_HASHING(1, 0)
#define GEN6_WIZ_HASHING_MASK GEN6_WIZ_HASHING(1, 1) #define GEN6_WIZ_HASHING_MASK GEN6_WIZ_HASHING(1, 1)
#define GEN6_TD_FOUR_ROW_DISPATCH_DISABLE (1 << 5) #define GEN6_TD_FOUR_ROW_DISPATCH_DISABLE (1 << 5)
#define GEN9_IZ_HASHING_MASK(slice) (0x3 << (slice * 2)) #define GEN9_IZ_HASHING_MASK(slice) (0x3 << ((slice) * 2))
#define GEN9_IZ_HASHING(slice, val) ((val) << (slice * 2)) #define GEN9_IZ_HASHING(slice, val) ((val) << ((slice) * 2))
#define GFX_MODE 0x02520 #define GFX_MODE 0x02520
#define GFX_MODE_GEN7 0x0229c #define GFX_MODE_GEN7 0x0229c
@ -2144,7 +2144,7 @@ enum skl_disp_power_wells {
# define GPIO_DATA_VAL_IN (1 << 12) # define GPIO_DATA_VAL_IN (1 << 12)
# define GPIO_DATA_PULLUP_DISABLE (1 << 13) # define GPIO_DATA_PULLUP_DISABLE (1 << 13)
#define GMBUS0 0x5100 /* clock/port select */ #define GMBUS0 (dev_priv->gpio_mmio_base + 0x5100) /* clock/port select */
#define GMBUS_RATE_100KHZ (0<<8) #define GMBUS_RATE_100KHZ (0<<8)
#define GMBUS_RATE_50KHZ (1<<8) #define GMBUS_RATE_50KHZ (1<<8)
#define GMBUS_RATE_400KHZ (2<<8) /* reserved on Pineview */ #define GMBUS_RATE_400KHZ (2<<8) /* reserved on Pineview */
@ -2163,7 +2163,7 @@ enum skl_disp_power_wells {
#define GMBUS_PIN_2_BXT 2 #define GMBUS_PIN_2_BXT 2
#define GMBUS_PIN_3_BXT 3 #define GMBUS_PIN_3_BXT 3
#define GMBUS_NUM_PINS 7 /* including 0 */ #define GMBUS_NUM_PINS 7 /* including 0 */
#define GMBUS1 0x5104 /* command/status */ #define GMBUS1 (dev_priv->gpio_mmio_base + 0x5104) /* command/status */
#define GMBUS_SW_CLR_INT (1<<31) #define GMBUS_SW_CLR_INT (1<<31)
#define GMBUS_SW_RDY (1<<30) #define GMBUS_SW_RDY (1<<30)
#define GMBUS_ENT (1<<29) /* enable timeout */ #define GMBUS_ENT (1<<29) /* enable timeout */
@ -2177,7 +2177,7 @@ enum skl_disp_power_wells {
#define GMBUS_SLAVE_ADDR_SHIFT 1 #define GMBUS_SLAVE_ADDR_SHIFT 1
#define GMBUS_SLAVE_READ (1<<0) #define GMBUS_SLAVE_READ (1<<0)
#define GMBUS_SLAVE_WRITE (0<<0) #define GMBUS_SLAVE_WRITE (0<<0)
#define GMBUS2 0x5108 /* status */ #define GMBUS2 (dev_priv->gpio_mmio_base + 0x5108) /* status */
#define GMBUS_INUSE (1<<15) #define GMBUS_INUSE (1<<15)
#define GMBUS_HW_WAIT_PHASE (1<<14) #define GMBUS_HW_WAIT_PHASE (1<<14)
#define GMBUS_STALL_TIMEOUT (1<<13) #define GMBUS_STALL_TIMEOUT (1<<13)
@ -2185,14 +2185,14 @@ enum skl_disp_power_wells {
#define GMBUS_HW_RDY (1<<11) #define GMBUS_HW_RDY (1<<11)
#define GMBUS_SATOER (1<<10) #define GMBUS_SATOER (1<<10)
#define GMBUS_ACTIVE (1<<9) #define GMBUS_ACTIVE (1<<9)
#define GMBUS3 0x510c /* data buffer bytes 3-0 */ #define GMBUS3 (dev_priv->gpio_mmio_base + 0x510c) /* data buffer bytes 3-0 */
#define GMBUS4 0x5110 /* interrupt mask (Pineview+) */ #define GMBUS4 (dev_priv->gpio_mmio_base + 0x5110) /* interrupt mask (Pineview+) */
#define GMBUS_SLAVE_TIMEOUT_EN (1<<4) #define GMBUS_SLAVE_TIMEOUT_EN (1<<4)
#define GMBUS_NAK_EN (1<<3) #define GMBUS_NAK_EN (1<<3)
#define GMBUS_IDLE_EN (1<<2) #define GMBUS_IDLE_EN (1<<2)
#define GMBUS_HW_WAIT_EN (1<<1) #define GMBUS_HW_WAIT_EN (1<<1)
#define GMBUS_HW_RDY_EN (1<<0) #define GMBUS_HW_RDY_EN (1<<0)
#define GMBUS5 0x5120 /* byte index */ #define GMBUS5 (dev_priv->gpio_mmio_base + 0x5120) /* byte index */
#define GMBUS_2BYTE_INDEX_EN (1<<31) #define GMBUS_2BYTE_INDEX_EN (1<<31)
/* /*
@ -2866,21 +2866,21 @@ enum skl_disp_power_wells {
* doesn't need saving on GT1 * doesn't need saving on GT1
*/ */
#define CXT_SIZE 0x21a0 #define CXT_SIZE 0x21a0
#define GEN6_CXT_POWER_SIZE(cxt_reg) ((cxt_reg >> 24) & 0x3f) #define GEN6_CXT_POWER_SIZE(cxt_reg) (((cxt_reg) >> 24) & 0x3f)
#define GEN6_CXT_RING_SIZE(cxt_reg) ((cxt_reg >> 18) & 0x3f) #define GEN6_CXT_RING_SIZE(cxt_reg) (((cxt_reg) >> 18) & 0x3f)
#define GEN6_CXT_RENDER_SIZE(cxt_reg) ((cxt_reg >> 12) & 0x3f) #define GEN6_CXT_RENDER_SIZE(cxt_reg) (((cxt_reg) >> 12) & 0x3f)
#define GEN6_CXT_EXTENDED_SIZE(cxt_reg) ((cxt_reg >> 6) & 0x3f) #define GEN6_CXT_EXTENDED_SIZE(cxt_reg) (((cxt_reg) >> 6) & 0x3f)
#define GEN6_CXT_PIPELINE_SIZE(cxt_reg) ((cxt_reg >> 0) & 0x3f) #define GEN6_CXT_PIPELINE_SIZE(cxt_reg) (((cxt_reg) >> 0) & 0x3f)
#define GEN6_CXT_TOTAL_SIZE(cxt_reg) (GEN6_CXT_RING_SIZE(cxt_reg) + \ #define GEN6_CXT_TOTAL_SIZE(cxt_reg) (GEN6_CXT_RING_SIZE(cxt_reg) + \
GEN6_CXT_EXTENDED_SIZE(cxt_reg) + \ GEN6_CXT_EXTENDED_SIZE(cxt_reg) + \
GEN6_CXT_PIPELINE_SIZE(cxt_reg)) GEN6_CXT_PIPELINE_SIZE(cxt_reg))
#define GEN7_CXT_SIZE 0x21a8 #define GEN7_CXT_SIZE 0x21a8
#define GEN7_CXT_POWER_SIZE(ctx_reg) ((ctx_reg >> 25) & 0x7f) #define GEN7_CXT_POWER_SIZE(ctx_reg) (((ctx_reg) >> 25) & 0x7f)
#define GEN7_CXT_RING_SIZE(ctx_reg) ((ctx_reg >> 22) & 0x7) #define GEN7_CXT_RING_SIZE(ctx_reg) (((ctx_reg) >> 22) & 0x7)
#define GEN7_CXT_RENDER_SIZE(ctx_reg) ((ctx_reg >> 16) & 0x3f) #define GEN7_CXT_RENDER_SIZE(ctx_reg) (((ctx_reg) >> 16) & 0x3f)
#define GEN7_CXT_EXTENDED_SIZE(ctx_reg) ((ctx_reg >> 9) & 0x7f) #define GEN7_CXT_EXTENDED_SIZE(ctx_reg) (((ctx_reg) >> 9) & 0x7f)
#define GEN7_CXT_GT1_SIZE(ctx_reg) ((ctx_reg >> 6) & 0x7) #define GEN7_CXT_GT1_SIZE(ctx_reg) (((ctx_reg) >> 6) & 0x7)
#define GEN7_CXT_VFSTATE_SIZE(ctx_reg) ((ctx_reg >> 0) & 0x3f) #define GEN7_CXT_VFSTATE_SIZE(ctx_reg) (((ctx_reg) >> 0) & 0x3f)
#define GEN7_CXT_TOTAL_SIZE(ctx_reg) (GEN7_CXT_EXTENDED_SIZE(ctx_reg) + \ #define GEN7_CXT_TOTAL_SIZE(ctx_reg) (GEN7_CXT_EXTENDED_SIZE(ctx_reg) + \
GEN7_CXT_VFSTATE_SIZE(ctx_reg)) GEN7_CXT_VFSTATE_SIZE(ctx_reg))
/* Haswell does have the CXT_SIZE register however it does not appear to be /* Haswell does have the CXT_SIZE register however it does not appear to be
@ -4284,7 +4284,7 @@ enum skl_disp_power_wells {
#define DP_AUX_CH_CTL_PSR_DATA_AUX_REG_SKL (1 << 14) #define DP_AUX_CH_CTL_PSR_DATA_AUX_REG_SKL (1 << 14)
#define DP_AUX_CH_CTL_FS_DATA_AUX_REG_SKL (1 << 13) #define DP_AUX_CH_CTL_FS_DATA_AUX_REG_SKL (1 << 13)
#define DP_AUX_CH_CTL_GTC_DATA_AUX_REG_SKL (1 << 12) #define DP_AUX_CH_CTL_GTC_DATA_AUX_REG_SKL (1 << 12)
#define DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL_MASK (1f << 5) #define DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL_MASK (0x1f << 5)
#define DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(c) (((c) - 1) << 5) #define DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(c) (((c) - 1) << 5)
#define DP_AUX_CH_CTL_SYNC_PULSE_SKL(c) ((c) - 1) #define DP_AUX_CH_CTL_SYNC_PULSE_SKL(c) ((c) - 1)
@ -4846,10 +4846,10 @@ enum skl_disp_power_wells {
#define PIPE_PIXEL_MASK 0x00ffffff #define PIPE_PIXEL_MASK 0x00ffffff
#define PIPE_PIXEL_SHIFT 0 #define PIPE_PIXEL_SHIFT 0
/* GM45+ just has to be different */ /* GM45+ just has to be different */
#define _PIPEA_FRMCOUNT_GM45 0x70040 #define _PIPEA_FRMCOUNT_G4X 0x70040
#define _PIPEA_FLIPCOUNT_GM45 0x70044 #define _PIPEA_FLIPCOUNT_G4X 0x70044
#define PIPE_FRMCOUNT_GM45(pipe) _PIPE2(pipe, _PIPEA_FRMCOUNT_GM45) #define PIPE_FRMCOUNT_G4X(pipe) _PIPE2(pipe, _PIPEA_FRMCOUNT_G4X)
#define PIPE_FLIPCOUNT_GM45(pipe) _PIPE2(pipe, _PIPEA_FLIPCOUNT_GM45) #define PIPE_FLIPCOUNT_G4X(pipe) _PIPE2(pipe, _PIPEA_FLIPCOUNT_G4X)
/* Cursor A & B regs */ /* Cursor A & B regs */
#define _CURACNTR 0x70080 #define _CURACNTR 0x70080
@ -4991,20 +4991,20 @@ enum skl_disp_power_wells {
#define I915_LO_DISPBASE(val) (val & ~DISP_BASEADDR_MASK) #define I915_LO_DISPBASE(val) (val & ~DISP_BASEADDR_MASK)
#define I915_HI_DISPBASE(val) (val & DISP_BASEADDR_MASK) #define I915_HI_DISPBASE(val) (val & DISP_BASEADDR_MASK)
/* VBIOS flags */ /*
#define SWF00 (dev_priv->info.display_mmio_offset + 0x71410) * VBIOS flags
#define SWF01 (dev_priv->info.display_mmio_offset + 0x71414) * gen2:
#define SWF02 (dev_priv->info.display_mmio_offset + 0x71418) * [00:06] alm,mgm
#define SWF03 (dev_priv->info.display_mmio_offset + 0x7141c) * [10:16] all
#define SWF04 (dev_priv->info.display_mmio_offset + 0x71420) * [30:32] alm,mgm
#define SWF05 (dev_priv->info.display_mmio_offset + 0x71424) * gen3+:
#define SWF06 (dev_priv->info.display_mmio_offset + 0x71428) * [00:0f] all
#define SWF10 (dev_priv->info.display_mmio_offset + 0x70410) * [10:1f] all
#define SWF11 (dev_priv->info.display_mmio_offset + 0x70414) * [30:32] all
#define SWF14 (dev_priv->info.display_mmio_offset + 0x71420) */
#define SWF30 (dev_priv->info.display_mmio_offset + 0x72414) #define SWF0(i) (dev_priv->info.display_mmio_offset + 0x70410 + (i) * 4)
#define SWF31 (dev_priv->info.display_mmio_offset + 0x72418) #define SWF1(i) (dev_priv->info.display_mmio_offset + 0x71410 + (i) * 4)
#define SWF32 (dev_priv->info.display_mmio_offset + 0x7241c) #define SWF3(i) (dev_priv->info.display_mmio_offset + 0x72414 + (i) * 4)
/* Pipe B */ /* Pipe B */
#define _PIPEBDSL (dev_priv->info.display_mmio_offset + 0x71000) #define _PIPEBDSL (dev_priv->info.display_mmio_offset + 0x71000)
@ -5012,8 +5012,8 @@ enum skl_disp_power_wells {
#define _PIPEBSTAT (dev_priv->info.display_mmio_offset + 0x71024) #define _PIPEBSTAT (dev_priv->info.display_mmio_offset + 0x71024)
#define _PIPEBFRAMEHIGH 0x71040 #define _PIPEBFRAMEHIGH 0x71040
#define _PIPEBFRAMEPIXEL 0x71044 #define _PIPEBFRAMEPIXEL 0x71044
#define _PIPEB_FRMCOUNT_GM45 (dev_priv->info.display_mmio_offset + 0x71040) #define _PIPEB_FRMCOUNT_G4X (dev_priv->info.display_mmio_offset + 0x71040)
#define _PIPEB_FLIPCOUNT_GM45 (dev_priv->info.display_mmio_offset + 0x71044) #define _PIPEB_FLIPCOUNT_G4X (dev_priv->info.display_mmio_offset + 0x71044)
/* Display B control */ /* Display B control */
@ -5223,18 +5223,18 @@ enum skl_disp_power_wells {
#define _SPBCONSTALPHA (VLV_DISPLAY_BASE + 0x722a8) #define _SPBCONSTALPHA (VLV_DISPLAY_BASE + 0x722a8)
#define _SPBGAMC (VLV_DISPLAY_BASE + 0x722f4) #define _SPBGAMC (VLV_DISPLAY_BASE + 0x722f4)
#define SPCNTR(pipe, plane) _PIPE(pipe * 2 + plane, _SPACNTR, _SPBCNTR) #define SPCNTR(pipe, plane) _PIPE((pipe) * 2 + (plane), _SPACNTR, _SPBCNTR)
#define SPLINOFF(pipe, plane) _PIPE(pipe * 2 + plane, _SPALINOFF, _SPBLINOFF) #define SPLINOFF(pipe, plane) _PIPE((pipe) * 2 + (plane), _SPALINOFF, _SPBLINOFF)
#define SPSTRIDE(pipe, plane) _PIPE(pipe * 2 + plane, _SPASTRIDE, _SPBSTRIDE) #define SPSTRIDE(pipe, plane) _PIPE((pipe) * 2 + (plane), _SPASTRIDE, _SPBSTRIDE)
#define SPPOS(pipe, plane) _PIPE(pipe * 2 + plane, _SPAPOS, _SPBPOS) #define SPPOS(pipe, plane) _PIPE((pipe) * 2 + (plane), _SPAPOS, _SPBPOS)
#define SPSIZE(pipe, plane) _PIPE(pipe * 2 + plane, _SPASIZE, _SPBSIZE) #define SPSIZE(pipe, plane) _PIPE((pipe) * 2 + (plane), _SPASIZE, _SPBSIZE)
#define SPKEYMINVAL(pipe, plane) _PIPE(pipe * 2 + plane, _SPAKEYMINVAL, _SPBKEYMINVAL) #define SPKEYMINVAL(pipe, plane) _PIPE((pipe) * 2 + (plane), _SPAKEYMINVAL, _SPBKEYMINVAL)
#define SPKEYMSK(pipe, plane) _PIPE(pipe * 2 + plane, _SPAKEYMSK, _SPBKEYMSK) #define SPKEYMSK(pipe, plane) _PIPE((pipe) * 2 + (plane), _SPAKEYMSK, _SPBKEYMSK)
#define SPSURF(pipe, plane) _PIPE(pipe * 2 + plane, _SPASURF, _SPBSURF) #define SPSURF(pipe, plane) _PIPE((pipe) * 2 + (plane), _SPASURF, _SPBSURF)
#define SPKEYMAXVAL(pipe, plane) _PIPE(pipe * 2 + plane, _SPAKEYMAXVAL, _SPBKEYMAXVAL) #define SPKEYMAXVAL(pipe, plane) _PIPE((pipe) * 2 + (plane), _SPAKEYMAXVAL, _SPBKEYMAXVAL)
#define SPTILEOFF(pipe, plane) _PIPE(pipe * 2 + plane, _SPATILEOFF, _SPBTILEOFF) #define SPTILEOFF(pipe, plane) _PIPE((pipe) * 2 + (plane), _SPATILEOFF, _SPBTILEOFF)
#define SPCONSTALPHA(pipe, plane) _PIPE(pipe * 2 + plane, _SPACONSTALPHA, _SPBCONSTALPHA) #define SPCONSTALPHA(pipe, plane) _PIPE((pipe) * 2 + (plane), _SPACONSTALPHA, _SPBCONSTALPHA)
#define SPGAMC(pipe, plane) _PIPE(pipe * 2 + plane, _SPAGAMC, _SPBGAMC) #define SPGAMC(pipe, plane) _PIPE((pipe) * 2 + (plane), _SPAGAMC, _SPBGAMC)
/* /*
* CHV pipe B sprite CSC * CHV pipe B sprite CSC
@ -5580,7 +5580,7 @@ enum skl_disp_power_wells {
#define PS_SCALER_MODE_DYN (0 << 28) #define PS_SCALER_MODE_DYN (0 << 28)
#define PS_SCALER_MODE_HQ (1 << 28) #define PS_SCALER_MODE_HQ (1 << 28)
#define PS_PLANE_SEL_MASK (7 << 25) #define PS_PLANE_SEL_MASK (7 << 25)
#define PS_PLANE_SEL(plane) ((plane + 1) << 25) #define PS_PLANE_SEL(plane) (((plane) + 1) << 25)
#define PS_FILTER_MASK (3 << 23) #define PS_FILTER_MASK (3 << 23)
#define PS_FILTER_MEDIUM (0 << 23) #define PS_FILTER_MEDIUM (0 << 23)
#define PS_FILTER_EDGE_ENHANCE (2 << 23) #define PS_FILTER_EDGE_ENHANCE (2 << 23)
@ -5745,7 +5745,7 @@ enum skl_disp_power_wells {
#define DE_PLANEA_FLIP_DONE_IVB (1<<3) #define DE_PLANEA_FLIP_DONE_IVB (1<<3)
#define DE_PLANE_FLIP_DONE_IVB(plane) (1<< (3 + 5*(plane))) #define DE_PLANE_FLIP_DONE_IVB(plane) (1<< (3 + 5*(plane)))
#define DE_PIPEA_VBLANK_IVB (1<<0) #define DE_PIPEA_VBLANK_IVB (1<<0)
#define DE_PIPE_VBLANK_IVB(pipe) (1 << (pipe * 5)) #define DE_PIPE_VBLANK_IVB(pipe) (1 << ((pipe) * 5))
#define VLV_MASTER_IER 0x4400c /* Gunit master IER */ #define VLV_MASTER_IER 0x4400c /* Gunit master IER */
#define MASTER_INTERRUPT_ENABLE (1<<31) #define MASTER_INTERRUPT_ENABLE (1<<31)
@ -5769,7 +5769,7 @@ enum skl_disp_power_wells {
#define GEN8_DE_PIPE_C_IRQ (1<<18) #define GEN8_DE_PIPE_C_IRQ (1<<18)
#define GEN8_DE_PIPE_B_IRQ (1<<17) #define GEN8_DE_PIPE_B_IRQ (1<<17)
#define GEN8_DE_PIPE_A_IRQ (1<<16) #define GEN8_DE_PIPE_A_IRQ (1<<16)
#define GEN8_DE_PIPE_IRQ(pipe) (1<<(16+pipe)) #define GEN8_DE_PIPE_IRQ(pipe) (1<<(16+(pipe)))
#define GEN8_GT_VECS_IRQ (1<<6) #define GEN8_GT_VECS_IRQ (1<<6)
#define GEN8_GT_PM_IRQ (1<<4) #define GEN8_GT_PM_IRQ (1<<4)
#define GEN8_GT_VCS2_IRQ (1<<3) #define GEN8_GT_VCS2_IRQ (1<<3)
@ -5813,7 +5813,7 @@ enum skl_disp_power_wells {
#define GEN9_PIPE_PLANE3_FLIP_DONE (1 << 5) #define GEN9_PIPE_PLANE3_FLIP_DONE (1 << 5)
#define GEN9_PIPE_PLANE2_FLIP_DONE (1 << 4) #define GEN9_PIPE_PLANE2_FLIP_DONE (1 << 4)
#define GEN9_PIPE_PLANE1_FLIP_DONE (1 << 3) #define GEN9_PIPE_PLANE1_FLIP_DONE (1 << 3)
#define GEN9_PIPE_PLANE_FLIP_DONE(p) (1 << (3 + p)) #define GEN9_PIPE_PLANE_FLIP_DONE(p) (1 << (3 + (p)))
#define GEN8_DE_PIPE_IRQ_FAULT_ERRORS \ #define GEN8_DE_PIPE_IRQ_FAULT_ERRORS \
(GEN8_PIPE_CURSOR_FAULT | \ (GEN8_PIPE_CURSOR_FAULT | \
GEN8_PIPE_SPRITE_FAULT | \ GEN8_PIPE_SPRITE_FAULT | \
@ -6072,7 +6072,7 @@ enum skl_disp_power_wells {
#define SERR_INT_TRANS_C_FIFO_UNDERRUN (1<<6) #define SERR_INT_TRANS_C_FIFO_UNDERRUN (1<<6)
#define SERR_INT_TRANS_B_FIFO_UNDERRUN (1<<3) #define SERR_INT_TRANS_B_FIFO_UNDERRUN (1<<3)
#define SERR_INT_TRANS_A_FIFO_UNDERRUN (1<<0) #define SERR_INT_TRANS_A_FIFO_UNDERRUN (1<<0)
#define SERR_INT_TRANS_FIFO_UNDERRUN(pipe) (1<<(pipe*3)) #define SERR_INT_TRANS_FIFO_UNDERRUN(pipe) (1<<((pipe)*3))
/* digital port hotplug */ /* digital port hotplug */
#define PCH_PORT_HOTPLUG 0xc4030 /* SHOTPLUG_CTL */ #define PCH_PORT_HOTPLUG 0xc4030 /* SHOTPLUG_CTL */
@ -6183,9 +6183,9 @@ enum skl_disp_power_wells {
#define PCH_SSC4_AUX_PARMS 0xc6214 #define PCH_SSC4_AUX_PARMS 0xc6214
#define PCH_DPLL_SEL 0xc7000 #define PCH_DPLL_SEL 0xc7000
#define TRANS_DPLLB_SEL(pipe) (1 << (pipe * 4)) #define TRANS_DPLLB_SEL(pipe) (1 << ((pipe) * 4))
#define TRANS_DPLLA_SEL(pipe) 0 #define TRANS_DPLLA_SEL(pipe) 0
#define TRANS_DPLL_ENABLE(pipe) (1 << (pipe * 4 + 3)) #define TRANS_DPLL_ENABLE(pipe) (1 << ((pipe) * 4 + 3))
/* transcoder */ /* transcoder */
@ -6286,16 +6286,16 @@ enum skl_disp_power_wells {
#define HSW_TVIDEO_DIP_CTL(trans) \ #define HSW_TVIDEO_DIP_CTL(trans) \
_TRANSCODER2(trans, HSW_VIDEO_DIP_CTL_A) _TRANSCODER2(trans, HSW_VIDEO_DIP_CTL_A)
#define HSW_TVIDEO_DIP_AVI_DATA(trans) \ #define HSW_TVIDEO_DIP_AVI_DATA(trans, i) \
_TRANSCODER2(trans, HSW_VIDEO_DIP_AVI_DATA_A) (_TRANSCODER2(trans, HSW_VIDEO_DIP_AVI_DATA_A) + (i) * 4)
#define HSW_TVIDEO_DIP_VS_DATA(trans) \ #define HSW_TVIDEO_DIP_VS_DATA(trans, i) \
_TRANSCODER2(trans, HSW_VIDEO_DIP_VS_DATA_A) (_TRANSCODER2(trans, HSW_VIDEO_DIP_VS_DATA_A) + (i) * 4)
#define HSW_TVIDEO_DIP_SPD_DATA(trans) \ #define HSW_TVIDEO_DIP_SPD_DATA(trans, i) \
_TRANSCODER2(trans, HSW_VIDEO_DIP_SPD_DATA_A) (_TRANSCODER2(trans, HSW_VIDEO_DIP_SPD_DATA_A) + (i) * 4)
#define HSW_TVIDEO_DIP_GCP(trans) \ #define HSW_TVIDEO_DIP_GCP(trans) \
_TRANSCODER2(trans, HSW_VIDEO_DIP_GCP_A) _TRANSCODER2(trans, HSW_VIDEO_DIP_GCP_A)
#define HSW_TVIDEO_DIP_VSC_DATA(trans) \ #define HSW_TVIDEO_DIP_VSC_DATA(trans, i) \
_TRANSCODER2(trans, HSW_VIDEO_DIP_VSC_DATA_A) (_TRANSCODER2(trans, HSW_VIDEO_DIP_VSC_DATA_A) + (i) * 4)
#define HSW_STEREO_3D_CTL_A 0x70020 #define HSW_STEREO_3D_CTL_A 0x70020
#define S3D_ENABLE (1<<31) #define S3D_ENABLE (1<<31)
@ -6587,10 +6587,10 @@ enum skl_disp_power_wells {
#define _BXT_PP_ON_DELAYS2 0xc7308 #define _BXT_PP_ON_DELAYS2 0xc7308
#define _BXT_PP_OFF_DELAYS2 0xc730c #define _BXT_PP_OFF_DELAYS2 0xc730c
#define BXT_PP_STATUS(n) ((!n) ? PCH_PP_STATUS : _BXT_PP_STATUS2) #define BXT_PP_STATUS(n) _PIPE(n, PCH_PP_STATUS, _BXT_PP_STATUS2)
#define BXT_PP_CONTROL(n) ((!n) ? PCH_PP_CONTROL : _BXT_PP_CONTROL2) #define BXT_PP_CONTROL(n) _PIPE(n, PCH_PP_CONTROL, _BXT_PP_CONTROL2)
#define BXT_PP_ON_DELAYS(n) ((!n) ? PCH_PP_ON_DELAYS : _BXT_PP_ON_DELAYS2) #define BXT_PP_ON_DELAYS(n) _PIPE(n, PCH_PP_ON_DELAYS, _BXT_PP_ON_DELAYS2)
#define BXT_PP_OFF_DELAYS(n) ((!n) ? PCH_PP_OFF_DELAYS : _BXT_PP_OFF_DELAYS2) #define BXT_PP_OFF_DELAYS(n) _PIPE(n, PCH_PP_OFF_DELAYS, _BXT_PP_OFF_DELAYS2)
#define PCH_DP_B 0xe4100 #define PCH_DP_B 0xe4100
#define PCH_DPB_AUX_CH_CTL 0xe4110 #define PCH_DPB_AUX_CH_CTL 0xe4110
@ -7348,7 +7348,7 @@ enum skl_disp_power_wells {
#define TRANS_CLK_SEL(tran) _TRANSCODER(tran, TRANS_CLK_SEL_A, TRANS_CLK_SEL_B) #define TRANS_CLK_SEL(tran) _TRANSCODER(tran, TRANS_CLK_SEL_A, TRANS_CLK_SEL_B)
/* For each transcoder, we need to select the corresponding port clock */ /* For each transcoder, we need to select the corresponding port clock */
#define TRANS_CLK_SEL_DISABLED (0x0<<29) #define TRANS_CLK_SEL_DISABLED (0x0<<29)
#define TRANS_CLK_SEL_PORT(x) ((x+1)<<29) #define TRANS_CLK_SEL_PORT(x) (((x)+1)<<29)
#define TRANSA_MSA_MISC 0x60410 #define TRANSA_MSA_MISC 0x60410
#define TRANSB_MSA_MISC 0x61410 #define TRANSB_MSA_MISC 0x61410
@ -7421,10 +7421,10 @@ enum skl_disp_power_wells {
/* DPLL control2 */ /* DPLL control2 */
#define DPLL_CTRL2 0x6C05C #define DPLL_CTRL2 0x6C05C
#define DPLL_CTRL2_DDI_CLK_OFF(port) (1<<(port+15)) #define DPLL_CTRL2_DDI_CLK_OFF(port) (1<<((port)+15))
#define DPLL_CTRL2_DDI_CLK_SEL_MASK(port) (3<<((port)*3+1)) #define DPLL_CTRL2_DDI_CLK_SEL_MASK(port) (3<<((port)*3+1))
#define DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port) ((port)*3+1) #define DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port) ((port)*3+1)
#define DPLL_CTRL2_DDI_CLK_SEL(clk, port) (clk<<((port)*3+1)) #define DPLL_CTRL2_DDI_CLK_SEL(clk, port) ((clk)<<((port)*3+1))
#define DPLL_CTRL2_DDI_SEL_OVERRIDE(port) (1<<((port)*3)) #define DPLL_CTRL2_DDI_SEL_OVERRIDE(port) (1<<((port)*3))
/* DPLL Status */ /* DPLL Status */
@ -7437,23 +7437,23 @@ enum skl_disp_power_wells {
#define DPLL3_CFGCR1 0x6C050 #define DPLL3_CFGCR1 0x6C050
#define DPLL_CFGCR1_FREQ_ENABLE (1<<31) #define DPLL_CFGCR1_FREQ_ENABLE (1<<31)
#define DPLL_CFGCR1_DCO_FRACTION_MASK (0x7fff<<9) #define DPLL_CFGCR1_DCO_FRACTION_MASK (0x7fff<<9)
#define DPLL_CFGCR1_DCO_FRACTION(x) (x<<9) #define DPLL_CFGCR1_DCO_FRACTION(x) ((x)<<9)
#define DPLL_CFGCR1_DCO_INTEGER_MASK (0x1ff) #define DPLL_CFGCR1_DCO_INTEGER_MASK (0x1ff)
#define DPLL1_CFGCR2 0x6C044 #define DPLL1_CFGCR2 0x6C044
#define DPLL2_CFGCR2 0x6C04C #define DPLL2_CFGCR2 0x6C04C
#define DPLL3_CFGCR2 0x6C054 #define DPLL3_CFGCR2 0x6C054
#define DPLL_CFGCR2_QDIV_RATIO_MASK (0xff<<8) #define DPLL_CFGCR2_QDIV_RATIO_MASK (0xff<<8)
#define DPLL_CFGCR2_QDIV_RATIO(x) (x<<8) #define DPLL_CFGCR2_QDIV_RATIO(x) ((x)<<8)
#define DPLL_CFGCR2_QDIV_MODE(x) (x<<7) #define DPLL_CFGCR2_QDIV_MODE(x) ((x)<<7)
#define DPLL_CFGCR2_KDIV_MASK (3<<5) #define DPLL_CFGCR2_KDIV_MASK (3<<5)
#define DPLL_CFGCR2_KDIV(x) (x<<5) #define DPLL_CFGCR2_KDIV(x) ((x)<<5)
#define DPLL_CFGCR2_KDIV_5 (0<<5) #define DPLL_CFGCR2_KDIV_5 (0<<5)
#define DPLL_CFGCR2_KDIV_2 (1<<5) #define DPLL_CFGCR2_KDIV_2 (1<<5)
#define DPLL_CFGCR2_KDIV_3 (2<<5) #define DPLL_CFGCR2_KDIV_3 (2<<5)
#define DPLL_CFGCR2_KDIV_1 (3<<5) #define DPLL_CFGCR2_KDIV_1 (3<<5)
#define DPLL_CFGCR2_PDIV_MASK (7<<2) #define DPLL_CFGCR2_PDIV_MASK (7<<2)
#define DPLL_CFGCR2_PDIV(x) (x<<2) #define DPLL_CFGCR2_PDIV(x) ((x)<<2)
#define DPLL_CFGCR2_PDIV_1 (0<<2) #define DPLL_CFGCR2_PDIV_1 (0<<2)
#define DPLL_CFGCR2_PDIV_2 (1<<2) #define DPLL_CFGCR2_PDIV_2 (1<<2)
#define DPLL_CFGCR2_PDIV_3 (2<<2) #define DPLL_CFGCR2_PDIV_3 (2<<2)
@ -7979,7 +7979,7 @@ enum skl_disp_power_wells {
#define VIRTUAL_CHANNEL_SHIFT 6 #define VIRTUAL_CHANNEL_SHIFT 6
#define VIRTUAL_CHANNEL_MASK (3 << 6) #define VIRTUAL_CHANNEL_MASK (3 << 6)
#define DATA_TYPE_SHIFT 0 #define DATA_TYPE_SHIFT 0
#define DATA_TYPE_MASK (3f << 0) #define DATA_TYPE_MASK (0x3f << 0)
/* data type values, see include/video/mipi_display.h */ /* data type values, see include/video/mipi_display.h */
#define _MIPIA_GEN_FIFO_STAT (dev_priv->mipi_mmio_base + 0xb074) #define _MIPIA_GEN_FIFO_STAT (dev_priv->mipi_mmio_base + 0xb074)

View File

@ -122,12 +122,24 @@ int i915_save_state(struct drm_device *dev)
dev_priv->regfile.saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); dev_priv->regfile.saveMI_ARB_STATE = I915_READ(MI_ARB_STATE);
/* Scratch space */ /* Scratch space */
for (i = 0; i < 16; i++) { if (IS_GEN2(dev_priv) && IS_MOBILE(dev_priv)) {
dev_priv->regfile.saveSWF0[i] = I915_READ(SWF00 + (i << 2)); for (i = 0; i < 7; i++) {
dev_priv->regfile.saveSWF1[i] = I915_READ(SWF10 + (i << 2)); dev_priv->regfile.saveSWF0[i] = I915_READ(SWF0(i));
dev_priv->regfile.saveSWF1[i] = I915_READ(SWF1(i));
}
for (i = 0; i < 3; i++)
dev_priv->regfile.saveSWF3[i] = I915_READ(SWF3(i));
} else if (IS_GEN2(dev_priv)) {
for (i = 0; i < 7; i++)
dev_priv->regfile.saveSWF1[i] = I915_READ(SWF1(i));
} else if (HAS_GMCH_DISPLAY(dev_priv)) {
for (i = 0; i < 16; i++) {
dev_priv->regfile.saveSWF0[i] = I915_READ(SWF0(i));
dev_priv->regfile.saveSWF1[i] = I915_READ(SWF1(i));
}
for (i = 0; i < 3; i++)
dev_priv->regfile.saveSWF3[i] = I915_READ(SWF3(i));
} }
for (i = 0; i < 3; i++)
dev_priv->regfile.saveSWF2[i] = I915_READ(SWF30 + (i << 2));
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
@ -156,12 +168,25 @@ int i915_restore_state(struct drm_device *dev)
/* Memory arbitration state */ /* Memory arbitration state */
I915_WRITE(MI_ARB_STATE, dev_priv->regfile.saveMI_ARB_STATE | 0xffff0000); I915_WRITE(MI_ARB_STATE, dev_priv->regfile.saveMI_ARB_STATE | 0xffff0000);
for (i = 0; i < 16; i++) { /* Scratch space */
I915_WRITE(SWF00 + (i << 2), dev_priv->regfile.saveSWF0[i]); if (IS_GEN2(dev_priv) && IS_MOBILE(dev_priv)) {
I915_WRITE(SWF10 + (i << 2), dev_priv->regfile.saveSWF1[i]); for (i = 0; i < 7; i++) {
I915_WRITE(SWF0(i), dev_priv->regfile.saveSWF0[i]);
I915_WRITE(SWF1(i), dev_priv->regfile.saveSWF1[i]);
}
for (i = 0; i < 3; i++)
I915_WRITE(SWF3(i), dev_priv->regfile.saveSWF3[i]);
} else if (IS_GEN2(dev_priv)) {
for (i = 0; i < 7; i++)
I915_WRITE(SWF1(i), dev_priv->regfile.saveSWF1[i]);
} else if (HAS_GMCH_DISPLAY(dev_priv)) {
for (i = 0; i < 16; i++) {
I915_WRITE(SWF0(i), dev_priv->regfile.saveSWF0[i]);
I915_WRITE(SWF1(i), dev_priv->regfile.saveSWF1[i]);
}
for (i = 0; i < 3; i++)
I915_WRITE(SWF3(i), dev_priv->regfile.saveSWF3[i]);
} }
for (i = 0; i < 3; i++)
I915_WRITE(SWF30 + (i << 2), dev_priv->regfile.saveSWF2[i]);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);

View File

@ -5,7 +5,6 @@
*/ */
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/vga_switcheroo.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include "i915_drv.h" #include "i915_drv.h"

View File

@ -94,7 +94,6 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base); __drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base);
crtc_state->update_pipe = false; crtc_state->update_pipe = false;
crtc_state->disable_lp_wm = false;
return &crtc_state->base; return &crtc_state->base;
} }

View File

@ -61,21 +61,21 @@ static const struct {
int clock; int clock;
u32 config; u32 config;
} hdmi_audio_clock[] = { } hdmi_audio_clock[] = {
{ DIV_ROUND_UP(25200 * 1000, 1001), AUD_CONFIG_PIXEL_CLOCK_HDMI_25175 }, { 25175, AUD_CONFIG_PIXEL_CLOCK_HDMI_25175 },
{ 25200, AUD_CONFIG_PIXEL_CLOCK_HDMI_25200 }, /* default per bspec */ { 25200, AUD_CONFIG_PIXEL_CLOCK_HDMI_25200 }, /* default per bspec */
{ 27000, AUD_CONFIG_PIXEL_CLOCK_HDMI_27000 }, { 27000, AUD_CONFIG_PIXEL_CLOCK_HDMI_27000 },
{ 27000 * 1001 / 1000, AUD_CONFIG_PIXEL_CLOCK_HDMI_27027 }, { 27027, AUD_CONFIG_PIXEL_CLOCK_HDMI_27027 },
{ 54000, AUD_CONFIG_PIXEL_CLOCK_HDMI_54000 }, { 54000, AUD_CONFIG_PIXEL_CLOCK_HDMI_54000 },
{ 54000 * 1001 / 1000, AUD_CONFIG_PIXEL_CLOCK_HDMI_54054 }, { 54054, AUD_CONFIG_PIXEL_CLOCK_HDMI_54054 },
{ DIV_ROUND_UP(74250 * 1000, 1001), AUD_CONFIG_PIXEL_CLOCK_HDMI_74176 }, { 74176, AUD_CONFIG_PIXEL_CLOCK_HDMI_74176 },
{ 74250, AUD_CONFIG_PIXEL_CLOCK_HDMI_74250 }, { 74250, AUD_CONFIG_PIXEL_CLOCK_HDMI_74250 },
{ DIV_ROUND_UP(148500 * 1000, 1001), AUD_CONFIG_PIXEL_CLOCK_HDMI_148352 }, { 148352, AUD_CONFIG_PIXEL_CLOCK_HDMI_148352 },
{ 148500, AUD_CONFIG_PIXEL_CLOCK_HDMI_148500 }, { 148500, AUD_CONFIG_PIXEL_CLOCK_HDMI_148500 },
}; };
/* HDMI N/CTS table */ /* HDMI N/CTS table */
#define TMDS_297M 297000 #define TMDS_297M 297000
#define TMDS_296M DIV_ROUND_UP(297000 * 1000, 1001) #define TMDS_296M 296703
static const struct { static const struct {
int sample_rate; int sample_rate;
int clock; int clock;

View File

@ -1231,20 +1231,13 @@ static const struct dmi_system_id intel_no_opregion_vbt[] = {
{ } { }
}; };
static const struct bdb_header *validate_vbt(const void __iomem *_base, static const struct bdb_header *validate_vbt(const void *base,
size_t size, size_t size,
const void __iomem *_vbt, const void *_vbt,
const char *source) const char *source)
{ {
/* size_t offset = _vbt - base;
* This is the one place where we explicitly discard the address space const struct vbt_header *vbt = _vbt;
* (__iomem) of the BIOS/VBT. (And this will cause a sparse complaint.)
* From now on everything is based on 'base', and treated as regular
* memory.
*/
const void *base = (const void *) _base;
size_t offset = _vbt - _base;
const struct vbt_header *vbt = base + offset;
const struct bdb_header *bdb; const struct bdb_header *bdb;
if (offset + sizeof(struct vbt_header) > size) { if (offset + sizeof(struct vbt_header) > size) {
@ -1282,7 +1275,15 @@ static const struct bdb_header *find_vbt(void __iomem *bios, size_t size)
/* Scour memory looking for the VBT signature. */ /* Scour memory looking for the VBT signature. */
for (i = 0; i + 4 < size; i++) { for (i = 0; i + 4 < size; i++) {
if (ioread32(bios + i) == *((const u32 *) "$VBT")) { if (ioread32(bios + i) == *((const u32 *) "$VBT")) {
bdb = validate_vbt(bios, size, bios + i, "PCI ROM"); /*
* This is the one place where we explicitly discard the
* address space (__iomem) of the BIOS/VBT. From now on
* everything is based on 'base', and treated as regular
* memory.
*/
void *_bios = (void __force *) bios;
bdb = validate_vbt(_bios, size, _bios + i, "PCI ROM");
break; break;
} }
} }

View File

@ -1157,12 +1157,10 @@ static const char *state_string(bool enabled)
void assert_pll(struct drm_i915_private *dev_priv, void assert_pll(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state) enum pipe pipe, bool state)
{ {
int reg;
u32 val; u32 val;
bool cur_state; bool cur_state;
reg = DPLL(pipe); val = I915_READ(DPLL(pipe));
val = I915_READ(reg);
cur_state = !!(val & DPLL_VCO_ENABLE); cur_state = !!(val & DPLL_VCO_ENABLE);
I915_STATE_WARN(cur_state != state, I915_STATE_WARN(cur_state != state,
"PLL state assertion failure (expected %s, current %s)\n", "PLL state assertion failure (expected %s, current %s)\n",
@ -1219,20 +1217,16 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
static void assert_fdi_tx(struct drm_i915_private *dev_priv, static void assert_fdi_tx(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state) enum pipe pipe, bool state)
{ {
int reg;
u32 val;
bool cur_state; bool cur_state;
enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
pipe); pipe);
if (HAS_DDI(dev_priv->dev)) { if (HAS_DDI(dev_priv->dev)) {
/* DDI does not have a specific FDI_TX register */ /* DDI does not have a specific FDI_TX register */
reg = TRANS_DDI_FUNC_CTL(cpu_transcoder); u32 val = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
val = I915_READ(reg);
cur_state = !!(val & TRANS_DDI_FUNC_ENABLE); cur_state = !!(val & TRANS_DDI_FUNC_ENABLE);
} else { } else {
reg = FDI_TX_CTL(pipe); u32 val = I915_READ(FDI_TX_CTL(pipe));
val = I915_READ(reg);
cur_state = !!(val & FDI_TX_ENABLE); cur_state = !!(val & FDI_TX_ENABLE);
} }
I915_STATE_WARN(cur_state != state, I915_STATE_WARN(cur_state != state,
@ -1245,12 +1239,10 @@ static void assert_fdi_tx(struct drm_i915_private *dev_priv,
static void assert_fdi_rx(struct drm_i915_private *dev_priv, static void assert_fdi_rx(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state) enum pipe pipe, bool state)
{ {
int reg;
u32 val; u32 val;
bool cur_state; bool cur_state;
reg = FDI_RX_CTL(pipe); val = I915_READ(FDI_RX_CTL(pipe));
val = I915_READ(reg);
cur_state = !!(val & FDI_RX_ENABLE); cur_state = !!(val & FDI_RX_ENABLE);
I915_STATE_WARN(cur_state != state, I915_STATE_WARN(cur_state != state,
"FDI RX state assertion failure (expected %s, current %s)\n", "FDI RX state assertion failure (expected %s, current %s)\n",
@ -1262,7 +1254,6 @@ static void assert_fdi_rx(struct drm_i915_private *dev_priv,
static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv, static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv,
enum pipe pipe) enum pipe pipe)
{ {
int reg;
u32 val; u32 val;
/* ILK FDI PLL is always enabled */ /* ILK FDI PLL is always enabled */
@ -1273,20 +1264,17 @@ static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv,
if (HAS_DDI(dev_priv->dev)) if (HAS_DDI(dev_priv->dev))
return; return;
reg = FDI_TX_CTL(pipe); val = I915_READ(FDI_TX_CTL(pipe));
val = I915_READ(reg);
I915_STATE_WARN(!(val & FDI_TX_PLL_ENABLE), "FDI TX PLL assertion failure, should be active but is disabled\n"); I915_STATE_WARN(!(val & FDI_TX_PLL_ENABLE), "FDI TX PLL assertion failure, should be active but is disabled\n");
} }
void assert_fdi_rx_pll(struct drm_i915_private *dev_priv, void assert_fdi_rx_pll(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state) enum pipe pipe, bool state)
{ {
int reg;
u32 val; u32 val;
bool cur_state; bool cur_state;
reg = FDI_RX_CTL(pipe); val = I915_READ(FDI_RX_CTL(pipe));
val = I915_READ(reg);
cur_state = !!(val & FDI_RX_PLL_ENABLE); cur_state = !!(val & FDI_RX_PLL_ENABLE);
I915_STATE_WARN(cur_state != state, I915_STATE_WARN(cur_state != state,
"FDI RX PLL assertion failure (expected %s, current %s)\n", "FDI RX PLL assertion failure (expected %s, current %s)\n",
@ -1356,8 +1344,6 @@ static void assert_cursor(struct drm_i915_private *dev_priv,
void assert_pipe(struct drm_i915_private *dev_priv, void assert_pipe(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state) enum pipe pipe, bool state)
{ {
int reg;
u32 val;
bool cur_state; bool cur_state;
enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
pipe); pipe);
@ -1371,8 +1357,7 @@ void assert_pipe(struct drm_i915_private *dev_priv,
POWER_DOMAIN_TRANSCODER(cpu_transcoder))) { POWER_DOMAIN_TRANSCODER(cpu_transcoder))) {
cur_state = false; cur_state = false;
} else { } else {
reg = PIPECONF(cpu_transcoder); u32 val = I915_READ(PIPECONF(cpu_transcoder));
val = I915_READ(reg);
cur_state = !!(val & PIPECONF_ENABLE); cur_state = !!(val & PIPECONF_ENABLE);
} }
@ -1384,12 +1369,10 @@ void assert_pipe(struct drm_i915_private *dev_priv,
static void assert_plane(struct drm_i915_private *dev_priv, static void assert_plane(struct drm_i915_private *dev_priv,
enum plane plane, bool state) enum plane plane, bool state)
{ {
int reg;
u32 val; u32 val;
bool cur_state; bool cur_state;
reg = DSPCNTR(plane); val = I915_READ(DSPCNTR(plane));
val = I915_READ(reg);
cur_state = !!(val & DISPLAY_PLANE_ENABLE); cur_state = !!(val & DISPLAY_PLANE_ENABLE);
I915_STATE_WARN(cur_state != state, I915_STATE_WARN(cur_state != state,
"plane %c assertion failure (expected %s, current %s)\n", "plane %c assertion failure (expected %s, current %s)\n",
@ -1403,14 +1386,11 @@ static void assert_planes_disabled(struct drm_i915_private *dev_priv,
enum pipe pipe) enum pipe pipe)
{ {
struct drm_device *dev = dev_priv->dev; struct drm_device *dev = dev_priv->dev;
int reg, i; int i;
u32 val;
int cur_pipe;
/* Primary planes are fixed to pipes on gen4+ */ /* Primary planes are fixed to pipes on gen4+ */
if (INTEL_INFO(dev)->gen >= 4) { if (INTEL_INFO(dev)->gen >= 4) {
reg = DSPCNTR(pipe); u32 val = I915_READ(DSPCNTR(pipe));
val = I915_READ(reg);
I915_STATE_WARN(val & DISPLAY_PLANE_ENABLE, I915_STATE_WARN(val & DISPLAY_PLANE_ENABLE,
"plane %c assertion failure, should be disabled but not\n", "plane %c assertion failure, should be disabled but not\n",
plane_name(pipe)); plane_name(pipe));
@ -1419,9 +1399,8 @@ static void assert_planes_disabled(struct drm_i915_private *dev_priv,
/* Need to check both planes against the pipe */ /* Need to check both planes against the pipe */
for_each_pipe(dev_priv, i) { for_each_pipe(dev_priv, i) {
reg = DSPCNTR(i); u32 val = I915_READ(DSPCNTR(i));
val = I915_READ(reg); enum pipe cur_pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
cur_pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
DISPPLANE_SEL_PIPE_SHIFT; DISPPLANE_SEL_PIPE_SHIFT;
I915_STATE_WARN((val & DISPLAY_PLANE_ENABLE) && pipe == cur_pipe, I915_STATE_WARN((val & DISPLAY_PLANE_ENABLE) && pipe == cur_pipe,
"plane %c assertion failure, should be off on pipe %c but is still active\n", "plane %c assertion failure, should be off on pipe %c but is still active\n",
@ -1433,33 +1412,29 @@ static void assert_sprites_disabled(struct drm_i915_private *dev_priv,
enum pipe pipe) enum pipe pipe)
{ {
struct drm_device *dev = dev_priv->dev; struct drm_device *dev = dev_priv->dev;
int reg, sprite; int sprite;
u32 val;
if (INTEL_INFO(dev)->gen >= 9) { if (INTEL_INFO(dev)->gen >= 9) {
for_each_sprite(dev_priv, pipe, sprite) { for_each_sprite(dev_priv, pipe, sprite) {
val = I915_READ(PLANE_CTL(pipe, sprite)); u32 val = I915_READ(PLANE_CTL(pipe, sprite));
I915_STATE_WARN(val & PLANE_CTL_ENABLE, I915_STATE_WARN(val & PLANE_CTL_ENABLE,
"plane %d assertion failure, should be off on pipe %c but is still active\n", "plane %d assertion failure, should be off on pipe %c but is still active\n",
sprite, pipe_name(pipe)); sprite, pipe_name(pipe));
} }
} else if (IS_VALLEYVIEW(dev)) { } else if (IS_VALLEYVIEW(dev)) {
for_each_sprite(dev_priv, pipe, sprite) { for_each_sprite(dev_priv, pipe, sprite) {
reg = SPCNTR(pipe, sprite); u32 val = I915_READ(SPCNTR(pipe, sprite));
val = I915_READ(reg);
I915_STATE_WARN(val & SP_ENABLE, I915_STATE_WARN(val & SP_ENABLE,
"sprite %c assertion failure, should be off on pipe %c but is still active\n", "sprite %c assertion failure, should be off on pipe %c but is still active\n",
sprite_name(pipe, sprite), pipe_name(pipe)); sprite_name(pipe, sprite), pipe_name(pipe));
} }
} else if (INTEL_INFO(dev)->gen >= 7) { } else if (INTEL_INFO(dev)->gen >= 7) {
reg = SPRCTL(pipe); u32 val = I915_READ(SPRCTL(pipe));
val = I915_READ(reg);
I915_STATE_WARN(val & SPRITE_ENABLE, I915_STATE_WARN(val & SPRITE_ENABLE,
"sprite %c assertion failure, should be off on pipe %c but is still active\n", "sprite %c assertion failure, should be off on pipe %c but is still active\n",
plane_name(pipe), pipe_name(pipe)); plane_name(pipe), pipe_name(pipe));
} else if (INTEL_INFO(dev)->gen >= 5) { } else if (INTEL_INFO(dev)->gen >= 5) {
reg = DVSCNTR(pipe); u32 val = I915_READ(DVSCNTR(pipe));
val = I915_READ(reg);
I915_STATE_WARN(val & DVS_ENABLE, I915_STATE_WARN(val & DVS_ENABLE,
"sprite %c assertion failure, should be off on pipe %c but is still active\n", "sprite %c assertion failure, should be off on pipe %c but is still active\n",
plane_name(pipe), pipe_name(pipe)); plane_name(pipe), pipe_name(pipe));
@ -1488,12 +1463,10 @@ static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv)
static void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv, static void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
enum pipe pipe) enum pipe pipe)
{ {
int reg;
u32 val; u32 val;
bool enabled; bool enabled;
reg = PCH_TRANSCONF(pipe); val = I915_READ(PCH_TRANSCONF(pipe));
val = I915_READ(reg);
enabled = !!(val & TRANS_ENABLE); enabled = !!(val & TRANS_ENABLE);
I915_STATE_WARN(enabled, I915_STATE_WARN(enabled,
"transcoder assertion failed, should be off on pipe %c but is still active\n", "transcoder assertion failed, should be off on pipe %c but is still active\n",
@ -1600,21 +1573,18 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
enum pipe pipe) enum pipe pipe)
{ {
int reg;
u32 val; u32 val;
assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B); assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B);
assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C); assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C);
assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D); assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D);
reg = PCH_ADPA; val = I915_READ(PCH_ADPA);
val = I915_READ(reg);
I915_STATE_WARN(adpa_pipe_enabled(dev_priv, pipe, val), I915_STATE_WARN(adpa_pipe_enabled(dev_priv, pipe, val),
"PCH VGA enabled on transcoder %c, should be disabled\n", "PCH VGA enabled on transcoder %c, should be disabled\n",
pipe_name(pipe)); pipe_name(pipe));
reg = PCH_LVDS; val = I915_READ(PCH_LVDS);
val = I915_READ(reg);
I915_STATE_WARN(lvds_pipe_enabled(dev_priv, pipe, val), I915_STATE_WARN(lvds_pipe_enabled(dev_priv, pipe, val),
"PCH LVDS enabled on transcoder %c, should be disabled\n", "PCH LVDS enabled on transcoder %c, should be disabled\n",
pipe_name(pipe)); pipe_name(pipe));
@ -4804,6 +4774,7 @@ static void intel_post_plane_update(struct intel_crtc *crtc)
struct intel_crtc_atomic_commit *atomic = &crtc->atomic; struct intel_crtc_atomic_commit *atomic = &crtc->atomic;
struct drm_device *dev = crtc->base.dev; struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_plane *plane;
if (atomic->wait_vblank) if (atomic->wait_vblank)
intel_wait_for_vblank(dev, crtc->pipe); intel_wait_for_vblank(dev, crtc->pipe);
@ -4822,6 +4793,10 @@ static void intel_post_plane_update(struct intel_crtc *crtc)
if (atomic->post_enable_primary) if (atomic->post_enable_primary)
intel_post_enable_primary(&crtc->base); intel_post_enable_primary(&crtc->base);
drm_for_each_plane_mask(plane, dev, atomic->update_sprite_watermarks)
intel_update_sprite_watermarks(plane, &crtc->base,
0, 0, 0, false, false);
memset(atomic, 0, sizeof(*atomic)); memset(atomic, 0, sizeof(*atomic));
} }
@ -9952,7 +9927,7 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
} }
cntl |= pipe << 28; /* Connect to correct pipe */ cntl |= pipe << 28; /* Connect to correct pipe */
if (IS_HASWELL(dev) || IS_BROADWELL(dev)) if (HAS_DDI(dev))
cntl |= CURSOR_PIPE_CSC_ENABLE; cntl |= CURSOR_PIPE_CSC_ENABLE;
} }
@ -10822,7 +10797,7 @@ static bool page_flip_finished(struct intel_crtc *crtc)
*/ */
return (I915_READ(DSPSURFLIVE(crtc->plane)) & ~0xfff) == return (I915_READ(DSPSURFLIVE(crtc->plane)) & ~0xfff) ==
crtc->unpin_work->gtt_offset && crtc->unpin_work->gtt_offset &&
g4x_flip_count_after_eq(I915_READ(PIPE_FLIPCOUNT_GM45(crtc->pipe)), g4x_flip_count_after_eq(I915_READ(PIPE_FLIPCOUNT_G4X(crtc->pipe)),
crtc->unpin_work->flip_count); crtc->unpin_work->flip_count);
} }
@ -10848,11 +10823,11 @@ void intel_prepare_page_flip(struct drm_device *dev, int plane)
spin_unlock_irqrestore(&dev->event_lock, flags); spin_unlock_irqrestore(&dev->event_lock, flags);
} }
static inline void intel_mark_page_flip_active(struct intel_crtc *intel_crtc) static inline void intel_mark_page_flip_active(struct intel_unpin_work *work)
{ {
/* Ensure that the work item is consistent when activating it ... */ /* Ensure that the work item is consistent when activating it ... */
smp_wmb(); smp_wmb();
atomic_set(&intel_crtc->unpin_work->pending, INTEL_FLIP_PENDING); atomic_set(&work->pending, INTEL_FLIP_PENDING);
/* and that it is marked active as soon as the irq could fire. */ /* and that it is marked active as soon as the irq could fire. */
smp_wmb(); smp_wmb();
} }
@ -10888,7 +10863,7 @@ static int intel_gen2_queue_flip(struct drm_device *dev,
intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset); intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset);
intel_ring_emit(ring, 0); /* aux display base address, unused */ intel_ring_emit(ring, 0); /* aux display base address, unused */
intel_mark_page_flip_active(intel_crtc); intel_mark_page_flip_active(intel_crtc->unpin_work);
return 0; return 0;
} }
@ -10920,7 +10895,7 @@ static int intel_gen3_queue_flip(struct drm_device *dev,
intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset); intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset);
intel_ring_emit(ring, MI_NOOP); intel_ring_emit(ring, MI_NOOP);
intel_mark_page_flip_active(intel_crtc); intel_mark_page_flip_active(intel_crtc->unpin_work);
return 0; return 0;
} }
@ -10959,7 +10934,7 @@ static int intel_gen4_queue_flip(struct drm_device *dev,
pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
intel_ring_emit(ring, pf | pipesrc); intel_ring_emit(ring, pf | pipesrc);
intel_mark_page_flip_active(intel_crtc); intel_mark_page_flip_active(intel_crtc->unpin_work);
return 0; return 0;
} }
@ -10995,7 +10970,7 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
intel_ring_emit(ring, pf | pipesrc); intel_ring_emit(ring, pf | pipesrc);
intel_mark_page_flip_active(intel_crtc); intel_mark_page_flip_active(intel_crtc->unpin_work);
return 0; return 0;
} }
@ -11090,7 +11065,7 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset); intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset);
intel_ring_emit(ring, (MI_NOOP)); intel_ring_emit(ring, (MI_NOOP));
intel_mark_page_flip_active(intel_crtc); intel_mark_page_flip_active(intel_crtc->unpin_work);
return 0; return 0;
} }
@ -11121,7 +11096,8 @@ static bool use_mmio_flip(struct intel_engine_cs *ring,
return ring != i915_gem_request_get_ring(obj->last_write_req); return ring != i915_gem_request_get_ring(obj->last_write_req);
} }
static void skl_do_mmio_flip(struct intel_crtc *intel_crtc) static void skl_do_mmio_flip(struct intel_crtc *intel_crtc,
struct intel_unpin_work *work)
{ {
struct drm_device *dev = intel_crtc->base.dev; struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
@ -11162,11 +11138,12 @@ static void skl_do_mmio_flip(struct intel_crtc *intel_crtc)
I915_WRITE(PLANE_CTL(pipe, 0), ctl); I915_WRITE(PLANE_CTL(pipe, 0), ctl);
I915_WRITE(PLANE_STRIDE(pipe, 0), stride); I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
I915_WRITE(PLANE_SURF(pipe, 0), intel_crtc->unpin_work->gtt_offset); I915_WRITE(PLANE_SURF(pipe, 0), work->gtt_offset);
POSTING_READ(PLANE_SURF(pipe, 0)); POSTING_READ(PLANE_SURF(pipe, 0));
} }
static void ilk_do_mmio_flip(struct intel_crtc *intel_crtc) static void ilk_do_mmio_flip(struct intel_crtc *intel_crtc,
struct intel_unpin_work *work)
{ {
struct drm_device *dev = intel_crtc->base.dev; struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
@ -11186,31 +11163,36 @@ static void ilk_do_mmio_flip(struct intel_crtc *intel_crtc)
I915_WRITE(reg, dspcntr); I915_WRITE(reg, dspcntr);
I915_WRITE(DSPSURF(intel_crtc->plane), I915_WRITE(DSPSURF(intel_crtc->plane), work->gtt_offset);
intel_crtc->unpin_work->gtt_offset);
POSTING_READ(DSPSURF(intel_crtc->plane)); POSTING_READ(DSPSURF(intel_crtc->plane));
} }
/* /*
* XXX: This is the temporary way to update the plane registers until we get * XXX: This is the temporary way to update the plane registers until we get
* around to using the usual plane update functions for MMIO flips * around to using the usual plane update functions for MMIO flips
*/ */
static void intel_do_mmio_flip(struct intel_crtc *intel_crtc) static void intel_do_mmio_flip(struct intel_mmio_flip *mmio_flip)
{ {
struct drm_device *dev = intel_crtc->base.dev; struct intel_crtc *crtc = mmio_flip->crtc;
struct intel_unpin_work *work;
intel_mark_page_flip_active(intel_crtc); spin_lock_irq(&crtc->base.dev->event_lock);
work = crtc->unpin_work;
spin_unlock_irq(&crtc->base.dev->event_lock);
if (work == NULL)
return;
intel_pipe_update_start(intel_crtc); intel_mark_page_flip_active(work);
if (INTEL_INFO(dev)->gen >= 9) intel_pipe_update_start(crtc);
skl_do_mmio_flip(intel_crtc);
if (INTEL_INFO(mmio_flip->i915)->gen >= 9)
skl_do_mmio_flip(crtc, work);
else else
/* use_mmio_flip() retricts MMIO flips to ilk+ */ /* use_mmio_flip() retricts MMIO flips to ilk+ */
ilk_do_mmio_flip(intel_crtc); ilk_do_mmio_flip(crtc, work);
intel_pipe_update_end(intel_crtc); intel_pipe_update_end(crtc);
} }
static void intel_mmio_flip_work_func(struct work_struct *work) static void intel_mmio_flip_work_func(struct work_struct *work)
@ -11218,15 +11200,15 @@ static void intel_mmio_flip_work_func(struct work_struct *work)
struct intel_mmio_flip *mmio_flip = struct intel_mmio_flip *mmio_flip =
container_of(work, struct intel_mmio_flip, work); container_of(work, struct intel_mmio_flip, work);
if (mmio_flip->req) if (mmio_flip->req) {
WARN_ON(__i915_wait_request(mmio_flip->req, WARN_ON(__i915_wait_request(mmio_flip->req,
mmio_flip->crtc->reset_counter, mmio_flip->crtc->reset_counter,
false, NULL, false, NULL,
&mmio_flip->i915->rps.mmioflips)); &mmio_flip->i915->rps.mmioflips));
i915_gem_request_unreference__unlocked(mmio_flip->req);
}
intel_do_mmio_flip(mmio_flip->crtc); intel_do_mmio_flip(mmio_flip);
i915_gem_request_unreference__unlocked(mmio_flip->req);
kfree(mmio_flip); kfree(mmio_flip);
} }
@ -11427,7 +11409,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
intel_crtc->reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); intel_crtc->reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev)) if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev))
work->flip_count = I915_READ(PIPE_FLIPCOUNT_GM45(pipe)) + 1; work->flip_count = I915_READ(PIPE_FLIPCOUNT_G4X(pipe)) + 1;
if (IS_VALLEYVIEW(dev)) { if (IS_VALLEYVIEW(dev)) {
ring = &dev_priv->ring[BCS]; ring = &dev_priv->ring[BCS];
@ -11577,32 +11559,18 @@ retry:
static bool intel_wm_need_update(struct drm_plane *plane, static bool intel_wm_need_update(struct drm_plane *plane,
struct drm_plane_state *state) struct drm_plane_state *state)
{ {
struct intel_plane_state *new = to_intel_plane_state(state); /* Update watermarks on tiling changes. */
struct intel_plane_state *cur = to_intel_plane_state(plane->state);
/* Update watermarks on tiling or size changes. */
if (!plane->state->fb || !state->fb || if (!plane->state->fb || !state->fb ||
plane->state->fb->modifier[0] != state->fb->modifier[0] || plane->state->fb->modifier[0] != state->fb->modifier[0] ||
plane->state->rotation != state->rotation || plane->state->rotation != state->rotation)
drm_rect_width(&new->src) != drm_rect_width(&cur->src) || return true;
drm_rect_height(&new->src) != drm_rect_height(&cur->src) ||
drm_rect_width(&new->dst) != drm_rect_width(&cur->dst) || if (plane->state->crtc_w != state->crtc_w)
drm_rect_height(&new->dst) != drm_rect_height(&cur->dst))
return true; return true;
return false; return false;
} }
static bool needs_scaling(struct intel_plane_state *state)
{
int src_w = drm_rect_width(&state->src) >> 16;
int src_h = drm_rect_height(&state->src) >> 16;
int dst_w = drm_rect_width(&state->dst);
int dst_h = drm_rect_height(&state->dst);
return (src_w != dst_w || src_h != dst_h);
}
int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
struct drm_plane_state *plane_state) struct drm_plane_state *plane_state)
{ {
@ -11618,6 +11586,7 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
bool mode_changed = needs_modeset(crtc_state); bool mode_changed = needs_modeset(crtc_state);
bool was_crtc_enabled = crtc->state->active; bool was_crtc_enabled = crtc->state->active;
bool is_crtc_enabled = crtc_state->active; bool is_crtc_enabled = crtc_state->active;
bool turn_off, turn_on, visible, was_visible; bool turn_off, turn_on, visible, was_visible;
struct drm_framebuffer *fb = plane_state->fb; struct drm_framebuffer *fb = plane_state->fb;
@ -11735,23 +11704,11 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
case DRM_PLANE_TYPE_CURSOR: case DRM_PLANE_TYPE_CURSOR:
break; break;
case DRM_PLANE_TYPE_OVERLAY: case DRM_PLANE_TYPE_OVERLAY:
/* if (turn_off && !mode_changed) {
* WaCxSRDisabledForSpriteScaling:ivb
*
* cstate->update_wm was already set above, so this flag will
* take effect when we commit and program watermarks.
*/
if (IS_IVYBRIDGE(dev) &&
needs_scaling(to_intel_plane_state(plane_state)) &&
!needs_scaling(old_plane_state)) {
to_intel_crtc_state(crtc_state)->disable_lp_wm = true;
} else if (turn_off && !mode_changed) {
intel_crtc->atomic.wait_vblank = true; intel_crtc->atomic.wait_vblank = true;
intel_crtc->atomic.update_sprite_watermarks |= intel_crtc->atomic.update_sprite_watermarks |=
1 << i; 1 << i;
} }
break;
} }
return 0; return 0;
} }
@ -14942,13 +14899,12 @@ intel_check_plane_mapping(struct intel_crtc *crtc)
{ {
struct drm_device *dev = crtc->base.dev; struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 reg, val; u32 val;
if (INTEL_INFO(dev)->num_pipes == 1) if (INTEL_INFO(dev)->num_pipes == 1)
return true; return true;
reg = DSPCNTR(!crtc->plane); val = I915_READ(DSPCNTR(!crtc->plane));
val = I915_READ(reg);
if ((val & DISPLAY_PLANE_ENABLE) && if ((val & DISPLAY_PLANE_ENABLE) &&
(!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe)) (!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe))

View File

@ -574,8 +574,6 @@ static int edp_notify_handler(struct notifier_block *this, unsigned long code,
edp_notifier); edp_notifier);
struct drm_device *dev = intel_dp_to_dev(intel_dp); struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp_div;
u32 pp_ctrl_reg, pp_div_reg;
if (!is_edp(intel_dp) || code != SYS_RESTART) if (!is_edp(intel_dp) || code != SYS_RESTART)
return 0; return 0;
@ -584,6 +582,8 @@ static int edp_notify_handler(struct notifier_block *this, unsigned long code,
if (IS_VALLEYVIEW(dev)) { if (IS_VALLEYVIEW(dev)) {
enum pipe pipe = vlv_power_sequencer_pipe(intel_dp); enum pipe pipe = vlv_power_sequencer_pipe(intel_dp);
u32 pp_ctrl_reg, pp_div_reg;
u32 pp_div;
pp_ctrl_reg = VLV_PIPE_PP_CONTROL(pipe); pp_ctrl_reg = VLV_PIPE_PP_CONTROL(pipe);
pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe); pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe);
@ -5536,7 +5536,6 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
struct intel_dp *intel_dp = dev_priv->drrs.dp; struct intel_dp *intel_dp = dev_priv->drrs.dp;
struct intel_crtc_state *config = NULL; struct intel_crtc_state *config = NULL;
struct intel_crtc *intel_crtc = NULL; struct intel_crtc *intel_crtc = NULL;
u32 reg, val;
enum drrs_refresh_rate_type index = DRRS_HIGH_RR; enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
if (refresh_rate <= 0) { if (refresh_rate <= 0) {
@ -5598,9 +5597,10 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
DRM_ERROR("Unsupported refreshrate type\n"); DRM_ERROR("Unsupported refreshrate type\n");
} }
} else if (INTEL_INFO(dev)->gen > 6) { } else if (INTEL_INFO(dev)->gen > 6) {
reg = PIPECONF(intel_crtc->config->cpu_transcoder); u32 reg = PIPECONF(intel_crtc->config->cpu_transcoder);
val = I915_READ(reg); u32 val;
val = I915_READ(reg);
if (index > DRRS_HIGH_RR) { if (index > DRRS_HIGH_RR) {
if (IS_VALLEYVIEW(dev)) if (IS_VALLEYVIEW(dev))
val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV; val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV;

View File

@ -468,9 +468,6 @@ struct intel_crtc_state {
/* w/a for waiting 2 vblanks during crtc enable */ /* w/a for waiting 2 vblanks during crtc enable */
enum pipe hsw_workaround_pipe; enum pipe hsw_workaround_pipe;
/* IVB sprite scaling w/a (WaCxSRDisabledForSpriteScaling:ivb) */
bool disable_lp_wm;
}; };
struct vlv_wm_state { struct vlv_wm_state {
@ -1399,6 +1396,12 @@ void intel_init_clock_gating(struct drm_device *dev);
void intel_suspend_hw(struct drm_device *dev); void intel_suspend_hw(struct drm_device *dev);
int ilk_wm_max_level(const struct drm_device *dev); int ilk_wm_max_level(const struct drm_device *dev);
void intel_update_watermarks(struct drm_crtc *crtc); void intel_update_watermarks(struct drm_crtc *crtc);
void intel_update_sprite_watermarks(struct drm_plane *plane,
struct drm_crtc *crtc,
uint32_t sprite_width,
uint32_t sprite_height,
int pixel_size,
bool enabled, bool scaled);
void intel_init_pm(struct drm_device *dev); void intel_init_pm(struct drm_device *dev);
void intel_pm_setup(struct drm_device *dev); void intel_pm_setup(struct drm_device *dev);
void intel_gpu_ips_init(struct drm_i915_private *dev_priv); void intel_gpu_ips_init(struct drm_i915_private *dev_priv);

View File

@ -113,17 +113,18 @@ static u32 hsw_infoframe_enable(enum hdmi_infoframe_type type)
} }
} }
static u32 hsw_infoframe_data_reg(enum hdmi_infoframe_type type, static u32 hsw_dip_data_reg(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder, enum transcoder cpu_transcoder,
struct drm_i915_private *dev_priv) enum hdmi_infoframe_type type,
int i)
{ {
switch (type) { switch (type) {
case HDMI_INFOFRAME_TYPE_AVI: case HDMI_INFOFRAME_TYPE_AVI:
return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder); return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder, i);
case HDMI_INFOFRAME_TYPE_SPD: case HDMI_INFOFRAME_TYPE_SPD:
return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder); return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder, i);
case HDMI_INFOFRAME_TYPE_VENDOR: case HDMI_INFOFRAME_TYPE_VENDOR:
return HSW_TVIDEO_DIP_VS_DATA(cpu_transcoder); return HSW_TVIDEO_DIP_VS_DATA(cpu_transcoder, i);
default: default:
DRM_DEBUG_DRIVER("unknown info frame type %d\n", type); DRM_DEBUG_DRIVER("unknown info frame type %d\n", type);
return 0; return 0;
@ -365,14 +366,13 @@ static void hsw_write_infoframe(struct drm_encoder *encoder,
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config->cpu_transcoder); enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
u32 ctl_reg = HSW_TVIDEO_DIP_CTL(cpu_transcoder);
u32 data_reg; u32 data_reg;
int i; int i;
u32 val = I915_READ(ctl_reg); u32 val = I915_READ(ctl_reg);
data_reg = hsw_infoframe_data_reg(type, data_reg = hsw_dip_data_reg(dev_priv, cpu_transcoder, type, 0);
intel_crtc->config->cpu_transcoder,
dev_priv);
if (data_reg == 0) if (data_reg == 0)
return; return;
@ -381,12 +381,14 @@ static void hsw_write_infoframe(struct drm_encoder *encoder,
mmiowb(); mmiowb();
for (i = 0; i < len; i += 4) { for (i = 0; i < len; i += 4) {
I915_WRITE(data_reg + i, *data); I915_WRITE(hsw_dip_data_reg(dev_priv, cpu_transcoder,
type, i >> 2), *data);
data++; data++;
} }
/* Write every possible data byte to force correct ECC calculation. */ /* Write every possible data byte to force correct ECC calculation. */
for (; i < VIDEO_DIP_DATA_SIZE; i += 4) for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
I915_WRITE(data_reg + i, 0); I915_WRITE(hsw_dip_data_reg(dev_priv, cpu_transcoder,
type, i >> 2), 0);
mmiowb(); mmiowb();
val |= hsw_infoframe_enable(type); val |= hsw_infoframe_enable(type);

View File

@ -114,8 +114,8 @@ intel_i2c_reset(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
I915_WRITE(dev_priv->gpio_mmio_base + GMBUS0, 0); I915_WRITE(GMBUS0, 0);
I915_WRITE(dev_priv->gpio_mmio_base + GMBUS4, 0); I915_WRITE(GMBUS4, 0);
} }
static void intel_i2c_quirk_set(struct drm_i915_private *dev_priv, bool enable) static void intel_i2c_quirk_set(struct drm_i915_private *dev_priv, bool enable)
@ -261,7 +261,6 @@ gmbus_wait_hw_status(struct drm_i915_private *dev_priv,
u32 gmbus4_irq_en) u32 gmbus4_irq_en)
{ {
int i; int i;
int reg_offset = dev_priv->gpio_mmio_base;
u32 gmbus2 = 0; u32 gmbus2 = 0;
DEFINE_WAIT(wait); DEFINE_WAIT(wait);
@ -271,13 +270,13 @@ gmbus_wait_hw_status(struct drm_i915_private *dev_priv,
/* Important: The hw handles only the first bit, so set only one! Since /* Important: The hw handles only the first bit, so set only one! Since
* we also need to check for NAKs besides the hw ready/idle signal, we * we also need to check for NAKs besides the hw ready/idle signal, we
* need to wake up periodically and check that ourselves. */ * need to wake up periodically and check that ourselves. */
I915_WRITE(GMBUS4 + reg_offset, gmbus4_irq_en); I915_WRITE(GMBUS4, gmbus4_irq_en);
for (i = 0; i < msecs_to_jiffies_timeout(50); i++) { for (i = 0; i < msecs_to_jiffies_timeout(50); i++) {
prepare_to_wait(&dev_priv->gmbus_wait_queue, &wait, prepare_to_wait(&dev_priv->gmbus_wait_queue, &wait,
TASK_UNINTERRUPTIBLE); TASK_UNINTERRUPTIBLE);
gmbus2 = I915_READ_NOTRACE(GMBUS2 + reg_offset); gmbus2 = I915_READ_NOTRACE(GMBUS2);
if (gmbus2 & (GMBUS_SATOER | gmbus2_status)) if (gmbus2 & (GMBUS_SATOER | gmbus2_status))
break; break;
@ -285,7 +284,7 @@ gmbus_wait_hw_status(struct drm_i915_private *dev_priv,
} }
finish_wait(&dev_priv->gmbus_wait_queue, &wait); finish_wait(&dev_priv->gmbus_wait_queue, &wait);
I915_WRITE(GMBUS4 + reg_offset, 0); I915_WRITE(GMBUS4, 0);
if (gmbus2 & GMBUS_SATOER) if (gmbus2 & GMBUS_SATOER)
return -ENXIO; return -ENXIO;
@ -298,20 +297,19 @@ static int
gmbus_wait_idle(struct drm_i915_private *dev_priv) gmbus_wait_idle(struct drm_i915_private *dev_priv)
{ {
int ret; int ret;
int reg_offset = dev_priv->gpio_mmio_base;
#define C ((I915_READ_NOTRACE(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0) #define C ((I915_READ_NOTRACE(GMBUS2) & GMBUS_ACTIVE) == 0)
if (!HAS_GMBUS_IRQ(dev_priv->dev)) if (!HAS_GMBUS_IRQ(dev_priv->dev))
return wait_for(C, 10); return wait_for(C, 10);
/* Important: The hw handles only the first bit, so set only one! */ /* Important: The hw handles only the first bit, so set only one! */
I915_WRITE(GMBUS4 + reg_offset, GMBUS_IDLE_EN); I915_WRITE(GMBUS4, GMBUS_IDLE_EN);
ret = wait_event_timeout(dev_priv->gmbus_wait_queue, C, ret = wait_event_timeout(dev_priv->gmbus_wait_queue, C,
msecs_to_jiffies_timeout(10)); msecs_to_jiffies_timeout(10));
I915_WRITE(GMBUS4 + reg_offset, 0); I915_WRITE(GMBUS4, 0);
if (ret) if (ret)
return 0; return 0;
@ -325,9 +323,7 @@ gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv,
unsigned short addr, u8 *buf, unsigned int len, unsigned short addr, u8 *buf, unsigned int len,
u32 gmbus1_index) u32 gmbus1_index)
{ {
int reg_offset = dev_priv->gpio_mmio_base; I915_WRITE(GMBUS1,
I915_WRITE(GMBUS1 + reg_offset,
gmbus1_index | gmbus1_index |
GMBUS_CYCLE_WAIT | GMBUS_CYCLE_WAIT |
(len << GMBUS_BYTE_COUNT_SHIFT) | (len << GMBUS_BYTE_COUNT_SHIFT) |
@ -342,7 +338,7 @@ gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv,
if (ret) if (ret)
return ret; return ret;
val = I915_READ(GMBUS3 + reg_offset); val = I915_READ(GMBUS3);
do { do {
*buf++ = val & 0xff; *buf++ = val & 0xff;
val >>= 8; val >>= 8;
@ -380,7 +376,6 @@ static int
gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv, gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv,
unsigned short addr, u8 *buf, unsigned int len) unsigned short addr, u8 *buf, unsigned int len)
{ {
int reg_offset = dev_priv->gpio_mmio_base;
unsigned int chunk_size = len; unsigned int chunk_size = len;
u32 val, loop; u32 val, loop;
@ -390,8 +385,8 @@ gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv,
len -= 1; len -= 1;
} }
I915_WRITE(GMBUS3 + reg_offset, val); I915_WRITE(GMBUS3, val);
I915_WRITE(GMBUS1 + reg_offset, I915_WRITE(GMBUS1,
GMBUS_CYCLE_WAIT | GMBUS_CYCLE_WAIT |
(chunk_size << GMBUS_BYTE_COUNT_SHIFT) | (chunk_size << GMBUS_BYTE_COUNT_SHIFT) |
(addr << GMBUS_SLAVE_ADDR_SHIFT) | (addr << GMBUS_SLAVE_ADDR_SHIFT) |
@ -404,7 +399,7 @@ gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv,
val |= *buf++ << (8 * loop); val |= *buf++ << (8 * loop);
} while (--len && ++loop < 4); } while (--len && ++loop < 4);
I915_WRITE(GMBUS3 + reg_offset, val); I915_WRITE(GMBUS3, val);
ret = gmbus_wait_hw_status(dev_priv, GMBUS_HW_RDY, ret = gmbus_wait_hw_status(dev_priv, GMBUS_HW_RDY,
GMBUS_HW_RDY_EN); GMBUS_HW_RDY_EN);
@ -452,7 +447,6 @@ gmbus_is_index_read(struct i2c_msg *msgs, int i, int num)
static int static int
gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs) gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
{ {
int reg_offset = dev_priv->gpio_mmio_base;
u32 gmbus1_index = 0; u32 gmbus1_index = 0;
u32 gmbus5 = 0; u32 gmbus5 = 0;
int ret; int ret;
@ -466,13 +460,13 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
/* GMBUS5 holds 16-bit index */ /* GMBUS5 holds 16-bit index */
if (gmbus5) if (gmbus5)
I915_WRITE(GMBUS5 + reg_offset, gmbus5); I915_WRITE(GMBUS5, gmbus5);
ret = gmbus_xfer_read(dev_priv, &msgs[1], gmbus1_index); ret = gmbus_xfer_read(dev_priv, &msgs[1], gmbus1_index);
/* Clear GMBUS5 after each index transfer */ /* Clear GMBUS5 after each index transfer */
if (gmbus5) if (gmbus5)
I915_WRITE(GMBUS5 + reg_offset, 0); I915_WRITE(GMBUS5, 0);
return ret; return ret;
} }
@ -486,7 +480,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
struct intel_gmbus, struct intel_gmbus,
adapter); adapter);
struct drm_i915_private *dev_priv = bus->dev_priv; struct drm_i915_private *dev_priv = bus->dev_priv;
int i = 0, inc, try = 0, reg_offset; int i = 0, inc, try = 0;
int ret = 0; int ret = 0;
intel_aux_display_runtime_get(dev_priv); intel_aux_display_runtime_get(dev_priv);
@ -497,10 +491,8 @@ gmbus_xfer(struct i2c_adapter *adapter,
goto out; goto out;
} }
reg_offset = dev_priv->gpio_mmio_base;
retry: retry:
I915_WRITE(GMBUS0 + reg_offset, bus->reg0); I915_WRITE(GMBUS0, bus->reg0);
for (; i < num; i += inc) { for (; i < num; i += inc) {
inc = 1; inc = 1;
@ -530,7 +522,7 @@ retry:
* a STOP on the very first cycle. To simplify the code we * a STOP on the very first cycle. To simplify the code we
* unconditionally generate the STOP condition with an additional gmbus * unconditionally generate the STOP condition with an additional gmbus
* cycle. */ * cycle. */
I915_WRITE(GMBUS1 + reg_offset, GMBUS_CYCLE_STOP | GMBUS_SW_RDY); I915_WRITE(GMBUS1, GMBUS_CYCLE_STOP | GMBUS_SW_RDY);
/* Mark the GMBUS interface as disabled after waiting for idle. /* Mark the GMBUS interface as disabled after waiting for idle.
* We will re-enable it at the start of the next xfer, * We will re-enable it at the start of the next xfer,
@ -541,7 +533,7 @@ retry:
adapter->name); adapter->name);
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
} }
I915_WRITE(GMBUS0 + reg_offset, 0); I915_WRITE(GMBUS0, 0);
ret = ret ?: i; ret = ret ?: i;
goto out; goto out;
@ -570,9 +562,9 @@ clear_err:
* of resetting the GMBUS controller and so clearing the * of resetting the GMBUS controller and so clearing the
* BUS_ERROR raised by the slave's NAK. * BUS_ERROR raised by the slave's NAK.
*/ */
I915_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT); I915_WRITE(GMBUS1, GMBUS_SW_CLR_INT);
I915_WRITE(GMBUS1 + reg_offset, 0); I915_WRITE(GMBUS1, 0);
I915_WRITE(GMBUS0 + reg_offset, 0); I915_WRITE(GMBUS0, 0);
DRM_DEBUG_KMS("GMBUS [%s] NAK for addr: %04x %c(%d)\n", DRM_DEBUG_KMS("GMBUS [%s] NAK for addr: %04x %c(%d)\n",
adapter->name, msgs[i].addr, adapter->name, msgs[i].addr,
@ -595,7 +587,7 @@ clear_err:
timeout: timeout:
DRM_INFO("GMBUS [%s] timed out, falling back to bit banging on pin %d\n", DRM_INFO("GMBUS [%s] timed out, falling back to bit banging on pin %d\n",
bus->adapter.name, bus->reg0 & 0xff); bus->adapter.name, bus->reg0 & 0xff);
I915_WRITE(GMBUS0 + reg_offset, 0); I915_WRITE(GMBUS0, 0);
/* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */ /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */
bus->force_bit = 1; bus->force_bit = 1;

View File

@ -98,15 +98,11 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
{ {
struct drm_device *dev = encoder->base.dev; struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 lvds_reg, tmp, flags = 0; struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
u32 tmp, flags = 0;
int dotclock; int dotclock;
if (HAS_PCH_SPLIT(dev)) tmp = I915_READ(lvds_encoder->reg);
lvds_reg = PCH_LVDS;
else
lvds_reg = LVDS;
tmp = I915_READ(lvds_reg);
if (tmp & LVDS_HSYNC_POLARITY) if (tmp & LVDS_HSYNC_POLARITY)
flags |= DRM_MODE_FLAG_NHSYNC; flags |= DRM_MODE_FLAG_NHSYNC;
else else
@ -943,6 +939,7 @@ void intel_lvds_init(struct drm_device *dev)
struct drm_display_mode *downclock_mode = NULL; struct drm_display_mode *downclock_mode = NULL;
struct edid *edid; struct edid *edid;
struct drm_crtc *crtc; struct drm_crtc *crtc;
u32 lvds_reg;
u32 lvds; u32 lvds;
int pipe; int pipe;
u8 pin; u8 pin;
@ -965,8 +962,15 @@ void intel_lvds_init(struct drm_device *dev)
if (dmi_check_system(intel_no_lvds)) if (dmi_check_system(intel_no_lvds))
return; return;
if (HAS_PCH_SPLIT(dev))
lvds_reg = PCH_LVDS;
else
lvds_reg = LVDS;
lvds = I915_READ(lvds_reg);
if (HAS_PCH_SPLIT(dev)) { if (HAS_PCH_SPLIT(dev)) {
if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) if ((lvds & LVDS_DETECTED) == 0)
return; return;
if (dev_priv->vbt.edp_support) { if (dev_priv->vbt.edp_support) {
DRM_DEBUG_KMS("disable LVDS for eDP support\n"); DRM_DEBUG_KMS("disable LVDS for eDP support\n");
@ -976,8 +980,7 @@ void intel_lvds_init(struct drm_device *dev)
pin = GMBUS_PIN_PANEL; pin = GMBUS_PIN_PANEL;
if (!lvds_is_present_in_vbt(dev, &pin)) { if (!lvds_is_present_in_vbt(dev, &pin)) {
u32 reg = HAS_PCH_SPLIT(dev) ? PCH_LVDS : LVDS; if ((lvds & LVDS_PORT_EN) == 0) {
if ((I915_READ(reg) & LVDS_PORT_EN) == 0) {
DRM_DEBUG_KMS("LVDS is not present in VBT\n"); DRM_DEBUG_KMS("LVDS is not present in VBT\n");
return; return;
} }
@ -1054,11 +1057,7 @@ void intel_lvds_init(struct drm_device *dev)
connector->interlace_allowed = false; connector->interlace_allowed = false;
connector->doublescan_allowed = false; connector->doublescan_allowed = false;
if (HAS_PCH_SPLIT(dev)) { lvds_encoder->reg = lvds_reg;
lvds_encoder->reg = PCH_LVDS;
} else {
lvds_encoder->reg = LVDS;
}
/* create the scaling mode property */ /* create the scaling mode property */
drm_mode_create_scaling_mode_property(dev); drm_mode_create_scaling_mode_property(dev);
@ -1139,7 +1138,6 @@ void intel_lvds_init(struct drm_device *dev)
if (HAS_PCH_SPLIT(dev)) if (HAS_PCH_SPLIT(dev))
goto failed; goto failed;
lvds = I915_READ(LVDS);
pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
crtc = intel_get_crtc_for_pipe(dev, pipe); crtc = intel_get_crtc_for_pipe(dev, pipe);

View File

@ -239,7 +239,7 @@ struct opregion_asle {
static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out) static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct opregion_swsci __iomem *swsci = dev_priv->opregion.swsci; struct opregion_swsci *swsci = dev_priv->opregion.swsci;
u32 main_function, sub_function, scic; u32 main_function, sub_function, scic;
u16 pci_swsci; u16 pci_swsci;
u32 dslp; u32 dslp;
@ -264,7 +264,7 @@ static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out)
} }
/* Driver sleep timeout in ms. */ /* Driver sleep timeout in ms. */
dslp = ioread32(&swsci->dslp); dslp = swsci->dslp;
if (!dslp) { if (!dslp) {
/* The spec says 2ms should be the default, but it's too small /* The spec says 2ms should be the default, but it's too small
* for some machines. */ * for some machines. */
@ -277,7 +277,7 @@ static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out)
} }
/* The spec tells us to do this, but we are the only user... */ /* The spec tells us to do this, but we are the only user... */
scic = ioread32(&swsci->scic); scic = swsci->scic;
if (scic & SWSCI_SCIC_INDICATOR) { if (scic & SWSCI_SCIC_INDICATOR) {
DRM_DEBUG_DRIVER("SWSCI request already in progress\n"); DRM_DEBUG_DRIVER("SWSCI request already in progress\n");
return -EBUSY; return -EBUSY;
@ -285,8 +285,8 @@ static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out)
scic = function | SWSCI_SCIC_INDICATOR; scic = function | SWSCI_SCIC_INDICATOR;
iowrite32(parm, &swsci->parm); swsci->parm = parm;
iowrite32(scic, &swsci->scic); swsci->scic = scic;
/* Ensure SCI event is selected and event trigger is cleared. */ /* Ensure SCI event is selected and event trigger is cleared. */
pci_read_config_word(dev->pdev, PCI_SWSCI, &pci_swsci); pci_read_config_word(dev->pdev, PCI_SWSCI, &pci_swsci);
@ -301,7 +301,7 @@ static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out)
pci_write_config_word(dev->pdev, PCI_SWSCI, pci_swsci); pci_write_config_word(dev->pdev, PCI_SWSCI, pci_swsci);
/* Poll for the result. */ /* Poll for the result. */
#define C (((scic = ioread32(&swsci->scic)) & SWSCI_SCIC_INDICATOR) == 0) #define C (((scic = swsci->scic) & SWSCI_SCIC_INDICATOR) == 0)
if (wait_for(C, dslp)) { if (wait_for(C, dslp)) {
DRM_DEBUG_DRIVER("SWSCI request timed out\n"); DRM_DEBUG_DRIVER("SWSCI request timed out\n");
return -ETIMEDOUT; return -ETIMEDOUT;
@ -317,7 +317,7 @@ static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out)
} }
if (parm_out) if (parm_out)
*parm_out = ioread32(&swsci->parm); *parm_out = swsci->parm;
return 0; return 0;
@ -412,7 +412,7 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_connector *intel_connector; struct intel_connector *intel_connector;
struct opregion_asle __iomem *asle = dev_priv->opregion.asle; struct opregion_asle *asle = dev_priv->opregion.asle;
DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp); DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp);
@ -437,7 +437,7 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp); DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp);
list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head) list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head)
intel_panel_set_backlight_acpi(intel_connector, bclp, 255); intel_panel_set_backlight_acpi(intel_connector, bclp, 255);
iowrite32(DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID, &asle->cblv); asle->cblv = DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID;
drm_modeset_unlock(&dev->mode_config.connection_mutex); drm_modeset_unlock(&dev->mode_config.connection_mutex);
@ -524,14 +524,14 @@ static void asle_work(struct work_struct *work)
struct drm_i915_private *dev_priv = struct drm_i915_private *dev_priv =
container_of(opregion, struct drm_i915_private, opregion); container_of(opregion, struct drm_i915_private, opregion);
struct drm_device *dev = dev_priv->dev; struct drm_device *dev = dev_priv->dev;
struct opregion_asle __iomem *asle = dev_priv->opregion.asle; struct opregion_asle *asle = dev_priv->opregion.asle;
u32 aslc_stat = 0; u32 aslc_stat = 0;
u32 aslc_req; u32 aslc_req;
if (!asle) if (!asle)
return; return;
aslc_req = ioread32(&asle->aslc); aslc_req = asle->aslc;
if (!(aslc_req & ASLC_REQ_MSK)) { if (!(aslc_req & ASLC_REQ_MSK)) {
DRM_DEBUG_DRIVER("No request on ASLC interrupt 0x%08x\n", DRM_DEBUG_DRIVER("No request on ASLC interrupt 0x%08x\n",
@ -540,34 +540,34 @@ static void asle_work(struct work_struct *work)
} }
if (aslc_req & ASLC_SET_ALS_ILLUM) if (aslc_req & ASLC_SET_ALS_ILLUM)
aslc_stat |= asle_set_als_illum(dev, ioread32(&asle->alsi)); aslc_stat |= asle_set_als_illum(dev, asle->alsi);
if (aslc_req & ASLC_SET_BACKLIGHT) if (aslc_req & ASLC_SET_BACKLIGHT)
aslc_stat |= asle_set_backlight(dev, ioread32(&asle->bclp)); aslc_stat |= asle_set_backlight(dev, asle->bclp);
if (aslc_req & ASLC_SET_PFIT) if (aslc_req & ASLC_SET_PFIT)
aslc_stat |= asle_set_pfit(dev, ioread32(&asle->pfit)); aslc_stat |= asle_set_pfit(dev, asle->pfit);
if (aslc_req & ASLC_SET_PWM_FREQ) if (aslc_req & ASLC_SET_PWM_FREQ)
aslc_stat |= asle_set_pwm_freq(dev, ioread32(&asle->pfmb)); aslc_stat |= asle_set_pwm_freq(dev, asle->pfmb);
if (aslc_req & ASLC_SUPPORTED_ROTATION_ANGLES) if (aslc_req & ASLC_SUPPORTED_ROTATION_ANGLES)
aslc_stat |= asle_set_supported_rotation_angles(dev, aslc_stat |= asle_set_supported_rotation_angles(dev,
ioread32(&asle->srot)); asle->srot);
if (aslc_req & ASLC_BUTTON_ARRAY) if (aslc_req & ASLC_BUTTON_ARRAY)
aslc_stat |= asle_set_button_array(dev, ioread32(&asle->iuer)); aslc_stat |= asle_set_button_array(dev, asle->iuer);
if (aslc_req & ASLC_CONVERTIBLE_INDICATOR) if (aslc_req & ASLC_CONVERTIBLE_INDICATOR)
aslc_stat |= asle_set_convertible(dev, ioread32(&asle->iuer)); aslc_stat |= asle_set_convertible(dev, asle->iuer);
if (aslc_req & ASLC_DOCKING_INDICATOR) if (aslc_req & ASLC_DOCKING_INDICATOR)
aslc_stat |= asle_set_docking(dev, ioread32(&asle->iuer)); aslc_stat |= asle_set_docking(dev, asle->iuer);
if (aslc_req & ASLC_ISCT_STATE_CHANGE) if (aslc_req & ASLC_ISCT_STATE_CHANGE)
aslc_stat |= asle_isct_state(dev); aslc_stat |= asle_isct_state(dev);
iowrite32(aslc_stat, &asle->aslc); asle->aslc = aslc_stat;
} }
void intel_opregion_asle_intr(struct drm_device *dev) void intel_opregion_asle_intr(struct drm_device *dev)
@ -592,8 +592,8 @@ static int intel_opregion_video_event(struct notifier_block *nb,
Linux, these are handled by the dock, button and video drivers. Linux, these are handled by the dock, button and video drivers.
*/ */
struct opregion_acpi __iomem *acpi;
struct acpi_bus_event *event = data; struct acpi_bus_event *event = data;
struct opregion_acpi *acpi;
int ret = NOTIFY_OK; int ret = NOTIFY_OK;
if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0) if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
@ -604,11 +604,10 @@ static int intel_opregion_video_event(struct notifier_block *nb,
acpi = system_opregion->acpi; acpi = system_opregion->acpi;
if (event->type == 0x80 && if (event->type == 0x80 && ((acpi->cevt & 1) == 0))
(ioread32(&acpi->cevt) & 1) == 0)
ret = NOTIFY_BAD; ret = NOTIFY_BAD;
iowrite32(0, &acpi->csts); acpi->csts = 0;
return ret; return ret;
} }
@ -628,14 +627,14 @@ static u32 get_did(struct intel_opregion *opregion, int i)
u32 did; u32 did;
if (i < ARRAY_SIZE(opregion->acpi->didl)) { if (i < ARRAY_SIZE(opregion->acpi->didl)) {
did = ioread32(&opregion->acpi->didl[i]); did = opregion->acpi->didl[i];
} else { } else {
i -= ARRAY_SIZE(opregion->acpi->didl); i -= ARRAY_SIZE(opregion->acpi->didl);
if (WARN_ON(i >= ARRAY_SIZE(opregion->acpi->did2))) if (WARN_ON(i >= ARRAY_SIZE(opregion->acpi->did2)))
return 0; return 0;
did = ioread32(&opregion->acpi->did2[i]); did = opregion->acpi->did2[i];
} }
return did; return did;
@ -644,14 +643,14 @@ static u32 get_did(struct intel_opregion *opregion, int i)
static void set_did(struct intel_opregion *opregion, int i, u32 val) static void set_did(struct intel_opregion *opregion, int i, u32 val)
{ {
if (i < ARRAY_SIZE(opregion->acpi->didl)) { if (i < ARRAY_SIZE(opregion->acpi->didl)) {
iowrite32(val, &opregion->acpi->didl[i]); opregion->acpi->didl[i] = val;
} else { } else {
i -= ARRAY_SIZE(opregion->acpi->didl); i -= ARRAY_SIZE(opregion->acpi->didl);
if (WARN_ON(i >= ARRAY_SIZE(opregion->acpi->did2))) if (WARN_ON(i >= ARRAY_SIZE(opregion->acpi->did2)))
return; return;
iowrite32(val, &opregion->acpi->did2[i]); opregion->acpi->did2[i] = val;
} }
} }
@ -773,7 +772,7 @@ static void intel_setup_cadls(struct drm_device *dev)
* there are less than eight devices. */ * there are less than eight devices. */
do { do {
disp_id = get_did(opregion, i); disp_id = get_did(opregion, i);
iowrite32(disp_id, &opregion->acpi->cadl[i]); opregion->acpi->cadl[i] = disp_id;
} while (++i < 8 && disp_id != 0); } while (++i < 8 && disp_id != 0);
} }
@ -792,16 +791,16 @@ void intel_opregion_init(struct drm_device *dev)
/* Notify BIOS we are ready to handle ACPI video ext notifs. /* Notify BIOS we are ready to handle ACPI video ext notifs.
* Right now, all the events are handled by the ACPI video module. * Right now, all the events are handled by the ACPI video module.
* We don't actually need to do anything with them. */ * We don't actually need to do anything with them. */
iowrite32(0, &opregion->acpi->csts); opregion->acpi->csts = 0;
iowrite32(1, &opregion->acpi->drdy); opregion->acpi->drdy = 1;
system_opregion = opregion; system_opregion = opregion;
register_acpi_notifier(&intel_opregion_notifier); register_acpi_notifier(&intel_opregion_notifier);
} }
if (opregion->asle) { if (opregion->asle) {
iowrite32(ASLE_TCHE_BLC_EN, &opregion->asle->tche); opregion->asle->tche = ASLE_TCHE_BLC_EN;
iowrite32(ASLE_ARDY_READY, &opregion->asle->ardy); opregion->asle->ardy = ASLE_ARDY_READY;
} }
} }
@ -814,19 +813,19 @@ void intel_opregion_fini(struct drm_device *dev)
return; return;
if (opregion->asle) if (opregion->asle)
iowrite32(ASLE_ARDY_NOT_READY, &opregion->asle->ardy); opregion->asle->ardy = ASLE_ARDY_NOT_READY;
cancel_work_sync(&dev_priv->opregion.asle_work); cancel_work_sync(&dev_priv->opregion.asle_work);
if (opregion->acpi) { if (opregion->acpi) {
iowrite32(0, &opregion->acpi->drdy); opregion->acpi->drdy = 0;
system_opregion = NULL; system_opregion = NULL;
unregister_acpi_notifier(&intel_opregion_notifier); unregister_acpi_notifier(&intel_opregion_notifier);
} }
/* just clear all opregion memory pointers now */ /* just clear all opregion memory pointers now */
iounmap(opregion->header); memunmap(opregion->header);
opregion->header = NULL; opregion->header = NULL;
opregion->acpi = NULL; opregion->acpi = NULL;
opregion->swsci = NULL; opregion->swsci = NULL;
@ -899,10 +898,10 @@ int intel_opregion_setup(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_opregion *opregion = &dev_priv->opregion; struct intel_opregion *opregion = &dev_priv->opregion;
void __iomem *base;
u32 asls, mboxes; u32 asls, mboxes;
char buf[sizeof(OPREGION_SIGNATURE)]; char buf[sizeof(OPREGION_SIGNATURE)];
int err = 0; int err = 0;
void *base;
BUILD_BUG_ON(sizeof(struct opregion_header) != 0x100); BUILD_BUG_ON(sizeof(struct opregion_header) != 0x100);
BUILD_BUG_ON(sizeof(struct opregion_acpi) != 0x100); BUILD_BUG_ON(sizeof(struct opregion_acpi) != 0x100);
@ -920,11 +919,11 @@ int intel_opregion_setup(struct drm_device *dev)
INIT_WORK(&opregion->asle_work, asle_work); INIT_WORK(&opregion->asle_work, asle_work);
#endif #endif
base = acpi_os_ioremap(asls, OPREGION_SIZE); base = memremap(asls, OPREGION_SIZE, MEMREMAP_WB);
if (!base) if (!base)
return -ENOMEM; return -ENOMEM;
memcpy_fromio(buf, base, sizeof(buf)); memcpy(buf, base, sizeof(buf));
if (memcmp(buf, OPREGION_SIGNATURE, 16)) { if (memcmp(buf, OPREGION_SIGNATURE, 16)) {
DRM_DEBUG_DRIVER("opregion signature mismatch\n"); DRM_DEBUG_DRIVER("opregion signature mismatch\n");
@ -936,7 +935,7 @@ int intel_opregion_setup(struct drm_device *dev)
opregion->lid_state = base + ACPI_CLID; opregion->lid_state = base + ACPI_CLID;
mboxes = ioread32(&opregion->header->mboxes); mboxes = opregion->header->mboxes;
if (mboxes & MBOX_ACPI) { if (mboxes & MBOX_ACPI) {
DRM_DEBUG_DRIVER("Public ACPI methods supported\n"); DRM_DEBUG_DRIVER("Public ACPI methods supported\n");
opregion->acpi = base + OPREGION_ACPI_OFFSET; opregion->acpi = base + OPREGION_ACPI_OFFSET;
@ -951,12 +950,12 @@ int intel_opregion_setup(struct drm_device *dev)
DRM_DEBUG_DRIVER("ASLE supported\n"); DRM_DEBUG_DRIVER("ASLE supported\n");
opregion->asle = base + OPREGION_ASLE_OFFSET; opregion->asle = base + OPREGION_ASLE_OFFSET;
iowrite32(ASLE_ARDY_NOT_READY, &opregion->asle->ardy); opregion->asle->ardy = ASLE_ARDY_NOT_READY;
} }
return 0; return 0;
err_out: err_out:
iounmap(base); memunmap(base);
return err; return err;
} }

View File

@ -381,7 +381,7 @@ intel_panel_detect(struct drm_device *dev)
/* Assume that the BIOS does not lie through the OpRegion... */ /* Assume that the BIOS does not lie through the OpRegion... */
if (!i915.panel_ignore_lid && dev_priv->opregion.lid_state) { if (!i915.panel_ignore_lid && dev_priv->opregion.lid_state) {
return ioread32(dev_priv->opregion.lid_state) & 0x1 ? return *dev_priv->opregion.lid_state & 0x1 ?
connector_status_connected : connector_status_connected :
connector_status_disconnected; connector_status_disconnected;
} }

View File

@ -52,56 +52,10 @@
#define INTEL_RC6p_ENABLE (1<<1) #define INTEL_RC6p_ENABLE (1<<1)
#define INTEL_RC6pp_ENABLE (1<<2) #define INTEL_RC6pp_ENABLE (1<<2)
static void gen9_init_clock_gating(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
/* WaEnableLbsSlaRetryTimerDecrement:skl */
I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) |
GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE);
/* WaDisableKillLogic:bxt,skl */
I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
ECOCHK_DIS_TLB);
}
static void skl_init_clock_gating(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
gen9_init_clock_gating(dev);
if (INTEL_REVID(dev) <= SKL_REVID_D0) {
/* WaDisableHDCInvalidation:skl */
I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
BDW_DISABLE_HDC_INVALIDATION);
/* WaDisableChickenBitTSGBarrierAckForFFSliceCS:skl */
I915_WRITE(FF_SLICE_CS_CHICKEN2,
_MASKED_BIT_ENABLE(GEN9_TSG_BARRIER_ACK_DISABLE));
}
/* GEN8_L3SQCREG4 has a dependency with WA batch so any new changes
* involving this register should also be added to WA batch as required.
*/
if (INTEL_REVID(dev) <= SKL_REVID_E0)
/* WaDisableLSQCROPERFforOCL:skl */
I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) |
GEN8_LQSC_RO_PERF_DIS);
/* WaEnableGapsTsvCreditFix:skl */
if (IS_SKYLAKE(dev) && (INTEL_REVID(dev) >= SKL_REVID_C0)) {
I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
GEN9_GAPS_TSV_CREDIT_DISABLE));
}
}
static void bxt_init_clock_gating(struct drm_device *dev) static void bxt_init_clock_gating(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
gen9_init_clock_gating(dev);
/* WaDisableSDEUnitClockGating:bxt */ /* WaDisableSDEUnitClockGating:bxt */
I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
GEN8_SDEUNIT_CLOCK_GATE_DISABLE); GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
@ -112,17 +66,6 @@ static void bxt_init_clock_gating(struct drm_device *dev)
*/ */
I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ);
/* WaStoreMultiplePTEenable:bxt */
/* This is a requirement according to Hardware specification */
if (INTEL_REVID(dev) == BXT_REVID_A0)
I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF);
/* WaSetClckGatingDisableMedia:bxt */
if (INTEL_REVID(dev) == BXT_REVID_A0) {
I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) &
~GEN8_DOP_CLOCK_GATE_MEDIA_ENABLE));
}
} }
static void i915_pineview_get_mem_freq(struct drm_device *dev) static void i915_pineview_get_mem_freq(struct drm_device *dev)
@ -1765,6 +1708,13 @@ static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels,
return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2; return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2;
} }
struct skl_pipe_wm_parameters {
bool active;
uint32_t pipe_htotal;
uint32_t pixel_rate; /* in KHz */
struct intel_plane_wm_parameters plane[I915_MAX_PLANES];
};
struct ilk_wm_maximums { struct ilk_wm_maximums {
uint16_t pri; uint16_t pri;
uint16_t spr; uint16_t spr;
@ -2805,40 +2755,18 @@ static bool ilk_disable_lp_wm(struct drm_device *dev)
#define SKL_DDB_SIZE 896 /* in blocks */ #define SKL_DDB_SIZE 896 /* in blocks */
#define BXT_DDB_SIZE 512 #define BXT_DDB_SIZE 512
/*
* Return the index of a plane in the SKL DDB and wm result arrays. Primary
* plane is always in slot 0, cursor is always in slot I915_MAX_PLANES-1, and
* other universal planes are in indices 1..n. Note that this may leave unused
* indices between the top "sprite" plane and the cursor.
*/
static int
skl_wm_plane_id(const struct intel_plane *plane)
{
switch (plane->base.type) {
case DRM_PLANE_TYPE_PRIMARY:
return 0;
case DRM_PLANE_TYPE_CURSOR:
return PLANE_CURSOR;
case DRM_PLANE_TYPE_OVERLAY:
return plane->plane + 1;
default:
MISSING_CASE(plane->base.type);
return plane->plane;
}
}
static void static void
skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
const struct intel_crtc_state *cstate, struct drm_crtc *for_crtc,
const struct intel_wm_config *config, const struct intel_wm_config *config,
const struct skl_pipe_wm_parameters *params,
struct skl_ddb_entry *alloc /* out */) struct skl_ddb_entry *alloc /* out */)
{ {
struct drm_crtc *for_crtc = cstate->base.crtc;
struct drm_crtc *crtc; struct drm_crtc *crtc;
unsigned int pipe_size, ddb_size; unsigned int pipe_size, ddb_size;
int nth_active_pipe; int nth_active_pipe;
if (!cstate->base.active) { if (!params->active) {
alloc->start = 0; alloc->start = 0;
alloc->end = 0; alloc->end = 0;
return; return;
@ -2904,29 +2832,19 @@ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
} }
static unsigned int static unsigned int
skl_plane_relative_data_rate(const struct intel_crtc_state *cstate, skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p, int y)
const struct drm_plane_state *pstate,
int y)
{ {
struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
struct drm_framebuffer *fb = pstate->fb;
/* for planar format */ /* for planar format */
if (fb->pixel_format == DRM_FORMAT_NV12) { if (p->y_bytes_per_pixel) {
if (y) /* y-plane data rate */ if (y) /* y-plane data rate */
return intel_crtc->config->pipe_src_w * return p->horiz_pixels * p->vert_pixels * p->y_bytes_per_pixel;
intel_crtc->config->pipe_src_h *
drm_format_plane_cpp(fb->pixel_format, 0);
else /* uv-plane data rate */ else /* uv-plane data rate */
return (intel_crtc->config->pipe_src_w/2) * return (p->horiz_pixels/2) * (p->vert_pixels/2) * p->bytes_per_pixel;
(intel_crtc->config->pipe_src_h/2) *
drm_format_plane_cpp(fb->pixel_format, 1);
} }
/* for packed formats */ /* for packed formats */
return intel_crtc->config->pipe_src_w * return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel;
intel_crtc->config->pipe_src_h *
drm_format_plane_cpp(fb->pixel_format, 0);
} }
/* /*
@ -2935,51 +2853,46 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
* 3 * 4096 * 8192 * 4 < 2^32 * 3 * 4096 * 8192 * 4 < 2^32
*/ */
static unsigned int static unsigned int
skl_get_total_relative_data_rate(const struct intel_crtc_state *cstate) skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc,
const struct skl_pipe_wm_parameters *params)
{ {
struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
struct drm_device *dev = intel_crtc->base.dev;
const struct intel_plane *intel_plane;
unsigned int total_data_rate = 0; unsigned int total_data_rate = 0;
int plane;
for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
const struct drm_plane_state *pstate = intel_plane->base.state; const struct intel_plane_wm_parameters *p;
if (pstate->fb == NULL) p = &params->plane[plane];
if (!p->enabled)
continue; continue;
/* packed/uv */ total_data_rate += skl_plane_relative_data_rate(p, 0); /* packed/uv */
total_data_rate += skl_plane_relative_data_rate(cstate, if (p->y_bytes_per_pixel) {
pstate, total_data_rate += skl_plane_relative_data_rate(p, 1); /* y-plane */
0); }
if (pstate->fb->pixel_format == DRM_FORMAT_NV12)
/* y-plane */
total_data_rate += skl_plane_relative_data_rate(cstate,
pstate,
1);
} }
return total_data_rate; return total_data_rate;
} }
static void static void
skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, skl_allocate_pipe_ddb(struct drm_crtc *crtc,
const struct intel_wm_config *config, const struct intel_wm_config *config,
const struct skl_pipe_wm_parameters *params,
struct skl_ddb_allocation *ddb /* out */) struct skl_ddb_allocation *ddb /* out */)
{ {
struct drm_crtc *crtc = cstate->base.crtc;
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_plane *intel_plane;
enum pipe pipe = intel_crtc->pipe; enum pipe pipe = intel_crtc->pipe;
struct skl_ddb_entry *alloc = &ddb->pipe[pipe]; struct skl_ddb_entry *alloc = &ddb->pipe[pipe];
uint16_t alloc_size, start, cursor_blocks; uint16_t alloc_size, start, cursor_blocks;
uint16_t minimum[I915_MAX_PLANES]; uint16_t minimum[I915_MAX_PLANES];
uint16_t y_minimum[I915_MAX_PLANES]; uint16_t y_minimum[I915_MAX_PLANES];
unsigned int total_data_rate; unsigned int total_data_rate;
int plane;
skl_ddb_get_pipe_allocation_limits(dev, cstate, config, alloc); skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, alloc);
alloc_size = skl_ddb_entry_size(alloc); alloc_size = skl_ddb_entry_size(alloc);
if (alloc_size == 0) { if (alloc_size == 0) {
memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
@ -2996,20 +2909,17 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
alloc->end -= cursor_blocks; alloc->end -= cursor_blocks;
/* 1. Allocate the mininum required blocks for each active plane */ /* 1. Allocate the mininum required blocks for each active plane */
for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { for_each_plane(dev_priv, pipe, plane) {
struct drm_plane *plane = &intel_plane->base; const struct intel_plane_wm_parameters *p;
struct drm_framebuffer *fb = plane->fb;
int id = skl_wm_plane_id(intel_plane);
if (fb == NULL) p = &params->plane[plane];
continue; if (!p->enabled)
if (plane->type == DRM_PLANE_TYPE_CURSOR)
continue; continue;
minimum[id] = 8; minimum[plane] = 8;
alloc_size -= minimum[id]; alloc_size -= minimum[plane];
y_minimum[id] = (fb->pixel_format == DRM_FORMAT_NV12) ? 8 : 0; y_minimum[plane] = p->y_bytes_per_pixel ? 8 : 0;
alloc_size -= y_minimum[id]; alloc_size -= y_minimum[plane];
} }
/* /*
@ -3018,50 +2928,45 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
* *
* FIXME: we may not allocate every single block here. * FIXME: we may not allocate every single block here.
*/ */
total_data_rate = skl_get_total_relative_data_rate(cstate); total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params);
start = alloc->start; start = alloc->start;
for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
struct drm_plane *plane = &intel_plane->base; const struct intel_plane_wm_parameters *p;
struct drm_plane_state *pstate = intel_plane->base.state;
unsigned int data_rate, y_data_rate; unsigned int data_rate, y_data_rate;
uint16_t plane_blocks, y_plane_blocks = 0; uint16_t plane_blocks, y_plane_blocks = 0;
int id = skl_wm_plane_id(intel_plane);
if (pstate->fb == NULL) p = &params->plane[plane];
continue; if (!p->enabled)
if (plane->type == DRM_PLANE_TYPE_CURSOR)
continue; continue;
data_rate = skl_plane_relative_data_rate(cstate, pstate, 0); data_rate = skl_plane_relative_data_rate(p, 0);
/* /*
* allocation for (packed formats) or (uv-plane part of planar format): * allocation for (packed formats) or (uv-plane part of planar format):
* promote the expression to 64 bits to avoid overflowing, the * promote the expression to 64 bits to avoid overflowing, the
* result is < available as data_rate / total_data_rate < 1 * result is < available as data_rate / total_data_rate < 1
*/ */
plane_blocks = minimum[id]; plane_blocks = minimum[plane];
plane_blocks += div_u64((uint64_t)alloc_size * data_rate, plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
total_data_rate); total_data_rate);
ddb->plane[pipe][id].start = start; ddb->plane[pipe][plane].start = start;
ddb->plane[pipe][id].end = start + plane_blocks; ddb->plane[pipe][plane].end = start + plane_blocks;
start += plane_blocks; start += plane_blocks;
/* /*
* allocation for y_plane part of planar format: * allocation for y_plane part of planar format:
*/ */
if (pstate->fb->pixel_format == DRM_FORMAT_NV12) { if (p->y_bytes_per_pixel) {
y_data_rate = skl_plane_relative_data_rate(cstate, y_data_rate = skl_plane_relative_data_rate(p, 1);
pstate, y_plane_blocks = y_minimum[plane];
1);
y_plane_blocks = y_minimum[id];
y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate, y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate,
total_data_rate); total_data_rate);
ddb->y_plane[pipe][id].start = start; ddb->y_plane[pipe][plane].start = start;
ddb->y_plane[pipe][id].end = start + y_plane_blocks; ddb->y_plane[pipe][plane].end = start + y_plane_blocks;
start += y_plane_blocks; start += y_plane_blocks;
} }
@ -3148,21 +3053,87 @@ static void skl_compute_wm_global_parameters(struct drm_device *dev,
struct intel_wm_config *config) struct intel_wm_config *config)
{ {
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_plane *plane;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
config->num_pipes_active += to_intel_crtc(crtc)->active; config->num_pipes_active += to_intel_crtc(crtc)->active;
/* FIXME: I don't think we need those two global parameters on SKL */
list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
struct intel_plane *intel_plane = to_intel_plane(plane);
config->sprites_enabled |= intel_plane->wm.enabled;
config->sprites_scaled |= intel_plane->wm.scaled;
}
}
static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
struct skl_pipe_wm_parameters *p)
{
struct drm_device *dev = crtc->dev;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
enum pipe pipe = intel_crtc->pipe;
struct drm_plane *plane;
struct drm_framebuffer *fb;
int i = 1; /* Index for sprite planes start */
p->active = intel_crtc->active;
if (p->active) {
p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
p->pixel_rate = skl_pipe_pixel_rate(intel_crtc->config);
fb = crtc->primary->state->fb;
/* For planar: Bpp is for uv plane, y_Bpp is for y plane */
if (fb) {
p->plane[0].enabled = true;
p->plane[0].bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ?
drm_format_plane_cpp(fb->pixel_format, 1) :
drm_format_plane_cpp(fb->pixel_format, 0);
p->plane[0].y_bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ?
drm_format_plane_cpp(fb->pixel_format, 0) : 0;
p->plane[0].tiling = fb->modifier[0];
} else {
p->plane[0].enabled = false;
p->plane[0].bytes_per_pixel = 0;
p->plane[0].y_bytes_per_pixel = 0;
p->plane[0].tiling = DRM_FORMAT_MOD_NONE;
}
p->plane[0].horiz_pixels = intel_crtc->config->pipe_src_w;
p->plane[0].vert_pixels = intel_crtc->config->pipe_src_h;
p->plane[0].rotation = crtc->primary->state->rotation;
fb = crtc->cursor->state->fb;
p->plane[PLANE_CURSOR].y_bytes_per_pixel = 0;
if (fb) {
p->plane[PLANE_CURSOR].enabled = true;
p->plane[PLANE_CURSOR].bytes_per_pixel = fb->bits_per_pixel / 8;
p->plane[PLANE_CURSOR].horiz_pixels = crtc->cursor->state->crtc_w;
p->plane[PLANE_CURSOR].vert_pixels = crtc->cursor->state->crtc_h;
} else {
p->plane[PLANE_CURSOR].enabled = false;
p->plane[PLANE_CURSOR].bytes_per_pixel = 0;
p->plane[PLANE_CURSOR].horiz_pixels = 64;
p->plane[PLANE_CURSOR].vert_pixels = 64;
}
}
list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
struct intel_plane *intel_plane = to_intel_plane(plane);
if (intel_plane->pipe == pipe &&
plane->type == DRM_PLANE_TYPE_OVERLAY)
p->plane[i++] = intel_plane->wm;
}
} }
static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
struct intel_crtc_state *cstate, struct skl_pipe_wm_parameters *p,
struct intel_plane *intel_plane, struct intel_plane_wm_parameters *p_params,
uint16_t ddb_allocation, uint16_t ddb_allocation,
int level, int level,
uint16_t *out_blocks, /* out */ uint16_t *out_blocks, /* out */
uint8_t *out_lines /* out */) uint8_t *out_lines /* out */)
{ {
struct drm_plane *plane = &intel_plane->base;
struct drm_framebuffer *fb = plane->state->fb;
uint32_t latency = dev_priv->wm.skl_latency[level]; uint32_t latency = dev_priv->wm.skl_latency[level];
uint32_t method1, method2; uint32_t method1, method2;
uint32_t plane_bytes_per_line, plane_blocks_per_line; uint32_t plane_bytes_per_line, plane_blocks_per_line;
@ -3170,35 +3141,31 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
uint32_t selected_result; uint32_t selected_result;
uint8_t bytes_per_pixel; uint8_t bytes_per_pixel;
if (latency == 0 || !cstate->base.active || !fb) if (latency == 0 || !p->active || !p_params->enabled)
return false; return false;
bytes_per_pixel = (fb->pixel_format == DRM_FORMAT_NV12) ? bytes_per_pixel = p_params->y_bytes_per_pixel ?
drm_format_plane_cpp(DRM_FORMAT_NV12, 0) : p_params->y_bytes_per_pixel :
drm_format_plane_cpp(DRM_FORMAT_NV12, 1); p_params->bytes_per_pixel;
method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate), method1 = skl_wm_method1(p->pixel_rate,
bytes_per_pixel, bytes_per_pixel,
latency); latency);
method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate), method2 = skl_wm_method2(p->pixel_rate,
cstate->base.adjusted_mode.crtc_htotal, p->pipe_htotal,
cstate->pipe_src_w, p_params->horiz_pixels,
bytes_per_pixel, bytes_per_pixel,
fb->modifier[0], p_params->tiling,
latency); latency);
plane_bytes_per_line = cstate->pipe_src_w * bytes_per_pixel; plane_bytes_per_line = p_params->horiz_pixels * bytes_per_pixel;
plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || if (p_params->tiling == I915_FORMAT_MOD_Y_TILED ||
fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) { p_params->tiling == I915_FORMAT_MOD_Yf_TILED) {
uint32_t min_scanlines = 4; uint32_t min_scanlines = 4;
uint32_t y_tile_minimum; uint32_t y_tile_minimum;
if (intel_rotation_90_or_270(plane->state->rotation)) { if (intel_rotation_90_or_270(p_params->rotation)) {
int bpp = (fb->pixel_format == DRM_FORMAT_NV12) ? switch (p_params->bytes_per_pixel) {
drm_format_plane_cpp(fb->pixel_format, 1) :
drm_format_plane_cpp(fb->pixel_format, 0);
switch (bpp) {
case 1: case 1:
min_scanlines = 16; min_scanlines = 16;
break; break;
@ -3222,8 +3189,8 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line); res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line);
if (level >= 1 && level <= 7) { if (level >= 1 && level <= 7) {
if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || if (p_params->tiling == I915_FORMAT_MOD_Y_TILED ||
fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) p_params->tiling == I915_FORMAT_MOD_Yf_TILED)
res_lines += 4; res_lines += 4;
else else
res_blocks++; res_blocks++;
@ -3240,80 +3207,84 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
static void skl_compute_wm_level(const struct drm_i915_private *dev_priv, static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
struct skl_ddb_allocation *ddb, struct skl_ddb_allocation *ddb,
struct intel_crtc_state *cstate, struct skl_pipe_wm_parameters *p,
enum pipe pipe,
int level, int level,
int num_planes,
struct skl_wm_level *result) struct skl_wm_level *result)
{ {
struct drm_device *dev = dev_priv->dev;
struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
struct intel_plane *intel_plane;
uint16_t ddb_blocks; uint16_t ddb_blocks;
enum pipe pipe = intel_crtc->pipe; int i;
for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
int i = skl_wm_plane_id(intel_plane);
for (i = 0; i < num_planes; i++) {
ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]); ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
result->plane_en[i] = skl_compute_plane_wm(dev_priv, result->plane_en[i] = skl_compute_plane_wm(dev_priv,
cstate, p, &p->plane[i],
intel_plane,
ddb_blocks, ddb_blocks,
level, level,
&result->plane_res_b[i], &result->plane_res_b[i],
&result->plane_res_l[i]); &result->plane_res_l[i]);
} }
ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][PLANE_CURSOR]);
result->plane_en[PLANE_CURSOR] = skl_compute_plane_wm(dev_priv, p,
&p->plane[PLANE_CURSOR],
ddb_blocks, level,
&result->plane_res_b[PLANE_CURSOR],
&result->plane_res_l[PLANE_CURSOR]);
} }
static uint32_t static uint32_t
skl_compute_linetime_wm(struct intel_crtc_state *cstate) skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p)
{ {
if (!cstate->base.active) if (!to_intel_crtc(crtc)->active)
return 0; return 0;
if (WARN_ON(skl_pipe_pixel_rate(cstate) == 0)) if (WARN_ON(p->pixel_rate == 0))
return 0; return 0;
return DIV_ROUND_UP(8 * cstate->base.adjusted_mode.crtc_htotal * 1000, return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate);
skl_pipe_pixel_rate(cstate));
} }
static void skl_compute_transition_wm(struct intel_crtc_state *cstate, static void skl_compute_transition_wm(struct drm_crtc *crtc,
struct skl_pipe_wm_parameters *params,
struct skl_wm_level *trans_wm /* out */) struct skl_wm_level *trans_wm /* out */)
{ {
struct drm_crtc *crtc = cstate->base.crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_plane *intel_plane; int i;
if (!cstate->base.active) if (!params->active)
return; return;
/* Until we know more, just disable transition WMs */ /* Until we know more, just disable transition WMs */
for_each_intel_plane_on_crtc(crtc->dev, intel_crtc, intel_plane) { for (i = 0; i < intel_num_planes(intel_crtc); i++)
int i = skl_wm_plane_id(intel_plane);
trans_wm->plane_en[i] = false; trans_wm->plane_en[i] = false;
} trans_wm->plane_en[PLANE_CURSOR] = false;
} }
static void skl_compute_pipe_wm(struct intel_crtc_state *cstate, static void skl_compute_pipe_wm(struct drm_crtc *crtc,
struct skl_ddb_allocation *ddb, struct skl_ddb_allocation *ddb,
struct skl_pipe_wm_parameters *params,
struct skl_pipe_wm *pipe_wm) struct skl_pipe_wm *pipe_wm)
{ {
struct drm_device *dev = cstate->base.crtc->dev; struct drm_device *dev = crtc->dev;
const struct drm_i915_private *dev_priv = dev->dev_private; const struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int level, max_level = ilk_wm_max_level(dev); int level, max_level = ilk_wm_max_level(dev);
for (level = 0; level <= max_level; level++) { for (level = 0; level <= max_level; level++) {
skl_compute_wm_level(dev_priv, ddb, cstate, skl_compute_wm_level(dev_priv, ddb, params, intel_crtc->pipe,
level, &pipe_wm->wm[level]); level, intel_num_planes(intel_crtc),
&pipe_wm->wm[level]);
} }
pipe_wm->linetime = skl_compute_linetime_wm(cstate); pipe_wm->linetime = skl_compute_linetime_wm(crtc, params);
skl_compute_transition_wm(cstate, &pipe_wm->trans_wm); skl_compute_transition_wm(crtc, params, &pipe_wm->trans_wm);
} }
static void skl_compute_wm_results(struct drm_device *dev, static void skl_compute_wm_results(struct drm_device *dev,
struct skl_pipe_wm_parameters *p,
struct skl_pipe_wm *p_wm, struct skl_pipe_wm *p_wm,
struct skl_wm_values *r, struct skl_wm_values *r,
struct intel_crtc *intel_crtc) struct intel_crtc *intel_crtc)
@ -3557,15 +3528,16 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
} }
static bool skl_update_pipe_wm(struct drm_crtc *crtc, static bool skl_update_pipe_wm(struct drm_crtc *crtc,
struct skl_pipe_wm_parameters *params,
struct intel_wm_config *config, struct intel_wm_config *config,
struct skl_ddb_allocation *ddb, /* out */ struct skl_ddb_allocation *ddb, /* out */
struct skl_pipe_wm *pipe_wm /* out */) struct skl_pipe_wm *pipe_wm /* out */)
{ {
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
skl_allocate_pipe_ddb(cstate, config, ddb); skl_compute_wm_pipe_parameters(crtc, params);
skl_compute_pipe_wm(cstate, ddb, pipe_wm); skl_allocate_pipe_ddb(crtc, config, params, ddb);
skl_compute_pipe_wm(crtc, ddb, params, pipe_wm);
if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm))) if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
return false; return false;
@ -3598,6 +3570,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
*/ */
list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
base.head) { base.head) {
struct skl_pipe_wm_parameters params = {};
struct skl_pipe_wm pipe_wm = {}; struct skl_pipe_wm pipe_wm = {};
bool wm_changed; bool wm_changed;
@ -3607,7 +3580,8 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
if (!intel_crtc->active) if (!intel_crtc->active)
continue; continue;
wm_changed = skl_update_pipe_wm(&intel_crtc->base, config, wm_changed = skl_update_pipe_wm(&intel_crtc->base,
&params, config,
&r->ddb, &pipe_wm); &r->ddb, &pipe_wm);
/* /*
@ -3617,7 +3591,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
*/ */
WARN_ON(!wm_changed); WARN_ON(!wm_changed);
skl_compute_wm_results(dev, &pipe_wm, r, intel_crtc); skl_compute_wm_results(dev, &params, &pipe_wm, r, intel_crtc);
r->dirty[intel_crtc->pipe] = true; r->dirty[intel_crtc->pipe] = true;
} }
} }
@ -3647,6 +3621,7 @@ static void skl_update_wm(struct drm_crtc *crtc)
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct skl_pipe_wm_parameters params = {};
struct skl_wm_values *results = &dev_priv->wm.skl_results; struct skl_wm_values *results = &dev_priv->wm.skl_results;
struct skl_pipe_wm pipe_wm = {}; struct skl_pipe_wm pipe_wm = {};
struct intel_wm_config config = {}; struct intel_wm_config config = {};
@ -3659,10 +3634,11 @@ static void skl_update_wm(struct drm_crtc *crtc)
skl_compute_wm_global_parameters(dev, &config); skl_compute_wm_global_parameters(dev, &config);
if (!skl_update_pipe_wm(crtc, &config, &results->ddb, &pipe_wm)) if (!skl_update_pipe_wm(crtc, &params, &config,
&results->ddb, &pipe_wm))
return; return;
skl_compute_wm_results(dev, &pipe_wm, results, intel_crtc); skl_compute_wm_results(dev, &params, &pipe_wm, results, intel_crtc);
results->dirty[intel_crtc->pipe] = true; results->dirty[intel_crtc->pipe] = true;
skl_update_other_pipe_wm(dev, crtc, &config, results); skl_update_other_pipe_wm(dev, crtc, &config, results);
@ -3673,6 +3649,39 @@ static void skl_update_wm(struct drm_crtc *crtc)
dev_priv->wm.skl_hw = *results; dev_priv->wm.skl_hw = *results;
} }
static void
skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc,
uint32_t sprite_width, uint32_t sprite_height,
int pixel_size, bool enabled, bool scaled)
{
struct intel_plane *intel_plane = to_intel_plane(plane);
struct drm_framebuffer *fb = plane->state->fb;
intel_plane->wm.enabled = enabled;
intel_plane->wm.scaled = scaled;
intel_plane->wm.horiz_pixels = sprite_width;
intel_plane->wm.vert_pixels = sprite_height;
intel_plane->wm.tiling = DRM_FORMAT_MOD_NONE;
/* For planar: Bpp is for UV plane, y_Bpp is for Y plane */
intel_plane->wm.bytes_per_pixel =
(fb && fb->pixel_format == DRM_FORMAT_NV12) ?
drm_format_plane_cpp(plane->state->fb->pixel_format, 1) : pixel_size;
intel_plane->wm.y_bytes_per_pixel =
(fb && fb->pixel_format == DRM_FORMAT_NV12) ?
drm_format_plane_cpp(plane->state->fb->pixel_format, 0) : 0;
/*
* Framebuffer can be NULL on plane disable, but it does not
* matter for watermarks if we assume no tiling in that case.
*/
if (fb)
intel_plane->wm.tiling = fb->modifier[0];
intel_plane->wm.rotation = plane->state->rotation;
skl_update_wm(crtc);
}
static void ilk_update_wm(struct drm_crtc *crtc) static void ilk_update_wm(struct drm_crtc *crtc)
{ {
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@ -3688,18 +3697,6 @@ static void ilk_update_wm(struct drm_crtc *crtc)
WARN_ON(cstate->base.active != intel_crtc->active); WARN_ON(cstate->base.active != intel_crtc->active);
/*
* IVB workaround: must disable low power watermarks for at least
* one frame before enabling scaling. LP watermarks can be re-enabled
* when scaling is disabled.
*
* WaCxSRDisabledForSpriteScaling:ivb
*/
if (cstate->disable_lp_wm) {
ilk_disable_lp_wm(dev);
intel_wait_for_vblank(dev, intel_crtc->pipe);
}
intel_compute_pipe_wm(cstate, &pipe_wm); intel_compute_pipe_wm(cstate, &pipe_wm);
if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm))) if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
@ -3731,6 +3728,28 @@ static void ilk_update_wm(struct drm_crtc *crtc)
ilk_write_wm_values(dev_priv, &results); ilk_write_wm_values(dev_priv, &results);
} }
static void
ilk_update_sprite_wm(struct drm_plane *plane,
struct drm_crtc *crtc,
uint32_t sprite_width, uint32_t sprite_height,
int pixel_size, bool enabled, bool scaled)
{
struct drm_device *dev = plane->dev;
struct intel_plane *intel_plane = to_intel_plane(plane);
/*
* IVB workaround: must disable low power watermarks for at least
* one frame before enabling scaling. LP watermarks can be re-enabled
* when scaling is disabled.
*
* WaCxSRDisabledForSpriteScaling:ivb
*/
if (IS_IVYBRIDGE(dev) && scaled && ilk_disable_lp_wm(dev))
intel_wait_for_vblank(dev, intel_plane->pipe);
ilk_update_wm(crtc);
}
static void skl_pipe_wm_active_state(uint32_t val, static void skl_pipe_wm_active_state(uint32_t val,
struct skl_pipe_wm *active, struct skl_pipe_wm *active,
bool is_transwm, bool is_transwm,
@ -4108,6 +4127,21 @@ void intel_update_watermarks(struct drm_crtc *crtc)
dev_priv->display.update_wm(crtc); dev_priv->display.update_wm(crtc);
} }
void intel_update_sprite_watermarks(struct drm_plane *plane,
struct drm_crtc *crtc,
uint32_t sprite_width,
uint32_t sprite_height,
int pixel_size,
bool enabled, bool scaled)
{
struct drm_i915_private *dev_priv = plane->dev->dev_private;
if (dev_priv->display.update_sprite_wm)
dev_priv->display.update_sprite_wm(plane, crtc,
sprite_width, sprite_height,
pixel_size, enabled, scaled);
}
/** /**
* Lock protecting IPS related data structures * Lock protecting IPS related data structures
*/ */
@ -7018,10 +7052,8 @@ void intel_init_pm(struct drm_device *dev)
if (IS_BROXTON(dev)) if (IS_BROXTON(dev))
dev_priv->display.init_clock_gating = dev_priv->display.init_clock_gating =
bxt_init_clock_gating; bxt_init_clock_gating;
else if (IS_SKYLAKE(dev))
dev_priv->display.init_clock_gating =
skl_init_clock_gating;
dev_priv->display.update_wm = skl_update_wm; dev_priv->display.update_wm = skl_update_wm;
dev_priv->display.update_sprite_wm = skl_update_sprite_wm;
} else if (HAS_PCH_SPLIT(dev)) { } else if (HAS_PCH_SPLIT(dev)) {
ilk_setup_wm_latency(dev); ilk_setup_wm_latency(dev);
@ -7030,6 +7062,7 @@ void intel_init_pm(struct drm_device *dev)
(!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] && (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] &&
dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) { dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) {
dev_priv->display.update_wm = ilk_update_wm; dev_priv->display.update_wm = ilk_update_wm;
dev_priv->display.update_sprite_wm = ilk_update_sprite_wm;
} else { } else {
DRM_DEBUG_KMS("Failed to read display plane latency. " DRM_DEBUG_KMS("Failed to read display plane latency. "
"Disable CxSR\n"); "Disable CxSR\n");

View File

@ -73,14 +73,14 @@ static bool vlv_is_psr_active_on_pipe(struct drm_device *dev, int pipe)
} }
static void intel_psr_write_vsc(struct intel_dp *intel_dp, static void intel_psr_write_vsc(struct intel_dp *intel_dp,
struct edp_vsc_psr *vsc_psr) const struct edp_vsc_psr *vsc_psr)
{ {
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_device *dev = dig_port->base.base.dev; struct drm_device *dev = dig_port->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc); struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc);
u32 ctl_reg = HSW_TVIDEO_DIP_CTL(crtc->config->cpu_transcoder); enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
u32 data_reg = HSW_TVIDEO_DIP_VSC_DATA(crtc->config->cpu_transcoder); u32 ctl_reg = HSW_TVIDEO_DIP_CTL(cpu_transcoder);
uint32_t *data = (uint32_t *) vsc_psr; uint32_t *data = (uint32_t *) vsc_psr;
unsigned int i; unsigned int i;
@ -90,12 +90,14 @@ static void intel_psr_write_vsc(struct intel_dp *intel_dp,
I915_WRITE(ctl_reg, 0); I915_WRITE(ctl_reg, 0);
POSTING_READ(ctl_reg); POSTING_READ(ctl_reg);
for (i = 0; i < VIDEO_DIP_VSC_DATA_SIZE; i += 4) { for (i = 0; i < sizeof(*vsc_psr); i += 4) {
if (i < sizeof(struct edp_vsc_psr)) I915_WRITE(HSW_TVIDEO_DIP_VSC_DATA(cpu_transcoder,
I915_WRITE(data_reg + i, *data++); i >> 2), *data);
else data++;
I915_WRITE(data_reg + i, 0);
} }
for (; i < VIDEO_DIP_VSC_DATA_SIZE; i += 4)
I915_WRITE(HSW_TVIDEO_DIP_VSC_DATA(cpu_transcoder,
i >> 2), 0);
I915_WRITE(ctl_reg, VIDEO_DIP_ENABLE_VSC_HSW); I915_WRITE(ctl_reg, VIDEO_DIP_ENABLE_VSC_HSW);
POSTING_READ(ctl_reg); POSTING_READ(ctl_reg);

View File

@ -906,6 +906,14 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t tmp; uint32_t tmp;
/* WaEnableLbsSlaRetryTimerDecrement:skl */
I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) |
GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE);
/* WaDisableKillLogic:bxt,skl */
I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
ECOCHK_DIS_TLB);
/* WaDisablePartialInstShootdown:skl,bxt */ /* WaDisablePartialInstShootdown:skl,bxt */
WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
@ -1018,7 +1026,6 @@ static int skl_tune_iz_hashing(struct intel_engine_cs *ring)
return 0; return 0;
} }
static int skl_init_workarounds(struct intel_engine_cs *ring) static int skl_init_workarounds(struct intel_engine_cs *ring)
{ {
int ret; int ret;
@ -1029,6 +1036,30 @@ static int skl_init_workarounds(struct intel_engine_cs *ring)
if (ret) if (ret)
return ret; return ret;
if (INTEL_REVID(dev) <= SKL_REVID_D0) {
/* WaDisableHDCInvalidation:skl */
I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
BDW_DISABLE_HDC_INVALIDATION);
/* WaDisableChickenBitTSGBarrierAckForFFSliceCS:skl */
I915_WRITE(FF_SLICE_CS_CHICKEN2,
_MASKED_BIT_ENABLE(GEN9_TSG_BARRIER_ACK_DISABLE));
}
/* GEN8_L3SQCREG4 has a dependency with WA batch so any new changes
* involving this register should also be added to WA batch as required.
*/
if (INTEL_REVID(dev) <= SKL_REVID_E0)
/* WaDisableLSQCROPERFforOCL:skl */
I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) |
GEN8_LQSC_RO_PERF_DIS);
/* WaEnableGapsTsvCreditFix:skl */
if (IS_SKYLAKE(dev) && (INTEL_REVID(dev) >= SKL_REVID_C0)) {
I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
GEN9_GAPS_TSV_CREDIT_DISABLE));
}
/* WaDisablePowerCompilerClockGating:skl */ /* WaDisablePowerCompilerClockGating:skl */
if (INTEL_REVID(dev) == SKL_REVID_B0) if (INTEL_REVID(dev) == SKL_REVID_B0)
WA_SET_BIT_MASKED(HIZ_CHICKEN, WA_SET_BIT_MASKED(HIZ_CHICKEN,
@ -1072,6 +1103,17 @@ static int bxt_init_workarounds(struct intel_engine_cs *ring)
if (ret) if (ret)
return ret; return ret;
/* WaStoreMultiplePTEenable:bxt */
/* This is a requirement according to Hardware specification */
if (INTEL_REVID(dev) == BXT_REVID_A0)
I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF);
/* WaSetClckGatingDisableMedia:bxt */
if (INTEL_REVID(dev) == BXT_REVID_A0) {
I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) &
~GEN8_DOP_CLOCK_GATE_MEDIA_ENABLE));
}
/* WaDisableThreadStallDopClockGating:bxt */ /* WaDisableThreadStallDopClockGating:bxt */
WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
STALL_DOP_GATING_DISABLE); STALL_DOP_GATING_DISABLE);

View File

@ -192,6 +192,7 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
const int pipe = intel_plane->pipe; const int pipe = intel_plane->pipe;
const int plane = intel_plane->plane + 1; const int plane = intel_plane->plane + 1;
u32 plane_ctl, stride_div, stride; u32 plane_ctl, stride_div, stride;
int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
const struct drm_intel_sprite_colorkey *key = const struct drm_intel_sprite_colorkey *key =
&to_intel_plane_state(drm_plane->state)->ckey; &to_intel_plane_state(drm_plane->state)->ckey;
unsigned long surf_addr; unsigned long surf_addr;
@ -202,6 +203,7 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
int scaler_id; int scaler_id;
plane_ctl = PLANE_CTL_ENABLE | plane_ctl = PLANE_CTL_ENABLE |
PLANE_CTL_PIPE_GAMMA_ENABLE |
PLANE_CTL_PIPE_CSC_ENABLE; PLANE_CTL_PIPE_CSC_ENABLE;
plane_ctl |= skl_plane_ctl_format(fb->pixel_format); plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
@ -210,6 +212,10 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
rotation = drm_plane->state->rotation; rotation = drm_plane->state->rotation;
plane_ctl |= skl_plane_ctl_rotation(rotation); plane_ctl |= skl_plane_ctl_rotation(rotation);
intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h,
pixel_size, true,
src_w != crtc_w || src_h != crtc_h);
stride_div = intel_fb_stride_alignment(dev, fb->modifier[0], stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
fb->pixel_format); fb->pixel_format);
@ -291,6 +297,8 @@ skl_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
I915_WRITE(PLANE_SURF(pipe, plane), 0); I915_WRITE(PLANE_SURF(pipe, plane), 0);
POSTING_READ(PLANE_SURF(pipe, plane)); POSTING_READ(PLANE_SURF(pipe, plane));
intel_update_sprite_watermarks(dplane, crtc, 0, 0, 0, false, false);
} }
static void static void
@ -533,6 +541,10 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
if (IS_HASWELL(dev) || IS_BROADWELL(dev)) if (IS_HASWELL(dev) || IS_BROADWELL(dev))
sprctl |= SPRITE_PIPE_CSC_ENABLE; sprctl |= SPRITE_PIPE_CSC_ENABLE;
intel_update_sprite_watermarks(plane, crtc, src_w, src_h, pixel_size,
true,
src_w != crtc_w || src_h != crtc_h);
/* Sizes are 0 based */ /* Sizes are 0 based */
src_w--; src_w--;
src_h--; src_h--;
@ -601,7 +613,7 @@ ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
struct intel_plane *intel_plane = to_intel_plane(plane); struct intel_plane *intel_plane = to_intel_plane(plane);
int pipe = intel_plane->pipe; int pipe = intel_plane->pipe;
I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE); I915_WRITE(SPRCTL(pipe), 0);
/* Can't leave the scaler enabled... */ /* Can't leave the scaler enabled... */
if (intel_plane->can_scale) if (intel_plane->can_scale)
I915_WRITE(SPRSCALE(pipe), 0); I915_WRITE(SPRSCALE(pipe), 0);
@ -666,6 +678,10 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
if (IS_GEN6(dev)) if (IS_GEN6(dev))
dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */
intel_update_sprite_watermarks(plane, crtc, src_w, src_h,
pixel_size, true,
src_w != crtc_w || src_h != crtc_h);
/* Sizes are 0 based */ /* Sizes are 0 based */
src_w--; src_w--;
src_h--; src_h--;

View File

@ -525,7 +525,7 @@ void assert_forcewakes_inactive(struct drm_i915_private *dev_priv)
} }
/* We give fast paths for the really cool registers */ /* We give fast paths for the really cool registers */
#define NEEDS_FORCE_WAKE(dev_priv, reg) \ #define NEEDS_FORCE_WAKE(reg) \
((reg) < 0x40000 && (reg) != FORCEWAKE) ((reg) < 0x40000 && (reg) != FORCEWAKE)
#define REG_RANGE(reg, start, end) ((reg) >= (start) && (reg) < (end)) #define REG_RANGE(reg, start, end) ((reg) >= (start) && (reg) < (end))
@ -727,7 +727,7 @@ static u##x \
gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
GEN6_READ_HEADER(x); \ GEN6_READ_HEADER(x); \
hsw_unclaimed_reg_debug(dev_priv, reg, true, true); \ hsw_unclaimed_reg_debug(dev_priv, reg, true, true); \
if (NEEDS_FORCE_WAKE((dev_priv), (reg))) \ if (NEEDS_FORCE_WAKE(reg)) \
__force_wake_get(dev_priv, FORCEWAKE_RENDER); \ __force_wake_get(dev_priv, FORCEWAKE_RENDER); \
val = __raw_i915_read##x(dev_priv, reg); \ val = __raw_i915_read##x(dev_priv, reg); \
hsw_unclaimed_reg_debug(dev_priv, reg, true, false); \ hsw_unclaimed_reg_debug(dev_priv, reg, true, false); \
@ -761,7 +761,7 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
GEN6_READ_FOOTER; \ GEN6_READ_FOOTER; \
} }
#define SKL_NEEDS_FORCE_WAKE(dev_priv, reg) \ #define SKL_NEEDS_FORCE_WAKE(reg) \
((reg) < 0x40000 && !FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg)) ((reg) < 0x40000 && !FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg))
#define __gen9_read(x) \ #define __gen9_read(x) \
@ -770,9 +770,9 @@ gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
enum forcewake_domains fw_engine; \ enum forcewake_domains fw_engine; \
GEN6_READ_HEADER(x); \ GEN6_READ_HEADER(x); \
hsw_unclaimed_reg_debug(dev_priv, reg, true, true); \ hsw_unclaimed_reg_debug(dev_priv, reg, true, true); \
if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg))) \ if (!SKL_NEEDS_FORCE_WAKE(reg)) \
fw_engine = 0; \ fw_engine = 0; \
else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) \ else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) \
fw_engine = FORCEWAKE_RENDER; \ fw_engine = FORCEWAKE_RENDER; \
else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) \ else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) \
fw_engine = FORCEWAKE_MEDIA; \ fw_engine = FORCEWAKE_MEDIA; \
@ -868,7 +868,7 @@ static void \
gen6_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \ gen6_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
u32 __fifo_ret = 0; \ u32 __fifo_ret = 0; \
GEN6_WRITE_HEADER; \ GEN6_WRITE_HEADER; \
if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ if (NEEDS_FORCE_WAKE(reg)) { \
__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
} \ } \
__raw_i915_write##x(dev_priv, reg, val); \ __raw_i915_write##x(dev_priv, reg, val); \
@ -883,7 +883,7 @@ static void \
hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
u32 __fifo_ret = 0; \ u32 __fifo_ret = 0; \
GEN6_WRITE_HEADER; \ GEN6_WRITE_HEADER; \
if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ if (NEEDS_FORCE_WAKE(reg)) { \
__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
} \ } \
hsw_unclaimed_reg_debug(dev_priv, reg, false, true); \ hsw_unclaimed_reg_debug(dev_priv, reg, false, true); \
@ -985,7 +985,7 @@ gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
enum forcewake_domains fw_engine; \ enum forcewake_domains fw_engine; \
GEN6_WRITE_HEADER; \ GEN6_WRITE_HEADER; \
hsw_unclaimed_reg_debug(dev_priv, reg, false, true); \ hsw_unclaimed_reg_debug(dev_priv, reg, false, true); \
if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)) || \ if (!SKL_NEEDS_FORCE_WAKE(reg) || \
is_gen9_shadowed(dev_priv, reg)) \ is_gen9_shadowed(dev_priv, reg)) \
fw_engine = 0; \ fw_engine = 0; \
else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) \ else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) \