2019-09-03 09:39:15

by Yong Wu (吴勇)

[permalink] [raw]
Subject: [PATCH v3 00/14] Clean up "mediatek,larb" after adding device_link

MediaTek IOMMU block diagram always like below:

M4U
|
smi-common
|
-------------
| | ...
| |
larb1 larb2
| |
vdec venc

All the consumer connect with smi-larb, then connect with smi-common.

MediaTek IOMMU don't have its power-domain. When the consumer works,
it should enable the smi-larb's power which also need enable the smi-common's
power firstly.

Thus, Firstly, use the device link connect the consumer and the
smi-larbs. then add device link between the smi-larb and smi-common.

After adding the device_link, then "mediatek,larb" property can be removed.
the iommu consumer don't need call the mtk_smi_larb_get/put to enable
the power and clock of smi-larb and smi-common.

This patchset depends on "MT8183 IOMMU SUPPORT"[1].

[1] http://lists.infradead.org/pipermail/linux-mediatek/2019-August/022611.html

Change notes:
v3: 1) rebase on v5.3-rc1 and the latest mt8183 patchset.
2) Use device_is_bound to check whether the driver is ready from Matthias.
3) Add DL_FLAG_STATELESS flag when calling device_link_add and explain the
reason in the commit message[3/14].
4) Add a display patch[12/14] into this series. otherwise it may affect
display HW fastlogo even though it don't happen in mt8183.

v2: http://lists.infradead.org/pipermail/linux-mediatek/2019-June/020440.html
1) rebase on v5.2-rc1.
2) Move adding device_link between the consumer and smi-larb into
iommu_add_device from Robin.
3) add DL_FLAG_AUTOREMOVE_CONSUMER even though the smi is built-in from Evan.
4) Remove the shutdown callback in iommu.

v1: https://lists.linuxfoundation.org/pipermail/iommu/2019-January/032387.html

Yong Wu (13):
dt-binding: mediatek: Get rid of mediatek,larb for multimedia HW
iommu/mediatek: Add probe_defer for smi-larb
iommu/mediatek: Add device_link between the consumer and the larb
devices
memory: mtk-smi: Add device-link between smi-larb and smi-common
media: mtk-jpeg: Get rid of mtk_smi_larb_get/put
media: mtk-mdp: Get rid of mtk_smi_larb_get/put
media: mtk-vcodec: Get rid of mtk_smi_larb_get/put
drm/mediatek: Get rid of mtk_smi_larb_get/put
memory: mtk-smi: Get rid of mtk_smi_larb_get/put
iommu/mediatek: Use builtin_platform_driver
memory: mtk-smi: Use device_is_bound to check if smi-common is ready
arm: dts: mediatek: Get rid of mediatek,larb for MM nodes
arm64: dts: mediatek: Get rid of mediatek,larb for MM nodes

Yongqiang Niu (1):
drm/mediatek: Add pm runtime support for ovl and rdma

.../bindings/display/mediatek/mediatek,disp.txt | 9 ----
.../bindings/media/mediatek-jpeg-decoder.txt | 4 --
.../devicetree/bindings/media/mediatek-mdp.txt | 8 ----
.../devicetree/bindings/media/mediatek-vcodec.txt | 4 --
arch/arm/boot/dts/mt2701.dtsi | 1 -
arch/arm/boot/dts/mt7623.dtsi | 1 -
arch/arm64/boot/dts/mediatek/mt8173.dtsi | 15 ------
drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 5 ++
drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 5 ++
drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 20 ++++----
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 31 ++----------
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 2 +-
drivers/iommu/mtk_iommu.c | 56 ++++++++++------------
drivers/iommu/mtk_iommu_v1.c | 49 ++++++++++---------
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c | 22 ---------
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h | 2 -
drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 38 ---------------
drivers/media/platform/mtk-mdp/mtk_mdp_comp.h | 2 -
drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 1 -
.../media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 22 ---------
drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | 3 --
drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c | 1 -
.../media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c | 47 ------------------
drivers/memory/mtk-smi.c | 41 +++++++---------
include/soc/mediatek/smi.h | 20 --------
25 files changed, 93 insertions(+), 316 deletions(-)

--
1.9.1


2019-09-03 09:40:03

by Yong Wu (吴勇)

[permalink] [raw]
Subject: [PATCH v3 01/14] dt-binding: mediatek: Get rid of mediatek,larb for multimedia HW

After adding device_link between the consumer with the smi-larbs,
if the consumer call its owner pm_runtime_get(_sync), the
pm_runtime_get(_sync) of smi-larb and smi-common will be called
automatically. Thus, the consumer don't need the property.

And IOMMU also know which larb this consumer connects with from
iommu id in the "iommus=" property.

Signed-off-by: Yong Wu <[email protected]>
Reviewed-by: Rob Herring <[email protected]>
Reviewed-by: Evan Green <[email protected]>
---
.../devicetree/bindings/display/mediatek/mediatek,disp.txt | 9 ---------
.../devicetree/bindings/media/mediatek-jpeg-decoder.txt | 4 ----
Documentation/devicetree/bindings/media/mediatek-mdp.txt | 8 --------
Documentation/devicetree/bindings/media/mediatek-vcodec.txt | 4 ----
4 files changed, 25 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
index 8469de5..464b92f 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
@@ -56,8 +56,6 @@ Required properties (DMA function blocks):
"mediatek,<chip>-disp-rdma"
"mediatek,<chip>-disp-wdma"
the supported chips are mt2701 and mt8173.
-- larb: Should contain a phandle pointing to the local arbiter device as defined
- in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
- iommus: Should point to the respective IOMMU block with master port as
argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
for details.
@@ -78,7 +76,6 @@ ovl0: ovl@1400c000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_OVL0>;
iommus = <&iommu M4U_PORT_DISP_OVL0>;
- mediatek,larb = <&larb0>;
};

ovl1: ovl@1400d000 {
@@ -88,7 +85,6 @@ ovl1: ovl@1400d000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_OVL1>;
iommus = <&iommu M4U_PORT_DISP_OVL1>;
- mediatek,larb = <&larb4>;
};

rdma0: rdma@1400e000 {
@@ -98,7 +94,6 @@ rdma0: rdma@1400e000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_RDMA0>;
iommus = <&iommu M4U_PORT_DISP_RDMA0>;
- mediatek,larb = <&larb0>;
};

rdma1: rdma@1400f000 {
@@ -108,7 +103,6 @@ rdma1: rdma@1400f000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_RDMA1>;
iommus = <&iommu M4U_PORT_DISP_RDMA1>;
- mediatek,larb = <&larb4>;
};

rdma2: rdma@14010000 {
@@ -118,7 +112,6 @@ rdma2: rdma@14010000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_RDMA2>;
iommus = <&iommu M4U_PORT_DISP_RDMA2>;
- mediatek,larb = <&larb4>;
};

wdma0: wdma@14011000 {
@@ -128,7 +121,6 @@ wdma0: wdma@14011000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_WDMA0>;
iommus = <&iommu M4U_PORT_DISP_WDMA0>;
- mediatek,larb = <&larb0>;
};

wdma1: wdma@14012000 {
@@ -138,7 +130,6 @@ wdma1: wdma@14012000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_WDMA1>;
iommus = <&iommu M4U_PORT_DISP_WDMA1>;
- mediatek,larb = <&larb4>;
};

color0: color@14013000 {
diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
index 044b119..7978f21 100644
--- a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
@@ -15,9 +15,6 @@ Required properties:
- clock-names: must contain "jpgdec-smi" and "jpgdec".
- power-domains: a phandle to the power domain, see
Documentation/devicetree/bindings/power/power_domain.txt for details.
-- mediatek,larb: must contain the local arbiters in the current Socs, see
- Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
- for details.
- iommus: should point to the respective IOMMU block with master port as
argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
for details.
@@ -32,7 +29,6 @@ Example:
clock-names = "jpgdec-smi",
"jpgdec";
power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
- mediatek,larb = <&larb2>;
iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>,
<&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>;
};
diff --git a/Documentation/devicetree/bindings/media/mediatek-mdp.txt b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
index 0d03e3a..df69c5a 100644
--- a/Documentation/devicetree/bindings/media/mediatek-mdp.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
@@ -27,9 +27,6 @@ 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.txt
for details.
-- mediatek,larb: must contain the local arbiters in the current Socs, see
- Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
- for details.

