drm/rockchip: dsi: dynamically manage the clock in runtime pm

Signed-off-by: Guochun Huang <hero.huang@rock-chips.com>
Change-Id: Idad08904c393f30b4bcc405edac09237696f5cf6
This commit is contained in:
Guochun Huang
2021-08-30 19:51:46 +08:00
committed by Tao Huang
parent d226c884fd
commit f5d16f932b
+24 -30
View File
@@ -241,6 +241,7 @@ struct dw_mipi_dsi_rockchip {
struct regmap *grf_regmap;
struct clk *pllref_clk;
struct clk *pclk;
struct clk *grf_clk;
struct clk *phy_cfg_clk;
struct clk *hclk;
@@ -390,7 +391,7 @@ static inline unsigned int ns2ui(struct dw_mipi_dsi_rockchip *dsi, int ns)
static int dw_mipi_dsi_phy_init(void *priv_data)
{
struct dw_mipi_dsi_rockchip *dsi = priv_data;
int ret, i, vco;
int i, vco;
if (dsi->phy)
return 0;
@@ -417,12 +418,6 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
return i;
}
ret = clk_prepare_enable(dsi->phy_cfg_clk);
if (ret) {
DRM_DEV_ERROR(dsi->dev, "Failed to enable phy_cfg_clk\n");
return ret;
}
dw_mipi_dsi_phy_write(dsi, PLL_BIAS_CUR_SEL_CAP_VCO_CONTROL,
BYPASS_VCO_RANGE |
VCO_RANGE_CON_SEL(vco) |
@@ -498,9 +493,7 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
dw_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_EXIT_STATE_TIME_CONTROL,
BIT(5) | ns2bc(dsi, 100));
clk_disable_unprepare(dsi->phy_cfg_clk);
return ret;
return 0;
}
static void dw_mipi_dsi_phy_power_on(void *priv_data)
@@ -822,7 +815,7 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
{
struct dw_mipi_dsi_rockchip *dsi = to_dsi(encoder);
int ret, mux;
int mux;
mux = drm_of_encoder_active_endpoint_id(dsi->dev->of_node,
&dsi->encoder);
@@ -833,22 +826,9 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
if (dsi->slave)
pm_runtime_get_sync(dsi->slave->dev);
/*
* For the RK3399, the clk of grf must be enabled before writing grf
* register. And for RK3288 or other soc, this grf_clk must be NULL,
* the clk_prepare_enable return true directly.
*/
ret = clk_prepare_enable(dsi->grf_clk);
if (ret) {
DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret);
return;
}
dw_mipi_dsi_rockchip_config(dsi, mux);
if (dsi->slave)
dw_mipi_dsi_rockchip_config(dsi->slave, mux);
clk_disable_unprepare(dsi->grf_clk);
}
static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)
@@ -862,19 +842,18 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)
static void dw_mipi_dsi_rockchip_loader_protect(struct dw_mipi_dsi_rockchip *dsi, bool on)
{
dw_mipi_dsi_loader_protect(dsi->dmd, on);
if (on) {
pm_runtime_get_sync(dsi->dev);
phy_init(dsi->phy);
dsi->phy->power_count++;
dsi->phy_enabled = true;
if (dsi->phy)
dsi->phy->power_count++;
} else {
pm_runtime_put(dsi->dev);
phy_exit(dsi->phy);
dsi->phy->power_count--;
dsi->phy_enabled = false;
if (dsi->phy)
dsi->phy->power_count--;
}
if (dsi->slave)
@@ -1123,6 +1102,13 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
return ret;
}
dsi->pclk = devm_clk_get(dev, "pclk");
if (IS_ERR(dsi->pclk)) {
ret = PTR_ERR(dsi->pclk);
dev_err(dev, "Unable to get pclk: %d\n", ret);
return ret;
}
dsi->pllref_clk = devm_clk_get(dev, "ref");
if (IS_ERR(dsi->pllref_clk)) {
if (dsi->phy) {
@@ -1214,7 +1200,10 @@ static __maybe_unused int dw_mipi_dsi_runtime_suspend(struct device *dev)
{
struct dw_mipi_dsi_rockchip *dsi = dev_get_drvdata(dev);
clk_disable_unprepare(dsi->grf_clk);
clk_disable_unprepare(dsi->pclk);
clk_disable_unprepare(dsi->hclk);
clk_disable_unprepare(dsi->phy_cfg_clk);
return 0;
}
@@ -1223,7 +1212,12 @@ static __maybe_unused int dw_mipi_dsi_runtime_resume(struct device *dev)
{
struct dw_mipi_dsi_rockchip *dsi = dev_get_drvdata(dev);
return clk_prepare_enable(dsi->hclk);
clk_prepare_enable(dsi->phy_cfg_clk);
clk_prepare_enable(dsi->hclk);
clk_prepare_enable(dsi->pclk);
clk_prepare_enable(dsi->grf_clk);
return 0;
}
static const struct dev_pm_ops dw_mipi_dsi_rockchip_pm_ops = {