[PATCH v6 0/9] Refactor MTK MDP driver into core/components

STALE1810d

Revision v6 of 7 in this series.

42 messages, 6 authors, 2021-08-18 · open the first message on its own page

[PATCH v6 0/9] Refactor MTK MDP driver into core/components

From: Eizan Miyamoto <hidden>
Date: 2021-08-02 12:12:32

This is an update to
https://patchwork.kernel.org/project/linux-mediatek/list/?series=283075
To address some comments and fixes.

This series has been verified to work on 5.13.


Changes in v6:
- Don't propagate errors from clock_on/off as an afterthought.
- Split apart modifying mdp driver to be loadable from mmsys from
  actually loading it from mmsys into two changs to make review easier.
- Update devicetree bindings to reflect no longer needing the
  mediatek,vpu property in the mdp_rdma0 device node.
- Some stylistic cleanups.

Changes in v5:
- rebase and test on 5.13-next @ e2f74b13dbe6

Changes in v4:
- rebase and test on 5.13
- don't depend on https://patchwork.kernel.org/project/linux-mediatek/list/?series=464873

Changes in v3:
- get mdp master from aliases instead of strcmp against of_node->name

Changes in v2:
- rebased onto Linux 5.12
- 100 char line length allowance was utilized in a few places
- Removal of a redundant dev_err() print at the end of
  mtk_mdp_comp_init()
- Instead of printing errors and ignoring them, I've added a patch to
  correctly propagate them.
- Use of C style comments.
- Three additional patches were added to eliminate dependency on the
  mediatek,vpu property inside the mdp_rdma0 device node.

Eizan Miyamoto (9):
  mtk-mdp: propagate errors from clock_on
  mtk-mdp: add driver to probe mdp components
  mtk-mdp: use pm_runtime in MDP component driver
  media: mtk-mdp: don't pm_run_time_get/put for master comp in clock_on
  mtk-mdp: make mdp driver to be loadable by platform_device_register*()
  soc: mediatek: mmsys: instantiate mdp virtual device from mmsys
  media: mtk-mdp: use mdp-rdma0 alias to point to MDP master
  dts: mtk-mdp: remove mediatek,vpu property from primary MDP device
  dt-bindings: mediatek: remove vpu requirement from mtk-mdp

 .../bindings/media/mediatek-mdp.txt           |   3 -
 arch/arm64/boot/dts/mediatek/mt8173.dtsi      |   1 -
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 268 +++++++++++++++--
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  34 +--
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 282 ++++++++++++------
 drivers/media/platform/mtk-mdp/mtk_mdp_core.h |   3 +
 drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c  |   4 +-
 drivers/soc/mediatek/mtk-mmsys.c              |  20 +-
 8 files changed, 470 insertions(+), 145 deletions(-)

-- 
2.32.0.554.ge1b32706d8-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

[PATCH v6 1/9] mtk-mdp: propagate errors from clock_on

From: Eizan Miyamoto <hidden>
Date: 2021-08-02 12:12:44

Up until this change, many errors were logged but ignored when powering
on clocks inside mtk_mdp_core. This change tries to do a better job at
propagating errors back to the power management framework.

Signed-off-by: Eizan Miyamoto <redacted>
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 25 ++++++++++++-----
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  2 +-
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 27 ++++++++++++++-----
 3 files changed, 39 insertions(+), 15 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index b3426a551bea..76e295c8d9bc 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -13,10 +13,9 @@
 
 #include "mtk_mdp_comp.h"
 
-
-void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
+int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 {
-	int i, err;
+	int i, err, status;
 
 	if (comp->larb_dev) {
 		err = mtk_smi_larb_get(comp->larb_dev);
@@ -30,11 +29,23 @@ void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 		if (IS_ERR(comp->clk[i]))
 			continue;
 		err = clk_prepare_enable(comp->clk[i]);
-		if (err)
-			dev_err(dev,
-			"failed to enable clock, err %d. type:%d i:%d\n",
-				err, comp->type, i);
+		if (err) {
+			status = err;
+			dev_err(dev, "failed to enable clock, err %d. i:%d\n", err, i);
+			goto err_clk_prepare_enable;
+		}
+	}
+
+	return 0;
+
+err_clk_prepare_enable:
+	for (--i; i >= 0; i--) {
+		if (IS_ERR(comp->clk[i]))
+			continue;
+		clk_disable_unprepare(comp->clk[i]);
 	}
+
+	return status;
 }
 
 void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index 7897766c96bb..92ab5249bcad 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -41,7 +41,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
 		      struct mtk_mdp_comp *comp,
 		      enum mtk_mdp_comp_type comp_type);
 void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp);
-void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
 void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);
 
 
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 976aa1f4829b..412bbec0f735 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -52,13 +52,28 @@ static const struct of_device_id mtk_mdp_of_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, mtk_mdp_of_ids);
 
-static void mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
+static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
 {
-	struct device *dev = &mdp->pdev->dev;
 	struct mtk_mdp_comp *comp_node;
+	int status;
+	struct device *dev = &mdp->pdev->dev;
+	int err;
 
-	list_for_each_entry(comp_node, &mdp->comp_list, node)
-		mtk_mdp_comp_clock_on(dev, comp_node);
+	list_for_each_entry(comp_node, &mdp->comp_list, node) {
+		err = mtk_mdp_comp_clock_on(dev, comp_node);
+		if (err) {
+			status = err;
+			goto err_mtk_mdp_comp_clock_on;
+		}
+	}
+
+	return 0;
+
+err_mtk_mdp_comp_clock_on:
+	list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node)
+		mtk_mdp_comp_clock_off(dev, comp_node);
+
+	return status;
 }
 
 static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
@@ -274,9 +289,7 @@ static int __maybe_unused mtk_mdp_pm_resume(struct device *dev)
 {
 	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
 
-	mtk_mdp_clock_on(mdp);
-
-	return 0;
+	return mtk_mdp_clock_on(mdp);
 }
 
 static int __maybe_unused mtk_mdp_suspend(struct device *dev)
-- 
2.32.0.554.ge1b32706d8-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 1/9] mtk-mdp: propagate errors from clock_on

From: Enric Balletbo Serra <eballetbo@gmail.com>
Date: 2021-08-03 10:27:18

Hi Eizan,

Thank you for your patch.

Missatge de Eizan Miyamoto [off-list ref] del dia dl., 2 d’ag.
2021 a les 14:13:
Up until this change, many errors were logged but ignored when powering
on clocks inside mtk_mdp_core. This change tries to do a better job at
propagating errors back to the power management framework.

Signed-off-by: Eizan Miyamoto <redacted>
Reviewed-by: Enric Balletbo i Serra <redacted>
quoted hunk
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 25 ++++++++++++-----
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  2 +-
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 27 ++++++++++++++-----
 3 files changed, 39 insertions(+), 15 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index b3426a551bea..76e295c8d9bc 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -13,10 +13,9 @@

 #include "mtk_mdp_comp.h"

-
-void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
+int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 {
-       int i, err;
+       int i, err, status;

        if (comp->larb_dev) {
                err = mtk_smi_larb_get(comp->larb_dev);
@@ -30,11 +29,23 @@ void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
                if (IS_ERR(comp->clk[i]))
                        continue;
                err = clk_prepare_enable(comp->clk[i]);
-               if (err)
-                       dev_err(dev,
-                       "failed to enable clock, err %d. type:%d i:%d\n",
-                               err, comp->type, i);
+               if (err) {
+                       status = err;
+                       dev_err(dev, "failed to enable clock, err %d. i:%d\n", err, i);
+                       goto err_clk_prepare_enable;
+               }
+       }
+
+       return 0;
+
+err_clk_prepare_enable:
+       for (--i; i >= 0; i--) {
+               if (IS_ERR(comp->clk[i]))
+                       continue;
+               clk_disable_unprepare(comp->clk[i]);
nit: We could use bulk functions here, but that's probably a follow-up patch.



quoted hunk
        }
+
+       return status;
 }

 void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index 7897766c96bb..92ab5249bcad 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -41,7 +41,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
                      struct mtk_mdp_comp *comp,
                      enum mtk_mdp_comp_type comp_type);
 void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp);
-void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
 void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 976aa1f4829b..412bbec0f735 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -52,13 +52,28 @@ static const struct of_device_id mtk_mdp_of_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, mtk_mdp_of_ids);

-static void mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
+static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
 {
-       struct device *dev = &mdp->pdev->dev;
        struct mtk_mdp_comp *comp_node;
+       int status;
+       struct device *dev = &mdp->pdev->dev;
+       int err;

-       list_for_each_entry(comp_node, &mdp->comp_list, node)
-               mtk_mdp_comp_clock_on(dev, comp_node);
+       list_for_each_entry(comp_node, &mdp->comp_list, node) {
+               err = mtk_mdp_comp_clock_on(dev, comp_node);
+               if (err) {
+                       status = err;
+                       goto err_mtk_mdp_comp_clock_on;
+               }
+       }
+
+       return 0;
+
+err_mtk_mdp_comp_clock_on:
+       list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node)
+               mtk_mdp_comp_clock_off(dev, comp_node);
+
+       return status;
 }

 static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
@@ -274,9 +289,7 @@ static int __maybe_unused mtk_mdp_pm_resume(struct device *dev)
 {
        struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);

-       mtk_mdp_clock_on(mdp);
-
-       return 0;
+       return mtk_mdp_clock_on(mdp);
 }

 static int __maybe_unused mtk_mdp_suspend(struct device *dev)
--
2.32.0.554.ge1b32706d8-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 1/9] mtk-mdp: propagate errors from clock_on

From: Dafna Hirschfeld <hidden>
Date: 2021-08-05 06:06:26


On 02.08.21 14:12, Eizan Miyamoto wrote:
quoted hunk
Up until this change, many errors were logged but ignored when powering
on clocks inside mtk_mdp_core. This change tries to do a better job at
propagating errors back to the power management framework.

Signed-off-by: Eizan Miyamoto <redacted>
---

(no changes since v1)

  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 25 ++++++++++++-----
  drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  2 +-
  drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 27 ++++++++++++++-----
  3 files changed, 39 insertions(+), 15 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index b3426a551bea..76e295c8d9bc 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -13,10 +13,9 @@
  
  #include "mtk_mdp_comp.h"
  
-
-void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
+int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
  {
-	int i, err;
+	int i, err, status;
  
  	if (comp->larb_dev) {
  		err = mtk_smi_larb_get(comp->larb_dev);
@@ -30,11 +29,23 @@ void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
  		if (IS_ERR(comp->clk[i]))
  			continue;
  		err = clk_prepare_enable(comp->clk[i]);
-		if (err)
-			dev_err(dev,
-			"failed to enable clock, err %d. type:%d i:%d\n",
-				err, comp->type, i);
+		if (err) {
+			status = err;
+			dev_err(dev, "failed to enable clock, err %d. i:%d\n", err, i);
+			goto err_clk_prepare_enable;
+		}
+	}
+
+	return 0;
+
+err_clk_prepare_enable:
+	for (--i; i >= 0; i--) {
+		if (IS_ERR(comp->clk[i]))
+			continue;
+		clk_disable_unprepare(comp->clk[i]);
  	}
+
+	return status;
There is an API function clk_bulk_prepare_enable to prepare and enable an array of clks
so you can just use it.
quoted hunk
  }
  
  void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index 7897766c96bb..92ab5249bcad 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -41,7 +41,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
  		      struct mtk_mdp_comp *comp,
  		      enum mtk_mdp_comp_type comp_type);
  void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp);
-void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
  void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);
  
  
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 976aa1f4829b..412bbec0f735 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -52,13 +52,28 @@ static const struct of_device_id mtk_mdp_of_ids[] = {
  };
  MODULE_DEVICE_TABLE(of, mtk_mdp_of_ids);
  
-static void mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
+static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
  {
-	struct device *dev = &mdp->pdev->dev;
  	struct mtk_mdp_comp *comp_node;
+	int status;
+	struct device *dev = &mdp->pdev->dev;
+	int err;
  
-	list_for_each_entry(comp_node, &mdp->comp_list, node)
-		mtk_mdp_comp_clock_on(dev, comp_node);
+	list_for_each_entry(comp_node, &mdp->comp_list, node) {
+		err = mtk_mdp_comp_clock_on(dev, comp_node);
+		if (err) {
+			status = err;
You can get rid of the new var 'status' and just return ret in case of error
quoted hunk
+			goto err_mtk_mdp_comp_clock_on;
+		}
+	}
+
+	return 0;
+
+err_mtk_mdp_comp_clock_on:
+	list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node)
+		mtk_mdp_comp_clock_off(dev, comp_node);
+
+	return status;
  }
  
  static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
@@ -274,9 +289,7 @@ static int __maybe_unused mtk_mdp_pm_resume(struct device *dev)
  {
  	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
  
-	mtk_mdp_clock_on(mdp);
-
-	return 0;
+	return mtk_mdp_clock_on(mdp);
  }
  
  static int __maybe_unused mtk_mdp_suspend(struct device *dev)
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 1/9] mtk-mdp: propagate errors from clock_on

From: Eizan Miyamoto <hidden>
Date: 2021-08-09 03:23:26

Hi Dafna, thank you very much for spending time to review the patch,
your time spent is very much appreciated.

On Thu, Aug 5, 2021 at 4:06 PM Dafna Hirschfeld
[off-list ref] wrote:
quoted
+err_clk_prepare_enable:
+     for (--i; i >= 0; i--) {
+             if (IS_ERR(comp->clk[i]))
+                     continue;
+             clk_disable_unprepare(comp->clk[i]);
      }
+
+     return status;
There is an API function clk_bulk_prepare_enable to prepare and enable an array of clks
so you can just use it.
As per Enric's suggestion earlier in this email thread, are you OK
with me making this change in a follow-up patch, particularly since
the logic as it is was preserved from previous functionality?
quoted
-static void mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
+static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
  {
-     struct device *dev = &mdp->pdev->dev;
      struct mtk_mdp_comp *comp_node;
+     int status;
+     struct device *dev = &mdp->pdev->dev;
+     int err;

-     list_for_each_entry(comp_node, &mdp->comp_list, node)
-             mtk_mdp_comp_clock_on(dev, comp_node);
+     list_for_each_entry(comp_node, &mdp->comp_list, node) {
+             err = mtk_mdp_comp_clock_on(dev, comp_node);
+             if (err) {
+                     status = err;
You can get rid of the new var 'status' and just return ret in case of error
This seems like a nit (please let me know if you disagree), and it's
also cleaned up in a follow-on patch in the series ("don't
pm_run_time_get/put for master comp in clock_on"). Is making the
change you are suggesting here something that should require uploading
a new series version?

Eizan

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 1/9] mtk-mdp: propagate errors from clock_on

From: Dafna Hirschfeld <hidden>
Date: 2021-08-09 07:43:06

Hi,

On 09.08.21 05:23, Eizan Miyamoto wrote:
Hi Dafna, thank you very much for spending time to review the patch,
your time spent is very much appreciated.

On Thu, Aug 5, 2021 at 4:06 PM Dafna Hirschfeld
[off-list ref] wrote:
quoted
quoted
+err_clk_prepare_enable:
+     for (--i; i >= 0; i--) {
+             if (IS_ERR(comp->clk[i]))
+                     continue;
+             clk_disable_unprepare(comp->clk[i]);
       }
+
+     return status;
There is an API function clk_bulk_prepare_enable to prepare and enable an array of clks
so you can just use it.
As per Enric's suggestion earlier in this email thread, are you OK
with me making this change in a follow-up patch, particularly since
the logic as it is was preserved from previous functionality?
sure,
I just give suggestions.
A follow-up patch would be nice.
quoted
quoted
-static void mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
+static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
   {
-     struct device *dev = &mdp->pdev->dev;
       struct mtk_mdp_comp *comp_node;
+     int status;
+     struct device *dev = &mdp->pdev->dev;
+     int err;

-     list_for_each_entry(comp_node, &mdp->comp_list, node)
-             mtk_mdp_comp_clock_on(dev, comp_node);
+     list_for_each_entry(comp_node, &mdp->comp_list, node) {
+             err = mtk_mdp_comp_clock_on(dev, comp_node);
+             if (err) {
+                     status = err;
You can get rid of the new var 'status' and just return ret in case of error
This seems like a nit (please let me know if you disagree), and it's
also cleaned up in a follow-on patch in the series ("don't
pm_run_time_get/put for master comp in clock_on"). Is making the
change you are suggesting here something that should require uploading
a new series version?
Hi, no, I am fine with it. No need for new version.


Thanks,
Dafna
Eizan
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 1/9] mtk-mdp: propagate errors from clock_on

From: houlong wei <houlong.wei@mediatek.com>
Date: 2021-08-16 00:47:11

On Mon, 2021-08-02 at 20:12 +0800, Eizan Miyamoto wrote:
Up until this change, many errors were logged but ignored when
powering
on clocks inside mtk_mdp_core. This change tries to do a better job
at
propagating errors back to the power management framework.

Signed-off-by: Eizan Miyamoto <redacted>
---
Reviewed-by: Houlong Wei <houlong.wei@mediatek.com>
(no changes since v1)
[...]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

[PATCH v6 2/9] mtk-mdp: add driver to probe mdp components

From: Eizan Miyamoto <hidden>
Date: 2021-08-02 12:12:48

Broadly, this patch (1) adds a driver for various MTK MDP components to
go alongside the main MTK MDP driver, and (2) hooks them all together
using the component framework.

(1) Up until now, the MTK MDP driver controls 8 devices in the device
tree on its own. When running tests for the hardware video decoder, we
found that the iommus and LARBs were not being properly configured. To
configure them, a driver for each be added to mtk_mdp_comp so that
mtk_iommu_add_device() can (eventually) be called from dma_configure()
inside really_probe().

(2) The integration into the component framework allows us to defer the
registration with the v4l2 subsystem until all the MDP-related devices
have been probed, so that the relevant device node does not become
available until initialization of all the components is complete.

Some notes about how the component framework has been integrated:

- The driver for the rdma0 component serves double duty as the "master"
  (aggregate) driver as well as a component driver. This is a non-ideal
  compromise until a better solution is developed. This device is
  differentiated from the rest by checking for a "mediatek,vpu" property
  in the device node.

- The list of mdp components remains hard-coded as mtk_mdp_comp_dt_ids[]
  in mtk_mdp_core.c, and as mtk_mdp_comp_driver_dt_match[] in
  mtk_mdp_comp.c. This unfortunate duplication of information is
  addressed in a following patch in this series.

- The component driver calls component_add() for each device that is
  probed.

- In mtk_mdp_probe (the "master" device), we scan the device tree for
  any matching nodes against mtk_mdp_comp_dt_ids, and add component
  matches for them. The match criteria is a matching device node
  pointer.

- When the set of components devices that have been probed corresponds
  with the list that is generated by the "master", the callback to
  mtk_mdp_master_bind() is made, which then calls the component bind
  functions.

- Inside mtk_mdp_master_bind(), once all the component bind functions
  have been called, we can then register our device to the v4l2
  subsystem.

- The call to pm_runtime_enable() in the master device is called after
  all the components have been registered by their bind() functions
  called by mtk_mtp_master_bind(). As a result, the list of components
  will not change while power management callbacks mtk_mdp_suspend()/
  resume() are accessing the list of components.

Signed-off-by: Eizan Miyamoto <redacted>
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 143 ++++++++++++--
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  25 +--
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 174 +++++++++++++-----
 drivers/media/platform/mtk-mdp/mtk_mdp_core.h |   1 +
 4 files changed, 252 insertions(+), 91 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 76e295c8d9bc..7a0e3acffab9 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -5,13 +5,50 @@
  */
 
 #include <linux/clk.h>
+#include <linux/component.h>
 #include <linux/device.h>
 #include <linux/of.h>
+#include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <soc/mediatek/smi.h>
 
 #include "mtk_mdp_comp.h"
+#include "mtk_mdp_core.h"
+
+/**
+ * enum mtk_mdp_comp_type - the MDP component
+ * @MTK_MDP_RDMA:		Read DMA
+ * @MTK_MDP_RSZ:		Reszer
+ * @MTK_MDP_WDMA:		Write DMA
+ * @MTK_MDP_WROT:		Write DMA with rotation
+ * @MTK_MDP_COMP_TYPE_MAX:	Placeholder for num elems in this enum
+ */
+enum mtk_mdp_comp_type {
+	MTK_MDP_RDMA,
+	MTK_MDP_RSZ,
+	MTK_MDP_WDMA,
+	MTK_MDP_WROT,
+	MTK_MDP_COMP_TYPE_MAX,
+};
+
+static const struct of_device_id mtk_mdp_comp_driver_dt_match[] = {
+	{
+		.compatible = "mediatek,mt8173-mdp-rdma",
+		.data = (void *)MTK_MDP_RDMA
+	}, {
+		.compatible = "mediatek,mt8173-mdp-rsz",
+		.data = (void *)MTK_MDP_RSZ
+	}, {
+		.compatible = "mediatek,mt8173-mdp-wdma",
+		.data = (void *)MTK_MDP_WDMA
+	}, {
+		.compatible = "mediatek,mt8173-mdp-wrot",
+		.data = (void *)MTK_MDP_WROT
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mtk_mdp_comp_driver_dt_match);
 
 int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 {
@@ -20,9 +57,7 @@ int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 	if (comp->larb_dev) {
 		err = mtk_smi_larb_get(comp->larb_dev);
 		if (err)
-			dev_err(dev,
-				"failed to get larb, err %d. type:%d\n",
-				err, comp->type);
+			dev_err(dev, "failed to get larb, err %d.\n", err);
 	}
 
 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
@@ -62,17 +97,41 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
 		mtk_smi_larb_put(comp->larb_dev);
 }
 
-int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
-		      struct mtk_mdp_comp *comp,
-		      enum mtk_mdp_comp_type comp_type)
+static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
+{
+	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
+	struct mtk_mdp_dev *mdp = data;
+
+	mtk_mdp_register_component(mdp, comp);
+
+	return 0;
+}
+
+static void mtk_mdp_comp_unbind(struct device *dev, struct device *master,
+			   void *data)
+{
+	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
+	struct mtk_mdp_dev *mdp = data;
+
+	mtk_mdp_unregister_component(mdp, comp);
+}
+
+static const struct component_ops mtk_mdp_component_ops = {
+	.bind   = mtk_mdp_comp_bind,
+	.unbind = mtk_mdp_comp_unbind,
+};
+
+int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
 {
 	struct device_node *larb_node;
 	struct platform_device *larb_pdev;
 	int ret;
 	int i;
+	struct device_node *node = dev->of_node;
+	enum mtk_mdp_comp_type comp_type =
+		 (enum mtk_mdp_comp_type)of_device_get_match_data(dev);
 
-	comp->dev_node = of_node_get(node);
-	comp->type = comp_type;
+	INIT_LIST_HEAD(&comp->node);
 
 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
 		comp->clk[i] = of_clk_get(node, i);
@@ -80,19 +139,17 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
 			if (PTR_ERR(comp->clk[i]) != -EPROBE_DEFER)
 				dev_err(dev, "Failed to get clock\n");
 			ret = PTR_ERR(comp->clk[i]);
-			goto put_dev;
+			goto err;
 		}
 
 		/* Only RDMA needs two clocks */
-		if (comp->type != MTK_MDP_RDMA)
+		if (comp_type != MTK_MDP_RDMA)
 			break;
 	}
 
 	/* Only DMA capable components need the LARB property */
 	comp->larb_dev = NULL;
-	if (comp->type != MTK_MDP_RDMA &&
-	    comp->type != MTK_MDP_WDMA &&
-	    comp->type != MTK_MDP_WROT)
+	if (comp_type != MTK_MDP_RDMA && comp_type != MTK_MDP_WDMA && comp_type != MTK_MDP_WROT)
 		return 0;
 
 	larb_node = of_parse_phandle(node, "mediatek,larb", 0);
@@ -100,7 +157,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
 		dev_err(dev,
 			"Missing mediadek,larb phandle in %pOF node\n", node);
 		ret = -EINVAL;
-		goto put_dev;
+		goto err;
 	}
 
 	larb_pdev = of_find_device_by_node(larb_node);
@@ -108,7 +165,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
 		dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
 		of_node_put(larb_node);
 		ret = -EPROBE_DEFER;
-		goto put_dev;
+		goto err;
 	}
 	of_node_put(larb_node);
 
@@ -116,13 +173,59 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
 
 	return 0;
 
-put_dev:
-	of_node_put(comp->dev_node);
-
+err:
 	return ret;
 }
 
-void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp)
+static int mtk_mdp_comp_probe(struct platform_device *pdev)
 {
-	of_node_put(comp->dev_node);
+	struct device *dev = &pdev->dev;
+	struct device_node *vpu_node;
+	int status;
+	struct mtk_mdp_comp *comp;
+
+	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
+	if (vpu_node) {
+		of_node_put(vpu_node);
+		/*
+		 * The device tree node with a mediatek,vpu property is deemed
+		 * the MDP "master" device, we don't want to add a component
+		 * for it in this function because the initialization for the
+		 * master is done elsewhere.
+		 */
+		dev_info(dev, "vpu node found, not probing\n");
+		return -ENODEV;
+	}
+
+	comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
+	if (!comp)
+		return -ENOMEM;
+
+	status = mtk_mdp_comp_init(comp, dev);
+	if (status) {
+		dev_err(dev, "Failed to initialize component: %d\n", status);
+		return status;
+	}
+
+	dev_set_drvdata(dev, comp);
+
+	return component_add(dev, &mtk_mdp_component_ops);
 }
+
+static int mtk_mdp_comp_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	component_del(dev, &mtk_mdp_component_ops);
+	return 0;
+}
+
+struct platform_driver mtk_mdp_component_driver = {
+	.probe          = mtk_mdp_comp_probe,
+	.remove         = mtk_mdp_comp_remove,
+	.driver         = {
+		.name   = "mediatek-mdp-comp",
+		.owner  = THIS_MODULE,
+		.of_match_table = mtk_mdp_comp_driver_dt_match,
+	},
+};
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index 92ab5249bcad..df5fc4c94f90 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -7,42 +7,23 @@
 #ifndef __MTK_MDP_COMP_H__
 #define __MTK_MDP_COMP_H__
 
