diff options
| author | Dhaval Patel <pdhaval@codeaurora.org> | 2015-02-15 13:39:00 -0800 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:38:02 -0700 |
| commit | 9382fb049fa58e4aab1da95767c64450cd8a56ef (patch) | |
| tree | c4dc426d0bab13543aa0984d81930c82653fa7d9 | |
| parent | 35589945c50c7aa8ce7a43d6910afd2fd51de7d4 (diff) | |
msm: mdss: enable mmagic gdsc before calling SMMUv2 APIs
SMMUv2 clients needs to enable the mmagic gdsc before
creating mapping or attaching context bank. It can disable
the GDSC when context banks are detached. Display module
enables mmagic gdsc before creating secure & unsecure
context bank mapping for MDP and rotation clients during
probe. This GDSC is also turned on and off when clients
tries to attach context banks and detach respectively.
Change-Id: Iee3c93d440388693d83cc57ca001408d95c9654b
Signed-off-by: Dhaval Patel <pdhaval@codeaurora.org>
| -rw-r--r-- | Documentation/devicetree/bindings/fb/mdss-mdp.txt | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_smmu.c | 108 |
2 files changed, 89 insertions, 21 deletions
diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt index 19549d1cb0bd..009c6a6ea2bb 100644 --- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt +++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt @@ -511,6 +511,7 @@ Subnode properties: secure mdp domain. "qcom,smmu_rot_sec" - smmu context bank device for secure rotation domain. +- gdsc-mmagic-mdss-supply: Phandle for mmagic mdss supply regulator device node. - clocks: List of Phandles for clock device nodes needed by the device. - clock-names: List of clock names needed by the device. @@ -674,6 +675,7 @@ Example: smmu_mdp_sec: qcom,smmu_mdp_sec_cb { compatible = "qcom,smmu_mdp_sec"; iommus = <&mdp_smmu 1>; + gdsc-mmagic-mdss-supply = <&gdsc_mmagic_mdss>; clocks = <&clock_mmss clk_smmu_mdp_ahb_clk>, <&clock_mmss clk_smmu_mdp_axi_clk>; clock-names = "dummy_clk", "dummy_clk"; diff --git a/drivers/video/fbdev/msm/mdss_smmu.c b/drivers/video/fbdev/msm/mdss_smmu.c index 0d3e31489127..0dbf2091aad5 100644 --- a/drivers/video/fbdev/msm/mdss_smmu.c +++ b/drivers/video/fbdev/msm/mdss_smmu.c @@ -168,6 +168,35 @@ end: return rc; } +static int mdss_smmu_enable_power(struct dss_module_power *mp, bool enable) +{ + int rc = 0; + + if (!mp) + return -EINVAL; + + if (enable) { + rc = msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, true); + if (rc) { + pr_err("vreg enable failed - rc:%d\n", rc); + goto end; + } + + rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true); + if (rc) { + pr_err("clock enable failed - rc:%d\n", rc); + msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, + false); + goto end; + } + } else { + msm_dss_enable_clk(mp->clk_config, mp->num_clk, false); + msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, false); + } +end: + return rc; +} + /* * mdss_smmu_v2_attach() * @@ -181,6 +210,7 @@ static int mdss_smmu_attach_v2(struct mdss_data_type *mdata) struct mdss_smmu_client *mdss_smmu; int i, rc = 0; int disable_htw = 1; + struct dss_module_power *mp; for (i = 0; i < MDSS_IOMMU_MAX_DOMAIN; i++) { if (!mdss_smmu_is_valid_domain_type(mdata, i)) @@ -188,11 +218,11 @@ static int mdss_smmu_attach_v2(struct mdss_data_type *mdata) mdss_smmu = mdss_smmu_get_cb(i); if (mdss_smmu->dev) { - rc = msm_dss_enable_clk(mdss_smmu->mp.clk_config, - mdss_smmu->mp.num_clk, 1); + mp = &mdss_smmu->mp; + rc = mdss_smmu_enable_power(mp, true); if (rc) { - pr_err("clock enable failed - domain:[%i] rc:%d\n", - i, rc); + pr_err("power enable failed - domain:[%d] rc:%d\n", + i, rc); goto err; } @@ -202,9 +232,7 @@ static int mdss_smmu_attach_v2(struct mdss_data_type *mdata) if (rc) { pr_err("iommu attach device failed for domain[%d] with err:%d\n", i, rc); - msm_dss_enable_clk( - mdss_smmu->mp.clk_config, - mdss_smmu->mp.num_clk, 0); + mdss_smmu_enable_power(mp, false); goto err; } if (iommu_domain_set_attr( @@ -214,9 +242,7 @@ static int mdss_smmu_attach_v2(struct mdss_data_type *mdata) pr_err("couldn't disable coherent HTW\n"); arm_iommu_detach_device(mdss_smmu->dev); - msm_dss_enable_clk( - mdss_smmu->mp.clk_config, - mdss_smmu->mp.num_clk, 0); + mdss_smmu_enable_power(mp, false); goto err; } mdss_smmu->domain_attached = true; @@ -233,9 +259,9 @@ err: for (i--; i >= 0; i--) { mdss_smmu = mdss_smmu_get_cb(i); if (mdss_smmu->dev) { + mp = &mdss_smmu->mp; arm_iommu_detach_device(mdss_smmu->dev); - msm_dss_enable_clk(mdss_smmu->mp.clk_config, - mdss_smmu->mp.num_clk, 0); + mdss_smmu_enable_power(mp, false); mdss_smmu->domain_attached = false; } } @@ -281,6 +307,7 @@ static int mdss_smmu_detach_v2(struct mdss_data_type *mdata) { struct mdss_smmu_client *mdss_smmu; int i; + struct dss_module_power *mp; for (i = 0; i < MDSS_IOMMU_MAX_DOMAIN; i++) { if (!mdss_smmu_is_valid_domain_type(mdata, i)) @@ -288,8 +315,8 @@ static int mdss_smmu_detach_v2(struct mdss_data_type *mdata) mdss_smmu = mdss_smmu_get_cb(i); if (mdss_smmu->dev) { - msm_dss_enable_clk(mdss_smmu->mp.clk_config, - mdss_smmu->mp.num_clk, 0); + mp = &mdss_smmu->mp; + mdss_smmu_enable_power(mp, false); } } return 0; @@ -843,6 +870,7 @@ int mdss_smmu_probe(struct platform_device *pdev) u32 domain; size_t va_start, va_size; const struct of_device_id *match; + struct dss_module_power *mp; if (!mdata) { pr_err("probe failed as mdata is not initialized\n"); @@ -876,20 +904,58 @@ int mdss_smmu_probe(struct platform_device *pdev) return -EINVAL; } + mp = &mdss_smmu->mp; + + mp->vreg_config = devm_kzalloc(&pdev->dev, + sizeof(struct dss_vreg), GFP_KERNEL); + if (!mp->vreg_config) { + pr_err("can't alloc vreg mem\n"); + return -ENOMEM; + } + + strlcpy(mp->vreg_config->vreg_name, "gdsc-mmagic-mdss", + sizeof(mp->vreg_config->vreg_name)); + + mp->num_vreg = 1; + + rc = msm_dss_config_vreg(&pdev->dev, mp->vreg_config, + mp->num_vreg, true); + if (rc) { + pr_err("vreg config failed rc=%d\n", rc); + return rc; + } + + rc = mdss_smmu_clk_register(pdev, mp); + if (rc) { + pr_err("smmu clk register failed for domain[%d] with err:%d\n", + domain, rc); + msm_dss_config_vreg(&pdev->dev, mp->vreg_config, mp->num_vreg, + false); + return rc; + } + + rc = mdss_smmu_enable_power(mp, true); + if (rc) { + pr_err("power enable failed - domain:[%d] rc:%d\n", domain, rc); + msm_dss_config_vreg(&pdev->dev, mp->vreg_config, mp->num_vreg, + false); + return rc; + } + mdss_smmu->mmu_mapping = arm_iommu_create_mapping( &platform_bus_type, va_start, va_size, order); if (IS_ERR(mdss_smmu->mmu_mapping)) { pr_err("iommu create mapping failed for domain[%d]\n", domain); + + mdss_smmu_enable_power(mp, false); + msm_dss_config_vreg(&pdev->dev, mp->vreg_config, mp->num_vreg, + false); + return PTR_ERR(mdss_smmu->mmu_mapping); } - rc = mdss_smmu_clk_register(pdev, &mdss_smmu->mp); - if (rc) { - pr_err("smmu clk register failed for domain[%d] with err:%d\n", - domain, rc); - arm_iommu_release_mapping(mdss_smmu->mmu_mapping); - return rc; - } + mdss_smmu_enable_power(mp, false); + mdss_smmu->dev = dev; pr_info("iommu v2 domain[%d] mapping and clk register successful!\n", domain); |
