Re: [PATCH v3 11/12] samples: vfio-mdev: constify fb ops

2019-12-09 Thread Jani Nikula
On Tue, 10 Dec 2019, Kirti Wankhede  wrote:
> On 12/9/2019 7:31 PM, Jani Nikula wrote:
>> On Tue, 03 Dec 2019, Jani Nikula  wrote:
>>> Now that the fbops member of struct fb_info is const, we can start
>>> making the ops const as well.
>>>
>>> v2: fix typo (Christophe de Dinechin)
>>>
>>> Cc: Kirti Wankhede 
>>> Cc: k...@vger.kernel.org
>>> Reviewed-by: Daniel Vetter 
>>> Signed-off-by: Jani Nikula 
>> 
>> Kirti, may I have your ack to merge this through drm-misc please?
>> 
>> BR,
>> Jani.
>> 
>>> ---
>>>   samples/vfio-mdev/mdpy-fb.c | 2 +-
>>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/samples/vfio-mdev/mdpy-fb.c b/samples/vfio-mdev/mdpy-fb.c
>>> index 2719bb259653..21dbf63d6e41 100644
>>> --- a/samples/vfio-mdev/mdpy-fb.c
>>> +++ b/samples/vfio-mdev/mdpy-fb.c
>>> @@ -86,7 +86,7 @@ static void mdpy_fb_destroy(struct fb_info *info)
>>> iounmap(info->screen_base);
>>>   }
>>>   
>>> -static struct fb_ops mdpy_fb_ops = {
>>> +static const struct fb_ops mdpy_fb_ops = {
>>> .owner  = THIS_MODULE,
>>> .fb_destroy = mdpy_fb_destroy,
>>> .fb_setcolreg   = mdpy_fb_setcolreg,
>> 
>
> Acked-by : Kirti Wankhede 

Thanks, pushed to drm-misc-next.

BR,
Jani.

-- 
Jani Nikula, Intel Open Source Graphics Center
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/komeda: Correct d71 register block counting

2019-12-09 Thread james qian wang (Arm Technology China)
Per HW, d71->num_blocks includes reserved blocks but no PERIPH block,
correct the block counting accordingly.
D71 happens to only have one reserved block and periph block, which
hides this counting error.

Signed-off-by: james qian wang (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index 822b23a1ce75..d53f95dea0a1 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -414,8 +414,11 @@ static int d71_enum_resources(struct komeda_dev *mdev)
d71->pipes[i] = to_d71_pipeline(pipe);
}
 
-   /* loop the register blks and probe */
-   i = 2; /* exclude GCU and PERIPH */
+   /* loop the register blks and probe.
+* NOTE: d71->num_blocks includes reserved blocks.
+* d71->num_blocks = GCU + valid blocks + reserved blocks
+*/
+   i = 1; /* exclude GCU */
offset = D71_BLOCK_SIZE; /* skip GCU */
while (i < d71->num_blocks) {
blk_base = mdev->reg_base + (offset >> 2);
@@ -425,9 +428,9 @@ static int d71_enum_resources(struct komeda_dev *mdev)
err = d71_probe_block(d71, , blk_base);
if (err)
goto err_cleanup;
-   i++;
}
 
+   i++;
offset += D71_BLOCK_SIZE;
}
 
-- 
2.20.1

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


Re: [PATCH v8 20/26] powerpc: book3s64: convert to pin_user_pages() and put_user_page()

2019-12-09 Thread John Hubbard

On 12/9/19 3:46 PM, John Hubbard wrote:

On 12/9/19 2:53 PM, John Hubbard wrote:
...

@@ -212,10 +211,9 @@ static void mm_iommu_unpin(struct 
mm_iommu_table_group_mem_t *mem)
if (!page)
continue;
  
-		if (mem->hpas[i] & MM_IOMMU_TABLE_GROUP_PAGE_DIRTY)

-   SetPageDirty(page);
+   put_user_pages_dirty_lock(, 1,
+   mem->hpas[i] & MM_IOMMU_TABLE_GROUP_PAGE_DIRTY);
  
-		put_page(page);



Correction: this is somehow missing the fixes that resulted from Jan Kara's 
review (he
noted that we can't take a page lock in this context). I must have picked up the
wrong version of it, when I rebased for -rc1.



Andrew, given that the series is now in -mm, what's the preferred way for me to 
fix this?
Send a v9 version of the whole series? Or something else?

I'm still learning the ropes...

thanks,
--
John Hubbard
NVIDIA


Will fix in the next version (including the commit description). Here's what the
corrected hunk will look like:

@@ -215,7 +214,8 @@ static void mm_iommu_unpin(struct 
mm_iommu_table_group_mem_t *mem)
 if (mem->hpas[i] & MM_IOMMU_TABLE_GROUP_PAGE_DIRTY)
 SetPageDirty(page);
  
-   put_page(page);

+   put_user_page(page);
+
 mem->hpas[i] = 0;
 }
  }


thanks,


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


Re: [PATCH v8 17/26] media/v4l2-core: set pages dirty upon releasing DMA buffers

2019-12-09 Thread John Hubbard

On 12/9/19 4:56 PM, Andrew Morton wrote:

On Mon, 9 Dec 2019 14:53:35 -0800 John Hubbard  wrote:


After DMA is complete, and the device and CPU caches are synchronized,
it's still required to mark the CPU pages as dirty, if the data was
coming from the device. However, this driver was just issuing a
bare put_page() call, without any set_page_dirty*() call.

Fix the problem, by calling set_page_dirty_lock() if the CPU pages
were potentially receiving data from the device.

Reviewed-by: Christoph Hellwig 
Acked-by: Hans Verkuil 
Cc: Mauro Carvalho Chehab 
Cc: 


What are the user-visible effects of this change?


I'll have to defer to Hans or other experts, because I merely spotted
this by reading the code.



As it's cc:stable I'd normally send this to Linus within 1-2 weeks, or
sooner.  Please confirm that this is a standalone fix, independent of
the rest of this series.




Yes, this is a stand-alone fix. Of course, as part of this series, the
put_page() gets converted to put_user_pages_dirty() in the next patch,
and that in turn gets renamed to unpin_user_pages_dirty() in a later
patch. Just so we keep that in mind when moving patches around.


thanks,
--
John Hubbard
NVIDIA
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 0/7] drm/mediatek: fix cursor issue and apply CMDQ in MTK DRM

2019-12-09 Thread Bibby Hsieh
The CMDQ (Command Queue) in MT8183 is used to help update all
relevant display controller registers with critical time limation.
This patch add cmdq interface in ddp_comp interface, let all
ddp_comp interface can support cpu/cmdq function at the same time.

These patches also can fixup cursor moving is not smooth
when heavy load in webgl.

This patch depends on ptach:
add drm support for MT8183
(https://patchwork.kernel.org/cover/11121519/)
support gce on mt8183 platform
(https://patchwork.kernel.org/cover/11255147/)
drm/mediatek: Check return value of mtk_drm_ddp_comp_for_plane
(https://lore.kernel.org/patchwork/patch/1154517/)

Changes since v4:
 - rebase to Linux 5.5-rc1
 - add fixes tag

Changes since v3:
 - remove redundant code and variable

Changes since v2:
 - move some changes to another patch
 - disable layer in atomic_disable()

Changes since v1:
 - remove redundant code
 - merge the duplicate code
 - use async instead of cursor

Changes since v0:
 - remove redundant code
 - remove patch
   "drm/mediatek: fix atomic_state reference counting"
   After remove this patch, the issue we met before is gone.
   So I do not add any extra code to do something.

Bibby Hsieh (7):
  drm/mediatek: use DRM core's atomic commit helper
  drm/mediatek: handle events when enabling/disabling crtc
  drm/mediatek: update cursors by using async atomic update
  drm/mediatek: disable all the planes in atomic_disable
  drm/mediatek: remove unused external function
  drm/mediatek: support CMDQ interface in ddp component
  drm/mediatek: apply CMDQ control flow

 drivers/gpu/drm/mediatek/mtk_disp_color.c   |   7 +-
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c |  67 
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c|  43 ++---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 165 
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h |   2 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 131 
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  47 +++---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |  86 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h  |   7 -
 drivers/gpu/drm/mediatek/mtk_drm_plane.c|  47 ++
 drivers/gpu/drm/mediatek/mtk_drm_plane.h|   2 +
 11 files changed, 380 insertions(+), 224 deletions(-)

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


[PATCH v5 1/7] drm/mediatek: use DRM core's atomic commit helper

2019-12-09 Thread Bibby Hsieh
The DRM core atomic helper now supports asynchronous commits natively.
The custom drm implementation isn't needed anymore, remove it.

Signed-off-by: Bibby Hsieh 
Reviewed-by: CK Hu 
---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 86 ++
 drivers/gpu/drm/mediatek/mtk_drm_drv.h |  7 ---
 2 files changed, 5 insertions(+), 88 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index c2030c92a78e..e004ef342846 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -36,89 +36,14 @@
 #define DRIVER_MAJOR 1
 #define DRIVER_MINOR 0
 
-static void mtk_atomic_schedule(struct mtk_drm_private *private,
-   struct drm_atomic_state *state)
-{
-   private->commit.state = state;
-   schedule_work(>commit.work);
-}
-
-static void mtk_atomic_complete(struct mtk_drm_private *private,
-   struct drm_atomic_state *state)
-{
-   struct drm_device *drm = private->drm;
-
-   drm_atomic_helper_wait_for_fences(drm, state, false);
-
-   /*
-* Mediatek drm supports runtime PM, so plane registers cannot be
-* written when their crtc is disabled.
-*
-* The comment for drm_atomic_helper_commit states:
-* For drivers supporting runtime PM the recommended sequence is
-*
-* drm_atomic_helper_commit_modeset_disables(dev, state);
-* drm_atomic_helper_commit_modeset_enables(dev, state);
-* drm_atomic_helper_commit_planes(dev, state,
-* DRM_PLANE_COMMIT_ACTIVE_ONLY);
-*
-* See the kerneldoc entries for these three functions for more details.
-*/
-   drm_atomic_helper_commit_modeset_disables(drm, state);
-   drm_atomic_helper_commit_modeset_enables(drm, state);
-   drm_atomic_helper_commit_planes(drm, state,
-   DRM_PLANE_COMMIT_ACTIVE_ONLY);
-
-   drm_atomic_helper_wait_for_vblanks(drm, state);
-
-   drm_atomic_helper_cleanup_planes(drm, state);
-   drm_atomic_state_put(state);
-}
-
-static void mtk_atomic_work(struct work_struct *work)
-{
-   struct mtk_drm_private *private = container_of(work,
-   struct mtk_drm_private, commit.work);
-
-   mtk_atomic_complete(private, private->commit.state);
-}
-
-static int mtk_atomic_commit(struct drm_device *drm,
-struct drm_atomic_state *state,
-bool async)
-{
-   struct mtk_drm_private *private = drm->dev_private;
-   int ret;
-
-   ret = drm_atomic_helper_prepare_planes(drm, state);
-   if (ret)
-   return ret;
-
-   mutex_lock(>commit.lock);
-   flush_work(>commit.work);
-
-   ret = drm_atomic_helper_swap_state(state, true);
-   if (ret) {
-   mutex_unlock(>commit.lock);
-   drm_atomic_helper_cleanup_planes(drm, state);
-   return ret;
-   }
-
-   drm_atomic_state_get(state);
-   if (async)
-   mtk_atomic_schedule(private, state);
-   else
-   mtk_atomic_complete(private, state);
-
-   mutex_unlock(>commit.lock);
-
-   return 0;
-}
+static const struct drm_mode_config_helper_funcs mtk_drm_mode_config_helpers = 
{
+   .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
+};
 
 static const struct drm_mode_config_funcs mtk_drm_mode_config_funcs = {
.fb_create = mtk_drm_mode_fb_create,
.atomic_check = drm_atomic_helper_check,
-   .atomic_commit = mtk_atomic_commit,
+   .atomic_commit = drm_atomic_helper_commit,
 };
 
 static const enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = {
@@ -265,6 +190,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
drm->mode_config.max_width = 4096;
drm->mode_config.max_height = 4096;
drm->mode_config.funcs = _drm_mode_config_funcs;
+   drm->mode_config.helper_private = _drm_mode_config_helpers;
 
ret = component_bind_all(drm->dev, drm);
if (ret)
@@ -540,8 +466,6 @@ static int mtk_drm_probe(struct platform_device *pdev)
if (!private)
return -ENOMEM;
 
-   mutex_init(>commit.lock);
-   INIT_WORK(>commit.work, mtk_atomic_work);
private->data = of_device_get_match_data(dev);
 
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index b6a82728d563..9f4ce60174f6 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -46,13 +46,6 @@ struct mtk_drm_private {
struct device_node *comp_node[DDP_COMPONENT_ID_MAX];
struct mtk_ddp_comp *ddp_comp[DDP_COMPONENT_ID_MAX];
const struct mtk_mmsys_driver_data *data;
-
-   struct {
-   struct drm_atomic_state *state;
-  

[PATCH v5 3/7] drm/mediatek: update cursors by using async atomic update

2019-12-09 Thread Bibby Hsieh
Support to async updates of cursors by using the new atomic
interface for that.

Signed-off-by: Bibby Hsieh 
Reviewed-by: CK Hu 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  | 98 +++-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h  |  2 +
 drivers/gpu/drm/mediatek/mtk_drm_plane.c | 47 
 drivers/gpu/drm/mediatek/mtk_drm_plane.h |  2 +
 4 files changed, 128 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index af097b7db72f..b771ee05968b 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -41,12 +41,16 @@ struct mtk_drm_crtc {
struct drm_plane*planes;
unsigned intlayer_nr;
boolpending_planes;
+   boolpending_async_planes;
 
void __iomem*config_regs;
const struct mtk_mmsys_reg_data *mmsys_reg_data;
struct mtk_disp_mutex   *mutex;
unsigned intddp_comp_nr;
struct mtk_ddp_comp **ddp_comp;
+
+   /* lock for display hardware access */
+   struct mutexhw_lock;
 };
 
 struct mtk_crtc_state {
@@ -412,6 +416,63 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
}
mtk_crtc->pending_planes = false;
}
+
+   if (mtk_crtc->pending_async_planes) {
+   for (i = 0; i < mtk_crtc->layer_nr; i++) {
+   struct drm_plane *plane = _crtc->planes[i];
+   struct mtk_plane_state *plane_state;
+
+   plane_state = to_mtk_plane_state(plane->state);
+
+   if (!plane_state->pending.async_config)
+   continue;
+
+   comp = mtk_drm_ddp_comp_for_plane(crtc, plane,
+ _layer);
+
+   if (comp)
+   mtk_ddp_comp_layer_config(comp, local_layer,
+ plane_state);
+   plane_state->pending.async_config = false;
+   }
+   mtk_crtc->pending_async_planes = false;
+   }
+}
+
+static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc *mtk_crtc)
+{
+   struct drm_crtc *crtc = _crtc->base;
+   struct mtk_drm_private *priv = crtc->dev->dev_private;
+   unsigned int pending_planes = 0, pending_async_planes = 0;
+   int i;
+
+   mutex_lock(_crtc->hw_lock);
+   for (i = 0; i < mtk_crtc->layer_nr; i++) {
+   struct drm_plane *plane = _crtc->planes[i];
+   struct mtk_plane_state *plane_state;
+
+   plane_state = to_mtk_plane_state(plane->state);
+   if (plane_state->pending.dirty) {
+   plane_state->pending.config = true;
+   plane_state->pending.dirty = false;
+   pending_planes |= BIT(i);
+   } else if (plane_state->pending.async_dirty) {
+   plane_state->pending.async_config = true;
+   plane_state->pending.async_dirty = false;
+   pending_async_planes |= BIT(i);
+   }
+   }
+   if (pending_planes)
+   mtk_crtc->pending_planes = true;
+   if (pending_async_planes)
+   mtk_crtc->pending_async_planes = true;
+
+   if (priv->data->shadow_register) {
+   mtk_disp_mutex_acquire(mtk_crtc->mutex);
+   mtk_crtc_ddp_config(crtc);
+   mtk_disp_mutex_release(mtk_crtc->mutex);
+   }
+   mutex_unlock(_crtc->hw_lock);
 }
 
 int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
@@ -426,6 +487,20 @@ int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct 
drm_plane *plane,
return 0;
 }
 
+void mtk_drm_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
+  struct drm_plane_state *new_state)
+{
+   struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+   const struct drm_plane_helper_funcs *plane_helper_funcs =
+   plane->helper_private;
+
+   if (!mtk_crtc->enabled)
+   return;
+
+   plane_helper_funcs->atomic_update(plane, new_state);
+   mtk_drm_crtc_hw_config(mtk_crtc);
+}
+
 static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
   struct drm_crtc_state *old_state)
 {
@@ -507,34 +582,14 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc 
*crtc,
  struct drm_crtc_state *old_crtc_state)
 {
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
-   struct mtk_drm_private *priv = crtc->dev->dev_private;
-   unsigned int pending_planes = 0;
int i;
 
if 

[PATCH v5 5/7] drm/mediatek: remove unused external function

2019-12-09 Thread Bibby Hsieh
layer_on and layer_off both are unused external function,
remove them from mtk_ddp_comp_funcs structure.

Signed-off-by: Bibby Hsieh 
Reviewed-by: CK Hu 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c |  2 --
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 16 
 2 files changed, 18 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 722a5adb79dc..8a32248671c3 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -314,8 +314,6 @@ static const struct mtk_ddp_comp_funcs mtk_disp_ovl_funcs = 
{
.disable_vblank = mtk_ovl_disable_vblank,
.supported_rotations = mtk_ovl_supported_rotations,
.layer_nr = mtk_ovl_layer_nr,
-   .layer_on = mtk_ovl_layer_on,
-   .layer_off = mtk_ovl_layer_off,
.layer_check = mtk_ovl_layer_check,
.layer_config = mtk_ovl_layer_config,
.bgclr_in_on = mtk_ovl_bgclr_in_on,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h 
b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 19a955ab0748..dbfb90e9b9cf 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -81,8 +81,6 @@ struct mtk_ddp_comp_funcs {
void (*unprepare)(struct mtk_ddp_comp *comp);
unsigned int (*supported_rotations)(struct mtk_ddp_comp *comp);
unsigned int (*layer_nr)(struct mtk_ddp_comp *comp);
-   void (*layer_on)(struct mtk_ddp_comp *comp, unsigned int idx);
-   void (*layer_off)(struct mtk_ddp_comp *comp, unsigned int idx);
int (*layer_check)(struct mtk_ddp_comp *comp,
   unsigned int idx,
   struct mtk_plane_state *state);
@@ -165,20 +163,6 @@ static inline unsigned int mtk_ddp_comp_layer_nr(struct 
mtk_ddp_comp *comp)
return 0;
 }
 
-static inline void mtk_ddp_comp_layer_on(struct mtk_ddp_comp *comp,
-unsigned int idx)
-{
-   if (comp->funcs && comp->funcs->layer_on)
-   comp->funcs->layer_on(comp, idx);
-}
-
-static inline void mtk_ddp_comp_layer_off(struct mtk_ddp_comp *comp,
- unsigned int idx)
-{
-   if (comp->funcs && comp->funcs->layer_off)
-   comp->funcs->layer_off(comp, idx);
-}
-
 static inline int mtk_ddp_comp_layer_check(struct mtk_ddp_comp *comp,
   unsigned int idx,
   struct mtk_plane_state *state)
-- 
2.18.0
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 7/7] drm/mediatek: apply CMDQ control flow

2019-12-09 Thread Bibby Hsieh
Unlike other SoCs, MT8183 does not have "shadow"
registers for performaing an atomic video mode
set or page flip at vblank/vsync.

The CMDQ (Commend Queue) in MT8183 is used to help
update all relevant display controller registers
with critical time limation.

Signed-off-by: YT Shen 
Signed-off-by: CK Hu 
Signed-off-by: Philipp Zabel 
Signed-off-by: Bibby Hsieh 
Signed-off-by: Yongqiang Niu 
Reviewed-by: CK Hu 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 56 +
 1 file changed, 49 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 5b3e24a7ef6c..ca4fc4735f9a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -12,6 +12,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include "mtk_drm_drv.h"
 #include "mtk_drm_crtc.h"
@@ -43,6 +45,9 @@ struct mtk_drm_crtc {
boolpending_planes;
boolpending_async_planes;
 
+   struct cmdq_client  *cmdq_client;
+   u32 cmdq_event;
+
void __iomem*config_regs;
const struct mtk_mmsys_reg_data *mmsys_reg_data;
struct mtk_disp_mutex   *mutex;
@@ -234,6 +239,13 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct 
drm_crtc *crtc,
return NULL;
 }
 
+#if IS_ENABLED(CONFIG_MTK_CMDQ)
+static void ddp_cmdq_cb(struct cmdq_cb_data data)
+{
+   cmdq_pkt_destroy(data.data);
+}
+#endif
+
 static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
 {
struct drm_crtc *crtc = _crtc->base;
@@ -375,7 +387,8 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc 
*mtk_crtc)
}
 }
 
-static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
+static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
+   struct cmdq_pkt *cmdq_handle)
 {
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
@@ -391,7 +404,8 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
if (state->pending_config) {
mtk_ddp_comp_config(comp, state->pending_width,
state->pending_height,
-   state->pending_vrefresh, 0, NULL);
+   state->pending_vrefresh, 0,
+   cmdq_handle);
 
state->pending_config = false;
}
@@ -411,7 +425,8 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
 
if (comp)
mtk_ddp_comp_layer_config(comp, local_layer,
- plane_state, NULL);
+ plane_state,
+ cmdq_handle);
plane_state->pending.config = false;
}
mtk_crtc->pending_planes = false;
@@ -432,7 +447,8 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
 
if (comp)
mtk_ddp_comp_layer_config(comp, local_layer,
- plane_state, NULL);
+ plane_state,
+ cmdq_handle);
plane_state->pending.async_config = false;
}
mtk_crtc->pending_async_planes = false;
@@ -441,6 +457,7 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
 
 static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc *mtk_crtc)
 {
+   struct cmdq_pkt *cmdq_handle;
struct drm_crtc *crtc = _crtc->base;
struct mtk_drm_private *priv = crtc->dev->dev_private;
unsigned int pending_planes = 0, pending_async_planes = 0;
@@ -469,9 +486,18 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
*mtk_crtc)
 
if (priv->data->shadow_register) {
mtk_disp_mutex_acquire(mtk_crtc->mutex);
-   mtk_crtc_ddp_config(crtc);
+   mtk_crtc_ddp_config(crtc, NULL);
mtk_disp_mutex_release(mtk_crtc->mutex);
}
+#if IS_ENABLED(CONFIG_MTK_CMDQ)
+   if (mtk_crtc->cmdq_client) {
+   cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
+   cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
+   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
+   mtk_crtc_ddp_config(crtc, cmdq_handle);
+   cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
+   }
+#endif
mutex_unlock(_crtc->hw_lock);
 }
 
@@ -640,8 +666,8 @@ void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct 
mtk_ddp_comp *comp)
struct mtk_drm_crtc *mtk_crtc 

[PATCH v5 4/7] drm/mediatek: disable all the planes in atomic_disable

2019-12-09 Thread Bibby Hsieh
Under shadow register case, we do not disable all the plane before
disable all the hardwares. Fix it.

Fixes: 9dc84e98a31f ("drm/mediatek: add shadow register support")

Signed-off-by: Bibby Hsieh 
Reviewed-by: CK Hu 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index b771ee05968b..adf072fb4ae3 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -547,6 +547,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc 
*crtc,
}
mtk_crtc->pending_planes = true;
 
+   mtk_drm_crtc_hw_config(mtk_crtc);
/* Wait for planes to be disabled */
drm_crtc_wait_one_vblank(crtc);
 
-- 
2.18.0
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 6/7] drm/mediatek: support CMDQ interface in ddp component

2019-12-09 Thread Bibby Hsieh
The CMDQ (Command Queue) in MT8183 is used to help
update all relevant display controller registers
with critical time limation.
This patch add cmdq interface in ddp_comp interface,
let all ddp_comp interface can support cpu/cmdq function
at the same time.

Signed-off-by: YT Shen 
Signed-off-by: CK Hu 
Signed-off-by: Philipp Zabel 
Signed-off-by: Bibby Hsieh 
Signed-off-by: Yongqiang Niu 
Reviewed-by: CK Hu 
---
 drivers/gpu/drm/mediatek/mtk_disp_color.c   |   7 +-
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c |  65 +-
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c|  43 ---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  10 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 131 +++-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  31 +++--
 6 files changed, 193 insertions(+), 94 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c 
b/drivers/gpu/drm/mediatek/mtk_disp_color.c
index 59de2a46aa49..6fb0d6983a4a 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_color.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "mtk_drm_crtc.h"
 #include "mtk_drm_ddp_comp.h"
@@ -45,12 +46,12 @@ static inline struct mtk_disp_color *comp_to_color(struct 
mtk_ddp_comp *comp)
 
 static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w,
 unsigned int h, unsigned int vrefresh,
-unsigned int bpc)
+unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
 {
struct mtk_disp_color *color = comp_to_color(comp);
 
-   writel(w, comp->regs + DISP_COLOR_WIDTH(color));
-   writel(h, comp->regs + DISP_COLOR_HEIGHT(color));
+   mtk_ddp_write(cmdq_pkt, w, comp, DISP_COLOR_WIDTH(color));
+   mtk_ddp_write(cmdq_pkt, h, comp, DISP_COLOR_HEIGHT(color));
 }
 
 static void mtk_color_start(struct mtk_ddp_comp *comp)
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 8a32248671c3..649e371dd9b7 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "mtk_drm_crtc.h"
 #include "mtk_drm_ddp_comp.h"
@@ -125,14 +126,15 @@ static void mtk_ovl_stop(struct mtk_ddp_comp *comp)
 
 static void mtk_ovl_config(struct mtk_ddp_comp *comp, unsigned int w,
   unsigned int h, unsigned int vrefresh,
-  unsigned int bpc)
+  unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
 {
if (w != 0 && h != 0)
-   writel_relaxed(h << 16 | w, comp->regs + DISP_REG_OVL_ROI_SIZE);
-   writel_relaxed(0x0, comp->regs + DISP_REG_OVL_ROI_BGCLR);
+   mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, comp,
+ DISP_REG_OVL_ROI_SIZE);
+   mtk_ddp_write_relaxed(cmdq_pkt, 0x0, comp, DISP_REG_OVL_ROI_BGCLR);
 
-   writel(0x1, comp->regs + DISP_REG_OVL_RST);
-   writel(0x0, comp->regs + DISP_REG_OVL_RST);
+   mtk_ddp_write(cmdq_pkt, 0x1, comp, DISP_REG_OVL_RST);
+   mtk_ddp_write(cmdq_pkt, 0x0, comp, DISP_REG_OVL_RST);
 }
 
 static unsigned int mtk_ovl_layer_nr(struct mtk_ddp_comp *comp)
@@ -176,16 +178,16 @@ static int mtk_ovl_layer_check(struct mtk_ddp_comp *comp, 
unsigned int idx,
return 0;
 }
 
-static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx)
+static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx,
+struct cmdq_pkt *cmdq_pkt)
 {
-   unsigned int reg;
unsigned int gmc_thrshd_l;
unsigned int gmc_thrshd_h;
unsigned int gmc_value;
struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
 
-   writel(0x1, comp->regs + DISP_REG_OVL_RDMA_CTRL(idx));
-
+   mtk_ddp_write(cmdq_pkt, 0x1, comp,
+ DISP_REG_OVL_RDMA_CTRL(idx));
gmc_thrshd_l = GMC_THRESHOLD_LOW >>
  (GMC_THRESHOLD_BITS - ovl->data->gmc_bits);
gmc_thrshd_h = GMC_THRESHOLD_HIGH >>
@@ -195,22 +197,19 @@ static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, 
unsigned int idx)
else
gmc_value = gmc_thrshd_l | gmc_thrshd_l << 8 |
gmc_thrshd_h << 16 | gmc_thrshd_h << 24;
-   writel(gmc_value, comp->regs + DISP_REG_OVL_RDMA_GMC(idx));
-
-   reg = readl(comp->regs + DISP_REG_OVL_SRC_CON);
-   reg = reg | BIT(idx);
-   writel(reg, comp->regs + DISP_REG_OVL_SRC_CON);
+   mtk_ddp_write(cmdq_pkt, gmc_value,
+ comp, DISP_REG_OVL_RDMA_GMC(idx));
+   mtk_ddp_write_mask(cmdq_pkt, BIT(idx), comp,
+  DISP_REG_OVL_SRC_CON, BIT(idx));
 }
 
-static void mtk_ovl_layer_off(struct mtk_ddp_comp *comp, unsigned int idx)
+static void mtk_ovl_layer_off(struct mtk_ddp_comp *comp, unsigned int idx,
+ struct cmdq_pkt *cmdq_pkt)

[PATCH v5 2/7] drm/mediatek: handle events when enabling/disabling crtc

2019-12-09 Thread Bibby Hsieh
The driver currently handles vblank events only when updating planes on
an already enabled CRTC. The atomic update API however allows requesting
an event when enabling or disabling a CRTC. This currently leads to
event objects being leaked in the kernel and to events not being sent
out. Fix it.

Signed-off-by: Bibby Hsieh 
Reviewed-by: CK Hu 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 4bb468fd9226..af097b7db72f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -332,6 +332,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc 
*mtk_crtc)
 static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
 {
struct drm_device *drm = mtk_crtc->base.dev;
+   struct drm_crtc *crtc = _crtc->base;
int i;
 
DRM_DEBUG_DRIVER("%s\n", __func__);
@@ -361,6 +362,13 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc 
*mtk_crtc)
mtk_ddp_comp_unprepare(mtk_crtc->ddp_comp[i]);
 
pm_runtime_put(drm->dev);
+
+   if (crtc->state->event && !crtc->state->active) {
+   spin_lock_irq(>dev->event_lock);
+   drm_crtc_send_vblank_event(crtc, crtc->state->event);
+   crtc->state->event = NULL;
+   spin_unlock_irq(>dev->event_lock);
+   }
 }
 
 static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
-- 
2.18.0
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [Intel-gfx] [PATCH 5/5] drm/i915: Introduce intel_plane_state_reset()

2019-12-09 Thread Souza, Jose
On Thu, 2019-11-07 at 16:24 +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> For the sake of symmetry with the crtc stuff let's add
> a helper to reset the plane state to sane default values.
> For the moment this only gets caller from the plane init.
> 

Reviewed-by: José Roberto de Souza 

> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/display/intel_atomic_plane.c | 15
> +--
>  1 file changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> index 42b3b3449d2e..9429b8e17270 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> @@ -41,6 +41,16 @@
>  #include "intel_pm.h"
>  #include "intel_sprite.h"
>  
> +static void intel_plane_state_reset(struct intel_plane_state
> *plane_state,
> + struct intel_plane *plane)
> +{
> + memset(plane_state, 0, sizeof(*plane_state));
> +
> + __drm_atomic_helper_plane_state_reset(_state->uapi,
> >base);
> +
> + plane_state->scaler_id = -1;
> +}
> +
>  struct intel_plane *intel_plane_alloc(void)
>  {
>   struct intel_plane_state *plane_state;
> @@ -56,8 +66,9 @@ struct intel_plane *intel_plane_alloc(void)
>   return ERR_PTR(-ENOMEM);
>   }
>  
> - __drm_atomic_helper_plane_reset(>base, _state-
> >uapi);
> - plane_state->scaler_id = -1;
> + intel_plane_state_reset(plane_state, plane);
> +
> + plane->base.state = _state->uapi;
>  
>   return plane;
>  }
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [Intel-gfx] [PATCH 4/5] drm/i915: Introduce intel_crtc_state_reset()

2019-12-09 Thread Souza, Jose
On Thu, 2019-11-07 at 16:24 +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> We have a few places where we want to reset a crtc state to its
> default values. Let's add a helper for that. We'll need the new
> __drm_atomic_helper_crtc_state_reset() helper for this to allow
> us to just reset the state itself without clobbering the
> crtc->state pointer.
> 
> And while at it let's zero out the whole thing, except a few
> choice member which we'll mark as "invalid". And thanks to this
> we can now nuke intel_crtc_init_scalers().
> 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 47 +-
> --
>  1 file changed, 22 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index e6291841053f..fd4120533c3f 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -164,7 +164,6 @@ static void vlv_prepare_pll(struct intel_crtc
> *crtc,
>   const struct intel_crtc_state
> *pipe_config);
>  static void chv_prepare_pll(struct intel_crtc *crtc,
>   const struct intel_crtc_state
> *pipe_config);
> -static void intel_crtc_init_scalers(struct intel_crtc_state
> *crtc_state);
>  static void skylake_pfit_enable(const struct intel_crtc_state
> *crtc_state);
>  static void ironlake_pfit_disable(const struct intel_crtc_state
> *old_crtc_state);
>  static void ironlake_pfit_enable(const struct intel_crtc_state
> *crtc_state);
> @@ -10655,8 +10654,6 @@ static bool haswell_get_pipe_config(struct
> intel_crtc *crtc,
>   u64 power_domain_mask;
>   bool active;
>  
> - intel_crtc_init_scalers(pipe_config);
> -
>   pipe_config->master_transcoder = INVALID_TRANSCODER;
>  
>   power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
> @@ -11704,6 +11701,20 @@ static void ironlake_pch_clock_get(struct
> intel_crtc *crtc,
>_config->fdi_m_n);
>  }
>  
> +static void intel_crtc_state_reset(struct intel_crtc_state
> *crtc_state,
> +struct intel_crtc *crtc)
> +{
> + memset(crtc_state, 0, sizeof(*crtc_state));
> +
> + __drm_atomic_helper_crtc_state_reset(_state->uapi, 
> >base);
> +
> + crtc_state->cpu_transcoder = INVALID_TRANSCODER;
> + crtc_state->master_transcoder = INVALID_TRANSCODER;

At least master_transcoder is set to invalid again but we can remove
the redundant sets later

Reviewed-by: José Roberto de Souza 

> + crtc_state->hsw_workaround_pipe = INVALID_PIPE;
> + crtc_state->output_format = INTEL_OUTPUT_FORMAT_INVALID;
> + crtc_state->scaler_state.scaler_id = -1;
> +}
> +
>  /* Returns the currently programmed mode of the given encoder. */
>  struct drm_display_mode *
>  intel_encoder_current_mode(struct intel_encoder *encoder)
> @@ -11729,7 +11740,7 @@ intel_encoder_current_mode(struct
> intel_encoder *encoder)
>   return NULL;
>   }
>  
> - crtc_state->uapi.crtc = >base;
> + intel_crtc_state_reset(crtc_state, crtc);
>  
>   if (!dev_priv->display.get_pipe_config(crtc, crtc_state)) {
>   kfree(crtc_state);
> @@ -13577,18 +13588,14 @@ verify_crtc_state(struct intel_crtc *crtc,
>   struct drm_device *dev = crtc->base.dev;
>   struct drm_i915_private *dev_priv = to_i915(dev);
>   struct intel_encoder *encoder;
> - struct intel_crtc_state *pipe_config;
> - struct drm_atomic_state *state;
> + struct intel_crtc_state *pipe_config = old_crtc_state;
> + struct drm_atomic_state *state = old_crtc_state->uapi.state;
>   bool active;
>  
> - state = old_crtc_state->uapi.state;
>   __drm_atomic_helper_crtc_destroy_state(_crtc_state->uapi);
>   intel_crtc_free_hw_state(old_crtc_state);
> -
> - pipe_config = old_crtc_state;
> - memset(pipe_config, 0, sizeof(*pipe_config));
> - pipe_config->uapi.crtc = >base;
> - pipe_config->uapi.state = state;
> + intel_crtc_state_reset(old_crtc_state, crtc);
> + old_crtc_state->uapi.state = state;
>  
>   DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.base.id, crtc-
> >base.name);
>  
> @@ -15745,15 +15752,6 @@ intel_cursor_plane_create(struct
> drm_i915_private *dev_priv,
>   return ERR_PTR(ret);
>  }
>  
> -static void intel_crtc_init_scalers(struct intel_crtc_state
> *crtc_state)
> -{
> - struct intel_crtc_scaler_state *scaler_state =
> - _state->scaler_state;
> -
> - memset(scaler_state, 0, sizeof(*scaler_state));
> - scaler_state->scaler_id = -1;
> -}
> -
>  #define INTEL_CRTC_FUNCS \
>   .gamma_set = drm_atomic_helper_legacy_gamma_set, \
>   .set_config = drm_atomic_helper_set_config, \
> @@ -15836,9 +15834,9 @@ static struct intel_crtc
> *intel_crtc_alloc(void)
>   return ERR_PTR(-ENOMEM);
>   }
>  
> - __drm_atomic_helper_crtc_reset(>base, _state->uapi);
> - 