Example:
mdp_rdma0: rdma@14001000 {
@@ -40,7 +37,6 @@ 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>;
};

@@ -51,7 +47,6 @@ 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 {
@@ -81,7 +76,6 @@ 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 {
@@ -90,7 +84,6 @@ 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 {
@@ -99,5 +92,4 @@ 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/Documentation/devicetree/bindings/media/mediatek-vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
index b6b5dde..5c9ee6a 100644
--- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
@@ -9,7 +9,6 @@ Required properties:
- reg : Physical base address of the video codec registers and length of
memory mapped region.
- interrupts : interrupt number to the cpu.
-- mediatek,larb : must contain the local arbiters in the current Socs.
- clocks : list of clock specifiers, corresponding to entries in
the clock-names property.
- clock-names: encoder must contain "venc_sel_src", "venc_sel",,
@@ -39,7 +38,6 @@ vcodec_dec: vcodec@16000000 {
<0 0x16027800 0 0x800>, /*VP8_VL*/
<0 0x16028400 0 0x400>; /*VP9_VD*/
interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
- mediatek,larb = <&larb1>;
iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
<&iommu M4U_PORT_HW_VDEC_PP_EXT>,
<&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
@@ -83,8 +81,6 @@ vcodec_dec: vcodec@16000000 {
<0 0x19002000 0 0x1000>; /*VENC_LT_SYS*/
interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>,
<GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
- mediatek,larb = <&larb3>,
- <&larb5>;
iommus = <&iommu M4U_PORT_VENC_RCPU>,
<&iommu M4U_PORT_VENC_REC>,
<&iommu M4U_PORT_VENC_BSDMA>,
--
1.9.1

2019-09-03 09:40:40

by Yong Wu (吴勇)

[permalink] [raw]
Subject: [PATCH v3 07/14] media: mtk-vcodec: Get rid of mtk_smi_larb_get/put

MediaTek IOMMU has already added the device_link between the consumer
and smi-larb device. If the vcodec device call the pm_runtime_get_sync,
the smi-larb's pm_runtime_get_sync also be called automatically.

CC: Tiffany Lin <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
Reviewed-by: Evan Green <[email protected]>
---
.../media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 22 ----------
drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | 3 --
drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c | 1 -
.../media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c | 47 ----------------------
4 files changed, 73 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 5a6ec8f..eb82d87 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -8,7 +8,6 @@
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/pm_runtime.h>
-#include <soc/mediatek/smi.h>

#include "mtk_vcodec_dec_pm.h"
#include "mtk_vcodec_util.h"
@@ -16,7 +15,6 @@

int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
{
- struct device_node *node;
struct platform_device *pdev;
struct mtk_vcodec_pm *pm;
struct mtk_vcodec_clk *dec_clk;
@@ -27,19 +25,6 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
pm = &mtkdev->pm;
pm->mtkdev = mtkdev;
dec_clk = &pm->vdec_clk;
- node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0);
- if (!node) {
- mtk_v4l2_err("of_parse_phandle mediatek,larb fail!");
- return -1;
- }
-
- pdev = of_find_device_by_node(node);
- of_node_put(node);
- if (WARN_ON(!pdev)) {
- return -1;
- }
- pm->larbvdec = &pdev->dev;
- pdev = mtkdev->plat_dev;
pm->dev = &pdev->dev;

dec_clk->clk_num =
@@ -113,12 +98,6 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
goto error;
}
}
-
- ret = mtk_smi_larb_get(pm->larbvdec);
- if (ret) {
- mtk_v4l2_err("mtk_smi_larb_get larbvdec fail %d", ret);
- goto error;
- }
return;

error:
@@ -131,7 +110,6 @@ void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
int i = 0;

- mtk_smi_larb_put(pm->larbvdec);
for (i = dec_clk->clk_num - 1; i >= 0; i--)
clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
}
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index c95de5d..61fefa1 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -188,11 +188,8 @@ 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 *larbvenclt;
struct device *dev;
struct mtk_vcodec_dev *mtkdev;
};
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
index fd8de02..75e0e85 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -8,7 +8,6 @@
#include <media/v4l2-event.h>
#include <media/v4l2-mem2mem.h>
#include <media/videobuf2-dma-contig.h>
-#include <soc/mediatek/smi.h>

#include "mtk_vcodec_drv.h"
#include "mtk_vcodec_enc.h"
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index 3e2bfde..f484ac7 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -8,7 +8,6 @@
#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"
@@ -17,49 +16,18 @@

int mtk_vcodec_init_enc_pm(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 = 0, i = 0;
- struct device *dev;

pdev = mtkdev->plat_dev;
pm = &mtkdev->pm;
memset(pm, 0, sizeof(struct mtk_vcodec_pm));
pm->mtkdev = mtkdev;
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;
-
- node = of_parse_phandle(dev->of_node, "mediatek,larb", 1);
- 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->larbvenclt = &pdev->dev;
pdev = mtkdev->plat_dev;
pm->dev = &pdev->dev;

@@ -115,21 +83,8 @@ 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 larbvencerr;
- }
- ret = mtk_smi_larb_get(pm->larbvenclt);
- if (ret) {
- mtk_v4l2_err("mtk_smi_larb_get larb4 fail %d", ret);
- goto larbvenclterr;
- }
return;

-larbvenclterr:
- mtk_smi_larb_put(pm->larbvenc);
-larbvencerr:
clkerr:
for (i -= 1; i >= 0; i--)
clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
@@ -140,8 +95,6 @@ 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);
- mtk_smi_larb_put(pm->larbvenclt);
for (i = enc_clk->clk_num - 1; i >= 0; i--)
clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
}
--
1.9.1

2019-09-03 09:40:46

by Yong Wu (吴勇)

[permalink] [raw]
Subject: [PATCH v3 02/14] iommu/mediatek: Add probe_defer for smi-larb

The iommu consumer should use device_link to connect with the
smi-larb(supplier). then the smi-larb should run before the iommu
consumer. Here we delay the iommu driver until the smi driver is
ready, then all the iommu consumer always is after the smi driver.

When there is no this patch, if some consumer drivers run before
smi-larb, the supplier link_status is DL_DEV_NO_DRIVER(0) in the
device_link_add, then device_links_driver_bound will use WARN_ON
to complain that the link_status of supplier is not right.

This is a preparing patch for adding device_link.

Signed-off-by: Yong Wu <[email protected]>
---
drivers/iommu/mtk_iommu.c | 8 +++++++-
drivers/iommu/mtk_iommu_v1.c | 7 ++++++-
2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 400066d..b138b94 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -660,6 +660,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
for (i = 0; i < larb_nr; i++) {
struct device_node *larbnode;
struct platform_device *plarbdev;
+ bool larbdev_is_bound = false;
u32 id;

larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i);
@@ -676,7 +677,12 @@ static int mtk_iommu_probe(struct platform_device *pdev)
id = i;

