| From 74e24e28311ba0fca98d12776eaa991ff7f54662 Mon Sep 17 00:00:00 2001 |
| From: Eizan Miyamoto <eizan@chromium.org> |
| Date: Wed, 25 Aug 2021 16:33:19 +1000 |
| Subject: [PATCH] CHROMIUM: mtk-mdp: use pm_runtime in MDP component driver |
| |
| 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. |
| |
| BUG=b:229583743 |
| TEST=Open YouTube and check chrome://media-internals |
| |
| Signed-off-by: Eizan Miyamoto <eizan@chromium.org> |
| Reviewed-by: Enric Balletbo i Serra <enric.balletbo@collabora.com> |
| Reviewed-by: Houlong Wei <houlong.wei@mediatek.com> |
| Change-Id: Ic18d30b9588ee5b8d10e804e83d6fea114d05f1a |
| Signed-off-by: Pin-Yen Lin <treapking@chromium.org> |
| Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/3583710 |
| Reviewed-by: Hsin-Yi Wang <hsinyi@chromium.org> |
| Commit-Queue: Hsin-Yi Wang <hsinyi@chromium.org> |
| --- |
| .../platform/mediatek/mdp/mtk_mdp_comp.c | 44 +++++++++++++++---- |
| .../platform/mediatek/mdp/mtk_mdp_comp.h | 6 ++- |
| .../platform/mediatek/mdp/mtk_mdp_core.c | 6 +-- |
| 3 files changed, 43 insertions(+), 13 deletions(-) |
| |
| diff --git a/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.c b/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.c |
| index 98f8010dc57a0ab0ffff47c1555ed8dee1513605..904ea4408b006d8f4a219939600ef8d8b05ab6b0 100644 |
| --- a/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.c |
| +++ b/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.c |
| @@ -9,6 +9,8 @@ |
| #include <linux/device.h> |
| #include <linux/of.h> |
| #include <linux/module.h> |
| +#include <soc/mediatek/smi.h> |
| +#include <linux/pm_runtime.h> |
| |
| #include "mtk_mdp_comp.h" |
| #include "mtk_mdp_core.h" |
| @@ -47,23 +49,44 @@ static const struct of_device_id mtk_mdp_comp_driver_dt_match[] = { |
| }; |
| MODULE_DEVICE_TABLE(of, mtk_mdp_comp_driver_dt_match); |
| |
| - |
| -void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp) |
| +void mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp) |
| { |
| - int i, err; |
| + int i, err, status; |
| + |
| + err = pm_runtime_get_sync(comp->dev); |
| + if (err < 0) { |
| + dev_err(comp->dev, |
| + "failed to runtime get, err %d.\n", |
| + err); |
| + return; |
| + } |
| |
| for (i = 0; i < ARRAY_SIZE(comp->clk); i++) { |
| 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. i:%d\n", |
| - err, i); |
| + if (err) { |
| + status = err; |
| + dev_err(comp->dev, "failed to enable clock, err %d. i:%d\n", err, i); |
| + goto err_clk_prepare_enable; |
| + } |
| } |
| + |
| + return; |
| + |
| +err_clk_prepare_enable: |
| + for (--i; i >= 0; i--) { |
| + if (IS_ERR(comp->clk[i])) |
| + continue; |
| + clk_disable_unprepare(comp->clk[i]); |
| + } |
| + |
| + pm_runtime_put_sync(comp->dev); |
| + |
| + return; |
| } |
| |
| -void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp) |
| +void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp) |
| { |
| int i; |
| |
| @@ -72,6 +95,8 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp) |
| continue; |
| clk_disable_unprepare(comp->clk[i]); |
| } |
| + |
| + pm_runtime_put_sync(comp->dev); |
| } |
| |
| static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data) |
| @@ -80,6 +105,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; |
| } |
| @@ -90,6 +116,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); |
| } |
| |
| @@ -107,6 +134,7 @@ int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev) |
| (long)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/mediatek/mdp/mtk_mdp_comp.h b/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.h |
| index 956d20c01e34c380f544542ee01f9f1cd8f7bd95..355e226d74fefc9251555fe07d7ef8c011d11ae7 100644 |
| --- a/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.h |
| +++ b/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.h |
| @@ -11,16 +11,18 @@ |
| * struct mtk_mdp_comp - the MDP's function component data |
| * @node: list node to track sibing MDP components |
| * @clk: clocks required for component |
| + * @dev: component's device |
| */ |
| struct mtk_mdp_comp { |
| struct list_head node; |
| struct clk *clk[2]; |
| + struct device *dev; |
| }; |
| |
| int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev); |
| |
| -void 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); |
| +void mtk_mdp_comp_clock_on(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/mediatek/mdp/mtk_mdp_core.c b/drivers/media/platform/mediatek/mdp/mtk_mdp_core.c |
| index 6889156f3f09fd1c63cf9c99b0d68362a22433b1..d1d98f0412e67571d2d48ee4c3da0d537eb6e57a 100644 |
| --- a/drivers/media/platform/mediatek/mdp/mtk_mdp_core.c |
| +++ b/drivers/media/platform/mediatek/mdp/mtk_mdp_core.c |
| @@ -53,18 +53,18 @@ static void mtk_mdp_clock_on(struct mtk_mdp_dev *mdp) |
| { |
| struct device *dev = &mdp->pdev->dev; |
| struct mtk_mdp_comp *comp_node; |
| + mtk_mdp_comp_clock_off(comp_node); |
| |
| list_for_each_entry(comp_node, &mdp->comp_list, node) |
| - mtk_mdp_comp_clock_on(dev, comp_node); |
| + mtk_mdp_comp_clock_on(comp_node); |
| } |
| |
| 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.34.1 |
| |