[PATCH v3] drm/rockchip: support non-iommu buffer path

2016-04-29 Thread Mark Yao
Some rockchip vop not support iommu, need use non-iommu
buffer for it. And if we get iommu issues, we can compare
the issues with non-iommu path, the would help the debug.

Signed-off-by: Mark Yao 
---
Changes in v3
- fix conflict with other iommu patch.
Changes in v2
Advised by Heiko Stuebner
- use more suitable message print.

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 64 +
 1 file changed, 46 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 1e2d88b..0bd1cea 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -36,6 +36,8 @@
 #define DRIVER_MAJOR   1
 #define DRIVER_MINOR   0

+static bool is_support_iommu = true;
+
 /*
  * Attach a (component) device to the shared drm dma mapping from master drm
  * device.  This is used by the VOPs to map GEM buffers to a common DMA
@@ -47,6 +49,9 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
struct dma_iommu_mapping *mapping = drm_dev->dev->archdata.mapping;
int ret;

+   if (!is_support_iommu)
+   return 0;
+
ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
if (ret)
return ret;
@@ -59,6 +64,9 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
 void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
struct device *dev)
 {
+   if (!is_support_iommu)
+   return;
+
arm_iommu_detach_device(dev);
 }

@@ -152,23 +160,26 @@ static int rockchip_drm_load(struct drm_device *drm_dev, 
unsigned long flags)
goto err_config_cleanup;
}

-   /* TODO(djkurtz): fetch the mapping start/size from somewhere */
-   mapping = arm_iommu_create_mapping(&platform_bus_type, 0x,
-  SZ_2G);
-   if (IS_ERR(mapping)) {
-   ret = PTR_ERR(mapping);
-   goto err_config_cleanup;
-   }
+   if (is_support_iommu) {
+   /* TODO(djkurtz): fetch the mapping start/size from somewhere */
+   mapping = arm_iommu_create_mapping(&platform_bus_type,
+  0x,
+  SZ_2G);
+   if (IS_ERR(mapping)) {
+   ret = PTR_ERR(mapping);
+   goto err_config_cleanup;
+   }

-   ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
-   if (ret)
-   goto err_release_mapping;
+   ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+   if (ret)
+   goto err_release_mapping;

-   dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
+   dma_set_max_seg_size(dev, DMA_BIT_MASK(32));

-   ret = arm_iommu_attach_device(dev, mapping);
-   if (ret)
-   goto err_release_mapping;
+   ret = arm_iommu_attach_device(dev, mapping);
+   if (ret)
+   goto err_release_mapping;
+   }

/* Try to bind all sub drivers. */
ret = component_bind_all(dev, drm_dev);
@@ -218,7 +229,8 @@ static int rockchip_drm_load(struct drm_device *drm_dev, 
unsigned long flags)
if (ret)
goto err_vblank_cleanup;

-   arm_iommu_release_mapping(mapping);
+   if (is_support_iommu)
+   arm_iommu_release_mapping(mapping);
return 0;
 err_vblank_cleanup:
drm_vblank_cleanup(drm_dev);
@@ -227,9 +239,11 @@ err_kms_helper_poll_fini:
 err_unbind:
component_unbind_all(dev, drm_dev);
 err_detach_device:
-   arm_iommu_detach_device(dev);
+   if (is_support_iommu)
+   arm_iommu_detach_device(dev);
 err_release_mapping:
-   arm_iommu_release_mapping(mapping);
+   if (is_support_iommu)
+   arm_iommu_release_mapping(mapping);
 err_config_cleanup:
drm_mode_config_cleanup(drm_dev);
drm_dev->dev_private = NULL;
@@ -244,7 +258,8 @@ static int rockchip_drm_unload(struct drm_device *drm_dev)
drm_vblank_cleanup(drm_dev);
drm_kms_helper_poll_fini(drm_dev);
component_unbind_all(dev, drm_dev);
-   arm_iommu_detach_device(dev);
+   if (is_support_iommu)
+   arm_iommu_detach_device(dev);
drm_mode_config_cleanup(drm_dev);
drm_dev->dev_private = NULL;

@@ -488,6 +503,8 @@ static int rockchip_drm_platform_probe(struct 
platform_device *pdev)
 * works as expected.
 */
for (i = 0;; i++) {
+   struct device_node *iommu;
+
port = of_parse_phandle(np, "ports", i);
if (!port)
break;
@@ -497,6 +514,17 @@ static int rockchip_drm_platform_probe(struct 
platform_device *pdev)
  

[PATCH] drm/rockchip: vop: fix iommu crash with async atomic

2016-04-29 Thread Mark Yao
On Async atomic_commit callback, drm_atomic_clean_old_fb will
clean all old fb, but because async, the old fb may be also on
the vop hardware, dma will access the old fb buffer, clean old
fb will cause iommu page fault.

Reference the fb and unreference it when the fb actuall swap out
from vop hardware.

Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 28596e7..38c4de9 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -560,6 +560,22 @@ static void vop_plane_destroy(struct drm_plane *plane)
drm_plane_cleanup(plane);
 }

+static int vop_plane_prepare_fb(struct drm_plane *plane,
+const struct drm_plane_state *new_state)
+{
+   if (plane->state->fb)
+   drm_framebuffer_reference(plane->state->fb);
+
+   return 0;
+}
+
+static void vop_plane_cleanup_fb(struct drm_plane *plane,
+ const struct drm_plane_state *old_state)
+{
+   if (old_state->fb)
+   drm_framebuffer_unreference(old_state->fb);
+}
+
 static int vop_plane_atomic_check(struct drm_plane *plane,
   struct drm_plane_state *state)
 {
@@ -756,6 +772,8 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
 }

 static const struct drm_plane_helper_funcs plane_helper_funcs = {
+   .prepare_fb = vop_plane_prepare_fb,
+   .cleanup_fb = vop_plane_cleanup_fb,
.atomic_check = vop_plane_atomic_check,
.atomic_update = vop_plane_atomic_update,
.atomic_disable = vop_plane_atomic_disable,
-- 
1.9.1




[PATCH] drm/rockchip: vop: Initialize vskiplines to zero

2016-04-29 Thread Mark Yao
There is a path that use vskiplines with non-initialize.
That would cause vop abnormal behavior.

Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 8652bb1..bf55cda 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -310,7 +310,7 @@ static void scl_vop_cal_scl_fac(struct vop *vop, const 
struct vop_win_data *win,
uint16_t vsu_mode;
uint16_t lb_mode;
uint32_t val;
-   int vskiplines;
+   int vskiplines = 0;

if (dst_w > 3840) {
DRM_ERROR("Maximum destination width (3840) exceeded\n");
-- 
1.9.1




[PATCH v2] drm/rockchip: vop: fix iommu crash with async atomic

2016-04-29 Thread Mark Yao
After async atomic_commit callback, drm_atomic_clean_old_fb will
cleanup all old fb, but because async, the old fb may be also on
the vop hardware, dma will access the old fb buffer, clean old
fb will cause iommu page fault.

Fix the problem by reference the fb and unreference it when the fb
actually swap out from vop hardware.

Signed-off-by: Mark Yao 
---
Changes in v2:
- fix some format problem.

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 28596e7..8652bb1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -560,6 +560,22 @@ static void vop_plane_destroy(struct drm_plane *plane)
drm_plane_cleanup(plane);
 }

+static int vop_plane_prepare_fb(struct drm_plane *plane,
+   const struct drm_plane_state *new_state)
+{
+   if (plane->state->fb)
+   drm_framebuffer_reference(plane->state->fb);
+
+   return 0;
+}
+
+static void vop_plane_cleanup_fb(struct drm_plane *plane,
+const struct drm_plane_state *old_state)
+{
+   if (old_state->fb)
+   drm_framebuffer_unreference(old_state->fb);
+}
+
 static int vop_plane_atomic_check(struct drm_plane *plane,
   struct drm_plane_state *state)
 {
@@ -756,6 +772,8 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
 }

 static const struct drm_plane_helper_funcs plane_helper_funcs = {
+   .prepare_fb = vop_plane_prepare_fb,
+   .cleanup_fb = vop_plane_cleanup_fb,
.atomic_check = vop_plane_atomic_check,
.atomic_update = vop_plane_atomic_update,
.atomic_disable = vop_plane_atomic_disable,
-- 
1.9.1




[PATCH] drm/rockchip: fix fbdev crash when not use DRM_FBDEV_EMULATION

2016-08-03 Thread Mark Yao
[1.162571] Unable to handle kernel NULL pointer dereference at virtual 
address 0200
[1.165656] Modules linked in:
[1.165941] CPU: 5 PID: 143 Comm: kworker/5:2 Not tainted 4.4.15 #237
[1.166506] Hardware name: Rockchip RK3399 Evaluation Board v1 (Android) (DT)
[1.167153] Workqueue: events output_poll_execute
[1.168231] PC is at mutex_lock+0x14/0x44
[1.168586] LR is at drm_fb_helper_hotplug_event+0x28/0xcc
[1.172192] [] mutex_lock+0x14/0x44
[1.172196] [] drm_fb_helper_hotplug_event+0x28/0xcc
[1.172201] [] rockchip_drm_output_poll_changed+0x14/0x1c
[1.172204] [] drm_kms_helper_hotplug_event+0x28/0x34
[1.172207] [] output_poll_execute+0x150/0x198
[1.172212] [] process_one_work+0x218/0x3dc
[1.172215] [] worker_thread+0x24c/0x374
[1.172217] [] kthread+0xdc/0xe4
[1.17] [] ret_from_fork+0x10/0x40

Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c   | 13 ++---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |  8 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c|  6 +++---
 drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 26 +-
 4 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index a822d49..1a4dad6 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -261,7 +261,10 @@ static void rockchip_drm_lastclose(struct drm_device *dev)
 {
struct rockchip_drm_private *priv = dev->dev_private;

-   drm_fb_helper_restore_fbdev_mode_unlocked(&priv->fbdev_helper);
+   if (!priv->fbdev)
+   return;
+
+   drm_fb_helper_restore_fbdev_mode_unlocked(&priv->fbdev->fbdev_helper);
 }

 static const struct file_operations rockchip_drm_driver_fops = {
@@ -310,8 +313,10 @@ void rockchip_drm_fb_suspend(struct drm_device *drm)
 {
struct rockchip_drm_private *priv = drm->dev_private;

+   if (!priv->fbdev)
+   return;
console_lock();
-   drm_fb_helper_set_suspend(&priv->fbdev_helper, 1);
+   drm_fb_helper_set_suspend(&priv->fbdev->fbdev_helper, 1);
console_unlock();
 }

@@ -319,8 +324,10 @@ void rockchip_drm_fb_resume(struct drm_device *drm)
 {
struct rockchip_drm_private *priv = drm->dev_private;

+   if (!priv->fbdev)
+   return;
console_lock();
-   drm_fb_helper_set_suspend(&priv->fbdev_helper, 0);
+   drm_fb_helper_set_suspend(&priv->fbdev->fbdev_helper, 0);
console_unlock();
 }

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index ea39329..c054fc2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -50,6 +50,11 @@ struct rockchip_crtc_state {
 #define to_rockchip_crtc_state(s) \
container_of(s, struct rockchip_crtc_state, base)

+struct rockchip_drm_fbdev {
+   struct drm_fb_helper fbdev_helper;
+   struct drm_gem_object *fbdev_bo;
+};
+
 /*
  * Rockchip drm private structure.
  *
@@ -57,8 +62,7 @@ struct rockchip_crtc_state {
  * @num_pipe: number of pipes for this device.
  */
 struct rockchip_drm_private {
-   struct drm_fb_helper fbdev_helper;
-   struct drm_gem_object *fbdev_bo;
+   struct rockchip_drm_fbdev *fbdev;
const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
struct drm_atomic_state *state;
 };
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 55c5273..fef6f8d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -156,10 +156,10 @@ err_gem_object_unreference:
 static void rockchip_drm_output_poll_changed(struct drm_device *dev)
 {
struct rockchip_drm_private *private = dev->dev_private;
-   struct drm_fb_helper *fb_helper = &private->fbdev_helper;
+   struct rockchip_drm_fbdev *fbdev = private->fbdev;

-   if (fb_helper)
-   drm_fb_helper_hotplug_event(fb_helper);
+   if (fbdev)
+   drm_fb_helper_hotplug_event(&fbdev->fbdev_helper);
 }

 static void rockchip_crtc_wait_for_update(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
index 207e01d..cc5781a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
@@ -22,16 +22,16 @@
 #include "rockchip_drm_fb.h"

 #define PREFERRED_BPP  32
-#define to_drm_private(x) \
-   container_of(x, struct rockchip_drm_private, fbdev_helper)
+#define to_rockchip_fbdev(x) \
+   container_of(x, struct rockchip_drm_fbdev, fbdev_helper)

 static int rockchip_fbdev_mmap(struct fb_inf

[PATCH] drm/rockchip: fix fbdev crash when not use DRM_FBDEV_EMULATION

2016-08-03 Thread Mark yao
On 2016年08月03日 16:46, Daniel Vetter wrote:
> On Wed, Aug 03, 2016 at 10:43:21AM +0200, Daniel Vetter wrote:
>> On Wed, Aug 03, 2016 at 04:13:45PM +0800, Mark Yao wrote:
>>> [1.162571] Unable to handle kernel NULL pointer dereference at virtual 
>>> address 0200
>>> [1.165656] Modules linked in:
>>> [1.165941] CPU: 5 PID: 143 Comm: kworker/5:2 Not tainted 4.4.15 #237
>>> [1.166506] Hardware name: Rockchip RK3399 Evaluation Board v1 (Android) 
>>> (DT)
>>> [1.167153] Workqueue: events output_poll_execute
>>> [1.168231] PC is at mutex_lock+0x14/0x44
>>> [1.168586] LR is at drm_fb_helper_hotplug_event+0x28/0xcc
>>> [1.172192] [] mutex_lock+0x14/0x44
>>> [1.172196] [] drm_fb_helper_hotplug_event+0x28/0xcc
>>> [1.172201] [] 
>>> rockchip_drm_output_poll_changed+0x14/0x1c
>>> [1.172204] [] drm_kms_helper_hotplug_event+0x28/0x34
>>> [1.172207] [] output_poll_execute+0x150/0x198
>>> [1.172212] [] process_one_work+0x218/0x3dc
>>> [1.172215] [] worker_thread+0x24c/0x374
>>> [1.172217] [] kthread+0xdc/0xe4
>>> [1.17] [] ret_from_fork+0x10/0x40
>>>
>>> Signed-off-by: Mark Yao 
>> Erhm, how exactly did you manage to blow up in there? Without fbdev
>> support enable drm_fb_helper_hotplug_event() does nothing at all.
>>
>> The fbdev helper is designed such that you _don't_ have to check for NULL
>> everywhere in the driver, that would be pretty bad code.
> And indeed this issue seems preexisting, and was already attempt to fix in
>
> commit 765c35bbd267e93eabe15a94534688ddaa0b9dc7
> Author: Heiko Stübner 
> Date:   Tue Jun 2 16:41:45 2015 +0200
>
>  drm/rockchip: only call drm_fb_helper_hotplug_event if fb_helper present
>
> except that patch is complete nonsense - the added check is always true.
> Oh and it's missing your s-o-b, which is not good at all.
>
> The proper fix is to make delayed fbdev loading work correctly, Thierry
> has patches for that on the mailing list. Not add even more hacks like the
> above (and then slap a misleading subject onto your patch).
> -Daniel

Hmmm, there is a mistake on Heiko's patch:

 struct drm_fb_helper *fb_helper = &private->fbdev_helper;

-   drm_fb_helper_hotplug_event(fb_helper);
   +   if (fb_helper)
   +   drm_fb_helper_hotplug_event(fb_helper);

But the fb_helper would never be NULL, because the private->fbdev_helper 
is not a pointer.

So the first step is making private->fbdev_helper to a pointer, that's 
what I do on this patch.


>> -Daniel
>>
>>> ---
>>>   drivers/gpu/drm/rockchip/rockchip_drm_drv.c   | 13 ++---
>>>   drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |  8 ++--
>>>   drivers/gpu/drm/rockchip/rockchip_drm_fb.c|  6 +++---
>>>   drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 26 
>>> +-
>>>   4 files changed, 36 insertions(+), 17 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
>>> b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
>>> index a822d49..1a4dad6 100644
>>> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
>>> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
>>> @@ -261,7 +261,10 @@ static void rockchip_drm_lastclose(struct drm_device 
>>> *dev)
>>>   {
>>> struct rockchip_drm_private *priv = dev->dev_private;
>>>   
>>> -   drm_fb_helper_restore_fbdev_mode_unlocked(&priv->fbdev_helper);
>>> +   if (!priv->fbdev)
>>> +   return;
>>> +
>>> +   drm_fb_helper_restore_fbdev_mode_unlocked(&priv->fbdev->fbdev_helper);
>>>   }
>>>   
>>>   static const struct file_operations rockchip_drm_driver_fops = {
>>> @@ -310,8 +313,10 @@ void rockchip_drm_fb_suspend(struct drm_device *drm)
>>>   {
>>> struct rockchip_drm_private *priv = drm->dev_private;
>>>   
>>> +   if (!priv->fbdev)
>>> +   return;
>>> console_lock();
>>> -   drm_fb_helper_set_suspend(&priv->fbdev_helper, 1);
>>> +   drm_fb_helper_set_suspend(&priv->fbdev->fbdev_helper, 1);
>>> console_unlock();
>>>   }
>>>   
>>> @@ -319,8 +324,10 @@ void rockchip_drm_fb_resume(struct drm_device *drm)
>>>   {
>>> struct rockchip_drm_private *priv = drm->dev_private;
>>>   
>>> +   if (!priv->fbdev)
>>> +   return;
>>>  

[PATCH 1/3] drm/rockchip: inno_hdmi: add audio support

2016-08-04 Thread Mark yao
Hi Yakir

After apply your patch, I got following warning messge:

drivers/gpu/drm/rockchip/inno_hdmi.c:818:2: warning: initialization from 
incompatible pointer type [enabled by default]
drivers/gpu/drm/rockchip/inno_hdmi.c:818:2: warning: (near 
initialization for 'audio_codec_ops.hw_params') [enabled by default]
drivers/gpu/drm/rockchip/inno_hdmi.c:819:2: warning: initialization from 
incompatible pointer type [enabled by default]
drivers/gpu/drm/rockchip/inno_hdmi.c:819:2: warning: (near 
initialization for 'audio_codec_ops.audio_shutdown') [enabled by default]
drivers/gpu/drm/rockchip/inno_hdmi.c:820:2: warning: initialization from 
incompatible pointer type [enabled by default]
drivers/gpu/drm/rockchip/inno_hdmi.c:820:2: warning: (near 
initialization for 'audio_codec_ops.digital_mute') [enabled by default]
drivers/gpu/drm/rockchip/inno_hdmi.c:821:2: warning: initialization from 
incompatible pointer type [enabled by default]
drivers/gpu/drm/rockchip/inno_hdmi.c:821:2: warning: (near 
initialization for 'audio_codec_ops.get_eld') [enabled by default]

since the commit "efc9194 ASoC: hdmi-codec: callback function will be 
called with private data",
the hdmi_codec_ops had some changes.
Can you rebase your patch to the newest kernel?

Thanks.
On 2016年06月15日 21:28, Yakir Yang wrote:
> Using the common hdmi-codec driver to support hdmi audio function.
>
> Signed-off-by: Yakir Yang 
> ---
>   drivers/gpu/drm/rockchip/inno_hdmi.c | 237 
> ++-
>   drivers/gpu/drm/rockchip/inno_hdmi.h |   2 +
>   2 files changed, 237 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
> b/drivers/gpu/drm/rockchip/inno_hdmi.c
> index f8b4feb..c31dc07 100644
> --- a/drivers/gpu/drm/rockchip/inno_hdmi.c
> +++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
> @@ -29,6 +29,8 @@
>   #include 
>   #include 
>   
> +#include 
> +
>   #include "rockchip_drm_drv.h"
>   #include "rockchip_drm_vop.h"
>   
> @@ -36,6 +38,12 @@
>   
>   #define to_inno_hdmi(x) container_of(x, struct inno_hdmi, x)
>   
> +struct audio_info {
> + int sample_rate;
> + int channels;
> + int sample_width;
> +};
> +
>   struct hdmi_data_info {
>   int vic;
>   bool sink_is_hdmi;
> @@ -71,6 +79,9 @@ struct inno_hdmi {
>   
>   unsigned int tmds_rate;
>   
> + struct platform_device *audio_pdev;
> + bool audio_enable;
> +
>   struct hdmi_data_info   hdmi_data;
>   struct drm_display_mode previous_mode;
>   };
> @@ -306,6 +317,57 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi 
> *hdmi,
>   return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_AVI, 0, 0, 0);
>   }
>   
> +static int inno_hdmi_config_audio_aai(struct inno_hdmi *hdmi,
> +   struct audio_info *audio)
> +{
> + struct hdmi_audio_infoframe *faudio;
> + union hdmi_infoframe frame;
> + int rc;
> +
> + rc = hdmi_audio_infoframe_init(&frame.audio);
> + faudio = (struct hdmi_audio_infoframe *)&frame;
> +
> + faudio->channels = audio->channels;
> +
> + switch (audio->sample_width) {
> + case 16:
> + faudio->sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> + break;
> + case 20:
> + faudio->sample_size = HDMI_AUDIO_SAMPLE_SIZE_20;
> + break;
> + case 24:
> + faudio->sample_size = HDMI_AUDIO_SAMPLE_SIZE_24;
> + break;
> + }
> +
> + switch (audio->sample_rate) {
> + case 32000:
> + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_32000;
> + break;
> + case 44100:
> + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_44100;
> + break;
> + case 48000:
> + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_48000;
> + break;
> + case 88200:
> + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_88200;
> + break;
> + case 96000:
> + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_96000;
> + break;
> + case 176400:
> + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_176400;
> + break;
> + case 192000:
> + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_192000;
> + break;
> + }
> +
> + return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_AAI, 0, 0, 0);
> +}
> +
>   static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
>   {
>   struct hdmi_data_info *data = &hdmi->hdmi_data;
> @@ -478,8 +540,9 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
>   inno_hdmi_i2c_init(hdmi);
>   
>   /* Unmute video and audio output */
> - hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
> -   v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
> + hdmi_modb(hdmi, HDMI_AV_MUTE, m_VIDEO_BLACK, v_VIDEO_MUTE(0));
> + if (hdmi->audio_enable)
> + hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDI

[PATCH v1] drm/rockchip: fix fbdev crash when not use DRM_FBDEV_EMULATION

2016-08-04 Thread Mark Yao
[1.162571] Unable to handle kernel NULL pointer dereference at virtual 
address 0200
[1.165656] Modules linked in:
[1.165941] CPU: 5 PID: 143 Comm: kworker/5:2 Not tainted 4.4.15 #237
[1.166506] Hardware name: Rockchip RK3399 Evaluation Board v1 (Android) (DT)
[1.167153] Workqueue: events output_poll_execute
[1.168231] PC is at mutex_lock+0x14/0x44
[1.168586] LR is at drm_fb_helper_hotplug_event+0x28/0xcc
[1.172192] [] mutex_lock+0x14/0x44
[1.172196] [] drm_fb_helper_hotplug_event+0x28/0xcc
[1.172201] [] rockchip_drm_output_poll_changed+0x14/0x1c
[1.172204] [] drm_kms_helper_hotplug_event+0x28/0x34
[1.172207] [] output_poll_execute+0x150/0x198
[1.172212] [] process_one_work+0x218/0x3dc
[1.172215] [] worker_thread+0x24c/0x374
[1.172217] [] kthread+0xdc/0xe4
[1.17] [] ret_from_fork+0x10/0x40

Signed-off-by: Mark Yao 
---
Change in v1:
Advised by Daniel Vetter
  only do the struct->pointer conversion alone

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c   |  6 +++---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |  2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c|  2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 17 ++---
 4 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index a822d49..fe22f76 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -261,7 +261,7 @@ static void rockchip_drm_lastclose(struct drm_device *dev)
 {
struct rockchip_drm_private *priv = dev->dev_private;

-   drm_fb_helper_restore_fbdev_mode_unlocked(&priv->fbdev_helper);
+   drm_fb_helper_restore_fbdev_mode_unlocked(priv->fbdev_helper);
 }

 static const struct file_operations rockchip_drm_driver_fops = {
@@ -311,7 +311,7 @@ void rockchip_drm_fb_suspend(struct drm_device *drm)
struct rockchip_drm_private *priv = drm->dev_private;

console_lock();
-   drm_fb_helper_set_suspend(&priv->fbdev_helper, 1);
+   drm_fb_helper_set_suspend(priv->fbdev_helper, 1);
console_unlock();
 }

@@ -320,7 +320,7 @@ void rockchip_drm_fb_resume(struct drm_device *drm)
struct rockchip_drm_private *priv = drm->dev_private;

console_lock();
-   drm_fb_helper_set_suspend(&priv->fbdev_helper, 0);
+   drm_fb_helper_set_suspend(priv->fbdev_helper, 0);
console_unlock();
 }

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index ea39329..f005f3f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -57,7 +57,7 @@ struct rockchip_crtc_state {
  * @num_pipe: number of pipes for this device.
  */
 struct rockchip_drm_private {
-   struct drm_fb_helper fbdev_helper;
+   struct drm_fb_helper *fbdev_helper;
struct drm_gem_object *fbdev_bo;
const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
struct drm_atomic_state *state;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 55c5273..dc034ec 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -156,7 +156,7 @@ err_gem_object_unreference:
 static void rockchip_drm_output_poll_changed(struct drm_device *dev)
 {
struct rockchip_drm_private *private = dev->dev_private;
-   struct drm_fb_helper *fb_helper = &private->fbdev_helper;
+   struct drm_fb_helper *fb_helper = private->fbdev_helper;

if (fb_helper)
drm_fb_helper_hotplug_event(fb_helper);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
index 207e01d..6b50dfa 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
@@ -22,14 +22,12 @@
 #include "rockchip_drm_fb.h"

 #define PREFERRED_BPP  32
-#define to_drm_private(x) \
-   container_of(x, struct rockchip_drm_private, fbdev_helper)

 static int rockchip_fbdev_mmap(struct fb_info *info,
   struct vm_area_struct *vma)
 {
struct drm_fb_helper *helper = info->par;
-   struct rockchip_drm_private *private = to_drm_private(helper);
+   struct rockchip_drm_private *private = helper->dev->dev_private;

return rockchip_gem_mmap_buf(private->fbdev_bo, vma);
 }
@@ -50,7 +48,7 @@ static struct fb_ops rockchip_drm_fbdev_ops = {
 static int rockchip_drm_fbdev_create(struct drm_fb_helper *helper,
 struct drm_fb_helper_surface_size *sizes)
 {
-   struct rockchip_drm_private *private = to_drm_private(helper);
+   struct rockchip_drm_private *private = helper->dev->dev_private;
str

[PATCH] drm/rockchip: Properly adjust to a true clock in adjusted_mode

2016-08-09 Thread Mark yao
On 2016年08月09日 03:29, Sean Paul wrote:
> From: Douglas Anderson 
>
> When fixing up the clock in vop_crtc_mode_fixup() we're not doing it
> quite correctly.  Specifically if we've got the true clock 26667 Hz,
> we'll perform this calculation:
> 26667 / 1000 => 26
>
> Later when we try to set the clock we'll do clk_set_rate(26 *
> 1000).  The common clock framework won't actually pick the proper clock
> in this case since it always wants clocks <= the specified one.
>
> Let's solve this by using DIV_ROUND_UP.
Good, applied to my drm fixes.

Thanks

> Signed-off-by: Douglas Anderson 
> Signed-off-by: Sean Paul 
> ---
>   drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
> b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index 31744fe..1bbffaf 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -891,7 +891,8 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
>   struct vop *vop = to_vop(crtc);
>   
>   adjusted_mode->clock =
> - clk_round_rate(vop->dclk, mode->clock * 1000) / 1000;
> + DIV_ROUND_UP(clk_round_rate(vop->dclk, mode->clock * 1000),
> +  1000);
>   
>   return true;
>   }


-- 
ï¼­ark Yao




[PATCH] drm/bridge: dw-hdmi: fix hdmi display lost

2016-08-11 Thread Mark Yao
hdmi->disabled maybe not match to the real hardware status.

->dw_hdmi_bridge_enable()
  hdmi->disabled = false;
-->dw_hdmi_update_power()
   if (hdmi->rxsense)
   force = DRM_FORCE_ON;
   else
   force = DRM_FORCE_OFF;

hdmi->rxsense maybe false on bridge enable path, then hdmi->disabled
is false, but actually hardware is power off, they are not match.

So on dw_hdmi_irq, judge the hardware status with hdmi->disabled is wrong.
This bug would cause display lost, unplug/plug can't recovery display.

Cc: Russell King 
Cc: Daniel Vetter 
Cc: Fabio Estevam 
Cc: Liu Ying 

Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/bridge/dw-hdmi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 77ab473..a4fcb47 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -1563,7 +1563,7 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
if (intr_stat &
(HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
mutex_lock(&hdmi->mutex);
-   if (!hdmi->disabled && !hdmi->force) {
+   if (!hdmi->bridge_is_on && !hdmi->force) {
/*
 * If the RX sense status indicates we're disconnected,
 * clear the software rxsense status.
-- 
1.9.1




[PATCH] drm/bridge: dw-hdmi: fix hdmi display lost

2016-08-11 Thread Mark yao
An HTML attachment was scrubbed...
URL: 



[PATCH] drm/bridge: dw-hdmi: fix hdmi display lost

2016-08-11 Thread Mark yao
An HTML attachment was scrubbed...
URL: 



[v10.1 PATCH 5/5] drm/rockchip: cdn-dp: add cdn DP support for rk3399

2016-08-12 Thread Mark yao
Hi Chris

Looks good for me

only tiny problem comment inline.

Thanks.

On 2016年08月11日 07:32, Chris Zhong wrote:
> Add support for cdn DP controller which is embedded in the rk3399
> SoCs. The DP is compliant with DisplayPort Specification,
> Version 1.3, This IP is compatible with the rockchip type-c PHY IP.
> There is a uCPU in DP controller, it need a firmware to work,
> please put the firmware file to /lib/firmware/rockchip/dptx.bin. The
> uCPU in charge of aux communication and link training, the host use
> mailbox to communicate with the ucpu.
> The dclk pin_pol of vop must not be invert for DP.
>
> Signed-off-by: Chris Zhong 
> Reviewed-by: Sean Paul 
> Acked-by: Mark Yao 
>
> ---
>
> Changes in v10.1:
> - support read sink count from DPCD
>
> Changes in v10:
> - control the grf_clk in DP
>
> Changes in v9:
> - do not need reset the phy before power_on
> - add a orientation information for set_capability
> - retry to read dpcd in 10 seconds
>
> Changes in v8:
> - optimization the err log
>
> Changes in v7:
> - support firmware standby when no dptx connection
> - optimization the calculation of tu size and valid symbol
>
> Changes in v6:
> - add a port struct
> - select SND_SOC_HDMI_CODEC
> - force reset the phy when hpd detected
>
> Changes in v5:
> - alphabetical order
> - do not use long, use u32 or u64
> - return MODE_CLOCK_HIGH when requested > actual
> - Optimized Coding Style
> - add a formula to get better tu size and symbol value.
> - modify according to Sean Paul's comments
> - fixed the fw_wait always 0
>
> Changes in v4:
> - use phy framework to control DP phy
> - support 2 phys
>
> Changes in v3:
> - use EXTCON_DISP_DP and EXTCON_DISP_DP_ALT cable to get dp port state.
> - reset spdif before config it
> - modify the firmware clk to 100Mhz
> - retry load firmware if fw file is requested too early
>
> Changes in v2:
> - Alphabetic order
> - remove excess error message
> - use define clk_rate
> - check all return value
> - remove dev_set_name(dp->dev, "cdn-dp");
> - use schedule_delayed_work
> - remove never-called functions
> - remove some unnecessary ()
>
> Changes in v1:
> - use extcon API
> - use hdmi-codec for the DP Asoc
> - do not initialize the "ret"
> - printk a err log when drm_of_encoder_active_endpoint_id
> - modify the dclk pin_pol to a single line
>
>   drivers/gpu/drm/rockchip/Kconfig|  10 +
>   drivers/gpu/drm/rockchip/Makefile   |   1 +
>   drivers/gpu/drm/rockchip/cdn-dp-core.c  | 937 
> +++
>   drivers/gpu/drm/rockchip/cdn-dp-core.h  | 104 +++
>   drivers/gpu/drm/rockchip/cdn-dp-reg.c   | 959 
> 
>   drivers/gpu/drm/rockchip/cdn-dp-reg.h   | 482 ++
>   drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  13 +-
>   drivers/gpu/drm/rockchip/rockchip_drm_vop.h |   9 +
>   drivers/gpu/drm/rockchip/rockchip_vop_reg.c |   2 +
>   9 files changed, 2514 insertions(+), 3 deletions(-)
>   create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.c
>   create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.h
>   create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.c
>   create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.h
>
> diff --git a/drivers/gpu/drm/rockchip/Kconfig 
> b/drivers/gpu/drm/rockchip/Kconfig
> index d30bdc3..20aaafe 100644
> --- a/drivers/gpu/drm/rockchip/Kconfig
> +++ b/drivers/gpu/drm/rockchip/Kconfig
> @@ -25,6 +25,16 @@ config ROCKCHIP_ANALOGIX_DP
> for the Analogix Core DP driver. If you want to enable DP
> on RK3288 based SoC, you should selet this option.
>   
> +config ROCKCHIP_CDN_DP
> +tristate "Rockchip cdn DP"
> +depends on DRM_ROCKCHIP
> + select SND_SOC_HDMI_CODEC if SND_SOC
> +help
> +   This selects support for Rockchip SoC specific extensions
> +   for the cdn DP driver. If you want to enable Dp on
> +   RK3399 based SoC, you should select this
> +   option.
> +
>   config ROCKCHIP_DW_HDMI
>   tristate "Rockchip specific extensions for Synopsys DW HDMI"
>   depends on DRM_ROCKCHIP
> diff --git a/drivers/gpu/drm/rockchip/Makefile 
> b/drivers/gpu/drm/rockchip/Makefile
> index 05d0713..abdecd5 100644
> --- a/drivers/gpu/drm/rockchip/Makefile
> +++ b/drivers/gpu/drm/rockchip/Makefile
> @@ -7,6 +7,7 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
>   rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
>   
>   obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
> +obj-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.

[PATCH 2/2] drm/rockchip: Use DRM_DEV_ERROR in vop

2016-08-18 Thread Mark yao
On 2016年08月13日 01:00, Sean Paul wrote:
> Since we can have multiple vops, use DRM_DEV_ERROR to
> make logs easier to process.
>
> Signed-off-by: Sean Paul 

looks good for me

Acked-by: Mark Yao 
> ---
>   drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 24 ++--
>   1 file changed, 14 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
> b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index 31744fe..ec8ad00 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -238,7 +238,7 @@ static enum vop_data_format vop_convert_format(uint32_t 
> format)
>   case DRM_FORMAT_NV24:
>   return VOP_FMT_YUV444SP;
>   default:
> - DRM_ERROR("unsupport format[%08x]\n", format);
> + DRM_ERROR("unsupported format[%08x]\n", format);
>   return -EINVAL;
>   }
>   }
> @@ -315,7 +315,7 @@ static void scl_vop_cal_scl_fac(struct vop *vop, const 
> struct vop_win_data *win,
>   int vskiplines = 0;
>   
>   if (dst_w > 3840) {
> - DRM_ERROR("Maximum destination width (3840) exceeded\n");
> + DRM_DEV_ERROR(vop->dev, "Maximum dst width (3840) exceeded\n");
>   return;
>   }
>   
> @@ -353,11 +353,11 @@ static void scl_vop_cal_scl_fac(struct vop *vop, const 
> struct vop_win_data *win,
>   VOP_SCL_SET_EXT(vop, win, lb_mode, lb_mode);
>   if (lb_mode == LB_RGB_3840X2) {
>   if (yrgb_ver_scl_mode != SCALE_NONE) {
> - DRM_ERROR("ERROR : not allow yrgb ver scale\n");
> + DRM_DEV_ERROR(vop->dev, "not allow yrgb ver scale\n");
>   return;
>   }
>   if (cbcr_ver_scl_mode != SCALE_NONE) {
> - DRM_ERROR("ERROR : not allow cbcr ver scale\n");
> + DRM_DEV_ERROR(vop->dev, "not allow cbcr ver scale\n");
>   return;
>   }
>   vsu_mode = SCALE_UP_BIL;
> @@ -970,7 +970,8 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
>   VOP_CTRL_SET(vop, mipi_en, 1);
>   break;
>   default:
> - DRM_ERROR("unsupport connector_type[%d]\n", s->output_type);
> + DRM_DEV_ERROR(vop->dev, "unsupported connector_type [%d]\n",
> +   s->output_type);
>   }
>   VOP_CTRL_SET(vop, out_mode, s->output_mode);
>   
> @@ -1154,7 +1155,8 @@ static irqreturn_t vop_isr(int irq, void *data)
>   
>   /* Unhandled irqs are spurious. */
>   if (active_irqs)
> - DRM_ERROR("Unknown VOP IRQs: %#02x\n", active_irqs);
> + DRM_DEV_ERROR(vop->dev, "Unknown VOP IRQs: %#02x\n",
> +   active_irqs);
>   
>   return ret;
>   }
> @@ -1189,7 +1191,8 @@ static int vop_create_crtc(struct vop *vop)
>  win_data->phy->nformats,
>  win_data->type, NULL);
>   if (ret) {
> - DRM_ERROR("failed to initialize plane\n");
> + DRM_DEV_ERROR(vop->dev, "failed to init plane %d\n",
> +   ret);
>   goto err_cleanup_planes;
>   }
>   
> @@ -1227,7 +1230,8 @@ static int vop_create_crtc(struct vop *vop)
>  win_data->phy->nformats,
>  win_data->type, NULL);
>   if (ret) {
> - DRM_ERROR("failed to initialize overlay plane\n");
> + DRM_DEV_ERROR(vop->dev, "failed to init overlay %d\n",
> +   ret);
>   goto err_cleanup_crtc;
>   }
>   drm_plane_helper_add(&vop_win->base, &plane_helper_funcs);
> @@ -1235,8 +1239,8 @@ static int vop_create_crtc(struct vop *vop)
>   
>   port = of_get_child_by_name(dev->of_node, "port");
>   if (!port) {
> - DRM_ERROR("no port node found in %s\n",
> -   dev->of_node->full_name);
> + DRM_DEV_ERROR(vop->dev, "no port node found in %s\n",
> +   dev->of_node->full_name);
>   ret = -ENOENT;
>   goto err_cleanup_crtc;
>   }


-- 
ï¼­ark Yao




[PATCH v3 1/5] drm/rockchip: sort registers define by chip's number

2016-08-18 Thread Mark yao
Hi Sean

Thanks for send v3 patch for rk3399 vop support.

But sorry for that, I had changed my mind, those patches are deprecated,
I have new rk3399 patch on my downstream kernel, I will upstream soon.

Thanks.

On 2016年08月18日 01:20, Sean Paul wrote:
> From: Mark Yao 
>
> No functional changes, sort the vop registers to make
> code more readable.
>
> Signed-off-by: Mark Yao 
> [seanpaul resolved conflict with name change from _3066 to _3036]
> Signed-off-by: Sean Paul 
> ---
>
> Changes in v3:
>   - Fix typo from _3066 _3036 (Tomasz Figa)
>
>   drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 168 
> ++--
>   1 file changed, 84 insertions(+), 84 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c 
> b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
> index 919992c..44caf14 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
> @@ -50,6 +50,88 @@ static const uint32_t formats_win_lite[] = {
>   DRM_FORMAT_BGR565,
>   };
>   
> +static const struct vop_scl_regs rk3036_win_scl = {
> + .scale_yrgb_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0x, 0x0),
> + .scale_yrgb_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0x, 16),
> + .scale_cbcr_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0x, 0x0),
> + .scale_cbcr_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0x, 16),
> +};
> +
> +static const struct vop_win_phy rk3036_win0_data = {
> + .scl = &rk3036_win_scl,
> + .data_formats = formats_win_full,
> + .nformats = ARRAY_SIZE(formats_win_full),
> + .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 0),
> + .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 3),
> + .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 15),
> + .act_info = VOP_REG(RK3036_WIN0_ACT_INFO, 0x1fff1fff, 0),
> + .dsp_info = VOP_REG(RK3036_WIN0_DSP_INFO, 0x0fff0fff, 0),
> + .dsp_st = VOP_REG(RK3036_WIN0_DSP_ST, 0x1fff1fff, 0),
> + .yrgb_mst = VOP_REG(RK3036_WIN0_YRGB_MST, 0x, 0),
> + .uv_mst = VOP_REG(RK3036_WIN0_CBR_MST, 0x, 0),
> + .yrgb_vir = VOP_REG(RK3036_WIN0_VIR, 0x, 0),
> + .uv_vir = VOP_REG(RK3036_WIN0_VIR, 0x1fff, 16),
> +};
> +
> +static const struct vop_win_phy rk3036_win1_data = {
> + .data_formats = formats_win_lite,
> + .nformats = ARRAY_SIZE(formats_win_lite),
> + .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
> + .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
> + .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
> + .act_info = VOP_REG(RK3036_WIN1_ACT_INFO, 0x1fff1fff, 0),
> + .dsp_info = VOP_REG(RK3036_WIN1_DSP_INFO, 0x0fff0fff, 0),
> + .dsp_st = VOP_REG(RK3036_WIN1_DSP_ST, 0x1fff1fff, 0),
> + .yrgb_mst = VOP_REG(RK3036_WIN1_MST, 0x, 0),
> + .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0x, 0),
> +};
> +
> +static const struct vop_win_data rk3036_vop_win_data[] = {
> + { .base = 0x00, .phy = &rk3036_win0_data,
> +   .type = DRM_PLANE_TYPE_PRIMARY },
> + { .base = 0x00, .phy = &rk3036_win1_data,
> +   .type = DRM_PLANE_TYPE_CURSOR },
> +};
> +
> +static const int rk3036_vop_intrs[] = {
> + DSP_HOLD_VALID_INTR,
> + FS_INTR,
> + LINE_FLAG_INTR,
> + BUS_ERROR_INTR,
> +};
> +
> +static const struct vop_intr rk3036_intr = {
> + .intrs = rk3036_vop_intrs,
> + .nintrs = ARRAY_SIZE(rk3036_vop_intrs),
> + .status = VOP_REG(RK3036_INT_STATUS, 0xf, 0),
> + .enable = VOP_REG(RK3036_INT_STATUS, 0xf, 4),
> + .clear = VOP_REG(RK3036_INT_STATUS, 0xf, 8),
> +};
> +
> +static const struct vop_ctrl rk3036_ctrl_data = {
> + .standby = VOP_REG(RK3036_SYS_CTRL, 0x1, 30),
> + .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
> + .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
> + .htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
> + .hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
> + .vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
> + .vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
> + .cfg_done = VOP_REG(RK3036_REG_CFG_DONE, 0x1, 0),
> +};
> +
> +static const struct vop_reg_data rk3036_vop_init_reg_table[] = {
> + {RK3036_DSP_CTRL1, 0x},
> +};
> +
> +static const struct vop_data rk3036_vop = {
> + .init_table = rk3036_vop_init_reg_table,
> + .table_size = ARRAY_SIZE(rk3036_vop_init_reg_table),
> + .ctrl = &rk3036_ctrl_data,
> + .intr = &rk3036_intr,
> + .win = rk3036_vop_win_data,
> + .win_size = ARRAY_SIZE(rk3036_vop_win_data),
> +};
> +
>   static const struct vop_scl_extension rk3288_win_full_scl_ext = {
>   .cbcr_vsd_mode = VOP_REG(R

[PATCH v3 1/5] drm/rockchip: sort registers define by chip's number

2016-08-18 Thread Mark yao
On 2016年08月18日 17:11, Daniel Vetter wrote:
> On Thu, Aug 18, 2016 at 05:08:14PM +0800, Mark yao wrote:
>> >Hi Sean
>> >
>> >Thanks for send v3 patch for rk3399 vop support.
>> >
>> >But sorry for that, I had changed my mind, those patches are deprecated,
>> >I have new rk3399 patch on my downstream kernel, I will upstream soon.
> Wut? Imo merge Sean's patch here, and then rebase your downstream patches
> on top of it. That you have a downstream tree which is out of sync with
> upstream shouldn't be a reason to stall upstream development.
> -Daniel
>
Yeah, Sorry for that.

In fact, on my downstream kernel, also have those patches, my new rk3399 
patches are based on them,
but the new rk3399 patches will cover the those patches,  Sean's patches 
is old version.

I just want to fast forward, don't want to send two version drivers to 
upstream.
but if you and Dave feel ok for that, I have no problem:-) .

merged Sean's patches and then apply new version patches.

Thanks.

-- 
ï¼­ark Yao




[PATCH v3 1/5] drm/rockchip: sort registers define by chip's number

2016-08-23 Thread Mark yao
On 2016年08月23日 04:30, Sean Paul wrote:
> On Thu, Aug 18, 2016 at 6:02 AM, Mark yao  wrote:
>> On 2016年08月18日 17:11, Daniel Vetter wrote:
>>> On Thu, Aug 18, 2016 at 05:08:14PM +0800, Mark yao wrote:
>>>>> Hi Sean
>>>>>
>>>>> Thanks for send v3 patch for rk3399 vop support.
>>>>>
>>>>> But sorry for that, I had changed my mind, those patches are deprecated,
>>>>> I have new rk3399 patch on my downstream kernel, I will upstream soon.
>>> Wut? Imo merge Sean's patch here, and then rebase your downstream patches
>>> on top of it. That you have a downstream tree which is out of sync with
>>> upstream shouldn't be a reason to stall upstream development.
>>> -Daniel
>>>
>> Yeah, Sorry for that.
>>
>> In fact, on my downstream kernel, also have those patches, my new rk3399
>> patches are based on them,
>> but the new rk3399 patches will cover the those patches,  Sean's patches is
>> old version.
>>
>> I just want to fast forward, don't want to send two version drivers to
>> upstream.
>> but if you and Dave feel ok for that, I have no problem:-) .
>>
>> merged Sean's patches and then apply new version patches.
>>
> Ok, so can I get a review/ack for these revised patches then?
> Something is better than nothing, and there's a bunch of stuff that
> depends on these changes.
>
> Sean
Yes, But I miss your [PATCH v3 0/5] and [PATCH v3 4/5]. do you mean the 
lost patches use v2 version?


>
>
>> Thanks.
>>
>> --
>> ï¼­ark Yao
>>
>>
>
>


-- 
ï¼­ark Yao




[PATCH] drm/bridge: analogix: protect power when get_modes or detect

2016-10-12 Thread Mark Yao
The drm callback ->detect and ->get_modes seems is not power safe,
they may be called when device is power off, do register access on
detect or get_modes will cause system die.

Here is the path call ->detect before analogix_dp power on
[] analogix_dp_detect+0x44/0xdc
[] 
drm_helper_probe_single_connector_modes_merge_bits+0xe8/0x41c
[] drm_helper_probe_single_connector_modes+0x10/0x18
[] drm_mode_getconnector+0xf4/0x304
[] drm_ioctl+0x23c/0x390
[] do_vfs_ioctl+0x4b8/0x58c
[] SyS_ioctl+0x60/0x88

Cc: Inki Dae 
Cc: Sean Paul 
Cc: Gustavo Padovan 
Cc: "Ville Syrjälä" 

Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 28 ++
 1 file changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index efac8ab..09dece2 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1062,6 +1062,13 @@ int analogix_dp_get_modes(struct drm_connector 
*connector)
return 0;
}

+   if (dp->dpms_mode != DRM_MODE_DPMS_ON) {
+   pm_runtime_get_sync(dp->dev);
+
+   if (dp->plat_data->power_on)
+   dp->plat_data->power_on(dp->plat_data);
+   }
+
if (analogix_dp_handle_edid(dp) == 0) {
drm_mode_connector_update_edid_property(&dp->connector, edid);
num_modes += drm_add_edid_modes(&dp->connector, edid);
@@ -1073,6 +1080,13 @@ int analogix_dp_get_modes(struct drm_connector 
*connector)
if (dp->plat_data->get_modes)
num_modes += dp->plat_data->get_modes(dp->plat_data, connector);

+   if (dp->dpms_mode != DRM_MODE_DPMS_ON) {
+   if (dp->plat_data->power_off)
+   dp->plat_data->power_off(dp->plat_data);
+
+   pm_runtime_put_sync(dp->dev);
+   }
+
ret = analogix_dp_prepare_panel(dp, false, false);
if (ret)
DRM_ERROR("Failed to unprepare panel (%d)\n", ret);
@@ -1106,9 +1120,23 @@ analogix_dp_detect(struct drm_connector *connector, bool 
force)
return connector_status_disconnected;
}

+   if (dp->dpms_mode != DRM_MODE_DPMS_ON) {
+   pm_runtime_get_sync(dp->dev);
+
+   if (dp->plat_data->power_on)
+   dp->plat_data->power_on(dp->plat_data);
+   }
+
if (!analogix_dp_detect_hpd(dp))
status = connector_status_connected;

+   if (dp->dpms_mode != DRM_MODE_DPMS_ON) {
+   if (dp->plat_data->power_off)
+   dp->plat_data->power_off(dp->plat_data);
+
+   pm_runtime_put_sync(dp->dev);
+   }
+
ret = analogix_dp_prepare_panel(dp, false, false);
if (ret)
DRM_ERROR("Failed to unprepare panel (%d)\n", ret);
-- 
1.9.1




Question: Re: [PATCH] drm/bridge: analogix: protect power when get_modes or detect

2016-10-12 Thread Mark yao
An HTML attachment was scrubbed...
URL: 



[PATCH v2] drm/bridge: analogix: protect power when get_modes or detect

2016-10-13 Thread Mark Yao
The drm callback ->detect and ->get_modes seems is not power safe,
they may be called when device is power off, do register access on
detect or get_modes will cause system die.

Here is the path call ->detect before analogix_dp power on
[] analogix_dp_detect+0x44/0xdc
[] 
drm_helper_probe_single_connector_modes_merge_bits+0xe8/0x41c
[] drm_helper_probe_single_connector_modes+0x10/0x18
[] drm_mode_getconnector+0xf4/0x304
[] drm_ioctl+0x23c/0x390
[] do_vfs_ioctl+0x4b8/0x58c
[] SyS_ioctl+0x60/0x88

Cc: Inki Dae 
Cc: Sean Paul 
Cc: Gustavo Padovan 
Cc: "Ville Syrjälä" 

Signed-off-by: Mark Yao 
---
Changes in v2:
- remove sub device power on/off callback, use pm_runtime_get/put is enough
to fix my problem, so will can avoid race to dpms.

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index efac8ab..ff2d328 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1062,11 +1062,15 @@ int analogix_dp_get_modes(struct drm_connector 
*connector)
return 0;
}

+   pm_runtime_get_sync(dp->dev);
+
if (analogix_dp_handle_edid(dp) == 0) {
drm_mode_connector_update_edid_property(&dp->connector, edid);
num_modes += drm_add_edid_modes(&dp->connector, edid);
}

+   pm_runtime_put(dp->dev);
+
if (dp->plat_data->panel)
num_modes += drm_panel_get_modes(dp->plat_data->panel);

@@ -1106,9 +1110,13 @@ analogix_dp_detect(struct drm_connector *connector, bool 
force)
return connector_status_disconnected;
}

