summaryrefslogtreecommitdiff
path: root/shared-core
diff options
context:
space:
mode:
Diffstat (limited to 'shared-core')
-rw-r--r--shared-core/drm.h185
-rw-r--r--shared-core/drm_pciids.txt4
-rw-r--r--shared-core/i915_dma.c321
-rw-r--r--shared-core/i915_drm.h10
-rw-r--r--shared-core/i915_drv.h731
-rw-r--r--shared-core/i915_init.c365
-rw-r--r--shared-core/i915_irq.c386
-rw-r--r--shared-core/i915_mem.c23
-rw-r--r--shared-core/nouveau_mem.c6
-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.c24
-rw-r--r--shared-core/radeon_ms.h607
-rw-r--r--shared-core/radeon_ms_bo.c311
-rw-r--r--shared-core/radeon_ms_bus.c460
-rw-r--r--shared-core/radeon_ms_combios.c411
-rw-r--r--shared-core/radeon_ms_combios.h385
-rw-r--r--shared-core/radeon_ms_cp.c345
-rw-r--r--shared-core/radeon_ms_cp_mc.c801
-rw-r--r--shared-core/radeon_ms_crtc.c803
-rw-r--r--shared-core/radeon_ms_dac.c400
-rw-r--r--shared-core/radeon_ms_drm.c318
-rw-r--r--shared-core/radeon_ms_drm.h60
-rw-r--r--shared-core/radeon_ms_exec.c242
-rw-r--r--shared-core/radeon_ms_family.c141
-rw-r--r--shared-core/radeon_ms_fence.c129
-rw-r--r--shared-core/radeon_ms_gpu.c589
-rw-r--r--shared-core/radeon_ms_i2c.c336
-rw-r--r--shared-core/radeon_ms_irq.c161
-rw-r--r--shared-core/radeon_ms_output.c361
-rw-r--r--shared-core/radeon_ms_properties.c123
-rw-r--r--shared-core/radeon_ms_properties.h50
-rw-r--r--shared-core/radeon_ms_reg.h1681
-rw-r--r--shared-core/radeon_ms_rom.c91
-rw-r--r--shared-core/radeon_ms_rom.h51
-rw-r--r--shared-core/radeon_ms_state.c45
-rw-r--r--shared-core/radeon_state.c2
38 files changed, 10703 insertions, 340 deletions
diff --git a/shared-core/drm.h b/shared-core/drm.h
index 6c134566..0d7cfd25 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -950,6 +950,174 @@ 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_PROP_NAME_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 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 {
+ uint64_t fb_id_ptr;
+ uint64_t crtc_id_ptr;
+ uint64_t output_id_ptr;
+ int count_fbs;
+ int count_crtcs;
+ int count_outputs;
+ int min_width, max_width;
+ int min_height, max_height;
+};
+
+struct drm_mode_crtc {
+ uint64_t set_outputs_ptr;
+
+ unsigned int crtc_id; /**< Id */
+ unsigned int fb_id; /**< Id of framebuffer */
+
+ int x, y; /**< Position on the frameuffer */
+
+ int count_outputs;
+ unsigned int outputs; /**< Outputs that are connected */
+
+ int count_possibles;
+ unsigned int possibles; /**< Outputs that can be connected */
+ int gamma_size;
+ int mode_valid;
+ struct drm_mode_modeinfo mode;
+};
+
+#define DRM_MODE_OUTPUT_NONE 0
+#define DRM_MODE_OUTPUT_DAC 1
+#define DRM_MODE_OUTPUT_TMDS 2
+#define DRM_MODE_OUTPUT_LVDS 3
+#define DRM_MODE_OUTPUT_TVDAC 4
+
+struct drm_mode_get_output {
+
+ uint64_t modes_ptr;
+ uint64_t props_ptr;
+ uint64_t prop_values_ptr;
+
+ int count_modes;
+ int count_props;
+ unsigned int output; /**< Id */
+ unsigned int crtc; /**< Id of crtc */
+ unsigned int output_type;
+ unsigned int output_type_id;
+
+ unsigned int connection;
+ unsigned int mm_width, mm_height; /**< HxW in millimeters */
+ unsigned int subpixel;
+ int count_crtcs;
+ int count_clones;
+ unsigned int crtcs; /**< possible crtc to connect to */
+ unsigned int clones; /**< list of clones */
+};
+
+#define DRM_MODE_PROP_PENDING (1<<0)
+#define DRM_MODE_PROP_RANGE (1<<1)
+#define DRM_MODE_PROP_IMMUTABLE (1<<2)
+#define DRM_MODE_PROP_ENUM (1<<3) // enumerated type with text strings
+#define DRM_MODE_PROP_BLOB (1<<4)
+
+struct drm_mode_property_enum {
+ uint64_t value;
+ unsigned char name[DRM_PROP_NAME_LEN];
+};
+
+struct drm_mode_get_property {
+ uint64_t values_ptr; /* values and blob lengths */
+ uint64_t enum_blob_ptr; /* enum and blob id ptrs */
+
+ unsigned int prop_id;
+ unsigned int flags;
+ unsigned char name[DRM_PROP_NAME_LEN];
+
+ int count_values;
+ int count_enum_blobs;
+};
+
+struct drm_mode_output_set_property {
+ uint64_t value;
+ unsigned int prop_id;
+ unsigned int output_id;
+};
+
+struct drm_mode_get_blob {
+ uint32_t blob_id;
+ uint32_t length;
+ uint64_t data;
+};
+
+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;
+ struct drm_mode_modeinfo mode;
+};
+
+#define DRM_MODE_CURSOR_BO 0x01
+#define DRM_MODE_CURSOR_MOVE 0x02
+
+/*
+ * depending on the value in flags diffrent members are used.
+ *
+ * CURSOR_BO uses
+ * crtc
+ * width
+ * height
+ * handle - if 0 turns the cursor of
+ *
+ * CURSOR_MOVE uses
+ * crtc
+ * x
+ * y
+ */
+struct drm_mode_cursor {
+ unsigned int flags;
+ unsigned int crtc;
+ int x;
+ int y;
+ uint32_t width;
+ uint32_t height;
+ unsigned int handle;
+};
+
+/*
+ * oh so ugly hotplug
+ */
+struct drm_mode_hotplug {
+ uint32_t counter;
+};
+
/**
* \name Ioctls Definitions
*/
@@ -1042,6 +1210,23 @@ struct drm_mm_init_arg {
#define DRM_IOCTL_BO_WAIT_IDLE DRM_IOWR(0xd5, struct drm_bo_map_wait_idle_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_SETPROPERTY DRM_IOWR(0xA7, struct drm_mode_output_set_property)
+#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xA8, struct drm_mode_get_blob)
+#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)
+
+#define DRM_IOCTL_MODE_GETPROPERTY DRM_IOWR(0xAB, struct drm_mode_get_property)
+#define DRM_IOCTL_MODE_CURSOR DRM_IOWR(0xAC, struct drm_mode_cursor)
+#define DRM_IOCTL_MODE_HOTPLUG DRM_IOWR(0xAD, struct drm_mode_hotplug)
+
/*@}*/
/**
diff --git a/shared-core/drm_pciids.txt b/shared-core/drm_pciids.txt
index 63b5cd50..c895d7f7 100644
--- a/shared-core/drm_pciids.txt
+++ b/shared-core/drm_pciids.txt
@@ -1,3 +1,7 @@
+[radeon_ms]
+0x1002 0x4150 CHIP_RV350|RADEON_AGP "ATI Radeon RV350 9600"
+0x1002 0x5b63 CHIP_RV370|RADEON_PCIE "ATI Radeon RV370 X550"
+
[radeon]
0x1002 0x3150 CHIP_RV380|RADEON_IS_MOBILITY "ATI Radeon Mobility X600 M24"
0x1002 0x3152 CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Radeon Mobility X300 M24"
diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c
index 3874ed58..11c000b9 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;
@@ -63,8 +63,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;
@@ -73,9 +73,8 @@ void i915_kernel_lost_context(struct drm_device * dev)
ring->space += ring->Size;
}
-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.
@@ -83,26 +82,6 @@ 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;
}
@@ -122,7 +101,7 @@ setup_dri2_sarea(struct drm_device * dev,
struct drm_file *file_priv,
drm_i915_init_t * init)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
unsigned int *p, *end, *next;
@@ -150,8 +129,8 @@ setup_dri2_sarea(struct drm_device * dev,
while (p < end && DRI2_SAREA_BLOCK_TYPE(*p) != DRI2_SAREA_BLOCK_END) {
switch (DRI2_SAREA_BLOCK_TYPE(*p)) {
case DRI2_SAREA_BLOCK_LOCK:
- dev->lock.hw_lock = (void *) (p + 1);
- dev->sigdata.lock = dev->lock.hw_lock;
+ dev->primary->master->lock.hw_lock = (void *) (p + 1);
+ dev->sigdata.lock = dev->primary->master->lock.hw_lock;
break;
}
next = DRI2_SAREA_BLOCK_NEXT(p);
@@ -171,18 +150,10 @@ static int i915_initialize(struct drm_device * dev,
struct drm_file *file_priv,
drm_i915_init_t * init)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
- int ret;
-
- dev_priv->sarea = drm_getsarea(dev);
- if (!dev_priv->sarea) {
- DRM_ERROR("can not find sarea!\n");
- i915_dma_cleanup(dev);
- return -EINVAL;
- }
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
- if (init->mmio_offset != 0)
- dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
+ dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
if (!dev_priv->mmio_map) {
i915_dma_cleanup(dev);
DRM_ERROR("can not find mmio map!\n");
@@ -193,41 +164,32 @@ static int i915_initialize(struct drm_device * dev,
dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS;
#endif
- if (init->sarea_priv_offset)
- dev_priv->sarea_priv = (drm_i915_sarea_t *)
- ((u8 *) dev_priv->sarea->handle +
- init->sarea_priv_offset);
- else {
- /* No sarea_priv for you! */
- dev_priv->sarea_priv = NULL;
- }
-
- dev_priv->ring.Start = init->ring_start;
- dev_priv->ring.End = init->ring_end;
- dev_priv->ring.Size = init->ring_size;
- dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
-
- dev_priv->ring.map.offset = init->ring_start;
- dev_priv->ring.map.size = init->ring_size;
- dev_priv->ring.map.type = 0;
- dev_priv->ring.map.flags = 0;
- dev_priv->ring.map.mtrr = 0;
-
- drm_core_ioremap(&dev_priv->ring.map, dev);
-
- if (dev_priv->ring.map.handle == NULL) {
- i915_dma_cleanup(dev);
- DRM_ERROR("can not ioremap virtual address for"
- " ring buffer\n");
- return -ENOMEM;
+ if (!dev_priv->ring.Size) {
+ dev_priv->ring.Start = init->ring_start;
+ dev_priv->ring.End = init->ring_end;
+ dev_priv->ring.Size = init->ring_size;
+ dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
+
+ dev_priv->ring.map.offset = init->ring_start;
+ dev_priv->ring.map.size = init->ring_size;
+ dev_priv->ring.map.type = 0;
+ dev_priv->ring.map.flags = 0;
+ dev_priv->ring.map.mtrr = 0;
+
+ drm_core_ioremap(&dev_priv->ring.map, dev);
+
+ if (dev_priv->ring.map.handle == NULL) {
+ i915_dma_cleanup(dev);
+ DRM_ERROR("can not ioremap virtual address for"
+ " ring buffer\n");
+ return -ENOMEM;
+ }
+ dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
}
- dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
dev_priv->cpp = init->cpp;
-
- if (dev_priv->sarea_priv)
- dev_priv->sarea_priv->pf_current_page = 0;
+ master_priv->sarea_priv->pf_current_page = 0;
/* We are using separate values as placeholders for mechanisms for
* private backbuffer/depthbuffer usage.
@@ -267,29 +229,23 @@ static int i915_initialize(struct drm_device * dev,
#endif
if (init->func == I915_INIT_DMA2) {
- ret = setup_dri2_sarea(dev, file_priv, init);
+ int ret = setup_dri2_sarea(dev, file_priv, init);
if (ret) {
i915_dma_cleanup(dev);
DRM_ERROR("could not set up dri2 sarea\n");
return ret;
}
}
-
return 0;
}
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("\n");
- if (!dev_priv->sarea) {
- DRM_ERROR("can not find sarea!\n");
- return -EINVAL;
- }
-
if (!dev_priv->mmio_map) {
DRM_ERROR("can not find mmio map!\n");
return -EINVAL;
@@ -320,7 +276,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) {
@@ -421,7 +377,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;
@@ -462,7 +418,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;
@@ -503,7 +459,8 @@ 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;
+ struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
RING_LOCALS;
if (++dev_priv->counter > BREADCRUMB_MASK) {
@@ -511,8 +468,7 @@ void i915_emit_breadcrumb(struct drm_device *dev)
DRM_DEBUG("Breadcrumb counter wrapped around\n");
}
- if (dev_priv->sarea_priv)
- dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
+ master_priv->sarea_priv->last_enqueue = dev_priv->counter;
BEGIN_LP_RING(4);
OUT_RING(CMD_STORE_DWORD_IDX);
@@ -525,7 +481,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;
@@ -545,10 +501,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;
@@ -586,7 +542,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;
@@ -640,38 +596,39 @@ 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;
+ struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
u32 num_pages, current_page, next_page, dspbase;
int shift = 2 * plane, x, y;
RING_LOCALS;
/* Calculate display base offset */
- num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
- current_page = (dev_priv->sarea_priv->pf_current_page >> shift) & 0x3;
+ num_pages = master_priv->sarea_priv->third_handle ? 3 : 2;
+ current_page = (master_priv->sarea_priv->pf_current_page >> shift) & 0x3;
next_page = (current_page + 1) % num_pages;
switch (next_page) {
default:
case 0:
- dspbase = dev_priv->sarea_priv->front_offset;
+ dspbase = master_priv->sarea_priv->front_offset;
break;
case 1:
- dspbase = dev_priv->sarea_priv->back_offset;
+ dspbase = master_priv->sarea_priv->back_offset;
break;
case 2:
- dspbase = dev_priv->sarea_priv->third_offset;
+ dspbase = master_priv->sarea_priv->third_offset;
break;
}
if (plane == 0) {
- x = dev_priv->sarea_priv->planeA_x;
- y = dev_priv->sarea_priv->planeA_y;
+ x = master_priv->sarea_priv->planeA_x;
+ y = master_priv->sarea_priv->planeA_y;
} else {
- x = dev_priv->sarea_priv->planeB_x;
- y = dev_priv->sarea_priv->planeB_y;
+ x = master_priv->sarea_priv->planeB_x;
+ y = master_priv->sarea_priv->planeB_y;
}
- dspbase += (y * dev_priv->sarea_priv->pitch + x) * dev_priv->cpp;
+ dspbase += (y * master_priv->sarea_priv->pitch + x) * dev_priv->cpp;
DRM_DEBUG("plane=%d current_page=%d dspbase=0x%x\n", plane, current_page,
dspbase);
@@ -682,21 +639,22 @@ static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync)
MI_WAIT_FOR_PLANE_A_FLIP)));
OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | (sync ? 0 : ASYNC_FLIP) |
(plane ? DISPLAY_PLANE_B : DISPLAY_PLANE_A));
- OUT_RING(dev_priv->sarea_priv->pitch * dev_priv->cpp);
+ OUT_RING(master_priv->sarea_priv->pitch * dev_priv->cpp);
OUT_RING(dspbase);
ADVANCE_LP_RING();
- dev_priv->sarea_priv->pf_current_page &= ~(0x3 << shift);
- dev_priv->sarea_priv->pf_current_page |= next_page << shift;
+ master_priv->sarea_priv->pf_current_page &= ~(0x3 << shift);
+ master_priv->sarea_priv->pf_current_page |= next_page << shift;
}
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;
+ struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
int i;
DRM_DEBUG("planes=0x%x pfCurrentPage=%d\n",
- planes, dev_priv->sarea_priv->pf_current_page);
+ planes, master_priv->sarea_priv->pf_current_page);
i915_emit_mi_flush(dev, MI_READ_FLUSH | MI_EXE_FLUSH);
@@ -713,7 +671,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__);
@@ -731,9 +689,10 @@ 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;
+ struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
- dev_priv->sarea_priv;
+ master_priv->sarea_priv;
drm_i915_batchbuffer_t *batch = data;
int ret;
@@ -761,10 +720,11 @@ 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 *)
- dev_priv->sarea_priv;
- drm_i915_cmdbuffer_t *cmdbuf = data;
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+ struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
+ struct drm_i915_sarea *sarea_priv = (struct drm_i915_sarea *)
+ master_priv->sarea_priv;
+ struct drm_i915_cmdbuffer *cmdbuf = data;
int ret;
DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
@@ -966,7 +926,7 @@ static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle,
struct drm_i915_validate_buffer *buffers,
uint32_t buf_count)
{
- struct drm_device *dev = file_priv->head->dev;
+ struct drm_device *dev = file_priv->minor->dev;
struct i915_relocatee_info relocatee;
int ret = 0;
int b;
@@ -1026,7 +986,7 @@ int i915_validate_buffer_list(struct drm_file *file_priv,
unsigned long next = 0;
int ret = 0;
unsigned buf_count = 0;
- struct drm_device *dev = file_priv->head->dev;
+ struct drm_device *dev = file_priv->minor->dev;
uint32_t buf_handle;
uint32_t __user *reloc_user_ptr;
@@ -1117,11 +1077,12 @@ 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;
+ struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
- dev_priv->sarea_priv;
+ master_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;
@@ -1222,21 +1183,22 @@ 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_master_private *master_priv = dev->primary->master->driver_priv;
+ int i, planes, num_pages;
DRM_DEBUG("\n");
-
- 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 &
+ num_pages = master_priv->sarea_priv->third_handle ? 3 : 2;
+ for (i = 0, planes = 0; i < 2; i++) {
+ if (master_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) {
+ master_priv->sarea_priv->pf_current_page =
+ (master_priv->sarea_priv->pf_current_page &
~(0x3 << (2 * i))) | ((num_pages - 1) << (2 * i));
planes |= 1 << i;
}
+ }
if (planes)
i915_dispatch_flip(dev, planes, 0);
@@ -1246,7 +1208,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("\n");
@@ -1268,8 +1230,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) {
@@ -1306,7 +1268,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) {
@@ -1347,8 +1309,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;
@@ -1393,7 +1355,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) {
@@ -1421,99 +1383,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 | _DRM_DRIVER, &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));
-
- if (dev_priv->sarea_kmap.virtual) {
- drm_bo_kunmap(&dev_priv->sarea_kmap);
- dev_priv->sarea_kmap.virtual = NULL;
- dev->lock.hw_lock = NULL;
- dev->sigdata.lock = NULL;
- }
-
- if (dev_priv->sarea_bo) {
- mutex_lock(&dev->struct_mutex);
- drm_bo_usage_deref_locked(&dev_priv->sarea_bo);
- mutex_unlock(&dev->struct_mutex);
- dev_priv->sarea_bo = NULL;
- }
-
- 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),
@@ -1556,10 +1432,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 3dcb6278..b8eaa021 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,
@@ -69,7 +69,7 @@ typedef struct _drm_i915_init {
unsigned int sarea_handle;
} 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 */
@@ -211,7 +211,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 */
@@ -223,7 +223,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 */
@@ -375,7 +375,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 4d3ac0a5..f6c0005d 100644
--- a/shared-core/i915_drv.h
+++ b/shared-core/i915_drv.h
@@ -71,7 +71,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;
@@ -81,7 +81,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;
@@ -91,22 +91,31 @@ 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;
+ struct drm_minor *minor;
+};
-typedef struct drm_i915_private {
+struct drm_i915_master_private {
drm_local_map_t *sarea;
+ struct drm_i915_sarea *sarea_priv;
+};
+
+struct drm_i915_private {
+ struct drm_buffer_object *ring_buffer;
+
drm_local_map_t *mmio_map;
- drm_i915_sarea_t *sarea_priv;
- drm_i915_ring_buffer_t ring;
+ unsigned long mmiobase;
+ unsigned long mmiolen;
- drm_dma_handle_t *status_page_dmah;
+ struct drm_i915_ring_buffer ring;
+
+ struct drm_dma_handle *status_page_dmah;
void *hw_status_page;
dma_addr_t dma_status_page;
uint32_t counter;
@@ -131,6 +140,8 @@ typedef struct drm_i915_private {
uint32_t irq_enable_reg;
int irq_enabled;
+ struct workqueue_struct *wq;
+
#ifdef I915_HAVE_FENCE
uint32_t flush_sequence;
uint32_t flush_flags;
@@ -141,12 +152,18 @@ typedef struct drm_i915_private {
void *agp_iomap;
unsigned int max_validate_buffers;
struct mutex cmdbuf_mutex;
+ size_t stolen_base;
#endif
DRM_SPINTYPE swaps_lock;
- drm_i915_vbl_swap_t vbl_swaps;
+ struct drm_i915_vbl_swap vbl_swaps;
unsigned int swaps_pending;
+ /* LVDS info */
+ int backlight_duty_cycle; /* restore backlight to this value */
+ bool panel_wants_dither;
+ struct drm_display_mode *panel_fixed_mode;
+
/* DRI2 sarea */
struct drm_buffer_object *sarea_bo;
struct drm_bo_kmap_obj sarea_kmap;
@@ -237,7 +254,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,
@@ -249,10 +266,12 @@ enum intel_chip_family {
extern struct drm_ioctl_desc i915_ioctls[];
extern int i915_max_ioctl;
+extern int i915_master_create(struct drm_device *dev, struct drm_master *master);
+extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master);
/* 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);
@@ -263,6 +282,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,
@@ -279,13 +300,14 @@ extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
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_enable_interrupt (struct drm_device *dev);
extern int i915_enable_vblank(struct drm_device *dev, int crtc);
extern void i915_disable_vblank(struct drm_device *dev, int crtc);
extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
extern int i915_vblank_swap(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-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 void i915_user_irq_on(struct drm_i915_private *dev_priv);
+extern void i915_user_irq_off(struct drm_i915_private *dev_priv);
/* i915_mem.c */
extern int i915_mem_alloc(struct drm_device *dev, void *data,
@@ -328,6 +350,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))
@@ -365,8 +393,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
@@ -433,6 +484,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 */
@@ -516,6 +569,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
@@ -524,6 +634,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
@@ -685,8 +797,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)
@@ -728,6 +846,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.
@@ -1086,6 +1205,579 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
# define LVDS_B0B3_POWER_DOWN (0 << 2)
# define LVDS_B0B3_POWER_UP (3 << 2)
+#define TV_CTL 0x68000
+/** Enables the TV encoder */
+# define TV_ENC_ENABLE (1 << 31)
+/** Sources the TV encoder input from pipe B instead of A. */
+# define TV_ENC_PIPEB_SELECT (1 << 30)
+/** Outputs composite video (DAC A only) */
+# define TV_ENC_OUTPUT_COMPOSITE (0 << 28)
+/** Outputs SVideo video (DAC B/C) */
+# define TV_ENC_OUTPUT_SVIDEO (1 << 28)
+/** Outputs Component video (DAC A/B/C) */
+# define TV_ENC_OUTPUT_COMPONENT (2 << 28)
+/** Outputs Composite and SVideo (DAC A/B/C) */
+# define TV_ENC_OUTPUT_SVIDEO_COMPOSITE (3 << 28)
+# define TV_TRILEVEL_SYNC (1 << 21)
+/** Enables slow sync generation (945GM only) */
+# define TV_SLOW_SYNC (1 << 20)
+/** Selects 4x oversampling for 480i and 576p */
+# define TV_OVERSAMPLE_4X (0 << 18)
+/** Selects 2x oversampling for 720p and 1080i */
+# define TV_OVERSAMPLE_2X (1 << 18)
+/** Selects no oversampling for 1080p */
+# define TV_OVERSAMPLE_NONE (2 << 18)
+/** Selects 8x oversampling */
+# define TV_OVERSAMPLE_8X (3 << 18)
+/** Selects progressive mode rather than interlaced */
+# define TV_PROGRESSIVE (1 << 17)
+/** Sets the colorburst to PAL mode. Required for non-M PAL modes. */
+# define TV_PAL_BURST (1 << 16)
+/** Field for setting delay of Y compared to C */
+# define TV_YC_SKEW_MASK (7 << 12)
+/** Enables a fix for 480p/576p standard definition modes on the 915GM only */
+# define TV_ENC_SDP_FIX (1 << 11)
+/**
+ * Enables a fix for the 915GM only.
+ *
+ * Not sure what it does.
+ */
+# define TV_ENC_C0_FIX (1 << 10)
+/** Bits that must be preserved by software */
+# define TV_CTL_SAVE ((3 << 8) | (3 << 6))
+# define TV_FUSE_STATE_MASK (3 << 4)
+/** Read-only state that reports all features enabled */
+# define TV_FUSE_STATE_ENABLED (0 << 4)
+/** Read-only state that reports that Macrovision is disabled in hardware*/
+# define TV_FUSE_STATE_NO_MACROVISION (1 << 4)
+/** Read-only state that reports that TV-out is disabled in hardware. */
+# define TV_FUSE_STATE_DISABLED (2 << 4)
+/** Normal operation */
+# define TV_TEST_MODE_NORMAL (0 << 0)
+/** Encoder test pattern 1 - combo pattern */
+# define TV_TEST_MODE_PATTERN_1 (1 << 0)
+/** Encoder test pattern 2 - full screen vertical 75% color bars */
+# define TV_TEST_MODE_PATTERN_2 (2 << 0)
+/** Encoder test pattern 3 - full screen horizontal 75% color bars */
+# define TV_TEST_MODE_PATTERN_3 (3 << 0)
+/** Encoder test pattern 4 - random noise */
+# define TV_TEST_MODE_PATTERN_4 (4 << 0)
+/** Encoder test pattern 5 - linear color ramps */
+# define TV_TEST_MODE_PATTERN_5 (5 << 0)
+/**
+ * This test mode forces the DACs to 50% of full output.
+ *
+ * This is used for load detection in combination with TVDAC_SENSE_MASK
+ */
+# define TV_TEST_MODE_MONITOR_DETECT (7 << 0)
+# define TV_TEST_MODE_MASK (7 << 0)
+/** @} */
+
+/** @defgroup TV_DAC
+ * @{
+ */
+#define TV_DAC 0x68004
+/**
+ * Reports that DAC state change logic has reported change (RO).
+ *
+ * This gets cleared when TV_DAC_STATE_EN is cleared
+*/
+# define TVDAC_STATE_CHG (1 << 31)
+# define TVDAC_SENSE_MASK (7 << 28)
+/** Reports that DAC A voltage is above the detect threshold */
+# define TVDAC_A_SENSE (1 << 30)
+/** Reports that DAC B voltage is above the detect threshold */
+# define TVDAC_B_SENSE (1 << 29)
+/** Reports that DAC C voltage is above the detect threshold */
+# define TVDAC_C_SENSE (1 << 28)
+/**
+ * Enables DAC state detection logic, for load-based TV detection.
+ *
+ * The PLL of the chosen pipe (in TV_CTL) must be running, and the encoder set
+ * to off, for load detection to work.
+ */
+# define TVDAC_STATE_CHG_EN (1 << 27)
+/** Sets the DAC A sense value to high */
+# define TVDAC_A_SENSE_CTL (1 << 26)
+/** Sets the DAC B sense value to high */
+# define TVDAC_B_SENSE_CTL (1 << 25)
+/** Sets the DAC C sense value to high */
+# define TVDAC_C_SENSE_CTL (1 << 24)
+/** Overrides the ENC_ENABLE and DAC voltage levels */
+# define DAC_CTL_OVERRIDE (1 << 7)
+/** Sets the slew rate. Must be preserved in software */
+# define ENC_TVDAC_SLEW_FAST (1 << 6)
+# define DAC_A_1_3_V (0 << 4)
+# define DAC_A_1_1_V (1 << 4)
+# define DAC_A_0_7_V (2 << 4)
+# define DAC_A_OFF (3 << 4)
+# define DAC_B_1_3_V (0 << 2)
+# define DAC_B_1_1_V (1 << 2)
+# define DAC_B_0_7_V (2 << 2)
+# define DAC_B_OFF (3 << 2)
+# define DAC_C_1_3_V (0 << 0)
+# define DAC_C_1_1_V (1 << 0)
+# define DAC_C_0_7_V (2 << 0)
+# define DAC_C_OFF (3 << 0)
+/** @} */
+
+/**
+ * CSC coefficients are stored in a floating point format with 9 bits of
+ * mantissa and 2 or 3 bits of exponent. The exponent is represented as 2**-n,
+ * where 2-bit exponents are unsigned n, and 3-bit exponents are signed n with
+ * -1 (0x3) being the only legal negative value.
+ */
+#define TV_CSC_Y 0x68010
+# define TV_RY_MASK 0x07ff0000
+# define TV_RY_SHIFT 16
+# define TV_GY_MASK 0x00000fff
+# define TV_GY_SHIFT 0
+
+#define TV_CSC_Y2 0x68014
+# define TV_BY_MASK 0x07ff0000
+# define TV_BY_SHIFT 16
+/**
+ * Y attenuation for component video.
+ *
+ * Stored in 1.9 fixed point.
+ */
+# define TV_AY_MASK 0x000003ff
+# define TV_AY_SHIFT 0
+
+#define TV_CSC_U 0x68018
+# define TV_RU_MASK 0x07ff0000
+# define TV_RU_SHIFT 16
+# define TV_GU_MASK 0x000007ff
+# define TV_GU_SHIFT 0
+
+#define TV_CSC_U2 0x6801c
+# define TV_BU_MASK 0x07ff0000
+# define TV_BU_SHIFT 16
+/**
+ * U attenuation for component video.
+ *
+ * Stored in 1.9 fixed point.
+ */
+# define TV_AU_MASK 0x000003ff
+# define TV_AU_SHIFT 0
+
+#define TV_CSC_V 0x68020
+# define TV_RV_MASK 0x0fff0000
+# define TV_RV_SHIFT 16
+# define TV_GV_MASK 0x000007ff
+# define TV_GV_SHIFT 0
+
+#define TV_CSC_V2 0x68024
+# define TV_BV_MASK 0x07ff0000
+# define TV_BV_SHIFT 16
+/**
+ * V attenuation for component video.
+ *
+ * Stored in 1.9 fixed point.
+ */
+# define TV_AV_MASK 0x000007ff
+# define TV_AV_SHIFT 0
+
+/** @defgroup TV_CSC_KNOBS
+ * @{
+ */
+#define TV_CLR_KNOBS 0x68028
+/** 2s-complement brightness adjustment */
+# define TV_BRIGHTNESS_MASK 0xff000000
+# define TV_BRIGHTNESS_SHIFT 24
+/** Contrast adjustment, as a 2.6 unsigned floating point number */
+# define TV_CONTRAST_MASK 0x00ff0000
+# define TV_CONTRAST_SHIFT 16
+/** Saturation adjustment, as a 2.6 unsigned floating point number */
+# define TV_SATURATION_MASK 0x0000ff00
+# define TV_SATURATION_SHIFT 8
+/** Hue adjustment, as an integer phase angle in degrees */
+# define TV_HUE_MASK 0x000000ff
+# define TV_HUE_SHIFT 0
+/** @} */
+
+/** @defgroup TV_CLR_LEVEL
+ * @{
+ */
+#define TV_CLR_LEVEL 0x6802c
+/** Controls the DAC level for black */
+# define TV_BLACK_LEVEL_MASK 0x01ff0000
+# define TV_BLACK_LEVEL_SHIFT 16
+/** Controls the DAC level for blanking */
+# define TV_BLANK_LEVEL_MASK 0x000001ff
+# define TV_BLANK_LEVEL_SHIFT 0
+/* @} */
+
+/** @defgroup TV_H_CTL_1
+ * @{
+ */
+#define TV_H_CTL_1 0x68030
+/** Number of pixels in the hsync. */
+# define TV_HSYNC_END_MASK 0x1fff0000
+# define TV_HSYNC_END_SHIFT 16
+/** Total number of pixels minus one in the line (display and blanking). */
+# define TV_HTOTAL_MASK 0x00001fff
+# define TV_HTOTAL_SHIFT 0
+/** @} */
+
+/** @defgroup TV_H_CTL_2
+ * @{
+ */
+#define TV_H_CTL_2 0x68034
+/** Enables the colorburst (needed for non-component color) */
+# define TV_BURST_ENA (1 << 31)
+/** Offset of the colorburst from the start of hsync, in pixels minus one. */
+# define TV_HBURST_START_SHIFT 16
+# define TV_HBURST_START_MASK 0x1fff0000
+/** Length of the colorburst */
+# define TV_HBURST_LEN_SHIFT 0
+# define TV_HBURST_LEN_MASK 0x0001fff
+/** @} */
+
+/** @defgroup TV_H_CTL_3
+ * @{
+ */
+#define TV_H_CTL_3 0x68038
+/** End of hblank, measured in pixels minus one from start of hsync */
+# define TV_HBLANK_END_SHIFT 16
+# define TV_HBLANK_END_MASK 0x1fff0000
+/** Start of hblank, measured in pixels minus one from start of hsync */
+# define TV_HBLANK_START_SHIFT 0
+# define TV_HBLANK_START_MASK 0x0001fff
+/** @} */
+
+/** @defgroup TV_V_CTL_1
+ * @{
+ */
+#define TV_V_CTL_1 0x6803c
+/** XXX */
+# define TV_NBR_END_SHIFT 16
+# define TV_NBR_END_MASK 0x07ff0000
+/** XXX */
+# define TV_VI_END_F1_SHIFT 8
+# define TV_VI_END_F1_MASK 0x00003f00
+/** XXX */
+# define TV_VI_END_F2_SHIFT 0
+# define TV_VI_END_F2_MASK 0x0000003f
+/** @} */
+
+/** @defgroup TV_V_CTL_2
+ * @{
+ */
+#define TV_V_CTL_2 0x68040
+/** Length of vsync, in half lines */
+# define TV_VSYNC_LEN_MASK 0x07ff0000
+# define TV_VSYNC_LEN_SHIFT 16
+/** Offset of the start of vsync in field 1, measured in one less than the
+ * number of half lines.
+ */
+# define TV_VSYNC_START_F1_MASK 0x00007f00
+# define TV_VSYNC_START_F1_SHIFT 8
+/**
+ * Offset of the start of vsync in field 2, measured in one less than the
+ * number of half lines.
+ */
+# define TV_VSYNC_START_F2_MASK 0x0000007f
+# define TV_VSYNC_START_F2_SHIFT 0
+/** @} */
+
+/** @defgroup TV_V_CTL_3
+ * @{
+ */
+#define TV_V_CTL_3 0x68044
+/** Enables generation of the equalization signal */
+# define TV_EQUAL_ENA (1 << 31)
+/** Length of vsync, in half lines */
+# define TV_VEQ_LEN_MASK 0x007f0000
+# define TV_VEQ_LEN_SHIFT 16
+/** Offset of the start of equalization in field 1, measured in one less than
+ * the number of half lines.
+ */
+# define TV_VEQ_START_F1_MASK 0x0007f00
+# define TV_VEQ_START_F1_SHIFT 8
+/**
+ * Offset of the start of equalization in field 2, measured in one less than
+ * the number of half lines.
+ */
+# define TV_VEQ_START_F2_MASK 0x000007f
+# define TV_VEQ_START_F2_SHIFT 0
+/** @} */
+
+/** @defgroup TV_V_CTL_4
+ * @{
+ */
+#define TV_V_CTL_4 0x68048
+/**
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F1_MASK 0x003f0000
+# define TV_VBURST_START_F1_SHIFT 16
+/**
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F1_MASK 0x000000ff
+# define TV_VBURST_END_F1_SHIFT 0
+/** @} */
+
+/** @defgroup TV_V_CTL_5
+ * @{
+ */
+#define TV_V_CTL_5 0x6804c
+/**
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F2_MASK 0x003f0000
+# define TV_VBURST_START_F2_SHIFT 16
+/**
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F2_MASK 0x000000ff
+# define TV_VBURST_END_F2_SHIFT 0
+/** @} */
+
+/** @defgroup TV_V_CTL_6
+ * @{
+ */
+#define TV_V_CTL_6 0x68050
+/**
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F3_MASK 0x003f0000
+# define TV_VBURST_START_F3_SHIFT 16
+/**
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F3_MASK 0x000000ff
+# define TV_VBURST_END_F3_SHIFT 0
+/** @} */
+
+/** @defgroup TV_V_CTL_7
+ * @{
+ */
+#define TV_V_CTL_7 0x68054
+/**
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F4_MASK 0x003f0000
+# define TV_VBURST_START_F4_SHIFT 16
+/**
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F4_MASK 0x000000ff
+# define TV_VBURST_END_F4_SHIFT 0
+/** @} */
+
+/** @defgroup TV_SC_CTL_1
+ * @{
+ */
+#define TV_SC_CTL_1 0x68060
+/** Turns on the first subcarrier phase generation DDA */
+# define TV_SC_DDA1_EN (1 << 31)
+/** Turns on the first subcarrier phase generation DDA */
+# define TV_SC_DDA2_EN (1 << 30)
+/** Turns on the first subcarrier phase generation DDA */
+# define TV_SC_DDA3_EN (1 << 29)
+/** Sets the subcarrier DDA to reset frequency every other field */
+# define TV_SC_RESET_EVERY_2 (0 << 24)
+/** Sets the subcarrier DDA to reset frequency every fourth field */
+# define TV_SC_RESET_EVERY_4 (1 << 24)
+/** Sets the subcarrier DDA to reset frequency every eighth field */
+# define TV_SC_RESET_EVERY_8 (2 << 24)
+/** Sets the subcarrier DDA to never reset the frequency */
+# define TV_SC_RESET_NEVER (3 << 24)
+/** Sets the peak amplitude of the colorburst.*/
+# define TV_BURST_LEVEL_MASK 0x00ff0000
+# define TV_BURST_LEVEL_SHIFT 16
+/** Sets the increment of the first subcarrier phase generation DDA */
+# define TV_SCDDA1_INC_MASK 0x00000fff
+# define TV_SCDDA1_INC_SHIFT 0
+/** @} */
+
+/** @defgroup TV_SC_CTL_2
+ * @{
+ */
+#define TV_SC_CTL_2 0x68064
+/** Sets the rollover for the second subcarrier phase generation DDA */
+# define TV_SCDDA2_SIZE_MASK 0x7fff0000
+# define TV_SCDDA2_SIZE_SHIFT 16
+/** Sets the increent of the second subcarrier phase generation DDA */
+# define TV_SCDDA2_INC_MASK 0x00007fff
+# define TV_SCDDA2_INC_SHIFT 0
+/** @} */
+
+/** @defgroup TV_SC_CTL_3
+ * @{
+ */
+#define TV_SC_CTL_3 0x68068
+/** Sets the rollover for the third subcarrier phase generation DDA */
+# define TV_SCDDA3_SIZE_MASK 0x7fff0000
+# define TV_SCDDA3_SIZE_SHIFT 16
+/** Sets the increent of the third subcarrier phase generation DDA */
+# define TV_SCDDA3_INC_MASK 0x00007fff
+# define TV_SCDDA3_INC_SHIFT 0
+/** @} */
+
+/** @defgroup TV_WIN_POS
+ * @{
+ */
+#define TV_WIN_POS 0x68070
+/** X coordinate of the display from the start of horizontal active */
+# define TV_XPOS_MASK 0x1fff0000
+# define TV_XPOS_SHIFT 16
+/** Y coordinate of the display from the start of vertical active (NBR) */
+# define TV_YPOS_MASK 0x00000fff
+# define TV_YPOS_SHIFT 0
+/** @} */
+
+/** @defgroup TV_WIN_SIZE
+ * @{
+ */
+#define TV_WIN_SIZE 0x68074
+/** Horizontal size of the display window, measured in pixels*/
+# define TV_XSIZE_MASK 0x1fff0000
+# define TV_XSIZE_SHIFT 16
+/**
+ * Vertical size of the display window, measured in pixels.
+ *
+ * Must be even for interlaced modes.
+ */
+# define TV_YSIZE_MASK 0x00000fff
+# define TV_YSIZE_SHIFT 0
+/** @} */
+
+/** @defgroup TV_FILTER_CTL_1
+ * @{
+ */
+#define TV_FILTER_CTL_1 0x68080
+/**
+ * Enables automatic scaling calculation.
+ *
+ * If set, the rest of the registers are ignored, and the calculated values can
+ * be read back from the register.
+ */
+# define TV_AUTO_SCALE (1 << 31)
+/**
+ * Disables the vertical filter.
+ *
+ * This is required on modes more than 1024 pixels wide */
+# define TV_V_FILTER_BYPASS (1 << 29)
+/** Enables adaptive vertical filtering */
+# define TV_VADAPT (1 << 28)
+# define TV_VADAPT_MODE_MASK (3 << 26)
+/** Selects the least adaptive vertical filtering mode */
+# define TV_VADAPT_MODE_LEAST (0 << 26)
+/** Selects the moderately adaptive vertical filtering mode */
+# define TV_VADAPT_MODE_MODERATE (1 << 26)
+/** Selects the most adaptive vertical filtering mode */
+# define TV_VADAPT_MODE_MOST (3 << 26)
+/**
+ * Sets the horizontal scaling factor.
+ *
+ * This should be the fractional part of the horizontal scaling factor divided
+ * by the oversampling rate. TV_HSCALE should be less than 1, and set to:
+ *
+ * (src width - 1) / ((oversample * dest width) - 1)
+ */
+# define TV_HSCALE_FRAC_MASK 0x00003fff
+# define TV_HSCALE_FRAC_SHIFT 0
+/** @} */
+
+/** @defgroup TV_FILTER_CTL_2
+ * @{
+ */
+#define TV_FILTER_CTL_2 0x68084
+/**
+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * TV_VSCALE should be (src height - 1) / ((interlace * dest height) - 1)
+ */
+# define TV_VSCALE_INT_MASK 0x00038000
+# define TV_VSCALE_INT_SHIFT 15
+/**
+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * \sa TV_VSCALE_INT_MASK
+ */
+# define TV_VSCALE_FRAC_MASK 0x00007fff
+# define TV_VSCALE_FRAC_SHIFT 0
+/** @} */
+
+/** @defgroup TV_FILTER_CTL_3
+ * @{
+ */
+#define TV_FILTER_CTL_3 0x68088
+/**
+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * TV_VSCALE should be (src height - 1) / (1/4 * (dest height - 1))
+ *
+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
+ */
+# define TV_VSCALE_IP_INT_MASK 0x00038000
+# define TV_VSCALE_IP_INT_SHIFT 15
+/**
+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
+ *
+ * \sa TV_VSCALE_IP_INT_MASK
+ */
+# define TV_VSCALE_IP_FRAC_MASK 0x00007fff
+# define TV_VSCALE_IP_FRAC_SHIFT 0
+/** @} */
+
+/** @defgroup TV_CC_CONTROL
+ * @{
+ */
+#define TV_CC_CONTROL 0x68090
+# define TV_CC_ENABLE (1 << 31)
+/**
+ * Specifies which field to send the CC data in.
+ *
+ * CC data is usually sent in field 0.
+ */
+# define TV_CC_FID_MASK (1 << 27)
+# define TV_CC_FID_SHIFT 27
+/** Sets the horizontal position of the CC data. Usually 135. */
+# define TV_CC_HOFF_MASK 0x03ff0000
+# define TV_CC_HOFF_SHIFT 16
+/** Sets the vertical position of the CC data. Usually 21 */
+# define TV_CC_LINE_MASK 0x0000003f
+# define TV_CC_LINE_SHIFT 0
+/** @} */
+
+/** @defgroup TV_CC_DATA
+ * @{
+ */
+#define TV_CC_DATA 0x68094
+# define TV_CC_RDY (1 << 31)
+/** Second word of CC data to be transmitted. */
+# define TV_CC_DATA_2_MASK 0x007f0000
+# define TV_CC_DATA_2_SHIFT 16
+/** First word of CC data to be transmitted. */
+# define TV_CC_DATA_1_MASK 0x0000007f
+# define TV_CC_DATA_1_SHIFT 0
+/** @}
+ */
+
+/** @{ */
+#define TV_H_LUMA_0 0x68100
+#define TV_H_LUMA_59 0x681ec
+#define TV_H_CHROMA_0 0x68200
+#define TV_H_CHROMA_59 0x682ec
+#define TV_V_LUMA_0 0x68300
+#define TV_V_LUMA_42 0x683a8
+#define TV_V_CHROMA_0 0x68400
+#define TV_V_CHROMA_42 0x684a8
+
#define PIPEACONF 0x70008
#define PIPEACONF_ENABLE (1<<31)
#define PIPEACONF_DISABLE 0
@@ -1177,13 +1869,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.
@@ -1200,6 +1896,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..b2d3f0d0
--- /dev/null
+++ b/shared-core/i915_init.c
@@ -0,0 +1,365 @@
+/*
+ * 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;
+ 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)) {
+ pci_read_config_dword(dev->pdev, 0x5C, &dev_priv->stolen_base);
+ DRM_DEBUG("stolen base %p\n", (void*)dev_priv->stolen_base);
+ }
+
+ 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;
+ }
+
+ /*
+ * 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, 1);
+ drm_bo_init_mm(dev, DRM_BO_MEM_TT, prealloc_size >> PAGE_SHIFT, (agp_size - prealloc_size) >> PAGE_SHIFT, 1);
+
+ 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, 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);
+
+ //
+
+ 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");
+
+ dev_priv->wq = create_singlethread_workqueue("i915");
+ if (dev_priv == 0) {
+ DRM_DEBUG("Error\n");
+ }
+
+
+ intel_modeset_init(dev);
+ drm_initial_config(dev, false);
+
+ drm_mm_print(&dev->bm.man[DRM_BO_MEM_VRAM].manager, "VRAM");
+ drm_mm_print(&dev->bm.man[DRM_BO_MEM_TT].manager, "TT");
+
+ drm_irq_install(dev);
+
+ return 0;
+}
+
+int i915_driver_unload(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ I915_WRITE(LP_RING + RING_LEN, 0);
+
+ intel_modeset_cleanup(dev);
+
+#if 0
+ if (dev_priv->ring.virtual_start) {
+ drm_core_ioremapfree(&dev_priv->ring.map, dev);
+ }
+#endif
+ if (dev_priv->sarea_kmap.virtual) {
+ drm_bo_kunmap(&dev_priv->sarea_kmap);
+ dev_priv->sarea_kmap.virtual = NULL;
+ dev->primary->master->lock.hw_lock = NULL;
+ dev->sigdata.lock = NULL;
+ }
+
+ if (dev_priv->sarea_bo) {
+ mutex_lock(&dev->struct_mutex);
+ drm_bo_usage_deref_locked(&dev_priv->sarea_bo);
+ mutex_unlock(&dev->struct_mutex);
+ dev_priv->sarea_bo = NULL;
+ }
+
+ 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);
+ }
+
+ 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, 1)) {
+ DRM_ERROR("Memory manager type 3 not clean. "
+ "Delaying takedown\n");
+ }
+ if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM, 1)) {
+ DRM_ERROR("Memory manager type 3 not clean. "
+ "Delaying takedown\n");
+ }
+ mutex_unlock(&dev->struct_mutex);
+
+ drm_bo_driver_finish(dev);
+
+ DRM_DEBUG("%p\n", dev_priv->mmio_map);
+ drm_rmmap(dev, dev_priv->mmio_map);
+
+ drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
+
+ dev->dev_private = NULL;
+ return 0;
+}
+
+int i915_master_create(struct drm_device *dev, struct drm_master *master)
+{
+ struct drm_i915_master_private *master_priv;
+ unsigned long sareapage;
+ int ret;
+
+ master_priv = drm_calloc(1, sizeof(*master_priv), DRM_MEM_DRIVER);
+ if (!master_priv)
+ return -ENOMEM;
+
+ /* prebuild the SAREA */
+ sareapage = max(SAREA_MAX, PAGE_SIZE);
+ ret = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK|_DRM_DRIVER,
+ &master_priv->sarea);
+ if (ret) {
+ DRM_ERROR("SAREA setup failed\n");
+ return ret;
+ }
+ master_priv->sarea_priv = master_priv->sarea->handle + sizeof(struct drm_sarea);
+ master_priv->sarea_priv->pf_current_page = 0;
+
+ master->driver_priv = master_priv;
+ return 0;
+}
+
+void i915_master_destroy(struct drm_device *dev, struct drm_master *master)
+{
+ struct drm_i915_master_private *master_priv = master->driver_priv;
+
+ if (!master_priv)
+ return;
+
+ drm_rmmap(dev, master_priv->sarea);
+ drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER);
+
+ master->driver_priv = NULL;
+}
diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c
index fd08b6e8..dad6ef86 100644
--- a/shared-core/i915_irq.c
+++ b/shared-core/i915_irq.c
@@ -31,9 +31,12 @@
#include "i915_drm.h"
#include "i915_drv.h"
+#include "intel_drv.h"
+
#define USER_INT_FLAG (1<<1)
#define VSYNC_PIPEB_FLAG (1<<5)
#define VSYNC_PIPEA_FLAG (1<<7)
+#define HOTPLUG_FLAG (1 << 17)
#define MAX_NOPID ((u32)~0)
@@ -49,7 +52,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);
@@ -86,7 +89,7 @@ i915_get_plane(struct drm_device *dev, int pipe)
static int
i915_pipe_enabled(struct drm_device *dev, int pipe)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF;
if (I915_READ(pipeconf) & PIPEACONF_ENABLE)
@@ -104,8 +107,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_master_private *master_priv = dev->primary->master->driver_priv;
+ struct drm_i915_sarea *sarea_priv = master_priv->sarea_priv;
u16 x1, y1, x2, y2;
int pf_planes = 1 << plane;
@@ -149,19 +152,19 @@ 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 drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
struct list_head *list, *tmp, hits, *hit;
int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages;
unsigned counter[2];
struct drm_drawable_info *drw;
- drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ struct drm_i915_sarea *sarea_priv;
u32 cpp = dev_priv->cpp, offsets[3];
u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB)
: XY_SRC_COPY_BLT_CMD;
- u32 pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) |
- (cpp << 23) | (1 << 24);
+ u32 pitchropcpp;
RING_LOCALS;
counter[0] = drm_vblank_count(dev, 0);
@@ -182,13 +185,19 @@ 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))
continue;
+ master_priv = vbl_swap->minor->master->driver_priv;
+ sarea_priv = master_priv->sarea_priv;
+
+ pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) |
+ (cpp << 23) | (1 << 24);
+
list_del(list);
dev_priv->swaps_pending--;
drm_vblank_put(dev, pipe);
@@ -206,8 +215,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);
@@ -264,8 +273,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;
@@ -303,7 +312,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
top = upper[plane];
bottom = lower[plane];
- front = (dev_priv->sarea_priv->pf_current_page >>
+ front = (master_priv->sarea_priv->pf_current_page >>
(2 * plane)) & 0x3;
back = (front + 1) % num_pages;
@@ -333,8 +342,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);
@@ -344,7 +353,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
#if 0
static int i915_in_vblank(struct drm_device *dev, int pipe)
{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
unsigned long pipedsl, vblank, vtotal;
unsigned long vbl_start, vbl_end, cur_line;
@@ -365,7 +374,7 @@ static int i915_in_vblank(struct drm_device *dev, int pipe)
#endif
u32 i915_get_vblank_counter(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;
unsigned long high_frame;
unsigned long low_frame;
u32 high1, high2, low, count;
@@ -409,24 +418,196 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
return count;
}
+#define HOTPLUG_CMD_CRT 1
+#define HOTPLUG_CMD_CRT_DIS 2
+#define HOTPLUG_CMD_SDVOB 4
+#define HOTPLUG_CMD_SDVOC 8
+
+static struct drm_device *hotplug_dev;
+static int hotplug_cmd = 0;
+static spinlock_t hotplug_lock = SPIN_LOCK_UNLOCKED;
+
+static void i915_hotplug_crt(struct drm_device *dev, bool connected)
+{
+ struct drm_output *output;
+ struct intel_output *iout;
+
+ mutex_lock(&dev->mode_config.mutex);
+
+ /* find the crt output */
+ list_for_each_entry(output, &dev->mode_config.output_list, head) {
+ iout = output->driver_private;
+ if (iout->type == INTEL_OUTPUT_ANALOG)
+ break;
+ else
+ iout = 0;
+ }
+
+ if (iout == 0)
+ goto unlock;
+
+ drm_hotplug_stage_two(dev, output, connected);
+
+unlock:
+ mutex_unlock(&dev->mode_config.mutex);
+}
+
+static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB)
+{
+ struct drm_output *output = 0;
+ enum drm_output_status status;
+
+ mutex_lock(&dev->mode_config.mutex);
+
+ output = intel_sdvo_find(dev, sdvoB);
+
+ if (!output) {
+ DRM_ERROR("could not find sdvo%s output\n", sdvoB ? "B" : "C");
+ goto unlock;
+ }
+
+ status = output->funcs->detect(output);
+
+ if (status != output_status_connected)
+ drm_hotplug_stage_two(dev, output, false);
+ else
+ drm_hotplug_stage_two(dev, output, true);
+
+ /* wierd hw bug, sdvo stop sending interupts */
+ intel_sdvo_set_hotplug(output, 1);
+
+unlock:
+ mutex_unlock(&dev->mode_config.mutex);
+}
+/*
+ * This code is called in a more safe envirmoent to handle the hotplugs.
+ * Add code here for hotplug love to userspace.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void i915_hotplug_work_func(void *work)
+#else
+static void i915_hotplug_work_func(struct work_struct *work)
+#endif
+{
+ struct drm_device *dev = hotplug_dev;
+ int crt;
+ int crtDis;
+ int sdvoB;
+ int sdvoC;
+
+ spin_lock(&hotplug_lock);
+ crt = hotplug_cmd & HOTPLUG_CMD_CRT;
+ crtDis = hotplug_cmd & HOTPLUG_CMD_CRT_DIS;
+ sdvoB = hotplug_cmd & HOTPLUG_CMD_SDVOB;
+ sdvoC = hotplug_cmd & HOTPLUG_CMD_SDVOC;
+ hotplug_cmd = 0;
+ spin_unlock(&hotplug_lock);
+
+ if (crt)
+ i915_hotplug_crt(dev, true);
+ if (crtDis)
+ i915_hotplug_crt(dev, false);
+
+ if (sdvoB)
+ i915_hotplug_sdvo(dev, 1);
+
+ if (sdvoC)
+ i915_hotplug_sdvo(dev, 0);
+
+}
+
+static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+ static DECLARE_WORK(hotplug, i915_hotplug_work_func, NULL);
+#else
+ static DECLARE_WORK(hotplug, i915_hotplug_work_func);
+#endif
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ hotplug_dev = dev;
+
+ if (stat & CRT_HOTPLUG_INT_STATUS) {
+ DRM_DEBUG("CRT event\n");
+
+ if (stat & CRT_HOTPLUG_MONITOR_MASK) {
+ spin_lock(&hotplug_lock);
+ hotplug_cmd |= HOTPLUG_CMD_CRT;
+ spin_unlock(&hotplug_lock);
+ } else {
+ spin_lock(&hotplug_lock);
+ hotplug_cmd |= HOTPLUG_CMD_CRT_DIS;
+ spin_unlock(&hotplug_lock);
+ }
+ }
+
+ if (stat & SDVOB_HOTPLUG_INT_STATUS) {
+ DRM_DEBUG("sDVOB event\n");
+
+ spin_lock(&hotplug_lock);
+ hotplug_cmd |= HOTPLUG_CMD_SDVOB;
+ spin_unlock(&hotplug_lock);
+ }
+
+ if (stat & SDVOC_HOTPLUG_INT_STATUS) {
+ DRM_DEBUG("sDVOC event\n");
+
+ spin_lock(&hotplug_lock);
+ hotplug_cmd |= HOTPLUG_CMD_SDVOC;
+ spin_unlock(&hotplug_lock);
+ }
+
+ queue_work(dev_priv->wq, &hotplug);
+
+ return 0;
+}
+
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;
- u16 temp;
+ struct drm_i915_master_private *master_priv;
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+ u32 temp = 0;
+ u32 temp2;
u32 pipea_stats, pipeb_stats;
pipea_stats = I915_READ(I915REG_PIPEASTAT);
pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
- temp = I915_READ16(I915REG_INT_IDENTITY_R);
+ /* On i8xx hw the IIR and IER are 16bit on i9xx its 32bit */
+ if (IS_I9XX(dev))
+ temp = I915_READ(I915REG_INT_IDENTITY_R);
+ else
+ temp = I915_READ16(I915REG_INT_IDENTITY_R);
+
+ temp2 = temp;
+ temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG);
#if 0
+ /* ugly despamification of pipeb event irq */
+ if (temp & (0xFFFFFFF ^ ((1 << 5) | (1 << 7)))) {
+ DRM_DEBUG("IIR %08x\n", temp2);
+ DRM_DEBUG("MSK %08x\n", dev_priv->irq_enable_reg | USER_INT_FLAG);
+ DRM_DEBUG("M&I %08x\n", temp);
+ DRM_DEBUG("HOT %08x\n", I915_READ(PORT_HOTPLUG_STAT));
+ }
+#else
+#if 0
DRM_DEBUG("flag=%08x\n", temp);
#endif
+#endif
+
if (temp == 0)
return IRQ_NONE;
+ if (IS_I9XX(dev)) {
+ I915_WRITE(I915REG_INT_IDENTITY_R, temp);
+ (void) I915_READ(I915REG_INT_IDENTITY_R);
+ } else {
+ I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
+ (void) I915_READ16(I915REG_INT_IDENTITY_R);
+ }
+
/*
* Clear the PIPE(A|B)STAT regs before the IIR otherwise
* we may get extra interrupts.
@@ -437,6 +618,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
pipea_stats | I915_VBLANK_INTERRUPT_ENABLE |
I915_VBLANK_CLEAR);
}
+
if (temp & VSYNC_PIPEB_FLAG) {
drm_handle_vblank(dev, i915_get_plane(dev, 1));
I915_WRITE(I915REG_PIPEBSTAT,
@@ -447,12 +629,15 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
(void) I915_READ16(I915REG_INT_IDENTITY_R); /* Flush posted write */
+ DRM_READMEMORYBARRIER();
+
temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG | VSYNC_PIPEA_FLAG |
VSYNC_PIPEB_FLAG);
- if (dev_priv->sarea_priv)
- dev_priv->sarea_priv->last_dispatch =
- READ_BREADCRUMB(dev_priv);
+ if (dev->primary->master) {
+ master_priv = dev->primary->master->driver_priv;
+ master_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
+ }
if (temp & USER_INT_FLAG) {
DRM_WAKEUP(&dev_priv->irq_queue);
@@ -466,12 +651,23 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
drm_locked_tasklet(dev, i915_vblank_tasklet);
}
+ /* for now lest just ack it */
+ if (temp & (1 << 17)) {
+ DRM_DEBUG("Hotplug event received\n");
+
+ temp2 = I915_READ(PORT_HOTPLUG_STAT);
+
+ i915_run_hotplug_tasklet(dev, temp2);
+
+ I915_WRITE(PORT_HOTPLUG_STAT,temp2);
+ }
+
return IRQ_HANDLED;
}
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);
@@ -488,7 +684,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)){
@@ -498,8 +694,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)) {
@@ -512,7 +708,8 @@ 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;
+ struct drm_i915_master_private *master_priv;
int ret = 0;
DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
@@ -530,10 +727,12 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
}
+
+ if (dev->primary->master) {
+ master_priv = dev->primary->master->driver_priv;
+ master_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
+ }
- if (dev_priv->sarea_priv)
- dev_priv->sarea_priv->last_dispatch =
- READ_BREADCRUMB(dev_priv);
return ret;
}
@@ -542,8 +741,8 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
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);
@@ -568,8 +767,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("called with no initialization\n");
@@ -581,9 +780,9 @@ int i915_irq_wait(struct drm_device *dev, void *data,
int i915_enable_vblank(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;
int pipe = i915_get_pipe(dev, plane);
-
+
switch (pipe) {
case 0:
dev_priv->irq_enable_reg |= VSYNC_PIPEA_FLAG;
@@ -604,7 +803,7 @@ int i915_enable_vblank(struct drm_device *dev, int plane)
void i915_disable_vblank(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;
int pipe = i915_get_pipe(dev, plane);
switch (pipe) {
@@ -623,13 +822,48 @@ void i915_disable_vblank(struct drm_device *dev, int plane)
I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
}
-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;
+ struct drm_output *o;
+
dev_priv->irq_enable_reg |= USER_INT_FLAG;
- I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
+ if (IS_I9XX(dev) && dev->mode_config.num_output) {
+ dev_priv->irq_enable_reg |= HOTPLUG_FLAG;
+
+ /* Activate the CRT */
+ I915_WRITE(PORT_HOTPLUG_EN, CRT_HOTPLUG_INT_EN);
+
+ /* SDVOB */
+ o = intel_sdvo_find(dev, 1);
+ if (o && intel_sdvo_supports_hotplug(o)) {
+ intel_sdvo_set_hotplug(o, 1);
+ I915_WRITE(PORT_HOTPLUG_EN, SDVOB_HOTPLUG_INT_EN);
+ }
+
+ /* SDVOC */
+ o = intel_sdvo_find(dev, 0);
+ if (o && intel_sdvo_supports_hotplug(o)) {
+ intel_sdvo_set_hotplug(o, 1);
+ I915_WRITE(PORT_HOTPLUG_EN, SDVOC_HOTPLUG_INT_EN);
+ }
+
+ }
+
+ if (IS_I9XX(dev)) {
+ I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
+ } else {
+ I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
+ }
+
+ DRM_DEBUG("HEN %08x\n",I915_READ(PORT_HOTPLUG_EN));
+ DRM_DEBUG("HST %08x\n",I915_READ(PORT_HOTPLUG_STAT));
+ DRM_DEBUG("IER %08x\n",I915_READ(I915REG_INT_ENABLE_R));
+ DRM_DEBUG("SDB %08x\n",I915_READ(SDVOB));
+
+ I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
+
dev_priv->irq_enabled = 1;
}
@@ -638,8 +872,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("called with no initialization\n");
@@ -659,8 +893,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) {
@@ -684,9 +918,10 @@ 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_master_private *master_priv;
+ 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;
@@ -697,7 +932,12 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
return -EINVAL;
}
- if (!dev_priv->sarea_priv || dev_priv->sarea_priv->rotation) {
+ if (!dev->primary->master)
+ return -EINVAL;
+
+ master_priv = dev->primary->master->driver_priv;
+
+ if (master_priv->sarea_priv->rotation) {
DRM_DEBUG("Rotation not supported\n");
return -EINVAL;
}
@@ -780,7 +1020,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 &&
@@ -818,6 +1058,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
vbl_swap->plane = plane;
vbl_swap->sequence = swap->sequence;
vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP);
+ vbl_swap->minor = file_priv->minor;
if (vbl_swap->flip)
swap->sequence++;
@@ -836,16 +1077,22 @@ 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);
- I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
+ if (IS_I9XX(dev)) {
+ I915_WRITE(I915REG_INT_MASK_R, 0x0);
+ I915_WRITE(I915REG_INT_ENABLE_R, 0x0);
+ } else {
+ I915_WRITE16(I915REG_INT_MASK_R, 0x0);
+ I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
+ }
+
}
int 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;
int ret, num_pipes = 2;
DRM_SPININIT(&dev_priv->swaps_lock, "swap");
@@ -875,17 +1122,28 @@ int 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;
- u16 temp;
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+ u32 temp;
if (!dev_priv)
return;
dev_priv->irq_enabled = 0;
- I915_WRITE16(I915REG_HWSTAM, 0xffff);
- I915_WRITE16(I915REG_INT_MASK_R, 0xffff);
- I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
- temp = I915_READ16(I915REG_INT_IDENTITY_R);
- I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
+
+ if(IS_I9XX(dev)) {
+ I915_WRITE(I915REG_HWSTAM, 0xffffffff);
+ I915_WRITE(I915REG_INT_MASK_R, 0xffffffff);
+ I915_WRITE(I915REG_INT_ENABLE_R, 0x0);
+
+ temp = I915_READ(I915REG_INT_IDENTITY_R);
+ I915_WRITE(I915REG_INT_IDENTITY_R, temp);
+ } else {
+ I915_WRITE16(I915REG_HWSTAM, 0xffff);
+ I915_WRITE16(I915REG_INT_MASK_R, 0xffff);
+ I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
+
+ temp = I915_READ16(I915REG_INT_IDENTITY_R);
+ I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
+ }
}
diff --git a/shared-core/i915_mem.c b/shared-core/i915_mem.c
index 6126a60d..15d63dec 100644
--- a/shared-core/i915_mem.c
+++ b/shared-core/i915_mem.c
@@ -45,8 +45,9 @@
*/
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_master_private *master_priv = dev->primary->master->driver_priv;
+ struct drm_i915_sarea *sarea_priv = master_priv->sarea_priv;
struct drm_tex_region *list;
unsigned shift, nr;
unsigned start;
@@ -256,7 +257,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 +272,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 +310,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 +338,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 +362,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/nouveau_mem.c b/shared-core/nouveau_mem.c
index 3d376aed..80b2990d 100644
--- a/shared-core/nouveau_mem.c
+++ b/shared-core/nouveau_mem.c
@@ -376,7 +376,7 @@ nouveau_mem_init_ttm(struct drm_device *dev)
bar1_size = drm_get_resource_len(dev, 1) >> PAGE_SHIFT;
if (bar1_size < vram_size) {
if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0,
- bar1_size, vram_size - bar1_size))) {
+ bar1_size, vram_size - bar1_size, 1))) {
DRM_ERROR("Failed PRIV0 mm init: %d\n", ret);
return ret;
}
@@ -387,7 +387,7 @@ nouveau_mem_init_ttm(struct drm_device *dev)
#ifdef HACK_OLD_MM
vram_size /= 4;
#endif
- if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, vram_size))) {
+ if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, vram_size, 1))) {
DRM_ERROR("Failed VRAM mm init: %d\n", ret);
return ret;
}
@@ -407,7 +407,7 @@ nouveau_mem_init_ttm(struct drm_device *dev)
if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_TT, 0,
dev_priv->gart_info.aper_size >>
- PAGE_SHIFT))) {
+ PAGE_SHIFT, 1))) {
DRM_ERROR("Failed TT mm init: %d\n", ret);
return ret;
}
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
index ac46da38..f0eda664 100644
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -1518,6 +1518,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;
@@ -2433,6 +2455,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 1cf03415..0c503257 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
*/
@@ -291,8 +296,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;
@@ -355,6 +361,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);
@@ -374,6 +381,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 u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc);
@@ -407,6 +415,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 uint64_t radeon_evict_flags(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
@@ -1336,4 +1368,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 79e4e866..3f6ace88 100644
--- a/shared-core/radeon_irq.c
+++ b/shared-core/radeon_irq.c
@@ -128,9 +128,12 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
stat &= dev_priv->irq_enable_reg;
/* SW interrupt */
- if (stat & RADEON_SW_INT_TEST)
- DRM_WAKEUP(&dev_priv->swi_queue);
-
+ if (stat & RADEON_SW_INT_TEST) {
+ DRM_WAKEUP(&dev_priv->irq_queue);
+#ifdef RADEON_HAVE_FENCE
+ radeon_fence_handler(dev);
+#endif
+ }
/* VBLANK interrupt */
if (stat & RADEON_CRTC_VBLANK_STAT)
drm_handle_vblank(dev, 0);
@@ -140,14 +143,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);
@@ -164,13 +166,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;
}
@@ -258,8 +260,8 @@ int radeon_driver_irq_postinstall(struct drm_device * dev)
(drm_radeon_private_t *) dev->dev_private;
int ret;
- 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);
ret = drm_vblank_init(dev, 2);
if (ret)
diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h
new file mode 100644
index 00000000..903de97d
--- /dev/null
+++ b/shared-core/radeon_ms.h
@@ -0,0 +1,607 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Dave Airlie
+ * Copyright 2007 Alex Deucher
+ * All Rights Reserved.
+ *
+ * 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ */
+/*
+ * Authors:
+ * Jérôme Glisse <glisse@freedesktop.org>
+ */
+#ifndef __RADEON_MS_H__
+#define __RADEON_MS_H__
+
+#include "radeon_ms_drv.h"
+#include "radeon_ms_reg.h"
+#include "radeon_ms_drm.h"
+#include "radeon_ms_rom.h"
+#include "radeon_ms_properties.h"
+
+#define DRIVER_AUTHOR "Jerome Glisse, Dave Airlie, Gareth Hughes, "\
+ "Keith Whitwell, others."
+#define DRIVER_NAME "radeon_ms"
+#define DRIVER_DESC "radeon kernel modesetting"
+#define DRIVER_DATE "20071108"
+#define DRIVER_MAJOR 1
+#define DRIVER_MINOR 0
+#define DRIVER_PATCHLEVEL 0
+
+enum radeon_bus_type {
+ RADEON_PCI = 0x10000,
+ RADEON_AGP = 0x20000,
+ RADEON_PCIE = 0x30000,
+};
+
+enum radeon_family {
+ CHIP_R100,
+ CHIP_RV100,
+ CHIP_RS100,
+ CHIP_RV200,
+ CHIP_RS200,
+ CHIP_R200,
+ CHIP_RV250,
+ CHIP_RS300,
+ CHIP_RV280,
+ CHIP_R300,
+ CHIP_R350,
+ CHIP_R360,
+ CHIP_RV350,
+ CHIP_RV370,
+ CHIP_RV380,
+ CHIP_RS400,
+ CHIP_RV410,
+ CHIP_R420,
+ CHIP_R430,
+ CHIP_R480,
+ CHIP_LAST,
+};
+
+enum radeon_monitor_type {
+ MT_UNKNOWN = -1,
+ MT_NONE = 0,
+ MT_CRT = 1,
+ MT_LCD = 2,
+ MT_DFP = 3,
+ MT_CTV = 4,
+ MT_STV = 5
+};
+
+enum radeon_connector_type {
+ CONNECTOR_NONE,
+ CONNECTOR_PROPRIETARY,
+ CONNECTOR_VGA,
+ CONNECTOR_DVI_I,
+ CONNECTOR_DVI_D,
+ CONNECTOR_CTV,
+ CONNECTOR_STV,
+ CONNECTOR_UNSUPPORTED
+};
+
+enum radeon_output_type {
+ OUTPUT_NONE,
+ OUTPUT_DAC1,
+ OUTPUT_DAC2,
+ OUTPUT_TMDS,
+ OUTPUT_LVDS
+};
+
+struct radeon_state;
+
+struct radeon_ms_crtc {
+ int crtc;
+ uint16_t lut_r[256];
+ uint16_t lut_g[256];
+ uint16_t lut_b[256];
+};
+
+struct radeon_ms_i2c {
+ struct drm_device *drm_dev;
+ uint32_t reg;
+ struct i2c_adapter adapter;
+ struct i2c_algo_bit_data algo;
+};
+
+struct radeon_ms_connector {
+ struct radeon_ms_i2c *i2c;
+ struct edid *edid;
+ struct drm_output *output;
+ int type;
+ int monitor_type;
+ int crtc;
+ uint32_t i2c_reg;
+ char outputs[RADEON_MAX_OUTPUTS];
+ char name[32];
+};
+
+struct radeon_ms_output {
+ int type;
+ struct drm_device *dev;
+ struct radeon_ms_connector *connector;
+ int (*initialize)(struct radeon_ms_output *output);
+ enum drm_output_status (*detect)(struct radeon_ms_output *output);
+ void (*dpms)(struct radeon_ms_output *output, int mode);
+ int (*get_modes)(struct radeon_ms_output *output);
+ bool (*mode_fixup)(struct radeon_ms_output *output,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
+ int (*mode_set)(struct radeon_ms_output *output,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
+ void (*restore)(struct radeon_ms_output *output,
+ struct radeon_state *state);
+ void (*save)(struct radeon_ms_output *output,
+ struct radeon_state *state);
+};
+
+struct radeon_state {
+ /* memory */
+ uint32_t config_aper_0_base;
+ uint32_t config_aper_1_base;
+ uint32_t config_aper_size;
+ uint32_t mc_fb_location;
+ uint32_t display_base_addr;
+ /* irq */
+ uint32_t gen_int_cntl;
+ /* pci */
+ uint32_t aic_ctrl;
+ uint32_t aic_pt_base;
+ uint32_t aic_pt_base_lo;
+ uint32_t aic_pt_base_hi;
+ uint32_t aic_lo_addr;
+ uint32_t aic_hi_addr;
+ /* agp */
+ uint32_t agp_cntl;
+ uint32_t agp_command;
+ uint32_t agp_base;
+ uint32_t agp_base_2;
+ uint32_t bus_cntl;
+ uint32_t mc_agp_location;
+ /* cp */
+ uint32_t cp_rb_cntl;
+ uint32_t cp_rb_base;
+ uint32_t cp_rb_rptr_addr;
+ uint32_t cp_rb_wptr;
+ uint32_t cp_rb_wptr_delay;
+ uint32_t scratch_umsk;
+ uint32_t scratch_addr;
+ /* pcie */
+ uint32_t pcie_tx_gart_cntl;
+ uint32_t pcie_tx_gart_discard_rd_addr_lo;
+ uint32_t pcie_tx_gart_discard_rd_addr_hi;
+ uint32_t pcie_tx_gart_base;
+ uint32_t pcie_tx_gart_start_lo;
+ uint32_t pcie_tx_gart_start_hi;
+ uint32_t pcie_tx_gart_end_lo;
+ uint32_t pcie_tx_gart_end_hi;
+ /* surface */
+ uint32_t surface_cntl;
+ uint32_t surface0_info;
+ uint32_t surface0_lower_bound;
+ uint32_t surface0_upper_bound;
+ uint32_t surface1_info;
+ uint32_t surface1_lower_bound;
+ uint32_t surface1_upper_bound;
+ uint32_t surface2_info;
+ uint32_t surface2_lower_bound;
+ uint32_t surface2_upper_bound;
+ uint32_t surface3_info;
+ uint32_t surface3_lower_bound;
+ uint32_t surface3_upper_bound;
+ uint32_t surface4_info;
+ uint32_t surface4_lower_bound;
+ uint32_t surface4_upper_bound;
+ uint32_t surface5_info;
+ uint32_t surface5_lower_bound;
+ uint32_t surface5_upper_bound;
+ uint32_t surface6_info;
+ uint32_t surface6_lower_bound;
+ uint32_t surface6_upper_bound;
+ uint32_t surface7_info;
+ uint32_t surface7_lower_bound;
+ uint32_t surface7_upper_bound;
+ /* crtc */
+ uint32_t crtc_gen_cntl;
+ uint32_t crtc_ext_cntl;
+ uint32_t crtc_h_total_disp;
+ uint32_t crtc_h_sync_strt_wid;
+ uint32_t crtc_v_total_disp;
+ uint32_t crtc_v_sync_strt_wid;
+ uint32_t crtc_offset;
+ uint32_t crtc_offset_cntl;
+ uint32_t crtc_pitch;
+ uint32_t crtc_more_cntl;
+ uint32_t crtc_tile_x0_y0;
+ uint32_t fp_h_sync_strt_wid;
+ uint32_t fp_v_sync_strt_wid;
+ uint32_t fp_crtc_h_total_disp;
+ uint32_t fp_crtc_v_total_disp;
+ /* pll */
+ uint32_t clock_cntl_index;
+ uint32_t ppll_cntl;
+ uint32_t ppll_ref_div;
+ uint32_t ppll_div_0;
+ uint32_t ppll_div_1;
+ uint32_t ppll_div_2;
+ uint32_t ppll_div_3;
+ uint32_t vclk_ecp_cntl;
+ uint32_t htotal_cntl;
+ /* dac */
+ uint32_t dac_cntl;
+ uint32_t dac_cntl2;
+ uint32_t dac_ext_cntl;
+ uint32_t disp_misc_cntl;
+ uint32_t dac_macro_cntl;
+ uint32_t disp_pwr_man;
+ uint32_t disp_merge_cntl;
+ uint32_t disp_output_cntl;
+ uint32_t disp2_merge_cntl;
+ uint32_t dac_embedded_sync_cntl;
+ uint32_t dac_broad_pulse;
+ uint32_t dac_skew_clks;
+ uint32_t dac_incr;
+ uint32_t dac_neg_sync_level;
+ uint32_t dac_pos_sync_level;
+ uint32_t dac_blank_level;
+ uint32_t dac_sync_equalization;
+ uint32_t tv_dac_cntl;
+ uint32_t tv_master_cntl;
+};
+
+struct drm_radeon_private {
+ /* driver family specific functions */
+ int (*bus_finish)(struct drm_device *dev);
+ int (*bus_init)(struct drm_device *dev);
+ void (*bus_restore)(struct drm_device *dev, struct radeon_state *state);
+ void (*bus_save)(struct drm_device *dev, struct radeon_state *state);
+ struct drm_ttm_backend *(*create_ttm)(struct drm_device *dev);
+ void (*irq_emit)(struct drm_device *dev);
+ void (*flush_cache)(struct drm_device *dev);
+ /* bus informations */
+ void *bus;
+ uint32_t bus_type;
+ /* cp */
+ uint32_t ring_buffer_size;
+ uint32_t ring_rptr;
+ uint32_t ring_wptr;
+ uint32_t ring_mask;
+ int ring_free;
+ uint32_t ring_tail_mask;
+ uint32_t write_back_area_size;
+ struct drm_buffer_object *ring_buffer_object;
+ struct drm_bo_kmap_obj ring_buffer_map;
+ uint32_t *ring_buffer;
+ uint32_t *write_back_area;
+ const uint32_t *microcode;
+ /* card family */
+ uint32_t usec_timeout;
+ uint32_t family;
+ struct radeon_ms_output *outputs[RADEON_MAX_OUTPUTS];
+ struct radeon_ms_connector *connectors[RADEON_MAX_CONNECTORS];
+ /* drm map (MMIO, FB) */
+ struct drm_map mmio;
+ struct drm_map vram;
+ /* gpu address space */
+ uint32_t gpu_vram_size;
+ uint32_t gpu_vram_start;
+ uint32_t gpu_vram_end;
+ uint32_t gpu_gart_size;
+ uint32_t gpu_gart_start;
+ uint32_t gpu_gart_end;
+ /* state of the card when module was loaded */
+ struct radeon_state load_state;
+ /* state the driver wants */
+ struct radeon_state driver_state;
+ /* last emitted fence */
+ uint32_t fence_id_last;
+ uint32_t fence_reg;
+ /* when doing gpu stop we save here current state */
+ uint32_t crtc_ext_cntl;
+ uint32_t crtc_gen_cntl;
+ uint32_t crtc2_gen_cntl;
+ uint32_t ov0_scale_cntl;
+ /* bool & type on the hw */
+ uint8_t crtc1_dpms;
+ uint8_t crtc2_dpms;
+ uint8_t restore_state;
+ uint8_t cp_ready;
+ uint8_t bus_ready;
+ uint8_t write_back;
+ /* abstract asic specific structures */
+ struct radeon_ms_rom rom;
+ struct radeon_ms_properties properties;
+};
+
+
+/* radeon_ms_bo.c */
+int radeon_ms_bo_get_gpu_addr(struct drm_device *dev,
+ struct drm_bo_mem_reg *mem,
+ uint32_t *gpu_addr);
+int radeon_ms_bo_move(struct drm_buffer_object * bo, int evict,
+ int no_wait, struct drm_bo_mem_reg * new_mem);
+struct drm_ttm_backend *radeon_ms_create_ttm_backend(struct drm_device * dev);
+uint64_t radeon_ms_evict_flags(struct drm_buffer_object *bo);
+int radeon_ms_init_mem_type(struct drm_device * dev, uint32_t type,
+ struct drm_mem_type_manager * man);
+int radeon_ms_invalidate_caches(struct drm_device * dev, uint64_t flags);
+void radeon_ms_ttm_flush(struct drm_ttm *ttm);
+
+/* radeon_ms_bus.c */
+int radeon_ms_agp_finish(struct drm_device *dev);
+int radeon_ms_agp_init(struct drm_device *dev);
+void radeon_ms_agp_restore(struct drm_device *dev, struct radeon_state *state);
+void radeon_ms_agp_save(struct drm_device *dev, struct radeon_state *state);
+struct drm_ttm_backend *radeon_ms_pcie_create_ttm(struct drm_device *dev);
+int radeon_ms_pcie_finish(struct drm_device *dev);
+int radeon_ms_pcie_init(struct drm_device *dev);
+void radeon_ms_pcie_restore(struct drm_device *dev, struct radeon_state *state);
+void radeon_ms_pcie_save(struct drm_device *dev, struct radeon_state *state);
+
+/* radeon_ms_combios.c */
+int radeon_ms_combios_get_properties(struct drm_device *dev);
+int radeon_ms_connectors_from_combios(struct drm_device *dev);
+int radeon_ms_outputs_from_combios(struct drm_device *dev);
+
+/* radeon_ms_compat.c */
+long radeon_ms_compat_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg);
+
+/* radeon_ms_cp.c */
+int radeon_ms_cp_finish(struct drm_device *dev);
+int radeon_ms_cp_init(struct drm_device *dev);
+void radeon_ms_cp_restore(struct drm_device *dev, struct radeon_state *state);
+void radeon_ms_cp_save(struct drm_device *dev, struct radeon_state *state);
+void radeon_ms_cp_stop(struct drm_device *dev);
+int radeon_ms_cp_wait(struct drm_device *dev, int n);
+int radeon_ms_ring_emit(struct drm_device *dev, uint32_t *cmd, uint32_t count);
+
+/* radeon_ms_crtc.c */
+int radeon_ms_crtc_create(struct drm_device *dev, int crtc);
+void radeon_ms_crtc1_restore(struct drm_device *dev,
+ struct radeon_state *state);
+void radeon_ms_crtc1_save(struct drm_device *dev, struct radeon_state *state);
+
+/* radeon_ms_dac.c */
+int radeon_ms_dac1_initialize(struct radeon_ms_output *output);
+enum drm_output_status radeon_ms_dac1_detect(struct radeon_ms_output *output);
+void radeon_ms_dac1_dpms(struct radeon_ms_output *output, int mode);
+int radeon_ms_dac1_get_modes(struct radeon_ms_output *output);
+bool radeon_ms_dac1_mode_fixup(struct radeon_ms_output *output,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
+int radeon_ms_dac1_mode_set(struct radeon_ms_output *output,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
+void radeon_ms_dac1_restore(struct radeon_ms_output *output,
+ struct radeon_state *state);
+void radeon_ms_dac1_save(struct radeon_ms_output *output,
+ struct radeon_state *state);
+int radeon_ms_dac2_initialize(struct radeon_ms_output *output);
+enum drm_output_status radeon_ms_dac2_detect(struct radeon_ms_output *output);
+void radeon_ms_dac2_dpms(struct radeon_ms_output *output, int mode);
+int radeon_ms_dac2_get_modes(struct radeon_ms_output *output);
+bool radeon_ms_dac2_mode_fixup(struct radeon_ms_output *output,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
+int radeon_ms_dac2_mode_set(struct radeon_ms_output *output,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
+void radeon_ms_dac2_restore(struct radeon_ms_output *output,
+ struct radeon_state *state);
+void radeon_ms_dac2_save(struct radeon_ms_output *output,
+ struct radeon_state *state);
+
+/* radeon_ms_drm.c */
+int radeon_ms_driver_dma_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+void radeon_ms_driver_lastclose(struct drm_device * dev);
+int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags);
+int radeon_ms_driver_open(struct drm_device * dev, struct drm_file *file_priv);
+int radeon_ms_driver_unload(struct drm_device *dev);
+
+/* radeon_ms_exec.c */
+int radeon_ms_execbuffer(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+/* radeon_ms_family.c */
+int radeon_ms_family_init(struct drm_device *dev);
+
+/* radeon_ms_fence.c */
+int radeon_ms_fence_emit_sequence(struct drm_device *dev, uint32_t class,
+ uint32_t flags, uint32_t *sequence,
+ uint32_t *native_type);
+void radeon_ms_fence_handler(struct drm_device * dev);
+int radeon_ms_fence_has_irq(struct drm_device *dev, uint32_t class,
+ uint32_t flags);
+int radeon_ms_fence_types(struct drm_buffer_object *bo,
+ uint32_t * class, uint32_t * type);
+void radeon_ms_poke_flush(struct drm_device * dev, uint32_t class);
+
+/* radeon_ms_fb.c */
+int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc);
+int radeonfb_remove(struct drm_device *dev, struct drm_crtc *crtc);
+
+/* radeon_ms_gpu.c */
+int radeon_ms_gpu_initialize(struct drm_device *dev);
+void radeon_ms_gpu_dpms(struct drm_device *dev);
+void radeon_ms_gpu_flush(struct drm_device *dev);
+void radeon_ms_gpu_restore(struct drm_device *dev, struct radeon_state *state);
+void radeon_ms_gpu_save(struct drm_device *dev, struct radeon_state *state);
+int radeon_ms_wait_for_idle(struct drm_device *dev);
+
+/* radeon_ms_i2c.c */
+void radeon_ms_i2c_destroy(struct radeon_ms_i2c *i2c);
+struct radeon_ms_i2c *radeon_ms_i2c_create(struct drm_device *dev,
+ const uint32_t reg,
+ const char *name);
+
+/* radeon_ms_irq.c */
+void radeon_ms_irq_emit(struct drm_device *dev);
+irqreturn_t radeon_ms_irq_handler(DRM_IRQ_ARGS);
+void radeon_ms_irq_preinstall(struct drm_device * dev);
+int radeon_ms_irq_postinstall(struct drm_device * dev);
+int radeon_ms_irq_init(struct drm_device *dev);
+void radeon_ms_irq_restore(struct drm_device *dev, struct radeon_state *state);
+void radeon_ms_irq_save(struct drm_device *dev, struct radeon_state *state);
+void radeon_ms_irq_uninstall(struct drm_device * dev);
+
+/* radeon_ms_output.c */
+void radeon_ms_connectors_destroy(struct drm_device *dev);
+int radeon_ms_connectors_from_properties(struct drm_device *dev);
+int radeon_ms_connectors_from_rom(struct drm_device *dev);
+void radeon_ms_outputs_destroy(struct drm_device *dev);
+int radeon_ms_outputs_from_properties(struct drm_device *dev);
+int radeon_ms_outputs_from_rom(struct drm_device *dev);
+void radeon_ms_outputs_restore(struct drm_device *dev,
+ struct radeon_state *state);
+void radeon_ms_outputs_save(struct drm_device *dev, struct radeon_state *state);
+
+/* radeon_ms_properties.c */
+int radeon_ms_properties_init(struct drm_device *dev);
+
+/* radeon_ms_rom.c */
+int radeon_ms_rom_get_properties(struct drm_device *dev);
+int radeon_ms_rom_init(struct drm_device *dev);
+
+/* radeon_ms_state.c */
+void radeon_ms_state_save(struct drm_device *dev, struct radeon_state *state);
+void radeon_ms_state_restore(struct drm_device *dev,
+ struct radeon_state *state);
+
+
+/* packect stuff **************************************************************/
+#define RADEON_CP_PACKET0 0x00000000
+#define CP_PACKET0(reg, n) \
+ (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
+#define CP_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00
+# define GMC_SRC_PITCH_OFFSET_CNTL (1 << 0)
+# define GMC_DST_PITCH_OFFSET_CNTL (1 << 1)
+# define GMC_BRUSH_NONE (15 << 4)
+# define GMC_SRC_DATATYPE_COLOR (3 << 12)
+# define ROP3_S 0x00cc0000
+# define DP_SRC_SOURCE_MEMORY (2 << 24)
+# define GMC_CLR_CMP_CNTL_DIS (1 << 28)
+# define GMC_WR_MSK_DIS (1 << 30)
+
+/* helper macro & functions ***************************************************/
+#define REG_S(rn, bn, v) (((v) << rn##__##bn##__SHIFT) & rn##__##bn##__MASK)
+#define REG_G(rn, bn, v) (((v) & rn##__##bn##__MASK) >> rn##__##bn##__SHIFT)
+#define MMIO_R(rid) mmio_read(dev_priv, rid)
+#define MMIO_W(rid, v) mmio_write(dev_priv, rid, v)
+#define PCIE_R(rid) pcie_read(dev_priv, rid)
+#define PCIE_W(rid, v) pcie_write(dev_priv, rid, v)
+#define PPLL_R(rid) pll_read(dev_priv, rid)
+#define PPLL_W(rid, v) pll_write(dev_priv, rid, v)
+
+static __inline__ uint32_t mmio_read(struct drm_radeon_private *dev_priv,
+ uint32_t offset)
+{
+ return DRM_READ32(&dev_priv->mmio, offset);
+}
+
+
+static __inline__ void mmio_write(struct drm_radeon_private *dev_priv,
+ uint32_t offset, uint32_t v)
+{
+ DRM_WRITE32(&dev_priv->mmio, offset, v);
+}
+
+static __inline__ uint32_t pcie_read(struct drm_radeon_private *dev_priv,
+ uint32_t offset)
+{
+ MMIO_W(PCIE_INDEX, REG_S(PCIE_INDEX, PCIE_INDEX, offset));
+ return MMIO_R(PCIE_DATA);
+}
+
+static __inline__ void pcie_write(struct drm_radeon_private *dev_priv,
+ uint32_t offset, uint32_t v)
+{
+ MMIO_W(PCIE_INDEX, REG_S(PCIE_INDEX, PCIE_INDEX, offset));
+ MMIO_W(PCIE_DATA, v);
+}
+
+static __inline__ void pll_index_errata(struct drm_radeon_private *dev_priv)
+{
+ uint32_t tmp, save;
+
+ /* This workaround is necessary on rv200 and RS200 or PLL
+ * reads may return garbage (among others...)
+ */
+ if (dev_priv->properties.pll_dummy_reads) {
+ tmp = MMIO_R(CLOCK_CNTL_DATA);
+ tmp = MMIO_R(CRTC_GEN_CNTL);
+ }
+ /* This function is required to workaround a hardware bug in some (all?)
+ * revisions of the R300. This workaround should be called after every
+ * CLOCK_CNTL_INDEX register access. If not, register reads afterward
+ * may not be correct.
+ */
+ if (dev_priv->properties.pll_r300_errata) {
+ tmp = save = MMIO_R(CLOCK_CNTL_INDEX);
+ tmp = tmp & ~CLOCK_CNTL_INDEX__PLL_ADDR__MASK;
+ tmp = tmp & ~CLOCK_CNTL_INDEX__PLL_WR_EN;
+ MMIO_W(CLOCK_CNTL_INDEX, tmp);
+ tmp = MMIO_R(CLOCK_CNTL_DATA);
+ MMIO_W(CLOCK_CNTL_INDEX, save);
+ }
+}
+
+static __inline__ void pll_data_errata(struct drm_radeon_private *dev_priv)
+{
+ /* This workarounds is necessary on RV100, RS100 and RS200 chips
+ * or the chip could hang on a subsequent access
+ */
+ if (dev_priv->properties.pll_delay) {
+ /* we can't deal with posted writes here ... */
+ udelay(5000);
+ }
+}
+
+static __inline__ uint32_t pll_read(struct drm_radeon_private *dev_priv,
+ uint32_t offset)
+{
+ uint32_t clock_cntl_index = dev_priv->driver_state.clock_cntl_index;
+ uint32_t data;
+
+ clock_cntl_index &= ~CLOCK_CNTL_INDEX__PLL_ADDR__MASK;
+ clock_cntl_index |= REG_S(CLOCK_CNTL_INDEX, PLL_ADDR, offset);
+ MMIO_W(CLOCK_CNTL_INDEX, clock_cntl_index);
+ pll_index_errata(dev_priv);
+ data = MMIO_R(CLOCK_CNTL_DATA);
+ pll_data_errata(dev_priv);
+ return data;
+}
+
+static __inline__ void pll_write(struct drm_radeon_private *dev_priv,
+ uint32_t offset, uint32_t value)
+{
+ uint32_t clock_cntl_index = dev_priv->driver_state.clock_cntl_index;
+
+ clock_cntl_index &= ~CLOCK_CNTL_INDEX__PLL_ADDR__MASK;
+ clock_cntl_index |= REG_S(CLOCK_CNTL_INDEX, PLL_ADDR, offset);
+ clock_cntl_index |= CLOCK_CNTL_INDEX__PLL_WR_EN;
+ MMIO_W(CLOCK_CNTL_INDEX, clock_cntl_index);
+ pll_index_errata(dev_priv);
+ MMIO_W(CLOCK_CNTL_DATA, value);
+ pll_data_errata(dev_priv);
+}
+
+#endif
diff --git a/shared-core/radeon_ms_bo.c b/shared-core/radeon_ms_bo.c
new file mode 100644
index 00000000..6d9a97c1
--- /dev/null
+++ b/shared-core/radeon_ms_bo.c
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2007 Dave Airlie
+ * Copyright 2007 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+/*
+ * Authors:
+ * Dave Airlie <airlied@linux.ie>
+ * Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "drmP.h"
+#include "drm.h"
+
+#include "radeon_ms.h"
+
+void radeon_ms_bo_copy_blit(struct drm_device *dev,
+ uint32_t src_offset,
+ uint32_t dst_offset,
+ uint32_t pages)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t num_pages, stride, c;
+ uint32_t offset_inc = 0;
+ uint32_t cmd[7];
+
+ if (!dev_priv) {
+ return;
+ }
+
+ /* radeon limited to 16320=255*64 bytes per row so copy at
+ * most 2 pages */
+ num_pages = 2;
+ stride = ((num_pages * PAGE_SIZE) / 64) & 0xff;
+ while(pages > 0) {
+ if (num_pages > pages) {
+ num_pages = pages;
+ stride = ((num_pages * PAGE_SIZE) / 64) & 0xff;
+ }
+ c = pages / num_pages;
+ if (c >= 8192) {
+ c = 8191;
+ }
+ cmd[0] = CP_PACKET3_CNTL_BITBLT_MULTI | (5 << 16);
+ cmd[1] = GMC_SRC_PITCH_OFFSET_CNTL |
+ GMC_DST_PITCH_OFFSET_CNTL |
+ GMC_BRUSH_NONE |
+ (0x6 << 8) |
+ GMC_SRC_DATATYPE_COLOR |
+ ROP3_S |
+ DP_SRC_SOURCE_MEMORY |
+ GMC_CLR_CMP_CNTL_DIS |
+ GMC_WR_MSK_DIS;
+ cmd[2] = (stride << 22) | (src_offset >> 10);
+ cmd[3] = (stride << 22) | (dst_offset >> 10);
+ cmd[4] = (0 << 16) | 0;
+ cmd[5] = (0 << 16) | 0;
+ cmd[6] = ((stride * 16) << 16) | c;
+ radeon_ms_ring_emit(dev, cmd, 7);
+ offset_inc = num_pages * c * PAGE_SIZE;
+ src_offset += offset_inc;
+ dst_offset += offset_inc;
+ pages -= num_pages * c;
+ }
+ /* wait for 2d engine to go busy so wait_until stall */
+ for (c = 0; c < dev_priv->usec_timeout; c++) {
+ uint32_t status = MMIO_R(RBBM_STATUS);
+ if ((RBBM_STATUS__E2_BUSY & status) ||
+ (RBBM_STATUS__CBA2D_BUSY & status)) {
+ DRM_INFO("[radeon_ms] RBBM_STATUS 0x%08X\n", status);
+ break;
+ }
+ DRM_UDELAY(1);
+ }
+ /* Sync everything up */
+ cmd[0] = CP_PACKET0(WAIT_UNTIL, 0);
+ cmd[1] = WAIT_UNTIL__WAIT_2D_IDLECLEAN |
+ WAIT_UNTIL__WAIT_HOST_IDLECLEAN;
+ radeon_ms_ring_emit(dev, cmd, 2);
+ return;
+}
+
+static int radeon_ms_bo_move_blit(struct drm_buffer_object *bo,
+ int evict, int no_wait,
+ struct drm_bo_mem_reg *new_mem)
+{
+ struct drm_device *dev = bo->dev;
+ struct drm_bo_mem_reg *old_mem = &bo->mem;
+ uint32_t gpu_src_addr;
+ uint32_t gpu_dst_addr;
+ int ret;
+
+ ret = radeon_ms_bo_get_gpu_addr(dev, old_mem, &gpu_src_addr);
+ if (ret) {
+ return ret;
+ }
+ ret = radeon_ms_bo_get_gpu_addr(dev, new_mem, &gpu_dst_addr);
+ if (ret) {
+ return ret;
+ }
+
+ radeon_ms_bo_copy_blit(bo->dev,
+ gpu_src_addr,
+ gpu_dst_addr,
+ new_mem->num_pages);
+
+ ret = drm_bo_move_accel_cleanup(bo, evict, no_wait, 0,
+ DRM_FENCE_TYPE_EXE |
+ DRM_RADEON_FENCE_TYPE_RW,
+ DRM_RADEON_FENCE_FLAG_FLUSHED,
+ new_mem);
+ return ret;
+}
+
+static int radeon_ms_bo_move_flip(struct drm_buffer_object *bo,
+ int evict, int no_wait,
+ struct drm_bo_mem_reg *new_mem)
+{
+ struct drm_device *dev = bo->dev;
+ struct drm_bo_mem_reg tmp_mem;
+ int ret;
+
+ tmp_mem = *new_mem;
+ tmp_mem.mm_node = NULL;
+ tmp_mem.flags = DRM_BO_FLAG_MEM_TT |
+ DRM_BO_FLAG_CACHED |
+ DRM_BO_FLAG_FORCE_CACHING;
+ ret = drm_bo_mem_space(bo, &tmp_mem, no_wait);
+ if (ret) {
+ return ret;
+ }
+
+ ret = drm_ttm_bind(bo->ttm, &tmp_mem);
+ if (ret) {
+ goto out_cleanup;
+ }
+ ret = radeon_ms_bo_move_blit(bo, 1, no_wait, &tmp_mem);
+ if (ret) {
+ goto out_cleanup;
+ }
+ ret = drm_bo_move_ttm(bo, evict, no_wait, new_mem);
+out_cleanup:
+ if (tmp_mem.mm_node) {
+ mutex_lock(&dev->struct_mutex);
+ if (tmp_mem.mm_node != bo->pinned_node)
+ drm_mm_put_block(tmp_mem.mm_node);
+ tmp_mem.mm_node = NULL;
+ mutex_unlock(&dev->struct_mutex);
+ }
+ return ret;
+}
+
+int radeon_ms_bo_get_gpu_addr(struct drm_device *dev,
+ struct drm_bo_mem_reg *mem,
+ uint32_t *gpu_addr)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ *gpu_addr = mem->mm_node->start << PAGE_SHIFT;
+ switch (mem->flags & DRM_BO_MASK_MEM) {
+ case DRM_BO_FLAG_MEM_TT:
+ *gpu_addr += dev_priv->gpu_gart_start;
+ DRM_INFO("[radeon_ms] GPU TT: 0x%08X\n", *gpu_addr);
+ break;
+ case DRM_BO_FLAG_MEM_VRAM:
+ *gpu_addr += dev_priv->gpu_vram_start;
+ DRM_INFO("[radeon_ms] GPU VRAM: 0x%08X\n", *gpu_addr);
+ break;
+ default:
+ DRM_ERROR("[radeon_ms] memory not accessible by GPU\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int radeon_ms_bo_move(struct drm_buffer_object *bo, int evict,
+ int no_wait, struct drm_bo_mem_reg *new_mem)
+{
+ struct drm_bo_mem_reg *old_mem = &bo->mem;
+ if (old_mem->mem_type == DRM_BO_MEM_LOCAL) {
+ return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
+ } else if (new_mem->mem_type == DRM_BO_MEM_LOCAL) {
+ if (radeon_ms_bo_move_flip(bo, evict, no_wait, new_mem))
+ return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
+ } else {
+ if (radeon_ms_bo_move_blit(bo, evict, no_wait, new_mem))
+ return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
+ }
+ return 0;
+}
+
+struct drm_ttm_backend *radeon_ms_create_ttm_backend(struct drm_device * dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ if (dev_priv && dev_priv->create_ttm)
+ return dev_priv->create_ttm(dev);
+ return NULL;
+}
+
+uint64_t radeon_ms_evict_flags(struct drm_buffer_object *bo)
+{
+ switch (bo->mem.mem_type) {
+ case DRM_BO_MEM_LOCAL:
+ case DRM_BO_MEM_TT:
+ return DRM_BO_FLAG_MEM_LOCAL;
+ case DRM_BO_MEM_VRAM:
+ if (bo->mem.num_pages > 128)
+ return DRM_BO_MEM_TT;
+ else
+ return DRM_BO_MEM_LOCAL;
+ default:
+ return DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_CACHED;
+ }
+}
+
+int radeon_ms_init_mem_type(struct drm_device * dev, uint32_t type,
+ struct drm_mem_type_manager * man)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ switch (type) {
+ case DRM_BO_MEM_LOCAL:
+ man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
+ _DRM_FLAG_MEMTYPE_CACHED;
+ man->drm_bus_maptype = 0;
+ break;
+ case DRM_BO_MEM_VRAM:
+ man->flags = _DRM_FLAG_MEMTYPE_FIXED |
+ _DRM_FLAG_MEMTYPE_MAPPABLE |
+ _DRM_FLAG_NEEDS_IOREMAP;
+ man->io_addr = NULL;
+ man->drm_bus_maptype = _DRM_FRAME_BUFFER;
+ man->io_offset = dev_priv->vram.offset;
+ man->io_size = dev_priv->vram.size;
+ break;
+ case DRM_BO_MEM_TT:
+ if (!dev_priv->bus_ready) {
+ DRM_ERROR("Bus isn't initialized while "
+ "intializing TT memory type\n");
+ return -EINVAL;
+ }
+ switch(dev_priv->bus_type) {
+ case RADEON_AGP:
+ if (!(drm_core_has_AGP(dev) && dev->agp)) {
+ DRM_ERROR("AGP is not enabled for memory "
+ "type %u\n", (unsigned)type);
+ return -EINVAL;
+ }
+ man->io_offset = dev->agp->agp_info.aper_base;
+ man->io_size = dev->agp->agp_info.aper_size *
+ 1024 * 1024;
+ man->io_addr = NULL;
+ man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
+ _DRM_FLAG_MEMTYPE_CSELECT |
+ _DRM_FLAG_NEEDS_IOREMAP;
+ man->drm_bus_maptype = _DRM_AGP;
+ man->gpu_offset = 0;
+ break;
+ default:
+ man->io_offset = dev_priv->gpu_gart_start;
+ man->io_size = dev_priv->gpu_gart_size;
+ man->io_addr = NULL;
+ man->flags = _DRM_FLAG_MEMTYPE_CSELECT |
+ _DRM_FLAG_MEMTYPE_MAPPABLE |
+ _DRM_FLAG_MEMTYPE_CMA;
+ man->drm_bus_maptype = _DRM_SCATTER_GATHER;
+ break;
+ }
+ break;
+ default:
+ DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int radeon_ms_invalidate_caches(struct drm_device * dev, uint64_t flags)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ dev_priv->flush_cache(dev);
+ return 0;
+}
+
+void radeon_ms_ttm_flush(struct drm_ttm *ttm)
+{
+ if (!ttm)
+ return;
+
+ DRM_MEMORYBARRIER();
+}
diff --git a/shared-core/radeon_ms_bus.c b/shared-core/radeon_ms_bus.c
new file mode 100644
index 00000000..ed8fb211
--- /dev/null
+++ b/shared-core/radeon_ms_bus.c
@@ -0,0 +1,460 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Alex Deucher
+ * Copyright 2007 Dave Airlie
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+/*
+ * Authors:
+ * Dave Airlie <airlied@linux.ie>
+ * Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_ms.h"
+
+struct radeon_pcie {
+ uint32_t gart_table_size;
+ struct drm_buffer_object *gart_table_object;
+ volatile uint32_t *gart_table;
+ struct drm_device *dev;
+ unsigned long page_last;
+};
+
+struct radeon_pcie_gart {
+ struct drm_ttm_backend backend;
+ struct radeon_pcie *pcie;
+ unsigned long page_first;
+ struct page **pages;
+ struct page *dummy_read_page;
+ unsigned long num_pages;
+ int populated;
+ int bound;
+};
+
+static int pcie_ttm_bind(struct drm_ttm_backend *backend,
+ struct drm_bo_mem_reg *bo_mem);
+static void pcie_ttm_clear(struct drm_ttm_backend *backend);
+static void pcie_ttm_destroy(struct drm_ttm_backend *backend);
+static int pcie_ttm_needs_ub_cache_adjust(struct drm_ttm_backend *backend);
+static int pcie_ttm_populate(struct drm_ttm_backend *backend,
+ unsigned long num_pages, struct page **pages,
+ struct page *dummy_read_page);
+static int pcie_ttm_unbind(struct drm_ttm_backend *backend);
+
+static struct drm_ttm_backend_func radeon_pcie_gart_ttm_backend =
+{
+ .needs_ub_cache_adjust = pcie_ttm_needs_ub_cache_adjust,
+ .populate = pcie_ttm_populate,
+ .clear = pcie_ttm_clear,
+ .bind = pcie_ttm_bind,
+ .unbind = pcie_ttm_unbind,
+ .destroy = pcie_ttm_destroy,
+};
+
+static void pcie_gart_flush(struct radeon_pcie *pcie)
+{
+ struct drm_device *dev;
+ struct drm_radeon_private *dev_priv;
+ uint32_t flush;
+
+ if (pcie == NULL) {
+ return;
+ }
+ dev = pcie->dev;
+ dev_priv = dev->dev_private;
+ flush = dev_priv->driver_state.pcie_tx_gart_cntl;
+ flush |= PCIE_TX_GART_CNTL__GART_INVALIDATE_TLB;
+ PCIE_W(PCIE_TX_GART_CNTL, flush);
+ PCIE_W(PCIE_TX_GART_CNTL, dev_priv->driver_state.pcie_tx_gart_cntl);
+}
+
+static __inline__ uint32_t pcie_gart_get_page_base(struct radeon_pcie *pcie,
+ unsigned long page)
+{
+ if (pcie == NULL || pcie->gart_table == NULL) {
+ return 0;
+ }
+ return ((pcie->gart_table[page] & (~0xC)) << 8);
+}
+
+static __inline__ void pcie_gart_set_page_base(struct radeon_pcie *pcie,
+ unsigned long page,
+ uint32_t page_base)
+{
+ if (pcie == NULL || pcie->gart_table == NULL) {
+ return;
+ }
+ pcie->gart_table[page] = cpu_to_le32((page_base >> 8) | 0xC);
+}
+
+static int pcie_ttm_bind(struct drm_ttm_backend *backend,
+ struct drm_bo_mem_reg *bo_mem)
+{
+ struct radeon_pcie_gart *pcie_gart;
+ unsigned long page_first;
+ unsigned long page_last;
+ unsigned long page, i;
+ uint32_t page_base;
+
+ pcie_gart = container_of(backend, struct radeon_pcie_gart, backend);
+ page = page_first = bo_mem->mm_node->start;
+ page_last = page_first + pcie_gart->num_pages;
+ if (page_first >= pcie_gart->pcie->page_last ||
+ page_last >= pcie_gart->pcie->page_last)
+ return -EINVAL;
+ while (page < page_last) {
+ if (pcie_gart_get_page_base(pcie_gart->pcie, page)) {
+ return -EBUSY;
+ }
+ page++;
+ }
+
+ for (i = 0, page = page_first; i < pcie_gart->num_pages; i++, page++) {
+ struct page *cur_page = pcie_gart->pages[i];
+
+ if (!page) {
+ cur_page = pcie_gart->dummy_read_page;
+ }
+ /* write value */
+ page_base = page_to_phys(cur_page);
+ pcie_gart_set_page_base(pcie_gart->pcie, page, page_base);
+ }
+ DRM_MEMORYBARRIER();
+ pcie_gart_flush(pcie_gart->pcie);
+ pcie_gart->bound = 1;
+ pcie_gart->page_first = page_first;
+ return 0;
+}
+
+static void pcie_ttm_clear(struct drm_ttm_backend *backend)
+{
+ struct radeon_pcie_gart *pcie_gart;
+
+ pcie_gart = container_of(backend, struct radeon_pcie_gart, backend);
+ if (pcie_gart->pages) {
+ backend->func->unbind(backend);
+ pcie_gart->pages = NULL;
+ }
+ pcie_gart->num_pages = 0;
+}
+
+static void pcie_ttm_destroy(struct drm_ttm_backend *backend)
+{
+ struct radeon_pcie_gart *pcie_gart;
+
+ if (backend == NULL) {
+ return;
+ }
+ pcie_gart = container_of(backend, struct radeon_pcie_gart, backend);
+ if (pcie_gart->pages) {
+ backend->func->clear(backend);
+ }
+ drm_ctl_free(pcie_gart, sizeof(*pcie_gart), DRM_MEM_TTM);
+}
+
+static int pcie_ttm_needs_ub_cache_adjust(struct drm_ttm_backend *backend)
+{
+ return ((backend->flags & DRM_BE_FLAG_BOUND_CACHED) ? 0 : 1);
+}
+
+static int pcie_ttm_populate(struct drm_ttm_backend *backend,
+ unsigned long num_pages, struct page **pages,
+ struct page *dummy_read_page)
+{
+ struct radeon_pcie_gart *pcie_gart;
+
+ pcie_gart = container_of(backend, struct radeon_pcie_gart, backend);
+ pcie_gart->pages = pages;
+ pcie_gart->num_pages = num_pages;
+ pcie_gart->populated = 1;
+ return 0;
+}
+
+static int pcie_ttm_unbind(struct drm_ttm_backend *backend)
+{
+ struct radeon_pcie_gart *pcie_gart;
+ unsigned long page, i;
+
+ pcie_gart = container_of(backend, struct radeon_pcie_gart, backend);
+ if (pcie_gart->bound != 1 || pcie_gart->pcie->gart_table == NULL) {
+ return -EINVAL;
+ }
+ for (i = 0, page = pcie_gart->page_first; i < pcie_gart->num_pages;
+ i++, page++) {
+ pcie_gart->pcie->gart_table[page] = 0;
+ }
+ pcie_gart_flush(pcie_gart->pcie);
+ pcie_gart->bound = 0;
+ pcie_gart->page_first = 0;
+ return 0;
+}
+
+int radeon_ms_agp_finish(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ if (!dev_priv->bus_ready) {
+ return 0;
+ }
+ dev_priv->bus_ready = 0;
+ drm_agp_release(dev);
+ return 0;
+}
+
+int radeon_ms_agp_init(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_state *state = &dev_priv->driver_state;
+ struct drm_agp_mode mode;
+ uint32_t agp_status;
+ int ret;
+
+ dev_priv->bus_ready = -1;
+ if (dev->agp == NULL) {
+ DRM_ERROR("[radeon_ms] can't initialize AGP\n");
+ return -EINVAL;
+ }
+ ret = drm_agp_acquire(dev);
+ if (ret) {
+ DRM_ERROR("[radeon_ms] error failed to acquire agp\n");
+ return ret;
+ }
+ agp_status = MMIO_R(AGP_STATUS);
+ if ((AGP_STATUS__MODE_AGP30 & agp_status)) {
+ mode.mode = AGP_STATUS__RATE4X;
+ } else {
+ mode.mode = AGP_STATUS__RATE2X_8X;
+ }
+ ret = drm_agp_enable(dev, mode);
+ if (ret) {
+ DRM_ERROR("[radeon_ms] error failed to enable agp\n");
+ return ret;
+ }
+ state->agp_command = MMIO_R(AGP_COMMAND) | AGP_COMMAND__AGP_EN;
+ state->agp_command &= ~AGP_COMMAND__FW_EN;
+ state->agp_command &= ~AGP_COMMAND__MODE_4G_EN;
+ state->aic_ctrl = 0;
+ state->agp_base = REG_S(AGP_BASE, AGP_BASE_ADDR, dev->agp->base);
+ state->agp_base_2 = 0;
+ state->bus_cntl = MMIO_R(BUS_CNTL);
+ state->bus_cntl &= ~BUS_CNTL__BUS_MASTER_DIS;
+ state->mc_agp_location =
+ REG_S(MC_AGP_LOCATION, MC_AGP_START,
+ dev_priv->gpu_gart_start >> 16) |
+ REG_S(MC_AGP_LOCATION, MC_AGP_TOP,
+ dev_priv->gpu_gart_end >> 16);
+ DRM_INFO("[radeon_ms] gpu agp base 0x%08X\n", MMIO_R(AGP_BASE));
+ DRM_INFO("[radeon_ms] gpu agp location 0x%08X\n",
+ MMIO_R(MC_AGP_LOCATION));
+ DRM_INFO("[radeon_ms] gpu agp location 0x%08X\n",
+ state->mc_agp_location);
+ DRM_INFO("[radeon_ms] bus ready\n");
+ dev_priv->bus_ready = 1;
+ return 0;
+}
+
+void radeon_ms_agp_restore(struct drm_device *dev, struct radeon_state *state)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ MMIO_W(MC_AGP_LOCATION, state->mc_agp_location);
+ MMIO_W(AGP_BASE, state->agp_base);
+ MMIO_W(AGP_BASE_2, state->agp_base_2);
+ MMIO_W(AGP_COMMAND, state->agp_command);
+}
+
+void radeon_ms_agp_save(struct drm_device *dev, struct radeon_state *state)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ state->agp_command = MMIO_R(AGP_COMMAND);
+ state->agp_base = MMIO_R(AGP_BASE);
+ state->agp_base_2 = MMIO_R(AGP_BASE_2);
+ state->mc_agp_location = MMIO_R(MC_AGP_LOCATION);
+}
+
+struct drm_ttm_backend *radeon_ms_pcie_create_ttm(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_pcie_gart *pcie_gart;
+
+ pcie_gart = drm_ctl_calloc(1, sizeof (*pcie_gart), DRM_MEM_TTM);
+ if (pcie_gart == NULL) {
+ return NULL;
+ }
+ memset(pcie_gart, 0, sizeof(struct radeon_pcie_gart));
+ pcie_gart->populated = 0;
+ pcie_gart->pcie = dev_priv->bus;
+ pcie_gart->backend.func = &radeon_pcie_gart_ttm_backend;
+
+ return &pcie_gart->backend;
+}
+
+int radeon_ms_pcie_finish(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_pcie *pcie = dev_priv->bus;
+
+ if (!dev_priv->bus_ready || pcie == NULL) {
+ dev_priv->bus_ready = 0;
+ return 0;
+ }
+ dev_priv->bus_ready = 0;
+ if (pcie->gart_table) {
+ drm_mem_reg_iounmap(dev, &pcie->gart_table_object->mem,
+ (void *)pcie->gart_table);
+ }
+ pcie->gart_table = NULL;
+ if (pcie->gart_table_object) {
+ mutex_lock(&dev->struct_mutex);
+ drm_bo_usage_deref_locked(&pcie->gart_table_object);
+ mutex_unlock(&dev->struct_mutex);
+ }
+ dev_priv->bus = NULL;
+ drm_free(pcie, sizeof(*pcie), DRM_MEM_DRIVER);
+ return 0;
+}
+
+int radeon_ms_pcie_init(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_state *state = &dev_priv->driver_state;
+ struct radeon_pcie *pcie;
+ int ret = 0;
+
+ dev_priv->bus_ready = -1;
+ /* allocate and clear device private structure */
+ pcie = drm_alloc(sizeof(struct radeon_pcie), DRM_MEM_DRIVER);
+ if (pcie == NULL) {
+ return -ENOMEM;
+ }
+ memset(pcie, 0, sizeof(struct radeon_pcie));
+ pcie->dev = dev;
+ dev_priv->bus = (void *)pcie;
+ pcie->gart_table_size = (dev_priv->gpu_gart_size / RADEON_PAGE_SIZE) *
+ 4;
+ /* gart table start must be aligned on 16bytes, align it on one page */
+ ret = drm_buffer_object_create(dev,
+ pcie->gart_table_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,
+ 1,
+ 0,
+ &pcie->gart_table_object);
+ if (ret) {
+ return ret;
+ }
+ ret = drm_mem_reg_ioremap(dev, &pcie->gart_table_object->mem,
+ (void **) &pcie->gart_table);
+ if (ret) {
+ DRM_ERROR("[radeon_ms] error mapping gart table: %d\n", ret);
+ return ret;
+ }
+ DRM_INFO("[radeon_ms] gart table in vram at 0x%08lX\n",
+ pcie->gart_table_object->offset);
+ memset((void *)pcie->gart_table, 0, pcie->gart_table_size);
+ pcie->page_last = pcie->gart_table_size >> 2;
+ state->pcie_tx_gart_discard_rd_addr_lo =
+ REG_S(PCIE_TX_GART_DISCARD_RD_ADDR_LO,
+ GART_DISCARD_RD_ADDR_LO,
+ dev_priv->gpu_gart_start);
+ state->pcie_tx_gart_discard_rd_addr_hi =
+ REG_S(PCIE_TX_GART_DISCARD_RD_ADDR_HI,
+ GART_DISCARD_RD_ADDR_HI, 0);
+ state->pcie_tx_gart_base =
+ REG_S(PCIE_TX_GART_BASE, GART_BASE,
+ pcie->gart_table_object->offset);
+ state->pcie_tx_gart_start_lo =
+ REG_S(PCIE_TX_GART_START_LO, GART_START_LO,
+ dev_priv->gpu_gart_start);
+ state->pcie_tx_gart_start_hi =
+ REG_S(PCIE_TX_GART_START_HI, GART_START_HI, 0);
+ state->pcie_tx_gart_end_lo =
+ REG_S(PCIE_TX_GART_END_LO, GART_END_LO, dev_priv->gpu_gart_end);
+ state->pcie_tx_gart_end_hi =
+ REG_S(PCIE_TX_GART_END_HI, GART_END_HI, 0);
+ /* FIXME: why this ? */
+ state->aic_ctrl = 0;
+ state->agp_base = 0;
+ state->agp_base_2 = 0;
+ state->bus_cntl = MMIO_R(BUS_CNTL);
+ state->mc_agp_location = REG_S(MC_AGP_LOCATION, MC_AGP_START, 0xffc0) |
+ REG_S(MC_AGP_LOCATION, MC_AGP_TOP, 0xffff);
+ state->pcie_tx_gart_cntl =
+ PCIE_TX_GART_CNTL__GART_EN |
+ REG_S(PCIE_TX_GART_CNTL, GART_UNMAPPED_ACCESS,
+ GART_UNMAPPED_ACCESS__DISCARD) |
+ REG_S(PCIE_TX_GART_CNTL, GART_MODE, GART_MODE__CACHE_32x128) |
+ REG_S(PCIE_TX_GART_CNTL, GART_RDREQPATH_SEL,
+ GART_RDREQPATH_SEL__HDP);
+ DRM_INFO("[radeon_ms] gpu gart start 0x%08X\n",
+ PCIE_R(PCIE_TX_GART_START_LO));
+ DRM_INFO("[radeon_ms] gpu gart end 0x%08X\n",
+ PCIE_R(PCIE_TX_GART_END_LO));
+ DRM_INFO("[radeon_ms] bus ready\n");
+ dev_priv->bus_ready = 1;
+ return 0;
+}
+
+void radeon_ms_pcie_restore(struct drm_device *dev, struct radeon_state *state)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ /* disable gart before programing other registers */
+ radeon_ms_agp_restore(dev, state);
+ PCIE_W(PCIE_TX_GART_CNTL, 0);
+ PCIE_W(PCIE_TX_GART_BASE, state->pcie_tx_gart_base);
+ PCIE_W(PCIE_TX_GART_BASE, state->pcie_tx_gart_base);
+ PCIE_W(PCIE_TX_GART_DISCARD_RD_ADDR_HI,
+ state->pcie_tx_gart_discard_rd_addr_hi);
+ PCIE_W(PCIE_TX_GART_DISCARD_RD_ADDR_LO,
+ state->pcie_tx_gart_discard_rd_addr_lo);
+ PCIE_W(PCIE_TX_GART_START_HI, state->pcie_tx_gart_start_hi);
+ PCIE_W(PCIE_TX_GART_START_LO, state->pcie_tx_gart_start_lo);
+ PCIE_W(PCIE_TX_GART_END_HI, state->pcie_tx_gart_end_hi);
+ PCIE_W(PCIE_TX_GART_END_LO, state->pcie_tx_gart_end_lo);
+ PCIE_W(PCIE_TX_GART_CNTL, state->pcie_tx_gart_cntl);
+}
+
+void radeon_ms_pcie_save(struct drm_device *dev, struct radeon_state *state)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ radeon_ms_agp_save(dev, state);
+ state->pcie_tx_gart_base = PCIE_R(PCIE_TX_GART_BASE);
+ state->pcie_tx_gart_base = PCIE_R(PCIE_TX_GART_BASE);
+ state->pcie_tx_gart_discard_rd_addr_hi =
+ PCIE_R(PCIE_TX_GART_DISCARD_RD_ADDR_HI);
+ state->pcie_tx_gart_discard_rd_addr_lo =
+ PCIE_R(PCIE_TX_GART_DISCARD_RD_ADDR_LO);
+ state->pcie_tx_gart_start_hi = PCIE_R(PCIE_TX_GART_START_HI);
+ state->pcie_tx_gart_start_lo = PCIE_R(PCIE_TX_GART_START_LO);
+ state->pcie_tx_gart_end_hi = PCIE_R(PCIE_TX_GART_END_HI);
+ state->pcie_tx_gart_end_lo = PCIE_R(PCIE_TX_GART_END_LO);
+ state->pcie_tx_gart_cntl = PCIE_R(PCIE_TX_GART_CNTL);
+}
diff --git a/shared-core/radeon_ms_combios.c b/shared-core/radeon_ms_combios.c
new file mode 100644
index 00000000..65609af9
--- /dev/null
+++ b/shared-core/radeon_ms_combios.c
@@ -0,0 +1,411 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ */
+/*
+ * Authors:
+ * Jérôme Glisse <glisse@freedesktop.org>
+ */
+#include "radeon_ms.h"
+
+extern struct radeon_ms_output radeon_ms_dac1;
+extern struct radeon_ms_output radeon_ms_dac2;
+extern const struct drm_output_funcs radeon_ms_output_funcs;
+
+static struct combios_connector_chip_info *
+radeon_ms_combios_get_connector_chip_info(struct drm_device *dev, int chip_num)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_ms_rom *rom = &dev_priv->rom;
+ struct combios_header *header;
+ struct combios_connector_table *connector_table;
+ struct combios_connector_chip_info *connector_chip_info;
+ uint32_t offset;
+ int numof_chips, i;
+
+ if (rom->type != ROM_COMBIOS || rom->rom_image == NULL) {
+ return NULL;
+ }
+ header = rom->rom.combios_header;
+ offset = header->usPointerToExtendedInitTable2;
+ if ((offset + sizeof(struct combios_connector_table)) > rom->rom_size) {
+ DRM_INFO("[radeon_ms] wrong COMBIOS connector offset\n");
+ return NULL;
+ }
+ if (!offset) {
+ return NULL;
+ }
+ connector_table = (struct combios_connector_table *)
+ &rom->rom_image[offset];
+ numof_chips = (connector_table->ucConnectorHeader &
+ BIOS_CONNECTOR_HEADER__NUMBER_OF_CHIPS__MASK) >>
+ BIOS_CONNECTOR_HEADER__NUMBER_OF_CHIPS__SHIFT;
+ DRM_INFO("[radeon_ms] COMBIOS number of chip: %d (table rev: %d)\n",
+ numof_chips,
+ (connector_table->ucConnectorHeader &
+ BIOS_CONNECTOR_HEADER__TABLE_REVISION__MASK) >>
+ BIOS_CONNECTOR_HEADER__TABLE_REVISION__SHIFT);
+ for (i = 0; i < numof_chips; i++) {
+ int chip;
+
+ connector_chip_info = &connector_table->sChipConnectorInfo[i];
+ chip = (connector_chip_info->ucChipHeader &
+ BIOS_CHIPINFO_HEADER__CHIP_NUMBER__MASK) >>
+ BIOS_CHIPINFO_HEADER__CHIP_NUMBER__SHIFT;
+ DRM_INFO("[radeon_ms] COMBIOS chip: %d (asked for: %d)\n",
+ chip, chip_num);
+ if (chip == chip_num) {
+ return connector_chip_info;
+ }
+ }
+ return NULL;
+}
+
+static int radeon_combios_get_connector_infos(struct drm_device *dev,
+ int connector_info,
+ int *connector_type,
+ int *ddc_line,
+ int *tmds_type,
+ int *dac_type)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ *connector_type = (connector_info & BIOS_CONNECTOR_INFO__TYPE__MASK) >>
+ BIOS_CONNECTOR_INFO__TYPE__SHIFT;
+ *ddc_line = (connector_info & BIOS_CONNECTOR_INFO__DDC_LINE__MASK) >>
+ BIOS_CONNECTOR_INFO__DDC_LINE__SHIFT;
+ *tmds_type = (connector_info & BIOS_CONNECTOR_INFO__TMDS_TYPE__MASK) >>
+ BIOS_CONNECTOR_INFO__TMDS_TYPE__SHIFT;
+ *dac_type = (connector_info & BIOS_CONNECTOR_INFO__DAC_TYPE__MASK) >>
+ BIOS_CONNECTOR_INFO__DAC_TYPE__SHIFT;
+
+ /* most XPRESS chips seem to specify DDC_CRT2 for their
+ * VGA DDC port, however DDC never seems to work on that
+ * port. Some have reported success on DDC_MONID, so
+ * lets see what happens with that.
+ */
+ if (dev_priv->family == CHIP_RS400 &&
+ *connector_type == BIOS_CONNECTOR_TYPE__CRT &&
+ *ddc_line == BIOS_DDC_LINE__CRT2) {
+ *ddc_line = BIOS_DDC_LINE__MONID01;
+ }
+ /* XPRESS desktop chips seem to have a proprietary
+ * connector listed for DVI-D, try and do the right
+ * thing here.
+ */
+ if (dev_priv->family == CHIP_RS400 &&
+ *connector_type == BIOS_CONNECTOR_TYPE__PROPRIETARY) {
+ DRM_INFO("[radeon_ms] COMBIOS Proprietary connector "
+ "found, assuming DVI-D\n");
+ *dac_type = 2;
+ *tmds_type = BIOS_TMDS_TYPE__EXTERNAL;
+ *connector_type = BIOS_CONNECTOR_TYPE__DVI_D;
+ }
+ return 0;
+}
+
+static int radeon_ms_combios_connector_add(struct drm_device *dev,
+ int connector_number,
+ int connector_type,
+ uint32_t i2c_reg)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_ms_connector *connector = NULL;
+ struct drm_output *output = NULL;
+
+ connector = drm_alloc(sizeof(struct radeon_ms_connector),
+ DRM_MEM_DRIVER);
+ if (connector == NULL) {
+ radeon_ms_connectors_destroy(dev);
+ return -ENOMEM;
+ }
+ memset(connector, 0, sizeof(struct radeon_ms_connector));
+ connector->monitor_type = MT_NONE;
+ connector->type = connector_type;
+ connector->i2c_reg = i2c_reg;
+
+ switch (connector->type) {
+ case CONNECTOR_VGA:
+ sprintf(connector->name, "VGA");
+ break;
+ case CONNECTOR_DVI_I:
+ sprintf(connector->name, "DVI-I");
+ break;
+ case CONNECTOR_DVI_D:
+ sprintf(connector->name, "DVI-D");
+ break;
+ default:
+ sprintf(connector->name, "UNKNOWN-CONNECTOR");
+ break;
+ }
+
+ if (i2c_reg) {
+ connector->i2c = radeon_ms_i2c_create(dev,
+ connector->i2c_reg,
+ connector->name);
+ if (connector->i2c == NULL) {
+ radeon_ms_connectors_destroy(dev);
+ return -ENOMEM;
+ }
+ } else {
+ connector->i2c = NULL;
+ }
+
+ output = drm_output_create(dev, &radeon_ms_output_funcs,
+ connector->type);
+ if (output == NULL) {
+ radeon_ms_connectors_destroy(dev);
+ return -EINVAL;
+ }
+ connector->output = output;
+ output->driver_private = connector;
+ output->possible_crtcs = 0x3;
+ dev_priv->connectors[connector_number] = connector;
+ return 0;
+}
+
+int radeon_ms_combios_get_properties(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_ms_rom *rom = &dev_priv->rom;
+ struct combios_pll_block *pll_block;
+ struct combios_header *header;
+ uint32_t offset;
+
+ if (rom->type != ROM_COMBIOS || rom->rom_image == NULL) {
+ return 0;
+ }
+ header = rom->rom.combios_header;
+ offset = header->usPointerToPllInfoBlock;
+ if ((offset + sizeof(struct combios_pll_block)) > rom->rom_size) {
+ DRM_INFO("[radeon_ms] wrong COMBIOS pll block offset\n");
+ return 0;
+ }
+ if (!offset) {
+ return 0;
+ }
+ pll_block = (struct combios_pll_block *)&rom->rom_image[offset];
+ dev_priv->properties.pll_reference_freq = pll_block->usDotClockRefFreq;
+ dev_priv->properties.pll_reference_div = pll_block->usDotClockRefDiv;
+ dev_priv->properties.pll_min_pll_freq = pll_block->ulDotClockMinFreq;
+ dev_priv->properties.pll_max_pll_freq = pll_block->ulDotClockMaxFreq;
+ dev_priv->properties.pll_reference_freq *= 10;
+ dev_priv->properties.pll_min_pll_freq *= 10;
+ dev_priv->properties.pll_max_pll_freq *= 10;
+ DRM_INFO("[radeon_ms] COMBIOS pll reference frequency : %d\n",
+ dev_priv->properties.pll_reference_freq);
+ DRM_INFO("[radeon_ms] COMBIOS pll reference divider : %d\n",
+ dev_priv->properties.pll_reference_div);
+ DRM_INFO("[radeon_ms] COMBIOS pll minimum frequency : %d\n",
+ dev_priv->properties.pll_min_pll_freq);
+ DRM_INFO("[radeon_ms] COMBIOS pll maximum frequency : %d\n",
+ dev_priv->properties.pll_max_pll_freq);
+ return 1;
+}
+
+int radeon_ms_connectors_from_combios(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct combios_connector_chip_info *connector_chip_info;
+ int connector_type, ddc_line, tmds_type, dac_type;
+ int dac1, dac2, tmdsint, tmdsext;
+ int numof_connector, i, c = 0, added, j;
+ uint32_t i2c_reg;
+ int ret;
+
+ dac1 = dac2 = tmdsint = tmdsext = -1;
+ connector_chip_info = radeon_ms_combios_get_connector_chip_info(dev, 1);
+ if (connector_chip_info == NULL) {
+ return -1;
+ }
+ numof_connector = (connector_chip_info->ucChipHeader &
+ BIOS_CHIPINFO_HEADER__NUMBER_OF_CONNECTORS__MASK) >>
+ BIOS_CHIPINFO_HEADER__NUMBER_OF_CONNECTORS__SHIFT;
+ DRM_INFO("[radeon_ms] COMBIOS number of connector: %d\n",
+ numof_connector);
+ for (i = 0; i < numof_connector; i++) {
+ int connector_info = connector_chip_info->sConnectorInfo[i];
+
+ ret = radeon_combios_get_connector_infos(dev,
+ connector_info,
+ &connector_type,
+ &ddc_line,
+ &tmds_type,
+ &dac_type);
+
+ switch (ddc_line) {
+ case BIOS_DDC_LINE__MONID01:
+ i2c_reg = GPIO_MONID;
+ break;
+ case BIOS_DDC_LINE__DVI:
+ i2c_reg = GPIO_DVI_DDC;
+ break;
+ case BIOS_DDC_LINE__VGA:
+ i2c_reg = GPIO_DDC1;
+ break;
+ case BIOS_DDC_LINE__CRT2:
+ i2c_reg = GPIO_CRT2_DDC;
+ break;
+ case BIOS_DDC_LINE__GPIOPAD:
+ i2c_reg = VIPPAD_EN;
+ break;
+ case BIOS_DDC_LINE__ZV_LCDPAD:
+ i2c_reg = VIPPAD1_EN;
+ break;
+ default:
+ i2c_reg = 0;
+ break;
+ }
+ added = 0;
+ switch (connector_type) {
+ case BIOS_CONNECTOR_TYPE__CRT:
+ ret = radeon_ms_combios_connector_add(dev, c,
+ CONNECTOR_VGA,
+ i2c_reg);
+ if (ret) {
+ return ret;
+ }
+ added = 1;
+ break;
+ case BIOS_CONNECTOR_TYPE__DVI_I:
+ ret = radeon_ms_combios_connector_add(dev, c,
+ CONNECTOR_DVI_I,
+ i2c_reg);
+ if (ret) {
+ return ret;
+ }
+ added = 1;
+ break;
+ case BIOS_CONNECTOR_TYPE__DVI_D:
+ ret = radeon_ms_combios_connector_add(dev, c,
+ CONNECTOR_DVI_D,
+ i2c_reg);
+ if (ret) {
+ return ret;
+ }
+ added = 1;
+ break;
+ default:
+ break;
+ }
+ if (added) {
+ j = 0;
+ /* find to which output this connector is associated
+ * by following same algo as in:
+ * radeon_ms_outputs_from_combios*/
+ switch (dac_type) {
+ case BIOS_DAC_TYPE__CRT:
+ if (dac1 == -1) {
+ dac1 = c;
+ }
+ dev_priv->connectors[c]->outputs[j++] = dac1;
+ break;
+ case BIOS_DAC_TYPE__NON_CRT:
+ if (dac2 == -1) {
+ dac2 = c;
+ }
+ dev_priv->connectors[c]->outputs[j++] = dac2;
+ break;
+ }
+#if 0
+ switch (tmds_type) {
+ case BIOS_TMDS_TYPE__INTERNAL:
+ if (tmdsint == -1) {
+ tmdsint = c;
+ }
+ dev_priv->connectors[c]->outputs[j++] = tmdsint;
+ break;
+ case BIOS_TMDS_TYPE__EXTERNAL:
+ if (tmdsext == -1) {
+ tmdsext = c;
+ }
+ dev_priv->connectors[c]->outputs[j++] = tmdsext;
+ break;
+ }
+#endif
+ c++;
+ }
+ }
+ return c;
+}
+
+int radeon_ms_outputs_from_combios(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct combios_connector_chip_info *connector_chip_info;
+ int connector_type, ddc_line, tmds_type, dac_type;
+ int numof_connector, i, dac1_present, dac2_present, c = 0;
+ int ret;
+
+ dac1_present = dac2_present = 0;
+ connector_chip_info = radeon_ms_combios_get_connector_chip_info(dev, 1);
+ if (connector_chip_info == NULL) {
+ return -1;
+ }
+ numof_connector = (connector_chip_info->ucChipHeader &
+ BIOS_CHIPINFO_HEADER__NUMBER_OF_CONNECTORS__MASK) >>
+ BIOS_CHIPINFO_HEADER__NUMBER_OF_CONNECTORS__SHIFT;
+ DRM_INFO("[radeon_ms] COMBIOS number of connector: %d\n",
+ numof_connector);
+ for (i = 0; i < numof_connector; i++) {
+ int connector_info = connector_chip_info->sConnectorInfo[i];
+
+ ret = radeon_combios_get_connector_infos(dev,
+ connector_info,
+ &connector_type,
+ &ddc_line,
+ &tmds_type,
+ &dac_type);
+
+ if (!dac1_present && dac_type == BIOS_DAC_TYPE__CRT) {
+ dev_priv->outputs[c] =
+ drm_alloc(sizeof(struct radeon_ms_output),
+ DRM_MEM_DRIVER);
+ if (dev_priv->outputs[c] == NULL) {
+ radeon_ms_outputs_destroy(dev);
+ return -ENOMEM;
+ }
+ memcpy(dev_priv->outputs[c], &radeon_ms_dac1,
+ sizeof(struct radeon_ms_output));
+ dev_priv->outputs[c]->dev = dev;
+ dev_priv->outputs[c]->initialize(dev_priv->outputs[c]);
+ dac1_present = 1;
+ c++;
+ }
+ if (!dac2_present && dac_type == BIOS_DAC_TYPE__NON_CRT) {
+ dev_priv->outputs[c] =
+ drm_alloc(sizeof(struct radeon_ms_output),
+ DRM_MEM_DRIVER);
+ if (dev_priv->outputs[c] == NULL) {
+ radeon_ms_outputs_destroy(dev);
+ return -ENOMEM;
+ }
+ memcpy(dev_priv->outputs[c], &radeon_ms_dac2,
+ sizeof(struct radeon_ms_output));
+ dev_priv->outputs[c]->dev = dev;
+ dev_priv->outputs[c]->initialize(dev_priv->outputs[c]);
+ dac1_present = 1;
+ c++;
+ }
+ }
+ return c;
+}
diff --git a/shared-core/radeon_ms_combios.h b/shared-core/radeon_ms_combios.h
new file mode 100644
index 00000000..fbceadf2
--- /dev/null
+++ b/shared-core/radeon_ms_combios.h
@@ -0,0 +1,385 @@
+/*
+ * Copyright 2006-2007 Advanced Micro Devices, Inc.
+ * Copyright 2007 Jérôme Glisse
+ *
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ */
+/*
+ * Authors:
+ * Jérôme Glisse <glisse@freedesktop.org>
+ */
+#ifndef __RADEON_MS_COMBIOS_H__
+#define __RADEON_MS_COMBIOS_H__
+
+#pragma pack(1)
+
+#define ROM_HEADER 0x48
+
+struct combios_header
+{
+ uint8_t ucTypeDefinition;
+ uint8_t ucExtFunctionCode;
+ uint8_t ucOemID1;
+ uint8_t ucOemID2;
+ uint8_t ucBiosMajorRev;
+ uint8_t ucBiosMinorRev;
+ uint16_t usStructureSize;
+ uint16_t usPointerToSmi;
+ uint16_t usPointerToPmid;
+ uint16_t usPointerToInitTable;
+ uint16_t usPointerToCrcChecksumBlock;
+ uint16_t usPointerToConfigFilename;
+ uint16_t usPointerToLogonMessage;
+ uint16_t usPointerToMiscInfo;
+ uint16_t usPciBusDevInitCode;
+ uint16_t usBiosRuntimeSegmentAddress;
+ uint16_t usIoBaseAddress;
+ uint16_t usSubsystemVendorID;
+ uint16_t usSubsystemID;
+ uint16_t usPostVendorID;
+ uint16_t usInt10Offset;
+ uint16_t usInt10Segment;
+ uint16_t usMonitorInfo;
+ uint16_t usPointerToConfigBlock;
+ uint16_t usPointerToDacDelayInfo;
+ uint16_t usPointerToCapDataStruct;
+ uint16_t usPointerToInternalCrtTables;
+ uint16_t usPointerToPllInfoBlock;
+ uint16_t usPointerToTVInfoTable;
+ uint16_t usPointerToDFPInfoTable;
+ uint16_t usPointerToHWConfigTable;
+ uint16_t usPointerToMMConfigTable;
+ uint32_t ulTVStdPatchTableSignature;
+ uint16_t usPointerToTVStdPatchTable;
+ uint16_t usPointerToPanelInfoTable;
+ uint16_t usPointerToAsicInfoTable;
+ uint16_t usPointerToAuroraInfoTable;
+ uint16_t usPointerToPllInitTable;
+ uint16_t usPointerToMemoryConfigTable;
+ uint16_t usPointerToSaveMaskTable;
+ uint16_t usPointerHardCodedEdid;
+ uint16_t usPointerToExtendedInitTable1;
+ uint16_t usPointerToExtendedInitTable2;
+ uint16_t usPointerToDynamicClkTable;
+ uint16_t usPointerToReservedMemoryTable;
+ uint16_t usPointerToBridgetInitTable;
+ uint16_t usPointerToExtTMDSInitTable;
+ uint16_t usPointerToMemClkInfoTable;
+ uint16_t usPointerToExtDACTable;
+ uint16_t usPointerToMiscInfoTable;
+};
+
+struct combios_pll_block
+{
+ /* Usually 6 */
+ uint8_t ucPLLBiosVersion;
+ /* Size in bytes */
+ uint8_t ucStructureSize;
+ /* Dot clock entry used for accelerated modes */
+ uint8_t ucDotClockEntry;
+ /* Dot clock entry used for extended VGA modes */
+ uint8_t ucDotClockEntryVga;
+ /* Offset into internal clock table used for by VGA parameter table */
+ uint16_t usPointerToInternalClock;
+ /* Offset into actual programmed frequency table at POST */
+ uint16_t usPointerToFreqTable;
+ /* XCLK setting, (memory clock in 10 KHz units) */
+ uint16_t usXclkSetting;
+ /* MCLK setting, (engine clock in 10 KHz units) */
+ uint16_t usMclkSetting;
+ /* Number of PLL information block to follow, currently value is 3 */
+ uint8_t ucPllInfoBlockNumber;
+ /* Size of each PLL information block */
+ uint8_t ucPllInfoBlockSize;
+ /* Reference frequency of the dot clock */
+ uint16_t usDotClockRefFreq;
+ /* Reference Divider of the dot clock */
+ uint16_t usDotClockRefDiv;
+ /* Min Frequency supported before post divider for the dot clock */
+ uint32_t ulDotClockMinFreq;
+ /* Max Frequency can be supported for the dot clock */
+ uint32_t ulDotClockMaxFreq;
+ /* Reference frequency of the MCLK, engine clock */
+ uint16_t usMclkRefFreq;
+ /* Reference Divider of the MCLK, engine clock */
+ uint16_t usMclkRefDiv;
+ /* Min Frequency supported before post divider for MCLK, engine clock */
+ uint32_t ulMclkMinFreq;
+ /* Max Frequency can be supported for the MCLK, engine clock */
+ uint32_t ulMclkMaxFreq;
+ /* Reference frequency of the XCLK, memory clock */
+ uint16_t usXclkRefFreq;
+ /* Reference Divider of the XCLK, memory clock */
+ uint16_t usXclkRefDiv;
+ /* Min Frequency supported before post divider for XCLK, memory clock */
+ uint32_t ulXclkMinFreq;
+ /* Max Frequency can be supported for the XCLK, memory clock */
+ uint32_t ulXclkMaxFreq;
+
+ /*this is the PLL Information Table Extended structure version 10 */
+ uint8_t ucNumberOfExtendedPllBlocks;
+ uint8_t ucSizePLLDefinition;
+ uint16_t ulCrystalFrequencyPixelClock_pll;
+ uint32_t ulMinInputPixelClockPLLFrequency;
+ uint32_t ulMaxInputPixelClockPLLFrequency;
+ uint32_t ulMinOutputPixelClockPLLFrequency;
+ uint32_t ulMaxOutputPixelClockPLLFrequency;
+
+ /*version 11 */
+ uint16_t ulCrystalFrequencyEngineClock_pll;
+ uint32_t ulMinInputFrequencyEngineClock_pll;
+ uint32_t ulMaxInputFrequencyEngineClock_pll;
+ uint32_t ulMinOutputFrequencyEngineClock_pll;
+ uint32_t ulMaxOutputFrequencyEngineClock_pll;
+ uint16_t ulCrystalFrequencyMemoryClock_pll;
+ uint32_t ulMinInputFrequencyMemoryClock_pll;
+ uint32_t ulMaxInputFrequencyMemoryClock_pll;
+ uint32_t ulMinOutputFrequencyMemoryClock_pll;
+ uint32_t ulMaxOutputFrequencyMemoryClock_pll;
+ uint32_t ulMaximumDACOutputFrequency;
+};
+
+#define MAX_NO_OF_LCD_RES_TIMING 25
+
+struct panel_information_table
+{
+ uint8_t ucPanelIdentification;
+ uint8_t ucPanelIDString[24];
+ uint16_t usHorizontalSize;
+ uint16_t usVerticalSize;
+ uint16_t usFlatPanelType;
+ uint8_t ucRedBitsPerPrimary;
+ uint8_t ucGreenBitsPerPrimary;
+ uint8_t ucBlueBitsPerPrimary;
+ uint8_t ucReservedBitsPerPrimary;
+ uint8_t ucPanelCaps;
+ uint8_t ucPowerSequenceDelayStepsInMS;
+ uint8_t ucSupportedRefreshRateExtended;
+ uint16_t usExtendedPanelInfoTable;
+ uint16_t usPtrToHalfFrameBufferInformationTable;
+ uint16_t usVccOntoBlOn;
+ uint16_t usOffDelay;
+ uint16_t usRefDiv;
+ uint8_t ucPostDiv;
+ uint16_t usFeedBackDiv;
+ uint8_t ucSpreadSpectrumType;
+ uint16_t usSpreadSpectrumPercentage;
+ uint8_t ucBackLightLevel;
+ uint8_t ucBiasLevel;
+ uint8_t ucPowerSequenceDelay;
+ uint32_t ulPanelData;
+ uint8_t ucPanelRefreshRateData;
+ uint16_t usSupportedRefreshRate;
+ uint16_t usModeTableOffset[MAX_NO_OF_LCD_RES_TIMING];
+};
+
+struct extended_panel_info_table
+{
+ uint8_t ucExtendedPanelInfoTableVer;
+ uint8_t ucSSDelay;
+ uint8_t ucSSStepSizeIndex;
+};
+
+struct lcd_mode_table_center
+{
+ uint16_t usHorizontalRes;
+ uint16_t usVerticalRes;
+ uint8_t ucModeType;
+ uint16_t usOffset2ExpParamTable;
+ uint16_t usOffset2TvParamTable;
+ uint16_t usPixelClock;
+ uint16_t usPixelClockAdjustment;
+ uint16_t usFpPos;
+ uint8_t ucReserved;
+ uint8_t ucMiscBits;
+ uint16_t usCrtcHTotal;
+ uint16_t usCrtcHDisp;
+ uint16_t usCrtcHSyncStrt;
+ uint8_t ucCrtcHSyncWid;
+ uint16_t usCrtcVTotal;
+ uint16_t usCrtcVDisp;
+ uint16_t usCrtcVSyncStrt;
+ uint8_t ucOvrWidTop;
+};
+
+struct lcd_mode_table_exp
+{
+ uint16_t usPixelClock;
+ uint16_t usPixelClockAdjustment;
+ uint16_t usFpPos;
+ uint8_t ucReserved;
+ uint8_t ucMiscBits;
+ uint16_t usCrtcHTotal;
+ uint16_t usCrtcHDisp;
+ uint16_t usCrtcHSyncStrt;
+ uint8_t ucCrtcHSyncWid;
+ uint16_t usCrtcVTotal;
+ uint16_t usCrtcVDisp;
+ uint16_t usCrtcVSyncStrt;
+ uint8_t ucOvrWidTop;
+ uint16_t usHorizontalBlendRatio;
+ uint32_t ulVgaVertStretching;
+ uint16_t usCopVertStretching;
+ uint16_t usVgaExtVertStretching;
+};
+
+struct tmds_pll_cntl_block
+{
+ uint16_t usClockUpperRange;
+ uint32_t ulPllSetting;
+};
+
+#define MAX_PLL_CNTL_ENTRIES 8
+
+struct combios_dfp_info_table
+{
+ uint8_t ucDFPInfoTableRev;
+ uint8_t ucDFPInfoTableSize;
+ uint16_t usOffsetDetailedTimingTable;
+ uint8_t ucReserved;
+ uint8_t ucNumberOfClockRanges;
+ uint16_t usMaxPixelClock;
+ uint32_t ulInitValueTmdsPllCntl;
+ uint32_t ulFinalValueTmdsPllCntl;
+ struct tmds_pll_cntl_block sTmdsPllCntlBlock[MAX_PLL_CNTL_ENTRIES];
+};
+
+struct combios_exttmds_table_header
+{
+ uint8_t ucTableRev;
+ uint16_t usTableSize;
+ uint8_t ucNoBlocks;
+};
+
+struct combios_exttmds_block_header
+{
+ uint16_t usMaxFreq;
+ uint8_t ucI2CSlaveAddr;
+ uint8_t ucI2CLine;
+ uint8_t ucConnectorId;
+ uint8_t ucFlags;
+};
+
+/* Connector table - applicable from Piglet and later ASICs
+ byte 0 (embedded revision)
+ [7:4] = number of chips (valid number 1 - 15)
+ [3:0] = revision number of table (valid number 1 - 15)
+
+ byte 1 (Chip info)
+ [7:4] = chip number, max. 15 (valid number 1 - 15)
+ [3:0] = number of connectors for that chip, (valid number 1 - 15)
+ (number of connectors = number of 'Connector info' entries
+ for that chip)
+
+ byte 2,3 (Connector info)
+ [15:12] - connector type
+ = 0 - no connector
+ = 1 - proprietary
+ = 2 - CRT
+ = 3 - DVI-I
+ = 4 - DVI-D
+ = 5-15 - reserved for future expansion
+ [11:8] - DDC line pair used for that connector
+ = 0 - no DDC
+ = 1 - MONID 0/1
+ = 2 - DVI_DDC
+ = 3 - VGA_DDC
+ = 4 - CRT2_DDC
+ = 5-15 - reserved for future expansion
+ [5] - bit indicating presence of multiplexer for TV,CRT2
+ [7:6] - reserved for future expansion
+ [4] - TMDS type
+ = 0 - internal TMDS
+ = 1 - external TMDS
+ [3:1] - reserved for future expansion
+ [0] - DAC associated with that connector
+ = 0 - CRT DAC
+ = 1 - non-CRT DAC (e.g. TV DAC, external DAC ..)
+
+ byte 4,5,6... - byte 4,5 can be another "Connector info" word
+ describing another connector
+ - or byte 5 is a "Chip info" byte for anther chip,
+ then start with byte 5,6 to describe connectors
+ for that chip
+ - or byte 5 = 0 if all connectors for all chips on
+ board have been described, no more connector left
+ to describe.
+*/
+#define BIOS_CONNECTOR_INFO__TYPE__MASK 0xF000
+#define BIOS_CONNECTOR_INFO__TYPE__SHIFT 0x0000000C
+#define BIOS_CONNECTOR_TYPE__NONE 0x00000000
+#define BIOS_CONNECTOR_TYPE__PROPRIETARY 0x00000001
+#define BIOS_CONNECTOR_TYPE__CRT 0x00000002
+#define BIOS_CONNECTOR_TYPE__DVI_I 0x00000003
+#define BIOS_CONNECTOR_TYPE__DVI_D 0x00000004
+
+#define BIOS_CONNECTOR_INFO__DDC_LINE__MASK 0x0F00
+#define BIOS_CONNECTOR_INFO__DDC_LINE__SHIFT 0x00000008
+#define BIOS_DDC_LINE__NONE 0x00000000
+#define BIOS_DDC_LINE__MONID01 0x00000001
+#define BIOS_DDC_LINE__DVI 0x00000002
+#define BIOS_DDC_LINE__VGA 0x00000003
+#define BIOS_DDC_LINE__CRT2 0x00000004
+#define BIOS_DDC_LINE__GPIOPAD 0x00000005
+#define BIOS_DDC_LINE__ZV_LCDPAD 0x00000006
+
+#define BIOS_CONNECTOR_INFO__TMDS_TYPE__MASK 0x0010
+#define BIOS_CONNECTOR_INFO__TMDS_TYPE__SHIFT 0x00000004
+#define BIOS_TMDS_TYPE__INTERNAL 0x00000000
+#define BIOS_TMDS_TYPE__EXTERNAL 0x00000001
+
+#define BIOS_CONNECTOR_INFO__DAC_TYPE__MASK 0x0001
+#define BIOS_CONNECTOR_INFO__DAC_TYPE__SHIFT 0x00000000
+#define BIOS_DAC_TYPE__CRT 0x00000000
+#define BIOS_DAC_TYPE__NON_CRT 0x00000001
+
+#define BIOS_CONNECTOR_INFO__MUX_MASK 0x00000020
+#define BIOS_CONNECTOR_INFO__MUX_SHIFT 0x00000005
+
+#define BIOS_CHIPINFO_HEADER__CHIP_NUMBER__MASK 0xF0
+#define BIOS_CHIPINFO_HEADER__CHIP_NUMBER__SHIFT 0x00000004
+
+#define BIOS_CHIPINFO_HEADER__NUMBER_OF_CONNECTORS__MASK 0x0F
+#define BIOS_CHIPINFO_HEADER__NUMBER_OF_CONNECTORS__SHIFT 0x00000000
+
+#define BIOS_CHIPINFO__MAX_NUMBER_OF_CONNECTORS 0x00000010
+
+struct combios_connector_chip_info
+{
+ uint8_t ucChipHeader;
+ uint16_t sConnectorInfo[BIOS_CHIPINFO__MAX_NUMBER_OF_CONNECTORS];
+};
+
+#define BIOS_CONNECTOR_HEADER__NUMBER_OF_CHIPS__MASK 0xF0
+#define BIOS_CONNECTOR_HEADER__NUMBER_OF_CHIPS__SHIFT 0x00000004
+
+#define BIOS_CONNECTOR_HEADER__TABLE_REVISION__MASK 0x0F
+#define BIOS_CONNECTOR_HEADER__TABLE_REVISION__SHIFT 0x00000000
+
+struct combios_connector_table
+{
+ uint8_t ucConnectorHeader;
+ struct combios_connector_chip_info sChipConnectorInfo[0x10];
+};
+
+#pragma pack()
+
+int combios_parse(unsigned char *rom, struct combios_header *header);
+
+#endif
diff --git a/shared-core/radeon_ms_cp.c b/shared-core/radeon_ms_cp.c
new file mode 100644
index 00000000..c01769bd
--- /dev/null
+++ b/shared-core/radeon_ms_cp.c
@@ -0,0 +1,345 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Dave Airlie
+ * Copyright 2007 Alex Deucher
+ * All Rights Reserved.
+ *
+ * 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ */
+/*
+ * Authors:
+ * Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "radeon_ms.h"
+
+static int radeon_ms_test_ring_buffer(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ int i, ret;
+ uint32_t cmd[4];
+
+ MMIO_W(SCRATCH_REG4, 0);
+ cmd[0] = CP_PACKET0(SCRATCH_REG4, 0);
+ cmd[1] = 0xdeadbeef;
+ cmd[2] = CP_PACKET0(WAIT_UNTIL, 0);
+ cmd[3] = WAIT_UNTIL__WAIT_2D_IDLECLEAN |
+ WAIT_UNTIL__WAIT_HOST_IDLECLEAN;
+ DRM_MEMORYBARRIER();
+ ret = radeon_ms_ring_emit(dev, cmd, 4);
+ if (ret) {
+ return 0;
+ }
+ DRM_UDELAY(100);
+
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if (MMIO_R(SCRATCH_REG4) == 0xdeadbeef) {
+ DRM_INFO("[radeon_ms] cp test succeeded in %d usecs\n",
+ i);
+ return 1;
+ }
+ DRM_UDELAY(1);
+ }
+ DRM_INFO("[radeon_ms] cp test failed\n");
+ return 0;
+}
+
+static int radeon_ms_test_write_back(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t tmp;
+
+ if (dev_priv->ring_buffer_object == NULL ||
+ dev_priv->ring_buffer == NULL)
+ return 0;
+ dev_priv->write_back_area[0] = 0x0;
+ MMIO_W(SCRATCH_REG0, 0xdeadbeef);
+ for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
+ if (dev_priv->write_back_area[0] == 0xdeadbeef)
+ break;
+ DRM_UDELAY(1);
+ }
+ if (tmp < dev_priv->usec_timeout) {
+ DRM_INFO("[radeon_ms] writeback test succeeded in %d usecs\n",
+ tmp);
+ return 1;
+ }
+ MMIO_W(SCRATCH_UMSK, 0x0);
+ DRM_INFO("[radeon_ms] writeback test failed\n");
+ return 0;
+}
+
+static __inline__ void radeon_ms_load_mc(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ int i;
+
+ MMIO_W(CP_ME_RAM_ADDR, 0);
+ for (i = 0; i < 256; i++) {
+ MMIO_W(CP_ME_RAM_DATAH, dev_priv->microcode[(i * 2) + 1]);
+ MMIO_W(CP_ME_RAM_DATAL, dev_priv->microcode[(i * 2) + 0]);
+ }
+}
+
+int radeon_ms_cp_finish(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ if (!dev_priv->cp_ready) {
+ return 0;
+ }
+ dev_priv->cp_ready = 0;
+ radeon_ms_wait_for_idle(dev);
+ DRM_INFO("[radeon_ms] cp idle\n");
+ radeon_ms_cp_stop(dev);
+
+ DRM_INFO("[radeon_ms] ring buffer %p\n", dev_priv->ring_buffer);
+ if (dev_priv->ring_buffer) {
+ drm_bo_kunmap(&dev_priv->ring_buffer_map);
+ }
+ dev_priv->ring_buffer = NULL;
+ DRM_INFO("[radeon_ms] ring buffer object %p\n", dev_priv->ring_buffer_object);
+ if (dev_priv->ring_buffer_object) {
+ mutex_lock(&dev->struct_mutex);
+ drm_bo_usage_deref_locked(&dev_priv->ring_buffer_object);
+ mutex_unlock(&dev->struct_mutex);
+ }
+ return 0;
+}
+
+int radeon_ms_cp_init(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_state *state = &dev_priv->driver_state;
+ int ret = 0;
+
+ dev_priv->cp_ready = -1;
+ if (dev_priv->microcode == NULL) {
+ DRM_INFO("[radeon_ms] no microcode not starting cp");
+ return 0;
+ }
+ /* we allocate an extra page for all write back stuff */
+ ret = drm_buffer_object_create(dev,
+ dev_priv->ring_buffer_size +
+ dev_priv->write_back_area_size,
+ drm_bo_type_kernel,
+ DRM_BO_FLAG_READ |
+ DRM_BO_FLAG_WRITE |
+ DRM_BO_FLAG_MEM_TT |
+ DRM_BO_FLAG_NO_EVICT,
+ DRM_BO_HINT_DONT_FENCE,
+ 1,
+ 0,
+ &dev_priv->ring_buffer_object);
+ if (ret) {
+ return ret;
+ }
+ memset(&dev_priv->ring_buffer_map, 0, sizeof(struct drm_bo_kmap_obj));
+ ret = drm_bo_kmap(dev_priv->ring_buffer_object,
+ dev_priv->ring_buffer_object->mem.mm_node->start,
+ dev_priv->ring_buffer_object->mem.num_pages,
+ &dev_priv->ring_buffer_map);
+ if (ret) {
+ DRM_ERROR("[radeon_ms] error mapping ring buffer: %d\n", ret);
+ return ret;
+ }
+ dev_priv->ring_buffer = dev_priv->ring_buffer_map.virtual;
+ dev_priv->write_back_area =
+ &dev_priv->ring_buffer[dev_priv->ring_buffer_size >> 2];
+ /* setup write back offset */
+ state->scratch_umsk = 0x7;
+ state->scratch_addr =
+ REG_S(SCRATCH_ADDR, SCRATCH_ADDR,
+ (dev_priv->ring_buffer_object->offset +
+ dev_priv->ring_buffer_size +
+ dev_priv->gpu_gart_start) >> 5);
+ MMIO_W(SCRATCH_ADDR, state->scratch_addr);
+ MMIO_W(SCRATCH_UMSK, REG_S(SCRATCH_UMSK, SCRATCH_UMSK, 0x7));
+ DRM_INFO("[radeon_ms] write back at 0x%08X in gpu space\n",
+ MMIO_R(SCRATCH_ADDR));
+ dev_priv->write_back = radeon_ms_test_write_back(dev);
+
+ /* stop cp so it's in know state */
+ radeon_ms_cp_stop(dev);
+ if (dev_priv->ring_rptr) {
+ DRM_INFO("[radeon_ms] failed to set cp read ptr to 0\n");
+ } else {
+ DRM_INFO("[radeon_ms] set cp read ptr to 0\n");
+ }
+ dev_priv->ring_mask = (dev_priv->ring_buffer_size / 4) - 1;
+
+ /* load microcode */
+ DRM_INFO("[radeon_ms] load microcode\n");
+ radeon_ms_load_mc(dev);
+ /* initialize CP registers */
+ state->cp_rb_cntl =
+ REG_S(CP_RB_CNTL, RB_BUFSZ,
+ drm_order(dev_priv->ring_buffer_size / 8)) |
+ REG_S(CP_RB_CNTL, RB_BLKSZ, drm_order(4096 / 8)) |
+ REG_S(CP_RB_CNTL, MAX_FETCH, 2);
+ if (!dev_priv->write_back) {
+ state->cp_rb_cntl |= CP_RB_CNTL__RB_NO_UPDATE;
+ }
+ state->cp_rb_base =
+ REG_S(CP_RB_BASE, RB_BASE,
+ (dev_priv->ring_buffer_object->offset +
+ dev_priv->gpu_gart_start) >> 2);
+ /* read ptr writeback just after the
+ * 8 scratch registers 32 = 8*4 */
+ state->cp_rb_rptr_addr =
+ REG_S(CP_RB_RPTR_ADDR, RB_RPTR_ADDR,
+ (dev_priv->ring_buffer_object->offset +
+ dev_priv->ring_buffer_size + 32 +
+ dev_priv->gpu_gart_start) >> 2);
+ state->cp_rb_wptr = dev_priv->ring_wptr;
+ state->cp_rb_wptr_delay =
+ REG_S(CP_RB_WPTR_DELAY, PRE_WRITE_TIMER, 64) |
+ REG_S(CP_RB_WPTR_DELAY, PRE_WRITE_LIMIT, 8);
+ state->cp_rb_wptr_delay = 0;
+
+ radeon_ms_cp_restore(dev, state);
+ DRM_INFO("[radeon_ms] ring buffer at 0x%08X in gpu space\n",
+ MMIO_R(CP_RB_BASE));
+
+ /* compute free space */
+ dev_priv->ring_free = 0;
+ ret = radeon_ms_cp_wait(dev, 64);
+ if (ret) {
+ /* we shouldn't fail here */
+ DRM_INFO("[radeon_ms] failed to get ring free space\n");
+ return ret;
+ }
+ DRM_INFO("[radeon_ms] free ring size: %d\n", dev_priv->ring_free * 4);
+
+ MMIO_W(CP_CSQ_CNTL, REG_S(CP_CSQ_CNTL, CSQ_MODE,
+ CSQ_MODE__CSQ_PRIBM_INDBM));
+ if (!radeon_ms_test_ring_buffer(dev)) {
+ DRM_INFO("[radeon_ms] cp doesn't work\n");
+ /* disable ring should wait idle before */
+ radeon_ms_cp_stop(dev);
+ return -EBUSY;
+ }
+ /* waaooo the cp is ready & working */
+ DRM_INFO("[radeon_ms] cp ready, enjoy\n");
+ dev_priv->cp_ready = 1;
+ return 0;
+}
+
+void radeon_ms_cp_restore(struct drm_device *dev, struct radeon_state *state)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ radeon_ms_wait_for_idle(dev);
+ MMIO_W(SCRATCH_ADDR, state->scratch_addr);
+ MMIO_W(SCRATCH_UMSK, state->scratch_umsk);
+ MMIO_W(CP_RB_BASE, state->cp_rb_base);
+ MMIO_W(CP_RB_RPTR_ADDR, state->cp_rb_rptr_addr);
+ MMIO_W(CP_RB_WPTR_DELAY, state->cp_rb_wptr_delay);
+ MMIO_W(CP_RB_CNTL, state->cp_rb_cntl);
+ /* Sync everything up */
+ MMIO_W(ISYNC_CNTL, ISYNC_CNTL__ISYNC_ANY2D_IDLE3D |
+ ISYNC_CNTL__ISYNC_ANY3D_IDLE2D |
+ ISYNC_CNTL__ISYNC_WAIT_IDLEGUI |
+ ISYNC_CNTL__ISYNC_CPSCRATCH_IDLEGUI);
+}
+
+void radeon_ms_cp_save(struct drm_device *dev, struct radeon_state *state)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ state->scratch_addr = MMIO_R(SCRATCH_ADDR);
+ state->scratch_umsk = MMIO_R(SCRATCH_UMSK);
+ state->cp_rb_base = MMIO_R(CP_RB_BASE);
+ state->cp_rb_rptr_addr = MMIO_R(CP_RB_RPTR_ADDR);
+ state->cp_rb_wptr_delay = MMIO_R(CP_RB_WPTR_DELAY);
+ state->cp_rb_wptr = MMIO_R(CP_RB_WPTR);
+ state->cp_rb_cntl = MMIO_R(CP_RB_CNTL);
+}
+
+void radeon_ms_cp_stop(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ MMIO_W(CP_CSQ_CNTL, REG_S(CP_CSQ_CNTL, CSQ_MODE,
+ CSQ_MODE__CSQ_PRIDIS_INDDIS));
+ MMIO_W(CP_RB_CNTL, CP_RB_CNTL__RB_RPTR_WR_ENA);
+ MMIO_W(CP_RB_RPTR_WR, 0);
+ MMIO_W(CP_RB_WPTR, 0);
+ DRM_UDELAY(5);
+ dev_priv->ring_wptr = dev_priv->ring_rptr = MMIO_R(CP_RB_RPTR);
+ MMIO_W(CP_RB_WPTR, dev_priv->ring_wptr);
+}
+
+int radeon_ms_cp_wait(struct drm_device *dev, int n)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t i, last_rptr, p = 0;
+
+ last_rptr = MMIO_R(CP_RB_RPTR);
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ dev_priv->ring_rptr = MMIO_R(CP_RB_RPTR);
+ if (last_rptr != dev_priv->ring_rptr) {
+ /* the ring is progressing no lockup */
+ p = 1;
+ }
+ dev_priv->ring_free = (((int)dev_priv->ring_rptr) -
+ ((int)dev_priv->ring_wptr));
+ if (dev_priv->ring_free <= 0)
+ dev_priv->ring_free += (dev_priv->ring_buffer_size / 4);
+ if (dev_priv->ring_free > n)
+ return 0;
+ last_rptr = dev_priv->ring_rptr;
+ DRM_UDELAY(1);
+ }
+ if (p) {
+ DRM_INFO("[radeon_ms] timed out waiting free slot\n");
+ } else {
+ DRM_INFO("[radeon_ms] cp have lickely locked up\n");
+ }
+ return -EBUSY;
+}
+
+int radeon_ms_ring_emit(struct drm_device *dev, uint32_t *cmd, uint32_t count)
+{
+ static spinlock_t ring_lock = SPIN_LOCK_UNLOCKED;
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t i = 0;
+
+ if (!count)
+ return -EINVAL;
+
+ spin_lock(&ring_lock);
+ if (dev_priv->ring_free <= (count)) {
+ spin_unlock(&ring_lock);
+ return -EBUSY;
+ }
+ dev_priv->ring_free -= count;
+ for (i = 0; i < count; i++) {
+ dev_priv->ring_buffer[dev_priv->ring_wptr] = cmd[i];
+ dev_priv->ring_wptr++;
+ dev_priv->ring_wptr &= dev_priv->ring_mask;
+ }
+ /* commit ring */
+ DRM_MEMORYBARRIER();
+ MMIO_W(CP_RB_WPTR, REG_S(CP_RB_WPTR, RB_WPTR, dev_priv->ring_wptr));
+ /* read from PCI bus to ensure correct posting */
+ MMIO_R(CP_RB_WPTR);
+ spin_unlock(&ring_lock);
+ return 0;
+}
diff --git a/shared-core/radeon_ms_cp_mc.c b/shared-core/radeon_ms_cp_mc.c
new file mode 100644
index 00000000..f0397d87
--- /dev/null
+++ b/shared-core/radeon_ms_cp_mc.c
@@ -0,0 +1,801 @@
+/*
+ * Copyright 2007 Advanced Micro Devices, Inc.
+ *
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "radeon_ms.h"
+
+/* CP microcode (from ATI) */
+
+const uint32_t radeon_cp_microcode[] = {
+ 0x21007000, 0000000000,
+ 0x20007000, 0000000000,
+ 0x000000b4, 0x00000004,
+ 0x000000b8, 0x00000004,
+ 0x6f5b4d4c, 0000000000,
+ 0x4c4c427f, 0000000000,
+ 0x5b568a92, 0000000000,
+ 0x4ca09c6d, 0000000000,
+ 0xad4c4c4c, 0000000000,
+ 0x4ce1af3d, 0000000000,
+ 0xd8afafaf, 0000000000,
+ 0xd64c4cdc, 0000000000,
+ 0x4cd10d10, 0000000000,
+ 0x000f0000, 0x00000016,
+ 0x362f242d, 0000000000,
+ 0x00000012, 0x00000004,
+ 0x000f0000, 0x00000016,
+ 0x362f282d, 0000000000,
+ 0x000380e7, 0x00000002,
+ 0x04002c97, 0x00000002,
+ 0x000f0001, 0x00000016,
+ 0x333a3730, 0000000000,
+ 0x000077ef, 0x00000002,
+ 0x00061000, 0x00000002,
+ 0x00000021, 0x0000001a,
+ 0x00004000, 0x0000001e,
+ 0x00061000, 0x00000002,
+ 0x00000021, 0x0000001a,
+ 0x00004000, 0x0000001e,
+ 0x00061000, 0x00000002,
+ 0x00000021, 0x0000001a,
+ 0x00004000, 0x0000001e,
+ 0x00000017, 0x00000004,
+ 0x0003802b, 0x00000002,
+ 0x040067e0, 0x00000002,
+ 0x00000017, 0x00000004,
+ 0x000077e0, 0x00000002,
+ 0x00065000, 0x00000002,
+ 0x000037e1, 0x00000002,
+ 0x040067e1, 0x00000006,
+ 0x000077e0, 0x00000002,
+ 0x000077e1, 0x00000002,
+ 0x000077e1, 0x00000006,
+ 0xffffffff, 0000000000,
+ 0x10000000, 0000000000,
+ 0x0003802b, 0x00000002,
+ 0x040067e0, 0x00000006,
+ 0x00007675, 0x00000002,
+ 0x00007676, 0x00000002,
+ 0x00007677, 0x00000002,
+ 0x00007678, 0x00000006,
+ 0x0003802c, 0x00000002,
+ 0x04002676, 0x00000002,
+ 0x00007677, 0x00000002,
+ 0x00007678, 0x00000006,
+ 0x0000002f, 0x00000018,
+ 0x0000002f, 0x00000018,
+ 0000000000, 0x00000006,
+ 0x00000030, 0x00000018,
+ 0x00000030, 0x00000018,
+ 0000000000, 0x00000006,
+ 0x01605000, 0x00000002,
+ 0x00065000, 0x00000002,
+ 0x00098000, 0x00000002,
+ 0x00061000, 0x00000002,
+ 0x64c0603e, 0x00000004,
+ 0x000380e6, 0x00000002,
+ 0x040025c5, 0x00000002,
+ 0x00080000, 0x00000016,
+ 0000000000, 0000000000,
+ 0x0400251d, 0x00000002,
+ 0x00007580, 0x00000002,
+ 0x00067581, 0x00000002,
+ 0x04002580, 0x00000002,
+ 0x00067581, 0x00000002,
+ 0x00000049, 0x00000004,
+ 0x00005000, 0000000000,
+ 0x000380e6, 0x00000002,
+ 0x040025c5, 0x00000002,
+ 0x00061000, 0x00000002,
+ 0x0000750e, 0x00000002,
+ 0x00019000, 0x00000002,
+ 0x00011055, 0x00000014,
+ 0x00000055, 0x00000012,
+ 0x0400250f, 0x00000002,
+ 0x0000504f, 0x00000004,
+ 0x000380e6, 0x00000002,
+ 0x040025c5, 0x00000002,
+ 0x00007565, 0x00000002,
+ 0x00007566, 0x00000002,
+ 0x00000058, 0x00000004,
+ 0x000380e6, 0x00000002,
+ 0x040025c5, 0x00000002,
+ 0x01e655b4, 0x00000002,
+ 0x4401b0e4, 0x00000002,
+ 0x01c110e4, 0x00000002,
+ 0x26667066, 0x00000018,
+ 0x040c2565, 0x00000002,
+ 0x00000066, 0x00000018,
+ 0x04002564, 0x00000002,
+ 0x00007566, 0x00000002,
+ 0x0000005d, 0x00000004,
+ 0x00401069, 0x00000008,
+ 0x00101000, 0x00000002,
+ 0x000d80ff, 0x00000002,
+ 0x0080006c, 0x00000008,
+ 0x000f9000, 0x00000002,
+ 0x000e00ff, 0x00000002,
+ 0000000000, 0x00000006,
+ 0x0000008f, 0x00000018,
+ 0x0000005b, 0x00000004,
+ 0x000380e6, 0x00000002,
+ 0x040025c5, 0x00000002,
+ 0x00007576, 0x00000002,
+ 0x00065000, 0x00000002,
+ 0x00009000, 0x00000002,
+ 0x00041000, 0x00000002,
+ 0x0c00350e, 0x00000002,
+ 0x00049000, 0x00000002,
+ 0x00051000, 0x00000002,
+ 0x01e785f8, 0x00000002,
+ 0x00200000, 0x00000002,
+ 0x0060007e, 0x0000000c,
+ 0x00007563, 0x00000002,
+ 0x006075f0, 0x00000021,
+ 0x20007073, 0x00000004,
+ 0x00005073, 0x00000004,
+ 0x000380e6, 0x00000002,
+ 0x040025c5, 0x00000002,
+ 0x00007576, 0x00000002,
+ 0x00007577, 0x00000002,
+ 0x0000750e, 0x00000002,
+ 0x0000750f, 0x00000002,
+ 0x00a05000, 0x00000002,
+ 0x00600083, 0x0000000c,
+ 0x006075f0, 0x00000021,
+ 0x000075f8, 0x00000002,
+ 0x00000083, 0x00000004,
+ 0x000a750e, 0x00000002,
+ 0x000380e6, 0x00000002,
+ 0x040025c5, 0x00000002,
+ 0x0020750f, 0x00000002,
+ 0x00600086, 0x00000004,
+ 0x00007570, 0x00000002,
+ 0x00007571, 0x00000002,
+ 0x00007572, 0x00000006,
+ 0x000380e6, 0x00000002,
+ 0x040025c5, 0x00000002,
+ 0x00005000, 0x00000002,
+ 0x00a05000, 0x00000002,
+ 0x00007568, 0x00000002,
+ 0x00061000, 0x00000002,
+ 0x00000095, 0x0000000c,
+ 0x00058000, 0x00000002,
+ 0x0c607562, 0x00000002,
+ 0x00000097, 0x00000004,
+ 0x000380e6, 0x00000002,
+ 0x040025c5, 0x00000002,
+ 0x00600096, 0x00000004,
+ 0x400070e5, 0000000000,
+ 0x000380e6, 0x00000002,
+ 0x040025c5, 0x00000002,
+ 0x000380e5, 0x00000002,
+ 0x000000a8, 0x0000001c,
+ 0x000650aa, 0x00000018,
+ 0x040025bb, 0x00000002,
+ 0x000610ab, 0x00000018,
+ 0x040075bc, 0000000000,
+ 0x000075bb, 0x00000002,
+ 0x000075bc, 0000000000,
+ 0x00090000, 0x00000006,
+ 0x00090000, 0x00000002,
+ 0x000d8002, 0x00000006,
+ 0x00007832, 0x00000002,
+ 0x00005000, 0x00000002,
+ 0x000380e7, 0x00000002,
+ 0x04002c97, 0x00000002,
+ 0x00007820, 0x00000002,
+ 0x00007821, 0x00000002,
+ 0x00007800, 0000000000,
+ 0x01200000, 0x00000002,
+ 0x20077000, 0x00000002,
+ 0x01200000, 0x00000002,
+ 0x20007000, 0x00000002,
+ 0x00061000, 0x00000002,
+ 0x0120751b, 0x00000002,
+ 0x8040750a, 0x00000002,
+ 0x8040750b, 0x00000002,
+ 0x00110000, 0x00000002,
+ 0x000380e5, 0x00000002,
+ 0x000000c6, 0x0000001c,
+ 0x000610ab, 0x00000018,
+ 0x844075bd, 0x00000002,
+ 0x000610aa, 0x00000018,
+ 0x840075bb, 0x00000002,
+ 0x000610ab, 0x00000018,
+ 0x844075bc, 0x00000002,
+ 0x000000c9, 0x00000004,
+ 0x804075bd, 0x00000002,
+ 0x800075bb, 0x00000002,
+ 0x804075bc, 0x00000002,
+ 0x00108000, 0x00000002,
+ 0x01400000, 0x00000002,
+ 0x006000cd, 0x0000000c,
+ 0x20c07000, 0x00000020,
+ 0x000000cf, 0x00000012,
+ 0x00800000, 0x00000006,
+ 0x0080751d, 0x00000006,
+ 0000000000, 0000000000,
+ 0x0000775c, 0x00000002,
+ 0x00a05000, 0x00000002,
+ 0x00661000, 0x00000002,
+ 0x0460275d, 0x00000020,
+ 0x00004000, 0000000000,
+ 0x01e00830, 0x00000002,
+ 0x21007000, 0000000000,
+ 0x6464614d, 0000000000,
+ 0x69687420, 0000000000,
+ 0x00000073, 0000000000,
+ 0000000000, 0000000000,
+ 0x00005000, 0x00000002,
+ 0x000380d0, 0x00000002,
+ 0x040025e0, 0x00000002,
+ 0x000075e1, 0000000000,
+ 0x00000001, 0000000000,
+ 0x000380e0, 0x00000002,
+ 0x04002394, 0x00000002,
+ 0x00005000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0x00000008, 0000000000,
+ 0x00000004, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+};
+
+const uint32_t r200_cp_microcode[] = {
+ 0x21007000, 0000000000,
+ 0x20007000, 0000000000,
+ 0x000000ab, 0x00000004,
+ 0x000000af, 0x00000004,
+ 0x66544a49, 0000000000,
+ 0x49494174, 0000000000,
+ 0x54517d83, 0000000000,
+ 0x498d8b64, 0000000000,
+ 0x49494949, 0000000000,
+ 0x49da493c, 0000000000,
+ 0x49989898, 0000000000,
+ 0xd34949d5, 0000000000,
+ 0x9dc90e11, 0000000000,
+ 0xce9b9b9b, 0000000000,
+ 0x000f0000, 0x00000016,
+ 0x352e232c, 0000000000,
+ 0x00000013, 0x00000004,
+ 0x000f0000, 0x00000016,
+ 0x352e272c, 0000000000,
+ 0x000f0001, 0x00000016,
+ 0x3239362f, 0000000000,
+ 0x000077ef, 0x00000002,
+ 0x00061000, 0x00000002,
+ 0x00000020, 0x0000001a,
+ 0x00004000, 0x0000001e,
+ 0x00061000, 0x00000002,
+ 0x00000020, 0x0000001a,
+ 0x00004000, 0x0000001e,
+ 0x00061000, 0x00000002,
+ 0x00000020, 0x0000001a,
+ 0x00004000, 0x0000001e,
+ 0x00000016, 0x00000004,
+ 0x0003802a, 0x00000002,
+ 0x040067e0, 0x00000002,
+ 0x00000016, 0x00000004,
+ 0x000077e0, 0x00000002,
+ 0x00065000, 0x00000002,
+ 0x000037e1, 0x00000002,
+ 0x040067e1, 0x00000006,
+ 0x000077e0, 0x00000002,
+ 0x000077e1, 0x00000002,
+ 0x000077e1, 0x00000006,
+ 0xffffffff, 0000000000,
+ 0x10000000, 0000000000,
+ 0x0003802a, 0x00000002,
+ 0x040067e0, 0x00000006,
+ 0x00007675, 0x00000002,
+ 0x00007676, 0x00000002,
+ 0x00007677, 0x00000002,
+ 0x00007678, 0x00000006,
+ 0x0003802b, 0x00000002,
+ 0x04002676, 0x00000002,
+ 0x00007677, 0x00000002,
+ 0x00007678, 0x00000006,
+ 0x0000002e, 0x00000018,
+ 0x0000002e, 0x00000018,
+ 0000000000, 0x00000006,
+ 0x0000002f, 0x00000018,
+ 0x0000002f, 0x00000018,
+ 0000000000, 0x00000006,
+ 0x01605000, 0x00000002,
+ 0x00065000, 0x00000002,
+ 0x00098000, 0x00000002,
+ 0x00061000, 0x00000002,
+ 0x64c0603d, 0x00000004,
+ 0x00080000, 0x00000016,
+ 0000000000, 0000000000,
+ 0x0400251d, 0x00000002,
+ 0x00007580, 0x00000002,
+ 0x00067581, 0x00000002,
+ 0x04002580, 0x00000002,
+ 0x00067581, 0x00000002,
+ 0x00000046, 0x00000004,
+ 0x00005000, 0000000000,
+ 0x00061000, 0x00000002,
+ 0x0000750e, 0x00000002,
+ 0x00019000, 0x00000002,
+ 0x00011055, 0x00000014,
+ 0x00000055, 0x00000012,
+ 0x0400250f, 0x00000002,
+ 0x0000504a, 0x00000004,
+ 0x00007565, 0x00000002,
+ 0x00007566, 0x00000002,
+ 0x00000051, 0x00000004,
+ 0x01e655b4, 0x00000002,
+ 0x4401b0dc, 0x00000002,
+ 0x01c110dc, 0x00000002,
+ 0x2666705d, 0x00000018,
+ 0x040c2565, 0x00000002,
+ 0x0000005d, 0x00000018,
+ 0x04002564, 0x00000002,
+ 0x00007566, 0x00000002,
+ 0x00000054, 0x00000004,
+ 0x00401060, 0x00000008,
+ 0x00101000, 0x00000002,
+ 0x000d80ff, 0x00000002,
+ 0x00800063, 0x00000008,
+ 0x000f9000, 0x00000002,
+ 0x000e00ff, 0x00000002,
+ 0000000000, 0x00000006,
+ 0x00000080, 0x00000018,
+ 0x00000054, 0x00000004,
+ 0x00007576, 0x00000002,
+ 0x00065000, 0x00000002,
+ 0x00009000, 0x00000002,
+ 0x00041000, 0x00000002,
+ 0x0c00350e, 0x00000002,
+ 0x00049000, 0x00000002,
+ 0x00051000, 0x00000002,
+ 0x01e785f8, 0x00000002,
+ 0x00200000, 0x00000002,
+ 0x00600073, 0x0000000c,
+ 0x00007563, 0x00000002,
+ 0x006075f0, 0x00000021,
+ 0x20007068, 0x00000004,
+ 0x00005068, 0x00000004,
+ 0x00007576, 0x00000002,
+ 0x00007577, 0x00000002,
+ 0x0000750e, 0x00000002,
+ 0x0000750f, 0x00000002,
+ 0x00a05000, 0x00000002,
+ 0x00600076, 0x0000000c,
+ 0x006075f0, 0x00000021,
+ 0x000075f8, 0x00000002,
+ 0x00000076, 0x00000004,
+ 0x000a750e, 0x00000002,
+ 0x0020750f, 0x00000002,
+ 0x00600079, 0x00000004,
+ 0x00007570, 0x00000002,
+ 0x00007571, 0x00000002,
+ 0x00007572, 0x00000006,
+ 0x00005000, 0x00000002,
+ 0x00a05000, 0x00000002,
+ 0x00007568, 0x00000002,
+ 0x00061000, 0x00000002,
+ 0x00000084, 0x0000000c,
+ 0x00058000, 0x00000002,
+ 0x0c607562, 0x00000002,
+ 0x00000086, 0x00000004,
+ 0x00600085, 0x00000004,
+ 0x400070dd, 0000000000,
+ 0x000380dd, 0x00000002,
+ 0x00000093, 0x0000001c,
+ 0x00065095, 0x00000018,
+ 0x040025bb, 0x00000002,
+ 0x00061096, 0x00000018,
+ 0x040075bc, 0000000000,
+ 0x000075bb, 0x00000002,
+ 0x000075bc, 0000000000,
+ 0x00090000, 0x00000006,
+ 0x00090000, 0x00000002,
+ 0x000d8002, 0x00000006,
+ 0x00005000, 0x00000002,
+ 0x00007821, 0x00000002,
+ 0x00007800, 0000000000,
+ 0x00007821, 0x00000002,
+ 0x00007800, 0000000000,
+ 0x01665000, 0x00000002,
+ 0x000a0000, 0x00000002,
+ 0x000671cc, 0x00000002,
+ 0x0286f1cd, 0x00000002,
+ 0x000000a3, 0x00000010,
+ 0x21007000, 0000000000,
+ 0x000000aa, 0x0000001c,
+ 0x00065000, 0x00000002,
+ 0x000a0000, 0x00000002,
+ 0x00061000, 0x00000002,
+ 0x000b0000, 0x00000002,
+ 0x38067000, 0x00000002,
+ 0x000a00a6, 0x00000004,
+ 0x20007000, 0000000000,
+ 0x01200000, 0x00000002,
+ 0x20077000, 0x00000002,
+ 0x01200000, 0x00000002,
+ 0x20007000, 0000000000,
+ 0x00061000, 0x00000002,
+ 0x0120751b, 0x00000002,
+ 0x8040750a, 0x00000002,
+ 0x8040750b, 0x00000002,
+ 0x00110000, 0x00000002,
+ 0x000380dd, 0x00000002,
+ 0x000000bd, 0x0000001c,
+ 0x00061096, 0x00000018,
+ 0x844075bd, 0x00000002,
+ 0x00061095, 0x00000018,
+ 0x840075bb, 0x00000002,
+ 0x00061096, 0x00000018,
+ 0x844075bc, 0x00000002,
+ 0x000000c0, 0x00000004,
+ 0x804075bd, 0x00000002,
+ 0x800075bb, 0x00000002,
+ 0x804075bc, 0x00000002,
+ 0x00108000, 0x00000002,
+ 0x01400000, 0x00000002,
+ 0x006000c4, 0x0000000c,
+ 0x20c07000, 0x00000020,
+ 0x000000c6, 0x00000012,
+ 0x00800000, 0x00000006,
+ 0x0080751d, 0x00000006,
+ 0x000025bb, 0x00000002,
+ 0x000040c0, 0x00000004,
+ 0x0000775c, 0x00000002,
+ 0x00a05000, 0x00000002,
+ 0x00661000, 0x00000002,
+ 0x0460275d, 0x00000020,
+ 0x00004000, 0000000000,
+ 0x00007999, 0x00000002,
+ 0x00a05000, 0x00000002,
+ 0x00661000, 0x00000002,
+ 0x0460299b, 0x00000020,
+ 0x00004000, 0000000000,
+ 0x01e00830, 0x00000002,
+ 0x21007000, 0000000000,
+ 0x00005000, 0x00000002,
+ 0x00038042, 0x00000002,
+ 0x040025e0, 0x00000002,
+ 0x000075e1, 0000000000,
+ 0x00000001, 0000000000,
+ 0x000380d9, 0x00000002,
+ 0x04007394, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+};
+
+const uint32_t r300_cp_microcode[] = {
+ 0x4200e000, 0000000000,
+ 0x4000e000, 0000000000,
+ 0x000000af, 0x00000008,
+ 0x000000b3, 0x00000008,
+ 0x6c5a504f, 0000000000,
+ 0x4f4f497a, 0000000000,
+ 0x5a578288, 0000000000,
+ 0x4f91906a, 0000000000,
+ 0x4f4f4f4f, 0000000000,
+ 0x4fe24f44, 0000000000,
+ 0x4f9c9c9c, 0000000000,
+ 0xdc4f4fde, 0000000000,
+ 0xa1cd4f4f, 0000000000,
+ 0xd29d9d9d, 0000000000,
+ 0x4f0f9fd7, 0000000000,
+ 0x000ca000, 0x00000004,
+ 0x000d0012, 0x00000038,
+ 0x0000e8b4, 0x00000004,
+ 0x000d0014, 0x00000038,
+ 0x0000e8b6, 0x00000004,
+ 0x000d0016, 0x00000038,
+ 0x0000e854, 0x00000004,
+ 0x000d0018, 0x00000038,
+ 0x0000e855, 0x00000004,
+ 0x000d001a, 0x00000038,
+ 0x0000e856, 0x00000004,
+ 0x000d001c, 0x00000038,
+ 0x0000e857, 0x00000004,
+ 0x000d001e, 0x00000038,
+ 0x0000e824, 0x00000004,
+ 0x000d0020, 0x00000038,
+ 0x0000e825, 0x00000004,
+ 0x000d0022, 0x00000038,
+ 0x0000e830, 0x00000004,
+ 0x000d0024, 0x00000038,
+ 0x0000f0c0, 0x00000004,
+ 0x000d0026, 0x00000038,
+ 0x0000f0c1, 0x00000004,
+ 0x000d0028, 0x00000038,
+ 0x0000f041, 0x00000004,
+ 0x000d002a, 0x00000038,
+ 0x0000f184, 0x00000004,
+ 0x000d002c, 0x00000038,
+ 0x0000f185, 0x00000004,
+ 0x000d002e, 0x00000038,
+ 0x0000f186, 0x00000004,
+ 0x000d0030, 0x00000038,
+ 0x0000f187, 0x00000004,
+ 0x000d0032, 0x00000038,
+ 0x0000f180, 0x00000004,
+ 0x000d0034, 0x00000038,
+ 0x0000f393, 0x00000004,
+ 0x000d0036, 0x00000038,
+ 0x0000f38a, 0x00000004,
+ 0x000d0038, 0x00000038,
+ 0x0000f38e, 0x00000004,
+ 0x0000e821, 0x00000004,
+ 0x0140a000, 0x00000004,
+ 0x00000043, 0x00000018,
+ 0x00cce800, 0x00000004,
+ 0x001b0001, 0x00000004,
+ 0x08004800, 0x00000004,
+ 0x001b0001, 0x00000004,
+ 0x08004800, 0x00000004,
+ 0x001b0001, 0x00000004,
+ 0x08004800, 0x00000004,
+ 0x0000003a, 0x00000008,
+ 0x0000a000, 0000000000,
+ 0x02c0a000, 0x00000004,
+ 0x000ca000, 0x00000004,
+ 0x00130000, 0x00000004,
+ 0x000c2000, 0x00000004,
+ 0xc980c045, 0x00000008,
+ 0x2000451d, 0x00000004,
+ 0x0000e580, 0x00000004,
+ 0x000ce581, 0x00000004,
+ 0x08004580, 0x00000004,
+ 0x000ce581, 0x00000004,
+ 0x0000004c, 0x00000008,
+ 0x0000a000, 0000000000,
+ 0x000c2000, 0x00000004,
+ 0x0000e50e, 0x00000004,
+ 0x00032000, 0x00000004,
+ 0x00022056, 0x00000028,
+ 0x00000056, 0x00000024,
+ 0x0800450f, 0x00000004,
+ 0x0000a050, 0x00000008,
+ 0x0000e565, 0x00000004,
+ 0x0000e566, 0x00000004,
+ 0x00000057, 0x00000008,
+ 0x03cca5b4, 0x00000004,
+ 0x05432000, 0x00000004,
+ 0x00022000, 0x00000004,
+ 0x4ccce063, 0x00000030,
+ 0x08274565, 0x00000004,
+ 0x00000063, 0x00000030,
+ 0x08004564, 0x00000004,
+ 0x0000e566, 0x00000004,
+ 0x0000005a, 0x00000008,
+ 0x00802066, 0x00000010,
+ 0x00202000, 0x00000004,
+ 0x001b00ff, 0x00000004,
+ 0x01000069, 0x00000010,
+ 0x001f2000, 0x00000004,
+ 0x001c00ff, 0x00000004,
+ 0000000000, 0x0000000c,
+ 0x00000085, 0x00000030,
+ 0x0000005a, 0x00000008,
+ 0x0000e576, 0x00000004,
+ 0x000ca000, 0x00000004,
+ 0x00012000, 0x00000004,
+ 0x00082000, 0x00000004,
+ 0x1800650e, 0x00000004,
+ 0x00092000, 0x00000004,
+ 0x000a2000, 0x00000004,
+ 0x000f0000, 0x00000004,
+ 0x00400000, 0x00000004,
+ 0x00000079, 0x00000018,
+ 0x0000e563, 0x00000004,
+ 0x00c0e5f9, 0x000000c2,
+ 0x0000006e, 0x00000008,
+ 0x0000a06e, 0x00000008,
+ 0x0000e576, 0x00000004,
+ 0x0000e577, 0x00000004,
+ 0x0000e50e, 0x00000004,
+ 0x0000e50f, 0x00000004,
+ 0x0140a000, 0x00000004,
+ 0x0000007c, 0x00000018,
+ 0x00c0e5f9, 0x000000c2,
+ 0x0000007c, 0x00000008,
+ 0x0014e50e, 0x00000004,
+ 0x0040e50f, 0x00000004,
+ 0x00c0007f, 0x00000008,
+ 0x0000e570, 0x00000004,
+ 0x0000e571, 0x00000004,
+ 0x0000e572, 0x0000000c,
+ 0x0000a000, 0x00000004,
+ 0x0140a000, 0x00000004,
+ 0x0000e568, 0x00000004,
+ 0x000c2000, 0x00000004,
+ 0x00000089, 0x00000018,
+ 0x000b0000, 0x00000004,
+ 0x18c0e562, 0x00000004,
+ 0x0000008b, 0x00000008,
+ 0x00c0008a, 0x00000008,
+ 0x000700e4, 0x00000004,
+ 0x00000097, 0x00000038,
+ 0x000ca099, 0x00000030,
+ 0x080045bb, 0x00000004,
+ 0x000c209a, 0x00000030,
+ 0x0800e5bc, 0000000000,
+ 0x0000e5bb, 0x00000004,
+ 0x0000e5bc, 0000000000,
+ 0x00120000, 0x0000000c,
+ 0x00120000, 0x00000004,
+ 0x001b0002, 0x0000000c,
+ 0x0000a000, 0x00000004,
+ 0x0000e821, 0x00000004,
+ 0x0000e800, 0000000000,
+ 0x0000e821, 0x00000004,
+ 0x0000e82e, 0000000000,
+ 0x02cca000, 0x00000004,
+ 0x00140000, 0x00000004,
+ 0x000ce1cc, 0x00000004,
+ 0x050de1cd, 0x00000004,
+ 0x000000a7, 0x00000020,
+ 0x4200e000, 0000000000,
+ 0x000000ae, 0x00000038,
+ 0x000ca000, 0x00000004,
+ 0x00140000, 0x00000004,
+ 0x000c2000, 0x00000004,
+ 0x00160000, 0x00000004,
+ 0x700ce000, 0x00000004,
+ 0x001400aa, 0x00000008,
+ 0x4000e000, 0000000000,
+ 0x02400000, 0x00000004,
+ 0x400ee000, 0x00000004,
+ 0x02400000, 0x00000004,
+ 0x4000e000, 0000000000,
+ 0x000c2000, 0x00000004,
+ 0x0240e51b, 0x00000004,
+ 0x0080e50a, 0x00000005,
+ 0x0080e50b, 0x00000005,
+ 0x00220000, 0x00000004,
+ 0x000700e4, 0x00000004,
+ 0x000000c1, 0x00000038,
+ 0x000c209a, 0x00000030,
+ 0x0880e5bd, 0x00000005,
+ 0x000c2099, 0x00000030,
+ 0x0800e5bb, 0x00000005,
+ 0x000c209a, 0x00000030,
+ 0x0880e5bc, 0x00000005,
+ 0x000000c4, 0x00000008,
+ 0x0080e5bd, 0x00000005,
+ 0x0000e5bb, 0x00000005,
+ 0x0080e5bc, 0x00000005,
+ 0x00210000, 0x00000004,
+ 0x02800000, 0x00000004,
+ 0x00c000c8, 0x00000018,
+ 0x4180e000, 0x00000040,
+ 0x000000ca, 0x00000024,
+ 0x01000000, 0x0000000c,
+ 0x0100e51d, 0x0000000c,
+ 0x000045bb, 0x00000004,
+ 0x000080c4, 0x00000008,
+ 0x0000f3ce, 0x00000004,
+ 0x0140a000, 0x00000004,
+ 0x00cc2000, 0x00000004,
+ 0x08c053cf, 0x00000040,
+ 0x00008000, 0000000000,
+ 0x0000f3d2, 0x00000004,
+ 0x0140a000, 0x00000004,
+ 0x00cc2000, 0x00000004,
+ 0x08c053d3, 0x00000040,
+ 0x00008000, 0000000000,
+ 0x0000f39d, 0x00000004,
+ 0x0140a000, 0x00000004,
+ 0x00cc2000, 0x00000004,
+ 0x08c0539e, 0x00000040,
+ 0x00008000, 0000000000,
+ 0x03c00830, 0x00000004,
+ 0x4200e000, 0000000000,
+ 0x0000a000, 0x00000004,
+ 0x200045e0, 0x00000004,
+ 0x0000e5e1, 0000000000,
+ 0x00000001, 0000000000,
+ 0x000700e1, 0x00000004,
+ 0x0800e394, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+ 0000000000, 0000000000,
+};
diff --git a/shared-core/radeon_ms_crtc.c b/shared-core/radeon_ms_crtc.c
new file mode 100644
index 00000000..b2383859
--- /dev/null
+++ b/shared-core/radeon_ms_crtc.c
@@ -0,0 +1,803 @@
+/*
+ * Copyright © 2007 Alex Deucher
+ * Copyright © 2007 Dave Airlie
+ * Copyright © 2007 Michel Dänzer
+ * Copyright © 2007 Jerome Glisse
+ *
+ * All Rights Reserved.
+ *
+ * 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 on 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
+ * THEIR SUPPLIERS 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 "drmP.h"
+#include "drm.h"
+#include "drm_crtc.h"
+#include "radeon_ms.h"
+
+static void radeon_pll1_init(struct drm_radeon_private *dev_priv,
+ struct radeon_state *state);
+static void radeon_pll1_restore(struct drm_radeon_private *dev_priv,
+ struct radeon_state *state);
+static void radeon_pll1_save(struct drm_radeon_private *dev_priv,
+ struct radeon_state *state);
+static void radeon_ms_crtc_load_lut(struct drm_crtc *crtc);
+
+/**
+ * radeon_ms_crtc1_init - initialize CRTC state
+ * @dev_priv: radeon private structure
+ * @state: state structure to initialize to default value
+ *
+ * Initialize CRTC state to default values
+ */
+static void radeon_ms_crtc1_init(struct drm_radeon_private *dev_priv,
+ struct radeon_state *state)
+{
+ state->surface_cntl = SURFACE_CNTL__SURF_TRANSLATION_DIS;
+ state->surface0_info = 0;
+ state->surface0_lower_bound = 0;
+ state->surface0_upper_bound = 0;
+ state->surface1_info = 0;
+ state->surface1_lower_bound = 0;
+ state->surface1_upper_bound = 0;
+ state->surface2_info = 0;
+ state->surface2_lower_bound = 0;
+ state->surface2_upper_bound = 0;
+ state->surface3_info = 0;
+ state->surface3_lower_bound = 0;
+ state->surface3_upper_bound = 0;
+ state->surface4_info = 0;
+ state->surface4_lower_bound = 0;
+ state->surface4_upper_bound = 0;
+ state->surface5_info = 0;
+ state->surface5_lower_bound = 0;
+ state->surface5_upper_bound = 0;
+ state->surface6_info = 0;
+ state->surface6_lower_bound = 0;
+ state->surface6_upper_bound = 0;
+ state->surface7_info = 0;
+ state->surface7_lower_bound = 0;
+ state->surface7_upper_bound = 0;
+ state->crtc_gen_cntl = CRTC_GEN_CNTL__CRTC_EXT_DISP_EN |
+ CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B;
+ state->crtc_ext_cntl = CRTC_EXT_CNTL__VGA_ATI_LINEAR |
+ CRTC_EXT_CNTL__VGA_XCRT_CNT_EN |
+ CRTC_EXT_CNTL__CRT_ON;
+ state->crtc_h_total_disp = 0;
+ state->crtc_h_sync_strt_wid = 0;
+ state->crtc_v_total_disp = 0;
+ state->crtc_v_sync_strt_wid = 0;
+ state->crtc_offset = 0;
+ state->crtc_pitch = 0;
+ state->crtc_more_cntl = 0;
+ state->crtc_tile_x0_y0 = 0;
+ state->crtc_offset_cntl = 0;
+ switch (dev_priv->family) {
+ case CHIP_R100:
+ case CHIP_R200:
+ case CHIP_RV200:
+ case CHIP_RV250:
+ case CHIP_RV280:
+ case CHIP_RS300:
+ break;
+ case CHIP_R300:
+ case CHIP_R350:
+ case CHIP_R360:
+ case CHIP_RV350:
+ case CHIP_RV370:
+ case CHIP_RV380:
+ case CHIP_RS400:
+ case CHIP_RV410:
+ case CHIP_R420:
+ case CHIP_R430:
+ case CHIP_R480:
+ state->crtc_offset_cntl |= REG_S(CRTC_OFFSET_CNTL,
+ CRTC_MICRO_TILE_BUFFER_MODE,
+ CRTC_MICRO_TILE_BUFFER_MODE__DIS);
+ break;
+ default:
+ DRM_ERROR("Unknown radeon family, aborting\n");
+ return;
+ }
+ radeon_pll1_init(dev_priv, state);
+}
+
+/**
+ * radeon_pll1_init - initialize PLL1 state
+ * @dev_priv: radeon private structure
+ * @state: state structure to initialize to default value
+ *
+ * Initialize PLL1 state to default values
+ */
+static void radeon_pll1_init(struct drm_radeon_private *dev_priv,
+ struct radeon_state *state)
+{
+ state->clock_cntl_index = 0;
+ state->ppll_cntl = PPLL_R(PPLL_CNTL);
+ state->ppll_cntl |= PPLL_CNTL__PPLL_ATOMIC_UPDATE_EN |
+ PPLL_CNTL__PPLL_ATOMIC_UPDATE_SYNC |
+ PPLL_CNTL__PPLL_VGA_ATOMIC_UPDATE_EN;
+ state->ppll_cntl &= ~PPLL_CNTL__PPLL_TST_EN;
+ state->ppll_cntl &= ~PPLL_CNTL__PPLL_TCPOFF;
+ state->ppll_cntl &= ~PPLL_CNTL__PPLL_TVCOMAX;
+ state->ppll_cntl &= ~PPLL_CNTL__PPLL_DISABLE_AUTO_RESET;
+ state->ppll_ref_div = 0;
+ state->ppll_ref_div = REG_S(PPLL_REF_DIV, PPLL_REF_DIV, 12) |
+ REG_S(PPLL_REF_DIV, PPLL_REF_DIV_SRC, PPLL_REF_DIV_SRC__XTALIN);
+ state->ppll_div_0 = 0;
+ state->ppll_div_1 = 0;
+ state->ppll_div_2 = 0;
+ state->ppll_div_3 = 0;
+ state->vclk_ecp_cntl = 0;
+ state->htotal_cntl = 0;
+}
+
+/**
+ * radeon_ms_crtc1_restore - restore CRTC state
+ * @dev_priv: radeon private structure
+ * @state: CRTC state to restore
+ */
+void radeon_ms_crtc1_restore(struct drm_device *dev, struct radeon_state *state)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ /* We prevent the CRTC from hitting the memory controller until
+ * fully programmed
+ */
+ MMIO_W(CRTC_GEN_CNTL, ~CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B &
+ state->crtc_gen_cntl);
+ MMIO_W(CRTC_EXT_CNTL, CRTC_EXT_CNTL__CRTC_VSYNC_DIS |
+ CRTC_EXT_CNTL__CRTC_HSYNC_DIS |
+ CRTC_EXT_CNTL__CRTC_DISPLAY_DIS |
+ state->crtc_ext_cntl);
+ MMIO_W(SURFACE_CNTL, state->surface_cntl);
+ MMIO_W(SURFACE0_INFO, state->surface0_info);
+ MMIO_W(SURFACE0_LOWER_BOUND, state->surface0_lower_bound);
+ MMIO_W(SURFACE0_UPPER_BOUND, state->surface0_upper_bound);
+ MMIO_W(SURFACE1_INFO, state->surface1_info);
+ MMIO_W(SURFACE1_LOWER_BOUND, state->surface1_lower_bound);
+ MMIO_W(SURFACE1_UPPER_BOUND, state->surface1_upper_bound);
+ MMIO_W(SURFACE2_INFO, state->surface2_info);
+ MMIO_W(SURFACE2_LOWER_BOUND, state->surface2_lower_bound);
+ MMIO_W(SURFACE2_UPPER_BOUND, state->surface2_upper_bound);
+ MMIO_W(SURFACE3_INFO, state->surface3_info);
+ MMIO_W(SURFACE3_LOWER_BOUND, state->surface3_lower_bound);
+ MMIO_W(SURFACE3_UPPER_BOUND, state->surface3_upper_bound);
+ MMIO_W(SURFACE4_INFO, state->surface4_info);
+ MMIO_W(SURFACE4_LOWER_BOUND, state->surface4_lower_bound);
+ MMIO_W(SURFACE4_UPPER_BOUND, state->surface4_upper_bound);
+ MMIO_W(SURFACE5_INFO, state->surface5_info);
+ MMIO_W(SURFACE5_LOWER_BOUND, state->surface5_lower_bound);
+ MMIO_W(SURFACE5_UPPER_BOUND, state->surface5_upper_bound);
+ MMIO_W(SURFACE6_INFO, state->surface6_info);
+ MMIO_W(SURFACE6_LOWER_BOUND, state->surface6_lower_bound);
+ MMIO_W(SURFACE6_UPPER_BOUND, state->surface6_upper_bound);
+ MMIO_W(SURFACE7_INFO, state->surface7_info);
+ MMIO_W(SURFACE7_LOWER_BOUND, state->surface7_lower_bound);
+ MMIO_W(SURFACE7_UPPER_BOUND, state->surface7_upper_bound);
+ MMIO_W(CRTC_H_TOTAL_DISP, state->crtc_h_total_disp);
+ MMIO_W(CRTC_H_SYNC_STRT_WID, state->crtc_h_sync_strt_wid);
+ MMIO_W(CRTC_V_TOTAL_DISP, state->crtc_v_total_disp);
+ MMIO_W(CRTC_V_SYNC_STRT_WID, state->crtc_v_sync_strt_wid);
+ MMIO_W(FP_H_SYNC_STRT_WID, state->fp_h_sync_strt_wid);
+ MMIO_W(FP_V_SYNC_STRT_WID, state->fp_v_sync_strt_wid);
+ MMIO_W(FP_CRTC_H_TOTAL_DISP, state->fp_crtc_h_total_disp);
+ MMIO_W(FP_CRTC_V_TOTAL_DISP, state->fp_crtc_v_total_disp);
+ MMIO_W(CRTC_TILE_X0_Y0, state->crtc_tile_x0_y0);
+ MMIO_W(CRTC_OFFSET_CNTL, state->crtc_offset_cntl);
+ MMIO_W(CRTC_OFFSET, state->crtc_offset);
+ MMIO_W(CRTC_PITCH, state->crtc_pitch);
+ radeon_pll1_restore(dev_priv, state);
+ MMIO_W(CRTC_MORE_CNTL, state->crtc_more_cntl);
+ MMIO_W(CRTC_GEN_CNTL, state->crtc_gen_cntl);
+ MMIO_W(CRTC_EXT_CNTL, state->crtc_ext_cntl);
+}
+
+/**
+ * radeon_pll1_restore - restore PLL1 state
+ * @dev_priv: radeon private structure
+ * @state: PLL1 state to restore
+ */
+static void radeon_pll1_restore(struct drm_radeon_private *dev_priv,
+ struct radeon_state *state)
+{
+ uint32_t tmp;
+
+ /* switch to gpu clock while programing new clock */
+ MMIO_W(CLOCK_CNTL_INDEX, state->clock_cntl_index);
+ tmp = state->vclk_ecp_cntl;
+ tmp = REG_S(VCLK_ECP_CNTL, VCLK_SRC_SEL, VCLK_SRC_SEL__CPUCLK);
+ PPLL_W(VCLK_ECP_CNTL, tmp);
+ /* reset PLL and update atomicly */
+ state->ppll_cntl |= PPLL_CNTL__PPLL_ATOMIC_UPDATE_EN |
+ PPLL_CNTL__PPLL_ATOMIC_UPDATE_SYNC;
+
+ PPLL_W(PPLL_CNTL, state->ppll_cntl | PPLL_CNTL__PPLL_RESET);
+ PPLL_W(PPLL_REF_DIV, state->ppll_ref_div);
+ PPLL_W(PPLL_DIV_0, state->ppll_div_0);
+ PPLL_W(PPLL_DIV_1, state->ppll_div_1);
+ PPLL_W(PPLL_DIV_2, state->ppll_div_2);
+ PPLL_W(PPLL_DIV_3, state->ppll_div_3);
+ PPLL_W(HTOTAL_CNTL, state->htotal_cntl);
+
+ /* update */
+ PPLL_W(PPLL_REF_DIV, state->ppll_ref_div |
+ PPLL_REF_DIV__PPLL_ATOMIC_UPDATE_W);
+ for (tmp = 0; tmp < 100; tmp++) {
+ if (!(PPLL_REF_DIV__PPLL_ATOMIC_UPDATE_R &
+ PPLL_R(PPLL_REF_DIV))) {
+ break;
+ }
+ DRM_UDELAY(10);
+ }
+ state->ppll_cntl &= ~PPLL_CNTL__PPLL_RESET;
+ PPLL_W(PPLL_CNTL, state->ppll_cntl);
+ PPLL_W(VCLK_ECP_CNTL, state->vclk_ecp_cntl);
+}
+
+/**
+ * radeon_ms_crtc1_save - save CRTC state
+ * @dev_priv: radeon private structure
+ * @state: state where saving current CRTC state
+ */
+void radeon_ms_crtc1_save(struct drm_device *dev, struct radeon_state *state)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ state->surface_cntl = MMIO_R(SURFACE_CNTL);
+ state->surface0_info = MMIO_R(SURFACE0_INFO);
+ state->surface0_lower_bound = MMIO_R(SURFACE0_LOWER_BOUND);
+ state->surface0_upper_bound = MMIO_R(SURFACE0_UPPER_BOUND);
+ state->surface1_info = MMIO_R(SURFACE1_INFO);
+ state->surface1_lower_bound = MMIO_R(SURFACE1_LOWER_BOUND);
+ state->surface1_upper_bound = MMIO_R(SURFACE1_UPPER_BOUND);
+ state->surface2_info = MMIO_R(SURFACE2_INFO);
+ state->surface2_lower_bound = MMIO_R(SURFACE2_LOWER_BOUND);
+ state->surface2_upper_bound = MMIO_R(SURFACE2_UPPER_BOUND);
+ state->surface3_info = MMIO_R(SURFACE3_INFO);
+ state->surface3_lower_bound = MMIO_R(SURFACE3_LOWER_BOUND);
+ state->surface3_upper_bound = MMIO_R(SURFACE3_UPPER_BOUND);
+ state->surface4_info = MMIO_R(SURFACE4_INFO);
+ state->surface4_lower_bound = MMIO_R(SURFACE4_LOWER_BOUND);
+ state->surface4_upper_bound = MMIO_R(SURFACE4_UPPER_BOUND);
+ state->surface5_info = MMIO_R(SURFACE5_INFO);
+ state->surface5_lower_bound = MMIO_R(SURFACE5_LOWER_BOUND);
+ state->surface5_upper_bound = MMIO_R(SURFACE5_UPPER_BOUND);
+ state->surface6_info = MMIO_R(SURFACE6_INFO);
+ state->surface6_lower_bound = MMIO_R(SURFACE6_LOWER_BOUND);
+ state->surface6_upper_bound = MMIO_R(SURFACE6_UPPER_BOUND);
+ state->surface7_info = MMIO_R(SURFACE7_INFO);
+ state->surface7_lower_bound = MMIO_R(SURFACE7_LOWER_BOUND);
+ state->surface7_upper_bound = MMIO_R(SURFACE7_UPPER_BOUND);
+ state->crtc_gen_cntl = MMIO_R(CRTC_GEN_CNTL);
+ state->crtc_ext_cntl = MMIO_R(CRTC_EXT_CNTL);
+ state->crtc_h_total_disp = MMIO_R(CRTC_H_TOTAL_DISP);
+ state->crtc_h_sync_strt_wid = MMIO_R(CRTC_H_SYNC_STRT_WID);
+ state->crtc_v_total_disp = MMIO_R(CRTC_V_TOTAL_DISP);
+ state->crtc_v_sync_strt_wid = MMIO_R(CRTC_V_SYNC_STRT_WID);
+ state->fp_h_sync_strt_wid = MMIO_R(FP_H_SYNC_STRT_WID);
+ state->fp_v_sync_strt_wid = MMIO_R(FP_V_SYNC_STRT_WID);
+ state->fp_crtc_h_total_disp = MMIO_R(FP_CRTC_H_TOTAL_DISP);
+ state->fp_crtc_v_total_disp = MMIO_R(FP_CRTC_V_TOTAL_DISP);
+ state->crtc_offset = MMIO_R(CRTC_OFFSET);
+ state->crtc_offset_cntl = MMIO_R(CRTC_OFFSET_CNTL);
+ state->crtc_pitch = MMIO_R(CRTC_PITCH);
+ state->crtc_more_cntl = MMIO_R(CRTC_MORE_CNTL);
+ state->crtc_tile_x0_y0 = MMIO_R(CRTC_TILE_X0_Y0);
+ radeon_pll1_save(dev_priv,state);
+}
+
+/**
+ * radeon_pll1_save - save PLL1 state
+ * @dev_priv: radeon private structure
+ * @state: state where saving current PLL1 state
+ */
+static void radeon_pll1_save(struct drm_radeon_private *dev_priv,
+ struct radeon_state *state)
+{
+ state->clock_cntl_index = MMIO_R(CLOCK_CNTL_INDEX);
+ state->ppll_cntl = PPLL_R(PPLL_CNTL);
+ state->ppll_ref_div = PPLL_R(PPLL_REF_DIV);
+ state->ppll_div_0 = PPLL_R(PPLL_DIV_0);
+ state->ppll_div_1 = PPLL_R(PPLL_DIV_1);
+ state->ppll_div_2 = PPLL_R(PPLL_DIV_2);
+ state->ppll_div_3 = PPLL_R(PPLL_DIV_3);
+ state->vclk_ecp_cntl = PPLL_R(VCLK_ECP_CNTL);
+ state->htotal_cntl = PPLL_R(HTOTAL_CNTL);
+}
+
+static void radeon_ms_crtc1_dpms(struct drm_crtc *crtc, int mode)
+{
+ struct drm_radeon_private *dev_priv = crtc->dev->dev_private;
+ struct radeon_state *state = &dev_priv->driver_state;
+
+ state->crtc_gen_cntl &= ~CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B;
+ state->crtc_ext_cntl &= ~CRTC_EXT_CNTL__CRTC_DISPLAY_DIS;
+ state->crtc_ext_cntl &= ~CRTC_EXT_CNTL__CRTC_HSYNC_DIS;
+ state->crtc_ext_cntl &= ~CRTC_EXT_CNTL__CRTC_VSYNC_DIS;
+ switch(mode) {
+ case DPMSModeOn:
+ break;
+ case DPMSModeStandby:
+ state->crtc_ext_cntl |=
+ CRTC_EXT_CNTL__CRTC_DISPLAY_DIS |
+ CRTC_EXT_CNTL__CRTC_HSYNC_DIS;
+ break;
+ case DPMSModeSuspend:
+ state->crtc_ext_cntl |=
+ CRTC_EXT_CNTL__CRTC_DISPLAY_DIS |
+ CRTC_EXT_CNTL__CRTC_VSYNC_DIS;
+ break;
+ case DPMSModeOff:
+ state->crtc_ext_cntl |=
+ CRTC_EXT_CNTL__CRTC_DISPLAY_DIS |
+ CRTC_EXT_CNTL__CRTC_HSYNC_DIS |
+ CRTC_EXT_CNTL__CRTC_VSYNC_DIS;
+ state->crtc_gen_cntl |=
+ CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B;
+ break;
+ }
+ MMIO_W(CRTC_GEN_CNTL, state->crtc_gen_cntl);
+ MMIO_W(CRTC_EXT_CNTL, state->crtc_ext_cntl);
+
+ dev_priv->crtc1_dpms = mode;
+ /* FIXME: once adding crtc2 remove this */
+ dev_priv->crtc2_dpms = mode;
+ radeon_ms_gpu_dpms(crtc->dev);
+
+ if (mode != DPMSModeOff) {
+ radeon_ms_crtc_load_lut(crtc);
+ }
+}
+
+static bool radeon_ms_crtc_mode_fixup(struct drm_crtc *crtc,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ return true;
+}
+
+static void radeon_ms_crtc_mode_prepare(struct drm_crtc *crtc)
+{
+ crtc->funcs->dpms(crtc, DPMSModeOff);
+}
+
+/* compute PLL registers values for requested video mode */
+static int radeon_pll1_constraint(struct drm_device *dev,
+ int clock, int rdiv,
+ int fdiv, int pdiv,
+ int rfrq, int pfrq)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ int dfrq;
+
+ if (rdiv < 2 || fdiv < 4) {
+ return 0;
+ }
+ dfrq = rfrq / rdiv;
+ if (dfrq < 2000 || dfrq > 3300) {
+ return 0;
+ }
+ if (pfrq < dev_priv->properties.pll_min_pll_freq ||
+ pfrq > dev_priv->properties.pll_max_pll_freq) {
+ return 0;
+ }
+ return 1;
+}
+
+static void radeon_pll1_compute(struct drm_crtc *crtc,
+ struct drm_display_mode *mode)
+{
+ struct {
+ int divider;
+ int divider_id;
+ } *post_div, post_divs[] = {
+ /* From RAGE 128 VR/RAGE 128 GL Register
+ * Reference Manual (Technical Reference
+ * Manual P/N RRG-G04100-C Rev. 0.04), page
+ * 3-17 (PLL_DIV_[3:0]).
+ */
+ { 1, 0 }, /* VCLK_SRC */
+ { 2, 1 }, /* VCLK_SRC/2 */
+ { 4, 2 }, /* VCLK_SRC/4 */
+ { 8, 3 }, /* VCLK_SRC/8 */
+ { 3, 4 }, /* VCLK_SRC/3 */
+ { 16, 5 }, /* VCLK_SRC/16 */
+ { 6, 6 }, /* VCLK_SRC/6 */
+ { 12, 7 }, /* VCLK_SRC/12 */
+ { 0, 0 }
+ };
+ struct drm_radeon_private *dev_priv = crtc->dev->dev_private;
+ struct radeon_state *state = &dev_priv->driver_state;
+ int clock = mode->clock;
+ int rfrq = dev_priv->properties.pll_reference_freq;
+ int pdiv = 1;
+ int pdiv_id = 0;
+ int rdiv_best = 2;
+ int fdiv_best = 4;
+ int tfrq_best = 0;
+ int pfrq_best = 0;
+ int diff_cpfrq_best = 350000;
+ int vco_freq;
+ int vco_gain;
+ int rdiv = 0;
+ int fdiv = 0;
+ int tfrq = 35000;
+ int pfrq = 35000;
+ int diff_cpfrq = 350000;
+
+ /* clamp frequency into pll [min; max] frequency range */
+ if (clock > dev_priv->properties.pll_max_pll_freq) {
+ clock = dev_priv->properties.pll_max_pll_freq;
+ }
+ if ((clock * 12) < dev_priv->properties.pll_min_pll_freq) {
+ clock = dev_priv->properties.pll_min_pll_freq / 12;
+ }
+
+ /* maximize pll_ref_div while staying in boundary and minimizing
+ * the difference btw target frequency and programmed frequency */
+ for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
+ if (post_div->divider == 0) {
+ break;
+ }
+ tfrq = clock * post_div->divider;
+ for (fdiv = 1023; fdiv >= 4; fdiv--) {
+ rdiv = (fdiv * rfrq) / tfrq;
+ if (radeon_pll1_constraint(crtc->dev, clock, rdiv,
+ fdiv, pdiv, rfrq, tfrq)) {
+ pfrq = (fdiv * rfrq) / rdiv;
+ diff_cpfrq = pfrq - tfrq;
+ if ((diff_cpfrq >= 0 &&
+ diff_cpfrq < diff_cpfrq_best) ||
+ (diff_cpfrq == diff_cpfrq_best &&
+ rdiv > rdiv_best)) {
+ rdiv_best = rdiv;
+ fdiv_best = fdiv;
+ tfrq_best = tfrq;
+ pfrq_best = pfrq;
+ pdiv = post_div->divider;
+ pdiv_id = post_div->divider_id;
+ diff_cpfrq_best = diff_cpfrq;
+ }
+ }
+ }
+ }
+ state->ppll_ref_div =
+ REG_S(PPLL_REF_DIV, PPLL_REF_DIV, rdiv_best) |
+ REG_S(PPLL_REF_DIV, PPLL_REF_DIV_ACC, rdiv_best);
+ state->ppll_div_0 = REG_S(PPLL_DIV_0, PPLL_FB0_DIV, fdiv_best) |
+ REG_S(PPLL_DIV_0, PPLL_POST0_DIV, pdiv_id);
+
+ vco_freq = (fdiv_best * rfrq) / rdiv_best;
+ /* This is horribly crude: the VCO frequency range is divided into
+ * 3 parts, each part having a fixed PLL gain value.
+ */
+ if (vco_freq >= 300000) {
+ /* [300..max] MHz : 7 */
+ vco_gain = 7;
+ } else if (vco_freq >= 180000) {
+ /* [180..300) MHz : 4 */
+ vco_gain = 4;
+ } else {
+ /* [0..180) MHz : 1 */
+ vco_gain = 1;
+ }
+ state->ppll_cntl |= REG_S(PPLL_CNTL, PPLL_PVG, vco_gain);
+ state->vclk_ecp_cntl |= REG_S(VCLK_ECP_CNTL, VCLK_SRC_SEL,
+ VCLK_SRC_SEL__PPLLCLK);
+ state->htotal_cntl = 0;
+ DRM_INFO("rdiv: %d\n", rdiv_best);
+ DRM_INFO("fdiv: %d\n", fdiv_best);
+ DRM_INFO("pdiv: %d\n", pdiv);
+ DRM_INFO("pdiv: %d\n", pdiv_id);
+ DRM_INFO("tfrq: %d\n", tfrq_best);
+ DRM_INFO("pfrq: %d\n", pfrq_best);
+ DRM_INFO("PPLL_REF_DIV: 0x%08X\n", state->ppll_ref_div);
+ DRM_INFO("PPLL_DIV_0: 0x%08X\n", state->ppll_div_0);
+ DRM_INFO("PPLL_CNTL: 0x%08X\n", state->ppll_cntl);
+ DRM_INFO("VCLK_ECP_CNTL: 0x%08X\n", state->vclk_ecp_cntl);
+}
+
+static void radeon_ms_crtc1_mode_set(struct drm_crtc *crtc,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode,
+ int x, int y)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_state *state = &dev_priv->driver_state;
+ int format, hsync_wid, vsync_wid, pitch;
+
+ DRM_INFO("[radeon_ms] set modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x\n",
+ mode->mode_id, mode->name, mode->vrefresh, mode->clock,
+ mode->hdisplay, mode->hsync_start,
+ mode->hsync_end, mode->htotal,
+ mode->vdisplay, mode->vsync_start,
+ mode->vsync_end, mode->vtotal, mode->type);
+ DRM_INFO("[radeon_ms] set modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x (adjusted)\n",
+ adjusted_mode->mode_id, adjusted_mode->name, adjusted_mode->vrefresh, adjusted_mode->clock,
+ adjusted_mode->hdisplay, adjusted_mode->hsync_start,
+ adjusted_mode->hsync_end, adjusted_mode->htotal,
+ adjusted_mode->vdisplay, adjusted_mode->vsync_start,
+ adjusted_mode->vsync_end, adjusted_mode->vtotal, adjusted_mode->type);
+
+ /* only support RGB555,RGB565,ARGB8888 should satisfy all users */
+ switch (crtc->fb->bits_per_pixel) {
+ case 16:
+ if (crtc->fb->depth == 15) {
+ format = 3;
+ } else {
+ format = 4;
+ }
+ break;
+ case 32:
+ format = 6;
+ break;
+ default:
+ DRM_ERROR("Unknown color depth\n");
+ return;
+ }
+ radeon_pll1_compute(crtc, adjusted_mode);
+
+ state->crtc_offset = REG_S(CRTC_OFFSET, CRTC_OFFSET, crtc->fb->bo->offset);
+ state->crtc_gen_cntl = CRTC_GEN_CNTL__CRTC_EXT_DISP_EN |
+ CRTC_GEN_CNTL__CRTC_EN |
+ REG_S(CRTC_GEN_CNTL, CRTC_PIX_WIDTH, format);
+ if (adjusted_mode->flags & V_DBLSCAN) {
+ state->crtc_gen_cntl |= CRTC_GEN_CNTL__CRTC_DBL_SCAN_EN;
+ }
+ if (adjusted_mode->flags & V_CSYNC) {
+ state->crtc_gen_cntl |= CRTC_GEN_CNTL__CRTC_C_SYNC_EN;
+ }
+ if (adjusted_mode->flags & V_INTERLACE) {
+ state->crtc_gen_cntl |= CRTC_GEN_CNTL__CRTC_INTERLACE_EN;
+ }
+ state->crtc_more_cntl = 0;
+ state->crtc_h_total_disp =
+ REG_S(CRTC_H_TOTAL_DISP,
+ CRTC_H_TOTAL,
+ (adjusted_mode->crtc_htotal/8) - 1) |
+ REG_S(CRTC_H_TOTAL_DISP,
+ CRTC_H_DISP,
+ (adjusted_mode->crtc_hdisplay/8) - 1);
+ hsync_wid = (adjusted_mode->crtc_hsync_end -
+ adjusted_mode->crtc_hsync_start) / 8;
+ if (!hsync_wid) {
+ hsync_wid = 1;
+ }
+ if (hsync_wid > 0x3f) {
+ hsync_wid = 0x3f;
+ }
+ state->crtc_h_sync_strt_wid =
+ REG_S(CRTC_H_SYNC_STRT_WID,
+ CRTC_H_SYNC_WID, hsync_wid) |
+ REG_S(CRTC_H_SYNC_STRT_WID,
+ CRTC_H_SYNC_STRT_PIX,
+ adjusted_mode->crtc_hsync_start) |
+ REG_S(CRTC_H_SYNC_STRT_WID,
+ CRTC_H_SYNC_STRT_CHAR,
+ adjusted_mode->crtc_hsync_start/8);
+ if (adjusted_mode->flags & V_NHSYNC) {
+ state->crtc_h_sync_strt_wid |=
+ CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_POL;
+ }
+
+ state->crtc_v_total_disp =
+ REG_S(CRTC_V_TOTAL_DISP, CRTC_V_TOTAL,
+ adjusted_mode->crtc_vtotal - 1) |
+ REG_S(CRTC_V_TOTAL_DISP, CRTC_V_DISP,
+ adjusted_mode->crtc_vdisplay - 1);
+ vsync_wid = adjusted_mode->crtc_vsync_end -
+ adjusted_mode->crtc_vsync_start;
+ if (!vsync_wid) {
+ vsync_wid = 1;
+ }
+ if (vsync_wid > 0x1f) {
+ vsync_wid = 0x1f;
+ }
+ state->crtc_v_sync_strt_wid =
+ REG_S(CRTC_V_SYNC_STRT_WID,
+ CRTC_V_SYNC_WID,
+ vsync_wid) |
+ REG_S(CRTC_V_SYNC_STRT_WID,
+ CRTC_V_SYNC_STRT,
+ adjusted_mode->crtc_vsync_start);
+ if (adjusted_mode->flags & V_NVSYNC) {
+ state->crtc_v_sync_strt_wid |=
+ CRTC_V_SYNC_STRT_WID__CRTC_V_SYNC_POL;
+ }
+
+ pitch = (crtc->fb->width * crtc->fb->bits_per_pixel +
+ ((crtc->fb->bits_per_pixel * 8)- 1)) /
+ (crtc->fb->bits_per_pixel * 8);
+ state->crtc_pitch = REG_S(CRTC_PITCH, CRTC_PITCH, pitch) |
+ REG_S(CRTC_PITCH, CRTC_PITCH_RIGHT, pitch);
+
+ state->fp_h_sync_strt_wid = state->crtc_h_sync_strt_wid;
+ state->fp_v_sync_strt_wid = state->crtc_v_sync_strt_wid;
+ state->fp_crtc_h_total_disp = state->crtc_h_total_disp;
+ state->fp_crtc_v_total_disp = state->crtc_v_total_disp;
+
+ radeon_ms_crtc1_restore(dev, state);
+}
+
+static void radeon_ms_crtc_mode_commit(struct drm_crtc *crtc)
+{
+ crtc->funcs->dpms(crtc, DPMSModeOn);
+}
+
+static void radeon_ms_crtc_gamma_set(struct drm_crtc *crtc, u16 r,
+ u16 g, u16 b, int regno)
+{
+ struct drm_radeon_private *dev_priv = crtc->dev->dev_private;
+ struct radeon_ms_crtc *radeon_ms_crtc = crtc->driver_private;
+ struct radeon_state *state = &dev_priv->driver_state;
+ uint32_t color;
+
+ switch(radeon_ms_crtc->crtc) {
+ case 1:
+ state->dac_cntl2 &= ~DAC_CNTL2__PALETTE_ACCESS_CNTL;
+ break;
+ case 2:
+ state->dac_cntl2 |= DAC_CNTL2__PALETTE_ACCESS_CNTL;
+ break;
+ }
+ MMIO_W(DAC_CNTL2, state->dac_cntl2);
+ if (crtc->fb->bits_per_pixel == 16 && crtc->fb->depth == 16) {
+ if (regno >= 64) {
+ return;
+ }
+ MMIO_W(PALETTE_INDEX,
+ REG_S(PALETTE_INDEX, PALETTE_W_INDEX,
+ regno * 4));
+ color = 0;
+ color = REG_S(PALETTE_DATA, PALETTE_DATA_R, r >> 8) |
+ REG_S(PALETTE_DATA, PALETTE_DATA_G, g >> 8) |
+ REG_S(PALETTE_DATA, PALETTE_DATA_B, b >> 8);
+ MMIO_W(PALETTE_DATA, color);
+ MMIO_W(PALETTE_INDEX,
+ REG_S(PALETTE_INDEX, PALETTE_W_INDEX, regno * 4));
+ color = 0;
+ color = REG_S(PALETTE_30_DATA, PALETTE_DATA_R, r >> 6) |
+ REG_S(PALETTE_30_DATA, PALETTE_DATA_G, g >> 6) |
+ REG_S(PALETTE_30_DATA, PALETTE_DATA_B, b >> 6);
+ MMIO_W(PALETTE_30_DATA, color);
+ radeon_ms_crtc->lut_r[regno * 4] = r;
+ radeon_ms_crtc->lut_g[regno * 4] = g;
+ radeon_ms_crtc->lut_b[regno * 4] = b;
+ if (regno < 32) {
+ MMIO_W(PALETTE_INDEX,
+ REG_S(PALETTE_INDEX, PALETTE_W_INDEX,
+ regno * 8));
+ color = 0;
+ color = REG_S(PALETTE_DATA, PALETTE_DATA_R, r >> 8) |
+ REG_S(PALETTE_DATA, PALETTE_DATA_G, g >> 8) |
+ REG_S(PALETTE_DATA, PALETTE_DATA_B, b >> 8);
+ MMIO_W(PALETTE_DATA, color);
+ MMIO_W(PALETTE_INDEX,
+ REG_S(PALETTE_INDEX, PALETTE_W_INDEX,
+ regno * 8));
+ color = 0;
+ color = REG_S(PALETTE_30_DATA, PALETTE_DATA_R,r >> 6) |
+ REG_S(PALETTE_30_DATA, PALETTE_DATA_G,g >> 6) |
+ REG_S(PALETTE_30_DATA, PALETTE_DATA_B,b >> 6);
+ MMIO_W(PALETTE_30_DATA, color);
+ radeon_ms_crtc->lut_r[regno * 8] = r;
+ radeon_ms_crtc->lut_g[regno * 8] = g;
+ radeon_ms_crtc->lut_b[regno * 8] = b;
+ }
+ } else {
+ if (regno >= 256) {
+ return;
+ }
+ radeon_ms_crtc->lut_r[regno] = r;
+ radeon_ms_crtc->lut_g[regno] = g;
+ radeon_ms_crtc->lut_b[regno] = b;
+ MMIO_W(PALETTE_INDEX,
+ REG_S(PALETTE_INDEX, PALETTE_W_INDEX, regno));
+ color = 0;
+ color = REG_S(PALETTE_DATA, PALETTE_DATA_R, r >> 8) |
+ REG_S(PALETTE_DATA, PALETTE_DATA_G, g >> 8) |
+ REG_S(PALETTE_DATA, PALETTE_DATA_B, b >> 8);
+ MMIO_W(PALETTE_DATA, color);
+ MMIO_W(PALETTE_INDEX,
+ REG_S(PALETTE_INDEX, PALETTE_W_INDEX, regno));
+ color = 0;
+ color = REG_S(PALETTE_30_DATA, PALETTE_DATA_R, r >> 6) |
+ REG_S(PALETTE_30_DATA, PALETTE_DATA_G, g >> 6) |
+ REG_S(PALETTE_30_DATA, PALETTE_DATA_B, b >> 6);
+ }
+}
+
+static void radeon_ms_crtc_load_lut(struct drm_crtc *crtc)
+{
+ struct radeon_ms_crtc *radeon_ms_crtc = crtc->driver_private;
+ int i;
+
+ if (!crtc->enabled)
+ return;
+
+ for (i = 0; i < 256; i++) {
+ radeon_ms_crtc_gamma_set(crtc,
+ radeon_ms_crtc->lut_r[i],
+ radeon_ms_crtc->lut_g[i],
+ radeon_ms_crtc->lut_b[i],
+ i);
+ }
+}
+
+static bool radeon_ms_crtc_lock(struct drm_crtc *crtc)
+{
+ return true;
+}
+
+static void radeon_ms_crtc_unlock(struct drm_crtc *crtc)
+{
+}
+
+static const struct drm_crtc_funcs radeon_ms_crtc1_funcs= {
+ .dpms = radeon_ms_crtc1_dpms,
+ .save = NULL, /* XXX */
+ .restore = NULL, /* XXX */
+ .lock = radeon_ms_crtc_lock,
+ .unlock = radeon_ms_crtc_unlock,
+ .prepare = radeon_ms_crtc_mode_prepare,
+ .commit = radeon_ms_crtc_mode_commit,
+ .mode_fixup = radeon_ms_crtc_mode_fixup,
+ .mode_set = radeon_ms_crtc1_mode_set,
+ .gamma_set = radeon_ms_crtc_gamma_set,
+ .cleanup = NULL, /* XXX */
+};
+
+int radeon_ms_crtc_create(struct drm_device *dev, int crtc)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct drm_crtc *drm_crtc;
+ struct radeon_ms_crtc *radeon_ms_crtc;
+ int i;
+
+ switch (crtc) {
+ case 1:
+ radeon_ms_crtc1_init(dev_priv, &dev_priv->driver_state);
+ drm_crtc = drm_crtc_create(dev, &radeon_ms_crtc1_funcs);
+ break;
+ case 2:
+ default:
+ return -EINVAL;
+ }
+ if (drm_crtc == NULL) {
+ return -ENOMEM;
+ }
+
+ radeon_ms_crtc = drm_alloc(sizeof(struct radeon_ms_crtc), DRM_MEM_DRIVER);
+ if (radeon_ms_crtc == NULL) {
+ kfree(drm_crtc);
+ return -ENOMEM;
+ }
+
+ radeon_ms_crtc->crtc = crtc;
+ for (i = 0; i < 256; i++) {
+ radeon_ms_crtc->lut_r[i] = i << 8;
+ radeon_ms_crtc->lut_g[i] = i << 8;
+ radeon_ms_crtc->lut_b[i] = i << 8;
+ }
+ drm_crtc->driver_private = radeon_ms_crtc;
+ return 0;
+}
diff --git a/shared-core/radeon_ms_dac.c b/shared-core/radeon_ms_dac.c
new file mode 100644
index 00000000..e6312942
--- /dev/null
+++ b/shared-core/radeon_ms_dac.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Alex Deucher
+ * Copyright 2007 Dave Airlie
+ * All Rights Reserved.
+ *
+ * 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 on 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
+ * THEIR SUPPLIERS 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 "radeon_ms.h"
+
+int radeon_ms_dac1_initialize(struct radeon_ms_output *output)
+{
+ struct drm_radeon_private *dev_priv = output->dev->dev_private;
+ struct radeon_state *state = &dev_priv->driver_state;
+
+ state->dac_cntl =
+ REG_S(DAC_CNTL, DAC_RANGE_CNTL, DAC_RANGE_CNTL__PS2) |
+ DAC_CNTL__DAC_8BIT_EN |
+ DAC_CNTL__DAC_VGA_ADR_EN |
+ DAC_CNTL__DAC_PDWN |
+ REG_S(DAC_CNTL, DAC, 0xff);
+ state->dac_ext_cntl = 0;
+ state->dac_macro_cntl =
+ DAC_MACRO_CNTL__DAC_PDWN_R |
+ DAC_MACRO_CNTL__DAC_PDWN_G |
+ DAC_MACRO_CNTL__DAC_PDWN_B |
+ REG_S(DAC_MACRO_CNTL, DAC_WHITE_CNTL, 7) |
+ REG_S(DAC_MACRO_CNTL, DAC_BG_ADJ, 7);
+ state->dac_embedded_sync_cntl =
+ DAC_EMBEDDED_SYNC_CNTL__DAC_EMBED_VSYNC_EN_Y_G;
+ state->dac_broad_pulse = 0;
+ state->dac_skew_clks = 0;
+ state->dac_incr = 0;
+ state->dac_neg_sync_level = 0;
+ state->dac_pos_sync_level = 0;
+ state->dac_blank_level = 0;
+ state->dac_sync_equalization = 0;
+ state->disp_output_cntl = 0;
+ radeon_ms_dac1_restore(output, state);
+ return 0;
+}
+
+enum drm_output_status radeon_ms_dac1_detect(struct radeon_ms_output *output)
+{
+ return output_status_unknown;
+}
+
+void radeon_ms_dac1_dpms(struct radeon_ms_output *output, int mode)
+{
+ struct drm_radeon_private *dev_priv = output->dev->dev_private;
+ struct radeon_state *state = &dev_priv->driver_state;
+ uint32_t dac_cntl;
+ uint32_t dac_macro_cntl;
+
+ dac_cntl = DAC_CNTL__DAC_PDWN;
+ dac_macro_cntl = DAC_MACRO_CNTL__DAC_PDWN_R |
+ DAC_MACRO_CNTL__DAC_PDWN_G |
+ DAC_MACRO_CNTL__DAC_PDWN_B;
+ switch(mode) {
+ case DPMSModeOn:
+ state->dac_cntl &= ~dac_cntl;
+ state->dac_macro_cntl &= ~dac_macro_cntl;
+ break;
+ case DPMSModeStandby:
+ case DPMSModeSuspend:
+ case DPMSModeOff:
+ state->dac_cntl |= dac_cntl;
+ state->dac_macro_cntl |= dac_macro_cntl;
+ break;
+ default:
+ /* error */
+ break;
+ }
+ MMIO_W(DAC_CNTL, state->dac_cntl);
+ MMIO_W(DAC_MACRO_CNTL, state->dac_macro_cntl);
+}
+
+int radeon_ms_dac1_get_modes(struct radeon_ms_output *output)
+{
+ return 0;
+}
+
+bool radeon_ms_dac1_mode_fixup(struct radeon_ms_output *output,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ return true;
+}
+
+int radeon_ms_dac1_mode_set(struct radeon_ms_output *output,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct drm_radeon_private *dev_priv = output->dev->dev_private;
+ struct radeon_ms_connector *connector = output->connector;
+ struct radeon_state *state = &dev_priv->driver_state;
+ uint32_t v = 0;
+
+ if (connector == NULL) {
+ /* output not associated with a connector */
+ return -EINVAL;
+ }
+ state->disp_output_cntl &= ~DISP_OUTPUT_CNTL__DISP_DAC_SOURCE__MASK;
+ state->dac_cntl2 &= ~DAC_CNTL2__DAC_CLK_SEL;
+ switch (connector->crtc) {
+ case 1:
+ v = DISP_DAC_SOURCE__PRIMARYCRTC;
+ break;
+ case 2:
+ v = DISP_DAC_SOURCE__SECONDARYCRTC;
+ state->dac_cntl2 |= DAC_CNTL2__DAC_CLK_SEL;
+ break;
+ }
+ state->disp_output_cntl |= REG_S(DISP_OUTPUT_CNTL, DISP_DAC_SOURCE, v);
+ MMIO_W(DISP_OUTPUT_CNTL, state->disp_output_cntl);
+ MMIO_W(DAC_CNTL2, state->dac_cntl2);
+ return 0;
+}
+
+void radeon_ms_dac1_restore(struct radeon_ms_output *output,
+ struct radeon_state *state)
+{
+ struct drm_radeon_private *dev_priv = output->dev->dev_private;
+
+ MMIO_W(DAC_CNTL, state->dac_cntl);
+ MMIO_W(DAC_EXT_CNTL, state->dac_ext_cntl);
+ MMIO_W(DAC_MACRO_CNTL, state->dac_macro_cntl);
+ MMIO_W(DAC_EMBEDDED_SYNC_CNTL, state->dac_embedded_sync_cntl);
+ MMIO_W(DAC_BROAD_PULSE, state->dac_broad_pulse);
+ MMIO_W(DAC_SKEW_CLKS, state->dac_skew_clks);
+ MMIO_W(DAC_INCR, state->dac_incr);
+ MMIO_W(DAC_NEG_SYNC_LEVEL, state->dac_neg_sync_level);
+ MMIO_W(DAC_POS_SYNC_LEVEL, state->dac_pos_sync_level);
+ MMIO_W(DAC_BLANK_LEVEL, state->dac_blank_level);
+ MMIO_W(DAC_SYNC_EQUALIZATION, state->dac_sync_equalization);
+}
+
+void radeon_ms_dac1_save(struct radeon_ms_output *output,
+ struct radeon_state *state)
+{
+ struct drm_radeon_private *dev_priv = output->dev->dev_private;
+
+ state->dac_cntl = MMIO_R(DAC_CNTL);
+ state->dac_ext_cntl = MMIO_R(DAC_EXT_CNTL);
+ state->dac_macro_cntl = MMIO_R(DAC_MACRO_CNTL);
+ state->dac_embedded_sync_cntl = MMIO_R(DAC_EMBEDDED_SYNC_CNTL);
+ state->dac_broad_pulse = MMIO_R(DAC_BROAD_PULSE);
+ state->dac_skew_clks = MMIO_R(DAC_SKEW_CLKS);
+ state->dac_incr = MMIO_R(DAC_INCR);
+ state->dac_neg_sync_level = MMIO_R(DAC_NEG_SYNC_LEVEL);
+ state->dac_pos_sync_level = MMIO_R(DAC_POS_SYNC_LEVEL);
+ state->dac_blank_level = MMIO_R(DAC_BLANK_LEVEL);
+ state->dac_sync_equalization = MMIO_R(DAC_SYNC_EQUALIZATION);
+}
+
+int radeon_ms_dac2_initialize(struct radeon_ms_output *output)
+{
+ struct drm_radeon_private *dev_priv = output->dev->dev_private;
+ struct radeon_state *state = &dev_priv->driver_state;
+
+ state->tv_dac_cntl = TV_DAC_CNTL__BGSLEEP |
+ REG_S(TV_DAC_CNTL, STD, STD__PS2) |
+ REG_S(TV_DAC_CNTL, BGADJ, 0);
+ switch (dev_priv->family) {
+ case CHIP_R100:
+ case CHIP_R200:
+ case CHIP_RV200:
+ case CHIP_RV250:
+ case CHIP_RV280:
+ case CHIP_RS300:
+ case CHIP_R300:
+ case CHIP_R350:
+ case CHIP_R360:
+ case CHIP_RV350:
+ case CHIP_RV370:
+ case CHIP_RV380:
+ case CHIP_RS400:
+ state->tv_dac_cntl |= TV_DAC_CNTL__RDACPD |
+ TV_DAC_CNTL__GDACPD |
+ TV_DAC_CNTL__BDACPD |
+ REG_S(TV_DAC_CNTL, DACADJ, 0);
+ break;
+ case CHIP_RV410:
+ case CHIP_R420:
+ case CHIP_R430:
+ case CHIP_R480:
+ state->tv_dac_cntl |= TV_DAC_CNTL__RDACPD_R4 |
+ TV_DAC_CNTL__GDACPD_R4 |
+ TV_DAC_CNTL__BDACPD_R4 |
+ REG_S(TV_DAC_CNTL, DACADJ_R4, 0);
+ break;
+ }
+ state->tv_master_cntl = TV_MASTER_CNTL__TV_ASYNC_RST |
+ TV_MASTER_CNTL__CRT_ASYNC_RST |
+ TV_MASTER_CNTL__RESTART_PHASE_FIX |
+ TV_MASTER_CNTL__CRT_FIFO_CE_EN |
+ TV_MASTER_CNTL__TV_FIFO_CE_EN;
+ state->dac_cntl2 = 0;
+ state->disp_output_cntl = 0;
+ radeon_ms_dac2_restore(output, state);
+ return 0;
+}
+
+enum drm_output_status radeon_ms_dac2_detect(struct radeon_ms_output *output)
+{
+ return output_status_unknown;
+}
+
+void radeon_ms_dac2_dpms(struct radeon_ms_output *output, int mode)
+{
+ struct drm_radeon_private *dev_priv = output->dev->dev_private;
+ struct radeon_state *state = &dev_priv->driver_state;
+ uint32_t tv_dac_cntl_on, tv_dac_cntl_off;
+
+ tv_dac_cntl_off = TV_DAC_CNTL__BGSLEEP;
+ tv_dac_cntl_on = TV_DAC_CNTL__NBLANK |
+ TV_DAC_CNTL__NHOLD;
+ switch (dev_priv->family) {
+ case CHIP_R100:
+ case CHIP_R200:
+ case CHIP_RV200:
+ case CHIP_RV250:
+ case CHIP_RV280:
+ case CHIP_RS300:
+ case CHIP_R300:
+ case CHIP_R350:
+ case CHIP_R360:
+ case CHIP_RV350:
+ case CHIP_RV370:
+ case CHIP_RV380:
+ case CHIP_RS400:
+ tv_dac_cntl_off |= TV_DAC_CNTL__RDACPD |
+ TV_DAC_CNTL__GDACPD |
+ TV_DAC_CNTL__BDACPD;
+ break;
+ case CHIP_RV410:
+ case CHIP_R420:
+ case CHIP_R430:
+ case CHIP_R480:
+ tv_dac_cntl_off |= TV_DAC_CNTL__RDACPD_R4 |
+ TV_DAC_CNTL__GDACPD_R4 |
+ TV_DAC_CNTL__BDACPD_R4;
+ break;
+ }
+ switch(mode) {
+ case DPMSModeOn:
+ state->tv_dac_cntl &= ~tv_dac_cntl_off;
+ state->tv_dac_cntl |= tv_dac_cntl_on;
+ break;
+ case DPMSModeStandby:
+ case DPMSModeSuspend:
+ case DPMSModeOff:
+ state->tv_dac_cntl &= ~tv_dac_cntl_on;
+ state->tv_dac_cntl |= tv_dac_cntl_off;
+ break;
+ default:
+ /* error */
+ break;
+ }
+ MMIO_W(TV_DAC_CNTL, state->tv_dac_cntl);
+}
+
+int radeon_ms_dac2_get_modes(struct radeon_ms_output *output)
+{
+ return 0;
+}
+
+bool radeon_ms_dac2_mode_fixup(struct radeon_ms_output *output,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ return true;
+}
+
+int radeon_ms_dac2_mode_set(struct radeon_ms_output *output,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct drm_radeon_private *dev_priv = output->dev->dev_private;
+ struct radeon_ms_connector *connector = output->connector;
+ struct radeon_state *state = &dev_priv->driver_state;
+
+ if (connector == NULL) {
+ /* output not associated with a connector */
+ return -EINVAL;
+ }
+ switch (dev_priv->family) {
+ case CHIP_R100:
+ case CHIP_R200:
+ state->disp_output_cntl &= ~DISP_OUTPUT_CNTL__DISP_TV_SOURCE;
+ switch (connector->crtc) {
+ case 1:
+ break;
+ case 2:
+ state->disp_output_cntl |=
+ DISP_OUTPUT_CNTL__DISP_TV_SOURCE;
+ break;
+ }
+ break;
+ case CHIP_RV200:
+ case CHIP_RV250:
+ case CHIP_RV280:
+ case CHIP_RS300:
+ break;
+ case CHIP_R300:
+ case CHIP_R350:
+ case CHIP_R360:
+ case CHIP_RV350:
+ case CHIP_RV370:
+ case CHIP_RV380:
+ case CHIP_RS400:
+ case CHIP_RV410:
+ case CHIP_R420:
+ case CHIP_R430:
+ case CHIP_R480:
+ state->disp_output_cntl &=
+ ~DISP_OUTPUT_CNTL__DISP_TVDAC_SOURCE__MASK;
+ switch (connector->crtc) {
+ case 1:
+ state->disp_output_cntl |=
+ REG_S(DISP_OUTPUT_CNTL,
+ DISP_TVDAC_SOURCE,
+ DISP_TVDAC_SOURCE__PRIMARYCRTC);
+ break;
+ case 2:
+ state->disp_output_cntl |=
+ REG_S(DISP_OUTPUT_CNTL,
+ DISP_TVDAC_SOURCE,
+ DISP_TVDAC_SOURCE__SECONDARYCRTC);
+ break;
+ }
+ break;
+ }
+ switch (dev_priv->family) {
+ case CHIP_R200:
+ break;
+ case CHIP_R100:
+ case CHIP_RV200:
+ case CHIP_RV250:
+ case CHIP_RV280:
+ case CHIP_RS300:
+ case CHIP_R300:
+ case CHIP_R350:
+ case CHIP_R360:
+ case CHIP_RV350:
+ case CHIP_RV370:
+ case CHIP_RV380:
+ case CHIP_RS400:
+ case CHIP_RV410:
+ case CHIP_R420:
+ case CHIP_R430:
+ case CHIP_R480:
+ if (connector->type != CONNECTOR_CTV &&
+ connector->type != CONNECTOR_STV) {
+ state->dac_cntl2 |= DAC_CNTL2__DAC2_CLK_SEL;
+ }
+ }
+ MMIO_W(DAC_CNTL2, state->dac_cntl2);
+ MMIO_W(DISP_OUTPUT_CNTL, state->disp_output_cntl);
+ return 0;
+}
+
+void radeon_ms_dac2_restore(struct radeon_ms_output *output,
+ struct radeon_state *state)
+{
+ struct drm_radeon_private *dev_priv = output->dev->dev_private;
+
+ MMIO_W(DAC_CNTL2, state->dac_cntl2);
+ MMIO_W(TV_DAC_CNTL, state->tv_dac_cntl);
+ MMIO_W(TV_MASTER_CNTL, state->tv_master_cntl);
+}
+
+void radeon_ms_dac2_save(struct radeon_ms_output *output,
+ struct radeon_state *state)
+{
+ struct drm_radeon_private *dev_priv = output->dev->dev_private;
+
+ state->dac_cntl2 = MMIO_R(DAC_CNTL2);
+ state->tv_dac_cntl = MMIO_R(TV_DAC_CNTL);
+ state->tv_master_cntl = MMIO_R(TV_MASTER_CNTL);
+}
diff --git a/shared-core/radeon_ms_drm.c b/shared-core/radeon_ms_drm.c
new file mode 100644
index 00000000..857182ae
--- /dev/null
+++ b/shared-core/radeon_ms_drm.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Alex Deucher
+ * Copyright 2007 Dave Airlie
+ * All Rights Reserved.
+ *
+ * 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ */
+/*
+ * Authors:
+ * Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "drm_pciids.h"
+#include "radeon_ms.h"
+
+
+static uint32_t radeon_ms_mem_prios[] = {
+ DRM_BO_MEM_VRAM,
+ DRM_BO_MEM_TT,
+ DRM_BO_MEM_LOCAL,
+};
+
+static uint32_t radeon_ms_busy_prios[] = {
+ DRM_BO_MEM_TT,
+ DRM_BO_MEM_VRAM,
+ DRM_BO_MEM_LOCAL,
+};
+
+struct drm_fence_driver radeon_ms_fence_driver = {
+ .num_classes = 1,
+ .wrap_diff = (1 << 30),
+ .flush_diff = (1 << 29),
+ .sequence_mask = 0xffffffffU,
+ .lazy_capable = 1,
+ .emit = radeon_ms_fence_emit_sequence,
+ .poke_flush = radeon_ms_poke_flush,
+ .has_irq = radeon_ms_fence_has_irq,
+};
+
+struct drm_bo_driver radeon_ms_bo_driver = {
+ .mem_type_prio = radeon_ms_mem_prios,
+ .mem_busy_prio = radeon_ms_busy_prios,
+ .num_mem_type_prio = sizeof(radeon_ms_mem_prios)/sizeof(uint32_t),
+ .num_mem_busy_prio = sizeof(radeon_ms_busy_prios)/sizeof(uint32_t),
+ .create_ttm_backend_entry = radeon_ms_create_ttm_backend,
+ .fence_type = radeon_ms_fence_types,
+ .invalidate_caches = radeon_ms_invalidate_caches,
+ .init_mem_type = radeon_ms_init_mem_type,
+ .evict_flags = radeon_ms_evict_flags,
+ .move = radeon_ms_bo_move,
+ .ttm_cache_flush = radeon_ms_ttm_flush,
+};
+
+struct drm_ioctl_desc radeon_ms_ioctls[] = {
+ DRM_IOCTL_DEF(DRM_RADEON_EXECBUFFER, radeon_ms_execbuffer, DRM_AUTH),
+};
+int radeon_ms_num_ioctls = DRM_ARRAY_SIZE(radeon_ms_ioctls);
+
+int radeon_ms_driver_dma_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_device_dma *dma = dev->dma;
+ struct drm_dma *d = data;
+
+ LOCK_TEST_WITH_RETURN(dev, file_priv);
+
+ /* Please don't send us buffers.
+ */
+ if (d->send_count != 0) {
+ DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
+ DRM_CURRENTPID, d->send_count);
+ return -EINVAL;
+ }
+
+ /* Don't ask us buffer neither :)
+ */
+ DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
+ DRM_CURRENTPID, d->request_count, dma->buf_count);
+ return -EINVAL;
+}
+
+void radeon_ms_driver_lastclose(struct drm_device * dev)
+{
+}
+
+int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags)
+{
+ struct drm_radeon_private *dev_priv;
+ int ret = 0;
+
+ DRM_INFO("[radeon_ms] loading\n");
+ /* allocate and clear device private structure */
+ dev_priv = drm_alloc(sizeof(struct drm_radeon_private), DRM_MEM_DRIVER);
+ if (dev_priv == NULL)
+ return -ENOMEM;
+ memset(dev_priv, 0, sizeof(struct drm_radeon_private));
+ dev->dev_private = (void *)dev_priv;
+
+ /* initialize modesetting structure (must be done here) */
+ drm_mode_config_init(dev);
+
+ /* flags correspond to chipset family */
+ dev_priv->usec_timeout = 100;
+ dev_priv->family = flags & 0xffffU;
+ dev_priv->bus_type = flags & 0xff0000U;
+ /* initialize family functions */
+ ret = radeon_ms_family_init(dev);
+ if (ret != 0) {
+ radeon_ms_driver_unload(dev);
+ return ret;
+ }
+
+ /* we don't want userspace to be able to map this so don't use
+ * drm_addmap */
+ dev_priv->mmio.offset = drm_get_resource_start(dev, 2);
+ dev_priv->mmio.size = drm_get_resource_len(dev, 2);
+ dev_priv->mmio.type = _DRM_REGISTERS;
+ dev_priv->mmio.flags = _DRM_RESTRICTED;
+ drm_core_ioremap(&dev_priv->mmio, dev);
+ /* map vram FIXME: IGP likely don't have any of this */
+ dev_priv->vram.offset = drm_get_resource_start(dev, 0);
+ dev_priv->vram.size = drm_get_resource_len(dev, 0);
+ dev_priv->vram.type = _DRM_FRAME_BUFFER;
+ dev_priv->vram.flags = _DRM_RESTRICTED;
+ drm_core_ioremap(&dev_priv->vram, dev);
+
+ /* save radeon initial state which will be restored upon module
+ * exit */
+ radeon_ms_state_save(dev, &dev_priv->load_state);
+ dev_priv->restore_state = 1;
+ memcpy(&dev_priv->driver_state, &dev_priv->load_state,
+ sizeof(struct radeon_state));
+
+ /* initialize irq */
+ ret = radeon_ms_irq_init(dev);
+ if (ret != 0) {
+ radeon_ms_driver_unload(dev);
+ return ret;
+ }
+
+ /* init bo driver */
+ dev_priv->fence_id_last = 1;
+ dev_priv->fence_reg = SCRATCH_REG2;
+ drm_bo_driver_init(dev);
+ /* initialize vram */
+ ret = drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, dev_priv->vram.size, 1);
+ if (ret != 0) {
+ radeon_ms_driver_unload(dev);
+ return ret;
+ }
+
+ /* initialize gpu address space (only after) VRAM initialization */
+ ret = radeon_ms_gpu_initialize(dev);
+ if (ret != 0) {
+ radeon_ms_driver_unload(dev);
+ return ret;
+ }
+ radeon_ms_gpu_restore(dev, &dev_priv->driver_state);
+
+ /* initialize ttm */
+ ret = drm_bo_init_mm(dev, DRM_BO_MEM_TT, 0,
+ dev_priv->gpu_gart_size / RADEON_PAGE_SIZE, 1);
+ if (ret != 0) {
+ radeon_ms_driver_unload(dev);
+ return ret;
+ }
+
+ /* initialize ring buffer */
+ /* set ring size to 4Mo FIXME: should make a parameter for this */
+ dev_priv->write_back_area_size = 4 * 1024;
+ dev_priv->ring_buffer_size = 4 * 1024 * 1024;
+ ret = radeon_ms_cp_init(dev);
+ if (ret != 0) {
+ radeon_ms_driver_unload(dev);
+ return ret;
+ }
+
+ /* initialize modesetting */
+ dev->mode_config.min_width = 0;
+ dev->mode_config.min_height = 0;
+ dev->mode_config.max_width = 4096;
+ dev->mode_config.max_height = 4096;
+ dev->mode_config.fb_base = dev_priv->vram.offset;
+ ret = radeon_ms_crtc_create(dev, 1);
+ if (ret != 0) {
+ radeon_ms_driver_unload(dev);
+ return ret;
+ }
+ ret = radeon_ms_outputs_from_rom(dev);
+ if (ret < 0) {
+ radeon_ms_driver_unload(dev);
+ return ret;
+ } else if (!ret) {
+ ret = radeon_ms_outputs_from_properties(dev);
+ if (ret < 0) {
+ radeon_ms_driver_unload(dev);
+ return ret;
+ } else if (ret == 0) {
+ DRM_INFO("[radeon_ms] no outputs !\n");
+ }
+ } else {
+ DRM_INFO("[radeon_ms] added %d outputs from rom.\n", ret);
+ }
+ ret = radeon_ms_connectors_from_rom(dev);
+ if (ret < 0) {
+ radeon_ms_driver_unload(dev);
+ return ret;
+ } else if (!ret) {
+ ret = radeon_ms_connectors_from_properties(dev);
+ if (ret < 0) {
+ radeon_ms_driver_unload(dev);
+ return ret;
+ } else if (!ret) {
+ DRM_INFO("[radeon_ms] no connectors !\n");
+ }
+ } else {
+ DRM_INFO("[radeon_ms] added %d connectors from rom.\n", ret);
+ }
+ radeon_ms_outputs_save(dev, &dev_priv->load_state);
+ drm_initial_config(dev, false);
+
+ ret = drm_irq_install(dev);
+ if (ret != 0) {
+ radeon_ms_driver_unload(dev);
+ return ret;
+ }
+
+ DRM_INFO("[radeon_ms] successfull initialization\n");
+ return 0;
+}
+
+int radeon_ms_driver_open(struct drm_device * dev, struct drm_file *file_priv)
+{
+ return 0;
+}
+
+
+int radeon_ms_driver_unload(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ if (dev_priv == NULL) {
+ return 0;
+ }
+
+ /* cleanup modesetting */
+ drm_mode_config_cleanup(dev);
+ DRM_INFO("[radeon_ms] modesetting clean\n");
+ radeon_ms_outputs_restore(dev, &dev_priv->load_state);
+ radeon_ms_connectors_destroy(dev);
+ radeon_ms_outputs_destroy(dev);
+
+ /* shutdown cp engine */
+ radeon_ms_cp_finish(dev);
+ DRM_INFO("[radeon_ms] cp clean\n");
+
+ drm_irq_uninstall(dev);
+ DRM_INFO("[radeon_ms] irq uninstalled\n");
+
+ DRM_INFO("[radeon_ms] unloading\n");
+ /* clean ttm memory manager */
+ mutex_lock(&dev->struct_mutex);
+ if (drm_bo_clean_mm(dev, DRM_BO_MEM_TT, 1)) {
+ DRM_ERROR("TT memory manager not clean. Delaying takedown\n");
+ }
+ mutex_unlock(&dev->struct_mutex);
+ DRM_INFO("[radeon_ms] TT memory clean\n");
+ /* finish */
+ if (dev_priv->bus_finish) {
+ dev_priv->bus_finish(dev);
+ }
+ DRM_INFO("[radeon_ms] bus down\n");
+ /* clean vram memory manager */
+ mutex_lock(&dev->struct_mutex);
+ if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM, 1)) {
+ DRM_ERROR("VRAM memory manager not clean. Delaying takedown\n");
+ }
+ mutex_unlock(&dev->struct_mutex);
+ DRM_INFO("[radeon_ms] VRAM memory clean\n");
+ /* clean memory manager */
+ drm_bo_driver_finish(dev);
+ DRM_INFO("[radeon_ms] memory manager clean\n");
+ /* restore card state */
+ if (dev_priv->restore_state) {
+ radeon_ms_state_restore(dev, &dev_priv->load_state);
+ }
+ DRM_INFO("[radeon_ms] state restored\n");
+ if (dev_priv->mmio.handle) {
+ drm_core_ioremapfree(&dev_priv->mmio, dev);
+ }
+ if (dev_priv->vram.handle) {
+ drm_core_ioremapfree(&dev_priv->vram, dev);
+ }
+ DRM_INFO("[radeon_ms] map released\n");
+ drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
+ dev->dev_private = NULL;
+
+ DRM_INFO("[radeon_ms] that's all the folks\n");
+ return 0;
+}
+
diff --git a/shared-core/radeon_ms_drm.h b/shared-core/radeon_ms_drm.h
new file mode 100644
index 00000000..842d5331
--- /dev/null
+++ b/shared-core/radeon_ms_drm.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Dave Airlie
+ * Copyright 2007 Alex Deucher
+ * All Rights Reserved.
+ *
+ * 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ */
+/*
+ * Authors:
+ * Jérôme Glisse <glisse@freedesktop.org>
+ */
+#ifndef __RADEON_MS_DRM_H__
+#define __RADEON_MS_DRM_H__
+
+/* fence definitions */
+/* 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
+
+/* radeon ms ioctl */
+#define DRM_RADEON_EXECBUFFER 0x00
+
+struct drm_radeon_execbuffer_arg {
+ uint64_t next;
+ uint32_t reloc_offset;
+ union {
+ struct drm_bo_op_req req;
+ struct drm_bo_arg_rep rep;
+ } d;
+};
+
+struct drm_radeon_execbuffer {
+ uint32_t args_count;
+ uint64_t args;
+ uint32_t cmd_size;
+ struct drm_fence_arg fence_arg;
+};
+
+#endif
diff --git a/shared-core/radeon_ms_exec.c b/shared-core/radeon_ms_exec.c
new file mode 100644
index 00000000..b2ce3cbb
--- /dev/null
+++ b/shared-core/radeon_ms_exec.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * Authors:
+ * Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "radeon_ms.h"
+
+static void radeon_ms_execbuffer_args_clean(struct drm_device *dev,
+ struct drm_buffer_object **buffers,
+ uint32_t args_count)
+{
+ mutex_lock(&dev->struct_mutex);
+ while (args_count--) {
+ drm_bo_usage_deref_locked(&buffers[args_count]);
+ }
+ mutex_unlock(&dev->struct_mutex);
+}
+
+static int radeon_ms_execbuffer_args(struct drm_device *dev,
+ struct drm_file *file_priv,
+ struct drm_radeon_execbuffer *execbuffer,
+ struct drm_buffer_object **buffers,
+ uint32_t *relocs)
+{
+ struct drm_radeon_execbuffer_arg arg;
+ struct drm_bo_arg_rep rep;
+ uint32_t args_count = 0;
+ uint64_t next = 0;
+ uint64_t data = execbuffer->args;
+ int ret = 0;
+
+ do {
+ if (args_count >= execbuffer->args_count) {
+ DRM_ERROR("[radeon_ms] buffer count exceeded %d\n.",
+ execbuffer->args_count);
+ ret = -EINVAL;
+ goto out_err;
+ }
+ buffers[args_count] = NULL;
+ if (copy_from_user(&arg, (void __user *)((unsigned)data),
+ sizeof(struct drm_radeon_execbuffer_arg))) {
+ ret = -EFAULT;
+ goto out_err;
+ }
+ mutex_lock(&dev->struct_mutex);
+ buffers[args_count] =
+ drm_lookup_buffer_object(file_priv,
+ arg.d.req.arg_handle, 1);
+ relocs[args_count] = arg.reloc_offset;
+ mutex_unlock(&dev->struct_mutex);
+ if (arg.d.req.op != drm_bo_validate) {
+ DRM_ERROR("[radeon_ms] buffer object operation wasn't "
+ "validate.\n");
+ ret = -EINVAL;
+ goto out_err;
+ }
+ memset(&rep, 0, sizeof(struct drm_bo_arg_rep));
+ if (args_count >= 1) {
+ ret = drm_bo_handle_validate(file_priv,
+ arg.d.req.bo_req.handle,
+ arg.d.req.bo_req.fence_class,
+ arg.d.req.bo_req.flags,
+ arg.d.req.bo_req.mask,
+ arg.d.req.bo_req.hint,
+ 0,
+ &rep.bo_info,
+ &buffers[args_count]);
+ }
+ if (ret) {
+ DRM_ERROR("[radeon_ms] error on handle validate %d\n",
+ ret);
+ rep.ret = ret;
+ goto out_err;
+ }
+ next = arg.next;
+ arg.d.rep = rep;
+ if (copy_to_user((void __user *)((unsigned)data), &arg,
+ sizeof(struct drm_radeon_execbuffer_arg))) {
+ ret = -EFAULT;
+ goto out_err;
+ }
+ data = next;
+ args_count++;
+ } while (next != 0);
+ if (args_count != execbuffer->args_count) {
+ DRM_ERROR("[radeon_ms] not enought buffer got %d waited %d\n.",
+ args_count, execbuffer->args_count);
+ ret = -EINVAL;
+ goto out_err;
+ }
+ return 0;
+out_err:
+ radeon_ms_execbuffer_args_clean(dev, buffers, args_count);
+ return ret;
+}
+
+static int radeon_ms_execbuffer_check(struct drm_device *dev,
+ struct drm_file *file_priv,
+ struct drm_radeon_execbuffer *execbuffer,
+ struct drm_buffer_object **buffers,
+ uint32_t *relocs,
+ uint32_t *cmd)
+{
+ uint32_t i, gpu_addr;
+ int ret;
+
+ for (i = 0; i < execbuffer->args_count; i++) {
+ if (relocs[i]) {
+ ret = radeon_ms_bo_get_gpu_addr(dev, &buffers[i]->mem,
+ &gpu_addr);
+ if (ret) {
+ return ret;
+ }
+ cmd[relocs[i]] |= (gpu_addr) >> 10;
+ }
+ }
+ for (i = 0; i < execbuffer->cmd_size; i++) {
+#if 0
+ DRM_INFO("cmd[%d]=0x%08X\n", i, cmd[i]);
+#endif
+ }
+ return 0;
+}
+
+int radeon_ms_execbuffer(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_radeon_execbuffer *execbuffer = data;
+ struct drm_fence_arg *fence_arg = &execbuffer->fence_arg;
+ struct drm_buffer_object **buffers;
+ struct drm_bo_kmap_obj cmd_kmap;
+ struct drm_fence_object *fence;
+ uint32_t *relocs;
+ uint32_t *cmd;
+ int cmd_is_iomem;
+ int ret = 0;
+
+
+ ret = drm_bo_read_lock(&dev->bm.bm_lock);
+ if (ret) {
+ return ret;
+ }
+
+ relocs = drm_calloc(execbuffer->args_count, sizeof(uint32_t),
+ DRM_MEM_DRIVER);
+ if (relocs == NULL) {
+ drm_bo_read_unlock(&dev->bm.bm_lock);
+ return -ENOMEM;
+ }
+ buffers = drm_calloc(execbuffer->args_count,
+ sizeof(struct drm_buffer_object *),
+ DRM_MEM_DRIVER);
+ if (buffers == NULL) {
+ drm_free(relocs, (execbuffer->args_count * sizeof(uint32_t)),
+ DRM_MEM_DRIVER);
+ drm_bo_read_unlock(&dev->bm.bm_lock);
+ return -ENOMEM;
+ }
+ /* process arguments */
+ ret = radeon_ms_execbuffer_args(dev, file_priv, execbuffer,
+ buffers, relocs);
+ if (ret) {
+ DRM_ERROR("[radeon_ms] execbuffer wrong arguments\n");
+ goto out_free;
+ }
+ /* map command buffer */
+ memset(&cmd_kmap, 0, sizeof(struct drm_bo_kmap_obj));
+ ret = drm_bo_kmap(buffers[0],
+ 0,
+ buffers[0]->mem.num_pages,
+ &cmd_kmap);
+ if (ret) {
+ DRM_ERROR("[radeon_ms] error mapping ring buffer: %d\n", ret);
+ goto out_free_release;
+ }
+ cmd = drm_bmo_virtual(&cmd_kmap, &cmd_is_iomem);
+ /* do cmd checking & relocations */
+ ret = radeon_ms_execbuffer_check(dev, file_priv, execbuffer,
+ buffers, relocs, cmd);
+ if (ret) {
+ drm_putback_buffer_objects(dev);
+ goto out_free_release;
+ }
+
+ ret = radeon_ms_ring_emit(dev, cmd, execbuffer->cmd_size);
+ if (ret) {
+ drm_putback_buffer_objects(dev);
+ goto out_free_release;
+ }
+
+ /* fence */
+ ret = drm_fence_buffer_objects(dev, NULL, 0, NULL, &fence);
+ if (ret) {
+ drm_putback_buffer_objects(dev);
+ DRM_ERROR("[radeon_ms] fence buffer objects failed\n");
+ goto out_free_release;
+ }
+ if (!(fence_arg->flags & DRM_FENCE_FLAG_NO_USER)) {
+ ret = drm_fence_add_user_object(file_priv, fence,
+ fence_arg->flags & DRM_FENCE_FLAG_SHAREABLE);
+ if (!ret) {
+ fence_arg->handle = fence->base.hash.key;
+ fence_arg->fence_class = fence->fence_class;
+ fence_arg->type = fence->type;
+ fence_arg->signaled = fence->signaled;
+ fence_arg->sequence = fence->sequence;
+ }
+ }
+ drm_fence_usage_deref_unlocked(&fence);
+out_free_release:
+ drm_bo_kunmap(&cmd_kmap);
+ radeon_ms_execbuffer_args_clean(dev, buffers, execbuffer->args_count);
+out_free:
+ drm_free(relocs, (execbuffer->args_count * sizeof(uint32_t)),
+ DRM_MEM_DRIVER);
+ drm_free(buffers,
+ (execbuffer->args_count * sizeof(struct drm_buffer_object *)),
+ DRM_MEM_DRIVER);
+ drm_bo_read_unlock(&dev->bm.bm_lock);
+ return ret;
+}
diff --git a/shared-core/radeon_ms_family.c b/shared-core/radeon_ms_family.c
new file mode 100644
index 00000000..b70dca20
--- /dev/null
+++ b/shared-core/radeon_ms_family.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ */
+/*
+ * Authors:
+ * Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_ms.h"
+
+extern const uint32_t radeon_cp_microcode[];
+extern const uint32_t r200_cp_microcode[];
+extern const uint32_t r300_cp_microcode[];
+
+static void radeon_flush_cache(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t cmd[6];
+ int i, ret;
+
+ cmd[0] = CP_PACKET0(RB2D_DSTCACHE_CTLSTAT, 0);
+ cmd[1] = REG_S(RB2D_DSTCACHE_CTLSTAT, DC_FLUSH, 3);
+ cmd[2] = CP_PACKET0(RB3D_DSTCACHE_CTLSTAT, 0);
+ cmd[3] = REG_S(RB3D_DSTCACHE_CTLSTAT, DC_FLUSH, 3);
+ cmd[4] = CP_PACKET0(RB3D_ZCACHE_CTLSTAT, 0);
+ cmd[5] = RB3D_ZCACHE_CTLSTAT__ZC_FLUSH;
+ /* try to wait but if we timeout we likely are in bad situation */
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ ret = radeon_ms_ring_emit(dev, cmd, 6);
+ if (!ret) {
+ break;
+ }
+ }
+}
+
+static void r300_flush_cache(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t cmd[6];
+ int i, ret;
+
+ cmd[0] = CP_PACKET0(RB2D_DSTCACHE_CTLSTAT, 0);
+ cmd[1] = REG_S(RB2D_DSTCACHE_CTLSTAT, DC_FLUSH, 3);
+ cmd[2] = CP_PACKET0(RB3D_DSTCACHE_CTLSTAT_R3, 0);
+ cmd[3] = REG_S(RB3D_DSTCACHE_CTLSTAT_R3, DC_FLUSH, 3);
+ cmd[4] = CP_PACKET0(RB3D_ZCACHE_CTLSTAT_R3, 0);
+ cmd[5] = RB3D_ZCACHE_CTLSTAT_R3__ZC_FLUSH;
+ /* try to wait but if we timeout we likely are in bad situation */
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ ret = radeon_ms_ring_emit(dev, cmd, 6);
+ if (!ret) {
+ break;
+ }
+ }
+}
+
+int radeon_ms_family_init(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ int ret;
+
+ dev_priv->microcode = radeon_cp_microcode;
+ dev_priv->irq_emit = radeon_ms_irq_emit;
+
+ switch (dev_priv->family) {
+ case CHIP_R100:
+ case CHIP_R200:
+ dev_priv->microcode = radeon_cp_microcode;
+ dev_priv->flush_cache = radeon_flush_cache;
+ break;
+ case CHIP_RV200:
+ case CHIP_RV250:
+ case CHIP_RV280:
+ case CHIP_RS300:
+ dev_priv->microcode = r200_cp_microcode;
+ dev_priv->flush_cache = radeon_flush_cache;
+ break;
+ case CHIP_R300:
+ case CHIP_R350:
+ case CHIP_R360:
+ case CHIP_RV350:
+ case CHIP_RV370:
+ case CHIP_RV380:
+ case CHIP_RS400:
+ case CHIP_RV410:
+ case CHIP_R420:
+ case CHIP_R430:
+ case CHIP_R480:
+ dev_priv->microcode = r300_cp_microcode;
+ dev_priv->flush_cache = r300_flush_cache;
+ break;
+ default:
+ DRM_ERROR("Unknown radeon family, aborting\n");
+ return -EINVAL;
+ }
+ switch (dev_priv->bus_type) {
+ case RADEON_AGP:
+ dev_priv->create_ttm = drm_agp_init_ttm;
+ dev_priv->bus_init = radeon_ms_agp_init;
+ dev_priv->bus_restore = radeon_ms_agp_restore;
+ dev_priv->bus_save = radeon_ms_agp_save;
+ break;
+ case RADEON_PCIE:
+ dev_priv->create_ttm = radeon_ms_pcie_create_ttm;
+ dev_priv->bus_finish = radeon_ms_pcie_finish;
+ dev_priv->bus_init = radeon_ms_pcie_init;
+ dev_priv->bus_restore = radeon_ms_pcie_restore;
+ dev_priv->bus_save = radeon_ms_pcie_save;
+ break;
+ default:
+ DRM_ERROR("Unknown radeon bus type, aborting\n");
+ return -EINVAL;
+ }
+ ret = radeon_ms_rom_init(dev);
+ if (ret) {
+ return ret;
+ }
+ ret = radeon_ms_properties_init(dev);
+ return ret;
+}
diff --git a/shared-core/radeon_ms_fence.c b/shared-core/radeon_ms_fence.c
new file mode 100644
index 00000000..6fcf5437
--- /dev/null
+++ b/shared-core/radeon_ms_fence.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2007 Dave Airlie.
+ * Copyright 2007 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * Authors:
+ * Dave Airlie
+ * Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "radeon_ms.h"
+
+static void radeon_ms_fence_flush(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct drm_fence_class_manager *fc = &dev->fm.fence_class[0];
+ uint32_t pending_flush_types = 0;
+ uint32_t sequence;
+
+ if (dev_priv == NULL) {
+ return;
+ }
+ pending_flush_types = fc->pending_flush |
+ ((fc->pending_exe_flush) ?
+ DRM_FENCE_TYPE_EXE : 0);
+ if (pending_flush_types) {
+ sequence = mmio_read(dev_priv, dev_priv->fence_reg);
+ drm_fence_handler(dev, 0, sequence, pending_flush_types, 0);
+ }
+}
+
+int radeon_ms_fence_emit_sequence(struct drm_device *dev, uint32_t class,
+ uint32_t flags, uint32_t *sequence,
+ uint32_t *native_type)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t fence_id, cmd[2], i, ret;
+
+ if (!dev_priv || dev_priv->cp_ready != 1) {
+ return -EINVAL;
+ }
+ fence_id = (++dev_priv->fence_id_last);
+ if (dev_priv->fence_id_last > 0x7FFFFFFF) {
+ fence_id = dev_priv->fence_id_last = 1;
+ }
+ *sequence = fence_id;
+ *native_type = DRM_FENCE_TYPE_EXE;
+ if (flags & DRM_RADEON_FENCE_FLAG_FLUSHED) {
+ *native_type |= DRM_RADEON_FENCE_TYPE_RW;
+ dev_priv->flush_cache(dev);
+ }
+ cmd[0] = CP_PACKET0(dev_priv->fence_reg, 0);
+ cmd[1] = fence_id;
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ ret = radeon_ms_ring_emit(dev, cmd, 2);
+ if (!ret) {
+ dev_priv->irq_emit(dev);
+ return 0;
+ }
+ }
+ return -EBUSY;
+}
+
+void radeon_ms_fence_handler(struct drm_device * dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct drm_fence_manager *fm = &dev->fm;
+
+ if (dev_priv == NULL) {
+ return;
+ }
+
+ write_lock(&fm->lock);
+ radeon_ms_fence_flush(dev);
+ write_unlock(&fm->lock);
+}
+
+int radeon_ms_fence_has_irq(struct drm_device *dev, uint32_t class,
+ uint32_t flags)
+{
+ /*
+ * We have an irq that tells us when we have a new breadcrumb.
+ */
+ if (class == 0 && flags == DRM_FENCE_TYPE_EXE)
+ return 1;
+
+ return 0;
+}
+
+int radeon_ms_fence_types(struct drm_buffer_object *bo,
+ uint32_t *class, uint32_t *type)
+{
+ *class = 0;
+ if (bo->mem.flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE))
+ *type = 3;
+ else
+ *type = 1;
+ return 0;
+}
+
+void radeon_ms_poke_flush(struct drm_device *dev, uint32_t class)
+{
+ struct drm_fence_manager *fm = &dev->fm;
+ unsigned long flags;
+
+ if (class != 0)
+ return;
+ write_lock_irqsave(&fm->lock, flags);
+ radeon_ms_fence_flush(dev);
+ write_unlock_irqrestore(&fm->lock, flags);
+}
diff --git a/shared-core/radeon_ms_gpu.c b/shared-core/radeon_ms_gpu.c
new file mode 100644
index 00000000..28683781
--- /dev/null
+++ b/shared-core/radeon_ms_gpu.c
@@ -0,0 +1,589 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Alex Deucher
+ * Copyright 2007 Dave Airlie
+ * All Rights Reserved.
+ *
+ * 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 on 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
+ * THEIR SUPPLIERS 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 "radeon_ms.h"
+
+static int radeon_ms_gpu_address_space_init(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_state *state = &dev_priv->driver_state;
+
+ /* initialize gpu mapping */
+ dev_priv->gpu_vram_start = dev_priv->vram.offset;
+ dev_priv->gpu_vram_end = dev_priv->gpu_vram_start + dev_priv->vram.size;
+ /* align it on 16Mo boundary (clamp memory which is then
+ * unreachable but not manufacturer should use strange
+ * memory size */
+ dev_priv->gpu_vram_end = dev_priv->gpu_vram_end & (~0xFFFFFF);
+ dev_priv->gpu_vram_end -= 1;
+ dev_priv->gpu_vram_size = dev_priv->gpu_vram_end -
+ dev_priv->gpu_vram_start + 1;
+ /* set gart size to 32Mo FIXME: should make a parameter for this */
+ dev_priv->gpu_gart_size = 1024 * 1024 * 32;
+ if (dev_priv->gpu_gart_size > (0xffffffffU - dev_priv->gpu_vram_end)) {
+ /* align gart start to next 4Ko in gpu address space */
+ dev_priv->gpu_gart_start = (dev_priv->gpu_vram_end + 1) + 0xfff;
+ dev_priv->gpu_gart_start = dev_priv->gpu_gart_start & (~0xfff);
+ dev_priv->gpu_gart_end = dev_priv->gpu_gart_start +
+ dev_priv->gpu_gart_size;
+ dev_priv->gpu_gart_end = (dev_priv->gpu_gart_end & (~0xfff)) -
+ 0x1000;
+ } else {
+ /* align gart start to next 4Ko in gpu address space */
+ dev_priv->gpu_gart_start = (dev_priv->gpu_vram_start & ~0xfff) -
+ dev_priv->gpu_gart_size;
+ dev_priv->gpu_gart_start = dev_priv->gpu_gart_start & (~0xfff);
+ dev_priv->gpu_gart_end = dev_priv->gpu_gart_start +
+ dev_priv->gpu_gart_size;
+ dev_priv->gpu_gart_end = (dev_priv->gpu_gart_end & (~0xfff)) -
+ 0x1000;
+ }
+ state->mc_fb_location =
+ REG_S(MC_FB_LOCATION, MC_FB_START,
+ dev_priv->gpu_vram_start >> 16) |
+ REG_S(MC_FB_LOCATION, MC_FB_TOP, dev_priv->gpu_vram_end >> 16);
+ state->display_base_addr =
+ REG_S(DISPLAY_BASE_ADDR, DISPLAY_BASE_ADDR,
+ dev_priv->gpu_vram_start);
+ state->config_aper_0_base = dev_priv->gpu_vram_start;
+ state->config_aper_1_base = dev_priv->gpu_vram_start;
+ state->config_aper_size = dev_priv->gpu_vram_size;
+ DRM_INFO("[radeon_ms] gpu vram start 0x%08X\n",
+ dev_priv->gpu_vram_start);
+ DRM_INFO("[radeon_ms] gpu vram end 0x%08X\n",
+ dev_priv->gpu_vram_end);
+ DRM_INFO("[radeon_ms] gpu gart start 0x%08X\n",
+ dev_priv->gpu_gart_start);
+ DRM_INFO("[radeon_ms] gpu gart end 0x%08X\n",
+ dev_priv->gpu_gart_end);
+ return 0;
+}
+
+static void radeon_ms_gpu_reset(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t clock_cntl_index, mclk_cntl, rbbm_soft_reset;
+ uint32_t reset_mask, host_path_cntl, cache_mode;
+
+ radeon_ms_cp_stop(dev);
+ radeon_ms_gpu_flush(dev);
+
+ /* reset clock */
+ clock_cntl_index = MMIO_R(CLOCK_CNTL_INDEX);
+ pll_index_errata(dev_priv);
+ mclk_cntl = PPLL_R(MCLK_CNTL);
+ PPLL_W(MCLK_CNTL,
+ mclk_cntl |
+ MCLK_CNTL__FORCE_MCLKA |
+ MCLK_CNTL__FORCE_MCLKB |
+ MCLK_CNTL__FORCE_YCLKA |
+ MCLK_CNTL__FORCE_YCLKB |
+ MCLK_CNTL__FORCE_MC |
+ MCLK_CNTL__FORCE_AIC);
+ PPLL_W(SCLK_CNTL,
+ PPLL_R(SCLK_CNTL) |
+ SCLK_CNTL__FORCE_CP |
+ SCLK_CNTL__FORCE_VIP);
+
+ /* Soft resetting HDP thru RBBM_SOFT_RESET register can cause some
+ * unexpected behaviour on some machines. Here we use
+ * RADEON_HOST_PATH_CNTL to reset it.
+ */
+ host_path_cntl = MMIO_R(HOST_PATH_CNTL);
+ rbbm_soft_reset = MMIO_R(RBBM_SOFT_RESET);
+ reset_mask = RBBM_SOFT_RESET__SOFT_RESET_CP |
+ RBBM_SOFT_RESET__SOFT_RESET_HI |
+ RBBM_SOFT_RESET__SOFT_RESET_VAP |
+ RBBM_SOFT_RESET__SOFT_RESET_SE |
+ RBBM_SOFT_RESET__SOFT_RESET_RE |
+ RBBM_SOFT_RESET__SOFT_RESET_PP |
+ RBBM_SOFT_RESET__SOFT_RESET_E2 |
+ RBBM_SOFT_RESET__SOFT_RESET_RB;
+ MMIO_W(RBBM_SOFT_RESET, rbbm_soft_reset | reset_mask);
+ MMIO_R(RBBM_SOFT_RESET);
+ MMIO_W(RBBM_SOFT_RESET, 0);
+ MMIO_R(RBBM_SOFT_RESET);
+
+ cache_mode = MMIO_R(RB2D_DSTCACHE_MODE);
+ MMIO_W(RB2D_DSTCACHE_MODE,
+ cache_mode | RB2D_DSTCACHE_MODE__DC_DISABLE_IGNORE_PE);
+
+ MMIO_W(HOST_PATH_CNTL, host_path_cntl | HOST_PATH_CNTL__HDP_SOFT_RESET);
+ MMIO_R(HOST_PATH_CNTL);
+ MMIO_W(HOST_PATH_CNTL, host_path_cntl);
+ MMIO_R(HOST_PATH_CNTL);
+
+ MMIO_W(CLOCK_CNTL_INDEX, clock_cntl_index);
+ pll_index_errata(dev_priv);
+ PPLL_W(MCLK_CNTL, mclk_cntl);
+}
+
+static void radeon_ms_gpu_resume(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t a;
+ uint32_t i;
+
+ /* make sure we have sane offset before restoring crtc */
+ a = (MMIO_R(MC_FB_LOCATION) & MC_FB_LOCATION__MC_FB_START__MASK) << 16;
+ MMIO_W(DISPLAY_BASE_ADDR, a);
+ MMIO_W(CRTC2_DISPLAY_BASE_ADDR, a);
+ MMIO_W(CRTC_OFFSET, 0);
+ MMIO_W(CUR_OFFSET, 0);
+ MMIO_W(CRTC_OFFSET_CNTL, CRTC_OFFSET_CNTL__CRTC_OFFSET_FLIP_CNTL);
+ MMIO_W(CRTC2_OFFSET, 0);
+ MMIO_W(CUR2_OFFSET, 0);
+ MMIO_W(CRTC2_OFFSET_CNTL, CRTC2_OFFSET_CNTL__CRTC2_OFFSET_FLIP_CNTL);
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if (!(CRTC_OFFSET__CRTC_GUI_TRIG_OFFSET &
+ MMIO_R(CRTC_OFFSET))) {
+ break;
+ }
+ DRM_UDELAY(1);
+ }
+ if (i >= dev_priv->usec_timeout) {
+ DRM_ERROR("[radeon_ms] timeout waiting for crtc...\n");
+ }
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if (!(CRTC2_OFFSET__CRTC2_GUI_TRIG_OFFSET &
+ MMIO_R(CRTC2_OFFSET))) {
+ break;
+ }
+ DRM_UDELAY(1);
+ }
+ if (i >= dev_priv->usec_timeout) {
+ DRM_ERROR("[radeon_ms] timeout waiting for crtc...\n");
+ }
+ DRM_UDELAY(10000);
+}
+
+static void radeon_ms_gpu_stop(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t ov0_scale_cntl, crtc_ext_cntl, crtc_gen_cntl;
+ uint32_t crtc2_gen_cntl, i;
+
+ radeon_ms_wait_for_idle(dev);
+ /* Capture MC_STATUS in case things go wrong ... */
+ ov0_scale_cntl = dev_priv->ov0_scale_cntl = MMIO_R(OV0_SCALE_CNTL);
+ crtc_ext_cntl = dev_priv->crtc_ext_cntl = MMIO_R(CRTC_EXT_CNTL);
+ crtc_gen_cntl = dev_priv->crtc_gen_cntl = MMIO_R(CRTC_GEN_CNTL);
+ crtc2_gen_cntl = dev_priv->crtc2_gen_cntl = MMIO_R(CRTC2_GEN_CNTL);
+ ov0_scale_cntl &= ~OV0_SCALE_CNTL__OV0_OVERLAY_EN__MASK;
+ crtc_ext_cntl |= CRTC_EXT_CNTL__CRTC_DISPLAY_DIS;
+ crtc_gen_cntl &= ~CRTC_GEN_CNTL__CRTC_CUR_EN;
+ crtc_gen_cntl &= ~CRTC_GEN_CNTL__CRTC_ICON_EN;
+ crtc_gen_cntl |= CRTC_GEN_CNTL__CRTC_EXT_DISP_EN;
+ crtc_gen_cntl |= CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B;
+ crtc2_gen_cntl &= ~CRTC2_GEN_CNTL__CRTC2_CUR_EN;
+ crtc2_gen_cntl &= ~CRTC2_GEN_CNTL__CRTC2_ICON_EN;
+ crtc2_gen_cntl |= CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B;
+ MMIO_W(OV0_SCALE_CNTL, ov0_scale_cntl);
+ MMIO_W(CRTC_EXT_CNTL, crtc_ext_cntl);
+ MMIO_W(CRTC_GEN_CNTL, crtc_gen_cntl);
+ MMIO_W(CRTC2_GEN_CNTL, crtc2_gen_cntl);
+ DRM_UDELAY(10000);
+ switch (dev_priv->family) {
+ case CHIP_R100:
+ case CHIP_R200:
+ case CHIP_RV200:
+ case CHIP_RV250:
+ case CHIP_RV280:
+ case CHIP_RS300:
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if ((MC_STATUS__MC_IDLE & MMIO_R(MC_STATUS))) {
+ DRM_INFO("[radeon_ms] gpu stoped in %d usecs\n",
+ i);
+ return;
+ }
+ DRM_UDELAY(1);
+ }
+ break;
+ case CHIP_R300:
+ case CHIP_R350:
+ case CHIP_R360:
+ case CHIP_RV350:
+ case CHIP_RV370:
+ case CHIP_RV380:
+ case CHIP_RS400:
+ case CHIP_RV410:
+ case CHIP_R420:
+ case CHIP_R430:
+ case CHIP_R480:
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if ((MC_STATUS__MC_IDLE_R3 & MMIO_R(MC_STATUS))) {
+ DRM_INFO("[radeon_ms] gpu stoped in %d usecs\n",
+ i);
+ return;
+ }
+ DRM_UDELAY(1);
+ }
+ break;
+ default:
+ DRM_ERROR("Unknown radeon family, aborting\n");
+ return;
+ }
+ DRM_ERROR("[radeon_ms] failed to stop gpu...will proceed anyway\n");
+ DRM_UDELAY(20000);
+}
+
+static int radeon_ms_wait_for_fifo(struct drm_device *dev, int num_fifo)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ int i;
+
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ int t;
+ t = RBBM_STATUS__CMDFIFO_AVAIL__MASK & MMIO_R(RBBM_STATUS);
+ t = t >> RBBM_STATUS__CMDFIFO_AVAIL__SHIFT;
+ if (t >= num_fifo)
+ return 0;
+ DRM_UDELAY(1);
+ }
+ DRM_ERROR("[radeon_ms] failed to wait for fifo\n");
+ return -EBUSY;
+}
+
+int radeon_ms_gpu_initialize(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_state *state = &dev_priv->driver_state;
+ int ret;
+
+ state->disp_misc_cntl = DISP_MISC_CNTL__SYNC_PAD_FLOP_EN |
+ REG_S(DISP_MISC_CNTL, SYNC_STRENGTH, 2) |
+ REG_S(DISP_MISC_CNTL, PALETTE_MEM_RD_MARGIN, 0xb) |
+ REG_S(DISP_MISC_CNTL, PALETTE2_MEM_RD_MARGIN, 0xb) |
+ REG_S(DISP_MISC_CNTL, RMX_BUF_MEM_RD_MARGIN, 0x5);
+ state->disp_merge_cntl = REG_S(DISP_MERGE_CNTL, DISP_GRPH_ALPHA, 0xff) |
+ REG_S(DISP_MERGE_CNTL, DISP_OV0_ALPHA, 0xff);
+ state->disp_pwr_man = DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN |
+ DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN |
+ REG_S(DISP_PWR_MAN, DISP_PWR_MAN_DPMS, DISP_PWR_MAN_DPMS__OFF) |
+ DISP_PWR_MAN__DISP_D3_RST |
+ DISP_PWR_MAN__DISP_D3_REG_RST |
+ DISP_PWR_MAN__DISP_D3_GRPH_RST |
+ DISP_PWR_MAN__DISP_D3_SUBPIC_RST |
+ DISP_PWR_MAN__DISP_D3_OV0_RST |
+ DISP_PWR_MAN__DISP_D1D2_GRPH_RST |
+ DISP_PWR_MAN__DISP_D1D2_SUBPIC_RST |
+ DISP_PWR_MAN__DISP_D1D2_OV0_RST |
+ DISP_PWR_MAN__DISP_DVO_ENABLE_RST |
+ DISP_PWR_MAN__TV_ENABLE_RST;
+ state->disp2_merge_cntl = 0;
+ ret = radeon_ms_gpu_address_space_init(dev);
+ if (ret) {
+ return ret;
+ }
+
+ /* initialize bus */
+ ret = dev_priv->bus_init(dev);
+ if (ret != 0) {
+ return ret;
+ }
+ return 0;
+}
+
+void radeon_ms_gpu_dpms(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_state *state = &dev_priv->driver_state;
+
+ if (dev_priv->crtc1_dpms == dev_priv->crtc2_dpms) {
+ /* both crtc are in same state so use global display pwr */
+ state->disp_pwr_man &= ~DISP_PWR_MAN__DISP_PWR_MAN_DPMS__MASK;
+ switch(dev_priv->crtc1_dpms) {
+ case DPMSModeOn:
+ state->disp_pwr_man |= REG_S(DISP_PWR_MAN,
+ DISP_PWR_MAN_DPMS,
+ DISP_PWR_MAN_DPMS__ON);
+ break;
+ case DPMSModeStandby:
+ state->disp_pwr_man |= REG_S(DISP_PWR_MAN,
+ DISP_PWR_MAN_DPMS,
+ DISP_PWR_MAN_DPMS__STANDBY);
+ break;
+ case DPMSModeSuspend:
+ state->disp_pwr_man |= REG_S(DISP_PWR_MAN,
+ DISP_PWR_MAN_DPMS,
+ DISP_PWR_MAN_DPMS__SUSPEND);
+ break;
+ case DPMSModeOff:
+ state->disp_pwr_man |= REG_S(DISP_PWR_MAN,
+ DISP_PWR_MAN_DPMS,
+ DISP_PWR_MAN_DPMS__OFF);
+ break;
+ default:
+ /* error */
+ break;
+ }
+ MMIO_W(DISP_PWR_MAN, state->disp_pwr_man);
+ } else {
+ state->disp_pwr_man &= ~DISP_PWR_MAN__DISP_PWR_MAN_DPMS__MASK;
+ state->disp_pwr_man |= REG_S(DISP_PWR_MAN,
+ DISP_PWR_MAN_DPMS,
+ DISP_PWR_MAN_DPMS__ON);
+ MMIO_W(DISP_PWR_MAN, state->disp_pwr_man);
+ }
+}
+
+void radeon_ms_gpu_flush(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t i;
+ uint32_t purge2d;
+ uint32_t purge3d;
+
+ switch (dev_priv->family) {
+ case CHIP_R100:
+ case CHIP_R200:
+ case CHIP_RV200:
+ case CHIP_RV250:
+ case CHIP_RV280:
+ case CHIP_RS300:
+ purge2d = REG_S(RB2D_DSTCACHE_CTLSTAT, DC_FLUSH, 3) |
+ REG_S(RB2D_DSTCACHE_CTLSTAT, DC_FREE, 3);
+ purge3d = REG_S(RB3D_DSTCACHE_CTLSTAT, DC_FLUSH, 3) |
+ REG_S(RB3D_DSTCACHE_CTLSTAT, DC_FREE, 3);
+ MMIO_W(RB2D_DSTCACHE_CTLSTAT, purge2d);
+ MMIO_W(RB3D_DSTCACHE_CTLSTAT, purge3d);
+ break;
+ case CHIP_R300:
+ case CHIP_R350:
+ case CHIP_R360:
+ case CHIP_RV350:
+ case CHIP_RV370:
+ case CHIP_RV380:
+ case CHIP_RS400:
+ case CHIP_RV410:
+ case CHIP_R420:
+ case CHIP_R430:
+ case CHIP_R480:
+ purge2d = REG_S(RB2D_DSTCACHE_CTLSTAT, DC_FLUSH, 3) |
+ REG_S(RB2D_DSTCACHE_CTLSTAT, DC_FREE, 3);
+ purge3d = REG_S(RB3D_DSTCACHE_CTLSTAT_R3, DC_FLUSH, 3) |
+ REG_S(RB3D_DSTCACHE_CTLSTAT_R3, DC_FREE, 3);
+ MMIO_W(RB2D_DSTCACHE_CTLSTAT, purge2d);
+ MMIO_W(RB3D_DSTCACHE_CTLSTAT_R3, purge3d);
+ break;
+ default:
+ DRM_ERROR("Unknown radeon family, aborting\n");
+ return;
+ }
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if (!(RB2D_DSTCACHE_CTLSTAT__DC_BUSY &
+ MMIO_R(RB2D_DSTCACHE_CTLSTAT))) {
+ return;
+ }
+ DRM_UDELAY(1);
+ }
+ DRM_ERROR("[radeon_ms] gpu flush timeout\n");
+}
+
+void radeon_ms_gpu_restore(struct drm_device *dev, struct radeon_state *state)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t wait_until;
+ uint32_t fbstart;
+ int ret, ok = 1;
+
+ radeon_ms_gpu_reset(dev);
+ radeon_ms_wait_for_idle(dev);
+ radeon_ms_gpu_stop(dev);
+
+ MMIO_W(AIC_CTRL, state->aic_ctrl);
+ MMIO_W(MC_FB_LOCATION, state->mc_fb_location);
+ MMIO_R(MC_FB_LOCATION);
+ MMIO_W(CONFIG_APER_0_BASE, state->config_aper_0_base);
+ MMIO_W(CONFIG_APER_1_BASE, state->config_aper_1_base);
+ MMIO_W(CONFIG_APER_SIZE, state->config_aper_size);
+ MMIO_W(DISPLAY_BASE_ADDR, state->display_base_addr);
+ if (dev_priv->bus_restore) {
+ dev_priv->bus_restore(dev, state);
+ }
+
+ radeon_ms_gpu_reset(dev);
+ radeon_ms_gpu_resume(dev);
+
+ MMIO_W(BUS_CNTL, state->bus_cntl);
+ wait_until = WAIT_UNTIL__WAIT_DMA_VIPH0_IDLE |
+ WAIT_UNTIL__WAIT_DMA_VIPH1_IDLE |
+ WAIT_UNTIL__WAIT_DMA_VIPH2_IDLE |
+ WAIT_UNTIL__WAIT_DMA_VIPH3_IDLE |
+ WAIT_UNTIL__WAIT_DMA_VID_IDLE |
+ WAIT_UNTIL__WAIT_DMA_GUI_IDLE |
+ WAIT_UNTIL__WAIT_2D_IDLE |
+ WAIT_UNTIL__WAIT_3D_IDLE |
+ WAIT_UNTIL__WAIT_2D_IDLECLEAN |
+ WAIT_UNTIL__WAIT_3D_IDLECLEAN |
+ WAIT_UNTIL__WAIT_HOST_IDLECLEAN;
+ switch (dev_priv->family) {
+ case CHIP_R100:
+ case CHIP_R200:
+ case CHIP_RV200:
+ case CHIP_RV250:
+ case CHIP_RV280:
+ case CHIP_RS300:
+ break;
+ case CHIP_R300:
+ case CHIP_R350:
+ case CHIP_R360:
+ case CHIP_RV350:
+ case CHIP_RV370:
+ case CHIP_RV380:
+ case CHIP_RS400:
+ case CHIP_RV410:
+ case CHIP_R420:
+ case CHIP_R430:
+ case CHIP_R480:
+ wait_until |= WAIT_UNTIL__WAIT_VAP_IDLE;
+ break;
+ }
+ MMIO_W(WAIT_UNTIL, wait_until);
+ MMIO_W(DISP_MISC_CNTL, state->disp_misc_cntl);
+ MMIO_W(DISP_PWR_MAN, state->disp_pwr_man);
+ MMIO_W(DISP_MERGE_CNTL, state->disp_merge_cntl);
+ MMIO_W(DISP_OUTPUT_CNTL, state->disp_output_cntl);
+ MMIO_W(DISP2_MERGE_CNTL, state->disp2_merge_cntl);
+
+ /* Setup engine location. This shouldn't be necessary since we
+ * set them appropriately before any accel ops, but let's avoid
+ * random bogus DMA in case we inadvertently trigger the engine
+ * in the wrong place (happened).
+ */
+ ret = radeon_ms_wait_for_fifo(dev, 2);
+ if (ret) {
+ ok = 0;
+ DRM_ERROR("[radeon_ms] no fifo for setting up dst & src gui\n");
+ DRM_ERROR("[radeon_ms] proceed anyway\n");
+ }
+ fbstart = (MC_FB_LOCATION__MC_FB_START__MASK &
+ MMIO_R(MC_FB_LOCATION)) << 16;
+ MMIO_W(DST_PITCH_OFFSET,
+ REG_S(DST_PITCH_OFFSET, DST_OFFSET, fbstart >> 10));
+ MMIO_W(SRC_PITCH_OFFSET,
+ REG_S(SRC_PITCH_OFFSET, SRC_OFFSET, fbstart >> 10));
+
+ ret = radeon_ms_wait_for_fifo(dev, 1);
+ if (ret) {
+ ok = 0;
+ DRM_ERROR("[radeon_ms] no fifo for setting up dp data type\n");
+ DRM_ERROR("[radeon_ms] proceed anyway\n");
+ }
+#ifdef __BIG_ENDIAN
+ MMIO_W(DP_DATATYPE, DP_DATATYPE__DP_BYTE_PIX_ORDER);
+#else
+ MMIO_W(DP_DATATYPE, 0);
+#endif
+
+ ret = radeon_ms_wait_for_fifo(dev, 1);
+ if (ret) {
+ ok = 0;
+ DRM_ERROR("[radeon_ms] no fifo for setting up surface cntl\n");
+ DRM_ERROR("[radeon_ms] proceed anyway\n");
+ }
+ MMIO_W(SURFACE_CNTL, SURFACE_CNTL__SURF_TRANSLATION_DIS);
+
+ ret = radeon_ms_wait_for_fifo(dev, 2);
+ if (ret) {
+ ok = 0;
+ DRM_ERROR("[radeon_ms] no fifo for setting scissor\n");
+ DRM_ERROR("[radeon_ms] proceed anyway\n");
+ }
+ MMIO_W(DEFAULT_SC_BOTTOM_RIGHT, 0x1fff1fff);
+ MMIO_W(DEFAULT2_SC_BOTTOM_RIGHT, 0x1fff1fff);
+
+ ret = radeon_ms_wait_for_fifo(dev, 1);
+ if (ret) {
+ ok = 0;
+ DRM_ERROR("[radeon_ms] no fifo for setting up gui cntl\n");
+ DRM_ERROR("[radeon_ms] proceed anyway\n");
+ }
+ MMIO_W(DP_GUI_MASTER_CNTL, 0);
+
+ ret = radeon_ms_wait_for_fifo(dev, 5);
+ if (ret) {
+ ok = 0;
+ DRM_ERROR("[radeon_ms] no fifo for setting up clear color\n");
+ DRM_ERROR("[radeon_ms] proceed anyway\n");
+ }
+ MMIO_W(DP_BRUSH_BKGD_CLR, 0x00000000);
+ MMIO_W(DP_BRUSH_FRGD_CLR, 0xffffffff);
+ MMIO_W(DP_SRC_BKGD_CLR, 0x00000000);
+ MMIO_W(DP_SRC_FRGD_CLR, 0xffffffff);
+ MMIO_W(DP_WRITE_MSK, 0xffffffff);
+
+ if (!ok) {
+ DRM_ERROR("[radeon_ms] engine restore not enough fifo\n");
+ }
+}
+
+void radeon_ms_gpu_save(struct drm_device *dev, struct radeon_state *state)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ state->aic_ctrl = MMIO_R(AIC_CTRL);
+ state->bus_cntl = MMIO_R(BUS_CNTL);
+ state->mc_fb_location = MMIO_R(MC_FB_LOCATION);
+ state->display_base_addr = MMIO_R(DISPLAY_BASE_ADDR);
+ state->config_aper_0_base = MMIO_R(CONFIG_APER_0_BASE);
+ state->config_aper_1_base = MMIO_R(CONFIG_APER_1_BASE);
+ state->config_aper_size = MMIO_R(CONFIG_APER_SIZE);
+ state->disp_misc_cntl = MMIO_R(DISP_MISC_CNTL);
+ state->disp_pwr_man = MMIO_R(DISP_PWR_MAN);
+ state->disp_merge_cntl = MMIO_R(DISP_MERGE_CNTL);
+ state->disp_output_cntl = MMIO_R(DISP_OUTPUT_CNTL);
+ state->disp2_merge_cntl = MMIO_R(DISP2_MERGE_CNTL);
+ if (dev_priv->bus_save) {
+ dev_priv->bus_save(dev, state);
+ }
+}
+
+int radeon_ms_wait_for_idle(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ int i, j, ret;
+
+ for (i = 0; i < 2; i++) {
+ ret = radeon_ms_wait_for_fifo(dev, 64);
+ if (ret) {
+ DRM_ERROR("[radeon_ms] fifo not empty\n");
+ }
+ for (j = 0; j < dev_priv->usec_timeout; j++) {
+ if (!(RBBM_STATUS__GUI_ACTIVE & MMIO_R(RBBM_STATUS))) {
+ radeon_ms_gpu_flush(dev);
+ return 0;
+ }
+ DRM_UDELAY(1);
+ }
+ DRM_ERROR("[radeon_ms] idle timed out: status=0x%08x\n",
+ MMIO_R(RBBM_STATUS));
+ radeon_ms_gpu_stop(dev);
+ radeon_ms_gpu_reset(dev);
+ }
+ return -EBUSY;
+}
diff --git a/shared-core/radeon_ms_i2c.c b/shared-core/radeon_ms_i2c.c
new file mode 100644
index 00000000..f4468c1e
--- /dev/null
+++ b/shared-core/radeon_ms_i2c.c
@@ -0,0 +1,336 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Alex Deucher
+ * Copyright 2007 Dave Airlie
+ * All Rights Reserved.
+ *
+ * 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 on 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
+ * THEIR SUPPLIERS 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 "radeon_ms.h"
+
+static int get_clock(void *data)
+{
+ struct radeon_ms_i2c *i2c = data;
+ struct drm_radeon_private *dev_priv = i2c->drm_dev->dev_private;
+ int v;
+
+ switch (i2c->reg) {
+ case VIPPAD_EN:
+ v = MMIO_R(VIPPAD_Y);
+ if ((REG_G(VIPPAD_Y, VIPPAD_Y_VHAD, v) & 2)) {
+ v = 1;
+ } else {
+ v = 0;
+ }
+ break;
+ case VIPPAD1_EN:
+ v = MMIO_R(VIPPAD1_Y);
+ if ((REG_G(VIPPAD1_Y, VIPPAD_Y_DVODATA, v) & 8)) {
+ v = 1;
+ } else {
+ v = 0;
+ }
+ break;
+ case GPIO_DDC1:
+ v = MMIO_R(GPIO_DDC1);
+ if ((GPIO_DDC1__DDC1_CLK_INPUT & v)) {
+ v = 1;
+ } else {
+ v = 0;
+ }
+ break;
+ case GPIO_DDC2:
+ v = MMIO_R(GPIO_DDC2);
+ if ((GPIO_DDC2__DDC2_CLK_INPUT & v)) {
+ v = 1;
+ } else {
+ v = 0;
+ }
+ break;
+ case GPIO_MONID:
+ v = MMIO_R(GPIO_MONID);
+ if ((GPIO_MONID__GPIO_MONID_1_INPUT & v)) {
+ v = 1;
+ } else {
+ v = 0;
+ }
+ break;
+ case GPIO_CRT2_DDC:
+ v = MMIO_R(GPIO_CRT2_DDC);
+ if ((GPIO_CRT2_DDC__CRT2_DDC_CLK_INPUT & v)) {
+ v = 1;
+ } else {
+ v = 0;
+ }
+ break;
+ default:
+ v = 0;
+ break;
+ }
+ return v;
+}
+
+static int get_data(void *data)
+{
+ struct radeon_ms_i2c *i2c = data;
+ struct drm_radeon_private *dev_priv = i2c->drm_dev->dev_private;
+ int v;
+
+ switch (i2c->reg) {
+ case VIPPAD_EN:
+ v = MMIO_R(VIPPAD_Y);
+ if ((REG_G(VIPPAD_Y, VIPPAD_Y_VHAD, v) & 1)) {
+ v = 1;
+ } else {
+ v = 0;
+ }
+ break;
+ case VIPPAD1_EN:
+ v = MMIO_R(VIPPAD1_Y);
+ if ((REG_G(VIPPAD1_Y, VIPPAD_Y_DVODATA, v) & 4)) {
+ v = 1;
+ } else {
+ v = 0;
+ }
+ break;
+ case GPIO_DDC1:
+ v = MMIO_R(GPIO_DDC1);
+ if ((GPIO_DDC1__DDC1_DATA_INPUT & v)) {
+ v = 1;
+ } else {
+ v = 0;
+ }
+ break;
+ case GPIO_DDC2:
+ v = MMIO_R(GPIO_DDC2);
+ if ((GPIO_DDC2__DDC2_DATA_INPUT & v)) {
+ v = 1;
+ } else {
+ v = 0;
+ }
+ break;
+ case GPIO_MONID:
+ v = MMIO_R(GPIO_MONID);
+ if ((GPIO_MONID__GPIO_MONID_0_INPUT & v)) {
+ v = 1;
+ } else {
+ v = 0;
+ }
+ break;
+ case GPIO_CRT2_DDC:
+ v = MMIO_R(GPIO_CRT2_DDC);
+ if ((GPIO_CRT2_DDC__CRT2_DDC_DATA_INPUT & v)) {
+ v = 1;
+ } else {
+ v = 0;
+ }
+ break;
+ default:
+ v = 0;
+ break;
+ }
+ return v;
+}
+
+static void set_clock(void *i2c_priv, int clock)
+{
+ struct radeon_ms_i2c *i2c = i2c_priv;
+ struct drm_radeon_private *dev_priv = i2c->drm_dev->dev_private;
+ int v, line;
+
+ v = MMIO_R(i2c->reg);
+ switch (i2c->reg) {
+ case VIPPAD_EN:
+ line = REG_G(VIPPAD_EN, VIPPAD_EN_VHAD, v) & ~2;
+ v &= ~VIPPAD_EN__VIPPAD_EN_VHAD__MASK;
+ if (!clock) {
+ v |= REG_S(VIPPAD_EN, VIPPAD_EN_VHAD, line | 2);
+ } else {
+ v |= REG_S(VIPPAD_EN, VIPPAD_EN_VHAD, line);
+ }
+ break;
+ case VIPPAD1_EN:
+ line = REG_G(VIPPAD1_EN, VIPPAD_EN_DVODATA, v) & ~8;
+ v &= ~VIPPAD1_EN__VIPPAD_EN_DVODATA__MASK;
+ if (!clock) {
+ v |= REG_S(VIPPAD1_EN, VIPPAD_EN_DVODATA, line | 8);
+ } else {
+ v |= REG_S(VIPPAD1_EN, VIPPAD_EN_DVODATA, line);
+ }
+ break;
+ case GPIO_DDC1:
+ v &= ~GPIO_DDC1__DDC1_CLK_OUT_EN;
+ if (!clock) {
+ v |= GPIO_DDC1__DDC1_CLK_OUT_EN;
+ }
+ break;
+ case GPIO_DDC2:
+ v &= ~GPIO_DDC2__DDC2_CLK_OUT_EN;
+ if (!clock) {
+ v |= GPIO_DDC2__DDC2_CLK_OUT_EN;
+ }
+ break;
+ case GPIO_MONID:
+ v &= ~GPIO_MONID__GPIO_MONID_1_OUT_EN;
+ if (!clock) {
+ v |= GPIO_MONID__GPIO_MONID_1_OUT_EN;
+ }
+ break;
+ case GPIO_CRT2_DDC:
+ v &= ~GPIO_CRT2_DDC__CRT2_DDC_CLK_OUT_EN;
+ if (!clock) {
+ v |= GPIO_CRT2_DDC__CRT2_DDC_CLK_OUT_EN;
+ }
+ break;
+ default:
+ return;
+ }
+ MMIO_W(i2c->reg, v);
+}
+
+static void set_data(void *i2c_priv, int data)
+{
+ struct radeon_ms_i2c *i2c = i2c_priv;
+ struct drm_radeon_private *dev_priv = i2c->drm_dev->dev_private;
+ int v, line;
+
+ v = MMIO_R(i2c->reg);
+ switch (i2c->reg) {
+ case VIPPAD_EN:
+ line = REG_G(VIPPAD_EN, VIPPAD_EN_VHAD, v) & ~1;
+ v &= ~VIPPAD_EN__VIPPAD_EN_VHAD__MASK;
+ if (!data) {
+ v |= REG_S(VIPPAD_EN, VIPPAD_EN_VHAD, line | 1);
+ } else {
+ v |= REG_S(VIPPAD_EN, VIPPAD_EN_VHAD, line);
+ }
+ break;
+ case VIPPAD1_EN:
+ line = REG_G(VIPPAD1_EN, VIPPAD_EN_DVODATA, v) & ~4;
+ v &= ~VIPPAD1_EN__VIPPAD_EN_DVODATA__MASK;
+ if (!data) {
+ v |= REG_S(VIPPAD1_EN, VIPPAD_EN_DVODATA, line | 4);
+ } else {
+ v |= REG_S(VIPPAD1_EN, VIPPAD_EN_DVODATA, line);
+ }
+ break;
+ case GPIO_DDC1:
+ v &= ~GPIO_DDC1__DDC1_DATA_OUT_EN;
+ if (!data) {
+ v |= GPIO_DDC1__DDC1_DATA_OUT_EN;
+ }
+ break;
+ case GPIO_DDC2:
+ v &= ~GPIO_DDC2__DDC2_DATA_OUT_EN;
+ if (!data) {
+ v |= GPIO_DDC2__DDC2_DATA_OUT_EN;
+ }
+ break;
+ case GPIO_MONID:
+ v &= ~GPIO_MONID__GPIO_MONID_0_OUT_EN;
+ if (!data) {
+ v |= GPIO_MONID__GPIO_MONID_0_OUT_EN;
+ }
+ break;
+ case GPIO_CRT2_DDC:
+ v &= ~GPIO_CRT2_DDC__CRT2_DDC_DATA_OUT_EN;
+ if (!data) {
+ v |= GPIO_CRT2_DDC__CRT2_DDC_DATA_OUT_EN;
+ }
+ break;
+ default:
+ return;
+ }
+ MMIO_W(i2c->reg, v);
+}
+
+/**
+ * radeon_ms_i2c_create - instantiate an radeon i2c bus on specified GPIO reg
+ * @dev: DRM device
+ * @output: driver specific output device
+ * @reg: GPIO reg to use
+ * @name: name for this bus
+ *
+ * Creates and registers a new i2c bus with the Linux i2c layer, for use
+ * in output probing and control (e.g. DDC or SDVO control functions).
+ *
+ */
+struct radeon_ms_i2c *radeon_ms_i2c_create(struct drm_device *dev,
+ const uint32_t reg,
+ const char *name)
+{
+ struct radeon_ms_i2c *i2c;
+ int ret;
+
+ i2c = drm_alloc(sizeof(struct radeon_ms_i2c), DRM_MEM_DRIVER);
+ if (i2c == NULL) {
+ return NULL;
+ }
+ memset(i2c, 0, sizeof(struct radeon_ms_i2c));
+
+ i2c->drm_dev = dev;
+ i2c->reg = reg;
+ snprintf(i2c->adapter.name, I2C_NAME_SIZE, "radeon-%s", name);
+ i2c->adapter.owner = THIS_MODULE;
+ /* fixme need to take a look at what its needed for */
+ i2c->adapter.id = I2C_HW_B_RADEON;
+ i2c->adapter.algo_data = &i2c->algo;
+ i2c->adapter.dev.parent = &dev->pdev->dev;
+ i2c->algo.setsda = set_data;
+ i2c->algo.setscl = set_clock;
+ i2c->algo.getsda = get_data;
+ i2c->algo.getscl = get_clock;
+ i2c->algo.udelay = 20;
+ i2c->algo.timeout = usecs_to_jiffies(2200);
+ i2c->algo.data = i2c;
+
+ i2c_set_adapdata(&i2c->adapter, i2c);
+
+ ret = i2c_bit_add_bus(&i2c->adapter);
+ if(ret) {
+ DRM_INFO("[radeon_ms] failed to register I2C '%s' bus (0x%X)\n",
+ i2c->adapter.name, reg);
+ goto out_free;
+ }
+ DRM_INFO("[radeon_ms] registered I2C '%s' bus (0x%X)\n",
+ i2c->adapter.name, reg);
+ return i2c;
+
+out_free:
+ drm_free(i2c, sizeof(struct radeon_ms_i2c), DRM_MEM_DRIVER);
+ return NULL;
+}
+
+/**
+ * radeon_ms_i2c_destroy - unregister and free i2c bus resources
+ * @output: channel to free
+ *
+ * Unregister the adapter from the i2c layer, then free the structure.
+ */
+void radeon_ms_i2c_destroy(struct radeon_ms_i2c *i2c)
+{
+ if (i2c == NULL) {
+ return;
+ }
+ i2c_del_adapter(&i2c->adapter);
+ drm_free(i2c, sizeof(struct radeon_ms_i2c), DRM_MEM_DRIVER);
+}
diff --git a/shared-core/radeon_ms_irq.c b/shared-core/radeon_ms_irq.c
new file mode 100644
index 00000000..2f94118f
--- /dev/null
+++ b/shared-core/radeon_ms_irq.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Alex Deucher
+ * Copyright 2007 Dave Airlie
+ * All Rights Reserved.
+ *
+ * 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * Authors:
+ * Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_ms.h"
+
+static uint32_t radeon_ack_irqs(struct drm_radeon_private *dev_priv,
+ uint32_t mask)
+{
+ uint32_t irqs;
+
+ irqs = MMIO_R(GEN_INT_STATUS);
+ if (irqs) {
+ MMIO_W(GEN_INT_STATUS, irqs);
+ }
+ if (irqs & (~mask)) {
+ /* reprogram irq */
+ MMIO_W(GEN_INT_CNTL, dev_priv->driver_state.gen_int_cntl);
+ }
+ return irqs;
+}
+
+void radeon_ms_irq_emit(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t cmd[4];
+ int i, ret;
+
+ cmd[0] = CP_PACKET0(GEN_INT_CNTL, 1);
+ cmd[1] = dev_priv->driver_state.gen_int_cntl | GEN_INT_CNTL__SW_INT_EN;
+ cmd[2] = GEN_INT_STATUS__SW_INT_SET;
+ /* try to wait but if we timeout we likely are in bad situation */
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ ret = radeon_ms_ring_emit(dev, cmd, 3);
+ if (!ret) {
+ break;
+ }
+ }
+}
+
+static void radeon_ms_irq_enable(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_state *state = &dev_priv->driver_state;
+
+ state->gen_int_cntl = GEN_INT_CNTL__SW_INT_EN;
+ radeon_ms_irq_restore(dev, state);
+}
+
+irqreturn_t radeon_ms_irq_handler(DRM_IRQ_ARGS)
+{
+ struct drm_device *dev = (struct drm_device *)arg;
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t status, mask;
+
+ /* Only consider the bits we're interested in - others could be used
+ * outside the DRM
+ */
+ mask = GEN_INT_STATUS__SW_INT |
+ GEN_INT_STATUS__CRTC_VBLANK_STAT |
+ GEN_INT_STATUS__CRTC2_VBLANK_STAT;
+ status = radeon_ack_irqs(dev_priv, mask);
+ if (!status) {
+ return IRQ_NONE;
+ }
+
+ /* SW interrupt */
+ if (GEN_INT_STATUS__SW_INT & status) {
+ radeon_ms_fence_handler(dev);
+ }
+ radeon_ms_fence_handler(dev);
+ return IRQ_HANDLED;
+}
+
+void radeon_ms_irq_preinstall(struct drm_device * dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_state *state = &dev_priv->driver_state;
+ uint32_t mask;
+
+ /* Disable *all* interrupts */
+ state->gen_int_cntl = 0;
+ radeon_ms_irq_restore(dev, state);
+
+ /* Clear bits if they're already high */
+ mask = GEN_INT_STATUS__SW_INT |
+ GEN_INT_STATUS__CRTC_VBLANK_STAT |
+ GEN_INT_STATUS__CRTC2_VBLANK_STAT;
+ radeon_ack_irqs(dev_priv, mask);
+}
+
+int radeon_ms_irq_postinstall(struct drm_device * dev)
+{
+ radeon_ms_irq_enable(dev);
+ return 0;
+}
+
+int radeon_ms_irq_init(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_state *state = &dev_priv->driver_state;
+
+ /* Disable *all* interrupts */
+ state->gen_int_cntl = 0;
+ radeon_ms_irq_restore(dev, state);
+ return 0;
+}
+
+void radeon_ms_irq_restore(struct drm_device *dev, struct radeon_state *state)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ MMIO_W(GEN_INT_CNTL, state->gen_int_cntl);
+}
+
+void radeon_ms_irq_save(struct drm_device *dev, struct radeon_state *state)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ state->gen_int_cntl = MMIO_R(GEN_INT_CNTL);
+}
+
+void radeon_ms_irq_uninstall(struct drm_device * dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_state *state = &dev_priv->driver_state;
+
+ if (dev_priv == NULL) {
+ return;
+ }
+
+ /* Disable *all* interrupts */
+ state->gen_int_cntl = 0;
+ radeon_ms_irq_restore(dev, state);
+}
diff --git a/shared-core/radeon_ms_output.c b/shared-core/radeon_ms_output.c
new file mode 100644
index 00000000..bc174371
--- /dev/null
+++ b/shared-core/radeon_ms_output.c
@@ -0,0 +1,361 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Alex Deucher
+ * Copyright 2007 Dave Airlie
+ * All Rights Reserved.
+ *
+ * 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 on 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
+ * THEIR SUPPLIERS 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 "radeon_ms.h"
+
+static struct radeon_ms_output *radeon_ms_connector_get_output(
+ struct drm_radeon_private *dev_priv,
+ struct radeon_ms_connector *connector, int i)
+{
+ if (connector->outputs[i] < 0) {
+ return NULL;
+ }
+ if (connector->outputs[i] >= RADEON_MAX_OUTPUTS) {
+ return NULL;
+ }
+ i = connector->outputs[i];
+ if (dev_priv->outputs[i] == NULL) {
+ return NULL;
+ }
+ if (dev_priv->outputs[i]->connector == NULL) {
+ return dev_priv->outputs[i];
+ }
+ if (dev_priv->outputs[i]->connector == connector) {
+ return dev_priv->outputs[i];
+ }
+ return NULL;
+}
+
+static void radeon_ms_output_dpms(struct drm_output *output, int mode)
+{
+ struct drm_radeon_private *dev_priv = output->dev->dev_private;
+ struct radeon_ms_connector *connector = output->driver_private;
+ struct radeon_ms_output *routput = NULL;
+ int i;
+
+ if (connector == NULL) {
+ return;
+ }
+ for (i = 0; i < RADEON_MAX_OUTPUTS; i++) {
+ routput = radeon_ms_connector_get_output(dev_priv,
+ connector, i);
+
+ if (routput) {
+ routput->connector = connector;
+ routput->dpms(routput, mode);
+ }
+ }
+ radeon_ms_gpu_dpms(output->dev);
+}
+
+static int radeon_ms_output_mode_valid(struct drm_output *output,
+ struct drm_display_mode *mode)
+{
+ struct radeon_ms_connector *connector = output->driver_private;
+
+ if (connector == NULL) {
+ return MODE_ERROR;
+ }
+ return MODE_OK;
+}
+
+static bool radeon_ms_output_mode_fixup(struct drm_output *output,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ return true;
+}
+
+static void radeon_ms_output_prepare(struct drm_output *output)
+{
+ if (output->funcs->dpms) {
+ output->funcs->dpms(output, DPMSModeOff);
+ }
+}
+
+static void radeon_ms_output_commit(struct drm_output *output)
+{
+ if (output->funcs->dpms) {
+ output->funcs->dpms(output, DPMSModeOn);
+ }
+}
+
+static void radeon_ms_output_mode_set(struct drm_output *output,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct drm_radeon_private *dev_priv = output->dev->dev_private;
+ struct radeon_ms_connector *connector = output->driver_private;
+ struct radeon_ms_crtc *crtc;
+ struct radeon_ms_output *routput = NULL;
+ int i;
+
+ if (connector == NULL) {
+ return;
+ }
+ if (output->crtc == NULL) {
+ return;
+ }
+ crtc = output->crtc->driver_private;
+ connector->crtc = crtc->crtc;
+ /* catch unknown crtc */
+ switch (connector->crtc) {
+ case 1:
+ case 2:
+ break;
+ default:
+ /* error */
+ return;
+ }
+ for (i = 0; i < RADEON_MAX_OUTPUTS; i++) {
+ routput = radeon_ms_connector_get_output(dev_priv,
+ connector, i);
+ if (routput) {
+ routput->connector = connector;
+ routput->mode_set(routput, mode, adjusted_mode);
+ }
+ }
+}
+
+static enum drm_output_status radeon_ms_output_detect(struct drm_output *output)
+{
+ struct radeon_ms_connector *connector = output->driver_private;
+
+ if (connector == NULL || connector->i2c == NULL) {
+ return output_status_unknown;
+ }
+ kfree(connector->edid);
+ connector->edid = drm_get_edid(output, &connector->i2c->adapter);
+ if (connector->edid == NULL) {
+ return output_status_unknown;
+ }
+ return output_status_connected;
+}
+
+static int radeon_ms_output_get_modes(struct drm_output *output)
+{
+ struct radeon_ms_connector *connector = output->driver_private;
+ int ret = 0;
+
+ if (connector == NULL || connector->i2c == NULL) {
+ return 0;
+ }
+ if (connector->edid == NULL) {
+ return 0;
+ }
+ drm_mode_output_update_edid_property(output, connector->edid);
+ ret = drm_add_edid_modes(output, connector->edid);
+ kfree(connector->edid);
+ connector->edid = NULL;
+ return ret;
+}
+
+static void radeon_ms_output_cleanup(struct drm_output *output)
+{
+ struct radeon_ms_connector *connector = output->driver_private;
+
+ if (connector == NULL) {
+ return;
+ }
+ if (connector->edid) {
+ kfree(connector->edid);
+ }
+ connector->edid = NULL;
+ connector->output = NULL;
+ output->driver_private = NULL;
+}
+
+const struct drm_output_funcs radeon_ms_output_funcs = {
+ .dpms = radeon_ms_output_dpms,
+ .save = NULL,
+ .restore = NULL,
+ .mode_valid = radeon_ms_output_mode_valid,
+ .mode_fixup = radeon_ms_output_mode_fixup,
+ .prepare = radeon_ms_output_prepare,
+ .mode_set = radeon_ms_output_mode_set,
+ .commit = radeon_ms_output_commit,
+ .detect = radeon_ms_output_detect,
+ .get_modes = radeon_ms_output_get_modes,
+ .cleanup = radeon_ms_output_cleanup,
+};
+
+void radeon_ms_connectors_destroy(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_ms_connector *connector = NULL;
+ int i = 0;
+
+ for (i = 0; i < RADEON_MAX_CONNECTORS; i++) {
+ if (dev_priv->connectors[i]) {
+ connector = dev_priv->connectors[i];
+ dev_priv->connectors[i] = NULL;
+ if (connector->output) {
+ drm_output_destroy(connector->output);
+ connector->output = NULL;
+ }
+ if (connector->i2c) {
+ radeon_ms_i2c_destroy(connector->i2c);
+ connector->i2c = NULL;
+ }
+ drm_free(connector,
+ sizeof(struct radeon_ms_connector),
+ DRM_MEM_DRIVER);
+ }
+ }
+}
+
+int radeon_ms_connectors_from_properties(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_ms_connector *connector = NULL;
+ struct drm_output *output = NULL;
+ int i = 0, c = 0;
+
+ radeon_ms_connectors_destroy(dev);
+ for (i = 0; i < RADEON_MAX_CONNECTORS; i++) {
+ if (dev_priv->properties.connectors[i]) {
+ connector =
+ drm_alloc(sizeof(struct radeon_ms_connector),
+ DRM_MEM_DRIVER);
+ if (connector == NULL) {
+ radeon_ms_connectors_destroy(dev);
+ return -ENOMEM;
+ }
+ memcpy(connector, dev_priv->properties.connectors[i],
+ sizeof(struct radeon_ms_connector));
+ connector->i2c =
+ radeon_ms_i2c_create(dev, connector->i2c_reg,
+ connector->name);
+ if (connector->i2c == NULL) {
+ radeon_ms_connectors_destroy(dev);
+ return -ENOMEM;
+ }
+ output = drm_output_create(dev,
+ &radeon_ms_output_funcs,
+ connector->type);
+ if (output == NULL) {
+ radeon_ms_connectors_destroy(dev);
+ return -EINVAL;
+ }
+ connector->output = output;
+ output->driver_private = connector;
+ output->possible_crtcs = 0x3;
+ dev_priv->connectors[c++] = connector;
+ }
+ }
+ return c;
+}
+
+int radeon_ms_connectors_from_rom(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ switch (dev_priv->rom.type) {
+ case ROM_COMBIOS:
+ return radeon_ms_connectors_from_combios(dev);
+ }
+ return 0;
+}
+
+void radeon_ms_outputs_destroy(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ int i = 0;
+
+ for (i = 0; i < RADEON_MAX_OUTPUTS; i++) {
+ if (dev_priv->outputs[i]) {
+ drm_free(dev_priv->outputs[i],
+ sizeof(struct radeon_ms_output),
+ DRM_MEM_DRIVER);
+ dev_priv->outputs[i] = NULL;
+ }
+ }
+}
+
+int radeon_ms_outputs_from_properties(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ int i = 0;
+ int c = 0;
+
+ radeon_ms_outputs_destroy(dev);
+ for (i = 0; i < RADEON_MAX_OUTPUTS; i++) {
+ if (dev_priv->properties.outputs[i]) {
+ dev_priv->outputs[i] =
+ drm_alloc(sizeof(struct radeon_ms_output),
+ DRM_MEM_DRIVER);
+ if (dev_priv->outputs[i] == NULL) {
+ radeon_ms_outputs_destroy(dev);
+ return -ENOMEM;
+ }
+ memcpy(dev_priv->outputs[i],
+ dev_priv->properties.outputs[i],
+ sizeof(struct radeon_ms_output));
+ dev_priv->outputs[i]->dev = dev;
+ dev_priv->outputs[i]->initialize(dev_priv->outputs[i]);
+ c++;
+ }
+ }
+ return c;
+}
+
+int radeon_ms_outputs_from_rom(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ switch (dev_priv->rom.type) {
+ case ROM_COMBIOS:
+ return radeon_ms_outputs_from_combios(dev);
+ }
+ return 0;
+}
+
+void radeon_ms_outputs_restore(struct drm_device *dev,
+ struct radeon_state *state)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ int i;
+
+ for (i = 0; i < RADEON_MAX_OUTPUTS; i++) {
+ if (dev_priv->outputs[i]) {
+ dev_priv->outputs[i]->restore(dev_priv->outputs[i],
+ state);
+ }
+ }
+}
+
+void radeon_ms_outputs_save(struct drm_device *dev, struct radeon_state *state)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ int i;
+
+ for (i = 0; i < RADEON_MAX_OUTPUTS; i++) {
+ if (dev_priv->outputs[i]) {
+ dev_priv->outputs[i]->save(dev_priv->outputs[i], state);
+ }
+ }
+}
diff --git a/shared-core/radeon_ms_properties.c b/shared-core/radeon_ms_properties.c
new file mode 100644
index 00000000..baf2a7f2
--- /dev/null
+++ b/shared-core/radeon_ms_properties.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ */
+/*
+ * Authors:
+ * Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_ms.h"
+
+struct radeon_ms_output radeon_ms_dac1 = {
+ OUTPUT_DAC1,
+ NULL,
+ NULL,
+ radeon_ms_dac1_initialize,
+ radeon_ms_dac1_detect,
+ radeon_ms_dac1_dpms,
+ radeon_ms_dac1_get_modes,
+ radeon_ms_dac1_mode_fixup,
+ radeon_ms_dac1_mode_set,
+ radeon_ms_dac1_restore,
+ radeon_ms_dac1_save
+};
+
+struct radeon_ms_output radeon_ms_dac2 = {
+ OUTPUT_DAC2,
+ NULL,
+ NULL,
+ radeon_ms_dac2_initialize,
+ radeon_ms_dac2_detect,
+ radeon_ms_dac2_dpms,
+ radeon_ms_dac2_get_modes,
+ radeon_ms_dac2_mode_fixup,
+ radeon_ms_dac2_mode_set,
+ radeon_ms_dac2_restore,
+ radeon_ms_dac2_save
+};
+
+struct radeon_ms_connector radeon_ms_vga = {
+ NULL, NULL, NULL, CONNECTOR_VGA, MT_NONE, 0, GPIO_DDC1,
+ {
+ 0, -1, -1, -1, -1, -1, -1, -1
+ },
+ "VGA"
+};
+
+struct radeon_ms_connector radeon_ms_dvi_i_2 = {
+ NULL, NULL, NULL, CONNECTOR_DVI_I, MT_NONE, 0, GPIO_DDC2,
+ {
+ 1, -1, -1, -1, -1, -1, -1, -1
+ },
+ "DVI-I"
+};
+
+struct radeon_ms_properties properties[] = {
+ /* default only one VGA connector */
+ {
+ 0, 0, 27000, 12, 25000, 200000, 1, 1, 1, 1,
+ {
+ &radeon_ms_dac1, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL
+ },
+ {
+ &radeon_ms_vga, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL
+ }
+ }
+};
+
+int radeon_ms_properties_init(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ int i, ret;
+
+ for (i = 1; i < sizeof(properties)/sizeof(properties[0]); i++) {
+ if (dev->pdev->subsystem_vendor == properties[i].subvendor &&
+ dev->pdev->subsystem_device == properties[i].subdevice) {
+ DRM_INFO("[radeon_ms] found properties for "
+ "0x%04X:0x%04X\n", properties[i].subvendor,
+ properties[i].subdevice);
+ memcpy(&dev_priv->properties, &properties[i],
+ sizeof(struct radeon_ms_properties));
+ }
+ }
+ if (dev_priv->properties.subvendor == 0) {
+ ret = radeon_ms_rom_get_properties(dev);
+ if (ret < 0) {
+ return ret;
+ }
+ if (!ret) {
+ memcpy(&dev_priv->properties, &properties[0],
+ sizeof(struct radeon_ms_properties));
+ } else {
+ dev_priv->properties.pll_dummy_reads = 1;
+ dev_priv->properties.pll_delay = 1;
+ dev_priv->properties.pll_r300_errata = 1;
+ }
+ dev_priv->properties.subvendor = dev->pdev->subsystem_vendor;
+ dev_priv->properties.subdevice = dev->pdev->subsystem_device;
+ }
+ return 0;
+}
diff --git a/shared-core/radeon_ms_properties.h b/shared-core/radeon_ms_properties.h
new file mode 100644
index 00000000..a02a84d5
--- /dev/null
+++ b/shared-core/radeon_ms_properties.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ */
+/*
+ * Authors:
+ * Jerome Glisse <glisse@freedesktop.org>
+ */
+#ifndef __RADEON_MS_PROPERTIES_H__
+#define __RADEON_MS_PROPERTIES_H__
+
+#define RADEON_PAGE_SIZE 4096
+#define RADEON_MAX_CONNECTORS 8
+#define RADEON_MAX_OUTPUTS 8
+
+struct radeon_ms_properties {
+ uint16_t subvendor;
+ uint16_t subdevice;
+ int16_t pll_reference_freq;
+ int16_t pll_reference_div;
+ int32_t pll_min_pll_freq;
+ int32_t pll_max_pll_freq;
+ char pll_use_bios;
+ char pll_dummy_reads;
+ char pll_delay;
+ char pll_r300_errata;
+ struct radeon_ms_output *outputs[RADEON_MAX_OUTPUTS];
+ struct radeon_ms_connector *connectors[RADEON_MAX_CONNECTORS];
+};
+
+#endif
diff --git a/shared-core/radeon_ms_reg.h b/shared-core/radeon_ms_reg.h
new file mode 100644
index 00000000..56963c63
--- /dev/null
+++ b/shared-core/radeon_ms_reg.h
@@ -0,0 +1,1681 @@
+/*
+ * Copyright 2007 Advanced Micro Devices, Inc.
+ *
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ */
+#ifndef __RADEON_REG_H__
+#define __RADEON_REG_H__
+
+#define MC_FB_LOCATION 0x00000148
+#define MC_FB_LOCATION__MC_FB_START__MASK 0x0000FFFF
+#define MC_FB_LOCATION__MC_FB_START__SHIFT 0
+#define MC_FB_LOCATION__MC_FB_TOP__MASK 0xFFFF0000
+#define MC_FB_LOCATION__MC_FB_TOP__SHIFT 16
+#define MC_AGP_LOCATION 0x0000014C
+#define MC_AGP_LOCATION__MC_AGP_START__MASK 0x0000FFFF
+#define MC_AGP_LOCATION__MC_AGP_START__SHIFT 0
+#define MC_AGP_LOCATION__MC_AGP_TOP__MASK 0xFFFF0000
+#define MC_AGP_LOCATION__MC_AGP_TOP__SHIFT 16
+#define AGP_COMMAND 0x00000F60
+#define AGP_COMMAND__DATA_RATE__MASK 0x00000007
+#define AGP_COMMAND__DATA_RATE__SHIFT 0
+#define DATA_RATE__v2_1X 0x1
+#define DATA_RATE__v2_2X 0x2
+#define DATA_RATE__v2_4X 0x4
+#define DATA_RATE__v3_4X 0x1
+#define DATA_RATE__v3_8X 0x2
+#define AGP_COMMAND__AGP_EN 0x00000100
+#define AGP_COMMAND__SBA_EN 0x00000200
+#define AGP_COMMAND__RQ_DEPTH__MASK 0xFF000000
+#define AGP_COMMAND__RQ_DEPTH__SHIFT 24
+#define AGP_COMMAND__FW_EN 0x00000010
+#define AGP_COMMAND__MODE_4G_EN 0x00000020
+#define AGP_COMMAND__PARQSZ__MASK 0x0000E000
+#define AGP_COMMAND__PARQSZ__SHIFT 13
+#define AGP_STATUS 0x00000F5C
+#define AGP_STATUS__RATE1X 0x00000001
+#define AGP_STATUS__RATE2X 0x00000002
+#define AGP_STATUS__RATE4X 0x00000004
+#define AGP_STATUS__SBA 0x00000200
+#define AGP_STATUS__RQ__MASK 0xFF000000
+#define AGP_STATUS__RQ__SHIFT 24
+#define AGP_STATUS__FW 0x00000010
+#define AGP_STATUS__MODE_4G 0x00000020
+#define AGP_STATUS__RATE1X_4X 0x00000001
+#define AGP_STATUS__RATE2X_8X 0x00000002
+#define AGP_STATUS__MODE_AGP30 0x00000008
+#define AGP_STATUS__CAL_CYCLE__MASK 0x00001C00
+#define AGP_STATUS__CAL_CYCLE__SHIFT 10
+#define AGP_STATUS__ISOCH_SUPPORT 0x00020000
+#define AGP_BASE 0x00000170
+#define AGP_BASE__AGP_BASE_ADDR__MASK 0xFFFFFFFF
+#define AGP_BASE__AGP_BASE_ADDR__SHIFT 0
+#define AGP_BASE_2 0x0000015C
+#define AGP_BASE_2__AGP_BASE_ADDR_2__MASK 0x0000000F
+#define AGP_BASE_2__AGP_BASE_ADDR_2__SHIFT 0
+#define CONFIG_MEMSIZE 0x000000F8
+#define CONFIG_MEMSIZE__CONFIG_MEMSIZE__MASK 0x1F000000
+#define CONFIG_MEMSIZE__CONFIG_MEMSIZE__SHIFT 24
+#define CONFIG_MEMSIZE__CONFIG_MEMSIZE_R2__MASK 0x1FF00000
+#define CONFIG_MEMSIZE__CONFIG_MEMSIZE_R2__SHIFT 20
+#define CONFIG_APER_0_BASE 0x00000100
+#define CONFIG_APER_0_BASE__APER_0_BASE__MASK 0xFE000000
+#define CONFIG_APER_0_BASE__APER_0_BASE__SHIFT 25
+#define CONFIG_APER_1_BASE 0x00000104
+#define CONFIG_APER_1_BASE__APER_1_BASE__MASK 0xFF000000
+#define CONFIG_APER_1_BASE__APER_1_BASE__SHIFT 24
+#define CONFIG_APER_SIZE 0x00000108
+#define CONFIG_APER_SIZE__APER_SIZE__MASK 0x0F000000
+#define CONFIG_APER_SIZE__APER_SIZE__SHIFT 24
+#define GEN_INT_CNTL 0x00000040
+#define GEN_INT_CNTL__CRTC_VBLANK 0x00000001
+#define GEN_INT_CNTL__CRTC_VLINE 0x00000002
+#define GEN_INT_CNTL__CRTC_VSYNC 0x00000004
+#define GEN_INT_CNTL__SNAPSHOT 0x00000008
+#define GEN_INT_CNTL__FP_DETECT 0x00000010
+#define GEN_INT_CNTL__CRTC2_VLINE 0x00000020
+#define GEN_INT_CNTL__DMA_VIPH0_INT_EN 0x00001000
+#define GEN_INT_CNTL__CRTC2_VSYNC 0x00000040
+#define GEN_INT_CNTL__SNAPSHOT2 0x00000080
+#define GEN_INT_CNTL__CRTC2_VBLANK 0x00000200
+#define GEN_INT_CNTL__FP2_DETECT 0x00000400
+#define GEN_INT_CNTL__VSYNC_DIFF_OVER_LIMIT 0x00000800
+#define GEN_INT_CNTL__DMA_VIPH1_INT_EN 0x00002000
+#define GEN_INT_CNTL__DMA_VIPH2_INT_EN 0x00004000
+#define GEN_INT_CNTL__DMA_VIPH3_INT_EN 0x00008000
+#define GEN_INT_CNTL__I2C_INT_EN 0x00020000
+#define GEN_INT_CNTL__GUI_IDLE 0x00080000
+#define GEN_INT_CNTL__VIPH_INT_EN 0x01000000
+#define GEN_INT_CNTL__SW_INT_EN 0x02000000
+#define GEN_INT_CNTL__GEYSERVILLE 0x08000000
+#define GEN_INT_CNTL__DVI_I2C_INT 0x20000000
+#define GEN_INT_CNTL__GUIDMA 0x40000000
+#define GEN_INT_CNTL__VIDDMA 0x80000000
+#define GEN_INT_CNTL__TIMER_INT 0x00010000
+#define GEN_INT_CNTL__IDCT_INT_EN 0x08000000
+#define GEN_INT_STATUS 0x00000044
+#define GEN_INT_STATUS__CRTC_VBLANK_STAT 0x00000001
+#define GEN_INT_STATUS__CRTC_VBLANK_STAT_AK 0x00000001
+#define GEN_INT_STATUS__CRTC_VLINE_STAT 0x00000002
+#define GEN_INT_STATUS__CRTC_VLINE_STAT_AK 0x00000002
+#define GEN_INT_STATUS__CRTC_VSYNC_STAT 0x00000004
+#define GEN_INT_STATUS__CRTC_VSYNC_STAT_AK 0x00000004
+#define GEN_INT_STATUS__SNAPSHOT_STAT 0x00000008
+#define GEN_INT_STATUS__SNAPSHOT_STAT_AK 0x00000008
+#define GEN_INT_STATUS__FP_DETECT_STAT 0x00000010
+#define GEN_INT_STATUS__FP_DETECT_STAT_AK 0x00000010
+#define GEN_INT_STATUS__CRTC2_VLINE_STAT 0x00000020
+#define GEN_INT_STATUS__CRTC2_VLINE_STAT_AK 0x00000020
+#define GEN_INT_STATUS__CRTC2_VSYNC_STAT 0x00000040
+#define GEN_INT_STATUS__CRTC2_VSYNC_STAT_AK 0x00000040
+#define GEN_INT_STATUS__SNAPSHOT2_STAT 0x00000080
+#define GEN_INT_STATUS__SNAPSHOT2_STAT_AK 0x00000080
+#define GEN_INT_STATUS__CAP0_INT_ACTIVE 0x00000100
+#define GEN_INT_STATUS__CRTC2_VBLANK_STAT 0x00000200
+#define GEN_INT_STATUS__CRTC2_VBLANK_STAT_AK 0x00000200
+#define GEN_INT_STATUS__FP2_DETECT_STAT 0x00000400
+#define GEN_INT_STATUS__FP2_DETECT_STAT_AK 0x00000400
+#define GEN_INT_STATUS__VSYNC_DIFF_OVER_LIMIT_STAT 0x00000800
+#define GEN_INT_STATUS__VSYNC_DIFF_OVER_LIMIT_STAT_AK 0x00000800
+#define GEN_INT_STATUS__DMA_VIPH0_INT 0x00001000
+#define GEN_INT_STATUS__DMA_VIPH0_INT_AK 0x00001000
+#define GEN_INT_STATUS__DMA_VIPH1_INT 0x00002000
+#define GEN_INT_STATUS__DMA_VIPH1_INT_AK 0x00002000
+#define GEN_INT_STATUS__DMA_VIPH2_INT 0x00004000
+#define GEN_INT_STATUS__DMA_VIPH2_INT_AK 0x00004000
+#define GEN_INT_STATUS__DMA_VIPH3_INT 0x00008000
+#define GEN_INT_STATUS__DMA_VIPH3_INT_AK 0x00008000
+#define GEN_INT_STATUS__I2C_INT 0x00020000
+#define GEN_INT_STATUS__I2C_INT_AK 0x00020000
+#define GEN_INT_STATUS__GUI_IDLE_STAT 0x00080000
+#define GEN_INT_STATUS__GUI_IDLE_STAT_AK 0x00080000
+#define GEN_INT_STATUS__VIPH_INT 0x01000000
+#define GEN_INT_STATUS__SW_INT 0x02000000
+#define GEN_INT_STATUS__SW_INT_AK 0x02000000
+#define GEN_INT_STATUS__SW_INT_SET 0x04000000
+#define GEN_INT_STATUS__GEYSERVILLE_STAT 0x08000000
+#define GEN_INT_STATUS__GEYSERVILLE_STAT_AK 0x08000000
+#define GEN_INT_STATUS__DVI_I2C_INT_STAT 0x20000000
+#define GEN_INT_STATUS__DVI_I2C_INT_AK 0x20000000
+#define GEN_INT_STATUS__GUIDMA_STAT 0x40000000
+#define GEN_INT_STATUS__GUIDMA_AK 0x40000000
+#define GEN_INT_STATUS__VIDDMA_STAT 0x80000000
+#define GEN_INT_STATUS__VIDDMA_AK 0x80000000
+#define GEN_INT_STATUS__TIMER_INT_STAT 0x00010000
+#define GEN_INT_STATUS__TIMER_INT_STAT_AK 0x00010000
+#define GEN_INT_STATUS__IDCT_INT_STAT 0x08000000
+#define GEN_INT_STATUS__IDCT_INT_STAT_AK 0x08000000
+#define RB2D_DSTCACHE_MODE 0x00003428
+#define RB2D_DSTCACHE_MODE__DC_BYPASS__MASK 0x00000003
+#define RB2D_DSTCACHE_MODE__DC_BYPASS__SHIFT 0
+#define RB2D_DSTCACHE_MODE__DC_LINE_SIZE__MASK 0x0000000C
+#define RB2D_DSTCACHE_MODE__DC_LINE_SIZE__SHIFT 2
+#define RB2D_DSTCACHE_MODE__DC_AUTOFLUSH_ENABLE__MASK 0x00000300
+#define RB2D_DSTCACHE_MODE__DC_AUTOFLUSH_ENABLE__SHIFT 8
+#define RB2D_DSTCACHE_MODE__DC_FORCE_RMW 0x00010000
+#define RB2D_DSTCACHE_MODE__DC_DISABLE_RI_FILL 0x01000000
+#define RB2D_DSTCACHE_MODE__DC_DISABLE_RI_READ 0x02000000
+#define RB2D_DSTCACHE_MODE__DC_AUTOFREE_ENABLE__MASK 0x00000C00
+#define RB2D_DSTCACHE_MODE__DC_AUTOFREE_ENABLE__SHIFT 10
+#define RB2D_DSTCACHE_MODE__DC_DISABLE 0x04000000
+#define RB2D_DSTCACHE_MODE__DC_DISABLE_IGNORE_PE 0x00020000
+#define RB2D_DSTCACHE_CTLSTAT 0x0000342C
+#define RB2D_DSTCACHE_CTLSTAT__DC_FLUSH__MASK 0x00000003
+#define RB2D_DSTCACHE_CTLSTAT__DC_FLUSH__SHIFT 0
+#define RB2D_DSTCACHE_CTLSTAT__DC_FREE__MASK 0x0000000C
+#define RB2D_DSTCACHE_CTLSTAT__DC_FREE__SHIFT 2
+#define RB2D_DSTCACHE_CTLSTAT__DC_BUSY 0x80000000
+#define RB3D_DSTCACHE_CTLSTAT 0x0000325C
+#define RB3D_DSTCACHE_CTLSTAT__DC_FLUSH__MASK 0x00000003
+#define RB3D_DSTCACHE_CTLSTAT__DC_FLUSH__SHIFT 0
+#define RB3D_DSTCACHE_CTLSTAT__DC_FREE__MASK 0x0000000C
+#define RB3D_DSTCACHE_CTLSTAT__DC_FREE__SHIFT 2
+#define RB3D_DSTCACHE_CTLSTAT__DC_BUSY 0x80000000
+#define RB3D_DSTCACHE_CTLSTAT_R3 0x00004E4C
+#define RB3D_DSTCACHE_CTLSTAT_R3__DC_FLUSH__MASK 0x00000003
+#define RB3D_DSTCACHE_CTLSTAT_R3__DC_FLUSH__SHIFT 0
+#define RB3D_DSTCACHE_CTLSTAT_R3__DC_FREE__MASK 0x0000000C
+#define RB3D_DSTCACHE_CTLSTAT_R3__DC_FREE__SHIFT 2
+#define RB3D_DSTCACHE_CTLSTAT_R3__DC_FINISH 0x00000010
+#define RB3D_ZCACHE_CTLSTAT 0x00003254
+#define RB3D_ZCACHE_CTLSTAT__ZC_FLUSH 0x00000001
+#define RB3D_ZCACHE_CTLSTAT__ZC_FREE 0x00000004
+#define RB3D_ZCACHE_CTLSTAT__ZC_DIRTY 0x40000000
+#define RB3D_ZCACHE_CTLSTAT__ZC_BUSY 0x80000000
+#define RB3D_ZCACHE_CTLSTAT_R3 0x00004F18
+#define RB3D_ZCACHE_CTLSTAT_R3__ZC_FLUSH 0x00000001
+#define RB3D_ZCACHE_CTLSTAT_R3__ZC_FREE 0x00000002
+#define RB3D_ZCACHE_CTLSTAT_R3__ZC_BUSY 0x80000000
+#define SCRATCH_REG0 0x000015E0
+#define SCRATCH_REG0__SCRATCH_REG0__MASK 0xFFFFFFFF
+#define SCRATCH_REG0__SCRATCH_REG0__SHIFT 0
+#define SCRATCH_REG1 0x000015E4
+#define SCRATCH_REG1__SCRATCH_REG1__MASK 0xFFFFFFFF
+#define SCRATCH_REG1__SCRATCH_REG1__SHIFT 0
+#define SCRATCH_REG2 0x000015E8
+#define SCRATCH_REG2__SCRATCH_REG2__MASK 0xFFFFFFFF
+#define SCRATCH_REG2__SCRATCH_REG2__SHIFT 0
+#define SCRATCH_REG3 0x000015EC
+#define SCRATCH_REG3__SCRATCH_REG3__MASK 0xFFFFFFFF
+#define SCRATCH_REG3__SCRATCH_REG3__SHIFT 0
+#define SCRATCH_REG4 0x000015F0
+#define SCRATCH_REG4__SCRATCH_REG4__MASK 0xFFFFFFFF
+#define SCRATCH_REG4__SCRATCH_REG4__SHIFT 0
+#define SCRATCH_REG5 0x000015F4
+#define SCRATCH_REG5__SCRATCH_REG5__MASK 0xFFFFFFFF
+#define SCRATCH_REG5__SCRATCH_REG5__SHIFT 0
+#define SCRATCH_REG6 0x000015F8
+#define SCRATCH_REG6__SCRATCH_REG6__MASK 0xFFFFFFFF
+#define SCRATCH_REG6__SCRATCH_REG6__SHIFT 0
+#define SCRATCH_REG7 0x000015FC
+#define SCRATCH_REG7__SCRATCH_REG7__MASK 0xFFFFFFFF
+#define SCRATCH_REG7__SCRATCH_REG7__SHIFT 0
+#define PCIE_INDEX 0x00000030
+#define PCIE_INDEX__PCIE_INDEX__MASK 0x000007FF
+#define PCIE_INDEX__PCIE_INDEX__SHIFT 0
+#define PCIE_DATA 0x00000034
+#define PCIE_DATA__PCIE_DATA__MASK 0xFFFFFFFF
+#define PCIE_DATA__PCIE_DATA__SHIFT 0
+#define PCIE_TX_GART_CNTL 0x00000010
+#define PCIE_TX_GART_CNTL__GART_EN 0x00000001
+#define PCIE_TX_GART_CNTL__GART_UNMAPPED_ACCESS__MASK 0x00000006
+#define PCIE_TX_GART_CNTL__GART_UNMAPPED_ACCESS__SHIFT 1
+#define GART_UNMAPPED_ACCESS__PTHRU 0x0
+#define GART_UNMAPPED_ACCESS__CLAMP 0x1
+#define GART_UNMAPPED_ACCESS__DISCARD 0x3
+#define PCIE_TX_GART_CNTL__GART_MODE__MASK 0x00000018
+#define PCIE_TX_GART_CNTL__GART_MODE__SHIFT 3
+#define GART_MODE__CACHE_32x128 0x0
+#define GART_MODE__CACHE_8x4x128 0x1
+#define PCIE_TX_GART_CNTL__GART_CHK_RW_VALID_EN 0x00000020
+#define PCIE_TX_GART_CNTL__GART_RDREQPATH_SEL__MASK 0x00000040
+#define PCIE_TX_GART_CNTL__GART_RDREQPATH_SEL__SHIFT 6
+#define GART_RDREQPATH_SEL__HDP 0x0
+#define GART_RDREQPATH_SEL__DRQMC 0x1
+#define PCIE_TX_GART_CNTL__GART_INVALIDATE_TLB 0x00000100
+#define PCIE_TX_GART_DISCARD_RD_ADDR_LO 0x00000011
+#define PCIE_TX_GART_DISCARD_RD_ADDR_LO__GART_DISCARD_RD_ADDR_LO__MASK 0xFFFFFFFF
+#define PCIE_TX_GART_DISCARD_RD_ADDR_LO__GART_DISCARD_RD_ADDR_LO__SHIFT 0
+#define PCIE_TX_GART_DISCARD_RD_ADDR_HI 0x00000012
+#define PCIE_TX_GART_DISCARD_RD_ADDR_HI__GART_DISCARD_RD_ADDR_HI__MASK 0x000000FF
+#define PCIE_TX_GART_DISCARD_RD_ADDR_HI__GART_DISCARD_RD_ADDR_HI__SHIFT 0
+#define PCIE_TX_GART_BASE 0x00000013
+#define PCIE_TX_GART_BASE__GART_BASE__MASK 0xFFFFFFFF
+#define PCIE_TX_GART_BASE__GART_BASE__SHIFT 0
+#define PCIE_TX_GART_START_LO 0x00000014
+#define PCIE_TX_GART_START_LO__GART_START_LO__MASK 0xFFFFFFFF
+#define PCIE_TX_GART_START_LO__GART_START_LO__SHIFT 0
+#define PCIE_TX_GART_START_HI 0x00000015
+#define PCIE_TX_GART_START_HI__GART_START_HI__MASK 0x000000FF
+#define PCIE_TX_GART_START_HI__GART_START_HI__SHIFT 0
+#define PCIE_TX_GART_END_LO 0x00000016
+#define PCIE_TX_GART_END_LO__GART_END_LO__MASK 0xFFFFFFFF
+#define PCIE_TX_GART_END_LO__GART_END_LO__SHIFT 0
+#define PCIE_TX_GART_END_HI 0x00000017
+#define PCIE_TX_GART_END_HI__GART_END_HI__MASK 0x000000FF
+#define PCIE_TX_GART_END_HI__GART_END_HI__SHIFT 0
+#define PCIE_TX_GART_ERROR 0x00000018
+#define PCIE_TX_GART_ERROR__GART_UNMAPPED 0x00000002
+#define PCIE_TX_GART_ERROR__GART_INVALID_READ 0x00000004
+#define PCIE_TX_GART_ERROR__GART_INVALID_WRITE 0x00000008
+#define PCIE_TX_GART_ERROR__GART_INVALID_ADDR__MASK 0xFFFFFFF0
+#define PCIE_TX_GART_ERROR__GART_INVALID_ADDR__SHIFT 4
+#define CP_RB_CNTL 0x00000704
+#define CP_RB_CNTL__RB_BUFSZ__MASK 0x0000003F
+#define CP_RB_CNTL__RB_BUFSZ__SHIFT 0
+#define CP_RB_CNTL__RB_BLKSZ__MASK 0x00003F00
+#define CP_RB_CNTL__RB_BLKSZ__SHIFT 8
+#define CP_RB_CNTL__BUF_SWAP__MASK 0x00030000
+#define CP_RB_CNTL__BUF_SWAP__SHIFT 16
+#define CP_RB_CNTL__MAX_FETCH__MASK 0x000C0000
+#define CP_RB_CNTL__MAX_FETCH__SHIFT 18
+#define CP_RB_CNTL__RB_NO_UPDATE 0x08000000
+#define CP_RB_CNTL__RB_RPTR_WR_ENA 0x80000000
+#define CP_RB_BASE 0x00000700
+#define CP_RB_BASE__RB_BASE__MASK 0xFFFFFFFC
+#define CP_RB_BASE__RB_BASE__SHIFT 2
+#define CP_RB_RPTR_ADDR 0x0000070C
+#define CP_RB_RPTR_ADDR__RB_RPTR_SWAP__MASK 0x00000003
+#define CP_RB_RPTR_ADDR__RB_RPTR_SWAP__SHIFT 0
+#define CP_RB_RPTR_ADDR__RB_RPTR_ADDR__MASK 0xFFFFFFFC
+#define CP_RB_RPTR_ADDR__RB_RPTR_ADDR__SHIFT 2
+#define CP_RB_RPTR 0x00000710
+#define CP_RB_RPTR__RB_RPTR__MASK 0x007FFFFF
+#define CP_RB_RPTR__RB_RPTR__SHIFT 0
+#define CP_RB_RPTR_WR 0x0000071C
+#define CP_RB_RPTR_WR__RB_RPTR_WR__MASK 0x007FFFFF
+#define CP_RB_RPTR_WR__RB_RPTR_WR__SHIFT 0
+#define CP_RB_WPTR 0x00000714
+#define CP_RB_WPTR__RB_WPTR__MASK 0x007FFFFF
+#define CP_RB_WPTR__RB_WPTR__SHIFT 0
+#define CP_RB_WPTR_DELAY 0x00000718
+#define CP_RB_WPTR_DELAY__PRE_WRITE_TIMER__MASK 0x0FFFFFFF
+#define CP_RB_WPTR_DELAY__PRE_WRITE_TIMER__SHIFT 0
+#define CP_RB_WPTR_DELAY__PRE_WRITE_LIMIT__MASK 0xF0000000
+#define CP_RB_WPTR_DELAY__PRE_WRITE_LIMIT__SHIFT 28
+#define SCRATCH_UMSK 0x00000770
+#define SCRATCH_UMSK__SCRATCH_UMSK__MASK 0x0000003F
+#define SCRATCH_UMSK__SCRATCH_UMSK__SHIFT 0
+#define SCRATCH_UMSK__SCRATCH_SWAP__MASK 0x00030000
+#define SCRATCH_UMSK__SCRATCH_SWAP__SHIFT 16
+#define SCRATCH_UMSK__SCRATCH_UMSK_R2__MASK 0x000000FF
+#define SCRATCH_UMSK__SCRATCH_UMSK_R2__SHIFT 0
+#define SCRATCH_ADDR 0x00000774
+#define SCRATCH_ADDR__SCRATCH_ADDR__MASK 0xFFFFFFE0
+#define SCRATCH_ADDR__SCRATCH_ADDR__SHIFT 5
+#define CP_ME_RAM_ADDR 0x000007D4
+#define CP_ME_RAM_ADDR__ME_RAM_ADDR__MASK 0x000000FF
+#define CP_ME_RAM_ADDR__ME_RAM_ADDR__SHIFT 0
+#define CP_ME_RAM_DATAH 0x000007DC
+#define CP_ME_RAM_DATAH__ME_RAM_DATAH__MASK 0x0000003F
+#define CP_ME_RAM_DATAH__ME_RAM_DATAH__SHIFT 0
+#define CP_ME_RAM_DATAH__ME_RAM_DATAH_R3__MASK 0x000000FF
+#define CP_ME_RAM_DATAH__ME_RAM_DATAH_R3__SHIFT 0
+#define CP_ME_RAM_DATAL 0x000007E0
+#define CP_ME_RAM_DATAL__ME_RAM_DATAL__MASK 0xFFFFFFFF
+#define CP_ME_RAM_DATAL__ME_RAM_DATAL__SHIFT 0
+#define CP_CSQ_CNTL 0x00000740
+#define CP_CSQ_CNTL__CSQ_CNT_PRIMARY__MASK 0x000000FF
+#define CP_CSQ_CNTL__CSQ_CNT_PRIMARY__SHIFT 0
+#define CP_CSQ_CNTL__CSQ_CNT_INDIRECT__MASK 0x0000FF00
+#define CP_CSQ_CNTL__CSQ_CNT_INDIRECT__SHIFT 8
+#define CP_CSQ_CNTL__CSQ_MODE__MASK 0xF0000000
+#define CP_CSQ_CNTL__CSQ_MODE__SHIFT 28
+#define CSQ_MODE__CSQ_PRIDIS_INDDIS 0x0
+#define CSQ_MODE__CSQ_PRIPIO_INDDIS 0x1
+#define CSQ_MODE__CSQ_PRIBM_INDDIS 0x2
+#define CSQ_MODE__CSQ_PRIPIO_INDBM 0x3
+#define CSQ_MODE__CSQ_PRIBM_INDBM 0x4
+#define CSQ_MODE__CSQ_PRIPIO_INDPIO 0xF
+#define CP_CSQ_CNTL__CSQ_CNT_PRIMARY_R2__MASK 0x000001FF
+#define CP_CSQ_CNTL__CSQ_CNT_PRIMARY_R2__SHIFT 0
+#define CP_CSQ_CNTL__CSQ_CNT_INDIRECT_R2__MASK 0x0003FE00
+#define CP_CSQ_CNTL__CSQ_CNT_INDIRECT_R2__SHIFT 9
+#define CP_CSQ_CNTL__CSQ_CNT_INDIRECT2__MASK 0x07FC0000
+#define CP_CSQ_CNTL__CSQ_CNT_INDIRECT2__SHIFT 18
+#define CRTC_GEN_CNTL 0x00000050
+#define CRTC_GEN_CNTL__CRTC_DBL_SCAN_EN 0x00000001
+#define CRTC_GEN_CNTL__CRTC_INTERLACE_EN 0x00000002
+#define CRTC_GEN_CNTL__CRTC_C_SYNC_EN 0x00000010
+#define CRTC_GEN_CNTL__CRTC_PIX_WIDTH__MASK 0x00000F00
+#define CRTC_GEN_CNTL__CRTC_PIX_WIDTH__SHIFT 8
+#define CRTC_PIX_WIDTH__4BPP 0x100
+#define CRTC_PIX_WIDTH__8BPP 0x200
+#define CRTC_PIX_WIDTH__15BPP 0x300
+#define CRTC_PIX_WIDTH__16BPP 0x400
+#define CRTC_PIX_WIDTH__24BPP 0x500
+#define CRTC_PIX_WIDTH__34BPP 0x600
+#define CRTC_PIX_WIDTH__16BPP_4444 0x700
+#define CRTC_PIX_WIDTH__16BPP_88 0x800
+#define CRTC_GEN_CNTL__CRTC_ICON_EN 0x00008000
+#define CRTC_GEN_CNTL__CRTC_CUR_EN 0x00010000
+#define CRTC_GEN_CNTL__CRTC_VSTAT_MODE__MASK 0x00060000
+#define CRTC_GEN_CNTL__CRTC_VSTAT_MODE__SHIFT 17
+#define CRTC_GEN_CNTL__CRTC_CUR_MODE__MASK 0x00700000
+#define CRTC_GEN_CNTL__CRTC_CUR_MODE__SHIFT 20
+#define CRTC_CUR_MODE__PREMULTI_ALPHA 0x2
+#define CRTC_CUR_MODE__COLOR24BPP 0x1
+#define CRTC_GEN_CNTL__CRTC_EXT_DISP_EN 0x01000000
+#define CRTC_GEN_CNTL__CRTC_EN 0x02000000
+#define CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B 0x04000000
+#define CRTC_GEN_CNTL__CRTC_MODE9_COLOR_ORDER 0x00001000
+#define CRTC_EXT_CNTL 0x00000054
+#define CRTC_EXT_CNTL__CRTC_VGA_XOVERSCAN 0x00000001
+#define CRTC_EXT_CNTL__VGA_BLINK_RATE__MASK 0x00000006
+#define CRTC_EXT_CNTL__VGA_BLINK_RATE__SHIFT 1
+#define CRTC_EXT_CNTL__VGA_ATI_LINEAR 0x00000008
+#define CRTC_EXT_CNTL__VGA_128KAP_PAGING 0x00000010
+#define CRTC_EXT_CNTL__VGA_TEXT_132 0x00000020
+#define CRTC_EXT_CNTL__VGA_XCRT_CNT_EN 0x00000040
+#define CRTC_EXT_CNTL__CRTC_HSYNC_DIS 0x00000100
+#define CRTC_EXT_CNTL__CRTC_VSYNC_DIS 0x00000200
+#define CRTC_EXT_CNTL__CRTC_DISPLAY_DIS 0x00000400
+#define CRTC_EXT_CNTL__CRTC_SYNC_TRISTATE 0x00000800
+#define CRTC_EXT_CNTL__CRTC_HSYNC_TRISTATE 0x00001000
+#define CRTC_EXT_CNTL__CRTC_VSYNC_TRISTATE 0x00002000
+#define CRTC_EXT_CNTL__CRT_ON 0x00008000
+#define CRTC_EXT_CNTL__VGA_CUR_B_TEST 0x00020000
+#define CRTC_EXT_CNTL__VGA_PACK_DIS 0x00040000
+#define CRTC_EXT_CNTL__VGA_MEM_PS_EN 0x00080000
+#define CRTC_EXT_CNTL__VCRTC_IDX_MASTER__MASK 0x7F000000
+#define CRTC_EXT_CNTL__VCRTC_IDX_MASTER__SHIFT 24
+#define CRTC_H_TOTAL_DISP 0x00000200
+#define CRTC_H_TOTAL_DISP__CRTC_H_TOTAL__MASK 0x000003FF
+#define CRTC_H_TOTAL_DISP__CRTC_H_TOTAL__SHIFT 0
+#define CRTC_H_TOTAL_DISP__CRTC_H_DISP__MASK 0x01FF0000
+#define CRTC_H_TOTAL_DISP__CRTC_H_DISP__SHIFT 16
+#define CRTC_H_SYNC_STRT_WID 0x00000204
+#define CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_STRT_PIX__MASK 0x00000007
+#define CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_STRT_PIX__SHIFT 0
+#define CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_STRT_CHAR__MASK 0x00001FF8
+#define CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_STRT_CHAR__SHIFT 3
+#define CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_WID__MASK 0x003F0000
+#define CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_WID__SHIFT 16
+#define CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_POL 0x00800000
+#define CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_SKEW_TUNE__MASK 0x07000000
+#define CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_SKEW_TUNE__SHIFT 24
+#define CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_SKEW_TUNE_MODE 0x10000000
+#define CRTC_V_TOTAL_DISP 0x00000208
+#define CRTC_V_TOTAL_DISP__CRTC_V_TOTAL__MASK 0x00000FFF
+#define CRTC_V_TOTAL_DISP__CRTC_V_TOTAL__SHIFT 0
+#define CRTC_V_TOTAL_DISP__CRTC_V_DISP__MASK 0x0FFF0000
+#define CRTC_V_TOTAL_DISP__CRTC_V_DISP__SHIFT 16
+#define CRTC_V_SYNC_STRT_WID 0x0000020C
+#define CRTC_V_SYNC_STRT_WID__CRTC_V_SYNC_STRT__MASK 0x00000FFF
+#define CRTC_V_SYNC_STRT_WID__CRTC_V_SYNC_STRT__SHIFT 0
+#define CRTC_V_SYNC_STRT_WID__CRTC_V_SYNC_WID__MASK 0x001F0000
+#define CRTC_V_SYNC_STRT_WID__CRTC_V_SYNC_WID__SHIFT 16
+#define CRTC_V_SYNC_STRT_WID__CRTC_V_SYNC_POL 0x00800000
+#define CRTC_OFFSET 0x00000224
+#define CRTC_OFFSET__CRTC_OFFSET__MASK 0x07FFFFFF
+#define CRTC_OFFSET__CRTC_OFFSET__SHIFT 0
+#define CRTC_OFFSET__CRTC_GUI_TRIG_OFFSET 0x40000000
+#define CRTC_OFFSET__CRTC_OFFSET_LOCK 0x80000000
+#define CRTC_OFFSET__CRTC_OFFSET_R3__MASK 0x0FFFFFFF
+#define CRTC_OFFSET__CRTC_OFFSET_R3__SHIFT 0
+#define CRTC_OFFSET_CNTL 0x00000228
+#define CRTC_OFFSET_CNTL__CRTC_TILE_LINE__MASK 0x0000000F
+#define CRTC_OFFSET_CNTL__CRTC_TILE_LINE__SHIFT 0
+#define CRTC_OFFSET_CNTL__CRTC_TILE_LINE_RIGHT__MASK 0x000000F0
+#define CRTC_OFFSET_CNTL__CRTC_TILE_LINE_RIGHT__SHIFT 4
+#define CRTC_OFFSET_CNTL__CRTC_TILE_EN_RIGHT 0x00004000
+#define CRTC_OFFSET_CNTL__CRTC_TILE_EN 0x00008000
+#define CRTC_OFFSET_CNTL__CRTC_OFFSET_FLIP_CNTL 0x00010000
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_OFFSET_EN 0x00020000
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_EN__MASK 0x000C0000
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_EN__SHIFT 18
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN 0x00100000
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC 0x00200000
+#define CRTC_OFFSET_CNTL__CRTC_GUI_TRIG_OFFSET_LEFT_EN 0x10000000
+#define CRTC_OFFSET_CNTL__CRTC_GUI_TRIG_OFFSET_RIGHT_EN 0x20000000
+#define CRTC_OFFSET_CNTL__CRTC_GUI_TRIG_OFFSET 0x40000000
+#define CRTC_OFFSET_CNTL__CRTC_OFFSET_LOCK 0x80000000
+#define CRTC_OFFSET_CNTL__CRTC_X_Y_MODE_EN_RIGHT 0x00000040
+#define CRTC_OFFSET_CNTL__CRTC_MICRO_TILE_BUFFER_MODE_RIGHT__MASK 0x00000180
+#define CRTC_OFFSET_CNTL__CRTC_MICRO_TILE_BUFFER_MODE_RIGHT__SHIFT 7
+#define CRTC_OFFSET_CNTL__CRTC_X_Y_MODE_EN 0x00000200
+#define CRTC_OFFSET_CNTL__CRTC_MICRO_TILE_BUFFER_MODE__MASK 0x00000C00
+#define CRTC_OFFSET_CNTL__CRTC_MICRO_TILE_BUFFER_MODE__SHIFT 10
+#define CRTC_MICRO_TILE_BUFFER_MODE__AUTO 0x0
+#define CRTC_MICRO_TILE_BUFFER_MODE__SLINE 0x1
+#define CRTC_MICRO_TILE_BUFFER_MODE__DLINE 0x2
+#define CRTC_MICRO_TILE_BUFFER_MODE__DIS 0x3
+#define CRTC_OFFSET_CNTL__CRTC_MICRO_TILE_EN_RIGHT 0x00001000
+#define CRTC_OFFSET_CNTL__CRTC_MICRO_TILE_EN 0x00002000
+#define CRTC_OFFSET_CNTL__CRTC_MACRO_TILE_EN_RIGHT 0x00004000
+#define CRTC_OFFSET_CNTL__CRTC_MACRO_TILE_EN 0x00008000
+#define CRTC_PITCH 0x0000022C
+#define CRTC_PITCH__CRTC_PITCH__MASK 0x000007FF
+#define CRTC_PITCH__CRTC_PITCH__SHIFT 0
+#define CRTC_PITCH__CRTC_PITCH_RIGHT__MASK 0x07FF0000
+#define CRTC_PITCH__CRTC_PITCH_RIGHT__SHIFT 16
+#define CRTC_MORE_CNTL 0x0000027C
+#define CRTC_MORE_CNTL__CRTC_HORZ_BLANK_MODE_SEL 0x00000001
+#define CRTC_MORE_CNTL__CRTC_VERT_BLANK_MODE_SEL 0x00000002
+#define CRTC_MORE_CNTL__CRTC_AUTO_HORZ_CENTER_EN 0x00000004
+#define CRTC_MORE_CNTL__CRTC_AUTO_VERT_CENTER_EN 0x00000008
+#define CRTC_MORE_CNTL__CRTC_H_CUTOFF_ACTIVE_EN 0x00000010
+#define CRTC_MORE_CNTL__CRTC_V_CUTOFF_ACTIVE_EN 0x00000020
+#define CRTC_MORE_CNTL__FORCE_H_EVEN_PIXEL_COUNT 0x00000040
+#define CRTC_MORE_CNTL__RMX_H_FILT_COEFFICIENT__MASK 0x07000000
+#define CRTC_MORE_CNTL__RMX_H_FILT_COEFFICIENT__SHIFT 24
+#define CRTC_MORE_CNTL__RMX_H_FILTER_EN 0x08000000
+#define CRTC_MORE_CNTL__RMX_V_FILT_COEFFICIENT__MASK 0x70000000
+#define CRTC_MORE_CNTL__RMX_V_FILT_COEFFICIENT__SHIFT 28
+#define CRTC_MORE_CNTL__RMX_V_FILTER_EN 0x80000000
+#define CRTC_MORE_CNTL__DSP_RST_HCOUNT 0x00000100
+#define CRTC_MORE_CNTL__DSP_RST_VCOUNT 0x00000200
+#define CRTC_MORE_CNTL__HCOUNT_RST_POS 0x00000400
+#define CRTC_MORE_CNTL__VCOUNT_RST_POS 0x00000800
+#define CRTC_MORE_CNTL__CRTC_FIX_VSYNC_EDGE_POSITION_EN 0x00001000
+#define CRTC_TILE_X0_Y0 0x00000350
+#define CRTC_TILE_X0_Y0__CRTC_TILE_X0__MASK 0x00000FFF
+#define CRTC_TILE_X0_Y0__CRTC_TILE_X0__SHIFT 0
+#define CRTC_TILE_X0_Y0__CRTC_TILE_Y0__MASK 0x0FFF0000
+#define CRTC_TILE_X0_Y0__CRTC_TILE_Y0__SHIFT 16
+#define CRTC_TILE_X0_Y0__CRTC_GUI_TRIG_OFFSET 0x40000000
+#define CRTC_TILE_X0_Y0__CRTC_OFFSET_LOCK 0x80000000
+#define DAC_CNTL 0x00000058
+#define DAC_CNTL__DAC_RANGE_CNTL__MASK 0x00000003
+#define DAC_CNTL__DAC_RANGE_CNTL__SHIFT 0
+#define DAC_RANGE_CNTL__PS2 0x2
+#define DAC_RANGE_CNTL__YPbPr 0x3
+#define DAC_CNTL__DAC_BLANKING 0x00000004
+#define DAC_CNTL__DAC_CMP_EN 0x00000008
+#define DAC_CNTL__DAC_CMP_OUT_R 0x00000010
+#define DAC_CNTL__DAC_CMP_OUT_G 0x00000020
+#define DAC_CNTL__DAC_CMP_OUT_B 0x00000040
+#define DAC_CNTL__DAC_CMP_OUTPUT 0x00000080
+#define DAC_CNTL__DAC_8BIT_EN 0x00000100
+#define DAC_CNTL__DAC_4BPP_PIX_ORDER 0x00000200
+#define DAC_CNTL__DAC_TVO_EN 0x00000400
+#define DAC_CNTL__DAC_VGA_ADR_EN 0x00002000
+#define DAC_CNTL__DAC_EXPAND_MODE 0x00004000
+#define DAC_CNTL__DAC_PDWN 0x00008000
+#define DAC_CNTL__CRT_SENSE 0x00010000
+#define DAC_CNTL__CRT_DETECTION_ON 0x00020000
+#define DAC_CNTL__DAC_CRC_CONT_EN 0x00040000
+#define DAC_CNTL__DAC_CRC_EN 0x00080000
+#define DAC_CNTL__DAC_CRC_FIELD 0x00100000
+#define DAC_CNTL__DAC_LUT_COUNTER_LIMIT__MASK 0x00600000
+#define DAC_CNTL__DAC_LUT_COUNTER_LIMIT__SHIFT 21
+#define DAC_CNTL__DAC_LUT_READ_SEL 0x00800000
+#define DAC_CNTL__DAC__MASK 0xFF000000
+#define DAC_CNTL__DAC__SHIFT 24
+#define DAC_CNTL__DAC_CRC_BLANKb_ONLY 0x00000800
+#define DAC_CNTL2 0x0000007C
+#define DAC_CNTL2__DAC_CLK_SEL 0x00000001
+#define DAC_CNTL2__DAC2_CLK_SEL 0x00000002
+#define DAC_CNTL2__PALETTE_ACCESS_CNTL 0x00000020
+#define DAC_CNTL2__DAC2_CMP_EN 0x00000080
+#define DAC_CNTL2__DAC2_CMP_OUT_R 0x00000100
+#define DAC_CNTL2__DAC2_CMP_OUT_G 0x00000200
+#define DAC_CNTL2__DAC2_CMP_OUT_B 0x00000400
+#define DAC_CNTL2__DAC2_CMP_OUTPUT 0x00000800
+#define DAC_CNTL2__DAC2_EXPAND_MODE 0x00004000
+#define DAC_CNTL2__CRT2_SENSE 0x00010000
+#define DAC_CNTL2__CRT2_DETECTION_ON 0x00020000
+#define DAC_CNTL2__DAC_CRC2_CONT_EN 0x00040000
+#define DAC_CNTL2__DAC_CRC2_EN 0x00080000
+#define DAC_CNTL2__DAC_CRC2_FIELD 0x00100000
+#define DAC_CNTL2__DAC2_LUT_COUNTER_LIMIT__MASK 0x00600000
+#define DAC_CNTL2__DAC2_LUT_COUNTER_LIMIT__SHIFT 21
+#define DAC_CNTL2__PALETTE_AUTOFILL_PRIMARY_W 0x00000800
+#define DAC_CNTL2__PALETTE_AUTOFILL_PRIMARY_R 0x00000800
+#define DAC_CNTL2__PALETTE_AUTOFILL_SECONDARY_W 0x00001000
+#define DAC_CNTL2__PALETTE_AUTOFILL_SECONDARY_R 0x00001000
+#define DAC_CNTL2__DAC2_CMP_EN_R3 0x00000040
+#define DAC_CNTL2__DAC2_CMP_OUT_R_R3 0x00000080
+#define DAC_CNTL2__DAC2_CMP_OUT_G_R3 0x00000100
+#define DAC_CNTL2__DAC2_CMP_OUT_B_R3 0x00000200
+#define DAC_CNTL2__DAC2_CMP_OUTPUT_R3 0x00000400
+#define DAC_CNTL2__DAC_CRC2_BLANKb_ONLY 0x00020000
+#define DAC_EXT_CNTL 0x00000280
+#define DAC_EXT_CNTL__DAC2_FORCE_BLANK_OFF_EN 0x00000001
+#define DAC_EXT_CNTL__DAC2_FORCE_DATA_EN 0x00000002
+#define DAC_EXT_CNTL__DAC_FORCE_BLANK_OFF_EN 0x00000010
+#define DAC_EXT_CNTL__DAC_FORCE_DATA_EN 0x00000020
+#define DAC_EXT_CNTL__DAC_FORCE_DATA_SEL__MASK 0x000000C0
+#define DAC_EXT_CNTL__DAC_FORCE_DATA_SEL__SHIFT 6
+#define DAC_EXT_CNTL__DAC_FORCE_DATA__MASK 0x0003FF00
+#define DAC_EXT_CNTL__DAC_FORCE_DATA__SHIFT 8
+#define DISP_MISC_CNTL 0x00000D00
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH_PP 0x00000001
+#define DISP_MISC_CNTL__SOFT_RESET_SUBPIC_PP 0x00000002
+#define DISP_MISC_CNTL__SOFT_RESET_OV0_PP 0x00000004
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH_SCLK 0x00000010
+#define DISP_MISC_CNTL__SOFT_RESET_SUBPIC_SCLK 0x00000020
+#define DISP_MISC_CNTL__SOFT_RESET_OV0_SCLK 0x00000040
+#define DISP_MISC_CNTL__SYNC_STRENGTH__MASK 0x00000300
+#define DISP_MISC_CNTL__SYNC_STRENGTH__SHIFT 8
+#define DISP_MISC_CNTL__SYNC_PAD_FLOP_EN 0x00000400
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH2_PP 0x00001000
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH2_SCLK 0x00008000
+#define DISP_MISC_CNTL__SOFT_RESET_LVDS 0x00010000
+#define DISP_MISC_CNTL__SOFT_RESET_TMDS 0x00020000
+#define DISP_MISC_CNTL__SOFT_RESET_DIG_TMDS 0x00040000
+#define DISP_MISC_CNTL__SOFT_RESET_TV 0x00080000
+#define DISP_MISC_CNTL__PALETTE2_MEM_RD_MARGIN__MASK 0x00F00000
+#define DISP_MISC_CNTL__PALETTE2_MEM_RD_MARGIN__SHIFT 20
+#define DISP_MISC_CNTL__PALETTE_MEM_RD_MARGIN__MASK 0x0F000000
+#define DISP_MISC_CNTL__PALETTE_MEM_RD_MARGIN__SHIFT 24
+#define DISP_MISC_CNTL__RMX_BUF_MEM_RD_MARGIN__MASK 0xF0000000
+#define DISP_MISC_CNTL__RMX_BUF_MEM_RD_MARGIN__SHIFT 28
+#define DISP_MISC_CNTL__SOFT_RESET_DVO 0x00040000
+#define DISP_MISC_CNTL__SOFT_RESET_TV_R2 0x00000800
+#define DAC_MACRO_CNTL 0x00000D04
+#define DAC_MACRO_CNTL__DAC_WHITE_CNTL__MASK 0x0000000F
+#define DAC_MACRO_CNTL__DAC_WHITE_CNTL__SHIFT 0
+#define DAC_MACRO_CNTL__DAC_BG_ADJ__MASK 0x00000F00
+#define DAC_MACRO_CNTL__DAC_BG_ADJ__SHIFT 8
+#define DAC_MACRO_CNTL__DAC_PDWN_R 0x00010000
+#define DAC_MACRO_CNTL__DAC_PDWN_G 0x00020000
+#define DAC_MACRO_CNTL__DAC_PDWN_B 0x00040000
+#define DISP_PWR_MAN 0x00000D08
+#define DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN 0x00000001
+#define DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN 0x00000010
+#define DISP_PWR_MAN__DISP_PWR_MAN_DPMS__MASK 0x00000300
+#define DISP_PWR_MAN__DISP_PWR_MAN_DPMS__SHIFT 8
+#define DISP_PWR_MAN_DPMS__ON 0x0
+#define DISP_PWR_MAN_DPMS__STANDBY 0x1
+#define DISP_PWR_MAN_DPMS__SUSPEND 0x2
+#define DISP_PWR_MAN_DPMS__OFF 0x3
+#define DISP_PWR_MAN__DISP_D3_RST 0x00010000
+#define DISP_PWR_MAN__DISP_D3_REG_RST 0x00020000
+#define DISP_PWR_MAN__DISP_D3_GRPH_RST 0x00040000
+#define DISP_PWR_MAN__DISP_D3_SUBPIC_RST 0x00080000
+#define DISP_PWR_MAN__DISP_D3_OV0_RST 0x00100000
+#define DISP_PWR_MAN__DISP_D1D2_GRPH_RST 0x00200000
+#define DISP_PWR_MAN__DISP_D1D2_SUBPIC_RST 0x00400000
+#define DISP_PWR_MAN__DISP_D1D2_OV0_RST 0x00800000
+#define DISP_PWR_MAN__DIG_TMDS_ENABLE_RST 0x01000000
+#define DISP_PWR_MAN__TV_ENABLE_RST 0x02000000
+#define DISP_PWR_MAN__AUTO_PWRUP_EN 0x04000000
+#define DISP_PWR_MAN__DISP_DVO_ENABLE_RST 0x01000000
+#define DISP_MERGE_CNTL 0x00000D60
+#define DISP_MERGE_CNTL__DISP_ALPHA_MODE__MASK 0x00000003
+#define DISP_MERGE_CNTL__DISP_ALPHA_MODE__SHIFT 0
+#define DISP_MERGE_CNTL__DISP_ALPHA_INV 0x00000004
+#define DISP_MERGE_CNTL__DISP_ALPHA_PREMULT 0x00000008
+#define DISP_MERGE_CNTL__DISP_RGB_OFFSET_EN 0x00000100
+#define DISP_MERGE_CNTL__DISP_LIN_TRANS_BYPASS 0x00000200
+#define DISP_MERGE_CNTL__DISP_GRPH_ALPHA__MASK 0x00FF0000
+#define DISP_MERGE_CNTL__DISP_GRPH_ALPHA__SHIFT 16
+#define DISP_MERGE_CNTL__DISP_OV0_ALPHA__MASK 0xFF000000
+#define DISP_MERGE_CNTL__DISP_OV0_ALPHA__SHIFT 24
+#define DISP_OUTPUT_CNTL 0x00000D64
+#define DISP_OUTPUT_CNTL__DISP_DAC_SOURCE__MASK 0x00000003
+#define DISP_OUTPUT_CNTL__DISP_DAC_SOURCE__SHIFT 0
+#define DISP_DAC_SOURCE__YPbPr 0x3
+#define DISP_DAC_SOURCE__PRIMARYCRTC 0x0
+#define DISP_DAC_SOURCE__SECONDARYCRTC 0x1
+#define DISP_DAC_SOURCE__RMX 0x2
+#define DISP_OUTPUT_CNTL__DISP_TRANS_MATRIX_SEL__MASK 0x00000030
+#define DISP_OUTPUT_CNTL__DISP_TRANS_MATRIX_SEL__SHIFT 4
+#define DISP_OUTPUT_CNTL__DISP_RMX_SOURCE 0x00000100
+#define DISP_OUTPUT_CNTL__DISP_RMX_HTAP_SEL 0x00000200
+#define DISP_OUTPUT_CNTL__DISP_RMX_DITH_EN 0x00000400
+#define DISP_OUTPUT_CNTL__DISP_TV_SOURCE 0x00010000
+#define DISP_OUTPUT_CNTL__DISP_TV_MODE__MASK 0x00060000
+#define DISP_OUTPUT_CNTL__DISP_TV_MODE__SHIFT 17
+#define DISP_OUTPUT_CNTL__DISP_TV_YG_DITH_EN 0x00080000
+#define DISP_OUTPUT_CNTL__DISP_TV_CbB_CrR_DITH_EN 0x00100000
+#define DISP_OUTPUT_CNTL__DISP_TV_BIT_WIDTH 0x00200000
+#define DISP_OUTPUT_CNTL__DISP_TV_SYNC_MODE__MASK 0x00C00000
+#define DISP_OUTPUT_CNTL__DISP_TV_SYNC_MODE__SHIFT 22
+#define DISP_OUTPUT_CNTL__DISP_TV_SYNC_FORCE 0x01000000
+#define DISP_OUTPUT_CNTL__DISP_TV_SYNC_COLOR__MASK 0x06000000
+#define DISP_OUTPUT_CNTL__DISP_TV_SYNC_COLOR__SHIFT 25
+#define DISP_OUTPUT_CNTL__DISP_TV_EVEN_FLAG_CNTL__MASK 0x18000000
+#define DISP_OUTPUT_CNTL__DISP_TV_EVEN_FLAG_CNTL__SHIFT 27
+#define DISP_OUTPUT_CNTL__DISP_TV_SYNC_STATUS 0x20000000
+#define DISP_OUTPUT_CNTL__DISP_TV_H_DOWNSCALE 0x40000000
+#define DISP_OUTPUT_CNTL__DISP_TRANS_SOURCE__MASK 0x00003000
+#define DISP_OUTPUT_CNTL__DISP_TRANS_SOURCE__SHIFT 12
+#define DISP_TRANS_SOURCE__PRIMARYCRTC 0x0
+#define DISP_TRANS_SOURCE__SECONDARYCRTC 0x1
+#define DISP_TRANS_SOURCE__RMX 0x2
+#define DISP_OUTPUT_CNTL__DISP_TVDAC_SOURCE__MASK 0x0000000C
+#define DISP_OUTPUT_CNTL__DISP_TVDAC_SOURCE__SHIFT 2
+#define DISP_TVDAC_SOURCE__PRIMARYCRTC 0x0
+#define DISP_TVDAC_SOURCE__SECONDARYCRTC 0x1
+#define DISP_TVDAC_SOURCE__RMX 0x2
+#define DISP_TVDAC_SOURCE__YPbPr 0x3
+#define DISP2_MERGE_CNTL 0x00000D68
+#define DISP2_MERGE_CNTL__DISP2_RGB_OFFSET_EN 0x00000100
+#define DAC_EMBEDDED_SYNC_CNTL 0x00000DC0
+#define DAC_EMBEDDED_SYNC_CNTL__DAC_EMBED_SYNC_EN_Y_G 0x00000001
+#define DAC_EMBEDDED_SYNC_CNTL__DAC_EMBED_SYNC_EN_Cb_B 0x00000002
+#define DAC_EMBEDDED_SYNC_CNTL__DAC_EMBED_SYNC_EN_Cr_R 0x00000004
+#define DAC_EMBEDDED_SYNC_CNTL__DAC_TRILEVEL_SYNC_EN 0x00000008
+#define DAC_EMBEDDED_SYNC_CNTL__DAC_EMBED_VSYNC_EN_Y_G 0x00000010
+#define DAC_EMBEDDED_SYNC_CNTL__DAC_EMBED_VSYNC_EN_CbCr_BR 0x00000020
+#define DAC_EMBEDDED_SYNC_CNTL__DAC_HSYNC_WID_LSB__MASK 0x00070000
+#define DAC_EMBEDDED_SYNC_CNTL__DAC_HSYNC_WID_LSB__SHIFT 16
+#define DAC_BROAD_PULSE 0x00000DC4
+#define DAC_BROAD_PULSE__DAC_BROAD_PULSE_START__MASK 0x00001FFF
+#define DAC_BROAD_PULSE__DAC_BROAD_PULSE_START__SHIFT 0
+#define DAC_BROAD_PULSE__DAC_BROAD_PULSE_END__MASK 0x1FFF0000
+#define DAC_BROAD_PULSE__DAC_BROAD_PULSE_END__SHIFT 16
+#define DAC_BROAD_PULSE__DAC_BROAD_PULSE_START_R2__MASK 0x00000FFF
+#define DAC_BROAD_PULSE__DAC_BROAD_PULSE_START_R2__SHIFT 0
+#define DAC_BROAD_PULSE__DAC_BROAD_PULSE_END_R2__MASK 0x0FFF0000
+#define DAC_BROAD_PULSE__DAC_BROAD_PULSE_END_R2__SHIFT 16
+#define DAC_SKEW_CLKS 0x00000DC8
+#define DAC_SKEW_CLKS__DAC_SKEW_CLKS__MASK 0x000000FF
+#define DAC_SKEW_CLKS__DAC_SKEW_CLKS__SHIFT 0
+#define DAC_INCR 0x00000DCC
+#define DAC_INCR__DAC_INCR_Y_G__MASK 0x000003FF
+#define DAC_INCR__DAC_INCR_Y_G__SHIFT 0
+#define DAC_INCR__DAC_INCR_CrCb_RB__MASK 0x03FF0000
+#define DAC_INCR__DAC_INCR_CrCb_RB__SHIFT 16
+#define DAC_NEG_SYNC_LEVEL 0x00000DD0
+#define DAC_NEG_SYNC_LEVEL__DAC_NEG_SYNC_LEVEL_Y_G__MASK 0x000003FF
+#define DAC_NEG_SYNC_LEVEL__DAC_NEG_SYNC_LEVEL_Y_G__SHIFT 0
+#define DAC_NEG_SYNC_LEVEL__DAC_NEG_SYNC_LEVEL_CrCb_RB__MASK 0x03FF0000
+#define DAC_NEG_SYNC_LEVEL__DAC_NEG_SYNC_LEVEL_CrCb_RB__SHIFT 16
+#define DAC_POS_SYNC_LEVEL 0x00000DD4
+#define DAC_POS_SYNC_LEVEL__DAC_POS_SYNC_LEVEL_Y_G__MASK 0x000003FF
+#define DAC_POS_SYNC_LEVEL__DAC_POS_SYNC_LEVEL_Y_G__SHIFT 0
+#define DAC_POS_SYNC_LEVEL__DAC_POS_SYNC_LEVEL_CrCb_RB__MASK 0x03FF0000
+#define DAC_POS_SYNC_LEVEL__DAC_POS_SYNC_LEVEL_CrCb_RB__SHIFT 16
+#define DAC_BLANK_LEVEL 0x00000DD8
+#define DAC_BLANK_LEVEL__DAC_BLANK_LEVEL_Y_G__MASK 0x000003FF
+#define DAC_BLANK_LEVEL__DAC_BLANK_LEVEL_Y_G__SHIFT 0
+#define DAC_BLANK_LEVEL__DAC_BLANK_LEVEL_CrCb_RB__MASK 0x03FF0000
+#define DAC_BLANK_LEVEL__DAC_BLANK_LEVEL_CrCb_RB__SHIFT 16
+#define DAC_SYNC_EQUALIZATION 0x00000DDC
+#define DAC_SYNC_EQUALIZATION__DAC_SYNC_EQ_START__MASK 0x000007FF
+#define DAC_SYNC_EQUALIZATION__DAC_SYNC_EQ_START__SHIFT 0
+#define DAC_SYNC_EQUALIZATION__DAC_SYNC_EQ_END__MASK 0x07FF0000
+#define DAC_SYNC_EQUALIZATION__DAC_SYNC_EQ_END__SHIFT 16
+#define TV_MASTER_CNTL 0x00000800
+#define TV_MASTER_CNTL__TV_ASYNC_RST 0x00000001
+#define TV_MASTER_CNTL__CRT_ASYNC_RST 0x00000002
+#define TV_MASTER_CNTL__RESTART_PHASE_FIX 0x00000008
+#define TV_MASTER_CNTL__TV_FIFO_ASYNC_RST 0x00000010
+#define TV_MASTER_CNTL__MV_BP_LEVEL_FIX_EN 0x00000020
+#define TV_MASTER_CNTL__EXTRA_BIT_ONE_0 0x00000040
+#define TV_MASTER_CNTL__CRT_FIFO_CE_EN 0x00000200
+#define TV_MASTER_CNTL__TV_FIFO_CE_EN 0x00000400
+#define TV_MASTER_CNTL__RE_SYNC_NOW_SEL__MASK 0x0000C000
+#define TV_MASTER_CNTL__RE_SYNC_NOW_SEL__SHIFT 14
+#define TV_MASTER_CNTL__EXTRA_BIT_ZERO_1 0x00010000
+#define TV_MASTER_CNTL__EXTRA_BIT_ONE_1 0x00020000
+#define TV_MASTER_CNTL__EXTRA_BIT_ZERO_2 0x00040000
+#define TV_MASTER_CNTL__EXTRA_BIT_ONE_2 0x00080000
+#define TV_MASTER_CNTL__TVCLK_ALWAYS_ONb 0x40000000
+#define TV_MASTER_CNTL__TV_ON 0x80000000
+#define TV_DAC_CNTL 0x0000088C
+#define TV_DAC_CNTL__NBLANK 0x00000001
+#define TV_DAC_CNTL__NHOLD 0x00000002
+#define TV_DAC_CNTL__PEDESTAL 0x00000004
+#define TV_DAC_CNTL__DETECT 0x00000010
+#define TV_DAC_CNTL__CMPOUT 0x00000020
+#define TV_DAC_CNTL__BGSLEEP 0x00000040
+#define TV_DAC_CNTL__STD__MASK 0x00000300
+#define TV_DAC_CNTL__STD__SHIFT 8
+#define STD__PAL 0x0
+#define STD__NTSC 0x1
+#define STD__PS2 0x2
+#define STD__RS343 0x3
+#define TV_DAC_CNTL__MON__MASK 0x0000F000
+#define TV_DAC_CNTL__MON__SHIFT 12
+#define TV_DAC_CNTL__BGADJ__MASK 0x000F0000
+#define TV_DAC_CNTL__BGADJ__SHIFT 16
+#define TV_DAC_CNTL__DACADJ__MASK 0x00F00000
+#define TV_DAC_CNTL__DACADJ__SHIFT 20
+#define TV_DAC_CNTL__RDACPD 0x01000000
+#define TV_DAC_CNTL__GDACPD 0x02000000
+#define TV_DAC_CNTL__BDACPD 0x04000000
+#define TV_DAC_CNTL__RDACDET 0x20000000
+#define TV_DAC_CNTL__GDACDET 0x40000000
+#define TV_DAC_CNTL__BDACDET 0x80000000
+#define TV_DAC_CNTL__DACADJ_R4__MASK 0x01F00000
+#define TV_DAC_CNTL__DACADJ_R4__SHIFT 20
+#define TV_DAC_CNTL__RDACPD_R4 0x02000000
+#define TV_DAC_CNTL__GDACPD_R4 0x04000000
+#define TV_DAC_CNTL__BDACPD_R4 0x08000000
+#define TV_DAC_CNTL__TVENABLE_R4 0x10000000
+#define VIPPAD_EN 0x000001A0
+#define VIPPAD_EN__VIPPAD_EN__MASK 0x0007FFFF
+#define VIPPAD_EN__VIPPAD_EN__SHIFT 0
+#define VIPPAD_EN__VIPPAD_EN_TVODATA__MASK 0x000003FF
+#define VIPPAD_EN__VIPPAD_EN_TVODATA__SHIFT 0
+#define VIPPAD_EN__VIPPAD_EN_TVOCLKO 0x00000400
+#define VIPPAD_EN__VIPPAD_EN_ROMCSb 0x00000800
+#define VIPPAD_EN__VIPPAD_EN_VHAD__MASK 0x00003000
+#define VIPPAD_EN__VIPPAD_EN_VHAD__SHIFT 12
+#define VIPPAD_EN__VIPPAD_EN_VPHCTL 0x00010000
+#define VIPPAD_EN__VIPPAD_EN_VIPCLK 0x00020000
+#define VIPPAD_EN__VIPPAD_EN_SI 0x00080000
+#define VIPPAD_EN__VIPPAD_EN_SO 0x00100000
+#define VIPPAD_EN__VIPPAD_EN_SCK 0x00200000
+#define VIPPAD_Y 0x000001A4
+#define VIPPAD_Y__VIPPAD_Y__MASK 0x0007FFFF
+#define VIPPAD_Y__VIPPAD_Y__SHIFT 0
+#define VIPPAD_Y__VIPPAD_Y_TVODATA__MASK 0x000003FF
+#define VIPPAD_Y__VIPPAD_Y_TVODATA__SHIFT 0
+#define VIPPAD_Y__VIPPAD_Y_TVOCLKO 0x00000400
+#define VIPPAD_Y__VIPPAD_Y_ROMCSb 0x00000800
+#define VIPPAD_Y__VIPPAD_Y_VHAD__MASK 0x00003000
+#define VIPPAD_Y__VIPPAD_Y_VHAD__SHIFT 12
+#define VIPPAD_Y__VIPPAD_Y_VPHCTL 0x00010000
+#define VIPPAD_Y__VIPPAD_Y_VIPCLK 0x00020000
+#define VIPPAD_Y__VIPPAD_Y_SI 0x00080000
+#define VIPPAD_Y__VIPPAD_Y_SO 0x00100000
+#define VIPPAD_Y__VIPPAD_Y_SCK 0x00200000
+#define VIPPAD1_EN 0x000001B0
+#define VIPPAD1_EN__VIPPAD1_EN__MASK 0x0003FFFF
+#define VIPPAD1_EN__VIPPAD1_EN__SHIFT 0
+#define VIPPAD1_EN__VIPPAD_EN_VID__MASK 0x000000FF
+#define VIPPAD1_EN__VIPPAD_EN_VID__SHIFT 0
+#define VIPPAD1_EN__VIPPAD_EN_VPCLK0 0x00000100
+#define VIPPAD1_EN__VIPPAD_EN_DVALID 0x00000200
+#define VIPPAD1_EN__VIPPAD_EN_PSYNC 0x00000400
+#define VIPPAD1_EN__VIPPAD_EN_DVODATA__MASK 0x0FFF0000
+#define VIPPAD1_EN__VIPPAD_EN_DVODATA__SHIFT 16
+#define VIPPAD1_EN__VIPPAD_EN_DVOCNTL__MASK 0x70000000
+#define VIPPAD1_EN__VIPPAD_EN_DVOCNTL__SHIFT 28
+#define VIPPAD1_Y 0x000001B4
+#define VIPPAD1_Y__VIPPAD1_Y__MASK 0x0003FFFF
+#define VIPPAD1_Y__VIPPAD1_Y__SHIFT 0
+#define VIPPAD1_Y__VIPPAD_Y_VID__MASK 0x000000FF
+#define VIPPAD1_Y__VIPPAD_Y_VID__SHIFT 0
+#define VIPPAD1_Y__VIPPAD_Y_VPCLK0 0x00000100
+#define VIPPAD1_Y__VIPPAD_Y_DVALID 0x00000200
+#define VIPPAD1_Y__VIPPAD_Y_PSYNC 0x00000400
+#define VIPPAD1_Y__VIPPAD_Y_DVODATA__MASK 0x0FFF0000
+#define VIPPAD1_Y__VIPPAD_Y_DVODATA__SHIFT 16
+#define VIPPAD1_Y__VIPPAD_Y_DVOCNTL__MASK 0x70000000
+#define VIPPAD1_Y__VIPPAD_Y_DVOCNTL__SHIFT 28
+#define GPIO_DDC1 0x00000060
+#define GPIO_DDC1__DDC1_DATA_OUTPUT 0x00000001
+#define GPIO_DDC1__DDC1_CLK_OUTPUT 0x00000002
+#define GPIO_DDC1__DDC1_DATA_INPUT 0x00000100
+#define GPIO_DDC1__DDC1_CLK_INPUT 0x00000200
+#define GPIO_DDC1__DDC1_DATA_OUT_EN 0x00010000
+#define GPIO_DDC1__DDC1_CLK_OUT_EN 0x00020000
+#define GPIO_DDC1__SW_WANTS_TO_USE_DVI_I2C 0x00100000
+#define GPIO_DDC1__SW_CAN_USE_DVI_I2C 0x00100000
+#define GPIO_DDC1__SW_DONE_USING_DVI_I2C 0x00200000
+#define GPIO_DDC1__HW_USING_DVI_I2C 0x00400000
+#define GPIO_DDC2 0x00000064
+#define GPIO_DDC2__DDC2_DATA_OUTPUT 0x00000001
+#define GPIO_DDC2__DDC2_CLK_OUTPUT 0x00000002
+#define GPIO_DDC2__DDC2_DATA_INPUT 0x00000100
+#define GPIO_DDC2__DDC2_CLK_INPUT 0x00000200
+#define GPIO_DDC2__DDC2_DATA_OUT_EN 0x00010000
+#define GPIO_DDC2__DDC2_CLK_OUT_EN 0x00020000
+#define GPIO_DDC2__SW_WANTS_TO_USE_DVI_I2C 0x00100000
+#define GPIO_DDC2__SW_CAN_USE_DVI_I2C 0x00100000
+#define GPIO_DDC2__SW_DONE_USING_DVI_I2C 0x00200000
+#define GPIO_DDC2__HW_USING_DVI_I2C 0x00400000
+#define GPIO_DVI_DDC 0x00000064
+#define GPIO_DVI_DDC__DVI_DDC_DATA_OUTPUT 0x00000001
+#define GPIO_DVI_DDC__DVI_DCC_DATA_OUTPUT 0x00000001
+#define GPIO_DVI_DDC__DVI_DDC_CLK_OUTPUT 0x00000002
+#define GPIO_DVI_DDC__DVI_DDC_DATA_INPUT 0x00000100
+#define GPIO_DVI_DDC__DVI_DDC_CLK_INPUT 0x00000200
+#define GPIO_DVI_DDC__DVI_DDC_DATA_OUT_EN 0x00010000
+#define GPIO_DVI_DDC__DVI_DDC_CLK_OUT_EN 0x00020000
+#define GPIO_DVI_DDC__SW_WANTS_TO_USE_DVI_I2C 0x00100000
+#define GPIO_DVI_DDC__SW_CAN_USE_DVI_I2C 0x00100000
+#define GPIO_DVI_DDC__SW_DONE_USING_DVI_I2C 0x00200000
+#define GPIO_DVI_DDC__HW_USING_DVI_I2C 0x00400000
+#define GPIO_MONID 0x00000068
+#define GPIO_MONID__GPIO_MONID_0_OUTPUT 0x00000001
+#define GPIO_MONID__GPIO_MONID_1_OUTPUT 0x00000002
+#define GPIO_MONID__GPIO_MONID_0_INPUT 0x00000100
+#define GPIO_MONID__GPIO_MONID_1_INPUT 0x00000200
+#define GPIO_MONID__GPIO_MONID_0_OUT_EN 0x00010000
+#define GPIO_MONID__GPIO_MONID_1_OUT_EN 0x00020000
+#define GPIO_CRT2_DDC 0x0000006C
+#define GPIO_CRT2_DDC__CRT2_DDC_DATA_OUTPUT 0x00000001
+#define GPIO_CRT2_DDC__CRT2_DDC_CLK_OUTPUT 0x00000002
+#define GPIO_CRT2_DDC__CRT2_DDC_DATA_INPUT 0x00000100
+#define GPIO_CRT2_DDC__CRT2_DDC_CLK_INPUT 0x00000200
+#define GPIO_CRT2_DDC__CRT2_DDC_DATA_OUT_EN 0x00010000
+#define GPIO_CRT2_DDC__CRT2_DDC_CLK_OUT_EN 0x00020000
+#define CLOCK_CNTL_INDEX 0x00000008
+#define CLOCK_CNTL_INDEX__PLL_ADDR__MASK 0x0000001F
+#define CLOCK_CNTL_INDEX__PLL_ADDR__SHIFT 0
+#define CLOCK_CNTL_INDEX__PLL_WR_EN 0x00000080
+#define CLOCK_CNTL_INDEX__PPLL_DIV_SEL__MASK 0x00000300
+#define CLOCK_CNTL_INDEX__PPLL_DIV_SEL__SHIFT 8
+#define CLOCK_CNTL_INDEX__PLL_ADDR_R2__MASK 0x0000003F
+#define CLOCK_CNTL_INDEX__PLL_ADDR_R2__SHIFT 0
+#define CLOCK_CNTL_DATA 0x0000000C
+#define CLOCK_CNTL_DATA__PLL_DATA__MASK 0xFFFFFFFF
+#define CLOCK_CNTL_DATA__PLL_DATA__SHIFT 0
+#define MCLK_CNTL 0x00000012
+#define MCLK_CNTL__MCLKA_SRC_SEL__MASK 0x00000007
+#define MCLK_CNTL__MCLKA_SRC_SEL__SHIFT 0
+#define MCLK_CNTL__YCLKA_SRC_SEL__MASK 0x00000070
+#define MCLK_CNTL__YCLKA_SRC_SEL__SHIFT 4
+#define MCLK_CNTL__MCLKB_SRC_SEL__MASK 0x00000700
+#define MCLK_CNTL__MCLKB_SRC_SEL__SHIFT 8
+#define MCLK_CNTL__YCLKB_SRC_SEL__MASK 0x00007000
+#define MCLK_CNTL__YCLKB_SRC_SEL__SHIFT 12
+#define MCLK_CNTL__FORCE_MCLKA 0x00010000
+#define MCLK_CNTL__FORCE_MCLKB 0x00020000
+#define MCLK_CNTL__FORCE_YCLKA 0x00040000
+#define MCLK_CNTL__FORCE_YCLKB 0x00080000
+#define MCLK_CNTL__FORCE_MC 0x00100000
+#define MCLK_CNTL__FORCE_AIC 0x00200000
+#define MCLK_CNTL__MRDCKA0_SOUTSEL__MASK 0x03000000
+#define MCLK_CNTL__MRDCKA0_SOUTSEL__SHIFT 24
+#define MCLK_CNTL__MRDCKA1_SOUTSEL__MASK 0x0C000000
+#define MCLK_CNTL__MRDCKA1_SOUTSEL__SHIFT 26
+#define MCLK_CNTL__MRDCKB0_SOUTSEL__MASK 0x30000000
+#define MCLK_CNTL__MRDCKB0_SOUTSEL__SHIFT 28
+#define MCLK_CNTL__MRDCKB1_SOUTSEL__MASK 0xC0000000
+#define MCLK_CNTL__MRDCKB1_SOUTSEL__SHIFT 30
+#define MCLK_CNTL__FORCE_MC_MCLKA 0x00010000
+#define MCLK_CNTL__FORCE_MC_MCLKB 0x00020000
+#define MCLK_CNTL__FORCE_MC_MCLK 0x00100000
+#define MCLK_CNTL__DISABLE_MC_MCLKA 0x00200000
+#define MCLK_CNTL__DISABLE_MC_MCLKB 0x00400000
+#define SCLK_CNTL 0x0000000D
+#define SCLK_CNTL__SCLK_SRC_SEL__MASK 0x00000007
+#define SCLK_CNTL__SCLK_SRC_SEL__SHIFT 0
+#define SCLK_CNTL__TCLK_SRC_SEL__MASK 0x00000700
+#define SCLK_CNTL__TCLK_SRC_SEL__SHIFT 8
+#define SCLK_CNTL__FORCE_CP 0x00010000
+#define SCLK_CNTL__FORCE_HDP 0x00020000
+#define SCLK_CNTL__FORCE_DISP 0x00040000
+#define SCLK_CNTL__FORCE_TOP 0x00080000
+#define SCLK_CNTL__FORCE_E2 0x00100000
+#define SCLK_CNTL__FORCE_SE 0x00200000
+#define SCLK_CNTL__FORCE_IDCT 0x00400000
+#define SCLK_CNTL__FORCE_VIP 0x00800000
+#define SCLK_CNTL__FORCE_RE 0x01000000
+#define SCLK_CNTL__FORCE_PB 0x02000000
+#define SCLK_CNTL__FORCE_TAM 0x04000000
+#define SCLK_CNTL__FORCE_TDM 0x08000000
+#define SCLK_CNTL__FORCE_RB 0x10000000
+#define SCLK_CNTL__CP_MAX_DYN_STOP_LAT 0x00000008
+#define SCLK_CNTL__HDP_MAX_DYN_STOP_LAT 0x00000010
+#define SCLK_CNTL__E2_MAX_DYN_STOP_LAT 0x00000040
+#define SCLK_CNTL__SE_MAX_DYN_STOP_LAT 0x00000080
+#define SCLK_CNTL__IDCT_MAX_DYN_STOP_LAT 0x00000100
+#define SCLK_CNTL__VIP_MAX_DYN_STOP_LAT 0x00000200
+#define SCLK_CNTL__RE_MAX_DYN_STOP_LAT 0x00000400
+#define SCLK_CNTL__PB_MAX_DYN_STOP_LAT 0x00000800
+#define SCLK_CNTL__TAM_MAX_DYN_STOP_LAT 0x00001000
+#define SCLK_CNTL__TDM_MAX_DYN_STOP_LAT 0x00002000
+#define SCLK_CNTL__RB_MAX_DYN_STOP_LAT 0x00004000
+#define SCLK_CNTL__FORCE_DISP2 0x00008000
+#define SCLK_CNTL__FORCE_DISP1 0x00040000
+#define SCLK_CNTL__FORCE_SUBPIC 0x40000000
+#define SCLK_CNTL__FORCE_OV0 0x80000000
+#define SCLK_CNTL__TV_MAX_DYN_STOP_LAT 0x00000020
+#define SCLK_CNTL__FORCE_TV_SCLK 0x20000000
+#define SCLK_CNTL__VAP_MAX_DYN_STOP_LAT 0x00000080
+#define SCLK_CNTL__SR_MAX_DYN_STOP_LAT 0x00000400
+#define SCLK_CNTL__PX_MAX_DYN_STOP_LAT 0x00000800
+#define SCLK_CNTL__TX_MAX_DYN_STOP_LAT 0x00001000
+#define SCLK_CNTL__US_MAX_DYN_STOP_LAT 0x00002000
+#define SCLK_CNTL__SU_MAX_DYN_STOP_LAT 0x00004000
+#define SCLK_CNTL__FORCE_VAP 0x00200000
+#define SCLK_CNTL__FORCE_SR 0x02000000
+#define SCLK_CNTL__FORCE_PX 0x04000000
+#define SCLK_CNTL__FORCE_TX 0x08000000
+#define SCLK_CNTL__FORCE_US 0x10000000
+#define SCLK_CNTL__FORCE_SU 0x40000000
+#define PPLL_CNTL 0x00000002
+#define PPLL_CNTL__PPLL_RESET 0x00000001
+#define PPLL_CNTL__PPLL_SLEEP 0x00000002
+#define PPLL_CNTL__PPLL_TST_EN 0x00000004
+#define PPLL_CNTL__PPLL_REFCLK_SEL 0x00000010
+#define PPLL_CNTL__PPLL_FBCLK_SEL 0x00000020
+#define PPLL_CNTL__PPLL_TCPOFF 0x00000040
+#define PPLL_CNTL__PPLL_TVCOMAX 0x00000080
+#define PPLL_CNTL__PPLL_PCP__MASK 0x00000700
+#define PPLL_CNTL__PPLL_PCP__SHIFT 8
+#define PPLL_CNTL__PPLL_PVG__MASK 0x00003800
+#define PPLL_CNTL__PPLL_PVG__SHIFT 11
+#define PPLL_CNTL__PPLL_PDC__MASK 0x0000C000
+#define PPLL_CNTL__PPLL_PDC__SHIFT 14
+#define PPLL_CNTL__PPLL_ATOMIC_UPDATE_EN 0x00010000
+#define PPLL_CNTL__PPLL_VGA_ATOMIC_UPDATE_EN 0x00020000
+#define PPLL_CNTL__PPLL_ATOMIC_UPDATE_SYNC 0x00040000
+#define PPLL_CNTL__PPLL_DISABLE_AUTO_RESET 0x00080000
+#define PPLL_CNTL__PPLL_DIV_RESET 0x00000008
+#define PPLL_REF_DIV 0x00000003
+#define PPLL_REF_DIV__PPLL_REF_DIV__MASK 0x000003FF
+#define PPLL_REF_DIV__PPLL_REF_DIV__SHIFT 0
+#define PPLL_REF_DIV__PPLL_ATOMIC_UPDATE_W 0x00008000
+#define PPLL_REF_DIV__PPLL_ATOMIC_UPDATE_R 0x00008000
+#define PPLL_REF_DIV__PPLL_REF_DIV_SRC__MASK 0x00030000
+#define PPLL_REF_DIV__PPLL_REF_DIV_SRC__SHIFT 16
+#define PPLL_REF_DIV_SRC__XTALIN 0x0
+#define PPLL_REF_DIV_SRC__PLLSCLK_2 0x1
+#define PPLL_REF_DIV_SRC__PLLSCLK_4 0x2
+#define PPLL_REF_DIV_SRC__SREFCLK 0x3
+#define PPLL_REF_DIV__PPLL_REF_DIV_ACC__MASK 0x0FFC0000
+#define PPLL_REF_DIV__PPLL_REF_DIV_ACC__SHIFT 18
+#define PPLL_DIV_0 0x00000004
+#define PPLL_DIV_0__PPLL_FB0_DIV__MASK 0x000007FF
+#define PPLL_DIV_0__PPLL_FB0_DIV__SHIFT 0
+#define PPLL_DIV_0__PPLL_ATOMIC_UPDATE_W 0x00008000
+#define PPLL_DIV_0__PPLL_ATOMIC_UPDATE_R 0x00008000
+#define PPLL_DIV_0__PPLL_POST0_DIV__MASK 0x00070000
+#define PPLL_DIV_0__PPLL_POST0_DIV__SHIFT 16
+#define PPLL_DIV_0__PPLL_FB_DIV_FRACTION__MASK 0x00380000
+#define PPLL_DIV_0__PPLL_FB_DIV_FRACTION__SHIFT 19
+#define PPLL_DIV_0__PPLL_FB_DIV_FRACTION_UPDATE 0x00400000
+#define PPLL_DIV_0__PPLL_FB_DIV_FRACTION_EN 0x00800000
+#define PPLL_DIV_1 0x00000005
+#define PPLL_DIV_1__PPLL_FB1_DIV__MASK 0x000007FF
+#define PPLL_DIV_1__PPLL_FB1_DIV__SHIFT 0
+#define PPLL_DIV_1__PPLL_ATOMIC_UPDATE_W 0x00008000
+#define PPLL_DIV_1__PPLL_ATOMIC_UPDATE_R 0x00008000
+#define PPLL_DIV_1__PPLL_POST1_DIV__MASK 0x00070000
+#define PPLL_DIV_1__PPLL_POST1_DIV__SHIFT 16
+#define PPLL_DIV_2 0x00000006
+#define PPLL_DIV_2__PPLL_FB2_DIV__MASK 0x000007FF
+#define PPLL_DIV_2__PPLL_FB2_DIV__SHIFT 0
+#define PPLL_DIV_2__PPLL_ATOMIC_UPDATE_W 0x00008000
+#define PPLL_DIV_2__PPLL_ATOMIC_UPDATE_R 0x00008000
+#define PPLL_DIV_2__PPLL_POST2_DIV__MASK 0x00070000
+#define PPLL_DIV_2__PPLL_POST2_DIV__SHIFT 16
+#define PPLL_DIV_3 0x00000007
+#define PPLL_DIV_3__PPLL_FB3_DIV__MASK 0x000007FF
+#define PPLL_DIV_3__PPLL_FB3_DIV__SHIFT 0
+#define PPLL_DIV_3__PPLL_ATOMIC_UPDATE_W 0x00008000
+#define PPLL_DIV_3__PPLL_ATOMIC_UPDATE_R 0x00008000
+#define PPLL_DIV_3__PPLL_POST3_DIV__MASK 0x00070000
+#define PPLL_DIV_3__PPLL_POST3_DIV__SHIFT 16
+#define VCLK_ECP_CNTL 0x00000008
+#define VCLK_ECP_CNTL__VCLK_SRC_SEL__MASK 0x00000003
+#define VCLK_ECP_CNTL__VCLK_SRC_SEL__SHIFT 0
+#define VCLK_SRC_SEL__CPUCLK 0x0
+#define VCLK_SRC_SEL__PSCANCLK 0x1
+#define VCLK_SRC_SEL__BYTE_CLK 0x2
+#define VCLK_SRC_SEL__PPLLCLK 0x3
+#define VCLK_ECP_CNTL__VCLK_INVERT 0x00000010
+#define VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb 0x00000040
+#define VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb 0x00000080
+#define VCLK_ECP_CNTL__ECP_DIV__MASK 0x00000300
+#define VCLK_ECP_CNTL__ECP_DIV__SHIFT 8
+#define VCLK_ECP_CNTL__ECP_FORCE_ON 0x00040000
+#define VCLK_ECP_CNTL__SUBCLK_FORCE_ON 0x00080000
+#define VCLK_ECP_CNTL__BYTE_CLK_POST_DIV__MASK 0x00030000
+#define VCLK_ECP_CNTL__BYTE_CLK_POST_DIV__SHIFT 16
+#define VCLK_ECP_CNTL__BYTE_CLK_OUT_EN 0x00100000
+#define VCLK_ECP_CNTL__BYTE_CLK_SKEW__MASK 0x07000000
+#define VCLK_ECP_CNTL__BYTE_CLK_SKEW__SHIFT 24
+#define VCLK_ECP_CNTL__PCICLK_INVERT 0x00000020
+#define VCLK_ECP_CNTL__PIXCLK_SRC_INVERT 0x00000020
+#define VCLK_ECP_CNTL__PIXCLK_SRC_INVERT_R3 0x08000000
+#define VCLK_ECP_CNTL__DISP_DAC_PIXCLK_DAC_BLANK_OFF 0x00800000
+#define HTOTAL_CNTL 0x00000009
+#define HTOTAL_CNTL__HTOT_PIX_SLIP__MASK 0x0000000F
+#define HTOTAL_CNTL__HTOT_PIX_SLIP__SHIFT 0
+#define HTOTAL_CNTL__HTOT_VCLK_SLIP__MASK 0x00000F00
+#define HTOTAL_CNTL__HTOT_VCLK_SLIP__SHIFT 8
+#define HTOTAL_CNTL__HTOT_PPLL_SLIP__MASK 0x00070000
+#define HTOTAL_CNTL__HTOT_PPLL_SLIP__SHIFT 16
+#define HTOTAL_CNTL__HTOT_CNTL_EDGE 0x01000000
+#define HTOTAL_CNTL__HTOT_CNTL_VGA_EN 0x10000000
+#define FP_H_SYNC_STRT_WID 0x000002C4
+#define FP_H_SYNC_STRT_WID__FP_H_SYNC_STRT_PIX__MASK 0x00000007
+#define FP_H_SYNC_STRT_WID__FP_H_SYNC_STRT_PIX__SHIFT 0
+#define FP_H_SYNC_STRT_WID__FP_H_SYNC_STRT_CHAR__MASK 0x00001FF8
+#define FP_H_SYNC_STRT_WID__FP_H_SYNC_STRT_CHAR__SHIFT 3
+#define FP_H_SYNC_STRT_WID__FP_H_SYNC_WID__MASK 0x003F0000
+#define FP_H_SYNC_STRT_WID__FP_H_SYNC_WID__SHIFT 16
+#define FP_H_SYNC_STRT_WID__FP_H_SYNC_POL 0x00800000
+#define FP_V_SYNC_STRT_WID 0x000002C8
+#define FP_V_SYNC_STRT_WID__FP_V_SYNC_STRT__MASK 0x00000FFF
+#define FP_V_SYNC_STRT_WID__FP_V_SYNC_STRT__SHIFT 0
+#define FP_V_SYNC_STRT_WID__FP_V_SYNC_WID__MASK 0x001F0000
+#define FP_V_SYNC_STRT_WID__FP_V_SYNC_WID__SHIFT 16
+#define FP_V_SYNC_STRT_WID__FP_V_SYNC_POL 0x00800000
+#define FP_CRTC_H_TOTAL_DISP 0x00000250
+#define FP_CRTC_H_TOTAL_DISP__FP_CRTC_H_TOTAL__MASK 0x000003FF
+#define FP_CRTC_H_TOTAL_DISP__FP_CRTC_H_TOTAL__SHIFT 0
+#define FP_CRTC_H_TOTAL_DISP__FP_CRTC_H_DISP__MASK 0x01FF0000
+#define FP_CRTC_H_TOTAL_DISP__FP_CRTC_H_DISP__SHIFT 16
+#define FP_CRTC_V_TOTAL_DISP 0x00000254
+#define FP_CRTC_V_TOTAL_DISP__FP_CRTC_V_TOTAL__MASK 0x00000FFF
+#define FP_CRTC_V_TOTAL_DISP__FP_CRTC_V_TOTAL__SHIFT 0
+#define FP_CRTC_V_TOTAL_DISP__FP_CRTC_V_DISP__MASK 0x0FFF0000
+#define FP_CRTC_V_TOTAL_DISP__FP_CRTC_V_DISP__SHIFT 16
+#define PALETTE_INDEX 0x000000B0
+#define PALETTE_INDEX__PALETTE_W_INDEX__MASK 0x000000FF
+#define PALETTE_INDEX__PALETTE_W_INDEX__SHIFT 0
+#define PALETTE_INDEX__PALETTE_R_INDEX__MASK 0x00FF0000
+#define PALETTE_INDEX__PALETTE_R_INDEX__SHIFT 16
+#define PALETTE_DATA 0x000000B4
+#define PALETTE_DATA__PALETTE_DATA_B__MASK 0x000000FF
+#define PALETTE_DATA__PALETTE_DATA_B__SHIFT 0
+#define PALETTE_DATA__PALETTE_DATA_G__MASK 0x0000FF00
+#define PALETTE_DATA__PALETTE_DATA_G__SHIFT 8
+#define PALETTE_DATA__PALETTE_DATA_R__MASK 0x00FF0000
+#define PALETTE_DATA__PALETTE_DATA_R__SHIFT 16
+#define PALETTE_30_DATA 0x000000B8
+#define PALETTE_30_DATA__PALETTE_DATA_B__MASK 0x000003FF
+#define PALETTE_30_DATA__PALETTE_DATA_B__SHIFT 0
+#define PALETTE_30_DATA__PALETTE_DATA_G__MASK 0x000FFC00
+#define PALETTE_30_DATA__PALETTE_DATA_G__SHIFT 10
+#define PALETTE_30_DATA__PALETTE_DATA_R__MASK 0x3FF00000
+#define PALETTE_30_DATA__PALETTE_DATA_R__SHIFT 20
+#define SURFACE_CNTL 0x00000B00
+#define SURFACE_CNTL__SURF_TRANSLATION_DIS 0x00000100
+#define SURFACE_CNTL__NONSURF_AP0_SWP__MASK 0x00300000
+#define SURFACE_CNTL__NONSURF_AP0_SWP__SHIFT 20
+#define SURFACE_CNTL__NONSURF_AP1_SWP__MASK 0x00C00000
+#define SURFACE_CNTL__NONSURF_AP1_SWP__SHIFT 22
+#define SURFACE0_INFO 0x00000B0C
+#define SURFACE0_INFO__SURF0_PITCHSEL__MASK 0x000003FF
+#define SURFACE0_INFO__SURF0_PITCHSEL__SHIFT 0
+#define SURFACE0_INFO__SURF0_TILE_MODE__MASK 0x00030000
+#define SURFACE0_INFO__SURF0_TILE_MODE__SHIFT 16
+#define SURF0_TILE_MODE__NO_TILING(p) 0x0
+#define SURF0_TILE_MODE__MACRO_TILING(p) 0x0
+#define SURF0_TILE_MODE__MICRO_TILING(p) 0x0
+#define SURF0_TILE_MODE__MACRO_MICRO_TILING(p) 0x0
+#define SURF0_TILE_MODE__32_BIT_Z_TILING(p) 0x0
+#define SURF0_TILE_MODE__16_BIT_Z_TILING(p) 0x0
+#define SURFACE0_INFO__SURF0_AP0_SWP__MASK 0x00300000
+#define SURFACE0_INFO__SURF0_AP0_SWP__SHIFT 20
+#define SURFACE0_INFO__SURF0_AP1_SWP__MASK 0x00C00000
+#define SURFACE0_INFO__SURF0_AP1_SWP__SHIFT 22
+#define SURFACE0_INFO__SURF0_WRITE_FLAG 0x01000000
+#define SURFACE0_INFO__SURF0_READ_FLAG 0x02000000
+#define SURFACE0_INFO__SURF0_TILE_MODE_R2__MASK 0x00070000
+#define SURFACE0_INFO__SURF0_TILE_MODE_R2__SHIFT 16
+#define SURFACE0_INFO__SURF0_PITCHSEL_R3__MASK 0x00001FFF
+#define SURFACE0_INFO__SURF0_PITCHSEL_R3__SHIFT 0
+#define SURFACE0_LOWER_BOUND 0x00000B04
+#define SURFACE0_LOWER_BOUND__SURF_LOWER__MASK 0x0FFFFFFF
+#define SURFACE0_LOWER_BOUND__SURF_LOWER__SHIFT 0
+#define SURFACE0_UPPER_BOUND 0x00000B08
+#define SURFACE0_UPPER_BOUND__SURF_UPPER__MASK 0x0FFFFFFF
+#define SURFACE0_UPPER_BOUND__SURF_UPPER__SHIFT 0
+#define SURFACE1_INFO 0x00000B1C
+#define SURFACE1_INFO__SURF1_PITCHSEL__MASK 0x000003FF
+#define SURFACE1_INFO__SURF1_PITCHSEL__SHIFT 0
+#define SURFACE1_INFO__SURF1_TILE_MODE__MASK 0x00030000
+#define SURFACE1_INFO__SURF1_TILE_MODE__SHIFT 16
+#define SURFACE1_INFO__SURF1_AP0_SWP__MASK 0x00300000
+#define SURFACE1_INFO__SURF1_AP0_SWP__SHIFT 20
+#define SURFACE1_INFO__SURF1_AP1_SWP__MASK 0x00C00000
+#define SURFACE1_INFO__SURF1_AP1_SWP__SHIFT 22
+#define SURFACE1_INFO__SURF1_WRITE_FLAG 0x01000000
+#define SURFACE1_INFO__SURF1_READ_FLAG 0x02000000
+#define SURFACE1_INFO__SURF1_TILE_MODE_R2__MASK 0x00070000
+#define SURFACE1_INFO__SURF1_TILE_MODE_R2__SHIFT 16
+#define SURFACE1_INFO__SURF1_PITCHSEL_R3__MASK 0x00001FFF
+#define SURFACE1_INFO__SURF1_PITCHSEL_R3__SHIFT 0
+#define SURFACE1_LOWER_BOUND 0x00000B14
+#define SURFACE1_LOWER_BOUND__SURF_LOWER__MASK 0x0FFFFFFF
+#define SURFACE1_LOWER_BOUND__SURF_LOWER__SHIFT 0
+#define SURFACE1_UPPER_BOUND 0x00000B18
+#define SURFACE1_UPPER_BOUND__SURF_UPPER__MASK 0x0FFFFFFF
+#define SURFACE1_UPPER_BOUND__SURF_UPPER__SHIFT 0
+#define SURFACE2_INFO 0x00000B2C
+#define SURFACE2_INFO__SURF2_PITCHSEL__MASK 0x000003FF
+#define SURFACE2_INFO__SURF2_PITCHSEL__SHIFT 0
+#define SURFACE2_INFO__SURF2_TILE_MODE__MASK 0x00030000
+#define SURFACE2_INFO__SURF2_TILE_MODE__SHIFT 16
+#define SURFACE2_INFO__SURF2_AP0_SWP__MASK 0x00300000
+#define SURFACE2_INFO__SURF2_AP0_SWP__SHIFT 20
+#define SURFACE2_INFO__SURF2_AP1_SWP__MASK 0x00C00000
+#define SURFACE2_INFO__SURF2_AP1_SWP__SHIFT 22
+#define SURFACE2_INFO__SURF2_WRITE_FLAG 0x01000000
+#define SURFACE2_INFO__SURF2_READ_FLAG 0x02000000
+#define SURFACE2_INFO__SURF2_TILE_MODE_R2__MASK 0x00070000
+#define SURFACE2_INFO__SURF2_TILE_MODE_R2__SHIFT 16
+#define SURFACE2_INFO__SURF2_PITCHSEL_R3__MASK 0x00001FFF
+#define SURFACE2_INFO__SURF2_PITCHSEL_R3__SHIFT 0
+#define SURFACE2_LOWER_BOUND 0x00000B24
+#define SURFACE2_LOWER_BOUND__SURF_LOWER__MASK 0x0FFFFFFF
+#define SURFACE2_LOWER_BOUND__SURF_LOWER__SHIFT 0
+#define SURFACE2_UPPER_BOUND 0x00000B28
+#define SURFACE2_UPPER_BOUND__SURF_UPPER__MASK 0x0FFFFFFF
+#define SURFACE2_UPPER_BOUND__SURF_UPPER__SHIFT 0
+#define SURFACE3_INFO 0x00000B3C
+#define SURFACE3_INFO__SURF3_PITCHSEL__MASK 0x000003FF
+#define SURFACE3_INFO__SURF3_PITCHSEL__SHIFT 0
+#define SURFACE3_INFO__SURF3_TILE_MODE__MASK 0x00030000
+#define SURFACE3_INFO__SURF3_TILE_MODE__SHIFT 16
+#define SURFACE3_INFO__SURF3_AP0_SWP__MASK 0x00300000
+#define SURFACE3_INFO__SURF3_AP0_SWP__SHIFT 20
+#define SURFACE3_INFO__SURF3_AP1_SWP__MASK 0x00C00000
+#define SURFACE3_INFO__SURF3_AP1_SWP__SHIFT 22
+#define SURFACE3_INFO__SURF3_WRITE_FLAG 0x01000000
+#define SURFACE3_INFO__SURF3_READ_FLAG 0x02000000
+#define SURFACE3_INFO__SURF3_TILE_MODE_R2__MASK 0x00070000
+#define SURFACE3_INFO__SURF3_TILE_MODE_R2__SHIFT 16
+#define SURFACE3_INFO__SURF3_PITCHSEL_R3__MASK 0x00001FFF
+#define SURFACE3_INFO__SURF3_PITCHSEL_R3__SHIFT 0
+#define SURFACE3_LOWER_BOUND 0x00000B34
+#define SURFACE3_LOWER_BOUND__SURF_LOWER__MASK 0x0FFFFFFF
+#define SURFACE3_LOWER_BOUND__SURF_LOWER__SHIFT 0
+#define SURFACE3_UPPER_BOUND 0x00000B38
+#define SURFACE3_UPPER_BOUND__SURF_UPPER__MASK 0x0FFFFFFF
+#define SURFACE3_UPPER_BOUND__SURF_UPPER__SHIFT 0
+#define SURFACE4_INFO 0x00000B4C
+#define SURFACE4_INFO__SURF4_PITCHSEL__MASK 0x000003FF
+#define SURFACE4_INFO__SURF4_PITCHSEL__SHIFT 0
+#define SURFACE4_INFO__SURF4_TILE_MODE__MASK 0x00030000
+#define SURFACE4_INFO__SURF4_TILE_MODE__SHIFT 16
+#define SURFACE4_INFO__SURF4_AP0_SWP__MASK 0x00300000
+#define SURFACE4_INFO__SURF4_AP0_SWP__SHIFT 20
+#define SURFACE4_INFO__SURF4_AP1_SWP__MASK 0x00C00000
+#define SURFACE4_INFO__SURF4_AP1_SWP__SHIFT 22
+#define SURFACE4_INFO__SURF4_WRITE_FLAG 0x01000000
+#define SURFACE4_INFO__SURF4_READ_FLAG 0x02000000
+#define SURFACE4_INFO__SURF4_TILE_MODE_R2__MASK 0x00070000
+#define SURFACE4_INFO__SURF4_TILE_MODE_R2__SHIFT 16
+#define SURFACE4_INFO__SURF4_PITCHSEL_R3__MASK 0x00001FFF
+#define SURFACE4_INFO__SURF4_PITCHSEL_R3__SHIFT 0
+#define SURFACE4_LOWER_BOUND 0x00000B44
+#define SURFACE4_LOWER_BOUND__SURF_LOWER__MASK 0x0FFFFFFF
+#define SURFACE4_LOWER_BOUND__SURF_LOWER__SHIFT 0
+#define SURFACE4_UPPER_BOUND 0x00000B48
+#define SURFACE4_UPPER_BOUND__SURF_UPPER__MASK 0x0FFFFFFF
+#define SURFACE4_UPPER_BOUND__SURF_UPPER__SHIFT 0
+#define SURFACE5_INFO 0x00000B5C
+#define SURFACE5_INFO__SURF5_PITCHSEL__MASK 0x000003FF
+#define SURFACE5_INFO__SURF5_PITCHSEL__SHIFT 0
+#define SURFACE5_INFO__SURF5_TILE_MODE__MASK 0x00030000
+#define SURFACE5_INFO__SURF5_TILE_MODE__SHIFT 16
+#define SURFACE5_INFO__SURF5_AP0_SWP__MASK 0x00300000
+#define SURFACE5_INFO__SURF5_AP0_SWP__SHIFT 20
+#define SURFACE5_INFO__SURF5_AP1_SWP__MASK 0x00C00000
+#define SURFACE5_INFO__SURF5_AP1_SWP__SHIFT 22
+#define SURFACE5_INFO__SURF5_WRITE_FLAG 0x01000000
+#define SURFACE5_INFO__SURF5_READ_FLAG 0x02000000
+#define SURFACE5_INFO__SURF5_TILE_MODE_R2__MASK 0x00070000
+#define SURFACE5_INFO__SURF5_TILE_MODE_R2__SHIFT 16
+#define SURFACE5_INFO__SURF5_PITCHSEL_R3__MASK 0x00001FFF
+#define SURFACE5_INFO__SURF5_PITCHSEL_R3__SHIFT 0
+#define SURFACE5_LOWER_BOUND 0x00000B54
+#define SURFACE5_LOWER_BOUND__SURF_LOWER__MASK 0x0FFFFFFF
+#define SURFACE5_LOWER_BOUND__SURF_LOWER__SHIFT 0
+#define SURFACE5_UPPER_BOUND 0x00000B58
+#define SURFACE5_UPPER_BOUND__SURF_UPPER__MASK 0x0FFFFFFF
+#define SURFACE5_UPPER_BOUND__SURF_UPPER__SHIFT 0
+#define SURFACE6_INFO 0x00000B6C
+#define SURFACE6_INFO__SURF6_PITCHSEL__MASK 0x000003FF
+#define SURFACE6_INFO__SURF6_PITCHSEL__SHIFT 0
+#define SURFACE6_INFO__SURF6_TILE_MODE__MASK 0x00030000
+#define SURFACE6_INFO__SURF6_TILE_MODE__SHIFT 16
+#define SURFACE6_INFO__SURF6_AP0_SWP__MASK 0x00300000
+#define SURFACE6_INFO__SURF6_AP0_SWP__SHIFT 20
+#define SURFACE6_INFO__SURF6_AP1_SWP__MASK 0x00C00000
+#define SURFACE6_INFO__SURF6_AP1_SWP__SHIFT 22
+#define SURFACE6_INFO__SURF6_WRITE_FLAG 0x01000000
+#define SURFACE6_INFO__SURF6_READ_FLAG 0x02000000
+#define SURFACE6_INFO__SURF6_TILE_MODE_R2__MASK 0x00070000
+#define SURFACE6_INFO__SURF6_TILE_MODE_R2__SHIFT 16
+#define SURFACE6_INFO__SURF6_PITCHSEL_R3__MASK 0x00001FFF
+#define SURFACE6_INFO__SURF6_PITCHSEL_R3__SHIFT 0
+#define SURFACE6_LOWER_BOUND 0x00000B64
+#define SURFACE6_LOWER_BOUND__SURF_LOWER__MASK 0x0FFFFFFF
+#define SURFACE6_LOWER_BOUND__SURF_LOWER__SHIFT 0
+#define SURFACE6_UPPER_BOUND 0x00000B68
+#define SURFACE6_UPPER_BOUND__SURF_UPPER__MASK 0x0FFFFFFF
+#define SURFACE6_UPPER_BOUND__SURF_UPPER__SHIFT 0
+#define SURFACE7_INFO 0x00000B7C
+#define SURFACE7_INFO__SURF7_PITCHSEL__MASK 0x000003FF
+#define SURFACE7_INFO__SURF7_PITCHSEL__SHIFT 0
+#define SURFACE7_INFO__SURF7_TILE_MODE__MASK 0x00030000
+#define SURFACE7_INFO__SURF7_TILE_MODE__SHIFT 16
+#define SURFACE7_INFO__SURF7_AP0_SWP__MASK 0x00300000
+#define SURFACE7_INFO__SURF7_AP0_SWP__SHIFT 20
+#define SURFACE7_INFO__SURF7_AP1_SWP__MASK 0x00C00000
+#define SURFACE7_INFO__SURF7_AP1_SWP__SHIFT 22
+#define SURFACE7_INFO__SURF7_WRITE_FLAG 0x01000000
+#define SURFACE7_INFO__SURF7_READ_FLAG 0x02000000
+#define SURFACE7_INFO__SURF7_TILE_MODE_R2__MASK 0x00070000
+#define SURFACE7_INFO__SURF7_TILE_MODE_R2__SHIFT 16
+#define SURFACE7_INFO__SURF7_PITCHSEL_R3__MASK 0x00001FFF
+#define SURFACE7_INFO__SURF7_PITCHSEL_R3__SHIFT 0
+#define SURFACE7_LOWER_BOUND 0x00000B74
+#define SURFACE7_LOWER_BOUND__SURF_LOWER__MASK 0x0FFFFFFF
+#define SURFACE7_LOWER_BOUND__SURF_LOWER__SHIFT 0
+#define SURFACE7_UPPER_BOUND 0x00000B78
+#define SURFACE7_UPPER_BOUND__SURF_UPPER__MASK 0x0FFFFFFF
+#define SURFACE7_UPPER_BOUND__SURF_UPPER__SHIFT 0
+#define ISYNC_CNTL 0x00001724
+#define ISYNC_CNTL__ISYNC_ANY2D_IDLE3D 0x00000001
+#define ISYNC_CNTL__ISYNC_ANY3D_IDLE2D 0x00000002
+#define ISYNC_CNTL__ISYNC_TRIG2D_IDLE3D 0x00000004
+#define ISYNC_CNTL__ISYNC_TRIG3D_IDLE2D 0x00000008
+#define ISYNC_CNTL__ISYNC_WAIT_IDLEGUI 0x00000010
+#define ISYNC_CNTL__ISYNC_CPSCRATCH_IDLEGUI 0x00000020
+#define RBBM_STATUS 0x00000E40
+#define RBBM_STATUS__CMDFIFO_AVAIL__MASK 0x0000007F
+#define RBBM_STATUS__CMDFIFO_AVAIL__SHIFT 0
+#define RBBM_STATUS__HIRQ_ON_RBB 0x00000100
+#define RBBM_STATUS__CPRQ_ON_RBB 0x00000200
+#define RBBM_STATUS__CFRQ_ON_RBB 0x00000400
+#define RBBM_STATUS__HIRQ_IN_RTBUF 0x00000800
+#define RBBM_STATUS__CPRQ_IN_RTBUF 0x00001000
+#define RBBM_STATUS__CFRQ_IN_RTBUF 0x00002000
+#define RBBM_STATUS__CF_PIPE_BUSY 0x00004000
+#define RBBM_STATUS__ENG_EV_BUSY 0x00008000
+#define RBBM_STATUS__CP_CMDSTRM_BUSY 0x00010000
+#define RBBM_STATUS__E2_BUSY 0x00020000
+#define RBBM_STATUS__RB2D_BUSY 0x00040000
+#define RBBM_STATUS__RB3D_BUSY 0x00080000
+#define RBBM_STATUS__SE_BUSY 0x00100000
+#define RBBM_STATUS__RE_BUSY 0x00200000
+#define RBBM_STATUS__TAM_BUSY 0x00400000
+#define RBBM_STATUS__TDM_BUSY 0x00800000
+#define RBBM_STATUS__PB_BUSY 0x01000000
+#define RBBM_STATUS__GUI_ACTIVE 0x80000000
+#define RBBM_STATUS__VAP_BUSY 0x00100000
+#define RBBM_STATUS__TIM_BUSY 0x02000000
+#define RBBM_STATUS__GA_BUSY 0x04000000
+#define RBBM_STATUS__CBA2D_BUSY 0x08000000
+#define RBBM_SOFT_RESET 0x000000F0
+#define RBBM_SOFT_RESET__SOFT_RESET_CP 0x00000001
+#define RBBM_SOFT_RESET__SOFT_RESET_HI 0x00000002
+#define RBBM_SOFT_RESET__SOFT_RESET_SE 0x00000004
+#define RBBM_SOFT_RESET__SOFT_RESET_RE 0x00000008
+#define RBBM_SOFT_RESET__SOFT_RESET_PP 0x00000010
+#define RBBM_SOFT_RESET__SOFT_RESET_E2 0x00000020
+#define RBBM_SOFT_RESET__SOFT_RESET_RB 0x00000040
+#define RBBM_SOFT_RESET__SOFT_RESET_HDP 0x00000080
+#define RBBM_SOFT_RESET__SOFT_RESET_MC 0x00000100
+#define RBBM_SOFT_RESET__SOFT_RESET_AIC 0x00000200
+#define RBBM_SOFT_RESET__SOFT_RESET_VIP 0x00000400
+#define RBBM_SOFT_RESET__SOFT_RESET_DISP 0x00000800
+#define RBBM_SOFT_RESET__SOFT_RESET_CG 0x00001000
+#define RBBM_SOFT_RESET__SOFT_RESET_VAP 0x00000004
+#define RBBM_SOFT_RESET__SOFT_RESET_GA 0x00002000
+#define RBBM_SOFT_RESET__SOFT_RESET_IDCT 0x00004000
+#define WAIT_UNTIL 0x00001720
+#define WAIT_UNTIL__WAIT_CRTC_PFLIP 0x00000001
+#define WAIT_UNTIL__WAIT_RE_CRTC_VLINE 0x00000002
+#define WAIT_UNTIL__WAIT_FE_CRTC_VLINE 0x00000004
+#define WAIT_UNTIL__WAIT_CRTC_VLINE 0x00000008
+#define WAIT_UNTIL__WAIT_DMA_VIPH0_IDLE 0x00000010
+#define WAIT_UNTIL__WAIT_DMA_VIPH1_IDLE 0x00000020
+#define WAIT_UNTIL__WAIT_DMA_VIPH2_IDLE 0x00000040
+#define WAIT_UNTIL__WAIT_DMA_VIPH3_IDLE 0x00000080
+#define WAIT_UNTIL__WAIT_DMA_VID_IDLE 0x00000100
+#define WAIT_UNTIL__WAIT_DMA_GUI_IDLE 0x00000200
+#define WAIT_UNTIL__WAIT_CMDFIFO 0x00000400
+#define WAIT_UNTIL__WAIT_OV0_FLIP 0x00000800
+#define WAIT_UNTIL__WAIT_OV0_SLICEDONE 0x00001000
+#define WAIT_UNTIL__WAIT_2D_IDLE 0x00004000
+#define WAIT_UNTIL__WAIT_3D_IDLE 0x00008000
+#define WAIT_UNTIL__WAIT_2D_IDLECLEAN 0x00010000
+#define WAIT_UNTIL__WAIT_3D_IDLECLEAN 0x00020000
+#define WAIT_UNTIL__WAIT_HOST_IDLECLEAN 0x00040000
+#define WAIT_UNTIL__WAIT_EXTERN_SIG 0x00080000
+#define WAIT_UNTIL__CMDFIFO_ENTRIES__MASK 0x07F00000
+#define WAIT_UNTIL__CMDFIFO_ENTRIES__SHIFT 20
+#define WAIT_UNTIL__WAIT_BOTH_CRTC_PFLIP 0x40000000
+#define WAIT_UNTIL__ENG_DISPLAY_SELECT 0x80000000
+#define WAIT_UNTIL__WAIT_AGP_FLUSH 0x00002000
+#define WAIT_UNTIL__WAIT_IDCT_SEMAPHORE 0x08000000
+#define WAIT_UNTIL__WAIT_VAP_IDLE 0x10000000
+#define DISPLAY_BASE_ADDR 0x0000023C
+#define DISPLAY_BASE_ADDR__DISPLAY_BASE_ADDR__MASK 0xFFFFFFFF
+#define DISPLAY_BASE_ADDR__DISPLAY_BASE_ADDR__SHIFT 0
+#define CRTC2_DISPLAY_BASE_ADDR 0x0000033C
+#define CRTC2_DISPLAY_BASE_ADDR__CRTC2_DISPLAY_BASE_ADDR__MASK 0xFFFFFFFF
+#define CRTC2_DISPLAY_BASE_ADDR__CRTC2_DISPLAY_BASE_ADDR__SHIFT 0
+#define AIC_CTRL 0x000001D0
+#define AIC_CTRL__TRANSLATE_EN 0x00000001
+#define AIC_CTRL__HW_0_DEBUG 0x00000002
+#define AIC_CTRL__HW_1_DEBUG 0x00000004
+#define AIC_CTRL__HW_2_DEBUG 0x00000008
+#define AIC_CTRL__HW_3_DEBUG 0x00000010
+#define AIC_CTRL__HW_4_DEBUG 0x00000020
+#define AIC_CTRL__HW_5_DEBUG 0x00000040
+#define AIC_CTRL__HW_6_DEBUG 0x00000080
+#define AIC_CTRL__HW_7_DEBUG 0x00000100
+#define AIC_CTRL__HW_8_DEBUG 0x00000200
+#define AIC_CTRL__HW_9_DEBUG 0x00000400
+#define AIC_CTRL__HW_A_DEBUG 0x00000800
+#define AIC_CTRL__HW_B_DEBUG 0x00001000
+#define AIC_CTRL__HW_C_DEBUG 0x00002000
+#define AIC_CTRL__HW_D_DEBUG 0x00004000
+#define AIC_CTRL__HW_E_DEBUG 0x00008000
+#define AIC_CTRL__HW_F_DEBUG 0x00010000
+#define AIC_CTRL__HW_10_DEBUG 0x00020000
+#define AIC_CTRL__HW_11_DEBUG 0x00040000
+#define AIC_CTRL__HW_12_DEBUG 0x00080000
+#define AIC_CTRL__HW_13_DEBUG 0x00100000
+#define AIC_CTRL__HW_14_DEBUG 0x00200000
+#define AIC_CTRL__HW_15_DEBUG 0x00400000
+#define AIC_CTRL__HW_16_DEBUG 0x00800000
+#define AIC_CTRL__HW_17_DEBUG 0x01000000
+#define AIC_CTRL__HW_18_DEBUG 0x02000000
+#define AIC_CTRL__HW_19_DEBUG 0x04000000
+#define AIC_CTRL__HW_1A_DEBUG 0x08000000
+#define AIC_CTRL__HW_1B_DEBUG 0x10000000
+#define AIC_CTRL__HW_1C_DEBUG 0x20000000
+#define AIC_CTRL__HW_1D_DEBUG 0x40000000
+#define AIC_CTRL__HW_1E_DEBUG 0x80000000
+#define AIC_CTRL__DIS_OUT_OF_PCI_GART_ACCESS 0x00000002
+#define AIC_CTRL__HW_02_DEBUG 0x00000004
+#define AIC_CTRL__HW_03_DEBUG 0x00000008
+#define AIC_CTRL__TEST_RBF_DIV_VAL__MASK 0x00000070
+#define AIC_CTRL__TEST_RBF_DIV_VAL__SHIFT 4
+#define AIC_CTRL__TEST_RBF_EN 0x00000080
+#define AIC_CTRL__HW_08_DEBUG 0x00000100
+#define AIC_CTRL__HW_09_DEBUG 0x00000200
+#define AIC_CTRL__HW_10_DEBUG_R3 0x00000400
+#define AIC_CTRL__HW_11_DEBUG_R3 0x00000800
+#define AIC_CTRL__HW_12_DEBUG_R3 0x00001000
+#define AIC_CTRL__HW_13_DEBUG_R3 0x00002000
+#define AIC_CTRL__HW_14_DEBUG_R3 0x00004000
+#define AIC_CTRL__HW_15_DEBUG_R3 0x00008000
+#define AIC_CTRL__HW_16_DEBUG_R3 0x00010000
+#define AIC_CTRL__HW_17_DEBUG_R3 0x00020000
+#define AIC_CTRL__HW_18_DEBUG_R3 0x00040000
+#define AIC_CTRL__HW_19_DEBUG_R3 0x00080000
+#define AIC_CTRL__HW_20_DEBUG 0x00100000
+#define AIC_CTRL__HW_21_DEBUG 0x00200000
+#define AIC_CTRL__HW_22_DEBUG 0x00400000
+#define AIC_CTRL__HW_23_DEBUG 0x00800000
+#define AIC_CTRL__HW_24_DEBUG 0x01000000
+#define AIC_CTRL__HW_25_DEBUG 0x02000000
+#define AIC_CTRL__HW_26_DEBUG 0x04000000
+#define AIC_CTRL__HW_27_DEBUG 0x08000000
+#define AIC_CTRL__HW_28_DEBUG 0x10000000
+#define AIC_CTRL__HW_29_DEBUG 0x20000000
+#define AIC_CTRL__HW_30_DEBUG 0x40000000
+#define AIC_CTRL__HW_31_DEBUG 0x80000000
+#define BUS_CNTL 0x00000030
+#define BUS_CNTL__BUS_DBL_RESYNC 0x00000001
+#define BUS_CNTL__BUS_MSTR_RESET 0x00000002
+#define BUS_CNTL__BUS_FLUSH_BUF 0x00000004
+#define BUS_CNTL__BUS_STOP_REQ_DIS 0x00000008
+#define BUS_CNTL__BUS_READ_COMBINE_EN 0x00000010
+#define BUS_CNTL__BUS_WRT_COMBINE_EN 0x00000020
+#define BUS_CNTL__BUS_MASTER_DIS 0x00000040
+#define BUS_CNTL__BIOS_ROM_WRT_EN 0x00000080
+#define BUS_CNTL__BUS_PREFETCH_MODE__MASK 0x00000300
+#define BUS_CNTL__BUS_PREFETCH_MODE__SHIFT 8
+#define BUS_CNTL__BUS_VGA_PREFETCH_EN 0x00000400
+#define BUS_CNTL__BUS_SGL_READ_DISABLE 0x00000800
+#define BUS_CNTL__BIOS_DIS_ROM 0x00001000
+#define BUS_CNTL__BUS_PCI_READ_RETRY_EN 0x00002000
+#define BUS_CNTL__BUS_AGP_AD_STEPPING_EN 0x00004000
+#define BUS_CNTL__BUS_PCI_WRT_RETRY_EN 0x00008000
+#define BUS_CNTL__BUS_RETRY_WS__MASK 0x000F0000
+#define BUS_CNTL__BUS_RETRY_WS__SHIFT 16
+#define BUS_CNTL__BUS_MSTR_RD_MULT 0x00100000
+#define BUS_CNTL__BUS_MSTR_RD_LINE 0x00200000
+#define BUS_CNTL__BUS_SUSPEND 0x00400000
+#define BUS_CNTL__LAT_16X 0x00800000
+#define BUS_CNTL__BUS_RD_DISCARD_EN 0x01000000
+#define BUS_CNTL__ENFRCWRDY 0x02000000
+#define BUS_CNTL__BUS_MSTR_WS 0x04000000
+#define BUS_CNTL__BUS_PARKING_DIS 0x08000000
+#define BUS_CNTL__BUS_MSTR_DISCONNECT_EN 0x10000000
+#define BUS_CNTL__SERR_EN 0x20000000
+#define BUS_CNTL__BUS_READ_BURST 0x40000000
+#define BUS_CNTL__BUS_RDY_READ_DLY 0x80000000
+#define BUS_CNTL__BUS_PM4_READ_COMBINE_EN 0x00000010
+#define BUS_CNTL__BM_DAC_CRIPPLE 0x00000100
+#define BUS_CNTL__BUS_NON_PM4_READ_COMBINE_EN 0x00000200
+#define BUS_CNTL__BUS_XFERD_DISCARD_EN 0x00000400
+#define MC_STATUS 0x00000150
+#define MC_STATUS__MEM_PWRUP_COMPL_A 0x00000001
+#define MC_STATUS__MEM_PWRUP_COMPL_B 0x00000002
+#define MC_STATUS__MC_IDLE 0x00000004
+#define MC_STATUS__SPARE__MASK 0x0000FFF8
+#define MC_STATUS__SPARE__SHIFT 3
+#define MC_STATUS__IMP_N_VALUE_R_BACK__MASK 0x00000078
+#define MC_STATUS__IMP_N_VALUE_R_BACK__SHIFT 3
+#define MC_STATUS__IMP_P_VALUE_R_BACK__MASK 0x00000780
+#define MC_STATUS__IMP_P_VALUE_R_BACK__SHIFT 7
+#define MC_STATUS__TEST_OUT_R_BACK 0x00000800
+#define MC_STATUS__DUMMY_OUT_R_BACK 0x00001000
+#define MC_STATUS__IMP_N_VALUE_A_R_BACK__MASK 0x0001E000
+#define MC_STATUS__IMP_N_VALUE_A_R_BACK__SHIFT 13
+#define MC_STATUS__IMP_P_VALUE_A_R_BACK__MASK 0x001E0000
+#define MC_STATUS__IMP_P_VALUE_A_R_BACK__SHIFT 17
+#define MC_STATUS__IMP_N_VALUE_CK_R_BACK__MASK 0x01E00000
+#define MC_STATUS__IMP_N_VALUE_CK_R_BACK__SHIFT 21
+#define MC_STATUS__IMP_P_VALUE_CK_R_BACK__MASK 0x1E000000
+#define MC_STATUS__IMP_P_VALUE_CK_R_BACK__SHIFT 25
+#define MC_STATUS__MEM_PWRUP_COMPL_C 0x00000004
+#define MC_STATUS__MEM_PWRUP_COMPL_D 0x00000008
+#define MC_STATUS__MC_IDLE_R3 0x00000010
+#define MC_STATUS__IMP_CAL_COUNT__MASK 0x0000F000
+#define MC_STATUS__IMP_CAL_COUNT__SHIFT 12
+#define OV0_SCALE_CNTL 0x00000420
+#define OV0_SCALE_CNTL__OV0_NO_READ_BEHIND_SCAN 0x00000002
+#define OV0_SCALE_CNTL__OV0_HORZ_PICK_NEAREST 0x00000004
+#define OV0_SCALE_CNTL__OV0_VERT_PICK_NEAREST 0x00000008
+#define OV0_SCALE_CNTL__OV0_SIGNED_UV 0x00000010
+#define OV0_SCALE_CNTL__OV0_GAMMA_SEL__MASK 0x000000E0
+#define OV0_SCALE_CNTL__OV0_GAMMA_SEL__SHIFT 5
+#define OV0_SCALE_CNTL__OV0_SURFACE_FORMAT__MASK 0x00000F00
+#define OV0_SCALE_CNTL__OV0_SURFACE_FORMAT__SHIFT 8
+#define OV0_SURFACE_FORMAT__RESERVED0 0x0
+#define OV0_SURFACE_FORMAT__RESERVED1 0x100
+#define OV0_SURFACE_FORMAT__RESERVED2 0x200
+#define OV0_SURFACE_FORMAT__16BPP_ARGB 0x300
+#define OV0_SURFACE_FORMAT__16BPP_RGB 0x400
+#define OV0_SURFACE_FORMAT__RESERVED5 0x500
+#define OV0_SURFACE_FORMAT__32BPP_ARGB 0x600
+#define OV0_SURFACE_FORMAT__RESERVED7 0x700
+#define OV0_SURFACE_FORMAT__RESERVED8 0x800
+#define OV0_SURFACE_FORMAT__IF09_PLANAR 0x900
+#define OV0_SURFACE_FORMAT__YV12_PLANAR 0xA00
+#define OV0_SURFACE_FORMAT__YUY2_PACKED 0xB00
+#define OV0_SURFACE_FORMAT__UYVY_PACKED 0xC00
+#define OV0_SURFACE_FORMAT__YYUV9_PLANAR 0xD00
+#define OV0_SURFACE_FORMAT__YYUV12_PLANAR 0xE00
+#define OV0_SURFACE_FORMAT__RESERVED15 0xF00
+#define OV0_SCALE_CNTL__OV0_ADAPTIVE_DEINT 0x00001000
+#define OV0_SCALE_CNTL__OV0_CRTC_SEL 0x00004000
+#define OV0_SCALE_CNTL__OV0_BURST_PER_PLANE__MASK 0x007F0000
+#define OV0_SCALE_CNTL__OV0_BURST_PER_PLANE__SHIFT 16
+#define OV0_SCALE_CNTL__OV0_DOUBLE_BUFFER_REGS 0x01000000
+#define OV0_SCALE_CNTL__OV0_BANDWIDTH 0x04000000
+#define OV0_SCALE_CNTL__OV0_LIN_TRANS_BYPASS 0x10000000
+#define OV0_SCALE_CNTL__OV0_INT_EMU 0x20000000
+#define OV0_SCALE_CNTL__OV0_OVERLAY_EN__MASK 0x40000000
+#define OV0_SCALE_CNTL__OV0_OVERLAY_EN__SHIFT 30
+#define OV0_OVERLAY_EN__ENABLE 0x40000000
+#define OV0_SCALE_CNTL__OV0_SOFT_RESET__MASK 0x80000000
+#define OV0_SCALE_CNTL__OV0_SOFT_RESET__SHIFT 31
+#define OV0_SOFT_RESET__RESET 0x80000000
+#define OV0_SCALE_CNTL__OV0_TEMPORAL_DEINT 0x00002000
+#define OV0_SCALE_CNTL__OV0_PULLDOWN_ON_P1_ONLY 0x00008000
+#define OV0_SCALE_CNTL__OV0_FULL_BYPASS 0x00000020
+#define OV0_SCALE_CNTL__OV0_DYNAMIC_EXT 0x00000040
+#define OV0_SCALE_CNTL__OV0_RGB30_ON 0x00000080
+#define CRTC2_GEN_CNTL 0x000003F8
+#define CRTC2_GEN_CNTL__CRTC2_DBL_SCAN_EN 0x00000001
+#define CRTC2_GEN_CNTL__CRTC2_INTERLACE_EN 0x00000002
+#define CRTC2_GEN_CNTL__CRTC2_SYNC_TRISTATE 0x00000010
+#define CRTC2_GEN_CNTL__CRTC2_HSYNC_TRISTATE 0x00000020
+#define CRTC2_GEN_CNTL__CRTC2_VSYNC_TRISTATE 0x00000040
+#define CRTC2_GEN_CNTL__CRT2_ON 0x00000080
+#define CRTC2_GEN_CNTL__CRTC2_PIX_WIDTH__MASK 0x00000F00
+#define CRTC2_GEN_CNTL__CRTC2_PIX_WIDTH__SHIFT 8
+#define CRTC2_GEN_CNTL__CRTC2_ICON_EN 0x00008000
+#define CRTC2_GEN_CNTL__CRTC2_CUR_EN 0x00010000
+#define CRTC2_GEN_CNTL__CRTC2_CUR_MODE__MASK 0x00700000
+#define CRTC2_GEN_CNTL__CRTC2_CUR_MODE__SHIFT 20
+#define CRTC2_GEN_CNTL__CRTC2_DISPLAY_DIS 0x00800000
+#define CRTC2_GEN_CNTL__CRTC2_EN 0x02000000
+#define CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B 0x04000000
+#define CRTC2_GEN_CNTL__CRTC2_C_SYNC_EN 0x08000000
+#define CRTC2_GEN_CNTL__CRTC2_HSYNC_DIS 0x10000000
+#define CRTC2_GEN_CNTL__CRTC2_VSYNC_DIS 0x20000000
+#define CRTC2_GEN_CNTL__CRTC2_MODE9_COLOR_ORDER 0x00001000
+#define CRTC2_GEN_CNTL__CRTC2_FIX_VSYNC_EDGE_POSITION_EN 0x40000000
+#define CRTC2_OFFSET 0x00000324
+#define CRTC2_OFFSET__CRTC2_OFFSET__MASK 0x07FFFFFF
+#define CRTC2_OFFSET__CRTC2_OFFSET__SHIFT 0
+#define CRTC2_OFFSET__CRTC2_GUI_TRIG_OFFSET 0x40000000
+#define CRTC2_OFFSET__CRTC2_OFFSET_LOCK 0x80000000
+#define CRTC2_OFFSET__CRTC2_OFFSET_R3__MASK 0x0FFFFFFF
+#define CRTC2_OFFSET__CRTC2_OFFSET_R3__SHIFT 0
+#define CRTC2_OFFSET_CNTL 0x00000328
+#define CRTC2_OFFSET_CNTL__CRTC2_TILE_LINE__MASK 0x0000000F
+#define CRTC2_OFFSET_CNTL__CRTC2_TILE_LINE__SHIFT 0
+#define CRTC2_OFFSET_CNTL__CRTC2_TILE_EN 0x00008000
+#define CRTC2_OFFSET_CNTL__CRTC2_OFFSET_FLIP_CNTL 0x00010000
+#define CRTC2_OFFSET_CNTL__CRTC2_GUI_TRIG_OFFSET_LEFT_EN 0x10000000
+#define CRTC2_OFFSET_CNTL__CRTC2_GUI_TRIG_OFFSET 0x40000000
+#define CRTC2_OFFSET_CNTL__CRTC2_OFFSET_LOCK 0x80000000
+#define CRTC2_OFFSET_CNTL__CRTC2_TILE_LINE_RIGHT__MASK 0x000000F0
+#define CRTC2_OFFSET_CNTL__CRTC2_TILE_LINE_RIGHT__SHIFT 4
+#define CRTC2_OFFSET_CNTL__CRTC2_TILE_EN_RIGHT 0x00004000
+#define CRTC2_OFFSET_CNTL__CRTC2_STEREO_OFFSET_EN 0x00020000
+#define CRTC2_OFFSET_CNTL__CRTC2_STEREO_SYNC_EN__MASK 0x000C0000
+#define CRTC2_OFFSET_CNTL__CRTC2_STEREO_SYNC_EN__SHIFT 18
+#define CRTC2_OFFSET_CNTL__CRTC2_STEREO_SYNC 0x00200000
+#define CRTC2_OFFSET_CNTL__CRTC2_GUI_TRIG_OFFSET_RIGHT_EN 0x20000000
+#define CRTC2_OFFSET_CNTL__CRTC2_X_Y_MODE_EN_RIGHT 0x00000100
+#define CRTC2_OFFSET_CNTL__CRTC2_X_Y_MODE_EN 0x00000200
+#define CRTC2_OFFSET_CNTL__CRTC2_MICRO_TILE_EN_RIGHT 0x00001000
+#define CRTC2_OFFSET_CNTL__CRTC2_MICRO_TILE_EN 0x00002000
+#define CRTC2_OFFSET_CNTL__CRTC2_MACRO_TILE_EN_RIGHT 0x00004000
+#define CRTC2_OFFSET_CNTL__CRTC2_MACRO_TILE_EN 0x00008000
+#define CUR_OFFSET 0x00000260
+#define CUR_OFFSET__CUR_OFFSET__MASK 0x07FFFFFF
+#define CUR_OFFSET__CUR_OFFSET__SHIFT 0
+#define CUR_OFFSET__CUR_LOCK 0x80000000
+#define CUR2_OFFSET 0x00000360
+#define CUR2_OFFSET__CUR2_OFFSET__MASK 0x07FFFFFF
+#define CUR2_OFFSET__CUR2_OFFSET__SHIFT 0
+#define CUR2_OFFSET__CUR2_LOCK 0x80000000
+#define HOST_PATH_CNTL 0x00000130
+#define HOST_PATH_CNTL__HDP_APER_CNTL 0x00800000
+#define HOST_PATH_CNTL__HP_LIN_RD_CACHE_DIS 0x01000000
+#define HOST_PATH_CNTL__HP_RBBM_LOCK_DIS 0x02000000
+#define HOST_PATH_CNTL__HDP_SOFT_RESET 0x04000000
+#define HOST_PATH_CNTL__HDP_WRITE_COMBINER_TIMEOUT__MASK 0x70000000
+#define HOST_PATH_CNTL__HDP_WRITE_COMBINER_TIMEOUT__SHIFT 28
+#define HOST_PATH_CNTL__HP_TEST_RST_CNTL 0x80000000
+#define HOST_PATH_CNTL__HDP_WRITE_THROUGH_CACHE_DIS 0x00400000
+#define HOST_PATH_CNTL__HDP_READ_BUFFER_INVALIDATE 0x08000000
+#define DST_PITCH_OFFSET 0x0000142C
+#define DST_PITCH_OFFSET__DST_OFFSET__MASK 0x003FFFFF
+#define DST_PITCH_OFFSET__DST_OFFSET__SHIFT 0
+#define DST_PITCH_OFFSET__DST_PITCH__MASK 0x3FC00000
+#define DST_PITCH_OFFSET__DST_PITCH__SHIFT 22
+#define DST_PITCH_OFFSET__DST_TILE__MASK 0xC0000000
+#define DST_PITCH_OFFSET__DST_TILE__SHIFT 30
+#define DST_TILE__MACRO 0x1
+#define DST_TILE__MICRO 0x2
+#define SRC_PITCH_OFFSET 0x00001428
+#define SRC_PITCH_OFFSET__SRC_OFFSET__MASK 0x003FFFFF
+#define SRC_PITCH_OFFSET__SRC_OFFSET__SHIFT 0
+#define SRC_PITCH_OFFSET__SRC_PITCH__MASK 0x3FC00000
+#define SRC_PITCH_OFFSET__SRC_PITCH__SHIFT 22
+#define SRC_PITCH_OFFSET__SRC_TILE 0x40000000
+#define DEFAULT_SC_BOTTOM_RIGHT 0x000016E8
+#define DEFAULT_SC_BOTTOM_RIGHT__DEFAULT_SC_RIGHT__MASK 0x00003FFF
+#define DEFAULT_SC_BOTTOM_RIGHT__DEFAULT_SC_RIGHT__SHIFT 0
+#define DEFAULT_SC_BOTTOM_RIGHT__DEFAULT_SC_BOTTOM__MASK 0x3FFF0000
+#define DEFAULT_SC_BOTTOM_RIGHT__DEFAULT_SC_BOTTOM__SHIFT 16
+#define DEFAULT2_SC_BOTTOM_RIGHT 0x000016DC
+#define DEFAULT2_SC_BOTTOM_RIGHT__DEFAULT_SC_RIGHT__MASK 0x00003FFF
+#define DEFAULT2_SC_BOTTOM_RIGHT__DEFAULT_SC_RIGHT__SHIFT 0
+#define DEFAULT2_SC_BOTTOM_RIGHT__DEFAULT_SC_BOTTOM__MASK 0x3FFF0000
+#define DEFAULT2_SC_BOTTOM_RIGHT__DEFAULT_SC_BOTTOM__SHIFT 16
+#define DP_DATATYPE 0x000016C4
+#define DP_DATATYPE__DP_DST_DATATYPE__MASK 0x0000000F
+#define DP_DATATYPE__DP_DST_DATATYPE__SHIFT 0
+#define DP_DATATYPE__DP_BRUSH_DATATYPE__MASK 0x00000F00
+#define DP_DATATYPE__DP_BRUSH_DATATYPE__SHIFT 8
+#define DP_DATATYPE__DP_SRC_DATATYPE__MASK 0x00070000
+#define DP_DATATYPE__DP_SRC_DATATYPE__SHIFT 16
+#define DP_DATATYPE__DP_BYTE_PIX_ORDER 0x40000000
+#define DP_GUI_MASTER_CNTL 0x0000146C
+#define DP_GUI_MASTER_CNTL__GMC_SRC_PITCH_OFFSET_CNTL 0x00000001
+#define DP_GUI_MASTER_CNTL__GMC_DST_PITCH_OFFSET_CNTL 0x00000002
+#define DP_GUI_MASTER_CNTL__GMC_SRC_CLIPPING 0x00000004
+#define DP_GUI_MASTER_CNTL__GMC_DST_CLIPPING 0x00000008
+#define DP_GUI_MASTER_CNTL__GMC_BRUSH_DATATYPE__MASK 0x000000F0
+#define DP_GUI_MASTER_CNTL__GMC_BRUSH_DATATYPE__SHIFT 4
+#define GMC_BRUSH_DATATYPE__8X8_MONO_FG_BG 0x0
+#define GMC_BRUSH_DATATYPE__8X8_MONO_FG 0x1
+#define GMC_BRUSH_DATATYPE__32X1_MONO_LINE_FG_BG 0x6
+#define GMC_BRUSH_DATATYPE__32X1_MONO_LINE_FG 0x7
+#define GMC_BRUSH_DATATYPE__8X8_COLOR 0xA
+#define GMC_BRUSH_DATATYPE__SOLID_COLOR_FG 0xD
+#define GMC_BRUSH_DATATYPE__SOLID_COLOR_RESERVED 0xF
+#define GMC_BRUSH_DATATYPE__SOLID 0xD0
+#define GMC_BRUSH_DATATYPE__MONO8x8 0x0
+#define GMC_BRUSH_DATATYPE__COLOR8x8 0xA0
+#define DP_GUI_MASTER_CNTL__GMC_DST_DATATYPE__MASK 0x00000F00
+#define DP_GUI_MASTER_CNTL__GMC_DST_DATATYPE__SHIFT 8
+#define GMC_DST_DATATYPE__8BPP_CLUT 0x2
+#define GMC_DST_DATATYPE__16BPP_1555 0x3
+#define GMC_DST_DATATYPE__16BPP_565 0x4
+#define GMC_DST_DATATYPE__32BPP_8888 0x6
+#define GMC_DST_DATATYPE__CI8 0x200
+#define GMC_DST_DATATYPE__RGB16_1555 0x300
+#define GMC_DST_DATATYPE__RGB16_565 0x400
+#define GMC_DST_DATATYPE__RGB32 0x600
+#define DP_GUI_MASTER_CNTL__GMC_SRC_DATATYPE__MASK 0x00003000
+#define DP_GUI_MASTER_CNTL__GMC_SRC_DATATYPE__SHIFT 12
+#define GMC_SRC_DATATYPE__BUILD(x) 0x0
+#define GMC_SRC_DATATYPE__MONO_OPAQUE 0x0
+#define GMC_SRC_DATATYPE__MONO_TRANSPARENT 0x0
+#define GMC_SRC_DATATYPE__SAME_AS_DST 0x0
+#define GMC_SRC_DATATYPE__8BPP_CLUT_XLAT 0x0
+#define GMC_SRC_DATATYPE__32BPP_CLUT_XLAT 0x0
+#define GMC_SRC_DATATYPE__MONO_FG_BG 0x0
+#define GMC_SRC_DATATYPE__MONO_FG 0x1000
+#define GMC_SRC_DATATYPE__COLOR 0x3000
+#define GMC_SRC_DATATYPE__DST 0x3000
+#define DP_GUI_MASTER_CNTL__GMC_BYTE_PIX_ORDER 0x00004000
+#define DP_GUI_MASTER_CNTL__GMC_DEFAULT_SEL 0x00008000
+#define DP_GUI_MASTER_CNTL__GMC_ROP3__MASK 0x00FF0000
+#define DP_GUI_MASTER_CNTL__GMC_ROP3__SHIFT 16
+#define GMC_ROP3__SRCCPY 0xCC
+#define GMC_ROP3__WHITENESS 0xFF
+#define GMC_ROP3__BLACKNESS 0x0
+#define DP_GUI_MASTER_CNTL__GMC_DP_SRC_SOURCE__MASK 0x07000000
+#define DP_GUI_MASTER_CNTL__GMC_DP_SRC_SOURCE__SHIFT 24
+#define GMC_DP_SRC_SOURCE__VIDEO_MEM 0x2
+#define GMC_DP_SRC_SOURCE__HOSTDATA 0x3
+#define GMC_DP_SRC_SOURCE__HOSTDATA_BYTE 0x4
+#define DP_GUI_MASTER_CNTL__GMC_SRC_DATATYPE2 0x08000000
+#define DP_GUI_MASTER_CNTL__GMC_CLR_CMP_FCN_DIS 0x10000000
+#define DP_GUI_MASTER_CNTL__GMC_WR_MSK_DIS 0x40000000
+#define DP_BRUSH_FRGD_CLR 0x0000147C
+#define DP_BRUSH_FRGD_CLR__DP_BRUSH_FRGD_CLR__MASK 0xFFFFFFFF
+#define DP_BRUSH_FRGD_CLR__DP_BRUSH_FRGD_CLR__SHIFT 0
+#define DP_BRUSH_BKGD_CLR 0x00001478
+#define DP_BRUSH_BKGD_CLR__DP_BRUSH_BKGD_CLR__MASK 0xFFFFFFFF
+#define DP_BRUSH_BKGD_CLR__DP_BRUSH_BKGD_CLR__SHIFT 0
+#define DP_SRC_FRGD_CLR 0x000015D8
+#define DP_SRC_FRGD_CLR__DP_SRC_FRGD_CLR__MASK 0xFFFFFFFF
+#define DP_SRC_FRGD_CLR__DP_SRC_FRGD_CLR__SHIFT 0
+#define DP_SRC_BKGD_CLR 0x000015DC
+#define DP_SRC_BKGD_CLR__DP_SRC_BKGD_CLR__MASK 0xFFFFFFFF
+#define DP_SRC_BKGD_CLR__DP_SRC_BKGD_CLR__SHIFT 0
+#define DP_WRITE_MSK 0x000016CC
+#define DP_WRITE_MSK__DP_WRITE_MSK__MASK 0xFFFFFFFF
+#define DP_WRITE_MSK__DP_WRITE_MSK__SHIFT 0
+
+#endif
diff --git a/shared-core/radeon_ms_rom.c b/shared-core/radeon_ms_rom.c
new file mode 100644
index 00000000..5054a390
--- /dev/null
+++ b/shared-core/radeon_ms_rom.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ */
+/*
+ * Authors:
+ * Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "radeon_ms.h"
+
+int radeon_ms_rom_get_properties(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ switch (dev_priv->rom.type) {
+ case ROM_COMBIOS:
+ return radeon_ms_combios_get_properties(dev);
+ }
+ return 0;
+}
+
+int radeon_ms_rom_init(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_ms_rom *rom = &dev_priv->rom;
+ void *rom_mapped;
+ char atomstr[5] = {0, 0, 0, 0, 0};
+ uint16_t *offset;
+
+ dev_priv->rom.type = ROM_UNKNOWN;
+ /* copy rom if any */
+ rom_mapped = pci_map_rom_copy(dev->pdev, &rom->rom_size);
+ if (rom->rom_size) {
+ rom->rom_image = drm_alloc(rom->rom_size, DRM_MEM_DRIVER);
+ if (rom->rom_image == NULL) {
+ return -1;
+ }
+ memcpy(rom->rom_image, rom_mapped, rom->rom_size);
+ DRM_INFO("[radeon_ms] ROM %d bytes copied\n", rom->rom_size);
+ } else {
+ DRM_INFO("[radeon_ms] no ROM\n");
+ return 0;
+ }
+ pci_unmap_rom(dev->pdev, rom_mapped);
+
+ if (rom->rom_image[0] != 0x55 || rom->rom_image[1] != 0xaa) {
+ DRM_INFO("[radeon_ms] no ROM\n");
+ DRM_INFO("[radeon_ms] ROM signature 0x55 0xaa missing\n");
+ return 0;
+ }
+ offset = (uint16_t *)&rom->rom_image[ROM_HEADER];
+ memcpy(atomstr, &rom->rom_image[*offset + 4], 4);
+ if (!strcpy(atomstr, "ATOM") || !strcpy(atomstr, "MOTA")) {
+ DRM_INFO("[radeon_ms] ATOMBIOS ROM detected\n");
+ return 0;
+ } else {
+ struct combios_header **header;
+
+ header = &rom->rom.combios_header;
+ if ((*offset + sizeof(struct combios_header)) > rom->rom_size) {
+ DRM_INFO("[radeon_ms] wrong COMBIOS header offset\n");
+ return -1;
+ }
+ dev_priv->rom.type = ROM_COMBIOS;
+ *header = (struct combios_header *)&rom->rom_image[*offset];
+ DRM_INFO("[radeon_ms] COMBIOS type : %d\n",
+ (*header)->ucTypeDefinition);
+ DRM_INFO("[radeon_ms] COMBIOS OEM ID: %02x %02x\n",
+ (*header)->ucOemID1, (*header)->ucOemID2);
+ }
+ return 0;
+}
diff --git a/shared-core/radeon_ms_rom.h b/shared-core/radeon_ms_rom.h
new file mode 100644
index 00000000..36a54cbb
--- /dev/null
+++ b/shared-core/radeon_ms_rom.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ */
+/*
+ * Authors:
+ * Jerome Glisse <glisse@freedesktop.org>
+ */
+#ifndef __RADEON_MS_ROM_H__
+#define __RADEON_MS_ROM_H__
+
+#include "radeon_ms_combios.h"
+
+enum radeon_rom_type {
+ ROM_COMBIOS,
+ ROM_ATOMBIOS,
+ ROM_UNKNOWN
+};
+
+union radeon_ms_rom_type {
+ struct combios_header *combios_header;
+};
+
+struct radeon_ms_rom {
+ uint8_t type;
+ size_t rom_size;
+ uint8_t *rom_image;
+ union radeon_ms_rom_type rom;
+};
+
+#endif
+
diff --git a/shared-core/radeon_ms_state.c b/shared-core/radeon_ms_state.c
new file mode 100644
index 00000000..17f8b764
--- /dev/null
+++ b/shared-core/radeon_ms_state.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * Authors:
+ * Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_ms.h"
+
+void radeon_ms_state_restore(struct drm_device *dev, struct radeon_state *state)
+{
+ radeon_ms_irq_restore(dev, state);
+ radeon_ms_gpu_restore(dev, state);
+ radeon_ms_cp_restore(dev, state);
+ radeon_ms_crtc1_restore(dev, state);
+}
+
+void radeon_ms_state_save(struct drm_device *dev, struct radeon_state *state)
+{
+ radeon_ms_crtc1_save(dev, state);
+ radeon_ms_cp_save(dev, state);
+ radeon_ms_gpu_save(dev, state);
+ radeon_ms_irq_save(dev, state);
+}
diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c
index 6f2e05b3..289fddc7 100644
--- a/shared-core/radeon_state.c
+++ b/shared-core/radeon_state.c
@@ -3057,7 +3057,7 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
*/
case RADEON_PARAM_SAREA_HANDLE:
/* The lock is the first dword in the sarea. */
- value = (long)dev->lock.hw_lock;
+ value = (long)dev->primary->master->lock.hw_lock;
break;
#endif
case RADEON_PARAM_GART_TEX_HANDLE: