From 6e0eb52eba9e2c8d56e4e6826faa2bd6fd5dcf0c Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 9 Oct 2015 15:21:12 +0530 Subject: [PATCH] drm/msm/dsi: Parse bus clocks from a list DSI bus clocks seem to vary between different DSI host versions, and the SOC to which they belong. Even the enable/disable sequence varies. Provide a list of bus clock names in dsi_cfg. The driver will use this to retrieve the clocks, and enable/disable them. Add bus clock lists for DSI6G, and DSI for MSM8916(this is DSI6G too, but there is no MMSS_CC specific clock since there is no MMSS clock controller on 8916). Signed-off-by: Archit Taneja Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/dsi/dsi.h | 1 + drivers/gpu/drm/msm/dsi/dsi_cfg.c | 16 ++++- drivers/gpu/drm/msm/dsi/dsi_cfg.h | 2 + drivers/gpu/drm/msm/dsi/dsi_host.c | 107 ++++++++++------------------- 4 files changed, 53 insertions(+), 73 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index 8140e8b820e4..7336b55d05cc 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -36,6 +36,7 @@ enum msm_dsi_phy_type { }; #define DSI_DEV_REGULATOR_MAX 8 +#define DSI_BUS_CLK_MAX 4 /* Regulators for DSI devices */ struct dsi_reg_entry { diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c index 5872d5e5934f..c40044f8a6c0 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c @@ -18,6 +18,10 @@ static const struct msm_dsi_config dsi_v2_cfg = { .io_offset = 0, }; +static const char * const dsi_6g_bus_clk_names[] = { + "mdp_core_clk", "iface_clk", "bus_clk", "core_mmss_clk", +}; + static const struct msm_dsi_config msm8974_apq8084_dsi_cfg = { .io_offset = DSI_6G_REG_SHIFT, .reg_cfg = { @@ -29,6 +33,12 @@ static const struct msm_dsi_config msm8974_apq8084_dsi_cfg = { {"vddio", 1800000, 1800000, 100000, 100}, }, }, + .bus_clk_names = dsi_6g_bus_clk_names, + .num_bus_clks = ARRAY_SIZE(dsi_6g_bus_clk_names), +}; + +static const char * const dsi_8916_bus_clk_names[] = { + "mdp_core_clk", "iface_clk", "bus_clk", }; static const struct msm_dsi_config msm8916_dsi_cfg = { @@ -42,6 +52,8 @@ static const struct msm_dsi_config msm8916_dsi_cfg = { {"vddio", 1800000, 1800000, 100000, 100}, }, }, + .bus_clk_names = dsi_8916_bus_clk_names, + .num_bus_clks = ARRAY_SIZE(dsi_8916_bus_clk_names), }; static const struct msm_dsi_config msm8994_dsi_cfg = { @@ -57,7 +69,9 @@ static const struct msm_dsi_config msm8994_dsi_cfg = { {"lab_reg", -1, -1, -1, -1}, {"ibb_reg", -1, -1, -1, -1}, }, - } + }, + .bus_clk_names = dsi_6g_bus_clk_names, + .num_bus_clks = ARRAY_SIZE(dsi_6g_bus_clk_names), }; static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = { diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.h b/drivers/gpu/drm/msm/dsi/dsi_cfg.h index 4cf887240177..5a36836dd6fc 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.h +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.h @@ -30,6 +30,8 @@ struct msm_dsi_config { u32 io_offset; struct dsi_reg_config reg_cfg; + const char * const *bus_clk_names; + const int num_bus_clks; }; struct msm_dsi_cfg_handler { diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index f78702472819..56c75354fe03 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -103,10 +103,9 @@ struct msm_dsi_host { void __iomem *ctrl_base; struct regulator_bulk_data supplies[DSI_DEV_REGULATOR_MAX]; - struct clk *mdp_core_clk; - struct clk *ahb_clk; - struct clk *axi_clk; - struct clk *mmss_misc_ahb_clk; + + struct clk *bus_clks[DSI_BUS_CLK_MAX]; + struct clk *byte_clk; struct clk *esc_clk; struct clk *pixel_clk; @@ -319,40 +318,22 @@ static int dsi_regulator_init(struct msm_dsi_host *msm_host) static int dsi_clk_init(struct msm_dsi_host *msm_host) { struct device *dev = &msm_host->pdev->dev; - int ret = 0; - - msm_host->mdp_core_clk = devm_clk_get(dev, "mdp_core_clk"); - if (IS_ERR(msm_host->mdp_core_clk)) { - ret = PTR_ERR(msm_host->mdp_core_clk); - pr_err("%s: Unable to get mdp core clk. ret=%d\n", - __func__, ret); - goto exit; - } - - msm_host->ahb_clk = devm_clk_get(dev, "iface_clk"); - if (IS_ERR(msm_host->ahb_clk)) { - ret = PTR_ERR(msm_host->ahb_clk); - pr_err("%s: Unable to get mdss ahb clk. ret=%d\n", - __func__, ret); - goto exit; - } - - msm_host->axi_clk = devm_clk_get(dev, "bus_clk"); - if (IS_ERR(msm_host->axi_clk)) { - ret = PTR_ERR(msm_host->axi_clk); - pr_err("%s: Unable to get axi bus clk. ret=%d\n", - __func__, ret); - goto exit; - } - - msm_host->mmss_misc_ahb_clk = devm_clk_get(dev, "core_mmss_clk"); - if (IS_ERR(msm_host->mmss_misc_ahb_clk)) { - ret = PTR_ERR(msm_host->mmss_misc_ahb_clk); - pr_err("%s: Unable to get mmss misc ahb clk. ret=%d\n", - __func__, ret); - goto exit; + const struct msm_dsi_config *cfg = msm_host->cfg_hnd->cfg; + int i, ret = 0; + + /* get bus clocks */ + for (i = 0; i < cfg->num_bus_clks; i++) { + msm_host->bus_clks[i] = devm_clk_get(dev, + cfg->bus_clk_names[i]); + if (IS_ERR(msm_host->bus_clks[i])) { + ret = PTR_ERR(msm_host->bus_clks[i]); + pr_err("%s: Unable to get %s, ret = %d\n", + __func__, cfg->bus_clk_names[i], ret); + goto exit; + } } + /* get link and source clocks */ msm_host->byte_clk = devm_clk_get(dev, "byte_clk"); if (IS_ERR(msm_host->byte_clk)) { ret = PTR_ERR(msm_host->byte_clk); @@ -399,55 +380,37 @@ exit: static int dsi_bus_clk_enable(struct msm_dsi_host *msm_host) { - int ret; + const struct msm_dsi_config *cfg = msm_host->cfg_hnd->cfg; + int i, ret; DBG("id=%d", msm_host->id); - ret = clk_prepare_enable(msm_host->mdp_core_clk); - if (ret) { - pr_err("%s: failed to enable mdp_core_clock, %d\n", - __func__, ret); - goto core_clk_err; - } - - ret = clk_prepare_enable(msm_host->ahb_clk); - if (ret) { - pr_err("%s: failed to enable ahb clock, %d\n", __func__, ret); - goto ahb_clk_err; - } - - ret = clk_prepare_enable(msm_host->axi_clk); - if (ret) { - pr_err("%s: failed to enable ahb clock, %d\n", __func__, ret); - goto axi_clk_err; - } - - ret = clk_prepare_enable(msm_host->mmss_misc_ahb_clk); - if (ret) { - pr_err("%s: failed to enable mmss misc ahb clk, %d\n", - __func__, ret); - goto misc_ahb_clk_err; + for (i = 0; i < cfg->num_bus_clks; i++) { + ret = clk_prepare_enable(msm_host->bus_clks[i]); + if (ret) { + pr_err("%s: failed to enable bus clock %d ret %d\n", + __func__, i, ret); + goto err; + } } return 0; +err: + for (; i > 0; i--) + clk_disable_unprepare(msm_host->bus_clks[i]); -misc_ahb_clk_err: - clk_disable_unprepare(msm_host->axi_clk); -axi_clk_err: - clk_disable_unprepare(msm_host->ahb_clk); -ahb_clk_err: - clk_disable_unprepare(msm_host->mdp_core_clk); -core_clk_err: return ret; } static void dsi_bus_clk_disable(struct msm_dsi_host *msm_host) { + const struct msm_dsi_config *cfg = msm_host->cfg_hnd->cfg; + int i; + DBG(""); - clk_disable_unprepare(msm_host->mmss_misc_ahb_clk); - clk_disable_unprepare(msm_host->axi_clk); - clk_disable_unprepare(msm_host->ahb_clk); - clk_disable_unprepare(msm_host->mdp_core_clk); + + for (i = cfg->num_bus_clks - 1; i >= 0; i--) + clk_disable_unprepare(msm_host->bus_clks[i]); } static int dsi_link_clk_enable(struct msm_dsi_host *msm_host) -- 2.20.1