-/**
- * enum mtk_mdp_comp_type - the MDP component
- * @MTK_MDP_RDMA:	Read DMA
- * @MTK_MDP_RSZ:	Riszer
- * @MTK_MDP_WDMA:	Write DMA
- * @MTK_MDP_WROT:	Write DMA with rotation
- */
-enum mtk_mdp_comp_type {
-	MTK_MDP_RDMA,
-	MTK_MDP_RSZ,
-	MTK_MDP_WDMA,
-	MTK_MDP_WROT,
-};
-
 /**
  * struct mtk_mdp_comp - the MDP's function component data
  * @node:	list node to track sibing MDP components
- * @dev_node:	component device node
  * @clk:	clocks required for component
  * @larb_dev:	SMI device required for component
- * @type:	component type
  */
 struct mtk_mdp_comp {
 	struct list_head	node;
-	struct device_node	*dev_node;
 	struct clk		*clk[2];
 	struct device		*larb_dev;
-	enum mtk_mdp_comp_type	type;
 };
 
-int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
-		      struct mtk_mdp_comp *comp,
-		      enum mtk_mdp_comp_type comp_type);
-void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev);
+
 int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
 void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);
 
+extern struct platform_driver mtk_mdp_component_driver;
 
 #endif /* __MTK_MDP_COMP_H__ */
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 412bbec0f735..b813a822439a 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/component.h>
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
@@ -19,6 +20,7 @@
 #include <linux/workqueue.h>
 #include <soc/mediatek/smi.h>
 
+#include "mtk_mdp_comp.h"
 #include "mtk_mdp_core.h"
 #include "mtk_mdp_m2m.h"
 #include "mtk_vpu.h"
@@ -32,16 +34,12 @@ module_param(mtk_mdp_dbg_level, int, 0644);
 static const struct of_device_id mtk_mdp_comp_dt_ids[] = {
 	{
 		.compatible = "mediatek,mt8173-mdp-rdma",
-		.data = (void *)MTK_MDP_RDMA
 	}, {
 		.compatible = "mediatek,mt8173-mdp-rsz",
-		.data = (void *)MTK_MDP_RSZ
 	}, {
 		.compatible = "mediatek,mt8173-mdp-wdma",
-		.data = (void *)MTK_MDP_WDMA
 	}, {
 		.compatible = "mediatek,mt8173-mdp-wrot",
-		.data = (void *)MTK_MDP_WROT
 	},
 	{ },
 };
@@ -106,6 +104,63 @@ static void mtk_mdp_reset_handler(void *priv)
 	queue_work(mdp->wdt_wq, &mdp->wdt_work);
 }
 
+static int compare_of(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static void release_of(struct device *dev, void *data)
+{
+	of_node_put(data);
+}
+
+static int mtk_mdp_master_bind(struct device *dev)
+{
+	int status;
+	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
+
+	mtk_mdp_register_component(mdp, &mdp->comp_self);
+
+	status = component_bind_all(dev, mdp);
+	if (status) {
+		dev_err(dev, "Failed to bind all components: %d\n", status);
+		goto err_component_bind_all;
+	}
+
+	status = mtk_mdp_register_m2m_device(mdp);
+	if (status) {
+		dev_err(dev, "Failed to register m2m device: %d\n", status);
+		goto err_mtk_mdp_register_m2m_device;
+	}
+
+	pm_runtime_enable(dev);
+
+	return 0;
+
+err_mtk_mdp_register_m2m_device:
+	component_unbind_all(dev, mdp);
+
+err_component_bind_all:
+	mtk_mdp_unregister_component(mdp, &mdp->comp_self);
+
+	return status;
+}
+
+static void mtk_mdp_master_unbind(struct device *dev)
+{
+	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
+
+	pm_runtime_disable(dev);
+	mtk_mdp_unregister_m2m_device(mdp);
+	component_unbind_all(dev, mdp);
+	mtk_mdp_unregister_component(mdp, &mdp->comp_self);
+}
+
+static const struct component_master_ops mtk_mdp_com_ops = {
+	.bind		= mtk_mdp_master_bind,
+	.unbind		= mtk_mdp_master_unbind,
+};
+
 void mtk_mdp_register_component(struct mtk_mdp_dev *mdp,
 				struct mtk_mdp_comp *comp)
 {
@@ -123,8 +178,8 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 	struct mtk_mdp_dev *mdp;
 	struct device *dev = &pdev->dev;
 	struct device_node *node, *parent;
-	struct mtk_mdp_comp *comp, *comp_temp;
-	int ret = 0;
+	int i, ret = 0;
+	struct component_match *match = NULL;
 
 	mdp = devm_kzalloc(dev, sizeof(*mdp), GFP_KERNEL);
 	if (!mdp)
@@ -149,36 +204,43 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 	}
 
 	/* Iterate over sibling MDP function blocks */
+	i = 0;
 	for_each_child_of_node(parent, node) {
-		const struct of_device_id *of_id;
-		enum mtk_mdp_comp_type comp_type;
+		struct platform_device *pdev;
 
-		of_id = of_match_node(mtk_mdp_comp_dt_ids, node);
-		if (!of_id)
+		if (!of_match_node(mtk_mdp_comp_dt_ids, node))
 			continue;
 
-		if (!of_device_is_available(node)) {
-			dev_err(dev, "Skipping disabled component %pOF\n",
-				node);
+		if (!of_device_is_available(node))
 			continue;
-		}
-
-		comp_type = (enum mtk_mdp_comp_type)of_id->data;
 
-		comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
-		if (!comp) {
-			ret = -ENOMEM;
-			of_node_put(node);
-			goto err_comp;
+		pdev = of_find_device_by_node(node);
+		if (!pdev) {
+			dev_warn(dev, "Unable to find comp device %s\n",
+				 node->full_name);
+			continue;
 		}
 
-		ret = mtk_mdp_comp_init(dev, node, comp, comp_type);
-		if (ret) {
-			of_node_put(node);
-			goto err_comp;
+		/*
+		 * Do not add a match for my own (rdma0) device node.
+		 * I will be managing it directly instead using comp_self.
+		 */
+		if (&pdev->dev != dev) {
+			dev_dbg(dev, "adding match %d for: %pOF\n", i++, node);
+			component_match_add_release(dev, &match, release_of,
+						    compare_of,
+						    of_node_get(node));
 		}
+	}
 
-		mtk_mdp_register_component(mdp, comp);
+	/*
+	 * Create a component for myself so that clocks can be toggled in
+	 * clock_on().
+	 */
+	ret = mtk_mdp_comp_init(&mdp->comp_self, dev);
+	if (ret) {
+		dev_err(dev, "Failed to initialize component\n");
+		goto err_comp;
 	}
 
 	mdp->job_wq = create_singlethread_workqueue(MTK_MDP_MODULE_NAME);
@@ -203,18 +265,12 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 		goto err_dev_register;
 	}
 
-	ret = mtk_mdp_register_m2m_device(mdp);
-	if (ret) {
-		v4l2_err(&mdp->v4l2_dev, "Failed to init mem2mem device\n");
-		goto err_m2m_register;
-	}
-
 	mdp->vpu_dev = vpu_get_plat_device(pdev);
 	ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
 				  VPU_RST_MDP);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register reset handler\n");
-		goto err_m2m_register;
+		goto err_wdt_reg;
 	}
 
 	platform_set_drvdata(pdev, mdp);
@@ -222,15 +278,25 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 	ret = vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to set vb2 dma mag seg size\n");
-		goto err_m2m_register;
+		goto err_set_max_seg_size;
+	}
+
+	ret = component_master_add_with_match(dev, &mtk_mdp_com_ops, match);
+	if (ret) {
+		dev_err(dev, "Component master add failed\n");
+		goto err_component_master_add;
 	}
 
-	pm_runtime_enable(dev);
 	dev_dbg(dev, "mdp-%d registered successfully\n", mdp->id);
 
 	return 0;
 
-err_m2m_register:
+err_component_master_add:
+	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
+
+err_set_max_seg_size:
+
+err_wdt_reg:
 	v4l2_device_unregister(&mdp->v4l2_dev);
 
 err_dev_register:
@@ -242,11 +308,6 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 err_alloc_job_wq:
 
 err_comp:
-	list_for_each_entry_safe(comp, comp_temp, &mdp->comp_list, node) {
-		mtk_mdp_unregister_component(mdp, comp);
-		mtk_mdp_comp_deinit(dev, comp);
-	}
-
 	dev_dbg(dev, "err %d\n", ret);
 	return ret;
 }
@@ -254,11 +315,10 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 static int mtk_mdp_remove(struct platform_device *pdev)
 {
 	struct mtk_mdp_dev *mdp = platform_get_drvdata(pdev);
-	struct mtk_mdp_comp *comp, *comp_temp;
 
-	pm_runtime_disable(&pdev->dev);
+	component_master_del(&pdev->dev, &mtk_mdp_com_ops);
+
 	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
-	mtk_mdp_unregister_m2m_device(mdp);
 	v4l2_device_unregister(&mdp->v4l2_dev);
 
 	flush_workqueue(mdp->wdt_wq);
@@ -267,10 +327,8 @@ static int mtk_mdp_remove(struct platform_device *pdev)
 	flush_workqueue(mdp->job_wq);
 	destroy_workqueue(mdp->job_wq);
 
-	list_for_each_entry_safe(comp, comp_temp, &mdp->comp_list, node) {
-		mtk_mdp_unregister_component(mdp, comp);
-		mtk_mdp_comp_deinit(&pdev->dev, comp);
-	}
+	if (!list_empty(&mdp->comp_list))
+		dev_warn(&pdev->dev, "not all components removed\n");
 
 	dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name);
 	return 0;
@@ -323,7 +381,25 @@ static struct platform_driver mtk_mdp_driver = {
 	}
 };
 
-module_platform_driver(mtk_mdp_driver);
+static struct platform_driver * const mtk_mdp_drivers[] = {
+	&mtk_mdp_driver,
+	&mtk_mdp_component_driver,
+};
+
+static int __init mtk_mdp_init(void)
+{
+	return platform_register_drivers(mtk_mdp_drivers,
+					 ARRAY_SIZE(mtk_mdp_drivers));
+}
+
+static void __exit mtk_mdp_exit(void)
+{
+	platform_unregister_drivers(mtk_mdp_drivers,
+				    ARRAY_SIZE(mtk_mdp_drivers));
+}
+
+module_init(mtk_mdp_init);
+module_exit(mtk_mdp_exit);
 
 MODULE_AUTHOR("Houlong Wei <houlong.wei@mediatek.com>");
 MODULE_DESCRIPTION("Mediatek image processor driver");
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
index a6e6dc36307b..8a52539b15d4 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
@@ -155,6 +155,7 @@ struct mtk_mdp_dev {
 	struct mtk_mdp_variant		*variant;
 	u16				id;
 	struct list_head		comp_list;
+	struct mtk_mdp_comp		comp_self;
 	struct v4l2_m2m_dev		*m2m_dev;
 	struct list_head		ctx_list;
 	struct video_device		*vdev;
-- 
2.32.0.554.ge1b32706d8-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 2/9] mtk-mdp: add driver to probe mdp components

From: Enric Balletbo Serra <eballetbo@gmail.com>
Date: 2021-08-03 10:27:13

Hi Eizan,

Thank you for your patch.

Missatge de Eizan Miyamoto [off-list ref] del dia dl., 2 d’ag.
2021 a les 14:13:
Broadly, this patch (1) adds a driver for various MTK MDP components to
go alongside the main MTK MDP driver, and (2) hooks them all together
using the component framework.

(1) Up until now, the MTK MDP driver controls 8 devices in the device
tree on its own. When running tests for the hardware video decoder, we
found that the iommus and LARBs were not being properly configured. To
configure them, a driver for each be added to mtk_mdp_comp so that
mtk_iommu_add_device() can (eventually) be called from dma_configure()
inside really_probe().

(2) The integration into the component framework allows us to defer the
registration with the v4l2 subsystem until all the MDP-related devices
have been probed, so that the relevant device node does not become
available until initialization of all the components is complete.

Some notes about how the component framework has been integrated:

- The driver for the rdma0 component serves double duty as the "master"
  (aggregate) driver as well as a component driver. This is a non-ideal
  compromise until a better solution is developed. This device is
  differentiated from the rest by checking for a "mediatek,vpu" property
  in the device node.

- The list of mdp components remains hard-coded as mtk_mdp_comp_dt_ids[]
  in mtk_mdp_core.c, and as mtk_mdp_comp_driver_dt_match[] in
  mtk_mdp_comp.c. This unfortunate duplication of information is
  addressed in a following patch in this series.

- The component driver calls component_add() for each device that is
  probed.

- In mtk_mdp_probe (the "master" device), we scan the device tree for
  any matching nodes against mtk_mdp_comp_dt_ids, and add component
  matches for them. The match criteria is a matching device node
  pointer.

- When the set of components devices that have been probed corresponds
  with the list that is generated by the "master", the callback to
  mtk_mdp_master_bind() is made, which then calls the component bind
  functions.

- Inside mtk_mdp_master_bind(), once all the component bind functions
  have been called, we can then register our device to the v4l2
  subsystem.

- The call to pm_runtime_enable() in the master device is called after
  all the components have been registered by their bind() functions
  called by mtk_mtp_master_bind(). As a result, the list of components
  will not change while power management callbacks mtk_mdp_suspend()/
  resume() are accessing the list of components.

Signed-off-by: Eizan Miyamoto <redacted>
Reviewed-by: Enric Balletbo i Serra <redacted>


quoted hunk
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 143 ++++++++++++--
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  25 +--
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 174 +++++++++++++-----
 drivers/media/platform/mtk-mdp/mtk_mdp_core.h |   1 +
 4 files changed, 252 insertions(+), 91 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 76e295c8d9bc..7a0e3acffab9 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -5,13 +5,50 @@
  */

 #include <linux/clk.h>
+#include <linux/component.h>
 #include <linux/device.h>
 #include <linux/of.h>
+#include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <soc/mediatek/smi.h>

 #include "mtk_mdp_comp.h"
+#include "mtk_mdp_core.h"
+
+/**
+ * enum mtk_mdp_comp_type - the MDP component
+ * @MTK_MDP_RDMA:              Read DMA
+ * @MTK_MDP_RSZ:               Reszer
+ * @MTK_MDP_WDMA:              Write DMA
+ * @MTK_MDP_WROT:              Write DMA with rotation
+ * @MTK_MDP_COMP_TYPE_MAX:     Placeholder for num elems in this enum
+ */
+enum mtk_mdp_comp_type {
+       MTK_MDP_RDMA,
+       MTK_MDP_RSZ,
+       MTK_MDP_WDMA,
+       MTK_MDP_WROT,
+       MTK_MDP_COMP_TYPE_MAX,
+};
+
+static const struct of_device_id mtk_mdp_comp_driver_dt_match[] = {
+       {
+               .compatible = "mediatek,mt8173-mdp-rdma",
+               .data = (void *)MTK_MDP_RDMA
+       }, {
+               .compatible = "mediatek,mt8173-mdp-rsz",
+               .data = (void *)MTK_MDP_RSZ
+       }, {
+               .compatible = "mediatek,mt8173-mdp-wdma",
+               .data = (void *)MTK_MDP_WDMA
+       }, {
+               .compatible = "mediatek,mt8173-mdp-wrot",
+               .data = (void *)MTK_MDP_WROT
+       },
+       { }
+};
+MODULE_DEVICE_TABLE(of, mtk_mdp_comp_driver_dt_match);

 int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 {
@@ -20,9 +57,7 @@ int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
        if (comp->larb_dev) {
                err = mtk_smi_larb_get(comp->larb_dev);
                if (err)
-                       dev_err(dev,
-                               "failed to get larb, err %d. type:%d\n",
-                               err, comp->type);
+                       dev_err(dev, "failed to get larb, err %d.\n", err);
        }

        for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
@@ -62,17 +97,41 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
                mtk_smi_larb_put(comp->larb_dev);
 }

-int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
-                     struct mtk_mdp_comp *comp,
-                     enum mtk_mdp_comp_type comp_type)
+static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
+{
+       struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
+       struct mtk_mdp_dev *mdp = data;
+
+       mtk_mdp_register_component(mdp, comp);
+
+       return 0;
+}
+
+static void mtk_mdp_comp_unbind(struct device *dev, struct device *master,
+                          void *data)
+{
+       struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
+       struct mtk_mdp_dev *mdp = data;
+
+       mtk_mdp_unregister_component(mdp, comp);
+}
+
+static const struct component_ops mtk_mdp_component_ops = {
+       .bind   = mtk_mdp_comp_bind,
+       .unbind = mtk_mdp_comp_unbind,
+};
+
+int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
 {
        struct device_node *larb_node;
        struct platform_device *larb_pdev;
        int ret;
        int i;
+       struct device_node *node = dev->of_node;
+       enum mtk_mdp_comp_type comp_type =
+                (enum mtk_mdp_comp_type)of_device_get_match_data(dev);

-       comp->dev_node = of_node_get(node);
-       comp->type = comp_type;
+       INIT_LIST_HEAD(&comp->node);

        for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
                comp->clk[i] = of_clk_get(node, i);
@@ -80,19 +139,17 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
                        if (PTR_ERR(comp->clk[i]) != -EPROBE_DEFER)
                                dev_err(dev, "Failed to get clock\n");
                        ret = PTR_ERR(comp->clk[i]);
-                       goto put_dev;
+                       goto err;
                }

                /* Only RDMA needs two clocks */
-               if (comp->type != MTK_MDP_RDMA)
+               if (comp_type != MTK_MDP_RDMA)
                        break;
        }

        /* Only DMA capable components need the LARB property */
        comp->larb_dev = NULL;
-       if (comp->type != MTK_MDP_RDMA &&
-           comp->type != MTK_MDP_WDMA &&
-           comp->type != MTK_MDP_WROT)
+       if (comp_type != MTK_MDP_RDMA && comp_type != MTK_MDP_WDMA && comp_type != MTK_MDP_WROT)
                return 0;

        larb_node = of_parse_phandle(node, "mediatek,larb", 0);
@@ -100,7 +157,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
                dev_err(dev,
                        "Missing mediadek,larb phandle in %pOF node\n", node);
                ret = -EINVAL;
-               goto put_dev;
+               goto err;
        }

        larb_pdev = of_find_device_by_node(larb_node);
@@ -108,7 +165,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
                dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
                of_node_put(larb_node);
                ret = -EPROBE_DEFER;
-               goto put_dev;
+               goto err;
        }
        of_node_put(larb_node);
@@ -116,13 +173,59 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,

        return 0;

-put_dev:
-       of_node_put(comp->dev_node);
-
+err:
        return ret;
 }

-void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp)
+static int mtk_mdp_comp_probe(struct platform_device *pdev)
 {
-       of_node_put(comp->dev_node);
+       struct device *dev = &pdev->dev;
+       struct device_node *vpu_node;
+       int status;
+       struct mtk_mdp_comp *comp;
+
+       vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
+       if (vpu_node) {
+               of_node_put(vpu_node);
+               /*
+                * The device tree node with a mediatek,vpu property is deemed
+                * the MDP "master" device, we don't want to add a component
+                * for it in this function because the initialization for the
+                * master is done elsewhere.
+                */
+               dev_info(dev, "vpu node found, not probing\n");
+               return -ENODEV;
+       }
+
+       comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
+       if (!comp)
+               return -ENOMEM;
+
+       status = mtk_mdp_comp_init(comp, dev);
+       if (status) {
+               dev_err(dev, "Failed to initialize component: %d\n", status);
+               return status;
+       }
+
+       dev_set_drvdata(dev, comp);
+
+       return component_add(dev, &mtk_mdp_component_ops);
 }
+
+static int mtk_mdp_comp_remove(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+
+       component_del(dev, &mtk_mdp_component_ops);
+       return 0;
+}
+
+struct platform_driver mtk_mdp_component_driver = {
+       .probe          = mtk_mdp_comp_probe,
+       .remove         = mtk_mdp_comp_remove,
+       .driver         = {
+               .name   = "mediatek-mdp-comp",
+               .owner  = THIS_MODULE,
+               .of_match_table = mtk_mdp_comp_driver_dt_match,
+       },
+};
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index 92ab5249bcad..df5fc4c94f90 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -7,42 +7,23 @@
 #ifndef __MTK_MDP_COMP_H__
 #define __MTK_MDP_COMP_H__

-/**
- * enum mtk_mdp_comp_type - the MDP component
- * @MTK_MDP_RDMA:      Read DMA
- * @MTK_MDP_RSZ:       Riszer
- * @MTK_MDP_WDMA:      Write DMA
- * @MTK_MDP_WROT:      Write DMA with rotation
- */
-enum mtk_mdp_comp_type {
-       MTK_MDP_RDMA,
-       MTK_MDP_RSZ,
-       MTK_MDP_WDMA,
-       MTK_MDP_WROT,
-};
-
 /**
  * struct mtk_mdp_comp - the MDP's function component data
  * @node:      list node to track sibing MDP components
- * @dev_node:  component device node
  * @clk:       clocks required for component
  * @larb_dev:  SMI device required for component
- * @type:      component type
  */
 struct mtk_mdp_comp {
        struct list_head        node;
-       struct device_node      *dev_node;
        struct clk              *clk[2];
        struct device           *larb_dev;
-       enum mtk_mdp_comp_type  type;
 };

-int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
-                     struct mtk_mdp_comp *comp,
-                     enum mtk_mdp_comp_type comp_type);
-void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev);
+
 int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
 void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);

+extern struct platform_driver mtk_mdp_component_driver;

 #endif /* __MTK_MDP_COMP_H__ */
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 412bbec0f735..b813a822439a 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -6,6 +6,7 @@
  */

 #include <linux/clk.h>
+#include <linux/component.h>
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
@@ -19,6 +20,7 @@
 #include <linux/workqueue.h>
 #include <soc/mediatek/smi.h>

+#include "mtk_mdp_comp.h"
 #include "mtk_mdp_core.h"
 #include "mtk_mdp_m2m.h"
 #include "mtk_vpu.h"
@@ -32,16 +34,12 @@ module_param(mtk_mdp_dbg_level, int, 0644);
 static const struct of_device_id mtk_mdp_comp_dt_ids[] = {
        {
                .compatible = "mediatek,mt8173-mdp-rdma",
-               .data = (void *)MTK_MDP_RDMA
        }, {
                .compatible = "mediatek,mt8173-mdp-rsz",
-               .data = (void *)MTK_MDP_RSZ
        }, {
                .compatible = "mediatek,mt8173-mdp-wdma",
-               .data = (void *)MTK_MDP_WDMA
        }, {
                .compatible = "mediatek,mt8173-mdp-wrot",
-               .data = (void *)MTK_MDP_WROT
        },
        { },
 };
@@ -106,6 +104,63 @@ static void mtk_mdp_reset_handler(void *priv)
        queue_work(mdp->wdt_wq, &mdp->wdt_work);
 }

