+ /* Choose the best pred and postd to match freq for lcd */
+ for (i = 1; i <= max_pred; i++) {
+ for (j = 1; j <= max_postd; j++) {
+ temp = freq * i * j;
+ if (temp > max || temp < min)
+ continue;
+ if (best == 0 || temp < best) {
+ best = temp;
+ pred = i;
+ postd = j;
+ }
+ }
+ }
+
+ if (best == 0) {
+ printf("Fail to set rate to %dKHz", freq);
+ return;
+ }
+
+ debug("best %d, pred = %d, postd = %d\n", best, pred, postd);
+
+ pll_div = best / hck;
+ pll_denom = 1000000;
+ pll_num = (best - hck * pll_div) * pll_denom / hck;
+
+ /*
+ * pll_num
+ * (24MHz * (pll_div + --------- ))
+ * pll_denom
+ *freq KHz = --------------------------------
+ * post_div * pred * postd * 1000
+ */
+
+ if (base_addr == LCDIF1_BASE_ADDR) {
+ if (enable_pll_video(pll_div, pll_num, pll_denom, post_div))
+ return;
+
+ /* Select pre-lcd clock to PLL5 and set pre divider */
+ clrsetbits_le32(&imx_ccm->cscdr2,
+ MXC_CCM_CSCDR2_LCDIF1_PRED_SEL_MASK |
+ MXC_CCM_CSCDR2_LCDIF1_PRE_DIV_MASK,
+ (0x2 << MXC_CCM_CSCDR2_LCDIF1_PRED_SEL_OFFSET) |
+ ((pred - 1) <<
+ MXC_CCM_CSCDR2_LCDIF1_PRE_DIV_OFFSET));
+
+ /* Set the post divider */
+ clrsetbits_le32(&imx_ccm->cbcmr,
+ MXC_CCM_CBCMR_LCDIF1_PODF_MASK,
+ ((postd - 1) <<
+ MXC_CCM_CBCMR_LCDIF1_PODF_OFFSET));
+ } else if (is_mx6sx()) {
+ /* Setting LCDIF2 for i.MX6SX */
+ if (enable_pll_video(pll_div, pll_num, pll_denom, post_div))
+ return;
+
+ /* Select pre-lcd clock to PLL5 and set pre divider */
+ clrsetbits_le32(&imx_ccm->cscdr2,
+ MXC_CCM_CSCDR2_LCDIF2_PRED_SEL_MASK |
+ MXC_CCM_CSCDR2_LCDIF2_PRE_DIV_MASK,
+ (0x2 << MXC_CCM_CSCDR2_LCDIF2_PRED_SEL_OFFSET) |
+ ((pred - 1) <<
+ MXC_CCM_CSCDR2_LCDIF2_PRE_DIV_OFFSET));
+
+ /* Set the post divider */
+ clrsetbits_le32(&imx_ccm->cscmr1,
+ MXC_CCM_CSCMR1_LCDIF2_PODF_MASK,
+ ((postd - 1) <<
+ MXC_CCM_CSCMR1_LCDIF2_PODF_OFFSET));
+ }
+}
+
+int enable_lcdif_clock(u32 base_addr)
+{
+ u32 reg = 0;
+ u32 lcdif_clk_sel_mask, lcdif_ccgr3_mask;
+
+ if (is_mx6sx()) {
+ if ((base_addr != LCDIF1_BASE_ADDR) &&
+ (base_addr != LCDIF2_BASE_ADDR)) {
+ puts("Wrong LCD interface!\n");
+ return -EINVAL;
+ }
+ /* Set to pre-mux clock at default */
+ lcdif_clk_sel_mask = (base_addr == LCDIF2_BASE_ADDR) ?
+ MXC_CCM_CSCDR2_LCDIF2_CLK_SEL_MASK :
+ MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK;
+ lcdif_ccgr3_mask = (base_addr == LCDIF2_BASE_ADDR) ?
+ (MXC_CCM_CCGR3_LCDIF2_PIX_MASK |
+ MXC_CCM_CCGR3_DISP_AXI_MASK) :
+ (MXC_CCM_CCGR3_LCDIF1_PIX_MASK |
+ MXC_CCM_CCGR3_DISP_AXI_MASK);
+ } else if (is_mx6ul() || is_mx6ull()) {
+ if (base_addr != LCDIF1_BASE_ADDR) {
+ puts("Wrong LCD interface!\n");
+ return -EINVAL;
+ }
+ /* Set to pre-mux clock at default */
+ lcdif_clk_sel_mask = MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK;
+ lcdif_ccgr3_mask = MXC_CCM_CCGR3_LCDIF1_PIX_MASK;
+ } else {
+ return 0;
+ }
+
+ reg = readl(&imx_ccm->cscdr2);
+ reg &= ~lcdif_clk_sel_mask;
+ writel(reg, &imx_ccm->cscdr2);
+
+ /* Enable the LCDIF pix clock */
+ reg = readl(&imx_ccm->CCGR3);
+ reg |= lcdif_ccgr3_mask;
+ writel(reg, &imx_ccm->CCGR3);
+
+ reg = readl(&imx_ccm->CCGR2);
+ reg |= MXC_CCM_CCGR2_LCD_MASK;
+ writel(reg, &imx_ccm->CCGR2);
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_FSL_QSPI
+/* qspi_num can be from 0 - 1 */
+void enable_qspi_clk(int qspi_num)
+{
+ u32 reg = 0;
+ /* Enable QuadSPI clock */
+ switch (qspi_num) {
+ case 0:
+ /* disable the clock gate */
+ clrbits_le32(&imx_ccm->CCGR3, MXC_CCM_CCGR3_QSPI1_MASK);
+
+ /* set 50M : (50 = 396 / 2 / 4) */
+ reg = readl(&imx_ccm->cscmr1);
+ reg &= ~(MXC_CCM_CSCMR1_QSPI1_PODF_MASK |
+ MXC_CCM_CSCMR1_QSPI1_CLK_SEL_MASK);
+ reg |= ((1 << MXC_CCM_CSCMR1_QSPI1_PODF_OFFSET) |
+ (2 << MXC_CCM_CSCMR1_QSPI1_CLK_SEL_OFFSET));
+ writel(reg, &imx_ccm->cscmr1);
+
+ /* enable the clock gate */
+ setbits_le32(&imx_ccm->CCGR3, MXC_CCM_CCGR3_QSPI1_MASK);
+ break;
+ case 1:
+ /*
+ * disable the clock gate
+ * QSPI2 and GPMI_BCH_INPUT_GPMI_IO share the same clock gate,
+ * disable both of them.
+ */
+ clrbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK |
+ MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK);
+
+ /* set 50M : (50 = 396 / 2 / 4) */
+ reg = readl(&imx_ccm->cs2cdr);
+ reg &= ~(MXC_CCM_CS2CDR_QSPI2_CLK_PODF_MASK |
+ MXC_CCM_CS2CDR_QSPI2_CLK_PRED_MASK |
+ MXC_CCM_CS2CDR_QSPI2_CLK_SEL_MASK);
+ reg |= (MXC_CCM_CS2CDR_QSPI2_CLK_PRED(0x1) |
+ MXC_CCM_CS2CDR_QSPI2_CLK_SEL(0x3));
+ writel(reg, &imx_ccm->cs2cdr);
+
+ /*enable the clock gate*/
+ setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK |
+ MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK);
+ break;
+ default:
+ break;
+ }