Skip to content

Commit b97fa2f

Browse files
Hsiao Chien SungChun-Kuang Hu
authored andcommitted
drm/mediatek: Power on/off devices with function pointers
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> Link: https://patchwork.kernel.org/project/dri-devel/patch/20231214055847.4936-15-shawn.sung@mediatek.com/ Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
1 parent 7bacaee commit b97fa2f

File tree

6 files changed

+107
-20
lines changed

6 files changed

+107
-20
lines changed

drivers/gpu/drm/mediatek/mtk_disp_drv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ void mtk_ovl_adaptor_connect(struct device *dev, struct device *mmsys_dev,
110110
unsigned int next);
111111
void mtk_ovl_adaptor_disconnect(struct device *dev, struct device *mmsys_dev,
112112
unsigned int next);
113+
int mtk_ovl_adaptor_power_on(struct device *dev);
114+
void mtk_ovl_adaptor_power_off(struct device *dev);
113115
int mtk_ovl_adaptor_clk_enable(struct device *dev);
114116
void mtk_ovl_adaptor_clk_disable(struct device *dev);
115117
void mtk_ovl_adaptor_config(struct device *dev, unsigned int w,
@@ -151,6 +153,8 @@ void mtk_rdma_disable_vblank(struct device *dev);
151153
const u32 *mtk_rdma_get_formats(struct device *dev);
152154
size_t mtk_rdma_get_num_formats(struct device *dev);
153155

156+
int mtk_mdp_rdma_power_on(struct device *dev);
157+
void mtk_mdp_rdma_power_off(struct device *dev);
154158
int mtk_mdp_rdma_clk_enable(struct device *dev);
155159
void mtk_mdp_rdma_clk_disable(struct device *dev);
156160
void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt);

drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ static const struct mtk_ddp_comp_funcs merge = {
8080
};
8181

8282
static const struct mtk_ddp_comp_funcs rdma = {
83+
.power_on = mtk_mdp_rdma_power_on,
84+
.power_off = mtk_mdp_rdma_power_off,
8385
.clk_enable = mtk_mdp_rdma_clk_enable,
8486
.clk_disable = mtk_mdp_rdma_clk_disable,
8587
};
@@ -201,21 +203,72 @@ void mtk_ovl_adaptor_stop(struct device *dev)
201203
mtk_ethdr_stop(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
202204
}
203205

204-
int mtk_ovl_adaptor_clk_enable(struct device *dev)
206+
/**
207+
* power_off - Power off the devices in OVL adaptor
208+
* @dev: Device to be powered off
209+
* @num: Number of the devices to be powered off
210+
*
211+
* Calls the .power_off() ovl_adaptor component callback if it is present.
212+
*/
213+
static inline void power_off(struct device *dev, int num)
205214
{
206215
struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
207-
struct device *comp;
208-
int ret;
209216
int i;
210217

211-
for (i = 0; i < OVL_ADAPTOR_MERGE0; i++) {
212-
comp = ovl_adaptor->ovl_adaptor_comp[i];
213-
ret = pm_runtime_get_sync(comp);
218+
if (num > OVL_ADAPTOR_ID_MAX)
219+
num = OVL_ADAPTOR_ID_MAX;
220+
221+
for (i = num - 1; i >= 0; i--) {
222+
if (!ovl_adaptor->ovl_adaptor_comp[i] ||
223+
!comp_matches[i].funcs->power_off)
224+
continue;
225+
226+
comp_matches[i].funcs->power_off(ovl_adaptor->ovl_adaptor_comp[i]);
227+
}
228+
}
229+
230+
/**
231+
* mtk_ovl_adaptor_power_on - Power on the devices in OVL adaptor
232+
* @dev: Device to be powered on
233+
*
234+
* Different from OVL, OVL adaptor is a pseudo device so
235+
* we didn't define it in the device tree, pm_runtime_resume_and_get()
236+
* called by .atomic_enable() power on no device in OVL adaptor,
237+
* we have to implement a function to do the job instead.
238+
*
239+
* Return: Zero for success or negative number for failure.
240+
*/
241+
int mtk_ovl_adaptor_power_on(struct device *dev)
242+
{
243+
struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
244+
int i, ret;
245+
246+
for (i = 0; i < OVL_ADAPTOR_ID_MAX; i++) {
247+
if (!ovl_adaptor->ovl_adaptor_comp[i] ||
248+
!comp_matches[i].funcs->power_on)
249+
continue;
250+
251+
ret = comp_matches[i].funcs->power_on(ovl_adaptor->ovl_adaptor_comp[i]);
214252
if (ret < 0) {
215253
dev_err(dev, "Failed to enable power domain %d, err %d\n", i, ret);
216-
goto error;
254+
power_off(dev, i);
255+
return ret;
217256
}
218257
}
258+
return 0;
259+
}
260+
261+
void mtk_ovl_adaptor_power_off(struct device *dev)
262+
{
263+
power_off(dev, OVL_ADAPTOR_ID_MAX);
264+
}
265+
266+
int mtk_ovl_adaptor_clk_enable(struct device *dev)
267+
{
268+
struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
269+
struct device *comp;
270+
int ret;
271+
int i;
219272

220273
for (i = 0; i < OVL_ADAPTOR_ID_MAX; i++) {
221274
comp = ovl_adaptor->ovl_adaptor_comp[i];
@@ -226,16 +279,10 @@ int mtk_ovl_adaptor_clk_enable(struct device *dev)
226279
dev_err(dev, "Failed to enable clock %d, err %d\n", i, ret);
227280
while (--i >= 0)
228281
comp_matches[i].funcs->clk_disable(comp);
229-
i = OVL_ADAPTOR_MERGE0;
230-
goto error;
282+
return ret;
231283
}
232284
}
233285
return 0;
234-
error:
235-
while (--i >= 0)
236-
pm_runtime_put(ovl_adaptor->ovl_adaptor_comp[i]);
237-
238-
return ret;
239286
}
240287