+static int compare_of(struct device *dev, void *data)
+{
+       return dev->of_node == data;
+}
+
+static void release_of(struct device *dev, void *data)
+{
+       of_node_put(data);
+}
+
+static int mtk_mdp_master_bind(struct device *dev)
+{
+       int status;
+       struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
+
+       mtk_mdp_register_component(mdp, &mdp->comp_self);
+
+       status = component_bind_all(dev, mdp);
+       if (status) {
+               dev_err(dev, "Failed to bind all components: %d\n", status);
+               goto err_component_bind_all;
+       }
+
+       status = mtk_mdp_register_m2m_device(mdp);
+       if (status) {
+               dev_err(dev, "Failed to register m2m device: %d\n", status);
+               goto err_mtk_mdp_register_m2m_device;
+       }
+
+       pm_runtime_enable(dev);
+
+       return 0;
+
+err_mtk_mdp_register_m2m_device:
+       component_unbind_all(dev, mdp);
+
+err_component_bind_all:
+       mtk_mdp_unregister_component(mdp, &mdp->comp_self);
+
+       return status;
+}
+
+static void mtk_mdp_master_unbind(struct device *dev)
+{
+       struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
+
+       pm_runtime_disable(dev);
+       mtk_mdp_unregister_m2m_device(mdp);
+       component_unbind_all(dev, mdp);
+       mtk_mdp_unregister_component(mdp, &mdp->comp_self);
+}
+
+static const struct component_master_ops mtk_mdp_com_ops = {
+       .bind           = mtk_mdp_master_bind,
+       .unbind         = mtk_mdp_master_unbind,
+};
+
 void mtk_mdp_register_component(struct mtk_mdp_dev *mdp,
                                struct mtk_mdp_comp *comp)
 {
@@ -123,8 +178,8 @@ static int mtk_mdp_probe(struct platform_device *pdev)
        struct mtk_mdp_dev *mdp;
        struct device *dev = &pdev->dev;
        struct device_node *node, *parent;
-       struct mtk_mdp_comp *comp, *comp_temp;
-       int ret = 0;
+       int i, ret = 0;
+       struct component_match *match = NULL;

        mdp = devm_kzalloc(dev, sizeof(*mdp), GFP_KERNEL);
        if (!mdp)
@@ -149,36 +204,43 @@ static int mtk_mdp_probe(struct platform_device *pdev)
        }

        /* Iterate over sibling MDP function blocks */
+       i = 0;
        for_each_child_of_node(parent, node) {
-               const struct of_device_id *of_id;
-               enum mtk_mdp_comp_type comp_type;
+               struct platform_device *pdev;

-               of_id = of_match_node(mtk_mdp_comp_dt_ids, node);
-               if (!of_id)
+               if (!of_match_node(mtk_mdp_comp_dt_ids, node))
                        continue;

-               if (!of_device_is_available(node)) {
-                       dev_err(dev, "Skipping disabled component %pOF\n",
-                               node);
+               if (!of_device_is_available(node))
                        continue;
-               }
-
-               comp_type = (enum mtk_mdp_comp_type)of_id->data;

-               comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
-               if (!comp) {
-                       ret = -ENOMEM;
-                       of_node_put(node);
-                       goto err_comp;
+               pdev = of_find_device_by_node(node);
+               if (!pdev) {
+                       dev_warn(dev, "Unable to find comp device %s\n",
+                                node->full_name);
+                       continue;
                }

-               ret = mtk_mdp_comp_init(dev, node, comp, comp_type);
-               if (ret) {
-                       of_node_put(node);
-                       goto err_comp;
+               /*
+                * Do not add a match for my own (rdma0) device node.
+                * I will be managing it directly instead using comp_self.
+                */
+               if (&pdev->dev != dev) {
+                       dev_dbg(dev, "adding match %d for: %pOF\n", i++, node);
+                       component_match_add_release(dev, &match, release_of,
+                                                   compare_of,
+                                                   of_node_get(node));
                }
+       }

-               mtk_mdp_register_component(mdp, comp);
+       /*
+        * Create a component for myself so that clocks can be toggled in
+        * clock_on().
+        */
+       ret = mtk_mdp_comp_init(&mdp->comp_self, dev);
+       if (ret) {
+               dev_err(dev, "Failed to initialize component\n");
+               goto err_comp;
        }

        mdp->job_wq = create_singlethread_workqueue(MTK_MDP_MODULE_NAME);
@@ -203,18 +265,12 @@ static int mtk_mdp_probe(struct platform_device *pdev)
                goto err_dev_register;
        }

-       ret = mtk_mdp_register_m2m_device(mdp);
-       if (ret) {
-               v4l2_err(&mdp->v4l2_dev, "Failed to init mem2mem device\n");
-               goto err_m2m_register;
-       }
-
        mdp->vpu_dev = vpu_get_plat_device(pdev);
        ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
                                  VPU_RST_MDP);
        if (ret) {
                dev_err(&pdev->dev, "Failed to register reset handler\n");
-               goto err_m2m_register;
+               goto err_wdt_reg;
        }

        platform_set_drvdata(pdev, mdp);
@@ -222,15 +278,25 @@ static int mtk_mdp_probe(struct platform_device *pdev)
        ret = vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
        if (ret) {
                dev_err(&pdev->dev, "Failed to set vb2 dma mag seg size\n");
-               goto err_m2m_register;
+               goto err_set_max_seg_size;
+       }
+
+       ret = component_master_add_with_match(dev, &mtk_mdp_com_ops, match);
+       if (ret) {
+               dev_err(dev, "Component master add failed\n");
+               goto err_component_master_add;
        }

-       pm_runtime_enable(dev);
        dev_dbg(dev, "mdp-%d registered successfully\n", mdp->id);

        return 0;

-err_m2m_register:
+err_component_master_add:
+       vb2_dma_contig_clear_max_seg_size(&pdev->dev);
+
+err_set_max_seg_size:
+
+err_wdt_reg:
        v4l2_device_unregister(&mdp->v4l2_dev);

 err_dev_register:
@@ -242,11 +308,6 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 err_alloc_job_wq:

 err_comp:
-       list_for_each_entry_safe(comp, comp_temp, &mdp->comp_list, node) {
-               mtk_mdp_unregister_component(mdp, comp);
-               mtk_mdp_comp_deinit(dev, comp);
-       }
-
        dev_dbg(dev, "err %d\n", ret);
        return ret;
 }
@@ -254,11 +315,10 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 static int mtk_mdp_remove(struct platform_device *pdev)
 {
        struct mtk_mdp_dev *mdp = platform_get_drvdata(pdev);
-       struct mtk_mdp_comp *comp, *comp_temp;

-       pm_runtime_disable(&pdev->dev);
+       component_master_del(&pdev->dev, &mtk_mdp_com_ops);
+
        vb2_dma_contig_clear_max_seg_size(&pdev->dev);
-       mtk_mdp_unregister_m2m_device(mdp);
        v4l2_device_unregister(&mdp->v4l2_dev);

        flush_workqueue(mdp->wdt_wq);
@@ -267,10 +327,8 @@ static int mtk_mdp_remove(struct platform_device *pdev)
        flush_workqueue(mdp->job_wq);
        destroy_workqueue(mdp->job_wq);

-       list_for_each_entry_safe(comp, comp_temp, &mdp->comp_list, node) {
-               mtk_mdp_unregister_component(mdp, comp);
-               mtk_mdp_comp_deinit(&pdev->dev, comp);
-       }
+       if (!list_empty(&mdp->comp_list))
+               dev_warn(&pdev->dev, "not all components removed\n");

        dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name);
        return 0;
@@ -323,7 +381,25 @@ static struct platform_driver mtk_mdp_driver = {
        }
 };

-module_platform_driver(mtk_mdp_driver);
+static struct platform_driver * const mtk_mdp_drivers[] = {
+       &mtk_mdp_driver,
+       &mtk_mdp_component_driver,
+};
+
+static int __init mtk_mdp_init(void)
+{
+       return platform_register_drivers(mtk_mdp_drivers,
+                                        ARRAY_SIZE(mtk_mdp_drivers));
+}
+
+static void __exit mtk_mdp_exit(void)
+{
+       platform_unregister_drivers(mtk_mdp_drivers,
+                                   ARRAY_SIZE(mtk_mdp_drivers));
+}
+
+module_init(mtk_mdp_init);
+module_exit(mtk_mdp_exit);

 MODULE_AUTHOR("Houlong Wei <houlong.wei@mediatek.com>");
 MODULE_DESCRIPTION("Mediatek image processor driver");
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
index a6e6dc36307b..8a52539b15d4 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
@@ -155,6 +155,7 @@ struct mtk_mdp_dev {
        struct mtk_mdp_variant          *variant;
        u16                             id;
        struct list_head                comp_list;
+       struct mtk_mdp_comp             comp_self;
        struct v4l2_m2m_dev             *m2m_dev;
        struct list_head                ctx_list;
        struct video_device             *vdev;
--
2.32.0.554.ge1b32706d8-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 2/9] mtk-mdp: add driver to probe mdp components

From: Dafna Hirschfeld <hidden>
Date: 2021-08-05 06:41:00


On 02.08.21 14:12, Eizan Miyamoto wrote:
quoted hunk
Broadly, this patch (1) adds a driver for various MTK MDP components to
go alongside the main MTK MDP driver, and (2) hooks them all together
using the component framework.

(1) Up until now, the MTK MDP driver controls 8 devices in the device
tree on its own. When running tests for the hardware video decoder, we
found that the iommus and LARBs were not being properly configured. To
configure them, a driver for each be added to mtk_mdp_comp so that
mtk_iommu_add_device() can (eventually) be called from dma_configure()
inside really_probe().

(2) The integration into the component framework allows us to defer the
registration with the v4l2 subsystem until all the MDP-related devices
have been probed, so that the relevant device node does not become
available until initialization of all the components is complete.

Some notes about how the component framework has been integrated:

- The driver for the rdma0 component serves double duty as the "master"
   (aggregate) driver as well as a component driver. This is a non-ideal
   compromise until a better solution is developed. This device is
   differentiated from the rest by checking for a "mediatek,vpu" property
   in the device node.

- The list of mdp components remains hard-coded as mtk_mdp_comp_dt_ids[]
   in mtk_mdp_core.c, and as mtk_mdp_comp_driver_dt_match[] in
   mtk_mdp_comp.c. This unfortunate duplication of information is
   addressed in a following patch in this series.

- The component driver calls component_add() for each device that is
   probed.

- In mtk_mdp_probe (the "master" device), we scan the device tree for
   any matching nodes against mtk_mdp_comp_dt_ids, and add component
   matches for them. The match criteria is a matching device node
   pointer.

- When the set of components devices that have been probed corresponds
   with the list that is generated by the "master", the callback to
   mtk_mdp_master_bind() is made, which then calls the component bind
   functions.

- Inside mtk_mdp_master_bind(), once all the component bind functions
   have been called, we can then register our device to the v4l2
   subsystem.

- The call to pm_runtime_enable() in the master device is called after
   all the components have been registered by their bind() functions
   called by mtk_mtp_master_bind(). As a result, the list of components
   will not change while power management callbacks mtk_mdp_suspend()/
   resume() are accessing the list of components.

Signed-off-by: Eizan Miyamoto <redacted>
---

(no changes since v1)

  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 143 ++++++++++++--
  drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  25 +--
  drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 174 +++++++++++++-----
  drivers/media/platform/mtk-mdp/mtk_mdp_core.h |   1 +
  4 files changed, 252 insertions(+), 91 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 76e295c8d9bc..7a0e3acffab9 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -5,13 +5,50 @@
   */
  
  #include <linux/clk.h>
+#include <linux/component.h>
  #include <linux/device.h>
  #include <linux/of.h>
+#include <linux/module.h>
  #include <linux/of_address.h>
  #include <linux/of_platform.h>
  #include <soc/mediatek/smi.h>
  
  #include "mtk_mdp_comp.h"
+#include "mtk_mdp_core.h"
+
+/**
+ * enum mtk_mdp_comp_type - the MDP component
+ * @MTK_MDP_RDMA:		Read DMA
+ * @MTK_MDP_RSZ:		Reszer
+ * @MTK_MDP_WDMA:		Write DMA
+ * @MTK_MDP_WROT:		Write DMA with rotation
+ * @MTK_MDP_COMP_TYPE_MAX:	Placeholder for num elems in this enum
+ */
+enum mtk_mdp_comp_type {
+	MTK_MDP_RDMA,
+	MTK_MDP_RSZ,
+	MTK_MDP_WDMA,
+	MTK_MDP_WROT,
+	MTK_MDP_COMP_TYPE_MAX,
+};
+
+static const struct of_device_id mtk_mdp_comp_driver_dt_match[] = {
+	{
+		.compatible = "mediatek,mt8173-mdp-rdma",
+		.data = (void *)MTK_MDP_RDMA
+	}, {
+		.compatible = "mediatek,mt8173-mdp-rsz",
+		.data = (void *)MTK_MDP_RSZ
+	}, {
+		.compatible = "mediatek,mt8173-mdp-wdma",
+		.data = (void *)MTK_MDP_WDMA
+	}, {
+		.compatible = "mediatek,mt8173-mdp-wrot",
+		.data = (void *)MTK_MDP_WROT
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mtk_mdp_comp_driver_dt_match);
  
  int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
  {
@@ -20,9 +57,7 @@ int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
  	if (comp->larb_dev) {
  		err = mtk_smi_larb_get(comp->larb_dev);
  		if (err)
-			dev_err(dev,
-				"failed to get larb, err %d. type:%d\n",
-				err, comp->type);
+			dev_err(dev, "failed to get larb, err %d.\n", err);
  	}
  
  	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
@@ -62,17 +97,41 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
  		mtk_smi_larb_put(comp->larb_dev);
  }
  
-int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
-		      struct mtk_mdp_comp *comp,
-		      enum mtk_mdp_comp_type comp_type)
+static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
+{
+	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
+	struct mtk_mdp_dev *mdp = data;
+
+	mtk_mdp_register_component(mdp, comp);
+
+	return 0;
+}
+
+static void mtk_mdp_comp_unbind(struct device *dev, struct device *master,
+			   void *data)
+{
+	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
+	struct mtk_mdp_dev *mdp = data;
+
+	mtk_mdp_unregister_component(mdp, comp);
+}
+
+static const struct component_ops mtk_mdp_component_ops = {
+	.bind   = mtk_mdp_comp_bind,
+	.unbind = mtk_mdp_comp_unbind,
+};
+
+int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
This function can be static
  {
  	struct device_node *larb_node;
  	struct platform_device *larb_pdev;
  	int ret;
  	int i;
+	struct device_node *node = dev->of_node;
+	enum mtk_mdp_comp_type comp_type =
+		 (enum mtk_mdp_comp_type)of_device_get_match_data(dev);
  
-	comp->dev_node = of_node_get(node);
-	comp->type = comp_type;
+	INIT_LIST_HEAD(&comp->node);
  
  	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
  		comp->clk[i] = of_clk_get(node, i);
that iteration can be replaced with clk_bulk_get
quoted hunk
@@ -80,19 +139,17 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
  			if (PTR_ERR(comp->clk[i]) != -EPROBE_DEFER)
  				dev_err(dev, "Failed to get clock\n");
  			ret = PTR_ERR(comp->clk[i]);
-			goto put_dev;
+			goto err;
  		}
  
  		/* Only RDMA needs two clocks */
-		if (comp->type != MTK_MDP_RDMA)
+		if (comp_type != MTK_MDP_RDMA)
  			break;
  	}
  
  	/* Only DMA capable components need the LARB property */
  	comp->larb_dev = NULL;
-	if (comp->type != MTK_MDP_RDMA &&
-	    comp->type != MTK_MDP_WDMA &&
-	    comp->type != MTK_MDP_WROT)
+	if (comp_type != MTK_MDP_RDMA && comp_type != MTK_MDP_WDMA && comp_type != MTK_MDP_WROT)
  		return 0;
  
  	larb_node = of_parse_phandle(node, "mediatek,larb", 0);
@@ -100,7 +157,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
  		dev_err(dev,
  			"Missing mediadek,larb phandle in %pOF node\n", node);
  		ret = -EINVAL;
-		goto put_dev;
+		goto err;
  	}
  
  	larb_pdev = of_find_device_by_node(larb_node);
@@ -108,7 +165,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
  		dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
  		of_node_put(larb_node);
  		ret = -EPROBE_DEFER;
-		goto put_dev;
+		goto err;
  	}
  	of_node_put(larb_node);
  
@@ -116,13 +173,59 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
  
  	return 0;
  
-put_dev:
-	of_node_put(comp->dev_node);
-
+err:
  	return ret;
  }
  
-void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp)
+static int mtk_mdp_comp_probe(struct platform_device *pdev)
  {
-	of_node_put(comp->dev_node);
+	struct device *dev = &pdev->dev;
+	struct device_node *vpu_node;
+	int status;
+	struct mtk_mdp_comp *comp;
+
+	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
+	if (vpu_node) {
+		of_node_put(vpu_node);
+		/*
+		 * The device tree node with a mediatek,vpu property is deemed
+		 * the MDP "master" device, we don't want to add a component
+		 * for it in this function because the initialization for the
+		 * master is done elsewhere.
+		 */
+		dev_info(dev, "vpu node found, not probing\n");
+		return -ENODEV;
+	}
+
+	comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
+	if (!comp)
+		return -ENOMEM;
+
+	status = mtk_mdp_comp_init(comp, dev);
+	if (status) {
+		dev_err(dev, "Failed to initialize component: %d\n", status);
+		return status;
+	}
+
+	dev_set_drvdata(dev, comp);
+
+	return component_add(dev, &mtk_mdp_component_ops);
  }
+
+static int mtk_mdp_comp_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	component_del(dev, &mtk_mdp_component_ops);
+	return 0;
+}
+
+struct platform_driver mtk_mdp_component_driver = {
+	.probe          = mtk_mdp_comp_probe,
+	.remove         = mtk_mdp_comp_remove,
+	.driver         = {
+		.name   = "mediatek-mdp-comp",
+		.owner  = THIS_MODULE,
+		.of_match_table = mtk_mdp_comp_driver_dt_match,
+	},
+};
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index 92ab5249bcad..df5fc4c94f90 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -7,42 +7,23 @@
  #ifndef __MTK_MDP_COMP_H__
  #define __MTK_MDP_COMP_H__
  
-/**
- * enum mtk_mdp_comp_type - the MDP component
- * @MTK_MDP_RDMA:	Read DMA
- * @MTK_MDP_RSZ:	Riszer
- * @MTK_MDP_WDMA:	Write DMA
- * @MTK_MDP_WROT:	Write DMA with rotation
- */
-enum mtk_mdp_comp_type {
-	MTK_MDP_RDMA,
-	MTK_MDP_RSZ,
-	MTK_MDP_WDMA,
-	MTK_MDP_WROT,
-};
-
  /**
   * struct mtk_mdp_comp - the MDP's function component data
   * @node:	list node to track sibing MDP components
- * @dev_node:	component device node
   * @clk:	clocks required for component
   * @larb_dev:	SMI device required for component
- * @type:	component type
   */
  struct mtk_mdp_comp {
  	struct list_head	node;
-	struct device_node	*dev_node;
  	struct clk		*clk[2];
  	struct device		*larb_dev;
-	enum mtk_mdp_comp_type	type;
  };
  
-int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
-		      struct mtk_mdp_comp *comp,
-		      enum mtk_mdp_comp_type comp_type);
-void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev);
+
  int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
  void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);
  
+extern struct platform_driver mtk_mdp_component_driver;
  
  #endif /* __MTK_MDP_COMP_H__ */
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 412bbec0f735..b813a822439a 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -6,6 +6,7 @@
   */
  
  #include <linux/clk.h>
+#include <linux/component.h>
  #include <linux/device.h>
  #include <linux/errno.h>
  #include <linux/interrupt.h>
@@ -19,6 +20,7 @@
  #include <linux/workqueue.h>
  #include <soc/mediatek/smi.h>
  
+#include "mtk_mdp_comp.h"
  #include "mtk_mdp_core.h"
  #include "mtk_mdp_m2m.h"
  #include "mtk_vpu.h"
@@ -32,16 +34,12 @@ module_param(mtk_mdp_dbg_level, int, 0644);
  static const struct of_device_id mtk_mdp_comp_dt_ids[] = {
  	{
  		.compatible = "mediatek,mt8173-mdp-rdma",
-		.data = (void *)MTK_MDP_RDMA
  	}, {
  		.compatible = "mediatek,mt8173-mdp-rsz",
-		.data = (void *)MTK_MDP_RSZ
  	}, {
  		.compatible = "mediatek,mt8173-mdp-wdma",
-		.data = (void *)MTK_MDP_WDMA
  	}, {
  		.compatible = "mediatek,mt8173-mdp-wrot",
-		.data = (void *)MTK_MDP_WROT
  	},
  	{ },
  };
@@ -106,6 +104,63 @@ static void mtk_mdp_reset_handler(void *priv)
  	queue_work(mdp->wdt_wq, &mdp->wdt_work);
  }
  
+static int compare_of(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static void release_of(struct device *dev, void *data)
+{
+	of_node_put(data);
+}
+
+static int mtk_mdp_master_bind(struct device *dev)
+{
+	int status;
+	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
+
+	mtk_mdp_register_component(mdp, &mdp->comp_self);
+
+	status = component_bind_all(dev, mdp);
+	if (status) {
+		dev_err(dev, "Failed to bind all components: %d\n", status);
+		goto err_component_bind_all;
+	}
+
+	status = mtk_mdp_register_m2m_device(mdp);
+	if (status) {
+		dev_err(dev, "Failed to register m2m device: %d\n", status);
+		goto err_mtk_mdp_register_m2m_device;
+	}
+
+	pm_runtime_enable(dev);
+
+	return 0;
+
+err_mtk_mdp_register_m2m_device:
+	component_unbind_all(dev, mdp);
+
+err_component_bind_all:
+	mtk_mdp_unregister_component(mdp, &mdp->comp_self);
+
+	return status;
+}
+
+static void mtk_mdp_master_unbind(struct device *dev)
+{
+	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
+
+	pm_runtime_disable(dev);
+	mtk_mdp_unregister_m2m_device(mdp);
+	component_unbind_all(dev, mdp);
+	mtk_mdp_unregister_component(mdp, &mdp->comp_self);
+}
+
+static const struct component_master_ops mtk_mdp_com_ops = {
+	.bind		= mtk_mdp_master_bind,
+	.unbind		= mtk_mdp_master_unbind,
+};
+
  void mtk_mdp_register_component(struct mtk_mdp_dev *mdp,
  				struct mtk_mdp_comp *comp)
  {
@@ -123,8 +178,8 @@ static int mtk_mdp_probe(struct platform_device *pdev)
  	struct mtk_mdp_dev *mdp;
  	struct device *dev = &pdev->dev;
  	struct device_node *node, *parent;
-	struct mtk_mdp_comp *comp, *comp_temp;
-	int ret = 0;
+	int i, ret = 0;
+	struct component_match *match = NULL;
  
  	mdp = devm_kzalloc(dev, sizeof(*mdp), GFP_KERNEL);
  	if (!mdp)
@@ -149,36 +204,43 @@ static int mtk_mdp_probe(struct platform_device *pdev)
  	}
  
  	/* Iterate over sibling MDP function blocks */
+	i = 0;
  	for_each_child_of_node(parent, node) {
-		const struct of_device_id *of_id;
-		enum mtk_mdp_comp_type comp_type;
+		struct platform_device *pdev;
  
-		of_id = of_match_node(mtk_mdp_comp_dt_ids, node);
-		if (!of_id)
+		if (!of_match_node(mtk_mdp_comp_dt_ids, node))
  			continue;
  
-		if (!of_device_is_available(node)) {
-			dev_err(dev, "Skipping disabled component %pOF\n",
-				node);
+		if (!of_device_is_available(node))
  			continue;
-		}
-
-		comp_type = (enum mtk_mdp_comp_type)of_id->data;
  
-		comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
-		if (!comp) {
-			ret = -ENOMEM;
-			of_node_put(node);
-			goto err_comp;
+		pdev = of_find_device_by_node(node);
+		if (!pdev) {
+			dev_warn(dev, "Unable to find comp device %s\n",
+				 node->full_name);
+			continue;
  		}
  
-		ret = mtk_mdp_comp_init(dev, node, comp, comp_type);
-		if (ret) {
-			of_node_put(node);
-			goto err_comp;
+		/*
+		 * Do not add a match for my own (rdma0) device node.
+		 * I will be managing it directly instead using comp_self.
+		 */
+		if (&pdev->dev != dev) {
+			dev_dbg(dev, "adding match %d for: %pOF\n", i++, node);
+			component_match_add_release(dev, &match, release_of,
+						    compare_of,
+						    of_node_get(node));
  		}
+	}
  
-		mtk_mdp_register_component(mdp, comp);
+	/*
+	 * Create a component for myself so that clocks can be toggled in
+	 * clock_on().
+	 */
+	ret = mtk_mdp_comp_init(&mdp->comp_self, dev);
+	if (ret) {
+		dev_err(dev, "Failed to initialize component\n");
+		goto err_comp;
  	}
  
  	mdp->job_wq = create_singlethread_workqueue(MTK_MDP_MODULE_NAME);
@@ -203,18 +265,12 @@ static int mtk_mdp_probe(struct platform_device *pdev)
  		goto err_dev_register;
  	}
  
-	ret = mtk_mdp_register_m2m_device(mdp);
-	if (ret) {
-		v4l2_err(&mdp->v4l2_dev, "Failed to init mem2mem device\n");
-		goto err_m2m_register;
-	}
-
  	mdp->vpu_dev = vpu_get_plat_device(pdev);
  	ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
  				  VPU_RST_MDP);
  	if (ret) {
  		dev_err(&pdev->dev, "Failed to register reset handler\n");
-		goto err_m2m_register;
+		goto err_wdt_reg;
  	}
  
  	platform_set_drvdata(pdev, mdp);
@@ -222,15 +278,25 @@ static int mtk_mdp_probe(struct platform_device *pdev)
  	ret = vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
  	if (ret) {
  		dev_err(&pdev->dev, "Failed to set vb2 dma mag seg size\n");
-		goto err_m2m_register;
+		goto err_set_max_seg_size;
+	}
+
+	ret = component_master_add_with_match(dev, &mtk_mdp_com_ops, match);
+	if (ret) {
+		dev_err(dev, "Component master add failed\n");
+		goto err_component_master_add;
  	}
  
-	pm_runtime_enable(dev);
  	dev_dbg(dev, "mdp-%d registered successfully\n", mdp->id);
  
  	return 0;
  
-err_m2m_register:
+err_component_master_add:
+	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
+
+err_set_max_seg_size:
+
+err_wdt_reg:
  	v4l2_device_unregister(&mdp->v4l2_dev);
  
  err_dev_register:
@@ -242,11 +308,6 @@ static int mtk_mdp_probe(struct platform_device *pdev)
  err_alloc_job_wq:
  
  err_comp:
-	list_for_each_entry_safe(comp, comp_temp, &mdp->comp_list, node) {
-		mtk_mdp_unregister_component(mdp, comp);
-		mtk_mdp_comp_deinit(dev, comp);
-	}
-
  	dev_dbg(dev, "err %d\n", ret);
  	return ret;
  }
