From be5bf1346e49d5c2e0080913fd55e6898a8744cf Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 1 Apr 2007 16:48:38 +1000 Subject: copy over some files and reorg radeon to add ttm fencing not working yet --- shared-core/radeon_drm.h | 9 +++++++++ shared-core/radeon_drv.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- shared-core/radeon_irq.c | 20 +++++++++++--------- 3 files changed, 66 insertions(+), 11 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index e96e7851..bdf45802 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 3e56af30..9f6cff89 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -102,6 +102,11 @@ #define DRIVER_MINOR 26 #define DRIVER_PATCHLEVEL 0 +#if defined(__linux__) +#define RADEON_HAVE_FENCE +#define RADEON_HAVE_BUFFER +#endif + /* * Radeon chip families */ @@ -276,8 +281,8 @@ 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; struct radeon_surface surfaces[RADEON_MAX_SURFACES]; struct radeon_virt_surface virt_surfaces[2*RADEON_MAX_SURFACES]; @@ -376,6 +381,30 @@ extern int r300_do_cp_cmdbuf(drm_device_t *dev, DRMFILE filp, drm_file_t* filp_priv, drm_radeon_kcmd_buffer_t* cmdbuf); + +#ifdef RADEON_HAVE_FENCE +/* i915_fence.c */ + + +extern void radeon_fence_handler(drm_device_t *dev); +extern int radeon_fence_emit_sequence(drm_device_t *dev, uint32_t class, + uint32_t flags, uint32_t *sequence, + uint32_t *native_type); +extern void radeon_poke_flush(drm_device_t *dev, uint32_t class); +extern int radeon_fence_has_irq(drm_device_t *dev, uint32_t class, uint32_t flags); +#endif + +#ifdef RADEON_HAVE_BUFFER +/* radeon_buffer.c */ +extern drm_ttm_backend_t *radeon_create_ttm_backend_entry(drm_device_t *dev); +extern int radeon_fence_types(struct drm_buffer_object *bo, uint32_t *class, uint32_t *type); +extern int radeon_invalidate_caches(drm_device_t *dev, uint32_t buffer_flags); +extern uint32_t radeon_evict_mask(drm_buffer_object_t *bo); +extern int radeon_init_mem_type(drm_device_t * dev, uint32_t type, + drm_mem_type_manager_t * man); +extern int radeon_move(drm_buffer_object_t * bo, + int evict, int no_wait, drm_bo_mem_reg_t * new_mem); +#endif /* Flags for stats.boxes */ #define RADEON_BOX_DMA_IDLE 0x1 @@ -1184,4 +1213,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(drm_device_t *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 3ff0baa2..8678f5d1 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -79,7 +79,10 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) /* SW interrupt */ if (stat & RADEON_SW_INT_TEST) { - DRM_WAKEUP(&dev_priv->swi_queue); + DRM_WAKEUP(&dev_priv->irq_queue); +#ifdef RADEON_HAVE_FENCE + radeon_fence_handler(dev); +#endif } /* VBLANK interrupt */ @@ -98,8 +101,7 @@ static int radeon_emit_irq(drm_device_t * dev) 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); @@ -110,19 +112,19 @@ static int radeon_emit_irq(drm_device_t * dev) return ret; } -static int radeon_wait_irq(drm_device_t * dev, int swi_nr) +static int radeon_wait_irq(drm_device_t * dev, int irq_nr) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; int ret = 0; - if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr) + if (READ_BREADCRUMB(dev_priv) >= irq_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) >= irq_nr); return ret; } @@ -224,8 +226,8 @@ void radeon_driver_irq_postinstall(drm_device_t * dev) drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; - atomic_set(&dev_priv->swi_emitted, 0); - DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); + dev_priv->counter = 0; + DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); /* Turn on SW and VBL ints */ RADEON_WRITE(RADEON_GEN_INT_CNTL, -- cgit v1.2.3 From b1f0b2d960a8f488332652677073ab95ce72cd3f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 1 Apr 2007 18:24:23 +1000 Subject: radeon: de-static irq function, fixup fence/buffer --- shared-core/radeon_drv.h | 1 + shared-core/radeon_irq.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 9f6cff89..6d2bcc8f 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -355,6 +355,7 @@ extern void radeon_mem_release(DRMFILE filp, struct mem_block *heap); /* radeon_irq.c */ extern int radeon_irq_emit(DRM_IOCTL_ARGS); extern int radeon_irq_wait(DRM_IOCTL_ARGS); +extern int radeon_emit_irq(drm_device_t * dev); extern void radeon_do_release(drm_device_t * dev); extern int radeon_driver_vblank_wait(drm_device_t * dev, diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c index 8678f5d1..4f3099dc 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -95,7 +95,7 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) return IRQ_HANDLED; } -static int radeon_emit_irq(drm_device_t * dev) +int radeon_emit_irq(drm_device_t * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; unsigned int ret; -- cgit v1.2.3 From bdc5a8b62ef2f59e05f69da2150212c0243f6efb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 1 Apr 2007 19:09:00 +1000 Subject: radeon: enable buffer manager --- shared-core/radeon_cp.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index e02796e7..93c75d10 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2244,6 +2244,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; } -- cgit v1.2.3 From 52f9028c84baea81230dc673b756552e8e90aecd Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 5 Apr 2007 11:21:06 +1000 Subject: Initial import of modesetting for intel driver in DRM --- shared-core/i915_dma.c | 135 ++++++++------ shared-core/i915_drv.h | 474 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 557 insertions(+), 52 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index aed3eea1..a5f1473a 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -31,13 +31,6 @@ #include "i915_drm.h" #include "i915_drv.h" -#define IS_I965G(dev) (dev->pci_device == 0x2972 || \ - dev->pci_device == 0x2982 || \ - dev->pci_device == 0x2992 || \ - dev->pci_device == 0x29A2 || \ - dev->pci_device == 0x2A02) - - /* Really want an OS-independent resettable timer. Would like to have * this loop run for (eg) 3 sec, but have the timer reset every time * the head pointer changes, so that EBUSY only happens if the ring @@ -87,6 +80,7 @@ void i915_kernel_lost_context(drm_device_t * dev) static int i915_dma_cleanup(drm_device_t * dev) { + drm_i915_private_t *dev_priv = (drm_i915_private_t *) 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. @@ -94,25 +88,16 @@ static int i915_dma_cleanup(drm_device_t * dev) if (dev->irq) drm_irq_uninstall(dev); - if (dev->dev_private) { - drm_i915_private_t *dev_priv = - (drm_i915_private_t *) dev->dev_private; - - if (dev_priv->ring.virtual_start) { - drm_core_ioremapfree(&dev_priv->ring.map, dev); - } - - if (dev_priv->status_page_dmah) { - drm_pci_free(dev, dev_priv->status_page_dmah); - /* Need to rewrite hardware status page */ - I915_WRITE(0x02080, 0x1ffff000); - } - - drm_free(dev->dev_private, sizeof(drm_i915_private_t), - DRM_MEM_DRIVER); - - dev->dev_private = 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(0x02080, 0x1ffff000); } + + dev_priv->sarea_priv = NULL; return 0; } @@ -121,8 +106,6 @@ static int i915_initialize(drm_device_t * dev, drm_i915_private_t * dev_priv, drm_i915_init_t * init) { - memset(dev_priv, 0, sizeof(drm_i915_private_t)); - DRM_GETSAREA(); if (!dev_priv->sarea) { DRM_ERROR("can not find sarea!\n"); @@ -131,14 +114,6 @@ static int i915_initialize(drm_device_t * dev, return DRM_ERR(EINVAL); } - dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); - if (!dev_priv->mmio_map) { - dev->dev_private = (void *)dev_priv; - i915_dma_cleanup(dev); - DRM_ERROR("can not find mmio map!\n"); - return DRM_ERR(EINVAL); - } - dev_priv->sarea_priv = (drm_i915_sarea_t *) ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); @@ -195,7 +170,11 @@ static int i915_initialize(drm_device_t * dev, I915_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); - dev->dev_private = (void *)dev_priv; + + /* this probably doesn't belong here - TODO */ + drm_framebuffer_set_object(dev, dev_priv->sarea_priv->front_handle); + drm_set_desired_modes(dev); + return 0; } @@ -237,7 +216,7 @@ static int i915_dma_resume(drm_device_t * dev) static int i915_dma_init(DRM_IOCTL_ARGS) { DRM_DEVICE; - drm_i915_private_t *dev_priv; + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_init_t init; int retcode = 0; @@ -246,10 +225,6 @@ static int i915_dma_init(DRM_IOCTL_ARGS) switch (init.func) { case I915_INIT_DMA: - dev_priv = drm_alloc(sizeof(drm_i915_private_t), - DRM_MEM_DRIVER); - if (dev_priv == NULL) - return DRM_ERR(ENOMEM); retcode = i915_initialize(dev, dev_priv, &init); break; case I915_CLEANUP_DMA: @@ -882,6 +857,18 @@ static int i915_mmio(DRM_IOCTL_ARGS) int i915_driver_load(drm_device_t *dev, unsigned long flags) { + drm_i915_private_t *dev_priv; + int ret; + unsigned long mmiobase, mmiolen; + + dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); + if (dev_priv == NULL) + return DRM_ERR(ENOMEM); + + memset(dev_priv, 0, sizeof(drm_i915_private_t)); + dev->dev_private = (void *)dev_priv; +// dev_priv->flags = flags; + /* i915 has 4 more counters */ dev->counters += 4; dev->types[6] = _DRM_STAT_IRQ; @@ -889,25 +876,55 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) dev->types[8] = _DRM_STAT_SECONDARY; dev->types[9] = _DRM_STAT_DMA; + if (IS_I9XX(dev)) { + dev_priv->mmiobase = drm_get_resource_start(dev, 0); + dev_priv->mmiolen = drm_get_resource_len(dev, 0); + } 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); + } else { + DRM_ERROR("Unable to find MMIO registers\n"); + return -ENODEV; + } + + ret = drm_addmap(dev, dev_priv->mmiobase, dev_priv->mmiolen, + _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio_map); + if (ret != 0) { + DRM_ERROR("Cannot add mapping for MMIO registers\n"); + return ret; + } + + DRM_DEBUG("dev_priv->mmio map is %08X\n", dev_priv->mmio_map); + intel_modeset_init(dev); + return 0; +} + +int i915_driver_unload(drm_device_t *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + + intel_modeset_cleanup(dev); + drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); + + dev->dev_private = NULL; return 0; } void i915_driver_lastclose(drm_device_t * dev) { - if (dev->dev_private) { - drm_i915_private_t *dev_priv = dev->dev_private; - i915_do_cleanup_pageflip(dev); - i915_mem_takedown(&(dev_priv->agp_heap)); - } + drm_i915_private_t *dev_priv = dev->dev_private; + + i915_mem_takedown(&(dev_priv->agp_heap)); + i915_dma_cleanup(dev); + + dev_priv->mmio_map = NULL; } void i915_driver_preclose(drm_device_t * dev, DRMFILE filp) { - if (dev->dev_private) { - drm_i915_private_t *dev_priv = dev->dev_private; - i915_mem_release(dev, filp, dev_priv->agp_heap); - } + drm_i915_private_t *dev_priv = dev->dev_private; + i915_mem_release(dev, filp, dev_priv->agp_heap); } drm_ioctl_desc_t i915_ioctls[] = { @@ -950,8 +967,22 @@ int i915_driver_device_is_agp(drm_device_t * dev) int i915_driver_firstopen(struct drm_device *dev) { -#ifdef I915_HAVE_BUFFER + drm_i915_private_t *dev_priv = dev->dev_private; + int ret; + DRM_DEBUG("\n"); drm_bo_driver_init(dev); -#endif + + if (!dev_priv->mmio_map) { + ret = drm_addmap(dev, dev_priv->mmiobase, dev_priv->mmiolen, + _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio_map); + if (ret != 0) { + DRM_ERROR("Cannot add mapping for MMIO registers\n"); + return ret; + } + } + + DRM_DEBUG("dev_priv->mmio map is %08X\n", dev_priv->mmio_map); + return 0; } + diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index e8a7be29..f37f5873 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -92,6 +92,9 @@ typedef struct drm_i915_private { drm_local_map_t *sarea; drm_local_map_t *mmio_map; + unsigned long mmiobase; + unsigned long mmiolen; + drm_i915_sarea_t *sarea_priv; drm_i915_ring_buffer_t ring; @@ -145,6 +148,8 @@ extern int i915_max_ioctl; /* i915_dma.c */ extern void i915_kernel_lost_context(drm_device_t * dev); extern int i915_driver_load(struct drm_device *, unsigned long flags); +extern int i915_driver_unload(drm_device_t *dev); +extern int i915_driver_firstopen(struct drm_device *dev); extern void i915_driver_lastclose(drm_device_t * dev); extern void i915_driver_preclose(drm_device_t * dev, DRMFILE filp); extern int i915_driver_device_is_agp(drm_device_t * dev); @@ -206,6 +211,12 @@ extern int i915_move(drm_buffer_object_t *bo, int evict, #endif + +/* modesetting */ +extern void intel_modeset_init(drm_device_t *dev); +extern void intel_modeset_cleanup(drm_device_t *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)) @@ -273,6 +284,30 @@ extern int i915_wait_ring(drm_device_t * 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) + + #define SRX_INDEX 0x3c4 #define SRX_DATA 0x3c5 #define SR01 1 @@ -281,6 +316,8 @@ extern int i915_wait_ring(drm_device_t * 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 @@ -363,4 +400,441 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5]) #define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) + +#define BLC_PWM_CTL 0x61254 +#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) +/** + * This is the most significant 15 bits of the number of backlight cycles in a + * complete cycle of the modulated backlight control. + * + * The actual value is this field multiplied by two. + */ +#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) +#define BLM_LEGACY_MODE (1 << 16) +/** + * This is the number of cycles out of the backlight modulation cycle for which + * the backlight is on. + * + * This field must be no greater than the number of cycles in the complete + * backlight modulation cycle. + */ +#define BACKLIGHT_DUTY_CYCLE_SHIFT (0) +#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) + +#define I915_GCFGC 0xf0 +#define I915_LOW_FREQUENCY_ENABLE (1 << 7) +#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4) +#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4) +#define I915_DISPLAY_CLOCK_MASK (7 << 4) + +#define I855_HPLLCC 0xc0 +#define I855_CLOCK_CONTROL_MASK (3 << 0) +#define I855_CLOCK_133_200 (0 << 0) +#define I855_CLOCK_100_200 (1 << 0) +#define I855_CLOCK_100_133 (2 << 0) +#define I855_CLOCK_166_250 (3 << 0) + +/* I830 CRTC registers */ +#define HTOTAL_A 0x60000 +#define HBLANK_A 0x60004 +#define HSYNC_A 0x60008 +#define VTOTAL_A 0x6000c +#define VBLANK_A 0x60010 +#define VSYNC_A 0x60014 +#define PIPEASRC 0x6001c +#define BCLRPAT_A 0x60020 +#define VSYNCSHIFT_A 0x60028 + +#define HTOTAL_B 0x61000 +#define HBLANK_B 0x61004 +#define HSYNC_B 0x61008 +#define VTOTAL_B 0x6100c +#define VBLANK_B 0x61010 +#define VSYNC_B 0x61014 +#define PIPEBSRC 0x6101c +#define BCLRPAT_B 0x61020 +#define VSYNCSHIFT_B 0x61028 + +#define PP_STATUS 0x61200 +# define PP_ON (1 << 31) +/** + * Indicates that all dependencies of the panel are on: + * + * - PLL enabled + * - pipe enabled + * - LVDS/DVOB/DVOC on + */ +# define PP_READY (1 << 30) +# define PP_SEQUENCE_NONE (0 << 28) +# define PP_SEQUENCE_ON (1 << 28) +# define PP_SEQUENCE_OFF (2 << 28) +# define PP_SEQUENCE_MASK 0x30000000 +#define PP_CONTROL 0x61204 +# define POWER_TARGET_ON (1 << 0) + +#define LVDSPP_ON 0x61208 +#define LVDSPP_OFF 0x6120c +#define PP_CYCLE 0x61210 + +#define PFIT_CONTROL 0x61230 +# define PFIT_ENABLE (1 << 31) +# define VERT_INTERP_DISABLE (0 << 10) +# define VERT_INTERP_BILINEAR (1 << 10) +# define VERT_INTERP_MASK (3 << 10) +# define VERT_AUTO_SCALE (1 << 9) +# define HORIZ_INTERP_DISABLE (0 << 6) +# define HORIZ_INTERP_BILINEAR (1 << 6) +# define HORIZ_INTERP_MASK (3 << 6) +# define HORIZ_AUTO_SCALE (1 << 5) +# define PANEL_8TO6_DITHER_ENABLE (1 << 3) + +#define PFIT_PGM_RATIOS 0x61234 +# define PFIT_VERT_SCALE_MASK 0xfff00000 +# define PFIT_HORIZ_SCALE_MASK 0x0000fff0 + +#define PFIT_AUTO_RATIOS 0x61238 + + +#define DPLL_A 0x06014 +#define DPLL_B 0x06018 +# define DPLL_VCO_ENABLE (1 << 31) +# define DPLL_DVO_HIGH_SPEED (1 << 30) +# define DPLL_SYNCLOCK_ENABLE (1 << 29) +# define DPLL_VGA_MODE_DIS (1 << 28) +# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */ +# define DPLLB_MODE_LVDS (2 << 26) /* i915 */ +# define DPLL_MODE_MASK (3 << 26) +# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */ +# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */ +# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ +# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ +# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ +# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ +/** + * The i830 generation, in DAC/serial mode, defines p1 as two plus this + * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set. + */ +# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 +/** + * The i830 generation, in LVDS mode, defines P1 as the bit number set within + * this field (only one bit may be set). + */ +# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 +# define DPLL_FPA01_P1_POST_DIV_SHIFT 16 +# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */ +# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ +# define PLL_REF_INPUT_DREFCLK (0 << 13) +# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ +# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */ +# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) +# define PLL_REF_INPUT_MASK (3 << 13) +# define PLL_LOAD_PULSE_PHASE_SHIFT 9 +/* + * Parallel to Serial Load Pulse phase selection. + * Selects the phase for the 10X DPLL clock for the PCIe + * digital display port. The range is 4 to 13; 10 or more + * is just a flip delay. The default is 6 + */ +# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) +# define DISPLAY_RATE_SELECT_FPA1 (1 << 8) + +/** + * SDVO multiplier for 945G/GM. Not used on 965. + * + * \sa DPLL_MD_UDI_MULTIPLIER_MASK + */ +# define SDVO_MULTIPLIER_MASK 0x000000ff +# define SDVO_MULTIPLIER_SHIFT_HIRES 4 +# define SDVO_MULTIPLIER_SHIFT_VGA 0 + +/** @defgroup DPLL_MD + * @{ + */ +/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */ +#define DPLL_A_MD 0x0601c +/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */ +#define DPLL_B_MD 0x06020 +/** + * UDI pixel divider, controlling how many pixels are stuffed into a packet. + * + * Value is pixels minus 1. Must be set to 1 pixel for SDVO. + */ +# define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 +# define DPLL_MD_UDI_DIVIDER_SHIFT 24 +/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ +# define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 +# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 +/** + * SDVO/UDI pixel multiplier. + * + * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus + * clock rate is 10 times the DPLL clock. At low resolution/refresh rate + * modes, the bus rate would be below the limits, so SDVO allows for stuffing + * dummy bytes in the datastream at an increased clock rate, with both sides of + * the link knowing how many bytes are fill. + * + * So, for a mode with a dotclock of 65Mhz, we would want to double the clock + * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be + * set to 130Mhz, and the SDVO multiplier set to 2x in this register and + * through an SDVO command. + * + * This register field has values of multiplication factor minus 1, with + * a maximum multiplier of 5 for SDVO. + */ +# define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 +# define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 +/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. + * This best be set to the default value (3) or the CRT won't work. No, + * I don't entirely understand what this does... + */ +# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f +# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 +/** @} */ + +#define DPLL_TEST 0x606c +# define DPLLB_TEST_SDVO_DIV_1 (0 << 22) +# define DPLLB_TEST_SDVO_DIV_2 (1 << 22) +# define DPLLB_TEST_SDVO_DIV_4 (2 << 22) +# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22) +# define DPLLB_TEST_N_BYPASS (1 << 19) +# define DPLLB_TEST_M_BYPASS (1 << 18) +# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16) +# define DPLLA_TEST_N_BYPASS (1 << 3) +# define DPLLA_TEST_M_BYPASS (1 << 2) +# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) + +#define ADPA 0x61100 +#define ADPA_DAC_ENABLE (1<<31) +#define ADPA_DAC_DISABLE 0 +#define ADPA_PIPE_SELECT_MASK (1<<30) +#define ADPA_PIPE_A_SELECT 0 +#define ADPA_PIPE_B_SELECT (1<<30) +#define ADPA_USE_VGA_HVPOLARITY (1<<15) +#define ADPA_SETS_HVPOLARITY 0 +#define ADPA_VSYNC_CNTL_DISABLE (1<<11) +#define ADPA_VSYNC_CNTL_ENABLE 0 +#define ADPA_HSYNC_CNTL_DISABLE (1<<10) +#define ADPA_HSYNC_CNTL_ENABLE 0 +#define ADPA_VSYNC_ACTIVE_HIGH (1<<4) +#define ADPA_VSYNC_ACTIVE_LOW 0 +#define ADPA_HSYNC_ACTIVE_HIGH (1<<3) +#define ADPA_HSYNC_ACTIVE_LOW 0 + +#define FPA0 0x06040 +#define FPA1 0x06044 +#define FPB0 0x06048 +#define FPB1 0x0604c +# define FP_N_DIV_MASK 0x003f0000 +# define FP_N_DIV_SHIFT 16 +# define FP_M1_DIV_MASK 0x00003f00 +# define FP_M1_DIV_SHIFT 8 +# define FP_M2_DIV_MASK 0x0000003f +# define FP_M2_DIV_SHIFT 0 + + +#define PORT_HOTPLUG_EN 0x61110 +# define SDVOB_HOTPLUG_INT_EN (1 << 26) +# define SDVOC_HOTPLUG_INT_EN (1 << 25) +# define TV_HOTPLUG_INT_EN (1 << 18) +# define CRT_HOTPLUG_INT_EN (1 << 9) +# define CRT_HOTPLUG_FORCE_DETECT (1 << 3) + +#define PORT_HOTPLUG_STAT 0x61114 +# define CRT_HOTPLUG_INT_STATUS (1 << 11) +# define TV_HOTPLUG_INT_STATUS (1 << 10) +# define CRT_HOTPLUG_MONITOR_MASK (3 << 8) +# define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) +# define CRT_HOTPLUG_MONITOR_MONO (2 << 8) +# define CRT_HOTPLUG_MONITOR_NONE (0 << 8) +# define SDVOC_HOTPLUG_INT_STATUS (1 << 7) +# define SDVOB_HOTPLUG_INT_STATUS (1 << 6) + +#define SDVOB 0x61140 +#define SDVOC 0x61160 +#define SDVO_ENABLE (1 << 31) +#define SDVO_PIPE_B_SELECT (1 << 30) +#define SDVO_STALL_SELECT (1 << 29) +#define SDVO_INTERRUPT_ENABLE (1 << 26) +/** + * 915G/GM SDVO pixel multiplier. + * + * Programmed value is multiplier - 1, up to 5x. + * + * \sa DPLL_MD_UDI_MULTIPLIER_MASK + */ +#define SDVO_PORT_MULTIPLY_MASK (7 << 23) +#define SDVO_PORT_MULTIPLY_SHIFT 23 +#define SDVO_PHASE_SELECT_MASK (15 << 19) +#define SDVO_PHASE_SELECT_DEFAULT (6 << 19) +#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) +#define SDVOC_GANG_MODE (1 << 16) +#define SDVO_BORDER_ENABLE (1 << 7) +#define SDVOB_PCIE_CONCURRENCY (1 << 3) +#define SDVO_DETECTED (1 << 2) +/* Bits to be preserved when writing */ +#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14)) +#define SDVOC_PRESERVE_MASK (1 << 17) + +/** @defgroup LVDS + * @{ + */ +/** + * This register controls the LVDS output enable, pipe selection, and data + * format selection. + * + * All of the clock/data pairs are force powered down by power sequencing. + */ +#define LVDS 0x61180 +/** + * Enables the LVDS port. This bit must be set before DPLLs are enabled, as + * the DPLL semantics change when the LVDS is assigned to that pipe. + */ +# define LVDS_PORT_EN (1 << 31) +/** Selects pipe B for LVDS data. Must be set on pre-965. */ +# define LVDS_PIPEB_SELECT (1 << 30) + +/** + * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per + * pixel. + */ +# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) +# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) +# define LVDS_A0A2_CLKA_POWER_UP (3 << 8) +/** + * Controls the A3 data pair, which contains the additional LSBs for 24 bit + * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be + * on. + */ +# define LVDS_A3_POWER_MASK (3 << 6) +# define LVDS_A3_POWER_DOWN (0 << 6) +# define LVDS_A3_POWER_UP (3 << 6) +/** + * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP + * is set. + */ +# define LVDS_CLKB_POWER_MASK (3 << 4) +# define LVDS_CLKB_POWER_DOWN (0 << 4) +# define LVDS_CLKB_POWER_UP (3 << 4) + +/** + * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 + * setting for whether we are in dual-channel mode. The B3 pair will + * additionally only be powered up when LVDS_A3_POWER_UP is set. + */ +# define LVDS_B0B3_POWER_MASK (3 << 2) +# define LVDS_B0B3_POWER_DOWN (0 << 2) +# define LVDS_B0B3_POWER_UP (3 << 2) + +#define PIPEACONF 0x70008 +#define PIPEACONF_ENABLE (1<<31) +#define PIPEACONF_DISABLE 0 +#define PIPEACONF_DOUBLE_WIDE (1<<30) +#define I965_PIPECONF_ACTIVE (1<<30) +#define PIPEACONF_SINGLE_WIDE 0 +#define PIPEACONF_PIPE_UNLOCKED 0 +#define PIPEACONF_PIPE_LOCKED (1<<25) +#define PIPEACONF_PALETTE 0 +#define PIPEACONF_GAMMA (1<<24) +#define PIPECONF_FORCE_BORDER (1<<25) +#define PIPECONF_PROGRESSIVE (0 << 21) +#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) +#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) + +#define PIPEBCONF 0x71008 +#define PIPEBCONF_ENABLE (1<<31) +#define PIPEBCONF_DISABLE 0 +#define PIPEBCONF_DOUBLE_WIDE (1<<30) +#define PIPEBCONF_DISABLE 0 +#define PIPEBCONF_GAMMA (1<<24) +#define PIPEBCONF_PALETTE 0 + +#define PIPEBGCMAXRED 0x71010 +#define PIPEBGCMAXGREEN 0x71014 +#define PIPEBGCMAXBLUE 0x71018 +#define PIPEBSTAT 0x71024 +#define PIPEBFRAMEHIGH 0x71040 +#define PIPEBFRAMEPIXEL 0x71044 + +#define DSPACNTR 0x70180 +#define DSPBCNTR 0x71180 +#define DISPLAY_PLANE_ENABLE (1<<31) +#define DISPLAY_PLANE_DISABLE 0 +#define DISPPLANE_GAMMA_ENABLE (1<<30) +#define DISPPLANE_GAMMA_DISABLE 0 +#define DISPPLANE_PIXFORMAT_MASK (0xf<<26) +#define DISPPLANE_8BPP (0x2<<26) +#define DISPPLANE_15_16BPP (0x4<<26) +#define DISPPLANE_16BPP (0x5<<26) +#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) +#define DISPPLANE_32BPP (0x7<<26) +#define DISPPLANE_STEREO_ENABLE (1<<25) +#define DISPPLANE_STEREO_DISABLE 0 +#define DISPPLANE_SEL_PIPE_MASK (1<<24) +#define DISPPLANE_SEL_PIPE_A 0 +#define DISPPLANE_SEL_PIPE_B (1<<24) +#define DISPPLANE_SRC_KEY_ENABLE (1<<22) +#define DISPPLANE_SRC_KEY_DISABLE 0 +#define DISPPLANE_LINE_DOUBLE (1<<20) +#define DISPPLANE_NO_LINE_DOUBLE 0 +#define DISPPLANE_STEREO_POLARITY_FIRST 0 +#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) +/* plane B only */ +#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15) +#define DISPPLANE_ALPHA_TRANS_DISABLE 0 +#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0 +#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1) + +#define DSPABASE 0x70184 +#define DSPASTRIDE 0x70188 + +#define DSPBBASE 0x71184 +#define DSPBADDR DSPBBASE +#define DSPBSTRIDE 0x71188 + +#define DSPAKEYVAL 0x70194 +#define DSPAKEYMASK 0x70198 + +#define DSPAPOS 0x7018C /* reserved */ +#define DSPASIZE 0x70190 +#define DSPBPOS 0x7118C +#define DSPBSIZE 0x71190 + +#define DSPASURF 0x7019C +#define DSPATILEOFF 0x701A4 + +#define DSPBSURF 0x7119C +#define DSPBTILEOFF 0x711A4 + +#define VGACNTRL 0x71400 +# define VGA_DISP_DISABLE (1 << 31) +# define VGA_2X_MODE (1 << 30) +# define VGA_PIPE_B_SELECT (1 << 29) + +/* + * Palette registers + */ +#define PALETTE_A 0x0a000 +#define PALETTE_B 0x0a800 + +#define IS_I830(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82830_CGC) +#define IS_845G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82845G_IG) +#define IS_I85X(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82855GM_IG) +#define IS_I855(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82855GM_IG) +#define IS_I865G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82865_IG) + +#define IS_I915G(pI810) (dev->pci_device == PCI_DEVICE_ID_INTEL_82915G_IG)/* || dev->pci_device == PCI_DEVICE_ID_INTELPCI_CHIP_E7221_G)*/ +#define IS_I915GM(pI810) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82915GM_IG) +#define IS_I945G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945G_IG) +#define IS_I945GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945GM_IG) + +#define IS_I965G(dev) ((dev)->pci_device == 0x2972 || \ + (dev)->pci_device == 0x2982 || \ + (dev)->pci_device == 0x2992 || \ + (dev)->pci_device == 0x29A2) + + +#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810)) + +#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810)) + #endif -- cgit v1.2.3 From 5bffbd6e275efffbb649c20c528a11412ccf99cd Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 5 Apr 2007 13:34:50 +1000 Subject: initial userspace interface to get modes --- shared-core/drm.h | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 3c59cd40..33194dcc 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -888,6 +888,74 @@ typedef union drm_mm_init_arg{ } rep; } drm_mm_init_arg_t; +/* + * Drm mode setting + */ + +struct drm_mode_modeinfo { + + unsigned int id; + + unsigned int clock; + unsigned short hdisplay, hsync_start, hsync_end, htotal, hskew; + unsigned short vdisplay, vsync_start, vsync_end, vtotal, vscan; + + unsigned int flags; +// int count_flag; +// unsigned int __user *modeFlags; +}; + +struct drm_mode_card_res { + + unsigned int fb_id; + + int count_crtcs; + int count_outputs; + int count_modes; + struct drm_mode_modeinfo __user *modes; + +}; + +struct drm_mode_crtc { + unsigned int crtc_id; /**< Id */ + unsigned int buffer_id; /**< Id of framebuffer */ + + int x, y; /**< Position on the frameuffer */ + unsigned int width, height; + unsigned int mode; /**< Current mode used */ + + int count_outputs; + unsigned int outputs; /**< Outputs that are connected */ + + int count_possibles; + unsigned int possibles; /**< Outputs that can be connected */ + + unsigned int __user *set_outputs; /**< Outputs to be connected */ + + int gamma_size; + +}; + +struct drm_mode_get_output { + + unsigned int output; /**< Id */ + unsigned int crtc; /**< Id of crtc */ + + unsigned int connection; + unsigned int width, height; /**< HxW in millimeters */ + unsigned int subpixel; + + int count_crtcs; + unsigned int crtcs; /**< possible crtc to connect to */ + + int count_clones; + unsigned int clones; /**< list of clones */ + + int count_modes; + unsigned int __user *modes; /**< list of modes it supports */ + +}; + /** * \name Ioctls Definitions */ @@ -959,6 +1027,10 @@ typedef union drm_mm_init_arg{ #define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, drm_update_draw_t) +#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res) +#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, drm_mode_crtc_t) +#define DRM_IOCTL_MODE_GETOUTPUT DRM_IOWR(0xA2, drm_mode_get_output_t) + /*@}*/ /** -- cgit v1.2.3 From 7bb112fecadc6fe42e5828b861600691071ccd91 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 5 Apr 2007 17:06:42 +1000 Subject: checkpoint commit: added getresources, crtc and output This adds the user interfaces from Jakob and hooks them up for 3 ioctls GetResources, GetCrtc and GetOutput. I've made the ids for everything fbs, crtcs, outputs and modes go via idr as per krh's suggestion on irc as it make the code nice and consistent. --- shared-core/drm.h | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 33194dcc..1af0be38 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -892,6 +892,8 @@ typedef union drm_mm_init_arg{ * Drm mode setting */ +#define DRM_DISPLAY_MODE_LEN 32 + struct drm_mode_modeinfo { unsigned int id; @@ -901,8 +903,8 @@ struct drm_mode_modeinfo { unsigned short vdisplay, vsync_start, vsync_end, vtotal, vscan; unsigned int flags; -// int count_flag; -// unsigned int __user *modeFlags; + + char name[DRM_DISPLAY_MODE_LEN]; }; struct drm_mode_card_res { @@ -910,7 +912,11 @@ struct drm_mode_card_res { unsigned int fb_id; int count_crtcs; + unsigned int __user *crtc_id; + int count_outputs; + unsigned int __user *output_id; + int count_modes; struct drm_mode_modeinfo __user *modes; @@ -918,10 +924,10 @@ struct drm_mode_card_res { struct drm_mode_crtc { unsigned int crtc_id; /**< Id */ - unsigned int buffer_id; /**< Id of framebuffer */ + unsigned int fb_id; /**< Id of framebuffer */ int x, y; /**< Position on the frameuffer */ - unsigned int width, height; + unsigned int mode; /**< Current mode used */ int count_outputs; @@ -942,7 +948,7 @@ struct drm_mode_get_output { unsigned int crtc; /**< Id of crtc */ unsigned int connection; - unsigned int width, height; /**< HxW in millimeters */ + unsigned int mm_width, mm_height; /**< HxW in millimeters */ unsigned int subpixel; int count_crtcs; @@ -1028,8 +1034,8 @@ struct drm_mode_get_output { #define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, drm_update_draw_t) #define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res) -#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, drm_mode_crtc_t) -#define DRM_IOCTL_MODE_GETOUTPUT DRM_IOWR(0xA2, drm_mode_get_output_t) +#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) /*@}*/ -- cgit v1.2.3 From b4094864f188a1346cc3b51bcb457beeacefbf82 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 5 Apr 2007 18:01:02 +1000 Subject: checkpoint commit: implement SetCrtc so modes can in theory be set from user This hooks up the userspace mode set it "seems" to work. --- shared-core/drm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 1af0be38..49bc41bc 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1036,7 +1036,7 @@ struct drm_mode_get_output { #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) /*@}*/ /** -- cgit v1.2.3 From b50bda002b824efb24e18e8d514ff0ca763c15b9 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 10 Apr 2007 18:44:47 +1000 Subject: add addfb/rmfb ioctls Originally from Jakob, cleaned up by airlied. --- shared-core/drm.h | 10 ++++++++++ shared-core/i915_dma.c | 2 -- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 49bc41bc..8329609f 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -962,6 +962,14 @@ struct drm_mode_get_output { }; +struct drm_mode_fb_cmd { + unsigned int buffer_id; + unsigned int width, height; + unsigned int pitch; + unsigned int bpp; + unsigned int handle; +}; + /** * \name Ioctls Definitions */ @@ -1037,6 +1045,8 @@ struct drm_mode_get_output { #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) /*@}*/ /** diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index a5f1473a..811e4bb9 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -171,8 +171,6 @@ static int i915_initialize(drm_device_t * dev, I915_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); - /* this probably doesn't belong here - TODO */ - drm_framebuffer_set_object(dev, dev_priv->sarea_priv->front_handle); drm_set_desired_modes(dev); return 0; -- cgit v1.2.3 From 65f465ed5ad3caf773658bb2832785c963b987f6 Mon Sep 17 00:00:00 2001 From: David Airlie Date: Tue, 10 Apr 2007 14:49:49 +1000 Subject: fixup numerous issues with adding framebuffer support This still isn't perfect but it fixes a few oopses and cleans up some of the tabs and bugs in the original fb limit code --- shared-core/i915_dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 811e4bb9..2c14cb5d 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -171,7 +171,7 @@ static int i915_initialize(drm_device_t * dev, I915_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); - drm_set_desired_modes(dev); +//drm_set_desired_modes(dev); return 0; } -- cgit v1.2.3 From 40bd6dcd86d554ca426deccd4fbada693c4be8a6 Mon Sep 17 00:00:00 2001 From: David Airlie Date: Tue, 10 Apr 2007 15:20:50 +1000 Subject: set the base address of the CRTC correctly --- shared-core/i915_dma.c | 4 +++- shared-core/i915_drv.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 2c14cb5d..c2a6d863 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -877,11 +877,13 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) if (IS_I9XX(dev)) { dev_priv->mmiobase = drm_get_resource_start(dev, 0); dev_priv->mmiolen = drm_get_resource_len(dev, 0); + dev_priv->baseaddr = 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_priv->baseaddr = drm_get_resource_start(dev, 0) & 0xff000000; } else { - DRM_ERROR("Unable to find MMIO registers\n"); + DRM_ERROR("Unable to find MMIO registers or FB\n"); return -ENODEV; } diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index f37f5873..517d0bf6 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -92,6 +92,7 @@ typedef struct drm_i915_private { drm_local_map_t *sarea; drm_local_map_t *mmio_map; + unsigned long baseaddr; unsigned long mmiobase; unsigned long mmiolen; -- cgit v1.2.3 From 1e39dc43230ba1827eedc29ab422464281ec3e1b Mon Sep 17 00:00:00 2001 From: David Airlie Date: Tue, 10 Apr 2007 16:25:31 +1000 Subject: export output name to userspace --- shared-core/drm.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 8329609f..f1afc049 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -891,7 +891,7 @@ typedef union drm_mm_init_arg{ /* * Drm mode setting */ - +#define DRM_OUTPUT_NAME_LEN 32 #define DRM_DISPLAY_MODE_LEN 32 struct drm_mode_modeinfo { @@ -946,6 +946,7 @@ struct drm_mode_get_output { unsigned int output; /**< Id */ unsigned int crtc; /**< Id of crtc */ + unsigned char name[DRM_OUTPUT_NAME_LEN]; unsigned int connection; unsigned int mm_width, mm_height; /**< HxW in millimeters */ -- cgit v1.2.3 From 5130918e2531b9a8f6f6b65cdfce81f4f0904329 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 10 Apr 2007 09:51:17 -0700 Subject: Add save/restore state for LVDS code, along with a few other LVDS related items to i915 private structure. --- shared-core/i915_drv.h | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'shared-core') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index f37f5873..6e81f6f8 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -133,6 +133,67 @@ typedef struct drm_i915_private { spinlock_t swaps_lock; drm_i915_vbl_swap_t 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; + + /* Register state */ + u32 saveDSPACNTR; + u32 saveDSPBCNTR; + u32 savePIPEACONF; + u32 savePIPEBCONF; + u32 savePIPEASRC; + u32 savePIPEBSRC; + u32 saveFPA0; + u32 saveFPA1; + u32 saveDPLL_A; + u32 saveDPLL_A_MD; + u32 saveHTOTAL_A; + u32 saveHBLANK_A; + u32 saveHSYNC_A; + u32 saveVTOTAL_A; + u32 saveVBLANK_A; + u32 saveVSYNC_A; + u32 saveDSPASTRIDE; + u32 saveDSPASIZE; + u32 saveDSPAPOS; + u32 saveDSPABASE; + u32 saveDSPASURF; + u32 saveFPB0; + u32 saveFPB1; + u32 saveDPLL_B; + u32 saveDPLL_B_MD; + u32 saveHTOTAL_B; + u32 saveHBLANK_B; + u32 saveHSYNC_B; + u32 saveVTOTAL_B; + u32 saveVBLANK_B; + u32 saveVSYNC_B; + u32 saveDSPBSTRIDE; + u32 saveDSPBSIZE; + u32 saveDSPBPOS; + u32 saveDSPBBASE; + u32 saveDSPBSURF; + u32 saveVCLK_DIVISOR_VGA0; + u32 saveVCLK_DIVISOR_VGA1; + u32 saveVCLK_POST_DIV; + u32 saveVGACNTRL; + u32 saveADPA; + u32 saveLVDS; + u32 saveDVOA; + u32 saveDVOB; + u32 saveDVOC; + u32 savePP_ON; + u32 savePP_OFF; + u32 savePP_CONTROL; + u32 savePP_CYCLE; + u32 savePFIT_CONTROL; + u32 savePaletteA[256]; + u32 savePaletteB[256]; + u32 saveSWF[17]; + u32 saveBLC_PWM_CTL; } drm_i915_private_t; enum intel_chip_family { @@ -478,6 +539,8 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define PFIT_CONTROL 0x61230 # define PFIT_ENABLE (1 << 31) +# define PFIT_PIPE_MASK (3 << 29) +# define PFIT_PIPE_SHIFT 29 # define VERT_INTERP_DISABLE (0 << 10) # define VERT_INTERP_BILINEAR (1 << 10) # define VERT_INTERP_MASK (3 << 10) -- cgit v1.2.3 From b59285d738b1a832b12d9258bd6f1db8f7e61f08 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 10 Apr 2007 10:31:10 -0700 Subject: Move i915 init code to new file, i915_init.c, and create a new high level init routine that runs at driver load time. --- shared-core/i915_dma.c | 76 +---------------------- shared-core/i915_init.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+), 74 deletions(-) create mode 100644 shared-core/i915_init.c (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index a5f1473a..0ba3048a 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -78,7 +78,7 @@ void i915_kernel_lost_context(drm_device_t * dev) dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; } -static int i915_dma_cleanup(drm_device_t * dev) +int i915_dma_cleanup(drm_device_t * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; /* Make sure interrupts are disabled here because the uninstall ioctl @@ -855,78 +855,6 @@ static int i915_mmio(DRM_IOCTL_ARGS) return 0; } -int i915_driver_load(drm_device_t *dev, unsigned long flags) -{ - drm_i915_private_t *dev_priv; - int ret; - unsigned long mmiobase, mmiolen; - - dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); - if (dev_priv == NULL) - return DRM_ERR(ENOMEM); - - memset(dev_priv, 0, sizeof(drm_i915_private_t)); - dev->dev_private = (void *)dev_priv; -// dev_priv->flags = flags; - - /* i915 has 4 more counters */ - dev->counters += 4; - dev->types[6] = _DRM_STAT_IRQ; - dev->types[7] = _DRM_STAT_PRIMARY; - dev->types[8] = _DRM_STAT_SECONDARY; - dev->types[9] = _DRM_STAT_DMA; - - if (IS_I9XX(dev)) { - dev_priv->mmiobase = drm_get_resource_start(dev, 0); - dev_priv->mmiolen = drm_get_resource_len(dev, 0); - } 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); - } else { - DRM_ERROR("Unable to find MMIO registers\n"); - return -ENODEV; - } - - ret = drm_addmap(dev, dev_priv->mmiobase, dev_priv->mmiolen, - _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio_map); - if (ret != 0) { - DRM_ERROR("Cannot add mapping for MMIO registers\n"); - return ret; - } - - DRM_DEBUG("dev_priv->mmio map is %08X\n", dev_priv->mmio_map); - intel_modeset_init(dev); - return 0; -} - -int i915_driver_unload(drm_device_t *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - intel_modeset_cleanup(dev); - drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); - - dev->dev_private = NULL; - return 0; -} - -void i915_driver_lastclose(drm_device_t * dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - i915_mem_takedown(&(dev_priv->agp_heap)); - - i915_dma_cleanup(dev); - - dev_priv->mmio_map = NULL; -} - -void i915_driver_preclose(drm_device_t * dev, DRMFILE filp) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - i915_mem_release(dev, filp, dev_priv->agp_heap); -} - drm_ioctl_desc_t i915_ioctls[] = { [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, DRM_AUTH}, @@ -981,7 +909,7 @@ int i915_driver_firstopen(struct drm_device *dev) } } - DRM_DEBUG("dev_priv->mmio map is %08X\n", dev_priv->mmio_map); + DRM_DEBUG("dev_priv->mmio map is %p\n", dev_priv->mmio_map); return 0; } diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c new file mode 100644 index 00000000..e03ed429 --- /dev/null +++ b/shared-core/i915_init.c @@ -0,0 +1,157 @@ +#include "drmP.h" +#include "drm.h" +#include "drm_sarea.h" +#include "i915_drm.h" +#include "i915_drv.h" + +int i915_driver_load(drm_device_t *dev, unsigned long flags) +{ + drm_i915_private_t *dev_priv; + drm_i915_init_t init; + int ret; + + dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); + if (dev_priv == NULL) + return DRM_ERR(ENOMEM); + + memset(dev_priv, 0, sizeof(drm_i915_private_t)); + dev->dev_private = (void *)dev_priv; +// dev_priv->flags = flags; + + /* i915 has 4 more counters */ + dev->counters += 4; + dev->types[6] = _DRM_STAT_IRQ; + dev->types[7] = _DRM_STAT_PRIMARY; + dev->types[8] = _DRM_STAT_SECONDARY; + dev->types[9] = _DRM_STAT_DMA; + + if (IS_I9XX(dev)) { + dev_priv->mmiobase = drm_get_resource_start(dev, 0); + dev_priv->mmiolen = drm_get_resource_len(dev, 0); + } 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); + } else { + DRM_ERROR("Unable to find MMIO registers\n"); + return -ENODEV; + } + + ret = drm_addmap(dev, dev_priv->mmiobase, dev_priv->mmiolen, + _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio_map); + if (ret != 0) { + DRM_ERROR("Cannot add mapping for MMIO registers\n"); + return ret; + } + + + ret = drm_setup(dev); + if (ret) { + DRM_ERROR("drm_setup failed\n"); + return ret; + } + + DRM_GETSAREA(); + if (!dev_priv->sarea) { + DRM_ERROR("can not find sarea!\n"); + dev->dev_private = (void *)dev_priv; + i915_dma_cleanup(dev); + return DRM_ERR(EINVAL); + } + + /* FIXME: where does the sarea_priv really go? */ + dev_priv->sarea_priv = kmalloc(sizeof(drm_i915_sarea_t), GFP_KERNEL); + + /* FIXME: need real front buffer offset */ + dev_priv->sarea_priv->front_handle = 0xa0000000 + 1024*1024; + + drm_bo_driver_init(dev); + /* this probably doesn't belong here - TODO */ + drm_framebuffer_set_object(dev, dev_priv->sarea_priv->front_handle); + intel_modeset_init(dev); + drm_set_desired_modes(dev); + + /* FIXME: command ring needs AGP space, do we own it at this point? */ + dev_priv->ring.Start = 0xa0000000; + dev_priv->ring.End = 128*1024; + dev_priv->ring.Size = 128*1024; + dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; + + dev_priv->ring.map.offset = dev_priv->ring.Start; + dev_priv->ring.map.size = dev_priv->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) { + dev->dev_private = (void *)dev_priv; + i915_dma_cleanup(dev); + DRM_ERROR("can not ioremap virtual address for" + " ring buffer\n"); + return DRM_ERR(ENOMEM); + } + + dev_priv->ring.virtual_start = dev_priv->ring.map.handle; + dev_priv->cpp = 4; + dev_priv->sarea_priv->pf_current_page = 0; + + /* 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 */ + 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 DRM_ERR(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); + DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); + + I915_WRITE(0x02080, dev_priv->dma_status_page); + DRM_DEBUG("Enabled hardware status page\n"); + + return 0; +} + +int i915_driver_unload(drm_device_t *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + + intel_modeset_cleanup(dev); + drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); + + dev->dev_private = NULL; + return 0; +} + +void i915_driver_lastclose(drm_device_t * dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + + i915_mem_takedown(&(dev_priv->agp_heap)); + + i915_dma_cleanup(dev); + + dev_priv->mmio_map = NULL; +} + +void i915_driver_preclose(drm_device_t * dev, DRMFILE filp) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + i915_mem_release(dev, filp, dev_priv->agp_heap); +} + -- cgit v1.2.3 From 44be9c9d5950d3b2ba4d5527189abec8dac0686f Mon Sep 17 00:00:00 2001 From: David Airlie Date: Wed, 11 Apr 2007 13:19:30 +1000 Subject: add an fb count + id get to the get resources code path --- shared-core/drm.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index f1afc049..a5330b28 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -909,7 +909,8 @@ struct drm_mode_modeinfo { struct drm_mode_card_res { - unsigned int fb_id; + int count_fbs; + unsigned int __user *fb_id; int count_crtcs; unsigned int __user *crtc_id; -- cgit v1.2.3 From b329f91502a20cc6def44b7bea6cbc8b016edd5e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 11 Apr 2007 14:04:18 +1000 Subject: use the baseaddr at least --- shared-core/i915_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index e454c9fc..038e3939 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -64,7 +64,7 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) dev_priv->sarea_priv = kmalloc(sizeof(drm_i915_sarea_t), GFP_KERNEL); /* FIXME: need real front buffer offset */ - dev_priv->sarea_priv->front_handle = 0xa0000000 + 1024*1024; + dev_priv->sarea_priv->front_handle = dev_priv->baseaddr + 1024*1024; drm_bo_driver_init(dev); /* this probably doesn't belong here - TODO */ @@ -73,7 +73,7 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) drm_set_desired_modes(dev); /* FIXME: command ring needs AGP space, do we own it at this point? */ - dev_priv->ring.Start = 0xa0000000; + dev_priv->ring.Start = dev_priv->baseaddr; dev_priv->ring.End = 128*1024; dev_priv->ring.Size = 128*1024; dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; -- cgit v1.2.3 From 3dd5dc5728620cadec24ee5db323a20c3bb48bf0 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 11 Apr 2007 14:34:43 +1000 Subject: only init at driver load --- shared-core/i915_dma.c | 1 - 1 file changed, 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 1c8a0d45..a7603405 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -896,7 +896,6 @@ int i915_driver_firstopen(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; int ret; DRM_DEBUG("\n"); - drm_bo_driver_init(dev); if (!dev_priv->mmio_map) { ret = drm_addmap(dev, dev_priv->mmiobase, dev_priv->mmiolen, -- cgit v1.2.3 From add7a928ad1819df17d5764d06fb81985b285d08 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 11 Apr 2007 14:43:02 +1000 Subject: comment out unworkable code --- shared-core/i915_init.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 038e3939..61c128cb 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -45,7 +45,7 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) return ret; } - +#if 0 ret = drm_setup(dev); if (ret) { DRM_ERROR("drm_setup failed\n"); @@ -61,17 +61,17 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) } /* FIXME: where does the sarea_priv really go? */ - dev_priv->sarea_priv = kmalloc(sizeof(drm_i915_sarea_t), GFP_KERNEL); + // dev_priv->sarea_priv = kmalloc(sizeof(drm_i915_sarea_t), GFP_KERNEL); /* FIXME: need real front buffer offset */ - dev_priv->sarea_priv->front_handle = dev_priv->baseaddr + 1024*1024; - + /// dev_priv->sarea_priv->front_handle = dev_priv->baseaddr + 1024*1024; +#endif drm_bo_driver_init(dev); /* this probably doesn't belong here - TODO */ //drm_framebuffer_set_object(dev, dev_priv->sarea_priv->front_handle); intel_modeset_init(dev); - drm_set_desired_modes(dev); - + // drm_set_desired_modes(dev); +#if 0 /* FIXME: command ring needs AGP space, do we own it at this point? */ dev_priv->ring.Start = dev_priv->baseaddr; dev_priv->ring.End = 128*1024; @@ -125,6 +125,7 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) I915_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); +#endif return 0; } -- cgit v1.2.3 From 32f6a58db216f23a7c71ca9c7eda56aaa8293078 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 11 Apr 2007 16:33:03 +1000 Subject: add initial drm_fb framebuffer So far I can load fbcon, once I use my miniglx to add a framebuffer. fbcon doesn't show anything on screen but baby steps and all that. --- shared-core/i915_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 61c128cb..5af86f82 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -28,11 +28,11 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) if (IS_I9XX(dev)) { dev_priv->mmiobase = drm_get_resource_start(dev, 0); dev_priv->mmiolen = drm_get_resource_len(dev, 0); - dev_priv->baseaddr = drm_get_resource_start(dev, 2) & 0xff000000; + dev->mode_config.fb_base = dev_priv->baseaddr = 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_priv->baseaddr = drm_get_resource_start(dev, 0) & 0xff000000; + dev->mode_config.fb_base = dev_priv->baseaddr = drm_get_resource_start(dev, 0) & 0xff000000; } else { DRM_ERROR("Unable to find MMIO registers\n"); return -ENODEV; -- cgit v1.2.3 From a6cc6a778f8b2f86300a8ce87441d044fd67f930 Mon Sep 17 00:00:00 2001 From: David Airlie Date: Wed, 11 Apr 2007 17:13:45 +1000 Subject: add support for setting a framebuffer depth --- shared-core/drm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index a5330b28..621b201c 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -970,6 +970,7 @@ struct drm_mode_fb_cmd { unsigned int pitch; unsigned int bpp; unsigned int handle; + unsigned int depth; }; /** -- cgit v1.2.3 From 78598fdaa8b23a199880a63b79f17cfd7f14cb0f Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 11 Apr 2007 07:07:54 -0700 Subject: Various changes for in-kernel modesetting: - allow drm_buffer_object_create to be called w/o dev_mapping - fixup i915 init code to allocate memory, fb and set modes right - pass fb to drm_initial_config for setup - change some debug output to make it easier to spot - fixup lvds code to use DDC probing correctly --- shared-core/i915_init.c | 65 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 10 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 5af86f82..d9fb485b 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -4,10 +4,23 @@ #include "i915_drm.h" #include "i915_drv.h" +/** + * 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(drm_device_t *dev, unsigned long flags) { drm_i915_private_t *dev_priv; drm_i915_init_t init; + drm_buffer_object_t *entry; + struct drm_framebuffer *fb; int ret; dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); @@ -45,7 +58,6 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) return ret; } -#if 0 ret = drm_setup(dev); if (ret) { DRM_ERROR("drm_setup failed\n"); @@ -60,17 +72,48 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) return DRM_ERR(EINVAL); } - /* FIXME: where does the sarea_priv really go? */ - // dev_priv->sarea_priv = kmalloc(sizeof(drm_i915_sarea_t), GFP_KERNEL); + /* FIXME: assume sarea_priv is right after SAREA */ + dev_priv->sarea_priv = dev_priv->sarea->handle + sizeof(drm_sarea_t); - /* FIXME: need real front buffer offset */ - /// dev_priv->sarea_priv->front_handle = dev_priv->baseaddr + 1024*1024; -#endif + /* + * Initialize the memory manager for local and AGP space + */ drm_bo_driver_init(dev); - /* this probably doesn't belong here - TODO */ - //drm_framebuffer_set_object(dev, dev_priv->sarea_priv->front_handle); + /* FIXME: initial stolen area 8M init */ +#define SCANOUT_SIZE 1024*1024*8 /* big enough for 2048x1024 32bpp */ + drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, dev->mode_config.fb_base, + SCANOUT_SIZE); + + /* Allocate scanout buffer and command ring */ + /* FIXME: types and other args correct? */ + drm_buffer_object_create(dev, SCANOUT_SIZE, drm_bo_type_dc, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE, + 0, PAGE_SIZE, 0, + &entry); + + DRM_DEBUG("allocated bo, start: 0x%lx, offset: 0x%lx\n", + entry->buffer_start, entry->offset); intel_modeset_init(dev); - // drm_set_desired_modes(dev); + + fb = drm_framebuffer_create(dev); + if (!fb) { + DRM_ERROR("failed to allocate fb\n"); + return -EINVAL; + } + + fb->width = 1024; + fb->height = 768; + fb->pitch = 1024; + fb->bits_per_pixel = 32; + fb->depth = 32; + fb->offset = entry->offset; + fb->bo = entry; + + drm_initial_config(dev, fb, false); + drmfb_probe(dev, fb); + drm_set_desired_modes(dev); + #if 0 /* FIXME: command ring needs AGP space, do we own it at this point? */ dev_priv->ring.Start = dev_priv->baseaddr; @@ -133,8 +176,10 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) int i915_driver_unload(drm_device_t *dev) { drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_framebuffer *fb; - intel_modeset_cleanup(dev); + /* FIXME: remove framebuffer */ + //intel_modeset_cleanup(dev); drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); dev->dev_private = NULL; -- cgit v1.2.3 From cc7faa4de80a68d5a7a484046b9b42de961cdbef Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 11 Apr 2007 07:21:24 -0700 Subject: fix modeset cleanup for LVDS and reenable it in i915. --- shared-core/i915_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index d9fb485b..43c535d2 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -179,7 +179,7 @@ int i915_driver_unload(drm_device_t *dev) struct drm_framebuffer *fb; /* FIXME: remove framebuffer */ - //intel_modeset_cleanup(dev); + intel_modeset_cleanup(dev); drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); dev->dev_private = NULL; -- cgit v1.2.3 From 8dd75bd601f5fbf9793afc7b869a278050aa17d5 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 11 Apr 2007 11:47:58 -0700 Subject: Add aperture size and preallocation probing (from intelfb), cleanup load code to be more general. --- shared-core/i915_drv.h | 21 ++++++++ shared-core/i915_init.c | 132 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 140 insertions(+), 13 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index b1bf0469..c22ab843 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -318,6 +318,27 @@ extern void intel_modeset_cleanup(drm_device_t *dev); extern int i915_wait_ring(drm_device_t * 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) + #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) #define CMD_REPORT_HEAD (7<<23) diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 43c535d2..fba633fd 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -1,9 +1,108 @@ +/* + * Copyright (c) 2007 Intel Corporation + * Jesse Barnes + * + * Copyright © 2002, 2003 David Dawes + * 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_82915G_IG: + case PCI_DEVICE_ID_INTEL_82915GM_IG: + case PCI_DEVICE_ID_INTEL_82945G_IG: + case PCI_DEVICE_ID_INTEL_82945GM_IG: + /* 915 and 945 chipsets support a 256MB aperture. + Aperture size is determined by inspected the + base address of the aperture. */ + if (pci_resource_start(pdev, 2) & 0x08000000) + *aperture_size *= 128; + else + *aperture_size *= 256; + break; + default: + if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M) + *aperture_size *= 64; + else + *aperture_size *= 128; + 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 @@ -21,7 +120,8 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) drm_i915_init_t init; drm_buffer_object_t *entry; struct drm_framebuffer *fb; - int ret; + unsigned long agp_size, prealloc_size; + int hsize, vsize, bytes_per_pixel, size, ret; dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); if (dev_priv == NULL) @@ -41,11 +141,13 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) 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 = dev_priv->baseaddr = drm_get_resource_start(dev, 2) & 0xff000000; + dev->mode_config.fb_base = dev_priv->baseaddr = + 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 = dev_priv->baseaddr = drm_get_resource_start(dev, 0) & 0xff000000; + dev->mode_config.fb_base = dev_priv->baseaddr = + drm_get_resource_start(dev, 0) & 0xff000000; } else { DRM_ERROR("Unable to find MMIO registers\n"); return -ENODEV; @@ -79,14 +181,18 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) * Initialize the memory manager for local and AGP space */ drm_bo_driver_init(dev); - /* FIXME: initial stolen area 8M init */ -#define SCANOUT_SIZE 1024*1024*8 /* big enough for 2048x1024 32bpp */ - drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, dev->mode_config.fb_base, - SCANOUT_SIZE); + + i915_probe_agp(dev->pdev, &agp_size, &prealloc_size); + drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, dev_priv->baseaddr, + prealloc_size); /* Allocate scanout buffer and command ring */ /* FIXME: types and other args correct? */ - drm_buffer_object_create(dev, SCANOUT_SIZE, drm_bo_type_dc, + hsize = 1280; + vsize = 800; + bytes_per_pixel = 4; + size = hsize * vsize * bytes_per_pixel; + drm_buffer_object_create(dev, size, drm_bo_type_dc, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE, 0, PAGE_SIZE, 0, @@ -102,11 +208,11 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) return -EINVAL; } - fb->width = 1024; - fb->height = 768; - fb->pitch = 1024; - fb->bits_per_pixel = 32; - fb->depth = 32; + fb->width = hsize; + fb->height = vsize; + fb->pitch = hsize; + fb->bits_per_pixel = bytes_per_pixel * 8; + fb->depth = bytes_per_pixel * 8; fb->offset = entry->offset; fb->bo = entry; -- cgit v1.2.3 From 2e21779992bd5026d8ec4dea52466377dbe5a0ed Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 11 Apr 2007 12:51:52 -0700 Subject: Add new buffer object type for kernel allocations that don't initially have a user mapping. --- shared-core/drm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 621b201c..698f851b 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -795,6 +795,7 @@ typedef struct drm_fence_arg { typedef enum { drm_bo_type_dc, + drm_bo_type_kernel, /* for initial kernel allocations */ drm_bo_type_user, drm_bo_type_fake }drm_bo_type_t; -- cgit v1.2.3 From 9d7160c43a7475b9d2ab06c5c353acb9456efa12 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 11 Apr 2007 12:52:57 -0700 Subject: Use new kernel buffer object type and cleanup agp probing. --- shared-core/i915_init.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index fba633fd..b942b70f 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -44,24 +44,19 @@ int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size, *preallocated_size = 1024 * 1024; switch (pdev->device) { - case PCI_DEVICE_ID_INTEL_82915G_IG: - case PCI_DEVICE_ID_INTEL_82915GM_IG: - case PCI_DEVICE_ID_INTEL_82945G_IG: - case PCI_DEVICE_ID_INTEL_82945GM_IG: - /* 915 and 945 chipsets support a 256MB aperture. - Aperture size is determined by inspected the - base address of the aperture. */ - if (pci_resource_start(pdev, 2) & 0x08000000) - *aperture_size *= 128; - else - *aperture_size *= 256; - break; - default: + case PCI_DEVICE_ID_INTEL_82830_CGC: + case PCI_DEVICE_ID_INTEL_82845G_HB: + 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; } /* @@ -192,7 +187,7 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) vsize = 800; bytes_per_pixel = 4; size = hsize * vsize * bytes_per_pixel; - drm_buffer_object_create(dev, size, drm_bo_type_dc, + drm_buffer_object_create(dev, size, drm_bo_type_kernel, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE, 0, PAGE_SIZE, 0, -- cgit v1.2.3 From a81558d8b3ee17fbf46e32b10732e22fcd997858 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 12 Apr 2007 08:45:40 +1000 Subject: add getfb ioctl --- shared-core/drm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 698f851b..b5b0aa52 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1051,6 +1051,7 @@ struct drm_mode_fb_cmd { #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) /*@}*/ /** -- cgit v1.2.3 From fb6c5aacb9955248300e0c62f68a5a65b40e15e1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 12 Apr 2007 11:54:49 +1000 Subject: only initialise modes when fbcon or fbset asks for it --- shared-core/i915_init.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index b942b70f..ebe73815 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -213,8 +213,6 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) drm_initial_config(dev, fb, false); drmfb_probe(dev, fb); - drm_set_desired_modes(dev); - #if 0 /* FIXME: command ring needs AGP space, do we own it at this point? */ dev_priv->ring.Start = dev_priv->baseaddr; -- cgit v1.2.3 From 0430a80fc7861a3397a3f2649dfeb9eff14359a5 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 11 Apr 2007 20:41:27 -0700 Subject: Remove debug statement about buffer objects --- shared-core/i915_init.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index b942b70f..7616b33e 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -193,8 +193,6 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) 0, PAGE_SIZE, 0, &entry); - DRM_DEBUG("allocated bo, start: 0x%lx, offset: 0x%lx\n", - entry->buffer_start, entry->offset); intel_modeset_init(dev); fb = drm_framebuffer_create(dev); -- cgit v1.2.3 From 2160e267ff3e1a503ab7666b60ffe21f4a90b803 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 12 Apr 2007 09:01:53 -0700 Subject: Don't use drm_setup, do SAREA allocation and mapping directly instead. --- shared-core/i915_init.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 1a8af0ab..687eaa4b 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -114,8 +114,10 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) drm_i915_private_t *dev_priv; drm_i915_init_t init; drm_buffer_object_t *entry; + drm_local_map_t *map; struct drm_framebuffer *fb; unsigned long agp_size, prealloc_size; + unsigned long sareapage; int hsize, vsize, bytes_per_pixel, size, ret; dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); @@ -155,9 +157,12 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) return ret; } - ret = drm_setup(dev); + /* prebuild the SAREA */ + sareapage = max(SAREA_MAX, PAGE_SIZE); + ret = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK, + &map); if (ret) { - DRM_ERROR("drm_setup failed\n"); + DRM_ERROR("SAREA setup failed\n"); return ret; } -- cgit v1.2.3 From e183a091ff44e5b03ec521696830c45b2ce9ce87 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 12 Apr 2007 11:40:12 -0700 Subject: Initialize the hw lock waitqueue so we don't hang in drm_lastclose. --- shared-core/i915_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 687eaa4b..f0ab4574 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -173,6 +173,7 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) i915_dma_cleanup(dev); return DRM_ERR(EINVAL); } + init_waitqueue_head(&dev->lock.lock_queue); /* FIXME: assume sarea_priv is right after SAREA */ dev_priv->sarea_priv = dev_priv->sarea->handle + sizeof(drm_sarea_t); @@ -280,7 +281,6 @@ int i915_driver_unload(drm_device_t *dev) drm_i915_private_t *dev_priv = dev->dev_private; struct drm_framebuffer *fb; - /* FIXME: remove framebuffer */ intel_modeset_cleanup(dev); drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); -- cgit v1.2.3 From cc471a361fc7058df4fb8d15d9c9a8b5cdd3dd77 Mon Sep 17 00:00:00 2001 From: David Airlie Date: Fri, 13 Apr 2007 14:33:52 +1000 Subject: i915/drm: clean up a lot of the i915/drm startup/teardown sequences When the kernel driver is loaded it sets up a lot of stuff.. it tears down the same stuff on unload. This add a new map type called DRM_DRIVER which means the driver will clean the mapping up and fix up the map cleaner --- shared-core/drm.h | 3 +- shared-core/i915_dma.c | 106 -------------------------------------- shared-core/i915_drv.h | 3 ++ shared-core/i915_init.c | 132 +++++++++++++++++++++++++++--------------------- 4 files changed, 79 insertions(+), 165 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index b5b0aa52..6c626f66 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -289,7 +289,8 @@ typedef enum drm_map_flags { _DRM_KERNEL = 0x08, /**< kernel requires access */ _DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */ _DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */ - _DRM_REMOVABLE = 0x40 /**< Removable mapping */ + _DRM_REMOVABLE = 0x40, /**< Removable mapping */ + _DRM_DRIVER = 0x80 /**< Driver will take care of it */ } drm_map_flags_t; typedef struct drm_ctx_priv_map { diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index cf729c6f..2b29dbe2 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -88,16 +88,6 @@ int i915_dma_cleanup(drm_device_t * dev) if (dev->irq) drm_irq_uninstall(dev); - if (dev_priv->status_page_dmah) { - drm_pci_free(dev, dev_priv->status_page_dmah); - dev_priv->status_page_dmah = NULL; - dev_priv->hw_status_page = NULL; - dev_priv->dma_status_page = 0; - /* Need to rewrite hardware status page */ - I915_WRITE(0x02080, 0x1ffff000); - } - - dev_priv->sarea_priv = NULL; return 0; } @@ -106,39 +96,6 @@ static int i915_initialize(drm_device_t * dev, drm_i915_private_t * dev_priv, drm_i915_init_t * init) { - DRM_GETSAREA(); - if (!dev_priv->sarea) { - DRM_ERROR("can not find sarea!\n"); - dev->dev_private = (void *)dev_priv; - i915_dma_cleanup(dev); - return DRM_ERR(EINVAL); - } - - dev_priv->sarea_priv = (drm_i915_sarea_t *) - ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); - - 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) { - dev->dev_private = (void *)dev_priv; - i915_dma_cleanup(dev); - DRM_ERROR("can not ioremap virtual address for" - " ring buffer\n"); - return DRM_ERR(ENOMEM); - } - - dev_priv->ring.virtual_start = dev_priv->ring.map.handle; dev_priv->cpp = init->cpp; dev_priv->sarea_priv->pf_current_page = 0; @@ -152,27 +109,6 @@ static int i915_initialize(drm_device_t * dev, */ dev_priv->allow_batchbuffer = 1; - /* Program Hardware Status Page */ - 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 DRM_ERR(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); - DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); - - I915_WRITE(0x02080, dev_priv->dma_status_page); - DRM_DEBUG("Enabled hardware status page\n"); - -//drm_set_desired_modes(dev); - return 0; } @@ -182,29 +118,6 @@ static int i915_dma_resume(drm_device_t * dev) DRM_DEBUG("%s\n", __FUNCTION__); - if (!dev_priv->sarea) { - DRM_ERROR("can not find sarea!\n"); - return DRM_ERR(EINVAL); - } - - if (!dev_priv->mmio_map) { - DRM_ERROR("can not find mmio map!\n"); - return DRM_ERR(EINVAL); - } - - if (dev_priv->ring.map.handle == NULL) { - DRM_ERROR("can not ioremap virtual address for" - " ring buffer\n"); - return DRM_ERR(ENOMEM); - } - - /* Program Hardware Status Page */ - if (!dev_priv->hw_status_page) { - DRM_ERROR("Can not find hardware status page\n"); - return DRM_ERR(EINVAL); - } - DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); - I915_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); @@ -889,23 +802,4 @@ int i915_driver_device_is_agp(drm_device_t * dev) return 1; } -int i915_driver_firstopen(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - DRM_DEBUG("\n"); - - if (!dev_priv->mmio_map) { - ret = drm_addmap(dev, dev_priv->mmiobase, dev_priv->mmiolen, - _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio_map); - if (ret != 0) { - DRM_ERROR("Cannot add mapping for MMIO registers\n"); - return ret; - } - } - - DRM_DEBUG("dev_priv->mmio map is %p\n", dev_priv->mmio_map); - - return 0; -} diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index c22ab843..f4343014 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -89,6 +89,7 @@ typedef struct _drm_i915_vbl_swap { } drm_i915_vbl_swap_t; typedef struct drm_i915_private { + drm_buffer_object_t *ring_buffer; drm_local_map_t *sarea; drm_local_map_t *mmio_map; @@ -922,4 +923,6 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810)) +#define PRIMARY_RINGBUFFER_SIZE (128*1024) + #endif diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index f0ab4574..be702624 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -151,7 +151,7 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) } ret = drm_addmap(dev, dev_priv->mmiobase, dev_priv->mmiolen, - _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio_map); + _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; @@ -159,20 +159,13 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) /* prebuild the SAREA */ sareapage = max(SAREA_MAX, PAGE_SIZE); - ret = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK, - &map); + ret = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK|_DRM_DRIVER, + &dev_priv->sarea); if (ret) { DRM_ERROR("SAREA setup failed\n"); return ret; } - DRM_GETSAREA(); - if (!dev_priv->sarea) { - DRM_ERROR("can not find sarea!\n"); - dev->dev_private = (void *)dev_priv; - i915_dma_cleanup(dev); - return DRM_ERR(EINVAL); - } init_waitqueue_head(&dev->lock.lock_queue); /* FIXME: assume sarea_priv is right after SAREA */ @@ -187,61 +180,34 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, dev_priv->baseaddr, prealloc_size); - /* Allocate scanout buffer and command ring */ - /* FIXME: types and other args correct? */ - hsize = 1280; - vsize = 800; - bytes_per_pixel = 4; - size = hsize * vsize * bytes_per_pixel; - drm_buffer_object_create(dev, size, drm_bo_type_kernel, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE, - 0, PAGE_SIZE, 0, - &entry); - - intel_modeset_init(dev); - - fb = drm_framebuffer_create(dev); - if (!fb) { - DRM_ERROR("failed to allocate fb\n"); + 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_PRIV0 | + DRM_BO_FLAG_NO_MOVE, + DRM_BO_HINT_DONT_FENCE, 0x1, 0, + &dev_priv->ring_buffer); + if (ret < 0) { + DRM_ERROR("Unable to allocate ring buffer\n"); return -EINVAL; } - fb->width = hsize; - fb->height = vsize; - fb->pitch = hsize; - fb->bits_per_pixel = bytes_per_pixel * 8; - fb->depth = bytes_per_pixel * 8; - fb->offset = entry->offset; - fb->bo = entry; - - drm_initial_config(dev, fb, false); - drmfb_probe(dev, fb); -#if 0 - /* FIXME: command ring needs AGP space, do we own it at this point? */ - dev_priv->ring.Start = dev_priv->baseaddr; - dev_priv->ring.End = 128*1024; - dev_priv->ring.Size = 128*1024; + /* remap the buffer object properly */ + dev_priv->ring.Start = dev_priv->ring_buffer->offset + dev_priv->baseaddr; + dev_priv->ring.End = dev_priv->ring.Start + size; + dev_priv->ring.Size = size; dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; - dev_priv->ring.map.offset = dev_priv->ring.Start; - dev_priv->ring.map.size = dev_priv->ring.Size; - dev_priv->ring.map.type = 0; - dev_priv->ring.map.flags = 0; - dev_priv->ring.map.mtrr = 0; + dev_priv->ring.virtual_start = ioremap((dev_priv->ring.Start), (dev_priv->ring_buffer->mem.num_pages * PAGE_SIZE)); - drm_core_ioremap(&dev_priv->ring.map, dev); - if (dev_priv->ring.map.handle == NULL) { - dev->dev_private = (void *)dev_priv; - i915_dma_cleanup(dev); - DRM_ERROR("can not ioremap virtual address for" - " ring buffer\n"); - return DRM_ERR(ENOMEM); - } + DRM_DEBUG("ring start %08X, %08X, %08X\n", dev_priv->ring.Start, dev_priv->ring.virtual_start, dev_priv->ring.Size); + I915_WRITE(LP_RING + RING_HEAD, 0); + I915_WRITE(LP_RING + RING_TAIL, 0); + 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)); - dev_priv->ring.virtual_start = dev_priv->ring.map.handle; - dev_priv->cpp = 4; dev_priv->sarea_priv->pf_current_page = 0; /* We are using separate values as placeholders for mechanisms for @@ -271,8 +237,40 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) I915_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); + +#if 1 + /* Allocate scanout buffer and command ring */ + /* FIXME: types and other args correct? */ + hsize = 1280; + vsize = 800; + bytes_per_pixel = 4; + size = hsize * vsize * bytes_per_pixel; + drm_buffer_object_create(dev, size, drm_bo_type_kernel, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE, + 0, PAGE_SIZE, 0, + &entry); #endif + intel_modeset_init(dev); + +#if 1 + fb = drm_framebuffer_create(dev); + if (!fb) { + DRM_ERROR("failed to allocate fb\n"); + return -EINVAL; + } + fb->width = hsize; + fb->height = vsize; + fb->pitch = hsize; + fb->bits_per_pixel = bytes_per_pixel * 8; + fb->depth = bytes_per_pixel * 8; + fb->offset = entry->offset; + fb->bo = entry; + + drm_initial_config(dev, fb, false); + drmfb_probe(dev, fb); +#endif return 0; } @@ -281,7 +279,26 @@ int i915_driver_unload(drm_device_t *dev) drm_i915_private_t *dev_priv = dev->dev_private; struct drm_framebuffer *fb; + 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(0x02080, 0x1ffff000); + } + + I915_WRITE(LP_RING + RING_LEN, 0); + + iounmap(dev_priv->ring.virtual_start); + + drm_bo_driver_finish(dev); + intel_modeset_cleanup(dev); + DRM_DEBUG("%p, %p\n", dev_priv->mmio_map, dev_priv->sarea); + drm_rmmap(dev, dev_priv->mmio_map); + drm_rmmap(dev, dev_priv->sarea); + drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); dev->dev_private = NULL; @@ -296,7 +313,6 @@ void i915_driver_lastclose(drm_device_t * dev) i915_dma_cleanup(dev); - dev_priv->mmio_map = NULL; } void i915_driver_preclose(drm_device_t * dev, DRMFILE filp) -- cgit v1.2.3 From 65619cab276ba1f00014f9701b8347e2b834abe4 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Sat, 14 Apr 2007 15:35:21 -0700 Subject: Fix PRIV0 memory initialization (mm_init takes pages, not bytes), align fb allocation correctly, and use drm_mem_reg_iomap to map ring buffer object. --- shared-core/i915_init.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index be702624..273a1116 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -177,8 +177,9 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) drm_bo_driver_init(dev); i915_probe_agp(dev->pdev, &agp_size, &prealloc_size); + DRM_DEBUG("setting up %d bytes of PRIV0 space\n", prealloc_size); drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, dev_priv->baseaddr, - prealloc_size); + prealloc_size >> PAGE_SHIFT); size = PRIMARY_RINGBUFFER_SIZE; ret = drm_buffer_object_create(dev, size, drm_bo_type_kernel, @@ -198,8 +199,11 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) dev_priv->ring.Size = size; dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; - dev_priv->ring.virtual_start = ioremap((dev_priv->ring.Start), (dev_priv->ring_buffer->mem.num_pages * PAGE_SIZE)); + ret = drm_mem_reg_ioremap(dev, &dev_priv->ring_buffer->mem, + &dev_priv->ring.virtual_start); + if (ret) + DRM_ERROR("error mapping ring buffer: %d\n", ret); DRM_DEBUG("ring start %08X, %08X, %08X\n", dev_priv->ring.Start, dev_priv->ring.virtual_start, dev_priv->ring.Size); I915_WRITE(LP_RING + RING_HEAD, 0); @@ -248,7 +252,7 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) drm_buffer_object_create(dev, size, drm_bo_type_kernel, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE, - 0, PAGE_SIZE, 0, + 0, 0, 0, &entry); #endif intel_modeset_init(dev); -- cgit v1.2.3 From 79aa1d54746f33c33ffbf98fb96ccbf88c3cb390 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 17 Apr 2007 18:16:38 +1000 Subject: another large overhaul of interactions with userspace... We need to keep a list of user created fbs to nuke on master exit. We also need to use the bo properly. --- shared-core/i915_dma.c | 12 ++++++++++++ shared-core/i915_drv.h | 1 - shared-core/i915_init.c | 35 ++++++++++++++++++++++------------- 3 files changed, 34 insertions(+), 14 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 2b29dbe2..25172c1b 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -85,6 +85,8 @@ int i915_dma_cleanup(drm_device_t * dev) * may not have been called from userspace and after dev_private * is freed, it's too late. */ + I915_WRITE(LP_RING + RING_LEN, 0); + if (dev->irq) drm_irq_uninstall(dev); @@ -97,6 +99,16 @@ static int i915_initialize(drm_device_t * dev, drm_i915_init_t * init) { + /* reset ring pointers */ + I915_WRITE(LP_RING + RING_LEN, 0); + mb(); + + 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)); + + dev_priv->cpp = init->cpp; dev_priv->sarea_priv->pf_current_page = 0; diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index f4343014..8c2b4817 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -93,7 +93,6 @@ typedef struct drm_i915_private { drm_local_map_t *sarea; drm_local_map_t *mmio_map; - unsigned long baseaddr; unsigned long mmiobase; unsigned long mmiolen; diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 273a1116..2ed7a822 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -138,12 +138,12 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) 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 = dev_priv->baseaddr = + 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 = dev_priv->baseaddr = + dev->mode_config.fb_base = drm_get_resource_start(dev, 0) & 0xff000000; } else { DRM_ERROR("Unable to find MMIO registers\n"); @@ -178,14 +178,18 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) i915_probe_agp(dev->pdev, &agp_size, &prealloc_size); DRM_DEBUG("setting up %d bytes of PRIV0 space\n", prealloc_size); - drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, dev_priv->baseaddr, + drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, 0, prealloc_size >> PAGE_SHIFT); + I915_WRITE(LP_RING + RING_LEN, 0); + I915_WRITE(LP_RING + RING_HEAD, 0); + I915_WRITE(LP_RING + RING_TAIL, 0); + size = PRIMARY_RINGBUFFER_SIZE; ret = drm_buffer_object_create(dev, size, drm_bo_type_kernel, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MEM_PRIV0 | - DRM_BO_FLAG_NO_MOVE, + DRM_BO_FLAG_NO_EVICT, DRM_BO_HINT_DONT_FENCE, 0x1, 0, &dev_priv->ring_buffer); if (ret < 0) { @@ -194,23 +198,17 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) } /* remap the buffer object properly */ - dev_priv->ring.Start = dev_priv->ring_buffer->offset + dev_priv->baseaddr; + 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; - ret = drm_mem_reg_ioremap(dev, &dev_priv->ring_buffer->mem, &dev_priv->ring.virtual_start); if (ret) DRM_ERROR("error mapping ring buffer: %d\n", ret); DRM_DEBUG("ring start %08X, %08X, %08X\n", dev_priv->ring.Start, dev_priv->ring.virtual_start, dev_priv->ring.Size); - I915_WRITE(LP_RING + RING_HEAD, 0); - I915_WRITE(LP_RING + RING_TAIL, 0); - 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)); dev_priv->sarea_priv->pf_current_page = 0; @@ -294,11 +292,22 @@ int i915_driver_unload(drm_device_t *dev) I915_WRITE(LP_RING + RING_LEN, 0); - iounmap(dev_priv->ring.virtual_start); + intel_modeset_cleanup(dev); + + drm_mem_reg_iounmap(dev, &dev_priv->ring_buffer->mem, + dev_priv->ring.virtual_start); + + mutex_lock(&dev->struct_mutex); + drm_bo_usage_deref_locked(dev_priv->ring_buffer); + mutex_unlock(&dev->struct_mutex); + + if (drm_bo_clean_mm(dev, DRM_BO_MEM_PRIV0)) { + DRM_ERROR("Memory manager type 3 not clean. " + "Delaying takedown\n"); + } drm_bo_driver_finish(dev); - intel_modeset_cleanup(dev); DRM_DEBUG("%p, %p\n", dev_priv->mmio_map, dev_priv->sarea); drm_rmmap(dev, dev_priv->mmio_map); drm_rmmap(dev, dev_priv->sarea); -- cgit v1.2.3 From 32b5616cc681e404f671b4bc3b030ee24b753d4a Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Tue, 17 Apr 2007 16:08:26 +0100 Subject: Correct PCI ID for i845 --- shared-core/i915_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 2ed7a822..5872aeb3 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -45,7 +45,7 @@ int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size, switch (pdev->device) { case PCI_DEVICE_ID_INTEL_82830_CGC: - case PCI_DEVICE_ID_INTEL_82845G_HB: + 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) -- cgit v1.2.3 From eeb5de059401361871e34e29c456a1feebac0b1e Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 17 Apr 2007 09:59:21 -0700 Subject: Cleanup whitespace, rename macro argument. --- shared-core/i915_drv.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index f4343014..b0d70124 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -908,8 +908,8 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define IS_I855(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82855GM_IG) #define IS_I865G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82865_IG) -#define IS_I915G(pI810) (dev->pci_device == PCI_DEVICE_ID_INTEL_82915G_IG)/* || dev->pci_device == PCI_DEVICE_ID_INTELPCI_CHIP_E7221_G)*/ -#define IS_I915GM(pI810) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82915GM_IG) +#define IS_I915G(dev) (dev->pci_device == PCI_DEVICE_ID_INTEL_82915G_IG)/* || dev->pci_device == PCI_DEVICE_ID_INTELPCI_CHIP_E7221_G)*/ +#define IS_I915GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82915GM_IG) #define IS_I945G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945G_IG) #define IS_I945GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945GM_IG) @@ -919,9 +919,11 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); (dev)->pci_device == 0x29A2) -#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810)) +#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \ + IS_I945GM(dev) || IS_I965G(dev)) -#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810)) +#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ + IS_I945GM(dev)) #define PRIMARY_RINGBUFFER_SIZE (128*1024) -- cgit v1.2.3 From 4e4d9cbeb3f52b605e46aad8ae1a947ca236079f Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 17 Apr 2007 10:00:37 -0700 Subject: Move initial framebuffer allocation and configuration to drm_initial_config, remove i915_driver_load fb related stuff. Add a small helper for setting up outputs. --- shared-core/i915_init.c | 48 ++++++++---------------------------------------- 1 file changed, 8 insertions(+), 40 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 273a1116..b98f155b 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -112,13 +112,9 @@ int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size, int i915_driver_load(drm_device_t *dev, unsigned long flags) { drm_i915_private_t *dev_priv; - drm_i915_init_t init; - drm_buffer_object_t *entry; - drm_local_map_t *map; - struct drm_framebuffer *fb; unsigned long agp_size, prealloc_size; unsigned long sareapage; - int hsize, vsize, bytes_per_pixel, size, ret; + int size, ret; dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); if (dev_priv == NULL) @@ -150,6 +146,8 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) return -ENODEV; } + DRM_DEBUG("fb_base: 0x%08lx\n", dev_priv->baseaddr); + ret = drm_addmap(dev, dev_priv->mmiobase, dev_priv->mmiolen, _DRM_REGISTERS, _DRM_READ_ONLY|_DRM_DRIVER, &dev_priv->mmio_map); if (ret != 0) { @@ -177,7 +175,7 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) drm_bo_driver_init(dev); i915_probe_agp(dev->pdev, &agp_size, &prealloc_size); - DRM_DEBUG("setting up %d bytes of PRIV0 space\n", prealloc_size); + DRM_DEBUG("setting up %ld bytes of PRIV0 space\n", prealloc_size); drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, dev_priv->baseaddr, prealloc_size >> PAGE_SHIFT); @@ -199,13 +197,14 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) 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, &dev_priv->ring.virtual_start); if (ret) DRM_ERROR("error mapping ring buffer: %d\n", ret); - DRM_DEBUG("ring start %08X, %08X, %08X\n", dev_priv->ring.Start, dev_priv->ring.virtual_start, dev_priv->ring.Size); + DRM_DEBUG("ring start %08lX, %p, %08lX\n", dev_priv->ring.Start, + dev_priv->ring.virtual_start, dev_priv->ring.Size); I915_WRITE(LP_RING + RING_HEAD, 0); I915_WRITE(LP_RING + RING_TAIL, 0); I915_WRITE(LP_RING + RING_START, dev_priv->ring.Start); @@ -242,46 +241,15 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) I915_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); -#if 1 - /* Allocate scanout buffer and command ring */ - /* FIXME: types and other args correct? */ - hsize = 1280; - vsize = 800; - bytes_per_pixel = 4; - size = hsize * vsize * bytes_per_pixel; - drm_buffer_object_create(dev, size, drm_bo_type_kernel, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE, - 0, 0, 0, - &entry); -#endif intel_modeset_init(dev); + drm_initial_config(dev, false); -#if 1 - fb = drm_framebuffer_create(dev); - if (!fb) { - DRM_ERROR("failed to allocate fb\n"); - return -EINVAL; - } - - fb->width = hsize; - fb->height = vsize; - fb->pitch = hsize; - fb->bits_per_pixel = bytes_per_pixel * 8; - fb->depth = bytes_per_pixel * 8; - fb->offset = entry->offset; - fb->bo = entry; - - drm_initial_config(dev, fb, false); - drmfb_probe(dev, fb); -#endif return 0; } int i915_driver_unload(drm_device_t *dev) { drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_framebuffer *fb; if (dev_priv->status_page_dmah) { drm_pci_free(dev, dev_priv->status_page_dmah); -- cgit v1.2.3 From 7c9e19ba55dcdf212845253648194115639fe7b6 Mon Sep 17 00:00:00 2001 From: David Airlie Date: Fri, 13 Apr 2007 16:43:55 +1000 Subject: clean up ring buffer and TTM in i915_driver_unload I've commented out the framebuffer for now --- shared-core/i915_init.c | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 3e44dd54..0c9ef4d4 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -265,6 +265,7 @@ int i915_driver_unload(drm_device_t *dev) drm_mem_reg_iounmap(dev, &dev_priv->ring_buffer->mem, dev_priv->ring.virtual_start); + DRM_DEBUG("usage is %d\n", dev_priv->ring_buffer->usage); mutex_lock(&dev->struct_mutex); drm_bo_usage_deref_locked(dev_priv->ring_buffer); mutex_unlock(&dev->struct_mutex); -- cgit v1.2.3 From eb892fb09dc2e5206f2461e8b258495c7cef904a Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 20 Apr 2007 17:59:30 -0700 Subject: Add a monitor information structure separate from the EDID data for tracking monitor limits, etc. --- shared-core/drm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 6c626f66..b55640e1 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -893,6 +893,7 @@ typedef union drm_mm_init_arg{ /* * Drm mode setting */ +#define DRM_DISPLAY_INFO_LEN 32 #define DRM_OUTPUT_NAME_LEN 32 #define DRM_DISPLAY_MODE_LEN 32 -- cgit v1.2.3 From 0f3c5148f02bd98411095fdc8059207fa17b4a7d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 23 Apr 2007 09:10:46 +1000 Subject: fixup vrefresh reporting, it should now be *1000 in userspace --- shared-core/drm.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index b55640e1..d42bf73a 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -905,6 +905,8 @@ struct drm_mode_modeinfo { 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; char name[DRM_DISPLAY_MODE_LEN]; -- cgit v1.2.3 From 34be91fe4e9f0ad73b7c4354aea0c8ce10f45f68 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 26 Apr 2007 14:50:00 +1000 Subject: i915: fix vblank pipe setup --- shared-core/i915_drv.h | 1 + shared-core/i915_irq.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 2dd76d30..946e464f 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -237,6 +237,7 @@ extern int i915_vblank_pipe_get(DRM_IOCTL_ARGS); extern int i915_emit_irq(drm_device_t * dev); extern void i915_user_irq_on(drm_i915_private_t *dev_priv); extern void i915_user_irq_off(drm_i915_private_t *dev_priv); +extern void i915_enable_interrupt (drm_device_t *dev); extern int i915_vblank_swap(DRM_IOCTL_ARGS); /* i915_mem.c */ diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 4047e77e..870fe402 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -489,7 +489,7 @@ int i915_irq_wait(DRM_IOCTL_ARGS) return i915_wait_irq(dev, irqwait.irq_seq); } -static void i915_enable_interrupt (drm_device_t *dev) +void i915_enable_interrupt (drm_device_t *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; -- cgit v1.2.3 From 89231953d108e74ee7b0eb99494ead1dd795d640 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 1 May 2007 13:16:29 +1000 Subject: Add support for user defined modes This allows userspace to specify modes and add them to the modesetting system and attach modes to outputs --- shared-core/drm.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index d42bf73a..890dcf88 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -978,6 +978,11 @@ struct drm_mode_fb_cmd { unsigned int depth; }; +struct drm_mode_mode_cmd { + unsigned int output_id; + unsigned int mode_id; +}; + /** * \name Ioctls Definitions */ @@ -1055,7 +1060,12 @@ struct drm_mode_fb_cmd { #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_GETFB DRM_IOWR(0xA6, struct drm_mode_fb_cmd) + +#define DRM_IOCTL_MODE_ADDMODE DRM_IOWR(0xA7, struct drm_mode_modeinfo) +#define DRM_IOCTL_MODE_RMMODE DRM_IOWR(0xA8, unsigned int) +#define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd) +#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xAA, struct drm_mode_mode_cmd) /*@}*/ /** -- cgit v1.2.3 From eba00df1203040905d38bf0ef449d25d6dbdb72c Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Thu, 10 May 2007 13:16:05 +0100 Subject: Just some minor cleanups. --- shared-core/i915_drv.h | 1 + shared-core/i915_init.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 946e464f..0513eed8 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -221,6 +221,7 @@ extern void i915_emit_breadcrumb(drm_device_t *dev); extern void i915_dispatch_flip(drm_device_t * dev, int pipes, int sync); extern int i915_emit_mi_flush(drm_device_t *dev, uint32_t flush); extern int i915_driver_firstopen(struct drm_device *dev); +extern int i915_dma_cleanup(drm_device_t * dev); /* i915_irq.c */ extern int i915_irq_emit(DRM_IOCTL_ARGS); diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 0c9ef4d4..43040e6e 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -202,7 +202,7 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) /* FIXME: need wrapper with PCI mem checks */ ret = drm_mem_reg_ioremap(dev, &dev_priv->ring_buffer->mem, - &dev_priv->ring.virtual_start); + (void **) &dev_priv->ring.virtual_start); if (ret) DRM_ERROR("error mapping ring buffer: %d\n", ret); -- cgit v1.2.3 From a18b4befb9b76c4b2662ff6caa0e4f0975eb8e9c Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 17 May 2007 09:00:06 -0700 Subject: Fix FB pitch value (we had it wrong and were working around it in a few places). Add new FB hooks to the drm driver structure and make i915 use them for an Intel specific FB driver. This will allow acceleration and better handling of the command stream. --- shared-core/i915_dma.c | 2 +- shared-core/i915_drv.h | 9 +++++++++ shared-core/i915_init.c | 11 +++++++++-- 3 files changed, 19 insertions(+), 3 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 25172c1b..f4761da9 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -130,7 +130,7 @@ static int i915_dma_resume(drm_device_t * dev) DRM_DEBUG("%s\n", __FUNCTION__); - I915_WRITE(0x02080, dev_priv->dma_status_page); + I915_WRITE(I915REG_HWS_PGA, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); return 0; diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 946e464f..a99beaa9 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -317,6 +317,8 @@ extern void intel_modeset_cleanup(drm_device_t *dev); I915_WRITE(LP_RING + RING_TAIL, outring); \ } while(0) +#define MI_NOOP (0x00 << 23) + extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); /* @@ -356,6 +358,7 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define BB1_UNPROTECTED (0<<0) #define BB2_END_ADDR_MASK (~0x7) +#define I915REG_HWS_PGA 0x02080 #define I915REG_HWSTAM 0x02098 #define I915REG_INT_IDENTITY_R 0x020a4 #define I915REG_INT_MASK_R 0x020a8 @@ -460,8 +463,14 @@ extern int i915_wait_ring(drm_device_t * 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) diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 0c9ef4d4..510e853b 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -211,6 +211,13 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) dev_priv->sarea_priv->pf_current_page = 0; + memset((void *)(dev_priv->ring.virtual_start), 0, dev_priv->ring.Size); + + I915_WRITE(LP_RING + RING_START, dev_priv->ring.Start); + I915_WRITE(LP_RING + RING_LEN, + ((dev_priv->ring.Size - 4096) & RING_NR_PAGES) | + (RING_NO_REPORT | RING_VALID)); + /* We are using separate values as placeholders for mechanisms for * private backbuffer/depthbuffer usage. */ @@ -236,7 +243,7 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) memset(dev_priv->hw_status_page, 0, PAGE_SIZE); DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); - I915_WRITE(0x02080, dev_priv->dma_status_page); + I915_WRITE(I915REG_HWS_PGA, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); intel_modeset_init(dev); @@ -255,7 +262,7 @@ int i915_driver_unload(drm_device_t *dev) dev_priv->hw_status_page = NULL; dev_priv->dma_status_page = 0; /* Need to rewrite hardware status page */ - I915_WRITE(0x02080, 0x1ffff000); + I915_WRITE(I915REG_HWS_PGA, 0x1ffff000); } I915_WRITE(LP_RING + RING_LEN, 0); -- cgit v1.2.3 From 3851600b3450697e20286b1937f3e51397f1965a Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Fri, 18 May 2007 13:59:46 +0100 Subject: Fix merge problem. --- shared-core/drm.h | 1 - 1 file changed, 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 64536690..0f4a878b 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -789,7 +789,6 @@ typedef struct drm_fence_arg { typedef enum { drm_bo_type_dc, - drm_bo_type_kernel, /* for initial kernel allocations */ drm_bo_type_user, drm_bo_type_fake, drm_bo_type_kernel, /* for initial kernel allocations */ -- cgit v1.2.3 From e918d2b7814e2cf5345dba63031c402010b1d3e4 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 22 May 2007 13:38:58 -0700 Subject: Call preallocated space VRAM instead of PRIV0 to be more consistent with other drivers. --- shared-core/i915_init.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 61576aae..7516b2ce 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -175,8 +175,8 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) drm_bo_driver_init(dev); i915_probe_agp(dev->pdev, &agp_size, &prealloc_size); - DRM_DEBUG("setting up %ld bytes of PRIV0 space\n", prealloc_size); - drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, 0, prealloc_size >> PAGE_SHIFT); + DRM_DEBUG("setting up %ld bytes of VRAM space\n", prealloc_size); + drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, prealloc_size >> PAGE_SHIFT); I915_WRITE(LP_RING + RING_LEN, 0); I915_WRITE(LP_RING + RING_HEAD, 0); @@ -185,7 +185,7 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) 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_PRIV0 | + DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_NO_EVICT, DRM_BO_HINT_DONT_FENCE, 0x1, 0, &dev_priv->ring_buffer); @@ -277,7 +277,7 @@ int i915_driver_unload(drm_device_t *dev) drm_bo_usage_deref_locked(dev_priv->ring_buffer); mutex_unlock(&dev->struct_mutex); - if (drm_bo_clean_mm(dev, DRM_BO_MEM_PRIV0)) { + if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM)) { DRM_ERROR("Memory manager type 3 not clean. " "Delaying takedown\n"); } -- cgit v1.2.3 From 462d5a0dfc80dfa02da3d24d30ad90ad0387f0a2 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 22 May 2007 17:49:04 -0700 Subject: Suspend/resume support (incomplete). --- shared-core/i915_drv.h | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++ shared-core/i915_irq.c | 13 ++++++++ 2 files changed, 99 insertions(+) (limited to 'shared-core') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index c41fbbc5..b0aa5df1 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -227,6 +227,7 @@ extern int i915_dma_cleanup(drm_device_t * dev); extern int i915_irq_emit(DRM_IOCTL_ARGS); extern int i915_irq_wait(DRM_IOCTL_ARGS); +extern void i915_driver_wait_next_vblank(drm_device_t *dev, int pipe); extern int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence); extern int i915_driver_vblank_wait2(drm_device_t *dev, unsigned int *sequence); extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); @@ -395,6 +396,39 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); # 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 @@ -906,6 +940,58 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); # define VGA_2X_MODE (1 << 30) # define VGA_PIPE_B_SELECT (1 << 29) +/* + * Some BIOS scratch area registers. The 845 (and 830?) store the amount + * of video memory available to the BIOS in SWF1. + */ + +#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 SWF00 0x70410 +#define SWF01 0x70414 +#define SWF02 0x70418 +#define SWF03 0x7041c +#define SWF04 0x70420 +#define SWF05 0x70424 +#define SWF06 0x70428 + +#define SWF10 SWF0 +#define SWF11 SWF1 +#define SWF12 SWF2 +#define SWF13 SWF3 +#define SWF14 SWF4 +#define SWF15 SWF5 +#define SWF16 SWF6 + +#define SWF30 0x72414 +#define SWF31 0x72418 +#define SWF32 0x7241c + +/* + * Overlay registers. These are overlay registers accessed via MMIO. + * Those loaded via the overlay register page are defined in i830_video.c. + */ +#define OVADD 0x30000 + +#define DOVSTA 0x30008 +#define OC_BUF (0x3<<20) + +#define OGAMC5 0x30010 +#define OGAMC4 0x30014 +#define OGAMC3 0x30018 +#define OGAMC2 0x3001c +#define OGAMC1 0x30020 +#define OGAMC0 0x30024 + /* * Palette registers */ diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 4ceed3e3..2d4df76e 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -438,6 +438,19 @@ static int i915_driver_vblank_do_wait(drm_device_t *dev, unsigned int *sequence, return ret; } +void i915_driver_wait_next_vblank(drm_device_t *dev, int pipe) +{ + unsigned int seq; + + seq = pipe ? atomic_read(&dev->vbl_received2) + 1 : + atomic_read(&dev->vbl_received) + 1; + + if (!pipe) + i915_driver_vblank_do_wait(dev, &seq, &dev->vbl_received); + else + i915_driver_vblank_do_wait(dev, &seq, &dev->vbl_received2); +} + int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) { return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received); -- cgit v1.2.3 From 4294dcc050c5d2685f633e8a52deb925d806be85 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 5 Jun 2007 12:26:06 +1000 Subject: complete PCIE backend for ttm ttm test runs with it at least, needs to do more testing on it --- shared-core/radeon_cp.c | 20 ++++++++++++++++++++ shared-core/radeon_drv.h | 1 + 2 files changed, 21 insertions(+) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 56d17b9a..9dc871ca 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -1384,6 +1384,26 @@ 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) { + + + } else { + + + } + +} + static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) { drm_radeon_private_t *dev_priv = dev->dev_private; diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index c16a43eb..5a33231a 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -344,6 +344,7 @@ extern int radeon_cp_resume(DRM_IOCTL_ARGS); extern int radeon_engine_reset(DRM_IOCTL_ARGS); extern int radeon_fullscreen(DRM_IOCTL_ARGS); extern int radeon_cp_buffers(DRM_IOCTL_ARGS); +extern void radeon_gart_flush(struct drm_device *dev); extern void radeon_freelist_reset(drm_device_t * dev); extern drm_buf_t *radeon_freelist_get(drm_device_t * dev); -- cgit v1.2.3 From c9dbe0f2c2248ef8c3ba5718f77922d1c7429e6f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 5 Jun 2007 12:38:43 +1000 Subject: invalidate gart tlb on PCIE after table change --- shared-core/radeon_cp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 9dc871ca..2c0549e5 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -1395,8 +1395,11 @@ void radeon_gart_flush(struct drm_device *dev) 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 { -- cgit v1.2.3 From 14c49df06bb0b1adc0fa2a9bd575c454d39c7cf0 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Fri, 29 Jun 2007 20:14:09 +0100 Subject: merge fixes --- shared-core/i915_dma.c | 2 +- shared-core/i915_drv.h | 2 -- shared-core/i915_init.c | 3 +-- 3 files changed, 2 insertions(+), 5 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index c95f1857..59bf15ef 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -78,7 +78,7 @@ void i915_kernel_lost_context(drm_device_t * dev) dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; } -static int i915_dma_cleanup(drm_device_t * dev) +int i915_dma_cleanup(drm_device_t * dev) { /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 35451feb..35e5be1c 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -213,7 +213,6 @@ extern int i915_max_ioctl; extern void i915_kernel_lost_context(drm_device_t * dev); extern int i915_driver_load(struct drm_device *, unsigned long flags); extern int i915_driver_unload(drm_device_t *dev); -extern int i915_driver_firstopen(struct drm_device *dev); extern void i915_driver_lastclose(drm_device_t * dev); extern void i915_driver_preclose(drm_device_t * dev, DRMFILE filp); extern int i915_driver_device_is_agp(drm_device_t * dev); @@ -222,7 +221,6 @@ extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, extern void i915_emit_breadcrumb(drm_device_t *dev); extern void i915_dispatch_flip(drm_device_t * dev, int pipes, int sync); extern int i915_emit_mi_flush(drm_device_t *dev, uint32_t flush); -extern int i915_driver_firstopen(struct drm_device *dev); extern int i915_dma_cleanup(drm_device_t * dev); /* i915_irq.c */ diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 83219e49..e4a2cdef 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -275,7 +275,7 @@ int i915_driver_unload(drm_device_t *dev) 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); + drm_bo_usage_deref_locked(&dev_priv->ring_buffer); mutex_unlock(&dev->struct_mutex); if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM)) { @@ -302,7 +302,6 @@ void i915_driver_lastclose(drm_device_t * dev) i915_mem_takedown(&(dev_priv->agp_heap)); i915_dma_cleanup(dev); - } void i915_driver_preclose(drm_device_t * dev, DRMFILE filp) -- cgit v1.2.3 From adff58223f4568d084cf62d03d4ecfc3a6cec000 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Fri, 29 Jun 2007 20:58:16 +0100 Subject: Bring back code from merge that was accidentally removed. --- shared-core/i915_dma.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 59bf15ef..008adc0a 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -80,13 +80,41 @@ void i915_kernel_lost_context(drm_device_t * dev) int i915_dma_cleanup(drm_device_t * dev) { + drm_i915_private_t *dev_priv = (drm_i915_private_t *) 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. */ + I915_WRITE(LP_RING + RING_LEN, 0); + if (dev->irq) drm_irq_uninstall(dev); + if (dev->dev_private) { + drm_i915_private_t *dev_priv = + (drm_i915_private_t *) dev->dev_private; + + if (dev_priv->ring.virtual_start) { + drm_core_ioremapfree(&dev_priv->ring.map, dev); + } + + if (dev_priv->status_page_dmah) { + drm_pci_free(dev, dev_priv->status_page_dmah); + /* 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_free(dev->dev_private, sizeof(drm_i915_private_t), + DRM_MEM_DRIVER); + + dev->dev_private = NULL; + } + return 0; } -- cgit v1.2.3 From 70fd9351ed6c666def710fd61b542a7c975d9ac9 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Fri, 29 Jun 2007 21:04:17 +0100 Subject: Move out the code from i915_dma_cleanup to unload to match existing code. This needs verifying. --- shared-core/i915_dma.c | 24 ------------------------ shared-core/i915_init.c | 10 ++++++++++ 2 files changed, 10 insertions(+), 24 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 008adc0a..7dd68954 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -91,30 +91,6 @@ int i915_dma_cleanup(drm_device_t * dev) if (dev->irq) drm_irq_uninstall(dev); - if (dev->dev_private) { - drm_i915_private_t *dev_priv = - (drm_i915_private_t *) dev->dev_private; - - if (dev_priv->ring.virtual_start) { - drm_core_ioremapfree(&dev_priv->ring.map, dev); - } - - if (dev_priv->status_page_dmah) { - drm_pci_free(dev, dev_priv->status_page_dmah); - /* 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_free(dev->dev_private, sizeof(drm_i915_private_t), - DRM_MEM_DRIVER); - - dev->dev_private = NULL; - } - return 0; } diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index e4a2cdef..fd102b35 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -257,6 +257,10 @@ int i915_driver_unload(drm_device_t *dev) { drm_i915_private_t *dev_priv = dev->dev_private; + if (dev_priv->ring.virtual_start) { + drm_core_ioremapfree(&dev_priv->ring.map, dev); + } + if (dev_priv->status_page_dmah) { drm_pci_free(dev, dev_priv->status_page_dmah); dev_priv->status_page_dmah = NULL; @@ -266,6 +270,12 @@ int i915_driver_unload(drm_device_t *dev) I915_WRITE(I915REG_HWS_PGA, 0x1ffff000); } + if (dev_priv->status_gfx_addr) { + dev_priv->status_gfx_addr = 0; + drm_core_ioremapfree(&dev_priv->hws_map, dev); + I915_WRITE(I915REG_HWS_PGA, 0x1ffff000); + } + I915_WRITE(LP_RING + RING_LEN, 0); intel_modeset_cleanup(dev); -- cgit v1.2.3 From 0be6e919aa3e7af884980e2004755848a2aa7519 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 24 Sep 2007 15:40:55 -0700 Subject: Add 965GM macro bits Update IS_MOBILE macro to include new IS_I965GM test. --- shared-core/i915_drv.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index d6b64b61..2d2d3a20 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -1160,6 +1160,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); (dev)->pci_device == 0x2A02 || \ (dev)->pci_device == 0x2A12) +#define IS_I965GM(dev) (((dev)->pci_device == 0x2A02)) #define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \ IS_I945GM(dev) || IS_I965G(dev)) @@ -1169,7 +1170,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); (dev)->pci_device == 0x29D2) #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ - IS_I945GM(dev)) + IS_I945GM(dev) || IS_I965GM(dev)) #define PRIMARY_RINGBUFFER_SIZE (128*1024) -- cgit v1.2.3 From 972ec4fa25059c84ed103c28efcb17f9f97a6d74 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 25 Sep 2007 16:18:01 -0700 Subject: Hack out i915_mem_takedown We may want to make the old i915 memory manager obsolete eventually, and in the meantime the takedown causes problems on unload so remove it for now. --- shared-core/i915_init.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 065afcdf..918bbcb8 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -291,12 +291,12 @@ int i915_driver_unload(struct drm_device *dev) 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); - mutex_unlock(&dev->struct_mutex); if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM)) { DRM_ERROR("Memory manager type 3 not clean. " "Delaying takedown\n"); } + mutex_unlock(&dev->struct_mutex); drm_bo_driver_finish(dev); @@ -315,15 +315,14 @@ void i915_driver_lastclose(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; i915_do_cleanup_pageflip(dev); - - i915_mem_takedown(&(dev_priv->agp_heap)); - + //i915_mem_takedown(&(dev_priv->agp_heap)); i915_dma_cleanup(dev); } void i915_driver_preclose(struct drm_device *dev, struct drm_file *filp) { struct drm_i915_private *dev_priv = dev->dev_private; - i915_mem_release(dev, filp, dev_priv->agp_heap); + + //i915_mem_release(dev, filp, dev_priv->agp_heap); } -- cgit v1.2.3 From bf9bd5671c184e1caeeb25ead588cbb2ab77c360 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Thu, 27 Sep 2007 14:21:29 +0100 Subject: Create memory pool for TT memory --- shared-core/i915_init.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 918bbcb8..8e419b8a 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -175,8 +175,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) drm_bo_driver_init(dev); i915_probe_agp(dev->pdev, &agp_size, &prealloc_size); - DRM_DEBUG("setting up %ld bytes of VRAM space\n", prealloc_size); + printk("setting up %ld bytes of VRAM space\n", prealloc_size); + printk("setting up %ld bytes of TT space\n", (agp_size - prealloc_size)); drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, prealloc_size >> PAGE_SHIFT); + drm_bo_init_mm(dev, DRM_BO_MEM_TT, prealloc_size >> PAGE_SHIFT, (agp_size - prealloc_size) >> PAGE_SHIFT); I915_WRITE(LP_RING + RING_LEN, 0); I915_WRITE(LP_RING + RING_HEAD, 0); @@ -292,6 +294,10 @@ int i915_driver_unload(struct drm_device *dev) mutex_lock(&dev->struct_mutex); drm_bo_usage_deref_locked(&dev_priv->ring_buffer); + if (drm_bo_clean_mm(dev, DRM_BO_MEM_TT)) { + DRM_ERROR("Memory manager type 3 not clean. " + "Delaying takedown\n"); + } if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM)) { DRM_ERROR("Memory manager type 3 not clean. " "Delaying takedown\n"); -- cgit v1.2.3 From be2d68914d0992a37b9fb4d93338aeaf2240c4f5 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Wed, 17 Oct 2007 09:35:44 +0100 Subject: Fix a crash on X startup --- shared-core/i915_dma.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 23994821..54621d9e 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -86,8 +86,6 @@ int i915_dma_cleanup(struct drm_device * dev) * may not have been called from userspace and after dev_private * is freed, it's too late. */ - I915_WRITE(LP_RING + RING_LEN, 0); - if (dev->irq) drm_irq_uninstall(dev); @@ -1042,7 +1040,7 @@ int i915_do_cleanup_pageflip(struct drm_device * dev) DRM_DEBUG("%s\n", __FUNCTION__); - for (i = 0, planes = 0; i < 2; i++) + 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 & @@ -1050,6 +1048,7 @@ int i915_do_cleanup_pageflip(struct drm_device * dev) planes |= 1 << i; } + } if (planes) i915_dispatch_flip(dev, planes, 0); -- cgit v1.2.3 From d983ed90cb9de559271817e04bddc8b40fc16a0d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 9 Nov 2007 11:30:50 +1000 Subject: i915: cleanup pageflip derefs sarea even if no sarea exists --- shared-core/i915_dma.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 47befeb5..117f1265 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1070,10 +1070,12 @@ out_free: int i915_do_cleanup_pageflip(struct drm_device * dev) { struct drm_i915_private *dev_priv = dev->dev_private; - int i, planes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2; + int i, planes, num_pages; DRM_DEBUG("%s\n", __FUNCTION__); - + if (!dev_priv->sarea_priv) + return 0; + num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2; for (i = 0, planes = 0; i < 2; i++) { if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) { dev_priv->sarea_priv->pf_current_page = -- cgit v1.2.3 From 2520d3fd99636e493060d51b1c3287a5faac22bf Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 15 Nov 2007 16:52:04 +1100 Subject: modes: pass type to userspace for preferred showing --- shared-core/drm.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index e10ceb14..59cbfaf2 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -898,6 +898,14 @@ struct drm_mm_init_arg { #define DRM_OUTPUT_NAME_LEN 32 #define DRM_DISPLAY_MODE_LEN 32 +#define DRM_MODE_TYPE_BUILTIN (1<<0) +#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN) +#define DRM_MODE_TYPE_CRTC_C ((1<<2) | DRM_MODE_TYPE_BUILTIN) +#define DRM_MODE_TYPE_PREFERRED (1<<3) +#define DRM_MODE_TYPE_DEFAULT (1<<4) +#define DRM_MODE_TYPE_USERDEF (1<<5) +#define DRM_MODE_TYPE_DRIVER (1<<6) + struct drm_mode_modeinfo { unsigned int id; @@ -909,7 +917,7 @@ struct drm_mode_modeinfo { unsigned int vrefresh; /* vertical refresh * 1000 */ unsigned int flags; - + unsigned int type; char name[DRM_DISPLAY_MODE_LEN]; }; -- cgit v1.2.3 From b3af2b59a77a6916ea7151236d3da9bde6a537fc Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 27 Nov 2007 14:31:02 +1000 Subject: drm/modesetting: add initial gettable properites code. This allow the user to retrieve a list of properties for an output. Properties can either be 32-bit values or an enum with an associated name. Range properties are to be supported. This API is probably not all correct, I may make properties part of the general resource get when I think about it some more. So basically you can create properties and attached them to whatever outputs you want, so it should be possible to create some generics and just attach them to every output. --- shared-core/drm.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 55675d2f..9219b456 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -897,6 +897,7 @@ struct drm_mm_init_arg { #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) @@ -976,6 +977,32 @@ struct drm_mode_get_output { int count_modes; unsigned int __user *modes; /**< list of modes it supports */ + int count_props; + unsigned int __user *props; + unsigned int __user *prop_values; +}; + +#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 + +struct drm_mode_property_enum { + uint32_t value; + unsigned char name[DRM_PROP_NAME_LEN]; +}; + +struct drm_mode_get_property { + + unsigned int prop_id; + unsigned int flags; + unsigned char name[DRM_PROP_NAME_LEN]; + + int count_values; + uint32_t __user *values; + + int count_enums; + struct drm_mode_property_enum *enums; }; struct drm_mode_fb_cmd { @@ -1096,6 +1123,8 @@ struct drm_mode_mode_cmd { #define DRM_IOCTL_MODE_RMMODE DRM_IOWR(0xA8, unsigned int) #define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd) #define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xAA, struct drm_mode_mode_cmd) + +#define DRM_IOCTL_MODE_GETPROPERTY DRM_IOWR(0xAB, struct drm_mode_get_property) /*@}*/ /** -- cgit v1.2.3 From 91cd3e3c097d581ea75ec4bcbc1ba8d23b471a2e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 28 Nov 2007 15:18:25 +1000 Subject: modesetting API change for removing mode ids and making modes per output. so really want to get a list of modes per output not the global hammer list. also we remove the mode ids and let the user pass back the full mode description need to fix up add/remove mode for user modes now --- shared-core/drm.h | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 9219b456..5c24e0af 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -908,9 +908,6 @@ struct drm_mm_init_arg { #define DRM_MODE_TYPE_DRIVER (1<<6) struct drm_mode_modeinfo { - - unsigned int id; - unsigned int clock; unsigned short hdisplay, hsync_start, hsync_end, htotal, hskew; unsigned short vdisplay, vsync_start, vsync_end, vtotal, vscan; @@ -932,10 +929,6 @@ struct drm_mode_card_res { int count_outputs; unsigned int __user *output_id; - - int count_modes; - struct drm_mode_modeinfo __user *modes; - }; struct drm_mode_crtc { @@ -944,8 +937,6 @@ struct drm_mode_crtc { int x, y; /**< Position on the frameuffer */ - unsigned int mode; /**< Current mode used */ - int count_outputs; unsigned int outputs; /**< Outputs that are connected */ @@ -955,7 +946,8 @@ struct drm_mode_crtc { unsigned int __user *set_outputs; /**< Outputs to be connected */ int gamma_size; - + int mode_valid; + struct drm_mode_modeinfo mode; }; struct drm_mode_get_output { @@ -975,7 +967,7 @@ struct drm_mode_get_output { unsigned int clones; /**< list of clones */ int count_modes; - unsigned int __user *modes; /**< list of modes it supports */ + struct drm_mode_modeinfo *modes; int count_props; unsigned int __user *props; -- cgit v1.2.3 From 96df9b11ad8974d7a2a0a589114cbbb04a584f18 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Dec 2007 13:42:32 +1000 Subject: finish of mode add/remove, just have attach/detach modes --- shared-core/drm.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 5c24e0af..f4f75cf5 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1008,7 +1008,7 @@ struct drm_mode_fb_cmd { struct drm_mode_mode_cmd { unsigned int output_id; - unsigned int mode_id; + struct drm_mode_modeinfo mode; }; /** @@ -1111,8 +1111,6 @@ struct drm_mode_mode_cmd { #define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xA5, unsigned int) #define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xA6, struct drm_mode_fb_cmd) -#define DRM_IOCTL_MODE_ADDMODE DRM_IOWR(0xA7, struct drm_mode_modeinfo) -#define DRM_IOCTL_MODE_RMMODE DRM_IOWR(0xA8, unsigned int) #define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd) #define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xAA, struct drm_mode_mode_cmd) -- cgit v1.2.3 From 34797ff67c16beb9c331920f663bdf8387c14c78 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sun, 2 Dec 2007 23:48:45 +0100 Subject: radeon_ms: radeon modesetting first commit. This should work on all radeon but there is still many things todo: - add crtc2 - tmds - lvds - add bios data table so we don't need to hardcode dac/crtc infos - separate clock control to make power saving easier & cleaner - tiling (warning tiling shouldn't be enable in double scan or interlace) - surface reg manager (this goes along with tiling) - suspend/resume hook - avivo & r500 family support - atom bios support (for posting card mostly) - finish superioctl skeleton - what else ? :) --- shared-core/drm_pciids.txt | 4 + shared-core/radeon_ms.h | 607 +++++++++++++++ shared-core/radeon_ms_bo.c | 311 ++++++++ shared-core/radeon_ms_bus.c | 443 +++++++++++ shared-core/radeon_ms_cp.c | 341 +++++++++ shared-core/radeon_ms_cp_mc.c | 801 +++++++++++++++++++ shared-core/radeon_ms_crtc.c | 769 +++++++++++++++++++ shared-core/radeon_ms_dac.c | 400 ++++++++++ shared-core/radeon_ms_drm.c | 299 ++++++++ shared-core/radeon_ms_drm.h | 60 ++ shared-core/radeon_ms_exec.c | 242 ++++++ shared-core/radeon_ms_family.c | 229 ++++++ shared-core/radeon_ms_fence.c | 129 ++++ shared-core/radeon_ms_gpu.c | 589 ++++++++++++++ shared-core/radeon_ms_i2c.c | 279 +++++++ shared-core/radeon_ms_irq.c | 160 ++++ shared-core/radeon_ms_output.c | 333 ++++++++ shared-core/radeon_ms_reg.h | 1655 ++++++++++++++++++++++++++++++++++++++++ shared-core/radeon_ms_state.c | 45 ++ 19 files changed, 7696 insertions(+) create mode 100644 shared-core/radeon_ms.h create mode 100644 shared-core/radeon_ms_bo.c create mode 100644 shared-core/radeon_ms_bus.c create mode 100644 shared-core/radeon_ms_cp.c create mode 100644 shared-core/radeon_ms_cp_mc.c create mode 100644 shared-core/radeon_ms_crtc.c create mode 100644 shared-core/radeon_ms_dac.c create mode 100644 shared-core/radeon_ms_drm.c create mode 100644 shared-core/radeon_ms_drm.h create mode 100644 shared-core/radeon_ms_exec.c create mode 100644 shared-core/radeon_ms_family.c create mode 100644 shared-core/radeon_ms_fence.c create mode 100644 shared-core/radeon_ms_gpu.c create mode 100644 shared-core/radeon_ms_i2c.c create mode 100644 shared-core/radeon_ms_irq.c create mode 100644 shared-core/radeon_ms_output.c create mode 100644 shared-core/radeon_ms_reg.h create mode 100644 shared-core/radeon_ms_state.c (limited to 'shared-core') diff --git a/shared-core/drm_pciids.txt b/shared-core/drm_pciids.txt index 05d32f2e..a76413d4 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/radeon_ms.h b/shared-core/radeon_ms.h new file mode 100644 index 00000000..ee795f3a --- /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 + */ +#ifndef __RADEON_MS_H__ +#define __RADEON_MS_H__ + +#include "radeon_ms_drv.h" +#include "radeon_ms_reg.h" +#include "radeon_ms_drm.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 + +#define RADEON_PAGE_SIZE 4096 +#define RADEON_MAX_CONNECTORS 8 +#define RADEON_MAX_OUTPUTS 8 + +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_ms_properties { + uint16_t subvendor; + uint16_t subdevice; + int16_t pll_reference_freq; + 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]; +}; + +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_properties *properties; + 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; +}; + + +/* 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); +uint32_t radeon_ms_evict_mask(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_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); +void 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); +void radeon_ms_outputs_destroy(struct drm_device *dev); +int radeon_ms_outputs_from_properties(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_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..cedad689 --- /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 + * Jerome Glisse + */ +#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.mask = 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_bind_ttm(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; +} + +uint32_t radeon_ms_evict_mask(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..6a782b1c --- /dev/null +++ b/shared-core/radeon_ms_bus.c @@ -0,0 +1,443 @@ +/* + * 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 + * Jerome Glisse + */ +#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; + 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); +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]; + /* 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 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) +{ + 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; + + 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"); + 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; + + /* 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"); + 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_cp.c b/shared-core/radeon_ms_cp.c new file mode 100644 index 00000000..7426facb --- /dev/null +++ b/shared-core/radeon_ms_cp.c @@ -0,0 +1,341 @@ +/* + * 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 + */ +#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; + + 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; + + 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..a9387f96 --- /dev/null +++ b/shared-core/radeon_ms_crtc.c @@ -0,0 +1,769 @@ +/* + * 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 n/d with rounding */ +static int radeon_div(int n, int d) +{ + return (n + (d / 2)) / d; +} + +/* compute PLL registers values for requested video mode */ +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; + unsigned long freq = mode->clock / 10; + int pll_output_freq; + int min_rcenter_dist; + int rcenter_dist; + int post_divider; + int post_divider_id; + int ref_div; + int fb_div; + int vco_freq; + int vco_gain; + + /* clamp frequency into pll [min; max] frequency range */ + if (freq > dev_priv->properties->pll_max_pll_freq) { + freq = dev_priv->properties->pll_max_pll_freq; + } + if (freq < dev_priv->properties->pll_min_pll_freq) { + freq = dev_priv->properties->pll_min_pll_freq; + } + /* select divider so that pll output frequency is the nearest to + * the center of [350; 125]Mhz range */ + min_rcenter_dist = 350 * 100; + post_divider = post_divs[0].divider; + post_divider_id = post_divs[0].divider_id; + for (post_div = &post_divs[0]; post_div->divider; ++post_div) { + if (post_div->divider == 0) + break; + /* pll output frequency (before post divider) */ + pll_output_freq = post_div->divider * freq; + /* compute distance to [350; 125] range center*/ + rcenter_dist = abs(pll_output_freq - 11250); + if (rcenter_dist < min_rcenter_dist) { + min_rcenter_dist = rcenter_dist; + post_divider = post_div->divider; + post_divider_id = post_div->divider_id; + } + } + pll_output_freq = post_divider * freq; + /* select first feedback */ + state->clock_cntl_index = REG_S(CLOCK_CNTL_INDEX, PPLL_DIV_SEL, 0); + /* set ref div so that ref_freq/ref_div is in middle of [2; 3.3]Mhz */ + ref_div = dev_priv->properties->pll_reference_freq / 265; + state->ppll_ref_div = REG_S(PPLL_REF_DIV, PPLL_REF_DIV, ref_div) | + REG_S(PPLL_REF_DIV, PPLL_REF_DIV_ACC, ref_div); + fb_div = radeon_div(pll_output_freq * ref_div, + dev_priv->properties->pll_reference_freq); + state->ppll_div_0 = REG_S(PPLL_DIV_0, PPLL_FB0_DIV, fb_div) | + REG_S(PPLL_DIV_0, PPLL_POST0_DIV, post_divider_id); + /* configure vco gain */ + state->ppll_cntl = PPLL_R(PPLL_CNTL); + vco_gain = REG_G(PPLL_CNTL, PPLL_PVG, state->ppll_cntl); + vco_freq = (fb_div * dev_priv->properties->pll_reference_freq) / + ref_div; + /* This is horribly crude: the VCO frequency range is divided into + * 3 parts, each part having a fixed PLL gain value. + */ + if (vco_freq >= 30000) { + /* [300..max] MHz : 7 */ + vco_gain = 7; + } else if (vco_freq >= 18000) { + /* [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; +} + +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->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..297623a0 --- /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..b22c83a7 --- /dev/null +++ b/shared-core/radeon_ms_drm.c @@ -0,0 +1,299 @@ +/* + * 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 + */ +#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_mask = radeon_ms_evict_mask, + .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); + 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); + dev_priv->bus_ready = 1; + + /* initialize ttm */ + ret = drm_bo_init_mm(dev, DRM_BO_MEM_TT, 0, + dev_priv->gpu_gart_size / RADEON_PAGE_SIZE); + 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_properties(dev); + if (ret != 0) { + radeon_ms_driver_unload(dev); + return ret; + } + ret = radeon_ms_connectors_from_properties(dev); + if (ret != 0) { + radeon_ms_driver_unload(dev); + return 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)) { + 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)) { + 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 + */ +#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 + */ +#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..ea5f6ca3 --- /dev/null +++ b/shared-core/radeon_ms_family.c @@ -0,0 +1,229 @@ +/* + * 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 + */ +#include "drmP.h" +#include "drm.h" +#include "radeon_ms.h" + +static 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 +}; + +static 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 +}; + +static 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" +}; + +static 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" +}; + +static struct radeon_ms_properties properties[] = { + /* default only one VGA connector */ + { + 0, 0, 2700, 2500, 20000, 1, 1, 1, 1, + { + &radeon_ms_dac1, NULL, NULL, NULL, NULL, NULL, NULL, + NULL + }, + { + &radeon_ms_vga, NULL, NULL, NULL, NULL, NULL, NULL, + NULL + } + }, + { + 0x1043, 0x176, 2700, 2500, 20000, 1, 1, 1, 1, + { + &radeon_ms_dac1, &radeon_ms_dac2, NULL, NULL, NULL, + NULL, NULL, NULL + }, + { + &radeon_ms_vga, &radeon_ms_dvi_i_2, NULL, NULL, NULL, + NULL, NULL, NULL + } + }, + { + 0x1002, 0x4150, 2700, 2500, 20000, 1, 1, 1, 1, + { + &radeon_ms_dac1, &radeon_ms_dac2, NULL, NULL, NULL, + NULL, NULL, NULL + }, + { + &radeon_ms_vga, &radeon_ms_dvi_i_2, NULL, NULL, NULL, + NULL, NULL, NULL + } + }, +}; + +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 i; + + 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; + } + dev_priv->properties = NULL; + 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); + dev_priv->properties = &properties[i]; + } + } + if (dev_priv->properties == NULL) { + dev_priv->properties = &properties[0]; + } + return 0; +} diff --git a/shared-core/radeon_ms_fence.c b/shared-core/radeon_ms_fence.c new file mode 100644 index 00000000..96bb0858 --- /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 + */ +#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) { + 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..1801c496 --- /dev/null +++ b/shared-core/radeon_ms_i2c.c @@ -0,0 +1,279 @@ +/* + * 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; + 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; + 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; + 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; + 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\n", + i2c->adapter.name); + goto out_free; + } + DRM_INFO("[radeon_ms] registered I2C '%s' bus\n", i2c->adapter.name); + 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..24182c75 --- /dev/null +++ b/shared-core/radeon_ms_irq.c @@ -0,0 +1,160 @@ +/* + * 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 + */ +#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); +} + +void radeon_ms_irq_postinstall(struct drm_device * dev) +{ + radeon_ms_irq_enable(dev); +} + +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..4d6cb01e --- /dev/null +++ b/shared-core/radeon_ms_output.c @@ -0,0 +1,333 @@ +/* + * 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; + } + 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; +} + +static 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; + + 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->name); + if (output == NULL) { + radeon_ms_connectors_destroy(dev); + return -EINVAL; + } + connector->output = output; + output->driver_private = connector; + output->possible_crtcs = 0x3; + dev_priv->connectors[i] = connector; + } + } + 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; + + 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]); + } + } + 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_reg.h b/shared-core/radeon_ms_reg.h new file mode 100644 index 00000000..d450280c --- /dev/null +++ b/shared-core/radeon_ms_reg.h @@ -0,0 +1,1655 @@ +/* + * 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 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_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 + */ +#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); +} -- cgit v1.2.3 From 1a6c95ef711fce807659ab5e4fe480d65ac233b6 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 5 Dec 2007 16:03:05 +1000 Subject: arrgggh.. make all ioctl structs 32/64-bit compatible hopefully. This also starts to add blob property support. someone needs to check this work for other things like ppc/x86 alignment diffs --- shared-core/drm.h | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index f4f75cf5..6317f142 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -920,18 +920,19 @@ struct drm_mode_modeinfo { }; struct drm_mode_card_res { - + uint64_t fb_id_ptr; + uint64_t crtc_id_ptr; + uint64_t output_id_ptr; int count_fbs; - unsigned int __user *fb_id; - int count_crtcs; - unsigned int __user *crtc_id; - int count_outputs; - unsigned int __user *output_id; + int 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 */ @@ -942,9 +943,6 @@ struct drm_mode_crtc { int count_possibles; unsigned int possibles; /**< Outputs that can be connected */ - - unsigned int __user *set_outputs; /**< Outputs to be connected */ - int gamma_size; int mode_valid; struct drm_mode_modeinfo mode; @@ -952,6 +950,12 @@ struct drm_mode_crtc { 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 char name[DRM_OUTPUT_NAME_LEN]; @@ -959,42 +963,37 @@ struct drm_mode_get_output { unsigned int connection; unsigned int mm_width, mm_height; /**< HxW in millimeters */ unsigned int subpixel; - int count_crtcs; - unsigned int crtcs; /**< possible crtc to connect to */ - int count_clones; + unsigned int crtcs; /**< possible crtc to connect to */ unsigned int clones; /**< list of clones */ - - int count_modes; - struct drm_mode_modeinfo *modes; - - int count_props; - unsigned int __user *props; - unsigned int __user *prop_values; }; #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 { - uint32_t value; + uint64_t value; unsigned char name[DRM_PROP_NAME_LEN]; }; + +struct drm_mode_property_blob { + uint32_t length; +}; struct drm_mode_get_property { + uint64_t values_ptr; + uint64_t enum_blob_ptr; unsigned int prop_id; unsigned int flags; unsigned char name[DRM_PROP_NAME_LEN]; int count_values; - uint32_t __user *values; - - int count_enums; - struct drm_mode_property_enum *enums; + int count_enum_blobs; }; struct drm_mode_fb_cmd { @@ -1111,6 +1110,7 @@ struct drm_mode_mode_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_GETPROPBLOB DRM_IOWR(0xA8, struct drm_mode_get_propblob) #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) -- cgit v1.2.3 From c9cda51af5a8bea1d30ce575ae260de52950fe2f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 5 Dec 2007 16:31:35 +1000 Subject: more WIP on blobs.. I'm going to pass back a list of blob ids and lengths in the getproperty. will need another ioctl to return the blob data as it is variable length. --- shared-core/drm.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 6317f142..7649abd6 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -981,12 +981,13 @@ struct drm_mode_property_enum { }; struct drm_mode_property_blob { + uint64_t data_ptr; uint32_t length; }; struct drm_mode_get_property { - uint64_t values_ptr; - uint64_t enum_blob_ptr; + 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; -- cgit v1.2.3 From 67f6eb1eb8d3dc5bb5fdb097655d3da326f637c1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 6 Dec 2007 10:44:51 +1000 Subject: add property blobs and edid reporting support --- shared-core/drm.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 7649abd6..0c66f85c 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -980,11 +980,6 @@ struct drm_mode_property_enum { unsigned char name[DRM_PROP_NAME_LEN]; }; -struct drm_mode_property_blob { - uint64_t data_ptr; - uint32_t length; -}; - struct drm_mode_get_property { uint64_t values_ptr; /* values and blob lengths */ uint64_t enum_blob_ptr; /* enum and blob id ptrs */ @@ -997,6 +992,12 @@ struct drm_mode_get_property { int count_enum_blobs; }; +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; @@ -1111,7 +1112,7 @@ struct drm_mode_mode_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_GETPROPBLOB DRM_IOWR(0xA8, struct drm_mode_get_propblob) +#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) -- cgit v1.2.3 From 3a51a8077bf55ba9d18805f2f03b78eb980fa982 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 6 Dec 2007 22:38:44 +0100 Subject: radeon_ms: avoid to unintialize things which haven't been initialized --- shared-core/radeon_ms_bus.c | 10 ++++++++++ shared-core/radeon_ms_cp.c | 4 ++++ shared-core/radeon_ms_drm.c | 1 - shared-core/radeon_ms_fence.c | 2 +- 4 files changed, 15 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_ms_bus.c b/shared-core/radeon_ms_bus.c index 6a782b1c..d50c9fb8 100644 --- a/shared-core/radeon_ms_bus.c +++ b/shared-core/radeon_ms_bus.c @@ -205,6 +205,12 @@ static int pcie_ttm_unbind(struct drm_ttm_backend *backend) 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; } @@ -217,6 +223,7 @@ int radeon_ms_agp_init(struct drm_device *dev) 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; @@ -256,6 +263,7 @@ int radeon_ms_agp_init(struct drm_device *dev) 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; } @@ -328,6 +336,7 @@ int radeon_ms_pcie_init(struct drm_device *dev) 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) { @@ -401,6 +410,7 @@ int radeon_ms_pcie_init(struct drm_device *dev) 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; } diff --git a/shared-core/radeon_ms_cp.c b/shared-core/radeon_ms_cp.c index 7426facb..c01769bd 100644 --- a/shared-core/radeon_ms_cp.c +++ b/shared-core/radeon_ms_cp.c @@ -101,6 +101,9 @@ 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"); @@ -126,6 +129,7 @@ int radeon_ms_cp_init(struct drm_device *dev) 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; diff --git a/shared-core/radeon_ms_drm.c b/shared-core/radeon_ms_drm.c index b22c83a7..8d0481e1 100644 --- a/shared-core/radeon_ms_drm.c +++ b/shared-core/radeon_ms_drm.c @@ -173,7 +173,6 @@ int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags) return ret; } radeon_ms_gpu_restore(dev, &dev_priv->driver_state); - dev_priv->bus_ready = 1; /* initialize ttm */ ret = drm_bo_init_mm(dev, DRM_BO_MEM_TT, 0, diff --git a/shared-core/radeon_ms_fence.c b/shared-core/radeon_ms_fence.c index 96bb0858..6fcf5437 100644 --- a/shared-core/radeon_ms_fence.c +++ b/shared-core/radeon_ms_fence.c @@ -54,7 +54,7 @@ int radeon_ms_fence_emit_sequence(struct drm_device *dev, uint32_t class, struct drm_radeon_private *dev_priv = dev->dev_private; uint32_t fence_id, cmd[2], i, ret; - if (!dev_priv || !dev_priv->cp_ready) { + if (!dev_priv || dev_priv->cp_ready != 1) { return -EINVAL; } fence_id = (++dev_priv->fence_id_last); -- cgit v1.2.3 From a39560e767f8d66508f7cf98222199b2cc96fcaf Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 6 Dec 2007 23:19:52 +0100 Subject: radeon_ms: update to lastest fb change --- shared-core/radeon_ms_output.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'shared-core') diff --git a/shared-core/radeon_ms_output.c b/shared-core/radeon_ms_output.c index 4d6cb01e..35e5c376 100644 --- a/shared-core/radeon_ms_output.c +++ b/shared-core/radeon_ms_output.c @@ -164,6 +164,10 @@ static int radeon_ms_output_get_modes(struct drm_output *output) 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; -- cgit v1.2.3 From 9d064966d8495038921d0e731c0bfca0cd58d244 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sat, 8 Dec 2007 00:45:33 +0100 Subject: radeon_ms: fix pll computation to follow hw constraint --- shared-core/radeon_ms_crtc.c | 127 +++++++++++++++++++++++++---------------- shared-core/radeon_ms_family.c | 6 +- 2 files changed, 82 insertions(+), 51 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_ms_crtc.c b/shared-core/radeon_ms_crtc.c index a9387f96..fe89e5e4 100644 --- a/shared-core/radeon_ms_crtc.c +++ b/shared-core/radeon_ms_crtc.c @@ -379,13 +379,26 @@ static void radeon_ms_crtc_mode_prepare(struct drm_crtc *crtc) crtc->funcs->dpms(crtc, DPMSModeOff); } -/* Compute n/d with rounding */ -static int radeon_div(int n, int d) +/* compute PLL registers values for requested video mode */ +static int radeon_pll1_constraint(int clock, int rdiv, + int fdiv, int pdiv, + int rfrq, int pfrq) { - return (n + (d / 2)) / d; + int dfrq; + + if (rdiv < 2 || fdiv < 4) { + return 0; + } + dfrq = rfrq / rdiv; + if (dfrq < 2000 || dfrq > 3300) { + return 0; + } + if (pfrq < 125000 || pfrq > 250000) { + return 0; + } + return 1; } -/* compute PLL registers values for requested video mode */ static void radeon_pll1_compute(struct drm_crtc *crtc, struct drm_display_mode *mode) { @@ -410,65 +423,73 @@ static void radeon_pll1_compute(struct drm_crtc *crtc, }; struct drm_radeon_private *dev_priv = crtc->dev->dev_private; struct radeon_state *state = &dev_priv->driver_state; - unsigned long freq = mode->clock / 10; - int pll_output_freq; - int min_rcenter_dist; - int rcenter_dist; - int post_divider; - int post_divider_id; - int ref_div; - int fb_div; + 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 (freq > dev_priv->properties->pll_max_pll_freq) { - freq = dev_priv->properties->pll_max_pll_freq; + if (clock > dev_priv->properties->pll_max_pll_freq) { + clock = dev_priv->properties->pll_max_pll_freq; } - if (freq < dev_priv->properties->pll_min_pll_freq) { - freq = dev_priv->properties->pll_min_pll_freq; + if ((clock * 12) < dev_priv->properties->pll_min_pll_freq) { + clock = dev_priv->properties->pll_min_pll_freq / 12; } - /* select divider so that pll output frequency is the nearest to - * the center of [350; 125]Mhz range */ - min_rcenter_dist = 350 * 100; - post_divider = post_divs[0].divider; - post_divider_id = post_divs[0].divider_id; + + /* 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) + if (post_div->divider == 0) { break; - /* pll output frequency (before post divider) */ - pll_output_freq = post_div->divider * freq; - /* compute distance to [350; 125] range center*/ - rcenter_dist = abs(pll_output_freq - 11250); - if (rcenter_dist < min_rcenter_dist) { - min_rcenter_dist = rcenter_dist; - post_divider = post_div->divider; - post_divider_id = post_div->divider_id; + } + tfrq = clock * post_div->divider; + for (fdiv = 1023; fdiv >= 4; fdiv--) { + rdiv = (fdiv * rfrq) / tfrq; + if (radeon_pll1_constraint(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; + } + } } } - pll_output_freq = post_divider * freq; - /* select first feedback */ - state->clock_cntl_index = REG_S(CLOCK_CNTL_INDEX, PPLL_DIV_SEL, 0); - /* set ref div so that ref_freq/ref_div is in middle of [2; 3.3]Mhz */ - ref_div = dev_priv->properties->pll_reference_freq / 265; - state->ppll_ref_div = REG_S(PPLL_REF_DIV, PPLL_REF_DIV, ref_div) | - REG_S(PPLL_REF_DIV, PPLL_REF_DIV_ACC, ref_div); - fb_div = radeon_div(pll_output_freq * ref_div, - dev_priv->properties->pll_reference_freq); - state->ppll_div_0 = REG_S(PPLL_DIV_0, PPLL_FB0_DIV, fb_div) | - REG_S(PPLL_DIV_0, PPLL_POST0_DIV, post_divider_id); - /* configure vco gain */ - state->ppll_cntl = PPLL_R(PPLL_CNTL); - vco_gain = REG_G(PPLL_CNTL, PPLL_PVG, state->ppll_cntl); - vco_freq = (fb_div * dev_priv->properties->pll_reference_freq) / - ref_div; + 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 >= 30000) { + if (vco_freq >= 300000) { /* [300..max] MHz : 7 */ vco_gain = 7; - } else if (vco_freq >= 18000) { + } else if (vco_freq >= 180000) { /* [180..300) MHz : 4 */ vco_gain = 4; } else { @@ -479,6 +500,16 @@ static void radeon_pll1_compute(struct drm_crtc *crtc, 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, diff --git a/shared-core/radeon_ms_family.c b/shared-core/radeon_ms_family.c index ea5f6ca3..779595d6 100644 --- a/shared-core/radeon_ms_family.c +++ b/shared-core/radeon_ms_family.c @@ -76,7 +76,7 @@ static struct radeon_ms_connector radeon_ms_dvi_i_2 = { static struct radeon_ms_properties properties[] = { /* default only one VGA connector */ { - 0, 0, 2700, 2500, 20000, 1, 1, 1, 1, + 0, 0, 27000, 25000, 200000, 1, 1, 1, 1, { &radeon_ms_dac1, NULL, NULL, NULL, NULL, NULL, NULL, NULL @@ -87,7 +87,7 @@ static struct radeon_ms_properties properties[] = { } }, { - 0x1043, 0x176, 2700, 2500, 20000, 1, 1, 1, 1, + 0x1043, 0x176, 27000, 25000, 200000, 1, 1, 1, 1, { &radeon_ms_dac1, &radeon_ms_dac2, NULL, NULL, NULL, NULL, NULL, NULL @@ -98,7 +98,7 @@ static struct radeon_ms_properties properties[] = { } }, { - 0x1002, 0x4150, 2700, 2500, 20000, 1, 1, 1, 1, + 0x1002, 0x4150, 27000, 25000, 200000, 1, 1, 1, 1, { &radeon_ms_dac1, &radeon_ms_dac2, NULL, NULL, NULL, NULL, NULL, NULL -- cgit v1.2.3 From 3b6786e3e6523b1ceca3645ea4c6081f170d2134 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 11 Dec 2007 14:46:51 +1000 Subject: modesetting: add dpms property and initial settable property ioctl --- shared-core/drm.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 0c66f85c..df43802f 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -992,6 +992,12 @@ struct drm_mode_get_property { 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; @@ -1112,6 +1118,7 @@ struct drm_mode_mode_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(0xAB, struct drm_mode_set_output_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) -- cgit v1.2.3 From f99dea7db00dd46aa96eaed3a61dff9c956fd86f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 11 Dec 2007 15:56:48 +1000 Subject: modesetting: fixup property setting and add connector property --- shared-core/drm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index df43802f..f13e36c9 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1118,7 +1118,7 @@ struct drm_mode_mode_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(0xAB, struct drm_mode_set_output_property) +#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) -- cgit v1.2.3 From e239882b1e90cba0297118ec7dc432bea06b0bd0 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 4 Dec 2007 15:36:36 +0100 Subject: Modesetting Hotplug --- shared-core/i915_drv.h | 2 + shared-core/i915_init.c | 40 ++++---- shared-core/i915_irq.c | 238 +++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 245 insertions(+), 35 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index d9e86de9..45b7786a 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -135,6 +135,8 @@ 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; diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 3b43c722..588cd17e 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -30,7 +30,7 @@ int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size, u16 tmp = 0; unsigned long overhead; - bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); + bridge_dev = pci_find_slot(0, PCI_DEVFN(0,0)); if (!bridge_dev) { DRM_ERROR("bridge device not found\n"); return -1; @@ -249,9 +249,20 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) } 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; } @@ -259,9 +270,15 @@ 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->status_page_dmah) { drm_pci_free(dev, dev_priv->status_page_dmah); @@ -278,10 +295,6 @@ int i915_driver_unload(struct drm_device *dev) I915_WRITE(I915REG_HWS_PGA, 0x1ffff000); } - I915_WRITE(LP_RING + RING_LEN, 0); - - intel_modeset_cleanup(dev); - drm_mem_reg_iounmap(dev, &dev_priv->ring_buffer->mem, dev_priv->ring.virtual_start); @@ -310,20 +323,3 @@ int i915_driver_unload(struct drm_device *dev) dev->dev_private = NULL; return 0; } - -void i915_driver_lastclose(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - i915_do_cleanup_pageflip(dev); - //i915_mem_takedown(&(dev_priv->agp_heap)); - i915_dma_cleanup(dev); -} - -void i915_driver_preclose(struct drm_device *dev, struct drm_file *filp) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - //i915_mem_release(dev, filp, dev_priv->agp_heap); -} - diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 4312eae2..4508d146 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -31,6 +31,8 @@ #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) @@ -301,27 +303,174 @@ static void i915_vblank_tasklet(struct drm_device *dev) } } +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) +{ + 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); + +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_DEBUG("disconnect or unkown we don't do anything then\n"); + else + drm_hotplug_stage_two(dev, output); + + /* wierd hw bug, sdvo stop sending interupts */ + intel_sdvo_set_hotplug(output, 1); + +unlock: + mutex_unlock(&dev->mode_config.mutex); +} + +static void i915_hotplug_work_func(struct work_struct *work) +{ + struct drm_device *dev = hotplug_dev; + int crt; + int sdvoB; + int sdvoC; + + spin_lock(&hotplug_lock); + crt = hotplug_cmd & 1; + sdvoB = hotplug_cmd & 4; + sdvoC = hotplug_cmd & 8; + hotplug_cmd = 0; + spin_unlock(&hotplug_lock); + + if (crt) + i915_hotplug_crt(dev); + + 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) +{ + static DECLARE_WORK(hotplug, i915_hotplug_work_func); + struct drm_i915_private *dev_priv = dev->dev_private; + + hotplug_dev = dev; + + if (stat & (1 << 11)) { + DRM_DEBUG("CRT event\n"); + + if (stat & (1 << 9) && stat & (1 << 8)) { + spin_lock(&hotplug_lock); + hotplug_cmd |= 1; + spin_unlock(&hotplug_lock); + } else { + /* handle crt disconnects */ + } + } + + if (stat & (1 << 6)) { + DRM_DEBUG("sDVOB event\n"); + + spin_lock(&hotplug_lock); + hotplug_cmd |= 4; + spin_unlock(&hotplug_lock); + } + + if (stat & (1 << 7)) { + DRM_DEBUG("sDVOC event\n"); + + spin_lock(&hotplug_lock); + hotplug_cmd |= 8; + 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; struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; - u16 temp; + 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("%s flag=%08x\n", __FUNCTION__, temp); #endif +#endif + if (temp == 0) return IRQ_NONE; - I915_WRITE16(I915REG_INT_IDENTITY_R, temp); - (void) I915_READ16(I915REG_INT_IDENTITY_R); + 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); + } + DRM_READMEMORYBARRIER(); dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); @@ -362,6 +511,17 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) I915_VBLANK_CLEAR); } + /* for now lest just ack it */ + if (temp & (1 << 17)) { + DRM_DEBUG("Hotplug event recived\n"); + + temp2 = I915_READ(PORT_HOTPLUG_STAT); + + i915_run_hotplug_tasklet(dev, temp2); + + I915_WRITE(PORT_HOTPLUG_STAT,temp2); + } + return IRQ_HANDLED; } @@ -536,6 +696,7 @@ int i915_irq_wait(struct drm_device *dev, void *data, void i915_enable_interrupt (struct drm_device *dev) { 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; @@ -544,7 +705,41 @@ void i915_enable_interrupt (struct drm_device *dev) if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B) dev_priv->irq_enable_reg |= VSYNC_PIPEB_FLAG; - I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + if (IS_I9XX(dev) && dev->mode_config.funcs) { + dev_priv->irq_enable_reg |= (1 << 17); + + /* Activate the CRT */ + I915_WRITE(PORT_HOTPLUG_EN, (1 << 9)); + + /* 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, (1 << 26)); + } + + /* 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, (1 << 25)); + } + + } + + 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; } @@ -749,8 +944,14 @@ void i915_driver_irq_preinstall(struct drm_device * dev) 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); + } + } void i915_driver_irq_postinstall(struct drm_device * dev) @@ -777,16 +978,27 @@ void i915_driver_irq_postinstall(struct drm_device * dev) void i915_driver_irq_uninstall(struct drm_device * dev) { struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; - u16 temp; + 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); + } } -- cgit v1.2.3 From bdbc34e297bd7e4cb036df6244dfb0d816eed36d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 18 Dec 2007 02:09:48 +0100 Subject: Fix and cleanup of Hotplug --- shared-core/i915_irq.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 4508d146..ac5361f2 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -36,6 +36,7 @@ #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) @@ -303,6 +304,10 @@ static void i915_vblank_tasklet(struct drm_device *dev) } } +#define HOTPLUG_CMD_CRT 1 +#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; @@ -359,7 +364,10 @@ static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB) 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. + */ static void i915_hotplug_work_func(struct work_struct *work) { struct drm_device *dev = hotplug_dev; @@ -368,9 +376,9 @@ static void i915_hotplug_work_func(struct work_struct *work) int sdvoC; spin_lock(&hotplug_lock); - crt = hotplug_cmd & 1; - sdvoB = hotplug_cmd & 4; - sdvoC = hotplug_cmd & 8; + crt = hotplug_cmd & HOTPLUG_CMD_CRT; + sdvoB = hotplug_cmd & HOTPLUG_CMD_SDVOB; + sdvoC = hotplug_cmd & HOTPLUG_CMD_SDVOC; hotplug_cmd = 0; spin_unlock(&hotplug_lock); @@ -392,31 +400,31 @@ static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat) hotplug_dev = dev; - if (stat & (1 << 11)) { + if (stat & CRT_HOTPLUG_INT_STATUS) { DRM_DEBUG("CRT event\n"); - if (stat & (1 << 9) && stat & (1 << 8)) { + if (stat & CRT_HOTPLUG_MONITOR_MASK) { spin_lock(&hotplug_lock); - hotplug_cmd |= 1; + hotplug_cmd |= HOTPLUG_CMD_CRT; spin_unlock(&hotplug_lock); } else { /* handle crt disconnects */ } } - if (stat & (1 << 6)) { + if (stat & SDVOB_HOTPLUG_INT_STATUS) { DRM_DEBUG("sDVOB event\n"); spin_lock(&hotplug_lock); - hotplug_cmd |= 4; + hotplug_cmd |= HOTPLUG_CMD_SDVOB; spin_unlock(&hotplug_lock); } - if (stat & (1 << 7)) { + if (stat & SDVOC_HOTPLUG_INT_STATUS) { DRM_DEBUG("sDVOC event\n"); spin_lock(&hotplug_lock); - hotplug_cmd |= 8; + hotplug_cmd |= HOTPLUG_CMD_SDVOC; spin_unlock(&hotplug_lock); } @@ -513,7 +521,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) /* for now lest just ack it */ if (temp & (1 << 17)) { - DRM_DEBUG("Hotplug event recived\n"); + DRM_DEBUG("Hotplug event received\n"); temp2 = I915_READ(PORT_HOTPLUG_STAT); @@ -705,24 +713,24 @@ void i915_enable_interrupt (struct drm_device *dev) if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B) dev_priv->irq_enable_reg |= VSYNC_PIPEB_FLAG; - if (IS_I9XX(dev) && dev->mode_config.funcs) { - dev_priv->irq_enable_reg |= (1 << 17); + if (IS_I9XX(dev) && dev->mode_config.num_output) { + dev_priv->irq_enable_reg |= HOTPLUG_FLAG; /* Activate the CRT */ - I915_WRITE(PORT_HOTPLUG_EN, (1 << 9)); + 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, (1 << 26)); + 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, (1 << 25)); + I915_WRITE(PORT_HOTPLUG_EN, SDVOC_HOTPLUG_INT_EN); } } -- cgit v1.2.3 From ea915c77e169a50ca7dc557512212eafa93e2205 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 18 Dec 2007 02:52:09 +0100 Subject: Fixed build --- shared-core/i915_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 588cd17e..ebdcd5d3 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -30,7 +30,7 @@ int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size, u16 tmp = 0; unsigned long overhead; - bridge_dev = pci_find_slot(0, PCI_DEVFN(0,0)); + bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); if (!bridge_dev) { DRM_ERROR("bridge device not found\n"); return -1; -- cgit v1.2.3 From b13dc383df85d75cb1ea422f4d13efc2a4a8a732 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 18 Dec 2007 17:41:20 +1100 Subject: remove output names --- shared-core/drm.h | 9 ++++++++- shared-core/i915_init.c | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 9a8dc1d2..f8d44048 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -950,6 +950,12 @@ struct drm_mode_crtc { 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; @@ -960,7 +966,8 @@ struct drm_mode_get_output { int count_props; unsigned int output; /**< Id */ unsigned int crtc; /**< Id of crtc */ - unsigned char name[DRM_OUTPUT_NAME_LEN]; + unsigned int output_type; + unsigned int output_type_id; unsigned int connection; unsigned int mm_width, mm_height; /**< HxW in millimeters */ diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 3b43c722..e44cb930 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -188,8 +188,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ret = drm_buffer_object_create(dev, size, drm_bo_type_kernel, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MEM_VRAM | - DRM_BO_FLAG_NO_EVICT | - DRM_BO_HINT_DONT_FENCE, 0, 0x1, 0, + 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"); -- cgit v1.2.3 From d8c94a84b7f8da5fdf32a0799eaac72a1fc3007d Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Wed, 19 Dec 2007 18:27:38 +0100 Subject: radeon_ms: add sarea & install header --- shared-core/Makefile.am | 1 + shared-core/radeon_ms_drm.h | 8 ++++++++ 2 files changed, 9 insertions(+) (limited to 'shared-core') diff --git a/shared-core/Makefile.am b/shared-core/Makefile.am index 7193e527..42e08e75 100644 --- a/shared-core/Makefile.am +++ b/shared-core/Makefile.am @@ -32,6 +32,7 @@ klibdrminclude_HEADERS = \ nouveau_drm.h \ r128_drm.h \ radeon_drm.h \ + radeon_ms_drm.h \ savage_drm.h \ sis_drm.h \ via_drm.h \ diff --git a/shared-core/radeon_ms_drm.h b/shared-core/radeon_ms_drm.h index 842d5331..7186030c 100644 --- a/shared-core/radeon_ms_drm.h +++ b/shared-core/radeon_ms_drm.h @@ -57,4 +57,12 @@ struct drm_radeon_execbuffer { struct drm_fence_arg fence_arg; }; +#define RADEON_MS_MAX_SAREA_CLIPRECTS 16 + +struct drm_radeon_ms_sarea { + /* the cliprects */ + struct drm_clip_rect boxes[RADEON_MS_MAX_SAREA_CLIPRECTS]; + unsigned int nbox; +}; + #endif -- cgit v1.2.3 From 21b01cd4b54781cfab038016c2d644069d522787 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 20 Dec 2007 12:35:54 +0100 Subject: radeon_ms: update to follow lastest modesetting change --- shared-core/radeon_ms.h | 15 +-------------- shared-core/radeon_ms_dac.c | 4 ++-- shared-core/radeon_ms_family.c | 10 ++++------ shared-core/radeon_ms_i2c.c | 15 ++++++++++++--- shared-core/radeon_ms_output.c | 4 ++-- 5 files changed, 21 insertions(+), 27 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h index ee795f3a..d86c40b9 100644 --- a/shared-core/radeon_ms.h +++ b/shared-core/radeon_ms.h @@ -87,17 +87,6 @@ enum radeon_monitor_type { 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, @@ -131,7 +120,6 @@ struct radeon_ms_connector { int crtc; uint32_t i2c_reg; char outputs[RADEON_MAX_OUTPUTS]; - char name[32]; }; struct radeon_ms_output { @@ -459,8 +447,7 @@ 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); + const uint32_t reg, int type); /* radeon_ms_irq.c */ void radeon_ms_irq_emit(struct drm_device *dev); diff --git a/shared-core/radeon_ms_dac.c b/shared-core/radeon_ms_dac.c index 297623a0..2483eab8 100644 --- a/shared-core/radeon_ms_dac.c +++ b/shared-core/radeon_ms_dac.c @@ -369,8 +369,8 @@ int radeon_ms_dac2_mode_set(struct radeon_ms_output *output, case CHIP_R420: case CHIP_R430: case CHIP_R480: - if (connector->type != CONNECTOR_CTV && - connector->type != CONNECTOR_STV) { + if (connector->type != ConnectorComposite && + connector->type != ConnectorSVIDEO) { state->dac_cntl2 |= DAC_CNTL2__DAC2_CLK_SEL; } } diff --git a/shared-core/radeon_ms_family.c b/shared-core/radeon_ms_family.c index 779595d6..fcfec799 100644 --- a/shared-core/radeon_ms_family.c +++ b/shared-core/radeon_ms_family.c @@ -58,19 +58,17 @@ static struct radeon_ms_output radeon_ms_dac2 = { }; static struct radeon_ms_connector radeon_ms_vga = { - NULL, NULL, NULL, CONNECTOR_VGA, MT_NONE, 0, GPIO_DDC1, + NULL, NULL, NULL, ConnectorVGA, MT_NONE, 0, GPIO_DDC1, { 0, -1, -1, -1, -1, -1, -1, -1 - }, - "VGA" + } }; static struct radeon_ms_connector radeon_ms_dvi_i_2 = { - NULL, NULL, NULL, CONNECTOR_DVI_I, MT_NONE, 0, GPIO_DDC2, + NULL, NULL, NULL, ConnectorDVII, MT_NONE, 0, GPIO_DDC2, { 1, -1, -1, -1, -1, -1, -1, -1 - }, - "DVI-I" + } }; static struct radeon_ms_properties properties[] = { diff --git a/shared-core/radeon_ms_i2c.c b/shared-core/radeon_ms_i2c.c index 1801c496..f8730702 100644 --- a/shared-core/radeon_ms_i2c.c +++ b/shared-core/radeon_ms_i2c.c @@ -219,8 +219,7 @@ static void set_data(void *i2c_priv, int data) * */ struct radeon_ms_i2c *radeon_ms_i2c_create(struct drm_device *dev, - const uint32_t reg, - const char *name) + const uint32_t reg, int type) { struct radeon_ms_i2c *i2c; int ret; @@ -233,7 +232,17 @@ struct radeon_ms_i2c *radeon_ms_i2c_create(struct drm_device *dev, i2c->drm_dev = dev; i2c->reg = reg; - snprintf(i2c->adapter.name, I2C_NAME_SIZE, "radeon-%s", name); + switch (type) { + case ConnectorVGA: + snprintf(i2c->adapter.name, I2C_NAME_SIZE, "radeon-VGA"); + break; + case ConnectorDVII: + snprintf(i2c->adapter.name, I2C_NAME_SIZE, "radeon-DVII"); + break; + default: + snprintf(i2c->adapter.name, I2C_NAME_SIZE, "radeon-UNKNOWN"); + break; + } i2c->adapter.owner = THIS_MODULE; /* fixme need to take a look at what its needed for */ i2c->adapter.id = I2C_HW_B_RADEON; diff --git a/shared-core/radeon_ms_output.c b/shared-core/radeon_ms_output.c index 35e5c376..a1ed29cb 100644 --- a/shared-core/radeon_ms_output.c +++ b/shared-core/radeon_ms_output.c @@ -249,14 +249,14 @@ int radeon_ms_connectors_from_properties(struct drm_device *dev) dev_priv->properties->connectors[i], sizeof(struct radeon_ms_connector)); connector->i2c = radeon_ms_i2c_create(dev, - connector->i2c_reg, connector->name); + connector->i2c_reg, connector->type); if (connector->i2c == NULL) { radeon_ms_connectors_destroy(dev); return -ENOMEM; } output = drm_output_create(dev, &radeon_ms_output_funcs, - connector->name); + connector->type); if (output == NULL) { radeon_ms_connectors_destroy(dev); return -EINVAL; -- cgit v1.2.3 From 10937cf20b6814e4cf68114fab4619fad94eafcb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 4 Jan 2008 16:12:24 +1100 Subject: drm: move drm_head to drm_minor and fix up users --- shared-core/Makefile.am | 1 - shared-core/i915_dma.c | 6 +++--- shared-core/radeon_ms.h | 15 ++++++++++++++- shared-core/radeon_ms_dac.c | 4 ++-- shared-core/radeon_ms_drm.h | 8 -------- shared-core/radeon_ms_family.c | 10 ++++++---- shared-core/radeon_ms_i2c.c | 15 +++------------ shared-core/radeon_ms_output.c | 4 ++-- 8 files changed, 30 insertions(+), 33 deletions(-) (limited to 'shared-core') diff --git a/shared-core/Makefile.am b/shared-core/Makefile.am index 42e08e75..7193e527 100644 --- a/shared-core/Makefile.am +++ b/shared-core/Makefile.am @@ -32,7 +32,6 @@ klibdrminclude_HEADERS = \ nouveau_drm.h \ r128_drm.h \ radeon_drm.h \ - radeon_ms_drm.h \ savage_drm.h \ sis_drm.h \ via_drm.h \ diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 23e8b491..4c1a07ac 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -780,7 +780,7 @@ int i915_process_relocs(struct drm_file *file_priv, struct drm_i915_validate_buffer *buffers, uint32_t num_buffers) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; struct drm_buffer_object *reloc_list_object; uint32_t cur_handle = *reloc_buf_handle; uint32_t *reloc_page; @@ -866,7 +866,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; @@ -926,7 +926,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_reloc_handle, buf_handle; diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h index d86c40b9..ee795f3a 100644 --- a/shared-core/radeon_ms.h +++ b/shared-core/radeon_ms.h @@ -87,6 +87,17 @@ enum radeon_monitor_type { 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, @@ -120,6 +131,7 @@ struct radeon_ms_connector { int crtc; uint32_t i2c_reg; char outputs[RADEON_MAX_OUTPUTS]; + char name[32]; }; struct radeon_ms_output { @@ -447,7 +459,8 @@ 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, int type); + const uint32_t reg, + const char *name); /* radeon_ms_irq.c */ void radeon_ms_irq_emit(struct drm_device *dev); diff --git a/shared-core/radeon_ms_dac.c b/shared-core/radeon_ms_dac.c index 2483eab8..297623a0 100644 --- a/shared-core/radeon_ms_dac.c +++ b/shared-core/radeon_ms_dac.c @@ -369,8 +369,8 @@ int radeon_ms_dac2_mode_set(struct radeon_ms_output *output, case CHIP_R420: case CHIP_R430: case CHIP_R480: - if (connector->type != ConnectorComposite && - connector->type != ConnectorSVIDEO) { + if (connector->type != CONNECTOR_CTV && + connector->type != CONNECTOR_STV) { state->dac_cntl2 |= DAC_CNTL2__DAC2_CLK_SEL; } } diff --git a/shared-core/radeon_ms_drm.h b/shared-core/radeon_ms_drm.h index 7186030c..842d5331 100644 --- a/shared-core/radeon_ms_drm.h +++ b/shared-core/radeon_ms_drm.h @@ -57,12 +57,4 @@ struct drm_radeon_execbuffer { struct drm_fence_arg fence_arg; }; -#define RADEON_MS_MAX_SAREA_CLIPRECTS 16 - -struct drm_radeon_ms_sarea { - /* the cliprects */ - struct drm_clip_rect boxes[RADEON_MS_MAX_SAREA_CLIPRECTS]; - unsigned int nbox; -}; - #endif diff --git a/shared-core/radeon_ms_family.c b/shared-core/radeon_ms_family.c index fcfec799..779595d6 100644 --- a/shared-core/radeon_ms_family.c +++ b/shared-core/radeon_ms_family.c @@ -58,17 +58,19 @@ static struct radeon_ms_output radeon_ms_dac2 = { }; static struct radeon_ms_connector radeon_ms_vga = { - NULL, NULL, NULL, ConnectorVGA, MT_NONE, 0, GPIO_DDC1, + NULL, NULL, NULL, CONNECTOR_VGA, MT_NONE, 0, GPIO_DDC1, { 0, -1, -1, -1, -1, -1, -1, -1 - } + }, + "VGA" }; static struct radeon_ms_connector radeon_ms_dvi_i_2 = { - NULL, NULL, NULL, ConnectorDVII, MT_NONE, 0, GPIO_DDC2, + NULL, NULL, NULL, CONNECTOR_DVI_I, MT_NONE, 0, GPIO_DDC2, { 1, -1, -1, -1, -1, -1, -1, -1 - } + }, + "DVI-I" }; static struct radeon_ms_properties properties[] = { diff --git a/shared-core/radeon_ms_i2c.c b/shared-core/radeon_ms_i2c.c index f8730702..1801c496 100644 --- a/shared-core/radeon_ms_i2c.c +++ b/shared-core/radeon_ms_i2c.c @@ -219,7 +219,8 @@ static void set_data(void *i2c_priv, int data) * */ struct radeon_ms_i2c *radeon_ms_i2c_create(struct drm_device *dev, - const uint32_t reg, int type) + const uint32_t reg, + const char *name) { struct radeon_ms_i2c *i2c; int ret; @@ -232,17 +233,7 @@ struct radeon_ms_i2c *radeon_ms_i2c_create(struct drm_device *dev, i2c->drm_dev = dev; i2c->reg = reg; - switch (type) { - case ConnectorVGA: - snprintf(i2c->adapter.name, I2C_NAME_SIZE, "radeon-VGA"); - break; - case ConnectorDVII: - snprintf(i2c->adapter.name, I2C_NAME_SIZE, "radeon-DVII"); - break; - default: - snprintf(i2c->adapter.name, I2C_NAME_SIZE, "radeon-UNKNOWN"); - break; - } + 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; diff --git a/shared-core/radeon_ms_output.c b/shared-core/radeon_ms_output.c index a1ed29cb..35e5c376 100644 --- a/shared-core/radeon_ms_output.c +++ b/shared-core/radeon_ms_output.c @@ -249,14 +249,14 @@ int radeon_ms_connectors_from_properties(struct drm_device *dev) dev_priv->properties->connectors[i], sizeof(struct radeon_ms_connector)); connector->i2c = radeon_ms_i2c_create(dev, - connector->i2c_reg, connector->type); + 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); + connector->name); if (output == NULL) { radeon_ms_connectors_destroy(dev); return -EINVAL; -- cgit v1.2.3 From f1f934c8c97d6664fb5e1920a41154c09cc7f293 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Tue, 15 Jan 2008 14:05:25 +0100 Subject: radeon_ms: add rom parsing & adapt code Add rom (only combios for now) parsing and use informations retrieve instead of hardcoded table. Shuffle code around a bit. --- shared-core/radeon_ms.h | 44 ++--- shared-core/radeon_ms_combios.c | 396 +++++++++++++++++++++++++++++++++++++ shared-core/radeon_ms_combios.h | 385 ++++++++++++++++++++++++++++++++++++ shared-core/radeon_ms_crtc.c | 45 +++-- shared-core/radeon_ms_drm.c | 28 ++- shared-core/radeon_ms_family.c | 100 +--------- shared-core/radeon_ms_i2c.c | 63 +++++- shared-core/radeon_ms_output.c | 50 +++-- shared-core/radeon_ms_properties.c | 121 ++++++++++++ shared-core/radeon_ms_properties.h | 50 +++++ shared-core/radeon_ms_reg.h | 26 +++ shared-core/radeon_ms_rom.c | 91 +++++++++ shared-core/radeon_ms_rom.h | 51 +++++ 13 files changed, 1293 insertions(+), 157 deletions(-) create mode 100644 shared-core/radeon_ms_combios.c create mode 100644 shared-core/radeon_ms_combios.h create mode 100644 shared-core/radeon_ms_properties.c create mode 100644 shared-core/radeon_ms_properties.h create mode 100644 shared-core/radeon_ms_rom.c create mode 100644 shared-core/radeon_ms_rom.h (limited to 'shared-core') diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h index ee795f3a..a784882b 100644 --- a/shared-core/radeon_ms.h +++ b/shared-core/radeon_ms.h @@ -33,6 +33,8 @@ #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." @@ -43,10 +45,6 @@ #define DRIVER_MINOR 0 #define DRIVER_PATCHLEVEL 0 -#define RADEON_PAGE_SIZE 4096 -#define RADEON_MAX_CONNECTORS 8 -#define RADEON_MAX_OUTPUTS 8 - enum radeon_bus_type { RADEON_PCI = 0x10000, RADEON_AGP = 0x20000, @@ -154,20 +152,6 @@ struct radeon_ms_output { struct radeon_state *state); }; -struct radeon_ms_properties { - uint16_t subvendor; - uint16_t subdevice; - int16_t pll_reference_freq; - 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]; -}; - struct radeon_state { /* memory */ uint32_t config_aper_0_base; @@ -310,7 +294,6 @@ struct drm_radeon_private { /* card family */ uint32_t usec_timeout; uint32_t family; - struct radeon_ms_properties *properties; struct radeon_ms_output *outputs[RADEON_MAX_OUTPUTS]; struct radeon_ms_connector *connectors[RADEON_MAX_CONNECTORS]; /* drm map (MMIO, FB) */ @@ -342,6 +325,9 @@ struct drm_radeon_private { 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; }; @@ -369,6 +355,11 @@ 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); @@ -475,12 +466,21 @@ 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, @@ -545,7 +545,7 @@ static __inline__ void pll_index_errata(struct drm_radeon_private *dev_priv) /* This workaround is necessary on rv200 and RS200 or PLL * reads may return garbage (among others...) */ - if (dev_priv->properties->pll_dummy_reads) { + if (dev_priv->properties.pll_dummy_reads) { tmp = MMIO_R(CLOCK_CNTL_DATA); tmp = MMIO_R(CRTC_GEN_CNTL); } @@ -554,7 +554,7 @@ static __inline__ void pll_index_errata(struct drm_radeon_private *dev_priv) * CLOCK_CNTL_INDEX register access. If not, register reads afterward * may not be correct. */ - if (dev_priv->properties->pll_r300_errata) { + 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; @@ -569,7 +569,7 @@ 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) { + if (dev_priv->properties.pll_delay) { /* we can't deal with posted writes here ... */ udelay(5000); } diff --git a/shared-core/radeon_ms_combios.c b/shared-core/radeon_ms_combios.c new file mode 100644 index 00000000..04a33699 --- /dev/null +++ b/shared-core/radeon_ms_combios.c @@ -0,0 +1,396 @@ +/* + * 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 + */ +#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; + + if (i2c_reg) { + connector->i2c = radeon_ms_i2c_create(dev, + connector->i2c_reg, + connector->type); + 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, + ConnectorVGA, + i2c_reg); + if (ret) { + return ret; + } + added = 1; + break; + case BIOS_CONNECTOR_TYPE__DVI_I: + ret = radeon_ms_combios_connector_add(dev, c, + ConnectorDVII, + i2c_reg); + if (ret) { + return ret; + } + added = 1; + break; + case BIOS_CONNECTOR_TYPE__DVI_D: + ret = radeon_ms_combios_connector_add(dev, c, + ConnectorDVID, + 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 + */ +#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_crtc.c b/shared-core/radeon_ms_crtc.c index fe89e5e4..0da5a5a4 100644 --- a/shared-core/radeon_ms_crtc.c +++ b/shared-core/radeon_ms_crtc.c @@ -380,23 +380,26 @@ static void radeon_ms_crtc_mode_prepare(struct drm_crtc *crtc) } /* compute PLL registers values for requested video mode */ -static int radeon_pll1_constraint(int clock, int rdiv, +static int radeon_pll1_constraint(struct drm_device *dev, + int clock, int rdiv, int fdiv, int pdiv, int rfrq, int pfrq) { - int dfrq; - - if (rdiv < 2 || fdiv < 4) { - return 0; - } - dfrq = rfrq / rdiv; - if (dfrq < 2000 || dfrq > 3300) { - return 0; - } - if (pfrq < 125000 || pfrq > 250000) { - return 0; - } - return 1; + 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, @@ -424,7 +427,7 @@ static void radeon_pll1_compute(struct drm_crtc *crtc, 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 rfrq = dev_priv->properties.pll_reference_freq; int pdiv = 1; int pdiv_id = 0; int rdiv_best = 2; @@ -441,11 +444,11 @@ static void radeon_pll1_compute(struct drm_crtc *crtc, 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 > 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; + 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 @@ -457,8 +460,8 @@ static void radeon_pll1_compute(struct drm_crtc *crtc, tfrq = clock * post_div->divider; for (fdiv = 1023; fdiv >= 4; fdiv--) { rdiv = (fdiv * rfrq) / tfrq; - if (radeon_pll1_constraint(clock, rdiv, fdiv, - pdiv, 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 --git a/shared-core/radeon_ms_drm.c b/shared-core/radeon_ms_drm.c index 8d0481e1..91ca4a32 100644 --- a/shared-core/radeon_ms_drm.c +++ b/shared-core/radeon_ms_drm.c @@ -203,15 +203,35 @@ int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags) radeon_ms_driver_unload(dev); return ret; } - ret = radeon_ms_outputs_from_properties(dev); - if (ret != 0) { + 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_properties(dev); - if (ret != 0) { + 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); diff --git a/shared-core/radeon_ms_family.c b/shared-core/radeon_ms_family.c index 779595d6..b70dca20 100644 --- a/shared-core/radeon_ms_family.c +++ b/shared-core/radeon_ms_family.c @@ -29,87 +29,6 @@ #include "drm.h" #include "radeon_ms.h" -static 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 -}; - -static 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 -}; - -static 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" -}; - -static 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" -}; - -static struct radeon_ms_properties properties[] = { - /* default only one VGA connector */ - { - 0, 0, 27000, 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 - } - }, - { - 0x1043, 0x176, 27000, 25000, 200000, 1, 1, 1, 1, - { - &radeon_ms_dac1, &radeon_ms_dac2, NULL, NULL, NULL, - NULL, NULL, NULL - }, - { - &radeon_ms_vga, &radeon_ms_dvi_i_2, NULL, NULL, NULL, - NULL, NULL, NULL - } - }, - { - 0x1002, 0x4150, 27000, 25000, 200000, 1, 1, 1, 1, - { - &radeon_ms_dac1, &radeon_ms_dac2, NULL, NULL, NULL, - NULL, NULL, NULL - }, - { - &radeon_ms_vga, &radeon_ms_dvi_i_2, NULL, NULL, NULL, - NULL, NULL, NULL - } - }, -}; - extern const uint32_t radeon_cp_microcode[]; extern const uint32_t r200_cp_microcode[]; extern const uint32_t r300_cp_microcode[]; @@ -159,7 +78,7 @@ static void r300_flush_cache(struct drm_device *dev) int radeon_ms_family_init(struct drm_device *dev) { struct drm_radeon_private *dev_priv = dev->dev_private; - int i; + int ret; dev_priv->microcode = radeon_cp_microcode; dev_priv->irq_emit = radeon_ms_irq_emit; @@ -213,17 +132,10 @@ int radeon_ms_family_init(struct drm_device *dev) DRM_ERROR("Unknown radeon bus type, aborting\n"); return -EINVAL; } - dev_priv->properties = NULL; - 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); - dev_priv->properties = &properties[i]; - } - } - if (dev_priv->properties == NULL) { - dev_priv->properties = &properties[0]; + ret = radeon_ms_rom_init(dev); + if (ret) { + return ret; } - return 0; + ret = radeon_ms_properties_init(dev); + return ret; } diff --git a/shared-core/radeon_ms_i2c.c b/shared-core/radeon_ms_i2c.c index 1801c496..f4468c1e 100644 --- a/shared-core/radeon_ms_i2c.c +++ b/shared-core/radeon_ms_i2c.c @@ -66,6 +66,22 @@ static int get_clock(void *data) 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; @@ -112,6 +128,22 @@ static int get_data(void *data) 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; @@ -157,6 +189,18 @@ static void set_clock(void *i2c_priv, int 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; } @@ -201,6 +245,18 @@ static void set_data(void *i2c_priv, int 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; } @@ -251,11 +307,12 @@ struct radeon_ms_i2c *radeon_ms_i2c_create(struct drm_device *dev, ret = i2c_bit_add_bus(&i2c->adapter); if(ret) { - DRM_INFO("[radeon_ms] failed to register I2C '%s' bus\n", - i2c->adapter.name); + 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\n", i2c->adapter.name); + DRM_INFO("[radeon_ms] registered I2C '%s' bus (0x%X)\n", + i2c->adapter.name, reg); return i2c; out_free: diff --git a/shared-core/radeon_ms_output.c b/shared-core/radeon_ms_output.c index 35e5c376..18806324 100644 --- a/shared-core/radeon_ms_output.c +++ b/shared-core/radeon_ms_output.c @@ -189,7 +189,7 @@ static void radeon_ms_output_cleanup(struct drm_output *output) output->driver_private = NULL; } -static const struct drm_output_funcs radeon_ms_output_funcs = { +const struct drm_output_funcs radeon_ms_output_funcs = { .dpms = radeon_ms_output_dpms, .save = NULL, .restore = NULL, @@ -233,11 +233,11 @@ 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; + int i = 0, c = 0; radeon_ms_connectors_destroy(dev); for (i = 0; i < RADEON_MAX_CONNECTORS; i++) { - if (dev_priv->properties->connectors[i]) { + if (dev_priv->properties.connectors[i]) { connector = drm_alloc(sizeof(struct radeon_ms_connector), DRM_MEM_DRIVER); @@ -245,11 +245,11 @@ int radeon_ms_connectors_from_properties(struct drm_device *dev) 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); + 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; @@ -264,9 +264,20 @@ int radeon_ms_connectors_from_properties(struct drm_device *dev) connector->output = output; output->driver_private = connector; output->possible_crtcs = 0x3; - dev_priv->connectors[i] = connector; + 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; } @@ -289,24 +300,37 @@ 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]) { + if (dev_priv->properties.outputs[i]) { dev_priv->outputs[i] = drm_alloc(sizeof(struct radeon_ms_output), - DRM_MEM_DRIVER); + 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->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; } diff --git a/shared-core/radeon_ms_properties.c b/shared-core/radeon_ms_properties.c new file mode 100644 index 00000000..393f496f --- /dev/null +++ b/shared-core/radeon_ms_properties.c @@ -0,0 +1,121 @@ +/* + * 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 + */ +#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, ConnectorVGA, MT_NONE, 0, GPIO_DDC1, + { + 0, -1, -1, -1, -1, -1, -1, -1 + } +}; + +struct radeon_ms_connector radeon_ms_dvi_i_2 = { + NULL, NULL, NULL, ConnectorDVII, MT_NONE, 0, GPIO_DDC2, + { + 1, -1, -1, -1, -1, -1, -1, -1 + } +}; + +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 + */ +#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 index d450280c..56963c63 100644 --- a/shared-core/radeon_ms_reg.h +++ b/shared-core/radeon_ms_reg.h @@ -827,6 +827,32 @@ #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 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 + */ +#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 + */ +#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 + -- cgit v1.2.3 From 20a8e2d30e99a3248e6f02f792a29d20ec9f2ce5 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Tue, 15 Jan 2008 14:30:40 +0100 Subject: radeon_ms: cope with lastest drm modesetting change --- shared-core/radeon_ms_combios.c | 17 ++++++++++++++++- shared-core/radeon_ms_output.c | 4 ++-- shared-core/radeon_ms_properties.c | 6 ++++-- 3 files changed, 22 insertions(+), 5 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_ms_combios.c b/shared-core/radeon_ms_combios.c index 04a33699..ecd4bd06 100644 --- a/shared-core/radeon_ms_combios.c +++ b/shared-core/radeon_ms_combios.c @@ -143,10 +143,25 @@ static int radeon_ms_combios_connector_add(struct drm_device *dev, connector->type = connector_type; connector->i2c_reg = i2c_reg; + switch (connector->type) { + case ConnectorVGA: + sprintf(connector->name, "VGA"); + break; + case ConnectorDVII: + sprintf(connector->name, "DVI-I"); + break; + case ConnectorDVID: + 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->type); + connector->name); if (connector->i2c == NULL) { radeon_ms_connectors_destroy(dev); return -ENOMEM; diff --git a/shared-core/radeon_ms_output.c b/shared-core/radeon_ms_output.c index 18806324..bc174371 100644 --- a/shared-core/radeon_ms_output.c +++ b/shared-core/radeon_ms_output.c @@ -255,8 +255,8 @@ int radeon_ms_connectors_from_properties(struct drm_device *dev) return -ENOMEM; } output = drm_output_create(dev, - &radeon_ms_output_funcs, - connector->name); + &radeon_ms_output_funcs, + connector->type); if (output == NULL) { radeon_ms_connectors_destroy(dev); return -EINVAL; diff --git a/shared-core/radeon_ms_properties.c b/shared-core/radeon_ms_properties.c index 393f496f..2bd45dcd 100644 --- a/shared-core/radeon_ms_properties.c +++ b/shared-core/radeon_ms_properties.c @@ -61,14 +61,16 @@ struct radeon_ms_connector radeon_ms_vga = { NULL, NULL, NULL, ConnectorVGA, 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, ConnectorDVII, MT_NONE, 0, GPIO_DDC2, { 1, -1, -1, -1, -1, -1, -1, -1 - } + }, + "DVI-I" }; struct radeon_ms_properties properties[] = { -- cgit v1.2.3 From 6ba979ea467ef6ff76c32ee63ee9a6d4073ec672 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Tue, 15 Jan 2008 16:01:39 +0100 Subject: radeon_ms: use radeon connector type insted of drm --- shared-core/radeon_ms_combios.c | 12 ++++++------ shared-core/radeon_ms_dac.c | 2 +- shared-core/radeon_ms_properties.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_ms_combios.c b/shared-core/radeon_ms_combios.c index ecd4bd06..65609af9 100644 --- a/shared-core/radeon_ms_combios.c +++ b/shared-core/radeon_ms_combios.c @@ -144,13 +144,13 @@ static int radeon_ms_combios_connector_add(struct drm_device *dev, connector->i2c_reg = i2c_reg; switch (connector->type) { - case ConnectorVGA: + case CONNECTOR_VGA: sprintf(connector->name, "VGA"); break; - case ConnectorDVII: + case CONNECTOR_DVI_I: sprintf(connector->name, "DVI-I"); break; - case ConnectorDVID: + case CONNECTOR_DVI_D: sprintf(connector->name, "DVI-D"); break; default: @@ -279,7 +279,7 @@ int radeon_ms_connectors_from_combios(struct drm_device *dev) switch (connector_type) { case BIOS_CONNECTOR_TYPE__CRT: ret = radeon_ms_combios_connector_add(dev, c, - ConnectorVGA, + CONNECTOR_VGA, i2c_reg); if (ret) { return ret; @@ -288,7 +288,7 @@ int radeon_ms_connectors_from_combios(struct drm_device *dev) break; case BIOS_CONNECTOR_TYPE__DVI_I: ret = radeon_ms_combios_connector_add(dev, c, - ConnectorDVII, + CONNECTOR_DVI_I, i2c_reg); if (ret) { return ret; @@ -297,7 +297,7 @@ int radeon_ms_connectors_from_combios(struct drm_device *dev) break; case BIOS_CONNECTOR_TYPE__DVI_D: ret = radeon_ms_combios_connector_add(dev, c, - ConnectorDVID, + CONNECTOR_DVI_D, i2c_reg); if (ret) { return ret; diff --git a/shared-core/radeon_ms_dac.c b/shared-core/radeon_ms_dac.c index 297623a0..e6312942 100644 --- a/shared-core/radeon_ms_dac.c +++ b/shared-core/radeon_ms_dac.c @@ -370,7 +370,7 @@ int radeon_ms_dac2_mode_set(struct radeon_ms_output *output, case CHIP_R430: case CHIP_R480: if (connector->type != CONNECTOR_CTV && - connector->type != CONNECTOR_STV) { + connector->type != CONNECTOR_STV) { state->dac_cntl2 |= DAC_CNTL2__DAC2_CLK_SEL; } } diff --git a/shared-core/radeon_ms_properties.c b/shared-core/radeon_ms_properties.c index 2bd45dcd..baf2a7f2 100644 --- a/shared-core/radeon_ms_properties.c +++ b/shared-core/radeon_ms_properties.c @@ -58,7 +58,7 @@ struct radeon_ms_output radeon_ms_dac2 = { }; struct radeon_ms_connector radeon_ms_vga = { - NULL, NULL, NULL, ConnectorVGA, MT_NONE, 0, GPIO_DDC1, + NULL, NULL, NULL, CONNECTOR_VGA, MT_NONE, 0, GPIO_DDC1, { 0, -1, -1, -1, -1, -1, -1, -1 }, @@ -66,7 +66,7 @@ struct radeon_ms_connector radeon_ms_vga = { }; struct radeon_ms_connector radeon_ms_dvi_i_2 = { - NULL, NULL, NULL, ConnectorDVII, MT_NONE, 0, GPIO_DDC2, + NULL, NULL, NULL, CONNECTOR_DVI_I, MT_NONE, 0, GPIO_DDC2, { 1, -1, -1, -1, -1, -1, -1, -1 }, -- cgit v1.2.3 From fa7b779c91cbac16ec699efab4ee150412d4ba74 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 25 Jan 2008 16:32:09 +1000 Subject: don't reinit ring if already initialised --- shared-core/i915_dma.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 66d1b13d..68505dca 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -110,27 +110,29 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) dev_priv->sarea_priv = (drm_i915_sarea_t *) ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); - 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; dev_priv->sarea_priv->pf_current_page = 0; -- cgit v1.2.3 From a2254c5a9670a3e865f0eb5acd46e905c9b146ce Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 28 Jan 2008 03:12:29 +0100 Subject: Added cursor support --- shared-core/drm.h | 28 ++++++++++++++++++++++++++++ shared-core/i915_drv.h | 1 + shared-core/i915_init.c | 5 +++++ 3 files changed, 34 insertions(+) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 7aea3033..209a8db0 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1084,6 +1084,33 @@ struct drm_mode_mode_cmd { 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; +}; + /** * \name Ioctls Definitions */ @@ -1190,6 +1217,7 @@ 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) /*@}*/ diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 49e23ac3..ea89bc4c 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -147,6 +147,7 @@ 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; diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 3b271b17..792c40bb 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -131,6 +131,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) 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); -- cgit v1.2.3 From 53937a189f8dbe2dd82fb97c0e88454d29a6c7cd Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Tue, 5 Feb 2008 10:12:21 +0000 Subject: build fix for older kernels --- shared-core/i915_irq.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'shared-core') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 9b391b75..836a8c46 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -476,7 +476,11 @@ unlock: * 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; @@ -503,7 +507,11 @@ static void i915_hotplug_work_func(struct work_struct *work) 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; -- cgit v1.2.3 From 34b76e0fac579e4afd269ebd3cbcbdd0416ec944 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 7 Feb 2008 19:23:27 +0100 Subject: Added hotplug ioctl --- shared-core/drm.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 209a8db0..0d7cfd25 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1111,6 +1111,13 @@ struct drm_mode_cursor { unsigned int handle; }; +/* + * oh so ugly hotplug + */ +struct drm_mode_hotplug { + uint32_t counter; +}; + /** * \name Ioctls Definitions */ @@ -1218,6 +1225,7 @@ struct drm_mode_cursor { #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) /*@}*/ -- cgit v1.2.3 From 0618ac8a07d834e469cb96818a1dfee6f50662b8 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 7 Feb 2008 19:24:58 +0100 Subject: Added kernel part of hotplug ioctl --- shared-core/i915_irq.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 836a8c46..5f6fa56d 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -413,6 +413,7 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane) } #define HOTPLUG_CMD_CRT 1 +#define HOTPLUG_CMD_CRT_DIS 2 #define HOTPLUG_CMD_SDVOB 4 #define HOTPLUG_CMD_SDVOC 8 @@ -420,7 +421,7 @@ 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) +static void i915_hotplug_crt(struct drm_device *dev, bool connected) { struct drm_output *output; struct intel_output *iout; @@ -439,7 +440,7 @@ static void i915_hotplug_crt(struct drm_device *dev) if (iout == 0) goto unlock; - drm_hotplug_stage_two(dev, output); + drm_hotplug_stage_two(dev, output, connected); unlock: mutex_unlock(&dev->mode_config.mutex); @@ -462,9 +463,9 @@ static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB) status = output->funcs->detect(output); if (status != output_status_connected) - DRM_DEBUG("disconnect or unkown we don't do anything then\n"); + drm_hotplug_stage_two(dev, output, false); else - drm_hotplug_stage_two(dev, output); + drm_hotplug_stage_two(dev, output, true); /* wierd hw bug, sdvo stop sending interupts */ intel_sdvo_set_hotplug(output, 1); @@ -484,18 +485,22 @@ static void i915_hotplug_work_func(struct work_struct *work) { 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); + i915_hotplug_crt(dev, true); + if (crtDis) + i915_hotplug_crt(dev, false); if (sdvoB) i915_hotplug_sdvo(dev, 1); @@ -524,7 +529,9 @@ static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat) hotplug_cmd |= HOTPLUG_CMD_CRT; spin_unlock(&hotplug_lock); } else { - /* handle crt disconnects */ + spin_lock(&hotplug_lock); + hotplug_cmd |= HOTPLUG_CMD_CRT_DIS; + spin_unlock(&hotplug_lock); } } -- cgit v1.2.3 From 04257f1a5a28550dc430d8051bb58fd0ac34e77d Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sat, 9 Feb 2008 18:23:35 +0100 Subject: radeon_ms: bring radeon_ms up to date with lastest changes --- shared-core/radeon_ms.h | 2 +- shared-core/radeon_ms_bus.c | 11 +++++++++-- shared-core/radeon_ms_irq.c | 3 ++- 3 files changed, 12 insertions(+), 4 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h index 66533837..903de97d 100644 --- a/shared-core/radeon_ms.h +++ b/shared-core/radeon_ms.h @@ -457,7 +457,7 @@ struct radeon_ms_i2c *radeon_ms_i2c_create(struct drm_device *dev, 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); -void radeon_ms_irq_postinstall(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); diff --git a/shared-core/radeon_ms_bus.c b/shared-core/radeon_ms_bus.c index d50c9fb8..ed8fb211 100644 --- a/shared-core/radeon_ms_bus.c +++ b/shared-core/radeon_ms_bus.c @@ -46,6 +46,7 @@ struct radeon_pcie_gart { struct radeon_pcie *pcie; unsigned long page_first; struct page **pages; + struct page *dummy_read_page; unsigned long num_pages; int populated; int bound; @@ -57,7 +58,8 @@ 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); + 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 = @@ -130,6 +132,10 @@ static int pcie_ttm_bind(struct drm_ttm_backend *backend, 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); @@ -173,7 +179,8 @@ 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) + unsigned long num_pages, struct page **pages, + struct page *dummy_read_page) { struct radeon_pcie_gart *pcie_gart; diff --git a/shared-core/radeon_ms_irq.c b/shared-core/radeon_ms_irq.c index 24182c75..2f94118f 100644 --- a/shared-core/radeon_ms_irq.c +++ b/shared-core/radeon_ms_irq.c @@ -115,9 +115,10 @@ void radeon_ms_irq_preinstall(struct drm_device * dev) radeon_ack_irqs(dev_priv, mask); } -void radeon_ms_irq_postinstall(struct drm_device * dev) +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) -- cgit v1.2.3 From 8bf8cd63bb4631b57ceb27058f81d767a94edc74 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 14 Feb 2008 07:37:34 +1000 Subject: missing bits --- shared-core/i915_dma.c | 71 ++++++++++++++++++++-------------------------- shared-core/i915_drv.h | 11 +++++-- shared-core/i915_init.c | 58 +++++++++++++++++++++++++------------ shared-core/i915_irq.c | 40 ++++++++++++++++++++------ shared-core/i915_mem.c | 3 +- shared-core/radeon_state.c | 2 +- 6 files changed, 114 insertions(+), 71 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 68505dca..0a3d82a0 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -88,14 +88,7 @@ int i915_dma_cleanup(struct drm_device * dev) static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) { struct drm_i915_private *dev_priv = dev->dev_private; - - 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_master_private *master_priv = dev->primary->master->driver_priv; dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); if (!dev_priv->mmio_map) { i915_dma_cleanup(dev); @@ -107,9 +100,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS; #endif - dev_priv->sarea_priv = (drm_i915_sarea_t *) - ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); - if (!dev_priv->ring.Size) { dev_priv->ring.Start = init->ring_start; dev_priv->ring.End = init->ring_end; @@ -135,7 +125,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) dev_priv->cpp = init->cpp; - 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. @@ -182,11 +172,6 @@ static int i915_dma_resume(struct drm_device * dev) 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; @@ -400,6 +385,7 @@ static int i915_emit_box(struct drm_device * dev, void i915_emit_breadcrumb(struct drm_device *dev) { 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) { @@ -407,7 +393,7 @@ void i915_emit_breadcrumb(struct drm_device *dev) DRM_DEBUG("Breadcrumb counter wrapped around\n"); } - 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); @@ -534,37 +520,38 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync) { 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); @@ -575,21 +562,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) { 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); @@ -625,8 +613,9 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv) { 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; @@ -655,8 +644,9 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv) { 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 *) - dev_priv->sarea_priv; + master_priv->sarea_priv; struct drm_i915_cmdbuffer *cmdbuf = data; int ret; @@ -1011,8 +1001,9 @@ static int i915_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv) { 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_fence_arg *fence_arg = &exec_buf->fence_arg; @@ -1116,15 +1107,15 @@ out_free: int i915_do_cleanup_pageflip(struct drm_device * dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; int i, planes, num_pages; DRM_DEBUG("\n"); - num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2; + num_pages = master_priv->sarea_priv->third_handle ? 3 : 2; for (i = 0, planes = 0; i < 2; i++) { - if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) { - dev_priv->sarea_priv->pf_current_page = - (dev_priv->sarea_priv->pf_current_page & + 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; diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index ea89bc4c..19fec0fc 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -97,17 +97,22 @@ struct drm_i915_vbl_swap { unsigned int plane; unsigned int sequence; int flip; + struct drm_minor *minor; }; +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 *sarea; + drm_local_map_t *mmio_map; unsigned long mmiobase; unsigned long mmiolen; - struct drm_i915_sarea *sarea_priv; struct drm_i915_ring_buffer ring; struct drm_dma_handle *status_page_dmah; @@ -249,6 +254,8 @@ 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); diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 792c40bb..c2d8964e 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -113,7 +113,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) { struct drm_i915_private *dev_priv; unsigned long agp_size, prealloc_size; - unsigned long sareapage; int size, ret; dev_priv = drm_alloc(sizeof(struct drm_i915_private), DRM_MEM_DRIVER); @@ -160,20 +159,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) return ret; } - /* prebuild the SAREA */ - sareapage = max(SAREA_MAX, PAGE_SIZE); - ret = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK|_DRM_DRIVER, - &dev_priv->sarea); - if (ret) { - DRM_ERROR("SAREA setup failed\n"); - return ret; - } - - init_waitqueue_head(&dev->lock.lock_queue); - - /* FIXME: assume sarea_priv is right after SAREA */ - dev_priv->sarea_priv = dev_priv->sarea->handle + sizeof(struct drm_sarea); - /* * Initialize the memory manager for local and AGP space */ @@ -216,7 +201,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) DRM_DEBUG("ring start %08lX, %p, %08lX\n", dev_priv->ring.Start, dev_priv->ring.virtual_start, dev_priv->ring.Size); - dev_priv->sarea_priv->pf_current_page = 0; + // memset((void *)(dev_priv->ring.virtual_start), 0, dev_priv->ring.Size); @@ -319,12 +304,49 @@ int i915_driver_unload(struct drm_device *dev) drm_bo_driver_finish(dev); - DRM_DEBUG("%p, %p\n", dev_priv->mmio_map, dev_priv->sarea); + DRM_DEBUG("%p\n", dev_priv->mmio_map); drm_rmmap(dev, dev_priv->mmio_map); - drm_rmmap(dev, dev_priv->sarea); drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); dev->dev_private = NULL; return 0; } + +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 5f6fa56d..dad6ef86 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -107,8 +107,8 @@ static void i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw, int plane) { - struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; - struct drm_i915_sarea *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; @@ -153,18 +153,18 @@ i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw, static void i915_vblank_tasklet(struct drm_device *dev) { 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; - struct drm_i915_sarea *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); @@ -192,6 +192,12 @@ static void i915_vblank_tasklet(struct drm_device *dev) 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); @@ -306,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; @@ -559,6 +565,7 @@ static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat) irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; + 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; @@ -627,7 +634,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG); - 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); @@ -699,6 +709,7 @@ void i915_user_irq_off(struct drm_i915_private *dev_priv) static int i915_wait_irq(struct drm_device * dev, int irq_nr) { 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, @@ -716,8 +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); + } - dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); return ret; } @@ -904,6 +919,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data, struct drm_file *file_priv) { 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; @@ -916,7 +932,12 @@ int i915_vblank_swap(struct drm_device *dev, void *data, return -EINVAL; } - if (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; } @@ -1037,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++; diff --git a/shared-core/i915_mem.c b/shared-core/i915_mem.c index f24547c7..15d63dec 100644 --- a/shared-core/i915_mem.c +++ b/shared-core/i915_mem.c @@ -46,7 +46,8 @@ static void mark_block(struct drm_device * dev, struct mem_block *p, int in_use) { struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_sarea *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; struct drm_tex_region *list; unsigned shift, nr; unsigned start; 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: -- cgit v1.2.3 From 2b1c9cd696049d23845870329d2b61a5873f7b13 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 15 Feb 2008 16:13:21 -0800 Subject: i915: initial (and untested) TV out support Ported from xf86-video-intel. Still need to tie in TV modes somehow, though preferably w/o using the properties mechanism. --- shared-core/i915_drv.h | 573 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 573 insertions(+) (limited to 'shared-core') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 19fec0fc..1432806d 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -1192,6 +1192,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 -- cgit v1.2.3 From 8caf6e95712bfae8d1a42ffabafcbb9686766116 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Tue, 19 Feb 2008 15:17:24 +0000 Subject: Fix up conflicts for DRI2 (untested) --- shared-core/i915_dma.c | 38 +++++--------------------------------- shared-core/i915_init.c | 13 +++++++++++++ 2 files changed, 18 insertions(+), 33 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 3d489231..11c000b9 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -101,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; @@ -129,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); @@ -152,6 +152,7 @@ static int i915_initialize(struct drm_device * dev, { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; + dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); if (!dev_priv->mmio_map) { i915_dma_cleanup(dev); @@ -228,14 +229,13 @@ 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; } @@ -1390,34 +1390,6 @@ static int i915_set_status_page(struct drm_device *dev, void *data, return 0; } -#if 0 /* FIXME DRI2 */ -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); -} -#endif - 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), diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index c2d8964e..fe2fb389 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -269,6 +269,19 @@ int i915_driver_unload(struct drm_device *dev) 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); -- cgit v1.2.3 From 2c409f9a07a9d815b95fc8a5a4705d7988afe5df Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 18 Feb 2008 10:39:21 +1000 Subject: ttm: make sure userspace can't destroy kernel create memory managers --- shared-core/i915_init.c | 8 ++++---- shared-core/nouveau_mem.c | 6 +++--- shared-core/radeon_ms_drm.c | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index fe2fb389..b2d3f0d0 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -167,8 +167,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) i915_probe_agp(dev->pdev, &agp_size, &prealloc_size); printk("setting up %ld bytes of VRAM space\n", prealloc_size); printk("setting up %ld bytes of TT space\n", (agp_size - prealloc_size)); - drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, prealloc_size >> PAGE_SHIFT); - drm_bo_init_mm(dev, DRM_BO_MEM_TT, prealloc_size >> PAGE_SHIFT, (agp_size - prealloc_size) >> PAGE_SHIFT); + 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); @@ -305,11 +305,11 @@ int i915_driver_unload(struct drm_device *dev) mutex_lock(&dev->struct_mutex); drm_bo_usage_deref_locked(&dev_priv->ring_buffer); - if (drm_bo_clean_mm(dev, DRM_BO_MEM_TT)) { + 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)) { + if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM, 1)) { DRM_ERROR("Memory manager type 3 not clean. " "Delaying takedown\n"); } 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_ms_drm.c b/shared-core/radeon_ms_drm.c index bf76b45d..857182ae 100644 --- a/shared-core/radeon_ms_drm.c +++ b/shared-core/radeon_ms_drm.c @@ -160,7 +160,7 @@ int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags) 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); + 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; @@ -176,7 +176,7 @@ int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags) /* initialize ttm */ ret = drm_bo_init_mm(dev, DRM_BO_MEM_TT, 0, - dev_priv->gpu_gart_size / RADEON_PAGE_SIZE); + dev_priv->gpu_gart_size / RADEON_PAGE_SIZE, 1); if (ret != 0) { radeon_ms_driver_unload(dev); return ret; @@ -277,7 +277,7 @@ int radeon_ms_driver_unload(struct drm_device *dev) 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)) { + 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); @@ -289,7 +289,7 @@ int radeon_ms_driver_unload(struct drm_device *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)) { + 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); -- cgit v1.2.3 From 8844245cfcc5b19caafc772fd457401ab3253a28 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 20 Feb 2008 10:51:19 +1000 Subject: drm/fb: get rid of offset from structure use bo offset --- shared-core/radeon_ms_crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_ms_crtc.c b/shared-core/radeon_ms_crtc.c index 0da5a5a4..b2383859 100644 --- a/shared-core/radeon_ms_crtc.c +++ b/shared-core/radeon_ms_crtc.c @@ -556,7 +556,7 @@ static void radeon_ms_crtc1_mode_set(struct drm_crtc *crtc, } radeon_pll1_compute(crtc, adjusted_mode); - state->crtc_offset = REG_S(CRTC_OFFSET, CRTC_OFFSET, crtc->fb->offset); + 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); -- cgit v1.2.3 From 3f6c8f64aa8c3a9e427d453433e828693fb4e017 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Wed, 20 Feb 2008 22:22:49 +0000 Subject: fix SAREA --- shared-core/i915_drm.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'shared-core') diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h index 6067fa02..b8eaa021 100644 --- a/shared-core/i915_drm.h +++ b/shared-core/i915_drm.h @@ -125,6 +125,15 @@ typedef struct drm_i915_sarea { int third_offset; int third_size; unsigned int third_tiled; + + /* buffer object handles for the static buffers. May change + * over the lifetime of the client, though it doesn't in our current + * implementation. + */ + unsigned int front_bo_handle; + unsigned int back_bo_handle; + unsigned int third_bo_handle; + unsigned int depth_bo_handle; } drm_i915_sarea_t; /* Driver specific fence types and classes. -- cgit v1.2.3 From cdad850ebc3570e5ff5a0996f36832c965aa8a1d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 20 Feb 2008 13:27:10 +1000 Subject: add ioctl to get back memory managed area sized - used for kernel inited areas --- shared-core/drm.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 0d7cfd25..cbe83fd1 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -950,6 +950,12 @@ struct drm_mm_init_arg { uint64_t p_size; }; +struct drm_mm_info_arg { + unsigned int mem_type; + uint64_t p_size; +}; + + /* * Drm mode setting */ @@ -1209,6 +1215,7 @@ struct drm_mode_hotplug { #define DRM_IOCTL_BO_INFO DRM_IOWR(0xd4, struct drm_bo_reference_info_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_MM_INFO DRM_IOWR(0xd7, struct drm_mm_info_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) -- cgit v1.2.3 From 35d1b13b4a574faf3a95bf3b7cdd14897ef07f67 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 26 Feb 2008 16:11:39 +1000 Subject: i915_mmio: add overlay regs --- shared-core/i915_dma.c | 11 ++++++++++- shared-core/i915_drm.h | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 11c000b9..7a5d1d9f 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1300,7 +1300,16 @@ drm_i915_mmio_entry_t mmio_table[] = { I915_MMIO_MAY_READ|I915_MMIO_MAY_WRITE, 0x2350, 8 - } + }, + [MMIO_REGS_DOVSTA] = { + I915_MMIO_MAY_READ, + 0x30008, + 1 + }, + [MMIO_REGS_GAMMAA] = { + I915_MMIO_MAY_READ|I915_MMIO_MAY_WRITE, + 0x30010, + 6 }; static int mmio_table_size = sizeof(mmio_table)/sizeof(drm_i915_mmio_entry_t); diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h index b8eaa021..a40cabdc 100644 --- a/shared-core/i915_drm.h +++ b/shared-core/i915_drm.h @@ -326,6 +326,8 @@ typedef struct drm_i915_vblank_swap { #define MMIO_REGS_CL_INVOCATION_COUNT 6 #define MMIO_REGS_PS_INVOCATION_COUNT 7 #define MMIO_REGS_PS_DEPTH_COUNT 8 +#define MMIO_REGS_DOVSTA 9 +#define MMIO_REGS_GAMMA 10 typedef struct drm_i915_mmio_entry { unsigned int flag; -- cgit v1.2.3 From b92e343dc46212b665f0465274ef6767882bb10c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 26 Feb 2008 16:19:54 +1000 Subject: i915: fix typos --- shared-core/i915_dma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 7a5d1d9f..727aeee0 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1306,10 +1306,11 @@ drm_i915_mmio_entry_t mmio_table[] = { 0x30008, 1 }, - [MMIO_REGS_GAMMAA] = { + [MMIO_REGS_GAMMA] = { I915_MMIO_MAY_READ|I915_MMIO_MAY_WRITE, 0x30010, 6 + } }; static int mmio_table_size = sizeof(mmio_table)/sizeof(drm_i915_mmio_entry_t); -- cgit v1.2.3 From 75c9e0d3462f04766d490fac5cc93569957a8365 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Tue, 26 Feb 2008 23:30:45 +0100 Subject: radeon: remove TTM from an earlier merge --- shared-core/radeon_cp.c | 25 ------------------------ shared-core/radeon_drv.h | 51 ++---------------------------------------------- shared-core/radeon_irq.c | 24 +++++++++++------------ 3 files changed, 13 insertions(+), 87 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index f0eda664..ac46da38 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -1518,28 +1518,6 @@ 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; @@ -2455,9 +2433,6 @@ 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_drv.h b/shared-core/radeon_drv.h index 0c503257..1cf03415 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -104,11 +104,6 @@ #define DRIVER_MINOR 28 #define DRIVER_PATCHLEVEL 0 -#if defined(__linux__) -#define RADEON_HAVE_FENCE -#define RADEON_HAVE_BUFFER -#endif - /* * Radeon chip families */ @@ -296,9 +291,8 @@ typedef struct drm_radeon_private { struct mem_block *fb_heap; /* SW interrupt */ - wait_queue_head_t irq_queue; - int counter; - + wait_queue_head_t swi_queue; + atomic_t swi_emitted; int vblank_crtc; uint32_t irq_enable_reg; int irq_enabled; @@ -361,7 +355,6 @@ 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); @@ -381,7 +374,6 @@ 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); @@ -415,30 +407,6 @@ 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 @@ -1368,19 +1336,4 @@ 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 3f6ace88..79e4e866 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -128,12 +128,9 @@ 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->irq_queue); -#ifdef RADEON_HAVE_FENCE - radeon_fence_handler(dev); -#endif - } + if (stat & RADEON_SW_INT_TEST) + DRM_WAKEUP(&dev_priv->swi_queue); + /* VBLANK interrupt */ if (stat & RADEON_CRTC_VBLANK_STAT) drm_handle_vblank(dev, 0); @@ -143,13 +140,14 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) return IRQ_HANDLED; } -int radeon_emit_irq(struct drm_device * dev) +static int radeon_emit_irq(struct drm_device * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; unsigned int ret; RING_LOCALS; - ret = radeon_update_breadcrumb(dev); + atomic_inc(&dev_priv->swi_emitted); + ret = atomic_read(&dev_priv->swi_emitted); BEGIN_RING(4); OUT_RING_REG(RADEON_LAST_SWI_REG, ret); @@ -166,13 +164,13 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr) (drm_radeon_private_t *) dev->dev_private; int ret = 0; - if (READ_BREADCRUMB(dev_priv) >= swi_nr) + if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr) return 0; dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, - READ_BREADCRUMB(dev_priv) >= swi_nr); + DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ, + RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr); return ret; } @@ -260,8 +258,8 @@ int radeon_driver_irq_postinstall(struct drm_device * dev) (drm_radeon_private_t *) dev->dev_private; int ret; - dev_priv->counter = 0; - DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); + atomic_set(&dev_priv->swi_emitted, 0); + DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); ret = drm_vblank_init(dev, 2); if (ret) -- cgit v1.2.3 From 01dcc47d895997f77c9457558e974d41c23ed4e1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 28 Feb 2008 16:24:17 +1000 Subject: drm: add modesetting as a driver feature. This change adds a driver feature that for i915 is controlled by a module parameter. You now need to do insmod i915.ko modeset=1 to enable it the modesetting paths. It also fixes up lots of X paths. I can run my new DDX driver on this code with and without modesetting enabled --- shared-core/i915_dma.c | 49 +++++++++-- shared-core/i915_init.c | 226 ++++++++++++++++++++++++++++-------------------- 2 files changed, 176 insertions(+), 99 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index eee24dd1..20095a95 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -66,6 +66,11 @@ void i915_kernel_lost_context(struct drm_device * dev) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_ring_buffer *ring = &(dev_priv->ring); + /* we should never lose context on the ring with modesetting + * as we don't expose it to userspace */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return; + ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR; ring->space = ring->head - (ring->tail + 8); @@ -75,6 +80,11 @@ void i915_kernel_lost_context(struct drm_device * dev) int i915_dma_cleanup(struct drm_device * dev) { + struct drm_i915_private *dev_priv = dev->dev_private; + + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + /* 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. @@ -82,6 +92,28 @@ 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; + dev_priv->ring.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; } @@ -153,13 +185,17 @@ static int i915_initialize(struct drm_device * dev, struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - 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"); - return -EINVAL; + if (!drm_core_check_feature(dev, DRIVER_MODESET)) { + if (init->mmio_offset != 0) + 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"); + return -EINVAL; + } } + #ifdef I915_HAVE_BUFFER dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS; #endif @@ -246,6 +282,9 @@ static int i915_dma_resume(struct drm_device * dev) DRM_DEBUG("\n"); + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + if (!dev_priv->mmio_map) { DRM_ERROR("can not find mmio map!\n"); return -EINVAL; diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index b2d3f0d0..a2e08bc1 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -153,106 +153,113 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) 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); + _DRM_REGISTERS, _DRM_KERNEL|_DRM_READ_ONLY|_DRM_DRIVER, &dev_priv->mmio_map); if (ret != 0) { DRM_ERROR("Cannot add mapping for MMIO registers\n"); return ret; } +#ifdef __linux__ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) + intel_init_chipset_flush_compat(dev); +#endif +#endif + /* * 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); + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + 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; + 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"); - /* 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->wq = create_singlethread_workqueue("i915"); + if (dev_priv == 0) { + DRM_DEBUG("Error\n"); } - 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); + intel_modeset_init(dev); + drm_initial_config(dev, false); - I915_WRITE(I915REG_HWS_PGA, dev_priv->dma_status_page); - } - DRM_DEBUG("Enabled hardware status page\n"); + drm_mm_print(&dev->bm.man[DRM_BO_MEM_VRAM].manager, "VRAM"); + drm_mm_print(&dev->bm.man[DRM_BO_MEM_TT].manager, "TT"); - dev_priv->wq = create_singlethread_workqueue("i915"); - if (dev_priv == 0) { - DRM_DEBUG("Error\n"); + drm_irq_install(dev); } - - 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; } @@ -262,7 +269,10 @@ int i915_driver_unload(struct drm_device *dev) I915_WRITE(LP_RING + RING_LEN, 0); - intel_modeset_cleanup(dev); + + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + intel_modeset_cleanup(dev); + } #if 0 if (dev_priv->ring.virtual_start) { @@ -298,25 +308,33 @@ int i915_driver_unload(struct drm_device *dev) I915_WRITE(I915REG_HWS_PGA, 0x1ffff000); } - drm_mem_reg_iounmap(dev, &dev_priv->ring_buffer->mem, - dev_priv->ring.virtual_start); + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + 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); + 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"); + 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); } - mutex_unlock(&dev->struct_mutex); drm_bo_driver_finish(dev); +#ifdef __linux__ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) + intel_init_chipset_flush_compat(dev); +#endif +#endif + DRM_DEBUG("%p\n", dev_priv->mmio_map); drm_rmmap(dev, dev_priv->mmio_map); @@ -363,3 +381,23 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master) master->driver_priv = NULL; } + +void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + if (drm_core_check_feature(dev, DRIVER_MODESET)) + i915_mem_release(dev, file_priv, dev_priv->agp_heap); +} + +void i915_driver_lastclose(struct drm_device * dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return; + + if (dev_priv->agp_heap) + i915_mem_takedown(&(dev_priv->agp_heap)); + + i915_dma_cleanup(dev); +} -- cgit v1.2.3 From 9c5ba9f5d153877ab2e7cb623cab5607aa5cd4a8 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Sun, 2 Mar 2008 21:48:40 +0000 Subject: Add FENCE registers to MMIO list --- shared-core/i915_dma.c | 10 ++++++++++ shared-core/i915_drm.h | 2 ++ 2 files changed, 12 insertions(+) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 20095a95..28835a04 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1469,6 +1469,16 @@ drm_i915_mmio_entry_t mmio_table[] = { I915_MMIO_MAY_READ|I915_MMIO_MAY_WRITE, 0x30010, 6 + }, + [MMIO_REGS_FENCE] = { + I915_MMIO_MAY_READ|I915_MMIO_MAY_WRITE, + 0x2000, + 8 + }, + [MMIO_REGS_FENCE_NEW] = { + I915_MMIO_MAY_READ|I915_MMIO_MAY_WRITE, + 0x3000, + 16 } }; diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h index a40cabdc..824aee27 100644 --- a/shared-core/i915_drm.h +++ b/shared-core/i915_drm.h @@ -328,6 +328,8 @@ typedef struct drm_i915_vblank_swap { #define MMIO_REGS_PS_DEPTH_COUNT 8 #define MMIO_REGS_DOVSTA 9 #define MMIO_REGS_GAMMA 10 +#define MMIO_REGS_FENCE 11 +#define MMIO_REGS_FENCE_NEW 12 typedef struct drm_i915_mmio_entry { unsigned int flag; -- cgit v1.2.3 From 4dbf447f4305e3c2aa8914b5ccfc07d9bf8ef28e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 5 Mar 2008 15:28:38 +1000 Subject: drm: fixup compat with old x.org drivers --- shared-core/i915_init.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index a2e08bc1..1f22d171 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -401,3 +401,12 @@ void i915_driver_lastclose(struct drm_device * dev) i915_dma_cleanup(dev); } + +int i915_driver_firstopen(struct drm_device *dev) +{ + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + + drm_bo_driver_init(dev); + return 0; +} -- cgit v1.2.3 From 48a166af14d7455835b9dc2ffd831347d18635d2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 7 Mar 2008 08:49:27 +1000 Subject: woah somehow got these upstream --- shared-core/drm.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 753af6b7..6b3c6229 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1052,7 +1052,6 @@ struct drm_mm_info_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_MM_INFO DRM_IOWR(0xd7, struct drm_mm_info_arg) -<<<<<<< HEAD:shared-core/drm.h #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) @@ -1070,8 +1069,6 @@ struct drm_mm_info_arg { #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) -======= ->>>>>>> d5c0101252e9f48ef1b59f48c05fea7007df97f0:shared-core/drm.h /*@}*/ -- cgit v1.2.3 From ccae12a837e7b17c4e9211295ecbd18807020742 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 7 Mar 2008 08:58:24 +1000 Subject: I really screwed up that merge somehow --- shared-core/drm.h | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 6b3c6229..303a84b6 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -960,6 +960,175 @@ struct drm_mm_info_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 */ -- cgit v1.2.3 From cf28ca4212662c3c7e4bfbe51aee307ac539fb3d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 7 Mar 2008 13:03:32 +1100 Subject: actually turn the irq off --- shared-core/i915_init.c | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 1f22d171..3d8a1dca 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -271,6 +271,7 @@ int i915_driver_unload(struct drm_device *dev) if (drm_core_check_feature(dev, DRIVER_MODESET)) { + drm_irq_uninstall(dev); intel_modeset_cleanup(dev); } -- cgit v1.2.3 From a7dc4d08b9b4f8fe6fcaa4c778f6dd3718d1e36a Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Mon, 10 Mar 2008 23:35:07 +0100 Subject: rradeon_ms: rework fence code and bring radeon ms up to date --- shared-core/radeon_ms.h | 14 +-- shared-core/radeon_ms_drm.c | 22 ++-- shared-core/radeon_ms_drm.h | 23 ++-- shared-core/radeon_ms_exec.c | 2 +- shared-core/radeon_ms_fence.c | 248 ++++++++++++++++++++++++++++++++---------- shared-core/radeon_ms_irq.c | 4 +- 6 files changed, 226 insertions(+), 87 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h index 903de97d..12c945f9 100644 --- a/shared-core/radeon_ms.h +++ b/shared-core/radeon_ms.h @@ -31,6 +31,7 @@ #define __RADEON_MS_H__ #include "radeon_ms_drv.h" +#include "amd_r3xx_fence.h" #include "radeon_ms_reg.h" #include "radeon_ms_drm.h" #include "radeon_ms_rom.h" @@ -328,6 +329,7 @@ struct drm_radeon_private { /* abstract asic specific structures */ struct radeon_ms_rom rom; struct radeon_ms_properties properties; + void *fence; }; @@ -425,15 +427,9 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, 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); +void r3xx_fence_handler(struct drm_device * dev); +int r3xx_fence_types(struct drm_buffer_object *bo, + uint32_t * class, uint32_t * type); /* radeon_ms_fb.c */ int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc); diff --git a/shared-core/radeon_ms_drm.c b/shared-core/radeon_ms_drm.c index 857182ae..b9245d99 100644 --- a/shared-core/radeon_ms_drm.c +++ b/shared-core/radeon_ms_drm.c @@ -43,24 +43,13 @@ static uint32_t radeon_ms_busy_prios[] = { 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, + .fence_type = r3xx_fence_types, .invalidate_caches = radeon_ms_invalidate_caches, .init_mem_type = radeon_ms_init_mem_type, .evict_flags = radeon_ms_evict_flags, @@ -127,6 +116,13 @@ int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags) return ret; } + dev_priv->fence = drm_alloc(sizeof(struct r3xx_fence), DRM_MEM_DRIVER); + if (dev_priv->fence == NULL) { + radeon_ms_driver_unload(dev); + return -ENOMEM; + } + memset(dev_priv->fence, 0, sizeof(struct r3xx_fence)); + /* 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); @@ -309,9 +305,11 @@ int radeon_ms_driver_unload(struct drm_device *dev) drm_core_ioremapfree(&dev_priv->vram, dev); } DRM_INFO("[radeon_ms] map released\n"); + drm_free(dev_priv->fence, sizeof(struct r3xx_fence), DRM_MEM_DRIVER); 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 index 842d5331..39c050ad 100644 --- a/shared-core/radeon_ms_drm.h +++ b/shared-core/radeon_ms_drm.h @@ -30,16 +30,23 @@ #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 +/* Fence + * We have only one fence class as we submit command through th + * same fifo so there is no need to synchronize buffer btw different + * cmd stream. + * + * Set DRM_RADEON_FENCE_FLAG_FLUSHED if you want a flush with + * emission of the fence + * + * For fence type we have the native DRM EXE type and the radeon RW + * type. + */ +#define DRM_RADEON_FENCE_CLASS_ACCEL 0 +#define DRM_RADEON_FENCE_TYPE_RW 2 +#define DRM_RADEON_FENCE_FLAG_FLUSHED 0x01000000 /* radeon ms ioctl */ -#define DRM_RADEON_EXECBUFFER 0x00 +#define DRM_RADEON_EXECBUFFER 0x00 struct drm_radeon_execbuffer_arg { uint64_t next; diff --git a/shared-core/radeon_ms_exec.c b/shared-core/radeon_ms_exec.c index b2ce3cbb..8e28b19e 100644 --- a/shared-core/radeon_ms_exec.c +++ b/shared-core/radeon_ms_exec.c @@ -223,7 +223,7 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, 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->signaled = fence->signaled_types; fence_arg->sequence = fence->sequence; } } diff --git a/shared-core/radeon_ms_fence.c b/shared-core/radeon_ms_fence.c index 6fcf5437..162d37d6 100644 --- a/shared-core/radeon_ms_fence.c +++ b/shared-core/radeon_ms_fence.c @@ -27,103 +27,241 @@ * Jerome Glisse */ #include "radeon_ms.h" +#include "amd_r3xx_fence.h" -static void radeon_ms_fence_flush(struct drm_device *dev) +#define R3XX_FENCE_SEQUENCE_RW_FLUSH 0x80000000u + +static inline int r3xx_fence_emit_sequence(struct drm_device *dev, + struct drm_radeon_private *dev_priv, + uint32_t sequence) { - 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; + struct r3xx_fence *r3xx_fence = dev_priv->fence; + uint32_t cmd[2]; + int i, r; + + if (sequence & R3XX_FENCE_SEQUENCE_RW_FLUSH) { + r3xx_fence->sequence_last_flush = + sequence & ~R3XX_FENCE_SEQUENCE_RW_FLUSH; + /* Ask flush for VERTEX & FRAGPROG pipeline + * have 3D idle */ + dev_priv->flush_cache(dev); + } + cmd[0] = CP_PACKET0(dev_priv->fence_reg, 0); + cmd[1] = sequence; + for (i = 0; i < dev_priv->usec_timeout; i++) { + r = radeon_ms_ring_emit(dev, cmd, 2); + if (!r) { + dev_priv->irq_emit(dev); + return 0; + } + } + return -EBUSY; +} + +static inline uint32_t r3xx_fence_sequence(struct r3xx_fence *r3xx_fence) +{ + r3xx_fence->sequence += 1; + if (unlikely(r3xx_fence->sequence > 0x7fffffffu)) { + r3xx_fence->sequence = 1; + } + return r3xx_fence->sequence; +} + +static inline void r3xx_fence_report(struct drm_device *dev, + struct drm_radeon_private *dev_priv, + struct r3xx_fence *r3xx_fence) +{ + uint32_t fence_types = DRM_FENCE_TYPE_EXE; 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); + sequence = mmio_read(dev_priv, dev_priv->fence_reg); + if (sequence & R3XX_FENCE_SEQUENCE_RW_FLUSH) { + sequence &= ~R3XX_FENCE_SEQUENCE_RW_FLUSH; + fence_types |= DRM_RADEON_FENCE_TYPE_RW; + if (sequence == r3xx_fence->sequence_last_flush) { + r3xx_fence->sequence_last_flush = 0; + } } + /* avoid to report already reported sequence */ + if (sequence != r3xx_fence->sequence_last_reported) { + drm_fence_handler(dev, 0, sequence, fence_types, 0); + r3xx_fence->sequence_last_reported = sequence; + } +} + +static void r3xx_fence_flush(struct drm_device *dev, uint32_t class) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + struct r3xx_fence *r3xx_fence = dev_priv->fence; + uint32_t sequence; + + sequence = r3xx_fence_sequence(r3xx_fence); + sequence |= R3XX_FENCE_SEQUENCE_RW_FLUSH; + r3xx_fence_emit_sequence(dev, dev_priv, sequence); } -int radeon_ms_fence_emit_sequence(struct drm_device *dev, uint32_t class, - uint32_t flags, uint32_t *sequence, - uint32_t *native_type) +static void r3xx_fence_poll(struct drm_device *dev, uint32_t fence_class, + uint32_t waiting_types) { struct drm_radeon_private *dev_priv = dev->dev_private; - uint32_t fence_id, cmd[2], i, ret; + struct drm_fence_manager *fm = &dev->fm; + struct drm_fence_class_manager *fc = &fm->fence_class[fence_class]; + struct r3xx_fence *r3xx_fence = dev_priv->fence; + + if (unlikely(!dev_priv)) { + return; + } + /* if there is a RW flush pending then submit new sequence + * preceded by flush cmds */ + if (fc->pending_flush & DRM_RADEON_FENCE_TYPE_RW) { + r3xx_fence_flush(dev, 0); + fc->pending_flush &= ~DRM_RADEON_FENCE_TYPE_RW; + } + r3xx_fence_report(dev, dev_priv, r3xx_fence); + return; +} + +static int r3xx_fence_emit(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; + struct r3xx_fence *r3xx_fence = dev_priv->fence; + uint32_t tmp; 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; + *sequence = tmp = r3xx_fence_sequence(r3xx_fence); *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); + tmp |= R3XX_FENCE_SEQUENCE_RW_FLUSH; } - 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 r3xx_fence_emit_sequence(dev, dev_priv, tmp); +} + +static int r3xx_fence_has_irq(struct drm_device *dev, + uint32_t class, uint32_t type) +{ + const uint32_t type_irq_mask = DRM_FENCE_TYPE_EXE | + DRM_RADEON_FENCE_TYPE_RW; + /* + * We have an irq for EXE & RW fence. + */ + if (class == 0 && (type & type_irq_mask)) { + return 1; + } + return 0; +} + +static uint32_t r3xx_fence_needed_flush(struct drm_fence_object *fence) +{ + struct drm_device *dev = fence->dev; + struct drm_radeon_private *dev_priv = dev->dev_private; + struct r3xx_fence *r3xx_fence = dev_priv->fence; + struct drm_fence_driver *driver = dev->driver->fence_driver; + uint32_t flush_types, diff; + + flush_types = fence->waiting_types & + ~(DRM_FENCE_TYPE_EXE | fence->signaled_types); + + if (flush_types == 0 || ((flush_types & ~fence->native_types) == 0)) { + return 0; + } + if (unlikely(dev_priv == NULL)) { + return 0; + } + if (r3xx_fence->sequence_last_flush) { + diff = (r3xx_fence->sequence_last_flush - fence->sequence) & + driver->sequence_mask; + if (diff < driver->wrap_diff) { return 0; } } - return -EBUSY; + return flush_types; } -void radeon_ms_fence_handler(struct drm_device * dev) +static int r3xx_fence_wait(struct drm_fence_object *fence, + int lazy, int interruptible, uint32_t mask) { - struct drm_radeon_private *dev_priv = dev->dev_private; + struct drm_device *dev = fence->dev; struct drm_fence_manager *fm = &dev->fm; + struct drm_fence_class_manager *fc = &fm->fence_class[0]; + int r; - if (dev_priv == NULL) { - return; + drm_fence_object_flush(fence, mask); + if (likely(interruptible)) { + r = wait_event_interruptible_timeout( + fc->fence_queue, + drm_fence_object_signaled(fence, DRM_FENCE_TYPE_EXE), + 3 * DRM_HZ); + } else { + r = wait_event_timeout( + fc->fence_queue, + drm_fence_object_signaled(fence, DRM_FENCE_TYPE_EXE), + 3 * DRM_HZ); + } + if (unlikely(r == -ERESTARTSYS)) { + return -EAGAIN; + } + if (unlikely(r == 0)) { + return -EBUSY; } - write_lock(&fm->lock); - radeon_ms_fence_flush(dev); - write_unlock(&fm->lock); -} + if (likely(mask == DRM_FENCE_TYPE_EXE || + drm_fence_object_signaled(fence, mask))) { + return 0; + } -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. + * Poll for sync flush completion. */ - if (class == 0 && flags == DRM_FENCE_TYPE_EXE) - return 1; - - return 0; + return drm_fence_wait_polling(fence, lazy, interruptible, + mask, 3 * DRM_HZ); } -int radeon_ms_fence_types(struct drm_buffer_object *bo, - uint32_t *class, uint32_t *type) +struct drm_fence_driver r3xx_fence_driver = { + .num_classes = 1, + .wrap_diff = (1 << 29), + .flush_diff = (1 << 28), + .sequence_mask = 0x7fffffffU, + .has_irq = r3xx_fence_has_irq, + .emit = r3xx_fence_emit, + .flush = r3xx_fence_flush, + .poll = r3xx_fence_poll, + .needed_flush = r3xx_fence_needed_flush, + .wait = r3xx_fence_wait, +}; + +/* this are used by the buffer object code */ +int r3xx_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; + if (bo->mem.flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) { + *type = DRM_FENCE_TYPE_EXE | DRM_RADEON_FENCE_TYPE_RW; + } else { + *type = DRM_FENCE_TYPE_EXE; + } return 0; } -void radeon_ms_poke_flush(struct drm_device *dev, uint32_t class) +/* this are used by the irq code */ +void r3xx_fence_handler(struct drm_device * dev) { + struct drm_radeon_private *dev_priv = dev->dev_private; struct drm_fence_manager *fm = &dev->fm; - unsigned long flags; + struct drm_fence_class_manager *fc = &fm->fence_class[0]; - if (class != 0) + if (unlikely(dev_priv == NULL)) { return; - write_lock_irqsave(&fm->lock, flags); - radeon_ms_fence_flush(dev); - write_unlock_irqrestore(&fm->lock, flags); + } + + write_lock(&fm->lock); + r3xx_fence_poll(dev, 0, fc->waiting_types); + write_unlock(&fm->lock); } diff --git a/shared-core/radeon_ms_irq.c b/shared-core/radeon_ms_irq.c index 2f94118f..5c68c902 100644 --- a/shared-core/radeon_ms_irq.c +++ b/shared-core/radeon_ms_irq.c @@ -92,9 +92,9 @@ irqreturn_t radeon_ms_irq_handler(DRM_IRQ_ARGS) /* SW interrupt */ if (GEN_INT_STATUS__SW_INT & status) { - radeon_ms_fence_handler(dev); + r3xx_fence_handler(dev); } - radeon_ms_fence_handler(dev); + r3xx_fence_handler(dev); return IRQ_HANDLED; } -- cgit v1.2.3 From 52748d17923b7e501b707b950227864c0b64d8a1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 11 Mar 2008 11:49:27 +1000 Subject: drm: hopefully fix cursors on 965 --- shared-core/i915_drv.h | 3 ++- shared-core/i915_init.c | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index f6c0005d..b8dfbc34 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -139,9 +139,10 @@ struct drm_i915_private { int fence_irq_on; uint32_t irq_enable_reg; int irq_enabled; - struct workqueue_struct *wq; + bool cursor_needs_physical; + #ifdef I915_HAVE_FENCE uint32_t flush_sequence; uint32_t flush_flags; diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 3d8a1dca..274322e1 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -130,6 +130,14 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev->types[8] = _DRM_STAT_SECONDARY; dev->types[9] = _DRM_STAT_DMA; + if (IS_MOBILE(dev) || IS_I9XX(dev)) + dev_priv->cursor_needs_physical = true; + else + dev_priv->cursor_needs_physical = false; + + if (IS_I965G(dev) || IS_G33(dev)) + dev_priv->cursor_needs_physical = false; + 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); -- cgit v1.2.3 From 5a7f4b3074d5cda909fc7329bc91da11d89181e1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 11 Mar 2008 16:05:26 +1000 Subject: drm: fix oops on unload. if we are unloading the module, there is no master so therefore no lock --- shared-core/i915_init.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 274322e1..fa2fc3da 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -277,7 +277,6 @@ int i915_driver_unload(struct drm_device *dev) I915_WRITE(LP_RING + RING_LEN, 0); - if (drm_core_check_feature(dev, DRIVER_MODESET)) { drm_irq_uninstall(dev); intel_modeset_cleanup(dev); @@ -291,7 +290,6 @@ int i915_driver_unload(struct drm_device *dev) 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; } -- cgit v1.2.3 From 903d9231d6f998657cc80ee6f20ded4df68e691b Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Tue, 11 Mar 2008 20:29:37 +0000 Subject: Add support for monitor hotplug signals/waits Also adjust i915 irq handling as it follows the 16bit'ism's of the i8xx series. --- shared-core/drm.h | 34 +++++++ shared-core/i915_drv.h | 17 ++-- shared-core/i915_irq.c | 246 +++++++++++++++++++++++++++++++------------------ 3 files changed, 202 insertions(+), 95 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 303a84b6..a1ebfb93 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -555,6 +555,39 @@ union drm_wait_vblank { struct drm_wait_vblank_reply reply; }; +/* Handle monitor hotplug. + * + * May want to extend this later to pass reply information which + * details the outputs which generated the hotplug event. + * Some chipsets can't determine that though, and we'd need to leave + * it to the higher levels to determine exactly what changed. + */ +enum drm_hotplug_seq_type { + _DRM_HOTPLUG_SIGNAL = 0x00000001, /**< Send signal instead of blocking */ +}; + +struct drm_wait_hotplug_request { + enum drm_hotplug_seq_type type; + unsigned long signal; +}; + +struct drm_wait_hotplug_reply { + enum drm_hotplug_seq_type type; + unsigned int counter; + long tval_sec; + long tval_usec; +}; + +/** + * DRM_IOCTL_WAIT_HOTPLUG ioctl argument type. + * + * \sa drmWaitHotplug(). + */ +union drm_wait_hotplug { + struct drm_wait_hotplug_request request; + struct drm_wait_hotplug_reply reply; +}; + enum drm_modeset_ctl_cmd { _DRM_PRE_MODESET = 1, _DRM_POST_MODESET = 2, @@ -1238,6 +1271,7 @@ struct drm_mode_hotplug { #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) +#define DRM_IOCTL_WAIT_HOTPLUG DRM_IOWR(0xAE, union drm_wait_hotplug) /*@}*/ diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index b8dfbc34..fb855933 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -307,8 +307,8 @@ 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(struct drm_i915_private *dev_priv); -extern void i915_user_irq_off(struct drm_i915_private *dev_priv); +extern void i915_user_irq_on(struct drm_device *dev); +extern void i915_user_irq_off(struct drm_device *dev); /* i915_mem.c */ extern int i915_mem_alloc(struct drm_device *dev, void *data, @@ -536,6 +536,12 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define I915REG_PIPEASTAT 0x70024 #define I915REG_PIPEBSTAT 0x71024 + +#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) +#define I915_HOTPLUG_INTERRUPT_ENABLE (1UL<<26) +#define I915_HOTPLUG_CLEAR (1UL<<10) +#define I915_VBLANK_CLEAR (1UL<<1) + /* * The two pipe frame counter registers are not synchronized, so * reading a stable value is somewhat tricky. The following code @@ -567,9 +573,6 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define PIPE_PIXEL_MASK 0x00ffffff #define PIPE_PIXEL_SHIFT 0 -#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) -#define I915_VBLANK_CLEAR (1UL<<1) - #define GPIOA 0x5010 #define GPIOB 0x5014 #define GPIOC 0x5018 @@ -1153,8 +1156,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define SDVOB_PCIE_CONCURRENCY (1 << 3) #define SDVO_DETECTED (1 << 2) /* Bits to be preserved when writing */ -#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14)) -#define SDVOC_PRESERVE_MASK (1 << 17) +#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14) | (1 << 26)) +#define SDVOC_PRESERVE_MASK ((1 << 17) | (1 << 26)) /** @defgroup LVDS * @{ diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index b9d137f4..4127383a 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -34,7 +34,9 @@ #include "intel_drv.h" #define USER_INT_FLAG (1<<1) +#define EVENT_PIPEB_FLAG (1<<4) #define VSYNC_PIPEB_FLAG (1<<5) +#define EVENT_PIPEA_FLAG (1<<6) #define VSYNC_PIPEA_FLAG (1<<7) #define HOTPLUG_FLAG (1 << 17) @@ -158,13 +160,14 @@ static void i915_vblank_tasklet(struct drm_device *dev) int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages; unsigned counter[2]; struct drm_drawable_info *drw; - struct drm_i915_sarea *sarea_priv; + struct drm_i915_sarea *sarea_priv = master_priv->sarea_priv; u32 cpp = dev_priv->cpp, offsets[3]; u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB) : XY_SRC_COPY_BLT_CMD; - u32 pitchropcpp; + u32 pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) | + (cpp << 23) | (1 << 24); RING_LOCALS; counter[0] = drm_vblank_count(dev, 0); @@ -434,7 +437,7 @@ 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) +static void i915_hotplug_crt(struct drm_device *dev, bool isconnected) { struct drm_output *output; struct intel_output *iout; @@ -453,7 +456,7 @@ static void i915_hotplug_crt(struct drm_device *dev, bool connected) if (iout == 0) goto unlock; - drm_hotplug_stage_two(dev, output, connected); + drm_hotplug_stage_two(dev, output, isconnected); unlock: mutex_unlock(&dev->mode_config.mutex); @@ -468,10 +471,8 @@ static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB) output = intel_sdvo_find(dev, sdvoB); - if (!output) { - DRM_ERROR("could not find sdvo%s output\n", sdvoB ? "B" : "C"); + if (!output) goto unlock; - } status = output->funcs->detect(output); @@ -480,7 +481,6 @@ static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB) else drm_hotplug_stage_two(dev, output, true); - /* wierd hw bug, sdvo stop sending interupts */ intel_sdvo_set_hotplug(output, 1); unlock: @@ -521,6 +521,7 @@ static void i915_hotplug_work_func(struct work_struct *work) if (sdvoC) i915_hotplug_sdvo(dev, 0); + drm_handle_hotplug(dev); } static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat) @@ -575,45 +576,21 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) 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); - - /* On i8xx hw the IIR and IER are 16bit on i9xx its 32bit */ - if (IS_I9XX(dev)) + /* On i8xx/i915 hw the IIR and IER are 16bit on i9xx its 32bit */ + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(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); - } + pipea_stats = I915_READ(I915REG_PIPEASTAT); + pipeb_stats = I915_READ(I915REG_PIPEBSTAT); /* * Clear the PIPE(A|B)STAT regs before the IIR otherwise @@ -621,25 +598,40 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) */ if (temp & VSYNC_PIPEA_FLAG) { drm_handle_vblank(dev, i915_get_plane(dev, 0)); - I915_WRITE(I915REG_PIPEASTAT, - pipea_stats | I915_VBLANK_INTERRUPT_ENABLE | - I915_VBLANK_CLEAR); + + 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, - pipeb_stats | I915_VBLANK_INTERRUPT_ENABLE | - I915_VBLANK_CLEAR); + + pipeb_stats |= I915_VBLANK_INTERRUPT_ENABLE | + I915_VBLANK_CLEAR; } - I915_WRITE16(I915REG_INT_IDENTITY_R, temp); - (void) I915_READ16(I915REG_INT_IDENTITY_R); /* Flush posted write */ + if (temp & EVENT_PIPEA_FLAG) + pipea_stats |= I915_HOTPLUG_INTERRUPT_ENABLE | + I915_HOTPLUG_CLEAR; - DRM_READMEMORYBARRIER(); + if (temp & EVENT_PIPEB_FLAG) + pipeb_stats |= I915_HOTPLUG_INTERRUPT_ENABLE | + I915_HOTPLUG_CLEAR; + + I915_WRITE(I915REG_PIPEASTAT, pipea_stats); + (void) I915_READ(I915REG_PIPEASTAT); + I915_WRITE(I915REG_PIPEBSTAT, pipeb_stats); + (void) I915_READ(I915REG_PIPEBSTAT); + + /* Clear the generated interrupt */ + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(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); + } - temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG | VSYNC_PIPEA_FLAG | - VSYNC_PIPEB_FLAG); if (dev->primary->master) { master_priv = dev->primary->master->driver_priv; @@ -658,15 +650,43 @@ 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"); + if (temp & (HOTPLUG_FLAG | EVENT_PIPEA_FLAG | EVENT_PIPEB_FLAG)) { + u32 temp2 = 0; - temp2 = I915_READ(PORT_HOTPLUG_STAT); + DRM_INFO("Hotplug event received\n"); - i915_run_hotplug_tasklet(dev, temp2); + if (!IS_I9XX(dev) || IS_I915G(dev) || IS_I915GM(dev)) { +#if 0 + u32 b,c; + + b = I915_READ(SDVOB) & SDVO_PIPE_B_SELECT; + c = I915_READ(SDVOC) & SDVO_PIPE_B_SELECT; + + if (temp & EVENT_PIPEA_FLAG) { + if (!b) + temp2 |= SDVOB_HOTPLUG_INT_STATUS; + if (!c) + temp2 |= SDVOC_HOTPLUG_INT_STATUS; + + } + + if (temp & EVENT_PIPEB_FLAG) { + if (b) + temp2 |= SDVOB_HOTPLUG_INT_STATUS; + if (c) + temp2 |= SDVOC_HOTPLUG_INT_STATUS; + + } +#else + temp2 |= SDVOB_HOTPLUG_INT_STATUS | + SDVOC_HOTPLUG_INT_STATUS; +#endif + } else { + temp2 = I915_READ(PORT_HOTPLUG_STAT); - I915_WRITE(PORT_HOTPLUG_STAT,temp2); + I915_WRITE(PORT_HOTPLUG_STAT, temp2); + } + i915_run_hotplug_tasklet(dev, temp2); } return IRQ_HANDLED; @@ -691,23 +711,33 @@ int i915_emit_irq(struct drm_device *dev) return dev_priv->counter; } -void i915_user_irq_on(struct drm_i915_private *dev_priv) +void i915_user_irq_on(struct drm_device *dev) { + struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; + DRM_SPINLOCK(&dev_priv->user_irq_lock); if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1)){ dev_priv->irq_enable_reg |= USER_INT_FLAG; - I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(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_SPINUNLOCK(&dev_priv->user_irq_lock); } -void i915_user_irq_off(struct drm_i915_private *dev_priv) +void i915_user_irq_off(struct drm_device *dev) { + struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; + DRM_SPINLOCK(&dev_priv->user_irq_lock); if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { // dev_priv->irq_enable_reg &= ~USER_INT_FLAG; - // I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + // if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(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_SPINUNLOCK(&dev_priv->user_irq_lock); } @@ -725,10 +755,10 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) if (READ_BREADCRUMB(dev_priv) >= irq_nr) return 0; - i915_user_irq_on(dev_priv); + i915_user_irq_on(dev); DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, READ_BREADCRUMB(dev_priv) >= irq_nr); - i915_user_irq_off(dev_priv); + i915_user_irq_off(dev); if (ret == -EBUSY) { DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", @@ -803,7 +833,10 @@ int i915_enable_vblank(struct drm_device *dev, int plane) break; } - I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) + I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + else + I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); return 0; } @@ -826,7 +859,10 @@ void i915_disable_vblank(struct drm_device *dev, int plane) break; } - I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) + I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + else + I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); } void i915_enable_interrupt (struct drm_device *dev) @@ -836,40 +872,62 @@ void i915_enable_interrupt (struct drm_device *dev) dev_priv->irq_enable_reg |= USER_INT_FLAG; - if (IS_I9XX(dev) && dev->mode_config.num_output) { - dev_priv->irq_enable_reg |= HOTPLUG_FLAG; + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { + if (dev->mode_config.num_output) + dev_priv->irq_enable_reg |= HOTPLUG_FLAG; + } else { + if (dev->mode_config.num_output) + dev_priv->irq_enable_reg |= EVENT_PIPEA_FLAG | EVENT_PIPEB_FLAG; + + I915_WRITE(I915REG_PIPEASTAT, I915_READ(I915REG_PIPEASTAT) | I915_HOTPLUG_INTERRUPT_ENABLE | I915_HOTPLUG_CLEAR); + I915_WRITE(I915REG_PIPEBSTAT, I915_READ(I915REG_PIPEBSTAT) | I915_HOTPLUG_INTERRUPT_ENABLE | I915_HOTPLUG_CLEAR); + } + + if (dev_priv->irq_enable_reg & (HOTPLUG_FLAG | EVENT_PIPEA_FLAG | EVENT_PIPEB_FLAG)) { + u32 temp = 0; - /* Activate the CRT */ - I915_WRITE(PORT_HOTPLUG_EN, CRT_HOTPLUG_INT_EN); + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { + temp = I915_READ(PORT_HOTPLUG_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); + /* Activate the CRT */ + temp |= CRT_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)) { + /* SDVOB */ + o = intel_sdvo_find(dev, 1); + if (o && intel_sdvo_supports_hotplug(o)) { + intel_sdvo_set_hotplug(o, 1); + temp |= SDVOB_HOTPLUG_INT_EN; + } + + /* SDVOC */ + o = intel_sdvo_find(dev, 0); + if (o && intel_sdvo_supports_hotplug(o)) { + intel_sdvo_set_hotplug(o, 1); + temp |= SDVOC_HOTPLUG_INT_EN; + } + + I915_WRITE(SDVOB, I915_READ(SDVOB) | SDVO_INTERRUPT_ENABLE); + I915_WRITE(SDVOC, I915_READ(SDVOC) | SDVO_INTERRUPT_ENABLE); + } else { + /* DVO ???? */ } + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { + I915_WRITE(PORT_HOTPLUG_EN, temp); + + DRM_DEBUG("HEN %08x\n",I915_READ(PORT_HOTPLUG_EN)); + DRM_DEBUG("HST %08x\n",I915_READ(PORT_HOTPLUG_STAT)); + + I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); + } } - if (IS_I9XX(dev)) { + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); - } else { + 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; } @@ -909,7 +967,11 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data, return -EINVAL; } - flag = I915_READ(I915REG_INT_ENABLE_R); + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) + flag = I915_READ(I915REG_INT_ENABLE_R); + else + flag = I915_READ16(I915REG_INT_ENABLE_R); + pipe->pipe = 0; if (flag & VSYNC_PIPEA_FLAG) pipe->pipe |= DRM_I915_VBLANK_PIPE_A; @@ -1086,8 +1148,10 @@ void i915_driver_irq_preinstall(struct drm_device * dev) { struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; + I915_WRITE(I915REG_PIPEASTAT, 0xffff); + I915_WRITE(I915REG_PIPEBSTAT, 0xffff); I915_WRITE16(I915REG_HWSTAM, 0xeffe); - if (IS_I9XX(dev)) { + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { I915_WRITE(I915REG_INT_MASK_R, 0x0); I915_WRITE(I915REG_INT_ENABLE_R, 0x0); } else { @@ -1114,6 +1178,10 @@ int i915_driver_irq_postinstall(struct drm_device * dev) if (ret) return ret; + ret = drm_hotplug_init(dev); + if (ret) + return ret; + dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ i915_enable_interrupt(dev); @@ -1138,7 +1206,9 @@ void i915_driver_irq_uninstall(struct drm_device * dev) dev_priv->irq_enabled = 0; - if(IS_I9XX(dev)) { + I915_WRITE(I915REG_PIPEASTAT, 0xffff); + I915_WRITE(I915REG_PIPEBSTAT, 0xffff); + if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { I915_WRITE(I915REG_HWSTAM, 0xffffffff); I915_WRITE(I915REG_INT_MASK_R, 0xffffffff); I915_WRITE(I915REG_INT_ENABLE_R, 0x0); -- cgit v1.2.3 From cf1a2499ed9a0051bcd8627136fb53b496b6484c Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Tue, 11 Mar 2008 21:24:29 +0000 Subject: global hotplug events happen in the pipe A stat register, they are not pipe A specific. Remove pipe B code. --- shared-core/i915_irq.c | 38 +++++++++----------------------------- 1 file changed, 9 insertions(+), 29 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 4127383a..558693f1 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -577,6 +577,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; u32 temp = 0; u32 pipea_stats, pipeb_stats; + int hotplug = 0; /* On i8xx/i915 hw the IIR and IER are 16bit on i9xx its 32bit */ if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) @@ -610,13 +611,15 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) I915_VBLANK_CLEAR; } - if (temp & EVENT_PIPEA_FLAG) + /* This is a global event, and not a pipe A event */ + if (temp & EVENT_PIPEA_FLAG) { + if (pipea_stats & I915_HOTPLUG_CLEAR) + hotplug = 1; + pipea_stats |= I915_HOTPLUG_INTERRUPT_ENABLE | I915_HOTPLUG_CLEAR; - if (temp & EVENT_PIPEB_FLAG) - pipeb_stats |= I915_HOTPLUG_INTERRUPT_ENABLE | - I915_HOTPLUG_CLEAR; + } I915_WRITE(I915REG_PIPEASTAT, pipea_stats); (void) I915_READ(I915REG_PIPEASTAT); @@ -650,37 +653,14 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) drm_locked_tasklet(dev, i915_vblank_tasklet); } - if (temp & (HOTPLUG_FLAG | EVENT_PIPEA_FLAG | EVENT_PIPEB_FLAG)) { + if ((temp & HOTPLUG_FLAG) || hotplug) { u32 temp2 = 0; DRM_INFO("Hotplug event received\n"); if (!IS_I9XX(dev) || IS_I915G(dev) || IS_I915GM(dev)) { -#if 0 - u32 b,c; - - b = I915_READ(SDVOB) & SDVO_PIPE_B_SELECT; - c = I915_READ(SDVOC) & SDVO_PIPE_B_SELECT; - - if (temp & EVENT_PIPEA_FLAG) { - if (!b) - temp2 |= SDVOB_HOTPLUG_INT_STATUS; - if (!c) - temp2 |= SDVOC_HOTPLUG_INT_STATUS; - - } - - if (temp & EVENT_PIPEB_FLAG) { - if (b) - temp2 |= SDVOB_HOTPLUG_INT_STATUS; - if (c) - temp2 |= SDVOC_HOTPLUG_INT_STATUS; - - } -#else temp2 |= SDVOB_HOTPLUG_INT_STATUS | SDVOC_HOTPLUG_INT_STATUS; -#endif } else { temp2 = I915_READ(PORT_HOTPLUG_STAT); @@ -879,8 +859,8 @@ void i915_enable_interrupt (struct drm_device *dev) if (dev->mode_config.num_output) dev_priv->irq_enable_reg |= EVENT_PIPEA_FLAG | EVENT_PIPEB_FLAG; + /* Enable global interrupts for hotplug - not a pipeA event */ I915_WRITE(I915REG_PIPEASTAT, I915_READ(I915REG_PIPEASTAT) | I915_HOTPLUG_INTERRUPT_ENABLE | I915_HOTPLUG_CLEAR); - I915_WRITE(I915REG_PIPEBSTAT, I915_READ(I915REG_PIPEBSTAT) | I915_HOTPLUG_INTERRUPT_ENABLE | I915_HOTPLUG_CLEAR); } if (dev_priv->irq_enable_reg & (HOTPLUG_FLAG | EVENT_PIPEA_FLAG | EVENT_PIPEB_FLAG)) { -- cgit v1.2.3 From 2d0411cb7544ea45b5879d4f454cb9ee3c9ff5fb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 17 Mar 2008 16:34:15 +1000 Subject: i915: safety check the sarea map still exists --- shared-core/i915_init.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index fa2fc3da..a76acb4e 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -383,7 +383,9 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master) if (!master_priv) return; - drm_rmmap(dev, master_priv->sarea); + if (master_priv->sarea) + drm_rmmap(dev, master_priv->sarea); + drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER); master->driver_priv = NULL; -- cgit v1.2.3 From 607964ed9e5f6d86a0960bef2341e7f5de9c71da Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 17 Mar 2008 16:37:46 +1000 Subject: drm: add master set/drop protocol this may not survive long - just need something for testing --- shared-core/drm.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index a1ebfb93..a72263ae 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1200,6 +1200,9 @@ struct drm_mode_hotplug { #define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map) #define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map) +#define DRM_IOCTL_SET_MASTER DRM_IO(0x1e) +#define DRM_IOCTL_DROP_MASTER DRM_IO(0x1f) + #define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx) #define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx) #define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx) -- cgit v1.2.3 From 6ef119abf5d19c85fe039fd19d12e9bd64fd44df Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 20 Mar 2008 17:43:43 +0100 Subject: radeon_ms: fix fence --- shared-core/amd_legacy_fence.h | 39 +++++++++++++++++++++++++++++++++++++++ shared-core/radeon_ms.h | 1 - shared-core/radeon_ms_drm.c | 7 ++++--- shared-core/radeon_ms_fence.c | 16 ++++++++-------- 4 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 shared-core/amd_legacy_fence.h (limited to 'shared-core') diff --git a/shared-core/amd_legacy_fence.h b/shared-core/amd_legacy_fence.h new file mode 100644 index 00000000..d82138ba --- /dev/null +++ b/shared-core/amd_legacy_fence.h @@ -0,0 +1,39 @@ +/* + * 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 + */ +#ifndef __AMD_LEGACY_FENCE_H__ +#define __AMD_LEGACY_FENCE_H__ + +struct legacy_fence +{ + uint32_t sequence; + uint32_t sequence_last_reported; + uint32_t sequence_last_flush; + uint32_t fence_reg; +}; + +#endif diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h index 12c945f9..d9aa0351 100644 --- a/shared-core/radeon_ms.h +++ b/shared-core/radeon_ms.h @@ -31,7 +31,6 @@ #define __RADEON_MS_H__ #include "radeon_ms_drv.h" -#include "amd_r3xx_fence.h" #include "radeon_ms_reg.h" #include "radeon_ms_drm.h" #include "radeon_ms_rom.h" diff --git a/shared-core/radeon_ms_drm.c b/shared-core/radeon_ms_drm.c index b9245d99..40f5d791 100644 --- a/shared-core/radeon_ms_drm.c +++ b/shared-core/radeon_ms_drm.c @@ -29,6 +29,7 @@ */ #include "drm_pciids.h" #include "radeon_ms.h" +#include "amd_legacy_fence.h" static uint32_t radeon_ms_mem_prios[] = { @@ -116,12 +117,12 @@ int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags) return ret; } - dev_priv->fence = drm_alloc(sizeof(struct r3xx_fence), DRM_MEM_DRIVER); + dev_priv->fence = drm_alloc(sizeof(struct legacy_fence), DRM_MEM_DRIVER); if (dev_priv->fence == NULL) { radeon_ms_driver_unload(dev); return -ENOMEM; } - memset(dev_priv->fence, 0, sizeof(struct r3xx_fence)); + memset(dev_priv->fence, 0, sizeof(struct legacy_fence)); /* we don't want userspace to be able to map this so don't use * drm_addmap */ @@ -305,7 +306,7 @@ int radeon_ms_driver_unload(struct drm_device *dev) drm_core_ioremapfree(&dev_priv->vram, dev); } DRM_INFO("[radeon_ms] map released\n"); - drm_free(dev_priv->fence, sizeof(struct r3xx_fence), DRM_MEM_DRIVER); + drm_free(dev_priv->fence, sizeof(struct legacy_fence), DRM_MEM_DRIVER); drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); dev->dev_private = NULL; diff --git a/shared-core/radeon_ms_fence.c b/shared-core/radeon_ms_fence.c index 162d37d6..994c3e48 100644 --- a/shared-core/radeon_ms_fence.c +++ b/shared-core/radeon_ms_fence.c @@ -27,7 +27,7 @@ * Jerome Glisse */ #include "radeon_ms.h" -#include "amd_r3xx_fence.h" +#include "amd_legacy_fence.h" #define R3XX_FENCE_SEQUENCE_RW_FLUSH 0x80000000u @@ -35,7 +35,7 @@ static inline int r3xx_fence_emit_sequence(struct drm_device *dev, struct drm_radeon_private *dev_priv, uint32_t sequence) { - struct r3xx_fence *r3xx_fence = dev_priv->fence; + struct legacy_fence *r3xx_fence = dev_priv->fence; uint32_t cmd[2]; int i, r; @@ -58,7 +58,7 @@ static inline int r3xx_fence_emit_sequence(struct drm_device *dev, return -EBUSY; } -static inline uint32_t r3xx_fence_sequence(struct r3xx_fence *r3xx_fence) +static inline uint32_t r3xx_fence_sequence(struct legacy_fence *r3xx_fence) { r3xx_fence->sequence += 1; if (unlikely(r3xx_fence->sequence > 0x7fffffffu)) { @@ -69,7 +69,7 @@ static inline uint32_t r3xx_fence_sequence(struct r3xx_fence *r3xx_fence) static inline void r3xx_fence_report(struct drm_device *dev, struct drm_radeon_private *dev_priv, - struct r3xx_fence *r3xx_fence) + struct legacy_fence *r3xx_fence) { uint32_t fence_types = DRM_FENCE_TYPE_EXE; uint32_t sequence; @@ -95,7 +95,7 @@ static inline void r3xx_fence_report(struct drm_device *dev, static void r3xx_fence_flush(struct drm_device *dev, uint32_t class) { struct drm_radeon_private *dev_priv = dev->dev_private; - struct r3xx_fence *r3xx_fence = dev_priv->fence; + struct legacy_fence *r3xx_fence = dev_priv->fence; uint32_t sequence; sequence = r3xx_fence_sequence(r3xx_fence); @@ -109,7 +109,7 @@ static void r3xx_fence_poll(struct drm_device *dev, uint32_t fence_class, struct drm_radeon_private *dev_priv = dev->dev_private; struct drm_fence_manager *fm = &dev->fm; struct drm_fence_class_manager *fc = &fm->fence_class[fence_class]; - struct r3xx_fence *r3xx_fence = dev_priv->fence; + struct legacy_fence *r3xx_fence = dev_priv->fence; if (unlikely(!dev_priv)) { return; @@ -129,7 +129,7 @@ static int r3xx_fence_emit(struct drm_device *dev, uint32_t class, uint32_t *native_type) { struct drm_radeon_private *dev_priv = dev->dev_private; - struct r3xx_fence *r3xx_fence = dev_priv->fence; + struct legacy_fence *r3xx_fence = dev_priv->fence; uint32_t tmp; if (!dev_priv || dev_priv->cp_ready != 1) { @@ -162,7 +162,7 @@ static uint32_t r3xx_fence_needed_flush(struct drm_fence_object *fence) { struct drm_device *dev = fence->dev; struct drm_radeon_private *dev_priv = dev->dev_private; - struct r3xx_fence *r3xx_fence = dev_priv->fence; + struct legacy_fence *r3xx_fence = dev_priv->fence; struct drm_fence_driver *driver = dev->driver->fence_driver; uint32_t flush_types, diff; -- cgit v1.2.3 From 0da289bafd2da72a14f3d5cf82fec836d30f7b8d Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 27 Mar 2008 20:08:37 +0100 Subject: radeon_ms: this is a modesetting driver, bring things up to date --- shared-core/radeon_ms_drm.c | 15 ++++++++++++++- shared-core/radeon_ms_exec.c | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_ms_drm.c b/shared-core/radeon_ms_drm.c index 40f5d791..b3fb7e03 100644 --- a/shared-core/radeon_ms_drm.c +++ b/shared-core/radeon_ms_drm.c @@ -155,7 +155,13 @@ int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags) /* init bo driver */ dev_priv->fence_id_last = 1; dev_priv->fence_reg = SCRATCH_REG2; - drm_bo_driver_init(dev); + ret = drm_bo_driver_init(dev); + if (ret != 0) { + DRM_INFO("[radeon_ms] failed to init bo driver %d.\n", ret); + radeon_ms_driver_unload(dev); + return ret; + } + DRM_INFO("[radeon_ms] bo driver succesfull %d.\n", dev->bm.initialized); /* initialize vram */ ret = drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, dev_priv->vram.size, 1); if (ret != 0) { @@ -239,6 +245,13 @@ int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags) return ret; } + if (dev->primary && dev->control) { + DRM_INFO("[radeon_ms] control 0x%lx, render 0x%lx\n", + (long)dev->primary->device, (long)dev->control->device); + } else { + DRM_INFO("[radeon_ms] error control 0x%lx, render 0x%lx\n", + (long)dev->primary, (long)dev->control); + } DRM_INFO("[radeon_ms] successfull initialization\n"); return 0; } diff --git a/shared-core/radeon_ms_exec.c b/shared-core/radeon_ms_exec.c index 8e28b19e..d8f67842 100644 --- a/shared-core/radeon_ms_exec.c +++ b/shared-core/radeon_ms_exec.c @@ -79,10 +79,10 @@ static int radeon_ms_execbuffer_args(struct drm_device *dev, 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, + arg.d.req.bo_req.fence_class, 0, &rep.bo_info, &buffers[args_count]); -- cgit v1.2.3 From 2d9eccfd056425e4ebdf1a7b879979fd0a9d1340 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sun, 30 Mar 2008 12:45:57 +0200 Subject: radeon_ms: add hang debuging helper functions --- shared-core/Makefile.am | 1 + shared-core/radeon_ms.h | 2 ++ shared-core/radeon_ms_cp.c | 51 ++++++++++++++++++++++++++--- shared-core/radeon_ms_drm.c | 1 + shared-core/radeon_ms_drm.h | 1 + shared-core/radeon_ms_exec.c | 34 ++++++++++--------- shared-core/radeon_ms_gpu.c | 59 +++++++++++++++++++-------------- shared-core/radeon_ms_reg.h | 77 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 182 insertions(+), 44 deletions(-) (limited to 'shared-core') diff --git a/shared-core/Makefile.am b/shared-core/Makefile.am index 7193e527..42e08e75 100644 --- a/shared-core/Makefile.am +++ b/shared-core/Makefile.am @@ -32,6 +32,7 @@ klibdrminclude_HEADERS = \ nouveau_drm.h \ r128_drm.h \ radeon_drm.h \ + radeon_ms_drm.h \ savage_drm.h \ sis_drm.h \ via_drm.h \ diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h index d9aa0351..13e41e1b 100644 --- a/shared-core/radeon_ms.h +++ b/shared-core/radeon_ms.h @@ -373,6 +373,8 @@ 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); +int radeon_ms_resetcp(struct drm_device *dev, void *data, + struct drm_file *file_priv); /* radeon_ms_crtc.c */ int radeon_ms_crtc_create(struct drm_device *dev, int crtc); diff --git a/shared-core/radeon_ms_cp.c b/shared-core/radeon_ms_cp.c index c01769bd..7b26c0ba 100644 --- a/shared-core/radeon_ms_cp.c +++ b/shared-core/radeon_ms_cp.c @@ -156,7 +156,7 @@ int radeon_ms_cp_init(struct drm_device *dev) 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); + DRM_INFO("[radeon_ms] error mapping ring buffer: %d\n", ret); return ret; } dev_priv->ring_buffer = dev_priv->ring_buffer_map.virtual; @@ -275,15 +275,32 @@ void radeon_ms_cp_save(struct drm_device *dev, struct radeon_state *state) void radeon_ms_cp_stop(struct drm_device *dev) { struct drm_radeon_private *dev_priv = dev->dev_private; + uint32_t rbbm_status, rbbm_status_cp_mask; - MMIO_W(CP_CSQ_CNTL, REG_S(CP_CSQ_CNTL, CSQ_MODE, - CSQ_MODE__CSQ_PRIDIS_INDDIS)); + dev_priv->cp_ready = 0; + MMIO_W(CP_CSQ_CNTL, 0); + MMIO_R(CP_CSQ_CNTL); + MMIO_W(CP_CSQ_MODE, 0); + MMIO_R(CP_CSQ_MODE); + MMIO_W(RBBM_SOFT_RESET, RBBM_SOFT_RESET__SOFT_RESET_CP); + MMIO_R(RBBM_SOFT_RESET); + MMIO_W(RBBM_SOFT_RESET, 0); + MMIO_R(RBBM_SOFT_RESET); + rbbm_status = MMIO_R(RBBM_STATUS); + rbbm_status_cp_mask = (RBBM_STATUS__CPRQ_ON_RBB | + RBBM_STATUS__CPRQ_IN_RTBUF | + RBBM_STATUS__CP_CMDSTRM_BUSY); + if (rbbm_status & rbbm_status_cp_mask) { + DRM_INFO("[radeon_ms] cp busy (RBBM_STATUS: 0x%08X " + "RBBM_STATUS(cp_mask): 0x%08X)\n", rbbm_status, + rbbm_status_cp_mask); + } 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); + MMIO_W(CP_RB_CNTL, 0); } int radeon_ms_cp_wait(struct drm_device *dev, int n) @@ -332,6 +349,7 @@ int radeon_ms_ring_emit(struct drm_device *dev, uint32_t *cmd, uint32_t count) dev_priv->ring_free -= count; for (i = 0; i < count; i++) { dev_priv->ring_buffer[dev_priv->ring_wptr] = cmd[i]; + DRM_INFO("ring[%d] = 0x%08X\n", dev_priv->ring_wptr, cmd[i]); dev_priv->ring_wptr++; dev_priv->ring_wptr &= dev_priv->ring_mask; } @@ -343,3 +361,28 @@ int radeon_ms_ring_emit(struct drm_device *dev, uint32_t *cmd, uint32_t count) spin_unlock(&ring_lock); return 0; } + +int radeon_ms_resetcp(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + int i; + + DRM_INFO("[radeon_ms]--------------------------------------------\n"); + + /* reset VAP */ + DRM_INFO("[radeon_ms] status before VAP : RBBM_STATUS: 0x%08X\n", + MMIO_R(RBBM_STATUS)); + MMIO_W(RBBM_SOFT_RESET, RBBM_SOFT_RESET__SOFT_RESET_VAP); + MMIO_R(RBBM_SOFT_RESET); + MMIO_W(RBBM_SOFT_RESET, 0); + MMIO_R(RBBM_SOFT_RESET); + for (i = 0; i < 100; i++) { + DRM_UDELAY(100); + } + DRM_INFO("[radeon_ms] status after VAP : RBBM_STATUS: 0x%08X\n", + MMIO_R(RBBM_STATUS)); + + DRM_INFO("[radeon_ms]--------------------------------------------\n"); + return 0; +} diff --git a/shared-core/radeon_ms_drm.c b/shared-core/radeon_ms_drm.c index b3fb7e03..869ccac4 100644 --- a/shared-core/radeon_ms_drm.c +++ b/shared-core/radeon_ms_drm.c @@ -60,6 +60,7 @@ struct drm_bo_driver radeon_ms_bo_driver = { struct drm_ioctl_desc radeon_ms_ioctls[] = { DRM_IOCTL_DEF(DRM_RADEON_EXECBUFFER, radeon_ms_execbuffer, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_RESETCP, radeon_ms_resetcp, DRM_AUTH), }; int radeon_ms_num_ioctls = DRM_ARRAY_SIZE(radeon_ms_ioctls); diff --git a/shared-core/radeon_ms_drm.h b/shared-core/radeon_ms_drm.h index 39c050ad..e1b4c18c 100644 --- a/shared-core/radeon_ms_drm.h +++ b/shared-core/radeon_ms_drm.h @@ -47,6 +47,7 @@ /* radeon ms ioctl */ #define DRM_RADEON_EXECBUFFER 0x00 +#define DRM_RADEON_RESETCP 0x01 struct drm_radeon_execbuffer_arg { uint64_t next; diff --git a/shared-core/radeon_ms_exec.c b/shared-core/radeon_ms_exec.c index d8f67842..68b3e145 100644 --- a/shared-core/radeon_ms_exec.c +++ b/shared-core/radeon_ms_exec.c @@ -210,24 +210,26 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, } /* 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_types; - fence_arg->sequence = fence->sequence; + if (execbuffer->args_count > 1) { + 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_types; + fence_arg->sequence = fence->sequence; + } } + drm_fence_usage_deref_unlocked(&fence); } - drm_fence_usage_deref_unlocked(&fence); out_free_release: drm_bo_kunmap(&cmd_kmap); radeon_ms_execbuffer_args_clean(dev, buffers, execbuffer->args_count); diff --git a/shared-core/radeon_ms_gpu.c b/shared-core/radeon_ms_gpu.c index 28683781..21c86027 100644 --- a/shared-core/radeon_ms_gpu.c +++ b/shared-core/radeon_ms_gpu.c @@ -128,9 +128,20 @@ static void radeon_ms_gpu_reset(struct drm_device *dev) MMIO_W(RBBM_SOFT_RESET, 0); MMIO_R(RBBM_SOFT_RESET); +#if 0 cache_mode = MMIO_R(RB2D_DSTCACHE_MODE); MMIO_W(RB2D_DSTCACHE_MODE, cache_mode | RB2D_DSTCACHE_MODE__DC_DISABLE_IGNORE_PE); +#else + reset_mask = RBBM_SOFT_RESET__SOFT_RESET_CP | + RBBM_SOFT_RESET__SOFT_RESET_HI | + RBBM_SOFT_RESET__SOFT_RESET_E2; + MMIO_W(RBBM_SOFT_RESET, rbbm_soft_reset | reset_mask); + MMIO_R(RBBM_SOFT_RESET); + MMIO_W(RBBM_SOFT_RESET, 0); + cache_mode = MMIO_R(RB3D_DSTCACHE_CTLSTAT); + MMIO_W(RB3D_DSTCACHE_CTLSTAT, cache_mode | (0xf)); +#endif MMIO_W(HOST_PATH_CNTL, host_path_cntl | HOST_PATH_CNTL__HDP_SOFT_RESET); MMIO_R(HOST_PATH_CNTL); @@ -166,7 +177,7 @@ static void radeon_ms_gpu_resume(struct drm_device *dev) DRM_UDELAY(1); } if (i >= dev_priv->usec_timeout) { - DRM_ERROR("[radeon_ms] timeout waiting for crtc...\n"); + DRM_INFO("[radeon_ms] timeout waiting for crtc...\n"); } for (i = 0; i < dev_priv->usec_timeout; i++) { if (!(CRTC2_OFFSET__CRTC2_GUI_TRIG_OFFSET & @@ -176,7 +187,7 @@ static void radeon_ms_gpu_resume(struct drm_device *dev) DRM_UDELAY(1); } if (i >= dev_priv->usec_timeout) { - DRM_ERROR("[radeon_ms] timeout waiting for crtc...\n"); + DRM_INFO("[radeon_ms] timeout waiting for crtc...\n"); } DRM_UDELAY(10000); } @@ -187,7 +198,6 @@ static void radeon_ms_gpu_stop(struct drm_device *dev) 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); @@ -244,10 +254,10 @@ static void radeon_ms_gpu_stop(struct drm_device *dev) } break; default: - DRM_ERROR("Unknown radeon family, aborting\n"); + DRM_INFO("Unknown radeon family, aborting\n"); return; } - DRM_ERROR("[radeon_ms] failed to stop gpu...will proceed anyway\n"); + DRM_INFO("[radeon_ms] failed to stop gpu...will proceed anyway\n"); DRM_UDELAY(20000); } @@ -264,7 +274,7 @@ static int radeon_ms_wait_for_fifo(struct drm_device *dev, int num_fifo) return 0; DRM_UDELAY(1); } - DRM_ERROR("[radeon_ms] failed to wait for fifo\n"); + DRM_INFO("[radeon_ms] failed to wait for fifo\n"); return -EBUSY; } @@ -391,7 +401,7 @@ void radeon_ms_gpu_flush(struct drm_device *dev) MMIO_W(RB3D_DSTCACHE_CTLSTAT_R3, purge3d); break; default: - DRM_ERROR("Unknown radeon family, aborting\n"); + DRM_INFO("Unknown radeon family, aborting\n"); return; } for (i = 0; i < dev_priv->usec_timeout; i++) { @@ -401,7 +411,7 @@ void radeon_ms_gpu_flush(struct drm_device *dev) } DRM_UDELAY(1); } - DRM_ERROR("[radeon_ms] gpu flush timeout\n"); + DRM_INFO("[radeon_ms] gpu flush timeout\n"); } void radeon_ms_gpu_restore(struct drm_device *dev, struct radeon_state *state) @@ -478,8 +488,8 @@ void radeon_ms_gpu_restore(struct drm_device *dev, struct radeon_state *state) 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"); + DRM_INFO("[radeon_ms] no fifo for setting up dst & src gui\n"); + DRM_INFO("[radeon_ms] proceed anyway\n"); } fbstart = (MC_FB_LOCATION__MC_FB_START__MASK & MMIO_R(MC_FB_LOCATION)) << 16; @@ -491,8 +501,8 @@ void radeon_ms_gpu_restore(struct drm_device *dev, struct radeon_state *state) 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"); + DRM_INFO("[radeon_ms] no fifo for setting up dp data type\n"); + DRM_INFO("[radeon_ms] proceed anyway\n"); } #ifdef __BIG_ENDIAN MMIO_W(DP_DATATYPE, DP_DATATYPE__DP_BYTE_PIX_ORDER); @@ -503,16 +513,16 @@ void radeon_ms_gpu_restore(struct drm_device *dev, struct radeon_state *state) 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"); + DRM_INFO("[radeon_ms] no fifo for setting up surface cntl\n"); + DRM_INFO("[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"); + DRM_INFO("[radeon_ms] no fifo for setting scissor\n"); + DRM_INFO("[radeon_ms] proceed anyway\n"); } MMIO_W(DEFAULT_SC_BOTTOM_RIGHT, 0x1fff1fff); MMIO_W(DEFAULT2_SC_BOTTOM_RIGHT, 0x1fff1fff); @@ -520,16 +530,16 @@ void radeon_ms_gpu_restore(struct drm_device *dev, struct radeon_state *state) 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"); + DRM_INFO("[radeon_ms] no fifo for setting up gui cntl\n"); + DRM_INFO("[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"); + DRM_INFO("[radeon_ms] no fifo for setting up clear color\n"); + DRM_INFO("[radeon_ms] proceed anyway\n"); } MMIO_W(DP_BRUSH_BKGD_CLR, 0x00000000); MMIO_W(DP_BRUSH_FRGD_CLR, 0xffffffff); @@ -538,7 +548,7 @@ void radeon_ms_gpu_restore(struct drm_device *dev, struct radeon_state *state) MMIO_W(DP_WRITE_MSK, 0xffffffff); if (!ok) { - DRM_ERROR("[radeon_ms] engine restore not enough fifo\n"); + DRM_INFO("[radeon_ms] engine restore not enough fifo\n"); } } @@ -566,12 +576,13 @@ void radeon_ms_gpu_save(struct drm_device *dev, struct radeon_state *state) int radeon_ms_wait_for_idle(struct drm_device *dev) { struct drm_radeon_private *dev_priv = dev->dev_private; + struct radeon_state *state = &dev_priv->driver_state; 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"); + DRM_INFO("[radeon_ms] fifo not empty\n"); } for (j = 0; j < dev_priv->usec_timeout; j++) { if (!(RBBM_STATUS__GUI_ACTIVE & MMIO_R(RBBM_STATUS))) { @@ -580,10 +591,10 @@ int radeon_ms_wait_for_idle(struct drm_device *dev) } DRM_UDELAY(1); } - DRM_ERROR("[radeon_ms] idle timed out: status=0x%08x\n", + DRM_INFO("[radeon_ms] idle timed out: status=0x%08x\n", MMIO_R(RBBM_STATUS)); - radeon_ms_gpu_stop(dev); radeon_ms_gpu_reset(dev); + radeon_ms_gpu_resume(dev); } return -EBUSY; } diff --git a/shared-core/radeon_ms_reg.h b/shared-core/radeon_ms_reg.h index 56963c63..adb6434b 100644 --- a/shared-core/radeon_ms_reg.h +++ b/shared-core/radeon_ms_reg.h @@ -226,6 +226,16 @@ #define SCRATCH_REG7 0x000015FC #define SCRATCH_REG7__SCRATCH_REG7__MASK 0xFFFFFFFF #define SCRATCH_REG7__SCRATCH_REG7__SHIFT 0 +#define SC_SCISSOR0 0x000043E0 +#define SC_SCISSOR0__XS0__MASK 0x00001FFF +#define SC_SCISSOR0__XS0__SHIFT 0 +#define SC_SCISSOR0__YS0__MASK 0x03FFE000 +#define SC_SCISSOR0__YS0__SHIFT 13 +#define SC_SCISSOR1 0x000043E4 +#define SC_SCISSOR1__XS1__MASK 0x00001FFF +#define SC_SCISSOR1__XS1__SHIFT 0 +#define SC_SCISSOR1__YS1__MASK 0x03FFE000 +#define SC_SCISSOR1__YS1__SHIFT 13 #define PCIE_INDEX 0x00000030 #define PCIE_INDEX__PCIE_INDEX__MASK 0x000007FF #define PCIE_INDEX__PCIE_INDEX__SHIFT 0 @@ -276,6 +286,17 @@ #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_CSQ_MODE 0x00000744 +#define CP_CSQ_MODE__INDIRECT2_START__MASK 0x0000007F +#define CP_CSQ_MODE__INDIRECT2_START__SHIFT 0 +#define CP_CSQ_MODE__INDIRECT1_START__MASK 0x00007F00 +#define CP_CSQ_MODE__INDIRECT1_START__SHIFT 8 +#define CP_CSQ_MODE__CSQ_INDIRECT2_MODE 0x04000000 +#define CP_CSQ_MODE__CSQ_INDIRECT2_ENABLE 0x08000000 +#define CP_CSQ_MODE__CSQ_INDIRECT1_MODE 0x10000000 +#define CP_CSQ_MODE__CSQ_INDIRECT1_ENABLE 0x20000000 +#define CP_CSQ_MODE__CSQ_PRIMARY_MODE 0x40000000 +#define CP_CSQ_MODE__CSQ_PRIMARY_ENABLE 0x80000000 #define CP_RB_CNTL 0x00000704 #define CP_RB_CNTL__RB_BUFSZ__MASK 0x0000003F #define CP_RB_CNTL__RB_BUFSZ__SHIFT 0 @@ -1265,6 +1286,33 @@ #define ISYNC_CNTL__ISYNC_TRIG3D_IDLE2D 0x00000008 #define ISYNC_CNTL__ISYNC_WAIT_IDLEGUI 0x00000010 #define ISYNC_CNTL__ISYNC_CPSCRATCH_IDLEGUI 0x00000020 +#define GA_SOFT_RESET 0x0000429C +#define GA_SOFT_RESET__SOFT_RESET_COUNT__MASK 0x0000FFFF +#define GA_SOFT_RESET__SOFT_RESET_COUNT__SHIFT 0 +#define RBBM_CNTL 0x000000EC +#define RBBM_CNTL__RB_SETTLE__MASK 0x0000000F +#define RBBM_CNTL__RB_SETTLE__SHIFT 0 +#define RBBM_CNTL__ABORTCLKS_HI__MASK 0x00000070 +#define RBBM_CNTL__ABORTCLKS_HI__SHIFT 4 +#define RBBM_CNTL__ABORTCLKS_CP__MASK 0x00000700 +#define RBBM_CNTL__ABORTCLKS_CP__SHIFT 8 +#define RBBM_CNTL__ABORTCLKS_CFIFO__MASK 0x00007000 +#define RBBM_CNTL__ABORTCLKS_CFIFO__SHIFT 12 +#define RBBM_CNTL__CPQ_DATA_SWAP 0x00020000 +#define RBBM_CNTL__NO_ABORT_IDCT 0x00200000 +#define RBBM_CNTL__NO_ABORT_BIOS 0x00400000 +#define RBBM_CNTL__NO_ABORT_FB 0x00800000 +#define RBBM_CNTL__NO_ABORT_CP 0x01000000 +#define RBBM_CNTL__NO_ABORT_HI 0x02000000 +#define RBBM_CNTL__NO_ABORT_HDP 0x04000000 +#define RBBM_CNTL__NO_ABORT_MC 0x08000000 +#define RBBM_CNTL__NO_ABORT_AIC 0x10000000 +#define RBBM_CNTL__NO_ABORT_VIP 0x20000000 +#define RBBM_CNTL__NO_ABORT_DISP 0x40000000 +#define RBBM_CNTL__NO_ABORT_CG 0x80000000 +#define RBBM_CNTL__NO_ABORT_VAP 0x00080000 +#define RBBM_CNTL__NO_ABORT_GA 0x00100000 +#define RBBM_CNTL__NO_ABORT_TVOUT 0x00800000 #define RBBM_STATUS 0x00000E40 #define RBBM_STATUS__CMDFIFO_AVAIL__MASK 0x0000007F #define RBBM_STATUS__CMDFIFO_AVAIL__SHIFT 0 @@ -1307,6 +1355,19 @@ #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 RBBM_CMDFIFO_ADDR 0x00000E70 +#define RBBM_CMDFIFO_ADDR__CMDFIFO_ADDR__MASK 0x0000003F +#define RBBM_CMDFIFO_ADDR__CMDFIFO_ADDR__SHIFT 0 +#define RBBM_CMDFIFO_ADDR__CMDFIFO_ADDR_R3__MASK 0x000001FF +#define RBBM_CMDFIFO_ADDR__CMDFIFO_ADDR_R3__SHIFT 0 +#define RBBM_CMDFIFO_DATA 0x00000E74 +#define RBBM_CMDFIFO_DATA__CMDFIFO_DATA__MASK 0xFFFFFFFF +#define RBBM_CMDFIFO_DATA__CMDFIFO_DATA__SHIFT 0 +#define RBBM_CMDFIFO_STAT 0x00000E7C +#define RBBM_CMDFIFO_STAT__CMDFIFO_RPTR__MASK 0x0000003F +#define RBBM_CMDFIFO_STAT__CMDFIFO_RPTR__SHIFT 0 +#define RBBM_CMDFIFO_STAT__CMDFIFO_WPTR__MASK 0x00003F00 +#define RBBM_CMDFIFO_STAT__CMDFIFO_WPTR__SHIFT 8 #define WAIT_UNTIL 0x00001720 #define WAIT_UNTIL__WAIT_CRTC_PFLIP 0x00000001 #define WAIT_UNTIL__WAIT_RE_CRTC_VLINE 0x00000002 @@ -1677,5 +1738,21 @@ #define DP_WRITE_MSK 0x000016CC #define DP_WRITE_MSK__DP_WRITE_MSK__MASK 0xFFFFFFFF #define DP_WRITE_MSK__DP_WRITE_MSK__SHIFT 0 +#define US_CONFIG 0x00004600 +#define US_CONFIG__NLEVEL__MASK 0x00000007 +#define US_CONFIG__NLEVEL__SHIFT 0 +#define US_CONFIG__FIRST_TEX 0x00000008 +#define US_CONFIG__PERF0__MASK 0x000001F0 +#define US_CONFIG__PERF0__SHIFT 4 +#define US_CONFIG__PERF1__MASK 0x00003E00 +#define US_CONFIG__PERF1__SHIFT 9 +#define US_CONFIG__PERF2__MASK 0x0007C000 +#define US_CONFIG__PERF2__SHIFT 14 +#define US_CONFIG__PERF3__MASK 0x00F80000 +#define US_CONFIG__PERF3__SHIFT 19 +#define US_RESET 0x0000460C +#define VAP_PVS_STATE_FLUSH_REG 0x00002284 +#define VAP_PVS_STATE_FLUSH_REG__DATA_REGISTER__MASK 0xFFFFFFFF +#define VAP_PVS_STATE_FLUSH_REG__DATA_REGISTER__SHIFT 0 #endif -- cgit v1.2.3 From 09e637848a6afa54a091c4c70fdfbfbdce7ac805 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Mon, 31 Mar 2008 00:55:05 +0200 Subject: radeon_ms: initial pass at command buffer validation --- shared-core/amd_cbuffer.h | 51 ++++++ shared-core/radeon_ms.h | 16 +- shared-core/radeon_ms_bo.c | 11 +- shared-core/radeon_ms_bus.c | 3 +- shared-core/radeon_ms_cp.c | 31 +--- shared-core/radeon_ms_exec.c | 359 +++++++++++++++++++++++++++++++---------- shared-core/radeon_ms_family.c | 1 + shared-core/radeon_ms_gpu.c | 3 +- shared-core/radeon_ms_reg.h | 29 ++++ 9 files changed, 376 insertions(+), 128 deletions(-) create mode 100644 shared-core/amd_cbuffer.h (limited to 'shared-core') diff --git a/shared-core/amd_cbuffer.h b/shared-core/amd_cbuffer.h new file mode 100644 index 00000000..bca05751 --- /dev/null +++ b/shared-core/amd_cbuffer.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 + */ +#ifndef __AMD_CBUFFER_H__ +#define __AMD_CBUFFER_H__ + +/* struct amd_cbuffer are for command buffer, this is the structure passed + * around during command validation (ie check that user have the right to + * execute the given command). + */ + +struct amd_cbuffer_arg +{ + struct list_head list; + struct drm_buffer_object *buffer; + int32_t dw_id; +}; + +struct amd_cbuffer +{ + uint32_t *cbuffer; + uint32_t cbuffer_dw_count; + struct amd_cbuffer_arg arg_unused; + struct amd_cbuffer_arg arg_used; + struct amd_cbuffer_arg *args; +}; + +#endif diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h index 13e41e1b..e4010d84 100644 --- a/shared-core/radeon_ms.h +++ b/shared-core/radeon_ms.h @@ -35,6 +35,7 @@ #include "radeon_ms_drm.h" #include "radeon_ms_rom.h" #include "radeon_ms_properties.h" +#include "amd_cbuffer.h" #define DRIVER_AUTHOR "Jerome Glisse, Dave Airlie, Gareth Hughes, "\ "Keith Whitwell, others." @@ -483,21 +484,6 @@ 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) diff --git a/shared-core/radeon_ms_bo.c b/shared-core/radeon_ms_bo.c index 6d9a97c1..015595a4 100644 --- a/shared-core/radeon_ms_bo.c +++ b/shared-core/radeon_ms_bo.c @@ -33,6 +33,15 @@ #include "radeon_ms.h" +#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) + void radeon_ms_bo_copy_blit(struct drm_device *dev, uint32_t src_offset, uint32_t dst_offset, @@ -60,7 +69,7 @@ void radeon_ms_bo_copy_blit(struct drm_device *dev, if (c >= 8192) { c = 8191; } - cmd[0] = CP_PACKET3_CNTL_BITBLT_MULTI | (5 << 16); + cmd[0] = CP_PACKET3(PACKET3_OPCODE_BITBLT, 5); cmd[1] = GMC_SRC_PITCH_OFFSET_CNTL | GMC_DST_PITCH_OFFSET_CNTL | GMC_BRUSH_NONE | diff --git a/shared-core/radeon_ms_bus.c b/shared-core/radeon_ms_bus.c index ed8fb211..333fd558 100644 --- a/shared-core/radeon_ms_bus.c +++ b/shared-core/radeon_ms_bus.c @@ -218,6 +218,7 @@ int radeon_ms_agp_finish(struct drm_device *dev) return 0; } dev_priv->bus_ready = 0; + DRM_INFO("[radeon_ms] release agp\n"); drm_agp_release(dev); return 0; } @@ -237,7 +238,7 @@ int radeon_ms_agp_init(struct drm_device *dev) } ret = drm_agp_acquire(dev); if (ret) { - DRM_ERROR("[radeon_ms] error failed to acquire agp\n"); + DRM_ERROR("[radeon_ms] error failed to acquire agp %d\n", ret); return ret; } agp_status = MMIO_R(AGP_STATUS); diff --git a/shared-core/radeon_ms_cp.c b/shared-core/radeon_ms_cp.c index 7b26c0ba..f551000a 100644 --- a/shared-core/radeon_ms_cp.c +++ b/shared-core/radeon_ms_cp.c @@ -156,7 +156,7 @@ int radeon_ms_cp_init(struct drm_device *dev) dev_priv->ring_buffer_object->mem.num_pages, &dev_priv->ring_buffer_map); if (ret) { - DRM_INFO("[radeon_ms] error mapping ring buffer: %d\n", ret); + DRM_ERROR("[radeon_ms] error mapping ring buffer: %d\n", ret); return ret; } dev_priv->ring_buffer = dev_priv->ring_buffer_map.virtual; @@ -275,32 +275,15 @@ void radeon_ms_cp_save(struct drm_device *dev, struct radeon_state *state) void radeon_ms_cp_stop(struct drm_device *dev) { struct drm_radeon_private *dev_priv = dev->dev_private; - uint32_t rbbm_status, rbbm_status_cp_mask; - dev_priv->cp_ready = 0; - MMIO_W(CP_CSQ_CNTL, 0); - MMIO_R(CP_CSQ_CNTL); - MMIO_W(CP_CSQ_MODE, 0); - MMIO_R(CP_CSQ_MODE); - MMIO_W(RBBM_SOFT_RESET, RBBM_SOFT_RESET__SOFT_RESET_CP); - MMIO_R(RBBM_SOFT_RESET); - MMIO_W(RBBM_SOFT_RESET, 0); - MMIO_R(RBBM_SOFT_RESET); - rbbm_status = MMIO_R(RBBM_STATUS); - rbbm_status_cp_mask = (RBBM_STATUS__CPRQ_ON_RBB | - RBBM_STATUS__CPRQ_IN_RTBUF | - RBBM_STATUS__CP_CMDSTRM_BUSY); - if (rbbm_status & rbbm_status_cp_mask) { - DRM_INFO("[radeon_ms] cp busy (RBBM_STATUS: 0x%08X " - "RBBM_STATUS(cp_mask): 0x%08X)\n", rbbm_status, - rbbm_status_cp_mask); - } + 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_CNTL, 0); + MMIO_W(CP_RB_WPTR, dev_priv->ring_wptr); } int radeon_ms_cp_wait(struct drm_device *dev, int n) @@ -349,7 +332,7 @@ int radeon_ms_ring_emit(struct drm_device *dev, uint32_t *cmd, uint32_t count) dev_priv->ring_free -= count; for (i = 0; i < count; i++) { dev_priv->ring_buffer[dev_priv->ring_wptr] = cmd[i]; - DRM_INFO("ring[%d] = 0x%08X\n", dev_priv->ring_wptr, cmd[i]); + DRM_INFO("ring[%d]=0x%08X\n", dev_priv->ring_wptr, cmd[i]); dev_priv->ring_wptr++; dev_priv->ring_wptr &= dev_priv->ring_mask; } @@ -363,7 +346,7 @@ int radeon_ms_ring_emit(struct drm_device *dev, uint32_t *cmd, uint32_t count) } int radeon_ms_resetcp(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file_priv) { struct drm_radeon_private *dev_priv = dev->dev_private; int i; @@ -381,7 +364,7 @@ int radeon_ms_resetcp(struct drm_device *dev, void *data, DRM_UDELAY(100); } DRM_INFO("[radeon_ms] status after VAP : RBBM_STATUS: 0x%08X\n", - MMIO_R(RBBM_STATUS)); + MMIO_R(RBBM_STATUS)); DRM_INFO("[radeon_ms]--------------------------------------------\n"); return 0; diff --git a/shared-core/radeon_ms_exec.c b/shared-core/radeon_ms_exec.c index 68b3e145..574e5a06 100644 --- a/shared-core/radeon_ms_exec.c +++ b/shared-core/radeon_ms_exec.c @@ -25,14 +25,15 @@ * Jerome Glisse */ #include "radeon_ms.h" +#include "amd_cbuffer.h" static void radeon_ms_execbuffer_args_clean(struct drm_device *dev, - struct drm_buffer_object **buffers, + struct amd_cbuffer *cbuffer, uint32_t args_count) { mutex_lock(&dev->struct_mutex); while (args_count--) { - drm_bo_usage_deref_locked(&buffers[args_count]); + drm_bo_usage_deref_locked(&cbuffer->args[args_count].buffer); } mutex_unlock(&dev->struct_mutex); } @@ -40,8 +41,7 @@ static void radeon_ms_execbuffer_args_clean(struct drm_device *dev, 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 amd_cbuffer *cbuffer) { struct drm_radeon_execbuffer_arg arg; struct drm_bo_arg_rep rep; @@ -57,17 +57,18 @@ static int radeon_ms_execbuffer_args(struct drm_device *dev, ret = -EINVAL; goto out_err; } - buffers[args_count] = NULL; + INIT_LIST_HEAD(&cbuffer->args[args_count].list); + cbuffer->args[args_count].buffer = 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] = + cbuffer->args[args_count].buffer = drm_lookup_buffer_object(file_priv, arg.d.req.arg_handle, 1); - relocs[args_count] = arg.reloc_offset; + cbuffer->args[args_count].dw_id = 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 " @@ -76,17 +77,15 @@ static int radeon_ms_execbuffer_args(struct drm_device *dev, 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.flags, - arg.d.req.bo_req.mask, - arg.d.req.bo_req.hint, - arg.d.req.bo_req.fence_class, - 0, - &rep.bo_info, - &buffers[args_count]); - } + ret = drm_bo_handle_validate(file_priv, + arg.d.req.bo_req.handle, + arg.d.req.bo_req.flags, + arg.d.req.bo_req.mask, + arg.d.req.bo_req.hint, + arg.d.req.bo_req.fence_class, + 0, + &rep.bo_info, + &cbuffer->args[args_count].buffer); if (ret) { DRM_ERROR("[radeon_ms] error on handle validate %d\n", ret); @@ -101,6 +100,10 @@ static int radeon_ms_execbuffer_args(struct drm_device *dev, goto out_err; } data = next; + + list_add_tail(&cbuffer->args[args_count].list, + &cbuffer->arg_unused.list); + args_count++; } while (next != 0); if (args_count != execbuffer->args_count) { @@ -111,34 +114,201 @@ static int radeon_ms_execbuffer_args(struct drm_device *dev, } return 0; out_err: - radeon_ms_execbuffer_args_clean(dev, buffers, args_count); + radeon_ms_execbuffer_args_clean(dev, cbuffer, 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) +enum { + REGISTER_FORBIDDEN = 0, + REGISTER_SAFE, + REGISTER_SET_OFFSET, +}; +static uint8_t _r3xx_register_right[0x5000 >> 2]; + +static int amd_cbuffer_packet0_set_offset(struct drm_device *dev, + struct amd_cbuffer *cbuffer, + uint32_t reg, int dw_id, + struct amd_cbuffer_arg *arg) +{ + uint32_t gpu_addr; + int ret; + + ret = radeon_ms_bo_get_gpu_addr(dev, &arg->buffer->mem, &gpu_addr); + if (ret) { + return ret; + } + switch (reg) { + default: + return -EINVAL; + } + return 0; +} + +static struct amd_cbuffer_arg * +amd_cbuffer_arg_from_dw_id(struct amd_cbuffer_arg *head, uint32_t dw_id) +{ + struct amd_cbuffer_arg *arg; + + list_for_each_entry(arg, &head->list, list) { + if (arg->dw_id == dw_id) { + return arg; + } + } + /* no buffer at this dw index */ + return NULL; +} + +static int amd_cbuffer_packet0_check(struct drm_device *dev, + struct drm_file *file_priv, + struct amd_cbuffer *cbuffer, + int dw_id, + uint8_t *register_right) { - uint32_t i, gpu_addr; + struct amd_cbuffer_arg *arg; + uint32_t reg, count, r, i; 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); + reg = cbuffer->cbuffer[dw_id] & PACKET0_REG_MASK; + count = (cbuffer->cbuffer[dw_id] & PACKET0_COUNT_MASK) >> + PACKET0_COUNT_SHIFT; + for (r = reg, i = 0; i <= count; i++, r++) { + switch (register_right[i]) { + case REGISTER_FORBIDDEN: + return -EINVAL; + case REGISTER_SAFE: + break; + case REGISTER_SET_OFFSET: + arg = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, + dw_id + i +1); + if (arg == NULL) { + return -EINVAL; + } + /* remove from unparsed list */ + list_del(&arg->list); + list_add_tail(&arg->list, &cbuffer->arg_used.list); + /* set the offset */ + ret = amd_cbuffer_packet0_set_offset(dev, cbuffer, + r, dw_id + i + 1, + arg); if (ret) { return ret; } - cmd[relocs[i]] |= (gpu_addr) >> 10; + break; } } - for (i = 0; i < execbuffer->cmd_size; i++) { -#if 0 - DRM_INFO("cmd[%d]=0x%08X\n", i, cmd[i]); -#endif + /* header + N + 1 dword passed test */ + return count + 2; +} + +static int amd_cbuffer_packet3_check(struct drm_device *dev, + struct drm_file *file_priv, + struct amd_cbuffer *cbuffer, + int dw_id) +{ + struct amd_cbuffer_arg *arg; + uint32_t opcode, count; + uint32_t s_auth, s_mask; + uint32_t gpu_addr; + int ret; + + opcode = (cbuffer->cbuffer[dw_id] & PACKET3_OPCODE_MASK) >> + PACKET3_OPCODE_SHIFT; + count = (cbuffer->cbuffer[dw_id] & PACKET3_COUNT_MASK) >> + PACKET3_COUNT_SHIFT; + switch (opcode) { + case PACKET3_OPCODE_NOP: + break; + case PACKET3_OPCODE_BITBLT: + case PACKET3_OPCODE_BITBLT_MULTI: + DRM_INFO("[radeon_ms] exec step - [05][P3]00.00\n"); + /* we only alow simple blit */ + if (count != 5) { + return -EINVAL; + } + DRM_INFO("[radeon_ms] exec step - [05][P3]01.00\n"); + s_mask = 0xf; + s_auth = 0x3; + if ((cbuffer->cbuffer[dw_id + 1] & s_mask) != s_auth) { + return -EINVAL; + } + DRM_INFO("[radeon_ms] exec step - [05][P3]02.00\n"); + arg = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, dw_id+2); + if (arg == NULL) { + return -EINVAL; + } + DRM_INFO("[radeon_ms] exec step - [05][P3]03.00\n"); + ret = radeon_ms_bo_get_gpu_addr(dev, &arg->buffer->mem, + &gpu_addr); + if (ret) { + return ret; + } + DRM_INFO("[radeon_ms] exec step - [05][P3]04.00\n"); + gpu_addr = (gpu_addr >> 10) & 0x003FFFFF; + cbuffer->cbuffer[dw_id + 2] &= 0xFFC00000; + cbuffer->cbuffer[dw_id + 2] |= gpu_addr; + arg = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, dw_id+3); + if (arg == NULL) { + return -EINVAL; + } + DRM_INFO("[radeon_ms] exec step - [05][P3]05.00\n"); + ret = radeon_ms_bo_get_gpu_addr(dev, &arg->buffer->mem, + &gpu_addr); + if (ret) { + return ret; + } + DRM_INFO("[radeon_ms] exec step - [05][P3]06.00\n"); + gpu_addr = (gpu_addr >> 10) & 0x003FFFFF; + cbuffer->cbuffer[dw_id + 3] &= 0xFFC00000; + cbuffer->cbuffer[dw_id + 3] |= gpu_addr; + DRM_INFO("[radeon_ms] exec step - [05][P3]07.00\n"); + /* FIXME: check that source & destination are big enough + * for requested blit */ + break; + default: + return -EINVAL; + } + /* header + N + 1 dword passed test */ + return count + 2; +} + +static int amd_cbuffer_check(struct drm_device *dev, + struct drm_file *file_priv, + struct amd_cbuffer *cbuffer) +{ + uint32_t i; + int ret; + + for (i = 0; i < cbuffer->cbuffer_dw_count;) { + DRM_INFO("[radeon_ms] exec step - [05]00.00 %d 0x%08X\n", + i, cbuffer->cbuffer[i]); + switch (PACKET_HEADER_GET(cbuffer->cbuffer[i])) { + case 0: + ret = amd_cbuffer_packet0_check(dev, file_priv, + cbuffer, i, + _r3xx_register_right); + if (ret) { + return ret; + } + /* advance to next packet */ + i += ret; + break; + case 1: + /* we don't accept packet 1 */ + return -EINVAL; + case 2: + /* packet 2 */ + i += 1; + break; + case 3: + ret = amd_cbuffer_packet3_check(dev, file_priv, + cbuffer, i); + if (ret) { + return ret; + } + /* advance to next packet */ + i += ret; + break; + } } return 0; } @@ -148,97 +318,116 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, { 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; + struct amd_cbuffer cbuffer; + /* command buffer dword count must be >= 0 */ + if (execbuffer->cmd_size < 0) { + return -EINVAL; + } + /* FIXME: Lock buffer manager, is this really needed ? + */ + DRM_INFO("[radeon_ms] exec step - 00.00\n"); 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; + DRM_INFO("[radeon_ms] exec step - 01.00\n"); + cbuffer.args = drm_calloc(execbuffer->args_count, + sizeof(struct amd_cbuffer_arg), + DRM_MEM_DRIVER); + if (cbuffer.args == NULL) { + ret = -ENOMEM; + goto out_free; } + + INIT_LIST_HEAD(&cbuffer.arg_unused.list); + INIT_LIST_HEAD(&cbuffer.arg_used.list); + /* process arguments */ - ret = radeon_ms_execbuffer_args(dev, file_priv, execbuffer, - buffers, relocs); + DRM_INFO("[radeon_ms] exec step - 02.00\n"); + ret = radeon_ms_execbuffer_args(dev, file_priv, execbuffer, &cbuffer); if (ret) { DRM_ERROR("[radeon_ms] execbuffer wrong arguments\n"); goto out_free; } + /* map command buffer */ + DRM_INFO("[radeon_ms] exec step - 03.00\n"); + cbuffer.cbuffer_dw_count = (cbuffer.args[0].buffer->mem.num_pages * + PAGE_SIZE) >> 2; + if (execbuffer->cmd_size > cbuffer.cbuffer_dw_count) { + ret = -EINVAL; + goto out_free_release; + } + DRM_INFO("[radeon_ms] exec step - 04.00\n"); + cbuffer.cbuffer_dw_count = execbuffer->cmd_size; memset(&cmd_kmap, 0, sizeof(struct drm_bo_kmap_obj)); - ret = drm_bo_kmap(buffers[0], - 0, - buffers[0]->mem.num_pages, - &cmd_kmap); + ret = drm_bo_kmap(cbuffer.args[0].buffer, 0, + cbuffer.args[0].buffer->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); + DRM_INFO("[radeon_ms] exec step - 05.00\n"); + cbuffer.cbuffer = drm_bmo_virtual(&cmd_kmap, &cmd_is_iomem); + DRM_INFO("[radeon_ms] exec step - 05.01\n"); + list_del(&cbuffer.args[0].list); + DRM_INFO("[radeon_ms] exec step - 05.02\n"); + list_add_tail(&cbuffer.args[0].list , &cbuffer.arg_used.list); + DRM_INFO("[radeon_ms] exec step - 05.03\n"); + /* do cmd checking & relocations */ - ret = radeon_ms_execbuffer_check(dev, file_priv, execbuffer, - buffers, relocs, cmd); + ret = amd_cbuffer_check(dev, file_priv, &cbuffer); if (ret) { drm_putback_buffer_objects(dev); goto out_free_release; } + DRM_INFO("[radeon_ms] exec step - 06.00\n"); - ret = radeon_ms_ring_emit(dev, cmd, execbuffer->cmd_size); + ret = radeon_ms_ring_emit(dev, cbuffer.cbuffer, + cbuffer.cbuffer_dw_count); if (ret) { drm_putback_buffer_objects(dev); goto out_free_release; } + DRM_INFO("[radeon_ms] exec step - 07.00\n"); /* fence */ - if (execbuffer->args_count > 1) { - 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_types; - fence_arg->sequence = fence->sequence; - } + 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_types; + fence_arg->sequence = fence->sequence; } - drm_fence_usage_deref_unlocked(&fence); } + drm_fence_usage_deref_unlocked(&fence); + DRM_INFO("[radeon_ms] exec step - 08.00\n"); out_free_release: drm_bo_kunmap(&cmd_kmap); - radeon_ms_execbuffer_args_clean(dev, buffers, execbuffer->args_count); + radeon_ms_execbuffer_args_clean(dev, &cbuffer, execbuffer->args_count); + DRM_INFO("[radeon_ms] exec step - 09.00\n"); 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_free(cbuffer.args, + (execbuffer->args_count * sizeof(struct amd_cbuffer_arg)), DRM_MEM_DRIVER); drm_bo_read_unlock(&dev->bm.bm_lock); + DRM_INFO("[radeon_ms] exec step - 10.00\n"); return ret; } diff --git a/shared-core/radeon_ms_family.c b/shared-core/radeon_ms_family.c index b70dca20..5e83766a 100644 --- a/shared-core/radeon_ms_family.c +++ b/shared-core/radeon_ms_family.c @@ -117,6 +117,7 @@ int radeon_ms_family_init(struct drm_device *dev) switch (dev_priv->bus_type) { case RADEON_AGP: dev_priv->create_ttm = drm_agp_init_ttm; + dev_priv->bus_finish = radeon_ms_agp_finish; dev_priv->bus_init = radeon_ms_agp_init; dev_priv->bus_restore = radeon_ms_agp_restore; dev_priv->bus_save = radeon_ms_agp_save; diff --git a/shared-core/radeon_ms_gpu.c b/shared-core/radeon_ms_gpu.c index 21c86027..5b03dc35 100644 --- a/shared-core/radeon_ms_gpu.c +++ b/shared-core/radeon_ms_gpu.c @@ -128,7 +128,7 @@ static void radeon_ms_gpu_reset(struct drm_device *dev) MMIO_W(RBBM_SOFT_RESET, 0); MMIO_R(RBBM_SOFT_RESET); -#if 0 +#if 1 cache_mode = MMIO_R(RB2D_DSTCACHE_MODE); MMIO_W(RB2D_DSTCACHE_MODE, cache_mode | RB2D_DSTCACHE_MODE__DC_DISABLE_IGNORE_PE); @@ -576,7 +576,6 @@ void radeon_ms_gpu_save(struct drm_device *dev, struct radeon_state *state) int radeon_ms_wait_for_idle(struct drm_device *dev) { struct drm_radeon_private *dev_priv = dev->dev_private; - struct radeon_state *state = &dev_priv->driver_state; int i, j, ret; for (i = 0; i < 2; i++) { diff --git a/shared-core/radeon_ms_reg.h b/shared-core/radeon_ms_reg.h index adb6434b..25063990 100644 --- a/shared-core/radeon_ms_reg.h +++ b/shared-core/radeon_ms_reg.h @@ -1755,4 +1755,33 @@ #define VAP_PVS_STATE_FLUSH_REG__DATA_REGISTER__MASK 0xFFFFFFFF #define VAP_PVS_STATE_FLUSH_REG__DATA_REGISTER__SHIFT 0 +/* packet stuff **************************************************************/ +#define PACKET_HEADER_MASK 0xC0000000 +#define PACKET_HEADER_SHIFT 30 +#define PACKET_HEADER_GET(p) (((p) & PACKET_HEADER_MASK) >> PACKET_HEADER_SHIFT) +#define PACKET_HEADER_SET(p) (((p) << PACKET_HEADER_SHIFT) & PACKET_HEADER_MASK) + +#define PACKET0_HEADER 0x0 +# define PACKET0_REG_MASK 0x00001FFF +# define PACKET0_REG_SHIFT 0 +# define PACKET0_COUNT_MASK 0x3FFF0000 +# define PACKET0_COUNT_SHIFT 16 +#define PACKET1_HEADER 0x1 +#define PACKET2_HEADER 0x2 +#define PACKET3_HEADER 0x3 +# define PACKET3_OPCODE_MASK 0x0000FF00 +# define PACKET3_OPCODE_SHIFT 8 +# define PACKET3_OPCODE_NOP 0x10 +# define PACKET3_OPCODE_BITBLT 0x92 +# define PACKET3_OPCODE_BITBLT_MULTI 0x9B +# define PACKET3_COUNT_MASK 0x3FFF0000 +# define PACKET3_COUNT_SHIFT 16 + +#define CP_PACKET0(r, n) (PACKET_HEADER_SET(PACKET0_HEADER) |\ + ((((r)>>2)< Date: Mon, 31 Mar 2008 21:50:02 +0200 Subject: radeon_ms: small fix & cleanup to command checking --- shared-core/radeon_ms_exec.c | 29 +++-------------------------- 1 file changed, 3 insertions(+), 26 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_ms_exec.c b/shared-core/radeon_ms_exec.c index 574e5a06..32b55eaf 100644 --- a/shared-core/radeon_ms_exec.c +++ b/shared-core/radeon_ms_exec.c @@ -220,47 +220,40 @@ static int amd_cbuffer_packet3_check(struct drm_device *dev, break; case PACKET3_OPCODE_BITBLT: case PACKET3_OPCODE_BITBLT_MULTI: - DRM_INFO("[radeon_ms] exec step - [05][P3]00.00\n"); /* we only alow simple blit */ if (count != 5) { return -EINVAL; } - DRM_INFO("[radeon_ms] exec step - [05][P3]01.00\n"); s_mask = 0xf; s_auth = 0x3; if ((cbuffer->cbuffer[dw_id + 1] & s_mask) != s_auth) { return -EINVAL; } - DRM_INFO("[radeon_ms] exec step - [05][P3]02.00\n"); arg = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, dw_id+2); if (arg == NULL) { return -EINVAL; } - DRM_INFO("[radeon_ms] exec step - [05][P3]03.00\n"); ret = radeon_ms_bo_get_gpu_addr(dev, &arg->buffer->mem, &gpu_addr); if (ret) { return ret; } - DRM_INFO("[radeon_ms] exec step - [05][P3]04.00\n"); gpu_addr = (gpu_addr >> 10) & 0x003FFFFF; cbuffer->cbuffer[dw_id + 2] &= 0xFFC00000; cbuffer->cbuffer[dw_id + 2] |= gpu_addr; + arg = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, dw_id+3); if (arg == NULL) { return -EINVAL; } - DRM_INFO("[radeon_ms] exec step - [05][P3]05.00\n"); ret = radeon_ms_bo_get_gpu_addr(dev, &arg->buffer->mem, &gpu_addr); if (ret) { return ret; } - DRM_INFO("[radeon_ms] exec step - [05][P3]06.00\n"); gpu_addr = (gpu_addr >> 10) & 0x003FFFFF; cbuffer->cbuffer[dw_id + 3] &= 0xFFC00000; cbuffer->cbuffer[dw_id + 3] |= gpu_addr; - DRM_INFO("[radeon_ms] exec step - [05][P3]07.00\n"); /* FIXME: check that source & destination are big enough * for requested blit */ break; @@ -279,14 +272,12 @@ static int amd_cbuffer_check(struct drm_device *dev, int ret; for (i = 0; i < cbuffer->cbuffer_dw_count;) { - DRM_INFO("[radeon_ms] exec step - [05]00.00 %d 0x%08X\n", - i, cbuffer->cbuffer[i]); switch (PACKET_HEADER_GET(cbuffer->cbuffer[i])) { case 0: ret = amd_cbuffer_packet0_check(dev, file_priv, cbuffer, i, _r3xx_register_right); - if (ret) { + if (ret <= 0) { return ret; } /* advance to next packet */ @@ -302,7 +293,7 @@ static int amd_cbuffer_check(struct drm_device *dev, case 3: ret = amd_cbuffer_packet3_check(dev, file_priv, cbuffer, i); - if (ret) { + if (ret <= 0) { return ret; } /* advance to next packet */ @@ -331,13 +322,11 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, /* FIXME: Lock buffer manager, is this really needed ? */ - DRM_INFO("[radeon_ms] exec step - 00.00\n"); ret = drm_bo_read_lock(&dev->bm.bm_lock); if (ret) { return ret; } - DRM_INFO("[radeon_ms] exec step - 01.00\n"); cbuffer.args = drm_calloc(execbuffer->args_count, sizeof(struct amd_cbuffer_arg), DRM_MEM_DRIVER); @@ -350,7 +339,6 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, INIT_LIST_HEAD(&cbuffer.arg_used.list); /* process arguments */ - DRM_INFO("[radeon_ms] exec step - 02.00\n"); ret = radeon_ms_execbuffer_args(dev, file_priv, execbuffer, &cbuffer); if (ret) { DRM_ERROR("[radeon_ms] execbuffer wrong arguments\n"); @@ -358,14 +346,12 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, } /* map command buffer */ - DRM_INFO("[radeon_ms] exec step - 03.00\n"); cbuffer.cbuffer_dw_count = (cbuffer.args[0].buffer->mem.num_pages * PAGE_SIZE) >> 2; if (execbuffer->cmd_size > cbuffer.cbuffer_dw_count) { ret = -EINVAL; goto out_free_release; } - DRM_INFO("[radeon_ms] exec step - 04.00\n"); cbuffer.cbuffer_dw_count = execbuffer->cmd_size; memset(&cmd_kmap, 0, sizeof(struct drm_bo_kmap_obj)); ret = drm_bo_kmap(cbuffer.args[0].buffer, 0, @@ -374,13 +360,9 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, DRM_ERROR("[radeon_ms] error mapping ring buffer: %d\n", ret); goto out_free_release; } - DRM_INFO("[radeon_ms] exec step - 05.00\n"); cbuffer.cbuffer = drm_bmo_virtual(&cmd_kmap, &cmd_is_iomem); - DRM_INFO("[radeon_ms] exec step - 05.01\n"); list_del(&cbuffer.args[0].list); - DRM_INFO("[radeon_ms] exec step - 05.02\n"); list_add_tail(&cbuffer.args[0].list , &cbuffer.arg_used.list); - DRM_INFO("[radeon_ms] exec step - 05.03\n"); /* do cmd checking & relocations */ ret = amd_cbuffer_check(dev, file_priv, &cbuffer); @@ -388,7 +370,6 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, drm_putback_buffer_objects(dev); goto out_free_release; } - DRM_INFO("[radeon_ms] exec step - 06.00\n"); ret = radeon_ms_ring_emit(dev, cbuffer.cbuffer, cbuffer.cbuffer_dw_count); @@ -396,7 +377,6 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, drm_putback_buffer_objects(dev); goto out_free_release; } - DRM_INFO("[radeon_ms] exec step - 07.00\n"); /* fence */ ret = drm_fence_buffer_objects(dev, NULL, 0, NULL, &fence); @@ -418,16 +398,13 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, } } drm_fence_usage_deref_unlocked(&fence); - DRM_INFO("[radeon_ms] exec step - 08.00\n"); out_free_release: drm_bo_kunmap(&cmd_kmap); radeon_ms_execbuffer_args_clean(dev, &cbuffer, execbuffer->args_count); - DRM_INFO("[radeon_ms] exec step - 09.00\n"); out_free: drm_free(cbuffer.args, (execbuffer->args_count * sizeof(struct amd_cbuffer_arg)), DRM_MEM_DRIVER); drm_bo_read_unlock(&dev->bm.bm_lock); - DRM_INFO("[radeon_ms] exec step - 10.00\n"); return ret; } -- cgit v1.2.3 From dfc8d2b2fe70a84de53f72f0eeff911c58469089 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 3 Apr 2008 03:15:47 +0200 Subject: radeon_ms: add crtc set base callback & fix palette --- shared-core/radeon_ms_crtc.c | 95 +++++++++++++++----------------------------- 1 file changed, 31 insertions(+), 64 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_ms_crtc.c b/shared-core/radeon_ms_crtc.c index b2383859..63bd4a0a 100644 --- a/shared-core/radeon_ms_crtc.c +++ b/shared-core/radeon_ms_crtc.c @@ -638,6 +638,17 @@ static void radeon_ms_crtc1_mode_set(struct drm_crtc *crtc, radeon_ms_crtc1_restore(dev, state); } +static void radeon_ms_crtc1_mode_set_base(struct drm_crtc *crtc, 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; + + DRM_INFO("[radeon_ms] mode_set_base\n"); + state->crtc_offset = REG_S(CRTC_OFFSET, CRTC_OFFSET, crtc->fb->bo->offset); + radeon_ms_crtc1_restore(dev, state); +} + static void radeon_ms_crtc_mode_commit(struct drm_crtc *crtc) { crtc->funcs->dpms(crtc, DPMSModeOn); @@ -651,6 +662,9 @@ static void radeon_ms_crtc_gamma_set(struct drm_crtc *crtc, u16 r, struct radeon_state *state = &dev_priv->driver_state; uint32_t color; + if (regno >= 256) { + return; + } switch(radeon_ms_crtc->crtc) { case 1: state->dac_cntl2 &= ~DAC_CNTL2__PALETTE_ACCESS_CNTL; @@ -660,70 +674,22 @@ static void radeon_ms_crtc_gamma_set(struct drm_crtc *crtc, u16 r, 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); - } + 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); + MMIO_W(PALETTE_30_DATA, color); } static void radeon_ms_crtc_load_lut(struct drm_crtc *crtc) @@ -762,6 +728,7 @@ static const struct drm_crtc_funcs radeon_ms_crtc1_funcs= { .commit = radeon_ms_crtc_mode_commit, .mode_fixup = radeon_ms_crtc_mode_fixup, .mode_set = radeon_ms_crtc1_mode_set, + .mode_set_base = radeon_ms_crtc1_mode_set_base, .gamma_set = radeon_ms_crtc_gamma_set, .cleanup = NULL, /* XXX */ }; -- cgit v1.2.3 From 91bfd69745dbb62dc28c57f940ff44da867e96ea Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sun, 6 Apr 2008 19:01:31 +0200 Subject: radeon_ms: check for NULL fb --- shared-core/radeon_ms_crtc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_ms_crtc.c b/shared-core/radeon_ms_crtc.c index 63bd4a0a..83dd0777 100644 --- a/shared-core/radeon_ms_crtc.c +++ b/shared-core/radeon_ms_crtc.c @@ -537,6 +537,10 @@ static void radeon_ms_crtc1_mode_set(struct drm_crtc *crtc, adjusted_mode->hsync_end, adjusted_mode->htotal, adjusted_mode->vdisplay, adjusted_mode->vsync_start, adjusted_mode->vsync_end, adjusted_mode->vtotal, adjusted_mode->type); + if (crtc->fb == NULL) { + DRM_INFO("[radeon_ms] no FB bound\n"); + return; + } /* only support RGB555,RGB565,ARGB8888 should satisfy all users */ switch (crtc->fb->bits_per_pixel) { @@ -551,7 +555,7 @@ static void radeon_ms_crtc1_mode_set(struct drm_crtc *crtc, format = 6; break; default: - DRM_ERROR("Unknown color depth\n"); + DRM_ERROR("Unknown color depth %d\n", crtc->fb->bits_per_pixel); return; } radeon_pll1_compute(crtc, adjusted_mode); @@ -665,6 +669,7 @@ static void radeon_ms_crtc_gamma_set(struct drm_crtc *crtc, u16 r, if (regno >= 256) { return; } + DRM_INFO("[radeon_ms] gamma[%d]=(%d, %d, %d)\n", regno, r, g, b); switch(radeon_ms_crtc->crtc) { case 1: state->dac_cntl2 &= ~DAC_CNTL2__PALETTE_ACCESS_CNTL; -- cgit v1.2.3 From 060e725a0e8aa1f1157f97ca8e7dfa60d02d17ac Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sun, 6 Apr 2008 19:23:20 +0200 Subject: radeon_ms: fix framebuffer code --- shared-core/amd.h | 40 ++++++++++++++++++++++++++++++++++++++++ shared-core/radeon_ms.h | 3 +++ 2 files changed, 43 insertions(+) create mode 100644 shared-core/amd.h (limited to 'shared-core') diff --git a/shared-core/amd.h b/shared-core/amd.h new file mode 100644 index 00000000..ac6195e2 --- /dev/null +++ b/shared-core/amd.h @@ -0,0 +1,40 @@ +/* + * 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 + */ +#ifndef __AMD_H__ +#define __AMD_H__ + +/* struct amd_fb amd is for storing amd framebuffer informations + */ +struct amd_fb +{ + struct drm_device *dev; + struct drm_crtc *crtc; + struct drm_display_mode *fb_mode; + struct drm_framebuffer *fb; +}; + +#endif diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h index e4010d84..bbd0477b 100644 --- a/shared-core/radeon_ms.h +++ b/shared-core/radeon_ms.h @@ -35,6 +35,7 @@ #include "radeon_ms_drm.h" #include "radeon_ms_rom.h" #include "radeon_ms_properties.h" +#include "amd.h" #include "amd_cbuffer.h" #define DRIVER_AUTHOR "Jerome Glisse, Dave Airlie, Gareth Hughes, "\ @@ -292,6 +293,8 @@ struct drm_radeon_private { uint32_t *ring_buffer; uint32_t *write_back_area; const uint32_t *microcode; + /* framebuffer */ + struct amd_fb *fb; /* card family */ uint32_t usec_timeout; uint32_t family; -- cgit v1.2.3 From 779e826c1e2c127f4950c78a56cc314c43b7eb56 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Tue, 8 Apr 2008 02:18:14 +0200 Subject: radeon_ms: command buffer validation use array of function pointer --- shared-core/amd.h | 37 +++++ shared-core/amd_cbuffer.h | 51 ------- shared-core/amd_legacy.h | 33 +++++ shared-core/amd_legacy_cbuffer.c | 306 +++++++++++++++++++++++++++++++++++++++ shared-core/radeon_ms.h | 4 +- shared-core/radeon_ms_drm.c | 10 ++ shared-core/radeon_ms_exec.c | 195 ++++++++----------------- 7 files changed, 452 insertions(+), 184 deletions(-) delete mode 100644 shared-core/amd_cbuffer.h create mode 100644 shared-core/amd_legacy.h create mode 100644 shared-core/amd_legacy_cbuffer.c (limited to 'shared-core') diff --git a/shared-core/amd.h b/shared-core/amd.h index ac6195e2..31cf3eff 100644 --- a/shared-core/amd.h +++ b/shared-core/amd.h @@ -27,6 +27,43 @@ #ifndef __AMD_H__ #define __AMD_H__ +/* struct amd_cbuffer are for command buffer, this is the structure passed + * around during command validation (ie check that user have the right to + * execute the given command). + */ +struct amd_cbuffer_arg +{ + struct list_head list; + struct drm_buffer_object *buffer; + int32_t dw_id; +}; + +struct amd_cbuffer +{ + uint32_t *cbuffer; + uint32_t cbuffer_dw_count; + struct amd_cbuffer_arg arg_unused; + struct amd_cbuffer_arg arg_used; + struct amd_cbuffer_arg *args; + void *driver; +}; + +struct amd_cbuffer_checker +{ + uint32_t numof_p0_checkers; + uint32_t numof_p3_checkers; + int (*check)(struct drm_device *dev, struct amd_cbuffer *cbuffer); + int (**check_p0)(struct drm_device *dev, struct amd_cbuffer *cbuffer, + int dw_id, int reg); + int (**check_p3)(struct drm_device *dev, struct amd_cbuffer *cbuffer, + int dw_id, int op, int count); +}; + +struct amd_cbuffer_arg * +amd_cbuffer_arg_from_dw_id(struct amd_cbuffer_arg *head, uint32_t dw_id); +int amd_cbuffer_check(struct drm_device *dev, struct amd_cbuffer *cbuffer); + + /* struct amd_fb amd is for storing amd framebuffer informations */ struct amd_fb diff --git a/shared-core/amd_cbuffer.h b/shared-core/amd_cbuffer.h deleted file mode 100644 index bca05751..00000000 --- a/shared-core/amd_cbuffer.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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 - */ -#ifndef __AMD_CBUFFER_H__ -#define __AMD_CBUFFER_H__ - -/* struct amd_cbuffer are for command buffer, this is the structure passed - * around during command validation (ie check that user have the right to - * execute the given command). - */ - -struct amd_cbuffer_arg -{ - struct list_head list; - struct drm_buffer_object *buffer; - int32_t dw_id; -}; - -struct amd_cbuffer -{ - uint32_t *cbuffer; - uint32_t cbuffer_dw_count; - struct amd_cbuffer_arg arg_unused; - struct amd_cbuffer_arg arg_used; - struct amd_cbuffer_arg *args; -}; - -#endif diff --git a/shared-core/amd_legacy.h b/shared-core/amd_legacy.h new file mode 100644 index 00000000..92997dcd --- /dev/null +++ b/shared-core/amd_legacy.h @@ -0,0 +1,33 @@ +/* + * 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 + */ +#ifndef __AMD_LEGACY_H__ +#define __AMD_LEGACY_H__ + +int amd_legacy_cbuffer_destroy(struct drm_device *dev); +int amd_legacy_cbuffer_initialize(struct drm_device *dev); + +#endif diff --git a/shared-core/amd_legacy_cbuffer.c b/shared-core/amd_legacy_cbuffer.c new file mode 100644 index 00000000..f1b7a44b --- /dev/null +++ b/shared-core/amd_legacy_cbuffer.c @@ -0,0 +1,306 @@ +/* + * Copyright 2008 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 + */ +#include "radeon_ms.h" +#include "amd.h" + +#define RADEON_DST_Y_X 0x1438 +#define RADEON_SRC_Y_X 0x1434 +#define RADEON_DP_CNTL 0x16c0 +#define RADEON_DP_GUI_MASTER_CNTL 0x146c +#define RADEON_DP_BRUSH_BKGD_CLR 0x1478 +#define RADEON_DP_BRUSH_FRGD_CLR 0x147c +#define RADEON_DP_WRITE_MASK 0x16cc +#define RADEON_DST_PITCH_OFFSET 0x142c +#define RADEON_SRC_PITCH_OFFSET 0x1428 +#define RADEON_DST_HEIGHT_WIDTH 0x143c + +struct legacy_check +{ + /* for 2D operations */ + uint32_t dp_gui_master_cntl; + uint32_t dst_offset; + uint32_t dst_pitch; + struct amd_cbuffer_arg *dst; + uint32_t dst_x; + uint32_t dst_y; + uint32_t dst_h; + uint32_t dst_w; + struct amd_cbuffer_arg *src; + uint32_t src_pitch; + uint32_t src_x; + uint32_t src_y; +}; + +static int check_blit(struct drm_device *dev, struct amd_cbuffer *cbuffer) +{ + struct legacy_check *legacy_check; + long bpp, start, end; + + legacy_check = (struct legacy_check *)cbuffer->driver; + /* check that gui master cntl have been set */ + if (legacy_check->dp_gui_master_cntl == 0xffffffff) { + return -EINVAL; + } + switch ((legacy_check->dp_gui_master_cntl >> 8) & 0xf) { + case 2: + bpp = 1; + break; + case 3: + case 4: + bpp = 2; + break; + case 6: + bpp = 4; + break; + default: + return -EINVAL; + } + /* check that a destination have been set */ + if (legacy_check->dst == (void *)-1) { + return -EINVAL; + } + if (legacy_check->dst_pitch == 0xffffffff) { + return -EINVAL; + } + if (legacy_check->dst_x == 0xffffffff) { + return -EINVAL; + } + if (legacy_check->dst_y == 0xffffffff) { + return -EINVAL; + } + if (legacy_check->dst_w == 0xffffffff) { + return -EINVAL; + } + if (legacy_check->dst_h == 0xffffffff) { + return -EINVAL; + } + /* compute start offset of blit */ + start = legacy_check->dst_pitch * legacy_check->dst_y + + legacy_check->dst_x * bpp; + /* compute end offset of blit */ + end = legacy_check->dst_pitch * legacy_check->dst_h + + legacy_check->dst_w * bpp; + /* FIXME: check that end offset is inside dst bo */ + + /* check that a destination have been set */ + if (legacy_check->dp_gui_master_cntl & 1) { + if (legacy_check->src == (void *)-1) { + return -EINVAL; + } + if (legacy_check->src_pitch == 0xffffffff) { + return -EINVAL; + } + if (legacy_check->src_x == 0xffffffff) { + return -EINVAL; + } + if (legacy_check->src_y == 0xffffffff) { + return -EINVAL; + } + /* compute start offset of blit */ + start = legacy_check->src_pitch * legacy_check->src_y + + legacy_check->src_x * bpp; + /* compute end offset of blit */ + end = legacy_check->src_pitch * legacy_check->dst_h + + legacy_check->dst_w * bpp + start; + /* FIXME: check that end offset is inside src bo */ + } + return 0; +} + +static int p0_dp_gui_master_cntl(struct drm_device *dev, + struct amd_cbuffer *cbuffer, + int dw_id, int reg) +{ + struct legacy_check *legacy_check; + + legacy_check = (struct legacy_check *)cbuffer->driver; + legacy_check->dp_gui_master_cntl = cbuffer->cbuffer[dw_id]; + /* we only accept src data type to be same as dst */ + if (((legacy_check->dp_gui_master_cntl >> 12) & 0x3) != 3) { + return -EINVAL; + } + return 0; +} + +static int p0_dst_pitch_offset(struct drm_device *dev, + struct amd_cbuffer *cbuffer, + int dw_id, int reg) +{ + struct legacy_check *legacy_check; + uint32_t gpu_addr; + int ret; + + legacy_check = (struct legacy_check *)cbuffer->driver; + legacy_check->dst_pitch = ((cbuffer->cbuffer[dw_id] >> 22) & 0xff) << 6; + legacy_check->dst = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, + dw_id); + if (legacy_check->dst == NULL) { + return -EINVAL; + } + ret = radeon_ms_bo_get_gpu_addr(dev, &legacy_check->dst->buffer->mem, + &gpu_addr); + if (ret) { + return -EINVAL; + } + cbuffer->cbuffer[dw_id] &= 0xffc00000; + cbuffer->cbuffer[dw_id] |= (gpu_addr >> 10); + return 0; +} + +static int p0_src_pitch_offset(struct drm_device *dev, + struct amd_cbuffer *cbuffer, + int dw_id, int reg) +{ + struct legacy_check *legacy_check; + uint32_t gpu_addr; + int ret; + + legacy_check = (struct legacy_check *)cbuffer->driver; + legacy_check->src_pitch = ((cbuffer->cbuffer[dw_id] >> 22) & 0xff) << 6; + legacy_check->src = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, + dw_id); + if (legacy_check->dst == NULL) { + return -EINVAL; + } + ret = radeon_ms_bo_get_gpu_addr(dev, &legacy_check->src->buffer->mem, + &gpu_addr); + if (ret) { + return -EINVAL; + } + cbuffer->cbuffer[dw_id] &= 0xffc00000; + cbuffer->cbuffer[dw_id] |= (gpu_addr >> 10); + return 0; +} + +static int p0_dst_y_x(struct drm_device *dev, + struct amd_cbuffer *cbuffer, + int dw_id, int reg) +{ + struct legacy_check *legacy_check; + + legacy_check = (struct legacy_check *)cbuffer->driver; + legacy_check->dst_x = cbuffer->cbuffer[dw_id] & 0xffff; + legacy_check->dst_y = (cbuffer->cbuffer[dw_id] >> 16) & 0xffff; + return 0; +} + +static int p0_src_y_x(struct drm_device *dev, + struct amd_cbuffer *cbuffer, + int dw_id, int reg) +{ + struct legacy_check *legacy_check; + + legacy_check = (struct legacy_check *)cbuffer->driver; + legacy_check->src_x = cbuffer->cbuffer[dw_id] & 0xffff; + legacy_check->src_y = (cbuffer->cbuffer[dw_id] >> 16) & 0xffff; + return 0; +} + +static int p0_dst_h_w(struct drm_device *dev, + struct amd_cbuffer *cbuffer, + int dw_id, int reg) +{ + struct legacy_check *legacy_check; + + legacy_check = (struct legacy_check *)cbuffer->driver; + legacy_check->dst_w = cbuffer->cbuffer[dw_id] & 0xffff; + legacy_check->dst_h = (cbuffer->cbuffer[dw_id] >> 16) & 0xffff; + return check_blit(dev, cbuffer); +} + +static int legacy_cbuffer_check(struct drm_device *dev, + struct amd_cbuffer *cbuffer) +{ + struct legacy_check legacy_check; + + memset(&legacy_check, 0xff, sizeof(struct legacy_check)); + cbuffer->driver = &legacy_check; + return amd_cbuffer_check(dev, cbuffer); +} + +int amd_legacy_cbuffer_destroy(struct drm_device *dev) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + + dev_priv->cbuffer_checker.check = NULL; + if (dev_priv->cbuffer_checker.numof_p0_checkers) { + drm_free(dev_priv->cbuffer_checker.check_p0, + dev_priv->cbuffer_checker.numof_p0_checkers * + sizeof(void*), DRM_MEM_DRIVER); + dev_priv->cbuffer_checker.numof_p0_checkers = 0; + } + if (dev_priv->cbuffer_checker.numof_p3_checkers) { + drm_free(dev_priv->cbuffer_checker.check_p3, + dev_priv->cbuffer_checker.numof_p3_checkers * + sizeof(void*), DRM_MEM_DRIVER); + dev_priv->cbuffer_checker.numof_p3_checkers = 0; + } + return 0; +} + +int amd_legacy_cbuffer_initialize(struct drm_device *dev) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + struct amd_cbuffer_checker *checker = &dev_priv->cbuffer_checker; + long size; + + /* packet 0 */ + checker->numof_p0_checkers = 0x5000 >> 2; + size = checker->numof_p0_checkers * sizeof(void*); + checker->check_p0 = drm_alloc(size, DRM_MEM_DRIVER); + if (checker->check_p0 == NULL) { + amd_legacy_cbuffer_destroy(dev); + return -ENOMEM; + } + /* initialize to -1 */ + memset(checker->check_p0, 0xff, size); + + /* packet 3 */ + checker->numof_p3_checkers = 20; + size = checker->numof_p3_checkers * sizeof(void*); + checker->check_p3 = drm_alloc(size, DRM_MEM_DRIVER); + if (checker->check_p3 == NULL) { + amd_legacy_cbuffer_destroy(dev); + return -ENOMEM; + } + /* initialize to -1 */ + memset(checker->check_p3, 0xff, size); + + /* initialize packet0 checker */ + checker->check_p0[RADEON_DST_Y_X >> 2] = p0_dst_y_x; + checker->check_p0[RADEON_SRC_Y_X >> 2] = p0_src_y_x; + checker->check_p0[RADEON_DST_HEIGHT_WIDTH >> 2] = p0_dst_h_w; + checker->check_p0[RADEON_DST_PITCH_OFFSET >> 2] = p0_dst_pitch_offset; + checker->check_p0[RADEON_SRC_PITCH_OFFSET >> 2] = p0_src_pitch_offset; + checker->check_p0[RADEON_DP_GUI_MASTER_CNTL>>2] = p0_dp_gui_master_cntl; + checker->check_p0[RADEON_DP_BRUSH_FRGD_CLR >> 2] = NULL; + checker->check_p0[RADEON_DP_WRITE_MASK >> 2] = NULL; + checker->check_p0[RADEON_DP_CNTL >> 2] = NULL; + + checker->check = legacy_cbuffer_check; + return 0; +} diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h index bbd0477b..ec264207 100644 --- a/shared-core/radeon_ms.h +++ b/shared-core/radeon_ms.h @@ -36,7 +36,7 @@ #include "radeon_ms_rom.h" #include "radeon_ms_properties.h" #include "amd.h" -#include "amd_cbuffer.h" +#include "amd_legacy.h" #define DRIVER_AUTHOR "Jerome Glisse, Dave Airlie, Gareth Hughes, "\ "Keith Whitwell, others." @@ -329,6 +329,8 @@ struct drm_radeon_private { uint8_t cp_ready; uint8_t bus_ready; uint8_t write_back; + /* command buffer informations */ + struct amd_cbuffer_checker cbuffer_checker; /* abstract asic specific structures */ struct radeon_ms_rom rom; struct radeon_ms_properties properties; diff --git a/shared-core/radeon_ms_drm.c b/shared-core/radeon_ms_drm.c index 869ccac4..0d327925 100644 --- a/shared-core/radeon_ms_drm.c +++ b/shared-core/radeon_ms_drm.c @@ -246,6 +246,13 @@ int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags) return ret; } + /* initialze driver specific */ + ret = amd_legacy_cbuffer_initialize(dev); + if (ret != 0) { + radeon_ms_driver_unload(dev); + return ret; + } + if (dev->primary && dev->control) { DRM_INFO("[radeon_ms] control 0x%lx, render 0x%lx\n", (long)dev->primary->device, (long)dev->control->device); @@ -277,6 +284,9 @@ int radeon_ms_driver_unload(struct drm_device *dev) radeon_ms_outputs_restore(dev, &dev_priv->load_state); radeon_ms_connectors_destroy(dev); radeon_ms_outputs_destroy(dev); + + /* shutdown specific driver */ + amd_legacy_cbuffer_destroy(dev); /* shutdown cp engine */ radeon_ms_cp_finish(dev); diff --git a/shared-core/radeon_ms_exec.c b/shared-core/radeon_ms_exec.c index 32b55eaf..28fcc180 100644 --- a/shared-core/radeon_ms_exec.c +++ b/shared-core/radeon_ms_exec.c @@ -25,7 +25,7 @@ * Jerome Glisse */ #include "radeon_ms.h" -#include "amd_cbuffer.h" +#include "amd.h" static void radeon_ms_execbuffer_args_clean(struct drm_device *dev, struct amd_cbuffer *cbuffer, @@ -118,155 +118,69 @@ out_err: return ret; } -enum { - REGISTER_FORBIDDEN = 0, - REGISTER_SAFE, - REGISTER_SET_OFFSET, -}; -static uint8_t _r3xx_register_right[0x5000 >> 2]; - -static int amd_cbuffer_packet0_set_offset(struct drm_device *dev, - struct amd_cbuffer *cbuffer, - uint32_t reg, int dw_id, - struct amd_cbuffer_arg *arg) -{ - uint32_t gpu_addr; - int ret; - - ret = radeon_ms_bo_get_gpu_addr(dev, &arg->buffer->mem, &gpu_addr); - if (ret) { - return ret; - } - switch (reg) { - default: - return -EINVAL; - } - return 0; -} - -static struct amd_cbuffer_arg * -amd_cbuffer_arg_from_dw_id(struct amd_cbuffer_arg *head, uint32_t dw_id) +static int cbuffer_packet0_check(struct drm_device *dev, + struct amd_cbuffer *cbuffer, + int dw_id) { - struct amd_cbuffer_arg *arg; - - list_for_each_entry(arg, &head->list, list) { - if (arg->dw_id == dw_id) { - return arg; - } - } - /* no buffer at this dw index */ - return NULL; -} - -static int amd_cbuffer_packet0_check(struct drm_device *dev, - struct drm_file *file_priv, - struct amd_cbuffer *cbuffer, - int dw_id, - uint8_t *register_right) -{ - struct amd_cbuffer_arg *arg; + struct drm_radeon_private *dev_priv = dev->dev_private; uint32_t reg, count, r, i; int ret; reg = cbuffer->cbuffer[dw_id] & PACKET0_REG_MASK; count = (cbuffer->cbuffer[dw_id] & PACKET0_COUNT_MASK) >> PACKET0_COUNT_SHIFT; + if (reg + count > dev_priv->cbuffer_checker.numof_p0_checkers) { + return -EINVAL; + } for (r = reg, i = 0; i <= count; i++, r++) { - switch (register_right[i]) { - case REGISTER_FORBIDDEN: + if (dev_priv->cbuffer_checker.check_p0[r] == NULL) { + continue; + } + if (dev_priv->cbuffer_checker.check_p0[r] == (void *)-1) { + DRM_INFO("[radeon_ms] check_f: %d %d -1 checker\n", + r, r << 2); + return -EINVAL; + } + ret = dev_priv->cbuffer_checker.check_p0[r](dev, cbuffer, + dw_id + i + 1, reg); + if (ret) { + DRM_INFO("[radeon_ms] check_f: %d %d checker ret=%d\n", + r, r << 2, ret); return -EINVAL; - case REGISTER_SAFE: - break; - case REGISTER_SET_OFFSET: - arg = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, - dw_id + i +1); - if (arg == NULL) { - return -EINVAL; - } - /* remove from unparsed list */ - list_del(&arg->list); - list_add_tail(&arg->list, &cbuffer->arg_used.list); - /* set the offset */ - ret = amd_cbuffer_packet0_set_offset(dev, cbuffer, - r, dw_id + i + 1, - arg); - if (ret) { - return ret; - } - break; } } /* header + N + 1 dword passed test */ return count + 2; } -static int amd_cbuffer_packet3_check(struct drm_device *dev, - struct drm_file *file_priv, - struct amd_cbuffer *cbuffer, - int dw_id) +static int cbuffer_packet3_check(struct drm_device *dev, + struct amd_cbuffer *cbuffer, + int dw_id) { - struct amd_cbuffer_arg *arg; + struct drm_radeon_private *dev_priv = dev->dev_private; uint32_t opcode, count; - uint32_t s_auth, s_mask; - uint32_t gpu_addr; int ret; opcode = (cbuffer->cbuffer[dw_id] & PACKET3_OPCODE_MASK) >> PACKET3_OPCODE_SHIFT; + if (opcode > dev_priv->cbuffer_checker.numof_p3_checkers) { + return -EINVAL; + } count = (cbuffer->cbuffer[dw_id] & PACKET3_COUNT_MASK) >> PACKET3_COUNT_SHIFT; - switch (opcode) { - case PACKET3_OPCODE_NOP: - break; - case PACKET3_OPCODE_BITBLT: - case PACKET3_OPCODE_BITBLT_MULTI: - /* we only alow simple blit */ - if (count != 5) { - return -EINVAL; - } - s_mask = 0xf; - s_auth = 0x3; - if ((cbuffer->cbuffer[dw_id + 1] & s_mask) != s_auth) { - return -EINVAL; - } - arg = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, dw_id+2); - if (arg == NULL) { - return -EINVAL; - } - ret = radeon_ms_bo_get_gpu_addr(dev, &arg->buffer->mem, - &gpu_addr); - if (ret) { - return ret; - } - gpu_addr = (gpu_addr >> 10) & 0x003FFFFF; - cbuffer->cbuffer[dw_id + 2] &= 0xFFC00000; - cbuffer->cbuffer[dw_id + 2] |= gpu_addr; - - arg = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, dw_id+3); - if (arg == NULL) { - return -EINVAL; - } - ret = radeon_ms_bo_get_gpu_addr(dev, &arg->buffer->mem, - &gpu_addr); - if (ret) { - return ret; - } - gpu_addr = (gpu_addr >> 10) & 0x003FFFFF; - cbuffer->cbuffer[dw_id + 3] &= 0xFFC00000; - cbuffer->cbuffer[dw_id + 3] |= gpu_addr; - /* FIXME: check that source & destination are big enough - * for requested blit */ - break; - default: + if (dev_priv->cbuffer_checker.check_p3[opcode] == NULL) { + return -EINVAL; + } + ret = dev_priv->cbuffer_checker.check_p3[opcode](dev, cbuffer, + dw_id + 1, opcode, + count); + if (ret) { return -EINVAL; } - /* header + N + 1 dword passed test */ return count + 2; } -static int amd_cbuffer_check(struct drm_device *dev, - struct drm_file *file_priv, - struct amd_cbuffer *cbuffer) +int amd_cbuffer_check(struct drm_device *dev, struct amd_cbuffer *cbuffer) { uint32_t i; int ret; @@ -274,9 +188,7 @@ static int amd_cbuffer_check(struct drm_device *dev, for (i = 0; i < cbuffer->cbuffer_dw_count;) { switch (PACKET_HEADER_GET(cbuffer->cbuffer[i])) { case 0: - ret = amd_cbuffer_packet0_check(dev, file_priv, - cbuffer, i, - _r3xx_register_right); + ret = cbuffer_packet0_check(dev, cbuffer, i); if (ret <= 0) { return ret; } @@ -287,12 +199,10 @@ static int amd_cbuffer_check(struct drm_device *dev, /* we don't accept packet 1 */ return -EINVAL; case 2: - /* packet 2 */ - i += 1; - break; + /* FIXME: accept packet 2 */ + return -EINVAL; case 3: - ret = amd_cbuffer_packet3_check(dev, file_priv, - cbuffer, i); + ret = cbuffer_packet3_check(dev, cbuffer, i); if (ret <= 0) { return ret; } @@ -304,9 +214,25 @@ static int amd_cbuffer_check(struct drm_device *dev, return 0; } +struct amd_cbuffer_arg * +amd_cbuffer_arg_from_dw_id(struct amd_cbuffer_arg *head, uint32_t dw_id) +{ + struct amd_cbuffer_arg *arg; + + list_for_each_entry(arg, &head->list, list) { + if (arg->dw_id == dw_id) { + return arg; + } + } + /* no buffer at this dw index */ + return NULL; +} + + int radeon_ms_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct drm_radeon_private *dev_priv = dev->dev_private; struct drm_radeon_execbuffer *execbuffer = data; struct drm_fence_arg *fence_arg = &execbuffer->fence_arg; struct drm_bo_kmap_obj cmd_kmap; @@ -365,8 +291,13 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, list_add_tail(&cbuffer.args[0].list , &cbuffer.arg_used.list); /* do cmd checking & relocations */ - ret = amd_cbuffer_check(dev, file_priv, &cbuffer); - if (ret) { + if (dev_priv->cbuffer_checker.check) { + ret = dev_priv->cbuffer_checker.check(dev, &cbuffer); + if (ret) { + drm_putback_buffer_objects(dev); + goto out_free_release; + } + } else { drm_putback_buffer_objects(dev); goto out_free_release; } -- cgit v1.2.3 From a2edd07f20df67e741026097c5d46f12296d7c9d Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 8 Apr 2008 12:44:52 -0700 Subject: Add devname in modeset case If the driver is 'modeset' enabled, it'll register it's interrupt handler at load time. Set the devname in this case so that /proc/interrupts makes sense. --- shared-core/i915_init.c | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index a76acb4e..ce6f1656 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -265,6 +265,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) drm_mm_print(&dev->bm.man[DRM_BO_MEM_VRAM].manager, "VRAM"); drm_mm_print(&dev->bm.man[DRM_BO_MEM_TT].manager, "TT"); + dev->devname = DRIVER_NAME; drm_irq_install(dev); } -- cgit v1.2.3 From 386ea38b8e3af9bc9166d4ab63c4beb7e0e2267b Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 9 Apr 2008 14:12:56 -0700 Subject: Add TV out hotplug detection Doesn't yet work on my i915 test machine, but most of the necessary bits should be there. --- shared-core/i915_drv.h | 3 +++ shared-core/i915_irq.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 59 insertions(+), 4 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 64faac9b..e32c36f1 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -554,7 +554,9 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) #define I915_HOTPLUG_INTERRUPT_ENABLE (1UL<<26) +#define I915_HOTPLUG_TV_INTERRUPT_ENABLE (1UL<<18) #define I915_HOTPLUG_CLEAR (1UL<<10) +#define I915_HOTPLUG_TV_CLEAR (1UL<<2) #define I915_VBLANK_CLEAR (1UL<<1) /* @@ -669,6 +671,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6) #define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5) #define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4) +#define I915_HOTPLUG_TV_INTERRUPT_STATUS (1UL<<2) #define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ #define I915_VBLANK_INTERRUPT_STATUS (1UL<<1) #define I915_OVERLAY_UPDATED_STATUS (1UL<<0) diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index abd8a7d3..8f136c8f 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -424,11 +424,41 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane) #define HOTPLUG_CMD_CRT_DIS 2 #define HOTPLUG_CMD_SDVOB 4 #define HOTPLUG_CMD_SDVOC 8 +#define HOTPLUG_CMD_TV 16 static struct drm_device *hotplug_dev; static int hotplug_cmd = 0; static spinlock_t hotplug_lock = SPIN_LOCK_UNLOCKED; +static void i915_hotplug_tv(struct drm_device *dev) +{ + struct drm_output *output; + struct intel_output *iout; + enum drm_output_status status; + + 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_TVOUT) + break; + else + iout = 0; + } + + if (iout == 0) + goto unlock; + + /* may need to I915_WRITE(TVDAC, 1<<31) to ack the interrupt */ + status = output->funcs->detect(output); + drm_hotplug_stage_two(dev, output, + status == output_status_connected ? 1 : 0); + +unlock: + mutex_unlock(&dev->mode_config.mutex); +} + static void i915_hotplug_crt(struct drm_device *dev, bool isconnected) { struct drm_output *output; @@ -493,8 +523,10 @@ static void i915_hotplug_work_func(struct work_struct *work) int crtDis; int sdvoB; int sdvoC; + int tv; spin_lock(&hotplug_lock); + tv = hotplug_cmd & HOTPLUG_CMD_TV; crt = hotplug_cmd & HOTPLUG_CMD_CRT; crtDis = hotplug_cmd & HOTPLUG_CMD_CRT_DIS; sdvoB = hotplug_cmd & HOTPLUG_CMD_SDVOB; @@ -502,6 +534,8 @@ static void i915_hotplug_work_func(struct work_struct *work) hotplug_cmd = 0; spin_unlock(&hotplug_lock); + if (tv) + i915_hotplug_tv(dev); if (crt) i915_hotplug_crt(dev, true); if (crtDis) @@ -527,6 +561,14 @@ static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat) hotplug_dev = dev; + if (stat & TV_HOTPLUG_INT_STATUS) { + DRM_DEBUG("TV event\n"); + + spin_lock(&hotplug_lock); + hotplug_cmd |= HOTPLUG_CMD_TV; + spin_unlock(&hotplug_lock); + } + if (stat & CRT_HOTPLUG_INT_STATUS) { DRM_DEBUG("CRT event\n"); @@ -584,12 +626,14 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) DRM_DEBUG("flag=%08x\n", iir); #endif if (iir == 0) { +#if 0 DRM_DEBUG ("iir 0x%08x im 0x%08x ie 0x%08x pipea 0x%08x pipeb 0x%08x\n", iir, I915_READ(I915REG_INT_MASK_R), I915_READ(I915REG_INT_ENABLE_R), I915_READ(I915REG_PIPEASTAT), I915_READ(I915REG_PIPEBSTAT)); +#endif return IRQ_NONE; } @@ -607,7 +651,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) } /* This is a global event, and not a pipe A event */ - if (pipea_stats & I915_HOTPLUG_INTERRUPT_STATUS) + if ((pipea_stats & I915_HOTPLUG_INTERRUPT_STATUS) || + (pipea_stats & I915_HOTPLUG_TV_INTERRUPT_STATUS)) hotplug = 1; I915_WRITE(I915REG_PIPEASTAT, pipea_stats); @@ -656,8 +701,11 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) DRM_INFO("Hotplug event received\n"); if (!IS_I9XX(dev) || IS_I915G(dev) || IS_I915GM(dev)) { - temp2 |= SDVOB_HOTPLUG_INT_STATUS | - SDVOC_HOTPLUG_INT_STATUS; + if (pipea_stats & I915_HOTPLUG_INTERRUPT_STATUS) + temp2 |= SDVOB_HOTPLUG_INT_STATUS | + SDVOC_HOTPLUG_INT_STATUS; + if (pipea_stats & I915_HOTPLUG_TV_INTERRUPT_STATUS) + temp2 |= TV_HOTPLUG_INT_STATUS; } else { temp2 = I915_READ(PORT_HOTPLUG_STAT); @@ -898,7 +946,11 @@ void i915_enable_interrupt (struct drm_device *dev) dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; /* Enable global interrupts for hotplug - not a pipeA event */ - I915_WRITE(I915REG_PIPEASTAT, I915_READ(I915REG_PIPEASTAT) | I915_HOTPLUG_INTERRUPT_ENABLE | I915_HOTPLUG_CLEAR); + I915_WRITE(I915REG_PIPEASTAT, I915_READ(I915REG_PIPEASTAT) | + I915_HOTPLUG_INTERRUPT_ENABLE | + I915_HOTPLUG_TV_INTERRUPT_ENABLE | + I915_HOTPLUG_TV_CLEAR | + I915_HOTPLUG_CLEAR); } if (dev_priv->irq_enable_reg & (I915_DISPLAY_PORT_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT)) { -- cgit v1.2.3 From 5891b0bd2ae441d738e78737a4c4826bd2e60b43 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sat, 12 Apr 2008 00:15:12 +0200 Subject: radeon_ms: rework command submission ioctl & cleanup --- shared-core/amd.h | 57 +++-- shared-core/amd_legacy.h | 4 +- shared-core/amd_legacy_cbuffer.c | 146 +++++++------ shared-core/radeon_ms.h | 6 +- shared-core/radeon_ms_bo.c | 5 +- shared-core/radeon_ms_cp.c | 2 +- shared-core/radeon_ms_crtc.c | 3 +- shared-core/radeon_ms_drm.c | 8 +- shared-core/radeon_ms_drm.h | 64 +++--- shared-core/radeon_ms_exec.c | 442 ++++++++++++++++++++++----------------- shared-core/radeon_ms_fence.c | 32 +-- 11 files changed, 436 insertions(+), 333 deletions(-) (limited to 'shared-core') diff --git a/shared-core/amd.h b/shared-core/amd.h index 31cf3eff..f8096053 100644 --- a/shared-core/amd.h +++ b/shared-core/amd.h @@ -31,38 +31,55 @@ * around during command validation (ie check that user have the right to * execute the given command). */ -struct amd_cbuffer_arg +struct amd_cmd_bo { - struct list_head list; - struct drm_buffer_object *buffer; - int32_t dw_id; + struct list_head list; + uint64_t *offsets; + uint32_t *cdw_id; + struct drm_buffer_object *bo; + unsigned int handle; + uint64_t mask; + uint64_t flags; + uint32_t type; }; -struct amd_cbuffer +struct amd_cmd { - uint32_t *cbuffer; - uint32_t cbuffer_dw_count; - struct amd_cbuffer_arg arg_unused; - struct amd_cbuffer_arg arg_used; - struct amd_cbuffer_arg *args; - void *driver; + uint32_t *cdw; + uint32_t cdw_count; + struct drm_bo_kmap_obj cdw_kmap; + size_t cdw_size; + struct amd_cmd_bo *cdw_bo; + struct amd_cmd_bo bo_unused; + struct amd_cmd_bo bo_used; + struct amd_cmd_bo *bo; + uint32_t bo_count; + void *driver; }; -struct amd_cbuffer_checker +struct amd_cmd_module { uint32_t numof_p0_checkers; uint32_t numof_p3_checkers; - int (*check)(struct drm_device *dev, struct amd_cbuffer *cbuffer); - int (**check_p0)(struct drm_device *dev, struct amd_cbuffer *cbuffer, - int dw_id, int reg); - int (**check_p3)(struct drm_device *dev, struct amd_cbuffer *cbuffer, - int dw_id, int op, int count); + int (*check)(struct drm_device *dev, struct amd_cmd *cmd); + int (**check_p0)(struct drm_device *dev, struct amd_cmd *cmd, + int cdw_id, int reg); + int (**check_p3)(struct drm_device *dev, struct amd_cmd *cmd, + int cdw_id, int op, int count); }; -struct amd_cbuffer_arg * -amd_cbuffer_arg_from_dw_id(struct amd_cbuffer_arg *head, uint32_t dw_id); -int amd_cbuffer_check(struct drm_device *dev, struct amd_cbuffer *cbuffer); +int amd_cmd_check(struct drm_device *dev, struct amd_cmd *cmd); +int amd_ioctl_cmd(struct drm_device *dev, void *data, struct drm_file *file); +static inline struct amd_cmd_bo *amd_cmd_get_bo(struct amd_cmd *cmd, int i) +{ + if (i < cmd->bo_count && cmd->bo[i].type == DRM_AMD_CMD_BO_TYPE_DATA) { + list_del(&cmd->bo[i].list); + list_add_tail(&cmd->bo[i].list, &cmd->bo_used.list); + return &cmd->bo[i]; + } + return NULL; +} /* struct amd_fb amd is for storing amd framebuffer informations */ diff --git a/shared-core/amd_legacy.h b/shared-core/amd_legacy.h index 92997dcd..c1e5f5da 100644 --- a/shared-core/amd_legacy.h +++ b/shared-core/amd_legacy.h @@ -27,7 +27,7 @@ #ifndef __AMD_LEGACY_H__ #define __AMD_LEGACY_H__ -int amd_legacy_cbuffer_destroy(struct drm_device *dev); -int amd_legacy_cbuffer_initialize(struct drm_device *dev); +int amd_legacy_cmd_module_destroy(struct drm_device *dev); +int amd_legacy_cmd_module_initialize(struct drm_device *dev); #endif diff --git a/shared-core/amd_legacy_cbuffer.c b/shared-core/amd_legacy_cbuffer.c index f1b7a44b..7971ee67 100644 --- a/shared-core/amd_legacy_cbuffer.c +++ b/shared-core/amd_legacy_cbuffer.c @@ -44,23 +44,23 @@ struct legacy_check uint32_t dp_gui_master_cntl; uint32_t dst_offset; uint32_t dst_pitch; - struct amd_cbuffer_arg *dst; + struct amd_cmd_bo *dst; uint32_t dst_x; uint32_t dst_y; uint32_t dst_h; uint32_t dst_w; - struct amd_cbuffer_arg *src; + struct amd_cmd_bo *src; uint32_t src_pitch; uint32_t src_x; uint32_t src_y; }; -static int check_blit(struct drm_device *dev, struct amd_cbuffer *cbuffer) +static int check_blit(struct drm_device *dev, struct amd_cmd *cmd) { struct legacy_check *legacy_check; long bpp, start, end; - legacy_check = (struct legacy_check *)cbuffer->driver; + legacy_check = (struct legacy_check *)cmd->driver; /* check that gui master cntl have been set */ if (legacy_check->dp_gui_master_cntl == 0xffffffff) { return -EINVAL; @@ -132,13 +132,13 @@ static int check_blit(struct drm_device *dev, struct amd_cbuffer *cbuffer) } static int p0_dp_gui_master_cntl(struct drm_device *dev, - struct amd_cbuffer *cbuffer, - int dw_id, int reg) + struct amd_cmd *cmd, + int cdw_id, int reg) { struct legacy_check *legacy_check; - legacy_check = (struct legacy_check *)cbuffer->driver; - legacy_check->dp_gui_master_cntl = cbuffer->cbuffer[dw_id]; + legacy_check = (struct legacy_check *)cmd->driver; + legacy_check->dp_gui_master_cntl = cmd->cdw[cdw_id]; /* we only accept src data type to be same as dst */ if (((legacy_check->dp_gui_master_cntl >> 12) & 0x3) != 3) { return -EINVAL; @@ -147,125 +147,139 @@ static int p0_dp_gui_master_cntl(struct drm_device *dev, } static int p0_dst_pitch_offset(struct drm_device *dev, - struct amd_cbuffer *cbuffer, - int dw_id, int reg) + struct amd_cmd *cmd, + int cdw_id, int reg) { struct legacy_check *legacy_check; - uint32_t gpu_addr; + uint32_t tmp; int ret; - legacy_check = (struct legacy_check *)cbuffer->driver; - legacy_check->dst_pitch = ((cbuffer->cbuffer[dw_id] >> 22) & 0xff) << 6; - legacy_check->dst = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, - dw_id); + legacy_check = (struct legacy_check *)cmd->driver; + legacy_check->dst_pitch = ((cmd->cdw[cdw_id] >> 22) & 0xff) << 6; + tmp = cmd->cdw[cdw_id] & 0x003fffff; + legacy_check->dst = amd_cmd_get_bo(cmd, tmp); if (legacy_check->dst == NULL) { + DRM_ERROR("invalid bo (%d) for DST_PITCH_OFFSET register.\n", + tmp); return -EINVAL; } - ret = radeon_ms_bo_get_gpu_addr(dev, &legacy_check->dst->buffer->mem, - &gpu_addr); + ret = radeon_ms_bo_get_gpu_addr(dev, &legacy_check->dst->bo->mem, &tmp); if (ret) { + DRM_ERROR("failed to get GPU offset for bo 0x%x.\n", + legacy_check->dst->handle); return -EINVAL; } - cbuffer->cbuffer[dw_id] &= 0xffc00000; - cbuffer->cbuffer[dw_id] |= (gpu_addr >> 10); + if (tmp & 0x3fff) { + DRM_ERROR("bo 0x%x offset doesn't meet alignement 0x%x.\n", + legacy_check->dst->handle, tmp); + } + cmd->cdw[cdw_id] &= 0xffc00000; + cmd->cdw[cdw_id] |= (tmp >> 10); return 0; } static int p0_src_pitch_offset(struct drm_device *dev, - struct amd_cbuffer *cbuffer, - int dw_id, int reg) + struct amd_cmd *cmd, + int cdw_id, int reg) { struct legacy_check *legacy_check; - uint32_t gpu_addr; + uint32_t tmp; int ret; - legacy_check = (struct legacy_check *)cbuffer->driver; - legacy_check->src_pitch = ((cbuffer->cbuffer[dw_id] >> 22) & 0xff) << 6; - legacy_check->src = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, - dw_id); - if (legacy_check->dst == NULL) { + legacy_check = (struct legacy_check *)cmd->driver; + legacy_check->src_pitch = ((cmd->cdw[cdw_id] >> 22) & 0xff) << 6; + tmp = cmd->cdw[cdw_id] & 0x003fffff; + legacy_check->src = amd_cmd_get_bo(cmd, tmp); + if (legacy_check->src == NULL) { + DRM_ERROR("invalid bo (%d) for SRC_PITCH_OFFSET register.\n", + tmp); return -EINVAL; } - ret = radeon_ms_bo_get_gpu_addr(dev, &legacy_check->src->buffer->mem, - &gpu_addr); + ret = radeon_ms_bo_get_gpu_addr(dev, &legacy_check->src->bo->mem, &tmp); if (ret) { + DRM_ERROR("failed to get GPU offset for bo 0x%x.\n", + legacy_check->src->handle); return -EINVAL; } - cbuffer->cbuffer[dw_id] &= 0xffc00000; - cbuffer->cbuffer[dw_id] |= (gpu_addr >> 10); + if (tmp & 0x3fff) { + DRM_ERROR("bo 0x%x offset doesn't meet alignement 0x%x.\n", + legacy_check->src->handle, tmp); + } + cmd->cdw[cdw_id] &= 0xffc00000; + cmd->cdw[cdw_id] |= (tmp >> 10); return 0; } static int p0_dst_y_x(struct drm_device *dev, - struct amd_cbuffer *cbuffer, - int dw_id, int reg) + struct amd_cmd *cmd, + int cdw_id, int reg) { struct legacy_check *legacy_check; - legacy_check = (struct legacy_check *)cbuffer->driver; - legacy_check->dst_x = cbuffer->cbuffer[dw_id] & 0xffff; - legacy_check->dst_y = (cbuffer->cbuffer[dw_id] >> 16) & 0xffff; + legacy_check = (struct legacy_check *)cmd->driver; + legacy_check->dst_x = cmd->cdw[cdw_id] & 0xffff; + legacy_check->dst_y = (cmd->cdw[cdw_id] >> 16) & 0xffff; return 0; } static int p0_src_y_x(struct drm_device *dev, - struct amd_cbuffer *cbuffer, - int dw_id, int reg) + struct amd_cmd *cmd, + int cdw_id, int reg) { struct legacy_check *legacy_check; - legacy_check = (struct legacy_check *)cbuffer->driver; - legacy_check->src_x = cbuffer->cbuffer[dw_id] & 0xffff; - legacy_check->src_y = (cbuffer->cbuffer[dw_id] >> 16) & 0xffff; + legacy_check = (struct legacy_check *)cmd->driver; + legacy_check->src_x = cmd->cdw[cdw_id] & 0xffff; + legacy_check->src_y = (cmd->cdw[cdw_id] >> 16) & 0xffff; return 0; } static int p0_dst_h_w(struct drm_device *dev, - struct amd_cbuffer *cbuffer, - int dw_id, int reg) + struct amd_cmd *cmd, + int cdw_id, int reg) { struct legacy_check *legacy_check; - legacy_check = (struct legacy_check *)cbuffer->driver; - legacy_check->dst_w = cbuffer->cbuffer[dw_id] & 0xffff; - legacy_check->dst_h = (cbuffer->cbuffer[dw_id] >> 16) & 0xffff; - return check_blit(dev, cbuffer); + legacy_check = (struct legacy_check *)cmd->driver; + legacy_check->dst_w = cmd->cdw[cdw_id] & 0xffff; + legacy_check->dst_h = (cmd->cdw[cdw_id] >> 16) & 0xffff; + return check_blit(dev, cmd); } -static int legacy_cbuffer_check(struct drm_device *dev, - struct amd_cbuffer *cbuffer) +static int legacy_cmd_check(struct drm_device *dev, + struct amd_cmd *cmd) { struct legacy_check legacy_check; memset(&legacy_check, 0xff, sizeof(struct legacy_check)); - cbuffer->driver = &legacy_check; - return amd_cbuffer_check(dev, cbuffer); + cmd->driver = &legacy_check; + return amd_cmd_check(dev, cmd); } -int amd_legacy_cbuffer_destroy(struct drm_device *dev) +int amd_legacy_cmd_module_destroy(struct drm_device *dev) { struct drm_radeon_private *dev_priv = dev->dev_private; - dev_priv->cbuffer_checker.check = NULL; - if (dev_priv->cbuffer_checker.numof_p0_checkers) { - drm_free(dev_priv->cbuffer_checker.check_p0, - dev_priv->cbuffer_checker.numof_p0_checkers * + dev_priv->cmd_module.check = NULL; + if (dev_priv->cmd_module.numof_p0_checkers) { + drm_free(dev_priv->cmd_module.check_p0, + dev_priv->cmd_module.numof_p0_checkers * sizeof(void*), DRM_MEM_DRIVER); - dev_priv->cbuffer_checker.numof_p0_checkers = 0; + dev_priv->cmd_module.numof_p0_checkers = 0; } - if (dev_priv->cbuffer_checker.numof_p3_checkers) { - drm_free(dev_priv->cbuffer_checker.check_p3, - dev_priv->cbuffer_checker.numof_p3_checkers * + if (dev_priv->cmd_module.numof_p3_checkers) { + drm_free(dev_priv->cmd_module.check_p3, + dev_priv->cmd_module.numof_p3_checkers * sizeof(void*), DRM_MEM_DRIVER); - dev_priv->cbuffer_checker.numof_p3_checkers = 0; + dev_priv->cmd_module.numof_p3_checkers = 0; } return 0; } -int amd_legacy_cbuffer_initialize(struct drm_device *dev) +int amd_legacy_cmd_module_initialize(struct drm_device *dev) { struct drm_radeon_private *dev_priv = dev->dev_private; - struct amd_cbuffer_checker *checker = &dev_priv->cbuffer_checker; + struct amd_cmd_module *checker = &dev_priv->cmd_module; long size; /* packet 0 */ @@ -273,7 +287,7 @@ int amd_legacy_cbuffer_initialize(struct drm_device *dev) size = checker->numof_p0_checkers * sizeof(void*); checker->check_p0 = drm_alloc(size, DRM_MEM_DRIVER); if (checker->check_p0 == NULL) { - amd_legacy_cbuffer_destroy(dev); + amd_legacy_cmd_module_destroy(dev); return -ENOMEM; } /* initialize to -1 */ @@ -284,7 +298,7 @@ int amd_legacy_cbuffer_initialize(struct drm_device *dev) size = checker->numof_p3_checkers * sizeof(void*); checker->check_p3 = drm_alloc(size, DRM_MEM_DRIVER); if (checker->check_p3 == NULL) { - amd_legacy_cbuffer_destroy(dev); + amd_legacy_cmd_module_destroy(dev); return -ENOMEM; } /* initialize to -1 */ @@ -301,6 +315,6 @@ int amd_legacy_cbuffer_initialize(struct drm_device *dev) checker->check_p0[RADEON_DP_WRITE_MASK >> 2] = NULL; checker->check_p0[RADEON_DP_CNTL >> 2] = NULL; - checker->check = legacy_cbuffer_check; + checker->check = legacy_cmd_check; return 0; } diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h index ec264207..dd34683e 100644 --- a/shared-core/radeon_ms.h +++ b/shared-core/radeon_ms.h @@ -330,7 +330,7 @@ struct drm_radeon_private { uint8_t bus_ready; uint8_t write_back; /* command buffer informations */ - struct amd_cbuffer_checker cbuffer_checker; + struct amd_cmd_module cmd_module; /* abstract asic specific structures */ struct radeon_ms_rom rom; struct radeon_ms_properties properties; @@ -426,10 +426,6 @@ 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); diff --git a/shared-core/radeon_ms_bo.c b/shared-core/radeon_ms_bo.c index 015595a4..b366ae5a 100644 --- a/shared-core/radeon_ms_bo.c +++ b/shared-core/radeon_ms_bo.c @@ -134,8 +134,9 @@ static int radeon_ms_bo_move_blit(struct drm_buffer_object *bo, 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, + DRM_AMD_FENCE_TYPE_R | + DRM_AMD_FENCE_TYPE_W, + DRM_AMD_FENCE_FLAG_FLUSH, new_mem); return ret; } diff --git a/shared-core/radeon_ms_cp.c b/shared-core/radeon_ms_cp.c index f551000a..3ddeea47 100644 --- a/shared-core/radeon_ms_cp.c +++ b/shared-core/radeon_ms_cp.c @@ -332,7 +332,7 @@ int radeon_ms_ring_emit(struct drm_device *dev, uint32_t *cmd, uint32_t count) dev_priv->ring_free -= count; for (i = 0; i < count; i++) { dev_priv->ring_buffer[dev_priv->ring_wptr] = cmd[i]; - DRM_INFO("ring[%d]=0x%08X\n", dev_priv->ring_wptr, cmd[i]); + DRM_DEBUG("ring[%d]=0x%08X\n", dev_priv->ring_wptr, cmd[i]); dev_priv->ring_wptr++; dev_priv->ring_wptr &= dev_priv->ring_mask; } diff --git a/shared-core/radeon_ms_crtc.c b/shared-core/radeon_ms_crtc.c index 83dd0777..3586e019 100644 --- a/shared-core/radeon_ms_crtc.c +++ b/shared-core/radeon_ms_crtc.c @@ -551,6 +551,7 @@ static void radeon_ms_crtc1_mode_set(struct drm_crtc *crtc, format = 4; } break; + case 24: case 32: format = 6; break; @@ -648,7 +649,7 @@ static void radeon_ms_crtc1_mode_set_base(struct drm_crtc *crtc, int x, int y) struct drm_radeon_private *dev_priv = dev->dev_private; struct radeon_state *state = &dev_priv->driver_state; - DRM_INFO("[radeon_ms] mode_set_base\n"); + DRM_INFO("mode_set_base 0x%lX\n", crtc->fb->bo->offset); state->crtc_offset = REG_S(CRTC_OFFSET, CRTC_OFFSET, crtc->fb->bo->offset); radeon_ms_crtc1_restore(dev, state); } diff --git a/shared-core/radeon_ms_drm.c b/shared-core/radeon_ms_drm.c index 0d327925..9238de24 100644 --- a/shared-core/radeon_ms_drm.c +++ b/shared-core/radeon_ms_drm.c @@ -59,8 +59,8 @@ struct drm_bo_driver radeon_ms_bo_driver = { }; struct drm_ioctl_desc radeon_ms_ioctls[] = { - DRM_IOCTL_DEF(DRM_RADEON_EXECBUFFER, radeon_ms_execbuffer, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_RESETCP, radeon_ms_resetcp, DRM_AUTH), + DRM_IOCTL_DEF(DRM_AMD_CMD, amd_ioctl_cmd, DRM_AUTH), + DRM_IOCTL_DEF(DRM_AMD_RESETCP, radeon_ms_resetcp, DRM_AUTH), }; int radeon_ms_num_ioctls = DRM_ARRAY_SIZE(radeon_ms_ioctls); @@ -247,7 +247,7 @@ int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags) } /* initialze driver specific */ - ret = amd_legacy_cbuffer_initialize(dev); + ret = amd_legacy_cmd_module_initialize(dev); if (ret != 0) { radeon_ms_driver_unload(dev); return ret; @@ -286,7 +286,7 @@ int radeon_ms_driver_unload(struct drm_device *dev) radeon_ms_outputs_destroy(dev); /* shutdown specific driver */ - amd_legacy_cbuffer_destroy(dev); + amd_legacy_cmd_module_destroy(dev); /* shutdown cp engine */ radeon_ms_cp_finish(dev); diff --git a/shared-core/radeon_ms_drm.h b/shared-core/radeon_ms_drm.h index e1b4c18c..d7fe6fab 100644 --- a/shared-core/radeon_ms_drm.h +++ b/shared-core/radeon_ms_drm.h @@ -27,42 +27,54 @@ * Authors: * Jérôme Glisse */ -#ifndef __RADEON_MS_DRM_H__ -#define __RADEON_MS_DRM_H__ +#ifndef __AMD_DRM_H__ +#define __AMD_DRM_H__ /* Fence - * We have only one fence class as we submit command through th - * same fifo so there is no need to synchronize buffer btw different - * cmd stream. * - * Set DRM_RADEON_FENCE_FLAG_FLUSHED if you want a flush with + * Set DRM_AND_FENCE_FLAG_FLUSH if you want a flush with * emission of the fence * - * For fence type we have the native DRM EXE type and the radeon RW - * type. + * For fence type we have the native DRM EXE type and the amd R & W type. */ -#define DRM_RADEON_FENCE_CLASS_ACCEL 0 -#define DRM_RADEON_FENCE_TYPE_RW 2 -#define DRM_RADEON_FENCE_FLAG_FLUSHED 0x01000000 +#define DRM_AMD_FENCE_CLASS_2D 0 +#define DRM_AMD_FENCE_TYPE_R (1 << 1) +#define DRM_AMD_FENCE_TYPE_W (1 << 2) +#define DRM_AMD_FENCE_FLAG_FLUSH 0x01000000 -/* radeon ms ioctl */ -#define DRM_RADEON_EXECBUFFER 0x00 -#define DRM_RADEON_RESETCP 0x01 +/* ioctl */ +#define DRM_AMD_CMD 0x00 +#define DRM_AMD_RESETCP 0x01 -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; +/* cmd ioctl */ + +#define DRM_AMD_CMD_BO_TYPE_INVALID 0 +#define DRM_AMD_CMD_BO_TYPE_CMD_RING (1 << 0) +#define DRM_AMD_CMD_BO_TYPE_CMD_INDIRECT (1 << 1) +#define DRM_AMD_CMD_BO_TYPE_DATA (1 << 2) + +struct drm_amd_cmd_bo_offset +{ + uint64_t next; + uint64_t offset; + uint32_t cs_id; +}; + +struct drm_amd_cmd_bo +{ + uint32_t type; + uint64_t next; + uint64_t offset; + struct drm_bo_op_req op_req; + struct drm_bo_arg_rep op_rep; }; -struct drm_radeon_execbuffer { - uint32_t args_count; - uint64_t args; - uint32_t cmd_size; - struct drm_fence_arg fence_arg; +struct drm_amd_cmd +{ + uint32_t cdw_count; + uint32_t bo_count; + uint64_t bo; + struct drm_fence_arg fence_arg; }; #endif diff --git a/shared-core/radeon_ms_exec.c b/shared-core/radeon_ms_exec.c index 28fcc180..fc359d45 100644 --- a/shared-core/radeon_ms_exec.c +++ b/shared-core/radeon_ms_exec.c @@ -27,173 +27,233 @@ #include "radeon_ms.h" #include "amd.h" -static void radeon_ms_execbuffer_args_clean(struct drm_device *dev, - struct amd_cbuffer *cbuffer, - uint32_t args_count) +static inline void amd_cmd_bo_cleanup(struct drm_device *dev, + struct amd_cmd *cmd) { + struct amd_cmd_bo *bo; + mutex_lock(&dev->struct_mutex); - while (args_count--) { - drm_bo_usage_deref_locked(&cbuffer->args[args_count].buffer); + list_for_each_entry(bo, &cmd->bo_unused.list, list) { + drm_bo_usage_deref_locked(&bo->bo); + } + list_for_each_entry(bo, &cmd->bo_used.list, list) { + drm_bo_usage_deref_locked(&bo->bo); } 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 amd_cbuffer *cbuffer) +static inline int amd_cmd_bo_validate(struct drm_device *dev, + struct drm_file *file, + struct amd_cmd_bo *cmd_bo, + struct drm_amd_cmd_bo *bo, + uint64_t data) +{ + int ret; + + /* validate only cmd indirect or data bo */ + switch (bo->type) { + case DRM_AMD_CMD_BO_TYPE_CMD_INDIRECT: + case DRM_AMD_CMD_BO_TYPE_DATA: + case DRM_AMD_CMD_BO_TYPE_CMD_RING: + /* FIXME: make sure userspace can no longer map the bo */ + break; + default: + return 0; + } + /* check that buffer operation is validate */ + if (bo->op_req.op != drm_bo_validate) { + DRM_ERROR("buffer 0x%x object operation is not validate.\n", + cmd_bo->handle); + return -EINVAL; + } + /* validate buffer */ + memset(&bo->op_rep, 0, sizeof(struct drm_bo_arg_rep)); + ret = drm_bo_handle_validate(file, + bo->op_req.bo_req.handle, + bo->op_req.bo_req.flags, + bo->op_req.bo_req.mask, + bo->op_req.bo_req.hint, + bo->op_req.bo_req.fence_class, + 0, + &bo->op_rep.bo_info, + &cmd_bo->bo); + if (ret) { + DRM_ERROR("validate error %d for 0x%08x\n", + ret, cmd_bo->handle); + return ret; + } + if (copy_to_user((void __user *)((unsigned)data), bo, + sizeof(struct drm_amd_cmd_bo))) { + DRM_ERROR("failed to copy to user validate result of 0x%08x\n", + cmd_bo->handle); + return -EFAULT; + } + return 0; +} + +static int amd_cmd_parse_cmd_bo(struct drm_device *dev, + struct drm_file *file, + struct drm_amd_cmd *drm_amd_cmd, + struct amd_cmd *cmd) { - 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; + struct drm_amd_cmd_bo drm_amd_cmd_bo; + struct amd_cmd_bo *cmd_bo; + uint32_t bo_count = 0; + uint64_t data = drm_amd_cmd->bo; 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; + /* check we don't have more buffer than announced */ + if (bo_count >= drm_amd_cmd->bo_count) { + DRM_ERROR("cmd bo count exceeded got %d waited %d\n.", + bo_count, drm_amd_cmd->bo_count); + return -EINVAL; } - INIT_LIST_HEAD(&cbuffer->args[args_count].list); - cbuffer->args[args_count].buffer = NULL; - if (copy_from_user(&arg, (void __user *)((unsigned)data), - sizeof(struct drm_radeon_execbuffer_arg))) { - ret = -EFAULT; - goto out_err; + /* initialize amd_cmd_bo */ + cmd_bo = &cmd->bo[bo_count]; + INIT_LIST_HEAD(&cmd_bo->list); + cmd_bo->bo = NULL; + /* copy from userspace */ + if (copy_from_user(&drm_amd_cmd_bo, + (void __user *)((unsigned)data), + sizeof(struct drm_amd_cmd_bo))) { + return -EFAULT; } + /* collect informations */ + cmd_bo->type = drm_amd_cmd_bo.type; + cmd_bo->mask = drm_amd_cmd_bo.op_req.bo_req.mask; + cmd_bo->flags = drm_amd_cmd_bo.op_req.bo_req.flags; + cmd_bo->handle = drm_amd_cmd_bo.op_req.arg_handle; + /* get bo objects */ mutex_lock(&dev->struct_mutex); - cbuffer->args[args_count].buffer = - drm_lookup_buffer_object(file_priv, - arg.d.req.arg_handle, 1); - cbuffer->args[args_count].dw_id = arg.reloc_offset; + cmd_bo->bo = drm_lookup_buffer_object(file, cmd_bo->handle, 1); 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; + if (cmd_bo->bo == NULL) { + DRM_ERROR("unknown bo handle 0x%x\n", cmd_bo->handle); + return -EINVAL; } - memset(&rep, 0, sizeof(struct drm_bo_arg_rep)); - ret = drm_bo_handle_validate(file_priv, - arg.d.req.bo_req.handle, - arg.d.req.bo_req.flags, - arg.d.req.bo_req.mask, - arg.d.req.bo_req.hint, - arg.d.req.bo_req.fence_class, - 0, - &rep.bo_info, - &cbuffer->args[args_count].buffer); + /* validate buffer if necessary */ + ret = amd_cmd_bo_validate(dev, file, cmd_bo, + &drm_amd_cmd_bo, data); if (ret) { - DRM_ERROR("[radeon_ms] error on handle validate %d\n", - ret); - rep.ret = ret; - goto out_err; + mutex_lock(&dev->struct_mutex); + drm_bo_usage_deref_locked(&cmd_bo->bo); + mutex_unlock(&dev->struct_mutex); + return ret; } - 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; + /* inspect bo type */ + switch (cmd_bo->type) { + case DRM_AMD_CMD_BO_TYPE_CMD_INDIRECT: + /* add it so we properly unreference in case of error */ + list_add_tail(&cmd_bo->list, &cmd->bo_used.list); + return -EINVAL; + case DRM_AMD_CMD_BO_TYPE_DATA: + /* add to unused list */ + list_add_tail(&cmd_bo->list, &cmd->bo_unused.list); + break; + case DRM_AMD_CMD_BO_TYPE_CMD_RING: + /* set cdw_bo */ + list_add_tail(&cmd_bo->list, &cmd->bo_used.list); + cmd->cdw_bo = cmd_bo; + break; + default: + mutex_lock(&dev->struct_mutex); + drm_bo_usage_deref_locked(&cmd_bo->bo); + mutex_unlock(&dev->struct_mutex); + DRM_ERROR("unknow bo 0x%x unknown type 0x%x in cmd\n", + cmd_bo->handle, cmd_bo->type); + return -EINVAL; } - data = next; - - list_add_tail(&cbuffer->args[args_count].list, - &cbuffer->arg_unused.list); - - 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; + /* ok next bo */ + data = drm_amd_cmd_bo.next; + bo_count++; + } while (data != 0); + if (bo_count != drm_amd_cmd->bo_count) { + DRM_ERROR("not enought buffer got %d expected %d\n.", + bo_count, drm_amd_cmd->bo_count); + return -EINVAL; } return 0; -out_err: - radeon_ms_execbuffer_args_clean(dev, cbuffer, args_count); - return ret; } -static int cbuffer_packet0_check(struct drm_device *dev, - struct amd_cbuffer *cbuffer, - int dw_id) +static int amd_cmd_packet0_check(struct drm_device *dev, + struct amd_cmd *cmd, + int *cdw_id) { struct drm_radeon_private *dev_priv = dev->dev_private; uint32_t reg, count, r, i; int ret; - reg = cbuffer->cbuffer[dw_id] & PACKET0_REG_MASK; - count = (cbuffer->cbuffer[dw_id] & PACKET0_COUNT_MASK) >> - PACKET0_COUNT_SHIFT; - if (reg + count > dev_priv->cbuffer_checker.numof_p0_checkers) { + reg = cmd->cdw[*cdw_id] & PACKET0_REG_MASK; + count = (cmd->cdw[*cdw_id] & PACKET0_COUNT_MASK) >> PACKET0_COUNT_SHIFT; + if (reg + count > dev_priv->cmd_module.numof_p0_checkers) { + DRM_ERROR("0x%08X registers is above last accepted registers\n", + reg << 2); return -EINVAL; } for (r = reg, i = 0; i <= count; i++, r++) { - if (dev_priv->cbuffer_checker.check_p0[r] == NULL) { + if (dev_priv->cmd_module.check_p0[r] == NULL) { continue; } - if (dev_priv->cbuffer_checker.check_p0[r] == (void *)-1) { - DRM_INFO("[radeon_ms] check_f: %d %d -1 checker\n", - r, r << 2); + if (dev_priv->cmd_module.check_p0[r] == (void *)-1) { + DRM_ERROR("register 0x%08X (at %d) is forbidden\n", + r << 2, (*cdw_id) + i + 1); return -EINVAL; } - ret = dev_priv->cbuffer_checker.check_p0[r](dev, cbuffer, - dw_id + i + 1, reg); + ret = dev_priv->cmd_module.check_p0[r](dev, cmd, + (*cdw_id) + i + 1, r); if (ret) { - DRM_INFO("[radeon_ms] check_f: %d %d checker ret=%d\n", - r, r << 2, ret); - return -EINVAL; + return ret; } } /* header + N + 1 dword passed test */ - return count + 2; + (*cdw_id) += count + 2; + return 0; } -static int cbuffer_packet3_check(struct drm_device *dev, - struct amd_cbuffer *cbuffer, - int dw_id) +static int amd_cmd_packet3_check(struct drm_device *dev, + struct amd_cmd *cmd, + int *cdw_id) { struct drm_radeon_private *dev_priv = dev->dev_private; uint32_t opcode, count; int ret; - opcode = (cbuffer->cbuffer[dw_id] & PACKET3_OPCODE_MASK) >> + opcode = (cmd->cdw[*cdw_id] & PACKET3_OPCODE_MASK) >> PACKET3_OPCODE_SHIFT; - if (opcode > dev_priv->cbuffer_checker.numof_p3_checkers) { + if (opcode > dev_priv->cmd_module.numof_p3_checkers) { + DRM_ERROR("0x%08X opcode is above last accepted opcodes\n", + opcode); return -EINVAL; } - count = (cbuffer->cbuffer[dw_id] & PACKET3_COUNT_MASK) >> - PACKET3_COUNT_SHIFT; - if (dev_priv->cbuffer_checker.check_p3[opcode] == NULL) { + count = (cmd->cdw[*cdw_id] & PACKET3_COUNT_MASK) >> PACKET3_COUNT_SHIFT; + if (dev_priv->cmd_module.check_p3[opcode] == NULL) { + DRM_ERROR("0x%08X opcode is forbidden\n", opcode); return -EINVAL; } - ret = dev_priv->cbuffer_checker.check_p3[opcode](dev, cbuffer, - dw_id + 1, opcode, - count); + ret = dev_priv->cmd_module.check_p3[opcode](dev, cmd, + (*cdw_id) + 1, opcode, + count); if (ret) { - return -EINVAL; + return ret; } - return count + 2; + /* header + N + 1 dword passed test */ + (*cdw_id) += count + 2; + return 0; } -int amd_cbuffer_check(struct drm_device *dev, struct amd_cbuffer *cbuffer) +int amd_cmd_check(struct drm_device *dev, struct amd_cmd *cmd) { uint32_t i; int ret; - for (i = 0; i < cbuffer->cbuffer_dw_count;) { - switch (PACKET_HEADER_GET(cbuffer->cbuffer[i])) { + for (i = 0; i < cmd->cdw_count;) { + switch (PACKET_HEADER_GET(cmd->cdw[i])) { case 0: - ret = cbuffer_packet0_check(dev, cbuffer, i); - if (ret <= 0) { + ret = amd_cmd_packet0_check(dev, cmd, &i); + if (ret) { return ret; } - /* advance to next packet */ - i += ret; break; case 1: /* we don't accept packet 1 */ @@ -202,122 +262,122 @@ int amd_cbuffer_check(struct drm_device *dev, struct amd_cbuffer *cbuffer) /* FIXME: accept packet 2 */ return -EINVAL; case 3: - ret = cbuffer_packet3_check(dev, cbuffer, i); - if (ret <= 0) { + ret = amd_cmd_packet3_check(dev, cmd, &i); + if (ret) { return ret; } - /* advance to next packet */ - i += ret; break; } } return 0; } -struct amd_cbuffer_arg * -amd_cbuffer_arg_from_dw_id(struct amd_cbuffer_arg *head, uint32_t dw_id) +static int amd_ioctl_cmd_cleanup(struct drm_device *dev, + struct drm_file *file, + struct amd_cmd *cmd, + int r) { - struct amd_cbuffer_arg *arg; - - list_for_each_entry(arg, &head->list, list) { - if (arg->dw_id == dw_id) { - return arg; - } + /* check if we need to unfence object */ + if (r && (!list_empty(&cmd->bo_unused.list) || + !list_empty(&cmd->bo_unused.list))) { + drm_putback_buffer_objects(dev); + } + if (cmd->cdw) { + drm_bo_kunmap(&cmd->cdw_kmap); + cmd->cdw = NULL; } - /* no buffer at this dw index */ - return NULL; + /* derefence buffer as lookup reference them */ + amd_cmd_bo_cleanup(dev, cmd); + if (cmd->bo) { + drm_free(cmd->bo, + cmd->bo_count * sizeof(struct amd_cmd_bo), + DRM_MEM_DRIVER); + cmd->bo = NULL; + } + drm_bo_read_unlock(&dev->bm.bm_lock); + return r; } - -int radeon_ms_execbuffer(struct drm_device *dev, void *data, - struct drm_file *file_priv) +int amd_ioctl_cmd(struct drm_device *dev, void *data, struct drm_file *file) { struct drm_radeon_private *dev_priv = dev->dev_private; - struct drm_radeon_execbuffer *execbuffer = data; - struct drm_fence_arg *fence_arg = &execbuffer->fence_arg; - struct drm_bo_kmap_obj cmd_kmap; + struct drm_amd_cmd *drm_amd_cmd = data; + struct drm_fence_arg *fence_arg = &drm_amd_cmd->fence_arg; struct drm_fence_object *fence; - int cmd_is_iomem; - int ret = 0; - struct amd_cbuffer cbuffer; + struct amd_cmd cmd; + int tmp; + int ret; - /* command buffer dword count must be >= 0 */ - if (execbuffer->cmd_size < 0) { + /* check that we have a command checker */ + if (dev_priv->cmd_module.check == NULL) { + DRM_ERROR("invalid command checker module.\n"); + return -EFAULT; + } + /* command dword count must be >= 0 */ + if (drm_amd_cmd->cdw_count == 0) { + DRM_ERROR("command dword count is 0.\n"); return -EINVAL; } - - /* FIXME: Lock buffer manager, is this really needed ? - */ + /* FIXME: Lock buffer manager, is this really needed ? */ ret = drm_bo_read_lock(&dev->bm.bm_lock); if (ret) { + DRM_ERROR("bo read locking failed.\n"); return ret; } - - cbuffer.args = drm_calloc(execbuffer->args_count, - sizeof(struct amd_cbuffer_arg), - DRM_MEM_DRIVER); - if (cbuffer.args == NULL) { - ret = -ENOMEM; - goto out_free; + /* cleanup & initialize amd cmd structure */ + memset(&cmd, 0, sizeof(struct amd_cmd)); + cmd.bo_count = drm_amd_cmd->bo_count; + INIT_LIST_HEAD(&cmd.bo_unused.list); + INIT_LIST_HEAD(&cmd.bo_used.list); + /* allocate structure for bo parsing */ + cmd.bo = drm_calloc(cmd.bo_count, sizeof(struct amd_cmd_bo), + DRM_MEM_DRIVER); + if (cmd.bo == NULL) { + return amd_ioctl_cmd_cleanup(dev, file, &cmd, -ENOMEM); } - - INIT_LIST_HEAD(&cbuffer.arg_unused.list); - INIT_LIST_HEAD(&cbuffer.arg_used.list); - - /* process arguments */ - ret = radeon_ms_execbuffer_args(dev, file_priv, execbuffer, &cbuffer); + /* parse cmd bo */ + ret = amd_cmd_parse_cmd_bo(dev, file, drm_amd_cmd, &cmd); if (ret) { - DRM_ERROR("[radeon_ms] execbuffer wrong arguments\n"); - goto out_free; + return amd_ioctl_cmd_cleanup(dev, file, &cmd, ret); + } + /* check that a command buffer have been found */ + if (cmd.cdw_bo == NULL) { + DRM_ERROR("no command buffer submited in cmd ioctl\n"); + return amd_ioctl_cmd_cleanup(dev, file, &cmd, -EINVAL); } - /* map command buffer */ - cbuffer.cbuffer_dw_count = (cbuffer.args[0].buffer->mem.num_pages * - PAGE_SIZE) >> 2; - if (execbuffer->cmd_size > cbuffer.cbuffer_dw_count) { - ret = -EINVAL; - goto out_free_release; + cmd.cdw_count = drm_amd_cmd->cdw_count; + cmd.cdw_size = (cmd.cdw_bo->bo->mem.num_pages * PAGE_SIZE) >> 2; + if (cmd.cdw_size < cmd.cdw_count) { + DRM_ERROR("command buffer (%d) is smaller than expected (%d)\n", + cmd.cdw_size, cmd.cdw_count); + return amd_ioctl_cmd_cleanup(dev, file, &cmd, -EINVAL); } - cbuffer.cbuffer_dw_count = execbuffer->cmd_size; - memset(&cmd_kmap, 0, sizeof(struct drm_bo_kmap_obj)); - ret = drm_bo_kmap(cbuffer.args[0].buffer, 0, - cbuffer.args[0].buffer->mem.num_pages, &cmd_kmap); + memset(&cmd.cdw_kmap, 0, sizeof(struct drm_bo_kmap_obj)); + ret = drm_bo_kmap(cmd.cdw_bo->bo, 0, + cmd.cdw_bo->bo->mem.num_pages, &cmd.cdw_kmap); if (ret) { - DRM_ERROR("[radeon_ms] error mapping ring buffer: %d\n", ret); - goto out_free_release; + DRM_ERROR("error mapping command buffer\n"); + return amd_ioctl_cmd_cleanup(dev, file, &cmd, ret); } - cbuffer.cbuffer = drm_bmo_virtual(&cmd_kmap, &cmd_is_iomem); - list_del(&cbuffer.args[0].list); - list_add_tail(&cbuffer.args[0].list , &cbuffer.arg_used.list); - - /* do cmd checking & relocations */ - if (dev_priv->cbuffer_checker.check) { - ret = dev_priv->cbuffer_checker.check(dev, &cbuffer); - if (ret) { - drm_putback_buffer_objects(dev); - goto out_free_release; - } - } else { - drm_putback_buffer_objects(dev); - goto out_free_release; + cmd.cdw = drm_bmo_virtual(&cmd.cdw_kmap, &tmp); + /* do command checking */ + ret = dev_priv->cmd_module.check(dev, &cmd); + if (ret) { + return amd_ioctl_cmd_cleanup(dev, file, &cmd, ret); } - - ret = radeon_ms_ring_emit(dev, cbuffer.cbuffer, - cbuffer.cbuffer_dw_count); + /* copy command to ring */ + ret = radeon_ms_ring_emit(dev, cmd.cdw, cmd.cdw_count); if (ret) { - drm_putback_buffer_objects(dev); - goto out_free_release; + return amd_ioctl_cmd_cleanup(dev, file, &cmd, ret); } - /* 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; + return amd_ioctl_cmd_cleanup(dev, file, &cmd, ret); } if (!(fence_arg->flags & DRM_FENCE_FLAG_NO_USER)) { - ret = drm_fence_add_user_object(file_priv, fence, + ret = drm_fence_add_user_object(file, fence, fence_arg->flags & DRM_FENCE_FLAG_SHAREABLE); if (!ret) { @@ -326,16 +386,10 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, fence_arg->type = fence->type; fence_arg->signaled = fence->signaled_types; fence_arg->sequence = fence->sequence; + } else { + DRM_ERROR("error add object fence, expect oddity !\n"); } } drm_fence_usage_deref_unlocked(&fence); -out_free_release: - drm_bo_kunmap(&cmd_kmap); - radeon_ms_execbuffer_args_clean(dev, &cbuffer, execbuffer->args_count); -out_free: - drm_free(cbuffer.args, - (execbuffer->args_count * sizeof(struct amd_cbuffer_arg)), - DRM_MEM_DRIVER); - drm_bo_read_unlock(&dev->bm.bm_lock); - return ret; + return amd_ioctl_cmd_cleanup(dev, file, &cmd, 0); } diff --git a/shared-core/radeon_ms_fence.c b/shared-core/radeon_ms_fence.c index 994c3e48..08e53bd2 100644 --- a/shared-core/radeon_ms_fence.c +++ b/shared-core/radeon_ms_fence.c @@ -44,7 +44,10 @@ static inline int r3xx_fence_emit_sequence(struct drm_device *dev, sequence & ~R3XX_FENCE_SEQUENCE_RW_FLUSH; /* Ask flush for VERTEX & FRAGPROG pipeline * have 3D idle */ + /* FIXME: proper flush */ +#if 0 dev_priv->flush_cache(dev); +#endif } cmd[0] = CP_PACKET0(dev_priv->fence_reg, 0); cmd[1] = sequence; @@ -78,18 +81,17 @@ static inline void r3xx_fence_report(struct drm_device *dev, return; } sequence = mmio_read(dev_priv, dev_priv->fence_reg); +DRM_INFO("%s pass fence 0x%08x\n", __func__, sequence); if (sequence & R3XX_FENCE_SEQUENCE_RW_FLUSH) { sequence &= ~R3XX_FENCE_SEQUENCE_RW_FLUSH; - fence_types |= DRM_RADEON_FENCE_TYPE_RW; + fence_types |= DRM_AMD_FENCE_TYPE_R; + fence_types |= DRM_AMD_FENCE_TYPE_W; if (sequence == r3xx_fence->sequence_last_flush) { r3xx_fence->sequence_last_flush = 0; } } - /* avoid to report already reported sequence */ - if (sequence != r3xx_fence->sequence_last_reported) { - drm_fence_handler(dev, 0, sequence, fence_types, 0); - r3xx_fence->sequence_last_reported = sequence; - } + drm_fence_handler(dev, 0, sequence, fence_types, 0); + r3xx_fence->sequence_last_reported = sequence; } static void r3xx_fence_flush(struct drm_device *dev, uint32_t class) @@ -116,9 +118,10 @@ static void r3xx_fence_poll(struct drm_device *dev, uint32_t fence_class, } /* if there is a RW flush pending then submit new sequence * preceded by flush cmds */ - if (fc->pending_flush & DRM_RADEON_FENCE_TYPE_RW) { + if (fc->pending_flush & (DRM_AMD_FENCE_TYPE_R | DRM_AMD_FENCE_TYPE_W)) { r3xx_fence_flush(dev, 0); - fc->pending_flush &= ~DRM_RADEON_FENCE_TYPE_RW; + fc->pending_flush &= ~DRM_AMD_FENCE_TYPE_R; + fc->pending_flush &= ~DRM_AMD_FENCE_TYPE_W; } r3xx_fence_report(dev, dev_priv, r3xx_fence); return; @@ -137,10 +140,12 @@ static int r3xx_fence_emit(struct drm_device *dev, uint32_t class, } *sequence = tmp = r3xx_fence_sequence(r3xx_fence); *native_type = DRM_FENCE_TYPE_EXE; - if (flags & DRM_RADEON_FENCE_FLAG_FLUSHED) { - *native_type |= DRM_RADEON_FENCE_TYPE_RW; + if (flags & DRM_AMD_FENCE_FLAG_FLUSH) { + *native_type |= DRM_AMD_FENCE_TYPE_R; + *native_type |= DRM_AMD_FENCE_TYPE_W; tmp |= R3XX_FENCE_SEQUENCE_RW_FLUSH; } +DRM_INFO("%s emit fence 0x%08x\n", __func__, tmp); return r3xx_fence_emit_sequence(dev, dev_priv, tmp); } @@ -148,7 +153,8 @@ static int r3xx_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t type) { const uint32_t type_irq_mask = DRM_FENCE_TYPE_EXE | - DRM_RADEON_FENCE_TYPE_RW; + DRM_AMD_FENCE_TYPE_R | + DRM_AMD_FENCE_TYPE_W; /* * We have an irq for EXE & RW fence. */ @@ -243,7 +249,9 @@ int r3xx_fence_types(struct drm_buffer_object *bo, { *class = 0; if (bo->mem.flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) { - *type = DRM_FENCE_TYPE_EXE | DRM_RADEON_FENCE_TYPE_RW; + *type = DRM_FENCE_TYPE_EXE | + DRM_AMD_FENCE_TYPE_R | + DRM_AMD_FENCE_TYPE_W; } else { *type = DRM_FENCE_TYPE_EXE; } -- cgit v1.2.3 From 21a93915d8a21518c5da76a739f9459ed7f99d6a Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Thu, 17 Apr 2008 16:51:00 +0800 Subject: Porting DVO stuff Ported from Xorg intel 2d driver. Changed interfaces definitions, which needed to be changed later if other device wants to use these DVO stuff. --- shared-core/i915_drv.h | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index e32c36f1..80d8d462 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -685,11 +685,39 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define PPCR_ON (1<<0) #define DVOA 0x61120 -#define DVOA_ON (1<<31) #define DVOB 0x61140 -#define DVOB_ON (1<<31) #define DVOC 0x61160 -#define DVOC_ON (1<<31) +#define DVO_ENABLE (1 << 31) +#define DVO_PIPE_B_SELECT (1 << 30) +#define DVO_PIPE_STALL_UNUSED (0 << 28) +#define DVO_PIPE_STALL (1 << 28) +#define DVO_PIPE_STALL_TV (2 << 28) +#define DVO_PIPE_STALL_MASK (3 << 28) +#define DVO_USE_VGA_SYNC (1 << 15) +#define DVO_DATA_ORDER_I740 (0 << 14) +#define DVO_DATA_ORDER_FP (1 << 14) +#define DVO_VSYNC_DISABLE (1 << 11) +#define DVO_HSYNC_DISABLE (1 << 10) +#define DVO_VSYNC_TRISTATE (1 << 9) +#define DVO_HSYNC_TRISTATE (1 << 8) +#define DVO_BORDER_ENABLE (1 << 7) +#define DVO_DATA_ORDER_GBRG (1 << 6) +#define DVO_DATA_ORDER_RGGB (0 << 6) +#define DVO_DATA_ORDER_GBRG_ERRATA (0 << 6) +#define DVO_DATA_ORDER_RGGB_ERRATA (1 << 6) +#define DVO_VSYNC_ACTIVE_HIGH (1 << 4) +#define DVO_HSYNC_ACTIVE_HIGH (1 << 3) +#define DVO_BLANK_ACTIVE_HIGH (1 << 2) +#define DVO_OUTPUT_CSTATE_PIXELS (1 << 1) /* SDG only */ +#define DVO_OUTPUT_SOURCE_SIZE_PIXELS (1 << 0) /* SDG only */ +#define DVO_PRESERVE_MASK (0x7<<24) + +#define DVOA_SRCDIM 0x61124 +#define DVOB_SRCDIM 0x61144 +#define DVOC_SRCDIM 0x61164 +#define DVO_SRCDIM_HORIZONTAL_SHIFT 12 +#define DVO_SRCDIM_VERTICAL_SHIFT 0 + #define LVDS 0x61180 #define LVDS_ON (1<<31) -- cgit v1.2.3 From 8a390e058fcea70b0c3a912543816bdf4c3e7c4c Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Fri, 18 Apr 2008 16:49:23 +0800 Subject: clear interrupt status before install irq On my 865G machine, it seems the CPU will receive interrupt before irq_postinstall is called. This will cause kernel oops because vblank is not inited at that time. Clear interrupt status before install seems fixing this problem. Signed-off-by: Hong Liu --- shared-core/i915_irq.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'shared-core') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 8f136c8f..422e81ed 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -1217,14 +1217,25 @@ int i915_vblank_swap(struct drm_device *dev, void *data, void i915_driver_irq_preinstall(struct drm_device * dev) { struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; + u32 tmp; + + tmp = I915_READ(I915REG_PIPEASTAT); + I915_WRITE(I915REG_PIPEASTAT, tmp); + tmp = I915_READ(I915REG_PIPEBSTAT); + I915_WRITE(I915REG_PIPEBSTAT, tmp); + I915_WRITE16(I915REG_HWSTAM, 0xeffe); if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { I915_WRITE(I915REG_INT_MASK_R, 0x0); I915_WRITE(I915REG_INT_ENABLE_R, 0x0); + tmp = I915_READ(I915REG_INT_IDENTITY_R); + I915_WRITE(I915REG_INT_IDENTITY_R, tmp); } else { I915_WRITE16(I915REG_INT_MASK_R, 0x0); I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); + tmp = I915_READ16(I915REG_INT_IDENTITY_R); + I915_WRITE16(I915REG_INT_IDENTITY_R, tmp); } } -- cgit v1.2.3 From 8dc4d4fa1f1394c2faed89760e1183287577fed3 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 22 Apr 2008 18:41:28 -0700 Subject: i915: allocate devname at init time Since it'll be freed at unload time, we should alloc devname rather than pointing to the DRIVER_NAME string. --- shared-core/i915_init.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index ce6f1656..53574eb7 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -265,7 +265,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) drm_mm_print(&dev->bm.man[DRM_BO_MEM_VRAM].manager, "VRAM"); drm_mm_print(&dev->bm.man[DRM_BO_MEM_TT].manager, "TT"); - dev->devname = DRIVER_NAME; + dev->devname = kstrdup(DRIVER_NAME, GFP_KERNEL); + if (!dev->devname) + return -ENOMEM; + drm_irq_install(dev); } -- cgit v1.2.3 From 33fa02f2d850da252d5ddd9ef7428b02de7bd6a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 23 Apr 2008 12:42:26 -0400 Subject: Make radeon_ms compile. Remove lock functions and use pci_map_rom() instead of pci_map_rom_copy(). --- shared-core/radeon_ms_crtc.c | 11 ----------- shared-core/radeon_ms_rom.c | 4 ++-- 2 files changed, 2 insertions(+), 13 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_ms_crtc.c b/shared-core/radeon_ms_crtc.c index 3586e019..d73275bb 100644 --- a/shared-core/radeon_ms_crtc.c +++ b/shared-core/radeon_ms_crtc.c @@ -715,21 +715,10 @@ static void radeon_ms_crtc_load_lut(struct drm_crtc *crtc) } } -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, diff --git a/shared-core/radeon_ms_rom.c b/shared-core/radeon_ms_rom.c index 5054a390..b4db02be 100644 --- a/shared-core/radeon_ms_rom.c +++ b/shared-core/radeon_ms_rom.c @@ -48,8 +48,8 @@ int radeon_ms_rom_init(struct drm_device *dev) 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_mapped = pci_map_rom(dev->pdev, &rom->rom_size); + if (rom_mapped && rom->rom_size) { rom->rom_image = drm_alloc(rom->rom_size, DRM_MEM_DRIVER); if (rom->rom_image == NULL) { return -1; -- cgit v1.2.3 From ed072ed075ec431b0746ac1aa8bad5f687d75d8c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 8 May 2008 14:01:24 +1000 Subject: drm_mode: initial replacefb implemenation --- shared-core/drm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index c847b4ef..eb2033c7 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1276,6 +1276,7 @@ struct drm_mode_hotplug { #define DRM_IOCTL_MODE_HOTPLUG DRM_IOWR(0xAD, struct drm_mode_hotplug) #define DRM_IOCTL_WAIT_HOTPLUG DRM_IOWR(0xAE, union drm_wait_hotplug) +#define DRM_IOCTL_MODE_REPLACEFB DRM_IOWR(0xAF, struct drm_mode_fb_cmd) /*@}*/ /** -- cgit v1.2.3 From 2a78ad22647933aa8842d534bce6495ff93fbf76 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 8 May 2008 16:14:33 +1000 Subject: i915: fix vbl swap for multi-master patch from F9 tree --- shared-core/i915_irq.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 0ee0c444..ea2c88a1 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -198,9 +198,6 @@ static void i915_vblank_tasklet(struct drm_device *dev) if ((counter[pipe] - vbl_swap->sequence) > (1<<23)) continue; - master_priv = vbl_swap->minor->master->driver_priv; - sarea_priv = master_priv->sarea_priv; - list_del(list); dev_priv->swaps_pending--; drm_vblank_put(dev, pipe); @@ -249,16 +246,6 @@ static void i915_vblank_tasklet(struct drm_device *dev) i915_kernel_lost_context(dev); - upper[0] = upper[1] = 0; - slice[0] = max(sarea_priv->planeA_h / nhits, 1); - slice[1] = max(sarea_priv->planeB_h / nhits, 1); - lower[0] = sarea_priv->planeA_y + slice[0]; - lower[1] = sarea_priv->planeB_y + slice[0]; - - offsets[0] = sarea_priv->front_offset; - offsets[1] = sarea_priv->back_offset; - offsets[2] = sarea_priv->third_offset; - num_pages = sarea_priv->third_handle ? 3 : 2; DRM_SPINLOCK(&dev->drw_lock); @@ -272,8 +259,6 @@ static void i915_vblank_tasklet(struct drm_device *dev) upper[1] = lower[1], lower[1] += slice[1]) { int init_drawrect = 1; - if (i == nhits) - lower[0] = lower[1] = sarea_priv->height; list_for_each(hit, &hits) { struct drm_i915_vbl_swap *swap_hit = @@ -282,6 +267,24 @@ static void i915_vblank_tasklet(struct drm_device *dev) int num_rects, plane, front, back; unsigned short top, bottom; + sarea_priv = master_priv->sarea_priv; + + upper[0] = upper[1] = 0; + slice[0] = max(sarea_priv->planeA_h / nhits, 1); + slice[1] = max(sarea_priv->planeB_h / nhits, 1); + lower[0] = sarea_priv->planeA_y + slice[0]; + lower[1] = sarea_priv->planeB_y + slice[0]; + + offsets[0] = sarea_priv->front_offset; + offsets[1] = sarea_priv->back_offset; + offsets[2] = sarea_priv->third_offset; + num_pages = sarea_priv->third_handle ? 3 : 2; + if (i == nhits) + lower[0] = lower[1] = sarea_priv->height; + + pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) | + (cpp << 23) | (1 << 24); + drw = drm_get_drawable_info(dev, swap_hit->drw_id); if (!drw) @@ -294,6 +297,8 @@ static void i915_vblank_tasklet(struct drm_device *dev) continue; } + master_priv = swap_hit->minor->master->driver_priv; + if (init_drawrect) { int width = sarea_priv->width; int height = sarea_priv->height; @@ -332,6 +337,8 @@ static void i915_vblank_tasklet(struct drm_device *dev) (2 * plane)) & 0x3; back = (front + 1) % num_pages; + + for (num_rects = drw->num_rects; num_rects--; rect++) { int y1 = max(rect->y1, top); int y2 = min(rect->y2, bottom); -- cgit v1.2.3 From 4466fea7bab2af5c1e25947af474d0ae69df1ffd Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 8 May 2008 17:12:16 +1000 Subject: Revert "i915: fix vbl swap for multi-master" This reverts commit 2a78ad22647933aa8842d534bce6495ff93fbf76. --- shared-core/i915_irq.c | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index ea2c88a1..0ee0c444 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -198,6 +198,9 @@ static void i915_vblank_tasklet(struct drm_device *dev) if ((counter[pipe] - vbl_swap->sequence) > (1<<23)) continue; + master_priv = vbl_swap->minor->master->driver_priv; + sarea_priv = master_priv->sarea_priv; + list_del(list); dev_priv->swaps_pending--; drm_vblank_put(dev, pipe); @@ -246,6 +249,16 @@ static void i915_vblank_tasklet(struct drm_device *dev) i915_kernel_lost_context(dev); + upper[0] = upper[1] = 0; + slice[0] = max(sarea_priv->planeA_h / nhits, 1); + slice[1] = max(sarea_priv->planeB_h / nhits, 1); + lower[0] = sarea_priv->planeA_y + slice[0]; + lower[1] = sarea_priv->planeB_y + slice[0]; + + offsets[0] = sarea_priv->front_offset; + offsets[1] = sarea_priv->back_offset; + offsets[2] = sarea_priv->third_offset; + num_pages = sarea_priv->third_handle ? 3 : 2; DRM_SPINLOCK(&dev->drw_lock); @@ -259,6 +272,8 @@ static void i915_vblank_tasklet(struct drm_device *dev) upper[1] = lower[1], lower[1] += slice[1]) { int init_drawrect = 1; + if (i == nhits) + lower[0] = lower[1] = sarea_priv->height; list_for_each(hit, &hits) { struct drm_i915_vbl_swap *swap_hit = @@ -267,24 +282,6 @@ static void i915_vblank_tasklet(struct drm_device *dev) int num_rects, plane, front, back; unsigned short top, bottom; - sarea_priv = master_priv->sarea_priv; - - upper[0] = upper[1] = 0; - slice[0] = max(sarea_priv->planeA_h / nhits, 1); - slice[1] = max(sarea_priv->planeB_h / nhits, 1); - lower[0] = sarea_priv->planeA_y + slice[0]; - lower[1] = sarea_priv->planeB_y + slice[0]; - - offsets[0] = sarea_priv->front_offset; - offsets[1] = sarea_priv->back_offset; - offsets[2] = sarea_priv->third_offset; - num_pages = sarea_priv->third_handle ? 3 : 2; - if (i == nhits) - lower[0] = lower[1] = sarea_priv->height; - - pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) | - (cpp << 23) | (1 << 24); - drw = drm_get_drawable_info(dev, swap_hit->drw_id); if (!drw) @@ -297,8 +294,6 @@ static void i915_vblank_tasklet(struct drm_device *dev) continue; } - master_priv = swap_hit->minor->master->driver_priv; - if (init_drawrect) { int width = sarea_priv->width; int height = sarea_priv->height; @@ -337,8 +332,6 @@ static void i915_vblank_tasklet(struct drm_device *dev) (2 * plane)) & 0x3; back = (front + 1) % num_pages; - - for (num_rects = drw->num_rects; num_rects--; rect++) { int y1 = max(rect->y1, top); int y2 = min(rect->y2, bottom); -- cgit v1.2.3 From 7bcbc443f4f5161ab1e1a11cb6694e6d6269377c Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 8 May 2008 20:10:18 +0200 Subject: i915: Changed intel_fb to use the new drm_crtc_set_config interface --- shared-core/radeon_ms.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h index dd34683e..1fdcd0a1 100644 --- a/shared-core/radeon_ms.h +++ b/shared-core/radeon_ms.h @@ -435,7 +435,7 @@ int r3xx_fence_types(struct drm_buffer_object *bo, uint32_t * class, uint32_t * type); /* radeon_ms_fb.c */ -int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc); +int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output); int radeonfb_remove(struct drm_device *dev, struct drm_crtc *crtc); /* radeon_ms_gpu.c */ -- cgit v1.2.3 From 12725a37af691345e74fe22d53300abec2581852 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 9 May 2008 14:19:00 -0700 Subject: i915: add basic VBT support Map the VBIOS (and therefore VBT) at init time for use by various output initialization routines. --- shared-core/i915_drv.h | 6 ++++++ shared-core/i915_init.c | 7 +++++++ 2 files changed, 13 insertions(+) (limited to 'shared-core') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index a7040f5b..2e7b6bd2 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -33,6 +33,8 @@ /* General customization: */ +#include "intel_bios.h" + #define DRIVER_AUTHOR "Tungsten Graphics, Inc." #define DRIVER_NAME "i915" @@ -171,6 +173,10 @@ struct drm_i915_private { struct drm_buffer_object *sarea_bo; struct drm_bo_kmap_obj sarea_kmap; + /* BIOS data */ + struct vbt_header *vbt; + struct bdb_header *bdb; + /* Register state */ u8 saveLBB; u32 saveDSPACNTR; diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 53574eb7..8824b959 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -12,6 +12,7 @@ #include "drm_sarea.h" #include "i915_drm.h" #include "i915_drv.h" +#include "intel_bios.h" /** * i915_probe_agp - get AGP bootup configuration @@ -259,6 +260,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) DRM_DEBUG("Error\n"); } + ret = intel_find_bios(dev); + if (ret) { + DRM_ERROR("failed to find VBT\n"); + return -ENODEV; + } + intel_modeset_init(dev); drm_initial_config(dev, false); -- cgit v1.2.3 From dce34421947d1828ff76c001281107e937e307d4 Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Fri, 9 May 2008 10:08:36 +0800 Subject: fixup i915 workqueue handling when modeset=1 Fixup workqueue creation error handling and make sure we destroy the queue on unload. --- shared-core/i915_init.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 8824b959..b9e7e17b 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -256,7 +256,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) DRM_DEBUG("Enabled hardware status page\n"); dev_priv->wq = create_singlethread_workqueue("i915"); - if (dev_priv == 0) { + if (dev_priv->wq == 0) { DRM_DEBUG("Error\n"); } @@ -291,6 +291,7 @@ int i915_driver_unload(struct drm_device *dev) if (drm_core_check_feature(dev, DRIVER_MODESET)) { drm_irq_uninstall(dev); intel_modeset_cleanup(dev); + destroy_workqueue(dev_priv->wq); } #if 0 -- cgit v1.2.3 From 3f66a0005c1273b0fc935b9bd62a6fabaf99c2be Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 12 May 2008 16:29:13 +1000 Subject: drm: remove root only from a lot of drm ioctls to get stuff running as non-root --- shared-core/i915_dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index f3a963b1..fc9e0e49 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1026,14 +1026,14 @@ static int i915_set_status_page(struct drm_device *dev, void *data, } 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_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER), DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_FLIP, i915_flip_bufs, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_GETPARAM, i915_getparam, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER), DRM_IOCTL_DEF(DRM_I915_ALLOC, i915_mem_alloc, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_FREE, i915_mem_free, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), -- cgit v1.2.3 From af60d87869303d7f17352c82d2fb1cebb9a8f7ff Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Mon, 12 May 2008 14:38:49 +0800 Subject: fix G33 hardware status page in modeset We need to alloc a hw status page bo for G33 if modeset is enabled since the 2D driver can't alloc gfx memory when working in drm modeset. --- shared-core/i915_dma.c | 4 ++++ shared-core/i915_drv.h | 1 + shared-core/i915_init.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index fc9e0e49..9bec85a1 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -997,6 +997,10 @@ static int i915_set_status_page(struct drm_device *dev, void *data, DRM_ERROR("called with no initialization\n"); return -EINVAL; } + + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr); dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 2e7b6bd2..10e08c55 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -124,6 +124,7 @@ struct drm_i915_private { uint32_t counter; unsigned int status_gfx_addr; drm_local_map_t hws_map; + struct drm_buffer_object *hws_bo; unsigned int cpp; int use_mi_batchbuffer_start; diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index b9e7e17b..7183f81f 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -252,6 +252,38 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) memset(dev_priv->hw_status_page, 0, PAGE_SIZE); I915_WRITE(I915REG_HWS_PGA, dev_priv->dma_status_page); + } else { + size = 4 * 1024; + 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->hws_bo); + if (ret < 0) { + DRM_ERROR("Unable to allocate or pin ring buffer\n"); + return -EINVAL; + } + dev_priv->status_gfx_addr = + dev_priv->hws_bo->offset & (0x1ffff << 12); + dev_priv->hws_map.offset = dev->agp->base + + dev_priv->hws_bo->offset; + dev_priv->hws_map.size = size; + dev_priv->hws_map.type = 0; + dev_priv->hws_map.flags = 0; + dev_priv->hws_map.mtrr = 0; + + drm_core_ioremap(&dev_priv->hws_map, dev); + if (dev_priv->hws_map.handle == NULL) { + dev_priv->status_gfx_addr = 0; + DRM_ERROR("can not ioremap virtual addr" + " for G33 hw status page\n"); + return -ENOMEM; + } + dev_priv->hw_status_page = dev_priv->hws_map.handle; + memset(dev_priv->hw_status_page, 0, size); + I915_WRITE(I915REG_HWS_PGA, dev_priv->status_gfx_addr); } DRM_DEBUG("Enabled hardware status page\n"); @@ -324,6 +356,7 @@ int i915_driver_unload(struct drm_device *dev) if (dev_priv->status_gfx_addr) { dev_priv->status_gfx_addr = 0; drm_core_ioremapfree(&dev_priv->hws_map, dev); + drm_bo_usage_deref_unlocked(&dev_priv->hws_bo); I915_WRITE(I915REG_HWS_PGA, 0x1ffff000); } -- cgit v1.2.3 From f1b9bbe2b8f2339359afa39bf27702eca6f6c975 Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Mon, 12 May 2008 16:14:38 +0800 Subject: modeset init code cleanup moving modeset init code into one function and correct error handling druing i915 init --- shared-core/i915_init.c | 331 ++++++++++++++++++++++++++++-------------------- 1 file changed, 197 insertions(+), 134 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 7183f81f..22577c7f 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -99,6 +99,181 @@ int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size, return 0; } +int i915_load_modeset_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long agp_size, prealloc_size; + int size, ret = 0; + + 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"); + goto clean_mm; + } + + /* 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); + goto destroy_ringbuffer; + } + + 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) { + DRM_ERROR("Can not allocate hardware status page\n"); + ret = -ENOMEM; + goto destroy_ringbuffer; + } + 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); + } else { + size = 4 * 1024; + 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->hws_bo); + if (ret < 0) { + DRM_ERROR("Unable to allocate or pin hw status page\n"); + ret = -EINVAL; + goto destroy_ringbuffer; + } + + dev_priv->status_gfx_addr = + dev_priv->hws_bo->offset & (0x1ffff << 12); + dev_priv->hws_map.offset = dev->agp->base + + dev_priv->hws_bo->offset; + dev_priv->hws_map.size = size; + dev_priv->hws_map.type= 0; + dev_priv->hws_map.flags= 0; + dev_priv->hws_map.mtrr = 0; + + drm_core_ioremap(&dev_priv->hws_map, dev); + if (dev_priv->hws_map.handle == NULL) { + dev_priv->status_gfx_addr = 0; + DRM_ERROR("can not ioremap virtual addr for" + "G33 hw status page\n"); + ret = -ENOMEM; + goto destroy_hws; + } + dev_priv->hw_status_page = dev_priv->hws_map.handle; + memset(dev_priv->hw_status_page, 0, PAGE_SIZE); + I915_WRITE(I915REG_HWS_PGA, dev_priv->status_gfx_addr); + } + DRM_DEBUG("Enabled hardware status page\n"); + + dev_priv->wq = create_singlethread_workqueue("i915"); + if (dev_priv->wq == 0) { + DRM_DEBUG("Error\n"); + ret = -EINVAL; + goto destroy_hws; + } + + ret = intel_find_bios(dev); + if (ret) { + DRM_ERROR("failed to find VBT\n"); + ret = -ENODEV; + goto destroy_wq; + } + + 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"); + + dev->devname = kstrdup(DRIVER_NAME, GFP_KERNEL); + if (!dev->devname) { + ret = -ENOMEM; + goto modeset_cleanup; + } + + ret = drm_irq_install(dev); + if (ret) { + kfree(dev->devname); + goto modeset_cleanup; + } + return 0; + +modeset_cleanup: + intel_modeset_cleanup(dev); +destroy_wq: + destroy_workqueue(dev_priv->wq); +destroy_hws: + if (!IS_G33(dev)) { + if (dev_priv->status_page_dmah) + drm_pci_free(dev, dev_priv->status_page_dmah); + } else { + if (dev_priv->hws_map.handle) + drm_core_ioremapfree(&dev_priv->hws_map, dev); + if (dev_priv->hws_bo) + drm_bo_usage_deref_unlocked(&dev_priv->hws_bo); + } + I915_WRITE(I915REG_HWS_PGA, 0x1ffff000); +destroy_ringbuffer: + if (dev_priv->ring.virtual_start) + drm_mem_reg_iounmap(dev, &dev_priv->ring_buffer->mem, + dev_priv->ring.virtual_start); + if (dev_priv->ring_buffer) + drm_bo_usage_deref_unlocked(&dev_priv->ring_buffer); +clean_mm: + drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM, 1); + drm_bo_clean_mm(dev, DRM_BO_MEM_TT, 1); + return ret; +} + /** * i915_driver_load - setup chip and create an initial config * @dev: DRM device @@ -113,8 +288,7 @@ int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size, 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; + int ret = 0; dev_priv = drm_alloc(sizeof(struct drm_i915_private), DRM_MEM_DRIVER); if (dev_priv == NULL) @@ -156,16 +330,18 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) drm_get_resource_start(dev, 0) & 0xff000000; } else { DRM_ERROR("Unable to find MMIO registers\n"); - return -ENODEV; + ret = -ENODEV; + goto free_priv; } 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_KERNEL|_DRM_READ_ONLY|_DRM_DRIVER, &dev_priv->mmio_map); + _DRM_REGISTERS, _DRM_KERNEL|_DRM_READ_ONLY|_DRM_DRIVER, + &dev_priv->mmio_map); if (ret != 0) { DRM_ERROR("Cannot add mapping for MMIO registers\n"); - return ret; + goto free_priv; } #ifdef __linux__ @@ -177,141 +353,28 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) /* * Initialize the memory manager for local and AGP space */ - drm_bo_driver_init(dev); + ret = drm_bo_driver_init(dev); + if (ret) { + DRM_ERROR("fail to init memory manager for local & AGP space\n"); + goto out_rmmap; + } if (drm_core_check_feature(dev, DRIVER_MODESET)) { - 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); + ret = i915_load_modeset_init(dev); if (ret < 0) { - DRM_ERROR("Unable to allocate or pin ring buffer\n"); - return -EINVAL; + DRM_ERROR("failed to init modeset\n"); + goto driver_fini; } - - /* 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); - } else { - size = 4 * 1024; - 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->hws_bo); - if (ret < 0) { - DRM_ERROR("Unable to allocate or pin ring buffer\n"); - return -EINVAL; - } - dev_priv->status_gfx_addr = - dev_priv->hws_bo->offset & (0x1ffff << 12); - dev_priv->hws_map.offset = dev->agp->base + - dev_priv->hws_bo->offset; - dev_priv->hws_map.size = size; - dev_priv->hws_map.type = 0; - dev_priv->hws_map.flags = 0; - dev_priv->hws_map.mtrr = 0; - - drm_core_ioremap(&dev_priv->hws_map, dev); - if (dev_priv->hws_map.handle == NULL) { - dev_priv->status_gfx_addr = 0; - DRM_ERROR("can not ioremap virtual addr" - " for G33 hw status page\n"); - return -ENOMEM; - } - dev_priv->hw_status_page = dev_priv->hws_map.handle; - memset(dev_priv->hw_status_page, 0, size); - I915_WRITE(I915REG_HWS_PGA, dev_priv->status_gfx_addr); - } - DRM_DEBUG("Enabled hardware status page\n"); - - dev_priv->wq = create_singlethread_workqueue("i915"); - if (dev_priv->wq == 0) { - DRM_DEBUG("Error\n"); - } - - ret = intel_find_bios(dev); - if (ret) { - DRM_ERROR("failed to find VBT\n"); - return -ENODEV; - } - - 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"); - - dev->devname = kstrdup(DRIVER_NAME, GFP_KERNEL); - if (!dev->devname) - return -ENOMEM; - - drm_irq_install(dev); } - return 0; + +driver_fini: + drm_bo_driver_finish(dev); +out_rmmap: + drm_rmmap(dev, dev_priv->mmio_map); +free_priv: + drm_free(dev_priv, sizeof(struct drm_i915_private), DRM_MEM_DRIVER); + return ret; } int i915_driver_unload(struct drm_device *dev) -- cgit v1.2.3 From a51e38548cfdece2978e9b5f0d6f0467ba7a7272 Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Fri, 9 May 2008 10:06:17 +0800 Subject: fix kernel oops when removing fb drm_crtc->fb may point to NULL, f.e X server will allocate a new fb and assign it to the CRTC at startup, when X server exits, it will destroy the allocated fb, making drm_crtc->fb points to NULL. --- shared-core/radeon_ms.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h index 1fdcd0a1..f3bbc9a3 100644 --- a/shared-core/radeon_ms.h +++ b/shared-core/radeon_ms.h @@ -436,7 +436,7 @@ int r3xx_fence_types(struct drm_buffer_object *bo, /* radeon_ms_fb.c */ int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output); -int radeonfb_remove(struct drm_device *dev, struct drm_crtc *crtc); +int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb); /* radeon_ms_gpu.c */ int radeon_ms_gpu_initialize(struct drm_device *dev); -- cgit v1.2.3 From d32ce7f621c0d8e42cdf88ce6f1d15638a3d34b7 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 12 May 2008 15:47:19 -0700 Subject: i915: TV hotplug fixes In order to avoid recursive ->detect->interrupt->detect->interrupt->... we need to disable TV hotplug interrupts in intel_tv.c:intel_tv_detect_type. We also need to enable the TV interrupt detection and hotplug sequence properly in i915_irq.c. --- shared-core/i915_irq.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 0ee0c444..4aef568e 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -471,7 +471,6 @@ static void i915_hotplug_tv(struct drm_device *dev) if (iout == 0) goto unlock; - /* may need to I915_WRITE(TVDAC, 1<<31) to ack the interrupt */ status = output->funcs->detect(output); drm_hotplug_stage_two(dev, output, status == output_status_connected ? 1 : 0); @@ -631,7 +630,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) struct drm_i915_master_private *master_priv; struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; u32 iir; - u32 pipea_stats, pipeb_stats; + u32 pipea_stats = 0, pipeb_stats, tvdac; int hotplug = 0; int vblank = 0; @@ -672,10 +671,17 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) } /* This is a global event, and not a pipe A event */ - if ((pipea_stats & I915_HOTPLUG_INTERRUPT_STATUS) || - (pipea_stats & I915_HOTPLUG_TV_INTERRUPT_STATUS)) + if (pipea_stats & I915_HOTPLUG_INTERRUPT_STATUS) hotplug = 1; + if (pipea_stats & I915_HOTPLUG_TV_INTERRUPT_STATUS) { + hotplug = 1; + /* Toggle hotplug detection to clear hotplug status */ + tvdac = I915_READ(TV_DAC); + I915_WRITE(TV_DAC, tvdac & ~TVDAC_STATE_CHG_EN); + I915_WRITE(TV_DAC, tvdac | TVDAC_STATE_CHG_EN); + } + I915_WRITE(I915REG_PIPEASTAT, pipea_stats); } @@ -1001,6 +1007,9 @@ void i915_enable_interrupt (struct drm_device *dev) I915_WRITE(SDVOB, I915_READ(SDVOB) | SDVO_INTERRUPT_ENABLE); I915_WRITE(SDVOC, I915_READ(SDVOC) | SDVO_INTERRUPT_ENABLE); + + /* TV */ + I915_WRITE(TV_DAC, I915_READ(TV_DAC) | TVDAC_STATE_CHG_EN); } else { /* DVO ???? */ } -- cgit v1.2.3 From 5be53a0881c5248146c585015bf60bb2958773af Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 13 May 2008 09:24:47 +0200 Subject: i915: execbuf now works without i915_dma_init being called --- shared-core/i915_dma.c | 9 +++++++-- shared-core/i915_init.c | 4 ++++ 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 9bec85a1..498620f5 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -197,7 +197,9 @@ static int i915_initialize(struct drm_device * dev, #ifdef I915_HAVE_BUFFER - dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS; + if (!drm_core_check_feature(dev, DRIVER_MODESET)) { + dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS; + } #endif if (!dev_priv->ring.Size) { @@ -260,8 +262,11 @@ static int i915_initialize(struct drm_device * dev, I915_WRITE(0x02080, dev_priv->dma_status_page); } DRM_DEBUG("Enabled hardware status page\n"); + #ifdef I915_HAVE_BUFFER - mutex_init(&dev_priv->cmdbuf_mutex); + if (!drm_core_check_feature(dev, DRIVER_MODESET)) { + mutex_init(&dev_priv->cmdbuf_mutex); + } #endif if (init->func == I915_INIT_DMA2) { diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 22577c7f..c0ca226a 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -155,10 +155,14 @@ int i915_load_modeset_init(struct drm_device *dev) * private backbuffer/depthbuffer usage. */ dev_priv->use_mi_batchbuffer_start = 0; + if (IS_I965G(dev)) /* 965 doesn't support older method */ + dev_priv->use_mi_batchbuffer_start = 1; /* Allow hardware batchbuffers unless told otherwise. */ dev_priv->allow_batchbuffer = 1; + dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS; + mutex_init(&dev_priv->cmdbuf_mutex); /* Program Hardware Status Page */ if (!IS_G33(dev)) { -- cgit v1.2.3 From ee631e1b8604a176b9118396998ce5bfc6475dae Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 13 May 2008 14:44:17 -0700 Subject: i915: register definition & header file cleanup It would be nice if one day the DRM driver was the canonical source for register definitions and core macros. To that end, this patch cleans things up quite a bit, removing redundant definitions (some with different names referring to the same register) and generally tidying up the header file. --- shared-core/i915_dma.c | 14 +- shared-core/i915_drv.h | 1531 +++++++++++++++++++---------------------------- shared-core/i915_init.c | 25 +- shared-core/i915_irq.c | 160 ++--- 4 files changed, 720 insertions(+), 1010 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 9bec85a1..e1417388 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -40,11 +40,11 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller) { 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; + u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR; int i; for (i = 0; i < 10000; i++) { - ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; + ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) ring->space += ring->Size; @@ -71,8 +71,8 @@ void i915_kernel_lost_context(struct drm_device * dev) if (drm_core_check_feature(dev, DRIVER_MODESET)) return; - ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR; + ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; + ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) ring->space += ring->Size; @@ -510,7 +510,7 @@ void i915_emit_breadcrumb(struct drm_device *dev) master_priv->sarea_priv->last_enqueue = dev_priv->counter; BEGIN_LP_RING(4); - OUT_RING(CMD_STORE_DWORD_IDX); + OUT_RING(MI_STORE_DWORD_INDEX); OUT_RING(20); OUT_RING(dev_priv->counter); OUT_RING(0); @@ -521,7 +521,7 @@ void i915_emit_breadcrumb(struct drm_device *dev) int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush) { struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t flush_cmd = CMD_MI_FLUSH; + uint32_t flush_cmd = MI_FLUSH; RING_LOCALS; flush_cmd |= flush; @@ -1022,7 +1022,7 @@ 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(I915REG_HWS_PGA, dev_priv->status_gfx_addr); + I915_WRITE(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); diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 10e08c55..84cc60f3 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -69,6 +69,11 @@ #endif #define DRIVER_PATCHLEVEL 0 +enum pipe { + PIPE_A = 0, + PIPE_B, +}; + #ifdef I915_HAVE_BUFFER #define I915_MAX_VALIDATE_BUFFERS 4096 struct drm_i915_validate_buffer; @@ -202,7 +207,7 @@ struct drm_i915_private { u32 saveDSPASTRIDE; u32 saveDSPASIZE; u32 saveDSPAPOS; - u32 saveDSPABASE; + u32 saveDSPAADDR; u32 saveDSPASURF; u32 saveDSPATILEOFF; u32 savePFIT_PGM_RATIOS; @@ -223,24 +228,24 @@ struct drm_i915_private { u32 saveDSPBSTRIDE; u32 saveDSPBSIZE; u32 saveDSPBPOS; - u32 saveDSPBBASE; + u32 saveDSPBADDR; u32 saveDSPBSURF; u32 saveDSPBTILEOFF; - u32 saveVCLK_DIVISOR_VGA0; - u32 saveVCLK_DIVISOR_VGA1; - u32 saveVCLK_POST_DIV; + u32 saveVGA0; + u32 saveVGA1; + u32 saveVGA_PD; u32 saveVGACNTRL; u32 saveADPA; u32 saveLVDS; - u32 saveLVDSPP_ON; - u32 saveLVDSPP_OFF; + u32 savePP_ON_DELAYS; + u32 savePP_OFF_DELAYS; u32 saveDVOA; u32 saveDVOB; u32 saveDVOC; u32 savePP_ON; u32 savePP_OFF; u32 savePP_CONTROL; - u32 savePP_CYCLE; + u32 savePP_DIVISOR; u32 savePFIT_CONTROL; u32 save_palette_a[256]; u32 save_palette_b[256]; @@ -253,7 +258,7 @@ struct drm_i915_private { u32 saveIMR; u32 saveCACHE_MODE_0; u32 saveD_STATE; - u32 saveDSPCLK_GATE_D; + u32 saveCG_2D_DIS; u32 saveMI_ARB_STATE; u32 saveSWF0[16]; u32 saveSWF1[16]; @@ -382,6 +387,8 @@ extern void intel_modeset_cleanup(struct drm_device *dev); #define I915_VERBOSE 0 +#define PRIMARY_RINGBUFFER_SIZE (128*1024) + #define RING_LOCALS unsigned int outring, ringmask, outcount; \ volatile char *virt; @@ -409,10 +416,14 @@ extern void intel_modeset_cleanup(struct drm_device *dev); if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \ dev_priv->ring.tail = outring; \ dev_priv->ring.space -= outcount * 4; \ - I915_WRITE(LP_RING + RING_TAIL, outring); \ + I915_WRITE(PRB0_TAIL, outring); \ } while(0) -#define MI_NOOP (0x00 << 23) +#define BREADCRUMB_BITS 31 +#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1) + +#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5]) +#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); @@ -437,8 +448,20 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define INTEL_915G_GMCH_GMS_STOLEN_48M (0x6 << 4) #define INTEL_915G_GMCH_GMS_STOLEN_64M (0x7 << 4) -/* Extended config space */ -#define LBB 0xf4 +/* PCI config space */ + +#define HPLLCC 0xc0 /* 855 only */ +#define GC_CLOCK_CONTROL_MASK (3 << 0) +#define GC_CLOCK_133_200 (0 << 0) +#define GC_CLOCK_100_200 (1 << 0) +#define GC_CLOCK_100_133 (2 << 0) +#define GC_CLOCK_166_250 (3 << 0) +#define GCFGC 0xf0 /* 915+ only */ +#define GC_LOW_FREQUENCY_ENABLE (1 << 7) +#define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4) +#define GC_DISPLAY_CLOCK_333_MHZ (4 << 4) +#define GC_DISPLAY_CLOCK_MASK (7 << 4) +#define LBB 0xf4 /* VGA stuff */ @@ -481,32 +504,146 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define VGA_CR_INDEX_CGA 0x3d4 #define VGA_CR_DATA_CGA 0x3d5 -#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) -#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) -#define CMD_REPORT_HEAD (7<<23) -#define CMD_STORE_DWORD_IMM ((0x20<<23) | (0x1 << 22) | 0x1) -#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) -#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) - -#define CMD_MI_FLUSH (0x04 << 23) -#define MI_NO_WRITE_FLUSH (1 << 2) -#define MI_READ_FLUSH (1 << 0) -#define MI_EXE_FLUSH (1 << 1) -#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ -#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ - -/* Packet to load a register value from the ring/batch command stream: +/* + * Memory interface instructions used by the kernel + */ +#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags)) + +#define MI_NOOP MI_INSTR(0, 0) +#define MI_USER_INTERRUPT MI_INSTR(0x02, 0) +#define MI_WAIT_FOR_EVENT MI_INSTR(0x03, 0) +#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) +#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) +#define MI_FLUSH MI_INSTR(0x04, 0) +#define MI_READ_FLUSH (1 << 0) +#define MI_EXE_FLUSH (1 << 1) +#define MI_NO_WRITE_FLUSH (1 << 2) +#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ +#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ +#define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0) +#define MI_REPORT_HEAD MI_INSTR(0x07, 0) +#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0) +#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) /* used to have 1<<22? */ +#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) +#define MI_LOAD_REGISTER_IMM MI_INSTR(0x22, 1) +#define MI_BATCH_BUFFER MI_INSTR(0x30, 1) +#define MI_BATCH_NON_SECURE (1) +#define MI_BATCH_NON_SECURE_I965 (1<<8) +#define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0) + +/* + * 3D instructions used by the kernel */ -#define CMD_MI_LOAD_REGISTER_IMM ((0x22 << 23)|0x1) +#define GFX_INSTR(opcode, flags) ((0x3 << 29) | ((opcode) << 24) | (flags)) -#define BB1_START_ADDR_MASK (~0x7) -#define BB1_PROTECTED (1<<0) -#define BB1_UNPROTECTED (0<<0) -#define BB2_END_ADDR_MASK (~0x7) +#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24)) +#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) +#define SC_UPDATE_SCISSOR (0x1<<1) +#define SC_ENABLE_MASK (0x1<<0) +#define SC_ENABLE (0x1<<0) +#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16)) +#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) +#define SCI_YMIN_MASK (0xffff<<16) +#define SCI_XMIN_MASK (0xffff<<0) +#define SCI_YMAX_MASK (0xffff<<16) +#define SCI_XMAX_MASK (0xffff<<0) +#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19)) +#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1) +#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0) +#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4) +#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0) +#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) +#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2) +#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 XY_SRC_COPY_BLT_SRC_TILED (1<<15) +#define XY_SRC_COPY_BLT_DST_TILED (1<<11) +#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2) +#define ASYNC_FLIP (1<<22) +#define DISPLAY_PLANE_A (0<<20) +#define DISPLAY_PLANE_B (1<<20) -#define I915REG_HWS_PGA 0x02080 +/* + * Instruction and interrupt control regs + */ + +#define PRB0_TAIL 0x02030 +#define PRB0_HEAD 0x02034 +#define PRB0_START 0x02038 +#define PRB0_CTL 0x0203c +#define TAIL_ADDR 0x001FFFF8 +#define HEAD_WRAP_COUNT 0xFFE00000 +#define HEAD_WRAP_ONE 0x00200000 +#define HEAD_ADDR 0x001FFFFC +#define START_ADDR 0x0xFFFFF000 +#define RING_NR_PAGES 0x001FF000 +#define RING_REPORT_MASK 0x00000006 +#define RING_REPORT_64K 0x00000002 +#define RING_REPORT_128K 0x00000004 +#define RING_NO_REPORT 0x00000000 +#define RING_VALID_MASK 0x00000001 +#define RING_VALID 0x00000001 +#define RING_INVALID 0x00000000 +#define PRB1_TAIL 0x02040 /* 915+ only */ +#define PRB1_HEAD 0x02044 /* 915+ only */ +#define PRB1_START 0x02048 /* 915+ only */ +#define PRB1_CTL 0x0204c /* 915+ only */ +#define HWS_PGA 0x02080 +#define IPEIR 0x02088 +#define NOPID 0x02094 +#define HWSTAM 0x02098 +#define SCPD0 0x0209c /* 915+ only */ +#define IER 0x020a0 +#define IIR 0x020a4 +#define IMR 0x020a8 +#define ISR 0x020ac +#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18) +#define I915_DISPLAY_PORT_INTERRUPT (1<<17) +#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15) +#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14) +#define I915_HWB_OOM_INTERRUPT (1<<13) +#define I915_SYNC_STATUS_INTERRUPT (1<<12) +#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11) +#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10) +#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9) +#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8) +#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7) +#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6) +#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5) +#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4) +#define I915_DEBUG_INTERRUPT (1<<2) +#define I915_USER_INTERRUPT (1<<1) +#define EIR 0x020b0 +#define EMR 0x020b4 +#define ESR 0x020b8 +#define INSTPM 0x020c0 +#define FW_BLC 0x020d8 +#define FW_BLC_SELF 0x020e0 /* 915+ only */ +#define MI_ARB_STATE 0x020e4 /* 915+ only */ +#define CACHE_MODE_0 0x02120 /* 915+ only */ +#define CM0_MASK_SHIFT 16 +#define CM0_IZ_OPT_DISABLE (1<<6) +#define CM0_ZR_OPT_DISABLE (1<<5) +#define CM0_DEPTH_EVICT_DISABLE (1<<4) +#define CM0_COLOR_EVICT_DISABLE (1<<3) +#define CM0_DEPTH_WRITE_DISABLE (1<<1) +#define CM0_RC_OP_FLUSH_DISABLE (1<<0) +#define GFX_FLSH_CNTL 0x02170 /* 915+ only */ + +/* + * Framebuffer compression (915+ only) + */ -/* Framebuffer compression */ #define FBC_CFB_BASE 0x03200 /* 4k page aligned */ #define FBC_LL_BASE 0x03204 /* 4k page aligned */ #define FBC_CONTROL 0x03208 @@ -535,77 +672,10 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define FBC_FENCE_OFF 0x0321b #define FBC_LL_SIZE (1536) -#define FBC_LL_PAD (32) - -/* Interrupt bits: - */ -#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18) -#define I915_DISPLAY_PORT_INTERRUPT (1<<17) -#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15) -#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14) -#define I915_HWB_OOM_INTERRUPT (1<<13) /* binner out of memory */ -#define I915_SYNC_STATUS_INTERRUPT (1<<12) -#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11) -#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10) -#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9) -#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8) -#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7) -#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6) -#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5) -#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4) -#define I915_DEBUG_INTERRUPT (1<<2) -#define I915_USER_INTERRUPT (1<<1) - - -#define I915REG_HWSTAM 0x02098 -#define I915REG_INT_IDENTITY_R 0x020a4 -#define I915REG_INT_MASK_R 0x020a8 -#define I915REG_INT_ENABLE_R 0x020a0 -#define I915REG_INSTPM 0x020c0 - -#define PIPEADSL 0x70000 -#define PIPEBDSL 0x71000 - -#define I915REG_PIPEASTAT 0x70024 -#define I915REG_PIPEBSTAT 0x71024 - -#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) -#define I915_HOTPLUG_INTERRUPT_ENABLE (1UL<<26) -#define I915_HOTPLUG_TV_INTERRUPT_ENABLE (1UL<<18) -#define I915_HOTPLUG_CLEAR (1UL<<10) -#define I915_HOTPLUG_TV_CLEAR (1UL<<2) -#define I915_VBLANK_CLEAR (1UL<<1) - -/* - * The two pipe frame counter registers are not synchronized, so - * reading a stable value is somewhat tricky. The following code - * should work: - * - * do { - * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> - * PIPE_FRAME_HIGH_SHIFT; - * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >> - * PIPE_FRAME_LOW_SHIFT); - * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> - * PIPE_FRAME_HIGH_SHIFT); - * } while (high1 != high2); - * frame = (high1 << 8) | low1; - */ -#define PIPEAFRAMEHIGH 0x70040 -#define PIPEBFRAMEHIGH 0x71040 -#define PIPE_FRAME_HIGH_MASK 0x0000ffff -#define PIPE_FRAME_HIGH_SHIFT 0 -#define PIPEAFRAMEPIXEL 0x70044 -#define PIPEBFRAMEPIXEL 0x71044 -#define PIPE_FRAME_LOW_MASK 0xff000000 -#define PIPE_FRAME_LOW_SHIFT 24 /* - * Pixel within the current frame is counted in the PIPEAFRAMEPIXEL register - * and is 24 bits wide. + * GPIO regs */ -#define PIPE_PIXEL_MASK 0x00ffffff -#define PIPE_PIXEL_SHIFT 0 #define GPIOA 0x5010 #define GPIOB 0x5014 @@ -630,520 +700,82 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); # 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 I915_FIFO_UNDERRUN_STATUS (1UL<<31) -#define I915_CRC_ERROR_ENABLE (1UL<<29) -#define I915_CRC_DONE_ENABLE (1UL<<28) -#define I915_GMBUS_EVENT_ENABLE (1UL<<27) -#define I915_HOTPLUG_INTERRUPT_ENABLE (1UL<<26) -#define I915_VSYNC_INTERRUPT_ENABLE (1UL<<25) -#define I915_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24) -#define I915_DPST_EVENT_ENABLE (1UL<<23) -#define I915_LEGACY_BLC_EVENT_ENABLE (1UL<<22) -#define I915_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21) -#define I915_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20) -#define I915_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */ -#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) -#define I915_OVERLAY_UPDATED_ENABLE (1UL<<16) -#define I915_CRC_ERROR_INTERRUPT_STATUS (1UL<<13) -#define I915_CRC_DONE_INTERRUPT_STATUS (1UL<<12) -#define I915_GMBUS_INTERRUPT_STATUS (1UL<<11) -#define I915_HOTPLUG_INTERRUPT_STATUS (1UL<<10) -#define I915_VSYNC_INTERRUPT_STATUS (1UL<<9) -#define I915_DISPLAY_LINE_COMPARE_STATUS (1UL<<8) -#define I915_DPST_EVENT_STATUS (1UL<<7) -#define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6) -#define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5) -#define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4) -#define I915_HOTPLUG_TV_INTERRUPT_STATUS (1UL<<2) -#define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ -#define I915_VBLANK_INTERRUPT_STATUS (1UL<<1) -#define I915_OVERLAY_UPDATED_STATUS (1UL<<0) - -#define SRX_INDEX 0x3c4 -#define SRX_DATA 0x3c5 -#define SR01 1 -#define SR01_SCREEN_OFF (1<<5) - -#define PPCR 0x61204 -#define PPCR_ON (1<<0) - -#define DVOA 0x61120 -#define DVOB 0x61140 -#define DVOC 0x61160 -#define DVO_ENABLE (1 << 31) -#define DVO_PIPE_B_SELECT (1 << 30) -#define DVO_PIPE_STALL_UNUSED (0 << 28) -#define DVO_PIPE_STALL (1 << 28) -#define DVO_PIPE_STALL_TV (2 << 28) -#define DVO_PIPE_STALL_MASK (3 << 28) -#define DVO_USE_VGA_SYNC (1 << 15) -#define DVO_DATA_ORDER_I740 (0 << 14) -#define DVO_DATA_ORDER_FP (1 << 14) -#define DVO_VSYNC_DISABLE (1 << 11) -#define DVO_HSYNC_DISABLE (1 << 10) -#define DVO_VSYNC_TRISTATE (1 << 9) -#define DVO_HSYNC_TRISTATE (1 << 8) -#define DVO_BORDER_ENABLE (1 << 7) -#define DVO_DATA_ORDER_GBRG (1 << 6) -#define DVO_DATA_ORDER_RGGB (0 << 6) -#define DVO_DATA_ORDER_GBRG_ERRATA (0 << 6) -#define DVO_DATA_ORDER_RGGB_ERRATA (1 << 6) -#define DVO_VSYNC_ACTIVE_HIGH (1 << 4) -#define DVO_HSYNC_ACTIVE_HIGH (1 << 3) -#define DVO_BLANK_ACTIVE_HIGH (1 << 2) -#define DVO_OUTPUT_CSTATE_PIXELS (1 << 1) /* SDG only */ -#define DVO_OUTPUT_SOURCE_SIZE_PIXELS (1 << 0) /* SDG only */ -#define DVO_PRESERVE_MASK (0x7<<24) - -#define DVOA_SRCDIM 0x61124 -#define DVOB_SRCDIM 0x61144 -#define DVOC_SRCDIM 0x61164 -#define DVO_SRCDIM_HORIZONTAL_SHIFT 12 -#define DVO_SRCDIM_VERTICAL_SHIFT 0 - -#define LVDS 0x61180 -#define LVDS_ON (1<<31) - -#define ADPA 0x61100 -#define ADPA_DPMS_MASK (~(3<<10)) -#define ADPA_DPMS_ON (0<<10) -#define ADPA_DPMS_SUSPEND (1<<10) -#define ADPA_DPMS_STANDBY (2<<10) -#define ADPA_DPMS_OFF (3<<10) - -#define NOPID 0x2094 -#define LP_RING 0x2030 -#define HP_RING 0x2040 -/* The binner has its own ring buffer: - */ -#define HWB_RING 0x2400 - -#define RING_TAIL 0x00 -#define TAIL_ADDR 0x001FFFF8 -#define RING_HEAD 0x04 -#define HEAD_WRAP_COUNT 0xFFE00000 -#define HEAD_WRAP_ONE 0x00200000 -#define HEAD_ADDR 0x001FFFFC -#define RING_START 0x08 -#define START_ADDR 0x0xFFFFF000 -#define RING_LEN 0x0C -#define RING_NR_PAGES 0x001FF000 -#define RING_REPORT_MASK 0x00000006 -#define RING_REPORT_64K 0x00000002 -#define RING_REPORT_128K 0x00000004 -#define RING_NO_REPORT 0x00000000 -#define RING_VALID_MASK 0x00000001 -#define RING_VALID 0x00000001 -#define RING_INVALID 0x00000000 - -/* Instruction parser error reg: - */ -#define IPEIR 0x2088 - -/* Scratch pad debug 0 reg: - */ -#define SCPD0 0x209c - -/* Error status reg: - */ -#define ESR 0x20b8 - -/* Secondary DMA fetch address debug reg: - */ -#define DMA_FADD_S 0x20d4 - -/* Memory Interface Arbitration State - */ -#define MI_ARB_STATE 0x20e4 - -/* Cache mode 0 reg. - * - Manipulating render cache behaviour is central - * to the concept of zone rendering, tuning this reg can help avoid - * unnecessary render cache reads and even writes (for z/stencil) - * at beginning and end of scene. - * - * - To change a bit, write to this reg with a mask bit set and the - * bit of interest either set or cleared. EG: (BIT<<16) | BIT to set. - */ -#define Cache_Mode_0 0x2120 -#define CACHE_MODE_0 0x2120 -#define CM0_MASK_SHIFT 16 -#define CM0_IZ_OPT_DISABLE (1<<6) -#define CM0_ZR_OPT_DISABLE (1<<5) -#define CM0_DEPTH_EVICT_DISABLE (1<<4) -#define CM0_COLOR_EVICT_DISABLE (1<<3) -#define CM0_DEPTH_WRITE_DISABLE (1<<1) -#define CM0_RC_OP_FLUSH_DISABLE (1<<0) - - -/* Graphics flush control. A CPU write flushes the GWB of all writes. - * The data is discarded. - */ -#define GFX_FLSH_CNTL 0x2170 - -/* Binner control. Defines the location of the bin pointer list: - */ -#define BINCTL 0x2420 -#define BC_MASK (1 << 9) - -/* Binned scene info. - */ -#define BINSCENE 0x2428 -#define BS_OP_LOAD (1 << 8) -#define BS_MASK (1 << 22) - -/* Bin command parser debug reg: - */ -#define BCPD 0x2480 - -/* Bin memory control debug reg: - */ -#define BMCD 0x2484 - -/* Bin data cache debug reg: - */ -#define BDCD 0x2488 - -/* Binner pointer cache debug reg: - */ -#define BPCD 0x248c - -/* Binner scratch pad debug reg: - */ -#define BINSKPD 0x24f0 - -/* HWB scratch pad debug reg: - */ -#define HWBSKPD 0x24f4 - -/* Binner memory pool reg: - */ -#define BMP_BUFFER 0x2430 -#define BMP_PAGE_SIZE_4K (0 << 10) -#define BMP_BUFFER_SIZE_SHIFT 1 -#define BMP_ENABLE (1 << 0) - -/* Get/put memory from the binner memory pool: - */ -#define BMP_GET 0x2438 -#define BMP_PUT 0x2440 -#define BMP_OFFSET_SHIFT 5 - -/* 3D state packets: - */ -#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24)) - -#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) -#define SC_UPDATE_SCISSOR (0x1<<1) -#define SC_ENABLE_MASK (0x1<<0) -#define SC_ENABLE (0x1<<0) - -#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16)) - -#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) -#define SCI_YMIN_MASK (0xffff<<16) -#define SCI_XMIN_MASK (0xffff<<0) -#define SCI_YMAX_MASK (0xffff<<16) -#define SCI_XMAX_MASK (0xffff<<0) - -#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19)) -#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1) -#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0) -#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) -#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4) -#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0) -#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) - -#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2) - -#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 XY_SRC_COPY_BLT_SRC_TILED (1<<15) -#define XY_SRC_COPY_BLT_DST_TILED (1<<11) - -#define MI_BATCH_BUFFER ((0x30<<23)|1) -#define MI_BATCH_BUFFER_START (0x31<<23) -#define MI_BATCH_BUFFER_END (0xA<<23) -#define MI_BATCH_NON_SECURE (1) - -#define MI_BATCH_NON_SECURE_I965 (1<<8) - -#define MI_WAIT_FOR_EVENT ((0x3<<23)) -#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) -#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) -#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) - -#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23)) - -#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2) -#define ASYNC_FLIP (1<<22) -#define DISPLAY_PLANE_A (0<<20) -#define DISPLAY_PLANE_B (1<<20) - -/* Display regs */ -#define DSPACNTR 0x70180 -#define DSPBCNTR 0x71180 -#define DISPPLANE_SEL_PIPE_MASK (1<<24) - -/* Define the region of interest for the binner: - */ -#define CMD_OP_BIN_CONTROL ((0x3<<29)|(0x1d<<24)|(0x84<<16)|4) - -#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) - -#define BREADCRUMB_BITS 31 -#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1) - -#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5]) -#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) - -#define BLC_PWM_CTL 0x61254 -#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. - * - * The actual value is this field multiplied by two. - */ -#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) -#define BLM_LEGACY_MODE (1 << 16) -/** - * This is the number of cycles out of the backlight modulation cycle for which - * the backlight is on. - * - * This field must be no greater than the number of cycles in the complete - * backlight modulation cycle. - */ -#define BACKLIGHT_DUTY_CYCLE_SHIFT (0) -#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) - -#define I915_GCFGC 0xf0 -#define I915_LOW_FREQUENCY_ENABLE (1 << 7) -#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4) -#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4) -#define I915_DISPLAY_CLOCK_MASK (7 << 4) - -#define I855_HPLLCC 0xc0 -#define I855_CLOCK_CONTROL_MASK (3 << 0) -#define I855_CLOCK_133_200 (0 << 0) -#define I855_CLOCK_100_200 (1 << 0) -#define I855_CLOCK_100_133 (2 << 0) -#define I855_CLOCK_166_250 (3 << 0) - -/* 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) - -/* PCI D state control register */ -#define D_STATE 0x6104 -#define DSPCLK_GATE_D 0x6200 - -/* I830 CRTC registers */ -#define HTOTAL_A 0x60000 -#define HBLANK_A 0x60004 -#define HSYNC_A 0x60008 -#define VTOTAL_A 0x6000c -#define VBLANK_A 0x60010 -#define VSYNC_A 0x60014 -#define PIPEASRC 0x6001c -#define BCLRPAT_A 0x60020 -#define VSYNCSHIFT_A 0x60028 - -#define HTOTAL_B 0x61000 -#define HBLANK_B 0x61004 -#define HSYNC_B 0x61008 -#define VTOTAL_B 0x6100c -#define VBLANK_B 0x61010 -#define VSYNC_B 0x61014 -#define PIPEBSRC 0x6101c -#define BCLRPAT_B 0x61020 -#define VSYNCSHIFT_B 0x61028 - -#define HACTIVE_MASK 0x00000fff -#define VTOTAL_MASK 0x00001fff -#define VTOTAL_SHIFT 16 -#define VACTIVE_MASK 0x00000fff -#define VBLANK_END_MASK 0x00001fff -#define VBLANK_END_SHIFT 16 -#define VBLANK_START_MASK 0x00001fff - -#define PP_STATUS 0x61200 -# define PP_ON (1 << 31) -/** - * Indicates that all dependencies of the panel are on: - * - * - PLL enabled - * - pipe enabled - * - LVDS/DVOB/DVOC on - */ -# define PP_READY (1 << 30) -# define PP_SEQUENCE_NONE (0 << 28) -# define PP_SEQUENCE_ON (1 << 28) -# define PP_SEQUENCE_OFF (2 << 28) -# define PP_SEQUENCE_MASK 0x30000000 -#define PP_CONTROL 0x61204 -# define POWER_TARGET_ON (1 << 0) - -#define LVDSPP_ON 0x61208 -#define LVDSPP_OFF 0x6120c -#define PP_CYCLE 0x61210 - -#define PFIT_CONTROL 0x61230 -# define PFIT_ENABLE (1 << 31) -# define PFIT_PIPE_MASK (3 << 29) -# define PFIT_PIPE_SHIFT 29 -# define VERT_INTERP_DISABLE (0 << 10) -# define VERT_INTERP_BILINEAR (1 << 10) -# define VERT_INTERP_MASK (3 << 10) -# define VERT_AUTO_SCALE (1 << 9) -# define HORIZ_INTERP_DISABLE (0 << 6) -# define HORIZ_INTERP_BILINEAR (1 << 6) -# define HORIZ_INTERP_MASK (3 << 6) -# define HORIZ_AUTO_SCALE (1 << 5) -# define PANEL_8TO6_DITHER_ENABLE (1 << 3) - -#define PFIT_PGM_RATIOS 0x61234 -# define PFIT_VERT_SCALE_MASK 0xfff00000 -# define PFIT_HORIZ_SCALE_MASK 0x0000fff0 - -#define PFIT_AUTO_RATIOS 0x61238 - - -#define DPLL_A 0x06014 -#define DPLL_B 0x06018 -# define DPLL_VCO_ENABLE (1 << 31) -# define DPLL_DVO_HIGH_SPEED (1 << 30) -# define DPLL_SYNCLOCK_ENABLE (1 << 29) -# define DPLL_VGA_MODE_DIS (1 << 28) -# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */ -# define DPLLB_MODE_LVDS (2 << 26) /* i915 */ -# define DPLL_MODE_MASK (3 << 26) -# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */ -# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */ -# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ -# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ -# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ -# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ -/** +/* + * Clock control & power management + */ + +#define VGA0 0x6000 +#define VGA1 0x6004 +#define VGA_PD 0x6010 +#define VGA0_PD_P2_DIV_4 (1 << 7) +#define VGA0_PD_P1_DIV_2 (1 << 5) +#define VGA0_PD_P1_SHIFT 0 +#define VGA0_PD_P1_MASK (0x1f << 0) +#define VGA1_PD_P2_DIV_4 (1 << 15) +#define VGA1_PD_P1_DIV_2 (1 << 13) +#define VGA1_PD_P1_SHIFT 8 +#define VGA1_PD_P1_MASK (0x1f << 8) +#define DPLL_A 0x06014 +#define DPLL_B 0x06018 +#define DPLL_VCO_ENABLE (1 << 31) +#define DPLL_DVO_HIGH_SPEED (1 << 30) +#define DPLL_SYNCLOCK_ENABLE (1 << 29) +#define DPLL_VGA_MODE_DIS (1 << 28) +#define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */ +#define DPLLB_MODE_LVDS (2 << 26) /* i915 */ +#define DPLL_MODE_MASK (3 << 26) +#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */ +#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */ +#define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ +#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ +#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ +#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ +/* * The i830 generation, in DAC/serial mode, defines p1 as two plus this * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set. */ -# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 -/** +#define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 +/* * The i830 generation, in LVDS mode, defines P1 as the bit number set within * this field (only one bit may be set). */ -# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 -# define DPLL_FPA01_P1_POST_DIV_SHIFT 16 -# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */ -# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ -# define PLL_REF_INPUT_DREFCLK (0 << 13) -# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ -# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */ -# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) -# define PLL_REF_INPUT_MASK (3 << 13) -# define PLL_LOAD_PULSE_PHASE_SHIFT 9 +#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 +#define DPLL_FPA01_P1_POST_DIV_SHIFT 16 +/* i830, required in DVO non-gang */ +#define PLL_P2_DIVIDE_BY_4 (1 << 23) +#define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ +#define PLL_REF_INPUT_DREFCLK (0 << 13) +#define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ +#define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */ +#define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) +#define PLL_REF_INPUT_MASK (3 << 13) +#define PLL_LOAD_PULSE_PHASE_SHIFT 9 /* * Parallel to Serial Load Pulse phase selection. * Selects the phase for the 10X DPLL clock for the PCIe * digital display port. The range is 4 to 13; 10 or more * is just a flip delay. The default is 6 */ -# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) -# define DISPLAY_RATE_SELECT_FPA1 (1 << 8) - -/** +#define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) +#define DISPLAY_RATE_SELECT_FPA1 (1 << 8) +/* * SDVO multiplier for 945G/GM. Not used on 965. - * - * \sa DPLL_MD_UDI_MULTIPLIER_MASK - */ -# define SDVO_MULTIPLIER_MASK 0x000000ff -# define SDVO_MULTIPLIER_SHIFT_HIRES 4 -# define SDVO_MULTIPLIER_SHIFT_VGA 0 - -/** @defgroup DPLL_MD - * @{ */ -/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */ -#define DPLL_A_MD 0x0601c -/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */ -#define DPLL_B_MD 0x06020 -/** +#define SDVO_MULTIPLIER_MASK 0x000000ff +#define SDVO_MULTIPLIER_SHIFT_HIRES 4 +#define SDVO_MULTIPLIER_SHIFT_VGA 0 +#define DPLL_A_MD 0x0601c /* 965+ only */ +/* * UDI pixel divider, controlling how many pixels are stuffed into a packet. * * Value is pixels minus 1. Must be set to 1 pixel for SDVO. */ -# define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 -# define DPLL_MD_UDI_DIVIDER_SHIFT 24 -/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ -# define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 -# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 -/** +#define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 +#define DPLL_MD_UDI_DIVIDER_SHIFT 24 +/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ +#define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 +#define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 +/* * SDVO/UDI pixel multiplier. * * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus @@ -1160,80 +792,134 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); * This register field has values of multiplication factor minus 1, with * a maximum multiplier of 5 for SDVO. */ -# define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 -# define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 -/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. +#define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 +#define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 +/* + * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. * This best be set to the default value (3) or the CRT won't work. No, * I don't entirely understand what this does... */ -# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f -# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 -/** @} */ - -#define DPLL_TEST 0x606c -# define DPLLB_TEST_SDVO_DIV_1 (0 << 22) -# define DPLLB_TEST_SDVO_DIV_2 (1 << 22) -# define DPLLB_TEST_SDVO_DIV_4 (2 << 22) -# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22) -# define DPLLB_TEST_N_BYPASS (1 << 19) -# define DPLLB_TEST_M_BYPASS (1 << 18) -# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16) -# define DPLLA_TEST_N_BYPASS (1 << 3) -# define DPLLA_TEST_M_BYPASS (1 << 2) -# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) +#define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f +#define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 +#define DPLL_B_MD 0x06020 /* 965+ only */ +#define FPA0 0x06040 +#define FPA1 0x06044 +#define FPB0 0x06048 +#define FPB1 0x0604c +#define FP_N_DIV_MASK 0x003f0000 +#define FP_N_DIV_SHIFT 16 +#define FP_M1_DIV_MASK 0x00003f00 +#define FP_M1_DIV_SHIFT 8 +#define FP_M2_DIV_MASK 0x0000003f +#define FP_M2_DIV_SHIFT 0 +#define DPLL_TEST 0x606c +#define DPLLB_TEST_SDVO_DIV_1 (0 << 22) +#define DPLLB_TEST_SDVO_DIV_2 (1 << 22) +#define DPLLB_TEST_SDVO_DIV_4 (2 << 22) +#define DPLLB_TEST_SDVO_DIV_MASK (3 << 22) +#define DPLLB_TEST_N_BYPASS (1 << 19) +#define DPLLB_TEST_M_BYPASS (1 << 18) +#define DPLLB_INPUT_BUFFER_ENABLE (1 << 16) +#define DPLLA_TEST_N_BYPASS (1 << 3) +#define DPLLA_TEST_M_BYPASS (1 << 2) +#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) +#define D_STATE 0x6104 +#define CG_2D_DIS 0x6200 +#define CG_3D_DIS 0x6204 -#define ADPA 0x61100 -#define ADPA_DAC_ENABLE (1<<31) -#define ADPA_DAC_DISABLE 0 -#define ADPA_PIPE_SELECT_MASK (1<<30) -#define ADPA_PIPE_A_SELECT 0 -#define ADPA_PIPE_B_SELECT (1<<30) -#define ADPA_USE_VGA_HVPOLARITY (1<<15) -#define ADPA_SETS_HVPOLARITY 0 -#define ADPA_VSYNC_CNTL_DISABLE (1<<11) -#define ADPA_VSYNC_CNTL_ENABLE 0 -#define ADPA_HSYNC_CNTL_DISABLE (1<<10) -#define ADPA_HSYNC_CNTL_ENABLE 0 -#define ADPA_VSYNC_ACTIVE_HIGH (1<<4) -#define ADPA_VSYNC_ACTIVE_LOW 0 -#define ADPA_HSYNC_ACTIVE_HIGH (1<<3) -#define ADPA_HSYNC_ACTIVE_LOW 0 - -#define FPA0 0x06040 -#define FPA1 0x06044 -#define FPB0 0x06048 -#define FPB1 0x0604c -# define FP_N_DIV_MASK 0x003f0000 -# define FP_N_DIV_SHIFT 16 -# define FP_M1_DIV_MASK 0x00003f00 -# define FP_M1_DIV_SHIFT 8 -# define FP_M2_DIV_MASK 0x0000003f -# define FP_M2_DIV_SHIFT 0 +/* + * Palette regs + */ + +#define PALETTE_A 0x0a000 +#define PALETTE_B 0x0a800 + +/* + * Overlay regs + */ + +#define OVADD 0x30000 +#define DOVSTA 0x30008 +#define OC_BUF (0x3<<20) +#define OGAMC5 0x30010 +#define OGAMC4 0x30014 +#define OGAMC3 0x30018 +#define OGAMC2 0x3001c +#define OGAMC1 0x30020 +#define OGAMC0 0x30024 + +/* + * Display engine regs + */ + +/* Pipe A timing regs */ +#define HTOTAL_A 0x60000 +#define HBLANK_A 0x60004 +#define HSYNC_A 0x60008 +#define VTOTAL_A 0x6000c +#define VBLANK_A 0x60010 +#define VSYNC_A 0x60014 +#define PIPEASRC 0x6001c +#define BCLRPAT_A 0x60020 +/* Pipe B timing regs */ +#define HTOTAL_B 0x61000 +#define HBLANK_B 0x61004 +#define HSYNC_B 0x61008 +#define VTOTAL_B 0x6100c +#define VBLANK_B 0x61010 +#define VSYNC_B 0x61014 +#define PIPEBSRC 0x6101c +#define BCLRPAT_B 0x61020 +/* VGA port control */ +#define ADPA 0x61100 +#define ADPA_DAC_ENABLE (1<<31) +#define ADPA_DAC_DISABLE 0 +#define ADPA_PIPE_SELECT_MASK (1<<30) +#define ADPA_PIPE_A_SELECT 0 +#define ADPA_PIPE_B_SELECT (1<<30) +#define ADPA_USE_VGA_HVPOLARITY (1<<15) +#define ADPA_SETS_HVPOLARITY 0 +#define ADPA_VSYNC_CNTL_DISABLE (1<<11) +#define ADPA_VSYNC_CNTL_ENABLE 0 +#define ADPA_HSYNC_CNTL_DISABLE (1<<10) +#define ADPA_HSYNC_CNTL_ENABLE 0 +#define ADPA_VSYNC_ACTIVE_HIGH (1<<4) +#define ADPA_VSYNC_ACTIVE_LOW 0 +#define ADPA_HSYNC_ACTIVE_HIGH (1<<3) +#define ADPA_HSYNC_ACTIVE_LOW 0 +#define ADPA_DPMS_MASK (~(3<<10)) +#define ADPA_DPMS_ON (0<<10) +#define ADPA_DPMS_SUSPEND (1<<10) +#define ADPA_DPMS_STANDBY (2<<10) +#define ADPA_DPMS_OFF (3<<10) + +/* Hotplug control (945+ only) */ #define PORT_HOTPLUG_EN 0x61110 -# define SDVOB_HOTPLUG_INT_EN (1 << 26) -# define SDVOC_HOTPLUG_INT_EN (1 << 25) -# define TV_HOTPLUG_INT_EN (1 << 18) -# define CRT_HOTPLUG_INT_EN (1 << 9) -# define CRT_HOTPLUG_FORCE_DETECT (1 << 3) +#define SDVOB_HOTPLUG_INT_EN (1 << 26) +#define SDVOC_HOTPLUG_INT_EN (1 << 25) +#define TV_HOTPLUG_INT_EN (1 << 18) +#define CRT_HOTPLUG_INT_EN (1 << 9) +#define CRT_HOTPLUG_FORCE_DETECT (1 << 3) #define PORT_HOTPLUG_STAT 0x61114 -# define CRT_HOTPLUG_INT_STATUS (1 << 11) -# define TV_HOTPLUG_INT_STATUS (1 << 10) -# define CRT_HOTPLUG_MONITOR_MASK (3 << 8) -# define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) -# define CRT_HOTPLUG_MONITOR_MONO (2 << 8) -# define CRT_HOTPLUG_MONITOR_NONE (0 << 8) -# define SDVOC_HOTPLUG_INT_STATUS (1 << 7) -# define SDVOB_HOTPLUG_INT_STATUS (1 << 6) - +#define CRT_HOTPLUG_INT_STATUS (1 << 11) +#define TV_HOTPLUG_INT_STATUS (1 << 10) +#define CRT_HOTPLUG_MONITOR_MASK (3 << 8) +#define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) +#define CRT_HOTPLUG_MONITOR_MONO (2 << 8) +#define CRT_HOTPLUG_MONITOR_NONE (0 << 8) +#define SDVOC_HOTPLUG_INT_STATUS (1 << 7) +#define SDVOB_HOTPLUG_INT_STATUS (1 << 6) + +/* SDVO port control */ #define SDVOB 0x61140 #define SDVOC 0x61160 -#define SDVO_ENABLE (1 << 31) -#define SDVO_PIPE_B_SELECT (1 << 30) -#define SDVO_STALL_SELECT (1 << 29) -#define SDVO_INTERRUPT_ENABLE (1 << 26) +#define SDVO_ENABLE (1 << 31) +#define SDVO_PIPE_B_SELECT (1 << 30) +#define SDVO_STALL_SELECT (1 << 29) +#define SDVO_INTERRUPT_ENABLE (1 << 26) /** * 915G/GM SDVO pixel multiplier. * @@ -1241,69 +927,156 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); * * \sa DPLL_MD_UDI_MULTIPLIER_MASK */ -#define SDVO_PORT_MULTIPLY_MASK (7 << 23) -#define SDVO_PORT_MULTIPLY_SHIFT 23 -#define SDVO_PHASE_SELECT_MASK (15 << 19) -#define SDVO_PHASE_SELECT_DEFAULT (6 << 19) -#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) -#define SDVOC_GANG_MODE (1 << 16) -#define SDVO_BORDER_ENABLE (1 << 7) -#define SDVOB_PCIE_CONCURRENCY (1 << 3) -#define SDVO_DETECTED (1 << 2) +#define SDVO_PORT_MULTIPLY_MASK (7 << 23) +#define SDVO_PORT_MULTIPLY_SHIFT 23 +#define SDVO_PHASE_SELECT_MASK (15 << 19) +#define SDVO_PHASE_SELECT_DEFAULT (6 << 19) +#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) +#define SDVOC_GANG_MODE (1 << 16) +#define SDVO_BORDER_ENABLE (1 << 7) +#define SDVOB_PCIE_CONCURRENCY (1 << 3) +#define SDVO_DETECTED (1 << 2) /* Bits to be preserved when writing */ -#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14) | (1 << 26)) -#define SDVOC_PRESERVE_MASK ((1 << 17) | (1 << 26)) +#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14) | (1 << 26)) +#define SDVOC_PRESERVE_MASK ((1 << 17) | (1 << 26)) -/** @defgroup LVDS - * @{ - */ -/** - * This register controls the LVDS output enable, pipe selection, and data - * format selection. - * - * All of the clock/data pairs are force powered down by power sequencing. - */ +/* DVO port control */ +#define DVOA 0x61120 +#define DVOB 0x61140 +#define DVOC 0x61160 +#define DVO_ENABLE (1 << 31) +#define DVO_PIPE_B_SELECT (1 << 30) +#define DVO_PIPE_STALL_UNUSED (0 << 28) +#define DVO_PIPE_STALL (1 << 28) +#define DVO_PIPE_STALL_TV (2 << 28) +#define DVO_PIPE_STALL_MASK (3 << 28) +#define DVO_USE_VGA_SYNC (1 << 15) +#define DVO_DATA_ORDER_I740 (0 << 14) +#define DVO_DATA_ORDER_FP (1 << 14) +#define DVO_VSYNC_DISABLE (1 << 11) +#define DVO_HSYNC_DISABLE (1 << 10) +#define DVO_VSYNC_TRISTATE (1 << 9) +#define DVO_HSYNC_TRISTATE (1 << 8) +#define DVO_BORDER_ENABLE (1 << 7) +#define DVO_DATA_ORDER_GBRG (1 << 6) +#define DVO_DATA_ORDER_RGGB (0 << 6) +#define DVO_DATA_ORDER_GBRG_ERRATA (0 << 6) +#define DVO_DATA_ORDER_RGGB_ERRATA (1 << 6) +#define DVO_VSYNC_ACTIVE_HIGH (1 << 4) +#define DVO_HSYNC_ACTIVE_HIGH (1 << 3) +#define DVO_BLANK_ACTIVE_HIGH (1 << 2) +#define DVO_OUTPUT_CSTATE_PIXELS (1 << 1) /* SDG only */ +#define DVO_OUTPUT_SOURCE_SIZE_PIXELS (1 << 0) /* SDG only */ +#define DVO_PRESERVE_MASK (0x7<<24) +#define DVOA_SRCDIM 0x61124 +#define DVOB_SRCDIM 0x61144 +#define DVOC_SRCDIM 0x61164 +#define DVO_SRCDIM_HORIZONTAL_SHIFT 12 +#define DVO_SRCDIM_VERTICAL_SHIFT 0 + +/* LVDS port control */ #define LVDS 0x61180 -/** +/* * Enables the LVDS port. This bit must be set before DPLLs are enabled, as * the DPLL semantics change when the LVDS is assigned to that pipe. */ -# define LVDS_PORT_EN (1 << 31) -/** Selects pipe B for LVDS data. Must be set on pre-965. */ -# define LVDS_PIPEB_SELECT (1 << 30) - -/** +#define LVDS_PORT_EN (1 << 31) +/* Selects pipe B for LVDS data. Must be set on pre-965. */ +#define LVDS_PIPEB_SELECT (1 << 30) +/* * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per * pixel. */ -# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) -# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) -# define LVDS_A0A2_CLKA_POWER_UP (3 << 8) -/** +#define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) +#define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) +#define LVDS_A0A2_CLKA_POWER_UP (3 << 8) +/* * Controls the A3 data pair, which contains the additional LSBs for 24 bit * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be * on. */ -# define LVDS_A3_POWER_MASK (3 << 6) -# define LVDS_A3_POWER_DOWN (0 << 6) -# define LVDS_A3_POWER_UP (3 << 6) -/** +#define LVDS_A3_POWER_MASK (3 << 6) +#define LVDS_A3_POWER_DOWN (0 << 6) +#define LVDS_A3_POWER_UP (3 << 6) +/* * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP * is set. */ -# define LVDS_CLKB_POWER_MASK (3 << 4) -# define LVDS_CLKB_POWER_DOWN (0 << 4) -# define LVDS_CLKB_POWER_UP (3 << 4) - -/** +#define LVDS_CLKB_POWER_MASK (3 << 4) +#define LVDS_CLKB_POWER_DOWN (0 << 4) +#define LVDS_CLKB_POWER_UP (3 << 4) +/* * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 * setting for whether we are in dual-channel mode. The B3 pair will * additionally only be powered up when LVDS_A3_POWER_UP is set. */ -# define LVDS_B0B3_POWER_MASK (3 << 2) -# define LVDS_B0B3_POWER_DOWN (0 << 2) -# define LVDS_B0B3_POWER_UP (3 << 2) +#define LVDS_B0B3_POWER_MASK (3 << 2) +#define LVDS_B0B3_POWER_DOWN (0 << 2) +#define LVDS_B0B3_POWER_UP (3 << 2) + +/* Panel power sequencing */ +#define PP_STATUS 0x61200 +#define PP_ON (1 << 31) +/* + * Indicates that all dependencies of the panel are on: + * + * - PLL enabled + * - pipe enabled + * - LVDS/DVOB/DVOC on + */ +#define PP_READY (1 << 30) +#define PP_SEQUENCE_NONE (0 << 28) +#define PP_SEQUENCE_ON (1 << 28) +#define PP_SEQUENCE_OFF (2 << 28) +#define PP_SEQUENCE_MASK 0x30000000 +#define PP_CONTROL 0x61204 +#define POWER_TARGET_ON (1 << 0) +#define PP_ON_DELAYS 0x61208 +#define PP_OFF_DELAYS 0x6120c +#define PP_DIVISOR 0x61210 + +/* Panel fitting */ +#define PFIT_CONTROL 0x61230 +#define PFIT_ENABLE (1 << 31) +#define PFIT_PIPE_MASK (3 << 29) +#define PFIT_PIPE_SHIFT 29 +#define VERT_INTERP_DISABLE (0 << 10) +#define VERT_INTERP_BILINEAR (1 << 10) +#define VERT_INTERP_MASK (3 << 10) +#define VERT_AUTO_SCALE (1 << 9) +#define HORIZ_INTERP_DISABLE (0 << 6) +#define HORIZ_INTERP_BILINEAR (1 << 6) +#define HORIZ_INTERP_MASK (3 << 6) +#define HORIZ_AUTO_SCALE (1 << 5) +#define PANEL_8TO6_DITHER_ENABLE (1 << 3) +#define PFIT_PGM_RATIOS 0x61234 +#define PFIT_VERT_SCALE_MASK 0xfff00000 +#define PFIT_HORIZ_SCALE_MASK 0x0000fff0 +#define PFIT_AUTO_RATIOS 0x61238 +/* Backlight control */ +#define BLC_PWM_CTL 0x61254 +#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) +#define BLC_PWM_CTL2 0x61250 /* 965+ only */ +/* + * This is the most significant 15 bits of the number of backlight cycles in a + * complete cycle of the modulated backlight control. + * + * The actual value is this field multiplied by two. + */ +#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) +#define BLM_LEGACY_MODE (1 << 16) +/* + * This is the number of cycles out of the backlight modulation cycle for which + * the backlight is on. + * + * This field must be no greater than the number of cycles in the complete + * backlight modulation cycle. + */ +#define BACKLIGHT_DUTY_CYCLE_SHIFT (0) +#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) + +/* TV port control */ #define TV_CTL 0x68000 /** Enables the TV encoder */ # define TV_ENC_ENABLE (1 << 31) @@ -1370,11 +1143,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); */ # 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). @@ -1418,7 +1187,6 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); # 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 @@ -1477,9 +1245,6 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); # 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 @@ -1493,11 +1258,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); /** 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 @@ -1505,11 +1266,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); /** 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 @@ -1517,11 +1274,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); /** 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) @@ -1531,11 +1284,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); /** 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 @@ -1543,11 +1292,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); /** 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 @@ -1558,11 +1303,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); /** 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 @@ -1578,11 +1319,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); */ # 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) @@ -1600,11 +1337,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); */ # 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 @@ -1618,11 +1351,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); */ # 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 @@ -1636,11 +1365,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); */ # 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 @@ -1654,11 +1379,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); */ # 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 @@ -1672,11 +1393,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); */ # 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) @@ -1698,11 +1415,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); /** 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 @@ -1710,11 +1423,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); /** 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 @@ -1722,11 +1431,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); /** 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 @@ -1734,11 +1439,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); /** 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 @@ -1750,11 +1451,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); */ # 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. @@ -1787,11 +1484,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); */ # 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. @@ -1807,11 +1500,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); */ # 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. @@ -1831,11 +1520,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); */ # 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) /** @@ -1851,11 +1536,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); /** 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. */ @@ -1864,10 +1545,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); /** 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 @@ -1877,102 +1555,131 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define TV_V_CHROMA_0 0x68400 #define TV_V_CHROMA_42 0x684a8 -#define PIPEACONF 0x70008 -#define PIPEACONF_ENABLE (1<<31) -#define PIPEACONF_DISABLE 0 -#define PIPEACONF_DOUBLE_WIDE (1<<30) -#define I965_PIPECONF_ACTIVE (1<<30) -#define PIPEACONF_SINGLE_WIDE 0 -#define PIPEACONF_PIPE_UNLOCKED 0 -#define PIPEACONF_PIPE_LOCKED (1<<25) -#define PIPEACONF_PALETTE 0 -#define PIPEACONF_GAMMA (1<<24) -#define PIPECONF_FORCE_BORDER (1<<25) -#define PIPECONF_PROGRESSIVE (0 << 21) -#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) -#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) - -#define DSPARB 0x70030 -#define DSPARB_CSTART_MASK (0x7f << 7) -#define DSPARB_CSTART_SHIFT 7 -#define DSPARB_BSTART_MASK (0x7f) -#define DSPARB_BSTART_SHIFT 0 - -#define PIPEBCONF 0x71008 -#define PIPEBCONF_ENABLE (1<<31) -#define PIPEBCONF_DISABLE 0 -#define PIPEBCONF_DOUBLE_WIDE (1<<30) -#define PIPEBCONF_DISABLE 0 -#define PIPEBCONF_GAMMA (1<<24) -#define PIPEBCONF_PALETTE 0 - -#define PIPEBGCMAXRED 0x71010 -#define PIPEBGCMAXGREEN 0x71014 -#define PIPEBGCMAXBLUE 0x71018 -#define PIPEBSTAT 0x71024 -#define PIPEBFRAMEHIGH 0x71040 -#define PIPEBFRAMEPIXEL 0x71044 +/* Display & cursor control */ -#define DSPACNTR 0x70180 -#define DSPBCNTR 0x71180 -#define DISPLAY_PLANE_ENABLE (1<<31) -#define DISPLAY_PLANE_DISABLE 0 -#define DISPPLANE_GAMMA_ENABLE (1<<30) -#define DISPPLANE_GAMMA_DISABLE 0 -#define DISPPLANE_PIXFORMAT_MASK (0xf<<26) -#define DISPPLANE_8BPP (0x2<<26) -#define DISPPLANE_15_16BPP (0x4<<26) -#define DISPPLANE_16BPP (0x5<<26) -#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) -#define DISPPLANE_32BPP (0x7<<26) -#define DISPPLANE_STEREO_ENABLE (1<<25) -#define DISPPLANE_STEREO_DISABLE 0 -#define DISPPLANE_SEL_PIPE_MASK (1<<24) -#define DISPPLANE_SEL_PIPE_A 0 -#define DISPPLANE_SEL_PIPE_B (1<<24) -#define DISPPLANE_SRC_KEY_ENABLE (1<<22) -#define DISPPLANE_SRC_KEY_DISABLE 0 -#define DISPPLANE_LINE_DOUBLE (1<<20) -#define DISPPLANE_NO_LINE_DOUBLE 0 -#define DISPPLANE_STEREO_POLARITY_FIRST 0 -#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) -/* plane B only */ -#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15) -#define DISPPLANE_ALPHA_TRANS_DISABLE 0 -#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0 -#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1) - -#define DSPABASE 0x70184 +/* Pipe A */ +#define PIPEADSL 0x70000 +#define PIPEACONF 0x70008 +#define PIPEACONF_ENABLE (1<<31) +#define PIPEACONF_DISABLE 0 +#define PIPEACONF_DOUBLE_WIDE (1<<30) +#define I965_PIPECONF_ACTIVE (1<<30) +#define PIPEACONF_SINGLE_WIDE 0 +#define PIPEACONF_PIPE_UNLOCKED 0 +#define PIPEACONF_PIPE_LOCKED (1<<25) +#define PIPEACONF_PALETTE 0 +#define PIPEACONF_GAMMA (1<<24) +#define PIPECONF_FORCE_BORDER (1<<25) +#define PIPECONF_PROGRESSIVE (0 << 21) +#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) +#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) +#define PIPEASTAT 0x70024 +#define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31) +#define PIPE_CRC_ERROR_ENABLE (1UL<<29) +#define PIPE_CRC_DONE_ENABLE (1UL<<28) +#define PIPE_GMBUS_EVENT_ENABLE (1UL<<27) +#define PIPE_HOTPLUG_INTERRUPT_ENABLE (1UL<<26) +#define PIPE_VSYNC_INTERRUPT_ENABLE (1UL<<25) +#define PIPE_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24) +#define PIPE_DPST_EVENT_ENABLE (1UL<<23) +#define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL<<22) +#define PIPE_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21) +#define PIPE_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20) +#define PIPE_HOTPLUG_TV_INTERRUPT_ENABLE (1UL<<18) /* pre-965 */ +#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */ +#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17) +#define PIPE_OVERLAY_UPDATED_ENABLE (1UL<<16) +#define PIPE_CRC_ERROR_INTERRUPT_STATUS (1UL<<13) +#define PIPE_CRC_DONE_INTERRUPT_STATUS (1UL<<12) +#define PIPE_GMBUS_INTERRUPT_STATUS (1UL<<11) +#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL<<10) +#define PIPE_VSYNC_INTERRUPT_STATUS (1UL<<9) +#define PIPE_DISPLAY_LINE_COMPARE_STATUS (1UL<<8) +#define PIPE_DPST_EVENT_STATUS (1UL<<7) +#define PIPE_LEGACY_BLC_EVENT_STATUS (1UL<<6) +#define PIPE_ODD_FIELD_INTERRUPT_STATUS (1UL<<5) +#define PIPE_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4) +#define PIPE_HOTPLUG_TV_INTERRUPT_STATUS (1UL<<2) /* pre-965 */ +#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ +#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1) +#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0) + +#define DSPARB 0x70030 +#define DSPARB_CSTART_MASK (0x7f << 7) +#define DSPARB_CSTART_SHIFT 7 +#define DSPARB_BSTART_MASK (0x7f) +#define DSPARB_BSTART_SHIFT 0 +/* + * The two pipe frame counter registers are not synchronized, so + * reading a stable value is somewhat tricky. The following code + * should work: + * + * do { + * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> + * PIPE_FRAME_HIGH_SHIFT; + * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >> + * PIPE_FRAME_LOW_SHIFT); + * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> + * PIPE_FRAME_HIGH_SHIFT); + * } while (high1 != high2); + * frame = (high1 << 8) | low1; + */ +#define PIPEAFRAMEHIGH 0x70040 +#define PIPE_FRAME_HIGH_MASK 0x0000ffff +#define PIPE_FRAME_HIGH_SHIFT 0 +#define PIPEAFRAMEPIXEL 0x70044 +#define PIPE_FRAME_LOW_MASK 0xff000000 +#define PIPE_FRAME_LOW_SHIFT 24 +#define PIPE_PIXEL_MASK 0x00ffffff +#define PIPE_PIXEL_SHIFT 0 + +/* Cursor A & B regs */ +#define CURACNTR 0x70080 +#define CURSOR_MODE_DISABLE 0x00 +#define CURSOR_MODE_64_32B_AX 0x07 +#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX) +#define MCURSOR_GAMMA_ENABLE (1 << 26) +#define CURABASE 0x70084 +#define CURAPOS 0x70088 +#define CURSOR_POS_MASK 0x007FF +#define CURSOR_POS_SIGN 0x8000 +#define CURSOR_X_SHIFT 0 +#define CURSOR_Y_SHIFT 16 +#define CURBCNTR 0x700c0 +#define CURBBASE 0x700c4 +#define CURBPOS 0x700c8 + +/* Display A control */ +#define DSPACNTR 0x70180 +#define DISPLAY_PLANE_ENABLE (1<<31) +#define DISPLAY_PLANE_DISABLE 0 +#define DISPPLANE_GAMMA_ENABLE (1<<30) +#define DISPPLANE_GAMMA_DISABLE 0 +#define DISPPLANE_PIXFORMAT_MASK (0xf<<26) +#define DISPPLANE_8BPP (0x2<<26) +#define DISPPLANE_15_16BPP (0x4<<26) +#define DISPPLANE_16BPP (0x5<<26) +#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) +#define DISPPLANE_32BPP (0x7<<26) +#define DISPPLANE_STEREO_ENABLE (1<<25) +#define DISPPLANE_STEREO_DISABLE 0 +#define DISPPLANE_SEL_PIPE_MASK (1<<24) +#define DISPPLANE_SEL_PIPE_A 0 +#define DISPPLANE_SEL_PIPE_B (1<<24) +#define DISPPLANE_SRC_KEY_ENABLE (1<<22) +#define DISPPLANE_SRC_KEY_DISABLE 0 +#define DISPPLANE_LINE_DOUBLE (1<<20) +#define DISPPLANE_NO_LINE_DOUBLE 0 +#define DISPPLANE_STEREO_POLARITY_FIRST 0 +#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) +#define DSPAADDR 0x70184 #define DSPASTRIDE 0x70188 - -#define DSPBBASE 0x71184 -#define DSPBADDR DSPBBASE -#define DSPBSTRIDE 0x71188 - -#define DSPAKEYVAL 0x70194 -#define DSPAKEYMASK 0x70198 - #define DSPAPOS 0x7018C /* reserved */ #define DSPASIZE 0x70190 -#define DSPBPOS 0x7118C -#define DSPBSIZE 0x71190 - -#define DSPASURF 0x7019C -#define DSPATILEOFF 0x701A4 - -#define DSPBSURF 0x7119C -#define DSPBTILEOFF 0x711A4 - -#define VGACNTRL 0x71400 -# define VGA_DISP_DISABLE (1 << 31) -# define VGA_2X_MODE (1 << 30) -# define VGA_PIPE_B_SELECT (1 << 29) - -/* - * Some BIOS scratch area registers. The 845 (and 830?) store the amount - * of video memory available to the BIOS in SWF1. - */ +#define DSPASURF 0x7019C /* 965+ only */ +#define DSPATILEOFF 0x701A4 /* 965+ only */ +/* VBIOS flags */ #define SWF0 0x71410 #define SWF1 0x71414 #define SWF2 0x71418 @@ -1986,27 +1693,33 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define SWF31 0x72418 #define SWF32 0x7241c -/* - * Overlay registers. These are overlay registers accessed via MMIO. - * Those loaded via the overlay register page are defined in i830_video.c. - */ -#define OVADD 0x30000 +/* Pipe B */ +#define PIPEBDSL 0x71000 +#define PIPEBCONF 0x71008 +#define PIPEBSTAT 0x71024 +#define PIPEBFRAMEHIGH 0x71040 +#define PIPEBFRAMEPIXEL 0x71044 -#define DOVSTA 0x30008 -#define OC_BUF (0x3<<20) +/* Display B control */ +#define DSPBCNTR 0x71180 +#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15) +#define DISPPLANE_ALPHA_TRANS_DISABLE 0 +#define DISPPLANE_SPRITE_ABOVE_DISPLAY 0 +#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1) +#define DSPBADDR 0x71184 +#define DSPBSTRIDE 0x71188 +#define DSPBPOS 0x7118C +#define DSPBSIZE 0x71190 +#define DSPBSURF 0x7119C +#define DSPBTILEOFF 0x711A4 -#define OGAMC5 0x30010 -#define OGAMC4 0x30014 -#define OGAMC3 0x30018 -#define OGAMC2 0x3001c -#define OGAMC1 0x30020 -#define OGAMC0 0x30024 +/* VBIOS regs */ +#define VGACNTRL 0x71400 +# define VGA_DISP_DISABLE (1 << 31) +# define VGA_2X_MODE (1 << 30) +# define VGA_PIPE_B_SELECT (1 << 29) -/* - * Palette registers - */ -#define PALETTE_A 0x0a000 -#define PALETTE_B 0x0a800 +/* Chipset type macros */ #define IS_I830(dev) ((dev)->pci_device == 0x3577) #define IS_845G(dev) ((dev)->pci_device == 0x2562) @@ -2043,6 +1756,4 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev)) -#define PRIMARY_RINGBUFFER_SIZE (128*1024) - #endif diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 22577c7f..0bbad65e 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -112,9 +112,9 @@ int i915_load_modeset_init(struct drm_device *dev) 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); + I915_WRITE(PRB0_CTL, 0); + I915_WRITE(PRB0_HEAD, 0); + I915_WRITE(PRB0_TAIL, 0); size = PRIMARY_RINGBUFFER_SIZE; ret = drm_buffer_object_create(dev, size, drm_bo_type_kernel, @@ -146,10 +146,9 @@ int i915_load_modeset_init(struct drm_device *dev) 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)); + I915_WRITE(PRB0_START, dev_priv->ring.Start); + I915_WRITE(PRB0_CTL, ((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. @@ -175,7 +174,7 @@ int i915_load_modeset_init(struct drm_device *dev) memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - I915_WRITE(I915REG_HWS_PGA, dev_priv->dma_status_page); + I915_WRITE(HWS_PGA, dev_priv->dma_status_page); } else { size = 4 * 1024; ret = drm_buffer_object_create(dev, size, @@ -210,7 +209,7 @@ int i915_load_modeset_init(struct drm_device *dev) } dev_priv->hw_status_page = dev_priv->hws_map.handle; memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - I915_WRITE(I915REG_HWS_PGA, dev_priv->status_gfx_addr); + I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); } DRM_DEBUG("Enabled hardware status page\n"); @@ -261,7 +260,7 @@ destroy_hws: if (dev_priv->hws_bo) drm_bo_usage_deref_unlocked(&dev_priv->hws_bo); } - I915_WRITE(I915REG_HWS_PGA, 0x1ffff000); + I915_WRITE(HWS_PGA, 0x1ffff000); destroy_ringbuffer: if (dev_priv->ring.virtual_start) drm_mem_reg_iounmap(dev, &dev_priv->ring_buffer->mem, @@ -381,7 +380,7 @@ int i915_driver_unload(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - I915_WRITE(LP_RING + RING_LEN, 0); + I915_WRITE(PRB0_CTL, 0); if (drm_core_check_feature(dev, DRIVER_MODESET)) { drm_irq_uninstall(dev); @@ -413,14 +412,14 @@ int i915_driver_unload(struct drm_device *dev) dev_priv->hw_status_page = NULL; dev_priv->dma_status_page = 0; /* Need to rewrite hardware status page */ - I915_WRITE(I915REG_HWS_PGA, 0x1ffff000); + I915_WRITE(HWS_PGA, 0x1ffff000); } if (dev_priv->status_gfx_addr) { dev_priv->status_gfx_addr = 0; drm_core_ioremapfree(&dev_priv->hws_map, dev); drm_bo_usage_deref_unlocked(&dev_priv->hws_bo); - I915_WRITE(I915REG_HWS_PGA, 0x1ffff000); + I915_WRITE(HWS_PGA, 0x1ffff000); } if (drm_core_check_feature(dev, DRIVER_MODESET)) { diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 4aef568e..38995421 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -636,9 +636,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) /* On i8xx/i915 hw the IIR and IER are 16bit on i9xx its 32bit */ if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) - iir = I915_READ(I915REG_INT_IDENTITY_R); + iir = I915_READ(IIR); else - iir = I915_READ16(I915REG_INT_IDENTITY_R); + iir = I915_READ16(IIR); iir &= (dev_priv->irq_enable_reg | I915_USER_INTERRUPT); @@ -649,10 +649,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) #if 0 DRM_DEBUG ("iir 0x%08x im 0x%08x ie 0x%08x pipea 0x%08x pipeb 0x%08x\n", iir, - I915_READ(I915REG_INT_MASK_R), - I915_READ(I915REG_INT_ENABLE_R), - I915_READ(I915REG_PIPEASTAT), - I915_READ(I915REG_PIPEBSTAT)); + I915_READ(IMR), + I915_READ(IER), + I915_READ(PIPEASTAT), + I915_READ(PIPEBSTAT)); #endif return IRQ_NONE; } @@ -662,19 +662,19 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) * we may get extra interrupts. */ if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) { - pipea_stats = I915_READ(I915REG_PIPEASTAT); - if (pipea_stats & (I915_START_VBLANK_INTERRUPT_STATUS| - I915_VBLANK_INTERRUPT_STATUS)) + pipea_stats = I915_READ(PIPEASTAT); + if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS| + PIPE_VBLANK_INTERRUPT_STATUS)) { vblank++; drm_handle_vblank(dev, i915_get_plane(dev, 0)); } /* This is a global event, and not a pipe A event */ - if (pipea_stats & I915_HOTPLUG_INTERRUPT_STATUS) + if (pipea_stats & PIPE_HOTPLUG_INTERRUPT_STATUS) hotplug = 1; - if (pipea_stats & I915_HOTPLUG_TV_INTERRUPT_STATUS) { + if (pipea_stats & PIPE_HOTPLUG_TV_INTERRUPT_STATUS) { hotplug = 1; /* Toggle hotplug detection to clear hotplug status */ tvdac = I915_READ(TV_DAC); @@ -682,27 +682,27 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) I915_WRITE(TV_DAC, tvdac | TVDAC_STATE_CHG_EN); } - I915_WRITE(I915REG_PIPEASTAT, pipea_stats); + I915_WRITE(PIPEASTAT, pipea_stats); } if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) { - pipeb_stats = I915_READ(I915REG_PIPEBSTAT); - if (pipeb_stats & (I915_START_VBLANK_INTERRUPT_STATUS| - I915_VBLANK_INTERRUPT_STATUS)) + pipeb_stats = I915_READ(PIPEBSTAT); + if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS| + PIPE_VBLANK_INTERRUPT_STATUS)) { vblank++; drm_handle_vblank(dev, i915_get_plane(dev, 1)); } - I915_WRITE(I915REG_PIPEBSTAT, pipeb_stats); + I915_WRITE(PIPEBSTAT, pipeb_stats); } /* Clear the generated interrupt */ if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { - I915_WRITE(I915REG_INT_IDENTITY_R, iir); - (void) I915_READ(I915REG_INT_IDENTITY_R); + I915_WRITE(IIR, iir); + (void) I915_READ(IIR); } else { - I915_WRITE16(I915REG_INT_IDENTITY_R, iir); - (void) I915_READ16(I915REG_INT_IDENTITY_R); + I915_WRITE16(IIR, iir); + (void) I915_READ16(IIR); } if (dev->primary->master) { @@ -728,10 +728,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) DRM_INFO("Hotplug event received\n"); if (!IS_I9XX(dev) || IS_I915G(dev) || IS_I915GM(dev)) { - if (pipea_stats & I915_HOTPLUG_INTERRUPT_STATUS) + if (pipea_stats & PIPE_HOTPLUG_INTERRUPT_STATUS) temp2 |= SDVOB_HOTPLUG_INT_STATUS | SDVOC_HOTPLUG_INT_STATUS; - if (pipea_stats & I915_HOTPLUG_TV_INTERRUPT_STATUS) + if (pipea_stats & PIPE_HOTPLUG_TV_INTERRUPT_STATUS) temp2 |= TV_HOTPLUG_INT_STATUS; } else { temp2 = I915_READ(PORT_HOTPLUG_STAT); @@ -757,7 +757,7 @@ int i915_emit_irq(struct drm_device *dev) BEGIN_LP_RING(2); OUT_RING(0); - OUT_RING(GFX_OP_USER_INTERRUPT); + OUT_RING(MI_USER_INTERRUPT); ADVANCE_LP_RING(); return dev_priv->counter; @@ -771,9 +771,9 @@ void i915_user_irq_on(struct drm_device *dev) if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1)){ dev_priv->irq_enable_reg |= I915_USER_INTERRUPT; if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) - I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + I915_WRITE(IER, dev_priv->irq_enable_reg); else - I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + I915_WRITE16(IER, dev_priv->irq_enable_reg); } DRM_SPINUNLOCK(&dev_priv->user_irq_lock); @@ -787,9 +787,9 @@ void i915_user_irq_off(struct drm_device *dev) if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { // dev_priv->irq_enable_reg &= ~I915_USER_INTERRUPT; // if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) - // I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + // I915_WRITE(IER, dev_priv->irq_enable_reg); // else - // I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + // I915_WRITE16(IER, dev_priv->irq_enable_reg); } DRM_SPINUNLOCK(&dev_priv->user_irq_lock); } @@ -876,11 +876,11 @@ int i915_enable_vblank(struct drm_device *dev, int plane) switch (pipe) { case 0: - pipestat_reg = I915REG_PIPEASTAT; + pipestat_reg = PIPEASTAT; dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; break; case 1: - pipestat_reg = I915REG_PIPEBSTAT; + pipestat_reg = PIPEBSTAT; dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; break; default: @@ -897,21 +897,21 @@ int i915_enable_vblank(struct drm_device *dev, int plane) * but */ if (IS_I965G (dev)) - pipestat |= I915_START_VBLANK_INTERRUPT_ENABLE; + pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE; else - pipestat |= I915_VBLANK_INTERRUPT_ENABLE; + pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE; /* * Clear any pending status */ - pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS | - I915_VBLANK_INTERRUPT_STATUS); + pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS | + PIPE_VBLANK_INTERRUPT_STATUS); I915_WRITE(pipestat_reg, pipestat); } if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) - I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + I915_WRITE(IER, dev_priv->irq_enable_reg); else - I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + I915_WRITE16(IER, dev_priv->irq_enable_reg); return 0; @@ -926,11 +926,11 @@ void i915_disable_vblank(struct drm_device *dev, int plane) switch (pipe) { case 0: - pipestat_reg = I915REG_PIPEASTAT; + pipestat_reg = PIPEASTAT; dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; break; case 1: - pipestat_reg = I915REG_PIPEBSTAT; + pipestat_reg = PIPEBSTAT; dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; break; default: @@ -940,20 +940,20 @@ void i915_disable_vblank(struct drm_device *dev, int plane) } if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) - I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + I915_WRITE(IER, dev_priv->irq_enable_reg); else - I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + I915_WRITE16(IER, dev_priv->irq_enable_reg); if (pipestat_reg) { pipestat = I915_READ (pipestat_reg); - pipestat &= ~(I915_START_VBLANK_INTERRUPT_ENABLE | - I915_VBLANK_INTERRUPT_ENABLE); + pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | + PIPE_VBLANK_INTERRUPT_ENABLE); /* * Clear any pending status */ - pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS | - I915_VBLANK_INTERRUPT_STATUS); + pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS | + PIPE_VBLANK_INTERRUPT_STATUS); I915_WRITE(pipestat_reg, pipestat); } } @@ -973,11 +973,11 @@ void i915_enable_interrupt (struct drm_device *dev) dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; /* Enable global interrupts for hotplug - not a pipeA event */ - I915_WRITE(I915REG_PIPEASTAT, I915_READ(I915REG_PIPEASTAT) | - I915_HOTPLUG_INTERRUPT_ENABLE | - I915_HOTPLUG_TV_INTERRUPT_ENABLE | - I915_HOTPLUG_TV_CLEAR | - I915_HOTPLUG_CLEAR); + I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) | + PIPE_HOTPLUG_INTERRUPT_ENABLE | + PIPE_HOTPLUG_TV_INTERRUPT_ENABLE | + PIPE_HOTPLUG_TV_INTERRUPT_STATUS | + PIPE_HOTPLUG_INTERRUPT_STATUS); } if (dev_priv->irq_enable_reg & (I915_DISPLAY_PORT_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT)) { @@ -1025,9 +1025,9 @@ void i915_enable_interrupt (struct drm_device *dev) } if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) - I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + I915_WRITE(IER, dev_priv->irq_enable_reg); else - I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); + I915_WRITE16(IER, dev_priv->irq_enable_reg); dev_priv->irq_enabled = 1; } @@ -1068,9 +1068,9 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data, } if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) - flag = I915_READ(I915REG_INT_ENABLE_R); + flag = I915_READ(IER); else - flag = I915_READ16(I915REG_INT_ENABLE_R); + flag = I915_READ16(IER); pipe->pipe = 0; if (flag & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) @@ -1249,23 +1249,23 @@ void i915_driver_irq_preinstall(struct drm_device * dev) struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; u32 tmp; - tmp = I915_READ(I915REG_PIPEASTAT); - I915_WRITE(I915REG_PIPEASTAT, tmp); - tmp = I915_READ(I915REG_PIPEBSTAT); - I915_WRITE(I915REG_PIPEBSTAT, tmp); + tmp = I915_READ(PIPEASTAT); + I915_WRITE(PIPEASTAT, tmp); + tmp = I915_READ(PIPEBSTAT); + I915_WRITE(PIPEBSTAT, tmp); - I915_WRITE16(I915REG_HWSTAM, 0xeffe); + I915_WRITE16(HWSTAM, 0xeffe); if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { - I915_WRITE(I915REG_INT_MASK_R, 0x0); - I915_WRITE(I915REG_INT_ENABLE_R, 0x0); - tmp = I915_READ(I915REG_INT_IDENTITY_R); - I915_WRITE(I915REG_INT_IDENTITY_R, tmp); + I915_WRITE(IMR, 0x0); + I915_WRITE(IER, 0x0); + tmp = I915_READ(IIR); + I915_WRITE(IIR, tmp); } else { - I915_WRITE16(I915REG_INT_MASK_R, 0x0); - I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); - tmp = I915_READ16(I915REG_INT_IDENTITY_R); - I915_WRITE16(I915REG_INT_IDENTITY_R, tmp); + I915_WRITE16(IMR, 0x0); + I915_WRITE16(IER, 0x0); + tmp = I915_READ16(IIR); + I915_WRITE16(IIR, tmp); } } @@ -1300,7 +1300,7 @@ int i915_driver_irq_postinstall(struct drm_device * dev) * Initialize the hardware status page IRQ location. */ - I915_WRITE(I915REG_INSTPM, (1 << 5) | (1 << 21)); + I915_WRITE(INSTPM, (1 << 5) | (1 << 21)); return 0; } @@ -1314,23 +1314,23 @@ void i915_driver_irq_uninstall(struct drm_device * dev) dev_priv->irq_enabled = 0; - temp = I915_READ(I915REG_PIPEASTAT); - I915_WRITE(I915REG_PIPEASTAT, temp); - temp = I915_READ(I915REG_PIPEBSTAT); - I915_WRITE(I915REG_PIPEBSTAT, temp); + temp = I915_READ(PIPEASTAT); + I915_WRITE(PIPEASTAT, temp); + temp = I915_READ(PIPEBSTAT); + I915_WRITE(PIPEBSTAT, temp); if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { - I915_WRITE(I915REG_HWSTAM, 0xffffffff); - I915_WRITE(I915REG_INT_MASK_R, 0xffffffff); - I915_WRITE(I915REG_INT_ENABLE_R, 0x0); + I915_WRITE(HWSTAM, 0xffffffff); + I915_WRITE(IMR, 0xffffffff); + I915_WRITE(IER, 0x0); - temp = I915_READ(I915REG_INT_IDENTITY_R); - I915_WRITE(I915REG_INT_IDENTITY_R, temp); + temp = I915_READ(IIR); + I915_WRITE(IIR, temp); } else { - I915_WRITE16(I915REG_HWSTAM, 0xffff); - I915_WRITE16(I915REG_INT_MASK_R, 0xffff); - I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); + I915_WRITE16(HWSTAM, 0xffff); + I915_WRITE16(IMR, 0xffff); + I915_WRITE16(IER, 0x0); - temp = I915_READ16(I915REG_INT_IDENTITY_R); - I915_WRITE16(I915REG_INT_IDENTITY_R, temp); + temp = I915_READ16(IIR); + I915_WRITE16(IIR, temp); } } -- cgit v1.2.3 From e8320a716d97504d91299d20d640b847c86e4b17 Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Mon, 19 May 2008 17:06:38 +0800 Subject: i915: init bo mm at driver init only when modeset=1 To avoid bo memory manager being inited twice, it will be called at firstopen when modeset is not enabled. --- shared-core/i915_init.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 98908a50..f5fe5ba4 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -353,16 +353,17 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) #endif #endif - /* - * Initialize the memory manager for local and AGP space - */ - ret = drm_bo_driver_init(dev); - if (ret) { - DRM_ERROR("fail to init memory manager for local & AGP space\n"); - goto out_rmmap; - } - if (drm_core_check_feature(dev, DRIVER_MODESET)) { + /* + * Initialize the memory manager for local and AGP space + */ + ret = drm_bo_driver_init(dev); + if (ret) { + DRM_ERROR("fail to init memory manager for " + "local & AGP space\n"); + goto out_rmmap; + } + ret = i915_load_modeset_init(dev); if (ret < 0) { DRM_ERROR("failed to init modeset\n"); -- cgit v1.2.3 From 9fc4ea5c00dfb91ebff893fb5092e768155cc2e2 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 23 May 2008 18:42:47 -0700 Subject: i915: do a better job of parsing VBIOS data Add code to get panel modes from the VBIOS if present and check whether certain outputs exist. Should make our display detection code a little more robust. --- shared-core/i915_drv.h | 26 +++++++++++++++----------- shared-core/i915_init.c | 4 ++-- 2 files changed, 17 insertions(+), 13 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 84cc60f3..c5e22f7c 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -174,14 +174,17 @@ struct drm_i915_private { int backlight_duty_cycle; /* restore backlight to this value */ bool panel_wants_dither; struct drm_display_mode *panel_fixed_mode; + struct drm_display_mode *vbt_mode; /* if any */ /* DRI2 sarea */ struct drm_buffer_object *sarea_bo; struct drm_bo_kmap_obj sarea_kmap; - /* BIOS data */ - struct vbt_header *vbt; - struct bdb_header *bdb; + /* Feature bits from the VBIOS */ + int int_tv_support:1; + int lvds_dither:1; + int lvds_vbt:1; + int int_crt_support:1; /* Register state */ u8 saveLBB; @@ -1680,15 +1683,16 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define DSPATILEOFF 0x701A4 /* 965+ only */ /* VBIOS flags */ -#define SWF0 0x71410 -#define SWF1 0x71414 -#define SWF2 0x71418 -#define SWF3 0x7141c -#define SWF4 0x71420 -#define SWF5 0x71424 -#define SWF6 0x71428 - +#define SWF00 0x71410 +#define SWF01 0x71414 +#define SWF02 0x71418 +#define SWF03 0x7141c +#define SWF04 0x71420 +#define SWF05 0x71424 +#define SWF06 0x71428 #define SWF10 0x70410 +#define SWF11 0x70414 +#define SWF14 0x71420 #define SWF30 0x72414 #define SWF31 0x72418 #define SWF32 0x7241c diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index f5fe5ba4..bda15e01 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -224,9 +224,9 @@ int i915_load_modeset_init(struct drm_device *dev) goto destroy_hws; } - ret = intel_find_bios(dev); + ret = intel_init_bios(dev); if (ret) { - DRM_ERROR("failed to find VBT\n"); + DRM_ERROR("failed to find VBIOS tables\n"); ret = -ENODEV; goto destroy_wq; } -- cgit v1.2.3 From df8cd54286fbae5903d8ede390ec4a11cb6c4b6c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 29 May 2008 14:02:14 +1000 Subject: modesetting: reorganise code into core and helper functions. This splits a lot of the core modesetting code out into a file of helper functions, that are only called from themselves and/or the driver. The driver gets called into more often or can call these functions from itself if it is a helper using driver. I've broken framebuffer resize doing this but I didn't like the API for that in any case. --- shared-core/i915_init.c | 3 ++- shared-core/i915_irq.c | 11 ++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index bda15e01..f03f8949 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -13,6 +13,7 @@ #include "i915_drm.h" #include "i915_drv.h" #include "intel_bios.h" +#include "intel_drv.h" /** * i915_probe_agp - get AGP bootup configuration @@ -232,7 +233,7 @@ int i915_load_modeset_init(struct drm_device *dev) } intel_modeset_init(dev); - drm_initial_config(dev, false); + drm_helper_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"); diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 592e881b..ccedc70e 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -31,6 +31,7 @@ #include "i915_drm.h" #include "i915_drv.h" #include "intel_drv.h" +#include "drm_crtc_helper.h" #define MAX_NOPID ((u32)~0) @@ -471,8 +472,8 @@ static void i915_hotplug_tv(struct drm_device *dev) goto unlock; status = output->funcs->detect(output); - drm_hotplug_stage_two(dev, output, - status == output_status_connected ? 1 : 0); + drm_helper_hotplug_stage_two(dev, output, + status == output_status_connected ? 1 : 0); unlock: mutex_unlock(&dev->mode_config.mutex); @@ -497,7 +498,7 @@ static void i915_hotplug_crt(struct drm_device *dev, bool isconnected) if (iout == 0) goto unlock; - drm_hotplug_stage_two(dev, output, isconnected); + drm_helper_hotplug_stage_two(dev, output, isconnected); unlock: mutex_unlock(&dev->mode_config.mutex); @@ -518,9 +519,9 @@ static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB) status = output->funcs->detect(output); if (status != output_status_connected) - drm_hotplug_stage_two(dev, output, false); + drm_helper_hotplug_stage_two(dev, output, false); else - drm_hotplug_stage_two(dev, output, true); + drm_helper_hotplug_stage_two(dev, output, true); intel_sdvo_set_hotplug(output, 1); -- cgit v1.2.3 From 98c5cf7f6fc51f1a8f5f90b3895009cd38dd8f22 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 30 May 2008 11:25:41 +1000 Subject: modesetting: reorganise out crtc/outputs are allocated. Use subclassing from the drivers to allocate the objects. This saves two objects being allocated for each crtc/output and generally makes exit paths cleaner. --- shared-core/i915_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index ccedc70e..abf916ed 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -461,7 +461,7 @@ static void i915_hotplug_tv(struct drm_device *dev) /* find the crt output */ list_for_each_entry(output, &dev->mode_config.output_list, head) { - iout = output->driver_private; + iout = to_intel_output(output); if (iout->type == INTEL_OUTPUT_TVOUT) break; else @@ -488,7 +488,7 @@ static void i915_hotplug_crt(struct drm_device *dev, bool isconnected) /* find the crt output */ list_for_each_entry(output, &dev->mode_config.output_list, head) { - iout = output->driver_private; + iout = to_intel_output(output); if (iout->type == INTEL_OUTPUT_ANALOG) break; else -- cgit v1.2.3 From fae2c17b313e2838652c32ea4a576172b4063639 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 30 May 2008 12:14:44 +1000 Subject: drm: add more encoder interfaces --- shared-core/drm.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index eb2033c7..6cb68685 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1026,9 +1026,11 @@ struct drm_mode_card_res { uint64_t fb_id_ptr; uint64_t crtc_id_ptr; uint64_t output_id_ptr; + uint64_t encoder_id_ptr; int count_fbs; int count_crtcs; int count_outputs; + int count_encoders; int min_width, max_width; int min_height, max_height; }; @@ -1051,6 +1053,15 @@ struct drm_mode_crtc { struct drm_mode_modeinfo mode; }; +struct drm_mode_get_encoder { + + uint32_t encoder_type; + uint32_t encoder_id; + + uint32_t crtcs; + uint32_t clones; +}; + #define DRM_MODE_OUTPUT_NONE 0 #define DRM_MODE_OUTPUT_DAC 1 #define DRM_MODE_OUTPUT_TMDS 2 @@ -1059,12 +1070,15 @@ struct drm_mode_crtc { struct drm_mode_get_output { + uint64_t encoders_ptr; uint64_t modes_ptr; uint64_t props_ptr; uint64_t prop_values_ptr; int count_modes; int count_props; + int count_encoders; + unsigned int output; /**< Id */ unsigned int crtc; /**< Id of crtc */ unsigned int output_type; @@ -1277,6 +1291,7 @@ struct drm_mode_hotplug { #define DRM_IOCTL_WAIT_HOTPLUG DRM_IOWR(0xAE, union drm_wait_hotplug) #define DRM_IOCTL_MODE_REPLACEFB DRM_IOWR(0xAF, struct drm_mode_fb_cmd) +#define DRM_IOCTL_MODE_GETENCODER DRM_IOWR(0xB0, struct drm_mode_get_encoder) /*@}*/ /** -- cgit v1.2.3 From 6aeef92c0cad784a5019ea90d97ab81f4e51fdd9 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 30 May 2008 13:57:27 +1000 Subject: drm: attach an encoder. Time to do some renaming on the connectors I think --- shared-core/drm.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 6cb68685..0005bb0b 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1062,8 +1062,14 @@ struct drm_mode_get_encoder { uint32_t clones; }; +#define DRM_MODE_ENCODER_NONE 0 +#define DRM_MODE_ENCODER_DAC 1 +#define DRM_MODE_ENCODER_TMDS 2 +#define DRM_MODE_ENCODER_LVDS 3 +#define DRM_MODE_ENCODER_TVDAC 4 + #define DRM_MODE_OUTPUT_NONE 0 -#define DRM_MODE_OUTPUT_DAC 1 +#define DRM_MODE_OUTPUT_VGA 1 #define DRM_MODE_OUTPUT_TMDS 2 #define DRM_MODE_OUTPUT_LVDS 3 #define DRM_MODE_OUTPUT_TVDAC 4 -- cgit v1.2.3 From 9d38448ed33aaff324cc4bbe1e0878593e97d07d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 30 May 2008 15:03:12 +1000 Subject: modesetting: the great renaming. Okay we have crtc, encoder and connectors. No more outputs exposed beyond driver internals I've broken intel tv connector stuff. Really for TV we should have one TV connector, with a sub property for the type of signal been driven over it --- shared-core/drm.h | 40 +++++++++++++++++----------------------- shared-core/i915_irq.c | 46 +++++++++++++++++++++++----------------------- 2 files changed, 40 insertions(+), 46 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 0005bb0b..a7f590dc 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -558,7 +558,7 @@ union drm_wait_vblank { /* Handle monitor hotplug. * * May want to extend this later to pass reply information which - * details the outputs which generated the hotplug event. + * details the connectors which generated the hotplug event. * Some chipsets can't determine that though, and we'd need to leave * it to the higher levels to determine exactly what changed. */ @@ -998,7 +998,7 @@ struct drm_mm_info_arg { * Drm mode setting */ #define DRM_DISPLAY_INFO_LEN 32 -#define DRM_OUTPUT_NAME_LEN 32 +#define DRM_CONNECTOR_NAME_LEN 32 #define DRM_DISPLAY_MODE_LEN 32 #define DRM_PROP_NAME_LEN 32 @@ -1025,29 +1025,29 @@ struct drm_mode_modeinfo { struct drm_mode_card_res { uint64_t fb_id_ptr; uint64_t crtc_id_ptr; - uint64_t output_id_ptr; + uint64_t connector_id_ptr; uint64_t encoder_id_ptr; int count_fbs; int count_crtcs; - int count_outputs; + int count_connectors; int count_encoders; int min_width, max_width; int min_height, max_height; }; struct drm_mode_crtc { - uint64_t set_outputs_ptr; + uint64_t set_connectors_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_connectors; + unsigned int connectors; /**< Connectors that are connected */ int count_possibles; - unsigned int possibles; /**< Outputs that can be connected */ + unsigned int possibles; /**< Connectors that can be connected */ int gamma_size; int mode_valid; struct drm_mode_modeinfo mode; @@ -1068,13 +1068,7 @@ struct drm_mode_get_encoder { #define DRM_MODE_ENCODER_LVDS 3 #define DRM_MODE_ENCODER_TVDAC 4 -#define DRM_MODE_OUTPUT_NONE 0 -#define DRM_MODE_OUTPUT_VGA 1 -#define DRM_MODE_OUTPUT_TMDS 2 -#define DRM_MODE_OUTPUT_LVDS 3 -#define DRM_MODE_OUTPUT_TVDAC 4 - -struct drm_mode_get_output { +struct drm_mode_get_connector { uint64_t encoders_ptr; uint64_t modes_ptr; @@ -1085,10 +1079,10 @@ struct drm_mode_get_output { int count_props; int count_encoders; - unsigned int output; /**< Id */ + unsigned int connector; /**< Id */ unsigned int crtc; /**< Id of crtc */ - unsigned int output_type; - unsigned int output_type_id; + unsigned int connector_type; + unsigned int connector_type_id; unsigned int connection; unsigned int mm_width, mm_height; /**< HxW in millimeters */ @@ -1122,10 +1116,10 @@ struct drm_mode_get_property { int count_enum_blobs; }; -struct drm_mode_output_set_property { +struct drm_mode_connector_set_property { uint64_t value; unsigned int prop_id; - unsigned int output_id; + unsigned int connector_id; }; struct drm_mode_get_blob { @@ -1144,7 +1138,7 @@ struct drm_mode_fb_cmd { }; struct drm_mode_mode_cmd { - unsigned int output_id; + unsigned int connector_id; struct drm_mode_modeinfo mode; }; @@ -1280,13 +1274,13 @@ struct drm_mode_hotplug { #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_GETCONNECTOR DRM_IOWR(0xA2, struct drm_mode_get_connector) #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_SETPROPERTY DRM_IOWR(0xA7, struct drm_mode_connector_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) diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index abf916ed..4c147a08 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -453,15 +453,15 @@ static spinlock_t hotplug_lock = SPIN_LOCK_UNLOCKED; static void i915_hotplug_tv(struct drm_device *dev) { - struct drm_output *output; + struct drm_connector *connector; struct intel_output *iout; - enum drm_output_status status; + enum drm_connector_status status; mutex_lock(&dev->mode_config.mutex); /* find the crt output */ - list_for_each_entry(output, &dev->mode_config.output_list, head) { - iout = to_intel_output(output); + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + iout = to_intel_output(connector); if (iout->type == INTEL_OUTPUT_TVOUT) break; else @@ -471,9 +471,9 @@ static void i915_hotplug_tv(struct drm_device *dev) if (iout == 0) goto unlock; - status = output->funcs->detect(output); - drm_helper_hotplug_stage_two(dev, output, - status == output_status_connected ? 1 : 0); + status = connector->funcs->detect(connector); + drm_helper_hotplug_stage_two(dev, connector, + status == connector_status_connected ? 1 : 0); unlock: mutex_unlock(&dev->mode_config.mutex); @@ -481,14 +481,14 @@ unlock: static void i915_hotplug_crt(struct drm_device *dev, bool isconnected) { - struct drm_output *output; + struct drm_connector *connector; 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 = to_intel_output(output); + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + iout = to_intel_output(connector); if (iout->type == INTEL_OUTPUT_ANALOG) break; else @@ -498,7 +498,7 @@ static void i915_hotplug_crt(struct drm_device *dev, bool isconnected) if (iout == 0) goto unlock; - drm_helper_hotplug_stage_two(dev, output, isconnected); + drm_helper_hotplug_stage_two(dev, connector, isconnected); unlock: mutex_unlock(&dev->mode_config.mutex); @@ -506,24 +506,24 @@ unlock: static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB) { - struct drm_output *output = 0; - enum drm_output_status status; + struct drm_connector *connector = 0; + enum drm_connector_status status; mutex_lock(&dev->mode_config.mutex); - output = intel_sdvo_find(dev, sdvoB); + connector = intel_sdvo_find(dev, sdvoB); - if (!output) + if (!connector) goto unlock; - status = output->funcs->detect(output); + status = connector->funcs->detect(connector); - if (status != output_status_connected) - drm_helper_hotplug_stage_two(dev, output, false); + if (status != connector_status_connected) + drm_helper_hotplug_stage_two(dev, connector, false); else - drm_helper_hotplug_stage_two(dev, output, true); + drm_helper_hotplug_stage_two(dev, connector, true); - intel_sdvo_set_hotplug(output, 1); + intel_sdvo_set_hotplug(connector, 1); unlock: mutex_unlock(&dev->mode_config.mutex); @@ -961,15 +961,15 @@ void i915_disable_vblank(struct drm_device *dev, int plane) void i915_enable_interrupt (struct drm_device *dev) { struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; - struct drm_output *o; + struct drm_connector *o; dev_priv->irq_enable_reg |= I915_USER_INTERRUPT; if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { - if (dev->mode_config.num_output) + if (dev->mode_config.num_connector) dev_priv->irq_enable_reg |= I915_DISPLAY_PORT_INTERRUPT; } else { - if (dev->mode_config.num_output) + if (dev->mode_config.num_connector) dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; /* Enable global interrupts for hotplug - not a pipeA event */ -- cgit v1.2.3 From 5d47185eb69d73dd7e6ee3ddde4d0c7642c2d5b7 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 30 May 2008 15:32:58 +1000 Subject: drm: switch possible crtc/clones over to encoders --- shared-core/drm.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index a7f590dc..1fcbf144 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1087,10 +1087,6 @@ struct drm_mode_get_connector { 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) -- cgit v1.2.3 From e439e74776b215d70d8e34e8aa9cea22179dcbc6 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 2 Jun 2008 10:05:54 +1000 Subject: drm/modesetting: another re-org of some internals. Move dpms into the helper functions. Move crtc into the encoder. Move disable unused functions into the helper. --- shared-core/drm.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 1fcbf144..7e94fb82 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1058,6 +1058,7 @@ struct drm_mode_get_encoder { uint32_t encoder_type; uint32_t encoder_id; + unsigned int crtc; /**< Id of crtc */ uint32_t crtcs; uint32_t clones; }; @@ -1079,8 +1080,8 @@ struct drm_mode_get_connector { int count_props; int count_encoders; + unsigned int encoder; /**< Current Encoder */ unsigned int connector; /**< Id */ - unsigned int crtc; /**< Id of crtc */ unsigned int connector_type; unsigned int connector_type_id; -- cgit v1.2.3 From 4e7b24639808e5e1e2c05143028db1a3bc2812e9 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 2 Jun 2008 14:04:41 +1000 Subject: drm: add functions to get/set gamma ramps --- shared-core/drm.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 7e94fb82..132c7746 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1048,7 +1048,7 @@ struct drm_mode_crtc { int count_possibles; unsigned int possibles; /**< Connectors that can be connected */ - int gamma_size; + uint32_t gamma_size; int mode_valid; struct drm_mode_modeinfo mode; }; @@ -1173,6 +1173,16 @@ struct drm_mode_hotplug { uint32_t counter; }; +struct drm_mode_crtc_lut { + + uint32_t crtc_id; + uint32_t gamma_size; + + uint64_t red; + uint64_t green; + uint64_t blue; +}; + /** * \name Ioctls Definitions */ @@ -1289,6 +1299,9 @@ struct drm_mode_hotplug { #define DRM_IOCTL_MODE_REPLACEFB DRM_IOWR(0xAF, struct drm_mode_fb_cmd) #define DRM_IOCTL_MODE_GETENCODER DRM_IOWR(0xB0, struct drm_mode_get_encoder) +#define DRM_IOCTL_MODE_GETGAMMA DRM_IOWR(0xB1, struct drm_mode_crtc_lut) +#define DRM_IOCTL_MODE_SETGAMMA DRM_IOWR(0xB2, struct drm_mode_crtc_lut) + /*@}*/ /** -- cgit v1.2.3 From 382aa3ceeb79165a9bdddc8f944de131c8cbf2dd Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 4 Jun 2008 13:49:43 +1000 Subject: drm: introduce generation counter to interface. Idea being if you want to add new crtc/output/encoder dynamically later, you just increase the generation counter and userspace should re-read all the resources --- shared-core/drm.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 132c7746..40653b4b 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1033,6 +1033,7 @@ struct drm_mode_card_res { int count_encoders; int min_width, max_width; int min_height, max_height; + uint32_t generation; }; struct drm_mode_crtc { @@ -1043,6 +1044,8 @@ struct drm_mode_crtc { int x, y; /**< Position on the frameuffer */ + uint32_t generation; + int count_connectors; unsigned int connectors; /**< Connectors that are connected */ @@ -1055,6 +1058,8 @@ struct drm_mode_crtc { struct drm_mode_get_encoder { + uint32_t generation; + uint32_t encoder_type; uint32_t encoder_id; @@ -1085,6 +1090,8 @@ struct drm_mode_get_connector { unsigned int connector_type; unsigned int connector_type_id; + uint32_t generation; + unsigned int connection; unsigned int mm_width, mm_height; /**< HxW in millimeters */ unsigned int subpixel; -- cgit v1.2.3 From 967bd219116a4f20aec828b890a225d2f92afd0b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 5 Jun 2008 11:11:22 +1000 Subject: modesetting: initial attempt at debonging fb --- shared-core/i915_drv.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'shared-core') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index a54f5af9..34e81ad5 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -372,6 +372,8 @@ int i915_execbuffer(struct drm_device *dev, void *data, #endif +extern unsigned int i915_fbpercrtc; + #ifdef __linux__ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) extern void intel_init_chipset_flush_compat(struct drm_device *dev); -- cgit v1.2.3 From 25c1bb334f3a32e3e635e9d5de1abf8abdcc87f0 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 6 Jun 2008 10:38:35 +1000 Subject: drm/intel: make hotplug just be an event --- shared-core/i915_irq.c | 135 +------------------------------------------------ 1 file changed, 1 insertion(+), 134 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 4c147a08..2d355688 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -441,93 +441,8 @@ 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 -#define HOTPLUG_CMD_TV 16 - static struct drm_device *hotplug_dev; -static int hotplug_cmd = 0; -static spinlock_t hotplug_lock = SPIN_LOCK_UNLOCKED; - -static void i915_hotplug_tv(struct drm_device *dev) -{ - struct drm_connector *connector; - struct intel_output *iout; - enum drm_connector_status status; - - mutex_lock(&dev->mode_config.mutex); - - /* find the crt output */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - iout = to_intel_output(connector); - if (iout->type == INTEL_OUTPUT_TVOUT) - break; - else - iout = 0; - } - - if (iout == 0) - goto unlock; - - status = connector->funcs->detect(connector); - drm_helper_hotplug_stage_two(dev, connector, - status == connector_status_connected ? 1 : 0); - -unlock: - mutex_unlock(&dev->mode_config.mutex); -} - -static void i915_hotplug_crt(struct drm_device *dev, bool isconnected) -{ - struct drm_connector *connector; - struct intel_output *iout; - - mutex_lock(&dev->mode_config.mutex); - - /* find the crt output */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - iout = to_intel_output(connector); - if (iout->type == INTEL_OUTPUT_ANALOG) - break; - else - iout = 0; - } - - if (iout == 0) - goto unlock; - - drm_helper_hotplug_stage_two(dev, connector, isconnected); -unlock: - mutex_unlock(&dev->mode_config.mutex); -} - -static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB) -{ - struct drm_connector *connector = 0; - enum drm_connector_status status; - - mutex_lock(&dev->mode_config.mutex); - - connector = intel_sdvo_find(dev, sdvoB); - - if (!connector) - goto unlock; - - status = connector->funcs->detect(connector); - - if (status != connector_status_connected) - drm_helper_hotplug_stage_two(dev, connector, false); - else - drm_helper_hotplug_stage_two(dev, connector, true); - - intel_sdvo_set_hotplug(connector, 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. @@ -539,34 +454,8 @@ 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; - int tv; - - spin_lock(&hotplug_lock); - tv = hotplug_cmd & HOTPLUG_CMD_TV; - 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 (tv) - i915_hotplug_tv(dev); - 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); + drm_helper_hotplug_stage_two(dev); drm_handle_hotplug(dev); } @@ -583,40 +472,18 @@ static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat) if (stat & TV_HOTPLUG_INT_STATUS) { DRM_DEBUG("TV event\n"); - - spin_lock(&hotplug_lock); - hotplug_cmd |= HOTPLUG_CMD_TV; - spin_unlock(&hotplug_lock); } 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); -- cgit v1.2.3 From c2fc142ea7e9dd651702773efbc9c3366f977aa6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 6 Jun 2008 21:54:38 +0100 Subject: [intel] remove settable use_mi_batchbuffer_start The driver can know what hardware requires MI_BATCH_BUFFER vs MI_BATCH_BUFFER_START; there's no reason to let user mode configure this. --- shared-core/i915_dma.c | 22 ++++++++-------------- shared-core/i915_drv.h | 1 - shared-core/i915_init.c | 7 ------- 3 files changed, 8 insertions(+), 22 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 5e06fa6d..db857fbd 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -232,9 +232,6 @@ static int i915_initialize(struct drm_device * dev, /* We are using separate values as placeholders for mechanisms for * private backbuffer/depthbuffer usage. */ - dev_priv->use_mi_batchbuffer_start = 0; - if (IS_I965G(dev)) /* 965 doesn't support older method */ - dev_priv->use_mi_batchbuffer_start = 1; /* Allow hardware batchbuffers unless told otherwise. */ @@ -610,7 +607,14 @@ int i915_dispatch_batchbuffer(struct drm_device * dev, return ret; } - if (dev_priv->use_mi_batchbuffer_start) { + if (IS_I830(dev) || IS_845G(dev)) { + BEGIN_LP_RING(4); + OUT_RING(MI_BATCH_BUFFER); + OUT_RING(batch->start | MI_BATCH_NON_SECURE); + OUT_RING(batch->start + batch->used - 4); + OUT_RING(0); + ADVANCE_LP_RING(); + } else { BEGIN_LP_RING(2); if (IS_I965G(dev)) { OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); @@ -620,14 +624,6 @@ int i915_dispatch_batchbuffer(struct drm_device * dev, OUT_RING(batch->start | MI_BATCH_NON_SECURE); } ADVANCE_LP_RING(); - - } else { - BEGIN_LP_RING(4); - OUT_RING(MI_BATCH_BUFFER); - OUT_RING(batch->start | MI_BATCH_NON_SECURE); - OUT_RING(batch->start + batch->used - 4); - OUT_RING(0); - ADVANCE_LP_RING(); } } @@ -896,8 +892,6 @@ static int i915_setparam(struct drm_device *dev, void *data, switch (param->param) { case I915_SETPARAM_USE_MI_BATCHBUFFER_START: - if (!IS_I965G(dev)) - dev_priv->use_mi_batchbuffer_start = param->value; break; case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: dev_priv->tex_lru_log_granularity = param->value; diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 34e81ad5..6d72c051 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -132,7 +132,6 @@ struct drm_i915_private { struct drm_buffer_object *hws_bo; unsigned int cpp; - int use_mi_batchbuffer_start; wait_queue_head_t irq_queue; atomic_t irq_received; diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index f03f8949..f2c07fc6 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -151,13 +151,6 @@ int i915_load_modeset_init(struct drm_device *dev) I915_WRITE(PRB0_CTL, ((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; - if (IS_I965G(dev)) /* 965 doesn't support older method */ - dev_priv->use_mi_batchbuffer_start = 1; - /* Allow hardware batchbuffers unless told otherwise. */ dev_priv->allow_batchbuffer = 1; -- cgit v1.2.3 From 4a2e29bf9982165deeeabb5c585fc0a8a659f380 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 11 Jun 2008 15:59:01 -0700 Subject: Use GEM in modesetting Use GEM for ring buffer setup and framebuffer allocation. This means reworking the hardware status page stuff a bit (just use the basic range allocator for vram for now) and #ifdef'ing out the TTM & DRI2 code. Works well enough to load/unload several times and display fbcon on my T61 (though there's still some unexplained console corruption). --- shared-core/i915_dma.c | 39 +++++----- shared-core/i915_drv.h | 41 +++++----- shared-core/i915_init.c | 193 +++++++++++++++++++++++------------------------- 3 files changed, 129 insertions(+), 144 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 1e51e702..0cd920de 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -139,8 +139,8 @@ int i915_dma_cleanup(struct drm_device * dev) I915_WRITE(0x02080, 0x1ffff000); } - if (dev_priv->status_gfx_addr) { - dev_priv->status_gfx_addr = 0; + if (dev_priv->hws_agpoffset) { + dev_priv->hws_agpoffset = 0; drm_core_ioremapfree(&dev_priv->hws_map, dev); I915_WRITE(0x02080, 0x1ffff000); } @@ -148,7 +148,7 @@ int i915_dma_cleanup(struct drm_device * dev) return 0; } -#if defined(I915_HAVE_BUFFER) +#if defined(I915_HAVE_BUFFER) && defined(DRI2) #define DRI2_SAREA_BLOCK_TYPE(b) ((b) >> 16) #define DRI2_SAREA_BLOCK_SIZE(b) ((b) & 0xffff) #define DRI2_SAREA_BLOCK_NEXT(p) \ @@ -276,10 +276,10 @@ static int i915_initialize(struct drm_device * 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->hws_vaddr = 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); + memset(dev_priv->hws_vaddr, 0, PAGE_SIZE); I915_WRITE(0x02080, dev_priv->dma_status_page); } @@ -289,7 +289,7 @@ static int i915_initialize(struct drm_device * dev, if (!drm_core_check_feature(dev, DRIVER_MODESET)) { mutex_init(&dev_priv->cmdbuf_mutex); } - +#ifdef DRI2 if (init->func == I915_INIT_DMA2) { int ret = setup_dri2_sarea(dev, file_priv, init); if (ret) { @@ -298,7 +298,8 @@ static int i915_initialize(struct drm_device * dev, return ret; } } -#endif +#endif /* DRI2 */ +#endif /* I915_HAVE_BUFFER */ return 0; } @@ -319,16 +320,16 @@ static int i915_dma_resume(struct drm_device * dev) } /* Program Hardware Status Page */ - if (!dev_priv->hw_status_page) { + if (!dev_priv->hws_vaddr) { DRM_ERROR("Can not find hardware status page\n"); return -EINVAL; } - DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); + DRM_DEBUG("hw status page @ %p\n", dev_priv->hws_vaddr); - if (dev_priv->status_gfx_addr != 0) - I915_WRITE(0x02080, dev_priv->status_gfx_addr); + if (dev_priv->hws_agpoffset != 0) + I915_WRITE(HWS_PGA, dev_priv->hws_agpoffset); else - I915_WRITE(0x02080, dev_priv->dma_status_page); + I915_WRITE(HWS_PGA, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); return 0; @@ -1032,7 +1033,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr); - dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); + dev_priv->hws_agpoffset = hws->addr & (0x1ffff<<12); dev_priv->hws_map.offset = dev->agp->base + hws->addr; dev_priv->hws_map.size = 4*1024; @@ -1043,18 +1044,18 @@ static int i915_set_status_page(struct drm_device *dev, void *data, drm_core_ioremap(&dev_priv->hws_map, dev); if (dev_priv->hws_map.handle == NULL) { i915_dma_cleanup(dev); - dev_priv->status_gfx_addr = 0; + dev_priv->hws_agpoffset = 0; DRM_ERROR("can not ioremap virtual address for" " G33 hw status page\n"); return -ENOMEM; } - dev_priv->hw_status_page = dev_priv->hws_map.handle; + dev_priv->hws_vaddr = dev_priv->hws_map.handle; - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); + memset(dev_priv->hws_vaddr, 0, PAGE_SIZE); + I915_WRITE(HWS_PGA, dev_priv->hws_agpoffset); 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); + dev_priv->hws_agpoffset); + DRM_DEBUG("load hws at %p\n", dev_priv->hws_vaddr); return 0; } diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index cfb064ff..06aa00ab 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -115,8 +115,6 @@ struct drm_i915_master_private { struct drm_i915_private { struct drm_device *dev; - struct drm_buffer_object *ring_buffer; - drm_local_map_t *mmio_map; unsigned long mmiobase; @@ -125,12 +123,12 @@ struct drm_i915_private { 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; - unsigned int status_gfx_addr; + uint32_t hws_agpoffset; drm_local_map_t hws_map; - struct drm_buffer_object *hws_bo; + void *hws_vaddr; + struct drm_memrange_node *hws; unsigned int cpp; @@ -152,6 +150,8 @@ struct drm_i915_private { bool cursor_needs_physical; + struct drm_memrange vram; + #ifdef I915_HAVE_FENCE uint32_t flush_sequence; uint32_t flush_flags; @@ -176,17 +176,17 @@ struct drm_i915_private { struct drm_display_mode *panel_fixed_mode; struct drm_display_mode *vbt_mode; /* if any */ -#if defined(I915_HAVE_BUFFER) +#if defined(I915_HAVE_BUFFER) && defined(DRI2) /* DRI2 sarea */ - struct drm_buffer_object *sarea_bo; - struct drm_bo_kmap_obj sarea_kmap; + struct drm_gem_object *sarea_object; + struct drm_bo_kmap_obj sarea_kmap; +#endif /* Feature bits from the VBIOS */ int int_tv_support:1; int lvds_dither:1; int lvds_vbt:1; int int_crt_support:1; -#endif struct { struct drm_memrange gtt_space; @@ -483,7 +483,7 @@ extern void i915_invalidate_reported_sequence(struct drm_device *dev); #endif -#ifdef I915_HAVE_BUFFER +#if defined(I915_HAVE_BUFFER) && defined(I915_TTM) /* i915_buffer.c */ extern struct drm_ttm_backend *i915_create_ttm_backend_entry(struct drm_device *dev); extern int i915_fence_type(struct drm_buffer_object *bo, uint32_t *fclass, @@ -495,6 +495,8 @@ extern uint64_t i915_evict_flags(struct drm_buffer_object *bo); extern int i915_move(struct drm_buffer_object *bo, int evict, int no_wait, struct drm_bo_mem_reg *new_mem); void i915_flush_ttm(struct drm_ttm *ttm); +#endif /* ttm */ +#ifdef I915_HAVE_BUFFER /* i915_execbuf.c */ int i915_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -530,6 +532,9 @@ void i915_gem_retire_requests(struct drm_device *dev); void i915_gem_retire_timeout(unsigned long data); void i915_gem_retire_handler(struct work_struct *work); int i915_gem_init_ringbuffer(struct drm_device *dev); +void i915_gem_cleanup_ringbuffer(struct drm_device *dev); +int i915_gem_do_init(struct drm_device *dev, unsigned long start, + unsigned long end); #endif extern unsigned int i915_fbpercrtc; @@ -596,12 +601,6 @@ void i915_ring_validate(struct drm_device *dev, const char *func, int line); I915_WRITE(PRB0_TAIL, outring); \ } while(0) -#define BREADCRUMB_BITS 31 -#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1) - -#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5]) -#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) - extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); /* @@ -713,7 +712,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define BREADCRUMB_BITS 31 #define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1) -#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5]) +#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hws_vaddr))[5]) /** * Reads a dword out of the status page, which is written to from the command @@ -728,7 +727,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); * * The area from dword 0x10 to 0x3ff is available for driver usage. */ -#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) +#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hws_vaddr))[reg]) #define I915_GEM_HWS_INDEX 0x10 /* @@ -986,12 +985,6 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define ADPA_DPMS_STANDBY (2<<10) #define ADPA_DPMS_OFF (3<<10) -#define LP_RING 0x2030 -#define HP_RING 0x2040 -/* The binner has its own ring buffer: - */ -#define HWB_RING 0x2400 - #define RING_TAIL 0x00 #define TAIL_ADDR 0x001FFFF8 #define RING_HEAD 0x04 diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index ba02f485..3f310770 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -100,24 +100,11 @@ int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size, return 0; } -int i915_load_modeset_init(struct drm_device *dev) +static int i915_init_hwstatus(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long agp_size, prealloc_size; - int size, ret = 0; - - 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)); - ret = i915_gem_init_ringbuffer(dev); - if (ret) - goto out; - - /* Allow hardware batchbuffers unless told otherwise. - */ - dev_priv->allow_batchbuffer = 1; - dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS; - mutex_init(&dev_priv->cmdbuf_mutex); + struct drm_memrange_node *free_space; + int ret = 0; /* Program Hardware Status Page */ if (!IS_G33(dev)) { @@ -127,52 +114,105 @@ int i915_load_modeset_init(struct drm_device *dev) if (!dev_priv->status_page_dmah) { DRM_ERROR("Can not allocate hardware status page\n"); ret = -ENOMEM; - goto destroy_ringbuffer; + goto out; } - dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; + dev_priv->hws_vaddr = 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(HWS_PGA, dev_priv->dma_status_page); } else { - size = 4 * 1024; - 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->hws_bo); - if (ret < 0) { + free_space = drm_memrange_search_free(&dev_priv->vram, + PAGE_SIZE, + PAGE_SIZE, 0); + if (!free_space) { + DRM_ERROR("No free vram available, aborting\n"); + ret = -ENOMEM; + goto out; + } + + dev_priv->hws = drm_memrange_get_block(free_space, PAGE_SIZE, + PAGE_SIZE); + if (!dev_priv->hws) { DRM_ERROR("Unable to allocate or pin hw status page\n"); ret = -EINVAL; - goto destroy_ringbuffer; + goto out; } - dev_priv->status_gfx_addr = - dev_priv->hws_bo->offset & (0x1ffff << 12); + dev_priv->hws_agpoffset = dev_priv->hws->start; dev_priv->hws_map.offset = dev->agp->base + - dev_priv->hws_bo->offset; - dev_priv->hws_map.size = size; + dev_priv->hws->start; + dev_priv->hws_map.size = PAGE_SIZE; dev_priv->hws_map.type= 0; dev_priv->hws_map.flags= 0; dev_priv->hws_map.mtrr = 0; drm_core_ioremap(&dev_priv->hws_map, dev); if (dev_priv->hws_map.handle == NULL) { - dev_priv->status_gfx_addr = 0; + dev_priv->hws_agpoffset = 0; DRM_ERROR("can not ioremap virtual addr for" "G33 hw status page\n"); ret = -ENOMEM; - goto destroy_hws; + goto out_free; } - dev_priv->hw_status_page = dev_priv->hws_map.handle; - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); + dev_priv->hws_vaddr = dev_priv->hws_map.handle; + I915_WRITE(HWS_PGA, dev_priv->hws_agpoffset); } + + memset(dev_priv->hws_vaddr, 0, PAGE_SIZE); + DRM_DEBUG("Enabled hardware status page\n"); + return 0; + +out_free: + /* free hws */ +out: + return ret; +} + +static void i915_cleanup_hwstatus(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (!IS_G33(dev)) { + if (dev_priv->status_page_dmah) + drm_pci_free(dev, dev_priv->status_page_dmah); + } else { + if (dev_priv->hws_map.handle) + drm_core_ioremapfree(&dev_priv->hws_map, dev); + if (dev_priv->hws) + drm_memrange_put_block(dev_priv->hws); + } + I915_WRITE(HWS_PGA, 0x1ffff000); +} + +static int i915_load_modeset_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long agp_size, prealloc_size; + int ret = 0; + + i915_probe_agp(dev->pdev, &agp_size, &prealloc_size); + + /* Basic memrange allocator for stolen space (aka vram) */ + drm_memrange_init(&dev_priv->vram, 0, prealloc_size); + /* Let GEM Manage from end of prealloc space to end of aperture */ + i915_gem_do_init(dev, prealloc_size, agp_size); + + ret = i915_gem_init_ringbuffer(dev); + if (ret) + goto out; + + ret = i915_init_hwstatus(dev); + if (ret) + goto destroy_ringbuffer; + + /* Allow hardware batchbuffers unless told otherwise. + */ + dev_priv->allow_batchbuffer = 1; + dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS; + mutex_init(&dev_priv->cmdbuf_mutex); + dev_priv->wq = create_singlethread_workqueue("i915"); if (dev_priv->wq == 0) { DRM_DEBUG("Error\n"); @@ -208,22 +248,9 @@ modeset_cleanup: destroy_wq: destroy_workqueue(dev_priv->wq); destroy_hws: - if (!IS_G33(dev)) { - if (dev_priv->status_page_dmah) - drm_pci_free(dev, dev_priv->status_page_dmah); - } else { - if (dev_priv->hws_map.handle) - drm_core_ioremapfree(&dev_priv->hws_map, dev); - if (dev_priv->hws_bo) - drm_bo_usage_deref_unlocked(&dev_priv->hws_bo); - } - I915_WRITE(HWS_PGA, 0x1ffff000); + i915_cleanup_hwstatus(dev); destroy_ringbuffer: - if (dev_priv->ring.virtual_start) - drm_mem_reg_iounmap(dev, &dev_priv->ring_buffer->mem, - dev_priv->ring.virtual_start); - if (dev_priv->ring_buffer) - drm_bo_usage_deref_unlocked(&dev_priv->ring_buffer); + i915_gem_cleanup_ringbuffer(dev); out: return ret; } @@ -318,26 +345,14 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) #endif if (drm_core_check_feature(dev, DRIVER_MODESET)) { - /* - * Initialize the memory manager for local and AGP space - */ - ret = drm_bo_driver_init(dev); - if (ret) { - DRM_ERROR("fail to init memory manager for " - "local & AGP space\n"); - goto out_rmmap; - } - ret = i915_load_modeset_init(dev); if (ret < 0) { DRM_ERROR("failed to init modeset\n"); - goto driver_fini; + goto out_rmmap; } } return 0; -driver_fini: - drm_bo_driver_finish(dev); out_rmmap: drm_rmmap(dev, dev_priv->mmio_map); free_priv: @@ -362,6 +377,8 @@ int i915_driver_unload(struct drm_device *dev) drm_core_ioremapfree(&dev_priv->ring.map, dev); } #endif + +#ifdef DRI2 if (dev_priv->sarea_kmap.virtual) { drm_bo_kunmap(&dev_priv->sarea_kmap); dev_priv->sarea_kmap.virtual = NULL; @@ -374,44 +391,17 @@ int i915_driver_unload(struct drm_device *dev) 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(HWS_PGA, 0x1ffff000); - } - - if (dev_priv->status_gfx_addr) { - dev_priv->status_gfx_addr = 0; - drm_core_ioremapfree(&dev_priv->hws_map, dev); - drm_bo_usage_deref_unlocked(&dev_priv->hws_bo); - I915_WRITE(HWS_PGA, 0x1ffff000); - } +#endif + i915_cleanup_hwstatus(dev); if (drm_core_check_feature(dev, DRIVER_MODESET)) { - 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"); - } + i915_gem_cleanup_ringbuffer(dev); mutex_unlock(&dev->struct_mutex); + drm_memrange_takedown(&dev_priv->vram); + i915_gem_lastclose(dev); } - drm_bo_driver_finish(dev); - #ifdef __linux__ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) intel_init_chipset_flush_compat(dev); @@ -493,7 +483,7 @@ void i915_driver_lastclose(struct drm_device * dev) if (dev_priv->agp_heap) i915_mem_takedown(&(dev_priv->agp_heap)); -#if defined(I915_HAVE_BUFFER) +#if defined(DRI2) if (dev_priv->sarea_kmap.virtual) { drm_bo_kunmap(&dev_priv->sarea_kmap); dev_priv->sarea_kmap.virtual = NULL; @@ -516,7 +506,8 @@ int i915_driver_firstopen(struct drm_device *dev) { if (drm_core_check_feature(dev, DRIVER_MODESET)) return 0; - +#if defined(I915_HAVE_BUFFER) && defined(I915_TTM) drm_bo_driver_init(dev); +#endif return 0; } -- cgit v1.2.3 From 473a1997ace1a9fb545d0457549e50d17eb36175 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Sun, 22 Jun 2008 16:29:00 +0200 Subject: NV50: Initial import of kernel modesetting. --- shared-core/nouveau_dma.h | 5 + shared-core/nouveau_drv.h | 26 ++++ shared-core/nouveau_irq.c | 80 +++++++++++- shared-core/nouveau_mem.c | 11 ++ shared-core/nouveau_reg.h | 298 ++++++++++++++++++++++++++++++++++++++++++++ shared-core/nouveau_state.c | 50 +++++++- 6 files changed, 465 insertions(+), 5 deletions(-) (limited to 'shared-core') diff --git a/shared-core/nouveau_dma.h b/shared-core/nouveau_dma.h index ce3c58cb..07652c2b 100644 --- a/shared-core/nouveau_dma.h +++ b/shared-core/nouveau_dma.h @@ -93,4 +93,9 @@ typedef enum { } \ } while(0) +/* This should allow easy switching to a real fifo in the future. */ +#define OUT_MODE(mthd, val) do { \ + nv50_display_command(dev_priv, mthd, val); \ +} while(0) + #endif diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index a51e552c..20aa6b86 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -41,6 +41,9 @@ #include "nouveau_drm.h" #include "nouveau_reg.h" +#include "nouveau_bios.h" + +#define MAX_NUM_DCB_ENTRIES 16 struct mem_block { struct mem_block *next; @@ -310,6 +313,28 @@ struct drm_nouveau_private { struct nouveau_config config; struct list_head gpuobj_list; + + void *display_priv; /* internal modesetting */ + void *kms_priv; /* related to public interface */ + + /* Hook these up to the "public interface" to accomodate a certain allocation style. */ + /* This is to avoid polluting the internal interface. */ + void *(*alloc_crtc) (struct drm_device *dev); + void *(*alloc_output) (struct drm_device *dev); + void *(*alloc_connector) (struct drm_device *dev); + + void (*free_crtc) (void *crtc); + void (*free_output) (void *output); + void (*free_connector) (void *connector); + + struct bios bios; + + struct { + int entries; + struct dcb_entry entry[MAX_NUM_DCB_ENTRIES]; + unsigned char i2c_read[MAX_NUM_DCB_ENTRIES]; + unsigned char i2c_write[MAX_NUM_DCB_ENTRIES]; + } dcb_table; }; #define NOUVEAU_CHECK_INITIALISED_WITH_RETURN do { \ @@ -353,6 +378,7 @@ extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *, struct drm_file *); extern void nouveau_mem_takedown(struct mem_block **heap); extern void nouveau_mem_free_block(struct mem_block *); +extern struct mem_block* find_block_by_handle(struct mem_block *heap, drm_handle_t handle); extern uint64_t nouveau_mem_fb_amount(struct drm_device *); extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap); extern int nouveau_ioctl_mem_alloc(struct drm_device *, void *data, diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index 2a3d8a0b..e68b755f 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -37,6 +37,11 @@ #include "nouveau_reg.h" #include "nouveau_swmthd.h" +/* needed for interrupt based vpll changes */ +#include "nv50_display.h" +#include "nv50_crtc.h" +#include "nv50_output.h" + void nouveau_irq_preinstall(struct drm_device *dev) { @@ -503,11 +508,82 @@ static void nouveau_nv50_display_irq_handler(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t val = NV_READ(NV50_DISPLAY_SUPERVISOR); + uint32_t val = NV_READ(NV50_PDISPLAY_SUPERVISOR); DRM_INFO("NV50_DISPLAY_INTR - 0x%08X\n", val); - NV_WRITE(NV50_DISPLAY_SUPERVISOR, val); + /* vblank interrupts */ + if (val & NV50_PDISPLAY_SUPERVISOR_CRTCn) { + NV_WRITE(NV50_PDISPLAY_SUPERVISOR, val & NV50_PDISPLAY_SUPERVISOR_CRTCn); + val &= ~NV50_PDISPLAY_SUPERVISOR_CRTCn; + } + + /* clock setting amongst other things. */ + if (val & NV50_PDISPLAY_SUPERVISOR_CLK_MASK) { + uint32_t state = (val & NV50_PDISPLAY_SUPERVISOR_CLK_MASK) >> NV50_PDISPLAY_SUPERVISOR_CLK_MASK__SHIFT; + + NV50_DEBUG("state %d\n", state); + + /* Set pll */ + if (state == 2) { + struct nv50_display *display = nv50_get_display(dev); + struct nv50_output *output = NULL; + struct nv50_crtc *crtc = NULL; + int crtc_index; + + uint32_t unk30 = NV_READ(NV50_PDISPLAY_UNK30_CTRL); + + for (crtc_index = 0; crtc_index < 2; crtc_index++) { + bool clock_change = false; + bool clock_ack = false; + + if (crtc_index == 0 && (unk30 & NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK0)) + clock_change = true; + + if (crtc_index == 1 && (unk30 & NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK1)) + clock_change = true; + + if (clock_change) + clock_ack = true; + + if (display->last_crtc == crtc_index) + clock_ack = true; + + list_for_each_entry(crtc, &display->crtcs, head) { + if (crtc->index == crtc_index) + break; + } + + if (clock_change) + crtc->set_clock(crtc); + + NV50_DEBUG("index %d clock_change %d clock_ack %d\n", crtc_index, clock_change, clock_ack); + + if (!clock_ack) + continue; + + crtc->set_clock_mode(crtc); + + list_for_each_entry(output, &display->outputs, head) { + if (!output->crtc) + continue; + + if (output->crtc == crtc) + output->set_clock_mode(output); + } + } + } + + NV_WRITE(NV50_PDISPLAY_UNK30_CTRL, NV50_PDISPLAY_UNK30_CTRL_PENDING); + NV_WRITE(NV50_PDISPLAY_SUPERVISOR, val & NV50_PDISPLAY_SUPERVISOR_CLK_MASK); + + val &= ~NV50_PDISPLAY_SUPERVISOR_CLK_MASK; + } + + if (val) + DRM_ERROR("unsupported NV50_DISPLAY_INTR - 0x%08X\n", val); + + NV_WRITE(NV50_PDISPLAY_SUPERVISOR, val); } static void diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 2cf8807d..810eaf9e 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -108,6 +108,17 @@ static struct mem_block *find_block(struct mem_block *heap, uint64_t start) return NULL; } +struct mem_block *find_block_by_handle(struct mem_block *heap, drm_handle_t handle) +{ + struct mem_block *p; + + list_for_each(p, heap) + if (p->map_handle == handle) + return p; + + return NULL; +} + void nouveau_mem_free_block(struct mem_block *p) { p->file_priv = NULL; diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h index 1ae0177c..8cf7f889 100644 --- a/shared-core/nouveau_reg.h +++ b/shared-core/nouveau_reg.h @@ -116,6 +116,9 @@ #define NV04_PBUS_PCI_NV_1 0x00001804 #define NV04_PBUS_PCI_NV_19 0x0000184C +#define NV04_PBUS_PCI_NV_20 0x00001850 +# define NV04_PBUS_PCI_NV_20_ROM_SHADOW_DISABLED (0 << 0) +# define NV04_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED (1 << 0) #define NV04_PTIMER_INTR_0 0x00009100 #define NV04_PTIMER_INTR_EN_0 0x00009140 @@ -542,6 +545,8 @@ /* This name is a partial guess. */ #define NV50_DISPLAY_SUPERVISOR 0x00610024 +#define NV04_PRAMIN 0x00700000 + /* Fifo commands. These are not regs, neither masks */ #define NV03_FIFO_CMD_JUMP 0x20000000 #define NV03_FIFO_CMD_JUMP_OFFSET_MASK 0x1ffffffc @@ -591,3 +596,296 @@ #define NV40_RAMFC_UNK_48 0x48 #define NV40_RAMFC_UNK_4C 0x4C #define NV40_RAMFC_UNK_50 0x50 + +/* This is a partial import from rules-ng, a few things may be duplicated. + * Eventually we should completely import everything from rules-ng. + * For the moment check rules-ng for docs. + */ + +#define NV50_PMC 0x00000000 +#define NV50_PMC__LEN 0x1 +#define NV50_PMC__ESIZE 0x2000 +# define NV50_PMC_BOOT_0 0x00000000 +# define NV50_PMC_BOOT_0_REVISION 0x000000ff +# define NV50_PMC_BOOT_0_REVISION__SHIFT 0 +# define NV50_PMC_BOOT_0_ARCH 0x0ff00000 +# define NV50_PMC_BOOT_0_ARCH__SHIFT 20 +# define NV50_PMC_INTR_0 0x00000100 +# define NV50_PMC_INTR_0_PFIFO (1<<8) +# define NV50_PMC_INTR_0_PGRAPH (1<<12) +# define NV50_PMC_INTR_0_PTIMER (1<<20) +# define NV50_PMC_INTR_0_HOTPLUG (1<<21) +# define NV50_PMC_INTR_0_DISPLAY (1<<26) +# define NV50_PMC_INTR_EN_0 0x00000140 +# define NV50_PMC_INTR_EN_0_MASTER (1<<0) +# define NV50_PMC_INTR_EN_0_MASTER_DISABLED (0<<0) +# define NV50_PMC_INTR_EN_0_MASTER_ENABLED (1<<0) +# define NV50_PMC_ENABLE 0x00000200 +# define NV50_PMC_ENABLE_PFIFO (1<<8) +# define NV50_PMC_ENABLE_PGRAPH (1<<12) + +#define NV50_PCONNECTOR 0x0000e000 +#define NV50_PCONNECTOR__LEN 0x1 +#define NV50_PCONNECTOR__ESIZE 0x1000 +# define NV50_PCONNECTOR_HOTPLUG_INTR 0x0000e050 +# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C0 (1<<0) +# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C1 (1<<1) +# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C2 (1<<2) +# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C3 (1<<3) +# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C4 (1<<4) +# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C5 (1<<5) +# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C6 (1<<6) +# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C7 (1<<7) +# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C8 (1<<8) +# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C9 (1<<9) +# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C10 (1<<10) +# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C11 (1<<11) +# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C12 (1<<12) +# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C13 (1<<13) +# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C14 (1<<14) +# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C15 (1<<15) +# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C0 (1<<16) +# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C1 (1<<17) +# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C2 (1<<18) +# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C3 (1<<19) +# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C4 (1<<20) +# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C5 (1<<21) +# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C6 (1<<22) +# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C7 (1<<23) +# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C8 (1<<24) +# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C9 (1<<25) +# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C10 (1<<26) +# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C11 (1<<27) +# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C12 (1<<28) +# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C13 (1<<29) +# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C14 (1<<30) +# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C15 (1<<31) +# define NV50_PCONNECTOR_HOTPLUG_CTRL 0x0000e054 +# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C0 (1<<0) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C1 (1<<1) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C2 (1<<2) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C3 (1<<3) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C4 (1<<4) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C5 (1<<5) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C6 (1<<6) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C7 (1<<7) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C8 (1<<8) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C9 (1<<9) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C10 (1<<10) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C11 (1<<11) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C12 (1<<12) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C13 (1<<13) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C14 (1<<14) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C15 (1<<15) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C0 (1<<16) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C1 (1<<17) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C2 (1<<18) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C3 (1<<19) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C4 (1<<20) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C5 (1<<21) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C6 (1<<22) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C7 (1<<23) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C8 (1<<24) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C9 (1<<25) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C10 (1<<26) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C11 (1<<27) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C12 (1<<28) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C13 (1<<29) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C14 (1<<30) +# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C15 (1<<31) +# define NV50_PCONNECTOR_HOTPLUG_STATE1 0x0000e104 +# define NV50_PCONNECTOR_HOTPLUG_STATE1_PIN_CONNECTED_I2C0 (1<<2) +# define NV50_PCONNECTOR_HOTPLUG_STATE1_PIN_CONNECTED_I2C1 (1<<6) +# define NV50_PCONNECTOR_HOTPLUG_STATE1_PIN_CONNECTED_I2C2 (1<<10) +# define NV50_PCONNECTOR_HOTPLUG_STATE1_PIN_CONNECTED_I2C3 (1<<14) +# define NV50_PCONNECTOR_HOTPLUG_STATE1_PIN_CONNECTED_I2C4 (1<<18) +# define NV50_PCONNECTOR_HOTPLUG_STATE1_PIN_CONNECTED_I2C5 (1<<22) +# define NV50_PCONNECTOR_HOTPLUG_STATE1_PIN_CONNECTED_I2C6 (1<<26) +# define NV50_PCONNECTOR_HOTPLUG_STATE1_PIN_CONNECTED_I2C7 (1<<30) +# define NV50_PCONNECTOR_HOTPLUG_STATE2 0x0000e108 +# define NV50_PCONNECTOR_HOTPLUG_STATE2_PIN_CONNECTED_I2C8 (1<<2) +# define NV50_PCONNECTOR_HOTPLUG_STATE2_PIN_CONNECTED_I2C9 (1<<6) +# define NV50_PCONNECTOR_HOTPLUG_STATE2_PIN_CONNECTED_I2C10 (1<<10) +# define NV50_PCONNECTOR_HOTPLUG_STATE2_PIN_CONNECTED_I2C11 (1<<14) +# define NV50_PCONNECTOR_HOTPLUG_STATE2_PIN_CONNECTED_I2C12 (1<<18) +# define NV50_PCONNECTOR_HOTPLUG_STATE2_PIN_CONNECTED_I2C13 (1<<22) +# define NV50_PCONNECTOR_HOTPLUG_STATE2_PIN_CONNECTED_I2C14 (1<<26) +# define NV50_PCONNECTOR_HOTPLUG_STATE2_PIN_CONNECTED_I2C15 (1<<30) +# define NV50_PCONNECTOR_I2C 0x0000e138 +# define NV50_PCONNECTOR_I2C__LEN 0x10 +# define NV50_PCONNECTOR_I2C__ESIZE 0x18 +# define NV50_PCONNECTOR_I2C_PORT(i) (0x0000e138+(i)*0x18) + + +#define NV50_PBUS 0x00088000 +#define NV50_PBUS__LEN 0x1 +#define NV50_PBUS__ESIZE 0x1000 +# define NV50_PBUS_PCI_ID 0x00088000 +# define NV50_PBUS_PCI_ID_VENDOR_ID 0x0000ffff +# define NV50_PBUS_PCI_ID_VENDOR_ID__SHIFT 0 +# define NV50_PBUS_PCI_ID_DEVICE_ID 0xffff0000 +# define NV50_PBUS_PCI_ID_DEVICE_ID__SHIFT 16 + +#define NV50_PFB 0x00100000 +#define NV50_PFB__LEN 0x1 +#define NV50_PFB__ESIZE 0x1000 + +#define NV50_PEXTDEV 0x00101000 +#define NV50_PEXTDEV__LEN 0x1 +#define NV50_PEXTDEV__ESIZE 0x1000 + +#define NV50_PROM 0x00300000 +#define NV50_PROM__LEN 0x1 +#define NV50_PROM__ESIZE 0x10000 + +#define NV50_PGRAPH 0x00400000 +#define NV50_PGRAPH__LEN 0x1 +#define NV50_PGRAPH__ESIZE 0x10000 + +#define NV50_PDISPLAY 0x00610000 +#define NV50_PDISPLAY__LEN 0x1 +#define NV50_PDISPLAY__ESIZE 0x10000 +# define NV50_PDISPLAY_SUPERVISOR 0x00610024 +# define NV50_PDISPLAY_SUPERVISOR_CRTCn 0x0000000c +# define NV50_PDISPLAY_SUPERVISOR_CRTCn__SHIFT 2 +# define NV50_PDISPLAY_SUPERVISOR_CRTC0 (1<<2) +# define NV50_PDISPLAY_SUPERVISOR_CRTC1 (1<<3) +# define NV50_PDISPLAY_SUPERVISOR_CLK_MASK 0x00000070 +# define NV50_PDISPLAY_SUPERVISOR_CLK_MASK__SHIFT 4 +# define NV50_PDISPLAY_SUPERVISOR_CLK_UPDATE (1<<5) +# define NV50_PDISPLAY_SUPERVISOR_INTR 0x0061002c +# define NV50_PDISPLAY_SUPERVISOR_INTR_VBLANK_CRTC0 (1<<2) +# define NV50_PDISPLAY_SUPERVISOR_INTR_VBLANK_CRTC1 (1<<3) +# define NV50_PDISPLAY_SUPERVISOR_INTR_UNK1 (1<<4) +# define NV50_PDISPLAY_SUPERVISOR_INTR_CLK_UPDATE (1<<5) +# define NV50_PDISPLAY_SUPERVISOR_INTR_UNK4 (1<<6) +# define NV50_PDISPLAY_UNK30_CTRL 0x00610030 +# define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK0 (1<<9) +# define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK1 (1<<10) +# define NV50_PDISPLAY_UNK30_CTRL_PENDING (1<<31) +# define NV50_PDISPLAY_UNK50_CTRL 0x00610050 +# define NV50_PDISPLAY_UNK50_CTRL_CRTC0_ACTIVE (1<<1) +# define NV50_PDISPLAY_UNK50_CTRL_CRTC0_ACTIVE_MASK 0x00000003 +# define NV50_PDISPLAY_UNK50_CTRL_CRTC0_ACTIVE_MASK__SHIFT 0 +# define NV50_PDISPLAY_UNK50_CTRL_CRTC1_ACTIVE (1<<9) +# define NV50_PDISPLAY_UNK50_CTRL_CRTC1_ACTIVE_MASK 0x00000300 +# define NV50_PDISPLAY_UNK50_CTRL_CRTC1_ACTIVE_MASK__SHIFT 8 +# define NV50_PDISPLAY_UNK200_CTRL 0x00610200 +# define NV50_PDISPLAY_CURSOR 0x00610270 +# define NV50_PDISPLAY_CURSOR__LEN 0x2 +# define NV50_PDISPLAY_CURSOR__ESIZE 0x10 +# define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i) (0x00610270+(i)*0x10) +# define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON (1<<0) +# define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_MASK 0x00030000 +# define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_MASK__SHIFT 16 +# define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE (1<<16) + +# define NV50_PDISPLAY_CTRL_STATE 0x00610300 +# define NV50_PDISPLAY_CTRL_STATE_ENABLE (1<<0) +# define NV50_PDISPLAY_CTRL_STATE_PENDING (1<<31) +# define NV50_PDISPLAY_CTRL_VAL 0x00610304 +# define NV50_PDISPLAY_UNK_380 0x00610380 +# define NV50_PDISPLAY_RAM_AMOUNT 0x00610384 +# define NV50_PDISPLAY_UNK_388 0x00610388 +# define NV50_PDISPLAY_UNK_38C 0x0061038c +# define NV50_PDISPLAY_CRTC_VAL 0x00610a00 +# define NV50_PDISPLAY_CRTC_VAL__LEN 0x2 +# define NV50_PDISPLAY_CRTC_VAL_UNK_900(i,j) (0x00610a18+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_CLUT_MODE(i,j) (0x00610a24+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_INTERLACE(i,j) (0x00610a48+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_SCALE_CTRL(i,j) (0x00610a50+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_CURSOR_CTRL(i,j) (0x00610a58+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_UNK_904(i,j) (0x00610ab8+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_DEPTH(i,j) (0x00610ac8+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_CLOCK(i,j) (0x00610ad0+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_COLOR_CTRL(i,j) (0x00610ae0+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_SYNC_START_TO_BLANK_END(i,j) (0x00610ae8+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_MODE_UNK1(i,j) (0x00610af0+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_DISPLAY_TOTAL(i,j) (0x00610af8+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_SYNC_DURATION(i,j) (0x00610b00+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_MODE_UNK2(i,j) (0x00610b08+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_UNK_828(i,j) (0x00610b10+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_FB_SIZE(i,j) (0x00610b18+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_FB_PITCH(i,j) (0x00610b20+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_FB_PITCH_LINEAR_FB (1<<20) +# define NV50_PDISPLAY_CRTC_VAL_FB_POS(i,j) (0x00610b28+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_SCALE_CENTER_OFFSET(i,j) (0x00610b38+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_REAL_RES(i,j) (0x00610b40+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_SCALE_RES1(i,j) (0x00610b48+(i)*0x540+(j)*0x4) +# define NV50_PDISPLAY_CRTC_VAL_SCALE_RES2(i,j) (0x00610b50+(i)*0x540+(j)*0x4) + + +# define NV50_PDISPLAY_DAC_VAL_MODE_CTRL(i,j) (0x00610b58+(i)*0x8+(j)*0x4) + + +# define NV50_PDISPLAY_SOR_VAL_MODE_CTRL(i,j) (0x00610b70+(i)*0x8+(j)*0x4) + + +# define NV50_PDISPLAY_DAC_VAL_MODE_CTRL2(i,j) (0x00610bdc+(i)*0x8+(j)*0x4) + + +# define NV50_PDISPLAY_CRTC_CLK 0x00614000 +# define NV50_PDISPLAY_CRTC_CLK__LEN 0x2 +# define NV50_PDISPLAY_CRTC_CLK_CLK_CTRL1(i) (0x00614100+(i)*0x800) +# define NV50_PDISPLAY_CRTC_CLK_CLK_CTRL1_CONNECTED 0x00000600 +# define NV50_PDISPLAY_CRTC_CLK_CLK_CTRL1_CONNECTED__SHIFT 9 +# define NV50_PDISPLAY_CRTC_CLK_VPLL_A(i) (0x00614104+(i)*0x800) +# define NV50_PDISPLAY_CRTC_CLK_VPLL_B(i) (0x00614108+(i)*0x800) +# define NV50_PDISPLAY_CRTC_CLK_CLK_CTRL2(i) (0x00614200+(i)*0x800) + +# define NV50_PDISPLAY_DAC_CLK 0x00614000 +# define NV50_PDISPLAY_DAC_CLK__LEN 0x3 +# define NV50_PDISPLAY_DAC_CLK_CLK_CTRL2(i) (0x00614280+(i)*0x800) + +# define NV50_PDISPLAY_SOR_CLK 0x00614000 +# define NV50_PDISPLAY_SOR_CLK__LEN 0x3 +# define NV50_PDISPLAY_SOR_CLK_CLK_CTRL2(i) (0x00614300+(i)*0x800) + +# define NV50_PDISPLAY_DAC_REGS 0x0061a000 +# define NV50_PDISPLAY_DAC_REGS__LEN 0x3 +# define NV50_PDISPLAY_DAC_REGS__ESIZE 0x800 +# define NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(i) (0x0061a004+(i)*0x800) +# define NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_HSYNC_OFF (1<<0) +# define NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_VSYNC_OFF (1<<2) +# define NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_BLANKED (1<<4) +# define NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_OFF (1<<6) +# define NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_PENDING (1<<31) +# define NV50_PDISPLAY_DAC_REGS_LOAD_CTRL(i) (0x0061a00c+(i)*0x800) +# define NV50_PDISPLAY_DAC_REGS_LOAD_CTRL_ACTIVE (1<<20) +# define NV50_PDISPLAY_DAC_REGS_LOAD_CTRL_PRESENT 0x38000000 +# define NV50_PDISPLAY_DAC_REGS_LOAD_CTRL_PRESENT__SHIFT 29 +# define NV50_PDISPLAY_DAC_REGS_LOAD_CTRL_DONE (1<<31) +# define NV50_PDISPLAY_DAC_REGS_CLK_CTRL1(i) (0x0061a010+(i)*0x800) +# define NV50_PDISPLAY_DAC_REGS_CLK_CTRL1_CONNECTED 0x00000600 +# define NV50_PDISPLAY_DAC_REGS_CLK_CTRL1_CONNECTED__SHIFT 9 + +# define NV50_PDISPLAY_SOR_REGS 0x0061c000 +# define NV50_PDISPLAY_SOR_REGS__LEN 0x2 +# define NV50_PDISPLAY_SOR_REGS__ESIZE 0x800 +# define NV50_PDISPLAY_SOR_REGS_DPMS_CTRL(i) (0x0061c004+(i)*0x800) +# define NV50_PDISPLAY_SOR_REGS_DPMS_CTRL_ON (1<<0) +# define NV50_PDISPLAY_SOR_REGS_DPMS_CTRL_PENDING (1<<31) +# define NV50_PDISPLAY_SOR_REGS_CLK_CTRL1(i) (0x0061c008+(i)*0x800) +# define NV50_PDISPLAY_SOR_REGS_CLK_CTRL1_CONNECTED 0x00000600 +# define NV50_PDISPLAY_SOR_REGS_CLK_CTRL1_CONNECTED__SHIFT 9 +# define NV50_PDISPLAY_SOR_REGS_UNK_00C(i) (0x0061c00c+(i)*0x800) +# define NV50_PDISPLAY_SOR_REGS_UNK_010(i) (0x0061c010+(i)*0x800) +# define NV50_PDISPLAY_SOR_REGS_UNK_014(i) (0x0061c014+(i)*0x800) +# define NV50_PDISPLAY_SOR_REGS_UNK_018(i) (0x0061c018+(i)*0x800) +# define NV50_PDISPLAY_SOR_REGS_DPMS_STATE(i) (0x0061c030+(i)*0x800) +# define NV50_PDISPLAY_SOR_REGS_DPMS_STATE_ACTIVE 0x00030000 +# define NV50_PDISPLAY_SOR_REGS_DPMS_STATE_ACTIVE__SHIFT 16 +# define NV50_PDISPLAY_SOR_REGS_DPMS_STATE_BLANKED (1<<19) +# define NV50_PDISPLAY_SOR_REGS_DPMS_STATE_WAIT (1<<28) + + +#define NV50_UNK640000 0x00640000 +#define NV50_UNK640000__LEN 0x6 +#define NV50_UNK640000__ESIZE 0x1000 +# define NV50_UNK640000_UNK_000(i) (0x00640000+(i)*0x1000) + +#define NV50_HW_CURSOR 0x00647000 +#define NV50_HW_CURSOR__LEN 0x2 +#define NV50_HW_CURSOR__ESIZE 0x1000 +# define NV50_HW_CURSOR_POS_CTRL(i) (0x00647080+(i)*0x1000) +# define NV50_HW_CURSOR_POS(i) (0x00647084+(i)*0x1000) diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index d9c6efe7..82591c64 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -27,6 +27,7 @@ #include "drm_sarea.h" #include "nouveau_drv.h" #include "nouveau_drm.h" +#include "nv50_kms_wrapper.h" static int nouveau_init_card_mappings(struct drm_device *dev) { @@ -362,6 +363,13 @@ nouveau_card_init(struct drm_device *dev) if (ret) return ret; dev_priv->init_state = NOUVEAU_CARD_INIT_DONE; + + if (drm_core_check_feature(dev, DRIVER_MODESET)) + if (dev_priv->card_type >= NV_50) { + nv50_kms_init(dev); + nv50_kms_connector_detect_all(dev); + } + return 0; } @@ -410,8 +418,7 @@ void nouveau_preclose(struct drm_device *dev, struct drm_file *file_priv) nouveau_mem_release(file_priv,dev_priv->pci_heap); } -/* first module load, setup the mmio/fb mapping */ -int nouveau_firstopen(struct drm_device *dev) +int nouveau_setup_mappings(struct drm_device *dev) { #if defined(__powerpc__) struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -457,6 +464,16 @@ int nouveau_firstopen(struct drm_device *dev) return 0; } +/* first module load, setup the mmio/fb mapping */ +/* KMS: we need mmio at load time, not when the first drm client opens. */ +int nouveau_firstopen(struct drm_device *dev) +{ + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + + return nouveau_setup_mappings(dev); +} + #define NV40_CHIPSET_MASK 0x00000baf #define NV44_CHIPSET_MASK 0x00005450 @@ -549,10 +566,23 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) dev->dev_private = (void *)dev_priv; + /* init card now, otherwise bad things happen */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + int rval = 0; + + rval = nouveau_setup_mappings(dev); + if (rval != 0) + return rval; + + rval = nouveau_card_init(dev); + if (rval != 0) + return rval; + } + return 0; } -void nouveau_lastclose(struct drm_device *dev) +void nouveau_close(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -568,8 +598,22 @@ void nouveau_lastclose(struct drm_device *dev) } } +/* KMS: we need mmio at load time, not when the first drm client opens. */ +void nouveau_lastclose(struct drm_device *dev) +{ + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return; + + nouveau_close(dev); +} + int nouveau_unload(struct drm_device *dev) { + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + nv50_kms_destroy(dev); + nouveau_close(dev); + } + drm_free(dev->dev_private, sizeof(*dev->dev_private), DRM_MEM_DRIVER); dev->dev_private = NULL; return 0; -- cgit v1.2.3 From 30f153a7c2a9bc69e615b7fff3fb060af0e3ed83 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Sun, 22 Jun 2008 19:31:55 +0200 Subject: nouveau: disable KMS for pre-NV50 even when specifically enabled --- shared-core/nouveau_state.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'shared-core') diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index 82591c64..9f8fc43d 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -557,6 +557,10 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) return -EINVAL; } + /* For those who think they want to be funny. */ + if (dev_priv->card_type < NV_50) + dev->driver->driver_features &= ~DRIVER_MODESET; + /* Special flags */ if (dev->pci_device == 0x01a0) { dev_priv->flags |= NV_NFORCE; -- cgit v1.2.3 From 5a0164d1e1799b68b3131efd7b9fcaf20c578257 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 23 Jun 2008 01:00:42 +1000 Subject: nouveau: allocate drm-use vram buffers from end of vram. This avoids seeing garbage from engine setup etc before X gets around to pointing the CRTCs at a new scanout buffer. Not actually a noticable problem before G80 as PRAMIN is forced to the end of VRAM by the hardware already. --- shared-core/nouveau_drm.h | 4 ++- shared-core/nouveau_drv.h | 2 +- shared-core/nouveau_mem.c | 58 ++++++++++++++++++++++++++---------------- shared-core/nouveau_notifier.c | 2 +- shared-core/nouveau_object.c | 2 +- 5 files changed, 42 insertions(+), 26 deletions(-) (limited to 'shared-core') diff --git a/shared-core/nouveau_drm.h b/shared-core/nouveau_drm.h index cf762052..bbb51bc4 100644 --- a/shared-core/nouveau_drm.h +++ b/shared-core/nouveau_drm.h @@ -88,9 +88,11 @@ struct drm_nouveau_gpuobj_free { #define NOUVEAU_MEM_INSTANCE 0x00000200 /* internal */ #define NOUVEAU_MEM_NOTIFIER 0x00000400 /* internal */ #define NOUVEAU_MEM_NOVM 0x00000800 /* internal */ +#define NOUVEAU_MEM_USER 0x00001000 /* internal */ #define NOUVEAU_MEM_INTERNAL (NOUVEAU_MEM_INSTANCE | \ NOUVEAU_MEM_NOTIFIER | \ - NOUVEAU_MEM_NOVM) + NOUVEAU_MEM_NOVM | \ + NOUVEAU_MEM_USER) struct drm_nouveau_mem_alloc { int flags; diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 20aa6b86..33e2a5b6 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -375,7 +375,7 @@ extern int nouveau_mem_init_heap(struct mem_block **, uint64_t start, uint64_t size); extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *, uint64_t size, int align2, - struct drm_file *); + struct drm_file *, int tail); extern void nouveau_mem_takedown(struct mem_block **heap); extern void nouveau_mem_free_block(struct mem_block *); extern struct mem_block* find_block_by_handle(struct mem_block *heap, drm_handle_t handle); diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 810eaf9e..51ac48dd 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -35,8 +35,9 @@ #include "drm_sarea.h" #include "nouveau_drv.h" -static struct mem_block *split_block(struct mem_block *p, uint64_t start, uint64_t size, - struct drm_file *file_priv) +static struct mem_block * +split_block(struct mem_block *p, uint64_t start, uint64_t size, + struct drm_file *file_priv) { /* Maybe cut off the start of an existing block */ if (start > p->start) { @@ -77,10 +78,9 @@ out: return p; } -struct mem_block *nouveau_mem_alloc_block(struct mem_block *heap, - uint64_t size, - int align2, - struct drm_file *file_priv) +struct mem_block * +nouveau_mem_alloc_block(struct mem_block *heap, uint64_t size, + int align2, struct drm_file *file_priv, int tail) { struct mem_block *p; uint64_t mask = (1 << align2) - 1; @@ -88,10 +88,22 @@ struct mem_block *nouveau_mem_alloc_block(struct mem_block *heap, if (!heap) return NULL; - list_for_each(p, heap) { - uint64_t start = (p->start + mask) & ~mask; - if (p->file_priv == 0 && start + size <= p->start + p->size) - return split_block(p, start, size, file_priv); + if (tail) { + list_for_each_prev(p, heap) { + uint64_t start = ((p->start + p->size) - size) & ~mask; + + if (p->file_priv == 0 && start >= p->start && + start + size <= p->start + p->size) + return split_block(p, start, size, file_priv); + } + } else { + list_for_each(p, heap) { + uint64_t start = (p->start + mask) & ~mask; + + if (p->file_priv == 0 && + start + size <= p->start + p->size) + return split_block(p, start, size, file_priv); + } } return NULL; @@ -574,13 +586,13 @@ int nouveau_mem_init(struct drm_device *dev) return 0; } -struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, - uint64_t size, int flags, - struct drm_file *file_priv) +struct mem_block * +nouveau_mem_alloc(struct drm_device *dev, int alignment, uint64_t size, + int flags, struct drm_file *file_priv) { - struct mem_block *block; - int type; struct drm_nouveau_private *dev_priv = dev->dev_private; + struct mem_block *block; + int type, tail = !(flags & NOUVEAU_MEM_USER); /* * Make things easier on ourselves: all allocations are page-aligned. @@ -611,14 +623,14 @@ struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, #define NOUVEAU_MEM_ALLOC_AGP {\ type=NOUVEAU_MEM_AGP;\ block = nouveau_mem_alloc_block(dev_priv->agp_heap, size,\ - alignment, file_priv); \ + alignment, file_priv, tail); \ if (block) goto alloc_ok;\ } #define NOUVEAU_MEM_ALLOC_PCI {\ type = NOUVEAU_MEM_PCI;\ block = nouveau_mem_alloc_block(dev_priv->pci_heap, size, \ - alignment, file_priv); \ + alignment, file_priv, tail); \ if ( block ) goto alloc_ok;\ } @@ -627,11 +639,11 @@ struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, if (!(flags&NOUVEAU_MEM_MAPPED)) {\ block = nouveau_mem_alloc_block(dev_priv->fb_nomap_heap,\ size, alignment, \ - file_priv); \ + file_priv, tail); \ if (block) goto alloc_ok;\ }\ block = nouveau_mem_alloc_block(dev_priv->fb_heap, size,\ - alignment, file_priv);\ + alignment, file_priv, tail);\ if (block) goto alloc_ok;\ } @@ -749,7 +761,9 @@ out_free: * Ioctls */ -int nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) +int +nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, + struct drm_file *file_priv) { struct drm_nouveau_mem_alloc *alloc = data; struct mem_block *block; @@ -759,8 +773,8 @@ int nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, struct drm_file if (alloc->flags & NOUVEAU_MEM_INTERNAL) return -EINVAL; - block=nouveau_mem_alloc(dev, alloc->alignment, alloc->size, - alloc->flags, file_priv); + block = nouveau_mem_alloc(dev, alloc->alignment, alloc->size, + alloc->flags | NOUVEAU_MEM_USER, file_priv); if (!block) return -ENOMEM; alloc->map_handle=block->map_handle; diff --git a/shared-core/nouveau_notifier.c b/shared-core/nouveau_notifier.c index 82c8ab7d..edece4da 100644 --- a/shared-core/nouveau_notifier.c +++ b/shared-core/nouveau_notifier.c @@ -94,7 +94,7 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, } mem = nouveau_mem_alloc_block(chan->notifier_heap, count*32, 0, - (struct drm_file *)-2); + (struct drm_file *)-2, 0); if (!mem) { DRM_ERROR("Channel %d notifier block full\n", chan->id); return -ENOMEM; diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index 09f9027a..5664bfc8 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -248,7 +248,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, /* Allocate a chunk of the PRAMIN aperture */ gpuobj->im_pramin = nouveau_mem_alloc_block(pramin, size, drm_order(align), - (struct drm_file *)-2); + (struct drm_file *)-2, 0); if (!gpuobj->im_pramin) { nouveau_gpuobj_del(dev, &gpuobj); return -ENOMEM; -- cgit v1.2.3 From be7276281694145e7c947b91a1c8e6e347de666c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 25 Jun 2008 16:45:41 +1000 Subject: nv50: when destroying a channel make sure it's not still current on PFIFO We won't get a PFIFO context switch when the same channel ID is recreated if the hw still thinks the channel is already active, which causes fun issues. Should allow X to be stopped and started without tearing down the entire card state in lastclose(). --- shared-core/nv50_fifo.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'shared-core') diff --git a/shared-core/nv50_fifo.c b/shared-core/nv50_fifo.c index edf4edbf..d6810666 100644 --- a/shared-core/nv50_fifo.c +++ b/shared-core/nv50_fifo.c @@ -289,6 +289,7 @@ void nv50_fifo_destroy_context(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; DRM_DEBUG("ch%d\n", chan->id); @@ -298,6 +299,9 @@ nv50_fifo_destroy_context(struct nouveau_channel *chan) if (chan->id == 0) nv50_fifo_channel_disable(dev, 127, 0); + if ((NV_READ(NV03_PFIFO_CACHE1_PUSH1) & 0xffff) == chan->id) + NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, 127); + nouveau_gpuobj_ref_del(dev, &chan->ramfc); } -- cgit v1.2.3 From 09b67dda0bc040860aedce4a2d28bce1c80e56d6 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Wed, 25 Jun 2008 15:16:38 +0200 Subject: NV50: Some cleanup and fixes. --- shared-core/nouveau_mem.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'shared-core') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 51ac48dd..4acd6bd6 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -34,6 +34,8 @@ #include "drm.h" #include "drm_sarea.h" #include "nouveau_drv.h" +#include "nv50_kms_wrapper.h" + static struct mem_block * split_block(struct mem_block *p, uint64_t start, uint64_t size, @@ -730,6 +732,33 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) DRM_DEBUG("freeing 0x%llx type=0x%08x\n", block->start, block->flags); + /* Check if the deallocations cause problems for our modesetting system. */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + if (dev_priv->card_type >= NV_50) { + struct nv50_crtc *crtc = NULL; + struct nv50_display *display = nv50_get_display(dev); + + list_for_each_entry(crtc, &display->crtcs, head) { + if (crtc->fb->block == block) { + crtc->fb->block = NULL; + + /* this will force a lut change next time a fb is loaded */ + crtc->lut->depth = 0; + + if (!crtc->blanked) + crtc->blank(crtc, TRUE); + } + + if (crtc->cursor->block == block) { + crtc->cursor->block = NULL; + + if (crtc->cursor->visible) + crtc->cursor->hide(crtc); + } + } + } + } + if (block->flags&NOUVEAU_MEM_MAPPED) drm_rmmap(dev, block->map); -- cgit v1.2.3 From 4d85d5d25116304e476849ee64c206ffb3a7f372 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Wed, 25 Jun 2008 15:27:07 +0200 Subject: NV50: i misunderstood NOUVEAU_MEM_INTERNAL, so remove it --- shared-core/nouveau_mem.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'shared-core') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 4acd6bd6..46b6e4d6 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -742,9 +742,6 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) if (crtc->fb->block == block) { crtc->fb->block = NULL; - /* this will force a lut change next time a fb is loaded */ - crtc->lut->depth = 0; - if (!crtc->blanked) crtc->blank(crtc, TRUE); } -- cgit v1.2.3 From 91c742663a618e81da69ad4f098321d9af56d636 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Fri, 27 Jun 2008 18:58:13 +0200 Subject: NV50: use list_head item instead of list_head head to avoid confusion --- shared-core/nouveau_irq.c | 4 ++-- shared-core/nouveau_mem.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'shared-core') diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index e68b755f..4c46da8d 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -549,7 +549,7 @@ nouveau_nv50_display_irq_handler(struct drm_device *dev) if (display->last_crtc == crtc_index) clock_ack = true; - list_for_each_entry(crtc, &display->crtcs, head) { + list_for_each_entry(crtc, &display->crtcs, item) { if (crtc->index == crtc_index) break; } @@ -564,7 +564,7 @@ nouveau_nv50_display_irq_handler(struct drm_device *dev) crtc->set_clock_mode(crtc); - list_for_each_entry(output, &display->outputs, head) { + list_for_each_entry(output, &display->outputs, item) { if (!output->crtc) continue; diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 46b6e4d6..425cebe2 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -738,7 +738,7 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) struct nv50_crtc *crtc = NULL; struct nv50_display *display = nv50_get_display(dev); - list_for_each_entry(crtc, &display->crtcs, head) { + list_for_each_entry(crtc, &display->crtcs, item) { if (crtc->fb->block == block) { crtc->fb->block = NULL; -- cgit v1.2.3 From bc32d1798a213d7701b20feb95781eb51a42e945 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Tue, 1 Jul 2008 15:14:30 +0200 Subject: NV50: some i2c cleanup --- shared-core/nouveau_reg.h | 82 +++++++---------------------------------------- 1 file changed, 11 insertions(+), 71 deletions(-) (limited to 'shared-core') diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h index 8cf7f889..6ed23e26 100644 --- a/shared-core/nouveau_reg.h +++ b/shared-core/nouveau_reg.h @@ -632,90 +632,30 @@ # define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C1 (1<<1) # define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C2 (1<<2) # define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C3 (1<<3) -# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C4 (1<<4) -# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C5 (1<<5) -# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C6 (1<<6) -# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C7 (1<<7) -# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C8 (1<<8) -# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C9 (1<<9) -# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C10 (1<<10) -# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C11 (1<<11) -# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C12 (1<<12) -# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C13 (1<<13) -# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C14 (1<<14) -# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C15 (1<<15) # define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C0 (1<<16) # define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C1 (1<<17) # define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C2 (1<<18) # define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C3 (1<<19) -# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C4 (1<<20) -# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C5 (1<<21) -# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C6 (1<<22) -# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C7 (1<<23) -# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C8 (1<<24) -# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C9 (1<<25) -# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C10 (1<<26) -# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C11 (1<<27) -# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C12 (1<<28) -# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C13 (1<<29) -# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C14 (1<<30) -# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C15 (1<<31) # define NV50_PCONNECTOR_HOTPLUG_CTRL 0x0000e054 # define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C0 (1<<0) # define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C1 (1<<1) # define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C2 (1<<2) # define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C3 (1<<3) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C4 (1<<4) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C5 (1<<5) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C6 (1<<6) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C7 (1<<7) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C8 (1<<8) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C9 (1<<9) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C10 (1<<10) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C11 (1<<11) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C12 (1<<12) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C13 (1<<13) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C14 (1<<14) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C15 (1<<15) # define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C0 (1<<16) # define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C1 (1<<17) # define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C2 (1<<18) # define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C3 (1<<19) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C4 (1<<20) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C5 (1<<21) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C6 (1<<22) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C7 (1<<23) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C8 (1<<24) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C9 (1<<25) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C10 (1<<26) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C11 (1<<27) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C12 (1<<28) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C13 (1<<29) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C14 (1<<30) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C15 (1<<31) -# define NV50_PCONNECTOR_HOTPLUG_STATE1 0x0000e104 -# define NV50_PCONNECTOR_HOTPLUG_STATE1_PIN_CONNECTED_I2C0 (1<<2) -# define NV50_PCONNECTOR_HOTPLUG_STATE1_PIN_CONNECTED_I2C1 (1<<6) -# define NV50_PCONNECTOR_HOTPLUG_STATE1_PIN_CONNECTED_I2C2 (1<<10) -# define NV50_PCONNECTOR_HOTPLUG_STATE1_PIN_CONNECTED_I2C3 (1<<14) -# define NV50_PCONNECTOR_HOTPLUG_STATE1_PIN_CONNECTED_I2C4 (1<<18) -# define NV50_PCONNECTOR_HOTPLUG_STATE1_PIN_CONNECTED_I2C5 (1<<22) -# define NV50_PCONNECTOR_HOTPLUG_STATE1_PIN_CONNECTED_I2C6 (1<<26) -# define NV50_PCONNECTOR_HOTPLUG_STATE1_PIN_CONNECTED_I2C7 (1<<30) -# define NV50_PCONNECTOR_HOTPLUG_STATE2 0x0000e108 -# define NV50_PCONNECTOR_HOTPLUG_STATE2_PIN_CONNECTED_I2C8 (1<<2) -# define NV50_PCONNECTOR_HOTPLUG_STATE2_PIN_CONNECTED_I2C9 (1<<6) -# define NV50_PCONNECTOR_HOTPLUG_STATE2_PIN_CONNECTED_I2C10 (1<<10) -# define NV50_PCONNECTOR_HOTPLUG_STATE2_PIN_CONNECTED_I2C11 (1<<14) -# define NV50_PCONNECTOR_HOTPLUG_STATE2_PIN_CONNECTED_I2C12 (1<<18) -# define NV50_PCONNECTOR_HOTPLUG_STATE2_PIN_CONNECTED_I2C13 (1<<22) -# define NV50_PCONNECTOR_HOTPLUG_STATE2_PIN_CONNECTED_I2C14 (1<<26) -# define NV50_PCONNECTOR_HOTPLUG_STATE2_PIN_CONNECTED_I2C15 (1<<30) -# define NV50_PCONNECTOR_I2C 0x0000e138 -# define NV50_PCONNECTOR_I2C__LEN 0x10 -# define NV50_PCONNECTOR_I2C__ESIZE 0x18 -# define NV50_PCONNECTOR_I2C_PORT(i) (0x0000e138+(i)*0x18) - +# define NV50_PCONNECTOR_HOTPLUG_STATE 0x0000e104 +# define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C0 (1<<2) +# define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C1 (1<<6) +# define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C2 (1<<10) +# define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C3 (1<<14) +# define NV50_PCONNECTOR_I2C_PORT_0 0x0000e138 +# define NV50_PCONNECTOR_I2C_PORT_1 0x0000e150 +# define NV50_PCONNECTOR_I2C_PORT_2 0x0000e168 +# define NV50_PCONNECTOR_I2C_PORT_3 0x0000e180 +# define NV50_PCONNECTOR_I2C_PORT_4 0x0000e240 +# define NV50_PCONNECTOR_I2C_PORT_5 0x0000e258 #define NV50_PBUS 0x00088000 #define NV50_PBUS__LEN 0x1 -- cgit v1.2.3 From f1fe9178f1a2aef272c7feeb15c8de42c8c609d5 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Wed, 2 Jul 2008 16:13:54 +0200 Subject: NV50: basic fbcon + misc fixes - There is one fb, used for as many outputs as possible. - Eventually smaller screens will be scaled to see the full console, but for the moment this'll do. --- shared-core/nouveau_state.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index 9f8fc43d..3baae6ad 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -28,6 +28,7 @@ #include "nouveau_drv.h" #include "nouveau_drm.h" #include "nv50_kms_wrapper.h" +#include "nv50_fbcon.h" static int nouveau_init_card_mappings(struct drm_device *dev) { @@ -367,7 +368,8 @@ nouveau_card_init(struct drm_device *dev) if (drm_core_check_feature(dev, DRIVER_MODESET)) if (dev_priv->card_type >= NV_50) { nv50_kms_init(dev); - nv50_kms_connector_detect_all(dev); + //nv50_kms_connector_detect_all(dev); + nv50_fbcon_init(dev); } return 0; @@ -615,6 +617,7 @@ int nouveau_unload(struct drm_device *dev) { if (drm_core_check_feature(dev, DRIVER_MODESET)) { nv50_kms_destroy(dev); + nv50_fbcon_destroy(dev); nouveau_close(dev); } -- cgit v1.2.3 From 062d85062061199f2326982e27d54955a4ad76dc Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Thu, 3 Jul 2008 09:08:01 +0200 Subject: nv50: s/FALSE/false && s/TRUE/true --- shared-core/nouveau_mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 425cebe2..861d699f 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -743,7 +743,7 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) crtc->fb->block = NULL; if (!crtc->blanked) - crtc->blank(crtc, TRUE); + crtc->blank(crtc, true); } if (crtc->cursor->block == block) { -- cgit v1.2.3 From 142a309604b65c26ca95594943ee91dde8688697 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 4 Jul 2008 09:34:24 +1000 Subject: modesetting: rip out all of the generation code. not needed, hotplug will work just as well hopefully. --- shared-core/drm.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 40653b4b..132c7746 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1033,7 +1033,6 @@ struct drm_mode_card_res { int count_encoders; int min_width, max_width; int min_height, max_height; - uint32_t generation; }; struct drm_mode_crtc { @@ -1044,8 +1043,6 @@ struct drm_mode_crtc { int x, y; /**< Position on the frameuffer */ - uint32_t generation; - int count_connectors; unsigned int connectors; /**< Connectors that are connected */ @@ -1058,8 +1055,6 @@ struct drm_mode_crtc { struct drm_mode_get_encoder { - uint32_t generation; - uint32_t encoder_type; uint32_t encoder_id; @@ -1090,8 +1085,6 @@ struct drm_mode_get_connector { unsigned int connector_type; unsigned int connector_type_id; - uint32_t generation; - unsigned int connection; unsigned int mm_width, mm_height; /**< HxW in millimeters */ unsigned int subpixel; -- cgit v1.2.3 From c9915d695dad8e4f75b4f551f9f78ff3d64dc666 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Fri, 4 Jul 2008 17:28:04 +0200 Subject: modesetting-101: Move some defines used for enumeration into the public header. - Otherwise userspace has no idea of the meaning. --- shared-core/drm.h | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 5 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 132c7746..c9b40e78 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1010,6 +1010,28 @@ struct drm_mm_info_arg { #define DRM_MODE_TYPE_USERDEF (1<<5) #define DRM_MODE_TYPE_DRIVER (1<<6) +/* Video mode flags */ +#define V_PHSYNC (1<<0) +#define V_NHSYNC (1<<1) +#define V_PVSYNC (1<<2) +#define V_NVSYNC (1<<3) +#define V_INTERLACE (1<<4) +#define V_DBLSCAN (1<<5) +#define V_CSYNC (1<<6) +#define V_PCSYNC (1<<7) +#define V_NCSYNC (1<<8) +#define V_HSKEW (1<<9) /* hskew provided */ +#define V_BCAST (1<<10) +#define V_PIXMUX (1<<11) +#define V_DBLCLK (1<<12) +#define V_CLKDIV2 (1<<13) + +/* DPMS flags */ +#define DPMSModeOn 0 +#define DPMSModeStandby 1 +#define DPMSModeSuspend 2 +#define DPMSModeOff 3 + struct drm_mode_modeinfo { unsigned int clock; unsigned short hdisplay, hsync_start, hsync_end, htotal, hskew; @@ -1053,6 +1075,12 @@ struct drm_mode_crtc { struct drm_mode_modeinfo mode; }; +#define DRM_MODE_ENCODER_NONE 0 +#define DRM_MODE_ENCODER_DAC 1 +#define DRM_MODE_ENCODER_TMDS 2 +#define DRM_MODE_ENCODER_LVDS 3 +#define DRM_MODE_ENCODER_TVDAC 4 + struct drm_mode_get_encoder { uint32_t encoder_type; @@ -1063,11 +1091,29 @@ struct drm_mode_get_encoder { uint32_t clones; }; -#define DRM_MODE_ENCODER_NONE 0 -#define DRM_MODE_ENCODER_DAC 1 -#define DRM_MODE_ENCODER_TMDS 2 -#define DRM_MODE_ENCODER_LVDS 3 -#define DRM_MODE_ENCODER_TVDAC 4 +/* This is for connectors with multiple signal types. */ +/* Try to match DRM_MODE_CONNECTOR_X as closely as possible. */ +#define DRM_MODE_SUBCONNECTOR_Automatic 0 +#define DRM_MODE_SUBCONNECTOR_Unknown 0 +#define DRM_MODE_SUBCONNECTOR_DVID 3 +#define DRM_MODE_SUBCONNECTOR_DVIA 4 +#define DRM_MODE_SUBCONNECTOR_Composite 5 +#define DRM_MODE_SUBCONNECTOR_SVIDEO 6 +#define DRM_MODE_SUBCONNECTOR_Component 8 + +#define DRM_MODE_CONNECTOR_Unknown 0 +#define DRM_MODE_CONNECTOR_VGA 1 +#define DRM_MODE_CONNECTOR_DVII 2 +#define DRM_MODE_CONNECTOR_DVID 3 +#define DRM_MODE_CONNECTOR_DVIA 4 +#define DRM_MODE_CONNECTOR_Composite 5 +#define DRM_MODE_CONNECTOR_SVIDEO 6 +#define DRM_MODE_CONNECTOR_LVDS 7 +#define DRM_MODE_CONNECTOR_Component 8 +#define DRM_MODE_CONNECTOR_9PinDIN 9 +#define DRM_MODE_CONNECTOR_DisplayPort 10 +#define DRM_MODE_CONNECTOR_HDMIA 11 +#define DRM_MODE_CONNECTOR_HDMIB 12 struct drm_mode_get_connector { -- cgit v1.2.3 From 7cbc5f6145046f3775e3b3ca2862bfb71831ec44 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Sat, 5 Jul 2008 12:04:07 +0200 Subject: modesetting-101: Make the interface variable names a little more consistent + modeprint changes. - All things are now called _id when they are id's. - modeprint now accepts driver name as first argument. --- shared-core/drm.h | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index c9b40e78..b64e265d 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1059,17 +1059,13 @@ struct drm_mode_card_res { struct drm_mode_crtc { uint64_t set_connectors_ptr; + int count_connectors; unsigned int crtc_id; /**< Id */ unsigned int fb_id; /**< Id of framebuffer */ int x, y; /**< Position on the frameuffer */ - int count_connectors; - unsigned int connectors; /**< Connectors that are connected */ - - int count_possibles; - unsigned int possibles; /**< Connectors that can be connected */ uint32_t gamma_size; int mode_valid; struct drm_mode_modeinfo mode; @@ -1083,12 +1079,13 @@ struct drm_mode_crtc { struct drm_mode_get_encoder { - uint32_t encoder_type; - uint32_t encoder_id; + unsigned int encoder_type; + unsigned int encoder_id; + + unsigned int crtc_id; /**< Id of crtc */ - unsigned int crtc; /**< Id of crtc */ - uint32_t crtcs; - uint32_t clones; + uint32_t possible_crtcs; + uint32_t possible_clones; }; /* This is for connectors with multiple signal types. */ @@ -1126,8 +1123,8 @@ struct drm_mode_get_connector { int count_props; int count_encoders; - unsigned int encoder; /**< Current Encoder */ - unsigned int connector; /**< Id */ + unsigned int encoder_id; /**< Current Encoder */ + unsigned int connector_id; /**< Id */ unsigned int connector_type; unsigned int connector_type_id; -- cgit v1.2.3 From e810cb9243fe6c4905182869d9e3272d861a14cb Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Sun, 6 Jul 2008 10:52:25 +0200 Subject: modesetting-101: rename modeflags, as to avoid conflicts with the xorg definitions --- shared-core/drm.h | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index b64e265d..c7c7f13c 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1011,20 +1011,21 @@ struct drm_mm_info_arg { #define DRM_MODE_TYPE_DRIVER (1<<6) /* Video mode flags */ -#define V_PHSYNC (1<<0) -#define V_NHSYNC (1<<1) -#define V_PVSYNC (1<<2) -#define V_NVSYNC (1<<3) -#define V_INTERLACE (1<<4) -#define V_DBLSCAN (1<<5) -#define V_CSYNC (1<<6) -#define V_PCSYNC (1<<7) -#define V_NCSYNC (1<<8) -#define V_HSKEW (1<<9) /* hskew provided */ -#define V_BCAST (1<<10) -#define V_PIXMUX (1<<11) -#define V_DBLCLK (1<<12) -#define V_CLKDIV2 (1<<13) +/* bit compatible with the xorg definitions. */ +#define DRM_MODE_FLAG_PHSYNC (1<<0) +#define DRM_MODE_FLAG_NHSYNC (1<<1) +#define DRM_MODE_FLAG_PVSYNC (1<<2) +#define DRM_MODE_FLAG_NVSYNC (1<<3) +#define DRM_MODE_FLAG_INTERLACE (1<<4) +#define DRM_MODE_FLAG_DBLSCAN (1<<5) +#define DRM_MODE_FLAG_CSYNC (1<<6) +#define DRM_MODE_FLAG_PCSYNC (1<<7) +#define DRM_MODE_FLAG_NCSYNC (1<<8) +#define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */ +#define DRM_MODE_FLAG_BCAST (1<<10) +#define DRM_MODE_FLAG_PIXMUX (1<<11) +#define DRM_MODE_FLAG_DBLCLK (1<<12) +#define DRM_MODE_FLAG_CLKDIV2 (1<<13) /* DPMS flags */ #define DPMSModeOn 0 -- cgit v1.2.3 From 6738e7b00bf05529303ed690873495db6d83337c Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Sun, 6 Jul 2008 11:08:49 +0200 Subject: modesetting-101: Rename DPMS modes to avoid compatibility issues with xorg definitions. --- shared-core/drm.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index c7c7f13c..2e4d2a94 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1028,10 +1028,11 @@ struct drm_mm_info_arg { #define DRM_MODE_FLAG_CLKDIV2 (1<<13) /* DPMS flags */ -#define DPMSModeOn 0 -#define DPMSModeStandby 1 -#define DPMSModeSuspend 2 -#define DPMSModeOff 3 +/* bit compatible with the xorg definitions. */ +#define DRM_MODE_DPMS_ON 0 +#define DRM_MODE_DPMS_STANDBY 1 +#define DRM_MODE_DPMS_SUSPEND 2 +#define DRM_MODE_DPMS_OFF 3 struct drm_mode_modeinfo { unsigned int clock; -- cgit v1.2.3 From 38a5f6686cd38d5204e240f30006538bcf70f5ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Mon, 7 Jul 2008 18:00:23 -0400 Subject: Add back flink, open and close ioctls. They fell through the cracks in 86accbcb. --- shared-core/drm.h | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 2d0f1f4d..382e3fa1 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -993,15 +993,30 @@ struct drm_mm_info_arg { uint64_t p_size; }; -struct drm_gem_set_domain { - /** Handle for the object */ +struct drm_gem_close { + /** Handle of the object to be closed. */ uint32_t handle; - /** New read domains */ - uint32_t read_domains; - /** New write domain */ - uint32_t write_domain; + uint32_t pad; +}; + +struct drm_gem_flink { + /** Handle for the object being named */ + uint32_t handle; + + /** Returned global name */ + uint32_t name; +}; + +struct drm_gem_open { + /** Name of object being opened */ + uint32_t name; + + /** Returned handle for the object */ + uint32_t handle; + + /** Returned size of the object */ + uint64_t size; }; -#define DRM_GEM_DOMAIN_CPU 0x00000001 /* * Drm mode setting -- cgit v1.2.3 From 4872ac9c6204c3f212fd622ed292f6fc245020bf Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 25 Jun 2008 04:39:32 +1000 Subject: nouveau: interface changes for nv5x 3d --- shared-core/nouveau_drm.h | 20 +++++++++---- shared-core/nouveau_drv.h | 4 ++- shared-core/nouveau_fifo.c | 1 + shared-core/nouveau_mem.c | 71 ++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 87 insertions(+), 9 deletions(-) (limited to 'shared-core') diff --git a/shared-core/nouveau_drm.h b/shared-core/nouveau_drm.h index bbb51bc4..4b5869ad 100644 --- a/shared-core/nouveau_drm.h +++ b/shared-core/nouveau_drm.h @@ -25,7 +25,7 @@ #ifndef __NOUVEAU_DRM_H__ #define __NOUVEAU_DRM_H__ -#define NOUVEAU_DRM_HEADER_PATCHLEVEL 10 +#define NOUVEAU_DRM_HEADER_PATCHLEVEL 11 struct drm_nouveau_channel_alloc { uint32_t fb_ctxdma_handle; @@ -85,10 +85,12 @@ struct drm_nouveau_gpuobj_free { #define NOUVEAU_MEM_PINNED 0x00000040 #define NOUVEAU_MEM_USER_BACKED 0x00000080 #define NOUVEAU_MEM_MAPPED 0x00000100 -#define NOUVEAU_MEM_INSTANCE 0x00000200 /* internal */ -#define NOUVEAU_MEM_NOTIFIER 0x00000400 /* internal */ -#define NOUVEAU_MEM_NOVM 0x00000800 /* internal */ -#define NOUVEAU_MEM_USER 0x00001000 /* internal */ +#define NOUVEAU_MEM_TILE 0x00000200 +#define NOUVEAU_MEM_TILE_ZETA 0x00000400 +#define NOUVEAU_MEM_INSTANCE 0x01000000 /* internal */ +#define NOUVEAU_MEM_NOTIFIER 0x02000000 /* internal */ +#define NOUVEAU_MEM_NOVM 0x04000000 /* internal */ +#define NOUVEAU_MEM_USER 0x08000000 /* internal */ #define NOUVEAU_MEM_INTERNAL (NOUVEAU_MEM_INSTANCE | \ NOUVEAU_MEM_NOTIFIER | \ NOUVEAU_MEM_NOVM | \ @@ -107,6 +109,13 @@ struct drm_nouveau_mem_free { int flags; }; +struct drm_nouveau_mem_tile { + uint64_t offset; + uint64_t delta; + uint64_t size; + int flags; +}; + /* FIXME : maybe unify {GET,SET}PARAMs */ #define NOUVEAU_GETPARAM_PCI_VENDOR 3 #define NOUVEAU_GETPARAM_PCI_DEVICE 4 @@ -168,5 +177,6 @@ struct drm_nouveau_sarea { #define DRM_NOUVEAU_GPUOBJ_FREE 0x07 #define DRM_NOUVEAU_MEM_ALLOC 0x08 #define DRM_NOUVEAU_MEM_FREE 0x09 +#define DRM_NOUVEAU_MEM_TILE 0x0a #endif /* __NOUVEAU_DRM_H__ */ diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 33e2a5b6..03fe2ba7 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -34,7 +34,7 @@ #define DRIVER_MAJOR 0 #define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 10 +#define DRIVER_PATCHLEVEL 11 #define NOUVEAU_FAMILY 0x0000FFFF #define NOUVEAU_FLAGS 0xFFFF0000 @@ -385,6 +385,8 @@ extern int nouveau_ioctl_mem_alloc(struct drm_device *, void *data, struct drm_file *); extern int nouveau_ioctl_mem_free(struct drm_device *, void *data, struct drm_file *); +extern int nouveau_ioctl_mem_tile(struct drm_device *, void *data, + struct drm_file *); extern struct mem_block* nouveau_mem_alloc(struct drm_device *, int alignment, uint64_t size, int flags, struct drm_file *); diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index d8fda277..085336af 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -593,6 +593,7 @@ struct drm_ioctl_desc nouveau_ioctls[] = { DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH), DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_ALLOC, nouveau_ioctl_mem_alloc, DRM_AUTH), DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_FREE, nouveau_ioctl_mem_free, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_TILE, nouveau_ioctl_mem_tile, DRM_AUTH), }; int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 861d699f..db207e76 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -606,8 +606,11 @@ nouveau_mem_alloc(struct drm_device *dev, int alignment, uint64_t size, /* Align allocation sizes to 64KiB blocks on G8x. We use a 64KiB * page size in the GPU VM. */ - if (flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50) - size = (size + (64 * 1024)) & ~((64 * 1024) - 1); + if (flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50) { + size = (size + 65535) & ~65535; + if (alignment < 16) + alignment = 16; + } /* * Warn about 0 sized allocations, but let it go through. It'll return 1 page @@ -669,6 +672,7 @@ alloc_ok: struct nouveau_gpuobj *pt = dev_priv->vm_vram_pt; unsigned offset = block->start; unsigned count = block->size / 65536; + unsigned tile = 0; if (!pt) { DRM_ERROR("vm alloc without vm pt\n"); @@ -676,11 +680,22 @@ alloc_ok: return NULL; } + /* The tiling stuff is *not* what NVIDIA does - but both the + * 2D and 3D engines seem happy with this simpler method. + * Should look into why NVIDIA do what they do at some point. + */ + if (flags & NOUVEAU_MEM_TILE) { + if (flags & NOUVEAU_MEM_TILE_ZETA) + tile = 0x00002800; + else + tile = 0x00007000; + } + while (count--) { unsigned pte = offset / 65536; INSTANCE_WR(pt, (pte * 2) + 0, offset | 1); - INSTANCE_WR(pt, (pte * 2) + 1, 0x00000000); + INSTANCE_WR(pt, (pte * 2) + 1, 0x00000000 | tile); offset += 65536; } } else { @@ -833,3 +848,53 @@ int nouveau_ioctl_mem_free(struct drm_device *dev, void *data, struct drm_file * nouveau_mem_free(dev, block); return 0; } + +int +nouveau_ioctl_mem_tile(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_nouveau_mem_tile *memtile = data; + struct mem_block *block = NULL; + + NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + + if (dev_priv->card_type < NV_50) + return -EINVAL; + + if (memtile->flags & NOUVEAU_MEM_FB) { + memtile->offset -= 512*1024*1024; + block = find_block(dev_priv->fb_heap, memtile->offset); + } + + if (!block) + return -EINVAL; + + if (block->file_priv != file_priv) + return -EPERM; + + { + struct nouveau_gpuobj *pt = dev_priv->vm_vram_pt; + unsigned offset = block->start + memtile->delta; + unsigned count = memtile->size / 65536; + unsigned tile = 0; + + if (memtile->flags & NOUVEAU_MEM_TILE) { + if (memtile->flags & NOUVEAU_MEM_TILE_ZETA) + tile = 0x00002800; + else + tile = 0x00007000; + } + + while (count--) { + unsigned pte = offset / 65536; + + INSTANCE_WR(pt, (pte * 2) + 0, offset | 1); + INSTANCE_WR(pt, (pte * 2) + 1, 0x00000000 | tile); + offset += 65536; + } + } + + return 0; +} + -- cgit v1.2.3 From 0ef097b598433a5756df2bd6a72deba1f0e1d1c7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 23 Jun 2008 01:24:11 +1000 Subject: nv50: use same dma object for fb/tt access We depend on the VM fully now for memory protection, separate DMA objects for VRAM and GART are unneccesary. However, until the next interface break (soon) a client can't depend on the objects being the same and must still call NV_OBJ_SET_DMA_* methods appropriately. --- shared-core/nouveau_mem.c | 11 ++++++++++- shared-core/nouveau_object.c | 6 ++++-- 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'shared-core') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index db207e76..375463b4 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -806,6 +806,7 @@ int nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_mem_alloc *alloc = data; struct mem_block *block; @@ -822,10 +823,15 @@ nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, alloc->offset=block->start; alloc->flags=block->flags; + if (dev_priv->card_type >= NV_50 && alloc->flags & NOUVEAU_MEM_FB) + alloc->offset += 512*1024*1024; + return 0; } -int nouveau_ioctl_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv) +int +nouveau_ioctl_mem_free(struct drm_device *dev, void *data, + struct drm_file *file_priv) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_mem_free *memfree = data; @@ -833,6 +839,9 @@ int nouveau_ioctl_mem_free(struct drm_device *dev, void *data, struct drm_file * NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + if (dev_priv->card_type >= NV_50 && memfree->flags & NOUVEAU_MEM_FB) + memfree->offset -= 512*1024*1024; + block=NULL; if (memfree->flags & NOUVEAU_MEM_FB) block = find_block(dev_priv->fb_heap, memfree->offset); diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index 5664bfc8..894e7336 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -1036,8 +1036,7 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, /* VRAM ctxdma */ if (dev_priv->card_type >= NV_50) { ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, - 512*1024*1024, - dev_priv->fb_available_size, + 0, 0x100000000ULL, NV_DMA_ACCESS_RW, NV_DMA_TARGET_AGP, &vram); if (ret) { @@ -1059,6 +1058,9 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, } /* TT memory ctxdma */ + if (dev_priv->card_type >= NV_50) { + tt = vram; + } else if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) { ret = nouveau_gpuobj_gart_dma_new(chan, 0, dev_priv->gart_info.aper_size, -- cgit v1.2.3 From 65803e53a696347e38d7f6c2c8dc186c6764ff03 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Sun, 20 Jul 2008 13:49:18 +0200 Subject: modesetting-101: implement optional scaling and dithering properties --- shared-core/drm.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 2e4d2a94..41190640 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1034,6 +1034,16 @@ struct drm_mm_info_arg { #define DRM_MODE_DPMS_SUSPEND 2 #define DRM_MODE_DPMS_OFF 3 +/* Scaling mode options */ +#define DRM_MODE_SCALE_NON_GPU 0 +#define DRM_MODE_SCALE_FULLSCREEN 1 +#define DRM_MODE_SCALE_NO_SCALE 2 +#define DRM_MODE_SCALE_ASPECT 3 + +/* Dithering mode options */ +#define DRM_MODE_DITHERING_OFF 0 +#define DRM_MODE_DITHERING_ON 1 + struct drm_mode_modeinfo { unsigned int clock; unsigned short hdisplay, hsync_start, hsync_end, htotal, hskew; -- cgit v1.2.3 From df9871064e8b564d9ae2e56d561b64434fd004af Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 26 Jul 2008 08:56:23 +1000 Subject: radeon: add initial atombios modesetting and GEM -> TTM translation layer. This is an initial import of the atom bios parser with modesetting support for r500 hw using atombios. It also includes a simple memory manager layer that translates a radeon GEM style interface onto TTM internally. So far this memory manager has only been used for pinned object allocation for the DDX to test modesetting. --- shared-core/drm.h | 2 +- shared-core/r300_cmdbuf.c | 11 +- shared-core/radeon_cp.c | 992 +++++++++++++++++++++++++++++++++++++++++---- shared-core/radeon_drm.h | 117 +++++- shared-core/radeon_drv.h | 298 ++++++++++---- shared-core/radeon_irq.c | 14 +- shared-core/radeon_state.c | 203 ++++++---- 7 files changed, 1369 insertions(+), 268 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 900bffc1..7aba2939 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -236,7 +236,7 @@ enum drm_map_type { _DRM_AGP = 3, /**< AGP/GART */ _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */ _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */ - _DRM_TTM = 6 + _DRM_TTM = 6, }; /** diff --git a/shared-core/r300_cmdbuf.c b/shared-core/r300_cmdbuf.c index bff6378f..e8f18dbc 100644 --- a/shared-core/r300_cmdbuf.c +++ b/shared-core/r300_cmdbuf.c @@ -732,12 +732,12 @@ static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv) * The actual age emit is done by r300_do_cp_cmdbuf, which is why you must * be careful about how this function is called. */ -static void r300_discard_buffer(struct drm_device * dev, struct drm_buf * buf) +static void r300_discard_buffer(struct drm_device * dev, struct drm_master *master, struct drm_buf * buf) { - drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_buf_priv_t *buf_priv = buf->dev_private; + struct drm_radeon_master_private *master_priv = master->driver_priv; - buf_priv->age = ++dev_priv->sarea_priv->last_dispatch; + buf_priv->age = ++master_priv->sarea_priv->last_dispatch; buf->pending = 1; buf->used = 0; } @@ -898,6 +898,7 @@ int r300_do_cp_cmdbuf(struct drm_device *dev, drm_radeon_kcmd_buffer_t *cmdbuf) { drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; struct drm_device_dma *dma = dev->dma; struct drm_buf *buf = NULL; int emit_dispatch_age = 0; @@ -1005,7 +1006,7 @@ int r300_do_cp_cmdbuf(struct drm_device *dev, } emit_dispatch_age = 1; - r300_discard_buffer(dev, buf); + r300_discard_buffer(dev, file_priv->master, buf); break; case R300_CMD_WAIT: @@ -1060,7 +1061,7 @@ int r300_do_cp_cmdbuf(struct drm_device *dev, /* Emit the vertex buffer age */ BEGIN_RING(2); - RADEON_DISPATCH_AGE(dev_priv->sarea_priv->last_dispatch); + RADEON_DISPATCH_AGE(master_priv->sarea_priv->last_dispatch); ADVANCE_RING(); } diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 819a61ae..80951e91 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -31,6 +31,7 @@ #include "drmP.h" #include "drm.h" +#include "drm_sarea.h" #include "radeon_drm.h" #include "radeon_drv.h" #include "r300_reg.h" @@ -75,6 +76,23 @@ static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) return RS480_READ_MCIND(dev_priv, addr); } +u32 radeon_read_mc_reg(drm_radeon_private_t *dev_priv, int addr) +{ + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) + return IGP_READ_MCIND(dev_priv, addr); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) + return R500_READ_MCIND(dev_priv, addr); + return 0; +} + +void radeon_write_mc_reg(drm_radeon_private_t *dev_priv, u32 addr, u32 val) +{ + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) + IGP_WRITE_MCIND(addr, val); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) + R500_WRITE_MCIND(addr, val); +} + u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) { @@ -133,12 +151,57 @@ static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) } } -static int RADEON_READ_PLL(struct drm_device * dev, int addr) + +void radeon_pll_errata_after_index(struct drm_radeon_private *dev_priv) { - drm_radeon_private_t *dev_priv = dev->dev_private; + if (!(dev_priv->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS)) + return; + + (void)RADEON_READ(RADEON_CLOCK_CNTL_DATA); + (void)RADEON_READ(RADEON_CRTC_GEN_CNTL); +} + +void radeon_pll_errata_after_data(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->pll_errata & CHIP_ERRATA_PLL_DELAY) + udelay(5000); + + /* 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->pll_errata & CHIP_ERRATA_R300_CG) { + uint32_t save, tmp; + + save = RADEON_READ(RADEON_CLOCK_CNTL_INDEX); + tmp = save & ~(0x3f | RADEON_PLL_WR_EN); + RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, tmp); + tmp = RADEON_READ(RADEON_CLOCK_CNTL_DATA); + RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, save); + } +} + +int RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr) +{ + uint32_t data; - RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f); - return RADEON_READ(RADEON_CLOCK_CNTL_DATA); + RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x3f); + radeon_pll_errata_after_index(dev_priv); + data = RADEON_READ(RADEON_CLOCK_CNTL_DATA); + radeon_pll_errata_after_data(dev_priv); + return data; +} + +void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint32_t data) +{ + RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, ((addr & 0x3f) | RADEON_PLL_WR_EN)); + radeon_pll_errata_after_index(dev_priv); + RADEON_WRITE(RADEON_CLOCK_CNTL_DATA, data); + radeon_pll_errata_after_data(dev_priv); } static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) @@ -147,6 +210,39 @@ static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) return RADEON_READ(RADEON_PCIE_DATA); } +/* ATOM accessor methods */ +static uint32_t cail_mc_read(struct card_info *info, uint32_t reg) +{ + uint32_t ret = radeon_read_mc_reg(info->dev->dev_private, reg); + + // DRM_DEBUG("(%x) = %x\n", reg, ret); + return ret; +} + +static void cail_mc_write(struct card_info *info, uint32_t reg, uint32_t val) +{ + // DRM_DEBUG("(%x, %x)\n", reg, val); + radeon_write_mc_reg(info->dev->dev_private, reg, val); +} + +static void cail_reg_write(struct card_info *info, uint32_t reg, uint32_t val) +{ + drm_radeon_private_t *dev_priv = info->dev->dev_private; + + // DRM_DEBUG("(%x, %x)\n", reg*4, val); + RADEON_WRITE(reg*4, val); +} + +static uint32_t cail_reg_read(struct card_info *info, uint32_t reg) +{ + uint32_t ret; + drm_radeon_private_t *dev_priv = info->dev->dev_private; + + ret = RADEON_READ(reg*4); + // DRM_DEBUG("(%x) = %x\n", reg*4, ret); + return ret; +} + #if RADEON_FIFO_DEBUG static void radeon_status(drm_radeon_private_t * dev_priv) { @@ -298,7 +394,7 @@ static void radeon_init_pipes(drm_radeon_private_t * dev_priv) } if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { - RADEON_WRITE_PLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); + RADEON_WRITE_PLL(dev_priv, R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); RADEON_WRITE(R500_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1)); } RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config); @@ -491,15 +587,15 @@ static int radeon_do_engine_reset(struct drm_device * dev) if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) { /* may need something similar for newer chips */ clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX); - mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL); - - RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl | - RADEON_FORCEON_MCLKA | - RADEON_FORCEON_MCLKB | - RADEON_FORCEON_YCLKA | - RADEON_FORCEON_YCLKB | - RADEON_FORCEON_MC | - RADEON_FORCEON_AIC)); + mclk_cntl = RADEON_READ_PLL(dev_priv, RADEON_MCLK_CNTL); + + RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_CNTL, (mclk_cntl | + RADEON_FORCEON_MCLKA | + RADEON_FORCEON_MCLKB | + RADEON_FORCEON_YCLKA | + RADEON_FORCEON_YCLKB | + RADEON_FORCEON_MC | + RADEON_FORCEON_AIC)); } rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET); @@ -524,7 +620,7 @@ static int radeon_do_engine_reset(struct drm_device * dev) RADEON_READ(RADEON_RBBM_SOFT_RESET); if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) { - RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl); + RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_CNTL, mclk_cntl); RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset); } @@ -540,7 +636,8 @@ static int radeon_do_engine_reset(struct drm_device * dev) dev_priv->cp_running = 0; /* Reset any pending vertex, indirect buffers */ - radeon_freelist_reset(dev); + if (dev->dma) + radeon_freelist_reset(dev); return 0; } @@ -558,9 +655,13 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, */ if (!dev_priv->new_memmap) radeon_write_fb_location(dev_priv, - ((dev_priv->gart_vm_start - 1) & 0xffff0000) - | (dev_priv->fb_location >> 16)); - + ((dev_priv->gart_vm_start - 1) & 0xffff0000) + | (dev_priv->fb_location >> 16)); + + if (dev_priv->mm.ring) { + ring_start = dev_priv->mm.ring->offset + + dev_priv->gart_vm_start; + } else #if __OS_HAS_AGP if (dev_priv->flags & RADEON_IS_AGP) { radeon_write_agp_base(dev_priv, dev->agp->base); @@ -590,6 +691,12 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, SET_RING_HEAD(dev_priv, cur_read_ptr); dev_priv->ring.tail = cur_read_ptr; + + if (dev_priv->mm.ring_read_ptr) { + RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, + dev_priv->mm.ring_read_ptr->offset + + dev_priv->gart_vm_start); + } else #if __OS_HAS_AGP if (dev_priv->flags & RADEON_IS_AGP) { RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, @@ -638,9 +745,14 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) + RADEON_SCRATCH_REG_OFFSET); - dev_priv->scratch = ((__volatile__ u32 *) - dev_priv->ring_rptr->handle + - (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); + if (dev_priv->mm.ring_read_ptr) + dev_priv->scratch = ((__volatile__ u32 *) + dev_priv->mm.ring_read_ptr_map.virtual + + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); + else + dev_priv->scratch = ((__volatile__ u32 *) + dev_priv->ring_rptr->handle + + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); @@ -648,15 +760,14 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; RADEON_WRITE(RADEON_BUS_CNTL, tmp); - dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; - RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); + dev_priv->scratch[0] = 0; + RADEON_WRITE(RADEON_LAST_FRAME_REG, 0); - dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0; - RADEON_WRITE(RADEON_LAST_DISPATCH_REG, - dev_priv->sarea_priv->last_dispatch); + dev_priv->scratch[1] = 0; + RADEON_WRITE(RADEON_LAST_DISPATCH_REG, 0); - dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0; - RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear); + dev_priv->scratch[2] = 0; + RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); radeon_do_wait_for_idle(dev_priv); @@ -672,15 +783,21 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, static void radeon_test_writeback(drm_radeon_private_t * dev_priv) { u32 tmp; + void *ring_read_ptr; + + if (dev_priv->mm.ring_read_ptr) + ring_read_ptr = dev_priv->mm.ring_read_ptr_map.virtual; + else + ring_read_ptr = dev_priv->ring_rptr->handle; /* Writeback doesn't seem to work everywhere, test it here and possibly * enable it if it appears to work */ - DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0); + writel(0, ring_read_ptr + RADEON_SCRATCHOFF(1)); RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { - if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) == + if (readl(ring_read_ptr + RADEON_SCRATCHOFF(1)) == 0xdeadbeef) break; DRM_UDELAY(1); @@ -813,7 +930,7 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) } /* Enable or disable PCI GART on the chip */ -static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) +void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) { u32 tmp; @@ -854,9 +971,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) } } -static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) +static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, + struct drm_file *file_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; DRM_DEBUG("\n"); @@ -897,17 +1016,6 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) */ dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; - switch(init->func) { - case RADEON_INIT_R200_CP: - dev_priv->microcode_version = UCODE_R200; - break; - case RADEON_INIT_R300_CP: - dev_priv->microcode_version = UCODE_R300; - break; - default: - dev_priv->microcode_version = UCODE_R100; - } - dev_priv->do_boxes = 0; dev_priv->cp_mode = init->cp_mode; @@ -955,9 +1063,8 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) */ dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | (dev_priv->color_fmt << 10) | - (dev_priv->microcode_version == - UCODE_R100 ? RADEON_ZBLOCK16 : 0)); - + (dev_priv->chip_family < CHIP_R200 ? RADEON_ZBLOCK16 : 0)); + dev_priv->depth_clear.rb3d_zstencilcntl = (dev_priv->depth_fmt | RADEON_Z_TEST_ALWAYS | @@ -984,8 +1091,8 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) dev_priv->buffers_offset = init->buffers_offset; dev_priv->gart_textures_offset = init->gart_textures_offset; - dev_priv->sarea = drm_getsarea(dev); - if (!dev_priv->sarea) { + master_priv->sarea = drm_getsarea(dev); + if (!master_priv->sarea) { DRM_ERROR("could not find sarea!\n"); radeon_do_cleanup_cp(dev); return -EINVAL; @@ -1021,10 +1128,6 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) } } - dev_priv->sarea_priv = - (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->handle + - init->sarea_priv_offset); - #if __OS_HAS_AGP if (dev_priv->flags & RADEON_IS_AGP) { drm_core_ioremap(dev_priv->cp_ring, dev); @@ -1155,28 +1258,41 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); /* if we have an offset set from userspace */ if (dev_priv->pcigart_offset_set) { - dev_priv->gart_info.bus_addr = - dev_priv->pcigart_offset + dev_priv->fb_location; - dev_priv->gart_info.mapping.offset = - dev_priv->pcigart_offset + dev_priv->fb_aper_offset; - dev_priv->gart_info.mapping.size = - dev_priv->gart_info.table_size; - - drm_core_ioremap(&dev_priv->gart_info.mapping, dev); - dev_priv->gart_info.addr = - dev_priv->gart_info.mapping.handle; - - if (dev_priv->flags & RADEON_IS_PCIE) - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE; - else - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; - dev_priv->gart_info.gart_table_location = - DRM_ATI_GART_FB; - DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", - dev_priv->gart_info.addr, - dev_priv->pcigart_offset); + /* if it came from userspace - remap it */ + if (dev_priv->pcigart_offset_set == 1) { + dev_priv->gart_info.bus_addr = + dev_priv->pcigart_offset + dev_priv->fb_location; + dev_priv->gart_info.mapping.offset = + dev_priv->pcigart_offset + dev_priv->fb_aper_offset; + dev_priv->gart_info.mapping.size = + dev_priv->gart_info.table_size; + + /* this is done by the mm now */ + drm_core_ioremap(&dev_priv->gart_info.mapping, dev); + dev_priv->gart_info.addr = + dev_priv->gart_info.mapping.handle; + + memset(dev_priv->gart_info.addr, 0, dev_priv->gart_info.table_size); + if (dev_priv->flags & RADEON_IS_PCIE) + dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE; + else + dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; + dev_priv->gart_info.gart_table_location = + DRM_ATI_GART_FB; + + DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", + dev_priv->gart_info.addr, + dev_priv->pcigart_offset); + } } else { + + if (dev_priv->flags & RADEON_IS_PCIE) { + DRM_ERROR + ("Cannot use PCI Express without GART in FB memory\n"); + radeon_do_cleanup_cp(dev); + return -EINVAL; + } if (dev_priv->flags & RADEON_IS_IGPGART) dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP; else @@ -1185,12 +1301,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) DRM_ATI_GART_MAIN; dev_priv->gart_info.addr = NULL; dev_priv->gart_info.bus_addr = 0; - if (dev_priv->flags & RADEON_IS_PCIE) { - DRM_ERROR - ("Cannot use PCI Express without GART in FB memory\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } + } if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { @@ -1253,8 +1364,10 @@ static int radeon_do_cleanup_cp(struct drm_device * dev) if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) { - drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); - dev_priv->gart_info.addr = 0; + if (dev_priv->pcigart_offset_set == 1) { + drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); + dev_priv->gart_info.addr = NULL; + } } } /* only clear to the start of flags */ @@ -1305,6 +1418,10 @@ static int radeon_do_resume_cp(struct drm_device * dev) int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_radeon_init_t *init = data; + + /* on a modesetting driver ignore this stuff */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; LOCK_TEST_WITH_RETURN(dev, file_priv); @@ -1315,7 +1432,7 @@ int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_pri case RADEON_INIT_CP: case RADEON_INIT_R200_CP: case RADEON_INIT_R300_CP: - return radeon_do_init_cp(dev, init); + return radeon_do_init_cp(dev, init, file_priv); case RADEON_CLEANUP_CP: return radeon_do_cleanup_cp(dev); } @@ -1328,6 +1445,9 @@ int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_pr drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + LOCK_TEST_WITH_RETURN(dev, file_priv); if (dev_priv->cp_running) { @@ -1355,6 +1475,9 @@ int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_pri int ret; DRM_DEBUG("\n"); + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv->cp_running) @@ -1393,6 +1516,9 @@ void radeon_do_release(struct drm_device * dev) drm_radeon_private_t *dev_priv = dev->dev_private; int i, ret; + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return; + if (dev_priv) { if (dev_priv->cp_running) { /* Stop the cp */ @@ -1431,6 +1557,9 @@ void radeon_do_release(struct drm_device * dev) radeon_mem_takedown(&(dev_priv->gart_heap)); radeon_mem_takedown(&(dev_priv->fb_heap)); + + radeon_gem_mm_fini(dev); + /* deallocate kernel resources */ radeon_do_cleanup_cp(dev); } @@ -1443,6 +1572,9 @@ int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_pr drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv) { @@ -1463,7 +1595,9 @@ int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_pri drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, file_priv); + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + LOCK_TEST_WITH_RETURN(dev, file_priv); return radeon_do_cp_idle(dev_priv); } @@ -1473,6 +1607,9 @@ int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_pri int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv) { + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + return radeon_do_resume_cp(dev); } @@ -1480,6 +1617,9 @@ int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *fil { DRM_DEBUG("\n"); + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + LOCK_TEST_WITH_RETURN(dev, file_priv); return radeon_do_engine_reset(dev); @@ -1702,6 +1842,541 @@ int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_ return ret; } +static void radeon_get_vram_type(struct drm_device *dev) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + uint32_t tmp; + + if (dev_priv->flags & RADEON_IS_IGP || (dev_priv->chip_family >= CHIP_R300)) + dev_priv->is_ddr = true; + else if (RADEON_READ(RADEON_MEM_SDRAM_MODE_REG) & RADEON_MEM_CFG_TYPE_DDR) + dev_priv->is_ddr = true; + else + dev_priv->is_ddr = false; + + if ((dev_priv->chip_family >= CHIP_R600) && + (dev_priv->chip_family <= CHIP_RV635)) { + int chansize; + + tmp = RADEON_READ(R600_RAMCFG); + if (tmp & R600_CHANSIZE_OVERRIDE) + chansize = 16; + else if (tmp & R600_CHANSIZE) + chansize = 64; + else + chansize = 32; + + if (dev_priv->chip_family == CHIP_R600) + dev_priv->ram_width = 8 * chansize; + else if (dev_priv->chip_family == CHIP_RV670) + dev_priv->ram_width = 4 * chansize; + else if ((dev_priv->chip_family == CHIP_RV610) || + (dev_priv->chip_family == CHIP_RV620)) + dev_priv->ram_width = chansize; + else if ((dev_priv->chip_family == CHIP_RV630) || + (dev_priv->chip_family == CHIP_RV635)) + dev_priv->ram_width = 2 * chansize; + } else if (dev_priv->chip_family == CHIP_RV515) { + tmp = radeon_read_mc_reg(dev_priv, RV515_MC_CNTL); + tmp &= RV515_MEM_NUM_CHANNELS_MASK; + switch (tmp) { + case 0: dev_priv->ram_width = 64; break; + case 1: dev_priv->ram_width = 128; break; + default: dev_priv->ram_width = 128; break; + } + } else if ((dev_priv->chip_family >= CHIP_R520) && + (dev_priv->chip_family <= CHIP_RV570)) { + tmp = radeon_read_mc_reg(dev_priv, R520_MC_CNTL0); + switch ((tmp & R520_MEM_NUM_CHANNELS_MASK) >> R520_MEM_NUM_CHANNELS_SHIFT) { + case 0: dev_priv->ram_width = 32; break; + case 1: dev_priv->ram_width = 64; break; + case 2: dev_priv->ram_width = 128; break; + case 3: dev_priv->ram_width = 256; break; + default: dev_priv->ram_width = 128; break; + } + } else if ((dev_priv->chip_family == CHIP_RV100) || + (dev_priv->chip_family == CHIP_RS100) || + (dev_priv->chip_family == CHIP_RS200)) { + tmp = RADEON_READ(RADEON_MEM_CNTL); + if (tmp & RV100_HALF_MODE) + dev_priv->ram_width = 32; + else + dev_priv->ram_width = 64; + + if (dev_priv->flags & RADEON_SINGLE_CRTC) { + dev_priv->ram_width /= 4; + dev_priv->is_ddr = true; + } + } else if (dev_priv->chip_family <= CHIP_RV280) { + tmp = RADEON_READ(RADEON_MEM_CNTL); + if (tmp & RADEON_MEM_NUM_CHANNELS_MASK) + dev_priv->ram_width = 128; + else + dev_priv->ram_width = 64; + } else { + /* newer IGPs */ + dev_priv->ram_width = 128; + } + DRM_DEBUG("RAM width %d bits %cDR\n", dev_priv->ram_width, dev_priv->is_ddr ? 'D' : 'S'); +} + +static void radeon_force_some_clocks(struct drm_device *dev) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + uint32_t tmp; + + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); + tmp |= RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_VIP; + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); +} + +static void radeon_set_dynamic_clock(struct drm_device *dev, int mode) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + uint32_t tmp; + + switch(mode) { + case 0: + if (dev_priv->flags & RADEON_SINGLE_CRTC) { + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); + tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_HDP | + RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_TOP | + RADEON_SCLK_FORCE_E2 | RADEON_SCLK_FORCE_SE | + RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_VIP | + RADEON_SCLK_FORCE_RE | RADEON_SCLK_FORCE_PB | + RADEON_SCLK_FORCE_TAM | RADEON_SCLK_FORCE_TDM | + RADEON_SCLK_FORCE_RB); + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); + } else if (dev_priv->chip_family == CHIP_RV350) { + /* for RV350/M10, no delays are required. */ + tmp = RADEON_READ_PLL(dev_priv, R300_SCLK_CNTL2); + tmp |= (R300_SCLK_FORCE_TCL | + R300_SCLK_FORCE_GA | + R300_SCLK_FORCE_CBA); + RADEON_WRITE_PLL(dev_priv, R300_SCLK_CNTL2, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); + tmp &= ~(RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP | + RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | + RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 | + R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT | + RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR | + R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX | + R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK | + R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0); + tmp |= RADEON_DYN_STOP_LAT_MASK; + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_MORE_CNTL); + tmp &= ~RADEON_SCLK_MORE_FORCEON; + tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT; + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_MORE_CNTL, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL); + tmp |= (RADEON_PIXCLK_ALWAYS_ONb | + RADEON_PIXCLK_DAC_ALWAYS_ONb); + RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL); + tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | + RADEON_PIX2CLK_DAC_ALWAYS_ONb | + RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | + R300_DVOCLK_ALWAYS_ONb | + RADEON_PIXCLK_BLEND_ALWAYS_ONb | + RADEON_PIXCLK_GV_ALWAYS_ONb | + R300_PIXCLK_DVO_ALWAYS_ONb | + RADEON_PIXCLK_LVDS_ALWAYS_ONb | + RADEON_PIXCLK_TMDS_ALWAYS_ONb | + R300_PIXCLK_TRANS_ALWAYS_ONb | + R300_PIXCLK_TVO_ALWAYS_ONb | + R300_P2G2CLK_ALWAYS_ONb | + R300_P2G2CLK_ALWAYS_ONb); + RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, tmp); + } else { + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); + tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_E2); + tmp |= RADEON_SCLK_FORCE_SE; + + if ( dev_priv->flags & RADEON_SINGLE_CRTC ) { + tmp |= ( RADEON_SCLK_FORCE_RB | + RADEON_SCLK_FORCE_TDM | + RADEON_SCLK_FORCE_TAM | + RADEON_SCLK_FORCE_PB | + RADEON_SCLK_FORCE_RE | + RADEON_SCLK_FORCE_VIP | + RADEON_SCLK_FORCE_IDCT | + RADEON_SCLK_FORCE_TOP | + RADEON_SCLK_FORCE_DISP1 | + RADEON_SCLK_FORCE_DISP2 | + RADEON_SCLK_FORCE_HDP ); + } else if ((dev_priv->chip_family == CHIP_R300) || + (dev_priv->chip_family == CHIP_R350)) { + tmp |= ( RADEON_SCLK_FORCE_HDP | + RADEON_SCLK_FORCE_DISP1 | + RADEON_SCLK_FORCE_DISP2 | + RADEON_SCLK_FORCE_TOP | + RADEON_SCLK_FORCE_IDCT | + RADEON_SCLK_FORCE_VIP); + } + + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); + + udelay(16000); + + if ((dev_priv->chip_family == CHIP_R300) || + (dev_priv->chip_family == CHIP_R350)) { + tmp = RADEON_READ_PLL(dev_priv, R300_SCLK_CNTL2); + tmp |= ( R300_SCLK_FORCE_TCL | + R300_SCLK_FORCE_GA | + R300_SCLK_FORCE_CBA); + RADEON_WRITE_PLL(dev_priv, R300_SCLK_CNTL2, tmp); + udelay(16000); + } + + if (dev_priv->flags & RADEON_IS_IGP) { + tmp = RADEON_READ_PLL(dev_priv, RADEON_MCLK_CNTL); + tmp &= ~(RADEON_FORCEON_MCLKA | + RADEON_FORCEON_YCLKA); + RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_CNTL, tmp); + udelay(16000); + } + + if ((dev_priv->chip_family == CHIP_RV200) || + (dev_priv->chip_family == CHIP_RV250) || + (dev_priv->chip_family == CHIP_RV280)) { + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_MORE_CNTL); + tmp |= RADEON_SCLK_MORE_FORCEON; + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_MORE_CNTL, tmp); + udelay(16000); + } + + tmp = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL); + tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb | + RADEON_PIX2CLK_DAC_ALWAYS_ONb | + RADEON_PIXCLK_BLEND_ALWAYS_ONb | + RADEON_PIXCLK_GV_ALWAYS_ONb | + RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb | + RADEON_PIXCLK_LVDS_ALWAYS_ONb | + RADEON_PIXCLK_TMDS_ALWAYS_ONb); + + RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, tmp); + udelay(16000); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL); + tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | + RADEON_PIXCLK_DAC_ALWAYS_ONb); + RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, tmp); + } + DRM_DEBUG("Dynamic Clock Scaling Disabled\n"); + break; + case 1: + if (dev_priv->flags & RADEON_SINGLE_CRTC) { + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); + if ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) > + RADEON_CFG_ATI_REV_A13) { + tmp &= ~(RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_RB); + } + tmp &= ~(RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | + RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_SE | + RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_RE | + RADEON_SCLK_FORCE_PB | RADEON_SCLK_FORCE_TAM | + RADEON_SCLK_FORCE_TDM); + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); + } else if ((dev_priv->chip_family == CHIP_R300) || + (dev_priv->chip_family == CHIP_R350) || + (dev_priv->chip_family == CHIP_RV350)) { + if (dev_priv->chip_family == CHIP_RV350) { + tmp = RADEON_READ_PLL(dev_priv, R300_SCLK_CNTL2); + tmp &= ~(R300_SCLK_FORCE_TCL | + R300_SCLK_FORCE_GA | + R300_SCLK_FORCE_CBA); + tmp |= (R300_SCLK_TCL_MAX_DYN_STOP_LAT | + R300_SCLK_GA_MAX_DYN_STOP_LAT | + R300_SCLK_CBA_MAX_DYN_STOP_LAT); + RADEON_WRITE_PLL(dev_priv, R300_SCLK_CNTL2, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); + tmp &= ~(RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP | + RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | + RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 | + R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT | + RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR | + R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX | + R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK | + R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0); + tmp |= RADEON_DYN_STOP_LAT_MASK; + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_MORE_CNTL); + tmp &= ~RADEON_SCLK_MORE_FORCEON; + tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT; + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_MORE_CNTL, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL); + tmp |= (RADEON_PIXCLK_ALWAYS_ONb | + RADEON_PIXCLK_DAC_ALWAYS_ONb); + RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL); + tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | + RADEON_PIX2CLK_DAC_ALWAYS_ONb | + RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | + R300_DVOCLK_ALWAYS_ONb | + RADEON_PIXCLK_BLEND_ALWAYS_ONb | + RADEON_PIXCLK_GV_ALWAYS_ONb | + R300_PIXCLK_DVO_ALWAYS_ONb | + RADEON_PIXCLK_LVDS_ALWAYS_ONb | + RADEON_PIXCLK_TMDS_ALWAYS_ONb | + R300_PIXCLK_TRANS_ALWAYS_ONb | + R300_PIXCLK_TVO_ALWAYS_ONb | + R300_P2G2CLK_ALWAYS_ONb | + R300_P2G2CLK_ALWAYS_ONb); + RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_MCLK_MISC); + tmp |= (RADEON_MC_MCLK_DYN_ENABLE | + RADEON_IO_MCLK_DYN_ENABLE); + RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_MISC, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_MCLK_CNTL); + tmp |= (RADEON_FORCEON_MCLKA | + RADEON_FORCEON_MCLKB); + + tmp &= ~(RADEON_FORCEON_YCLKA | + RADEON_FORCEON_YCLKB | + RADEON_FORCEON_MC); + + /* Some releases of vbios have set DISABLE_MC_MCLKA + and DISABLE_MC_MCLKB bits in the vbios table. Setting these + bits will cause H/W hang when reading video memory with dynamic clocking + enabled. */ + if ((tmp & R300_DISABLE_MC_MCLKA) && + (tmp & R300_DISABLE_MC_MCLKB)) { + /* If both bits are set, then check the active channels */ + tmp = RADEON_READ_PLL(dev_priv, RADEON_MCLK_CNTL); + if (dev_priv->ram_width == 64) { + if (RADEON_READ(RADEON_MEM_CNTL) & R300_MEM_USE_CD_CH_ONLY) + tmp &= ~R300_DISABLE_MC_MCLKB; + else + tmp &= ~R300_DISABLE_MC_MCLKA; + } else { + tmp &= ~(R300_DISABLE_MC_MCLKA | + R300_DISABLE_MC_MCLKB); + } + } + + RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_CNTL, tmp); + } else { + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); + tmp &= ~(R300_SCLK_FORCE_VAP); + tmp |= RADEON_SCLK_FORCE_CP; + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); + udelay(15000); + + tmp = RADEON_READ_PLL(dev_priv, R300_SCLK_CNTL2); + tmp &= ~(R300_SCLK_FORCE_TCL | + R300_SCLK_FORCE_GA | + R300_SCLK_FORCE_CBA); + RADEON_WRITE_PLL(dev_priv, R300_SCLK_CNTL2, tmp); + } + } else { + tmp = RADEON_READ_PLL(dev_priv, RADEON_CLK_PWRMGT_CNTL); + tmp &= ~(RADEON_ACTIVE_HILO_LAT_MASK | + RADEON_DISP_DYN_STOP_LAT_MASK | + RADEON_DYN_STOP_MODE_MASK); + + tmp |= (RADEON_ENGIN_DYNCLK_MODE | + (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT)); + RADEON_WRITE_PLL(dev_priv, RADEON_CLK_PWRMGT_CNTL, tmp); + udelay(15000); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_CLK_PIN_CNTL); + tmp |= RADEON_SCLK_DYN_START_CNTL; + RADEON_WRITE_PLL(dev_priv, RADEON_CLK_PIN_CNTL, tmp); + udelay(15000); + + /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200 + to lockup randomly, leave them as set by BIOS. + */ + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); + /*tmp &= RADEON_SCLK_SRC_SEL_MASK;*/ + tmp &= ~RADEON_SCLK_FORCEON_MASK; + + /*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300*/ + if (((dev_priv->chip_family == CHIP_RV250) && + ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) < + RADEON_CFG_ATI_REV_A13)) || + ((dev_priv->chip_family == CHIP_RV100) && + ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) <= + RADEON_CFG_ATI_REV_A13))){ + tmp |= RADEON_SCLK_FORCE_CP; + tmp |= RADEON_SCLK_FORCE_VIP; + } + + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); + + if ((dev_priv->chip_family == CHIP_RV200) || + (dev_priv->chip_family == CHIP_RV250) || + (dev_priv->chip_family == CHIP_RV280)) { + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_MORE_CNTL); + tmp &= ~RADEON_SCLK_MORE_FORCEON; + + /* RV200::A11 A12 RV250::A11 A12 */ + if (((dev_priv->chip_family == CHIP_RV200) || + (dev_priv->chip_family == CHIP_RV250)) && + ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) < + RADEON_CFG_ATI_REV_A13)) { + tmp |= RADEON_SCLK_MORE_FORCEON; + } + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_MORE_CNTL, tmp); + udelay(15000); + } + + /* RV200::A11 A12, RV250::A11 A12 */ + if (((dev_priv->chip_family == CHIP_RV200) || + (dev_priv->chip_family == CHIP_RV250)) && + ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) < + RADEON_CFG_ATI_REV_A13)) { + tmp = RADEON_READ_PLL(dev_priv, RADEON_PLL_PWRMGT_CNTL); + tmp |= RADEON_TCL_BYPASS_DISABLE; + RADEON_WRITE_PLL(dev_priv, RADEON_PLL_PWRMGT_CNTL, tmp); + } + udelay(15000); + + /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK)*/ + tmp = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL); + tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | + RADEON_PIX2CLK_DAC_ALWAYS_ONb | + RADEON_PIXCLK_BLEND_ALWAYS_ONb | + RADEON_PIXCLK_GV_ALWAYS_ONb | + RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb | + RADEON_PIXCLK_LVDS_ALWAYS_ONb | + RADEON_PIXCLK_TMDS_ALWAYS_ONb); + + RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, tmp); + udelay(15000); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL); + tmp |= (RADEON_PIXCLK_ALWAYS_ONb | + RADEON_PIXCLK_DAC_ALWAYS_ONb); + + RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, tmp); + udelay(15000); + } + DRM_DEBUG("Dynamic Clock Scaling Enabled\n"); + break; + default: + break; + } + +} + +int radeon_modeset_cp_init(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + /* allocate a ring and ring rptr bits from GART space */ + /* these are allocated in GEM files */ + + dev_priv->usec_timeout = RADEON_DEFAULT_CP_TIMEOUT; + dev_priv->ring.size = RADEON_DEFAULT_RING_SIZE; + dev_priv->cp_mode = RADEON_CSQ_PRIBM_INDBM; + + dev_priv->ring.start = (u32 *)(void *)(unsigned long)dev_priv->mm.ring_map.virtual; + dev_priv->ring.end = (u32 *)(void *)(unsigned long)dev_priv->mm.ring_map.virtual + + dev_priv->ring.size / sizeof(u32); + dev_priv->ring.size_l2qw = drm_order(dev_priv->ring.size / 8); + dev_priv->ring.rptr_update = 4096; + dev_priv->ring.rptr_update_l2qw = drm_order(4096 / 8); + dev_priv->ring.fetch_size = 32; + dev_priv->ring.fetch_size_l2ow = drm_order(32 / 16); + dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; + dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; + + dev_priv->new_memmap = 1; + + radeon_cp_load_microcode(dev_priv); + + DRM_DEBUG("ring offset is %x %x\n", dev_priv->mm.ring->offset, dev_priv->mm.ring_read_ptr->offset); + + radeon_cp_init_ring_buffer(dev, dev_priv); + + radeon_do_engine_reset(dev); + radeon_test_writeback(dev_priv); + + radeon_do_cp_start(dev_priv); + return 0; +} + +static bool radeon_get_bios(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + u8 __iomem *bios; + size_t size; + uint16_t tmp; + + bios = pci_map_rom(dev->pdev, &size); + if (!bios) + return -1; + + dev_priv->bios = kmalloc(size, GFP_KERNEL); + if (!dev_priv->bios) { + pci_unmap_rom(dev->pdev, bios); + return -1; + } + + memcpy(dev_priv->bios, bios, size); + + pci_unmap_rom(dev->pdev, bios); + + if (dev_priv->bios[0] != 0x55 || dev_priv->bios[1] != 0xaa) + goto free_bios; + + dev_priv->bios_header_start = radeon_bios16(dev_priv, 0x48); + + if (!dev_priv->bios_header_start) + goto free_bios; + + tmp = dev_priv->bios_header_start + 4; + + if (!memcmp(dev_priv->bios + tmp, "ATOM", 4) || + !memcmp(dev_priv->bios + tmp, "MOTA", 4)) + dev_priv->is_atom_bios = true; + else + dev_priv->is_atom_bios = false; + + DRM_DEBUG("%sBIOS detected\n", dev_priv->is_atom_bios ? "ATOM" : "COM"); + return true; +free_bios: + kfree(dev_priv->bios); + dev_priv->bios = NULL; + return false; +} + +int radeon_modeset_preinit(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + static struct card_info card; + int ret; + + card.dev = dev; + card.reg_read = cail_reg_read; + card.reg_write = cail_reg_write; + card.mc_read = cail_mc_read; + card.mc_write = cail_mc_write; + + ret = radeon_get_bios(dev); + if (!ret) + return -1; + + if (dev_priv->is_atom_bios) { + dev_priv->mode_info.atom_context = atom_parse(&card, dev_priv->bios); + radeon_get_clock_info(dev); + } + return 0; +} + + int radeon_driver_load(struct drm_device *dev, unsigned long flags) { drm_radeon_private_t *dev_priv; @@ -1734,6 +2409,7 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) break; } + dev_priv->chip_family = flags & RADEON_FAMILY_MASK; if (drm_device_is_agp(dev)) dev_priv->flags |= RADEON_IS_AGP; else if (drm_device_is_pcie(dev)) @@ -1741,11 +2417,122 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) else dev_priv->flags |= RADEON_IS_PCI; + + DRM_DEBUG("%s card detected\n", ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); + + ret = drm_addmap(dev, drm_get_resource_start(dev, 2), + drm_get_resource_len(dev, 2), _DRM_REGISTERS, + _DRM_DRIVER | _DRM_READ_ONLY, &dev_priv->mmio); + if (ret != 0) + return ret; + + if (drm_core_check_feature(dev, DRIVER_MODESET)) + radeon_modeset_preinit(dev); + + + radeon_get_vram_type(dev); + + dev_priv->pll_errata = 0; + + if (dev_priv->chip_family == CHIP_R300 && + (RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) == RADEON_CFG_ATI_REV_A11) + dev_priv->pll_errata |= CHIP_ERRATA_R300_CG; + + if (dev_priv->chip_family == CHIP_RV200 || + dev_priv->chip_family == CHIP_RS200) + dev_priv->pll_errata |= CHIP_ERRATA_PLL_DUMMYREADS; + + + if (dev_priv->chip_family == CHIP_RV100 || + dev_priv->chip_family == CHIP_RS100 || + dev_priv->chip_family == CHIP_RS200) + dev_priv->pll_errata |= CHIP_ERRATA_PLL_DELAY; + + + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + if ((dev_priv->flags & RADEON_IS_MOBILITY) && !radeon_is_avivo(dev_priv)) { + radeon_set_dynamic_clock(dev, radeon_dynclks); + } else if (radeon_is_avivo(dev_priv)) { + if (radeon_dynclks) { + radeon_atom_static_pwrmgt_setup(dev, 1); + radeon_atom_dyn_clk_setup(dev, 1); + } + } + radeon_force_some_clocks(dev); + } + + /* init memory manager - start with all of VRAM and a 32MB GART aperture for now */ + dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0); + + drm_bo_driver_init(dev); + + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + + dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16; + dev_priv->fb_size = + ((radeon_read_fb_location(dev_priv) & 0xffff0000u) + 0x10000) + - dev_priv->fb_location; + radeon_gem_mm_init(dev); + radeon_modeset_init(dev); + + radeon_modeset_cp_init(dev); + dev->devname = kstrdup(DRIVER_NAME, GFP_KERNEL); + + drm_irq_install(dev); + } + + return ret; } + +int radeon_master_create(struct drm_device *dev, struct drm_master *master) +{ + struct drm_radeon_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->pfCurrentPage = 0; + + master->driver_priv = master_priv; + return 0; +} + +void radeon_master_destroy(struct drm_device *dev, struct drm_master *master) +{ + struct drm_radeon_master_private *master_priv = master->driver_priv; + struct drm_radeon_private *dev_priv = dev->dev_private; + + if (!master_priv) + return; + + if (master_priv->sarea_priv && + master_priv->sarea_priv->pfCurrentPage != 0) + radeon_cp_dispatch_flip(dev, master); + + master_priv->sarea_priv = NULL; + if (master_priv->sarea) + drm_rmmap(dev, master_priv->sarea); + + drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER); + + master->driver_priv = NULL; +} /* Create mappings for registers and framebuffer so userland doesn't necessarily * have to find them. */ @@ -1757,13 +2544,9 @@ int radeon_driver_firstopen(struct drm_device *dev) dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; - ret = drm_addmap(dev, drm_get_resource_start(dev, 2), - drm_get_resource_len(dev, 2), _DRM_REGISTERS, - _DRM_READ_ONLY, &dev_priv->mmio); - if (ret != 0) - return ret; + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + radeon_gem_mm_init(dev); - dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0); ret = drm_addmap(dev, dev_priv->fb_aper_offset, drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING, &map); @@ -1777,9 +2560,40 @@ int radeon_driver_unload(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + drm_irq_uninstall(dev); + radeon_modeset_cleanup(dev); + radeon_gem_mm_fini(dev); + } + + drm_bo_driver_finish(dev); + drm_rmmap(dev, dev_priv->mmio); + DRM_DEBUG("\n"); drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); dev->dev_private = NULL; return 0; } + +void radeon_gart_flush(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + if (dev_priv->flags & RADEON_IS_IGPGART) { + IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); + IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, RS480_GART_CACHE_INVALIDATE); + IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); + IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, 0); + } 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 { + + + } + +} diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index 81944061..7fcf9305 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -457,12 +457,6 @@ typedef struct { 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) @@ -502,6 +496,17 @@ typedef struct { #define DRM_RADEON_SURF_ALLOC 0x1a #define DRM_RADEON_SURF_FREE 0x1b +#define DRM_RADEON_GEM_INFO 0x1c +#define DRM_RADEON_GEM_CREATE 0x1d +#define DRM_RADEON_GEM_MMAP 0x1e +#define DRM_RADEON_GEM_PIN 0x1f +#define DRM_RADEON_GEM_UNPIN 0x20 +#define DRM_RADEON_GEM_PREAD 0x21 +#define DRM_RADEON_GEM_PWRITE 0x22 +#define DRM_RADEON_GEM_SET_DOMAIN 0x23 +#define DRM_RADEON_GEM_INDIRECT 0x24 // temporary for X server + + #define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t) #define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START) #define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_STOP, drm_radeon_cp_stop_t) @@ -530,6 +535,18 @@ typedef struct { #define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t) #define DRM_IOCTL_RADEON_SURF_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t) +#define DRM_IOCTL_RADEON_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INFO, struct drm_radeon_gem_info) +#define DRM_IOCTL_RADEON_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_CREATE, struct drm_radeon_gem_create) +#define DRM_IOCTL_RADEON_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_MMAP, struct drm_radeon_gem_mmap) +#define DRM_IOCTL_RADEON_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PIN, struct drm_radeon_gem_pin) +#define DRM_IOCTL_RADEON_GEM_UNPIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_UNPIN, struct drm_radeon_gem_unpin) +#define DRM_IOCTL_RADEON_GEM_PREAD DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PREAD, struct drm_radeon_gem_pread) +#define DRM_IOCTL_RADEON_GEM_PWRITE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PWRITE, struct drm_radeon_gem_pwrite) +#define DRM_IOCTL_RADEON_GEM_SET_DOMAIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain) +#define DRM_IOCTL_RADEON_GEM_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INDIRECT, struct drm_radeon_gem_indirect) + + + typedef struct drm_radeon_init { enum { RADEON_INIT_CP = 0x01, @@ -756,4 +773,92 @@ typedef struct drm_radeon_surface_free { #define DRM_RADEON_VBLANK_CRTC1 1 #define DRM_RADEON_VBLANK_CRTC2 2 +#define RADEON_GEM_DOMAIN_CPU 0x1 +#define RADEON_GEM_DOMAIN_VRAM 0x2 +#define RADEON_GEM_DOMAIN_2D 0x4 +#define RADEON_GEM_DOMAIN_3D 0x8 +#define RADEON_GEM_DOMAIN_TEXTURE 0x10 +#define RADEON_GEM_DOMAIN_GPU 0x20 // for vertex buffers + +/* return to userspace start/size of gtt and vram apertures */ +struct drm_radeon_gem_info { + uint64_t gart_start; + uint64_t gart_size; + uint64_t vram_start; + uint64_t vram_size; + uint64_t vram_visible; +}; + +struct drm_radeon_gem_create { + uint64_t size; + uint64_t alignment; + uint32_t handle; + uint32_t initial_domain; // to allow VRAM to be created + uint32_t no_backing_store; // for VRAM objects - select whether they need backing store + // pretty much front/back/depth don't need it - other things do +}; + +struct drm_radeon_gem_mmap { + uint32_t handle; + uint32_t pad; + uint64_t offset; + uint64_t size; + uint64_t addr_ptr; +}; + +struct drm_radeon_gem_set_domain { + uint32_t handle; + uint32_t read_domains; + uint32_t write_domain; +}; + +struct drm_radeon_gem_exec_buffer { +}; + +struct drm_radeon_gem_pin { + uint32_t handle; + uint32_t pad; + uint64_t alignment; + uint64_t offset; +}; + +struct drm_radeon_gem_unpin { + uint32_t handle; + uint32_t pad; +}; + +struct drm_radeon_gem_busy { + uint32_t handle; + uint32_t busy; +}; + +struct drm_radeon_gem_pread { + /** Handle for the object being read. */ + uint32_t handle; + uint32_t pad; + /** Offset into the object to read from */ + uint64_t offset; + /** Length of data to read */ + uint64_t size; + /** Pointer to write the data into. */ + uint64_t data_ptr; /* void *, but pointers are not 32/64 compatible */ +}; + +struct drm_radeon_gem_pwrite { + /** Handle for the object being written to. */ + uint32_t handle; + uint32_t pad; + /** Offset into the object to write to */ + uint64_t offset; + /** Length of data to write */ + uint64_t size; + /** Pointer to read the data from. */ + uint64_t data_ptr; /* void *, but pointers are not 32/64 compatible */ +}; + +struct drm_radeon_gem_indirect { + uint32_t handle; + uint32_t used; +}; + #endif diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index e263c610..b8f49404 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -31,6 +31,7 @@ #ifndef __RADEON_DRV_H__ #define __RADEON_DRV_H__ +#include "atom.h" /* General customization: */ @@ -96,13 +97,13 @@ * 1.25- Add support for r200 vertex programs (R200_EMIT_VAP_PVS_CNTL, * new packet type) * 1.26- Add support for variable size PCI(E) gart aperture - * 1.27- Add support for IGP GART + * 1.27- Add support for IGPGART * 1.28- Add support for VBL on CRTC2 * 1.29- R500 3D cmd buffer support */ #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 29 +#define DRIVER_MINOR 30 #define DRIVER_PATCHLEVEL 0 /* @@ -124,23 +125,29 @@ enum radeon_family { CHIP_RV380, CHIP_R420, CHIP_RV410, + CHIP_RS400, CHIP_RS480, + CHIP_RS600, CHIP_RS690, + CHIP_RS740, CHIP_RV515, CHIP_R520, CHIP_RV530, CHIP_RV560, CHIP_RV570, CHIP_R580, + CHIP_R600, + CHIP_R630, + CHIP_RV610, + CHIP_RV630, + CHIP_RV670, + CHIP_RV620, + CHIP_RV635, + CHIP_RS780, + CHIP_RV770, CHIP_LAST, }; -enum radeon_cp_microcode_version { - UCODE_R100, - UCODE_R200, - UCODE_R300, -}; - /* * Chip flags */ @@ -158,9 +165,42 @@ enum radeon_chip_flags { RADEON_IS_IGPGART = 0x01000000UL, }; +/* + * Errata workarounds + */ +enum radeon_pll_errata { + CHIP_ERRATA_R300_CG = 0x00000001, + CHIP_ERRATA_PLL_DUMMYREADS = 0x00000002, + CHIP_ERRATA_PLL_DELAY = 0x00000004 +}; + +enum radeon_ext_tmds_chip { + RADEON_DVOCHIP_NONE, + RADEON_SIL_164, + RADEON_SIL_1178 +}; + +#if defined(__powerpc__) +enum radeon_mac_model { + RADEON_MAC_NONE, + RADEON_MAC_IBOOK, + RADEON_MAC_POWERBOOK_EXTERNAL, + RADEON_MAC_POWERBOOK_INTERNAL, + RADEON_MAC_POWERBOOK_VGA, + RADEON_MAC_MINI_EXTERNAL, + RADEON_MAC_MINI_INTERNAL, + RADEON_MAC_IMAC_G5_ISIGHT +}; +#endif + + #define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ - DRM_READ32( (dev_priv)->ring_rptr, 0 ) : RADEON_READ(RADEON_CP_RB_RPTR)) -#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) + (dev_priv->mm.ring_read_ptr ? readl(dev_priv->mm.ring_read_ptr_map.virtual + 0) : DRM_READ32((dev_priv)->ring_rptr, 0 )) : \ + RADEON_READ(RADEON_CP_RB_RPTR)) + +#define SET_RING_HEAD(dev_priv,val) (dev_priv->mm.ring_read_ptr ? \ + writel((val), dev_priv->mm.ring_read_ptr_map.virtual) : \ + DRM_WRITE32((dev_priv)->ring_rptr, 0, (val))) typedef struct drm_radeon_freelist { unsigned int age; @@ -221,13 +261,35 @@ struct radeon_virt_surface { struct drm_file *file_priv; }; +struct radeon_mm_info { + uint64_t vram_offset; // Offset into GPU space + uint64_t vram_size; + uint64_t vram_visible; + + uint64_t gart_start; + uint64_t gart_size; + + struct drm_buffer_object *pcie_table; + struct drm_bo_kmap_obj pcie_table_map; + + struct drm_buffer_object *ring; + struct drm_bo_kmap_obj ring_map; + + struct drm_buffer_object *ring_read_ptr; + struct drm_bo_kmap_obj ring_read_ptr_map; +}; + +#include "radeon_mode.h" + +struct drm_radeon_master_private { + drm_local_map_t *sarea; + drm_radeon_sarea_t *sarea_priv; +}; + typedef struct drm_radeon_private { drm_radeon_ring_buffer_t ring; - drm_radeon_sarea_t *sarea_priv; - u32 fb_location; - u32 fb_size; int new_memmap; int gart_size; @@ -245,8 +307,6 @@ typedef struct drm_radeon_private { int usec_timeout; - int microcode_version; - struct { u32 boxes; int freelist_timeouts; @@ -282,8 +342,6 @@ typedef struct drm_radeon_private { unsigned long buffers_offset; unsigned long gart_textures_offset; - drm_local_map_t *sarea; - drm_local_map_t *mmio; drm_local_map_t *cp_ring; drm_local_map_t *ring_rptr; drm_local_map_t *gart_textures; @@ -292,8 +350,8 @@ typedef struct drm_radeon_private { struct mem_block *fb_heap; /* SW interrupt */ + int counter; wait_queue_head_t swi_queue; - atomic_t swi_emitted; int vblank_crtc; uint32_t irq_enable_reg; int irq_enabled; @@ -302,9 +360,6 @@ typedef struct drm_radeon_private { struct radeon_surface surfaces[RADEON_MAX_SURFACES]; struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES]; - unsigned long pcigart_offset; - unsigned int pcigart_offset_set; - struct drm_ati_pcigart_info gart_info; u32 scratch_ages[5]; @@ -316,6 +371,28 @@ typedef struct drm_radeon_private { unsigned long fb_aper_offset; int num_gb_pipes; + + struct radeon_mm_info mm; + drm_local_map_t *mmio; + + uint32_t chip_family; + + unsigned long pcigart_offset; + unsigned int pcigart_offset_set; + struct drm_ati_pcigart_info gart_info; + + struct radeon_mode_info mode_info; + + uint8_t *bios; /* copy of the BIOS image */ + bool is_atom_bios; + uint16_t bios_header_start; + u32 fb_location; + u32 fb_size; + bool is_ddr; + u32 ram_width; + + enum radeon_pll_errata pll_errata; + } drm_radeon_private_t; typedef struct drm_radeon_buf_priv { @@ -330,6 +407,7 @@ typedef struct drm_radeon_kcmd_buffer { } drm_radeon_kcmd_buffer_t; extern int radeon_no_wb; +extern int radeon_dynclks; extern struct drm_ioctl_desc radeon_ioctls[]; extern int radeon_max_ioctl; @@ -417,9 +495,14 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, #define RADEON_BOX_WAIT_IDLE 0x8 #define RADEON_BOX_TEXTURE_LOAD 0x10 +#define R600_CONFIG_MEMSIZE 0x5428 +#define R600_CONFIG_APER_SIZE 0x5430 /* Register definitions, register access macros and drmAddMap constants * for Radeon kernel driver. */ + +#include "radeon_reg.h" + #define RADEON_AGP_COMMAND 0x0f60 #define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */ # define RADEON_AGP_ENABLE (1<<8) @@ -522,16 +605,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, #define R520_MC_IND_WR_EN (1 << 24) #define R520_MC_IND_DATA 0x74 -#define RV515_MC_FB_LOCATION 0x01 -#define RV515_MC_AGP_LOCATION 0x02 -#define RV515_MC_AGP_BASE 0x03 -#define RV515_MC_AGP_BASE_2 0x04 - -#define R520_MC_FB_LOCATION 0x04 -#define R520_MC_AGP_LOCATION 0x05 -#define R520_MC_AGP_BASE 0x06 -#define R520_MC_AGP_BASE_2 0x07 - #define RADEON_MPP_TB_CONFIG 0x01c0 #define RADEON_MEM_CNTL 0x0140 #define RADEON_MEM_SDRAM_MODE_REG 0x0158 @@ -601,9 +674,11 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, #define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x)) -#define GET_SCRATCH( x ) (dev_priv->writeback_works \ - ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \ - : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) ) +#define GET_SCRATCH( x ) (dev_priv->writeback_works ? \ + (dev_priv->mm.ring_read_ptr ? \ + readl(dev_priv->mm.ring_read_ptr_map.virtual + RADEON_SCRATCHOFF(0)) : \ + DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(x))) : \ + RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x))) #define RADEON_CRTC_CRNT_FRAME 0x0214 #define RADEON_CRTC2_CRNT_FRAME 0x0314 @@ -628,11 +703,11 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, # define RADEON_SW_INT_FIRE (1 << 26) # define R500_DISPLAY_INT_STATUS (1 << 0) +#define RADEON_HOST_PATH_CNTL 0x0130 +# define RADEON_HDP_SOFT_RESET (1 << 26) +# define RADEON_HDP_APER_CNTL (1 << 23) -#define RADEON_HOST_PATH_CNTL 0x0130 -# define RADEON_HDP_SOFT_RESET (1 << 26) -# define RADEON_HDP_WC_TIMEOUT_MASK (7 << 28) -# define RADEON_HDP_WC_TIMEOUT_28BCLK (7 << 28) +#define RADEON_NB_TOM 0x15c #define RADEON_ISYNC_CNTL 0x1724 # define RADEON_ISYNC_ANY2D_IDLE3D (1 << 0) @@ -703,11 +778,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, # define R300_ZC_FREE (1 << 1) # define R300_ZC_FLUSH_ALL 0x3 # define R300_ZC_BUSY (1 << 31) -#define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325c -# define RADEON_RB3D_DC_FLUSH (3 << 0) -# define RADEON_RB3D_DC_FREE (3 << 2) -# define RADEON_RB3D_DC_FLUSH_ALL 0xf -# define RADEON_RB3D_DC_BUSY (1 << 31) #define R300_RB3D_DSTCACHE_CTLSTAT 0x4e4c # define R300_RB3D_DC_FINISH (1 << 4) #define RADEON_RB3D_ZSTENCILCNTL 0x1c2c @@ -981,27 +1051,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, #define RADEON_NUM_VERTICES_SHIFT 16 #define RADEON_COLOR_FORMAT_CI8 2 -#define RADEON_COLOR_FORMAT_ARGB1555 3 -#define RADEON_COLOR_FORMAT_RGB565 4 -#define RADEON_COLOR_FORMAT_ARGB8888 6 -#define RADEON_COLOR_FORMAT_RGB332 7 -#define RADEON_COLOR_FORMAT_RGB8 9 -#define RADEON_COLOR_FORMAT_ARGB4444 15 - -#define RADEON_TXFORMAT_I8 0 -#define RADEON_TXFORMAT_AI88 1 -#define RADEON_TXFORMAT_RGB332 2 -#define RADEON_TXFORMAT_ARGB1555 3 -#define RADEON_TXFORMAT_RGB565 4 -#define RADEON_TXFORMAT_ARGB4444 5 -#define RADEON_TXFORMAT_ARGB8888 6 -#define RADEON_TXFORMAT_RGBA8888 7 -#define RADEON_TXFORMAT_Y8 8 -#define RADEON_TXFORMAT_VYUY422 10 -#define RADEON_TXFORMAT_YVYU422 11 -#define RADEON_TXFORMAT_DXT1 12 -#define RADEON_TXFORMAT_DXT23 14 -#define RADEON_TXFORMAT_DXT45 15 #define R200_PP_TXCBLEND_0 0x2f00 #define R200_PP_TXCBLEND_1 0x2f10 @@ -1187,18 +1236,16 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, #define RADEON_RING_HIGH_MARK 128 #define RADEON_PCIGART_TABLE_SIZE (32*1024) +#define RADEON_DEFAULT_RING_SIZE (1024*1024) +#define RADEON_DEFAULT_CP_TIMEOUT 100000 /* usecs */ #define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) #define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) #define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) #define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) ) -#define RADEON_WRITE_PLL( addr, val ) \ -do { \ - RADEON_WRITE8( RADEON_CLOCK_CNTL_INDEX, \ - ((addr) & 0x1f) | RADEON_PLL_WR_EN ); \ - RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \ -} while (0) +extern int RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr); +extern void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint32_t data); #define RADEON_WRITE_PCIE( addr, val ) \ do { \ @@ -1311,7 +1358,7 @@ do { \ OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \ OUT_RING( RADEON_RB3D_ZC_FLUSH_ALL ); \ } else { \ - OUT_RING( CP_PACKET0( R300_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \ + OUT_RING( CP_PACKET0( R300_RB3D_ZCACHE_CTLSTAT, 0 ) ); \ OUT_RING( R300_ZC_FLUSH_ALL ); \ } \ } while (0) @@ -1333,7 +1380,8 @@ do { \ #define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ do { \ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; \ + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; \ + drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; \ if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \ int __ret = radeon_do_cp_idle( dev_priv ); \ if ( __ret ) return __ret; \ @@ -1439,4 +1487,110 @@ do { \ write &= mask; \ } while (0) +/* radeon GEM->TTM munger */ +struct drm_radeon_gem_object { + /* wrap a TTM bo */ + struct drm_buffer_object *bo; + struct drm_fence_object *fence; + struct drm_gem_object *obj; + +}; + +extern int radeon_gem_info_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +extern int radeon_gem_create_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +extern int radeon_gem_pwrite_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +extern int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int radeon_gem_pread_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +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); + +/* 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 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); + +extern void radeon_gart_flush(struct drm_device *dev); +extern uint64_t radeon_evict_flags(struct drm_buffer_object *bo); + +#define BREADCRUMB_BITS 31 +#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1) + +/* Breadcrumb - swi irq */ +#define READ_BREADCRUMB(dev_priv) RADEON_READ(RADEON_LAST_SWI_REG) + +static inline int radeon_update_breadcrumb(struct drm_device *dev) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + struct drm_radeon_master_private *master_priv; + + ++dev_priv->counter; + if (dev_priv->counter > BREADCRUMB_MASK) + dev_priv->counter = 1; + + if (dev->primary->master) { + master_priv = dev->primary->master->driver_priv; + + if (master_priv->sarea_priv) + master_priv->sarea_priv->last_fence = dev_priv->counter; + } + return dev_priv->counter; +} + +#define radeon_is_avivo(dev_priv) ((dev_priv->chip_family >= CHIP_RS600)) + +#define radeon_is_dce3(dev_priv) ((dev_priv->chip_family >= CHIP_RV620)) + +#define radeon_bios8(dev_priv, v) (dev_priv->bios[v]) +#define radeon_bios16(dev_priv, v) (dev_priv->bios[v] | (dev_priv->bios[(v) + 1] << 8)) +#define radeon_bios32(dev_priv, v) ((dev_priv->bios[v]) | \ + (dev_priv->bios[(v) + 1] << 8) | \ + (dev_priv->bios[(v) + 2] << 16) | \ + (dev_priv->bios[(v) + 3] << 24)) + +extern int radeon_emit_irq(struct drm_device * dev); + +extern void radeon_gem_free_object(struct drm_gem_object *obj); +extern int radeon_gem_init_object(struct drm_gem_object *obj); +extern int radeon_gem_mm_init(struct drm_device *dev); +extern void radeon_gem_mm_fini(struct drm_device *dev); +extern int radeon_gem_pin_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +int radeon_gem_object_pin(struct drm_gem_object *obj, + uint32_t alignment); +int radeon_gem_indirect_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +struct drm_gem_object *radeon_gem_object_alloc(struct drm_device *dev, int size, int alignment, + int initial_domain); +int radeon_modeset_init(struct drm_device *dev); +void radeon_modeset_cleanup(struct drm_device *dev); +extern u32 radeon_read_mc_reg(drm_radeon_private_t *dev_priv, int addr); +extern void radeon_write_mc_reg(drm_radeon_private_t *dev_priv, u32 addr, u32 val); + +extern void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on); +#define RADEONFB_CONN_LIMIT 4 + +extern int radeon_master_create(struct drm_device *dev, struct drm_master *master); +extern void radeon_master_destroy(struct drm_device *dev, struct drm_master *master); +extern void radeon_cp_dispatch_flip(struct drm_device * dev, struct drm_master *master); #endif /* __RADEON_DRV_H__ */ diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c index d21761fb..f5f7f75d 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -198,8 +198,10 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) stat &= dev_priv->irq_enable_reg; /* SW interrupt */ - if (stat & RADEON_SW_INT_TEST) + if (stat & RADEON_SW_INT_TEST) { DRM_WAKEUP(&dev_priv->swi_queue); + radeon_fence_handler(dev); + } /* VBLANK interrupt */ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { @@ -216,14 +218,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); @@ -240,13 +241,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); + READ_BREADCRUMB(dev_priv) >= swi_nr); return ret; } @@ -349,7 +350,6 @@ 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); ret = drm_vblank_init(dev, 2); diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index 1d550a9f..6de4b135 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -305,8 +305,9 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * case RADEON_CP_3D_DRAW_INDX_2: case RADEON_3D_CLEAR_HIZ: /* safe but r200 only */ - if (dev_priv->microcode_version != UCODE_R200) { - DRM_ERROR("Invalid 3d packet for r100-class chip\n"); + if ((dev_priv->chip_family < CHIP_R200) || + (dev_priv->chip_family > CHIP_RV280)) { + DRM_ERROR("Invalid 3d packet for non r200-class chip\n"); return -EINVAL; } break; @@ -359,8 +360,8 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * break; case RADEON_3D_RNDR_GEN_INDX_PRIM: - if (dev_priv->microcode_version != UCODE_R100) { - DRM_ERROR("Invalid 3d packet for r200-class chip\n"); + if (dev_priv->chip_family > CHIP_RS200) { + DRM_ERROR("Invalid 3d packet for non-r100-class chip\n"); return -EINVAL; } if (radeon_check_and_fixup_offset(dev_priv, file_priv, &cmd[1])) { @@ -370,8 +371,10 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * break; case RADEON_CP_INDX_BUFFER: - if (dev_priv->microcode_version != UCODE_R200) { - DRM_ERROR("Invalid 3d packet for r100-class chip\n"); + /* safe but r200 only */ + if ((dev_priv->chip_family < CHIP_R200) || + (dev_priv->chip_family > CHIP_RV280)) { + DRM_ERROR("Invalid 3d packet for non-r200-class chip\n"); return -EINVAL; } if ((cmd[1] & 0x8000ffff) != 0x80000810) { @@ -742,13 +745,14 @@ static struct { */ static void radeon_clear_box(drm_radeon_private_t * dev_priv, + struct drm_radeon_master_private *master_priv, int x, int y, int w, int h, int r, int g, int b) { u32 color; RING_LOCALS; - x += dev_priv->sarea_priv->boxes[0].x1; - y += dev_priv->sarea_priv->boxes[0].y1; + x += master_priv->sarea_priv->boxes[0].x1; + y += master_priv->sarea_priv->boxes[0].y1; switch (dev_priv->color_fmt) { case RADEON_COLOR_FORMAT_RGB565: @@ -776,7 +780,7 @@ static void radeon_clear_box(drm_radeon_private_t * dev_priv, RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS); - if (dev_priv->sarea_priv->pfCurrentPage == 1) { + if (master_priv->sarea_priv->pfCurrentPage == 1) { OUT_RING(dev_priv->front_pitch_offset); } else { OUT_RING(dev_priv->back_pitch_offset); @@ -790,7 +794,7 @@ static void radeon_clear_box(drm_radeon_private_t * dev_priv, ADVANCE_RING(); } -static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv) +static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv, struct drm_radeon_master_private *master_priv) { /* Collapse various things into a wait flag -- trying to * guess if userspase slept -- better just to have them tell us. @@ -807,12 +811,12 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv) /* Purple box for page flipping */ if (dev_priv->stats.boxes & RADEON_BOX_FLIP) - radeon_clear_box(dev_priv, 4, 4, 8, 8, 255, 0, 255); + radeon_clear_box(dev_priv, master_priv, 4, 4, 8, 8, 255, 0, 255); /* Red box if we have to wait for idle at any point */ if (dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE) - radeon_clear_box(dev_priv, 16, 4, 8, 8, 255, 0, 0); + radeon_clear_box(dev_priv, master_priv, 16, 4, 8, 8, 255, 0, 0); /* Blue box: lost context? */ @@ -820,12 +824,12 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv) /* Yellow box for texture swaps */ if (dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD) - radeon_clear_box(dev_priv, 40, 4, 8, 8, 255, 255, 0); + radeon_clear_box(dev_priv, master_priv, 40, 4, 8, 8, 255, 255, 0); /* Green box if hardware never idles (as far as we can tell) */ if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE)) - radeon_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0); + radeon_clear_box(dev_priv, master_priv, 64, 4, 8, 8, 0, 255, 0); /* Draw bars indicating number of buffers allocated * (not a great measure, easily confused) @@ -834,7 +838,7 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv) if (dev_priv->stats.requested_bufs > 100) dev_priv->stats.requested_bufs = 100; - radeon_clear_box(dev_priv, 4, 16, + radeon_clear_box(dev_priv, master_priv, 4, 16, dev_priv->stats.requested_bufs, 4, 196, 128, 128); } @@ -848,11 +852,13 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv) */ static void radeon_cp_dispatch_clear(struct drm_device * dev, + struct drm_master *master, drm_radeon_clear_t * clear, drm_radeon_clear_rect_t * depth_boxes) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + struct drm_radeon_master_private *master_priv = master->driver_priv; + drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear; int nbox = sarea_priv->nbox; struct drm_clip_rect *pbox = sarea_priv->boxes; @@ -864,7 +870,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, dev_priv->stats.clears++; - if (dev_priv->sarea_priv->pfCurrentPage == 1) { + if (sarea_priv->pfCurrentPage == 1) { unsigned int tmp = flags; flags &= ~(RADEON_FRONT | RADEON_BACK); @@ -890,7 +896,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, /* Make sure we restore the 3D state next time. */ - dev_priv->sarea_priv->ctx_owner = 0; + sarea_priv->ctx_owner = 0; for (i = 0; i < nbox; i++) { int x = pbox[i].x1; @@ -967,7 +973,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, /* Make sure we restore the 3D state next time. * we haven't touched any "normal" state - still need this? */ - dev_priv->sarea_priv->ctx_owner = 0; + sarea_priv->ctx_owner = 0; if ((dev_priv->flags & RADEON_HAS_HIERZ) && (flags & RADEON_USE_HIERZ)) { @@ -1015,7 +1021,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, int tileoffset, nrtilesx, nrtilesy, j; /* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */ if ((dev_priv->flags & RADEON_HAS_HIERZ) - && !(dev_priv->microcode_version == UCODE_R200)) { + && (dev_priv->chip_family < CHIP_R200)) { /* FIXME : figure this out for r200 (when hierz is enabled). Or maybe r200 actually doesn't need to put the low-res z value into the tile cache like r100, but just needs to clear the hi-level z-buffer? @@ -1044,7 +1050,8 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, ADVANCE_RING(); tileoffset += depthpixperline >> 6; } - } else if (dev_priv->microcode_version == UCODE_R200) { + } else if ((dev_priv->chip_family >= CHIP_R200) && + (dev_priv->chip_family <= CHIP_RV280)) { /* works for rv250. */ /* find first macro tile (8x2 4x4 z-pixels on rv250) */ tileoffset = @@ -1099,7 +1106,8 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, /* TODO don't always clear all hi-level z tiles */ if ((dev_priv->flags & RADEON_HAS_HIERZ) - && (dev_priv->microcode_version == UCODE_R200) + && ((dev_priv->chip_family >= CHIP_R200) && + (dev_priv->chip_family <= CHIP_RV280)) && (flags & RADEON_USE_HIERZ)) /* r100 and cards without hierarchical z-buffer have no high-level z-buffer */ /* FIXME : the mask supposedly contains low-res z values. So can't set @@ -1119,8 +1127,9 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, * rendering a quad into just those buffers. Thus, we have to * make sure the 3D engine is configured correctly. */ - else if ((dev_priv->microcode_version == UCODE_R200) && - (flags & (RADEON_DEPTH | RADEON_STENCIL))) { + else if ((dev_priv->chip_family >= CHIP_R200) && + (dev_priv->chip_family <= CHIP_RV280) && + (flags & (RADEON_DEPTH | RADEON_STENCIL))) { int tempPP_CNTL; int tempRE_CNTL; @@ -1214,7 +1223,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, /* Make sure we restore the 3D state next time. */ - dev_priv->sarea_priv->ctx_owner = 0; + sarea_priv->ctx_owner = 0; for (i = 0; i < nbox; i++) { @@ -1285,7 +1294,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, /* Make sure we restore the 3D state next time. */ - dev_priv->sarea_priv->ctx_owner = 0; + sarea_priv->ctx_owner = 0; for (i = 0; i < nbox; i++) { @@ -1328,20 +1337,21 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, * wait on this value before performing the clear ioctl. We * need this because the card's so damned fast... */ - dev_priv->sarea_priv->last_clear++; + sarea_priv->last_clear++; BEGIN_RING(4); - RADEON_CLEAR_AGE(dev_priv->sarea_priv->last_clear); + RADEON_CLEAR_AGE(sarea_priv->last_clear); RADEON_WAIT_UNTIL_IDLE(); ADVANCE_RING(); } -static void radeon_cp_dispatch_swap(struct drm_device * dev) +static void radeon_cp_dispatch_swap(struct drm_device * dev, struct drm_master *master) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + struct drm_radeon_master_private *master_priv = master->driver_priv; + drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; int nbox = sarea_priv->nbox; struct drm_clip_rect *pbox = sarea_priv->boxes; int i; @@ -1351,7 +1361,7 @@ static void radeon_cp_dispatch_swap(struct drm_device * dev) /* Do some trivial performance monitoring... */ if (dev_priv->do_boxes) - radeon_cp_performance_boxes(dev_priv); + radeon_cp_performance_boxes(dev_priv, master_priv); /* Wait for the 3D stream to idle before dispatching the bitblt. * This will prevent data corruption between the two streams. @@ -1385,7 +1395,7 @@ static void radeon_cp_dispatch_swap(struct drm_device * dev) /* Make this work even if front & back are flipped: */ OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1)); - if (dev_priv->sarea_priv->pfCurrentPage == 0) { + if (sarea_priv->pfCurrentPage == 0) { OUT_RING(dev_priv->back_pitch_offset); OUT_RING(dev_priv->front_pitch_offset); } else { @@ -1405,31 +1415,32 @@ static void radeon_cp_dispatch_swap(struct drm_device * dev) * throttle the framerate by waiting for this value before * performing the swapbuffer ioctl. */ - dev_priv->sarea_priv->last_frame++; + sarea_priv->last_frame++; BEGIN_RING(4); - RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame); + RADEON_FRAME_AGE(sarea_priv->last_frame); RADEON_WAIT_UNTIL_2D_IDLE(); ADVANCE_RING(); } -static void radeon_cp_dispatch_flip(struct drm_device * dev) +void radeon_cp_dispatch_flip(struct drm_device * dev, struct drm_master *master) { drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_sarea *sarea = (struct drm_sarea *) dev_priv->sarea->handle; - int offset = (dev_priv->sarea_priv->pfCurrentPage == 1) + struct drm_radeon_master_private *master_priv = master->driver_priv; + struct drm_sarea *sarea = (struct drm_sarea *) master_priv->sarea->handle; + int offset = (master_priv->sarea_priv->pfCurrentPage == 1) ? dev_priv->front_offset : dev_priv->back_offset; RING_LOCALS; DRM_DEBUG("pfCurrentPage=%d\n", - dev_priv->sarea_priv->pfCurrentPage); + master_priv->sarea_priv->pfCurrentPage); /* Do some trivial performance monitoring... */ if (dev_priv->do_boxes) { dev_priv->stats.boxes |= RADEON_BOX_FLIP; - radeon_cp_performance_boxes(dev_priv); + radeon_cp_performance_boxes(dev_priv, master_priv); } /* Update the frame offsets for both CRTCs @@ -1441,7 +1452,7 @@ static void radeon_cp_dispatch_flip(struct drm_device * dev) ((sarea->frame.y * dev_priv->front_pitch + sarea->frame.x * (dev_priv->color_fmt - 2)) & ~7) + offset); - OUT_RING_REG(RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base + OUT_RING_REG(RADEON_CRTC2_OFFSET, master_priv->sarea_priv->crtc2_base + offset); ADVANCE_RING(); @@ -1450,13 +1461,13 @@ static void radeon_cp_dispatch_flip(struct drm_device * dev) * throttle the framerate by waiting for this value before * performing the swapbuffer ioctl. */ - dev_priv->sarea_priv->last_frame++; - dev_priv->sarea_priv->pfCurrentPage = - 1 - dev_priv->sarea_priv->pfCurrentPage; + master_priv->sarea_priv->last_frame++; + master_priv->sarea_priv->pfCurrentPage = + 1 - master_priv->sarea_priv->pfCurrentPage; BEGIN_RING(2); - RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame); + RADEON_FRAME_AGE(master_priv->sarea_priv->last_frame); ADVANCE_RING(); } @@ -1494,11 +1505,13 @@ typedef struct { } drm_radeon_tcl_prim_t; static void radeon_cp_dispatch_vertex(struct drm_device * dev, + struct drm_file *file_priv, struct drm_buf * buf, drm_radeon_tcl_prim_t * prim) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; + drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; int offset = dev_priv->gart_buffers_offset + buf->offset + prim->start; int numverts = (int)prim->numverts; int nbox = sarea_priv->nbox; @@ -1539,13 +1552,14 @@ static void radeon_cp_dispatch_vertex(struct drm_device * dev, } while (i < nbox); } -static void radeon_cp_discard_buffer(struct drm_device * dev, struct drm_buf * buf) +static void radeon_cp_discard_buffer(struct drm_device * dev, struct drm_master *master, struct drm_buf * buf) { drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_radeon_master_private *master_priv = master->driver_priv; drm_radeon_buf_priv_t *buf_priv = buf->dev_private; RING_LOCALS; - buf_priv->age = ++dev_priv->sarea_priv->last_dispatch; + buf_priv->age = ++master_priv->sarea_priv->last_dispatch; /* Emit the vertex buffer age */ BEGIN_RING(2); @@ -1590,12 +1604,14 @@ static void radeon_cp_dispatch_indirect(struct drm_device * dev, } } -static void radeon_cp_dispatch_indices(struct drm_device * dev, +static void radeon_cp_dispatch_indices(struct drm_device *dev, + struct drm_master *master, struct drm_buf * elt_buf, drm_radeon_tcl_prim_t * prim) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + struct drm_radeon_master_private *master_priv = master->driver_priv; + drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; int offset = dev_priv->gart_buffers_offset + prim->offset; u32 *data; int dwords; @@ -1870,7 +1886,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev, ADVANCE_RING(); COMMIT_RING(); - radeon_cp_discard_buffer(dev, buf); + radeon_cp_discard_buffer(dev, file_priv->master, buf); /* Update the input parameters for next time */ image->y += height; @@ -2120,7 +2136,8 @@ static int radeon_surface_free(struct drm_device *dev, void *data, struct drm_fi static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; + drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; drm_radeon_clear_t *clear = data; drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; DRM_DEBUG("\n"); @@ -2136,7 +2153,7 @@ static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file * sarea_priv->nbox * sizeof(depth_boxes[0]))) return -EFAULT; - radeon_cp_dispatch_clear(dev, clear, depth_boxes); + radeon_cp_dispatch_clear(dev, file_priv->master, clear, depth_boxes); COMMIT_RING(); return 0; @@ -2144,9 +2161,10 @@ static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file * /* Not sure why this isn't set all the time: */ -static int radeon_do_init_pageflip(struct drm_device * dev) +static int radeon_do_init_pageflip(struct drm_device * dev, struct drm_master *master) { drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_radeon_master_private *master_priv = master->driver_priv; RING_LOCALS; DRM_DEBUG("\n"); @@ -2163,8 +2181,8 @@ static int radeon_do_init_pageflip(struct drm_device * dev) dev_priv->page_flipping = 1; - if (dev_priv->sarea_priv->pfCurrentPage != 1) - dev_priv->sarea_priv->pfCurrentPage = 0; + if (master_priv->sarea_priv->pfCurrentPage != 1) + master_priv->sarea_priv->pfCurrentPage = 0; return 0; } @@ -2182,9 +2200,9 @@ static int radeon_cp_flip(struct drm_device *dev, void *data, struct drm_file *f RING_SPACE_TEST_WITH_RETURN(dev_priv); if (!dev_priv->page_flipping) - radeon_do_init_pageflip(dev); + radeon_do_init_pageflip(dev, file_priv->master); - radeon_cp_dispatch_flip(dev); + radeon_cp_dispatch_flip(dev, file_priv->master); COMMIT_RING(); return 0; @@ -2193,7 +2211,9 @@ static int radeon_cp_flip(struct drm_device *dev, void *data, struct drm_file *f static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; + drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; + DRM_DEBUG("\n"); LOCK_TEST_WITH_RETURN(dev, file_priv); @@ -2203,8 +2223,8 @@ static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *f if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; - radeon_cp_dispatch_swap(dev); - dev_priv->sarea_priv->ctx_owner = 0; + radeon_cp_dispatch_swap(dev, file_priv->master); + sarea_priv->ctx_owner = 0; COMMIT_RING(); return 0; @@ -2213,6 +2233,7 @@ static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *f static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; drm_radeon_sarea_t *sarea_priv; struct drm_device_dma *dma = dev->dma; struct drm_buf *buf; @@ -2226,7 +2247,7 @@ static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file return -EINVAL; } - sarea_priv = dev_priv->sarea_priv; + sarea_priv = master_priv->sarea_priv; DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n", DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard); @@ -2280,13 +2301,13 @@ static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file prim.finish = vertex->count; /* unused */ prim.prim = vertex->prim; prim.numverts = vertex->count; - prim.vc_format = dev_priv->sarea_priv->vc_format; + prim.vc_format = sarea_priv->vc_format; - radeon_cp_dispatch_vertex(dev, buf, &prim); + radeon_cp_dispatch_vertex(dev, file_priv, buf, &prim); } if (vertex->discard) { - radeon_cp_discard_buffer(dev, buf); + radeon_cp_discard_buffer(dev, file_priv->master, buf); } COMMIT_RING(); @@ -2296,6 +2317,7 @@ static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; drm_radeon_sarea_t *sarea_priv; struct drm_device_dma *dma = dev->dma; struct drm_buf *buf; @@ -2309,7 +2331,7 @@ static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file DRM_ERROR("called with no initialization\n"); return -EINVAL; } - sarea_priv = dev_priv->sarea_priv; + sarea_priv = master_priv->sarea_priv; DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n", DRM_CURRENTPID, elts->idx, elts->start, elts->end, @@ -2376,11 +2398,11 @@ static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file prim.prim = elts->prim; prim.offset = 0; /* offset from start of dma buffers */ prim.numverts = RADEON_MAX_VB_VERTS; /* duh */ - prim.vc_format = dev_priv->sarea_priv->vc_format; + prim.vc_format = sarea_priv->vc_format; - radeon_cp_dispatch_indices(dev, buf, &prim); + radeon_cp_dispatch_indices(dev, file_priv->master, buf, &prim); if (elts->discard) { - radeon_cp_discard_buffer(dev, buf); + radeon_cp_discard_buffer(dev, file_priv->master, buf); } COMMIT_RING(); @@ -2496,7 +2518,7 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil */ radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); if (indirect->discard) { - radeon_cp_discard_buffer(dev, buf); + radeon_cp_discard_buffer(dev, file_priv->master, buf); } COMMIT_RING(); @@ -2506,6 +2528,7 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; drm_radeon_sarea_t *sarea_priv; struct drm_device_dma *dma = dev->dma; struct drm_buf *buf; @@ -2520,7 +2543,7 @@ static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file return -EINVAL; } - sarea_priv = dev_priv->sarea_priv; + sarea_priv = master_priv->sarea_priv; DRM_DEBUG("pid=%d index=%d discard=%d\n", DRM_CURRENTPID, vertex->idx, vertex->discard); @@ -2582,12 +2605,12 @@ static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file tclprim.offset = prim.numverts * 64; tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */ - radeon_cp_dispatch_indices(dev, buf, &tclprim); + radeon_cp_dispatch_indices(dev, file_priv->master, buf, &tclprim); } else { tclprim.numverts = prim.numverts; tclprim.offset = 0; /* not used */ - radeon_cp_dispatch_vertex(dev, buf, &tclprim); + radeon_cp_dispatch_vertex(dev, file_priv, buf, &tclprim); } if (sarea_priv->nbox == 1) @@ -2595,7 +2618,7 @@ static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file } if (vertex->discard) { - radeon_cp_discard_buffer(dev, buf); + radeon_cp_discard_buffer(dev, file_priv->master, buf); } COMMIT_RING(); @@ -2889,7 +2912,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file orig_nbox = cmdbuf->nbox; - if (dev_priv->microcode_version == UCODE_R300) { + if (dev_priv->chip_family >= CHIP_R300) { int temp; temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf); @@ -2949,7 +2972,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file goto err; } - radeon_cp_discard_buffer(dev, buf); + radeon_cp_discard_buffer(dev, file_priv->master, buf); break; case RADEON_CMD_PACKET3: @@ -3110,6 +3133,7 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; drm_radeon_setparam_t *sp = data; struct drm_radeon_driver_file_fields *radeon_priv; @@ -3129,14 +3153,14 @@ static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_fil DRM_DEBUG("color tiling disabled\n"); dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO; dev_priv->back_pitch_offset &= ~RADEON_DST_TILE_MACRO; - if (dev_priv->sarea_priv) - dev_priv->sarea_priv->tiling_enabled = 0; + if (master_priv->sarea_priv) + master_priv->sarea_priv->tiling_enabled = 0; } else if (sp->value == 1) { DRM_DEBUG("color tiling enabled\n"); dev_priv->front_pitch_offset |= RADEON_DST_TILE_MACRO; dev_priv->back_pitch_offset |= RADEON_DST_TILE_MACRO; - if (dev_priv->sarea_priv) - dev_priv->sarea_priv->tiling_enabled = 1; + if (master_priv->sarea_priv) + master_priv->sarea_priv->tiling_enabled = 1; } break; case RADEON_SETPARAM_PCIGART_LOCATION: @@ -3183,14 +3207,6 @@ void radeon_driver_preclose(struct drm_device *dev, void radeon_driver_lastclose(struct drm_device *dev) { - if (dev->dev_private) { - drm_radeon_private_t *dev_priv = dev->dev_private; - - if (dev_priv->sarea_priv && - dev_priv->sarea_priv->pfCurrentPage != 0) - radeon_cp_dispatch_flip(dev); - } - radeon_do_release(dev); } @@ -3251,7 +3267,18 @@ struct drm_ioctl_desc radeon_ioctls[] = { DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH) + DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH), + + DRM_IOCTL_DEF(DRM_RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH), + + DRM_IOCTL_DEF(DRM_RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_GEM_PIN, radeon_gem_pin_ioctl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_GEM_UNPIN, radeon_gem_unpin_ioctl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_GEM_INDIRECT, radeon_gem_indirect_ioctl, DRM_AUTH), }; int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); -- cgit v1.2.3 From 38835f9cd2b44cfb6587a52ba1bfe292b958d0e1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 28 Jul 2008 15:21:13 +1000 Subject: radeon command submission start take code from Jerome munge into a TTM IB re-use --- shared-core/radeon_cp.c | 30 +++++--- shared-core/radeon_cs.c | 181 +++++++++++++++++++++++++++++++++++++++++++++ shared-core/radeon_drm.h | 15 ++++ shared-core/radeon_drv.h | 56 ++++++++++---- shared-core/radeon_state.c | 1 + 5 files changed, 256 insertions(+), 27 deletions(-) create mode 100644 shared-core/radeon_cs.c (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 80951e91..46f4290a 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -658,8 +658,8 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, ((dev_priv->gart_vm_start - 1) & 0xffff0000) | (dev_priv->fb_location >> 16)); - if (dev_priv->mm.ring) { - ring_start = dev_priv->mm.ring->offset + + if (dev_priv->mm.ring.bo) { + ring_start = dev_priv->mm.ring.bo->offset + dev_priv->gart_vm_start; } else #if __OS_HAS_AGP @@ -692,9 +692,9 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, dev_priv->ring.tail = cur_read_ptr; - if (dev_priv->mm.ring_read_ptr) { + if (dev_priv->mm.ring_read.bo) { RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, - dev_priv->mm.ring_read_ptr->offset + + dev_priv->mm.ring_read.bo->offset + dev_priv->gart_vm_start); } else #if __OS_HAS_AGP @@ -745,9 +745,9 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) + RADEON_SCRATCH_REG_OFFSET); - if (dev_priv->mm.ring_read_ptr) + if (dev_priv->mm.ring_read.bo) dev_priv->scratch = ((__volatile__ u32 *) - dev_priv->mm.ring_read_ptr_map.virtual + + dev_priv->mm.ring_read.kmap.virtual + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); else dev_priv->scratch = ((__volatile__ u32 *) @@ -772,12 +772,18 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, radeon_do_wait_for_idle(dev_priv); /* Sync everything up */ + if (dev_priv->chip_family > CHIP_RV280) { RADEON_WRITE(RADEON_ISYNC_CNTL, (RADEON_ISYNC_ANY2D_IDLE3D | RADEON_ISYNC_ANY3D_IDLE2D | RADEON_ISYNC_WAIT_IDLEGUI | RADEON_ISYNC_CPSCRATCH_IDLEGUI)); - + } else { + RADEON_WRITE(RADEON_ISYNC_CNTL, + (RADEON_ISYNC_ANY2D_IDLE3D | + RADEON_ISYNC_ANY3D_IDLE2D | + RADEON_ISYNC_WAIT_IDLEGUI)); + } } static void radeon_test_writeback(drm_radeon_private_t * dev_priv) @@ -785,8 +791,8 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv) u32 tmp; void *ring_read_ptr; - if (dev_priv->mm.ring_read_ptr) - ring_read_ptr = dev_priv->mm.ring_read_ptr_map.virtual; + if (dev_priv->mm.ring_read.bo) + ring_read_ptr = dev_priv->mm.ring_read.kmap.virtual; else ring_read_ptr = dev_priv->ring_rptr->handle; @@ -2282,8 +2288,8 @@ int radeon_modeset_cp_init(struct drm_device *dev) dev_priv->ring.size = RADEON_DEFAULT_RING_SIZE; dev_priv->cp_mode = RADEON_CSQ_PRIBM_INDBM; - dev_priv->ring.start = (u32 *)(void *)(unsigned long)dev_priv->mm.ring_map.virtual; - dev_priv->ring.end = (u32 *)(void *)(unsigned long)dev_priv->mm.ring_map.virtual + + dev_priv->ring.start = (u32 *)(void *)(unsigned long)dev_priv->mm.ring.kmap.virtual; + dev_priv->ring.end = (u32 *)(void *)(unsigned long)dev_priv->mm.ring.kmap.virtual + dev_priv->ring.size / sizeof(u32); dev_priv->ring.size_l2qw = drm_order(dev_priv->ring.size / 8); dev_priv->ring.rptr_update = 4096; @@ -2297,7 +2303,7 @@ int radeon_modeset_cp_init(struct drm_device *dev) radeon_cp_load_microcode(dev_priv); - DRM_DEBUG("ring offset is %x %x\n", dev_priv->mm.ring->offset, dev_priv->mm.ring_read_ptr->offset); + DRM_DEBUG("ring offset is %x %x\n", dev_priv->mm.ring.bo->offset, dev_priv->mm.ring_read.bo->offset); radeon_cp_init_ring_buffer(dev, dev_priv); diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c new file mode 100644 index 00000000..61fef79d --- /dev/null +++ b/shared-core/radeon_cs.c @@ -0,0 +1,181 @@ +/* + * Copyright 2008 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 + * 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 + */ +#include "drmP.h" +#include "radeon_drm.h" +#include "radeon_drv.h" +#include "r300_reg.h" + +int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) +{ + struct drm_radeon_private *radeon = dev->dev_private; + struct drm_radeon_cs *cs = data; + uint32_t *packets = NULL; + uint32_t cs_id; + void *ib = NULL; + long size; + int r; + + /* set command stream id to 0 which is fake id */ + cs_id = 0; + DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t)); + + if (radeon == NULL) { + DRM_ERROR("called with no initialization\n"); + return -EINVAL; + } + if (!cs->dwords) { + return 0; + } + /* limit cs to 64K ib */ + if (cs->dwords > (16 * 1024)) { + return -EINVAL; + } + /* copy cs from userspace maybe we should copy into ib to save + * one copy but ib will be mapped wc so not good for cmd checking + * somethings worth testing i guess (Jerome) + */ + size = cs->dwords * sizeof(uint32_t); + packets = drm_alloc(size, DRM_MEM_DRIVER); + if (packets == NULL) { + return -ENOMEM; + } + if (DRM_COPY_FROM_USER(packets, (void __user *)(unsigned long)cs->packets, size)) { + r = -EFAULT; + goto out; + } + /* get ib */ + r = radeon->cs.ib_get(dev, &ib, cs->dwords); + if (r) { + goto out; + } + + /* now parse command stream */ + r = radeon->cs.parse(dev, ib, packets, cs->dwords); + if (r) { + goto out; + } + + /* emit cs id sequence */ + radeon->cs.id_emit(dev, &cs_id); + DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t)); +out: + radeon->cs.ib_free(dev, ib, cs->dwords); + drm_free(packets, size, DRM_MEM_DRIVER); + return r; +} + +int radeon_cs_parse(struct drm_device *dev, void *ib, + uint32_t *packets, uint32_t dwords) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + volatile int rb; + + /* copy the packet into the IB */ + memcpy(ib, packets, dwords * sizeof(uint32_t)); + + /* read back last byte to flush WC buffers */ + rb = readl((ib + (dwords-1) * sizeof(uint32_t))); + + return 0; +} + +uint32_t radeon_cs_id_get(struct drm_radeon_private *radeon) +{ + /* FIXME: protect with a spinlock */ + /* FIXME: check if wrap affect last reported wrap & sequence */ + radeon->cs.id_scnt = (radeon->cs.id_scnt + 1) & 0x00FFFFFF; + if (!radeon->cs.id_scnt) { + /* increment wrap counter */ + radeon->cs.id_wcnt += 0x01000000; + /* valid sequence counter start at 1 */ + radeon->cs.id_scnt = 1; + } + return (radeon->cs.id_scnt | radeon->cs.id_wcnt); +} + +void r100_cs_id_emit(struct drm_device *dev, uint32_t *id) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + /* ISYNC_CNTL should have CPSCRACTH bit set */ + *id = radeon_cs_id_get(dev_priv); + /* emit id in SCRATCH4 (not used yet in old drm) */ + BEGIN_RING(2); + OUT_RING(CP_PACKET0(RADEON_SCRATCH_REG4, 0)); + OUT_RING(*id); + ADVANCE_RING(); +} + +void r300_cs_id_emit(struct drm_device *dev, uint32_t *id) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + /* ISYNC_CNTL should not have CPSCRACTH bit set */ + *id = radeon_cs_id_get(dev_priv); + /* emit id in SCRATCH6 */ + BEGIN_RING(6); + OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 0)); + OUT_RING(6); + OUT_RING(CP_PACKET0(R300_CP_RESYNC_DATA, 0)); + OUT_RING(*id); + OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); + OUT_RING(R300_RB3D_DC_FINISH); + ADVANCE_RING(); +} + +uint32_t r100_cs_id_last_get(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + return RADEON_READ(RADEON_SCRATCH_REG4); +} + +uint32_t r300_cs_id_last_get(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + return RADEON_READ(RADEON_SCRATCH_REG6); +} + +int radeon_cs_init(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + if (dev_priv->chip_family < CHIP_RV280) { + dev_priv->cs.id_emit = r100_cs_id_emit; + dev_priv->cs.id_last_get = r100_cs_id_last_get; + } else if (dev_priv->chip_family < CHIP_R600) { + dev_priv->cs.id_emit = r300_cs_id_emit; + dev_priv->cs.id_last_get = r300_cs_id_last_get; + } + + dev_priv->cs.parse = radeon_cs_parse; + /* ib get depends on memory manager or not so memory manager */ + return 0; +} diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index 7fcf9305..c20de561 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -506,6 +506,7 @@ typedef struct { #define DRM_RADEON_GEM_SET_DOMAIN 0x23 #define DRM_RADEON_GEM_INDIRECT 0x24 // temporary for X server +#define DRM_RADEON_CS 0x25 #define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t) #define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START) @@ -545,6 +546,7 @@ typedef struct { #define DRM_IOCTL_RADEON_GEM_SET_DOMAIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain) #define DRM_IOCTL_RADEON_GEM_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INDIRECT, struct drm_radeon_gem_indirect) +#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs) typedef struct drm_radeon_init { @@ -861,4 +863,17 @@ struct drm_radeon_gem_indirect { uint32_t used; }; +/* New interface which obsolete all previous interface. + */ + + +struct drm_radeon_cs { +// uint32_t __user *packets; + uint32_t dwords; + uint32_t cs_id; + uint64_t packets; + +}; + + #endif diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index b8f49404..c431fe4a 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -195,11 +195,11 @@ enum radeon_mac_model { #define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ - (dev_priv->mm.ring_read_ptr ? readl(dev_priv->mm.ring_read_ptr_map.virtual + 0) : DRM_READ32((dev_priv)->ring_rptr, 0 )) : \ + (dev_priv->mm.ring_read.bo ? readl(dev_priv->mm.ring_read.kmap.virtual + 0) : DRM_READ32((dev_priv)->ring_rptr, 0 )) : \ RADEON_READ(RADEON_CP_RB_RPTR)) -#define SET_RING_HEAD(dev_priv,val) (dev_priv->mm.ring_read_ptr ? \ - writel((val), dev_priv->mm.ring_read_ptr_map.virtual) : \ +#define SET_RING_HEAD(dev_priv,val) (dev_priv->mm.ring_read.bo ? \ + writel((val), dev_priv->mm.ring_read.kmap.virtual) : \ DRM_WRITE32((dev_priv)->ring_rptr, 0, (val))) typedef struct drm_radeon_freelist { @@ -261,6 +261,11 @@ struct radeon_virt_surface { struct drm_file *file_priv; }; +struct radeon_mm_obj { + struct drm_buffer_object *bo; + struct drm_bo_kmap_obj kmap; +}; + struct radeon_mm_info { uint64_t vram_offset; // Offset into GPU space uint64_t vram_size; @@ -268,15 +273,10 @@ struct radeon_mm_info { uint64_t gart_start; uint64_t gart_size; - - struct drm_buffer_object *pcie_table; - struct drm_bo_kmap_obj pcie_table_map; - - struct drm_buffer_object *ring; - struct drm_bo_kmap_obj ring_map; - - struct drm_buffer_object *ring_read_ptr; - struct drm_bo_kmap_obj ring_read_ptr_map; + + struct radeon_mm_obj pcie_table; + struct radeon_mm_obj ring; + struct radeon_mm_obj ring_read; }; #include "radeon_mode.h" @@ -286,6 +286,25 @@ struct drm_radeon_master_private { drm_radeon_sarea_t *sarea_priv; }; +/* command submission struct */ +struct drm_radeon_cs_priv { + uint32_t id_wcnt; + uint32_t id_scnt; + uint32_t id_last_wcnt; + uint32_t id_last_scnt; + + int (*parse)(struct drm_device *dev, void *ib, + uint32_t *packets, uint32_t dwords); + void (*id_emit)(struct drm_device *dev, uint32_t *id); + uint32_t (*id_last_get)(struct drm_device *dev); + /* this ib handling callback are for hidding memory manager drm + * from memory manager less drm, free have to emit ib discard + * sequence into the ring */ + int (*ib_get)(struct drm_device *dev, void **ib, uint32_t dwords); + uint32_t (*ib_get_ptr)(struct drm_device *dev, void *ib); + void (*ib_free)(struct drm_device *dev, void *ib, uint32_t dwords); +}; + typedef struct drm_radeon_private { drm_radeon_ring_buffer_t ring; @@ -392,7 +411,11 @@ typedef struct drm_radeon_private { u32 ram_width; enum radeon_pll_errata pll_errata; - + + struct radeon_mm_obj **ib_objs; + /* ib bitmap */ + uint64_t ib_alloc_bitmap; // TO DO replace with a real bitmap + struct drm_radeon_cs_priv cs; } drm_radeon_private_t; typedef struct drm_radeon_buf_priv { @@ -669,14 +692,15 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, #define RADEON_SCRATCH_REG3 0x15ec #define RADEON_SCRATCH_REG4 0x15f0 #define RADEON_SCRATCH_REG5 0x15f4 +#define RADEON_SCRATCH_REG6 0x15f8 #define RADEON_SCRATCH_UMSK 0x0770 #define RADEON_SCRATCH_ADDR 0x0774 #define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x)) #define GET_SCRATCH( x ) (dev_priv->writeback_works ? \ - (dev_priv->mm.ring_read_ptr ? \ - readl(dev_priv->mm.ring_read_ptr_map.virtual + RADEON_SCRATCHOFF(0)) : \ + (dev_priv->mm.ring_read.bo ? \ + readl(dev_priv->mm.ring_read.kmap.virtual + RADEON_SCRATCHOFF(0)) : \ DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(x))) : \ RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x))) @@ -1593,4 +1617,6 @@ extern void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on); extern int radeon_master_create(struct drm_device *dev, struct drm_master *master); extern void radeon_master_destroy(struct drm_device *dev, struct drm_master *master); extern void radeon_cp_dispatch_flip(struct drm_device * dev, struct drm_master *master); +extern int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv); +extern int radeon_cs_init(struct drm_device *dev); #endif /* __RADEON_DRV_H__ */ diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index 6de4b135..d56dac19 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -3279,6 +3279,7 @@ struct drm_ioctl_desc radeon_ioctls[] = { DRM_IOCTL_DEF(DRM_RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_GEM_INDIRECT, radeon_gem_indirect_ioctl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH), }; int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); -- cgit v1.2.3 From dc3a7c023dd089150ee2dc40755fde348252bedb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 28 Jul 2008 17:27:24 +1000 Subject: r300: initial command stream parser for packet 0. this at least parses the DDX stream and lets me run gnome-terminal/metacity --- shared-core/r300_cmdbuf.c | 48 +++++++++++++++++++++++++++++-- shared-core/radeon_cp.c | 2 ++ shared-core/radeon_cs.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++ shared-core/radeon_drv.h | 7 +++++ 4 files changed, 127 insertions(+), 3 deletions(-) (limited to 'shared-core') diff --git a/shared-core/r300_cmdbuf.c b/shared-core/r300_cmdbuf.c index e8f18dbc..f4111554 100644 --- a/shared-core/r300_cmdbuf.c +++ b/shared-core/r300_cmdbuf.c @@ -151,8 +151,6 @@ void r300_init_reg_flags(struct drm_device *dev) for(i=((reg)>>2);i<((reg)>>2)+(count);i++)\ r300_reg_flags[i]|=(mark); -#define MARK_SAFE 1 -#define MARK_CHECK_OFFSET 2 #define ADD_RANGE(reg, count) ADD_RANGE_MARK(reg, count, MARK_SAFE) @@ -234,6 +232,11 @@ void r300_init_reg_flags(struct drm_device *dev) ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8); ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8); + ADD_RANGE(R500_SU_REG_DEST, 1); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV410) { + ADD_RANGE(R300_DST_PIPE_CONFIG, 1); + } + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { ADD_RANGE(R500_VAP_INDEX_OFFSET, 1); ADD_RANGE(R500_US_CONFIG, 2); @@ -243,6 +246,8 @@ void r300_init_reg_flags(struct drm_device *dev) ADD_RANGE(R500_RS_INST_0, 16); ADD_RANGE(R500_RB3D_COLOR_CLEAR_VALUE_AR, 2); ADD_RANGE(R500_RB3D_CONSTANT_COLOR_AR, 2); + + ADD_RANGE(R500_GA_US_VECTOR_INDEX, 2); } else { ADD_RANGE(R300_PFS_CNTL_0, 3); ADD_RANGE(R300_PFS_NODE_0, 4); @@ -255,9 +260,39 @@ void r300_init_reg_flags(struct drm_device *dev) ADD_RANGE(R300_RS_ROUTE_0, 8); } + + /* add 2d blit engine registers for DDX */ + ADD_RANGE(RADEON_SRC_Y_X, 3); /* 1434, 1438, 143c, + SRC_Y_X, DST_Y_X, DST_HEIGHT_WIDTH + */ + ADD_RANGE(RADEON_DP_GUI_MASTER_CNTL, 1); /* 146c */ + ADD_RANGE(RADEON_DP_BRUSH_BKGD_CLR, 2); /* 1478, 147c */ + ADD_RANGE(RADEON_DP_SRC_FRGD_CLR, 2); /* 15d8, 15dc */ + ADD_RANGE(RADEON_DP_CNTL, 1); /* 16c0 */ + ADD_RANGE(RADEON_DP_WRITE_MASK, 1); /* 16cc */ + ADD_RANGE(RADEON_DEFAULT_SC_BOTTOM_RIGHT, 1); /* 16e8 */ + + ADD_RANGE(RADEON_DSTCACHE_CTLSTAT, 1); + ADD_RANGE(RADEON_WAIT_UNTIL, 1); + + ADD_RANGE_MARK(RADEON_DST_OFFSET, 1, MARK_CHECK_OFFSET); + ADD_RANGE_MARK(RADEON_SRC_OFFSET, 1, MARK_CHECK_OFFSET); + + ADD_RANGE_MARK(RADEON_DST_PITCH_OFFSET, 1, MARK_CHECK_OFFSET); + ADD_RANGE_MARK(RADEON_SRC_PITCH_OFFSET, 1, MARK_CHECK_OFFSET); + + /* TODO SCISSOR */ + ADD_RANGE_MARK(R300_SC_SCISSOR0, 2, MARK_CHECK_SCISSOR); + + ADD_RANGE(R300_SC_CLIP_0_A, 2); + ADD_RANGE(R300_SC_CLIP_RULE, 1); + ADD_RANGE(R300_SC_SCREENDOOR, 1); + + ADD_RANGE(R300_VAP_PVS_CODE_CNTL_0, 4); + ADD_RANGE(R300_VAP_PVS_VECTOR_INDX_REG, 2); } -static __inline__ int r300_check_range(unsigned reg, int count) +int r300_check_range(unsigned reg, int count) { int i; if (reg & ~0xffff) @@ -268,6 +303,13 @@ static __inline__ int r300_check_range(unsigned reg, int count) return 0; } +int r300_get_reg_flags(unsigned reg) +{ + if (reg & ~0xffff) + return -1; + return r300_reg_flags[(reg >> 2)]; +} + static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * dev_priv, drm_radeon_kcmd_buffer_t diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 46f4290a..48f72ab0 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2301,6 +2301,8 @@ int radeon_modeset_cp_init(struct drm_device *dev) dev_priv->new_memmap = 1; + r300_init_reg_flags(dev); + radeon_cp_load_microcode(dev_priv); DRM_DEBUG("ring offset is %x %x\n", dev_priv->mm.ring.bo->offset, dev_priv->mm.ring_read.bo->offset); diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index 61fef79d..8c2aea89 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -88,11 +88,84 @@ out: return r; } +int radeon_cs_packet0(struct drm_device *dev, uint32_t *packets, + uint32_t offset_dw) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + int hdr = packets[offset_dw]; + int num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2; + int need_reloc = 0; + int reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2; + int count_dw = 1; + int ret; + + while (count_dw < num_dw) { + /* need to have something like the r300 validation here - + list of allowed registers */ + int flags; + + ret = r300_check_range(reg, 1); + switch(ret) { + case -1: + DRM_ERROR("Illegal register %x\n", reg); + break; + case 0: + break; + case 1: + flags = r300_get_reg_flags(reg); + if (flags == MARK_CHECK_OFFSET) + DRM_DEBUG("need to relocate %x %d\n", reg, flags); + else if (flags == MARK_CHECK_SCISSOR) { + DRM_DEBUG("need to validate scissor %x %d\n", reg, flags); + } else { + DRM_DEBUG("illegal register %x %d\n", reg, flags); + return -EINVAL; + } + break; + } + count_dw++; + reg += 4; + } + return 0; +} + int radeon_cs_parse(struct drm_device *dev, void *ib, uint32_t *packets, uint32_t dwords) { drm_radeon_private_t *dev_priv = dev->dev_private; volatile int rb; + int size_dw = dwords; + /* scan the packet for various things */ + int count_dw = 0; + int ret = 0; + + while (count_dw < size_dw && ret == 0) { + int hdr = packets[count_dw]; + int num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16; + int reg; + + switch (hdr & RADEON_CP_PACKET_MASK) { + case RADEON_CP_PACKET0: + ret = radeon_cs_packet0(dev, packets, count_dw); + break; + case RADEON_CP_PACKET1: + case RADEON_CP_PACKET2: + reg = hdr & RADEON_CP_PACKET0_REG_MASK; + DRM_DEBUG("Packet 1/2: %d %x\n", num_dw, reg); + break; + + case RADEON_CP_PACKET3: + reg = hdr & 0xff00; + DRM_DEBUG("Packet 3: %d %x\n", num_dw, reg); + break; + } + + count_dw += num_dw+2; + } + + if (ret) + return ret; + /* copy the packet into the IB */ memcpy(ib, packets, dwords * sizeof(uint32_t)); diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index c431fe4a..232102d5 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -1619,4 +1619,11 @@ extern void radeon_master_destroy(struct drm_device *dev, struct drm_master *mas extern void radeon_cp_dispatch_flip(struct drm_device * dev, struct drm_master *master); extern int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv); extern int radeon_cs_init(struct drm_device *dev); + +#define MARK_SAFE 1 +#define MARK_CHECK_OFFSET 2 +#define MARK_CHECK_SCISSOR 3 + +extern int r300_check_range(unsigned reg, int count); +extern int r300_get_reg_flags(unsigned reg); #endif /* __RADEON_DRV_H__ */ -- cgit v1.2.3 From 87520347b45e2f40a2d84831538a38d6a8d92439 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 28 Jul 2008 17:42:53 +1000 Subject: r300: add some packet 3 decodes --- shared-core/radeon_cs.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index 8c2aea89..00860c2e 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -156,7 +156,25 @@ int radeon_cs_parse(struct drm_device *dev, void *ib, case RADEON_CP_PACKET3: reg = hdr & 0xff00; - DRM_DEBUG("Packet 3: %d %x\n", num_dw, reg); + + switch(reg) { + case RADEON_CNTL_HOSTDATA_BLT: + case RADEON_CNTL_BITBLT_MULTI: + case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */ + case RADEON_CP_INDX_BUFFER: + DRM_ERROR("need relocate packet 3 for %x\n", reg); + break; + + case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */ + case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */ + case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */ + case RADEON_WAIT_FOR_IDLE: + case RADEON_CP_NOP: + break; + default: + DRM_ERROR("unknown packet 3 %x\n", reg); + ret = -EINVAL; + } break; } -- cgit v1.2.3 From 42e373e903d960b38c605229ab102933b18cff73 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 28 Jul 2008 18:18:28 +1000 Subject: radeon_cs: extract some offsets from packet data --- shared-core/radeon_cs.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index 00860c2e..5cfe85be 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -88,6 +88,31 @@ out: return r; } +static __inline__ int radeon_cs_check_offset(struct drm_device *dev, + uint32_t reg, uint32_t val) +{ + uint32_t offset; + + switch(reg) { + case RADEON_DST_PITCH_OFFSET: + case RADEON_SRC_PITCH_OFFSET: + offset = val & ((1 << 22) - 1); + offset <<= 10; + break; + case R300_RB3D_COLOROFFSET0: + case R300_RB3D_DEPTHOFFSET: + offset = val; + break; + case R300_TX_OFFSET_0: + case R300_TX_OFFSET_0+4: + offset = val & 0xffffffe0; + break; + } + + DRM_ERROR("Offset check %x %x\n", reg, offset); + return 0; +} + int radeon_cs_packet0(struct drm_device *dev, uint32_t *packets, uint32_t offset_dw) { @@ -113,9 +138,11 @@ int radeon_cs_packet0(struct drm_device *dev, uint32_t *packets, break; case 1: flags = r300_get_reg_flags(reg); - if (flags == MARK_CHECK_OFFSET) + if (flags == MARK_CHECK_OFFSET) { + radeon_cs_check_offset(dev, reg, packets[offset_dw+count_dw]); + DRM_DEBUG("need to relocate %x %d\n", reg, flags); - else if (flags == MARK_CHECK_SCISSOR) { + } else if (flags == MARK_CHECK_SCISSOR) { DRM_DEBUG("need to validate scissor %x %d\n", reg, flags); } else { DRM_DEBUG("illegal register %x %d\n", reg, flags); @@ -159,6 +186,13 @@ int radeon_cs_parse(struct drm_device *dev, void *ib, switch(reg) { case RADEON_CNTL_HOSTDATA_BLT: + { + uint32_t offset; + offset = packets[count_dw+2] & ((1 << 22) - 1); + offset <<= 10; + DRM_ERROR("Offset check for Packet 3 %x %x\n", reg, offset); + break; + } case RADEON_CNTL_BITBLT_MULTI: case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */ case RADEON_CP_INDX_BUFFER: -- cgit v1.2.3 From 4234f82acc70f41e005d8cc301da56634352425c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 29 Jul 2008 16:51:47 +1000 Subject: radeon_cs: add relocate hook for mm and non-mm relocations --- shared-core/radeon_cs.c | 90 +++++++++++++++++++++++++++++++++++++++++++----- shared-core/radeon_drv.h | 8 +++-- 2 files changed, 87 insertions(+), 11 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index 5cfe85be..f01334bc 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -74,7 +74,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) } /* now parse command stream */ - r = radeon->cs.parse(dev, ib, packets, cs->dwords); + r = radeon->cs.parse(dev, fpriv, ib, packets, cs->dwords); if (r) { goto out; } @@ -88,6 +88,69 @@ out: return r; } +/* for non-mm */ +static int radeon_nomm_relocate(struct drm_device *dev, struct drm_file *file_priv, uint32_t *reloc, uint32_t *offset) +{ + *offset = reloc[1]; + return 0; +} +#define RELOC_SIZE 2 +#define RADEON_2D_OFFSET_MASK 0x3fffff + +static __inline__ int radeon_cs_relocate_offset(struct drm_device *dev, struct drm_file *file_priv, + uint32_t *packets, uint32_t offset_dw) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + uint32_t hdr = packets[offset_dw]; + uint32_t reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2; + uint32_t val = packets[offset_dw + 1]; + uint32_t packet3_hdr = packets[offset_dw+2]; + uint32_t tmp, offset; + int ret; + + /* this is too strict we may want to expand the length in the future and have + old kernels ignore it. */ + if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16))) { + DRM_ERROR("Packet 3 was %x should have been %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16)); + return -EINVAL; + } + + switch(reg) { + case RADEON_DST_PITCH_OFFSET: + case RADEON_SRC_PITCH_OFFSET: + /* pass in the start of the reloc */ + ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + 2, &offset); + if (ret) + return ret; + tmp = (val & RADEON_2D_OFFSET_MASK) << 10; + val &= ~RADEON_2D_OFFSET_MASK; + offset += tmp; + offset >>= 10; + val |= offset; + break; + case R300_RB3D_COLOROFFSET0: + case R300_RB3D_DEPTHOFFSET: + case R300_TX_OFFSET_0: + case R300_TX_OFFSET_0+4: + offset = packets[offset_dw + 3]; + + ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + 2, &offset); + if (ret) + return ret; + + offset &= 0xffffffe0; + val += offset; + break; + default: + break; + } + + + DRM_ERROR("New offset %x %x %x\n", packets[offset_dw+1], val, offset); + packets[offset_dw + 1] = val; + + return 0; +} static __inline__ int radeon_cs_check_offset(struct drm_device *dev, uint32_t reg, uint32_t val) { @@ -113,11 +176,11 @@ static __inline__ int radeon_cs_check_offset(struct drm_device *dev, return 0; } -int radeon_cs_packet0(struct drm_device *dev, uint32_t *packets, - uint32_t offset_dw) +int radeon_cs_packet0(struct drm_device *dev, struct drm_file *file_priv, + uint32_t *packets, uint32_t offset_dw) { drm_radeon_private_t *dev_priv = dev->dev_private; - int hdr = packets[offset_dw]; + uint32_t hdr = packets[offset_dw]; int num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2; int need_reloc = 0; int reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2; @@ -139,9 +202,16 @@ int radeon_cs_packet0(struct drm_device *dev, uint32_t *packets, case 1: flags = r300_get_reg_flags(reg); if (flags == MARK_CHECK_OFFSET) { - radeon_cs_check_offset(dev, reg, packets[offset_dw+count_dw]); - + if (num_dw > 2) { + DRM_ERROR("Cannot relocate inside type stream of reg0 packets\n"); + return -EINVAL; + } + + ret = radeon_cs_relocate_offset(dev, file_priv, packets, offset_dw); + if (ret) + return ret; DRM_DEBUG("need to relocate %x %d\n", reg, flags); + /* okay it should be followed by a NOP */ } else if (flags == MARK_CHECK_SCISSOR) { DRM_DEBUG("need to validate scissor %x %d\n", reg, flags); } else { @@ -156,8 +226,8 @@ int radeon_cs_packet0(struct drm_device *dev, uint32_t *packets, return 0; } -int radeon_cs_parse(struct drm_device *dev, void *ib, - uint32_t *packets, uint32_t dwords) +int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv, + void *ib, uint32_t *packets, uint32_t dwords) { drm_radeon_private_t *dev_priv = dev->dev_private; volatile int rb; @@ -173,7 +243,7 @@ int radeon_cs_parse(struct drm_device *dev, void *ib, switch (hdr & RADEON_CP_PACKET_MASK) { case RADEON_CP_PACKET0: - ret = radeon_cs_packet0(dev, packets, count_dw); + ret = radeon_cs_packet0(dev, file_priv, packets, count_dw); break; case RADEON_CP_PACKET1: case RADEON_CP_PACKET2: @@ -191,6 +261,7 @@ int radeon_cs_parse(struct drm_device *dev, void *ib, offset = packets[count_dw+2] & ((1 << 22) - 1); offset <<= 10; DRM_ERROR("Offset check for Packet 3 %x %x\n", reg, offset); + /* okay it should be followed by a NOP */ break; } case RADEON_CNTL_BITBLT_MULTI: @@ -302,5 +373,6 @@ int radeon_cs_init(struct drm_device *dev) dev_priv->cs.parse = radeon_cs_parse; /* ib get depends on memory manager or not so memory manager */ + dev_priv->cs.relocate = radeon_nomm_relocate; return 0; } diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 232102d5..f79eade5 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -293,8 +293,8 @@ struct drm_radeon_cs_priv { uint32_t id_last_wcnt; uint32_t id_last_scnt; - int (*parse)(struct drm_device *dev, void *ib, - uint32_t *packets, uint32_t dwords); + int (*parse)(struct drm_device *dev, struct drm_file *file_priv, + void *ib, uint32_t *packets, uint32_t dwords); void (*id_emit)(struct drm_device *dev, uint32_t *id); uint32_t (*id_last_get)(struct drm_device *dev); /* this ib handling callback are for hidding memory manager drm @@ -303,6 +303,9 @@ struct drm_radeon_cs_priv { int (*ib_get)(struct drm_device *dev, void **ib, uint32_t dwords); uint32_t (*ib_get_ptr)(struct drm_device *dev, void *ib); void (*ib_free)(struct drm_device *dev, void *ib, uint32_t dwords); + /* do a relocation either MM or non-MM */ + bool (*relocate)(struct drm_device *dev, struct drm_file *file_priv, + uint32_t *reloc, uint32_t *offset); }; typedef struct drm_radeon_private { @@ -391,6 +394,7 @@ typedef struct drm_radeon_private { int num_gb_pipes; + int mm_disabled; /* on OSes with no MM this will be 1*/ struct radeon_mm_info mm; drm_local_map_t *mmio; -- cgit v1.2.3 From 0452be882607f2d1601f4e592a11ccf543f5f9ca Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 29 Jul 2008 18:05:11 +1000 Subject: radeon: move code around putting emit into cs --- shared-core/radeon_cs.c | 76 ++++++++++++++++++++++++++++++++++++------------ shared-core/radeon_drv.h | 4 +-- 2 files changed, 59 insertions(+), 21 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index f01334bc..33a8ccd4 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -31,19 +31,21 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) { - struct drm_radeon_private *radeon = dev->dev_private; + struct drm_radeon_private *dev_priv = dev->dev_private; struct drm_radeon_cs *cs = data; uint32_t *packets = NULL; uint32_t cs_id; + uint32_t card_offset; void *ib = NULL; long size; int r; + RING_LOCALS; /* set command stream id to 0 which is fake id */ cs_id = 0; DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t)); - if (radeon == NULL) { + if (dev_priv == NULL) { DRM_ERROR("called with no initialization\n"); return -EINVAL; } @@ -68,22 +70,31 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) goto out; } /* get ib */ - r = radeon->cs.ib_get(dev, &ib, cs->dwords); + r = dev_priv->cs.ib_get(dev, &ib, cs->dwords, &card_offset); if (r) { goto out; } /* now parse command stream */ - r = radeon->cs.parse(dev, fpriv, ib, packets, cs->dwords); + r = dev_priv->cs.parse(dev, fpriv, ib, packets, cs->dwords); if (r) { goto out; } + BEGIN_RING(4); + OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1)); + OUT_RING(card_offset); + OUT_RING(cs->dwords); + OUT_RING(CP_PACKET2()); + ADVANCE_RING(); + /* emit cs id sequence */ - radeon->cs.id_emit(dev, &cs_id); + dev_priv->cs.id_emit(dev, &cs_id); + COMMIT_RING(); + DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t)); out: - radeon->cs.ib_free(dev, ib, cs->dwords); + dev_priv->cs.ib_free(dev, ib, cs->dwords); drm_free(packets, size, DRM_MEM_DRIVER); return r; } @@ -97,8 +108,8 @@ static int radeon_nomm_relocate(struct drm_device *dev, struct drm_file *file_pr #define RELOC_SIZE 2 #define RADEON_2D_OFFSET_MASK 0x3fffff -static __inline__ int radeon_cs_relocate_offset(struct drm_device *dev, struct drm_file *file_priv, - uint32_t *packets, uint32_t offset_dw) +static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct drm_file *file_priv, + uint32_t *packets, uint32_t offset_dw) { drm_radeon_private_t *dev_priv = dev->dev_private; uint32_t hdr = packets[offset_dw]; @@ -107,7 +118,7 @@ static __inline__ int radeon_cs_relocate_offset(struct drm_device *dev, struct d uint32_t packet3_hdr = packets[offset_dw+2]; uint32_t tmp, offset; int ret; - + /* this is too strict we may want to expand the length in the future and have old kernels ignore it. */ if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16))) { @@ -132,8 +143,6 @@ static __inline__ int radeon_cs_relocate_offset(struct drm_device *dev, struct d case R300_RB3D_DEPTHOFFSET: case R300_TX_OFFSET_0: case R300_TX_OFFSET_0+4: - offset = packets[offset_dw + 3]; - ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + 2, &offset); if (ret) return ret; @@ -151,6 +160,40 @@ static __inline__ int radeon_cs_relocate_offset(struct drm_device *dev, struct d return 0; } + +static int radeon_cs_relocate_packet3(struct drm_device *dev, struct drm_file *file_priv, + uint32_t *packets, uint32_t offset_dw) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + uint32_t hdr = packets[offset_dw]; + int num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16; + uint32_t reg = hdr & 0xff00; + uint32_t offset, val, tmp; + int ret; + + switch(reg) { + case RADEON_CNTL_HOSTDATA_BLT: + { + val = packets[offset_dw + 2]; + ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + num_dw + 2, &offset); + if (ret) + return ret; + + tmp = (val & RADEON_2D_OFFSET_MASK) << 10; + val &= ~RADEON_2D_OFFSET_MASK; + offset += tmp; + offset >>= 10; + val |= offset; + + DRM_ERROR("New offset %x %x %x\n", packets[offset_dw+2], val, offset); + packets[offset_dw + 2] = val; + } + default: + return -EINVAL; + } + return 0; +} + static __inline__ int radeon_cs_check_offset(struct drm_device *dev, uint32_t reg, uint32_t val) { @@ -207,7 +250,7 @@ int radeon_cs_packet0(struct drm_device *dev, struct drm_file *file_priv, return -EINVAL; } - ret = radeon_cs_relocate_offset(dev, file_priv, packets, offset_dw); + ret = radeon_cs_relocate_packet0(dev, file_priv, packets, offset_dw); if (ret) return ret; DRM_DEBUG("need to relocate %x %d\n", reg, flags); @@ -256,14 +299,9 @@ int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv, switch(reg) { case RADEON_CNTL_HOSTDATA_BLT: - { - uint32_t offset; - offset = packets[count_dw+2] & ((1 << 22) - 1); - offset <<= 10; - DRM_ERROR("Offset check for Packet 3 %x %x\n", reg, offset); - /* okay it should be followed by a NOP */ + radeon_cs_relocate_packet3(dev, file_priv, packets, count_dw); break; - } + case RADEON_CNTL_BITBLT_MULTI: case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */ case RADEON_CP_INDX_BUFFER: diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index f79eade5..e55a9697 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -300,11 +300,11 @@ struct drm_radeon_cs_priv { /* this ib handling callback are for hidding memory manager drm * from memory manager less drm, free have to emit ib discard * sequence into the ring */ - int (*ib_get)(struct drm_device *dev, void **ib, uint32_t dwords); + int (*ib_get)(struct drm_device *dev, void **ib, uint32_t dwords, uint32_t *card_offset); uint32_t (*ib_get_ptr)(struct drm_device *dev, void *ib); void (*ib_free)(struct drm_device *dev, void *ib, uint32_t dwords); /* do a relocation either MM or non-MM */ - bool (*relocate)(struct drm_device *dev, struct drm_file *file_priv, + int (*relocate)(struct drm_device *dev, struct drm_file *file_priv, uint32_t *reloc, uint32_t *offset); }; -- cgit v1.2.3 From d659302e0955598ae08316ab911a0fb74d5e2f2f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 30 Jul 2008 17:05:50 +1000 Subject: radeon: add some handles to the sarea + kernel mm available check --- shared-core/radeon_drm.h | 8 ++++++++ shared-core/radeon_state.c | 4 ++++ 2 files changed, 12 insertions(+) (limited to 'shared-core') diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index c20de561..8ee1baa7 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -455,6 +455,13 @@ typedef struct { int tiling_enabled; /* set by drm, read by 2d + 3d clients */ unsigned int last_fence; + + uint32_t front_handle; + uint32_t back_handle; + uint32_t depth_handle; + uint32_t front_pitch; + uint32_t back_pitch; + uint32_t depth_pitch; } drm_radeon_sarea_t; @@ -705,6 +712,7 @@ typedef struct drm_radeon_indirect { #define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */ #define RADEON_PARAM_FB_LOCATION 14 /* FB location */ #define RADEON_PARAM_NUM_GB_PIPES 15 /* num GB pipes */ +#define RADEON_PARAM_KERNEL_MM 16 typedef struct drm_radeon_getparam { int param; diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index d56dac19..00160fbf 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -3117,6 +3117,10 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil case RADEON_PARAM_NUM_GB_PIPES: value = dev_priv->num_gb_pipes; break; + case RADEON_PARAM_KERNEL_MM: + /* BSD TODO */ + value = 1; + break; default: DRM_DEBUG( "Invalid parameter %d\n", param->param ); return -EINVAL; -- cgit v1.2.3 From 9b8d71b5eb09857b07409731d3de182751f712a2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 31 Jul 2008 12:54:48 +1000 Subject: TTM: remove API and userspace objects. This removes all the TTM userspace API and all userspace objects. It also removes the drm_bo_lock.c code --- shared-core/drm.h | 343 ------------------------------------------------- shared-core/i915_dma.c | 32 +---- shared-core/i915_drm.h | 52 -------- 3 files changed, 2 insertions(+), 425 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 7aba2939..76d2c4c5 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -675,324 +675,6 @@ struct drm_set_version { int drm_dd_minor; }; - -#define DRM_FENCE_FLAG_EMIT 0x00000001 -#define DRM_FENCE_FLAG_SHAREABLE 0x00000002 -/** - * On hardware with no interrupt events for operation completion, - * indicates that the kernel should sleep while waiting for any blocking - * operation to complete rather than spinning. - * - * Has no effect otherwise. - */ -#define DRM_FENCE_FLAG_WAIT_LAZY 0x00000004 -#define DRM_FENCE_FLAG_NO_USER 0x00000010 - -/* Reserved for driver use */ -#define DRM_FENCE_MASK_DRIVER 0xFF000000 - -#define DRM_FENCE_TYPE_EXE 0x00000001 - -struct drm_fence_arg { - unsigned int handle; - unsigned int fence_class; - unsigned int type; - unsigned int flags; - unsigned int signaled; - unsigned int error; - unsigned int sequence; - unsigned int pad64; - uint64_t expand_pad[2]; /*Future expansion */ -}; - -/* Buffer permissions, referring to how the GPU uses the buffers. - * these translate to fence types used for the buffers. - * Typically a texture buffer is read, A destination buffer is write and - * a command (batch-) buffer is exe. Can be or-ed together. - */ - -#define DRM_BO_FLAG_READ (1ULL << 0) -#define DRM_BO_FLAG_WRITE (1ULL << 1) -#define DRM_BO_FLAG_EXE (1ULL << 2) - -/* - * All of the bits related to access mode - */ -#define DRM_BO_MASK_ACCESS (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE) -/* - * Status flags. Can be read to determine the actual state of a buffer. - * Can also be set in the buffer mask before validation. - */ - -/* - * Mask: Never evict this buffer. Not even with force. This type of buffer is only - * available to root and must be manually removed before buffer manager shutdown - * or lock. - * Flags: Acknowledge - */ -#define DRM_BO_FLAG_NO_EVICT (1ULL << 4) - -/* - * Mask: Require that the buffer is placed in mappable memory when validated. - * If not set the buffer may or may not be in mappable memory when validated. - * Flags: If set, the buffer is in mappable memory. - */ -#define DRM_BO_FLAG_MAPPABLE (1ULL << 5) - -/* Mask: The buffer should be shareable with other processes. - * Flags: The buffer is shareable with other processes. - */ -#define DRM_BO_FLAG_SHAREABLE (1ULL << 6) - -/* Mask: If set, place the buffer in cache-coherent memory if available. - * If clear, never place the buffer in cache coherent memory if validated. - * Flags: The buffer is currently in cache-coherent memory. - */ -#define DRM_BO_FLAG_CACHED (1ULL << 7) - -/* Mask: Make sure that every time this buffer is validated, - * it ends up on the same location provided that the memory mask is the same. - * The buffer will also not be evicted when claiming space for - * other buffers. Basically a pinned buffer but it may be thrown out as - * part of buffer manager shutdown or locking. - * Flags: Acknowledge. - */ -#define DRM_BO_FLAG_NO_MOVE (1ULL << 8) - -/* Mask: Make sure the buffer is in cached memory when mapped. In conjunction - * with DRM_BO_FLAG_CACHED it also allows the buffer to be bound into the GART - * with unsnooped PTEs instead of snooped, by using chipset-specific cache - * flushing at bind time. A better name might be DRM_BO_FLAG_TT_UNSNOOPED, - * as the eviction to local memory (TTM unbind) on map is just a side effect - * to prevent aggressive cache prefetch from the GPU disturbing the cache - * management that the DRM is doing. - * - * Flags: Acknowledge. - * Buffers allocated with this flag should not be used for suballocators - * This type may have issues on CPUs with over-aggressive caching - * http://marc.info/?l=linux-kernel&m=102376926732464&w=2 - */ -#define DRM_BO_FLAG_CACHED_MAPPED (1ULL << 19) - - -/* Mask: Force DRM_BO_FLAG_CACHED flag strictly also if it is set. - * Flags: Acknowledge. - */ -#define DRM_BO_FLAG_FORCE_CACHING (1ULL << 13) - -/* - * Mask: Force DRM_BO_FLAG_MAPPABLE flag strictly also if it is clear. - * Flags: Acknowledge. - */ -#define DRM_BO_FLAG_FORCE_MAPPABLE (1ULL << 14) -#define DRM_BO_FLAG_TILE (1ULL << 15) - -/* - * Memory type flags that can be or'ed together in the mask, but only - * one appears in flags. - */ - -/* System memory */ -#define DRM_BO_FLAG_MEM_LOCAL (1ULL << 24) -/* Translation table memory */ -#define DRM_BO_FLAG_MEM_TT (1ULL << 25) -/* Vram memory */ -#define DRM_BO_FLAG_MEM_VRAM (1ULL << 26) -/* Up to the driver to define. */ -#define DRM_BO_FLAG_MEM_PRIV0 (1ULL << 27) -#define DRM_BO_FLAG_MEM_PRIV1 (1ULL << 28) -#define DRM_BO_FLAG_MEM_PRIV2 (1ULL << 29) -#define DRM_BO_FLAG_MEM_PRIV3 (1ULL << 30) -#define DRM_BO_FLAG_MEM_PRIV4 (1ULL << 31) -/* We can add more of these now with a 64-bit flag type */ - -/* - * This is a mask covering all of the memory type flags; easier to just - * use a single constant than a bunch of | values. It covers - * DRM_BO_FLAG_MEM_LOCAL through DRM_BO_FLAG_MEM_PRIV4 - */ -#define DRM_BO_MASK_MEM 0x00000000FF000000ULL -/* - * This adds all of the CPU-mapping options in with the memory - * type to label all bits which change how the page gets mapped - */ -#define DRM_BO_MASK_MEMTYPE (DRM_BO_MASK_MEM | \ - DRM_BO_FLAG_CACHED_MAPPED | \ - DRM_BO_FLAG_CACHED | \ - DRM_BO_FLAG_MAPPABLE) - -/* Driver-private flags */ -#define DRM_BO_MASK_DRIVER 0xFFFF000000000000ULL - -/* - * Don't block on validate and map. Instead, return EBUSY. - */ -#define DRM_BO_HINT_DONT_BLOCK 0x00000002 -/* - * Don't place this buffer on the unfenced list. This means - * that the buffer will not end up having a fence associated - * with it as a result of this operation - */ -#define DRM_BO_HINT_DONT_FENCE 0x00000004 -/** - * On hardware with no interrupt events for operation completion, - * indicates that the kernel should sleep while waiting for any blocking - * operation to complete rather than spinning. - * - * Has no effect otherwise. - */ -#define DRM_BO_HINT_WAIT_LAZY 0x00000008 -/* - * The client has compute relocations refering to this buffer using the - * offset in the presumed_offset field. If that offset ends up matching - * where this buffer lands, the kernel is free to skip executing those - * relocations - */ -#define DRM_BO_HINT_PRESUMED_OFFSET 0x00000010 - -#define DRM_BO_INIT_MAGIC 0xfe769812 -#define DRM_BO_INIT_MAJOR 1 -#define DRM_BO_INIT_MINOR 0 -#define DRM_BO_INIT_PATCH 0 - - -struct drm_bo_info_req { - uint64_t mask; - uint64_t flags; - unsigned int handle; - unsigned int hint; - unsigned int fence_class; - unsigned int desired_tile_stride; - unsigned int tile_info; - unsigned int pad64; - uint64_t presumed_offset; -}; - -struct drm_bo_create_req { - uint64_t flags; - uint64_t size; - uint64_t buffer_start; - unsigned int hint; - unsigned int page_alignment; -}; - - -/* - * Reply flags - */ - -#define DRM_BO_REP_BUSY 0x00000001 - -struct drm_bo_info_rep { - uint64_t flags; - uint64_t proposed_flags; - uint64_t size; - uint64_t offset; - uint64_t arg_handle; - uint64_t buffer_start; - unsigned int handle; - unsigned int fence_flags; - unsigned int rep_flags; - unsigned int page_alignment; - unsigned int desired_tile_stride; - unsigned int hw_tile_stride; - unsigned int tile_info; - unsigned int pad64; - uint64_t expand_pad[4]; /*Future expansion */ -}; - -struct drm_bo_arg_rep { - struct drm_bo_info_rep bo_info; - int ret; - unsigned int pad64; -}; - -struct drm_bo_create_arg { - union { - struct drm_bo_create_req req; - struct drm_bo_info_rep rep; - } d; -}; - -struct drm_bo_handle_arg { - unsigned int handle; -}; - -struct drm_bo_reference_info_arg { - union { - struct drm_bo_handle_arg req; - struct drm_bo_info_rep rep; - } d; -}; - -struct drm_bo_map_wait_idle_arg { - union { - struct drm_bo_info_req req; - struct drm_bo_info_rep rep; - } d; -}; - -struct drm_bo_op_req { - enum { - drm_bo_validate, - drm_bo_fence, - drm_bo_ref_fence, - } op; - unsigned int arg_handle; - struct drm_bo_info_req bo_req; -}; - - -struct drm_bo_op_arg { - uint64_t next; - union { - struct drm_bo_op_req req; - struct drm_bo_arg_rep rep; - } d; - int handled; - unsigned int pad64; -}; - - -#define DRM_BO_MEM_LOCAL 0 -#define DRM_BO_MEM_TT 1 -#define DRM_BO_MEM_VRAM 2 -#define DRM_BO_MEM_PRIV0 3 -#define DRM_BO_MEM_PRIV1 4 -#define DRM_BO_MEM_PRIV2 5 -#define DRM_BO_MEM_PRIV3 6 -#define DRM_BO_MEM_PRIV4 7 - -#define DRM_BO_MEM_TYPES 8 /* For now. */ - -#define DRM_BO_LOCK_UNLOCK_BM (1 << 0) -#define DRM_BO_LOCK_IGNORE_NO_EVICT (1 << 1) - -struct drm_bo_version_arg { - uint32_t major; - uint32_t minor; - uint32_t patchlevel; -}; - -struct drm_mm_type_arg { - unsigned int mem_type; - unsigned int lock_flags; -}; - -struct drm_mm_init_arg { - unsigned int magic; - unsigned int major; - unsigned int minor; - unsigned int mem_type; - uint64_t p_offset; - uint64_t p_size; -}; - -struct drm_mm_info_arg { - unsigned int mem_type; - uint64_t p_size; -}; - struct drm_gem_close { /** Handle of the object to be closed. */ uint32_t handle; @@ -1337,31 +1019,6 @@ struct drm_mode_crtc_lut { #define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw) -#define DRM_IOCTL_MM_INIT DRM_IOWR(0xc0, struct drm_mm_init_arg) -#define DRM_IOCTL_MM_TAKEDOWN DRM_IOWR(0xc1, struct drm_mm_type_arg) -#define DRM_IOCTL_MM_LOCK DRM_IOWR(0xc2, struct drm_mm_type_arg) -#define DRM_IOCTL_MM_UNLOCK DRM_IOWR(0xc3, struct drm_mm_type_arg) - -#define DRM_IOCTL_FENCE_CREATE DRM_IOWR(0xc4, struct drm_fence_arg) -#define DRM_IOCTL_FENCE_REFERENCE DRM_IOWR(0xc6, struct drm_fence_arg) -#define DRM_IOCTL_FENCE_UNREFERENCE DRM_IOWR(0xc7, struct drm_fence_arg) -#define DRM_IOCTL_FENCE_SIGNALED DRM_IOWR(0xc8, struct drm_fence_arg) -#define DRM_IOCTL_FENCE_FLUSH DRM_IOWR(0xc9, struct drm_fence_arg) -#define DRM_IOCTL_FENCE_WAIT DRM_IOWR(0xca, struct drm_fence_arg) -#define DRM_IOCTL_FENCE_EMIT DRM_IOWR(0xcb, struct drm_fence_arg) -#define DRM_IOCTL_FENCE_BUFFERS DRM_IOWR(0xcc, struct drm_fence_arg) - -#define DRM_IOCTL_BO_CREATE DRM_IOWR(0xcd, struct drm_bo_create_arg) -#define DRM_IOCTL_BO_MAP DRM_IOWR(0xcf, struct drm_bo_map_wait_idle_arg) -#define DRM_IOCTL_BO_UNMAP DRM_IOWR(0xd0, struct drm_bo_handle_arg) -#define DRM_IOCTL_BO_REFERENCE DRM_IOWR(0xd1, struct drm_bo_reference_info_arg) -#define DRM_IOCTL_BO_UNREFERENCE DRM_IOWR(0xd2, struct drm_bo_handle_arg) -#define DRM_IOCTL_BO_SETSTATUS DRM_IOWR(0xd3, struct drm_bo_map_wait_idle_arg) -#define DRM_IOCTL_BO_INFO DRM_IOWR(0xd4, struct drm_bo_reference_info_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_MM_INFO DRM_IOWR(0xd7, struct drm_mm_info_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_GETCONNECTOR DRM_IOWR(0xA2, struct drm_mode_get_connector) diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 09c53676..3e6a6626 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -148,7 +148,7 @@ int i915_dma_cleanup(struct drm_device * dev) return 0; } -#if defined(I915_HAVE_BUFFER) && defined(DRI2) +#if defined(DRI2) #define DRI2_SAREA_BLOCK_TYPE(b) ((b) >> 16) #define DRI2_SAREA_BLOCK_SIZE(b) ((b) & 0xffff) #define DRI2_SAREA_BLOCK_NEXT(p) \ @@ -226,12 +226,7 @@ static int i915_initialize(struct drm_device * dev, } } -#ifdef I915_HAVE_BUFFER - if (!drm_core_check_feature(dev, DRIVER_MODESET)) { - dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS; - } -#endif - + if (init->ring_size != 0) { dev_priv->ring.Size = init->ring_size; dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; @@ -285,10 +280,6 @@ static int i915_initialize(struct drm_device * dev, } DRM_DEBUG("Enabled hardware status page\n"); -#ifdef I915_HAVE_BUFFER - if (!drm_core_check_feature(dev, DRIVER_MODESET)) { - mutex_init(&dev_priv->cmdbuf_mutex); - } #ifdef DRI2 if (init->func == I915_INIT_DMA2) { int ret = setup_dri2_sarea(dev, file_priv, init); @@ -299,7 +290,6 @@ static int i915_initialize(struct drm_device * dev, } } #endif /* DRI2 */ -#endif /* I915_HAVE_BUFFER */ return 0; } @@ -565,9 +555,6 @@ int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush) static int i915_dispatch_cmdbuffer(struct drm_device * dev, struct drm_i915_cmdbuffer * cmd) { -#ifdef I915_HAVE_FENCE - struct drm_i915_private *dev_priv = dev->dev_private; -#endif int nbox = cmd->num_cliprects; int i = 0, count, ret; @@ -594,10 +581,6 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev, } i915_emit_breadcrumb(dev); -#ifdef I915_HAVE_FENCE - if (unlikely((dev_priv->counter & 0xFF) == 0)) - drm_fence_flush_old(dev, 0, dev_priv->counter); -#endif return 0; } @@ -648,10 +631,6 @@ int i915_dispatch_batchbuffer(struct drm_device * dev, } i915_emit_breadcrumb(dev); -#ifdef I915_HAVE_FENCE - if (unlikely((dev_priv->counter & 0xFF) == 0)) - drm_fence_flush_old(dev, 0, dev_priv->counter); -#endif return 0; } @@ -724,10 +703,6 @@ void i915_dispatch_flip(struct drm_device * dev, int planes, int sync) i915_do_dispatch_flip(dev, i, sync); i915_emit_breadcrumb(dev); -#ifdef I915_HAVE_FENCE - if (unlikely(!sync && ((dev_priv->counter & 0xFF) == 0))) - drm_fence_flush_old(dev, 0, dev_priv->counter); -#endif } int i915_quiescent(struct drm_device *dev) @@ -1077,9 +1052,6 @@ struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_MMIO, i915_mmio, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH), -#ifdef I915_HAVE_BUFFER - DRM_IOCTL_DEF(DRM_I915_EXECBUFFER, i915_execbuffer, DRM_AUTH), -#endif DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY), diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h index 8ba71687..611f943a 100644 --- a/shared-core/i915_drm.h +++ b/shared-core/i915_drm.h @@ -375,58 +375,6 @@ typedef struct drm_i915_hws_addr { uint64_t addr; } drm_i915_hws_addr_t; -/* - * Relocation header is 4 uint32_ts - * 0 - 32 bit reloc count - * 1 - 32-bit relocation type - * 2-3 - 64-bit user buffer handle ptr for another list of relocs. - */ -#define I915_RELOC_HEADER 4 - -/* - * type 0 relocation has 4-uint32_t stride - * 0 - offset into buffer - * 1 - delta to add in - * 2 - buffer handle - * 3 - reserved (for optimisations later). - */ -/* - * type 1 relocation has 4-uint32_t stride. - * Hangs off the first item in the op list. - * Performed after all valiations are done. - * Try to group relocs into the same relocatee together for - * performance reasons. - * 0 - offset into buffer - * 1 - delta to add in - * 2 - buffer index in op list. - * 3 - relocatee index in op list. - */ -#define I915_RELOC_TYPE_0 0 -#define I915_RELOC0_STRIDE 4 -#define I915_RELOC_TYPE_1 1 -#define I915_RELOC1_STRIDE 4 - - -struct drm_i915_op_arg { - uint64_t next; - uint64_t reloc_ptr; - int handled; - unsigned int pad64; - union { - struct drm_bo_op_req req; - struct drm_bo_arg_rep rep; - } d; - -}; - -struct drm_i915_execbuffer { - uint64_t ops_list; - uint32_t num_buffers; - struct drm_i915_batchbuffer batch; - drm_context_t context; /* for lockless use in the future */ - struct drm_fence_arg fence_arg; -}; - struct drm_i915_gem_init { /** * Beginning offset in the GTT to be managed by the DRM memory -- cgit v1.2.3 From d2d7f3069dac4bc5ddd3c8da4d3955f690274276 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 31 Jul 2008 13:13:21 +1000 Subject: drm: userspace rip out TTM API --- shared-core/i915_dma.c | 1 - 1 file changed, 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 3e6a6626..bd52a057 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -689,7 +689,6 @@ static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync) void i915_dispatch_flip(struct drm_device * dev, int planes, int sync) { - struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; int i; -- cgit v1.2.3 From af6efc3d778b96164849f822331938c4cdf8f4b2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 4 Aug 2008 14:53:45 +1000 Subject: i915/radeon: use rmmap locked --- shared-core/i915_init.c | 2 +- shared-core/radeon_cp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 3a652e8d..dc218688 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -443,7 +443,7 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master) return; if (master_priv->sarea) - drm_rmmap(dev, master_priv->sarea); + drm_rmmap_locked(dev, master_priv->sarea); drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER); diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 48f72ab0..b69fadbb 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2535,7 +2535,7 @@ void radeon_master_destroy(struct drm_device *dev, struct drm_master *master) master_priv->sarea_priv = NULL; if (master_priv->sarea) - drm_rmmap(dev, master_priv->sarea); + drm_rmmap_locked(dev, master_priv->sarea); drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER); -- cgit v1.2.3 From dff84851516a71639d734e134c584f6ed4d3ee07 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 4 Aug 2008 14:55:12 +1000 Subject: drm: remove unused types --- shared-core/drm.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 76d2c4c5..ed390885 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1096,11 +1096,6 @@ typedef struct drm_agp_binding drm_agp_binding_t; typedef struct drm_agp_info drm_agp_info_t; typedef struct drm_scatter_gather drm_scatter_gather_t; typedef struct drm_set_version drm_set_version_t; - -typedef struct drm_fence_arg drm_fence_arg_t; -typedef struct drm_mm_type_arg drm_mm_type_arg_t; -typedef struct drm_mm_init_arg drm_mm_init_arg_t; -typedef enum drm_bo_type drm_bo_type_t; #endif #endif -- cgit v1.2.3 From aa8e15f8b51e555e78cb93e279bad5843eea5391 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 4 Aug 2008 14:59:17 +1000 Subject: radeon: add userspace mm enable switch --- shared-core/radeon_cp.c | 10 ++++++---- shared-core/radeon_drm.h | 1 + shared-core/radeon_drv.h | 2 ++ shared-core/radeon_state.c | 3 +++ 4 files changed, 12 insertions(+), 4 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index b69fadbb..430f5493 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -1364,8 +1364,7 @@ static int radeon_do_cleanup_cp(struct drm_device * dev) if (dev_priv->gart_info.bus_addr) { /* Turn off PCI GART */ radeon_set_pcigart(dev_priv, 0); - if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) - DRM_ERROR("failed to cleanup PCI GART!\n"); + drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info); } if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) @@ -1373,6 +1372,7 @@ static int radeon_do_cleanup_cp(struct drm_device * dev) if (dev_priv->pcigart_offset_set == 1) { drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); dev_priv->gart_info.addr = NULL; + dev_priv->pcigart_offset_set = 0; } } } @@ -1563,8 +1563,10 @@ void radeon_do_release(struct drm_device * dev) radeon_mem_takedown(&(dev_priv->gart_heap)); radeon_mem_takedown(&(dev_priv->fb_heap)); - - radeon_gem_mm_fini(dev); + if (dev_priv->user_mm_enable) { + radeon_gem_mm_fini(dev); + dev_priv->user_mm_enable = false; + } /* deallocate kernel resources */ radeon_do_cleanup_cp(dev); diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index 8ee1baa7..8bb5d87c 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -768,6 +768,7 @@ typedef struct drm_radeon_setparam { #define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ #define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */ #define RADEON_SETPARAM_VBLANK_CRTC 6 /* VBLANK CRTC */ +#define RADEON_SETPARAM_MM_INIT 7 /* Initialise the mm */ /* 1.14: Clients can allocate/free a surface */ typedef struct drm_radeon_surface_alloc { diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index e55a9697..0363dfd4 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -314,6 +314,8 @@ typedef struct drm_radeon_private { int new_memmap; + bool user_mm_enable; + int gart_size; u32 gart_vm_start; unsigned long gart_buffers_offset; diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index 00160fbf..ca10db4b 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -3182,6 +3182,9 @@ static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_fil case RADEON_SETPARAM_VBLANK_CRTC: return radeon_vblank_crtc_set(dev, sp->value); break; + case RADEON_SETPARAM_MM_INIT: + dev_priv->user_mm_enable = true; + return radeon_gem_mm_init(dev); default: DRM_DEBUG("Invalid parameter %d\n", sp->param); return -EINVAL; -- cgit v1.2.3 From 4748fbcbd7b0337448ce88c2cdbbc500ff959e42 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 5 Aug 2008 11:36:20 +1000 Subject: radeon: fix blit due to registers wrong --- shared-core/r300_reg.h | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'shared-core') diff --git a/shared-core/r300_reg.h b/shared-core/r300_reg.h index 0be01fc7..65c5606a 100644 --- a/shared-core/r300_reg.h +++ b/shared-core/r300_reg.h @@ -129,15 +129,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* END: Wild guesses */ #define R300_SE_VTE_CNTL 0x20b0 -# define R300_VPORT_X_SCALE_ENA 0x00000001 -# define R300_VPORT_X_OFFSET_ENA 0x00000002 -# define R300_VPORT_Y_SCALE_ENA 0x00000004 -# define R300_VPORT_Y_OFFSET_ENA 0x00000008 -# define R300_VPORT_Z_SCALE_ENA 0x00000010 -# define R300_VPORT_Z_OFFSET_ENA 0x00000020 -# define R300_VTX_XY_FMT 0x00000100 -# define R300_VTX_Z_FMT 0x00000200 -# define R300_VTX_W0_FMT 0x00000400 # define R300_VTX_W0_NORMALIZE 0x00000800 # define R300_VTX_ST_DENORMALIZED 0x00001000 @@ -493,7 +484,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_OFIFO_HIGHWATER_SHIFT 22 /* two bits only */ # define R300_CUBE_FIFO_HIGHWATER_COL_SHIFT 24 -#define R300_GB_SELECT 0x401C + # define R300_GB_FOG_SELECT_C0A 0 # define R300_GB_FOG_SELECT_C1A 1 # define R300_GB_FOG_SELECT_C2A 2 @@ -934,7 +925,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* 32 bit chroma key */ #define R300_TX_CHROMA_KEY_0 0x4580 /* ff00ff00 == { 0, 1.0, 0, 1.0 } */ -#define R300_TX_BORDER_COLOR_0 0x45C0 /* END: Texture specification */ @@ -1319,7 +1309,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* gap */ -#define R300_RB3D_COLOROFFSET0 0x4E28 # define R300_COLOROFFSET_MASK 0xFFFFFFF0 /* GUESS */ #define R300_RB3D_COLOROFFSET1 0x4E2C /* GUESS */ #define R300_RB3D_COLOROFFSET2 0x4E30 /* GUESS */ @@ -1331,7 +1320,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Bit 17: 4x2 tiles * Bit 18: Extremely weird tile like, but some pixels duplicated? */ -#define R300_RB3D_COLORPITCH0 0x4E38 # define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS */ # define R300_COLOR_TILE_ENABLE (1 << 16) /* GUESS */ # define R300_COLOR_MICROTILE_ENABLE (1 << 17) /* GUESS */ -- cgit v1.2.3 From 513d4c3ff1937159e0d32047376415df09031ce6 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 6 Aug 2008 10:21:20 +1000 Subject: radeon: fix setting new memmap in right place --- shared-core/radeon_cp.c | 2 +- shared-core/radeon_drv.h | 2 +- shared-core/radeon_state.c | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 430f5493..4c03f739 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2301,7 +2301,7 @@ int radeon_modeset_cp_init(struct drm_device *dev) dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; - dev_priv->new_memmap = 1; + dev_priv->new_memmap = true; r300_init_reg_flags(dev); diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 0363dfd4..94975e4d 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -312,7 +312,7 @@ typedef struct drm_radeon_private { drm_radeon_ring_buffer_t ring; - int new_memmap; + bool new_memmap; bool user_mm_enable; diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index ca10db4b..e168ea02 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -3184,6 +3184,7 @@ static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_fil break; case RADEON_SETPARAM_MM_INIT: dev_priv->user_mm_enable = true; + dev_priv->new_memmap = true; return radeon_gem_mm_init(dev); default: DRM_DEBUG("Invalid parameter %d\n", sp->param); -- cgit v1.2.3 From c2184e450e4c5613c1f1a004d183ad478358013e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 8 Aug 2008 16:04:45 +1000 Subject: radeon: add initial support for legacy crtc/encoders. not all there yet --- shared-core/radeon_cp.c | 8 +++- shared-core/radeon_drv.h | 106 +++++++++++++++++++++++++++++++---------------- 2 files changed, 78 insertions(+), 36 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 4c03f739..b751740c 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2282,6 +2282,7 @@ static void radeon_set_dynamic_clock(struct drm_device *dev, int mode) int radeon_modeset_cp_init(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; + uint32_t tmp; /* allocate a ring and ring rptr bits from GART space */ /* these are allocated in GEM files */ @@ -2311,6 +2312,11 @@ int radeon_modeset_cp_init(struct drm_device *dev) radeon_cp_init_ring_buffer(dev, dev_priv); + /* need to enable BUS mastering in Buscntl */ + tmp = RADEON_READ(RADEON_BUS_CNTL); + tmp &= ~RADEON_BUS_MASTER_DIS; + RADEON_WRITE(RADEON_BUS_CNTL, tmp); + radeon_do_engine_reset(dev); radeon_test_writeback(dev_priv); @@ -2381,8 +2387,8 @@ int radeon_modeset_preinit(struct drm_device *dev) if (dev_priv->is_atom_bios) { dev_priv->mode_info.atom_context = atom_parse(&card, dev_priv->bios); - radeon_get_clock_info(dev); } + radeon_get_clock_info(dev); return 0; } diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 94975e4d..51a5b00c 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -1277,41 +1277,59 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, extern int RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr); extern void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint32_t data); -#define RADEON_WRITE_PCIE( addr, val ) \ +#define RADEON_WRITE_P(reg, val, mask) \ +do { \ + uint32_t tmp = RADEON_READ(reg); \ + tmp &= ~(mask); \ + tmp |= ((val) & ~(mask)); \ + RADEON_WRITE(reg, tmp); \ +} while(0) + +#define RADEON_WRITE_PLL_P(dev_priv, addr, val, mask) \ +do { \ + uint32_t tmp_ = RADEON_READ_PLL(dev_priv, addr); \ + tmp_ &= (mask); \ + tmp_ |= ((val) & ~(mask)); \ + RADEON_WRITE_PLL(dev_priv, addr, tmp_); \ +} while (0) + + + +#define RADEON_WRITE_PCIE(addr, val) \ do { \ - RADEON_WRITE8( RADEON_PCIE_INDEX, \ + RADEON_WRITE8(RADEON_PCIE_INDEX, \ ((addr) & 0xff)); \ - RADEON_WRITE( RADEON_PCIE_DATA, (val) ); \ + RADEON_WRITE(RADEON_PCIE_DATA, (val)); \ } while (0) -#define R500_WRITE_MCIND( addr, val ) \ +#define R500_WRITE_MCIND(addr, val) \ do { \ RADEON_WRITE(R520_MC_IND_INDEX, 0xff0000 | ((addr) & 0xff)); \ RADEON_WRITE(R520_MC_IND_DATA, (val)); \ RADEON_WRITE(R520_MC_IND_INDEX, 0); \ } while (0) -#define RS480_WRITE_MCIND( addr, val ) \ +#define RS480_WRITE_MCIND(addr, val) \ do { \ - RADEON_WRITE( RS480_NB_MC_INDEX, \ + RADEON_WRITE(RS480_NB_MC_INDEX, \ ((addr) & 0xff) | RS480_NB_MC_IND_WR_EN); \ - RADEON_WRITE( RS480_NB_MC_DATA, (val) ); \ - RADEON_WRITE( RS480_NB_MC_INDEX, 0xff ); \ + RADEON_WRITE(RS480_NB_MC_DATA, (val)); \ + RADEON_WRITE(RS480_NB_MC_INDEX, 0xff); \ } while (0) -#define RS690_WRITE_MCIND( addr, val ) \ +#define RS690_WRITE_MCIND(addr, val) \ do { \ RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_EN | ((addr) & RS690_MC_INDEX_MASK)); \ RADEON_WRITE(RS690_MC_DATA, val); \ RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \ } while (0) -#define IGP_WRITE_MCIND( addr, val ) \ +#define IGP_WRITE_MCIND(addr, val) \ do { \ - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) \ - RS690_WRITE_MCIND( addr, val ); \ - else \ - RS480_WRITE_MCIND( addr, val ); \ + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) \ + RS690_WRITE_MCIND(addr, val); \ + else \ + RS480_WRITE_MCIND(addr, val); \ } while (0) #define CP_PACKET0( reg, n ) \ @@ -1355,42 +1373,42 @@ do { \ #define RADEON_FLUSH_CACHE() do { \ if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \ - OUT_RING( RADEON_RB3D_DC_FLUSH ); \ + OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \ + OUT_RING(RADEON_RB3D_DC_FLUSH); \ } else { \ - OUT_RING( CP_PACKET0( R300_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \ - OUT_RING( RADEON_RB3D_DC_FLUSH ); \ - } \ + OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \ + OUT_RING(RADEON_RB3D_DC_FLUSH); \ + } \ } while (0) #define RADEON_PURGE_CACHE() do { \ if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \ - OUT_RING( RADEON_RB3D_DC_FLUSH_ALL ); \ + OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \ + OUT_RING(RADEON_RB3D_DC_FLUSH_ALL); \ } else { \ - OUT_RING( CP_PACKET0( R300_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \ - OUT_RING( RADEON_RB3D_DC_FLUSH_ALL ); \ - } \ + OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \ + OUT_RING(RADEON_RB3D_DC_FLUSH_ALL); \ + } \ } while (0) #define RADEON_FLUSH_ZCACHE() do { \ if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \ - OUT_RING( RADEON_RB3D_ZC_FLUSH ); \ + OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); \ + OUT_RING(RADEON_RB3D_ZC_FLUSH); \ } else { \ - OUT_RING( CP_PACKET0( R300_ZB_ZCACHE_CTLSTAT, 0 ) ); \ - OUT_RING( R300_ZC_FLUSH ); \ - } \ + OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0)); \ + OUT_RING(R300_ZC_FLUSH); \ + } \ } while (0) #define RADEON_PURGE_ZCACHE() do { \ if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \ - OUT_RING( RADEON_RB3D_ZC_FLUSH_ALL ); \ + OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); \ + OUT_RING(RADEON_RB3D_ZC_FLUSH_ALL); \ } else { \ - OUT_RING( CP_PACKET0( R300_RB3D_ZCACHE_CTLSTAT, 0 ) ); \ - OUT_RING( R300_ZC_FLUSH_ALL ); \ - } \ + OUT_RING(CP_PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); \ + OUT_RING(R300_ZC_FLUSH_ALL); \ + } \ } while (0) /* ================================================================ @@ -1411,7 +1429,7 @@ do { \ #define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ do { \ struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; \ - drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; \ + drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; \ if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \ int __ret = radeon_do_cp_idle( dev_priv ); \ if ( __ret ) return __ret; \ @@ -1587,6 +1605,23 @@ static inline int radeon_update_breadcrumb(struct drm_device *dev) #define radeon_is_dce3(dev_priv) ((dev_priv->chip_family >= CHIP_RV620)) +#define radeon_is_rv100(dev_priv) ((dev_priv->chip_family == CHIP_RV100) || \ + (dev_priv->chip_family == CHIP_RV200) || \ + (dev_priv->chip_family == CHIP_RS100) || \ + (dev_priv->chip_family == CHIP_RS200) || \ + (dev_priv->chip_family == CHIP_RV250) || \ + (dev_priv->chip_family == CHIP_RV280) || \ + (dev_priv->chip_family == CHIP_RS300)) + +#define radeon_is_r300(dev_priv) ((dev_priv->chip_family == CHIP_R300) || \ + (dev_priv->chip_family == CHIP_RV350) || \ + (dev_priv->chip_family == CHIP_R350) || \ + (dev_priv->chip_family == CHIP_RV380) || \ + (dev_priv->chip_family == CHIP_R420) || \ + (dev_priv->chip_family == CHIP_RV410) || \ + (dev_priv->chip_family == CHIP_RS400) || \ + (dev_priv->chip_family == CHIP_RS480)) + #define radeon_bios8(dev_priv, v) (dev_priv->bios[v]) #define radeon_bios16(dev_priv, v) (dev_priv->bios[v] | (dev_priv->bios[(v) + 1] << 8)) #define radeon_bios32(dev_priv, v) ((dev_priv->bios[v]) | \ @@ -1594,6 +1629,7 @@ static inline int radeon_update_breadcrumb(struct drm_device *dev) (dev_priv->bios[(v) + 2] << 16) | \ (dev_priv->bios[(v) + 3] << 24)) +extern void radeon_pll_errata_after_index(struct drm_radeon_private *dev_priv); extern int radeon_emit_irq(struct drm_device * dev); extern void radeon_gem_free_object(struct drm_gem_object *obj); -- cgit v1.2.3 From f79ed5546229aa923f8dd54055bebeb56efaa76c Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Sat, 9 Aug 2008 19:47:06 +0200 Subject: NV50: enable hotplug irq --- shared-core/nouveau_irq.c | 9 +++++++-- shared-core/nouveau_reg.h | 2 -- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'shared-core') diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index 4c46da8d..5b700915 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -41,6 +41,8 @@ #include "nv50_display.h" #include "nv50_crtc.h" #include "nv50_output.h" +/* needed for hotplug irq */ +#include "nv50_kms_wrapper.h" void nouveau_irq_preinstall(struct drm_device *dev) @@ -591,10 +593,13 @@ nouveau_nv50_i2c_irq_handler(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - DRM_INFO("NV50_I2C_INTR - 0x%08X\n", NV_READ(NV50_I2C_CONTROLLER)); + DRM_INFO("NV50_I2C_INTR - 0x%08X\n", NV_READ(NV50_PCONNECTOR_HOTPLUG_CTRL)); /* This seems to be the way to acknowledge an interrupt. */ - NV_WRITE(NV50_I2C_CONTROLLER, 0x7FFF7FFF); + NV_WRITE(NV50_PCONNECTOR_HOTPLUG_CTRL, 0x7FFF7FFF); + + /* Do a "dumb" detect all */ + nv50_kms_connector_detect_all(dev); } irqreturn_t diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h index 6ed23e26..091c22c4 100644 --- a/shared-core/nouveau_reg.h +++ b/shared-core/nouveau_reg.h @@ -128,8 +128,6 @@ #define NV04_PTIMER_TIME_1 0x00009410 #define NV04_PTIMER_ALARM_0 0x00009420 -#define NV50_I2C_CONTROLLER 0x0000E054 - #define NV04_PFB_CFG0 0x00100200 #define NV04_PFB_CFG1 0x00100204 #define NV40_PFB_020C 0x0010020C -- cgit v1.2.3 From 9a2adc442af9d83b85e4d558cb5e4d33597b60b9 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Sat, 9 Aug 2008 19:50:00 +0200 Subject: NV50: minor changes --- shared-core/nouveau_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index 5b700915..48872622 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -512,7 +512,7 @@ nouveau_nv50_display_irq_handler(struct drm_device *dev) struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t val = NV_READ(NV50_PDISPLAY_SUPERVISOR); - DRM_INFO("NV50_DISPLAY_INTR - 0x%08X\n", val); + DRM_INFO("NV50_PDISPLAY_SUPERVISOR - 0x%08X\n", val); /* vblank interrupts */ if (val & NV50_PDISPLAY_SUPERVISOR_CRTCn) { @@ -593,7 +593,7 @@ nouveau_nv50_i2c_irq_handler(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - DRM_INFO("NV50_I2C_INTR - 0x%08X\n", NV_READ(NV50_PCONNECTOR_HOTPLUG_CTRL)); + DRM_INFO("NV50_PCONNECTOR_HOTPLUG_CTRL - 0x%08X\n", NV_READ(NV50_PCONNECTOR_HOTPLUG_CTRL)); /* This seems to be the way to acknowledge an interrupt. */ NV_WRITE(NV50_PCONNECTOR_HOTPLUG_CTRL, 0x7FFF7FFF); -- cgit v1.2.3 From 1c6abcefdc37f5cbb447e8fee1f3805fd7d19bea Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 13 Aug 2008 11:39:22 -0700 Subject: i915: setup hardware status page if physical addrs are required Needed for the modesetting case where we initialize the ring at load time. --- shared-core/i915_init.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'shared-core') diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 4f2d3a4f..b21351c0 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -100,6 +100,32 @@ int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size, return 0; } +static int +i915_init_hws_phys(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int ret = 0; + + dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, + 0xffffffff); + + if (!dev_priv->status_page_dmah) { + DRM_ERROR("Can not allocate hardware status page\n"); + ret = -ENOMEM; + goto out; + } + 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(HWS_PGA, dev_priv->dma_status_page); + DRM_DEBUG("hws kernel virt: 0x%p\n", dev_priv->hw_status_page); + +out: + return ret; +} + static int i915_load_modeset_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -113,6 +139,9 @@ static int i915_load_modeset_init(struct drm_device *dev) /* Let GEM Manage from end of prealloc space to end of aperture */ i915_gem_do_init(dev, prealloc_size, agp_size); + if (!I915_NEED_GFX_HWS(dev)) + i915_init_hws_phys(dev); + ret = i915_gem_init_ringbuffer(dev); if (ret) goto out; @@ -354,6 +383,8 @@ int i915_driver_unload(struct drm_device *dev) mutex_unlock(&dev->struct_mutex); drm_mm_takedown(&dev_priv->vram); i915_gem_lastclose(dev); + if (!I915_NEED_GFX_HWS(dev)) + drm_pci_free(dev, dev_priv->status_page_dmah); } drm_rmmap(dev, dev_priv->mmio_map); -- cgit v1.2.3 From 957c71ff52e93bb2c1bc01b99d29d763d0ef3899 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 14 Aug 2008 09:10:11 +1000 Subject: radeon: FEDORA: add old DMA buffers on top of GEM This really shouldn't go upstream, it just lets me run the old 3D driver on GEM setup system --- shared-core/radeon_drv.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'shared-core') diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 51a5b00c..138db794 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -277,6 +277,9 @@ struct radeon_mm_info { struct radeon_mm_obj pcie_table; struct radeon_mm_obj ring; struct radeon_mm_obj ring_read; + + struct radeon_mm_obj dma_bufs; + struct drm_map fake_agp_map; }; #include "radeon_mode.h" -- cgit v1.2.3 From d59f41b8cf0634a433be7d11f6b473035060c5e1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 14 Aug 2008 09:11:15 +1000 Subject: radeon: add userspace call for mm support check --- shared-core/radeon_state.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'shared-core') diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index e168ea02..01ee71f6 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -3121,6 +3121,9 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil /* BSD TODO */ value = 1; break; + case RADEON_PARAM_KERNEL_MM: + value = !dev_priv->mm_disabled; + break; default: DRM_DEBUG( "Invalid parameter %d\n", param->param ); return -EINVAL; -- cgit v1.2.3 From 18020e5e9647e218caf8f1566cdc053aac126f23 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 14 Aug 2008 09:12:36 +1000 Subject: radeon: make buffer swap for older drivers work again on GEM --- shared-core/radeon_drv.h | 1 + shared-core/radeon_state.c | 3 +++ 2 files changed, 4 insertions(+) (limited to 'shared-core') diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 138db794..aa5b4ba8 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -1664,6 +1664,7 @@ extern void radeon_master_destroy(struct drm_device *dev, struct drm_master *mas extern void radeon_cp_dispatch_flip(struct drm_device * dev, struct drm_master *master); extern int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv); extern int radeon_cs_init(struct drm_device *dev); +void radeon_gem_update_offsets(struct drm_device *dev, struct drm_master *master); #define MARK_SAFE 1 #define MARK_CHECK_OFFSET 2 diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index 01ee71f6..1a828be8 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -2223,6 +2223,9 @@ static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *f if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; + if (dev_priv->mm.vram_offset) + radeon_gem_update_offsets(dev, file_priv->master); + radeon_cp_dispatch_swap(dev, file_priv->master); sarea_priv->ctx_owner = 0; -- cgit v1.2.3 From b0ee12e6bb55655c92184483a065780529c8aa63 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 14 Aug 2008 09:14:14 +1000 Subject: radeon: use mm_enabled variable to denote memory manager running --- shared-core/radeon_drv.h | 2 +- shared-core/radeon_state.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index aa5b4ba8..df08b8d3 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -399,7 +399,7 @@ typedef struct drm_radeon_private { int num_gb_pipes; - int mm_disabled; /* on OSes with no MM this will be 1*/ + bool mm_enabled; struct radeon_mm_info mm; drm_local_map_t *mmio; diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index 1a828be8..4520a35d 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -3125,7 +3125,7 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil value = 1; break; case RADEON_PARAM_KERNEL_MM: - value = !dev_priv->mm_disabled; + value = dev_priv->mm_enabled; break; default: DRM_DEBUG( "Invalid parameter %d\n", param->param ); -- cgit v1.2.3 From 58df2fa0ecc7e4dac83b4e7a72d70c3ea41c7ed2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 14 Aug 2008 09:14:56 +1000 Subject: radeon: remove debugging --- shared-core/radeon_cs.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index 33a8ccd4..d961189e 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -154,10 +154,7 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct break; } - - DRM_ERROR("New offset %x %x %x\n", packets[offset_dw+1], val, offset); packets[offset_dw + 1] = val; - return 0; } @@ -185,7 +182,6 @@ static int radeon_cs_relocate_packet3(struct drm_device *dev, struct drm_file *f offset >>= 10; val |= offset; - DRM_ERROR("New offset %x %x %x\n", packets[offset_dw+2], val, offset); packets[offset_dw + 2] = val; } default: @@ -215,7 +211,6 @@ static __inline__ int radeon_cs_check_offset(struct drm_device *dev, break; } - DRM_ERROR("Offset check %x %x\n", reg, offset); return 0; } -- cgit v1.2.3 From b167ccf10fffb3e0ae0be14fc3b168fcacc373d8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 14 Aug 2008 09:17:43 +1000 Subject: radeon: fix kernel_mm properly --- shared-core/radeon_state.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index 4520a35d..7262b2aa 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -3120,10 +3120,6 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil case RADEON_PARAM_NUM_GB_PIPES: value = dev_priv->num_gb_pipes; break; - case RADEON_PARAM_KERNEL_MM: - /* BSD TODO */ - value = 1; - break; case RADEON_PARAM_KERNEL_MM: value = dev_priv->mm_enabled; break; -- cgit v1.2.3 From 5f427e9aaed76ec827b9523b4022205f5bd09a4a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 11 Aug 2008 12:29:42 -0400 Subject: Brute force port of legacy crtc/encoder code - removed save/init/restore chain with set functions --- shared-core/radeon_cp.c | 2 +- shared-core/radeon_drv.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index b751740c..53177bb0 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -185,7 +185,7 @@ void radeon_pll_errata_after_data(struct drm_radeon_private *dev_priv) } } -int RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr) +u32 RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr) { uint32_t data; diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index df08b8d3..fb266093 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -1277,7 +1277,7 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, #define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) #define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) ) -extern int RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr); +extern u32 RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr); extern void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint32_t data); #define RADEON_WRITE_P(reg, val, mask) \ -- cgit v1.2.3 From b486ed7f7d89528c94f2345040324946f6eadc81 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 12 Aug 2008 13:52:35 -0400 Subject: Get legacy working finally - extra ~ in RADEON_WRITE_P() - re-arrange crtc setup a bit - add debugging for tracing calls - fix pitch calculation --- shared-core/radeon_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index fb266093..2b8d7f6e 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -1283,7 +1283,7 @@ extern void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint #define RADEON_WRITE_P(reg, val, mask) \ do { \ uint32_t tmp = RADEON_READ(reg); \ - tmp &= ~(mask); \ + tmp &= (mask); \ tmp |= ((val) & ~(mask)); \ RADEON_WRITE(reg, tmp); \ } while(0) -- cgit v1.2.3 From 9dff806802bad79242c58cc5dca3fd108099982b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 14 Aug 2008 09:43:23 +1000 Subject: i915: fixup from last merge hopefully --- shared-core/i915_dma.c | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 7f025e62..ddc9cd5a 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -248,25 +248,6 @@ static int i915_initialize(struct drm_device * dev, */ dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A; - /* Program Hardware Status Page */ - if (!I915_NEED_GFX_HWS(dev)) { - dev_priv->status_page_dmah = - drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); - - if (!dev_priv->status_page_dmah) { - i915_dma_cleanup(dev); - DRM_ERROR("Can not allocate hardware status page\n"); - return -ENOMEM; - } - dev_priv->hws_vaddr = dev_priv->status_page_dmah->vaddr; - dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; - - memset(dev_priv->hws_vaddr, 0, PAGE_SIZE); - - I915_WRITE(0x02080, dev_priv->dma_status_page); - } - DRM_DEBUG("Enabled hardware status page\n"); - #ifdef DRI2 if (init->func == I915_INIT_DMA2) { int ret = setup_dri2_sarea(dev, file_priv, init); -- cgit v1.2.3 From eb8f9b9da4d34b9bfa16dc3847e81976a12d2d0c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 14 Aug 2008 14:41:15 +1000 Subject: radeon: add copy/solid regs for rn50 --- shared-core/r300_cmdbuf.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'shared-core') diff --git a/shared-core/r300_cmdbuf.c b/shared-core/r300_cmdbuf.c index 53961fc7..725829b2 100644 --- a/shared-core/r300_cmdbuf.c +++ b/shared-core/r300_cmdbuf.c @@ -303,6 +303,13 @@ void r300_init_reg_flags(struct drm_device *dev) ADD_RANGE(R300_VAP_PVS_CODE_CNTL_0, 4); ADD_RANGE(R300_VAP_PVS_VECTOR_INDX_REG, 2); + + if (dev_priv->chip_family <= CHIP_RV280) { + ADD_RANGE(RADEON_RE_TOP_LEFT, 1); + ADD_RANGE(RADEON_RE_WIDTH_HEIGHT, 1); + ADD_RANGE(RADEON_AUX_SC_CNTL, 1); + ADD_RANGE(RADEON_RB3D_DSTCACHE_CTLSTAT, 1); + } } int r300_check_range(unsigned reg, int count) -- cgit v1.2.3 From 30ff279e42b3b0608e8ff6620d2958c174449798 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 14 Aug 2008 14:43:51 +1000 Subject: radeon: add support for memory map init --- shared-core/radeon_cp.c | 42 ++++++++++++++++++++++++++++++++---------- shared-core/radeon_drv.h | 7 ++++++- 2 files changed, 38 insertions(+), 11 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 04f4b1f8..e30696fc 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -107,7 +107,33 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) return RADEON_READ(RADEON_MC_FB_LOCATION); } -static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) +void radeon_read_agp_location(drm_radeon_private_t *dev_priv, u32 *agp_lo, u32 *agp_hi) +{ + if (dev_priv->chip_family == CHIP_RV770) { + + } else if (dev_priv->chip_family == CHIP_R600) { + *agp_lo = RADEON_READ(R600_MC_VM_AGP_BOT); + *agp_hi = RADEON_READ(R600_MC_VM_AGP_TOP); + } else if (dev_priv->chip_family == CHIP_RV515) { + *agp_lo = radeon_read_mc_reg(dev_priv, RV515_MC_FB_LOCATION); + *agp_hi = 0; + } else if (dev_priv->chip_family == CHIP_RS600) { + *agp_lo = 0; + *agp_hi = 0; + } else if (dev_priv->chip_family == CHIP_RS690 || + dev_priv->chip_family == CHIP_RS740) { + *agp_lo = radeon_read_mc_reg(dev_priv, RS690_MC_AGP_LOCATION); + *agp_hi = 0; + } else if (dev_priv->chip_family >= CHIP_R520) { + *agp_lo = radeon_read_mc_reg(dev_priv, R520_MC_AGP_LOCATION); + *agp_hi = 0; + } else { + *agp_lo = RADEON_READ(RADEON_MC_FB_LOCATION); + *agp_hi = 0; + } +} + +void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) { if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); @@ -119,7 +145,7 @@ static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc); } -static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) +static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc, u32 agp_loc_hi) { if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); @@ -672,7 +698,7 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, radeon_write_agp_location(dev_priv, (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) & 0xffff0000) | - (dev_priv->gart_vm_start >> 16))); + (dev_priv->gart_vm_start >> 16)), 0); ring_start = (dev_priv->cp_ring->offset - dev->agp->base @@ -873,7 +899,7 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) & 0xffff0000) | (dev_priv->gart_vm_start >> 16)); - radeon_write_agp_location(dev_priv, temp); + radeon_write_agp_location(dev_priv, temp, 0); temp = IGP_READ_MCIND(dev_priv, RS480_AGP_ADDRESS_SPACE_SIZE); IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | @@ -921,7 +947,7 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) dev_priv->gart_vm_start + dev_priv->gart_size - 1); - radeon_write_agp_location(dev_priv, 0xffffffc0); /* ?? */ + radeon_write_agp_location(dev_priv, 0xffffffc0, 0); /* ?? */ RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, RADEON_PCIE_TX_GART_EN); @@ -965,7 +991,7 @@ void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) /* Turn off AGP aperture -- is this required for PCI GART? */ - radeon_write_agp_location(dev_priv, 0xffffffc0); + radeon_write_agp_location(dev_priv, 0xffffffc0, 0); RADEON_WRITE(RADEON_AGP_COMMAND, 0); /* clear AGP_COMMAND */ } else { RADEON_WRITE(RADEON_AIC_CNTL, @@ -2482,10 +2508,6 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) if (drm_core_check_feature(dev, DRIVER_MODESET)) { - dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16; - dev_priv->fb_size = - ((radeon_read_fb_location(dev_priv) & 0xffff0000u) + 0x10000) - - dev_priv->fb_location; radeon_gem_mm_init(dev); radeon_modeset_init(dev); diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index a40ff6dd..9edd3884 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -418,6 +418,10 @@ typedef struct drm_radeon_private { bool is_ddr; u32 ram_width; + uint32_t mc_fb_location; + uint32_t mc_agp_loc_lo; + uint32_t mc_agp_loc_hi; + enum radeon_pll_errata pll_errata; int num_gb_pipes; @@ -1655,7 +1659,8 @@ int radeon_modeset_init(struct drm_device *dev); void radeon_modeset_cleanup(struct drm_device *dev); extern u32 radeon_read_mc_reg(drm_radeon_private_t *dev_priv, int addr); extern void radeon_write_mc_reg(drm_radeon_private_t *dev_priv, u32 addr, u32 val); - +void radeon_read_agp_location(drm_radeon_private_t *dev_priv, u32 *agp_lo, u32 *agp_hi); +void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc); extern void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on); #define RADEONFB_CONN_LIMIT 4 -- cgit v1.2.3 From 893315d49ed678de95cf6ac553efb6093cc7343c Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Sat, 16 Aug 2008 11:35:10 -0700 Subject: i915: set domain properly on fb mapping, flush out changes The user visible ioctl does this, but since we call into GEM internals directly, we have to flush things ourselves. Fixes initial fb console corruption. --- shared-core/i915_drv.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'shared-core') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 087c6d64..a031afd2 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -627,6 +627,9 @@ int i915_gem_init_ringbuffer(struct drm_device *dev); void i915_gem_cleanup_ringbuffer(struct drm_device *dev); int i915_gem_do_init(struct drm_device *dev, unsigned long start, unsigned long end); +int i915_gem_object_set_domain(struct drm_gem_object *obj, + uint32_t read_domains, + uint32_t write_domain); void i915_gem_retire_work_handler(struct work_struct *work); void i915_gem_clflush_object(struct drm_gem_object *obj); #endif -- cgit v1.2.3 From a2adc696569de830c7a95722dd111bff706a0bbc Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Sat, 16 Aug 2008 12:09:24 -0700 Subject: i915: finish removing TTM bits Makes it build again. --- shared-core/i915_drv.h | 32 +------------------------------- shared-core/i915_init.c | 3 --- shared-core/i915_irq.c | 3 --- 3 files changed, 1 insertion(+), 37 deletions(-) (limited to 'shared-core') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index a031afd2..04062c45 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -42,7 +42,6 @@ #define DRIVER_DATE "20080730" #if defined(__linux__) -#define I915_HAVE_FENCE #define I915_HAVE_BUFFER #endif @@ -62,7 +61,7 @@ * 1.12: TTM relocation optimization */ #define DRIVER_MAJOR 1 -#if defined(I915_HAVE_FENCE) && defined(I915_HAVE_BUFFER) +#if defined(I915_HAVE_BUFFER) #define DRIVER_MINOR 13 #else #define DRIVER_MINOR 6 @@ -176,12 +175,6 @@ struct drm_i915_private { struct drm_mm vram; -#ifdef I915_HAVE_FENCE - uint32_t flush_sequence; - uint32_t flush_flags; - uint32_t flush_pending; - uint32_t saved_flush_status; -#endif #ifdef I915_HAVE_BUFFER void *agp_iomap; unsigned int max_validate_buffers; @@ -556,30 +549,7 @@ extern void i915_mem_release(struct drm_device * dev, extern int i915_save_state(struct drm_device *dev); extern int i915_restore_state(struct drm_device *dev); -#ifdef I915_HAVE_FENCE -/* i915_fence.c */ -extern void i915_fence_handler(struct drm_device *dev); -extern void i915_invalidate_reported_sequence(struct drm_device *dev); - -#endif - -#if defined(I915_HAVE_BUFFER) && defined(I915_TTM) -/* i915_buffer.c */ -extern struct drm_ttm_backend *i915_create_ttm_backend_entry(struct drm_device *dev); -extern int i915_fence_type(struct drm_buffer_object *bo, uint32_t *fclass, - uint32_t *type); -extern int i915_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags); -extern int i915_init_mem_type(struct drm_device *dev, uint32_t type, - struct drm_mem_type_manager *man); -extern uint64_t i915_evict_flags(struct drm_buffer_object *bo); -extern int i915_move(struct drm_buffer_object *bo, int evict, - int no_wait, struct drm_bo_mem_reg *new_mem); -void i915_flush_ttm(struct drm_ttm *ttm); -#endif /* ttm */ #ifdef I915_HAVE_BUFFER -/* i915_execbuf.c */ -int i915_execbuffer(struct drm_device *dev, void *data, - struct drm_file *file_priv); /* i915_gem.c */ int i915_gem_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 7b88cc8d..d6383929 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -519,8 +519,5 @@ int i915_driver_firstopen(struct drm_device *dev) { if (drm_core_check_feature(dev, DRIVER_MODESET)) return 0; -#if defined(I915_HAVE_BUFFER) && defined(I915_TTM) - drm_bo_driver_init(dev); -#endif return 0; } diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 28fa35fd..ee83b14e 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -554,9 +554,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) if (iir & I915_USER_INTERRUPT) { dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev); DRM_WAKEUP(&dev_priv->irq_queue); -#ifdef I915_HAVE_FENCE - i915_fence_handler(dev); -#endif } if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS| -- cgit v1.2.3 From aed70622ab33500721a30b06ec3783c581615cbb Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sun, 17 Aug 2008 18:09:07 -0400 Subject: radeon: first pass at bios scratch regs - todo: updated connected status --- shared-core/radeon_cp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index e30696fc..6b71360f 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2409,8 +2409,12 @@ int radeon_modeset_preinit(struct drm_device *dev) if (dev_priv->is_atom_bios) { dev_priv->mode_info.atom_context = atom_parse(&card, dev_priv->bios); - } + radeon_atom_initialize_bios_scratch_regs(dev); + } else + radeon_combios_initialize_bios_scratch_regs(dev); + radeon_get_clock_info(dev); + return 0; } -- cgit v1.2.3 From 2d4cf9cc0f31ca316b109cceffc463ea52db92f2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Aug 2008 08:18:46 +1000 Subject: radeon: oops set correct scratch --- shared-core/radeon_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 9edd3884..019491c7 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -717,7 +717,7 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, #define GET_SCRATCH( x ) (dev_priv->writeback_works ? \ (dev_priv->mm.ring_read.bo ? \ - readl(dev_priv->mm.ring_read.kmap.virtual + RADEON_SCRATCHOFF(0)) : \ + readl(dev_priv->mm.ring_read.kmap.virtual + RADEON_SCRATCHOFF(x)) : \ DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(x))) : \ RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x))) -- cgit v1.2.3 From 361ab10d2fb0c7ad73e54d92af2563194dbf7080 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 26 Aug 2008 17:39:00 +1000 Subject: radeon: fixup domains and use them properly --- shared-core/radeon_drm.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index 8bb5d87c..bb81bef0 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -784,12 +784,9 @@ typedef struct drm_radeon_surface_free { #define DRM_RADEON_VBLANK_CRTC1 1 #define DRM_RADEON_VBLANK_CRTC2 2 -#define RADEON_GEM_DOMAIN_CPU 0x1 -#define RADEON_GEM_DOMAIN_VRAM 0x2 -#define RADEON_GEM_DOMAIN_2D 0x4 -#define RADEON_GEM_DOMAIN_3D 0x8 -#define RADEON_GEM_DOMAIN_TEXTURE 0x10 -#define RADEON_GEM_DOMAIN_GPU 0x20 // for vertex buffers +#define RADEON_GEM_DOMAIN_CPU 0x1 // Cached CPU domain +#define RADEON_GEM_DOMAIN_GTT 0x2 // GTT or cache flushed +#define RADEON_GEM_DOMAIN_VRAM 0x4 // VRAM domain /* return to userspace start/size of gtt and vram apertures */ struct drm_radeon_gem_info { -- cgit v1.2.3 From 7552b2a6c3b29da308a76dade4959180d0d1c57b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 27 Aug 2008 13:41:53 +1000 Subject: drm: fix some whitespace --- shared-core/drm.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index b177dfe5..6f93618a 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -887,11 +887,11 @@ struct drm_mode_get_blob { }; struct drm_mode_fb_cmd { - unsigned int buffer_id; - unsigned int width, height; - unsigned int pitch; - unsigned int bpp; - unsigned int handle; + unsigned int buffer_id; + unsigned int width, height; + unsigned int pitch; + unsigned int bpp; + unsigned int handle; unsigned int depth; }; -- cgit v1.2.3 From f60d9a04b892904e5dde7dd1d2876b6bd9eb80ef Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 7 Sep 2008 08:09:24 +1000 Subject: radeon: change interface from headers add pin_domain into padding --- shared-core/radeon_drm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index bb81bef0..c924c689 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -825,7 +825,7 @@ struct drm_radeon_gem_exec_buffer { struct drm_radeon_gem_pin { uint32_t handle; - uint32_t pad; + uint32_t pin_domain; uint64_t alignment; uint64_t offset; }; -- cgit v1.2.3 From 2a6dad31d84252d505f392f91dffd90689bb947c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 18 Sep 2008 10:05:59 +1000 Subject: radeon: add initial suspend/resume support plus a bunch of fixes --- shared-core/radeon_cp.c | 103 ++++++++++++++++++++++++++++++++--------------- shared-core/radeon_drv.h | 21 +++++++++- 2 files changed, 90 insertions(+), 34 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 6b71360f..a34c6530 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -521,7 +521,6 @@ static void radeon_do_cp_flush(drm_radeon_private_t * dev_priv) DRM_DEBUG("\n"); #if 0 u32 tmp; - tmp = RADEON_READ(RADEON_CP_RB_WPTR) | (1 << 31); RADEON_WRITE(RADEON_CP_RB_WPTR, tmp); #endif @@ -761,8 +760,6 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, dev_priv->ring.size_l2qw); #endif - /* Start with assuming that writeback doesn't work */ - dev_priv->writeback_works = 0; /* Initialize the scratch register pointer. This will cause * the scratch register values to be written out to memory @@ -1341,6 +1338,9 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, radeon_set_pcigart(dev_priv, 1); } + /* Start with assuming that writeback doesn't work */ + dev_priv->writeback_works = 0; + radeon_cp_load_microcode(dev_priv); radeon_cp_init_ring_buffer(dev, dev_priv); @@ -2301,14 +2301,64 @@ static void radeon_set_dynamic_clock(struct drm_device *dev, int mode) } -int radeon_modeset_cp_init(struct drm_device *dev) +int radeon_modeset_cp_suspend(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + int ret; + + ret = radeon_do_cp_idle(dev_priv); + if (ret) + DRM_ERROR("failed to idle CP on suspend\n"); + + radeon_do_cp_stop(dev_priv); + radeon_do_engine_reset(dev); + if (dev_priv->flags & RADEON_IS_AGP) { + } else { + radeon_set_pcigart(dev_priv, 0); + } + + return 0; +} + +int radeon_modeset_cp_resume(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; uint32_t tmp; + radeon_do_wait_for_idle(dev_priv); +#if __OS_HAS_AGP + if (dev_priv->flags & RADEON_IS_AGP) { + /* Turn off PCI GART */ + radeon_set_pcigart(dev_priv, 0); + } else +#endif + { + /* Turn on PCI GART */ + radeon_set_pcigart(dev_priv, 1); + } + radeon_gart_flush(dev); + + DRM_ERROR("microcode loading\n"); + radeon_cp_load_microcode(dev_priv); + radeon_cp_init_ring_buffer(dev, dev_priv); + + DRM_ERROR("engine init\n"); + radeon_do_engine_reset(dev); + + radeon_do_cp_start(dev_priv); + return 0; +} + +int radeon_modeset_cp_init(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + /* allocate a ring and ring rptr bits from GART space */ /* these are allocated in GEM files */ + /* Start with assuming that writeback doesn't work */ + dev_priv->writeback_works = 0; + dev_priv->usec_timeout = RADEON_DEFAULT_CP_TIMEOUT; dev_priv->ring.size = RADEON_DEFAULT_RING_SIZE; dev_priv->cp_mode = RADEON_CSQ_PRIBM_INDBM; @@ -2327,23 +2377,8 @@ int radeon_modeset_cp_init(struct drm_device *dev) dev_priv->new_memmap = true; r300_init_reg_flags(dev); - - radeon_cp_load_microcode(dev_priv); - DRM_DEBUG("ring offset is %x %x\n", dev_priv->mm.ring.bo->offset, dev_priv->mm.ring_read.bo->offset); - - radeon_cp_init_ring_buffer(dev, dev_priv); - - /* need to enable BUS mastering in Buscntl */ - tmp = RADEON_READ(RADEON_BUS_CNTL); - tmp &= ~RADEON_BUS_MASTER_DIS; - RADEON_WRITE(RADEON_BUS_CNTL, tmp); - - radeon_do_engine_reset(dev); - radeon_test_writeback(dev_priv); - - radeon_do_cp_start(dev_priv); - return 0; + return radeon_modeset_cp_resume(dev); } static bool radeon_get_bios(struct drm_device *dev) @@ -2418,6 +2453,20 @@ int radeon_modeset_preinit(struct drm_device *dev) return 0; } +int radeon_static_clocks_init(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + if ((dev_priv->flags & RADEON_IS_MOBILITY) && !radeon_is_avivo(dev_priv)) { + radeon_set_dynamic_clock(dev, radeon_dynclks); + } else if (radeon_is_avivo(dev_priv)) { + if (radeon_dynclks) { + radeon_atom_static_pwrmgt_setup(dev, 1); + radeon_atom_dyn_clk_setup(dev, 1); + } + } + radeon_force_some_clocks(dev); +} int radeon_driver_load(struct drm_device *dev, unsigned long flags) { @@ -2473,7 +2522,6 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) if (drm_core_check_feature(dev, DRIVER_MODESET)) radeon_modeset_preinit(dev); - radeon_get_vram_type(dev); dev_priv->pll_errata = 0; @@ -2493,17 +2541,8 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->pll_errata |= CHIP_ERRATA_PLL_DELAY; - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - if ((dev_priv->flags & RADEON_IS_MOBILITY) && !radeon_is_avivo(dev_priv)) { - radeon_set_dynamic_clock(dev, radeon_dynclks); - } else if (radeon_is_avivo(dev_priv)) { - if (radeon_dynclks) { - radeon_atom_static_pwrmgt_setup(dev, 1); - radeon_atom_dyn_clk_setup(dev, 1); - } - } - radeon_force_some_clocks(dev); - } + if (drm_core_check_feature(dev, DRIVER_MODESET)) + radeon_static_clocks_init(dev); /* init memory manager - start with all of VRAM and a 32MB GART aperture for now */ dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0); diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 019491c7..662d9cc3 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -273,6 +273,8 @@ struct radeon_mm_info { uint64_t gart_start; uint64_t gart_size; + + void *pcie_table_backup; struct radeon_mm_obj pcie_table; struct radeon_mm_obj ring; @@ -314,6 +316,11 @@ struct drm_radeon_cs_priv { uint32_t *reloc, uint32_t *offset); }; +struct radeon_pm_regs { + uint32_t crtc_ext_cntl; + uint32_t bios_scratch[8]; +}; + typedef struct drm_radeon_private { drm_radeon_ring_buffer_t ring; @@ -432,6 +439,8 @@ typedef struct drm_radeon_private { /* ib bitmap */ uint64_t ib_alloc_bitmap; // TO DO replace with a real bitmap struct drm_radeon_cs_priv cs; + + struct radeon_pm_regs pmregs; } drm_radeon_private_t; typedef struct drm_radeon_buf_priv { @@ -527,6 +536,11 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, struct drm_file *file_priv, drm_radeon_kcmd_buffer_t *cmdbuf); +extern int radeon_modeset_cp_suspend(struct drm_device *dev); +extern int radeon_modeset_cp_resume(struct drm_device *dev); +/* radeon_pm.c */ +int radeon_suspend(struct drm_device *dev, pm_message_t state); +int radeon_resume(struct drm_device *dev); /* Flags for stats.boxes */ #define RADEON_BOX_DMA_IDLE 0x1 @@ -1464,7 +1478,7 @@ do { \ * Ring control */ -#define RADEON_VERBOSE 0 +#define RADEON_VERBOSE 1 #define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring; @@ -1648,7 +1662,8 @@ extern int radeon_gem_pin_ioctl(struct drm_device *dev, void *data, extern int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int radeon_gem_object_pin(struct drm_gem_object *obj, - uint32_t alignment); + uint32_t alignment, uint32_t pin_domain); +int radeon_gem_object_unpin(struct drm_gem_object *obj); int radeon_gem_indirect_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, @@ -1670,6 +1685,8 @@ extern void radeon_cp_dispatch_flip(struct drm_device * dev, struct drm_master * extern int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv); extern int radeon_cs_init(struct drm_device *dev); void radeon_gem_update_offsets(struct drm_device *dev, struct drm_master *master); +void radeon_init_memory_map(struct drm_device *dev); + #define MARK_SAFE 1 #define MARK_CHECK_OFFSET 2 -- cgit v1.2.3 From 8f23d4a44cdb17abff8f1ab3585e533ae0572224 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 18 Sep 2008 10:11:43 +1000 Subject: make text reserve 256k --- shared-core/radeon_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 662d9cc3..96f9a98c 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -1478,7 +1478,7 @@ do { \ * Ring control */ -#define RADEON_VERBOSE 1 +#define RADEON_VERBOSE 0 #define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring; -- cgit v1.2.3 From ed961cb428a73a35d473c27f62809ef80bde8706 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 18 Sep 2008 10:14:32 +1000 Subject: radeon: remove unneeded debugging --- shared-core/radeon_cp.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index a34c6530..8fc43756 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2338,11 +2338,9 @@ int radeon_modeset_cp_resume(struct drm_device *dev) } radeon_gart_flush(dev); - DRM_ERROR("microcode loading\n"); radeon_cp_load_microcode(dev_priv); radeon_cp_init_ring_buffer(dev, dev_priv); - DRM_ERROR("engine init\n"); radeon_do_engine_reset(dev); radeon_do_cp_start(dev_priv); -- cgit v1.2.3 From 515aa0800cf2d91bdf4706463e0531c5081a2679 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 18 Sep 2008 10:17:27 +1000 Subject: radeon: do proper memory controller init and setup --- shared-core/radeon_cp.c | 2 +- shared-core/radeon_drv.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 8fc43756..63957cd7 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -356,7 +356,7 @@ static int radeon_do_wait_for_fifo(drm_radeon_private_t * dev_priv, int entries) return -EBUSY; } -static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv) +int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv) { int i, ret; diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 96f9a98c..82d9d001 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -491,6 +491,7 @@ extern struct drm_buf *radeon_freelist_get(struct drm_device * dev); extern int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n); +extern int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv); extern int radeon_do_cp_idle(drm_radeon_private_t * dev_priv); extern int radeon_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv); -- cgit v1.2.3 From 8f38c28a3924dbda5babcf035911e103f27f9a05 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 18 Sep 2008 10:19:08 +1000 Subject: radeon: fail properly if we can't create the ring. Normally this will be due to an AGP driver needing updating --- shared-core/radeon_cp.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 63957cd7..6c5bf03b 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2549,7 +2549,9 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) if (drm_core_check_feature(dev, DRIVER_MODESET)) { - radeon_gem_mm_init(dev); + ret = radeon_gem_mm_init(dev); + if (ret) + goto modeset_fail; radeon_modeset_init(dev); radeon_modeset_cp_init(dev); @@ -2559,6 +2561,10 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) } + return ret; +modeset_fail: + dev->driver->driver_features &= ~DRIVER_MODESET; + drm_put_minor(&dev->control); return ret; } -- cgit v1.2.3 From 3a497db7862dc091a8582d8ea3ebfd7fe0f16b58 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 18 Sep 2008 10:22:23 +1000 Subject: radeon: fixup buffer and cs bits --- shared-core/radeon_cs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index b0c4abe8..a00ec21b 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -368,13 +368,14 @@ void r300_cs_id_emit(struct drm_device *dev, uint32_t *id) /* ISYNC_CNTL should not have CPSCRACTH bit set */ *id = radeon_cs_id_get(dev_priv); /* emit id in SCRATCH6 */ - BEGIN_RING(6); + BEGIN_RING(8); OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 0)); OUT_RING(6); OUT_RING(CP_PACKET0(R300_CP_RESYNC_DATA, 0)); OUT_RING(*id); OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); OUT_RING(R300_RB3D_DC_FINISH); + RADEON_WAIT_UNTIL_3D_IDLE(); ADVANCE_RING(); } -- cgit v1.2.3 From e1e782af5ddafdd24a4cf741139bb0b8e682e543 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 18 Sep 2008 15:11:48 -0400 Subject: Radeon: restructure PLL data - store pixel clocks, core clock, and memory clocks separately - grab all pll limits from bios tables --- shared-core/radeon_cp.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 6c5bf03b..1ad005b7 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2506,8 +2506,6 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) else dev_priv->flags |= RADEON_IS_PCI; - - DRM_DEBUG("%s card detected\n", ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); @@ -2527,7 +2525,7 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) if (dev_priv->chip_family == CHIP_R300 && (RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) == RADEON_CFG_ATI_REV_A11) dev_priv->pll_errata |= CHIP_ERRATA_R300_CG; - + if (dev_priv->chip_family == CHIP_RV200 || dev_priv->chip_family == CHIP_RS200) dev_priv->pll_errata |= CHIP_ERRATA_PLL_DUMMYREADS; -- cgit v1.2.3 From 34af71c42a66e5ef6a9a08250ca541030ca3cc4f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 18 Sep 2008 16:07:41 -0400 Subject: radeon: add function to configure PCIE lanes --- shared-core/radeon_cp.c | 2 +- shared-core/radeon_drv.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 1ad005b7..b934d3bc 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -235,7 +235,7 @@ void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint32_t da radeon_pll_errata_after_data(dev_priv); } -static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) +u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) { RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff); return RADEON_READ(RADEON_PCIE_DATA); diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 82d9d001..25a07e30 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -1298,6 +1298,7 @@ int radeon_resume(struct drm_device *dev); extern u32 RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr); extern void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint32_t data); +extern u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr); #define RADEON_WRITE_P(reg, val, mask) \ do { \ -- cgit v1.2.3 From 35e379ce5a0d23f4c812739f89e02703900cd91b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 24 Sep 2008 15:25:35 +1000 Subject: radeon: add r600 modesetting registers writes --- shared-core/radeon_cp.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index b934d3bc..ffe066fc 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -101,6 +101,10 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) + return RADEON_READ(R700_MC_VM_FB_LOCATION); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return RADEON_READ(R600_MC_VM_FB_LOCATION); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); else @@ -110,7 +114,8 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) void radeon_read_agp_location(drm_radeon_private_t *dev_priv, u32 *agp_lo, u32 *agp_hi) { if (dev_priv->chip_family == CHIP_RV770) { - + *agp_lo = RADEON_READ(R600_MC_VM_AGP_BOT); + *agp_hi = RADEON_READ(R600_MC_VM_AGP_TOP); } else if (dev_priv->chip_family == CHIP_R600) { *agp_lo = RADEON_READ(R600_MC_VM_AGP_BOT); *agp_hi = RADEON_READ(R600_MC_VM_AGP_TOP); @@ -139,6 +144,10 @@ void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) + RADEON_WRITE(R700_MC_VM_FB_LOCATION, fb_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + RADEON_WRITE(R600_MC_VM_FB_LOCATION, fb_loc); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); else @@ -151,7 +160,10 @@ static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_lo R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { + RADEON_WRITE(R600_MC_VM_AGP_BOT, agp_loc); + RADEON_WRITE(R600_MC_VM_AGP_TOP, agp_loc_hi); + } else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); else RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc); @@ -2357,6 +2369,9 @@ int radeon_modeset_cp_init(struct drm_device *dev) /* Start with assuming that writeback doesn't work */ dev_priv->writeback_works = 0; + if (dev_priv->chip_family > CHIP_R600) + return; + dev_priv->usec_timeout = RADEON_DEFAULT_CP_TIMEOUT; dev_priv->ring.size = RADEON_DEFAULT_RING_SIZE; dev_priv->cp_mode = RADEON_CSQ_PRIBM_INDBM; -- cgit v1.2.3 From ea9711b954ba9093546ba13052fb8bbda860b9e4 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 25 Sep 2008 23:12:07 +0200 Subject: Seperate modesetting userspace bits into drm_mode.h --- shared-core/drm.h | 244 +------------------------------------------ shared-core/drm_mode.h | 278 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 279 insertions(+), 243 deletions(-) create mode 100644 shared-core/drm_mode.h (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 6f93618a..ec5fd3b5 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -700,249 +700,7 @@ struct drm_gem_open { uint64_t size; }; -/* - * Drm mode setting - */ -#define DRM_DISPLAY_INFO_LEN 32 -#define DRM_CONNECTOR_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) - -/* Video mode flags */ -/* bit compatible with the xorg definitions. */ -#define DRM_MODE_FLAG_PHSYNC (1<<0) -#define DRM_MODE_FLAG_NHSYNC (1<<1) -#define DRM_MODE_FLAG_PVSYNC (1<<2) -#define DRM_MODE_FLAG_NVSYNC (1<<3) -#define DRM_MODE_FLAG_INTERLACE (1<<4) -#define DRM_MODE_FLAG_DBLSCAN (1<<5) -#define DRM_MODE_FLAG_CSYNC (1<<6) -#define DRM_MODE_FLAG_PCSYNC (1<<7) -#define DRM_MODE_FLAG_NCSYNC (1<<8) -#define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */ -#define DRM_MODE_FLAG_BCAST (1<<10) -#define DRM_MODE_FLAG_PIXMUX (1<<11) -#define DRM_MODE_FLAG_DBLCLK (1<<12) -#define DRM_MODE_FLAG_CLKDIV2 (1<<13) - -/* DPMS flags */ -/* bit compatible with the xorg definitions. */ -#define DRM_MODE_DPMS_ON 0 -#define DRM_MODE_DPMS_STANDBY 1 -#define DRM_MODE_DPMS_SUSPEND 2 -#define DRM_MODE_DPMS_OFF 3 - -/* Scaling mode options */ -#define DRM_MODE_SCALE_NON_GPU 0 -#define DRM_MODE_SCALE_FULLSCREEN 1 -#define DRM_MODE_SCALE_NO_SCALE 2 -#define DRM_MODE_SCALE_ASPECT 3 - -/* Dithering mode options */ -#define DRM_MODE_DITHERING_OFF 0 -#define DRM_MODE_DITHERING_ON 1 - -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 connector_id_ptr; - uint64_t encoder_id_ptr; - int count_fbs; - int count_crtcs; - int count_connectors; - int count_encoders; - int min_width, max_width; - int min_height, max_height; -}; - -struct drm_mode_crtc { - uint64_t set_connectors_ptr; - int count_connectors; - - unsigned int crtc_id; /**< Id */ - unsigned int fb_id; /**< Id of framebuffer */ - - int x, y; /**< Position on the frameuffer */ - - uint32_t gamma_size; - int mode_valid; - struct drm_mode_modeinfo mode; -}; - -#define DRM_MODE_ENCODER_NONE 0 -#define DRM_MODE_ENCODER_DAC 1 -#define DRM_MODE_ENCODER_TMDS 2 -#define DRM_MODE_ENCODER_LVDS 3 -#define DRM_MODE_ENCODER_TVDAC 4 - -struct drm_mode_get_encoder { - - unsigned int encoder_type; - unsigned int encoder_id; - - unsigned int crtc_id; /**< Id of crtc */ - - uint32_t possible_crtcs; - uint32_t possible_clones; -}; - -/* This is for connectors with multiple signal types. */ -/* Try to match DRM_MODE_CONNECTOR_X as closely as possible. */ -#define DRM_MODE_SUBCONNECTOR_Automatic 0 -#define DRM_MODE_SUBCONNECTOR_Unknown 0 -#define DRM_MODE_SUBCONNECTOR_DVID 3 -#define DRM_MODE_SUBCONNECTOR_DVIA 4 -#define DRM_MODE_SUBCONNECTOR_Composite 5 -#define DRM_MODE_SUBCONNECTOR_SVIDEO 6 -#define DRM_MODE_SUBCONNECTOR_Component 8 - -#define DRM_MODE_CONNECTOR_Unknown 0 -#define DRM_MODE_CONNECTOR_VGA 1 -#define DRM_MODE_CONNECTOR_DVII 2 -#define DRM_MODE_CONNECTOR_DVID 3 -#define DRM_MODE_CONNECTOR_DVIA 4 -#define DRM_MODE_CONNECTOR_Composite 5 -#define DRM_MODE_CONNECTOR_SVIDEO 6 -#define DRM_MODE_CONNECTOR_LVDS 7 -#define DRM_MODE_CONNECTOR_Component 8 -#define DRM_MODE_CONNECTOR_9PinDIN 9 -#define DRM_MODE_CONNECTOR_DisplayPort 10 -#define DRM_MODE_CONNECTOR_HDMIA 11 -#define DRM_MODE_CONNECTOR_HDMIB 12 - -struct drm_mode_get_connector { - - uint64_t encoders_ptr; - uint64_t modes_ptr; - uint64_t props_ptr; - uint64_t prop_values_ptr; - - int count_modes; - int count_props; - int count_encoders; - - unsigned int encoder_id; /**< Current Encoder */ - unsigned int connector_id; /**< Id */ - unsigned int connector_type; - unsigned int connector_type_id; - - unsigned int connection; - unsigned int mm_width, mm_height; /**< HxW in millimeters */ - unsigned int subpixel; -}; - -#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_connector_set_property { - uint64_t value; - unsigned int prop_id; - unsigned int connector_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 connector_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; -}; - -struct drm_mode_crtc_lut { - - uint32_t crtc_id; - uint32_t gamma_size; - - uint64_t red; - uint64_t green; - uint64_t blue; -}; +#include "drm_mode.h" /** * \name Ioctls Definitions diff --git a/shared-core/drm_mode.h b/shared-core/drm_mode.h new file mode 100644 index 00000000..678dc230 --- /dev/null +++ b/shared-core/drm_mode.h @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2007 Dave Airlie + * Copyright (c) 2007 Jakob Bornecrantz + * Copyright (c) 2008 Red Hat Inc. + * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * Copyright (c) 2007-2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef _DRM_MODE_H +#define _DRM_MODE_H + +#if !defined(__KERNEL__) && !defined(_KERNEL) +#include +#else +#include +#endif + +#define DRM_DISPLAY_INFO_LEN 32 +#define DRM_CONNECTOR_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) + +/* Video mode flags */ +/* bit compatible with the xorg definitions. */ +#define DRM_MODE_FLAG_PHSYNC (1<<0) +#define DRM_MODE_FLAG_NHSYNC (1<<1) +#define DRM_MODE_FLAG_PVSYNC (1<<2) +#define DRM_MODE_FLAG_NVSYNC (1<<3) +#define DRM_MODE_FLAG_INTERLACE (1<<4) +#define DRM_MODE_FLAG_DBLSCAN (1<<5) +#define DRM_MODE_FLAG_CSYNC (1<<6) +#define DRM_MODE_FLAG_PCSYNC (1<<7) +#define DRM_MODE_FLAG_NCSYNC (1<<8) +#define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */ +#define DRM_MODE_FLAG_BCAST (1<<10) +#define DRM_MODE_FLAG_PIXMUX (1<<11) +#define DRM_MODE_FLAG_DBLCLK (1<<12) +#define DRM_MODE_FLAG_CLKDIV2 (1<<13) + +/* DPMS flags */ +/* bit compatible with the xorg definitions. */ +#define DRM_MODE_DPMS_ON 0 +#define DRM_MODE_DPMS_STANDBY 1 +#define DRM_MODE_DPMS_SUSPEND 2 +#define DRM_MODE_DPMS_OFF 3 + +/* Scaling mode options */ +#define DRM_MODE_SCALE_NON_GPU 0 +#define DRM_MODE_SCALE_FULLSCREEN 1 +#define DRM_MODE_SCALE_NO_SCALE 2 +#define DRM_MODE_SCALE_ASPECT 3 + +/* Dithering mode options */ +#define DRM_MODE_DITHERING_OFF 0 +#define DRM_MODE_DITHERING_ON 1 + +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 connector_id_ptr; + uint64_t encoder_id_ptr; + int count_fbs; + int count_crtcs; + int count_connectors; + int count_encoders; + int min_width, max_width; + int min_height, max_height; +}; + +struct drm_mode_crtc { + uint64_t set_connectors_ptr; + int count_connectors; + + unsigned int crtc_id; /**< Id */ + unsigned int fb_id; /**< Id of framebuffer */ + + int x, y; /**< Position on the frameuffer */ + + uint32_t gamma_size; + int mode_valid; + struct drm_mode_modeinfo mode; +}; + +#define DRM_MODE_ENCODER_NONE 0 +#define DRM_MODE_ENCODER_DAC 1 +#define DRM_MODE_ENCODER_TMDS 2 +#define DRM_MODE_ENCODER_LVDS 3 +#define DRM_MODE_ENCODER_TVDAC 4 + +struct drm_mode_get_encoder { + + unsigned int encoder_type; + unsigned int encoder_id; + + unsigned int crtc_id; /**< Id of crtc */ + + uint32_t possible_crtcs; + uint32_t possible_clones; +}; + +/* This is for connectors with multiple signal types. */ +/* Try to match DRM_MODE_CONNECTOR_X as closely as possible. */ +#define DRM_MODE_SUBCONNECTOR_Automatic 0 +#define DRM_MODE_SUBCONNECTOR_Unknown 0 +#define DRM_MODE_SUBCONNECTOR_DVID 3 +#define DRM_MODE_SUBCONNECTOR_DVIA 4 +#define DRM_MODE_SUBCONNECTOR_Composite 5 +#define DRM_MODE_SUBCONNECTOR_SVIDEO 6 +#define DRM_MODE_SUBCONNECTOR_Component 8 + +#define DRM_MODE_CONNECTOR_Unknown 0 +#define DRM_MODE_CONNECTOR_VGA 1 +#define DRM_MODE_CONNECTOR_DVII 2 +#define DRM_MODE_CONNECTOR_DVID 3 +#define DRM_MODE_CONNECTOR_DVIA 4 +#define DRM_MODE_CONNECTOR_Composite 5 +#define DRM_MODE_CONNECTOR_SVIDEO 6 +#define DRM_MODE_CONNECTOR_LVDS 7 +#define DRM_MODE_CONNECTOR_Component 8 +#define DRM_MODE_CONNECTOR_9PinDIN 9 +#define DRM_MODE_CONNECTOR_DisplayPort 10 +#define DRM_MODE_CONNECTOR_HDMIA 11 +#define DRM_MODE_CONNECTOR_HDMIB 12 + +struct drm_mode_get_connector { + + uint64_t encoders_ptr; + uint64_t modes_ptr; + uint64_t props_ptr; + uint64_t prop_values_ptr; + + int count_modes; + int count_props; + int count_encoders; + + unsigned int encoder_id; /**< Current Encoder */ + unsigned int connector_id; /**< Id */ + unsigned int connector_type; + unsigned int connector_type_id; + + unsigned int connection; + unsigned int mm_width, mm_height; /**< HxW in millimeters */ + unsigned int subpixel; +}; + +#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_connector_set_property { + uint64_t value; + unsigned int prop_id; + unsigned int connector_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 connector_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; +}; + +struct drm_mode_crtc_lut { + + uint32_t crtc_id; + uint32_t gamma_size; + + /* pointers to arrays */ + uint64_t red; + uint64_t green; + uint64_t blue; +}; + +#endif -- cgit v1.2.3 From 09b2dfcedc8cb35444567626131ccc25db79a8c6 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 26 Sep 2008 17:20:04 -0400 Subject: radeon: make atom on r4xx a module option default is legacy modesetting. pass module option r4xx_atom to try using atom on r4xx. --- shared-core/radeon_drv.h | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core') diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 25a07e30..3490ddbe 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -456,6 +456,7 @@ typedef struct drm_radeon_kcmd_buffer { extern int radeon_no_wb; extern int radeon_dynclks; +extern int radeon_r4xx_atom; extern struct drm_ioctl_desc radeon_ioctls[]; extern int radeon_max_ioctl; -- cgit v1.2.3 From d958cd7bb95558aa6c49824e2ae2b302f1433d2e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 16 Oct 2008 10:51:31 +1000 Subject: radeon: use discardable flags on no backing store objects --- shared-core/radeon_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 3490ddbe..c37f23d6 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -1672,7 +1672,7 @@ int radeon_gem_indirect_ioctl(struct drm_device *dev, void *data, int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); struct drm_gem_object *radeon_gem_object_alloc(struct drm_device *dev, int size, int alignment, - int initial_domain); + int initial_domain, bool discardable); int radeon_modeset_init(struct drm_device *dev); void radeon_modeset_cleanup(struct drm_device *dev); extern u32 radeon_read_mc_reg(drm_radeon_private_t *dev_priv, int addr); -- cgit v1.2.3 From 8d9a11c55cf3692bd537c68044b4378aba53f438 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 16 Oct 2008 10:57:31 +1000 Subject: radeon: add CS support for r100/r200 in 2D driver --- shared-core/r300_cmdbuf.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++ shared-core/radeon_cs.c | 5 ++++ 2 files changed, 69 insertions(+) (limited to 'shared-core') diff --git a/shared-core/r300_cmdbuf.c b/shared-core/r300_cmdbuf.c index 725829b2..b15e8928 100644 --- a/shared-core/r300_cmdbuf.c +++ b/shared-core/r300_cmdbuf.c @@ -35,6 +35,7 @@ #include "drm.h" #include "radeon_drm.h" #include "radeon_drv.h" +#include "radeon_reg.h" #include "r300_reg.h" #define R300_SIMULTANEOUS_CLIPRECTS 4 @@ -309,6 +310,69 @@ void r300_init_reg_flags(struct drm_device *dev) ADD_RANGE(RADEON_RE_WIDTH_HEIGHT, 1); ADD_RANGE(RADEON_AUX_SC_CNTL, 1); ADD_RANGE(RADEON_RB3D_DSTCACHE_CTLSTAT, 1); + ADD_RANGE(RADEON_RB3D_PLANEMASK, 1); + ADD_RANGE(RADEON_SE_CNTL, 1); + ADD_RANGE(RADEON_PP_CNTL, 1); + ADD_RANGE(RADEON_RB3D_CNTL, 1); + ADD_RANGE_MARK(RADEON_RB3D_COLOROFFSET, 1, MARK_CHECK_OFFSET); + ADD_RANGE(RADEON_RB3D_COLORPITCH, 1); + ADD_RANGE(RADEON_RB3D_BLENDCNTL, 1); + + if (dev_priv->chip_family >= CHIP_R200) { + ADD_RANGE(R200_PP_CNTL_X, 1); + ADD_RANGE(R200_PP_TXMULTI_CTL_0, 1); + ADD_RANGE(R200_SE_VTX_STATE_CNTL, 1); + ADD_RANGE(R200_RE_CNTL, 1); + ADD_RANGE(R200_SE_VTE_CNTL, 1); + ADD_RANGE(R200_SE_VAP_CNTL, 1); + + ADD_RANGE(R200_PP_TXFILTER_0, 1); + ADD_RANGE(R200_PP_TXFORMAT_0, 1); + ADD_RANGE(R200_PP_TXFORMAT_X_0, 1); + ADD_RANGE(R200_PP_TXSIZE_0, 1); + ADD_RANGE(R200_PP_TXPITCH_0, 1); + ADD_RANGE(R200_PP_TFACTOR_0, 1); + + ADD_RANGE(R200_PP_TXFILTER_1, 1); + ADD_RANGE(R200_PP_TXFORMAT_1, 1); + ADD_RANGE(R200_PP_TXFORMAT_X_1, 1); + ADD_RANGE(R200_PP_TXSIZE_1, 1); + ADD_RANGE(R200_PP_TXPITCH_1, 1); + ADD_RANGE(R200_PP_TFACTOR_1, 1); + + ADD_RANGE_MARK(R200_PP_TXOFFSET_0, 1, MARK_CHECK_OFFSET); + ADD_RANGE_MARK(R200_PP_TXOFFSET_1, 1, MARK_CHECK_OFFSET); + ADD_RANGE_MARK(R200_PP_TXOFFSET_2, 1, MARK_CHECK_OFFSET); + ADD_RANGE_MARK(R200_PP_TXOFFSET_3, 1, MARK_CHECK_OFFSET); + ADD_RANGE_MARK(R200_PP_TXOFFSET_4, 1, MARK_CHECK_OFFSET); + ADD_RANGE_MARK(R200_PP_TXOFFSET_5, 1, MARK_CHECK_OFFSET); + + ADD_RANGE(R200_SE_VTX_FMT_0, 1); + ADD_RANGE(R200_SE_VTX_FMT_1, 1); + ADD_RANGE(R200_PP_TXCBLEND_0, 1); + ADD_RANGE(R200_PP_TXCBLEND2_0, 1); + ADD_RANGE(R200_PP_TXABLEND_0, 1); + ADD_RANGE(R200_PP_TXABLEND2_0, 1); + + } else { + + ADD_RANGE(RADEON_PP_TXFILTER_0, 1); + ADD_RANGE(RADEON_PP_TXFORMAT_0, 1); + ADD_RANGE(RADEON_PP_TEX_SIZE_0, 1); + ADD_RANGE(RADEON_PP_TEX_PITCH_0, 1); + + ADD_RANGE(RADEON_PP_TXFILTER_1, 1); + ADD_RANGE(RADEON_PP_TXFORMAT_1, 1); + ADD_RANGE(RADEON_PP_TEX_SIZE_1, 1); + ADD_RANGE(RADEON_PP_TEX_PITCH_1, 1); + + ADD_RANGE(RADEON_PP_TXCBLEND_0, 1); + ADD_RANGE(RADEON_PP_TXABLEND_0, 1); + ADD_RANGE(RADEON_SE_VTX_FMT, 1); + ADD_RANGE_MARK(RADEON_PP_TXOFFSET_0, 1, MARK_CHECK_OFFSET); + ADD_RANGE_MARK(RADEON_PP_TXOFFSET_1, 1, MARK_CHECK_OFFSET); + ADD_RANGE_MARK(RADEON_PP_TXOFFSET_2, 1, MARK_CHECK_OFFSET); + } } } diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index a00ec21b..f9147136 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -139,10 +139,15 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct offset >>= 10; val |= offset; break; + case RADEON_RB3D_COLOROFFSET: case R300_RB3D_COLOROFFSET0: case R300_ZB_DEPTHOFFSET: case R300_TX_OFFSET_0: case R300_TX_OFFSET_0+4: + case R200_PP_TXOFFSET_0: + case R200_PP_TXOFFSET_1: + case RADEON_PP_TXOFFSET_0: + case RADEON_PP_TXOFFSET_1: ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + 2, &offset); if (ret) return ret; -- cgit v1.2.3 From 26076bf24a4e720e389d0a3ea616a8350397fdfc Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 16 Oct 2008 10:59:31 +1000 Subject: radeon: add initial agp support. This add agpmode command line option. --- shared-core/radeon_cp.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++- shared-core/radeon_drv.h | 1 + 2 files changed, 102 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 9825d709..190b1432 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2334,7 +2334,6 @@ int radeon_modeset_cp_suspend(struct drm_device *dev) int radeon_modeset_cp_resume(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; - uint32_t tmp; radeon_do_wait_for_idle(dev_priv); #if __OS_HAS_AGP @@ -2358,6 +2357,95 @@ int radeon_modeset_cp_resume(struct drm_device *dev) return 0; } +#if __OS_HAS_AGP +int radeon_modeset_agp_init(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_agp_mode mode; + struct drm_agp_info info; + int ret; + int default_mode; + uint32_t agp_status; + bool is_v3; + + /* Acquire AGP. */ + ret = drm_agp_acquire(dev); + if (ret) { + DRM_ERROR("Unable to acquire AGP: %d\n", ret); + return ret; + } + + ret = drm_agp_info(dev, &info); + if (ret) { + DRM_ERROR("Unable to get AGP info: %d\n", ret); + return ret; + } + + mode.mode = info.mode; + + agp_status = (RADEON_READ(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode; + is_v3 = !!(agp_status & RADEON_AGPv3_MODE); + + if (is_v3) { + default_mode = (agp_status & RADEON_AGPv3_8X_MODE) ? 8 : 4; + } else { + if (agp_status & RADEON_AGP_4X_MODE) default_mode = 4; + else if (agp_status & RADEON_AGP_2X_MODE) default_mode = 2; + else default_mode = 1; + } + + if (radeon_agpmode > 0) { + if ((radeon_agpmode < (is_v3 ? 4 : 1)) || + (radeon_agpmode > (is_v3 ? 8 : 4)) || + (radeon_agpmode & (radeon_agpmode - 1))) { + DRM_ERROR("Illegal AGP Mode: %d (valid %s), leaving at %d\n", + radeon_agpmode, is_v3 ? "4, 8" : "1, 2, 4", + default_mode); + radeon_agpmode = default_mode; + } + else + DRM_INFO("AGP mode requested: %d\n", radeon_agpmode); + } else + radeon_agpmode = default_mode; + + mode.mode &= ~RADEON_AGP_MODE_MASK; + if (is_v3) { + switch(radeon_agpmode) { + case 8: + mode.mode |= RADEON_AGPv3_8X_MODE; + break; + case 4: + default: + mode.mode |= RADEON_AGPv3_4X_MODE; + break; + } + } else { + switch(radeon_agpmode) { + case 4: mode.mode |= RADEON_AGP_4X_MODE; + case 2: mode.mode |= RADEON_AGP_2X_MODE; + case 1: + default: + mode.mode |= RADEON_AGP_1X_MODE; + break; + } + } + + mode.mode &= ~RADEON_AGP_FW_MODE; /* disable fw */ + + ret = drm_agp_enable(dev, mode); + if (ret) { + DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode); + return ret; + } + + /* workaround some hw issues */ + if (dev_priv->chip_family <= CHIP_R200) { + RADEON_WRITE(RADEON_AGP_CNTL, RADEON_READ(RADEON_AGP_CNTL) | 0x000e0000); + } + return 0; +} +#endif + int radeon_modeset_cp_init(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -2389,6 +2477,11 @@ int radeon_modeset_cp_init(struct drm_device *dev) dev_priv->new_memmap = true; r300_init_reg_flags(dev); + +#if __OS_HAS_AGP + if (dev_priv->flags & RADEON_IS_AGP) + radeon_modeset_agp_init(dev); +#endif return radeon_modeset_cp_resume(dev); } @@ -2478,6 +2571,7 @@ int radeon_static_clocks_init(struct drm_device *dev) } } radeon_force_some_clocks(dev); + return 0; } int radeon_driver_load(struct drm_device *dev, unsigned long flags) @@ -2523,6 +2617,12 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) DRM_DEBUG("%s card detected\n", ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); + if ((dev_priv->flags & RADEON_IS_AGP) && (radeon_agpmode == -1)) { + DRM_INFO("Forcing AGP to PCI mode\n"); + dev_priv->flags &= ~RADEON_IS_AGP; + } + + ret = drm_addmap(dev, drm_get_resource_start(dev, 2), drm_get_resource_len(dev, 2), _DRM_REGISTERS, _DRM_DRIVER | _DRM_READ_ONLY, &dev_priv->mmio); diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index c37f23d6..a6ce129d 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -459,6 +459,7 @@ extern int radeon_dynclks; extern int radeon_r4xx_atom; extern struct drm_ioctl_desc radeon_ioctls[]; extern int radeon_max_ioctl; +extern int radeon_agpmode; /* Check whether the given hardware address is inside the framebuffer or the * GART area. -- cgit v1.2.3 From 0796bf8c6b983de7fbb188bd5d84d4ea54f81525 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 24 Oct 2008 18:23:39 +0200 Subject: mode: Indent defines --- shared-core/drm_mode.h | 94 +++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 47 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm_mode.h b/shared-core/drm_mode.h index 678dc230..01e6c7e7 100644 --- a/shared-core/drm_mode.h +++ b/shared-core/drm_mode.h @@ -33,10 +33,10 @@ #include #endif -#define DRM_DISPLAY_INFO_LEN 32 -#define DRM_CONNECTOR_NAME_LEN 32 -#define DRM_DISPLAY_MODE_LEN 32 -#define DRM_PROP_NAME_LEN 32 +#define DRM_DISPLAY_INFO_LEN 32 +#define DRM_CONNECTOR_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) @@ -65,20 +65,20 @@ /* DPMS flags */ /* bit compatible with the xorg definitions. */ -#define DRM_MODE_DPMS_ON 0 -#define DRM_MODE_DPMS_STANDBY 1 -#define DRM_MODE_DPMS_SUSPEND 2 -#define DRM_MODE_DPMS_OFF 3 +#define DRM_MODE_DPMS_ON 0 +#define DRM_MODE_DPMS_STANDBY 1 +#define DRM_MODE_DPMS_SUSPEND 2 +#define DRM_MODE_DPMS_OFF 3 /* Scaling mode options */ -#define DRM_MODE_SCALE_NON_GPU 0 -#define DRM_MODE_SCALE_FULLSCREEN 1 -#define DRM_MODE_SCALE_NO_SCALE 2 -#define DRM_MODE_SCALE_ASPECT 3 +#define DRM_MODE_SCALE_NON_GPU 0 +#define DRM_MODE_SCALE_FULLSCREEN 1 +#define DRM_MODE_SCALE_NO_SCALE 2 +#define DRM_MODE_SCALE_ASPECT 3 /* Dithering mode options */ -#define DRM_MODE_DITHERING_OFF 0 -#define DRM_MODE_DITHERING_ON 1 +#define DRM_MODE_DITHERING_OFF 0 +#define DRM_MODE_DITHERING_ON 1 struct drm_mode_modeinfo { unsigned int clock; @@ -119,11 +119,11 @@ struct drm_mode_crtc { struct drm_mode_modeinfo mode; }; -#define DRM_MODE_ENCODER_NONE 0 -#define DRM_MODE_ENCODER_DAC 1 -#define DRM_MODE_ENCODER_TMDS 2 -#define DRM_MODE_ENCODER_LVDS 3 -#define DRM_MODE_ENCODER_TVDAC 4 +#define DRM_MODE_ENCODER_NONE 0 +#define DRM_MODE_ENCODER_DAC 1 +#define DRM_MODE_ENCODER_TMDS 2 +#define DRM_MODE_ENCODER_LVDS 3 +#define DRM_MODE_ENCODER_TVDAC 4 struct drm_mode_get_encoder { @@ -138,27 +138,27 @@ struct drm_mode_get_encoder { /* This is for connectors with multiple signal types. */ /* Try to match DRM_MODE_CONNECTOR_X as closely as possible. */ -#define DRM_MODE_SUBCONNECTOR_Automatic 0 -#define DRM_MODE_SUBCONNECTOR_Unknown 0 -#define DRM_MODE_SUBCONNECTOR_DVID 3 -#define DRM_MODE_SUBCONNECTOR_DVIA 4 -#define DRM_MODE_SUBCONNECTOR_Composite 5 -#define DRM_MODE_SUBCONNECTOR_SVIDEO 6 -#define DRM_MODE_SUBCONNECTOR_Component 8 - -#define DRM_MODE_CONNECTOR_Unknown 0 -#define DRM_MODE_CONNECTOR_VGA 1 -#define DRM_MODE_CONNECTOR_DVII 2 -#define DRM_MODE_CONNECTOR_DVID 3 -#define DRM_MODE_CONNECTOR_DVIA 4 -#define DRM_MODE_CONNECTOR_Composite 5 -#define DRM_MODE_CONNECTOR_SVIDEO 6 -#define DRM_MODE_CONNECTOR_LVDS 7 -#define DRM_MODE_CONNECTOR_Component 8 -#define DRM_MODE_CONNECTOR_9PinDIN 9 -#define DRM_MODE_CONNECTOR_DisplayPort 10 -#define DRM_MODE_CONNECTOR_HDMIA 11 -#define DRM_MODE_CONNECTOR_HDMIB 12 +#define DRM_MODE_SUBCONNECTOR_Automatic 0 +#define DRM_MODE_SUBCONNECTOR_Unknown 0 +#define DRM_MODE_SUBCONNECTOR_DVID 3 +#define DRM_MODE_SUBCONNECTOR_DVIA 4 +#define DRM_MODE_SUBCONNECTOR_Composite 5 +#define DRM_MODE_SUBCONNECTOR_SVIDEO 6 +#define DRM_MODE_SUBCONNECTOR_Component 8 + +#define DRM_MODE_CONNECTOR_Unknown 0 +#define DRM_MODE_CONNECTOR_VGA 1 +#define DRM_MODE_CONNECTOR_DVII 2 +#define DRM_MODE_CONNECTOR_DVID 3 +#define DRM_MODE_CONNECTOR_DVIA 4 +#define DRM_MODE_CONNECTOR_Composite 5 +#define DRM_MODE_CONNECTOR_SVIDEO 6 +#define DRM_MODE_CONNECTOR_LVDS 7 +#define DRM_MODE_CONNECTOR_Component 8 +#define DRM_MODE_CONNECTOR_9PinDIN 9 +#define DRM_MODE_CONNECTOR_DisplayPort 10 +#define DRM_MODE_CONNECTOR_HDMIA 11 +#define DRM_MODE_CONNECTOR_HDMIB 12 struct drm_mode_get_connector { @@ -181,11 +181,11 @@ struct drm_mode_get_connector { unsigned int subpixel; }; -#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) +#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; @@ -230,8 +230,8 @@ struct drm_mode_mode_cmd { struct drm_mode_modeinfo mode; }; -#define DRM_MODE_CURSOR_BO 0x01 -#define DRM_MODE_CURSOR_MOVE 0x02 +#define DRM_MODE_CURSOR_BO (1<<0) +#define DRM_MODE_CURSOR_MOVE (1<<1) /* * depending on the value in flags diffrent members are used. -- cgit v1.2.3 From 34a3ebffc369575412a4ff2c05c50264e83c6d3e Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 24 Oct 2008 18:43:55 +0200 Subject: mode: Try to settle on a standard for struct fields --- shared-core/drm_mode.h | 78 +++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 39 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm_mode.h b/shared-core/drm_mode.h index 01e6c7e7..e6daa7ca 100644 --- a/shared-core/drm_mode.h +++ b/shared-core/drm_mode.h @@ -81,14 +81,14 @@ #define DRM_MODE_DITHERING_ON 1 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; + uint32_t clock; + uint16_t hdisplay, hsync_start, hsync_end, htotal, hskew; + uint16_t vdisplay, vsync_start, vsync_end, vtotal, vscan; - unsigned int vrefresh; /* vertical refresh * 1000 */ + uint32_t vrefresh; /* vertical refresh * 1000 */ - unsigned int flags; - unsigned int type; + uint32_t flags; + uint32_t type; char name[DRM_DISPLAY_MODE_LEN]; }; @@ -97,25 +97,25 @@ struct drm_mode_card_res { uint64_t crtc_id_ptr; uint64_t connector_id_ptr; uint64_t encoder_id_ptr; - int count_fbs; - int count_crtcs; - int count_connectors; - int count_encoders; - int min_width, max_width; - int min_height, max_height; + uint32_t count_fbs; + uint32_t count_crtcs; + uint32_t count_connectors; + uint32_t count_encoders; + uint32_t min_width, max_width; + uint32_t min_height, max_height; }; struct drm_mode_crtc { uint64_t set_connectors_ptr; - int count_connectors; + uint32_t count_connectors; unsigned int crtc_id; /**< Id */ unsigned int fb_id; /**< Id of framebuffer */ - int x, y; /**< Position on the frameuffer */ + uint32_t x, y; /**< Position on the frameuffer */ uint32_t gamma_size; - int mode_valid; + uint32_t mode_valid; struct drm_mode_modeinfo mode; }; @@ -126,12 +126,11 @@ struct drm_mode_crtc { #define DRM_MODE_ENCODER_TVDAC 4 struct drm_mode_get_encoder { - - unsigned int encoder_type; unsigned int encoder_id; - unsigned int crtc_id; /**< Id of crtc */ + uint32_t encoder_type; + uint32_t possible_crtcs; uint32_t possible_clones; }; @@ -167,18 +166,18 @@ struct drm_mode_get_connector { uint64_t props_ptr; uint64_t prop_values_ptr; - int count_modes; - int count_props; - int count_encoders; + uint32_t count_modes; + uint32_t count_props; + uint32_t count_encoders; unsigned int encoder_id; /**< Current Encoder */ unsigned int connector_id; /**< Id */ unsigned int connector_type; unsigned int connector_type_id; - unsigned int connection; - unsigned int mm_width, mm_height; /**< HxW in millimeters */ - unsigned int subpixel; + uint32_t connection; + uint32_t mm_width, mm_height; /**< HxW in millimeters */ + uint32_t subpixel; }; #define DRM_MODE_PROP_PENDING (1<<0) @@ -197,11 +196,11 @@ struct drm_mode_get_property { uint64_t enum_blob_ptr; /* enum and blob id ptrs */ unsigned int prop_id; - unsigned int flags; + uint32_t flags; unsigned char name[DRM_PROP_NAME_LEN]; - int count_values; - int count_enum_blobs; + uint32_t count_values; + uint32_t count_enum_blobs; }; struct drm_mode_connector_set_property { @@ -218,11 +217,12 @@ struct drm_mode_get_blob { 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; + uint32_t width, height; + uint32_t pitch; + uint32_t bpp; + uint32_t depth; + + uint64_t handle; }; struct drm_mode_mode_cmd { @@ -248,13 +248,14 @@ struct drm_mode_mode_cmd { * y */ struct drm_mode_cursor { - unsigned int flags; - unsigned int crtc; - int x; - int y; + uint32_t flags; + unsigned int crtc_id; + int32_t x; + int32_t y; uint32_t width; uint32_t height; - unsigned int handle; + /* driver specific handle */ + uint64_t handle; }; /* @@ -265,8 +266,7 @@ struct drm_mode_hotplug { }; struct drm_mode_crtc_lut { - - uint32_t crtc_id; + unsigned int crtc_id; uint32_t gamma_size; /* pointers to arrays */ -- cgit v1.2.3 From 389b7617b5b88b6270af5b3824fe73519900c87f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 27 Oct 2008 17:06:23 +1000 Subject: drm: make handles 32-bits again not sure why they changed --- shared-core/drm_mode.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm_mode.h b/shared-core/drm_mode.h index e6daa7ca..0c378f44 100644 --- a/shared-core/drm_mode.h +++ b/shared-core/drm_mode.h @@ -220,9 +220,9 @@ struct drm_mode_fb_cmd { uint32_t width, height; uint32_t pitch; uint32_t bpp; + uint32_t handle; uint32_t depth; - uint64_t handle; }; struct drm_mode_mode_cmd { @@ -255,7 +255,7 @@ struct drm_mode_cursor { uint32_t width; uint32_t height; /* driver specific handle */ - uint64_t handle; + uint32_t handle; }; /* -- cgit v1.2.3 From 1db35ba58353b862ca04a190d46c6f074a21f223 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 29 Oct 2008 12:17:39 -0700 Subject: libdrm: fix ABI change in drm_mode_get_encoder The encoder_type field should be at the top to match the kernel. --- shared-core/drm_mode.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm_mode.h b/shared-core/drm_mode.h index 0c378f44..bd3d257e 100644 --- a/shared-core/drm_mode.h +++ b/shared-core/drm_mode.h @@ -126,10 +126,10 @@ struct drm_mode_crtc { #define DRM_MODE_ENCODER_TVDAC 4 struct drm_mode_get_encoder { + unsigned int encoder_type; unsigned int encoder_id; - unsigned int crtc_id; /**< Id of crtc */ - uint32_t encoder_type; + unsigned int crtc_id; /**< Id of crtc */ uint32_t possible_crtcs; uint32_t possible_clones; -- cgit v1.2.3 From b09cb93e2d188228e26135149786ee231cd9b11d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:23:19 +1000 Subject: radeon: add some more r100 support to test AGP --- shared-core/r300_cmdbuf.c | 3 +++ shared-core/radeon_cs.c | 27 ++------------------------- 2 files changed, 5 insertions(+), 25 deletions(-) (limited to 'shared-core') diff --git a/shared-core/r300_cmdbuf.c b/shared-core/r300_cmdbuf.c index b15e8928..f39a7afd 100644 --- a/shared-core/r300_cmdbuf.c +++ b/shared-core/r300_cmdbuf.c @@ -356,6 +356,9 @@ void r300_init_reg_flags(struct drm_device *dev) } else { + ADD_RANGE(RADEON_SE_COORD_FMT, 1); + ADD_RANGE(RADEON_SE_CNTL_STATUS, 1); + ADD_RANGE(RADEON_PP_TXFILTER_0, 1); ADD_RANGE(RADEON_PP_TXFORMAT_0, 1); ADD_RANGE(RADEON_PP_TEX_SIZE_0, 1); diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index f9147136..3e47ad12 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -122,7 +122,7 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct /* this is too strict we may want to expand the length in the future and have old kernels ignore it. */ if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16))) { - DRM_ERROR("Packet 3 was %x should have been %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16)); + DRM_ERROR("Packet 3 was %x should have been %x: reg is %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16), reg); return -EINVAL; } @@ -195,30 +195,6 @@ static int radeon_cs_relocate_packet3(struct drm_device *dev, struct drm_file *f return 0; } -static __inline__ int radeon_cs_check_offset(struct drm_device *dev, - uint32_t reg, uint32_t val) -{ - uint32_t offset; - - switch(reg) { - case RADEON_DST_PITCH_OFFSET: - case RADEON_SRC_PITCH_OFFSET: - offset = val & ((1 << 22) - 1); - offset <<= 10; - break; - case R300_RB3D_COLOROFFSET0: - case R300_ZB_DEPTHOFFSET: - offset = val; - break; - case R300_TX_OFFSET_0: - case R300_TX_OFFSET_0+4: - offset = val & 0xffffffe0; - break; - } - - return 0; -} - int radeon_cs_packet0(struct drm_device *dev, struct drm_file *file_priv, uint32_t *packets, uint32_t offset_dw) { @@ -308,6 +284,7 @@ int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv, DRM_ERROR("need relocate packet 3 for %x\n", reg); break; + case RADEON_3D_DRAW_IMMD: /* triggers drawing using in-packet vertex data */ case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */ case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */ case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */ -- cgit v1.2.3 From f74721fc2553d81acfe4d4a670833405dd52092b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:24:13 +1000 Subject: radeon: fix unused agp functionality --- shared-core/radeon_cp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 190b1432..d5889e61 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -120,7 +120,7 @@ void radeon_read_agp_location(drm_radeon_private_t *dev_priv, u32 *agp_lo, u32 * *agp_lo = RADEON_READ(R600_MC_VM_AGP_BOT); *agp_hi = RADEON_READ(R600_MC_VM_AGP_TOP); } else if (dev_priv->chip_family == CHIP_RV515) { - *agp_lo = radeon_read_mc_reg(dev_priv, RV515_MC_FB_LOCATION); + *agp_lo = radeon_read_mc_reg(dev_priv, RV515_MC_AGP_LOCATION); *agp_hi = 0; } else if (dev_priv->chip_family == CHIP_RS600) { *agp_lo = 0; @@ -133,7 +133,7 @@ void radeon_read_agp_location(drm_radeon_private_t *dev_priv, u32 *agp_lo, u32 * *agp_lo = radeon_read_mc_reg(dev_priv, R520_MC_AGP_LOCATION); *agp_hi = 0; } else { - *agp_lo = RADEON_READ(RADEON_MC_FB_LOCATION); + *agp_lo = RADEON_READ(RADEON_MC_AGP_LOCATION); *agp_hi = 0; } } -- cgit v1.2.3 From 48f222751643a349924ba3e6c26890310822f89c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:25:32 +1000 Subject: radeon: export radeon_modeset --- shared-core/radeon_drv.h | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core') diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index a6ce129d..3be99eb3 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -460,6 +460,7 @@ extern int radeon_r4xx_atom; extern struct drm_ioctl_desc radeon_ioctls[]; extern int radeon_max_ioctl; extern int radeon_agpmode; +extern int radeon_modeset; /* Check whether the given hardware address is inside the framebuffer or the * GART area. -- cgit v1.2.3 From d275f99c9a7d915473034e6abd575f35bea5db9c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:26:00 +1000 Subject: radeon: don't enable dynclks on rs48x --- shared-core/radeon_cp.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index d5889e61..ded6f676 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2562,6 +2562,10 @@ int radeon_static_clocks_init(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; + if (dev_priv->chip_family == CHIP_RS400 || + dev_priv->chip_family == CHIP_RS480) + radeon_dynclks = 0; + if ((dev_priv->flags & RADEON_IS_MOBILITY) && !radeon_is_avivo(dev_priv)) { radeon_set_dynamic_clock(dev, radeon_dynclks); } else if (radeon_is_avivo(dev_priv)) { -- cgit v1.2.3 From 52ef9d87db8d3b7e0e9114f987263292e8e12d6a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:27:00 +1000 Subject: radeon: fix small typo in agp code --- shared-core/radeon_cp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index ded6f676..ae3a69b6 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2439,7 +2439,7 @@ int radeon_modeset_agp_init(struct drm_device *dev) } /* workaround some hw issues */ - if (dev_priv->chip_family <= CHIP_R200) { + if (dev_priv->chip_family < CHIP_R200) { RADEON_WRITE(RADEON_AGP_CNTL, RADEON_READ(RADEON_AGP_CNTL) | 0x000e0000); } return 0; -- cgit v1.2.3 From 0dbe3436ee6e3f2a4d6d252ef5e31b7bb7e36764 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:28:36 +1000 Subject: radeon: fix some warnings --- shared-core/r300_reg.h | 2 +- shared-core/radeon_cp.c | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'shared-core') diff --git a/shared-core/r300_reg.h b/shared-core/r300_reg.h index 9e9cb526..1e4631db 100644 --- a/shared-core/r300_reg.h +++ b/shared-core/r300_reg.h @@ -1353,7 +1353,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */ #define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */ -#define R300_RB3D_AARESOLVE_CTL 0x4E88 +//#define R300_RB3D_AARESOLVE_CTL 0x4E88 /* gap */ /* Guess by Vladimir. diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index ae3a69b6..f579e01a 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2434,7 +2434,7 @@ int radeon_modeset_agp_init(struct drm_device *dev) ret = drm_agp_enable(dev, mode); if (ret) { - DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode); + DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode); return ret; } @@ -2457,7 +2457,7 @@ int radeon_modeset_cp_init(struct drm_device *dev) dev_priv->writeback_works = 0; if (dev_priv->chip_family > CHIP_R600) - return; + return 0; dev_priv->usec_timeout = RADEON_DEFAULT_CP_TIMEOUT; dev_priv->ring.size = RADEON_DEFAULT_RING_SIZE; @@ -2713,7 +2713,6 @@ int radeon_master_create(struct drm_device *dev, struct drm_master *master) void radeon_master_destroy(struct drm_device *dev, struct drm_master *master) { struct drm_radeon_master_private *master_priv = master->driver_priv; - struct drm_radeon_private *dev_priv = dev->dev_private; if (!master_priv) return; @@ -2735,8 +2734,6 @@ void radeon_master_destroy(struct drm_device *dev, struct drm_master *master) */ int radeon_driver_firstopen(struct drm_device *dev) { - int ret; - drm_local_map_t *map; drm_radeon_private_t *dev_priv = dev->dev_private; dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; -- cgit v1.2.3 From a066a5f908af0e82b1a0c7099b73d4a63585c69d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:28:56 +1000 Subject: radeon: make writeback work again --- shared-core/radeon_cp.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index f579e01a..0200797a 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -825,7 +825,7 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, static void radeon_test_writeback(drm_radeon_private_t * dev_priv) { - u32 tmp; + u32 tmp, scratch1_store; void *ring_read_ptr; if (dev_priv->mm.ring_read.bo) @@ -833,6 +833,7 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv) else ring_read_ptr = dev_priv->ring_rptr->handle; + scratch1_store = RADEON_READ(RADEON_SCRATCH_REG1); /* Writeback doesn't seem to work everywhere, test it here and possibly * enable it if it appears to work */ @@ -858,6 +859,9 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv) DRM_INFO("writeback forced off\n"); } + /* write back previous value */ + RADEON_WRITE(RADEON_SCRATCH_REG1, scratch1_store); + if (!dev_priv->writeback_works) { /* Disable writeback to avoid unnecessary bus master transfers */ RADEON_WRITE(RADEON_CP_RB_CNTL, RADEON_READ(RADEON_CP_RB_CNTL) | RADEON_RB_NO_UPDATE); @@ -2353,6 +2357,8 @@ int radeon_modeset_cp_resume(struct drm_device *dev) radeon_do_engine_reset(dev); + radeon_test_writeback(dev_priv); + radeon_do_cp_start(dev_priv); return 0; } -- cgit v1.2.3 From 3fd0e1483ebe640b69da888e286ea85d11539b46 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:29:22 +1000 Subject: radeon: fixup scratch register interactions properly --- shared-core/radeon_cp.c | 14 +++++++++++++- shared-core/radeon_cs.c | 4 ++-- shared-core/radeon_drv.h | 12 ++++++------ 3 files changed, 21 insertions(+), 9 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 0200797a..71d1a61b 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -791,7 +791,10 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, dev_priv->ring_rptr->handle + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); - RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); + if (dev_priv->chip_family > CHIP_R300) + RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x3f); + else + RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x1f); /* Turn on bus mastering */ tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; @@ -806,6 +809,15 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, dev_priv->scratch[2] = 0; RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); + dev_priv->scratch[3] = 0; + RADEON_WRITE(RADEON_LAST_SWI_REG, 0); + + dev_priv->scratch[4] = 0; + RADEON_WRITE(RADEON_SCRATCH_REG4, 0); + + dev_priv->scratch[6] = 0; + RADEON_WRITE(RADEON_SCRATCH_REG6, 0); + radeon_do_wait_for_idle(dev_priv); /* Sync everything up */ diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index 3e47ad12..b5982894 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -365,14 +365,14 @@ uint32_t r100_cs_id_last_get(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; - return RADEON_READ(RADEON_SCRATCH_REG4); + return GET_SCRATCH(4); } uint32_t r300_cs_id_last_get(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; - return RADEON_READ(RADEON_SCRATCH_REG6); + return GET_SCRATCH(6); } int radeon_cs_init(struct drm_device *dev) diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 3be99eb3..2d592e45 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -733,11 +733,11 @@ int radeon_resume(struct drm_device *dev); #define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x)) -#define GET_SCRATCH( x ) (dev_priv->writeback_works ? \ - (dev_priv->mm.ring_read.bo ? \ - readl(dev_priv->mm.ring_read.kmap.virtual + RADEON_SCRATCHOFF(x)) : \ - DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(x))) : \ - RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x))) +#define GET_SCRATCH( x ) (dev_priv->writeback_works ? \ + (dev_priv->mm.ring_read.bo ? \ + readl(dev_priv->mm.ring_read.kmap.virtual + RADEON_SCRATCHOFF(x)) : \ + DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(x))) : \ + RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x))) #define RADEON_CRTC_CRNT_FRAME 0x0214 #define RADEON_CRTC2_CRNT_FRAME 0x0314 @@ -1607,7 +1607,7 @@ extern uint64_t radeon_evict_flags(struct drm_buffer_object *bo); #define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1) /* Breadcrumb - swi irq */ -#define READ_BREADCRUMB(dev_priv) RADEON_READ(RADEON_LAST_SWI_REG) +#define READ_BREADCRUMB(dev_priv) GET_SCRATCH(3) static inline int radeon_update_breadcrumb(struct drm_device *dev) { -- cgit v1.2.3 From b4803991c8ad8596786f8cf1cffc6417c8ce446a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:30:48 +1000 Subject: radeon: update proper chip family --- shared-core/radeon_cp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 71d1a61b..4f5c538c 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -791,8 +791,8 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, dev_priv->ring_rptr->handle + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); - if (dev_priv->chip_family > CHIP_R300) - RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x3f); + if (dev_priv->chip_family >= CHIP_R300) + RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7f); else RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x1f); -- cgit v1.2.3 From 1c817cc3fc09abe93539413130de3875e4c7eafe Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:32:39 +1000 Subject: radeon: pull bus master enable into its own function --- shared-core/radeon_cp.c | 22 ++++++++++++++++++---- shared-core/radeon_drv.h | 2 +- 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 4f5c538c..b6207c7d 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -194,6 +194,23 @@ static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) } } +void radeon_enable_bm(struct drm_radeon_private *dev_priv) +{ + u32 tmp; + /* Turn on bus mastering */ + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { + /* rs400, rs690/rs740 */ + tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS400_BUS_MASTER_DIS; + RADEON_WRITE(RADEON_BUS_CNTL, tmp); + } else if (!(((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV380) || + ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R423))) { + /* r1xx, r2xx, r300, r(v)350, r420/r481, rs480 */ + tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; + RADEON_WRITE(RADEON_BUS_CNTL, tmp); + } /* PCIE cards appears to not need this */ +} void radeon_pll_errata_after_index(struct drm_radeon_private *dev_priv) { @@ -686,7 +703,6 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, drm_radeon_private_t * dev_priv) { u32 ring_start, cur_read_ptr; - u32 tmp; /* Initialize the memory controller. With new memory map, the fb location * is not changed, it should have been properly initialized already. Part @@ -796,9 +812,7 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, else RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x1f); - /* Turn on bus mastering */ - tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; - RADEON_WRITE(RADEON_BUS_CNTL, tmp); + radeon_enable_bm(dev_priv); dev_priv->scratch[0] = 0; RADEON_WRITE(RADEON_LAST_FRAME_REG, 0); diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 2d592e45..0d5f762b 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -1691,7 +1691,7 @@ extern int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file * extern int radeon_cs_init(struct drm_device *dev); void radeon_gem_update_offsets(struct drm_device *dev, struct drm_master *master); void radeon_init_memory_map(struct drm_device *dev); - +void radeon_enable_bm(struct drm_radeon_private *dev_priv); #define MARK_SAFE 1 #define MARK_CHECK_OFFSET 2 -- cgit v1.2.3 From 624da91277ee33936ea3cfaf20e7f6775293deb2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:33:12 +1000 Subject: radeon: add r423 bits to modesetting --- shared-core/radeon_drv.h | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core') diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 0d5f762b..17c0c297 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -1644,6 +1644,7 @@ static inline int radeon_update_breadcrumb(struct drm_device *dev) (dev_priv->chip_family == CHIP_R350) || \ (dev_priv->chip_family == CHIP_RV380) || \ (dev_priv->chip_family == CHIP_R420) || \ + (dev_priv->chip_family == CHIP_R423) || \ (dev_priv->chip_family == CHIP_RV410) || \ (dev_priv->chip_family == CHIP_RS400) || \ (dev_priv->chip_family == CHIP_RS480)) -- cgit v1.2.3 From fd9e05b3f4f464ddf08097817a3af824f54a97ca Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:33:32 +1000 Subject: radeon: release agp on module unload --- shared-core/radeon_cp.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index b6207c7d..8e97f034 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2476,6 +2476,12 @@ int radeon_modeset_agp_init(struct drm_device *dev) } return 0; } + +void radeon_modeset_agp_destroy(struct drm_device *dev) +{ + if (dev->agp->acquired) + drm_agp_release(dev); +} #endif int radeon_modeset_cp_init(struct drm_device *dev) @@ -2790,6 +2796,10 @@ int radeon_driver_unload(struct drm_device *dev) drm_irq_uninstall(dev); radeon_modeset_cleanup(dev); radeon_gem_mm_fini(dev); +#if __OS_HAS_AGP + if (dev_priv->flags & RADEON_IS_AGP) + radeon_modeset_agp_destroy(dev); +#endif } drm_bo_driver_finish(dev); -- cgit v1.2.3 From 8b2925468d326ab6fa31a312e845a3bc71343106 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:39:53 +1000 Subject: radeon: make new CS2 command submission interface port older interface to this --- shared-core/radeon_cs.c | 257 ++++++++++++++++++++++++++++++++++++++------- shared-core/radeon_drm.h | 19 +++- shared-core/radeon_drv.h | 31 ++++-- shared-core/radeon_state.c | 1 + 4 files changed, 261 insertions(+), 47 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index b5982894..452f04b4 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -29,16 +29,163 @@ #include "radeon_drv.h" #include "r300_reg.h" +int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) +{ + struct drm_radeon_cs_parser parser; + struct drm_radeon_private *dev_priv = dev->dev_private; + struct drm_radeon_cs2 *cs = data; + uint32_t cs_id; + struct drm_radeon_cs_chunk __user **chunk_ptr = NULL; + uint64_t *chunk_array; + uint64_t *chunk_array_ptr; + uint32_t card_offset; + long size; + int r, i; + RING_LOCALS; + + /* set command stream id to 0 which is fake id */ + cs_id = 0; + DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t)); + + if (dev_priv == NULL) { + DRM_ERROR("called with no initialization\n"); + return -EINVAL; + } + if (!cs->num_chunks) { + return 0; + } + + + chunk_array = drm_calloc(cs->num_chunks, sizeof(uint64_t), DRM_MEM_DRIVER); + if (!chunk_array) { + return -ENOMEM; + } + + chunk_array_ptr = (uint64_t *)(unsigned long)(cs->chunks); + + if (DRM_COPY_FROM_USER(chunk_array, chunk_array_ptr, sizeof(uint64_t)*cs->num_chunks)) { + r = -EFAULT; + goto out; + } + + parser.reloc_index = -1; + parser.ib_index = -1; + parser.num_chunks = cs->num_chunks; + /* copy out the chunk headers */ + parser.chunks = drm_calloc(parser.num_chunks, sizeof(struct drm_radeon_kernel_chunk), DRM_MEM_DRIVER); + if (!parser.chunks) { + return -ENOMEM; + } + + for (i = 0; i < parser.num_chunks; i++) { + struct drm_radeon_cs_chunk user_chunk; + + chunk_ptr = (void __user *)(unsigned long)chunk_array[i]; + + if (DRM_COPY_FROM_USER(&user_chunk, chunk_ptr, sizeof(struct drm_radeon_cs_chunk))){ + r = -EFAULT; + goto out; + } + parser.chunks[i].chunk_id = user_chunk.chunk_id; + + if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) + parser.reloc_index = i; + + if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_IB) + parser.ib_index = i; + + if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_OLD) { + parser.ib_index = i; + parser.reloc_index = -1; + } + + parser.chunks[i].length_dw = user_chunk.length_dw; + parser.chunks[i].chunk_data = (uint32_t *)(unsigned long)user_chunk.chunk_data; + + parser.chunks[i].kdata = NULL; + + switch(parser.chunks[i].chunk_id) { + case RADEON_CHUNK_ID_RELOCS: + case RADEON_CHUNK_ID_IB: + case RADEON_CHUNK_ID_OLD: { + /* copy from user the relocs chunk */ + int size = parser.chunks[i].length_dw * sizeof(uint32_t); + parser.chunks[i].kdata = drm_alloc(size, DRM_MEM_DRIVER); + if (!parser.chunks[i].kdata) { + r = -ENOMEM; + goto out; + } + + if (DRM_COPY_FROM_USER(parser.chunks[i].kdata, parser.chunks[i].chunk_data, size)) { + r = -EFAULT; + goto out; + } + } + break; + default: + break; + } + DRM_DEBUG("chunk %d %d %d %p\n", i, parser.chunks[i].chunk_id, parser.chunks[i].length_dw, + parser.chunks[i].chunk_data); + } + + + if (parser.chunks[parser.ib_index].length_dw > (16 * 1024)) { + DRM_ERROR("cs->dwords too big: %d\n", parser.chunks[parser.ib_index].length_dw); + r = -EINVAL; + goto out; + } + + /* get ib */ + r = dev_priv->cs.ib_get(&parser, &card_offset); + if (r) { + DRM_ERROR("ib_get failed\n"); + goto out; + } + + /* now parse command stream */ + r = dev_priv->cs.parse(&parser); + if (r) { + goto out; + } + + BEGIN_RING(4); + OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1)); + OUT_RING(card_offset); + OUT_RING(parser.chunks[parser.ib_index].length_dw); + OUT_RING(CP_PACKET2()); + ADVANCE_RING(); + + /* emit cs id sequence */ + dev_priv->cs.id_emit(dev, &cs_id); + COMMIT_RING(); + + DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t)); +out: + dev_priv->cs.ib_free(&parser); + + for (i = 0; i < parser.num_chunks; i++) { + if (parser.chunks[i].kdata) + drm_free(parser.chunks[i].kdata, parser.chunks[i].length_dw * sizeof(uint32_t), DRM_MEM_DRIVER); + } + + drm_free(parser.chunks, sizeof(struct drm_radeon_kernel_chunk)*parser.num_chunks, DRM_MEM_DRIVER); + drm_free(chunk_array, sizeof(uint64_t)*parser.num_chunks, DRM_MEM_DRIVER); + + return r; +} + int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) { + struct drm_radeon_cs_parser parser; struct drm_radeon_private *dev_priv = dev->dev_private; struct drm_radeon_cs *cs = data; uint32_t *packets = NULL; uint32_t cs_id; uint32_t card_offset; - void *ib = NULL; long size; int r; + struct drm_radeon_kernel_chunk chunk_fake[1]; RING_LOCALS; /* set command stream id to 0 which is fake id */ @@ -69,14 +216,26 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) r = -EFAULT; goto out; } + + chunk_fake[0].chunk_id = RADEON_CHUNK_ID_OLD; + chunk_fake[0].length_dw = cs->dwords; + chunk_fake[0].kdata = packets; + + parser.dev = dev; + parser.file_priv = fpriv; + parser.num_chunks = 1; + parser.chunks = chunk_fake; + parser.ib_index = 0; + parser.reloc_index = -1; + /* get ib */ - r = dev_priv->cs.ib_get(dev, &ib, cs->dwords, &card_offset); + r = dev_priv->cs.ib_get(&parser, &card_offset); if (r) { goto out; } /* now parse command stream */ - r = dev_priv->cs.parse(dev, fpriv, ib, packets, cs->dwords); + r = dev_priv->cs.parse(&parser); if (r) { goto out; } @@ -94,13 +253,13 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t)); out: - dev_priv->cs.ib_free(dev, ib, cs->dwords); + dev_priv->cs.ib_free(&parser); drm_free(packets, size, DRM_MEM_DRIVER); return r; } /* for non-mm */ -static int radeon_nomm_relocate(struct drm_device *dev, struct drm_file *file_priv, uint32_t *reloc, uint32_t *offset) +static int radeon_nomm_relocate(struct drm_radeon_cs_parser *parser, uint32_t *reloc, uint32_t *offset) { *offset = reloc[1]; return 0; @@ -108,17 +267,24 @@ static int radeon_nomm_relocate(struct drm_device *dev, struct drm_file *file_pr #define RELOC_SIZE 2 #define RADEON_2D_OFFSET_MASK 0x3fffff -static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct drm_file *file_priv, - uint32_t *packets, uint32_t offset_dw) +static __inline__ int radeon_cs_relocate_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw) { + struct drm_device *dev = parser->dev; drm_radeon_private_t *dev_priv = dev->dev_private; - uint32_t hdr = packets[offset_dw]; - uint32_t reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2; - uint32_t val = packets[offset_dw + 1]; - uint32_t packet3_hdr = packets[offset_dw+2]; + uint32_t hdr, reg, val, packet3_hdr; uint32_t tmp, offset; + struct drm_radeon_kernel_chunk *ib_chunk; int ret; + ib_chunk = &parser->chunks[parser->ib_index]; +// if (parser->reloc_index == -1) +// is_old = 1; + + hdr = ib_chunk->kdata[offset_dw]; + reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2; + val = ib_chunk->kdata[offset_dw + 1]; + packet3_hdr = ib_chunk->kdata[offset_dw + 2]; + /* this is too strict we may want to expand the length in the future and have old kernels ignore it. */ if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16))) { @@ -130,7 +296,7 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct case RADEON_DST_PITCH_OFFSET: case RADEON_SRC_PITCH_OFFSET: /* pass in the start of the reloc */ - ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + 2, &offset); + ret = dev_priv->cs.relocate(parser, ib_chunk->kdata + offset_dw + 2, &offset); if (ret) return ret; tmp = (val & RADEON_2D_OFFSET_MASK) << 10; @@ -148,7 +314,7 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct case R200_PP_TXOFFSET_1: case RADEON_PP_TXOFFSET_0: case RADEON_PP_TXOFFSET_1: - ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + 2, &offset); + ret = dev_priv->cs.relocate(parser. ib_chunk->kdata + offset_dw + 2, &offset); if (ret) return ret; @@ -159,25 +325,32 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct break; } - packets[offset_dw + 1] = val; + ib_chunk->kdata[offset_dw + 1] = val; return 0; } -static int radeon_cs_relocate_packet3(struct drm_device *dev, struct drm_file *file_priv, - uint32_t *packets, uint32_t offset_dw) +static int radeon_cs_relocate_packet3(struct drm_radeon_cs_parser *parser, + uint32_t offset_dw) { - drm_radeon_private_t *dev_priv = dev->dev_private; - uint32_t hdr = packets[offset_dw]; - int num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16; - uint32_t reg = hdr & 0xff00; + drm_radeon_private_t *dev_priv = parser->dev->dev_private; + uint32_t hdr, num_dw, reg; uint32_t offset, val, tmp; int ret; + struct drm_radeon_kernel_chunk *ib_chunk; + + ib_chunk = &parser->chunks[parser->ib_index]; +// if (parser->reloc_index == -1) +// is_old = 1; + + hdr = ib_chunk->kdata[offset_dw]; + num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16; + reg = hdr & 0xff00; switch(reg) { case RADEON_CNTL_HOSTDATA_BLT: { - val = packets[offset_dw + 2]; - ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + num_dw + 2, &offset); + val = ib_chunk->kdata[offset_dw + 2]; + ret = dev_priv->cs.relocate(parser, ib_chunk->kdata + offset_dw + num_dw + 2, &offset); if (ret) return ret; @@ -187,7 +360,7 @@ static int radeon_cs_relocate_packet3(struct drm_device *dev, struct drm_file *f offset >>= 10; val |= offset; - packets[offset_dw + 2] = val; + ib_chunk->kdata[offset_dw + 2] = val; } default: return -EINVAL; @@ -195,17 +368,18 @@ static int radeon_cs_relocate_packet3(struct drm_device *dev, struct drm_file *f return 0; } -int radeon_cs_packet0(struct drm_device *dev, struct drm_file *file_priv, - uint32_t *packets, uint32_t offset_dw) +int radeon_cs_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw) { - drm_radeon_private_t *dev_priv = dev->dev_private; - uint32_t hdr = packets[offset_dw]; - int num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2; + drm_radeon_private_t *dev_priv = parser->dev->dev_private; + uint32_t hdr, num_dw, reg; int need_reloc = 0; - int reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2; int count_dw = 1; int ret; + hdr = parser->chunks[parser->ib_index].kdata[offset_dw]; + num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2; + reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2; + while (count_dw < num_dw) { /* need to have something like the r300 validation here - list of allowed registers */ @@ -226,7 +400,7 @@ int radeon_cs_packet0(struct drm_device *dev, struct drm_file *file_priv, return -EINVAL; } - ret = radeon_cs_relocate_packet0(dev, file_priv, packets, offset_dw); + ret = radeon_cs_relocate_packet0(parser, offset_dw); if (ret) return ret; DRM_DEBUG("need to relocate %x %d\n", reg, flags); @@ -245,24 +419,27 @@ int radeon_cs_packet0(struct drm_device *dev, struct drm_file *file_priv, return 0; } -int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv, - void *ib, uint32_t *packets, uint32_t dwords) +int radeon_cs_parse(struct drm_radeon_cs_parser *parser) { - drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_device *dev = parser->dev; + drm_radeon_private_t *dev_priv = parser->dev->dev_private; volatile int rb; - int size_dw = dwords; + struct drm_radeon_kernel_chunk *ib_chunk; /* scan the packet for various things */ - int count_dw = 0; + int count_dw = 0, size_dw; int ret = 0; + ib_chunk = &parser->chunks[parser->ib_index]; + size_dw = ib_chunk->length_dw; + while (count_dw < size_dw && ret == 0) { - int hdr = packets[count_dw]; + int hdr = ib_chunk->kdata[count_dw]; int num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16; int reg; switch (hdr & RADEON_CP_PACKET_MASK) { case RADEON_CP_PACKET0: - ret = radeon_cs_packet0(dev, file_priv, packets, count_dw); + ret = radeon_cs_packet0(parser, count_dw); break; case RADEON_CP_PACKET1: case RADEON_CP_PACKET2: @@ -275,7 +452,7 @@ int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv, switch(reg) { case RADEON_CNTL_HOSTDATA_BLT: - radeon_cs_relocate_packet3(dev, file_priv, packets, count_dw); + radeon_cs_relocate_packet3(parser, count_dw); break; case RADEON_CNTL_BITBLT_MULTI: @@ -306,10 +483,10 @@ int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv, /* copy the packet into the IB */ - memcpy(ib, packets, dwords * sizeof(uint32_t)); + memcpy(parser->ib, ib_chunk->kdata, ib_chunk->length_dw * sizeof(uint32_t)); /* read back last byte to flush WC buffers */ - rb = readl((ib + (dwords-1) * sizeof(uint32_t))); + rb = readl((parser->ib + (ib_chunk->length_dw-1) * sizeof(uint32_t))); return 0; } diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index c924c689..bc2eb45a 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -514,6 +514,7 @@ typedef struct { #define DRM_RADEON_GEM_INDIRECT 0x24 // temporary for X server #define DRM_RADEON_CS 0x25 +#define DRM_RADEON_CS2 0x26 #define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t) #define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START) @@ -554,6 +555,7 @@ typedef struct { #define DRM_IOCTL_RADEON_GEM_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INDIRECT, struct drm_radeon_gem_indirect) #define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs) +#define DRM_IOCTL_RADEON_CS2 DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS2, struct drm_radeon_cs2) typedef struct drm_radeon_init { @@ -874,11 +876,26 @@ struct drm_radeon_gem_indirect { struct drm_radeon_cs { -// uint32_t __user *packets; uint32_t dwords; uint32_t cs_id; uint64_t packets; +}; + +#define RADEON_CHUNK_ID_RELOCS 0x01 +#define RADEON_CHUNK_ID_IB 0x02 +#define RADEON_CHUNK_ID_OLD 0xff + +struct drm_radeon_cs_chunk { + uint32_t chunk_id; + uint32_t length_dw; + uint64_t chunk_data; +}; +struct drm_radeon_cs2 { + uint32_t num_chunks; + uint32_t cs_id; + uint64_t chunks; /* this points to uint64_t * which point to + cs chunks */ }; diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 17c0c297..b741953b 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -294,6 +294,23 @@ struct drm_radeon_master_private { #define RADEON_FLUSH_EMITED (1 < 0) #define RADEON_PURGE_EMITED (1 < 1) +struct drm_radeon_kernel_chunk { + uint32_t chunk_id; + uint32_t length_dw; + uint32_t __user *chunk_data; + uint32_t *kdata; +}; + +struct drm_radeon_cs_parser { + struct drm_device *dev; + struct drm_file *file_priv; + uint32_t num_chunks; + struct drm_radeon_kernel_chunk *chunks; + int ib_index; + int reloc_index; + void *ib; +}; + /* command submission struct */ struct drm_radeon_cs_priv { uint32_t id_wcnt; @@ -301,21 +318,22 @@ struct drm_radeon_cs_priv { uint32_t id_last_wcnt; uint32_t id_last_scnt; - int (*parse)(struct drm_device *dev, struct drm_file *file_priv, - void *ib, uint32_t *packets, uint32_t dwords); + int (*parse)(struct drm_radeon_cs_parser *parser); void (*id_emit)(struct drm_device *dev, uint32_t *id); uint32_t (*id_last_get)(struct drm_device *dev); /* this ib handling callback are for hidding memory manager drm * from memory manager less drm, free have to emit ib discard * sequence into the ring */ - int (*ib_get)(struct drm_device *dev, void **ib, uint32_t dwords, uint32_t *card_offset); + int (*ib_get)(struct drm_radeon_cs_parser *parser, uint32_t *card_offset); uint32_t (*ib_get_ptr)(struct drm_device *dev, void *ib); - void (*ib_free)(struct drm_device *dev, void *ib, uint32_t dwords); + void (*ib_free)(struct drm_radeon_cs_parser *parser); /* do a relocation either MM or non-MM */ - int (*relocate)(struct drm_device *dev, struct drm_file *file_priv, - uint32_t *reloc, uint32_t *offset); + int (*relocate)(struct drm_radeon_cs_parser *parser, + uint32_t *reloc, uint32_t *offset); }; + + struct radeon_pm_regs { uint32_t crtc_ext_cntl; uint32_t bios_scratch[8]; @@ -1689,6 +1707,7 @@ extern int radeon_master_create(struct drm_device *dev, struct drm_master *maste extern void radeon_master_destroy(struct drm_device *dev, struct drm_master *master); extern void radeon_cp_dispatch_flip(struct drm_device * dev, struct drm_master *master); extern int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv); +extern int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv); extern int radeon_cs_init(struct drm_device *dev); void radeon_gem_update_offsets(struct drm_device *dev, struct drm_master *master); void radeon_init_memory_map(struct drm_device *dev); diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index 7262b2aa..f0cd6f89 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -3290,6 +3290,7 @@ struct drm_ioctl_desc radeon_ioctls[] = { DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_GEM_INDIRECT, radeon_gem_indirect_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_CS2, radeon_cs2_ioctl, DRM_AUTH), }; int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); -- cgit v1.2.3 From 35f080559287ebf30f417337fa124d827709503b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:40:24 +1000 Subject: radeon: don't copy to user the cs ids --- shared-core/radeon_cs.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index 452f04b4..14f3dcd9 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -45,7 +45,7 @@ int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) /* set command stream id to 0 which is fake id */ cs_id = 0; - DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t)); + cs->cs_id = cs_id; if (dev_priv == NULL) { DRM_ERROR("called with no initialization\n"); @@ -160,7 +160,8 @@ int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) dev_priv->cs.id_emit(dev, &cs_id); COMMIT_RING(); - DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t)); + cs->cs_id = cs_id; + out: dev_priv->cs.ib_free(&parser); @@ -190,7 +191,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) /* set command stream id to 0 which is fake id */ cs_id = 0; - DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t)); + cs->cs_id = cs_id; if (dev_priv == NULL) { DRM_ERROR("called with no initialization\n"); @@ -251,7 +252,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) dev_priv->cs.id_emit(dev, &cs_id); COMMIT_RING(); - DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t)); + cs->cs_id = cs_id; out: dev_priv->cs.ib_free(&parser); drm_free(packets, size, DRM_MEM_DRIVER); -- cgit v1.2.3 From 6000fa686294019e93f815433a1a9b44db511a69 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:40:52 +1000 Subject: radeon: CS2 make it all work with new relocs style --- shared-core/radeon_cs.c | 52 ++++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 20 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index 14f3dcd9..31cd53db 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -68,6 +68,8 @@ int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) goto out; } + parser.dev = dev; + parser.file_priv = fpriv; parser.reloc_index = -1; parser.ib_index = -1; parser.num_chunks = cs->num_chunks; @@ -103,24 +105,29 @@ int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) parser.chunks[i].chunk_data = (uint32_t *)(unsigned long)user_chunk.chunk_data; parser.chunks[i].kdata = NULL; + size = parser.chunks[i].length_dw * sizeof(uint32_t); switch(parser.chunks[i].chunk_id) { - case RADEON_CHUNK_ID_RELOCS: case RADEON_CHUNK_ID_IB: - case RADEON_CHUNK_ID_OLD: { - /* copy from user the relocs chunk */ - int size = parser.chunks[i].length_dw * sizeof(uint32_t); - parser.chunks[i].kdata = drm_alloc(size, DRM_MEM_DRIVER); - if (!parser.chunks[i].kdata) { - r = -ENOMEM; + case RADEON_CHUNK_ID_OLD: + if (size == 0) { + r = -EINVAL; goto out; } - - if (DRM_COPY_FROM_USER(parser.chunks[i].kdata, parser.chunks[i].chunk_data, size)) { - r = -EFAULT; - goto out; - } - } + case RADEON_CHUNK_ID_RELOCS: + if (size) { + parser.chunks[i].kdata = drm_alloc(size, DRM_MEM_DRIVER); + if (!parser.chunks[i].kdata) { + r = -ENOMEM; + goto out; + } + + if (DRM_COPY_FROM_USER(parser.chunks[i].kdata, parser.chunks[i].chunk_data, size)) { + r = -EFAULT; + goto out; + } + } else + parser.chunks[i].kdata = NULL; break; default: break; @@ -266,6 +273,7 @@ static int radeon_nomm_relocate(struct drm_radeon_cs_parser *parser, uint32_t *r return 0; } #define RELOC_SIZE 2 +#define RELOC_SIZE_NEW 0 #define RADEON_2D_OFFSET_MASK 0x3fffff static __inline__ int radeon_cs_relocate_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw) @@ -288,9 +296,17 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_radeon_cs_parser *pa /* this is too strict we may want to expand the length in the future and have old kernels ignore it. */ - if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16))) { - DRM_ERROR("Packet 3 was %x should have been %x: reg is %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16), reg); - return -EINVAL; + if (parser->reloc_index == -1) { + if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16))) { + DRM_ERROR("Packet 3 was %x should have been %x: reg is %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16), reg); + return -EINVAL; + } + } else { + if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE_NEW << 16))) { + DRM_ERROR("Packet 3 was %x should have been %x: reg is %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE_NEW << 16), reg); + return -EINVAL; + + } } switch(reg) { @@ -371,9 +387,7 @@ static int radeon_cs_relocate_packet3(struct drm_radeon_cs_parser *parser, int radeon_cs_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw) { - drm_radeon_private_t *dev_priv = parser->dev->dev_private; uint32_t hdr, num_dw, reg; - int need_reloc = 0; int count_dw = 1; int ret; @@ -422,8 +436,6 @@ int radeon_cs_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw) int radeon_cs_parse(struct drm_radeon_cs_parser *parser) { - struct drm_device *dev = parser->dev; - drm_radeon_private_t *dev_priv = parser->dev->dev_private; volatile int rb; struct drm_radeon_kernel_chunk *ib_chunk; /* scan the packet for various things */ -- cgit v1.2.3 From 4ccec67a239517458bace47bf08f6770393abb37 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:42:01 +1000 Subject: radeon: remove unused gem indirect ioctl --- shared-core/radeon_drm.h | 6 ------ shared-core/radeon_drv.h | 2 -- shared-core/radeon_state.c | 1 - 3 files changed, 9 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index bc2eb45a..0780eb7f 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -511,7 +511,6 @@ typedef struct { #define DRM_RADEON_GEM_PREAD 0x21 #define DRM_RADEON_GEM_PWRITE 0x22 #define DRM_RADEON_GEM_SET_DOMAIN 0x23 -#define DRM_RADEON_GEM_INDIRECT 0x24 // temporary for X server #define DRM_RADEON_CS 0x25 #define DRM_RADEON_CS2 0x26 @@ -552,7 +551,6 @@ typedef struct { #define DRM_IOCTL_RADEON_GEM_PREAD DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PREAD, struct drm_radeon_gem_pread) #define DRM_IOCTL_RADEON_GEM_PWRITE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PWRITE, struct drm_radeon_gem_pwrite) #define DRM_IOCTL_RADEON_GEM_SET_DOMAIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain) -#define DRM_IOCTL_RADEON_GEM_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INDIRECT, struct drm_radeon_gem_indirect) #define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs) #define DRM_IOCTL_RADEON_CS2 DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS2, struct drm_radeon_cs2) @@ -866,10 +864,6 @@ struct drm_radeon_gem_pwrite { uint64_t data_ptr; /* void *, but pointers are not 32/64 compatible */ }; -struct drm_radeon_gem_indirect { - uint32_t handle; - uint32_t used; -}; /* New interface which obsolete all previous interface. */ diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index b741953b..73e5a261 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -1688,8 +1688,6 @@ extern int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data, int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, uint32_t pin_domain); int radeon_gem_object_unpin(struct drm_gem_object *obj); -int radeon_gem_indirect_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); struct drm_gem_object *radeon_gem_object_alloc(struct drm_device *dev, int size, int alignment, diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index f0cd6f89..40ecf1c4 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -3288,7 +3288,6 @@ struct drm_ioctl_desc radeon_ioctls[] = { DRM_IOCTL_DEF(DRM_RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_GEM_INDIRECT, radeon_gem_indirect_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_CS2, radeon_cs2_ioctl, DRM_AUTH), }; -- cgit v1.2.3 From fc25c81eab2d847c854e0a44cae29f8c2213bba6 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:43:29 +1000 Subject: radeon: rs480 fixes for bus mastering --- shared-core/radeon_cp.c | 15 ++++++++------- shared-core/radeon_drv.h | 5 +++++ 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 8e97f034..942ccc51 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -198,15 +198,16 @@ void radeon_enable_bm(struct drm_radeon_private *dev_priv) { u32 tmp; /* Turn on bus mastering */ - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { - /* rs400, rs690/rs740 */ - tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS400_BUS_MASTER_DIS; + /* rs600/rs690/rs740 */ + tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS; RADEON_WRITE(RADEON_BUS_CNTL, tmp); - } else if (!(((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV380) || - ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R423))) { - /* r1xx, r2xx, r300, r(v)350, r420/r481, rs480 */ + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { + /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; RADEON_WRITE(RADEON_BUS_CNTL, tmp); } /* PCIE cards appears to not need this */ diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 73e5a261..85a22e9f 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -591,7 +591,11 @@ int radeon_resume(struct drm_device *dev); # define RADEON_SCISSOR_2_ENABLE (1 << 30) #define RADEON_BUS_CNTL 0x0030 +/* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ # define RADEON_BUS_MASTER_DIS (1 << 6) +/* rs600/rs690/rs740 */ +# define RS600_BUS_MASTER_DIS (1 << 14) +# define RS600_MSI_REARM (1 << 20) #define RADEON_CLOCK_CNTL_DATA 0x000c # define RADEON_PLL_WR_EN (1 << 7) @@ -1053,6 +1057,7 @@ int radeon_resume(struct drm_device *dev); #define RADEON_AIC_CNTL 0x01d0 # define RADEON_PCIGART_TRANSLATE_EN (1 << 0) +# define RS400_MSI_REARM (1 << 3) #define RADEON_AIC_STAT 0x01d4 #define RADEON_AIC_PT_BASE 0x01d8 #define RADEON_AIC_LO_ADDR 0x01dc -- cgit v1.2.3 From 31f8d4218c0f6455751d8bbc788172912359b0df Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:44:03 +1000 Subject: radeon: add wait rendering API --- shared-core/radeon_drm.h | 6 ++++-- shared-core/radeon_drv.h | 2 ++ shared-core/radeon_state.c | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index 0780eb7f..002e4004 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -511,6 +511,7 @@ typedef struct { #define DRM_RADEON_GEM_PREAD 0x21 #define DRM_RADEON_GEM_PWRITE 0x22 #define DRM_RADEON_GEM_SET_DOMAIN 0x23 +#define DRM_RADEON_GEM_WAIT_RENDERING 0x24 #define DRM_RADEON_CS 0x25 #define DRM_RADEON_CS2 0x26 @@ -551,7 +552,7 @@ typedef struct { #define DRM_IOCTL_RADEON_GEM_PREAD DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PREAD, struct drm_radeon_gem_pread) #define DRM_IOCTL_RADEON_GEM_PWRITE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PWRITE, struct drm_radeon_gem_pwrite) #define DRM_IOCTL_RADEON_GEM_SET_DOMAIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain) - +#define DRM_IOCTL_RADEON_GEM_WAIT_RENDERING DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_RENDERING, struct drm_radeon_gem_wait_rendering) #define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs) #define DRM_IOCTL_RADEON_CS2 DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS2, struct drm_radeon_cs2) @@ -820,7 +821,8 @@ struct drm_radeon_gem_set_domain { uint32_t write_domain; }; -struct drm_radeon_gem_exec_buffer { +struct drm_radeon_gem_wait_rendering { + uint32_t handle; }; struct drm_radeon_gem_pin { diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 85a22e9f..aa178d4d 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -1695,6 +1695,8 @@ int radeon_gem_object_pin(struct drm_gem_object *obj, int radeon_gem_object_unpin(struct drm_gem_object *obj); int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +int radeon_gem_wait_rendering(struct drm_device *dev, void *data, + struct drm_file *file_priv); struct drm_gem_object *radeon_gem_object_alloc(struct drm_device *dev, int size, int alignment, int initial_domain, bool discardable); int radeon_modeset_init(struct drm_device *dev); diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index 40ecf1c4..ada91362 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -3288,6 +3288,7 @@ struct drm_ioctl_desc radeon_ioctls[] = { DRM_IOCTL_DEF(DRM_RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_GEM_WAIT_RENDERING, radeon_gem_wait_rendering, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_CS2, radeon_cs2_ioctl, DRM_AUTH), }; -- cgit v1.2.3 From be3dac976e07fbfd727a2d0216ea9ba3247db348 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:44:32 +1000 Subject: radeon: only enable dynclks if asked for --- shared-core/radeon_cp.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 942ccc51..3f8f0c94 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2601,19 +2601,23 @@ int radeon_static_clocks_init(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; - if (dev_priv->chip_family == CHIP_RS400 || - dev_priv->chip_family == CHIP_RS480) - radeon_dynclks = 0; - - if ((dev_priv->flags & RADEON_IS_MOBILITY) && !radeon_is_avivo(dev_priv)) { - radeon_set_dynamic_clock(dev, radeon_dynclks); - } else if (radeon_is_avivo(dev_priv)) { - if (radeon_dynclks) { - radeon_atom_static_pwrmgt_setup(dev, 1); - radeon_atom_dyn_clk_setup(dev, 1); + if (radeon_dynclks != -1) { + + if (dev_priv->chip_family == CHIP_RS400 || + dev_priv->chip_family == CHIP_RS480) + radeon_dynclks = 0; + + if ((dev_priv->flags & RADEON_IS_MOBILITY) && !radeon_is_avivo(dev_priv)) { + radeon_set_dynamic_clock(dev, radeon_dynclks); + } else if (radeon_is_avivo(dev_priv)) { + if (radeon_dynclks) { + radeon_atom_static_pwrmgt_setup(dev, 1); + radeon_atom_dyn_clk_setup(dev, 1); + } } } - radeon_force_some_clocks(dev); + if (radeon_is_r300(dev_priv) || radeon_is_rv100(dev_priv)) + radeon_force_some_clocks(dev); return 0; } -- cgit v1.2.3 From 4ef8ace9a96bd6bb4040ef5c4c3ea5572d7129e1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:45:43 +1000 Subject: radeon: add proc debugging for interrupts/ring --- shared-core/radeon_drv.h | 3 +++ shared-core/radeon_irq.c | 1 + 2 files changed, 4 insertions(+) (limited to 'shared-core') diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index aa178d4d..8f77c850 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -459,6 +459,7 @@ typedef struct drm_radeon_private { struct drm_radeon_cs_priv cs; struct radeon_pm_regs pmregs; + atomic_t irq_received; } drm_radeon_private_t; typedef struct drm_radeon_buf_priv { @@ -1718,6 +1719,8 @@ void radeon_gem_update_offsets(struct drm_device *dev, struct drm_master *master void radeon_init_memory_map(struct drm_device *dev); void radeon_enable_bm(struct drm_radeon_private *dev_priv); +extern int radeon_gem_proc_init(struct drm_minor *minor); +extern void radeon_gem_proc_cleanup(struct drm_minor *minor); #define MARK_SAFE 1 #define MARK_CHECK_OFFSET 2 #define MARK_CHECK_SCISSOR 3 diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c index dcf58e43..311901c0 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -195,6 +195,7 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) if (!stat) return IRQ_NONE; + atomic_inc(&dev_priv->irq_received); stat &= dev_priv->irq_enable_reg; /* SW interrupt */ -- cgit v1.2.3 From 31b8a640db9b55638bf9967f0d78ec665fa8839f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:46:54 +1000 Subject: radeon: overhaul ring interactions emit in 16-dword blocks, emit irqs at same time as everything else --- shared-core/radeon_cs.c | 84 ++++++++++++++++++++++++++++++------------------ shared-core/radeon_drv.h | 6 ++-- shared-core/radeon_irq.c | 16 +++++---- 3 files changed, 66 insertions(+), 40 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index 31cd53db..4a231962 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -38,10 +38,8 @@ int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) struct drm_radeon_cs_chunk __user **chunk_ptr = NULL; uint64_t *chunk_array; uint64_t *chunk_array_ptr; - uint32_t card_offset; long size; int r, i; - RING_LOCALS; /* set command stream id to 0 which is fake id */ cs_id = 0; @@ -144,7 +142,7 @@ int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) } /* get ib */ - r = dev_priv->cs.ib_get(&parser, &card_offset); + r = dev_priv->cs.ib_get(&parser); if (r) { DRM_ERROR("ib_get failed\n"); goto out; @@ -156,16 +154,8 @@ int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) goto out; } - BEGIN_RING(4); - OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1)); - OUT_RING(card_offset); - OUT_RING(parser.chunks[parser.ib_index].length_dw); - OUT_RING(CP_PACKET2()); - ADVANCE_RING(); - /* emit cs id sequence */ - dev_priv->cs.id_emit(dev, &cs_id); - COMMIT_RING(); + dev_priv->cs.id_emit(&parser, &cs_id); cs->cs_id = cs_id; @@ -194,7 +184,6 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) long size; int r; struct drm_radeon_kernel_chunk chunk_fake[1]; - RING_LOCALS; /* set command stream id to 0 which is fake id */ cs_id = 0; @@ -237,7 +226,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) parser.reloc_index = -1; /* get ib */ - r = dev_priv->cs.ib_get(&parser, &card_offset); + r = dev_priv->cs.ib_get(&parser); if (r) { goto out; } @@ -248,15 +237,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) goto out; } - BEGIN_RING(4); - OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1)); - OUT_RING(card_offset); - OUT_RING(cs->dwords); - OUT_RING(CP_PACKET2()); - ADVANCE_RING(); - /* emit cs id sequence */ - dev_priv->cs.id_emit(dev, &cs_id); + dev_priv->cs.id_emit(&parser, &cs_id); COMMIT_RING(); cs->cs_id = cs_id; @@ -518,37 +500,75 @@ uint32_t radeon_cs_id_get(struct drm_radeon_private *radeon) return (radeon->cs.id_scnt | radeon->cs.id_wcnt); } -void r100_cs_id_emit(struct drm_device *dev, uint32_t *id) +void r100_cs_id_emit(struct drm_radeon_cs_parser *parser, uint32_t *id) { - drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_private_t *dev_priv = parser->dev->dev_private; RING_LOCALS; + dev_priv->irq_emitted = radeon_update_breadcrumb(parser->dev); /* ISYNC_CNTL should have CPSCRACTH bit set */ *id = radeon_cs_id_get(dev_priv); /* emit id in SCRATCH4 (not used yet in old drm) */ - BEGIN_RING(2); + BEGIN_RING(10); + OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1)); + OUT_RING(parser->card_offset); + OUT_RING(parser->chunks[parser->ib_index].length_dw); + OUT_RING(CP_PACKET2()); OUT_RING(CP_PACKET0(RADEON_SCRATCH_REG4, 0)); OUT_RING(*id); + OUT_RING_REG(RADEON_LAST_SWI_REG, dev_priv->irq_emitted); + OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE); ADVANCE_RING(); + COMMIT_RING(); + } -void r300_cs_id_emit(struct drm_device *dev, uint32_t *id) +void r300_cs_id_emit(struct drm_radeon_cs_parser *parser, uint32_t *id) { - drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_private_t *dev_priv = parser->dev->dev_private; + int i; RING_LOCALS; + dev_priv->irq_emitted = radeon_update_breadcrumb(parser->dev); + /* ISYNC_CNTL should not have CPSCRACTH bit set */ *id = radeon_cs_id_get(dev_priv); + /* emit id in SCRATCH6 */ - BEGIN_RING(8); - OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 0)); + BEGIN_RING(16); + OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1)); + OUT_RING(parser->card_offset); + OUT_RING(parser->chunks[parser->ib_index].length_dw); + OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); + OUT_RING(0); + for (i = 0; i < 11; i++) /* emit fillers like fglrx */ + OUT_RING(CP_PACKET2()); + ADVANCE_RING(); + COMMIT_RING(); + + BEGIN_RING(16); + OUT_RING_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DC_FLUSH); + OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 1)); OUT_RING(6); - OUT_RING(CP_PACKET0(R300_CP_RESYNC_DATA, 0)); OUT_RING(*id); - OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - OUT_RING(R300_RB3D_DC_FINISH); + OUT_RING_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DC_FINISH|R300_RB3D_DC_FLUSH); + /* emit inline breadcrumb for TTM fencing */ +#if 1 RADEON_WAIT_UNTIL_3D_IDLE(); + OUT_RING_REG(RADEON_LAST_SWI_REG, dev_priv->irq_emitted); +#else + OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 1)); + OUT_RING(3); /* breadcrumb register */ + OUT_RING(dev_priv->irq_emitted); + OUT_RING(CP_PACKET2()); +#endif + OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE); + OUT_RING(CP_PACKET2()); + OUT_RING(CP_PACKET2()); + OUT_RING(CP_PACKET2()); ADVANCE_RING(); + COMMIT_RING(); + } uint32_t r100_cs_id_last_get(struct drm_device *dev) diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 8f77c850..83478a27 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -308,6 +308,7 @@ struct drm_radeon_cs_parser { struct drm_radeon_kernel_chunk *chunks; int ib_index; int reloc_index; + uint32_t card_offset; void *ib; }; @@ -319,12 +320,12 @@ struct drm_radeon_cs_priv { uint32_t id_last_scnt; int (*parse)(struct drm_radeon_cs_parser *parser); - void (*id_emit)(struct drm_device *dev, uint32_t *id); + void (*id_emit)(struct drm_radeon_cs_parser *parser, uint32_t *id); uint32_t (*id_last_get)(struct drm_device *dev); /* this ib handling callback are for hidding memory manager drm * from memory manager less drm, free have to emit ib discard * sequence into the ring */ - int (*ib_get)(struct drm_radeon_cs_parser *parser, uint32_t *card_offset); + int (*ib_get)(struct drm_radeon_cs_parser *parser); uint32_t (*ib_get_ptr)(struct drm_device *dev, void *ib); void (*ib_free)(struct drm_radeon_cs_parser *parser); /* do a relocation either MM or non-MM */ @@ -459,6 +460,7 @@ typedef struct drm_radeon_private { struct drm_radeon_cs_priv cs; struct radeon_pm_regs pmregs; + int irq_emitted; atomic_t irq_received; } drm_radeon_private_t; diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c index 311901c0..46a27943 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -223,15 +223,19 @@ int radeon_emit_irq(struct drm_device * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; unsigned int ret; + int i; RING_LOCALS; - ret = radeon_update_breadcrumb(dev); + if (!dev_priv->irq_emitted) { + ret = radeon_update_breadcrumb(dev); - BEGIN_RING(4); - OUT_RING_REG(RADEON_LAST_SWI_REG, ret); - OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE); - ADVANCE_RING(); - COMMIT_RING(); + BEGIN_RING(4); + OUT_RING_REG(RADEON_LAST_SWI_REG, ret); + OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE); + ADVANCE_RING(); + COMMIT_RING(); + } else + ret = dev_priv->irq_emitted; return ret; } -- cgit v1.2.3 From e829d5b6bc9f5887c82653c007641c3c37f7ae67 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:47:49 +1000 Subject: radeon: setup isync cntl properly --- shared-core/radeon_cp.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 3f8f0c94..1c187b15 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -591,10 +591,15 @@ static void radeon_do_cp_start(drm_radeon_private_t * dev_priv) BEGIN_RING(8); /* isync can only be written through cp on r5xx write it here */ OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0)); + if (dev_priv->chip_family > CHIP_RV280) + OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D | + RADEON_ISYNC_ANY3D_IDLE2D | + RADEON_ISYNC_WAIT_IDLEGUI | + dev_priv->mm_enabled ? 0 : RADEON_ISYNC_CPSCRATCH_IDLEGUI); + else OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D | RADEON_ISYNC_ANY3D_IDLE2D | - RADEON_ISYNC_WAIT_IDLEGUI | - RADEON_ISYNC_CPSCRATCH_IDLEGUI); + RADEON_ISYNC_WAIT_IDLEGUI); RADEON_PURGE_CACHE(); RADEON_PURGE_ZCACHE(); RADEON_WAIT_UNTIL_IDLE(); -- cgit v1.2.3 From 28c9eb7b7493ee2478df66476c742432525f1efa Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:50:46 +1000 Subject: radeon: commit ring after emitting the buffer discards --- shared-core/radeon_state.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index ada91362..e0a00f02 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -1884,10 +1884,11 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev, OUT_RING((image->width << 16) | height); RADEON_WAIT_UNTIL_2D_IDLE(); ADVANCE_RING(); - COMMIT_RING(); radeon_cp_discard_buffer(dev, file_priv->master, buf); + COMMIT_RING(); + /* Update the input parameters for next time */ image->y += height; image->height -= height; -- cgit v1.2.3 From d3aa052f6174ea37136574b68ed55d7cb82c5017 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:51:33 +1000 Subject: radeon: disable debugging message --- shared-core/radeon_mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_mem.c b/shared-core/radeon_mem.c index dbd73c50..2622cf3c 100644 --- a/shared-core/radeon_mem.c +++ b/shared-core/radeon_mem.c @@ -294,7 +294,7 @@ int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *fi return -EFAULT; if (*heap) { - DRM_ERROR("heap already initialized?"); + DRM_DEBUG("heap already initialized?"); return -EFAULT; } -- cgit v1.2.3 From 2b9a7d5381534122858dc6e407794e8cd5c04d3e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:51:57 +1000 Subject: radeon: disable AGP for certain chips if not specified until we figure it out --- shared-core/radeon_cp.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 1c187b15..71914782 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2669,9 +2669,16 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) DRM_DEBUG("%s card detected\n", ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); - if ((dev_priv->flags & RADEON_IS_AGP) && (radeon_agpmode == -1)) { - DRM_INFO("Forcing AGP to PCI mode\n"); - dev_priv->flags &= ~RADEON_IS_AGP; + if (dev_priv->flags & RADEON_IS_AGP) { + + /* disable AGP for any chips after RV280 if not specified */ + if ((dev_priv->chip_family > CHIP_RV280) && (radeon_agpmode == 0)) + radeon_agpmode = -1; + + if (radeon_agpmode == -1) { + DRM_INFO("Forcing AGP to PCI mode\n"); + dev_priv->flags &= ~RADEON_IS_AGP; + } } -- cgit v1.2.3 From 0e1df6216e7ce3a69d4311e4685613e57129285f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:52:25 +1000 Subject: radeon: add mtrr support for VRAM aperture. --- shared-core/radeon_drv.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'shared-core') diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 83478a27..c6ebf9b6 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -462,6 +462,9 @@ typedef struct drm_radeon_private { struct radeon_pm_regs pmregs; int irq_emitted; atomic_t irq_received; + + uint32_t aper_size; + int vram_mtrr; } drm_radeon_private_t; typedef struct drm_radeon_buf_priv { -- cgit v1.2.3 From 68fcb7770efc20b9e27b1724e2fb5ac112a5330e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:58:12 +1000 Subject: radeon: make build again --- shared-core/radeon_cp.c | 9 --------- shared-core/radeon_cs.c | 2 +- shared-core/radeon_drv.h | 1 + 3 files changed, 2 insertions(+), 10 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 71914782..9a1e0e02 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2793,15 +2793,6 @@ int radeon_driver_firstopen(struct drm_device *dev) dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - radeon_gem_mm_init(dev); - - ret = drm_addmap(dev, dev_priv->fb_aper_offset, - drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER, - _DRM_WRITE_COMBINING, &map); - if (ret != 0) - return ret; - return 0; } diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index 4a231962..3dde321d 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -313,7 +313,7 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_radeon_cs_parser *pa case R200_PP_TXOFFSET_1: case RADEON_PP_TXOFFSET_0: case RADEON_PP_TXOFFSET_1: - ret = dev_priv->cs.relocate(parser. ib_chunk->kdata + offset_dw + 2, &offset); + ret = dev_priv->cs.relocate(parser, ib_chunk->kdata + offset_dw + 2, &offset); if (ret) return ret; diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index c6ebf9b6..a95ab152 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -124,6 +124,7 @@ enum radeon_family { CHIP_RV350, CHIP_RV380, CHIP_R420, + CHIP_R423, CHIP_RV410, CHIP_RS400, CHIP_RS480, -- cgit v1.2.3 From 7abb8416a7fd8d69f1f2317cdac2baa8e640671e Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sun, 9 Nov 2008 18:48:46 +0100 Subject: radeon: add more packet3 relocations handling --- shared-core/radeon_cs.c | 99 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 78 insertions(+), 21 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index 3dde321d..56f6cbac 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -180,7 +180,6 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) struct drm_radeon_cs *cs = data; uint32_t *packets = NULL; uint32_t cs_id; - uint32_t card_offset; long size; int r; struct drm_radeon_kernel_chunk chunk_fake[1]; @@ -280,12 +279,11 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_radeon_cs_parser *pa old kernels ignore it. */ if (parser->reloc_index == -1) { if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16))) { - DRM_ERROR("Packet 3 was %x should have been %x: reg is %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16), reg); + DRM_ERROR("Packet 3 was %x should have been %x: reg is %x at %d\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16), reg, offset_dw); return -EINVAL; } - } else { if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE_NEW << 16))) { - DRM_ERROR("Packet 3 was %x should have been %x: reg is %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE_NEW << 16), reg); + DRM_ERROR("Packet 3 was %x should have been %x: reg is %x at %d\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE_NEW << 16), reg, offset_dw); return -EINVAL; } @@ -295,9 +293,11 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_radeon_cs_parser *pa case RADEON_DST_PITCH_OFFSET: case RADEON_SRC_PITCH_OFFSET: /* pass in the start of the reloc */ - ret = dev_priv->cs.relocate(parser, ib_chunk->kdata + offset_dw + 2, &offset); - if (ret) + ret = dev_priv->cs.relocate(parser, + ib_chunk->kdata + offset_dw + 2, &offset); + if (ret) { return ret; + } tmp = (val & RADEON_2D_OFFSET_MASK) << 10; val &= ~RADEON_2D_OFFSET_MASK; offset += tmp; @@ -313,9 +313,12 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_radeon_cs_parser *pa case R200_PP_TXOFFSET_1: case RADEON_PP_TXOFFSET_0: case RADEON_PP_TXOFFSET_1: - ret = dev_priv->cs.relocate(parser, ib_chunk->kdata + offset_dw + 2, &offset); - if (ret) + ret = dev_priv->cs.relocate(parser, + ib_chunk->kdata + offset_dw + 2, &offset); + if (ret) { + DRM_ERROR("Failed to relocate %d\n", offset_dw); return ret; + } offset &= 0xffffffe0; val += offset; @@ -332,8 +335,9 @@ static int radeon_cs_relocate_packet3(struct drm_radeon_cs_parser *parser, uint32_t offset_dw) { drm_radeon_private_t *dev_priv = parser->dev->dev_private; - uint32_t hdr, num_dw, reg; - uint32_t offset, val, tmp; + uint32_t hdr, num_dw, reg, i; + uint32_t offset, val, tmp, nptr, cptr; + uint32_t *reloc; int ret; struct drm_radeon_kernel_chunk *ib_chunk; @@ -347,11 +351,13 @@ static int radeon_cs_relocate_packet3(struct drm_radeon_cs_parser *parser, switch(reg) { case RADEON_CNTL_HOSTDATA_BLT: - { val = ib_chunk->kdata[offset_dw + 2]; - ret = dev_priv->cs.relocate(parser, ib_chunk->kdata + offset_dw + num_dw + 2, &offset); - if (ret) + ret = dev_priv->cs.relocate(parser, + ib_chunk->kdata + offset_dw + num_dw + 2, + &offset); + if (ret) { return ret; + } tmp = (val & RADEON_2D_OFFSET_MASK) << 10; val &= ~RADEON_2D_OFFSET_MASK; @@ -360,8 +366,48 @@ static int radeon_cs_relocate_packet3(struct drm_radeon_cs_parser *parser, val |= offset; ib_chunk->kdata[offset_dw + 2] = val; - } + break; + case RADEON_3D_LOAD_VBPNTR: + nptr = ib_chunk->kdata[offset_dw + 1]; + cptr = offset_dw + 3; + for (i = 0; i < (nptr & ~1); i+= 2) { + reloc = ib_chunk->kdata + offset_dw + num_dw + 2; + reloc += ((i + 0) * 2); + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) { + return ret; + } + ib_chunk->kdata[cptr] += offset; + cptr += 1; + reloc = ib_chunk->kdata + offset_dw + num_dw + 2; + reloc += ((i + 1) * 2); + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) { + return ret; + } + ib_chunk->kdata[cptr] += offset; + cptr += 2; + } + if (nptr & 1) { + reloc = ib_chunk->kdata + offset_dw + num_dw + 2; + reloc += ((nptr - 1) * 2); + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) { + return ret; + } + ib_chunk->kdata[cptr] += offset; + } + break; + case RADEON_CP_INDX_BUFFER: + reloc = ib_chunk->kdata + offset_dw + num_dw + 2; + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) { + return ret; + } + ib_chunk->kdata[offset_dw + 2] += offset; + break; default: + DRM_ERROR("Unknown packet3 0x%08X\n", hdr); return -EINVAL; } return 0; @@ -377,6 +423,12 @@ int radeon_cs_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw) num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2; reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2; + if (hdr & (1 << 15)) { + if (reg == 0x2208) { + return 0; + } + } + while (count_dw < num_dw) { /* need to have something like the r300 validation here - list of allowed registers */ @@ -405,7 +457,8 @@ int radeon_cs_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw) } else if (flags == MARK_CHECK_SCISSOR) { DRM_DEBUG("need to validate scissor %x %d\n", reg, flags); } else { - DRM_DEBUG("illegal register %x %d\n", reg, flags); + + DRM_ERROR("illegal register 0x%x %d at %d\n", reg, flags, offset_dw); return -EINVAL; } break; @@ -435,6 +488,8 @@ int radeon_cs_parse(struct drm_radeon_cs_parser *parser) switch (hdr & RADEON_CP_PACKET_MASK) { case RADEON_CP_PACKET0: ret = radeon_cs_packet0(parser, count_dw); + if (ret) + return ret; break; case RADEON_CP_PACKET1: case RADEON_CP_PACKET2: @@ -446,14 +501,17 @@ int radeon_cs_parse(struct drm_radeon_cs_parser *parser) reg = hdr & 0xff00; switch(reg) { + case RADEON_3D_LOAD_VBPNTR: + case RADEON_CP_INDX_BUFFER: case RADEON_CNTL_HOSTDATA_BLT: - radeon_cs_relocate_packet3(parser, count_dw); + ret =radeon_cs_relocate_packet3(parser, + count_dw); + if (ret) + return ret; break; case RADEON_CNTL_BITBLT_MULTI: - case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */ - case RADEON_CP_INDX_BUFFER: - DRM_ERROR("need relocate packet 3 for %x\n", reg); + DRM_ERROR("need relocate packet 3 for %x %d\n", reg, count_dw); break; case RADEON_3D_DRAW_IMMD: /* triggers drawing using in-packet vertex data */ @@ -464,12 +522,11 @@ int radeon_cs_parse(struct drm_radeon_cs_parser *parser) case RADEON_CP_NOP: break; default: - DRM_ERROR("unknown packet 3 %x\n", reg); + DRM_ERROR("unknown packet 3 %x at %d\n", reg, count_dw); ret = -EINVAL; } break; } - count_dw += num_dw+2; } -- cgit v1.2.3 From 08ef5b5e677579892a454d44a96a12dc771b56ac Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 10 Nov 2008 15:24:42 +1000 Subject: radeon: force all ring writes to 16-dword alignment. --- shared-core/radeon_cp.c | 37 ++++++++++++++++++++++++++++++++----- shared-core/radeon_drv.h | 21 +++++++++------------ 2 files changed, 41 insertions(+), 17 deletions(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 9a1e0e02..73192d03 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -1313,9 +1313,7 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, dev_priv->ring.rptr_update = /* init->rptr_update */ 4096; dev_priv->ring.rptr_update_l2qw = drm_order( /* init->rptr_update */ 4096 / 8); - dev_priv->ring.fetch_size = /* init->fetch_size */ 32; - dev_priv->ring.fetch_size_l2ow = drm_order( /* init->fetch_size */ 32 / 16); - + dev_priv->ring.fetch_size_l2ow = 2; dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; @@ -2513,8 +2511,7 @@ int radeon_modeset_cp_init(struct drm_device *dev) dev_priv->ring.size_l2qw = drm_order(dev_priv->ring.size / 8); dev_priv->ring.rptr_update = 4096; dev_priv->ring.rptr_update_l2qw = drm_order(4096 / 8); - dev_priv->ring.fetch_size = 32; - dev_priv->ring.fetch_size_l2ow = drm_order(32 / 16); + dev_priv->ring.fetch_size_l2ow = 2; /* do what tcore does */ dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; @@ -2841,3 +2838,33 @@ void radeon_gart_flush(struct drm_device *dev) } } + +void radeon_commit_ring(drm_radeon_private_t *dev_priv) +{ + int i; + u32 *ring; + int tail_aligned; + + /* check if the ring is padded out to 16-dword alignment */ + + tail_aligned = dev_priv->ring.tail & 0xf; + if (tail_aligned) { + int num_p2 = 16 - tail_aligned; + + ring = dev_priv->ring.start; + /* pad with some CP_PACKET2 */ + for (i = 0; i < num_p2; i++) + ring[dev_priv->ring.tail + i] = CP_PACKET2(); + + dev_priv->ring.tail += i; + + dev_priv->ring.space -= num_p2 * sizeof(u32); + } + + DRM_MEMORYBARRIER(); + GET_RING_HEAD( dev_priv ); + + RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); + /* read from PCI bus to ensure correct posting */ + RADEON_READ( RADEON_CP_RB_RPTR ); +} diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index a95ab152..828ad3f9 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -219,7 +219,6 @@ typedef struct drm_radeon_ring_buffer { int rptr_update; /* Double Words */ int rptr_update_l2qw; /* log2 Quad Words */ - int fetch_size; /* Double Words */ int fetch_size_l2ow; /* log2 Oct Words */ u32 tail; @@ -1515,15 +1514,16 @@ do { \ #define RADEON_VERBOSE 0 -#define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring; +#define RING_LOCALS int write, _nr, _align_nr; unsigned int mask; u32 *ring; #define BEGIN_RING( n ) do { \ if ( RADEON_VERBOSE ) { \ DRM_INFO( "BEGIN_RING( %d )\n", (n)); \ } \ - if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ + _align_nr = (n + 0xf) & ~0xf; \ + if (dev_priv->ring.space <= (_align_nr * sizeof(u32))) { \ COMMIT_RING(); \ - radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \ + radeon_wait_ring(dev_priv, _align_nr * sizeof(u32)); \ } \ _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ ring = dev_priv->ring.start; \ @@ -1540,19 +1540,14 @@ do { \ DRM_ERROR( \ "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \ ((dev_priv->ring.tail + _nr) & mask), \ - write, __LINE__); \ + write, __LINE__); \ } else \ dev_priv->ring.tail = write; \ } while (0) #define COMMIT_RING() do { \ - /* Flush writes to ring */ \ - DRM_MEMORYBARRIER(); \ - GET_RING_HEAD( dev_priv ); \ - RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \ - /* read from PCI bus to ensure correct posting */ \ - RADEON_READ( RADEON_CP_RB_RPTR ); \ -} while (0) + radeon_commit_ring(dev_priv); \ + } while(0) #define OUT_RING( x ) do { \ if ( RADEON_VERBOSE ) { \ @@ -1731,6 +1726,8 @@ extern void radeon_gem_proc_cleanup(struct drm_minor *minor); #define MARK_CHECK_OFFSET 2 #define MARK_CHECK_SCISSOR 3 +extern void radeon_commit_ring(drm_radeon_private_t *dev_priv); + extern int r300_check_range(unsigned reg, int count); extern int r300_get_reg_flags(unsigned reg); #endif /* __RADEON_DRV_H__ */ -- cgit v1.2.3 From 758376e6eb2155605ad502d0dc5147c74f3c47a6 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 10 Nov 2008 15:25:12 +1000 Subject: radeon: disable HDP read cache for now --- shared-core/radeon_cp.c | 3 +++ shared-core/radeon_drv.h | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 73192d03..a087829e 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2519,6 +2519,9 @@ int radeon_modeset_cp_init(struct drm_device *dev) r300_init_reg_flags(dev); + /* turn off HDP read cache for now */ + RADEON_WRITE(RADEON_HOST_PATH_CNTL, RADEON_READ(RADEON_HOST_PATH_CNTL) | RADEON_HP_LIN_RD_CACHE_DIS); + #if __OS_HAS_AGP if (dev_priv->flags & RADEON_IS_AGP) radeon_modeset_agp_init(dev); diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 828ad3f9..cd683795 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -791,8 +791,10 @@ int radeon_resume(struct drm_device *dev); # define R500_DISPLAY_INT_STATUS (1 << 0) #define RADEON_HOST_PATH_CNTL 0x0130 -# define RADEON_HDP_SOFT_RESET (1 << 26) # define RADEON_HDP_APER_CNTL (1 << 23) +# define RADEON_HP_LIN_RD_CACHE_DIS (1 << 24) +# define RADEON_HDP_SOFT_RESET (1 << 26) +# define RADEON_HDP_READ_BUFFER_INVALIDATED (1 << 27) #define RADEON_NB_TOM 0x15c -- cgit v1.2.3 From 994f2405030f7f595c4ec6bee524f7c06f27cd7b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 10 Nov 2008 15:25:27 +1000 Subject: radeon: fix ring tail overflow issue since alignment --- shared-core/radeon_cp.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'shared-core') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index a087829e..285bd4d7 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2863,6 +2863,8 @@ void radeon_commit_ring(drm_radeon_private_t *dev_priv) dev_priv->ring.space -= num_p2 * sizeof(u32); } + + dev_priv->ring.tail &= dev_priv->ring.tail_mask; DRM_MEMORYBARRIER(); GET_RING_HEAD( dev_priv ); -- cgit v1.2.3 From 15464f5181538d01e8fc016211daa1a824b89531 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 10 Nov 2008 15:38:32 +1000 Subject: radeon: add gart useable size to report to userspace --- shared-core/radeon_drv.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'shared-core') diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index cd683795..cf3084e1 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -274,6 +274,8 @@ struct radeon_mm_info { uint64_t gart_start; uint64_t gart_size; + uint64_t gart_useable; + void *pcie_table_backup; struct radeon_mm_obj pcie_table; -- cgit v1.2.3 From 13948c635d83285909e25ffd5285165789a598b2 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 12 Nov 2008 18:16:38 +0100 Subject: mode: Unify types for ids and strings --- shared-core/drm_mode.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm_mode.h b/shared-core/drm_mode.h index bd3d257e..f44c9a0d 100644 --- a/shared-core/drm_mode.h +++ b/shared-core/drm_mode.h @@ -109,8 +109,8 @@ struct drm_mode_crtc { uint64_t set_connectors_ptr; uint32_t count_connectors; - unsigned int crtc_id; /**< Id */ - unsigned int fb_id; /**< Id of framebuffer */ + uint32_t crtc_id; /**< Id */ + uint32_t fb_id; /**< Id of framebuffer */ uint32_t x, y; /**< Position on the frameuffer */ @@ -126,10 +126,10 @@ struct drm_mode_crtc { #define DRM_MODE_ENCODER_TVDAC 4 struct drm_mode_get_encoder { - unsigned int encoder_type; - unsigned int encoder_id; + uint32_t encoder_type; + uint32_t encoder_id; - unsigned int crtc_id; /**< Id of crtc */ + uint32_t crtc_id; /**< Id of crtc */ uint32_t possible_crtcs; uint32_t possible_clones; @@ -170,10 +170,10 @@ struct drm_mode_get_connector { uint32_t count_props; uint32_t count_encoders; - unsigned int encoder_id; /**< Current Encoder */ - unsigned int connector_id; /**< Id */ - unsigned int connector_type; - unsigned int connector_type_id; + uint32_t encoder_id; /**< Current Encoder */ + uint32_t connector_id; /**< Id */ + uint32_t connector_type; + uint32_t connector_type_id; uint32_t connection; uint32_t mm_width, mm_height; /**< HxW in millimeters */ @@ -188,16 +188,16 @@ struct drm_mode_get_connector { struct drm_mode_property_enum { uint64_t value; - unsigned char name[DRM_PROP_NAME_LEN]; + 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; + uint32_t prop_id; uint32_t flags; - unsigned char name[DRM_PROP_NAME_LEN]; + char name[DRM_PROP_NAME_LEN]; uint32_t count_values; uint32_t count_enum_blobs; @@ -205,8 +205,8 @@ struct drm_mode_get_property { struct drm_mode_connector_set_property { uint64_t value; - unsigned int prop_id; - unsigned int connector_id; + uint32_t prop_id; + uint32_t connector_id; }; struct drm_mode_get_blob { @@ -216,7 +216,7 @@ struct drm_mode_get_blob { }; struct drm_mode_fb_cmd { - unsigned int buffer_id; + uint32_t buffer_id; uint32_t width, height; uint32_t pitch; uint32_t bpp; @@ -226,7 +226,7 @@ struct drm_mode_fb_cmd { }; struct drm_mode_mode_cmd { - unsigned int connector_id; + uint32_t connector_id; struct drm_mode_modeinfo mode; }; @@ -249,7 +249,7 @@ struct drm_mode_mode_cmd { */ struct drm_mode_cursor { uint32_t flags; - unsigned int crtc_id; + uint32_t crtc_id; int32_t x; int32_t y; uint32_t width; @@ -266,7 +266,7 @@ struct drm_mode_hotplug { }; struct drm_mode_crtc_lut { - unsigned int crtc_id; + uint32_t crtc_id; uint32_t gamma_size; /* pointers to arrays */ -- cgit v1.2.3 From 1ead45c8f02e7c51cfe977383726d20479385688 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 12 Nov 2008 18:40:04 +0100 Subject: mode: Remove hotplug support from ioctl interface --- shared-core/drm.h | 33 --------------------------------- shared-core/drm_mode.h | 7 ------- 2 files changed, 40 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 42dad492..cc6aead4 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -555,37 +555,6 @@ union drm_wait_vblank { struct drm_wait_vblank_reply reply; }; -/* Handle monitor hotplug. - * - * May want to extend this later to pass reply information which - * details the connectors which generated the hotplug event. - * Some chipsets can't determine that though, and we'd need to leave - * it to the higher levels to determine exactly what changed. - */ -enum drm_hotplug_seq_type { - _DRM_HOTPLUG_SIGNAL = 0x00000001, /**< Send signal instead of blocking */ -}; -struct drm_wait_hotplug_request { - enum drm_hotplug_seq_type type; - unsigned long signal; -}; - -struct drm_wait_hotplug_reply { - enum drm_hotplug_seq_type type; - unsigned int counter; - long tval_sec; - long tval_usec; -}; - -/** - * DRM_IOCTL_WAIT_HOTPLUG ioctl argument type. - * - * \sa drmWaitHotplug(). - */ -union drm_wait_hotplug { - struct drm_wait_hotplug_request request; - struct drm_wait_hotplug_reply reply; -}; enum drm_modeset_ctl_cmd { _DRM_PRE_MODESET = 1, @@ -792,8 +761,6 @@ struct drm_gem_open { #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) -#define DRM_IOCTL_WAIT_HOTPLUG DRM_IOWR(0xAE, union drm_wait_hotplug) #define DRM_IOCTL_MODE_REPLACEFB DRM_IOWR(0xAF, struct drm_mode_fb_cmd) #define DRM_IOCTL_MODE_GETENCODER DRM_IOWR(0xB0, struct drm_mode_get_encoder) diff --git a/shared-core/drm_mode.h b/shared-core/drm_mode.h index f44c9a0d..6b1abd5b 100644 --- a/shared-core/drm_mode.h +++ b/shared-core/drm_mode.h @@ -258,13 +258,6 @@ struct drm_mode_cursor { uint32_t handle; }; -/* - * oh so ugly hotplug - */ -struct drm_mode_hotplug { - uint32_t counter; -}; - struct drm_mode_crtc_lut { uint32_t crtc_id; uint32_t gamma_size; -- cgit v1.2.3 From 17789a409d3e83cad9f5cf06c2bb7123b78746b2 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 12 Nov 2008 19:10:50 +0100 Subject: mode: Reorder the ioctls and numbering This is to fill in the gaps left by the removal of the hotplug ioctls. And they also look better :) --- shared-core/drm.h | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index cc6aead4..7419ad6e 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -747,25 +747,26 @@ struct drm_gem_open { #define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw) #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_GETCONNECTOR DRM_IOWR(0xA2, struct drm_mode_get_connector) -#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_connector_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_REPLACEFB DRM_IOWR(0xAF, struct drm_mode_fb_cmd) -#define DRM_IOCTL_MODE_GETENCODER DRM_IOWR(0xB0, struct drm_mode_get_encoder) -#define DRM_IOCTL_MODE_GETGAMMA DRM_IOWR(0xB1, struct drm_mode_crtc_lut) -#define DRM_IOCTL_MODE_SETGAMMA DRM_IOWR(0xB2, struct drm_mode_crtc_lut) +#define DRM_IOCTL_MODE_SETCRTC DRM_IOWR(0xA2, struct drm_mode_crtc) +#define DRM_IOCTL_MODE_CURSOR DRM_IOWR(0xA3, struct drm_mode_cursor) +#define DRM_IOCTL_MODE_GETGAMMA DRM_IOWR(0xA4, struct drm_mode_crtc_lut) +#define DRM_IOCTL_MODE_SETGAMMA DRM_IOWR(0xA5, struct drm_mode_crtc_lut) + +#define DRM_IOCTL_MODE_GETENCODER DRM_IOWR(0xA6, struct drm_mode_get_encoder) + +#define DRM_IOCTL_MODE_GETCONNECTOR DRM_IOWR(0xA7, struct drm_mode_get_connector) +#define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA8, struct drm_mode_mode_cmd) +#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd) +#define DRM_IOCTL_MODE_GETPROPERTY DRM_IOWR(0xAA, struct drm_mode_get_property) +#define DRM_IOCTL_MODE_SETPROPERTY DRM_IOWR(0xAB, struct drm_mode_connector_set_property) +#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xAC, struct drm_mode_get_blob) + +#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd) +#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd) +#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, uint32_t) +#define DRM_IOCTL_MODE_REPLACEFB DRM_IOWR(0xB0, struct drm_mode_fb_cmd) /*@}*/ -- cgit v1.2.3 From 9a4cb7eab4f74747cc777a3fef31dbb46e1191e5 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 12 Nov 2008 19:17:18 +0100 Subject: mode: Minor reodering and renaming --- shared-core/drm_mode.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm_mode.h b/shared-core/drm_mode.h index 6b1abd5b..601d2bd8 100644 --- a/shared-core/drm_mode.h +++ b/shared-core/drm_mode.h @@ -126,8 +126,8 @@ struct drm_mode_crtc { #define DRM_MODE_ENCODER_TVDAC 4 struct drm_mode_get_encoder { - uint32_t encoder_type; uint32_t encoder_id; + uint32_t encoder_type; uint32_t crtc_id; /**< Id of crtc */ @@ -216,13 +216,13 @@ struct drm_mode_get_blob { }; struct drm_mode_fb_cmd { - uint32_t buffer_id; + uint32_t fb_id; uint32_t width, height; uint32_t pitch; uint32_t bpp; - uint32_t handle; uint32_t depth; - + /* driver specific handle */ + uint32_t handle; }; struct drm_mode_mode_cmd { -- cgit v1.2.3 From 7270731a8b7ebe11fe6df4f368c2ed613a530b52 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sun, 16 Nov 2008 18:11:00 +0100 Subject: radeon: protect cs ioctl atomic part with a mutex A small subset of CS need to be atomic (relocation+IB commit to ring) right now, because of the way relocation are handled, we need to protect the whole ioctl. --- shared-core/radeon_cs.c | 6 ++++++ shared-core/radeon_drv.h | 1 + 2 files changed, 7 insertions(+) (limited to 'shared-core') diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index 56f6cbac..9227a011 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -41,21 +41,25 @@ int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) long size; int r, i; + mutex_lock(&dev_priv->cs.cs_mutex); /* set command stream id to 0 which is fake id */ cs_id = 0; cs->cs_id = cs_id; if (dev_priv == NULL) { DRM_ERROR("called with no initialization\n"); + mutex_unlock(&dev_priv->cs.cs_mutex); return -EINVAL; } if (!cs->num_chunks) { + mutex_unlock(&dev_priv->cs.cs_mutex); return 0; } chunk_array = drm_calloc(cs->num_chunks, sizeof(uint64_t), DRM_MEM_DRIVER); if (!chunk_array) { + mutex_unlock(&dev_priv->cs.cs_mutex); return -ENOMEM; } @@ -161,6 +165,7 @@ int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) out: dev_priv->cs.ib_free(&parser); + mutex_unlock(&dev_priv->cs.cs_mutex); for (i = 0; i < parser.num_chunks; i++) { if (parser.chunks[i].kdata) @@ -646,6 +651,7 @@ int radeon_cs_init(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; + mutex_init(&dev_priv->cs.cs_mutex); if (dev_priv->chip_family < CHIP_RV280) { dev_priv->cs.id_emit = r100_cs_id_emit; dev_priv->cs.id_last_get = r100_cs_id_last_get; diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index cf3084e1..fdf321d1 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -316,6 +316,7 @@ struct drm_radeon_cs_parser { /* command submission struct */ struct drm_radeon_cs_priv { + struct mutex cs_mutex; uint32_t id_wcnt; uint32_t id_scnt; uint32_t id_last_wcnt; -- cgit v1.2.3 From 5923831bafca3cf2358ffc7f8b0079ab4de9da5c Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 20 Nov 2008 10:57:33 -0800 Subject: DRM: make drm_map_type match kernel GEM is upstream, but TTM isn't, so _DRM_GEM needs to be 6, not 7. --- shared-core/drm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm.h b/shared-core/drm.h index 08882b76..218a469d 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -236,8 +236,8 @@ enum drm_map_type { _DRM_AGP = 3, /**< AGP/GART */ _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */ _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */ - _DRM_TTM = 6, - _DRM_GEM = 7, + _DRM_GEM = 6, + _DRM_TTM = 7, }; /** -- cgit v1.2.3