Commit e6dfcc53 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-next-2013-06-01' of...

Merge tag 'drm-intel-next-2013-06-01' of git://people.freedesktop.org/~danvet/drm-intel into drm-next

Daniel writes:
Another round of drm-intel-next for 3.11. Highlights:
- Haswell IPS support (Paulo Zanoni)
- VECS support on Haswell (Ben Widawsky, Xiang Haihao, ...)
- Haswell watermark fixes (Paulo Zanoni)
- "Make the gun bigger again" multithread fence fix from Chris.
- i915_error_state finnally no longer fails with -ENOMEM! Big thanks to
  Mika for tackling this.
- vlv sideband locking fixes from Jani
- Hangcheck prep work for arb_robustness support (Mika&Chris)
- edp vs cpu port confusion clean-up from Imre
- pile of smaller fixes and cleanups all over.

* tag 'drm-intel-next-2013-06-01' of git://people.freedesktop.org/~danvet/drm-intel: (70 commits)
  drm/i915: add i915_ips_status debugfs entry
  drm/i915: add enable_ips module option
  drm/i915: implement IPS feature
  drm/i915: fix up the edp power well check
  drm/i915: add I915_PARAM_HAS_VEBOX to i915_getparam
  drm/i915: add I915_EXEC_VEBOX to i915_gem_do_execbuffer()
  drm/i915: add VEBOX into debugfs
  drm/i915: Enable vebox interrupts
  drm/i915: vebox interrupt get/put
  drm/i915: consolidate interrupt naming scheme
  drm/i915: Convert irq_refounct to struct
  drm/i915: make PM interrupt writes non-destructive
  drm/i915: Add PM regs to pre/post install
  drm/i915: Create an ivybridge_irq_preinstall
  drm/i915: Create a more generic pm handler for hsw+
  drm/i915: add support for 5/6 data buffer partitioning on Haswell
  drm/i915: properly set HSW WM_LP watermarks
  drm/i915: properly set HSW WM_PIPE registers
  drm/i915: fix pch_nop support
  drm/i915: Vebox ringbuffer init
  ...