@@ -254,11 +315,10 @@ static int mtk_mdp_probe(struct platform_device *pdev)
  static int mtk_mdp_remove(struct platform_device *pdev)
  {
  	struct mtk_mdp_dev *mdp = platform_get_drvdata(pdev);
-	struct mtk_mdp_comp *comp, *comp_temp;
  
-	pm_runtime_disable(&pdev->dev);
+	component_master_del(&pdev->dev, &mtk_mdp_com_ops);
+
  	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
-	mtk_mdp_unregister_m2m_device(mdp);
  	v4l2_device_unregister(&mdp->v4l2_dev);
  
  	flush_workqueue(mdp->wdt_wq);
@@ -267,10 +327,8 @@ static int mtk_mdp_remove(struct platform_device *pdev)
  	flush_workqueue(mdp->job_wq);
  	destroy_workqueue(mdp->job_wq);
  
-	list_for_each_entry_safe(comp, comp_temp, &mdp->comp_list, node) {
-		mtk_mdp_unregister_component(mdp, comp);
-		mtk_mdp_comp_deinit(&pdev->dev, comp);
-	}
+	if (!list_empty(&mdp->comp_list))
+		dev_warn(&pdev->dev, "not all components removed\n");
  
  	dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name);
  	return 0;
@@ -323,7 +381,25 @@ static struct platform_driver mtk_mdp_driver = {
  	}
  };
  
-module_platform_driver(mtk_mdp_driver);
+static struct platform_driver * const mtk_mdp_drivers[] = {
+	&mtk_mdp_driver,
+	&mtk_mdp_component_driver,
+};
+
+static int __init mtk_mdp_init(void)
+{
+	return platform_register_drivers(mtk_mdp_drivers,
+					 ARRAY_SIZE(mtk_mdp_drivers));
+}
+
+static void __exit mtk_mdp_exit(void)
+{
+	platform_unregister_drivers(mtk_mdp_drivers,
+				    ARRAY_SIZE(mtk_mdp_drivers));
+}
+
+module_init(mtk_mdp_init);
+module_exit(mtk_mdp_exit);
  
  MODULE_AUTHOR("Houlong Wei <houlong.wei@mediatek.com>");
  MODULE_DESCRIPTION("Mediatek image processor driver");
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
index a6e6dc36307b..8a52539b15d4 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
@@ -155,6 +155,7 @@ struct mtk_mdp_dev {
  	struct mtk_mdp_variant		*variant;
  	u16				id;
  	struct list_head		comp_list;
+	struct mtk_mdp_comp		comp_self;
  	struct v4l2_m2m_dev		*m2m_dev;
  	struct list_head		ctx_list;
  	struct video_device		*vdev;
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 2/9] mtk-mdp: add driver to probe mdp components

From: Eizan Miyamoto <hidden>
Date: 2021-08-09 03:24:01

Hi Dafna,

On Thu, Aug 5, 2021 at 4:40 PM Dafna Hirschfeld
[off-list ref] wrote:
quoted
+int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
This function can be static
If it's all the same to you, are you okay for me to make this change either:
- If upstream requests changes be made to this series, I will include
this suggestion
- If the series is accepted as-is, I will make a follow-up patch

This is to reduce workload on reviewers having to re-ack changes for
(what I hope you agree is) a nit.

If you don't agree, I will happily oblige and make the change and
upload a new version of the series.
quoted
      for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
              comp->clk[i] = of_clk_get(node, i);
that iteration can be replaced with clk_bulk_get
As per Enric's suggestion in response to "propagate errors from
clock_on" in this series, are you okay for me to make the change in a
follow-up patch?

Thanks again for your review,

Eizan

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 2/9] mtk-mdp: add driver to probe mdp components

From: Dafna Hirschfeld <hidden>
Date: 2021-08-09 07:53:41


On 09.08.21 05:23, Eizan Miyamoto wrote:
Hi Dafna,

On Thu, Aug 5, 2021 at 4:40 PM Dafna Hirschfeld
[off-list ref] wrote:
quoted
quoted
+int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
This function can be static
If it's all the same to you, are you okay for me to make this change either:
- If upstream requests changes be made to this series, I will include
this suggestion
- If the series is accepted as-is, I will make a follow-up patch

This is to reduce workload on reviewers having to re-ack changes for
(what I hope you agree is) a nit.
I think you can keep the review-by tag of the reviewers since this is just a nit.
So sending a new version won't need a re-ack from the reviewers.

You can send it also as a separate patch. I don't care too much.
If you don't agree, I will happily oblige and make the change and
upload a new version of the series.
quoted
quoted
       for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
               comp->clk[i] = of_clk_get(node, i);
that iteration can be replaced with clk_bulk_get
As per Enric's suggestion in response to "propagate errors from
clock_on" in this series, are you okay for me to make the change in a
follow-up patch?
yes,

Thanks,
Dafna
Thanks again for your review,

Eizan
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 2/9] mtk-mdp: add driver to probe mdp components

From: Eizan Miyamoto <hidden>
Date: 2021-08-11 11:15:48

Hi Dafna,

On Mon, Aug 9, 2021 at 5:53 PM Dafna Hirschfeld
[off-list ref] wrote:
You can send it also as a separate patch. I don't care too much.
Great. I've sent a separate patch to make mtk_mdp_comp_init static in
https://patchwork.kernel.org/project/linux-mediatek/list/?series=529639

I will continue with further work to use the clk_blk_* API.

Thanks,

Eizan

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 2/9] mtk-mdp: add driver to probe mdp components

From: houlong wei <houlong.wei@mediatek.com>
Date: 2021-08-16 01:06:08

On Mon, 2021-08-02 at 20:12 +0800, Eizan Miyamoto wrote:
Broadly, this patch (1) adds a driver for various MTK MDP components
to
go alongside the main MTK MDP driver, and (2) hooks them all together
using the component framework.

(1) Up until now, the MTK MDP driver controls 8 devices in the device
tree on its own. When running tests for the hardware video decoder,
we
found that the iommus and LARBs were not being properly configured.
To
configure them, a driver for each be added to mtk_mdp_comp so that
mtk_iommu_add_device() can (eventually) be called from
dma_configure()
inside really_probe().

(2) The integration into the component framework allows us to defer
the
registration with the v4l2 subsystem until all the MDP-related
devices
have been probed, so that the relevant device node does not become
available until initialization of all the components is complete.

Some notes about how the component framework has been integrated:

- The driver for the rdma0 component serves double duty as the
"master"
  (aggregate) driver as well as a component driver. This is a non-
ideal
  compromise until a better solution is developed. This device is
  differentiated from the rest by checking for a "mediatek,vpu"
property
  in the device node.

- The list of mdp components remains hard-coded as
mtk_mdp_comp_dt_ids[]
  in mtk_mdp_core.c, and as mtk_mdp_comp_driver_dt_match[] in
  mtk_mdp_comp.c. This unfortunate duplication of information is
  addressed in a following patch in this series.

- The component driver calls component_add() for each device that is
  probed.

- In mtk_mdp_probe (the "master" device), we scan the device tree for
  any matching nodes against mtk_mdp_comp_dt_ids, and add component
  matches for them. The match criteria is a matching device node
  pointer.

- When the set of components devices that have been probed
corresponds
  with the list that is generated by the "master", the callback to
  mtk_mdp_master_bind() is made, which then calls the component bind
  functions.

- Inside mtk_mdp_master_bind(), once all the component bind functions
  have been called, we can then register our device to the v4l2
  subsystem.

- The call to pm_runtime_enable() in the master device is called
after
  all the components have been registered by their bind() functions
  called by mtk_mtp_master_bind(). As a result, the list of
components
  will not change while power management callbacks mtk_mdp_suspend()/
  resume() are accessing the list of components.

Signed-off-by: Eizan Miyamoto <redacted>
---
Reviewed-by: Houlong Wei <houlong.wei@mediatek.com>
(no changes since v1)
[...]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

[PATCH v6 3/9] mtk-mdp: use pm_runtime in MDP component driver

From: Eizan Miyamoto <hidden>
Date: 2021-08-02 12:12:57

Without this change, the MDP components are not fully integrated into
the runtime power management subsystem, and the MDP driver does not
work.

For each of the component device drivers to be able to call
pm_runtime_get/put_sync() a pointer to the component's device struct
had to be added to struct mtk_mdp_comp, set by mtk_mdp_comp_init().

Note that the dev argument to mtk_mdp_comp_clock_on/off() has been
removed. Those functions used to be called from the "master" mdp driver
in mtk_mdp_core.c, but the component's device pointer no longer
corresponds to the mdp master device pointer, which is not the right
device to pass to pm_runtime_put/get_sync() which we had to add to get
the driver to work properly.

Signed-off-by: Eizan Miyamoto <redacted>
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 24 +++++++++++++++----
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  6 +++--
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c |  7 +++---
 3 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 7a0e3acffab9..472c261b01e8 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -12,6 +12,7 @@
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <soc/mediatek/smi.h>
+#include <linux/pm_runtime.h>
 
 #include "mtk_mdp_comp.h"
 #include "mtk_mdp_core.h"
@@ -50,14 +51,22 @@ static const struct of_device_id mtk_mdp_comp_driver_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, mtk_mdp_comp_driver_dt_match);
 
-int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
+int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
 {
 	int i, err, status;
 
 	if (comp->larb_dev) {
 		err = mtk_smi_larb_get(comp->larb_dev);
 		if (err)
-			dev_err(dev, "failed to get larb, err %d.\n", err);
+			dev_err(comp->dev, "failed to get larb, err %d.\n", err);
+	}
+
+	err = pm_runtime_get_sync(comp->dev);
+	if (err < 0) {
+		dev_err(comp->dev,
+			"failed to runtime get, err %d.\n",
+			err);
+		return err;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
@@ -66,7 +75,7 @@ int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 		err = clk_prepare_enable(comp->clk[i]);
 		if (err) {
 			status = err;
-			dev_err(dev, "failed to enable clock, err %d. i:%d\n", err, i);
+			dev_err(comp->dev, "failed to enable clock, err %d. i:%d\n", err, i);
 			goto err_clk_prepare_enable;
 		}
 	}
@@ -80,10 +89,12 @@ int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 		clk_disable_unprepare(comp->clk[i]);
 	}
 
+	pm_runtime_put_sync(comp->dev);
+
 	return status;
 }
 
-void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
+int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
 {
 	int i;
 
@@ -95,6 +106,8 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
 
 	if (comp->larb_dev)
 		mtk_smi_larb_put(comp->larb_dev);
+
+	return pm_runtime_put_sync(comp->dev);
 }
 
 static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
@@ -103,6 +116,7 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
 	struct mtk_mdp_dev *mdp = data;
 
 	mtk_mdp_register_component(mdp, comp);
+	pm_runtime_enable(dev);
 
 	return 0;
 }
@@ -113,6 +127,7 @@ static void mtk_mdp_comp_unbind(struct device *dev, struct device *master,
 	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
 	struct mtk_mdp_dev *mdp = data;
 
+	pm_runtime_disable(dev);
 	mtk_mdp_unregister_component(mdp, comp);
 }
 
@@ -132,6 +147,7 @@ int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
 		 (enum mtk_mdp_comp_type)of_device_get_match_data(dev);
 
 	INIT_LIST_HEAD(&comp->node);
+	comp->dev = dev;
 
 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
 		comp->clk[i] = of_clk_get(node, i);
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index df5fc4c94f90..f2e22e7e7c45 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -12,17 +12,19 @@
  * @node:	list node to track sibing MDP components
  * @clk:	clocks required for component
  * @larb_dev:	SMI device required for component
+ * @dev:	component's device
  */
 struct mtk_mdp_comp {
 	struct list_head	node;
 	struct clk		*clk[2];
+	struct device		*dev;
 	struct device		*larb_dev;
 };
 
 int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev);
 
-int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
-void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp);
 
 extern struct platform_driver mtk_mdp_component_driver;
 
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index b813a822439a..714154450981 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -58,7 +58,7 @@ static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
 	int err;
 
 	list_for_each_entry(comp_node, &mdp->comp_list, node) {
-		err = mtk_mdp_comp_clock_on(dev, comp_node);
+		err = mtk_mdp_comp_clock_on(comp_node);
 		if (err) {
 			status = err;
 			goto err_mtk_mdp_comp_clock_on;
@@ -69,18 +69,17 @@ static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
 
 err_mtk_mdp_comp_clock_on:
 	list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node)
-		mtk_mdp_comp_clock_off(dev, comp_node);
+		mtk_mdp_comp_clock_off(comp_node);
 
 	return status;
 }
 
 static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
 {
-	struct device *dev = &mdp->pdev->dev;
 	struct mtk_mdp_comp *comp_node;
 
 	list_for_each_entry(comp_node, &mdp->comp_list, node)
-		mtk_mdp_comp_clock_off(dev, comp_node);
+		mtk_mdp_comp_clock_off(comp_node);
 }
 
 static void mtk_mdp_wdt_worker(struct work_struct *work)
-- 
2.32.0.554.ge1b32706d8-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 3/9] mtk-mdp: use pm_runtime in MDP component driver

From: Enric Balletbo Serra <eballetbo@gmail.com>
Date: 2021-08-03 10:27:06

Hi Eizan,

Thank you for your patch.

Missatge de Eizan Miyamoto [off-list ref] del dia dl., 2 d’ag.
2021 a les 14:14:
Without this change, the MDP components are not fully integrated into
the runtime power management subsystem, and the MDP driver does not
work.

For each of the component device drivers to be able to call
pm_runtime_get/put_sync() a pointer to the component's device struct
had to be added to struct mtk_mdp_comp, set by mtk_mdp_comp_init().

Note that the dev argument to mtk_mdp_comp_clock_on/off() has been
removed. Those functions used to be called from the "master" mdp driver
in mtk_mdp_core.c, but the component's device pointer no longer
corresponds to the mdp master device pointer, which is not the right
device to pass to pm_runtime_put/get_sync() which we had to add to get
the driver to work properly.

Signed-off-by: Eizan Miyamoto <redacted>
Reviewed-by: Enric Balletbo i Serra <redacted>

quoted hunk
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 24 +++++++++++++++----
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  6 +++--
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c |  7 +++---
 3 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 7a0e3acffab9..472c261b01e8 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -12,6 +12,7 @@
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <soc/mediatek/smi.h>
+#include <linux/pm_runtime.h>

 #include "mtk_mdp_comp.h"
 #include "mtk_mdp_core.h"
@@ -50,14 +51,22 @@ static const struct of_device_id mtk_mdp_comp_driver_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, mtk_mdp_comp_driver_dt_match);

-int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
+int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
 {
        int i, err, status;

        if (comp->larb_dev) {
                err = mtk_smi_larb_get(comp->larb_dev);
                if (err)
-                       dev_err(dev, "failed to get larb, err %d.\n", err);
+                       dev_err(comp->dev, "failed to get larb, err %d.\n", err);
+       }
+
+       err = pm_runtime_get_sync(comp->dev);
+       if (err < 0) {
+               dev_err(comp->dev,
+                       "failed to runtime get, err %d.\n",
+                       err);
+               return err;
        }

        for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
@@ -66,7 +75,7 @@ int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
                err = clk_prepare_enable(comp->clk[i]);
                if (err) {
                        status = err;
-                       dev_err(dev, "failed to enable clock, err %d. i:%d\n", err, i);
+                       dev_err(comp->dev, "failed to enable clock, err %d. i:%d\n", err, i);
                        goto err_clk_prepare_enable;
                }
        }
@@ -80,10 +89,12 @@ int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
                clk_disable_unprepare(comp->clk[i]);
        }

+       pm_runtime_put_sync(comp->dev);
+
        return status;
 }

-void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
+int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
 {
        int i;
@@ -95,6 +106,8 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)

        if (comp->larb_dev)
                mtk_smi_larb_put(comp->larb_dev);
+
+       return pm_runtime_put_sync(comp->dev);
 }

 static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
@@ -103,6 +116,7 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
        struct mtk_mdp_dev *mdp = data;

        mtk_mdp_register_component(mdp, comp);
+       pm_runtime_enable(dev);

        return 0;
 }
@@ -113,6 +127,7 @@ static void mtk_mdp_comp_unbind(struct device *dev, struct device *master,
        struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
        struct mtk_mdp_dev *mdp = data;

+       pm_runtime_disable(dev);
        mtk_mdp_unregister_component(mdp, comp);
 }
@@ -132,6 +147,7 @@ int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
                 (enum mtk_mdp_comp_type)of_device_get_match_data(dev);

        INIT_LIST_HEAD(&comp->node);
+       comp->dev = dev;

        for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
                comp->clk[i] = of_clk_get(node, i);
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index df5fc4c94f90..f2e22e7e7c45 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -12,17 +12,19 @@
  * @node:      list node to track sibing MDP components
  * @clk:       clocks required for component
  * @larb_dev:  SMI device required for component
+ * @dev:       component's device
  */
 struct mtk_mdp_comp {
        struct list_head        node;
        struct clk              *clk[2];
+       struct device           *dev;
        struct device           *larb_dev;
 };

 int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev);

-int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
-void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp);

 extern struct platform_driver mtk_mdp_component_driver;
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index b813a822439a..714154450981 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -58,7 +58,7 @@ static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
        int err;

        list_for_each_entry(comp_node, &mdp->comp_list, node) {
-               err = mtk_mdp_comp_clock_on(dev, comp_node);
+               err = mtk_mdp_comp_clock_on(comp_node);
                if (err) {
                        status = err;
                        goto err_mtk_mdp_comp_clock_on;
@@ -69,18 +69,17 @@ static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)

 err_mtk_mdp_comp_clock_on:
        list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node)
-               mtk_mdp_comp_clock_off(dev, comp_node);
+               mtk_mdp_comp_clock_off(comp_node);

        return status;
 }

 static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
 {
-       struct device *dev = &mdp->pdev->dev;
        struct mtk_mdp_comp *comp_node;

        list_for_each_entry(comp_node, &mdp->comp_list, node)
-               mtk_mdp_comp_clock_off(dev, comp_node);
+               mtk_mdp_comp_clock_off(comp_node);
 }

 static void mtk_mdp_wdt_worker(struct work_struct *work)
--
2.32.0.554.ge1b32706d8-goog


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 3/9] mtk-mdp: use pm_runtime in MDP component driver

From: houlong wei <houlong.wei@mediatek.com>
Date: 2021-08-16 01:07:57

On Mon, 2021-08-02 at 20:12 +0800, Eizan Miyamoto wrote:
Without this change, the MDP components are not fully integrated into
the runtime power management subsystem, and the MDP driver does not
work.

For each of the component device drivers to be able to call
pm_runtime_get/put_sync() a pointer to the component's device struct
had to be added to struct mtk_mdp_comp, set by mtk_mdp_comp_init().

Note that the dev argument to mtk_mdp_comp_clock_on/off() has been
removed. Those functions used to be called from the "master" mdp
driver
in mtk_mdp_core.c, but the component's device pointer no longer
corresponds to the mdp master device pointer, which is not the right
device to pass to pm_runtime_put/get_sync() which we had to add to
get
the driver to work properly.

Signed-off-by: Eizan Miyamoto <redacted>
---
Reviewed-by: Houlong Wei <houlong.wei@mediatek.com>
(no changes since v1)
[...]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

[PATCH v6 4/9] media: mtk-mdp: don't pm_run_time_get/put for master comp in clock_on

From: Eizan Miyamoto <hidden>
Date: 2021-08-02 12:13:02

The original intent of commit 86698b9505bbc ("media: mtk-mdp: convert
mtk_mdp_dev.comp array to list") was to create a list to track all the
MDP components that needed to have their clocks enabled/disabled when
calling mtk_mdp_comp_clock_on/off. However, there was a bug inside
mtk_mdp_register_component where the args to a call to list_add were
swapped. The result is that only one component was added to
mtk_mdp_dev.comp_list because comp_list was instead being
repeatedly added to the single element lists headed by each
mtk_mdp_comp.

The order of the args to list_add in mtk_mdp_register_component was
fixed in https://patchwork.kernel.org/patch/11742895/ (Fix Null pointer
dereference when calling list_add).

Then, as a result of https://patchwork.kernel.org/patch/11530769/
(mtk-mdp: use pm_runtime in MDP component driver) if all the components
are added to the component list, the mdp "master" / rdma0 component
ends up having pm_runtime_get_sync() called on it twice recursively:

    rpm_resume+0x694/0x8f8
    __pm_runtime_resume+0x7c/0xa0 ***NOTE***
    mtk_mdp_comp_clock_on+0x48/0x104 [mtk_mdp]
    mtk_mdp_pm_resume+0x2c/0x44 [mtk_mdp]
    pm_generic_runtime_resume+0x34/0x48
    __genpd_runtime_resume+0x6c/0x80
    genpd_runtime_resume+0x104/0x1ac
    __rpm_callback+0x120/0x238
    rpm_callback+0x34/0x8c
    rpm_resume+0x7a0/0x8f8
    __pm_runtime_resume+0x7c/0xa0 ***NOTE***
    mtk_mdp_m2m_start_streaming+0x2c/0x3c [mtk_mdp]

(The calls to pm_runtime_get_sync are inlined and correspond to the
calls to __pm_runtime_resume). It is not correct to have
pm_runtime_get_sync called recursively and the second call will block
indefinitely.

As a result of all that, this change factors mtk_mdp_comp_clock_on/off
into mtk_mdp_comp_power_on/off and moves the calls to
pm_runtime_get/put into the power_on/off functions.

This change then special-cases the master/rdma0 MDP component and does
these things:
- the master/rdma0 component is not added to mtk_mdp_dev.comp_list
- the master/rdma0 component has its clocks (*but not power*) toggled
  by mtk_mpd_comp_clock_on/off inside mtk_mdp_clock_on/off.
- the other components have their clocks *and* power toggled with
  mtk_mdp_comp_power_on/off.

This change introduces the assumption that mtk_mdp_pm_resume will
always be called though a callback from pm_runtime_get_sync made on the
master / rdma0 component.

Signed-off-by: Eizan Miyamoto <redacted>
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 57 ++++++++++++++---
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  5 +-
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 62 ++++++++++++++-----
 3 files changed, 98 insertions(+), 26 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 472c261b01e8..7b6c8a3f3455 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -51,9 +51,9 @@ static const struct of_device_id mtk_mdp_comp_driver_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, mtk_mdp_comp_driver_dt_match);
 
-int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
+int mtk_mdp_comp_power_on(struct mtk_mdp_comp *comp)
 {
-	int i, err, status;
+	int status, err;
 
 	if (comp->larb_dev) {
 		err = mtk_smi_larb_get(comp->larb_dev);
@@ -63,12 +63,54 @@ int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
 
 	err = pm_runtime_get_sync(comp->dev);
 	if (err < 0) {
-		dev_err(comp->dev,
-			"failed to runtime get, err %d.\n",
-			err);
+		dev_err(comp->dev, "failed to runtime get, err %d.\n", err);
 		return err;
 	}
 
+	err = mtk_mdp_comp_clock_on(comp);
+	if (err) {
+		dev_err(comp->dev, "failed to turn on clock. err=%d", err);
+		status = err;
+		goto err_mtk_mdp_comp_clock_on;
+	}
+
+	return 0;
+
+err_mtk_mdp_comp_clock_on:
+	err = pm_runtime_put_sync(comp->dev);
+	if (err)
+		dev_err(comp->dev, "failed to runtime put in cleanup. err=%d", err);
+
+	return status;
+}
+
+int mtk_mdp_comp_power_off(struct mtk_mdp_comp *comp)
+{
+	int status, err;
+
+	mtk_mdp_comp_clock_off(comp);
+
+	err = pm_runtime_put_sync(comp->dev);
+	if (err < 0) {
+		dev_err(comp->dev, "failed to runtime put, err %d.\n", err);
+		status = err;
+		goto err_pm_runtime_put_sync;
+	}
+
+	return 0;
+
+err_pm_runtime_put_sync:
+	err = mtk_mdp_comp_clock_on(comp);
+	if (err)
+		dev_err(comp->dev, "failed to turn on clock in cleanup. err=%d", err);
+
+	return status;
+}
+
+int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
+{
+	int i, err, status;
+
 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
 		if (IS_ERR(comp->clk[i]))
 			continue;
@@ -94,7 +136,8 @@ int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
 	return status;
 }
 
-int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
+
+void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
 {
 	int i;
 
@@ -106,8 +149,6 @@ int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
 
 	if (comp->larb_dev)
 		mtk_smi_larb_put(comp->larb_dev);
-
-	return pm_runtime_put_sync(comp->dev);
 }
 
 static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index f2e22e7e7c45..e3d6aef52869 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -23,8 +23,11 @@ struct mtk_mdp_comp {
 
 int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev);
 
+int mtk_mdp_comp_power_on(struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_power_off(struct mtk_mdp_comp *comp);
+
 int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp);
-int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp);
+void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp);
 
 extern struct platform_driver mtk_mdp_component_driver;
 
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 714154450981..a72a9ba41ea6 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -57,29 +57,64 @@ static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
 	struct device *dev = &mdp->pdev->dev;
 	int err;
 
+	/*
+	 * The master / rdma0 component will have pm_runtime_get_sync called
+	 * on it through mtk_mdp_m2m_start_streaming, making it unnecessary to
+	 * have mtk_mdp_comp_power_on called on it.
+	 */
+	err = mtk_mdp_comp_clock_on(&mdp->comp_self);
+	if (err)
+		return err;
+
 	list_for_each_entry(comp_node, &mdp->comp_list, node) {
-		err = mtk_mdp_comp_clock_on(comp_node);
+		err = mtk_mdp_comp_power_on(comp_node);
 		if (err) {
 			status = err;
-			goto err_mtk_mdp_comp_clock_on;
+			goto err_mtk_mdp_comp_power_on;
 		}
 	}
 
 	return 0;
 
-err_mtk_mdp_comp_clock_on:
-	list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node)
-		mtk_mdp_comp_clock_off(comp_node);
-
+err_mtk_mdp_comp_power_on:
+	list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node) {
+		err = mtk_mdp_comp_power_off(comp_node);
+		if (err)
+			dev_err(&mdp->pdev->dev, "failed to power off after error. err=%d", err);
+	}
 	return status;
 }
 
-static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
+static int mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
 {
 	struct mtk_mdp_comp *comp_node;
+	int status, err;
+
+	list_for_each_entry(comp_node, &mdp->comp_list, node) {
+		err = mtk_mdp_comp_power_off(comp_node);
+		if (err) {
+			status = err;
+			goto err_mtk_mdp_comp_power_off;
+		}
+	}
 
-	list_for_each_entry(comp_node, &mdp->comp_list, node)
-		mtk_mdp_comp_clock_off(comp_node);
+	/*
+	 * The master / rdma0 component will have pm_runtime_put called
+	 * on it through mtk_mdp_m2m_stop_streaming, making it unnecessary to
+	 * have mtk_mdp_comp_power_off called on it.
+	 */
+	mtk_mdp_comp_clock_off(&mdp->comp_self);
+
+	return 0;
+
+err_mtk_mdp_comp_power_off:
+	list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node) {
+		err = mtk_mdp_comp_power_on(comp_node);
+		if (err)
+			dev_err(&mdp->pdev->dev, "failed to power on after error. err=%d", err);
+	}
+
+	return status;
 }
 
 static void mtk_mdp_wdt_worker(struct work_struct *work)
@@ -118,8 +153,6 @@ static int mtk_mdp_master_bind(struct device *dev)
 	int status;
 	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
 
-	mtk_mdp_register_component(mdp, &mdp->comp_self);
-
 	status = component_bind_all(dev, mdp);
 	if (status) {
 		dev_err(dev, "Failed to bind all components: %d\n", status);
@@ -140,8 +173,6 @@ static int mtk_mdp_master_bind(struct device *dev)
 	component_unbind_all(dev, mdp);
 
 err_component_bind_all:
-	mtk_mdp_unregister_component(mdp, &mdp->comp_self);
-
 	return status;
 }
 
@@ -152,7 +183,6 @@ static void mtk_mdp_master_unbind(struct device *dev)
 	pm_runtime_disable(dev);
 	mtk_mdp_unregister_m2m_device(mdp);
 	component_unbind_all(dev, mdp);
-	mtk_mdp_unregister_component(mdp, &mdp->comp_self);
 }
 
 static const struct component_master_ops mtk_mdp_com_ops = {
@@ -337,9 +367,7 @@ static int __maybe_unused mtk_mdp_pm_suspend(struct device *dev)
 {
 	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
 
-	mtk_mdp_clock_off(mdp);
-
-	return 0;
+	return mtk_mdp_clock_off(mdp);
 }
 
 static int __maybe_unused mtk_mdp_pm_resume(struct device *dev)
-- 
2.32.0.554.ge1b32706d8-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 4/9] media: mtk-mdp: don't pm_run_time_get/put for master comp in clock_on

From: Enric Balletbo Serra <eballetbo@gmail.com>
Date: 2021-08-03 10:27:22

Hi Eizan,

Thank you for your patch.

Missatge de Eizan Miyamoto [off-list ref] del dia dl., 2 d’ag.
2021 a les 14:13:
quoted hunk
The original intent of commit 86698b9505bbc ("media: mtk-mdp: convert
mtk_mdp_dev.comp array to list") was to create a list to track all the
MDP components that needed to have their clocks enabled/disabled when
calling mtk_mdp_comp_clock_on/off. However, there was a bug inside
mtk_mdp_register_component where the args to a call to list_add were
swapped. The result is that only one component was added to
mtk_mdp_dev.comp_list because comp_list was instead being
repeatedly added to the single element lists headed by each
mtk_mdp_comp.

The order of the args to list_add in mtk_mdp_register_component was
fixed in https://patchwork.kernel.org/patch/11742895/ (Fix Null pointer
dereference when calling list_add).

Then, as a result of https://patchwork.kernel.org/patch/11530769/
(mtk-mdp: use pm_runtime in MDP component driver) if all the components
are added to the component list, the mdp "master" / rdma0 component
ends up having pm_runtime_get_sync() called on it twice recursively:

    rpm_resume+0x694/0x8f8
    __pm_runtime_resume+0x7c/0xa0 ***NOTE***
    mtk_mdp_comp_clock_on+0x48/0x104 [mtk_mdp]
    mtk_mdp_pm_resume+0x2c/0x44 [mtk_mdp]
    pm_generic_runtime_resume+0x34/0x48
    __genpd_runtime_resume+0x6c/0x80
    genpd_runtime_resume+0x104/0x1ac
    __rpm_callback+0x120/0x238
    rpm_callback+0x34/0x8c
    rpm_resume+0x7a0/0x8f8
    __pm_runtime_resume+0x7c/0xa0 ***NOTE***
    mtk_mdp_m2m_start_streaming+0x2c/0x3c [mtk_mdp]

(The calls to pm_runtime_get_sync are inlined and correspond to the
calls to __pm_runtime_resume). It is not correct to have
pm_runtime_get_sync called recursively and the second call will block
indefinitely.

As a result of all that, this change factors mtk_mdp_comp_clock_on/off
into mtk_mdp_comp_power_on/off and moves the calls to
pm_runtime_get/put into the power_on/off functions.

This change then special-cases the master/rdma0 MDP component and does
these things:
- the master/rdma0 component is not added to mtk_mdp_dev.comp_list
- the master/rdma0 component has its clocks (*but not power*) toggled
  by mtk_mpd_comp_clock_on/off inside mtk_mdp_clock_on/off.
- the other components have their clocks *and* power toggled with
  mtk_mdp_comp_power_on/off.

This change introduces the assumption that mtk_mdp_pm_resume will
always be called though a callback from pm_runtime_get_sync made on the
master / rdma0 component.

Signed-off-by: Eizan Miyamoto <redacted>
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 57 ++++++++++++++---
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  5 +-
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 62 ++++++++++++++-----
 3 files changed, 98 insertions(+), 26 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 472c261b01e8..7b6c8a3f3455 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -51,9 +51,9 @@ static const struct of_device_id mtk_mdp_comp_driver_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, mtk_mdp_comp_driver_dt_match);

-int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
+int mtk_mdp_comp_power_on(struct mtk_mdp_comp *comp)
 {
-       int i, err, status;
+       int status, err;

        if (comp->larb_dev) {
                err = mtk_smi_larb_get(comp->larb_dev);
@@ -63,12 +63,54 @@ int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)

        err = pm_runtime_get_sync(comp->dev);
        if (err < 0) {
-               dev_err(comp->dev,
-                       "failed to runtime get, err %d.\n",
-                       err);
+               dev_err(comp->dev, "failed to runtime get, err %d.\n", err);
                return err;
        }

+       err = mtk_mdp_comp_clock_on(comp);
+       if (err) {
+               dev_err(comp->dev, "failed to turn on clock. err=%d", err);
+               status = err;
+               goto err_mtk_mdp_comp_clock_on;
+       }
+
+       return 0;
+
+err_mtk_mdp_comp_clock_on:
+       err = pm_runtime_put_sync(comp->dev);
+       if (err)
+               dev_err(comp->dev, "failed to runtime put in cleanup. err=%d", err);
+
+       return status;
+}
+
+int mtk_mdp_comp_power_off(struct mtk_mdp_comp *comp)
+{
+       int status, err;
+
+       mtk_mdp_comp_clock_off(comp);
+
+       err = pm_runtime_put_sync(comp->dev);
+       if (err < 0) {
+               dev_err(comp->dev, "failed to runtime put, err %d.\n", err);
+               status = err;
+               goto err_pm_runtime_put_sync;
+       }
+
+       return 0;
+
+err_pm_runtime_put_sync:
+       err = mtk_mdp_comp_clock_on(comp);
+       if (err)
+               dev_err(comp->dev, "failed to turn on clock in cleanup. err=%d", err);
+
+       return status;
+}
+
+int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
+{
+       int i, err, status;
+
        for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
                if (IS_ERR(comp->clk[i]))
                        continue;
@@ -94,7 +136,8 @@ int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
        return status;
 }

-int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
+
+void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
 {
        int i;
@@ -106,8 +149,6 @@ int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)

        if (comp->larb_dev)
                mtk_smi_larb_put(comp->larb_dev);
-
-       return pm_runtime_put_sync(comp->dev);
 }

 static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index f2e22e7e7c45..e3d6aef52869 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -23,8 +23,11 @@ struct mtk_mdp_comp {

 int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev);

+int mtk_mdp_comp_power_on(struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_power_off(struct mtk_mdp_comp *comp);
+
 int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp);
-int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp);
+void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp);

 extern struct platform_driver mtk_mdp_component_driver;
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 714154450981..a72a9ba41ea6 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -57,29 +57,64 @@ static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
        struct device *dev = &mdp->pdev->dev;
        int err;

+       /*
+        * The master / rdma0 component will have pm_runtime_get_sync called
+        * on it through mtk_mdp_m2m_start_streaming, making it unnecessary to
+        * have mtk_mdp_comp_power_on called on it.
+        */
+       err = mtk_mdp_comp_clock_on(&mdp->comp_self);
+       if (err)
+               return err;
+
        list_for_each_entry(comp_node, &mdp->comp_list, node) {
-               err = mtk_mdp_comp_clock_on(comp_node);
+               err = mtk_mdp_comp_power_on(comp_node);
                if (err) {
                        status = err;
-                       goto err_mtk_mdp_comp_clock_on;
+                       goto err_mtk_mdp_comp_power_on;
                }
        }

        return 0;

-err_mtk_mdp_comp_clock_on:
-       list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node)
-               mtk_mdp_comp_clock_off(comp_node);
-
+err_mtk_mdp_comp_power_on:
+       list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node) {
+               err = mtk_mdp_comp_power_off(comp_node);
+               if (err)
+                       dev_err(&mdp->pdev->dev, "failed to power off after error. err=%d", err);
+       }
        return status;
 }

-static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
+static int mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
 {
        struct mtk_mdp_comp *comp_node;
+       int status, err;
+
+       list_for_each_entry(comp_node, &mdp->comp_list, node) {
+               err = mtk_mdp_comp_power_off(comp_node);
+               if (err) {
+                       status = err;
+                       goto err_mtk_mdp_comp_power_off;
+               }
+       }

-       list_for_each_entry(comp_node, &mdp->comp_list, node)
-               mtk_mdp_comp_clock_off(comp_node);
+       /*
+        * The master / rdma0 component will have pm_runtime_put called
+        * on it through mtk_mdp_m2m_stop_streaming, making it unnecessary to
+        * have mtk_mdp_comp_power_off called on it.
+        */
+       mtk_mdp_comp_clock_off(&mdp->comp_self);
+
+       return 0;
+
+err_mtk_mdp_comp_power_off:
+       list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node) {
+               err = mtk_mdp_comp_power_on(comp_node);
+               if (err)
+                       dev_err(&mdp->pdev->dev, "failed to power on after error. err=%d", err);
+       }
+
+       return status;
 }

 static void mtk_mdp_wdt_worker(struct work_struct *work)
@@ -118,8 +153,6 @@ static int mtk_mdp_master_bind(struct device *dev)
        int status;
        struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);

-       mtk_mdp_register_component(mdp, &mdp->comp_self);
-
        status = component_bind_all(dev, mdp);
        if (status) {
                dev_err(dev, "Failed to bind all components: %d\n", status);
@@ -140,8 +173,6 @@ static int mtk_mdp_master_bind(struct device *dev)
        component_unbind_all(dev, mdp);

 err_component_bind_all:
-       mtk_mdp_unregister_component(mdp, &mdp->comp_self);
-
        return status;
 }
@@ -152,7 +183,6 @@ static void mtk_mdp_master_unbind(struct device *dev)
        pm_runtime_disable(dev);
        mtk_mdp_unregister_m2m_device(mdp);
        component_unbind_all(dev, mdp);
-       mtk_mdp_unregister_component(mdp, &mdp->comp_self);
 }

 static const struct component_master_ops mtk_mdp_com_ops = {
@@ -337,9 +367,7 @@ static int __maybe_unused mtk_mdp_pm_suspend(struct device *dev)
 {
        struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);

-       mtk_mdp_clock_off(mdp);
-
-       return 0;
+       return mtk_mdp_clock_off(mdp);
 }

 static int __maybe_unused mtk_mdp_pm_resume(struct device *dev)
--
2.32.0.554.ge1b32706d8-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 4/9] media: mtk-mdp: don't pm_run_time_get/put for master comp in clock_on

From: houlong wei <houlong.wei@mediatek.com>
Date: 2021-08-16 01:10:48

On Mon, 2021-08-02 at 20:12 +0800, Eizan Miyamoto wrote:
The original intent of commit 86698b9505bbc ("media: mtk-mdp: convert
mtk_mdp_dev.comp array to list") was to create a list to track all
the
MDP components that needed to have their clocks enabled/disabled when
calling mtk_mdp_comp_clock_on/off. However, there was a bug inside
mtk_mdp_register_component where the args to a call to list_add were
swapped. The result is that only one component was added to
mtk_mdp_dev.comp_list because comp_list was instead being
repeatedly added to the single element lists headed by each
mtk_mdp_comp.

The order of the args to list_add in mtk_mdp_register_component was
fixed in https://patchwork.kernel.org/patch/11742895/ (Fix Null
pointer
dereference when calling list_add).

Then, as a result of https://patchwork.kernel.org/patch/11530769/
(mtk-mdp: use pm_runtime in MDP component driver) if all the
components
are added to the component list, the mdp "master" / rdma0 component
ends up having pm_runtime_get_sync() called on it twice recursively:

    rpm_resume+0x694/0x8f8
    __pm_runtime_resume+0x7c/0xa0 ***NOTE***
    mtk_mdp_comp_clock_on+0x48/0x104 [mtk_mdp]
    mtk_mdp_pm_resume+0x2c/0x44 [mtk_mdp]
    pm_generic_runtime_resume+0x34/0x48
    __genpd_runtime_resume+0x6c/0x80
    genpd_runtime_resume+0x104/0x1ac
    __rpm_callback+0x120/0x238
    rpm_callback+0x34/0x8c
    rpm_resume+0x7a0/0x8f8
    __pm_runtime_resume+0x7c/0xa0 ***NOTE***
    mtk_mdp_m2m_start_streaming+0x2c/0x3c [mtk_mdp]

(The calls to pm_runtime_get_sync are inlined and correspond to the
calls to __pm_runtime_resume). It is not correct to have
pm_runtime_get_sync called recursively and the second call will block
indefinitely.

As a result of all that, this change factors
mtk_mdp_comp_clock_on/off
into mtk_mdp_comp_power_on/off and moves the calls to
pm_runtime_get/put into the power_on/off functions.

This change then special-cases the master/rdma0 MDP component and
does
these things:
- the master/rdma0 component is not added to mtk_mdp_dev.comp_list
- the master/rdma0 component has its clocks (*but not power*) toggled
  by mtk_mpd_comp_clock_on/off inside mtk_mdp_clock_on/off.
- the other components have their clocks *and* power toggled with
  mtk_mdp_comp_power_on/off.

This change introduces the assumption that mtk_mdp_pm_resume will
always be called though a callback from pm_runtime_get_sync made on
the
master / rdma0 component.

Signed-off-by: Eizan Miyamoto <redacted>
---
Reviewed-by: Houlong Wei <houlong.wei@mediatek.com>
(no changes since v1)
[...]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

[PATCH v6 5/9] mtk-mdp: make mdp driver to be loadable by platform_device_register*()

From: Eizan Miyamoto <hidden>
Date: 2021-08-02 12:13:10

Rather than hanging the MDP master component driver off of the rdma0
device, make it possible too create a "virtual" device by registering
it with platform_device_register_*() to be probed by the mtk_mdp_core
driver.

Broadly, three interdependent things are done by this change:
- Make it is possible to search for MDP devices in the device tree
  through the grandparent device's of_node.
- v4l-related setup is moved into from the mtk_mdp_core driver to the
  mtk_mdp_comp driver.
- Presence of a mediatek,vpu property in an MDP component device node
  is used to determine what device to use when dispatching DMA ops from
  the relevant ioctl, and also do V4L2 initialization in this case.

Signed-off-by: Eizan Miyamoto <redacted>
---

Changes in v6:
- Don't propagate errors from clock_on/off as an afterthought.
- Split apart modifying mdp driver to be loadable from mmsys from
  actually loading it from mmsys into two changs to make review easier.
- Update devicetree bindings to reflect no longer needing the
  mediatek,vpu property in the mdp_rdma0 device node.
- Some stylistic cleanups.

Changes in v5:
- rebase and test on 5.13-next @ e2f74b13dbe6

Changes in v4:
- rebase and test on 5.13
- don't depend on https://patchwork.kernel.org/project/linux-mediatek/list/?series=464873

Changes in v3:
- get mdp master from aliases instead of strcmp against of_node->name

Changes in v2:
- rebased onto Linux 5.12
- 100 char line length allowance was utilized in a few places
- Removal of a redundant dev_err() print at the end of
  mtk_mdp_comp_init()
- Instead of printing errors and ignoring them, I've added a patch to
  correctly propagate them.
- Use of C style comments.
- Three additional patches were added to eliminate dependency on the
  mediatek,vpu property inside the mdp_rdma0 device node.

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 51 ++++++++++-----
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 62 ++++++-------------
 drivers/media/platform/mtk-mdp/mtk_mdp_core.h |  2 +
 drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c  |  4 +-
 4 files changed, 60 insertions(+), 59 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 7b6c8a3f3455..85ef274841a3 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -155,8 +155,45 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
 {
 	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
 	struct mtk_mdp_dev *mdp = data;
+	struct device_node *vpu_node;
 
 	mtk_mdp_register_component(mdp, comp);
+
+	/*
+	 * If this component has a "mediatek-vpu" property, it is responsible for
+	 * notifying the mdp master driver about it so it can be further initialized
+	 * later.
+	 */
+	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
+	if (vpu_node) {
+		int ret;
+
+		mdp->vpu_dev = of_find_device_by_node(vpu_node);
+		if (WARN_ON(!mdp->vpu_dev)) {
+			dev_err(dev, "vpu pdev failed\n");
+			of_node_put(vpu_node);
+		}
+
+		ret = v4l2_device_register(dev, &mdp->v4l2_dev);
+		if (ret) {
+			dev_err(dev, "Failed to register v4l2 device\n");
+			return -EINVAL;
+		}
+
+		ret = vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
+		if (ret) {
+			dev_err(dev, "Failed to set vb2 dma mag seg size\n");
+			return -EINVAL;
+		}
+
+		/*
+		 * presence of the "mediatek,vpu" property in a device node
+		 * indicates that it is the primary MDP rdma device and MDP DMA
+		 * ops should be handled by its DMA callbacks.
+		 */
+		mdp->rdma_dev = dev;
+	}
+
 	pm_runtime_enable(dev);
 
 	return 0;
@@ -237,23 +274,9 @@ int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
 static int mtk_mdp_comp_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct device_node *vpu_node;
 	int status;
 	struct mtk_mdp_comp *comp;
 
-	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
-	if (vpu_node) {
-		of_node_put(vpu_node);
-		/*
-		 * The device tree node with a mediatek,vpu property is deemed
-		 * the MDP "master" device, we don't want to add a component
-		 * for it in this function because the initialization for the
-		 * master is done elsewhere.
-		 */
-		dev_info(dev, "vpu node found, not probing\n");
-		return -ENODEV;
-	}
-
 	comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
 	if (!comp)
 		return -ENOMEM;
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index a72a9ba41ea6..50eafcc9993d 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -159,6 +159,17 @@ static int mtk_mdp_master_bind(struct device *dev)
 		goto err_component_bind_all;
 	}
 
+	if (mdp->vpu_dev) {
+		int ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
+					  VPU_RST_MDP);
+		if (ret) {
+			dev_err(dev, "Failed to register reset handler\n");
+			goto err_wdt_reg;
+		}
+	} else {
+		dev_err(dev, "no vpu_dev found\n");
+	}
+
 	status = mtk_mdp_register_m2m_device(mdp);
 	if (status) {
 		dev_err(dev, "Failed to register m2m device: %d\n", status);
@@ -170,6 +181,8 @@ static int mtk_mdp_master_bind(struct device *dev)
 	return 0;
 
 err_mtk_mdp_register_m2m_device:
+
+err_wdt_reg:
 	component_unbind_all(dev, mdp);
 
 err_component_bind_all:
@@ -228,8 +241,13 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 		of_node_put(node);
 		parent = dev->of_node;
 		dev_warn(dev, "device tree is out of date\n");
-	} else {
+	} else if (dev->of_node) {
 		parent = dev->of_node->parent;
+	} else if (dev->parent) {
+		/* maybe we were created from a call to platform_device_register_data() */
+		parent = dev->parent->parent->of_node;
+	} else {
+		return -ENODEV;
 	}
 
 	/* Iterate over sibling MDP function blocks */
