Lines Matching +full:stm32 +full:- +full:ltdc
1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
8 #include <clk-uclass.h>
13 #include <asm/arch/stm32.h>
16 #include <dt-bindings/mfd/stm32f7-rcc.h>
147 struct stm32_rcc_regs *regs = priv->base; in configure_clocks()
148 struct stm32_pwr_regs *pwr = priv->pwr_regs; in configure_clocks()
149 struct pll_psc *sys_pll_psc = &priv->info.sys_pll_psc; in configure_clocks()
152 setbits_le32(®s->cr, RCC_CR_HSION); in configure_clocks()
153 writel(0, ®s->cfgr); /* Reset CFGR */ in configure_clocks()
154 clrbits_le32(®s->cr, (RCC_CR_HSEON | RCC_CR_CSSON in configure_clocks()
156 writel(0x24003010, ®s->pllcfgr); /* Reset value from RM */ in configure_clocks()
157 clrbits_le32(®s->cr, RCC_CR_HSEBYP); in configure_clocks()
158 writel(0, ®s->cir); /* Disable all interrupts */ in configure_clocks()
161 setbits_le32(®s->cr, RCC_CR_HSEON); in configure_clocks()
162 while (!(readl(®s->cr) & RCC_CR_HSERDY)) in configure_clocks()
165 setbits_le32(®s->cfgr, (( in configure_clocks()
166 sys_pll_psc->ahb_psc << RCC_CFGR_HPRE_SHIFT) in configure_clocks()
167 | (sys_pll_psc->apb1_psc << RCC_CFGR_PPRE1_SHIFT) in configure_clocks()
168 | (sys_pll_psc->apb2_psc << RCC_CFGR_PPRE2_SHIFT))); in configure_clocks()
171 setbits_le32(®s->pllcfgr, RCC_PLLCFGR_PLLSRC); /* pll source HSE */ in configure_clocks()
172 clrsetbits_le32(®s->pllcfgr, RCC_PLLCFGR_PLLM_MASK, in configure_clocks()
173 sys_pll_psc->pll_m << RCC_PLLCFGR_PLLM_SHIFT); in configure_clocks()
174 clrsetbits_le32(®s->pllcfgr, RCC_PLLCFGR_PLLN_MASK, in configure_clocks()
175 sys_pll_psc->pll_n << RCC_PLLCFGR_PLLN_SHIFT); in configure_clocks()
176 clrsetbits_le32(®s->pllcfgr, RCC_PLLCFGR_PLLP_MASK, in configure_clocks()
177 ((sys_pll_psc->pll_p >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT); in configure_clocks()
178 clrsetbits_le32(®s->pllcfgr, RCC_PLLCFGR_PLLQ_MASK, in configure_clocks()
179 sys_pll_psc->pll_q << RCC_PLLCFGR_PLLQ_SHIFT); in configure_clocks()
182 if (priv->info.v2) { /*stm32f7 case */ in configure_clocks()
183 if (priv->pllsaip) in configure_clocks()
185 setbits_le32(®s->dckcfgr2, RCC_DCKCFGRX_CK48MSEL); in configure_clocks()
188 clrbits_le32(®s->dckcfgr2, RCC_DCKCFGRX_CK48MSEL); in configure_clocks()
191 clrbits_le32(®s->dckcfgr2, RCC_DCKCFGRX_SDMMC1SEL); in configure_clocks()
194 clrbits_le32(®s->dckcfgr2, RCC_DCKCFGR2_SDMMC2SEL); in configure_clocks()
196 if (priv->pllsaip) in configure_clocks()
198 setbits_le32(®s->dckcfgr, RCC_DCKCFGRX_CK48MSEL); in configure_clocks()
201 clrbits_le32(®s->dckcfgr, RCC_DCKCFGRX_CK48MSEL); in configure_clocks()
204 clrbits_le32(®s->dckcfgr, RCC_DCKCFGRX_SDMMC1SEL); in configure_clocks()
208 * Configure the SAI PLL to generate LTDC pixel clock and in configure_clocks()
211 clrsetbits_le32(®s->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIP_MASK, in configure_clocks()
213 clrsetbits_le32(®s->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIR_MASK, in configure_clocks()
215 clrsetbits_le32(®s->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIN_MASK, in configure_clocks()
218 clrsetbits_le32(®s->dckcfgr, RCC_DCKCFGR_PLLSAIDIVR_MASK, in configure_clocks()
222 setbits_le32(®s->cr, RCC_CR_PLLON); in configure_clocks()
223 while (!(readl(®s->cr) & RCC_CR_PLLRDY)) in configure_clocks()
227 setbits_le32(®s->cr, RCC_CR_PLLSAION); in configure_clocks()
228 while (!(readl(®s->cr) & RCC_CR_PLLSAIRDY)) in configure_clocks()
230 setbits_le32(®s->apb1enr, RCC_APB1ENR_PWREN); in configure_clocks()
232 if (priv->info.has_overdrive) { in configure_clocks()
237 setbits_le32(&pwr->cr1, PWR_CR1_ODEN); in configure_clocks()
239 while (!(readl(&pwr->csr1) & PWR_CSR1_ODRDY)) in configure_clocks()
241 /* Enable the Over-drive switch */ in configure_clocks()
242 setbits_le32(&pwr->cr1, PWR_CR1_ODSWEN); in configure_clocks()
244 while (!(readl(&pwr->csr1) & PWR_CSR1_ODSWRDY)) in configure_clocks()
249 clrbits_le32(®s->cfgr, (RCC_CFGR_SW0 | RCC_CFGR_SW1)); in configure_clocks()
250 setbits_le32(®s->cfgr, RCC_CFGR_SW_PLL); in configure_clocks()
252 while ((readl(®s->cfgr) & RCC_CFGR_SWS_MASK) != in configure_clocks()
258 setbits_le32(®s->apb2enr, RCC_APB2ENR_SYSCFGEN); in configure_clocks()
266 struct stm32_rcc_regs *regs = priv->base; in stm32_clk_get_ck48msel()
268 if (priv->info.v2) /*stm32f7 case */ in stm32_clk_get_ck48msel()
269 return readl(®s->dckcfgr2) & RCC_DCKCFGRX_CK48MSEL; in stm32_clk_get_ck48msel()
272 return readl(®s->dckcfgr) & RCC_DCKCFGRX_CK48MSEL; in stm32_clk_get_ck48msel()
277 struct stm32_rcc_regs *regs = priv->base; in stm32_clk_get_pllsai_vco_rate()
280 pllm = (readl(®s->pllcfgr) & RCC_PLLCFGR_PLLM_MASK); in stm32_clk_get_pllsai_vco_rate()
281 pllsain = ((readl(®s->pllsaicfgr) & RCC_PLLSAICFGR_PLLSAIN_MASK) in stm32_clk_get_pllsai_vco_rate()
284 return ((priv->hse_rate / pllm) * pllsain); in stm32_clk_get_pllsai_vco_rate()
290 struct stm32_rcc_regs *regs = priv->base; in stm32_clk_get_pllsai_rate()
295 pll_div_output = ((((readl(®s->pllsaicfgr) in stm32_clk_get_pllsai_rate()
300 pll_div_output = (readl(®s->pllsaicfgr) in stm32_clk_get_pllsai_rate()
305 pll_div_output = (readl(®s->pllsaicfgr) in stm32_clk_get_pllsai_rate()
311 return -EINVAL; in stm32_clk_get_pllsai_rate()
319 struct stm32_rcc_regs *regs = priv->base; in stm32_get_timpre()
322 if (priv->info.v2) /*stm32f7 case */ in stm32_get_timpre()
323 val = readl(®s->dckcfgr2); in stm32_get_timpre()
325 val = readl(®s->dckcfgr); in stm32_get_timpre()
339 (readl(®s->cfgr) & RCC_CFGR_AHB_PSC_MASK) in stm32_get_hclk_rate()
354 (readl(®s->cfgr) & RCC_CFGR_APB1_PSC_MASK) in stm32_get_apb_shift()
358 (readl(®s->cfgr) & RCC_CFGR_APB2_PSC_MASK) in stm32_get_apb_shift()
365 struct stm32_rcc_regs *regs = priv->base; in stm32_get_timer_rate()
394 struct stm32_clk *priv = dev_get_priv(clk->dev); in stm32_clk_get_rate()
395 struct stm32_rcc_regs *regs = priv->base; in stm32_clk_get_rate()
403 if ((readl(®s->cfgr) & RCC_CFGR_SWS_MASK) == in stm32_clk_get_rate()
405 pllm = (readl(®s->pllcfgr) & RCC_PLLCFGR_PLLM_MASK); in stm32_clk_get_rate()
406 plln = ((readl(®s->pllcfgr) & RCC_PLLCFGR_PLLN_MASK) in stm32_clk_get_rate()
408 pllp = ((((readl(®s->pllcfgr) & RCC_PLLCFGR_PLLP_MASK) in stm32_clk_get_rate()
410 pllq = ((readl(®s->pllcfgr) & RCC_PLLCFGR_PLLQ_MASK) in stm32_clk_get_rate()
412 vco = (priv->hse_rate / pllm) * plln; in stm32_clk_get_rate()
415 return -EINVAL; in stm32_clk_get_rate()
418 switch (clk->id) { in stm32_clk_get_rate()
428 switch (clk->id) { in stm32_clk_get_rate()
444 switch (clk->id) { in stm32_clk_get_rate()
452 if (clk->id == STM32F7_APB2_CLOCK(SDMMC1)) in stm32_clk_get_rate()
457 if (readl(®s->dckcfgr2) & sdmmcxsel_bit) in stm32_clk_get_rate()
479 /* particular case for LTDC clock */ in stm32_clk_get_rate()
480 case STM32F7_APB2_CLOCK(LTDC): in stm32_clk_get_rate()
481 saidivr = readl(®s->dckcfgr); in stm32_clk_get_rate()
491 pr_err("clock index %ld out of range\n", clk->id); in stm32_clk_get_rate()
492 return -EINVAL; in stm32_clk_get_rate()
499 struct stm32_clk *priv = dev_get_priv(clk->dev); in stm32_set_rate()
500 struct stm32_rcc_regs *regs = priv->base; in stm32_set_rate()
508 /* Only set_rate for LTDC clock is implemented */ in stm32_set_rate()
509 if (clk->id != STM32F7_APB2_CLOCK(LTDC)) { in stm32_set_rate()
511 clk->id); in stm32_set_rate()
527 clrsetbits_le32(®s->dckcfgr, in stm32_set_rate()
560 current_rate - rate : rate - current_rate; in stm32_set_rate()
575 clrbits_le32(®s->cr, RCC_CR_PLLSAION); in stm32_set_rate()
578 clrsetbits_le32(®s->dckcfgr, RCC_DCKCFGR_PLLSAIDIVR_MASK, in stm32_set_rate()
582 clrsetbits_le32(®s->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIR_MASK, in stm32_set_rate()
587 setbits_le32(®s->cr, RCC_CR_PLLSAION); in stm32_set_rate()
588 while (!(readl(®s->cr) & RCC_CR_PLLSAIRDY)) in stm32_set_rate()
600 struct stm32_clk *priv = dev_get_priv(clk->dev); in stm32_clk_enable()
601 struct stm32_rcc_regs *regs = priv->base; in stm32_clk_enable()
602 u32 offset = clk->id / 32; in stm32_clk_enable()
603 u32 bit_index = clk->id % 32; in stm32_clk_enable()
606 __func__, clk->id, offset, bit_index); in stm32_clk_enable()
607 setbits_le32(®s->ahb1enr + offset, BIT(bit_index)); in stm32_clk_enable()
626 return -EINVAL; in stm32_clk_probe()
628 priv->base = (struct stm32_rcc_regs *)addr; in stm32_clk_probe()
629 priv->pllsaip = true; in stm32_clk_probe()
633 priv->pllsaip = false; in stm32_clk_probe()
636 memcpy(&priv->info, &stm32f4_clk_info, in stm32_clk_probe()
641 memcpy(&priv->info, &stm32f7_clk_info, in stm32_clk_probe()
645 return -EINVAL; in stm32_clk_probe()
649 err = uclass_get_device_by_name(UCLASS_CLK, "clk-hse", in stm32_clk_probe()
659 pr_err("Can't request %s clk (%d)", fixed_clock_dev->name, in stm32_clk_probe()
671 priv->hse_rate = clk_get_rate(&clk); in stm32_clk_probe()
673 if (priv->hse_rate < 1000000) { in stm32_clk_probe()
675 priv->hse_rate); in stm32_clk_probe()
676 return -EINVAL; in stm32_clk_probe()
679 priv->info.sys_pll_psc.pll_m = priv->hse_rate / 1000000; in stm32_clk_probe()
681 if (priv->info.has_overdrive) { in stm32_clk_probe()
690 priv->pwr_regs = (struct stm32_pwr_regs *)ofnode_get_addr(args.node); in stm32_clk_probe()
702 if (args->args_count != 2) { in stm32_clk_of_xlate()
703 debug("Invaild args_count: %d\n", args->args_count); in stm32_clk_of_xlate()
704 return -EINVAL; in stm32_clk_of_xlate()
707 if (args->args_count) in stm32_clk_of_xlate()
708 clk->id = args->args[1]; in stm32_clk_of_xlate()
710 clk->id = 0; in stm32_clk_of_xlate()