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 */