[PATCH 2/2] drm/omap: add GEM support for tiled/dmm buffers

2011-12-06 Thread Rob Clark
On Tue, Dec 6, 2011 at 5:30 AM, Alan Cox  wrote:
> On Mon, ?5 Dec 2011 19:19:22 -0600
> Rob Clark  wrote:
>
>> + ? ? usergart = kzalloc(3 * sizeof(*usergart), GFP_KERNEL);
>> +
>> + ? ? /* reserve 4k aligned/wide regions for userspace mappings: */
>> + ? ? for (i = 0; i < ARRAY_SIZE(fmts); i++) {
>> + ? ? ? ? ? ? uint16_t h = 1, w = PAGE_SIZE >> i;
>> + ? ? ? ? ? ? tiler_align(fmts[i], &w, &h);
>> + ? ? ? ? ? ? /* note: since each region is 1 4kb page wide, and minimum
>> + ? ? ? ? ? ? ?* number of rows, the height ends up being the same as the
>> + ? ? ? ? ? ? ?* # of pages in the region
>> + ? ? ? ? ? ? ?*/
>> + ? ? ? ? ? ? usergart[i].height = h;
>> + ? ? ? ? ? ? usergart[i].height_shift = ilog2(h);
>
> Seems to be missing anallocation failure check
>

oh, woops.. I've fixed that.. will give a couple more days to see if
there are any other comments and then send v2..

BR,
-R


Re: [PATCH 2/2] drm/omap: add GEM support for tiled/dmm buffers

2011-12-06 Thread Rob Clark
On Tue, Dec 6, 2011 at 5:30 AM, Alan Cox  wrote:
> On Mon,  5 Dec 2011 19:19:22 -0600
> Rob Clark  wrote:
>
>> +     usergart = kzalloc(3 * sizeof(*usergart), GFP_KERNEL);
>> +
>> +     /* reserve 4k aligned/wide regions for userspace mappings: */
>> +     for (i = 0; i < ARRAY_SIZE(fmts); i++) {
>> +             uint16_t h = 1, w = PAGE_SIZE >> i;
>> +             tiler_align(fmts[i], &w, &h);
>> +             /* note: since each region is 1 4kb page wide, and minimum
>> +              * number of rows, the height ends up being the same as the
>> +              * # of pages in the region
>> +              */
>> +             usergart[i].height = h;
>> +             usergart[i].height_shift = ilog2(h);
>
> Seems to be missing anallocation failure check
>

oh, woops.. I've fixed that.. will give a couple more days to see if
there are any other comments and then send v2..

BR,
-R
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 2/2] drm/omap: add GEM support for tiled/dmm buffers

2011-12-06 Thread Alan Cox
On Mon,  5 Dec 2011 19:19:22 -0600
Rob Clark  wrote:

> + usergart = kzalloc(3 * sizeof(*usergart), GFP_KERNEL);
> +
> + /* reserve 4k aligned/wide regions for userspace mappings: */
> + for (i = 0; i < ARRAY_SIZE(fmts); i++) {
> + uint16_t h = 1, w = PAGE_SIZE >> i;
> + tiler_align(fmts[i], &w, &h);
> + /* note: since each region is 1 4kb page wide, and minimum
> +  * number of rows, the height ends up being the same as the
> +  * # of pages in the region
> +  */
> + usergart[i].height = h;
> + usergart[i].height_shift = ilog2(h);

Seems to be missing anallocation failure check




Re: [PATCH 2/2] drm/omap: add GEM support for tiled/dmm buffers

2011-12-06 Thread Alan Cox
On Mon,  5 Dec 2011 19:19:22 -0600
Rob Clark  wrote:

> + usergart = kzalloc(3 * sizeof(*usergart), GFP_KERNEL);
> +
> + /* reserve 4k aligned/wide regions for userspace mappings: */
> + for (i = 0; i < ARRAY_SIZE(fmts); i++) {
> + uint16_t h = 1, w = PAGE_SIZE >> i;
> + tiler_align(fmts[i], &w, &h);
> + /* note: since each region is 1 4kb page wide, and minimum
> +  * number of rows, the height ends up being the same as the
> +  * # of pages in the region
> +  */
> + usergart[i].height = h;
> + usergart[i].height_shift = ilog2(h);

Seems to be missing anallocation failure check


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 2/2] drm/omap: add GEM support for tiled/dmm buffers

2011-12-05 Thread Rob Clark
From: Rob Clark 

TILER/DMM provides two features for omapdrm GEM objects:
1) providing a physically contiguous view to discontiguous memory
   for hw initiators that cannot otherwise support discontiguous
   buffers (DSS scanout, IVAHD video decode/encode, etc)
2) providing untiling for 2d tiled buffers, which are used in some
   cases to provide rotation and reduce memory bandwidth for hw
   initiators that tend to access data in 2d block patterns.

