summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDhaval Patel <pdhaval@codeaurora.org>2015-02-15 13:39:00 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:38:02 -0700
commit9382fb049fa58e4aab1da95767c64450cd8a56ef (patch)
treec4dc426d0bab13543aa0984d81930c82653fa7d9
parent35589945c50c7aa8ce7a43d6910afd2fd51de7d4 (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.txt2
-rw-r--r--drivers/video/fbdev/msm/mdss_smmu.c108
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);