Re: [PATCH] drm/exynos: g2d: fix overflow of cmdlist size

2017-01-23 Thread Joonyoung Shim
Hi Tobias,

On 01/21/2017 01:05 AM, Tobias Jakobi wrote:
> Hello Joonyoung,
> 
> 
> Joonyoung Shim wrote:
>> Hi Tobias,
>>
>> On 01/19/2017 10:16 PM, Tobias Jakobi wrote:
>>> Hello Joonyoung,
>>>
>>> Joonyoung Shim wrote:
>>>> Hi Tobias,
>>>>
>>>> On 01/17/2017 11:24 PM, Tobias Jakobi wrote:
>>>>> Joonyoung Shim wrote:
>>>>>> The size of cmdlist is integer type, so it can be overflowed by cmd and
>>>>>> cmd_buf that has too big size. This patch will fix overflow issue as
>>>>>> checking maximum size of cmd and cmd_buf.
>>>>> I don't understand/see the issue here. Could you point out for which
>>>>> input of the set_cmdlist ioctl you see this particular overflow?
>>>>>
>>>>> In particular it is not clear to me which size field you're talking
>>>>> about. struct g2d_cmdlist does not have any field named 'size'.
>>>>>
>>>>
>>>> I mean size of cmdlist is
>>>> size = cmdlist->last + req->cmd_nr * 2 + req->cmd_buf_nr * 2 + 2;
>>>> in exynos_g2d_set_cmdlist_ioctl().
>>> ok, that makes things more clear. But then you need to fix the commit
>>> message. The current message implies that this 'size' you're talking
>>> about is some property of the cmdlist.
>>>
>>> Also the new comment is wrong.
>>> /* Check size of cmd and cmdlist: last 2 is about G2D_BITBLT_START */
>>>
>>> What is cmd and cmdlist? You're mixing two different things here. We are
>>> still checking the size of 'cmdlist' (which is a struct g2d_cmdlist) here.
>>>
>>> What you add is a check for the fields of 'req' (which is a struct
>>> drm_exynos_g2d_set_cmdlist).
>>>
>>> With all that said, I don't like the changes. I see the issue, but the
>>> current solution should be cleaner.
>>>
>>> I propose this. We just check req->cmd_buf_nr and req->cmd_nr against
>>> G2D_CMDLIST_DATA_NUM. This leaves us enough headrom so that the later
>>> computation (i.e. what is ending up in the local variable 'size') can
>>> never overflow.
>>>
>>
>> Agree, it's more clear to check req->cmd_buf_nr and req->cmd_nr against
>> G2D_CMDLIST_DATA_NUM.
>>
>>> For a comment for the check I propose this:
>>> "To avoid an integer overflow for the later size computations, we
>>> enforce a maximum number of submitted commands here. This limit is
>>> sufficient for all conceivable usage cases of the G2D."
>>>
>>
>> Could you post your patch to ML about this if you want?
> Sure, I've just send it together with two other small patches. Let me
> know if the current version is OK with you. I hope I did the order of
> SoB correctly (I know that Krzysztof has pointed this out lately).
> 

I don't know exactly about order of SoB but it's ok to me except
WARNING: line over 80 characters from checkpatch.pl.

Thanks for posting.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/exynos: g2d: fix overflow of cmdlist size

2017-01-19 Thread Joonyoung Shim
Hi Tobias,

On 01/19/2017 10:16 PM, Tobias Jakobi wrote:
> Hello Joonyoung,
> 
> Joonyoung Shim wrote:
>> Hi Tobias,
>>
>> On 01/17/2017 11:24 PM, Tobias Jakobi wrote:
>>> Joonyoung Shim wrote:
>>>> The size of cmdlist is integer type, so it can be overflowed by cmd and
>>>> cmd_buf that has too big size. This patch will fix overflow issue as
>>>> checking maximum size of cmd and cmd_buf.
>>> I don't understand/see the issue here. Could you point out for which
>>> input of the set_cmdlist ioctl you see this particular overflow?
>>>
>>> In particular it is not clear to me which size field you're talking
>>> about. struct g2d_cmdlist does not have any field named 'size'.
>>>
>>
>> I mean size of cmdlist is
>> size = cmdlist->last + req->cmd_nr * 2 + req->cmd_buf_nr * 2 + 2;
>> in exynos_g2d_set_cmdlist_ioctl().
> ok, that makes things more clear. But then you need to fix the commit
> message. The current message implies that this 'size' you're talking
> about is some property of the cmdlist.
> 
> Also the new comment is wrong.
> /* Check size of cmd and cmdlist: last 2 is about G2D_BITBLT_START */
> 
> What is cmd and cmdlist? You're mixing two different things here. We are
> still checking the size of 'cmdlist' (which is a struct g2d_cmdlist) here.
> 
> What you add is a check for the fields of 'req' (which is a struct
> drm_exynos_g2d_set_cmdlist).
> 
> With all that said, I don't like the changes. I see the issue, but the
> current solution should be cleaner.
> 
> I propose this. We just check req->cmd_buf_nr and req->cmd_nr against
> G2D_CMDLIST_DATA_NUM. This leaves us enough headrom so that the later
> computation (i.e. what is ending up in the local variable 'size') can
> never overflow.
> 

Agree, it's more clear to check req->cmd_buf_nr and req->cmd_nr against
G2D_CMDLIST_DATA_NUM.

> For a comment for the check I propose this:
> "To avoid an integer overflow for the later size computations, we
> enforce a maximum number of submitted commands here. This limit is
> sufficient for all conceivable usage cases of the G2D."
> 

Could you post your patch to ML about this if you want?

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


Re: [PATCH] drm/exynos: g2d: fix overflow of cmdlist size

2017-01-17 Thread Joonyoung Shim
Hi Tobias,

On 01/17/2017 11:24 PM, Tobias Jakobi wrote:
> Joonyoung Shim wrote:
>> The size of cmdlist is integer type, so it can be overflowed by cmd and
>> cmd_buf that has too big size. This patch will fix overflow issue as
>> checking maximum size of cmd and cmd_buf.
> I don't understand/see the issue here. Could you point out for which
> input of the set_cmdlist ioctl you see this particular overflow?
> 
> In particular it is not clear to me which size field you're talking
> about. struct g2d_cmdlist does not have any field named 'size'.
> 

I mean size of cmdlist is
size = cmdlist->last + req->cmd_nr * 2 + req->cmd_buf_nr * 2 + 2;
in exynos_g2d_set_cmdlist_ioctl().

You can reproduce overflow of size easily if you use value like
4294967295 or 2147483647 at the req->cmd_buf_nr.

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


[PATCH] drm/exynos: g2d: fix overflow of cmdlist size

2017-01-16 Thread Joonyoung Shim
The size of cmdlist is integer type, so it can be overflowed by cmd and
cmd_buf that has too big size. This patch will fix overflow issue as
checking maximum size of cmd and cmd_buf.

Signed-off-by: Joonyoung Shim <jy0922.s...@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_g2d.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c 
b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index fbd13fa..b31244f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -1250,7 +1250,14 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device 
*drm_dev, void *data,
cmdlist->data[cmdlist->last++] = G2D_INTEN_ACF;
}
 
-   /* Check size of cmdlist: last 2 is about G2D_BITBLT_START */
+   /* Check size of cmd and cmdlist: last 2 is about G2D_BITBLT_START */
+   size = (G2D_CMDLIST_DATA_NUM - cmdlist->last - 2) / 2;
+   if (req->cmd_nr > size || req->cmd_buf_nr > size) {
+   dev_err(dev, "size of cmd or cmd_buf is too big\n");
+   ret = -EINVAL;
+   goto err_free_event;
+   }
+
size = cmdlist->last + req->cmd_nr * 2 + req->cmd_buf_nr * 2 + 2;
if (size > G2D_CMDLIST_DATA_NUM) {
dev_err(dev, "cmdlist size is too big\n");
-- 
1.9.1

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


Re: [PATCH v2] drm/exynos/decon5433: set STANDALONE_UPDATE_F also if planes are disabled

2017-01-13 Thread Joonyoung Shim
Hi Andrzej,

On 01/13/2017 05:42 PM, Andrzej Hajda wrote:
> @@ -339,8 +342,10 @@ static void decon_atomic_flush(struct exynos_drm_crtc 
> *crtc)
>   decon_shadow_protect_win(ctx, i, false);
>  
>   /* update iff there are active windows */
> - if (crtc->base.state->plane_mask)
> + if (test_bit(BIT_REQUEST_UPDATE, >flags)) {

It's better to just use test_and_clear_bit?

>   decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
> + clear_bit(BIT_REQUEST_UPDATE, >flags);
> + }
>  
>   if (ctx->out_type & IFTYPE_I80)
>   set_bit(BIT_WIN_UPDATED, >flags);
> 

I tested on TM2E board,

Tested-by: Joonyoung Shim <jy0922.s...@samsung.com>

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


Re: [PATCH] drm/exynos/decon5433: set STANDALONE_UPDATE_F also if planes are disabled

2017-01-13 Thread Joonyoung Shim
Hi Andrzej,

On 01/13/2017 05:10 PM, Andrzej Hajda wrote:
> STANDALONE_UPDATE_F should be set if something changed in plane 
> configurations,
> including plane disable.
> The patch fixes page-faults bugs, caused by decon still using framebuffers
> of disabled planes.
> 
> Signed-off-by: Andrzej Hajda 
> ---
>  drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 9 +++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c 
> b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
> index ef7fcb5..3999e88 100644
> --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
> +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
> @@ -46,7 +46,8 @@ enum decon_flag_bits {
>   BIT_CLKS_ENABLED,
>   BIT_IRQS_ENABLED,
>   BIT_WIN_UPDATED,
> - BIT_SUSPENDED
> + BIT_SUSPENDED,
> + BIT_REQUEST_UPDATE
>  };
>  
>  struct decon_context {
> @@ -313,6 +314,7 @@ static void decon_update_plane(struct exynos_drm_crtc 
> *crtc,
>  
>   /* window enable */
>   decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, ~0);
> + set_bit(BIT_REQUEST_UPDATE, >flags);
>  }
>  
>  static void decon_disable_plane(struct exynos_drm_crtc *crtc,
> @@ -325,6 +327,7 @@ static void decon_disable_plane(struct exynos_drm_crtc 
> *crtc,
>   return;
>  
>   decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);
> + set_bit(BIT_REQUEST_UPDATE, >flags);
>  }
>  
>  static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
> @@ -339,8 +342,10 @@ static void decon_atomic_flush(struct exynos_drm_crtc 
> *crtc)
>   decon_shadow_protect_win(ctx, i, false);
>  
>   /* update iff there are active windows */
> - if (crtc->base.state->plane_mask)
> + if (test_bit(BIT_REQUEST_UPDATE, >flags)) {
>   decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
> + set_bit(BIT_REQUEST_UPDATE, >flags);
> + }

There is no code to clear BIT_REQUEST_UPDATE, is it right?

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


[PATCH] drm/exynos: use directly DMA mapping APIs on g2d

2016-04-22 Thread Joonyoung Shim
There is no reason to be wapper functions to use DMA mapping APIs. Use
directly DMA mapping APIs and remove the wapper functions.

Signed-off-by: Joonyoung Shim 
---
This is based on linux-next for 20160422.

 drivers/gpu/drm/exynos/exynos_drm_g2d.c | 10 +-
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 22 --
 drivers/gpu/drm/exynos/exynos_drm_gem.h | 10 --
 3 files changed, 5 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c 
b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index 193d3602dffb..493552368295 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -383,8 +383,8 @@ static void g2d_userptr_put_dma_addr(struct drm_device 
*drm_dev,
return;

 out:
-   exynos_gem_unmap_sgt_from_dma(drm_dev, g2d_userptr->sgt,
-   DMA_BIDIRECTIONAL);
+   dma_unmap_sg(to_dma_dev(drm_dev), g2d_userptr->sgt->sgl,
+   g2d_userptr->sgt->nents, DMA_BIDIRECTIONAL);

pages = frame_vector_pages(g2d_userptr->vec);
if (!IS_ERR(pages)) {
@@ -501,10 +501,10 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct 
drm_device *drm_dev,

g2d_userptr->sgt = sgt;

-   ret = exynos_gem_map_sgt_with_dma(drm_dev, g2d_userptr->sgt,
-   DMA_BIDIRECTIONAL);
-   if (ret < 0) {
+   if (!dma_map_sg(to_dma_dev(drm_dev), sgt->sgl, sgt->nents,
+   DMA_BIDIRECTIONAL)) {
DRM_ERROR("failed to map sgt with dma region.\n");
+   ret = -ENOMEM;
goto err_sg_free_table;
}

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 6fb98f4c3544..96bb40361b1c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -378,28 +378,6 @@ int exynos_drm_gem_get_ioctl(struct drm_device *dev, void 
*data,
return 0;
 }

-int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev,
-   struct sg_table *sgt,
-   enum dma_data_direction dir)
-{
-   int nents;
-
-   nents = dma_map_sg(to_dma_dev(drm_dev), sgt->sgl, sgt->nents, dir);
-   if (!nents) {
-   DRM_ERROR("failed to map sgl with dma.\n");
-   return nents;
-   }
-
-   return 0;
-}
-
-void exynos_gem_unmap_sgt_from_dma(struct drm_device *drm_dev,
-   struct sg_table *sgt,
-   enum dma_data_direction dir)
-{
-   dma_unmap_sg(to_dma_dev(drm_dev), sgt->sgl, sgt->nents, dir);
-}
-
 void exynos_drm_gem_free_object(struct drm_gem_object *obj)
 {
exynos_drm_gem_destroy(to_exynos_gem(obj));
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h 
b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 00223052b87b..c1df26877b76 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -121,16 +121,6 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, 
struct vm_fault *vmf);
 /* set vm_flags and we can change the vm attribute to other one at here. */
 int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);

-/* map sgt with dma region. */
-int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev,
-   struct sg_table *sgt,
-   enum dma_data_direction dir);
-
-/* unmap sgt from dma region. */
-void exynos_gem_unmap_sgt_from_dma(struct drm_device *drm_dev,
-   struct sg_table *sgt,
-   enum dma_data_direction dir);
-
 /* low-level interface prime helpers */
 struct sg_table *exynos_drm_gem_prime_get_sg_table(struct drm_gem_object *obj);
 struct drm_gem_object *
-- 
1.9.1



[PATCH 2/2] drm/exynos: fix imported dma-buf to be mapped

2016-04-22 Thread Joonyoung Shim
The imported dma-buf should be mapped by sub-system exporting it.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 9f688c28fa8e..6c83884f1fe6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -547,6 +547,9 @@ int exynos_drm_gem_mmap(struct file *filp, struct 
vm_area_struct *vma)

obj = vma->vm_private_data;

+   if (obj->import_attach)
+   return dma_buf_mmap(obj->dma_buf, vma, 0);
+
return exynos_drm_gem_mmap_obj(obj, vma);
 }

-- 
1.9.1



[PATCH 1/2] drm/exynos: support gem_prime_mmap

2016-04-22 Thread Joonyoung Shim
This allows exported dma-bufs to be mapped using gem_prime_mmap.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_drv.c |  1 +
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 45 +++--
 drivers/gpu/drm/exynos/exynos_drm_gem.h |  2 ++
 3 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 5344940c8a07..94d0d785fac2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -431,6 +431,7 @@ static struct drm_driver exynos_drm_driver = {
.gem_prime_import_sg_table  = exynos_drm_gem_prime_import_sg_table,
.gem_prime_vmap = exynos_drm_gem_prime_vmap,
.gem_prime_vunmap   = exynos_drm_gem_prime_vunmap,
+   .gem_prime_mmap = exynos_drm_gem_prime_mmap,
.ioctls = exynos_ioctls,
.num_ioctls = ARRAY_SIZE(exynos_ioctls),
.fops   = _drm_driver_fops,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 6fb98f4c3544..9f688c28fa8e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -503,22 +503,12 @@ out:
}
 }

-int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+static int exynos_drm_gem_mmap_obj(struct drm_gem_object *obj,
+  struct vm_area_struct *vma)
 {
-   struct exynos_drm_gem *exynos_gem;
-   struct drm_gem_object *obj;
+   struct exynos_drm_gem *exynos_gem = to_exynos_gem(obj);
int ret;

-   /* set vm_area_struct. */
-   ret = drm_gem_mmap(filp, vma);
-   if (ret < 0) {
-   DRM_ERROR("failed to mmap.\n");
-   return ret;
-   }
-
-   obj = vma->vm_private_data;
-   exynos_gem = to_exynos_gem(obj);
-
DRM_DEBUG_KMS("flags = 0x%x\n", exynos_gem->flags);

/* non-cachable as default. */
@@ -543,6 +533,23 @@ err_close_vm:
return ret;
 }

+int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+   struct drm_gem_object *obj;
+   int ret;
+
+   /* set vm_area_struct. */
+   ret = drm_gem_mmap(filp, vma);
+   if (ret < 0) {
+   DRM_ERROR("failed to mmap.\n");
+   return ret;
+   }
+
+   obj = vma->vm_private_data;
+
+   return exynos_drm_gem_mmap_obj(obj, vma);
+}
+
 /* low-level interface prime helpers */
 struct sg_table *exynos_drm_gem_prime_get_sg_table(struct drm_gem_object *obj)
 {
@@ -617,3 +624,15 @@ void exynos_drm_gem_prime_vunmap(struct drm_gem_object 
*obj, void *vaddr)
 {
/* Nothing to do */
 }
+
+int exynos_drm_gem_prime_mmap(struct drm_gem_object *obj,
+ struct vm_area_struct *vma)
+{
+   int ret;
+
+   ret = drm_gem_mmap_obj(obj, obj->size, vma);
+   if (ret < 0)
+   return ret;
+
+   return exynos_drm_gem_mmap_obj(obj, vma);
+}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h 
b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 00223052b87b..895125431227 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -139,5 +139,7 @@ exynos_drm_gem_prime_import_sg_table(struct drm_device *dev,
 struct sg_table *sgt);
 void *exynos_drm_gem_prime_vmap(struct drm_gem_object *obj);
 void exynos_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
+int exynos_drm_gem_prime_mmap(struct drm_gem_object *obj,
+ struct vm_area_struct *vma);

 #endif
-- 
1.9.1



[PATCH v3 5/7] drm/exynos: mixer: refactor layer setup

2015-12-18 Thread Joonyoung Shim
+Cc Boram Park,

On 12/18/2015 12:54 AM, Marek Szyprowski wrote:
> Hi Joonyoung,
> 
> On 2015-12-17 05:19, Joonyoung Shim wrote:
>> Hi Marek,
>>
>> On 12/16/2015 09:21 PM, Marek Szyprowski wrote:
>>> Properly configure blending properties of given hardware layer based on
>>> the selected pixel format. Currently only per-pixel-based alpha is possible
>>> when respective pixel format has been selected. Configuration of global,
>>> per-plane alpha value, color key and background color will be added later.
>>>
>>> This patch is heavily inspired by earlier work done by Tobias Jakobi
>>> .
>>>
>>> Signed-off-by: Marek Szyprowski 
>>> ---
>>>   drivers/gpu/drm/exynos/exynos_mixer.c | 43 
>>> +++
>>>   drivers/gpu/drm/exynos/regs-mixer.h   |  1 +
>>>   2 files changed, 44 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
>>> b/drivers/gpu/drm/exynos/exynos_mixer.c
>>> index c572e271579e..ae7b122274ac 100644
>>> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
>>> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
>>> @@ -165,6 +165,16 @@ static const u8 filter_cr_horiz_tap4[] = {
>>>   70,59,48,37,27,19,11,5,
>>>   };
>>>   +static inline bool is_alpha_format(unsigned int pixel_format)
>>> +{
>>> +switch (pixel_format) {
>>> +case DRM_FORMAT_ARGB:
>>> +return true;
>>> +default:
>>> +return false;
>>> +}
>>> +}
>>> +
>>>   static inline u32 vp_reg_read(struct mixer_resources *res, u32 reg_id)
>>>   {
>>>   return readl(res->vp_regs + reg_id);
>>> @@ -294,6 +304,37 @@ static void vp_default_filter(struct mixer_resources 
>>> *res)
>>>   filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4));
>>>   }
>>>   +static void mixer_cfg_gfx_blend(struct mixer_context *ctx, unsigned int 
>>> win,
>>> +bool alpha)
>>> +{
>>> +struct mixer_resources *res = >mixer_res;
>>> +u32 val;
>>> +
>>> +val  = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */
>>> +if (alpha) {
>>> +/* blending based on pixel alpha */
>>> +val |= MXR_GRP_CFG_BLEND_PRE_MUL;
>>> +val |= MXR_GRP_CFG_PIXEL_BLEND_EN;
>>> +}
>>> +mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win),
>>> +val, MXR_GRP_CFG_MISC_MASK);
>> I think the priority of plane and whether vp layer exists should be
>> considered for blending setting. When priority of graphic layer0 is
>> lowest and vp layer is not, this will blend background layer.
>> It was not permitted to blend background layer until current.
> 
> Currently blending is hardcoded to following configuration:
> 1. Order: [top] Grp1 > Grp0 > Video [bottom]
> 2. Per-pixel alpha blending enabled unconditionally for Grp1 layer (regardless
>of the selected pixel format for Grp1 layer).
> 3. Per-pixel alpha blending enabled for Grp0 layer when Video layer gets 
> enabled
>(regardless of the selected pixel format for Grp0 layer).
> 
> It is not very intuitive and it looks hardcoded for one particular use case.
> With the above patch application can configure blending for its needs.
> 

Sure, i'm not to oppose this patch.

> I really see no reason for special handling of the bottom layer (like
> disabling per-pixel alpha even if alpha-enabled format is selected). It is
> role of application to set proper pixel format (like XRGB instead of
> ARGB) if the application is not interested in alpha blending. Per-pixel
> alpha blending is enabled only for formats which really support alpha.
> 

You mean this is role of application definitely, then it's reasonable to
me.

Thanks.


[PATCH v3 2/7] drm/exynos: make zpos property configurable

2015-12-18 Thread Joonyoung Shim
On 12/17/2015 10:05 PM, Marek Szyprowski wrote:
> Hello,
> 
> On 2015-12-17 03:55, Joonyoung Shim wrote:
>> +Cc: Boram Park,
>>
>> Hi Marek,
>>
>> On 12/16/2015 09:21 PM, Marek Szyprowski wrote:
>>> This patch adds all infrastructure to make zpos plane property
>>> configurable from userspace.
>>>
>>> Signed-off-by: Marek Szyprowski 
>>> ---
>>>   drivers/gpu/drm/exynos/exynos_drm_drv.h   |  4 ++-
>>>   drivers/gpu/drm/exynos/exynos_drm_plane.c | 51 
>>> ---
>>>   2 files changed, 49 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
>>> b/drivers/gpu/drm/exynos/exynos_drm_drv.h
>>> index 588b6763f9c7..f0827dbebb7d 100644
>>> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
>>> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
>>> @@ -64,6 +64,7 @@ struct exynos_drm_plane_state {
>>>   struct exynos_drm_rect src;
>>>   unsigned int h_ratio;
>>>   unsigned int v_ratio;
>>> +unsigned int zpos;
>>>   };
>>> static inline struct exynos_drm_plane_state *
>>> @@ -91,11 +92,12 @@ struct exynos_drm_plane {
>>> #define EXYNOS_DRM_PLANE_CAP_DOUBLE(1 << 0)
>>>   #define EXYNOS_DRM_PLANE_CAP_SCALE(1 << 1)
>>> +#define EXYNOS_DRM_PLANE_CAP_ZPOS(1 << 2)
>>> /*
>>>* Exynos DRM plane configuration structure.
>>>*
>>> - * @zpos: z-position of the plane.
>>> + * @zpos: initial z-position of the plane.
>>>* @type: type of the plane (primary, cursor or overlay).
>>>* @pixel_formats: supported pixel formats.
>>>* @num_pixel_formats: number of elements in 'pixel_formats'.
>>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c 
>>> b/drivers/gpu/drm/exynos/exynos_drm_plane.c
>>> index fd6cb4cee01a..a2bdab836b50 100644
>>> --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
>>> +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
>>> @@ -124,6 +124,7 @@ static void exynos_plane_mode_set(struct 
>>> exynos_drm_plane_state *exynos_state)
>>> static void exynos_drm_plane_reset(struct drm_plane *plane)
>>>   {
>>> +struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
>>>   struct exynos_drm_plane_state *exynos_state;
>>> if (plane->state) {
>>> @@ -136,6 +137,7 @@ static void exynos_drm_plane_reset(struct drm_plane 
>>> *plane)
>>> exynos_state = kzalloc(sizeof(*exynos_state), GFP_KERNEL);
>>>   if (exynos_state) {
>>> +exynos_state->zpos = exynos_plane->config->zpos;
>>>   plane->state = _state->base;
>>>   plane->state->plane = plane;
>>>   }
>>> @@ -153,6 +155,7 @@ exynos_drm_plane_duplicate_state(struct drm_plane 
>>> *plane)
>>>   return NULL;
>>> __drm_atomic_helper_plane_duplicate_state(plane, >base);
>>> +copy->zpos = exynos_state->zpos;
>>>   return >base;
>>>   }
>>>   @@ -165,13 +168,53 @@ static void exynos_drm_plane_destroy_state(struct 
>>> drm_plane *plane,
>>>   kfree(old_exynos_state);
>>>   }
>>>   +static int exynos_drm_plane_atomic_set_property(struct drm_plane *plane,
>>> +struct drm_plane_state *state,
>>> +struct drm_property *property,
>>> +uint64_t val)
>>> +{
>>> +struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
>>> +struct exynos_drm_plane_state *exynos_state =
>>> +to_exynos_plane_state(state);
>>> +struct exynos_drm_private *dev_priv = plane->dev->dev_private;
>>> +const struct exynos_drm_plane_config *config = exynos_plane->config;
>>> +
>>> +if (property == dev_priv->plane_zpos_property &&
>>> +(config->capabilities & EXYNOS_DRM_PLANE_CAP_ZPOS))
>>> +exynos_state->zpos = val;
>>> +else
>>> +return -EINVAL;
>>> +
>>> +return 0;
>>> +}
>>> +
>>> +static int exynos_drm_plane_atomic_get_property(struct drm_plane *plane,
>>> +  const struct drm_plane_state *state,
>>> +  struct drm_property *property,
>>> +  uint64_t *val)
>>> +{
>&g

[PATCH v3 5/7] drm/exynos: mixer: refactor layer setup

2015-12-17 Thread Joonyoung Shim
Hi Marek,

On 12/16/2015 09:21 PM, Marek Szyprowski wrote:
> Properly configure blending properties of given hardware layer based on
> the selected pixel format. Currently only per-pixel-based alpha is possible
> when respective pixel format has been selected. Configuration of global,
> per-plane alpha value, color key and background color will be added later.
> 
> This patch is heavily inspired by earlier work done by Tobias Jakobi
> .
> 
> Signed-off-by: Marek Szyprowski 
> ---
>  drivers/gpu/drm/exynos/exynos_mixer.c | 43 
> +++
>  drivers/gpu/drm/exynos/regs-mixer.h   |  1 +
>  2 files changed, 44 insertions(+)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
> b/drivers/gpu/drm/exynos/exynos_mixer.c
> index c572e271579e..ae7b122274ac 100644
> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
> @@ -165,6 +165,16 @@ static const u8 filter_cr_horiz_tap4[] = {
>   70, 59, 48, 37, 27, 19, 11, 5,
>  };
>  
> +static inline bool is_alpha_format(unsigned int pixel_format)
> +{
> + switch (pixel_format) {
> + case DRM_FORMAT_ARGB:
> + return true;
> + default:
> + return false;
> + }
> +}
> +
>  static inline u32 vp_reg_read(struct mixer_resources *res, u32 reg_id)
>  {
>   return readl(res->vp_regs + reg_id);
> @@ -294,6 +304,37 @@ static void vp_default_filter(struct mixer_resources 
> *res)
>   filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4));
>  }
>  
> +static void mixer_cfg_gfx_blend(struct mixer_context *ctx, unsigned int win,
> + bool alpha)
> +{
> + struct mixer_resources *res = >mixer_res;
> + u32 val;
> +
> + val  = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */
> + if (alpha) {
> + /* blending based on pixel alpha */
> + val |= MXR_GRP_CFG_BLEND_PRE_MUL;
> + val |= MXR_GRP_CFG_PIXEL_BLEND_EN;
> + }
> + mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win),
> + val, MXR_GRP_CFG_MISC_MASK);

I think the priority of plane and whether vp layer exists should be
considered for blending setting. When priority of graphic layer0 is 
lowest and vp layer is not, this will blend background layer. 
It was not permitted to blend background layer until current.

Thanks.

