clk_stm32f7.c 8.5 KB
Newer Older
1
/*
2 3
 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
 * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
4 5 6
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */
7

8
#include <common.h>
9 10
#include <clk-uclass.h>
#include <dm.h>
11

12 13 14 15
#include <asm/io.h>
#include <asm/arch/rcc.h>
#include <asm/arch/stm32.h>
#include <asm/arch/stm32_periph.h>
16
#include <asm/arch/stm32_pwr.h>
17

18 19
#include <dt-bindings/mfd/stm32f7-rcc.h>

M
Michael Kurz 已提交
20 21 22 23 24 25 26
#define RCC_CR_HSION			BIT(0)
#define RCC_CR_HSEON			BIT(16)
#define RCC_CR_HSERDY			BIT(17)
#define RCC_CR_HSEBYP			BIT(18)
#define RCC_CR_CSSON			BIT(19)
#define RCC_CR_PLLON			BIT(24)
#define RCC_CR_PLLRDY			BIT(25)
27

M
Michael Kurz 已提交
28 29 30 31 32 33 34 35 36
#define RCC_PLLCFGR_PLLM_MASK		GENMASK(5, 0)
#define RCC_PLLCFGR_PLLN_MASK		GENMASK(14, 6)
#define RCC_PLLCFGR_PLLP_MASK		GENMASK(17, 16)
#define RCC_PLLCFGR_PLLQ_MASK		GENMASK(27, 24)
#define RCC_PLLCFGR_PLLSRC		BIT(22)
#define RCC_PLLCFGR_PLLM_SHIFT		0
#define RCC_PLLCFGR_PLLN_SHIFT		6
#define RCC_PLLCFGR_PLLP_SHIFT		16
#define RCC_PLLCFGR_PLLQ_SHIFT		24
37

M
Michael Kurz 已提交
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
#define RCC_CFGR_AHB_PSC_MASK		GENMASK(7, 4)
#define RCC_CFGR_APB1_PSC_MASK		GENMASK(12, 10)
#define RCC_CFGR_APB2_PSC_MASK		GENMASK(15, 13)
#define RCC_CFGR_SW0			BIT(0)
#define RCC_CFGR_SW1			BIT(1)
#define RCC_CFGR_SW_MASK		GENMASK(1, 0)
#define RCC_CFGR_SW_HSI			0
#define RCC_CFGR_SW_HSE			RCC_CFGR_SW0
#define RCC_CFGR_SW_PLL			RCC_CFGR_SW1
#define RCC_CFGR_SWS0			BIT(2)
#define RCC_CFGR_SWS1			BIT(3)
#define RCC_CFGR_SWS_MASK		GENMASK(3, 2)
#define RCC_CFGR_SWS_HSI		0
#define RCC_CFGR_SWS_HSE		RCC_CFGR_SWS0
#define RCC_CFGR_SWS_PLL		RCC_CFGR_SWS1
#define RCC_CFGR_HPRE_SHIFT		4
#define RCC_CFGR_PPRE1_SHIFT		10
#define RCC_CFGR_PPRE2_SHIFT		13
56 57 58 59 60 61 62 63 64 65 66 67


struct pll_psc {
	u8	pll_m;
	u16	pll_n;
	u8	pll_p;
	u8	pll_q;
	u8	ahb_psc;
	u8	apb1_psc;
	u8	apb2_psc;
};

M
Michael Kurz 已提交
68 69 70 71 72 73 74 75 76
#define AHB_PSC_1			0
#define AHB_PSC_2			0x8
#define AHB_PSC_4			0x9
#define AHB_PSC_8			0xA
#define AHB_PSC_16			0xB
#define AHB_PSC_64			0xC
#define AHB_PSC_128			0xD
#define AHB_PSC_256			0xE
#define AHB_PSC_512			0xF
77

M
Michael Kurz 已提交
78 79 80 81 82
#define APB_PSC_1			0
#define APB_PSC_2			0x4
#define APB_PSC_4			0x5
#define APB_PSC_8			0x6
#define APB_PSC_16			0x7
83

84 85
struct stm32_clk {
	struct stm32_rcc_regs *base;
86
	struct stm32_pwr_regs *pwr_regs;
87 88
};

89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
#if !defined(CONFIG_STM32_HSE_HZ)
#error "CONFIG_STM32_HSE_HZ not defined!"
#else
#if (CONFIG_STM32_HSE_HZ == 25000000)
#if (CONFIG_SYS_CLK_FREQ == 200000000)
/* 200 MHz */
struct pll_psc sys_pll_psc = {
	.pll_m = 25,
	.pll_n = 400,
	.pll_p = 2,
	.pll_q = 8,
	.ahb_psc = AHB_PSC_1,
	.apb1_psc = APB_PSC_4,
	.apb2_psc = APB_PSC_2
};
#endif
#else
#error "No PLL/Prescaler configuration for given CONFIG_STM32_HSE_HZ exists"
#endif
#endif