@@ -262,16 +280,6 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 		}
 	}
 
-	/*
-	 * Create a component for myself so that clocks can be toggled in
-	 * clock_on().
-	 */
-	ret = mtk_mdp_comp_init(&mdp->comp_self, dev);
-	if (ret) {
-		dev_err(dev, "Failed to initialize component\n");
-		goto err_comp;
-	}
-
 	mdp->job_wq = create_singlethread_workqueue(MTK_MDP_MODULE_NAME);
 	if (!mdp->job_wq) {
 		dev_err(&pdev->dev, "unable to alloc job workqueue\n");
@@ -287,29 +295,8 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 	}
 	INIT_WORK(&mdp->wdt_work, mtk_mdp_wdt_worker);
 
-	ret = v4l2_device_register(dev, &mdp->v4l2_dev);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to register v4l2 device\n");
-		ret = -EINVAL;
-		goto err_dev_register;
-	}
-
-	mdp->vpu_dev = vpu_get_plat_device(pdev);
-	ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
-				  VPU_RST_MDP);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to register reset handler\n");
-		goto err_wdt_reg;
-	}
-
 	platform_set_drvdata(pdev, mdp);
 
-	ret = vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to set vb2 dma mag seg size\n");
-		goto err_set_max_seg_size;
-	}
-
 	ret = component_master_add_with_match(dev, &mtk_mdp_com_ops, match);
 	if (ret) {
 		dev_err(dev, "Component master add failed\n");
@@ -321,22 +308,12 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 	return 0;
 
 err_component_master_add:
-	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
-
-err_set_max_seg_size:
-
-err_wdt_reg:
-	v4l2_device_unregister(&mdp->v4l2_dev);
-
-err_dev_register:
 	destroy_workqueue(mdp->wdt_wq);
 
 err_alloc_wdt_wq:
 	destroy_workqueue(mdp->job_wq);
 
 err_alloc_job_wq:
-
-err_comp:
 	dev_dbg(dev, "err %d\n", ret);
 	return ret;
 }
@@ -404,7 +381,6 @@ static struct platform_driver mtk_mdp_driver = {
 	.driver = {
 		.name	= MTK_MDP_MODULE_NAME,
 		.pm	= &mtk_mdp_pm_ops,
-		.of_match_table = mtk_mdp_of_ids,
 	}
 };
 
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
index 8a52539b15d4..9fcd8b8e7c25 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
@@ -133,6 +133,7 @@ struct mtk_mdp_variant {
  * struct mtk_mdp_dev - abstraction for image processor entity
  * @lock:	the mutex protecting this data structure
  * @vpulock:	the mutex protecting the communication with VPU
+ * @rdma_dev:  device pointer to rdma device for MDP
  * @pdev:	pointer to the image processor platform device
  * @variant:	the IP variant information
  * @id:		image processor device index (0..MTK_MDP_MAX_DEVS)
@@ -151,6 +152,7 @@ struct mtk_mdp_variant {
 struct mtk_mdp_dev {
 	struct mutex			lock;
 	struct mutex			vpulock;
+	struct device			*rdma_dev;
 	struct platform_device		*pdev;
 	struct mtk_mdp_variant		*variant;
 	u16				id;
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
index f14779e7596e..9834d3bbe851 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
@@ -929,7 +929,7 @@ static int mtk_mdp_m2m_queue_init(void *priv, struct vb2_queue *src_vq,
 	src_vq->mem_ops = &vb2_dma_contig_memops;
 	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
 	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-	src_vq->dev = &ctx->mdp_dev->pdev->dev;
+	src_vq->dev = ctx->mdp_dev->rdma_dev;
 	src_vq->lock = &ctx->mdp_dev->lock;
 
 	ret = vb2_queue_init(src_vq);
@@ -944,7 +944,7 @@ static int mtk_mdp_m2m_queue_init(void *priv, struct vb2_queue *src_vq,
 	dst_vq->mem_ops = &vb2_dma_contig_memops;
 	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
 	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-	dst_vq->dev = &ctx->mdp_dev->pdev->dev;
+	dst_vq->dev = ctx->mdp_dev->rdma_dev;
 	dst_vq->lock = &ctx->mdp_dev->lock;
 
 	return vb2_queue_init(dst_vq);
-- 
2.32.0.554.ge1b32706d8-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 5/9] mtk-mdp: make mdp driver to be loadable by platform_device_register*()

From: Enric Balletbo Serra <eballetbo@gmail.com>
Date: 2021-08-03 10:27:47

Hi Eizan,

Thank you for your patch.

Missatge de Eizan Miyamoto [off-list ref] del dia dl., 2 d’ag.
2021 a les 14:13:
quoted hunk
Rather than hanging the MDP master component driver off of the rdma0
device, make it possible too create a "virtual" device by registering
it with platform_device_register_*() to be probed by the mtk_mdp_core
driver.

Broadly, three interdependent things are done by this change:
- Make it is possible to search for MDP devices in the device tree
  through the grandparent device's of_node.
- v4l-related setup is moved into from the mtk_mdp_core driver to the
  mtk_mdp_comp driver.
- Presence of a mediatek,vpu property in an MDP component device node
  is used to determine what device to use when dispatching DMA ops from
  the relevant ioctl, and also do V4L2 initialization in this case.

Signed-off-by: Eizan Miyamoto <redacted>
---

Changes in v6:
- Don't propagate errors from clock_on/off as an afterthought.
- Split apart modifying mdp driver to be loadable from mmsys from
  actually loading it from mmsys into two changs to make review easier.
- Update devicetree bindings to reflect no longer needing the
  mediatek,vpu property in the mdp_rdma0 device node.
- Some stylistic cleanups.

Changes in v5:
- rebase and test on 5.13-next @ e2f74b13dbe6

Changes in v4:
- rebase and test on 5.13
- don't depend on https://patchwork.kernel.org/project/linux-mediatek/list/?series=464873

Changes in v3:
- get mdp master from aliases instead of strcmp against of_node->name

Changes in v2:
- rebased onto Linux 5.12
- 100 char line length allowance was utilized in a few places
- Removal of a redundant dev_err() print at the end of
  mtk_mdp_comp_init()
- Instead of printing errors and ignoring them, I've added a patch to
  correctly propagate them.
- Use of C style comments.
- Three additional patches were added to eliminate dependency on the
  mediatek,vpu property inside the mdp_rdma0 device node.

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 51 ++++++++++-----
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 62 ++++++-------------
 drivers/media/platform/mtk-mdp/mtk_mdp_core.h |  2 +
 drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c  |  4 +-
 4 files changed, 60 insertions(+), 59 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 7b6c8a3f3455..85ef274841a3 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -155,8 +155,45 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
 {
        struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
        struct mtk_mdp_dev *mdp = data;
+       struct device_node *vpu_node;

        mtk_mdp_register_component(mdp, comp);
+
+       /*
+        * If this component has a "mediatek-vpu" property, it is responsible for
+        * notifying the mdp master driver about it so it can be further initialized
+        * later.
+        */
+       vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
+       if (vpu_node) {
+               int ret;
+
+               mdp->vpu_dev = of_find_device_by_node(vpu_node);
+               if (WARN_ON(!mdp->vpu_dev)) {
This looks a bit excessive IMO, but on the other hand looks like this
is a transitional patch as all this will be removed after some rework
on the latest patch.
+                       dev_err(dev, "vpu pdev failed\n");
You already did a WARN_ON, this print is not needed. But again, all
this seems to be transitional and is removed later. So it doesn't
really bothers me

Reviewed-by: Enric Balletbo i Serra <redacted>

quoted hunk
+                       of_node_put(vpu_node);
+               }
+
+               ret = v4l2_device_register(dev, &mdp->v4l2_dev);
+               if (ret) {
+                       dev_err(dev, "Failed to register v4l2 device\n");
+                       return -EINVAL;
+               }
+
+               ret = vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
+               if (ret) {
+                       dev_err(dev, "Failed to set vb2 dma mag seg size\n");
+                       return -EINVAL;
+               }
+
+               /*
+                * presence of the "mediatek,vpu" property in a device node
+                * indicates that it is the primary MDP rdma device and MDP DMA
+                * ops should be handled by its DMA callbacks.
+                */
+               mdp->rdma_dev = dev;
+       }
+
        pm_runtime_enable(dev);

        return 0;
@@ -237,23 +274,9 @@ int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
 static int mtk_mdp_comp_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
-       struct device_node *vpu_node;
        int status;
        struct mtk_mdp_comp *comp;

-       vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
-       if (vpu_node) {
-               of_node_put(vpu_node);
-               /*
-                * The device tree node with a mediatek,vpu property is deemed
-                * the MDP "master" device, we don't want to add a component
-                * for it in this function because the initialization for the
-                * master is done elsewhere.
-                */
-               dev_info(dev, "vpu node found, not probing\n");
-               return -ENODEV;
-       }
-
        comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
        if (!comp)
                return -ENOMEM;
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index a72a9ba41ea6..50eafcc9993d 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -159,6 +159,17 @@ static int mtk_mdp_master_bind(struct device *dev)
                goto err_component_bind_all;
        }

+       if (mdp->vpu_dev) {
+               int ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
+                                         VPU_RST_MDP);
+               if (ret) {
+                       dev_err(dev, "Failed to register reset handler\n");
+                       goto err_wdt_reg;
+               }
+       } else {
+               dev_err(dev, "no vpu_dev found\n");
+       }
+
        status = mtk_mdp_register_m2m_device(mdp);
        if (status) {
                dev_err(dev, "Failed to register m2m device: %d\n", status);
@@ -170,6 +181,8 @@ static int mtk_mdp_master_bind(struct device *dev)
        return 0;

 err_mtk_mdp_register_m2m_device:
+
+err_wdt_reg:
        component_unbind_all(dev, mdp);

 err_component_bind_all:
@@ -228,8 +241,13 @@ static int mtk_mdp_probe(struct platform_device *pdev)
                of_node_put(node);
                parent = dev->of_node;
                dev_warn(dev, "device tree is out of date\n");
-       } else {
+       } else if (dev->of_node) {
                parent = dev->of_node->parent;
+       } else if (dev->parent) {
+               /* maybe we were created from a call to platform_device_register_data() */
+               parent = dev->parent->parent->of_node;
+       } else {
+               return -ENODEV;
        }

        /* Iterate over sibling MDP function blocks */
@@ -262,16 +280,6 @@ static int mtk_mdp_probe(struct platform_device *pdev)
                }
        }

-       /*
-        * Create a component for myself so that clocks can be toggled in
-        * clock_on().
-        */
-       ret = mtk_mdp_comp_init(&mdp->comp_self, dev);
-       if (ret) {
-               dev_err(dev, "Failed to initialize component\n");
-               goto err_comp;
-       }
-
        mdp->job_wq = create_singlethread_workqueue(MTK_MDP_MODULE_NAME);
        if (!mdp->job_wq) {
                dev_err(&pdev->dev, "unable to alloc job workqueue\n");
@@ -287,29 +295,8 @@ static int mtk_mdp_probe(struct platform_device *pdev)
        }
        INIT_WORK(&mdp->wdt_work, mtk_mdp_wdt_worker);

-       ret = v4l2_device_register(dev, &mdp->v4l2_dev);
-       if (ret) {
-               dev_err(&pdev->dev, "Failed to register v4l2 device\n");
-               ret = -EINVAL;
-               goto err_dev_register;
-       }
-
-       mdp->vpu_dev = vpu_get_plat_device(pdev);
-       ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
-                                 VPU_RST_MDP);
-       if (ret) {
-               dev_err(&pdev->dev, "Failed to register reset handler\n");
-               goto err_wdt_reg;
-       }
-
        platform_set_drvdata(pdev, mdp);

-       ret = vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
-       if (ret) {
-               dev_err(&pdev->dev, "Failed to set vb2 dma mag seg size\n");
-               goto err_set_max_seg_size;
-       }
-
        ret = component_master_add_with_match(dev, &mtk_mdp_com_ops, match);
        if (ret) {
                dev_err(dev, "Component master add failed\n");
@@ -321,22 +308,12 @@ static int mtk_mdp_probe(struct platform_device *pdev)
        return 0;

 err_component_master_add:
-       vb2_dma_contig_clear_max_seg_size(&pdev->dev);
-
-err_set_max_seg_size:
-
-err_wdt_reg:
-       v4l2_device_unregister(&mdp->v4l2_dev);
-
-err_dev_register:
        destroy_workqueue(mdp->wdt_wq);

 err_alloc_wdt_wq:
        destroy_workqueue(mdp->job_wq);

 err_alloc_job_wq:
-
-err_comp:
        dev_dbg(dev, "err %d\n", ret);
        return ret;
 }
@@ -404,7 +381,6 @@ static struct platform_driver mtk_mdp_driver = {
        .driver = {
                .name   = MTK_MDP_MODULE_NAME,
                .pm     = &mtk_mdp_pm_ops,
-               .of_match_table = mtk_mdp_of_ids,
        }
 };
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
index 8a52539b15d4..9fcd8b8e7c25 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
@@ -133,6 +133,7 @@ struct mtk_mdp_variant {
  * struct mtk_mdp_dev - abstraction for image processor entity
  * @lock:      the mutex protecting this data structure
  * @vpulock:   the mutex protecting the communication with VPU
+ * @rdma_dev:  device pointer to rdma device for MDP
  * @pdev:      pointer to the image processor platform device
  * @variant:   the IP variant information
  * @id:                image processor device index (0..MTK_MDP_MAX_DEVS)
@@ -151,6 +152,7 @@ struct mtk_mdp_variant {
 struct mtk_mdp_dev {
        struct mutex                    lock;
        struct mutex                    vpulock;
+       struct device                   *rdma_dev;
        struct platform_device          *pdev;
        struct mtk_mdp_variant          *variant;
        u16                             id;
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
index f14779e7596e..9834d3bbe851 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
@@ -929,7 +929,7 @@ static int mtk_mdp_m2m_queue_init(void *priv, struct vb2_queue *src_vq,
        src_vq->mem_ops = &vb2_dma_contig_memops;
        src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
        src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-       src_vq->dev = &ctx->mdp_dev->pdev->dev;
+       src_vq->dev = ctx->mdp_dev->rdma_dev;
        src_vq->lock = &ctx->mdp_dev->lock;

        ret = vb2_queue_init(src_vq);
@@ -944,7 +944,7 @@ static int mtk_mdp_m2m_queue_init(void *priv, struct vb2_queue *src_vq,
        dst_vq->mem_ops = &vb2_dma_contig_memops;
        dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
        dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-       dst_vq->dev = &ctx->mdp_dev->pdev->dev;
+       dst_vq->dev = ctx->mdp_dev->rdma_dev;
        dst_vq->lock = &ctx->mdp_dev->lock;

        return vb2_queue_init(dst_vq);
--
2.32.0.554.ge1b32706d8-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 5/9] mtk-mdp: make mdp driver to be loadable by platform_device_register*()

From: houlong wei <houlong.wei@mediatek.com>
Date: 2021-08-16 01:15:17

On Mon, 2021-08-02 at 20:12 +0800, Eizan Miyamoto wrote:
Rather than hanging the MDP master component driver off of the rdma0
device, make it possible too create a "virtual" device by registering
it with platform_device_register_*() to be probed by the mtk_mdp_core
driver.

Broadly, three interdependent things are done by this change:
- Make it is possible to search for MDP devices in the device tree
  through the grandparent device's of_node.
- v4l-related setup is moved into from the mtk_mdp_core driver to the
  mtk_mdp_comp driver.
- Presence of a mediatek,vpu property in an MDP component device node
  is used to determine what device to use when dispatching DMA ops
from
  the relevant ioctl, and also do V4L2 initialization in this case.

Signed-off-by: Eizan Miyamoto <redacted>
---
Reviewed-by: Houlong Wei <houlong.wei@mediatek.com>
Changes in v6:
- Don't propagate errors from clock_on/off as an afterthought.
- Split apart modifying mdp driver to be loadable from mmsys from
  actually loading it from mmsys into two changs to make review
easier.
- Update devicetree bindings to reflect no longer needing the
  mediatek,vpu property in the mdp_rdma0 device node.
- Some stylistic cleanups.

Changes in v5:
- rebase and test on 5.13-next @ e2f74b13dbe6

Changes in v4:
- rebase and test on 5.13
- don't depend on 
https://patchwork.kernel.org/project/linux-mediatek/list/?series=464873

Changes in v3:
- get mdp master from aliases instead of strcmp against of_node->name

Changes in v2:
- rebased onto Linux 5.12
- 100 char line length allowance was utilized in a few places
- Removal of a redundant dev_err() print at the end of
  mtk_mdp_comp_init()
- Instead of printing errors and ignoring them, I've added a patch to
  correctly propagate them.
- Use of C style comments.
- Three additional patches were added to eliminate dependency on the
  mediatek,vpu property inside the mdp_rdma0 device node.
[...]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 5/9] mtk-mdp: make mdp driver to be loadable by platform_device_register*()

From: houlong wei <houlong.wei@mediatek.com>
Date: 2021-08-16 03:39:36

On Mon, 2021-08-02 at 20:12 +0800, Eizan Miyamoto wrote:
quoted hunk
Rather than hanging the MDP master component driver off of the rdma0
device, make it possible too create a "virtual" device by registering
it with platform_device_register_*() to be probed by the mtk_mdp_core
driver.

Broadly, three interdependent things are done by this change:
- Make it is possible to search for MDP devices in the device tree
  through the grandparent device's of_node.
- v4l-related setup is moved into from the mtk_mdp_core driver to the
  mtk_mdp_comp driver.
- Presence of a mediatek,vpu property in an MDP component device node
  is used to determine what device to use when dispatching DMA ops
from
  the relevant ioctl, and also do V4L2 initialization in this case.

Signed-off-by: Eizan Miyamoto <redacted>
---

Changes in v6:
- Don't propagate errors from clock_on/off as an afterthought.
- Split apart modifying mdp driver to be loadable from mmsys from
  actually loading it from mmsys into two changs to make review
easier.
- Update devicetree bindings to reflect no longer needing the
  mediatek,vpu property in the mdp_rdma0 device node.
- Some stylistic cleanups.

Changes in v5:
- rebase and test on 5.13-next @ e2f74b13dbe6

Changes in v4:
- rebase and test on 5.13
- don't depend on 
https://patchwork.kernel.org/project/linux-mediatek/list/?series=464873

Changes in v3:
- get mdp master from aliases instead of strcmp against of_node->name

Changes in v2:
- rebased onto Linux 5.12
- 100 char line length allowance was utilized in a few places
- Removal of a redundant dev_err() print at the end of
  mtk_mdp_comp_init()
- Instead of printing errors and ignoring them, I've added a patch to
  correctly propagate them.
- Use of C style comments.
- Three additional patches were added to eliminate dependency on the
  mediatek,vpu property inside the mdp_rdma0 device node.

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 51 ++++++++++-----
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 62 ++++++-----------
--
 drivers/media/platform/mtk-mdp/mtk_mdp_core.h |  2 +
 drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c  |  4 +-
 4 files changed, 60 insertions(+), 59 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 7b6c8a3f3455..85ef274841a3 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -155,8 +155,45 @@ static int mtk_mdp_comp_bind(struct device *dev,
struct device *master, void *da
 {
 	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
 	struct mtk_mdp_dev *mdp = data;
+	struct device_node *vpu_node;
 
 	mtk_mdp_register_component(mdp, comp);
+
+	/*
+	 * If this component has a "mediatek-vpu" property, it is
responsible for
+	 * notifying the mdp master driver about it so it can be
further initialized
+	 * later.
+	 */
+	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
+	if (vpu_node) {
+		int ret;
+
+		mdp->vpu_dev = of_find_device_by_node(vpu_node);
+		if (WARN_ON(!mdp->vpu_dev)) {
+			dev_err(dev, "vpu pdev failed\n");
+			of_node_put(vpu_node);
+		}
Maybe 'of_node_put(vpu_node)' should be called when 'mdp->vpu_dev' is
valid.

quoted hunk
+		ret = v4l2_device_register(dev, &mdp->v4l2_dev);
+		if (ret) {
+			dev_err(dev, "Failed to register v4l2
device\n");
+			return -EINVAL;
+		}
+
+		ret = vb2_dma_contig_set_max_seg_size(dev,
DMA_BIT_MASK(32));
+		if (ret) {
+			dev_err(dev, "Failed to set vb2 dma mag seg
size\n");
+			return -EINVAL;
+		}
+
+		/*
+		 * presence of the "mediatek,vpu" property in a device
node
+		 * indicates that it is the primary MDP rdma device and
MDP DMA
+		 * ops should be handled by its DMA callbacks.
+		 */
+		mdp->rdma_dev = dev;
+	}
+
 	pm_runtime_enable(dev);
 
 	return 0;
@@ -237,23 +274,9 @@ int mtk_mdp_comp_init(struct mtk_mdp_comp *comp,
struct device *dev)
 static int mtk_mdp_comp_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct device_node *vpu_node;
 	int status;
 	struct mtk_mdp_comp *comp;
 
-	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
-	if (vpu_node) {
-		of_node_put(vpu_node);
-		/*
-		 * The device tree node with a mediatek,vpu property is
deemed
-		 * the MDP "master" device, we don't want to add a
component
-		 * for it in this function because the initialization
for the
-		 * master is done elsewhere.
-		 */
-		dev_info(dev, "vpu node found, not probing\n");
-		return -ENODEV;
-	}
-
 	comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
 	if (!comp)
 		return -ENOMEM;
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index a72a9ba41ea6..50eafcc9993d 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -159,6 +159,17 @@ static int mtk_mdp_master_bind(struct device
*dev)
 		goto err_component_bind_all;
 	}
 
+	if (mdp->vpu_dev) {
+		int ret = vpu_wdt_reg_handler(mdp->vpu_dev,
mtk_mdp_reset_handler, mdp,
+					  VPU_RST_MDP);
+		if (ret) {
+			dev_err(dev, "Failed to register reset
handler\n");
+			goto err_wdt_reg;
+		}
+	} else {
+		dev_err(dev, "no vpu_dev found\n");
+	}
+
 	status = mtk_mdp_register_m2m_device(mdp);
 	if (status) {
 		dev_err(dev, "Failed to register m2m device: %d\n",
status);
@@ -170,6 +181,8 @@ static int mtk_mdp_master_bind(struct device
*dev)
 	return 0;
 
 err_mtk_mdp_register_m2m_device:
+
+err_wdt_reg:
 	component_unbind_all(dev, mdp);
 
 err_component_bind_all:
@@ -228,8 +241,13 @@ static int mtk_mdp_probe(struct platform_device
*pdev)
 		of_node_put(node);
 		parent = dev->of_node;
 		dev_warn(dev, "device tree is out of date\n");
-	} else {
+	} else if (dev->of_node) {
 		parent = dev->of_node->parent;
+	} else if (dev->parent) {
+		/* maybe we were created from a call to
platform_device_register_data() */
+		parent = dev->parent->parent->of_node;
+	} else {
+		return -ENODEV;
 	}
 
 	/* Iterate over sibling MDP function blocks */
@@ -262,16 +280,6 @@ static int mtk_mdp_probe(struct platform_device
*pdev)
 		}
 	}
 
-	/*
-	 * Create a component for myself so that clocks can be toggled
in
-	 * clock_on().
-	 */
-	ret = mtk_mdp_comp_init(&mdp->comp_self, dev);
-	if (ret) {
-		dev_err(dev, "Failed to initialize component\n");
-		goto err_comp;
-	}
-
 	mdp->job_wq =
create_singlethread_workqueue(MTK_MDP_MODULE_NAME);
 	if (!mdp->job_wq) {
 		dev_err(&pdev->dev, "unable to alloc job workqueue\n");
@@ -287,29 +295,8 @@ static int mtk_mdp_probe(struct platform_device
*pdev)
 	}
 	INIT_WORK(&mdp->wdt_work, mtk_mdp_wdt_worker);
 
-	ret = v4l2_device_register(dev, &mdp->v4l2_dev);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to register v4l2
device\n");
-		ret = -EINVAL;
-		goto err_dev_register;
-	}
-
-	mdp->vpu_dev = vpu_get_plat_device(pdev);
-	ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler,
mdp,
-				  VPU_RST_MDP);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to register reset
handler\n");
-		goto err_wdt_reg;
-	}
-
 	platform_set_drvdata(pdev, mdp);
 
-	ret = vb2_dma_contig_set_max_seg_size(&pdev->dev,
DMA_BIT_MASK(32));
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to set vb2 dma mag seg
size\n");
-		goto err_set_max_seg_size;
-	}
-
 	ret = component_master_add_with_match(dev, &mtk_mdp_com_ops,
match);
 	if (ret) {
 		dev_err(dev, "Component master add failed\n");
@@ -321,22 +308,12 @@ static int mtk_mdp_probe(struct platform_device
*pdev)
 	return 0;
 
 err_component_master_add:
-	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
-
-err_set_max_seg_size:
-
-err_wdt_reg:
-	v4l2_device_unregister(&mdp->v4l2_dev);
-
-err_dev_register:
 	destroy_workqueue(mdp->wdt_wq);
 
 err_alloc_wdt_wq:
 	destroy_workqueue(mdp->job_wq);
 
 err_alloc_job_wq:
-
-err_comp:
 	dev_dbg(dev, "err %d\n", ret);
 	return ret;
 }
@@ -404,7 +381,6 @@ static struct platform_driver mtk_mdp_driver = {
 	.driver = {
 		.name	= MTK_MDP_MODULE_NAME,
 		.pm	= &mtk_mdp_pm_ops,
-		.of_match_table = mtk_mdp_of_ids,
 	}
 };
 
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
index 8a52539b15d4..9fcd8b8e7c25 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
@@ -133,6 +133,7 @@ struct mtk_mdp_variant {
  * struct mtk_mdp_dev - abstraction for image processor entity
  * @lock:	the mutex protecting this data structure
  * @vpulock:	the mutex protecting the communication with VPU
+ * @rdma_dev:  device pointer to rdma device for MDP
  * @pdev:	pointer to the image processor platform device
  * @variant:	the IP variant information
  * @id:		image processor device index
(0..MTK_MDP_MAX_DEVS)
@@ -151,6 +152,7 @@ struct mtk_mdp_variant {
 struct mtk_mdp_dev {
 	struct mutex			lock;
 	struct mutex			vpulock;
+	struct device			*rdma_dev;
 	struct platform_device		*pdev;
 	struct mtk_mdp_variant		*variant;
 	u16				id;
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
index f14779e7596e..9834d3bbe851 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
@@ -929,7 +929,7 @@ static int mtk_mdp_m2m_queue_init(void *priv,
struct vb2_queue *src_vq,
 	src_vq->mem_ops = &vb2_dma_contig_memops;
 	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
 	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-	src_vq->dev = &ctx->mdp_dev->pdev->dev;
+	src_vq->dev = ctx->mdp_dev->rdma_dev;
 	src_vq->lock = &ctx->mdp_dev->lock;
 
 	ret = vb2_queue_init(src_vq);
@@ -944,7 +944,7 @@ static int mtk_mdp_m2m_queue_init(void *priv,
struct vb2_queue *src_vq,
 	dst_vq->mem_ops = &vb2_dma_contig_memops;
 	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
 	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-	dst_vq->dev = &ctx->mdp_dev->pdev->dev;
+	dst_vq->dev = ctx->mdp_dev->rdma_dev;
 	dst_vq->lock = &ctx->mdp_dev->lock;
 
 	return vb2_queue_init(dst_vq);
-- 
2.32.0.554.ge1b32706d8-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

[PATCH v6 6/9] soc: mediatek: mmsys: instantiate mdp virtual device from mmsys

From: Eizan Miyamoto <hidden>
Date: 2021-08-02 12:13:16

A virtual device that is probed by the mtk_mdp_core driver is
instantiated by the mtk_mmsys driver.

This better reflects the logical organization of the hardware and
driver: there are a number of hardware blocks that are used by the MDP
that have no strict hierarchy, and the software driver is responsible
for driving them properly.

Signed-off-by: Eizan Miyamoto <redacted>
---

(no changes since v1)

 drivers/soc/mediatek/mtk-mmsys.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 080660ef11bf..e681029fe804 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -97,6 +97,7 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 	struct platform_device *clks;
 	struct platform_device *drm;
 	struct mtk_mmsys *mmsys;
+	struct platform_device *mdp;
 	int ret;
 
 	mmsys = devm_kzalloc(dev, sizeof(*mmsys), GFP_KERNEL);
@@ -122,10 +123,27 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 					    PLATFORM_DEVID_AUTO, NULL, 0);
 	if (IS_ERR(drm)) {
 		platform_device_unregister(clks);
-		return PTR_ERR(drm);
+		ret = PTR_ERR(drm);
+		goto err_drm;
+	}
+
+	mdp = platform_device_register_data(&pdev->dev, "mtk-mdp",
+					    PLATFORM_DEVID_AUTO, NULL, 0);
+	if (IS_ERR(mdp)) {
+		ret = PTR_ERR(mdp);
+		dev_err(dev, "Failed to register mdp: %d\n", ret);
+		goto err_mdp;
 	}
 
 	return 0;
+
+err_mdp:
+	platform_device_unregister(drm);
+
+err_drm:
+	platform_device_unregister(clks);
+
+	return ret;
 }
 
 static const struct of_device_id of_match_mtk_mmsys[] = {
-- 
2.32.0.554.ge1b32706d8-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 6/9] soc: mediatek: mmsys: instantiate mdp virtual device from mmsys

From: Enric Balletbo Serra <eballetbo@gmail.com>
Date: 2021-08-03 10:27:28

Hi Eizan,

Thank you for your patch.

Missatge de Eizan Miyamoto [off-list ref] del dia dl., 2 d’ag.
2021 a les 14:14:
A virtual device that is probed by the mtk_mdp_core driver is
instantiated by the mtk_mmsys driver.

This better reflects the logical organization of the hardware and
driver: there are a number of hardware blocks that are used by the MDP
that have no strict hierarchy, and the software driver is responsible
for driving them properly.

Signed-off-by: Eizan Miyamoto <redacted>
Reviewed-by: Enric Balletbo i Serra <redacted>

quoted hunk
---

(no changes since v1)

 drivers/soc/mediatek/mtk-mmsys.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 080660ef11bf..e681029fe804 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -97,6 +97,7 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
        struct platform_device *clks;
        struct platform_device *drm;
        struct mtk_mmsys *mmsys;
+       struct platform_device *mdp;
        int ret;

        mmsys = devm_kzalloc(dev, sizeof(*mmsys), GFP_KERNEL);
@@ -122,10 +123,27 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
                                            PLATFORM_DEVID_AUTO, NULL, 0);
        if (IS_ERR(drm)) {
                platform_device_unregister(clks);
-               return PTR_ERR(drm);
+               ret = PTR_ERR(drm);
+               goto err_drm;
+       }
+
+       mdp = platform_device_register_data(&pdev->dev, "mtk-mdp",
+                                           PLATFORM_DEVID_AUTO, NULL, 0);
+       if (IS_ERR(mdp)) {
+               ret = PTR_ERR(mdp);
+               dev_err(dev, "Failed to register mdp: %d\n", ret);
+               goto err_mdp;
        }

        return 0;
+
+err_mdp:
+       platform_device_unregister(drm);
+
+err_drm:
+       platform_device_unregister(clks);
+
+       return ret;
 }

 static const struct of_device_id of_match_mtk_mmsys[] = {
--
2.32.0.554.ge1b32706d8-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 6/9] soc: mediatek: mmsys: instantiate mdp virtual device from mmsys

From: houlong wei <houlong.wei@mediatek.com>
Date: 2021-08-16 01:18:28

On Mon, 2021-08-02 at 20:12 +0800, Eizan Miyamoto wrote:
A virtual device that is probed by the mtk_mdp_core driver is
instantiated by the mtk_mmsys driver.

This better reflects the logical organization of the hardware and
driver: there are a number of hardware blocks that are used by the
MDP
that have no strict hierarchy, and the software driver is responsible
for driving them properly.

Signed-off-by: Eizan Miyamoto <redacted>
---
Reviewed-by: Houlong Wei <houlong.wei@mediatek.com>
quoted hunk
(no changes since v1)

 drivers/soc/mediatek/mtk-mmsys.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/mediatek/mtk-mmsys.c
b/drivers/soc/mediatek/mtk-mmsys.c
index 080660ef11bf..e681029fe804 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -97,6 +97,7 @@ static int mtk_mmsys_probe(struct platform_device
*pdev)
 	struct platform_device *clks;
 	struct platform_device *drm;
 	struct mtk_mmsys *mmsys;
+	struct platform_device *mdp;
 	int ret;
 
 	mmsys = devm_kzalloc(dev, sizeof(*mmsys), GFP_KERNEL);
@@ -122,10 +123,27 @@ static int mtk_mmsys_probe(struct
platform_device *pdev)
 					    PLATFORM_DEVID_AUTO, NULL,
0);
 	if (IS_ERR(drm)) {
 		platform_device_unregister(clks);
-		return PTR_ERR(drm);
+		ret = PTR_ERR(drm);
+		goto err_drm;
+	}
+
+	mdp = platform_device_register_data(&pdev->dev, "mtk-mdp",
+					    PLATFORM_DEVID_AUTO, NULL,
0);
+	if (IS_ERR(mdp)) {
+		ret = PTR_ERR(mdp);
+		dev_err(dev, "Failed to register mdp: %d\n", ret);
+		goto err_mdp;
 	}
 
 	return 0;
+
+err_mdp:
+	platform_device_unregister(drm);
+
+err_drm:
+	platform_device_unregister(clks);
+
+	return ret;
 }
 
 static const struct of_device_id of_match_mtk_mmsys[] = {
-- 
2.32.0.554.ge1b32706d8-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

[PATCH v6 7/9] media: mtk-mdp: use mdp-rdma0 alias to point to MDP master

From: Eizan Miyamoto <hidden>
Date: 2021-08-02 12:13:23

... Instead of depending on the presence of a mediatek,vpu property in
the device node.

That property was originally added to link to the vpu node so that the
mtk_mdp_core driver could pass the right device to
vpu_wdt_reg_handler(). However in a previous patch in this series,
the driver has been modified to search the device tree for that node
instead.

That property was also used to indicate the primary MDP device, so that
it can be passed to the V4L2 subsystem as well as register it to be
used when setting up queues in the open() callback for the filesystem
device node that is created. In this case, assuming that the primary
MDP device is the one with a specific alias seems useable because the
alternative is to add a property to the device tree which doesn't
actually represent any facet of hardware (i.e., this being the primary
MDP device is a software decision). In other words, this solution is
equally as arbitrary, but at least it doesn't add a property to a
device node where said property is unrelated to the hardware present.

Signed-off-by: Eizan Miyamoto <redacted>
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 56 +++++++++++++------
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 36 ++++++++----
 2 files changed, 64 insertions(+), 28 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 85ef274841a3..9527649de98e 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -151,29 +151,50 @@ void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
 		mtk_smi_larb_put(comp->larb_dev);
 }
 