> +}
> +
> +static void mixer_cfg_vp_blend(struct mixer_context *ctx)
> +{
> + struct mixer_resources *res = >mixer_res;
> + u32 val;
> +
> + /*
> +  * No blending at the moment since the NV12/NV21 pixelformats don't
> +  * have an alpha channel. However the mixer supports a global alpha
> +  * value for a layer. Once this functionality is exposed, we can
> +  * support blending of the video layer through this.
> +  */
> + val = 0;
> + mixer_reg_write(res, MXR_VIDEO_CFG, val);
> +}
> +
>  static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable)
>  {
>   struct mixer_resources *res = >mixer_res;
> @@ -519,6 +560,7 @@ static void vp_video_buffer(struct mixer_context *ctx,
>   mixer_cfg_scan(ctx, mode->vdisplay);
>   mixer_cfg_rgb_fmt(ctx, mode->vdisplay);
>   mixer_cfg_layer(ctx, plane->index, state->zpos + 1, true);
> + mixer_cfg_vp_blend(ctx);
>   mixer_run(ctx);
>  
>   mixer_vsync_set_update(ctx, true);
> @@ -634,6 +676,7 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
>   mixer_cfg_scan(ctx, mode->vdisplay);
>   mixer_cfg_rgb_fmt(ctx, mode->vdisplay);
>   mixer_cfg_layer(ctx, win, state->zpos + 1, true);
> + mixer_cfg_gfx_blend(ctx, win, is_alpha_format(fb->pixel_format));
>  
>   /* layer update mandatory for mixer 16.0.33.0 */
>   if (ctx->mxr_ver == MXR_VER_16_0_33_0 ||
> diff --git a/drivers/gpu/drm/exynos/regs-mixer.h 
> b/drivers/gpu/drm/exynos/regs-mixer.h
> index dbdbc0af3358..7f22df5bf707 100644
> --- a/drivers/gpu/drm/exynos/regs-mixer.h
> +++ b/drivers/gpu/drm/exynos/regs-mixer.h
> @@ -113,6 +113,7 @@
>  #define MXR_GRP_CFG_BLEND_PRE_MUL(1 << 20)
>  #define MXR_GRP_CFG_WIN_BLEND_EN (1 << 17)
>  #define MXR_GRP_CFG_PIXEL_BLEND_EN   (1 << 16)
> +#define MXR_GRP_CFG_MISC_MASK((3 << 16) | (3 << 20))
>  #define MXR_GRP_CFG_FORMAT_VAL(x)MXR_MASK_VAL(x, 11, 8)
>  #define MXR_GRP_CFG_FORMAT_MASK  MXR_GRP_CFG_FORMAT_VAL(~0)
>  #define MXR_GRP_CFG_ALPHA_VAL(x) MXR_MASK_VAL(x, 7, 0)
> 



[PATCH v3 2/7] drm/exynos: make zpos property configurable

2015-12-17 Thread Joonyoung Shim
+Cc: Boram Park,

Hi Marek,

On 12/16/2015 09:21 PM, Marek Szyprowski wrote:
> This patch adds all infrastructure to make zpos plane property
> configurable from userspace.
> 
> Signed-off-by: Marek Szyprowski 
> ---
>  drivers/gpu/drm/exynos/exynos_drm_drv.h   |  4 ++-
>  drivers/gpu/drm/exynos/exynos_drm_plane.c | 51 
> ---
>  2 files changed, 49 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
> b/drivers/gpu/drm/exynos/exynos_drm_drv.h
> index 588b6763f9c7..f0827dbebb7d 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
> @@ -64,6 +64,7 @@ struct exynos_drm_plane_state {
>   struct exynos_drm_rect src;
>   unsigned int h_ratio;
>   unsigned int v_ratio;
> + unsigned int zpos;
>  };
>  
>  static inline struct exynos_drm_plane_state *
> @@ -91,11 +92,12 @@ struct exynos_drm_plane {
>  
>  #define EXYNOS_DRM_PLANE_CAP_DOUBLE  (1 << 0)
>  #define EXYNOS_DRM_PLANE_CAP_SCALE   (1 << 1)
> +#define EXYNOS_DRM_PLANE_CAP_ZPOS(1 << 2)
>  
>  /*
>   * Exynos DRM plane configuration structure.
>   *
> - * @zpos: z-position of the plane.
> + * @zpos: initial z-position of the plane.
>   * @type: type of the plane (primary, cursor or overlay).
>   * @pixel_formats: supported pixel formats.
>   * @num_pixel_formats: number of elements in 'pixel_formats'.
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c 
> b/drivers/gpu/drm/exynos/exynos_drm_plane.c
> index fd6cb4cee01a..a2bdab836b50 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
> @@ -124,6 +124,7 @@ static void exynos_plane_mode_set(struct 
> exynos_drm_plane_state *exynos_state)
>  
>  static void exynos_drm_plane_reset(struct drm_plane *plane)
>  {
> + struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
>   struct exynos_drm_plane_state *exynos_state;
>  
>   if (plane->state) {
> @@ -136,6 +137,7 @@ static void exynos_drm_plane_reset(struct drm_plane 
> *plane)
>  
>   exynos_state = kzalloc(sizeof(*exynos_state), GFP_KERNEL);
>   if (exynos_state) {
> + exynos_state->zpos = exynos_plane->config->zpos;
>   plane->state = _state->base;
>   plane->state->plane = plane;
>   }
> @@ -153,6 +155,7 @@ exynos_drm_plane_duplicate_state(struct drm_plane *plane)
>   return NULL;
>  
>   __drm_atomic_helper_plane_duplicate_state(plane, >base);
> + copy->zpos = exynos_state->zpos;
>   return >base;
>  }
>  
> @@ -165,13 +168,53 @@ static void exynos_drm_plane_destroy_state(struct 
> drm_plane *plane,
>   kfree(old_exynos_state);
>  }
>  
> +static int exynos_drm_plane_atomic_set_property(struct drm_plane *plane,
> + struct drm_plane_state *state,
> + struct drm_property *property,
> + uint64_t val)
> +{
> + struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
> + struct exynos_drm_plane_state *exynos_state =
> + to_exynos_plane_state(state);
> + struct exynos_drm_private *dev_priv = plane->dev->dev_private;
> + const struct exynos_drm_plane_config *config = exynos_plane->config;
> +
> + if (property == dev_priv->plane_zpos_property &&
> + (config->capabilities & EXYNOS_DRM_PLANE_CAP_ZPOS))
> + exynos_state->zpos = val;
> + else
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +static int exynos_drm_plane_atomic_get_property(struct drm_plane *plane,
> +   const struct drm_plane_state *state,
> +   struct drm_property *property,
> +   uint64_t *val)
> +{
> + const struct exynos_drm_plane_state *exynos_state =
> + container_of(state, const struct exynos_drm_plane_state, base);
> + struct exynos_drm_private *dev_priv = plane->dev->dev_private;
> +
> + if (property == dev_priv->plane_zpos_property)
> + *val = exynos_state->zpos;
> + else
> + return -EINVAL;
> +
> + return 0;
> +}
> +
>  static struct drm_plane_funcs exynos_plane_funcs = {
>   .update_plane   = drm_atomic_helper_update_plane,
>   .disable_plane  = drm_atomic_helper_disable_plane,
>   .destroy= drm_plane_cleanup,
> + .set_property   = drm_atomic_helper_plane_set_property,
>   .reset  = exynos_drm_plane_reset,
>   .atomic_duplicate_state = exynos_drm_plane_duplicate_state,
>   .atomic_destroy_state = exynos_drm_plane_destroy_state,
> + .atomic_set_property = exynos_drm_plane_atomic_set_property,
> + .atomic_get_property = exynos_drm_plane_atomic_get_property,
>  };
>  
>  static int
> @@ -267,8 +310,8 @@ static void exynos_plane_attach_zpos_property(struct 
> 

drm/exynos: when to call dma_map_sg() on a GEM object?

2015-11-02 Thread Joonyoung Shim
On 10/31/2015 05:44 AM, Tobias Jakobi wrote:
> Hey there,
> 
> this question arose during some discussion with someone concerning the
> Exynos mixer and G2D.
> 
> The question is the following. Consider the Exynos mixer when run under
> the IOMMU (that's sysmmu_tv IIRC). What exactly does setup the IOMMU
> mapping so that the mixer can scanout the framebuffer?
> 

IOMMU mapping is in dma_alloc_attrs(). Already IOMMU was integrated in
the DMA mapping API on ARM arch.

> There is exynos_gem_map_sgt_with_dma() in the Exynos GEM code, but it's
> currently exclusively used for the G2D and only when dealing with
> userptr (and not GEM) there.
> 
> I was looking at exynos_drm_alloc_buf() since this called when
> allocating a BO to be used as scanout.
> 
> I see dma_alloc_attrs() being called, which also sets the DMA address
> that is later used in the mixer code. But DMA_ATTR_NO_KERNEL_MAPPING is
> passed, so no mapping is done at this point.
> 

Did you read Documentation/DMA-attributes.txt document?
DMA_ATTR_NO_KERNEL_MAPPING is just to avoid creating a kernel virtual
mapping for the allocated buffer on ARM arch.

> Is the mapping done somewhere else, or is it simply not necessary here?
> 

What is the mapping you mean? As you know, the DMA address of the
memory gets from dma_alloc_attrs() and it can be used by device. There
is no reason to use dma_map_*().

Thanks.


[PATCH 6/9] drm/exynos: switch to new buffer allocation

2015-10-20 Thread Joonyoung Shim
On 10/19/2015 09:20 PM, Inki Dae wrote:
> Hi,
> 
> How about combining patch 5 and 6?
> 
> Patch 5 just introduces new internal API but these API aren't used anywhere 
> in patch 5.
> 

I split it to be easy to understand changes of codes on patch file. It's
no matter to me to combine them.

Anyway, because this patchset introduces new userspace interfaces and
there is no real userspace to use them yet, i'm not sure it's better
whether i keep going this patchset or without the patch to introduce new
userspace interfaces.

Thanks.


[PATCH 0/9] drm/exynos: update codes related with gem

2015-10-14 Thread Joonyoung Shim
On 10/13/2015 09:29 PM, Daniel Vetter wrote:
> On Tue, Oct 13, 2015 at 06:32:53PM +0900, Joonyoung Shim wrote:
>> On 10/13/2015 05:37 PM, Joonyoung Shim wrote:
>>> On 10/13/2015 05:27 PM, Daniel Vetter wrote:
>>>> On Tue, Oct 13, 2015 at 04:00:45PM +0900, Joonyoung Shim wrote:
>>>>> Hi,
>>>>>
>>>>> This patchset is about gem codes update of exynos-drm.
>>>>>
>>>>> The first and second patches are cleanup to remove useless codes.
>>>>> The rest is to support cachable gem allocation.
>>>>>
>>>>> The exynos-drm uses DMA mapping API to allocate/mmap buffer of gem. If
>>>>> it is cachable, does it with DMA_ATTR_NON_CONSISTENT attribute, but
>>>>> DMA_ATTR_NON_CONSISTENT isn't supported in DMA mapping API of ARM, so it
>>>>> doesn't give any effects.
>>>>>
>>>>> This patchset introduces new buffer allocation to use
>>>>> drm_gem_get/put_pages() instead of DMA mapping API. It will be used
>>>>> for the rest except allocation of physically continuous buffer on
>>>>> non-iommu, then exynos-drm can support cachable buffer of gem. Also it
>>>>> can support physically non-continuous buffer on non-iommu.
>>>>>
>>>>> EXYNOS_BO_CONTIG flag on iommu is ambiguous because it doesn't care
>>>>> whether buffer is continuous physically if iommu is supported. This
>>>>> patchset always will use EXYNOS_BO_CONTIG flag on iommu and then can
>>>>> mean that the buffer is continuous for device.
>>>>>
>>>>> There is no user API to control cache coherence for the cpu and device
>>>>> about cachable buffer. This patchset introduces two ioctls for cpu
>>>>> access of gem object from user. It will be synced properly in order for
>>>>> the cpu and device if buffer of gem object is cachable.
>>>>
>>>> Out of curiosity, where's the userspace part for this work? Usually kernel
>>>> abi extensions come with a link to the relevant branch for easier review.
>>>> -Daniel
>>>>
>>>
>>> Right, thanks for point.
>>>
>>> I just modified a little bit exynos_fimg2d_test and exynos parts of
>>> libdrm to test them as workaround. I will expose it.
>>>
>>
>> Please refer follows.
>> https://github.com/dofmind/libdrm/commits/exynos
>>
>> If fimd2d test program uses cachable gem, it will show cache coherency
>> problem, so it adds to use new ioctls to keep cache coherency.
> 
> Is there some real userspace too, not just a test/demo app?

Unfortunately not yet, i hope it can be used on real userspace.

Thanks.


[PATCH] drm/exynos/gem: remove DMA-mapping hacks used for constructing page array

2015-10-13 Thread Joonyoung Shim
Hi Marek,

On 10/13/2015 07:22 PM, Marek Szyprowski wrote:
> Exynos GEM objects contains an array of pointers to the pages, which the
> allocated buffer consists of. Till now the code used some hacks (like
> relying on DMA-mapping internal structures or using ARM-specific
> dma_to_pfn helper) to build this array. This patch fixes this by adding
> proper call to dma_get_sgtable_attrs() and using the acquired scatter-list
> to construct needed array. This approach is more portable (work also for
> ARM64) and finally fixes the layering violation that was present in this
> code.

I also sent related patches to update codes of Exynos GEM object and i
think this can be applied easily on my patchset or i will be able to
rebase my patchset on your patch.

> 
> Signed-off-by: Marek Szyprowski 
> ---
> Patch is based on exynos-drm-next branch.
> ---
>  drivers/gpu/drm/exynos/exynos_drm_gem.c | 60 
> +++--
>  1 file changed, 35 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
> b/drivers/gpu/drm/exynos/exynos_drm_gem.c
> index 29f48756e72f..e998a64a3dd0 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
> @@ -25,6 +25,10 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem 
> *exynos_gem)
>   struct drm_device *dev = exynos_gem->base.dev;
>   enum dma_attr attr;
>   unsigned int nr_pages;
> + struct sg_table sgt;
> + struct scatterlist *s;
> + int ret = -ENOMEM;
> + int i, j;
>  
>   if (exynos_gem->dma_addr) {
>   DRM_DEBUG_KMS("already allocated.\n");
> @@ -56,13 +60,10 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem 
> *exynos_gem)
>  
>   nr_pages = exynos_gem->size >> PAGE_SHIFT;
>  
> - if (!is_drm_iommu_supported(dev)) {
> - exynos_gem->pages = drm_calloc_large(nr_pages,
> -  sizeof(struct page *));
> - if (!exynos_gem->pages) {
> - DRM_ERROR("failed to allocate pages.\n");
> - return -ENOMEM;
> - }
> + exynos_gem->pages = drm_calloc_large(nr_pages, sizeof(struct page *));
> + if (!exynos_gem->pages) {
> + DRM_ERROR("failed to allocate pages.\n");
> + return -ENOMEM;
>   }
>  
>   exynos_gem->cookie = dma_alloc_attrs(dev->dev, exynos_gem->size,
> @@ -70,30 +71,40 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem 
> *exynos_gem)
>_gem->dma_attrs);
>   if (!exynos_gem->cookie) {
>   DRM_ERROR("failed to allocate buffer.\n");
> - if (exynos_gem->pages)
> - drm_free_large(exynos_gem->pages);
> - return -ENOMEM;
> + goto err_free;
>   }
>  
> - if (exynos_gem->pages) {
> - dma_addr_t start_addr;
> - unsigned int i = 0;
> -
> - start_addr = exynos_gem->dma_addr;
> - while (i < nr_pages) {
> - exynos_gem->pages[i] =
> - pfn_to_page(dma_to_pfn(dev->dev, start_addr));
> - start_addr += PAGE_SIZE;
> - i++;
> - }
> - } else {
> - exynos_gem->pages = exynos_gem->cookie;
> + ret = dma_get_sgtable_attrs(dev->dev, , exynos_gem->cookie,
> + exynos_gem->dma_addr, exynos_gem->size,
> + _gem->dma_attrs);
> + if (ret < 0) {
> + DRM_ERROR("failed to get sgtable.\n");
> + goto err_dma_free;
> + }
> +
> + j = 0;
> + for_each_sg(sgt.sgl, s, sgt.orig_nents, i) {
> + int size = s->length >> PAGE_SHIFT;
> + struct page *page = sg_page(s);
> +
> + while (size-- > 0)
> + exynos_gem->pages[j++] = page++;
>   }

drm_prime_sg_to_page_addr_arrays() will do same operation.

Thanks.


[PATCH 0/9] drm/exynos: update codes related with gem

2015-10-13 Thread Joonyoung Shim
On 10/13/2015 05:37 PM, Joonyoung Shim wrote:
> On 10/13/2015 05:27 PM, Daniel Vetter wrote:
>> On Tue, Oct 13, 2015 at 04:00:45PM +0900, Joonyoung Shim wrote:
>>> Hi,
>>>
>>> This patchset is about gem codes update of exynos-drm.
>>>
>>> The first and second patches are cleanup to remove useless codes.
>>> The rest is to support cachable gem allocation.
>>>
>>> The exynos-drm uses DMA mapping API to allocate/mmap buffer of gem. If
>>> it is cachable, does it with DMA_ATTR_NON_CONSISTENT attribute, but
>>> DMA_ATTR_NON_CONSISTENT isn't supported in DMA mapping API of ARM, so it
>>> doesn't give any effects.
>>>
>>> This patchset introduces new buffer allocation to use
>>> drm_gem_get/put_pages() instead of DMA mapping API. It will be used
>>> for the rest except allocation of physically continuous buffer on
>>> non-iommu, then exynos-drm can support cachable buffer of gem. Also it
>>> can support physically non-continuous buffer on non-iommu.
>>>
>>> EXYNOS_BO_CONTIG flag on iommu is ambiguous because it doesn't care
>>> whether buffer is continuous physically if iommu is supported. This
>>> patchset always will use EXYNOS_BO_CONTIG flag on iommu and then can
>>> mean that the buffer is continuous for device.
>>>
>>> There is no user API to control cache coherence for the cpu and device
>>> about cachable buffer. This patchset introduces two ioctls for cpu
>>> access of gem object from user. It will be synced properly in order for
>>> the cpu and device if buffer of gem object is cachable.
>>
>> Out of curiosity, where's the userspace part for this work? Usually kernel
>> abi extensions come with a link to the relevant branch for easier review.
>> -Daniel
>>
> 
> Right, thanks for point.
> 
> I just modified a little bit exynos_fimg2d_test and exynos parts of
> libdrm to test them as workaround. I will expose it.
> 

Please refer follows.
https://github.com/dofmind/libdrm/commits/exynos

If fimd2d test program uses cachable gem, it will show cache coherency
problem, so it adds to use new ioctls to keep cache coherency.

Thanks.

> Thanks.
> 
>>>
>>> Thanks.
>>>
>>> Joonyoung Shim (9):
>>>   drm/exynos: eliminate useless codes of exynos_drm_gem.h
>>>   drm/exynos: use directly DMA mapping APIs on g2d
>>>   drm/exynos: remove using non-consistent DMA attribute
>>>   drm/exynos: split buffer allocation using DMA mapping API on non-iommu
>>>   drm/exynos: introduce buffer allocation using drm_gem_get/put_pages()
>>>   drm/exynos: switch to new buffer allocation
>>>   drm/exynos: always use EXYNOS_BO_CONTIG flag on iommu
>>>   drm/exynos: use DMA_ERROR_CODE
>>>   drm/exynos: add ioctls for cpu access of gem object from user
>>>
>>>  drivers/gpu/drm/exynos/exynos_drm_drv.c   |   4 +
>>>  drivers/gpu/drm/exynos/exynos_drm_fb.c|  32 +---
>>>  drivers/gpu/drm/exynos/exynos_drm_fbdev.c |  14 +-
>>>  drivers/gpu/drm/exynos/exynos_drm_g2d.c   |  10 +-
>>>  drivers/gpu/drm/exynos/exynos_drm_gem.c   | 288 
>>> ++
>>>  drivers/gpu/drm/exynos/exynos_drm_gem.h   |  56 ++
>>>  include/uapi/drm/exynos_drm.h |  23 ++-
>>>  7 files changed, 225 insertions(+), 202 deletions(-)
>>>
>>> -- 
>>> 1.9.1
>>>
>>> ___
>>> dri-devel mailing list
>>> dri-devel at lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>>
> 
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
> 



[PATCH 0/9] drm/exynos: update codes related with gem

2015-10-13 Thread Joonyoung Shim
On 10/13/2015 05:27 PM, Daniel Vetter wrote:
> On Tue, Oct 13, 2015 at 04:00:45PM +0900, Joonyoung Shim wrote:
>> Hi,
>>
>> This patchset is about gem codes update of exynos-drm.
>>
>> The first and second patches are cleanup to remove useless codes.
>> The rest is to support cachable gem allocation.
>>
>> The exynos-drm uses DMA mapping API to allocate/mmap buffer of gem. If
>> it is cachable, does it with DMA_ATTR_NON_CONSISTENT attribute, but
>> DMA_ATTR_NON_CONSISTENT isn't supported in DMA mapping API of ARM, so it
>> doesn't give any effects.
>>
>> This patchset introduces new buffer allocation to use
>> drm_gem_get/put_pages() instead of DMA mapping API. It will be used
>> for the rest except allocation of physically continuous buffer on
>> non-iommu, then exynos-drm can support cachable buffer of gem. Also it
>> can support physically non-continuous buffer on non-iommu.
>>
>> EXYNOS_BO_CONTIG flag on iommu is ambiguous because it doesn't care
>> whether buffer is continuous physically if iommu is supported. This
>> patchset always will use EXYNOS_BO_CONTIG flag on iommu and then can
>> mean that the buffer is continuous for device.
>>
>> There is no user API to control cache coherence for the cpu and device
>> about cachable buffer. This patchset introduces two ioctls for cpu
>> access of gem object from user. It will be synced properly in order for
>> the cpu and device if buffer of gem object is cachable.
> 
> Out of curiosity, where's the userspace part for this work? Usually kernel
> abi extensions come with a link to the relevant branch for easier review.
> -Daniel
> 

Right, thanks for point.

I just modified a little bit exynos_fimg2d_test and exynos parts of
libdrm to test them as workaround. I will expose it.

Thanks.

>>
>> Thanks.
>>
>> Joonyoung Shim (9):
>>   drm/exynos: eliminate useless codes of exynos_drm_gem.h
>>   drm/exynos: use directly DMA mapping APIs on g2d
>>   drm/exynos: remove using non-consistent DMA attribute
>>   drm/exynos: split buffer allocation using DMA mapping API on non-iommu
>>   drm/exynos: introduce buffer allocation using drm_gem_get/put_pages()
>>   drm/exynos: switch to new buffer allocation
>>   drm/exynos: always use EXYNOS_BO_CONTIG flag on iommu
>>   drm/exynos: use DMA_ERROR_CODE
>>   drm/exynos: add ioctls for cpu access of gem object from user
>>
>>  drivers/gpu/drm/exynos/exynos_drm_drv.c   |   4 +
>>  drivers/gpu/drm/exynos/exynos_drm_fb.c|  32 +---
>>  drivers/gpu/drm/exynos/exynos_drm_fbdev.c |  14 +-
>>  drivers/gpu/drm/exynos/exynos_drm_g2d.c   |  10 +-
>>  drivers/gpu/drm/exynos/exynos_drm_gem.c   | 288 
>> ++
>>  drivers/gpu/drm/exynos/exynos_drm_gem.h   |  56 ++
>>  include/uapi/drm/exynos_drm.h |  23 ++-
>>  7 files changed, 225 insertions(+), 202 deletions(-)
>>
>> -- 
>> 1.9.1
>>
>> ___
>> dri-devel mailing list
>> dri-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
> 



[PATCH 9/9] drm/exynos: add ioctls for cpu access of gem object from user

2015-10-13 Thread Joonyoung Shim
This adds necessary two ioctls for cpu access of gem object from user.
It needs to be synced properly in order for the cpu and device if the
buffer of gem object is cachable.

- DRM_IOCTL_EXYNOS_GEM_CPU_PREP
Should be used explicitly before it will be cpu access of gem object
from user.

- DRM_IOCTL_EXYNOS_GEM_CPU_FINI
Should be used explicitly after it is finished cpu access of gem object
from user.

Signed-off-by: Joonyoung Shim 
---
This is based on patch of Daniel dropping DRM_UNLOCKED flag on each
drivers[1] and patch that is droped DRM_UNLOCKED flag from my posted
patch[2].

[1] http://lists.freedesktop.org/archives/intel-gfx/2015-September/075368.html
[2] http://www.spinics.net/lists/dri-devel/msg91465.html

 drivers/gpu/drm/exynos/exynos_drm_drv.c |  4 +++
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 48 +
 drivers/gpu/drm/exynos/exynos_drm_gem.h | 14 ++
 include/uapi/drm/exynos_drm.h   | 18 -
 4 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 74bf3afed519..f15945c1c01d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -408,6 +408,10 @@ static const struct drm_ioctl_desc exynos_ioctls[] = {
DRM_AUTH | DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MAP, exynos_drm_gem_map_ioctl,
DRM_AUTH | DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CPU_PREP, exynos_drm_gem_cpu_prep_ioctl,
+   DRM_AUTH | DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CPU_FINI, exynos_drm_gem_cpu_fini_ioctl,
+   DRM_AUTH | DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(EXYNOS_GEM_GET, exynos_drm_gem_get_ioctl,
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION, vidi_connection_ioctl,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 01c5e0854016..4907ad3994db 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -321,6 +321,54 @@ int exynos_drm_gem_map_ioctl(struct drm_device *dev, void 
*data,
  >offset);
 }

+int exynos_drm_gem_cpu_prep_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+   struct drm_exynos_gem_cpu_access *args = data;
+   struct drm_gem_object *obj;
+   struct exynos_drm_gem *exynos_gem;
+
+   obj = drm_gem_object_lookup(dev, file, args->handle);
+   if (!obj) {
+   DRM_ERROR("Failed to lookup gem object\n");
+   return -EINVAL;
+   }
+
+   exynos_gem = to_exynos_gem(obj);
+
+   if (exynos_gem->flags & EXYNOS_BO_CACHABLE)
+   dma_sync_sg_for_cpu(dev->dev, exynos_gem->sgt->sgl,
+   exynos_gem->sgt->nents, DMA_FROM_DEVICE);
+
+   drm_gem_object_unreference_unlocked(obj);
+
+   return 0;
+}
+
+int exynos_drm_gem_cpu_fini_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+   struct drm_exynos_gem_cpu_access *args = data;
+   struct drm_gem_object *obj;
+   struct exynos_drm_gem *exynos_gem;
+
+   obj = drm_gem_object_lookup(dev, file, args->handle);
+   if (!obj) {
+   DRM_ERROR("Failed to lookup gem object\n");
+   return -EINVAL;
+   }
+
+   exynos_gem = to_exynos_gem(obj);
+
+   if (exynos_gem->flags & EXYNOS_BO_CACHABLE)
+   dma_sync_sg_for_device(dev->dev, exynos_gem->sgt->sgl,
+  exynos_gem->sgt->nents, DMA_TO_DEVICE);
+
+   drm_gem_object_unreference_unlocked(obj);
+
+   return 0;
+}
+
 dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
unsigned int gem_handle,
struct drm_file *filp)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h 
b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index e9eb5631f322..d5aac38f455a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -74,6 +74,20 @@ int exynos_drm_gem_map_ioctl(struct drm_device *dev, void 
*data,
 struct drm_file *file_priv);

 /*
+ * Should be used explicitly before it will be cpu access of gem object
+ * from user.
+ */
+int exynos_drm_gem_cpu_prep_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+/*
+ * Should be used explicitly after it is finished cpu access of gem
+ * object from user.
+ */
+int exynos_drm_gem_cpu_fini_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+/*
  * get 

[PATCH 8/9] drm/exynos: use DMA_ERROR_CODE

2015-10-13 Thread Joonyoung Shim
The dma_addr of gem will be DMA_ERROR_CODE if gem is created and
will keep DMA_ERROR_CODE if gem has EXYNOS_BO_NONCONTIG flag on
non-iommu.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 24 +---
 1 file changed, 9 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 96a69468283b..01c5e0854016 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -44,7 +44,9 @@ static int exynos_drm_get_pages(struct exynos_drm_gem 
*exynos_gem)
goto err;
}

-   exynos_gem->dma_addr = sg_dma_address(sgt->sgl);
+   if (is_drm_iommu_supported(dev))
+   exynos_gem->dma_addr = sg_dma_address(sgt->sgl);
+
exynos_gem->sgt = sgt;
exynos_gem->pages = pages;

@@ -127,11 +129,6 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem 
*exynos_gem)
struct drm_device *dev = exynos_gem->base.dev;
int ret;

-   if (exynos_gem->dma_addr) {
-   DRM_DEBUG_KMS("already allocated.\n");
-   return 0;
-   }
-
if (!is_drm_iommu_supported(dev)) {
if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
return exynos_drm_alloc_dma(exynos_gem);
@@ -150,11 +147,6 @@ static void exynos_drm_free_buf(struct exynos_drm_gem 
*exynos_gem)
 {
struct drm_device *dev = exynos_gem->base.dev;

-   if (!exynos_gem->dma_addr) {
-   DRM_DEBUG_KMS("dma_addr is invalid.\n");
-   return;
-   }
-
if (!is_drm_iommu_supported(dev)) {
if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
return exynos_drm_free_dma(exynos_gem);
@@ -256,6 +248,8 @@ static struct exynos_drm_gem *exynos_drm_gem_init(struct 
drm_device *dev,
return ERR_PTR(ret);
}

+   exynos_gem->dma_addr = DMA_ERROR_CODE;
+
DRM_DEBUG_KMS("created file object = 0x%x\n", (unsigned int)obj->filp);

return exynos_gem;
@@ -594,18 +588,18 @@ exynos_drm_gem_prime_import_sg_table(struct drm_device 
*dev,
return ERR_PTR(ret);
}

-   exynos_gem->dma_addr = sg_dma_address(sgt->sgl);
-
/*
 * Always physically continuous memory if sgt->nents is 1. It
 * doesn't care if IOMMU is supported but EXYNOS_BO_NONCONTIG
 * flag will be cleared. It will mean the memory is continuous
 * for device. EXYNOS_BO_NONCONTIG flag will be set if not both.
 */
-   if (sgt->nents == 1 || is_drm_iommu_supported(dev))
+   if (sgt->nents == 1 || is_drm_iommu_supported(dev)) {
exynos_gem->flags &= ~EXYNOS_BO_NONCONTIG;
-   else
+   exynos_gem->dma_addr = sg_dma_address(sgt->sgl);
+   } else {
exynos_gem->flags |= EXYNOS_BO_NONCONTIG;
+   }

npages = exynos_gem->size >> PAGE_SHIFT;
exynos_gem->pages = drm_malloc_ab(npages, sizeof(struct page *));
-- 
1.9.1



[PATCH 7/9] drm/exynos: always use EXYNOS_BO_CONTIG flag on iommu

2015-10-13 Thread Joonyoung Shim
It doesn't care whether memory is continuous physically if iommu is
supported but we will always use EXYNOS_BO_CONTIG flag on iommu, so it
can mean that the memory is continuous memory for device.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_fb.c| 32 ---
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 14 +-
 drivers/gpu/drm/exynos/exynos_drm_gem.c   | 31 ++
 drivers/gpu/drm/exynos/exynos_drm_gem.h   |  2 --
 include/uapi/drm/exynos_drm.h |  5 -
 5 files changed, 23 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c 
b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index fcea28bdbc42..8fbae903c7ed 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -39,32 +39,6 @@ struct exynos_drm_fb {
struct exynos_drm_gem   *exynos_gem[MAX_FB_BUFFER];
 };

-static int check_fb_gem_memory_type(struct drm_device *drm_dev,
-   struct exynos_drm_gem *exynos_gem)
-{
-   unsigned int flags;
-
-   /*
-* if exynos drm driver supports iommu then framebuffer can use
-* all the buffer types.
-*/
-   if (is_drm_iommu_supported(drm_dev))
-   return 0;
-
-   flags = exynos_gem->flags;
-
-   /*
-* without iommu support, not support physically non-continuous memory
-* for framebuffer.
-*/
-   if (IS_NONCONTIG_BUFFER(flags)) {
-   DRM_ERROR("cannot use this gem memory type for fb.\n");
-   return -EINVAL;
-   }
-
-   return 0;
-}
-
 static void exynos_drm_fb_destroy(struct drm_framebuffer *fb)
 {
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
@@ -130,9 +104,11 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
return ERR_PTR(-ENOMEM);

for (i = 0; i < count; i++) {
-   ret = check_fb_gem_memory_type(dev, exynos_gem[i]);
-   if (ret < 0)
+   /* Not support physically non-continuous memory for FB */
+   if (exynos_gem[i]->flags & EXYNOS_BO_NONCONTIG) {
+   ret = -EINVAL;
goto err;
+   }

exynos_fb->exynos_gem[i] = exynos_gem[i];
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c 
b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index f6118baa8e3e..fcbe43a580c1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -124,7 +124,6 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper 
*helper,
struct exynos_drm_gem *exynos_gem;
struct drm_device *dev = helper->dev;
struct drm_mode_fb_cmd2 mode_cmd = { 0 };
-   struct platform_device *pdev = dev->platformdev;
unsigned long size;
int ret;

@@ -142,18 +141,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper 
*helper,

size = mode_cmd.pitches[0] * mode_cmd.height;

-   exynos_gem = exynos_drm_gem_create(dev, EXYNOS_BO_CONTIG, size);
-   /*
-* If physically contiguous memory allocation fails and if IOMMU is
-* supported then try to get buffer from non physically contiguous
-* memory area.
-*/
-   if (IS_ERR(exynos_gem) && is_drm_iommu_supported(dev)) {
-   dev_warn(>dev, "contiguous FB allocation failed, falling 
back to non-contiguous\n");
-   exynos_gem = exynos_drm_gem_create(dev, EXYNOS_BO_NONCONTIG,
-  size);
-   }
-
+   exynos_gem = exynos_drm_gem_create(dev, 0, size);
if (IS_ERR(exynos_gem)) {
ret = PTR_ERR(exynos_gem);
goto out;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 163d113df1ab..96a69468283b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -135,6 +135,8 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem 
*exynos_gem)
if (!is_drm_iommu_supported(dev)) {
if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
return exynos_drm_alloc_dma(exynos_gem);
+   } else {
+   exynos_gem->flags &= ~EXYNOS_BO_NONCONTIG;
}

ret = exynos_drm_get_pages(exynos_gem);
@@ -440,10 +442,7 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
args->pitch = args->width * ((args->bpp + 7) / 8);
args->size = args->pitch * args->height;

-   if (is_drm_iommu_supported(dev))
-   flags = EXYNOS_BO_NONCONTIG | EXYNOS_BO_WC;
-   else
-   flags = EXYNOS_BO_CONTIG | EXYNOS_BO_WC;
+   flags = EXYNOS_BO_WC;

exynos_gem = exynos_drm_gem_create(dev, flags, args->size);
if (IS_ERR(exyno

[PATCH 6/9] drm/exynos: switch to new buffer allocation

2015-10-13 Thread Joonyoung Shim
The buffer allocation using DMA mapping API can't support non-continuous
buffer on non-iommu and cachable buffer, so switch to new buffer
allocation using drm_gem_get/put_pages() and doesn't use DMA mapping API
for mmap except allocation of physically continuous buffer on non-iommu.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 90 +++--
 1 file changed, 29 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index d982d46b04da..163d113df1ab 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -77,10 +77,7 @@ static int exynos_drm_alloc_dma(struct exynos_drm_gem 
*exynos_gem)

init_dma_attrs(_gem->dma_attrs);

-   if (exynos_gem->flags & EXYNOS_BO_WC ||
-   !(exynos_gem->flags & EXYNOS_BO_CACHABLE))
-   dma_set_attr(DMA_ATTR_WRITE_COMBINE, _gem->dma_attrs);
-
+   dma_set_attr(DMA_ATTR_WRITE_COMBINE, _gem->dma_attrs);
dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, _gem->dma_attrs);

nr_pages = exynos_gem->size >> PAGE_SHIFT;
@@ -128,51 +125,21 @@ static void exynos_drm_free_dma(struct exynos_drm_gem 
*exynos_gem)
 static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 {
struct drm_device *dev = exynos_gem->base.dev;
-   enum dma_attr attr;
-   unsigned int nr_pages;
+   int ret;

if (exynos_gem->dma_addr) {
DRM_DEBUG_KMS("already allocated.\n");
return 0;
}

-   if (!is_drm_iommu_supported(dev))
-   return exynos_drm_alloc_dma(exynos_gem);
-
-   init_dma_attrs(_gem->dma_attrs);
-
-   /*
-* if EXYNOS_BO_CONTIG, fully physically contiguous memory
-* region will be allocated else physically contiguous
-* as possible.
-*/
-   if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
-   dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, _gem->dma_attrs);
-
-   /* if EXYNOS_BO_WC or EXYNOS_BO_NONCACHABLE, writecombine mapping */
-   if (exynos_gem->flags & EXYNOS_BO_WC ||
-   !(exynos_gem->flags & EXYNOS_BO_CACHABLE))
-   attr = DMA_ATTR_WRITE_COMBINE;
-
-   dma_set_attr(attr, _gem->dma_attrs);
-   dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, _gem->dma_attrs);
-
-   nr_pages = exynos_gem->size >> PAGE_SHIFT;
-
-   exynos_gem->cookie = dma_alloc_attrs(dev->dev, exynos_gem->size,
-_gem->dma_addr, GFP_KERNEL,
-_gem->dma_attrs);
-   if (!exynos_gem->cookie) {
-   DRM_ERROR("failed to allocate buffer.\n");
-   if (exynos_gem->pages)
-   drm_free_large(exynos_gem->pages);
-   return -ENOMEM;
+   if (!is_drm_iommu_supported(dev)) {
+   if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
+   return exynos_drm_alloc_dma(exynos_gem);
}

-   exynos_gem->pages = exynos_gem->cookie;
-
-   DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n",
-   (unsigned long)exynos_gem->dma_addr, exynos_gem->size);
+   ret = exynos_drm_get_pages(exynos_gem);
+   if (ret < 0)
+   return ret;

return 0;
 }
@@ -186,15 +153,12 @@ static void exynos_drm_free_buf(struct exynos_drm_gem 
*exynos_gem)
return;
}

-   if (!is_drm_iommu_supported(dev))
-   return exynos_drm_free_dma(exynos_gem);
-
-   DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n",
-   (unsigned long)exynos_gem->dma_addr, exynos_gem->size);
+   if (!is_drm_iommu_supported(dev)) {
+   if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
+   return exynos_drm_free_dma(exynos_gem);
+   }

-   dma_free_attrs(dev->dev, exynos_gem->size, exynos_gem->cookie,
-   (dma_addr_t)exynos_gem->dma_addr,
-   _gem->dma_attrs);
+   exynos_drm_put_pages(exynos_gem);
 }

 static int exynos_drm_gem_handle_create(struct drm_gem_object *obj,
@@ -400,8 +364,8 @@ void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
drm_gem_object_unreference_unlocked(obj);
 }

-static int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem *exynos_gem,
- struct vm_area_struct *vma)
+static int exynos_drm_gem_mmap_dma(struct exynos_drm_gem *exynos_gem,
+  struct vm_area_struct *vma)
 {
struct drm_device *drm_dev = exynos_gem->base.dev;
unsigned long vm_size;
@@ -579,6 +543,19 @@ int exynos_drm_gem_mmap(struct file *filp, s

[PATCH 5/9] drm/exynos: introduce buffer allocation using drm_gem_get/put_pages()

2015-10-13 Thread Joonyoung Shim
This introduces new functions to allocate/free buffer using
drm_gem_get/put_pages() instead of DMA mapping API. They also use sg
list to manage pages.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 48 +
 drivers/gpu/drm/exynos/exynos_drm_gem.h |  2 +-
 2 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 88196edd4ade..d982d46b04da 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -20,6 +20,54 @@
 #include "exynos_drm_gem.h"
 #include "exynos_drm_iommu.h"

+static int exynos_drm_get_pages(struct exynos_drm_gem *exynos_gem)
+{
+   struct drm_device *dev = exynos_gem->base.dev;
+   struct page **pages;
+   struct sg_table *sgt;
+   int ret;
+
+   pages = drm_gem_get_pages(_gem->base);
+   if (IS_ERR(pages))
+   return PTR_ERR(pages);
+
+   sgt = drm_prime_pages_to_sg(pages, exynos_gem->size >> PAGE_SHIFT);
+   if (IS_ERR(sgt)) {
+   ret = PTR_ERR(sgt);
+   goto err;
+   }
+
+   if (!dma_map_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL)) {
+   sg_free_table(sgt);
+   kfree(sgt);
+   ret = -ENOMEM;
+   goto err;
+   }
+
+   exynos_gem->dma_addr = sg_dma_address(sgt->sgl);
+   exynos_gem->sgt = sgt;
+   exynos_gem->pages = pages;
+
+   return 0;
+
+err:
+   drm_gem_put_pages(_gem->base, pages, false, false);
+   return ret;
+}
+
+static void exynos_drm_put_pages(struct exynos_drm_gem *exynos_gem)
+{
+   struct drm_device *dev = exynos_gem->base.dev;
+   struct sg_table *sgt = exynos_gem->sgt;
+
+   dma_unmap_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+
+   sg_free_table(sgt);
+   kfree(sgt);
+
+   drm_gem_put_pages(_gem->base, exynos_gem->pages, false, false);
+}
+
 static int exynos_drm_alloc_dma(struct exynos_drm_gem *exynos_gem)
 {
struct drm_device *dev = exynos_gem->base.dev;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h 
b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index c1df26877b76..f47daec776e6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -38,7 +38,7 @@
  * - this address could be physical address without IOMMU and
  * device address with IOMMU.
  * @pages: Array of backing pages.
- * @sgt: Imported sg_table.
+ * @sgt: Converted sg_table of pages or imported sg_table.
  *
  * P.S. this object would be transferred to user as kms_bo.handle so
  * user can access the buffer through kms_bo.handle.
-- 
1.9.1



[PATCH 4/9] drm/exynos: split buffer allocation using DMA mapping API on non-iommu

2015-10-13 Thread Joonyoung Shim
This introduces new functions to allocate/free buffer using DMA mapping
API. Now already exynos-drm uses DMA mapping API to allocate/free buffer
but it is used on both iommu and non-iommu, so split it. It will be
added new buffer allocation not to use DMA mapping API later.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 90 +++--
 1 file changed, 64 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index d5951f75c774..88196edd4ade 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -20,6 +20,63 @@
 #include "exynos_drm_gem.h"
 #include "exynos_drm_iommu.h"

+static int exynos_drm_alloc_dma(struct exynos_drm_gem *exynos_gem)
+{
+   struct drm_device *dev = exynos_gem->base.dev;
+   unsigned int nr_pages;
+   unsigned int i;
+   dma_addr_t addr;
+
+   init_dma_attrs(_gem->dma_attrs);
+
+   if (exynos_gem->flags & EXYNOS_BO_WC ||
+   !(exynos_gem->flags & EXYNOS_BO_CACHABLE))
+   dma_set_attr(DMA_ATTR_WRITE_COMBINE, _gem->dma_attrs);
+
+   dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, _gem->dma_attrs);
+
+   nr_pages = exynos_gem->size >> PAGE_SHIFT;
+
+   exynos_gem->pages = drm_calloc_large(nr_pages, sizeof(struct page *));
+   if (!exynos_gem->pages) {
+   DRM_ERROR("failed to allocate pages\n");
+   return -ENOMEM;
+   }
+
+   exynos_gem->cookie = dma_alloc_attrs(dev->dev, exynos_gem->size,
+_gem->dma_addr, GFP_KERNEL,
+_gem->dma_attrs);
+   if (!exynos_gem->cookie) {
+   DRM_ERROR("failed to allocate buffer\n");
+   drm_free_large(exynos_gem->pages);
+   return -ENOMEM;
+   }
+
+   addr = exynos_gem->dma_addr;
+   for (i = 0; i < nr_pages; i++) {
+   exynos_gem->pages[i] =
+   pfn_to_page(dma_to_pfn(dev->dev, addr));
+   addr += PAGE_SIZE;
+   }
+
+   DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n",
+   (unsigned long)exynos_gem->dma_addr, exynos_gem->size);
+
+   return 0;
+}
+
+static void exynos_drm_free_dma(struct exynos_drm_gem *exynos_gem)
+{
+   struct drm_device *dev = exynos_gem->base.dev;
+
+   DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n",
+   (unsigned long)exynos_gem->dma_addr, exynos_gem->size);
+
+   dma_free_attrs(dev->dev, exynos_gem->size, exynos_gem->cookie,
+   exynos_gem->dma_addr, _gem->dma_attrs);
+   drm_free_large(exynos_gem->pages);
+}
+
 static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 {
struct drm_device *dev = exynos_gem->base.dev;
@@ -31,6 +88,9 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem 
*exynos_gem)
return 0;
}