110
static int configure_clocks(struct udevice *dev)
111
{
112 113
	struct stm32_clk *priv = dev_get_priv(dev);
	struct stm32_rcc_regs *regs = priv->base;
114
	struct stm32_pwr_regs *pwr = priv->pwr_regs;
115

116
	/* Reset RCC configuration */
117 118 119
	setbits_le32(&regs->cr, RCC_CR_HSION);
	writel(0, &regs->cfgr); /* Reset CFGR */
	clrbits_le32(&regs->cr, (RCC_CR_HSEON | RCC_CR_CSSON
120
		| RCC_CR_PLLON));
121 122 123
	writel(0x24003010, &regs->pllcfgr); /* Reset value from RM */
	clrbits_le32(&regs->cr, RCC_CR_HSEBYP);
	writel(0, &regs->cir); /* Disable all interrupts */
124 125

	/* Configure for HSE+PLL operation */
126 127
	setbits_le32(&regs->cr, RCC_CR_HSEON);
	while (!(readl(&regs->cr) & RCC_CR_HSERDY))
128 129
		;

130
	setbits_le32(&regs->cfgr, ((
131 132 133 134 135
		sys_pll_psc.ahb_psc << RCC_CFGR_HPRE_SHIFT)
		| (sys_pll_psc.apb1_psc << RCC_CFGR_PPRE1_SHIFT)
		| (sys_pll_psc.apb2_psc << RCC_CFGR_PPRE2_SHIFT)));

	/* Configure the main PLL */
136 137 138 139 140 141 142 143 144
	setbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLSRC); /* pll source HSE */
	clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLM_MASK,
			sys_pll_psc.pll_m << RCC_PLLCFGR_PLLM_SHIFT);
	clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLN_MASK,
			sys_pll_psc.pll_n << RCC_PLLCFGR_PLLN_SHIFT);
	clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLP_MASK,
			((sys_pll_psc.pll_p >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT);
	clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLQ_MASK,
			sys_pll_psc.pll_q << RCC_PLLCFGR_PLLQ_SHIFT);
145 146

	/* Enable the main PLL */
147 148
	setbits_le32(&regs->cr, RCC_CR_PLLON);
	while (!(readl(&regs->cr) & RCC_CR_PLLRDY))
149 150 151
		;

	/* Enable high performance mode, System frequency up to 200 MHz */
152
	setbits_le32(&regs->apb1enr, RCC_APB1ENR_PWREN);
153
	setbits_le32(&pwr->cr1, PWR_CR1_ODEN);
154
	/* Infinite wait! */
155
	while (!(readl(&pwr->csr1) & PWR_CSR1_ODRDY))
156 157
		;
	/* Enable the Over-drive switch */
158
	setbits_le32(&pwr->cr1, PWR_CR1_ODSWEN);
159
	/* Infinite wait! */
160
	while (!(readl(&pwr->csr1) & PWR_CSR1_ODSWRDY))
161 162 163
		;

	stm32_flash_latency_cfg(5);
164 165
	clrbits_le32(&regs->cfgr, (RCC_CFGR_SW0 | RCC_CFGR_SW1));
	setbits_le32(&regs->cfgr, RCC_CFGR_SW_PLL);
166

167
	while ((readl(&regs->cfgr) & RCC_CFGR_SWS_MASK) !=
168 169 170 171 172 173
			RCC_CFGR_SWS_PLL)
		;

	return 0;
}