For 2d tiled buffers, there are some additional complications when
it comes to userspace mmap'ings.  For non-tiled buffers, the original
(potentially physically discontiguous) pages are used to back the
mmap.  For tiled buffers, we need to mmap via the tiler/dmm region to
provide an unswizzled view of the buffer.  But (a) the buffer is not
necessarily pinned in TILER all the time (it can be unmapped when
there is no DMA access to the buffer), and (b) when they are they
are pinned, they not necessarily page aligned from the perspective of
the CPU.  And non-page aligned userspace buffer mapping is evil.

To solve this, we reserve one or more small regions in each of the 2d
containers when the driver is loaded to use as a "user-GART" where we
can create a second page-aligned mapping of parts of the buffer being
accessed from userspace.  Page faulting is used to evict and remap
different regions of whichever buffers are being accessed from user-
space.

Signed-off-by: Rob Clark 
---
 drivers/staging/omapdrm/TODO   |5 +
 drivers/staging/omapdrm/omap_drv.c |6 +-
 drivers/staging/omapdrm/omap_drv.h |3 +
 drivers/staging/omapdrm/omap_fb.c  |2 +-
 drivers/staging/omapdrm/omap_gem.c |  432 +---
 drivers/staging/omapdrm/omap_gem_helpers.c |   55 
 6 files changed, 466 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/omapdrm/TODO b/drivers/staging/omapdrm/TODO
index 18677e7..55b1837 100644
--- a/drivers/staging/omapdrm/TODO
+++ b/drivers/staging/omapdrm/TODO
@@ -22,6 +22,11 @@ TODO
 . Review DSS vs KMS mismatches.  The omap_dss_device is sort of part encoder,
   part connector.  Which results in a bit of duct tape to fwd calls from
   encoder to connector.  Possibly this could be done a bit better.
+. Solve PM sequencing on resume.  DMM/TILER must be reloaded before any
+  access is made from any component in the system.  Which means on suspend
+  CRTC's should be disabled, and on resume the LUT should be reprogrammed
+  before CRTC's are re-enabled, to prevent DSS from trying to DMA from a
+  buffer mapped in DMM/TILER before LUT is reloaded.
 . Add debugfs information for DMM/TILER

 Userspace:
diff --git a/drivers/staging/omapdrm/omap_drv.c 
b/drivers/staging/omapdrm/omap_drv.c
index 71de7cf..7ecf578 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -509,7 +509,7 @@ static int ioctl_gem_info(struct drm_device *dev, void 
*data,
return -ENOENT;
}

-   args->size = obj->size;  /* for now */
+   args->size = omap_gem_mmap_size(obj);
args->offset = omap_gem_mmap_offset(obj);

drm_gem_object_unreference_unlocked(obj);
@@ -557,6 +557,8 @@ static int dev_load(struct drm_device *dev, unsigned long 
flags)

dev->dev_private = priv;