parents 9bc3cd56 92d44621
...@@ -1653,8 +1653,6 @@ void intel_crt_init(struct drm_device *dev) ...@@ -1653,8 +1653,6 @@ void intel_crt_init(struct drm_device *dev)
<sect2> <sect2>
<title>KMS API Functions</title> <title>KMS API Functions</title>
!Edrivers/gpu/drm/drm_crtc.c !Edrivers/gpu/drm/drm_crtc.c
!Edrivers/gpu/drm/drm_rect.c
!Finclude/drm/drm_rect.h
</sect2> </sect2>
</sect1> </sect1>
...@@ -2163,6 +2161,12 @@ void intel_crt_init(struct drm_device *dev) ...@@ -2163,6 +2161,12 @@ void intel_crt_init(struct drm_device *dev)
<title>EDID Helper Functions Reference</title> <title>EDID Helper Functions Reference</title>
!Edrivers/gpu/drm/drm_edid.c !Edrivers/gpu/drm/drm_edid.c
</sect2> </sect2>
<sect2>
<title>Rectangle Utilities Reference</title>
!Pinclude/drm/drm_rect.h rect utils
!Iinclude/drm/drm_rect.h
!Edrivers/gpu/drm/drm_rect.c
</sect2>
</sect1> </sect1>
<!-- Internals: vertical blanking --> <!-- Internals: vertical blanking -->
......
...@@ -36,6 +36,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \ ...@@ -36,6 +36,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
intel_overlay.o \ intel_overlay.o \
intel_sprite.o \ intel_sprite.o \
intel_opregion.o \ intel_opregion.o \
intel_sideband.o \
dvo_ch7xxx.o \ dvo_ch7xxx.o \
dvo_ch7017.o \ dvo_ch7017.o \
dvo_ivch.o \ dvo_ivch.o \
......
This diff is collapsed.
...@@ -955,6 +955,9 @@ static int i915_getparam(struct drm_device *dev, void *data, ...@@ -955,6 +955,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_HAS_BLT: case I915_PARAM_HAS_BLT:
value = intel_ring_initialized(&dev_priv->ring[BCS]); value = intel_ring_initialized(&dev_priv->ring[BCS]);
break; break;
case I915_PARAM_HAS_VEBOX:
value = intel_ring_initialized(&dev_priv->ring[VECS]);
break;
case I915_PARAM_HAS_RELAXED_FENCING: case I915_PARAM_HAS_RELAXED_FENCING:
value = 1; value = 1;
break; break;
...@@ -1358,8 +1361,10 @@ static int i915_load_modeset_init(struct drm_device *dev) ...@@ -1358,8 +1361,10 @@ static int i915_load_modeset_init(struct drm_device *dev)
cleanup_gem: cleanup_gem:
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
i915_gem_cleanup_ringbuffer(dev); i915_gem_cleanup_ringbuffer(dev);
i915_gem_context_fini(dev);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
i915_gem_cleanup_aliasing_ppgtt(dev); i915_gem_cleanup_aliasing_ppgtt(dev);
drm_mm_takedown(&dev_priv->mm.gtt_space);
cleanup_irq: cleanup_irq:
drm_irq_uninstall(dev); drm_irq_uninstall(dev);
cleanup_gem_stolen: cleanup_gem_stolen:
...@@ -1407,7 +1412,7 @@ static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) ...@@ -1407,7 +1412,7 @@ static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
return; return;
ap->ranges[0].base = dev_priv->gtt.mappable_base; ap->ranges[0].base = dev_priv->gtt.mappable_base;
ap->ranges[0].size = dev_priv->gtt.mappable_end - dev_priv->gtt.start; ap->ranges[0].size = dev_priv->gtt.mappable_end;
primary = primary =
pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
...@@ -1744,6 +1749,7 @@ int i915_driver_unload(struct drm_device *dev) ...@@ -1744,6 +1749,7 @@ int i915_driver_unload(struct drm_device *dev)
i915_free_hws(dev); i915_free_hws(dev);
} }
drm_mm_takedown(&dev_priv->mm.gtt_space);
if (dev_priv->regs != NULL) if (dev_priv->regs != NULL)
pci_iounmap(dev->pdev, dev_priv->regs); pci_iounmap(dev->pdev, dev_priv->regs);
...@@ -1753,6 +1759,8 @@ int i915_driver_unload(struct drm_device *dev) ...@@ -1753,6 +1759,8 @@ int i915_driver_unload(struct drm_device *dev)
destroy_workqueue(dev_priv->wq); destroy_workqueue(dev_priv->wq);
pm_qos_remove_request(&dev_priv->pm_qos); pm_qos_remove_request(&dev_priv->pm_qos);
dev_priv->gtt.gtt_remove(dev);
if (dev_priv->slab) if (dev_priv->slab)
kmem_cache_destroy(dev_priv->slab); kmem_cache_destroy(dev_priv->slab);
......
...@@ -128,6 +128,10 @@ module_param_named(disable_power_well, i915_disable_power_well, int, 0600); ...@@ -128,6 +128,10 @@ module_param_named(disable_power_well, i915_disable_power_well, int, 0600);
MODULE_PARM_DESC(disable_power_well, MODULE_PARM_DESC(disable_power_well,
"Disable the power well when possible (default: false)"); "Disable the power well when possible (default: false)");
int i915_enable_ips __read_mostly = 1;
module_param_named(enable_ips, i915_enable_ips, int, 0600);
MODULE_PARM_DESC(enable_ips, "Enable IPS (default: true)");
static struct drm_driver driver; static struct drm_driver driver;
extern int intel_agp_enabled; extern int intel_agp_enabled;
...@@ -311,6 +315,7 @@ static const struct intel_device_info intel_haswell_d_info = { ...@@ -311,6 +315,7 @@ static const struct intel_device_info intel_haswell_d_info = {
.is_haswell = 1, .is_haswell = 1,
.has_ddi = 1, .has_ddi = 1,
.has_fpga_dbg = 1, .has_fpga_dbg = 1,
.has_vebox_ring = 1,
}; };
static const struct intel_device_info intel_haswell_m_info = { static const struct intel_device_info intel_haswell_m_info = {
...@@ -320,6 +325,7 @@ static const struct intel_device_info intel_haswell_m_info = { ...@@ -320,6 +325,7 @@ static const struct intel_device_info intel_haswell_m_info = {
.has_ddi = 1, .has_ddi = 1,
.has_fpga_dbg = 1, .has_fpga_dbg = 1,
.has_fbc = 1, .has_fbc = 1,
.has_vebox_ring = 1,
}; };
static const struct pci_device_id pciidlist[] = { /* aka */ static const struct pci_device_id pciidlist[] = { /* aka */
...@@ -863,37 +869,14 @@ static int gen6_do_reset(struct drm_device *dev) ...@@ -863,37 +869,14 @@ static int gen6_do_reset(struct drm_device *dev)
int intel_gpu_reset(struct drm_device *dev) int intel_gpu_reset(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private;
int ret = -ENODEV;
switch (INTEL_INFO(dev)->gen) { switch (INTEL_INFO(dev)->gen) {
case 7: case 7:
case 6: case 6: return gen6_do_reset(dev);
ret = gen6_do_reset(dev); case 5: return ironlake_do_reset(dev);
break; case 4: return i965_do_reset(dev);
case 5: case 2: return i8xx_do_reset(dev);
ret = ironlake_do_reset(dev); default: return -ENODEV;
break;
case 4:
ret = i965_do_reset(dev);
break;
case 2:
ret = i8xx_do_reset(dev);
break;
} }
/* Also reset the gpu hangman. */
if (dev_priv->gpu_error.stop_rings) {
DRM_INFO("Simulated gpu hang, resetting stop_rings\n");
dev_priv->gpu_error.stop_rings = 0;
if (ret == -ENODEV) {
DRM_ERROR("Reset not implemented, but ignoring "
"error for simulated gpu hangs\n");
ret = 0;
}
}
return ret;
} }
/** /**
...@@ -914,6 +897,7 @@ int intel_gpu_reset(struct drm_device *dev) ...@@ -914,6 +897,7 @@ int intel_gpu_reset(struct drm_device *dev)
int i915_reset(struct drm_device *dev) int i915_reset(struct drm_device *dev)
{ {
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
bool simulated;
int ret; int ret;
if (!i915_try_reset) if (!i915_try_reset)
...@@ -923,13 +907,26 @@ int i915_reset(struct drm_device *dev) ...@@ -923,13 +907,26 @@ int i915_reset(struct drm_device *dev)
i915_gem_reset(dev); i915_gem_reset(dev);
ret = -ENODEV; simulated = dev_priv->gpu_error.stop_rings != 0;
if (get_seconds() - dev_priv->gpu_error.last_reset < 5)
if (!simulated && get_seconds() - dev_priv->gpu_error.last_reset < 5) {
DRM_ERROR("GPU hanging too fast, declaring wedged!\n"); DRM_ERROR("GPU hanging too fast, declaring wedged!\n");
else ret = -ENODEV;
} else {
ret = intel_gpu_reset(dev); ret = intel_gpu_reset(dev);
dev_priv->gpu_error.last_reset = get_seconds(); /* Also reset the gpu hangman. */
if (simulated) {
DRM_INFO("Simulated gpu hang, resetting stop_rings\n");
dev_priv->gpu_error.stop_rings = 0;
if (ret == -ENODEV) {
DRM_ERROR("Reset not implemented, but ignoring "
"error for simulated gpu hangs\n");
ret = 0;
}
} else
dev_priv->gpu_error.last_reset = get_seconds();
}
if (ret) { if (ret) {
DRM_ERROR("Failed to reset chip.\n"); DRM_ERROR("Failed to reset chip.\n");
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
......
...@@ -315,9 +315,8 @@ struct drm_i915_display_funcs { ...@@ -315,9 +315,8 @@ struct drm_i915_display_funcs {
int (*get_fifo_size)(struct drm_device *dev, int plane); int (*get_fifo_size)(struct drm_device *dev, int plane);
void (*update_wm)(struct drm_device *dev); void (*update_wm)(struct drm_device *dev);
void (*update_sprite_wm)(struct drm_device *dev, int pipe, void (*update_sprite_wm)(struct drm_device *dev, int pipe,
uint32_t sprite_width, int pixel_size); uint32_t sprite_width, int pixel_size,
void (*update_linetime_wm)(struct drm_device *dev, int pipe, bool enable);
struct drm_display_mode *mode);
void (*modeset_global_resources)(struct drm_device *dev); void (*modeset_global_resources)(struct drm_device *dev);
/* 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,
* fills out the pipe-config with the hw state. */ * fills out the pipe-config with the hw state. */
...@@ -375,6 +374,7 @@ struct drm_i915_gt_funcs { ...@@ -375,6 +374,7 @@ struct drm_i915_gt_funcs {
func(supports_tv) sep \ func(supports_tv) sep \
func(has_bsd_ring) sep \ func(has_bsd_ring) sep \
func(has_blt_ring) sep \ func(has_blt_ring) sep \
func(has_vebox_ring) sep \
func(has_llc) sep \ func(has_llc) sep \
func(has_ddi) sep \ func(has_ddi) sep \
func(has_fpga_dbg) func(has_fpga_dbg)
...@@ -828,14 +828,21 @@ struct i915_gem_mm { ...@@ -828,14 +828,21 @@ struct i915_gem_mm {
u32 object_count; u32 object_count;
}; };
struct drm_i915_error_state_buf {
unsigned bytes;
unsigned size;
int err;
u8 *buf;
loff_t start;
loff_t pos;
};
struct i915_gpu_error { struct i915_gpu_error {
/* For hangcheck timer */ /* For hangcheck timer */
#define DRM_I915_HANGCHECK_PERIOD 1500 /* in ms */ #define DRM_I915_HANGCHECK_PERIOD 1500 /* in ms */
#define DRM_I915_HANGCHECK_JIFFIES msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD) #define DRM_I915_HANGCHECK_JIFFIES msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)
struct timer_list hangcheck_timer; struct timer_list hangcheck_timer;
int hangcheck_count; int hangcheck_count;
uint32_t last_acthd[I915_NUM_RINGS];
uint32_t prev_instdone[I915_NUM_INSTDONE_REG];
/* For reset and error_state handling. */ /* For reset and error_state handling. */
spinlock_t lock; spinlock_t lock;
...@@ -1367,6 +1374,7 @@ struct drm_i915_file_private { ...@@ -1367,6 +1374,7 @@ struct drm_i915_file_private {
#define HAS_BSD(dev) (INTEL_INFO(dev)->has_bsd_ring) #define HAS_BSD(dev) (INTEL_INFO(dev)->has_bsd_ring)
#define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring) #define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring)
#define HAS_VEBOX(dev) (INTEL_INFO(dev)->has_vebox_ring)
#define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc) #define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc)
#define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws)
...@@ -1462,6 +1470,7 @@ extern bool i915_enable_hangcheck __read_mostly; ...@@ -1462,6 +1470,7 @@ extern bool i915_enable_hangcheck __read_mostly;
extern int i915_enable_ppgtt __read_mostly; extern int i915_enable_ppgtt __read_mostly;
extern unsigned int i915_preliminary_hw_support __read_mostly; extern unsigned int i915_preliminary_hw_support __read_mostly;
extern int i915_disable_power_well __read_mostly; extern int i915_disable_power_well __read_mostly;
extern int i915_enable_ips __read_mostly;
extern int i915_suspend(struct drm_device *dev, pm_message_t state); extern int i915_suspend(struct drm_device *dev, pm_message_t state);
extern int i915_resume(struct drm_device *dev); extern int i915_resume(struct drm_device *dev);
...@@ -1820,6 +1829,8 @@ void i915_gem_dump_object(struct drm_i915_gem_object *obj, int len, ...@@ -1820,6 +1829,8 @@ void i915_gem_dump_object(struct drm_i915_gem_object *obj, int len,
/* i915_debugfs.c */ /* i915_debugfs.c */
int i915_debugfs_init(struct drm_minor *minor); int i915_debugfs_init(struct drm_minor *minor);
void i915_debugfs_cleanup(struct drm_minor *minor); void i915_debugfs_cleanup(struct drm_minor *minor);
__printf(2, 3)
void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...);
/* i915_suspend.c */ /* i915_suspend.c */
extern int i915_save_state(struct drm_device *dev); extern int i915_save_state(struct drm_device *dev);
...@@ -1901,10 +1912,11 @@ int i915_reg_read_ioctl(struct drm_device *dev, void *data, ...@@ -1901,10 +1912,11 @@ int i915_reg_read_ioctl(struct drm_device *dev, void *data,
/* overlay */ /* overlay */
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev);
extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error); extern void intel_overlay_print_error_state(struct drm_i915_error_state_buf *e,
struct intel_overlay_error_state *error);
extern struct intel_display_error_state *intel_display_capture_error_state(struct drm_device *dev); extern struct intel_display_error_state *intel_display_capture_error_state(struct drm_device *dev);
extern void intel_display_print_error_state(struct seq_file *m, extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
struct drm_device *dev, struct drm_device *dev,
struct intel_display_error_state *error); struct intel_display_error_state *error);
#endif #endif
...@@ -1919,9 +1931,17 @@ int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv); ...@@ -1919,9 +1931,17 @@ int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv);
int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val); int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val);
int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val); int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val);
int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val);
int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val); /* intel_sideband.c */
int valleyview_nc_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val); u32 vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr);
void vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val);
u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr);
u32 vlv_dpio_read(struct drm_i915_private *dev_priv, int reg);
void vlv_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val);
u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
enum intel_sbi_destination destination);
void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
enum intel_sbi_destination destination);
int vlv_gpu_freq(int ddr_freq, int val); int vlv_gpu_freq(int ddr_freq, int val);
int vlv_freq_opcode(int ddr_freq, int val); int vlv_freq_opcode(int ddr_freq, int val);
......
...@@ -2693,18 +2693,33 @@ static inline int fence_number(struct drm_i915_private *dev_priv, ...@@ -2693,18 +2693,33 @@ static inline int fence_number(struct drm_i915_private *dev_priv,
return fence - dev_priv->fence_regs; return fence - dev_priv->fence_regs;
} }
struct write_fence {
struct drm_device *dev;
struct drm_i915_gem_object *obj;
int fence;
};
static void i915_gem_write_fence__ipi(void *data) static void i915_gem_write_fence__ipi(void *data)
{ {
struct write_fence *args = data;
/* Required for SNB+ with LLC */
wbinvd(); wbinvd();
/* Required for VLV */
i915_gem_write_fence(args->dev, args->fence, args->obj);
} }
static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
struct drm_i915_fence_reg *fence, struct drm_i915_fence_reg *fence,
bool enable) bool enable)
{ {
struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
struct drm_i915_private *dev_priv = dev->dev_private; struct write_fence args = {
int fence_reg = fence_number(dev_priv, fence); .dev = obj->base.dev,
.fence = fence_number(dev_priv, fence),
.obj = enable ? obj : NULL,
};
/* In order to fully serialize access to the fenced region and /* In order to fully serialize access to the fenced region and
* the update to the fence register we need to take extreme * the update to the fence register we need to take extreme
...@@ -2715,13 +2730,19 @@ static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, ...@@ -2715,13 +2730,19 @@ static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
* SNB+ we need to take a step further and emit an explicit wbinvd() * SNB+ we need to take a step further and emit an explicit wbinvd()
* on each processor in order to manually flush all memory * on each processor in order to manually flush all memory
* transactions before updating the fence register. * transactions before updating the fence register.
*
* However, Valleyview complicates matter. There the wbinvd is
* insufficient and unlike SNB/IVB requires the serialising
* register write. (Note that that register write by itself is
* conversely not sufficient for SNB+.) To compromise, we do both.
*/ */
if (HAS_LLC(obj->base.dev)) if (INTEL_INFO(args.dev)->gen >= 6)
on_each_cpu(i915_gem_write_fence__ipi, NULL, 1); on_each_cpu(i915_gem_write_fence__ipi, &args, 1);
i915_gem_write_fence(dev, fence_reg, enable ? obj : NULL); else
i915_gem_write_fence(args.dev, args.fence, args.obj);
if (enable) { if (enable) {
obj->fence_reg = fence_reg; obj->fence_reg = args.fence;
fence->obj = obj; fence->obj = obj;
list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list); list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list);
} else { } else {
...@@ -2947,6 +2968,8 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, ...@@ -2947,6 +2968,8 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
struct drm_mm_node *node; struct drm_mm_node *node;
u32 size, fence_size, fence_alignment, unfenced_alignment; u32 size, fence_size, fence_alignment, unfenced_alignment;
bool mappable, fenceable; bool mappable, fenceable;
size_t gtt_max = map_and_fenceable ?
dev_priv->gtt.mappable_end : dev_priv->gtt.total;
int ret; int ret;
fence_size = i915_gem_get_gtt_size(dev, fence_size = i915_gem_get_gtt_size(dev,
...@@ -2973,9 +2996,11 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, ...@@ -2973,9 +2996,11 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
/* If the object is bigger than the entire aperture, reject it early /* If the object is bigger than the entire aperture, reject it early
* before evicting everything in a vain attempt to find space. * before evicting everything in a vain attempt to find space.
*/ */
if (obj->base.size > if (obj->base.size > gtt_max) {
(map_and_fenceable ? dev_priv->gtt.mappable_end : dev_priv->gtt.total)) { DRM_ERROR("Attempting to bind an object larger than the aperture: object=%zd > %s aperture=%ld\n",
DRM_ERROR("Attempting to bind an object larger than the aperture\n"); obj->base.size,
map_and_fenceable ? "mappable" : "total",
gtt_max);
return -E2BIG; return -E2BIG;
} }
...@@ -2991,14 +3016,10 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, ...@@ -2991,14 +3016,10 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
return -ENOMEM; return -ENOMEM;
} }
search_free: search_free:
if (map_and_fenceable) ret = drm_mm_insert_node_in_range_generic(&dev_priv->mm.gtt_space, node,
ret = drm_mm_insert_node_in_range_generic(&dev_priv->mm.gtt_space, node, size, alignment,
size, alignment, obj->cache_level, obj->cache_level, 0, gtt_max);
0, dev_priv->gtt.mappable_end);
else
ret = drm_mm_insert_node_generic(&dev_priv->mm.gtt_space, node,
size, alignment, obj->cache_level);
if (ret) { if (ret) {
ret = i915_gem_evict_something(dev, size, alignment, ret = i915_gem_evict_something(dev, size, alignment,
obj->cache_level, obj->cache_level,
...@@ -3992,12 +4013,21 @@ static int i915_gem_init_rings(struct drm_device *dev) ...@@ -3992,12 +4013,21 @@ static int i915_gem_init_rings(struct drm_device *dev)
goto cleanup_bsd_ring; goto cleanup_bsd_ring;
} }
if (HAS_VEBOX(dev)) {
ret = intel_init_vebox_ring_buffer(dev);
if (ret)
goto cleanup_blt_ring;
}
ret = i915_gem_set_seqno(dev, ((u32)~0 - 0x1000)); ret = i915_gem_set_seqno(dev, ((u32)~0 - 0x1000));
if (ret) if (ret)
goto cleanup_blt_ring; goto cleanup_vebox_ring;
return 0; return 0;
cleanup_vebox_ring:
intel_cleanup_ring_buffer(&dev_priv->ring[VECS]);
cleanup_blt_ring: cleanup_blt_ring:
intel_cleanup_ring_buffer(&dev_priv->ring[BCS]); intel_cleanup_ring_buffer(&dev_priv->ring[BCS]);
cleanup_bsd_ring: cleanup_bsd_ring:
......
...@@ -156,7 +156,8 @@ create_hw_context(struct drm_device *dev, ...@@ -156,7 +156,8 @@ create_hw_context(struct drm_device *dev,
if (INTEL_INFO(dev)->gen >= 7) { if (INTEL_INFO(dev)->gen >= 7) {
ret = i915_gem_object_set_cache_level(ctx->obj, ret = i915_gem_object_set_cache_level(ctx->obj,
I915_CACHE_LLC_MLC); I915_CACHE_LLC_MLC);
if (ret) /* Failure shouldn't ever happen this early */
if (WARN_ON(ret))
goto err_out; goto err_out;
} }
...@@ -214,12 +215,16 @@ static int create_default_context(struct drm_i915_private *dev_priv) ...@@ -214,12 +215,16 @@ static int create_default_context(struct drm_i915_private *dev_priv)
*/ */
dev_priv->ring[RCS].default_context = ctx; dev_priv->ring[RCS].default_context = ctx;
ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false, false); ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false, false);
if (ret) if (ret) {
DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret);
goto err_destroy; goto err_destroy;
}
ret = do_switch(ctx); ret = do_switch(ctx);
if (ret) if (ret) {
DRM_DEBUG_DRIVER("Switch failed %d\n", ret);
goto err_unpin; goto err_unpin;
}
DRM_DEBUG_DRIVER("Default HW context loaded\n"); DRM_DEBUG_DRIVER("Default HW context loaded\n");
return 0; return 0;
...@@ -237,6 +242,7 @@ void i915_gem_context_init(struct drm_device *dev) ...@@ -237,6 +242,7 @@ void i915_gem_context_init(struct drm_device *dev)
if (!HAS_HW_CONTEXTS(dev)) { if (!HAS_HW_CONTEXTS(dev)) {
dev_priv->hw_contexts_disabled = true; dev_priv->hw_contexts_disabled = true;
DRM_DEBUG_DRIVER("Disabling HW Contexts; old hardware\n");
return; return;
} }
...@@ -249,11 +255,13 @@ void i915_gem_context_init(struct drm_device *dev) ...@@ -249,11 +255,13 @@ void i915_gem_context_init(struct drm_device *dev)
if (dev_priv->hw_context_size > (1<<20)) { if (dev_priv->hw_context_size > (1<<20)) {
dev_priv->hw_contexts_disabled = true; dev_priv->hw_contexts_disabled = true;
DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size\n");
return; return;
} }
if (create_default_context(dev_priv)) { if (create_default_context(dev_priv)) {
dev_priv->hw_contexts_disabled = true; dev_priv->hw_contexts_disabled = true;
DRM_DEBUG_DRIVER("Disabling HW Contexts; create failed\n");
return; return;
} }
......
...@@ -885,6 +885,15 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, ...@@ -885,6 +885,15 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
return -EPERM; return -EPERM;
} }
break; break;
case I915_EXEC_VEBOX:
ring = &dev_priv->ring[VECS];
if (ctx_id != 0) {
DRM_DEBUG("Ring %s doesn't support contexts\n",
ring->name);
return -EPERM;
}
break;
default: default:
DRM_DEBUG("execbuf with unknown ring: %d\n", DRM_DEBUG("execbuf with unknown ring: %d\n",
(int)(args->flags & I915_EXEC_RING_MASK)); (int)(args->flags & I915_EXEC_RING_MASK));
......
This diff is collapsed.
This diff is collapsed.
...@@ -214,7 +214,7 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev, ...@@ -214,7 +214,7 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
mutex_lock(&dev_priv->rps.hw_lock); mutex_lock(&dev_priv->rps.hw_lock);
if (IS_VALLEYVIEW(dev_priv->dev)) { if (IS_VALLEYVIEW(dev_priv->dev)) {
u32 freq; u32 freq;
valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &freq); freq = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
ret = vlv_gpu_freq(dev_priv->mem_freq, (freq >> 8) & 0xff); ret = vlv_gpu_freq(dev_priv->mem_freq, (freq >> 8) & 0xff);
} else { } else {
ret = dev_priv->rps.cur_delay * GT_FREQUENCY_MULTIPLIER; ret = dev_priv->rps.cur_delay * GT_FREQUENCY_MULTIPLIER;
......
...@@ -84,6 +84,28 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder, ...@@ -84,6 +84,28 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
return true; return true;
} }
static void intel_crt_get_config(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config)
{
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
struct intel_crt *crt = intel_encoder_to_crt(encoder);
u32 tmp, flags = 0;
tmp = I915_READ(crt->adpa_reg);
if (tmp & ADPA_HSYNC_ACTIVE_HIGH)
flags |= DRM_MODE_FLAG_PHSYNC;
else
flags |= DRM_MODE_FLAG_NHSYNC;
if (tmp & ADPA_VSYNC_ACTIVE_HIGH)
flags |= DRM_MODE_FLAG_PVSYNC;
else
flags |= DRM_MODE_FLAG_NVSYNC;
pipe_config->adjusted_mode.flags |= flags;
}
/* Note: The caller is required to filter out dpms modes not supported by the /* Note: The caller is required to filter out dpms modes not supported by the
* platform. */ * platform. */
static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode) static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
...@@ -127,7 +149,7 @@ static void intel_enable_crt(struct intel_encoder *encoder) ...@@ -127,7 +149,7 @@ static void intel_enable_crt(struct intel_encoder *encoder)
intel_crt_set_dpms(encoder, crt->connector->base.dpms); intel_crt_set_dpms(encoder, crt->connector->base.dpms);
} }
/* Special dpms function to support cloning between dvo/sdvo/crt. */
static void intel_crt_dpms(struct drm_connector *connector, int mode) static void intel_crt_dpms(struct drm_connector *connector, int mode)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
...@@ -158,6 +180,8 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode) ...@@ -158,6 +180,8 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode)
else else
encoder->connectors_active = true; encoder->connectors_active = true;
/* We call connector dpms manually below in case pipe dpms doesn't
* change due to cloning. */
if (mode < old_dpms) { if (mode < old_dpms) {
/* From off to on, enable the pipe first. */ /* From off to on, enable the pipe first. */
intel_crtc_update_dpms(crtc); intel_crtc_update_dpms(crtc);
...@@ -778,6 +802,7 @@ void intel_crt_init(struct drm_device *dev) ...@@ -778,6 +802,7 @@ void intel_crt_init(struct drm_device *dev)
crt->base.compute_config = intel_crt_compute_config; crt->base.compute_config = intel_crt_compute_config;
crt->base.disable = intel_disable_crt; crt->base.disable = intel_disable_crt;
crt->base.enable = intel_enable_crt; crt->base.enable = intel_enable_crt;
crt->base.get_config = intel_crt_get_config;
if (I915_HAS_HOTPLUG(dev)) if (I915_HAS_HOTPLUG(dev))
crt->base.hpd_pin = HPD_CRT; crt->base.hpd_pin = HPD_CRT;
if (HAS_DDI(dev)) if (HAS_DDI(dev))
......
...@@ -1153,14 +1153,14 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder) ...@@ -1153,14 +1153,14 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
{ {
if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT) if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT)
return 450; return 450000;
else if ((I915_READ(LCPLL_CTL) & LCPLL_CLK_FREQ_MASK) == else if ((I915_READ(LCPLL_CTL) & LCPLL_CLK_FREQ_MASK) ==
LCPLL_CLK_FREQ_450) LCPLL_CLK_FREQ_450)
return 450; return 450000;
else if (IS_ULT(dev_priv->dev)) else if (IS_ULT(dev_priv->dev))
return 338; return 337500;
else else
return 540; return 540000;
} }
void intel_ddi_pll_init(struct drm_device *dev) void intel_ddi_pll_init(struct drm_device *dev)
...@@ -1173,7 +1173,7 @@ void intel_ddi_pll_init(struct drm_device *dev) ...@@ -1173,7 +1173,7 @@ void intel_ddi_pll_init(struct drm_device *dev)
* Don't even try to turn it on. * Don't even try to turn it on.
*/ */
DRM_DEBUG_KMS("CDCLK running at %dMHz\n", DRM_DEBUG_KMS("CDCLK running at %dKHz\n",
intel_ddi_get_cdclk_freq(dev_priv)); intel_ddi_get_cdclk_freq(dev_priv));
if (val & LCPLL_CD_SOURCE_FCLK) if (val & LCPLL_CD_SOURCE_FCLK)
...@@ -1259,6 +1259,28 @@ static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder) ...@@ -1259,6 +1259,28 @@ static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder)
intel_dp_check_link_status(intel_dp); intel_dp_check_link_status(intel_dp);
} }
static void intel_ddi_get_config(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config)
{
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
u32 temp, flags = 0;
temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
if (temp & TRANS_DDI_PHSYNC)
flags |= DRM_MODE_FLAG_PHSYNC;
else
flags |= DRM_MODE_FLAG_NHSYNC;
if (temp & TRANS_DDI_PVSYNC)
flags |= DRM_MODE_FLAG_PVSYNC;
else
flags |= DRM_MODE_FLAG_NVSYNC;
pipe_config->adjusted_mode.flags |= flags;
pipe_config->pixel_multiplier = 1;
}
static void intel_ddi_destroy(struct drm_encoder *encoder) static void intel_ddi_destroy(struct drm_encoder *encoder)
{ {
/* HDMI has nothing special to destroy, so we can go with this. */ /* HDMI has nothing special to destroy, so we can go with this. */
...@@ -1269,9 +1291,13 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder, ...@@ -1269,9 +1291,13 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config) struct intel_crtc_config *pipe_config)
{ {
int type = encoder->type; int type = encoder->type;
int port = intel_ddi_get_encoder_port(encoder);
WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
if (port == PORT_A)
pipe_config->cpu_transcoder = TRANSCODER_EDP;
if (type == INTEL_OUTPUT_HDMI) if (type == INTEL_OUTPUT_HDMI)
return intel_hdmi_compute_config(encoder, pipe_config); return intel_hdmi_compute_config(encoder, pipe_config);
else else
...@@ -1318,6 +1344,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port) ...@@ -1318,6 +1344,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
intel_encoder->disable = intel_disable_ddi; intel_encoder->disable = intel_disable_ddi;
intel_encoder->post_disable = intel_ddi_post_disable; intel_encoder->post_disable = intel_ddi_post_disable;
intel_encoder->get_hw_state = intel_ddi_get_hw_state; intel_encoder->get_hw_state = intel_ddi_get_hw_state;
intel_encoder->get_config = intel_ddi_get_config;
intel_dig_port->port = port; intel_dig_port->port = port;
intel_dig_port->port_reversal = I915_READ(DDI_BUF_CTL(port)) & intel_dig_port->port_reversal = I915_READ(DDI_BUF_CTL(port)) &
......
This diff is collapsed.
This diff is collapsed.
...@@ -139,6 +139,10 @@ struct intel_encoder { ...@@ -139,6 +139,10 @@ struct intel_encoder {
* the encoder is active. If the encoder is enabled it also set the pipe * the encoder is active. If the encoder is enabled it also set the pipe
* it is connected to in the pipe parameter. */ * it is connected to in the pipe parameter. */
bool (*get_hw_state)(struct intel_encoder *, enum pipe *pipe); bool (*get_hw_state)(struct intel_encoder *, enum pipe *pipe);
/* Reconstructs the equivalent mode flags for the current hardware
* state. */
void (*get_config)(struct intel_encoder *,
struct intel_crtc_config *pipe_config);
int crtc_mask; int crtc_mask;
enum hpd_pin hpd_pin; enum hpd_pin hpd_pin;
}; };
...@@ -264,6 +268,8 @@ struct intel_crtc_config { ...@@ -264,6 +268,8 @@ struct intel_crtc_config {
/* FDI configuration, only valid if has_pch_encoder is set. */ /* FDI configuration, only valid if has_pch_encoder is set. */
int fdi_lanes; int fdi_lanes;
struct intel_link_m_n fdi_m_n; struct intel_link_m_n fdi_m_n;
bool ips_enabled;
}; };
struct intel_crtc { struct intel_crtc {
...@@ -322,6 +328,18 @@ struct intel_plane { ...@@ -322,6 +328,18 @@ struct intel_plane {
unsigned int crtc_w, crtc_h; unsigned int crtc_w, crtc_h;
uint32_t src_x, src_y; uint32_t src_x, src_y;
uint32_t src_w, src_h; uint32_t src_w, src_h;
/* Since we need to change the watermarks before/after
* enabling/disabling the planes, we need to store the parameters here
* as the other pieces of the struct may not reflect the values we want
* for the watermark calculations. Currently only Haswell uses this.
*/
struct {
bool enable;
uint8_t bytes_per_pixel;
uint32_t horiz_pixels;
} wm;
void (*update_plane)(struct drm_plane *plane, void (*update_plane)(struct drm_plane *plane,
struct drm_framebuffer *fb, struct drm_framebuffer *fb,
struct drm_i915_gem_object *obj, struct drm_i915_gem_object *obj,
...@@ -727,9 +745,7 @@ extern void intel_ddi_init(struct drm_device *dev, enum port port); ...@@ -727,9 +745,7 @@ extern void intel_ddi_init(struct drm_device *dev, enum port port);
extern void intel_update_watermarks(struct drm_device *dev); extern void intel_update_watermarks(struct drm_device *dev);
extern void intel_update_sprite_watermarks(struct drm_device *dev, int pipe, extern void intel_update_sprite_watermarks(struct drm_device *dev, int pipe,
uint32_t sprite_width, uint32_t sprite_width,
int pixel_size); int pixel_size, bool enable);
extern void intel_update_linetime_watermarks(struct drm_device *dev, int pipe,
struct drm_display_mode *mode);
extern unsigned long intel_gen4_compute_page_offset(int *x, int *y, extern unsigned long intel_gen4_compute_page_offset(int *x, int *y,
unsigned int tiling_mode, unsigned int tiling_mode,
...@@ -741,10 +757,6 @@ extern int intel_sprite_set_colorkey(struct drm_device *dev, void *data, ...@@ -741,10 +757,6 @@ extern int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
extern int intel_sprite_get_colorkey(struct drm_device *dev, void *data, extern int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
extern u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg);
extern void intel_dpio_write(struct drm_i915_private *dev_priv, int reg,
u32 val);
/* Power-related functions, located in intel_pm.c */ /* Power-related functions, located in intel_pm.c */
extern void intel_init_pm(struct drm_device *dev); extern void intel_init_pm(struct drm_device *dev);
/* FBC */ /* FBC */
......
...@@ -136,6 +136,26 @@ static bool intel_dvo_get_hw_state(struct intel_encoder *encoder, ...@@ -136,6 +136,26 @@ static bool intel_dvo_get_hw_state(struct intel_encoder *encoder,
return true; return true;
} }
static void intel_dvo_get_config(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config)
{
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base);
u32 tmp, flags = 0;
tmp = I915_READ(intel_dvo->dev.dvo_reg);
if (tmp & DVO_HSYNC_ACTIVE_HIGH)
flags |= DRM_MODE_FLAG_PHSYNC;
else
flags |= DRM_MODE_FLAG_NHSYNC;
if (tmp & DVO_VSYNC_ACTIVE_HIGH)
flags |= DRM_MODE_FLAG_PVSYNC;
else
flags |= DRM_MODE_FLAG_NVSYNC;
pipe_config->adjusted_mode.flags |= flags;
}
static void intel_disable_dvo(struct intel_encoder *encoder) static void intel_disable_dvo(struct intel_encoder *encoder)
{ {
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
...@@ -160,6 +180,7 @@ static void intel_enable_dvo(struct intel_encoder *encoder) ...@@ -160,6 +180,7 @@ static void intel_enable_dvo(struct intel_encoder *encoder)
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true); intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true);
} }
/* Special dpms function to support cloning between dvo/sdvo/crt. */
static void intel_dvo_dpms(struct drm_connector *connector, int mode) static void intel_dvo_dpms(struct drm_connector *connector, int mode)
{ {
struct intel_dvo *intel_dvo = intel_attached_dvo(connector); struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
...@@ -181,6 +202,8 @@ static void intel_dvo_dpms(struct drm_connector *connector, int mode) ...@@ -181,6 +202,8 @@ static void intel_dvo_dpms(struct drm_connector *connector, int mode)
return; return;
} }
/* We call connector dpms manually below in case pipe dpms doesn't
* change due to cloning. */
if (mode == DRM_MODE_DPMS_ON) { if (mode == DRM_MODE_DPMS_ON) {
intel_dvo->base.connectors_active = true; intel_dvo->base.connectors_active = true;
...@@ -447,6 +470,7 @@ void intel_dvo_init(struct drm_device *dev) ...@@ -447,6 +470,7 @@ void intel_dvo_init(struct drm_device *dev)
intel_encoder->disable = intel_disable_dvo; intel_encoder->disable = intel_disable_dvo;
intel_encoder->enable = intel_enable_dvo; intel_encoder->enable = intel_enable_dvo;
intel_encoder->get_hw_state = intel_dvo_get_hw_state; intel_encoder->get_hw_state = intel_dvo_get_hw_state;
intel_encoder->get_config = intel_dvo_get_config;
intel_connector->get_hw_state = intel_dvo_connector_get_hw_state; intel_connector->get_hw_state = intel_dvo_connector_get_hw_state;
/* Now, try to find a controller */ /* Now, try to find a controller */
......
...@@ -658,6 +658,28 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder, ...@@ -658,6 +658,28 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,
return true; return true;
} }
static void intel_hdmi_get_config(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config)
{
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
u32 tmp, flags = 0;
tmp = I915_READ(intel_hdmi->hdmi_reg);
if (tmp & SDVO_HSYNC_ACTIVE_HIGH)
flags |= DRM_MODE_FLAG_PHSYNC;
else
flags |= DRM_MODE_FLAG_NHSYNC;
if (tmp & SDVO_VSYNC_ACTIVE_HIGH)
flags |= DRM_MODE_FLAG_PVSYNC;
else
flags |= DRM_MODE_FLAG_NVSYNC;
pipe_config->adjusted_mode.flags |= flags;
}
static void intel_enable_hdmi(struct intel_encoder *encoder) static void intel_enable_hdmi(struct intel_encoder *encoder)
{ {
struct drm_device *dev = encoder->base.dev; struct drm_device *dev = encoder->base.dev;
...@@ -996,38 +1018,36 @@ static void intel_hdmi_pre_enable(struct intel_encoder *encoder) ...@@ -996,38 +1018,36 @@ static void intel_hdmi_pre_enable(struct intel_encoder *encoder)
if (!IS_VALLEYVIEW(dev)) if (!IS_VALLEYVIEW(dev))
return; return;
WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
/* Enable clock channels for this port */ /* Enable clock channels for this port */
val = intel_dpio_read(dev_priv, DPIO_DATA_LANE_A(port)); val = vlv_dpio_read(dev_priv, DPIO_DATA_LANE_A(port));
val = 0; val = 0;
if (pipe) if (pipe)
val |= (1<<21); val |= (1<<21);
else else
val &= ~(1<<21); val &= ~(1<<21);
val |= 0x001000c4; val |= 0x001000c4;
intel_dpio_write(dev_priv, DPIO_DATA_CHANNEL(port), val); vlv_dpio_write(dev_priv, DPIO_DATA_CHANNEL(port), val);
/* HDMI 1.0V-2dB */ /* HDMI 1.0V-2dB */
intel_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0); vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0);
intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL4(port), vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL4(port),
0x2b245f5f); 0x2b245f5f);
intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL2(port), vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL2(port),
0x5578b83a); 0x5578b83a);
intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL3(port), vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL3(port),
0x0c782040); 0x0c782040);
intel_dpio_write(dev_priv, DPIO_TX3_SWING_CTL4(port), vlv_dpio_write(dev_priv, DPIO_TX3_SWING_CTL4(port),
0x2b247878); 0x2b247878);
intel_dpio_write(dev_priv, DPIO_PCS_STAGGER0(port), 0x00030000); vlv_dpio_write(dev_priv, DPIO_PCS_STAGGER0(port), 0x00030000);
intel_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(port), vlv_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(port),
0x00002000); 0x00002000);
intel_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port),
DPIO_TX_OCALINIT_EN); DPIO_TX_OCALINIT_EN);
/* Program lane clock */ /* Program lane clock */
intel_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF0(port), vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF0(port),
0x00760018); 0x00760018);
intel_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(port), vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(port),
0x00400888); 0x00400888);
} }
...@@ -1041,26 +1061,24 @@ static void intel_hdmi_pre_pll_enable(struct intel_encoder *encoder) ...@@ -1041,26 +1061,24 @@ static void intel_hdmi_pre_pll_enable(struct intel_encoder *encoder)
if (!IS_VALLEYVIEW(dev)) if (!IS_VALLEYVIEW(dev))
return; return;
WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
/* Program Tx lane resets to default */ /* Program Tx lane resets to default */
intel_dpio_write(dev_priv, DPIO_PCS_TX(port), vlv_dpio_write(dev_priv, DPIO_PCS_TX(port),
DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE2_RESET |
DPIO_PCS_TX_LANE1_RESET); DPIO_PCS_TX_LANE1_RESET);
intel_dpio_write(dev_priv, DPIO_PCS_CLK(port), vlv_dpio_write(dev_priv, DPIO_PCS_CLK(port),
DPIO_PCS_CLK_CRI_RXEB_EIOS_EN | DPIO_PCS_CLK_CRI_RXEB_EIOS_EN |
DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN | DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN |
(1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) | (1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) |
DPIO_PCS_CLK_SOFT_RESET); DPIO_PCS_CLK_SOFT_RESET);
/* Fix up inter-pair skew failure */ /* Fix up inter-pair skew failure */
intel_dpio_write(dev_priv, DPIO_PCS_STAGGER1(port), 0x00750f00); vlv_dpio_write(dev_priv, DPIO_PCS_STAGGER1(port), 0x00750f00);
intel_dpio_write(dev_priv, DPIO_TX_CTL(port), 0x00001500); vlv_dpio_write(dev_priv, DPIO_TX_CTL(port), 0x00001500);
intel_dpio_write(dev_priv, DPIO_TX_LANE(port), 0x40400000); vlv_dpio_write(dev_priv, DPIO_TX_LANE(port), 0x40400000);
intel_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(port), vlv_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(port),
0x00002000); 0x00002000);
intel_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port),
DPIO_TX_OCALINIT_EN); DPIO_TX_OCALINIT_EN);
} }
...@@ -1072,8 +1090,8 @@ static void intel_hdmi_post_disable(struct intel_encoder *encoder) ...@@ -1072,8 +1090,8 @@ static void intel_hdmi_post_disable(struct intel_encoder *encoder)
/* Reset lanes to avoid HDMI flicker (VLV w/a) */ /* Reset lanes to avoid HDMI flicker (VLV w/a) */
mutex_lock(&dev_priv->dpio_lock); mutex_lock(&dev_priv->dpio_lock);
intel_dpio_write(dev_priv, DPIO_PCS_TX(port), 0x00000000); vlv_dpio_write(dev_priv, DPIO_PCS_TX(port), 0x00000000);
intel_dpio_write(dev_priv, DPIO_PCS_CLK(port), 0x00e00060); vlv_dpio_write(dev_priv, DPIO_PCS_CLK(port), 0x00e00060);
mutex_unlock(&dev_priv->dpio_lock); mutex_unlock(&dev_priv->dpio_lock);
} }
...@@ -1216,6 +1234,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port) ...@@ -1216,6 +1234,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port)
intel_encoder->enable = intel_enable_hdmi; intel_encoder->enable = intel_enable_hdmi;
intel_encoder->disable = intel_disable_hdmi; intel_encoder->disable = intel_disable_hdmi;
intel_encoder->get_hw_state = intel_hdmi_get_hw_state; intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
intel_encoder->get_config = intel_hdmi_get_config;
if (IS_VALLEYVIEW(dev)) { if (IS_VALLEYVIEW(dev)) {
intel_encoder->pre_enable = intel_hdmi_pre_enable; intel_encoder->pre_enable = intel_hdmi_pre_enable;
intel_encoder->pre_pll_enable = intel_hdmi_pre_pll_enable; intel_encoder->pre_pll_enable = intel_hdmi_pre_pll_enable;
......
...@@ -86,6 +86,31 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder, ...@@ -86,6 +86,31 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder,
return true; return true;
} }
static void intel_lvds_get_config(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config)
{
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 lvds_reg, tmp, flags = 0;
if (HAS_PCH_SPLIT(dev))
lvds_reg = PCH_LVDS;
else
lvds_reg = LVDS;
tmp = I915_READ(lvds_reg);
if (tmp & LVDS_HSYNC_POLARITY)
flags |= DRM_MODE_FLAG_NHSYNC;
else
flags |= DRM_MODE_FLAG_PHSYNC;
if (tmp & LVDS_VSYNC_POLARITY)
flags |= DRM_MODE_FLAG_NVSYNC;
else
flags |= DRM_MODE_FLAG_PVSYNC;
pipe_config->adjusted_mode.flags |= flags;
}
/* The LVDS pin pair needs to be on before the DPLLs are enabled. /* The LVDS pin pair needs to be on before the DPLLs are enabled.
* This is an exception to the general rule that mode_set doesn't turn * This is an exception to the general rule that mode_set doesn't turn
* things on. * things on.
...@@ -921,6 +946,7 @@ bool intel_lvds_init(struct drm_device *dev) ...@@ -921,6 +946,7 @@ bool intel_lvds_init(struct drm_device *dev)
intel_encoder->compute_config = intel_lvds_compute_config; intel_encoder->compute_config = intel_lvds_compute_config;
intel_encoder->disable = intel_disable_lvds; intel_encoder->disable = intel_disable_lvds;
intel_encoder->get_hw_state = intel_lvds_get_hw_state; intel_encoder->get_hw_state = intel_lvds_get_hw_state;
intel_encoder->get_config = intel_lvds_get_config;
intel_connector->get_hw_state = intel_connector_get_hw_state; intel_connector->get_hw_state = intel_connector_get_hw_state;
intel_connector_attach_encoder(intel_connector, intel_encoder); intel_connector_attach_encoder(intel_connector, intel_encoder);
......
...@@ -1485,14 +1485,15 @@ intel_overlay_capture_error_state(struct drm_device *dev) ...@@ -1485,14 +1485,15 @@ intel_overlay_capture_error_state(struct drm_device *dev)
} }
void void
intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error) intel_overlay_print_error_state(struct drm_i915_error_state_buf *m,
struct intel_overlay_error_state *error)
{ {
seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n", i915_error_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
error->dovsta, error->isr); error->dovsta, error->isr);
seq_printf(m, " Register file at 0x%08lx:\n", i915_error_printf(m, " Register file at 0x%08lx:\n",
error->base); error->base);
#define P(x) seq_printf(m, " " #x ": 0x%08x\n", error->regs.x) #define P(x) i915_error_printf(m, " " #x ": 0x%08x\n", error->regs.x)
P(OBUF_0Y); P(OBUF_0Y);
P(OBUF_1Y); P(OBUF_1Y);
P(OBUF_0U); P(OBUF_0U);
......
...@@ -332,7 +332,7 @@ static u32 i915_read_blc_pwm_ctl(struct drm_device *dev) ...@@ -332,7 +332,7 @@ static u32 i915_read_blc_pwm_ctl(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 val; u32 val;
WARN_ON(!spin_is_locked(&dev_priv->backlight.lock)); WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight.lock));
/* Restore the CTL value if it lost, e.g. GPU reset */ /* Restore the CTL value if it lost, e.g. GPU reset */
......
This diff is collapsed.
This diff is collapsed.
...@@ -37,14 +37,19 @@ struct intel_hw_status_page { ...@@ -37,14 +37,19 @@ struct intel_hw_status_page {
#define I915_READ_SYNC_0(ring) I915_READ(RING_SYNC_0((ring)->mmio_base)) #define I915_READ_SYNC_0(ring) I915_READ(RING_SYNC_0((ring)->mmio_base))
#define I915_READ_SYNC_1(ring) I915_READ(RING_SYNC_1((ring)->mmio_base)) #define I915_READ_SYNC_1(ring) I915_READ(RING_SYNC_1((ring)->mmio_base))
struct intel_ring_hangcheck {
u32 seqno;
};
struct intel_ring_buffer { struct intel_ring_buffer {
const char *name; const char *name;
enum intel_ring_id { enum intel_ring_id {
RCS = 0x0, RCS = 0x0,
VCS, VCS,
BCS, BCS,
VECS,
} id; } id;
#define I915_NUM_RINGS 3 #define I915_NUM_RINGS 4
u32 mmio_base; u32 mmio_base;
void __iomem *virtual_start; void __iomem *virtual_start;
struct drm_device *dev; struct drm_device *dev;
...@@ -67,7 +72,10 @@ struct intel_ring_buffer { ...@@ -67,7 +72,10 @@ struct intel_ring_buffer {
*/ */
u32 last_retired_head; u32 last_retired_head;
u32 irq_refcount; /* protected by dev_priv->irq_lock */ struct {
u32 gt; /* protected by dev_priv->irq_lock */
u32 pm; /* protected by dev_priv->rps.lock (sucks) */
} irq_refcount;
u32 irq_enable_mask; /* bitmask to enable ring interrupt */ u32 irq_enable_mask; /* bitmask to enable ring interrupt */
u32 trace_irq_seqno; u32 trace_irq_seqno;
u32 sync_seqno[I915_NUM_RINGS-1]; u32 sync_seqno[I915_NUM_RINGS-1];
...@@ -102,8 +110,11 @@ struct intel_ring_buffer { ...@@ -102,8 +110,11 @@ struct intel_ring_buffer {
struct intel_ring_buffer *to, struct intel_ring_buffer *to,
u32 seqno); u32 seqno);
u32 semaphore_register[3]; /*our mbox written by others */ /* our mbox written by others */
u32 signal_mbox[2]; /* mboxes this ring signals to */ u32 semaphore_register[I915_NUM_RINGS];
/* mboxes this ring signals to */
u32 signal_mbox[I915_NUM_RINGS];
/** /**
* List of objects currently involved in rendering from the * List of objects currently involved in rendering from the
* ringbuffer. * ringbuffer.
...@@ -137,6 +148,8 @@ struct intel_ring_buffer { ...@@ -137,6 +148,8 @@ struct intel_ring_buffer {
struct i915_hw_context *default_context; struct i915_hw_context *default_context;
struct i915_hw_context *last_context; struct i915_hw_context *last_context;
struct intel_ring_hangcheck hangcheck;
void *private; void *private;
}; };
...@@ -224,6 +237,7 @@ int intel_ring_invalidate_all_caches(struct intel_ring_buffer *ring); ...@@ -224,6 +237,7 @@ int intel_ring_invalidate_all_caches(struct intel_ring_buffer *ring);
int intel_init_render_ring_buffer(struct drm_device *dev); int intel_init_render_ring_buffer(struct drm_device *dev);
int intel_init_bsd_ring_buffer(struct drm_device *dev); int intel_init_bsd_ring_buffer(struct drm_device *dev);
int intel_init_blt_ring_buffer(struct drm_device *dev); int intel_init_blt_ring_buffer(struct drm_device *dev);
int intel_init_vebox_ring_buffer(struct drm_device *dev);
u32 intel_ring_get_active_head(struct intel_ring_buffer *ring); u32 intel_ring_get_active_head(struct intel_ring_buffer *ring);
void intel_ring_setup_status_page(struct intel_ring_buffer *ring); void intel_ring_setup_status_page(struct intel_ring_buffer *ring);
......
...@@ -712,6 +712,13 @@ static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd, ...@@ -712,6 +712,13 @@ static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd,
intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
} }
static bool intel_sdvo_get_timing(struct intel_sdvo *intel_sdvo, u8 cmd,
struct intel_sdvo_dtd *dtd)
{
return intel_sdvo_get_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) &&
intel_sdvo_get_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
}
static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo, static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo,
struct intel_sdvo_dtd *dtd) struct intel_sdvo_dtd *dtd)
{ {
...@@ -726,6 +733,13 @@ static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo, ...@@ -726,6 +733,13 @@ static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo,
SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
} }
static bool intel_sdvo_get_input_timing(struct intel_sdvo *intel_sdvo,
struct intel_sdvo_dtd *dtd)
{
return intel_sdvo_get_timing(intel_sdvo,
SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
}
static bool static bool
intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo, intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo,
uint16_t clock, uint16_t clock,
...@@ -1295,6 +1309,33 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder, ...@@ -1295,6 +1309,33 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder,
return true; return true;
} }
static void intel_sdvo_get_config(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config)
{
struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
struct intel_sdvo_dtd dtd;
u32 flags = 0;
bool ret;
ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd);
if (!ret) {
DRM_DEBUG_DRIVER("failed to retrieve SDVO DTD\n");
return;
}
if (dtd.part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE)
flags |= DRM_MODE_FLAG_PHSYNC;
else
flags |= DRM_MODE_FLAG_NHSYNC;
if (dtd.part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE)
flags |= DRM_MODE_FLAG_PVSYNC;
else
flags |= DRM_MODE_FLAG_NVSYNC;
pipe_config->adjusted_mode.flags |= flags;
}
static void intel_disable_sdvo(struct intel_encoder *encoder) static void intel_disable_sdvo(struct intel_encoder *encoder)
{ {
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
...@@ -1375,6 +1416,7 @@ static void intel_enable_sdvo(struct intel_encoder *encoder) ...@@ -1375,6 +1416,7 @@ static void intel_enable_sdvo(struct intel_encoder *encoder)
intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output);
} }
/* Special dpms function to support cloning between dvo/sdvo/crt. */
static void intel_sdvo_dpms(struct drm_connector *connector, int mode) static void intel_sdvo_dpms(struct drm_connector *connector, int mode)
{ {
struct drm_crtc *crtc; struct drm_crtc *crtc;
...@@ -1396,6 +1438,8 @@ static void intel_sdvo_dpms(struct drm_connector *connector, int mode) ...@@ -1396,6 +1438,8 @@ static void intel_sdvo_dpms(struct drm_connector *connector, int mode)
return; return;
} }
/* We set active outputs manually below in case pipe dpms doesn't change
* due to cloning. */
if (mode != DRM_MODE_DPMS_ON) { if (mode != DRM_MODE_DPMS_ON) {
intel_sdvo_set_active_outputs(intel_sdvo, 0); intel_sdvo_set_active_outputs(intel_sdvo, 0);
if (0) if (0)
...@@ -2827,6 +2871,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) ...@@ -2827,6 +2871,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
intel_encoder->mode_set = intel_sdvo_mode_set; intel_encoder->mode_set = intel_sdvo_mode_set;
intel_encoder->enable = intel_enable_sdvo; intel_encoder->enable = intel_enable_sdvo;
intel_encoder->get_hw_state = intel_sdvo_get_hw_state; intel_encoder->get_hw_state = intel_sdvo_get_hw_state;
intel_encoder->get_config = intel_sdvo_get_config;
/* In default case sdvo lvds is false */ /* In default case sdvo lvds is false */
if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))
......
/*
* Copyright © 2013 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
*/
#include "i915_drv.h"
#include "intel_drv.h"
/* IOSF sideband */
static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn,
u32 port, u32 opcode, u32 addr, u32 *val)
{
u32 cmd, be = 0xf, bar = 0;
bool is_read = (opcode == PUNIT_OPCODE_REG_READ ||
opcode == DPIO_OPCODE_REG_READ);
cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) |
(port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) |
(bar << IOSF_BAR_SHIFT);
WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) {
DRM_DEBUG_DRIVER("IOSF sideband idle wait (%s) timed out\n",
is_read ? "read" : "write");
return -EAGAIN;
}
I915_WRITE(VLV_IOSF_ADDR, addr);
if (!is_read)
I915_WRITE(VLV_IOSF_DATA, *val);
I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd);
if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) {
DRM_DEBUG_DRIVER("IOSF sideband finish wait (%s) timed out\n",
is_read ? "read" : "write");
return -ETIMEDOUT;
}
if (is_read)
*val = I915_READ(VLV_IOSF_DATA);
I915_WRITE(VLV_IOSF_DATA, 0);
return 0;
}
u32 vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr)
{
u32 val = 0;
WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
mutex_lock(&dev_priv->dpio_lock);
vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT,
PUNIT_OPCODE_REG_READ, addr, &val);
mutex_unlock(&dev_priv->dpio_lock);
return val;
}
void vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val)
{
WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
mutex_lock(&dev_priv->dpio_lock);
vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT,
PUNIT_OPCODE_REG_WRITE, addr, &val);
mutex_unlock(&dev_priv->dpio_lock);
}
u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
{
u32 val = 0;
WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
mutex_lock(&dev_priv->dpio_lock);
vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_NC,
PUNIT_OPCODE_REG_READ, addr, &val);
mutex_unlock(&dev_priv->dpio_lock);
return val;
}
u32 vlv_dpio_read(struct drm_i915_private *dev_priv, int reg)
{
u32 val = 0;
vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_DPIO,
DPIO_OPCODE_REG_READ, reg, &val);
return val;
}
void vlv_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val)
{
vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_DPIO,
DPIO_OPCODE_REG_WRITE, reg, &val);
}
/* SBI access */
u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
enum intel_sbi_destination destination)
{
u32 value = 0;
WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
100)) {
DRM_ERROR("timeout waiting for SBI to become ready\n");
return 0;
}
I915_WRITE(SBI_ADDR, (reg << 16));
if (destination == SBI_ICLK)
value = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD;
else
value = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD;
I915_WRITE(SBI_CTL_STAT, value | SBI_BUSY);
if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
100)) {
DRM_ERROR("timeout waiting for SBI to complete read transaction\n");
return 0;
}
return I915_READ(SBI_DATA);
}
void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
enum intel_sbi_destination destination)
{
u32 tmp;
WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
100)) {
DRM_ERROR("timeout waiting for SBI to become ready\n");
return;
}
I915_WRITE(SBI_ADDR, (reg << 16));
I915_WRITE(SBI_DATA, value);
if (destination == SBI_ICLK)
tmp = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRWR;
else
tmp = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IOWR;
I915_WRITE(SBI_CTL_STAT, SBI_BUSY | tmp);
if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
100)) {
DRM_ERROR("timeout waiting for SBI to complete write transaction\n");
return;
}
}
...@@ -114,7 +114,7 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_framebuffer *fb, ...@@ -114,7 +114,7 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_framebuffer *fb,
crtc_w--; crtc_w--;
crtc_h--; crtc_h--;
intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true);
I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]); I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]);
I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x); I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x);
...@@ -268,7 +268,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, ...@@ -268,7 +268,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
crtc_w--; crtc_w--;
crtc_h--; crtc_h--;
intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true);
/* /*
* IVB workaround: must disable low power watermarks for at least * IVB workaround: must disable low power watermarks for at least
...@@ -335,6 +335,8 @@ ivb_disable_plane(struct drm_plane *plane) ...@@ -335,6 +335,8 @@ ivb_disable_plane(struct drm_plane *plane)
dev_priv->sprite_scaling_enabled &= ~(1 << pipe); dev_priv->sprite_scaling_enabled &= ~(1 << pipe);
intel_update_sprite_watermarks(dev, pipe, 0, 0, false);
/* potentially re-enable LP watermarks */ /* potentially re-enable LP watermarks */
if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled)
intel_update_watermarks(dev); intel_update_watermarks(dev);
...@@ -453,7 +455,7 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, ...@@ -453,7 +455,7 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
crtc_w--; crtc_w--;
crtc_h--; crtc_h--;
intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true);
dvsscale = 0; dvsscale = 0;
if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h) if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h)
......
...@@ -25,7 +25,14 @@ ...@@ -25,7 +25,14 @@
#define DRM_RECT_H #define DRM_RECT_H
/** /**
* drm_rect - two dimensional rectangle * DOC: rect utils
*
* Utility functions to help manage rectangular areas for
* clipping, scaling, etc. calculations.
*/
/**
* struct drm_rect - two dimensional rectangle
* @x1: horizontal starting coordinate (inclusive) * @x1: horizontal starting coordinate (inclusive)
* @x2: horizontal ending coordinate (exclusive) * @x2: horizontal ending coordinate (exclusive)
* @y1: vertical starting coordinate (inclusive) * @y1: vertical starting coordinate (inclusive)
......
...@@ -305,7 +305,7 @@ typedef struct drm_i915_irq_wait { ...@@ -305,7 +305,7 @@ typedef struct drm_i915_irq_wait {
#define I915_PARAM_HAS_WAIT_TIMEOUT 19 #define I915_PARAM_HAS_WAIT_TIMEOUT 19
#define I915_PARAM_HAS_SEMAPHORES 20 #define I915_PARAM_HAS_SEMAPHORES 20
#define I915_PARAM_HAS_PRIME_VMAP_FLUSH 21 #define I915_PARAM_HAS_PRIME_VMAP_FLUSH 21
#define I915_PARAM_RSVD_FOR_FUTURE_USE 22 #define I915_PARAM_HAS_VEBOX 22
#define I915_PARAM_HAS_SECURE_BATCHES 23 #define I915_PARAM_HAS_SECURE_BATCHES 23
#define I915_PARAM_HAS_PINNED_BATCHES 24 #define I915_PARAM_HAS_PINNED_BATCHES 24
#define I915_PARAM_HAS_EXEC_NO_RELOC 25 #define I915_PARAM_HAS_EXEC_NO_RELOC 25
...@@ -660,6 +660,7 @@ struct drm_i915_gem_execbuffer2 { ...@@ -660,6 +660,7 @@ struct drm_i915_gem_execbuffer2 {
#define I915_EXEC_RENDER (1<<0) #define I915_EXEC_RENDER (1<<0)
#define I915_EXEC_BSD (2<<0) #define I915_EXEC_BSD (2<<0)
#define I915_EXEC_BLT (3<<0) #define I915_EXEC_BLT (3<<0)
#define I915_EXEC_VEBOX (4<<0)
/* Used for switching the constants addressing mode on gen4+ RENDER ring. /* Used for switching the constants addressing mode on gen4+ RENDER ring.
* Gen6+ only supports relative addressing to dynamic state (default) and * Gen6+ only supports relative addressing to dynamic state (default) and
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment