summaryrefslogtreecommitdiff
path: root/arch/arm/cpu
diff options
context:
space:
mode:
authorPeng Fan <Peng.Fan@freescale.com>2015-05-05 14:40:02 +0800
committerPeng Fan <Peng.Fan@freescale.com>2015-05-05 14:40:02 +0800
commitfd623964a78194543cfe21e5be031aa4ce9f623e (patch)
treeb2b5f81fa06205542c196d1c8870f176275d85ce /arch/arm/cpu
parent88ae4c453ba53c5920a381a5d9c23d3815413271 (diff)
downloadu-boot-imx-fd623964a78194543cfe21e5be031aa4ce9f623e.zip
u-boot-imx-fd623964a78194543cfe21e5be031aa4ce9f623e.tar.gz
u-boot-imx-fd623964a78194543cfe21e5be031aa4ce9f623e.tar.bz2
MLK-10812-2 imx:mx6ul add clock support
add i.MX6UL clock related settings/macros/apis When using TFT43AB, its pixel size is 480x272 which needs a slow pix clock. Without apply the test_div in PLL video, we can't get the pix clock in the rate. So change the LCDIF clock calculation to use the test_div. Signed-off-by: Peng Fan <Peng.Fan@freescale.com> Signed-off-by: Ye.Li <B37916@freescale.com>
Diffstat (limited to 'arch/arm/cpu')
-rw-r--r--arch/arm/cpu/armv7/mx6/clock.c170
1 files changed, 152 insertions, 18 deletions
diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c
index e6a2115..bac45e0 100644
--- a/arch/arm/cpu/armv7/mx6/clock.c
+++ b/arch/arm/cpu/armv7/mx6/clock.c
@@ -94,16 +94,27 @@ void enable_usboh3_clk(unsigned char enable)
#if defined(CONFIG_FEC_MXC) && !defined(CONFIG_MX6SX)
void enable_enet_clk(unsigned char enable)
{
+#ifdef CONFIG_MX6UL
+ u32 mask = MXC_CCM_CCGR3_ENET_CLK_ENABLE_MASK;
+ /* Set AHB clk, since enet clock is sourced from AHB and IPG */
+ /* ROM has set AHB, just leave here empty */
+ /* Enable enet system clock */
+ if (enable)
+ setbits_le32(&imx_ccm->CCGR3, mask);
+ else
+ clrbits_le32(&imx_ccm->CCGR3, mask);
+#else
u32 mask = MXC_CCM_CCGR1_ENET_CLK_ENABLE_MASK;
if (enable)
setbits_le32(&imx_ccm->CCGR1, mask);
else
clrbits_le32(&imx_ccm->CCGR1, mask);
+#endif
}
#endif
-#ifdef CONFIG_MXC_UART
+#if defined(CONFIG_MXC_UART) && !defined(CONFIG_MX6UL)
void enable_uart_clk(unsigned char enable)
{
u32 mask = MXC_CCM_CCGR5_UART_MASK | MXC_CCM_CCGR5_UART_SERIAL_MASK;
@@ -246,10 +257,12 @@ static u32 mxc_get_pll_pfd(enum pll_clocks pll, int pfd_num)
switch (pll) {
case PLL_BUS:
+#if !defined(CONFIG_MX6UL) && !defined(CONFIG_MX6UL)
if (pfd_num == 3) {
/* No PFD3 on PPL2 */
return 0;
}
+#endif
div = __raw_readl(&imx_ccm->analog_pfd_528);
freq = (u64)decode_pll(PLL_BUS, MXC_HCLK);
break;
@@ -281,9 +294,12 @@ static u32 get_mcu_main_clk(void)
u32 get_periph_clk(void)
{
u32 reg, freq = 0;
+ u32 div;
reg = __raw_readl(&imx_ccm->cbcdr);
if (reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL) {
+ div = (reg & MXC_CCM_CBCDR_PERIPH_CLK2_PODF_MASK) >>
+ MXC_CCM_CBCDR_PERIPH_CLK2_PODF_OFFSET;
reg = __raw_readl(&imx_ccm->cbcmr);
reg &= MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK;
reg >>= MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET;
@@ -321,9 +337,10 @@ u32 get_periph_clk(void)
default:
break;
}
+ div = 0;
}
- return freq;
+ return freq / (div + 1);
}
static u32 get_ipg_clk(void)
@@ -342,7 +359,8 @@ static u32 get_ipg_per_clk(void)
u32 reg, perclk_podf;
reg = __raw_readl(&imx_ccm->cscmr1);
-#if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX) || defined(CONFIG_MX6QP))
+#if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX) || \
+ defined(CONFIG_MX6QP) || defined(CONFIG_MX6UL))
if (reg & MXC_CCM_CSCMR1_PER_CLK_SEL_MASK)
return MXC_HCLK; /* OSC 24Mhz */
#endif
@@ -356,7 +374,8 @@ static u32 get_uart_clk(void)
u32 reg, uart_podf;
u32 freq = decode_pll(PLL_USBOTG, MXC_HCLK) / 6; /* static divider */
reg = __raw_readl(&imx_ccm->cscdr1);
-#if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX) || defined(CONFIG_MX6QP))
+#if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX) || \
+ defined(CONFIG_MX6QP) || defined(CONFIG_MX6UL))
if (reg & MXC_CCM_CSCDR1_UART_CLK_SEL)
freq = MXC_HCLK;
#endif
@@ -374,7 +393,8 @@ static u32 get_cspi_clk(void)
cspi_podf = (reg & MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK)
>> MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET;
-#if defined(CONFIG_MX6QP)
+#if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX) || \
+ defined(CONFIG_MX6QP) || defined(CONFIG_MX6UL))
if (reg & MXC_CCM_CSCDR2_ECSPI_CLK_SEL_MASK)
return MXC_HCLK / (cspi_podf + 1);
#endif
@@ -429,7 +449,46 @@ static u32 get_emi_slow_clk(void)
return root_freq / (emi_slow_podf + 1);
}
-#if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX))
+#if defined(CONFIG_MX6UL) || defined(CONFIG_MX6SX)
+static u32 get_mmdc_ch0_clk(void)
+{
+ u32 cbcmr = __raw_readl(&imx_ccm->cbcmr);
+ u32 cbcdr = __raw_readl(&imx_ccm->cbcdr);
+ u32 freq, mmdc_podf, per2_clk2_podf;
+
+ mmdc_podf = (cbcdr & MXC_CCM_CBCDR_MMDC_CH1_PODF_MASK)
+ >> MXC_CCM_CBCDR_MMDC_CH1_PODF_OFFSET;
+ if (cbcdr & MXC_CCM_CBCDR_PERIPH2_CLK_SEL) {
+ per2_clk2_podf = (cbcdr & MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_MASK)
+ >> MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_OFFSET;
+ if (cbcmr & MXC_CCM_CBCMR_PERIPH2_CLK2_SEL)
+ freq = MXC_HCLK;
+ else
+ freq = decode_pll(PLL_USBOTG, MXC_HCLK);
+ } else {
+ per2_clk2_podf = 0;
+ switch ((cbcmr & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK) >>
+ MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET) {
+ case 0:
+ freq = decode_pll(PLL_BUS, MXC_HCLK);
+ break;
+ case 1:
+ freq = mxc_get_pll_pfd(PLL_BUS, 2);
+ break;
+ case 2:
+ freq = mxc_get_pll_pfd(PLL_BUS, 0);
+ break;
+ case 3:
+ /* static / 2 divider */
+ freq = mxc_get_pll_pfd(PLL_BUS, 2) / 2;
+ break;
+ }
+ }
+
+
+ return freq / (mmdc_podf + 1) / (per2_clk2_podf + 1);
+}
+#elif defined(CONFIG_MX6SL)
static u32 get_mmdc_ch0_clk(void)
{
u32 cbcmr = __raw_readl(&imx_ccm->cbcmr);
@@ -540,7 +599,41 @@ void enable_lcdif_clock(uint32_t base_addr)
writel(reg, &imx_ccm->CCGR2);
}
-static int enable_pll_video(u32 pll_div, u32 pll_num, u32 pll_denom)
+void mxs_set_vadcclk(void)
+{
+ u32 reg = 0;
+
+ reg = readl(&imx_ccm->cscmr2);
+ reg &= ~MXC_CCM_CSCMR2_VID_CLK_SEL_MASK;
+ reg |= 0x19 << MXC_CCM_CSCMR2_VID_CLK_SEL_OFFSET;
+ writel(reg, &imx_ccm->cscmr2);
+}
+#endif
+
+#ifdef CONFIG_MX6UL
+void enable_lcdif_clock(uint32_t base_addr)
+{
+ u32 reg = 0;
+
+ /* Set to pre-mux clock at default */
+ reg = readl(&imx_ccm->cscdr2);
+ reg &= ~MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK;
+ writel(reg, &imx_ccm->cscdr2);
+
+ /* Enable the LCDIF pix clock */
+ reg = readl(&imx_ccm->CCGR3);
+ reg |= MXC_CCM_CCGR3_LCDIF1_PIX_MASK;
+ writel(reg, &imx_ccm->CCGR3);
+
+ reg = readl(&imx_ccm->CCGR2);
+ reg |= MXC_CCM_CCGR2_LCD_MASK;
+ writel(reg, &imx_ccm->CCGR2);
+}
+#endif
+
+#if defined(CONFIG_MX6SX) || defined(CONFIG_MX6UL)
+static int enable_pll_video(u32 pll_div, u32 pll_num, u32 pll_denom,
+ u32 test_div)
{
u32 reg = 0;
ulong start;
@@ -554,9 +647,23 @@ static int enable_pll_video(u32 pll_div, u32 pll_num, u32 pll_denom)
&imx_ccm->analog_pll_video_clr);
/* Set div, num and denom */
- writel(BF_ANADIG_PLL_VIDEO_DIV_SELECT(pll_div) |
- BF_ANADIG_PLL_VIDEO_TEST_DIV_SELECT(0x2),
- &imx_ccm->analog_pll_video_set);
+ switch (test_div) {
+ case 1:
+ writel(BF_ANADIG_PLL_VIDEO_DIV_SELECT(pll_div) |
+ BF_ANADIG_PLL_VIDEO_TEST_DIV_SELECT(0x1),
+ &imx_ccm->analog_pll_video_set);
+ break;
+ case 2:
+ writel(BF_ANADIG_PLL_VIDEO_DIV_SELECT(pll_div) |
+ BF_ANADIG_PLL_VIDEO_TEST_DIV_SELECT(0x0),
+ &imx_ccm->analog_pll_video_set);
+ break;
+ default:
+ writel(BF_ANADIG_PLL_VIDEO_DIV_SELECT(pll_div) |
+ BF_ANADIG_PLL_VIDEO_TEST_DIV_SELECT(0x2),
+ &imx_ccm->analog_pll_video_set);
+ break;
+ }
writel(BF_ANADIG_PLL_VIDEO_NUM_A(pll_num),
&imx_ccm->analog_pll_video_num);
@@ -590,7 +697,7 @@ void mxs_set_lcdclk(uint32_t base_addr, uint32_t freq)
u32 max = hck * 54;
u32 temp, best = 0;
u32 i, j, pred = 1, postd = 1;
- u32 pll_div, pll_num, pll_denom;
+ u32 pll_div, pll_num, pll_denom, post_div = 0;
debug("mxs_set_lcdclk, freq = %d\n", freq);
@@ -598,11 +705,30 @@ void mxs_set_lcdclk(uint32_t base_addr, uint32_t freq)
reg = readl(&imx_ccm->cscdr2);
if ((reg & MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK) != 0)
return; /*Can't change clocks when clock not from pre-mux */
- } else {
+ }
+#ifdef CONFIG_MX6SX
+ else {
reg = readl(&imx_ccm->cscdr2);
if ((reg & MXC_CCM_CSCDR2_LCDIF2_CLK_SEL_MASK) != 0)
return; /*Can't change clocks when clock not from pre-mux */
}
+#endif
+
+ temp = (freq * 8 * 8);
+ if (temp < min) {
+ for (i = 1; i <= 2; i++) {
+ if ((temp * (1 << i)) > min) {
+ post_div = i;
+ freq = (freq * (1 << i));
+ break;
+ }
+ }
+
+ if (3 == i) {
+ printf("Fail to set rate to %dkhz", freq);
+ return;
+ }
+ }
for (i = 1; i <= 8; i++) {
for (j = 1; j <= 8; j++) {
@@ -630,7 +756,7 @@ void mxs_set_lcdclk(uint32_t base_addr, uint32_t freq)
pll_num = (best - hck * pll_div) * pll_denom / hck;
if (base_addr == LCDIF1_BASE_ADDR) {
- if (enable_pll_video(pll_div, pll_num, pll_denom))
+ if (enable_pll_video(pll_div, pll_num, pll_denom, post_div))
return;
/* Select pre-lcd clock to PLL5 */
@@ -647,8 +773,9 @@ void mxs_set_lcdclk(uint32_t base_addr, uint32_t freq)
reg &= ~MXC_CCM_CBCMR_LCDIF1_PODF_MASK;
reg |= ((postd - 1) << MXC_CCM_CBCMR_LCDIF1_PODF_OFFSET);
writel(reg, &imx_ccm->cbcmr);
-
- } else {
+ }
+#ifdef CONFIG_MX6SX
+ else {
if (enable_pll_video(pll_div, pll_num, pll_denom))
return;
@@ -667,6 +794,7 @@ void mxs_set_lcdclk(uint32_t base_addr, uint32_t freq)
reg |= ((postd - 1) << MXC_CCM_CSCMR1_LCDIF2_PODF_OFFSET);
writel(reg, &imx_ccm->cscmr1);
}
+#endif
}
/* qspi_num can be from 0 - 1 */
@@ -690,6 +818,7 @@ void enable_qspi_clk(int qspi_num)
/* enable the clock gate */
setbits_le32(&imx_ccm->CCGR3, MXC_CCM_CCGR3_QSPI1_MASK);
break;
+#ifdef CONFIG_MX6SX
case 1:
/*
* disable the clock gate
@@ -712,12 +841,13 @@ void enable_qspi_clk(int qspi_num)
setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK |
MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK);
break;
+#endif
default:
break;
}
}
-void mxs_set_vadcclk()
+void mxs_set_vadcclk(void)
{
u32 reg = 0;
@@ -774,7 +904,7 @@ int enable_fec_anatop_clock(int fec_id, enum enet_freq freq)
#endif
writel(reg, &anatop->pll_enet);
-#ifdef CONFIG_MX6SX
+#if defined(CONFIG_MX6SX)
/*
* Set enet ahb clock to 200MHz
* pll2_pfd2_396m-> ENET_PODF-> ENET_AHB
@@ -818,6 +948,7 @@ static u32 get_usdhc_clk(u32 port)
clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC2_CLK_SEL;
break;
+#ifndef CONFIG_MX6UL
case 2:
usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC3_PODF_MASK) >>
MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET;
@@ -830,6 +961,7 @@ static u32 get_usdhc_clk(u32 port)
clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC4_CLK_SEL;
break;
+#endif
default:
break;
}
@@ -852,6 +984,7 @@ u32 imx_get_fecclk(void)
return mxc_get_clock(MXC_IPG_CLK);
}
+#ifndef CONFIG_MX6UL
static int enable_enet_pll(uint32_t en)
{
struct mxc_ccm_reg *const imx_ccm
@@ -980,6 +1113,7 @@ int enable_pcie_clock(void)
return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_PCIE);
#endif
}
+#endif
#ifdef CONFIG_SECURE_BOOT
void hab_caam_clock_enable(unsigned char enable)
@@ -1114,7 +1248,7 @@ int do_mx6_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return 0;
}
-#ifndef CONFIG_MX6SX
+#if !defined(CONFIG_MX6SX) && !defined(CONFIG_MX6UL)
#ifdef CONFIG_MX6QP
static void pre_misc_setting(void)
{