+   omap_gem_init(dev);
+
ret = omap_modeset_init(dev);
if (ret) {
dev_err(dev->dev, "omap_modeset_init failed: ret=%d\n", ret);
@@ -589,8 +591,8 @@ static int dev_unload(struct drm_device *dev)
drm_kms_helper_poll_fini(dev);

omap_fbdev_free(dev);
-
omap_modeset_free(dev);
+   omap_gem_deinit(dev);

kfree(dev->dev_private);
dev->dev_private = NULL;
diff --git a/drivers/staging/omapdrm/omap_drv.h 
b/drivers/staging/omapdrm/omap_drv.h
index c8f2752..9d0783d 100644
--- a/drivers/staging/omapdrm/omap_drv.h
+++ b/drivers/staging/omapdrm/omap_drv.h
@@ -84,6 +84,8 @@ struct drm_connector *omap_framebuffer_get_next_connector(
 void omap_framebuffer_flush(struct drm_framebuffer *fb,
int x, int y, int w, int h);

+void omap_gem_init(struct drm_device *dev);
+void omap_gem_deinit(struct drm_device *dev);

 struct drm_gem_object *omap_gem_new(struct drm_device *dev,
union omap_gem_size gsize, uint32_t flags);
@@ -109,6 +111,7 @@ int omap_gem_get_paddr(struct drm_gem_object *obj,
dma_addr_t *paddr, bool remap);
 int omap_gem_put_paddr(struct drm_gem_object *obj);
 uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj);
+size_t omap_gem_mmap_size(struct drm_gem_object *obj);

 static inline int align_pitch(int pitch, int width, int bpp)
 {
diff --git a/drivers/staging/omapdrm/omap_fb.c 
b/drivers/staging/omapdrm/omap_fb.c
index 82ed612..491be53 100644
--- a/drivers/staging/omapdrm/omap_fb.c
+++ b/drivers/staging/omapdrm/omap_fb.c
@@ -102,7 +102,7 @@ int omap_framebuffer_get_buffer(struct drm_framebuffer *fb, 
int x, int y,
   

[PATCH 2/2] drm/omap: add GEM support for tiled/dmm buffers

2011-12-05 Thread Rob Clark
From: Rob Clark 

TILER/DMM provides two features for omapdrm GEM objects:
1) providing a physically contiguous view to discontiguous memory
   for hw initiators that cannot otherwise support discontiguous
   buffers (DSS scanout, IVAHD video decode/encode, etc)
2) providing untiling for 2d tiled buffers, which are used in some
   cases to provide rotation and reduce memory bandwidth for hw
   initiators that tend to access data in 2d block patterns.

For 2d tiled buffers, there are some additional complications when
it comes to userspace mmap'ings.  For non-tiled buffers, the original
(potentially physically discontiguous) pages are used to back the
mmap.  For tiled buffers, we need to mmap via the tiler/dmm region to
provide an unswizzled view of the buffer.  But (a) the buffer is not
necessarily pinned in TILER all the time (it can be unmapped when
there is no DMA access to the buffer), and (b) when they are they
are pinned, they not necessarily page aligned from the perspective of
the CPU.  And non-page aligned userspace buffer mapping is evil.

To solve this, we reserve one or more small regions in each of the 2d
containers when the driver is loaded to use as a "user-GART" where we
can create a second page-aligned mapping of parts of the buffer being
accessed from userspace.  Page faulting is used to evict and remap
different regions of whichever buffers are being accessed from user-
space.

Signed-off-by: Rob Clark 
---
 drivers/staging/omapdrm/TODO   |5 +
 drivers/staging/omapdrm/omap_drv.c |6 +-
 drivers/staging/omapdrm/omap_drv.h |3 +
 drivers/staging/omapdrm/omap_fb.c  |2 +-
 drivers/staging/omapdrm/omap_gem.c |  432 +---
 drivers/staging/omapdrm/omap_gem_helpers.c |   55 
 6 files changed, 466 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/omapdrm/TODO b/drivers/staging/omapdrm/TODO
index 18677e7..55b1837 100644
--- a/drivers/staging/omapdrm/TODO
+++ b/drivers/staging/omapdrm/TODO
@@ -22,6 +22,11 @@ TODO
 . Review DSS vs KMS mismatches.  The omap_dss_device is sort of part encoder,
   part connector.  Which results in a bit of duct tape to fwd calls from
   encoder to connector.  Possibly this could be done a bit better.
+. Solve PM sequencing on resume.  DMM/TILER must be reloaded before any
+  access is made from any component in the system.  Which means on suspend
+  CRTC's should be disabled, and on resume the LUT should be reprogrammed
+  before CRTC's are re-enabled, to prevent DSS from trying to DMA from a
+  buffer mapped in DMM/TILER before LUT is reloaded.
 . Add debugfs information for DMM/TILER
 
 Userspace:
diff --git a/drivers/staging/omapdrm/omap_drv.c 
b/drivers/staging/omapdrm/omap_drv.c
index 71de7cf..7ecf578 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -509,7 +509,7 @@ static int ioctl_gem_info(struct drm_device *dev, void 
*data,
return -ENOENT;
}
 
-   args->size = obj->size;  /* for now */
+   args->size = omap_gem_mmap_size(obj);
args->offset = omap_gem_mmap_offset(obj);
 
drm_gem_object_unreference_unlocked(obj);
@@ -557,6 +557,8 @@ static int dev_load(struct drm_device *dev, unsigned long 
flags)
 
dev->dev_private = priv;
 
+   omap_gem_init(dev);
+
ret = omap_modeset_init(dev);
if (ret) {
dev_err(dev->dev, "omap_modeset_init failed: ret=%d\n", ret);
@@ -589,8 +591,8 @@ static int dev_unload(struct drm_device *dev)
drm_kms_helper_poll_fini(dev);
 
omap_fbdev_free(dev);
-
omap_modeset_free(dev);
+   omap_gem_deinit(dev);
 
kfree(dev->dev_private);
dev->dev_private = NULL;
diff --git a/drivers/staging/omapdrm/omap_drv.h 
b/drivers/staging/omapdrm/omap_drv.h
index c8f2752..9d0783d 100644
--- a/drivers/staging/omapdrm/omap_drv.h
+++ b/drivers/staging/omapdrm/omap_drv.h
@@ -84,6 +84,8 @@ struct drm_connector *omap_framebuffer_get_next_connector(
 void omap_framebuffer_flush(struct drm_framebuffer *fb,
int x, int y, int w, int h);
 
+void omap_gem_init(struct drm_device *dev);
+void omap_gem_deinit(struct drm_device *dev);
 
 struct drm_gem_object *omap_gem_new(struct drm_device *dev,
union omap_gem_size gsize, uint32_t flags);
@@ -109,6 +111,7 @@ int omap_gem_get_paddr(struct drm_gem_object *obj,
dma_addr_t *paddr, bool remap);
 int omap_gem_put_paddr(struct drm_gem_object *obj);
 uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj);
+size_t omap_gem_mmap_size(struct drm_gem_object *obj);
 
 static inline int align_pitch(int pitch, int width, int bpp)
 {
diff --git a/drivers/staging/omapdrm/omap_fb.c 
b/drivers/staging/omapdrm/omap_fb.c
index 82ed612..491be53 100644
--- a/drivers/staging/omapdrm/omap_fb.c
+++ b/drivers/staging/omapdrm/omap_fb.c
@@ -102,7 +102,7 @@ int omap_framebuffer_get_buffer(struct drm_framebuffer *fb, 
int x, int y,