Re: [Intel-gfx] [PATCH 2/5] drm/i915: s/intel_crtc/crtc/ in intel_crtc_init()

2019-12-09 Thread Souza, Jose
On Thu, 2019-11-07 at 16:24 +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Let's get rid of the redundant intel_ prefix on our variables.
> 

Reviewed-by: José Roberto de Souza 

> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 32 ++--
> 
>  1 file changed, 16 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 551de2baa569..8b889c9f29b5 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -15838,14 +15838,14 @@ static const struct drm_crtc_funcs
> i8xx_crtc_funcs = {
>  static int intel_crtc_init(struct drm_i915_private *dev_priv, enum
> pipe pipe)
>  {
>   const struct drm_crtc_funcs *funcs;
> - struct intel_crtc *intel_crtc;
> + struct intel_crtc *crtc;
>   struct intel_crtc_state *crtc_state = NULL;
>   struct intel_plane *primary = NULL;
>   struct intel_plane *cursor = NULL;
>   int sprite, ret;
>  
> - intel_crtc = kzalloc(sizeof(*intel_crtc), GFP_KERNEL);
> - if (!intel_crtc)
> + crtc = kzalloc(sizeof(*crtc), GFP_KERNEL);
> + if (!crtc)
>   return -ENOMEM;
>  
>   crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
> @@ -15853,15 +15853,15 @@ static int intel_crtc_init(struct
> drm_i915_private *dev_priv, enum pipe pipe)
>   ret = -ENOMEM;
>   goto fail;
>   }
> - __drm_atomic_helper_crtc_reset(_crtc->base, _state-
> >uapi);
> - intel_crtc->config = crtc_state;
> + __drm_atomic_helper_crtc_reset(>base, _state->uapi);
> + crtc->config = crtc_state;
>  
>   primary = intel_primary_plane_create(dev_priv, pipe);
>   if (IS_ERR(primary)) {
>   ret = PTR_ERR(primary);
>   goto fail;
>   }
> - intel_crtc->plane_ids_mask |= BIT(primary->id);
> + crtc->plane_ids_mask |= BIT(primary->id);
>  
>   for_each_sprite(dev_priv, pipe, sprite) {
>   struct intel_plane *plane;
> @@ -15871,7 +15871,7 @@ static int intel_crtc_init(struct
> drm_i915_private *dev_priv, enum pipe pipe)
>   ret = PTR_ERR(plane);
>   goto fail;
>   }
> - intel_crtc->plane_ids_mask |= BIT(plane->id);
> + crtc->plane_ids_mask |= BIT(plane->id);
>   }
>  
>   cursor = intel_cursor_plane_create(dev_priv, pipe);
> @@ -15879,7 +15879,7 @@ static int intel_crtc_init(struct
> drm_i915_private *dev_priv, enum pipe pipe)
>   ret = PTR_ERR(cursor);
>   goto fail;
>   }
> - intel_crtc->plane_ids_mask |= BIT(cursor->id);
> + crtc->plane_ids_mask |= BIT(cursor->id);
>  
>   if (HAS_GMCH(dev_priv)) {
>   if (IS_CHERRYVIEW(dev_priv) ||
> @@ -15900,32 +15900,32 @@ static int intel_crtc_init(struct
> drm_i915_private *dev_priv, enum pipe pipe)
>   funcs = _crtc_funcs;
>   }
>  
> - ret = drm_crtc_init_with_planes(_priv->drm, _crtc-
> >base,
> + ret = drm_crtc_init_with_planes(_priv->drm, >base,
>   >base, >base,
>   funcs, "pipe %c",
> pipe_name(pipe));
>   if (ret)
>   goto fail;
>  
> - intel_crtc->pipe = pipe;
> + crtc->pipe = pipe;
>  
>   /* initialize shared scalers */
> - intel_crtc_init_scalers(intel_crtc, crtc_state);
> + intel_crtc_init_scalers(crtc, crtc_state);
>  
>   BUG_ON(pipe >= ARRAY_SIZE(dev_priv->pipe_to_crtc_mapping) ||
>  dev_priv->pipe_to_crtc_mapping[pipe] != NULL);
> - dev_priv->pipe_to_crtc_mapping[pipe] = intel_crtc;
> + dev_priv->pipe_to_crtc_mapping[pipe] = crtc;
>  
>   if (INTEL_GEN(dev_priv) < 9) {
>   enum i9xx_plane_id i9xx_plane = primary->i9xx_plane;
>  
>   BUG_ON(i9xx_plane >= ARRAY_SIZE(dev_priv-
> >plane_to_crtc_mapping) ||
>  dev_priv->plane_to_crtc_mapping[i9xx_plane] !=
> NULL);
> - dev_priv->plane_to_crtc_mapping[i9xx_plane] =
> intel_crtc;
> + dev_priv->plane_to_crtc_mapping[i9xx_plane] = crtc;
>   }
>  
> - intel_color_init(intel_crtc);
> + intel_color_init(crtc);
>  
> - WARN_ON(drm_crtc_index(_crtc->base) != intel_crtc->pipe);
> + WARN_ON(drm_crtc_index(>base) != crtc->pipe);
>  
>   return 0;
>  
> @@ -15935,7 +15935,7 @@ static int intel_crtc_init(struct
> drm_i915_private *dev_priv, enum pipe pipe)
>* crtcs/planes already initialized.
>*/
>   kfree(crtc_state);
> - kfree(intel_crtc);
> + kfree(crtc);
>  
>   return ret;
>  }
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 3/5] drm/i915: Introduce intel_crtc_{alloc,free}()

2019-12-09 Thread Souza, Jose
On Thu, 2019-11-07 at 16:24 +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> We already have alloc/free helpers for planes, add the same for
> crtcs. The main benefit is we get to move all the annoying state
> initialization out of the main crtc_init() flow.
> 

Reviewed-by: José Roberto de Souza 

> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 74 ++--
> 
>  1 file changed, 36 insertions(+), 38 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 8b889c9f29b5..e6291841053f 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -164,8 +164,7 @@ static void vlv_prepare_pll(struct intel_crtc
> *crtc,
>   const struct intel_crtc_state
> *pipe_config);
>  static void chv_prepare_pll(struct intel_crtc *crtc,
>   const struct intel_crtc_state
> *pipe_config);
> -static void intel_crtc_init_scalers(struct intel_crtc *crtc,
> - struct intel_crtc_state
> *crtc_state);
> +static void intel_crtc_init_scalers(struct intel_crtc_state
> *crtc_state);
>  static void skylake_pfit_enable(const struct intel_crtc_state
> *crtc_state);
>  static void ironlake_pfit_disable(const struct intel_crtc_state
> *old_crtc_state);
>  static void ironlake_pfit_enable(const struct intel_crtc_state
> *crtc_state);
> @@ -10656,7 +10655,7 @@ static bool haswell_get_pipe_config(struct
> intel_crtc *crtc,
>   u64 power_domain_mask;
>   bool active;
>  
> - intel_crtc_init_scalers(crtc, pipe_config);
> + intel_crtc_init_scalers(pipe_config);
>  
>   pipe_config->master_transcoder = INVALID_TRANSCODER;
>  
> @@ -15746,25 +15745,12 @@ intel_cursor_plane_create(struct
> drm_i915_private *dev_priv,
>   return ERR_PTR(ret);
>  }
>  
> -static void intel_crtc_init_scalers(struct intel_crtc *crtc,
> - struct intel_crtc_state
> *crtc_state)
> +static void intel_crtc_init_scalers(struct intel_crtc_state
> *crtc_state)
>  {
>   struct intel_crtc_scaler_state *scaler_state =
>   _state->scaler_state;
> - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> - int i;
> -
> - crtc->num_scalers = RUNTIME_INFO(dev_priv)->num_scalers[crtc-
> >pipe];
> - if (!crtc->num_scalers)
> - return;
> -
> - for (i = 0; i < crtc->num_scalers; i++) {
> - struct intel_scaler *scaler = _state-
> >scalers[i];
> -
> - scaler->in_use = 0;
> - scaler->mode = 0;
> - }
>  
> + memset(scaler_state, 0, sizeof(*scaler_state));
>   scaler_state->scaler_id = -1;
>  }
>  
> @@ -15835,27 +15821,49 @@ static const struct drm_crtc_funcs
> i8xx_crtc_funcs = {
>   .disable_vblank = i8xx_disable_vblank,
>  };
>  
> -static int intel_crtc_init(struct drm_i915_private *dev_priv, enum
> pipe pipe)
> +static struct intel_crtc *intel_crtc_alloc(void)
>  {
> - const struct drm_crtc_funcs *funcs;
> + struct intel_crtc_state *crtc_state;
>   struct intel_crtc *crtc;
> - struct intel_crtc_state *crtc_state = NULL;
> - struct intel_plane *primary = NULL;
> - struct intel_plane *cursor = NULL;
> - int sprite, ret;
>  
>   crtc = kzalloc(sizeof(*crtc), GFP_KERNEL);
>   if (!crtc)
> - return -ENOMEM;
> + return ERR_PTR(-ENOMEM);
>  
>   crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
>   if (!crtc_state) {
> - ret = -ENOMEM;
> - goto fail;
> + kfree(crtc);
> + return ERR_PTR(-ENOMEM);
>   }
> +
>   __drm_atomic_helper_crtc_reset(>base, _state->uapi);
> + intel_crtc_init_scalers(crtc_state);
> +
>   crtc->config = crtc_state;
>  
> + return crtc;
> +}
> +
> +static void intel_crtc_free(struct intel_crtc *crtc)
> +{
> + intel_crtc_destroy_state(>base, crtc->base.state);
> + kfree(crtc);
> +}
> +
> +static int intel_crtc_init(struct drm_i915_private *dev_priv, enum
> pipe pipe)
> +{
> + struct intel_plane *primary, *cursor;
> + const struct drm_crtc_funcs *funcs;
> + struct intel_crtc *crtc;
> + int sprite, ret;
> +
> + crtc = intel_crtc_alloc();
> + if (IS_ERR(crtc))
> + return PTR_ERR(crtc);
> +
> + crtc->pipe = pipe;
> + crtc->num_scalers = RUNTIME_INFO(dev_priv)->num_scalers[pipe];
> +
>   primary = intel_primary_plane_create(dev_priv, pipe);
>   if (IS_ERR(primary)) {
>   ret = PTR_ERR(primary);
> @@ -15906,11 +15914,6 @@ static int intel_crtc_init(struct
> drm_i915_private *dev_priv, enum pipe pipe)
>   if (ret)
>   goto fail;
>  
> - crtc->pipe = pipe;
> -
> - /* initialize shared scalers */
> - intel_crtc_init_scalers(crtc, crtc_state);
> -
>   BUG_ON(pipe >= ARRAY_SIZE(dev_priv->pipe_to_crtc_mapping) ||
> 

Re: [PATCH v2 24/28] drm/mediatek: hdmi: Use drm_bridge_init()

2019-12-09 Thread CK Hu
Hi, Mihail:

On Wed, 2019-12-04 at 11:48 +, Mihail Atanassov wrote:
> No functional change.
> 

Acked-by: CK Hu 

> Signed-off-by: Mihail Atanassov 
> ---
>  drivers/gpu/drm/mediatek/mtk_hdmi.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c 
> b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> index f684947c5243..9761a80674d9 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> @@ -1708,8 +1708,8 @@ static int mtk_drm_hdmi_probe(struct platform_device 
> *pdev)
>  
>   mtk_hdmi_register_audio_driver(dev);
>  
> - hdmi->bridge.funcs = _hdmi_bridge_funcs;
> - hdmi->bridge.of_node = pdev->dev.of_node;
> + drm_bridge_init(>bridge, >dev, _hdmi_bridge_funcs,
> + NULL, NULL);
>   drm_bridge_add(>bridge);
>  
>   ret = mtk_hdmi_clk_enable_audio(hdmi);

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


[Bug 201539] AMDGPU R9 390 automatic fan speed control in Linux 4.19/4.20/5.0

2019-12-09 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=201539

--- Comment #53 from MasterCATZ (masterc...@hotmail.com) ---
its been like this since mid  kernel 4's, just wish I knew whats locking that
file root has no permissions and it seems to activate @ 70 deg , which even if
i run the fan 100% will be reached unless I under clock 

amdgpupro just turns PC into a paperweight so I don't use that 
radeon drivers suck for any gaming  
amdgpu / mesa 
are what I need to use and its been like this since powerplay was introduced 

Ubuntu 18.04, and just upgraded it to 19.10 same issues 
currently using 5.4.2-050402-generic

GRUB_CMDLINE_LINUX_DEFAULT="amdgpu.ppfeaturemask=0xfffd7fff
amdgpu.ppfeaturemask=0x amdgpu.dc=1 amdgpu.cik_support=1
radeon.cik_support=0"

featuremasks seem to make no difference 
maybe I should re - add 
radeon.si_support=0  amdgpu.si_support=1

as  in as radeon profile is showing radeonsi is in use ?, 
but I thought R9 290 were Sea Islands = amdgpu.cik_support=1 ?

-- 
You are receiving this mail because:
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v8 20/26] powerpc: book3s64: convert to pin_user_pages() and put_user_page()

2019-12-09 Thread John Hubbard
On 12/9/19 2:53 PM, John Hubbard wrote:
...
> @@ -212,10 +211,9 @@ static void mm_iommu_unpin(struct 
> mm_iommu_table_group_mem_t *mem)
>   if (!page)
>   continue;
>  
> - if (mem->hpas[i] & MM_IOMMU_TABLE_GROUP_PAGE_DIRTY)
> - SetPageDirty(page);
> + put_user_pages_dirty_lock(, 1,
> + mem->hpas[i] & MM_IOMMU_TABLE_GROUP_PAGE_DIRTY);
>  
> - put_page(page);


Correction: this is somehow missing the fixes that resulted from Jan Kara's 
review (he
noted that we can't take a page lock in this context). I must have picked up 
the 
wrong version of it, when I rebased for -rc1.

Will fix in the next version (including the commit description). Here's what the
corrected hunk will look like:

@@ -215,7 +214,8 @@ static void mm_iommu_unpin(struct 
mm_iommu_table_group_mem_t *mem)
if (mem->hpas[i] & MM_IOMMU_TABLE_GROUP_PAGE_DIRTY)
SetPageDirty(page);
 
-   put_page(page);
+   put_user_page(page);
+
mem->hpas[i] = 0;
}
 }


thanks,
-- 
John Hubbard
NVIDIA
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v8 17/26] media/v4l2-core: set pages dirty upon releasing DMA buffers

2019-12-09 Thread Andrew Morton
On Mon, 9 Dec 2019 14:53:35 -0800 John Hubbard  wrote:

> After DMA is complete, and the device and CPU caches are synchronized,
> it's still required to mark the CPU pages as dirty, if the data was
> coming from the device. However, this driver was just issuing a
> bare put_page() call, without any set_page_dirty*() call.
> 
> Fix the problem, by calling set_page_dirty_lock() if the CPU pages
> were potentially receiving data from the device.
> 
> Reviewed-by: Christoph Hellwig 
> Acked-by: Hans Verkuil 
> Cc: Mauro Carvalho Chehab 
> Cc: 

What are the user-visible effects of this change?

As it's cc:stable I'd normally send this to Linus within 1-2 weeks, or
sooner.  Please confirm that this is a standalone fix, independent of
the rest of this series.


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


[PATCH v8 24/26] mm/gup: track FOLL_PIN pages

2019-12-09 Thread John Hubbard
Add tracking of pages that were pinned via FOLL_PIN.

As mentioned in the FOLL_PIN documentation, callers who effectively set
FOLL_PIN are required to ultimately free such pages via unpin_user_page().
The effect is similar to FOLL_GET, and may be thought of as "FOLL_GET
for DIO and/or RDMA use".

Pages that have been pinned via FOLL_PIN are identifiable via a
new function call:

   bool page_dma_pinned(struct page *page);

What to do in response to encountering such a page, is left to later
patchsets. There is discussion about this in [1], [2], and [3].

This also changes a BUG_ON(), to a WARN_ON(), in follow_page_mask().

[1] Some slow progress on get_user_pages() (Apr 2, 2019):
https://lwn.net/Articles/784574/
[2] DMA and get_user_pages() (LPC: Dec 12, 2018):
https://lwn.net/Articles/774411/
[3] The trouble with get_user_pages() (Apr 30, 2018):
https://lwn.net/Articles/753027/

Suggested-by: Jan Kara 
Suggested-by: Jérôme Glisse 
Signed-off-by: John Hubbard 
---
 Documentation/core-api/pin_user_pages.rst |   2 +-
 include/linux/mm.h|  73 -
 include/linux/mmzone.h|   2 +
 include/linux/page_ref.h  |  10 +
 mm/gup.c  | 338 +-
 mm/huge_memory.c  |  23 +-
 mm/hugetlb.c  |  15 +-
 mm/vmstat.c   |   2 +
 8 files changed, 362 insertions(+), 103 deletions(-)

diff --git a/Documentation/core-api/pin_user_pages.rst 
b/Documentation/core-api/pin_user_pages.rst
index bba96428ade7..6d93ef203561 100644
--- a/Documentation/core-api/pin_user_pages.rst
+++ b/Documentation/core-api/pin_user_pages.rst
@@ -53,7 +53,7 @@ Which flags are set by each wrapper
 For these pin_user_pages*() functions, FOLL_PIN is OR'd in with whatever gup
 flags the caller provides. The caller is required to pass in a non-null struct
 pages* array, and the function then pin pages by incrementing each by a special
-value. For now, that value is +1, just like get_user_pages*().::
+value: GUP_PIN_COUNTING_BIAS.::
 
  Function
  
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 6a1a357e7d86..9666989d2b9e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1016,6 +1016,8 @@ static inline void get_page(struct page *page)
page_ref_inc(page);
 }
 
+void grab_page(struct page *page, unsigned int flags);
+
 static inline __must_check bool try_get_page(struct page *page)
 {
page = compound_head(page);
@@ -1044,29 +1046,70 @@ static inline void put_page(struct page *page)
__put_page(page);
 }
 
-/**
- * unpin_user_page() - release a gup-pinned page
- * @page:pointer to page to be released
+/*
+ * GUP_PIN_COUNTING_BIAS, and the associated functions that use it, overload
+ * the page's refcount so that two separate items are tracked: the original 
page
+ * reference count, and also a new count of how many pin_user_pages() calls 
were
+ * made against the page. ("gup-pinned" is another term for the latter).
+ *
+ * With this scheme, pin_user_pages() becomes special: such pages are marked as
+ * distinct from normal pages. As such, the unpin_user_page() call (and its
+ * variants) must be used in order to release gup-pinned pages.
+ *
+ * Choice of value:
  *
- * Pages that were pinned via pin_user_pages*() must be released via either
- * unpin_user_page(), or one of the unpin_user_pages*() routines. This is so
- * that eventually such pages can be separately tracked and uniquely handled. 
In
- * particular, interactions with RDMA and filesystems need special handling.
+ * By making GUP_PIN_COUNTING_BIAS a power of two, debugging of page reference
+ * counts with respect to pin_user_pages() and unpin_user_page() becomes
+ * simpler, due to the fact that adding an even power of two to the page
+ * refcount has the effect of using only the upper N bits, for the code that
+ * counts up using the bias value. This means that the lower bits are left for
+ * the exclusive use of the original code that increments and decrements by one
+ * (or at least, by much smaller values than the bias value).
  *
- * unpin_user_page() and put_page() are not interchangeable, despite this early
- * implementation that makes them look the same. unpin_user_page() calls must
- * be perfectly matched up with pin*() calls.
+ * Of course, once the lower bits overflow into the upper bits (and this is
+ * OK, because subtraction recovers the original values), then visual 
inspection
+ * no longer suffices to directly view the separate counts. However, for normal
+ * applications that don't have huge page reference counts, this won't be an
+ * issue.
+ *
+ * Locking: the lockless algorithm described in page_cache_get_speculative()
+ * and page_cache_gup_pin_speculative() provides safe operation for
+ * get_user_pages and page_mkclean and other calls that race to set up page
+ * table entries.
  */
-static inline void 

[PATCH v8 25/26] mm/gup_benchmark: support pin_user_pages() and related calls

2019-12-09 Thread John Hubbard
Up until now, gup_benchmark supported testing of the
following kernel functions:

* get_user_pages(): via the '-U' command line option
* get_user_pages_longterm(): via the '-L' command line option
* get_user_pages_fast(): as the default (no options required)

Add test coverage for the new corresponding pin_*() functions:

* pin_user_pages_fast(): via the '-a' command line option
* pin_user_pages():  via the '-b' command line option

Also, add an option for clarity: '-u' for what is now (still) the
default choice: get_user_pages_fast().

Also, for the commands that set FOLL_PIN, verify that the pages
really are dma-pinned, via the new is_dma_pinned() routine.
Those commands are:

PIN_FAST_BENCHMARK : calls pin_user_pages_fast()
PIN_BENCHMARK  : calls pin_user_pages()

In between the calls to pin_*() and unpin_user_pages(),
check each page: if page_dma_pinned() returns false, then
WARN and return.

Do this outside of the benchmark timestamps, so that it doesn't
affect reported times.

Reviewed-by: Ira Weiny 
Signed-off-by: John Hubbard 
---
 mm/gup_benchmark.c | 65 --
 tools/testing/selftests/vm/gup_benchmark.c | 15 -
 2 files changed, 74 insertions(+), 6 deletions(-)

diff --git a/mm/gup_benchmark.c b/mm/gup_benchmark.c
index 7fc44d25eca7..76d32db48af8 100644
--- a/mm/gup_benchmark.c
+++ b/mm/gup_benchmark.c
@@ -8,6 +8,8 @@
 #define GUP_FAST_BENCHMARK _IOWR('g', 1, struct gup_benchmark)
 #define GUP_LONGTERM_BENCHMARK _IOWR('g', 2, struct gup_benchmark)
 #define GUP_BENCHMARK  _IOWR('g', 3, struct gup_benchmark)
