10a61ee88SVikas Manocha /*
20a61ee88SVikas Manocha * (C) Copyright 2015
30a61ee88SVikas Manocha * Kamil Lulko, <kamil.lulko@gmail.com>
40a61ee88SVikas Manocha *
50a61ee88SVikas Manocha * (C) Copyright 2014
60a61ee88SVikas Manocha * STMicroelectronics
70a61ee88SVikas Manocha *
80a61ee88SVikas Manocha * SPDX-License-Identifier: GPL-2.0+
90a61ee88SVikas Manocha */
100a61ee88SVikas Manocha
110a61ee88SVikas Manocha #include <common.h>
120a61ee88SVikas Manocha #include <asm/io.h>
130a61ee88SVikas Manocha #include <asm/arch/stm32.h>
14dffceb4bSVikas Manocha #include <asm/arch/stm32_periph.h>
150a61ee88SVikas Manocha
160a61ee88SVikas Manocha #define RCC_CR_HSION (1 << 0)
170a61ee88SVikas Manocha #define RCC_CR_HSEON (1 << 16)
180a61ee88SVikas Manocha #define RCC_CR_HSERDY (1 << 17)
190a61ee88SVikas Manocha #define RCC_CR_HSEBYP (1 << 18)
200a61ee88SVikas Manocha #define RCC_CR_CSSON (1 << 19)
210a61ee88SVikas Manocha #define RCC_CR_PLLON (1 << 24)
220a61ee88SVikas Manocha #define RCC_CR_PLLRDY (1 << 25)
230a61ee88SVikas Manocha
240a61ee88SVikas Manocha #define RCC_PLLCFGR_PLLM_MASK 0x3F
250a61ee88SVikas Manocha #define RCC_PLLCFGR_PLLN_MASK 0x7FC0
260a61ee88SVikas Manocha #define RCC_PLLCFGR_PLLP_MASK 0x30000
270a61ee88SVikas Manocha #define RCC_PLLCFGR_PLLQ_MASK 0xF000000
280a61ee88SVikas Manocha #define RCC_PLLCFGR_PLLSRC (1 << 22)
290a61ee88SVikas Manocha #define RCC_PLLCFGR_PLLN_SHIFT 6
300a61ee88SVikas Manocha #define RCC_PLLCFGR_PLLP_SHIFT 16
310a61ee88SVikas Manocha #define RCC_PLLCFGR_PLLQ_SHIFT 24
320a61ee88SVikas Manocha
330a61ee88SVikas Manocha #define RCC_CFGR_AHB_PSC_MASK 0xF0
340a61ee88SVikas Manocha #define RCC_CFGR_APB1_PSC_MASK 0x1C00
350a61ee88SVikas Manocha #define RCC_CFGR_APB2_PSC_MASK 0xE000
360a61ee88SVikas Manocha #define RCC_CFGR_SW0 (1 << 0)
370a61ee88SVikas Manocha #define RCC_CFGR_SW1 (1 << 1)
380a61ee88SVikas Manocha #define RCC_CFGR_SW_MASK 0x3
390a61ee88SVikas Manocha #define RCC_CFGR_SW_HSI 0
400a61ee88SVikas Manocha #define RCC_CFGR_SW_HSE RCC_CFGR_SW0
410a61ee88SVikas Manocha #define RCC_CFGR_SW_PLL RCC_CFGR_SW1
420a61ee88SVikas Manocha #define RCC_CFGR_SWS0 (1 << 2)
430a61ee88SVikas Manocha #define RCC_CFGR_SWS1 (1 << 3)
440a61ee88SVikas Manocha #define RCC_CFGR_SWS_MASK 0xC
450a61ee88SVikas Manocha #define RCC_CFGR_SWS_HSI 0
460a61ee88SVikas Manocha #define RCC_CFGR_SWS_HSE RCC_CFGR_SWS0
470a61ee88SVikas Manocha #define RCC_CFGR_SWS_PLL RCC_CFGR_SWS1
480a61ee88SVikas Manocha #define RCC_CFGR_HPRE_SHIFT 4
490a61ee88SVikas Manocha #define RCC_CFGR_PPRE1_SHIFT 10
500a61ee88SVikas Manocha #define RCC_CFGR_PPRE2_SHIFT 13
510a61ee88SVikas Manocha
520a61ee88SVikas Manocha #define RCC_APB1ENR_PWREN (1 << 28)
530a61ee88SVikas Manocha
54dffceb4bSVikas Manocha /*
55dffceb4bSVikas Manocha * RCC USART specific definitions
56dffceb4bSVikas Manocha */
57dffceb4bSVikas Manocha #define RCC_ENR_USART1EN (1 << 4)
58dffceb4bSVikas Manocha #define RCC_ENR_USART2EN (1 << 17)
59dffceb4bSVikas Manocha #define RCC_ENR_USART3EN (1 << 18)
60dffceb4bSVikas Manocha #define RCC_ENR_USART6EN (1 << 5)
61dffceb4bSVikas Manocha
620a61ee88SVikas Manocha #define PWR_CR_VOS0 (1 << 14)
630a61ee88SVikas Manocha #define PWR_CR_VOS1 (1 << 15)
640a61ee88SVikas Manocha #define PWR_CR_VOS_MASK 0xC000
650a61ee88SVikas Manocha #define PWR_CR_VOS_SCALE_MODE_1 (PWR_CR_VOS0 | PWR_CR_VOS1)
660a61ee88SVikas Manocha #define PWR_CR_VOS_SCALE_MODE_2 (PWR_CR_VOS1)
670a61ee88SVikas Manocha #define PWR_CR_VOS_SCALE_MODE_3 (PWR_CR_VOS0)
680a61ee88SVikas Manocha
6914cec061SVikas Manocha /*
7014cec061SVikas Manocha * RCC GPIO specific definitions
7114cec061SVikas Manocha */
7214cec061SVikas Manocha #define RCC_ENR_GPIO_A_EN (1 << 0)
7314cec061SVikas Manocha #define RCC_ENR_GPIO_B_EN (1 << 1)
7414cec061SVikas Manocha #define RCC_ENR_GPIO_C_EN (1 << 2)
7514cec061SVikas Manocha #define RCC_ENR_GPIO_D_EN (1 << 3)
7614cec061SVikas Manocha #define RCC_ENR_GPIO_E_EN (1 << 4)
7714cec061SVikas Manocha #define RCC_ENR_GPIO_F_EN (1 << 5)
7814cec061SVikas Manocha #define RCC_ENR_GPIO_G_EN (1 << 6)
7914cec061SVikas Manocha #define RCC_ENR_GPIO_H_EN (1 << 7)
8014cec061SVikas Manocha #define RCC_ENR_GPIO_I_EN (1 << 8)
8114cec061SVikas Manocha #define RCC_ENR_GPIO_J_EN (1 << 9)
8214cec061SVikas Manocha #define RCC_ENR_GPIO_K_EN (1 << 10)
8314cec061SVikas Manocha
840a61ee88SVikas Manocha struct pll_psc {
850a61ee88SVikas Manocha u8 pll_m;
860a61ee88SVikas Manocha u16 pll_n;
870a61ee88SVikas Manocha u8 pll_p;
880a61ee88SVikas Manocha u8 pll_q;
890a61ee88SVikas Manocha u8 ahb_psc;
900a61ee88SVikas Manocha u8 apb1_psc;
910a61ee88SVikas Manocha u8 apb2_psc;
920a61ee88SVikas Manocha };
930a61ee88SVikas Manocha
940a61ee88SVikas Manocha #define AHB_PSC_1 0
950a61ee88SVikas Manocha #define AHB_PSC_2 0x8
960a61ee88SVikas Manocha #define AHB_PSC_4 0x9
970a61ee88SVikas Manocha #define AHB_PSC_8 0xA
980a61ee88SVikas Manocha #define AHB_PSC_16 0xB
990a61ee88SVikas Manocha #define AHB_PSC_64 0xC
1000a61ee88SVikas Manocha #define AHB_PSC_128 0xD
1010a61ee88SVikas Manocha #define AHB_PSC_256 0xE
1020a61ee88SVikas Manocha #define AHB_PSC_512 0xF
1030a61ee88SVikas Manocha
1040a61ee88SVikas Manocha #define APB_PSC_1 0
1050a61ee88SVikas Manocha #define APB_PSC_2 0x4
1060a61ee88SVikas Manocha #define APB_PSC_4 0x5
1070a61ee88SVikas Manocha #define APB_PSC_8 0x6
1080a61ee88SVikas Manocha #define APB_PSC_16 0x7
1090a61ee88SVikas Manocha
1100a61ee88SVikas Manocha #if !defined(CONFIG_STM32_HSE_HZ)
1110a61ee88SVikas Manocha #error "CONFIG_STM32_HSE_HZ not defined!"
1120a61ee88SVikas Manocha #else
1130a61ee88SVikas Manocha #if (CONFIG_STM32_HSE_HZ == 8000000)
1140a61ee88SVikas Manocha #if (CONFIG_SYS_CLK_FREQ == 180000000)
1150a61ee88SVikas Manocha /* 180 MHz */
1160a61ee88SVikas Manocha struct pll_psc sys_pll_psc = {
1170a61ee88SVikas Manocha .pll_m = 8,
1180a61ee88SVikas Manocha .pll_n = 360,
1190a61ee88SVikas Manocha .pll_p = 2,
1200a61ee88SVikas Manocha .pll_q = 8,
1210a61ee88SVikas Manocha .ahb_psc = AHB_PSC_1,
1220a61ee88SVikas Manocha .apb1_psc = APB_PSC_4,
1230a61ee88SVikas Manocha .apb2_psc = APB_PSC_2
1240a61ee88SVikas Manocha };
1250a61ee88SVikas Manocha #else
1260a61ee88SVikas Manocha /* default 168 MHz */
1270a61ee88SVikas Manocha struct pll_psc sys_pll_psc = {
1280a61ee88SVikas Manocha .pll_m = 8,
1290a61ee88SVikas Manocha .pll_n = 336,
1300a61ee88SVikas Manocha .pll_p = 2,
1310a61ee88SVikas Manocha .pll_q = 7,
1320a61ee88SVikas Manocha .ahb_psc = AHB_PSC_1,
1330a61ee88SVikas Manocha .apb1_psc = APB_PSC_4,
1340a61ee88SVikas Manocha .apb2_psc = APB_PSC_2
1350a61ee88SVikas Manocha };
1360a61ee88SVikas Manocha #endif
1370a61ee88SVikas Manocha #else
1380a61ee88SVikas Manocha #error "No PLL/Prescaler configuration for given CONFIG_STM32_HSE_HZ exists"
1390a61ee88SVikas Manocha #endif
1400a61ee88SVikas Manocha #endif
1410a61ee88SVikas Manocha
configure_clocks(void)1420a61ee88SVikas Manocha int configure_clocks(void)
1430a61ee88SVikas Manocha {
1440a61ee88SVikas Manocha /* Reset RCC configuration */
1450a61ee88SVikas Manocha setbits_le32(&STM32_RCC->cr, RCC_CR_HSION);
1460a61ee88SVikas Manocha writel(0, &STM32_RCC->cfgr); /* Reset CFGR */
1470a61ee88SVikas Manocha clrbits_le32(&STM32_RCC->cr, (RCC_CR_HSEON | RCC_CR_CSSON
1480a61ee88SVikas Manocha | RCC_CR_PLLON));
1490a61ee88SVikas Manocha writel(0x24003010, &STM32_RCC->pllcfgr); /* Reset value from RM */
1500a61ee88SVikas Manocha clrbits_le32(&STM32_RCC->cr, RCC_CR_HSEBYP);
1510a61ee88SVikas Manocha writel(0, &STM32_RCC->cir); /* Disable all interrupts */
1520a61ee88SVikas Manocha
1530a61ee88SVikas Manocha /* Configure for HSE+PLL operation */
1540a61ee88SVikas Manocha setbits_le32(&STM32_RCC->cr, RCC_CR_HSEON);
1550a61ee88SVikas Manocha while (!(readl(&STM32_RCC->cr) & RCC_CR_HSERDY))
1560a61ee88SVikas Manocha ;
1570a61ee88SVikas Manocha
1580a61ee88SVikas Manocha /* Enable high performance mode, System frequency up to 180 MHz */
1590a61ee88SVikas Manocha setbits_le32(&STM32_RCC->apb1enr, RCC_APB1ENR_PWREN);
1600a61ee88SVikas Manocha writel(PWR_CR_VOS_SCALE_MODE_1, &STM32_PWR->cr);
1610a61ee88SVikas Manocha
1620a61ee88SVikas Manocha setbits_le32(&STM32_RCC->cfgr, ((
1630a61ee88SVikas Manocha sys_pll_psc.ahb_psc << RCC_CFGR_HPRE_SHIFT)
1640a61ee88SVikas Manocha | (sys_pll_psc.apb1_psc << RCC_CFGR_PPRE1_SHIFT)
1650a61ee88SVikas Manocha | (sys_pll_psc.apb2_psc << RCC_CFGR_PPRE2_SHIFT)));
1660a61ee88SVikas Manocha
1670a61ee88SVikas Manocha writel(sys_pll_psc.pll_m
1680a61ee88SVikas Manocha | (sys_pll_psc.pll_n << RCC_PLLCFGR_PLLN_SHIFT)
1690a61ee88SVikas Manocha | (((sys_pll_psc.pll_p >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT)
1700a61ee88SVikas Manocha | (sys_pll_psc.pll_q << RCC_PLLCFGR_PLLQ_SHIFT),
1710a61ee88SVikas Manocha &STM32_RCC->pllcfgr);
1720a61ee88SVikas Manocha setbits_le32(&STM32_RCC->pllcfgr, RCC_PLLCFGR_PLLSRC);
1730a61ee88SVikas Manocha
1740a61ee88SVikas Manocha setbits_le32(&STM32_RCC->cr, RCC_CR_PLLON);
1750a61ee88SVikas Manocha
1760a61ee88SVikas Manocha while (!(readl(&STM32_RCC->cr) & RCC_CR_PLLRDY))
1770a61ee88SVikas Manocha ;
1780a61ee88SVikas Manocha
179*9ecb0c41SVikas Manocha stm32_flash_latency_cfg(5);
1800a61ee88SVikas Manocha clrbits_le32(&STM32_RCC->cfgr, (RCC_CFGR_SW0 | RCC_CFGR_SW1));
1810a61ee88SVikas Manocha setbits_le32(&STM32_RCC->cfgr, RCC_CFGR_SW_PLL);
1820a61ee88SVikas Manocha
1830a61ee88SVikas Manocha while ((readl(&STM32_RCC->cfgr) & RCC_CFGR_SWS_MASK) !=
1840a61ee88SVikas Manocha RCC_CFGR_SWS_PLL)
1850a61ee88SVikas Manocha ;
1860a61ee88SVikas Manocha
1870a61ee88SVikas Manocha return 0;
1880a61ee88SVikas Manocha }
1890a61ee88SVikas Manocha
clock_get(enum clock clck)1900a61ee88SVikas Manocha unsigned long clock_get(enum clock clck)
1910a61ee88SVikas Manocha {
1920a61ee88SVikas Manocha u32 sysclk = 0;
1930a61ee88SVikas Manocha u32 shift = 0;
1940a61ee88SVikas Manocha /* Prescaler table lookups for clock computation */
1950a61ee88SVikas Manocha u8 ahb_psc_table[16] = {
1960a61ee88SVikas Manocha 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9
1970a61ee88SVikas Manocha };
1980a61ee88SVikas Manocha u8 apb_psc_table[8] = {
1990a61ee88SVikas Manocha 0, 0, 0, 0, 1, 2, 3, 4
2000a61ee88SVikas Manocha };
2010a61ee88SVikas Manocha
2020a61ee88SVikas Manocha if ((readl(&STM32_RCC->cfgr) & RCC_CFGR_SWS_MASK) ==
2030a61ee88SVikas Manocha RCC_CFGR_SWS_PLL) {
2040a61ee88SVikas Manocha u16 pllm, plln, pllp;
2050a61ee88SVikas Manocha pllm = (readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLM_MASK);
2060a61ee88SVikas Manocha plln = ((readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLN_MASK)
2070a61ee88SVikas Manocha >> RCC_PLLCFGR_PLLN_SHIFT);
2080a61ee88SVikas Manocha pllp = ((((readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLP_MASK)
2090a61ee88SVikas Manocha >> RCC_PLLCFGR_PLLP_SHIFT) + 1) << 1);
2100a61ee88SVikas Manocha sysclk = ((CONFIG_STM32_HSE_HZ / pllm) * plln) / pllp;
2110a61ee88SVikas Manocha }
2120a61ee88SVikas Manocha
2130a61ee88SVikas Manocha switch (clck) {
2140a61ee88SVikas Manocha case CLOCK_CORE:
2150a61ee88SVikas Manocha return sysclk;
2160a61ee88SVikas Manocha break;
2170a61ee88SVikas Manocha case CLOCK_AHB:
2180a61ee88SVikas Manocha shift = ahb_psc_table[(
2190a61ee88SVikas Manocha (readl(&STM32_RCC->cfgr) & RCC_CFGR_AHB_PSC_MASK)
2200a61ee88SVikas Manocha >> RCC_CFGR_HPRE_SHIFT)];
2210a61ee88SVikas Manocha return sysclk >>= shift;
2220a61ee88SVikas Manocha break;
2230a61ee88SVikas Manocha case CLOCK_APB1:
2240a61ee88SVikas Manocha shift = apb_psc_table[(
2250a61ee88SVikas Manocha (readl(&STM32_RCC->cfgr) & RCC_CFGR_APB1_PSC_MASK)
2260a61ee88SVikas Manocha >> RCC_CFGR_PPRE1_SHIFT)];
2270a61ee88SVikas Manocha return sysclk >>= shift;
2280a61ee88SVikas Manocha break;
2290a61ee88SVikas Manocha case CLOCK_APB2:
2300a61ee88SVikas Manocha shift = apb_psc_table[(
2310a61ee88SVikas Manocha (readl(&STM32_RCC->cfgr) & RCC_CFGR_APB2_PSC_MASK)
2320a61ee88SVikas Manocha >> RCC_CFGR_PPRE2_SHIFT)];
2330a61ee88SVikas Manocha return sysclk >>= shift;
2340a61ee88SVikas Manocha break;
2350a61ee88SVikas Manocha default:
2360a61ee88SVikas Manocha return 0;
2370a61ee88SVikas Manocha break;
2380a61ee88SVikas Manocha }
2390a61ee88SVikas Manocha }
240dffceb4bSVikas Manocha
clock_setup(int peripheral)241dffceb4bSVikas Manocha void clock_setup(int peripheral)
242dffceb4bSVikas Manocha {
243dffceb4bSVikas Manocha switch (peripheral) {
244dffceb4bSVikas Manocha case USART1_CLOCK_CFG:
245dffceb4bSVikas Manocha setbits_le32(&STM32_RCC->apb2enr, RCC_ENR_USART1EN);
246dffceb4bSVikas Manocha break;
24714cec061SVikas Manocha case GPIO_A_CLOCK_CFG:
24814cec061SVikas Manocha setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_A_EN);
24914cec061SVikas Manocha break;
25014cec061SVikas Manocha case GPIO_B_CLOCK_CFG:
25114cec061SVikas Manocha setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_B_EN);
25214cec061SVikas Manocha break;
25314cec061SVikas Manocha case GPIO_C_CLOCK_CFG:
25414cec061SVikas Manocha setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_C_EN);
25514cec061SVikas Manocha break;
25614cec061SVikas Manocha case GPIO_D_CLOCK_CFG:
25714cec061SVikas Manocha setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_D_EN);
25814cec061SVikas Manocha break;
25914cec061SVikas Manocha case GPIO_E_CLOCK_CFG:
26014cec061SVikas Manocha setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_E_EN);
26114cec061SVikas Manocha break;
26214cec061SVikas Manocha case GPIO_F_CLOCK_CFG:
26314cec061SVikas Manocha setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_F_EN);
26414cec061SVikas Manocha break;
26514cec061SVikas Manocha case GPIO_G_CLOCK_CFG:
26614cec061SVikas Manocha setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_G_EN);
26714cec061SVikas Manocha break;
26814cec061SVikas Manocha case GPIO_H_CLOCK_CFG:
26914cec061SVikas Manocha setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_H_EN);
27014cec061SVikas Manocha break;
27114cec061SVikas Manocha case GPIO_I_CLOCK_CFG:
27214cec061SVikas Manocha setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_I_EN);
27314cec061SVikas Manocha break;
27414cec061SVikas Manocha case GPIO_J_CLOCK_CFG:
27514cec061SVikas Manocha setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_J_EN);
27614cec061SVikas Manocha break;
27714cec061SVikas Manocha case GPIO_K_CLOCK_CFG:
27814cec061SVikas Manocha setbits_le32(&STM32_RCC->ahb1enr, RCC_ENR_GPIO_K_EN);
27914cec061SVikas Manocha break;
280dffceb4bSVikas Manocha default:
281dffceb4bSVikas Manocha break;
282dffceb4bSVikas Manocha }
283dffceb4bSVikas Manocha }
284