241288
void mtk_ovl_adaptor_clk_disable(struct device *dev)

drivers/gpu/drm/mediatek/mtk_drm_crtc.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,7 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
721721

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

724-
ret = pm_runtime_resume_and_get(comp->dev);
724+
ret = mtk_ddp_comp_power_on(comp);
725725
if (ret < 0) {
726726
DRM_DEV_ERROR(comp->dev, "Failed to enable power domain: %d\n", ret);
727727
return;
@@ -731,7 +731,7 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
731731

732732
ret = mtk_crtc_ddp_hw_init(mtk_crtc);
733733
if (ret) {
734-
pm_runtime_put(comp->dev);
734+
mtk_ddp_comp_power_off(comp);
735735
return;
736736
}
737737

@@ -744,7 +744,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
744744
{
745745
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
746746
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
747-
int i, ret;
747+
int i;
748748

749749
DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
750750
if (!mtk_crtc->enabled)
@@ -774,9 +774,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
774774

775775
drm_crtc_vblank_off(crtc);
776776
mtk_crtc_ddp_hw_fini(mtk_crtc);
777-
ret = pm_runtime_put(comp->dev);
778-
if (ret < 0)
779-
DRM_DEV_ERROR(comp->dev, "Failed to disable power domain: %d\n", ret);
777+
mtk_ddp_comp_power_off(comp);
780778

781779
mtk_crtc->enabled = false;
782780
}

drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe = {
398398
};
399399

400400
static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
401+
.power_on = mtk_ovl_adaptor_power_on,
402+
.power_off = mtk_ovl_adaptor_power_off,
401403
.clk_enable = mtk_ovl_adaptor_clk_enable,
402404
.clk_disable = mtk_ovl_adaptor_clk_disable,
403405
.config = mtk_ovl_adaptor_config,

drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define MTK_DRM_DDP_COMP_H
88

99
#include <linux/io.h>
10+
#include <linux/pm_runtime.h>
1011
#include <linux/soc/mediatek/mtk-cmdq.h>
1112
#include <linux/soc/mediatek/mtk-mmsys.h>
1213
#include <linux/soc/mediatek/mtk-mutex.h>
@@ -46,6 +47,8 @@ enum mtk_ddp_comp_type {
4647
struct mtk_ddp_comp;
4748
struct cmdq_pkt;
4849
struct mtk_ddp_comp_funcs {
50+
int (*power_on)(struct device *dev);
51+
void (*power_off)(struct device *dev);
4952
int (*clk_enable)(struct device *dev);
5053
void (*clk_disable)(struct device *dev);
5154
void (*config)(struct device *dev, unsigned int w,
@@ -92,6 +95,23 @@ struct mtk_ddp_comp {
9295
const struct mtk_ddp_comp_funcs *funcs;
9396
};
9497

98+
static inline int mtk_ddp_comp_power_on(struct mtk_ddp_comp *comp)
99+
{
100+
if (comp->funcs && comp->funcs->power_on)
101+
return comp->funcs->power_on(comp->dev);
102+
else
103+
return pm_runtime_resume_and_get(comp->dev);
104+
return 0;
105+
}
106+
107+
static inline void mtk_ddp_comp_power_off(struct mtk_ddp_comp *comp)
108+
{
109+
if (comp->funcs && comp->funcs->power_off)
110+
comp->funcs->power_off(comp->dev);
111+
else
112+
pm_runtime_put(comp->dev);
113+
}
114+
95115
static inline int mtk_ddp_comp_clk_enable(struct mtk_ddp_comp *comp)
96116
{
97117
if (comp->funcs && comp->funcs->clk_enable)

drivers/gpu/drm/mediatek/mtk_mdp_rdma.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,22 @@ size_t mtk_mdp_rdma_get_num_formats(struct device *dev)
242242
return ARRAY_SIZE(formats);
243243
}
244244

245+
int mtk_mdp_rdma_power_on(struct device *dev)
246+
{
247+
int ret = pm_runtime_resume_and_get(dev);
248+
249+
if (ret < 0) {
250+
dev_err(dev, "Failed to power on: %d\n", ret);
251+
return ret;
252+
}
253+
return 0;
254+
}
255+
256+
void mtk_mdp_rdma_power_off(struct device *dev)
257+
{
258+
pm_runtime_put(dev);
259+
}
260+
245261
int mtk_mdp_rdma_clk_enable(struct device *dev)
246262
{
247263
struct mtk_mdp_rdma *rdma = dev_get_drvdata(dev);

0 commit comments

Comments
 (0)