diff --git a/arch/arm/include/asm/arch-mx7/clock.h b/arch/arm/include/asm/arch-mx7/clock.h
index f56564ea6fc7e999159db42f3847f76d2fd28036..06ba55064ad0a71b025683db0601bd903a841656 100644
--- a/arch/arm/include/asm/arch-mx7/clock.h
+++ b/arch/arm/include/asm/arch-mx7/clock.h
@@ -333,7 +333,7 @@ int enable_i2c_clk(unsigned char enable, unsigned i2c_num);
 #ifdef CONFIG_FEC_MXC
 int set_clk_enet(enum enet_freq type);
 #endif
-int set_clk_qspi(void);
+int set_clk_qspi(u32 freq);
 int set_clk_nand(void);
 #ifdef CONFIG_MXC_OCOTP
 void enable_ocotp_clk(unsigned char enable);
diff --git a/arch/arm/mach-imx/mx7/clock.c b/arch/arm/mach-imx/mx7/clock.c
index 8cda71cf55bee61738a406b9034ff76c9897bc09..03a96309cd505e3dbb46545014115e84ed1dbe7c 100644
--- a/arch/arm/mach-imx/mx7/clock.c
+++ b/arch/arm/mach-imx/mx7/clock.c
@@ -849,17 +849,37 @@ static int enable_pll_video(u32 pll_div, u32 pll_num, u32 pll_denom,
 	return 1;
 }
 
-int set_clk_qspi(void)
+int set_clk_qspi(u32 freq)
 {
 	u32 target;
+	u32 div, pre, post;
+	u32 best = 64 * 8;
+	u32 best_pre = 8;
+	u32 best_post = 64;
 
 	/* disable the clock gate first */
 	clock_enable(CCGR_QSPI, 0);
+	if (!freq)
+		return 0;
+
+
+	target = ((392000000/4 - 1)/ freq) + 1;
+	for (pre = 1; pre <= 8; pre++) {
+		post = ((target - 1)/ pre) + 1;
+		if (post > 64)
+			continue;
+		div = pre * post;
+		if (best >= div) {
+			best = div;
+			best_pre = pre;
+			best_post = post;
+		}
+	}
 
 	/* 49M: 392/2/4 */
 	target = CLK_ROOT_ON | QSPI_CLK_ROOT_FROM_PLL_SYS_PFD4_CLK |
-		 CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
-		 CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2);
+		 CLK_ROOT_PRE_DIV(best_pre - 1) |
+		 CLK_ROOT_POST_DIV(best_post - 1);
 	clock_set_target_val(QSPI_CLK_ROOT, target);
 
 	/* enable the clock gate */