blob: 6e7e6c4de20b6e9fb489b4dbf56cf7f274ed1a2c [file] [log] [blame]
From 58aa15a26b4104a7783808d4f815185ff57017c4 Mon Sep 17 00:00:00 2001
From: Yong Wu <yong.wu@mediatek.com>
Date: Fri, 11 Feb 2022 15:08:27 +0800
Subject: [PATCH] Revert "FROMLIST: memory: mtk-smi: Get rid of
mtk_smi_larb_get/put"
Revert "FROMLIST: dt-binding: mediatek: Get rid of mediatek, larb for multimedia HW"
This reverts commit 81c356de527cd4073ff140ca39efd0ea55427ba9.
Revert "FROMLIST: memory: mtk-smi: Get rid of mtk_smi_larb_get/put"
This reverts commit e0b2c5727626a39aa86c9f68b1d52262d6309300.
Revert "BACKPORT: FROMLIST: drm/mediatek: Get rid of mtk_smi_larb_get/put"
This reverts commit 45d9a4a3451963722f9f63d1247a2b74cd267939.
Revert "FROMLIST: drm/mediatek: Add pm runtime support for ovl and rdma"
This reverts commit b2528a7abf57d773a410c7cfdf9c36d206b1d042.
Revert "FROMLIST: media: mtk-vcodec: Get rid of mtk_smi_larb_get/put"
This reverts commit d27e2aeca797d1dd2790d0e15a2ef5ea4309bba4.
Revert "FROMLIST: media: mtk-mdp: Get rid of mtk_smi_larb_get/put"
This reverts commit eb4da80f6522f2d5b8cf2be5466363e990b31417.
Revert "FROMLIST: media: mtk-jpeg: Get rid of mtk_smi_larb_get/put"
This reverts commit 52e67eea10852cfc46997271704b946cd4774b00.
Revert "FROMLIST: iommu/mediatek: Add device_link between the consumer and the larb devices"
This reverts commit 7df81352b02e3aa935823dd3068b562d38a059a4.
Revert "FROMLIST: iommu/mediatek: Add probe_defer for smi-larb"
This reverts commit bcffc3608bf534e4ff1f1d07cb95c8857d33f86f.
BUG=b:126008328
TEST=emerge-corsola sys-kernel/chromeos-kernel-5_15
Signed-off-by: Yong Wu <yong.wu@mediatek.com>
Change-Id: Icfa63e5d20cd04bf67f8c6e47769479fde6e3f82
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/3454898
Reviewed-by: Hsin-Yi Wang <hsinyi@chromium.org>
Commit-Queue: Hsin-Yi Wang <hsinyi@chromium.org>
Tested-by: Hsin-Yi Wang <hsinyi@chromium.org>
---
.../bindings/media/mediatek-mdp.txt | 8 ++++
drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 8 +---
drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 9 +---
drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 15 +++----
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 34 ++++++++++++++
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 1 +
drivers/gpu/drm/mediatek/mtk_drm_drv.c | 5 ++-
drivers/iommu/mtk_iommu.c | 30 -------------
drivers/iommu/mtk_iommu_v1.c | 29 +-----------
.../platform/mediatek/jpeg/mtk_jpeg_core.c | 45 ++++++++++++++++++-
.../platform/mediatek/jpeg/mtk_jpeg_core.h | 2 +
.../platform/mediatek/mdp/mtk_mdp_comp.c | 40 +++++++++++++++++
.../platform/mediatek/mdp/mtk_mdp_comp.h | 2 +
.../platform/mediatek/mdp/mtk_mdp_core.c | 1 +
.../platform/mediatek/vcodec/mtk_vcodec_drv.h | 3 ++
.../platform/mediatek/vcodec/mtk_vcodec_enc.c | 1 +
.../mediatek/vcodec/mtk_vcodec_enc_pm.c | 43 +++++++++++++++---
drivers/memory/mtk-smi.c | 14 ++++++
include/soc/mediatek/smi.h | 20 +++++++++
19 files changed, 221 insertions(+), 89 deletions(-)
diff --git a/Documentation/devicetree/bindings/media/mediatek-mdp.txt b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
index 53ef26e2c857..caa24943da33 100644
--- a/Documentation/devicetree/bindings/media/mediatek-mdp.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
@@ -27,6 +27,9 @@ Required properties (DMA function blocks, child node):
- iommus: should point to the respective IOMMU block with master port as
argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
for details.
+- mediatek,larb: must contain the local arbiters in the current Socs, see
+ Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
+ for details.
Example:
mdp_rdma0: rdma@14001000 {
@@ -37,6 +40,7 @@ Example:
<&mmsys CLK_MM_MUTEX_32K>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_RDMA0>;
+ mediatek,larb = <&larb0>;
mediatek,vpu = <&vpu>;
};
@@ -47,6 +51,7 @@ Example:
<&mmsys CLK_MM_MUTEX_32K>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_RDMA1>;
+ mediatek,larb = <&larb4>;
};
mdp_rsz0: rsz@14003000 {
@@ -76,6 +81,7 @@ Example:
clocks = <&mmsys CLK_MM_MDP_WDMA>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_WDMA>;
+ mediatek,larb = <&larb0>;
};
mdp_wrot0: wrot@14007000 {
@@ -84,6 +90,7 @@ Example:
clocks = <&mmsys CLK_MM_MDP_WROT0>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_WROT0>;
+ mediatek,larb = <&larb0>;
};
mdp_wrot1: wrot@14008000 {
@@ -92,4 +99,5 @@ Example:
clocks = <&mmsys CLK_MM_MDP_WROT1>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_WROT1>;
+ mediatek,larb = <&larb4>;
};
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 17cd9b932298..2146299e5f52 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -11,7 +11,6 @@
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
#include <linux/soc/mediatek/mtk-cmdq.h>
#include "mtk_disp_drv.h"
@@ -415,13 +414,9 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
return ret;
}
- pm_runtime_enable(dev);
-
ret = component_add(dev, &mtk_disp_ovl_component_ops);
- if (ret) {
- pm_runtime_disable(dev);
+ if (ret)
dev_err(dev, "Failed to add component: %d\n", ret);
- }
return ret;
}
@@ -429,7 +424,6 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
static int mtk_disp_ovl_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &mtk_disp_ovl_component_ops);
- pm_runtime_disable(&pdev->dev);
return 0;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index 662e91d9d45f..d41a3970b944 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -9,7 +9,6 @@
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
#include <linux/soc/mediatek/mtk-cmdq.h>
#include "mtk_disp_drv.h"
@@ -328,13 +327,9 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv);
- pm_runtime_enable(dev);
-
ret = component_add(dev, &mtk_disp_rdma_component_ops);
- if (ret) {
- pm_runtime_disable(dev);
+ if (ret)
dev_err(dev, "Failed to add component: %d\n", ret);
- }
return ret;
}
@@ -343,8 +338,6 @@ static int mtk_disp_rdma_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &mtk_disp_rdma_component_ops);
- pm_runtime_disable(&pdev->dev);
-
return 0;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index ede435d2c1ef..8cc0a1283d7c 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -12,6 +12,7 @@
#include <linux/soc/mediatek/mtk-mutex.h>
#include <asm/barrier.h>
+#include <soc/mediatek/smi.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
@@ -662,15 +663,15 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
- ret = pm_runtime_resume_and_get(comp->dev);
- if (ret < 0) {
- DRM_DEV_ERROR(comp->dev, "Failed to enable power domain: %d\n", ret);
+ ret = mtk_smi_larb_get(comp->larb_dev);
+ if (ret) {
+ DRM_ERROR("Failed to get larb: %d\n", ret);
return;
}
ret = mtk_crtc_ddp_hw_init(mtk_crtc);
if (ret) {
- pm_runtime_put(comp->dev);
+ mtk_smi_larb_put(comp->larb_dev);
return;
}
@@ -683,7 +684,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
- int i, ret;
+ int i;
DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
if (!mtk_crtc->enabled)
@@ -713,9 +714,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
drm_crtc_vblank_off(crtc);
mtk_crtc_ddp_hw_fini(mtk_crtc);
- ret = pm_runtime_put(comp->dev);
- if (ret < 0)
- DRM_DEV_ERROR(comp->dev, "Failed to disable power domain: %d\n", ret);
+ mtk_smi_larb_put(comp->larb_dev);
mtk_crtc->enabled = false;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 2e99aee13dfe..3667f9e61ad7 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -447,6 +447,30 @@ unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm,
return ret;
}
+static int mtk_ddp_get_larb_dev(struct device_node *node, struct mtk_ddp_comp *comp,
+ struct device *dev)
+{
+ struct device_node *larb_node;
+ struct platform_device *larb_pdev;
+
+ larb_node = of_parse_phandle(node, "mediatek,larb", 0);
+ if (!larb_node) {
+ dev_err(dev, "Missing mediadek,larb phandle in %pOF node\n", node);
+ return -EINVAL;
+ }
+
+ larb_pdev = of_find_device_by_node(larb_node);
+ if (!larb_pdev) {
+ dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
+ of_node_put(larb_node);
+ return -EPROBE_DEFER;
+ }
+ of_node_put(larb_node);
+ comp->larb_dev = &larb_pdev->dev;
+
+ return 0;
+}
+
int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
enum mtk_ddp_comp_id comp_id)
{
@@ -471,6 +495,16 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
}
comp->dev = &comp_pdev->dev;
+ /* Only DMA capable components need the LARB property */
+ if (type == MTK_DISP_OVL ||
+ type == MTK_DISP_OVL_2L ||
+ type == MTK_DISP_RDMA ||
+ type == MTK_DISP_WDMA) {
+ ret = mtk_ddp_get_larb_dev(node, comp, comp->dev);
+ if (ret)
+ return ret;
+ }
+
if (type == MTK_DISP_AAL ||
type == MTK_DISP_BLS ||
type == MTK_DISP_CCORR ||
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index ad267bb8fc9b..4c6a98662305 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -71,6 +71,7 @@ struct mtk_ddp_comp_funcs {
struct mtk_ddp_comp {
struct device *dev;
int irq;
+ struct device *larb_dev;
enum mtk_ddp_comp_id id;
const struct mtk_ddp_comp_funcs *funcs;
};
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 247c6ff277ef..632bf7ed888b 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -643,8 +643,11 @@ static int mtk_drm_probe(struct platform_device *pdev)
pm_runtime_disable(dev);
err_node:
of_node_put(private->mutex_node);
- for (i = 0; i < DDP_COMPONENT_ID_MAX; i++)
+ for (i = 0; i < DDP_COMPONENT_ID_MAX; i++) {
of_node_put(private->comp_node[i]);
+ if (private->ddp_comp[i].larb_dev)
+ put_device(private->ddp_comp[i].larb_dev);
+ }
return ret;
}
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 6fd75a60abd6..c70a84f7c172 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -557,52 +557,22 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
{
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
struct mtk_iommu_data *data;
- struct device_link *link;
- struct device *larbdev;
- unsigned int larbid, larbidx, i;
if (!fwspec || fwspec->ops != &mtk_iommu_ops)
return ERR_PTR(-ENODEV); /* Not a iommu client device */
data = dev_iommu_priv_get(dev);
- /*
- * Link the consumer device with the smi-larb device(supplier).
- * The device that connects with each a larb is a independent HW.
- * All the ports in each a device should be in the same larbs.
- */
- larbid = MTK_M4U_TO_LARB(fwspec->ids[0]);
- for (i = 1; i < fwspec->num_ids; i++) {
- larbidx = MTK_M4U_TO_LARB(fwspec->ids[i]);
- if (larbid != larbidx) {
- dev_err(dev, "Can only use one larb. Fail@larb%d-%d.\n",
- larbid, larbidx);
- return ERR_PTR(-EINVAL);
- }
- }
- larbdev = data->larb_imu[larbid].dev;
- link = device_link_add(dev, larbdev,
- DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
- if (!link)
- dev_err(dev, "Unable to link %s\n", dev_name(larbdev));
return &data->iommu;
}
static void mtk_iommu_release_device(struct device *dev)
{
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
- struct mtk_iommu_data *data;
- struct device *larbdev;
- unsigned int larbid;
if (!fwspec || fwspec->ops != &mtk_iommu_ops)
return;
- data = dev_iommu_priv_get(dev);
- larbid = MTK_M4U_TO_LARB(fwspec->ids[0]);
- larbdev = data->larb_imu[larbid].dev;
- device_link_remove(dev, larbdev);
-
iommu_fwspec_free(dev);
}
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index ecff800656e6..136e7215b25a 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -423,9 +423,7 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
struct of_phandle_args iommu_spec;
struct mtk_iommu_data *data;
- int err, idx = 0, larbid, larbidx;
- struct device_link *link;
- struct device *larbdev;
+ int err, idx = 0;
/*
* In the deferred case, free the existed fwspec.
@@ -455,23 +453,6 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
data = dev_iommu_priv_get(dev);
- /* Link the consumer device with the smi-larb device(supplier) */
- larbid = mt2701_m4u_to_larb(fwspec->ids[0]);
- for (idx = 1; idx < fwspec->num_ids; idx++) {
- larbidx = mt2701_m4u_to_larb(fwspec->ids[idx]);
- if (larbid != larbidx) {
- dev_err(dev, "Can only use one larb. Fail@larb%d-%d.\n",
- larbid, larbidx);
- return ERR_PTR(-EINVAL);
- }
- }
-
- larbdev = data->larb_imu[larbid].dev;
- link = device_link_add(dev, larbdev,
- DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
- if (!link)
- dev_err(dev, "Unable to link %s\n", dev_name(larbdev));
-
return &data->iommu;
}
@@ -492,18 +473,10 @@ static void mtk_iommu_probe_finalize(struct device *dev)
static void mtk_iommu_release_device(struct device *dev)
{
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
- struct mtk_iommu_data *data;
- struct device *larbdev;
- unsigned int larbid;
if (!fwspec || fwspec->ops != &mtk_iommu_ops)
return;
- data = dev_iommu_priv_get(dev);
- larbid = mt2701_m4u_to_larb(fwspec->ids[0]);
- larbdev = data->larb_imu[larbid].dev;
- device_link_remove(dev, larbdev);
-
iommu_fwspec_free(dev);
}
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index ab5485dfc20c..b334bbb2e682 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -22,6 +22,7 @@
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-core.h>
#include <media/videobuf2-dma-contig.h>
+#include <soc/mediatek/smi.h>
#include "mtk_jpeg_enc_hw.h"
#include "mtk_jpeg_dec_hw.h"
@@ -1054,6 +1055,10 @@ static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg)
{
int ret;
+ ret = mtk_smi_larb_get(jpeg->larb);
+ if (ret)
+ dev_err(jpeg->dev, "mtk_smi_larb_get larbvdec fail %d\n", ret);
+
ret = clk_bulk_prepare_enable(jpeg->variant->num_clks,
jpeg->variant->clks);
if (ret)
@@ -1064,6 +1069,7 @@ static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg)
{
clk_bulk_disable_unprepare(jpeg->variant->num_clks,
jpeg->variant->clks);
+ mtk_smi_larb_put(jpeg->larb);
}
static irqreturn_t mtk_jpeg_enc_done(struct mtk_jpeg_dev *jpeg)
@@ -1278,6 +1284,35 @@ static struct clk_bulk_data mtk_jpeg_clocks[] = {
{ .id = "jpgenc" },
};
+static int mtk_jpeg_clk_init(struct mtk_jpeg_dev *jpeg)
+{
+ struct device_node *node;
+ struct platform_device *pdev;
+ int ret;
+
+ node = of_parse_phandle(jpeg->dev->of_node, "mediatek,larb", 0);
+ if (!node)
+ return -EINVAL;
+ pdev = of_find_device_by_node(node);
+ if (WARN_ON(!pdev)) {
+ of_node_put(node);
+ return -EINVAL;
+ }
+ of_node_put(node);
+
+ jpeg->larb = &pdev->dev;
+
+ ret = devm_clk_bulk_get(jpeg->dev, jpeg->variant->num_clks,
+ jpeg->variant->clks);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get jpeg clock:%d\n", ret);
+ put_device(&pdev->dev);
+ return ret;
+ }
+
+ return 0;
+}
+
static void mtk_jpeg_job_timeout_work(struct work_struct *work)
{
struct mtk_jpeg_dev *jpeg = container_of(work, struct mtk_jpeg_dev,
@@ -1298,6 +1333,11 @@ static void mtk_jpeg_job_timeout_work(struct work_struct *work)
v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
}
+static inline void mtk_jpeg_clk_release(struct mtk_jpeg_dev *jpeg)
+{
+ put_device(jpeg->larb);
+}
+
static int mtk_jpeg_probe(struct platform_device *pdev)
{
struct mtk_jpeg_dev *jpeg;
@@ -1332,8 +1372,7 @@ static int mtk_jpeg_probe(struct platform_device *pdev)
goto err_req_irq;
}
- ret = devm_clk_bulk_get(jpeg->dev, jpeg->variant->num_clks,
- jpeg->variant->clks);
+ ret = mtk_jpeg_clk_init(jpeg);
if (ret) {
dev_err(&pdev->dev, "Failed to init clk, err %d\n", ret);
goto err_clk_init;
@@ -1399,6 +1438,7 @@ static int mtk_jpeg_probe(struct platform_device *pdev)
v4l2_device_unregister(&jpeg->v4l2_dev);
err_dev_register:
+ mtk_jpeg_clk_release(jpeg);
err_clk_init:
@@ -1416,6 +1456,7 @@ static int mtk_jpeg_remove(struct platform_device *pdev)
video_device_release(jpeg->vdev);
v4l2_m2m_release(jpeg->m2m_dev);
v4l2_device_unregister(&jpeg->v4l2_dev);
+ mtk_jpeg_clk_release(jpeg);
return 0;
}
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
index 3e4811a41ba2..595f7f10c9fd 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
@@ -85,6 +85,7 @@ struct mtk_jpeg_variant {
* @alloc_ctx: videobuf2 memory allocator's context
* @vdev: video device node for jpeg mem2mem mode
* @reg_base: JPEG registers mapping
+ * @larb: SMI device
* @job_timeout_work: IRQ timeout structure
* @variant: driver variant to be used
*/
@@ -98,6 +99,7 @@ struct mtk_jpeg_dev {
void *alloc_ctx;
struct video_device *vdev;
void __iomem *reg_base;
+ struct device *larb;
struct delayed_work job_timeout_work;
const struct mtk_jpeg_variant *variant;
};
diff --git a/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.c b/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.c
index 1e3833f1c9ae..b3426a551bea 100644
--- a/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.c
@@ -9,6 +9,7 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
+#include <soc/mediatek/smi.h>
#include "mtk_mdp_comp.h"
@@ -17,6 +18,14 @@ void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
{
int i, err;
+ 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);
+ }
+
for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
if (IS_ERR(comp->clk[i]))
continue;
@@ -37,12 +46,17 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
continue;
clk_disable_unprepare(comp->clk[i]);
}
+
+ if (comp->larb_dev)
+ 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)
{
+ struct device_node *larb_node;
+ struct platform_device *larb_pdev;
int ret;
int i;
@@ -63,6 +77,32 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
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)
+ return 0;
+
+ larb_node = of_parse_phandle(node, "mediatek,larb", 0);
+ if (!larb_node) {
+ dev_err(dev,
+ "Missing mediadek,larb phandle in %pOF node\n", node);
+ ret = -EINVAL;
+ goto put_dev;
+ }
+
+ larb_pdev = of_find_device_by_node(larb_node);
+ if (!larb_pdev) {
+ dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
+ of_node_put(larb_node);
+ ret = -EPROBE_DEFER;
+ goto put_dev;
+ }
+ of_node_put(larb_node);
+
+ comp->larb_dev = &larb_pdev->dev;
+
return 0;
put_dev:
diff --git a/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.h b/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.h
index ae41dd3cd72a..7897766c96bb 100644
--- a/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mediatek/mdp/mtk_mdp_comp.h
@@ -26,12 +26,14 @@ enum mtk_mdp_comp_type {
* @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;
};
diff --git a/drivers/media/platform/mediatek/mdp/mtk_mdp_core.c b/drivers/media/platform/mediatek/mdp/mtk_mdp_core.c
index d83c4964eaf9..fbd6e06a0567 100644
--- a/drivers/media/platform/mediatek/mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mediatek/mdp/mtk_mdp_core.c
@@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/workqueue.h>
+#include <soc/mediatek/smi.h>
#include "mtk_mdp_core.h"
#include "mtk_mdp_m2m.h"
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h
index 813901c4be5e..94b47b7c912b 100644
--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h
@@ -214,7 +214,10 @@ struct mtk_vcodec_clk {
*/
struct mtk_vcodec_pm {
struct mtk_vcodec_clk vdec_clk;
+ struct device *larbvdec;
+
struct mtk_vcodec_clk venc_clk;
+ struct device *larbvenc;
struct device *dev;
};
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c
index a8de28b90d4c..434b8c4b7cb7 100644
--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c
@@ -8,6 +8,7 @@
#include <media/v4l2-event.h>
#include <media/v4l2-mem2mem.h>
#include <media/videobuf2-dma-contig.h>
+#include <soc/mediatek/smi.h>
#include <linux/pm_runtime.h>
#include "mtk_vcodec_drv.h"
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_pm.c
index 7055954eb2af..309843cce17e 100644
--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_pm.c
@@ -8,35 +8,57 @@
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/pm_runtime.h>
+#include <soc/mediatek/smi.h>
#include "mtk_vcodec_enc_pm.h"
#include "mtk_vcodec_util.h"
int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *mtkdev)
{
+ struct device_node *node;
struct platform_device *pdev;
struct mtk_vcodec_pm *pm;
struct mtk_vcodec_clk *enc_clk;
struct mtk_vcodec_clk_info *clk_info;
int ret, i;
+ struct device *dev;
pdev = mtkdev->plat_dev;
pm = &mtkdev->pm;
memset(pm, 0, sizeof(struct mtk_vcodec_pm));
pm->dev = &pdev->dev;
+ dev = &pdev->dev;
enc_clk = &pm->venc_clk;
+ node = of_parse_phandle(dev->of_node, "mediatek,larb", 0);
+ if (!node) {
+ mtk_v4l2_err("no mediatek,larb found");
+ return -ENODEV;
+ }
+ pdev = of_find_device_by_node(node);
+ of_node_put(node);
+ if (!pdev) {
+ mtk_v4l2_err("no mediatek,larb device found");
+ return -ENODEV;
+ }
+ pm->larbvenc = &pdev->dev;
+ pdev = mtkdev->plat_dev;
+ pm->dev = &pdev->dev;
+
enc_clk->clk_num = of_property_count_strings(pdev->dev.of_node,
"clock-names");
if (enc_clk->clk_num > 0) {
enc_clk->clk_info = devm_kcalloc(&pdev->dev,
enc_clk->clk_num, sizeof(*clk_info),
GFP_KERNEL);
- if (!enc_clk->clk_info)
- return -ENOMEM;
+ if (!enc_clk->clk_info) {
+ ret = -ENOMEM;
+ goto put_larbvenc;
+ }
} else {
mtk_v4l2_err("Failed to get venc clock count");
- return -EINVAL;
+ ret = -EINVAL;
+ goto put_larbvenc;
}
for (i = 0; i < enc_clk->clk_num; i++) {
@@ -45,18 +67,23 @@ int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *mtkdev)
"clock-names", i, &clk_info->clk_name);
if (ret) {
mtk_v4l2_err("venc failed to get clk name %d", i);
- return ret;
+ goto put_larbvenc;
}
clk_info->vcodec_clk = devm_clk_get(&pdev->dev,
clk_info->clk_name);
if (IS_ERR(clk_info->vcodec_clk)) {
mtk_v4l2_err("venc devm_clk_get (%d)%s fail", i,
clk_info->clk_name);
- return PTR_ERR(clk_info->vcodec_clk);
+ ret = PTR_ERR(clk_info->vcodec_clk);
+ goto put_larbvenc;
}
}
return 0;
+
+put_larbvenc:
+ put_device(pm->larbvenc);
+ return ret;
}
void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
@@ -73,6 +100,11 @@ void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
}
}
+ ret = mtk_smi_larb_get(pm->larbvenc);
+ if (ret) {
+ mtk_v4l2_err("mtk_smi_larb_get larb3 fail %d", ret);
+ goto clkerr;
+ }
return;
clkerr:
@@ -85,6 +117,7 @@ void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
int i = 0;
+ mtk_smi_larb_put(pm->larbvenc);
for (i = enc_clk->clk_num - 1; i >= 0; i--)
clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
}
diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 86a3d34f418e..7d8a083df44a 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -154,6 +154,20 @@ struct mtk_smi_larb { /* larb: local arbiter */
unsigned char *bank;
};
+int mtk_smi_larb_get(struct device *larbdev)
+{
+ int ret = pm_runtime_resume_and_get(larbdev);
+
+ return (ret < 0) ? ret : 0;
+}
+EXPORT_SYMBOL_GPL(mtk_smi_larb_get);
+
+void mtk_smi_larb_put(struct device *larbdev)
+{
+ pm_runtime_put_sync(larbdev);
+}
+EXPORT_SYMBOL_GPL(mtk_smi_larb_put);
+
static int
mtk_smi_larb_bind(struct device *dev, struct device *master, void *data)
{
diff --git a/include/soc/mediatek/smi.h b/include/soc/mediatek/smi.h
index 11f7d6b59642..15e3397cec58 100644
--- a/include/soc/mediatek/smi.h
+++ b/include/soc/mediatek/smi.h
@@ -19,6 +19,26 @@ struct mtk_smi_larb_iommu {
unsigned char bank[32];
};
+/*
+ * mtk_smi_larb_get: Enable the power domain and clocks for this local arbiter.
+ * It also initialize some basic setting(like iommu).
+ * mtk_smi_larb_put: Disable the power domain and clocks for this local arbiter.
+ * Both should be called in non-atomic context.
+ *
+ * Returns 0 if successful, negative on failure.
+ */
+int mtk_smi_larb_get(struct device *larbdev);
+void mtk_smi_larb_put(struct device *larbdev);
+
+#else
+
+static inline int mtk_smi_larb_get(struct device *larbdev)
+{
+ return 0;
+}
+
+static inline void mtk_smi_larb_put(struct device *larbdev) { }
+
#endif
#endif
--
2.35.1.1178.g4f1659d476-goog