summaryrefslogtreecommitdiff
path: root/shared-core
diff options
context:
space:
mode:
Diffstat (limited to 'shared-core')
-rw-r--r--shared-core/drm.h116
-rw-r--r--shared-core/i915_dma.c176
-rw-r--r--shared-core/i915_drm.h10
-rw-r--r--shared-core/i915_drv.h153
-rw-r--r--shared-core/i915_init.c329
-rw-r--r--shared-core/i915_irq.c91
-rw-r--r--shared-core/i915_mem.c22
-rw-r--r--shared-core/radeon_cp.c25
-rw-r--r--shared-core/radeon_drm.h9
-rw-r--r--shared-core/radeon_drv.h51
-rw-r--r--shared-core/radeon_irq.c20
11 files changed, 781 insertions, 221 deletions
diff --git a/shared-core/drm.h b/shared-core/drm.h
index 636c1217..55675d2f 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -249,7 +249,8 @@ enum drm_map_flags {
_DRM_KERNEL = 0x08, /**< kernel requires access */
_DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */
_DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */
- _DRM_REMOVABLE = 0x40 /**< Removable mapping */
+ _DRM_REMOVABLE = 0x40, /**< Removable mapping */
+ _DRM_DRIVER = 0x80 /**< Driver will take care of it */
};
struct drm_ctx_priv_map {
@@ -890,6 +891,107 @@ struct drm_mm_init_arg {
uint64_t p_size;
};
+/*
+ * Drm mode setting
+ */
+#define DRM_DISPLAY_INFO_LEN 32
+#define DRM_OUTPUT_NAME_LEN 32
+#define DRM_DISPLAY_MODE_LEN 32
+
+#define DRM_MODE_TYPE_BUILTIN (1<<0)
+#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN)
+#define DRM_MODE_TYPE_CRTC_C ((1<<2) | DRM_MODE_TYPE_BUILTIN)
+#define DRM_MODE_TYPE_PREFERRED (1<<3)
+#define DRM_MODE_TYPE_DEFAULT (1<<4)
+#define DRM_MODE_TYPE_USERDEF (1<<5)
+#define DRM_MODE_TYPE_DRIVER (1<<6)
+
+struct drm_mode_modeinfo {
+
+ unsigned int id;
+
+ unsigned int clock;
+ unsigned short hdisplay, hsync_start, hsync_end, htotal, hskew;
+ unsigned short vdisplay, vsync_start, vsync_end, vtotal, vscan;
+
+ unsigned int vrefresh; /* vertical refresh * 1000 */
+
+ unsigned int flags;
+ unsigned int type;
+ char name[DRM_DISPLAY_MODE_LEN];
+};
+
+struct drm_mode_card_res {
+
+ int count_fbs;
+ unsigned int __user *fb_id;
+
+ int count_crtcs;
+ unsigned int __user *crtc_id;
+
+ int count_outputs;
+ unsigned int __user *output_id;
+
+ int count_modes;
+ struct drm_mode_modeinfo __user *modes;
+
+};
+
+struct drm_mode_crtc {
+ unsigned int crtc_id; /**< Id */
+ unsigned int fb_id; /**< Id of framebuffer */
+
+ int x, y; /**< Position on the frameuffer */
+
+ unsigned int mode; /**< Current mode used */
+
+ int count_outputs;
+ unsigned int outputs; /**< Outputs that are connected */
+
+ int count_possibles;
+ unsigned int possibles; /**< Outputs that can be connected */
+
+ unsigned int __user *set_outputs; /**< Outputs to be connected */
+
+ int gamma_size;
+
+};
+
+struct drm_mode_get_output {
+
+ unsigned int output; /**< Id */
+ unsigned int crtc; /**< Id of crtc */
+ unsigned char name[DRM_OUTPUT_NAME_LEN];
+
+ unsigned int connection;
+ unsigned int mm_width, mm_height; /**< HxW in millimeters */
+ unsigned int subpixel;
+
+ int count_crtcs;
+ unsigned int crtcs; /**< possible crtc to connect to */
+
+ int count_clones;
+ unsigned int clones; /**< list of clones */
+
+ int count_modes;
+ unsigned int __user *modes; /**< list of modes it supports */
+
+};
+
+struct drm_mode_fb_cmd {
+ unsigned int buffer_id;
+ unsigned int width, height;
+ unsigned int pitch;
+ unsigned int bpp;
+ unsigned int handle;
+ unsigned int depth;
+};
+
+struct drm_mode_mode_cmd {
+ unsigned int output_id;
+ unsigned int mode_id;
+};
+
/**
* \name Ioctls Definitions
*/
@@ -982,6 +1084,18 @@ struct drm_mm_init_arg {
#define DRM_IOCTL_BO_VERSION DRM_IOR(0xd6, struct drm_bo_version_arg)
+#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res)
+#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc)
+#define DRM_IOCTL_MODE_GETOUTPUT DRM_IOWR(0xA2, struct drm_mode_get_output)
+#define DRM_IOCTL_MODE_SETCRTC DRM_IOWR(0xA3, struct drm_mode_crtc)
+#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xA4, struct drm_mode_fb_cmd)
+#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xA5, unsigned int)
+#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xA6, struct drm_mode_fb_cmd)
+
+#define DRM_IOCTL_MODE_ADDMODE DRM_IOWR(0xA7, struct drm_mode_modeinfo)
+#define DRM_IOCTL_MODE_RMMODE DRM_IOWR(0xA8, unsigned int)
+#define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd)
+#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xAA, struct drm_mode_mode_cmd)
/*@}*/
/**
diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c
index 9aff752c..3632a091 100644
--- a/shared-core/i915_dma.c
+++ b/shared-core/i915_dma.c
@@ -38,8 +38,8 @@
*/
int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
- drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_ring_buffer *ring = &(dev_priv->ring);
u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
int i;
@@ -65,8 +65,8 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
void i915_kernel_lost_context(struct drm_device * dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
- drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_ring_buffer *ring = &(dev_priv->ring);
ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
@@ -78,9 +78,8 @@ void i915_kernel_lost_context(struct drm_device * dev)
dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;
}
-static int i915_dma_cleanup(struct drm_device * dev)
+int i915_dma_cleanup(struct drm_device * dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
/* Make sure interrupts are disabled here because the uninstall ioctl
* may not have been called from userspace and after dev_private
* is freed, it's too late.
@@ -88,32 +87,12 @@ static int i915_dma_cleanup(struct drm_device * dev)
if (dev->irq)
drm_irq_uninstall(dev);
- if (dev_priv->ring.virtual_start) {
- drm_core_ioremapfree(&dev_priv->ring.map, dev);
- dev_priv->ring.virtual_start = 0;
- dev_priv->ring.map.handle = 0;
- dev_priv->ring.map.size = 0;
- }
-
- if (dev_priv->status_page_dmah) {
- drm_pci_free(dev, dev_priv->status_page_dmah);
- dev_priv->status_page_dmah = NULL;
- /* Need to rewrite hardware status page */
- I915_WRITE(0x02080, 0x1ffff000);
- }
-
- if (dev_priv->status_gfx_addr) {
- dev_priv->status_gfx_addr = 0;
- drm_core_ioremapfree(&dev_priv->hws_map, dev);
- I915_WRITE(0x02080, 0x1ffff000);
- }
-
return 0;
}
static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
dev_priv->sarea = drm_getsarea(dev);
if (!dev_priv->sarea) {
@@ -200,7 +179,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
static int i915_dma_resume(struct drm_device * dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
DRM_DEBUG("%s\n", __FUNCTION__);
@@ -239,7 +218,7 @@ static int i915_dma_resume(struct drm_device * dev)
static int i915_dma_init(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- drm_i915_init_t *init = data;
+ struct drm_i915_init *init = data;
int retcode = 0;
switch (init->func) {
@@ -339,7 +318,7 @@ static int validate_cmd(int cmd)
static int i915_emit_cmds(struct drm_device * dev, int __user * buffer,
int dwords)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int i;
RING_LOCALS;
@@ -380,7 +359,7 @@ static int i915_emit_box(struct drm_device * dev,
struct drm_clip_rect __user * boxes,
int i, int DR1, int DR4)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_clip_rect box;
RING_LOCALS;
@@ -421,7 +400,7 @@ static int i915_emit_box(struct drm_device * dev,
void i915_emit_breadcrumb(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
RING_LOCALS;
if (++dev_priv->counter > BREADCRUMB_MASK) {
@@ -442,7 +421,7 @@ void i915_emit_breadcrumb(struct drm_device *dev)
int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t flush_cmd = CMD_MI_FLUSH;
RING_LOCALS;
@@ -462,10 +441,10 @@ int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush)
static int i915_dispatch_cmdbuffer(struct drm_device * dev,
- drm_i915_cmdbuffer_t * cmd)
+ struct drm_i915_cmdbuffer * cmd)
{
#ifdef I915_HAVE_FENCE
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
#endif
int nbox = cmd->num_cliprects;
int i = 0, count, ret;
@@ -502,7 +481,7 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev,
static int i915_dispatch_batchbuffer(struct drm_device * dev,
drm_i915_batchbuffer_t * batch)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_clip_rect __user *boxes = batch->cliprects;
int nbox = batch->num_cliprects;
int i = 0, count;
@@ -555,7 +534,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 num_pages, current_page, next_page, dspbase;
int shift = 2 * plane, x, y;
RING_LOCALS;
@@ -607,7 +586,7 @@ static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync)
void i915_dispatch_flip(struct drm_device * dev, int planes, int sync)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int i;
DRM_DEBUG("%s: planes=0x%x pfCurrentPage=%d\n",
@@ -629,7 +608,7 @@ void i915_dispatch_flip(struct drm_device * dev, int planes, int sync)
static int i915_quiescent(struct drm_device * dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
i915_kernel_lost_context(dev);
return i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);
@@ -647,7 +626,7 @@ static int i915_flush_ioctl(struct drm_device *dev, void *data,
static int i915_batchbuffer(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
dev_priv->sarea_priv;
drm_i915_batchbuffer_t *batch = data;
@@ -677,10 +656,10 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
static int i915_cmdbuffer(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+ struct drm_i915_sarea *sarea_priv = (struct drm_i915_sarea *)
dev_priv->sarea_priv;
- drm_i915_cmdbuffer_t *cmdbuf = data;
+ struct drm_i915_cmdbuffer *cmdbuf = data;
int ret;
DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
@@ -987,11 +966,11 @@ out_err:
static int i915_execbuffer(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
dev_priv->sarea_priv;
struct drm_i915_execbuffer *exec_buf = data;
- struct _drm_i915_batchbuffer *batch = &exec_buf->batch;
+ struct drm_i915_batchbuffer *batch = &exec_buf->batch;
struct drm_fence_arg *fence_arg = &exec_buf->fence_arg;
int num_buffers;
int ret;
@@ -1090,14 +1069,16 @@ out_free:
}
#endif
-static int i915_do_cleanup_pageflip(struct drm_device * dev)
+int i915_do_cleanup_pageflip(struct drm_device * dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
- int i, planes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int i, planes, num_pages;
DRM_DEBUG("%s\n", __FUNCTION__);
-
- for (i = 0, planes = 0; i < 2; i++)
+ if (!dev_priv->sarea_priv)
+ return 0;
+ num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
+ for (i = 0, planes = 0; i < 2; i++) {
if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) {
dev_priv->sarea_priv->pf_current_page =
(dev_priv->sarea_priv->pf_current_page &
@@ -1105,6 +1086,7 @@ static int i915_do_cleanup_pageflip(struct drm_device * dev)
planes |= 1 << i;
}
+ }
if (planes)
i915_dispatch_flip(dev, planes, 0);
@@ -1114,7 +1096,7 @@ static int i915_do_cleanup_pageflip(struct drm_device * dev)
static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- drm_i915_flip_t *param = data;
+ struct drm_i915_flip *param = data;
DRM_DEBUG("%s\n", __FUNCTION__);
@@ -1136,8 +1118,8 @@ static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *f
static int i915_getparam(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
- drm_i915_getparam_t *param = data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_getparam *param = data;
int value;
if (!dev_priv) {
@@ -1171,7 +1153,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
static int i915_setparam(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
drm_i915_setparam_t *param = data;
if (!dev_priv) {
@@ -1212,8 +1194,8 @@ static int i915_mmio(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
uint32_t buf[8];
- drm_i915_private_t *dev_priv = dev->dev_private;
- drm_i915_mmio_entry_t *e;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ drm_i915_mmio_entry_t *e;
drm_i915_mmio_t *mmio = data;
void __iomem *base;
int i;
@@ -1258,7 +1240,7 @@ static int i915_mmio(struct drm_device *dev, void *data,
static int i915_set_status_page(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
drm_i915_hws_addr_t *hws = data;
if (!dev_priv) {
@@ -1286,84 +1268,13 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
dev_priv->hw_status_page = dev_priv->hws_map.handle;
memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
- I915_WRITE(0x02080, dev_priv->status_gfx_addr);
+ I915_WRITE(I915REG_HWS_PGA, dev_priv->status_gfx_addr);
DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n",
dev_priv->status_gfx_addr);
DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page);
return 0;
}
-int i915_driver_load(struct drm_device *dev, unsigned long flags)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- unsigned long base, size;
- int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1;
-
- /* i915 has 4 more counters */
- dev->counters += 4;
- dev->types[6] = _DRM_STAT_IRQ;
- dev->types[7] = _DRM_STAT_PRIMARY;
- dev->types[8] = _DRM_STAT_SECONDARY;
- dev->types[9] = _DRM_STAT_DMA;
-
- dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER);
- if (dev_priv == NULL)
- return -ENOMEM;
-
- memset(dev_priv, 0, sizeof(drm_i915_private_t));
-
- dev->dev_private = (void *)dev_priv;
-
- /* Add register map (needed for suspend/resume) */
- base = drm_get_resource_start(dev, mmio_bar);
- size = drm_get_resource_len(dev, mmio_bar);
-
- ret = drm_addmap(dev, base, size, _DRM_REGISTERS, _DRM_KERNEL,
- &dev_priv->mmio_map);
-
-#ifdef __linux__
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
- intel_init_chipset_flush_compat(dev);
-#endif
-#endif
- return ret;
-}
-
-int i915_driver_unload(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- if (dev_priv->mmio_map)
- drm_rmmap(dev, dev_priv->mmio_map);
-
- drm_free(dev->dev_private, sizeof(drm_i915_private_t),
- DRM_MEM_DRIVER);
-#ifdef __linux__
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
- intel_fini_chipset_flush_compat(dev);
-#endif
-#endif
- return 0;
-}
-
-void i915_driver_lastclose(struct drm_device * dev)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
-
- if (drm_getsarea(dev) && dev_priv->sarea_priv)
- i915_do_cleanup_pageflip(dev);
- if (dev_priv->agp_heap)
- i915_mem_takedown(&(dev_priv->agp_heap));
-
- i915_dma_cleanup(dev);
-}
-
-void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
- i915_mem_release(dev, file_priv, dev_priv->agp_heap);
-}
-
struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH),
@@ -1406,10 +1317,3 @@ int i915_driver_device_is_agp(struct drm_device * dev)
return 1;
}
-int i915_driver_firstopen(struct drm_device *dev)
-{
-#ifdef I915_HAVE_BUFFER
- drm_bo_driver_init(dev);
-#endif
- return 0;
-}
diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h
index 8a3be4e0..65bc9e89 100644
--- a/shared-core/i915_drm.h
+++ b/shared-core/i915_drm.h
@@ -39,7 +39,7 @@
* of chars for next/prev indices */
#define I915_LOG_MIN_TEX_REGION_SIZE 14
-typedef struct _drm_i915_init {
+typedef struct drm_i915_init {
enum {
I915_INIT_DMA = 0x01,
I915_CLEANUP_DMA = 0x02,
@@ -63,7 +63,7 @@ typedef struct _drm_i915_init {
unsigned int chipset;
} drm_i915_init_t;
-typedef struct _drm_i915_sarea {
+typedef struct drm_i915_sarea {
struct drm_tex_region texList[I915_NR_TEX_REGIONS + 1];
int last_upload; /* last time texture was uploaded */
int last_enqueue; /* last time a buffer was enqueued */
@@ -195,7 +195,7 @@ typedef struct drm_i915_flip {
/* Allow drivers to submit batchbuffers directly to hardware, relying
* on the security mechanisms provided by hardware.
*/
-typedef struct _drm_i915_batchbuffer {
+typedef struct drm_i915_batchbuffer {
int start; /* agp offset */
int used; /* nr bytes in use */
int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
@@ -207,7 +207,7 @@ typedef struct _drm_i915_batchbuffer {
/* As above, but pass a pointer to userspace buffer which can be
* validated by the kernel prior to sending to hardware.
*/
-typedef struct _drm_i915_cmdbuffer {
+typedef struct drm_i915_cmdbuffer {
char __user *buf; /* pointer to userspace command buffer */
int sz; /* nr bytes in buf */
int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
@@ -358,7 +358,7 @@ struct drm_i915_op_arg {
struct drm_i915_execbuffer {
uint64_t ops_list;
uint32_t num_buffers;
- struct _drm_i915_batchbuffer batch;
+ struct drm_i915_batchbuffer batch;
drm_context_t context; /* for lockless use in the future */
struct drm_fence_arg fence_arg;
};
diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h
index cb336659..9382fa6f 100644
--- a/shared-core/i915_drv.h
+++ b/shared-core/i915_drv.h
@@ -70,7 +70,7 @@
#define I915_MAX_VALIDATE_BUFFERS 4096
#endif
-typedef struct _drm_i915_ring_buffer {
+struct drm_i915_ring_buffer {
int tail_mask;
unsigned long Start;
unsigned long End;
@@ -80,7 +80,7 @@ typedef struct _drm_i915_ring_buffer {
int tail;
int space;
drm_local_map_t map;
-} drm_i915_ring_buffer_t;
+};
struct mem_block {
struct mem_block *next;
@@ -90,22 +90,26 @@ struct mem_block {
struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */
};
-typedef struct _drm_i915_vbl_swap {
+struct drm_i915_vbl_swap {
struct list_head head;
drm_drawable_t drw_id;
unsigned int plane;
unsigned int sequence;
int flip;
-} drm_i915_vbl_swap_t;
+};
-typedef struct drm_i915_private {
+struct drm_i915_private {
+ struct drm_buffer_object *ring_buffer;
drm_local_map_t *sarea;
drm_local_map_t *mmio_map;
- drm_i915_sarea_t *sarea_priv;
- drm_i915_ring_buffer_t ring;
+ unsigned long mmiobase;
+ unsigned long mmiolen;
+
+ struct drm_i915_sarea *sarea_priv;
+ struct drm_i915_ring_buffer ring;
- drm_dma_handle_t *status_page_dmah;
+ struct drm_dma_handle *status_page_dmah;
void *hw_status_page;
dma_addr_t dma_status_page;
uint32_t counter;
@@ -143,10 +147,15 @@ typedef struct drm_i915_private {
#endif
DRM_SPINTYPE swaps_lock;
- drm_i915_vbl_swap_t vbl_swaps;
+ struct drm_i915_vbl_swap vbl_swaps;
unsigned int swaps_pending;
- /* Register state */
+ /* LVDS info */
+ int backlight_duty_cycle; /* restore backlight to this value */
+ bool panel_wants_dither;
+ struct drm_display_mode *panel_fixed_mode;
+
+ /* Register state */
u8 saveLBB;
u32 saveDSPACNTR;
u32 saveDSPBCNTR;
@@ -224,7 +233,7 @@ typedef struct drm_i915_private {
u8 saveDACMASK;
u8 saveDACDATA[256*3]; /* 256 3-byte colors */
u8 saveCR[36];
-} drm_i915_private_t;
+};
enum intel_chip_family {
CHIP_I8XX = 0x01,
@@ -239,7 +248,7 @@ extern int i915_max_ioctl;
/* i915_dma.c */
extern void i915_kernel_lost_context(struct drm_device * dev);
extern int i915_driver_load(struct drm_device *, unsigned long flags);
-extern int i915_driver_unload(struct drm_device *);
+extern int i915_driver_unload(struct drm_device *dev);
extern void i915_driver_lastclose(struct drm_device * dev);
extern void i915_driver_preclose(struct drm_device *dev,
struct drm_file *file_priv);
@@ -250,6 +259,8 @@ extern void i915_emit_breadcrumb(struct drm_device *dev);
extern void i915_dispatch_flip(struct drm_device * dev, int pipes, int sync);
extern int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush);
extern int i915_driver_firstopen(struct drm_device *dev);
+extern int i915_do_cleanup_pageflip(struct drm_device *dev);
+extern int i915_dma_cleanup(struct drm_device *dev);
/* i915_irq.c */
extern int i915_irq_emit(struct drm_device *dev, void *data,
@@ -257,6 +268,7 @@ extern int i915_irq_emit(struct drm_device *dev, void *data,
extern int i915_irq_wait(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+extern void i915_driver_wait_next_vblank(struct drm_device *dev, int pipe);
extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence);
extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
@@ -267,9 +279,10 @@ extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-extern int i915_emit_irq(struct drm_device *dev);
-extern void i915_user_irq_on(drm_i915_private_t *dev_priv);
-extern void i915_user_irq_off(drm_i915_private_t *dev_priv);
+extern int i915_emit_irq(struct drm_device * dev);
+extern void i915_user_irq_on(struct drm_i915_private *dev_priv);
+extern void i915_user_irq_off(struct drm_i915_private *dev_priv);
+extern void i915_enable_interrupt (struct drm_device *dev);
extern int i915_vblank_swap(struct drm_device *dev, void *data,
struct drm_file *file_priv);
@@ -320,6 +333,12 @@ extern void intel_fini_chipset_flush_compat(struct drm_device *dev);
#endif
#endif
+
+/* modesetting */
+extern void intel_modeset_init(struct drm_device *dev);
+extern void intel_modeset_cleanup(struct drm_device *dev);
+
+
#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg))
#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
#define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg))
@@ -357,8 +376,31 @@ extern void intel_fini_chipset_flush_compat(struct drm_device *dev);
I915_WRITE(LP_RING + RING_TAIL, outring); \
} while(0)
+#define MI_NOOP (0x00 << 23)
+
extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
+/*
+ * The Bridge device's PCI config space has information about the
+ * fb aperture size and the amount of pre-reserved memory.
+ */
+#define INTEL_GMCH_CTRL 0x52
+#define INTEL_GMCH_ENABLED 0x4
+#define INTEL_GMCH_MEM_MASK 0x1
+#define INTEL_GMCH_MEM_64M 0x1
+#define INTEL_GMCH_MEM_128M 0
+
+#define INTEL_855_GMCH_GMS_MASK (0x7 << 4)
+#define INTEL_855_GMCH_GMS_DISABLED (0x0 << 4)
+#define INTEL_855_GMCH_GMS_STOLEN_1M (0x1 << 4)
+#define INTEL_855_GMCH_GMS_STOLEN_4M (0x2 << 4)
+#define INTEL_855_GMCH_GMS_STOLEN_8M (0x3 << 4)
+#define INTEL_855_GMCH_GMS_STOLEN_16M (0x4 << 4)
+#define INTEL_855_GMCH_GMS_STOLEN_32M (0x5 << 4)
+
+#define INTEL_915G_GMCH_GMS_STOLEN_48M (0x6 << 4)
+#define INTEL_915G_GMCH_GMS_STOLEN_64M (0x7 << 4)
+
/* Extended config space */
#define LBB 0xf4
@@ -425,6 +467,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define BB1_UNPROTECTED (0<<0)
#define BB2_END_ADDR_MASK (~0x7)
+#define I915REG_HWS_PGA 0x02080
+
/* Framebuffer compression */
#define FBC_CFB_BASE 0x03200 /* 4k page aligned */
#define FBC_LL_BASE 0x03204 /* 4k page aligned */
@@ -475,6 +519,63 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
#define I915_VBLANK_CLEAR (1UL<<1)
+#define GPIOA 0x5010
+#define GPIOB 0x5014
+#define GPIOC 0x5018
+#define GPIOD 0x501c
+#define GPIOE 0x5020
+#define GPIOF 0x5024
+#define GPIOG 0x5028
+#define GPIOH 0x502c
+# define GPIO_CLOCK_DIR_MASK (1 << 0)
+# define GPIO_CLOCK_DIR_IN (0 << 1)
+# define GPIO_CLOCK_DIR_OUT (1 << 1)
+# define GPIO_CLOCK_VAL_MASK (1 << 2)
+# define GPIO_CLOCK_VAL_OUT (1 << 3)
+# define GPIO_CLOCK_VAL_IN (1 << 4)
+# define GPIO_CLOCK_PULLUP_DISABLE (1 << 5)
+# define GPIO_DATA_DIR_MASK (1 << 8)
+# define GPIO_DATA_DIR_IN (0 << 9)
+# define GPIO_DATA_DIR_OUT (1 << 9)
+# define GPIO_DATA_VAL_MASK (1 << 10)
+# define GPIO_DATA_VAL_OUT (1 << 11)
+# define GPIO_DATA_VAL_IN (1 << 12)
+# define GPIO_DATA_PULLUP_DISABLE (1 << 13)
+
+/* p317, 319
+ */
+#define VCLK2_VCO_M 0x6008 /* treat as 16 bit? (includes msbs) */
+#define VCLK2_VCO_N 0x600a
+#define VCLK2_VCO_DIV_SEL 0x6012
+
+#define VCLK_DIVISOR_VGA0 0x6000
+#define VCLK_DIVISOR_VGA1 0x6004
+#define VCLK_POST_DIV 0x6010
+/** Selects a post divisor of 4 instead of 2. */
+# define VGA1_PD_P2_DIV_4 (1 << 15)
+/** Overrides the p2 post divisor field */
+# define VGA1_PD_P1_DIV_2 (1 << 13)
+# define VGA1_PD_P1_SHIFT 8
+/** P1 value is 2 greater than this field */
+# define VGA1_PD_P1_MASK (0x1f << 8)
+/** Selects a post divisor of 4 instead of 2. */
+# define VGA0_PD_P2_DIV_4 (1 << 7)
+/** Overrides the p2 post divisor field */
+# define VGA0_PD_P1_DIV_2 (1 << 5)
+# define VGA0_PD_P1_SHIFT 0
+/** P1 value is 2 greater than this field */
+# define VGA0_PD_P1_MASK (0x1f << 0)
+
+#define POST_DIV_SELECT 0x70
+#define POST_DIV_1 0x00
+#define POST_DIV_2 0x10
+#define POST_DIV_4 0x20
+#define POST_DIV_8 0x30
+#define POST_DIV_16 0x40
+#define POST_DIV_32 0x50
+#define VCO_LOOP_DIV_BY_4M 0x00
+#define VCO_LOOP_DIV_BY_16M 0x04
+
#define SRX_INDEX 0x3c4
#define SRX_DATA 0x3c5
#define SR01 1
@@ -483,6 +584,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define PPCR 0x61204
#define PPCR_ON (1<<0)
+#define DVOA 0x61120
+#define DVOA_ON (1<<31)
#define DVOB 0x61140
#define DVOB_ON (1<<31)
#define DVOC 0x61160
@@ -639,8 +742,14 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4)
#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
+#define XY_MONO_SRC_COPY_IMM_BLT ((2<<29)|(0x71<<22)|5)
#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
+#define BLT_DEPTH_8 (0<<24)
+#define BLT_DEPTH_16_565 (1<<24)
+#define BLT_DEPTH_16_1555 (2<<24)
+#define BLT_DEPTH_32 (3<<24)
+#define BLT_ROP_GXCOPY (0xcc<<16)
#define MI_BATCH_BUFFER ((0x30<<23)|1)
#define MI_BATCH_BUFFER_START (0x31<<23)
@@ -682,6 +791,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
#define BLC_PWM_CTL2 0x61250
+
/**
* This is the most significant 15 bits of the number of backlight cycles in a
* complete cycle of the modulated backlight control.
@@ -1121,13 +1231,17 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
*/
#define SWF0 0x71410
+#define SWF1 0x71414
+#define SWF2 0x71418
+#define SWF3 0x7141c
+#define SWF4 0x71420
+#define SWF5 0x71424
+#define SWF6 0x71428
-/*
- * 855 scratch registers.
- */
#define SWF10 0x70410
-
#define SWF30 0x72414
+#define SWF31 0x72418
+#define SWF32 0x7241c
/*
* Overlay registers. These are overlay registers accessed via MMIO.
@@ -1144,6 +1258,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define OGAMC2 0x3001c
#define OGAMC1 0x30020
#define OGAMC0 0x30024
+
/*
* Palette registers
*/
diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c
new file mode 100644
index 00000000..3b43c722
--- /dev/null
+++ b/shared-core/i915_init.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2007 Intel Corporation
+ * Jesse Barnes <jesse.barnes@intel.com>
+ *
+ * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
+ * 2004 Sylvain Meyer
+ *
+ * GPL/BSD dual license
+ */
+#include "drmP.h"
+#include "drm.h"
+#include "drm_sarea.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+
+/**
+ * i915_probe_agp - get AGP bootup configuration
+ * @pdev: PCI device
+ * @aperture_size: returns AGP aperture configured size
+ * @preallocated_size: returns size of BIOS preallocated AGP space
+ *
+ * Since Intel integrated graphics are UMA, the BIOS has to set aside
+ * some RAM for the framebuffer at early boot. This code figures out
+ * how much was set aside so we can use it for our own purposes.
+ */
+int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size,
+ unsigned long *preallocated_size)
+{
+ struct pci_dev *bridge_dev;
+ u16 tmp = 0;
+ unsigned long overhead;
+
+ bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
+ if (!bridge_dev) {
+ DRM_ERROR("bridge device not found\n");
+ return -1;
+ }
+
+ /* Get the fb aperture size and "stolen" memory amount. */
+ pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp);
+ pci_dev_put(bridge_dev);
+
+ *aperture_size = 1024 * 1024;
+ *preallocated_size = 1024 * 1024;
+
+ switch (pdev->device) {
+ case PCI_DEVICE_ID_INTEL_82830_CGC:
+ case PCI_DEVICE_ID_INTEL_82845G_IG:
+ case PCI_DEVICE_ID_INTEL_82855GM_IG:
+ case PCI_DEVICE_ID_INTEL_82865_IG:
+ if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M)
+ *aperture_size *= 64;
+ else
+ *aperture_size *= 128;
+ break;
+ default:
+ /* 9xx supports large sizes, just look at the length */
+ *aperture_size = pci_resource_len(pdev, 2);
+ break;
+ }
+
+ /*
+ * Some of the preallocated space is taken by the GTT
+ * and popup. GTT is 1K per MB of aperture size, and popup is 4K.
+ */
+ overhead = (*aperture_size / 1024) + 4096;
+ switch (tmp & INTEL_855_GMCH_GMS_MASK) {
+ case INTEL_855_GMCH_GMS_STOLEN_1M:
+ break; /* 1M already */
+ case INTEL_855_GMCH_GMS_STOLEN_4M:
+ *preallocated_size *= 4;
+ break;
+ case INTEL_855_GMCH_GMS_STOLEN_8M:
+ *preallocated_size *= 8;
+ break;
+ case INTEL_855_GMCH_GMS_STOLEN_16M:
+ *preallocated_size *= 16;
+ break;
+ case INTEL_855_GMCH_GMS_STOLEN_32M:
+ *preallocated_size *= 32;
+ break;
+ case INTEL_915G_GMCH_GMS_STOLEN_48M:
+ *preallocated_size *= 48;
+ break;
+ case INTEL_915G_GMCH_GMS_STOLEN_64M:
+ *preallocated_size *= 64;
+ break;
+ case INTEL_855_GMCH_GMS_DISABLED:
+ DRM_ERROR("video memory is disabled\n");
+ return -1;
+ default:
+ DRM_ERROR("unexpected GMCH_GMS value: 0x%02x\n",
+ tmp & INTEL_855_GMCH_GMS_MASK);
+ return -1;
+ }
+ *preallocated_size -= overhead;
+
+ return 0;
+}
+
+/**
+ * i915_driver_load - setup chip and create an initial config
+ * @dev: DRM device
+ * @flags: startup flags
+ *
+ * The driver load routine has to do several things:
+ * - drive output discovery via intel_modeset_init()
+ * - initialize the memory manager
+ * - allocate initial config memory
+ * - setup the DRM framebuffer with the allocated memory
+ */
+int i915_driver_load(struct drm_device *dev, unsigned long flags)
+{
+ struct drm_i915_private *dev_priv;
+ unsigned long agp_size, prealloc_size;
+ unsigned long sareapage;
+ int size, ret;
+
+ dev_priv = drm_alloc(sizeof(struct drm_i915_private), DRM_MEM_DRIVER);
+ if (dev_priv == NULL)
+ return -ENOMEM;
+
+ memset(dev_priv, 0, sizeof(struct drm_i915_private));
+ dev->dev_private = (void *)dev_priv;
+// dev_priv->flags = flags;
+
+ /* i915 has 4 more counters */
+ dev->counters += 4;
+ dev->types[6] = _DRM_STAT_IRQ;
+ dev->types[7] = _DRM_STAT_PRIMARY;
+ dev->types[8] = _DRM_STAT_SECONDARY;
+ dev->types[9] = _DRM_STAT_DMA;
+
+ if (IS_I9XX(dev)) {
+ dev_priv->mmiobase = drm_get_resource_start(dev, 0);
+ dev_priv->mmiolen = drm_get_resource_len(dev, 0);
+ dev->mode_config.fb_base =
+ drm_get_resource_start(dev, 2) & 0xff000000;
+ } else if (drm_get_resource_start(dev, 1)) {
+ dev_priv->mmiobase = drm_get_resource_start(dev, 1);
+ dev_priv->mmiolen = drm_get_resource_len(dev, 1);
+ dev->mode_config.fb_base =
+ drm_get_resource_start(dev, 0) & 0xff000000;
+ } else {
+ DRM_ERROR("Unable to find MMIO registers\n");
+ return -ENODEV;
+ }
+
+ DRM_DEBUG("fb_base: 0x%08lx\n", dev->mode_config.fb_base);
+
+ ret = drm_addmap(dev, dev_priv->mmiobase, dev_priv->mmiolen,
+ _DRM_REGISTERS, _DRM_READ_ONLY|_DRM_DRIVER, &dev_priv->mmio_map);
+ if (ret != 0) {
+ DRM_ERROR("Cannot add mapping for MMIO registers\n");
+ return ret;
+ }
+
+ /* prebuild the SAREA */
+ sareapage = max(SAREA_MAX, PAGE_SIZE);
+ ret = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK|_DRM_DRIVER,
+ &dev_priv->sarea);
+ if (ret) {
+ DRM_ERROR("SAREA setup failed\n");
+ return ret;
+ }
+
+ init_waitqueue_head(&dev->lock.lock_queue);
+
+ /* FIXME: assume sarea_priv is right after SAREA */
+ dev_priv->sarea_priv = dev_priv->sarea->handle + sizeof(struct drm_sarea);
+
+ /*
+ * Initialize the memory manager for local and AGP space
+ */
+ drm_bo_driver_init(dev);
+
+ i915_probe_agp(dev->pdev, &agp_size, &prealloc_size);
+ printk("setting up %ld bytes of VRAM space\n", prealloc_size);
+ printk("setting up %ld bytes of TT space\n", (agp_size - prealloc_size));
+ drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, prealloc_size >> PAGE_SHIFT);
+ drm_bo_init_mm(dev, DRM_BO_MEM_TT, prealloc_size >> PAGE_SHIFT, (agp_size - prealloc_size) >> PAGE_SHIFT);
+
+ I915_WRITE(LP_RING + RING_LEN, 0);
+ I915_WRITE(LP_RING + RING_HEAD, 0);
+ I915_WRITE(LP_RING + RING_TAIL, 0);
+
+ size = PRIMARY_RINGBUFFER_SIZE;
+ ret = drm_buffer_object_create(dev, size, drm_bo_type_kernel,
+ DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
+ DRM_BO_FLAG_MEM_VRAM |
+ DRM_BO_FLAG_NO_EVICT |
+ DRM_BO_HINT_DONT_FENCE, 0, 0x1, 0,
+ &dev_priv->ring_buffer);
+ if (ret < 0) {
+ DRM_ERROR("Unable to allocate or pin ring buffer\n");
+ return -EINVAL;
+ }
+
+ /* remap the buffer object properly */
+ dev_priv->ring.Start = dev_priv->ring_buffer->offset;
+ dev_priv->ring.End = dev_priv->ring.Start + size;
+ dev_priv->ring.Size = size;
+ dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
+
+ /* FIXME: need wrapper with PCI mem checks */
+ ret = drm_mem_reg_ioremap(dev, &dev_priv->ring_buffer->mem,
+ (void **) &dev_priv->ring.virtual_start);
+ if (ret)
+ DRM_ERROR("error mapping ring buffer: %d\n", ret);
+
+ DRM_DEBUG("ring start %08lX, %p, %08lX\n", dev_priv->ring.Start,
+ dev_priv->ring.virtual_start, dev_priv->ring.Size);
+
+ dev_priv->sarea_priv->pf_current_page = 0;
+
+ memset((void *)(dev_priv->ring.virtual_start), 0, dev_priv->ring.Size);
+
+ I915_WRITE(LP_RING + RING_START, dev_priv->ring.Start);
+ I915_WRITE(LP_RING + RING_LEN,
+ ((dev_priv->ring.Size - 4096) & RING_NR_PAGES) |
+ (RING_NO_REPORT | RING_VALID));
+
+ /* We are using separate values as placeholders for mechanisms for
+ * private backbuffer/depthbuffer usage.
+ */
+ dev_priv->use_mi_batchbuffer_start = 0;
+
+ /* Allow hardware batchbuffers unless told otherwise.
+ */
+ dev_priv->allow_batchbuffer = 1;
+
+ /* Program Hardware Status Page */
+ if (!IS_G33(dev)) {
+ dev_priv->status_page_dmah =
+ drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
+
+ if (!dev_priv->status_page_dmah) {
+ dev->dev_private = (void *)dev_priv;
+ i915_dma_cleanup(dev);
+ DRM_ERROR("Can not allocate hardware status page\n");
+ return -ENOMEM;
+ }
+ dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
+ dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
+
+ memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
+
+ I915_WRITE(I915REG_HWS_PGA, dev_priv->dma_status_page);
+ }
+ DRM_DEBUG("Enabled hardware status page\n");
+
+ intel_modeset_init(dev);
+ drm_initial_config(dev, false);
+
+ return 0;
+}
+
+int i915_driver_unload(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (dev_priv->ring.virtual_start) {
+ drm_core_ioremapfree(&dev_priv->ring.map, dev);
+ }
+
+ if (dev_priv->status_page_dmah) {
+ drm_pci_free(dev, dev_priv->status_page_dmah);
+ dev_priv->status_page_dmah = NULL;
+ dev_priv->hw_status_page = NULL;
+ dev_priv->dma_status_page = 0;
+ /* Need to rewrite hardware status page */
+ I915_WRITE(I915REG_HWS_PGA, 0x1ffff000);
+ }
+
+ if (dev_priv->status_gfx_addr) {
+ dev_priv->status_gfx_addr = 0;
+ drm_core_ioremapfree(&dev_priv->hws_map, dev);
+ I915_WRITE(I915REG_HWS_PGA, 0x1ffff000);
+ }
+
+ I915_WRITE(LP_RING + RING_LEN, 0);
+
+ intel_modeset_cleanup(dev);
+
+ drm_mem_reg_iounmap(dev, &dev_priv->ring_buffer->mem,
+ dev_priv->ring.virtual_start);
+
+ DRM_DEBUG("usage is %d\n", atomic_read(&dev_priv->ring_buffer->usage));
+ mutex_lock(&dev->struct_mutex);
+ drm_bo_usage_deref_locked(&dev_priv->ring_buffer);
+
+ if (drm_bo_clean_mm(dev, DRM_BO_MEM_TT)) {
+ DRM_ERROR("Memory manager type 3 not clean. "
+ "Delaying takedown\n");
+ }
+ if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM)) {
+ DRM_ERROR("Memory manager type 3 not clean. "
+ "Delaying takedown\n");
+ }
+ mutex_unlock(&dev->struct_mutex);
+
+ drm_bo_driver_finish(dev);
+
+ DRM_DEBUG("%p, %p\n", dev_priv->mmio_map, dev_priv->sarea);
+ drm_rmmap(dev, dev_priv->mmio_map);
+ drm_rmmap(dev, dev_priv->sarea);
+
+ drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
+
+ dev->dev_private = NULL;
+ return 0;
+}
+
+void i915_driver_lastclose(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ i915_do_cleanup_pageflip(dev);
+ //i915_mem_takedown(&(dev_priv->agp_heap));
+ i915_dma_cleanup(dev);
+}
+
+void i915_driver_preclose(struct drm_device *dev, struct drm_file *filp)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ //i915_mem_release(dev, filp, dev_priv->agp_heap);
+}
+
diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c
index 2c699ecd..bd576078 100644
--- a/shared-core/i915_irq.c
+++ b/shared-core/i915_irq.c
@@ -49,7 +49,7 @@
static int
i915_get_pipe(struct drm_device *dev, int plane)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
u32 dspcntr;
dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR);
@@ -66,8 +66,8 @@ static void
i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw,
int plane)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+ struct drm_i915_sarea *sarea_priv = dev_priv->sarea_priv;
u16 x1, y1, x2, y2;
int pf_planes = 1 << plane;
@@ -111,13 +111,13 @@ i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw,
*/
static void i915_vblank_tasklet(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
struct list_head *list, *tmp, hits, *hit;
int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages;
unsigned counter[2] = { atomic_read(&dev->vbl_received),
atomic_read(&dev->vbl_received2) };
struct drm_drawable_info *drw;
- drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ struct drm_i915_sarea *sarea_priv = dev_priv->sarea_priv;
u32 cpp = dev_priv->cpp, offsets[3];
u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
XY_SRC_COPY_BLT_WRITE_ALPHA |
@@ -142,8 +142,8 @@ static void i915_vblank_tasklet(struct drm_device *dev)
/* Find buffer swaps scheduled for this vertical blank */
list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
- drm_i915_vbl_swap_t *vbl_swap =
- list_entry(list, drm_i915_vbl_swap_t, head);
+ struct drm_i915_vbl_swap *vbl_swap =
+ list_entry(list, struct drm_i915_vbl_swap, head);
int pipe = i915_get_pipe(dev, vbl_swap->plane);
if ((counter[pipe] - vbl_swap->sequence) > (1<<23))
@@ -165,8 +165,8 @@ static void i915_vblank_tasklet(struct drm_device *dev)
}
list_for_each(hit, &hits) {
- drm_i915_vbl_swap_t *swap_cmp =
- list_entry(hit, drm_i915_vbl_swap_t, head);
+ struct drm_i915_vbl_swap *swap_cmp =
+ list_entry(hit, struct drm_i915_vbl_swap, head);
struct drm_drawable_info *drw_cmp =
drm_get_drawable_info(dev, swap_cmp->drw_id);
@@ -223,8 +223,8 @@ static void i915_vblank_tasklet(struct drm_device *dev)
lower[0] = lower[1] = sarea_priv->height;
list_for_each(hit, &hits) {
- drm_i915_vbl_swap_t *swap_hit =
- list_entry(hit, drm_i915_vbl_swap_t, head);
+ struct drm_i915_vbl_swap *swap_hit =
+ list_entry(hit, struct drm_i915_vbl_swap, head);
struct drm_clip_rect *rect;
int num_rects, plane, front, back;
unsigned short top, bottom;
@@ -292,8 +292,8 @@ static void i915_vblank_tasklet(struct drm_device *dev)
DRM_SPINUNLOCK(&dev->drw_lock);
list_for_each_safe(hit, tmp, &hits) {
- drm_i915_vbl_swap_t *swap_hit =
- list_entry(hit, drm_i915_vbl_swap_t, head);
+ struct drm_i915_vbl_swap *swap_hit =
+ list_entry(hit, struct drm_i915_vbl_swap, head);
list_del(hit);
@@ -304,7 +304,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
u16 temp;
u32 pipea_stats, pipeb_stats;
@@ -367,7 +367,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
int i915_emit_irq(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+
+ struct drm_i915_private *dev_priv = dev->dev_private;
RING_LOCALS;
i915_kernel_lost_context(dev);
@@ -384,7 +385,7 @@ int i915_emit_irq(struct drm_device *dev)
return dev_priv->counter;
}
-void i915_user_irq_on(drm_i915_private_t *dev_priv)
+void i915_user_irq_on(struct drm_i915_private *dev_priv)
{
DRM_SPINLOCK(&dev_priv->user_irq_lock);
if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1)){
@@ -394,8 +395,8 @@ void i915_user_irq_on(drm_i915_private_t *dev_priv)
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
}
-
-void i915_user_irq_off(drm_i915_private_t *dev_priv)
+
+void i915_user_irq_off(struct drm_i915_private *dev_priv)
{
DRM_SPINLOCK(&dev_priv->user_irq_lock);
if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
@@ -408,7 +409,7 @@ void i915_user_irq_off(drm_i915_private_t *dev_priv)
static int i915_wait_irq(struct drm_device * dev, int irq_nr)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
int ret = 0;
DRM_DEBUG("%s irq_nr=%d breadcrumb=%d\n", __FUNCTION__, irq_nr,
@@ -438,7 +439,7 @@ static int i915_driver_vblank_do_wait(struct drm_device *dev,
unsigned int *sequence,
atomic_t *counter)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
unsigned int cur_vblank;
int ret = 0;
@@ -456,6 +457,19 @@ static int i915_driver_vblank_do_wait(struct drm_device *dev,
return ret;
}
+void i915_driver_wait_next_vblank(struct drm_device *dev, int pipe)
+{
+ unsigned int seq;
+
+ seq = pipe ? atomic_read(&dev->vbl_received2) + 1 :
+ atomic_read(&dev->vbl_received) + 1;
+
+ if (!pipe)
+ i915_driver_vblank_do_wait(dev, &seq, &dev->vbl_received);
+ else
+ i915_driver_vblank_do_wait(dev, &seq, &dev->vbl_received2);
+}
+
int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
{
return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received);
@@ -471,8 +485,8 @@ int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
int i915_irq_emit(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
- drm_i915_irq_emit_t *emit = data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_irq_emit *emit = data;
int result;
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -497,8 +511,8 @@ int i915_irq_emit(struct drm_device *dev, void *data,
int i915_irq_wait(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
- drm_i915_irq_wait_t *irqwait = data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_irq_wait *irqwait = data;
if (!dev_priv) {
DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
@@ -508,11 +522,12 @@ int i915_irq_wait(struct drm_device *dev, void *data,
return i915_wait_irq(dev, irqwait->irq_seq);
}
-static void i915_enable_interrupt (struct drm_device *dev)
+void i915_enable_interrupt (struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+
+ dev_priv->irq_enable_reg = USER_INT_FLAG;
- dev_priv->irq_enable_reg = USER_INT_FLAG;
if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
dev_priv->irq_enable_reg |= VSYNC_PIPEA_FLAG;
if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
@@ -527,8 +542,8 @@ static void i915_enable_interrupt (struct drm_device *dev)
int i915_vblank_pipe_set(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
- drm_i915_vblank_pipe_t *pipe = data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_vblank_pipe *pipe = data;
if (!dev_priv) {
DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
@@ -551,8 +566,8 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data,
int i915_vblank_pipe_get(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
- drm_i915_vblank_pipe_t *pipe = data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_vblank_pipe *pipe = data;
u16 flag;
if (!dev_priv) {
@@ -576,9 +591,9 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
int i915_vblank_swap(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
- drm_i915_vblank_swap_t *swap = data;
- drm_i915_vbl_swap_t *vbl_swap;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_vblank_swap *swap = data;
+ struct drm_i915_vbl_swap *vbl_swap;
unsigned int pipe, seqtype, curseq, plane;
unsigned long irqflags;
struct list_head *list;
@@ -670,7 +685,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
DRM_SPINLOCK_IRQSAVE(&dev_priv->swaps_lock, irqflags);
list_for_each(list, &dev_priv->vbl_swaps.head) {
- vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head);
+ vbl_swap = list_entry(list, struct drm_i915_vbl_swap, head);
if (vbl_swap->drw_id == swap->drawable &&
vbl_swap->plane == plane &&
@@ -720,7 +735,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
*/
void i915_driver_irq_preinstall(struct drm_device * dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
I915_WRITE16(I915REG_HWSTAM, 0xeffe);
I915_WRITE16(I915REG_INT_MASK_R, 0x0);
@@ -729,7 +744,7 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
void i915_driver_irq_postinstall(struct drm_device * dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
DRM_SPININIT(&dev_priv->swaps_lock, "swap");
INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
@@ -750,7 +765,7 @@ void i915_driver_irq_postinstall(struct drm_device * dev)
void i915_driver_irq_uninstall(struct drm_device * dev)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
u16 temp;
if (!dev_priv)
diff --git a/shared-core/i915_mem.c b/shared-core/i915_mem.c
index d360896f..4c7ced24 100644
--- a/shared-core/i915_mem.c
+++ b/shared-core/i915_mem.c
@@ -45,8 +45,8 @@
*/
static void mark_block(struct drm_device * dev, struct mem_block *p, int in_use)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
- drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_sarea *sarea_priv = dev_priv->sarea_priv;
struct drm_tex_region *list;
unsigned shift, nr;
unsigned start;
@@ -256,7 +256,7 @@ void i915_mem_takedown(struct mem_block **heap)
*heap = NULL;
}
-static struct mem_block **get_heap(drm_i915_private_t * dev_priv, int region)
+static struct mem_block **get_heap(struct drm_i915_private * dev_priv, int region)
{
switch (region) {
case I915_MEM_REGION_AGP:
@@ -271,8 +271,8 @@ static struct mem_block **get_heap(drm_i915_private_t * dev_priv, int region)
int i915_mem_alloc(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
- drm_i915_mem_alloc_t *alloc = data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_mem_alloc *alloc = data;
struct mem_block *block, **heap;
if (!dev_priv) {
@@ -309,8 +309,8 @@ int i915_mem_alloc(struct drm_device *dev, void *data,
int i915_mem_free(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
- drm_i915_mem_free_t *memfree = data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_mem_free *memfree = data;
struct mem_block *block, **heap;
if (!dev_priv) {
@@ -337,8 +337,8 @@ int i915_mem_free(struct drm_device *dev, void *data,
int i915_mem_init_heap(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
- drm_i915_mem_init_heap_t *initheap = data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_mem_init_heap *initheap = data;
struct mem_block **heap;
if (!dev_priv) {
@@ -361,8 +361,8 @@ int i915_mem_init_heap(struct drm_device *dev, void *data,
int i915_mem_destroy_heap( struct drm_device *dev, void *data,
struct drm_file *file_priv )
{
- drm_i915_private_t *dev_priv = dev->dev_private;
- drm_i915_mem_destroy_heap_t *destroyheap = data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_mem_destroy_heap *destroyheap = data;
struct mem_block **heap;
if ( !dev_priv ) {
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
index 8f95a077..76232e48 100644
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -1405,6 +1405,28 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
}
}
+void radeon_gart_flush(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ if (dev_priv->flags & RADEON_IS_IGPGART) {
+ RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH);
+ RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x1);
+ RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH);
+ RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x0);
+ } else if (dev_priv->flags & RADEON_IS_PCIE) {
+ u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
+ tmp |= RADEON_PCIE_TX_GART_INVALIDATE_TLB;
+ RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp);
+ tmp &= ~RADEON_PCIE_TX_GART_INVALIDATE_TLB;
+ RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp);
+ } else {
+
+
+ }
+
+}
+
static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -2316,6 +2338,9 @@ int radeon_driver_firstopen(struct drm_device *dev)
if (ret != 0)
return ret;
+#ifdef RADEON_HAVE_BUFFER
+ drm_bo_driver_init(dev);
+#endif
return 0;
}
diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h
index 0971f970..67536c26 100644
--- a/shared-core/radeon_drm.h
+++ b/shared-core/radeon_drm.h
@@ -434,8 +434,17 @@ typedef struct {
int pfCurrentPage; /* which buffer is being displayed? */
int crtc2_base; /* CRTC2 frame offset */
int tiling_enabled; /* set by drm, read by 2d + 3d clients */
+
+ unsigned int last_fence;
} drm_radeon_sarea_t;
+/* The only fence class we support */
+#define DRM_RADEON_FENCE_CLASS_ACCEL 0
+/* Fence type that guarantees read-write flush */
+#define DRM_RADEON_FENCE_TYPE_RW 2
+/* cache flushes programmed just before the fence */
+#define DRM_RADEON_FENCE_FLAG_FLUSHED 0x01000000
+
/* WARNING: If you change any of these defines, make sure to change the
* defines in the Xserver file (xf86drmRadeon.h)
*
diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h
index fcbdc2e2..37b9c43f 100644
--- a/shared-core/radeon_drv.h
+++ b/shared-core/radeon_drv.h
@@ -104,6 +104,11 @@
#define DRIVER_MINOR 28
#define DRIVER_PATCHLEVEL 0
+#if defined(__linux__)
+#define RADEON_HAVE_FENCE
+#define RADEON_HAVE_BUFFER
+#endif
+
/*
* Radeon chip families
*/
@@ -284,8 +289,9 @@ typedef struct drm_radeon_private {
struct mem_block *fb_heap;
/* SW interrupt */
- wait_queue_head_t swi_queue;
- atomic_t swi_emitted;
+ wait_queue_head_t irq_queue;
+ int counter;
+
int vblank_crtc;
uint32_t irq_enable_reg;
int irq_enabled;
@@ -345,6 +351,7 @@ extern int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file
extern int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern void radeon_gart_flush(struct drm_device *dev);
extern u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv);
extern void radeon_freelist_reset(struct drm_device * dev);
@@ -364,6 +371,7 @@ extern void radeon_mem_release(struct drm_file *file_priv,
/* radeon_irq.c */
extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int radeon_emit_irq(struct drm_device * dev);
extern void radeon_do_release(struct drm_device * dev);
extern int radeon_driver_vblank_wait(struct drm_device * dev,
@@ -397,6 +405,30 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
struct drm_file *file_priv,
drm_radeon_kcmd_buffer_t *cmdbuf);
+
+#ifdef RADEON_HAVE_FENCE
+/* i915_fence.c */
+
+
+extern void radeon_fence_handler(struct drm_device *dev);
+extern int radeon_fence_emit_sequence(struct drm_device *dev, uint32_t class,
+ uint32_t flags, uint32_t *sequence,
+ uint32_t *native_type);
+extern void radeon_poke_flush(struct drm_device *dev, uint32_t class);
+extern int radeon_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t flags);
+#endif
+
+#ifdef RADEON_HAVE_BUFFER
+/* radeon_buffer.c */
+extern struct drm_ttm_backend *radeon_create_ttm_backend_entry(struct drm_device *dev);
+extern int radeon_fence_types(struct drm_buffer_object *bo, uint32_t *class, uint32_t *type);
+extern int radeon_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags);
+extern uint32_t radeon_evict_mask(struct drm_buffer_object *bo);
+extern int radeon_init_mem_type(struct drm_device * dev, uint32_t type,
+ struct drm_mem_type_manager * man);
+extern int radeon_move(struct drm_buffer_object * bo,
+ int evict, int no_wait, struct drm_bo_mem_reg * new_mem);
+#endif
/* Flags for stats.boxes
*/
#define RADEON_BOX_DMA_IDLE 0x1
@@ -1268,4 +1300,19 @@ do { \
write &= mask; \
} while (0)
+/* Breadcrumb - swi irq */
+#define READ_BREADCRUMB(dev_priv) RADEON_READ(RADEON_LAST_SWI_REG)
+
+static inline int radeon_update_breadcrumb(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ dev_priv->sarea_priv->last_fence = ++dev_priv->counter;
+
+ if (dev_priv->counter > 0x7FFFFFFFUL)
+ dev_priv->sarea_priv->last_fence = dev_priv->counter = 1;
+
+ return dev_priv->counter;
+}
+
#endif /* __RADEON_DRV_H__ */
diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c
index 2b2407ee..544e3a0f 100644
--- a/shared-core/radeon_irq.c
+++ b/shared-core/radeon_irq.c
@@ -82,7 +82,10 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
/* SW interrupt */
if (stat & RADEON_SW_INT_TEST) {
- DRM_WAKEUP(&dev_priv->swi_queue);
+ DRM_WAKEUP(&dev_priv->irq_queue);
+#ifdef RADEON_HAVE_FENCE
+ radeon_fence_handler(dev);
+#endif
}
/* VBLANK interrupt */
@@ -109,14 +112,13 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
return IRQ_HANDLED;
}
-static int radeon_emit_irq(struct drm_device * dev)
+int radeon_emit_irq(struct drm_device * dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
unsigned int ret;
RING_LOCALS;
- atomic_inc(&dev_priv->swi_emitted);
- ret = atomic_read(&dev_priv->swi_emitted);
+ ret = radeon_update_breadcrumb(dev);
BEGIN_RING(4);
OUT_RING_REG(RADEON_LAST_SWI_REG, ret);
@@ -133,13 +135,13 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr)
(drm_radeon_private_t *) dev->dev_private;
int ret = 0;
- if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr)
+ if (READ_BREADCRUMB(dev_priv) >= swi_nr)
return 0;
dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
- DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ,
- RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr);
+ DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
+ READ_BREADCRUMB(dev_priv) >= swi_nr);
return ret;
}
@@ -270,8 +272,8 @@ void radeon_driver_irq_postinstall(struct drm_device * dev)
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *) dev->dev_private;
- atomic_set(&dev_priv->swi_emitted, 0);
- DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
+ dev_priv->counter = 0;
+ DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
radeon_enable_interrupt(dev);
}