diff options
| -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); |