plarbdev = of_find_device_by_node(larbnode);
- if (!plarbdev) {
+ if (plarbdev) {
+ device_lock(&plarbdev->dev);
+ larbdev_is_bound = device_is_bound(&plarbdev->dev);
+ device_unlock(&plarbdev->dev);
+ }
+ if (!plarbdev || !larbdev_is_bound) {
of_node_put(larbnode);
return -EPROBE_DEFER;
}
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index 860926c..2034d72 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -601,10 +601,15 @@ static int mtk_iommu_probe(struct platform_device *pdev)

plarbdev = of_find_device_by_node(larb_spec.np);
if (!plarbdev) {
+ bool larbdev_is_bound;
+
plarbdev = of_platform_device_create(
larb_spec.np, NULL,
platform_bus_type.dev_root);
- if (!plarbdev) {
+ device_lock(&plarbdev->dev);
+ larbdev_is_bound = device_is_bound(&plarbdev->dev);
+ device_unlock(&plarbdev->dev);
+ if (!plarbdev || !larbdev_is_bound) {
of_node_put(larb_spec.np);
return -EPROBE_DEFER;
}
--
1.9.1

2019-09-03 09:41:00

by Yong Wu (吴勇)

[permalink] [raw]
Subject: [PATCH v3 09/14] memory: mtk-smi: Get rid of mtk_smi_larb_get/put

After adding device_link between the iommu consumer and smi-larb,
the pm_runtime_get(_sync) of smi-larb and smi-common will be called
automatically. we can get rid of mtk_smi_larb_get/put.

CC: Matthias Brugger <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
Reviewed-by: Evan Green <[email protected]>
---
drivers/memory/mtk-smi.c | 14 --------------
include/soc/mediatek/smi.h | 20 --------------------
2 files changed, 34 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 5dab56c..3df9036 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -125,20 +125,6 @@ static void mtk_smi_clk_disable(const struct mtk_smi *smi)
clk_disable_unprepare(smi->clk_apb);
}

-int mtk_smi_larb_get(struct device *larbdev)
-{
- int ret = pm_runtime_get_sync(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 5a34b87..f8bf595 100644
--- a/include/soc/mediatek/smi.h
+++ b/include/soc/mediatek/smi.h
@@ -20,26 +20,6 @@ struct mtk_smi_larb_iommu {
unsigned int mmu;
};

-/*
- * 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
--
1.9.1

2019-09-03 09:41:06

by Yong Wu (吴勇)

[permalink] [raw]
Subject: [PATCH v3 08/14] drm/mediatek: Get rid of mtk_smi_larb_get/put

MediaTek IOMMU has already added the device_link between the consumer
and smi-larb device. If the drm device call the pm_runtime_get_sync,
the smi-larb's pm_runtime_get_sync also be called automatically.

CC: CK Hu <[email protected]>
CC: Philipp Zabel <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
Reviewed-by: Evan Green <[email protected]>
---
drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 14 +-------------
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 30 -----------------------------
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 1 -
3 files changed, 1 insertion(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index a900721..c1e891e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -10,7 +10,6 @@
#include <drm/drm_probe_helper.h>
#include <linux/clk.h>
#include <linux/pm_runtime.h>
-#include <soc/mediatek/smi.h>

#include "mtk_drm_drv.h"
#include "mtk_drm_crtc.h"
@@ -359,22 +358,13 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
- struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
int ret;

DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);

- 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) {
- mtk_smi_larb_put(comp->larb_dev);
+ if (ret)
return;
- }

drm_crtc_vblank_on(crtc);
mtk_crtc->enabled = true;
@@ -384,7 +374,6 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
- struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
int i;

DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
@@ -407,7 +396,6 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,

drm_crtc_vblank_off(crtc);
mtk_crtc_ddp_hw_fini(mtk_crtc);
- 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 b38963f..7dc8496 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -256,15 +256,9 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
struct mtk_ddp_comp *comp, enum mtk_ddp_comp_id comp_id,
const struct mtk_ddp_comp_funcs *funcs)
{
- enum mtk_ddp_comp_type type;
- struct device_node *larb_node;
- struct platform_device *larb_pdev;
-
if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX)
return -EINVAL;

- type = mtk_ddp_matches[comp_id].type;
-
comp->id = comp_id;
comp->funcs = funcs ?: mtk_ddp_matches[comp_id].funcs;

@@ -288,30 +282,6 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
if (IS_ERR(comp->clk))
return PTR_ERR(comp->clk);

- /* Only DMA capable components need the LARB property */
- comp->larb_dev = NULL;
- if (type != MTK_DISP_OVL &&
- type != MTK_DISP_RDMA &&
- type != MTK_DISP_WDMA)
- 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);
- 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;
}

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 0ad287f..108de60 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -83,7 +83,6 @@ struct mtk_ddp_comp {
struct clk *clk;
void __iomem *regs;
int irq;
- struct device *larb_dev;
enum mtk_ddp_comp_id id;
const struct mtk_ddp_comp_funcs *funcs;
};
--
1.9.1

2019-09-03 09:41:15

by Yong Wu (吴勇)

[permalink] [raw]
Subject: [PATCH v3 10/14] iommu/mediatek: Use builtin_platform_driver

MediaTek IOMMU should wait for smi larb which need wait for the
power domain(mtk-scpsys.c) and the multimedia ccf who both are
module init. Thus, subsys_initcall for MediaTek IOMMU is not helpful.
Switch to builtin_platform_driver.

Signed-off-by: Yong Wu <[email protected]>
---
drivers/iommu/mtk_iommu.c | 31 +------------------------------
drivers/iommu/mtk_iommu_v1.c | 24 +-----------------------
2 files changed, 2 insertions(+), 53 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 2511b3c..109c3f2 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -735,22 +735,6 @@ static int mtk_iommu_probe(struct platform_device *pdev)
return component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
}

-static int mtk_iommu_remove(struct platform_device *pdev)
-{
- struct mtk_iommu_data *data = platform_get_drvdata(pdev);
-
- iommu_device_sysfs_remove(&data->iommu);
- iommu_device_unregister(&data->iommu);
-
- if (iommu_present(&platform_bus_type))
- bus_set_iommu(&platform_bus_type, NULL);
-
- clk_disable_unprepare(data->bclk);
- devm_free_irq(&pdev->dev, data->irq, data);
- component_master_del(&pdev->dev, &mtk_iommu_com_ops);
- return 0;
-}
-
static int __maybe_unused mtk_iommu_suspend(struct device *dev)
{
struct mtk_iommu_data *data = dev_get_drvdata(dev);
@@ -831,23 +815,10 @@ static int __maybe_unused mtk_iommu_resume(struct device *dev)

static struct platform_driver mtk_iommu_driver = {
.probe = mtk_iommu_probe,
- .remove = mtk_iommu_remove,
.driver = {
.name = "mtk-iommu",
.of_match_table = of_match_ptr(mtk_iommu_of_ids),
.pm = &mtk_iommu_pm_ops,
}
};
-
-static int __init mtk_iommu_init(void)
-{
- int ret;
-
- ret = platform_driver_register(&mtk_iommu_driver);
- if (ret != 0)
- pr_err("Failed to register MTK IOMMU driver\n");
-
- return ret;
-}
-
-subsys_initcall(mtk_iommu_init)
+builtin_platform_driver(mtk_iommu_driver);
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index a7f22a2..821d483 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -660,22 +660,6 @@ static int mtk_iommu_probe(struct platform_device *pdev)
return component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
}

-static int mtk_iommu_remove(struct platform_device *pdev)
-{
- struct mtk_iommu_data *data = platform_get_drvdata(pdev);
-
- iommu_device_sysfs_remove(&data->iommu);
- iommu_device_unregister(&data->iommu);
-
- if (iommu_present(&platform_bus_type))
- bus_set_iommu(&platform_bus_type, NULL);
-
- clk_disable_unprepare(data->bclk);
- devm_free_irq(&pdev->dev, data->irq, data);
- component_master_del(&pdev->dev, &mtk_iommu_com_ops);
- return 0;
-}
-
static int __maybe_unused mtk_iommu_suspend(struct device *dev)
{
struct mtk_iommu_data *data = dev_get_drvdata(dev);
@@ -712,16 +696,10 @@ static int __maybe_unused mtk_iommu_resume(struct device *dev)

static struct platform_driver mtk_iommu_driver = {
.probe = mtk_iommu_probe,
- .remove = mtk_iommu_remove,
.driver = {
.name = "mtk-iommu-v1",
.of_match_table = mtk_iommu_of_ids,
.pm = &mtk_iommu_pm_ops,
}
};
-
-static int __init m4u_init(void)
-{
- return platform_driver_register(&mtk_iommu_driver);
-}
-subsys_initcall(m4u_init);
+builtin_platform_driver(mtk_iommu_driver);
--
1.9.1

2019-09-03 09:41:31

by Yong Wu (吴勇)

[permalink] [raw]
Subject: [PATCH v3 03/14] iommu/mediatek: Add device_link between the consumer and the larb devices

MediaTek IOMMU don't have its power-domain. all the consumer connect
with smi-larb, then connect with smi-common.

M4U
|
smi-common
|
-------------
| | ...
| |
larb1 larb2
| |
vdec venc

When the consumer works, it should enable the smi-larb's power which
also need enable the smi-common's power firstly.

Thus, First of all, use the device link connect the consumer and the
smi-larbs. then add device link between the smi-larb and smi-common.

This patch adds device_link between the consumer and the larbs.

When device_link_add, I add the flag DL_FLAG_STATELESS to avoid calling
pm_runtime_xx to keep the original status of clocks. It can avoid two
issues:
1) Display HW show fastlogo abnormally reported in [1]. At the beggining,
all the clocks are enabled before entering kernel, but the clocks for
display HW(always in larb0) will be gated after clk_enable and clk_disable
called from device_link_add(->pm_runtime_resume) and rpm_idle. The clock
operation happened before display driver probe. At that time, the display
HW will be abnormal.

2) A deadlock issue reported in [2]. Use DL_FLAG_STATELESS to skip
pm_runtime_xx to avoid the deadlock.

