diff options
| -rw-r--r-- | drivers/char/drm/drm_pciids.h | 5 | ||||
| -rw-r--r-- | drivers/char/drm/i915_dma.c | 90 | ||||
| -rw-r--r-- | drivers/char/drm/i915_drm.h | 5 | ||||
| -rw-r--r-- | drivers/char/drm/i915_drv.h | 2 | ||||
| -rw-r--r-- | drivers/char/drm/radeon_ioc32.c | 26 |
5 files changed, 110 insertions, 18 deletions
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index 177ccc07f968..aa6335032d1e 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h | |||
| @@ -300,10 +300,15 @@ | |||
| 300 | {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 300 | {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
| 301 | {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 301 | {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
| 302 | {0x8086, 0x27a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 302 | {0x8086, 0x27a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
| 303 | {0x8086, 0x27ae, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | ||
| 303 | {0x8086, 0x2972, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 304 | {0x8086, 0x2972, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
| 304 | {0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 305 | {0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
| 305 | {0x8086, 0x2992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 306 | {0x8086, 0x2992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
| 306 | {0x8086, 0x29a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 307 | {0x8086, 0x29a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
| 308 | {0x8086, 0x29b2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | ||
| 309 | {0x8086, 0x29c2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | ||
| 310 | {0x8086, 0x29d2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | ||
| 307 | {0x8086, 0x2a02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 311 | {0x8086, 0x2a02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
| 312 | {0x8086, 0x2a12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | ||
| 308 | {0, 0, 0} | 313 | {0, 0, 0} |
| 309 | 314 | ||
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c index 1ba15d9a171a..ea52740af4f6 100644 --- a/drivers/char/drm/i915_dma.c +++ b/drivers/char/drm/i915_dma.c | |||
| @@ -35,7 +35,12 @@ | |||
| 35 | dev->pci_device == 0x2982 || \ | 35 | dev->pci_device == 0x2982 || \ |
| 36 | dev->pci_device == 0x2992 || \ | 36 | dev->pci_device == 0x2992 || \ |
| 37 | dev->pci_device == 0x29A2 || \ | 37 | dev->pci_device == 0x29A2 || \ |
| 38 | dev->pci_device == 0x2A02) | 38 | dev->pci_device == 0x2A02 || \ |
| 39 | dev->pci_device == 0x2A12) | ||
| 40 | |||
| 41 | #define IS_G33(dev) (dev->pci_device == 0x29b2 || \ | ||
| 42 | dev->pci_device == 0x29c2 || \ | ||
| 43 | dev->pci_device == 0x29d2) | ||
| 39 | 44 | ||
| 40 | /* Really want an OS-independent resettable timer. Would like to have | 45 | /* Really want an OS-independent resettable timer. Would like to have |
| 41 | * this loop run for (eg) 3 sec, but have the timer reset every time | 46 | * this loop run for (eg) 3 sec, but have the timer reset every time |
| @@ -106,6 +111,12 @@ static int i915_dma_cleanup(drm_device_t * dev) | |||
| 106 | I915_WRITE(0x02080, 0x1ffff000); | 111 | I915_WRITE(0x02080, 0x1ffff000); |
| 107 | } | 112 | } |
| 108 | 113 | ||
| 114 | if (dev_priv->status_gfx_addr) { | ||
| 115 | dev_priv->status_gfx_addr = 0; | ||
| 116 | drm_core_ioremapfree(&dev_priv->hws_map, dev); | ||
| 117 | I915_WRITE(0x2080, 0x1ffff000); | ||
| 118 | } | ||
| 119 | |||
| 109 | drm_free(dev->dev_private, sizeof(drm_i915_private_t), | 120 | drm_free(dev->dev_private, sizeof(drm_i915_private_t), |
| 110 | DRM_MEM_DRIVER); | 121 | DRM_MEM_DRIVER); |
| 111 | 122 | ||
| @@ -179,26 +190,24 @@ static int i915_initialize(drm_device_t * dev, | |||
| 179 | dev_priv->allow_batchbuffer = 1; | 190 | dev_priv->allow_batchbuffer = 1; |
| 180 | 191 | ||
| 181 | /* Program Hardware Status Page */ | 192 | /* Program Hardware Status Page */ |
| 182 | dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, | 193 | if (!IS_G33(dev)) { |
| 183 | 0xffffffff); | 194 | dev_priv->status_page_dmah = |
| 195 | drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); | ||
| 196 | |||
| 197 | if (!dev_priv->status_page_dmah) { | ||
| 198 | dev->dev_private = (void *)dev_priv; | ||
| 199 | i915_dma_cleanup(dev); | ||
| 200 | DRM_ERROR("Can not allocate hardware status page\n"); | ||
| 201 | return DRM_ERR(ENOMEM); | ||
| 202 | } | ||
| 203 | dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; | ||
| 204 | dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; | ||
| 184 | 205 | ||
| 185 | if (!dev_priv->status_page_dmah) { | 206 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); |
| 186 | dev->dev_private = (void *)dev_priv; | 207 | I915_WRITE(0x02080, dev_priv->dma_status_page); |
| 187 | i915_dma_cleanup(dev); | ||
| 188 | DRM_ERROR("Can not allocate hardware status page\n"); | ||
| 189 | return DRM_ERR(ENOMEM); | ||
| 190 | } | 208 | } |
| 191 | dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; | ||
| 192 | dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; | ||
| 193 | |||
| 194 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); | ||
| 195 | DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); | ||
| 196 | |||
| 197 | I915_WRITE(0x02080, dev_priv->dma_status_page); | ||
| 198 | DRM_DEBUG("Enabled hardware status page\n"); | 209 | DRM_DEBUG("Enabled hardware status page\n"); |
| 199 | |||
| 200 | dev->dev_private = (void *)dev_priv; | 210 | dev->dev_private = (void *)dev_priv; |
| 201 | |||
| 202 | return 0; | 211 | return 0; |
| 203 | } | 212 | } |
| 204 | 213 | ||
| @@ -231,7 +240,10 @@ static int i915_dma_resume(drm_device_t * dev) | |||
| 231 | } | 240 | } |
| 232 | DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); | 241 | DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); |
| 233 | 242 | ||
| 234 | I915_WRITE(0x02080, dev_priv->dma_status_page); | 243 | if (dev_priv->status_gfx_addr != 0) |
| 244 | I915_WRITE(0x02080, dev_priv->status_gfx_addr); | ||
| 245 | else | ||
| 246 | I915_WRITE(0x02080, dev_priv->dma_status_page); | ||
| 235 | DRM_DEBUG("Enabled hardware status page\n"); | 247 | DRM_DEBUG("Enabled hardware status page\n"); |
| 236 | 248 | ||
| 237 | return 0; | 249 | return 0; |
| @@ -739,6 +751,47 @@ static int i915_setparam(DRM_IOCTL_ARGS) | |||
| 739 | return 0; | 751 | return 0; |
| 740 | } | 752 | } |
| 741 | 753 | ||
| 754 | static int i915_set_status_page(DRM_IOCTL_ARGS) | ||
| 755 | { | ||
| 756 | DRM_DEVICE; | ||
| 757 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 758 | drm_i915_hws_addr_t hws; | ||
| 759 | |||
| 760 | if (!dev_priv) { | ||
| 761 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
| 762 | return DRM_ERR(EINVAL); | ||
| 763 | } | ||
| 764 | DRM_COPY_FROM_USER_IOCTL(hws, (drm_i915_hws_addr_t __user *) data, | ||
| 765 | sizeof(hws)); | ||
| 766 | printk(KERN_DEBUG "set status page addr 0x%08x\n", (u32)hws.addr); | ||
| 767 | |||
| 768 | dev_priv->status_gfx_addr = hws.addr & (0x1ffff<<12); | ||
| 769 | |||
| 770 | dev_priv->hws_map.offset = dev->agp->agp_info.aper_base + hws.addr; | ||
| 771 | dev_priv->hws_map.size = 4*1024; | ||
| 772 | dev_priv->hws_map.type = 0; | ||
| 773 | dev_priv->hws_map.flags = 0; | ||
| 774 | dev_priv->hws_map.mtrr = 0; | ||
| 775 | |||
| 776 | drm_core_ioremap(&dev_priv->hws_map, dev); | ||
| 777 | if (dev_priv->hws_map.handle == NULL) { | ||
| 778 | dev->dev_private = (void *)dev_priv; | ||
| 779 | i915_dma_cleanup(dev); | ||
| 780 | dev_priv->status_gfx_addr = 0; | ||
| 781 | DRM_ERROR("can not ioremap virtual address for" | ||
| 782 | " G33 hw status page\n"); | ||
| 783 | return DRM_ERR(ENOMEM); | ||
| 784 | } | ||
| 785 | dev_priv->hw_status_page = dev_priv->hws_map.handle; | ||
| 786 | |||
| 787 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); | ||
| 788 | I915_WRITE(0x02080, dev_priv->status_gfx_addr); | ||
| 789 | DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n", | ||
| 790 | dev_priv->status_gfx_addr); | ||
| 791 | DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page); | ||
| 792 | return 0; | ||
| 793 | } | ||
| 794 | |||
| 742 | int i915_driver_load(drm_device_t *dev, unsigned long flags) | 795 | int i915_driver_load(drm_device_t *dev, unsigned long flags) |
| 743 | { | 796 | { |
| 744 | /* i915 has 4 more counters */ | 797 | /* i915 has 4 more counters */ |
| @@ -785,6 +838,7 @@ drm_ioctl_desc_t i915_ioctls[] = { | |||
| 785 | [DRM_IOCTL_NR(DRM_I915_SET_VBLANK_PIPE)] = { i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, | 838 | [DRM_IOCTL_NR(DRM_I915_SET_VBLANK_PIPE)] = { i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, |
| 786 | [DRM_IOCTL_NR(DRM_I915_GET_VBLANK_PIPE)] = { i915_vblank_pipe_get, DRM_AUTH }, | 839 | [DRM_IOCTL_NR(DRM_I915_GET_VBLANK_PIPE)] = { i915_vblank_pipe_get, DRM_AUTH }, |
| 787 | [DRM_IOCTL_NR(DRM_I915_VBLANK_SWAP)] = {i915_vblank_swap, DRM_AUTH}, | 840 | [DRM_IOCTL_NR(DRM_I915_VBLANK_SWAP)] = {i915_vblank_swap, DRM_AUTH}, |
| 841 | [DRM_IOCTL_NR(DRM_I915_HWS_ADDR)] = {i915_set_status_page, DRM_AUTH}, | ||
| 788 | }; | 842 | }; |
| 789 | 843 | ||
| 790 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); | 844 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); |
diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h index 96a468886a7a..7b7b68b96f31 100644 --- a/drivers/char/drm/i915_drm.h +++ b/drivers/char/drm/i915_drm.h | |||
| @@ -142,6 +142,7 @@ typedef struct _drm_i915_sarea { | |||
| 142 | #define DRM_I915_SET_VBLANK_PIPE 0x0d | 142 | #define DRM_I915_SET_VBLANK_PIPE 0x0d |
| 143 | #define DRM_I915_GET_VBLANK_PIPE 0x0e | 143 | #define DRM_I915_GET_VBLANK_PIPE 0x0e |
| 144 | #define DRM_I915_VBLANK_SWAP 0x0f | 144 | #define DRM_I915_VBLANK_SWAP 0x0f |
| 145 | #define DRM_I915_HWS_ADDR 0x11 | ||
| 145 | 146 | ||
| 146 | #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) | 147 | #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) |
| 147 | #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) | 148 | #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) |
| @@ -262,4 +263,8 @@ typedef struct drm_i915_vblank_swap { | |||
| 262 | unsigned int sequence; | 263 | unsigned int sequence; |
| 263 | } drm_i915_vblank_swap_t; | 264 | } drm_i915_vblank_swap_t; |
| 264 | 265 | ||
| 266 | typedef struct drm_i915_hws_addr { | ||
| 267 | uint64_t addr; | ||
| 268 | } drm_i915_hws_addr_t; | ||
| 269 | |||
| 265 | #endif /* _I915_DRM_H_ */ | 270 | #endif /* _I915_DRM_H_ */ |
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index 93cdcfe6aa84..85e323acb95d 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h | |||
| @@ -91,6 +91,8 @@ typedef struct drm_i915_private { | |||
| 91 | void *hw_status_page; | 91 | void *hw_status_page; |
| 92 | dma_addr_t dma_status_page; | 92 | dma_addr_t dma_status_page; |
| 93 | unsigned long counter; | 93 | unsigned long counter; |
| 94 | unsigned int status_gfx_addr; | ||
| 95 | drm_local_map_t hws_map; | ||
| 94 | 96 | ||
| 95 | unsigned int cpp; | 97 | unsigned int cpp; |
| 96 | int back_offset; | 98 | int back_offset; |
diff --git a/drivers/char/drm/radeon_ioc32.c b/drivers/char/drm/radeon_ioc32.c index 1f1f9cc055a4..04126c2e79ab 100644 --- a/drivers/char/drm/radeon_ioc32.c +++ b/drivers/char/drm/radeon_ioc32.c | |||
| @@ -349,6 +349,31 @@ static int compat_radeon_irq_emit(struct file *file, unsigned int cmd, | |||
| 349 | DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request); | 349 | DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request); |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | typedef struct drm_radeon_setparam32 { | ||
| 353 | int param; | ||
| 354 | u64 value; | ||
| 355 | } __attribute__((packed)) drm_radeon_setparam32_t; | ||
| 356 | |||
| 357 | static int compat_radeon_cp_setparam(struct file *file, unsigned int cmd, | ||
| 358 | unsigned long arg) | ||
| 359 | { | ||
| 360 | drm_radeon_setparam32_t req32; | ||
| 361 | drm_radeon_setparam_t __user *request; | ||
| 362 | |||
| 363 | if (copy_from_user(&req32, (void __user *) arg, sizeof(req32))) | ||
| 364 | return -EFAULT; | ||
| 365 | |||
| 366 | request = compat_alloc_user_space(sizeof(*request)); | ||
| 367 | if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) | ||
| 368 | || __put_user(req32.param, &request->param) | ||
| 369 | || __put_user((void __user *)(unsigned long)req32.value, | ||
| 370 | &request->value)) | ||
| 371 | return -EFAULT; | ||
| 372 | |||
| 373 | return drm_ioctl(file->f_dentry->d_inode, file, | ||
| 374 | DRM_IOCTL_RADEON_SETPARAM, (unsigned long) request); | ||
| 375 | } | ||
| 376 | |||
| 352 | drm_ioctl_compat_t *radeon_compat_ioctls[] = { | 377 | drm_ioctl_compat_t *radeon_compat_ioctls[] = { |
| 353 | [DRM_RADEON_CP_INIT] = compat_radeon_cp_init, | 378 | [DRM_RADEON_CP_INIT] = compat_radeon_cp_init, |
| 354 | [DRM_RADEON_CLEAR] = compat_radeon_cp_clear, | 379 | [DRM_RADEON_CLEAR] = compat_radeon_cp_clear, |
| @@ -357,6 +382,7 @@ drm_ioctl_compat_t *radeon_compat_ioctls[] = { | |||
| 357 | [DRM_RADEON_VERTEX2] = compat_radeon_cp_vertex2, | 382 | [DRM_RADEON_VERTEX2] = compat_radeon_cp_vertex2, |
| 358 | [DRM_RADEON_CMDBUF] = compat_radeon_cp_cmdbuf, | 383 | [DRM_RADEON_CMDBUF] = compat_radeon_cp_cmdbuf, |
| 359 | [DRM_RADEON_GETPARAM] = compat_radeon_cp_getparam, | 384 | [DRM_RADEON_GETPARAM] = compat_radeon_cp_getparam, |
| 385 | [DRM_RADEON_SETPARAM] = compat_radeon_cp_setparam, | ||
| 360 | [DRM_RADEON_ALLOC] = compat_radeon_mem_alloc, | 386 | [DRM_RADEON_ALLOC] = compat_radeon_mem_alloc, |
| 361 | [DRM_RADEON_IRQ_EMIT] = compat_radeon_irq_emit, | 387 | [DRM_RADEON_IRQ_EMIT] = compat_radeon_irq_emit, |
| 362 | }; | 388 | }; |
