提交 5e82ea99 编写于 作者: L Linus Torvalds

Merge branch 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6

* 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
  drm/radeon/kms: add new radeon_info ioctl query for clock crystal freq
  drm/i915: Prevent uninitialised reads during error state capture
  drm/i915: Use consistent mappings for OpRegion between ACPI and i915
  drm/i915: Handle the no-interrupts case for UMS by polling
  drm/i915: Disable high-precision vblank timestamping for UMS
  drm/i915: Increase the amount of defense before computing vblank timestamps
  drm/i915,agp/intel: Do not clear stolen entries
  drm/radeon/kms: simplify atom adjust pll setup
  drm/radeon/kms: match r6xx/r7xx/evergreen asic_reset with previous asics
  drm/radeon/kms: make the mac rv630 quirk generic
  drm/radeon/kms: fix a spelling error in an error message
  drm/radeon/kms: Initialize pageflip spinlocks.
  drm/i915: Recognise non-VGA display devices
  drm/i915: Fix use of invalid array size for ring->sync_seqno
  drm/i915/ringbuffer: Fix use of stale HEAD position whilst polling for space
  drm/i915: Don't kick-off hangcheck after a DRI interrupt
  drm/i915: Add dependency on CONFIG_TMPFS
  drm/i915: Initialise ring vfuncs for old DRI paths
  drm/i915: make the blitter report buffer modifications to the FBC unit
  drm/i915: set more FBC chicken bits
