diff options
| author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2012-05-21 15:39:42 -0400 |
|---|---|---|
| committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2012-05-21 15:39:42 -0400 |
| commit | 0ad8c6a22d03a1598f7cc6585c65354dadca62ad (patch) | |
| tree | 1507deef3d55d5f3c71b2f76924fe1f6c6211905 /drivers/gpu | |
| parent | 8527f8e2934683e53405fbe876a4e6f4a0c46eb8 (diff) | |
| parent | 76e10d158efb6d4516018846f60c2ab5501900bc (diff) | |
Merge tag 'v3.4' with SCSI updates, needed for subsequent firewire-sbp2 changes
Linux 3.4
Diffstat (limited to 'drivers/gpu')
61 files changed, 512 insertions, 555 deletions
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 30372f7b2d45..348b367debeb 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c | |||
| @@ -1510,8 +1510,8 @@ int drm_freebufs(struct drm_device *dev, void *data, | |||
| 1510 | * \param arg pointer to a drm_buf_map structure. | 1510 | * \param arg pointer to a drm_buf_map structure. |
| 1511 | * \return zero on success or a negative number on failure. | 1511 | * \return zero on success or a negative number on failure. |
| 1512 | * | 1512 | * |
| 1513 | * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information | 1513 | * Maps the AGP, SG or PCI buffer region with vm_mmap(), and copies information |
| 1514 | * about each buffer into user space. For PCI buffers, it calls do_mmap() with | 1514 | * about each buffer into user space. For PCI buffers, it calls vm_mmap() with |
| 1515 | * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls | 1515 | * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls |
| 1516 | * drm_mmap_dma(). | 1516 | * drm_mmap_dma(). |
| 1517 | */ | 1517 | */ |
| @@ -1553,18 +1553,14 @@ int drm_mapbufs(struct drm_device *dev, void *data, | |||
| 1553 | retcode = -EINVAL; | 1553 | retcode = -EINVAL; |
| 1554 | goto done; | 1554 | goto done; |
| 1555 | } | 1555 | } |
| 1556 | down_write(¤t->mm->mmap_sem); | 1556 | virtual = vm_mmap(file_priv->filp, 0, map->size, |
| 1557 | virtual = do_mmap(file_priv->filp, 0, map->size, | ||
| 1558 | PROT_READ | PROT_WRITE, | 1557 | PROT_READ | PROT_WRITE, |
| 1559 | MAP_SHARED, | 1558 | MAP_SHARED, |
| 1560 | token); | 1559 | token); |
| 1561 | up_write(¤t->mm->mmap_sem); | ||
| 1562 | } else { | 1560 | } else { |
| 1563 | down_write(¤t->mm->mmap_sem); | 1561 | virtual = vm_mmap(file_priv->filp, 0, dma->byte_count, |
| 1564 | virtual = do_mmap(file_priv->filp, 0, dma->byte_count, | ||
| 1565 | PROT_READ | PROT_WRITE, | 1562 | PROT_READ | PROT_WRITE, |
| 1566 | MAP_SHARED, 0); | 1563 | MAP_SHARED, 0); |
| 1567 | up_write(¤t->mm->mmap_sem); | ||
| 1568 | } | 1564 | } |
| 1569 | if (virtual > -1024UL) { | 1565 | if (virtual > -1024UL) { |
| 1570 | /* Real error */ | 1566 | /* Real error */ |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index d3aaeb6ae236..c79870a75c2f 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
| @@ -3335,10 +3335,12 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, | |||
| 3335 | 3335 | ||
| 3336 | ret = crtc->funcs->page_flip(crtc, fb, e); | 3336 | ret = crtc->funcs->page_flip(crtc, fb, e); |
| 3337 | if (ret) { | 3337 | if (ret) { |
| 3338 | spin_lock_irqsave(&dev->event_lock, flags); | 3338 | if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { |
| 3339 | file_priv->event_space += sizeof e->event; | 3339 | spin_lock_irqsave(&dev->event_lock, flags); |
| 3340 | spin_unlock_irqrestore(&dev->event_lock, flags); | 3340 | file_priv->event_space += sizeof e->event; |
| 3341 | kfree(e); | 3341 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 3342 | kfree(e); | ||
| 3343 | } | ||
| 3342 | } | 3344 | } |
| 3343 | 3345 | ||
| 3344 | out: | 3346 | out: |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index cdfbf27b2b3c..123de28f94ef 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
| @@ -507,12 +507,12 @@ int drm_release(struct inode *inode, struct file *filp) | |||
| 507 | 507 | ||
| 508 | drm_events_release(file_priv); | 508 | drm_events_release(file_priv); |
| 509 | 509 | ||
| 510 | if (dev->driver->driver_features & DRIVER_GEM) | ||
| 511 | drm_gem_release(dev, file_priv); | ||
| 512 | |||
| 513 | if (dev->driver->driver_features & DRIVER_MODESET) | 510 | if (dev->driver->driver_features & DRIVER_MODESET) |
| 514 | drm_fb_release(file_priv); | 511 | drm_fb_release(file_priv); |
| 515 | 512 | ||
| 513 | if (dev->driver->driver_features & DRIVER_GEM) | ||
| 514 | drm_gem_release(dev, file_priv); | ||
| 515 | |||
| 516 | mutex_lock(&dev->ctxlist_mutex); | 516 | mutex_lock(&dev->ctxlist_mutex); |
| 517 | if (!list_empty(&dev->ctxlist)) { | 517 | if (!list_empty(&dev->ctxlist)) { |
| 518 | struct drm_ctx_list *pos, *n; | 518 | struct drm_ctx_list *pos, *n; |
diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c index c8c83dad2ce1..37c9a523dd1c 100644 --- a/drivers/gpu/drm/drm_usb.c +++ b/drivers/gpu/drm/drm_usb.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | #include "drmP.h" | 1 | #include "drmP.h" |
| 2 | #include <linux/usb.h> | 2 | #include <linux/usb.h> |
| 3 | #include <linux/export.h> | 3 | #include <linux/module.h> |
| 4 | 4 | ||
| 5 | int drm_get_usb_dev(struct usb_interface *interface, | 5 | int drm_get_usb_dev(struct usb_interface *interface, |
| 6 | const struct usb_device_id *id, | 6 | const struct usb_device_id *id, |
| @@ -114,3 +114,7 @@ void drm_usb_exit(struct drm_driver *driver, | |||
| 114 | usb_deregister(udriver); | 114 | usb_deregister(udriver); |
| 115 | } | 115 | } |
| 116 | EXPORT_SYMBOL(drm_usb_exit); | 116 | EXPORT_SYMBOL(drm_usb_exit); |
| 117 | |||
| 118 | MODULE_AUTHOR("David Airlie"); | ||
| 119 | MODULE_DESCRIPTION("USB DRM support"); | ||
| 120 | MODULE_LICENSE("GPL and additional rights"); | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c index 4a3a5f72ed4a..de8d2090bce3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_buf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c | |||
| @@ -34,14 +34,14 @@ | |||
| 34 | static int lowlevel_buffer_allocate(struct drm_device *dev, | 34 | static int lowlevel_buffer_allocate(struct drm_device *dev, |
| 35 | unsigned int flags, struct exynos_drm_gem_buf *buf) | 35 | unsigned int flags, struct exynos_drm_gem_buf *buf) |
| 36 | { | 36 | { |
| 37 | dma_addr_t start_addr, end_addr; | 37 | dma_addr_t start_addr; |
| 38 | unsigned int npages, page_size, i = 0; | 38 | unsigned int npages, page_size, i = 0; |
| 39 | struct scatterlist *sgl; | 39 | struct scatterlist *sgl; |
| 40 | int ret = 0; | 40 | int ret = 0; |
| 41 | 41 | ||
| 42 | DRM_DEBUG_KMS("%s\n", __FILE__); | 42 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 43 | 43 | ||
| 44 | if (flags & EXYNOS_BO_NONCONTIG) { | 44 | if (IS_NONCONTIG_BUFFER(flags)) { |
| 45 | DRM_DEBUG_KMS("not support allocation type.\n"); | 45 | DRM_DEBUG_KMS("not support allocation type.\n"); |
| 46 | return -EINVAL; | 46 | return -EINVAL; |
| 47 | } | 47 | } |
| @@ -52,13 +52,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, | |||
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | if (buf->size >= SZ_1M) { | 54 | if (buf->size >= SZ_1M) { |
| 55 | npages = (buf->size >> SECTION_SHIFT) + 1; | 55 | npages = buf->size >> SECTION_SHIFT; |
| 56 | page_size = SECTION_SIZE; | 56 | page_size = SECTION_SIZE; |
| 57 | } else if (buf->size >= SZ_64K) { | 57 | } else if (buf->size >= SZ_64K) { |
| 58 | npages = (buf->size >> 16) + 1; | 58 | npages = buf->size >> 16; |
| 59 | page_size = SZ_64K; | 59 | page_size = SZ_64K; |
| 60 | } else { | 60 | } else { |
| 61 | npages = (buf->size >> PAGE_SHIFT) + 1; | 61 | npages = buf->size >> PAGE_SHIFT; |
| 62 | page_size = PAGE_SIZE; | 62 | page_size = PAGE_SIZE; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| @@ -76,26 +76,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, | |||
| 76 | return -ENOMEM; | 76 | return -ENOMEM; |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size, | 79 | buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size, |
| 80 | &buf->dma_addr, GFP_KERNEL); | 80 | &buf->dma_addr, GFP_KERNEL); |
| 81 | if (!buf->kvaddr) { | 81 | if (!buf->kvaddr) { |
| 82 | DRM_ERROR("failed to allocate buffer.\n"); | 82 | DRM_ERROR("failed to allocate buffer.\n"); |
| 83 | ret = -ENOMEM; | 83 | ret = -ENOMEM; |
| 84 | goto err1; | 84 | goto err1; |
| 85 | } | 85 | } |
| 86 | |||
| 87 | start_addr = buf->dma_addr; | ||
| 88 | end_addr = buf->dma_addr + buf->size; | ||
| 89 | |||
| 90 | buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL); | ||
| 91 | if (!buf->pages) { | ||
| 92 | DRM_ERROR("failed to allocate pages.\n"); | ||
| 93 | ret = -ENOMEM; | ||
| 94 | goto err2; | ||
| 95 | } | ||
| 96 | |||
| 97 | start_addr = buf->dma_addr; | ||
| 98 | end_addr = buf->dma_addr + buf->size; | ||
| 99 | 86 | ||
| 100 | buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL); | 87 | buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL); |
| 101 | if (!buf->pages) { | 88 | if (!buf->pages) { |
| @@ -105,23 +92,17 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, | |||
| 105 | } | 92 | } |
| 106 | 93 | ||
| 107 | sgl = buf->sgt->sgl; | 94 | sgl = buf->sgt->sgl; |
| 95 | start_addr = buf->dma_addr; | ||
| 108 | 96 | ||
| 109 | while (i < npages) { | 97 | while (i < npages) { |
| 110 | buf->pages[i] = phys_to_page(start_addr); | 98 | buf->pages[i] = phys_to_page(start_addr); |
| 111 | sg_set_page(sgl, buf->pages[i], page_size, 0); | 99 | sg_set_page(sgl, buf->pages[i], page_size, 0); |
| 112 | sg_dma_address(sgl) = start_addr; | 100 | sg_dma_address(sgl) = start_addr; |
| 113 | start_addr += page_size; | 101 | start_addr += page_size; |
| 114 | if (end_addr - start_addr < page_size) | ||
| 115 | break; | ||
| 116 | sgl = sg_next(sgl); | 102 | sgl = sg_next(sgl); |
| 117 | i++; | 103 | i++; |
| 118 | } | 104 | } |
| 119 | 105 | ||
| 120 | buf->pages[i] = phys_to_page(start_addr); | ||
| 121 | |||
| 122 | sgl = sg_next(sgl); | ||
| 123 | sg_set_page(sgl, buf->pages[i+1], end_addr - start_addr, 0); | ||
| 124 | |||
| 125 | DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", | 106 | DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", |
| 126 | (unsigned long)buf->kvaddr, | 107 | (unsigned long)buf->kvaddr, |
| 127 | (unsigned long)buf->dma_addr, | 108 | (unsigned long)buf->dma_addr, |
| @@ -150,7 +131,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev, | |||
| 150 | * non-continuous memory would be released by exynos | 131 | * non-continuous memory would be released by exynos |
| 151 | * gem framework. | 132 | * gem framework. |
| 152 | */ | 133 | */ |
| 153 | if (flags & EXYNOS_BO_NONCONTIG) { | 134 | if (IS_NONCONTIG_BUFFER(flags)) { |
| 154 | DRM_DEBUG_KMS("not support allocation type.\n"); | 135 | DRM_DEBUG_KMS("not support allocation type.\n"); |
| 155 | return; | 136 | return; |
| 156 | } | 137 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c index 411832e8e17a..eaf630dc5dba 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_core.c +++ b/drivers/gpu/drm/exynos/exynos_drm_core.c | |||
| @@ -54,16 +54,18 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev, | |||
| 54 | * | 54 | * |
| 55 | * P.S. note that this driver is considered for modularization. | 55 | * P.S. note that this driver is considered for modularization. |
| 56 | */ | 56 | */ |
| 57 | ret = subdrv->probe(dev, subdrv->manager.dev); | 57 | ret = subdrv->probe(dev, subdrv->dev); |
| 58 | if (ret) | 58 | if (ret) |
| 59 | return ret; | 59 | return ret; |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | if (subdrv->is_local) | 62 | if (!subdrv->manager) |
| 63 | return 0; | 63 | return 0; |
| 64 | 64 | ||
| 65 | subdrv->manager->dev = subdrv->dev; | ||
| 66 | |||
| 65 | /* create and initialize a encoder for this sub driver. */ | 67 | /* create and initialize a encoder for this sub driver. */ |
| 66 | encoder = exynos_drm_encoder_create(dev, &subdrv->manager, | 68 | encoder = exynos_drm_encoder_create(dev, subdrv->manager, |
| 67 | (1 << MAX_CRTC) - 1); | 69 | (1 << MAX_CRTC) - 1); |
| 68 | if (!encoder) { | 70 | if (!encoder) { |
| 69 | DRM_ERROR("failed to create encoder\n"); | 71 | DRM_ERROR("failed to create encoder\n"); |
| @@ -186,7 +188,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file) | |||
| 186 | 188 | ||
| 187 | list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { | 189 | list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { |
| 188 | if (subdrv->open) { | 190 | if (subdrv->open) { |
| 189 | ret = subdrv->open(dev, subdrv->manager.dev, file); | 191 | ret = subdrv->open(dev, subdrv->dev, file); |
| 190 | if (ret) | 192 | if (ret) |
| 191 | goto err; | 193 | goto err; |
| 192 | } | 194 | } |
| @@ -197,7 +199,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file) | |||
| 197 | err: | 199 | err: |
| 198 | list_for_each_entry_reverse(subdrv, &subdrv->list, list) { | 200 | list_for_each_entry_reverse(subdrv, &subdrv->list, list) { |
| 199 | if (subdrv->close) | 201 | if (subdrv->close) |
| 200 | subdrv->close(dev, subdrv->manager.dev, file); | 202 | subdrv->close(dev, subdrv->dev, file); |
| 201 | } | 203 | } |
| 202 | return ret; | 204 | return ret; |
| 203 | } | 205 | } |
| @@ -209,7 +211,7 @@ void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file) | |||
| 209 | 211 | ||
| 210 | list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { | 212 | list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { |
| 211 | if (subdrv->close) | 213 | if (subdrv->close) |
| 212 | subdrv->close(dev, subdrv->manager.dev, file); | 214 | subdrv->close(dev, subdrv->dev, file); |
| 213 | } | 215 | } |
| 214 | } | 216 | } |
| 215 | EXPORT_SYMBOL_GPL(exynos_drm_subdrv_close); | 217 | EXPORT_SYMBOL_GPL(exynos_drm_subdrv_close); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index fbd0a232c93d..1d814175cd49 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h | |||
| @@ -225,24 +225,25 @@ struct exynos_drm_private { | |||
| 225 | * Exynos drm sub driver structure. | 225 | * Exynos drm sub driver structure. |
| 226 | * | 226 | * |
| 227 | * @list: sub driver has its own list object to register to exynos drm driver. | 227 | * @list: sub driver has its own list object to register to exynos drm driver. |
| 228 | * @dev: pointer to device object for subdrv device driver. | ||
| 228 | * @drm_dev: pointer to drm_device and this pointer would be set | 229 | * @drm_dev: pointer to drm_device and this pointer would be set |
| 229 | * when sub driver calls exynos_drm_subdrv_register(). | 230 | * when sub driver calls exynos_drm_subdrv_register(). |
| 230 | * @is_local: appear encoder and connector disrelated device. | 231 | * @manager: subdrv has its own manager to control a hardware appropriately |
| 232 | * and we can access a hardware drawing on this manager. | ||
| 231 | * @probe: this callback would be called by exynos drm driver after | 233 | * @probe: this callback would be called by exynos drm driver after |
| 232 | * subdrv is registered to it. | 234 | * subdrv is registered to it. |
| 233 | * @remove: this callback is used to release resources created | 235 | * @remove: this callback is used to release resources created |
| 234 | * by probe callback. | 236 | * by probe callback. |
| 235 | * @open: this would be called with drm device file open. | 237 | * @open: this would be called with drm device file open. |
| 236 | * @close: this would be called with drm device file close. | 238 | * @close: this would be called with drm device file close. |
| 237 | * @manager: subdrv has its own manager to control a hardware appropriately | ||
| 238 | * and we can access a hardware drawing on this manager. | ||
| 239 | * @encoder: encoder object owned by this sub driver. | 239 | * @encoder: encoder object owned by this sub driver. |
| 240 | * @connector: connector object owned by this sub driver. | 240 | * @connector: connector object owned by this sub driver. |
| 241 | */ | 241 | */ |
| 242 | struct exynos_drm_subdrv { | 242 | struct exynos_drm_subdrv { |
| 243 | struct list_head list; | 243 | struct list_head list; |
| 244 | struct device *dev; | ||
| 244 | struct drm_device *drm_dev; | 245 | struct drm_device *drm_dev; |
| 245 | bool is_local; | 246 | struct exynos_drm_manager *manager; |
| 246 | 247 | ||
| 247 | int (*probe)(struct drm_device *drm_dev, struct device *dev); | 248 | int (*probe)(struct drm_device *drm_dev, struct device *dev); |
| 248 | void (*remove)(struct drm_device *dev); | 249 | void (*remove)(struct drm_device *dev); |
| @@ -251,7 +252,6 @@ struct exynos_drm_subdrv { | |||
| 251 | void (*close)(struct drm_device *drm_dev, struct device *dev, | 252 | void (*close)(struct drm_device *drm_dev, struct device *dev, |
| 252 | struct drm_file *file); | 253 | struct drm_file *file); |
| 253 | 254 | ||
| 254 | struct exynos_drm_manager manager; | ||
| 255 | struct drm_encoder *encoder; | 255 | struct drm_encoder *encoder; |
| 256 | struct drm_connector *connector; | 256 | struct drm_connector *connector; |
| 257 | }; | 257 | }; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index ecb6db229700..29fdbfeb43cb 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
| @@ -172,7 +172,7 @@ static void fimd_dpms(struct device *subdrv_dev, int mode) | |||
| 172 | static void fimd_apply(struct device *subdrv_dev) | 172 | static void fimd_apply(struct device *subdrv_dev) |
| 173 | { | 173 | { |
| 174 | struct fimd_context *ctx = get_fimd_context(subdrv_dev); | 174 | struct fimd_context *ctx = get_fimd_context(subdrv_dev); |
| 175 | struct exynos_drm_manager *mgr = &ctx->subdrv.manager; | 175 | struct exynos_drm_manager *mgr = ctx->subdrv.manager; |
| 176 | struct exynos_drm_manager_ops *mgr_ops = mgr->ops; | 176 | struct exynos_drm_manager_ops *mgr_ops = mgr->ops; |
| 177 | struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops; | 177 | struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops; |
| 178 | struct fimd_win_data *win_data; | 178 | struct fimd_win_data *win_data; |
| @@ -577,6 +577,13 @@ static struct exynos_drm_overlay_ops fimd_overlay_ops = { | |||
| 577 | .disable = fimd_win_disable, | 577 | .disable = fimd_win_disable, |
| 578 | }; | 578 | }; |
| 579 | 579 | ||
| 580 | static struct exynos_drm_manager fimd_manager = { | ||
| 581 | .pipe = -1, | ||
| 582 | .ops = &fimd_manager_ops, | ||
| 583 | .overlay_ops = &fimd_overlay_ops, | ||
| 584 | .display_ops = &fimd_display_ops, | ||
| 585 | }; | ||
| 586 | |||
| 580 | static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc) | 587 | static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc) |
| 581 | { | 588 | { |
| 582 | struct exynos_drm_private *dev_priv = drm_dev->dev_private; | 589 | struct exynos_drm_private *dev_priv = drm_dev->dev_private; |
| @@ -628,7 +635,7 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id) | |||
| 628 | struct fimd_context *ctx = (struct fimd_context *)dev_id; | 635 | struct fimd_context *ctx = (struct fimd_context *)dev_id; |
| 629 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; | 636 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; |
| 630 | struct drm_device *drm_dev = subdrv->drm_dev; | 637 | struct drm_device *drm_dev = subdrv->drm_dev; |
| 631 | struct exynos_drm_manager *manager = &subdrv->manager; | 638 | struct exynos_drm_manager *manager = subdrv->manager; |
| 632 | u32 val; | 639 | u32 val; |
| 633 | 640 | ||
| 634 | val = readl(ctx->regs + VIDINTCON1); | 641 | val = readl(ctx->regs + VIDINTCON1); |
| @@ -744,7 +751,7 @@ static void fimd_clear_win(struct fimd_context *ctx, int win) | |||
| 744 | static int fimd_power_on(struct fimd_context *ctx, bool enable) | 751 | static int fimd_power_on(struct fimd_context *ctx, bool enable) |
| 745 | { | 752 | { |
| 746 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; | 753 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; |
| 747 | struct device *dev = subdrv->manager.dev; | 754 | struct device *dev = subdrv->dev; |
| 748 | 755 | ||
| 749 | DRM_DEBUG_KMS("%s\n", __FILE__); | 756 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 750 | 757 | ||
| @@ -867,13 +874,10 @@ static int __devinit fimd_probe(struct platform_device *pdev) | |||
| 867 | 874 | ||
| 868 | subdrv = &ctx->subdrv; | 875 | subdrv = &ctx->subdrv; |
| 869 | 876 | ||
| 877 | subdrv->dev = dev; | ||
| 878 | subdrv->manager = &fimd_manager; | ||
| 870 | subdrv->probe = fimd_subdrv_probe; | 879 | subdrv->probe = fimd_subdrv_probe; |
| 871 | subdrv->remove = fimd_subdrv_remove; | 880 | subdrv->remove = fimd_subdrv_remove; |
| 872 | subdrv->manager.pipe = -1; | ||
| 873 | subdrv->manager.ops = &fimd_manager_ops; | ||
| 874 | subdrv->manager.overlay_ops = &fimd_overlay_ops; | ||
| 875 | subdrv->manager.display_ops = &fimd_display_ops; | ||
| 876 | subdrv->manager.dev = dev; | ||
| 877 | 881 | ||
| 878 | mutex_init(&ctx->lock); | 882 | mutex_init(&ctx->lock); |
| 879 | 883 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index fa1aa94a3d8e..1dffa8359f88 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c | |||
| @@ -56,9 +56,28 @@ static unsigned int convert_to_vm_err_msg(int msg) | |||
| 56 | return out_msg; | 56 | return out_msg; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | static unsigned int mask_gem_flags(unsigned int flags) | 59 | static int check_gem_flags(unsigned int flags) |
| 60 | { | 60 | { |
| 61 | return flags &= EXYNOS_BO_NONCONTIG; | 61 | if (flags & ~(EXYNOS_BO_MASK)) { |
| 62 | DRM_ERROR("invalid flags.\n"); | ||
| 63 | return -EINVAL; | ||
| 64 | } | ||
| 65 | |||
| 66 | return 0; | ||
| 67 | } | ||
| 68 | |||
| 69 | static unsigned long roundup_gem_size(unsigned long size, unsigned int flags) | ||
| 70 | { | ||
| 71 | if (!IS_NONCONTIG_BUFFER(flags)) { | ||
| 72 | if (size >= SZ_1M) | ||
| 73 | return roundup(size, SECTION_SIZE); | ||
| 74 | else if (size >= SZ_64K) | ||
| 75 | return roundup(size, SZ_64K); | ||
| 76 | else | ||
| 77 | goto out; | ||
| 78 | } | ||
| 79 | out: | ||
| 80 | return roundup(size, PAGE_SIZE); | ||
| 62 | } | 81 | } |
| 63 | 82 | ||
| 64 | static struct page **exynos_gem_get_pages(struct drm_gem_object *obj, | 83 | static struct page **exynos_gem_get_pages(struct drm_gem_object *obj, |
| @@ -130,22 +149,12 @@ static int exynos_drm_gem_map_pages(struct drm_gem_object *obj, | |||
| 130 | unsigned long pfn; | 149 | unsigned long pfn; |
| 131 | 150 | ||
| 132 | if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { | 151 | if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { |
| 133 | unsigned long usize = buf->size; | ||
| 134 | |||
| 135 | if (!buf->pages) | 152 | if (!buf->pages) |
| 136 | return -EINTR; | 153 | return -EINTR; |
| 137 | 154 | ||
| 138 | while (usize > 0) { | 155 | pfn = page_to_pfn(buf->pages[page_offset++]); |
| 139 | pfn = page_to_pfn(buf->pages[page_offset++]); | 156 | } else |
| 140 | vm_insert_mixed(vma, f_vaddr, pfn); | 157 | pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset; |
| 141 | f_vaddr += PAGE_SIZE; | ||
| 142 | usize -= PAGE_SIZE; | ||
| 143 | } | ||
| 144 | |||
| 145 | return 0; | ||
| 146 | } | ||
| 147 | |||
| 148 | pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset; | ||
| 149 | 158 | ||
| 150 | return vm_insert_mixed(vma, f_vaddr, pfn); | 159 | return vm_insert_mixed(vma, f_vaddr, pfn); |
| 151 | } | 160 | } |
| @@ -319,10 +328,17 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, | |||
| 319 | struct exynos_drm_gem_buf *buf; | 328 | struct exynos_drm_gem_buf *buf; |
| 320 | int ret; | 329 | int ret; |
| 321 | 330 | ||
| 322 | size = roundup(size, PAGE_SIZE); | 331 | if (!size) { |
| 323 | DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size); | 332 | DRM_ERROR("invalid size.\n"); |
| 333 | return ERR_PTR(-EINVAL); | ||
| 334 | } | ||
| 335 | |||
| 336 | size = roundup_gem_size(size, flags); | ||
| 337 | DRM_DEBUG_KMS("%s\n", __FILE__); | ||
| 324 | 338 | ||
| 325 | flags = mask_gem_flags(flags); | 339 | ret = check_gem_flags(flags); |
| 340 | if (ret) | ||
| 341 | return ERR_PTR(ret); | ||
| 326 | 342 | ||
| 327 | buf = exynos_drm_init_buf(dev, size); | 343 | buf = exynos_drm_init_buf(dev, size); |
| 328 | if (!buf) | 344 | if (!buf) |
| @@ -331,7 +347,7 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, | |||
| 331 | exynos_gem_obj = exynos_drm_gem_init(dev, size); | 347 | exynos_gem_obj = exynos_drm_gem_init(dev, size); |
| 332 | if (!exynos_gem_obj) { | 348 | if (!exynos_gem_obj) { |
| 333 | ret = -ENOMEM; | 349 | ret = -ENOMEM; |
| 334 | goto err; | 350 | goto err_fini_buf; |
| 335 | } | 351 | } |
| 336 | 352 | ||
| 337 | exynos_gem_obj->buffer = buf; | 353 | exynos_gem_obj->buffer = buf; |
| @@ -347,18 +363,19 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, | |||
| 347 | ret = exynos_drm_gem_get_pages(&exynos_gem_obj->base); | 363 | ret = exynos_drm_gem_get_pages(&exynos_gem_obj->base); |
| 348 | if (ret < 0) { | 364 | if (ret < 0) { |
| 349 | drm_gem_object_release(&exynos_gem_obj->base); | 365 | drm_gem_object_release(&exynos_gem_obj->base); |
| 350 | goto err; | 366 | goto err_fini_buf; |
| 351 | } | 367 | } |
| 352 | } else { | 368 | } else { |
| 353 | ret = exynos_drm_alloc_buf(dev, buf, flags); | 369 | ret = exynos_drm_alloc_buf(dev, buf, flags); |
| 354 | if (ret < 0) { | 370 | if (ret < 0) { |
| 355 | drm_gem_object_release(&exynos_gem_obj->base); | 371 | drm_gem_object_release(&exynos_gem_obj->base); |
| 356 | goto err; | 372 | goto err_fini_buf; |
| 357 | } | 373 | } |
| 358 | } | 374 | } |
| 359 | 375 | ||
| 360 | return exynos_gem_obj; | 376 | return exynos_gem_obj; |
| 361 | err: | 377 | |
| 378 | err_fini_buf: | ||
| 362 | exynos_drm_fini_buf(dev, buf); | 379 | exynos_drm_fini_buf(dev, buf); |
| 363 | return ERR_PTR(ret); | 380 | return ERR_PTR(ret); |
| 364 | } | 381 | } |
| @@ -497,6 +514,8 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp, | |||
| 497 | if (!buffer->pages) | 514 | if (!buffer->pages) |
| 498 | return -EINVAL; | 515 | return -EINVAL; |
| 499 | 516 | ||
| 517 | vma->vm_flags |= VM_MIXEDMAP; | ||
| 518 | |||
| 500 | do { | 519 | do { |
| 501 | ret = vm_insert_page(vma, uaddr, buffer->pages[i++]); | 520 | ret = vm_insert_page(vma, uaddr, buffer->pages[i++]); |
| 502 | if (ret) { | 521 | if (ret) { |
| @@ -554,10 +573,8 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
| 554 | obj->filp->f_op = &exynos_drm_gem_fops; | 573 | obj->filp->f_op = &exynos_drm_gem_fops; |
| 555 | obj->filp->private_data = obj; | 574 | obj->filp->private_data = obj; |
| 556 | 575 | ||
| 557 | down_write(¤t->mm->mmap_sem); | 576 | addr = vm_mmap(obj->filp, 0, args->size, |
| 558 | addr = do_mmap(obj->filp, 0, args->size, | ||
| 559 | PROT_READ | PROT_WRITE, MAP_SHARED, 0); | 577 | PROT_READ | PROT_WRITE, MAP_SHARED, 0); |
| 560 | up_write(¤t->mm->mmap_sem); | ||
| 561 | 578 | ||
| 562 | drm_gem_object_unreference_unlocked(obj); | 579 | drm_gem_object_unreference_unlocked(obj); |
| 563 | 580 | ||
| @@ -685,7 +702,6 @@ int exynos_drm_gem_dumb_destroy(struct drm_file *file_priv, | |||
| 685 | int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | 702 | int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
| 686 | { | 703 | { |
| 687 | struct drm_gem_object *obj = vma->vm_private_data; | 704 | struct drm_gem_object *obj = vma->vm_private_data; |
| 688 | struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); | ||
| 689 | struct drm_device *dev = obj->dev; | 705 | struct drm_device *dev = obj->dev; |
| 690 | unsigned long f_vaddr; | 706 | unsigned long f_vaddr; |
| 691 | pgoff_t page_offset; | 707 | pgoff_t page_offset; |
| @@ -697,21 +713,10 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
| 697 | 713 | ||
| 698 | mutex_lock(&dev->struct_mutex); | 714 | mutex_lock(&dev->struct_mutex); |
| 699 | 715 | ||
| 700 | /* | ||
| 701 | * allocate all pages as desired size if user wants to allocate | ||
| 702 | * physically non-continuous memory. | ||
| 703 | */ | ||
| 704 | if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { | ||
| 705 | ret = exynos_drm_gem_get_pages(obj); | ||
| 706 | if (ret < 0) | ||
| 707 | goto err; | ||
| 708 | } | ||
| 709 | |||
| 710 | ret = exynos_drm_gem_map_pages(obj, vma, f_vaddr, page_offset); | 716 | ret = exynos_drm_gem_map_pages(obj, vma, f_vaddr, page_offset); |
| 711 | if (ret < 0) | 717 | if (ret < 0) |
| 712 | DRM_ERROR("failed to map pages.\n"); | 718 | DRM_ERROR("failed to map pages.\n"); |
| 713 | 719 | ||
| 714 | err: | ||
| 715 | mutex_unlock(&dev->struct_mutex); | 720 | mutex_unlock(&dev->struct_mutex); |
| 716 | 721 | ||
| 717 | return convert_to_vm_err_msg(ret); | 722 | return convert_to_vm_err_msg(ret); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h index e40fbad8b705..4ed842039505 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h | |||
| @@ -29,6 +29,8 @@ | |||
| 29 | #define to_exynos_gem_obj(x) container_of(x,\ | 29 | #define to_exynos_gem_obj(x) container_of(x,\ |
| 30 | struct exynos_drm_gem_obj, base) | 30 | struct exynos_drm_gem_obj, base) |
| 31 | 31 | ||
| 32 | #define IS_NONCONTIG_BUFFER(f) (f & EXYNOS_BO_NONCONTIG) | ||
| 33 | |||
| 32 | /* | 34 | /* |
| 33 | * exynos drm gem buffer structure. | 35 | * exynos drm gem buffer structure. |
| 34 | * | 36 | * |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index 14eb26b0ba1c..3424463676e0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c | |||
| @@ -30,9 +30,8 @@ | |||
| 30 | struct drm_hdmi_context, subdrv); | 30 | struct drm_hdmi_context, subdrv); |
| 31 | 31 | ||
| 32 | /* these callback points shoud be set by specific drivers. */ | 32 | /* these callback points shoud be set by specific drivers. */ |
| 33 | static struct exynos_hdmi_display_ops *hdmi_display_ops; | 33 | static struct exynos_hdmi_ops *hdmi_ops; |
| 34 | static struct exynos_hdmi_manager_ops *hdmi_manager_ops; | 34 | static struct exynos_mixer_ops *mixer_ops; |
| 35 | static struct exynos_hdmi_overlay_ops *hdmi_overlay_ops; | ||
| 36 | 35 | ||
| 37 | struct drm_hdmi_context { | 36 | struct drm_hdmi_context { |
| 38 | struct exynos_drm_subdrv subdrv; | 37 | struct exynos_drm_subdrv subdrv; |
| @@ -40,31 +39,20 @@ struct drm_hdmi_context { | |||
| 40 | struct exynos_drm_hdmi_context *mixer_ctx; | 39 | struct exynos_drm_hdmi_context *mixer_ctx; |
| 41 | }; | 40 | }; |
| 42 | 41 | ||
| 43 | void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops | 42 | void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops) |
| 44 | *display_ops) | ||
| 45 | { | 43 | { |
| 46 | DRM_DEBUG_KMS("%s\n", __FILE__); | 44 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 47 | 45 | ||
| 48 | if (display_ops) | 46 | if (ops) |
| 49 | hdmi_display_ops = display_ops; | 47 | hdmi_ops = ops; |
| 50 | } | 48 | } |
| 51 | 49 | ||
| 52 | void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops | 50 | void exynos_mixer_ops_register(struct exynos_mixer_ops *ops) |
| 53 | *manager_ops) | ||
| 54 | { | 51 | { |
| 55 | DRM_DEBUG_KMS("%s\n", __FILE__); | 52 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 56 | 53 | ||
| 57 | if (manager_ops) | 54 | if (ops) |
| 58 | hdmi_manager_ops = manager_ops; | 55 | mixer_ops = ops; |
| 59 | } | ||
| 60 | |||
| 61 | void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops | ||
| 62 | *overlay_ops) | ||
| 63 | { | ||
| 64 | DRM_DEBUG_KMS("%s\n", __FILE__); | ||
| 65 | |||
| 66 | if (overlay_ops) | ||
| 67 | hdmi_overlay_ops = overlay_ops; | ||
| 68 | } | 56 | } |
| 69 | 57 | ||
| 70 | static bool drm_hdmi_is_connected(struct device *dev) | 58 | static bool drm_hdmi_is_connected(struct device *dev) |
| @@ -73,8 +61,8 @@ static bool drm_hdmi_is_connected(struct device *dev) | |||
| 73 | 61 | ||
| 74 | DRM_DEBUG_KMS("%s\n", __FILE__); | 62 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 75 | 63 | ||
| 76 | if (hdmi_display_ops && hdmi_display_ops->is_connected) | 64 | if (hdmi_ops && hdmi_ops->is_connected) |
| 77 | return hdmi_display_ops->is_connected(ctx->hdmi_ctx->ctx); | 65 | return hdmi_ops->is_connected(ctx->hdmi_ctx->ctx); |
| 78 | 66 | ||
| 79 | return false; | 67 | return false; |
| 80 | } | 68 | } |
| @@ -86,9 +74,9 @@ static int drm_hdmi_get_edid(struct device *dev, | |||
| 86 | 74 | ||
| 87 | DRM_DEBUG_KMS("%s\n", __FILE__); | 75 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 88 | 76 | ||
| 89 | if (hdmi_display_ops && hdmi_display_ops->get_edid) | 77 | if (hdmi_ops && hdmi_ops->get_edid) |
| 90 | return hdmi_display_ops->get_edid(ctx->hdmi_ctx->ctx, | 78 | return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector, edid, |
| 91 | connector, edid, len); | 79 | len); |
| 92 | 80 | ||
| 93 | return 0; | 81 | return 0; |
| 94 | } | 82 | } |
| @@ -99,9 +87,8 @@ static int drm_hdmi_check_timing(struct device *dev, void *timing) | |||
| 99 | 87 | ||
| 100 | DRM_DEBUG_KMS("%s\n", __FILE__); | 88 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 101 | 89 | ||
| 102 | if (hdmi_display_ops && hdmi_display_ops->check_timing) | 90 | if (hdmi_ops && hdmi_ops->check_timing) |
| 103 | return hdmi_display_ops->check_timing(ctx->hdmi_ctx->ctx, | 91 | return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing); |
| 104 | timing); | ||
| 105 | 92 | ||
| 106 | return 0; | 93 | return 0; |
| 107 | } | 94 | } |
| @@ -112,8 +99,8 @@ static int drm_hdmi_power_on(struct device *dev, int mode) | |||
| 112 | 99 | ||
| 113 | DRM_DEBUG_KMS("%s\n", __FILE__); | 100 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 114 | 101 | ||
| 115 | if (hdmi_display_ops && hdmi_display_ops->power_on) | 102 | if (hdmi_ops && hdmi_ops->power_on) |
| 116 | return hdmi_display_ops->power_on(ctx->hdmi_ctx->ctx, mode); | 103 | return hdmi_ops->power_on(ctx->hdmi_ctx->ctx, mode); |
| 117 | 104 | ||
| 118 | return 0; | 105 | return 0; |
| 119 | } | 106 | } |
| @@ -130,13 +117,13 @@ static int drm_hdmi_enable_vblank(struct device *subdrv_dev) | |||
| 130 | { | 117 | { |
| 131 | struct drm_hdmi_context *ctx = to_context(subdrv_dev); | 118 | struct drm_hdmi_context *ctx = to_context(subdrv_dev); |
| 132 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; | 119 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; |
| 133 | struct exynos_drm_manager *manager = &subdrv->manager; | 120 | struct exynos_drm_manager *manager = subdrv->manager; |
| 134 | 121 | ||
| 135 | DRM_DEBUG_KMS("%s\n", __FILE__); | 122 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 136 | 123 | ||
| 137 | if (hdmi_overlay_ops && hdmi_overlay_ops->enable_vblank) | 124 | if (mixer_ops && mixer_ops->enable_vblank) |
| 138 | return hdmi_overlay_ops->enable_vblank(ctx->mixer_ctx->ctx, | 125 | return mixer_ops->enable_vblank(ctx->mixer_ctx->ctx, |
| 139 | manager->pipe); | 126 | manager->pipe); |
| 140 | 127 | ||
| 141 | return 0; | 128 | return 0; |
| 142 | } | 129 | } |
| @@ -147,8 +134,8 @@ static void drm_hdmi_disable_vblank(struct device *subdrv_dev) | |||
| 147 | 134 | ||
| 148 | DRM_DEBUG_KMS("%s\n", __FILE__); | 135 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 149 | 136 | ||
| 150 | if (hdmi_overlay_ops && hdmi_overlay_ops->disable_vblank) | 137 | if (mixer_ops && mixer_ops->disable_vblank) |
| 151 | return hdmi_overlay_ops->disable_vblank(ctx->mixer_ctx->ctx); | 138 | return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx); |
| 152 | } | 139 | } |
| 153 | 140 | ||
| 154 | static void drm_hdmi_mode_fixup(struct device *subdrv_dev, | 141 | static void drm_hdmi_mode_fixup(struct device *subdrv_dev, |
| @@ -160,9 +147,9 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev, | |||
| 160 | 147 | ||
| 161 | DRM_DEBUG_KMS("%s\n", __FILE__); | 148 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 162 | 149 | ||
| 163 | if (hdmi_manager_ops && hdmi_manager_ops->mode_fixup) | 150 | if (hdmi_ops && hdmi_ops->mode_fixup) |
| 164 | hdmi_manager_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, | 151 | hdmi_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, mode, |
| 165 | mode, adjusted_mode); | 152 | adjusted_mode); |
| 166 | } | 153 | } |
| 167 | 154 | ||
| 168 | static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode) | 155 | static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode) |
| @@ -171,8 +158,8 @@ static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode) | |||
| 171 | 158 | ||
| 172 | DRM_DEBUG_KMS("%s\n", __FILE__); | 159 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 173 | 160 | ||
| 174 | if (hdmi_manager_ops && hdmi_manager_ops->mode_set) | 161 | if (hdmi_ops && hdmi_ops->mode_set) |
| 175 | hdmi_manager_ops->mode_set(ctx->hdmi_ctx->ctx, mode); | 162 | hdmi_ops->mode_set(ctx->hdmi_ctx->ctx, mode); |
| 176 | } | 163 | } |
| 177 | 164 | ||
| 178 | static void drm_hdmi_get_max_resol(struct device *subdrv_dev, | 165 | static void drm_hdmi_get_max_resol(struct device *subdrv_dev, |
| @@ -182,9 +169,8 @@ static void drm_hdmi_get_max_resol(struct device *subdrv_dev, | |||
| 182 | 169 | ||
| 183 | DRM_DEBUG_KMS("%s\n", __FILE__); | 170 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 184 | 171 | ||
| 185 | if (hdmi_manager_ops && hdmi_manager_ops->get_max_resol) | 172 | if (hdmi_ops && hdmi_ops->get_max_resol) |
| 186 | hdmi_manager_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, | 173 | hdmi_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, height); |
| 187 | height); | ||
| 188 | } | 174 | } |
| 189 | 175 | ||
| 190 | static void drm_hdmi_commit(struct device *subdrv_dev) | 176 | static void drm_hdmi_commit(struct device *subdrv_dev) |
| @@ -193,8 +179,8 @@ static void drm_hdmi_commit(struct device *subdrv_dev) | |||
| 193 | 179 | ||
| 194 | DRM_DEBUG_KMS("%s\n", __FILE__); | 180 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 195 | 181 | ||
| 196 | if (hdmi_manager_ops && hdmi_manager_ops->commit) | 182 | if (hdmi_ops && hdmi_ops->commit) |
| 197 | hdmi_manager_ops->commit(ctx->hdmi_ctx->ctx); | 183 | hdmi_ops->commit(ctx->hdmi_ctx->ctx); |
| 198 | } | 184 | } |
| 199 | 185 | ||
| 200 | static void drm_hdmi_dpms(struct device *subdrv_dev, int mode) | 186 | static void drm_hdmi_dpms(struct device *subdrv_dev, int mode) |
| @@ -209,8 +195,8 @@ static void drm_hdmi_dpms(struct device *subdrv_dev, int mode) | |||
| 209 | case DRM_MODE_DPMS_STANDBY: | 195 | case DRM_MODE_DPMS_STANDBY: |
| 210 | case DRM_MODE_DPMS_SUSPEND: | 196 | case DRM_MODE_DPMS_SUSPEND: |
| 211 | case DRM_MODE_DPMS_OFF: | 197 | case DRM_MODE_DPMS_OFF: |
| 212 | if (hdmi_manager_ops && hdmi_manager_ops->disable) | 198 | if (hdmi_ops && hdmi_ops->disable) |
| 213 | hdmi_manager_ops->disable(ctx->hdmi_ctx->ctx); | 199 | hdmi_ops->disable(ctx->hdmi_ctx->ctx); |
| 214 | break; | 200 | break; |
| 215 | default: | 201 | default: |
| 216 | DRM_DEBUG_KMS("unkown dps mode: %d\n", mode); | 202 | DRM_DEBUG_KMS("unkown dps mode: %d\n", mode); |
| @@ -235,8 +221,8 @@ static void drm_mixer_mode_set(struct device *subdrv_dev, | |||
| 235 | 221 | ||
| 236 | DRM_DEBUG_KMS("%s\n", __FILE__); | 222 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 237 | 223 | ||
| 238 | if (hdmi_overlay_ops && hdmi_overlay_ops->win_mode_set) | 224 | if (mixer_ops && mixer_ops->win_mode_set) |
| 239 | hdmi_overlay_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay); | 225 | mixer_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay); |
| 240 | } | 226 | } |
| 241 | 227 | ||
| 242 | static void drm_mixer_commit(struct device *subdrv_dev, int zpos) | 228 | static void drm_mixer_commit(struct device *subdrv_dev, int zpos) |
| @@ -245,8 +231,8 @@ static void drm_mixer_commit(struct device *subdrv_dev, int zpos) | |||
| 245 | 231 | ||
| 246 | DRM_DEBUG_KMS("%s\n", __FILE__); | 232 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 247 | 233 | ||
| 248 | if (hdmi_overlay_ops && hdmi_overlay_ops->win_commit) | 234 | if (mixer_ops && mixer_ops->win_commit) |
| 249 | hdmi_overlay_ops->win_commit(ctx->mixer_ctx->ctx, zpos); | 235 | mixer_ops->win_commit(ctx->mixer_ctx->ctx, zpos); |
| 250 | } | 236 | } |
| 251 | 237 | ||
| 252 | static void drm_mixer_disable(struct device *subdrv_dev, int zpos) | 238 | static void drm_mixer_disable(struct device *subdrv_dev, int zpos) |
| @@ -255,8 +241,8 @@ static void drm_mixer_disable(struct device *subdrv_dev, int zpos) | |||
| 255 | 241 | ||
| 256 | DRM_DEBUG_KMS("%s\n", __FILE__); | 242 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 257 | 243 | ||
| 258 | if (hdmi_overlay_ops && hdmi_overlay_ops->win_disable) | 244 | if (mixer_ops && mixer_ops->win_disable) |
| 259 | hdmi_overlay_ops->win_disable(ctx->mixer_ctx->ctx, zpos); | 245 | mixer_ops->win_disable(ctx->mixer_ctx->ctx, zpos); |
| 260 | } | 246 | } |
| 261 | 247 | ||
| 262 | static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = { | 248 | static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = { |
| @@ -265,6 +251,12 @@ static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = { | |||
| 265 | .disable = drm_mixer_disable, | 251 | .disable = drm_mixer_disable, |
| 266 | }; | 252 | }; |
| 267 | 253 | ||
| 254 | static struct exynos_drm_manager hdmi_manager = { | ||
| 255 | .pipe = -1, | ||
| 256 | .ops = &drm_hdmi_manager_ops, | ||
| 257 | .overlay_ops = &drm_hdmi_overlay_ops, | ||
| 258 | .display_ops = &drm_hdmi_display_ops, | ||
| 259 | }; | ||
| 268 | 260 | ||
| 269 | static int hdmi_subdrv_probe(struct drm_device *drm_dev, | 261 | static int hdmi_subdrv_probe(struct drm_device *drm_dev, |
| 270 | struct device *dev) | 262 | struct device *dev) |
| @@ -332,12 +324,9 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev) | |||
| 332 | 324 | ||
| 333 | subdrv = &ctx->subdrv; | 325 | subdrv = &ctx->subdrv; |
| 334 | 326 | ||
| 327 | subdrv->dev = dev; | ||
| 328 | subdrv->manager = &hdmi_manager; | ||
| 335 | subdrv->probe = hdmi_subdrv_probe; | 329 | subdrv->probe = hdmi_subdrv_probe; |
| 336 | subdrv->manager.pipe = -1; | ||
| 337 | subdrv->manager.ops = &drm_hdmi_manager_ops; | ||
| 338 | subdrv->manager.overlay_ops = &drm_hdmi_overlay_ops; | ||
| 339 | subdrv->manager.display_ops = &drm_hdmi_display_ops; | ||
| 340 | subdrv->manager.dev = dev; | ||
| 341 | 330 | ||
| 342 | platform_set_drvdata(pdev, subdrv); | 331 | platform_set_drvdata(pdev, subdrv); |
| 343 | 332 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h index 44497cfb6c74..f3ae192c8dcf 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h | |||
| @@ -38,15 +38,15 @@ struct exynos_drm_hdmi_context { | |||
| 38 | void *ctx; | 38 | void *ctx; |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | struct exynos_hdmi_display_ops { | 41 | struct exynos_hdmi_ops { |
| 42 | /* display */ | ||
| 42 | bool (*is_connected)(void *ctx); | 43 | bool (*is_connected)(void *ctx); |
| 43 | int (*get_edid)(void *ctx, struct drm_connector *connector, | 44 | int (*get_edid)(void *ctx, struct drm_connector *connector, |
| 44 | u8 *edid, int len); | 45 | u8 *edid, int len); |
| 45 | int (*check_timing)(void *ctx, void *timing); | 46 | int (*check_timing)(void *ctx, void *timing); |
| 46 | int (*power_on)(void *ctx, int mode); | 47 | int (*power_on)(void *ctx, int mode); |
| 47 | }; | ||
| 48 | 48 | ||
| 49 | struct exynos_hdmi_manager_ops { | 49 | /* manager */ |
| 50 | void (*mode_fixup)(void *ctx, struct drm_connector *connector, | 50 | void (*mode_fixup)(void *ctx, struct drm_connector *connector, |
| 51 | struct drm_display_mode *mode, | 51 | struct drm_display_mode *mode, |
| 52 | struct drm_display_mode *adjusted_mode); | 52 | struct drm_display_mode *adjusted_mode); |
| @@ -57,22 +57,17 @@ struct exynos_hdmi_manager_ops { | |||
| 57 | void (*disable)(void *ctx); | 57 | void (*disable)(void *ctx); |
| 58 | }; | 58 | }; |
| 59 | 59 | ||
| 60 | struct exynos_hdmi_overlay_ops { | 60 | struct exynos_mixer_ops { |
| 61 | /* manager */ | ||
| 61 | int (*enable_vblank)(void *ctx, int pipe); | 62 | int (*enable_vblank)(void *ctx, int pipe); |
| 62 | void (*disable_vblank)(void *ctx); | 63 | void (*disable_vblank)(void *ctx); |
| 64 | |||
| 65 | /* overlay */ | ||
| 63 | void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay); | 66 | void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay); |
| 64 | void (*win_commit)(void *ctx, int zpos); | 67 | void (*win_commit)(void *ctx, int zpos); |
| 65 | void (*win_disable)(void *ctx, int zpos); | 68 | void (*win_disable)(void *ctx, int zpos); |
| 66 | }; | 69 | }; |
| 67 | 70 | ||
| 68 | extern struct platform_driver hdmi_driver; | 71 | void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops); |
| 69 | extern struct platform_driver mixer_driver; | 72 | void exynos_mixer_ops_register(struct exynos_mixer_ops *ops); |
| 70 | |||
| 71 | void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops | ||
| 72 | *display_ops); | ||
| 73 | void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops | ||
| 74 | *manager_ops); | ||
| 75 | void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops | ||
| 76 | *overlay_ops); | ||
| 77 | |||
| 78 | #endif | 73 | #endif |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index c277a3a445f5..f92fe4c6174a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c | |||
| @@ -24,6 +24,10 @@ struct exynos_plane { | |||
| 24 | 24 | ||
| 25 | static const uint32_t formats[] = { | 25 | static const uint32_t formats[] = { |
| 26 | DRM_FORMAT_XRGB8888, | 26 | DRM_FORMAT_XRGB8888, |
| 27 | DRM_FORMAT_ARGB8888, | ||
| 28 | DRM_FORMAT_NV12, | ||
| 29 | DRM_FORMAT_NV12M, | ||
| 30 | DRM_FORMAT_NV12MT, | ||
| 27 | }; | 31 | }; |
| 28 | 32 | ||
| 29 | static int | 33 | static int |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 8e1339f9fe1f..7b9c153dceb6 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c | |||
| @@ -199,7 +199,7 @@ static void vidi_dpms(struct device *subdrv_dev, int mode) | |||
| 199 | static void vidi_apply(struct device *subdrv_dev) | 199 | static void vidi_apply(struct device *subdrv_dev) |
| 200 | { | 200 | { |
| 201 | struct vidi_context *ctx = get_vidi_context(subdrv_dev); | 201 | struct vidi_context *ctx = get_vidi_context(subdrv_dev); |
| 202 | struct exynos_drm_manager *mgr = &ctx->subdrv.manager; | 202 | struct exynos_drm_manager *mgr = ctx->subdrv.manager; |
| 203 | struct exynos_drm_manager_ops *mgr_ops = mgr->ops; | 203 | struct exynos_drm_manager_ops *mgr_ops = mgr->ops; |
| 204 | struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops; | 204 | struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops; |
| 205 | struct vidi_win_data *win_data; | 205 | struct vidi_win_data *win_data; |
| @@ -374,6 +374,13 @@ static struct exynos_drm_overlay_ops vidi_overlay_ops = { | |||
| 374 | .disable = vidi_win_disable, | 374 | .disable = vidi_win_disable, |
| 375 | }; | 375 | }; |
| 376 | 376 | ||
| 377 | static struct exynos_drm_manager vidi_manager = { | ||
| 378 | .pipe = -1, | ||
| 379 | .ops = &vidi_manager_ops, | ||
| 380 | .overlay_ops = &vidi_overlay_ops, | ||
| 381 | .display_ops = &vidi_display_ops, | ||
| 382 | }; | ||
| 383 | |||
| 377 | static void vidi_finish_pageflip(struct drm_device *drm_dev, int crtc) | 384 | static void vidi_finish_pageflip(struct drm_device *drm_dev, int crtc) |
| 378 | { | 385 | { |
| 379 | struct exynos_drm_private *dev_priv = drm_dev->dev_private; | 386 | struct exynos_drm_private *dev_priv = drm_dev->dev_private; |
| @@ -425,7 +432,7 @@ static void vidi_fake_vblank_handler(struct work_struct *work) | |||
| 425 | struct vidi_context *ctx = container_of(work, struct vidi_context, | 432 | struct vidi_context *ctx = container_of(work, struct vidi_context, |
| 426 | work); | 433 | work); |
| 427 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; | 434 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; |
| 428 | struct exynos_drm_manager *manager = &subdrv->manager; | 435 | struct exynos_drm_manager *manager = subdrv->manager; |
| 429 | 436 | ||
| 430 | if (manager->pipe < 0) | 437 | if (manager->pipe < 0) |
| 431 | return; | 438 | return; |
| @@ -471,7 +478,7 @@ static void vidi_subdrv_remove(struct drm_device *drm_dev) | |||
| 471 | static int vidi_power_on(struct vidi_context *ctx, bool enable) | 478 | static int vidi_power_on(struct vidi_context *ctx, bool enable) |
| 472 | { | 479 | { |
| 473 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; | 480 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; |
| 474 | struct device *dev = subdrv->manager.dev; | 481 | struct device *dev = subdrv->dev; |
| 475 | 482 | ||
| 476 | DRM_DEBUG_KMS("%s\n", __FILE__); | 483 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 477 | 484 | ||
| @@ -611,13 +618,10 @@ static int __devinit vidi_probe(struct platform_device *pdev) | |||
| 611 | ctx->raw_edid = (struct edid *)fake_edid_info; | 618 | ctx->raw_edid = (struct edid *)fake_edid_info; |
| 612 | 619 | ||
| 613 | subdrv = &ctx->subdrv; | 620 | subdrv = &ctx->subdrv; |
| 621 | subdrv->dev = dev; | ||
| 622 | subdrv->manager = &vidi_manager; | ||
| 614 | subdrv->probe = vidi_subdrv_probe; | 623 | subdrv->probe = vidi_subdrv_probe; |
| 615 | subdrv->remove = vidi_subdrv_remove; | 624 | subdrv->remove = vidi_subdrv_remove; |
| 616 | subdrv->manager.pipe = -1; | ||
| 617 | subdrv->manager.ops = &vidi_manager_ops; | ||
| 618 | subdrv->manager.overlay_ops = &vidi_overlay_ops; | ||
| 619 | subdrv->manager.display_ops = &vidi_display_ops; | ||
| 620 | subdrv->manager.dev = dev; | ||
| 621 | 625 | ||
| 622 | mutex_init(&ctx->lock); | 626 | mutex_init(&ctx->lock); |
| 623 | 627 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 575a8cbd3533..b00353876458 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
| @@ -40,7 +40,6 @@ | |||
| 40 | 40 | ||
| 41 | #include "exynos_hdmi.h" | 41 | #include "exynos_hdmi.h" |
| 42 | 42 | ||
| 43 | #define HDMI_OVERLAY_NUMBER 3 | ||
| 44 | #define MAX_WIDTH 1920 | 43 | #define MAX_WIDTH 1920 |
| 45 | #define MAX_HEIGHT 1080 | 44 | #define MAX_HEIGHT 1080 |
| 46 | #define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev)) | 45 | #define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev)) |
| @@ -1194,7 +1193,7 @@ static int hdmi_conf_index(struct hdmi_context *hdata, | |||
| 1194 | 1193 | ||
| 1195 | static bool hdmi_is_connected(void *ctx) | 1194 | static bool hdmi_is_connected(void *ctx) |
| 1196 | { | 1195 | { |
| 1197 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; | 1196 | struct hdmi_context *hdata = ctx; |
| 1198 | u32 val = hdmi_reg_read(hdata, HDMI_HPD_STATUS); | 1197 | u32 val = hdmi_reg_read(hdata, HDMI_HPD_STATUS); |
| 1199 | 1198 | ||
| 1200 | if (val) | 1199 | if (val) |
| @@ -1207,7 +1206,7 @@ static int hdmi_get_edid(void *ctx, struct drm_connector *connector, | |||
| 1207 | u8 *edid, int len) | 1206 | u8 *edid, int len) |
| 1208 | { | 1207 | { |
| 1209 | struct edid *raw_edid; | 1208 | struct edid *raw_edid; |
| 1210 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; | 1209 | struct hdmi_context *hdata = ctx; |
| 1211 | 1210 | ||
| 1212 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 1211 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
| 1213 | 1212 | ||
| @@ -1275,7 +1274,7 @@ static int hdmi_v14_check_timing(struct fb_videomode *check_timing) | |||
| 1275 | 1274 | ||
| 1276 | static int hdmi_check_timing(void *ctx, void *timing) | 1275 | static int hdmi_check_timing(void *ctx, void *timing) |
| 1277 | { | 1276 | { |
| 1278 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; | 1277 | struct hdmi_context *hdata = ctx; |
| 1279 | struct fb_videomode *check_timing = timing; | 1278 | struct fb_videomode *check_timing = timing; |
| 1280 | 1279 | ||
| 1281 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 1280 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
| @@ -1312,13 +1311,6 @@ static int hdmi_display_power_on(void *ctx, int mode) | |||
| 1312 | return 0; | 1311 | return 0; |
| 1313 | } | 1312 | } |
| 1314 | 1313 | ||
| 1315 | static struct exynos_hdmi_display_ops display_ops = { | ||
| 1316 | .is_connected = hdmi_is_connected, | ||
| 1317 | .get_edid = hdmi_get_edid, | ||
| 1318 | .check_timing = hdmi_check_timing, | ||
| 1319 | .power_on = hdmi_display_power_on, | ||
| 1320 | }; | ||
| 1321 | |||
| 1322 | static void hdmi_set_acr(u32 freq, u8 *acr) | 1314 | static void hdmi_set_acr(u32 freq, u8 *acr) |
| 1323 | { | 1315 | { |
| 1324 | u32 n, cts; | 1316 | u32 n, cts; |
| @@ -1914,7 +1906,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector, | |||
| 1914 | struct drm_display_mode *adjusted_mode) | 1906 | struct drm_display_mode *adjusted_mode) |
| 1915 | { | 1907 | { |
| 1916 | struct drm_display_mode *m; | 1908 | struct drm_display_mode *m; |
| 1917 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; | 1909 | struct hdmi_context *hdata = ctx; |
| 1918 | int index; | 1910 | int index; |
| 1919 | 1911 | ||
| 1920 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 1912 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
| @@ -1951,7 +1943,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector, | |||
| 1951 | 1943 | ||
| 1952 | static void hdmi_mode_set(void *ctx, void *mode) | 1944 | static void hdmi_mode_set(void *ctx, void *mode) |
| 1953 | { | 1945 | { |
| 1954 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; | 1946 | struct hdmi_context *hdata = ctx; |
| 1955 | int conf_idx; | 1947 | int conf_idx; |
| 1956 | 1948 | ||
| 1957 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 1949 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
| @@ -1974,7 +1966,7 @@ static void hdmi_get_max_resol(void *ctx, unsigned int *width, | |||
| 1974 | 1966 | ||
| 1975 | static void hdmi_commit(void *ctx) | 1967 | static void hdmi_commit(void *ctx) |
| 1976 | { | 1968 | { |
| 1977 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; | 1969 | struct hdmi_context *hdata = ctx; |
| 1978 | 1970 | ||
| 1979 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 1971 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
| 1980 | 1972 | ||
| @@ -1985,7 +1977,7 @@ static void hdmi_commit(void *ctx) | |||
| 1985 | 1977 | ||
| 1986 | static void hdmi_disable(void *ctx) | 1978 | static void hdmi_disable(void *ctx) |
| 1987 | { | 1979 | { |
| 1988 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; | 1980 | struct hdmi_context *hdata = ctx; |
| 1989 | 1981 | ||
| 1990 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 1982 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
| 1991 | 1983 | ||
| @@ -1996,7 +1988,14 @@ static void hdmi_disable(void *ctx) | |||
| 1996 | } | 1988 | } |
| 1997 | } | 1989 | } |
| 1998 | 1990 | ||
| 1999 | static struct exynos_hdmi_manager_ops manager_ops = { | 1991 | static struct exynos_hdmi_ops hdmi_ops = { |
| 1992 | /* display */ | ||
| 1993 | .is_connected = hdmi_is_connected, | ||
| 1994 | .get_edid = hdmi_get_edid, | ||
| 1995 | .check_timing = hdmi_check_timing, | ||
| 1996 | .power_on = hdmi_display_power_on, | ||
| 1997 | |||
| 1998 | /* manager */ | ||
| 2000 | .mode_fixup = hdmi_mode_fixup, | 1999 | .mode_fixup = hdmi_mode_fixup, |
| 2001 | .mode_set = hdmi_mode_set, | 2000 | .mode_set = hdmi_mode_set, |
| 2002 | .get_max_resol = hdmi_get_max_resol, | 2001 | .get_max_resol = hdmi_get_max_resol, |
| @@ -2020,7 +2019,7 @@ static void hdmi_hotplug_func(struct work_struct *work) | |||
| 2020 | static irqreturn_t hdmi_irq_handler(int irq, void *arg) | 2019 | static irqreturn_t hdmi_irq_handler(int irq, void *arg) |
| 2021 | { | 2020 | { |
| 2022 | struct exynos_drm_hdmi_context *ctx = arg; | 2021 | struct exynos_drm_hdmi_context *ctx = arg; |
| 2023 | struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx; | 2022 | struct hdmi_context *hdata = ctx->ctx; |
| 2024 | u32 intc_flag; | 2023 | u32 intc_flag; |
| 2025 | 2024 | ||
| 2026 | intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG); | 2025 | intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG); |
| @@ -2173,7 +2172,7 @@ static int hdmi_runtime_suspend(struct device *dev) | |||
| 2173 | 2172 | ||
| 2174 | DRM_DEBUG_KMS("%s\n", __func__); | 2173 | DRM_DEBUG_KMS("%s\n", __func__); |
| 2175 | 2174 | ||
| 2176 | hdmi_resource_poweroff((struct hdmi_context *)ctx->ctx); | 2175 | hdmi_resource_poweroff(ctx->ctx); |
| 2177 | 2176 | ||
| 2178 | return 0; | 2177 | return 0; |
| 2179 | } | 2178 | } |
| @@ -2184,7 +2183,7 @@ static int hdmi_runtime_resume(struct device *dev) | |||
| 2184 | 2183 | ||
| 2185 | DRM_DEBUG_KMS("%s\n", __func__); | 2184 | DRM_DEBUG_KMS("%s\n", __func__); |
| 2186 | 2185 | ||
| 2187 | hdmi_resource_poweron((struct hdmi_context *)ctx->ctx); | 2186 | hdmi_resource_poweron(ctx->ctx); |
| 2188 | 2187 | ||
| 2189 | return 0; | 2188 | return 0; |
| 2190 | } | 2189 | } |
| @@ -2322,8 +2321,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev) | |||
| 2322 | hdata->irq = res->start; | 2321 | hdata->irq = res->start; |
| 2323 | 2322 | ||
| 2324 | /* register specific callbacks to common hdmi. */ | 2323 | /* register specific callbacks to common hdmi. */ |
| 2325 | exynos_drm_display_ops_register(&display_ops); | 2324 | exynos_hdmi_ops_register(&hdmi_ops); |
| 2326 | exynos_drm_manager_ops_register(&manager_ops); | ||
| 2327 | 2325 | ||
| 2328 | hdmi_resource_poweron(hdata); | 2326 | hdmi_resource_poweron(hdata); |
| 2329 | 2327 | ||
| @@ -2351,7 +2349,7 @@ err_data: | |||
| 2351 | static int __devexit hdmi_remove(struct platform_device *pdev) | 2349 | static int __devexit hdmi_remove(struct platform_device *pdev) |
| 2352 | { | 2350 | { |
| 2353 | struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev); | 2351 | struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev); |
| 2354 | struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx; | 2352 | struct hdmi_context *hdata = ctx->ctx; |
| 2355 | 2353 | ||
| 2356 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 2354 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
| 2357 | 2355 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 4d5f41e19527..e15438c01129 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c | |||
| @@ -37,7 +37,8 @@ | |||
| 37 | #include "exynos_drm_drv.h" | 37 | #include "exynos_drm_drv.h" |
| 38 | #include "exynos_drm_hdmi.h" | 38 | #include "exynos_drm_hdmi.h" |
| 39 | 39 | ||
| 40 | #define HDMI_OVERLAY_NUMBER 3 | 40 | #define MIXER_WIN_NR 3 |
| 41 | #define MIXER_DEFAULT_WIN 0 | ||
| 41 | 42 | ||
| 42 | #define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev)) | 43 | #define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev)) |
| 43 | 44 | ||
| @@ -75,16 +76,12 @@ struct mixer_resources { | |||
| 75 | }; | 76 | }; |
| 76 | 77 | ||
| 77 | struct mixer_context { | 78 | struct mixer_context { |
| 78 | struct fb_videomode *default_timing; | ||
| 79 | unsigned int default_win; | ||
| 80 | unsigned int default_bpp; | ||
| 81 | unsigned int irq; | 79 | unsigned int irq; |
| 82 | int pipe; | 80 | int pipe; |
| 83 | bool interlace; | 81 | bool interlace; |
| 84 | bool vp_enabled; | ||
| 85 | 82 | ||
| 86 | struct mixer_resources mixer_res; | 83 | struct mixer_resources mixer_res; |
| 87 | struct hdmi_win_data win_data[HDMI_OVERLAY_NUMBER]; | 84 | struct hdmi_win_data win_data[MIXER_WIN_NR]; |
| 88 | }; | 85 | }; |
| 89 | 86 | ||
| 90 | static const u8 filter_y_horiz_tap8[] = { | 87 | static const u8 filter_y_horiz_tap8[] = { |
| @@ -643,9 +640,9 @@ static void mixer_win_mode_set(void *ctx, | |||
| 643 | 640 | ||
| 644 | win = overlay->zpos; | 641 | win = overlay->zpos; |
| 645 | if (win == DEFAULT_ZPOS) | 642 | if (win == DEFAULT_ZPOS) |
| 646 | win = mixer_ctx->default_win; | 643 | win = MIXER_DEFAULT_WIN; |
| 647 | 644 | ||
| 648 | if (win < 0 || win > HDMI_OVERLAY_NUMBER) { | 645 | if (win < 0 || win > MIXER_WIN_NR) { |
| 649 | DRM_ERROR("overlay plane[%d] is wrong\n", win); | 646 | DRM_ERROR("overlay plane[%d] is wrong\n", win); |
| 650 | return; | 647 | return; |
| 651 | } | 648 | } |
| @@ -683,9 +680,9 @@ static void mixer_win_commit(void *ctx, int zpos) | |||
| 683 | DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); | 680 | DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); |
| 684 | 681 | ||
| 685 | if (win == DEFAULT_ZPOS) | 682 | if (win == DEFAULT_ZPOS) |
| 686 | win = mixer_ctx->default_win; | 683 | win = MIXER_DEFAULT_WIN; |
| 687 | 684 | ||
| 688 | if (win < 0 || win > HDMI_OVERLAY_NUMBER) { | 685 | if (win < 0 || win > MIXER_WIN_NR) { |
| 689 | DRM_ERROR("overlay plane[%d] is wrong\n", win); | 686 | DRM_ERROR("overlay plane[%d] is wrong\n", win); |
| 690 | return; | 687 | return; |
| 691 | } | 688 | } |
| @@ -706,9 +703,9 @@ static void mixer_win_disable(void *ctx, int zpos) | |||
| 706 | DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); | 703 | DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); |
| 707 | 704 | ||
| 708 | if (win == DEFAULT_ZPOS) | 705 | if (win == DEFAULT_ZPOS) |
| 709 | win = mixer_ctx->default_win; | 706 | win = MIXER_DEFAULT_WIN; |
| 710 | 707 | ||
| 711 | if (win < 0 || win > HDMI_OVERLAY_NUMBER) { | 708 | if (win < 0 || win > MIXER_WIN_NR) { |
| 712 | DRM_ERROR("overlay plane[%d] is wrong\n", win); | 709 | DRM_ERROR("overlay plane[%d] is wrong\n", win); |
| 713 | return; | 710 | return; |
| 714 | } | 711 | } |
| @@ -722,9 +719,12 @@ static void mixer_win_disable(void *ctx, int zpos) | |||
| 722 | spin_unlock_irqrestore(&res->reg_slock, flags); | 719 | spin_unlock_irqrestore(&res->reg_slock, flags); |
| 723 | } | 720 | } |
| 724 | 721 | ||
| 725 | static struct exynos_hdmi_overlay_ops overlay_ops = { | 722 | static struct exynos_mixer_ops mixer_ops = { |
| 723 | /* manager */ | ||
| 726 | .enable_vblank = mixer_enable_vblank, | 724 | .enable_vblank = mixer_enable_vblank, |
| 727 | .disable_vblank = mixer_disable_vblank, | 725 | .disable_vblank = mixer_disable_vblank, |
| 726 | |||
| 727 | /* overlay */ | ||
| 728 | .win_mode_set = mixer_win_mode_set, | 728 | .win_mode_set = mixer_win_mode_set, |
| 729 | .win_commit = mixer_win_commit, | 729 | .win_commit = mixer_win_commit, |
| 730 | .win_disable = mixer_win_disable, | 730 | .win_disable = mixer_win_disable, |
| @@ -771,8 +771,7 @@ static void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc) | |||
| 771 | static irqreturn_t mixer_irq_handler(int irq, void *arg) | 771 | static irqreturn_t mixer_irq_handler(int irq, void *arg) |
| 772 | { | 772 | { |
| 773 | struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg; | 773 | struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg; |
| 774 | struct mixer_context *ctx = | 774 | struct mixer_context *ctx = drm_hdmi_ctx->ctx; |
| 775 | (struct mixer_context *)drm_hdmi_ctx->ctx; | ||
| 776 | struct mixer_resources *res = &ctx->mixer_res; | 775 | struct mixer_resources *res = &ctx->mixer_res; |
| 777 | u32 val, val_base; | 776 | u32 val, val_base; |
| 778 | 777 | ||
| @@ -902,7 +901,7 @@ static int mixer_runtime_resume(struct device *dev) | |||
| 902 | 901 | ||
| 903 | DRM_DEBUG_KMS("resume - start\n"); | 902 | DRM_DEBUG_KMS("resume - start\n"); |
| 904 | 903 | ||
| 905 | mixer_resource_poweron((struct mixer_context *)ctx->ctx); | 904 | mixer_resource_poweron(ctx->ctx); |
| 906 | 905 | ||
| 907 | return 0; | 906 | return 0; |
| 908 | } | 907 | } |
| @@ -913,7 +912,7 @@ static int mixer_runtime_suspend(struct device *dev) | |||
| 913 | 912 | ||
| 914 | DRM_DEBUG_KMS("suspend - start\n"); | 913 | DRM_DEBUG_KMS("suspend - start\n"); |
| 915 | 914 | ||
| 916 | mixer_resource_poweroff((struct mixer_context *)ctx->ctx); | 915 | mixer_resource_poweroff(ctx->ctx); |
| 917 | 916 | ||
| 918 | return 0; | 917 | return 0; |
| 919 | } | 918 | } |
| @@ -926,8 +925,7 @@ static const struct dev_pm_ops mixer_pm_ops = { | |||
| 926 | static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx, | 925 | static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx, |
| 927 | struct platform_device *pdev) | 926 | struct platform_device *pdev) |
| 928 | { | 927 | { |
| 929 | struct mixer_context *mixer_ctx = | 928 | struct mixer_context *mixer_ctx = ctx->ctx; |
| 930 | (struct mixer_context *)ctx->ctx; | ||
| 931 | struct device *dev = &pdev->dev; | 929 | struct device *dev = &pdev->dev; |
| 932 | struct mixer_resources *mixer_res = &mixer_ctx->mixer_res; | 930 | struct mixer_resources *mixer_res = &mixer_ctx->mixer_res; |
| 933 | struct resource *res; | 931 | struct resource *res; |
| @@ -1076,7 +1074,7 @@ static int __devinit mixer_probe(struct platform_device *pdev) | |||
| 1076 | goto fail; | 1074 | goto fail; |
| 1077 | 1075 | ||
| 1078 | /* register specific callback point to common hdmi. */ | 1076 | /* register specific callback point to common hdmi. */ |
| 1079 | exynos_drm_overlay_ops_register(&overlay_ops); | 1077 | exynos_mixer_ops_register(&mixer_ops); |
| 1080 | 1078 | ||
| 1081 | mixer_resource_poweron(ctx); | 1079 | mixer_resource_poweron(ctx); |
| 1082 | 1080 | ||
| @@ -1093,7 +1091,7 @@ static int mixer_remove(struct platform_device *pdev) | |||
| 1093 | struct device *dev = &pdev->dev; | 1091 | struct device *dev = &pdev->dev; |
| 1094 | struct exynos_drm_hdmi_context *drm_hdmi_ctx = | 1092 | struct exynos_drm_hdmi_context *drm_hdmi_ctx = |
| 1095 | platform_get_drvdata(pdev); | 1093 | platform_get_drvdata(pdev); |
| 1096 | struct mixer_context *ctx = (struct mixer_context *)drm_hdmi_ctx->ctx; | 1094 | struct mixer_context *ctx = drm_hdmi_ctx->ctx; |
| 1097 | 1095 | ||
| 1098 | dev_info(dev, "remove successful\n"); | 1096 | dev_info(dev, "remove successful\n"); |
| 1099 | 1097 | ||
diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.h b/drivers/gpu/drm/gma500/mdfld_dsi_output.h index 21071cef92a4..36eb0744841c 100644 --- a/drivers/gpu/drm/gma500/mdfld_dsi_output.h +++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.h | |||
| @@ -29,7 +29,6 @@ | |||
| 29 | #define __MDFLD_DSI_OUTPUT_H__ | 29 | #define __MDFLD_DSI_OUTPUT_H__ |
| 30 | 30 | ||
| 31 | #include <linux/backlight.h> | 31 | #include <linux/backlight.h> |
| 32 | #include <linux/version.h> | ||
| 33 | #include <drm/drmP.h> | 32 | #include <drm/drmP.h> |
| 34 | #include <drm/drm.h> | 33 | #include <drm/drm.h> |
| 35 | #include <drm/drm_crtc.h> | 34 | #include <drm/drm_crtc.h> |
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 2c8a60c3b98e..f920fb5e42b6 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c | |||
| @@ -129,6 +129,7 @@ static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv) | |||
| 129 | if (buf_priv->currently_mapped == I810_BUF_MAPPED) | 129 | if (buf_priv->currently_mapped == I810_BUF_MAPPED) |
| 130 | return -EINVAL; | 130 | return -EINVAL; |
| 131 | 131 | ||
| 132 | /* This is all entirely broken */ | ||
| 132 | down_write(¤t->mm->mmap_sem); | 133 | down_write(¤t->mm->mmap_sem); |
| 133 | old_fops = file_priv->filp->f_op; | 134 | old_fops = file_priv->filp->f_op; |
| 134 | file_priv->filp->f_op = &i810_buffer_fops; | 135 | file_priv->filp->f_op = &i810_buffer_fops; |
| @@ -157,11 +158,8 @@ static int i810_unmap_buffer(struct drm_buf *buf) | |||
| 157 | if (buf_priv->currently_mapped != I810_BUF_MAPPED) | 158 | if (buf_priv->currently_mapped != I810_BUF_MAPPED) |
| 158 | return -EINVAL; | 159 | return -EINVAL; |
| 159 | 160 | ||
| 160 | down_write(¤t->mm->mmap_sem); | 161 | retcode = vm_munmap((unsigned long)buf_priv->virtual, |
| 161 | retcode = do_munmap(current->mm, | ||
| 162 | (unsigned long)buf_priv->virtual, | ||
| 163 | (size_t) buf->total); | 162 | (size_t) buf->total); |
| 164 | up_write(¤t->mm->mmap_sem); | ||
| 165 | 163 | ||
| 166 | buf_priv->currently_mapped = I810_BUF_UNMAPPED; | 164 | buf_priv->currently_mapped = I810_BUF_UNMAPPED; |
| 167 | buf_priv->virtual = NULL; | 165 | buf_priv->virtual = NULL; |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index b505b70dba05..e6162a1681f0 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
| @@ -1224,6 +1224,9 @@ static int i915_emon_status(struct seq_file *m, void *unused) | |||
| 1224 | unsigned long temp, chipset, gfx; | 1224 | unsigned long temp, chipset, gfx; |
| 1225 | int ret; | 1225 | int ret; |
| 1226 | 1226 | ||
| 1227 | if (!IS_GEN5(dev)) | ||
| 1228 | return -ENODEV; | ||
| 1229 | |||
| 1227 | ret = mutex_lock_interruptible(&dev->struct_mutex); | 1230 | ret = mutex_lock_interruptible(&dev->struct_mutex); |
| 1228 | if (ret) | 1231 | if (ret) |
| 1229 | return ret; | 1232 | return ret; |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 785f67f963ef..ba60f3c8f911 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
| @@ -1701,6 +1701,9 @@ void i915_update_gfx_val(struct drm_i915_private *dev_priv) | |||
| 1701 | unsigned long diffms; | 1701 | unsigned long diffms; |
| 1702 | u32 count; | 1702 | u32 count; |
| 1703 | 1703 | ||
| 1704 | if (dev_priv->info->gen != 5) | ||
| 1705 | return; | ||
| 1706 | |||
| 1704 | getrawmonotonic(&now); | 1707 | getrawmonotonic(&now); |
| 1705 | diff1 = timespec_sub(now, dev_priv->last_time2); | 1708 | diff1 = timespec_sub(now, dev_priv->last_time2); |
| 1706 | 1709 | ||
| @@ -2121,12 +2124,14 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
| 2121 | setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, | 2124 | setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, |
| 2122 | (unsigned long) dev); | 2125 | (unsigned long) dev); |
| 2123 | 2126 | ||
| 2124 | spin_lock(&mchdev_lock); | 2127 | if (IS_GEN5(dev)) { |
| 2125 | i915_mch_dev = dev_priv; | 2128 | spin_lock(&mchdev_lock); |
| 2126 | dev_priv->mchdev_lock = &mchdev_lock; | 2129 | i915_mch_dev = dev_priv; |
| 2127 | spin_unlock(&mchdev_lock); | 2130 | dev_priv->mchdev_lock = &mchdev_lock; |
| 2131 | spin_unlock(&mchdev_lock); | ||
| 2128 | 2132 | ||
| 2129 | ips_ping_for_i915_load(); | 2133 | ips_ping_for_i915_load(); |
| 2134 | } | ||
| 2130 | 2135 | ||
| 2131 | return 0; | 2136 | return 0; |
| 2132 | 2137 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index dfa55e7478fb..ae8a64f9f845 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -64,7 +64,7 @@ MODULE_PARM_DESC(semaphores, | |||
| 64 | "Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))"); | 64 | "Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))"); |
| 65 | 65 | ||
| 66 | int i915_enable_rc6 __read_mostly = -1; | 66 | int i915_enable_rc6 __read_mostly = -1; |
| 67 | module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); | 67 | module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0400); |
| 68 | MODULE_PARM_DESC(i915_enable_rc6, | 68 | MODULE_PARM_DESC(i915_enable_rc6, |
| 69 | "Enable power-saving render C-state 6. " | 69 | "Enable power-saving render C-state 6. " |
| 70 | "Different stages can be selected via bitmask values " | 70 | "Different stages can be selected via bitmask values " |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4c65c639f772..0d1e4b7b4b99 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -1087,11 +1087,9 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
| 1087 | if (obj == NULL) | 1087 | if (obj == NULL) |
| 1088 | return -ENOENT; | 1088 | return -ENOENT; |
| 1089 | 1089 | ||
| 1090 | down_write(¤t->mm->mmap_sem); | 1090 | addr = vm_mmap(obj->filp, 0, args->size, |
| 1091 | addr = do_mmap(obj->filp, 0, args->size, | ||
| 1092 | PROT_READ | PROT_WRITE, MAP_SHARED, | 1091 | PROT_READ | PROT_WRITE, MAP_SHARED, |
| 1093 | args->offset); | 1092 | args->offset); |
| 1094 | up_write(¤t->mm->mmap_sem); | ||
| 1095 | drm_gem_object_unreference_unlocked(obj); | 1093 | drm_gem_object_unreference_unlocked(obj); |
| 1096 | if (IS_ERR((void *)addr)) | 1094 | if (IS_ERR((void *)addr)) |
| 1097 | return addr; | 1095 | return addr; |
| @@ -1493,6 +1491,7 @@ i915_gem_object_move_off_active(struct drm_i915_gem_object *obj) | |||
| 1493 | { | 1491 | { |
| 1494 | list_del_init(&obj->ring_list); | 1492 | list_del_init(&obj->ring_list); |
| 1495 | obj->last_rendering_seqno = 0; | 1493 | obj->last_rendering_seqno = 0; |
| 1494 | obj->last_fenced_seqno = 0; | ||
| 1496 | } | 1495 | } |
| 1497 | 1496 | ||
| 1498 | static void | 1497 | static void |
| @@ -1521,6 +1520,7 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) | |||
| 1521 | BUG_ON(!list_empty(&obj->gpu_write_list)); | 1520 | BUG_ON(!list_empty(&obj->gpu_write_list)); |
| 1522 | BUG_ON(!obj->active); | 1521 | BUG_ON(!obj->active); |
| 1523 | obj->ring = NULL; | 1522 | obj->ring = NULL; |
| 1523 | obj->last_fenced_ring = NULL; | ||
| 1524 | 1524 | ||
| 1525 | i915_gem_object_move_off_active(obj); | 1525 | i915_gem_object_move_off_active(obj); |
| 1526 | obj->fenced_gpu_access = false; | 1526 | obj->fenced_gpu_access = false; |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index f51a696486cb..de431942ded4 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
| @@ -1133,6 +1133,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
| 1133 | return -EINVAL; | 1133 | return -EINVAL; |
| 1134 | } | 1134 | } |
| 1135 | 1135 | ||
| 1136 | if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) { | ||
| 1137 | DRM_DEBUG("execbuf with %u cliprects\n", | ||
| 1138 | args->num_cliprects); | ||
| 1139 | return -EINVAL; | ||
| 1140 | } | ||
| 1136 | cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects), | 1141 | cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects), |
| 1137 | GFP_KERNEL); | 1142 | GFP_KERNEL); |
| 1138 | if (cliprects == NULL) { | 1143 | if (cliprects == NULL) { |
| @@ -1404,7 +1409,8 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, | |||
| 1404 | struct drm_i915_gem_exec_object2 *exec2_list = NULL; | 1409 | struct drm_i915_gem_exec_object2 *exec2_list = NULL; |
| 1405 | int ret; | 1410 | int ret; |
| 1406 | 1411 | ||
| 1407 | if (args->buffer_count < 1) { | 1412 | if (args->buffer_count < 1 || |
| 1413 | args->buffer_count > UINT_MAX / sizeof(*exec2_list)) { | ||
| 1408 | DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count); | 1414 | DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count); |
| 1409 | return -EINVAL; | 1415 | return -EINVAL; |
| 1410 | } | 1416 | } |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2abf4eb94039..9d24d65f0c3e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -568,6 +568,7 @@ | |||
| 568 | #define CM0_MASK_SHIFT 16 | 568 | #define CM0_MASK_SHIFT 16 |
| 569 | #define CM0_IZ_OPT_DISABLE (1<<6) | 569 | #define CM0_IZ_OPT_DISABLE (1<<6) |
| 570 | #define CM0_ZR_OPT_DISABLE (1<<5) | 570 | #define CM0_ZR_OPT_DISABLE (1<<5) |
| 571 | #define CM0_STC_EVICT_DISABLE_LRA_SNB (1<<5) | ||
| 571 | #define CM0_DEPTH_EVICT_DISABLE (1<<4) | 572 | #define CM0_DEPTH_EVICT_DISABLE (1<<4) |
| 572 | #define CM0_COLOR_EVICT_DISABLE (1<<3) | 573 | #define CM0_COLOR_EVICT_DISABLE (1<<3) |
| 573 | #define CM0_DEPTH_WRITE_DISABLE (1<<1) | 574 | #define CM0_DEPTH_WRITE_DISABLE (1<<1) |
| @@ -3728,6 +3729,9 @@ | |||
| 3728 | #define GT_FIFO_FREE_ENTRIES 0x120008 | 3729 | #define GT_FIFO_FREE_ENTRIES 0x120008 |
| 3729 | #define GT_FIFO_NUM_RESERVED_ENTRIES 20 | 3730 | #define GT_FIFO_NUM_RESERVED_ENTRIES 20 |
| 3730 | 3731 | ||
| 3732 | #define GEN6_UCGCTL1 0x9400 | ||
| 3733 | # define GEN6_BLBUNIT_CLOCK_GATE_DISABLE (1 << 5) | ||
| 3734 | |||
| 3731 | #define GEN6_UCGCTL2 0x9404 | 3735 | #define GEN6_UCGCTL2 0x9404 |
| 3732 | # define GEN6_RCZUNIT_CLOCK_GATE_DISABLE (1 << 13) | 3736 | # define GEN6_RCZUNIT_CLOCK_GATE_DISABLE (1 << 13) |
| 3733 | # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) | 3737 | # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 4d3d736a4f56..90b9793fd5da 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
| @@ -430,8 +430,8 @@ intel_crt_detect(struct drm_connector *connector, bool force) | |||
| 430 | { | 430 | { |
| 431 | struct drm_device *dev = connector->dev; | 431 | struct drm_device *dev = connector->dev; |
| 432 | struct intel_crt *crt = intel_attached_crt(connector); | 432 | struct intel_crt *crt = intel_attached_crt(connector); |
| 433 | struct drm_crtc *crtc; | ||
| 434 | enum drm_connector_status status; | 433 | enum drm_connector_status status; |
| 434 | struct intel_load_detect_pipe tmp; | ||
| 435 | 435 | ||
| 436 | if (I915_HAS_HOTPLUG(dev)) { | 436 | if (I915_HAS_HOTPLUG(dev)) { |
| 437 | if (intel_crt_detect_hotplug(connector)) { | 437 | if (intel_crt_detect_hotplug(connector)) { |
| @@ -450,23 +450,16 @@ intel_crt_detect(struct drm_connector *connector, bool force) | |||
| 450 | return connector->status; | 450 | return connector->status; |
| 451 | 451 | ||
| 452 | /* for pre-945g platforms use load detect */ | 452 | /* for pre-945g platforms use load detect */ |
| 453 | crtc = crt->base.base.crtc; | 453 | if (intel_get_load_detect_pipe(&crt->base, connector, NULL, |
| 454 | if (crtc && crtc->enabled) { | 454 | &tmp)) { |
| 455 | status = intel_crt_load_detect(crt); | 455 | if (intel_crt_detect_ddc(connector)) |
| 456 | } else { | 456 | status = connector_status_connected; |
| 457 | struct intel_load_detect_pipe tmp; | 457 | else |
| 458 | 458 | status = intel_crt_load_detect(crt); | |
| 459 | if (intel_get_load_detect_pipe(&crt->base, connector, NULL, | 459 | intel_release_load_detect_pipe(&crt->base, connector, |
| 460 | &tmp)) { | 460 | &tmp); |
| 461 | if (intel_crt_detect_ddc(connector)) | 461 | } else |
| 462 | status = connector_status_connected; | 462 | status = connector_status_unknown; |
| 463 | else | ||
| 464 | status = intel_crt_load_detect(crt); | ||
| 465 | intel_release_load_detect_pipe(&crt->base, connector, | ||
| 466 | &tmp); | ||
| 467 | } else | ||
| 468 | status = connector_status_unknown; | ||
| 469 | } | ||
| 470 | 463 | ||
| 471 | return status; | 464 | return status; |
| 472 | } | 465 | } |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 91b35fd1db8c..1b1cf3b3ff51 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -2245,6 +2245,33 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
| 2245 | } | 2245 | } |
| 2246 | 2246 | ||
| 2247 | static int | 2247 | static int |
| 2248 | intel_finish_fb(struct drm_framebuffer *old_fb) | ||
| 2249 | { | ||
| 2250 | struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj; | ||
| 2251 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | ||
| 2252 | bool was_interruptible = dev_priv->mm.interruptible; | ||
| 2253 | int ret; | ||
| 2254 | |||
| 2255 | wait_event(dev_priv->pending_flip_queue, | ||
| 2256 | atomic_read(&dev_priv->mm.wedged) || | ||
| 2257 | atomic_read(&obj->pending_flip) == 0); | ||
| 2258 | |||
| 2259 | /* Big Hammer, we also need to ensure that any pending | ||
| 2260 | * MI_WAIT_FOR_EVENT inside a user batch buffer on the | ||
| 2261 | * current scanout is retired before unpinning the old | ||
| 2262 | * framebuffer. | ||
| 2263 | * | ||
| 2264 | * This should only fail upon a hung GPU, in which case we | ||
| 2265 | * can safely continue. | ||
| 2266 | */ | ||
| 2267 | dev_priv->mm.interruptible = false; | ||
| 2268 | ret = i915_gem_object_finish_gpu(obj); | ||
| 2269 | dev_priv->mm.interruptible = was_interruptible; | ||
| 2270 | |||
| 2271 | return ret; | ||
| 2272 | } | ||
| 2273 | |||
| 2274 | static int | ||
| 2248 | intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | 2275 | intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, |
| 2249 | struct drm_framebuffer *old_fb) | 2276 | struct drm_framebuffer *old_fb) |
| 2250 | { | 2277 | { |
| @@ -2282,25 +2309,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 2282 | return ret; | 2309 | return ret; |
| 2283 | } | 2310 | } |
| 2284 | 2311 | ||
| 2285 | if (old_fb) { | 2312 | if (old_fb) |
| 2286 | struct drm_i915_private *dev_priv = dev->dev_private; | 2313 | intel_finish_fb(old_fb); |
| 2287 | struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj; | ||
| 2288 | |||
| 2289 | wait_event(dev_priv->pending_flip_queue, | ||
| 2290 | atomic_read(&dev_priv->mm.wedged) || | ||
| 2291 | atomic_read(&obj->pending_flip) == 0); | ||
| 2292 | |||
| 2293 | /* Big Hammer, we also need to ensure that any pending | ||
| 2294 | * MI_WAIT_FOR_EVENT inside a user batch buffer on the | ||
| 2295 | * current scanout is retired before unpinning the old | ||
| 2296 | * framebuffer. | ||
| 2297 | * | ||
| 2298 | * This should only fail upon a hung GPU, in which case we | ||
| 2299 | * can safely continue. | ||
| 2300 | */ | ||
| 2301 | ret = i915_gem_object_finish_gpu(obj); | ||
| 2302 | (void) ret; | ||
| 2303 | } | ||
| 2304 | 2314 | ||
| 2305 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, | 2315 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, |
| 2306 | LEAVE_ATOMIC_MODE_SET); | 2316 | LEAVE_ATOMIC_MODE_SET); |
| @@ -3371,6 +3381,23 @@ static void intel_crtc_disable(struct drm_crtc *crtc) | |||
| 3371 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; | 3381 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; |
| 3372 | struct drm_device *dev = crtc->dev; | 3382 | struct drm_device *dev = crtc->dev; |
| 3373 | 3383 | ||
| 3384 | /* Flush any pending WAITs before we disable the pipe. Note that | ||
| 3385 | * we need to drop the struct_mutex in order to acquire it again | ||
| 3386 | * during the lowlevel dpms routines around a couple of the | ||
| 3387 | * operations. It does not look trivial nor desirable to move | ||
| 3388 | * that locking higher. So instead we leave a window for the | ||
| 3389 | * submission of further commands on the fb before we can actually | ||
| 3390 | * disable it. This race with userspace exists anyway, and we can | ||
| 3391 | * only rely on the pipe being disabled by userspace after it | ||
| 3392 | * receives the hotplug notification and has flushed any pending | ||
| 3393 | * batches. | ||
| 3394 | */ | ||
| 3395 | if (crtc->fb) { | ||
| 3396 | mutex_lock(&dev->struct_mutex); | ||
| 3397 | intel_finish_fb(crtc->fb); | ||
| 3398 | mutex_unlock(&dev->struct_mutex); | ||
| 3399 | } | ||
| 3400 | |||
| 3374 | crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); | 3401 | crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); |
| 3375 | assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane); | 3402 | assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane); |
| 3376 | assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe); | 3403 | assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe); |
| @@ -3451,8 +3478,11 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, | |||
| 3451 | return false; | 3478 | return false; |
| 3452 | } | 3479 | } |
| 3453 | 3480 | ||
| 3454 | /* All interlaced capable intel hw wants timings in frames. */ | 3481 | /* All interlaced capable intel hw wants timings in frames. Note though |
| 3455 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 3482 | * that intel_lvds_mode_fixup does some funny tricks with the crtc |
| 3483 | * timings, so we need to be careful not to clobber these.*/ | ||
| 3484 | if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET)) | ||
| 3485 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
| 3456 | 3486 | ||
| 3457 | return true; | 3487 | return true; |
| 3458 | } | 3488 | } |
| @@ -7042,9 +7072,6 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) | |||
| 7042 | struct drm_device *dev = crtc->dev; | 7072 | struct drm_device *dev = crtc->dev; |
| 7043 | drm_i915_private_t *dev_priv = dev->dev_private; | 7073 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 7044 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 7074 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 7045 | int pipe = intel_crtc->pipe; | ||
| 7046 | int dpll_reg = DPLL(pipe); | ||
| 7047 | int dpll = I915_READ(dpll_reg); | ||
| 7048 | 7075 | ||
| 7049 | if (HAS_PCH_SPLIT(dev)) | 7076 | if (HAS_PCH_SPLIT(dev)) |
| 7050 | return; | 7077 | return; |
| @@ -7057,10 +7084,15 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) | |||
| 7057 | * the manual case. | 7084 | * the manual case. |
| 7058 | */ | 7085 | */ |
| 7059 | if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) { | 7086 | if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) { |
| 7087 | int pipe = intel_crtc->pipe; | ||
| 7088 | int dpll_reg = DPLL(pipe); | ||
| 7089 | u32 dpll; | ||
| 7090 | |||
| 7060 | DRM_DEBUG_DRIVER("downclocking LVDS\n"); | 7091 | DRM_DEBUG_DRIVER("downclocking LVDS\n"); |
| 7061 | 7092 | ||
| 7062 | assert_panel_unlocked(dev_priv, pipe); | 7093 | assert_panel_unlocked(dev_priv, pipe); |
| 7063 | 7094 | ||
| 7095 | dpll = I915_READ(dpll_reg); | ||
| 7064 | dpll |= DISPLAY_RATE_SELECT_FPA1; | 7096 | dpll |= DISPLAY_RATE_SELECT_FPA1; |
| 7065 | I915_WRITE(dpll_reg, dpll); | 7097 | I915_WRITE(dpll_reg, dpll); |
| 7066 | intel_wait_for_vblank(dev, pipe); | 7098 | intel_wait_for_vblank(dev, pipe); |
| @@ -7068,7 +7100,6 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) | |||
| 7068 | if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) | 7100 | if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) |
| 7069 | DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); | 7101 | DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); |
| 7070 | } | 7102 | } |
| 7071 | |||
| 7072 | } | 7103 | } |
| 7073 | 7104 | ||
| 7074 | /** | 7105 | /** |
| @@ -7438,7 +7469,13 @@ static int intel_gen6_queue_flip(struct drm_device *dev, | |||
| 7438 | OUT_RING(fb->pitches[0] | obj->tiling_mode); | 7469 | OUT_RING(fb->pitches[0] | obj->tiling_mode); |
| 7439 | OUT_RING(obj->gtt_offset); | 7470 | OUT_RING(obj->gtt_offset); |
| 7440 | 7471 | ||
| 7441 | pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; | 7472 | /* Contrary to the suggestions in the documentation, |
| 7473 | * "Enable Panel Fitter" does not seem to be required when page | ||
| 7474 | * flipping with a non-native mode, and worse causes a normal | ||
| 7475 | * modeset to fail. | ||
| 7476 | * pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; | ||
| 7477 | */ | ||
| 7478 | pf = 0; | ||
| 7442 | pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; | 7479 | pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; |
| 7443 | OUT_RING(pf | pipesrc); | 7480 | OUT_RING(pf | pipesrc); |
| 7444 | ADVANCE_LP_RING(); | 7481 | ADVANCE_LP_RING(); |
| @@ -8529,6 +8566,10 @@ static void gen6_init_clock_gating(struct drm_device *dev) | |||
| 8529 | I915_WRITE(WM2_LP_ILK, 0); | 8566 | I915_WRITE(WM2_LP_ILK, 0); |
| 8530 | I915_WRITE(WM1_LP_ILK, 0); | 8567 | I915_WRITE(WM1_LP_ILK, 0); |
| 8531 | 8568 | ||
| 8569 | I915_WRITE(GEN6_UCGCTL1, | ||
| 8570 | I915_READ(GEN6_UCGCTL1) | | ||
| 8571 | GEN6_BLBUNIT_CLOCK_GATE_DISABLE); | ||
| 8572 | |||
| 8532 | /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock | 8573 | /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock |
| 8533 | * gating disable must be set. Failure to set it results in | 8574 | * gating disable must be set. Failure to set it results in |
| 8534 | * flickering pixels due to Z write ordering failures after | 8575 | * flickering pixels due to Z write ordering failures after |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 110552ff302c..4b637919f74f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -219,14 +219,38 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes) | |||
| 219 | return (max_link_clock * max_lanes * 8) / 10; | 219 | return (max_link_clock * max_lanes * 8) / 10; |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | static bool | ||
| 223 | intel_dp_adjust_dithering(struct intel_dp *intel_dp, | ||
| 224 | struct drm_display_mode *mode, | ||
| 225 | struct drm_display_mode *adjusted_mode) | ||
| 226 | { | ||
| 227 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); | ||
| 228 | int max_lanes = intel_dp_max_lane_count(intel_dp); | ||
| 229 | int max_rate, mode_rate; | ||
| 230 | |||
| 231 | mode_rate = intel_dp_link_required(mode->clock, 24); | ||
| 232 | max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); | ||
| 233 | |||
| 234 | if (mode_rate > max_rate) { | ||
| 235 | mode_rate = intel_dp_link_required(mode->clock, 18); | ||
| 236 | if (mode_rate > max_rate) | ||
| 237 | return false; | ||
| 238 | |||
| 239 | if (adjusted_mode) | ||
| 240 | adjusted_mode->private_flags | ||
| 241 | |= INTEL_MODE_DP_FORCE_6BPC; | ||
| 242 | |||
| 243 | return true; | ||
| 244 | } | ||
| 245 | |||
| 246 | return true; | ||
| 247 | } | ||
| 248 | |||
| 222 | static int | 249 | static int |
| 223 | intel_dp_mode_valid(struct drm_connector *connector, | 250 | intel_dp_mode_valid(struct drm_connector *connector, |
| 224 | struct drm_display_mode *mode) | 251 | struct drm_display_mode *mode) |
| 225 | { | 252 | { |
| 226 | struct intel_dp *intel_dp = intel_attached_dp(connector); | 253 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
| 227 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); | ||
| 228 | int max_lanes = intel_dp_max_lane_count(intel_dp); | ||
| 229 | int max_rate, mode_rate; | ||
| 230 | 254 | ||
| 231 | if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { | 255 | if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { |
| 232 | if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay) | 256 | if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay) |
| @@ -236,16 +260,8 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
| 236 | return MODE_PANEL; | 260 | return MODE_PANEL; |
| 237 | } | 261 | } |
| 238 | 262 | ||
| 239 | mode_rate = intel_dp_link_required(mode->clock, 24); | 263 | if (!intel_dp_adjust_dithering(intel_dp, mode, NULL)) |
| 240 | max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); | 264 | return MODE_CLOCK_HIGH; |
| 241 | |||
| 242 | if (mode_rate > max_rate) { | ||
| 243 | mode_rate = intel_dp_link_required(mode->clock, 18); | ||
| 244 | if (mode_rate > max_rate) | ||
| 245 | return MODE_CLOCK_HIGH; | ||
| 246 | else | ||
| 247 | mode->private_flags |= INTEL_MODE_DP_FORCE_6BPC; | ||
| 248 | } | ||
| 249 | 265 | ||
| 250 | if (mode->clock < 10000) | 266 | if (mode->clock < 10000) |
| 251 | return MODE_CLOCK_LOW; | 267 | return MODE_CLOCK_LOW; |
| @@ -672,7 +688,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 672 | int lane_count, clock; | 688 | int lane_count, clock; |
| 673 | int max_lane_count = intel_dp_max_lane_count(intel_dp); | 689 | int max_lane_count = intel_dp_max_lane_count(intel_dp); |
| 674 | int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; | 690 | int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; |
| 675 | int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; | 691 | int bpp; |
| 676 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; | 692 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; |
| 677 | 693 | ||
| 678 | if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { | 694 | if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { |
| @@ -686,6 +702,11 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 686 | mode->clock = intel_dp->panel_fixed_mode->clock; | 702 | mode->clock = intel_dp->panel_fixed_mode->clock; |
| 687 | } | 703 | } |
| 688 | 704 | ||
| 705 | if (!intel_dp_adjust_dithering(intel_dp, mode, adjusted_mode)) | ||
| 706 | return false; | ||
| 707 | |||
| 708 | bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; | ||
| 709 | |||
| 689 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { | 710 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { |
| 690 | for (clock = 0; clock <= max_clock; clock++) { | 711 | for (clock = 0; clock <= max_clock; clock++) { |
| 691 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); | 712 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 5a14149b3794..715afa153025 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -105,6 +105,10 @@ | |||
| 105 | #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) | 105 | #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) |
| 106 | #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) | 106 | #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) |
| 107 | #define INTEL_MODE_DP_FORCE_6BPC (0x10) | 107 | #define INTEL_MODE_DP_FORCE_6BPC (0x10) |
| 108 | /* This flag must be set by the encoder's mode_fixup if it changes the crtc | ||
| 109 | * timings in the mode to prevent the crtc fixup from overwriting them. | ||
| 110 | * Currently only lvds needs that. */ | ||
| 111 | #define INTEL_MODE_CRTC_TIMINGS_SET (0x20) | ||
| 108 | 112 | ||
| 109 | static inline void | 113 | static inline void |
| 110 | intel_mode_set_pixel_multiplier(struct drm_display_mode *mode, | 114 | intel_mode_set_pixel_multiplier(struct drm_display_mode *mode, |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 19ecd78b8a2c..6e9ee33fd412 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
| @@ -279,6 +279,8 @@ void intel_fb_restore_mode(struct drm_device *dev) | |||
| 279 | struct drm_mode_config *config = &dev->mode_config; | 279 | struct drm_mode_config *config = &dev->mode_config; |
| 280 | struct drm_plane *plane; | 280 | struct drm_plane *plane; |
| 281 | 281 | ||
| 282 | mutex_lock(&dev->mode_config.mutex); | ||
| 283 | |||
| 282 | ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); | 284 | ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); |
| 283 | if (ret) | 285 | if (ret) |
| 284 | DRM_DEBUG("failed to restore crtc mode\n"); | 286 | DRM_DEBUG("failed to restore crtc mode\n"); |
| @@ -286,4 +288,6 @@ void intel_fb_restore_mode(struct drm_device *dev) | |||
| 286 | /* Be sure to shut off any planes that may be active */ | 288 | /* Be sure to shut off any planes that may be active */ |
| 287 | list_for_each_entry(plane, &config->plane_list, head) | 289 | list_for_each_entry(plane, &config->plane_list, head) |
| 288 | plane->funcs->disable_plane(plane); | 290 | plane->funcs->disable_plane(plane); |
| 291 | |||
| 292 | mutex_unlock(&dev->mode_config.mutex); | ||
| 289 | } | 293 | } |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index cae3e5f17a49..2d7f47b56b6a 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
| @@ -136,7 +136,7 @@ static void i9xx_write_infoframe(struct drm_encoder *encoder, | |||
| 136 | 136 | ||
| 137 | val &= ~VIDEO_DIP_SELECT_MASK; | 137 | val &= ~VIDEO_DIP_SELECT_MASK; |
| 138 | 138 | ||
| 139 | I915_WRITE(VIDEO_DIP_CTL, val | port | flags); | 139 | I915_WRITE(VIDEO_DIP_CTL, VIDEO_DIP_ENABLE | val | port | flags); |
| 140 | 140 | ||
| 141 | for (i = 0; i < len; i += 4) { | 141 | for (i = 0; i < len; i += 4) { |
| 142 | I915_WRITE(VIDEO_DIP_DATA, *data); | 142 | I915_WRITE(VIDEO_DIP_DATA, *data); |
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 601c86e664af..8fdc95700218 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
| @@ -390,7 +390,7 @@ int intel_setup_gmbus(struct drm_device *dev) | |||
| 390 | bus->has_gpio = intel_gpio_setup(bus, i); | 390 | bus->has_gpio = intel_gpio_setup(bus, i); |
| 391 | 391 | ||
| 392 | /* XXX force bit banging until GMBUS is fully debugged */ | 392 | /* XXX force bit banging until GMBUS is fully debugged */ |
| 393 | if (bus->has_gpio && IS_GEN2(dev)) | 393 | if (bus->has_gpio) |
| 394 | bus->force_bit = true; | 394 | bus->force_bit = true; |
| 395 | } | 395 | } |
| 396 | 396 | ||
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 95db2e988227..9c71183629c2 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -187,6 +187,8 @@ centre_horizontally(struct drm_display_mode *mode, | |||
| 187 | 187 | ||
| 188 | mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; | 188 | mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; |
| 189 | mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; | 189 | mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; |
| 190 | |||
| 191 | mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; | ||
| 190 | } | 192 | } |
| 191 | 193 | ||
| 192 | static void | 194 | static void |
| @@ -208,6 +210,8 @@ centre_vertically(struct drm_display_mode *mode, | |||
| 208 | 210 | ||
| 209 | mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; | 211 | mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; |
| 210 | mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; | 212 | mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; |
| 213 | |||
| 214 | mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; | ||
| 211 | } | 215 | } |
| 212 | 216 | ||
| 213 | static inline u32 panel_fitter_scaling(u32 source, u32 target) | 217 | static inline u32 panel_fitter_scaling(u32 source, u32 target) |
| @@ -283,6 +287,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
| 283 | for_each_pipe(pipe) | 287 | for_each_pipe(pipe) |
| 284 | I915_WRITE(BCLRPAT(pipe), 0); | 288 | I915_WRITE(BCLRPAT(pipe), 0); |
| 285 | 289 | ||
| 290 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
| 291 | |||
| 286 | switch (intel_lvds->fitting_mode) { | 292 | switch (intel_lvds->fitting_mode) { |
| 287 | case DRM_MODE_SCALE_CENTER: | 293 | case DRM_MODE_SCALE_CENTER: |
| 288 | /* | 294 | /* |
| @@ -744,7 +750,7 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
| 744 | .ident = "Hewlett-Packard t5745", | 750 | .ident = "Hewlett-Packard t5745", |
| 745 | .matches = { | 751 | .matches = { |
| 746 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), | 752 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), |
| 747 | DMI_MATCH(DMI_BOARD_NAME, "hp t5745"), | 753 | DMI_MATCH(DMI_PRODUCT_NAME, "hp t5745"), |
| 748 | }, | 754 | }, |
| 749 | }, | 755 | }, |
| 750 | { | 756 | { |
| @@ -752,7 +758,7 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
| 752 | .ident = "Hewlett-Packard st5747", | 758 | .ident = "Hewlett-Packard st5747", |
| 753 | .matches = { | 759 | .matches = { |
| 754 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), | 760 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), |
| 755 | DMI_MATCH(DMI_BOARD_NAME, "hp st5747"), | 761 | DMI_MATCH(DMI_PRODUCT_NAME, "hp st5747"), |
| 756 | }, | 762 | }, |
| 757 | }, | 763 | }, |
| 758 | { | 764 | { |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 230a141dbea3..48177ec4720e 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
| @@ -47,8 +47,6 @@ intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, | |||
| 47 | adjusted_mode->vtotal = fixed_mode->vtotal; | 47 | adjusted_mode->vtotal = fixed_mode->vtotal; |
| 48 | 48 | ||
| 49 | adjusted_mode->clock = fixed_mode->clock; | 49 | adjusted_mode->clock = fixed_mode->clock; |
| 50 | |||
| 51 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
| 52 | } | 50 | } |
| 53 | 51 | ||
| 54 | /* adjusted_mode has been preset to be the panel's fixed mode */ | 52 | /* adjusted_mode has been preset to be the panel's fixed mode */ |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index e25581a9f60f..62892a826ede 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
| @@ -398,6 +398,17 @@ static int init_render_ring(struct intel_ring_buffer *ring) | |||
| 398 | return ret; | 398 | return ret; |
| 399 | } | 399 | } |
| 400 | 400 | ||
| 401 | |||
| 402 | if (IS_GEN6(dev)) { | ||
| 403 | /* From the Sandybridge PRM, volume 1 part 3, page 24: | ||
| 404 | * "If this bit is set, STCunit will have LRA as replacement | ||
| 405 | * policy. [...] This bit must be reset. LRA replacement | ||
| 406 | * policy is not supported." | ||
| 407 | */ | ||
| 408 | I915_WRITE(CACHE_MODE_0, | ||
| 409 | CM0_STC_EVICT_DISABLE_LRA_SNB << CM0_MASK_SHIFT); | ||
| 410 | } | ||
| 411 | |||
| 401 | if (INTEL_INFO(dev)->gen >= 6) { | 412 | if (INTEL_INFO(dev)->gen >= 6) { |
| 402 | I915_WRITE(INSTPM, | 413 | I915_WRITE(INSTPM, |
| 403 | INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING); | 414 | INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING); |
| @@ -1038,7 +1049,7 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
| 1038 | * of the buffer. | 1049 | * of the buffer. |
| 1039 | */ | 1050 | */ |
| 1040 | ring->effective_size = ring->size; | 1051 | ring->effective_size = ring->size; |
| 1041 | if (IS_I830(ring->dev)) | 1052 | if (IS_I830(ring->dev) || IS_845G(ring->dev)) |
| 1042 | ring->effective_size -= 128; | 1053 | ring->effective_size -= 128; |
| 1043 | 1054 | ||
| 1044 | return 0; | 1055 | return 0; |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index e36b171c1e7d..ae5e748f39bb 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
| @@ -731,6 +731,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, | |||
| 731 | uint16_t width, height; | 731 | uint16_t width, height; |
| 732 | uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; | 732 | uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; |
| 733 | uint16_t h_sync_offset, v_sync_offset; | 733 | uint16_t h_sync_offset, v_sync_offset; |
| 734 | int mode_clock; | ||
| 734 | 735 | ||
| 735 | width = mode->crtc_hdisplay; | 736 | width = mode->crtc_hdisplay; |
| 736 | height = mode->crtc_vdisplay; | 737 | height = mode->crtc_vdisplay; |
| @@ -745,7 +746,11 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, | |||
| 745 | h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start; | 746 | h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start; |
| 746 | v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; | 747 | v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; |
| 747 | 748 | ||
| 748 | dtd->part1.clock = mode->clock / 10; | 749 | mode_clock = mode->clock; |
| 750 | mode_clock /= intel_mode_get_pixel_multiplier(mode) ?: 1; | ||
| 751 | mode_clock /= 10; | ||
| 752 | dtd->part1.clock = mode_clock; | ||
| 753 | |||
| 749 | dtd->part1.h_active = width & 0xff; | 754 | dtd->part1.h_active = width & 0xff; |
| 750 | dtd->part1.h_blank = h_blank_len & 0xff; | 755 | dtd->part1.h_blank = h_blank_len & 0xff; |
| 751 | dtd->part1.h_high = (((width >> 8) & 0xf) << 4) | | 756 | dtd->part1.h_high = (((width >> 8) & 0xf) << 4) | |
| @@ -996,7 +1001,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
| 996 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); | 1001 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); |
| 997 | u32 sdvox; | 1002 | u32 sdvox; |
| 998 | struct intel_sdvo_in_out_map in_out; | 1003 | struct intel_sdvo_in_out_map in_out; |
| 999 | struct intel_sdvo_dtd input_dtd; | 1004 | struct intel_sdvo_dtd input_dtd, output_dtd; |
| 1000 | int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); | 1005 | int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); |
| 1001 | int rate; | 1006 | int rate; |
| 1002 | 1007 | ||
| @@ -1021,20 +1026,13 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
| 1021 | intel_sdvo->attached_output)) | 1026 | intel_sdvo->attached_output)) |
| 1022 | return; | 1027 | return; |
| 1023 | 1028 | ||
| 1024 | /* We have tried to get input timing in mode_fixup, and filled into | 1029 | /* lvds has a special fixed output timing. */ |
| 1025 | * adjusted_mode. | 1030 | if (intel_sdvo->is_lvds) |
| 1026 | */ | 1031 | intel_sdvo_get_dtd_from_mode(&output_dtd, |
| 1027 | if (intel_sdvo->is_tv || intel_sdvo->is_lvds) { | 1032 | intel_sdvo->sdvo_lvds_fixed_mode); |
| 1028 | input_dtd = intel_sdvo->input_dtd; | 1033 | else |
| 1029 | } else { | 1034 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); |
| 1030 | /* Set the output timing to the screen */ | 1035 | (void) intel_sdvo_set_output_timing(intel_sdvo, &output_dtd); |
| 1031 | if (!intel_sdvo_set_target_output(intel_sdvo, | ||
| 1032 | intel_sdvo->attached_output)) | ||
| 1033 | return; | ||
| 1034 | |||
| 1035 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | ||
| 1036 | (void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd); | ||
| 1037 | } | ||
| 1038 | 1036 | ||
| 1039 | /* Set the input timing to the screen. Assume always input 0. */ | 1037 | /* Set the input timing to the screen. Assume always input 0. */ |
| 1040 | if (!intel_sdvo_set_target_input(intel_sdvo)) | 1038 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
| @@ -1052,6 +1050,10 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
| 1052 | !intel_sdvo_set_tv_format(intel_sdvo)) | 1050 | !intel_sdvo_set_tv_format(intel_sdvo)) |
| 1053 | return; | 1051 | return; |
| 1054 | 1052 | ||
| 1053 | /* We have tried to get input timing in mode_fixup, and filled into | ||
| 1054 | * adjusted_mode. | ||
| 1055 | */ | ||
| 1056 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | ||
| 1055 | (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); | 1057 | (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); |
| 1056 | 1058 | ||
| 1057 | switch (pixel_multiplier) { | 1059 | switch (pixel_multiplier) { |
| @@ -1218,8 +1220,14 @@ static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct in | |||
| 1218 | 1220 | ||
| 1219 | static int intel_sdvo_supports_hotplug(struct intel_sdvo *intel_sdvo) | 1221 | static int intel_sdvo_supports_hotplug(struct intel_sdvo *intel_sdvo) |
| 1220 | { | 1222 | { |
| 1223 | struct drm_device *dev = intel_sdvo->base.base.dev; | ||
| 1221 | u8 response[2]; | 1224 | u8 response[2]; |
| 1222 | 1225 | ||
| 1226 | /* HW Erratum: SDVO Hotplug is broken on all i945G chips, there's noise | ||
| 1227 | * on the line. */ | ||
| 1228 | if (IS_I945G(dev) || IS_I945GM(dev)) | ||
| 1229 | return false; | ||
| 1230 | |||
| 1223 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, | 1231 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, |
| 1224 | &response, 2) && response[0]; | 1232 | &response, 2) && response[0]; |
| 1225 | } | 1233 | } |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index a464771a7240..e90dfb625c42 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
| @@ -95,7 +95,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
| 95 | /* must disable */ | 95 | /* must disable */ |
| 96 | sprctl |= SPRITE_TRICKLE_FEED_DISABLE; | 96 | sprctl |= SPRITE_TRICKLE_FEED_DISABLE; |
| 97 | sprctl |= SPRITE_ENABLE; | 97 | sprctl |= SPRITE_ENABLE; |
| 98 | sprctl |= SPRITE_DEST_KEY; | ||
| 99 | 98 | ||
| 100 | /* Sizes are 0 based */ | 99 | /* Sizes are 0 based */ |
| 101 | src_w--; | 100 | src_w--; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 7814a760c164..284bd25d5d21 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c | |||
| @@ -270,7 +270,7 @@ static bool nouveau_dsm_detect(void) | |||
| 270 | struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name}; | 270 | struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name}; |
| 271 | struct pci_dev *pdev = NULL; | 271 | struct pci_dev *pdev = NULL; |
| 272 | int has_dsm = 0; | 272 | int has_dsm = 0; |
| 273 | int has_optimus; | 273 | int has_optimus = 0; |
| 274 | int vga_count = 0; | 274 | int vga_count = 0; |
| 275 | bool guid_valid; | 275 | bool guid_valid; |
| 276 | int retval; | 276 | int retval; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 80963d05b54a..0be4a815e706 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
| @@ -6156,10 +6156,14 @@ dcb_fake_connectors(struct nvbios *bios) | |||
| 6156 | 6156 | ||
| 6157 | /* heuristic: if we ever get a non-zero connector field, assume | 6157 | /* heuristic: if we ever get a non-zero connector field, assume |
| 6158 | * that all the indices are valid and we don't need fake them. | 6158 | * that all the indices are valid and we don't need fake them. |
| 6159 | * | ||
| 6160 | * and, as usual, a blacklist of boards with bad bios data.. | ||
| 6159 | */ | 6161 | */ |
| 6160 | for (i = 0; i < dcbt->entries; i++) { | 6162 | if (!nv_match_device(bios->dev, 0x0392, 0x107d, 0x20a2)) { |
| 6161 | if (dcbt->entry[i].connector) | 6163 | for (i = 0; i < dcbt->entries; i++) { |
| 6162 | return; | 6164 | if (dcbt->entry[i].connector) |
| 6165 | return; | ||
| 6166 | } | ||
| 6163 | } | 6167 | } |
| 6164 | 6168 | ||
| 6165 | /* no useful connector info available, we need to make it up | 6169 | /* no useful connector info available, we need to make it up |
diff --git a/drivers/gpu/drm/nouveau/nouveau_hdmi.c b/drivers/gpu/drm/nouveau/nouveau_hdmi.c index 59ea1c14eca0..c3de36384522 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hdmi.c +++ b/drivers/gpu/drm/nouveau/nouveau_hdmi.c | |||
| @@ -32,7 +32,9 @@ static bool | |||
| 32 | hdmi_sor(struct drm_encoder *encoder) | 32 | hdmi_sor(struct drm_encoder *encoder) |
| 33 | { | 33 | { |
| 34 | struct drm_nouveau_private *dev_priv = encoder->dev->dev_private; | 34 | struct drm_nouveau_private *dev_priv = encoder->dev->dev_private; |
| 35 | if (dev_priv->chipset < 0xa3) | 35 | if (dev_priv->chipset < 0xa3 || |
| 36 | dev_priv->chipset == 0xaa || | ||
| 37 | dev_priv->chipset == 0xac) | ||
| 36 | return false; | 38 | return false; |
| 37 | return true; | 39 | return true; |
| 38 | } | 40 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index e2be95af2e52..77e564667b5c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c | |||
| @@ -29,10 +29,6 @@ | |||
| 29 | #include "nouveau_i2c.h" | 29 | #include "nouveau_i2c.h" |
| 30 | #include "nouveau_hw.h" | 30 | #include "nouveau_hw.h" |
| 31 | 31 | ||
| 32 | #define T_TIMEOUT 2200000 | ||
| 33 | #define T_RISEFALL 1000 | ||
| 34 | #define T_HOLD 5000 | ||
| 35 | |||
| 36 | static void | 32 | static void |
| 37 | i2c_drive_scl(void *data, int state) | 33 | i2c_drive_scl(void *data, int state) |
| 38 | { | 34 | { |
| @@ -113,175 +109,6 @@ i2c_sense_sda(void *data) | |||
| 113 | return 0; | 109 | return 0; |
| 114 | } | 110 | } |
| 115 | 111 | ||
| 116 | static void | ||
| 117 | i2c_delay(struct nouveau_i2c_chan *port, u32 nsec) | ||
| 118 | { | ||
| 119 | udelay((nsec + 500) / 1000); | ||
| 120 | } | ||
| 121 | |||
| 122 | static bool | ||
| 123 | i2c_raise_scl(struct nouveau_i2c_chan *port) | ||
| 124 | { | ||
| 125 | u32 timeout = T_TIMEOUT / T_RISEFALL; | ||
| 126 | |||
| 127 | i2c_drive_scl(port, 1); | ||
| 128 | do { | ||
| 129 | i2c_delay(port, T_RISEFALL); | ||
| 130 | } while (!i2c_sense_scl(port) && --timeout); | ||
| 131 | |||
| 132 | return timeout != 0; | ||
| 133 | } | ||
| 134 | |||
| 135 | static int | ||
| 136 | i2c_start(struct nouveau_i2c_chan *port) | ||
| 137 | { | ||
| 138 | int ret = 0; | ||
| 139 | |||
| 140 | port->state = i2c_sense_scl(port); | ||
| 141 | port->state |= i2c_sense_sda(port) << 1; | ||
| 142 | if (port->state != 3) { | ||
| 143 | i2c_drive_scl(port, 0); | ||
| 144 | i2c_drive_sda(port, 1); | ||
| 145 | if (!i2c_raise_scl(port)) | ||
| 146 | ret = -EBUSY; | ||
| 147 | } | ||
| 148 | |||
| 149 | i2c_drive_sda(port, 0); | ||
| 150 | i2c_delay(port, T_HOLD); | ||
| 151 | i2c_drive_scl(port, 0); | ||
| 152 | i2c_delay(port, T_HOLD); | ||
| 153 | return ret; | ||
| 154 | } | ||
| 155 | |||
| 156 | static void | ||
| 157 | i2c_stop(struct nouveau_i2c_chan *port) | ||
| 158 | { | ||
| 159 | i2c_drive_scl(port, 0); | ||
| 160 | i2c_drive_sda(port, 0); | ||
| 161 | i2c_delay(port, T_RISEFALL); | ||
| 162 | |||
| 163 | i2c_drive_scl(port, 1); | ||
| 164 | i2c_delay(port, T_HOLD); | ||
| 165 | i2c_drive_sda(port, 1); | ||
| 166 | i2c_delay(port, T_HOLD); | ||
| 167 | } | ||
| 168 | |||
| 169 | static int | ||
| 170 | i2c_bitw(struct nouveau_i2c_chan *port, int sda) | ||
| 171 | { | ||
| 172 | i2c_drive_sda(port, sda); | ||
| 173 | i2c_delay(port, T_RISEFALL); | ||
| 174 | |||
| 175 | if (!i2c_raise_scl(port)) | ||
| 176 | return -ETIMEDOUT; | ||
| 177 | i2c_delay(port, T_HOLD); | ||
| 178 | |||
| 179 | i2c_drive_scl(port, 0); | ||
| 180 | i2c_delay(port, T_HOLD); | ||
| 181 | return 0; | ||
| 182 | } | ||
| 183 | |||
| 184 | static int | ||
| 185 | i2c_bitr(struct nouveau_i2c_chan *port) | ||
| 186 | { | ||
| 187 | int sda; | ||
| 188 | |||
| 189 | i2c_drive_sda(port, 1); | ||
| 190 | i2c_delay(port, T_RISEFALL); | ||
| 191 | |||
| 192 | if (!i2c_raise_scl(port)) | ||
| 193 | return -ETIMEDOUT; | ||
| 194 | i2c_delay(port, T_HOLD); | ||
| 195 | |||
| 196 | sda = i2c_sense_sda(port); | ||
| 197 | |||
| 198 | i2c_drive_scl(port, 0); | ||
| 199 | i2c_delay(port, T_HOLD); | ||
| 200 | return sda; | ||
| 201 | } | ||
| 202 | |||
| 203 | static int | ||
| 204 | i2c_get_byte(struct nouveau_i2c_chan *port, u8 *byte, bool last) | ||
| 205 | { | ||
| 206 | int i, bit; | ||
| 207 | |||
| 208 | *byte = 0; | ||
| 209 | for (i = 7; i >= 0; i--) { | ||
| 210 | bit = i2c_bitr(port); | ||
| 211 | if (bit < 0) | ||
| 212 | return bit; | ||
| 213 | *byte |= bit << i; | ||
| 214 | } | ||
| 215 | |||
| 216 | return i2c_bitw(port, last ? 1 : 0); | ||
| 217 | } | ||
| 218 | |||
| 219 | static int | ||
| 220 | i2c_put_byte(struct nouveau_i2c_chan *port, u8 byte) | ||
| 221 | { | ||
| 222 | int i, ret; | ||
| 223 | for (i = 7; i >= 0; i--) { | ||
| 224 | ret = i2c_bitw(port, !!(byte & (1 << i))); | ||
| 225 | if (ret < 0) | ||
| 226 | return ret; | ||
| 227 | } | ||
| 228 | |||
| 229 | ret = i2c_bitr(port); | ||
| 230 | if (ret == 1) /* nack */ | ||
| 231 | ret = -EIO; | ||
| 232 | return ret; | ||
| 233 | } | ||
| 234 | |||
| 235 | static int | ||
| 236 | i2c_addr(struct nouveau_i2c_chan *port, struct i2c_msg *msg) | ||
| 237 | { | ||
| 238 | u32 addr = msg->addr << 1; | ||
| 239 | if (msg->flags & I2C_M_RD) | ||
| 240 | addr |= 1; | ||
| 241 | return i2c_put_byte(port, addr); | ||
| 242 | } | ||
| 243 | |||
| 244 | static int | ||
| 245 | i2c_bit_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | ||
| 246 | { | ||
| 247 | struct nouveau_i2c_chan *port = (struct nouveau_i2c_chan *)adap; | ||
| 248 | struct i2c_msg *msg = msgs; | ||
| 249 | int ret = 0, mcnt = num; | ||
| 250 | |||
| 251 | while (!ret && mcnt--) { | ||
| 252 | u8 remaining = msg->len; | ||
| 253 | u8 *ptr = msg->buf; | ||
| 254 | |||
| 255 | ret = i2c_start(port); | ||
| 256 | if (ret == 0) | ||
| 257 | ret = i2c_addr(port, msg); | ||
| 258 | |||
| 259 | if (msg->flags & I2C_M_RD) { | ||
| 260 | while (!ret && remaining--) | ||
| 261 | ret = i2c_get_byte(port, ptr++, !remaining); | ||
| 262 | } else { | ||
| 263 | while (!ret && remaining--) | ||
| 264 | ret = i2c_put_byte(port, *ptr++); | ||
| 265 | } | ||
| 266 | |||
| 267 | msg++; | ||
| 268 | } | ||
| 269 | |||
| 270 | i2c_stop(port); | ||
| 271 | return (ret < 0) ? ret : num; | ||
| 272 | } | ||
| 273 | |||
| 274 | static u32 | ||
| 275 | i2c_bit_func(struct i2c_adapter *adap) | ||
| 276 | { | ||
| 277 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | ||
| 278 | } | ||
| 279 | |||
| 280 | const struct i2c_algorithm nouveau_i2c_bit_algo = { | ||
| 281 | .master_xfer = i2c_bit_xfer, | ||
| 282 | .functionality = i2c_bit_func | ||
| 283 | }; | ||
| 284 | |||
| 285 | static const uint32_t nv50_i2c_port[] = { | 112 | static const uint32_t nv50_i2c_port[] = { |
| 286 | 0x00e138, 0x00e150, 0x00e168, 0x00e180, | 113 | 0x00e138, 0x00e150, 0x00e168, 0x00e180, |
| 287 | 0x00e254, 0x00e274, 0x00e764, 0x00e780, | 114 | 0x00e254, 0x00e274, 0x00e764, 0x00e780, |
| @@ -384,12 +211,10 @@ nouveau_i2c_init(struct drm_device *dev) | |||
| 384 | case 0: /* NV04:NV50 */ | 211 | case 0: /* NV04:NV50 */ |
| 385 | port->drive = entry[0]; | 212 | port->drive = entry[0]; |
| 386 | port->sense = entry[1]; | 213 | port->sense = entry[1]; |
| 387 | port->adapter.algo = &nouveau_i2c_bit_algo; | ||
| 388 | break; | 214 | break; |
| 389 | case 4: /* NV4E */ | 215 | case 4: /* NV4E */ |
| 390 | port->drive = 0x600800 + entry[1]; | 216 | port->drive = 0x600800 + entry[1]; |
| 391 | port->sense = port->drive; | 217 | port->sense = port->drive; |
| 392 | port->adapter.algo = &nouveau_i2c_bit_algo; | ||
| 393 | break; | 218 | break; |
| 394 | case 5: /* NV50- */ | 219 | case 5: /* NV50- */ |
| 395 | port->drive = entry[0] & 0x0f; | 220 | port->drive = entry[0] & 0x0f; |
| @@ -402,7 +227,6 @@ nouveau_i2c_init(struct drm_device *dev) | |||
| 402 | port->drive = 0x00d014 + (port->drive * 0x20); | 227 | port->drive = 0x00d014 + (port->drive * 0x20); |
| 403 | port->sense = port->drive; | 228 | port->sense = port->drive; |
| 404 | } | 229 | } |
| 405 | port->adapter.algo = &nouveau_i2c_bit_algo; | ||
| 406 | break; | 230 | break; |
| 407 | case 6: /* NV50- DP AUX */ | 231 | case 6: /* NV50- DP AUX */ |
| 408 | port->drive = entry[0]; | 232 | port->drive = entry[0]; |
| @@ -413,7 +237,7 @@ nouveau_i2c_init(struct drm_device *dev) | |||
| 413 | break; | 237 | break; |
| 414 | } | 238 | } |
| 415 | 239 | ||
| 416 | if (!port->adapter.algo) { | 240 | if (!port->adapter.algo && !port->drive) { |
| 417 | NV_ERROR(dev, "I2C%d: type %d index %x/%x unknown\n", | 241 | NV_ERROR(dev, "I2C%d: type %d index %x/%x unknown\n", |
| 418 | i, port->type, port->drive, port->sense); | 242 | i, port->type, port->drive, port->sense); |
| 419 | kfree(port); | 243 | kfree(port); |
| @@ -429,7 +253,26 @@ nouveau_i2c_init(struct drm_device *dev) | |||
| 429 | port->dcb = ROM32(entry[0]); | 253 | port->dcb = ROM32(entry[0]); |
| 430 | i2c_set_adapdata(&port->adapter, i2c); | 254 | i2c_set_adapdata(&port->adapter, i2c); |
| 431 | 255 | ||
| 432 | ret = i2c_add_adapter(&port->adapter); | 256 | if (port->adapter.algo != &nouveau_dp_i2c_algo) { |
| 257 | port->adapter.algo_data = &port->bit; | ||
| 258 | port->bit.udelay = 10; | ||
| 259 | port->bit.timeout = usecs_to_jiffies(2200); | ||
| 260 | port->bit.data = port; | ||
| 261 | port->bit.setsda = i2c_drive_sda; | ||
| 262 | port->bit.setscl = i2c_drive_scl; | ||
| 263 | port->bit.getsda = i2c_sense_sda; | ||
| 264 | port->bit.getscl = i2c_sense_scl; | ||
| 265 | |||
| 266 | i2c_drive_scl(port, 0); | ||
| 267 | i2c_drive_sda(port, 1); | ||
| 268 | i2c_drive_scl(port, 1); | ||
| 269 | |||
| 270 | ret = i2c_bit_add_bus(&port->adapter); | ||
| 271 | } else { | ||
| 272 | port->adapter.algo = &nouveau_dp_i2c_algo; | ||
| 273 | ret = i2c_add_adapter(&port->adapter); | ||
| 274 | } | ||
| 275 | |||
| 433 | if (ret) { | 276 | if (ret) { |
| 434 | NV_ERROR(dev, "I2C%d: failed register: %d\n", i, ret); | 277 | NV_ERROR(dev, "I2C%d: failed register: %d\n", i, ret); |
| 435 | kfree(port); | 278 | kfree(port); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.h b/drivers/gpu/drm/nouveau/nouveau_i2c.h index 4d2e4e9031be..1d083893a4d7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.h +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.h | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | struct nouveau_i2c_chan { | 34 | struct nouveau_i2c_chan { |
| 35 | struct i2c_adapter adapter; | 35 | struct i2c_adapter adapter; |
| 36 | struct drm_device *dev; | 36 | struct drm_device *dev; |
| 37 | struct i2c_algo_bit_data bit; | ||
| 37 | struct list_head head; | 38 | struct list_head head; |
| 38 | u8 index; | 39 | u8 index; |
| 39 | u8 type; | 40 | u8 type; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c index 34d591b7d4ef..da3e7c3abab7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/drivers/gpu/drm/nouveau/nouveau_pm.c | |||
| @@ -235,6 +235,7 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile) | |||
| 235 | return -EPERM; | 235 | return -EPERM; |
| 236 | 236 | ||
| 237 | strncpy(string, profile, sizeof(string)); | 237 | strncpy(string, profile, sizeof(string)); |
| 238 | string[sizeof(string) - 1] = 0; | ||
| 238 | if ((ptr = strchr(string, '\n'))) | 239 | if ((ptr = strchr(string, '\n'))) |
| 239 | *ptr = '\0'; | 240 | *ptr = '\0'; |
| 240 | 241 | ||
diff --git a/drivers/gpu/drm/nouveau/nv10_gpio.c b/drivers/gpu/drm/nouveau/nv10_gpio.c index 550ad3fcf0af..9d79180069df 100644 --- a/drivers/gpu/drm/nouveau/nv10_gpio.c +++ b/drivers/gpu/drm/nouveau/nv10_gpio.c | |||
| @@ -65,7 +65,7 @@ nv10_gpio_drive(struct drm_device *dev, int line, int dir, int out) | |||
| 65 | if (line < 10) { | 65 | if (line < 10) { |
| 66 | line = (line - 2) * 4; | 66 | line = (line - 2) * 4; |
| 67 | reg = NV_PCRTC_GPIO_EXT; | 67 | reg = NV_PCRTC_GPIO_EXT; |
| 68 | mask = 0x00000003 << ((line - 2) * 4); | 68 | mask = 0x00000003; |
| 69 | data = (dir << 1) | out; | 69 | data = (dir << 1) | out; |
| 70 | } else | 70 | } else |
| 71 | if (line < 14) { | 71 | if (line < 14) { |
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index a7844ab6a50c..274640212475 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c | |||
| @@ -42,7 +42,7 @@ nv50_sor_dp_lane_map(struct drm_device *dev, struct dcb_entry *dcb, u8 lane) | |||
| 42 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 42 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 43 | static const u8 nvaf[] = { 24, 16, 8, 0 }; /* thanks, apple.. */ | 43 | static const u8 nvaf[] = { 24, 16, 8, 0 }; /* thanks, apple.. */ |
| 44 | static const u8 nv50[] = { 16, 8, 0, 24 }; | 44 | static const u8 nv50[] = { 16, 8, 0, 24 }; |
| 45 | if (dev_priv->card_type == 0xaf) | 45 | if (dev_priv->chipset == 0xaf) |
| 46 | return nvaf[lane]; | 46 | return nvaf[lane]; |
| 47 | return nv50[lane]; | 47 | return nv50[lane]; |
| 48 | } | 48 | } |
diff --git a/drivers/gpu/drm/nouveau/nvc0_fb.c b/drivers/gpu/drm/nouveau/nvc0_fb.c index 5bf55038fd92..f704e942372e 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fb.c +++ b/drivers/gpu/drm/nouveau/nvc0_fb.c | |||
| @@ -54,6 +54,11 @@ nvc0_mfb_isr(struct drm_device *dev) | |||
| 54 | nvc0_mfb_subp_isr(dev, unit, subp); | 54 | nvc0_mfb_subp_isr(dev, unit, subp); |
| 55 | units &= ~(1 << unit); | 55 | units &= ~(1 << unit); |
| 56 | } | 56 | } |
| 57 | |||
| 58 | /* we do something horribly wrong and upset PMFB a lot, so mask off | ||
| 59 | * interrupts from it after the first one until it's fixed | ||
| 60 | */ | ||
| 61 | nv_mask(dev, 0x000640, 0x02000000, 0x00000000); | ||
| 57 | } | 62 | } |
| 58 | 63 | ||
| 59 | static void | 64 | static void |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index b5ff1f7b6f7e..af1054f8202a 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
| @@ -575,6 +575,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 575 | 575 | ||
| 576 | if (rdev->family < CHIP_RV770) | 576 | if (rdev->family < CHIP_RV770) |
| 577 | pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; | 577 | pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; |
| 578 | /* use frac fb div on APUs */ | ||
| 579 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) | ||
| 580 | pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; | ||
| 578 | } else { | 581 | } else { |
| 579 | pll->flags |= RADEON_PLL_LEGACY; | 582 | pll->flags |= RADEON_PLL_LEGACY; |
| 580 | 583 | ||
| @@ -955,8 +958,8 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
| 955 | break; | 958 | break; |
| 956 | } | 959 | } |
| 957 | 960 | ||
| 958 | if (radeon_encoder->active_device & | 961 | if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || |
| 959 | (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) { | 962 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) { |
| 960 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 963 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 961 | struct drm_connector *connector = | 964 | struct drm_connector *connector = |
| 962 | radeon_get_connector_for_encoder(encoder); | 965 | radeon_get_connector_for_encoder(encoder); |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index e607c4d7dd98..2d39f9977e00 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
| @@ -230,6 +230,10 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action) | |||
| 230 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | 230 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
| 231 | return; | 231 | return; |
| 232 | 232 | ||
| 233 | /* some R4xx chips have the wrong frev */ | ||
| 234 | if (rdev->family <= CHIP_RV410) | ||
| 235 | frev = 1; | ||
| 236 | |||
| 233 | switch (frev) { | 237 | switch (frev) { |
| 234 | case 1: | 238 | case 1: |
| 235 | switch (crev) { | 239 | switch (crev) { |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 81801c176aa5..fe33d35dae8c 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
| @@ -2553,7 +2553,7 @@ static void r100_pll_errata_after_data(struct radeon_device *rdev) | |||
| 2553 | * or the chip could hang on a subsequent access | 2553 | * or the chip could hang on a subsequent access |
| 2554 | */ | 2554 | */ |
| 2555 | if (rdev->pll_errata & CHIP_ERRATA_PLL_DELAY) { | 2555 | if (rdev->pll_errata & CHIP_ERRATA_PLL_DELAY) { |
| 2556 | udelay(5000); | 2556 | mdelay(5); |
| 2557 | } | 2557 | } |
| 2558 | 2558 | ||
| 2559 | /* This function is required to workaround a hardware bug in some (all?) | 2559 | /* This function is required to workaround a hardware bug in some (all?) |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 391bd2636a80..c8187c4b6ae8 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -1135,7 +1135,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc | |||
| 1135 | } | 1135 | } |
| 1136 | if (rdev->flags & RADEON_IS_AGP) { | 1136 | if (rdev->flags & RADEON_IS_AGP) { |
| 1137 | size_bf = mc->gtt_start; | 1137 | size_bf = mc->gtt_start; |
| 1138 | size_af = 0xFFFFFFFF - mc->gtt_end + 1; | 1138 | size_af = 0xFFFFFFFF - mc->gtt_end; |
| 1139 | if (size_bf > size_af) { | 1139 | if (size_bf > size_af) { |
| 1140 | if (mc->mc_vram_size > size_bf) { | 1140 | if (mc->mc_vram_size > size_bf) { |
| 1141 | dev_warn(rdev->dev, "limiting VRAM\n"); | 1141 | dev_warn(rdev->dev, "limiting VRAM\n"); |
| @@ -1149,7 +1149,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc | |||
| 1149 | mc->real_vram_size = size_af; | 1149 | mc->real_vram_size = size_af; |
| 1150 | mc->mc_vram_size = size_af; | 1150 | mc->mc_vram_size = size_af; |
| 1151 | } | 1151 | } |
| 1152 | mc->vram_start = mc->gtt_end; | 1152 | mc->vram_start = mc->gtt_end + 1; |
| 1153 | } | 1153 | } |
| 1154 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; | 1154 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; |
| 1155 | dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", | 1155 | dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", |
| @@ -2839,7 +2839,7 @@ void r600_rlc_stop(struct radeon_device *rdev) | |||
| 2839 | /* r7xx asics need to soft reset RLC before halting */ | 2839 | /* r7xx asics need to soft reset RLC before halting */ |
| 2840 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC); | 2840 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC); |
| 2841 | RREG32(SRBM_SOFT_RESET); | 2841 | RREG32(SRBM_SOFT_RESET); |
| 2842 | udelay(15000); | 2842 | mdelay(15); |
| 2843 | WREG32(SRBM_SOFT_RESET, 0); | 2843 | WREG32(SRBM_SOFT_RESET, 0); |
| 2844 | RREG32(SRBM_SOFT_RESET); | 2844 | RREG32(SRBM_SOFT_RESET); |
| 2845 | } | 2845 | } |
diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c index 84c546250955..75ed17c96115 100644 --- a/drivers/gpu/drm/radeon/r600_cp.c +++ b/drivers/gpu/drm/radeon/r600_cp.c | |||
| @@ -407,7 +407,7 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) | |||
| 407 | 407 | ||
| 408 | RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); | 408 | RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); |
| 409 | RADEON_READ(R600_GRBM_SOFT_RESET); | 409 | RADEON_READ(R600_GRBM_SOFT_RESET); |
| 410 | DRM_UDELAY(15000); | 410 | mdelay(15); |
| 411 | RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); | 411 | RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); |
| 412 | 412 | ||
| 413 | fw_data = (const __be32 *)dev_priv->me_fw->data; | 413 | fw_data = (const __be32 *)dev_priv->me_fw->data; |
| @@ -500,7 +500,7 @@ static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv) | |||
| 500 | 500 | ||
| 501 | RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); | 501 | RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); |
| 502 | RADEON_READ(R600_GRBM_SOFT_RESET); | 502 | RADEON_READ(R600_GRBM_SOFT_RESET); |
| 503 | DRM_UDELAY(15000); | 503 | mdelay(15); |
| 504 | RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); | 504 | RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); |
| 505 | 505 | ||
| 506 | fw_data = (const __be32 *)dev_priv->pfp_fw->data; | 506 | fw_data = (const __be32 *)dev_priv->pfp_fw->data; |
| @@ -1797,7 +1797,7 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev, | |||
| 1797 | 1797 | ||
| 1798 | RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); | 1798 | RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); |
| 1799 | RADEON_READ(R600_GRBM_SOFT_RESET); | 1799 | RADEON_READ(R600_GRBM_SOFT_RESET); |
| 1800 | DRM_UDELAY(15000); | 1800 | mdelay(15); |
| 1801 | RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); | 1801 | RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); |
| 1802 | 1802 | ||
| 1803 | 1803 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c index 6ae0c75f016a..9c6b29a41927 100644 --- a/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/drivers/gpu/drm/radeon/radeon_clocks.c | |||
| @@ -633,7 +633,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
| 633 | tmp &= ~(R300_SCLK_FORCE_VAP); | 633 | tmp &= ~(R300_SCLK_FORCE_VAP); |
| 634 | tmp |= RADEON_SCLK_FORCE_CP; | 634 | tmp |= RADEON_SCLK_FORCE_CP; |
| 635 | WREG32_PLL(RADEON_SCLK_CNTL, tmp); | 635 | WREG32_PLL(RADEON_SCLK_CNTL, tmp); |
| 636 | udelay(15000); | 636 | mdelay(15); |
| 637 | 637 | ||
| 638 | tmp = RREG32_PLL(R300_SCLK_CNTL2); | 638 | tmp = RREG32_PLL(R300_SCLK_CNTL2); |
| 639 | tmp &= ~(R300_SCLK_FORCE_TCL | | 639 | tmp &= ~(R300_SCLK_FORCE_TCL | |
| @@ -651,12 +651,12 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
| 651 | tmp |= (RADEON_ENGIN_DYNCLK_MODE | | 651 | tmp |= (RADEON_ENGIN_DYNCLK_MODE | |
| 652 | (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT)); | 652 | (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT)); |
| 653 | WREG32_PLL(RADEON_CLK_PWRMGT_CNTL, tmp); | 653 | WREG32_PLL(RADEON_CLK_PWRMGT_CNTL, tmp); |
| 654 | udelay(15000); | 654 | mdelay(15); |
| 655 | 655 | ||
| 656 | tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL); | 656 | tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL); |
| 657 | tmp |= RADEON_SCLK_DYN_START_CNTL; | 657 | tmp |= RADEON_SCLK_DYN_START_CNTL; |
| 658 | WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp); | 658 | WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp); |
| 659 | udelay(15000); | 659 | mdelay(15); |
| 660 | 660 | ||
| 661 | /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200 | 661 | /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200 |
| 662 | to lockup randomly, leave them as set by BIOS. | 662 | to lockup randomly, leave them as set by BIOS. |
| @@ -696,7 +696,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
| 696 | tmp |= RADEON_SCLK_MORE_FORCEON; | 696 | tmp |= RADEON_SCLK_MORE_FORCEON; |
| 697 | } | 697 | } |
| 698 | WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); | 698 | WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); |
| 699 | udelay(15000); | 699 | mdelay(15); |
| 700 | } | 700 | } |
| 701 | 701 | ||
| 702 | /* RV200::A11 A12, RV250::A11 A12 */ | 702 | /* RV200::A11 A12, RV250::A11 A12 */ |
| @@ -709,7 +709,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
| 709 | tmp |= RADEON_TCL_BYPASS_DISABLE; | 709 | tmp |= RADEON_TCL_BYPASS_DISABLE; |
| 710 | WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp); | 710 | WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp); |
| 711 | } | 711 | } |
| 712 | udelay(15000); | 712 | mdelay(15); |
| 713 | 713 | ||
| 714 | /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK) */ | 714 | /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK) */ |
| 715 | tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); | 715 | tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); |
| @@ -722,14 +722,14 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
| 722 | RADEON_PIXCLK_TMDS_ALWAYS_ONb); | 722 | RADEON_PIXCLK_TMDS_ALWAYS_ONb); |
| 723 | 723 | ||
| 724 | WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); | 724 | WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); |
| 725 | udelay(15000); | 725 | mdelay(15); |
| 726 | 726 | ||
| 727 | tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); | 727 | tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); |
| 728 | tmp |= (RADEON_PIXCLK_ALWAYS_ONb | | 728 | tmp |= (RADEON_PIXCLK_ALWAYS_ONb | |
| 729 | RADEON_PIXCLK_DAC_ALWAYS_ONb); | 729 | RADEON_PIXCLK_DAC_ALWAYS_ONb); |
| 730 | 730 | ||
| 731 | WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); | 731 | WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); |
| 732 | udelay(15000); | 732 | mdelay(15); |
| 733 | } | 733 | } |
| 734 | } else { | 734 | } else { |
| 735 | /* Turn everything OFF (ForceON to everything) */ | 735 | /* Turn everything OFF (ForceON to everything) */ |
| @@ -861,7 +861,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
| 861 | } | 861 | } |
| 862 | WREG32_PLL(RADEON_SCLK_CNTL, tmp); | 862 | WREG32_PLL(RADEON_SCLK_CNTL, tmp); |
| 863 | 863 | ||
| 864 | udelay(16000); | 864 | mdelay(16); |
| 865 | 865 | ||
| 866 | if ((rdev->family == CHIP_R300) || | 866 | if ((rdev->family == CHIP_R300) || |
| 867 | (rdev->family == CHIP_R350)) { | 867 | (rdev->family == CHIP_R350)) { |
| @@ -870,7 +870,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
| 870 | R300_SCLK_FORCE_GA | | 870 | R300_SCLK_FORCE_GA | |
| 871 | R300_SCLK_FORCE_CBA); | 871 | R300_SCLK_FORCE_CBA); |
| 872 | WREG32_PLL(R300_SCLK_CNTL2, tmp); | 872 | WREG32_PLL(R300_SCLK_CNTL2, tmp); |
| 873 | udelay(16000); | 873 | mdelay(16); |
| 874 | } | 874 | } |
| 875 | 875 | ||
| 876 | if (rdev->flags & RADEON_IS_IGP) { | 876 | if (rdev->flags & RADEON_IS_IGP) { |
| @@ -878,7 +878,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
| 878 | tmp &= ~(RADEON_FORCEON_MCLKA | | 878 | tmp &= ~(RADEON_FORCEON_MCLKA | |
| 879 | RADEON_FORCEON_YCLKA); | 879 | RADEON_FORCEON_YCLKA); |
| 880 | WREG32_PLL(RADEON_MCLK_CNTL, tmp); | 880 | WREG32_PLL(RADEON_MCLK_CNTL, tmp); |
| 881 | udelay(16000); | 881 | mdelay(16); |
| 882 | } | 882 | } |
| 883 | 883 | ||
| 884 | if ((rdev->family == CHIP_RV200) || | 884 | if ((rdev->family == CHIP_RV200) || |
| @@ -887,7 +887,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
| 887 | tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL); | 887 | tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL); |
| 888 | tmp |= RADEON_SCLK_MORE_FORCEON; | 888 | tmp |= RADEON_SCLK_MORE_FORCEON; |
| 889 | WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); | 889 | WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); |
| 890 | udelay(16000); | 890 | mdelay(16); |
| 891 | } | 891 | } |
| 892 | 892 | ||
| 893 | tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); | 893 | tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); |
| @@ -900,7 +900,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
| 900 | RADEON_PIXCLK_TMDS_ALWAYS_ONb); | 900 | RADEON_PIXCLK_TMDS_ALWAYS_ONb); |
| 901 | 901 | ||
| 902 | WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); | 902 | WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); |
| 903 | udelay(16000); | 903 | mdelay(16); |
| 904 | 904 | ||
| 905 | tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); | 905 | tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); |
| 906 | tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | | 906 | tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 81fc100be7e1..2cad9fde92fc 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
| @@ -2845,7 +2845,7 @@ bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder) | |||
| 2845 | case 4: | 2845 | case 4: |
| 2846 | val = RBIOS16(index); | 2846 | val = RBIOS16(index); |
| 2847 | index += 2; | 2847 | index += 2; |
| 2848 | udelay(val * 1000); | 2848 | mdelay(val); |
| 2849 | break; | 2849 | break; |
| 2850 | case 6: | 2850 | case 6: |
| 2851 | slave_addr = id & 0xff; | 2851 | slave_addr = id & 0xff; |
| @@ -3044,7 +3044,7 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset) | |||
| 3044 | udelay(150); | 3044 | udelay(150); |
| 3045 | break; | 3045 | break; |
| 3046 | case 2: | 3046 | case 2: |
| 3047 | udelay(1000); | 3047 | mdelay(1); |
| 3048 | break; | 3048 | break; |
| 3049 | case 3: | 3049 | case 3: |
| 3050 | while (tmp--) { | 3050 | while (tmp--) { |
| @@ -3075,13 +3075,13 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset) | |||
| 3075 | /*mclk_cntl |= 0x00001111;*//* ??? */ | 3075 | /*mclk_cntl |= 0x00001111;*//* ??? */ |
| 3076 | WREG32_PLL(RADEON_MCLK_CNTL, | 3076 | WREG32_PLL(RADEON_MCLK_CNTL, |
| 3077 | mclk_cntl); | 3077 | mclk_cntl); |
| 3078 | udelay(10000); | 3078 | mdelay(10); |
| 3079 | #endif | 3079 | #endif |
| 3080 | WREG32_PLL | 3080 | WREG32_PLL |
| 3081 | (RADEON_CLK_PWRMGT_CNTL, | 3081 | (RADEON_CLK_PWRMGT_CNTL, |
| 3082 | tmp & | 3082 | tmp & |
| 3083 | ~RADEON_CG_NO1_DEBUG_0); | 3083 | ~RADEON_CG_NO1_DEBUG_0); |
| 3084 | udelay(10000); | 3084 | mdelay(10); |
| 3085 | } | 3085 | } |
| 3086 | break; | 3086 | break; |
| 3087 | default: | 3087 | default: |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index bd05156edbdb..3c2e7a000a2a 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
| @@ -970,7 +970,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
| 970 | 970 | ||
| 971 | encoder = obj_to_encoder(obj); | 971 | encoder = obj_to_encoder(obj); |
| 972 | 972 | ||
| 973 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC || | 973 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC && |
| 974 | encoder->encoder_type != DRM_MODE_ENCODER_TVDAC) | 974 | encoder->encoder_type != DRM_MODE_ENCODER_TVDAC) |
| 975 | continue; | 975 | continue; |
| 976 | 976 | ||
| @@ -1000,6 +1000,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
| 1000 | * cases the DVI port is actually a virtual KVM port connected to the service | 1000 | * cases the DVI port is actually a virtual KVM port connected to the service |
| 1001 | * processor. | 1001 | * processor. |
| 1002 | */ | 1002 | */ |
| 1003 | out: | ||
| 1003 | if ((!rdev->is_atom_bios) && | 1004 | if ((!rdev->is_atom_bios) && |
| 1004 | (ret == connector_status_disconnected) && | 1005 | (ret == connector_status_disconnected) && |
| 1005 | rdev->mode_info.bios_hardcoded_edid_size) { | 1006 | rdev->mode_info.bios_hardcoded_edid_size) { |
| @@ -1007,7 +1008,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
| 1007 | ret = connector_status_connected; | 1008 | ret = connector_status_connected; |
| 1008 | } | 1009 | } |
| 1009 | 1010 | ||
| 1010 | out: | ||
| 1011 | /* updated in get modes as well since we need to know if it's analog or digital */ | 1011 | /* updated in get modes as well since we need to know if it's analog or digital */ |
| 1012 | radeon_connector_update_scratch_regs(connector, ret); | 1012 | radeon_connector_update_scratch_regs(connector, ret); |
| 1013 | return ret; | 1013 | return ret; |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index ea7df16e2f84..5992502a3448 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -241,8 +241,8 @@ int radeon_wb_init(struct radeon_device *rdev) | |||
| 241 | rdev->wb.use_event = true; | 241 | rdev->wb.use_event = true; |
| 242 | } | 242 | } |
| 243 | } | 243 | } |
| 244 | /* always use writeback/events on NI */ | 244 | /* always use writeback/events on NI, APUs */ |
| 245 | if (ASIC_IS_DCE5(rdev)) { | 245 | if (rdev->family >= CHIP_PALM) { |
| 246 | rdev->wb.enabled = true; | 246 | rdev->wb.enabled = true; |
| 247 | rdev->wb.use_event = true; | 247 | rdev->wb.use_event = true; |
| 248 | } | 248 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 8086c96e0b06..0a1d4bd65edc 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
| @@ -533,7 +533,7 @@ static void radeon_crtc_init(struct drm_device *dev, int index) | |||
| 533 | radeon_legacy_init_crtc(dev, radeon_crtc); | 533 | radeon_legacy_init_crtc(dev, radeon_crtc); |
| 534 | } | 534 | } |
| 535 | 535 | ||
| 536 | static const char *encoder_names[36] = { | 536 | static const char *encoder_names[37] = { |
| 537 | "NONE", | 537 | "NONE", |
| 538 | "INTERNAL_LVDS", | 538 | "INTERNAL_LVDS", |
| 539 | "INTERNAL_TMDS1", | 539 | "INTERNAL_TMDS1", |
| @@ -570,6 +570,7 @@ static const char *encoder_names[36] = { | |||
| 570 | "INTERNAL_UNIPHY2", | 570 | "INTERNAL_UNIPHY2", |
| 571 | "NUTMEG", | 571 | "NUTMEG", |
| 572 | "TRAVIS", | 572 | "TRAVIS", |
| 573 | "INTERNAL_VCE" | ||
| 573 | }; | 574 | }; |
| 574 | 575 | ||
| 575 | static const char *connector_names[15] = { | 576 | static const char *connector_names[15] = { |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 85bcfc8923a7..3edec1c198e3 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
| @@ -900,6 +900,10 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | |||
| 900 | struct radeon_i2c_chan *i2c; | 900 | struct radeon_i2c_chan *i2c; |
| 901 | int ret; | 901 | int ret; |
| 902 | 902 | ||
| 903 | /* don't add the mm_i2c bus unless hw_i2c is enabled */ | ||
| 904 | if (rec->mm_i2c && (radeon_hw_i2c == 0)) | ||
| 905 | return NULL; | ||
| 906 | |||
| 903 | i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); | 907 | i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); |
| 904 | if (i2c == NULL) | 908 | if (i2c == NULL) |
| 905 | return NULL; | 909 | return NULL; |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 66d5fe1c8174..65060b77c805 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
| @@ -147,6 +147,12 @@ static bool radeon_msi_ok(struct radeon_device *rdev) | |||
| 147 | (rdev->pdev->subsystem_device == 0x01fd)) | 147 | (rdev->pdev->subsystem_device == 0x01fd)) |
| 148 | return true; | 148 | return true; |
| 149 | 149 | ||
| 150 | /* RV515 seems to have MSI issues where it loses | ||
| 151 | * MSI rearms occasionally. This leads to lockups and freezes. | ||
| 152 | * disable it by default. | ||
| 153 | */ | ||
| 154 | if (rdev->family == CHIP_RV515) | ||
| 155 | return false; | ||
| 150 | if (rdev->flags & RADEON_IS_IGP) { | 156 | if (rdev->flags & RADEON_IS_IGP) { |
| 151 | /* APUs work fine with MSIs */ | 157 | /* APUs work fine with MSIs */ |
| 152 | if (rdev->family >= CHIP_PALM) | 158 | if (rdev->family >= CHIP_PALM) |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 2f46e0c8df53..42db254f6bb0 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
| @@ -88,7 +88,7 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode) | |||
| 88 | lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); | 88 | lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); |
| 89 | lvds_pll_cntl |= RADEON_LVDS_PLL_EN; | 89 | lvds_pll_cntl |= RADEON_LVDS_PLL_EN; |
| 90 | WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); | 90 | WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); |
| 91 | udelay(1000); | 91 | mdelay(1); |
| 92 | 92 | ||
| 93 | lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); | 93 | lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); |
| 94 | lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET; | 94 | lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET; |
| @@ -101,7 +101,7 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode) | |||
| 101 | (backlight_level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT)); | 101 | (backlight_level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT)); |
| 102 | if (is_mac) | 102 | if (is_mac) |
| 103 | lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN; | 103 | lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN; |
| 104 | udelay(panel_pwr_delay * 1000); | 104 | mdelay(panel_pwr_delay); |
| 105 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); | 105 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); |
| 106 | break; | 106 | break; |
| 107 | case DRM_MODE_DPMS_STANDBY: | 107 | case DRM_MODE_DPMS_STANDBY: |
| @@ -118,10 +118,10 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode) | |||
| 118 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); | 118 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); |
| 119 | lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON); | 119 | lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON); |
| 120 | } | 120 | } |
| 121 | udelay(panel_pwr_delay * 1000); | 121 | mdelay(panel_pwr_delay); |
| 122 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); | 122 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); |
| 123 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); | 123 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); |
| 124 | udelay(panel_pwr_delay * 1000); | 124 | mdelay(panel_pwr_delay); |
| 125 | break; | 125 | break; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| @@ -656,7 +656,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc | |||
| 656 | 656 | ||
| 657 | WREG32(RADEON_DAC_MACRO_CNTL, tmp); | 657 | WREG32(RADEON_DAC_MACRO_CNTL, tmp); |
| 658 | 658 | ||
| 659 | udelay(2000); | 659 | mdelay(2); |
| 660 | 660 | ||
| 661 | if (RREG32(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT) | 661 | if (RREG32(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT) |
| 662 | found = connector_status_connected; | 662 | found = connector_status_connected; |
| @@ -1499,7 +1499,7 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder | |||
| 1499 | tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN; | 1499 | tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN; |
| 1500 | WREG32(RADEON_DAC_CNTL2, tmp); | 1500 | WREG32(RADEON_DAC_CNTL2, tmp); |
| 1501 | 1501 | ||
| 1502 | udelay(10000); | 1502 | mdelay(10); |
| 1503 | 1503 | ||
| 1504 | if (ASIC_IS_R300(rdev)) { | 1504 | if (ASIC_IS_R300(rdev)) { |
| 1505 | if (RREG32(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B) | 1505 | if (RREG32(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B) |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index c62ae4be3845..cdab1aeaed6e 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
| @@ -969,7 +969,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | |||
| 969 | } | 969 | } |
| 970 | if (rdev->flags & RADEON_IS_AGP) { | 970 | if (rdev->flags & RADEON_IS_AGP) { |
| 971 | size_bf = mc->gtt_start; | 971 | size_bf = mc->gtt_start; |
| 972 | size_af = 0xFFFFFFFF - mc->gtt_end + 1; | 972 | size_af = 0xFFFFFFFF - mc->gtt_end; |
| 973 | if (size_bf > size_af) { | 973 | if (size_bf > size_af) { |
| 974 | if (mc->mc_vram_size > size_bf) { | 974 | if (mc->mc_vram_size > size_bf) { |
| 975 | dev_warn(rdev->dev, "limiting VRAM\n"); | 975 | dev_warn(rdev->dev, "limiting VRAM\n"); |
| @@ -983,7 +983,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | |||
| 983 | mc->real_vram_size = size_af; | 983 | mc->real_vram_size = size_af; |
| 984 | mc->mc_vram_size = size_af; | 984 | mc->mc_vram_size = size_af; |
| 985 | } | 985 | } |
| 986 | mc->vram_start = mc->gtt_end; | 986 | mc->vram_start = mc->gtt_end + 1; |
| 987 | } | 987 | } |
| 988 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; | 988 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; |
| 989 | dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", | 989 | dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index ac7a199ffece..27bda986fc2b 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
| @@ -2999,8 +2999,8 @@ int si_rlc_init(struct radeon_device *rdev) | |||
| 2999 | } | 2999 | } |
| 3000 | r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM, | 3000 | r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM, |
| 3001 | &rdev->rlc.save_restore_gpu_addr); | 3001 | &rdev->rlc.save_restore_gpu_addr); |
| 3002 | radeon_bo_unreserve(rdev->rlc.save_restore_obj); | ||
| 3002 | if (r) { | 3003 | if (r) { |
| 3003 | radeon_bo_unreserve(rdev->rlc.save_restore_obj); | ||
| 3004 | dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r); | 3004 | dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r); |
| 3005 | si_rlc_fini(rdev); | 3005 | si_rlc_fini(rdev); |
| 3006 | return r; | 3006 | return r; |
| @@ -3023,9 +3023,8 @@ int si_rlc_init(struct radeon_device *rdev) | |||
| 3023 | } | 3023 | } |
| 3024 | r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM, | 3024 | r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM, |
| 3025 | &rdev->rlc.clear_state_gpu_addr); | 3025 | &rdev->rlc.clear_state_gpu_addr); |
| 3026 | radeon_bo_unreserve(rdev->rlc.clear_state_obj); | ||
| 3026 | if (r) { | 3027 | if (r) { |
| 3027 | |||
| 3028 | radeon_bo_unreserve(rdev->rlc.clear_state_obj); | ||
| 3029 | dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r); | 3028 | dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r); |
| 3030 | si_rlc_fini(rdev); | 3029 | si_rlc_fini(rdev); |
| 3031 | return r; | 3030 | return r; |
diff --git a/drivers/gpu/drm/savage/savage_state.c b/drivers/gpu/drm/savage/savage_state.c index 031aaaf79ac2..b6d8608375cd 100644 --- a/drivers/gpu/drm/savage/savage_state.c +++ b/drivers/gpu/drm/savage/savage_state.c | |||
| @@ -988,7 +988,7 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_ | |||
| 988 | * for locking on FreeBSD. | 988 | * for locking on FreeBSD. |
| 989 | */ | 989 | */ |
| 990 | if (cmdbuf->size) { | 990 | if (cmdbuf->size) { |
| 991 | kcmd_addr = kmalloc(cmdbuf->size * 8, GFP_KERNEL); | 991 | kcmd_addr = kmalloc_array(cmdbuf->size, 8, GFP_KERNEL); |
| 992 | if (kcmd_addr == NULL) | 992 | if (kcmd_addr == NULL) |
| 993 | return -ENOMEM; | 993 | return -ENOMEM; |
| 994 | 994 | ||
| @@ -1015,8 +1015,8 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_ | |||
| 1015 | cmdbuf->vb_addr = kvb_addr; | 1015 | cmdbuf->vb_addr = kvb_addr; |
| 1016 | } | 1016 | } |
| 1017 | if (cmdbuf->nbox) { | 1017 | if (cmdbuf->nbox) { |
| 1018 | kbox_addr = kmalloc(cmdbuf->nbox * sizeof(struct drm_clip_rect), | 1018 | kbox_addr = kmalloc_array(cmdbuf->nbox, sizeof(struct drm_clip_rect), |
| 1019 | GFP_KERNEL); | 1019 | GFP_KERNEL); |
| 1020 | if (kbox_addr == NULL) { | 1020 | if (kbox_addr == NULL) { |
| 1021 | ret = -ENOMEM; | 1021 | ret = -ENOMEM; |
| 1022 | goto done; | 1022 | goto done; |