+   pm_runtime_get_sync(dp->dev);
+
if (!analogix_dp_detect_hpd(dp))
status = connector_status_connected;

+   pm_runtime_put(dp->dev);
+
ret = analogix_dp_prepare_panel(dp, false, false);
if (ret)
DRM_ERROR("Failed to unprepare panel (%d)\n", ret);
-- 
1.9.1




Question: Re: [PATCH] drm/bridge: analogix: protect power when get_modes or detect

2016-10-13 Thread Mark yao
On 2016年10月12日 22:51, Sean Paul wrote:
> On Wed, Oct 12, 2016 at 6:22 AM, Mark yao  wrote:
>> I'm not familiar with the analogix driver, maybe use a power reference count
>> would better then direct power on/off analogix_dp.
>>
>> Does anyone has the idea to protect detect and get_modes context?
>>
> I'm not sure a reference count is going to help here. The common
> pattern is to call detect() followed by get_modes() and then modeset.
> However, it's not guaranteed that any one of those functions will be
> called after the other. So, if you leave things on after detect or
> get_modes, you might be wasting power (or worse).
>
> I recently ran into this exact problem with a panel we're using. Check
> out "0b8b059a7: drm/bridge: analogix_dp: Ensure the panel is properly
> prepared/unprepared". Perhaps you can piggyback on that function to
> add your pm_runtime and plat_data callbacks (since using dpms_mode
> might be racey).
>
> Sean
Hi Sean

Thanks for your advice.

I re-test the detect and get_modes, only use pm_runtime_get/put also can 
fix my problem.
without plat_data callbacks can avoid race to dpms_mode.

I had send v2 patch,  you can review it.

Thanks.

>
>> I found many other connector driver also direct access register on detect or
>> get_modes, no problem for it?
>>
>> On 2016年10月12日 18:00, Mark Yao wrote:
>>
>> The drm callback ->detect and ->get_modes seems is not power safe,
>> they may be called when device is power off, do register access on
>> detect or get_modes will cause system die.
>>
>> Here is the path call ->detect before analogix_dp power on
>> [] analogix_dp_detect+0x44/0xdc
>> []
>> drm_helper_probe_single_connector_modes_merge_bits+0xe8/0x41c
>> [] drm_helper_probe_single_connector_modes+0x10/0x18
>> [] drm_mode_getconnector+0xf4/0x304
>> [] drm_ioctl+0x23c/0x390
>> [] do_vfs_ioctl+0x4b8/0x58c
>> [] SyS_ioctl+0x60/0x88
>>
>> Cc: Inki Dae 
>> Cc: Sean Paul 
>> Cc: Gustavo Padovan 
>> Cc: "Ville Syrjälä" 
>>
>> Signed-off-by: Mark Yao 
>> ---
>>   drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 28
>> ++
>>   1 file changed, 28 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
>> b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
>> index efac8ab..09dece2 100644
>> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
>> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
>> @@ -1062,6 +1062,13 @@ int analogix_dp_get_modes(struct drm_connector
>> *connector)
>>return 0;
>>}
>>
>> + if (dp->dpms_mode != DRM_MODE_DPMS_ON) {
>> + pm_runtime_get_sync(dp->dev);
>> +
>> + if (dp->plat_data->power_on)
>> + dp->plat_data->power_on(dp->plat_data);
>> + }
>> +
>>if (analogix_dp_handle_edid(dp) == 0) {
>>drm_mode_connector_update_edid_property(&dp->connector, edid);
>>num_modes += drm_add_edid_modes(&dp->connector, edid);
>> @@ -1073,6 +1080,13 @@ int analogix_dp_get_modes(struct drm_connector
>> *connector)
>>if (dp->plat_data->get_modes)
>>num_modes += dp->plat_data->get_modes(dp->plat_data, connector);
>>
>> + if (dp->dpms_mode != DRM_MODE_DPMS_ON) {
>> + if (dp->plat_data->power_off)
>> + dp->plat_data->power_off(dp->plat_data);
>> +
>> + pm_runtime_put_sync(dp->dev);
>> + }
>> +
>>ret = analogix_dp_prepare_panel(dp, false, false);
>>if (ret)
>>DRM_ERROR("Failed to unprepare panel (%d)\n", ret);
>> @@ -1106,9 +1120,23 @@ analogix_dp_detect(struct drm_connector *connector,
>> bool force)
>>return connector_status_disconnected;
>>}
>>
>> + if (dp->dpms_mode != DRM_MODE_DPMS_ON) {
>> + pm_runtime_get_sync(dp->dev);
>> +
>> + if (dp->plat_data->power_on)
>> + dp->plat_data->power_on(dp->plat_data);
>> + }
>> +
>>if (!analogix_dp_detect_hpd(dp))
>>status = connector_status_connected;
>>
>> + if (dp->dpms_mode != DRM_MODE_DPMS_ON) {
>> + if (dp->plat_data->power_off)
>> + dp->plat_data->power_off(dp->plat_data);
>> +
>> + pm_runtime_put_sync(dp->dev);
>> + }
>> +
>>ret = analogix_dp_prepare_panel(dp, false, false);
>>if (ret)
>>DRM_ERROR("Failed to unprepare panel (%d)\n", ret);
>>
>>
>>
>> --
>> ï¼­ark Yao
>
>


-- 
ï¼­ark Yao




rockchip: drm: analogix_dp-rockchip would stock the kernel

2016-10-17 Thread Mark yao
On 2016年10月16日 02:03, ayaka wrote:
> Hello:
>I meet a problem with eDP in rk3288 with the linux next 20161006, 
> it is just like the early stage of 4.4
> kernel.  I have added a eDP panel entry in the firefly reload board, 
> once the kernel loaded analogix_dp-rockchip.ko, after printed the 
> following two lines, the kernel stop working.
> rockchip-drm display-subsystem: bound ff94.vop (ops 
> vop_component_ops [rockchipdrm])
> rockchip-drm display-subsystem: bound ff93.vop (ops 
> vop_component_ops [rockchipdrm])

Hi ayaka

This log seems no problem.

How about tested it with build-in? we had test it with build-in.

Maybe this patch can help you, you can have a try.
 https://patchwork.kernel.org/patch/9374135

Thanks.

> In the early June of the 4.4 kernel, I meet the same problem with 
> rk3288 evb board with different error message, I have to disable the 
> display system that time.
>   In the today test, I meet the same problem with rk3399 evb board in 
> 4.4.
>   I have no idea what caused that, and it is a little hard to debug as 
> kernel still would never kill that task.
> Randy Li
>
>
>


-- 
ï¼­ark Yao




About the Xserver for rockchip

2016-10-17 Thread Mark yao
On 2016年10月17日 15:12, Heiko Stuebner wrote:
> Am Montag, 17. Oktober 2016, 14:45:30 CEST schrieb Randy Li:
>> Hello Tomasz:
>>Heiko told me you are in charge of the graphics part of chromium, I
>> think I had better told you the developing status of the xorg xserver in
>> rockchip.
> What I actually said was that Tomasz did the original VPU driver used on
> veyron chromebooks, so may be interested in your current work on that :-) .
>
> Also ChromeOS moved from X11 to use Freon instead, so I'm not sure if ChromeOS
> cares about that anymore.
>
>> Currently the graphics department released a modification
>> version of xserver which would support the libMali, but the way to
>> support it is some kind of hacker which disabled the original mesa gl
>> support.
>> https://github.com/rockchip-linux/xserver/commit/bae12718e76d50d7388a93a251e
>> f6777f6ca4850#diff-92a9ba7d51895d2d69c5c893fa0f658dL792
>>
>> Since the code base of that is really a mess, I rebase the branch
>> rockchip with the xserver branch 1.18 from upstream, it is there
>> https://github.com/rockchip-linux/xserver/tree/rockchip-1.18
>> But the version I made would omit some pixels when it is drawing, I have
>> not found out why.
> Didn't Mark do a lot of changes on your xserver, so maybe he knows what might
> be going wrong?

I don't what the problem it's, I haven't a chance to try Randy's issue yet.

Hi Randy

Did you re-test it with this patch: 
https://github.com/rockchip-linux/xserver/commit/bfee8067608b9dcbf6dae0ed897ae1295fdef7f2

Thanks.

>
>
> Heiko
>
>
>


-- 
ï¼­ark Yao




Re: [PATCH] drm/rockchip: Set line flag config register in vop_crtc_enable

2017-04-27 Thread Mark yao

On 2017年04月27日 14:54, Jeffy Chen wrote:

We need to set vop config done after update line flag config, it's a
new requirement for chips newer than rk3368.

Since we would only use line flag irq for vact_end, let's move it to
vop_crtc_enable.

Signed-off-by: Jeffy Chen 


looks good for me:

Acked-by: Mark Yao 



---

  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c |  4 ++--
  drivers/gpu/drm/rockchip/rockchip_drm_drv.h |  3 +--
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 20 +---
  3 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index d8fa7a9..9bfdbc6 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -115,8 +115,8 @@ static void analogix_dp_psr_work(struct work_struct *work)
  
  	vact_end = crtc->mode.vtotal - crtc->mode.vsync_start + crtc->mode.vdisplay;
  
-	ret = rockchip_drm_wait_line_flag(dp->encoder.crtc, vact_end,

- PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
+   ret = rockchip_drm_wait_vact_end(dp->encoder.crtc,
+PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
if (ret) {
dev_err(dp->dev, "line flag interrupt did not arrive\n");
return;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index a48fcce..47905fa 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -62,8 +62,7 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
   struct device *dev);
  void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
struct device *dev);
-int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
-   unsigned int mstimeout);
+int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout);
  
  extern struct platform_driver cdn_dp_driver;

  extern struct platform_driver dw_hdmi_rockchip_pltfm_driver;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 3f7a82d..40a5e6e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -468,7 +468,7 @@ static bool vop_line_flag_irq_is_enabled(struct vop *vop)
return !!line_flag_irq;
  }
  
-static void vop_line_flag_irq_enable(struct vop *vop, int line_num)

+static void vop_line_flag_irq_enable(struct vop *vop)
  {
unsigned long flags;
  
@@ -477,7 +477,6 @@ static void vop_line_flag_irq_enable(struct vop *vop, int line_num)
  
  	spin_lock_irqsave(&vop->irq_lock, flags);
  
-	VOP_CTRL_SET(vop, line_flag_num[0], line_num);

VOP_INTR_SET_TYPE(vop, clear, LINE_FLAG_INTR, 1);
VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1);
  
@@ -981,6 +980,8 @@ static void vop_crtc_enable(struct drm_crtc *crtc)

VOP_CTRL_SET(vop, vact_st_end, val);
VOP_CTRL_SET(vop, vpost_st_end, val);
  
+	VOP_CTRL_SET(vop, line_flag_num[0], vact_end);

+
clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
  
  	VOP_CTRL_SET(vop, standby, 0);

@@ -1507,19 +1508,16 @@ static void vop_win_init(struct vop *vop)
  }
  
  /**

- * rockchip_drm_wait_line_flag - acqiure the give line flag event
+ * rockchip_drm_wait_vact_end
   * @crtc: CRTC to enable line flag
- * @line_num: interested line number
   * @mstimeout: millisecond for timeout
   *
- * Driver would hold here until the interested line flag interrupt have
- * happened or timeout to wait.
+ * Wait for vact_end line flag irq or timeout.
   *
   * Returns:
   * Zero on success, negative errno on failure.
   */
-int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
-   unsigned int mstimeout)
+int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
  {
struct vop *vop = to_vop(crtc);
unsigned long jiffies_left;
@@ -1527,14 +1525,14 @@ int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, 
unsigned int line_num,
if (!crtc || !vop->is_enabled)
return -ENODEV;
  
-	if (line_num > crtc->mode.vtotal || mstimeout <= 0)

+   if (mstimeout <= 0)
return -EINVAL;
  
  	if (vop_line_flag_irq_is_enabled(vop))

return -EBUSY;
  
  	reinit_completion(&vop->line_flag_completion);

-   vop_line_flag_irq_enable(vop, line_num);
+   vop_line_flag_irq_enable(vop);
  
  	jiffies_left = wait_for_completion_timeout(&vop->line_flag_completion,

   msecs_to_jiffies(mstimeout));
@@ -1547,7 +1545,7 @@ int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, 
unsign

[PATCH 1/2] drm/rockchip: support mode_valid for crtc

2017-02-04 Thread Mark Yao
drm crtc already has mode_fixup callback to can do mode check, but
We actually want to valid display mode on connector getmode time,
mode_fixup can't do it.

So add a private mode_valid callback to rockchip crtc, connectors can
check mode with this mode_valid callback.

Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |  2 ++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 15 +++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |  7 +++
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 13 +
 4 files changed, 37 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index fb6226c..d10b15c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -39,6 +39,8 @@
 struct rockchip_crtc_funcs {
int (*enable_vblank)(struct drm_crtc *crtc);
void (*disable_vblank)(struct drm_crtc *crtc);
+   enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc,
+  const struct drm_display_mode *mode);
 };
 
 struct rockchip_crtc_state {
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index fb5f001..256fe73 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -853,9 +853,24 @@ static void vop_crtc_disable_vblank(struct drm_crtc *crtc)
spin_unlock_irqrestore(&vop->irq_lock, flags);
 }
 
+static enum drm_mode_status
+vop_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
+{
+   struct vop *vop = to_vop(crtc);
+   const struct vop_data *vop_data = vop->data;
+
+   if (mode->hdisplay > vop_data->max_output.width)
+   return MODE_BAD_HVALUE;
+   if (mode->vdisplay > vop_data->max_output.height)
+   return MODE_BAD_VVALUE;
+
+   return MODE_OK;
+}
+
 static const struct rockchip_crtc_funcs private_crtc_funcs = {
.enable_vblank = vop_crtc_enable_vblank,
.disable_vblank = vop_crtc_disable_vblank,
+   .mode_valid = vop_crtc_mode_valid,
 };
 
 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 1dbc526..9e9dba1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -133,6 +133,11 @@ struct vop_win_data {
enum drm_plane_type type;
 };
 