+   if (!is_drm_iommu_supported(dev))
+   return exynos_drm_alloc_dma(exynos_gem);
+
init_dma_attrs(_gem->dma_attrs);

/*
@@ -51,15 +111,6 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem 
*exynos_gem)

nr_pages = exynos_gem->size >> PAGE_SHIFT;

-   if (!is_drm_iommu_supported(dev)) {
-   exynos_gem->pages = drm_calloc_large(nr_pages,
-sizeof(struct page *));
-   if (!exynos_gem->pages) {
-   DRM_ERROR("failed to allocate pages.\n");
-   return -ENOMEM;
-   }
-   }
-
exynos_gem->cookie = dma_alloc_attrs(dev->dev, exynos_gem->size,
 _gem->dma_addr, GFP_KERNEL,
 _gem->dma_attrs);
@@ -70,20 +121,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem 
*exynos_gem)
return -ENOMEM;
}

-   if (exynos_gem->pages) {
-   dma_addr_t start_addr;
-   unsigned int i = 0;
-
-   start_addr = exynos_gem->dma_addr;
-   while (i < nr_pages) {
-   exynos_gem->pages[i] =
-   pfn_to_page(dma_to_pfn(dev->dev, start_addr));
-   start_addr += PAGE_SIZE;
-   i++;
-   }
-   } else {
-   exynos_gem->pages = exynos_gem->cookie;
-   }
+   exynos_gem->pages = exynos_gem->cookie;

DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n",
(unsigned long)exynos_gem->dma_addr, exynos_gem->size);
@@ -100,15 +138,15 @@ 

[PATCH 3/9] drm/exynos: remove using non-consistent DMA attribute

2015-10-13 Thread Joonyoung Shim
DMA_ATTR_NON_CONSISTENT isn't supported in DMA mapping API of ARM, so
it doesn't give any effects to use non-consistent DMA attribute.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 17a52f89a690..d5951f75c774 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -41,15 +41,10 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem 
*exynos_gem)
if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, _gem->dma_attrs);

-   /*
-* if EXYNOS_BO_WC or EXYNOS_BO_NONCACHABLE, writecombine mapping
-* else cachable mapping.
-*/
+   /* if EXYNOS_BO_WC or EXYNOS_BO_NONCACHABLE, writecombine mapping */
if (exynos_gem->flags & EXYNOS_BO_WC ||
!(exynos_gem->flags & EXYNOS_BO_CACHABLE))
attr = DMA_ATTR_WRITE_COMBINE;
-   else
-   attr = DMA_ATTR_NON_CONSISTENT;

dma_set_attr(attr, _gem->dma_attrs);
dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, _gem->dma_attrs);
-- 
1.9.1



[PATCH 2/9] drm/exynos: use directly DMA mapping APIs on g2d

2015-10-13 Thread Joonyoung Shim
There is no reason to be wapper functions to use DMA mapping APIs. We
can use directly DMA mapping APIs without locking and remove the wapper
functions.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_g2d.c | 10 +-
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 26 --
 drivers/gpu/drm/exynos/exynos_drm_gem.h | 10 --
 3 files changed, 5 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c 
b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index c17efdb238a6..24d84a4298ac 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -365,6 +365,7 @@ static void g2d_userptr_put_dma_addr(struct drm_device 
*drm_dev,
 {
struct g2d_cmdlist_userptr *g2d_userptr =
(struct g2d_cmdlist_userptr *)obj;
+   struct sg_table *sgt;
struct page **pages;

if (!obj)
@@ -382,8 +383,8 @@ static void g2d_userptr_put_dma_addr(struct drm_device 
*drm_dev,
return;

 out:
-   exynos_gem_unmap_sgt_from_dma(drm_dev, g2d_userptr->sgt,
-   DMA_BIDIRECTIONAL);
+   sgt = g2d_userptr->sgt;
+   dma_unmap_sg(drm_dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);

pages = frame_vector_pages(g2d_userptr->vec);
if (!IS_ERR(pages)) {
@@ -500,9 +501,8 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct 
drm_device *drm_dev,

g2d_userptr->sgt = sgt;

-   ret = exynos_gem_map_sgt_with_dma(drm_dev, g2d_userptr->sgt,
-   DMA_BIDIRECTIONAL);
-   if (ret < 0) {
+   if (!dma_map_sg(drm_dev->dev, sgt->sgl, sgt->nents,
+   DMA_BIDIRECTIONAL)) {
DRM_ERROR("failed to map sgt with dma region.\n");
goto err_sg_free_table;
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 29f48756e72f..17a52f89a690 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -373,32 +373,6 @@ int exynos_drm_gem_get_ioctl(struct drm_device *dev, void 
*data,
return 0;
 }

-int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev,
-   struct sg_table *sgt,
-   enum dma_data_direction dir)
-{
-   int nents;
-
-   mutex_lock(_dev->struct_mutex);
-
-   nents = dma_map_sg(drm_dev->dev, sgt->sgl, sgt->nents, dir);
-   if (!nents) {
-   DRM_ERROR("failed to map sgl with dma.\n");
-   mutex_unlock(_dev->struct_mutex);
-   return nents;
-   }
-
-   mutex_unlock(_dev->struct_mutex);
-   return 0;
-}
-
-void exynos_gem_unmap_sgt_from_dma(struct drm_device *drm_dev,
-   struct sg_table *sgt,
-   enum dma_data_direction dir)
-{
-   dma_unmap_sg(drm_dev->dev, sgt->sgl, sgt->nents, dir);
-}
-
 void exynos_drm_gem_free_object(struct drm_gem_object *obj)
 {
exynos_drm_gem_destroy(to_exynos_gem(obj));
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h 
b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 00223052b87b..c1df26877b76 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -121,16 +121,6 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, 
struct vm_fault *vmf);
 /* set vm_flags and we can change the vm attribute to other one at here. */
 int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);

-/* map sgt with dma region. */
-int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev,
-   struct sg_table *sgt,
-   enum dma_data_direction dir);
-
-/* unmap sgt from dma region. */
-void exynos_gem_unmap_sgt_from_dma(struct drm_device *drm_dev,
-   struct sg_table *sgt,
-   enum dma_data_direction dir);
-
 /* low-level interface prime helpers */
 struct sg_table *exynos_drm_gem_prime_get_sg_table(struct drm_gem_object *obj);
 struct drm_gem_object *
-- 
1.9.1



[PATCH 1/9] drm/exynos: eliminate useless codes of exynos_drm_gem.h

2015-10-13 Thread Joonyoung Shim
This eliminates declaration of functions that is removed by the
commit 63540f01917c ("[media] drm/exynos: Convert
g2d_userptr_get_dma_addr() to use get_vaddr_frames()") and eliminate
vma_is_io() that isn't used anywhere now.

Also remove exynos_gem_get_pages() and exynos_drm_gem_userptr_ioctl(),
there is no body for them.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.h | 28 
 1 file changed, 28 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h 
b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 0d0ab27b48fa..00223052b87b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -55,8 +55,6 @@ struct exynos_drm_gem {
struct sg_table *sgt;
 };

-struct page **exynos_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask);
-
 /* destroy a buffer with gem object */
 void exynos_drm_gem_destroy(struct exynos_drm_gem *exynos_gem);

@@ -95,10 +93,6 @@ void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
unsigned int gem_handle,
struct drm_file *filp);

-/* map user space allocated by malloc to pages. */
-int exynos_drm_gem_userptr_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-
 /* get buffer information to memory region allocated by gem. */
 int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data,
  struct drm_file *file_priv);
@@ -127,28 +121,6 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, 
struct vm_fault *vmf);
 /* set vm_flags and we can change the vm attribute to other one at here. */
 int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);

-static inline int vma_is_io(struct vm_area_struct *vma)
-{
-   return !!(vma->vm_flags & (VM_IO | VM_PFNMAP));
-}
-
-/* get a copy of a virtual memory region. */
-struct vm_area_struct *exynos_gem_get_vma(struct vm_area_struct *vma);
-
-/* release a userspace virtual memory area. */
-void exynos_gem_put_vma(struct vm_area_struct *vma);
-
-/* get pages from user space. */
-int exynos_gem_get_pages_from_userptr(unsigned long start,
-   unsigned int npages,
-   struct page **pages,
-   struct vm_area_struct *vma);
-
-/* drop the reference to pages. */
-void exynos_gem_put_pages_to_userptr(struct page **pages,
-   unsigned int npages,
-   struct vm_area_struct *vma);
-
 /* map sgt with dma region. */
 int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev,
struct sg_table *sgt,
-- 
1.9.1



[PATCH 0/9] drm/exynos: update codes related with gem

2015-10-13 Thread Joonyoung Shim
Hi,

This patchset is about gem codes update of exynos-drm.

The first and second patches are cleanup to remove useless codes.
The rest is to support cachable gem allocation.

The exynos-drm uses DMA mapping API to allocate/mmap buffer of gem. If
it is cachable, does it with DMA_ATTR_NON_CONSISTENT attribute, but
DMA_ATTR_NON_CONSISTENT isn't supported in DMA mapping API of ARM, so it
doesn't give any effects.

This patchset introduces new buffer allocation to use
drm_gem_get/put_pages() instead of DMA mapping API. It will be used
for the rest except allocation of physically continuous buffer on
non-iommu, then exynos-drm can support cachable buffer of gem. Also it
can support physically non-continuous buffer on non-iommu.

EXYNOS_BO_CONTIG flag on iommu is ambiguous because it doesn't care
whether buffer is continuous physically if iommu is supported. This
patchset always will use EXYNOS_BO_CONTIG flag on iommu and then can
mean that the buffer is continuous for device.

There is no user API to control cache coherence for the cpu and device
about cachable buffer. This patchset introduces two ioctls for cpu
access of gem object from user. It will be synced properly in order for
the cpu and device if buffer of gem object is cachable.

Thanks.

Joonyoung Shim (9):
  drm/exynos: eliminate useless codes of exynos_drm_gem.h
  drm/exynos: use directly DMA mapping APIs on g2d
  drm/exynos: remove using non-consistent DMA attribute
  drm/exynos: split buffer allocation using DMA mapping API on non-iommu
  drm/exynos: introduce buffer allocation using drm_gem_get/put_pages()
  drm/exynos: switch to new buffer allocation
  drm/exynos: always use EXYNOS_BO_CONTIG flag on iommu
  drm/exynos: use DMA_ERROR_CODE
  drm/exynos: add ioctls for cpu access of gem object from user

 drivers/gpu/drm/exynos/exynos_drm_drv.c   |   4 +
 drivers/gpu/drm/exynos/exynos_drm_fb.c|  32 +---
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |  14 +-
 drivers/gpu/drm/exynos/exynos_drm_g2d.c   |  10 +-
 drivers/gpu/drm/exynos/exynos_drm_gem.c   | 288 ++
 drivers/gpu/drm/exynos/exynos_drm_gem.h   |  56 ++
 include/uapi/drm/exynos_drm.h |  23 ++-
 7 files changed, 225 insertions(+), 202 deletions(-)

-- 
1.9.1



[PATCH] drm/exynos: add DRM_EXYNOS_GEM_MAP ioctl

2015-10-13 Thread Joonyoung Shim
On 10/13/2015 02:23 PM, Joonyoung Shim wrote:
> On 10/13/2015 02:11 PM, Inki Dae wrote:
>>
>> Merged.
>>
> 
> Thanks for merge but this will be conflicted with the patch of Daniel,
> http://patchwork.freedesktop.org/patch/60565/
> 

Oops, wrong link,

http://lists.freedesktop.org/archives/intel-gfx/2015-September/075368.html

Thanks.

> I found it on next-20151012, do you want v2 patch that DRM_UNLOCKED flag
> is dropped?
> 
> Thanks.
> 
>> Thanks,
>> Inki Dae
>>
>> 2015년 10월 05일 12:04에 Joonyoung Shim 이(가) 쓴 글:
>>> The commit d931589c01a2 ("drm/exynos: remove DRM_EXYNOS_GEM_MAP_OFFSET
>>> ioctl") removed it same with the ioctl that this patch adds. The reason
>>> that removed DRM_EXYNOS_GEM_MAP_OFFSET was we could use
>>> DRM_IOCTL_MODE_MAP_DUMB. Both did exactly same thing.
>>>
>>> Now we again will revive it as DRM_EXYNOS_GEM_MAP because of render
>>> node. DRM_IOCTL_MODE_MAP_DUMB isn't permitted in render node.
>>>
>>> Signed-off-by: Joonyoung Shim 
>>> ---
>>>   drivers/gpu/drm/exynos/exynos_drm_drv.c |  2 ++
>>>   drivers/gpu/drm/exynos/exynos_drm_gem.c |  9 +
>>>   drivers/gpu/drm/exynos/exynos_drm_gem.h |  4 
>>>   include/uapi/drm/exynos_drm.h   | 17 -
>>>   4 files changed, 31 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
>>> b/drivers/gpu/drm/exynos/exynos_drm_drv.c
>>> index f0a5839..8fd7201 100644
>>> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
>>> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
>>> @@ -404,6 +404,8 @@ static const struct vm_operations_struct 
>>> exynos_drm_gem_vm_ops = {
>>>   static const struct drm_ioctl_desc exynos_ioctls[] = {
>>>   DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE, exynos_drm_gem_create_ioctl,
>>>   DRM_UNLOCKED | DRM_AUTH | DRM_RENDER_ALLOW),
>>> +DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MAP, exynos_drm_gem_map_ioctl,
>>> +DRM_UNLOCKED | DRM_AUTH | DRM_RENDER_ALLOW),
>>>   DRM_IOCTL_DEF_DRV(EXYNOS_GEM_GET, exynos_drm_gem_get_ioctl,
>>>   DRM_UNLOCKED | DRM_RENDER_ALLOW),
>>>   DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION, vidi_connection_ioctl,
>>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
>>> b/drivers/gpu/drm/exynos/exynos_drm_gem.c
>>> index f1dcdd0..29f4875 100644
>>> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
>>> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
>>> @@ -271,6 +271,15 @@ int exynos_drm_gem_create_ioctl(struct drm_device 
>>> *dev, void *data,
>>>   return 0;
>>>   }
>>>
>>> +int exynos_drm_gem_map_ioctl(struct drm_device *dev, void *data,
>>> + struct drm_file *file_priv)
>>> +{
>>> +struct drm_exynos_gem_map *args = data;
>>> +
>>> +return exynos_drm_gem_dumb_map_offset(file_priv, dev, args->handle,
>>> +  >offset);
>>> +}
>>> +
>>>   dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
>>>   unsigned int gem_handle,
>>>   struct drm_file *filp)
>>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h 
>>> b/drivers/gpu/drm/exynos/exynos_drm_gem.h
>>> index 37ab8b2..0d0ab27 100644
>>> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
>>> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
>>> @@ -73,6 +73,10 @@ struct exynos_drm_gem *exynos_drm_gem_create(struct 
>>> drm_device *dev,
>>>   int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
>>>   struct drm_file *file_priv);
>>>
>>> +/* get fake-offset of gem object that can be used with mmap. */
>>> +int exynos_drm_gem_map_ioctl(struct drm_device *dev, void *data,
>>> + struct drm_file *file_priv);
>>> +
>>>   /*
>>>* get dma address from gem handle and this function could be used for
>>>* other drivers such as 2d/3d acceleration drivers.
>>> diff --git a/include/uapi/drm/exynos_drm.h b/include/uapi/drm/exynos_drm.h
>>> index 5575ed1..18f0601 100644
>>> --- a/include/uapi/drm/exynos_drm.h
>>> +++ b/include/uapi/drm/exynos_drm.h
>>> @@ -33,6 +33,19 @@ struct drm_exynos_gem_create {
>>>   };
>>>
>>>   /**
>>> + * A structure for getting a fake-offset that can be used with mmap.
>>> + *
>>> + * @han

[PATCH] drm/exynos: add DRM_EXYNOS_GEM_MAP ioctl

2015-10-13 Thread Joonyoung Shim
On 10/13/2015 02:11 PM, Inki Dae wrote:
> 
> Merged.
> 

Thanks for merge but this will be conflicted with the patch of Daniel,
http://patchwork.freedesktop.org/patch/60565/

I found it on next-20151012, do you want v2 patch that DRM_UNLOCKED flag
is dropped?

Thanks.

> Thanks,
> Inki Dae
> 
> 2015년 10월 05일 12:04에 Joonyoung Shim 이(가) 쓴 글:
>> The commit d931589c01a2 ("drm/exynos: remove DRM_EXYNOS_GEM_MAP_OFFSET
>> ioctl") removed it same with the ioctl that this patch adds. The reason
>> that removed DRM_EXYNOS_GEM_MAP_OFFSET was we could use
>> DRM_IOCTL_MODE_MAP_DUMB. Both did exactly same thing.
>>
>> Now we again will revive it as DRM_EXYNOS_GEM_MAP because of render
>> node. DRM_IOCTL_MODE_MAP_DUMB isn't permitted in render node.
>>
>> Signed-off-by: Joonyoung Shim 
>> ---
>>   drivers/gpu/drm/exynos/exynos_drm_drv.c |  2 ++
>>   drivers/gpu/drm/exynos/exynos_drm_gem.c |  9 +
>>   drivers/gpu/drm/exynos/exynos_drm_gem.h |  4 
>>   include/uapi/drm/exynos_drm.h   | 17 -
>>   4 files changed, 31 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
>> b/drivers/gpu/drm/exynos/exynos_drm_drv.c
>> index f0a5839..8fd7201 100644
>> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
>> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
>> @@ -404,6 +404,8 @@ static const struct vm_operations_struct 
>> exynos_drm_gem_vm_ops = {
>>   static const struct drm_ioctl_desc exynos_ioctls[] = {
>>   DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE, exynos_drm_gem_create_ioctl,
>>   DRM_UNLOCKED | DRM_AUTH | DRM_RENDER_ALLOW),
>> +DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MAP, exynos_drm_gem_map_ioctl,
>> +DRM_UNLOCKED | DRM_AUTH | DRM_RENDER_ALLOW),
>>   DRM_IOCTL_DEF_DRV(EXYNOS_GEM_GET, exynos_drm_gem_get_ioctl,
>>   DRM_UNLOCKED | DRM_RENDER_ALLOW),
>>   DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION, vidi_connection_ioctl,
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
>> b/drivers/gpu/drm/exynos/exynos_drm_gem.c
>> index f1dcdd0..29f4875 100644
>> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
>> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
>> @@ -271,6 +271,15 @@ int exynos_drm_gem_create_ioctl(struct drm_device *dev, 
>> void *data,
>>   return 0;
>>   }
>>
>> +int exynos_drm_gem_map_ioctl(struct drm_device *dev, void *data,
>> + struct drm_file *file_priv)
>> +{
>> +struct drm_exynos_gem_map *args = data;
>> +
>> +return exynos_drm_gem_dumb_map_offset(file_priv, dev, args->handle,
>> +  >offset);
>> +}
>> +
>>   dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
>>   unsigned int gem_handle,
>>   struct drm_file *filp)
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h 
>> b/drivers/gpu/drm/exynos/exynos_drm_gem.h
>> index 37ab8b2..0d0ab27 100644
>> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
>> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
>> @@ -73,6 +73,10 @@ struct exynos_drm_gem *exynos_drm_gem_create(struct 
>> drm_device *dev,
>>   int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
>>   struct drm_file *file_priv);
>>
>> +/* get fake-offset of gem object that can be used with mmap. */
>> +int exynos_drm_gem_map_ioctl(struct drm_device *dev, void *data,
>> + struct drm_file *file_priv);
>> +
>>   /*
>>* get dma address from gem handle and this function could be used for
>>* other drivers such as 2d/3d acceleration drivers.
>> diff --git a/include/uapi/drm/exynos_drm.h b/include/uapi/drm/exynos_drm.h
>> index 5575ed1..18f0601 100644
>> --- a/include/uapi/drm/exynos_drm.h
>> +++ b/include/uapi/drm/exynos_drm.h
>> @@ -33,6 +33,19 @@ struct drm_exynos_gem_create {
>>   };
>>
>>   /**
>> + * A structure for getting a fake-offset that can be used with mmap.
>> + *
>> + * @handle: handle of gem object.
>> + * @reserved: just padding to be 64-bit aligned.
>> + * @offset: a fake-offset of gem object.
>> + */
>> +struct drm_exynos_gem_map {
>> +__u32 handle;
>> +__u32 reserved;
>> +__u64 offset;
>> +};
>> +
>> +/**
>>* A structure to gem information.
>>*
>>* @handle: a handle to gem object created.
>> @@ -284,6 +297,7 @@ struct drm_exynos_ipp_cmd_ctrl {
>>   };
>>
>>   #define DRM_EXYNOS_GE

[PATCH] drm/exynos: add DRM_EXYNOS_GEM_MAP ioctl

2015-10-05 Thread Joonyoung Shim
The commit d931589c01a2 ("drm/exynos: remove DRM_EXYNOS_GEM_MAP_OFFSET
ioctl") removed it same with the ioctl that this patch adds. The reason
that removed DRM_EXYNOS_GEM_MAP_OFFSET was we could use
DRM_IOCTL_MODE_MAP_DUMB. Both did exactly same thing.

Now we again will revive it as DRM_EXYNOS_GEM_MAP because of render
node. DRM_IOCTL_MODE_MAP_DUMB isn't permitted in render node.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_drv.c |  2 ++
 drivers/gpu/drm/exynos/exynos_drm_gem.c |  9 +
 drivers/gpu/drm/exynos/exynos_drm_gem.h |  4 
 include/uapi/drm/exynos_drm.h   | 17 -
 4 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index f0a5839..8fd7201 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -404,6 +404,8 @@ static const struct vm_operations_struct 
exynos_drm_gem_vm_ops = {
 static const struct drm_ioctl_desc exynos_ioctls[] = {
DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE, exynos_drm_gem_create_ioctl,
DRM_UNLOCKED | DRM_AUTH | DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MAP, exynos_drm_gem_map_ioctl,
+   DRM_UNLOCKED | DRM_AUTH | DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(EXYNOS_GEM_GET, exynos_drm_gem_get_ioctl,
DRM_UNLOCKED | DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION, vidi_connection_ioctl,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index f1dcdd0..29f4875 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -271,6 +271,15 @@ int exynos_drm_gem_create_ioctl(struct drm_device *dev, 
void *data,
return 0;
 }

+int exynos_drm_gem_map_ioctl(struct drm_device *dev, void *data,
+struct drm_file *file_priv)
+{
+   struct drm_exynos_gem_map *args = data;
+
+   return exynos_drm_gem_dumb_map_offset(file_priv, dev, args->handle,
+ >offset);
+}
+
 dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
unsigned int gem_handle,
struct drm_file *filp)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h 
b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 37ab8b2..0d0ab27 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -73,6 +73,10 @@ struct exynos_drm_gem *exynos_drm_gem_create(struct 
drm_device *dev,
 int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);

+/* get fake-offset of gem object that can be used with mmap. */
+int exynos_drm_gem_map_ioctl(struct drm_device *dev, void *data,
+struct drm_file *file_priv);
+
 /*
  * get dma address from gem handle and this function could be used for
  * other drivers such as 2d/3d acceleration drivers.
diff --git a/include/uapi/drm/exynos_drm.h b/include/uapi/drm/exynos_drm.h
index 5575ed1..18f0601 100644
--- a/include/uapi/drm/exynos_drm.h
+++ b/include/uapi/drm/exynos_drm.h
@@ -33,6 +33,19 @@ struct drm_exynos_gem_create {
 };

 /**
+ * A structure for getting a fake-offset that can be used with mmap.
+ *
+ * @handle: handle of gem object.
+ * @reserved: just padding to be 64-bit aligned.
+ * @offset: a fake-offset of gem object.
+ */
+struct drm_exynos_gem_map {
+   __u32 handle;
+   __u32 reserved;
+   __u64 offset;
+};
+
+/**
  * A structure to gem information.
  *
  * @handle: a handle to gem object created.
@@ -284,6 +297,7 @@ struct drm_exynos_ipp_cmd_ctrl {
 };

 #define DRM_EXYNOS_GEM_CREATE  0x00
+#define DRM_EXYNOS_GEM_MAP 0x01
 /* Reserved 0x03 ~ 0x05 for exynos specific gem ioctl */
 #define DRM_EXYNOS_GEM_GET 0x04
 #define DRM_EXYNOS_VIDI_CONNECTION 0x07