...@@ -68,6 +68,7 @@ static struct _intel_private { ...@@ -68,6 +68,7 @@ static struct _intel_private {
phys_addr_t gma_bus_addr; phys_addr_t gma_bus_addr;
u32 PGETBL_save; u32 PGETBL_save;
u32 __iomem *gtt; /* I915G */ u32 __iomem *gtt; /* I915G */
bool clear_fake_agp; /* on first access via agp, fill with scratch */
int num_dcache_entries; int num_dcache_entries;
union { union {
void __iomem *i9xx_flush_page; void __iomem *i9xx_flush_page;
...@@ -869,21 +870,12 @@ static int intel_fake_agp_free_gatt_table(struct agp_bridge_data *bridge) ...@@ -869,21 +870,12 @@ static int intel_fake_agp_free_gatt_table(struct agp_bridge_data *bridge)
static int intel_fake_agp_configure(void) static int intel_fake_agp_configure(void)
{ {
int i;
if (!intel_enable_gtt()) if (!intel_enable_gtt())
return -EIO; return -EIO;
intel_private.clear_fake_agp = true;
agp_bridge->gart_bus_addr = intel_private.gma_bus_addr; agp_bridge->gart_bus_addr = intel_private.gma_bus_addr;
for (i = 0; i < intel_private.base.gtt_total_entries; i++) {
intel_private.driver->write_entry(intel_private.scratch_page_dma,
i, 0);
}
readl(intel_private.gtt+i-1); /* PCI Posting. */
global_cache_flush();
return 0; return 0;
} }
...@@ -945,6 +937,13 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem, ...@@ -945,6 +937,13 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem,
{ {
int ret = -EINVAL; int ret = -EINVAL;
if (intel_private.clear_fake_agp) {
int start = intel_private.base.stolen_size / PAGE_SIZE;
int end = intel_private.base.gtt_mappable_entries;
intel_gtt_clear_range(start, end - start);
intel_private.clear_fake_agp = false;
}
if (INTEL_GTT_GEN == 1 && type == AGP_DCACHE_MEMORY) if (INTEL_GTT_GEN == 1 && type == AGP_DCACHE_MEMORY)
return i810_insert_dcache_entries(mem, pg_start, type); return i810_insert_dcache_entries(mem, pg_start, type);
......
...@@ -100,7 +100,10 @@ config DRM_I830 ...@@ -100,7 +100,10 @@ config DRM_I830
config DRM_I915 config DRM_I915
tristate "i915 driver" tristate "i915 driver"
depends on AGP_INTEL depends on AGP_INTEL
# we need shmfs for the swappable backing store, and in particular
# the shmem_readpage() which depends upon tmpfs
select SHMEM select SHMEM
select TMPFS
select DRM_KMS_HELPER select DRM_KMS_HELPER
select FB_CFB_FILLRECT select FB_CFB_FILLRECT
select FB_CFB_COPYAREA select FB_CFB_COPYAREA
......
...@@ -152,7 +152,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) ...@@ -152,7 +152,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
{ {
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
struct intel_ring_buffer *ring = LP_RING(dev_priv); int ret;
master_priv->sarea = drm_getsarea(dev); master_priv->sarea = drm_getsarea(dev);
if (master_priv->sarea) { if (master_priv->sarea) {
...@@ -163,33 +163,22 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) ...@@ -163,33 +163,22 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
} }
if (init->ring_size != 0) { if (init->ring_size != 0) {
if (ring->obj != NULL) { if (LP_RING(dev_priv)->obj != NULL) {
i915_dma_cleanup(dev); i915_dma_cleanup(dev);
DRM_ERROR("Client tried to initialize ringbuffer in " DRM_ERROR("Client tried to initialize ringbuffer in "
"GEM mode\n"); "GEM mode\n");
return -EINVAL; return -EINVAL;
} }
ring->size = init->ring_size; ret = intel_render_ring_init_dri(dev,
init->ring_start,
ring->map.offset = init->ring_start; init->ring_size);
ring->map.size = init->ring_size; if (ret) {
ring->map.type = 0;
ring->map.flags = 0;
ring->map.mtrr = 0;
drm_core_ioremap_wc(&ring->map, dev);
if (ring->map.handle == NULL) {
i915_dma_cleanup(dev); i915_dma_cleanup(dev);
DRM_ERROR("can not ioremap virtual address for" return ret;
" ring buffer\n");
return -ENOMEM;
} }
} }
ring->virtual_start = ring->map.handle;
dev_priv->cpp = init->cpp; dev_priv->cpp = init->cpp;
dev_priv->back_offset = init->back_offset; dev_priv->back_offset = init->back_offset;
dev_priv->front_offset = init->front_offset; dev_priv->front_offset = init->front_offset;
...@@ -1226,9 +1215,15 @@ static int i915_load_modeset_init(struct drm_device *dev) ...@@ -1226,9 +1215,15 @@ static int i915_load_modeset_init(struct drm_device *dev)
if (ret) if (ret)
DRM_INFO("failed to find VBIOS tables\n"); DRM_INFO("failed to find VBIOS tables\n");
/* if we have > 1 VGA cards, then disable the radeon VGA resources */ /* If we have > 1 VGA cards, then we need to arbitrate access
* to the common VGA resources.
*
* If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA),
* then we do not take part in VGA arbitration and the
* vga_client_register() fails with -ENODEV.
*/
ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode); ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode);
if (ret) if (ret && ret != -ENODEV)
goto cleanup_ringbuffer; goto cleanup_ringbuffer;
intel_register_dsm_handler(); intel_register_dsm_handler();
......
...@@ -60,7 +60,7 @@ extern int intel_agp_enabled; ...@@ -60,7 +60,7 @@ extern int intel_agp_enabled;
#define INTEL_VGA_DEVICE(id, info) { \ #define INTEL_VGA_DEVICE(id, info) { \
.class = PCI_CLASS_DISPLAY_VGA << 8, \ .class = PCI_CLASS_DISPLAY_VGA << 8, \
.class_mask = 0xffff00, \ .class_mask = 0xff0000, \
.vendor = 0x8086, \ .vendor = 0x8086, \
.device = id, \ .device = id, \
.subvendor = PCI_ANY_ID, \ .subvendor = PCI_ANY_ID, \
...@@ -752,6 +752,9 @@ static int __init i915_init(void) ...@@ -752,6 +752,9 @@ static int __init i915_init(void)
driver.driver_features &= ~DRIVER_MODESET; driver.driver_features &= ~DRIVER_MODESET;
#endif #endif
if (!(driver.driver_features & DRIVER_MODESET))
driver.get_vblank_timestamp = NULL;
return drm_init(&driver); return drm_init(&driver);
} }
......
...@@ -543,8 +543,11 @@ typedef struct drm_i915_private { ...@@ -543,8 +543,11 @@ typedef struct drm_i915_private {
/** List of all objects in gtt_space. Used to restore gtt /** List of all objects in gtt_space. Used to restore gtt
* mappings on resume */ * mappings on resume */
struct list_head gtt_list; struct list_head gtt_list;
/** End of mappable part of GTT */
/** Usable portion of the GTT for GEM */
unsigned long gtt_start;
unsigned long gtt_mappable_end; unsigned long gtt_mappable_end;
unsigned long gtt_end;
struct io_mapping *gtt_mapping; struct io_mapping *gtt_mapping;
int gtt_mtrr; int gtt_mtrr;
......
...@@ -140,12 +140,16 @@ void i915_gem_do_init(struct drm_device *dev, ...@@ -140,12 +140,16 @@ void i915_gem_do_init(struct drm_device *dev,
{ {
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
drm_mm_init(&dev_priv->mm.gtt_space, start, drm_mm_init(&dev_priv->mm.gtt_space, start, end - start);
end - start);
dev_priv->mm.gtt_start = start;
dev_priv->mm.gtt_mappable_end = mappable_end;
dev_priv->mm.gtt_end = end;
dev_priv->mm.gtt_total = end - start; dev_priv->mm.gtt_total = end - start;
dev_priv->mm.mappable_gtt_total = min(end, mappable_end) - start; dev_priv->mm.mappable_gtt_total = min(end, mappable_end) - start;
dev_priv->mm.gtt_mappable_end = mappable_end;
/* Take over this portion of the GTT */
intel_gtt_clear_range(start / PAGE_SIZE, (end-start) / PAGE_SIZE);
} }
int int
...@@ -1857,7 +1861,7 @@ i915_gem_retire_requests_ring(struct drm_device *dev, ...@@ -1857,7 +1861,7 @@ i915_gem_retire_requests_ring(struct drm_device *dev,
seqno = ring->get_seqno(ring); seqno = ring->get_seqno(ring);
for (i = 0; i < I915_NUM_RINGS; i++) for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++)
if (seqno >= ring->sync_seqno[i]) if (seqno >= ring->sync_seqno[i])
ring->sync_seqno[i] = 0; ring->sync_seqno[i] = 0;
......
...@@ -1175,7 +1175,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, ...@@ -1175,7 +1175,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
goto err; goto err;
seqno = i915_gem_next_request_seqno(dev, ring); seqno = i915_gem_next_request_seqno(dev, ring);
for (i = 0; i < I915_NUM_RINGS-1; i++) { for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++) {
if (seqno < ring->sync_seqno[i]) { if (seqno < ring->sync_seqno[i]) {
/* The GPU can not handle its semaphore value wrapping, /* The GPU can not handle its semaphore value wrapping,
* so every billion or so execbuffers, we need to stall * so every billion or so execbuffers, we need to stall
......
...@@ -34,6 +34,10 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) ...@@ -34,6 +34,10 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
/* First fill our portion of the GTT with scratch pages */
intel_gtt_clear_range(dev_priv->mm.gtt_start / PAGE_SIZE,
(dev_priv->mm.gtt_end - dev_priv->mm.gtt_start) / PAGE_SIZE);
list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) {
i915_gem_clflush_object(obj); i915_gem_clflush_object(obj);
......
...@@ -274,24 +274,35 @@ int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, ...@@ -274,24 +274,35 @@ int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
return ret; return ret;
} }
int i915_get_vblank_timestamp(struct drm_device *dev, int crtc, int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
int *max_error, int *max_error,
struct timeval *vblank_time, struct timeval *vblank_time,
unsigned flags) unsigned flags)
{ {
struct drm_crtc *drmcrtc; struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc;
if (crtc < 0 || crtc >= dev->num_crtcs) { if (pipe < 0 || pipe >= dev_priv->num_pipe) {
DRM_ERROR("Invalid crtc %d\n", crtc); DRM_ERROR("Invalid crtc %d\n", pipe);
return -EINVAL; return -EINVAL;
} }
/* Get drm_crtc to timestamp: */ /* Get drm_crtc to timestamp: */
drmcrtc = intel_get_crtc_for_pipe(dev, crtc); crtc = intel_get_crtc_for_pipe(dev, pipe);
if (crtc == NULL) {
DRM_ERROR("Invalid crtc %d\n", pipe);
return -EINVAL;
}
if (!crtc->enabled) {
DRM_DEBUG_KMS("crtc %d is disabled\n", pipe);
return -EBUSY;
}
/* Helper routine in DRM core does all the work: */ /* Helper routine in DRM core does all the work: */
return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
vblank_time, flags, drmcrtc); vblank_time, flags,
crtc);
} }
/* /*
...@@ -348,8 +359,12 @@ static void notify_ring(struct drm_device *dev, ...@@ -348,8 +359,12 @@ static void notify_ring(struct drm_device *dev,
struct intel_ring_buffer *ring) struct intel_ring_buffer *ring)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 seqno = ring->get_seqno(ring); u32 seqno;
if (ring->obj == NULL)
return;
seqno = ring->get_seqno(ring);
trace_i915_gem_request_complete(dev, seqno); trace_i915_gem_request_complete(dev, seqno);
ring->irq_seqno = seqno; ring->irq_seqno = seqno;
...@@ -831,6 +846,8 @@ static void i915_capture_error_state(struct drm_device *dev) ...@@ -831,6 +846,8 @@ static void i915_capture_error_state(struct drm_device *dev)
i++; i++;
error->pinned_bo_count = i - error->active_bo_count; error->pinned_bo_count = i - error->active_bo_count;
error->active_bo = NULL;
error->pinned_bo = NULL;
if (i) { if (i) {
error->active_bo = kmalloc(sizeof(*error->active_bo)*i, error->active_bo = kmalloc(sizeof(*error->active_bo)*i,
GFP_ATOMIC); GFP_ATOMIC);
...@@ -1278,12 +1295,12 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) ...@@ -1278,12 +1295,12 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
if (master_priv->sarea_priv) if (master_priv->sarea_priv)
master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
ret = -ENODEV;
if (ring->irq_get(ring)) { if (ring->irq_get(ring)) {
DRM_WAIT_ON(ret, ring->irq_queue, 3 * DRM_HZ, DRM_WAIT_ON(ret, ring->irq_queue, 3 * DRM_HZ,
READ_BREADCRUMB(dev_priv) >= irq_nr); READ_BREADCRUMB(dev_priv) >= irq_nr);
ring->irq_put(ring); ring->irq_put(ring);
} } else if (wait_for(READ_BREADCRUMB(dev_priv) >= irq_nr, 3000))
ret = -EBUSY;
if (ret == -EBUSY) { if (ret == -EBUSY) {
DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
......
...@@ -513,6 +513,10 @@ ...@@ -513,6 +513,10 @@
#define GEN6_BLITTER_SYNC_STATUS (1 << 24) #define GEN6_BLITTER_SYNC_STATUS (1 << 24)
#define GEN6_BLITTER_USER_INTERRUPT (1 << 22) #define GEN6_BLITTER_USER_INTERRUPT (1 << 22)
#define GEN6_BLITTER_ECOSKPD 0x221d0
#define GEN6_BLITTER_LOCK_SHIFT 16
#define GEN6_BLITTER_FBC_NOTIFY (1<<3)
#define GEN6_BSD_SLEEP_PSMI_CONTROL 0x12050 #define GEN6_BSD_SLEEP_PSMI_CONTROL 0x12050
#define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK (1 << 16) #define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK (1 << 16)
#define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_DISABLE (1 << 0) #define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_DISABLE (1 << 0)
...@@ -2626,6 +2630,8 @@ ...@@ -2626,6 +2630,8 @@
#define DISPLAY_PORT_PLL_BIOS_2 0x46014 #define DISPLAY_PORT_PLL_BIOS_2 0x46014
#define PCH_DSPCLK_GATE_D 0x42020 #define PCH_DSPCLK_GATE_D 0x42020
# define DPFCUNIT_CLOCK_GATE_DISABLE (1 << 9)
# define DPFCRUNIT_CLOCK_GATE_DISABLE (1 << 8)
# define DPFDUNIT_CLOCK_GATE_DISABLE (1 << 7) # define DPFDUNIT_CLOCK_GATE_DISABLE (1 << 7)
# define DPARBUNIT_CLOCK_GATE_DISABLE (1 << 5) # define DPARBUNIT_CLOCK_GATE_DISABLE (1 << 5)
......
...@@ -1213,6 +1213,26 @@ static bool g4x_fbc_enabled(struct drm_device *dev) ...@@ -1213,6 +1213,26 @@ static bool g4x_fbc_enabled(struct drm_device *dev)
return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN; return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN;
} }
static void sandybridge_blit_fbc_update(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 blt_ecoskpd;
/* Make sure blitter notifies FBC of writes */
__gen6_force_wake_get(dev_priv);
blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD);
blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY <<
GEN6_BLITTER_LOCK_SHIFT;
I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY;
I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
blt_ecoskpd &= ~(GEN6_BLITTER_FBC_NOTIFY <<
GEN6_BLITTER_LOCK_SHIFT);
I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
POSTING_READ(GEN6_BLITTER_ECOSKPD);
__gen6_force_wake_put(dev_priv);
}
static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
...@@ -1266,6 +1286,7 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) ...@@ -1266,6 +1286,7 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
I915_WRITE(SNB_DPFC_CTL_SA, I915_WRITE(SNB_DPFC_CTL_SA,
SNB_CPU_FENCE_ENABLE | dev_priv->cfb_fence); SNB_CPU_FENCE_ENABLE | dev_priv->cfb_fence);
I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y); I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y);
sandybridge_blit_fbc_update(dev);
} }
DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane);
...@@ -6286,7 +6307,9 @@ void intel_enable_clock_gating(struct drm_device *dev) ...@@ -6286,7 +6307,9 @@ void intel_enable_clock_gating(struct drm_device *dev)
if (IS_GEN5(dev)) { if (IS_GEN5(dev)) {
/* Required for FBC */ /* Required for FBC */
dspclk_gate |= DPFDUNIT_CLOCK_GATE_DISABLE; dspclk_gate |= DPFCUNIT_CLOCK_GATE_DISABLE |
DPFCRUNIT_CLOCK_GATE_DISABLE |
DPFDUNIT_CLOCK_GATE_DISABLE;
/* Required for CxSR */ /* Required for CxSR */
dspclk_gate |= DPARBUNIT_CLOCK_GATE_DISABLE; dspclk_gate |= DPARBUNIT_CLOCK_GATE_DISABLE;
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
*/ */
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/acpi_io.h>
#include <acpi/video.h> #include <acpi/video.h>
#include "drmP.h" #include "drmP.h"
...@@ -476,7 +477,7 @@ int intel_opregion_setup(struct drm_device *dev) ...@@ -476,7 +477,7 @@ int intel_opregion_setup(struct drm_device *dev)
return -ENOTSUPP; return -ENOTSUPP;
} }
base = ioremap(asls, OPREGION_SIZE); base = acpi_os_ioremap(asls, OPREGION_SIZE);
if (!base) if (!base)
return -ENOMEM; return -ENOMEM;
......
...@@ -34,6 +34,14 @@ ...@@ -34,6 +34,14 @@
#include "i915_trace.h" #include "i915_trace.h"
#include "intel_drv.h" #include "intel_drv.h"
static inline int ring_space(struct intel_ring_buffer *ring)
{
int space = (ring->head & HEAD_ADDR) - (ring->tail + 8);
if (space < 0)
space += ring->size;
return space;
}
static u32 i915_gem_get_seqno(struct drm_device *dev) static u32 i915_gem_get_seqno(struct drm_device *dev)
{ {
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
...@@ -204,11 +212,9 @@ static int init_ring_common(struct intel_ring_buffer *ring) ...@@ -204,11 +212,9 @@ static int init_ring_common(struct intel_ring_buffer *ring)
if (!drm_core_check_feature(ring->dev, DRIVER_MODESET)) if (!drm_core_check_feature(ring->dev, DRIVER_MODESET))
i915_kernel_lost_context(ring->dev); i915_kernel_lost_context(ring->dev);
else { else {
ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; ring->head = I915_READ_HEAD(ring);
ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR;
ring->space = ring->head - (ring->tail + 8); ring->space = ring_space(ring);
if (ring->space < 0)
ring->space += ring->size;
} }
return 0; return 0;
...@@ -921,32 +927,34 @@ static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring) ...@@ -921,32 +927,34 @@ static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring)
} }
ring->tail = 0; ring->tail = 0;
ring->space = ring->head - 8; ring->space = ring_space(ring);
return 0; return 0;
} }
int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n)
{ {
int reread = 0;
struct drm_device *dev = ring->dev; struct drm_device *dev = ring->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long end; unsigned long end;
u32 head; u32 head;
/* If the reported head position has wrapped or hasn't advanced,
* fallback to the slow and accurate path.
*/
head = intel_read_status_page(ring, 4);
if (head > ring->head) {
ring->head = head;
ring->space = ring_space(ring);
if (ring->space >= n)
return 0;
}
trace_i915_ring_wait_begin (dev); trace_i915_ring_wait_begin (dev);
end = jiffies + 3 * HZ; end = jiffies + 3 * HZ;
do { do {
/* If the reported head position has wrapped or hasn't advanced, ring->head = I915_READ_HEAD(ring);
* fallback to the slow and accurate path. ring->space = ring_space(ring);
*/
head = intel_read_status_page(ring, 4);
if (reread)
head = I915_READ_HEAD(ring);
ring->head = head & HEAD_ADDR;
ring->space = ring->head - (ring->tail + 8);
if (ring->space < 0)
ring->space += ring->size;
if (ring->space >= n) { if (ring->space >= n) {
trace_i915_ring_wait_end(dev); trace_i915_ring_wait_end(dev);
return 0; return 0;
...@@ -961,7 +969,6 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) ...@@ -961,7 +969,6 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n)
msleep(1); msleep(1);
if (atomic_read(&dev_priv->mm.wedged)) if (atomic_read(&dev_priv->mm.wedged))
return -EAGAIN; return -EAGAIN;
reread = 1;
} while (!time_after(jiffies, end)); } while (!time_after(jiffies, end));
trace_i915_ring_wait_end (dev); trace_i915_ring_wait_end (dev);
return -EBUSY; return -EBUSY;
...@@ -1292,6 +1299,48 @@ int intel_init_render_ring_buffer(struct drm_device *dev) ...@@ -1292,6 +1299,48 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
return intel_init_ring_buffer(dev, ring); return intel_init_ring_buffer(dev, ring);
} }
int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
*ring = render_ring;
if (INTEL_INFO(dev)->gen >= 6) {
ring->add_request = gen6_add_request;
ring->irq_get = gen6_render_ring_get_irq;
ring->irq_put = gen6_render_ring_put_irq;
} else if (IS_GEN5(dev)) {
ring->add_request = pc_render_add_request;
ring->get_seqno = pc_render_get_seqno;
}
ring->dev = dev;
INIT_LIST_HEAD(&ring->active_list);
INIT_LIST_HEAD(&ring->request_list);
INIT_LIST_HEAD(&ring->gpu_write_list);
ring->size = size;
ring->effective_size = ring->size;
if (IS_I830(ring->dev))
ring->effective_size -= 128;
ring->map.offset = start;
ring->map.size = size;
ring->map.type = 0;
ring->map.flags = 0;
ring->map.mtrr = 0;
drm_core_ioremap_wc(&ring->map, dev);
if (ring->map.handle == NULL) {
DRM_ERROR("can not ioremap virtual address for"
" ring buffer\n");
return -ENOMEM;
}
ring->virtual_start = (void __force __iomem *)ring->map.handle;
return 0;
}
int intel_init_bsd_ring_buffer(struct drm_device *dev) int intel_init_bsd_ring_buffer(struct drm_device *dev)
{ {
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
......
...@@ -166,4 +166,7 @@ int intel_init_blt_ring_buffer(struct drm_device *dev); ...@@ -166,4 +166,7 @@ int intel_init_blt_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);
/* DRI warts */
int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size);
#endif /* _INTEL_RINGBUFFER_H_ */ #endif /* _INTEL_RINGBUFFER_H_ */
...@@ -606,14 +606,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, ...@@ -606,14 +606,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
args.v1.ucTransmitterID = radeon_encoder->encoder_id; args.v1.ucTransmitterID = radeon_encoder->encoder_id;
args.v1.ucEncodeMode = encoder_mode; args.v1.ucEncodeMode = encoder_mode;
if (encoder_mode == ATOM_ENCODER_MODE_DP) { if (ss_enabled)
if (ss_enabled)
args.v1.ucConfig |=
ADJUST_DISPLAY_CONFIG_SS_ENABLE;
} else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) {
args.v1.ucConfig |= args.v1.ucConfig |=
ADJUST_DISPLAY_CONFIG_SS_ENABLE; ADJUST_DISPLAY_CONFIG_SS_ENABLE;
}
atom_execute_table(rdev->mode_info.atom_context, atom_execute_table(rdev->mode_info.atom_context,
index, (uint32_t *)&args); index, (uint32_t *)&args);
...@@ -624,12 +619,12 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, ...@@ -624,12 +619,12 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id; args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id;
args.v3.sInput.ucEncodeMode = encoder_mode; args.v3.sInput.ucEncodeMode = encoder_mode;
args.v3.sInput.ucDispPllConfig = 0; args.v3.sInput.ucDispPllConfig = 0;
if (ss_enabled)
args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_SS_ENABLE;
if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
if (encoder_mode == ATOM_ENCODER_MODE_DP) { if (encoder_mode == ATOM_ENCODER_MODE_DP) {
if (ss_enabled)
args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_SS_ENABLE;
args.v3.sInput.ucDispPllConfig |= args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_COHERENT_MODE; DISPPLL_CONFIG_COHERENT_MODE;
/* 16200 or 27000 */ /* 16200 or 27000 */
...@@ -649,18 +644,11 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, ...@@ -649,18 +644,11 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
} }
} else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
if (encoder_mode == ATOM_ENCODER_MODE_DP) { if (encoder_mode == ATOM_ENCODER_MODE_DP) {
if (ss_enabled)
args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_SS_ENABLE;
args.v3.sInput.ucDispPllConfig |= args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_COHERENT_MODE; DISPPLL_CONFIG_COHERENT_MODE;
/* 16200 or 27000 */ /* 16200 or 27000 */
args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10);
} else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) { } else if (encoder_mode != ATOM_ENCODER_MODE_LVDS) {
if (ss_enabled)
args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_SS_ENABLE;
} else {
if (mode->clock > 165000) if (mode->clock > 165000)
args.v3.sInput.ucDispPllConfig |= args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_DUAL_LINK; DISPPLL_CONFIG_DUAL_LINK;
......
...@@ -2201,6 +2201,9 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev) ...@@ -2201,6 +2201,9 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
struct evergreen_mc_save save; struct evergreen_mc_save save;
u32 grbm_reset = 0; u32 grbm_reset = 0;
if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
return 0;
dev_info(rdev->dev, "GPU softreset \n"); dev_info(rdev->dev, "GPU softreset \n");
dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n",
RREG32(GRBM_STATUS)); RREG32(GRBM_STATUS));
......
...@@ -3522,7 +3522,7 @@ int r100_ring_test(struct radeon_device *rdev) ...@@ -3522,7 +3522,7 @@ int r100_ring_test(struct radeon_device *rdev)
if (i < rdev->usec_timeout) { if (i < rdev->usec_timeout) {
DRM_INFO("ring test succeeded in %d usecs\n", i); DRM_INFO("ring test succeeded in %d usecs\n", i);
} else { } else {
DRM_ERROR("radeon: ring test failed (sracth(0x%04X)=0x%08X)\n", DRM_ERROR("radeon: ring test failed (scratch(0x%04X)=0x%08X)\n",
scratch, tmp); scratch, tmp);
r = -EINVAL; r = -EINVAL;
} }
......
...@@ -1287,6 +1287,9 @@ int r600_gpu_soft_reset(struct radeon_device *rdev) ...@@ -1287,6 +1287,9 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1); S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1);
u32 tmp; u32 tmp;
if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
return 0;
dev_info(rdev->dev, "GPU softreset \n"); dev_info(rdev->dev, "GPU softreset \n");
dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n", dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n",
RREG32(R_008010_GRBM_STATUS)); RREG32(R_008010_GRBM_STATUS));
......
...@@ -387,15 +387,11 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, ...@@ -387,15 +387,11 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,
*line_mux = 0x90; *line_mux = 0x90;
} }
/* mac rv630 */ /* mac rv630, rv730, others */
if ((dev->pdev->device == 0x9588) && if ((supported_device == ATOM_DEVICE_TV1_SUPPORT) &&
(dev->pdev->subsystem_vendor == 0x106b) && (*connector_type == DRM_MODE_CONNECTOR_DVII)) {
(dev->pdev->subsystem_device == 0x00a6)) { *connector_type = DRM_MODE_CONNECTOR_9PinDIN;
if ((supported_device == ATOM_DEVICE_TV1_SUPPORT) && *line_mux = CONNECTOR_7PIN_DIN_ENUM_ID1;
(*connector_type == DRM_MODE_CONNECTOR_DVII)) {
*connector_type = DRM_MODE_CONNECTOR_9PinDIN;
*line_mux = CONNECTOR_7PIN_DIN_ENUM_ID1;
}
} }
/* ASUS HD 3600 XT board lists the DVI port as HDMI */ /* ASUS HD 3600 XT board lists the DVI port as HDMI */
......
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
* - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen
* - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500) * - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500)
* 2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs * 2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs
* 2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf, r300->r500 CMASK * 2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf, r300->r500 CMASK, clock crystal query
*/ */
#define KMS_DRIVER_MAJOR 2 #define KMS_DRIVER_MAJOR 2
#define KMS_DRIVER_MINOR 8 #define KMS_DRIVER_MINOR 8
......
...@@ -110,11 +110,14 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev) ...@@ -110,11 +110,14 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
int radeon_irq_kms_init(struct radeon_device *rdev) int radeon_irq_kms_init(struct radeon_device *rdev)
{ {
int i;
int r = 0; int r = 0;
INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
spin_lock_init(&rdev->irq.sw_lock); spin_lock_init(&rdev->irq.sw_lock);
for (i = 0; i < rdev->num_crtc; i++)
spin_lock_init(&rdev->irq.pflip_lock[i]);
r = drm_vblank_init(rdev->ddev, rdev->num_crtc); r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
if (r) { if (r) {
return r; return r;
......
...@@ -201,6 +201,10 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) ...@@ -201,6 +201,10 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
} }
radeon_set_filp_rights(dev, &rdev->cmask_filp, filp, &value); radeon_set_filp_rights(dev, &rdev->cmask_filp, filp, &value);
break; break;
case RADEON_INFO_CLOCK_CRYSTAL_FREQ:
/* return clock value in KHz */
value = rdev->clock.spll.reference_freq * 10;
break;
default: default:
DRM_DEBUG_KMS("Invalid request %d\n", info->request); DRM_DEBUG_KMS("Invalid request %d\n", info->request);
return -EINVAL; return -EINVAL;
......
...@@ -636,7 +636,7 @@ int vga_client_register(struct pci_dev *pdev, void *cookie, ...@@ -636,7 +636,7 @@ int vga_client_register(struct pci_dev *pdev, void *cookie,
void (*irq_set_state)(void *cookie, bool state), void (*irq_set_state)(void *cookie, bool state),
unsigned int (*set_vga_decode)(void *cookie, bool decode)) unsigned int (*set_vga_decode)(void *cookie, bool decode))
{ {
int ret = -1; int ret = -ENODEV;
struct vga_device *vgadev; struct vga_device *vgadev;
unsigned long flags; unsigned long flags;
......
...@@ -907,6 +907,7 @@ struct drm_radeon_cs { ...@@ -907,6 +907,7 @@ struct drm_radeon_cs {
#define RADEON_INFO_TILING_CONFIG 0x06 #define RADEON_INFO_TILING_CONFIG 0x06
#define RADEON_INFO_WANT_HYPERZ 0x07 #define RADEON_INFO_WANT_HYPERZ 0x07
#define RADEON_INFO_WANT_CMASK 0x08 /* get access to CMASK on r300 */ #define RADEON_INFO_WANT_CMASK 0x08 /* get access to CMASK on r300 */
#define RADEON_INFO_CLOCK_CRYSTAL_FREQ 0x09 /* clock crystal frequency */
struct drm_radeon_info { struct drm_radeon_info {
uint32_t request; uint32_t request;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册