Corresponding, DL_FLAG_AUTOREMOVE_CONSUMER can't be added, then
device_link_removed should be added explicitly.

[1] http://lists.infradead.org/pipermail/linux-mediatek/2019-July/
021500.html
[2] https://lore.kernel.org/patchwork/patch/1086569/

Suggested-by: Tomasz Figa <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
---
drivers/iommu/mtk_iommu.c | 17 +++++++++++++++++
drivers/iommu/mtk_iommu_v1.c | 18 +++++++++++++++++-
2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index b138b94..2511b3c 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -450,6 +450,9 @@ static int mtk_iommu_add_device(struct device *dev)
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
struct mtk_iommu_data *data;
struct iommu_group *group;
+ struct device_link *link;
+ struct device *larbdev;
+ unsigned int larbid;

if (!fwspec || fwspec->ops != &mtk_iommu_ops)
return -ENODEV; /* Not a iommu client device */
@@ -461,6 +464,14 @@ static int mtk_iommu_add_device(struct device *dev)
if (IS_ERR(group))
return PTR_ERR(group);

+ /* Link the consumer device with the smi-larb device(supplier) */
+ larbid = MTK_M4U_TO_LARB(fwspec->ids[0]);
+ 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));
+
iommu_group_put(group);
return 0;
}
@@ -469,6 +480,8 @@ static void mtk_iommu_remove_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;
@@ -476,6 +489,10 @@ static void mtk_iommu_remove_device(struct device *dev)
data = fwspec->iommu_priv;
iommu_device_unlink(&data->iommu, dev);

+ larbid = MTK_M4U_TO_LARB(fwspec->ids[0]);
+ larbdev = data->larb_imu[larbid].dev;
+ device_link_remove(dev, larbdev);
+
iommu_group_remove_device(dev);
iommu_fwspec_free(dev);
}
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index 2034d72..a7f22a2 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -423,7 +423,9 @@ static int mtk_iommu_add_device(struct device *dev)
struct of_phandle_iterator it;
struct mtk_iommu_data *data;
struct iommu_group *group;
- int err;
+ struct device_link *link;
+ struct device *larbdev;
+ int err, larbid;

of_for_each_phandle(&it, err, dev->of_node, "iommus",
"#iommu-cells", 0) {
@@ -466,6 +468,14 @@ static int mtk_iommu_add_device(struct device *dev)
return err;
}

+ /* Link the consumer device with the smi-larb device(supplier) */
+ larbid = mt2701_m4u_to_larb(fwspec->ids[0]);
+ 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 iommu_device_link(&data->iommu, dev);
}

@@ -473,6 +483,8 @@ static void mtk_iommu_remove_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;
@@ -480,6 +492,10 @@ static void mtk_iommu_remove_device(struct device *dev)
data = fwspec->iommu_priv;
iommu_device_unlink(&data->iommu, dev);

+ larbid = mt2701_m4u_to_larb(fwspec->ids[0]);
+ larbdev = data->larb_imu[larbid].dev;
+ device_link_remove(dev, larbdev);
+
iommu_group_remove_device(dev);
iommu_fwspec_free(dev);
}
--
1.9.1

2019-09-03 09:41:34

by Yong Wu (吴勇)

[permalink] [raw]
Subject: [PATCH v3 04/14] memory: mtk-smi: Add device-link between smi-larb and smi-common

Normally, If the smi-larb HW need work, we should enable the smi-common
HW power and clock firstly.
This patch adds device-link between the smi-larb dev and the smi-common
dev. then If pm_runtime_get_sync(smi-larb-dev), the pm_runtime_get_sync
(smi-common-dev) will be called automatically.

Also, Add DL_FLAG_STATELESS to avoid the smi-common clocks be gated when
probe.

CC: Matthias Brugger <[email protected]>
Suggested-by: Tomasz Figa <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
---
drivers/memory/mtk-smi.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 439d7d8..5dab56c 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -273,6 +273,7 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct device_node *smi_node;
struct platform_device *smi_pdev;
+ struct device_link *link;

larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
if (!larb)
@@ -312,6 +313,12 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
if (!platform_get_drvdata(smi_pdev))
return -EPROBE_DEFER;
larb->smi_common_dev = &smi_pdev->dev;
+ link = device_link_add(dev, larb->smi_common_dev,
+ DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
+ if (!link) {
+ dev_err(dev, "Unable to link smi-common dev\n");
+ return -ENODEV;
+ }
} else {
dev_err(dev, "Failed to get the smi_common device\n");
return -EINVAL;
@@ -324,6 +331,9 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)

static int mtk_smi_larb_remove(struct platform_device *pdev)
{
+ struct mtk_smi_larb *larb = platform_get_drvdata(pdev);
+
+ device_link_remove(&pdev->dev, larb->smi_common_dev);
pm_runtime_disable(&pdev->dev);
component_del(&pdev->dev, &mtk_smi_larb_component_ops);
return 0;
@@ -335,17 +345,9 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
int ret;

- /* Power on smi-common. */
- ret = pm_runtime_get_sync(larb->smi_common_dev);
- if (ret < 0) {
- dev_err(dev, "Failed to pm get for smi-common(%d).\n", ret);
- return ret;
- }
-
ret = mtk_smi_clk_enable(&larb->smi);
if (ret < 0) {
dev_err(dev, "Failed to enable clock(%d).\n", ret);
- pm_runtime_put_sync(larb->smi_common_dev);
return ret;
}

@@ -360,7 +362,6 @@ static int __maybe_unused mtk_smi_larb_suspend(struct device *dev)
struct mtk_smi_larb *larb = dev_get_drvdata(dev);

mtk_smi_clk_disable(&larb->smi);
- pm_runtime_put_sync(larb->smi_common_dev);
return 0;
}

--
1.9.1

2019-09-03 09:41:42

by Yong Wu (吴勇)

[permalink] [raw]
Subject: [PATCH v3 06/14] media: mtk-mdp: Get rid of mtk_smi_larb_get/put

MediaTek IOMMU has already added the device_link between the consumer
and smi-larb device. If the mdp device call the pm_runtime_get_sync,
the smi-larb's pm_runtime_get_sync also be called automatically.

CC: Minghsiu Tsai <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
Reviewed-by: Evan Green <[email protected]>
---
drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 38 ---------------------------
drivers/media/platform/mtk-mdp/mtk_mdp_comp.h | 2 --
drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 1 -
3 files changed, 41 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 9afe816..5985a9b 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -9,7 +9,6 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
-#include <soc/mediatek/smi.h>

#include "mtk_mdp_comp.h"

