F: arch/arm/mach-footbridge/
ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
- M: Shawn Guo <shawn.guo@linaro.org>
+ M: Shawn Guo <shawn.guo@freescale.com>
M: Sascha Hauer <kernel@pengutronix.de>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
- T: git git://git.linaro.org/people/shawnguo/linux-2.6.git
+ T: git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
F: arch/arm/mach-imx/
F: arch/arm/boot/dts/imx*
F: arch/arm/configs/imx*_defconfig
F: include/net/bluetooth/
BONDING DRIVER
- M: Jay Vosburgh <fubar@us.ibm.com>
- M: Veaceslav Falico <vfalico@redhat.com>
+ M: Jay Vosburgh <j.vosburgh@gmail.com>
+ M: Veaceslav Falico <vfalico@gmail.com>
M: Andy Gospodarek <andy@greyhouse.net>
L: netdev@vger.kernel.org
W: http://sourceforge.net/projects/bonding/
F: drivers/acpi/dock.c
DOCUMENTATION
- M: Rob Landley <rob@landley.net>
+ M: Randy Dunlap <rdunlap@infradead.org>
L: linux-doc@vger.kernel.org
- T: TBD
+ T: quilt http://www.infradead.org/~rdunlap/Doc/patches/
S: Maintained
F: Documentation/
F: include/drm/radeon*
F: include/uapi/drm/radeon*
+DRM PANEL DRIVERS
+M: Thierry Reding <thierry.reding@gmail.com>
+L: dri-devel@lists.freedesktop.org
+T: git git://anongit.freedesktop.org/tegra/linux.git
+S: Maintained
+F: drivers/gpu/drm/drm_panel.c
+F: drivers/gpu/drm/panel/
+F: include/drm/drm_panel.h
+F: Documentation/devicetree/bindings/panel/
+
INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets)
M: Daniel Vetter <daniel.vetter@ffwll.ch>
M: Jani Nikula <jani.nikula@linux.intel.com>
F: drivers/extcon/
F: Documentation/extcon/
-EXYNOS DP DRIVER
-M: Jingoo Han <jg1.han@samsung.com>
-L: linux-fbdev@vger.kernel.org
-S: Maintained
-F: drivers/video/exynos/exynos_dp*
-
EXYNOS MIPI DISPLAY DRIVERS
M: Inki Dae <inki.dae@samsung.com>
M: Donghwa Lee <dh09.lee@samsung.com>
M: Alex Duyck <alexander.h.duyck@intel.com>
M: John Ronciak <john.ronciak@intel.com>
M: Mitch Williams <mitch.a.williams@intel.com>
+ M: Linux NICS <linux.nics@intel.com>
L: e1000-devel@lists.sourceforge.net
W: http://www.intel.com/support/feedback.htm
W: http://e1000.sourceforge.net/
F: include/uapi/linux/netdevice.h
F: tools/net/
F: tools/testing/selftests/net/
+ F: lib/random32.c
NETWORKING [IPv4/IPv6]
M: "David S. Miller" <davem@davemloft.net>
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
struct drm_i915_gem_request *gem_request;
int ret, count, i;
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
int ret, i;
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
int ret, i, pipe;
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int i, ret;
ret = mutex_lock_interruptible(&dev->struct_mutex);
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
const u32 *hws;
int i;
i915_next_seqno_get(void *data, u64 *val)
{
struct drm_device *dev = data;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
ret = mutex_lock_interruptible(&dev->struct_mutex);
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u16 crstanddelay;
int ret;
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int ret = 0;
intel_runtime_pm_get(dev_priv);
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 delayfreq;
int ret, i;
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 inttoext;
int ret, i;
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 rgvmodectl, rstdbyctl;
u16 crstandvid;
int ret;
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
if (!HAS_FBC(dev)) {
seq_puts(m, "FBC unsupported on this chipset\n");
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
bool sr_enabled = false;
intel_runtime_pm_get(dev_priv);
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long temp, chipset, gfx;
int ret;
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int ret = 0;
int gpu_freq, ia_freq;
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
ret = mutex_lock_interruptible(&dev->struct_mutex);
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_opregion *opregion = &dev_priv->opregion;
void *data = kmalloc(OPREGION_SIZE, GFP_KERNEL);
int ret;
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
struct i915_hw_context *ctx;
int ret, i;
struct intel_encoder *intel_encoder;
seq_printf(m, "\tfb: %d, pos: %dx%d, size: %dx%d\n",
- crtc->fb->base.id, crtc->x, crtc->y,
- crtc->fb->width, crtc->fb->height);
+ crtc->primary->fb->base.id, crtc->x, crtc->y,
+ crtc->primary->fb->width, crtc->primary->fb->height);
for_each_encoder_on_crtc(dev, crtc, intel_encoder)
intel_encoder_info(m, intel_crtc, intel_encoder);
}
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *crtc;
struct drm_connector *connector;
+ intel_runtime_pm_get(dev_priv);
drm_modeset_lock_all(dev);
seq_printf(m, "CRTC info\n");
seq_printf(m, "---------\n");
seq_printf(m, "CRTC %d: pipe: %c, active: %s\n",
crtc->base.base.id, pipe_name(crtc->pipe),
yesno(crtc->active));
- if (crtc->active)
+ if (crtc->active) {
intel_crtc_info(m, crtc);
- active = cursor_position(dev, crtc->pipe, &x, &y);
- seq_printf(m, "\tcursor visible? %s, position (%d, %d), addr 0x%08x, active? %s\n",
- yesno(crtc->cursor_visible),
- x, y, crtc->cursor_addr,
- yesno(active));
+ active = cursor_position(dev, crtc->pipe, &x, &y);
+ seq_printf(m, "\tcursor visible? %s, position (%d, %d), addr 0x%08x, active? %s\n",
+ yesno(crtc->cursor_visible),
+ x, y, crtc->cursor_addr,
+ yesno(active));
+ }
}
seq_printf(m, "\n");
intel_connector_info(m, connector);
}
drm_modeset_unlock_all(dev);
+ intel_runtime_pm_put(dev_priv);
return 0;
}
i915_wedged_get(void *data, u64 *val)
{
struct drm_device *dev = data;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
*val = atomic_read(&dev_priv->gpu_error.reset_counter);
i915_ring_stop_get(void *data, u64 *val)
{
struct drm_device *dev = data;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
*val = dev_priv->gpu_error.stop_rings;
i915_max_freq_get(void *data, u64 *val)
{
struct drm_device *dev = data;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
if (!(IS_GEN6(dev) || IS_GEN7(dev)))
i915_min_freq_get(void *data, u64 *val)
{
struct drm_device *dev = data;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
if (!(IS_GEN6(dev) || IS_GEN7(dev)))
i915_cache_sharing_get(void *data, u64 *val)
{
struct drm_device *dev = data;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 snpcr;
int ret;
if (INTEL_INFO(dev)->gen < 6)
return 0;
- intel_runtime_pm_get(dev_priv);
gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
return 0;
return 0;
gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
- intel_runtime_pm_put(dev_priv);
return 0;
}
struct drm_i915_gem_pwrite *args,
struct drm_file *file)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
ssize_t remain;
loff_t offset, page_base;
char __user *user_data;
struct drm_i915_file_private *file_priv)
{
struct drm_device *dev = ring->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
const bool irq_test_in_progress =
ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_ring_flag(ring);
struct timespec before, now;
{
struct drm_i915_gem_object *obj = to_intel_bo(vma->vm_private_data);
struct drm_device *dev = obj->base.dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
pgoff_t page_offset;
unsigned long pfn;
int ret = 0;
struct drm_i915_gem_object *obj,
u32 *out_seqno)
{
- drm_i915_private_t *dev_priv = ring->dev->dev_private;
+ struct drm_i915_private *dev_priv = ring->dev->dev_private;
struct drm_i915_gem_request *request;
u32 request_ring_position, request_start;
int ret;
bool
i915_gem_retire_requests(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
bool idle = true;
int i;
int
i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_wait *args = data;
struct drm_i915_gem_object *obj;
struct intel_ring_buffer *ring = NULL;
int i915_vma_unbind(struct i915_vma *vma)
{
struct drm_i915_gem_object *obj = vma->obj;
- drm_i915_private_t *dev_priv = obj->base.dev->dev_private;
+ struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
int ret;
if (list_empty(&vma->vma_link))
int i915_gpu_idle(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
int ret, i;
static void i965_write_fence_reg(struct drm_device *dev, int reg,
struct drm_i915_gem_object *obj)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int fence_reg;
int fence_pitch_shift;
static void i915_write_fence_reg(struct drm_device *dev, int reg,
struct drm_i915_gem_object *obj)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 val;
if (obj) {
static void i830_write_fence_reg(struct drm_device *dev, int reg,
struct drm_i915_gem_object *obj)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t val;
if (obj) {
unsigned flags)
{
struct drm_device *dev = obj->base.dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 size, fence_size, fence_alignment, unfenced_alignment;
size_t gtt_max =
flags & PIN_MAPPABLE ? dev_priv->gtt.mappable_end : vm->total;
ret = drm_mm_insert_node_in_range_generic(&vm->mm, &vma->node,
size, alignment,
obj->cache_level, 0, gtt_max,
- DRM_MM_SEARCH_DEFAULT);
+ DRM_MM_SEARCH_DEFAULT,
+ DRM_MM_CREATE_DEFAULT);
if (ret) {
ret = i915_gem_evict_something(dev, vm, size, alignment,
obj->cache_level, flags);
int
i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
{
- drm_i915_private_t *dev_priv = obj->base.dev->dev_private;
+ struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
uint32_t old_write_domain, old_read_domains;
int ret;
{
struct drm_i915_gem_object *obj = to_intel_bo(gem_obj);
struct drm_device *dev = obj->base.dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct i915_vma *vma, *next;
intel_runtime_pm_get(dev_priv);
int
i915_gem_suspend(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int ret = 0;
mutex_lock(&dev->struct_mutex);
int i915_gem_l3_remap(struct intel_ring_buffer *ring, int slice)
{
struct drm_device *dev = ring->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 reg_base = GEN7_L3LOG_BASE + (slice * 0x200);
u32 *remap_info = dev_priv->l3_parity.remap_info[slice];
int i, ret;
void i915_gem_init_swizzling(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
if (INTEL_INFO(dev)->gen < 5 ||
dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_NONE)
int
i915_gem_init_hw(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int ret, i;
if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt())
void
i915_gem_cleanup_ringbuffer(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
int i;
void
i915_gem_load(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int i;
dev_priv->slab =
static int i915_gem_init_phys_object(struct drm_device *dev,
int id, int size, int align)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_phys_object *phys_obj;
int ret;
static void i915_gem_free_phys_object(struct drm_device *dev, int id)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_phys_object *phys_obj;
if (!dev_priv->mm.phys_objs[id - 1])
int align)
{
struct address_space *mapping = file_inode(obj->base.filp)->i_mapping;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int ret = 0;
int page_count;
int i;
static int gen7_ppgtt_enable(struct i915_hw_ppgtt *ppgtt)
{
struct drm_device *dev = ppgtt->base.dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
uint32_t ecochk, ecobits;
int i;
static int gen6_ppgtt_enable(struct i915_hw_ppgtt *ppgtt)
{
struct drm_device *dev = ppgtt->base.dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
uint32_t ecochk, gab_ctl, ecobits;
int i;
&ppgtt->node, GEN6_PD_SIZE,
GEN6_PD_ALIGN, 0,
0, dev_priv->gtt.base.total,
- DRM_MM_SEARCH_DEFAULT);
+ DRM_MM_SEARCH_DEFAULT,
+ DRM_MM_CREATE_DEFAULT);
if (ret == -ENOSPC && !retried) {
ret = i915_gem_evict_something(dev, &dev_priv->gtt.base,
GEN6_PD_SIZE, GEN6_PD_ALIGN,
dev_priv->gtt.base.clear_range(&dev_priv->gtt.base,
dev_priv->gtt.base.start,
dev_priv->gtt.base.total,
- false);
+ true);
}
void i915_gem_restore_gtt_mappings(struct drm_device *dev)
/* For display hotplug interrupt */
static void
- ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
+ ironlake_enable_display_irq(struct drm_i915_private *dev_priv, u32 mask)
{
assert_spin_locked(&dev_priv->irq_lock);
}
static void
- ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
+ ironlake_disable_display_irq(struct drm_i915_private *dev_priv, u32 mask)
{
assert_spin_locked(&dev_priv->irq_lock);
*/
static void i915_enable_asle_pipestat(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long irqflags;
if (!dev_priv->opregion.asle || !IS_MOBILE(dev))
static int
i915_pipe_enabled(struct drm_device *dev, int pipe)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
/* Locking is horribly broken here, but whatever. */
*/
static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long high_frame;
unsigned long low_frame;
u32 high1, high2, low, pixel, vbl_start;
static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int reg = PIPE_FRMCOUNT_GM45(pipe);
if (!i915_pipe_enabled(dev, pipe)) {
/* raw reads, only for fast reads of display block, no need for forcewake etc. */
#define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__))
- #define __raw_i915_read16(dev_priv__, reg__) readw((dev_priv__)->regs + (reg__))
static bool ilk_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t status;
-
- if (INTEL_INFO(dev)->gen < 7) {
- status = pipe == PIPE_A ?
- DE_PIPEA_VBLANK :
- DE_PIPEB_VBLANK;
+ int reg;
+
+ if (INTEL_INFO(dev)->gen >= 8) {
+ status = GEN8_PIPE_VBLANK;
+ reg = GEN8_DE_PIPE_ISR(pipe);
+ } else if (INTEL_INFO(dev)->gen >= 7) {
+ status = DE_PIPE_VBLANK_IVB(pipe);
+ reg = DEISR;
} else {
- switch (pipe) {
- default:
- case PIPE_A:
- status = DE_PIPEA_VBLANK_IVB;
- break;
- case PIPE_B:
- status = DE_PIPEB_VBLANK_IVB;
- break;
- case PIPE_C:
- status = DE_PIPEC_VBLANK_IVB;
- break;
- }
+ status = DE_PIPE_VBLANK(pipe);
+ reg = DEISR;
}
- return __raw_i915_read32(dev_priv, DEISR) & status;
+ return __raw_i915_read32(dev_priv, reg) & status;
}
static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
else
position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3;
- if (HAS_PCH_SPLIT(dev)) {
+ if (HAS_DDI(dev)) {
+ /*
+ * On HSW HDMI outputs there seems to be a 2 line
+ * difference, whereas eDP has the normal 1 line
+ * difference that earlier platforms have. External
+ * DP is unknown. For now just check for the 2 line
+ * difference case on all output types on HSW+.
+ *
+ * This might misinterpret the scanline counter being
+ * one line too far along on eDP, but that's less
+ * dangerous than the alternative since that would lead
+ * the vblank timestamp code astray when it sees a
+ * scanline count before vblank_start during a vblank
+ * interrupt.
+ */
+ in_vbl = ilk_pipe_in_vblank_locked(dev, pipe);
+ if ((in_vbl && (position == vbl_start - 2 ||
+ position == vbl_start - 1)) ||
+ (!in_vbl && (position == vbl_end - 2 ||
+ position == vbl_end - 1)))
+ position = (position + 2) % vtotal;
+ } else if (HAS_PCH_SPLIT(dev)) {
/*
* The scanline counter increments at the leading edge
* of hsync, ie. it completely misses the active portion
static void i915_hotplug_work_func(struct work_struct *work)
{
- drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
- hotplug_work);
+ struct drm_i915_private *dev_priv =
+ container_of(work, struct drm_i915_private, hotplug_work);
struct drm_device *dev = dev_priv->dev;
struct drm_mode_config *mode_config = &dev->mode_config;
struct intel_connector *intel_connector;
static void ironlake_rps_change_irq_handler(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 busy_up, busy_down, max_avg, min_avg;
u8 new_delay;
i915_queue_hangcheck(dev);
}
- void gen6_set_pm_mask(struct drm_i915_private *dev_priv,
- u32 pm_iir, int new_delay)
- {
- if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) {
- if (new_delay >= dev_priv->rps.max_freq_softlimit) {
- /* Mask UP THRESHOLD Interrupts */
- I915_WRITE(GEN6_PMINTRMSK,
- I915_READ(GEN6_PMINTRMSK) |
- GEN6_PM_RP_UP_THRESHOLD);
- dev_priv->rps.rp_up_masked = true;
- }
- if (dev_priv->rps.rp_down_masked) {
- /* UnMask DOWN THRESHOLD Interrupts */
- I915_WRITE(GEN6_PMINTRMSK,
- I915_READ(GEN6_PMINTRMSK) &
- ~GEN6_PM_RP_DOWN_THRESHOLD);
- dev_priv->rps.rp_down_masked = false;
- }
- } else if (pm_iir & GEN6_PM_RP_DOWN_THRESHOLD) {
- if (new_delay <= dev_priv->rps.min_freq_softlimit) {
- /* Mask DOWN THRESHOLD Interrupts */
- I915_WRITE(GEN6_PMINTRMSK,
- I915_READ(GEN6_PMINTRMSK) |
- GEN6_PM_RP_DOWN_THRESHOLD);
- dev_priv->rps.rp_down_masked = true;
- }
-
- if (dev_priv->rps.rp_up_masked) {
- /* UnMask UP THRESHOLD Interrupts */
- I915_WRITE(GEN6_PMINTRMSK,
- I915_READ(GEN6_PMINTRMSK) &
- ~GEN6_PM_RP_UP_THRESHOLD);
- dev_priv->rps.rp_up_masked = false;
- }
- }
- }
-
static void gen6_pm_rps_work(struct work_struct *work)
{
- drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
- rps.work);
+ struct drm_i915_private *dev_priv =
+ container_of(work, struct drm_i915_private, rps.work);
u32 pm_iir;
int new_delay, adj;
pm_iir = dev_priv->rps.pm_iir;
dev_priv->rps.pm_iir = 0;
/* Make sure not to corrupt PMIMR state used by ringbuffer code */
- snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS);
+ snb_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
spin_unlock_irq(&dev_priv->irq_lock);
/* Make sure we didn't queue anything we're not going to process. */
- WARN_ON(pm_iir & ~GEN6_PM_RPS_EVENTS);
+ WARN_ON(pm_iir & ~dev_priv->pm_rps_events);
- if ((pm_iir & GEN6_PM_RPS_EVENTS) == 0)
+ if ((pm_iir & dev_priv->pm_rps_events) == 0)
return;
mutex_lock(&dev_priv->rps.hw_lock);
dev_priv->rps.min_freq_softlimit,
dev_priv->rps.max_freq_softlimit);
- gen6_set_pm_mask(dev_priv, pm_iir, new_delay);
dev_priv->rps.last_adj = new_delay - dev_priv->rps.cur_freq;
if (IS_VALLEYVIEW(dev_priv->dev))
*/
static void ivybridge_parity_work(struct work_struct *work)
{
- drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
- l3_parity.error_work);
+ struct drm_i915_private *dev_priv =
+ container_of(work, struct drm_i915_private, l3_parity.error_work);
u32 error_status, row, bank, subbank;
char *parity_event[6];
uint32_t misccpctl;
static void ivybridge_parity_error_irq_handler(struct drm_device *dev, u32 iir)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
if (!HAS_L3_DPF(dev))
return;
u32 hotplug_trigger,
const u32 *hpd)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int i;
bool storm_detected = false;
static void gmbus_irq_handler(struct drm_device *dev)
{
- struct drm_i915_private *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
wake_up_all(&dev_priv->gmbus_wait_queue);
}
static void dp_aux_irq_handler(struct drm_device *dev)
{
- struct drm_i915_private *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
wake_up_all(&dev_priv->gmbus_wait_queue);
}
* the work queue. */
static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
{
- if (pm_iir & GEN6_PM_RPS_EVENTS) {
+ if (pm_iir & dev_priv->pm_rps_events) {
spin_lock(&dev_priv->irq_lock);
- dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RPS_EVENTS;
- snb_disable_pm_irq(dev_priv, pm_iir & GEN6_PM_RPS_EVENTS);
+ dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events;
+ snb_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events);
spin_unlock(&dev_priv->irq_lock);
queue_work(dev_priv->wq, &dev_priv->rps.work);
static irqreturn_t valleyview_irq_handler(int irq, void *arg)
{
struct drm_device *dev = (struct drm_device *) arg;
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 iir, gt_iir, pm_iir;
irqreturn_t ret = IRQ_NONE;
static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int pipe;
u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK;
static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int pipe;
u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT;
static irqreturn_t ironlake_irq_handler(int irq, void *arg)
{
struct drm_device *dev = (struct drm_device *) arg;
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 de_iir, gt_iir, de_ier, sde_ier = 0;
irqreturn_t ret = IRQ_NONE;
{
struct i915_gpu_error *error = container_of(work, struct i915_gpu_error,
work);
- drm_i915_private_t *dev_priv = container_of(error, drm_i915_private_t,
- gpu_error);
+ struct drm_i915_private *dev_priv =
+ container_of(error, struct drm_i915_private, gpu_error);
struct drm_device *dev = dev_priv->dev;
char *error_event[] = { I915_ERROR_UEVENT "=1", NULL };
char *reset_event[] = { I915_RESET_UEVENT "=1", NULL };
static void __always_unused i915_pageflip_stall_check(struct drm_device *dev, int pipe)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_i915_gem_object *obj;
} else {
int dspaddr = DSPADDR(intel_crtc->plane);
stall_detected = I915_READ(dspaddr) == (i915_gem_obj_ggtt_offset(obj) +
- crtc->y * crtc->fb->pitches[0] +
- crtc->x * crtc->fb->bits_per_pixel/8);
+ crtc->y * crtc->primary->fb->pitches[0] +
+ crtc->x * crtc->primary->fb->bits_per_pixel/8);
}
spin_unlock_irqrestore(&dev->event_lock, flags);
*/
static int i915_enable_vblank(struct drm_device *dev, int pipe)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long irqflags;
if (!i915_pipe_enabled(dev, pipe))
static int ironlake_enable_vblank(struct drm_device *dev, int pipe)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long irqflags;
uint32_t bit = (INTEL_INFO(dev)->gen >= 7) ? DE_PIPE_VBLANK_IVB(pipe) :
DE_PIPE_VBLANK(pipe);
static int valleyview_enable_vblank(struct drm_device *dev, int pipe)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long irqflags;
if (!i915_pipe_enabled(dev, pipe))
*/
static void i915_disable_vblank(struct drm_device *dev, int pipe)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long irqflags;
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
static void ironlake_disable_vblank(struct drm_device *dev, int pipe)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long irqflags;
uint32_t bit = (INTEL_INFO(dev)->gen >= 7) ? DE_PIPE_VBLANK_IVB(pipe) :
DE_PIPE_VBLANK(pipe);
static void valleyview_disable_vblank(struct drm_device *dev, int pipe)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long irqflags;
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
semaphore_waits_for(struct intel_ring_buffer *ring, u32 *seqno)
{
struct drm_i915_private *dev_priv = ring->dev->dev_private;
- u32 cmd, ipehr, acthd, acthd_min;
+ u32 cmd, ipehr, head;
+ int i;
ipehr = I915_READ(RING_IPEHR(ring->mmio_base));
if ((ipehr & ~(0x3 << 16)) !=
(MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE | MI_SEMAPHORE_REGISTER))
return NULL;
- /* ACTHD is likely pointing to the dword after the actual command,
- * so scan backwards until we find the MBOX.
+ /*
+ * HEAD is likely pointing to the dword after the actual command,
+ * so scan backwards until we find the MBOX. But limit it to just 3
+ * dwords. Note that we don't care about ACTHD here since that might
+ * point at at batch, and semaphores are always emitted into the
+ * ringbuffer itself.
*/
- acthd = intel_ring_get_active_head(ring) & HEAD_ADDR;
- acthd_min = max((int)acthd - 3 * 4, 0);
- do {
- cmd = ioread32(ring->virtual_start + acthd);
+ head = I915_READ_HEAD(ring) & HEAD_ADDR;
+
+ for (i = 4; i; --i) {
+ /*
+ * Be paranoid and presume the hw has gone off into the wild -
+ * our ring is smaller than what the hardware (and hence
+ * HEAD_ADDR) allows. Also handles wrap-around.
+ */
+ head &= ring->size - 1;
+
+ /* This here seems to blow up */
+ cmd = ioread32(ring->virtual_start + head);
if (cmd == ipehr)
break;
- acthd -= 4;
- if (acthd < acthd_min)
- return NULL;
- } while (1);
+ head -= 4;
+ }
- *seqno = ioread32(ring->virtual_start+acthd+4)+1;
+ if (!i)
+ return NULL;
+
+ *seqno = ioread32(ring->virtual_start + head + 4) + 1;
return &dev_priv->ring[(ring->id + (((ipehr >> 17) & 1) + 1)) % 3];
}
}
static enum intel_ring_hangcheck_action
- ring_stuck(struct intel_ring_buffer *ring, u32 acthd)
+ ring_stuck(struct intel_ring_buffer *ring, u64 acthd)
{
struct drm_device *dev = ring->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
static void i915_hangcheck_elapsed(unsigned long data)
{
struct drm_device *dev = (struct drm_device *)data;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
int i;
int busy_count = 0, rings_hung = 0;
return;
for_each_ring(ring, dev_priv, i) {
- u32 seqno, acthd;
+ u64 acthd;
+ u32 seqno;
bool busy = true;
semaphore_clear_deadlocks(dev_priv);
*/
static void ironlake_irq_preinstall(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
I915_WRITE(HWSTAM, 0xeffe);
static void valleyview_irq_preinstall(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int pipe;
/* VLV magic */
static void ibx_hpd_irq_setup(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_mode_config *mode_config = &dev->mode_config;
struct intel_encoder *intel_encoder;
u32 hotplug_irqs, hotplug, enabled_irqs = 0;
static void ibx_irq_postinstall(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 mask;
if (HAS_PCH_NOP(dev))
return;
if (HAS_PCH_IBX(dev)) {
- mask = SDE_GMBUS | SDE_AUX_MASK | SDE_TRANSB_FIFO_UNDER |
- SDE_TRANSA_FIFO_UNDER | SDE_POISON;
+ mask = SDE_GMBUS | SDE_AUX_MASK | SDE_POISON;
} else {
- mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT | SDE_ERROR_CPT;
+ mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT;
I915_WRITE(SERR_INT, I915_READ(SERR_INT));
}
POSTING_READ(GTIER);
if (INTEL_INFO(dev)->gen >= 6) {
- pm_irqs |= GEN6_PM_RPS_EVENTS;
+ pm_irqs |= dev_priv->pm_rps_events;
if (HAS_VEBOX(dev))
pm_irqs |= PM_VEBOX_USER_INTERRUPT;
static int ironlake_irq_postinstall(struct drm_device *dev)
{
unsigned long irqflags;
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 display_mask, extra_mask;
if (INTEL_INFO(dev)->gen >= 7) {
display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB |
DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB |
DE_PLANEB_FLIP_DONE_IVB |
- DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB |
- DE_ERR_INT_IVB);
+ DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB);
extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB |
- DE_PIPEA_VBLANK_IVB);
+ DE_PIPEA_VBLANK_IVB | DE_ERR_INT_IVB);
I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT));
} else {
display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE |
DE_AUX_CHANNEL_A |
- DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN |
DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE |
DE_POISON);
- extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT;
+ extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT |
+ DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN;
}
dev_priv->irq_mask = ~display_mask;
static int valleyview_irq_postinstall(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long irqflags;
dev_priv->irq_mask = ~0;
struct drm_device *dev = dev_priv->dev;
uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE |
GEN8_PIPE_CDCLK_CRC_DONE |
- GEN8_PIPE_FIFO_UNDERRUN |
GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
- uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK;
+ uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK |
+ GEN8_PIPE_FIFO_UNDERRUN;
int pipe;
dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked;
dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked;
static void valleyview_irq_uninstall(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long irqflags;
int pipe;
static void ironlake_irq_uninstall(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
if (!dev_priv)
return;
static void i8xx_irq_preinstall(struct drm_device * dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int pipe;
for_each_pipe(pipe)
static int i8xx_irq_postinstall(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long irqflags;
I915_WRITE16(EMR,
static bool i8xx_handle_vblank(struct drm_device *dev,
int plane, int pipe, u32 iir)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u16 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane);
if (!drm_handle_vblank(dev, pipe))
static irqreturn_t i8xx_irq_handler(int irq, void *arg)
{
struct drm_device *dev = (struct drm_device *) arg;
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u16 iir, new_iir;
u32 pipe_stats[2];
unsigned long irqflags;
static void i8xx_irq_uninstall(struct drm_device * dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int pipe;
for_each_pipe(pipe) {
static void i915_irq_preinstall(struct drm_device * dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int pipe;
if (I915_HAS_HOTPLUG(dev)) {
static int i915_irq_postinstall(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 enable_mask;
unsigned long irqflags;
static bool i915_handle_vblank(struct drm_device *dev,
int plane, int pipe, u32 iir)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane);
if (!drm_handle_vblank(dev, pipe))
static irqreturn_t i915_irq_handler(int irq, void *arg)
{
struct drm_device *dev = (struct drm_device *) arg;
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 iir, new_iir, pipe_stats[I915_MAX_PIPES];
unsigned long irqflags;
u32 flip_mask =
static void i915_irq_uninstall(struct drm_device * dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int pipe;
intel_hpd_irq_uninstall(dev_priv);
static void i965_irq_preinstall(struct drm_device * dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int pipe;
I915_WRITE(PORT_HOTPLUG_EN, 0);
static int i965_irq_postinstall(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 enable_mask;
u32 error_mask;
unsigned long irqflags;
static void i915_hpd_irq_setup(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_mode_config *mode_config = &dev->mode_config;
struct intel_encoder *intel_encoder;
u32 hotplug_en;
static irqreturn_t i965_irq_handler(int irq, void *arg)
{
struct drm_device *dev = (struct drm_device *) arg;
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 iir, new_iir;
u32 pipe_stats[I915_MAX_PIPES];
unsigned long irqflags;
static void i965_irq_uninstall(struct drm_device * dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int pipe;
if (!dev_priv)
static void intel_hpd_irq_reenable(unsigned long data)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *)data;
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *)data;
struct drm_device *dev = dev_priv->dev;
struct drm_mode_config *mode_config = &dev->mode_config;
unsigned long irqflags;
INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work);
INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work);
+ /* Let's track the enabled rps events */
+ dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS;
+
setup_timer(&dev_priv->gpu_error.hangcheck_timer,
i915_hangcheck_elapsed,
(unsigned long) dev);
* We can ditch the adjusted_mode.crtc_clock check as soon
* as Haswell has gained clock readout/fastboot support.
*
- * We can ditch the crtc->fb check as soon as we can
+ * We can ditch the crtc->primary->fb check as soon as we can
* properly reconstruct framebuffers.
*/
- return intel_crtc->active && crtc->fb &&
+ return intel_crtc->active && crtc->primary->fb &&
intel_crtc->config.adjusted_mode.crtc_clock;
}
if (plane_config->tiled) {
obj->tiling_mode = I915_TILING_X;
- obj->stride = crtc->base.fb->pitches[0];
+ obj->stride = crtc->base.primary->fb->pitches[0];
}
- mode_cmd.pixel_format = crtc->base.fb->pixel_format;
- mode_cmd.width = crtc->base.fb->width;
- mode_cmd.height = crtc->base.fb->height;
- mode_cmd.pitches[0] = crtc->base.fb->pitches[0];
+ mode_cmd.pixel_format = crtc->base.primary->fb->pixel_format;
+ mode_cmd.width = crtc->base.primary->fb->width;
+ mode_cmd.height = crtc->base.primary->fb->height;
+ mode_cmd.pitches[0] = crtc->base.primary->fb->pitches[0];
mutex_lock(&dev->struct_mutex);
- if (intel_framebuffer_init(dev, to_intel_framebuffer(crtc->base.fb),
+ if (intel_framebuffer_init(dev, to_intel_framebuffer(crtc->base.primary->fb),
&mode_cmd, obj)) {
DRM_DEBUG_KMS("intel fb init failed\n");
goto out_unref_obj;
struct intel_crtc *i;
struct intel_framebuffer *fb;
- if (!intel_crtc->base.fb)
+ if (!intel_crtc->base.primary->fb)
return;
if (intel_alloc_plane_obj(intel_crtc, plane_config))
return;
- kfree(intel_crtc->base.fb);
- intel_crtc->base.fb = NULL;
+ kfree(intel_crtc->base.primary->fb);
+ intel_crtc->base.primary->fb = NULL;
/*
* Failed to alloc the obj, check to see if we should share
if (c == &intel_crtc->base)
continue;
- if (!i->active || !c->fb)
+ if (!i->active || !c->primary->fb)
continue;
- fb = to_intel_framebuffer(c->fb);
+ fb = to_intel_framebuffer(c->primary->fb);
if (i915_gem_obj_ggtt_offset(fb->obj) == plane_config->base) {
- drm_framebuffer_reference(c->fb);
- intel_crtc->base.fb = c->fb;
+ drm_framebuffer_reference(c->primary->fb);
+ intel_crtc->base.primary->fb = c->primary->fb;
break;
}
}
/*
* FIXME: Once we have proper support for primary planes (and
* disabling them without disabling the entire crtc) allow again
- * a NULL crtc->fb.
+ * a NULL crtc->primary->fb.
*/
- if (intel_crtc->active && crtc->fb)
+ if (intel_crtc->active && crtc->primary->fb)
dev_priv->display.update_primary_plane(crtc,
- crtc->fb,
+ crtc->primary->fb,
crtc->x,
crtc->y);
mutex_unlock(&crtc->mutex);
return ret;
}
- old_fb = crtc->fb;
- crtc->fb = fb;
+ old_fb = crtc->primary->fb;
+ crtc->primary->fb = fb;
crtc->x = x;
crtc->y = y;
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- if (crtc->fb == NULL)
+ if (crtc->primary->fb == NULL)
return;
WARN_ON(waitqueue_active(&dev_priv->pending_flip_queue));
!intel_crtc_has_pending_flip(crtc));
mutex_lock(&dev->struct_mutex);
- intel_finish_fb(crtc->fb);
+ intel_finish_fb(crtc->primary->fb);
mutex_unlock(&dev->struct_mutex);
}
{
struct drm_device *dev = crtc->dev;
enum pipe pipe = to_intel_crtc(crtc)->pipe;
+ struct drm_plane *plane;
struct intel_plane *intel_plane;
- list_for_each_entry(intel_plane, &dev->mode_config.plane_list, base.head)
+ drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) {
+ intel_plane = to_intel_plane(plane);
if (intel_plane->pipe == pipe)
intel_plane_restore(&intel_plane->base);
+ }
}
static void intel_disable_planes(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
enum pipe pipe = to_intel_crtc(crtc)->pipe;
+ struct drm_plane *plane;
struct intel_plane *intel_plane;
- list_for_each_entry(intel_plane, &dev->mode_config.plane_list, base.head)
+ drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) {
+ intel_plane = to_intel_plane(plane);
if (intel_plane->pipe == pipe)
intel_plane_disable(&intel_plane->base);
+ }
}
void hsw_enable_ips(struct intel_crtc *crtc)
assert_cursor_disabled(dev_priv, to_intel_crtc(crtc)->pipe);
assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe);
- if (crtc->fb) {
+ if (crtc->primary->fb) {
mutex_lock(&dev->struct_mutex);
- intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj);
+ intel_unpin_fb_obj(to_intel_framebuffer(crtc->primary->fb)->obj);
mutex_unlock(&dev->struct_mutex);
- crtc->fb = NULL;
+ crtc->primary->fb = NULL;
}
/* Update computed state. */
enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
struct drm_display_mode *adjusted_mode =
&intel_crtc->config.adjusted_mode;
- uint32_t vsyncshift, crtc_vtotal, crtc_vblank_end;
+ uint32_t crtc_vtotal, crtc_vblank_end;
+ int vsyncshift = 0;
/* We need to be careful not to changed the adjusted mode, for otherwise
* the hw state checker will get angry at the mismatch. */
crtc_vtotal = adjusted_mode->crtc_vtotal;
crtc_vblank_end = adjusted_mode->crtc_vblank_end;
- if (!IS_GEN2(dev) && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
+ if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
/* the chip adds 2 halflines automatically */
crtc_vtotal -= 1;
crtc_vblank_end -= 1;
- vsyncshift = adjusted_mode->crtc_hsync_start
- - adjusted_mode->crtc_htotal / 2;
- } else {
- vsyncshift = 0;
+
+ if (intel_pipe_has_type(&intel_crtc->base, INTEL_OUTPUT_SDVO))
+ vsyncshift = (adjusted_mode->crtc_htotal - 1) / 2;
+ else
+ vsyncshift = adjusted_mode->crtc_hsync_start -
+ adjusted_mode->crtc_htotal / 2;
+ if (vsyncshift < 0)
+ vsyncshift += adjusted_mode->crtc_htotal;
}
if (INTEL_INFO(dev)->gen > 3)
}
}
- if (!IS_GEN2(dev) &&
- intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
- pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
- else
+ if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
+ if (INTEL_INFO(dev)->gen < 4 ||
+ intel_pipe_has_type(&intel_crtc->base, INTEL_OUTPUT_SDVO))
+ pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
+ else
+ pipeconf |= PIPECONF_INTERLACE_W_SYNC_SHIFT;
+ } else
pipeconf |= PIPECONF_PROGRESSIVE;
if (IS_VALLEYVIEW(dev) && intel_crtc->config.limited_color_range)
int fourcc, pixel_format;
int aligned_height;
- crtc->base.fb = kzalloc(sizeof(struct intel_framebuffer), GFP_KERNEL);
- if (!crtc->base.fb) {
+ crtc->base.primary->fb = kzalloc(sizeof(struct intel_framebuffer), GFP_KERNEL);
+ if (!crtc->base.primary->fb) {
DRM_DEBUG_KMS("failed to alloc fb\n");
return;
}
pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
fourcc = intel_format_to_fourcc(pixel_format);
- crtc->base.fb->pixel_format = fourcc;
- crtc->base.fb->bits_per_pixel =
+ crtc->base.primary->fb->pixel_format = fourcc;
+ crtc->base.primary->fb->bits_per_pixel =
drm_format_plane_cpp(fourcc, 0) * 8;
if (INTEL_INFO(dev)->gen >= 4) {
plane_config->base = base;
val = I915_READ(PIPESRC(pipe));
- crtc->base.fb->width = ((val >> 16) & 0xfff) + 1;
- crtc->base.fb->height = ((val >> 0) & 0xfff) + 1;
+ crtc->base.primary->fb->width = ((val >> 16) & 0xfff) + 1;
+ crtc->base.primary->fb->height = ((val >> 0) & 0xfff) + 1;
val = I915_READ(DSPSTRIDE(pipe));
- crtc->base.fb->pitches[0] = val & 0xffffff80;
+ crtc->base.primary->fb->pitches[0] = val & 0xffffff80;
- aligned_height = intel_align_height(dev, crtc->base.fb->height,
+ aligned_height = intel_align_height(dev, crtc->base.primary->fb->height,
plane_config->tiled);
- plane_config->size = ALIGN(crtc->base.fb->pitches[0] *
+ plane_config->size = ALIGN(crtc->base.primary->fb->pitches[0] *
aligned_height, PAGE_SIZE);
DRM_DEBUG_KMS("pipe/plane %d/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
- pipe, plane, crtc->base.fb->width,
- crtc->base.fb->height,
- crtc->base.fb->bits_per_pixel, base,
- crtc->base.fb->pitches[0],
+ pipe, plane, crtc->base.primary->fb->width,
+ crtc->base.primary->fb->height,
+ crtc->base.primary->fb->bits_per_pixel, base,
+ crtc->base.primary->fb->pitches[0],
plane_config->size);
}
int fourcc, pixel_format;
int aligned_height;
- crtc->base.fb = kzalloc(sizeof(struct intel_framebuffer), GFP_KERNEL);
- if (!crtc->base.fb) {
+ crtc->base.primary->fb = kzalloc(sizeof(struct intel_framebuffer), GFP_KERNEL);
+ if (!crtc->base.primary->fb) {
DRM_DEBUG_KMS("failed to alloc fb\n");
return;
}
pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
fourcc = intel_format_to_fourcc(pixel_format);
- crtc->base.fb->pixel_format = fourcc;
- crtc->base.fb->bits_per_pixel =
+ crtc->base.primary->fb->pixel_format = fourcc;
+ crtc->base.primary->fb->bits_per_pixel =
drm_format_plane_cpp(fourcc, 0) * 8;
base = I915_READ(DSPSURF(plane)) & 0xfffff000;
plane_config->base = base;
val = I915_READ(PIPESRC(pipe));
- crtc->base.fb->width = ((val >> 16) & 0xfff) + 1;
- crtc->base.fb->height = ((val >> 0) & 0xfff) + 1;
+ crtc->base.primary->fb->width = ((val >> 16) & 0xfff) + 1;
+ crtc->base.primary->fb->height = ((val >> 0) & 0xfff) + 1;
val = I915_READ(DSPSTRIDE(pipe));
- crtc->base.fb->pitches[0] = val & 0xffffff80;
+ crtc->base.primary->fb->pitches[0] = val & 0xffffff80;
- aligned_height = intel_align_height(dev, crtc->base.fb->height,
+ aligned_height = intel_align_height(dev, crtc->base.primary->fb->height,
plane_config->tiled);
- plane_config->size = ALIGN(crtc->base.fb->pitches[0] *
+ plane_config->size = ALIGN(crtc->base.primary->fb->pitches[0] *
aligned_height, PAGE_SIZE);
DRM_DEBUG_KMS("pipe/plane %d/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
- pipe, plane, crtc->base.fb->width,
- crtc->base.fb->height,
- crtc->base.fb->bits_per_pixel, base,
- crtc->base.fb->pitches[0],
+ pipe, plane, crtc->base.primary->fb->width,
+ crtc->base.primary->fb->height,
+ crtc->base.primary->fb->bits_per_pixel, base,
+ crtc->base.primary->fb->pitches[0],
plane_config->size);
}
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_i915_gem_object *obj;
+ unsigned old_width;
uint32_t addr;
int ret;
mutex_unlock(&dev->struct_mutex);
+ old_width = intel_crtc->cursor_width;
+
intel_crtc->cursor_addr = addr;
intel_crtc->cursor_bo = obj;
intel_crtc->cursor_width = width;
intel_crtc->cursor_height = height;
- if (intel_crtc->active)
+ if (intel_crtc->active) {
+ if (old_width != width)
+ intel_update_watermarks(crtc);
intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL);
+ }
return 0;
fail_unpin:
static void intel_increase_pllclock(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_crtc->pipe;
int dpll_reg = DPLL(pipe);
static void intel_decrease_pllclock(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
if (HAS_PCH_SPLIT(dev))
goto out;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- if (!crtc->fb)
+ if (!crtc->primary->fb)
continue;
intel_decrease_pllclock(crtc);
return;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- if (!crtc->fb)
+ if (!crtc->primary->fb)
continue;
- if (to_intel_framebuffer(crtc->fb)->obj != obj)
+ if (to_intel_framebuffer(crtc->primary->fb)->obj != obj)
continue;
intel_increase_pllclock(crtc);
static void do_intel_finish_page_flip(struct drm_device *dev,
struct drm_crtc *crtc)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_unpin_work *work;
unsigned long flags;
void intel_finish_page_flip(struct drm_device *dev, int pipe)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
do_intel_finish_page_flip(dev, crtc);
void intel_finish_page_flip_plane(struct drm_device *dev, int plane)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = dev_priv->plane_to_crtc_mapping[plane];
do_intel_finish_page_flip(dev, crtc);
void intel_prepare_page_flip(struct drm_device *dev, int plane)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc =
to_intel_crtc(dev_priv->plane_to_crtc_mapping[plane]);
unsigned long flags;
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_framebuffer *old_fb = crtc->fb;
+ struct drm_framebuffer *old_fb = crtc->primary->fb;
struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_unpin_work *work;
int ret;
/* Can't change pixel format via MI display flips. */
- if (fb->pixel_format != crtc->fb->pixel_format)
+ if (fb->pixel_format != crtc->primary->fb->pixel_format)
return -EINVAL;
/*
* Note that pitch changes could also affect these register.
*/
if (INTEL_INFO(dev)->gen > 3 &&
- (fb->offsets[0] != crtc->fb->offsets[0] ||
- fb->pitches[0] != crtc->fb->pitches[0]))
+ (fb->offsets[0] != crtc->primary->fb->offsets[0] ||
+ fb->pitches[0] != crtc->primary->fb->pitches[0]))
return -EINVAL;
if (i915_terminally_wedged(&dev_priv->gpu_error))
drm_gem_object_reference(&work->old_fb_obj->base);
drm_gem_object_reference(&obj->base);
- crtc->fb = fb;
+ crtc->primary->fb = fb;
work->pending_flip_obj = obj;
cleanup_pending:
atomic_dec(&intel_crtc->unpin_work_count);
- crtc->fb = old_fb;
+ crtc->primary->fb = old_fb;
drm_gem_object_unreference(&work->old_fb_obj->base);
drm_gem_object_unreference(&obj->base);
mutex_unlock(&dev->struct_mutex);
static void
check_crtc_state(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *crtc;
struct intel_encoder *encoder;
struct intel_crtc_config pipe_config;
static void
check_shared_dpll_state(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *crtc;
struct intel_dpll_hw_state dpll_hw_state;
int i;
int x, int y, struct drm_framebuffer *fb)
{
struct drm_device *dev = crtc->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_display_mode *saved_mode;
struct intel_crtc_config *pipe_config = NULL;
struct intel_crtc *intel_crtc;
void intel_crtc_restore_mode(struct drm_crtc *crtc)
{
- intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->fb);
+ intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb);
}
#undef for_each_intel_crtc_masked
* and then just flip_or_move it */
if (is_crtc_connector_off(set)) {
config->mode_changed = true;
- } else if (set->crtc->fb != set->fb) {
+ } else if (set->crtc->primary->fb != set->fb) {
/* If we have no fb then treat it as a full mode set */
- if (set->crtc->fb == NULL) {
+ if (set->crtc->primary->fb == NULL) {
struct intel_crtc *intel_crtc =
to_intel_crtc(set->crtc);
} else if (set->fb == NULL) {
config->mode_changed = true;
} else if (set->fb->pixel_format !=
- set->crtc->fb->pixel_format) {
+ set->crtc->primary->fb->pixel_format) {
config->mode_changed = true;
} else {
config->fb_changed = true;
save_set.mode = &set->crtc->mode;
save_set.x = set->crtc->x;
save_set.y = set->crtc->y;
- save_set.fb = set->crtc->fb;
+ save_set.fb = set->crtc->primary->fb;
/* Compute whether we need a full modeset, only an fb base update or no
* change at all. In the future we might also check whether only the
static void intel_crtc_init(struct drm_device *dev, int pipe)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc;
int i;
encoder->base.crtc = NULL;
}
}
+ if (crtc->active) {
+ /*
+ * We start out with underrun reporting disabled to avoid races.
+ * For correct bookkeeping mark this on active crtcs.
+ *
+ * No protection against concurrent access is required - at
+ * worst a fifo underrun happens which also sets this to false.
+ */
+ crtc->cpu_fifo_underrun_disabled = true;
+ crtc->pch_fifo_underrun_disabled = true;
+ }
}
static void intel_sanitize_encoder(struct intel_encoder *encoder)
dev_priv->pipe_to_crtc_mapping[pipe];
__intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y,
- crtc->fb);
+ crtc->primary->fb);
}
} else {
intel_modeset_update_staged_output_state(dev);
struct drm_crtc *c;
struct intel_framebuffer *fb;
+ mutex_lock(&dev->struct_mutex);
+ intel_init_gt_powersave(dev);
+ mutex_unlock(&dev->struct_mutex);
+
intel_modeset_init_hw(dev);
intel_setup_overlay(dev);
*/
mutex_lock(&dev->struct_mutex);
list_for_each_entry(c, &dev->mode_config.crtc_list, head) {
- if (!c->fb)
+ if (!c->primary->fb)
continue;
- fb = to_intel_framebuffer(c->fb);
+ fb = to_intel_framebuffer(c->primary->fb);
if (intel_pin_and_fence_fb_obj(dev, fb->obj, NULL)) {
DRM_ERROR("failed to pin boot fb on pipe %d\n",
to_intel_crtc(c)->pipe);
- drm_framebuffer_unreference(c->fb);
- c->fb = NULL;
+ drm_framebuffer_unreference(c->primary->fb);
+ c->primary->fb = NULL;
}
}
mutex_unlock(&dev->struct_mutex);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
/* Skip inactive CRTCs */
- if (!crtc->fb)
+ if (!crtc->primary->fb)
continue;
intel_increase_pllclock(crtc);
drm_mode_config_cleanup(dev);
intel_cleanup_overlay(dev);
+
+ mutex_lock(&dev->struct_mutex);
+ intel_cleanup_gt_powersave(dev);
+ mutex_unlock(&dev->struct_mutex);
}
/*
struct intel_display_error_state *
intel_display_capture_error_state(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_display_error_state *error;
int transcoders[] = {
TRANSCODER_A,
struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct drm_i915_private *dev_priv = dev->dev_private;
- return (I915_READ(_pp_ctrl_reg(intel_dp)) & EDP_FORCE_VDD) != 0;
+ return !dev_priv->pm.suspended &&
+ (I915_READ(_pp_ctrl_reg(intel_dp)) & EDP_FORCE_VDD) != 0;
}
static void
val |= EDP_PSR_LINK_DISABLE;
I915_WRITE(EDP_PSR_CTL(dev), val |
- IS_BROADWELL(dev) ? 0 : link_entry_time |
+ (IS_BROADWELL(dev) ? 0 : link_entry_time) |
max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT |
idle_frames << EDP_PSR_IDLE_FRAME_SHIFT |
EDP_PSR_ENABLE);
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = dig_port->base.base.crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct drm_i915_gem_object *obj = to_intel_framebuffer(crtc->fb)->obj;
+ struct drm_i915_gem_object *obj = to_intel_framebuffer(crtc->primary->fb)->obj;
struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base;
dev_priv->psr.source_ok = false;
return false;
}
- obj = to_intel_framebuffer(crtc->fb)->obj;
+ obj = to_intel_framebuffer(crtc->primary->fb)->obj;
if (obj->tiling_mode != I915_TILING_X ||
obj->fence_reg == I915_FENCE_REG_NONE) {
DRM_DEBUG_KMS("PSR condition failed: fb not tiled or fenced\n");
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
intel_crtc = to_intel_crtc(crtc);
- if (!intel_crtc->active || !crtc->fb) {
+ if (!intel_crtc->active || !crtc->primary->fb) {
DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
pipe_name(intel_crtc->pipe));
continue;
DRM_DEBUG_KMS("found possible fb from plane %c\n",
pipe_name(intel_crtc->pipe));
plane_config = &intel_crtc->plane_config;
- fb = to_intel_framebuffer(crtc->fb);
+ fb = to_intel_framebuffer(crtc->primary->fb);
max_size = plane_config->size;
}
}
/*
* See if the plane fb we found above will fit on this
- * pipe. Note we need to use the selected fb's bpp rather
- * than the current pipe's, since they could be different.
+ * pipe. Note we need to use the selected fb's pitch and bpp
+ * rather than the current pipe's, since they differ.
*/
- cur_size = intel_crtc->config.adjusted_mode.crtc_hdisplay *
- intel_crtc->config.adjusted_mode.crtc_vdisplay;
- DRM_DEBUG_KMS("pipe %c area: %d\n", pipe_name(intel_crtc->pipe),
+ cur_size = intel_crtc->config.adjusted_mode.crtc_hdisplay;
+ cur_size = cur_size * fb->base.bits_per_pixel / 8;
+ if (fb->base.pitches[0] < cur_size) {
+ DRM_DEBUG_KMS("fb not wide enough for plane %c (%d vs %d)\n",
+ pipe_name(intel_crtc->pipe),
+ cur_size, fb->base.pitches[0]);
+ plane_config = NULL;
+ fb = NULL;
+ break;
+ }
+
+ cur_size = intel_crtc->config.adjusted_mode.crtc_vdisplay;
+ cur_size = ALIGN(cur_size, plane_config->tiled ? (IS_GEN2(dev) ? 16 : 8) : 1);
+ cur_size *= fb->base.pitches[0];
+ DRM_DEBUG_KMS("pipe %c area: %dx%d, bpp: %d, size: %d\n",
+ pipe_name(intel_crtc->pipe),
+ intel_crtc->config.adjusted_mode.crtc_hdisplay,
+ intel_crtc->config.adjusted_mode.crtc_vdisplay,
+ fb->base.bits_per_pixel,
cur_size);
- cur_size *= fb->base.bits_per_pixel / 8;
- DRM_DEBUG_KMS("total size %d (bpp %d)\n", cur_size,
- fb->base.bits_per_pixel / 8);
if (cur_size > max_size) {
DRM_DEBUG_KMS("fb not big enough for plane %c (%d vs %d)\n",
if (!intel_crtc->active)
continue;
- WARN(!crtc->fb,
+ WARN(!crtc->primary->fb,
"re-used BIOS config but lost an fb on crtc %d\n",
crtc->base.id);
}
static struct overlay_registers __iomem *
intel_overlay_map_regs(struct intel_overlay *overlay)
{
- drm_i915_private_t *dev_priv = overlay->dev->dev_private;
+ struct drm_i915_private *dev_priv = overlay->dev->dev_private;
struct overlay_registers __iomem *regs;
if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
void (*tail)(struct intel_overlay *))
{
struct drm_device *dev = overlay->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
int ret;
bool load_polyphase_filter)
{
struct drm_device *dev = overlay->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
u32 flip_addr = overlay->flip_addr;
u32 tmp;
static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
{
struct drm_device *dev = overlay->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
int ret;
static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
{
struct drm_device *dev = overlay->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
int ret;
{
u32 key = overlay->color_key;
- switch (overlay->crtc->base.fb->bits_per_pixel) {
+ switch (overlay->crtc->base.primary->fb->bits_per_pixel) {
case 8:
iowrite32(0, ®s->DCLRKV);
iowrite32(CLK_RGB8I_MASK | DST_KEY_ENABLE, ®s->DCLRKM);
break;
case 16:
- if (overlay->crtc->base.fb->depth == 15) {
+ if (overlay->crtc->base.primary->fb->depth == 15) {
iowrite32(RGB15_TO_COLORKEY(key), ®s->DCLRKV);
iowrite32(CLK_RGB15_MASK | DST_KEY_ENABLE,
®s->DCLRKM);
static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
{
struct drm_device *dev = overlay->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 pfit_control = I915_READ(PFIT_CONTROL);
u32 ratio;
struct drm_file *file_priv)
{
struct drm_intel_overlay_put_image *put_image_rec = data;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_overlay *overlay;
struct drm_mode_object *drmmode_obj;
struct intel_crtc *crtc;
struct drm_file *file_priv)
{
struct drm_intel_overlay_attrs *attrs = data;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_overlay *overlay;
struct overlay_registers __iomem *regs;
int ret;
void intel_setup_overlay(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_overlay *overlay;
struct drm_i915_gem_object *reg_bo;
struct overlay_registers __iomem *regs;
void intel_cleanup_overlay(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
if (!dev_priv->overlay)
return;
static struct overlay_registers __iomem *
intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
{
- drm_i915_private_t *dev_priv = overlay->dev->dev_private;
+ struct drm_i915_private *dev_priv = overlay->dev->dev_private;
struct overlay_registers __iomem *regs;
if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
struct intel_overlay_error_state *
intel_overlay_capture_error_state(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_overlay *overlay = dev_priv->overlay;
struct intel_overlay_error_state *error;
struct overlay_registers __iomem *regs;
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_framebuffer *fb = crtc->fb;
+ struct drm_framebuffer *fb = crtc->primary->fb;
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
struct drm_i915_gem_object *obj = intel_fb->obj;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_framebuffer *fb = crtc->fb;
+ struct drm_framebuffer *fb = crtc->primary->fb;
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
struct drm_i915_gem_object *obj = intel_fb->obj;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_framebuffer *fb = crtc->fb;
+ struct drm_framebuffer *fb = crtc->primary->fb;
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
struct drm_i915_gem_object *obj = intel_fb->obj;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_framebuffer *fb = crtc->fb;
+ struct drm_framebuffer *fb = crtc->primary->fb;
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
struct drm_i915_gem_object *obj = intel_fb->obj;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
/* Double check that we haven't switched fb without cancelling
* the prior work.
*/
- if (work->crtc->fb == work->fb) {
+ if (work->crtc->primary->fb == work->fb) {
dev_priv->display.enable_fbc(work->crtc);
dev_priv->fbc.plane = to_intel_crtc(work->crtc)->plane;
- dev_priv->fbc.fb_id = work->crtc->fb->base.id;
+ dev_priv->fbc.fb_id = work->crtc->primary->fb->base.id;
dev_priv->fbc.y = work->crtc->y;
}
}
work->crtc = crtc;
- work->fb = crtc->fb;
+ work->fb = crtc->primary->fb;
INIT_DELAYED_WORK(&work->work, intel_fbc_work_fn);
dev_priv->fbc.fbc_work = work;
}
}
- if (!crtc || crtc->fb == NULL) {
+ if (!crtc || crtc->primary->fb == NULL) {
if (set_no_fbc_reason(dev_priv, FBC_NO_OUTPUT))
DRM_DEBUG_KMS("no output, disabling\n");
goto out_disable;
}
intel_crtc = to_intel_crtc(crtc);
- fb = crtc->fb;
+ fb = crtc->primary->fb;
intel_fb = to_intel_framebuffer(fb);
obj = intel_fb->obj;
adjusted_mode = &intel_crtc->config.adjusted_mode;
static void i915_pineview_get_mem_freq(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 tmp;
tmp = I915_READ(CLKCFG);
static void i915_ironlake_get_mem_freq(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u16 ddrpll, csipll;
ddrpll = I915_READ16(DDRMPLL1);
crtc = single_enabled_crtc(dev);
if (crtc) {
const struct drm_display_mode *adjusted_mode;
- int pixel_size = crtc->fb->bits_per_pixel / 8;
+ int pixel_size = crtc->primary->fb->bits_per_pixel / 8;
int clock;
adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
clock = adjusted_mode->crtc_clock;
htotal = adjusted_mode->crtc_htotal;
hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
- pixel_size = crtc->fb->bits_per_pixel / 8;
+ pixel_size = crtc->primary->fb->bits_per_pixel / 8;
/* Use the small buffer method to calculate plane watermark */
entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000;
/* Use the large buffer method to calculate cursor watermark */
line_time_us = max(htotal * 1000 / clock, 1);
line_count = (cursor_latency_ns / line_time_us + 1000) / 1000;
- entries = line_count * 64 * pixel_size;
+ entries = line_count * to_intel_crtc(crtc)->cursor_width * pixel_size;
tlb_miss = cursor->fifo_size*cursor->cacheline_size - hdisplay * 8;
if (tlb_miss > 0)
entries += tlb_miss;
clock = adjusted_mode->crtc_clock;
htotal = adjusted_mode->crtc_htotal;
hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
- pixel_size = crtc->fb->bits_per_pixel / 8;
+ pixel_size = crtc->primary->fb->bits_per_pixel / 8;
line_time_us = max(htotal * 1000 / clock, 1);
line_count = (latency_ns / line_time_us + 1000) / 1000;
*display_wm = entries + display->guard_size;
/* calculate the self-refresh watermark for display cursor */
- entries = line_count * pixel_size * 64;
+ entries = line_count * pixel_size * to_intel_crtc(crtc)->cursor_width;
entries = DIV_ROUND_UP(entries, cursor->cacheline_size);
*cursor_wm = entries + cursor->guard_size;
return false;
clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock;
- pixel_size = crtc->fb->bits_per_pixel / 8; /* BPP */
+ pixel_size = crtc->primary->fb->bits_per_pixel / 8; /* BPP */
entries = (clock / 1000) * pixel_size;
*plane_prec_mult = (entries > 256) ?
int clock = adjusted_mode->crtc_clock;
int htotal = adjusted_mode->crtc_htotal;
int hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
- int pixel_size = crtc->fb->bits_per_pixel / 8;
+ int pixel_size = crtc->primary->fb->bits_per_pixel / 8;
unsigned long line_time_us;
int entries;
entries, srwm);
entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) *
- pixel_size * 64;
+ pixel_size * to_intel_crtc(crtc)->cursor_width;
entries = DIV_ROUND_UP(entries,
i965_cursor_wm_info.cacheline_size);
cursor_sr = i965_cursor_wm_info.fifo_size -
crtc = intel_get_crtc_for_plane(dev, 0);
if (intel_crtc_active(crtc)) {
const struct drm_display_mode *adjusted_mode;
- int cpp = crtc->fb->bits_per_pixel / 8;
+ int cpp = crtc->primary->fb->bits_per_pixel / 8;
if (IS_GEN2(dev))
cpp = 4;
crtc = intel_get_crtc_for_plane(dev, 1);
if (intel_crtc_active(crtc)) {
const struct drm_display_mode *adjusted_mode;
- int cpp = crtc->fb->bits_per_pixel / 8;
+ int cpp = crtc->primary->fb->bits_per_pixel / 8;
if (IS_GEN2(dev))
cpp = 4;
int clock = adjusted_mode->crtc_clock;
int htotal = adjusted_mode->crtc_htotal;
int hdisplay = to_intel_crtc(enabled)->config.pipe_src_w;
- int pixel_size = enabled->fb->bits_per_pixel / 8;
+ int pixel_size = enabled->primary->fb->bits_per_pixel / 8;
unsigned long line_time_us;
int entries;
if (p->active) {
p->pipe_htotal = intel_crtc->config.adjusted_mode.crtc_htotal;
p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc);
- p->pri.bytes_per_pixel = crtc->fb->bits_per_pixel / 8;
+ p->pri.bytes_per_pixel = crtc->primary->fb->bits_per_pixel / 8;
p->cur.bytes_per_pixel = 4;
p->pri.horiz_pixels = intel_crtc->config.pipe_src_w;
- p->cur.horiz_pixels = 64;
+ p->cur.horiz_pixels = intel_crtc->cursor_width;
/* TODO: for now, assume primary and cursor planes are always enabled. */
p->pri.enabled = true;
p->cur.enabled = true;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
config->num_pipes_active += intel_crtc_active(crtc);
- list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+ drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) {
struct intel_plane *intel_plane = to_intel_plane(plane);
if (intel_plane->pipe == pipe)
dev_priv->rps.last_adj = 0;
}
+ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val)
+ {
+ u32 mask = 0;
+
+ if (val > dev_priv->rps.min_freq_softlimit)
+ mask |= GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT;
+ if (val < dev_priv->rps.max_freq_softlimit)
+ mask |= GEN6_PM_RP_UP_THRESHOLD;
+
+ /* IVB and SNB hard hangs on looping batchbuffer
+ * if GEN6_PM_UP_EI_EXPIRED is masked.
+ */
+ if (INTEL_INFO(dev_priv->dev)->gen <= 7 && !IS_HASWELL(dev_priv->dev))
+ mask |= GEN6_PM_RP_UP_EI_EXPIRED;
+
+ return ~mask;
+ }
+
/* gen6_set_rps is called to update the frequency request, but should also be
* called when the range (min_delay and max_delay) is modified so that we can
* update the GEN6_RP_INTERRUPT_LIMITS register accordingly. */
WARN_ON(val > dev_priv->rps.max_freq_softlimit);
WARN_ON(val < dev_priv->rps.min_freq_softlimit);
- if (val == dev_priv->rps.cur_freq) {
- /* min/max delay may still have been modified so be sure to
- * write the limits value */
- I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
- gen6_rps_limits(dev_priv, val));
+ /* min/max delay may still have been modified so be sure to
+ * write the limits value.
+ */
+ if (val != dev_priv->rps.cur_freq) {
+ gen6_set_rps_thresholds(dev_priv, val);
- return;
+ if (IS_HASWELL(dev))
+ I915_WRITE(GEN6_RPNSWREQ,
+ HSW_FREQUENCY(val));
+ else
+ I915_WRITE(GEN6_RPNSWREQ,
+ GEN6_FREQUENCY(val) |
+ GEN6_OFFSET(0) |
+ GEN6_AGGRESSIVE_TURBO);
}
- gen6_set_rps_thresholds(dev_priv, val);
-
- if (IS_HASWELL(dev))
- I915_WRITE(GEN6_RPNSWREQ,
- HSW_FREQUENCY(val));
- else
- I915_WRITE(GEN6_RPNSWREQ,
- GEN6_FREQUENCY(val) |
- GEN6_OFFSET(0) |
- GEN6_AGGRESSIVE_TURBO);
-
/* Make sure we continue to get interrupts
* until we hit the minimum or maximum frequencies.
*/
- I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
- gen6_rps_limits(dev_priv, val));
+ I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, gen6_rps_limits(dev_priv, val));
+ I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val));
POSTING_READ(GEN6_RPNSWREQ);
dev_priv->rps.cur_freq = val;
-
trace_intel_gpu_freq_change(val * 50);
}
I915_READ(VLV_GTLC_SURVIVABILITY_REG) &
~VLV_GFX_CLK_FORCE_ON_BIT);
- /* Unmask Up interrupts */
- dev_priv->rps.rp_up_masked = true;
- gen6_set_pm_mask(dev_priv, GEN6_PM_RP_DOWN_THRESHOLD,
- dev_priv->rps.min_freq_softlimit);
+ I915_WRITE(GEN6_PMINTRMSK,
+ gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq));
}
void gen6_rps_idle(struct drm_i915_private *dev_priv)
dev_priv->rps.cur_freq,
vlv_gpu_freq(dev_priv, val), val);
- if (val == dev_priv->rps.cur_freq)
- return;
+ if (val != dev_priv->rps.cur_freq)
+ vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val);
- vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val);
+ I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val));
dev_priv->rps.cur_freq = val;
-
trace_intel_gpu_freq_change(vlv_gpu_freq(dev_priv, val));
}
struct drm_i915_private *dev_priv = dev->dev_private;
I915_WRITE(GEN6_PMINTRMSK, 0xffffffff);
- I915_WRITE(GEN6_PMIER, I915_READ(GEN6_PMIER) & ~GEN6_PM_RPS_EVENTS);
+ I915_WRITE(GEN6_PMIER, I915_READ(GEN6_PMIER) &
+ ~dev_priv->pm_rps_events);
/* Complete PM interrupt masking here doesn't race with the rps work
* item again unmasking PM interrupts because that is using a different
* register (PMIMR) to mask PM interrupts. The only risk is in leaving
dev_priv->rps.pm_iir = 0;
spin_unlock_irq(&dev_priv->irq_lock);
- I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS);
+ I915_WRITE(GEN6_PMIIR, dev_priv->pm_rps_events);
}
static void gen6_disable_rps(struct drm_device *dev)
I915_WRITE(GEN6_RC_CONTROL, 0);
gen6_disable_rps_interrupts(dev);
-
- if (dev_priv->vlv_pctx) {
- drm_gem_object_unreference(&dev_priv->vlv_pctx->base);
- dev_priv->vlv_pctx = NULL;
- }
}
static void intel_print_rc6_info(struct drm_device *dev, u32 mode)
static void gen6_enable_rps_interrupts(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- u32 enabled_intrs;
spin_lock_irq(&dev_priv->irq_lock);
WARN_ON(dev_priv->rps.pm_iir);
- snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS);
- I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS);
+ snb_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
+ I915_WRITE(GEN6_PMIIR, dev_priv->pm_rps_events);
spin_unlock_irq(&dev_priv->irq_lock);
-
- /* only unmask PM interrupts we need. Mask all others. */
- enabled_intrs = GEN6_PM_RPS_EVENTS;
-
- /* IVB and SNB hard hangs on looping batchbuffer
- * if GEN6_PM_UP_EI_EXPIRED is masked.
- */
- if (INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev))
- enabled_intrs |= GEN6_PM_RP_UP_EI_EXPIRED;
-
- I915_WRITE(GEN6_PMINTRMSK, ~enabled_intrs);
}
static void gen8_enable_rps(struct drm_device *dev)
return vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM) & 0xff;
}
+ /* Check that the pctx buffer wasn't move under us. */
+ static void valleyview_check_pctx(struct drm_i915_private *dev_priv)
+ {
+ unsigned long pctx_addr = I915_READ(VLV_PCBR) & ~4095;
+
+ WARN_ON(pctx_addr != dev_priv->mm.stolen_base +
+ dev_priv->vlv_pctx->stolen->start);
+ }
+
static void valleyview_setup_pctx(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
dev_priv->vlv_pctx = pctx;
}
+ static void valleyview_cleanup_pctx(struct drm_device *dev)
+ {
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (WARN_ON(!dev_priv->vlv_pctx))
+ return;
+
+ drm_gem_object_unreference(&dev_priv->vlv_pctx->base);
+ dev_priv->vlv_pctx = NULL;
+ }
+
static void valleyview_enable_rps(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+ valleyview_check_pctx(dev_priv);
+
if ((gtfifodbg = I915_READ(GTFIFODBG))) {
DRM_DEBUG_DRIVER("GT fifo had a previous error %x\n",
gtfifodbg);
valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq);
- dev_priv->rps.rp_up_masked = false;
- dev_priv->rps.rp_down_masked = false;
-
gen6_enable_rps_interrupts(dev);
gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
dev_priv->ips.corr = (lcfuse & LCFUSE_HIV_MASK);
}
+ void intel_init_gt_powersave(struct drm_device *dev)
+ {
+ if (IS_VALLEYVIEW(dev))
+ valleyview_setup_pctx(dev);
+ }
+
+ void intel_cleanup_gt_powersave(struct drm_device *dev)
+ {
+ if (IS_VALLEYVIEW(dev))
+ valleyview_cleanup_pctx(dev);
+ }
+
void intel_disable_gt_powersave(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
ironlake_enable_rc6(dev);
intel_init_emon(dev);
} else if (IS_GEN6(dev) || IS_GEN7(dev)) {
- if (IS_VALLEYVIEW(dev))
- valleyview_setup_pctx(dev);
/*
* PCU communication is slow and this doesn't need to be
* done at any specific time, so do this out of our fast path
/* WaDisableSDEUnitClockGating:bdw */
I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
+
+ /* Wa4x4STCOptimizationDisable:bdw */
+ I915_WRITE(CACHE_MODE_1,
+ _MASKED_BIT_ENABLE(GEN8_4x4_STC_OPTIMIZATION_DISABLE));
}
static void haswell_init_clock_gating(struct drm_device *dev)
mutex_unlock(&dev_priv->rps.hw_lock);
switch ((val >> 6) & 3) {
case 0:
- dev_priv->mem_freq = 800;
- break;
case 1:
- dev_priv->mem_freq = 1066;
+ dev_priv->mem_freq = 800;
break;
case 2:
- dev_priv->mem_freq = 1333;
+ dev_priv->mem_freq = 1066;
break;
case 3:
dev_priv->mem_freq = 1333;
bool is_enabled;
int i;
+ if (dev_priv->pm.suspended)
+ return false;
+
power_domains = &dev_priv->power_domains;
is_enabled = true;
#include <core/client.h>
#include <core/gpuobj.h>
#include <core/class.h>
+#include <core/option.h>
#include <engine/device.h>
#include <engine/disp.h>
static struct drm_driver driver;
static u64
-nouveau_name(struct pci_dev *pdev)
+nouveau_pci_name(struct pci_dev *pdev)
{
u64 name = (u64)pci_domain_nr(pdev->bus) << 32;
name |= pdev->bus->number << 16;
return name | PCI_FUNC(pdev->devfn);
}
+static u64
+nouveau_platform_name(struct platform_device *platformdev)
+{
+ return platformdev->id;
+}
+
+static u64
+nouveau_name(struct drm_device *dev)
+{
+ if (dev->pdev)
+ return nouveau_pci_name(dev->pdev);
+ else
+ return nouveau_platform_name(dev->platformdev);
+}
+
static int
-nouveau_cli_create(struct pci_dev *pdev, const char *name,
+nouveau_cli_create(u64 name, const char *sname,
int size, void **pcli)
{
struct nouveau_cli *cli;
int ret;
*pcli = NULL;
- ret = nouveau_client_create_(name, nouveau_name(pdev), nouveau_config,
+ ret = nouveau_client_create_(sname, name, nouveau_config,
nouveau_debug, size, pcli);
cli = *pcli;
if (ret) {
remove_conflicting_framebuffers(aper, "nouveaufb", boot);
kfree(aper);
- ret = nouveau_device_create(pdev, nouveau_name(pdev), pci_name(pdev),
+ ret = nouveau_device_create(pdev, NOUVEAU_BUS_PCI,
+ nouveau_pci_name(pdev), pci_name(pdev),
nouveau_config, nouveau_debug, &device);
if (ret)
return ret;
#define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403
static void
-nouveau_get_hdmi_dev(struct drm_device *dev)
+nouveau_get_hdmi_dev(struct nouveau_drm *drm)
{
- struct nouveau_drm *drm = dev->dev_private;
- struct pci_dev *pdev = dev->pdev;
+ struct pci_dev *pdev = drm->dev->pdev;
+
+ if (!pdev) {
+ DRM_INFO("not a PCI device; no HDMI\n");
+ drm->hdmi_device = NULL;
+ return;
+ }
/* subfunction one is a hdmi audio device? */
drm->hdmi_device = pci_get_bus_and_slot((unsigned int)pdev->bus->number,
PCI_DEVFN(PCI_SLOT(pdev->devfn), 1));
if (!drm->hdmi_device) {
- DRM_INFO("hdmi device not found %d %d %d\n", pdev->bus->number, PCI_SLOT(pdev->devfn), 1);
+ NV_DEBUG(drm, "hdmi device not found %d %d %d\n", pdev->bus->number, PCI_SLOT(pdev->devfn), 1);
return;
}
if ((drm->hdmi_device->class >> 8) != PCI_CLASS_MULTIMEDIA_HD_AUDIO) {
- DRM_INFO("possible hdmi device not audio %d\n", drm->hdmi_device->class);
+ NV_DEBUG(drm, "possible hdmi device not audio %d\n", drm->hdmi_device->class);
pci_dev_put(drm->hdmi_device);
drm->hdmi_device = NULL;
return;
struct nouveau_drm *drm;
int ret;
- ret = nouveau_cli_create(pdev, "DRM", sizeof(*drm), (void**)&drm);
+ ret = nouveau_cli_create(nouveau_name(dev), "DRM", sizeof(*drm),
+ (void **)&drm);
if (ret)
return ret;
dev->dev_private = drm;
drm->dev = dev;
+ nouveau_client(drm)->debug = nouveau_dbgopt(nouveau_debug, "DRM");
INIT_LIST_HEAD(&drm->clients);
spin_lock_init(&drm->tile.lock);
- nouveau_get_hdmi_dev(dev);
+ nouveau_get_hdmi_dev(drm);
/* make sure AGP controller is in a consistent state before we
* (possibly) execute vbios init tables (see nouveau_agp.h)
*/
- if (drm_pci_device_is_agp(dev) && dev->agp) {
+ if (pdev && drm_pci_device_is_agp(dev) && dev->agp) {
/* dummy device object, doesn't init anything, but allows
* agp code access to registers
*/
}
static int
-nouveau_do_suspend(struct drm_device *dev)
+nouveau_do_suspend(struct drm_device *dev, bool runtime)
{
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_cli *cli;
int ret;
- if (dev->mode_config.num_crtc) {
+ if (dev->mode_config.num_crtc && !runtime) {
NV_INFO(drm, "suspending display...\n");
ret = nouveau_display_suspend(dev);
if (ret)
if (drm_dev->mode_config.num_crtc)
nouveau_fbcon_set_suspend(drm_dev, 1);
- ret = nouveau_do_suspend(drm_dev);
+ ret = nouveau_do_suspend(drm_dev, false);
if (ret)
return ret;
if (drm_dev->mode_config.num_crtc)
nouveau_fbcon_set_suspend(drm_dev, 1);
- ret = nouveau_do_suspend(drm_dev);
+ ret = nouveau_do_suspend(drm_dev, false);
return ret;
}
static int
nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv)
{
- struct pci_dev *pdev = dev->pdev;
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_cli *cli;
char name[32], tmpname[TASK_COMM_LEN];
/* need to bring up power immediately if opening device */
ret = pm_runtime_get_sync(dev->dev);
- if (ret < 0)
+ if (ret < 0 && ret != -EACCES)
return ret;
get_task_comm(tmpname, current);
snprintf(name, sizeof(name), "%s[%d]", tmpname, pid_nr(fpriv->pid));
- ret = nouveau_cli_create(pdev, name, sizeof(*cli), (void **)&cli);
+ ret = nouveau_cli_create(nouveau_name(dev), name, sizeof(*cli),
+ (void **)&cli);
+
if (ret)
goto out_suspend;
dev = file_priv->minor->dev;
ret = pm_runtime_get_sync(dev->dev);
- if (ret < 0)
+ if (ret < 0 && ret != -EACCES)
return ret;
ret = drm_ioctl(filp, cmd, arg);
struct drm_device *drm_dev = pci_get_drvdata(pdev);
int ret;
- if (nouveau_runtime_pm == 0)
- return -EINVAL;
+ if (nouveau_runtime_pm == 0) {
+ pm_runtime_forbid(dev);
+ return -EBUSY;
+ }
/* are we optimus enabled? */
if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) {
DRM_DEBUG_DRIVER("failing to power off - not optimus\n");
- return -EINVAL;
+ pm_runtime_forbid(dev);
+ return -EBUSY;
}
nv_debug_level(SILENT);
drm_kms_helper_poll_disable(drm_dev);
vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF);
nouveau_switcheroo_optimus_dsm();
- ret = nouveau_do_suspend(drm_dev);
+ ret = nouveau_do_suspend(drm_dev, true);
pci_save_state(pdev);
pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3cold);
pci_set_master(pdev);
ret = nouveau_do_resume(drm_dev);
- if (drm_dev->mode_config.num_crtc)
- nouveau_display_resume(drm_dev);
drm_kms_helper_poll_enable(drm_dev);
/* do magic */
nv_mask(device, 0x88488, (1 << 25), (1 << 25));
struct nouveau_drm *drm = nouveau_drm(drm_dev);
struct drm_crtc *crtc;
- if (nouveau_runtime_pm == 0)
+ if (nouveau_runtime_pm == 0) {
+ pm_runtime_forbid(dev);
return -EBUSY;
+ }
/* are we optimus enabled? */
if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) {
DRM_DEBUG_DRIVER("failing to power off - not optimus\n");
+ pm_runtime_forbid(dev);
return -EBUSY;
}
.driver.pm = &nouveau_pm_ops,
};
+int nouveau_drm_platform_probe(struct platform_device *pdev)
+{
+ struct nouveau_device *device;
+ int ret;
+
+ ret = nouveau_device_create(pdev, NOUVEAU_BUS_PLATFORM,
+ nouveau_platform_name(pdev),
+ dev_name(&pdev->dev), nouveau_config,
+ nouveau_debug, &device);
+
+ ret = drm_platform_init(&driver, pdev);
+ if (ret) {
+ nouveau_object_ref(NULL, (struct nouveau_object **)&device);
+ return ret;
+ }
+
+ return ret;
+}
+
static int __init
nouveau_drm_init(void)
{