+#define PIN_FAST_BENCHMARK _IOWR('g', 4, struct gup_benchmark)
+#define PIN_BENCHMARK  _IOWR('g', 5, struct gup_benchmark)
 
 struct gup_benchmark {
__u64 get_delta_usec;
@@ -19,6 +21,42 @@ struct gup_benchmark {
__u64 expansion[10];/* For future use */
 };
 
+static void put_back_pages(int cmd, struct page **pages, unsigned long 
nr_pages)
+{
+   int i;
+
+   switch (cmd) {
+   case GUP_FAST_BENCHMARK:
+   case GUP_LONGTERM_BENCHMARK:
+   case GUP_BENCHMARK:
+   for (i = 0; i < nr_pages; i++)
+   put_page(pages[i]);
+   break;
+
+   case PIN_FAST_BENCHMARK:
+   case PIN_BENCHMARK:
+   unpin_user_pages(pages, nr_pages);
+   break;
+   }
+}
+
+static void verify_dma_pinned(int cmd, struct page **pages,
+ unsigned long nr_pages)
+{
+   int i;
+
+   switch (cmd) {
+   case PIN_FAST_BENCHMARK:
+   case PIN_BENCHMARK:
+   for (i = 0; i < nr_pages; i++) {
+   if (WARN(!page_dma_pinned(pages[i]),
+"pages[%d] is NOT dma-pinned\n", i))
+   break;
+   }
+   break;
+   }
+}
+
 static int __gup_benchmark_ioctl(unsigned int cmd,
struct gup_benchmark *gup)
 {
@@ -65,6 +103,14 @@ static int __gup_benchmark_ioctl(unsigned int cmd,
nr = get_user_pages(addr, nr, gup->flags, pages + i,
NULL);
break;
+   case PIN_FAST_BENCHMARK:
+   nr = pin_user_pages_fast(addr, nr, gup->flags,
+pages + i);
+   break;
+   case PIN_BENCHMARK:
+   nr = pin_user_pages(addr, nr, gup->flags, pages + i,
+   NULL);
+   break;
default:
return -1;
}
@@ -75,15 +121,22 @@ static int __gup_benchmark_ioctl(unsigned int cmd,
}
end_time = ktime_get();
 
+   /* Shifting the meaning of nr_pages: now it is actual number pinned: */
+   nr_pages = i;
+
gup->get_delta_usec = ktime_us_delta(end_time, start_time);
gup->size = addr - gup->addr;
 
+   /*
+* Take an un-benchmark-timed moment to verify DMA pinned
+* state: print a warning if any non-dma-pinned pages are found:
+*/
+   verify_dma_pinned(cmd, pages, nr_pages);
+
start_time = ktime_get();
-   for (i = 0; i < nr_pages; i++) {
-   if (!pages[i])
-   break;
-   put_page(pages[i]);
-   }
+
+   put_back_pages(cmd, pages, nr_pages);
+
end_time = ktime_get();
gup->put_delta_usec = ktime_us_delta(end_time, start_time);
 
@@ -101,6 +154,8 @@ static long gup_benchmark_ioctl(struct file *filep, 
unsigned int cmd,
case GUP_FAST_BENCHMARK:
case GUP_LONGTERM_BENCHMARK:
case GUP_BENCHMARK:
+   case PIN_FAST_BENCHMARK:
+   case PIN_BENCHMARK:
break;
default:
return -EINVAL;
diff --git a/tools/testing/selftests/vm/gup_benchmark.c 

[PATCH v8 26/26] selftests/vm: run_vmtests: invoke gup_benchmark with basic FOLL_PIN coverage

2019-12-09 Thread John Hubbard
It's good to have basic unit test coverage of the new FOLL_PIN
behavior. Fortunately, the gup_benchmark unit test is extremely
fast (a few milliseconds), so adding it the the run_vmtests suite
is going to cause no noticeable change in running time.

So, add two new invocations to run_vmtests:

1) Run gup_benchmark with normal get_user_pages().

2) Run gup_benchmark with pin_user_pages(). This is much like
the first call, except that it sets FOLL_PIN.

Running these two in quick succession also provide a visual
comparison of the running times, which is convenient.

The new invocations are fairly early in the run_vmtests script,
because with test suites, it's usually preferable to put the
shorter, faster tests first, all other things being equal.

Reviewed-by: Ira Weiny 
Signed-off-by: John Hubbard 
---
 tools/testing/selftests/vm/run_vmtests | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/tools/testing/selftests/vm/run_vmtests 
b/tools/testing/selftests/vm/run_vmtests
index a692ea828317..df6a6bf3f238 100755
--- a/tools/testing/selftests/vm/run_vmtests
+++ b/tools/testing/selftests/vm/run_vmtests
@@ -112,6 +112,28 @@ echo "NOTE: The above hugetlb tests provide minimal 
coverage.  Use"
 echo "  https://github.com/libhugetlbfs/libhugetlbfs.git for"
 echo "  hugetlb regression testing."
 
+echo ""
+echo "running 'gup_benchmark -U' (normal/slow gup)"
+echo ""
+./gup_benchmark -U
+if [ $? -ne 0 ]; then
+   echo "[FAIL]"
+   exitcode=1
+else
+   echo "[PASS]"
+fi
+
+echo "--"
+echo "running gup_benchmark -b (pin_user_pages)"
+echo "--"
+./gup_benchmark -b
+if [ $? -ne 0 ]; then
+   echo "[FAIL]"
+   exitcode=1
+else
+   echo "[PASS]"
+fi
+
 echo "---"
 echo "running userfaultfd"
 echo "---"
-- 
2.24.0

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

[PATCH v8 19/26] vfio, mm: pin_user_pages (FOLL_PIN) and put_user_page() conversion

2019-12-09 Thread John Hubbard
1. Change vfio from get_user_pages_remote(), to
pin_user_pages_remote().

2. Because all FOLL_PIN-acquired pages must be released via
put_user_page(), also convert the put_page() call over to
put_user_pages_dirty_lock().

Note that this effectively changes the code's behavior in
vfio_iommu_type1.c: put_pfn(): it now ultimately calls
set_page_dirty_lock(), instead of set_page_dirty(). This is
probably more accurate.

As Christoph Hellwig put it, "set_page_dirty() is only safe if we are
dealing with a file backed page where we have reference on the inode it
hangs off." [1]

[1] https://lore.kernel.org/r/20190723153640.gb...@lst.de

Tested-by: Alex Williamson 
Acked-by: Alex Williamson 
Signed-off-by: John Hubbard 
---
 drivers/vfio/vfio_iommu_type1.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index b800fc9a0251..18bfc2fc8e6d 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -309,9 +309,8 @@ static int put_pfn(unsigned long pfn, int prot)
 {
if (!is_invalid_reserved_pfn(pfn)) {
struct page *page = pfn_to_page(pfn);
-   if (prot & IOMMU_WRITE)
-   SetPageDirty(page);
-   put_page(page);
+
+   put_user_pages_dirty_lock(, 1, prot & IOMMU_WRITE);
return 1;
}
return 0;
@@ -329,7 +328,7 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned 
long vaddr,
flags |= FOLL_WRITE;
 
down_read(>mmap_sem);
-   ret = get_user_pages_remote(NULL, mm, vaddr, 1, flags | FOLL_LONGTERM,
+   ret = pin_user_pages_remote(NULL, mm, vaddr, 1, flags | FOLL_LONGTERM,
page, NULL, NULL);
if (ret == 1) {
*pfn = page_to_pfn(page[0]);
-- 
2.24.0

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

[PATCH v8 23/26] mm/gup: pass flags arg to __gup_device_* functions

2019-12-09 Thread John Hubbard
A subsequent patch requires access to gup flags, so pass the flags
argument through to the __gup_device_* functions.

Also placate checkpatch.pl by shortening a nearby line.

TODO: Christoph Hellwig requested folding this into the patch the uses
the gup flags arguments.

Reviewed-by: Jan Kara 
Reviewed-by: Jérôme Glisse 
Reviewed-by: Ira Weiny 
Cc: Kirill A. Shutemov 
Signed-off-by: John Hubbard 
---
 mm/gup.c | 28 ++--
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/mm/gup.c b/mm/gup.c
index 73aedcefa4bd..687d48506f04 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1957,7 +1957,8 @@ static int gup_pte_range(pmd_t pmd, unsigned long addr, 
unsigned long end,
 
 #if defined(CONFIG_ARCH_HAS_PTE_DEVMAP) && defined(CONFIG_TRANSPARENT_HUGEPAGE)
 static int __gup_device_huge(unsigned long pfn, unsigned long addr,
-   unsigned long end, struct page **pages, int *nr)
+unsigned long end, unsigned int flags,
+struct page **pages, int *nr)
 {
int nr_start = *nr;
struct dev_pagemap *pgmap = NULL;
@@ -1983,13 +1984,14 @@ static int __gup_device_huge(unsigned long pfn, 
unsigned long addr,
 }
 
 static int __gup_device_huge_pmd(pmd_t orig, pmd_t *pmdp, unsigned long addr,
-   unsigned long end, struct page **pages, int *nr)
+unsigned long end, unsigned int flags,
+struct page **pages, int *nr)
 {
unsigned long fault_pfn;
int nr_start = *nr;
 
fault_pfn = pmd_pfn(orig) + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
-   if (!__gup_device_huge(fault_pfn, addr, end, pages, nr))
+   if (!__gup_device_huge(fault_pfn, addr, end, flags, pages, nr))
return 0;
 
if (unlikely(pmd_val(orig) != pmd_val(*pmdp))) {
@@ -2000,13 +2002,14 @@ static int __gup_device_huge_pmd(pmd_t orig, pmd_t 
*pmdp, unsigned long addr,
 }
 
 static int __gup_device_huge_pud(pud_t orig, pud_t *pudp, unsigned long addr,
-   unsigned long end, struct page **pages, int *nr)
+unsigned long end, unsigned int flags,
+struct page **pages, int *nr)
 {
unsigned long fault_pfn;
int nr_start = *nr;
 
fault_pfn = pud_pfn(orig) + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
-   if (!__gup_device_huge(fault_pfn, addr, end, pages, nr))
+   if (!__gup_device_huge(fault_pfn, addr, end, flags, pages, nr))
return 0;
 
if (unlikely(pud_val(orig) != pud_val(*pudp))) {
@@ -2017,14 +2020,16 @@ static int __gup_device_huge_pud(pud_t orig, pud_t 
*pudp, unsigned long addr,
 }
 #else
 static int __gup_device_huge_pmd(pmd_t orig, pmd_t *pmdp, unsigned long addr,
-   unsigned long end, struct page **pages, int *nr)
+unsigned long end, unsigned int flags,
+struct page **pages, int *nr)
 {
BUILD_BUG();
return 0;
 }
 
 static int __gup_device_huge_pud(pud_t pud, pud_t *pudp, unsigned long addr,
-   unsigned long end, struct page **pages, int *nr)
+unsigned long end, unsigned int flags,
+struct page **pages, int *nr)
 {
BUILD_BUG();
return 0;
@@ -2136,7 +2141,8 @@ static int gup_huge_pmd(pmd_t orig, pmd_t *pmdp, unsigned 
long addr,
if (pmd_devmap(orig)) {
if (unlikely(flags & FOLL_LONGTERM))
return 0;
-   return __gup_device_huge_pmd(orig, pmdp, addr, end, pages, nr);
+   return __gup_device_huge_pmd(orig, pmdp, addr, end, flags,
+pages, nr);
}
 
page = pmd_page(orig) + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
@@ -2157,7 +2163,8 @@ static int gup_huge_pmd(pmd_t orig, pmd_t *pmdp, unsigned 
long addr,
 }
 
 static int gup_huge_pud(pud_t orig, pud_t *pudp, unsigned long addr,
-   unsigned long end, unsigned int flags, struct page **pages, int 
*nr)
+   unsigned long end, unsigned int flags,
+   struct page **pages, int *nr)
 {
struct page *head, *page;
int refs;
@@ -2168,7 +2175,8 @@ static int gup_huge_pud(pud_t orig, pud_t *pudp, unsigned 
long addr,
if (pud_devmap(orig)) {
if (unlikely(flags & FOLL_LONGTERM))
return 0;
-   return __gup_device_huge_pud(orig, pudp, addr, end, pages, nr);
+   return __gup_device_huge_pud(orig, pudp, addr, end, flags,
+pages, nr);
}
 
page = pud_page(orig) + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
-- 
2.24.0

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

[PATCH v8 21/26] mm/gup_benchmark: use proper FOLL_WRITE flags instead of hard-coding "1"

2019-12-09 Thread John Hubbard
Fix the gup benchmark flags to use the symbolic FOLL_WRITE,
instead of a hard-coded "1" value.

Also, clean up the filtering of gup flags a little, by just doing
it once before issuing any of the get_user_pages*() calls. This
makes it harder to overlook, instead of having little "gup_flags & 1"
phrases in the function calls.

Reviewed-by: Ira Weiny 
Signed-off-by: John Hubbard 
---
 mm/gup_benchmark.c | 9 ++---
 tools/testing/selftests/vm/gup_benchmark.c | 6 +-
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/mm/gup_benchmark.c b/mm/gup_benchmark.c
index 7dd602d7f8db..7fc44d25eca7 100644
--- a/mm/gup_benchmark.c
+++ b/mm/gup_benchmark.c
@@ -48,18 +48,21 @@ static int __gup_benchmark_ioctl(unsigned int cmd,
nr = (next - addr) / PAGE_SIZE;
}
 
+   /* Filter out most gup flags: only allow a tiny subset here: */
+   gup->flags &= FOLL_WRITE;
+
switch (cmd) {
case GUP_FAST_BENCHMARK:
-   nr = get_user_pages_fast(addr, nr, gup->flags & 1,
+   nr = get_user_pages_fast(addr, nr, gup->flags,
 pages + i);
break;
case GUP_LONGTERM_BENCHMARK:
nr = get_user_pages(addr, nr,
-   (gup->flags & 1) | FOLL_LONGTERM,
+   gup->flags | FOLL_LONGTERM,
pages + i, NULL);
break;
case GUP_BENCHMARK:
-   nr = get_user_pages(addr, nr, gup->flags & 1, pages + i,
+   nr = get_user_pages(addr, nr, gup->flags, pages + i,
NULL);
break;
default:
diff --git a/tools/testing/selftests/vm/gup_benchmark.c 
b/tools/testing/selftests/vm/gup_benchmark.c
index 485cf06ef013..389327e9b30a 100644
--- a/tools/testing/selftests/vm/gup_benchmark.c
+++ b/tools/testing/selftests/vm/gup_benchmark.c
@@ -18,6 +18,9 @@
 #define GUP_LONGTERM_BENCHMARK _IOWR('g', 2, struct gup_benchmark)
 #define GUP_BENCHMARK  _IOWR('g', 3, struct gup_benchmark)
 
+/* Just the flags we need, copied from mm.h: */
+#define FOLL_WRITE 0x01/* check pte is writable */
+
 struct gup_benchmark {
__u64 get_delta_usec;
__u64 put_delta_usec;
@@ -85,7 +88,8 @@ int main(int argc, char **argv)
}
 
gup.nr_pages_per_call = nr_pages;
-   gup.flags = write;
+   if (write)
+   gup.flags |= FOLL_WRITE;
 
fd = open("/sys/kernel/debug/gup_benchmark", O_RDWR);
if (fd == -1)
-- 
2.24.0

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

[PATCH v8 22/26] mm, tree-wide: rename put_user_page*() to unpin_user_page*()

2019-12-09 Thread John Hubbard
In order to provide a clearer, more symmetric API for pinning
and unpinning DMA pages. This way, pin_user_pages*() calls
match up with unpin_user_pages*() calls, and the API is a lot
closer to being self-explanatory.

Reviewed-by: Jan Kara 
Signed-off-by: John Hubbard 
---
 Documentation/core-api/pin_user_pages.rst   |  2 +-
 arch/powerpc/mm/book3s64/iommu_api.c|  4 +--
 drivers/gpu/drm/via/via_dmablit.c   |  4 +--
 drivers/infiniband/core/umem.c  |  2 +-
 drivers/infiniband/hw/hfi1/user_pages.c |  2 +-
 drivers/infiniband/hw/mthca/mthca_memfree.c |  6 ++--
 drivers/infiniband/hw/qib/qib_user_pages.c  |  2 +-
 drivers/infiniband/hw/qib/qib_user_sdma.c   |  6 ++--
 drivers/infiniband/hw/usnic/usnic_uiom.c|  2 +-
 drivers/infiniband/sw/siw/siw_mem.c |  2 +-
 drivers/media/v4l2-core/videobuf-dma-sg.c   |  4 +--
 drivers/platform/goldfish/goldfish_pipe.c   |  4 +--
 drivers/vfio/vfio_iommu_type1.c |  2 +-
 fs/io_uring.c   |  4 +--
 include/linux/mm.h  | 26 -
 mm/gup.c| 32 ++---
 mm/process_vm_access.c  |  4 +--
 net/xdp/xdp_umem.c  |  2 +-
 18 files changed, 55 insertions(+), 55 deletions(-)

diff --git a/Documentation/core-api/pin_user_pages.rst 
b/Documentation/core-api/pin_user_pages.rst
index 4f26637a5005..bba96428ade7 100644
--- a/Documentation/core-api/pin_user_pages.rst
+++ b/Documentation/core-api/pin_user_pages.rst
@@ -220,7 +220,7 @@ since the system was booted, via two new /proc/vmstat 
entries: ::
 /proc/vmstat/nr_foll_pin_requested
 
 Those are both going to show zero, unless CONFIG_DEBUG_VM is set. This is
-because there is a noticeable performance drop in put_user_page(), when they
+because there is a noticeable performance drop in unpin_user_page(), when they
 are activated.
 
 References
diff --git a/arch/powerpc/mm/book3s64/iommu_api.c 
b/arch/powerpc/mm/book3s64/iommu_api.c
index fc1670a6fc3c..b965a0dfd4a2 100644
--- a/arch/powerpc/mm/book3s64/iommu_api.c
+++ b/arch/powerpc/mm/book3s64/iommu_api.c
@@ -168,7 +168,7 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, 
unsigned long ua,
 
 free_exit:
/* free the references taken */
-   put_user_pages(mem->hpages, pinned);
+   unpin_user_pages(mem->hpages, pinned);
 
vfree(mem->hpas);
kfree(mem);
@@ -211,7 +211,7 @@ static void mm_iommu_unpin(struct 
mm_iommu_table_group_mem_t *mem)
if (!page)
continue;
 
-   put_user_pages_dirty_lock(, 1,
+   unpin_user_pages_dirty_lock(, 1,
mem->hpas[i] & MM_IOMMU_TABLE_GROUP_PAGE_DIRTY);
 
mem->hpas[i] = 0;
diff --git a/drivers/gpu/drm/via/via_dmablit.c 
b/drivers/gpu/drm/via/via_dmablit.c
index 37c5e572993a..719d036c9384 100644
--- a/drivers/gpu/drm/via/via_dmablit.c
+++ b/drivers/gpu/drm/via/via_dmablit.c
@@ -188,8 +188,8 @@ via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t 
*vsg)
kfree(vsg->desc_pages);
/* fall through */
case dr_via_pages_locked:
-   put_user_pages_dirty_lock(vsg->pages, vsg->num_pages,
- (vsg->direction == DMA_FROM_DEVICE));
+   unpin_user_pages_dirty_lock(vsg->pages, vsg->num_pages,
+  (vsg->direction == DMA_FROM_DEVICE));
/* fall through */
case dr_via_pages_alloc:
vfree(vsg->pages);
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 55daefaa9b88..a6094766b6f5 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -54,7 +54,7 @@ static void __ib_umem_release(struct ib_device *dev, struct 
ib_umem *umem, int d
 
for_each_sg_page(umem->sg_head.sgl, _iter, umem->sg_nents, 0) {
page = sg_page_iter_page(_iter);
-   put_user_pages_dirty_lock(, 1, umem->writable && dirty);
+   unpin_user_pages_dirty_lock(, 1, umem->writable && dirty);
}
 
sg_free_table(>sg_head);
diff --git a/drivers/infiniband/hw/hfi1/user_pages.c 
b/drivers/infiniband/hw/hfi1/user_pages.c
index 9a94761765c0..3b505006c0a6 100644
--- a/drivers/infiniband/hw/hfi1/user_pages.c
+++ b/drivers/infiniband/hw/hfi1/user_pages.c
@@ -118,7 +118,7 @@ int hfi1_acquire_user_pages(struct mm_struct *mm, unsigned 
long vaddr, size_t np
 void hfi1_release_user_pages(struct mm_struct *mm, struct page **p,
 size_t npages, bool dirty)
 {
-   put_user_pages_dirty_lock(p, npages, dirty);
+   unpin_user_pages_dirty_lock(p, npages, dirty);
 
if (mm) { /* during close after signal, mm can be NULL */
atomic64_sub(npages, >pinned_vm);
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c 

[PATCH v8 16/26] net/xdp: set FOLL_PIN via pin_user_pages()

2019-12-09 Thread John Hubbard
Convert net/xdp to use the new pin_longterm_pages() call, which sets
FOLL_PIN. Setting FOLL_PIN is now required for code that requires
tracking of pinned pages.

In partial anticipation of this work, the net/xdp code was already
calling put_user_page() instead of put_page(). Therefore, in order to
convert from the get_user_pages()/put_page() model, to the
pin_user_pages()/put_user_page() model, the only change required
here is to change get_user_pages() to pin_user_pages().

Acked-by: Björn Töpel 
Signed-off-by: John Hubbard 
---
 net/xdp/xdp_umem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/xdp/xdp_umem.c b/net/xdp/xdp_umem.c
index 3049af269fbf..d071003b5e76 100644
--- a/net/xdp/xdp_umem.c
+++ b/net/xdp/xdp_umem.c
@@ -291,7 +291,7 @@ static int xdp_umem_pin_pages(struct xdp_umem *umem)
return -ENOMEM;
 
down_read(>mm->mmap_sem);
-   npgs = get_user_pages(umem->address, umem->npgs,
+   npgs = pin_user_pages(umem->address, umem->npgs,
  gup_flags | FOLL_LONGTERM, >pgs[0], NULL);
up_read(>mm->mmap_sem);
 
-- 
2.24.0

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

[PATCH v8 06/26] mm: fix get_user_pages_remote()'s handling of FOLL_LONGTERM

2019-12-09 Thread John Hubbard
As it says in the updated comment in gup.c: current FOLL_LONGTERM
behavior is incompatible with FAULT_FLAG_ALLOW_RETRY because of the
FS DAX check requirement on vmas.

However, the corresponding restriction in get_user_pages_remote() was
slightly stricter than is actually required: it forbade all
FOLL_LONGTERM callers, but we can actually allow FOLL_LONGTERM callers
that do not set the "locked" arg.

Update the code and comments to loosen the restriction, allowing
FOLL_LONGTERM in some cases.

Also, copy the DAX check ("if a VMA is DAX, don't allow long term
pinning") from the VFIO call site, all the way into the internals
of get_user_pages_remote() and __gup_longterm_locked(). That is:
get_user_pages_remote() calls __gup_longterm_locked(), which in turn
calls check_dax_vmas(). This check will then be removed from the VFIO
call site in a subsequent patch.

Thanks to Jason Gunthorpe for pointing out a clean way to fix this,
and to Dan Williams for helping clarify the DAX refactoring.

Tested-by: Alex Williamson 
Acked-by: Alex Williamson 
Reviewed-by: Jason Gunthorpe 
Reviewed-by: Ira Weiny 
Suggested-by: Jason Gunthorpe 
Cc: Dan Williams 
Cc: Jerome Glisse 
Signed-off-by: John Hubbard 
---
 mm/gup.c | 27 ++-
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/mm/gup.c b/mm/gup.c
index 3ecce297a47f..c0c56888e7cc 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -29,6 +29,13 @@ struct follow_page_context {
unsigned int page_mask;
 };
 
+static __always_inline long __gup_longterm_locked(struct task_struct *tsk,
+ struct mm_struct *mm,
+ unsigned long start,
+ unsigned long nr_pages,
+ struct page **pages,
+ struct vm_area_struct **vmas,
+ unsigned int flags);
 /*
  * Return the compound head page with ref appropriately incremented,
  * or NULL if that failed.
@@ -1179,13 +1186,23 @@ long get_user_pages_remote(struct task_struct *tsk, 
struct mm_struct *mm,
struct vm_area_struct **vmas, int *locked)
 {
/*
-* FIXME: Current FOLL_LONGTERM behavior is incompatible with
+* Parts of FOLL_LONGTERM behavior are incompatible with
 * FAULT_FLAG_ALLOW_RETRY because of the FS DAX check requirement on
-* vmas.  As there are no users of this flag in this call we simply
-* disallow this option for now.
+* vmas. However, this only comes up if locked is set, and there are
+* callers that do request FOLL_LONGTERM, but do not set locked. So,
+* allow what we can.
 */
-   if (WARN_ON_ONCE(gup_flags & FOLL_LONGTERM))
-   return -EINVAL;
+   if (gup_flags & FOLL_LONGTERM) {
+   if (WARN_ON_ONCE(locked))
+   return -EINVAL;
+   /*
+* This will check the vmas (even if our vmas arg is NULL)
+* and return -ENOTSUPP if DAX isn't allowed in this case:
+*/
+   return __gup_longterm_locked(tsk, mm, start, nr_pages, pages,
+vmas, gup_flags | FOLL_TOUCH |
+FOLL_REMOTE);
+   }
 
return __get_user_pages_locked(tsk, mm, start, nr_pages, pages, vmas,
   locked,
-- 
2.24.0

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

[PATCH v8 12/26] IB/{core, hw, umem}: set FOLL_PIN via pin_user_pages*(), fix up ODP

2019-12-09 Thread John Hubbard
Convert infiniband to use the new pin_user_pages*() calls.

Also, revert earlier changes to Infiniband ODP that had it using
put_user_page(). ODP is "Case 3" in
Documentation/core-api/pin_user_pages.rst, which is to say, normal
get_user_pages() and put_page() is the API to use there.

The new pin_user_pages*() calls replace corresponding get_user_pages*()
calls, and set the FOLL_PIN flag. The FOLL_PIN flag requires that the
caller must return the pages via put_user_page*() calls, but infiniband
was already doing that as part of an earlier commit.

Reviewed-by: Jason Gunthorpe 
Signed-off-by: John Hubbard 
---
 drivers/infiniband/core/umem.c  |  2 +-
 drivers/infiniband/core/umem_odp.c  | 13 ++---
 drivers/infiniband/hw/hfi1/user_pages.c |  2 +-
 drivers/infiniband/hw/mthca/mthca_memfree.c |  2 +-
 drivers/infiniband/hw/qib/qib_user_pages.c  |  2 +-
 drivers/infiniband/hw/qib/qib_user_sdma.c   |  2 +-
 drivers/infiniband/hw/usnic/usnic_uiom.c|  2 +-
 drivers/infiniband/sw/siw/siw_mem.c |  2 +-
 8 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 214e87aa609d..55daefaa9b88 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -266,7 +266,7 @@ struct ib_umem *ib_umem_get(struct ib_udata *udata, 
unsigned long addr,
sg = umem->sg_head.sgl;
 
while (npages) {
-   ret = get_user_pages_fast(cur_base,
+   ret = pin_user_pages_fast(cur_base,
  min_t(unsigned long, npages,
PAGE_SIZE /
sizeof(struct page *)),
diff --git a/drivers/infiniband/core/umem_odp.c 
b/drivers/infiniband/core/umem_odp.c
index e42d44e501fd..abc3bb6578cc 100644
--- a/drivers/infiniband/core/umem_odp.c
+++ b/drivers/infiniband/core/umem_odp.c
@@ -308,9 +308,8 @@ EXPORT_SYMBOL(ib_umem_odp_release);
  * The function returns -EFAULT if the DMA mapping operation fails. It returns
  * -EAGAIN if a concurrent invalidation prevents us from updating the page.
  *
- * The page is released via put_user_page even if the operation failed. For
- * on-demand pinning, the page is released whenever it isn't stored in the
- * umem.
+ * The page is released via put_page even if the operation failed. For 
on-demand
+ * pinning, the page is released whenever it isn't stored in the umem.
  */
 static int ib_umem_odp_map_dma_single_page(
struct ib_umem_odp *umem_odp,
@@ -363,7 +362,7 @@ static int ib_umem_odp_map_dma_single_page(
}
 
 out:
-   put_user_page(page);
+   put_page(page);
return ret;
 }
 
@@ -473,7 +472,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem_odp *umem_odp, 
u64 user_virt,
ret = -EFAULT;
break;
}
-   put_user_page(local_page_list[j]);
+   put_page(local_page_list[j]);
continue;
}
 
@@ -500,8 +499,8 @@ int ib_umem_odp_map_dma_pages(struct ib_umem_odp *umem_odp, 
u64 user_virt,
 * ib_umem_odp_map_dma_single_page().
 */
if (npages - (j + 1) > 0)
-   put_user_pages(_page_list[j+1],
-  npages - (j + 1));
+   release_pages(_page_list[j+1],
+ npages - (j + 1));
break;
}
}
diff --git a/drivers/infiniband/hw/hfi1/user_pages.c 
b/drivers/infiniband/hw/hfi1/user_pages.c
index 469acb961fbd..9a94761765c0 100644
--- a/drivers/infiniband/hw/hfi1/user_pages.c
+++ b/drivers/infiniband/hw/hfi1/user_pages.c
@@ -106,7 +106,7 @@ int hfi1_acquire_user_pages(struct mm_struct *mm, unsigned 
long vaddr, size_t np
int ret;
unsigned int gup_flags = FOLL_LONGTERM | (writable ? FOLL_WRITE : 0);
 
-   ret = get_user_pages_fast(vaddr, npages, gup_flags, pages);
+   ret = pin_user_pages_fast(vaddr, npages, gup_flags, pages);
if (ret < 0)
return ret;
 
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c 
b/drivers/infiniband/hw/mthca/mthca_memfree.c
index edccfd6e178f..8269ab040c21 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -472,7 +472,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct 
mthca_uar *uar,
goto out;
}
 
-   ret = get_user_pages_fast(uaddr & PAGE_MASK, 1,
+   ret = pin_user_pages_fast(uaddr & PAGE_MASK, 1,
  FOLL_WRITE | FOLL_LONGTERM, pages);
if (ret < 0)
goto out;
diff --git 

[PATCH v8 08/26] mm/gup: allow FOLL_FORCE for get_user_pages_fast()

2019-12-09 Thread John Hubbard
Commit 817be129e6f2 ("mm: validate get_user_pages_fast flags") allowed
only FOLL_WRITE and FOLL_LONGTERM to be passed to get_user_pages_fast().
This, combined with the fact that get_user_pages_fast() falls back to
"slow gup", which *does* accept FOLL_FORCE, leads to an odd situation:
if you need FOLL_FORCE, you cannot call get_user_pages_fast().

There does not appear to be any reason for filtering out FOLL_FORCE.
There is nothing in the _fast() implementation that requires that we
avoid writing to the pages. So it appears to have been an oversight.

Fix by allowing FOLL_FORCE to be set for get_user_pages_fast().

Fixes: 817be129e6f2 ("mm: validate get_user_pages_fast flags")
Cc: Christoph Hellwig 
Reviewed-by: Leon Romanovsky 
Signed-off-by: John Hubbard 
---
 mm/gup.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/mm/gup.c b/mm/gup.c
index c0c56888e7cc..958ab0757389 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -2414,7 +2414,8 @@ int get_user_pages_fast(unsigned long start, int nr_pages,
unsigned long addr, len, end;
int nr = 0, ret = 0;
 
-   if (WARN_ON_ONCE(gup_flags & ~(FOLL_WRITE | FOLL_LONGTERM)))
+   if (WARN_ON_ONCE(gup_flags & ~(FOLL_WRITE | FOLL_LONGTERM |
+  FOLL_FORCE)))
return -EINVAL;
 
start = untagged_addr(start) & PAGE_MASK;
-- 
2.24.0

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

[PATCH v8 18/26] media/v4l2-core: pin_user_pages (FOLL_PIN) and put_user_page() conversion

2019-12-09 Thread John Hubbard
1. Change v4l2 from get_user_pages() to pin_user_pages().

2. Because all FOLL_PIN-acquired pages must be released via
put_user_page(), also convert the put_page() call over to
put_user_pages_dirty_lock().

Acked-by: Hans Verkuil 
Cc: Ira Weiny 
Signed-off-by: John Hubbard 
---
 drivers/media/v4l2-core/videobuf-dma-sg.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c 
b/drivers/media/v4l2-core/videobuf-dma-sg.c
index 28262190c3ab..162a2633b1e3 100644
--- a/drivers/media/v4l2-core/videobuf-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf-dma-sg.c
@@ -183,12 +183,12 @@ static int videobuf_dma_init_user_locked(struct 
videobuf_dmabuf *dma,
dprintk(1, "init user [0x%lx+0x%lx => %d pages]\n",
data, size, dma->nr_pages);
 
-   err = get_user_pages(data & PAGE_MASK, dma->nr_pages,
+   err = pin_user_pages(data & PAGE_MASK, dma->nr_pages,
 flags | FOLL_LONGTERM, dma->pages, NULL);
 
if (err != dma->nr_pages) {
dma->nr_pages = (err >= 0) ? err : 0;
-   dprintk(1, "get_user_pages: err=%d [%d]\n", err,
+   dprintk(1, "pin_user_pages: err=%d [%d]\n", err,
dma->nr_pages);
return err < 0 ? err : -EINVAL;
}
@@ -349,11 +349,8 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma)
BUG_ON(dma->sglen);
 
if (dma->pages) {
-   for (i = 0; i < dma->nr_pages; i++) {
-   if (dma->direction == DMA_FROM_DEVICE)
-   set_page_dirty_lock(dma->pages[i]);
-   put_page(dma->pages[i]);
-   }
+   put_user_pages_dirty_lock(dma->pages, dma->nr_pages,
+ dma->direction == DMA_FROM_DEVICE);
kfree(dma->pages);
dma->pages = NULL;
}
-- 
2.24.0

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

[PATCH v8 01/26] mm/gup: factor out duplicate code from four routines

2019-12-09 Thread John Hubbard
There are four locations in gup.c that have a fair amount of code
duplication. This means that changing one requires making the same
changes in four places, not to mention reading the same code four
times, and wondering if there are subtle differences.

Factor out the common code into static functions, thus reducing the
overall line count and the code's complexity.

Also, take the opportunity to slightly improve the efficiency of the
error cases, by doing a mass subtraction of the refcount, surrounded
by get_page()/put_page().

Also, further simplify (slightly), by waiting until the the successful
end of each routine, to increment *nr.

Reviewed-by: Christoph Hellwig 
Reviewed-by: Jérôme Glisse 
Reviewed-by: Jan Kara 
Cc: Ira Weiny 
Cc: Christoph Hellwig 
Cc: Aneesh Kumar K.V 
Signed-off-by: John Hubbard 
---
 mm/gup.c | 91 ++--
 1 file changed, 36 insertions(+), 55 deletions(-)

diff --git a/mm/gup.c b/mm/gup.c
index 7646bf993b25..f764432914c4 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1978,6 +1978,25 @@ static int __gup_device_huge_pud(pud_t pud, pud_t *pudp, 
unsigned long addr,
 }
 #endif
 
+static int record_subpages(struct page *page, unsigned long addr,
+  unsigned long end, struct page **pages)
+{
+   int nr;
+
+   for (nr = 0; addr != end; addr += PAGE_SIZE)
+   pages[nr++] = page++;
+
+   return nr;
+}
+
+static void put_compound_head(struct page *page, int refs)
+{
+   /* Do a get_page() first, in case refs == page->_refcount */
+   get_page(page);
+   page_ref_sub(page, refs);
+   put_page(page);
+}
+
 #ifdef CONFIG_ARCH_HAS_HUGEPD
 static unsigned long hugepte_addr_end(unsigned long addr, unsigned long end,
  unsigned long sz)
@@ -2007,32 +2026,20 @@ static int gup_hugepte(pte_t *ptep, unsigned long sz, 
unsigned long addr,
/* hugepages are never "special" */
VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
 
-   refs = 0;
head = pte_page(pte);
-
page = head + ((addr & (sz-1)) >> PAGE_SHIFT);
-   do {
-   VM_BUG_ON(compound_head(page) != head);
-   pages[*nr] = page;
-   (*nr)++;
-   page++;
-   refs++;
-   } while (addr += PAGE_SIZE, addr != end);
+   refs = record_subpages(page, addr, end, pages + *nr);
 
head = try_get_compound_head(head, refs);
-   if (!head) {
-   *nr -= refs;
+   if (!head)
return 0;
-   }
 
if (unlikely(pte_val(pte) != pte_val(*ptep))) {
-   /* Could be optimized better */
-   *nr -= refs;
-   while (refs--)
-   put_page(head);
+   put_compound_head(head, refs);
return 0;
}
 
+   *nr += refs;
SetPageReferenced(head);
return 1;
 }
@@ -2079,28 +2086,19 @@ static int gup_huge_pmd(pmd_t orig, pmd_t *pmdp, 
unsigned long addr,
return __gup_device_huge_pmd(orig, pmdp, addr, end, pages, nr);
}
 
-   refs = 0;
page = pmd_page(orig) + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
-   do {
-   pages[*nr] = page;
-   (*nr)++;
-   page++;
-   refs++;
-   } while (addr += PAGE_SIZE, addr != end);
+   refs = record_subpages(page, addr, end, pages + *nr);
 
head = try_get_compound_head(pmd_page(orig), refs);
-   if (!head) {
-   *nr -= refs;
+   if (!head)
return 0;
-   }
 
if (unlikely(pmd_val(orig) != pmd_val(*pmdp))) {
-   *nr -= refs;
-   while (refs--)
-   put_page(head);
+   put_compound_head(head, refs);
return 0;
}
 
+   *nr += refs;
SetPageReferenced(head);
return 1;
 }
@@ -2120,28 +2118,19 @@ static int gup_huge_pud(pud_t orig, pud_t *pudp, 
unsigned long addr,
return __gup_device_huge_pud(orig, pudp, addr, end, pages, nr);
}
 
-   refs = 0;
page = pud_page(orig) + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
-   do {
-   pages[*nr] = page;
-   (*nr)++;
-   page++;
-   refs++;
-   } while (addr += PAGE_SIZE, addr != end);
+   refs = record_subpages(page, addr, end, pages + *nr);
 
head = try_get_compound_head(pud_page(orig), refs);
-   if (!head) {
-   *nr -= refs;
+   if (!head)
return 0;
-   }
 
if (unlikely(pud_val(orig) != pud_val(*pudp))) {
-   *nr -= refs;
-   while (refs--)
-   put_page(head);
+   put_compound_head(head, refs);
return 0;
}
 
+   *nr += refs;
SetPageReferenced(head);
return 1;
 }
@@ -2157,28 +2146,20 @@ static int gup_huge_pgd(pgd_t orig, pgd_t *pgdp, 
unsigned long 

[PATCH v8 09/26] IB/umem: use get_user_pages_fast() to pin DMA pages

2019-12-09 Thread John Hubbard
And get rid of the mmap_sem calls, as part of that. Note
that get_user_pages_fast() will, if necessary, fall back to
__gup_longterm_unlocked(), which takes the mmap_sem as needed.

Reviewed-by: Leon Romanovsky 
Reviewed-by: Christoph Hellwig 
Reviewed-by: Jan Kara 
Reviewed-by: Jason Gunthorpe 
Reviewed-by: Ira Weiny 
Signed-off-by: John Hubbard 
---
 drivers/infiniband/core/umem.c | 17 ++---
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 7a3b99597ead..214e87aa609d 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -266,16 +266,13 @@ struct ib_umem *ib_umem_get(struct ib_udata *udata, 
unsigned long addr,
sg = umem->sg_head.sgl;
 
while (npages) {
-   down_read(>mmap_sem);
-   ret = get_user_pages(cur_base,
-min_t(unsigned long, npages,
-  PAGE_SIZE / sizeof (struct page *)),
-gup_flags | FOLL_LONGTERM,
-page_list, NULL);
-   if (ret < 0) {
-   up_read(>mmap_sem);
+   ret = get_user_pages_fast(cur_base,
+ min_t(unsigned long, npages,
+   PAGE_SIZE /
+   sizeof(struct page *)),
+ gup_flags | FOLL_LONGTERM, page_list);
+   if (ret < 0)
goto umem_release;
-   }
 
cur_base += ret * PAGE_SIZE;
npages   -= ret;
@@ -283,8 +280,6 @@ struct ib_umem *ib_umem_get(struct ib_udata *udata, 
unsigned long addr,
sg = ib_umem_add_sg_table(sg, page_list, ret,
dma_get_max_seg_size(context->device->dma_device),
>sg_nents);
-
-   up_read(>mmap_sem);
}
 
sg_mark_end(sg);
-- 
2.24.0

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

[PATCH v8 00/26] mm/gup: track dma-pinned pages: FOLL_PIN

2019-12-09 Thread John Hubbard
Hi,

This implements an API naming change (put_user_page*() -->
unpin_user_page*()), and also implements tracking of FOLL_PIN pages. It
extends that tracking to a few select subsystems. More subsystems will
be added in follow up work.

Christoph Hellwig, a couple of points of interest:

a) I've moved the bulk of the code out of the inline functions, as
   requested, for the devmap changes (patch 4: "mm: devmap: refactor
   1-based refcounting for ZONE_DEVICE pages").

b) Contrary to my earlier response to your review, I have not actually
   merged patch 23 ("mm/gup: pass flags arg to __gup_device_*
   functions") into patch 24 ("mm/gup: track FOLL_PIN pages"). This is
   because I suspect that it's better to avoid making patch 24 any larger
   and worse to review than it already is. But if you feel strongly
   about it, I'll combine them anyway.

Changes since v7:

* Rebased onto Linux 5.5-rc1

* Reworked the grab_page() and try_grab_compound_head(), for API
  consistency and less diffs (thanks to Jan Kara's reviews).

* Added Leon Romanovsky's reviewed-by tags for two of the IB-related
  patches.

* patch 4 refactoring changes, as mentioned above.

There is a git repo and branch, for convenience:

g...@github.com:johnhubbard/linux.git pin_user_pages_tracking_v8

For the remaining list of "changes since version N", those are all in
v7, which is here:

  https://lore.kernel.org/r/20191121071354.456618-1-jhubb...@nvidia.com


Overview:

This is a prerequisite to solving the problem of proper interactions
between file-backed pages, and [R]DMA activities, as discussed in [1],
[2], [3], and in a remarkable number of email threads since about
2017. :)

A new internal gup flag, FOLL_PIN is introduced, and thoroughly
documented in the last patch's Documentation/vm/pin_user_pages.rst.

I believe that this will provide a good starting point for doing the
layout lease work that Ira Weiny has been working on. That's because
these new wrapper functions provide a clean, constrained, systematically
named set of functionality that, again, is required in order to even
know if a page is "dma-pinned".

In contrast to earlier approaches, the page tracking can be
incrementally applied to the kernel call sites that, until now, have
been simply calling get_user_pages() ("gup"). In other words, opt-in by
changing from this:

get_user_pages() (sets FOLL_GET)
put_page()

to this:
pin_user_pages() (sets FOLL_PIN)
unpin_user_page()


Testing:

* I've done some overall kernel testing (LTP, and a few other goodies),
  and some directed testing to exercise some of the changes. And as you
  can see, gup_benchmark is enhanced to exercise this. Basically, I've
  been able to runtime test the core get_user_pages() and
  pin_user_pages() and related routines, but not so much on several of
  the call sites--but those are generally just a couple of lines
  changed, each.

  Not much of the kernel is actually using this, which on one hand
  reduces risk quite a lot. But on the other hand, testing coverage
  is low. So I'd love it if, in particular, the Infiniband and PowerPC
  folks could do a smoke test of this series for me.

  Runtime testing for the call sites so far is pretty light:

* io_uring: Some directed tests from liburing exercise this, and
they pass.
* process_vm_access.c: A small directed test passes.
* gup_benchmark: the enhanced version hits the new gup.c code, and
 passes.
* infiniband: ran "ib_write_bw", which exercises the umem.c changes,
  but not the other changes.
* VFIO: compiles (I'm vowing to set up a run time test soon, but it's
  not ready just yet)
* powerpc: it compiles...
* drm/via: compiles...
* goldfish: compiles...
* net/xdp: compiles...
* media/v4l2: compiles...

[1] Some slow progress on get_user_pages() (Apr 2, 2019): 
https://lwn.net/Articles/784574/
[2] DMA and get_user_pages() (LPC: Dec 12, 2018): 
https://lwn.net/Articles/774411/
[3] The trouble with get_user_pages() (Apr 30, 2018): 
https://lwn.net/Articles/753027/

Dan Williams (1):
  mm: Cleanup __put_devmap_managed_page() vs ->page_free()

John Hubbard (25):
  mm/gup: factor out duplicate code from four routines
  mm/gup: move try_get_compound_head() to top, fix minor issues
  mm: devmap: refactor 1-based refcounting for ZONE_DEVICE pages
  goldish_pipe: rename local pin_user_pages() routine
  mm: fix get_user_pages_remote()'s handling of FOLL_LONGTERM
  vfio: fix FOLL_LONGTERM use, simplify get_user_pages_remote() call
  mm/gup: allow FOLL_FORCE for get_user_pages_fast()
  IB/umem: use get_user_pages_fast() to pin DMA pages
  mm/gup: introduce pin_user_pages*() and FOLL_PIN
  goldish_pipe: convert to pin_user_pages() and put_user_page()
  IB/{core,hw,umem}: set FOLL_PIN via pin_user_pages*(), fix up 

[PATCH v8 10/26] mm/gup: introduce pin_user_pages*() and FOLL_PIN

2019-12-09 Thread John Hubbard
Introduce pin_user_pages*() variations of get_user_pages*() calls,
and also pin_longterm_pages*() variations.

For now, these are placeholder calls, until the various call sites
are converted to use the correct get_user_pages*() or
pin_user_pages*() API.

These variants will eventually all set FOLL_PIN, which is also
introduced, and thoroughly documented.

pin_user_pages()
pin_user_pages_remote()
pin_user_pages_fast()

All pages that are pinned via the above calls, must be unpinned via
put_user_page().

The underlying rules are:

* FOLL_PIN is a gup-internal flag, so the call sites should not directly
set it. That behavior is enforced with assertions.

* Call sites that want to indicate that they are going to do DirectIO
  ("DIO") or something with similar characteristics, should call a
  get_user_pages()-like wrapper call that sets FOLL_PIN. These wrappers
  will:
* Start with "pin_user_pages" instead of "get_user_pages". That
  makes it easy to find and audit the call sites.
* Set FOLL_PIN

* For pages that are received via FOLL_PIN, those pages must be returned
  via put_user_page().

Thanks to Jan Kara and Vlastimil Babka for explaining the 4 cases
in this documentation. (I've reworded it and expanded upon it.)

Reviewed-by: Jan Kara 
Reviewed-by: Mike Rapoport   # Documentation
Reviewed-by: Jérôme Glisse 
Cc: Jonathan Corbet 
Cc: Ira Weiny 
Signed-off-by: John Hubbard 
---
 Documentation/core-api/index.rst  |   1 +
 Documentation/core-api/pin_user_pages.rst | 233 ++
 include/linux/mm.h|  63 --
 mm/gup.c  | 161 +--
 4 files changed, 424 insertions(+), 34 deletions(-)
 create mode 100644 Documentation/core-api/pin_user_pages.rst

diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst
index ab0eae1c153a..413f7d7c8642 100644
--- a/Documentation/core-api/index.rst
+++ b/Documentation/core-api/index.rst
@@ -31,6 +31,7 @@ Core utilities
generic-radix-tree
memory-allocation
mm-api
+   pin_user_pages
gfp_mask-from-fs-io
timekeeping
boot-time-mm
diff --git a/Documentation/core-api/pin_user_pages.rst 
b/Documentation/core-api/pin_user_pages.rst
new file mode 100644
index ..4f26637a5005
--- /dev/null
+++ b/Documentation/core-api/pin_user_pages.rst
@@ -0,0 +1,233 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+
+pin_user_pages() and related calls
+
+
+.. contents:: :local:
+
+Overview
+
+
+This document describes the following functions: ::
+
+ pin_user_pages
+ pin_user_pages_fast
+ pin_user_pages_remote
+
+Basic description of FOLL_PIN
+=
+
+FOLL_PIN and FOLL_LONGTERM are flags that can be passed to the 
get_user_pages*()
+("gup") family of functions. FOLL_PIN has significant interactions and
+interdependencies with FOLL_LONGTERM, so both are covered here.
+
+FOLL_PIN is internal to gup, meaning that it should not appear at the gup call
+sites. This allows the associated wrapper functions  (pin_user_pages*() and
+others) to set the correct combination of these flags, and to check for 
problems
+as well.
+
+FOLL_LONGTERM, on the other hand, *is* allowed to be set at the gup call sites.
+This is in order to avoid creating a large number of wrapper functions to cover
+all combinations of get*(), pin*(), FOLL_LONGTERM, and more. Also, the
+pin_user_pages*() APIs are clearly distinct from the get_user_pages*() APIs, so
+that's a natural dividing line, and a good point to make separate wrapper 
calls.
+In other words, use pin_user_pages*() for DMA-pinned pages, and
+get_user_pages*() for other cases. There are four cases described later on in
+this document, to further clarify that concept.
+
+FOLL_PIN and FOLL_GET are mutually exclusive for a given gup call. However,
+multiple threads and call sites are free to pin the same struct pages, via both
+FOLL_PIN and FOLL_GET. It's just the call site that needs to choose one or the
+other, not the struct page(s).
+
+The FOLL_PIN implementation is nearly the same as FOLL_GET, except that 
FOLL_PIN
+uses a different reference counting technique.
+
+FOLL_PIN is a prerequisite to FOLL_LONGTGERM. Another way of saying that is,
+FOLL_LONGTERM is a specific case, more restrictive case of FOLL_PIN.
+
+Which flags are set by each wrapper
+===
+
+For these pin_user_pages*() functions, FOLL_PIN is OR'd in with whatever gup
+flags the caller provides. The caller is required to pass in a non-null struct
+pages* array, and the function then pin pages by incrementing each by a special
+value. For now, that value is +1, just like get_user_pages*().::
+
+ Function
+ 
+ pin_user_pages  FOLL_PIN is always set internally by this function.
+ pin_user_pages_fast FOLL_PIN is always set internally by this function.
+ 

[PATCH v8 02/26] mm/gup: move try_get_compound_head() to top, fix minor issues

2019-12-09 Thread John Hubbard
An upcoming patch uses try_get_compound_head() more widely,
so move it to the top of gup.c.

Also fix a tiny spelling error and a checkpatch.pl warning.

Reviewed-by: Christoph Hellwig 
Reviewed-by: Jan Kara 
Reviewed-by: Ira Weiny 
Signed-off-by: John Hubbard 
---
 mm/gup.c | 29 +++--
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/mm/gup.c b/mm/gup.c
index f764432914c4..3ecce297a47f 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -29,6 +29,21 @@ struct follow_page_context {
unsigned int page_mask;
 };
 
+/*
+ * Return the compound head page with ref appropriately incremented,
+ * or NULL if that failed.
+ */
+static inline struct page *try_get_compound_head(struct page *page, int refs)
+{
+   struct page *head = compound_head(page);
+
+   if (WARN_ON_ONCE(page_ref_count(head) < 0))
+   return NULL;
+   if (unlikely(!page_cache_add_speculative(head, refs)))
+   return NULL;
+   return head;
+}
+
 /**
  * put_user_pages_dirty_lock() - release and optionally dirty gup-pinned pages
  * @pages:  array of pages to be maybe marked dirty, and definitely released.
@@ -1807,20 +1822,6 @@ static void __maybe_unused undo_dev_pagemap(int *nr, int 
nr_start,
}
 }
 
-/*
- * Return the compund head page with ref appropriately incremented,
- * or NULL if that failed.
- */
-static inline struct page *try_get_compound_head(struct page *page, int refs)
-{
-   struct page *head = compound_head(page);
-   if (WARN_ON_ONCE(page_ref_count(head) < 0))
-   return NULL;
-   if (unlikely(!page_cache_add_speculative(head, refs)))
-   return NULL;
-   return head;
-}
-
 #ifdef CONFIG_ARCH_HAS_PTE_SPECIAL
 static int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end,
 unsigned int flags, struct page **pages, int *nr)
-- 
2.24.0

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

[PATCH v8 17/26] media/v4l2-core: set pages dirty upon releasing DMA buffers

2019-12-09 Thread John Hubbard
After DMA is complete, and the device and CPU caches are synchronized,
it's still required to mark the CPU pages as dirty, if the data was
coming from the device. However, this driver was just issuing a
bare put_page() call, without any set_page_dirty*() call.

Fix the problem, by calling set_page_dirty_lock() if the CPU pages
were potentially receiving data from the device.

Reviewed-by: Christoph Hellwig 
Acked-by: Hans Verkuil 
Cc: Mauro Carvalho Chehab 
Cc: 
Signed-off-by: John Hubbard 
---
 drivers/media/v4l2-core/videobuf-dma-sg.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c 
b/drivers/media/v4l2-core/videobuf-dma-sg.c
index 66a6c6c236a7..28262190c3ab 100644
--- a/drivers/media/v4l2-core/videobuf-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf-dma-sg.c
@@ -349,8 +349,11 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma)
BUG_ON(dma->sglen);
 
if (dma->pages) {
-   for (i = 0; i < dma->nr_pages; i++)
+   for (i = 0; i < dma->nr_pages; i++) {
+   if (dma->direction == DMA_FROM_DEVICE)
+   set_page_dirty_lock(dma->pages[i]);
put_page(dma->pages[i]);
+   }
kfree(dma->pages);
dma->pages = NULL;
}
-- 
2.24.0

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

[PATCH v8 20/26] powerpc: book3s64: convert to pin_user_pages() and put_user_page()

2019-12-09 Thread John Hubbard
1. Convert from get_user_pages() to pin_user_pages().

2. As required by pin_user_pages(), release these pages via
put_user_page(). In this case, do so via put_user_pages_dirty_lock().

That has the side effect of calling set_page_dirty_lock(), instead
of set_page_dirty(). This is probably more accurate.

As Christoph Hellwig put it, "set_page_dirty() is only safe if we are
dealing with a file backed page where we have reference on the inode it
hangs off." [1]

[1] https://lore.kernel.org/r/20190723153640.gb...@lst.de

Cc: Jan Kara 
Signed-off-by: John Hubbard 
---
 arch/powerpc/mm/book3s64/iommu_api.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/mm/book3s64/iommu_api.c 
b/arch/powerpc/mm/book3s64/iommu_api.c
index 56cc84520577..fc1670a6fc3c 100644
--- a/arch/powerpc/mm/book3s64/iommu_api.c
+++ b/arch/powerpc/mm/book3s64/iommu_api.c
@@ -103,7 +103,7 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, 
unsigned long ua,
for (entry = 0; entry < entries; entry += chunk) {
unsigned long n = min(entries - entry, chunk);
 
-   ret = get_user_pages(ua + (entry << PAGE_SHIFT), n,
+   ret = pin_user_pages(ua + (entry << PAGE_SHIFT), n,
FOLL_WRITE | FOLL_LONGTERM,
mem->hpages + entry, NULL);
if (ret == n) {
@@ -167,9 +167,8 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, 
unsigned long ua,
return 0;
 
 free_exit:
-   /* free the reference taken */
-   for (i = 0; i < pinned; i++)
-   put_page(mem->hpages[i]);
+   /* free the references taken */
+   put_user_pages(mem->hpages, pinned);
 
vfree(mem->hpas);
kfree(mem);
@@ -212,10 +211,9 @@ static void mm_iommu_unpin(struct 
mm_iommu_table_group_mem_t *mem)
if (!page)
continue;
 
-   if (mem->hpas[i] & MM_IOMMU_TABLE_GROUP_PAGE_DIRTY)
-   SetPageDirty(page);
+   put_user_pages_dirty_lock(, 1,
+   mem->hpas[i] & MM_IOMMU_TABLE_GROUP_PAGE_DIRTY);
 
-   put_page(page);
mem->hpas[i] = 0;
}
 }
-- 
2.24.0

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

[PATCH v8 13/26] mm/process_vm_access: set FOLL_PIN via pin_user_pages_remote()

2019-12-09 Thread John Hubbard
Convert process_vm_access to use the new pin_user_pages_remote()
call, which sets FOLL_PIN. Setting FOLL_PIN is now required for
code that requires tracking of pinned pages.

Also, release the pages via put_user_page*().

Also, rename "pages" to "pinned_pages", as this makes for
easier reading of process_vm_rw_single_vec().

Reviewed-by: Jan Kara 
Reviewed-by: Jérôme Glisse 
Reviewed-by: Ira Weiny 
Signed-off-by: John Hubbard 
---
 mm/process_vm_access.c | 28 +++-
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/mm/process_vm_access.c b/mm/process_vm_access.c
index 357aa7bef6c0..fd20ab675b85 100644
--- a/mm/process_vm_access.c
+++ b/mm/process_vm_access.c
@@ -42,12 +42,11 @@ static int process_vm_rw_pages(struct page **pages,
if (copy > len)
copy = len;
 
-   if (vm_write) {
+   if (vm_write)
copied = copy_page_from_iter(page, offset, copy, iter);
-   set_page_dirty_lock(page);
-   } else {
+   else
copied = copy_page_to_iter(page, offset, copy, iter);
-   }
+
len -= copied;
if (copied < copy && iov_iter_count(iter))
return -EFAULT;
@@ -96,7 +95,7 @@ static int process_vm_rw_single_vec(unsigned long addr,
flags |= FOLL_WRITE;
 
while (!rc && nr_pages && iov_iter_count(iter)) {
-   int pages = min(nr_pages, max_pages_per_loop);
+   int pinned_pages = min(nr_pages, max_pages_per_loop);
int locked = 1;
size_t bytes;
 
@@ -106,14 +105,15 @@ static int process_vm_rw_single_vec(unsigned long addr,
 * current/current->mm
 */
down_read(>mmap_sem);
-   pages = get_user_pages_remote(task, mm, pa, pages, flags,
- process_pages, NULL, );
+   pinned_pages = pin_user_pages_remote(task, mm, pa, pinned_pages,
+flags, process_pages,
+NULL, );
if (locked)
up_read(>mmap_sem);
-   if (pages <= 0)
+   if (pinned_pages <= 0)
return -EFAULT;
 
-   bytes = pages * PAGE_SIZE - start_offset;
+   bytes = pinned_pages * PAGE_SIZE - start_offset;
if (bytes > len)
bytes = len;
 
@@ -122,10 +122,12 @@ static int process_vm_rw_single_vec(unsigned long addr,
 vm_write);
len -= bytes;
start_offset = 0;
-   nr_pages -= pages;
-   pa += pages * PAGE_SIZE;
-   while (pages)
-   put_page(process_pages[--pages]);
+   nr_pages -= pinned_pages;
+   pa += pinned_pages * PAGE_SIZE;
+
+   /* If vm_write is set, the pages need to be made dirty: */
+   put_user_pages_dirty_lock(process_pages, pinned_pages,
+ vm_write);
}
 
return rc;
-- 
2.24.0

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

[PATCH v8 04/26] mm: devmap: refactor 1-based refcounting for ZONE_DEVICE pages

2019-12-09 Thread John Hubbard
An upcoming patch changes and complicates the refcounting and
especially the "put page" aspects of it. In order to keep
everything clean, refactor the devmap page release routines:

* Rename put_devmap_managed_page() to page_is_devmap_managed(),
  and limit the functionality to "read only": return a bool,
  with no side effects.

* Add a new routine, put_devmap_managed_page(), to handle checking
  what kind of page it is, and what kind of refcount handling it
  requires.

* Rename __put_devmap_managed_page() to free_devmap_managed_page(),
  and limit the functionality to unconditionally freeing a devmap
  page.

This is originally based on a separate patch by Ira Weiny, which
applied to an early version of the put_user_page() experiments.
Since then, Jérôme Glisse suggested the refactoring described above.

Cc: Christoph Hellwig 
Suggested-by: Jérôme Glisse 
Reviewed-by: Dan Williams 
Reviewed-by: Jan Kara 
Signed-off-by: Ira Weiny 
Signed-off-by: John Hubbard 
---
 include/linux/mm.h | 17 +
 mm/memremap.c  | 16 ++--
 mm/swap.c  | 24 
 3 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index c97ea3b694e6..77a4df06c8a7 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -952,9 +952,10 @@ static inline bool is_zone_device_page(const struct page 
*page)
 #endif
 
 #ifdef CONFIG_DEV_PAGEMAP_OPS
-void __put_devmap_managed_page(struct page *page);
+void free_devmap_managed_page(struct page *page);
 DECLARE_STATIC_KEY_FALSE(devmap_managed_key);
-static inline bool put_devmap_managed_page(struct page *page)
+
+static inline bool page_is_devmap_managed(struct page *page)
 {
if (!static_branch_unlikely(_managed_key))
return false;
@@ -963,7 +964,6 @@ static inline bool put_devmap_managed_page(struct page 
*page)
switch (page->pgmap->type) {
case MEMORY_DEVICE_PRIVATE:
case MEMORY_DEVICE_FS_DAX:
-   __put_devmap_managed_page(page);
return true;
default:
break;
@@ -971,7 +971,14 @@ static inline bool put_devmap_managed_page(struct page 
*page)
return false;
 }
 
+bool put_devmap_managed_page(struct page *page);
+
 #else /* CONFIG_DEV_PAGEMAP_OPS */
+static inline bool page_is_devmap_managed(struct page *page)
+{
+   return false;
+}
+
 static inline bool put_devmap_managed_page(struct page *page)
 {
return false;
@@ -1028,8 +1035,10 @@ static inline void put_page(struct page *page)
 * need to inform the device driver through callback. See
 * include/linux/memremap.h and HMM for details.
 */
-   if (put_devmap_managed_page(page))
+   if (page_is_devmap_managed(page)) {
+   put_devmap_managed_page(page);
return;
+   }
 
if (put_page_testzero(page))
__put_page(page);
diff --git a/mm/memremap.c b/mm/memremap.c
index e899fa876a62..2ba773859031 100644
--- a/mm/memremap.c
+++ b/mm/memremap.c
@@ -411,20 +411,8 @@ struct dev_pagemap *get_dev_pagemap(unsigned long pfn,
 EXPORT_SYMBOL_GPL(get_dev_pagemap);
 
 #ifdef CONFIG_DEV_PAGEMAP_OPS
-void __put_devmap_managed_page(struct page *page)
+void free_devmap_managed_page(struct page *page)
 {
-   int count = page_ref_dec_return(page);
-
-   /* still busy */
-   if (count > 1)
-   return;
-
-   /* only triggered by the dev_pagemap shutdown path */
-   if (count == 0) {
-   __put_page(page);
-   return;
-   }
-
/* notify page idle for dax */
if (!is_device_private_page(page)) {
wake_up_var(>_refcount);
@@ -461,5 +449,5 @@ void __put_devmap_managed_page(struct page *page)
page->mapping = NULL;
page->pgmap->ops->page_free(page);
 }
-EXPORT_SYMBOL(__put_devmap_managed_page);
+EXPORT_SYMBOL(free_devmap_managed_page);
 #endif /* CONFIG_DEV_PAGEMAP_OPS */
diff --git a/mm/swap.c b/mm/swap.c
index 5341ae93861f..49f7c2eea0ba 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -1102,3 +1102,27 @@ void __init swap_setup(void)
 * _really_ don't want to cluster much more
 */
 }
+
+#ifdef CONFIG_DEV_PAGEMAP_OPS
+bool put_devmap_managed_page(struct page *page)
+{
+   bool is_devmap = page_is_devmap_managed(page);
+
+   if (is_devmap) {
+   int count = page_ref_dec_return(page);
+
+   /*
+* devmap page refcounts are 1-based, rather than 0-based: if
+* refcount is 1, then the page is free and the refcount is
+* stable because nobody holds a reference on the page.
+*/
+   if (count == 1)
+   free_devmap_managed_page(page);
+   else if (!count)
+   __put_page(page);
+   }
+
+   return is_devmap;
+}
+EXPORT_SYMBOL(put_devmap_managed_page);
+#endif
-- 
2.24.0


[PATCH v8 11/26] goldish_pipe: convert to pin_user_pages() and put_user_page()

2019-12-09 Thread John Hubbard
1. Call the new global pin_user_pages_fast(), from pin_goldfish_pages().

2. As required by pin_user_pages(), release these pages via
put_user_page(). In this case, do so via put_user_pages_dirty_lock().

That has the side effect of calling set_page_dirty_lock(), instead
of set_page_dirty(). This is probably more accurate.

As Christoph Hellwig put it, "set_page_dirty() is only safe if we are
dealing with a file backed page where we have reference on the inode it
hangs off." [1]

Another side effect is that the release code is simplified because
the page[] loop is now in gup.c instead of here, so just delete the
local release_user_pages() entirely, and call
put_user_pages_dirty_lock() directly, instead.

[1] https://lore.kernel.org/r/20190723153640.gb...@lst.de

Reviewed-by: Jan Kara 
Reviewed-by: Ira Weiny 
Signed-off-by: John Hubbard 
---
 drivers/platform/goldfish/goldfish_pipe.c | 17 +++--
 1 file changed, 3 insertions(+), 14 deletions(-)

diff --git a/drivers/platform/goldfish/goldfish_pipe.c 
b/drivers/platform/goldfish/goldfish_pipe.c
index ef50c264db71..2a5901efecde 100644
--- a/drivers/platform/goldfish/goldfish_pipe.c
+++ b/drivers/platform/goldfish/goldfish_pipe.c
@@ -274,7 +274,7 @@ static int goldfish_pin_pages(unsigned long first_page,
*iter_last_page_size = last_page_size;
}
 
-   ret = get_user_pages_fast(first_page, requested_pages,
+   ret = pin_user_pages_fast(first_page, requested_pages,
  !is_write ? FOLL_WRITE : 0,
  pages);
if (ret <= 0)
@@ -285,18 +285,6 @@ static int goldfish_pin_pages(unsigned long first_page,
return ret;
 }
 
-static void release_user_pages(struct page **pages, int pages_count,
-  int is_write, s32 consumed_size)
-{
-   int i;
-
-   for (i = 0; i < pages_count; i++) {
-   if (!is_write && consumed_size > 0)
-   set_page_dirty(pages[i]);
-   put_page(pages[i]);
-   }
-}
-
 /* Populate the call parameters, merging adjacent pages together */
 static void populate_rw_params(struct page **pages,
   int pages_count,
@@ -372,7 +360,8 @@ static int transfer_max_buffers(struct goldfish_pipe *pipe,
 
*consumed_size = pipe->command_buffer->rw_params.consumed_size;
 
-   release_user_pages(pipe->pages, pages_count, is_write, *consumed_size);
+   put_user_pages_dirty_lock(pipe->pages, pages_count,
+ !is_write && *consumed_size > 0);
 
mutex_unlock(>lock);
return 0;
-- 
2.24.0

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

[PATCH v8 14/26] drm/via: set FOLL_PIN via pin_user_pages_fast()

2019-12-09 Thread John Hubbard
Convert drm/via to use the new pin_user_pages_fast() call, which sets
FOLL_PIN. Setting FOLL_PIN is now required for code that requires
tracking of pinned pages, and therefore for any code that calls
put_user_page().

In partial anticipation of this work, the drm/via driver was already
calling put_user_page() instead of put_page(). Therefore, in order to
convert from the get_user_pages()/put_page() model, to the
pin_user_pages()/put_user_page() model, the only change required
is to change get_user_pages() to pin_user_pages().

Acked-by: Daniel Vetter 
Reviewed-by: Jérôme Glisse 
Reviewed-by: Ira Weiny 
Signed-off-by: John Hubbard 
---
 drivers/gpu/drm/via/via_dmablit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/via/via_dmablit.c 
b/drivers/gpu/drm/via/via_dmablit.c
index 3db000aacd26..37c5e572993a 100644
--- a/drivers/gpu/drm/via/via_dmablit.c
+++ b/drivers/gpu/drm/via/via_dmablit.c
@@ -239,7 +239,7 @@ via_lock_all_dma_pages(drm_via_sg_info_t *vsg,  
drm_via_dmablit_t *xfer)
vsg->pages = vzalloc(array_size(sizeof(struct page *), vsg->num_pages));
if (NULL == vsg->pages)
return -ENOMEM;
-   ret = get_user_pages_fast((unsigned long)xfer->mem_addr,
+   ret = pin_user_pages_fast((unsigned long)xfer->mem_addr,
vsg->num_pages,
vsg->direction == DMA_FROM_DEVICE ? FOLL_WRITE : 0,
vsg->pages);
-- 
2.24.0

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

[PATCH v8 15/26] fs/io_uring: set FOLL_PIN via pin_user_pages()

2019-12-09 Thread John Hubbard
Convert fs/io_uring to use the new pin_user_pages() call, which sets
FOLL_PIN. Setting FOLL_PIN is now required for code that requires
tracking of pinned pages, and therefore for any code that calls
put_user_page().

In partial anticipation of this work, the io_uring code was already
calling put_user_page() instead of put_page(). Therefore, in order to
convert from the get_user_pages()/put_page() model, to the
pin_user_pages()/put_user_page() model, the only change required
here is to change get_user_pages() to pin_user_pages().

Reviewed-by: Jens Axboe 
Reviewed-by: Jan Kara 
Signed-off-by: John Hubbard 
---
 fs/io_uring.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index 405be10da73d..9639ebc21e8a 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -4521,7 +4521,7 @@ static int io_sqe_buffer_register(struct io_ring_ctx 
*ctx, void __user *arg,
 
ret = 0;
down_read(>mm->mmap_sem);
-   pret = get_user_pages(ubuf, nr_pages,
+   pret = pin_user_pages(ubuf, nr_pages,
  FOLL_WRITE | FOLL_LONGTERM,
  pages, vmas);
if (pret == nr_pages) {
-- 
2.24.0

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

[PATCH v8 07/26] vfio: fix FOLL_LONGTERM use, simplify get_user_pages_remote() call

2019-12-09 Thread John Hubbard
Update VFIO to take advantage of the recently loosened restriction on
FOLL_LONGTERM with get_user_pages_remote(). Also, now it is possible to
fix a bug: the VFIO caller is logically a FOLL_LONGTERM user, but it
wasn't setting FOLL_LONGTERM.

Also, remove an unnessary pair of calls that were releasing and
reacquiring the mmap_sem. There is no need to avoid holding mmap_sem
just in order to call page_to_pfn().

Also, now that the the DAX check ("if a VMA is DAX, don't allow long
term pinning") is in the internals of get_user_pages_remote() and
__gup_longterm_locked(), there's no need for it at the VFIO call site.
So remove it.

Tested-by: Alex Williamson 
Acked-by: Alex Williamson 
Reviewed-by: Jason Gunthorpe 
Reviewed-by: Ira Weiny 
Suggested-by: Jason Gunthorpe 
Cc: Dan Williams 
Cc: Jerome Glisse 
Signed-off-by: John Hubbard 
---
 drivers/vfio/vfio_iommu_type1.c | 30 +-
 1 file changed, 5 insertions(+), 25 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 2ada8e6cdb88..b800fc9a0251 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -322,7 +322,6 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned 
long vaddr,
 {
struct page *page[1];
struct vm_area_struct *vma;
-   struct vm_area_struct *vmas[1];
unsigned int flags = 0;
int ret;
 
@@ -330,33 +329,14 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned 
long vaddr,
flags |= FOLL_WRITE;
 
down_read(>mmap_sem);
-   if (mm == current->mm) {
-   ret = get_user_pages(vaddr, 1, flags | FOLL_LONGTERM, page,
-vmas);
-   } else {
-   ret = get_user_pages_remote(NULL, mm, vaddr, 1, flags, page,
-   vmas, NULL);
-   /*
-* The lifetime of a vaddr_get_pfn() page pin is
-* userspace-controlled. In the fs-dax case this could
-* lead to indefinite stalls in filesystem operations.
-* Disallow attempts to pin fs-dax pages via this
-* interface.
-*/
-   if (ret > 0 && vma_is_fsdax(vmas[0])) {
-   ret = -EOPNOTSUPP;
-   put_page(page[0]);
-   }
-   }
-   up_read(>mmap_sem);
-
+   ret = get_user_pages_remote(NULL, mm, vaddr, 1, flags | FOLL_LONGTERM,
+   page, NULL, NULL);
if (ret == 1) {
*pfn = page_to_pfn(page[0]);
-   return 0;
+   ret = 0;
+   goto done;
}
 
-   down_read(>mmap_sem);
-
vaddr = untagged_addr(vaddr);
 
vma = find_vma_intersection(mm, vaddr, vaddr + 1);
@@ -366,7 +346,7 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned 
long vaddr,
if (is_invalid_reserved_pfn(*pfn))
ret = 0;
}
-
+done:
up_read(>mmap_sem);
return ret;
 }
-- 
2.24.0

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

[PATCH v8 05/26] goldish_pipe: rename local pin_user_pages() routine

2019-12-09 Thread John Hubbard
1. Avoid naming conflicts: rename local static function from
"pin_user_pages()" to "goldfish_pin_pages()".

An upcoming patch will introduce a global pin_user_pages()
function.

Reviewed-by: Jan Kara 
Reviewed-by: Jérôme Glisse 
Reviewed-by: Ira Weiny 
Signed-off-by: John Hubbard 
---
 drivers/platform/goldfish/goldfish_pipe.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/platform/goldfish/goldfish_pipe.c 
b/drivers/platform/goldfish/goldfish_pipe.c
index cef0133aa47a..ef50c264db71 100644
--- a/drivers/platform/goldfish/goldfish_pipe.c
+++ b/drivers/platform/goldfish/goldfish_pipe.c
@@ -257,12 +257,12 @@ static int goldfish_pipe_error_convert(int status)
}
 }
 
-static int pin_user_pages(unsigned long first_page,
- unsigned long last_page,
- unsigned int last_page_size,
- int is_write,
- struct page *pages[MAX_BUFFERS_PER_COMMAND],
- unsigned int *iter_last_page_size)
+static int goldfish_pin_pages(unsigned long first_page,
+ unsigned long last_page,
+ unsigned int last_page_size,
+ int is_write,
+ struct page *pages[MAX_BUFFERS_PER_COMMAND],
+ unsigned int *iter_last_page_size)
 {
int ret;
int requested_pages = ((last_page - first_page) >> PAGE_SHIFT) + 1;
@@ -354,9 +354,9 @@ static int transfer_max_buffers(struct goldfish_pipe *pipe,
if (mutex_lock_interruptible(>lock))
return -ERESTARTSYS;
 
-   pages_count = pin_user_pages(first_page, last_page,
-last_page_size, is_write,
-pipe->pages, _last_page_size);
+   pages_count = goldfish_pin_pages(first_page, last_page,
+last_page_size, is_write,
+pipe->pages, _last_page_size);
if (pages_count < 0) {
mutex_unlock(>lock);
return pages_count;
-- 
2.24.0

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

[PATCH v8 03/26] mm: Cleanup __put_devmap_managed_page() vs ->page_free()

2019-12-09 Thread John Hubbard
From: Dan Williams 

After the removal of the device-public infrastructure there are only 2
->page_free() call backs in the kernel. One of those is a device-private
callback in the nouveau driver, the other is a generic wakeup needed in
the DAX case. In the hopes that all ->page_free() callbacks can be
migrated to common core kernel functionality, move the device-private
specific actions in __put_devmap_managed_page() under the
is_device_private_page() conditional, including the ->page_free()
callback. For the other page types just open-code the generic wakeup.

Yes, the wakeup is only needed in the MEMORY_DEVICE_FSDAX case, but it
does no harm in the MEMORY_DEVICE_DEVDAX and MEMORY_DEVICE_PCI_P2PDMA
case.

Reviewed-by: Christoph Hellwig 
Reviewed-by: Jérôme Glisse 
Cc: Jan Kara 
Cc: Ira Weiny 
Signed-off-by: Dan Williams 
Signed-off-by: John Hubbard 
---
 drivers/nvdimm/pmem.c |  6 
 mm/memremap.c | 80 ---
 2 files changed, 44 insertions(+), 42 deletions(-)

diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index ad8e4df1282b..4eae441f86c9 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -337,13 +337,7 @@ static void pmem_release_disk(void *__pmem)
put_disk(pmem->disk);
 }
 
-static void pmem_pagemap_page_free(struct page *page)
-{
-   wake_up_var(>_refcount);
-}
-
 static const struct dev_pagemap_ops fsdax_pagemap_ops = {
-   .page_free  = pmem_pagemap_page_free,
.kill   = pmem_pagemap_kill,
.cleanup= pmem_pagemap_cleanup,
 };
diff --git a/mm/memremap.c b/mm/memremap.c
index 03ccbdfeb697..e899fa876a62 100644
--- a/mm/memremap.c
+++ b/mm/memremap.c
@@ -27,7 +27,8 @@ static void devmap_managed_enable_put(void)
 
 static int devmap_managed_enable_get(struct dev_pagemap *pgmap)
 {
-   if (!pgmap->ops || !pgmap->ops->page_free) {
+   if (pgmap->type == MEMORY_DEVICE_PRIVATE &&
+   (!pgmap->ops || !pgmap->ops->page_free)) {
WARN(1, "Missing page_free method\n");
return -EINVAL;
}
@@ -414,44 +415,51 @@ void __put_devmap_managed_page(struct page *page)
 {
int count = page_ref_dec_return(page);
 
-   /*
-* If refcount is 1 then page is freed and refcount is stable as nobody
-* holds a reference on the page.
-*/
-   if (count == 1) {
-   /* Clear Active bit in case of parallel mark_page_accessed */
-   __ClearPageActive(page);
-   __ClearPageWaiters(page);
+   /* still busy */
+   if (count > 1)
+   return;
 
-   mem_cgroup_uncharge(page);
+   /* only triggered by the dev_pagemap shutdown path */
+   if (count == 0) {
+   __put_page(page);
+   return;
+   }
 
-   /*
-* When a device_private page is freed, the page->mapping field
-* may still contain a (stale) mapping value. For example, the
-* lower bits of page->mapping may still identify the page as
-* an anonymous page. Ultimately, this entire field is just
-* stale and wrong, and it will cause errors if not cleared.
-* One example is:
-*
-*  migrate_vma_pages()
-*migrate_vma_insert_page()
-*  page_add_new_anon_rmap()
-*__page_set_anon_rmap()
-*  ...checks page->mapping, via PageAnon(page) call,
-*and incorrectly concludes that the page is an
-*anonymous page. Therefore, it incorrectly,
-*silently fails to set up the new anon rmap.
-*
-* For other types of ZONE_DEVICE pages, migration is either
-* handled differently or not done at all, so there is no need
-* to clear page->mapping.
-*/
-   if (is_device_private_page(page))
-   page->mapping = NULL;
+   /* notify page idle for dax */
+   if (!is_device_private_page(page)) {
+   wake_up_var(>_refcount);
+   return;
+   }
 
-   page->pgmap->ops->page_free(page);
-   } else if (!count)
-   __put_page(page);
+   /* Clear Active bit in case of parallel mark_page_accessed */
+   __ClearPageActive(page);
+   __ClearPageWaiters(page);
+
+   mem_cgroup_uncharge(page);
+
+   /*
+* When a device_private page is freed, the page->mapping field
+* may still contain a (stale) mapping value. For example, the
+* lower bits of page->mapping may still identify the page as an
+* anonymous page. Ultimately, this entire field is just stale
+* and wrong, and it will cause errors if not cleared.  One
+* example is:
+*
+*  

Re: [PATCH 4/4] udmabuf: implement begin_cpu_access/end_cpu_access hooks

2019-12-09 Thread Chia-I Wu
On Mon, Dec 2, 2019 at 5:36 PM Gurchetan Singh
 wrote:
>
> With the misc device, we should end up using the result of
> get_arch_dma_ops(..) or dma-direct ops.
>
> This can allow us to have WC mappings in the guest after
> synchronization.
>
> Signed-off-by: Gurchetan Singh 
> ---
>  drivers/dma-buf/udmabuf.c | 39 +++
>  1 file changed, 39 insertions(+)
>
> diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
> index 0a610e09ae23..61b0a2cff874 100644
> --- a/drivers/dma-buf/udmabuf.c
> +++ b/drivers/dma-buf/udmabuf.c
> @@ -18,6 +18,7 @@ static const size_t size_limit_mb = 64; /* total dmabuf 
> size, in megabytes  */
>  struct udmabuf {
> pgoff_t pagecount;
> struct page **pages;
> +   struct sg_table *sg;
> struct miscdevice *device;
>  };
>
> @@ -98,20 +99,58 @@ static void unmap_udmabuf(struct dma_buf_attachment *at,
>  static void release_udmabuf(struct dma_buf *buf)
>  {
> struct udmabuf *ubuf = buf->priv;
> +   struct device *dev = ubuf->device->this_device;
> pgoff_t pg;
>
> +   if (ubuf->sg)
> +   put_sg_table(dev, ubuf->sg, DMA_BIDIRECTIONAL);
> +
> for (pg = 0; pg < ubuf->pagecount; pg++)
> put_page(ubuf->pages[pg]);
> kfree(ubuf->pages);
> kfree(ubuf);
>  }
>
> +static int begin_cpu_udmabuf(struct dma_buf *buf,
> +enum dma_data_direction direction)
> +{
> +   struct udmabuf *ubuf = buf->priv;
> +   struct device *dev = ubuf->device->this_device;
> +
> +   if (!ubuf->sg) {
> +   ubuf->sg = get_sg_table(dev, buf, direction);
> +   if (IS_ERR(ubuf->sg))
> +   return PTR_ERR(ubuf->sg);
> +   } else {
> +   dma_sync_sg_for_device(dev, ubuf->sg->sgl,
> +  ubuf->sg->nents,
> +  direction);
I know this solves the issue (flush the CPU cache before WC access),
but it looks like an abuse?  It is counter-intuitive that the buffer
is synced for device when one wants CPU access.

> +   }
> +
> +   return 0;
> +}
> +
> +static int end_cpu_udmabuf(struct dma_buf *buf,
> +  enum dma_data_direction direction)
> +{
> +   struct udmabuf *ubuf = buf->priv;
> +   struct device *dev = ubuf->device->this_device;
> +
> +   if (!ubuf->sg)
> +   return -EINVAL;
> +
> +   dma_sync_sg_for_cpu(dev, ubuf->sg->sgl, ubuf->sg->nents, direction);
> +   return 0;
> +}
> +
>  static const struct dma_buf_ops udmabuf_ops = {
> .cache_sgt_mapping = true,
> .map_dma_buf   = map_udmabuf,
> .unmap_dma_buf = unmap_udmabuf,
> .release   = release_udmabuf,
> .mmap  = mmap_udmabuf,
> +   .begin_cpu_access  = begin_cpu_udmabuf,
> +   .end_cpu_access= end_cpu_udmabuf,
>  };
>
>  #define SEALS_WANTED (F_SEAL_SHRINK)
> --
> 2.24.0.393.g34dc348eaf-goog
>
> ___
> 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

Re: linux-next: build failure after merge of the drm-intel tree

2019-12-09 Thread Stephen Rothwell
Hi all,

[Just adding Dave Airlie to the cc list]

On Tue, 10 Dec 2019 09:39:57 +1100 Stephen Rothwell  
wrote:
>
> After merging the drm-intel tree, today's linux-next build (x86_64
> allmodconfig) failed like this:
> 
> In file included from include/linux/spinlock_types.h:18,
>  from include/linux/mutex.h:16,
>  from include/linux/kernfs.h:12,
>  from include/linux/sysfs.h:16,
>  from include/linux/kobject.h:20,
>  from include/linux/of.h:17,
>  from include/linux/irqdomain.h:35,
>  from include/linux/acpi.h:13,
>  from drivers/gpu/drm/i915/i915_drv.c:30:
> drivers/gpu/drm/i915/gem/i915_gem_object.h: In function 
> 'i915_gem_object_pin_pages':
> include/linux/lockdep.h:635:2: error: too many arguments to function 
> 'lock_release'
>   635 |  lock_release(&(lock)->dep_map, 0, _THIS_IP_);  \
>   |  ^~~~
> drivers/gpu/drm/i915/gem/i915_gem_object.h:294:2: note: in expansion of macro 
> 'might_lock_nested'
>   294 |  might_lock_nested(>mm.lock, I915_MM_GET_PAGES);
>   |  ^
> include/linux/lockdep.h:352:13: note: declared here
>   352 | extern void lock_release(struct lockdep_map *lock, unsigned long ip);
>   | ^~~~
> In file included from include/linux/spinlock_types.h:18,
>  from include/linux/spinlock.h:83,
>  from include/linux/mmzone.h:8,
>  from include/linux/gfp.h:6,
>  from include/linux/slab.h:15,
>  from drivers/gpu/drm/i915/i915_irq.c:32:
> drivers/gpu/drm/i915/gem/i915_gem_object.h: In function 
> 'i915_gem_object_pin_pages':
> include/linux/lockdep.h:635:2: error: too many arguments to function 
> 'lock_release'
>   635 |  lock_release(&(lock)->dep_map, 0, _THIS_IP_);  \
>   |  ^~~~
> drivers/gpu/drm/i915/gem/i915_gem_object.h:294:2: note: in expansion of macro 
> 'might_lock_nested'
>   294 |  might_lock_nested(>mm.lock, I915_MM_GET_PAGES);
>   |  ^
> include/linux/lockdep.h:352:13: note: declared here
>   352 | extern void lock_release(struct lockdep_map *lock, unsigned long ip);
>   | ^~~~
> 
> Caused by commit
> 
>   e692b4021a2e ("lockdep: add might_lock_nested()")
> 
> interacting with commit
> 
>   5facae4f3549 ("locking/lockdep: Remove unused @nested argument from 
> lock_release()")
> 
> from Linus' tree.
> 
> I have applied the following merge fix patch for today:
> 
> From: Stephen Rothwell 
> Date: Tue, 10 Dec 2019 09:37:07 +1100
> Subject: [PATCH] lockdep: fix up for lock_release API change
> 
> ---
>  include/linux/lockdep.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
> index 5bbfd5866081..664f52c6dd4c 100644
> --- a/include/linux/lockdep.h
> +++ b/include/linux/lockdep.h
> @@ -632,7 +632,7 @@ do {  
> \
>   typecheck(struct lockdep_map *, &(lock)->dep_map);  \
>   lock_acquire(&(lock)->dep_map, subclass, 0, 1, 1, NULL, \
>_THIS_IP_);\
> - lock_release(&(lock)->dep_map, 0, _THIS_IP_);   \
> + lock_release(&(lock)->dep_map, _THIS_IP_);  \
>  } while (0)
>  
>  #define lockdep_assert_irqs_enabled()do {
> \

-- 
Cheers,
Stephen Rothwell


pgpiNpLQg1P1J.pgp
Description: OpenPGP digital signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

linux-next: build failure after merge of the drm-intel tree

2019-12-09 Thread Stephen Rothwell
Hi all,

After merging the drm-intel tree, today's linux-next build (x86_64
allmodconfig) failed like this:

In file included from include/linux/spinlock_types.h:18,
 from include/linux/mutex.h:16,
 from include/linux/kernfs.h:12,
 from include/linux/sysfs.h:16,
 from include/linux/kobject.h:20,
 from include/linux/of.h:17,
 from include/linux/irqdomain.h:35,
 from include/linux/acpi.h:13,
 from drivers/gpu/drm/i915/i915_drv.c:30:
drivers/gpu/drm/i915/gem/i915_gem_object.h: In function 
'i915_gem_object_pin_pages':
include/linux/lockdep.h:635:2: error: too many arguments to function 
'lock_release'
  635 |  lock_release(&(lock)->dep_map, 0, _THIS_IP_);  \
  |  ^~~~
drivers/gpu/drm/i915/gem/i915_gem_object.h:294:2: note: in expansion of macro 
'might_lock_nested'
  294 |  might_lock_nested(>mm.lock, I915_MM_GET_PAGES);
  |  ^
include/linux/lockdep.h:352:13: note: declared here
  352 | extern void lock_release(struct lockdep_map *lock, unsigned long ip);
  | ^~~~
In file included from include/linux/spinlock_types.h:18,
 from include/linux/spinlock.h:83,
 from include/linux/mmzone.h:8,
 from include/linux/gfp.h:6,
 from include/linux/slab.h:15,
 from drivers/gpu/drm/i915/i915_irq.c:32:
drivers/gpu/drm/i915/gem/i915_gem_object.h: In function 
'i915_gem_object_pin_pages':
include/linux/lockdep.h:635:2: error: too many arguments to function 
'lock_release'
  635 |  lock_release(&(lock)->dep_map, 0, _THIS_IP_);  \
  |  ^~~~
drivers/gpu/drm/i915/gem/i915_gem_object.h:294:2: note: in expansion of macro 
'might_lock_nested'
  294 |  might_lock_nested(>mm.lock, I915_MM_GET_PAGES);
  |  ^
include/linux/lockdep.h:352:13: note: declared here
  352 | extern void lock_release(struct lockdep_map *lock, unsigned long ip);
  | ^~~~

Caused by commit

  e692b4021a2e ("lockdep: add might_lock_nested()")

interacting with commit

  5facae4f3549 ("locking/lockdep: Remove unused @nested argument from 
lock_release()")

from Linus' tree.

I have applied the following merge fix patch for today:

From: Stephen Rothwell 
Date: Tue, 10 Dec 2019 09:37:07 +1100
Subject: [PATCH] lockdep: fix up for lock_release API change

---
 include/linux/lockdep.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 5bbfd5866081..664f52c6dd4c 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -632,7 +632,7 @@ do {
\
typecheck(struct lockdep_map *, &(lock)->dep_map);  \
lock_acquire(&(lock)->dep_map, subclass, 0, 1, 1, NULL, \
 _THIS_IP_);\
-   lock_release(&(lock)->dep_map, 0, _THIS_IP_);   \
+   lock_release(&(lock)->dep_map, _THIS_IP_);  \
 } while (0)
 
 #define lockdep_assert_irqs_enabled()  do {\
-- 
2.24.0

-- 
Cheers,
Stephen Rothwell


pgpDHEj619Jij.pgp
Description: OpenPGP digital signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v2 1/2] gpu: host1x: Rename "parent" to "host"

2019-12-09 Thread kbuild test robot
Hi Thierry,

I love your patch! Perhaps something to improve:

[auto build test WARNING on next-20191209]
[also build test WARNING on tegra-drm/drm/tegra/for-next v5.5-rc1]
[cannot apply to tegra/for-next drm-intel/for-linux-next v5.4]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:
https://github.com/0day-ci/linux/commits/Thierry-Reding/gpu-host1x-Rename-parent-to-host/20191210-025426
base:6cf8298daad041cd15dc514d8a4f93ca3636c84e
reproduce: make htmldocs

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot 

All warnings (new ones prefixed by >>):

   drivers/usb/typec/bus.c:1: warning: 'typec_altmode_unregister_driver' not 
found
   drivers/usb/typec/class.c:1: warning: 'typec_altmode_register_notifier' not 
found
   drivers/usb/typec/class.c:1: warning: 'typec_altmode_unregister_notifier' 
not found
   fs/posix_acl.c:647: warning: Function parameter or member 'inode' not 
described in 'posix_acl_update_mode'
   fs/posix_acl.c:647: warning: Function parameter or member 'mode_p' not 
described in 'posix_acl_update_mode'
   fs/posix_acl.c:647: warning: Function parameter or member 'acl' not 
described in 'posix_acl_update_mode'
   include/linux/regulator/machine.h:196: warning: Function parameter or member 
'max_uV_step' not described in 'regulation_constraints'
   include/linux/regulator/driver.h:223: warning: Function parameter or member 
'resume' not described in 'regulator_ops'
   sound/soc/soc-core.c:2519: warning: Function parameter or member 
'legacy_dai_naming' not described in 'snd_soc_register_dai'
   include/linux/skbuff.h:888: warning: Function parameter or member 
'dev_scratch' not described in 'sk_buff'
   include/linux/skbuff.h:888: warning: Function parameter or member 'list' not 
described in 'sk_buff'
   include/linux/skbuff.h:888: warning: Function parameter or member 
'ip_defrag_offset' not described in 'sk_buff'
   include/linux/skbuff.h:888: warning: Function parameter or member 
'skb_mstamp_ns' not described in 'sk_buff'
   include/linux/skbuff.h:888: warning: Function parameter or member 
'__cloned_offset' not described in 'sk_buff'
   include/linux/skbuff.h:888: warning: Function parameter or member 
'head_frag' not described in 'sk_buff'
   include/linux/skbuff.h:888: warning: Function parameter or member 
'__pkt_type_offset' not described in 'sk_buff'
   include/linux/skbuff.h:888: warning: Function parameter or member 
'encapsulation' not described in 'sk_buff'
   include/linux/skbuff.h:888: warning: Function parameter or member 
'encap_hdr_csum' not described in 'sk_buff'
   include/linux/skbuff.h:888: warning: Function parameter or member 
'csum_valid' not described in 'sk_buff'
   include/linux/skbuff.h:888: warning: Function parameter or member 
'__pkt_vlan_present_offset' not described in 'sk_buff'
   include/linux/skbuff.h:888: warning: Function parameter or member 
'vlan_present' not described in 'sk_buff'
   include/linux/skbuff.h:888: warning: Function parameter or member 
'csum_complete_sw' not described in 'sk_buff'
   include/linux/skbuff.h:888: warning: Function parameter or member 
'csum_level' not described in 'sk_buff'
   include/linux/skbuff.h:888: warning: Function parameter or member 
'inner_protocol_type' not described in 'sk_buff'
   include/linux/skbuff.h:888: warning: Function parameter or member 
'remcsum_offload' not described in 'sk_buff'
   include/linux/skbuff.h:888: warning: Function parameter or member 
'sender_cpu' not described in 'sk_buff'
   include/linux/skbuff.h:888: warning: Function parameter or member 
'reserved_tailroom' not described in 'sk_buff'
   include/linux/skbuff.h:888: warning: Function parameter or member 
'inner_ipproto' not described in 'sk_buff'
   include/net/sock.h:232: warning: Function parameter or member 'skc_addrpair' 
not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or member 'skc_portpair' 
not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or member 'skc_ipv6only' 
not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or member 
'skc_net_refcnt' not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or member 'skc_v6_daddr' 
not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or member 
'skc_v6_rcv_saddr' not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or member 'skc_cookie' 
not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or member 'skc_listener' 
not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or member 'skc_tw_dr' 
not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or 

Re: [PATCH v3 0/9] drm/meson: add AFBC support

2019-12-09 Thread Kevin Hilman
Neil Armstrong  writes:

> This adds support for the ARM Framebuffer Compression decoders found
> in the Amlogic GXM and G12A SoCs.
>
> This patchset is a merge of v2 "drm/meson: add AFBC support" at [3] and v2
> "drm/meson: implement RDMA for AFBC reset on vsync" at [4].

Oops, replied to the wrong series earlier...

> The VPU embeds a "Register DMA" that can write a sequence of registers
> on the VPU AHB bus, either manually or triggered by an internal IRQ
> event like VSYNC or a line input counter.
>
> The Amlogic GXM and G12A AFBC decoder are totally different, the GXM only
> handling only the AFBC v1.0 modes and the G12A decoder handling the
> AFBC v1.2 modes.
>
> The G12A AFBC decoder is an external IP integrated in the video pipeline,
> and the GXM AFBC decoder seems to the an Amlogic custom decoder more
> tighly integrated in the video pipeline.
>
> The GXM AFBC decoder can handle only one AFBC plane for 2 available
> OSD planes available in HW, and the G12A AFBC decoder can handle up
> to 4 AFBC planes for up to 3 OSD planes available in HW.
>
> The Amlogic GXM supports 16x16 SPARSE and 16x16 SPLIT AFBC buffers up
> to 4k.
>
> On the other side, for G12A SPLIT is mandatory in 16x16 block mode, but
> for 4k modes 32x8+SPLIT AFBC buffers is manadatory for performances reasons.
>
> The Amlogic GXM and G12A AFBC decoders are integrated very differently.
>
> The Amlogic GXM has a direct output path to the OSD1 VIU pixel input,
> because the GXM AFBC decoder seem to be a custom IP developed by Amlogic.
>
> On the other side, the Amlogic G12A AFBC decoder seems to be an external
> IP that emit pixels on an AXI master hooked to a "Mali Unpack" block
> feeding the OSD1 VIU pixel input.
> This uses a weird "0x100" internal HW physical address on both
> sides to transfer the pixels.
>
> For Amlogic GXM, the supported pixel formats are the same as the normal
> linear OSD1 mode.
>
> On the other side, Amlogic added support for all AFBC v1.2 formats for
> the G12A AFBC integration.
>
> The initial RDMA implementation handles a single channel (over 8), triggered
> by the VSYNC irq and does not handle the RDMA irq.
>
> The RDMA will be usefull to reset and program the AFBC decoder unit
> on each vsync without involving the interrupt handler that can
> be masked for a long period of time, producing display glitches.
>
> For this we use the meson_rdma_writel_sync() which adds the register
> write tuple (VPU register offset and register value) to the RDMA buffer
> and write the value to the HW.
>
> When enabled, the RDMA is enabled to rewritte the same sequence at the
> next VSYNC event, until a new buffer is committed to the OSD plane.
>
> For testing, the only available AFBC buffer generation is the Android
> Yukawa Dvalin Android Mali blobs found at [1].
>
> Both SoCs has been tested using buffers generated under AOSP, but only
> G12A was tested using a runtime stream of AFBC buffers, GXM was only
> tested using static buffers loaded from files.

Reviewed-by: Kevin Hilman 

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

Re: [PATCH v3 8/9] drm/meson: hold 32 lines after vsync to give time for AFBC start

2019-12-09 Thread Kevin Hilman
Neil Armstrong  writes:

> When using an AFBC encoded frame, the AFBC Decoder must be resetted,

minor grammar nit: s/resetted/reset/

> configured and enabled at each vsync IRQ.
>
> To leave time for that, use the maximum lines hold time to give time
> for AFBC setup and avoid visual glitches.
>
> Signed-off-by: Neil Armstrong 

otherwise...

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

Re: [PATCH v2 0/25] drm/panel infrastructure + backlight update

2019-12-09 Thread Sam Ravnborg
On Sat, Dec 07, 2019 at 03:03:28PM +0100, Sam Ravnborg wrote:
> This patchset include a couple of different
> things - all related to panels.
> 
> - The callbacks are optional - so drop error if
>   callback is not present.
>  
> - Add support for backlight in drm_panel.
>   This allows us to make much simpler backlight
>   support to most panels.
>   The patchset include conversion of most of the
>   trivial cases.
> 
> - Drop drm_connector from drm_panel.
>   This change required many changes to most
>   panels and many bridges and display drivers.
>   This is by far the most invasive change in this patchset.
> 
> With this patchset drm_panel_(attach|detach) are nop's
> but they are kept for now.
> 
> A few of these patches has been sent out before - but versioning
> started again from v1 - as the most patches are new.
> 
> I have tested the panel-simple changes, and thus some
> of the infrastructure changes.
> The testing was done on an earlier iteration - and I ended
> up submitting this as Laurent and others started to depend on it.
> 
> v2:
>   This is mostly addressing comments from Laurent.
>   - drop get_timings removal, we should start using it
>   - do not fail in drm_panel_of_backlight() if DT is not enabled
>   - updated changelogs and code comments in many places (thanks Laurent!)
>   - get_modes is a mandatory callback - return -EOPNOTSUPP if not specified
>   - log if backlight update fails
>   - added a-b/r-bs
> o thanks to Laurent and Linus for the prompt reviews!
> 
> When "drm/panel: add backlight support" is reviewed I plan to
> apply the full series to drm-misc-next.

Fixed the last bits pointed out by Laurent and pushed to drm-misc-next.

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

Re: [PATCH v2 0/3] drm/meson: implement RDMA for AFBC reset on vsync

2019-12-09 Thread Kevin Hilman
Neil Armstrong  writes:

> The VPU embeds a "Register DMA" that can write a sequence of registers
> on the VPU AHB bus, either manually or triggered by an internal IRQ
> event like VSYNC or a line input counter.
>
> The initial implementation handles a single channel (over 8), triggered
> by the VSYNC irq and does not handle the RDMA irq.
>
> The RDMA will be usefull to reset and program the AFBC decoder unit
> on each vsync without involving the interrupt handler that can
> be masked for a long period of time, producing display glitches.
>
> For this we use the meson_rdma_writel_sync() which adds the register
> write tuple (VPU register offset and register value) to the RDMA buffer
> and write the value to the HW.
>
> When enabled, the RDMA is enabled to rewritte the same sequence at the
> next VSYNC event, until a new buffer is committed to the OSD plane.
>
> The the Amlogic G12A is switched to RDMA, the Amlogic GXM Decoder
> doesn't need a reset/reprogram at each vsync.
>
> Changes since v1 at [1]:
> - Fixed a regression when AFBC was not used, adding a reset() call for the 
> afbc module
> - Added a define for the RDMA descriptor size
> - Fixed overflow detection

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

[Bug 201539] AMDGPU R9 390 automatic fan speed control in Linux 4.19/4.20/5.0

2019-12-09 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=201539

--- Comment #52 from muncrief (rmuncr...@humanavance.com) ---
(In reply to MasterCATZ from comment #51)
> current temp: 61000
> interpolated pwm value for temperature 61000 is: 170
> current pwm: 165, requested to set pwm to 170
> current pwm: 165, requested to set pwm to 170
> temp at last change was 61000
> changing pwm to 170
> 
> current temp: 71000
> current pwm: 255, requested to set pwm to 255
> current pwm: 255, requested to set pwm to 255
> not changing pwm, we just did at 71000, next change when below 66000
> 
> 
> current temp: 73000
> current pwm: 68, requested to set pwm to 255
> current pwm: 68, requested to set pwm to 255
> Fanmode not set to manual.
> setting fan mode to 1
> temp at last change was 73000
> changing pwm to 255
> /usr/local/bin/amdgpu-fancontrol: line 65: echo: write error: Invalid
> argument
> 
> 
> 
> 
> current temp: 87000
> current pwm: 124, requested to set pwm to 255
> current pwm: 124, requested to set pwm to 255
> Fanmode not set to manual.
> setting fan mode to 1
> temp at last change was 87000
> changing pwm to 255
> /usr/local/bin/amdgpu-fancontrol: line 65: echo: write error: Invalid
> argument

Well, that's certainly quite bizarre. I wish I could think of something else
but I'm stumped. I've never experienced that problem on my system, and I don't
know why yours isn't allowing the write. Is it possible there was some error in
copying the script? It seems unlikely but that's all I can come up with at this
point. If you have somewhere I can send my actual script and service files I'd
be happy to send them to you. Otherwise I'm just out of ideas.

-- 
You are receiving this mail because:
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/gma500: add a missed gma_power_end in error path

2019-12-09 Thread Patrik Jakobsson
On Mon, Dec 9, 2019 at 9:57 AM Chuhong Yuan  wrote:
>
> oaktrail_lvds_mode_set() misses a gma_power_end() in an error path.
> Add the call to fix it.
>
> Signed-off-by: Chuhong Yuan 

Hi Chuhong, thanks for the patch.

Applied to drm-misc-next

-Patrik

> ---
>  drivers/gpu/drm/gma500/oaktrail_lvds.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/gma500/oaktrail_lvds.c 
> b/drivers/gpu/drm/gma500/oaktrail_lvds.c
> index 7390403ea1b7..582e09597500 100644
> --- a/drivers/gpu/drm/gma500/oaktrail_lvds.c
> +++ b/drivers/gpu/drm/gma500/oaktrail_lvds.c
> @@ -117,6 +117,7 @@ static void oaktrail_lvds_mode_set(struct drm_encoder 
> *encoder,
>
> if (!connector) {
> DRM_ERROR("Couldn't find connector when setting mode");
> +   gma_power_end(dev);
> return;
> }
>
> --
> 2.24.0
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v2 7/8] drm/msm/a6xx: Support split pagetables

2019-12-09 Thread Rob Clark
On Fri, Nov 22, 2019 at 3:32 PM Jordan Crouse  wrote:
>
> Attempt to enable split pagetables if the arm-smmu driver supports it.
> This will move the default address space from the default region to
> the address range assigned to TTBR1. The behavior should be transparent
> to the driver for now but it gets the default buffers out of the way
> when we want to start swapping TTBR0 for context-specific pagetables.
>
> Signed-off-by: Jordan Crouse 
> ---
>
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 46 
> ++-
>  1 file changed, 45 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> index 5dc0b2c..96b3b28 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -811,6 +811,50 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu)
> return (unsigned long)busy_time;
>  }
>
> +static struct msm_gem_address_space *
> +a6xx_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev)
> +{
> +   struct iommu_domain *iommu = iommu_domain_alloc(_bus_type);
> +   struct msm_gem_address_space *aspace;
> +   struct msm_mmu *mmu;
> +   u64 start, size;
> +   u32 val = 1;
> +   int ret;
> +
> +   if (!iommu)
> +   return ERR_PTR(-ENOMEM);
> +
> +   /* Try to request split pagetables */
> +   iommu_domain_set_attr(iommu, DOMAIN_ATTR_SPLIT_TABLES, );
> +
> +   mmu = msm_iommu_new(>dev, iommu);
> +   if (IS_ERR(mmu)) {
> +   iommu_domain_free(iommu);
> +   return ERR_CAST(mmu);
> +   }
> +
> +   /* Check to see if split pagetables were successful */
> +   ret = iommu_domain_get_attr(iommu, DOMAIN_ATTR_SPLIT_TABLES, );

I assume the split between this and iommu_domain_set_attr() is because
attach needs to happen in between?  At any rate, if it needs to be
like this, maybe a comment is in order.  As it is it looks like
something future-self would "cleanup"..

BR,
-R

> +   if (!ret && val) {
> +   /*
> +* The aperture start will be at the beginning of the TTBR1
> +* space so use that as a base
> +*/
> +   start = iommu->geometry.aperture_start;
> +   size = 0x;
> +   } else {
> +   /* Otherwise use the legacy 32 bit region */
> +   start = SZ_16M;
> +   size = 0x - SZ_16M;
> +   }
> +
> +   aspace = msm_gem_address_space_create(mmu, "gpu", start, size);
> +   if (IS_ERR(aspace))
> +   iommu_domain_free(iommu);
> +
> +   return aspace;
> +}
> +
>  static const struct adreno_gpu_funcs funcs = {
> .base = {
> .get_param = adreno_get_param,
> @@ -832,7 +876,7 @@ static const struct adreno_gpu_funcs funcs = {
>  #if defined(CONFIG_DRM_MSM_GPU_STATE)
> .gpu_state_get = a6xx_gpu_state_get,
> .gpu_state_put = a6xx_gpu_state_put,
> -   .create_address_space = adreno_iommu_create_address_space,
> +   .create_address_space = a6xx_create_address_space,
>  #endif
> },
> .get_timestamp = a6xx_get_timestamp,
> --
> 2.7.4
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v2 6/8] drm/msm: Refactor address space initialization

2019-12-09 Thread Rob Clark
On Fri, Nov 22, 2019 at 3:32 PM Jordan Crouse  wrote:
>
> Refactor how address space initialization works. Instead of having the
> address space function create the MMU object (and thus require separate but
> equal functions for gpummu and iommu) use a single function and pass the
> MMU struct in. Make the generic code cleaner by using target specific
> functions to create the address space so a2xx can do its own thing in its
> own space.  For all the other targets use a generic helper to initialize
> IOMMU but leave the door open for newer targets to use customization
> if they need it.
>
> Signed-off-by: Jordan Crouse 

Reviewed-by: Rob Clark 

> ---
>
>  drivers/gpu/drm/msm/adreno/a2xx_gpu.c| 16 ++
>  drivers/gpu/drm/msm/adreno/a3xx_gpu.c|  1 +
>  drivers/gpu/drm/msm/adreno/a4xx_gpu.c|  1 +
>  drivers/gpu/drm/msm/adreno/a5xx_gpu.c|  1 +
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c|  1 +
>  drivers/gpu/drm/msm/adreno/adreno_gpu.c  | 23 ++
>  drivers/gpu/drm/msm/adreno/adreno_gpu.h  |  8 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c  | 10 +++---
>  drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 14 +
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c |  4 ---
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 11 +--
>  drivers/gpu/drm/msm/msm_drv.h|  8 ++---
>  drivers/gpu/drm/msm/msm_gem_vma.c| 52 
> +---
>  drivers/gpu/drm/msm/msm_gpu.c| 40 ++--
>  drivers/gpu/drm/msm/msm_gpu.h|  4 +--
>  drivers/gpu/drm/msm/msm_iommu.c  |  3 ++
>  16 files changed, 83 insertions(+), 114 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c 
> b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
> index 1f83bc1..60f6472 100644
> --- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
> @@ -401,6 +401,21 @@ static struct msm_gpu_state *a2xx_gpu_state_get(struct 
> msm_gpu *gpu)
> return state;
>  }
>
> +static struct msm_gem_address_space *
> +a2xx_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev)
> +{
> +   struct msm_mmu *mmu = msm_gpummu_new(>dev, gpu);
> +   struct msm_gem_address_space *aspace;
> +
> +   aspace = msm_gem_address_space_create(mmu, "gpu", SZ_16M,
> +   SZ_16M + 0xfff * SZ_64K);
> +
> +   if (IS_ERR(aspace) && !IS_ERR(mmu))
> +   mmu->funcs->destroy(mmu);
> +
> +   return aspace;
> +}
> +
>  /* Register offset defines for A2XX - copy of A3XX */
>  static const unsigned int a2xx_register_offsets[REG_ADRENO_REGISTER_MAX] = {
> REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_AXXX_CP_RB_BASE),
> @@ -429,6 +444,7 @@ static const struct adreno_gpu_funcs funcs = {
>  #endif
> .gpu_state_get = a2xx_gpu_state_get,
> .gpu_state_put = adreno_gpu_state_put,
> +   .create_address_space = a2xx_create_address_space,
> },
>  };
>
> diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c 
> b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
> index 7ad1493..41e51e0 100644
> --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
> @@ -441,6 +441,7 @@ static const struct adreno_gpu_funcs funcs = {
>  #endif
> .gpu_state_get = a3xx_gpu_state_get,
> .gpu_state_put = adreno_gpu_state_put,
> +   .create_address_space = adreno_iommu_create_address_space,
> },
>  };
>
> diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c 
> b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
> index b01388a..3655440 100644
> --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
> @@ -532,6 +532,7 @@ static const struct adreno_gpu_funcs funcs = {
>  #endif
> .gpu_state_get = a4xx_gpu_state_get,
> .gpu_state_put = adreno_gpu_state_put,
> +   .create_address_space = adreno_iommu_create_address_space,
> },
> .get_timestamp = a4xx_get_timestamp,
>  };
> diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
> b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> index b02e204..0f5db72 100644
> --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> @@ -1432,6 +1432,7 @@ static const struct adreno_gpu_funcs funcs = {
> .gpu_busy = a5xx_gpu_busy,
> .gpu_state_get = a5xx_gpu_state_get,
> .gpu_state_put = a5xx_gpu_state_put,
> +   .create_address_space = adreno_iommu_create_address_space,
> },
> .get_timestamp = a5xx_get_timestamp,
>  };
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> index dc8ec2c..5dc0b2c 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -832,6 +832,7 @@ static const struct adreno_gpu_funcs funcs = {
>  #if defined(CONFIG_DRM_MSM_GPU_STATE)
> .gpu_state_get = 

Re: [PATCH v2 5/8] drm/msm: Attach the IOMMU device during initialization

2019-12-09 Thread Rob Clark
On Fri, Nov 22, 2019 at 3:32 PM Jordan Crouse  wrote:
>
> Everywhere an IOMMU object is created by msm_gpu_create_address_space
> the IOMMU device is attached immediately after. Instead of carrying around
> the infrastructure to do the attach from the device specific code do it
> directly in the msm_iommu_init() function. This gets it out of the way for
> more aggressive cleanups that follow.
>
> Signed-off-by: Jordan Crouse 

Hmm, yeah, now that we dropped the extra mmu->attach() args (which was
some ancient downstream compat thing), we don't need the separate
attach step.  I suppose we probably should do a similar cleanup for
mmu->detach(), but I guess that can be it's own patch

Reviewed-by: Rob Clark 


> ---
>
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c  |  8 
>  drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c |  4 
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c |  7 ---
>  drivers/gpu/drm/msm/msm_gem_vma.c| 23 +++
>  drivers/gpu/drm/msm/msm_gpu.c| 11 +--
>  drivers/gpu/drm/msm/msm_gpummu.c |  6 --
>  drivers/gpu/drm/msm/msm_iommu.c  | 15 +++
>  drivers/gpu/drm/msm/msm_mmu.h|  1 -
>  8 files changed, 27 insertions(+), 48 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> index 6c92f0f..b082b23 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> @@ -704,7 +704,6 @@ static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms)
>  {
> struct iommu_domain *domain;
> struct msm_gem_address_space *aspace;
> -   int ret;
>
> domain = iommu_domain_alloc(_bus_type);
> if (!domain)
> @@ -720,13 +719,6 @@ static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms)
> return PTR_ERR(aspace);
> }
>
> -   ret = aspace->mmu->funcs->attach(aspace->mmu);
> -   if (ret) {
> -   DPU_ERROR("failed to attach iommu %d\n", ret);
> -   msm_gem_address_space_put(aspace);
> -   return ret;
> -   }
> -
> dpu_kms->base.aspace = aspace;
> return 0;
>  }
> diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c 
> b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
> index dda0543..9dba37c 100644
> --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
> +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
> @@ -518,10 +518,6 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
> }
>
> kms->aspace = aspace;
> -
> -   ret = aspace->mmu->funcs->attach(aspace->mmu);
> -   if (ret)
> -   goto fail;
> } else {
> DRM_DEV_INFO(dev->dev, "no iommu, fallback to phys "
> "contig buffers for scanout\n");
> diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c 
> b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
> index e43ecd4..653dab2 100644
> --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
> +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
> @@ -736,13 +736,6 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
> }
>
> kms->aspace = aspace;
> -
> -   ret = aspace->mmu->funcs->attach(aspace->mmu);
> -   if (ret) {
> -   DRM_DEV_ERROR(>dev, "failed to attach iommu: 
> %d\n",
> -   ret);
> -   goto fail;
> -   }
> } else {
> DRM_DEV_INFO(>dev,
>  "no iommu, fallback to phys contig buffers for 
> scanout\n");
> diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c 
> b/drivers/gpu/drm/msm/msm_gem_vma.c
> index 1af5354..91d993a 100644
> --- a/drivers/gpu/drm/msm/msm_gem_vma.c
> +++ b/drivers/gpu/drm/msm/msm_gem_vma.c
> @@ -131,8 +131,8 @@ msm_gem_address_space_create(struct device *dev, struct 
> iommu_domain *domain,
> const char *name)
>  {
> struct msm_gem_address_space *aspace;
> -   u64 size = domain->geometry.aperture_end -
> -   domain->geometry.aperture_start;
> +   u64 start = domain->geometry.aperture_start;
> +   u64 size = domain->geometry.aperture_end - start;
>
> aspace = kzalloc(sizeof(*aspace), GFP_KERNEL);
> if (!aspace)
> @@ -141,9 +141,18 @@ msm_gem_address_space_create(struct device *dev, struct 
> iommu_domain *domain,
> spin_lock_init(>lock);
> aspace->name = name;
> aspace->mmu = msm_iommu_new(dev, domain);
> +   if (IS_ERR(aspace->mmu)) {
> +   int ret = PTR_ERR(aspace->mmu);
>
> -   drm_mm_init(>mm, (domain->geometry.aperture_start >> 
> PAGE_SHIFT),
> -   size >> PAGE_SHIFT);
> +   kfree(aspace);
> +   return ERR_PTR(ret);
> +   }
> +
> +   /*
> +* Attaching the IOMMU device changes the aperture values so use the
> +* cached values instead
> +*/
> +  

Patch "drm: damage_helper: Fix race checking plane->state->fb" has been added to the 5.4-stable tree

2019-12-09 Thread gregkh

This is a note to let you know that I've just added the patch titled

drm: damage_helper: Fix race checking plane->state->fb

to the 5.4-stable tree which can be found at:

http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
 drm-damage_helper-fix-race-checking-plane-state-fb.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let  know about it.


From 354c2d310082d1c384213ba76c3757dd3cd8755d Mon Sep 17 00:00:00 2001
From: Sean Paul 
Date: Wed, 4 Sep 2019 16:29:13 -0400
Subject: drm: damage_helper: Fix race checking plane->state->fb

From: Sean Paul 

commit 354c2d310082d1c384213ba76c3757dd3cd8755d upstream.

Since the dirtyfb ioctl doesn't give us any hints as to which plane is
scanning out the fb it's marking as damaged, we need to loop through
planes to find it.

Currently we just reach into plane state and check, but that can race
with another commit changing the fb out from under us. This patch locks
the plane before checking the fb and will release the lock if the plane
is not displaying the dirty fb.

Fixes: b9fc5e01d1ce ("drm: Add helper to implement legacy dirtyfb")
Cc: Rob Clark 
Cc: Deepak Rawat 
Cc: Daniel Vetter 
Cc: Thomas Hellstrom 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: Sean Paul 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: dri-devel@lists.freedesktop.org
Cc:  # v5.0+
Reported-by: Daniel Vetter 
Reviewed-by: Daniel Vetter 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20190904202938.110207-1-s...@poorly.run
Signed-off-by: Greg Kroah-Hartman 

---
 drivers/gpu/drm/drm_damage_helper.c |8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

--- a/drivers/gpu/drm/drm_damage_helper.c
+++ b/drivers/gpu/drm/drm_damage_helper.c
@@ -212,8 +212,14 @@ retry:
drm_for_each_plane(plane, fb->dev) {
struct drm_plane_state *plane_state;
 
-   if (plane->state->fb != fb)
+   ret = drm_modeset_lock(>mutex, state->acquire_ctx);
+   if (ret)
+   goto out;
+
+   if (plane->state->fb != fb) {
+   drm_modeset_unlock(>mutex);
continue;
+   }
 
plane_state = drm_atomic_get_plane_state(state, plane);
if (IS_ERR(plane_state)) {


Patches currently in stable-queue which might be from seanp...@chromium.org are

queue-5.4/drm-msm-fix-memleak-on-release.patch
queue-5.4/drm-damage_helper-fix-race-checking-plane-state-fb.patch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Patch "drm: damage_helper: Fix race checking plane->state->fb" has been added to the 5.3-stable tree

2019-12-09 Thread gregkh

This is a note to let you know that I've just added the patch titled

drm: damage_helper: Fix race checking plane->state->fb

to the 5.3-stable tree which can be found at:

http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
 drm-damage_helper-fix-race-checking-plane-state-fb.patch
and it can be found in the queue-5.3 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let  know about it.


From 354c2d310082d1c384213ba76c3757dd3cd8755d Mon Sep 17 00:00:00 2001
From: Sean Paul 
Date: Wed, 4 Sep 2019 16:29:13 -0400
Subject: drm: damage_helper: Fix race checking plane->state->fb

From: Sean Paul 

commit 354c2d310082d1c384213ba76c3757dd3cd8755d upstream.

Since the dirtyfb ioctl doesn't give us any hints as to which plane is
scanning out the fb it's marking as damaged, we need to loop through
planes to find it.

Currently we just reach into plane state and check, but that can race
with another commit changing the fb out from under us. This patch locks
the plane before checking the fb and will release the lock if the plane
is not displaying the dirty fb.

Fixes: b9fc5e01d1ce ("drm: Add helper to implement legacy dirtyfb")
Cc: Rob Clark 
Cc: Deepak Rawat 
Cc: Daniel Vetter 
Cc: Thomas Hellstrom 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: Sean Paul 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: dri-devel@lists.freedesktop.org
Cc:  # v5.0+
Reported-by: Daniel Vetter 
Reviewed-by: Daniel Vetter 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20190904202938.110207-1-s...@poorly.run
Signed-off-by: Greg Kroah-Hartman 

---
 drivers/gpu/drm/drm_damage_helper.c |8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

--- a/drivers/gpu/drm/drm_damage_helper.c
+++ b/drivers/gpu/drm/drm_damage_helper.c
@@ -212,8 +212,14 @@ retry:
drm_for_each_plane(plane, fb->dev) {
struct drm_plane_state *plane_state;
 
-   if (plane->state->fb != fb)
+   ret = drm_modeset_lock(>mutex, state->acquire_ctx);
+   if (ret)
+   goto out;
+
+   if (plane->state->fb != fb) {
+   drm_modeset_unlock(>mutex);
continue;
+   }
 
plane_state = drm_atomic_get_plane_state(state, plane);
if (IS_ERR(plane_state)) {


Patches currently in stable-queue which might be from seanp...@chromium.org are

queue-5.3/drm-msm-fix-memleak-on-release.patch
queue-5.3/drm-damage_helper-fix-race-checking-plane-state-fb.patch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH V4] drm: Add support for DP 1.4 Compliance edid corruption test

2019-12-09 Thread Jerry (Fangzhi) Zuo
Unlike DP 1.2 edid corruption test, DP 1.4 requires to calculate
real CRC value of the last edid data block, and write it back.
Current edid CRC calculates routine adds the last CRC byte,
and check if non-zero.

This behavior is not accurate; actually, we need to return
the actual CRC value when corruption is detected.
This commit changes this issue by returning the calculated CRC,
and initiate the required sequence.

Change since v4
- Fix for CI.CHECKPATCH

Change since v3
- Fix a minor typo.

Change since v2
- Rewrite checksum computation routine to avoid duplicated code.
- Rename to avoid confusion.

Change since v1
- Have separate routine for returning real CRC.

Signed-off-by: Jerry (Fangzhi) Zuo 
---
 drivers/gpu/drm/drm_dp_helper.c | 35 +
 drivers/gpu/drm/drm_edid.c  | 23 ++
 include/drm/drm_connector.h |  6 ++
 include/drm/drm_dp_helper.h |  3 +++
 4 files changed, 63 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 2c7870aef469..85a777ce98ba 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -351,6 +351,41 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
 }
 EXPORT_SYMBOL(drm_dp_dpcd_read_link_status);
 
+/**
+ * drm_dp_send_real_edid_checksum() - send back real edid checksum value
+ * @aux: DisplayPort AUX channel
+ * @real_edid_checksum: real edid checksum for the last block
+ *
+ * Returns true on success
+ */
+bool drm_dp_send_real_edid_checksum(struct drm_dp_aux *aux,
+u8 real_edid_checksum)
+{
+   u8 link_edid_read = 0, auto_test_req = 0, test_resp = 0;
+
+   drm_dp_dpcd_read(aux, DP_DEVICE_SERVICE_IRQ_VECTOR, _test_req, 1);
+   auto_test_req &= DP_AUTOMATED_TEST_REQUEST;
+
+   drm_dp_dpcd_read(aux, DP_TEST_REQUEST, _edid_read, 1);
+   link_edid_read &= DP_TEST_LINK_EDID_READ;
+
+   if (!auto_test_req || !link_edid_read) {
+   DRM_DEBUG_KMS("Source DUT does not support TEST_EDID_READ\n");
+   return false;
+   }
+
+   drm_dp_dpcd_write(aux, DP_DEVICE_SERVICE_IRQ_VECTOR, _test_req, 1);
+
+   /* send back checksum for the last edid extension block data */
+   drm_dp_dpcd_write(aux, DP_TEST_EDID_CHECKSUM, _edid_checksum, 1);
+
+   test_resp |= DP_TEST_EDID_CHECKSUM_WRITE;
+   drm_dp_dpcd_write(aux, DP_TEST_RESPONSE, _resp, 1);
+
+   return true;
+}
+EXPORT_SYMBOL(drm_dp_send_real_edid_checksum);
+
 /**
  * drm_dp_downstream_max_clock() - extract branch device max
  * pixel rate for legacy VGA
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 5b33b7cfd645..0e35405ecc74 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1450,11 +1450,22 @@ static int validate_displayid(u8 *displayid, int 
length, int idx);
 static int drm_edid_block_checksum(const u8 *raw_edid)
 {
int i;
-   u8 csum = 0;
-   for (i = 0; i < EDID_LENGTH; i++)
+   u8 csum = 0, crc = 0;
+
+   for (i = 0; i < EDID_LENGTH - 1; i++)
csum += raw_edid[i];
 
-   return csum;
+   crc = 0x100 - csum;
+
+   return crc;
+}
+
+static bool drm_edid_block_checksum_diff(const u8 *raw_edid, u8 real_checksum)
+{
+   if (raw_edid[EDID_LENGTH - 1] != real_checksum)
+   return true;
+   else
+   return false;
 }
 
 static bool drm_edid_is_zero(const u8 *in_edid, int length)
@@ -1512,7 +1523,7 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool 
print_bad_edid,
}
 
csum = drm_edid_block_checksum(raw_edid);
-   if (csum) {
+   if (drm_edid_block_checksum_diff(raw_edid, csum)) {
if (edid_corrupt)
*edid_corrupt = true;
 
@@ -1653,6 +1664,7 @@ static void connector_bad_edid(struct drm_connector 
*connector,
   u8 *edid, int num_blocks)
 {
int i;
+   u8 num_of_ext = edid[0x7e];
 
if (connector->bad_edid_counter++ && !drm_debug_enabled(DRM_UT_KMS))
return;
@@ -1675,6 +1687,9 @@ static void connector_bad_edid(struct drm_connector 
*connector,
   prefix, DUMP_PREFIX_NONE, 16, 1,
   block, EDID_LENGTH, false);
}
+
+   /* Calculate real checksum for the last edid extension block data */
+   connector->real_edid_checksum = drm_edid_block_checksum(edid + 
num_of_ext * EDID_LENGTH);
 }
 
 /* Get override or firmware EDID */
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 5f8c3389d46f..b07d8276a58c 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1349,6 +1349,12 @@ struct drm_connector {
 * rev1.1 4.2.2.6
 */
bool edid_corrupt;
+   /**
+* @real_edid_checksum: real edid checksum for corrupted edid block.
+* 

[PATCH] drm/modes: Support video parameters with only reflect option

2019-12-09 Thread Stephan Gerhold
At the moment, video mode parameters like video=540x960,reflect_x,
(without rotation set) are silently ignored.

One of the reasons for this is that the calculation that
combines the panel_orientation with cmdline->rotation_reflection
does not handle the case when cmdline->rotation_reflection does
not have any rotation set.
(i.e. cmdline->rotation_reflection & DRM_MODE_ROTATE_MASK == 0)

Example:
  *rotation = DRM_MODE_ROTATE_0 (no panel_orientation)
  cmdline->rotation_reflection = DRM_MODE_REFLECT_X (video=MODE,reflect_x)

The current code does:
  panel_rot = ilog2(*rotation & DRM_MODE_ROTATE_MASK);
  cmdline_rot = ilog2(cmdline->rotation_reflection & DRM_MODE_ROTATE_MASK);
  sum_rot = (panel_rot + cmdline_rot) % 4;

and therefore:
  panel_rot = ilog2(DRM_MODE_ROTATE_0) = ilog2(1) = 0
  cmdline_rot = ilog2(0) = -1
  sum_rot = (0 + -1) % 4 = -1 % 4 = 3
   ...
  *rotation = DRM_MODE_ROTATE_270 | DRM_MODE_REFLECT_X

So we incorrectly generate DRM_MODE_ROTATE_270 in this case.
To prevent cmdline_rot from becoming -1, we need to treat
the rotation as DRM_MODE_ROTATE_0.

On the other hand, there is no need to go through that calculation
at all if no rotation is set in rotation_reflection.
A simple XOR is enough to combine the reflections.

Finally, also allow DRM_MODE_ROTATE_0 in the if statement below.
DRM_MODE_ROTATE_0 means "no rotation" and should therefore not
require any special handling (e.g. specific tiling format).

This makes video parameters with only reflect option work correctly.

Signed-off-by: Stephan Gerhold 
---
 drivers/gpu/drm/drm_client_modeset.c | 27 ---
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/drm_client_modeset.c 
b/drivers/gpu/drm/drm_client_modeset.c
index 895b73f23079..cfebce4f19a5 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -859,19 +859,23 @@ bool drm_client_rotation(struct drm_mode_set *modeset, 
unsigned int *rotation)
 */
cmdline = >cmdline_mode;
if (cmdline->specified && cmdline->rotation_reflection) {
-   unsigned int cmdline_rest, panel_rest;
-   unsigned int cmdline_rot, panel_rot;
-   unsigned int sum_rot, sum_rest;
+   if (cmdline->rotation_reflection & DRM_MODE_ROTATE_MASK) {
+   unsigned int cmdline_rest, panel_rest;
+   unsigned int cmdline_rot, panel_rot;
+   unsigned int sum_rot, sum_rest;
 
-   panel_rot = ilog2(*rotation & DRM_MODE_ROTATE_MASK);
-   cmdline_rot = ilog2(cmdline->rotation_reflection & 
DRM_MODE_ROTATE_MASK);
-   sum_rot = (panel_rot + cmdline_rot) % 4;
+   panel_rot = ilog2(*rotation & DRM_MODE_ROTATE_MASK);
+   cmdline_rot = ilog2(cmdline->rotation_reflection & 
DRM_MODE_ROTATE_MASK);
+   sum_rot = (panel_rot + cmdline_rot) % 4;
 
-   panel_rest = *rotation & ~DRM_MODE_ROTATE_MASK;
-   cmdline_rest = cmdline->rotation_reflection & 
~DRM_MODE_ROTATE_MASK;
-   sum_rest = panel_rest ^ cmdline_rest;
+   panel_rest = *rotation & ~DRM_MODE_ROTATE_MASK;
+   cmdline_rest = cmdline->rotation_reflection & 
~DRM_MODE_ROTATE_MASK;
+   sum_rest = panel_rest ^ cmdline_rest;
 
-   *rotation = (1 << sum_rot) | sum_rest;
+   *rotation = (1 << sum_rot) | sum_rest;
+   } else {
+   *rotation ^= cmdline->rotation_reflection;
+   }
}
 
/*
@@ -879,7 +883,8 @@ bool drm_client_rotation(struct drm_mode_set *modeset, 
unsigned int *rotation)
 * depending on the hardware this may require the framebuffer
 * to be in a specific tiling format.
 */
-   if ((*rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_180 ||
+   if (((*rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_0 &&
+(*rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_180) ||
!plane->rotation_property)
return false;
 
-- 
2.24.0

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

Re: [PATCH] dt-bindings: display: Convert a bunch of panels to DT schema

2019-12-09 Thread Sam Ravnborg
Hi Rob.

> 
> Yes. The issue would be enforcing the big disclaimer of "Do not add
> your panel here unless it has a single power rail." (And anything else
> we think of). Between a single line add vs. a whole new doc, you know
> what people will pick. I guess panels could still be moved out of the
> common doc later on. We'd also have to be fighting off the "let me add
> just one new property for my panel".

If the panel cannot be supported by the panel-simple driver then
this is a good sign that it does not belong in the bindings file.
Or something like this.

I do not see it as a 1:1 for all panels but I guess most panels
supported by panel-simple would go in a single bindings file.

> You did. I'd like to hear Thierry's thoughts on this before going down
> this path.
Seconded, Thierry?

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

Re: [PATCH] dt-bindings: display: Convert a bunch of panels to DT schema

2019-12-09 Thread Rob Herring
On Wed, Dec 4, 2019 at 2:15 PM Sam Ravnborg  wrote:
>
> Hi Rob.
>
> On Mon, Dec 02, 2019 at 08:38:39AM -0600, Rob Herring wrote:
> > On Sat, Nov 30, 2019 at 1:43 PM Sam Ravnborg  wrote:
> > >
> > > Hi Rob.
> > >
> > > Thanks for doing this boring, trivial and tiresome task.
> >
> > It was somewhat scripted at least...
> >
> > > On Tue, Nov 19, 2019 at 05:13:09PM -0600, Rob Herring wrote:
> > > > Convert all the 'simple' panels which either use the single
> > > > 'power-supply' property or don't say and just reference
> > > > simple-panel.txt. In the later case, bindings are clear as to which
> > > > properties are required or unused.
> > > >
> > > > Cc: Maxime Ripard 
> > > > Cc: Chen-Yu Tsai 
> > > > Cc: Thierry Reding 
> > > > Cc: Sam Ravnborg 
> > > > Signed-off-by: Rob Herring 
> > >
> > > So Thierry and I ended up as Maintianes for them all.
> > > I gues thats OK as we look after the panel stuff anyway.
> > >
> > > > ---
> > > > We could perhaps consolidate a bunch of these, but I have no idea how
> > > > accurate some of these are WRT what's required or not. Seems strange
> > > > that 'backlight' is optional unless the backlight is tied full on for
> > > > example. If that's the case, then should backlight ever be required?
> > > I do not really follow you here.
> > > Looking through the patch set things looks normal to me.
> > >
> > > What do I miss here?
> >
> > I'm saying a bunch of these could just be a single schema doc with a
> > long list of compatibles. The variation is in what properties are
> > required or not.
>
> It would be just wonderful if we could have only a few
> dt-bindings for the simple panels.
> Like you I cannot see why enable-gpios should be required.
>
> We could end up with something like three classes of bindings:
>
> +required:
> +  - compatible
> +  - power-supply
>
> +required:
> +  - compatible
> +  - port
> +  - power-supply
>
> +required:
> +  - backlight
> +  - compatible
> +  - port
> +  - power-supply
>
> The port part is to my best understanding a way to
> connect the panel to the display driver.
> So it should be more how the connect in the binding
> that decides if port is used or not.

Yes, though it's also initially panels were just the child of the
controller before 'port' came along. We still allow both ways though
'port' is preferred.

> And the panel should not require it.
>
> I may use it with display drivers that do not support it
> in their binding.
>
> And then we have backlight - which can hardly be mandatory.
> The panel could hard-wire it to provide backligt if it wanted
> and the binding should continue to work.
> I think you had the same argument.
>
> So we are down to two required properties:
> +required:
> +  - compatible
> +  - power-supply
>
> Could we put all simple panels in one binding file
> with only this - that would be great.
> Hopefully scripted somehow...
>
> Then adding new simple panels would be a matter of
> adding a new compatible.

Yes. The issue would be enforcing the big disclaimer of "Do not add
your panel here unless it has a single power rail." (And anything else
we think of). Between a single line add vs. a whole new doc, you know
what people will pick. I guess panels could still be moved out of the
common doc later on. We'd also have to be fighting off the "let me add
just one new property for my panel".

> And if they are sorted this should not cause many merge issues either.
>
> I hope I understood you correct.

You did. I'd like to hear Thierry's thoughts on this before going down
this path.

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

Re: [PATCH 04/11] drm/i915: Don't WARN on HDCP toggle if get_hw_state returns false

2019-12-09 Thread Ville Syrjälä
On Mon, Dec 09, 2019 at 11:16:27AM -0500, Sean Paul wrote:
> On Mon, Dec 9, 2019 at 10:21 AM Ville Syrjälä
>  wrote:
> >
> > On Fri, Dec 06, 2019 at 08:52:33AM -0500, Sean Paul wrote:
> > > On Thu, Dec 05, 2019 at 09:39:35PM +0200, Ville Syrjälä wrote:
> > > > On Tue, Dec 03, 2019 at 12:36:27PM -0500, Sean Paul wrote:
> > > > > From: Sean Paul 
> > > > >
> > > > > Now that we can rely on transcoder disable to toggle signalling off,
> > > > > it's less of a catastrophe if get_hw_state() returns false.
> > > > >
> > > > > Once we enable MST, this will be a valid exit path and we want to make
> > > > > sure we're not spamming the logs needlessly.
> > > > >
> > > > > Signed-off-by: Sean Paul 
> > > > > ---
> > > > >  drivers/gpu/drm/i915/display/intel_ddi.c | 2 +-
> > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> > > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > index e8ac98a8ee7f..ca28913a4c9f 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > @@ -1983,7 +1983,7 @@ int intel_ddi_toggle_hdcp_signalling(struct 
> > > > > intel_encoder *intel_encoder,
> > > > >   if (WARN_ON(!wakeref))
> > > > >   return -ENXIO;
> > > > >
> > > > > - if (WARN_ON(!intel_encoder->get_hw_state(intel_encoder, ))) {
> > > > > + if (!intel_encoder->get_hw_state(intel_encoder, )) {
> > > >
> > > > How can this get called when the encoder is not enabled?
> > > > Feels like this whole thing is trying to paper over some
> > > > bigger bug in the hdcp code.
> > >
> > > In the MST patch, I've added a call to intel_hdcp_disable() in the 
> > > connector
> > > destroy path. Usually toggling will be disabled as part of the check_link 
> > > call
> > > that is initiated on unplug, so in the destroy path it's non-essential to 
> > > do
> > > this again.
> >
> > Can't we just leave things be until userspace disables the thing?
> 
> The connector disappears, so userspace won't be able to disable it.

That would make everything broken. The connector should hang around
as a zombie until the last user disappears.

> 
> > If not, then we should know whether hdcp is still enabled. And if
> > hdcp is enabled so is the encoder, thus we don't need such silly
> > checks.
> 
> Alright, I'll look at taking this angle.
> 
> Sean
> 
> >
> > --
> > Ville Syrjälä
> > Intel

-- 
Ville Syrjälä
Intel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH 04/11] drm/i915: Don't WARN on HDCP toggle if get_hw_state returns false

2019-12-09 Thread Sean Paul
On Mon, Dec 9, 2019 at 10:21 AM Ville Syrjälä
 wrote:
>
> On Fri, Dec 06, 2019 at 08:52:33AM -0500, Sean Paul wrote:
> > On Thu, Dec 05, 2019 at 09:39:35PM +0200, Ville Syrjälä wrote:
> > > On Tue, Dec 03, 2019 at 12:36:27PM -0500, Sean Paul wrote:
> > > > From: Sean Paul 
> > > >
> > > > Now that we can rely on transcoder disable to toggle signalling off,
> > > > it's less of a catastrophe if get_hw_state() returns false.
> > > >
> > > > Once we enable MST, this will be a valid exit path and we want to make
> > > > sure we're not spamming the logs needlessly.
> > > >
> > > > Signed-off-by: Sean Paul 
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_ddi.c | 2 +-
> > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > index e8ac98a8ee7f..ca28913a4c9f 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > @@ -1983,7 +1983,7 @@ int intel_ddi_toggle_hdcp_signalling(struct 
> > > > intel_encoder *intel_encoder,
> > > >   if (WARN_ON(!wakeref))
> > > >   return -ENXIO;
> > > >
> > > > - if (WARN_ON(!intel_encoder->get_hw_state(intel_encoder, ))) {
> > > > + if (!intel_encoder->get_hw_state(intel_encoder, )) {
> > >
> > > How can this get called when the encoder is not enabled?
> > > Feels like this whole thing is trying to paper over some
> > > bigger bug in the hdcp code.
> >
> > In the MST patch, I've added a call to intel_hdcp_disable() in the connector
> > destroy path. Usually toggling will be disabled as part of the check_link 
> > call
> > that is initiated on unplug, so in the destroy path it's non-essential to do
> > this again.
>
> Can't we just leave things be until userspace disables the thing?

The connector disappears, so userspace won't be able to disable it.

> If not, then we should know whether hdcp is still enabled. And if
> hdcp is enabled so is the encoder, thus we don't need such silly
> checks.

Alright, I'll look at taking this angle.

Sean

>
> --
> Ville Syrjälä
> Intel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [Intel-gfx] [PATCH 03/11] drm/i915: Disable HDCP signalling on transcoder disable

2019-12-09 Thread Sean Paul
On Mon, Dec 9, 2019 at 10:18 AM Ville Syrjälä
 wrote:
>
> On Fri, Dec 06, 2019 at 08:55:09AM -0500, Sean Paul wrote:
> > On Thu, Dec 05, 2019 at 09:33:19PM +0200, Ville Syrjälä wrote:
> > > On Tue, Dec 03, 2019 at 12:36:26PM -0500, Sean Paul wrote:
> > > > From: Sean Paul 
> > > >
> > > > Currently we rely on intel_hdcp_disable() to disable HDCP signalling in
> > > > the DDI Function Control register. This patch adds a safety net by also
> > > > clearing the bit when we disable the transcoder.
> > > >
> > > > Once we have HDCP over MST and disappearing connectors, we want to make
> > > > sure that the signalling is truly disabled even if HDCP teardown doesn't
> > > > go as planned.
> > >
> > > Why wouldn't it go as planned?
> > >
> >
> > Because things can fail in weird and wonderful ways on unplug :-)
>
> Not really.
>

That is a bold position to take, bugs happen, hardware flakes, etc.

> >
> > It's a safety net. I saw this function and figured HDCP signalling should be
> > explicitly cleared here as well.
>
> I call it dead and confusing code.

...adding a bit to an existing register clear is confusing? That might
be a touch hyperbolic.

> If we get here with HDCP still
> enabled we have a more serious bug somewhere else.
>

Ok, I suppose it's your call as to whether you take this patch, feel
free to drop.

Sean

> --
> Ville Syrjälä
> Intel
> ___
> 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

Re: [PATCH 1/4] dt-bindings: display: panel: document panel-id

2019-12-09 Thread Rob Clark
On Mon, Dec 9, 2019 at 7:31 AM Rob Herring  wrote:
>
> On Sun, Dec 8, 2019 at 3:24 PM Rob Clark  wrote:
> >
> > On Sun, Dec 8, 2019 at 10:28 AM Laurent Pinchart
> >  wrote:
> > >
> > > Hi Rob,
> > >
> > > On Sun, Dec 08, 2019 at 08:50:32AM -0800, Rob Clark wrote:
> > > > On Sun, Dec 8, 2019 at 6:45 AM Laurent Pinchart wrote:
> > > > > On Sat, Dec 07, 2019 at 12:35:50PM -0800, Rob Clark wrote:
> > > > > > From: Rob Clark 
> > > > > >
> > > > > > For devices that have one of several possible panels installed, the
> > > > > > panel-id property gives firmware a generic way to locate and enable 
> > > > > > the
> > > > > > panel node corresponding to the installed panel.  Example of how to 
> > > > > > use
> > > > > > this property:
> > > > > >
> > > > > > ivo_panel {
> > > > > > compatible = "ivo,m133nwf4-r0";
> > > > > > panel-id = <0xc5>;
> > > > > > status = "disabled";
> > > > > >
> > > > > > ports {
> > > > > > port {
> > > > > > ivo_panel_in_edp: endpoint {
> > > > > > remote-endpoint = <_out_ivo>;
> > > > > > };
> > > > > > };
> > > > > > };
> > > > > > };
> > > > > >
> > > > > > boe_panel {
> > > > > > compatible = "boe,nv133fhm-n61";
> > > > > > panel-id = <0xc4>;
> > > > > > status = "disabled";
> > > > > >
> > > > > > ports {
> > > > > > port {
> > > > > > boe_panel_in_edp: endpoint {
> > > > > > remote-endpoint = <_out_boe>;
> > > > > > };
> > > > > > };
> > > > > > };
> > > > > > };
> > > > > >
> > > > > > sn65dsi86: bridge@2c {
> > > > > > compatible = "ti,sn65dsi86";
> > > > > >
> > > > > > ports {
> > > > > > #address-cells = <1>;
> > > > > > #size-cells = <0>;
> > > > > >
> > > > > > port@0 {
> > > > > > reg = <0>;
> > > > > > sn65dsi86_in_a: endpoint {
> > > > > > remote-endpoint = <_out>;
> > > > > > };
> > > > > > };
> > > > > >
> > > > > > port@1 {
> > > > > > reg = <1>;
> > > > > >
> > > > > > sn65dsi86_out_boe: endpoint@c4 {
> > > > > > remote-endpoint = <_panel_in_edp>;
> > > > > > };
> > > > > >
> > > > > > sn65dsi86_out_ivo: endpoint@c5 {
> > > > > > remote-endpoint = <_panel_in_edp>;
> > > > > > };
> > > > > > };
> > > > > > };
> > > > > > };
> > > > > >
> > > > > > Signed-off-by: Rob Clark 
> > > > > > ---
> > > > > >  .../bindings/display/panel/panel-common.yaml  | 26 
> > > > > > +++
> > > > > >  1 file changed, 26 insertions(+)
> > > > > >
> > > > > > diff --git 
> > > > > > a/Documentation/devicetree/bindings/display/panel/panel-common.yaml 
> > > > > > b/Documentation/devicetree/bindings/display/panel/panel-common.yaml
> > > > > > index ef8d8cdfcede..6113319b91dd 100644
> > > > > > --- 
> > > > > > a/Documentation/devicetree/bindings/display/panel/panel-common.yaml
> > > > > > +++ 
> > > > > > b/Documentation/devicetree/bindings/display/panel/panel-common.yaml
> > > > > > @@ -75,6 +75,32 @@ properties:
> > > > > >in the device graph bindings defined in
> > > > > >Documentation/devicetree/bindings/graph.txt.
> > > > > >
> > > > > > +  panel-id:
> > > > > > +description:
> > > > > > +  To support the case where one of several different panels 
> > > > > > can be installed
> > > > > > +  on a device, the panel-id property can be used by the 
> > > > > > firmware to identify
> > > > > > +  which panel should have it's status changed to "ok".  This 
> > > > > > property is not
> > > > > > +  used by the HLOS itself.
> > > > >
> > > > > If your firmware can modify the status property of a panel, it can 
> > > > > also
> > > > > add DT nodes. As discussed before, I don't think this belongs to DT.
> > > > > Even if panel-id isn't used by the operating system, you have Linux
> > > > > kernel patches in this series that show that this isn't transparent.
> > > >
> > > > I've already explained several times why this is not feasible.  It
> > > > would require DtbLoader to be familiar with each individual device,
> > > > and be rev'd every time a new device appears.  That is not practical
> > > > at all.
> > > >
> > > > (And fwiw, the ACPI tables describe each panel.. with an ACPI method
> > > > that is passed the the panel-id and returns the appropriate table..
> > > > since DT doesn't have methods, this is the solution.)
> > > >
> > > > I stand by this patch, we can't keep running away from this problem
> > > > and wave the magic firmware wand.
> > >
> > > I believe in firmware solutions more than firmware magic wands :-)
> > >
> >
> > and with that in mind, I think I've come up with a firmware solution,
> > 

[PATCH v2 2/2] drm/panel: simple: Add Rocktech RK101II01D-CT panel

2019-12-09 Thread Jyri Sarha
Add support for Rocktech RK101II01D-CT, 10.1" 1280x800 TFT with LVDS
interface, LED backlight and integrated Goodix GT928 capacitive touch
panel.

Signed-off-by: Jyri Sarha 
Reviewed-by: Tomi Valkeinen 
---
 drivers/gpu/drm/panel/panel-simple.c | 32 
 1 file changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
index 5d487686d25c..489e217102ea 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -2479,6 +2479,35 @@ static const struct panel_desc rocktech_rk070er9427 = {
.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
 };
 
+static const struct drm_display_mode rocktech_rk101ii01d_ct_mode = {
+   .clock = 71100,
+   .hdisplay = 1280,
+   .hsync_start = 1280 + 48,
+   .hsync_end = 1280 + 48 + 32,
+   .htotal = 1280 + 48 + 32 + 80,
+   .vdisplay = 800,
+   .vsync_start = 800 + 2,
+   .vsync_end = 800 + 2 + 5,
+   .vtotal = 800 + 2 + 5 + 16,
+   .vrefresh = 60,
+};
+
+static const struct panel_desc rocktech_rk101ii01d_ct = {
+   .modes = _rk101ii01d_ct_mode,
+   .num_modes = 1,
+   .size = {
+   .width = 217,
+   .height = 136,
+   },
+   .delay = {
+   .prepare = 50,
+   .disable = 50,
+   },
+   .bus_flags = DRM_BUS_FLAG_DE_HIGH,
+   .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
+   .connector_type = DRM_MODE_CONNECTOR_LVDS,
+};
+
 static const struct drm_display_mode samsung_lsn122dl01_c01_mode = {
.clock = 271560,
.hdisplay = 2560,
@@ -3338,6 +3367,9 @@ static const struct of_device_id platform_of_match[] = {
}, {
.compatible = "rocktech,rk070er9427",
.data = _rk070er9427,
+   }, {
+   .compatible = "rocktech,rk101ii01d-ct",
+   .data = _rk101ii01d_ct,
}, {
.compatible = "samsung,lsn122dl01-c01",
.data = _lsn122dl01_c01,
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

[PATCH v2 1/2] dt-bindings: display: DT schema for rocktech, rk101ii01d-ct panel

2019-12-09 Thread Jyri Sarha
Add DT schema binding for Rocktech Displays Limited RK101II01D-CT
10.1" TFT 1280x800 Pixels with LVDS interface, LED Backlight and
capacitive touch panel.

Signed-off-by: Jyri Sarha 
---
 .../display/panel/rocktech,rk101ii01d-ct.yaml | 48 +++
 1 file changed, 48 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/rocktech,rk101ii01d-ct.yaml

diff --git 
a/Documentation/devicetree/bindings/display/panel/rocktech,rk101ii01d-ct.yaml 
b/Documentation/devicetree/bindings/display/panel/rocktech,rk101ii01d-ct.yaml
new file mode 100644
index ..b37f89ca4bd0
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/display/panel/rocktech,rk101ii01d-ct.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/rocktech,rk101ii01d-ct.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rocktech Displays Ltd RK101II01D-CT 10.1" TFT 1280x800 Pixels
+
+maintainers:
+  - Jyri Sarha 
+  - Thierry Reding 
+
+allOf:
+  - $ref: panel-common.yaml#
+
+description: |
+  Rocktech Displays Limited RK101II01D-CT 10.1" TFT 1280x800 Pixels
+  with LVDS interface, LED Backlight and capacitive touch panel. For
+  touch screen details see "goodix,gt928" in:
+  Documentation/devicetree/bindings/input/touchscreen/goodix.txt
+
+properties:
+  compatible:
+const: rocktech,rk101ii01d-ct
+
+  reset-gpios: true
+  enable-gpios: true
+  backlight: true
+  port: true
+
+required:
+  - compatible
+  - power-supply
+
+examples:
+  - |
+display0 {
+compatible = "rocktech,rk101ii01d-ct";
+backlight = <_bl>;
+enable-gpios = < 8 GPIO_ACTIVE_HIGH>;
+power-supply = <_supply>;
+
+port {
+lcd_in0: endpoint {
+remote-endpoint = <_out0>;
+};
+};
+};
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

[PATCH v2 0/2] drm/panel: simple: Rocktech RK101II01D-CT + binding

2019-12-09 Thread Jyri Sarha
Since v1:
- Add "Reviewed-by: Tomi Valkeinen " to
  "drm/panel: simple: Add Rocktech RK101II01D-CT panel"
- Fix "dt-bindings: display: DT schema for rocktech,rk101ii01d-ct panel"
  Fix a copy-paste error on line 4 ("$id: http://devicetree.org/schemas...;)

Add support for Rocktech RK101II01D-CT panel to panel-simple and add
yaml binding for it.

Jyri Sarha (2):
  dt-bindings: display: DT schema for rocktech,rk101ii01d-ct panel
  drm/panel: simple: Add Rocktech RK101II01D-CT panel

 .../display/panel/rocktech,rk101ii01d-ct.yaml | 48 +++
 drivers/gpu/drm/panel/panel-simple.c  | 32 +
 2 files changed, 80 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/rocktech,rk101ii01d-ct.yaml

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

Re: [PATCH RESEND 3/4] dt-bindings: drm/bridge: analogix-anx78xx: support bypass GPIO

2019-12-09 Thread Laurent Pinchart
Hi Hsin-Yi,

On Mon, Dec 09, 2019 at 11:09:34PM +0800, Hsin-Yi Wang wrote:
> On Mon, Dec 9, 2019 at 10:55 PM Laurent Pinchart wrote:
> > On Mon, Dec 09, 2019 at 10:50:15PM +0800, Hsin-Yi Wang wrote:
> > > Support optional feature: bypass GPIO.
> > >
> > > Some SoC (eg. mt8173) have a hardware mux that connects to 2 ports:
> > > anx7688 and hdmi. When the GPIO is active, the bridge is bypassed.
> >
> > This doesn't look like the right place to fix this, as the mux is
> > unrelated to the bridge. You would have to duplicate this logic in every
> > bridge driver otherwise.
> >
> > Could you describe the hardware topology in a bit more details ? I can
> > then try to advise on how to best support it.
>
> Hi Laurent,
> 
> The mt8173 layout is:
> 
> MT8173 HDMI bridge-- hardware mux --- HDMI
>|
>  anx7688

You may have used a proportional font when writing this, the | doesn't
align with anything using a fixed font. Do I assume correctly that the
hardware multiplexer is actually a demultiplexer with one input and two
outputs ?
 +---+
+-+ +--+/--> | HDMI  |
| MT8173  |  HDMI   |   -->| --/ | Connector |
|  HDMI   | --> |--/   | +---+
| Encoder | |->| --\ +---+  +---+
+-+ +--+\--> | ANX7688   | ---> | USB-C |
 | Bridge|  | Connector |
 +---+  +---+

> There's a hardware mux that takes mt8173 hdmi as input and has 2
> output port: native hdmi and anx7688 bridge.
> If gpio is active, we would like it to go to HDMI.
> 
> Previous approach is to make hardware mux a generic gpio mux bridge,
> but this is probably a very rare use case that is only for
> mt8173.(https://lore.kernel.org/lkml/57723ad2.8020...@codeaurora.org/)
> We merge the mux and anx7688 to a single bridge and leave this as an
> optional feature in this time.

I think that's a better approach, at least at the DT level. The HDMI
demultiplexer should be represented as a DT node with 3 ports (one input
and two outputs) with a control GPIO.

From a video point of view, the ANX7688 should be represented as a DT
node with 2 ports (one input and one output), regardless of whether it
is used in conjunction with an HDMI switch as shown above, or directly
connected to the output of an HDMI encoder. However, as the ANX7688
supports both DP output and USB-C output, the situation may be slightly
more complex. Please see https://patchwork.kernel.org/patch/11184895/
for a similar discussion, related to the ANX7625.

In any case, I don't think the ANX7688 should care about the GPIO.

-- 
Regards,

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

Re: [PATCH 1/4] dt-bindings: display: panel: document panel-id

2019-12-09 Thread Rob Herring
On Sun, Dec 8, 2019 at 3:24 PM Rob Clark  wrote:
>
> On Sun, Dec 8, 2019 at 10:28 AM Laurent Pinchart
>  wrote:
> >
> > Hi Rob,
> >
> > On Sun, Dec 08, 2019 at 08:50:32AM -0800, Rob Clark wrote:
> > > On Sun, Dec 8, 2019 at 6:45 AM Laurent Pinchart wrote:
> > > > On Sat, Dec 07, 2019 at 12:35:50PM -0800, Rob Clark wrote:
> > > > > From: Rob Clark 
> > > > >
> > > > > For devices that have one of several possible panels installed, the
> > > > > panel-id property gives firmware a generic way to locate and enable 
> > > > > the
> > > > > panel node corresponding to the installed panel.  Example of how to 
> > > > > use
> > > > > this property:
> > > > >
> > > > > ivo_panel {
> > > > > compatible = "ivo,m133nwf4-r0";
> > > > > panel-id = <0xc5>;
> > > > > status = "disabled";
> > > > >
> > > > > ports {
> > > > > port {
> > > > > ivo_panel_in_edp: endpoint {
> > > > > remote-endpoint = <_out_ivo>;
> > > > > };
> > > > > };
> > > > > };
> > > > > };
> > > > >
> > > > > boe_panel {
> > > > > compatible = "boe,nv133fhm-n61";
> > > > > panel-id = <0xc4>;
> > > > > status = "disabled";
> > > > >
> > > > > ports {
> > > > > port {
> > > > > boe_panel_in_edp: endpoint {
> > > > > remote-endpoint = <_out_boe>;
> > > > > };
> > > > > };
> > > > > };
> > > > > };
> > > > >
> > > > > sn65dsi86: bridge@2c {
> > > > > compatible = "ti,sn65dsi86";
> > > > >
> > > > > ports {
> > > > > #address-cells = <1>;
> > > > > #size-cells = <0>;
> > > > >
> > > > > port@0 {
> > > > > reg = <0>;
> > > > > sn65dsi86_in_a: endpoint {
> > > > > remote-endpoint = <_out>;
> > > > > };
> > > > > };
> > > > >
> > > > > port@1 {
> > > > > reg = <1>;
> > > > >
> > > > > sn65dsi86_out_boe: endpoint@c4 {
> > > > > remote-endpoint = <_panel_in_edp>;
> > > > > };
> > > > >
> > > > > sn65dsi86_out_ivo: endpoint@c5 {
> > > > > remote-endpoint = <_panel_in_edp>;
> > > > > };
> > > > > };
> > > > > };
> > > > > };
> > > > >
> > > > > Signed-off-by: Rob Clark 
> > > > > ---
> > > > >  .../bindings/display/panel/panel-common.yaml  | 26 
> > > > > +++
> > > > >  1 file changed, 26 insertions(+)
> > > > >
> > > > > diff --git 
> > > > > a/Documentation/devicetree/bindings/display/panel/panel-common.yaml 
> > > > > b/Documentation/devicetree/bindings/display/panel/panel-common.yaml
> > > > > index ef8d8cdfcede..6113319b91dd 100644
> > > > > --- 
> > > > > a/Documentation/devicetree/bindings/display/panel/panel-common.yaml
> > > > > +++ 
> > > > > b/Documentation/devicetree/bindings/display/panel/panel-common.yaml
> > > > > @@ -75,6 +75,32 @@ properties:
> > > > >in the device graph bindings defined in
> > > > >Documentation/devicetree/bindings/graph.txt.
> > > > >
> > > > > +  panel-id:
> > > > > +description:
> > > > > +  To support the case where one of several different panels can 
> > > > > be installed
> > > > > +  on a device, the panel-id property can be used by the firmware 
> > > > > to identify
> > > > > +  which panel should have it's status changed to "ok".  This 
> > > > > property is not
> > > > > +  used by the HLOS itself.
> > > >
> > > > If your firmware can modify the status property of a panel, it can also
> > > > add DT nodes. As discussed before, I don't think this belongs to DT.
> > > > Even if panel-id isn't used by the operating system, you have Linux
> > > > kernel patches in this series that show that this isn't transparent.
> > >
> > > I've already explained several times why this is not feasible.  It
> > > would require DtbLoader to be familiar with each individual device,
> > > and be rev'd every time a new device appears.  That is not practical
> > > at all.
> > >
> > > (And fwiw, the ACPI tables describe each panel.. with an ACPI method
> > > that is passed the the panel-id and returns the appropriate table..
> > > since DT doesn't have methods, this is the solution.)
> > >
> > > I stand by this patch, we can't keep running away from this problem
> > > and wave the magic firmware wand.
> >
> > I believe in firmware solutions more than firmware magic wands :-)
> >
>
> and with that in mind, I think I've come up with a firmware solution,
> in the form of dtb overlays :-)
>
> I've managed to get DtbLoader to find and load a panel overlay based
> on the panel-id it reads, which drops all patches in the patchset
> except the last one, which now has this delta:

This looks good to me. The only slight concern I have with it is
making the overlay 

Re: [PATCH 04/11] drm/i915: Don't WARN on HDCP toggle if get_hw_state returns false

2019-12-09 Thread Ville Syrjälä
On Fri, Dec 06, 2019 at 08:52:33AM -0500, Sean Paul wrote:
> On Thu, Dec 05, 2019 at 09:39:35PM +0200, Ville Syrjälä wrote:
> > On Tue, Dec 03, 2019 at 12:36:27PM -0500, Sean Paul wrote:
> > > From: Sean Paul 
> > > 
> > > Now that we can rely on transcoder disable to toggle signalling off,
> > > it's less of a catastrophe if get_hw_state() returns false.
> > > 
> > > Once we enable MST, this will be a valid exit path and we want to make
> > > sure we're not spamming the logs needlessly.
> > > 
> > > Signed-off-by: Sean Paul 
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_ddi.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > index e8ac98a8ee7f..ca28913a4c9f 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > @@ -1983,7 +1983,7 @@ int intel_ddi_toggle_hdcp_signalling(struct 
> > > intel_encoder *intel_encoder,
> > >   if (WARN_ON(!wakeref))
> > >   return -ENXIO;
> > >  
> > > - if (WARN_ON(!intel_encoder->get_hw_state(intel_encoder, ))) {
> > > + if (!intel_encoder->get_hw_state(intel_encoder, )) {
> > 
> > How can this get called when the encoder is not enabled?
> > Feels like this whole thing is trying to paper over some
> > bigger bug in the hdcp code.
> 
> In the MST patch, I've added a call to intel_hdcp_disable() in the connector
> destroy path. Usually toggling will be disabled as part of the check_link call
> that is initiated on unplug, so in the destroy path it's non-essential to do
> this again.

Can't we just leave things be until userspace disables the thing?
If not, then we should know whether hdcp is still enabled. And if
hdcp is enabled so is the encoder, thus we don't need such silly
checks.

-- 
Ville Syrjälä
Intel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[Bug 205815] amdgpu: When playing a wine game, got black screen then screen flickers, game crashes and back to normal

2019-12-09 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=205815

Bernard MAUDRY (ramaspaces...@free.fr) changed:

   What|Removed |Added

Summary|When playing a wine game,   |amdgpu: When playing a wine
   |got black screen then   |game, got black screen then
   |screen flickers, game   |screen flickers, game
   |crashes and back to normal  |crashes and back to normal

-- 
You are receiving this mail because:
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[Bug 205815] When playing a wine game, got black screen then screen flickers, game crashes and back to normal

2019-12-09 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=205815

--- Comment #1 from Bernard MAUDRY (ramaspaces...@free.fr) ---
Created attachment 286237
  --> https://bugzilla.kernel.org/attachment.cgi?id=286237=edit
I also attached amdgpu_firmware_info.

-- 
You are receiving this mail because:
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [Intel-gfx] [PATCH 03/11] drm/i915: Disable HDCP signalling on transcoder disable

2019-12-09 Thread Ville Syrjälä
On Fri, Dec 06, 2019 at 08:55:09AM -0500, Sean Paul wrote:
> On Thu, Dec 05, 2019 at 09:33:19PM +0200, Ville Syrjälä wrote:
> > On Tue, Dec 03, 2019 at 12:36:26PM -0500, Sean Paul wrote:
> > > From: Sean Paul 
> > > 
> > > Currently we rely on intel_hdcp_disable() to disable HDCP signalling in
> > > the DDI Function Control register. This patch adds a safety net by also
> > > clearing the bit when we disable the transcoder.
> > > 
> > > Once we have HDCP over MST and disappearing connectors, we want to make
> > > sure that the signalling is truly disabled even if HDCP teardown doesn't
> > > go as planned.
> > 
> > Why wouldn't it go as planned?
> > 
> 
> Because things can fail in weird and wonderful ways on unplug :-)

Not really.

> 
> It's a safety net. I saw this function and figured HDCP signalling should be
> explicitly cleared here as well.

I call it dead and confusing code. If we get here with HDCP still
enabled we have a more serious bug somewhere else.

-- 
Ville Syrjälä
Intel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[Bug 205815] New: When playing a wine game, got black screen then screen flickers, game crashes and back to normal

2019-12-09 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=205815

Bug ID: 205815
   Summary: When playing a wine game, got black screen then screen
flickers, game crashes and back to normal
   Product: Drivers
   Version: 2.5
Kernel Version: 5.4.2-1~exp1 (Debian experimental)
  Hardware: x86-64
OS: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: Video(DRI - non Intel)
  Assignee: drivers_video-...@kernel-bugs.osdl.org
  Reporter: ramaspaces...@free.fr
Regression: No

Created attachment 286235
  --> https://bugzilla.kernel.org/attachment.cgi?id=286235=edit
System journal

Since I use a Ryzen 5 3400G I have trouble playing the Wine game I use to play.
I have tried several kernels, and seen a lot of progress from 4.19 to 5.4.
But it still fails after a while. I use Debian Buster with the latest Debian
experimental kernel (5.4.2), Xorg and Mesa are from Sid.

I attached the system journal of the last try (and failure).

-- 
You are receiving this mail because:
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v3 2/2] drm/bridge: tc358767: Expose test mode functionality via debugfs

2019-12-09 Thread Tomi Valkeinen

On 09/12/2019 16:38, Andrey Smirnov wrote:

On Mon, Dec 9, 2019 at 1:38 AM Tomi Valkeinen  wrote:


(Cc'ing Daniel for the last paragraph)

On 09/12/2019 07:08, Andrey Smirnov wrote:

Presently, the driver code artificially limits test pattern mode to a
single pattern with fixed color selection. It being a kernel module
parameter makes switching "test pattern" <-> "proper output" modes
on-the-fly clunky and outright impossible if the driver is built into
the kernel.


That's not correct, /sys/module/tc358767/parameters/test is there even if the 
driver is built-in.



True, I'll drop the "impossible" part of the descrption. Having to
unbind and bind device to the driver to use that parameter definitely
falls under "clunky" for me still, so I'll just stick to that in the
description.


You don't need to re-bind. You can change the module parameter at runtime, and if the driver happens 
to use the value, then it uses the new value. If I recall right, changing the module parameter and 
then doing a full modeset from userspace made the driver to use the test mode (I'm not 100% sure, 
though).


In any case, I'm not advocating for the use of module parameter here =)


Hmm, actually, just echoing 0 to tstctl multiple times, it makes the screen go 
black and then
restores it with every other echo.



Strange, works on my setup every time. No error messages in kernel log
I assume? Probably unrelated, but when you echo "0" and the screen


No errors.


stays black, what do you see in DP_SINK_STATUS register:

dd if=/dev/drm_dp_aux0 bs=1 skip=$((0x205)) count=1 2>/dev/null | hexdump -Cv

? Note that this needs CONFIG_DRM_DP_AUX_CHARDEV to be enabled.


I'll check this later, and do a few more tests.


+ debugfs = debugfs_create_dir(dev_name(dev), NULL);
+ if (!IS_ERR(debugfs)) {
+ debugfs_create_file_unsafe("tstctl", 0200, debugfs, tc,
+_tstctl_fops);
+ devm_add_action_or_reset(dev, tc_remove_debugfs, debugfs);
+ }
+


For me this creates debugfs/3-000f/tstctl. I don't think that's a clear or 
usable path, and could
even cause a name conflict in the worst case.



I agree on usability aspect, but I am not sure I can see how a
conflict can happen. What scenario do you have in mind that would
cause that? My thinking was that the combination of I2C bus number +
I2C address should always be unique on the system, but maybe I am
missing something?


Well, the dir name doesn't have "i2c" anywhere, so at least in theory, some other bus could have 
"3-000f" address too.


Maybe bigger problem is that it's not at all obvious what "3-000f" means. All the other debugfs dirs 
make sense when you look at the name, and "3-000f" looks very odd there.


 Tomi

--
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH RESEND 3/4] dt-bindings: drm/bridge: analogix-anx78xx: support bypass GPIO

2019-12-09 Thread Laurent Pinchart
Hi Hsin-Yi,

Thank you for the patch.

On Mon, Dec 09, 2019 at 10:50:15PM +0800, Hsin-Yi Wang wrote:
> Support optional feature: bypass GPIO.
> 
> Some SoC (eg. mt8173) have a hardware mux that connects to 2 ports:
> anx7688 and hdmi. When the GPIO is active, the bridge is bypassed.

This doesn't look like the right place to fix this, as the mux is
unrelated to the bridge. You would have to duplicate this logic in every
bridge driver otherwise.

Could you describe the hardware topology in a bit more details ? I can
then try to advise on how to best support it.

> Signed-off-by: Hsin-Yi Wang 
> ---
>  .../bindings/display/bridge/anx7688.txt   | 40 ++-
>  1 file changed, 39 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/anx7688.txt 
> b/Documentation/devicetree/bindings/display/bridge/anx7688.txt
> index 78b55bdb18f7..44185dcac839 100644
> --- a/Documentation/devicetree/bindings/display/bridge/anx7688.txt
> +++ b/Documentation/devicetree/bindings/display/bridge/anx7688.txt
> @@ -15,10 +15,13 @@ Required properties:
>  Optional properties:
>  
>   - Video port for HDMI input, using the DT bindings defined in [1].
> + - bypass-gpios: External GPIO. If this GPIO is active, we assume
> + the bridge is bypassed (e.g. by a mux).
> + - pinctrl-0, pinctrl-names: the pincontrol settings to configure bypass 
> GPIO.
>  
>  [1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>  
> -Example:
> +Example 1:
>  
>   anx7688: anx7688@2c {
>   compatible = "analogix,anx7688";
> @@ -30,3 +33,38 @@ Example:
>   };
>   };
>   };
> +
> +Example 2:
> +
> +   anx7688: anx7688@2c {
> +   compatible = "analogix,anx7688";
> +   status = "okay";
> +   reg = <0x2c>;
> +   ddc-i2c-bus = <>;
> +
> +   bypass-gpios = < 36 GPIO_ACTIVE_HIGH>;
> +   pinctrl-names = "default";
> +   pinctrl-0 = <_mux_pins>;
> +
> +   ports {
> +   #address-cells = <1>;
> +   #size-cells = <0>;
> +
> +   port@0 { /* input */
> +   reg = <0>;
> +
> +   anx7688_in: endpoint {
> +   remote-endpoint = <_out_anx>;
> +   };
> +   };
> +
> +   port@1 { /* output */
> +   reg = <1>;
> +
> +   anx7688_out: endpoint {
> +   remote-endpoint = 
> <_connector_in>;
> +   };
> +   };
> +   };
> +   };
> +

-- 
Regards,

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

Re: [PATCH RESEND 1/4] dt-bindings: drm/bridge: analogix-anx7688: Add ANX7688 transmitter binding

2019-12-09 Thread Laurent Pinchart
Hi Hsin-Yi,

Thank you for the patch.

On Mon, Dec 09, 2019 at 10:50:13PM +0800, Hsin-Yi Wang wrote:
> From: Nicolas Boichat 
> 
> Add support for analogix,anx7688
> 
> Signed-off-by: Nicolas Boichat 
> Signed-off-by: Hsin-Yi Wang 
> ---
>  .../bindings/display/bridge/anx7688.txt   | 32 +++

How about converting this to yaml bindings already ? It's fairly simple
and gives you DT validation.

>  1 file changed, 32 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/display/bridge/anx7688.txt
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/anx7688.txt 
> b/Documentation/devicetree/bindings/display/bridge/anx7688.txt
> new file mode 100644
> index ..78b55bdb18f7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/bridge/anx7688.txt
> @@ -0,0 +1,32 @@
> +Analogix ANX7688 SlimPort (Single-Chip Transmitter for DP over USB-C)
> +-
> +
> +The ANX7688 is a single-chip mobile transmitter to support 4K 60 frames per
> +second (4096x2160p60) or FHD 120 frames per second (1920x1080p120) video
> +resolution from a smartphone or tablet with full function USB-C.
> +
> +This binding only describes the HDMI to DP display bridge.
> +
> +Required properties:
> +
> + - compatible  : "analogix,anx7688"
> + - reg : I2C address of the device (fixed at 0x2c)
> +
> +Optional properties:
> +
> + - Video port for HDMI input, using the DT bindings defined in [1].
> +
> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
> +
> +Example:
> +
> + anx7688: anx7688@2c {
> + compatible = "analogix,anx7688";
> + reg = <0x2c>;
> +
> + port {
> + anx7688_in: endpoint {
> + remote-endpoint = <_out>;
> + };
> + };
> + };
> -- 
> 2.24.0.393.g34dc348eaf-goog
> 

-- 
Regards,

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

Re: [PATCH v2 2/3] dt-bindings: display: Add obsolete note to "ti,tilcdc,panel" binding

2019-12-09 Thread Laurent Pinchart
Hi Jyri,

Thank you for the patch.

On Mon, Dec 09, 2019 at 04:42:15PM +0200, Jyri Sarha wrote:
> The "ti,tilcdc,panel" binding should not be used anymore, since tilcdc
> is fully capable of using generic drm panels like panel-simple and
> panel-common binding. However, the obsolete binding is still widely
> used in many mainline supported platforms that I do not have access to
> and who knows how many custom platforms. So I am afraid we have to
> keep the old bundled tilcdc panel driver around.

But can't we drop the bindings instead of marking them as obsolete, even
if we keep the driver around for some time ?

Also, would it make sense to set a date for the removal of the driver,
and add it to the WARN() message in patch 3/3 ?

> Signed-off-by: Jyri Sarha 
> ---
>  Documentation/devicetree/bindings/display/tilcdc/panel.txt | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/tilcdc/panel.txt 
> b/Documentation/devicetree/bindings/display/tilcdc/panel.txt
> index 808216310ea2..54963f9173cc 100644
> --- a/Documentation/devicetree/bindings/display/tilcdc/panel.txt
> +++ b/Documentation/devicetree/bindings/display/tilcdc/panel.txt
> @@ -1,5 +1,11 @@
>  Device-Tree bindings for tilcdc DRM generic panel output driver
>  
> +NOTE: This binding (and the related driver) is obsolete and should not
> +  be used anymore. Please refer to drm panel-common binding (and
> +  to a generic drm panel driver like panel-simple).
> +  Documentation/devicetree/bindings/display/panel/panel-common.yaml
> +  (drivers/gpu/drm/panel/panel-simple.c)
> +
>  Required properties:
>   - compatible: value should be "ti,tilcdc,panel".
>   - panel-info: configuration info to configure LCDC correctly for the panel

-- 
Regards,

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

Re: [PATCH v2 3/3] drm/tilcdc: panel: Add WARN() with a comment to tilcdc-panel probe

2019-12-09 Thread Laurent Pinchart
Hi Jyri,

Thank you for the patch.

On Mon, Dec 09, 2019 at 04:42:16PM +0200, Jyri Sarha wrote:
> Add WARN() to the beginnig of tilcdc-panel probe. The obsolete

s/beginnig/beginning/

> tilcdc-panel driver should not be used anymore, since tilcdc is fully
> capable of using generic drm panels like panel-simple and panel-common
> binding.
> 
> Signed-off-by: Jyri Sarha 
> ---
>  drivers/gpu/drm/tilcdc/tilcdc_panel.c | 10 ++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c 
> b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
> index 5584e656b857..cf8e2462a524 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
> @@ -309,6 +309,16 @@ static int panel_probe(struct platform_device *pdev)
>   struct pinctrl *pinctrl;
>   int ret;
>  
> + /*
> +  * The obsolete tilcdc-panel driver should not be used
> + * anymore, since tilcdc is fully capable of using generic drm
> + * panels like panel-simple and panel-common binding.

Indentation should use tabs.

> +  */
> +
> + WARN(true,
> +  "tilcdc-panel is obsolte and should not be used. Please update 
> your configuration!\n",

s/obsolte/obsolete/ or deprecated ?

You may want to explicitly state what it should be updated to :-)

Reviewed-by: Laurent Pinchart 

> +  dev_name(>dev));
> +
>   /* bail out early if no DT data: */
>   if (!node) {
>   dev_err(>dev, "device-tree data is missing\n");

-- 
Regards,

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

[Intel-gfx][PATCH] drm/i915/display: cleanup intel_bw_state on i915 module removal

2019-12-09 Thread Pankaj Bharadiya
intel_bw_state allocated memory is not getting freed even after
module removal.

kmemleak reported backtrace:

[<79019739>] kmemdup+0x17/0x40
[] intel_bw_duplicate_state+0x1b/0x40 [i915]
[<7423ed0c>] drm_atomic_get_private_obj_state+0xca/0x140
[<100e3533>] intel_bw_atomic_check+0x133/0x350 [i915]
[<126d0e0c>] intel_atomic_check+0x1ab7/0x20d0 [i915]
[] drm_atomic_check_only+0x563/0x810
[] drm_atomic_commit+0xe/0x50
[] drm_atomic_helper_disable_all+0x133/0x160
[<3c44760c>] drm_atomic_helper_shutdown+0x65/0xc0
[<414e3e5c>] i915_driver_remove+0xcb/0x130 [i915]
[] i915_pci_remove+0x19/0x40 [i915]
[<2dcbd148>] pci_device_remove+0x36/0xb0
[<3c8c6b0a>] device_release_driver_internal+0xe0/0x1c0
[<580e9566>] unbind_store+0xc3/0x120
[<869d0df5>] kernfs_fop_write+0x104/0x190
[<4dc1a355>] vfs_write+0xb9/0x1d0

Call the drm_atomic_private_obj_fini(), which inturn calls the
intel_bw_destroy_state() to make sure the intel_bw_state memory is
freed properly.

Signed-off-by: Pankaj Bharadiya 
---
 drivers/gpu/drm/i915/display/intel_bw.c  | 5 +
 drivers/gpu/drm/i915/display/intel_bw.h  | 1 +
 drivers/gpu/drm/i915/display/intel_display.c | 2 ++
 3 files changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.c 
b/drivers/gpu/drm/i915/display/intel_bw.c
index dcb66a33be9b..b228671d5a5d 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -486,3 +486,8 @@ int intel_bw_init(struct drm_i915_private *dev_priv)
 
return 0;
 }
+
+void intel_bw_cleanup(struct drm_i915_private *dev_priv)
+{
+   drm_atomic_private_obj_fini(_priv->bw_obj);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_bw.h 
b/drivers/gpu/drm/i915/display/intel_bw.h
index 9db10af012f4..20b9ad241802 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.h
+++ b/drivers/gpu/drm/i915/display/intel_bw.h
@@ -25,6 +25,7 @@ struct intel_bw_state {
 
 void intel_bw_init_hw(struct drm_i915_private *dev_priv);
 int intel_bw_init(struct drm_i915_private *dev_priv);
+void intel_bw_cleanup(struct drm_i915_private *dev_priv);
 int intel_bw_atomic_check(struct intel_atomic_state *state);
 void intel_bw_crtc_update(struct intel_bw_state *bw_state,
  const struct intel_crtc_state *crtc_state);
diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 3190aa27ffdc..756eb90b1bb1 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -17912,6 +17912,8 @@ void intel_modeset_driver_remove(struct 
drm_i915_private *i915)
 
intel_gmbus_teardown(i915);
 
+   intel_bw_cleanup(i915);
+
destroy_workqueue(i915->flip_wq);
destroy_workqueue(i915->modeset_wq);
 
-- 
2.23.0

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

[PATCH v2 2/3] dt-bindings: display: Add obsolete note to "ti, tilcdc, panel" binding

2019-12-09 Thread Jyri Sarha
The "ti,tilcdc,panel" binding should not be used anymore, since tilcdc
is fully capable of using generic drm panels like panel-simple and
panel-common binding. However, the obsolete binding is still widely
used in many mainline supported platforms that I do not have access to
and who knows how many custom platforms. So I am afraid we have to
keep the old bundled tilcdc panel driver around.

Signed-off-by: Jyri Sarha 
---
 Documentation/devicetree/bindings/display/tilcdc/panel.txt | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/tilcdc/panel.txt 
b/Documentation/devicetree/bindings/display/tilcdc/panel.txt
index 808216310ea2..54963f9173cc 100644
--- a/Documentation/devicetree/bindings/display/tilcdc/panel.txt
+++ b/Documentation/devicetree/bindings/display/tilcdc/panel.txt
@@ -1,5 +1,11 @@
 Device-Tree bindings for tilcdc DRM generic panel output driver
 
+NOTE: This binding (and the related driver) is obsolete and should not
+  be used anymore. Please refer to drm panel-common binding (and
+  to a generic drm panel driver like panel-simple).
+  Documentation/devicetree/bindings/display/panel/panel-common.yaml
+  (drivers/gpu/drm/panel/panel-simple.c)
+
 Required properties:
  - compatible: value should be "ti,tilcdc,panel".
  - panel-info: configuration info to configure LCDC correctly for the panel
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

[PATCH 1/3] dt-bindings: Add vendor prefix for Xinpeng Technology

2019-12-09 Thread Heiko Stuebner
From: Heiko Stuebner 

Shenzhen Xinpeng Technology Co., Ltd produces for example display panels.

Signed-off-by: Heiko Stuebner 
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml 
b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 6046f4555852..85e7c26a05c7 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1056,6 +1056,8 @@ patternProperties:
 description: Extreme Engineering Solutions (X-ES)
   "^xillybus,.*":
 description: Xillybus Ltd.
+  "^xinpeng,.*":
+description: Shenzhen Xinpeng Technology Co., Ltd
   "^xlnx,.*":
 description: Xilinx
   "^xunlong,.*":
-- 
2.24.0

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

[PATCH 3/3] drm/panel: add panel driver for Xinpeng XPP055C272 panels

2019-12-09 Thread Heiko Stuebner
From: Heiko Stuebner 

Base on the somewhat similar Rocktech driver but adapted for
panel-specific init of the XPP055C272.

Signed-off-by: Heiko Stuebner 
---
 drivers/gpu/drm/panel/Kconfig |  10 +
 drivers/gpu/drm/panel/Makefile|   1 +
 .../gpu/drm/panel/panel-xinpeng-xpp055c272.c  | 433 ++
 3 files changed, 444 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index f152bc4eeb53..fb1ded47677e 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -355,4 +355,14 @@ config DRM_PANEL_TRULY_NT35597_WQXGA
help
  Say Y here if you want to enable support for Truly NT35597 WQXGA Dual 
DSI
  Video Mode panel
+
+config DRM_PANEL_XINPENG_XPP055C272
+   tristate "Xinpeng XPP055C272 panel driver"
+   depends on OF
+   depends on DRM_MIPI_DSI
+   depends on BACKLIGHT_CLASS_DEVICE
+   help
+ Say Y here if you want to enable support for the Xinpeng
+ XPP055C272 controller for 720x1280 LCD panels with MIPI/RGB/SPI
+ system interfaces.
 endmenu
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index b6cd39fe0f20..71d7722146a7 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -38,3 +38,4 @@ obj-$(CONFIG_DRM_PANEL_TPO_TD028TTEC1) += 
panel-tpo-td028ttec1.o
 obj-$(CONFIG_DRM_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
 obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o
 obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o
+obj-$(CONFIG_DRM_PANEL_XINPENG_XPP055C272) += panel-xinpeng-xpp055c272.o
diff --git a/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c 
b/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c
new file mode 100644
index ..9c5fbf1879c3
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c
@@ -0,0 +1,433 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xinpeng xpp055c272 5.5" MIPI-DSI panel driver
+ * Copyright (C) 2019 Theobroma Systems Design und Consulting GmbH
+ *
+ * based on
+ *
+ * Rockteck jh057n00900 5.5" MIPI-DSI panel driver
+ * Copyright (C) Purism SPC 2019
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DRV_NAME "panel-xinpeng-xpp055c272"
+
+/* Manufacturer specific Commands send via DSI */
+#define XPP055C272_CMD_ALL_PIXEL_OFF   0x22
+#define XPP055C272_CMD_ALL_PIXEL_ON0x23
+#define XPP055C272_CMD_SETDISP 0xb2
+#define XPP055C272_CMD_SETRGBIF0xb3
+#define XPP055C272_CMD_SETCYC  0xb4
+#define XPP055C272_CMD_SETBGP  0xb5
+#define XPP055C272_CMD_SETVCOM 0xb6
+#define XPP055C272_CMD_SETOTP  0xb7
+#define XPP055C272_CMD_SETPOWER_EXT0xb8
+#define XPP055C272_CMD_SETEXTC 0xb9
+#define XPP055C272_CMD_SETMIPI 0xbA
+#define XPP055C272_CMD_SETVDC  0xbc
+#define XPP055C272_CMD_SETPCR  0xbf
+#define XPP055C272_CMD_SETSCR  0xc0
+#define XPP055C272_CMD_SETPOWER0xc1
+#define XPP055C272_CMD_SETECO  0xc6
+#define XPP055C272_CMD_SETPANEL0xcc
+#define XPP055C272_CMD_SETGAMMA0xe0
+#define XPP055C272_CMD_SETEQ   0xe3
+#define XPP055C272_CMD_SETGIP1 0xe9
+#define XPP055C272_CMD_SETGIP2 0xea
+
+struct xpp055c272 {
+   struct device *dev;
+   struct drm_panel panel;
+   struct gpio_desc *reset_gpio;
+   struct backlight_device *backlight;
+   struct regulator *vci;
+   struct regulator *iovcc;
+   bool prepared;
+   bool enabled;
+};
+
+static inline struct xpp055c272 *panel_to_xpp055c272(struct drm_panel *panel)
+{
+   return container_of(panel, struct xpp055c272, panel);
+}
+
+#define dsi_generic_write_seq(dsi, cmd, seq...) do {   \
+   static const u8 d[] = { seq };  \
+   int ret;\
+   ret = mipi_dsi_dcs_write(dsi, cmd, d, ARRAY_SIZE(d));   \
+   if (ret < 0)\
+   return ret; \
+   } while (0)
+
+static int xpp055c272_init_sequence(struct xpp055c272 *ctx)
+{
+   struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+   struct device *dev = ctx->dev;
+   int ret;
+
+   /*
+* Init sequence was supplied by the panel vendor without much
+* documentation.
+*/
+   dsi_generic_write_seq(dsi, XPP055C272_CMD_SETEXTC, 0xf1, 0x12, 0x83);
+   dsi_generic_write_seq(dsi, XPP055C272_CMD_SETMIPI,
+ 0x33, 0x81, 0x05, 0xf9, 0x0e, 0x0e, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 

[PATCH v2 3/3] drm/tilcdc: panel: Add WARN() with a comment to tilcdc-panel probe

2019-12-09 Thread Jyri Sarha
Add WARN() to the beginnig of tilcdc-panel probe. The obsolete
tilcdc-panel driver should not be used anymore, since tilcdc is fully
capable of using generic drm panels like panel-simple and panel-common
binding.

Signed-off-by: Jyri Sarha 
---
 drivers/gpu/drm/tilcdc/tilcdc_panel.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c 
b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
index 5584e656b857..cf8e2462a524 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
@@ -309,6 +309,16 @@ static int panel_probe(struct platform_device *pdev)
struct pinctrl *pinctrl;
int ret;
 
+   /*
+* The obsolete tilcdc-panel driver should not be used
+ * anymore, since tilcdc is fully capable of using generic drm
+ * panels like panel-simple and panel-common binding.
+*/
+
+   WARN(true,
+"tilcdc-panel is obsolte and should not be used. Please update 
your configuration!\n",
+dev_name(>dev));
+
/* bail out early if no DT data: */
if (!node) {
dev_err(>dev, "device-tree data is missing\n");
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

[PATCH v2 1/3] drm/tilcdc: Remove obsolete bundled tilcdc tfp410 driver

2019-12-09 Thread Jyri Sarha
Remove obsolete bundled tfp410 driver with its "ti,tilcdc,tfp410"
devicetree binding. No platform has ever used this driver in the
mainline kernel and if anybody connects tfp410 to tilcdc he or she
should use the generic drm tfp410 bridge driver.

Signed-off-by: Jyri Sarha 
Reviewed-by: Laurent Pinchart 
---
 .../bindings/display/tilcdc/tfp410.txt|  21 -
 drivers/gpu/drm/tilcdc/Makefile   |   1 -
 drivers/gpu/drm/tilcdc/tilcdc_drv.c   |   3 -
 drivers/gpu/drm/tilcdc/tilcdc_tfp410.c| 379 --
 drivers/gpu/drm/tilcdc/tilcdc_tfp410.h|  15 -
 5 files changed, 419 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/display/tilcdc/tfp410.txt
 delete mode 100644 drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
 delete mode 100644 drivers/gpu/drm/tilcdc/tilcdc_tfp410.h

diff --git a/Documentation/devicetree/bindings/display/tilcdc/tfp410.txt 
b/Documentation/devicetree/bindings/display/tilcdc/tfp410.txt
deleted file mode 100644
index a58ae7756fc6..
--- a/Documentation/devicetree/bindings/display/tilcdc/tfp410.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-Device-Tree bindings for tilcdc DRM TFP410 output driver
-
-Required properties:
- - compatible: value should be "ti,tilcdc,tfp410".
- - i2c: the phandle for the i2c device to use for DDC
-
-Recommended properties:
- - pinctrl-names, pinctrl-0: the pincontrol settings to configure
-   muxing properly for pins that connect to TFP410 device
- - powerdn-gpio: the powerdown GPIO, pulled low to power down the
-   TFP410 device (for DPMS_OFF)
-
-Example:
-
-   dvicape {
-   compatible = "ti,tilcdc,tfp410";
-   i2c = <>;
-   pinctrl-names = "default";
-   pinctrl-0 = <_dvi_cape_dvi_00A1_pins>;
-   powerdn-gpio = < 31 0>;
-   };
diff --git a/drivers/gpu/drm/tilcdc/Makefile b/drivers/gpu/drm/tilcdc/Makefile
index 87f9480e43b0..662bf3a348c9 100644
--- a/drivers/gpu/drm/tilcdc/Makefile
+++ b/drivers/gpu/drm/tilcdc/Makefile
@@ -6,7 +6,6 @@ endif
 tilcdc-y := \
tilcdc_plane.o \
tilcdc_crtc.o \
-   tilcdc_tfp410.o \
tilcdc_panel.o \
tilcdc_external.o \
tilcdc_drv.o
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c 
b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 2a9e67597375..20745db863ff 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -30,7 +30,6 @@
 #include "tilcdc_external.h"
 #include "tilcdc_panel.h"
 #include "tilcdc_regs.h"
-#include "tilcdc_tfp410.h"
 
 static LIST_HEAD(module_list);
 
@@ -649,7 +648,6 @@ static struct platform_driver tilcdc_platform_driver = {
 static int __init tilcdc_drm_init(void)
 {
DBG("init");
-   tilcdc_tfp410_init();
tilcdc_panel_init();
return platform_driver_register(_platform_driver);
 }
@@ -659,7 +657,6 @@ static void __exit tilcdc_drm_fini(void)
DBG("fini");
platform_driver_unregister(_platform_driver);
tilcdc_panel_fini();
-   tilcdc_tfp410_fini();
 }
 
 module_init(tilcdc_drm_init);
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c 
b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
deleted file mode 100644
index 530edb3b51cc..
--- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
+++ /dev/null
@@ -1,379 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2012 Texas Instruments
- * Author: Rob Clark 
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-
-#include "tilcdc_drv.h"
-#include "tilcdc_tfp410.h"
-
-struct tfp410_module {
-   struct tilcdc_module base;
-   struct i2c_adapter *i2c;
-   int gpio;
-};
-#define to_tfp410_module(x) container_of(x, struct tfp410_module, base)
-
-
-static const struct tilcdc_panel_info dvi_info = {
-   .ac_bias= 255,
-   .ac_bias_intrpt = 0,
-   .dma_burst_sz   = 16,
-   .bpp= 16,
-   .fdd= 0x80,
-   .tft_alt_mode   = 0,
-   .sync_edge  = 0,
-   .sync_ctrl  = 1,
-   .raster_order   = 0,
-};
-
-/*
- * Encoder:
- */
-
-struct tfp410_encoder {
-   struct drm_encoder base;
-   struct tfp410_module *mod;
-   int dpms;
-};
-#define to_tfp410_encoder(x) container_of(x, struct tfp410_encoder, base)
-
-static void tfp410_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
-   struct tfp410_encoder *tfp410_encoder = to_tfp410_encoder(encoder);
-
-   if (tfp410_encoder->dpms == mode)
-   return;
-
-   if (mode == DRM_MODE_DPMS_ON) {
-   DBG("Power on");
-   gpio_direction_output(tfp410_encoder->mod->gpio, 1);
-   } else {
-   DBG("Power off");
-   gpio_direction_output(tfp410_encoder->mod->gpio, 0);
-   }
-
-   tfp410_encoder->dpms = mode;
-}
-

[PATCH v2 0/3] drm/tilcdc: Remove "ti, tilcdc, tfp410" and mark "ti, tilcdc, panel" obsolete

2019-12-09 Thread Jyri Sarha
Since v1:
- Add Reviewed-by: Laurent Pinchart 
  to "drm/tilcdc: Remove obsolete bundled tilcdc tfp410 driver"
- Add "drm/tilcdc: panel: Add WARN() with a comment to tilcdc-panel probe"

Nobody should any more use the old tilcdc bundled drivers anymore. The
driver is fully capable of using the generic drm bridge and panel
drivers.  However, the obsolete "ti,tilcdc,panel" binding is still
widely used in many mainline supported platforms that I do not have
access to and who knows how many custom platforms. So I am afraid we
have to keep the old bundled tilcdc panel driver around.

I'll wait with merging the "ti,tilcdc,panel" patches until these
patches have been merged:
https://lists.freedesktop.org/archives/dri-devel/2019-December/247301.html
https://lists.freedesktop.org/archives/dri-devel/2019-December/247594.html
So I can refer to them as an example in the comments. 

But I'll merge "drm/tilcdc: Remove obsolete bundled tilcdc tfp410
driver" trough drm-misc in couple days if I do not hear any
objections.

Jyri Sarha (3):
  drm/tilcdc: Remove obsolete bundled tilcdc tfp410 driver
  dt-bindings: display: Add obsolete note to "ti,tilcdc,panel" binding
  drm/tilcdc: panel: Add WARN() with a comment to tilcdc-panel probe

 .../bindings/display/tilcdc/panel.txt |   6 +
 .../bindings/display/tilcdc/tfp410.txt|  21 -
 drivers/gpu/drm/tilcdc/Makefile   |   1 -
 drivers/gpu/drm/tilcdc/tilcdc_drv.c   |   3 -
 drivers/gpu/drm/tilcdc/tilcdc_panel.c |  10 +
 drivers/gpu/drm/tilcdc/tilcdc_tfp410.c| 379 --
 drivers/gpu/drm/tilcdc/tilcdc_tfp410.h|  15 -
 7 files changed, 16 insertions(+), 419 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/display/tilcdc/tfp410.txt
 delete mode 100644 drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
 delete mode 100644 drivers/gpu/drm/tilcdc/tilcdc_tfp410.h

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

[PATCH 2/3] dt-bindings: display: panel: Add binding document for Xinpeng XPP055C272

2019-12-09 Thread Heiko Stuebner
From: Heiko Stuebner 

The XPP055C272 is a 5.5" 720x1280 DSI display.

Signed-off-by: Heiko Stuebner 
---
 .../display/panel/xinpeng,xpp055c272.yaml | 45 +++
 1 file changed, 45 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/xinpeng,xpp055c272.yaml

diff --git 
a/Documentation/devicetree/bindings/display/panel/xinpeng,xpp055c272.yaml 
b/Documentation/devicetree/bindings/display/panel/xinpeng,xpp055c272.yaml
new file mode 100644
index ..4515d44d189b
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/xinpeng,xpp055c272.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/sony,acx424akp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Xinpeng XPP055C272 720x1280 DSI panel
+
+maintainers:
+  - Heiko Stuebner 
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+const: xinpeng,xpp055c272
+  reg: true
+  backlight: true
+  port: true
+  reset-gpios: true
+  iovcc-supply:
+ description: regulator that supplies the iovcc voltage
+  vci-supply:
+ description: regulator that supplies the vci voltage
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+dsi@ff45 {
+panel@0 {
+compatible = "xinpeng,xpp055c272";
+reg = <0>;
+backlight = <>;
+iovcc-supply = <_1v8>;
+vci-supply = <_lcd>;
+};
+};
+
+...
-- 
2.24.0

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

Re: [PATCH v2 4/9] drm/udl: Inline DPMS code into CRTC enable and disable functions

2019-12-09 Thread Emil Velikov
On Fri, 6 Dec 2019 at 12:47, Thomas Zimmermann  wrote:
>
> DPMS functionality is only used by the CRTC's enable and disable
> functions. Inline the code.
>
> Signed-off-by: Thomas Zimmermann 
> ---
>  drivers/gpu/drm/udl/udl_modeset.c | 84 +++
>  1 file changed, 30 insertions(+), 54 deletions(-)
>
> diff --git a/drivers/gpu/drm/udl/udl_modeset.c 
> b/drivers/gpu/drm/udl/udl_modeset.c
> index 72884cbda131..4681446c2323 100644
> --- a/drivers/gpu/drm/udl/udl_modeset.c
> +++ b/drivers/gpu/drm/udl/udl_modeset.c
> @@ -48,25 +48,9 @@ static char *udl_vidreg_unlock(char *buf)
>   *  0x01 H and V sync off (screen blank but powered)
>   *  0x07 DPMS powerdown (requires modeset to come back)
>   */
> -static char *udl_set_blank(char *buf, int dpms_mode)
> +static char *udl_set_blank_mode(char *buf, u8 mode)
>  {
> -   u8 reg;
> -   switch (dpms_mode) {
> -   case DRM_MODE_DPMS_OFF:
> -   reg = 0x07;
> -   break;
> -   case DRM_MODE_DPMS_STANDBY:
> -   reg = 0x05;
> -   break;
> -   case DRM_MODE_DPMS_SUSPEND:
> -   reg = 0x01;
> -   break;
> -   case DRM_MODE_DPMS_ON:
> -   reg = 0x00;
> -   break;
> -   }
> -
As a follow-up, please add/use symbolic names for the the four states.
Apart from the cosmetic aspect, this allows us to trivially change
from DPMS_OFF to DPMS_SUSPEND or DPMS_STANDBY at any random point.

As-is the series is:
Reviewed-by: Emil Velikov 

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

[PATCH v5 2/6] drm/bridge/synopsys: dsi: move phy_ops callbacks around panel enablement

2019-12-09 Thread Heiko Stuebner
From: Heiko Stuebner 

If implementation-specific phy_ops need to be defined they probably
should be enabled before trying to talk to the panel and disabled only
after the panel was disabled.

Right now they are enabled last and disabled first, so might make it
impossible to talk to some panels - example for this being the px30
with an external Innosilicon dphy that needs the phy to be enabled
to transfer commands to the panel.

So move the calls appropriately.

changed in v5:
- rebased on top of 5.5-rc1
- merged with dsi timing change to prevent ordering conflicts

Signed-off-by: Heiko Stuebner 
Reviewed-by: Neil Armstrong 
Tested-by: Yannick Fertre 
Reviewed-by: Philippe Cornu 
---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index bfe0061e54a2..b18351b6760a 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -810,9 +810,6 @@ static void dw_mipi_dsi_bridge_post_disable(struct 
drm_bridge *bridge)
struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
 
-   if (phy_ops->power_off)
-   phy_ops->power_off(dsi->plat_data->priv_data);
-
/*
 * Switch to command mode before panel-bridge post_disable &
 * panel unprepare.
@@ -829,6 +826,9 @@ static void dw_mipi_dsi_bridge_post_disable(struct 
drm_bridge *bridge)
 */
dsi->panel_bridge->funcs->post_disable(dsi->panel_bridge);
 
+   if (phy_ops->power_off)
+   phy_ops->power_off(dsi->plat_data->priv_data);
+
if (dsi->slave) {
dw_mipi_dsi_disable(dsi->slave);
clk_disable_unprepare(dsi->slave->pclk);
@@ -895,6 +895,9 @@ static void dw_mipi_dsi_mode_set(struct dw_mipi_dsi *dsi,
 
/* Switch to cmd mode for panel-bridge pre_enable & panel prepare */
dw_mipi_dsi_set_mode(dsi, 0);
+
+   if (phy_ops->power_on)
+   phy_ops->power_on(dsi->plat_data->priv_data);
 }
 
 static void dw_mipi_dsi_bridge_mode_set(struct drm_bridge *bridge,
@@ -911,15 +914,11 @@ static void dw_mipi_dsi_bridge_mode_set(struct drm_bridge 
*bridge,
 static void dw_mipi_dsi_bridge_enable(struct drm_bridge *bridge)
 {
struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
-   const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
 
/* Switch to video mode for panel-bridge enable & panel enable */
dw_mipi_dsi_set_mode(dsi, MIPI_DSI_MODE_VIDEO);
if (dsi->slave)
dw_mipi_dsi_set_mode(dsi->slave, MIPI_DSI_MODE_VIDEO);
-
-   if (phy_ops->power_on)
-   phy_ops->power_on(dsi->plat_data->priv_data);
 }
 
 static enum drm_mode_status
-- 
2.24.0

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

[PATCH v5 1/6] drm/bridge/synopsys: dsi: driver-specific configuration of phy timings

2019-12-09 Thread Heiko Stuebner
From: Heiko Stuebner 

The timing values for dw-dsi are often dependent on the used display and
according to Philippe Cornu will most likely also depend on the used phy
technology in the soc-specific implementation.

To solve this and allow specific implementations to define them as needed
add a new get_timing callback to phy_ops and call this from the dphy_timing
function to retrieve the necessary values for the specific mode.

Right now this handles the hs2lp + lp2hs where Rockchip SoCs need handling
according to the phy speed, while STM seems to be ok with static values.

changes in v5:
- rebase on 5.5-rc1
- merge into px30 dsi series to prevent ordering conflicts

changes in v4:
- rebase to make it directly fit on top of drm-misc-next after all

changes in v3:
- check existence of phy_ops->get_timing in __dw_mipi_dsi_probe()
- emit actual error when get_timing() call fails
- add tags from Philippe and Yannick

changes in v2:
- add driver-specific handling, don't force all bridge users to use
  the same timings, as suggested by Philippe

Suggested-by: Philippe Cornu 
Signed-off-by: Heiko Stuebner 
Reviewed-by: Philippe Cornu 
Tested-by: Yannick Fertre 
---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 27 +--
 drivers/gpu/drm/rockchip/Kconfig  |  1 +
 .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   | 78 +++
 drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 13 
 include/drm/bridge/dw_mipi_dsi.h  |  9 +++
 5 files changed, 121 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index b6e793bb653c..bfe0061e54a2 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -719,7 +719,15 @@ static void dw_mipi_dsi_vertical_timing_config(struct 
dw_mipi_dsi *dsi,
 
 static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi)
 {
+   const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
+   struct dw_mipi_dsi_dphy_timing timing;
u32 hw_version;
+   int ret;
+
+   ret = phy_ops->get_timing(dsi->plat_data->priv_data,
+ dsi->lane_mbps, );
+   if (ret)
+   DRM_DEV_ERROR(dsi->dev, "Retrieving phy timings failed\n");
 
/*
 * TODO dw drv improvements
@@ -732,16 +740,20 @@ static void dw_mipi_dsi_dphy_timing_config(struct 
dw_mipi_dsi *dsi)
hw_version = dsi_read(dsi, DSI_VERSION) & VERSION;
 
if (hw_version >= HWVER_131) {
-   dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME_V131(0x40) |
- PHY_LP2HS_TIME_V131(0x40));
+   dsi_write(dsi, DSI_PHY_TMR_CFG,
+ PHY_HS2LP_TIME_V131(timing.data_hs2lp) |
+ PHY_LP2HS_TIME_V131(timing.data_lp2hs));
dsi_write(dsi, DSI_PHY_TMR_RD_CFG, MAX_RD_TIME_V131(1));
} else {
-   dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME(0x40) |
- PHY_LP2HS_TIME(0x40) | MAX_RD_TIME(1));
+   dsi_write(dsi, DSI_PHY_TMR_CFG,
+ PHY_HS2LP_TIME(timing.data_hs2lp) |
+ PHY_LP2HS_TIME(timing.data_lp2hs) |
+ MAX_RD_TIME(1));
}
 
-   dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG, PHY_CLKHS2LP_TIME(0x40)
- | PHY_CLKLP2HS_TIME(0x40));
+   dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG,
+ PHY_CLKHS2LP_TIME(timing.clk_hs2lp) |
+ PHY_CLKLP2HS_TIME(timing.clk_lp2hs));
 }
 
 static void dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi *dsi)
@@ -991,7 +1003,8 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
dsi->dev = dev;
dsi->plat_data = plat_data;
 
-   if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps) {
+   if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps ||
+   !plat_data->phy_ops->get_timing) {
DRM_ERROR("Phy not properly configured\n");
return ERR_PTR(-ENODEV);
}
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 6f4222f8beeb..4b7a276994ce 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -46,6 +46,7 @@ config ROCKCHIP_DW_HDMI
 
 config ROCKCHIP_DW_MIPI_DSI
bool "Rockchip specific extensions for Synopsys DW MIPI DSI"
+   select GENERIC_PHY_MIPI_DPHY
help
  This selects support for Rockchip SoC specific extensions
  for the Synopsys DesignWare HDMI driver. If you want to
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index bc073ec5c183..9406effe8077 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -559,9 +559,87 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const 

[PATCH v5 6/6] drm/rockchip: dsi: add px30 support

2019-12-09 Thread Heiko Stuebner
From: Heiko Stuebner 

Add the compatible and GRF definitions for the PX30 soc.

changes in v5:
- rebased on top of 5.5-rc1
- merged with dsi timing change to prevent ordering conflicts

Signed-off-by: Heiko Stuebner 
---
 .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index f16bd1e9b633..f04b5064974d 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -140,6 +140,12 @@
 #define DW_MIPI_NEEDS_PHY_CFG_CLK  BIT(0)
 #define DW_MIPI_NEEDS_GRF_CLK  BIT(1)
 
+#define PX30_GRF_PD_VO_CON10x0438
+#define PX30_DSI_FORCETXSTOPMODE   (0xf << 7)
+#define PX30_DSI_FORCERXMODE   BIT(6)
+#define PX30_DSI_TURNDISABLE   BIT(5)
+#define PX30_DSI_LCDC_SEL  BIT(0)
+
 #define RK3288_GRF_SOC_CON60x025c
 #define RK3288_DSI0_LCDC_SEL   BIT(6)
 #define RK3288_DSI1_LCDC_SEL   BIT(9)
@@ -1127,6 +1133,24 @@ static int dw_mipi_dsi_rockchip_remove(struct 
platform_device *pdev)
return 0;
 }
 
+static const struct rockchip_dw_dsi_chip_data px30_chip_data[] = {
+   {
+   .reg = 0xff45,
+   .lcdsel_grf_reg = PX30_GRF_PD_VO_CON1,
+   .lcdsel_big = HIWORD_UPDATE(0, PX30_DSI_LCDC_SEL),
+   .lcdsel_lit = HIWORD_UPDATE(PX30_DSI_LCDC_SEL,
+   PX30_DSI_LCDC_SEL),
+
+   .lanecfg1_grf_reg = PX30_GRF_PD_VO_CON1,
+   .lanecfg1 = HIWORD_UPDATE(0, PX30_DSI_TURNDISABLE |
+PX30_DSI_FORCERXMODE |
+PX30_DSI_FORCETXSTOPMODE),
+
+   .max_data_lanes = 4,
+   },
+   { /* sentinel */ }
+};
+
 static const struct rockchip_dw_dsi_chip_data rk3288_chip_data[] = {
{
.reg = 0xff96,
@@ -1195,6 +1219,9 @@ static const struct rockchip_dw_dsi_chip_data 
rk3399_chip_data[] = {
 
 static const struct of_device_id dw_mipi_dsi_rockchip_dt_ids[] = {
{
+.compatible = "rockchip,px30-mipi-dsi",
+.data = _chip_data,
+   }, {
 .compatible = "rockchip,rk3288-mipi-dsi",
 .data = _chip_data,
}, {
-- 
2.24.0

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

[PATCH v5 0/6] drm/rockchip: px30 dsi support

2019-12-09 Thread Heiko Stuebner
From: Heiko Stuebner 

This series addes support for the px30 Rockchip soc to the dsi driver.
This includes support for external dsi-phys like used on the px30.

What happened between v1 and v5? The then separate dsi hs2lp timing
patch happened ;-) . As both it and this series touch similar areas
in the dsi driver ordering becomes an issue and so combining them to
make ordering explicit is helpful. v2-v4 where then iterations of the
timing patch.

So this v5 is mainly rebased on 5.5-rc1 and rechecked against drm-misc.

Heiko Stuebner (6):
  drm/bridge/synopsys: dsi: driver-specific configuration of phy timings
  drm/bridge/synopsys: dsi: move phy_ops callbacks around panel
enablement
  dt-bindings: display: rockchip-dsi: document external phys
  drm/rockchip: add ability to handle external dphys in mipi-dsi
  dt-bindings: display: rockchip-dsi: add px30 compatible
  drm/rockchip: dsi: add px30 support

 .../display/rockchip/dw_mipi_dsi_rockchip.txt |  13 +-
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c |  40 ++--
 drivers/gpu/drm/rockchip/Kconfig  |   1 +
 .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   | 173 +-
 drivers/gpu/drm/stm/dw_mipi_dsi-stm.c |  13 ++
 include/drm/bridge/dw_mipi_dsi.h  |   9 +
 6 files changed, 227 insertions(+), 22 deletions(-)

-- 
2.24.0

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

[PATCH v5 3/6] dt-bindings: display: rockchip-dsi: document external phys

2019-12-09 Thread Heiko Stuebner
From: Heiko Stuebner 

Some dw-mipi-dsi instances in Rockchip SoCs use external dphys.
In these cases the needs clock will also be generated externally
so these don't need the ref-clock as well.

changes in v5:
- rebased on top of 5.5-rc1
- merged with dsi timing change to prevent ordering conflicts

Signed-off-by: Heiko Stuebner 
Reviewed-by: Rob Herring 
---
 .../bindings/display/rockchip/dw_mipi_dsi_rockchip.txt | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
index ce4c1fc9116c..1ba9237d0ac0 100644
--- 
a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
+++ 
b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
@@ -9,8 +9,9 @@ Required properties:
 - reg: Represent the physical address range of the controller.
 - interrupts: Represent the controller's interrupt to the CPU(s).
 - clocks, clock-names: Phandles to the controller's pll reference
-  clock(ref) and APB clock(pclk). For RK3399, a phy config clock
-  (phy_cfg) and a grf clock(grf) are required. As described in [1].
+  clock(ref) when using an internal dphy and APB clock(pclk).
+  For RK3399, a phy config clock (phy_cfg) and a grf clock(grf)
+  are required. As described in [1].
 - rockchip,grf: this soc should set GRF regs to mux vopl/vopb.
 - ports: contain a port node with endpoint definitions as defined in [2].
   For vopb,set the reg = <0> and set the reg = <1> for vopl.
@@ -18,6 +19,8 @@ Required properties:
 - video port 1 for either a panel or subsequent encoder
 
 Optional properties:
+- phys: from general PHY binding: the phandle for the PHY device.
+- phy-names: Should be "dphy" if phys references an external phy.
 - power-domains: a phandle to mipi dsi power domain node.
 - resets: list of phandle + reset specifier pairs, as described in [3].
 - reset-names: string reset name, must be "apb".
-- 
2.24.0

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

[PATCH v5 4/6] drm/rockchip: add ability to handle external dphys in mipi-dsi

2019-12-09 Thread Heiko Stuebner
From: Heiko Stuebner 

While the common case is that the dsi controller uses an internal dphy,
accessed through the phy registers inside the dsi controller, there is
also the possibility to use a separate dphy from a different vendor.

One such case is the Rockchip px30 that uses a Innosilicon Mipi dphy,
so add the support for handling such a constellation, including the pll
also getting generated inside that external phy.

changes in v5:
- rebased on top of 5.5-rc1
- merged with dsi timing change to prevent ordering conflicts

Signed-off-by: Heiko Stuebner 
---
 .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   | 68 +--
 1 file changed, 64 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index 9406effe8077..f16bd1e9b633 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -223,6 +224,10 @@ struct dw_mipi_dsi_rockchip {
bool is_slave;
struct dw_mipi_dsi_rockchip *slave;
 
+   /* optional external dphy */
+   struct phy *phy;
+   union phy_configure_opts phy_opts;
+
unsigned int lane_mbps; /* per lane */
u16 input_div;
u16 feedback_div;
@@ -359,6 +364,9 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
struct dw_mipi_dsi_rockchip *dsi = priv_data;
int ret, i, vco;
 
+   if (dsi->phy)
+   return 0;
+
/*
 * Get vco from frequency(lane_mbps)
 * vco  frequency table
@@ -467,6 +475,28 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
return ret;
 }
 
+static void dw_mipi_dsi_phy_power_on(void *priv_data)
+{
+   struct dw_mipi_dsi_rockchip *dsi = priv_data;
+   int ret;
+
+   ret = phy_set_mode(dsi->phy, PHY_MODE_MIPI_DPHY);
+   if (ret) {
+   DRM_DEV_ERROR(dsi->dev, "failed to set phy mode: %d\n", ret);
+   return;
+   }
+
+   phy_configure(dsi->phy, >phy_opts);
+   phy_power_on(dsi->phy);
+}
+
+static void dw_mipi_dsi_phy_power_off(void *priv_data)
+{
+   struct dw_mipi_dsi_rockchip *dsi = priv_data;
+
+   phy_power_off(dsi->phy);
+}
+
 static int
 dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
  unsigned long mode_flags, u32 lanes, u32 format,
@@ -504,6 +534,17 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct 
drm_display_mode *mode,
  "DPHY clock frequency is out of range\n");
}
 
+   /* for external phy only a the mipi_dphy_config is necessary */
+   if (dsi->phy) {
+   phy_mipi_dphy_get_default_config(mode->clock * 1000 * 10 / 8,
+bpp, lanes,
+>phy_opts.mipi_dphy);
+   dsi->lane_mbps = target_mbps;
+   *lane_mbps = dsi->lane_mbps;
+
+   return 0;
+   }
+
fin = clk_get_rate(dsi->pllref_clk);
fout = target_mbps * USEC_PER_SEC;
 
@@ -638,6 +679,8 @@ dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int 
lane_mbps,
 
 static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_rockchip_phy_ops = {
.init = dw_mipi_dsi_phy_init,
+   .power_on = dw_mipi_dsi_phy_power_on,
+   .power_off = dw_mipi_dsi_phy_power_off,
.get_lane_mbps = dw_mipi_dsi_get_lane_mbps,
.get_timing = dw_mipi_dsi_phy_get_timing,
 };
@@ -998,12 +1041,29 @@ static int dw_mipi_dsi_rockchip_probe(struct 
platform_device *pdev)
return -EINVAL;
}
 
+   /* try to get a possible external dphy */
+   dsi->phy = devm_phy_optional_get(dev, "dphy");
+   if (IS_ERR(dsi->phy)) {
+   ret = PTR_ERR(dsi->phy);
+   DRM_DEV_ERROR(dev, "failed to get mipi dphy: %d\n", ret);
+   return ret;
+   }
+
dsi->pllref_clk = devm_clk_get(dev, "ref");
if (IS_ERR(dsi->pllref_clk)) {
-   ret = PTR_ERR(dsi->pllref_clk);
-   DRM_DEV_ERROR(dev,
- "Unable to get pll reference clock: %d\n", ret);
-   return ret;
+   if (dsi->phy) {
+   /*
+* if external phy is present, pll will be
+* generated there.
+*/
+   dsi->pllref_clk = NULL;
+   } else {
+   ret = PTR_ERR(dsi->pllref_clk);
+   DRM_DEV_ERROR(dev,
+ "Unable to get pll reference clock: %d\n",
+ ret);
+   return ret;
+   }
}
 
if (dsi->cdata->flags & DW_MIPI_NEEDS_PHY_CFG_CLK) {
-- 
2.24.0

___
dri-devel 

  1   2   >