From: Hsiao Chien Sung <shawn.sung@mediatek.com>
To: AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com>,
CK Hu <ck.hu@mediatek.com>
Cc: Rob Herring <robh+dt@kernel.org>,
Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
Conor Dooley <conor+dt@kernel.org>,
Chun-Kuang Hu <chunkuang.hu@kernel.org>,
Philipp Zabel <p.zabel@pengutronix.de>,
David Airlie <airlied@gmail.com>, Daniel Vetter <daniel@ffwll.ch>,
Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
Maxime Ripard <mripard@kernel.org>,
Thomas Zimmermann <tzimmermann@suse.de>,
Matthias Brugger <matthias.bgg@gmail.com>,
Moudy Ho <moudy.ho@mediatek.com>,
Hsiao Chien Sung <shawn.sung@mediatek.com>,
Nathan Lu <nathan.lu@mediatek.com>,
"Nancy . Lin" <nancy.lin@mediatek.com>,
"Roy-CW . Yeh" <roy-cw.yeh@mediatek.com>,
"Jason-JH . Lin" <jason-jh.lin@mediatek.com>,
xinlei lee <xinlei.lee@mediatek.com>,
<devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<dri-devel@lists.freedesktop.org>,
<linux-mediatek@lists.infradead.org>,
<linux-arm-kernel@lists.infradead.org>
Subject: [PATCH v12 14/23] drm/mediatek: Power on/off devices with function pointers
Date: Thu, 14 Dec 2023 13:58:38 +0800 [thread overview]
Message-ID: <20231214055847.4936-15-shawn.sung@mediatek.com> (raw)
In-Reply-To: <20231214055847.4936-1-shawn.sung@mediatek.com>
Different from OVL, OVL adaptor is a pseudo device so we didn't
define it in the device tree, consequently, pm_runtime_resume_and_get()
called by .atomic_enable() powers on no device. For this reason, we
implement a function to power on the RDMAs in OVL adaptor, and the
system will make sure the IOMMUs are powered on as well because of the
device link (iommus) in the RDMA nodes in DTS.
This patch separates power and clock management process, it would be
easier to maintain and add extensions.
Reviewed-by: CK Hu <ck.hu@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_disp_drv.h | 4 +
.../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 75 +++++++++++++++----
drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 10 +--
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 2 +
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 +++++
drivers/gpu/drm/mediatek/mtk_mdp_rdma.c | 16 ++++
6 files changed, 107 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 1311562d25cc..2d426775b7ea 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -110,6 +110,8 @@ void mtk_ovl_adaptor_connect(struct device *dev, struct device *mmsys_dev,
unsigned int next);
void mtk_ovl_adaptor_disconnect(struct device *dev, struct device *mmsys_dev,
unsigned int next);
+int mtk_ovl_adaptor_power_on(struct device *dev);
+void mtk_ovl_adaptor_power_off(struct device *dev);
int mtk_ovl_adaptor_clk_enable(struct device *dev);
void mtk_ovl_adaptor_clk_disable(struct device *dev);
void mtk_ovl_adaptor_config(struct device *dev, unsigned int w,
@@ -151,6 +153,8 @@ void mtk_rdma_disable_vblank(struct device *dev);
const u32 *mtk_rdma_get_formats(struct device *dev);
size_t mtk_rdma_get_num_formats(struct device *dev);
+int mtk_mdp_rdma_power_on(struct device *dev);
+void mtk_mdp_rdma_power_off(struct device *dev);
int mtk_mdp_rdma_clk_enable(struct device *dev);
void mtk_mdp_rdma_clk_disable(struct device *dev);
void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
index a815dc8e2110..e00d8a395ca0 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -80,6 +80,8 @@ static const struct mtk_ddp_comp_funcs merge = {
};
static const struct mtk_ddp_comp_funcs rdma = {
+ .power_on = mtk_mdp_rdma_power_on,
+ .power_off = mtk_mdp_rdma_power_off,
.clk_enable = mtk_mdp_rdma_clk_enable,
.clk_disable = mtk_mdp_rdma_clk_disable,
};
@@ -201,21 +203,72 @@ void mtk_ovl_adaptor_stop(struct device *dev)
mtk_ethdr_stop(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
}
-int mtk_ovl_adaptor_clk_enable(struct device *dev)
+/**
+ * power_off - Power off the devices in OVL adaptor
+ * @dev: Device to be powered off
+ * @num: Number of the devices to be powered off
+ *
+ * Calls the .power_off() ovl_adaptor component callback if it is present.
+ */
+static inline void power_off(struct device *dev, int num)
{
struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
- struct device *comp;
- int ret;
int i;
- for (i = 0; i < OVL_ADAPTOR_MERGE0; i++) {
- comp = ovl_adaptor->ovl_adaptor_comp[i];
- ret = pm_runtime_get_sync(comp);
+ if (num > OVL_ADAPTOR_ID_MAX)
+ num = OVL_ADAPTOR_ID_MAX;
+
+ for (i = num - 1; i >= 0; i--) {
+ if (!ovl_adaptor->ovl_adaptor_comp[i] ||
+ !comp_matches[i].funcs->power_off)
+ continue;
+
+ comp_matches[i].funcs->power_off(ovl_adaptor->ovl_adaptor_comp[i]);
+ }
+}
+
+/**
+ * mtk_ovl_adaptor_power_on - Power on the devices in OVL adaptor
+ * @dev: Device to be powered on
+ *
+ * Different from OVL, OVL adaptor is a pseudo device so
+ * we didn't define it in the device tree, pm_runtime_resume_and_get()
+ * called by .atomic_enable() power on no device in OVL adaptor,
+ * we have to implement a function to do the job instead.
+ *
+ * Return: Zero for success or negative number for failure.
+ */
+int mtk_ovl_adaptor_power_on(struct device *dev)
+{
+ struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+ int i, ret;
+
+ for (i = 0; i < OVL_ADAPTOR_ID_MAX; i++) {
+ if (!ovl_adaptor->ovl_adaptor_comp[i] ||
+ !comp_matches[i].funcs->power_on)
+ continue;
+
+ ret = comp_matches[i].funcs->power_on(ovl_adaptor->ovl_adaptor_comp[i]);
if (ret < 0) {
dev_err(dev, "Failed to enable power domain %d, err %d\n", i, ret);
- goto error;
+ power_off(dev, i);
+ return ret;
}
}
+ return 0;
+}
+
+void mtk_ovl_adaptor_power_off(struct device *dev)
+{
+ power_off(dev, OVL_ADAPTOR_ID_MAX);
+}
+
+int mtk_ovl_adaptor_clk_enable(struct device *dev)
+{
+ struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+ struct device *comp;
+ int ret;
+ int i;
for (i = 0; i < OVL_ADAPTOR_ID_MAX; i++) {
comp = ovl_adaptor->ovl_adaptor_comp[i];
@@ -226,16 +279,10 @@ int mtk_ovl_adaptor_clk_enable(struct device *dev)
dev_err(dev, "Failed to enable clock %d, err %d\n", i, ret);
while (--i >= 0)
comp_matches[i].funcs->clk_disable(comp);
- i = OVL_ADAPTOR_MERGE0;
- goto error;
+ return ret;
}
}
return 0;
-error:
- while (--i >= 0)
- pm_runtime_put(ovl_adaptor->ovl_adaptor_comp[i]);
-
- return ret;
}
void mtk_ovl_adaptor_clk_disable(struct device *dev)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index c277b9fae950..4d5ff39dc2ef 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -721,7 +721,7 @@ 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);
+ ret = mtk_ddp_comp_power_on(comp);
if (ret < 0) {
DRM_DEV_ERROR(comp->dev, "Failed to enable power domain: %d\n", ret);
return;
@@ -731,7 +731,7 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
ret = mtk_crtc_ddp_hw_init(mtk_crtc);
if (ret) {
- pm_runtime_put(comp->dev);
+ mtk_ddp_comp_power_off(comp);
return;
}
@@ -744,7 +744,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)
@@ -774,9 +774,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_ddp_comp_power_off(comp);
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 3046c0409353..a9b5a21cde2d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -398,6 +398,8 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe = {
};
static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
+ .power_on = mtk_ovl_adaptor_power_on,
+ .power_off = mtk_ovl_adaptor_power_off,
.clk_enable = mtk_ovl_adaptor_clk_enable,
.clk_disable = mtk_ovl_adaptor_clk_disable,
.config = mtk_ovl_adaptor_config,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 4bae55bdb034..15b2eafff438 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -7,6 +7,7 @@
#define MTK_DRM_DDP_COMP_H
#include <linux/io.h>
+#include <linux/pm_runtime.h>
#include <linux/soc/mediatek/mtk-cmdq.h>
#include <linux/soc/mediatek/mtk-mmsys.h>
#include <linux/soc/mediatek/mtk-mutex.h>
@@ -46,6 +47,8 @@ enum mtk_ddp_comp_type {
struct mtk_ddp_comp;
struct cmdq_pkt;
struct mtk_ddp_comp_funcs {
+ int (*power_on)(struct device *dev);
+ void (*power_off)(struct device *dev);
int (*clk_enable)(struct device *dev);
void (*clk_disable)(struct device *dev);
void (*config)(struct device *dev, unsigned int w,
@@ -92,6 +95,23 @@ struct mtk_ddp_comp {
const struct mtk_ddp_comp_funcs *funcs;
};
+static inline int mtk_ddp_comp_power_on(struct mtk_ddp_comp *comp)
+{
+ if (comp->funcs && comp->funcs->power_on)
+ return comp->funcs->power_on(comp->dev);
+ else
+ return pm_runtime_resume_and_get(comp->dev);
+ return 0;
+}
+
+static inline void mtk_ddp_comp_power_off(struct mtk_ddp_comp *comp)
+{
+ if (comp->funcs && comp->funcs->power_off)
+ comp->funcs->power_off(comp->dev);
+ else
+ pm_runtime_put(comp->dev);
+}
+
static inline int mtk_ddp_comp_clk_enable(struct mtk_ddp_comp *comp)
{
if (comp->funcs && comp->funcs->clk_enable)
diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
index c3adaeefd551..dc7c9e991990 100644
--- a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
@@ -242,6 +242,22 @@ size_t mtk_mdp_rdma_get_num_formats(struct device *dev)
return ARRAY_SIZE(formats);
}
+int mtk_mdp_rdma_power_on(struct device *dev)
+{
+ int ret = pm_runtime_resume_and_get(dev);
+
+ if (ret < 0) {
+ dev_err(dev, "Failed to power on: %d\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+void mtk_mdp_rdma_power_off(struct device *dev)
+{
+ pm_runtime_put(dev);
+}
+
int mtk_mdp_rdma_clk_enable(struct device *dev)
{
struct mtk_mdp_rdma *rdma = dev_get_drvdata(dev);
--
2.18.0
next prev parent reply other threads:[~2023-12-14 6:01 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-14 5:58 [PATCH v12 00/23] Add display driver for MT8188 VDOSYS1 Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 01/23] dt-bindings: display: mediatek: ethdr: Add compatible for MT8188 Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 02/23] dt-bindings: display: mediatek: mdp-rdma: " Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 03/23] dt-bindings: display: mediatek: merge: " Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 04/23] dt-bindings: display: mediatek: padding: Add MT8188 Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 05/23] dt-bindings: arm: mediatek: Add compatible for MT8188 Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 06/23] dt-bindings: reset: mt8188: Add VDOSYS reset control bits Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 07/23] soc: mediatek: Support MT8188 VDOSYS1 in mtk-mmsys Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 08/23] soc: mediatek: Support MT8188 VDOSYS1 Padding " Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 09/23] soc: mediatek: Support reset bit mapping in mmsys driver Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 10/23] soc: mediatek: Add MT8188 VDOSYS reset bit map Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 11/23] drm/mediatek: Rename OVL_ADAPTOR_TYPE_RDMA Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 12/23] drm/mediatek: Add component ID to component match structure Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 13/23] drm/mediatek: Manage component's clock with function pointers Hsiao Chien Sung
2023-12-14 5:58 ` Hsiao Chien Sung [this message]
2023-12-14 5:58 ` [PATCH v12 15/23] drm/mediatek: Start/Stop components " Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 16/23] drm/mediatek: Sort OVL adaptor components Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 17/23] drm/mediatek: Refine device table of OVL adaptor Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 18/23] drm/mediatek: Support MT8188 Padding in display driver Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 19/23] drm/mediatek: Add Padding to OVL adaptor Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 20/23] drm/mediatek: Return error if MDP RDMA failed to enable the clock Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 21/23] drm/mediatek: Remove the redundant driver data for DPI Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 22/23] drm/mediatek: Fix underrun in VDO1 when switches off the layer Hsiao Chien Sung
2023-12-14 5:58 ` [PATCH v12 23/23] drm/mediatek: Support MT8188 VDOSYS1 in display driver Hsiao Chien Sung
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231214055847.4936-15-shawn.sung@mediatek.com \
--to=shawn.sung@mediatek.com \
--cc=airlied@gmail.com \
--cc=angelogioacchino.delregno@collabora.com \
--cc=chunkuang.hu@kernel.org \
--cc=ck.hu@mediatek.com \
--cc=conor+dt@kernel.org \
--cc=daniel@ffwll.ch \
--cc=devicetree@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=jason-jh.lin@mediatek.com \
--cc=krzysztof.kozlowski+dt@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=matthias.bgg@gmail.com \
--cc=moudy.ho@mediatek.com \
--cc=mripard@kernel.org \
--cc=nancy.lin@mediatek.com \
--cc=nathan.lu@mediatek.com \
--cc=p.zabel@pengutronix.de \
--cc=robh+dt@kernel.org \
--cc=roy-cw.yeh@mediatek.com \
--cc=tzimmermann@suse.de \
--cc=xinlei.lee@mediatek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®