162 lines
4.2 KiB
Diff
162 lines
4.2 KiB
Diff
From ba976d4a1d2bcad899b8d72ae1675a3c1f652e4a Mon Sep 17 00:00:00 2001
|
|
From: fanglifei <fanglifei@eswincomputing.com>
|
|
Date: Tue, 16 Jul 2024 17:43:26 +0800
|
|
Subject: [PATCH 101/219] feat(vo): OSD Support power management
|
|
|
|
Changelogs:
|
|
1. Add generic power management for vo.
|
|
2. Drm help functions are managed to do display suspend or
|
|
resume, so only clk prepare and unprepare were needed in
|
|
enable or disable funcs.
|
|
3. MIPI dsi clk prepare and unprepare were already added in
|
|
enable and disable callback funcs of drm encoder, which
|
|
will be called when PM suspend and resume. So no need to
|
|
add independant pm callback for dsi.
|
|
|
|
Signed-off-by: fanglifei <fanglifei@eswincomputing.com>
|
|
---
|
|
drivers/gpu/drm/eswin/es_dc.c | 77 ++++++++++++++++++++++-------------
|
|
drivers/gpu/drm/eswin/es_dc.h | 1 +
|
|
2 files changed, 50 insertions(+), 28 deletions(-)
|
|
|
|
diff --git a/drivers/gpu/drm/eswin/es_dc.c b/drivers/gpu/drm/eswin/es_dc.c
|
|
index 3ae03d20b600..4d5eaec87f5d 100644
|
|
--- a/drivers/gpu/drm/eswin/es_dc.c
|
|
+++ b/drivers/gpu/drm/eswin/es_dc.c
|
|
@@ -218,15 +218,56 @@ static inline u8 to_es_tile_mode(u64 modifier)
|
|
return (u8)(modifier & 0x1F);
|
|
}
|
|
|
|
+static int es_dc_clk_configs(struct device *dev, bool enable)
|
|
+{
|
|
+ int ret = 0;
|
|
+ struct es_dc *dc = dev_get_drvdata(dev);
|
|
+
|
|
+ if (enable) {
|
|
+ if (dc->dc_clkon) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ ret = clk_prepare_enable(dc->cfg_clk);
|
|
+ if (ret < 0) {
|
|
+ dev_err(dev, "failed to prepare/enable cfg_clk\n");
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ ret = clk_prepare_enable(dc->pix_clk);
|
|
+ if (ret < 0) {
|
|
+ dev_err(dev, "failed to prepare/enable pix_clk\n");
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ ret = clk_prepare_enable(dc->axi_clk);
|
|
+ if (ret < 0) {
|
|
+ dev_err(dev, "failed to prepare/enable axi_clk\n");
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ dc->pix_clk_rate = clk_get_rate(dc->pix_clk);
|
|
+ dc->dc_clkon = true;
|
|
+ } else {
|
|
+ if (!dc->dc_clkon) {
|
|
+ return 0;
|
|
+ }
|
|
+ clk_disable_unprepare(dc->pix_clk);
|
|
+ clk_disable_unprepare(dc->axi_clk);
|
|
+ clk_disable_unprepare(dc->cfg_clk);
|
|
+ dc->dc_clkon = false;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static void dc_deinit(struct device *dev)
|
|
{
|
|
struct es_dc *dc = dev_get_drvdata(dev);
|
|
|
|
dc_hw_enable_interrupt(&dc->hw, 0);
|
|
dc_hw_deinit(&dc->hw);
|
|
- clk_disable_unprepare(dc->cfg_clk);
|
|
- clk_disable_unprepare(dc->pix_clk);
|
|
- clk_disable_unprepare(dc->axi_clk);
|
|
+ es_dc_clk_configs(dev, false);
|
|
}
|
|
|
|
static int dc_init(struct device *dev)
|
|
@@ -252,41 +293,19 @@ static int dc_init(struct device *dev)
|
|
}
|
|
}
|
|
|
|
- ret = clk_prepare_enable(dc->cfg_clk);
|
|
+ ret = es_dc_clk_configs(dev, true);
|
|
if (ret < 0) {
|
|
- dev_err(dev, "failed to prepare/enable cfg_clk\n");
|
|
+ dev_err(dev, "failed to prepare/enable clks\n");
|
|
return ret;
|
|
}
|
|
|
|
- ret = clk_prepare_enable(dc->pix_clk);
|
|
- if (ret < 0) {
|
|
- dev_err(dev, "failed to prepare/enable pix_clk\n");
|
|
- goto err_unprepare_cfg_clk;
|
|
- }
|
|
-
|
|
- ret = clk_prepare_enable(dc->axi_clk);
|
|
- if (ret < 0) {
|
|
- dev_err(dev, "failed to prepare/enable axi_clk\n");
|
|
- goto err_unprepare_pix_clk;
|
|
- }
|
|
-
|
|
- dc->pix_clk_rate = clk_get_rate(dc->pix_clk);
|
|
-
|
|
ret = dc_hw_init(&dc->hw);
|
|
if (ret) {
|
|
dev_err(dev, "failed to init DC HW\n");
|
|
- goto err_unprepare_axi_clk;
|
|
+ return ret;
|
|
}
|
|
|
|
return 0;
|
|
-
|
|
-err_unprepare_axi_clk:
|
|
- clk_disable_unprepare(dc->axi_clk);
|
|
-err_unprepare_cfg_clk:
|
|
- clk_disable_unprepare(dc->cfg_clk);
|
|
-err_unprepare_pix_clk:
|
|
- clk_disable_unprepare(dc->pix_clk);
|
|
- return ret;
|
|
}
|
|
|
|
static void es_dc_dump_enable(struct device *dev, dma_addr_t addr,
|
|
@@ -335,6 +354,7 @@ static void es_dc_enable(struct device *dev, struct drm_crtc *crtc)
|
|
display.dither_enable = crtc_state->dither_enable;
|
|
|
|
display.enable = true;
|
|
+ es_dc_clk_configs(dev, true);
|
|
|
|
if (dc->pix_clk_rate != mode->clock) {
|
|
clk_set_rate(dc->pix_clk, mode->clock * 1000);
|
|
@@ -366,6 +386,7 @@ static void es_dc_disable(struct device *dev)
|
|
display.enable = false;
|
|
|
|
dc_hw_setup_display(&dc->hw, &display);
|
|
+ es_dc_clk_configs(dev, false);
|
|
}
|
|
|
|
static bool es_dc_mode_fixup(struct device *dev,
|
|
diff --git a/drivers/gpu/drm/eswin/es_dc.h b/drivers/gpu/drm/eswin/es_dc.h
|
|
index 3a20987aa799..8dbc3b4d7eb2 100644
|
|
--- a/drivers/gpu/drm/eswin/es_dc.h
|
|
+++ b/drivers/gpu/drm/eswin/es_dc.h
|
|
@@ -40,6 +40,7 @@ struct es_dc {
|
|
|
|
bool first_frame;
|
|
bool dc_initialized;
|
|
+ bool dc_clkon;
|
|
|
|
const struct es_dc_funcs *funcs;
|
|
};
|
|
--
|
|
2.47.0
|
|
|