@@ -58,14 +57,6 @@ 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 id:%d\n",
- err, comp->type, comp->id);
- }
-
for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
if (IS_ERR(comp->clk[i]))
continue;
@@ -86,16 +77,11 @@ 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_id comp_id)
{
- struct device_node *larb_node;
- struct platform_device *larb_pdev;
int i;

if (comp_id < 0 || comp_id >= MTK_MDP_COMP_ID_MAX) {
@@ -116,30 +102,6 @@ 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);
- 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;
}

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index 998a4b9..a2da8df 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -39,7 +39,6 @@ enum mtk_mdp_comp_id {
* @dev_node: component device node
* @clk: clocks required for component
* @regs: Mapped address of component registers.
- * @larb_dev: SMI device required for component
* @type: component type
* @id: component ID
*/
@@ -47,7 +46,6 @@ struct mtk_mdp_comp {
struct device_node *dev_node;
struct clk *clk[2];
void __iomem *regs;
- struct device *larb_dev;
enum mtk_mdp_comp_type type;
enum mtk_mdp_comp_id id;
};
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index fc9faec..c237ed9 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -17,7 +17,6 @@
#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"
--
1.9.1

2019-09-03 09:41:43

by Yong Wu (吴勇)

[permalink] [raw]
Subject: [PATCH v3 05/14] media: mtk-jpeg: Get rid of mtk_smi_larb_get/put

MediaTek IOMMU has already added device_link between the consumer
and smi-larb device. If the jpg device call the pm_runtime_get_sync,
the smi-larb's pm_runtime_get_sync also be called automatically.

CC: Rick Chang <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
Reviewed-by: Evan Green <[email protected]>
---
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c | 22 ----------------------
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h | 2 --
2 files changed, 24 deletions(-)

diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
index ee802fc..3242a8d 100644
--- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
@@ -21,7 +21,6 @@
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-core.h>
#include <media/videobuf2-dma-contig.h>
-#include <soc/mediatek/smi.h>

#include "mtk_jpeg_hw.h"
#include "mtk_jpeg_core.h"
@@ -893,11 +892,6 @@ static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq,

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);
clk_prepare_enable(jpeg->clk_jdec_smi);
clk_prepare_enable(jpeg->clk_jdec);
}
@@ -906,7 +900,6 @@ static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg)
{
clk_disable_unprepare(jpeg->clk_jdec);
clk_disable_unprepare(jpeg->clk_jdec_smi);
- mtk_smi_larb_put(jpeg->larb);
}

static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv)
@@ -1051,21 +1044,6 @@ static int mtk_jpeg_release(struct file *file)