-static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
+/*
+ * The MDP master device node is identified by the device tree alias
+ * "mdp-rdma0".
+ */
+static bool is_mdp_master(struct device *dev)
+{
+	struct device_node *aliases, *mdp_rdma0_node;
+	const char *mdp_rdma0_path;
+
+	if (!dev->of_node)
+		return false;
+
+	aliases = of_find_node_by_path("/aliases");
+	if (!aliases) {
+		dev_err(dev, "no aliases found for mdp-rdma0");
+		return false;
+	}
+
+	mdp_rdma0_path = of_get_property(aliases, "mdp-rdma0", NULL);
+	if (!mdp_rdma0_path) {
+		dev_err(dev, "get mdp-rdma0 property of /aliases failed");
+		return false;
+	}
+
+	mdp_rdma0_node = of_find_node_by_path(mdp_rdma0_path);
+	if (!mdp_rdma0_node) {
+		dev_err(dev, "path resolution failed for %s", mdp_rdma0_path);
+		return false;
+	}
+
+	return dev->of_node == mdp_rdma0_node;
+}
+
+static int mtk_mdp_comp_bind(struct device *dev, struct device *master,
+			void *data)
 {
 	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
 	struct mtk_mdp_dev *mdp = data;
-	struct device_node *vpu_node;
 
 	mtk_mdp_register_component(mdp, comp);
 
-	/*
-	 * If this component has a "mediatek-vpu" property, it is responsible for
-	 * notifying the mdp master driver about it so it can be further initialized
-	 * later.
-	 */
-	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
-	if (vpu_node) {
+	if (is_mdp_master(dev)) {
 		int ret;
 
-		mdp->vpu_dev = of_find_device_by_node(vpu_node);
-		if (WARN_ON(!mdp->vpu_dev)) {
-			dev_err(dev, "vpu pdev failed\n");
-			of_node_put(vpu_node);
-		}
-
 		ret = v4l2_device_register(dev, &mdp->v4l2_dev);
 		if (ret) {
 			dev_err(dev, "Failed to register v4l2 device\n");
@@ -187,9 +208,8 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
 		}
 
 		/*
-		 * presence of the "mediatek,vpu" property in a device node
-		 * indicates that it is the primary MDP rdma device and MDP DMA
-		 * ops should be handled by its DMA callbacks.
+		 * MDP DMA ops will be handled by the DMA callbacks associated with this
+		 * device;
 		 */
 		mdp->rdma_dev = dev;
 	}
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 50eafcc9993d..6a775463399c 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -150,8 +150,9 @@ static void release_of(struct device *dev, void *data)
 
 static int mtk_mdp_master_bind(struct device *dev)
 {
-	int status;
 	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
+	struct device_node *vpu_node;
+	int status;
 
 	status = component_bind_all(dev, mdp);
 	if (status) {
@@ -159,15 +160,30 @@ static int mtk_mdp_master_bind(struct device *dev)
 		goto err_component_bind_all;
 	}
 
-	if (mdp->vpu_dev) {
-		int ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
-					  VPU_RST_MDP);
-		if (ret) {
-			dev_err(dev, "Failed to register reset handler\n");
-			goto err_wdt_reg;
-		}
-	} else {
-		dev_err(dev, "no vpu_dev found\n");
+	if (mdp->rdma_dev == NULL) {
+		dev_err(dev, "Primary MDP device not found");
+		status = -ENODEV;
+		goto err_component_bind_all;
+	}
+
+	vpu_node = of_find_node_by_name(NULL, "vpu");
+	if (!vpu_node) {
+		dev_err(dev, "unable to find vpu node");
+		status = -ENODEV;
+		goto err_wdt_reg;
+	}
+
+	mdp->vpu_dev = of_find_device_by_node(vpu_node);
+	if (!mdp->vpu_dev) {
+		dev_err(dev, "unable to find vpu device");
+		status = -ENODEV;
+		goto err_wdt_reg;
+	}
+
+	status = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp, VPU_RST_MDP);
+	if (status) {
+		dev_err(dev, "Failed to register reset handler\n");
+		goto err_wdt_reg;
 	}
 
 	status = mtk_mdp_register_m2m_device(mdp);
-- 
2.32.0.554.ge1b32706d8-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 7/9] media: mtk-mdp: use mdp-rdma0 alias to point to MDP master

From: Enric Balletbo Serra <eballetbo@gmail.com>
Date: 2021-08-03 10:27:49

Hi Eizan,

Thank you for your patch.

Missatge de Eizan Miyamoto [off-list ref] del dia dl., 2 d’ag.
2021 a les 14:14:
... Instead of depending on the presence of a mediatek,vpu property in
Looks like there is something missing in the commit message?
the device node.

That property was originally added to link to the vpu node so that the
mtk_mdp_core driver could pass the right device to
vpu_wdt_reg_handler(). However in a previous patch in this series,
the driver has been modified to search the device tree for that node
instead.

That property was also used to indicate the primary MDP device, so that
it can be passed to the V4L2 subsystem as well as register it to be
used when setting up queues in the open() callback for the filesystem
device node that is created. In this case, assuming that the primary
MDP device is the one with a specific alias seems useable because the
alternative is to add a property to the device tree which doesn't
actually represent any facet of hardware (i.e., this being the primary
MDP device is a software decision). In other words, this solution is
equally as arbitrary, but at least it doesn't add a property to a
device node where said property is unrelated to the hardware present.

Signed-off-by: Eizan Miyamoto <redacted>
Other than the above,

Reviewed-by: Enric Balletbo i Serra <redacted>


quoted hunk
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 56 +++++++++++++------
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 36 ++++++++----
 2 files changed, 64 insertions(+), 28 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 85ef274841a3..9527649de98e 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -151,29 +151,50 @@ void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
                mtk_smi_larb_put(comp->larb_dev);
 }

-static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
+/*
+ * The MDP master device node is identified by the device tree alias
+ * "mdp-rdma0".
+ */
+static bool is_mdp_master(struct device *dev)
+{
+       struct device_node *aliases, *mdp_rdma0_node;
+       const char *mdp_rdma0_path;
+
+       if (!dev->of_node)
+               return false;
+
+       aliases = of_find_node_by_path("/aliases");
+       if (!aliases) {
+               dev_err(dev, "no aliases found for mdp-rdma0");
+               return false;
+       }
+
+       mdp_rdma0_path = of_get_property(aliases, "mdp-rdma0", NULL);
+       if (!mdp_rdma0_path) {
+               dev_err(dev, "get mdp-rdma0 property of /aliases failed");
+               return false;
+       }
+
+       mdp_rdma0_node = of_find_node_by_path(mdp_rdma0_path);
+       if (!mdp_rdma0_node) {
+               dev_err(dev, "path resolution failed for %s", mdp_rdma0_path);
+               return false;
+       }
+
+       return dev->of_node == mdp_rdma0_node;
+}
+
+static int mtk_mdp_comp_bind(struct device *dev, struct device *master,
+                       void *data)
 {
        struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
        struct mtk_mdp_dev *mdp = data;
-       struct device_node *vpu_node;

        mtk_mdp_register_component(mdp, comp);

-       /*
-        * If this component has a "mediatek-vpu" property, it is responsible for
-        * notifying the mdp master driver about it so it can be further initialized
-        * later.
-        */
-       vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
-       if (vpu_node) {
+       if (is_mdp_master(dev)) {
                int ret;

-               mdp->vpu_dev = of_find_device_by_node(vpu_node);
-               if (WARN_ON(!mdp->vpu_dev)) {
-                       dev_err(dev, "vpu pdev failed\n");
-                       of_node_put(vpu_node);
-               }
-
                ret = v4l2_device_register(dev, &mdp->v4l2_dev);
                if (ret) {
                        dev_err(dev, "Failed to register v4l2 device\n");
@@ -187,9 +208,8 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
                }

                /*
-                * presence of the "mediatek,vpu" property in a device node
-                * indicates that it is the primary MDP rdma device and MDP DMA
-                * ops should be handled by its DMA callbacks.
+                * MDP DMA ops will be handled by the DMA callbacks associated with this
+                * device;
                 */
                mdp->rdma_dev = dev;
        }
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 50eafcc9993d..6a775463399c 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -150,8 +150,9 @@ static void release_of(struct device *dev, void *data)

 static int mtk_mdp_master_bind(struct device *dev)
 {
-       int status;
        struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
+       struct device_node *vpu_node;
+       int status;

        status = component_bind_all(dev, mdp);
        if (status) {
@@ -159,15 +160,30 @@ static int mtk_mdp_master_bind(struct device *dev)
                goto err_component_bind_all;
        }

-       if (mdp->vpu_dev) {
-               int ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
-                                         VPU_RST_MDP);
-               if (ret) {
-                       dev_err(dev, "Failed to register reset handler\n");
-                       goto err_wdt_reg;
-               }
-       } else {
-               dev_err(dev, "no vpu_dev found\n");
+       if (mdp->rdma_dev == NULL) {
+               dev_err(dev, "Primary MDP device not found");
+               status = -ENODEV;
+               goto err_component_bind_all;
+       }
+
+       vpu_node = of_find_node_by_name(NULL, "vpu");
+       if (!vpu_node) {
+               dev_err(dev, "unable to find vpu node");
+               status = -ENODEV;
+               goto err_wdt_reg;
+       }
+
+       mdp->vpu_dev = of_find_device_by_node(vpu_node);
+       if (!mdp->vpu_dev) {
+               dev_err(dev, "unable to find vpu device");
+               status = -ENODEV;
+               goto err_wdt_reg;
+       }
+
+       status = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp, VPU_RST_MDP);
+       if (status) {
+               dev_err(dev, "Failed to register reset handler\n");
+               goto err_wdt_reg;
        }

        status = mtk_mdp_register_m2m_device(mdp);
--
2.32.0.554.ge1b32706d8-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 7/9] media: mtk-mdp: use mdp-rdma0 alias to point to MDP master

From: Eizan Miyamoto <hidden>
Date: 2021-08-03 11:49:27

Hi Enric, thanks for your comment.
quoted
... Instead of depending on the presence of a mediatek,vpu property in
Looks like there is something missing in the commit message?
That line is a continuation of the commit message header, I.e., it's
meant to read:
"use mdp-rdma0 alias to point to MDP master Instead of depending on
the presence of a mediatek,vpu property in the device node"

Eizan

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 7/9] media: mtk-mdp: use mdp-rdma0 alias to point to MDP master

From: houlong wei <houlong.wei@mediatek.com>
Date: 2021-08-16 03:00:56

On Mon, 2021-08-02 at 20:12 +0800, Eizan Miyamoto wrote:
quoted hunk
... Instead of depending on the presence of a mediatek,vpu property
in
the device node.

That property was originally added to link to the vpu node so that
the
mtk_mdp_core driver could pass the right device to
vpu_wdt_reg_handler(). However in a previous patch in this series,
the driver has been modified to search the device tree for that node
instead.

That property was also used to indicate the primary MDP device, so
that
it can be passed to the V4L2 subsystem as well as register it to be
used when setting up queues in the open() callback for the filesystem
device node that is created. In this case, assuming that the primary
MDP device is the one with a specific alias seems useable because the
alternative is to add a property to the device tree which doesn't
actually represent any facet of hardware (i.e., this being the
primary
MDP device is a software decision). In other words, this solution is
equally as arbitrary, but at least it doesn't add a property to a
device node where said property is unrelated to the hardware present.

Signed-off-by: Eizan Miyamoto <redacted>
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 56 +++++++++++++--
----
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 36 ++++++++----
 2 files changed, 64 insertions(+), 28 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 85ef274841a3..9527649de98e 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -151,29 +151,50 @@ void mtk_mdp_comp_clock_off(struct mtk_mdp_comp
*comp)
 		mtk_smi_larb_put(comp->larb_dev);
 }
 
