staging: add omapdrm DRM/KMS driver for TI OMAP platforms
A DRM display driver for TI OMAP platform. Similar to omapfb (fbdev)
and omap_vout (v4l2 display) drivers in the past, this driver uses the
DSS2 driver to access the display hardware, including support for
HDMI, DVI, and various types of LCD panels. And it implements GEM
support for buffer allocation (for KMS as well as offscreen buffers
used by the xf86-video-omap userspace xorg driver).
The driver maps CRTCs to overlays, encoders to overlay-managers, and
connectors to dssdev's. Note that this arrangement might change slightly
when support for drm_plane overlays is added.
For GEM support, non-scanout buffers are using the shmem backed pages
provided by GEM core (In drm_gem_object_init()). In the case of scanout
buffers, which need to be physically contiguous, those are allocated
with CMA and use drm_gem_private_object_init().
See userspace xorg driver:
git://github.com/robclark/xf86-video-omap.git
Refer to this link for CMA (Continuous Memory Allocator):
http://lkml.org/lkml/2011/8/19/302
Links to previous versions of the patch:
v1: http://lwn.net/Articles/458137/
v2: http://patches.linaro.org/4156/
v3: http://patches.linaro.org/4688/
v4: http://patches.linaro.org/4791/
History:
v5: move headers from include/drm at Greg KH's request, minor rebasing
on 3.2-rc1, pull in private copies of drm_gem_{get,put}_pages()
because "drm/gem: add functions to get/put pages" patch is not
merged yet
v4: bit of rework of encoder/connector _dpms() code, modeset_init()
rework to not use nested functions, update TODO.txt
v3: minor cleanups, improved error handling for dev_load(), some minor
API changes that will be needed later for tiled buffer support
v2: replace omap_vram with CMA for scanout buffer allocation, remove
unneeded functions, use dma_addr_t for physical addresses, error
handling cleanup, refactor attach/detach pages into common drm
functions, split non-userspace-facing API into omap_priv.h, remove
plugin API
v1: original
Signed-off-by: Rob Clark <rob@ti.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2011-11-12 18:09:40 +00:00
|
|
|
/*
|
2013-02-11 17:43:09 +00:00
|
|
|
* drivers/gpu/drm/omapdrm/omap_gem_helpers.c
|
staging: add omapdrm DRM/KMS driver for TI OMAP platforms
A DRM display driver for TI OMAP platform. Similar to omapfb (fbdev)
and omap_vout (v4l2 display) drivers in the past, this driver uses the
DSS2 driver to access the display hardware, including support for
HDMI, DVI, and various types of LCD panels. And it implements GEM
support for buffer allocation (for KMS as well as offscreen buffers
used by the xf86-video-omap userspace xorg driver).
The driver maps CRTCs to overlays, encoders to overlay-managers, and
connectors to dssdev's. Note that this arrangement might change slightly
when support for drm_plane overlays is added.
For GEM support, non-scanout buffers are using the shmem backed pages
provided by GEM core (In drm_gem_object_init()). In the case of scanout
buffers, which need to be physically contiguous, those are allocated
with CMA and use drm_gem_private_object_init().
See userspace xorg driver:
git://github.com/robclark/xf86-video-omap.git
Refer to this link for CMA (Continuous Memory Allocator):
http://lkml.org/lkml/2011/8/19/302
Links to previous versions of the patch:
v1: http://lwn.net/Articles/458137/
v2: http://patches.linaro.org/4156/
v3: http://patches.linaro.org/4688/
v4: http://patches.linaro.org/4791/
History:
v5: move headers from include/drm at Greg KH's request, minor rebasing
on 3.2-rc1, pull in private copies of drm_gem_{get,put}_pages()
because "drm/gem: add functions to get/put pages" patch is not
merged yet
v4: bit of rework of encoder/connector _dpms() code, modeset_init()
rework to not use nested functions, update TODO.txt
v3: minor cleanups, improved error handling for dev_load(), some minor
API changes that will be needed later for tiled buffer support
v2: replace omap_vram with CMA for scanout buffer allocation, remove
unneeded functions, use dma_addr_t for physical addresses, error
handling cleanup, refactor attach/detach pages into common drm
functions, split non-userspace-facing API into omap_priv.h, remove
plugin API
v1: original
Signed-off-by: Rob Clark <rob@ti.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2011-11-12 18:09:40 +00:00
|
|
|
*
|
|
|
|
* Copyright (C) 2011 Texas Instruments
|
|
|
|
* Author: Rob Clark <rob.clark@linaro.org>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License version 2 as published by
|
|
|
|
* the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
|
|
* more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along with
|
|
|
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* temporary copy of drm_gem_{get,put}_pages() until the
|
|
|
|
* "drm/gem: add functions to get/put pages" patch is merged..
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/types.h>
|
|
|
|
#include <linux/shmem_fs.h>
|
|
|
|
|
|
|
|
#include <drm/drmP.h>
|
|
|
|
|
|
|
|
/**
|
|
|
|
* drm_gem_get_pages - helper to allocate backing pages for a GEM object
|
|
|
|
* @obj: obj in question
|
|
|
|
* @gfpmask: gfp mask of requested pages
|
|
|
|
*/
|
2012-11-14 10:40:29 +00:00
|
|
|
struct page **_drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask)
|
staging: add omapdrm DRM/KMS driver for TI OMAP platforms
A DRM display driver for TI OMAP platform. Similar to omapfb (fbdev)
and omap_vout (v4l2 display) drivers in the past, this driver uses the
DSS2 driver to access the display hardware, including support for
HDMI, DVI, and various types of LCD panels. And it implements GEM
support for buffer allocation (for KMS as well as offscreen buffers
used by the xf86-video-omap userspace xorg driver).
The driver maps CRTCs to overlays, encoders to overlay-managers, and
connectors to dssdev's. Note that this arrangement might change slightly
when support for drm_plane overlays is added.
For GEM support, non-scanout buffers are using the shmem backed pages
provided by GEM core (In drm_gem_object_init()). In the case of scanout
buffers, which need to be physically contiguous, those are allocated
with CMA and use drm_gem_private_object_init().
See userspace xorg driver:
git://github.com/robclark/xf86-video-omap.git
Refer to this link for CMA (Continuous Memory Allocator):
http://lkml.org/lkml/2011/8/19/302
Links to previous versions of the patch:
v1: http://lwn.net/Articles/458137/
v2: http://patches.linaro.org/4156/
v3: http://patches.linaro.org/4688/
v4: http://patches.linaro.org/4791/
History:
v5: move headers from include/drm at Greg KH's request, minor rebasing
on 3.2-rc1, pull in private copies of drm_gem_{get,put}_pages()
because "drm/gem: add functions to get/put pages" patch is not
merged yet
v4: bit of rework of encoder/connector _dpms() code, modeset_init()
rework to not use nested functions, update TODO.txt
v3: minor cleanups, improved error handling for dev_load(), some minor
API changes that will be needed later for tiled buffer support
v2: replace omap_vram with CMA for scanout buffer allocation, remove
unneeded functions, use dma_addr_t for physical addresses, error
handling cleanup, refactor attach/detach pages into common drm
functions, split non-userspace-facing API into omap_priv.h, remove
plugin API
v1: original
Signed-off-by: Rob Clark <rob@ti.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2011-11-12 18:09:40 +00:00
|
|
|
{
|
|
|
|
struct inode *inode;
|
|
|
|
struct address_space *mapping;
|
|
|
|
struct page *p, **pages;
|
|
|
|
int i, npages;
|
|
|
|
|
|
|
|
/* This is the shared memory object that backs the GEM resource */
|
2013-01-23 22:07:38 +00:00
|
|
|
inode = file_inode(obj->filp);
|
staging: add omapdrm DRM/KMS driver for TI OMAP platforms
A DRM display driver for TI OMAP platform. Similar to omapfb (fbdev)
and omap_vout (v4l2 display) drivers in the past, this driver uses the
DSS2 driver to access the display hardware, including support for
HDMI, DVI, and various types of LCD panels. And it implements GEM
support for buffer allocation (for KMS as well as offscreen buffers
used by the xf86-video-omap userspace xorg driver).
The driver maps CRTCs to overlays, encoders to overlay-managers, and
connectors to dssdev's. Note that this arrangement might change slightly
when support for drm_plane overlays is added.
For GEM support, non-scanout buffers are using the shmem backed pages
provided by GEM core (In drm_gem_object_init()). In the case of scanout
buffers, which need to be physically contiguous, those are allocated
with CMA and use drm_gem_private_object_init().
See userspace xorg driver:
git://github.com/robclark/xf86-video-omap.git
Refer to this link for CMA (Continuous Memory Allocator):
http://lkml.org/lkml/2011/8/19/302
Links to previous versions of the patch:
v1: http://lwn.net/Articles/458137/
v2: http://patches.linaro.org/4156/
v3: http://patches.linaro.org/4688/
v4: http://patches.linaro.org/4791/
History:
v5: move headers from include/drm at Greg KH's request, minor rebasing
on 3.2-rc1, pull in private copies of drm_gem_{get,put}_pages()
because "drm/gem: add functions to get/put pages" patch is not
merged yet
v4: bit of rework of encoder/connector _dpms() code, modeset_init()
rework to not use nested functions, update TODO.txt
v3: minor cleanups, improved error handling for dev_load(), some minor
API changes that will be needed later for tiled buffer support
v2: replace omap_vram with CMA for scanout buffer allocation, remove
unneeded functions, use dma_addr_t for physical addresses, error
handling cleanup, refactor attach/detach pages into common drm
functions, split non-userspace-facing API into omap_priv.h, remove
plugin API
v1: original
Signed-off-by: Rob Clark <rob@ti.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2011-11-12 18:09:40 +00:00
|
|
|
mapping = inode->i_mapping;
|
|
|
|
|
|
|
|
npages = obj->size >> PAGE_SHIFT;
|
|
|
|
|
|
|
|
pages = drm_malloc_ab(npages, sizeof(struct page *));
|
|
|
|
if (pages == NULL)
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
|
|
|
|
gfpmask |= mapping_gfp_mask(mapping);
|
|
|
|
|
|
|
|
for (i = 0; i < npages; i++) {
|
|
|
|
p = shmem_read_mapping_page_gfp(mapping, i, gfpmask);
|
|
|
|
if (IS_ERR(p))
|
|
|
|
goto fail;
|
|
|
|
pages[i] = p;
|
|
|
|
|
|
|
|
/* There is a hypothetical issue w/ drivers that require
|
|
|
|
* buffer memory in the low 4GB.. if the pages are un-
|
|
|
|
* pinned, and swapped out, they can end up swapped back
|
|
|
|
* in above 4GB. If pages are already in memory, then
|
|
|
|
* shmem_read_mapping_page_gfp will ignore the gfpmask,
|
|
|
|
* even if the already in-memory page disobeys the mask.
|
|
|
|
*
|
|
|
|
* It is only a theoretical issue today, because none of
|
|
|
|
* the devices with this limitation can be populated with
|
|
|
|
* enough memory to trigger the issue. But this BUG_ON()
|
|
|
|
* is here as a reminder in case the problem with
|
|
|
|
* shmem_read_mapping_page_gfp() isn't solved by the time
|
|
|
|
* it does become a real issue.
|
|
|
|
*
|
|
|
|
* See this thread: http://lkml.org/lkml/2011/7/11/238
|
|
|
|
*/
|
|
|
|
BUG_ON((gfpmask & __GFP_DMA32) &&
|
|
|
|
(page_to_pfn(p) >= 0x00100000UL));
|
|
|
|
}
|
|
|
|
|
|
|
|
return pages;
|
|
|
|
|
|
|
|
fail:
|
2012-11-14 10:40:43 +00:00
|
|
|
while (i--)
|
staging: add omapdrm DRM/KMS driver for TI OMAP platforms
A DRM display driver for TI OMAP platform. Similar to omapfb (fbdev)
and omap_vout (v4l2 display) drivers in the past, this driver uses the
DSS2 driver to access the display hardware, including support for
HDMI, DVI, and various types of LCD panels. And it implements GEM
support for buffer allocation (for KMS as well as offscreen buffers
used by the xf86-video-omap userspace xorg driver).
The driver maps CRTCs to overlays, encoders to overlay-managers, and
connectors to dssdev's. Note that this arrangement might change slightly
when support for drm_plane overlays is added.
For GEM support, non-scanout buffers are using the shmem backed pages
provided by GEM core (In drm_gem_object_init()). In the case of scanout
buffers, which need to be physically contiguous, those are allocated
with CMA and use drm_gem_private_object_init().
See userspace xorg driver:
git://github.com/robclark/xf86-video-omap.git
Refer to this link for CMA (Continuous Memory Allocator):
http://lkml.org/lkml/2011/8/19/302
Links to previous versions of the patch:
v1: http://lwn.net/Articles/458137/
v2: http://patches.linaro.org/4156/
v3: http://patches.linaro.org/4688/
v4: http://patches.linaro.org/4791/
History:
v5: move headers from include/drm at Greg KH's request, minor rebasing
on 3.2-rc1, pull in private copies of drm_gem_{get,put}_pages()
because "drm/gem: add functions to get/put pages" patch is not
merged yet
v4: bit of rework of encoder/connector _dpms() code, modeset_init()
rework to not use nested functions, update TODO.txt
v3: minor cleanups, improved error handling for dev_load(), some minor
API changes that will be needed later for tiled buffer support
v2: replace omap_vram with CMA for scanout buffer allocation, remove
unneeded functions, use dma_addr_t for physical addresses, error
handling cleanup, refactor attach/detach pages into common drm
functions, split non-userspace-facing API into omap_priv.h, remove
plugin API
v1: original
Signed-off-by: Rob Clark <rob@ti.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2011-11-12 18:09:40 +00:00
|
|
|
page_cache_release(pages[i]);
|
2012-11-14 10:40:43 +00:00
|
|
|
|
staging: add omapdrm DRM/KMS driver for TI OMAP platforms
A DRM display driver for TI OMAP platform. Similar to omapfb (fbdev)
and omap_vout (v4l2 display) drivers in the past, this driver uses the
DSS2 driver to access the display hardware, including support for
HDMI, DVI, and various types of LCD panels. And it implements GEM
support for buffer allocation (for KMS as well as offscreen buffers
used by the xf86-video-omap userspace xorg driver).
The driver maps CRTCs to overlays, encoders to overlay-managers, and
connectors to dssdev's. Note that this arrangement might change slightly
when support for drm_plane overlays is added.
For GEM support, non-scanout buffers are using the shmem backed pages
provided by GEM core (In drm_gem_object_init()). In the case of scanout
buffers, which need to be physically contiguous, those are allocated
with CMA and use drm_gem_private_object_init().
See userspace xorg driver:
git://github.com/robclark/xf86-video-omap.git
Refer to this link for CMA (Continuous Memory Allocator):
http://lkml.org/lkml/2011/8/19/302
Links to previous versions of the patch:
v1: http://lwn.net/Articles/458137/
v2: http://patches.linaro.org/4156/
v3: http://patches.linaro.org/4688/
v4: http://patches.linaro.org/4791/
History:
v5: move headers from include/drm at Greg KH's request, minor rebasing
on 3.2-rc1, pull in private copies of drm_gem_{get,put}_pages()
because "drm/gem: add functions to get/put pages" patch is not
merged yet
v4: bit of rework of encoder/connector _dpms() code, modeset_init()
rework to not use nested functions, update TODO.txt
v3: minor cleanups, improved error handling for dev_load(), some minor
API changes that will be needed later for tiled buffer support
v2: replace omap_vram with CMA for scanout buffer allocation, remove
unneeded functions, use dma_addr_t for physical addresses, error
handling cleanup, refactor attach/detach pages into common drm
functions, split non-userspace-facing API into omap_priv.h, remove
plugin API
v1: original
Signed-off-by: Rob Clark <rob@ti.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2011-11-12 18:09:40 +00:00
|
|
|
drm_free_large(pages);
|
2012-01-22 17:27:21 +00:00
|
|
|
return ERR_CAST(p);
|
staging: add omapdrm DRM/KMS driver for TI OMAP platforms
A DRM display driver for TI OMAP platform. Similar to omapfb (fbdev)
and omap_vout (v4l2 display) drivers in the past, this driver uses the
DSS2 driver to access the display hardware, including support for
HDMI, DVI, and various types of LCD panels. And it implements GEM
support for buffer allocation (for KMS as well as offscreen buffers
used by the xf86-video-omap userspace xorg driver).
The driver maps CRTCs to overlays, encoders to overlay-managers, and
connectors to dssdev's. Note that this arrangement might change slightly
when support for drm_plane overlays is added.
For GEM support, non-scanout buffers are using the shmem backed pages
provided by GEM core (In drm_gem_object_init()). In the case of scanout
buffers, which need to be physically contiguous, those are allocated
with CMA and use drm_gem_private_object_init().
See userspace xorg driver:
git://github.com/robclark/xf86-video-omap.git
Refer to this link for CMA (Continuous Memory Allocator):
http://lkml.org/lkml/2011/8/19/302
Links to previous versions of the patch:
v1: http://lwn.net/Articles/458137/
v2: http://patches.linaro.org/4156/
v3: http://patches.linaro.org/4688/
v4: http://patches.linaro.org/4791/
History:
v5: move headers from include/drm at Greg KH's request, minor rebasing
on 3.2-rc1, pull in private copies of drm_gem_{get,put}_pages()
because "drm/gem: add functions to get/put pages" patch is not
merged yet
v4: bit of rework of encoder/connector _dpms() code, modeset_init()
rework to not use nested functions, update TODO.txt
v3: minor cleanups, improved error handling for dev_load(), some minor
API changes that will be needed later for tiled buffer support
v2: replace omap_vram with CMA for scanout buffer allocation, remove
unneeded functions, use dma_addr_t for physical addresses, error
handling cleanup, refactor attach/detach pages into common drm
functions, split non-userspace-facing API into omap_priv.h, remove
plugin API
v1: original
Signed-off-by: Rob Clark <rob@ti.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2011-11-12 18:09:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* drm_gem_put_pages - helper to free backing pages for a GEM object
|
|
|
|
* @obj: obj in question
|
|
|
|
* @pages: pages to free
|
|
|
|
*/
|
|
|
|
void _drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages,
|
|
|
|
bool dirty, bool accessed)
|
|
|
|
{
|
|
|
|
int i, npages;
|
|
|
|
|
|
|
|
npages = obj->size >> PAGE_SHIFT;
|
|
|
|
|
|
|
|
for (i = 0; i < npages; i++) {
|
|
|
|
if (dirty)
|
|
|
|
set_page_dirty(pages[i]);
|
|
|
|
|
|
|
|
if (accessed)
|
|
|
|
mark_page_accessed(pages[i]);
|
|
|
|
|
|
|
|
/* Undo the reference we took when populating the table */
|
|
|
|
page_cache_release(pages[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
drm_free_large(pages);
|
|
|
|
}
|
2011-12-06 01:19:22 +00:00
|
|
|
|
|
|
|
int
|
|
|
|
_drm_gem_create_mmap_offset_size(struct drm_gem_object *obj, size_t size)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = obj->dev;
|
|
|
|
struct drm_gem_mm *mm = dev->mm_private;
|
|
|
|
struct drm_map_list *list;
|
|
|
|
struct drm_local_map *map;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
/* Set the object up for mmap'ing */
|
|
|
|
list = &obj->map_list;
|
|
|
|
list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
|
|
|
|
if (!list->map)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
map = list->map;
|
|
|
|
map->type = _DRM_GEM;
|
|
|
|
map->size = size;
|
|
|
|
map->handle = obj;
|
|
|
|
|
|
|
|
/* Get a DRM GEM mmap offset allocated... */
|
|
|
|
list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
|
|
|
|
size / PAGE_SIZE, 0, 0);
|
|
|
|
|
|
|
|
if (!list->file_offset_node) {
|
|
|
|
DRM_ERROR("failed to allocate offset for bo %d\n", obj->name);
|
|
|
|
ret = -ENOSPC;
|
|
|
|
goto out_free_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
list->file_offset_node = drm_mm_get_block(list->file_offset_node,
|
|
|
|
size / PAGE_SIZE, 0);
|
|
|
|
if (!list->file_offset_node) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto out_free_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
list->hash.key = list->file_offset_node->start;
|
|
|
|
ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
|
|
|
|
if (ret) {
|
|
|
|
DRM_ERROR("failed to add to map hash\n");
|
|
|
|
goto out_free_mm;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
out_free_mm:
|
|
|
|
drm_mm_put_block(list->file_offset_node);
|
|
|
|
out_free_list:
|
|
|
|
kfree(list->map);
|
|
|
|
list->map = NULL;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|