static int mtk_jpeg_clk_init(struct mtk_jpeg_dev *jpeg)
{
- struct device_node *node;
- struct platform_device *pdev;
-
- 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;
-
jpeg->clk_jdec = devm_clk_get(jpeg->dev, "jpgdec");
if (IS_ERR(jpeg->clk_jdec))
return PTR_ERR(jpeg->clk_jdec);
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
index 999bd14..8579494 100644
--- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
@@ -47,7 +47,6 @@ enum mtk_jpeg_ctx_state {
* @dec_reg_base: JPEG registers mapping
* @clk_jdec: JPEG hw working clock
* @clk_jdec_smi: JPEG SMI bus clock
- * @larb: SMI device
*/
struct mtk_jpeg_dev {
struct mutex lock;
@@ -61,7 +60,6 @@ struct mtk_jpeg_dev {
void __iomem *dec_reg_base;
struct clk *clk_jdec;
struct clk *clk_jdec_smi;
- struct device *larb;
};

/**
--
1.9.1

2019-09-03 09:41:45

by Yong Wu (吴勇)

[permalink] [raw]
Subject: [PATCH v3 12/14] drm/mediatek: Add pm runtime support for ovl and rdma

From: Yongqiang Niu <[email protected]>

Display use the dispsys device to call pm_rumtime_get_sync before.
This patch add pm_runtime_xx with ovl and rdma device which has linked
with larb0, then it will enable the correpsonding larb0 clock
automatically by the device link.

Signed-off-by: Yongqiang Niu <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
---
drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 5 +++++
drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 5 +++++
drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 18 ++++++++++++++++--
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 9 +++++++++
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 1 +
5 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index c4f07c2..51958cf 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -9,6 +9,7 @@
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>

#include "mtk_drm_crtc.h"
#include "mtk_drm_ddp_comp.h"
@@ -300,6 +301,8 @@ 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)
dev_err(dev, "Failed to add component: %d\n", ret);
@@ -311,6 +314,8 @@ 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 9a6f0a2..15e5c3a 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -9,6 +9,7 @@
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>

#include "mtk_drm_crtc.h"
#include "mtk_drm_ddp_comp.h"
@@ -306,6 +307,8 @@ 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)
dev_err(dev, "Failed to add component: %d\n", ret);
@@ -317,6 +320,8 @@ 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 c1e891e..daf002e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -358,13 +358,21 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+ struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
int ret;

DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);

+ ret = pm_runtime_get_sync(comp->dev);
+ if (ret < 0)
+ DRM_DEV_ERROR(comp->dev, "Failed to enable power domain: %d\n",
+ ret);
+
ret = mtk_crtc_ddp_hw_init(mtk_crtc);
- if (ret)
+ if (ret) {
+ pm_runtime_put(comp->dev);
return;
+ }

drm_crtc_vblank_on(crtc);
mtk_crtc->enabled = true;
@@ -374,7 +382,8 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
- int i;
+ struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
+ int i, ret;

DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
if (!mtk_crtc->enabled)
@@ -398,6 +407,11 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
mtk_crtc_ddp_hw_fini(mtk_crtc);

mtk_crtc->enabled = false;
+
+ ret = pm_runtime_put(comp->dev);
+ if (ret < 0)
+ DRM_DEV_ERROR(comp->dev, "Failed to disable power domain: %d\n",
+ ret);
}

static void mtk_drm_crtc_atomic_begin(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 7dc8496..c45e1f0 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -256,6 +256,8 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
struct mtk_ddp_comp *comp, enum mtk_ddp_comp_id comp_id,
const struct mtk_ddp_comp_funcs *funcs)
{
+ struct platform_device *comp_pdev;
+
if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX)
return -EINVAL;

@@ -282,6 +284,13 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
if (IS_ERR(comp->clk))
return PTR_ERR(comp->clk);

+ comp_pdev = of_find_device_by_node(node);
+ if (!comp_pdev) {
+ dev_err(dev, "Waiting for device %s\n", node->full_name);
+ return -EPROBE_DEFER;
+ }
+ comp->dev = &comp_pdev->dev;
+
return 0;
}

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 108de60..d1838a8 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -83,6 +83,7 @@ struct mtk_ddp_comp {
struct clk *clk;
void __iomem *regs;
int irq;
+ struct device *dev;
enum mtk_ddp_comp_id id;
const struct mtk_ddp_comp_funcs *funcs;
};
--
1.9.1

2019-09-03 09:41:51

by Yong Wu (吴勇)

[permalink] [raw]
Subject: [PATCH v3 13/14] arm: dts: mediatek: Get rid of mediatek,larb for MM nodes

After adding device_link between the IOMMU consumer and smi,
the mediatek,larb is unnecessary now.

CC: Matthias Brugger <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
Reviewed-by: Evan Green <[email protected]>
---
arch/arm/boot/dts/mt2701.dtsi | 1 -
arch/arm/boot/dts/mt7623.dtsi | 1 -
2 files changed, 2 deletions(-)

diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
index 51e1305..57b5de3 100644
--- a/arch/arm/boot/dts/mt2701.dtsi
+++ b/arch/arm/boot/dts/mt2701.dtsi
@@ -564,7 +564,6 @@
clock-names = "jpgdec-smi",
"jpgdec";
power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
- mediatek,larb = <&larb2>;
iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>,
<&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>;
};
diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
index a79f0b6..cf22c58 100644
--- a/arch/arm/boot/dts/mt7623.dtsi
+++ b/arch/arm/boot/dts/mt7623.dtsi
@@ -783,7 +783,6 @@
clock-names = "jpgdec-smi",
"jpgdec";
power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
- mediatek,larb = <&larb2>;
iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>,
<&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>;
};
--
1.9.1

2019-09-03 09:42:02

by Yong Wu (吴勇)

[permalink] [raw]
Subject: [PATCH v3 14/14] arm64: dts: mediatek: Get rid of mediatek,larb for MM nodes

After adding device_link between the IOMMU consumer and smi,
the mediatek,larb is unnecessary now.

CC: Matthias Brugger <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
Reviewed-by: Evan Green <[email protected]>
---
arch/arm64/boot/dts/mediatek/mt8173.dtsi | 15 ---------------
1 file changed, 15 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 15f1842..06e2c09 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -921,7 +921,6 @@
<&mmsys CLK_MM_MUTEX_32K>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_RDMA0>;
- mediatek,larb = <&larb0>;
mediatek,vpu = <&vpu>;
};

@@ -932,7 +931,6 @@
<&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 {
@@ -962,7 +960,6 @@
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 {
@@ -971,7 +968,6 @@
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 {
@@ -980,7 +976,6 @@
clocks = <&mmsys CLK_MM_MDP_WROT1>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_WROT1>;
- mediatek,larb = <&larb4>;
};

ovl0: ovl@1400c000 {
@@ -990,7 +985,6 @@
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_OVL0>;
iommus = <&iommu M4U_PORT_DISP_OVL0>;
- mediatek,larb = <&larb0>;
};

ovl1: ovl@1400d000 {
@@ -1000,7 +994,6 @@
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_OVL1>;
iommus = <&iommu M4U_PORT_DISP_OVL1>;
- mediatek,larb = <&larb4>;
};

rdma0: rdma@1400e000 {
@@ -1010,7 +1003,6 @@
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_RDMA0>;
iommus = <&iommu M4U_PORT_DISP_RDMA0>;
- mediatek,larb = <&larb0>;
};

rdma1: rdma@1400f000 {
@@ -1020,7 +1012,6 @@
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_RDMA1>;
iommus = <&iommu M4U_PORT_DISP_RDMA1>;
- mediatek,larb = <&larb4>;
};

rdma2: rdma@14010000 {
@@ -1030,7 +1021,6 @@
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_RDMA2>;
iommus = <&iommu M4U_PORT_DISP_RDMA2>;
- mediatek,larb = <&larb4>;
};

wdma0: wdma@14011000 {
@@ -1040,7 +1030,6 @@
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_WDMA0>;
iommus = <&iommu M4U_PORT_DISP_WDMA0>;
- mediatek,larb = <&larb0>;
};

wdma1: wdma@14012000 {
@@ -1050,7 +1039,6 @@
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_WDMA1>;
iommus = <&iommu M4U_PORT_DISP_WDMA1>;
- mediatek,larb = <&larb4>;
};

color0: color@14013000 {
@@ -1294,7 +1282,6 @@
<0 0x16027800 0 0x800>, /* VDEC_HWB */
<0 0x16028400 0 0x400>; /* VDEC_HWG */
interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
- mediatek,larb = <&larb1>;
iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
<&iommu M4U_PORT_HW_VDEC_PP_EXT>,
<&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
@@ -1364,8 +1351,6 @@
<0 0x19002000 0 0x1000>; /* VENC_LT_SYS */
interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>,
<GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
- mediatek,larb = <&larb3>,
- <&larb5>;
iommus = <&iommu M4U_PORT_VENC_RCPU>,
<&iommu M4U_PORT_VENC_REC>,
<&iommu M4U_PORT_VENC_BSDMA>,
--
1.9.1

2019-09-03 09:42:42

by Yong Wu (吴勇)

[permalink] [raw]
Subject: [PATCH v3 11/14] memory: mtk-smi: Use device_is_bound to check if smi-common is ready

smi-larb driver should run after smi-common, Use device_is_bound to confirm
whether smicommon driver is ready.

CC: Matthias Brugger <[email protected]>
Signed-off-by: Yong Wu <[email protected]>
---
drivers/memory/mtk-smi.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 3df9036..789d2ab 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -296,8 +296,14 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
smi_pdev = of_find_device_by_node(smi_node);
of_node_put(smi_node);
if (smi_pdev) {
- if (!platform_get_drvdata(smi_pdev))
+ bool smicommon_is_bound;
+
+ device_lock(&smi_pdev->dev);
+ smicommon_is_bound = device_is_bound(&smi_pdev->dev);
+ device_unlock(&smi_pdev->dev);
+ if (!smicommon_is_bound)
return -EPROBE_DEFER;
+
larb->smi_common_dev = &smi_pdev->dev;
link = device_link_add(dev, larb->smi_common_dev,
DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
--
1.9.1

2019-09-04 04:09:26

by houlong wei

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] media: mtk-mdp: Get rid of mtk_smi_larb_get/put

Hi, Yong,

I have inline comment below.

> MediaTek IOMMU has already added the device_link between the consumer
> and smi-larb device. If the mdp device call the pm_runtime_get_sync,
> the smi-larb's pm_runtime_get_sync also be called automatically.
>
> CC: Minghsiu Tsai <[email protected]>
> Signed-off-by: Yong Wu <[email protected]>
> Reviewed-by: Evan Green <[email protected]>
> ---
> drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 38 ---------------------------
> drivers/media/platform/mtk-mdp/mtk_mdp_comp.h | 2 --
> drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 1 -
> 3 files changed, 41 deletions(-)
>
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> index 9afe816..5985a9b 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> @@ -9,7 +9,6 @@
> #include <linux/of.h>
> #include <linux/of_address.h>
> #include <linux/of_platform.h>
> -#include <soc/mediatek/smi.h>
>
> #include "mtk_mdp_comp.h"
>
> @@ -58,14 +57,6 @@ 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 id:%d\n",
> - err, comp->type, comp->id);
> - }

In previous design,mtk_mdp_comp_clock_on() is called by each MDP
hardware component, and mtk_smi_larb_get() is also called for each MDP
hardware component which accesses DRAM via SMI larb.

Since mdp device only contains mdp_rdma component, so
pm_runtime_get_sync() will ignore other smi-larb clock. We need consider
how to enable clocks of other smi-larb associated with other mdp
component, e.g. mdp_wdma, mdp_wrot.


> for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
> if (IS_ERR(comp->clk[i]))
> continue;
> @@ -86,16 +77,11 @@ 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_id comp_id)
> {
> - struct device_node *larb_node;
> - struct platform_device *larb_pdev;
> int i;
>
> if (comp_id < 0 || comp_id >= MTK_MDP_COMP_ID_MAX) {
> @@ -116,30 +102,6 @@ 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);
> - 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;
> }
>
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> index 998a4b9..a2da8df 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> @@ -39,7 +39,6 @@ enum mtk_mdp_comp_id {
> * @dev_node: component device node
> * @clk: clocks required for component
> * @regs: Mapped address of component registers.
> - * @larb_dev: SMI device required for component
> * @type: component type
> * @id: component ID
> */
> @@ -47,7 +46,6 @@ struct mtk_mdp_comp {
> struct device_node *dev_node;
> struct clk *clk[2];
> void __iomem *regs;
> - struct device *larb_dev;
> enum mtk_mdp_comp_type type;
> enum mtk_mdp_comp_id id;
> };
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> index fc9faec..c237ed9 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> @@ -17,7 +17,6 @@
> #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"



2019-09-05 05:58:10

by Yong Wu (吴勇)

[permalink] [raw]
Subject: Re: [PATCH v3 06/14] media: mtk-mdp: Get rid of mtk_smi_larb_get/put

On Wed, 2019-09-04 at 12:07 +0800, houlong wei wrote:
> Hi, Yong,
>
> I have inline comment below.

Thanks for your review.

>
> > MediaTek IOMMU has already added the device_link between the consumer
> > and smi-larb device. If the mdp device call the pm_runtime_get_sync,
> > the smi-larb's pm_runtime_get_sync also be called automatically.
> >
> > CC: Minghsiu Tsai <[email protected]>
> > Signed-off-by: Yong Wu <[email protected]>
> > Reviewed-by: Evan Green <[email protected]>
> > ---
> > drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 38 ---------------------------
> > drivers/media/platform/mtk-mdp/mtk_mdp_comp.h | 2 --
> > drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 1 -
> > 3 files changed, 41 deletions(-)
> >
> > diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> > index 9afe816..5985a9b 100644
> > --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> > +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> > @@ -9,7 +9,6 @@
> > #include <linux/of.h>
> > #include <linux/of_address.h>
> > #include <linux/of_platform.h>
> > -#include <soc/mediatek/smi.h>
> >
> > #include "mtk_mdp_comp.h"
> >
> > @@ -58,14 +57,6 @@ 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 id:%d\n",
> > - err, comp->type, comp->id);
> > - }
>
> In previous design,mtk_mdp_comp_clock_on() is called by each MDP
> hardware component, and mtk_smi_larb_get() is also called for each MDP
> hardware component which accesses DRAM via SMI larb.
>
> Since mdp device only contains mdp_rdma component, so
> pm_runtime_get_sync() will ignore other smi-larb clock. We need consider
> how to enable clocks of other smi-larb associated with other mdp
> component, e.g. mdp_wdma, mdp_wrot.
>

Sorry, I'm not so familiar with mdp, thus, for MDP part, the test and
reviewing from Minghsiu or you is expected.