+struct vop_rect {
+   int width;
+   int height;
+};
+
 struct vop_data {
const struct vop_reg_data *init_table;
unsigned int table_size;
@@ -140,6 +145,8 @@ struct vop_data {
const struct vop_intr *intr;
const struct vop_win_data *win;
unsigned int win_size;
+   struct vop_rect max_input;
+   struct vop_rect max_output;
 };
 
 /* interrupt define */
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c 
b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 35c51f3..0c72361 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -132,6 +132,8 @@
 };
 
 static const struct vop_data rk3036_vop = {
+   .max_input = { 1920, 1080},
+   .max_output = { 1920, 1080},
.init_table = rk3036_vop_init_reg_table,
.table_size = ARRAY_SIZE(rk3036_vop_init_reg_table),
.ctrl = &rk3036_ctrl_data,
@@ -273,6 +275,13 @@
 };
 
 static const struct vop_data rk3288_vop = {
+   .max_input = { 4096, 8192},
+   /*
+* TODO: rk3288 have two vop, big one support 3840x2160,
+* little one only support 2560x1600.
+* Now force use 3840x2160.
+*/
+   .max_output = { 3840, 2160},
.init_table = rk3288_init_reg_table,
.table_size = ARRAY_SIZE(rk3288_init_reg_table),
.intr = &rk3288_vop_intr,
@@ -339,6 +348,8 @@
 };
 
 static const struct vop_data rk3399_vop_big = {
+   .max_input = { 4096, 8192},
+   .max_output = { 4096, 2160},
.init_table = rk3399_init_reg_table,
.table_size = ARRAY_SIZE(rk3399_init_reg_table),
.intr = &rk3399_vop_intr,
@@ -358,6 +369,8 @@
 };
 
 static const struct vop_data rk3399_vop_lit = {
+   .max_input = { 4096, 8192},
+   .max_output = { 2560, 1600},
.init_table = rk3399_init_reg_table,
.table_size = ARRAY_SIZE(rk3399_init_reg_table),
.intr = &rk3399_vop_intr,
-- 
1.9.1


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


[PATCH 2/2] drm/rockchip: dw_hdmi: check display mode with crtc mode valid

2017-02-04 Thread Mark Yao
Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 47 +++--
 1 file changed, 44 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index a6d4a02..64408bc 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -158,18 +158,59 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi 
*hdmi)
struct drm_display_mode *mode)
 {
const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg;
+   struct drm_device *dev = connector->dev;
+   struct drm_encoder *encoder = connector->encoder;
+   struct rockchip_drm_private *priv = dev->dev_private;
int pclk = mode->clock * 1000;
-   bool valid = false;
+   enum drm_mode_status status = MODE_BAD;
+   struct drm_crtc *crtc;
int i;
 
for (i = 0; mpll_cfg[i].mpixelclock != (~0UL); i++) {
if (pclk == mpll_cfg[i].mpixelclock) {
-   valid = true;
+   status = MODE_OK;
break;
}
}
 
-   return (valid) ? MODE_OK : MODE_BAD;
+
+   if (status != MODE_OK)
+   return status;
+
+   if (!encoder) {
+   const struct drm_connector_helper_funcs *funcs;
+
+   funcs = connector->helper_private;
+   if (funcs->atomic_best_encoder)
+   encoder = funcs->atomic_best_encoder(connector,
+connector->state);
+   else
+   encoder = funcs->best_encoder(connector);
+   }
+
+   if (!encoder || !encoder->possible_crtcs)
+   return MODE_BAD;
+   /*
+* ensure all drm display mode can work, if someone want support more
+* resolutions, please limit the possible_crtc, only connect to
+* needed crtc.
+*/
+   drm_for_each_crtc(crtc, connector->dev) {
+   int pipe = drm_crtc_index(crtc);
+   const struct rockchip_crtc_funcs *funcs =
+   priv->crtc_funcs[pipe];
+
+   if (!(encoder->possible_crtcs & drm_crtc_mask(crtc)))
+   continue;
+   if (!funcs || !funcs->mode_valid)
+   continue;
+
+   status = funcs->mode_valid(crtc, mode);
+   if (status != MODE_OK)
+   return status;
+   }
+
+   return status;
 }
 
 static const struct drm_encoder_funcs dw_hdmi_rockchip_encoder_funcs = {
-- 
1.9.1


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


Re: [PATCH v3 3/5] drm/rockchip/dsi: remove mode_valid function

2017-02-04 Thread Mark yao

On 2017年02月05日 11:42, Chris Zhong wrote:



On 02/02/2017 02:12 AM, Sean Paul wrote:

On Tue, Jan 24, 2017 at 10:27:27AM +0800, Chris Zhong wrote:

Hi Sean

On 01/24/2017 01:48 AM, Sean Paul wrote:

On Fri, Jan 20, 2017 at 06:10:49PM +0800, Chris Zhong wrote:

The MIPI DSI do not need check the validity of resolution, the max
resolution should depend VOP. Hence, remove 
rk3288_mipi_dsi_mode_valid

here.
Does vop actually enforce this, though? I see that 
mode_config.max_width is

4096, but there is no bounds checking in mode_fixup().

The connector is currently rejecting everything greater than 2047. 
So I think

you're going to regress behavior here.

Sean

The mipi controller has not this width limit, it depend the VOP,
such as RK3399, VOP_LIT only support 2560,
but VOP_BIG support 4K. So this driver should check the width here.
I don't see anything in the vop driver that rejects large modes for 
little vop.
So, while I agree the check shouldn't be here, you should move it to 
where it

should be instead of removing it entirely.

Sean


drm_mode_validate_size will check the dev->mode_config.max_width and
dev->mode_config.max_height, these 2 value come from 
rockchip_drm_mode_config_init,
currently, they are both 4096. So you are right, drm driver does not 
distinguish

between vop lit and big.

I think Mark Yao already have a local solution, and he will post it soon.

Hi

See follow patches, support mode valid with vop callback.

[0] https://patchwork.kernel.org/patch/9555943/
[1] https://patchwork.kernel.org/patch/9555945/








Signed-off-by: Chris Zhong 
---

Changes in v3: None

  drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 39 
--

  1 file changed, 39 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c

index a93ce97..6f0e252 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -278,8 +278,6 @@ struct dw_mipi_dsi_plat_data {
  u32 grf_dsi0_mode;
  u32 grf_dsi0_mode_reg;
  unsigned int max_data_lanes;
-enum drm_mode_status (*mode_valid)(struct drm_connector 
*connector,

-   struct drm_display_mode *mode);
  };
  struct dw_mipi_dsi {
@@ -1081,23 +1079,8 @@ static int 
dw_mipi_dsi_connector_get_modes(struct drm_connector *connector)

  return drm_panel_get_modes(dsi->panel);
  }
-static enum drm_mode_status dw_mipi_dsi_mode_valid(
-struct drm_connector *connector,
-struct drm_display_mode *mode)
-{
-struct dw_mipi_dsi *dsi = con_to_dsi(connector);
-
-enum drm_mode_status mode_status = MODE_OK;
-
-if (dsi->pdata->mode_valid)
-mode_status = dsi->pdata->mode_valid(connector, mode);
-
-return mode_status;
-}
-
  static struct drm_connector_helper_funcs 
dw_mipi_dsi_connector_helper_funcs = {

  .get_modes = dw_mipi_dsi_connector_get_modes,
-.mode_valid = dw_mipi_dsi_mode_valid,
  };
  static void dw_mipi_dsi_drm_connector_destroy(struct 
drm_connector *connector)
@@ -1168,33 +1151,11 @@ static int rockchip_mipi_parse_dt(struct 
dw_mipi_dsi *dsi)

  return 0;
  }
-static enum drm_mode_status rk3288_mipi_dsi_mode_valid(
-struct drm_connector *connector,
-struct drm_display_mode *mode)
-{
-/*
- * The VID_PKT_SIZE field in the DSI_VID_PKT_CFG
- * register is 11-bit.
- */
-if (mode->hdisplay > 0x7ff)
-return MODE_BAD_HVALUE;
-
-/*
- * The V_ACTIVE_LINES field in the DSI_VTIMING_CFG
- * register is 11-bit.
- */
-if (mode->vdisplay > 0x7ff)
-return MODE_BAD_VVALUE;
-
-return MODE_OK;
-}
-
  static struct dw_mipi_dsi_plat_data rk3288_mipi_dsi_drv_data = {
  .dsi0_en_bit = RK3288_DSI0_SEL_VOP_LIT,
  .dsi1_en_bit = RK3288_DSI1_SEL_VOP_LIT,
  .grf_switch_reg = RK3288_GRF_SOC_CON6,
  .max_data_lanes = 4,
-.mode_valid = rk3288_mipi_dsi_mode_valid,
  };
  static struct dw_mipi_dsi_plat_data rk3399_mipi_dsi_drv_data = {
--
2.6.3

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


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








--
Mark Yao


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


[GIT PULL] drm/rockchip: add cdn-dp support and some fixes

2017-02-05 Thread Mark yao

Hi Dave

drm/rockchip cdn-dp driver is v17 now, I think it's ready to land it.

Thanks.

The following changes since commit 99743ae4c5f52f8f8ceb17783056fcc9b4f8b64c:

  Merge branch 'drm-etnaviv-next' of 
https://git.pengutronix.de/git/lst/linux into drm-next (2017-02-03 
05:41:58 +1000)


are available in the git repository at:

  https://github.com/markyzq/kernel-drm-rockchip.git 
drm-rockchip-next-2017-02-05


for you to fetch changes up to ef1844b7ed847430955a95d20242f0d1b9f5fa64:

  drm/rockchip: cdn-dp: don't configure hardware in mode_set 
(2017-02-05 16:30:11 +0800)



Chris Zhong (5):
  drm/rockchip: vop: make vop register setting take effect
  drm/rockchip: cdn-dp: add cdn DP support for rk3399
  drm/rockchip: cdn-dp: do not use drm_helper_hpd_irq_event
  drm/rockchip: cdn-dp: retry to check sink count
  drm/rockchip: cdn-dp: don't configure hardware in mode_set

Guenter Roeck (2):
  drm/rockchip: cdn-dp: Load firmware if no monitor connected
  drm/rockchip: cdn-dp: Do not run worker while suspended

Jeffy Chen (1):
  drm/rockchip: cdn-dp: Move mutex_init to probe

Julia Lawall (1):
  drm/rockchip: return ERR_PTR instead of NULL

 drivers/gpu/drm/rockchip/Kconfig|   10 +
 drivers/gpu/drm/rockchip/Makefile   |2 +
 drivers/gpu/drm/rockchip/cdn-dp-core.c  | 1260 
++

 drivers/gpu/drm/rockchip/cdn-dp-core.h  |  112 
 drivers/gpu/drm/rockchip/cdn-dp-reg.c   |  979 
++
 drivers/gpu/drm/rockchip/cdn-dp-reg.h   |  483 


 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  |2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   17 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |9 +
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c |2 +
 10 files changed, 2872 insertions(+), 4 deletions(-)
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.c
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.h
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.c
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.h

-- Mark Yao

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


Re: [PATCH v17 0/7] drm/rockchip: Add CDN DP driver

2017-02-05 Thread Mark yao

Hi Chris

Applied to my drm-next and already sent pull request to Dave.

Thanks.

On 2017年02月05日 15:54, Chris Zhong wrote:

This series adds support for the CDN DP controller to the rockchip drm
driver. This version fixes some coding style error in v16, it post by
Sean Paul, you can find it here:
https://patchwork.kernel.org/patch/9442135/

And I sorted out a few patches to fix the following problems:
- suspend/resume crash cause by drm_helper_hpd_irq_event
- crash during shutdown when cdn-dp failed to bind
- check sink count failed after reconnection
- suspend/reusme crash in mode_set function

I also added these 2 patches to this series, although nothing changed:
https://patchwork.kernel.org/patch/9442141/
https://patchwork.kernel.org/patch/9442151/


Changes in v17:
- Correct the clock check condition
- Correct the coding style
- change LANE_REF_CYC to 0x8000

Chris Zhong (4):
   drm/rockchip: cdn-dp: add cdn DP support for rk3399
   drm/rockchip: cdn-dp: do not use drm_helper_hpd_irq_event
   drm/rockchip: cdn-dp: retry to check sink count
   drm/rockchip: cdn-dp: don't configure hardware in mode_set

Guenter Roeck (2):
   drm/rockchip: cdn-dp: Load firmware if no monitor connected
   drm/rockchip: cdn-dp: Do not run worker while suspended

Jeffy Chen (1):
   drm/rockchip: cdn-dp: Move mutex_init to probe

  drivers/gpu/drm/rockchip/Kconfig|   10 +
  drivers/gpu/drm/rockchip/Makefile   |2 +
  drivers/gpu/drm/rockchip/cdn-dp-core.c  | 1260 +++
  drivers/gpu/drm/rockchip/cdn-dp-core.h  |  112 +++
  drivers/gpu/drm/rockchip/cdn-dp-reg.c   |  979 +
  drivers/gpu/drm/rockchip/cdn-dp-reg.h   |  483 ++
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   13 +-
  drivers/gpu/drm/rockchip/rockchip_drm_vop.h |9 +
  drivers/gpu/drm/rockchip/rockchip_vop_reg.c |2 +
  9 files changed, 2867 insertions(+), 3 deletions(-)
  create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.c
  create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.h
  create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.c
  create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.h




--
Mark Yao


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


[PATCH] drm/rockchip: cdn-dp: fix cdn-dp complie warning

2017-02-06 Thread Mark Yao
fix warning:

drivers/gpu/drm/rockchip/cdn-dp-reg.c:632:24: warning:
  'val[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
  msa_misc = 2 * val[0] + 32 * val[1] +

Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/cdn-dp-reg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c 
b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
index 3a5b8a4..319dbba 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
@@ -592,7 +592,7 @@ static int cdn_dp_get_msa_misc(struct video_info *video,
   struct drm_display_mode *mode)
 {
u32 msa_misc;
-   u8 val[2];
+   u8 val[2] = {0};
 
switch (video->color_fmt) {
case PXL_RGB:
-- 
1.9.1


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


Re: [GIT PULL] drm/rockchip: add cdn-dp support and some fixes

2017-02-06 Thread Mark yao

On 2017年02月07日 09:05, Dave Airlie wrote:

On 5 February 2017 at 18:40, Mark yao  wrote:

Hi Dave

drm/rockchip cdn-dp driver is v17 now, I think it's ready to land it.

Thanks.

The following changes since commit 99743ae4c5f52f8f8ceb17783056fcc9b4f8b64c:

   Merge branch 'drm-etnaviv-next' of
https://git.pengutronix.de/git/lst/linux into drm-next (2017-02-03 05:41:58
+1000)


   CC [M]  drivers/gpu/drm/rockchip/rockchip_vop_reg.o
   CC [M]  drivers/gpu/drm/rockchip/rockchip_drm_vop.o
/home/airlied/devel/kernel/drm-next/drivers/gpu/drm/rockchip/cdn-dp-reg.c:
In function ‘cdn_dp_config_video’:
/home/airlied/devel/kernel/drm-next/drivers/gpu/drm/rockchip/cdn-dp-reg.c:632:24:
warning: ‘val[1]’ may be used uninitialized in this function
[-Wmaybe-uninitialized]
   msa_misc = 2 * val[0] + 32 * val[1] +
  ~~~^
/home/airlied/devel/kernel/drm-next/drivers/gpu/drm/rockchip/cdn-dp-reg.c:595:5:
note: ‘val[1]’ was declared here
   u8 val[2];

You might want to send me a follow up pull request to fix that.

Dave.


Hi Dave

Sorry for the compile warning, following patch fix the compile warning 
with tiny modify.


Thanks.

The following changes since commit 26d7f34cae7aad9600cd40ce07ec3fbe8606a567:

  Merge branch 'msm-next' of 
git://people.freedesktop.org/~robclark/linux into drm-next (2017-02-07 
11:05:42 +1000)


are available in the git repository at:


  https://github.com/markyzq/kernel-drm-rockchip.git 
drm-rockchip-next-2017-02-07


for you to fetch changes up to 213c4b96639818a2dc8750d1b7a37672a9c9eaeb:

  drm/rockchip: cdn-dp: fix cdn-dp complie warning (2017-02-07 11:06:01 
+0800)


----
Mark Yao (1):
  drm/rockchip: cdn-dp: fix cdn-dp complie warning

 drivers/gpu/drm/rockchip/cdn-dp-reg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--
Mark Yao


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


[PATCH 0/4] drm/rockchip: switch to drm_mm for support arm64 iommu

2017-02-06 Thread Mark Yao
Some iommu patches on the series[0] "iommu/rockchip: Fix bugs and
enable on ARM64" already landed, So drm/rockchip related patches [1] and [2]
ready to landed, this series just rebase them to lastest drm-next.

And fix some bugs for drm/rockchip drm_mm

[0]: http://www.spinics.net/lists/arm-kernel/msg513781.html
[1]: https://patchwork.kernel.org/patch/9196367
[2]: https://patchwork.kernel.org/patch/9196369

Mark Yao (2):
  drm/rockchip: gem: add mutex lock for drm mm
  drm/rockchip: gem: fixup iommu_map_sg error path

Shunqian Zheng (1):
  drm/rockchip: Use common IOMMU API to attach devices

Tomasz Figa (1):
  drm/rockchip: Do not use DMA mapping API if attached to IOMMU domain

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 101 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   6 +-
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 228 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_gem.h |   8 +
 4 files changed, 286 insertions(+), 57 deletions(-)

-- 
1.9.1


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


[PATCH 1/4] drm/rockchip: Do not use DMA mapping API if attached to IOMMU domain

2017-02-06 Thread Mark Yao
From: Tomasz Figa 

The API is not suitable for subsystems consisting of multiple devices
and requires severe hacks to use it. To mitigate this, this patch
implements allocation and address space management locally by using
helpers provided by DRM framework, like other DRM drivers do, e.g.
Tegra.

This patch should not introduce any functional changes until the driver
is made to attach subdevices into an IOMMU domain with the generic IOMMU
API, which will happen in following patch. Based heavily on GEM
implementation of Tegra DRM driver.

Signed-off-by: Tomasz Figa 
Signed-off-by: Shunqian Zheng 
Acked-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   4 +-
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 217 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_gem.h |   8 +
 3 files changed, 219 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index fb6226c..7c123d9 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -30,6 +30,7 @@
 
 struct drm_device;
 struct drm_connector;
+struct iommu_domain;
 
 /*
  * Rockchip drm private crtc funcs.
@@ -60,7 +61,8 @@ struct rockchip_drm_private {
struct drm_gem_object *fbdev_bo;
const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
struct drm_atomic_state *state;
-
+   struct iommu_domain *domain;
+   struct drm_mm mm;
struct list_head psr_list;
spinlock_t psr_list_lock;
 };
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index b70f942..5209392 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -16,11 +16,135 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_gem.h"
 
-static int rockchip_gem_alloc_buf(struct rockchip_gem_object *rk_obj,
+static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
+{
+   struct drm_device *drm = rk_obj->base.dev;
+   struct rockchip_drm_private *private = drm->dev_private;
+   int prot = IOMMU_READ | IOMMU_WRITE;
+   ssize_t ret;
+
+   ret = drm_mm_insert_node_generic(&private->mm, &rk_obj->mm,
+rk_obj->base.size, PAGE_SIZE,
+0, 0);
+   if (ret < 0) {
+   DRM_ERROR("out of I/O virtual memory: %zd\n", ret);
+   return ret;
+   }
+
+   rk_obj->dma_addr = rk_obj->mm.start;
+
+   ret = iommu_map_sg(private->domain, rk_obj->dma_addr, rk_obj->sgt->sgl,
+  rk_obj->sgt->nents, prot);
+   if (ret < 0) {
+   DRM_ERROR("failed to map buffer: %zd\n", ret);
+   goto err_remove_node;
+   }
+
+   rk_obj->size = ret;
+
+   return 0;
+
+err_remove_node:
+   drm_mm_remove_node(&rk_obj->mm);
+
+   return ret;
+}
+
+static int rockchip_gem_iommu_unmap(struct rockchip_gem_object *rk_obj)
+{
+   struct drm_device *drm = rk_obj->base.dev;
+   struct rockchip_drm_private *private = drm->dev_private;
+
+   iommu_unmap(private->domain, rk_obj->dma_addr, rk_obj->size);
+   drm_mm_remove_node(&rk_obj->mm);
+
+   return 0;
+}
+
+static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj)
+{
+   struct drm_device *drm = rk_obj->base.dev;
+   int ret, i;
+   struct scatterlist *s;
+
+   rk_obj->pages = drm_gem_get_pages(&rk_obj->base);
+   if (IS_ERR(rk_obj->pages))
+   return PTR_ERR(rk_obj->pages);
+
+   rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT;
+
+   rk_obj->sgt = drm_prime_pages_to_sg(rk_obj->pages, rk_obj->num_pages);
+   if (IS_ERR(rk_obj->sgt)) {
+   ret = PTR_ERR(rk_obj->sgt);
+   goto err_put_pages;
+   }
+
+   /*
+* Fake up the SG table so that dma_sync_sg_for_device() can be used
+* to flush the pages associated with it.
+*
+* TODO: Replace this by drm_clflush_sg() once it can be implemented
+* without relying on symbols that are not exported.
+*/
+   for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->nents, i)
+   sg_dma_address(s) = sg_phys(s);
+
+   dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl, rk_obj->sgt->nents,
+  DMA_TO_DEVICE);
+
+   return 0;
+
+err_put_pages:
+   drm_gem_put_pages(&rk_obj->base, rk_obj->pages, false, false);
+   return ret;
+}
+
+static void rockchip_gem_put_pages(struct rockchip_gem_object *rk_obj)
+{
+   sg_free_table(rk_obj->sgt);
+   kfree(rk_obj->sgt);
+ 

[PATCH 3/4] drm/rockchip: gem: add mutex lock for drm mm

2017-02-06 Thread Mark Yao
drm_mm_insert_node_generic and drm_mm_remove_node may access same
resource with list ops, it's not threads safe, so protect this context
with mutex lock.

Fix bug:
[49451.856244] 
==
[49451.856350] BUG: KASAN: wild-memory-access on address dead0108
[49451.856379] Write of size 8 by task Binder:218_4/683
[49451.856417] CPU: 2 PID: 683 Comm: Binder:218_4 Not tainted 4.4.36 #62
[49451.856443] Hardware name: Rockchip RK3399 Excavator Board edp (Android) (DT)
[49451.856469] Call trace:
[49451.856519] [] dump_backtrace+0x0/0x230
[49451.856556] [] show_stack+0x14/0x1c
[49451.856592] [] dump_stack+0xa0/0xc8
[49451.856633] [] kasan_report+0x110/0x4dc
[49451.856670] [] __asan_store8+0x24/0x7c
[49451.856715] [] drm_mm_insert_node_generic+0x2dc/0x464
[49451.856760] [] rockchip_gem_iommu_map+0x60/0x158
[49451.856794] [] rockchip_gem_create_object+0x278/0x488
[49451.856827] [] rockchip_gem_create_with_handle+0x24/0x10c
[49451.856862] [] rockchip_gem_create_ioctl+0x3c/0x50
[49451.856896] [] drm_ioctl+0x354/0x52c
[49451.856939] [] do_vfs_ioctl+0x670/0x78c
[49451.856976] [] SyS_ioctl+0x60/0x88
[49451.857009] [] el0_svc_naked+0x24/0x28

Change-Id: I2ea377aa9ca24f70c59e2d86f2a6ad5ccb9c0891
Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 1 +
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 2 ++
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 9 +
 3 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 7a610e9..b360e62 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -146,6 +146,7 @@ static int rockchip_drm_init_iommu(struct drm_device 
*drm_dev)
DRM_DEBUG("IOMMU context initialized (aperture: %#llx-%#llx)\n",
  start, end);
drm_mm_init(&private->mm, start, end - start + 1);
+   mutex_init(&private->mm_lock);
 
return 0;
 }
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 7c123d9..adc3930 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -62,6 +62,8 @@ struct rockchip_drm_private {
const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
struct drm_atomic_state *state;
struct iommu_domain *domain;
+   /* protect drm_mm on multi-threads */
+   struct mutex mm_lock;
struct drm_mm mm;
struct list_head psr_list;
spinlock_t psr_list_lock;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index 5209392..8d27965 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -28,9 +28,13 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object 
*rk_obj)
int prot = IOMMU_READ | IOMMU_WRITE;
ssize_t ret;
 
+   mutex_lock(&private->mm_lock);
+
ret = drm_mm_insert_node_generic(&private->mm, &rk_obj->mm,
 rk_obj->base.size, PAGE_SIZE,
 0, 0);
+
+   mutex_unlock(&private->mm_lock);
if (ret < 0) {
DRM_ERROR("out of I/O virtual memory: %zd\n", ret);
return ret;
@@ -61,8 +65,13 @@ static int rockchip_gem_iommu_unmap(struct 
rockchip_gem_object *rk_obj)
struct rockchip_drm_private *private = drm->dev_private;
 
iommu_unmap(private->domain, rk_obj->dma_addr, rk_obj->size);
+
+   mutex_lock(&private->mm_lock);
+
drm_mm_remove_node(&rk_obj->mm);
 
+   mutex_unlock(&private->mm_lock);
+
return 0;
 }
 
-- 
1.9.1


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


[PATCH 2/4] drm/rockchip: Use common IOMMU API to attach devices

2017-02-06 Thread Mark Yao
From: Shunqian Zheng 

Rockchip DRM used the arm special API, arm_iommu_*(), to attach
iommu for ARM32 SoCs. This patch convert to common iommu API
so it would support ARM64 like RK3399.

Since previous patch added support for direct IOMMU address space
management, there is no need to use DMA API anymore and this patch wires
things to use the new method.

Signed-off-by: Shunqian Zheng 
Signed-off-by: Tomasz Figa 
Acked-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 100 +++-
 1 file changed, 53 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index c30d649..7a610e9 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -14,19 +14,19 @@
  * GNU General Public License for more details.
  */
 
-#include 
-
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_fb.h"
@@ -50,28 +50,31 @@
 int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
   struct device *dev)
 {
-   struct dma_iommu_mapping *mapping = drm_dev->dev->archdata.mapping;
+   struct rockchip_drm_private *private = drm_dev->dev_private;
int ret;
 
if (!is_support_iommu)
return 0;
 
-   ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
-   if (ret)
+   ret = iommu_attach_device(private->domain, dev);
+   if (ret) {
+   dev_err(dev, "Failed to attach iommu device\n");
return ret;
+   }
 
-   dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
-
-   return arm_iommu_attach_device(dev, mapping);
+   return 0;
 }
 
 void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
struct device *dev)
 {
+   struct rockchip_drm_private *private = drm_dev->dev_private;
+   struct iommu_domain *domain = private->domain;
+
if (!is_support_iommu)
return;
 
-   arm_iommu_detach_device(dev);
+   iommu_detach_device(domain, dev);
 }
 
 int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
@@ -123,11 +126,45 @@ static void rockchip_drm_crtc_disable_vblank(struct 
drm_device *dev,
priv->crtc_funcs[pipe]->disable_vblank(crtc);
 }
 
+static int rockchip_drm_init_iommu(struct drm_device *drm_dev)
+{
+   struct rockchip_drm_private *private = drm_dev->dev_private;
+   struct iommu_domain_geometry *geometry;
+   u64 start, end;
+
+   if (!is_support_iommu)
+   return 0;
+
+   private->domain = iommu_domain_alloc(&platform_bus_type);
+   if (!private->domain)
+   return -ENOMEM;
+
+   geometry = &private->domain->geometry;
+   start = geometry->aperture_start;
+   end = geometry->aperture_end;
+
+   DRM_DEBUG("IOMMU context initialized (aperture: %#llx-%#llx)\n",
+ start, end);
+   drm_mm_init(&private->mm, start, end - start + 1);
+
+   return 0;
+}
+
+static void rockchip_iommu_cleanup(struct drm_device *drm_dev)
+{
+   struct rockchip_drm_private *private = drm_dev->dev_private;
+
+   if (!is_support_iommu)
+   return;
+
+   drm_mm_takedown(&private->mm);
+   iommu_domain_free(private->domain);
+}
+
 static int rockchip_drm_bind(struct device *dev)
 {
struct drm_device *drm_dev;
struct rockchip_drm_private *private;
-   struct dma_iommu_mapping *mapping = NULL;
int ret;
 
drm_dev = drm_dev_alloc(&rockchip_drm_driver, dev);
@@ -151,38 +188,14 @@ static int rockchip_drm_bind(struct device *dev)
 
rockchip_drm_mode_config_init(drm_dev);
 
-   dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms),
- GFP_KERNEL);
-   if (!dev->dma_parms) {
-   ret = -ENOMEM;
+   ret = rockchip_drm_init_iommu(drm_dev);
+   if (ret)
goto err_config_cleanup;
-   }
-
-   if (is_support_iommu) {
-   /* TODO(djkurtz): fetch the mapping start/size from somewhere */
-   mapping = arm_iommu_create_mapping(&platform_bus_type,
-  0x,
-  SZ_2G);
-   if (IS_ERR(mapping)) {
-   ret = PTR_ERR(mapping);
-   goto err_config_cleanup;
-   }
-
-   ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
-   if (ret)
-   goto err_release_mapping;
-
-   dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
-
-   ret = arm_iommu_attach_devic

[PATCH 4/4] drm/rockchip: gem: fixup iommu_map_sg error path

2017-02-06 Thread Mark Yao
The return value of iommu_map_sg is size_t, it's unsigned,
So check ret < 0 is wrong.

And if iommu_map_sg is error, it's return value is zero, but
rockchip_gem_iommu_map feel the zero return value is success,
bug happen:

[5.227458] [drm:rockchip_gem_iommu_map] *ERROR* failed to map buffer: 0
[   12.291590] WARNING: at drivers/gpu/drm/drm_mm.c:369
[   12.291611] Modules linked in:
[   12.291634]
[   12.291658] CPU: 4 PID: 338 Comm: cameraserver Not tainted 4.4.41 #196
[   12.291680] Hardware name: rockchip,rk3399-mid (DT)
[   12.291703] task: ffc0e5a23100 ti: ffc0e5a64000 task.ti: 
ffc0e5a64000
[   12.291739] PC is at drm_mm_remove_node+0xc/0xf8
[   12.291766] LR is at rockchip_gem_iommu_unmap+0x3c/0x54
[   12.303799] [] drm_mm_remove_node+0xc/0xf8
[   12.303827] [] rockchip_gem_free_object+0x98/0x168
[   12.303854] [] drm_gem_object_free+0x2c/0x34
[   12.303878] [] drm_gem_dmabuf_release+0x90/0xa4
[   12.303904] [] dma_buf_release+0x64/0x15c
[   12.303929] [] __fput+0xe0/0x1a4
[   12.303950] [] fput+0xc/0x14
[   12.303977] [] task_work_run+0xa0/0xc0
[   12.304004] [] do_notify_resume+0x40/0x54
[   12.304026] [] work_pending+0x10/0x14

Change-Id: Id79c052691270553c1c60086f9926f39a5296354
Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index 8d27965..cc48673 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -44,8 +44,10 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object 
*rk_obj)
 
ret = iommu_map_sg(private->domain, rk_obj->dma_addr, rk_obj->sgt->sgl,
   rk_obj->sgt->nents, prot);
-   if (ret < 0) {
-   DRM_ERROR("failed to map buffer: %zd\n", ret);
+   if (ret < rk_obj->base.size) {
+   DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n",
+ ret, rk_obj->base.size);
+   ret = -ENOMEM;
goto err_remove_node;
}
 
-- 
1.9.1


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


Re: [PATCH 1/4] drm/rockchip: Do not use DMA mapping API if attached to IOMMU domain

2017-02-07 Thread Mark yao

On 2017年02月07日 14:53, Tomasz Figa wrote:

Hi Mark,

Thanks for reviving this series and sorry for not taking care of it
myself. Please see some comments inline.


Hi Tomasz

Thanks for review,

I will add the patches you mentioned  into v2 version.



On Tue, Feb 7, 2017 at 3:09 PM, Mark Yao  wrote:

From: Tomasz Figa 

The API is not suitable for subsystems consisting of multiple devices
and requires severe hacks to use it. To mitigate this, this patch
implements allocation and address space management locally by using
helpers provided by DRM framework, like other DRM drivers do, e.g.
Tegra.

This patch should not introduce any functional changes until the driver
is made to attach subdevices into an IOMMU domain with the generic IOMMU
API, which will happen in following patch. Based heavily on GEM
implementation of Tegra DRM driver.

Signed-off-by: Tomasz Figa 
Signed-off-by: Shunqian Zheng 
Acked-by: Mark Yao 

I believe you need your Signed-off-by here.


---
  drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   4 +-
  drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 217 ++--
  drivers/gpu/drm/rockchip/rockchip_drm_gem.h |   8 +
  3 files changed, 219 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index fb6226c..7c123d9 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -30,6 +30,7 @@

  struct drm_device;
  struct drm_connector;