174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
static unsigned long stm32_clk_get_rate(struct clk *clk)
{
	struct stm32_clk *priv = dev_get_priv(clk->dev);
	struct stm32_rcc_regs *regs = priv->base;
	u32 sysclk = 0;
	u32 shift = 0;
	/* Prescaler table lookups for clock computation */
	u8 ahb_psc_table[16] = {
		0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9
	};
	u8 apb_psc_table[8] = {
		0, 0, 0, 0, 1, 2, 3, 4
	};

	if ((readl(&regs->cfgr) & RCC_CFGR_SWS_MASK) ==
			RCC_CFGR_SWS_PLL) {
		u16 pllm, plln, pllp;
		pllm = (readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLM_MASK);
		plln = ((readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLN_MASK)
			>> RCC_PLLCFGR_PLLN_SHIFT);
		pllp = ((((readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLP_MASK)
			>> RCC_PLLCFGR_PLLP_SHIFT) + 1) << 1);
		sysclk = ((CONFIG_STM32_HSE_HZ / pllm) * plln) / pllp;
	} else {
		return -EINVAL;
	}

	switch (clk->id) {
	/*
	 * AHB CLOCK: 3 x 32 bits consecutive registers are used :
	 * AHB1, AHB2 and AHB3
	 */
	case STM32F7_AHB1_CLOCK(GPIOA) ... STM32F7_AHB3_CLOCK(QSPI):
		shift = ahb_psc_table[(
			(readl(&regs->cfgr) & RCC_CFGR_AHB_PSC_MASK)
			>> RCC_CFGR_HPRE_SHIFT)];
		return sysclk >>= shift;
		break;
	/* APB1 CLOCK */
	case STM32F7_APB1_CLOCK(TIM2) ... STM32F7_APB1_CLOCK(UART8):
		shift = apb_psc_table[(
			(readl(&regs->cfgr) & RCC_CFGR_APB1_PSC_MASK)
			>> RCC_CFGR_PPRE1_SHIFT)];
		return sysclk >>= shift;
		break;
	/* APB2 CLOCK */
	case STM32F7_APB2_CLOCK(TIM1) ... STM32F7_APB2_CLOCK(LTDC):
		shift = apb_psc_table[(
			(readl(&regs->cfgr) & RCC_CFGR_APB2_PSC_MASK)
			>> RCC_CFGR_PPRE2_SHIFT)];
		return sysclk >>= shift;
		break;
	default:
227
		pr_err("clock index %ld out of range\n", clk->id);
228 229 230 231 232
		return -EINVAL;
		break;
	}
}

233 234
static int stm32_clk_enable(struct clk *clk)
{
235 236
	struct stm32_clk *priv = dev_get_priv(clk->dev);
	struct stm32_rcc_regs *regs = priv->base;
237 238 239 240 241
	u32 offset = clk->id / 32;
	u32 bit_index = clk->id % 32;

	debug("%s: clkid = %ld, offset from AHB1ENR is %d, bit_index = %d\n",
	      __func__, clk->id, offset, bit_index);
242
	setbits_le32(&regs->ahb1enr + offset, BIT(bit_index));
243 244 245

	return 0;
}
246

247 248 249
void clock_setup(int peripheral)
{
	switch (peripheral) {
250 251 252 253 254 255
	case SYSCFG_CLOCK_CFG:
		setbits_le32(&STM32_RCC->apb2enr, RCC_APB2ENR_SYSCFGEN);
		break;
	case TIMER2_CLOCK_CFG:
		setbits_le32(&STM32_RCC->apb1enr, RCC_APB1ENR_TIM2EN);
		break;
256 257 258 259 260
	case STMMAC_CLOCK_CFG:
		setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_ETHMAC_EN);
		setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_ETHMAC_RX_EN);
		setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_ETHMAC_TX_EN);
		break;
261 262 263 264
	default:
		break;
	}
}
265 266 267

static int stm32_clk_probe(struct udevice *dev)
{
268 269 270
	struct ofnode_phandle_args args;
	int err;

271
	debug("%s: stm32_clk_probe\n", __func__);
272 273 274 275 276 277 278 279 280 281

	struct stm32_clk *priv = dev_get_priv(dev);
	fdt_addr_t addr;

	addr = devfdt_get_addr(dev);
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;

	priv->base = (struct stm32_rcc_regs *)addr;

282 283 284 285 286 287 288 289 290 291
	err = dev_read_phandle_with_args(dev, "st,syscfg", NULL, 0, 0,
					 &args);
	if (err) {
		debug("%s: can't find syscon device (%d)\n", __func__,
		      err);
		return err;
	}

	priv->pwr_regs = (struct stm32_pwr_regs *)ofnode_get_addr(args.node);

292
	configure_clocks(dev);
293 294 295 296

	return 0;
}

297
static int stm32_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
{
	debug("%s(clk=%p)\n", __func__, clk);

	if (args->args_count != 2) {
		debug("Invaild args_count: %d\n", args->args_count);
		return -EINVAL;
	}

	if (args->args_count)
		clk->id = args->args[1];
	else
		clk->id = 0;

	return 0;
}

static struct clk_ops stm32_clk_ops = {
	.of_xlate	= stm32_clk_of_xlate,
	.enable		= stm32_clk_enable,
317
	.get_rate	= stm32_clk_get_rate,
318 319 320 321 322 323 324 325
};

static const struct udevice_id stm32_clk_ids[] = {
	{ .compatible = "st,stm32f42xx-rcc"},
	{}
};

U_BOOT_DRIVER(stm32f7_clk) = {
326 327 328 329 330 331 332
	.name			= "stm32f7_clk",
	.id			= UCLASS_CLK,
	.of_match		= stm32_clk_ids,
	.ops			= &stm32_clk_ops,
	.probe			= stm32_clk_probe,
	.priv_auto_alloc_size	= sizeof(struct stm32_clk),
	.flags			= DM_FLAG_PRE_RELOC,
333
};