diff --git a/drivers/clk/mmp/clk-gate.c b/drivers/clk/mmp/clk-gate.c
index 1755916ddef2d..bf93ffb258667 100644
--- a/drivers/clk/mmp/clk-gate.c
+++ b/drivers/clk/mmp/clk-gate.c
@@ -9,6 +9,7 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/slab.h>
 #include <linux/io.h>
@@ -31,6 +32,8 @@ static int mmp_clk_gate_enable(struct clk_hw *hw)
 	unsigned long rate;
 	u32 tmp;
 
+	clk_prepare_enable(gate->companion);
+
 	if (gate->lock)
 		spin_lock_irqsave(gate->lock, flags);
 
@@ -67,6 +70,8 @@ static void mmp_clk_gate_disable(struct clk_hw *hw)
 
 	if (gate->lock)
 		spin_unlock_irqrestore(gate->lock, flags);
+
+	clk_disable_unprepare(gate->companion);
 }
 
 static int mmp_clk_gate_is_enabled(struct clk_hw *hw)
@@ -95,7 +100,8 @@ const struct clk_ops mmp_clk_gate_ops = {
 struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u32 mask, u32 val_enable, u32 val_disable,
-		unsigned int gate_flags, spinlock_t *lock)
+		unsigned int gate_flags, spinlock_t *lock,
+		struct clk *companion)
 {
 	struct mmp_clk_gate *gate;
 	struct clk *clk;
@@ -119,6 +125,7 @@ struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
 	gate->val_disable = val_disable;
 	gate->flags = gate_flags;
 	gate->lock = lock;
+	gate->companion = companion;
 	gate->hw.init = &init;
 
 	clk = clk_register(dev, &gate->hw);
diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index 8b2eb989980bf..7ac96a1dcd60c 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -394,7 +394,7 @@ static struct mmp_param_gate_clk mmp2_apmu_gate_clks[] = {
 static struct mmp_param_gate_clk mmp3_apmu_gate_clks[] = {
 	{MMP3_CLK_SDH4, "sdh4_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH4, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
 	{MMP3_CLK_GPU_3D, "gpu_3d_clk", "gpu_3d_div", CLK_SET_RATE_PARENT, APMU_GPU, 0x5, 0x5, 0x0, MMP_CLK_GATE_NEED_DELAY, &gpu_lock},
-	{MMP3_CLK_GPU_2D, "gpu_2d_clk", "gpu_2d_div", CLK_SET_RATE_PARENT, APMU_GPU, 0x1c0000, 0x1c0000, 0x0, MMP_CLK_GATE_NEED_DELAY, &gpu_lock},
+	{MMP3_CLK_GPU_2D, "gpu_2d_clk", "gpu_2d_div", CLK_SET_RATE_PARENT, APMU_GPU, 0x1c0000, 0x1c0000, 0x0, MMP_CLK_GATE_NEED_DELAY, &gpu_lock, MMP3_CLK_GPU_3D},
 };
 
 static void mmp2_axi_periph_clk_init(struct mmp2_clk_unit *pxa_unit)
diff --git a/drivers/clk/mmp/clk.c b/drivers/clk/mmp/clk.c
index ca7d37e2c7be6..05d2b901cae5f 100644
--- a/drivers/clk/mmp/clk.c
+++ b/drivers/clk/mmp/clk.c
@@ -109,7 +109,8 @@ void mmp_register_gate_clks(struct mmp_clk_unit *unit,
 					clks[i].val_enable,
 					clks[i].val_disable,
 					clks[i].gate_flags,
-					clks[i].lock);
+					clks[i].lock,
+					unit->clk_table[clks[i].companion_id]);
 
 		if (IS_ERR(clk)) {
 			pr_err("%s: failed to register clock %s\n",
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index 55ac053797819..385b74e671c31 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -117,6 +117,13 @@ struct mmp_clk_gate {
 	u32 val_disable;
 	unsigned int flags;
 	spinlock_t *lock;
+
+	/*
+	 * The sole purpose of this is to make sure the 3D GPU clock gets
+	 * enabled alongside 2D GPU clock, otherwise the 2D unit wouldn't
+	 * work. It is not know why this needs to be done.
+	 */
+	struct clk *companion;
 };
 
 extern const struct clk_ops mmp_clk_gate_ops;
@@ -124,7 +131,7 @@ extern struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
 			const char *parent_name, unsigned long flags,
 			void __iomem *reg, u32 mask, u32 val_enable,
 			u32 val_disable, unsigned int gate_flags,
-			spinlock_t *lock);
+			spinlock_t *lock, struct clk *companion);
 
 extern struct clk *mmp_clk_register_apbc(const char *name,
 		const char *parent_name, void __iomem *base,
@@ -187,6 +194,7 @@ struct mmp_param_gate_clk {
 	u32 val_disable;
 	unsigned int gate_flags;
 	spinlock_t *lock;
+	unsigned int companion_id;
 };
 void mmp_register_gate_clks(struct mmp_clk_unit *unit,
 			struct mmp_param_gate_clk *clks,