This patch only delete the smi interface literally. In my understanding,
mdp should call pm_runtime_get with the corresponding device, no matter
mdp_wdma or mdp_wrot device.

Of course I am not sure the mdp flow, If this patch affect its function,
please tell me. Also, If mdp driver need change correspondingly, I will
put it into this series like [12/14] of this patchset which is from
display.

[snip]


2019-09-16 14:49:25

by CK Hu (胡俊光)

[permalink] [raw]
Subject: Re: [PATCH v3 12/14] drm/mediatek: Add pm runtime support for ovl and rdma


Hi, Yong:

On Tue, 2019-09-03 at 17:37 +0800, Yong Wu wrote:
> From: Yongqiang Niu <[email protected]>
>
> Display use the dispsys device to call pm_rumtime_get_sync before.
> This patch add pm_runtime_xx with ovl and rdma device which has linked
> with larb0, then it will enable the correpsonding larb0 clock
> automatically by the device link.

This patch should be applied before "drm/mediatek: Get rid of
mtk_smi_larb_get/put". If before that patch, this patch is a preparation
of that patch. If after that patch, this patch is a bug fix of that
patch. Why let bug happen?

>
> Signed-off-by: Yongqiang Niu <[email protected]>
> Signed-off-by: Yong Wu <[email protected]>
> ---
> drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 5 +++++
> drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 5 +++++
> drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 18 ++++++++++++++++--
> drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 9 +++++++++
> drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 1 +
> 5 files changed, 36 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index c4f07c2..51958cf 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -9,6 +9,7 @@
> #include <linux/of_device.h>
> #include <linux/of_irq.h>
> #include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
>
> #include "mtk_drm_crtc.h"
> #include "mtk_drm_ddp_comp.h"
> @@ -300,6 +301,8 @@ 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)
> dev_err(dev, "Failed to add component: %d\n", ret);

This error should do some error handling to undo pm_runtime_enable().

> @@ -311,6 +314,8 @@ 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 9a6f0a2..15e5c3a 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> @@ -9,6 +9,7 @@
> #include <linux/of_device.h>
> #include <linux/of_irq.h>
> #include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
>
> #include "mtk_drm_crtc.h"
> #include "mtk_drm_ddp_comp.h"
> @@ -306,6 +307,8 @@ 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)
> dev_err(dev, "Failed to add component: %d\n", ret);

Ditto.

> @@ -317,6 +320,8 @@ 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 c1e891e..daf002e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -358,13 +358,21 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
> struct drm_crtc_state *old_state)
> {
> struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> + struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
> int ret;
>
> DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
>
> + ret = pm_runtime_get_sync(comp->dev);
> + if (ret < 0)
> + DRM_DEV_ERROR(comp->dev, "Failed to enable power domain: %d\n",
> + ret);
> +
> ret = mtk_crtc_ddp_hw_init(mtk_crtc);
> - if (ret)
> + if (ret) {
> + pm_runtime_put(comp->dev);
> return;
> + }
>
> drm_crtc_vblank_on(crtc);
> mtk_crtc->enabled = true;
> @@ -374,7 +382,8 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
> struct drm_crtc_state *old_state)
> {
> struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> - int i;
> + struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
> + int i, ret;
>
> DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
> if (!mtk_crtc->enabled)
> @@ -398,6 +407,11 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
> mtk_crtc_ddp_hw_fini(mtk_crtc);
>
> mtk_crtc->enabled = false;
> +
> + ret = pm_runtime_put(comp->dev);
> + if (ret < 0)
> + DRM_DEV_ERROR(comp->dev, "Failed to disable power domain: %d\n",
> + ret);
> }
>
> static void mtk_drm_crtc_atomic_begin(struct drm_crtc *crtc,
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 7dc8496..c45e1f0 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -256,6 +256,8 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
> struct mtk_ddp_comp *comp, enum mtk_ddp_comp_id comp_id,
> const struct mtk_ddp_comp_funcs *funcs)
> {
> + struct platform_device *comp_pdev;
> +
> if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX)
> return -EINVAL;
>
> @@ -282,6 +284,13 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
> if (IS_ERR(comp->clk))
> return PTR_ERR(comp->clk);
>
> + comp_pdev = of_find_device_by_node(node);
> + if (!comp_pdev) {
> + dev_err(dev, "Waiting for device %s\n", node->full_name);
> + return -EPROBE_DEFER;
> + }
> + comp->dev = &comp_pdev->dev;

This should be

comp->dev = dev;

Regards,
CK

> +
> return 0;
> }
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index 108de60..d1838a8 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -83,6 +83,7 @@ struct mtk_ddp_comp {
> struct clk *clk;
> void __iomem *regs;
> int irq;
> + struct device *dev;
> enum mtk_ddp_comp_id id;
> const struct mtk_ddp_comp_funcs *funcs;
> };



2020-03-05 05:15:56

by Nicolas Boichat

[permalink] [raw]
Subject: Re: [PATCH v3 03/14] iommu/mediatek: Add device_link between the consumer and the larb devices

On Tue, Sep 3, 2019 at 5:38 PM Yong Wu <[email protected]> wrote:
>
> MediaTek IOMMU don't have its power-domain. all the consumer connect
> with smi-larb, then connect with smi-common.
>
> M4U
> |
> smi-common
> |
> -------------
> | | ...
> | |
> larb1 larb2
> | |
> vdec venc
>
> When the consumer works, it should enable the smi-larb's power which
> also need enable the smi-common's power firstly.
>
> Thus, First of all, use the device link connect the consumer and the
> smi-larbs. then add device link between the smi-larb and smi-common.
>
> This patch adds device_link between the consumer and the larbs.
>
> When device_link_add, I add the flag DL_FLAG_STATELESS to avoid calling
> pm_runtime_xx to keep the original status of clocks. It can avoid two
> issues:
> 1) Display HW show fastlogo abnormally reported in [1]. At the beggining,
> all the clocks are enabled before entering kernel, but the clocks for
> display HW(always in larb0) will be gated after clk_enable and clk_disable
> called from device_link_add(->pm_runtime_resume) and rpm_idle. The clock
> operation happened before display driver probe. At that time, the display
> HW will be abnormal.
>
> 2) A deadlock issue reported in [2]. Use DL_FLAG_STATELESS to skip
> pm_runtime_xx to avoid the deadlock.
>
> Corresponding, DL_FLAG_AUTOREMOVE_CONSUMER can't be added, then
> device_link_removed should be added explicitly.
>
> [1] http://lists.infradead.org/pipermail/linux-mediatek/2019-July/
> 021500.html
> [2] https://lore.kernel.org/patchwork/patch/1086569/
>
> Suggested-by: Tomasz Figa <[email protected]>
> Signed-off-by: Yong Wu <[email protected]>
> ---
> drivers/iommu/mtk_iommu.c | 17 +++++++++++++++++
> drivers/iommu/mtk_iommu_v1.c | 18 +++++++++++++++++-
> 2 files changed, 34 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index b138b94..2511b3c 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -450,6 +450,9 @@ static int mtk_iommu_add_device(struct device *dev)
> struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> struct mtk_iommu_data *data;
> struct iommu_group *group;
> + struct device_link *link;
> + struct device *larbdev;
> + unsigned int larbid;
>
> if (!fwspec || fwspec->ops != &mtk_iommu_ops)
> return -ENODEV; /* Not a iommu client device */
> @@ -461,6 +464,14 @@ static int mtk_iommu_add_device(struct device *dev)
> if (IS_ERR(group))
> return PTR_ERR(group);
>
> + /* Link the consumer device with the smi-larb device(supplier) */
> + larbid = MTK_M4U_TO_LARB(fwspec->ids[0]);

I'll mirror the comment I made on gerrit
(https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/1361013):
Maybe I'm missing something here, but for example, on MT8173,
vcodec_enc: vcodec@18002000 needs to use both larb3 and larb5, isn't
the code below just adding a link for larb3?

Do we need to iterate over all fwspecs->ids to figure out which larbs
we need to add links to each of them?

