From: Patrice Chotard Date: Thu, 8 Feb 2018 16:20:49 +0000 (+0100) Subject: clk: clk_stm32f: Configure SAI PLL to generate LTDC pixel clock X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=e8fb9ed2542ab6ca1946bec34a5232bde785f141;p=u-boot.git clk: clk_stm32f: Configure SAI PLL to generate LTDC pixel clock Configure SAI PLL configuration to generate LTDC pixel clock on the PLLSAIR output. PLLSAI is enabled only if CONFIG_VIDEO_STM32 flag is set. Signed-off-by: Patrice Chotard --- diff --git a/drivers/clk/clk_stm32f.c b/drivers/clk/clk_stm32f.c index a687e2acd4..a11d6dc242 100644 --- a/drivers/clk/clk_stm32f.c +++ b/drivers/clk/clk_stm32f.c @@ -65,13 +65,17 @@ #define RCC_PLLSAICFGR_PLLSAIR_SHIFT 28 #define RCC_PLLSAICFGR_PLLSAIP_4 BIT(16) #define RCC_PLLSAICFGR_PLLSAIQ_4 BIT(26) -#define RCC_PLLSAICFGR_PLLSAIR_2 BIT(29) +#define RCC_PLLSAICFGR_PLLSAIR_3 BIT(29) | BIT(28) #define RCC_DCKCFGRX_TIMPRE BIT(24) #define RCC_DCKCFGRX_CK48MSEL BIT(27) #define RCC_DCKCFGRX_SDMMC1SEL BIT(28) #define RCC_DCKCFGR2_SDMMC2SEL BIT(29) +#define RCC_DCKCFGR_PLLSAIDIVR_SHIFT 16 +#define RCC_DCKCFGR_PLLSAIDIVR_MASK GENMASK(17, 16) +#define RCC_DCKCFGR_PLLSAIDIVR_2 0 + /* * RCC AHB1ENR specific definitions */ @@ -132,6 +136,8 @@ struct stm32_clk { unsigned long hse_rate; }; +static const u8 pllsaidivr_table[] = { 2, 4, 8, 16 }; + static int configure_clocks(struct udevice *dev) { struct stm32_clk *priv = dev_get_priv(dev); @@ -187,11 +193,29 @@ static int configure_clocks(struct udevice *dev) clrbits_le32(®s->dckcfgr, RCC_DCKCFGRX_SDMMC1SEL); } +#ifdef CONFIG_VIDEO_STM32 + /* + * Configure the SAI PLL to generate LTDC pixel clock + */ + clrsetbits_le32(®s->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIR_MASK, + RCC_PLLSAICFGR_PLLSAIR_3); + clrsetbits_le32(®s->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIN_MASK, + 195 << RCC_PLLSAICFGR_PLLSAIN_SHIFT); + + clrsetbits_le32(®s->dckcfgr, RCC_DCKCFGR_PLLSAIDIVR_MASK, + RCC_DCKCFGR_PLLSAIDIVR_2 << RCC_DCKCFGR_PLLSAIDIVR_SHIFT); +#endif /* Enable the main PLL */ setbits_le32(®s->cr, RCC_CR_PLLON); while (!(readl(®s->cr) & RCC_CR_PLLRDY)) ; +#ifdef CONFIG_VIDEO_STM32 +/* Enable the SAI PLL */ + setbits_le32(®s->cr, RCC_CR_PLLSAION); + while (!(readl(®s->cr) & RCC_CR_PLLSAIRDY)) + ; +#endif setbits_le32(®s->apb1enr, RCC_APB1ENR_PWREN); if (priv->info.has_overdrive) { @@ -361,6 +385,8 @@ static ulong stm32_clk_get_rate(struct clk *clk) u32 sysclk = 0; u32 vco; u32 sdmmcxsel_bit; + u32 saidivr; + u32 pllsai_rate; u16 pllm, plln, pllp, pllq; if ((readl(®s->cfgr) & RCC_CFGR_SWS_MASK) == @@ -438,6 +464,15 @@ static ulong stm32_clk_get_rate(struct clk *clk) case STM32F7_APB2_CLOCK(TIM11): return stm32_get_timer_rate(priv, sysclk, APB2); break; + + /* particular case for LTDC clock */ + case STM32F7_APB2_CLOCK(LTDC): + saidivr = readl(®s->dckcfgr); + saidivr = (saidivr & RCC_DCKCFGR_PLLSAIDIVR_MASK) + >> RCC_DCKCFGR_PLLSAIDIVR_SHIFT; + pllsai_rate = stm32_clk_get_pllsai_rate(priv, PLLSAIR); + + return pllsai_rate / pllsaidivr_table[saidivr]; } return (sysclk >> stm32_get_apb_shift(regs, APB2));