@@ -301,7 +315,8 @@ struct drm_exynos_ipp_cmd_ctrl {

 #define DRM_IOCTL_EXYNOS_GEM_CREATEDRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_GEM_CREATE, struct drm_exynos_gem_create)
-
+#define DRM_IOCTL_EXYNOS_GEM_MAP   DRM_IOWR(DRM_COMMAND_BASE + \
+   DRM_EXYNOS_GEM_MAP, struct drm_exynos_gem_map)
 #define DRM_IOCTL_EXYNOS_GEM_GET   DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_GEM_GET, struct drm_exynos_gem_info)

-- 
1.9.1



[PATCH] drm/exynos: cleanup name of gem object for exynos_drm

2015-10-02 Thread Joonyoung Shim
Struct of gem object in exynos_drm driver is struct exynos_drm_gem_obj.
It's too long and we can know its meaning of name without _obj postfix.

We use several names to variable name of gem object for exynos_drm -
exynos_gem_obj, gem_obj and obj. Especially "obj" name can cause
misunderstanding with variable name "obj" of struct drm_gem_object.

This will clean about name of gem object for exynos_drm as follows.
s/struct exynos_drm_gem_obj/struct exynos_drm_gem
s/exynos_gem_obj or gem_obj or obj/exynos_gem

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_fb.c|  45 +++---
 drivers/gpu/drm/exynos/exynos_drm_fb.h|   5 +-
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |  53 +++
 drivers/gpu/drm/exynos/exynos_drm_gem.c   | 239 +++---
 drivers/gpu/drm/exynos/exynos_drm_gem.h   |  15 +-
 drivers/gpu/drm/exynos/exynos_drm_plane.c |   9 +-
 6 files changed, 184 insertions(+), 182 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c 
b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index 0842808..fcea28b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -32,15 +32,15 @@
  * exynos specific framebuffer structure.
  *
  * @fb: drm framebuffer obejct.