+struct iommu_domain;

  /*
   * Rockchip drm private crtc funcs.
@@ -60,7 +61,8 @@ struct rockchip_drm_private {
 struct drm_gem_object *fbdev_bo;
 const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
 struct drm_atomic_state *state;
-
+   struct iommu_domain *domain;
+   struct drm_mm mm;
 struct list_head psr_list;
 spinlock_t psr_list_lock;
  };
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index b70f942..5209392 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -16,11 +16,135 @@
  #include 
  #include 
  #include 
+#include 

  #include "rockchip_drm_drv.h"
  #include "rockchip_drm_gem.h"

-static int rockchip_gem_alloc_buf(struct rockchip_gem_object *rk_obj,
+static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
+{
+   struct drm_device *drm = rk_obj->base.dev;
+   struct rockchip_drm_private *private = drm->dev_private;
+   int prot = IOMMU_READ | IOMMU_WRITE;
+   ssize_t ret;
+
+   ret = drm_mm_insert_node_generic(&private->mm, &rk_obj->mm,
+rk_obj->base.size, PAGE_SIZE,
+0, 0);
+   if (ret < 0) {
+   DRM_ERROR("out of I/O virtual memory: %zd\n", ret);
+   return ret;
+   }
+
+   rk_obj->dma_addr = rk_obj->mm.start;
+
+   ret = iommu_map_sg(private->domain, rk_obj->dma_addr, rk_obj->sgt->sgl,
+  rk_obj->sgt->nents, prot);
+   if (ret < 0) {
+   DRM_ERROR("failed to map buffer: %zd\n", ret);
+   goto err_remove_node;
+   }
+
+   rk_obj->size = ret;
+
+   return 0;
+
+err_remove_node:
+   drm_mm_remove_node(&rk_obj->mm);
+
+   return ret;
+}
+
+static int rockchip_gem_iommu_unmap(struct rockchip_gem_object *rk_obj)
+{
+   struct drm_device *drm = rk_obj->base.dev;
+   struct rockchip_drm_private *private = drm->dev_private;
+
+   iommu_unmap(private->domain, rk_obj->dma_addr, rk_obj->size);
+   drm_mm_remove_node(&rk_obj->mm);
+
+   return 0;
+}
+
+static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj)
+{
+   struct drm_device *drm = rk_obj->base.dev;
+   int ret, i;
+   struct scatterlist *s;
+
+   rk_obj->pages = drm_gem_get_pages(&rk_obj->base);
+   if (IS_ERR(rk_obj->pages))
+   return PTR_ERR(rk_obj->pages);
+
+   rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT;
+
+   rk_obj->sgt = drm_prime_pages_to_sg(rk_obj->pages, rk_obj->num_pages);
+   if (IS_ERR(rk_obj->sgt)) {
+   ret = PTR_ERR(rk_obj->sgt);
+   goto err_put_pages;
+   }
+
+   /*
+* Fake up the SG table so that dma_sync_sg_for_device() can be used
+* to flush the pages associated with it.
+*
+* TODO: Replace this by drm_clflush_sg() once it can be implemented
+* without relying on symbols that are not exported.
+*/
+   for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->nents, i)
+   sg_dma_address(s) = sg_phys(s);
+
+   dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl, rk

[PATCH v2 0/7] drm/rockchip: switch to drm_mm for support arm64 iommu

2017-02-07 Thread Mark Yao
Some iommu patches on the series[0] "iommu/rockchip: Fix bugs and
enable on ARM64" already landed, So drm/rockchip related patches [1] and [2]
ready to landed, this series just rebase them to lastest drm-next.

And fix some bugs for drm/rockchip drm_mm

[0]: http://www.spinics.net/lists/arm-kernel/msg513781.html
[1]: https://patchwork.kernel.org/patch/9196367
[2]: https://patchwork.kernel.org/patch/9196369

Changes in v2:
Advices by Tomasz:
  add some fixes patches from chromeos project.

Mark Yao (2):
  drm/rockchip: gem: add mutex lock for drm mm
  drm/rockchip: gem: fixup iommu_map_sg error path

Shunqian Zheng (1):
  drm/rockchip: Use common IOMMU API to attach devices

Tomasz Figa (3):
  drm/rockchip: Do not use DMA mapping API if attached to IOMMU domain
  drm/rockchip: Fix the call to drm_gem_put_pages()
  drm/rockchip: Call drm_gem_object_release() to destroy GEM base

Ørjan Eide (1):
  drm/rockchip: Respect page offset in IOMMU mmap

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 101 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   6 +-
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 244 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_gem.h |   8 +
 4 files changed, 298 insertions(+), 61 deletions(-)

-- 
1.9.1


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


[PATCH v2 1/7] drm/rockchip: Do not use DMA mapping API if attached to IOMMU domain

2017-02-07 Thread Mark Yao
From: Tomasz Figa 

The API is not suitable for subsystems consisting of multiple devices
and requires severe hacks to use it. To mitigate this, this patch
implements allocation and address space management locally by using
helpers provided by DRM framework, like other DRM drivers do, e.g.
Tegra.

This patch should not introduce any functional changes until the driver
is made to attach subdevices into an IOMMU domain with the generic IOMMU
API, which will happen in following patch. Based heavily on GEM
implementation of Tegra DRM driver.

Signed-off-by: Tomasz Figa 
Signed-off-by: Shunqian Zheng 
Acked-by: Mark Yao 
Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   4 +-
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 217 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_gem.h |   8 +
 3 files changed, 219 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index fb6226c..7c123d9 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -30,6 +30,7 @@
 
 struct drm_device;
 struct drm_connector;
+struct iommu_domain;
 
 /*
  * Rockchip drm private crtc funcs.
@@ -60,7 +61,8 @@ struct rockchip_drm_private {
struct drm_gem_object *fbdev_bo;
const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
struct drm_atomic_state *state;
-
+   struct iommu_domain *domain;
+   struct drm_mm mm;
struct list_head psr_list;
spinlock_t psr_list_lock;
 };
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index b70f942..5209392 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -16,11 +16,135 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_gem.h"
 
-static int rockchip_gem_alloc_buf(struct rockchip_gem_object *rk_obj,
+static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
+{
+   struct drm_device *drm = rk_obj->base.dev;
+   struct rockchip_drm_private *private = drm->dev_private;
+   int prot = IOMMU_READ | IOMMU_WRITE;
+   ssize_t ret;
+
+   ret = drm_mm_insert_node_generic(&private->mm, &rk_obj->mm,
+rk_obj->base.size, PAGE_SIZE,
+0, 0);
+   if (ret < 0) {
+   DRM_ERROR("out of I/O virtual memory: %zd\n", ret);
+   return ret;
+   }
+
+   rk_obj->dma_addr = rk_obj->mm.start;
+
+   ret = iommu_map_sg(private->domain, rk_obj->dma_addr, rk_obj->sgt->sgl,
+  rk_obj->sgt->nents, prot);
+   if (ret < 0) {
+   DRM_ERROR("failed to map buffer: %zd\n", ret);
+   goto err_remove_node;
+   }
+
+   rk_obj->size = ret;
+
+   return 0;
+
+err_remove_node:
+   drm_mm_remove_node(&rk_obj->mm);
+
+   return ret;
+}
+
+static int rockchip_gem_iommu_unmap(struct rockchip_gem_object *rk_obj)
+{
+   struct drm_device *drm = rk_obj->base.dev;
+   struct rockchip_drm_private *private = drm->dev_private;
+
+   iommu_unmap(private->domain, rk_obj->dma_addr, rk_obj->size);
+   drm_mm_remove_node(&rk_obj->mm);
+
+   return 0;
+}
+
+static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj)
+{
+   struct drm_device *drm = rk_obj->base.dev;
+   int ret, i;
+   struct scatterlist *s;
+
+   rk_obj->pages = drm_gem_get_pages(&rk_obj->base);
+   if (IS_ERR(rk_obj->pages))
+   return PTR_ERR(rk_obj->pages);
+
+   rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT;
+
+   rk_obj->sgt = drm_prime_pages_to_sg(rk_obj->pages, rk_obj->num_pages);
+   if (IS_ERR(rk_obj->sgt)) {
+   ret = PTR_ERR(rk_obj->sgt);
+   goto err_put_pages;
+   }
+
+   /*
+* Fake up the SG table so that dma_sync_sg_for_device() can be used
+* to flush the pages associated with it.
+*
+* TODO: Replace this by drm_clflush_sg() once it can be implemented
+* without relying on symbols that are not exported.
+*/
+   for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->nents, i)
+   sg_dma_address(s) = sg_phys(s);
+
+   dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl, rk_obj->sgt->nents,
+  DMA_TO_DEVICE);
+
+   return 0;
+
+err_put_pages:
+   drm_gem_put_pages(&rk_obj->base, rk_obj->pages, false, false);
+   return ret;
+}
+
+static void rockchip_gem_put_pages(struct rockchip_gem_object *rk_obj)
+{
+   sg_free_table(rk_obj->sgt);
+   kfree(rk_

[PATCH v2 4/7] drm/rockchip: gem: fixup iommu_map_sg error path

2017-02-07 Thread Mark Yao
The return value of iommu_map_sg is size_t, it's unsigned,
So check ret < 0 is wrong.

And if iommu_map_sg is error, it's return value is zero, but
rockchip_gem_iommu_map feel the zero return value is success,
bug happen:

[5.227458] [drm:rockchip_gem_iommu_map] *ERROR* failed to map buffer: 0
[   12.291590] WARNING: at drivers/gpu/drm/drm_mm.c:369
[   12.291611] Modules linked in:
[   12.291634]
[   12.291658] CPU: 4 PID: 338 Comm: cameraserver Not tainted 4.4.41 #196
[   12.291680] Hardware name: rockchip,rk3399-mid (DT)
[   12.291703] task: ffc0e5a23100 ti: ffc0e5a64000 task.ti: 
ffc0e5a64000
[   12.291739] PC is at drm_mm_remove_node+0xc/0xf8
[   12.291766] LR is at rockchip_gem_iommu_unmap+0x3c/0x54
[   12.303799] [] drm_mm_remove_node+0xc/0xf8
[   12.303827] [] rockchip_gem_free_object+0x98/0x168
[   12.303854] [] drm_gem_object_free+0x2c/0x34
[   12.303878] [] drm_gem_dmabuf_release+0x90/0xa4
[   12.303904] [] dma_buf_release+0x64/0x15c
[   12.303929] [] __fput+0xe0/0x1a4
[   12.303950] [] fput+0xc/0x14
[   12.303977] [] task_work_run+0xa0/0xc0
[   12.304004] [] do_notify_resume+0x40/0x54
[   12.304026] [] work_pending+0x10/0x14

Change-Id: Id79c052691270553c1c60086f9926f39a5296354
Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index 8d27965..cc48673 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -44,8 +44,10 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object 
*rk_obj)
 
ret = iommu_map_sg(private->domain, rk_obj->dma_addr, rk_obj->sgt->sgl,
   rk_obj->sgt->nents, prot);
-   if (ret < 0) {
-   DRM_ERROR("failed to map buffer: %zd\n", ret);
+   if (ret < rk_obj->base.size) {
+   DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n",
+ ret, rk_obj->base.size);
+   ret = -ENOMEM;
goto err_remove_node;
}
 
-- 
1.9.1


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


[PATCH v2 2/7] drm/rockchip: Use common IOMMU API to attach devices

2017-02-07 Thread Mark Yao
From: Shunqian Zheng 

Rockchip DRM used the arm special API, arm_iommu_*(), to attach
iommu for ARM32 SoCs. This patch convert to common iommu API
so it would support ARM64 like RK3399.

Since previous patch added support for direct IOMMU address space
management, there is no need to use DMA API anymore and this patch wires
things to use the new method.

Signed-off-by: Shunqian Zheng 
Signed-off-by: Tomasz Figa 
Acked-by: Mark Yao 
Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 100 +++-
 1 file changed, 53 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index c30d649..7a610e9 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -14,19 +14,19 @@
  * GNU General Public License for more details.
  */
 
-#include 
-
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_fb.h"
@@ -50,28 +50,31 @@
 int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
   struct device *dev)
 {
-   struct dma_iommu_mapping *mapping = drm_dev->dev->archdata.mapping;
+   struct rockchip_drm_private *private = drm_dev->dev_private;
int ret;
 
if (!is_support_iommu)
return 0;
 
-   ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
-   if (ret)
+   ret = iommu_attach_device(private->domain, dev);
+   if (ret) {
+   dev_err(dev, "Failed to attach iommu device\n");
return ret;
+   }
 
-   dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
-
-   return arm_iommu_attach_device(dev, mapping);
+   return 0;
 }
 
 void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
struct device *dev)
 {
+   struct rockchip_drm_private *private = drm_dev->dev_private;
+   struct iommu_domain *domain = private->domain;
+
if (!is_support_iommu)
return;
 
-   arm_iommu_detach_device(dev);
+   iommu_detach_device(domain, dev);
 }
 
 int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
@@ -123,11 +126,45 @@ static void rockchip_drm_crtc_disable_vblank(struct 
drm_device *dev,
priv->crtc_funcs[pipe]->disable_vblank(crtc);
 }
 
+static int rockchip_drm_init_iommu(struct drm_device *drm_dev)
+{
+   struct rockchip_drm_private *private = drm_dev->dev_private;
+   struct iommu_domain_geometry *geometry;
+   u64 start, end;
+
+   if (!is_support_iommu)
+   return 0;
+
+   private->domain = iommu_domain_alloc(&platform_bus_type);
+   if (!private->domain)
+   return -ENOMEM;
+
+   geometry = &private->domain->geometry;
+   start = geometry->aperture_start;
+   end = geometry->aperture_end;
+
+   DRM_DEBUG("IOMMU context initialized (aperture: %#llx-%#llx)\n",
+ start, end);
+   drm_mm_init(&private->mm, start, end - start + 1);
+
+   return 0;
+}
+
+static void rockchip_iommu_cleanup(struct drm_device *drm_dev)
+{
+   struct rockchip_drm_private *private = drm_dev->dev_private;
+
+   if (!is_support_iommu)
+   return;
+
+   drm_mm_takedown(&private->mm);
+   iommu_domain_free(private->domain);
+}
+
 static int rockchip_drm_bind(struct device *dev)
 {
struct drm_device *drm_dev;
struct rockchip_drm_private *private;
-   struct dma_iommu_mapping *mapping = NULL;
int ret;
 
drm_dev = drm_dev_alloc(&rockchip_drm_driver, dev);
@@ -151,38 +188,14 @@ static int rockchip_drm_bind(struct device *dev)
 
rockchip_drm_mode_config_init(drm_dev);
 
-   dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms),
- GFP_KERNEL);
-   if (!dev->dma_parms) {
-   ret = -ENOMEM;
+   ret = rockchip_drm_init_iommu(drm_dev);
+   if (ret)
goto err_config_cleanup;
-   }
-
-   if (is_support_iommu) {
-   /* TODO(djkurtz): fetch the mapping start/size from somewhere */
-   mapping = arm_iommu_create_mapping(&platform_bus_type,
-  0x,
-  SZ_2G);
-   if (IS_ERR(mapping)) {
-   ret = PTR_ERR(mapping);
-   goto err_config_cleanup;
-   }
-
-   ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
-   if (ret)
-   goto err_release_mapping;
-
-   dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
-
-   

[PATCH v2 3/7] drm/rockchip: gem: add mutex lock for drm mm

2017-02-07 Thread Mark Yao
drm_mm_insert_node_generic and drm_mm_remove_node may access same
resource with list ops, it's not threads safe, so protect this context
with mutex lock.

Fix bug:
[49451.856244] 
==
[49451.856350] BUG: KASAN: wild-memory-access on address dead0108
[49451.856379] Write of size 8 by task Binder:218_4/683
[49451.856417] CPU: 2 PID: 683 Comm: Binder:218_4 Not tainted 4.4.36 #62
[49451.856443] Hardware name: Rockchip RK3399 Excavator Board edp (Android) (DT)
[49451.856469] Call trace:
[49451.856519] [] dump_backtrace+0x0/0x230
[49451.856556] [] show_stack+0x14/0x1c
[49451.856592] [] dump_stack+0xa0/0xc8
[49451.856633] [] kasan_report+0x110/0x4dc
[49451.856670] [] __asan_store8+0x24/0x7c
[49451.856715] [] drm_mm_insert_node_generic+0x2dc/0x464
[49451.856760] [] rockchip_gem_iommu_map+0x60/0x158
[49451.856794] [] rockchip_gem_create_object+0x278/0x488
[49451.856827] [] rockchip_gem_create_with_handle+0x24/0x10c
[49451.856862] [] rockchip_gem_create_ioctl+0x3c/0x50
[49451.856896] [] drm_ioctl+0x354/0x52c
[49451.856939] [] do_vfs_ioctl+0x670/0x78c
[49451.856976] [] SyS_ioctl+0x60/0x88
[49451.857009] [] el0_svc_naked+0x24/0x28

Change-Id: I2ea377aa9ca24f70c59e2d86f2a6ad5ccb9c0891
Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 1 +
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 2 ++
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 9 +
 3 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 7a610e9..b360e62 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -146,6 +146,7 @@ static int rockchip_drm_init_iommu(struct drm_device 
*drm_dev)
DRM_DEBUG("IOMMU context initialized (aperture: %#llx-%#llx)\n",
  start, end);
drm_mm_init(&private->mm, start, end - start + 1);
+   mutex_init(&private->mm_lock);
 
return 0;
 }
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 7c123d9..adc3930 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -62,6 +62,8 @@ struct rockchip_drm_private {
const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
struct drm_atomic_state *state;
struct iommu_domain *domain;
+   /* protect drm_mm on multi-threads */
+   struct mutex mm_lock;
struct drm_mm mm;
struct list_head psr_list;
spinlock_t psr_list_lock;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index 5209392..8d27965 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -28,9 +28,13 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object 
*rk_obj)
int prot = IOMMU_READ | IOMMU_WRITE;
ssize_t ret;
 
+   mutex_lock(&private->mm_lock);
+
ret = drm_mm_insert_node_generic(&private->mm, &rk_obj->mm,
 rk_obj->base.size, PAGE_SIZE,
 0, 0);
+
+   mutex_unlock(&private->mm_lock);
if (ret < 0) {
DRM_ERROR("out of I/O virtual memory: %zd\n", ret);
return ret;
@@ -61,8 +65,13 @@ static int rockchip_gem_iommu_unmap(struct 
rockchip_gem_object *rk_obj)
struct rockchip_drm_private *private = drm->dev_private;
 
iommu_unmap(private->domain, rk_obj->dma_addr, rk_obj->size);
+
+   mutex_lock(&private->mm_lock);
+
drm_mm_remove_node(&rk_obj->mm);
 
+   mutex_unlock(&private->mm_lock);
+
return 0;
 }
 
-- 
1.9.1


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


[PATCH v2 5/7] drm/rockchip: Fix the call to drm_gem_put_pages()

2017-02-07 Thread Mark Yao
From: Tomasz Figa 

When freeing the buffer we don't have any means of determining if the
buffer was read or written, so we must assume both and pass true for
both arguments of drm_gem_put_pages(). Let's fix the code which
currently passes false.

TEST=while true; do backlight_dbus_tool --set --percent=0 && sleep 8 &&
 backlight_dbus_tool --set --percent=100 && sleep 3 ; done

Signed-off-by: Tomasz Figa 
Signed-off-by: Mark Yao 
Reviewed-on: https://chromium-review.googlesource.com/382934
Reviewed-by: Daniel Kurtz 
---
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index cc48673..1daa531 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -119,7 +119,7 @@ static void rockchip_gem_put_pages(struct 
rockchip_gem_object *rk_obj)
 {
sg_free_table(rk_obj->sgt);
kfree(rk_obj->sgt);
-   drm_gem_put_pages(&rk_obj->base, rk_obj->pages, false, false);
+   drm_gem_put_pages(&rk_obj->base, rk_obj->pages, true, true);
 }
 
 static int rockchip_gem_alloc_iommu(struct rockchip_gem_object *rk_obj,
-- 
1.9.1


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


[PATCH v2 7/7] drm/rockchip: Call drm_gem_object_release() to destroy GEM base

2017-02-07 Thread Mark Yao
From: Tomasz Figa 

When converting the driver to use shmem-backed GEMs for IOMMU-enabled
systems, we forgot to add calls to drm_gem_object_release(), which gave
us a quite nice memory leak. This patch adds the missing calls.

Fixes: f11d5f0 ("FROMLIST: drm/rockchip: Do not use DMA mapping API if
attached to IOMMU domain")

TEST=while true; do backlight_dbus_tool --set --percent=0 && sleep 8 &&
 backlight_dbus_tool --set --percent=100 && sleep 3 ; done

Signed-off-by: Tomasz Figa 
Signed-off-by: Mark Yao 
Reviewed-on: https://chromium-review.googlesource.com/385456
Reviewed-by: Douglas Anderson 
Reviewed-by: Daniel Kurtz 
---
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index 1769146..df9e570 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -301,6 +301,12 @@ int rockchip_gem_mmap(struct file *filp, struct 
vm_area_struct *vma)
return rockchip_drm_gem_object_mmap(obj, vma);
 }
 
+static void rockchip_gem_release_object(struct rockchip_gem_object *rk_obj)
+{
+   drm_gem_object_release(&rk_obj->base);
+   kfree(rk_obj);
+}
+
 struct rockchip_gem_object *
rockchip_gem_create_object(struct drm_device *drm, unsigned int size,
   bool alloc_kmap)
@@ -326,7 +332,7 @@ struct rockchip_gem_object *
return rk_obj;
 
 err_free_rk_obj:
-   kfree(rk_obj);
+   rockchip_gem_release_object(rk_obj);
return ERR_PTR(ret);
 }
 
@@ -338,13 +344,11 @@ void rockchip_gem_free_object(struct drm_gem_object *obj)
 {
struct rockchip_gem_object *rk_obj;
 
-   drm_gem_free_mmap_offset(obj);
-
rk_obj = to_rockchip_obj(obj);
 
rockchip_gem_free_buf(rk_obj);
 
-   kfree(rk_obj);
+   rockchip_gem_release_object(rk_obj);
 }
 
 /*
-- 
1.9.1


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


[PATCH v2 6/7] drm/rockchip: Respect page offset in IOMMU mmap

2017-02-07 Thread Mark Yao
From: Ørjan Eide 

When mapping buffers through the PRIME DMA-buf mmap path we might be
given an offset which has to be respected. The DRM GEM mmap path already
takes care of zeroing out the fake mmap offset, so we can just make the
IOMMU mmap implementation always respect the offset.

TEST=graphics_GLBench

Signed-off-by: rjan Eide 
Signed-off-by: Tomasz Figa 
Signed-off-by: Mark Yao 
Reviewed-on: https://chromium-review.googlesource.com/386477
Reviewed-by: Daniel Kurtz 
---
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index 1daa531..1769146 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -221,12 +221,16 @@ static int rockchip_drm_gem_object_mmap_iommu(struct 
drm_gem_object *obj,
unsigned int i, count = obj->size >> PAGE_SHIFT;
unsigned long user_count = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
unsigned long uaddr = vma->vm_start;
+   unsigned long offset = vma->vm_pgoff;
+   unsigned long end = user_count + offset;
int ret;
 
-   if (user_count == 0 || user_count > count)
+   if (user_count == 0)
+   return -ENXIO;
+   if (end > count)
return -ENXIO;
 
-   for (i = 0; i < user_count; i++) {
+   for (i = offset; i < end; i++) {
ret = vm_insert_page(vma, uaddr, rk_obj->pages[i]);
if (ret)
return ret;
-- 
1.9.1


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


Re: [PATCH v2 3/7] drm/rockchip: gem: add mutex lock for drm mm

2017-02-07 Thread Mark yao

On 2017年02月07日 20:19, Thierry Reding wrote:

On Tue, Feb 07, 2017 at 04:35:38PM +0800, Mark Yao wrote:

drm_mm_insert_node_generic and drm_mm_remove_node may access same
resource with list ops, it's not threads safe, so protect this context
with mutex lock.

Fix bug:
[49451.856244] 
==
[49451.856350] BUG: KASAN: wild-memory-access on address dead0108
[49451.856379] Write of size 8 by task Binder:218_4/683
[49451.856417] CPU: 2 PID: 683 Comm: Binder:218_4 Not tainted 4.4.36 #62
[49451.856443] Hardware name: Rockchip RK3399 Excavator Board edp (Android) (DT)
[49451.856469] Call trace:
[49451.856519] [] dump_backtrace+0x0/0x230
[49451.856556] [] show_stack+0x14/0x1c
[49451.856592] [] dump_stack+0xa0/0xc8
[49451.856633] [] kasan_report+0x110/0x4dc
[49451.856670] [] __asan_store8+0x24/0x7c
[49451.856715] [] drm_mm_insert_node_generic+0x2dc/0x464
[49451.856760] [] rockchip_gem_iommu_map+0x60/0x158
[49451.856794] [] rockchip_gem_create_object+0x278/0x488
[49451.856827] [] rockchip_gem_create_with_handle+0x24/0x10c
[49451.856862] [] rockchip_gem_create_ioctl+0x3c/0x50
[49451.856896] [] drm_ioctl+0x354/0x52c
[49451.856939] [] do_vfs_ioctl+0x670/0x78c
[49451.856976] [] SyS_ioctl+0x60/0x88
[49451.857009] [] el0_svc_naked+0x24/0x28

Change-Id: I2ea377aa9ca24f70c59e2d86f2a6ad5ccb9c0891

This is meaningless in an upstream tree. Please remove.

Thierry

Right, Forget to remove "Change-Id: "

Thanks.

--
Mark Yao


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


Re: [PATCH 1/2] drm/rockchip: support mode_valid for crtc

2017-02-07 Thread Mark yao

On 2017年02月08日 00:14, Sean Paul wrote:

On Sun, Feb 05, 2017 at 03:36:36PM +0800, Mark Yao wrote:

drm crtc already has mode_fixup callback to can do mode check, but
We actually want to valid display mode on connector getmode time,
mode_fixup can't do it.

So add a private mode_valid callback to rockchip crtc, connectors can
check mode with this mode_valid callback.


There are some nasty layer violations happening in this set. You should use
mode_fixup if the crtc has limitations on the mode being set.

Sean
Mode_fixup can also check crtc limitations, but it's secondly time to 
check display mode.


mode_fixup only works on drm_setcrtc or atomic_commit check, when 
userspace get a series of display modes,
They don't know which display mode is bad before drm_setcrtc or 
atomic_commit check, they need try,
but drm_setcrtc or atomic_commit check not only for display mode check, 
means that userspace didn't have a sure

method to verify display mode.

So I try to add the mode_valid callback to connector getmodes time, 
verify display mode before send mode list to userspace.

then userspace would get a good display mode list.


Signed-off-by: Mark Yao 
---
  drivers/gpu/drm/rockchip/rockchip_drm_drv.h |  2 ++
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 15 +++
  drivers/gpu/drm/rockchip/rockchip_drm_vop.h |  7 +++
  drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 13 +
  4 files changed, 37 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index fb6226c..d10b15c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -39,6 +39,8 @@
  struct rockchip_crtc_funcs {
int (*enable_vblank)(struct drm_crtc *crtc);
void (*disable_vblank)(struct drm_crtc *crtc);
+   enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc,
+  const struct drm_display_mode *mode);
  };
  
  struct rockchip_crtc_state {

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index fb5f001..256fe73 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -853,9 +853,24 @@ static void vop_crtc_disable_vblank(struct drm_crtc *crtc)
spin_unlock_irqrestore(&vop->irq_lock, flags);
  }
  
+static enum drm_mode_status

+vop_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
+{
+   struct vop *vop = to_vop(crtc);
+   const struct vop_data *vop_data = vop->data;
+
+   if (mode->hdisplay > vop_data->max_output.width)
+   return MODE_BAD_HVALUE;
+   if (mode->vdisplay > vop_data->max_output.height)
+   return MODE_BAD_VVALUE;
+
+   return MODE_OK;
+}
+
  static const struct rockchip_crtc_funcs private_crtc_funcs = {
.enable_vblank = vop_crtc_enable_vblank,
.disable_vblank = vop_crtc_disable_vblank,
+   .mode_valid = vop_crtc_mode_valid,
  };
  
  static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 1dbc526..9e9dba1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -133,6 +133,11 @@ struct vop_win_data {
enum drm_plane_type type;
  };
  
+struct vop_rect {

+   int width;
+   int height;
+};
+
  struct vop_data {
const struct vop_reg_data *init_table;
unsigned int table_size;
@@ -140,6 +145,8 @@ struct vop_data {
const struct vop_intr *intr;
const struct vop_win_data *win;
unsigned int win_size;
+   struct vop_rect max_input;
+   struct vop_rect max_output;
  };
  
  /* interrupt define */

diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c 
b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 35c51f3..0c72361 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -132,6 +132,8 @@
  };
  
  static const struct vop_data rk3036_vop = {

+   .max_input = { 1920, 1080},
+   .max_output = { 1920, 1080},
.init_table = rk3036_vop_init_reg_table,
.table_size = ARRAY_SIZE(rk3036_vop_init_reg_table),
.ctrl = &rk3036_ctrl_data,
@@ -273,6 +275,13 @@
  };
  
  static const struct vop_data rk3288_vop = {

+   .max_input = { 4096, 8192},
+   /*
+* TODO: rk3288 have two vop, big one support 3840x2160,
+* little one only support 2560x1600.
+* Now force use 3840x2160.
+*/
+   .max_output = { 3840, 2160},
.init_table = rk3288_init_reg_table,
.table_size = ARRAY_SIZE(rk3288_init_reg_table),
.intr = &rk3288_vop_intr,
@@ -339,6 +348,8 @@
  };
  
  static const struct vop_data rk3399_vop_big = {

+   .max_i

Re: [PATCH v2 0/7] drm/rockchip: switch to drm_mm for support arm64 iommu

2017-02-07 Thread Mark yao

On 2017年02月07日 20:38, Thierry Reding wrote:

On Tue, Feb 07, 2017 at 04:35:35PM +0800, Mark Yao wrote:

Some iommu patches on the series[0] "iommu/rockchip: Fix bugs and
enable on ARM64" already landed, So drm/rockchip related patches [1] and [2]
ready to landed, this series just rebase them to lastest drm-next.

And fix some bugs for drm/rockchip drm_mm

[0]: http://www.spinics.net/lists/arm-kernel/msg513781.html
[1]: https://patchwork.kernel.org/patch/9196367
[2]: https://patchwork.kernel.org/patch/9196369

Changes in v2:
Advices by Tomasz:
   add some fixes patches from chromeos project.

I think those fixes should've been squashed into the patches that they
fix. It's very unusual to merge patches upstream that are know to have
been fixed already.

Thierry

Got it, I will fix them at v3 version.

Thanks for review.

--
Mark Yao


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


[PATCH v3 1/2] drm/rockchip: Do not use DMA mapping API if attached to IOMMU domain

2017-02-09 Thread Mark Yao
From: Tomasz Figa 

The API is not suitable for subsystems consisting of multiple devices
and requires severe hacks to use it. To mitigate this, this patch
implements allocation and address space management locally by using
helpers provided by DRM framework, like other DRM drivers do, e.g.
Tegra.

This patch should not introduce any functional changes until the driver
is made to attach subdevices into an IOMMU domain with the generic IOMMU
API, which will happen in following patch. Based heavily on GEM
implementation of Tegra DRM driver.

Signed-off-by: Tomasz Figa 
Signed-off-by: Shunqian Zheng 
Signed-off-by: Mark Yao 
Signed-off-by: rjan Eide 
Tested-by: Heiko Stuebner 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   6 +-
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 244 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_gem.h |   8 +
 3 files changed, 244 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index fb6226c..adc3930 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -30,6 +30,7 @@
 
 struct drm_device;
 struct drm_connector;
+struct iommu_domain;
 
 /*
  * Rockchip drm private crtc funcs.
@@ -60,7 +61,10 @@ struct rockchip_drm_private {
struct drm_gem_object *fbdev_bo;
const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
struct drm_atomic_state *state;
-
+   struct iommu_domain *domain;
+   /* protect drm_mm on multi-threads */
+   struct mutex mm_lock;
+   struct drm_mm mm;
struct list_head psr_list;
spinlock_t psr_list_lock;
 };
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index b70f942..df9e570 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -16,11 +16,146 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_gem.h"
 
