diff options
Diffstat (limited to 'drivers/gpu')
98 files changed, 1130 insertions, 1079 deletions
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index 31123b6a0be..2d2c2f8d6dc 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -60,8 +60,7 @@ static DEFINE_PCI_DEVICE_TABLE(pciidlist) = { MODULE_DEVICE_TABLE(pci, pciidlist); -static int __devinit -ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { return drm_get_pci_dev(pdev, ent, &driver); } diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c index dcd1a8c029e..8ecb601152e 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.c +++ b/drivers/gpu/drm/cirrus/cirrus_drv.c @@ -56,8 +56,8 @@ static int cirrus_kick_out_firmware_fb(struct pci_dev *pdev) return 0; } -static int __devinit -cirrus_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +static int cirrus_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) { int ret; diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 2bf9670ba29..2aa331499f8 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -221,11 +221,13 @@ static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node, BUG_ON(!hole_node->hole_follows || node->allocated); - if (mm->color_adjust) - mm->color_adjust(hole_node, color, &adj_start, &adj_end); - if (adj_start < start) adj_start = start; + if (adj_end > end) + adj_end = end; + + if (mm->color_adjust) + mm->color_adjust(hole_node, color, &adj_start, &adj_end); if (alignment) { unsigned tmp = adj_start % alignment; @@ -506,7 +508,7 @@ void drm_mm_init_scan(struct drm_mm *mm, mm->scan_size = size; mm->scanned_blocks = 0; mm->scan_hit_start = 0; - mm->scan_hit_size = 0; + mm->scan_hit_end = 0; mm->scan_check_range = 0; mm->prev_scanned_node = NULL; } @@ -533,7 +535,7 @@ void drm_mm_init_scan_with_range(struct drm_mm *mm, mm->scan_size = size; mm->scanned_blocks = 0; mm->scan_hit_start = 0; - mm->scan_hit_size = 0; + mm->scan_hit_end = 0; mm->scan_start = start; mm->scan_end = end; mm->scan_check_range = 1; @@ -552,8 +554,7 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) struct drm_mm *mm = node->mm; struct drm_mm_node *prev_node; unsigned long hole_start, hole_end; - unsigned long adj_start; - unsigned long adj_end; + unsigned long adj_start, adj_end; mm->scanned_blocks++; @@ -570,14 +571,8 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) node->node_list.next = &mm->prev_scanned_node->node_list; mm->prev_scanned_node = node; - hole_start = drm_mm_hole_node_start(prev_node); - hole_end = drm_mm_hole_node_end(prev_node); - - adj_start = hole_start; - adj_end = hole_end; - - if (mm->color_adjust) - mm->color_adjust(prev_node, mm->scan_color, &adj_start, &adj_end); + adj_start = hole_start = drm_mm_hole_node_start(prev_node); + adj_end = hole_end = drm_mm_hole_node_end(prev_node); if (mm->scan_check_range) { if (adj_start < mm->scan_start) @@ -586,11 +581,14 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) adj_end = mm->scan_end; } + if (mm->color_adjust) + mm->color_adjust(prev_node, mm->scan_color, + &adj_start, &adj_end); + if (check_free_hole(adj_start, adj_end, mm->scan_size, mm->scan_alignment)) { mm->scan_hit_start = hole_start; - mm->scan_hit_size = hole_end; - + mm->scan_hit_end = hole_end; return 1; } @@ -626,19 +624,10 @@ int drm_mm_scan_remove_block(struct drm_mm_node *node) node_list); prev_node->hole_follows = node->scanned_preceeds_hole; - INIT_LIST_HEAD(&node->node_list); list_add(&node->node_list, &prev_node->node_list); - /* Only need to check for containement because start&size for the - * complete resulting free block (not just the desired part) is - * stored. */ - if (node->start >= mm->scan_hit_start && - node->start + node->size - <= mm->scan_hit_start + mm->scan_hit_size) { - return 1; - } - - return 0; + return (drm_mm_hole_node_end(node) > mm->scan_hit_start && + node->start < mm->scan_hit_end); } EXPORT_SYMBOL(drm_mm_scan_remove_block); diff --git a/drivers/gpu/drm/exynos/exynos_ddc.c b/drivers/gpu/drm/exynos/exynos_ddc.c index bef43e0342a..4e9b5ba8edf 100644 --- a/drivers/gpu/drm/exynos/exynos_ddc.c +++ b/drivers/gpu/drm/exynos/exynos_ddc.c @@ -66,6 +66,6 @@ struct i2c_driver ddc_driver = { }, .id_table = ddc_idtable, .probe = s5p_ddc_probe, - .remove = __devexit_p(s5p_ddc_remove), + .remove = s5p_ddc_remove, .command = NULL, }; diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c index 9601bad47a2..57affae9568 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_buf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c @@ -3,24 +3,10 @@ * Copyright (c) 2011 Samsung Electronics Co., Ltd. * Author: Inki Dae <inki.dae@samsung.com> * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. */ #include <drm/drmP.h> @@ -29,6 +15,7 @@ #include "exynos_drm_drv.h" #include "exynos_drm_gem.h" #include "exynos_drm_buf.h" +#include "exynos_drm_iommu.h" static int lowlevel_buffer_allocate(struct drm_device *dev, unsigned int flags, struct exynos_drm_gem_buf *buf) @@ -51,7 +38,7 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, * region will be allocated else physically contiguous * as possible. */ - if (flags & EXYNOS_BO_CONTIG) + if (!(flags & EXYNOS_BO_NONCONTIG)) dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, &buf->dma_attrs); /* @@ -66,14 +53,45 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, dma_set_attr(attr, &buf->dma_attrs); dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &buf->dma_attrs); - buf->pages = dma_alloc_attrs(dev->dev, buf->size, - &buf->dma_addr, GFP_KERNEL, &buf->dma_attrs); - if (!buf->pages) { - DRM_ERROR("failed to allocate buffer.\n"); - return -ENOMEM; + nr_pages = buf->size >> PAGE_SHIFT; + + if (!is_drm_iommu_supported(dev)) { + dma_addr_t start_addr; + unsigned int i = 0; + + buf->pages = kzalloc(sizeof(struct page) * nr_pages, + GFP_KERNEL); + if (!buf->pages) { + DRM_ERROR("failed to allocate pages.\n"); + return -ENOMEM; + } + + buf->kvaddr = dma_alloc_attrs(dev->dev, buf->size, + &buf->dma_addr, GFP_KERNEL, + &buf->dma_attrs); + if (!buf->kvaddr) { + DRM_ERROR("failed to allocate buffer.\n"); + kfree(buf->pages); + return -ENOMEM; + } + + start_addr = buf->dma_addr; + while (i < nr_pages) { + buf->pages[i] = phys_to_page(start_addr); + start_addr += PAGE_SIZE; + i++; + } + } else { + + buf->pages = dma_alloc_attrs(dev->dev, buf->size, + &buf->dma_addr, GFP_KERNEL, + &buf->dma_attrs); + if (!buf->pages) { + DRM_ERROR("failed to allocate buffer.\n"); + return -ENOMEM; + } } - nr_pages = buf->size >> PAGE_SHIFT; buf->sgt = drm_prime_pages_to_sg(buf->pages, nr_pages); if (!buf->sgt) { DRM_ERROR("failed to get sg table.\n"); @@ -92,6 +110,9 @@ err_free_attrs: (dma_addr_t)buf->dma_addr, &buf->dma_attrs); buf->dma_addr = (dma_addr_t)NULL; + if (!is_drm_iommu_supported(dev)) + kfree(buf->pages); + return ret; } @@ -114,8 +135,14 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev, kfree(buf->sgt); buf->sgt = NULL; - dma_free_attrs(dev->dev, buf->size, buf->pages, + if (!is_drm_iommu_supported(dev)) { + dma_free_attrs(dev->dev, buf->size, buf->kvaddr, (dma_addr_t)buf->dma_addr, &buf->dma_attrs); + kfree(buf->pages); + } else + dma_free_attrs(dev->dev, buf->size, buf->pages, + (dma_addr_t)buf->dma_addr, &buf->dma_attrs); + buf->dma_addr = (dma_addr_t)NULL; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.h b/drivers/gpu/drm/exynos/exynos_drm_buf.h index 25cf1628503..a6412f19673 100644 --- a/drivers/gpu/ |