- * @exynos_gem_obj: array of exynos specific gem object containing a gem 
object.
+ * @exynos_gem: array of exynos specific gem object containing a gem object.
  */
 struct exynos_drm_fb {
-   struct drm_framebuffer  fb;
-   struct exynos_drm_gem_obj   *exynos_gem_obj[MAX_FB_BUFFER];
+   struct drm_framebuffer  fb;
+   struct exynos_drm_gem   *exynos_gem[MAX_FB_BUFFER];
 };

 static int check_fb_gem_memory_type(struct drm_device *drm_dev,
-   struct exynos_drm_gem_obj *exynos_gem_obj)
+   struct exynos_drm_gem *exynos_gem)
 {
unsigned int flags;

@@ -51,7 +51,7 @@ static int check_fb_gem_memory_type(struct drm_device 
*drm_dev,
if (is_drm_iommu_supported(drm_dev))
return 0;

-   flags = exynos_gem_obj->flags;
+   flags = exynos_gem->flags;

/*
 * without iommu support, not support physically non-continuous memory
@@ -75,13 +75,13 @@ static void exynos_drm_fb_destroy(struct drm_framebuffer 
*fb)

drm_framebuffer_cleanup(fb);

-   for (i = 0; i < ARRAY_SIZE(exynos_fb->exynos_gem_obj); i++) {
+   for (i = 0; i < ARRAY_SIZE(exynos_fb->exynos_gem); i++) {
struct drm_gem_object *obj;

-   if (exynos_fb->exynos_gem_obj[i] == NULL)
+   if (exynos_fb->exynos_gem[i] == NULL)
continue;

-   obj = _fb->exynos_gem_obj[i]->base;
+   obj = _fb->exynos_gem[i]->base;
drm_gem_object_unreference_unlocked(obj);
}

@@ -96,7 +96,7 @@ static int exynos_drm_fb_create_handle(struct drm_framebuffer 
*fb,
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);

return drm_gem_handle_create(file_priv,
-   _fb->exynos_gem_obj[0]->base, handle);
+_fb->exynos_gem[0]->base, handle);
 }

 static int exynos_drm_fb_dirty(struct drm_framebuffer *fb,
@@ -118,7 +118,7 @@ static struct drm_framebuffer_funcs exynos_drm_fb_funcs = {
 struct drm_framebuffer *
 exynos_drm_framebuffer_init(struct drm_device *dev,
struct drm_mode_fb_cmd2 *mode_cmd,
-   struct exynos_drm_gem_obj **gem_obj,
+   struct exynos_drm_gem **exynos_gem,
int count)
 {
struct exynos_drm_fb *exynos_fb;
@@ -130,11 +130,11 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
return ERR_PTR(-ENOMEM);

for (i = 0; i < count; i++) {
-   ret = check_fb_gem_memory_type(dev, gem_obj[i]);
+   ret = check_fb_gem_memory_type(dev, exynos_gem[i]);
if (ret < 0)
goto err;

-   exynos_fb->exynos_gem_obj[i] = gem_obj[i];
+   exynos_fb->exynos_gem[i] = exynos_gem[i];
}

drm_helper_mode_fill_fb_struct(_fb->fb, mode_cmd);
@@ -156,7 +156,7 @@ static struct drm_framebuffer *
 exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
  struct drm_mode_fb_cmd2 *mode_cmd)
 {
-   struct exynos_drm_gem_obj *gem_objs[MAX_FB_BUFFER];
+   struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER];
struct drm_gem_object *obj;
struct drm_framebuffer *fb;
int i;
@@ -171,10 +171,10 @@ exynos_user_fb_create(struct drm_device *dev, struct 
drm_file *file_priv,
goto err;
}

-   gem_objs[i] = to_exynos_gem_obj(obj);
+   exynos_gem[i] = to_exynos_gem(obj);
}

-   fb = exynos_drm_framebu

[PATCH] drm/exynos: fix to detach device of iommu

2015-10-02 Thread Joonyoung Shim
The arm_iommu_detach_device() is a function to detach device of iommu
attached by arm_iommu_attach_device(). The exynos-drm uses
arm_iommu_attach_device() so it should use arm_iommu_detach_device() to
detach device of iommu, not iommu_detach_device().

The drm_release_iommu_mapping() is a function to release mapping of
iommu created by arm_iommu_create_mapping(). It is called by
exynos_drm_unload() so shouldn't be called by drm_iommu_detach_device().

Signed-off-by: Joonyoung Shim 
Cc:  # v3.8+
---
 drivers/gpu/drm/exynos/exynos_drm_iommu.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.c 
b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
index 055e8ec..d73b9ad 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_iommu.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
@@ -139,6 +139,5 @@ void drm_iommu_detach_device(struct drm_device *drm_dev,
if (!mapping || !mapping->domain)
return;

-   iommu_detach_device(mapping->domain, subdrv_dev);
-   drm_release_iommu_mapping(drm_dev);
+   arm_iommu_detach_device(subdrv_dev);
 }
-- 
1.9.1



[PATCH 09/14] drm/exynos: remove call to drm_gem_free_mmap_offset()

2015-09-30 Thread Joonyoung Shim
On 09/25/2015 06:15 PM, Inki Dae wrote:
> On 2015년 09월 24일 10:01, Joonyoung Shim wrote:
>> Hi Inki,
>>
>> On 08/17/2015 06:03 PM, Inki Dae wrote:
>>> On 2015년 08월 17일 17:17, Joonyoung Shim wrote:
>>>> On 08/17/2015 04:52 PM, Inki Dae wrote:
>>>>> On 2015년 08월 17일 14:29, Joonyoung Shim wrote:
>>>>>> On 08/16/2015 02:07 PM, Inki Dae wrote:
>>>>>>> On 2015년 07월 28일 17:53, Joonyoung Shim wrote:
>>>>>>>> The drm_gem_object_release() function already performs this cleanup,
>>>>>>>> so there is no reason to do it explicitly.
>>>>>>>>
>>>>>>>> Signed-off-by: Joonyoung Shim 
>>>>>>>> ---
>>>>>>>>  drivers/gpu/drm/exynos/exynos_drm_gem.c | 3 ---
>>>>>>>>  1 file changed, 3 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
>>>>>>>> b/drivers/gpu/drm/exynos/exynos_drm_gem.c
>>>>>>>> index c76aa8a..ab7d029 100644
>>>>>>>> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
>>>>>>>> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
>>>>>>>> @@ -100,8 +100,6 @@ out:
>>>>>>>>exynos_drm_fini_buf(obj->dev, buf);
>>>>>>>>exynos_gem_obj->buffer = NULL;
>>>>>>>>  
>>>>>>>> -  drm_gem_free_mmap_offset(obj);
>>>>>>>> -
>>>>>>>>/* release file pointer to gem object. */
>>>>>>>>drm_gem_object_release(obj);
>>>>>>>>  
>>>>>>>> @@ -600,7 +598,6 @@ int exynos_drm_gem_mmap(struct file *filp, struct 
>>>>>>>> vm_area_struct *vma)
>>>>>>>>  
>>>>>>>>  err_close_vm:
>>>>>>>>drm_gem_vm_close(vma);
>>>>>>>> -  drm_gem_free_mmap_offset(obj);
>>>>>>>
>>>>>>> Without previous patch, drm_gem_free_mmap_offset is required. I guess
>>>>>>> the reason you removed above line is that you thought
>>>>>>> drm_gem_object_release function would be called by drm_gem_vm_close
>>>>>>> function which drops a reference of the gem object.
>>>>>>>
>>>>>>> However, drm_gem_vm_close should be a pair with drm_gem_vm_open
>>>>>>> function. These will be called whenever a process opens or closes the
>>>>>>> VMA. So the reference count of the gem object had already been taken by
>>>>>>> open operation when a new reference to the VMA had been created.
>>>>>>>
>>>>>>
>>>>>> This changes is not related with drm_gem_vm_close and prior patch. Why
>>>>>> should free mmap offset when mmap operation is failed? The mmap offset
>>>>>> can be used repeatedly.
>>>>>
>>>>> Isn't vm space of vm manager still used even if any user-space process
>>>>> doesn't use the region? And if mmap is failed, then the user-space
>>>>> process will be terminated. Do you think it can be re-tried? However,
>>>>> mmap system call never return -EAGAIN. Is it reasonable to you? I cannot
>>>>> understand how the mmap offset can be re-used. So can you show me some
>>>>> example?
>>>>>
>>>>
>>>> Currently, mmap offset of exynos-drm gem is made by 
>>>> DRM_IOCTL_MODE_MAP_DUMB ioctl and mmap() ioctl just uses the mmap 
>>>> offset. User will use same mmap offset about same gem. It's why mmap
>>>> offset made by DRM_IOCTL_MODE_MAP_DUMB ioctl is unnecessary, it's just
>>>> enough to make mmap offset from when gem is create. You can get a
>>>> reference from drm_gem_cma_helper.c file.
>>>
>>> Hmm... It's not that the mmap offset can be re-used or not. It's that
>>> the mmap offset should be released or not when mmap failed. As your
>>> original comment, the call of drm_gem_free_mmap_offset() is unnecessary
>>> if mmap offset is created when gem creation because the mmap offset is
>>> removed by drm_gem_object_release() when gem is destroyed - gem should
>>> also be released when mmap failed.
>>>
>>> Ok, let's create mmap offset at gem creation and remove it gem
>>> releasing. Will merge these two patches.
>>>
>>
>> I can't find them from your git. Could you merge them?
> 
> Oops, sorry. Merged.
> 

Thanks for merge, but you are missing the first patch still,
http://www.spinics.net/lists/dri-devel/msg86891.html

Thanks.



[PATCH 09/14] drm/exynos: remove call to drm_gem_free_mmap_offset()

2015-09-24 Thread Joonyoung Shim
Hi Inki,

On 08/17/2015 06:03 PM, Inki Dae wrote:
> On 2015년 08월 17일 17:17, Joonyoung Shim wrote:
>> On 08/17/2015 04:52 PM, Inki Dae wrote:
>>> On 2015년 08월 17일 14:29, Joonyoung Shim wrote:
>>>> On 08/16/2015 02:07 PM, Inki Dae wrote:
>>>>> On 2015년 07월 28일 17:53, Joonyoung Shim wrote:
>>>>>> The drm_gem_object_release() function already performs this cleanup,
>>>>>> so there is no reason to do it explicitly.
>>>>>>
>>>>>> Signed-off-by: Joonyoung Shim 
>>>>>> ---
>>>>>>  drivers/gpu/drm/exynos/exynos_drm_gem.c | 3 ---
>>>>>>  1 file changed, 3 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
>>>>>> b/drivers/gpu/drm/exynos/exynos_drm_gem.c
>>>>>> index c76aa8a..ab7d029 100644
>>>>>> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
>>>>>> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
>>>>>> @@ -100,8 +100,6 @@ out:
>>>>>>  exynos_drm_fini_buf(obj->dev, buf);
>>>>>>  exynos_gem_obj->buffer = NULL;
>>>>>>  
>>>>>> -drm_gem_free_mmap_offset(obj);
>>>>>> -
>>>>>>  /* release file pointer to gem object. */
>>>>>>  drm_gem_object_release(obj);
>>>>>>  
>>>>>> @@ -600,7 +598,6 @@ int exynos_drm_gem_mmap(struct file *filp, struct 
>>>>>> vm_area_struct *vma)
>>>>>>  
>>>>>>  err_close_vm:
>>>>>>  drm_gem_vm_close(vma);
>>>>>> -drm_gem_free_mmap_offset(obj);
>>>>>
>>>>> Without previous patch, drm_gem_free_mmap_offset is required. I guess
>>>>> the reason you removed above line is that you thought
>>>>> drm_gem_object_release function would be called by drm_gem_vm_close
>>>>> function which drops a reference of the gem object.
>>>>>
>>>>> However, drm_gem_vm_close should be a pair with drm_gem_vm_open
>>>>> function. These will be called whenever a process opens or closes the
>>>>> VMA. So the reference count of the gem object had already been taken by
>>>>> open operation when a new reference to the VMA had been created.
>>>>>
>>>>
>>>> This changes is not related with drm_gem_vm_close and prior patch. Why
>>>> should free mmap offset when mmap operation is failed? The mmap offset
>>>> can be used repeatedly.
>>>
>>> Isn't vm space of vm manager still used even if any user-space process
>>> doesn't use the region? And if mmap is failed, then the user-space
>>> process will be terminated. Do you think it can be re-tried? However,
>>> mmap system call never return -EAGAIN. Is it reasonable to you? I cannot
>>> understand how the mmap offset can be re-used. So can you show me some
>>> example?
>>>
>>
>> Currently, mmap offset of exynos-drm gem is made by 
>> DRM_IOCTL_MODE_MAP_DUMB ioctl and mmap() ioctl just uses the mmap 
>> offset. User will use same mmap offset about same gem. It's why mmap
>> offset made by DRM_IOCTL_MODE_MAP_DUMB ioctl is unnecessary, it's just
>> enough to make mmap offset from when gem is create. You can get a
>> reference from drm_gem_cma_helper.c file.
> 
> Hmm... It's not that the mmap offset can be re-used or not. It's that
> the mmap offset should be released or not when mmap failed. As your
> original comment, the call of drm_gem_free_mmap_offset() is unnecessary
> if mmap offset is created when gem creation because the mmap offset is
> removed by drm_gem_object_release() when gem is destroyed - gem should
> also be released when mmap failed.
> 
> Ok, let's create mmap offset at gem creation and remove it gem
> releasing. Will merge these two patches.
> 

I can't find them from your git. Could you merge them?

Thanks.


[PATCH] drm/exynos: get event time from ktime

2015-09-16 Thread Joonyoung Shim
On 09/16/2015 02:31 PM, Joonyoung Shim wrote:
> G2D and IPP drivers get event time from do_gettimeofday(), but drm
> vblank event gets it from ktime. Use ktime for consistency.

Oops, this causes build errors, please ignore, i will retry.

Thanks.

> 
> Signed-off-by: Joonyoung Shim 
> ---
>  drivers/gpu/drm/exynos/exynos_drm_g2d.c | 4 +++-
>  drivers/gpu/drm/exynos/exynos_drm_ipp.c | 4 +++-
>  2 files changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c 
> b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> index 3734c34..fa8817c 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> @@ -880,6 +880,7 @@ static void g2d_finish_event(struct g2d_data *g2d, u32 
> cmdlist_no)
>   struct g2d_runqueue_node *runqueue_node = g2d->runqueue_node;
>   struct drm_exynos_pending_g2d_event *e;
>   struct timeval now;
> + ktime_t now_ktime;
>   unsigned long flags;
>  
>   if (list_empty(_node->event_list))
> @@ -888,7 +889,8 @@ static void g2d_finish_event(struct g2d_data *g2d, u32 
> cmdlist_no)
>   e = list_first_entry(_node->event_list,
>struct drm_exynos_pending_g2d_event, base.link);
>  
> - do_gettimeofday();
> + now_ktime = drm_timestamp_monotonic ? ktime_get() : ktime_get_real();
> + now = ktime_to_timeval(now_ktime);
>   e->event.tv_sec = now.tv_sec;
>   e->event.tv_usec = now.tv_usec;
>   e->event.cmdlist_no = cmdlist_no;
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c 
> b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
> index 67d2423..74076d0 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
> @@ -1412,6 +1412,7 @@ static int ipp_send_event(struct exynos_drm_ippdrv 
> *ippdrv,
>   struct drm_exynos_ipp_send_event *e;
>   struct list_head *head;
>   struct timeval now;
> + ktime_t now_ktime;
>   unsigned long flags;
>   u32 tbuf_id[EXYNOS_DRM_OPS_MAX] = {0, };
>   int ret, i;
> @@ -1515,7 +1516,8 @@ static int ipp_send_event(struct exynos_drm_ippdrv 
> *ippdrv,
>   e = list_first_entry(_node->event_list,
>   struct drm_exynos_ipp_send_event, base.link);
>  
> - do_gettimeofday();
> + now_ktime = drm_timestamp_monotonic ? ktime_get() : ktime_get_real();
> + now = ktime_to_timeval(now_ktime);
>   DRM_DEBUG_KMS("tv_sec[%ld]tv_usec[%ld]\n", now.tv_sec, now.tv_usec);
>   e->event.tv_sec = now.tv_sec;
>   e->event.tv_usec = now.tv_usec;
> 



[PATCH] drm/exynos: get event time from ktime

2015-09-16 Thread Joonyoung Shim
G2D and IPP drivers get event time from do_gettimeofday(), but drm
vblank event gets it from ktime. Use ktime for consistency.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_g2d.c | 4 +++-
 drivers/gpu/drm/exynos/exynos_drm_ipp.c | 4 +++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c 
b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index 3734c34..fa8817c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -880,6 +880,7 @@ static void g2d_finish_event(struct g2d_data *g2d, u32 
cmdlist_no)
struct g2d_runqueue_node *runqueue_node = g2d->runqueue_node;
struct drm_exynos_pending_g2d_event *e;
struct timeval now;
+   ktime_t now_ktime;
unsigned long flags;

if (list_empty(_node->event_list))
@@ -888,7 +889,8 @@ static void g2d_finish_event(struct g2d_data *g2d, u32 
cmdlist_no)
e = list_first_entry(_node->event_list,
 struct drm_exynos_pending_g2d_event, base.link);

-   do_gettimeofday();
+   now_ktime = drm_timestamp_monotonic ? ktime_get() : ktime_get_real();
+   now = ktime_to_timeval(now_ktime);
e->event.tv_sec = now.tv_sec;
e->event.tv_usec = now.tv_usec;
e->event.cmdlist_no = cmdlist_no;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c 
b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index 67d2423..74076d0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -1412,6 +1412,7 @@ static int ipp_send_event(struct exynos_drm_ippdrv 
*ippdrv,
struct drm_exynos_ipp_send_event *e;
struct list_head *head;
struct timeval now;
+   ktime_t now_ktime;
unsigned long flags;
u32 tbuf_id[EXYNOS_DRM_OPS_MAX] = {0, };
int ret, i;
@@ -1515,7 +1516,8 @@ static int ipp_send_event(struct exynos_drm_ippdrv 
*ippdrv,
e = list_first_entry(_node->event_list,
struct drm_exynos_ipp_send_event, base.link);

-   do_gettimeofday();
+   now_ktime = drm_timestamp_monotonic ? ktime_get() : ktime_get_real();
+   now = ktime_to_timeval(now_ktime);
DRM_DEBUG_KMS("tv_sec[%ld]tv_usec[%ld]\n", now.tv_sec, now.tv_usec);
e->event.tv_sec = now.tv_sec;
e->event.tv_usec = now.tv_usec;
-- 
1.9.1



[PATCH 4/4] drm/exynos: cleanup line feed in exynos_drm_gem_get_ioctl

2015-09-16 Thread Joonyoung Shim
The beginning of statement in function is next line of a brace.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 5bc0fc3..31c5b64 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -331,7 +331,8 @@ int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem_obj 
*exynos_gem_obj,

 int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data,
  struct drm_file *file_priv)
-{  struct exynos_drm_gem_obj *exynos_gem_obj;
+{
+   struct exynos_drm_gem_obj *exynos_gem_obj;
struct drm_exynos_gem_info *args = data;
struct drm_gem_object *obj;

-- 
1.9.1



[PATCH 3/4] drm/exynos: cleanup function calling written twice

2015-09-16 Thread Joonyoung Shim
By if statment, some function callings are written twice. It needs
several line feed by indentation in if statment. Make to one function
calling from outside if statment.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 56 ++---
 1 file changed, 23 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index fcb6a2c..5bc0fc3 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -56,24 +56,25 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem_obj 
*obj)
nr_pages = obj->size >> PAGE_SHIFT;

if (!is_drm_iommu_supported(dev)) {
-   dma_addr_t start_addr;
-   unsigned int i = 0;
-
obj->pages = drm_calloc_large(nr_pages, sizeof(struct page *));
if (!obj->pages) {
DRM_ERROR("failed to allocate pages.\n");
return -ENOMEM;
}
+   }

-   obj->cookie = dma_alloc_attrs(dev->dev,
-   obj->size,
-   >dma_addr, GFP_KERNEL,
-   >dma_attrs);
-   if (!obj->cookie) {
-   DRM_ERROR("failed to allocate buffer.\n");
+   obj->cookie = dma_alloc_attrs(dev->dev, obj->size, >dma_addr,
+ GFP_KERNEL, >dma_attrs);
+   if (!obj->cookie) {
+   DRM_ERROR("failed to allocate buffer.\n");
+   if (obj->pages)
drm_free_large(obj->pages);
-   return -ENOMEM;
-   }
+   return -ENOMEM;
+   }
+
+   if (obj->pages) {
+   dma_addr_t start_addr;
+   unsigned int i = 0;

start_addr = obj->dma_addr;
while (i < nr_pages) {
@@ -82,13 +83,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem_obj 
*obj)
i++;
}
} else {
-   obj->pages = dma_alloc_attrs(dev->dev, obj->size,
-   >dma_addr, GFP_KERNEL,
-   >dma_attrs);
-   if (!obj->pages) {
-   DRM_ERROR("failed to allocate buffer.\n");
-   return -ENOMEM;
-   }
+   obj->pages = obj->cookie;
}

DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n",
@@ -110,13 +105,11 @@ static void exynos_drm_free_buf(struct exynos_drm_gem_obj 
*obj)
DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n",
(unsigned long)obj->dma_addr, obj->size);

-   if (!is_drm_iommu_supported(dev)) {
-   dma_free_attrs(dev->dev, obj->size, obj->cookie,
-   (dma_addr_t)obj->dma_addr, >dma_attrs);
+   dma_free_attrs(dev->dev, obj->size, obj->cookie,
+   (dma_addr_t)obj->dma_addr, >dma_attrs);
+
+   if (!is_drm_iommu_supported(dev))
drm_free_large(obj->pages);
-   } else
-   dma_free_attrs(dev->dev, obj->size, obj->pages,
-   (dma_addr_t)obj->dma_addr, >dma_attrs);
 }

 static int exynos_drm_gem_handle_create(struct drm_gem_object *obj,
@@ -398,6 +391,7 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
   struct drm_mode_create_dumb *args)
 {
struct exynos_drm_gem_obj *exynos_gem_obj;
+   unsigned int flags;
int ret;

/*
@@ -409,16 +403,12 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
args->pitch = args->width * ((args->bpp + 7) / 8);
args->size = args->pitch * args->height;

-   if (is_drm_iommu_supported(dev)) {
-   exynos_gem_obj = exynos_drm_gem_create(dev,
-   EXYNOS_BO_NONCONTIG | EXYNOS_BO_WC,
-   args->size);
-   } else {
-   exynos_gem_obj = exynos_drm_gem_create(dev,
-   EXYNOS_BO_CONTIG | EXYNOS_BO_WC,
-   args->size);
-   }
+   if (is_drm_iommu_supported(dev))
+   flags = EXYNOS_BO_NONCONTIG | EXYNOS_BO_WC;
+   else
+   flags = EXYNOS_BO_CONTIG | EXYNOS_BO_WC;

+   exynos_gem_obj = exynos_drm_gem_create(dev, flags, args->size);
if (IS_ERR(exynos_gem_obj)) {
dev_warn(dev->dev, "FB allocation failed.\n");
return PTR_ERR(exynos_gem_obj);
-- 
1.9.1



[PATCH 2/4] drm/exynos: staticize exynos_drm_gem_init()

2015-09-16 Thread Joonyoung Shim
The exynos_drm_gem_init() is used only in exynos_drm_gem.c file. Make it
static and don't export it.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 3 +--
 drivers/gpu/drm/exynos/exynos_drm_gem.h | 4 
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 8dce40d..fcb6a2c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -187,8 +187,7 @@ unsigned long exynos_drm_gem_get_size(struct drm_device 
*dev,
return exynos_gem_obj->size;
 }

-
-struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev,
+static struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev,
  unsigned long size)
 {
struct exynos_drm_gem_obj *exynos_gem_obj;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h 
b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index cd62f84..610ccad 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -59,10 +59,6 @@ struct page **exynos_gem_get_pages(struct drm_gem_object 
*obj, gfp_t gfpmask);
 /* destroy a buffer with gem object */
 void exynos_drm_gem_destroy(struct exynos_drm_gem_obj *exynos_gem_obj);

-/* create a private gem object and initialize it. */
-struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev,
- unsigned long size);
-
 /* create a new buffer with gem object */
 struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
unsigned int flags,
-- 
1.9.1



[PATCH 1/4] drm/exynos: remove unnecessary NULL assignment

2015-09-16 Thread Joonyoung Shim
They will be freed right or was freed already, so NULL assignment is
unnecessary.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index f12fbc3..8dce40d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -117,8 +117,6 @@ static void exynos_drm_free_buf(struct exynos_drm_gem_obj 
*obj)
} else
dma_free_attrs(dev->dev, obj->size, obj->pages,
(dma_addr_t)obj->dma_addr, >dma_attrs);
-
-   obj->dma_addr = (dma_addr_t)NULL;
 }

 static int exynos_drm_gem_handle_create(struct drm_gem_object *obj,
@@ -167,7 +165,6 @@ out:
drm_gem_object_release(obj);

kfree(exynos_gem_obj);
-   exynos_gem_obj = NULL;
 }

 unsigned long exynos_drm_gem_get_size(struct drm_device *dev,
-- 
1.9.1



[PATCH 0/4] drm/exynos: small cleanup for exynos_drm_gem

2015-09-16 Thread Joonyoung Shim
Hi,

This patchset is small cleanup about exynos_drm_gem codes of exynos-drm
driver. This removes unnecessary and redundant codes, and staticize a
local function.

Thanks.

Joonyoung Shim (4):
  drm/exynos: remove unnecessary NULL assignment
  drm/exynos: staticize exynos_drm_gem_init()
  drm/exynos: cleanup function calling written twice
  drm/exynos: cleanup line feed in exynos_drm_gem_get_ioctl

 drivers/gpu/drm/exynos/exynos_drm_gem.c | 65 +
 drivers/gpu/drm/exynos/exynos_drm_gem.h |  4 --
 2 files changed, 26 insertions(+), 43 deletions(-)


[PATCH] drm/exynos: fix layering violation of address

2015-09-16 Thread Joonyoung Shim
There is no guarantee that DMA addresses are the same as physical
addresses, but dma_to_pfn() knows how to convert a dma_addr_t to a PFN
which can then be converted to a struct page.

Suggested-by: Russell King <rmk+kernel at arm.linux.org.uk>
Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index f12fbc3..a4fb78e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -77,7 +77,8 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem_obj 
*obj)

start_addr = obj->dma_addr;
while (i < nr_pages) {
-   obj->pages[i] = phys_to_page(start_addr);
+   obj->pages[i] = pfn_to_page(dma_to_pfn(dev->dev,
+  start_addr));
start_addr += PAGE_SIZE;
i++;
}
-- 
1.9.1



[PATCH] drm/exynos: fix missed calling of drm_prime_gem_destroy()

2015-09-16 Thread Joonyoung Shim
When obj->import_attach is existed, code calling drm_prime_gem_destroy()
was removed from commit 67e93c808b48 ("drm/exynos: stop copying sg
table"), and it's a fault.

The drm_prime_gem_destroy() is cleanup function which GEM drivers need
to call when they use drm_gem_prime_import() to import dma-bufs, so
exynos-drm driver using drm_gem_prime_import() needs calling
drm_prime_gem_destroy().

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 9 +
 drivers/gpu/drm/exynos/exynos_drm_gem.h | 2 ++
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index a4fb78e..ce05f13 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -157,11 +157,10 @@ void exynos_drm_gem_destroy(struct exynos_drm_gem_obj 
*exynos_gem_obj)
 * once dmabuf's refcount becomes 0.
 */
if (obj->import_attach)
-   goto out;
-
-   exynos_drm_free_buf(exynos_gem_obj);
+   drm_prime_gem_destroy(obj, exynos_gem_obj->sgt);
+   else
+   exynos_drm_free_buf(exynos_gem_obj);

-out:
drm_gem_free_mmap_offset(obj);

/* release file pointer to gem object. */
@@ -589,6 +588,8 @@ exynos_drm_gem_prime_import_sg_table(struct drm_device *dev,
if (ret < 0)
goto err_free_large;

+   exynos_gem_obj->sgt = sgt;
+
if (sgt->nents == 1) {
/* always physically continuous memory if sgt->nents is 1. */
exynos_gem_obj->flags |= EXYNOS_BO_CONTIG;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h 
b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index cd62f84..97bb48b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -39,6 +39,7 @@
  * - this address could be physical address without IOMMU and
  * device address with IOMMU.
  * @pages: Array of backing pages.
+ * @sgt: Imported sg_table.
  *
  * P.S. this object would be transferred to user as kms_bo.handle so
  * user can access the buffer through kms_bo.handle.
@@ -52,6 +53,7 @@ struct exynos_drm_gem_obj {
dma_addr_t  dma_addr;
struct dma_attrsdma_attrs;
struct page **pages;
+   struct sg_table *sgt;
 };

 struct page **exynos_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask);
-- 
1.9.1



[PATCH 9/9] drm/exynos: remove buf_cnt from struct exynos_drm_fb

2015-09-01 Thread Joonyoung Shim
Looking other drm drivers, there is no the restriction that framebuffer
has only one buffer in .create_handle() callback. They use just first
buffer.

If this limitation is removed, there is no reason keeping buffer count
for framebuffer, so we can remove buf_cnt from struct exynos_drm_fb.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_fb.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c 
b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index d2e746e..6d1b70e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -32,12 +32,10 @@
  * exynos specific framebuffer structure.
  *
  * @fb: drm framebuffer obejct.
- * @buf_cnt: a buffer count to drm framebuffer.
  * @exynos_gem_obj: array of exynos specific gem object containing a gem 
object.
  */
 struct exynos_drm_fb {
struct drm_framebuffer  fb;
-   unsigned intbuf_cnt;
struct exynos_drm_gem_obj   *exynos_gem_obj[MAX_FB_BUFFER];
 };

@@ -97,10 +95,6 @@ static int exynos_drm_fb_create_handle(struct 
drm_framebuffer *fb,
 {
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);

-   /* This fb should have only one gem object. */
-   if (WARN_ON(exynos_fb->buf_cnt != 1))
-   return -EINVAL;
-
return drm_gem_handle_create(file_priv,
_fb->exynos_gem_obj[0]->base, handle);
 }
@@ -135,9 +129,6 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
if (!exynos_fb)
return ERR_PTR(-ENOMEM);

-   exynos_fb->buf_cnt = count;
-   DRM_DEBUG_KMS("buf_cnt = %d\n", exynos_fb->buf_cnt);
-
for (i = 0; i < count; i++) {
ret = check_fb_gem_memory_type(dev, gem_obj[i]);
if (ret < 0)
-- 
1.9.1



[PATCH 8/9] drm/exynos: remove exynos_drm_fb_get_buf_cnt()

2015-09-01 Thread Joonyoung Shim
We can get buffer count of framebuffer using drm_format_num_planes(), so
keeping exynos_drm_fb_get_buf_cnt() is unnecessary.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_fb.c| 9 -
 drivers/gpu/drm/exynos/exynos_drm_fb.h| 3 ---
 drivers/gpu/drm/exynos/exynos_drm_plane.c | 2 +-
 3 files changed, 1 insertion(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c 
b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index 9accc0d..d2e746e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -121,15 +121,6 @@ static struct drm_framebuffer_funcs exynos_drm_fb_funcs = {
.dirty  = exynos_drm_fb_dirty,
 };

-unsigned int exynos_drm_fb_get_buf_cnt(struct drm_framebuffer *fb)
-{
-   struct exynos_drm_fb *exynos_fb;
-
-   exynos_fb = to_exynos_fb(fb);
-
-   return exynos_fb->buf_cnt;
-}
-
 struct drm_framebuffer *
 exynos_drm_framebuffer_init(struct drm_device *dev,
struct drm_mode_fb_cmd2 *mode_cmd,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.h 
b/drivers/gpu/drm/exynos/exynos_drm_fb.h
index 8900f6b..85e4445 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.h
@@ -28,7 +28,4 @@ struct exynos_drm_gem_obj *exynos_drm_fb_gem_obj(struct 
drm_framebuffer *fb,

 void exynos_drm_mode_config_init(struct drm_device *dev);

-/* get a buffer count to drm framebuffer. */
-unsigned int exynos_drm_fb_get_buf_cnt(struct drm_framebuffer *fb);
-
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c 
b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index d9a68fd..36c9911 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -132,7 +132,7 @@ static int exynos_plane_atomic_check(struct drm_plane 
*plane,
if (!state->fb)
return 0;

-   nr = exynos_drm_fb_get_buf_cnt(state->fb);
+   nr = drm_format_num_planes(state->fb->pixel_format);
for (i = 0; i < nr; i++) {
struct exynos_drm_gem_obj *obj =
exynos_drm_fb_gem_obj(state->fb, i);
-- 
1.9.1



[PATCH 7/9] drm/exynos: cleanup exynos_user_fb_create()

2015-09-01 Thread Joonyoung Shim
Using exynos_drm_framebuffer_init(), redundant codes can be removed.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_fb.c | 47 ++
 1 file changed, 13 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c 
b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index 8e5d3eb..9accc0d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -174,57 +174,36 @@ static struct drm_framebuffer *
 exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
  struct drm_mode_fb_cmd2 *mode_cmd)
 {
+   struct exynos_drm_gem_obj *gem_objs[MAX_FB_BUFFER];
struct drm_gem_object *obj;
-   struct exynos_drm_gem_obj *exynos_gem_obj;
-   struct exynos_drm_fb *exynos_fb;
-   int i, ret;
-
-   exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL);
-   if (!exynos_fb)
-   return ERR_PTR(-ENOMEM);
-
-   exynos_fb->buf_cnt = drm_format_num_planes(mode_cmd->pixel_format);
-
-   DRM_DEBUG_KMS("buf_cnt = %d\n", exynos_fb->buf_cnt);
+   struct drm_framebuffer *fb;
+   int i;
+   int ret;

-   for (i = 0; i < exynos_fb->buf_cnt; i++) {
+   for (i = 0; i < drm_format_num_planes(mode_cmd->pixel_format); i++) {
obj = drm_gem_object_lookup(dev, file_priv,
-   mode_cmd->handles[i]);
+   mode_cmd->handles[i]);
if (!obj) {
DRM_ERROR("failed to lookup gem object\n");
ret = -ENOENT;
-   exynos_fb->buf_cnt = i;
goto err;
}

-   exynos_gem_obj = to_exynos_gem_obj(obj);
-   exynos_fb->exynos_gem_obj[i] = exynos_gem_obj;
-
-   ret = check_fb_gem_memory_type(dev, exynos_gem_obj);
-   if (ret < 0)
-   goto err;
+   gem_objs[i] = to_exynos_gem_obj(obj);
}

-   drm_helper_mode_fill_fb_struct(_fb->fb, mode_cmd);
-
-   ret = drm_framebuffer_init(dev, _fb->fb, _drm_fb_funcs);
-   if (ret) {
-   DRM_ERROR("failed to init framebuffer.\n");
+   fb = exynos_drm_framebuffer_init(dev, mode_cmd, gem_objs, i);
+   if (IS_ERR(fb)) {
+   ret = PTR_ERR(fb);
goto err;
}

-   return _fb->fb;
+   return fb;

 err:
-   for (i = 0; i < exynos_fb->buf_cnt; i++) {
-   struct drm_gem_object *obj;
+   while (i--)
+   drm_gem_object_unreference_unlocked(_objs[i]->base);

-   obj = _fb->exynos_gem_obj[i]->base;
-   if (obj)
-   drm_gem_object_unreference_unlocked(obj);
-   }
-
-   kfree(exynos_fb);
return ERR_PTR(ret);
 }

-- 
1.9.1



[PATCH 6/9] drm/exynos: update exynos_drm_framebuffer_init() for multiple buffers

2015-09-01 Thread Joonyoung Shim
This modifies exynos_drm_framebuffer_init() to be possible to support
multiple buffers. Then it can be used by exynos_user_fb_create().

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_fb.c| 36 +--
 drivers/gpu/drm/exynos/exynos_drm_fb.h|  5 -
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |  3 +--
 3 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c 
b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index 5cee148..8e5d3eb 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -23,7 +23,6 @@
 #include "exynos_drm_drv.h"
 #include "exynos_drm_fb.h"
 #include "exynos_drm_fbdev.h"
-#include "exynos_drm_gem.h"
 #include "exynos_drm_iommu.h"
 #include "exynos_drm_crtc.h"

@@ -134,36 +133,41 @@ unsigned int exynos_drm_fb_get_buf_cnt(struct 
drm_framebuffer *fb)
 struct drm_framebuffer *
 exynos_drm_framebuffer_init(struct drm_device *dev,
struct drm_mode_fb_cmd2 *mode_cmd,
-   struct drm_gem_object *obj)
+   struct exynos_drm_gem_obj **gem_obj,
+   int count)
 {
struct exynos_drm_fb *exynos_fb;
-   struct exynos_drm_gem_obj *exynos_gem_obj;
+   int i;
int ret;

-   exynos_gem_obj = to_exynos_gem_obj(obj);
-
-   ret = check_fb_gem_memory_type(dev, exynos_gem_obj);
-   if (ret < 0)
-   return ERR_PTR(ret);
-
exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL);
if (!exynos_fb)
return ERR_PTR(-ENOMEM);

-   drm_helper_mode_fill_fb_struct(_fb->fb, mode_cmd);
-   exynos_fb->exynos_gem_obj[0] = exynos_gem_obj;
+   exynos_fb->buf_cnt = count;
+   DRM_DEBUG_KMS("buf_cnt = %d\n", exynos_fb->buf_cnt);

-   /* buffer count to framebuffer always is 1 at booting time. */
-   exynos_fb->buf_cnt = 1;
+   for (i = 0; i < count; i++) {
+   ret = check_fb_gem_memory_type(dev, gem_obj[i]);
+   if (ret < 0)
+   goto err;
+
+   exynos_fb->exynos_gem_obj[i] = gem_obj[i];
+   }
+
+   drm_helper_mode_fill_fb_struct(_fb->fb, mode_cmd);

ret = drm_framebuffer_init(dev, _fb->fb, _drm_fb_funcs);
-   if (ret) {
-   kfree(exynos_fb);
+   if (ret < 0) {
DRM_ERROR("failed to initialize framebuffer\n");
-   return ERR_PTR(ret);
+   goto err;
}

return _fb->fb;
+
+err:
+   kfree(exynos_fb);
+   return ERR_PTR(ret);
 }

 static struct drm_framebuffer *
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.h 
b/drivers/gpu/drm/exynos/exynos_drm_fb.h
index 897d2cf..8900f6b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.h
@@ -14,10 +14,13 @@
 #ifndef _EXYNOS_DRM_FB_H_
 #define _EXYNOS_DRM_FB_H

+#include "exynos_drm_gem.h"
+
 struct drm_framebuffer *
 exynos_drm_framebuffer_init(struct drm_device *dev,
struct drm_mode_fb_cmd2 *mode_cmd,
-   struct drm_gem_object *obj);
+   struct exynos_drm_gem_obj **gem_obj,
+   int count);

 /* get gem object of a drm framebuffer */
 struct exynos_drm_gem_obj *exynos_drm_fb_gem_obj(struct drm_framebuffer *fb,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c 
b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 133cf5f..a221f75 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -21,7 +21,6 @@
 #include "exynos_drm_drv.h"
 #include "exynos_drm_fb.h"
 #include "exynos_drm_fbdev.h"
-#include "exynos_drm_gem.h"
 #include "exynos_drm_iommu.h"

 #define MAX_CONNECTOR  4
@@ -160,7 +159,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper 
*helper,

exynos_fbdev->obj = obj;

-   helper->fb = exynos_drm_framebuffer_init(dev, _cmd, >base);
+   helper->fb = exynos_drm_framebuffer_init(dev, _cmd, , 1);
if (IS_ERR(helper->fb)) {
DRM_ERROR("failed to create drm framebuffer.\n");
ret = PTR_ERR(helper->fb);
-- 
1.9.1



[PATCH 5/9] drm/exynos: cleanup to get gem object for fb

2015-09-01 Thread Joonyoung Shim
Current codes get first gem object and then again get remain gem
objects. They can be unified to one routine.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_fb.c | 23 ---
 1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c 
b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index effeb64..5cee148 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -179,27 +179,18 @@ exynos_user_fb_create(struct drm_device *dev, struct 
drm_file *file_priv,
if (!exynos_fb)
return ERR_PTR(-ENOMEM);

-   obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
-   if (!obj) {
-   DRM_ERROR("failed to lookup gem object\n");
-   ret = -ENOENT;
-   goto err_free;
-   }
-
-   drm_helper_mode_fill_fb_struct(_fb->fb, mode_cmd);
-   exynos_fb->exynos_gem_obj[0] = to_exynos_gem_obj(obj);
exynos_fb->buf_cnt = drm_format_num_planes(mode_cmd->pixel_format);

DRM_DEBUG_KMS("buf_cnt = %d\n", exynos_fb->buf_cnt);

-   for (i = 1; i < exynos_fb->buf_cnt; i++) {
+   for (i = 0; i < exynos_fb->buf_cnt; i++) {
obj = drm_gem_object_lookup(dev, file_priv,
mode_cmd->handles[i]);
if (!obj) {
DRM_ERROR("failed to lookup gem object\n");
ret = -ENOENT;
exynos_fb->buf_cnt = i;
-   goto err_unreference;
+   goto err;
}

exynos_gem_obj = to_exynos_gem_obj(obj);
@@ -207,18 +198,20 @@ exynos_user_fb_create(struct drm_device *dev, struct 
drm_file *file_priv,

ret = check_fb_gem_memory_type(dev, exynos_gem_obj);
if (ret < 0)
-   goto err_unreference;
+   goto err;
}

+   drm_helper_mode_fill_fb_struct(_fb->fb, mode_cmd);
+
ret = drm_framebuffer_init(dev, _fb->fb, _drm_fb_funcs);
if (ret) {
DRM_ERROR("failed to init framebuffer.\n");
-   goto err_unreference;
+   goto err;
}

return _fb->fb;

-err_unreference:
+err:
for (i = 0; i < exynos_fb->buf_cnt; i++) {
struct drm_gem_object *obj;

@@ -226,7 +219,7 @@ err_unreference:
if (obj)
drm_gem_object_unreference_unlocked(obj);
}
-err_free:
+
kfree(exynos_fb);
return ERR_PTR(ret);
 }
-- 
1.9.1



[PATCH 4/9] drm/exynos: update fb_info via only one function

2015-09-01 Thread Joonyoung Shim
This patch moves codes to update fb_info into exynos_drm_fbdev_update(),
so fb_info is updated via only one function.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 29 +
 1 file changed, 13 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c 
b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 4ef8739..133cf5f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -78,12 +78,22 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper 
*helper,
   struct drm_fb_helper_surface_size *sizes,
   struct exynos_drm_gem_obj *obj)
 {
-   struct fb_info *fbi = helper->fbdev;
+   struct fb_info *fbi;
struct drm_framebuffer *fb = helper->fb;
unsigned int size = fb->width * fb->height * (fb->bits_per_pixel >> 3);
unsigned int nr_pages;
unsigned long offset;

+   fbi = drm_fb_helper_alloc_fbi(helper);
+   if (IS_ERR(fbi)) {
+   DRM_ERROR("failed to allocate fb info.\n");
+   return PTR_ERR(fbi);
+   }
+
+   fbi->par = helper;
+   fbi->flags = FBINFO_FLAG_DEFAULT;
+   fbi->fbops = _drm_fb_ops;
+
drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);

@@ -93,6 +103,7 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper 
*helper,
pgprot_writecombine(PAGE_KERNEL));
if (!obj->kvaddr) {
DRM_ERROR("failed to map pages to kernel space.\n");
+   drm_fb_helper_release_fbi(helper);
return -EIO;
}

@@ -112,7 +123,6 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper 
*helper,
struct exynos_drm_fbdev *exynos_fbdev = to_exynos_fbdev(helper);
struct exynos_drm_gem_obj *obj;
struct drm_device *dev = helper->dev;
-   struct fb_info *fbi;
struct drm_mode_fb_cmd2 mode_cmd = { 0 };
struct platform_device *pdev = dev->platformdev;
unsigned long size;
@@ -130,13 +140,6 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper 
*helper,

mutex_lock(>struct_mutex);

-   fbi = drm_fb_helper_alloc_fbi(helper);
-   if (IS_ERR(fbi)) {
-   DRM_ERROR("failed to allocate fb info.\n");
-   ret = PTR_ERR(fbi);
-   goto out;
-   }
-
size = mode_cmd.pitches[0] * mode_cmd.height;

obj = exynos_drm_gem_create(dev, EXYNOS_BO_CONTIG, size);
@@ -152,7 +155,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper 
*helper,

if (IS_ERR(obj)) {
ret = PTR_ERR(obj);
-   goto err_release_fbi;
+   goto out;
}

exynos_fbdev->obj = obj;
@@ -164,10 +167,6 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper 
*helper,
goto err_destroy_gem;
}

-   fbi->par = helper;
-   fbi->flags = FBINFO_FLAG_DEFAULT;
-   fbi->fbops = _drm_fb_ops;
-
ret = exynos_drm_fbdev_update(helper, sizes, obj);
if (ret < 0)
goto err_destroy_framebuffer;
@@ -179,8 +178,6 @@ err_destroy_framebuffer:
drm_framebuffer_cleanup(helper->fb);
 err_destroy_gem:
exynos_drm_gem_destroy(obj);
-err_release_fbi:
-   drm_fb_helper_release_fbi(helper);

 /*
  * if failed, all resources allocated above would be released by
-- 
1.9.1



[PATCH 3/9] drm/exynos: cleanup exynos_drm_fbdev_update()

2015-09-01 Thread Joonyoung Shim
It can get exynos_gem object via function argument, so no need to call
exynos_drm_fb_gem_obj() in exynos_drm_fbdev_update.

It also can get struct drm_framebuffer *fb via helper->fb, so can remove
a function argument for it.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 15 ---
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c 
b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 25170e2..4ef8739 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -75,11 +75,11 @@ static struct fb_ops exynos_drm_fb_ops = {
 };

 static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
-struct drm_fb_helper_surface_size *sizes,
-struct drm_framebuffer *fb)
+  struct drm_fb_helper_surface_size *sizes,
+  struct exynos_drm_gem_obj *obj)
 {
struct fb_info *fbi = helper->fbdev;
-   struct exynos_drm_gem_obj *obj;
+   struct drm_framebuffer *fb = helper->fb;
unsigned int size = fb->width * fb->height * (fb->bits_per_pixel >> 3);
unsigned int nr_pages;
unsigned long offset;
@@ -87,13 +87,6 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper 
*helper,
drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);

-   /* RGB formats use only one buffer */
-   obj = exynos_drm_fb_gem_obj(fb, 0);
-   if (!obj) {
-   DRM_DEBUG_KMS("gem object is null.\n");
-   return -EFAULT;
-   }
-
nr_pages = obj->size >> PAGE_SHIFT;

obj->kvaddr = (void __iomem *) vmap(obj->pages, nr_pages, VM_MAP,
@@ -175,7 +168,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper 
*helper,
fbi->flags = FBINFO_FLAG_DEFAULT;
fbi->fbops = _drm_fb_ops;

-   ret = exynos_drm_fbdev_update(helper, sizes, helper->fb);
+   ret = exynos_drm_fbdev_update(helper, sizes, obj);
if (ret < 0)
goto err_destroy_framebuffer;

-- 
1.9.1



[PATCH 2/9] drm/exynos: s/exynos_gem_obj/obj in exynos_drm_fbdev.c

2015-09-01 Thread Joonyoung Shim
The variable name "exynos_gem_obj" is too long, so some lines exceed 80
characters. It's simple to use "obj" instead of "exynos_gem_obj".

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 30 ++
 1 file changed, 14 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c 
b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 8188b1f..25170e2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -32,7 +32,7 @@

 struct exynos_drm_fbdev {
struct drm_fb_helperdrm_fb_helper;
-   struct exynos_drm_gem_obj   *exynos_gem_obj;
+   struct exynos_drm_gem_obj   *obj;
 };

 static int exynos_drm_fb_mmap(struct fb_info *info,
@@ -40,7 +40,7 @@ static int exynos_drm_fb_mmap(struct fb_info *info,
 {
struct drm_fb_helper *helper = info->par;
struct exynos_drm_fbdev *exynos_fbd = to_exynos_fbdev(helper);
-   struct exynos_drm_gem_obj *obj = exynos_fbd->exynos_gem_obj;
+   struct exynos_drm_gem_obj *obj = exynos_fbd->obj;
unsigned long vm_size;
int ret;

@@ -117,7 +117,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper 
*helper,
struct drm_fb_helper_surface_size *sizes)
 {
struct exynos_drm_fbdev *exynos_fbdev = to_exynos_fbdev(helper);
-   struct exynos_drm_gem_obj *exynos_gem_obj;
+   struct exynos_drm_gem_obj *obj;
struct drm_device *dev = helper->dev;
struct fb_info *fbi;
struct drm_mode_fb_cmd2 mode_cmd = { 0 };
@@ -146,27 +146,25 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper 
*helper,

size = mode_cmd.pitches[0] * mode_cmd.height;

-   exynos_gem_obj = exynos_drm_gem_create(dev, EXYNOS_BO_CONTIG, size);
+   obj = exynos_drm_gem_create(dev, EXYNOS_BO_CONTIG, size);
/*
 * If physically contiguous memory allocation fails and if IOMMU is
 * supported then try to get buffer from non physically contiguous
 * memory area.
 */
-   if (IS_ERR(exynos_gem_obj) && is_drm_iommu_supported(dev)) {
+   if (IS_ERR(obj) && is_drm_iommu_supported(dev)) {
dev_warn(>dev, "contiguous FB allocation failed, falling 
back to non-contiguous\n");
-   exynos_gem_obj = exynos_drm_gem_create(dev, EXYNOS_BO_NONCONTIG,
-   size);
+   obj = exynos_drm_gem_create(dev, EXYNOS_BO_NONCONTIG, size);
}

-   if (IS_ERR(exynos_gem_obj)) {
-   ret = PTR_ERR(exynos_gem_obj);
+   if (IS_ERR(obj)) {
+   ret = PTR_ERR(obj);
goto err_release_fbi;
}

-   exynos_fbdev->exynos_gem_obj = exynos_gem_obj;
+   exynos_fbdev->obj = obj;

-   helper->fb = exynos_drm_framebuffer_init(dev, _cmd,
-   _gem_obj->base);
+   helper->fb = exynos_drm_framebuffer_init(dev, _cmd, >base);
if (IS_ERR(helper->fb)) {
DRM_ERROR("failed to create drm framebuffer.\n");
ret = PTR_ERR(helper->fb);
@@ -187,7 +185,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper 
*helper,
 err_destroy_framebuffer:
drm_framebuffer_cleanup(helper->fb);
 err_destroy_gem:
-   exynos_drm_gem_destroy(exynos_gem_obj);
+   exynos_drm_gem_destroy(obj);
 err_release_fbi:
drm_fb_helper_release_fbi(helper);

@@ -282,11 +280,11 @@ static void exynos_drm_fbdev_destroy(struct drm_device 
*dev,
  struct drm_fb_helper *fb_helper)
 {
struct exynos_drm_fbdev *exynos_fbd = to_exynos_fbdev(fb_helper);
-   struct exynos_drm_gem_obj *exynos_gem_obj = exynos_fbd->exynos_gem_obj;
+   struct exynos_drm_gem_obj *obj = exynos_fbd->obj;
struct drm_framebuffer *fb;

-   if (exynos_gem_obj->kvaddr)
-   vunmap(exynos_gem_obj->kvaddr);
+   if (obj->kvaddr)
+   vunmap(obj->kvaddr);

/* release drm framebuffer and real buffer */
if (fb_helper->fb && fb_helper->fb->funcs) {
-- 
1.9.1



[PATCH 1/9] drm/exynos: remove exynos_drm_fb_set_buf_cnt()

2015-09-01 Thread Joonyoung Shim
The exynos_drm_fb_set_buf_cnt() is used to set buffer count only in
exynos_drm_fbdev_update(). This patch sets directly buffer count in
exynos_drm_framebuffer_init() without using exynos_drm_fb_set_buf_cnt(),
so there is no any reason to keep exynos_drm_fb_set_buf_cnt().

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_fb.c| 13 +++--
 drivers/gpu/drm/exynos/exynos_drm_fb.h|  4 
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |  3 ---
 3 files changed, 3 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c 
b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index 9738f4e..effeb64 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -122,16 +122,6 @@ static struct drm_framebuffer_funcs exynos_drm_fb_funcs = {
.dirty  = exynos_drm_fb_dirty,
 };

-void exynos_drm_fb_set_buf_cnt(struct drm_framebuffer *fb,
-   unsigned int cnt)
-{
-   struct exynos_drm_fb *exynos_fb;
-
-   exynos_fb = to_exynos_fb(fb);
-
-   exynos_fb->buf_cnt = cnt;
-}
-
 unsigned int exynos_drm_fb_get_buf_cnt(struct drm_framebuffer *fb)
 {
struct exynos_drm_fb *exynos_fb;
@@ -163,6 +153,9 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
drm_helper_mode_fill_fb_struct(_fb->fb, mode_cmd);
exynos_fb->exynos_gem_obj[0] = exynos_gem_obj;

+   /* buffer count to framebuffer always is 1 at booting time. */
+   exynos_fb->buf_cnt = 1;
+
ret = drm_framebuffer_init(dev, _fb->fb, _drm_fb_funcs);
if (ret) {
kfree(exynos_fb);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.h 
b/drivers/gpu/drm/exynos/exynos_drm_fb.h
index 1c9e27c..897d2cf 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.h
@@ -25,10 +25,6 @@ struct exynos_drm_gem_obj *exynos_drm_fb_gem_obj(struct 
drm_framebuffer *fb,

 void exynos_drm_mode_config_init(struct drm_device *dev);

-/* set a buffer count to drm framebuffer. */
-void exynos_drm_fb_set_buf_cnt(struct drm_framebuffer *fb,
-   unsigned int cnt);
-
 /* get a buffer count to drm framebuffer. */
 unsigned int exynos_drm_fb_get_buf_cnt(struct drm_framebuffer *fb);

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c 
b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 624595a..8188b1f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -103,9 +103,6 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper 
*helper,
return -EIO;
}

-   /* buffer count to framebuffer always is 1 at booting time. */
-   exynos_drm_fb_set_buf_cnt(fb, 1);
-
offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3);
offset += fbi->var.yoffset * fb->pitches[0];

-- 
1.9.1



[PATCH 0/9] drm/exynos: cleanup patchset for exynos_drm_fb/fbdev

2015-09-01 Thread Joonyoung Shim
Hi,

This patchset is for cleanup about fb and fbdev codes of exynos-drm
driver. This removes unnecesary and redundant codes mostly, and make a
variable having too long name to be short.

Thanks.

Joonyoung Shim (9):
  drm/exynos: remove exynos_drm_fb_set_buf_cnt()
  drm/exynos: s/exynos_gem_obj/obj in exynos_drm_fbdev.c
  drm/exynos: cleanup exynos_drm_fbdev_update()
  drm/exynos: update fb_info via only one function
  drm/exynos: cleanup to get gem object for fb
  drm/exynos: update exynos_drm_framebuffer_init() for multiple buffers
  drm/exynos: cleanup exynos_user_fb_create()
  drm/exynos: remove exynos_drm_fb_get_buf_cnt()
  drm/exynos: remove buf_cnt from struct exynos_drm_fb

 drivers/gpu/drm/exynos/exynos_drm_fb.c| 115 +-
 drivers/gpu/drm/exynos/exynos_drm_fb.h|  12 ++--
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |  78 
 drivers/gpu/drm/exynos/exynos_drm_plane.c |   2 +-
 4 files changed, 69 insertions(+), 138 deletions(-)


[PATCH] drm/exynos: fix exynos_drm_gem_prime_import_sg_table() error handling

2015-09-01 Thread Joonyoung Shim
On 08/31/2015 01:10 AM, Inki Dae wrote:
> 2015-08-27 17:31 GMT+09:00 Joonyoung Shim :
>> If exynos_drm_gem_init() is failed, the result is ERR_PTR, so we should
>> just return the result. If not, wrong porinter will be referenced from
>> err label.
>>
>> Reported-by: Dan Carpenter 
>> Signed-off-by: Joonyoung Shim 
>> ---
>>  drivers/gpu/drm/exynos/exynos_drm_gem.c | 6 ++
>>  1 file changed, 2 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
>> b/drivers/gpu/drm/exynos/exynos_drm_gem.c
>> index 3e4a64a..4842a31 100644
>> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
>> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
>> @@ -569,10 +569,8 @@ exynos_drm_gem_prime_import_sg_table(struct drm_device 
>> *dev,
>> int ret;
>>
>> exynos_gem_obj = exynos_drm_gem_init(dev, attach->dmabuf->size);
>> -   if (IS_ERR(exynos_gem_obj)) {
>> -   ret = PTR_ERR(exynos_gem_obj);
>> -   goto err;
>> -   }
>> +   if (IS_ERR(exynos_gem_obj))
>> +   return exynos_gem_obj;
> 
> This patch incurs below build warning,
> 
> drivers/gpu/drm/exynos/exynos_drm_gem.c: In function
> 'exynos_drm_gem_prime_import_sg_table':
> drivers/gpu/drm/exynos/exynos_drm_gem.c:670:3: warning: return from
> incompatible pointer type [enabled by default]

Oops, i didn't check this warning.

> 
> We can simply return ERR_PTR(ret) and I just fixed it.
> 

Is it better to just return (void *)exynos_gem_obj instead of exynos_gem_obj?


[PATCH] drm/exynos: fix exynos_drm_gem_prime_import_sg_table() error handling

2015-08-27 Thread Joonyoung Shim
If exynos_drm_gem_init() is failed, the result is ERR_PTR, so we should
just return the result. If not, wrong porinter will be referenced from
err label.

Reported-by: Dan Carpenter 
Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 3e4a64a..4842a31 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -569,10 +569,8 @@ exynos_drm_gem_prime_import_sg_table(struct drm_device 
*dev,
int ret;

exynos_gem_obj = exynos_drm_gem_init(dev, attach->dmabuf->size);
-   if (IS_ERR(exynos_gem_obj)) {
-   ret = PTR_ERR(exynos_gem_obj);
-   goto err;
-   }
+   if (IS_ERR(exynos_gem_obj))
+   return exynos_gem_obj;

exynos_gem_obj->dma_addr = sg_dma_address(sgt->sgl);

-- 
1.9.1



[PATCH 09/14] drm/exynos: remove call to drm_gem_free_mmap_offset()

2015-08-17 Thread Joonyoung Shim
On 08/17/2015 04:52 PM, Inki Dae wrote:
> On 2015년 08월 17일 14:29, Joonyoung Shim wrote:
>> On 08/16/2015 02:07 PM, Inki Dae wrote:
>>> On 2015년 07월 28일 17:53, Joonyoung Shim wrote:
>>>> The drm_gem_object_release() function already performs this cleanup,
>>>> so there is no reason to do it explicitly.
>>>>
>>>> Signed-off-by: Joonyoung Shim 
>>>> ---
>>>>  drivers/gpu/drm/exynos/exynos_drm_gem.c | 3 ---
>>>>  1 file changed, 3 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
>>>> b/drivers/gpu/drm/exynos/exynos_drm_gem.c
>>>> index c76aa8a..ab7d029 100644
>>>> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
>>>> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
>>>> @@ -100,8 +100,6 @@ out:
>>>>exynos_drm_fini_buf(obj->dev, buf);
>>>>exynos_gem_obj->buffer = NULL;
>>>>  
>>>> -  drm_gem_free_mmap_offset(obj);
>>>> -
>>>>/* release file pointer to gem object. */
>>>>drm_gem_object_release(obj);
>>>>  
>>>> @@ -600,7 +598,6 @@ int exynos_drm_gem_mmap(struct file *filp, struct 
>>>> vm_area_struct *vma)
>>>>  
>>>>  err_close_vm:
>>>>drm_gem_vm_close(vma);
>>>> -  drm_gem_free_mmap_offset(obj);
>>>
>>> Without previous patch, drm_gem_free_mmap_offset is required. I guess
>>> the reason you removed above line is that you thought
>>> drm_gem_object_release function would be called by drm_gem_vm_close
>>> function which drops a reference of the gem object.
>>>
>>> However, drm_gem_vm_close should be a pair with drm_gem_vm_open
>>> function. These will be called whenever a process opens or closes the
>>> VMA. So the reference count of the gem object had already been taken by
>>> open operation when a new reference to the VMA had been created.
>>>
>>
>> This changes is not related with drm_gem_vm_close and prior patch. Why
>> should free mmap offset when mmap operation is failed? The mmap offset
>> can be used repeatedly.
> 
> Isn't vm space of vm manager still used even if any user-space process
> doesn't use the region? And if mmap is failed, then the user-space
> process will be terminated. Do you think it can be re-tried? However,
> mmap system call never return -EAGAIN. Is it reasonable to you? I cannot
> understand how the mmap offset can be re-used. So can you show me some
> example?
> 

Currently, mmap offset of exynos-drm gem is made by 
DRM_IOCTL_MODE_MAP_DUMB ioctl and mmap() ioctl just uses the mmap 
offset. User will use same mmap offset about same gem. It's why mmap
offset made by DRM_IOCTL_MODE_MAP_DUMB ioctl is unnecessary, it's just
enough to make mmap offset from when gem is create. You can get a
reference from drm_gem_cma_helper.c file.


[PATCH 09/14] drm/exynos: remove call to drm_gem_free_mmap_offset()

2015-08-17 Thread Joonyoung Shim
On 08/16/2015 02:07 PM, Inki Dae wrote:
> On 2015년 07월 28일 17:53, Joonyoung Shim wrote:
>> The drm_gem_object_release() function already performs this cleanup,
>> so there is no reason to do it explicitly.
>>
>> Signed-off-by: Joonyoung Shim 
>> ---
>>  drivers/gpu/drm/exynos/exynos_drm_gem.c | 3 ---
>>  1 file changed, 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
>> b/drivers/gpu/drm/exynos/exynos_drm_gem.c
>> index c76aa8a..ab7d029 100644
>> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
>> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
>> @@ -100,8 +100,6 @@ out:
>>  exynos_drm_fini_buf(obj->dev, buf);
>>  exynos_gem_obj->buffer = NULL;
>>  
>> -drm_gem_free_mmap_offset(obj);
>> -
>>  /* release file pointer to gem object. */
>>  drm_gem_object_release(obj);
>>  
>> @@ -600,7 +598,6 @@ int exynos_drm_gem_mmap(struct file *filp, struct 
>> vm_area_struct *vma)
>>  
>>  err_close_vm:
>>  drm_gem_vm_close(vma);
>> -drm_gem_free_mmap_offset(obj);
> 
> Without previous patch, drm_gem_free_mmap_offset is required. I guess
> the reason you removed above line is that you thought
> drm_gem_object_release function would be called by drm_gem_vm_close
> function which drops a reference of the gem object.
> 
> However, drm_gem_vm_close should be a pair with drm_gem_vm_open
> function. These will be called whenever a process opens or closes the
> VMA. So the reference count of the gem object had already been taken by
> open operation when a new reference to the VMA had been created.
> 

This changes is not related with drm_gem_vm_close and prior patch. Why
should free mmap offset when mmap operation is failed? The mmap offset
can be used repeatedly.


[PATCH 08/14] drm/exynos: create a fake mmap offset with gem creation

2015-08-17 Thread Joonyoung Shim
On 08/16/2015 01:50 PM, Inki Dae wrote:
> On 2015년 07월 28일 17:53, Joonyoung Shim wrote:
>> Don't create a fake mmap offset in exynos_drm_gem_dumb_map_offset. If
>> not, it will call drm_gem_create_mmap_offset whenever user requests
>> DRM_IOCTL_MODE_MAP_DUMB ioctl.
> 
> This patch makes drm_gem_create_mmap_offset to be called even in case of
> not using dumb* interfaces. I.e.,
> exynos_drm_gem_create_ioctl -> exynos_drm_gem_mmap
> 

I know mmap() of exynos-drm also needs mmap offset in drm_gem_mmap().

> And drm_gem_create_mmap_offset checks if vma_node was already allocated
> or not so this patch doesn't make sense.
> 

OK, but it calls drm_gem_create_mmap_offset still and will be returned
after checking node->allocated. It's not unnecessary to me.

> Thanks,
> Inki Dae
> 
>>
>> Signed-off-by: Joonyoung Shim 
>> ---
>>  drivers/gpu/drm/exynos/exynos_drm_gem.c | 12 +++-
>>  1 file changed, 7 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
>> b/drivers/gpu/drm/exynos/exynos_drm_gem.c
>> index 550d267..c76aa8a 100644
>> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
>> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
>> @@ -151,6 +151,13 @@ struct exynos_drm_gem_obj *exynos_drm_gem_init(struct 
>> drm_device *dev,
>>  return ERR_PTR(ret);
>>  }
>>  
>> +ret = drm_gem_create_mmap_offset(obj);
>> +if (ret < 0) {
>> +drm_gem_object_release(obj);
>> +kfree(exynos_gem_obj);
>> +return ERR_PTR(ret);
>> +}
>> +
>>  DRM_DEBUG_KMS("created file object = 0x%x\n", (unsigned int)obj->filp);
>>  
>>  return exynos_gem_obj;
>> @@ -521,14 +528,9 @@ int exynos_drm_gem_dumb_map_offset(struct drm_file 
>> *file_priv,
>>  goto unlock;
>>  }
>>  
>> -ret = drm_gem_create_mmap_offset(obj);
>> -if (ret)
>> -goto out;
>> -
>>  *offset = drm_vma_node_offset_addr(>vma_node);
>>  DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset);
>>  
>> -out:
>>  drm_gem_object_unreference(obj);
>>  unlock:
>>  mutex_unlock(>struct_mutex);
>>
> 
> 



[PATCH 10/14] drm/exynos: remove function check_gem_flags

2015-08-11 Thread Joonyoung Shim
On 08/06/2015 07:00 PM, Daniel Stone wrote:
> Hi Joonyoung,
> 
> On 28 July 2015 at 09:53, Joonyoung Shim  wrote:
>>  static void update_vm_cache_attr(struct exynos_drm_gem_obj *obj,
>> struct vm_area_struct *vma)
>>  {
>> @@ -169,6 +159,11 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct 
>> drm_device *dev,
>> struct exynos_drm_gem_buf *buf;
>> int ret;
>>
>> +   if (flags & ~(EXYNOS_BO_MASK)) {
>> +   DRM_ERROR("invalid flags.\n");
>> +   return ERR_PTR(-EINVAL);
>> +   }
>> +
>> if (!size) {
>> DRM_ERROR("invalid size.\n");
>> return ERR_PTR(-EINVAL);
>> @@ -176,10 +171,6 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct 
>> drm_device *dev,
>>
>> size = roundup_gem_size(size, flags);
>>
>> -   ret = check_gem_flags(flags);
>> -   if (ret)
>> -   return ERR_PTR(ret);
>> -
>> buf = exynos_drm_init_buf(dev, size);
>> if (!buf)
>> return ERR_PTR(-ENOMEM);
>> @@ -584,9 +575,10 @@ int exynos_drm_gem_mmap(struct file *filp, struct 
>> vm_area_struct *vma)
>> obj = vma->vm_private_data;
>> exynos_gem_obj = to_exynos_gem_obj(obj);
>>
>> -   ret = check_gem_flags(exynos_gem_obj->flags);
>> -   if (ret)
>> +   if (exynos_gem_obj->flags & ~(EXYNOS_BO_MASK)) {
>> +   DRM_ERROR("invalid flags.\n");
>> goto err_close_vm;
>> +   }
> 
> This check should be removed, or turned into a WARN_ON: there is no
> way for the user to control the GEM object flags except through the
> create ioctl, no?
> 

Right, your point is reasonable to me.

Thanks.


[PATCH 14/14] drm/exynos: merge exynos_drm_buf.c to exynos_drm_gem.c

2015-07-28 Thread Joonyoung Shim
The struct exynos_drm_gem_obj can have fields of the struct
exynos_drm_gem_buf then don't need to use exynos_drm_buf.c file.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/Makefile   |   3 +-
 drivers/gpu/drm/exynos/exynos_drm_buf.c   | 170 
 drivers/gpu/drm/exynos/exynos_drm_buf.h   |  33 -
 drivers/gpu/drm/exynos/exynos_drm_fb.c|  14 +-
 drivers/gpu/drm/exynos/exynos_drm_fb.h|   4 +-
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |  30 ++---
 drivers/gpu/drm/exynos/exynos_drm_gem.c   | 209 +++---
 drivers/gpu/drm/exynos/exynos_drm_gem.h   |  40 +++---
 drivers/gpu/drm/exynos/exynos_drm_plane.c |  10 +-
 9 files changed, 179 insertions(+), 334 deletions(-)
 delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_buf.c
 delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_buf.h

diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 95d0306..9c72535 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -5,8 +5,7 @@
 ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/exynos
 exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o \
exynos_drm_crtc.o exynos_drm_fbdev.o exynos_drm_fb.o \
-   exynos_drm_buf.o exynos_drm_gem.o exynos_drm_core.o \
-   exynos_drm_plane.o
+   exynos_drm_gem.o exynos_drm_core.o exynos_drm_plane.o

 exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)+= exynos_drm_fimd.o
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c 
b/drivers/gpu/drm/exynos/exynos_drm_buf.c
deleted file mode 100644
index 9260dfb..000
--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/* exynos_drm_buf.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * Author: Inki Dae 
- *
- * 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 
-#include 
-
-#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)
-{
-   int ret = 0;
-   enum dma_attr attr;
-   unsigned int nr_pages;
-
-   if (buf->dma_addr) {
-   DRM_DEBUG_KMS("already allocated.\n");
-   return 0;
-   }
-
-   init_dma_attrs(>dma_attrs);
-
-   /*
-* if EXYNOS_BO_CONTIG, fully physically contiguous memory
-* region will be allocated else physically contiguous
-* as possible.
-*/
-   if (!(flags & EXYNOS_BO_NONCONTIG))
-   dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, >dma_attrs);
-
-   /*
-* if EXYNOS_BO_WC or EXYNOS_BO_NONCACHABLE, writecombine mapping
-* else cachable mapping.
-*/
-   if (flags & EXYNOS_BO_WC || !(flags & EXYNOS_BO_CACHABLE))
-   attr = DMA_ATTR_WRITE_COMBINE;
-   else
-   attr = DMA_ATTR_NON_CONSISTENT;
-
-   dma_set_attr(attr, >dma_attrs);
-   dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, >dma_attrs);
-
-   nr_pages = buf->size >> PAGE_SHIFT;
-
-   if (!is_drm_iommu_supported(dev)) {
-   dma_addr_t start_addr;
-   unsigned int i = 0;
-
-   buf->pages = drm_calloc_large(nr_pages, sizeof(struct page *));
-   if (!buf->pages) {
-   DRM_ERROR("failed to allocate pages.\n");
-   return -ENOMEM;
-   }
-
-   buf->cookie = dma_alloc_attrs(dev->dev,
-   buf->size,
-   >dma_addr, GFP_KERNEL,
-   >dma_attrs);
-   if (!buf->cookie) {
-   DRM_ERROR("failed to allocate buffer.\n");
-   ret = -ENOMEM;
-   goto err_free;
-   }
-
-   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,
-   >dma_addr, GFP_KERNEL,
-   >dma_attrs);
-   if (!buf->pages) {
-   DRM_ERROR("failed to allocate buffer.\n");
-   return -ENOMEM;
-   }
-   }
-
-   DRM_

[PATCH 13/14] drm/exynos: use prime helpers

2015-07-28 Thread Joonyoung Shim
The dma-buf codes of exynos drm is almost same with prime helpers. A
difference is that consider DMA_NONE when import dma-buf, but it's wrong
and we don't consider it any more, so we can use prime interface.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/Makefile|   2 +-
 drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | 289 -
 drivers/gpu/drm/exynos/exynos_drm_dmabuf.h |  20 --
 drivers/gpu/drm/exynos/exynos_drm_drv.c|   9 +-
 drivers/gpu/drm/exynos/exynos_drm_gem.c|  79 
 drivers/gpu/drm/exynos/exynos_drm_gem.h|   9 +
 6 files changed, 95 insertions(+), 313 deletions(-)
 delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
 delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_dmabuf.h

diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 7de0b10..95d0306 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -6,7 +6,7 @@ ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/exynos
 exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o \
exynos_drm_crtc.o exynos_drm_fbdev.o exynos_drm_fb.o \
exynos_drm_buf.o exynos_drm_gem.o exynos_drm_core.o \
-   exynos_drm_plane.o exynos_drm_dmabuf.o
+   exynos_drm_plane.o

 exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)+= exynos_drm_fimd.o
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c 
b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
deleted file mode 100644
index 619ecdd..000
--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/* exynos_drm_dmabuf.c
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd.
- * Author: Inki Dae 
- *
- * 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 
-#include 
-#include "exynos_drm_dmabuf.h"
-#include "exynos_drm_drv.h"
-#include "exynos_drm_gem.h"
-
-#include 
-
-struct exynos_drm_dmabuf_attachment {
-   struct sg_table *sgt;
-   enum dma_data_direction dir;
-   bool is_mapped;
-};
-
-static struct exynos_drm_gem_obj *dma_buf_to_obj(struct dma_buf *buf)
-{
-   return to_exynos_gem_obj(buf->priv);
-}
-
-static int exynos_gem_attach_dma_buf(struct dma_buf *dmabuf,
-   struct device *dev,
-   struct dma_buf_attachment *attach)
-{
-   struct exynos_drm_dmabuf_attachment *exynos_attach;
-
-   exynos_attach = kzalloc(sizeof(*exynos_attach), GFP_KERNEL);
-   if (!exynos_attach)
-   return -ENOMEM;
-
-   exynos_attach->dir = DMA_NONE;
-   attach->priv = exynos_attach;
-
-   return 0;
-}
-
-static void exynos_gem_detach_dma_buf(struct dma_buf *dmabuf,
-   struct dma_buf_attachment *attach)
-{
-   struct exynos_drm_dmabuf_attachment *exynos_attach = attach->priv;
-   struct sg_table *sgt;
-
-   if (!exynos_attach)
-   return;
-
-   sgt = exynos_attach->sgt;
-   if (sgt) {
-   if (exynos_attach->dir != DMA_NONE)
-   dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents,
-   exynos_attach->dir);
-   sg_free_table(sgt);
-   }
-
-   kfree(sgt);
-   kfree(exynos_attach);
-   attach->priv = NULL;
-}
-
-static struct sg_table *
-   exynos_gem_map_dma_buf(struct dma_buf_attachment *attach,
-   enum dma_data_direction dir)
-{
-   struct exynos_drm_dmabuf_attachment *exynos_attach = attach->priv;
-   struct exynos_drm_gem_obj *gem_obj = dma_buf_to_obj(attach->dmabuf);
-   struct exynos_drm_gem_buf *buf;
-   struct sg_table *sgt;
-   int npages;
-
-   /* just return current sgt if already requested. */
-   if (exynos_attach->dir == dir && exynos_attach->is_mapped)
-   return exynos_attach->sgt;
-
-   buf = gem_obj->buffer;
-   if (!buf) {
-   DRM_ERROR("buffer is null.\n");
-   return ERR_PTR(-ENOMEM);
-   }
-
-   npages = buf->size >> PAGE_SHIFT;
-
-   sgt = drm_prime_pages_to_sg(buf->pages, npages);
-   if (IS_ERR(sgt))
-   goto err;
-
-   if (dir != DMA_NONE) {
-   if (!dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir)) {
-   DRM_ERROR("failed to map sgl with iommu.\n");
-   sg_free_table(sgt);
-   sgt = ERR_PTR(-EIO);
-   goto err;
-   }
-   }
-
-   exynos_attach->is_mapped = true

[PATCH 12/14] drm/exynos: remove function roundup_gem_size

2015-07-28 Thread Joonyoung Shim
The function roundup_gem_size can be merged in exynos_drm_gem_create.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 9 +
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 55c64cf..9df100f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -20,13 +20,6 @@
 #include "exynos_drm_buf.h"
 #include "exynos_drm_iommu.h"

-static unsigned long roundup_gem_size(unsigned long size, unsigned int flags)
-{
-   /* TODO */
-
-   return roundup(size, PAGE_SIZE);
-}
-
 static int exynos_drm_gem_handle_create(struct drm_gem_object *obj,
struct drm_file *file_priv,
unsigned int *handle)
@@ -153,7 +146,7 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct 
drm_device *dev,
return ERR_PTR(-EINVAL);
}

-   size = roundup_gem_size(size, flags);
+   size = roundup(size, PAGE_SIZE);

buf = exynos_drm_init_buf(dev, size);
if (!buf)
-- 
1.9.1



[PATCH 11/14] drm/exynos: remove function update_vm_cache_attr

2015-07-28 Thread Joonyoung Shim
The function update_vm_cache_attr can be merged in exynos_drm_gem_mmap.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 28 +++-
 1 file changed, 11 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 03e85d8..55c64cf 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -20,22 +20,6 @@
 #include "exynos_drm_buf.h"
 #include "exynos_drm_iommu.h"

-static void update_vm_cache_attr(struct exynos_drm_gem_obj *obj,
-   struct vm_area_struct *vma)
-{
-   DRM_DEBUG_KMS("flags = 0x%x\n", obj->flags);
-
-   /* non-cachable as default. */
-   if (obj->flags & EXYNOS_BO_CACHABLE)
-   vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
-   else if (obj->flags & EXYNOS_BO_WC)
-   vma->vm_page_prot =
-   pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
-   else
-   vma->vm_page_prot =
-   pgprot_noncached(vm_get_page_prot(vma->vm_flags));
-}
-
 static unsigned long roundup_gem_size(unsigned long size, unsigned int flags)
 {
/* TODO */
@@ -580,7 +564,17 @@ int exynos_drm_gem_mmap(struct file *filp, struct 
vm_area_struct *vma)
goto err_close_vm;
}

-   update_vm_cache_attr(exynos_gem_obj, vma);
+   DRM_DEBUG_KMS("flags = 0x%x\n", exynos_gem_obj->flags);
+
+   /* non-cachable as default. */
+   if (exynos_gem_obj->flags & EXYNOS_BO_CACHABLE)
+   vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+   else if (exynos_gem_obj->flags & EXYNOS_BO_WC)
+   vma->vm_page_prot =
+   pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+   else
+   vma->vm_page_prot =
+   pgprot_noncached(vm_get_page_prot(vma->vm_flags));

ret = exynos_drm_gem_mmap_buffer(exynos_gem_obj, vma);
if (ret)
-- 
1.9.1



[PATCH 10/14] drm/exynos: remove function check_gem_flags

2015-07-28 Thread Joonyoung Shim
The function check_gem_flags is too simple, so it's better to move codes
in each consumer functions.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 24 
 1 file changed, 8 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index ab7d029..03e85d8 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -20,16 +20,6 @@
 #include "exynos_drm_buf.h"
 #include "exynos_drm_iommu.h"

-static int check_gem_flags(unsigned int flags)
-{
-   if (flags & ~(EXYNOS_BO_MASK)) {
-   DRM_ERROR("invalid flags.\n");
-   return -EINVAL;
-   }
-
-   return 0;
-}
-
 static void update_vm_cache_attr(struct exynos_drm_gem_obj *obj,
struct vm_area_struct *vma)
 {
@@ -169,6 +159,11 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct 
drm_device *dev,
struct exynos_drm_gem_buf *buf;
int ret;

+   if (flags & ~(EXYNOS_BO_MASK)) {
+   DRM_ERROR("invalid flags.\n");
+   return ERR_PTR(-EINVAL);
+   }
+
if (!size) {
DRM_ERROR("invalid size.\n");
return ERR_PTR(-EINVAL);
@@ -176,10 +171,6 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct 
drm_device *dev,

size = roundup_gem_size(size, flags);

-   ret = check_gem_flags(flags);
-   if (ret)
-   return ERR_PTR(ret);
-
buf = exynos_drm_init_buf(dev, size);
if (!buf)
return ERR_PTR(-ENOMEM);
@@ -584,9 +575,10 @@ int exynos_drm_gem_mmap(struct file *filp, struct 
vm_area_struct *vma)
obj = vma->vm_private_data;
exynos_gem_obj = to_exynos_gem_obj(obj);

-   ret = check_gem_flags(exynos_gem_obj->flags);
-   if (ret)
+   if (exynos_gem_obj->flags & ~(EXYNOS_BO_MASK)) {
+   DRM_ERROR("invalid flags.\n");
goto err_close_vm;
+   }

update_vm_cache_attr(exynos_gem_obj, vma);

-- 
1.9.1



[PATCH 09/14] drm/exynos: remove call to drm_gem_free_mmap_offset()

2015-07-28 Thread Joonyoung Shim
The drm_gem_object_release() function already performs this cleanup,
so there is no reason to do it explicitly.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index c76aa8a..ab7d029 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -100,8 +100,6 @@ out:
exynos_drm_fini_buf(obj->dev, buf);
exynos_gem_obj->buffer = NULL;

-   drm_gem_free_mmap_offset(obj);
-
/* release file pointer to gem object. */
drm_gem_object_release(obj);

@@ -600,7 +598,6 @@ int exynos_drm_gem_mmap(struct file *filp, struct 
vm_area_struct *vma)

 err_close_vm:
drm_gem_vm_close(vma);
-   drm_gem_free_mmap_offset(obj);

return ret;
 }
-- 
1.9.1



[PATCH 08/14] drm/exynos: create a fake mmap offset with gem creation

2015-07-28 Thread Joonyoung Shim
Don't create a fake mmap offset in exynos_drm_gem_dumb_map_offset. If
not, it will call drm_gem_create_mmap_offset whenever user requests
DRM_IOCTL_MODE_MAP_DUMB ioctl.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 550d267..c76aa8a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -151,6 +151,13 @@ struct exynos_drm_gem_obj *exynos_drm_gem_init(struct 
drm_device *dev,
return ERR_PTR(ret);
}

+   ret = drm_gem_create_mmap_offset(obj);
+   if (ret < 0) {
+   drm_gem_object_release(obj);
+   kfree(exynos_gem_obj);
+   return ERR_PTR(ret);
+   }
+
DRM_DEBUG_KMS("created file object = 0x%x\n", (unsigned int)obj->filp);

return exynos_gem_obj;
@@ -521,14 +528,9 @@ int exynos_drm_gem_dumb_map_offset(struct drm_file 
*file_priv,
goto unlock;
}

-   ret = drm_gem_create_mmap_offset(obj);
-   if (ret)
-   goto out;
-
*offset = drm_vma_node_offset_addr(>vma_node);
DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset);

-out:
drm_gem_object_unreference(obj);
 unlock:
mutex_unlock(>struct_mutex);
-- 
1.9.1



[PATCH 07/14] drm/exynos: use ERR_PTR instead of NULL in exynos_drm_gem_init

2015-07-28 Thread Joonyoung Shim
For more correct error information.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 8fffc4d..550d267 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -139,7 +139,7 @@ struct exynos_drm_gem_obj *exynos_drm_gem_init(struct 
drm_device *dev,

exynos_gem_obj = kzalloc(sizeof(*exynos_gem_obj), GFP_KERNEL);
if (!exynos_gem_obj)
-   return NULL;
+   return ERR_PTR(-ENOMEM);

exynos_gem_obj->size = size;
obj = _gem_obj->base;
@@ -148,7 +148,7 @@ struct exynos_drm_gem_obj *exynos_drm_gem_init(struct 
drm_device *dev,
if (ret < 0) {
DRM_ERROR("failed to initialize gem object\n");
kfree(exynos_gem_obj);
-   return NULL;
+   return ERR_PTR(ret);
}

DRM_DEBUG_KMS("created file object = 0x%x\n", (unsigned int)obj->filp);
@@ -180,8 +180,8 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct 
drm_device *dev,
return ERR_PTR(-ENOMEM);

exynos_gem_obj = exynos_drm_gem_init(dev, size);
-   if (!exynos_gem_obj) {
-   ret = -ENOMEM;
+   if (IS_ERR(exynos_gem_obj)) {
+   ret = PTR_ERR(exynos_gem_obj);
goto err_fini_buf;
}

-- 
1.9.1



[PATCH 06/14] drm/exynos: remove unused fields of struct exynos_drm_gem_buf

2015-07-28 Thread Joonyoung Shim
The userptr, write and pfnmap of struct exynos_drm_gem_buf are not used
anywhere.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.h | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h 
b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 5979f22..49b5ef1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -24,26 +24,19 @@
  *
  * @cookie: cookie returned by dma_alloc_attrs
  * @kvaddr: kernel virtual address to allocated memory region.
- * *userptr: user space address.
  * @dma_addr: bus address(accessed by dma) to allocated memory region.
  * - this address could be physical address without IOMMU and
  * device address with IOMMU.
- * @write: whether pages will be written to by the caller.
  * @pages: Array of backing pages.
  * @size: size of allocated memory region.
- * @pfnmap: indicate whether memory region from userptr is mmaped with
- * VM_PFNMAP or not.
  */
 struct exynos_drm_gem_buf {
void*cookie;
void __iomem*kvaddr;
-   unsigned long   userptr;
dma_addr_t  dma_addr;
struct dma_attrsdma_attrs;
-   unsigned intwrite;
struct page **pages;
unsigned long   size;
-   boolpfnmap;
 };

 /*
-- 
1.9.1



[PATCH 05/14] drm/exynos: stop copying sg table

2015-07-28 Thread Joonyoung Shim
Already struct exynos_drm_gem_buf has pages of the buffer, so we don't
need to copy from sg table of the buffer to sg table of dma-buf
attachment, just can make sg table from pages of the buffer.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | 55 +++---
 drivers/gpu/drm/exynos/exynos_drm_gem.c|  3 --
 drivers/gpu/drm/exynos/exynos_drm_gem.h|  2 --
 3 files changed, 20 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c 
b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
index d10f9b6..619ecdd 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
@@ -18,7 +18,7 @@
 #include 

 struct exynos_drm_dmabuf_attachment {
-   struct sg_table sgt;
+   struct sg_table *sgt;
enum dma_data_direction dir;
bool is_mapped;
 };
@@ -53,13 +53,15 @@ static void exynos_gem_detach_dma_buf(struct dma_buf 
*dmabuf,
if (!exynos_attach)
return;

-   sgt = _attach->sgt;
-
-   if (exynos_attach->dir != DMA_NONE)
-   dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents,
-   exynos_attach->dir);
+   sgt = exynos_attach->sgt;
+   if (sgt) {
+   if (exynos_attach->dir != DMA_NONE)
+   dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents,
+   exynos_attach->dir);
+   sg_free_table(sgt);
+   }

-   sg_free_table(sgt);
+   kfree(sgt);
kfree(exynos_attach);
attach->priv = NULL;
 }
@@ -70,16 +72,13 @@ static struct sg_table *
 {
struct exynos_drm_dmabuf_attachment *exynos_attach = attach->priv;
struct exynos_drm_gem_obj *gem_obj = dma_buf_to_obj(attach->dmabuf);
-   struct drm_device *dev = gem_obj->base.dev;
struct exynos_drm_gem_buf *buf;
-   struct scatterlist *rd, *wr;
-   struct sg_table *sgt = NULL;
-   unsigned int i;
-   int nents, ret;
+   struct sg_table *sgt;
+   int npages;

/* just return current sgt if already requested. */
if (exynos_attach->dir == dir && exynos_attach->is_mapped)
-   return _attach->sgt;
+   return exynos_attach->sgt;

buf = gem_obj->buffer;
if (!buf) {
@@ -87,42 +86,29 @@ static struct sg_table *
return ERR_PTR(-ENOMEM);
}

-   sgt = _attach->sgt;
+   npages = buf->size >> PAGE_SHIFT;

-   ret = sg_alloc_table(sgt, buf->sgt->orig_nents, GFP_KERNEL);
-   if (ret) {
-   DRM_ERROR("failed to alloc sgt.\n");
-   return ERR_PTR(-ENOMEM);
-   }
-
-   mutex_lock(>struct_mutex);
-
-   rd = buf->sgt->sgl;
-   wr = sgt->sgl;
-   for (i = 0; i < sgt->orig_nents; ++i) {
-   sg_set_page(wr, sg_page(rd), rd->length, rd->offset);
-   rd = sg_next(rd);
-   wr = sg_next(wr);
-   }
+   sgt = drm_prime_pages_to_sg(buf->pages, npages);
+   if (IS_ERR(sgt))
+   goto err;

if (dir != DMA_NONE) {
-   nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
-   if (!nents) {
+   if (!dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir)) {
DRM_ERROR("failed to map sgl with iommu.\n");
sg_free_table(sgt);
sgt = ERR_PTR(-EIO);
-   goto err_unlock;
+   goto err;
}
}

exynos_attach->is_mapped = true;
+   exynos_attach->sgt = sgt;
exynos_attach->dir = dir;
attach->priv = exynos_attach;

DRM_DEBUG_PRIME("buffer size = 0x%lx\n", buf->size);

-err_unlock:
-   mutex_unlock(>struct_mutex);
+err:
return sgt;
 }

@@ -280,7 +266,6 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct 
drm_device *drm_dev,
}

exynos_gem_obj->buffer = buffer;
-   buffer->sgt = sgt;
exynos_gem_obj->base.import_attach = attach;

DRM_DEBUG_PRIME("dma_addr = %pad, size = 0x%lx\n", >dma_addr,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index cb5d9b6..8fffc4d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -455,9 +455,6 @@ void exynos_drm_gem_free_object(struct drm_gem_object *obj)
exynos_gem_obj = to_exynos_gem_obj(obj);
buf = exynos_gem_obj->buffer;

-   if (obj->import_attach)
-   drm_prime_gem_destroy(obj, buf->sgt);
-
exynos_drm_gem_destroy(to_exynos_gem_obj(obj));
 }

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h 
b/drivers/gpu/drm/exyno

[PATCH 04/14] drm/exynos: remove function exynos_drm_gem_map_buf

2015-07-28 Thread Joonyoung Shim
The exynos_drm_gem_map_buf can be merged in exynos_drm_gem_fault.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 36 +++--
 1 file changed, 12 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 4741226..cb5d9b6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -53,25 +53,6 @@ static unsigned long roundup_gem_size(unsigned long size, 
unsigned int flags)
return roundup(size, PAGE_SIZE);
 }

-static int exynos_drm_gem_map_buf(struct drm_gem_object *obj,
-   struct vm_area_struct *vma,
-   unsigned long f_vaddr,
-   pgoff_t page_offset)
-{
-   struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
-   struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer;
-   unsigned long pfn;
-
-   if (page_offset >= (buf->size >> PAGE_SHIFT)) {
-   DRM_ERROR("invalid page offset\n");
-   return -EINVAL;
-   }
-
-   pfn = page_to_pfn(buf->pages[page_offset]);
-
-   return vm_insert_mixed(vma, f_vaddr, pfn);
-}
-
 static int exynos_drm_gem_handle_create(struct drm_gem_object *obj,
struct drm_file *file_priv,
unsigned int *handle)
@@ -560,18 +541,25 @@ unlock:
 int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
struct drm_gem_object *obj = vma->vm_private_data;
-   unsigned long f_vaddr;
+   struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
+   struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer;
+   unsigned long pfn;
pgoff_t page_offset;
int ret;

page_offset = ((unsigned long)vmf->virtual_address -
vma->vm_start) >> PAGE_SHIFT;
-   f_vaddr = (unsigned long)vmf->virtual_address;

-   ret = exynos_drm_gem_map_buf(obj, vma, f_vaddr, page_offset);
-   if (ret < 0)
-   DRM_ERROR("failed to map a buffer with user.\n");
+   if (page_offset >= (buf->size >> PAGE_SHIFT)) {
+   DRM_ERROR("invalid page offset\n");
+   ret = -EINVAL;
+   goto out;
+   }

+   pfn = page_to_pfn(buf->pages[page_offset]);
+   ret = vm_insert_mixed(vma, (unsigned long)vmf->virtual_address, pfn);
+
+out:
switch (ret) {
case 0:
case -ERESTARTSYS:
-- 
1.9.1



[PATCH 03/14] drm/exynos: remove mutex locking in pagefault handler

2015-07-28 Thread Joonyoung Shim
There is no reason to use mutex locking in pagefault handler.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 752cb7c..4741226 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -560,7 +560,6 @@ unlock:
 int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
struct drm_gem_object *obj = vma->vm_private_data;
-   struct drm_device *dev = obj->dev;
unsigned long f_vaddr;
pgoff_t page_offset;
int ret;
@@ -569,14 +568,10 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, 
struct vm_fault *vmf)
vma->vm_start) >> PAGE_SHIFT;
f_vaddr = (unsigned long)vmf->virtual_address;

-   mutex_lock(>struct_mutex);
-
ret = exynos_drm_gem_map_buf(obj, vma, f_vaddr, page_offset);
if (ret < 0)
DRM_ERROR("failed to map a buffer with user.\n");

-   mutex_unlock(>struct_mutex);
-
switch (ret) {
case 0:
case -ERESTARTSYS:
-- 
1.9.1



[PATCH 02/14] drm/exynos: remove function convert_to_vm_err_msg

2015-07-28 Thread Joonyoung Shim
The convert_to_vm_err_msg is called just once by exynos_drm_gem_fault,
so it's simple not to use the function.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 33 +
 1 file changed, 9 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index d320acd..752cb7c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -20,29 +20,6 @@
 #include "exynos_drm_buf.h"
 #include "exynos_drm_iommu.h"

-static unsigned int convert_to_vm_err_msg(int msg)
-{
-   unsigned int out_msg;
-
-   switch (msg) {
-   case 0:
-   case -ERESTARTSYS:
-   case -EINTR:
-   out_msg = VM_FAULT_NOPAGE;
-   break;
-
-   case -ENOMEM:
-   out_msg = VM_FAULT_OOM;
-   break;
-
-   default:
-   out_msg = VM_FAULT_SIGBUS;
-   break;
-   }
-
-   return out_msg;
-}
-
 static int check_gem_flags(unsigned int flags)
 {
if (flags & ~(EXYNOS_BO_MASK)) {
@@ -600,7 +577,15 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, 
struct vm_fault *vmf)

mutex_unlock(>struct_mutex);

-   return convert_to_vm_err_msg(ret);
+   switch (ret) {
+   case 0:
+   case -ERESTARTSYS:
+   return VM_FAULT_NOPAGE;
+   case -ENOMEM:
+   return VM_FAULT_OOM;
+   default:
+   return VM_FAULT_SIGBUS;
+   }
 }

 int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
-- 
1.9.1



[PATCH 01/14] drm/exynos: stop using sgtable in page fault handler

2015-07-28 Thread Joonyoung Shim
Already struct exynos_drm_gem_buf has pages of the buffer when buffer is
created, so just can use pages in page fault handler, we don't have to
make sgtable of the buffer. But this needs to construct pages of the
buffer that is imported from dma-buf prime.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_buf.c| 16 
 drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | 18 ++
 drivers/gpu/drm/exynos/exynos_drm_gem.c| 14 +-
 3 files changed, 19 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c 
b/drivers/gpu/drm/exynos/exynos_drm_buf.c
index 24994ba..9260dfb 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
@@ -90,23 +90,12 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
}
}

-   buf->sgt = drm_prime_pages_to_sg(buf->pages, nr_pages);
-   if (IS_ERR(buf->sgt)) {
-   DRM_ERROR("failed to get sg table.\n");
-   ret = PTR_ERR(buf->sgt);
-   goto err_free_attrs;
-   }
-
DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n",
(unsigned long)buf->dma_addr,
buf->size);

return ret;

-err_free_attrs:
-   dma_free_attrs(dev->dev, buf->size, buf->pages,
-   (dma_addr_t)buf->dma_addr, >dma_attrs);
-   buf->dma_addr = (dma_addr_t)NULL;
 err_free:
if (!is_drm_iommu_supported(dev))
drm_free_large(buf->pages);
@@ -126,11 +115,6 @@ static void lowlevel_buffer_deallocate(struct drm_device 
*dev,
(unsigned long)buf->dma_addr,
buf->size);

-   sg_free_table(buf->sgt);
-
-   kfree(buf->sgt);
-   buf->sgt = NULL;
-
if (!is_drm_iommu_supported(dev)) {
dma_free_attrs(dev->dev, buf->size, buf->cookie,
(dma_addr_t)buf->dma_addr, >dma_attrs);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c 
b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
index cd485c0..d10f9b6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
@@ -203,6 +203,7 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct 
drm_device *drm_dev,
struct scatterlist *sgl;
struct exynos_drm_gem_obj *exynos_gem_obj;
struct exynos_drm_gem_buf *buffer;
+   int npages;
int ret;

/* is this one of own objects? */
@@ -251,6 +252,20 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct 
drm_device *drm_dev,
buffer->size = dma_buf->size;
buffer->dma_addr = sg_dma_address(sgl);

+   npages = dma_buf->size >> PAGE_SHIFT;
+   buffer->pages = drm_malloc_ab(npages, sizeof(struct page *));
+   if (!buffer->pages) {
+   ret = -ENOMEM;
+   goto err_free_gem;
+   }
+
+   ret = drm_prime_sg_to_page_addr_arrays(sgt, buffer->pages, NULL,
+   npages);
+   if (ret < 0) {
+   drm_free_large(buffer->pages);
+   goto err_free_gem;
+   }
+
if (sgt->nents == 1) {
/* always physically continuous memory if sgt->nents is 1. */
exynos_gem_obj->flags |= EXYNOS_BO_CONTIG;
@@ -273,6 +288,9 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct 
drm_device *drm_dev,

return _gem_obj->base;

+err_free_gem:
+   drm_gem_object_release(_gem_obj->base);
+   kfree(exynos_gem_obj);
 err_free_buffer:
kfree(buffer);
buffer = NULL;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 0d5b969..d320acd 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -83,26 +83,14 @@ static int exynos_drm_gem_map_buf(struct drm_gem_object 
*obj,
 {
struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer;
-   struct scatterlist *sgl;
unsigned long pfn;
-   int i;
-
-   if (!buf->sgt)
-   return -EINTR;

if (page_offset >= (buf->size >> PAGE_SHIFT)) {
DRM_ERROR("invalid page offset\n");
return -EINVAL;
}

-   sgl = buf->sgt->sgl;
-   for_each_sg(buf->sgt->sgl, sgl, buf->sgt->nents, i) {
-   if (page_offset < (sgl->length >> PAGE_SHIFT))
-   break;
-   page_offset -=  (sgl->length >> PAGE_SHIFT);
-   }
-
-   pfn = __phys_to_pfn(sg_phys(sgl)) + page_offset;
+   pfn = page_to_pfn(buf->pages[page_offset]);

return vm_insert_mixed(vma, f_vaddr, pfn);
 }
-- 
1.9.1



[PATCH 00/14] drm/exynos: cleanup and update gem/dma-buf

2015-07-28 Thread Joonyoung Shim
This patchset improves gem and dma-buf codes of exynos drm.

Major changes:

- remove needless using sg table.
- use prime helpers instead of exynos specific dma-buf functions.
- merge struct exynos_drm_gem_buf in struct exynos_drm_gem.
- remove simple functions.
- cleanup.

Thanks.

Joonyoung Shim (14):
  drm/exynos: stop using sgtable in page fault handler
  drm/exynos: remove function convert_to_vm_err_msg
  drm/exynos: remove mutex locking in pagefault handler
  drm/exynos: remove function exynos_drm_gem_map_buf
  drm/exynos: stop copying sg table
  drm/exynos: remove unused fields of struct exynos_drm_gem_buf
  drm/exynos: use ERR_PTR instead of NULL in exynos_drm_gem_init
  drm/exynos: create a fake mmap offset with gem creation
  drm/exynos: remove call to drm_gem_free_mmap_offset()
  drm/exynos: remove function check_gem_flags
  drm/exynos: remove function update_vm_cache_attr
  drm/exynos: remove function roundup_gem_size
  drm/exynos: use prime helpers
  drm/exynos: merge exynos_drm_buf.c to exynos_drm_gem.c

 drivers/gpu/drm/exynos/Makefile|   3 +-
 drivers/gpu/drm/exynos/exynos_drm_buf.c| 186 ---
 drivers/gpu/drm/exynos/exynos_drm_buf.h|  33 ---
 drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | 286 --
 drivers/gpu/drm/exynos/exynos_drm_dmabuf.h |  20 --
 drivers/gpu/drm/exynos/exynos_drm_drv.c|   9 +-
 drivers/gpu/drm/exynos/exynos_drm_fb.c |  14 +-
 drivers/gpu/drm/exynos/exynos_drm_fb.h |   4 +-
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c  |  30 ++-
 drivers/gpu/drm/exynos/exynos_drm_gem.c| 365 +
 drivers/gpu/drm/exynos/exynos_drm_gem.h|  58 ++---
 drivers/gpu/drm/exynos/exynos_drm_plane.c  |  10 +-
 12 files changed, 277 insertions(+), 741 deletions(-)
 delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_buf.c
 delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_buf.h
 delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
 delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_dmabuf.h


[PATCH v2] drm/exynos: clear channels only when iommu is enabled

2015-07-28 Thread Joonyoung Shim
This is simplest solution about reported problem[1]. It's no problem to
clear channel only when iommu is enabled, if we consider that we cannot
recognize iommu errors when iommu is disabled and it have been valid
until now. But this cannot be nice solution.

[1] https://lkml.org/lkml/2015/7/21/404

Reported-by: Krzysztof Kozlowski 
Signed-off-by: Joonyoung Shim 
---
v2: add Reported-by.

 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c 
b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 8d362b9..337af02 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -956,7 +956,8 @@ static int fimd_bind(struct device *dev, struct device 
*master, void *data)
if (ctx->display)
exynos_drm_create_enc_conn(drm_dev, ctx->display);

-   fimd_clear_channels(ctx->crtc);
+   if (is_drm_iommu_supported(drm_dev))
+   fimd_clear_channels(ctx->crtc);

ret = drm_iommu_attach_device(drm_dev, dev);
if (ret)
-- 
1.9.1



[PATCH] drm/exynos: clear channels only when iommu is enabled

2015-07-28 Thread Joonyoung Shim
On 07/28/2015 05:30 PM, Krzysztof Kozlowski wrote:
> On 28.07.2015 17:28, Joonyoung Shim wrote:
>> This is simplest solution about reported problem[1]. It's no problem to
>> clear channel only when iommu is enabled, if we consider that we cannot
>> recognize iommu errors when iommu is disabled and it have been valid
>> until now. But this cannot be nice solution.
> 
> I am not sure if I got it correctly. If this cannot be "nice solution"
> so is this a proper fix or not?
> 

Yeah, that clean channels always is more reasonable to me but now i
cannot give proper fix for that e.g. about clock problem.

> Anyway, please:
> Reported-by: Krzysztof Kozlowski 

Sure, Thanks.


[PATCH] drm/exynos: clear channels only when iommu is enabled

2015-07-28 Thread Joonyoung Shim
This is simplest solution about reported problem[1]. It's no problem to
clear channel only when iommu is enabled, if we consider that we cannot
recognize iommu errors when iommu is disabled and it have been valid
until now. But this cannot be nice solution.

[1] https://lkml.org/lkml/2015/7/21/404

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c 
b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 8d362b9..337af02 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -956,7 +956,8 @@ static int fimd_bind(struct device *dev, struct device 
*master, void *data)
if (ctx->display)
exynos_drm_create_enc_conn(drm_dev, ctx->display);

-   fimd_clear_channels(ctx->crtc);
+   if (is_drm_iommu_supported(drm_dev))
+   fimd_clear_channels(ctx->crtc);

ret = drm_iommu_attach_device(drm_dev, dev);
if (ret)
-- 
1.9.1



Linux-next, Exynos Octa boot fail, bisected to: "drm/exynos: remove drm_iommu_attach_device_if_possible"

2015-07-22 Thread Joonyoung Shim
On 07/22/2015 05:22 PM, Inki Dae wrote:
> On 2015년 07월 22일 17:12, Joonyoung Shim wrote:
>> On 07/22/2015 01:55 PM, Inki Dae wrote:
>>> On 2015년 07월 22일 11:02, Joonyoung Shim wrote:
>>>> On 07/21/2015 10:19 PM, Krzysztof Kozlowski wrote:
>>>>> Hi,
>>>>>
>>>>> Today's linux-next (next-20150721) encounters boot failures on Exynos
>>>>> Octa (Exynos5422) based boards. The boards hangs. I bisected it to:
>>>>>
>>>>> d80167b85024982c5f18d0481a5c248100360118 is the first bad commit
>>>>> commit d80167b85024982c5f18d0481a5c248100360118
>>>>> Author: Joonyoung Shim 
>>>>> Date:   Thu Jul 2 21:49:39 2015 +0900
>>>>>
>>>>> drm/exynos: remove drm_iommu_attach_device_if_possible
>>>>>
>>>>> Already drm_iommu_attach_device checks whether support iommu 
>>>>> internally.
>>>>> It should clear channels always regardless iommu support. We didn't 
>>>>> know
>>>>> because we can detect the problem when iommu is enabled, so we don't
>>>>> have to use drm_iommu_attach_device_if_possible and then we can remove
>>>>> drm_iommu_attach_device_if_possible and clear_channels function 
>>>>> pointer.
>>>>>
>>>>> Signed-off-by: Joonyoung Shim 
>>>>> Tested-by: Marek Szyprowski 
>>>>> Signed-off-by: Inki Dae 
>>>>>
>>>>> :04 04 83379efbf4960f58d680371628ec04387935bd53
>>>>> da03c338b88e7cb6bda895b3dd52d78d9b6eba30 M drivers
>>>>>
>>>>>
>>>>> Config: exynos
>>>>> Boot log from Odroid XU3-Lite attached.
>>>>>
>>>>> Any hints or ideas?
>>>>
>>>> The point that hangs is when accesses fimd register in
>>>> fimd_clear_channels function, so i doubt clock setting for fimd.
>>>>
>>>> It's gone something that hangs after i enable gating for ACLK_200_DISP1
>>>> clock.
>>>>
>>>> If ACLK_200_DISP1 clock needs for fimd really, i'm thinking how can it
>>>> support. Any ideas?
>>>
>>> I think bootloader should have enabled ACLK_200_DISP1 clock and also
>>> device driver should enable all relevant clocks before the device
>>> accesses its own registers.
>>>
>>> Best way would be that the clock is enabled by common clock framework
>>> but it seems there is no anything that the clock framework can do it. So
>>> I think what we have to do is to add the clock support to device tree.
>>
>> It's not easy problem to me. Should we add which clock? I think we
>> cannot control ACLK_200_DISP1 or CLKDIV2_DISP1_BLK directly by below
>> hierarchy, right? Then we should control gate clocks, but we have not
>> controlled any gate clocks using BTS_ prefix.
>>
>> The clock hierarchy from Exynos5422 user manual,
>> ACLK_200_DISP1 -- CLKDIV2_DISP1_BLK -- HDMI LINK
>>HDMI PHY
>>MIC1
>>DSIM1
>>DPTX LINK
>>MDNIE1
>>SYSMMU_MIXER
>>SYSMMU_FIMD1_M0
>>SYSMMU_FIMD1_M1
>>BTS_TVM0
>>BTS_TVM1
>>BTS_FIMD1_M0
>>BTS_FIMD1_M1
>>
>> Other way, IMHO, fimd driver doesn't have to enable ACLK_200_DISP1 clock,
>> just it should be controlled by connector drivers, e.g. dsi, dp because
>> fimd only cannot operate, so dsi or dp must need (Actually i'm not sure
>> about this, just i thought that Exynos5 SoCs don't have any gpios for
>> dpi, so they cannot use dpi, right?).
>>
>> It needs to probe connector driver like dsi or dp earlier than fimd and
>> fimd_bind function should return error if connector driver like dsi or
>> dp was not probed. This is also not easy to me.
> 
> In this case, if one of above gate clocks is enabled, the ACLK_200_DISP1
> should be enabled. So I guess the problem would be due to below line of
> clk-exynos5420.c,
> 
> GATE(CLK_FIMD1, "fimd1", "aclk300_disp1", GATE_IP_DISP1, 0, 0, 0),
> 
> Can you check it again after modifying it like below?,
> GATE(CLK_FIMD1, "fimd1", "aclk200_disp1", GATE_IP_DISP1, 0, 0, 0),

No, parent clock of fimd1 gate clock is ACLK_300_DISP1.


Linux-next, Exynos Octa boot fail, bisected to: "drm/exynos: remove drm_iommu_attach_device_if_possible"

2015-07-22 Thread Joonyoung Shim
On 07/22/2015 01:55 PM, Inki Dae wrote:
> On 2015년 07월 22일 11:02, Joonyoung Shim wrote:
>> On 07/21/2015 10:19 PM, Krzysztof Kozlowski wrote:
>>> Hi,
>>>
>>> Today's linux-next (next-20150721) encounters boot failures on Exynos
>>> Octa (Exynos5422) based boards. The boards hangs. I bisected it to:
>>>
>>> d80167b85024982c5f18d0481a5c248100360118 is the first bad commit
>>> commit d80167b85024982c5f18d0481a5c248100360118
>>> Author: Joonyoung Shim 
>>> Date:   Thu Jul 2 21:49:39 2015 +0900
>>>
>>> drm/exynos: remove drm_iommu_attach_device_if_possible
>>>
>>> Already drm_iommu_attach_device checks whether support iommu internally.
>>> It should clear channels always regardless iommu support. We didn't know
>>> because we can detect the problem when iommu is enabled, so we don't
>>> have to use drm_iommu_attach_device_if_possible and then we can remove
>>> drm_iommu_attach_device_if_possible and clear_channels function pointer.
>>>
>>> Signed-off-by: Joonyoung Shim 
>>> Tested-by: Marek Szyprowski 
>>> Signed-off-by: Inki Dae 
>>>
>>> :04 04 83379efbf4960f58d680371628ec04387935bd53
>>> da03c338b88e7cb6bda895b3dd52d78d9b6eba30 M drivers
>>>
>>>
>>> Config: exynos
>>> Boot log from Odroid XU3-Lite attached.
>>>
>>> Any hints or ideas?
>>
>> The point that hangs is when accesses fimd register in
>> fimd_clear_channels function, so i doubt clock setting for fimd.
>>
>> It's gone something that hangs after i enable gating for ACLK_200_DISP1
>> clock.
>>
>> If ACLK_200_DISP1 clock needs for fimd really, i'm thinking how can it
>> support. Any ideas?
> 
> I think bootloader should have enabled ACLK_200_DISP1 clock and also
> device driver should enable all relevant clocks before the device
> accesses its own registers.
> 
> Best way would be that the clock is enabled by common clock framework
> but it seems there is no anything that the clock framework can do it. So
> I think what we have to do is to add the clock support to device tree.

It's not easy problem to me. Should we add which clock? I think we
cannot control ACLK_200_DISP1 or CLKDIV2_DISP1_BLK directly by below
hierarchy, right? Then we should control gate clocks, but we have not
controlled any gate clocks using BTS_ prefix.

The clock hierarchy from Exynos5422 user manual,
ACLK_200_DISP1 -- CLKDIV2_DISP1_BLK -- HDMI LINK
   HDMI PHY
   MIC1
   DSIM1
   DPTX LINK
   MDNIE1
   SYSMMU_MIXER
   SYSMMU_FIMD1_M0
   SYSMMU_FIMD1_M1
   BTS_TVM0
   BTS_TVM1
   BTS_FIMD1_M0
   BTS_FIMD1_M1

Other way, IMHO, fimd driver doesn't have to enable ACLK_200_DISP1 clock,
just it should be controlled by connector drivers, e.g. dsi, dp because
fimd only cannot operate, so dsi or dp must need (Actually i'm not sure
about this, just i thought that Exynos5 SoCs don't have any gpios for
dpi, so they cannot use dpi, right?).

It needs to probe connector driver like dsi or dp earlier than fimd and
fimd_bind function should return error if connector driver like dsi or
dp was not probed. This is also not easy to me.


Linux-next, Exynos Octa boot fail, bisected to: "drm/exynos: remove drm_iommu_attach_device_if_possible"

2015-07-22 Thread Joonyoung Shim
On 07/21/2015 10:19 PM, Krzysztof Kozlowski wrote:
> Hi,
> 
> Today's linux-next (next-20150721) encounters boot failures on Exynos
> Octa (Exynos5422) based boards. The boards hangs. I bisected it to:
> 
> d80167b85024982c5f18d0481a5c248100360118 is the first bad commit
> commit d80167b85024982c5f18d0481a5c248100360118
> Author: Joonyoung Shim 
> Date:   Thu Jul 2 21:49:39 2015 +0900
> 
> drm/exynos: remove drm_iommu_attach_device_if_possible
> 
> Already drm_iommu_attach_device checks whether support iommu internally.
> It should clear channels always regardless iommu support. We didn't know
> because we can detect the problem when iommu is enabled, so we don't
> have to use drm_iommu_attach_device_if_possible and then we can remove
> drm_iommu_attach_device_if_possible and clear_channels function pointer.
> 
> Signed-off-by: Joonyoung Shim 
> Tested-by: Marek Szyprowski 
> Signed-off-by: Inki Dae 
> 
> :04 04 83379efbf4960f58d680371628ec04387935bd53
> da03c338b88e7cb6bda895b3dd52d78d9b6eba30 M drivers
> 
> 
> Config: exynos
> Boot log from Odroid XU3-Lite attached.
> 
> Any hints or ideas?

The point that hangs is when accesses fimd register in
fimd_clear_channels function, so i doubt clock setting for fimd.

It's gone something that hangs after i enable gating for ACLK_200_DISP1
clock.

If ACLK_200_DISP1 clock needs for fimd really, i'm thinking how can it
support. Any ideas?

Thanks.


[PATCH libdrm] remove if HAVE_LIBUDEV for vbltest

2015-07-20 Thread Joonyoung Shim
The vbltest doesn't have any dependency of LIBUDEV.

Signed-off-by: Joonyoung Shim 
---
 tests/Makefile.am | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 069285f..c5edec8 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = modeprint proptest modetest
+SUBDIRS = modeprint proptest modetest vbltest

 if HAVE_LIBKMS
 SUBDIRS += kmstest
@@ -16,10 +16,6 @@ if HAVE_TEGRA
 SUBDIRS += tegra
 endif

-if HAVE_LIBUDEV
-SUBDIRS += vbltest
-endif
-
 AM_CFLAGS = \
$(WARN_CFLAGS)\
-I $(top_srcdir)/include/drm \
-- 
1.9.1



[PATCH] drm/exynos: move order to register vidi kms driver

2015-07-15 Thread Joonyoung Shim
The vidi is virtual kms driver and now it is registered earlier than
actual hw kms drivers, so it will occupy crtc index 0. Some users
assume the condition yet that actual hw kms driver has crtc index 0.
It may or may not be matter but let's arrange register order.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_drv.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 63a68c6..f1d6966 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -345,9 +345,6 @@ static struct platform_driver exynos_drm_platform_driver;
  * because connector requires pipe number of its crtc during initialization.
  */
 static struct platform_driver *const exynos_drm_kms_drivers[] = {
-#ifdef CONFIG_DRM_EXYNOS_VIDI
-   _driver,
-#endif
 #ifdef CONFIG_DRM_EXYNOS_FIMD
_driver,
 #endif
@@ -370,6 +367,9 @@ static struct platform_driver *const 
exynos_drm_kms_drivers[] = {
_driver,
_driver,
 #endif
+#ifdef CONFIG_DRM_EXYNOS_VIDI
+   _driver,
+#endif
 };

 static struct platform_driver *const exynos_drm_non_kms_drivers[] = {
-- 
1.9.1



[PATCH v2 00/23] drm/exynos: atomic improvements + exynos_encoder removal

2015-07-14 Thread Joonyoung Shim
On 07/06/2015 11:20 PM, Gustavo Padovan wrote:
> From: Gustavo Padovan 
> 
> Hi,   
>   
>   
>   
> This set improves exynos in a number of ways. The first five patches are  
>   
> general clean up/fixes.   
>   
>   
>   
> Patches 06 to 12 are improvements on top of the newly added atomic 
> modesetting  
> support.  
>   
>   
>   
> Patches 13-23 are a big journey to completely remove the internal 
>   
> exynos_drm_encoder struct. Now exynos encoders register themselves directly   
>   
> with the drm core.

I got compile error with 13-23 patches.

drivers/gpu/drm/exynos/exynos_drm_dsi.c: In function ‘exynos_dsi_bind’:
drivers/gpu/drm/exynos/exynos_drm_dsi.c:1839:3: error: ‘display’ undeclared 
(first use in this function)
   display->encoder->bridge = bridge;
   ^
drivers/gpu/drm/exynos/exynos_drm_dsi.c:1839:3: note: each undeclared 
identifier is reported only once for each function it appears in
make[4]: *** [drivers/gpu/drm/exynos/exynos_drm_dsi.o] Error 1


If you post the stuff that only be related, it will be reviewed and
merged easier.

01-04 and 06-11 patches look good to me, about them,
Reviewed-by: Joonyoung Shim 

>   
>   
> v2: Fix comments by Joonyoung 
>   
> - add an extra commit to check crtc->enable_vblank() value
>   
> - directly assign the vrefresh without checking for zero  
>   
> - don't remove FIMD ctc->suspended check  
>   
>   
>   
> Please review!
>   
>   
>   
> Gustavo
> 
> Gustavo Padovan (23):
>   drm/exynos: pass the correct pipe number
>   drm/exynos: calculate vrefresh instead of use a fixed value
>   drm/exynos: use KMS version of DRM vblanks functions
>   drm/exynos: remove duplicated check for suspend
>   drm/exynos: add atomic asynchronous commit
>   drm/exynos: rename win_commit/disable to atomic-like names
>   drm/exynos: pass struct exynos_drm_plane in update/enable
>   drm/exynos: use drm atomic state directly
>   drm/exynos: remove unused fields from struct exynos_drm_plane
>   drm/exynos: unify exynos_drm_plane names with drm core
>   drm/exynos: return return value of exynos_crtc->enable_vblank
>   drm/exynos: don't track enabled state at exynos_crtc
>   drm/exynos: split display's .dpms() into .enable() and .disable()
>   drm/exynos: remove wrappers for phy_power_{on,off}
>   drm/exynos: remove unused .remove() and .check_mode() ops from display
>   drm/exynos: simplify calculation of possible CRTCs
>   drm/exynos: remove struct exynos_drm_display
>   drm/exynos: remove extra call to hdmi_commit()
>   drm/exynos: remove extra call to exynos_dp_commit()
>   drm/exynos: remove exynos_encoder's .commit() op
>   drm/exynos: remove exynos_drm_create_enc_conn()
>   drm/exynos: fold encoder setup into exynos_drm_load()
>   drm/exynos: remove struct exynos_drm_encoder layer
> 
>  drivers/gpu/drm/exynos/Makefile   |   7 +-
>  drivers/gpu/drm/exynos/exynos5433_drm_decon.c |  57 -
>  drivers/gpu/drm/exynos/exynos7_drm_decon.c|  86 ++---
>  drivers/gpu/drm/exynos/exynos_dp_core.c   | 122 +-
>  drivers/gpu/drm/exynos/exynos_dp_core.h   |   3 +-
>  drivers/gpu/drm/exynos/exynos_drm_core.c  |  36 --
>  drivers/gpu/drm/exynos/exynos_drm_crtc.c  |  35 ++
>  drivers/gpu/drm/exynos/exynos_drm_crtc.h  |   4 +-
>  drivers/gpu/drm/exynos/exynos_drm_dpi.c   |  96 +++---
>  drivers/gpu/drm/exynos/exynos_drm_drv.c   |  19 ++-
>  drivers/gpu/drm/exynos/exynos_drm_drv.h   | 115 +
>  drivers/gpu/drm/exynos/exynos_drm_dsi.c   | 129 ++-
>  drivers/gpu/drm/exynos/exynos_drm_encoder.c   | 174 
> --
>  drivers/gpu/drm/exynos/exynos_drm_encoder.h   |  23 
>  drivers/gpu/drm/exynos/exynos_drm_fb.c|  51 ++--
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c  |  95 +++---
>  drivers/gpu/drm/exyno

[PATCH 0/7] drm/exynos/hdmi: refactoring/cleanup patches

2015-07-14 Thread Joonyoung Shim
On 07/09/2015 11:28 PM, Andrzej Hajda wrote:
> Hi Inki, Joonyoung,
> 
> These patches removes obsolete and old structures, to simplify further
> development. They should not change behavior of the driver.
> 
> The patchset is based on exynos-drm-next plus my HDMI related fixes [1].
> 
> The patchset was tested on Universal and Odroid U3.
> 
> [1]: http://permalink.gmane.org/gmane.comp.video.dri.devel/132348
> 
> Regards
> Andrzej
> 
> 
> Andrzej Hajda (7):
>   drm/exynos/hdmi: remove old platform data code
>   drm/exynos/hdmi: Simplify HPD gpio handling
>   drm/exynos/hdmi: remove private lock code
>   drm/exynos/hdmi: add driver data pointer to private context
>   drm/exynos/hdmi: remove redundant configuration fields
>   drm/exynos/hdmi: remove hdmi_v13_conf struct
>   drm/exynos/hdmi: remove hdmi_v14_conf struct
> 
>  drivers/gpu/drm/exynos/exynos_hdmi.c | 860 
> ++-
>  1 file changed, 245 insertions(+), 615 deletions(-)
> 

Looks good to me about this patchset,

Reviewed-by: Joonyoung Shim 


[PATCH v2 12/23] drm/exynos: don't track enabled state at exynos_crtc

2015-07-10 Thread Joonyoung Shim
On 07/10/2015 07:56 AM, Gustavo Padovan wrote:
> 2015-07-09 Joonyoung Shim :
> 
>> +Cc Andrzej,
>>
>> On 07/07/2015 02:41 AM, Daniel Vetter wrote:
>>> On Mon, Jul 06, 2015 at 11:20:13AM -0300, Gustavo Padovan wrote:
>>>> From: Gustavo Padovan 
>>>>
>>>> struct drm_crtc already stores the enabled state of the crtc
>>>> thus we don't need to replicate enabled in exynos_drm_crtc.
>>>>
>>
>> I think exynos_crtc->enabled can replace flags for power state of each
>> hw driver(e.g. "powered" of mixer driver, "suspended" of fimd driver).
>> Further, we can add other flag bit for instead of using special flag
>> in hw driver like vsync state("int_en" of mixer driver, "irq_flags" of
>> fimd driver.)
> 
> The reason I removed it is because crtc->state->active already stores
> the same information as exynos_crtc->enabled. I think we could rely
> on active as well for mixer powered and suspended.
> 

Then it may need another stuff on struct exynos_crtc if we try to
replace other hw flag like int_en or irq_flags.

Anyway, the reason that you remove it is ok to me now.

Thanks.


[PATCH RESEND v2 2/6] drm/exynos/mixer: fix interrupt clearing

2015-07-09 Thread Joonyoung Shim
On 07/09/2015 05:07 PM, Andrzej Hajda wrote:
> The driver used incorrect flags to clear interrupt status.
> The patch fixes it.
> 
> Signed-off-by: Andrzej Hajda 
> ---
>  drivers/gpu/drm/exynos/exynos_mixer.c | 9 -
>  1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
> b/drivers/gpu/drm/exynos/exynos_mixer.c
> index cae98db..25f0aac 100644
> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
> @@ -718,6 +718,10 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
>  
>   /* handling VSYNC */
>   if (val & MXR_INT_STATUS_VSYNC) {
> + /* vsync interrupt use different bit for read and clear */
> + val |= MXR_INT_CLEAR_VSYNC;
> + val &= ~MXR_INT_STATUS_VSYNC;
> +
>   /* interlace scan need to check shadow register */
>   if (ctx->interlace) {
>   base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0));
> @@ -743,11 +747,6 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
>  
>  out:
>   /* clear interrupts */
> - if (~val & MXR_INT_EN_VSYNC) {
> - /* vsync interrupt use different bit for read and clear */
> - val &= ~MXR_INT_EN_VSYNC;
> - val |= MXR_INT_CLEAR_VSYNC;
> -     }
>   mixer_reg_write(res, MXR_INT_STATUS, val);
>  
>   spin_unlock(>reg_slock);
> 

Reviewed-by: Joonyoung Shim 

Thanks.


[PATCH v2 12/23] drm/exynos: don't track enabled state at exynos_crtc

2015-07-09 Thread Joonyoung Shim
+Cc Andrzej,

On 07/07/2015 02:41 AM, Daniel Vetter wrote:
> On Mon, Jul 06, 2015 at 11:20:13AM -0300, Gustavo Padovan wrote:
>> From: Gustavo Padovan 
>>
>> struct drm_crtc already stores the enabled state of the crtc
>> thus we don't need to replicate enabled in exynos_drm_crtc.
>>

I think exynos_crtc->enabled can replace flags for power state of each
hw driver(e.g. "powered" of mixer driver, "suspended" of fimd driver).
Further, we can add other flag bit for instead of using special flag
in hw driver like vsync state("int_en" of mixer driver, "irq_flags" of
fimd driver.)

>> Signed-off-by: Gustavo Padovan 
> 
> Note that exynos_crtc->enabled doesn't match drm_crtc->enabled perfectly
> since the exynos one reflect hw state (including dpms). You want to look
> at crtc->state->active instead on functions enabling stuff, and
> old_crtc_state->active on functions disabling stuff (we don't wire that
> through everywhere yet).
> -Daniel
> 
>> ---
>>  drivers/gpu/drm/exynos/exynos_drm_crtc.c | 16 
>>  drivers/gpu/drm/exynos/exynos_drm_drv.h  |  1 -
>>  2 files changed, 17 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c 
>> b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
>> index 9bc2353..5ab8972 100644
>> --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
>> +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
>> @@ -26,14 +26,9 @@ static void exynos_drm_crtc_enable(struct drm_crtc *crtc)
>>  {
>>  struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
>>  
>> -if (exynos_crtc->enabled)
>> -return;
>> -
>>  if (exynos_crtc->ops->enable)
>>  exynos_crtc->ops->enable(exynos_crtc);
>>  
>> -exynos_crtc->enabled = true;
>> -
>>  drm_crtc_vblank_on(crtc);
>>  }
>>  
>> @@ -41,9 +36,6 @@ static void exynos_drm_crtc_disable(struct drm_crtc *crtc)
>>  {
>>  struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
>>  
>> -if (!exynos_crtc->enabled)
>> -return;
>> -
>>  /* wait for the completion of page flip. */
>>  if (!wait_event_timeout(exynos_crtc->pending_flip_queue,
>>  (exynos_crtc->event == NULL), HZ/20))
>> @@ -53,8 +45,6 @@ static void exynos_drm_crtc_disable(struct drm_crtc *crtc)
>>  
>>  if (exynos_crtc->ops->disable)
>>  exynos_crtc->ops->disable(exynos_crtc);
>> -
>> -exynos_crtc->enabled = false;
>>  }
>>  
>>  static bool
>> @@ -171,9 +161,6 @@ int exynos_drm_crtc_enable_vblank(struct drm_device 
>> *dev, int pipe)
>>  struct exynos_drm_crtc *exynos_crtc =
>>  to_exynos_crtc(private->crtc[pipe]);
>>  
>> -if (!exynos_crtc->enabled)
>> -return -EPERM;
>> -
>>  if (exynos_crtc->ops->enable_vblank)
>>  return exynos_crtc->ops->enable_vblank(exynos_crtc);
>>  
>> @@ -186,9 +173,6 @@ void exynos_drm_crtc_disable_vblank(struct drm_device 
>> *dev, int pipe)
>>  struct exynos_drm_crtc *exynos_crtc =
>>  to_exynos_crtc(private->crtc[pipe]);
>>  
>> -if (!exynos_crtc->enabled)
>> -return;
>> -
>>  if (exynos_crtc->ops->disable_vblank)
>>  exynos_crtc->ops->disable_vblank(exynos_crtc);
>>  }
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
>> b/drivers/gpu/drm/exynos/exynos_drm_drv.h
>> index 5bd1d3c..d3a8f0a 100644
>> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
>> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
>> @@ -185,7 +185,6 @@ struct exynos_drm_crtc {
>>  struct drm_crtc base;
>>  enum exynos_drm_output_type type;
>>  unsigned intpipe;
>> -boolenabled;
>>  wait_queue_head_t   pending_flip_queue;
>>  struct drm_pending_vblank_event *event;
>>  const struct exynos_drm_crtc_ops*ops;
>> -- 
>> 2.1.0
>>
>> ___
>> dri-devel mailing list
>> dri-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
> 



[PATCH RESEND 0/6] drm/exynos: HDMI related fixes

2015-07-09 Thread Joonyoung Shim
Hi Andrzej,

On 07/09/2015 03:25 PM, Andrzej Hajda wrote:
> 
> 
> Andrzej Hajda (6):
>   drm/exynos/hdmi: fix edid memory leak
>   drm/exynos/mixer: fix interrupt clearing
>   drm/exynos/mixer: correct vsync configuration sequence
>   drm/exynos/mixer: always update INT_EN cache
>   drm/exynos/mixer: simplify poweron flag
>   drm/exynos/mixer: replace MXR_INT_EN register cache with flag
> 
>  drivers/gpu/drm/exynos/exynos_hdmi.c  |  7 ++-
>  drivers/gpu/drm/exynos/exynos_mixer.c | 80 
> +--
>  2 files changed, 36 insertions(+), 51 deletions(-)
> 

Looks good to me except one comment of "drm/exynos/mixer: fix interrupt
clearing" patch. Also below my patch can be dropped by this patchset.

http://www.spinics.net/lists/dri-devel/msg85322.html

Reviewed-by: Joonyoung Shim 


[PATCH RESEND 2/6] drm/exynos/mixer: fix interrupt clearing

2015-07-09 Thread Joonyoung Shim
On 07/09/2015 03:25 PM, Andrzej Hajda wrote:
> The driver used incorrect flags to clear interrupt status.
> The patch fixes it.
> 
> Signed-off-by: Andrzej Hajda 
> ---
>  drivers/gpu/drm/exynos/exynos_mixer.c | 8 +++-
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
> b/drivers/gpu/drm/exynos/exynos_mixer.c
> index cae98db..0686484 100644
> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
> @@ -718,6 +718,9 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
>  
>   /* handling VSYNC */
>   if (val & MXR_INT_STATUS_VSYNC) {
> + /* vsync interrupt use different bit for read and clear */
> + val |= MXR_INT_CLEAR_VSYNC;

MXR_INT_STATUS_VSYNC bit of MXR_INT_STATUS register is read-only, so it
needs to be clear MXR_INT_STATUS_VSYNC bit of val.

> +
>   /* interlace scan need to check shadow register */
>   if (ctx->interlace) {
>   base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0));
> @@ -743,11 +746,6 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
>  
>  out:
>   /* clear interrupts */
> - if (~val & MXR_INT_EN_VSYNC) {
> - /* vsync interrupt use different bit for read and clear */
> - val &= ~MXR_INT_EN_VSYNC;
> - val |= MXR_INT_CLEAR_VSYNC;
> - }
>   mixer_reg_write(res, MXR_INT_STATUS, val);
>  
>   spin_unlock(>reg_slock);
> 



[PATCH 19/23] drm/exynos: remove extra call to exynos_dp_commit()

2015-07-03 Thread Joonyoung Shim
Hi Hyungwon,

On 07/02/2015 09:39 PM, Joonyoung Shim wrote:
> +Cc Hyungwon,
> 
> On 06/24/2015 06:35 AM, Gustavo Padovan wrote:
>> From: Gustavo Padovan 
>>
>> exynos_dp_commit() was getting called twice by exynos encoder core, once
>> inside the .enable() call and another time by .commit() itself.
>>
>> The remove of the second call caused the wake of a bug, the operations
>> orders inside exynos_dp_commit was wrong and we had to move
>> exynos_dp_start_video() to be the last operation in there.
>>
> 
> Hyungwon, can you check this?
> 

I confused that this is about dsi and you involved in exynos dsi driver
lately, so i requested.

Sorry for that.


[PATCH 3/3] drm/exynos: remove drm_iommu_attach_device_if_possible

2015-07-02 Thread Joonyoung Shim
Already drm_iommu_attach_device checks whether support iommu internally.
It should clear channels always regardless iommu support. We didn't know
because we can detect the problem when iommu is enabled, so we don't
have to use drm_iommu_attach_device_if_possible and then we can remove
drm_iommu_attach_device_if_possible and clear_channels function pointer.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c |  5 +++--
 drivers/gpu/drm/exynos/exynos7_drm_decon.c|  5 +++--
 drivers/gpu/drm/exynos/exynos_drm_drv.h   |  1 -
 drivers/gpu/drm/exynos/exynos_drm_fimd.c  |  5 +++--
 drivers/gpu/drm/exynos/exynos_drm_iommu.c | 11 ---
 drivers/gpu/drm/exynos/exynos_drm_iommu.h | 11 ---
 drivers/gpu/drm/exynos/exynos_mixer.c |  3 +--
 7 files changed, 10 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c 
b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index ba43437..b2794f8 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -463,7 +463,6 @@ static struct exynos_drm_crtc_ops decon_crtc_ops = {
.win_commit = decon_win_commit,
.win_disable= decon_win_disable,
.te_handler = decon_te_irq_handler,
-   .clear_channels = decon_clear_channels,
 };

 static int decon_bind(struct device *dev, struct device *master, void *data)
@@ -497,7 +496,9 @@ static int decon_bind(struct device *dev, struct device 
*master, void *data)
goto err;
}

-   ret = drm_iommu_attach_device_if_possible(ctx->crtc, drm_dev, dev);
+   decon_clear_channels(ctx->crtc);
+
+   ret = drm_iommu_attach_device(drm_dev, dev);
if (ret)
goto err;

diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c 
b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index 2c29635..a80b918 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -126,7 +126,9 @@ static int decon_ctx_initialize(struct decon_context *ctx,
ctx->drm_dev = drm_dev;
ctx->pipe = priv->pipe++;

-   ret = drm_iommu_attach_device_if_possible(ctx->crtc, drm_dev, ctx->dev);
+   decon_clear_channels(ctx->crtc);
+
+   ret = drm_iommu_attach_device(drm_dev, ctx->dev);
if (ret)
priv->pipe--;

@@ -622,7 +624,6 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = {
.wait_for_vblank = decon_wait_for_vblank,
.win_commit = decon_win_commit,
.win_disable = decon_win_disable,
-   .clear_channels = decon_clear_channels,
 };


diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index dd00f16..7da593f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -177,7 +177,6 @@ struct exynos_drm_crtc_ops {
void (*win_disable)(struct exynos_drm_crtc *crtc, unsigned int zpos);
void (*te_handler)(struct exynos_drm_crtc *crtc);
void (*clock_enable)(struct exynos_drm_crtc *crtc, bool enable);
-   void (*clear_channels)(struct exynos_drm_crtc *crtc);
 };

 /*
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c 
b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 300730c..8d362b9 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -887,7 +887,6 @@ static const struct exynos_drm_crtc_ops fimd_crtc_ops = {
.win_disable = fimd_win_disable,
.te_handler = fimd_te_handler,
.clock_enable = fimd_dp_clock_enable,
-   .clear_channels = fimd_clear_channels,
 };

 static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
@@ -957,7 +956,9 @@ static int fimd_bind(struct device *dev, struct device 
*master, void *data)
if (ctx->display)
exynos_drm_create_enc_conn(drm_dev, ctx->display);

-   ret = drm_iommu_attach_device_if_possible(ctx->crtc, drm_dev, dev);
+   fimd_clear_channels(ctx->crtc);
+
+   ret = drm_iommu_attach_device(drm_dev, dev);
if (ret)
priv->pipe--;

diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.c 
b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
index 4c2ec1b..055e8ec 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_iommu.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
@@ -142,14 +142,3 @@ void drm_iommu_detach_device(struct drm_device *drm_dev,
iommu_detach_device(mapping->domain, subdrv_dev);
drm_release_iommu_mapping(drm_dev);
 }
-
-int drm_iommu_attach_device_if_possible(struct exynos_drm_crtc *exynos_crtc,
-   struct drm_device *drm_dev, struct device *subdrv_dev)
-{
-   if (is_drm_iommu_supported(drm_dev)) {
-   if (exynos_crtc->ops->clear_channels)
-   exynos_crtc->ops->clear_channels(exynos_crtc)

[PATCH 2/3] drm/exynos: remove unnecessary checking to support iommu

2015-07-02 Thread Joonyoung Shim
Already drm_iommu_attach_device and drm_iommu_detach_device check
whether support iommu internally, so we don't have to call
is_drm_iommu_supported before call them.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c |  3 +--
 drivers/gpu/drm/exynos/exynos7_drm_decon.c|  3 +--
 drivers/gpu/drm/exynos/exynos_drm_fimd.c  |  9 +
 drivers/gpu/drm/exynos/exynos_drm_g2d.c   |  6 --
 drivers/gpu/drm/exynos/exynos_drm_iommu.c | 11 +++
 drivers/gpu/drm/exynos/exynos_drm_ipp.c   | 16 ++--
 drivers/gpu/drm/exynos/exynos_mixer.c |  3 +--
 7 files changed, 13 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c 
b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index 8b1225f..ba43437 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -514,8 +514,7 @@ static void decon_unbind(struct device *dev, struct device 
*master, void *data)
decon_disable(ctx->crtc);

/* detach this sub driver from iommu mapping if supported. */
-   if (is_drm_iommu_supported(ctx->drm_dev))
-   drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
+   drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
 }

 static const struct component_ops decon_component_ops = {
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c 
b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index 362532a..2c29635 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -136,8 +136,7 @@ static int decon_ctx_initialize(struct decon_context *ctx,
 static void decon_ctx_remove(struct decon_context *ctx)
 {
/* detach this sub driver from iommu mapping if supported. */
-   if (is_drm_iommu_supported(ctx->drm_dev))
-   drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
+   drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
 }

 static u32 decon_calc_clkdiv(struct decon_context *ctx,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c 
b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 794e56c..300730c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -348,13 +348,6 @@ static void fimd_clear_channels(struct exynos_drm_crtc 
*crtc)
pm_runtime_put(ctx->dev);
 }

-static void fimd_iommu_detach_devices(struct fimd_context *ctx)
-{
-   /* detach this sub driver from iommu mapping if supported. */
-   if (is_drm_iommu_supported(ctx->drm_dev))
-   drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
-}
-
 static u32 fimd_calc_clkdiv(struct fimd_context *ctx,
const struct drm_display_mode *mode)
 {
@@ -978,7 +971,7 @@ static void fimd_unbind(struct device *dev, struct device 
*master,

fimd_disable(ctx->crtc);

-   fimd_iommu_detach_devices(ctx);
+   drm_iommu_detach_device(ctx->drm_dev, ctx->dev);

if (ctx->display)
exynos_dpi_remove(ctx->display);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c 
b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index 7584834..7fb8d0b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -1288,9 +1288,6 @@ static int g2d_subdrv_probe(struct drm_device *drm_dev, 
struct device *dev)
return ret;
}

-   if (!is_drm_iommu_supported(drm_dev))
-   return 0;
-
ret = drm_iommu_attach_device(drm_dev, dev);
if (ret < 0) {
dev_err(dev, "failed to enable iommu.\n");
@@ -1303,9 +1300,6 @@ static int g2d_subdrv_probe(struct drm_device *drm_dev, 
struct device *dev)

 static void g2d_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
 {
-   if (!is_drm_iommu_supported(drm_dev))
-   return;
-
drm_iommu_detach_device(drm_dev, dev);
 }

diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.c 
b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
index d4ec746..4c2ec1b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_iommu.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
@@ -87,10 +87,8 @@ int drm_iommu_attach_device(struct drm_device *drm_dev,
struct device *dev = drm_dev->dev;
int ret;

-   if (!dev->archdata.mapping) {
-   DRM_ERROR("iommu_mapping is null.\n");
-   return -EFAULT;
-   }
+   if (!dev->archdata.mapping)
+   return 0;

subdrv_dev->dma_parms = devm_kzalloc(subdrv_dev,
sizeof(*subdrv_dev->dma_parms),
@@ -148,13 +146,10 @@ void drm_iommu_detach_device(struct drm_device *drm_dev,
 int drm_iommu_attach_device_if_possible(struct exynos_drm_crtc *exynos_crtc,
struct drm_device *drm_dev, struct device *subdrv_dev)
 {
-   int ret = 0;
-
if (is_drm_iommu_supported(drm

[PATCH 1/3] drm/exynos: remove to use ifdef CONFIG_ARM_DMA_USE_IOMMU

2015-07-02 Thread Joonyoung Shim
If CONFIG_ARM_DMA_USE_IOMMU is disable, CONFIG_DRM_EXYNOS_IOMMU also is
disable. When CONFIG_DRM_EXYNOS_IOMMU is disable,
is_drm_iommu_supported() returns always false, so we can remove to use
ifdef CONFIG_ARM_DMA_USE_IOMMU in is_drm_iommu_supported().

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_iommu.h | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.h 
b/drivers/gpu/drm/exynos/exynos_drm_iommu.h
index 8341c7a..a90357f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_iommu.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.h
@@ -29,13 +29,9 @@ void drm_iommu_detach_device(struct drm_device *dev_dev,

 static inline bool is_drm_iommu_supported(struct drm_device *drm_dev)
 {
-#ifdef CONFIG_ARM_DMA_USE_IOMMU
struct device *dev = drm_dev->dev;

return dev->archdata.mapping ? true : false;
-#else
-   return false;
-#endif
 }

 int drm_iommu_attach_device_if_possible(
-- 
1.9.1



[PATCH] drm/exynos: fix vsync interrupt clear routine of mixer

2015-07-02 Thread Joonyoung Shim
INT_EN_VSYNC bit is not used when we clear vsync interrupt but
INT_STATUS_VSYNC bit should be related.

Also, if we want to enable vsync interrupt, we should write 1 in
INT_CLEAR_VSYNC bit before we set INT_EN_VSYNC bit. It will clear prior
vsync interrupt. You can check it from exynos mixer user manual.

Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_mixer.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
b/drivers/gpu/drm/exynos/exynos_mixer.c
index cae98db..60538bf 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -739,15 +739,14 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
atomic_set(>wait_vsync_event, 0);
wake_up(>wait_vsync_queue);
}
-   }

 out:
-   /* clear interrupts */
-   if (~val & MXR_INT_EN_VSYNC) {
/* vsync interrupt use different bit for read and clear */
-   val &= ~MXR_INT_EN_VSYNC;
+   val &= ~MXR_INT_STATUS_VSYNC;
val |= MXR_INT_CLEAR_VSYNC;
}
+
+   /* clear interrupts */
mixer_reg_write(res, MXR_INT_STATUS, val);

spin_unlock(>reg_slock);
@@ -907,6 +906,7 @@ static int mixer_enable_vblank(struct exynos_drm_crtc *crtc)
}

/* enable vsync interrupt */
+   mixer_reg_write(res, MXR_INT_STATUS, MXR_INT_CLEAR_VSYNC);
mixer_reg_writemask(res, MXR_INT_EN, MXR_INT_EN_VSYNC,
MXR_INT_EN_VSYNC);

-- 
1.9.1



[PATCH] drm/exynos: fix compile error and warning of g2d

2015-07-02 Thread Joonyoung Shim
Should be !g2d_userptr->vec, not !vec. This will fix below compile
error.

drivers/gpu/drm/exynos/exynos_drm_g2d.c: In function 
‘g2d_userptr_get_dma_addr’:
drivers/gpu/drm/exynos/exynos_drm_g2d.c:465:7: error: ‘vec’ undeclared 
(first use in this function)
  if (!vec)

Also, if g2d_userptr->vec is NULL it should assign -ENOMEM in ret. It
will fix below compile warning.

drivers/gpu/drm/exynos/exynos_drm_g2d.c: In function 
‘exynos_g2d_set_cmdlist_ioctl’:
drivers/gpu/drm/exynos/exynos_drm_g2d.c:415:6: warning: ‘ret’ may be used 
uninitialized in this function [-Wmaybe-uninitialized]
  int ret;
  ^
Signed-off-by: Joonyoung Shim 
---
 drivers/gpu/drm/exynos/exynos_drm_g2d.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c 
b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index 810e1ee..7584834 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -462,8 +462,10 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct 
drm_device *drm_dev,
end = PAGE_ALIGN(userptr + size);
npages = (end - start) >> PAGE_SHIFT;
g2d_userptr->vec = frame_vector_create(npages);
-   if (!vec)
+   if (!g2d_userptr->vec) {
+   ret = -ENOMEM;
goto err_free;
+   }

ret = get_vaddr_frames(start, npages, true, true, g2d_userptr->vec);
if (ret != npages) {
-- 
1.9.1



[PATCH] drm/exynos: iommu: fix potential NULL pointer dereference

2015-07-02 Thread Joonyoung Shim
On 06/29/2015 03:35 PM, Hyungwon Hwang wrote:
> Dear Marek,
> 
> On Thu, 25 Jun 2015 15:10:12 +0200
> Marek Szyprowski  wrote:
> 
>> Some drivers (like Exynos mixer) calls
>> drm_iommu_attach_device_if_possible before registering crtc, so
>> additional check for NULL crtc pointer is required.
> 
> It seems reasonable.
> 
> Reviewed-by: Hyungwon Hwang 
> 

This patch is ok but i think it can remove to use clear_channels
function pointer and drm_iommu_attach_device_if_possible function
because already drm_iommu_attach_device function checks whether support
iommu internally.

I will ready related patch.

Thanks.

>>
>> Signed-off-by: Marek Szyprowski 
>> ---
>>  drivers/gpu/drm/exynos/exynos_drm_iommu.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.c
>> b/drivers/gpu/drm/exynos/exynos_drm_iommu.c index
>> d4ec7465e9cc..d4eb730ba254 100644 ---
>> a/drivers/gpu/drm/exynos/exynos_drm_iommu.c +++
>> b/drivers/gpu/drm/exynos/exynos_drm_iommu.c @@ -151,7 +151,7 @@ int
>> drm_iommu_attach_device_if_possible(struct exynos_drm_crtc
>> *exynos_crtc, int ret = 0; 
>>  if (is_drm_iommu_supported(drm_dev)) {
>> -if (exynos_crtc->ops->clear_channels)
>> +if (exynos_crtc && exynos_crtc->ops->clear_channels)
>>  exynos_crtc->ops->clear_channels(exynos_crtc);
>>  return drm_iommu_attach_device(drm_dev, subdrv_dev);
>>  }
> 
> 



[PATCH 00/23] drm/exynos: atomic improvements + exynos_encoder removal

2015-07-02 Thread Joonyoung Shim
Hi Gustavo,

On 06/24/2015 06:35 AM, Gustavo Padovan wrote:
> From: Gustavo Padovan 
> 
> Hi,
> 
> This set improves exynos in a number of ways. The first five patches are
> general clean up/fixes.
> 
> Patches 06 to 12 are improvements on top of the newly added atomic modesetting
> support.

I'm not sure yet whether need locking for atomic asynchronous commit.

> 
> Patches 13-23 are a big journey to completely remove the internal
> exynos_drm_encoder struct. Now exynos encoders register themselves directly
> with the drm core.
> 
> Please review!

I reviewed roughly and i think it seems be almost good. I will test it
if i can have more time.

Thanks.

> 
>   Gustavo
> 
> Gustavo Padovan (23):
>   drm/exynos: pass the correct pipe number
>   drm/exynos: calculate vrefresh instead of use a fixed value
>   drm/exynos: use KMS version of DRM vblanks functions
>   drm/exynos: remove duplicated check for suspend
>   drm/exynos: Kconfig: select DP if FIMD or DECON are selected
>   drm/exynos: add atomic asynchronous commit
>   drm/exynos: rename win_commit/disable to atomic-like names
>   drm/exynos: pass struct exynos_drm_plane in update/enable
>   drm/exynos: use drm atomic state directly
>   drm/exynos: remove unused fields from struct exynos_drm_plane
>   drm/exynos: unify exynos_drm_plane names with drm core
>   drm/exynos: don't track enabled state at exynos_crtc
>   drm/exynos: split display's .dpms() into .enable() and .disable()
>   drm/exynos: remove wrappers for phy_power_{on,off}
>   drm/exynos: remove unused .remove() and .check_mode() ops from display
>   drm/exynos: simplify calculation of possible CRTCs
>   drm/exynos: remove struct exynos_drm_display
>   drm/exynos: remove extra call to hdmi_commit()
>   drm/exynos: remove extra call to exynos_dp_commit()
>   drm/exynos: remove exynos_encoder's .commit() op
>   drm/exynos: remove exynos_drm_create_enc_conn()
>   drm/exynos: fold encoder setup into exynos_drm_load()
>   drm/exynos: remove struct exynos_drm_encoder layer
> 
>  drivers/gpu/drm/exynos/Kconfig  |   4 +-
>  drivers/gpu/drm/exynos/Makefile |   7 +-
>  drivers/gpu/drm/exynos/exynos7_drm_decon.c  |  86 +++---
>  drivers/gpu/drm/exynos/exynos_dp_core.c | 122 +--
>  drivers/gpu/drm/exynos/exynos_dp_core.h |   3 +-
>  drivers/gpu/drm/exynos/exynos_drm_core.c|  36 --
>  drivers/gpu/drm/exynos/exynos_drm_crtc.c|  33 ++
>  drivers/gpu/drm/exynos/exynos_drm_crtc.h|   4 +-
>  drivers/gpu/drm/exynos/exynos_drm_dpi.c |  96 ---
>  drivers/gpu/drm/exynos/exynos_drm_drv.c |  19 ++-
>  drivers/gpu/drm/exynos/exynos_drm_drv.h | 115 +-
>  drivers/gpu/drm/exynos/exynos_drm_dsi.c | 129 ++---
>  drivers/gpu/drm/exynos/exynos_drm_encoder.c | 174 
> 
>  drivers/gpu/drm/exynos/exynos_drm_encoder.h |  23 
>  drivers/gpu/drm/exynos/exynos_drm_fb.c  |  51 ++--
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c|  99 +++-
>  drivers/gpu/drm/exynos/exynos_drm_plane.c   |  31 ++---
>  drivers/gpu/drm/exynos/exynos_drm_vidi.c| 107 +
>  drivers/gpu/drm/exynos/exynos_hdmi.c| 168 +--
>  drivers/gpu/drm/exynos/exynos_mixer.c   | 111 +-
>  20 files changed, 572 insertions(+), 846 deletions(-)
>  delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_encoder.c
>  delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_encoder.h
> 



[PATCH 19/23] drm/exynos: remove extra call to exynos_dp_commit()

2015-07-02 Thread Joonyoung Shim
+Cc Hyungwon,

On 06/24/2015 06:35 AM, Gustavo Padovan wrote:
> From: Gustavo Padovan 
> 
> exynos_dp_commit() was getting called twice by exynos encoder core, once
> inside the .enable() call and another time by .commit() itself.
> 
> The remove of the second call caused the wake of a bug, the operations
> orders inside exynos_dp_commit was wrong and we had to move
> exynos_dp_start_video() to be the last operation in there.
> 

Hyungwon, can you check this?

> Signed-off-by: Gustavo Padovan 
> ---
>  drivers/gpu/drm/exynos/exynos_dp_core.c | 7 +++
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c 
> b/drivers/gpu/drm/exynos/exynos_dp_core.c
> index 8614b4f..c853b46 100644
> --- a/drivers/gpu/drm/exynos/exynos_dp_core.c
> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
> @@ -796,9 +796,6 @@ static int exynos_dp_config_video(struct exynos_dp_device 
> *dp)
>   /* Configure video slave mode */
>   exynos_dp_enable_video_master(dp, 0);
>  
> - /* Enable video */
> - exynos_dp_start_video(dp);
> -
>   timeout_loop = 0;
>  
>   for (;;) {
> @@ -939,6 +936,9 @@ static void exynos_dp_commit(struct exynos_drm_encoder 
> *encoder)
>   if (drm_panel_enable(dp->panel))
>   DRM_ERROR("failed to enable the panel\n");
>   }
> +
> + /* Enable video */
> + exynos_dp_start_video(dp);
>  }
>  
>  static enum drm_connector_status exynos_dp_detect(
> @@ -1108,7 +1108,6 @@ static struct exynos_drm_encoder_ops 
> exynos_dp_encoder_ops = {
>   .create_connector = exynos_dp_create_connector,
>   .enable = exynos_dp_enable,
>   .disable = exynos_dp_disable,
> - .commit = exynos_dp_commit,
>  };
>  
>  static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
> 



  1   2   3   4   5   6   >