-static int rockchip_gem_alloc_buf(struct rockchip_gem_object *rk_obj,
+static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
+{
+   struct drm_device *drm = rk_obj->base.dev;
+   struct rockchip_drm_private *private = drm->dev_private;
+   int prot = IOMMU_READ | IOMMU_WRITE;
+   ssize_t ret;
+
+   mutex_lock(&private->mm_lock);
+
+   ret = drm_mm_insert_node_generic(&private->mm, &rk_obj->mm,
+rk_obj->base.size, PAGE_SIZE,
+0, 0);
+
+   mutex_unlock(&private->mm_lock);
+   if (ret < 0) {
+   DRM_ERROR("out of I/O virtual memory: %zd\n", ret);
+   return ret;
+   }
+
+   rk_obj->dma_addr = rk_obj->mm.start;
+
+   ret = iommu_map_sg(private->domain, rk_obj->dma_addr, rk_obj->sgt->sgl,
+  rk_obj->sgt->nents, prot);
+   if (ret < rk_obj->base.size) {
+   DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n",
+ ret, rk_obj->base.size);
+   ret = -ENOMEM;
+   goto err_remove_node;
+   }
+
+   rk_obj->size = ret;
+
+   return 0;
+
+err_remove_node:
+   drm_mm_remove_node(&rk_obj->mm);
+
+   return ret;
+}
+
+static int rockchip_gem_iommu_unmap(struct rockchip_gem_object *rk_obj)
+{
+   struct drm_device *drm = rk_obj->base.dev;
+   struct rockchip_drm_private *private = drm->dev_private;
+
+   iommu_unmap(private->domain, rk_obj->dma_addr, rk_obj->size);
+
+   mutex_lock(&private->mm_lock);
+
+   drm_mm_remove_node(&rk_obj->mm);
+
+   mutex_unlock(&private->mm_lock);
+
+   return 0;
+}
+
+static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj)
+{
+   struct drm_device *drm = rk_obj->base.dev;
+   int ret, i;
+   struct scatterlist *s;
+
+   rk_obj->pages = drm_gem_get_pages(&rk_obj->base);
+   if (IS_ERR(rk_obj->pages))
+   return PTR_ERR(rk_obj->pages);
+
+   rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT;
+
+   rk_obj->sgt = drm_prime_pages_to_sg(rk_obj->pages, rk_obj->num_pages);
+   if (IS_ERR(rk_obj->sgt)) {
+   ret = PTR_ERR(rk_obj->sgt);
+   goto err_put_pages;
+   }
+
+   /*
+* Fake up the SG table so that dma_sync_sg_for_device() can be used
+* to flush the pages associated with it.
+*
+* TODO: Replace this by drm_clflush_sg() once it can be implemented
+* without relying on symbols that are not exported.
+*/
+   for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->nents, i)
+   sg_dma_address(s) = sg_phys(

[PATCH v3 0/2] drm/rockchip: switch to drm_mm for support arm64 iommu

2017-02-09 Thread Mark Yao
Some iommu patches on the series[0] "iommu/rockchip: Fix bugs and
enable on ARM64" already landed, So drm/rockchip related patches [1] and [2]
ready to landed, this series just rebase them to lastest drm-next.

Thanks Heiko's Tested-by on rk3288 and rk3399 platform.

Changes in v3:
Advices by Tomasz and Thierry:
  merge fixes into origin patch.

Changes in v2:
Advices by Tomasz:
  add some fixes patches from chromeos project.

Shunqian Zheng (1):
  drm/rockchip: Use common IOMMU API to attach devices

Tomasz Figa (1):
  drm/rockchip: Do not use DMA mapping API if attached to IOMMU domain

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 101 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   6 +-
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 244 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_gem.h |   8 +
 4 files changed, 298 insertions(+), 61 deletions(-)

-- 
1.9.1


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


[PATCH v3 2/2] drm/rockchip: Use common IOMMU API to attach devices

2017-02-09 Thread Mark Yao
From: Shunqian Zheng 

Rockchip DRM used the arm special API, arm_iommu_*(), to attach
iommu for ARM32 SoCs. This patch convert to common iommu API
so it would support ARM64 like RK3399.

Since previous patch added support for direct IOMMU address space
management, there is no need to use DMA API anymore and this patch wires
things to use the new method.

Signed-off-by: Shunqian Zheng 
Signed-off-by: Tomasz Figa 
Signed-off-by: Mark Yao 
Tested-by: Heiko Stuebner 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 101 +++-
 1 file changed, 54 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index c30d649..b360e62 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -14,19 +14,19 @@
  * GNU General Public License for more details.
  */
 
-#include 
-
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_fb.h"
@@ -50,28 +50,31 @@
 int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
   struct device *dev)
 {
-   struct dma_iommu_mapping *mapping = drm_dev->dev->archdata.mapping;
+   struct rockchip_drm_private *private = drm_dev->dev_private;
int ret;
 
if (!is_support_iommu)
return 0;
 
-   ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
-   if (ret)
+   ret = iommu_attach_device(private->domain, dev);
+   if (ret) {
+   dev_err(dev, "Failed to attach iommu device\n");
return ret;
+   }
 
-   dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
-
-   return arm_iommu_attach_device(dev, mapping);
+   return 0;
 }
 
 void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
struct device *dev)
 {
+   struct rockchip_drm_private *private = drm_dev->dev_private;
+   struct iommu_domain *domain = private->domain;
+
if (!is_support_iommu)
return;
 
-   arm_iommu_detach_device(dev);
+   iommu_detach_device(domain, dev);
 }
 
 int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
@@ -123,11 +126,46 @@ static void rockchip_drm_crtc_disable_vblank(struct 
drm_device *dev,
priv->crtc_funcs[pipe]->disable_vblank(crtc);
 }
 