> + 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));
> +
> iommu_group_put(group);
> return 0;
> }
> @@ -469,6 +480,8 @@ static void mtk_iommu_remove_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;
> @@ -476,6 +489,10 @@ static void mtk_iommu_remove_device(struct device *dev)
> data = fwspec->iommu_priv;
> iommu_device_unlink(&data->iommu, dev);
>
> + larbid = MTK_M4U_TO_LARB(fwspec->ids[0]);
> + larbdev = data->larb_imu[larbid].dev;
> + device_link_remove(dev, larbdev);
> +
> iommu_group_remove_device(dev);
> iommu_fwspec_free(dev);
> }
> diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
> index 2034d72..a7f22a2 100644
> --- a/drivers/iommu/mtk_iommu_v1.c
> +++ b/drivers/iommu/mtk_iommu_v1.c
> @@ -423,7 +423,9 @@ static int mtk_iommu_add_device(struct device *dev)
> struct of_phandle_iterator it;
> struct mtk_iommu_data *data;
> struct iommu_group *group;
> - int err;
> + struct device_link *link;
> + struct device *larbdev;
> + int err, larbid;
>
> of_for_each_phandle(&it, err, dev->of_node, "iommus",
> "#iommu-cells", 0) {
> @@ -466,6 +468,14 @@ static int mtk_iommu_add_device(struct device *dev)
> return err;
> }
>
> + /* Link the consumer device with the smi-larb device(supplier) */
> + larbid = mt2701_m4u_to_larb(fwspec->ids[0]);
> + 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 iommu_device_link(&data->iommu, dev);
> }
>
> @@ -473,6 +483,8 @@ static void mtk_iommu_remove_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;
> @@ -480,6 +492,10 @@ static void mtk_iommu_remove_device(struct device *dev)
> data = fwspec->iommu_priv;
> iommu_device_unlink(&data->iommu, dev);
>
> + larbid = mt2701_m4u_to_larb(fwspec->ids[0]);
> + larbdev = data->larb_imu[larbid].dev;
> + device_link_remove(dev, larbdev);
> +
> iommu_group_remove_device(dev);
> iommu_fwspec_free(dev);
> }
> --
> 1.9.1
>

2020-03-06 07:02:54

by Yong Wu (吴勇)

[permalink] [raw]
Subject: Re: [PATCH v3 03/14] iommu/mediatek: Add device_link between the consumer and the larb devices

On Thu, 2020-03-05 at 13:14 +0800, Nicolas Boichat wrote:
> On Tue, Sep 3, 2019 at 5:38 PM Yong Wu <[email protected]> wrote:
> >
> > MediaTek IOMMU don't have its power-domain. all the consumer connect
> > with smi-larb, then connect with smi-common.
> >
> > M4U
> > |
> > smi-common
> > |
> > -------------
> > | | ...
> > | |
> > larb1 larb2
> > | |
> > vdec venc
> >
> > When the consumer works, it should enable the smi-larb's power which
> > also need enable the smi-common's power firstly.
> >
> > Thus, First of all, use the device link connect the consumer and the
> > smi-larbs. then add device link between the smi-larb and smi-common.
> >
> > This patch adds device_link between the consumer and the larbs.
> >
> > When device_link_add, I add the flag DL_FLAG_STATELESS to avoid calling
> > pm_runtime_xx to keep the original status of clocks. It can avoid two
> > issues:
> > 1) Display HW show fastlogo abnormally reported in [1]. At the beggining,
> > all the clocks are enabled before entering kernel, but the clocks for
> > display HW(always in larb0) will be gated after clk_enable and clk_disable
> > called from device_link_add(->pm_runtime_resume) and rpm_idle. The clock
> > operation happened before display driver probe. At that time, the display
> > HW will be abnormal.
> >
> > 2) A deadlock issue reported in [2]. Use DL_FLAG_STATELESS to skip
> > pm_runtime_xx to avoid the deadlock.
> >
> > Corresponding, DL_FLAG_AUTOREMOVE_CONSUMER can't be added, then
> > device_link_removed should be added explicitly.
> >
> > [1] http://lists.infradead.org/pipermail/linux-mediatek/2019-July/
> > 021500.html
> > [2] https://lore.kernel.org/patchwork/patch/1086569/
> >
> > Suggested-by: Tomasz Figa <[email protected]>
> > Signed-off-by: Yong Wu <[email protected]>
> > ---
> > drivers/iommu/mtk_iommu.c | 17 +++++++++++++++++
> > drivers/iommu/mtk_iommu_v1.c | 18 +++++++++++++++++-
> > 2 files changed, 34 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> > index b138b94..2511b3c 100644
> > --- a/drivers/iommu/mtk_iommu.c
> > +++ b/drivers/iommu/mtk_iommu.c
> > @@ -450,6 +450,9 @@ static int mtk_iommu_add_device(struct device *dev)
> > struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> > struct mtk_iommu_data *data;
> > struct iommu_group *group;
> > + struct device_link *link;
> > + struct device *larbdev;
> > + unsigned int larbid;
> >
> > if (!fwspec || fwspec->ops != &mtk_iommu_ops)
> > return -ENODEV; /* Not a iommu client device */
> > @@ -461,6 +464,14 @@ static int mtk_iommu_add_device(struct device *dev)
> > if (IS_ERR(group))
> > return PTR_ERR(group);
> >
> > + /* Link the consumer device with the smi-larb device(supplier) */
> > + larbid = MTK_M4U_TO_LARB(fwspec->ids[0]);
>
> I'll mirror the comment I made on gerrit
> (https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/1361013):
> Maybe I'm missing something here, but for example, on MT8173,
> vcodec_enc: vcodec@18002000 needs to use both larb3 and larb5, isn't
> the code below just adding a link for larb3?

Yes. It only add larb3 here.

>
> Do we need to iterate over all fwspecs->ids to figure out which larbs
> we need to add links to each of them?

We have checked this venc issue. Currently I have requested our venc guy
to seperate larb3-venc and larb5-venc in the driver[1] since they are
independent HW actually. I will put it into this series when I send next
version.

If there is some reasonable driver which have two larbs in it, then the
iterating is really necessary, But I don't see it right now. Only using
fwspec->ids[0] is enough for now.

[1]
https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/1958322

>
> > + 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));
> > +
> > iommu_group_put(group);
> > return 0;
> > }
> > @@ -469,6 +480,8 @@ static void mtk_iommu_remove_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;
> > @@ -476,6 +489,10 @@ static void mtk_iommu_remove_device(struct device *dev)
> > data = fwspec->iommu_priv;
> > iommu_device_unlink(&data->iommu, dev);
> >
> > + larbid = MTK_M4U_TO_LARB(fwspec->ids[0]);
> > + larbdev = data->larb_imu[larbid].dev;
> > + device_link_remove(dev, larbdev);
> > +
> > iommu_group_remove_device(dev);
> > iommu_fwspec_free(dev);
> > }
> > diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
> > index 2034d72..a7f22a2 100644
> > --- a/drivers/iommu/mtk_iommu_v1.c
> > +++ b/drivers/iommu/mtk_iommu_v1.c
> > @@ -423,7 +423,9 @@ static int mtk_iommu_add_device(struct device *dev)
> > struct of_phandle_iterator it;
> > struct mtk_iommu_data *data;
> > struct iommu_group *group;
> > - int err;
> > + struct device_link *link;
> > + struct device *larbdev;
> > + int err, larbid;
> >
> > of_for_each_phandle(&it, err, dev->of_node, "iommus",
> > "#iommu-cells", 0) {
> > @@ -466,6 +468,14 @@ static int mtk_iommu_add_device(struct device *dev)
> > return err;
> > }
> >
> > + /* Link the consumer device with the smi-larb device(supplier) */
> > + larbid = mt2701_m4u_to_larb(fwspec->ids[0]);
> > + 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 iommu_device_link(&data->iommu, dev);
> > }
> >
> > @@ -473,6 +483,8 @@ static void mtk_iommu_remove_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;
> > @@ -480,6 +492,10 @@ static void mtk_iommu_remove_device(struct device *dev)
> > data = fwspec->iommu_priv;
> > iommu_device_unlink(&data->iommu, dev);
> >
> > + larbid = mt2701_m4u_to_larb(fwspec->ids[0]);
> > + larbdev = data->larb_imu[larbid].dev;
> > + device_link_remove(dev, larbdev);
> > +
> > iommu_group_remove_device(dev);
> > iommu_fwspec_free(dev);
> > }
> > --
> > 1.9.1
> >