diff --git a/Documentation/devicetree/bindings/drm/msm/mdp.txt b/Documentation/devicetree/bindings/drm/msm/mdp.txt
index 0833eda..99ba764 100644
--- a/Documentation/devicetree/bindings/drm/msm/mdp.txt
+++ b/Documentation/devicetree/bindings/drm/msm/mdp.txt
@@ -19,6 +19,9 @@ Optional properties:
 - gpus: phandle for gpu device
 - clock-names: the following clocks are optional:
   * "lut_clk"
+  * "iommu_clk"
+  * "mmagic_clk"
+- mmagic-supply: phandle for mmagic GDSC regulator used during IOMMU translation
 
 Example:
 
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 61fcb41..983bd53 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -129,6 +129,54 @@ static void mdp5_preclose(struct msm_kms *kms, struct drm_file *file)
 		mdp5_crtc_cancel_pending_flip(priv->crtcs[i], file);
 }
 
+static int mdp5_translation_ctrl_pwr(struct mdp5_kms *mdp5_kms, bool on)
+{
+	struct device *dev = mdp5_kms->dev->dev;
+	int ret;
+
+	if (on) {
+		if (mdp5_kms->mmagic) {
+			ret = regulator_enable(mdp5_kms->mmagic);
+			if (ret) {
+				dev_err(dev, "failed to enable mmagic GDSC: %d\n", ret);
+				return ret;
+			}
+		}
+		if (mdp5_kms->mmagic_clk) {
+			clk_prepare_enable(mdp5_kms->mmagic_clk);
+			if (ret) {
+				dev_err(dev, "failed to enable mmagic_clk\n");
+				goto undo_gdsc;
+			}
+		}
+		if (mdp5_kms->iommu_clk) {
+			ret = clk_prepare_enable(mdp5_kms->iommu_clk);
+			if (ret) {
+				dev_err(dev, "failed to enable iommu_clk\n");
+				goto undo_mmagic_clk;
+			}
+		}
+	} else {
+		if (mdp5_kms->iommu_clk)
+			clk_disable_unprepare(mdp5_kms->iommu_clk);
+		if (mdp5_kms->mmagic_clk)
+			clk_disable_unprepare(mdp5_kms->mmagic_clk);
+		if (mdp5_kms->mmagic)
+			regulator_disable(mdp5_kms->mmagic);
+	}
+
+	return 0;
+
+undo_mmagic_clk:
+	if (mdp5_kms->mmagic_clk)
+		clk_disable_unprepare(mdp5_kms->mmagic_clk);
+undo_gdsc:
+	if (mdp5_kms->mmagic)
+		regulator_disable(mdp5_kms->mmagic);
+
+	return ret;
+}
+
 static void mdp5_destroy(struct msm_kms *kms)
 {
 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
@@ -138,6 +186,7 @@ static void mdp5_destroy(struct msm_kms *kms)
 
 	if (mmu) {
 		mmu->funcs->detach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports));
+		mdp5_translation_ctrl_pwr(mdp5_kms, false);
 		mmu->funcs->destroy(mmu);
 	}
 
@@ -520,6 +569,13 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
 		goto fail;
 	}
 
+	mdp5_kms->mmagic = devm_regulator_get_optional(&pdev->dev, "mmagic");
+	if (IS_ERR(mdp5_kms->mmagic)) {
+		ret = PTR_ERR(mdp5_kms->mmagic);
+		DBG("failed to get mmagic GDSC regulator: %d\n", ret);
+		mdp5_kms->mmagic = NULL;
+	}
+
 	/* mandatory clocks: */
 	ret = get_clk(pdev, &mdp5_kms->axi_clk, "bus_clk", true);
 	if (ret)
@@ -539,6 +595,8 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
 
 	/* optional clocks: */
 	get_clk(pdev, &mdp5_kms->lut_clk, "lut_clk", false);
+	get_clk(pdev, &mdp5_kms->mmagic_clk, "mmagic_clk", false);
+	get_clk(pdev, &mdp5_kms->iommu_clk, "iommu_clk", false);
 
 	/* we need to set a default rate before enabling.  Set a safe
 	 * rate first, then figure out hw revision, and then set a
@@ -612,6 +670,13 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
 			DBG("coherent hardware translation table walks is off");
 		}
 
+		ret = mdp5_translation_ctrl_pwr(mdp5_kms, true);
+		if (ret) {
+			dev_err(dev->dev, "failed to power iommu: %d\n", ret);
+			mmu->funcs->destroy(mmu);
+			goto fail;
+		}
+
 		ret = mmu->funcs->attach(mmu, iommu_ports,
 				ARRAY_SIZE(iommu_ports));
 		if (ret) {
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
index 1e1a6b0..ab19d52a 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
@@ -44,12 +44,15 @@ struct mdp5_kms {
 	void __iomem *mmio, *vbif;
 
 	struct regulator *vdd;
+	struct regulator *mmagic;
 
 	struct clk *axi_clk;
 	struct clk *ahb_clk;
 	struct clk *src_clk;
 	struct clk *core_clk;
 	struct clk *lut_clk;
+	struct clk *mmagic_clk;
+	struct clk *iommu_clk;
 	struct clk *vsync_clk;
 
 	/*
