2 * PLL and clocks configurations for
3 * Qualcomm/Atheros AR934x and QCA95xx WiSoCs
5 * Copyright (C) 2016 Piotr Dymacz <piotr@dymacz.pl>
7 * SPDX-License-Identifier: GPL-2.0
10 #include <soc/qca_pll_list.h>
12 #include <soc/qca_soc_common.h>
13 #include <soc/qca95xx_pll_init.h>
14 #include <asm/regdef.h>
15 #include <asm/mipsregs.h>
16 #include <asm/addrspace.h>
18 #define reg_oc_recovery t0
19 #define reg_spi_ctrl_cfg t1
20 #define reg_ref_clk_val t2
21 #define reg_cpu_pll_cfg t3
22 #define reg_ddr_pll_cfg t4
23 #define reg_cpu_ddr_clk t5
24 #define reg_cpu_pll_dit t6
25 #define reg_ddr_pll_dit t7
27 /* Sanity check for O/C recovery button number */
28 #ifdef CONFIG_QCA_GPIO_OC_RECOVERY_BTN
29 #if (CONFIG_QCA_GPIO_OC_RECOVERY_BTN >= QCA_GPIO_COUNT)
30 #error "O/C recovery button number is not correct!"
33 #define CONFIG_QCA_GPIO_MASK_OC_RECOVERY_BTN \
34 (1 << CONFIG_QCA_GPIO_OC_RECOVERY_BTN)
38 .type lowlevel_init, @function
46 * Get reference clock (XTAL) type, based on BOOTSTRAP register
47 * and save its value in one register for later use
49 li reg_ref_clk_val, 25
50 li t8, QCA_RST_BOOTSTRAP_REG
52 li t8, QCA_RST_BOOTSTRAP_REF_CLK_MASK
54 bgtz t9, set_xtal_40mhz
61 li reg_ref_clk_val, 40
65 * 1. First reset RTC submodule using RST_RESET register
66 * 2. Then use RTC_SYNC_RESET register
67 * 3. And at the end, wait for ON_STATE bit set in RTC_SYNC_STATUS register
69 * TODO: do we need to reset RTC at all?
72 li t8, QCA_RST_RST_REG
74 or t9, t9, QCA_RST_RESET_RTC_RST_MASK
80 and t9, t9, ~QCA_RST_RESET_RTC_RST_MASK
84 li t8, QCA_RTC_SYNC_RST_REG
90 li t9, QCA_RTC_SYNC_RST_RESET_MASK
94 li t8, QCA_RTC_SYNC_STATUS_REG
98 and t9, t9, QCA_RTC_SYNC_STATUS_ON_MASK
103 * O/C recovery mode (start with safe PLL/clocks configuration):
104 * 1. Check if defined recovery button is pressed
105 * 2. Indicate recovery mode in predefined register
106 * 3. If in recovery mode, do not use PLL configuration from FLASH,
107 * because it is probably the reason why user is using recovery mode
109 #ifdef CONFIG_QCA_GPIO_OC_RECOVERY_BTN
110 is_oc_recovery_btn_pressed:
111 li reg_oc_recovery, 0
112 li t8, QCA_GPIO_IN_REG
114 and t9, t9, CONFIG_QCA_GPIO_MASK_OC_RECOVERY_BTN
116 #ifdef CONFIG_QCA_GPIO_OC_RECOVERY_BTN_ACTIVE_LOW
117 bne t9, CONFIG_QCA_GPIO_MASK_OC_RECOVERY_BTN, in_oc_recovery_mode
120 beq t9, CONFIG_QCA_GPIO_MASK_OC_RECOVERY_BTN, in_oc_recovery_mode
124 #ifdef CONFIG_QCA_PLL_IN_FLASH_MAGIC_OFFSET
125 b is_pll_cfg_in_flash
132 li reg_oc_recovery, 1
135 #endif /* CONFIG_QCA_GPIO_OC_RECOVERY_BTN */
138 * Check if PLL configuration is stored in FLASH:
139 * 1. Get 32-bit value from defined offset in FLASH
140 * 2. Compare it with predefined magic value
141 * 3. If values are not equal, continue default PLL/clocks configuration
142 * 4. If values are equal it means we should have target PLL/clocks register
143 * values stored in FLASH, just after magic value, in the following order:
144 * - SPI_CONTROL (offset 4)
145 * - CPU_PLL_CONFIG (offset 8)
146 * - DDR_PLL_CONFIG (offset 12)
147 * - CPU_DDR_CLOCK_CONTROL (offset 16)
148 * - CPU_PLL_DITHER (offset 20)
149 * - DDR_PLL_DITHER (offset 24)
150 * 5. After loading target values from FLASH,
151 * jump directly to PLL/clocks configuration
153 #ifdef CONFIG_QCA_PLL_IN_FLASH_MAGIC_OFFSET
155 li t8, CONFIG_QCA_PLL_IN_FLASH_MAGIC_OFFSET
157 bne t9, QCA_PLL_IN_FLASH_MAGIC, xtal_type_check
161 lw reg_spi_ctrl_cfg, 4(t8)
162 lw reg_cpu_pll_cfg, 8(t8)
163 lw reg_ddr_pll_cfg, 12(t8)
164 lw reg_cpu_ddr_clk, 16(t8)
165 lw reg_cpu_pll_dit, 20(t8)
166 lw reg_ddr_pll_dit, 24(t8)
167 b cpu_ddr_clock_control
169 #endif /* CONFIG_QCA_PLL_IN_FLASH_MAGIC_OFFSET */
172 * Check XTAL type and include dedicated PLL/clocks values,
173 * predefined in header file, based on selected preset configuration
176 beq reg_ref_clk_val, 40, xtal_is_40mhz
180 #ifdef CONFIG_QCA_GPIO_OC_RECOVERY_BTN
181 beq reg_oc_recovery, 1, xtal_is_25mhz_recovery
185 li reg_spi_ctrl_cfg, QCA_SPI_CTRL_REG_VAL
186 li reg_cpu_pll_cfg, QCA_PLL_CPU_PLL_CFG_REG_VAL_XTAL25
187 li reg_ddr_pll_cfg, QCA_PLL_DDR_PLL_CFG_REG_VAL_XTAL25
188 li reg_cpu_ddr_clk, QCA_PLL_CPU_DDR_CLK_CTRL_REG_VAL_XTAL25
189 li reg_cpu_pll_dit, QCA_PLL_CPU_PLL_DITHER_REG_VAL_XTAL25
190 li reg_ddr_pll_dit, QCA_PLL_DDR_PLL_DITHER_REG_VAL_XTAL25
191 b cpu_ddr_clock_control
194 #ifdef CONFIG_QCA_GPIO_OC_RECOVERY_BTN
195 xtal_is_25mhz_recovery:
196 li reg_spi_ctrl_cfg, QCA_SPI_CTRL_REG_VAL_SAFE
197 li reg_cpu_pll_cfg, QCA_PLL_CPU_PLL_CFG_REG_VAL_SAFE_XTAL25
198 li reg_ddr_pll_cfg, QCA_PLL_DDR_PLL_CFG_REG_VAL_SAFE_XTAL25
199 li reg_cpu_ddr_clk, QCA_PLL_CPU_DDR_CLK_CTRL_REG_VAL_SAFE_XTAL25
200 li reg_cpu_pll_dit, QCA_PLL_CPU_PLL_DITHER_REG_VAL_SAFE_XTAL25
201 li reg_ddr_pll_dit, QCA_PLL_DDR_PLL_DITHER_REG_VAL_SAFE_XTAL25
202 b cpu_ddr_clock_control
207 #ifdef CONFIG_QCA_GPIO_OC_RECOVERY_BTN
208 beq reg_oc_recovery, 1, xtal_is_40mhz_recovery
212 li reg_spi_ctrl_cfg, QCA_SPI_CTRL_REG_VAL
213 li reg_cpu_pll_cfg, QCA_PLL_CPU_PLL_CFG_REG_VAL_XTAL40
214 li reg_ddr_pll_cfg, QCA_PLL_DDR_PLL_CFG_REG_VAL_XTAL40
215 li reg_cpu_ddr_clk, QCA_PLL_CPU_DDR_CLK_CTRL_REG_VAL_XTAL40
216 li reg_cpu_pll_dit, QCA_PLL_CPU_PLL_DITHER_REG_VAL_XTAL40
217 li reg_ddr_pll_dit, QCA_PLL_DDR_PLL_DITHER_REG_VAL_XTAL40
219 #ifdef CONFIG_QCA_GPIO_OC_RECOVERY_BTN
220 b cpu_ddr_clock_control
223 xtal_is_40mhz_recovery:
224 li reg_spi_ctrl_cfg, QCA_SPI_CTRL_REG_VAL_SAFE
225 li reg_cpu_pll_cfg, QCA_PLL_CPU_PLL_CFG_REG_VAL_SAFE_XTAL40
226 li reg_ddr_pll_cfg, QCA_PLL_DDR_PLL_CFG_REG_VAL_SAFE_XTAL40
227 li reg_cpu_ddr_clk, QCA_PLL_CPU_DDR_CLK_CTRL_REG_VAL_SAFE_XTAL40
228 li reg_cpu_pll_dit, QCA_PLL_CPU_PLL_DITHER_REG_VAL_SAFE_XTAL40
229 li reg_ddr_pll_dit, QCA_PLL_DDR_PLL_DITHER_REG_VAL_SAFE_XTAL40
233 * Load target value into CPU_DDR_CLOCK_CONTROL register,
234 * but for now keep bypass enabled for all clocks (CPU, DDR, AHB)
235 * (by default, after reset, they should be bypassed, do it just in case)
237 cpu_ddr_clock_control:
238 li t8, QCA_PLL_CPU_DDR_CLK_CTRL_REG
239 move t9, reg_cpu_ddr_clk
240 or t9, t9, (QCA_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS_MASK |\
241 QCA_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS_MASK |\
242 QCA_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS_MASK)
246 * Load target values into CPU/DDR_PLL_CONFIG registers, but for now keep PLLs down
247 * (by default, after reset, it should be powered down, do it just in case)
250 li t8, QCA_PLL_CPU_PLL_CFG_REG
251 move t9, reg_cpu_pll_cfg
252 or t9, t9, QCA_PLL_CPU_PLL_CFG_PLLPWD_MASK
256 li t8, QCA_PLL_DDR_PLL_CFG_REG
257 move t9, reg_ddr_pll_cfg
258 or t9, t9, QCA_PLL_DDR_PLL_CFG_PLLPWD_MASK
261 /* Load target NFRAC_MIN values into CPU/DDR_PLL_DITHER registers */
263 li t8, QCA_PLL_CPU_PLL_DITHER_REG
265 and t9, t9, ~QCA_PLL_CPU_PLL_DITHER_NFRAC_MIN_MASK
266 or t9, t9, reg_cpu_pll_dit
270 li t8, QCA_PLL_DDR_PLL_DITHER_REG
272 and t9, t9, ~QCA_PLL_DDR_PLL_DITHER_NFRAC_MIN_MASK
273 or t9, t9, reg_ddr_pll_dit
276 /* Disable PLL configuration over SRIF registers (just for sure) */
277 cpu_pll_srif_disable:
278 li t8, QCA_PLL_SRIF_CPU_DPLL2_REG
280 and t9, t9, ~QCA_PLL_SRIF_DPLL2_LOCAL_PLL_MASK
283 ddr_pll_srif_disable:
284 li t8, QCA_PLL_SRIF_DDR_DPLL2_REG
286 and t9, t9, ~QCA_PLL_SRIF_DPLL2_LOCAL_PLL_MASK
289 /* Enable CPU PLL (only if we need it) and wait for update complete */
291 move t8, reg_cpu_pll_cfg
292 and t8, t8, QCA_PLL_CPU_PLL_CFG_PLLPWD_MASK
293 bgtz t8, ddr_pll_enable
295 li t8, QCA_PLL_CPU_PLL_CFG_REG
297 and t9, t9, ~QCA_PLL_CPU_PLL_CFG_PLLPWD_MASK
301 /* Wait for CPU PLL update complete */
304 and t9, t9, QCA_PLL_CPU_PLL_CFG_UPDATING_MASK
305 bgtz t9, cpu_pll_wait
308 /* Enable DDR PLL (only if we need it) and wait for update complete */
310 move t8, reg_ddr_pll_cfg
311 and t8, t8, QCA_PLL_DDR_PLL_CFG_PLLPWD_MASK
312 bgtz t8, pll_bypass_disable
314 li t8, QCA_PLL_DDR_PLL_CFG_REG
316 and t9, t9, ~QCA_PLL_DDR_PLL_CFG_PLLPWD_MASK
320 /* Wait for DDR PLL update complete */
323 and t9, t9, QCA_PLL_DDR_PLL_CFG_UPDATING_MASK
324 bgtz t9, ddr_pll_wait
327 /* Disable bypassing all clocks */
329 li t8, QCA_PLL_CPU_DDR_CLK_CTRL_REG
331 and t9, t9, ~(QCA_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS_MASK |\
332 QCA_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS_MASK |\
333 QCA_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS_MASK)
336 /* Setup SPI (clock and other settings) */
339 #ifdef CONFIG_QCA_PLL_SPI_FLASH_CLK_AUTO
341 * Configure SPI FLASH and clock:
342 * 1. Check which PLL is used to drive AHB clock
343 * 2. Calculate selected PLL output value
344 * 3. Calculate target AHB clock value
345 * 4. Find minimum divider for SPI clock
346 * 5. Setup SPI FLASH clock and other related options (REMAP, etc.)
348 li t8, QCA_PLL_CPU_DDR_CLK_CTRL_REG
351 and t3, t9, QCA_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK
352 srl t3, t3, QCA_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT
353 /* t3 = AHB_POST_DIV + 1 */
356 /* Find out where AHB clock come from (CPU or DDR PLL) */
357 and t9, t9, QCA_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_MASK
358 bgtz t9, ahb_clk_from_ddr_pll
361 ahb_clk_from_cpu_pll:
362 li t8, QCA_PLL_CPU_PLL_CFG_REG
366 and t8, t9, QCA_PLL_CPU_PLL_CFG_NINT_MASK
367 srl t8, t8, QCA_PLL_CPU_PLL_CFG_NINT_SHIFT
368 mul t4, t8, reg_ref_clk_val /* t4 = REFCLK * NINT */
370 /* Calculate OUTDIV */
371 and t8, t9, QCA_PLL_CPU_PLL_CFG_OUTDIV_MASK
372 srl t8, t8, QCA_PLL_CPU_PLL_CFG_OUTDIV_SHIFT
374 sllv t5, t5, t8 /* t5 = 2 ^ OUTDIV */
376 /* Calculate REFDIV */
377 and t8, t9, QCA_PLL_CPU_PLL_CFG_REFDIV_MASK
378 srl t8, t8, QCA_PLL_CPU_PLL_CFG_REFDIV_SHIFT
379 mul t5, t8, t5 /* t5 = REDIV * (2 ^ OUTDIV) */
382 b ahb_clk_calculation
385 ahb_clk_from_ddr_pll:
386 li t8, QCA_PLL_DDR_PLL_CFG_REG
390 and t8, t9, QCA_PLL_DDR_PLL_CFG_NINT_MASK
391 srl t8, t8, QCA_PLL_DDR_PLL_CFG_NINT_SHIFT
392 mul t4, t8, reg_ref_clk_val /* t4 = REFCLK * NINT */
394 /* Calculate OUTDIV */
395 and t8, t9, QCA_PLL_DDR_PLL_CFG_OUTDIV_MASK
396 srl t8, t8, QCA_PLL_DDR_PLL_CFG_OUTDIV_SHIFT
398 sllv t5, t5, t8 /* t5 = 2 ^ OUTDIV */
400 /* Calculate REFDIV */
401 and t8, t9, QCA_PLL_DDR_PLL_CFG_REFDIV_MASK
402 srl t8, t8, QCA_PLL_DDR_PLL_CFG_REFDIV_SHIFT
403 mul t5, t8, t5 /* t5 = REDIV * (2 ^ OUTDIV) */
408 mul t5, t5, t3 /* t5 = REDIV * (2 ^ OUTDIV) * (AHB_POST_DIV + 1) */
412 /* Store AHB CLK in t3 */
415 li t9, CONFIG_QCA_SPI_NOR_FLASH_MAX_CLK_MHZ
416 li t6, 0 /* t6 = CLOCK_DIVIDER for SPI FLASH clock */
418 /* Maximum SPI clock divider loop */
422 sll t7, t7, 1 /* t7 = 2 * (CLOCK_DIVIDER + 1) */
423 div t4, t3, t7 /* t4 = SPI FLASH clock */
424 sltu t5, t4, t9 /* t4 < t9 ? t5 = 1 : t5 = 0 */
426 /* SPI clock == target maximum clock? */
427 beq t4, t9, spi_clk_setup
430 /* SPI clock < target maximum clock? */
431 bgtz t5, spi_clk_setup
435 b spi_clk_calculation
439 sll t6, t6, QCA_SPI_CTRL_CLK_DIV_SHIFT
440 and reg_spi_ctrl_cfg, reg_spi_ctrl_cfg, ~QCA_SPI_CTRL_CLK_DIV_MASK
441 or reg_spi_ctrl_cfg, reg_spi_ctrl_cfg, t6
442 #endif /* CONFIG_QCA_PLL_SPI_FLASH_CLK_AUTO */
444 li t8, QCA_SPI_CTRL_REG
445 sw reg_spi_ctrl_cfg, 0(t8)
446 and reg_spi_ctrl_cfg, reg_spi_ctrl_cfg, QCA_SPI_CTRL_REMAP_DIS_MASK
447 beqz reg_spi_ctrl_cfg, end
451 * This is a small hack, needed after setting REMAP_DISABLE bit
452 * in SPI_CONTROL_ADDR register.
454 * Before that, SPI FLASH is mapped to 0x1FC00000, but just after
455 * setting REMAP_DISABLE bit, aliasing is disabled and SPI FLASH
456 * is mapped to 0x1F00000, so that the whole 16 MB address space
459 * That means, we need to "fix" return address, stored previously
460 * in $ra register, subtracting a value 0x00C00000 from it.
462 * Without that, jump would end up somewhere far away on FLASH...