-static int mtk_mdp_comp_bind(struct device *dev, struct device
*master, void *data)
+/*
+ * The MDP master device node is identified by the device tree alias
+ * "mdp-rdma0".
+ */
+static bool is_mdp_master(struct device *dev)
+{
+	struct device_node *aliases, *mdp_rdma0_node;
+	const char *mdp_rdma0_path;
+
+	if (!dev->of_node)
+		return false;
+
+	aliases = of_find_node_by_path("/aliases");
+	if (!aliases) {
+		dev_err(dev, "no aliases found for mdp-rdma0");
+		return false;
+	}
+
+	mdp_rdma0_path = of_get_property(aliases, "mdp-rdma0", NULL);
+	if (!mdp_rdma0_path) {
+		dev_err(dev, "get mdp-rdma0 property of /aliases
failed");
+		return false;
+	}
+
+	mdp_rdma0_node = of_find_node_by_path(mdp_rdma0_path);
+	if (!mdp_rdma0_node) {
+		dev_err(dev, "path resolution failed for %s",
mdp_rdma0_path);
+		return false;
+	}
+
Hi Eizan,

"mdp-rdma0" may be not the only one master device node. In fact, there
are 2 "mdp-rdma" in mt8173. You can see "mdp_rdma1" via below link.

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/arm64/boot/dts/mediatek/mt8173.dtsi?h=v5.13.11#n1016
If we add "mediatek,mt8173-mdp" to "mdp_rdma1" like below, we will have
one more V4L2 video devie node.

		mdp_rdma1: rdma@14002000 {
			compatible = "mediatek,mt8173-mdp-rdma",
				     "mediatek,mt8173-mdp";
			...
		}

We should consider the case that there are more than one "MDP_RDMA"
components. 

Regards,
Houlong
quoted hunk
+	return dev->of_node == mdp_rdma0_node;
+}
+
+static int mtk_mdp_comp_bind(struct device *dev, struct device
*master,
+			void *data)
 {
 	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
 	struct mtk_mdp_dev *mdp = data;
-	struct device_node *vpu_node;
 
 	mtk_mdp_register_component(mdp, comp);
 
-	/*
-	 * If this component has a "mediatek-vpu" property, it is
responsible for
-	 * notifying the mdp master driver about it so it can be
further initialized
-	 * later.
-	 */
-	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
-	if (vpu_node) {
+	if (is_mdp_master(dev)) {
 		int ret;
 
-		mdp->vpu_dev = of_find_device_by_node(vpu_node);
-		if (WARN_ON(!mdp->vpu_dev)) {
-			dev_err(dev, "vpu pdev failed\n");
-			of_node_put(vpu_node);
-		}
-
 		ret = v4l2_device_register(dev, &mdp->v4l2_dev);
 		if (ret) {
 			dev_err(dev, "Failed to register v4l2
device\n");
@@ -187,9 +208,8 @@ static int mtk_mdp_comp_bind(struct device *dev,
struct device *master, void *da
 		}
 
 		/*
-		 * presence of the "mediatek,vpu" property in a device
node
-		 * indicates that it is the primary MDP rdma device and
MDP DMA
-		 * ops should be handled by its DMA callbacks.
+		 * MDP DMA ops will be handled by the DMA callbacks
associated with this
+		 * device;
 		 */
 		mdp->rdma_dev = dev;
 	}
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 50eafcc9993d..6a775463399c 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -150,8 +150,9 @@ static void release_of(struct device *dev, void
*data)
 
 static int mtk_mdp_master_bind(struct device *dev)
 {
-	int status;
 	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
+	struct device_node *vpu_node;
+	int status;
 
 	status = component_bind_all(dev, mdp);
 	if (status) {
@@ -159,15 +160,30 @@ static int mtk_mdp_master_bind(struct device
*dev)
 		goto err_component_bind_all;
 	}
 
-	if (mdp->vpu_dev) {
-		int ret = vpu_wdt_reg_handler(mdp->vpu_dev,
mtk_mdp_reset_handler, mdp,
-					  VPU_RST_MDP);
-		if (ret) {
-			dev_err(dev, "Failed to register reset
handler\n");
-			goto err_wdt_reg;
-		}
-	} else {
-		dev_err(dev, "no vpu_dev found\n");
+	if (mdp->rdma_dev == NULL) {
+		dev_err(dev, "Primary MDP device not found");
+		status = -ENODEV;
+		goto err_component_bind_all;
+	}
+
+	vpu_node = of_find_node_by_name(NULL, "vpu");
+	if (!vpu_node) {
+		dev_err(dev, "unable to find vpu node");
+		status = -ENODEV;
+		goto err_wdt_reg;
+	}
+
+	mdp->vpu_dev = of_find_device_by_node(vpu_node);
+	if (!mdp->vpu_dev) {
+		dev_err(dev, "unable to find vpu device");
+		status = -ENODEV;
+		goto err_wdt_reg;
+	}
+
+	status = vpu_wdt_reg_handler(mdp->vpu_dev,
mtk_mdp_reset_handler, mdp, VPU_RST_MDP);
+	if (status) {
+		dev_err(dev, "Failed to register reset handler\n");
+		goto err_wdt_reg;
 	}
 
 	status = mtk_mdp_register_m2m_device(mdp);
-- 
2.32.0.554.ge1b32706d8-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 7/9] media: mtk-mdp: use mdp-rdma0 alias to point to MDP master

From: houlong wei <houlong.wei@mediatek.com>
Date: 2021-08-16 04:53:10

On Mon, 2021-08-16 at 11:00 +0800, houlong wei wrote:
On Mon, 2021-08-02 at 20:12 +0800, Eizan Miyamoto wrote:
quoted
... Instead of depending on the presence of a mediatek,vpu property
in
the device node.

That property was originally added to link to the vpu node so that
the
mtk_mdp_core driver could pass the right device to
vpu_wdt_reg_handler(). However in a previous patch in this series,
the driver has been modified to search the device tree for that
node
instead.

That property was also used to indicate the primary MDP device, so
that
it can be passed to the V4L2 subsystem as well as register it to be
used when setting up queues in the open() callback for the
filesystem
device node that is created. In this case, assuming that the
primary
MDP device is the one with a specific alias seems useable because
the
alternative is to add a property to the device tree which doesn't
actually represent any facet of hardware (i.e., this being the
primary
MDP device is a software decision). In other words, this solution
is
equally as arbitrary, but at least it doesn't add a property to a
device node where said property is unrelated to the hardware
present.

Signed-off-by: Eizan Miyamoto <redacted>
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 56 +++++++++++++--
----
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 36 ++++++++----
 2 files changed, 64 insertions(+), 28 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 85ef274841a3..9527649de98e 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -151,29 +151,50 @@ void mtk_mdp_comp_clock_off(struct
mtk_mdp_comp
*comp)
 		mtk_smi_larb_put(comp->larb_dev);
 }
 
-static int mtk_mdp_comp_bind(struct device *dev, struct device
*master, void *data)
+/*
+ * The MDP master device node is identified by the device tree
alias
+ * "mdp-rdma0".
+ */
+static bool is_mdp_master(struct device *dev)
+{
+	struct device_node *aliases, *mdp_rdma0_node;
+	const char *mdp_rdma0_path;
+
+	if (!dev->of_node)
+		return false;
+
+	aliases = of_find_node_by_path("/aliases");
+	if (!aliases) {
+		dev_err(dev, "no aliases found for mdp-rdma0");
+		return false;
+	}
+
+	mdp_rdma0_path = of_get_property(aliases, "mdp-rdma0", NULL);
+	if (!mdp_rdma0_path) {
+		dev_err(dev, "get mdp-rdma0 property of /aliases
failed");
+		return false;
+	}
+
+	mdp_rdma0_node = of_find_node_by_path(mdp_rdma0_path);
+	if (!mdp_rdma0_node) {
+		dev_err(dev, "path resolution failed for %s",
mdp_rdma0_path);
+		return false;
+	}
+
Hi Eizan,

"mdp-rdma0" may be not the only one master device node. In fact,
there
are 2 "mdp-rdma" in mt8173. You can see "mdp_rdma1" via below link.
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/arm64/boot/dts/mediatek/mt8173.dtsi?h=v5.13.11#n1016
If we add "mediatek,mt8173-mdp" to "mdp_rdma1" like below, we will
have
one more V4L2 video devie node.

		mdp_rdma1: rdma@14002000 {
			compatible = "mediatek,mt8173-mdp-rdma",
				     "mediatek,mt8173-mdp";
			...
		}

We should consider the case that there are more than one "MDP_RDMA"
components. 

Regards,
Houlong
quoted
+	return dev->of_node == mdp_rdma0_node;
+}
+
+static int mtk_mdp_comp_bind(struct device *dev, struct device
*master,
+			void *data)
 {
 	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
 	struct mtk_mdp_dev *mdp = data;
-	struct device_node *vpu_node;
 
 	mtk_mdp_register_component(mdp, comp);
 
-	/*
-	 * If this component has a "mediatek-vpu" property, it is
responsible for
-	 * notifying the mdp master driver about it so it can be
further initialized
-	 * later.
-	 */
-	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
-	if (vpu_node) {
+	if (is_mdp_master(dev)) {
 		int ret;
 
-		mdp->vpu_dev = of_find_device_by_node(vpu_node);
-		if (WARN_ON(!mdp->vpu_dev)) {
-			dev_err(dev, "vpu pdev failed\n");
-			of_node_put(vpu_node);
-		}
-
 		ret = v4l2_device_register(dev, &mdp->v4l2_dev);
 		if (ret) {
 			dev_err(dev, "Failed to register v4l2
device\n");
@@ -187,9 +208,8 @@ static int mtk_mdp_comp_bind(struct device
*dev,
struct device *master, void *da
 		}
 
 		/*
-		 * presence of the "mediatek,vpu" property in a device
node
-		 * indicates that it is the primary MDP rdma device and
MDP DMA
-		 * ops should be handled by its DMA callbacks.
+		 * MDP DMA ops will be handled by the DMA callbacks
associated with this
+		 * device;
 		 */
 		mdp->rdma_dev = dev;
 	}
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 50eafcc9993d..6a775463399c 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -150,8 +150,9 @@ static void release_of(struct device *dev, void
*data)
 
 static int mtk_mdp_master_bind(struct device *dev)
 {
-	int status;
 	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
+	struct device_node *vpu_node;
+	int status;
 
 	status = component_bind_all(dev, mdp);
 	if (status) {
@@ -159,15 +160,30 @@ static int mtk_mdp_master_bind(struct device
*dev)
 		goto err_component_bind_all;
 	}
 
-	if (mdp->vpu_dev) {
-		int ret = vpu_wdt_reg_handler(mdp->vpu_dev,
mtk_mdp_reset_handler, mdp,
-					  VPU_RST_MDP);
-		if (ret) {
-			dev_err(dev, "Failed to register reset
handler\n");
-			goto err_wdt_reg;
-		}
-	} else {
-		dev_err(dev, "no vpu_dev found\n");
+	if (mdp->rdma_dev == NULL) {
+		dev_err(dev, "Primary MDP device not found");
+		status = -ENODEV;
+		goto err_component_bind_all;
+	}
+
+	vpu_node = of_find_node_by_name(NULL, "vpu");
+	if (!vpu_node) {
+		dev_err(dev, "unable to find vpu node");
+		status = -ENODEV;
+		goto err_wdt_reg;
+	}
Hi Eizan,

Is your removing "mediatek,vpu" necessary for this series "Refactor MTK
MDP driver into core/components" ?

In some MediaTek projects (not upstream yet), the device-tree node name
"vpu" may be changed to something like "vpu0", "vpu1" or other name,
which depends on the implementation of "mtk-vpu" driver. We can specify
the different phandle to "mediatek,vpu" in .dtsi file. If we use
of_find_node_by_name() to get the vpu_node, we have to modify the name
string in different project.
If the answer of my previous questions is "No", I prefer to slow down
the modification of removing "mediatek,vpu".

Sorry for late reply.

Regards,
Houlong
quoted
+
+	mdp->vpu_dev = of_find_device_by_node(vpu_node);
+	if (!mdp->vpu_dev) {
+		dev_err(dev, "unable to find vpu device");
+		status = -ENODEV;
+		goto err_wdt_reg;
+	}
+
+	status = vpu_wdt_reg_handler(mdp->vpu_dev,
mtk_mdp_reset_handler, mdp, VPU_RST_MDP);
+	if (status) {
+		dev_err(dev, "Failed to register reset handler\n");
+		goto err_wdt_reg;
 	}
 
 	status = mtk_mdp_register_m2m_device(mdp);
-- 
2.32.0.554.ge1b32706d8-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 7/9] media: mtk-mdp: use mdp-rdma0 alias to point to MDP master

From: Eizan Miyamoto <hidden>
Date: 2021-08-18 07:51:02

Hi Houlong,

Thank you for your review on this series, it is much appreciated.

On Mon, Aug 16, 2021 at 2:53 PM houlong wei [off-list ref] wrote:
Is your removing "mediatek,vpu" necessary for this series "Refactor MTK
MDP driver into core/components" ?
Removing it is not strictly necessary for the series to function, I
will re-upload the series and omit the following changes:
- [PATCH v6 8/9] dts: mtk-mdp: remove mediatek,vpu property from
primary MDP device
- [PATCH v6 9/9] dt-bindings: mediatek: remove vpu requirement from mtk-mdp

Do please let me know if you meant something different.

Thanks,

Eizan



In some MediaTek projects (not upstream yet), the device-tree node name
"vpu" may be changed to something like "vpu0", "vpu1" or other name,
which depends on the implementation of "mtk-vpu" driver. We can specify
the different phandle to "mediatek,vpu" in .dtsi file. If we use
of_find_node_by_name() to get the vpu_node, we have to modify the name
string in different project.
If the answer of my previous questions is "No", I prefer to slow down
the modification of removing "mediatek,vpu".

Sorry for late reply.

Regards,
Houlong
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 7/9] media: mtk-mdp: use mdp-rdma0 alias to point to MDP master

From: houlong wei <houlong.wei@mediatek.com>
Date: 2021-08-18 15:42:59

On Wed, 2021-08-18 at 15:50 +0800, Eizan Miyamoto wrote:
Hi Houlong,

Thank you for your review on this series, it is much appreciated.

On Mon, Aug 16, 2021 at 2:53 PM houlong wei <houlong.wei@mediatek.com
quoted
wrote:
Is your removing "mediatek,vpu" necessary for this series "Refactor
MTK
MDP driver into core/components" ?
Removing it is not strictly necessary for the series to function, I
will re-upload the series and omit the following changes:
- [PATCH v6 8/9] dts: mtk-mdp: remove mediatek,vpu property from
primary MDP device
- [PATCH v6 9/9] dt-bindings: mediatek: remove vpu requirement from
mtk-mdp

Do please let me know if you meant something different.

Thanks,

Eizan
Hi Eizan,

Thanks for your help and effort. It's exactly what I expressed.

Regards,
Houlong
quoted
In some MediaTek projects (not upstream yet), the device-tree node
name
"vpu" may be changed to something like "vpu0", "vpu1" or other
name,
which depends on the implementation of "mtk-vpu" driver. We can
specify
the different phandle to "mediatek,vpu" in .dtsi file. If we use
of_find_node_by_name() to get the vpu_node, we have to modify the
name
string in different project.
If the answer of my previous questions is "No", I prefer to slow
down
the modification of removing "mediatek,vpu".

Sorry for late reply.

Regards,
Houlong
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 7/9] media: mtk-mdp: use mdp-rdma0 alias to point to MDP master

From: Eizan Miyamoto <hidden>
Date: 2021-08-18 07:43:56

Hi Houlong,

On Mon, Aug 16, 2021 at 1:00 PM houlong wei [off-list ref] wrote:
Hi Eizan,

"mdp-rdma0" may be not the only one master device node. In fact, there
are 2 "mdp-rdma" in mt8173. You can see "mdp_rdma1" via below link.

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/arm64/boot/dts/mediatek/mt8173.dtsi?h=v5.13.11#n1016
If we add "mediatek,mt8173-mdp" to "mdp_rdma1" like below, we will have
one more V4L2 video devie node.

                mdp_rdma1: rdma@14002000 {
                        compatible = "mediatek,mt8173-mdp-rdma",
                                     "mediatek,mt8173-mdp";
                        ...
                }

We should consider the case that there are more than one "MDP_RDMA"
components.
Would it be okay with you if we added support for multiple MDP master
device nodes in follow-up changes? My rationale is this:
- As far as I can tell, the mediatek integration with V4L2 currently
only handles a single MDP master device node. It's not clear to me the
scope of changes that will be needed to make things work properly with
multiple nodes.
- The patch series makes video decode work (admittedly, in light of
your comments not optimally) upstream, which is better than not
landing these changes at all.

I'd like to say that I'm very open to (and excited about) discussing
further work to support multiple MDP master nodes, perhaps we can
work together on this so I can understand what needs to be done.

Please let me know your thoughts,

Eizan

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 7/9] media: mtk-mdp: use mdp-rdma0 alias to point to MDP master

From: houlong wei <houlong.wei@mediatek.com>
Date: 2021-08-18 15:34:47

Hi Eizan,

Firstly, about how to determine the master mdp driver, we also can
judge the component type. The component type can be gotten by calling
of_device_get_match_data(dev). If the component is MTK_MDP_RDMA, it is
the master driver. No matter it is mdp_rdma0 or mdp_rdma1.

Secondly, about supporting the multiple MDP master device nodes, you
can try my advice in my previous comment after the completion of this
series of patches.

Thanks a lot.

Regards,
Houlong

On Wed, 2021-08-18 at 15:43 +0800, Eizan Miyamoto wrote:
Hi Houlong,

On Mon, Aug 16, 2021 at 1:00 PM houlong wei <houlong.wei@mediatek.com
quoted
wrote:
Hi Eizan,

"mdp-rdma0" may be not the only one master device node. In fact,
there
are 2 "mdp-rdma" in mt8173. You can see "mdp_rdma1" via below link.
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/arm64/boot/dts/mediatek/mt8173.dtsi?h=v5.13.11#n1016
quoted
If we add "mediatek,mt8173-mdp" to "mdp_rdma1" like below, we will
have
one more V4L2 video devie node.

                mdp_rdma1: rdma@14002000 {
                        compatible = "mediatek,mt8173-mdp-rdma",
                                     "mediatek,mt8173-mdp";
                        ...
                }

We should consider the case that there are more than one "MDP_RDMA"
components.
Would it be okay with you if we added support for multiple MDP master
device nodes in follow-up changes? My rationale is this:
- As far as I can tell, the mediatek integration with V4L2 currently
only handles a single MDP master device node. It's not clear to me
the
scope of changes that will be needed to make things work properly
with
multiple nodes.
- The patch series makes video decode work (admittedly, in light of
your comments not optimally) upstream, which is better than not
landing these changes at all.

I'd like to say that I'm very open to (and excited about) discussing
further work to support multiple MDP master nodes, perhaps we can
work together on this so I can understand what needs to be done.

Please let me know your thoughts,

Eizan
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

[PATCH v6 8/9] dts: mtk-mdp: remove mediatek,vpu property from primary MDP device

From: Eizan Miyamoto <hidden>
Date: 2021-08-02 12:13:33

It is no longer used by the mediatek MDP driver.

Signed-off-by: Eizan Miyamoto <redacted>
---

(no changes since v1)

 arch/arm64/boot/dts/mediatek/mt8173.dtsi | 1 -
 1 file changed, 1 deletion(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index d502073b551f..872427748110 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -1010,7 +1010,6 @@ mdp_rdma0: rdma@14001000 {
 			power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
 			iommus = <&iommu M4U_PORT_MDP_RDMA0>;
 			mediatek,larb = <&larb0>;
-			mediatek,vpu = <&vpu>;
 		};
 
 		mdp_rdma1: rdma@14002000 {
-- 
2.32.0.554.ge1b32706d8-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 8/9] dts: mtk-mdp: remove mediatek,vpu property from primary MDP device

From: Enric Balletbo Serra <eballetbo@gmail.com>
Date: 2021-08-03 10:27:36

Hi Eizan,

Thank you for your patch

Missatge de Eizan Miyamoto [off-list ref] del dia dl., 2 d’ag.
2021 a les 14:14:
It is no longer used by the mediatek MDP driver.

Signed-off-by: Eizan Miyamoto <redacted>
Reviewed-by: Enric Balletbo i Serra <redacted>

quoted hunk
---

(no changes since v1)

 arch/arm64/boot/dts/mediatek/mt8173.dtsi | 1 -
 1 file changed, 1 deletion(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index d502073b551f..872427748110 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -1010,7 +1010,6 @@ mdp_rdma0: rdma@14001000 {
                        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
                        iommus = <&iommu M4U_PORT_MDP_RDMA0>;
                        mediatek,larb = <&larb0>;
-                       mediatek,vpu = <&vpu>;
                };

                mdp_rdma1: rdma@14002000 {
--
2.32.0.554.ge1b32706d8-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

[PATCH v6 9/9] dt-bindings: mediatek: remove vpu requirement from mtk-mdp

From: Eizan Miyamoto <hidden>
Date: 2021-08-02 12:13:38

It is no longer needed by the mtk-mdp driver

Signed-off-by: Eizan Miyamoto <redacted>
---

(no changes since v1)

 Documentation/devicetree/bindings/media/mediatek-mdp.txt | 3 ---
 1 file changed, 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/media/mediatek-mdp.txt b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
index caa24943da33..4c325585f68f 100644
--- a/Documentation/devicetree/bindings/media/mediatek-mdp.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
@@ -4,8 +4,6 @@ Media Data Path is used for scaling and color space conversion.
 
 Required properties (controller node):
 - compatible: "mediatek,mt8173-mdp"
-- mediatek,vpu: the node of video processor unit, see
-  Documentation/devicetree/bindings/media/mediatek-vpu.txt for details.
 
 Required properties (all function blocks, child node):
 - compatible: Should be one of
@@ -41,7 +39,6 @@ Example:
 		power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 		iommus = <&iommu M4U_PORT_MDP_RDMA0>;
 		mediatek,larb = <&larb0>;
-		mediatek,vpu = <&vpu>;
 	};
 
 	mdp_rdma1: rdma@14002000 {
-- 
2.32.0.554.ge1b32706d8-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 9/9] dt-bindings: mediatek: remove vpu requirement from mtk-mdp

From: Enric Balletbo Serra <eballetbo@gmail.com>
Date: 2021-08-03 10:27:44

Hi Eizan,

Thank you for your patch.

Missatge de Eizan Miyamoto [off-list ref] del dia dl., 2 d’ag.
2021 a les 14:15:
It is no longer needed by the mtk-mdp driver

Signed-off-by: Eizan Miyamoto <redacted>
Reviewed-by: Enric Balletbo i Serra <redacted>

quoted hunk
---

(no changes since v1)

 Documentation/devicetree/bindings/media/mediatek-mdp.txt | 3 ---
 1 file changed, 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/media/mediatek-mdp.txt b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
index caa24943da33..4c325585f68f 100644
--- a/Documentation/devicetree/bindings/media/mediatek-mdp.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
@@ -4,8 +4,6 @@ Media Data Path is used for scaling and color space conversion.

 Required properties (controller node):
 - compatible: "mediatek,mt8173-mdp"
-- mediatek,vpu: the node of video processor unit, see
-  Documentation/devicetree/bindings/media/mediatek-vpu.txt for details.

 Required properties (all function blocks, child node):
 - compatible: Should be one of
@@ -41,7 +39,6 @@ Example:
                power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
                iommus = <&iommu M4U_PORT_MDP_RDMA0>;
                mediatek,larb = <&larb0>;
-               mediatek,vpu = <&vpu>;
        };

        mdp_rdma1: rdma@14002000 {
--
2.32.0.554.ge1b32706d8-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 9/9] dt-bindings: mediatek: remove vpu requirement from mtk-mdp

From: Rob Herring <robh@kernel.org>
Date: 2021-08-06 21:47:34

On Mon, 02 Aug 2021 22:12:15 +1000, Eizan Miyamoto wrote:
It is no longer needed by the mtk-mdp driver

Signed-off-by: Eizan Miyamoto <redacted>
---

(no changes since v1)

 Documentation/devicetree/bindings/media/mediatek-mdp.txt | 3 ---
 1 file changed, 3 deletions(-)
Acked-by: Rob Herring <robh@kernel.org>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v6 0/9] Refactor MTK MDP driver into core/components

From: Enric Balletbo Serra <eballetbo@gmail.com>
Date: 2021-08-03 10:30:08

Hi all,

Missatge de Eizan Miyamoto [off-list ref] del dia dl., 2 d’ag.
2021 a les 14:12:

This is an update to
https://patchwork.kernel.org/project/linux-mediatek/list/?series=283075
To address some comments and fixes.

This series has been verified to work on 5.13.
The series have also been validated on top of 5.14-rc4 and linux-next
on an Acer Chromebook R 13 without observing any problems and running
some video decoding tests, so, for the full series.

Tested-by: Enric Balletbo i Serra <redacted>
Changes in v6:
- Don't propagate errors from clock_on/off as an afterthought.
- Split apart modifying mdp driver to be loadable from mmsys from
  actually loading it from mmsys into two changs to make review easier.
- Update devicetree bindings to reflect no longer needing the
  mediatek,vpu property in the mdp_rdma0 device node.
- Some stylistic cleanups.

Changes in v5:
- rebase and test on 5.13-next @ e2f74b13dbe6

Changes in v4:
- rebase and test on 5.13
- don't depend on https://patchwork.kernel.org/project/linux-mediatek/list/?series=464873

Changes in v3:
- get mdp master from aliases instead of strcmp against of_node->name

Changes in v2:
- rebased onto Linux 5.12
- 100 char line length allowance was utilized in a few places
- Removal of a redundant dev_err() print at the end of
  mtk_mdp_comp_init()
- Instead of printing errors and ignoring them, I've added a patch to
  correctly propagate them.
- Use of C style comments.
- Three additional patches were added to eliminate dependency on the
  mediatek,vpu property inside the mdp_rdma0 device node.

Eizan Miyamoto (9):
  mtk-mdp: propagate errors from clock_on
  mtk-mdp: add driver to probe mdp components
  mtk-mdp: use pm_runtime in MDP component driver
  media: mtk-mdp: don't pm_run_time_get/put for master comp in clock_on
  mtk-mdp: make mdp driver to be loadable by platform_device_register*()
  soc: mediatek: mmsys: instantiate mdp virtual device from mmsys
  media: mtk-mdp: use mdp-rdma0 alias to point to MDP master
  dts: mtk-mdp: remove mediatek,vpu property from primary MDP device
  dt-bindings: mediatek: remove vpu requirement from mtk-mdp

 .../bindings/media/mediatek-mdp.txt           |   3 -
 arch/arm64/boot/dts/mediatek/mt8173.dtsi      |   1 -
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 268 +++++++++++++++--
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  34 +--
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 282 ++++++++++++------
 drivers/media/platform/mtk-mdp/mtk_mdp_core.h |   3 +
 drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c  |   4 +-
 drivers/soc/mediatek/mtk-mmsys.c              |  20 +-
 8 files changed, 470 insertions(+), 145 deletions(-)

--
2.32.0.554.ge1b32706d8-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help