+static int rockchip_drm_init_iommu(struct drm_device *drm_dev)
+{
+   struct rockchip_drm_private *private = drm_dev->dev_private;
+   struct iommu_domain_geometry *geometry;
+   u64 start, end;
+
+   if (!is_support_iommu)
+   return 0;
+
+   private->domain = iommu_domain_alloc(&platform_bus_type);
+   if (!private->domain)
+   return -ENOMEM;
+
+   geometry = &private->domain->geometry;
+   start = geometry->aperture_start;
+   end = geometry->aperture_end;
+
+   DRM_DEBUG("IOMMU context initialized (aperture: %#llx-%#llx)\n",
+ start, end);
+   drm_mm_init(&private->mm, start, end - start + 1);
+   mutex_init(&private->mm_lock);
+
+   return 0;
+}
+
+static void rockchip_iommu_cleanup(struct drm_device *drm_dev)
+{
+   struct rockchip_drm_private *private = drm_dev->dev_private;
+
+   if (!is_support_iommu)
+   return;
+
+   drm_mm_takedown(&private->mm);
+   iommu_domain_free(private->domain);
+}
+
 static int rockchip_drm_bind(struct device *dev)
 {
struct drm_device *drm_dev;
struct rockchip_drm_private *private;
-   struct dma_iommu_mapping *mapping = NULL;
int ret;
 
drm_dev = drm_dev_alloc(&rockchip_drm_driver, dev);
@@ -151,38 +189,14 @@ static int rockchip_drm_bind(struct device *dev)
 
rockchip_drm_mode_config_init(drm_dev);
 
-   dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms),
- GFP_KERNEL);
-   if (!dev->dma_parms) {
-   ret = -ENOMEM;
+   ret = rockchip_drm_init_iommu(drm_dev);
+   if (ret)
goto err_config_cleanup;
-   }
-
-   if (is_support_iommu) {
-   /* TODO(djkurtz): fetch the mapping start/size from somewhere */
-   mapping = arm_iommu_create_mapping(&platform_bus_type,
-  0x,
-  SZ_2G);
-   if (IS_ERR(mapping)) {
-   ret = PTR_ERR(mapping);
-   goto err_config_cleanup;
-   }
-
-   ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
-   if (ret)
-   goto err_release_mapping;
-
- 

Re: [PATCH] drm/rockchip: add extcon dependency for DP

2017-02-14 Thread Mark yao

On 2017年02月15日 05:31, Arnd Bergmann wrote:

The newly added DP driver links against the extcon core, which fails when
extcon is a module and this driver is not:

drivers/gpu/drm/rockchip/cdn-dp-core.o: In function `cdn_dp_get_port_lanes':
cdn-dp-core.c:(.text.cdn_dp_get_port_lanes+0x24): undefined reference to 
`extcon_get_state'
cdn-dp-core.c:(.text.cdn_dp_get_port_lanes+0x44): undefined reference to 
`extcon_get_property'

Let's make Kconfig enforce correct behavior with a dependency.


Thanks for the fix.

Applied to my drm-next.


Fixes: 1a0f7ed3abe2 ("drm/rockchip: cdn-dp: add cdn DP support for rk3399")
Signed-off-by: Arnd Bergmann 
---
  drivers/gpu/drm/rockchip/Kconfig | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index ad31b3eb408f..0e4eb845cbb0 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -24,6 +24,7 @@ config ROCKCHIP_ANALOGIX_DP
  config ROCKCHIP_CDN_DP
  tristate "Rockchip cdn DP"
  depends on DRM_ROCKCHIP
+   depends on EXTCON
select SND_SOC_HDMI_CODEC if SND_SOC
  help
  This selects support for Rockchip SoC specific extensions



--
Mark Yao


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


[GIT PULL] drm/rockchip: convert to drm_mm

2017-02-15 Thread Mark yao

  
  
Hi Dave

After convert to drm_mm, rockchip arm64 platform can works with
iommu, like rk3399. it's import patches for rockchip arm64 platform

And these patches already have full reviewed, I hope these patches
can be landed.

  
Best regards

The following changes since commit
13f62f54d174d3417c3caaafedf5e22a0a03e442:

  Merge branch 'drm-next-4.11' of
git://people.freedesktop.org/~agd5f/linux into drm-next (2017-02-10
10:13:30 +1000)

are available in the git repository at:


  https://github.com/markyzq/kernel-drm-rockchip.git
drm-rockchip-next-2017-02-16

for you to fetch changes up to
1aa5ca6e3ec63aa5815d78646748e88a7ceb1c8e:

  drm/rockchip: Use common IOMMU API to attach devices (2017-02-15
08:52:13 +0800)


Shunqian Zheng (1):
  drm/rockchip: Use common IOMMU API to attach devices

Tomasz Figa (1):
  drm/rockchip: Do not use DMA mapping API if attached to IOMMU
domain

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 101
-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   6 +++-
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 244
---
 drivers/gpu/drm/rockchip/rockchip_drm_gem.h |   8 +
 4 files changed, 298 insertions(+), 61 deletions(-)


-- Mark Yao
  


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


Re: [PATCH] drm/rockchip: cdn-dp: Fix error handling

2017-02-19 Thread Mark yao

On 2017年02月20日 00:59, Christophe JAILLET wrote:

It is likely that both 'clk_disable_unprepare()' should be called if
'pm_runtime_get_sync()' fails.

Add a new label for that, because 'err_set_rate' is not meaningful in this
case.


Fixes: 1a0f7ed3abe2 ("drm/rockchip: cdn-dp: add cdn DP support for rk3399")

Signed-off-by: Christophe JAILLET 
---
Not sure but a 'pm_runtime_get_sync()' is maybe also required in the
'err_set_rate' path.
---
  drivers/gpu/drm/rockchip/cdn-dp-core.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 9ab67a670885..0fe1ec8b8fb1 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -111,7 +111,7 @@ static int cdn_dp_clk_enable(struct cdn_dp_device *dp)
ret = pm_runtime_get_sync(dp->dev);
if (ret < 0) {
DRM_DEV_ERROR(dp->dev, "cannot get pm runtime %d\n", ret);
-   goto err_pclk;
+   goto err_sync;


I think the name err_pm_runtime_get is better.
err_sync is not a clear name for the pm_runtime_get_sync.


}
  
  	reset_control_assert(dp->core_rst);

@@ -133,6 +133,7 @@ static int cdn_dp_clk_enable(struct cdn_dp_device *dp)
return 0;
  
  err_set_rate:

+err_sync:


miss pm_runtime_put, it should be:

err_set_rate:
pm_runtime_put(dp->dev);
err_pm_runtime_get:
clk_disable_unprepare(dp->core_clk);
err_core_clk:


clk_disable_unprepare(dp->core_clk);
  err_core_clk:
clk_disable_unprepare(dp->pclk);



--
Mark Yao


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


Re: [PATCH] drm/rockchip: cdn-dp: Fix error handling

2017-02-19 Thread Mark yao

On 2017年02月20日 14:41, Christophe JAILLET wrote:

Le 20/02/2017 à 02:40, Mark yao a écrit :

On 2017年02月20日 00:59, Christophe JAILLET wrote:

It is likely that both 'clk_disable_unprepare()' should be called if
'pm_runtime_get_sync()' fails.

Add a new label for that, because 'err_set_rate' is not meaningful 
in this

case.


Fixes: 1a0f7ed3abe2 ("drm/rockchip: cdn-dp: add cdn DP support for 
rk3399")


Signed-off-by: Christophe JAILLET 
---
Not sure but a 'pm_runtime_get_sync()' is maybe also required in the
'err_set_rate' path.
---
  drivers/gpu/drm/rockchip/cdn-dp-core.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c

index 9ab67a670885..0fe1ec8b8fb1 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -111,7 +111,7 @@ static int cdn_dp_clk_enable(struct 
cdn_dp_device *dp)

  ret = pm_runtime_get_sync(dp->dev);
  if (ret < 0) {
  DRM_DEV_ERROR(dp->dev, "cannot get pm runtime %d\n", ret);
-goto err_pclk;
+goto err_sync;


I think the name err_pm_runtime_get is better.
err_sync is not a clear name for the pm_runtime_get_sync.


I will change it.


  }
reset_control_assert(dp->core_rst);
@@ -133,6 +133,7 @@ static int cdn_dp_clk_enable(struct 
cdn_dp_device *dp)

  return 0;
err_set_rate:
+err_sync:


miss pm_runtime_put, it should be:


I am wondering if 'pm_runtime_put_sync' should be added, instead.
We want to revert the 'pm_runtime_get_sync' of line 111. According to 
the naming of the function, the _sync version looks more logical to me.
Using ccoccinelle shows that 2/3 of functions calling both 
'pm_runtime_get_sync' and 'pm_runtime_get[_sync]' and using the _sync 
variant.




pm_runtime_get_sync will block until hardware actually done power configure,
we need make sure power is enable before use the hardware, So we should 
use pm_runtime_get_sync at power on.


At power off time, use pm_runtime_put is enough, it can be async, no 
need block.


Thanks.


Which semantic is the correct one?



err_set_rate:
pm_runtime_put(dp->dev);
err_pm_runtime_get:
clk_disable_unprepare(dp->core_clk);
err_core_clk:


clk_disable_unprepare(dp->core_clk);
  err_core_clk:
  clk_disable_unprepare(dp->pclk);











--
Mark Yao


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


Re: [PATCH v2] drm/rockchip: cdn-dp: Fix error handling

2017-02-19 Thread Mark yao

On 2017年02月20日 15:08, Christophe JAILLET wrote:

It is likely that both 'clk_disable_unprepare()' should be called if
'pm_runtime_get_sync()' fails.

Add a new label for that, because 'err_set_rate' is not meaningful in this
case.

Add a missing call to 'pm_runtime_put()'.

Fixes: 1a0f7ed3abe2 ("drm/rockchip: cdn-dp: add cdn DP support for rk3399")

Signed-off-by: Christophe JAILLET 


looks good for me

Reviewed-by: Mark Yao 



---
V2: rename label
 add missing call to 'pm_runtime_put_sync()' in error path
---
  drivers/gpu/drm/rockchip/cdn-dp-core.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 9ab67a670885..0fe1ec8b8fb1 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -111,7 +111,7 @@ static int cdn_dp_clk_enable(struct cdn_dp_device *dp)
ret = pm_runtime_get_sync(dp->dev);
if (ret < 0) {
DRM_DEV_ERROR(dp->dev, "cannot get pm runtime %d\n", ret);
-   goto err_pclk;
+   goto err_pm_runtime_get;
}
  
  	reset_control_assert(dp->core_rst);

@@ -133,6 +133,8 @@ static int cdn_dp_clk_enable(struct cdn_dp_device *dp)
return 0;
  
  err_set_rate:

+   pm_runtime_put(dp->dev);
+err_pm_runtime_get:
clk_disable_unprepare(dp->core_clk);
  err_core_clk:
clk_disable_unprepare(dp->pclk);



--
Mark Yao


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


[PATCH] drm/rockchip: vop: no need wait vblank on crtc enable

2017-02-20 Thread Mark Yao
Since atomic framework, crtc enable and disable are in pairs,
no need to wait vblank.

Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 36 -
 1 file changed, 36 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 76c79ac..8dab2af 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -900,42 +900,6 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
return;
}
 
-   /*
-* If dclk rate is zero, mean that scanout is stop,
-* we don't need wait any more.
-*/
-   if (clk_get_rate(vop->dclk)) {
-   /*
-* Rk3288 vop timing register is immediately, when configure
-* display timing on display time, may cause tearing.
-*
-* Vop standby will take effect at end of current frame,
-* if dsp hold valid irq happen, it means standby complete.
-*
-* mode set:
-*standby and wait complete --> |
-*  | display time
-*  |
-*  |---> dsp hold irq
-* configure display timing --> |
-* standby exit |
-*  | new frame start.
-*/
-
-   reinit_completion(&vop->dsp_hold_completion);
-   vop_dsp_hold_valid_irq_enable(vop);
-
-   spin_lock(&vop->reg_lock);
-
-   VOP_CTRL_SET(vop, standby, 1);
-
-   spin_unlock(&vop->reg_lock);
-
-   wait_for_completion(&vop->dsp_hold_completion);
-
-   vop_dsp_hold_valid_irq_disable(vop);
-   }
-
pin_pol = BIT(DCLK_INVERT);
pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ?
   0 : BIT(HSYNC_POSITIVE);
-- 
1.9.1


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


[PATCH 2/2] drm/rockchip: vop: verify pixelclock for hdmi and displayport

2017-02-20 Thread Mark Yao
Hdmi or DisplayPort request a accurate clock,
reject the display mode if clock is not good.

Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 7ec5d7f..a7c118e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -868,14 +868,24 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
 {
struct vop *vop = to_vop(crtc);
const struct vop_data *vop_data = vop->data;
+   struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
+   int clock;
 
if (mode->hdisplay > vop_data->max_output.width)
return false;
if (mode->vdisplay > vop_data->max_output.height)
return false;
 
-   adjusted_mode->clock =
-   clk_round_rate(vop->dclk, mode->clock * 1000) / 1000;
+   clock = clk_round_rate(vop->dclk, mode->clock * 1000) / 1000;
+   /*
+* Hdmi or DisplayPort request a Accurate clock.
+*/
+   if (s->output_type == DRM_MODE_CONNECTOR_HDMIA ||
+   s->output_type == DRM_MODE_CONNECTOR_DisplayPort)
+   if (clock != mode->clock)
+   return false;
+
+   adjusted_mode->clock = clock;
 
return true;
 }
-- 
1.9.1


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


[PATCH 1/2] drm/rockchip: vop: verify display mode with vop max_output

2017-02-20 Thread Mark Yao
Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  6 ++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |  7 +++
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 13 +
 3 files changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 8dab2af..7ec5d7f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -867,6 +867,12 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
struct drm_display_mode *adjusted_mode)
 {
struct vop *vop = to_vop(crtc);
+   const struct vop_data *vop_data = vop->data;
+
+   if (mode->hdisplay > vop_data->max_output.width)
+   return false;
+   if (mode->vdisplay > vop_data->max_output.height)
+   return false;
 
adjusted_mode->clock =
clk_round_rate(vop->dclk, mode->clock * 1000) / 1000;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 5a4faa85..de5a714 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -135,6 +135,11 @@ struct vop_win_data {
enum drm_plane_type type;
 };
 
+struct vop_rect {
+   int width;
+   int height;
+};
+
 struct vop_data {
const struct vop_reg_data *init_table;
unsigned int table_size;
@@ -142,6 +147,8 @@ struct vop_data {
const struct vop_intr *intr;
const struct vop_win_data *win;
unsigned int win_size;
+   struct vop_rect max_input;
+   struct vop_rect max_output;
 };
 
 /* interrupt define */
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c 
b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 91fbc7b..f4ffb677 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -132,6 +132,8 @@
 };
 
 static const struct vop_data rk3036_vop = {
+   .max_input = {1920, 1080},
+   .max_output = {1920, 1080},
.init_table = rk3036_vop_init_reg_table,
.table_size = ARRAY_SIZE(rk3036_vop_init_reg_table),
.ctrl = &rk3036_ctrl_data,
@@ -273,6 +275,13 @@
 };
 
 static const struct vop_data rk3288_vop = {
+   .max_input = {4096, 8192},
+   /*
+* TODO: rk3288 have two vop, big one support 3840x2160,
+* little one only support 2560x1600.
+* Now force use 3840x2160.
+*/
+   .max_output = {3840, 2160},
.init_table = rk3288_init_reg_table,
.table_size = ARRAY_SIZE(rk3288_init_reg_table),
.intr = &rk3288_vop_intr,
@@ -341,6 +350,8 @@
 };
 
 static const struct vop_data rk3399_vop_big = {
+   .max_input = {4096, 8192},
+   .max_output = {4096, 2160},
.init_table = rk3399_init_reg_table,
.table_size = ARRAY_SIZE(rk3399_init_reg_table),
.intr = &rk3399_vop_intr,
@@ -360,6 +371,8 @@
 };
 
 static const struct vop_data rk3399_vop_lit = {
+   .max_input = {4096, 8192},
+   .max_output = {2560, 1600},
.init_table = rk3399_init_reg_table,
.table_size = ARRAY_SIZE(rk3399_init_reg_table),
.intr = &rk3399_vop_intr,
-- 
1.9.1


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


[GIT PULL] drm/rockchip: some fixes

2017-02-21 Thread Mark yao

Hi Dave

Some fixes, looks good to me.

Best regards.

The following changes since commit 9ca70356a9260403c1bda40d942935e55d00c11c:

  Revert "drm: Resurrect atomic rmfb code, v3" (2017-02-17 12:39:04 +1000)

are available in the git repository at:

  https://github.com/markyzq/kernel-drm-rockchip.git 
drm-rockchip-next-2017-02-22


for you to fetch changes up to 3690629b844b961fc9dda98b0ffc16a6010a7f21:

  drm/rockchip: vop: verify pixelclock for hdmi and displayport 
(2017-02-22 08:44:22 +0800)



Arnd Bergmann (1):
  drm/rockchip: add extcon dependency for DP

Christophe Jaillet (1):
  drm/rockchip: cdn-dp: Fix error handling

Mark Yao (3):
  drm/rockchip: vop: no need wait vblank on crtc enable
  drm/rockchip: vop: verify display mode with vop max_output
  drm/rockchip: vop: verify pixelclock for hdmi and displayport

 drivers/gpu/drm/rockchip/Kconfig|  1 +
 drivers/gpu/drm/rockchip/cdn-dp-core.c  |  4 +++-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 56 
++--

 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |  7 +++
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 13 +
 5 files changed, 42 insertions(+), 39 deletions(-)

--
Mark Yao


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


Re: [GIT PULL] drm/rockchip: some fixes

2017-02-22 Thread Mark yao

On 2017年02月23日 00:09, Sean Paul wrote:

On Tue, Feb 21, 2017 at 7:54 PM, Mark yao  wrote:

Hi Dave

Some fixes, looks good to me.


Hi Mark,
As we discussed, rockchip patches should now go through -misc. Since
4.10 is already released, I'll push these through over there.

Sean


Hi Sean

Right, I had tried the -misc branch, but failed on some steps.  let us 
re-discussed how to use it.


and thanks for pushing these patches to -misc branch.

Best Regards.




Best regards.

The following changes since commit 9ca70356a9260403c1bda40d942935e55d00c11c:

   Revert "drm: Resurrect atomic rmfb code, v3" (2017-02-17 12:39:04 +1000)

are available in the git repository at:

   https://github.com/markyzq/kernel-drm-rockchip.git
drm-rockchip-next-2017-02-22

for you to fetch changes up to 3690629b844b961fc9dda98b0ffc16a6010a7f21:

   drm/rockchip: vop: verify pixelclock for hdmi and displayport (2017-02-22
08:44:22 +0800)


Arnd Bergmann (1):
   drm/rockchip: add extcon dependency for DP

Christophe Jaillet (1):
   drm/rockchip: cdn-dp: Fix error handling

Mark Yao (3):
   drm/rockchip: vop: no need wait vblank on crtc enable
   drm/rockchip: vop: verify display mode with vop max_output
   drm/rockchip: vop: verify pixelclock for hdmi and displayport

  drivers/gpu/drm/rockchip/Kconfig|  1 +
  drivers/gpu/drm/rockchip/cdn-dp-core.c  |  4 +++-
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 56
++--
  drivers/gpu/drm/rockchip/rockchip_drm_vop.h |  7 +++
  drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 13 +
  5 files changed, 42 insertions(+), 39 deletions(-)

--
Mark Yao


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






--
Mark Yao


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


Re: [GIT PULL] drm/rockchip: some fixes

2017-02-23 Thread Mark yao

On 2017年02月24日 02:01, Sean Paul wrote:

On Thu, Feb 23, 2017 at 10:03:23AM +0800, Mark yao wrote:

On 2017年02月23日 00:09, Sean Paul wrote:

On Tue, Feb 21, 2017 at 7:54 PM, Mark yao  wrote:

Hi Dave

Some fixes, looks good to me.


Hi Mark,
As we discussed, rockchip patches should now go through -misc. Since
4.10 is already released, I'll push these through over there.

Sean

Hi Sean

Right, I had tried the -misc branch, but failed on some steps.  let
us re-discussed how to use it.

and thanks for pushing these patches to -misc branch.

Best Regards.


Best regards.

The following changes since commit 9ca70356a9260403c1bda40d942935e55d00c11c:

   Revert "drm: Resurrect atomic rmfb code, v3" (2017-02-17 12:39:04 +1000)

are available in the git repository at:

   https://github.com/markyzq/kernel-drm-rockchip.git
drm-rockchip-next-2017-02-22

for you to fetch changes up to 3690629b844b961fc9dda98b0ffc16a6010a7f21:

   drm/rockchip: vop: verify pixelclock for hdmi and displayport (2017-02-22
08:44:22 +0800)


Arnd Bergmann (1):
   drm/rockchip: add extcon dependency for DP

Christophe Jaillet (1):
   drm/rockchip: cdn-dp: Fix error handling

Mark Yao (3):
   drm/rockchip: vop: no need wait vblank on crtc enable
   drm/rockchip: vop: verify display mode with vop max_output
   drm/rockchip: vop: verify pixelclock for hdmi and displayport

I don't think these 3 are fixes, per-se. So let's wait until drm-misc-next is
updated (these depend on Chris Zhong's cdn-dp patches) and merge them there.


Right, Thanks.



Sean



  drivers/gpu/drm/rockchip/Kconfig|  1 +
  drivers/gpu/drm/rockchip/cdn-dp-core.c  |  4 +++-
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 56
++--
  drivers/gpu/drm/rockchip/rockchip_drm_vop.h |  7 +++
  drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 13 +
  5 files changed, 42 insertions(+), 39 deletions(-)

--
Mark Yao


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




--
Mark Yao


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



--
Mark Yao


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


Re: [GIT PULL] drm/rockchip: convert to drm_mm

2017-02-26 Thread Mark yao

On 2017年02月27日 04:45, Daniel Vetter wrote:

On Thu, Feb 16, 2017 at 11:02:31AM +0800, Mark yao wrote:

Hi Dave

After convert to drm_mm, rockchip arm64 platform can works with iommu, like
rk3399. it's import patches for rockchip arm64 platform

And these patches already have full reviewed, I hope these patches can be
landed.
  
Best regards


The following changes since commit 13f62f54d174d3417c3caaafedf5e22a0a03e442:

   Merge branch 'drm-next-4.11' of git://people.freedesktop.org/~agd5f/linux
into drm-next (2017-02-10 10:13:30 +1000)

are available in the git repository at:


   https://github.com/markyzq/kernel-drm-rockchip.git
drm-rockchip-next-2017-02-16

for you to fetch changes up to 1aa5ca6e3ec63aa5815d78646748e88a7ceb1c8e:

   drm/rockchip: Use common IOMMU API to attach devices (2017-02-15 08:52:13
+0800)


Shunqian Zheng (1):
   drm/rockchip: Use common IOMMU API to attach devices

Tomasz Figa (1):
   drm/rockchip: Do not use DMA mapping API if attached to IOMMU domain

I thought we've moved rockchip into drm-misc ...?


Sorry, I'm not clear understand how the drm-misc maintain before, later 
patches would go through drm-misc



Can you and Sean Paul please talk and figure out how exactly you want to
maintain this driver?


Move drm/rockchip into drm-misc is good, Thanks Sean Paul's work.
I'm learning how to maintain drm/rockchip with drm-misc.

But I'm not understand drm-misc's step, I'm confused that:  do I need to 
pick up patches to drm-misc by myself?
or I just give a ACK on patches, and then Sean or other drm-misc's guys 
will pick patches up to drm-misc?


Thanks.

The current situation where we have stuff going in
independently through different maintainers is not great at all. If you
can't get agreement, we'll just make you agree by arbitrarily rolling the
dice or something silly like that :-)
-Daniel


--
Mark Yao


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


Re: [PATCH v4 00/23] drm/rockchip: MIPI fixes & improvements

2017-02-26 Thread Mark yao

On 2017年02月24日 20:54, John Keeping wrote:

This version is mostly small changes in response to review comments from
Sean and Chris, the details are in the individual patches.

I decided to drop the final patch which adds support for MIPI read
commands because I'm not using that feature now and I can't easily test
it.  It's on the list if anyone wants to pick it up in the future.

Version 3 was posted here:
http://www.spinics.net/lists/dri-devel/msg130977.html

Thanks to Sean Paul and Chris Zhong for their review and testing of this
series.


Looks good to me.

Acked-by: Mark Yao 



John Keeping (23):
   drm/rockchip: dw-mipi-dsi: don't configure hardware in mode_set for
 MIPI
   drm/rockchip: dw-mipi-dsi: pass mode in where needed
   drm/rockchip: dw-mipi-dsi: remove mode_set hook
   drm/rockchip: dw-mipi-dsi: fix command header writes
   drm/rockchip: dw-mipi-dsi: fix generic packet status check
   drm/rockchip: dw-mipi-dsi: avoid out-of-bounds read on tx_buf
   drm/rockchip: dw-mipi-dsi: include bad value in error message
   drm/rockchip: dw-mipi-dsi: respect message flags
   drm/rockchip: dw-mipi-dsi: only request HS clock when required
   drm/rockchip: dw-mipi-dsi: don't assume buffer is aligned
   drm/rockchip: dw-mipi-dsi: prepare panel after phy init
   drm/rockchip: dw-mipi-dsi: allow commands in panel_disable
   drm/rockchip: dw-mipi-dsi: fix escape clock rate
   drm/rockchip: dw-mipi-dsi: ensure PHY is reset
   drm/rockchip: dw-mipi-dsi: configure PHY before enabling
   drm/rockchip: dw-mipi-dsi: properly configure PHY timing
   drm/rockchip: dw-mipi-dsi: improve PLL configuration
   drm/rockchip: dw-mipi-dsi: use specific poll helper
   drm/rockchip: dw-mipi-dsi: use positive check for N{H,V}SYNC
   drm/rockchip: vop: test for P{H,V}SYNC
   drm/rockchip: dw-mipi-dsi: defer probe if panel is not loaded
   drm/rockchip: dw-mipi-dsi: support non-burst modes
   drm/rockchip: dw-mipi-dsi: add reset control

  drivers/gpu/drm/rockchip/dw-mipi-dsi.c  | 325 +++-
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   4 +-
  2 files changed, 220 insertions(+), 109 deletions(-)




--
Mark Yao


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


Re: [RFC][PATCH 1/2] drm/probe-helper: Add mode_valid check to drm_crtc_helper_funcs

2017-02-28 Thread Mark yao

  
  
On 2017年02月15日 04:32, Daniel Stone
  wrote:


  Hi John,

On 14 February 2017 at 19:25, John Stultz  wrote:

  
+static enum drm_mode_status
+drm_connector_check_crtc_modes(struct drm_connector *connector,
+  struct drm_display_mode *mode)
+{
+   struct drm_device *dev = connector->dev;
+   const struct drm_crtc_helper_funcs *crtc_funcs;
+   struct drm_crtc *c;
+
+   if (mode->status != MODE_OK)
+   return mode->status;
+
+   /* Check all the crtcs on a connector to make sure the mode is valid */
+   drm_for_each_crtc(c, dev) {
+   crtc_funcs = c->helper_private;
+   if (crtc_funcs && crtc_funcs->mode_valid)
+   mode->status = crtc_funcs->mode_valid(c, mode);
+   if (mode->status != MODE_OK)
+   break;
+   }
+   return mode->status;
+}

  
  
Hm, that's unfortunate: it limits the mode list for every connector,
to those which are supported by every single CRTC. So if you have one
CRTC serving low-res LVDS, and another serving higher-res HDMI,
suddenly you can't get bigger modes on HDMI. The idea seems sound
enough, but a little more nuance might be good ...


John, I have same requirement, also want to valid mode with crtc,
here is my patch[0], use encoder->possible_crtcs to limit the
crtc valid, may be can solved the low-res and high-res problem.


[0]: https://patchwork.kernel.org/patch/9555945


    /*
 * ensure all drm display mode can work, if someone want support
more
 * resolutions, please limit the possible_crtc, only connect to
 * needed crtc.
 */
    drm_for_each_crtc(crtc, connector->dev) {
    [...]
        if (!(encoder->possible_crtcs & drm_crtc_mask(crtc)))



  

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




-- 
Mark Yao
  


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


[PATCH] drm/rockchip: return ERR_PTR instead of NULL

2016-11-11 Thread Mark yao
On 2016年11月11日 05:10, Julia Lawall wrote:
> rockchip_drm_framebuffer_init is only used in one case, in
> rockchip_drm_fbdev.c, where its return value is tested using IS_ERR.  To
> enable propagating the reason for the error, change the definition so that
> it returns an ERR_PTR value.
>
> Problem found with the help of Coccinelle.
>
> Signed-off-by: Julia Lawall 
Thanks for the fix.

Applied to my drm-next.

>
> ---
>   drivers/gpu/drm/rockchip/rockchip_drm_fb.c |2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c 
> b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> index 0f6eda0..01e11bf 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> @@ -213,7 +213,7 @@ struct drm_framebuffer *
>   
>   rockchip_fb = rockchip_fb_alloc(dev, mode_cmd, &obj, 1);
>   if (IS_ERR(rockchip_fb))
> - return NULL;
> + return ERR_CAST(rockchip_fb);
>   
>   return &rockchip_fb->fb;
>   }
>
>
>
>


-- 
ï¼­ark Yao




[PATCH v3 2/3] drm/rockchip: dw_hdmi: introduce the VPLL clock setting

2017-06-09 Thread Mark Yao
For RK3399 HDMI, there is an external clock need for HDMI PHY,
and it should keep the same clock rate with VOP DCLK.

VPLL have supported the clock for HDMI PHY, but there is no
clock divider bewteen VPLL and HDMI PHY. So we need to set the
VPLL rate manually in HDMI driver.

Signed-off-by: Yakir Yang 
Signed-off-by: Mark Yao 
---
Changes in v3: none
Changes in v2: describe vpll on Documentation.

 .../bindings/display/rockchip/dw_hdmi-rockchip.txt |  2 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c| 25 +-
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
index 495bcf5..779e8ac 100644
--- a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
+++ b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
@@ -31,7 +31,7 @@ Optional properties
   I2C master controller.
 - clock-names: See dw_hdmi.txt. The "cec" clock is optional.
 - clock-names: May contain "cec" as defined in dw_hdmi.txt.
-
+- clock-names: May contain "vpll", external clock for some hdmi phy.
 
 Example:
 
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 90aaaf4..aaa0f3e 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -7,10 +7,12 @@
  * (at your option) any later version.
  */
 
+#include 
+#include 
 #include 
 #include 
-#include 
 #include 
+
 #include 
 #include 
 #include 
@@ -44,6 +46,7 @@ struct rockchip_hdmi {
struct regmap *regmap;
struct drm_encoder encoder;
const struct rockchip_hdmi_chip_data *chip_data;
+   struct clk *vpll_clk;
 };
 
 #define to_rockchip_hdmi(x)container_of(x, struct rockchip_hdmi, x)
@@ -160,6 +163,7 @@ struct rockchip_hdmi {
 static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
 {
struct device_node *np = hdmi->dev->of_node;
+   int ret;
 
hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
if (IS_ERR(hdmi->regmap)) {
@@ -167,6 +171,22 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi 
*hdmi)
return PTR_ERR(hdmi->regmap);
}
 
+   hdmi->vpll_clk = devm_clk_get(hdmi->dev, "vpll");
+   if (PTR_ERR(hdmi->vpll_clk) == -ENOENT) {
+   hdmi->vpll_clk = NULL;
+   } else if (PTR_ERR(hdmi->vpll_clk) == -EPROBE_DEFER) {
+   return -EPROBE_DEFER;
+   } else if (IS_ERR(hdmi->vpll_clk)) {
+   dev_err(hdmi->dev, "failed to get grf clock\n");
+   return PTR_ERR(hdmi->vpll_clk);
+   }
+
+   ret = clk_prepare_enable(hdmi->vpll_clk);
+   if (ret) {
+   dev_err(hdmi->dev, "Failed to enable HDMI vpll: %d\n", ret);
+   return ret;
+   }
+
return 0;
 }
 
@@ -209,6 +229,9 @@ static void dw_hdmi_rockchip_encoder_mode_set(struct 
drm_encoder *encoder,
  struct drm_display_mode *mode,
  struct drm_display_mode *adj_mode)
 {
+   struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
+
+   clk_set_rate(hdmi->vpll_clk, adj_mode->clock * 1000);
 }
 
 static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
-- 
1.9.1


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


[PATCH v3 0/3] Add RK3399 HDMI Support

2017-06-09 Thread Mark Yao
RK3399 and RK3288 shared the same HDMI IP controller, only some
light difference with GRF configure, and an external VPLL clock
need to configure.

base on Yakir's v1 thread:
   http://lkml.iu.edu/hypermail/linux/kernel/1607.1/01468.html

rely on Jose's hdmi phy patch:
   https://patchwork.kernel.org/patch/9702229

Some Yakir's hdmi patches cause hdmi no display on my test,
so I remove them on this thread.

Tested on rk3399 evb board with kernel 4.12.0-rc1.

Changes in v3:
  remove hdmi_phy_configure_dwc_hdmi_3d_tx callbak.

Changes in v2:
  rebase to newest uptream, reuse hdmi_phy_configure_dwc_hdmi_3d_tx

Mark Yao (3):
  drm/rockchip: dw_hdmi: add RK3399 HDMI support
  drm/rockchip: dw_hdmi: introduce the VPLL clock setting
  drm/rockchip: dw_hdmi: introduce the pclk for grf

 .../bindings/display/rockchip/dw_hdmi-rockchip.txt |   6 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c| 110 ++---
 2 files changed, 102 insertions(+), 14 deletions(-)

-- 
1.9.1


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


[PATCH v3 1/3] drm/rockchip: dw_hdmi: add RK3399 HDMI support

2017-06-09 Thread Mark Yao
RK3399 and RK3288 shared the same HDMI IP controller, only some light
difference with GRF configure.

Signed-off-by: Yakir Yang 
Signed-off-by: Mark Yao 
---
Changes in v3:
  remove hdmi_phy_configure_dwc_hdmi_3d_tx callbak.

Changes in v2:
  reuse hdmi_phy_configure_dwc_hdmi_3d_tx for phy configure
  fixup Documentation

 .../bindings/display/rockchip/dw_hdmi-rockchip.txt |  3 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c| 67 ++
 2 files changed, 58 insertions(+), 12 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
index 046076c..495bcf5 100644
--- a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
+++ b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
@@ -11,7 +11,8 @@ following device-specific properties.
 
 Required properties:
 
-- compatible: Shall contain "rockchip,rk3288-dw-hdmi".
+- compatible: "rockchip,rk3288-dw-hdmi",
+  "rockchip,rk3399-dw-hdmi";
 - reg: See dw_hdmi.txt.
 - reg-io-width: See dw_hdmi.txt. Shall be 4.
 - interrupts: HDMI interrupt number
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 63dab6f..90aaaf4 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -20,13 +20,30 @@
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
 
-#define GRF_SOC_CON60x025c
-#define HDMI_SEL_VOP_LIT(1 << 4)
+#define RK3288_GRF_SOC_CON60x025C
+#define RK3288_HDMI_LCDC_SEL   BIT(4)
+#define RK3399_GRF_SOC_CON20   0x6250
+#define RK3399_HDMI_LCDC_SEL   BIT(6)
+
+#define HIWORD_UPDATE(val, mask)   (val | (mask) << 16)
+
+/**
+ * struct rockchip_hdmi_chip_data - splite the grf setting of kind of chips
+ * @lcdsel_grf_reg: grf register offset of lcdc select
+ * @lcdsel_big: reg value of selecting vop big for HDMI
+ * @lcdsel_lit: reg value of selecting vop little for HDMI
+ */
+struct rockchip_hdmi_chip_data {
+   u32 lcdsel_grf_reg;
+   u32 lcdsel_big;
+   u32 lcdsel_lit;
+};
 
 struct rockchip_hdmi {
struct device *dev;
struct regmap *regmap;
struct drm_encoder encoder;
+   const struct rockchip_hdmi_chip_data *chip_data;
 };
 
 #define to_rockchip_hdmi(x)container_of(x, struct rockchip_hdmi, x)
@@ -198,17 +215,20 @@ static void dw_hdmi_rockchip_encoder_enable(struct 
drm_encoder *encoder)
 {
struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
u32 val;
-   int mux;
+   int ret;
 
-   mux = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder);
-   if (mux)
-   val = HDMI_SEL_VOP_LIT | (HDMI_SEL_VOP_LIT << 16);
+   ret = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder);
+   if (ret)
+   val = hdmi->chip_data->lcdsel_lit;
else
-   val = HDMI_SEL_VOP_LIT << 16;
+   val = hdmi->chip_data->lcdsel_big;
+
+   ret = regmap_write(hdmi->regmap, hdmi->chip_data->lcdsel_grf_reg, val);
+   if (ret != 0)
+   dev_err(hdmi->dev, "Could not write to GRF: %d\n", ret);
 
-   regmap_write(hdmi->regmap, GRF_SOC_CON6, val);
dev_dbg(hdmi->dev, "vop %s output to hdmi\n",
-   (mux) ? "LIT" : "BIG");
+   ret ? "LIT" : "BIG");
 }
 
 static int
@@ -232,16 +252,40 @@ static void dw_hdmi_rockchip_encoder_enable(struct 
drm_encoder *encoder)
.atomic_check = dw_hdmi_rockchip_encoder_atomic_check,
 };
 
-static const struct dw_hdmi_plat_data rockchip_hdmi_drv_data = {
+static struct rockchip_hdmi_chip_data rk3288_chip_data = {
+   .lcdsel_grf_reg = RK3288_GRF_SOC_CON6,
+   .lcdsel_big = HIWORD_UPDATE(0, RK3288_HDMI_LCDC_SEL),
+   .lcdsel_lit = HIWORD_UPDATE(RK3288_HDMI_LCDC_SEL, RK3288_HDMI_LCDC_SEL),
+};
+
+static const struct dw_hdmi_plat_data rk3288_hdmi_drv_data = {
+   .mode_valid = dw_hdmi_rockchip_mode_valid,
+   .mpll_cfg   = rockchip_mpll_cfg,
+   .cur_ctr= rockchip_cur_ctr,
+   .phy_config = rockchip_phy_config,
+   .phy_data = &rk3288_chip_data,
+};
+
+static struct rockchip_hdmi_chip_data rk3399_chip_data = {
+   .lcdsel_grf_reg = RK3399_GRF_SOC_CON20,
+   .lcdsel_big = HIWORD_UPDATE(0, RK3399_HDMI_LCDC_SEL),
+   .lcdsel_lit = HIWORD_UPDATE(RK3399_HDMI_LCDC_SEL, RK3399_HDMI_LCDC_SEL),
+};
+
+static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = {
.mode_valid = dw_hdmi_rockchip_mode_valid,
.mpll_cfg   = rockchip_mpll_cfg,
.cur_ctr= rockchip_cur_ctr,
.phy_config = rockchip_phy_config,
+   .phy_data = &

[PATCH v3 3/3] drm/rockchip: dw_hdmi: introduce the pclk for grf

2017-06-09 Thread Mark Yao
For RK3399's GRF module, if we want to operate the graphic related grf
registers, we need to enable the pclk_vio_grf which supply power for VIO
GRF IOs, so it's better to introduce an optional grf clock in driver.

Signed-off-by: Yakir Yang 
Signed-off-by: Mark Yao 
---
Changes in v3: none
Changes in v2: describe grf on Documentation.

 .../bindings/display/rockchip/dw_hdmi-rockchip.txt |  1 +
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c| 18 ++
 2 files changed, 19 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
index 779e8ac..6bce639 100644
--- a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
+++ b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
@@ -31,6 +31,7 @@ Optional properties
   I2C master controller.
 - clock-names: See dw_hdmi.txt. The "cec" clock is optional.
 - clock-names: May contain "cec" as defined in dw_hdmi.txt.
+- clock-names: May contain "grf", power for grf io.
 - clock-names: May contain "vpll", external clock for some hdmi phy.
 
 Example:
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index aaa0f3e..2b9cb47 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -47,6 +47,7 @@ struct rockchip_hdmi {
struct drm_encoder encoder;
const struct rockchip_hdmi_chip_data *chip_data;
struct clk *vpll_clk;
+   struct clk *grf_clk;
 };
 
 #define to_rockchip_hdmi(x)container_of(x, struct rockchip_hdmi, x)
@@ -181,6 +182,16 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi 
*hdmi)
return PTR_ERR(hdmi->vpll_clk);
}
 
+   hdmi->grf_clk = devm_clk_get(hdmi->dev, "grf");
+   if (PTR_ERR(hdmi->grf_clk) == -ENOENT) {
+   hdmi->grf_clk = NULL;
+   } else if (PTR_ERR(hdmi->grf_clk) == -EPROBE_DEFER) {
+   return -EPROBE_DEFER;
+   } else if (IS_ERR(hdmi->grf_clk)) {
+   dev_err(hdmi->dev, "failed to get grf clock\n");
+   return PTR_ERR(hdmi->grf_clk);
+   }
+
ret = clk_prepare_enable(hdmi->vpll_clk);
if (ret) {
dev_err(hdmi->dev, "Failed to enable HDMI vpll: %d\n", ret);
@@ -246,10 +257,17 @@ static void dw_hdmi_rockchip_encoder_enable(struct 
drm_encoder *encoder)
else
val = hdmi->chip_data->lcdsel_big;
 
+   ret = clk_prepare_enable(hdmi->grf_clk);
+   if (ret < 0) {
+   dev_err(hdmi->dev, "failed to enable grfclk %d\n", ret);
+   return;
+   }
+
ret = regmap_write(hdmi->regmap, hdmi->chip_data->lcdsel_grf_reg, val);
if (ret != 0)
dev_err(hdmi->dev, "Could not write to GRF: %d\n", ret);
 
+   clk_disable_unprepare(hdmi->grf_clk);
dev_dbg(hdmi->dev, "vop %s output to hdmi\n",
ret ? "LIT" : "BIG");
 }
-- 
1.9.1


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


Re: [PATCH 1/2] drm/rockchip: add const to drm_encoder_helper_funcs structures

2017-06-20 Thread Mark yao

On 2017年06月20日 21:07, Bhumika Goyal wrote:

Add const to drm_encoder_helper_funcs structures as they are only passed
as an argument to the function drm_encoder_helper_add and this argument
is of type const. So, add const to these structures. Also, fix line over
80 characters warning while adding const.

Signed-off-by: Bhumika Goyal 
---
  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 3 ++-
  drivers/gpu/drm/rockchip/inno_hdmi.c| 2 +-
  2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 9606121..96c6c10 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -252,7 +252,8 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder 
*encoder,
return 0;
  }
  
-static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = {

+static
+const struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = {


I don't think split static and const into two line is a good idea, it's 
ugly. I'm ok over 80 characters with good-looking.

Or split like following:
static const struct drm_encoder_helper_funcs
rockchip_dp_encoder_helper_funcs = {


.mode_fixup = rockchip_dp_drm_encoder_mode_fixup,
.mode_set = rockchip_dp_drm_encoder_mode_set,
.enable = rockchip_dp_drm_encoder_enable,
diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 7d9b75e..4ab9fad 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -530,7 +530,7 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
return 0;
  }
  
-static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {

+static const struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
.enable = inno_hdmi_encoder_enable,
.disable= inno_hdmi_encoder_disable,
.mode_fixup = inno_hdmi_encoder_mode_fixup,


Thanks

--
Mark Yao


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


Re: [PATCH v2 1/2] drm/rockchip: add const to drm_encoder_helper_funcs structures

2017-06-20 Thread Mark yao

On 2017年06月21日 14:31, Bhumika Goyal wrote:

Add const to drm_encoder_helper_funcs structures as they are only passed
as an argument to the function drm_encoder_helper_add and this argument
is of type const. So, add const to these structures.

Signed-off-by: Bhumika Goyal
---
Changes in v2 -
* Let the line exceed over 80 characters while adding const.


Acked-by: Mark Yao 

Thanks

--
Mark Yao


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


[PATCH v3.1 1/3] drm/rockchip: dw_hdmi: add RK3399 HDMI support

2017-06-22 Thread Mark Yao
RK3399 and RK3288 shared the same HDMI IP controller, only some light
difference with GRF configure.

Signed-off-by: Yakir Yang 
Signed-off-by: Mark Yao 
---
Changes in v3.1:
  Correct documentation compatible's format(Rob Herring).
Changes in v3:
  remove hdmi_phy_configure_dwc_hdmi_3d_tx callbak.

Changes in v2:
  reuse hdmi_phy_configure_dwc_hdmi_3d_tx for phy configure
  fixup Documentation

 .../bindings/display/rockchip/dw_hdmi-rockchip.txt |  4 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c| 67 ++
 2 files changed, 59 insertions(+), 12 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
index 046076c..7039a15 100644
--- a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
+++ b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
@@ -11,7 +11,9 @@ following device-specific properties.
 
 Required properties:
 
-- compatible: Shall contain "rockchip,rk3288-dw-hdmi".
+- compatible: should be one of the following:
+   "rockchip,rk3288-dw-hdmi"
+   "rockchip,rk3399-dw-hdmi"
 - reg: See dw_hdmi.txt.
 - reg-io-width: See dw_hdmi.txt. Shall be 4.
 - interrupts: HDMI interrupt number
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 63dab6f..90aaaf4 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -20,13 +20,30 @@
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
 
-#define GRF_SOC_CON60x025c
-#define HDMI_SEL_VOP_LIT(1 << 4)
+#define RK3288_GRF_SOC_CON60x025C
+#define RK3288_HDMI_LCDC_SEL   BIT(4)
+#define RK3399_GRF_SOC_CON20   0x6250
+#define RK3399_HDMI_LCDC_SEL   BIT(6)
+
+#define HIWORD_UPDATE(val, mask)   (val | (mask) << 16)
+
+/**
+ * struct rockchip_hdmi_chip_data - splite the grf setting of kind of chips
+ * @lcdsel_grf_reg: grf register offset of lcdc select
+ * @lcdsel_big: reg value of selecting vop big for HDMI
+ * @lcdsel_lit: reg value of selecting vop little for HDMI
+ */
+struct rockchip_hdmi_chip_data {
+   u32 lcdsel_grf_reg;
+   u32 lcdsel_big;
+   u32 lcdsel_lit;
+};
 
 struct rockchip_hdmi {
struct device *dev;
struct regmap *regmap;
struct drm_encoder encoder;
+   const struct rockchip_hdmi_chip_data *chip_data;
 };
 
 #define to_rockchip_hdmi(x)container_of(x, struct rockchip_hdmi, x)
@@ -198,17 +215,20 @@ static void dw_hdmi_rockchip_encoder_enable(struct 
drm_encoder *encoder)
 {
struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
u32 val;
-   int mux;
+   int ret;
 
-   mux = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder);
-   if (mux)
-   val = HDMI_SEL_VOP_LIT | (HDMI_SEL_VOP_LIT << 16);
+   ret = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder);
+   if (ret)
+   val = hdmi->chip_data->lcdsel_lit;
else
-   val = HDMI_SEL_VOP_LIT << 16;
+   val = hdmi->chip_data->lcdsel_big;
+
+   ret = regmap_write(hdmi->regmap, hdmi->chip_data->lcdsel_grf_reg, val);
+   if (ret != 0)
+   dev_err(hdmi->dev, "Could not write to GRF: %d\n", ret);
 
-   regmap_write(hdmi->regmap, GRF_SOC_CON6, val);
dev_dbg(hdmi->dev, "vop %s output to hdmi\n",
-   (mux) ? "LIT" : "BIG");
+   ret ? "LIT" : "BIG");
 }
 
 static int
@@ -232,16 +252,40 @@ static void dw_hdmi_rockchip_encoder_enable(struct 
drm_encoder *encoder)
.atomic_check = dw_hdmi_rockchip_encoder_atomic_check,
 };
 
-static const struct dw_hdmi_plat_data rockchip_hdmi_drv_data = {
+static struct rockchip_hdmi_chip_data rk3288_chip_data = {
+   .lcdsel_grf_reg = RK3288_GRF_SOC_CON6,
+   .lcdsel_big = HIWORD_UPDATE(0, RK3288_HDMI_LCDC_SEL),
+   .lcdsel_lit = HIWORD_UPDATE(RK3288_HDMI_LCDC_SEL, RK3288_HDMI_LCDC_SEL),
+};
+
+static const struct dw_hdmi_plat_data rk3288_hdmi_drv_data = {
+   .mode_valid = dw_hdmi_rockchip_mode_valid,
+   .mpll_cfg   = rockchip_mpll_cfg,
+   .cur_ctr= rockchip_cur_ctr,
+   .phy_config = rockchip_phy_config,
+   .phy_data = &rk3288_chip_data,
+};
+
+static struct rockchip_hdmi_chip_data rk3399_chip_data = {
+   .lcdsel_grf_reg = RK3399_GRF_SOC_CON20,
+   .lcdsel_big = HIWORD_UPDATE(0, RK3399_HDMI_LCDC_SEL),
+   .lcdsel_lit = HIWORD_UPDATE(RK3399_HDMI_LCDC_SEL, RK3399_HDMI_LCDC_SEL),
+};
+
+static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = {
.mode_valid = dw_hdmi_rockchip_mode_valid,
.mpll_cfg

Re: [PATCH v3.1 1/3] drm/rockchip: dw_hdmi: add RK3399 HDMI support

2017-06-22 Thread Mark yao

On 2017年06月22日 15:31, Heiko Stuebner wrote:

+
>+/**
>+ * struct rockchip_hdmi_chip_data - splite the grf setting of kind of chips
>+ * @lcdsel_grf_reg: grf register offset of lcdc select
>+ * @lcdsel_big: reg value of selecting vop big for HDMI
>+ * @lcdsel_lit: reg value of selecting vop little for HDMI
>+ */
>+struct rockchip_hdmi_chip_data {
>+   u32 lcdsel_grf_reg;

How do you plan on handling the rk3368 (with only one VOP and thus
no selection happening)? I'd just make the above an int, so we could
set it to -1 for that case. (value 0 is after all a valid reg).


It's a problem handling on rk3368, using -1 to judge means that we need
initial the lcdsel_grf_reg to -1 on rk3368 platform, we need always add a 
platform
data to handle it, seems not good enough.

Since the hdmi chip data only use for vop selection, maybe we can judge with
checking hdmi->chip_data == NULL for the case.

Mark.



Heiko




--
Mark Yao


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


Re: [PATCH] drm: bridge: synopsys/dw-hdmi: Provide default configuration function for HDMI 2.0 PHY

2017-06-22 Thread Mark yao

Hi Jose

Sorry miss your email and Sorry for the late reply

I can sure that your patch works on our rk3399 platform.

my internal kernel already has similar patch, using 
hdmi_phy_configure_dwc_hdmi_3d_tx() for hdmi 2.0 phy,
good works with many video modes (4k, 1080p, 720p etc.), I'm not familiar with 
hdmi,  but hdmi display actually works for us.

And, I had tried the 4.12-rc1 kernel with your patch, display works good.

So:
Tested-by: Mark Yao 

On 2017年06月13日 22:11, Jose Abreu wrote:

Hi Laurent,


Sorry for the late reply!


On 10-06-2017 09:50, Laurent Pinchart wrote:

Hi Jose,

On Friday 09 Jun 2017 13:53:12 Jose Abreu wrote:

On 09-06-2017 12:04, Jose Abreu wrote:

Currently HDMI 2.0 PHYs do not have a default configuration function.

As these PHYs have the same register layout as the 3D PHYs we can
safely use the default configuration function.

I may have been a little to fast arriving at this conclusion. I
mean most of the registers match but in the configuration
function there are registers that do not match. Did you actually
test this configuration function with an HDMI 2.0 phy? And did
you test with different video modes? From my experience the phy
may be wrongly configured and sometimes work anyway.

Do please retest with as many video modes as you can and give me
your phy ID (read from controller config reg HDMI_CONFIG2_ID).

The Renesas R-Car Gen3 HDMI PHY reports an DWC HDMI 2.0 TX PHY ID, but has a
configuration function (rcar_hdmi_phy_configure() in drivers/gpu/drm/rcar-
du/rcar_dw_hdmi.c) that doesn't match hdmi_phy_configure_dwc_hdmi_3d_tx().
 From the information I have been given the layout of the configuration
registers haven't been changed by Renesas. I know we've briefly discussed this
in the past, but I'd appreciate if you could have a second look and tell me
what you think.

Yup, yours seems correct. Though at the time you submitted I
found it odd that only 3 registers needed to be written whilst
for HDMI 2.0 phys I have here 6 registers, but you said it is
working so I though your phy was different ...

Even so, one thing I would like to know is what was the max
resolution you tested? I see you have clock values up to 297MHz,
so 4k@30Hz? If I send a patch with a general config function for
HDMI 2.0 phys can you test it on your platform?

Best regards,
Jose Miguel Abreu


  If, for some reason,

the PHY is custom this change will not make any impact because
in configuration function we prefer the pdata provided configuration
function over the internal one.

This patch is based on today's drm-misc-next branch.

Signed-off-by: Jose Abreu 
Cc: Kieran Bingham 
Cc: Laurent Pinchart 
Cc: Archit Taneja 
Cc: Andrzej Hajda 
Cc: Mark Yao 
Cc: Carlos Palminha 
---

  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index ead1124..10c8d8c 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2170,6 +2170,7 @@ static irqreturn_t dw_hdmi_irq(int irq, void
*dev_id)
.name = "DWC HDMI 2.0 TX PHY",
.gen = 2,
.has_svsret = true,
+   .configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
}, {
.type = DW_HDMI_PHY_VENDOR_PHY,
.name = "Vendor PHY",







--
Mark Yao


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


Re: [PATCH v3 0/3] Add RK3399 HDMI Support

2017-06-22 Thread Mark yao

Thanks for Heiko's review and Rob's Ack.

Seems no more confuse, pushed to drm-misc-next.

Thanks.

On 2017年06月09日 15:10, Mark Yao wrote:

RK3399 and RK3288 shared the same HDMI IP controller, only some
light difference with GRF configure, and an external VPLL clock
need to configure.

base on Yakir's v1 thread:
http://lkml.iu.edu/hypermail/linux/kernel/1607.1/01468.html

rely on Jose's hdmi phy patch:
https://patchwork.kernel.org/patch/9702229

Some Yakir's hdmi patches cause hdmi no display on my test,
so I remove them on this thread.

Tested on rk3399 evb board with kernel 4.12.0-rc1.

Changes in v3:
   remove hdmi_phy_configure_dwc_hdmi_3d_tx callbak.

Changes in v2:
   rebase to newest uptream, reuse hdmi_phy_configure_dwc_hdmi_3d_tx

Mark Yao (3):
   drm/rockchip: dw_hdmi: add RK3399 HDMI support
   drm/rockchip: dw_hdmi: introduce the VPLL clock setting
   drm/rockchip: dw_hdmi: introduce the pclk for grf

  .../bindings/display/rockchip/dw_hdmi-rockchip.txt |   6 +-
  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c| 110 ++---
  2 files changed, 102 insertions(+), 14 deletions(-)




--
Mark Yao


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


Re: [PATCH] drm/rockchip: fix NULL check on devm_kzalloc() return value

2017-07-06 Thread Mark yao

On 2017年07月07日 05:58, Gustavo A. R. Silva wrote:

The right variable to check here is port, not dp.

This issue was detected using Coccinelle and the following semantic patch:

@@
expression x;
identifier fld;
@@

* x = devm_kzalloc(...);
   ... when != x == NULL
   x->fld

Signed-off-by: Gustavo A. R. Silva 


Thanks for the fix,

Acked-by: Mark Yao 


---
  drivers/gpu/drm/rockchip/cdn-dp-core.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 14fa1f8..9b0b058 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -1195,7 +1195,7 @@ static int cdn_dp_probe(struct platform_device *pdev)
continue;
  
  		port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);

-   if (!dp)
+   if (!port)
return -ENOMEM;
  
  		port->extcon = extcon;



--
Mark Yao


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


Re: [PATCH] drm/rockchip: fix NULL check on devm_kzalloc() return value

2017-07-10 Thread Mark yao

On 2017年07月11日 03:04, Sean Paul wrote:

On Fri, Jul 07, 2017 at 08:56:28AM +0800, Mark yao wrote:

On 2017年07月07日 05:58, Gustavo A. R. Silva wrote:

The right variable to check here is port, not dp.

This issue was detected using Coccinelle and the following semantic patch:

@@
expression x;
identifier fld;
@@

* x = devm_kzalloc(...);
... when != x == NULL
x->fld

Signed-off-by: Gustavo A. R. Silva 

Thanks for the fix,

Acked-by: Mark Yao 

Hi Mark,
I've applied this patch, but in the future, please apply changes directly
instead of just acking.

If you're unable to apply it for some reason (vacation, etc), please reach out 
to
one of the -misc maintainers via email or irc so we don't inadvertently lose 
track
of it on the list.

Sean

Hi Sean

Got it,  I  will do it right next time.
Thanks to inform me this,




---
   drivers/gpu/drm/rockchip/cdn-dp-core.c | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 14fa1f8..9b0b058 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -1195,7 +1195,7 @@ static int cdn_dp_probe(struct platform_device *pdev)
continue;
port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
-   if (!dp)
+   if (!port)
return -ENOMEM;
port->extcon = extcon;


--
Mark Yao


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



--
Mark Yao


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


[PATCH 1/5] drm/rockchip: vop: get rid of register init table

2017-07-11 Thread Mark Yao
Register init table use un-document define, it is unreadable,
And sometimes we only want to update tiny bits, init table
method is not friendly, it's diffcult to reuse for difference
chips.

Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  6 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 10 ++-
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 43 +++--
 3 files changed, 10 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 45589d6..7a5f809 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1393,7 +1393,6 @@ static void vop_destroy_crtc(struct vop *vop)
 static int vop_initial(struct vop *vop)
 {
const struct vop_data *vop_data = vop->data;
-   const struct vop_reg_data *init_table = vop_data->init_table;
struct reset_control *ahb_rst;
int i, ret;
 
@@ -1453,13 +1452,14 @@ static int vop_initial(struct vop *vop)
 
memcpy(vop->regsbak, vop->regs, vop->len);
 
-   for (i = 0; i < vop_data->table_size; i++)
-   vop_writel(vop, init_table[i].offset, init_table[i].value);
+   VOP_CTRL_SET(vop, global_regdone_en, 1);
+   VOP_CTRL_SET(vop, dsp_blank, 0);
 
for (i = 0; i < vop_data->win_size; i++) {
const struct vop_win_data *win = &vop_data->win[i];
 
VOP_WIN_SET(vop, win, enable, 0);
+   VOP_WIN_SET(vop, win, gate, 1);
}
 
vop_cfg_done(vop);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 9979fd0..084d3b2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -24,11 +24,6 @@ enum vop_data_format {
VOP_FMT_YUV444SP,
 };
 
-struct vop_reg_data {
-   uint32_t offset;
-   uint32_t value;
-};
-
 struct vop_reg {
uint32_t offset;
uint32_t shift;
@@ -46,6 +41,7 @@ struct vop_ctrl {
struct vop_reg hdmi_en;
struct vop_reg mipi_en;
struct vop_reg dp_en;
+   struct vop_reg dsp_blank;
struct vop_reg out_mode;
struct vop_reg dither_down;
struct vop_reg dither_up;
@@ -65,6 +61,7 @@ struct vop_ctrl {
 
struct vop_reg line_flag_num[2];
 
+   struct vop_reg global_regdone_en;
struct vop_reg cfg_done;
 };
 
@@ -115,6 +112,7 @@ struct vop_win_phy {
uint32_t nformats;
 
struct vop_reg enable;
+   struct vop_reg gate;
struct vop_reg format;
struct vop_reg rb_swap;
struct vop_reg act_info;
@@ -136,8 +134,6 @@ struct vop_win_data {
 };
 
 struct vop_data {
-   const struct vop_reg_data *init_table;
-   unsigned int table_size;
const struct vop_ctrl *ctrl;
const struct vop_intr *intr;
const struct vop_win_data *win;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c 
b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index bafd698..00e9d79 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -127,13 +127,7 @@
.cfg_done = VOP_REG(RK3036_REG_CFG_DONE, 0x1, 0),
 };
 
-static const struct vop_reg_data rk3036_vop_init_reg_table[] = {
-   {RK3036_DSP_CTRL1, 0x},
-};
-
 static const struct vop_data rk3036_vop = {
-   .init_table = rk3036_vop_init_reg_table,
-   .table_size = ARRAY_SIZE(rk3036_vop_init_reg_table),
.ctrl = &rk3036_ctrl_data,
.intr = &rk3036_intr,
.win = rk3036_vop_win_data,
@@ -193,7 +187,8 @@
 static const struct vop_win_phy rk3288_win23_data = {
.data_formats = formats_win_lite,
.nformats = ARRAY_SIZE(formats_win_lite),
-   .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
+   .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4),
+   .gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
.format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1),
.rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12),
.dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0),
@@ -215,6 +210,7 @@
.dither_down = VOP_REG(RK3288_DSP_CTRL1, 0xf, 1),
.dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
.data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
+   .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
.out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
.pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
.htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
@@ -224,22 +220,10 @@
.hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
.line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
+   .global_regdone_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 11),
.cfg_done = VOP_REG(RK3288_REG_CFG_DONE, 0

[PATCH 0/5] drm/rockchip: add all full framework vop support

2017-07-11 Thread Mark Yao
These patches try to make all current rockchip full framework vop works
on drm, The newer vop design always have some different to the old one,
So we add a register verify mechanism to distinguish those register, then
the registers table can be reused.

And people can easy to know the different for the vops from register table.

Mark Yao (5):
  drm/rockchip: vop: get rid of register init table
  drm/rockchip: vop: support verify registers with vop version
  drm/rockchip: vop: move line_flag_num to interrupt registers
  drm/rockchip: vop: add a series of vop support
  dt-bindings: display: fill Documents for series of vop

 .../bindings/display/rockchip/rockchip-vop.txt |   4 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c|  74 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h|  32 +-
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c| 259 +++---
 drivers/gpu/drm/rockchip/rockchip_vop_reg.h| 905 -
 5 files changed, 952 insertions(+), 322 deletions(-)

-- 
1.9.1


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


[PATCH 2/5] drm/rockchip: vop: support verify registers with vop version

2017-07-11 Thread Mark Yao
Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 66 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 18 ++--
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 20 ++---
 3 files changed, 77 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 7a5f809..a9180fd 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -42,33 +42,60 @@
 #include "rockchip_drm_psr.h"
 #include "rockchip_drm_vop.h"
 
-#define __REG_SET_RELAXED(x, off, mask, shift, v, write_mask) \
-   vop_mask_write(x, off, mask, shift, v, write_mask, true)
+#define VOP_REG_SUPPORT(vop, reg) \
+   (!reg.major || (reg.major == VOP_MAJOR(vop->data->version) && \
+   reg.begin_minor <= VOP_MINOR(vop->data->version) && \
+   reg.end_minor >= VOP_MINOR(vop->data->version) && \
+   reg.mask))
 
-#define __REG_SET_NORMAL(x, off, mask, shift, v, write_mask) \
-   vop_mask_write(x, off, mask, shift, v, write_mask, false)
+#define VOP_WIN_SUPPORT(vop, win, name) \
+   VOP_REG_SUPPORT(vop, win->phy->name)
 
-#define REG_SET(x, base, reg, v, mode) \
-   __REG_SET_##mode(x, base + reg.offset, \
-reg.mask, reg.shift, v, reg.write_mask)
-#define REG_SET_MASK(x, base, reg, mask, v, mode) \
-   __REG_SET_##mode(x, base + reg.offset, \
-mask, reg.shift, v, reg.write_mask)
+#define VOP_CTRL_SUPPORT(vop, name) \
+   VOP_REG_SUPPORT(vop, vop->data->ctrl->name)
+
+#define VOP_INTR_SUPPORT(vop, name) \
+   VOP_REG_SUPPORT(vop, vop->data->intr->name)
+
+#define __REG_SET(x, off, mask, shift, v, write_mask, relaxed) \
+   vop_mask_write(x, off, mask, shift, v, write_mask, relaxed)
+
+#define _REG_SET(vop, name, off, reg, mask, v, relaxed) \
+   do { \
+   if (VOP_REG_SUPPORT(vop, reg)) \
+   __REG_SET(vop, off + reg.offset, mask, reg.shift, \
+ v, reg.write_mask, relaxed); \
+   else \
+   dev_dbg(vop->dev, "Warning: not support "#name"\n"); \
+   } while (0)
+
+#define REG_SET(x, name, off, reg, v, relaxed) \
+   _REG_SET(x, name, off, reg, reg.mask, v, relaxed)
+#define REG_SET_MASK(x, name, off, reg, mask, v, relaxed) \
+   _REG_SET(x, name, off, reg, reg.mask & mask, v, relaxed)
 
 #define VOP_WIN_SET(x, win, name, v) \
-   REG_SET(x, win->base, win->phy->name, v, RELAXED)
+   REG_SET(x, name, win->base, win->phy->name, v, true)
+#define VOP_WIN_SET_EXT(x, win, ext, name, v) \
+   REG_SET(x, name, 0, win->ext->name, v, true)
 #define VOP_SCL_SET(x, win, name, v) \
-   REG_SET(x, win->base, win->phy->scl->name, v, RELAXED)
+   REG_SET(x, name, win->base, win->phy->scl->name, v, true)
 #define VOP_SCL_SET_EXT(x, win, name, v) \
-   REG_SET(x, win->base, win->phy->scl->ext->name, v, RELAXED)
+   REG_SET(x, name, win->base, win->phy->scl->ext->name, v, true)
+
 #define VOP_CTRL_SET(x, name, v) \
-   REG_SET(x, 0, (x)->data->ctrl->name, v, NORMAL)
+   REG_SET(x, name, 0, (x)->data->ctrl->name, v, false)
 
 #define VOP_INTR_GET(vop, name) \
vop_read_reg(vop, 0, &vop->data->ctrl->name)
 
-#define VOP_INTR_SET(vop, name, mask, v) \
-   REG_SET_MASK(vop, 0, vop->data->intr->name, mask, v, NORMAL)
+#define VOP_INTR_SET(vop, name, v) \
+   REG_SET(vop, name, 0, vop->data->intr->name, \
+   v, false)
+#define VOP_INTR_SET_MASK(vop, name, mask, v) \
+   REG_SET_MASK(vop, name, 0, vop->data->intr->name, \
+mask, v, false)
+
 #define VOP_INTR_SET_TYPE(vop, name, type, v) \
do { \
int i, reg = 0, mask = 0; \
@@ -78,13 +105,16 @@
mask |= 1 << i; \
} \
} \
-   VOP_INTR_SET(vop, name, mask, reg); \
+   VOP_INTR_SET_MASK(vop, name, mask, reg); \
} while (0)
 #define VOP_INTR_GET_TYPE(vop, name, type) \
vop_get_intr_type(vop, &vop->data->intr->name, type)
 
+#define VOP_CTRL_GET(x, name) \
+   vop_read_reg(x, 0, &vop->data->ctrl->name)
+
 #define VOP_WIN_GET(x, win, name) \
-   vop_read_reg(x, win->base, &win->phy->name)
+   vop_read_reg(x, win->offset, win->phy->name)
 
 #de

[PATCH 5/5] dt-bindings: display: fill Documents for series of vop

2017-07-11 Thread Mark Yao
Signed-off-by: Mark Yao 
---
 Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt | 4 
 1 file changed, 4 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt 
b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
index 9eb3f0a..11fa3b0 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
@@ -8,8 +8,12 @@ Required properties:
 - compatible: value should be one of the following
"rockchip,rk3036-vop";
"rockchip,rk3288-vop";
+   "rockchip,rk3368-vop";
+   "rockchip,rk3366-vop";
"rockchip,rk3399-vop-big";
"rockchip,rk3399-vop-lit";
+   "rockchip,rk322x-vop";
+   "rockchip,rk3328-vop";
 
 - interrupts: should contain a list of all VOP IP block interrupts in the
 order: VSYNC, LCD_SYSTEM. The interrupt specifier
-- 
1.9.1


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


[PATCH 3/5] drm/rockchip: vop: move line_flag_num to interrupt registers

2017-07-11 Thread Mark Yao
Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 4 ++--
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 8 
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index a9180fd..be208ee 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -507,7 +507,7 @@ static void vop_line_flag_irq_enable(struct vop *vop, int 
line_num)
 
spin_lock_irqsave(&vop->irq_lock, flags);
 
-   VOP_CTRL_SET(vop, line_flag_num[0], line_num);
+   VOP_INTR_SET(vop, line_flag_num[0], line_num);
VOP_INTR_SET_TYPE(vop, clear, LINE_FLAG_INTR, 1);
VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1);
 
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index e4de890..f64685e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -70,8 +70,6 @@ struct vop_ctrl {
struct vop_reg hpost_st_end;
struct vop_reg vpost_st_end;
 
-   struct vop_reg line_flag_num[2];
-
struct vop_reg global_regdone_en;
struct vop_reg cfg_done;
 };
@@ -79,6 +77,8 @@ struct vop_ctrl {
 struct vop_intr {
const int *intrs;
uint32_t nintrs;
+
+   struct vop_reg line_flag_num[2];
struct vop_reg enable;
struct vop_reg clear;
struct vop_reg status;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c 
b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 7744603..159cedf 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -118,6 +118,7 @@
 static const struct vop_intr rk3036_intr = {
.intrs = rk3036_vop_intrs,
.nintrs = ARRAY_SIZE(rk3036_vop_intrs),
+   .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
.status = VOP_REG(RK3036_INT_STATUS, 0xf, 0),
.enable = VOP_REG(RK3036_INT_STATUS, 0xf, 4),
.clear = VOP_REG(RK3036_INT_STATUS, 0xf, 8),
@@ -131,7 +132,6 @@
.hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
.vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
.vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
-   .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
.cfg_done = VOP_REG(RK3036_REG_CFG_DONE, 0x1, 0),
 };
 
@@ -227,7 +227,6 @@
.vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
.hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
-   .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
.global_regdone_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 11),
.cfg_done = VOP_REG(RK3288_REG_CFG_DONE, 0x1, 0),
 };
@@ -259,6 +258,7 @@
 static const struct vop_intr rk3288_vop_intr = {
.intrs = rk3288_vop_intrs,
.nintrs = ARRAY_SIZE(rk3288_vop_intrs),
+   .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
.status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0),
.enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4),
.clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8),
@@ -295,8 +295,6 @@
.vact_st_end = VOP_REG(RK3399_DSP_VACT_ST_END, 0x1fff1fff, 0),
.hpost_st_end = VOP_REG(RK3399_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3399_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
-   .line_flag_num[0] = VOP_REG(RK3399_LINE_FLAG, 0x, 0),
-   .line_flag_num[1] = VOP_REG(RK3399_LINE_FLAG, 0x, 16),
.cfg_done = VOP_REG_MASK(RK3399_REG_CFG_DONE, 0x1, 0),
 };
 
@@ -313,6 +311,8 @@
 static const struct vop_intr rk3399_vop_intr = {
.intrs = rk3399_vop_intrs,
.nintrs = ARRAY_SIZE(rk3399_vop_intrs),
+   .line_flag_num[0] = VOP_REG(RK3399_LINE_FLAG, 0x, 0),
+   .line_flag_num[1] = VOP_REG(RK3399_LINE_FLAG, 0x, 16),
.status = VOP_REG_MASK(RK3399_INTR_STATUS0, 0x, 0),
.enable = VOP_REG_MASK(RK3399_INTR_EN0, 0x, 0),
.clear = VOP_REG_MASK(RK3399_INTR_CLEAR0, 0x, 0),
-- 
1.9.1


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


[PATCH 4/5] drm/rockchip: vop: add a series of vop support

2017-07-11 Thread Mark Yao
Vop Full framework now has following vops:
IP versionchipname
  3.1   rk3288
  3.2   rk3368
  3.4   rk3366
  3.5   rk3399 big
  3.6   rk3399 lit
  3.7   rk322x
  3.8   rk3328

The above IP version is from H/W define, some of vop support get
the IP version from VERSION_INFO register, some are not.
hardcode the IP version for each vop to identify them.

major version: used for IP structure, Vop full framework is 3,
   vop little framework is 2.
minor version: on same structure, newer design vop will bigger
   then old one.

Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 198 --
 drivers/gpu/drm/rockchip/rockchip_vop_reg.h | 905 ++--
 2 files changed, 859 insertions(+), 244 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c 
b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 159cedf..c5d7c70 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -211,6 +211,7 @@
.standby = VOP_REG(RK3288_SYS_CTRL, 0x1, 22),
.gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
.mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
+   .dp_en = VOP_REG_VER(RK3399_SYS_CTRL, 0x1, 11, 3, 5, -1),
.rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
.hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
.edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
@@ -221,13 +222,18 @@
.dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
.out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
.pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
+   .dp_pin_pol = VOP_REG_VER(RK3399_DSP_CTRL1, 0xf, 16, 3, 5, -1),
+   .rgb_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0xf, 16, 3, 2, -1),
+   .hdmi_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0xf, 20, 3, 2, -1),
+   .edp_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0xf, 24, 3, 2, -1),
+   .mipi_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0xf, 28, 3, 2, -1),
.htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
.hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0),
.vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
.vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
.hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
-   .global_regdone_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 11),
+   .global_regdone_en = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 11, 3, 2, -1),
.cfg_done = VOP_REG(RK3288_REG_CFG_DONE, 0x1, 0),
 };
 
@@ -272,33 +278,7 @@
.win_size = ARRAY_SIZE(rk3288_vop_win_data),
 };
 
-static const struct vop_ctrl rk3399_ctrl_data = {
-   .standby = VOP_REG(RK3399_SYS_CTRL, 0x1, 22),
-   .gate_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 23),
-   .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
-   .rgb_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 12),
-   .hdmi_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 13),
-   .edp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 14),
-   .mipi_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 15),
-   .dither_down = VOP_REG(RK3399_DSP_CTRL1, 0xf, 1),
-   .dither_up = VOP_REG(RK3399_DSP_CTRL1, 0x1, 6),
-   .data_blank = VOP_REG(RK3399_DSP_CTRL0, 0x1, 19),
-   .out_mode = VOP_REG(RK3399_DSP_CTRL0, 0xf, 0),
-   .rgb_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
-   .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
-   .hdmi_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 20),
-   .edp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 24),
-   .mipi_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 28),
-   .htotal_pw = VOP_REG(RK3399_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
-   .hact_st_end = VOP_REG(RK3399_DSP_HACT_ST_END, 0x1fff1fff, 0),
-   .vtotal_pw = VOP_REG(RK3399_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
-   .vact_st_end = VOP_REG(RK3399_DSP_VACT_ST_END, 0x1fff1fff, 0),
-   .hpost_st_end = VOP_REG(RK3399_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
-   .vpost_st_end = VOP_REG(RK3399_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
-   .cfg_done = VOP_REG_MASK(RK3399_REG_CFG_DONE, 0x1, 0),
-};
-
-static const int rk3399_vop_intrs[] = {
+static const int rk3368_vop_intrs[] = {
FS_INTR,
0, 0,
LINE_FLAG_INTR,
@@ -308,54 +288,170 @@
DSP_HOLD_VALID_INTR,
 };
 
-static const struct vop_intr rk3399_vop_intr = {
-   .intrs = rk3399_vop_intrs,
-   .nintrs = ARRAY_SIZE(rk3399_vop_intrs),
-   .line_flag_num[0] = VOP_REG(RK3399_LINE_FLAG, 0x, 0),
-   .line_flag_num[1] = VOP_REG(RK3399_LINE_FLAG, 0x, 16),
-   .status = VOP_REG_MASK(RK3399_INTR_STATUS0, 0x, 0),
-   .enable = VOP_REG_MASK(RK3399_INTR_EN0, 0x, 0),
-   .clear = VOP_REG_MASK(RK3399_INTR_CLEAR0, 0x, 0),
+static const struct vop_intr rk3368_vop_intr = {
+   .intrs = rk3368_vop_intrs,
+   .nintrs = ARRAY_SIZE(rk3368_vop_intrs

Re: [PATCH 5/5] dt-bindings: display: fill Documents for series of vop

2017-07-11 Thread Mark yao

On 2017年07月11日 20:45, Heiko Stübner wrote:

Hi Mark,

Am Dienstag, 11. Juli 2017, 20:42:38 CEST schrieb Mark Yao:

Signed-off-by: Mark Yao 
---
  Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt | 4
 1 file changed, 4 insertions(+)

diff --git
a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt index
9eb3f0a..11fa3b0 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
@@ -8,8 +8,12 @@ Required properties:
  - compatible: value should be one of the following
"rockchip,rk3036-vop";
"rockchip,rk3288-vop";
+   "rockchip,rk3368-vop";
+   "rockchip,rk3366-vop";
"rockchip,rk3399-vop-big";
"rockchip,rk3399-vop-lit";
+   "rockchip,rk322x-vop";

please don't use wildcards in devicetree compatibles. We've somehow
standardized on using rk3228 for both the rk3228 and rk3229 (which are
nearly the same soc with some speed adjustments)

So,
+   "rockchip,rk3228-vop";
please


Thanks
Heiko


Got it, I will fix it at next version

Thanks
Mark




+   "rockchip,rk3328-vop";

  - interrupts: should contain a list of all VOP IP block interrupts in the
 order: VSYNC, LCD_SYSTEM. The interrupt specifier








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


[PATCH v2 0/5] drm/rockchip: add all full framework vop support

2017-07-11 Thread Mark Yao
These patches try to make all current rockchip full framework vop works
on drm, The newer vop design always have some different to the old one,
So we add a register verify mechanism to distinguish those register, then
the registers table can be reused.

And people can easy to know the different for the vops from register table.

Tested on rk3399 evb board.

Changes in v2:
- rename rk322x to rk3228(Heiko Stübner)
- correct some vop registers define

Mark Yao (5):
  drm/rockchip: vop: get rid of register init table
  drm/rockchip: vop: support verify registers with vop version
  drm/rockchip: vop: move line_flag_num to interrupt registers
  drm/rockchip: vop: add a series of vop support
  dt-bindings: display: fill Documents for series of vop

 .../bindings/display/rockchip/rockchip-vop.txt |   4 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c|  74 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h|  32 +-
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c| 263 +++---
 drivers/gpu/drm/rockchip/rockchip_vop_reg.h| 905 -
 5 files changed, 956 insertions(+), 322 deletions(-)

-- 
1.9.1


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


[PATCH v2 1/5] drm/rockchip: vop: get rid of register init table

2017-07-11 Thread Mark Yao
Register init table use un-document define, it is unreadable,
And sometimes we only want to update tiny bits, init table
method is not friendly, it's diffcult to reuse for difference
chips.

Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  6 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 10 ++-
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 43 +++--
 3 files changed, 10 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 45589d6..7a5f809 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1393,7 +1393,6 @@ static void vop_destroy_crtc(struct vop *vop)
 static int vop_initial(struct vop *vop)
 {
const struct vop_data *vop_data = vop->data;
-   const struct vop_reg_data *init_table = vop_data->init_table;
struct reset_control *ahb_rst;
int i, ret;
 
@@ -1453,13 +1452,14 @@ static int vop_initial(struct vop *vop)
 
memcpy(vop->regsbak, vop->regs, vop->len);
 
-   for (i = 0; i < vop_data->table_size; i++)
-   vop_writel(vop, init_table[i].offset, init_table[i].value);
+   VOP_CTRL_SET(vop, global_regdone_en, 1);
+   VOP_CTRL_SET(vop, dsp_blank, 0);
 
for (i = 0; i < vop_data->win_size; i++) {
const struct vop_win_data *win = &vop_data->win[i];
 
VOP_WIN_SET(vop, win, enable, 0);
+   VOP_WIN_SET(vop, win, gate, 1);
}
 
vop_cfg_done(vop);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 9979fd0..084d3b2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -24,11 +24,6 @@ enum vop_data_format {
VOP_FMT_YUV444SP,
 };
 
-struct vop_reg_data {
-   uint32_t offset;
-   uint32_t value;
-};
-
 struct vop_reg {
uint32_t offset;
uint32_t shift;
@@ -46,6 +41,7 @@ struct vop_ctrl {
struct vop_reg hdmi_en;
struct vop_reg mipi_en;
struct vop_reg dp_en;
+   struct vop_reg dsp_blank;
struct vop_reg out_mode;
struct vop_reg dither_down;
struct vop_reg dither_up;
@@ -65,6 +61,7 @@ struct vop_ctrl {
 
struct vop_reg line_flag_num[2];
 
+   struct vop_reg global_regdone_en;
struct vop_reg cfg_done;
 };
 
@@ -115,6 +112,7 @@ struct vop_win_phy {
uint32_t nformats;
 
struct vop_reg enable;
+   struct vop_reg gate;
struct vop_reg format;
struct vop_reg rb_swap;
struct vop_reg act_info;
@@ -136,8 +134,6 @@ struct vop_win_data {
 };
 
 struct vop_data {
-   const struct vop_reg_data *init_table;
-   unsigned int table_size;
const struct vop_ctrl *ctrl;
const struct vop_intr *intr;
const struct vop_win_data *win;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c 
b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index bafd698..00e9d79 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -127,13 +127,7 @@
.cfg_done = VOP_REG(RK3036_REG_CFG_DONE, 0x1, 0),
 };
 
-static const struct vop_reg_data rk3036_vop_init_reg_table[] = {
-   {RK3036_DSP_CTRL1, 0x},
-};
-
 static const struct vop_data rk3036_vop = {
-   .init_table = rk3036_vop_init_reg_table,
-   .table_size = ARRAY_SIZE(rk3036_vop_init_reg_table),
.ctrl = &rk3036_ctrl_data,
.intr = &rk3036_intr,
.win = rk3036_vop_win_data,
@@ -193,7 +187,8 @@
 static const struct vop_win_phy rk3288_win23_data = {
.data_formats = formats_win_lite,
.nformats = ARRAY_SIZE(formats_win_lite),
-   .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
+   .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4),
+   .gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
.format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1),
.rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12),
.dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0),
@@ -215,6 +210,7 @@
.dither_down = VOP_REG(RK3288_DSP_CTRL1, 0xf, 1),
.dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
.data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
+   .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
.out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
.pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
.htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
@@ -224,22 +220,10 @@
.hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
.line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
+   .global_regdone_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 11),
.cfg_done = VOP_REG(RK3288_REG_CFG_DONE, 0

[PATCH v2 3/5] drm/rockchip: vop: move line_flag_num to interrupt registers

2017-07-11 Thread Mark Yao
Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 4 ++--
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 8 
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index a9180fd..be208ee 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -507,7 +507,7 @@ static void vop_line_flag_irq_enable(struct vop *vop, int 
line_num)
 
spin_lock_irqsave(&vop->irq_lock, flags);
 
-   VOP_CTRL_SET(vop, line_flag_num[0], line_num);
+   VOP_INTR_SET(vop, line_flag_num[0], line_num);
VOP_INTR_SET_TYPE(vop, clear, LINE_FLAG_INTR, 1);
VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1);
 
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index e4de890..f64685e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -70,8 +70,6 @@ struct vop_ctrl {
struct vop_reg hpost_st_end;
struct vop_reg vpost_st_end;
 
-   struct vop_reg line_flag_num[2];
-
struct vop_reg global_regdone_en;
struct vop_reg cfg_done;
 };
@@ -79,6 +77,8 @@ struct vop_ctrl {
 struct vop_intr {
const int *intrs;
uint32_t nintrs;
+
+   struct vop_reg line_flag_num[2];
struct vop_reg enable;
struct vop_reg clear;
struct vop_reg status;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c 
b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 7744603..159cedf 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -118,6 +118,7 @@
 static const struct vop_intr rk3036_intr = {
.intrs = rk3036_vop_intrs,
.nintrs = ARRAY_SIZE(rk3036_vop_intrs),
+   .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
.status = VOP_REG(RK3036_INT_STATUS, 0xf, 0),
.enable = VOP_REG(RK3036_INT_STATUS, 0xf, 4),
.clear = VOP_REG(RK3036_INT_STATUS, 0xf, 8),
@@ -131,7 +132,6 @@
.hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
.vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
.vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
-   .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
.cfg_done = VOP_REG(RK3036_REG_CFG_DONE, 0x1, 0),
 };
 
@@ -227,7 +227,6 @@
.vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
.hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
-   .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
.global_regdone_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 11),
.cfg_done = VOP_REG(RK3288_REG_CFG_DONE, 0x1, 0),
 };
@@ -259,6 +258,7 @@
 static const struct vop_intr rk3288_vop_intr = {
.intrs = rk3288_vop_intrs,
.nintrs = ARRAY_SIZE(rk3288_vop_intrs),
+   .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
.status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0),
.enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4),
.clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8),
@@ -295,8 +295,6 @@
.vact_st_end = VOP_REG(RK3399_DSP_VACT_ST_END, 0x1fff1fff, 0),
.hpost_st_end = VOP_REG(RK3399_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3399_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
-   .line_flag_num[0] = VOP_REG(RK3399_LINE_FLAG, 0x, 0),
-   .line_flag_num[1] = VOP_REG(RK3399_LINE_FLAG, 0x, 16),
.cfg_done = VOP_REG_MASK(RK3399_REG_CFG_DONE, 0x1, 0),
 };
 
@@ -313,6 +311,8 @@
 static const struct vop_intr rk3399_vop_intr = {
.intrs = rk3399_vop_intrs,
.nintrs = ARRAY_SIZE(rk3399_vop_intrs),
+   .line_flag_num[0] = VOP_REG(RK3399_LINE_FLAG, 0x, 0),
+   .line_flag_num[1] = VOP_REG(RK3399_LINE_FLAG, 0x, 16),
.status = VOP_REG_MASK(RK3399_INTR_STATUS0, 0x, 0),
.enable = VOP_REG_MASK(RK3399_INTR_EN0, 0x, 0),
.clear = VOP_REG_MASK(RK3399_INTR_CLEAR0, 0x, 0),
-- 
1.9.1


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


[PATCH v2 2/5] drm/rockchip: vop: support verify registers with vop version

2017-07-11 Thread Mark Yao
Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 66 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 18 ++--
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 20 ++---
 3 files changed, 77 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 7a5f809..a9180fd 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -42,33 +42,60 @@
 #include "rockchip_drm_psr.h"
 #include "rockchip_drm_vop.h"
 
-#define __REG_SET_RELAXED(x, off, mask, shift, v, write_mask) \
-   vop_mask_write(x, off, mask, shift, v, write_mask, true)
+#define VOP_REG_SUPPORT(vop, reg) \
+   (!reg.major || (reg.major == VOP_MAJOR(vop->data->version) && \
+   reg.begin_minor <= VOP_MINOR(vop->data->version) && \
+   reg.end_minor >= VOP_MINOR(vop->data->version) && \
+   reg.mask))
 
-#define __REG_SET_NORMAL(x, off, mask, shift, v, write_mask) \
-   vop_mask_write(x, off, mask, shift, v, write_mask, false)
+#define VOP_WIN_SUPPORT(vop, win, name) \
+   VOP_REG_SUPPORT(vop, win->phy->name)
 
-#define REG_SET(x, base, reg, v, mode) \
-   __REG_SET_##mode(x, base + reg.offset, \
-reg.mask, reg.shift, v, reg.write_mask)
-#define REG_SET_MASK(x, base, reg, mask, v, mode) \
-   __REG_SET_##mode(x, base + reg.offset, \
-mask, reg.shift, v, reg.write_mask)
+#define VOP_CTRL_SUPPORT(vop, name) \
+   VOP_REG_SUPPORT(vop, vop->data->ctrl->name)
+
+#define VOP_INTR_SUPPORT(vop, name) \
+   VOP_REG_SUPPORT(vop, vop->data->intr->name)
+
+#define __REG_SET(x, off, mask, shift, v, write_mask, relaxed) \
+   vop_mask_write(x, off, mask, shift, v, write_mask, relaxed)
+
+#define _REG_SET(vop, name, off, reg, mask, v, relaxed) \
+   do { \
+   if (VOP_REG_SUPPORT(vop, reg)) \
+   __REG_SET(vop, off + reg.offset, mask, reg.shift, \
+ v, reg.write_mask, relaxed); \
+   else \
+   dev_dbg(vop->dev, "Warning: not support "#name"\n"); \
+   } while (0)
+
+#define REG_SET(x, name, off, reg, v, relaxed) \
+   _REG_SET(x, name, off, reg, reg.mask, v, relaxed)
+#define REG_SET_MASK(x, name, off, reg, mask, v, relaxed) \
+   _REG_SET(x, name, off, reg, reg.mask & mask, v, relaxed)
 
 #define VOP_WIN_SET(x, win, name, v) \
-   REG_SET(x, win->base, win->phy->name, v, RELAXED)
+   REG_SET(x, name, win->base, win->phy->name, v, true)
+#define VOP_WIN_SET_EXT(x, win, ext, name, v) \
+   REG_SET(x, name, 0, win->ext->name, v, true)
 #define VOP_SCL_SET(x, win, name, v) \
-   REG_SET(x, win->base, win->phy->scl->name, v, RELAXED)
+   REG_SET(x, name, win->base, win->phy->scl->name, v, true)
 #define VOP_SCL_SET_EXT(x, win, name, v) \
-   REG_SET(x, win->base, win->phy->scl->ext->name, v, RELAXED)
+   REG_SET(x, name, win->base, win->phy->scl->ext->name, v, true)
+
 #define VOP_CTRL_SET(x, name, v) \
-   REG_SET(x, 0, (x)->data->ctrl->name, v, NORMAL)
+   REG_SET(x, name, 0, (x)->data->ctrl->name, v, false)
 
 #define VOP_INTR_GET(vop, name) \
vop_read_reg(vop, 0, &vop->data->ctrl->name)
 
-#define VOP_INTR_SET(vop, name, mask, v) \
-   REG_SET_MASK(vop, 0, vop->data->intr->name, mask, v, NORMAL)
+#define VOP_INTR_SET(vop, name, v) \
+   REG_SET(vop, name, 0, vop->data->intr->name, \
+   v, false)
+#define VOP_INTR_SET_MASK(vop, name, mask, v) \
+   REG_SET_MASK(vop, name, 0, vop->data->intr->name, \
+mask, v, false)
+
 #define VOP_INTR_SET_TYPE(vop, name, type, v) \
do { \
int i, reg = 0, mask = 0; \
@@ -78,13 +105,16 @@
mask |= 1 << i; \
} \
} \
-   VOP_INTR_SET(vop, name, mask, reg); \
+   VOP_INTR_SET_MASK(vop, name, mask, reg); \
} while (0)
 #define VOP_INTR_GET_TYPE(vop, name, type) \
vop_get_intr_type(vop, &vop->data->intr->name, type)
 
+#define VOP_CTRL_GET(x, name) \
+   vop_read_reg(x, 0, &vop->data->ctrl->name)
+
 #define VOP_WIN_GET(x, win, name) \
-   vop_read_reg(x, win->base, &win->phy->name)
+   vop_read_reg(x, win->offset, win->phy->name)
 
 #de

[PATCH v2 4/5] drm/rockchip: vop: add a series of vop support

2017-07-11 Thread Mark Yao
Vop Full framework now has following vops:
IP versionchipname
  3.1   rk3288
  3.2   rk3368
  3.4   rk3366
  3.5   rk3399 big
  3.6   rk3399 lit
  3.7   rk3228
  3.8   rk3328

The above IP version is from H/W define, some of vop support get
the IP version from VERSION_INFO register, some are not.
hardcode the IP version for each vop to identify them.

major version: used for IP structure, Vop full framework is 3,
   vop little framework is 2.
minor version: on same structure, newer design vop will bigger
   then old one.

Changes in v2:
- rename rk322x to rk3228(Heiko Stübner)
- correct some vop registers define

Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 202 +--
 drivers/gpu/drm/rockchip/rockchip_vop_reg.h | 905 ++--
 2 files changed, 863 insertions(+), 244 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c 
b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 159cedf..b33483c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -211,6 +211,7 @@
.standby = VOP_REG(RK3288_SYS_CTRL, 0x1, 22),
.gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
.mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
+   .dp_en = VOP_REG_VER(RK3399_SYS_CTRL, 0x1, 11, 3, 5, -1),
.rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
.hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
.edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
@@ -220,14 +221,19 @@
.data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
.dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
.out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
-   .pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
+   .pin_pol = VOP_REG_VER(RK3288_DSP_CTRL0, 0xf, 4, 3, 0, 1),
+   .dp_pin_pol = VOP_REG_VER(RK3399_DSP_CTRL1, 0xf, 16, 3, 5, -1),
+   .rgb_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0xf, 16, 3, 2, -1),
+   .hdmi_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0xf, 20, 3, 2, -1),
+   .edp_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0xf, 24, 3, 2, -1),
+   .mipi_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0xf, 28, 3, 2, -1),
.htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
.hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0),
.vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
.vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
.hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
-   .global_regdone_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 11),
+   .global_regdone_en = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 11, 3, 2, -1),
.cfg_done = VOP_REG(RK3288_REG_CFG_DONE, 0x1, 0),
 };
 
@@ -265,6 +271,7 @@
 };
 
 static const struct vop_data rk3288_vop = {
+   .version = VOP_VERSION(3, 1),
.feature = VOP_FEATURE_OUTPUT_RGB10,
.intr = &rk3288_vop_intr,
.ctrl = &rk3288_ctrl_data,
@@ -272,33 +279,7 @@
.win_size = ARRAY_SIZE(rk3288_vop_win_data),
 };
 
-static const struct vop_ctrl rk3399_ctrl_data = {
-   .standby = VOP_REG(RK3399_SYS_CTRL, 0x1, 22),
-   .gate_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 23),
-   .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
-   .rgb_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 12),
-   .hdmi_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 13),
-   .edp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 14),
-   .mipi_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 15),
-   .dither_down = VOP_REG(RK3399_DSP_CTRL1, 0xf, 1),
-   .dither_up = VOP_REG(RK3399_DSP_CTRL1, 0x1, 6),
-   .data_blank = VOP_REG(RK3399_DSP_CTRL0, 0x1, 19),
-   .out_mode = VOP_REG(RK3399_DSP_CTRL0, 0xf, 0),
-   .rgb_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
-   .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
-   .hdmi_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 20),
-   .edp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 24),
-   .mipi_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 28),
-   .htotal_pw = VOP_REG(RK3399_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
-   .hact_st_end = VOP_REG(RK3399_DSP_HACT_ST_END, 0x1fff1fff, 0),
-   .vtotal_pw = VOP_REG(RK3399_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
-   .vact_st_end = VOP_REG(RK3399_DSP_VACT_ST_END, 0x1fff1fff, 0),
-   .hpost_st_end = VOP_REG(RK3399_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
-   .vpost_st_end = VOP_REG(RK3399_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
-   .cfg_done = VOP_REG_MASK(RK3399_REG_CFG_DONE, 0x1, 0),
-};
-
-static const int rk3399_vop_intrs[] = {
+static const int rk3368_vop_intrs[] = {
FS_INTR,
0, 0,
LINE_FLAG_INTR,
@@ -308,54 +289,173 @@
DSP_HOLD_VALID_INTR,
 };
 
-static const struct vop_intr rk3399_vop_intr = {
-   .intrs = rk3399_vop_intrs,
-   .nintrs = ARRAY_SIZE(rk3399_vop_intrs),
-   .line_fl

[PATCH v2 5/5] dt-bindings: display: fill Documents for series of vop

2017-07-11 Thread Mark Yao
Changes in v2:
- rename rk322x to rk3228(Heiko Stübner)

Signed-off-by: Mark Yao 
---
 Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt | 4 
 1 file changed, 4 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt 
b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
index 9eb3f0a..5d835d9 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
@@ -8,8 +8,12 @@ Required properties:
 - compatible: value should be one of the following
"rockchip,rk3036-vop";
"rockchip,rk3288-vop";
+   "rockchip,rk3368-vop";
+   "rockchip,rk3366-vop";
"rockchip,rk3399-vop-big";
"rockchip,rk3399-vop-lit";
+   "rockchip,rk3228-vop";
+   "rockchip,rk3328-vop";
 
 - interrupts: should contain a list of all VOP IP block interrupts in the
 order: VSYNC, LCD_SYSTEM. The interrupt specifier
-- 
1.9.1


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


Re: [PATCH 09/16] drm/rockchip: Use for_each_oldnew_plane_in_state in vop_crtc_atomic_flush

2017-07-12 Thread Mark yao

On 2017年07月12日 16:13, Maarten Lankhorst wrote:

for_each_obj_in_state is about to be removed, so use the new atomic
iterator macros.

Signed-off-by: Maarten Lankhorst
Cc: Mark Yao
Cc: Heiko Stuebner
Cc:linux-arm-ker...@lists.infradead.org
Cc:linux-rockc...@lists.infradead.org


Looks good for me:

Acked-by: Mark Yao 

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


Re: [PATCH v2 4/5] drm/rockchip: vop: add a series of vop support

2017-07-12 Thread Mark yao

  
  
On 2017年07月13日 02:33, Sean Paul wrote:


  On Wed, Jul 12, 2017 at 10:03:54AM +0800, Mark Yao wrote:

  
Vop Full framework now has following vops:
IP versionchipname
  3.1   rk3288
  3.2   rk3368
  3.4   rk3366
  3.5   rk3399 big
  3.6   rk3399 lit

  
  
Below you say little vop is major == 2, but you have major == 3 here.


"RK3399 lit" is a full design vop framework, just cut down some
feature from rk3399 big design, so it's IP major is 3.

the little vop is rk3066, rk3188, rk3036, etc.


  


  
  3.7   rk3228
  3.8   rk3328

The above IP version is from H/W define, some of vop support get
the IP version from VERSION_INFO register, some are not.
hardcode the IP version for each vop to identify them.

major version: used for IP structure, Vop full framework is 3,
   vop little framework is 2.
minor version: on same structure, newer design vop will bigger
   then old one.

Changes in v2:
- rename rk322x to rk3228(Heiko Stübner)
- correct some vop registers define

Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 202 +--
 drivers/gpu/drm/rockchip/rockchip_vop_reg.h | 905 ++--
 2 files changed, 863 insertions(+), 244 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 159cedf..b33483c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -211,6 +211,7 @@
 	.standby = VOP_REG(RK3288_SYS_CTRL, 0x1, 22),
 	.gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
 	.mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
+	.dp_en = VOP_REG_VER(RK3399_SYS_CTRL, 0x1, 11, 3, 5, -1),
 	.rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
 	.hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
 	.edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
@@ -220,14 +221,19 @@
 	.data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
 	.dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
 	.out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
-	.pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
+	.pin_pol = VOP_REG_VER(RK3288_DSP_CTRL0, 0xf, 4, 3, 0, 1),
+	.dp_pin_pol = VOP_REG_VER(RK3399_DSP_CTRL1, 0xf, 16, 3, 5, -1),
+	.rgb_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0xf, 16, 3, 2, -1),
+	.hdmi_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0xf, 20, 3, 2, -1),
+	.edp_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0xf, 24, 3, 2, -1),
+	.mipi_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0xf, 28, 3, 2, -1),
 	.htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
 	.hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0),
 	.vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
 	.vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
 	.hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
 	.vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
-	.global_regdone_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 11),
+	.global_regdone_en = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 11, 3, 2, -1),
 	.cfg_done = VOP_REG(RK3288_REG_CFG_DONE, 0x1, 0),

  
  
I'm not really convinced VOP_REG_VER is a good idea. In the case of dp_en and
pin_pol, the register is already used for different offsets, so presumably
you're writing into don't care offsets?


VOP_REG_VER control when the register works.
for pin_pol, it only works on version(3.0 - 3.1),  rk3288, it's
dummy operate on other chips.
for dp_en, it works on version (3.5 - bigger), rk3399 big, rk3399
lit, rk322x, etc.
it's dummy operate on rk3288, rk3368.

Using VOP_REG means the register works on all platform,  Using
VOP_REG_VER means only can use on some platform.

So don't worry about writing wrong offsets, the register would be
dummy on un-support platform.

  

In the other cases, it just looks like a few new registers added for 3368 and
3399. In this scenario, I don't think it's that bad to just have separate
structs for each version that has distinct features. There's going to be more
duplication, but then it's super easy to understand which platform has which
registers.


separate
structs is TODO on my plan, separate with control, modesetting, etc.
but many register has no a clean group define, and need rewrite
write/read ops,
need handle conflict for each platform.

And I think  VOP_REG_VER mechanism can both works with separate
structs.





  

The whole versioning system is a little strange. For example, is each version
guaranteed to have the registered defined for the previous version (ie: 3.6
contains all registers defined for 3.5)?


Mostly, new version will contains all register of previous, if some
register only support on old version,
example, pin_p

Re: [PATCH v2 1/5] drm/rockchip: vop: get rid of register init table

2017-07-12 Thread Mark yao

On 2017年07月13日 00:47, Sean Paul wrote:

On Wed, Jul 12, 2017 at 10:03:27AM +0800, Mark Yao wrote:

Register init table use un-document define, it is unreadable,
And sometimes we only want to update tiny bits, init table
method is not friendly, it's diffcult to reuse for difference
chips.

While I'm happy to see the init_table removed, it seems like the new code is not
equivalent to the old (ie: some register writes have been dropped). How did you
ensure that you're not breaking existing boards that depend on the deleted 
register
initialization?

Sean


All the existing boards works fine on my internal kernel board with the 
init_table removed,
We had tested all the existing boards, so it's no problem to removed init_table




Signed-off-by: Mark Yao 
---
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  6 ++--
  drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 10 ++-
  drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 43 +++--
  3 files changed, 10 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 45589d6..7a5f809 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1393,7 +1393,6 @@ static void vop_destroy_crtc(struct vop *vop)
  static int vop_initial(struct vop *vop)
  {
const struct vop_data *vop_data = vop->data;
-   const struct vop_reg_data *init_table = vop_data->init_table;
struct reset_control *ahb_rst;
int i, ret;
  
@@ -1453,13 +1452,14 @@ static int vop_initial(struct vop *vop)
  
  	memcpy(vop->regsbak, vop->regs, vop->len);
  
-	for (i = 0; i < vop_data->table_size; i++)

-   vop_writel(vop, init_table[i].offset, init_table[i].value);
+   VOP_CTRL_SET(vop, global_regdone_en, 1);
+   VOP_CTRL_SET(vop, dsp_blank, 0);
  
  	for (i = 0; i < vop_data->win_size; i++) {

const struct vop_win_data *win = &vop_data->win[i];
  
  		VOP_WIN_SET(vop, win, enable, 0);

+   VOP_WIN_SET(vop, win, gate, 1);
}
  
  	vop_cfg_done(vop);

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 9979fd0..084d3b2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -24,11 +24,6 @@ enum vop_data_format {
VOP_FMT_YUV444SP,
  };
  
-struct vop_reg_data {

-   uint32_t offset;
-   uint32_t value;
-};
-
  struct vop_reg {
uint32_t offset;
uint32_t shift;
@@ -46,6 +41,7 @@ struct vop_ctrl {
struct vop_reg hdmi_en;
struct vop_reg mipi_en;
struct vop_reg dp_en;
+   struct vop_reg dsp_blank;
struct vop_reg out_mode;
struct vop_reg dither_down;
struct vop_reg dither_up;
@@ -65,6 +61,7 @@ struct vop_ctrl {
  
  	struct vop_reg line_flag_num[2];
  
+	struct vop_reg global_regdone_en;

struct vop_reg cfg_done;
  };
  
@@ -115,6 +112,7 @@ struct vop_win_phy {

uint32_t nformats;
  
  	struct vop_reg enable;

+   struct vop_reg gate;
struct vop_reg format;
struct vop_reg rb_swap;
struct vop_reg act_info;
@@ -136,8 +134,6 @@ struct vop_win_data {
  };
  
  struct vop_data {

-   const struct vop_reg_data *init_table;
-   unsigned int table_size;
const struct vop_ctrl *ctrl;
const struct vop_intr *intr;
const struct vop_win_data *win;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c 
b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index bafd698..00e9d79 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -127,13 +127,7 @@
.cfg_done = VOP_REG(RK3036_REG_CFG_DONE, 0x1, 0),
  };
  
-static const struct vop_reg_data rk3036_vop_init_reg_table[] = {

-   {RK3036_DSP_CTRL1, 0x},
-};
-
  static const struct vop_data rk3036_vop = {
-   .init_table = rk3036_vop_init_reg_table,
-   .table_size = ARRAY_SIZE(rk3036_vop_init_reg_table),
.ctrl = &rk3036_ctrl_data,
.intr = &rk3036_intr,
.win = rk3036_vop_win_data,
@@ -193,7 +187,8 @@
  static const struct vop_win_phy rk3288_win23_data = {
.data_formats = formats_win_lite,
.nformats = ARRAY_SIZE(formats_win_lite),
-   .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
+   .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4),
+   .gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
.format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1),
.rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12),
.dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0),
@@ -215,6 +210,7 @@
.dither_down = VOP_REG(RK3288_DSP_CTRL1, 0xf, 1),
.dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
.data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
+   .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 

Re: [PATCH v2 2/5] drm/rockchip: vop: support verify registers with vop version

2017-07-12 Thread Mark yao

On 2017年07月13日 01:53, Sean Paul wrote:

On Wed, Jul 12, 2017 at 10:03:38AM +0800, Mark Yao wrote:

Please add a commit message describing *what* and *why* you are making the
change.


Got it, I will fix it at next version.

Thanks.



Signed-off-by: Mark Yao 
---
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 66 +
  drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 18 ++--
  drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 20 ++---
  3 files changed, 77 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 7a5f809..a9180fd 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -42,33 +42,60 @@
  #include "rockchip_drm_psr.h"
  #include "rockchip_drm_vop.h"
  
-#define __REG_SET_RELAXED(x, off, mask, shift, v, write_mask) \

-   vop_mask_write(x, off, mask, shift, v, write_mask, true)
+#define VOP_REG_SUPPORT(vop, reg) \
+   (!reg.major || (reg.major == VOP_MAJOR(vop->data->version) && \
+   reg.begin_minor <= VOP_MINOR(vop->data->version) && \
+   reg.end_minor >= VOP_MINOR(vop->data->version) && \
+   reg.mask))

This would be better suited as a static inline function. As would many of the
macros below.


Got it, will fix it at next version.


  
-#define __REG_SET_NORMAL(x, off, mask, shift, v, write_mask) \

-   vop_mask_write(x, off, mask, shift, v, write_mask, false)
+#define VOP_WIN_SUPPORT(vop, win, name) \
+   VOP_REG_SUPPORT(vop, win->phy->name)
  
-#define REG_SET(x, base, reg, v, mode) \

-   __REG_SET_##mode(x, base + reg.offset, \
-reg.mask, reg.shift, v, reg.write_mask)
-#define REG_SET_MASK(x, base, reg, mask, v, mode) \
-   __REG_SET_##mode(x, base + reg.offset, \
-mask, reg.shift, v, reg.write_mask)
+#define VOP_CTRL_SUPPORT(vop, name) \
+   VOP_REG_SUPPORT(vop, vop->data->ctrl->name)
+
+#define VOP_INTR_SUPPORT(vop, name) \
+   VOP_REG_SUPPORT(vop, vop->data->intr->name)
+
+#define __REG_SET(x, off, mask, shift, v, write_mask, relaxed) \
+   vop_mask_write(x, off, mask, shift, v, write_mask, relaxed)

There's really no point to this, just call vop_mask_write directly.


Got it, will fix it at next version.



+
+#define _REG_SET(vop, name, off, reg, mask, v, relaxed) \
+   do { \
+   if (VOP_REG_SUPPORT(vop, reg)) \
+   __REG_SET(vop, off + reg.offset, mask, reg.shift, \

s/mask/reg.mask & mask/


Got it, will fix it at next version.



+ v, reg.write_mask, relaxed); \
+   else \
+   dev_dbg(vop->dev, "Warning: not support "#name"\n"); \
+   } while (0)


Also better as static inline, IMO.


Good idea, I will try it.




+
+#define REG_SET(x, name, off, reg, v, relaxed) \
+   _REG_SET(x, name, off, reg, reg.mask, v, relaxed)

s/reg.mask/~0/


Got it, will fix it at next version.



+#define REG_SET_MASK(x, name, off, reg, mask, v, relaxed) \
+   _REG_SET(x, name, off, reg, reg.mask & mask, v, relaxed)

s/reg.mask &//

Also, these can become static inline functions as well.


Got it, will fix it at next version.


  
  #define VOP_WIN_SET(x, win, name, v) \

-   REG_SET(x, win->base, win->phy->name, v, RELAXED)
+   REG_SET(x, name, win->base, win->phy->name, v, true)
+#define VOP_WIN_SET_EXT(x, win, ext, name, v) \
+   REG_SET(x, name, 0, win->ext->name, v, true)
  #define VOP_SCL_SET(x, win, name, v) \
-   REG_SET(x, win->base, win->phy->scl->name, v, RELAXED)
+   REG_SET(x, name, win->base, win->phy->scl->name, v, true)
  #define VOP_SCL_SET_EXT(x, win, name, v) \
-   REG_SET(x, win->base, win->phy->scl->ext->name, v, RELAXED)
+   REG_SET(x, name, win->base, win->phy->scl->ext->name, v, true)
+
  #define VOP_CTRL_SET(x, name, v) \
-   REG_SET(x, 0, (x)->data->ctrl->name, v, NORMAL)
+   REG_SET(x, name, 0, (x)->data->ctrl->name, v, false)
  
  #define VOP_INTR_GET(vop, name) \

vop_read_reg(vop, 0, &vop->data->ctrl->name)
  
-#define VOP_INTR_SET(vop, name, mask, v) \

-   REG_SET_MASK(vop, 0, vop->data->intr->name, mask, v, NORMAL)
+#define VOP_INTR_SET(vop, name, v) \
+   REG_SET(vop, name, 0, vop->data->intr->name, \
+   v, false)
+#define VOP_INTR_SET_MASK(vop, name, mask, v) \
+   REG_SET_MASK(vop

Re: [PATCH v2 3/5] drm/rockchip: vop: move line_flag_num to interrupt registers

2017-07-12 Thread Mark yao

On 2017年07月13日 01:54, Sean Paul wrote:

On Wed, Jul 12, 2017 at 10:03:46AM +0800, Mark Yao wrote:

Again, please add commit message describing the what and why of this change.

You can also add:

Reviewed-by: Sean Paul 



Thanks for the review, will fix it at next version.


Signed-off-by: Mark Yao 
---
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 +-
  drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 4 ++--
  drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 8 
  3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index a9180fd..be208ee 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -507,7 +507,7 @@ static void vop_line_flag_irq_enable(struct vop *vop, int 
line_num)
  
  	spin_lock_irqsave(&vop->irq_lock, flags);
  
-	VOP_CTRL_SET(vop, line_flag_num[0], line_num);

+   VOP_INTR_SET(vop, line_flag_num[0], line_num);
VOP_INTR_SET_TYPE(vop, clear, LINE_FLAG_INTR, 1);
VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1);
  
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h

index e4de890..f64685e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -70,8 +70,6 @@ struct vop_ctrl {
struct vop_reg hpost_st_end;
struct vop_reg vpost_st_end;
  
-	struct vop_reg line_flag_num[2];

-
struct vop_reg global_regdone_en;
struct vop_reg cfg_done;
  };
@@ -79,6 +77,8 @@ struct vop_ctrl {
  struct vop_intr {
const int *intrs;
uint32_t nintrs;
+
+   struct vop_reg line_flag_num[2];
struct vop_reg enable;
struct vop_reg clear;
struct vop_reg status;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c 
b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 7744603..159cedf 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -118,6 +118,7 @@
  static const struct vop_intr rk3036_intr = {
.intrs = rk3036_vop_intrs,
.nintrs = ARRAY_SIZE(rk3036_vop_intrs),
+   .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
.status = VOP_REG(RK3036_INT_STATUS, 0xf, 0),
.enable = VOP_REG(RK3036_INT_STATUS, 0xf, 4),
.clear = VOP_REG(RK3036_INT_STATUS, 0xf, 8),
@@ -131,7 +132,6 @@
.hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
.vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
.vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
-   .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
.cfg_done = VOP_REG(RK3036_REG_CFG_DONE, 0x1, 0),
  };
  
@@ -227,7 +227,6 @@

.vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
.hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
-   .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
.global_regdone_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 11),
.cfg_done = VOP_REG(RK3288_REG_CFG_DONE, 0x1, 0),
  };
@@ -259,6 +258,7 @@
  static const struct vop_intr rk3288_vop_intr = {
.intrs = rk3288_vop_intrs,
.nintrs = ARRAY_SIZE(rk3288_vop_intrs),
+   .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
.status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0),
.enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4),
.clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8),
@@ -295,8 +295,6 @@
.vact_st_end = VOP_REG(RK3399_DSP_VACT_ST_END, 0x1fff1fff, 0),
.hpost_st_end = VOP_REG(RK3399_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3399_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
-   .line_flag_num[0] = VOP_REG(RK3399_LINE_FLAG, 0x, 0),
-   .line_flag_num[1] = VOP_REG(RK3399_LINE_FLAG, 0x, 16),
.cfg_done = VOP_REG_MASK(RK3399_REG_CFG_DONE, 0x1, 0),
  };
  
@@ -313,6 +311,8 @@

  static const struct vop_intr rk3399_vop_intr = {
.intrs = rk3399_vop_intrs,
.nintrs = ARRAY_SIZE(rk3399_vop_intrs),
+   .line_flag_num[0] = VOP_REG(RK3399_LINE_FLAG, 0x, 0),
+   .line_flag_num[1] = VOP_REG(RK3399_LINE_FLAG, 0x, 16),
.status = VOP_REG_MASK(RK3399_INTR_STATUS0, 0x, 0),
.enable = VOP_REG_MASK(RK3399_INTR_EN0, 0x, 0),
.clear = VOP_REG_MASK(RK3399_INTR_CLEAR0, 0x, 0),
--
1.9.1





--
Mark Yao


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


Re: [PATCH v6 4/4] drm/rockchip: Implement CRC debugfs API

2017-03-05 Thread Mark yao

On 2017年03月03日 21:39, Tomeu Vizoso wrote:

Implement the .set_crc_source() callback and call the DP helpers
accordingly to start and stop CRC capture.

This is only done if this CRTC is currently using the eDP connector.

v3: Remove superfluous check on rockchip_crtc_state->output_type

v6: Remove superfluous variable

Signed-off-by: Tomeu Vizoso 
---


looks good for me

Acked-by: Mark Yao 


  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 41 +
  1 file changed, 41 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 94d7b7327ff7..17ab16c4b922 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -19,6 +19,7 @@
  #include 
  #include 
  #include 
+#include 
  
  #include 

  #include 
@@ -,6 +1112,45 @@ static void vop_crtc_destroy_state(struct drm_crtc *crtc,
kfree(s);
  }
  
+static struct drm_connector *vop_get_edp_connector(struct vop *vop)

+{
+   struct drm_crtc *crtc = &vop->crtc;
+   struct drm_connector *connector;
+
+   mutex_lock(&crtc->dev->mode_config.mutex);
+   drm_for_each_connector(connector, crtc->dev)
+   if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+   mutex_unlock(&crtc->dev->mode_config.mutex);
+   return connector;
+   }
+   mutex_unlock(&crtc->dev->mode_config.mutex);
+
+   return NULL;
+}
+
+static int vop_crtc_set_crc_source(struct drm_crtc *crtc,
+  const char *source_name, size_t *values_cnt)
+{
+   struct vop *vop = to_vop(crtc);
+   struct drm_connector *connector;
+   int ret;
+
+   connector = vop_get_edp_connector(vop);
+   if (!connector)
+   return -EINVAL;
+
+   *values_cnt = 3;
+
+   if (source_name && strcmp(source_name, "auto") == 0)
+   ret = analogix_dp_start_crc(connector);
+   else if (!source_name)
+   ret = analogix_dp_stop_crc(connector);
+   else
+   ret = -EINVAL;
+
+   return ret;
+}
+
  static const struct drm_crtc_funcs vop_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip,
@@ -1120,6 +1160,7 @@ static const struct drm_crtc_funcs vop_crtc_funcs = {
.atomic_destroy_state = vop_crtc_destroy_state,
.enable_vblank = vop_crtc_enable_vblank,
.disable_vblank = vop_crtc_disable_vblank,
+   .set_crc_source = vop_crtc_set_crc_source,
  };
  
  static void vop_fb_unref_worker(struct drm_flip_work *work, void *val)



--
Mark Yao


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


Re: [PATCH] drm/rockchip: Refactor the component match logic.

2017-03-09 Thread Mark yao
m_match_add(struct device *dev)
 {
-	struct device_node *ep, *remote;
+	struct component_match *match = NULL;
+	int i;
 
-	for_each_child_of_node(port, ep) {
-		remote = of_graph_get_remote_port_parent(ep);
-		if (!remote || !of_device_is_available(remote)) {
-			of_node_put(remote);
-			continue;
-		} else if (!of_device_is_available(remote->parent)) {
-			dev_warn(dev, "parent device of %s is not available\n",
- remote->full_name);
-			of_node_put(remote);
-			continue;
-		}
+	for (i = 0; i < ARRAY_SIZE(rockchip_drm_comp_drvs); i++) {
+		struct platform_driver *drv = rockchip_drm_comp_drvs[i];
+		struct device *p = NULL, *d;
 
-		drm_of_component_match_add(dev, match, compare_of, remote);
-		of_node_put(remote);
+		while ((d = bus_find_device(&platform_bus_type, p, &drv->driver,
+	(void *)platform_bus_type.match))) {
+			put_device(p);
+			component_match_add(dev, &match, compare_dev, d);
+			p = d;
+		}
+		put_device(p);
 	}
+
+	return match ?: ERR_PTR(-ENODEV);
 }
 
 static const struct component_master_ops rockchip_drm_ops = {
@@ -391,21 +406,16 @@ static const struct component_master_ops rockchip_drm_ops = {
 	.unbind = rockchip_drm_unbind,
 };
 
-static int rockchip_drm_platform_probe(struct platform_device *pdev)
+static int rockchip_drm_platform_of_probe(struct device *dev)
 {
-	struct device *dev = &pdev->dev;
-	struct component_match *match = NULL;
 	struct device_node *np = dev->of_node;
 	struct device_node *port;
+	bool found = false;
 	int i;
 
 	if (!np)
 		return -ENODEV;
-	/*
-	 * Bind the crtc ports first, so that
-	 * drm_of_find_possible_crtcs called from encoder .bind callbacks
-	 * works as expected.
-	 */
+
 	for (i = 0;; i++) {
 		struct device_node *iommu;
 
@@ -429,9 +439,9 @@ static int rockchip_drm_platform_probe(struct platform_device *pdev)
 			is_support_iommu = false;
 		}
 
+		found = true;
+
 		of_node_put(iommu);
-		drm_of_component_match_add(dev, &match, compare_of,
-	   port->parent);
 		of_node_put(port);
 	}
 
@@ -440,27 +450,27 @@ static int rockchip_drm_platform_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	if (!match) {
+	if (!found) {
 		dev_err(dev, "No available vop found for display-subsystem.\n");
 		return -ENODEV;
 	}
-	/*
-	 * For each bound crtc, bind the encoders attached to its
-	 * remote endpoint.
-	 */
-	for (i = 0;; i++) {
-		port = of_parse_phandle(np, "ports", i);
-		if (!port)
-			break;
 
-		if (!of_device_is_available(port->parent)) {
-			of_node_put(port);
-			continue;
-		}
+	return 0;
+}
 
-		rockchip_add_endpoints(dev, &match, port);
-		of_node_put(port);
-	}
+static int rockchip_drm_platform_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct component_match *match = NULL;
+	int ret;
+
+	ret = rockchip_drm_platform_of_probe(dev);
+	if (ret)
+		return ret;
+
+	match = rockchip_drm_match_add(dev);
+	if (IS_ERR(match))
+		return PTR_ERR(match);
 
 	return component_master_add_with_match(dev, &rockchip_drm_ops, match);
 }
@@ -488,7 +498,57 @@ static struct platform_driver rockchip_drm_platform_driver = {
 	},
 };
 
-module_platform_driver(rockchip_drm_platform_driver);
+static void rockchip_drm_unregister_drivers(void)
+{
+	int i;
+
+	for (i = ARRAY_SIZE(rockchip_drm_comp_drvs) - 1; i >= 0; i--)
+		platform_driver_unregister(rockchip_drm_comp_drvs[i]);
+}
+
+static int rockchip_drm_register_drivers(void)
+{
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(rockchip_drm_comp_drvs); i++) {
+		ret = platform_driver_register(rockchip_drm_comp_drvs[i]);
+		if (ret)
+			goto fail;
+	}
+	return 0;
+fail:
+	rockchip_drm_unregister_drivers();
+	return ret;
+}
+
+static int __init rockchip_drm_init(void)
+{
+	int ret;
+
+	ret = rockchip_drm_register_drivers();
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&rockchip_drm_platform_driver);
+	if (ret)
+		goto err_unreg_drivers;
+
+	return 0;
+
+err_unreg_drivers:
+	rockchip_drm_unregister_drivers();
+	return ret;
+}
+
+static void __exit rockchip_drm_fini(void)
+{
+	platform_driver_unregister(&rockchip_drm_platform_driver);
+
+	rockchip_drm_unregister_drivers();
+}
+
+module_init(rockchip_drm_init);
+module_exit(rockchip_drm_fini);
 
 MODULE_AUTHOR("Mark Yao ");
 MODULE_DESCRIPTION("ROCKCHIP DRM Driver");
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index adc3930..f46e1d0 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -79,4 +79,10 @@ void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
 int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
 unsigned int mstimeout);
 
+extern struct platform_driver cdn_dp_driver;
+extern struct platform_driver dw_hdmi_rockchip_pltfm_driver;
+extern struct platform_driver dw_mipi_dsi_driver;
+extern struct platform_drive

[PATCH] drm/rockchip: Correct vop out_mode configure

2017-05-27 Thread Mark Yao
Force vop output mode on encoder driver seem not a good idea,

EDP, HDMI, DisplayPort all have 10bit input on rk3399,
On non-10bit vop, vop 8bit output bit[0-7] connect to the
encoder high 8bit [2-9].

So force RGB10 to RGB888 on vop driver would be better.

And another problem, EDP check crtc id on atomic_check,
but encoder maybe NULL, so out_mode configure would fail,
it cause edp no display.

Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 12 
 drivers/gpu/drm/rockchip/cdn-dp-core.c  |  9 ++---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  8 
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |  3 +++
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c |  2 ++
 5 files changed, 15 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 1bccd82..9606121 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -237,8 +237,6 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder 
*encoder,
  struct drm_connector_state *conn_state)
 {
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
-   struct rockchip_dp_device *dp = to_dp(encoder);
-   int ret;
 
/*
 * The hardware IC designed that VOP must output the RGB10 video
@@ -250,16 +248,6 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder 
*encoder,
 
s->output_mode = ROCKCHIP_OUT_MODE_;
s->output_type = DRM_MODE_CONNECTOR_eDP;
-   if (dp->data->chip_type == RK3399_EDP) {
-   /*
-* For RK3399, VOP Lit must code the out mode to RGB888,
-* VOP Big must code the out mode to RGB10.
-*/
-   ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node,
-   encoder);
-   if (ret > 0)
-   s->output_mode = ROCKCHIP_OUT_MODE_P888;
-   }
 
return 0;
 }
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index a2169dd..14fa1f8 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -615,7 +615,6 @@ static void cdn_dp_encoder_enable(struct drm_encoder 
*encoder)
 {
struct cdn_dp_device *dp = encoder_to_dp(encoder);
int ret, val;
-   struct rockchip_crtc_state *state;
 
ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
if (ret < 0) {
@@ -625,14 +624,10 @@ static void cdn_dp_encoder_enable(struct drm_encoder 
*encoder)
 
DRM_DEV_DEBUG_KMS(dp->dev, "vop %s output to cdn-dp\n",
  (ret) ? "LIT" : "BIG");
-   state = to_rockchip_crtc_state(encoder->crtc->state);
-   if (ret) {
+   if (ret)
val = DP_SEL_VOP_LIT | (DP_SEL_VOP_LIT << 16);
-   state->output_mode = ROCKCHIP_OUT_MODE_P888;
-   } else {
+   else
val = DP_SEL_VOP_LIT << 16;
-   state->output_mode = ROCKCHIP_OUT_MODE_;
-   }
 
ret = cdn_dp_grf_write(dp, GRF_SOC_CON9, val);
if (ret)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 40a5e6e..c83f481 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -874,6 +874,7 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
 static void vop_crtc_enable(struct drm_crtc *crtc)
 {
struct vop *vop = to_vop(crtc);
+   const struct vop_data *vop_data = vop->data;
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
u16 hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
@@ -966,6 +967,13 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
DRM_DEV_ERROR(vop->dev, "unsupported connector_type [%d]\n",
  s->output_type);
}
+
+   /*
+* if vop is not support RGB10 output, need force RGB10 to RGB888.
+*/
+   if (s->output_mode == ROCKCHIP_OUT_MODE_ &&
+   !(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10))
+   s->output_mode = ROCKCHIP_OUT_MODE_P888;
VOP_CTRL_SET(vop, out_mode, s->output_mode);
 
VOP_CTRL_SET(vop, htotal_pw, (htotal << 16) | hsync_len);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 5a4faa85..9979fd0 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -142,6 +142,9 @@ str

Re: [PATCH] drm/rockchip: gem: add the lacks lock and trivial changes

2017-05-30 Thread Mark yao

On 2017年05月31日 10:14, Caesar Wang wrote:

As the allocation and free buffer that need to add mutex lock for drm mm,
but it lacks the locking on error path in rockchip_gem_iommu_map().
Also, the trivial changes like The comment should be  placed in the
kerneldoc and unused blank line.

Signed-off-by: Caesar Wang 


Looks good.

Reviewed-by: Mark Yao 


---

  drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 2 +-
  drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 5 +++--
  2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 47905fa..c7e96b8 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -45,13 +45,13 @@ struct rockchip_crtc_state {
   *
   * @crtc: array of enabled CRTCs, used to map from "pipe" to drm_crtc.
   * @num_pipe: number of pipes for this device.
+ * @mm_lock: protect drm_mm on multi-threads.
   */
  struct rockchip_drm_private {
struct drm_fb_helper fbdev_helper;
struct drm_gem_object *fbdev_bo;
struct drm_atomic_state *state;
struct iommu_domain *domain;
-   /* protect drm_mm on multi-threads */
struct mutex mm_lock;
struct drm_mm mm;
struct list_head psr_list;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index df9e570..b74ac71 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -29,12 +29,11 @@ static int rockchip_gem_iommu_map(struct 
rockchip_gem_object *rk_obj)
ssize_t ret;
  
  	mutex_lock(&private->mm_lock);

-
ret = drm_mm_insert_node_generic(&private->mm, &rk_obj->mm,
 rk_obj->base.size, PAGE_SIZE,
 0, 0);
-
mutex_unlock(&private->mm_lock);
+
if (ret < 0) {
DRM_ERROR("out of I/O virtual memory: %zd\n", ret);
return ret;
@@ -56,7 +55,9 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object 
*rk_obj)
return 0;
  
  err_remove_node:

+   mutex_lock(&private->mm_lock);
drm_mm_remove_node(&rk_obj->mm);
+   mutex_unlock(&private->mm_lock);
  
  	return ret;

  }



--
Mark Yao


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


  1   2   3   4   5   6   >