]> git.ipfire.org Git - people/ms/u-boot.git/blob - arch/avr32/cpu/at32ap700x/clk.c
stm32: Correct positioning of declaration
[people/ms/u-boot.git] / arch / avr32 / cpu / at32ap700x / clk.c
1 /*
2 * Copyright (C) 2005-2008 Atmel Corporation
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6 #include <common.h>
7
8 #include <asm/io.h>
9
10 #include <asm/arch/clk.h>
11 #include <asm/arch/hardware.h>
12 #include <asm/arch/portmux.h>
13
14 #include "sm.h"
15
16 void clk_init(void)
17 {
18 uint32_t cksel;
19
20 /* in case of soft resets, disable watchdog */
21 sm_writel(WDT_CTRL, SM_BF(KEY, 0x55));
22 sm_writel(WDT_CTRL, SM_BF(KEY, 0xaa));
23
24 #ifdef CONFIG_PLL
25 /* Initialize the PLL */
26 sm_writel(PM_PLL0, (SM_BF(PLLCOUNT, CONFIG_SYS_PLL0_SUPPRESS_CYCLES)
27 | SM_BF(PLLMUL, CONFIG_SYS_PLL0_MUL - 1)
28 | SM_BF(PLLDIV, CONFIG_SYS_PLL0_DIV - 1)
29 | SM_BF(PLLOPT, CONFIG_SYS_PLL0_OPT)
30 | SM_BF(PLLOSC, 0)
31 | SM_BIT(PLLEN)));
32
33 /* Wait for lock */
34 while (!(sm_readl(PM_ISR) & SM_BIT(LOCK0))) ;
35 #endif
36
37 /* Set up clocks for the CPU and all peripheral buses */
38 cksel = 0;
39 if (CONFIG_SYS_CLKDIV_CPU)
40 cksel |= SM_BIT(CPUDIV) | SM_BF(CPUSEL, CONFIG_SYS_CLKDIV_CPU - 1);
41 if (CONFIG_SYS_CLKDIV_HSB)
42 cksel |= SM_BIT(HSBDIV) | SM_BF(HSBSEL, CONFIG_SYS_CLKDIV_HSB - 1);
43 if (CONFIG_SYS_CLKDIV_PBA)
44 cksel |= SM_BIT(PBADIV) | SM_BF(PBASEL, CONFIG_SYS_CLKDIV_PBA - 1);
45 if (CONFIG_SYS_CLKDIV_PBB)
46 cksel |= SM_BIT(PBBDIV) | SM_BF(PBBSEL, CONFIG_SYS_CLKDIV_PBB - 1);
47 sm_writel(PM_CKSEL, cksel);
48
49 #ifdef CONFIG_PLL
50 /* Use PLL0 as main clock */
51 sm_writel(PM_MCCTRL, SM_BIT(PLLSEL));
52
53 #ifdef CONFIG_LCD
54 /* Set up pixel clock for the LCDC */
55 sm_writel(PM_GCCTRL(7), SM_BIT(PLLSEL) | SM_BIT(CEN));
56 #endif
57 #endif
58 }
59
60 unsigned long __gclk_set_rate(unsigned int id, enum gclk_parent parent,
61 unsigned long rate, unsigned long parent_rate)
62 {
63 unsigned long divider;
64
65 if (rate == 0 || parent_rate == 0) {
66 sm_writel(PM_GCCTRL(id), 0);
67 return 0;
68 }
69
70 divider = (parent_rate + rate / 2) / rate;
71 if (divider <= 1) {
72 sm_writel(PM_GCCTRL(id), parent | SM_BIT(CEN));
73 rate = parent_rate;
74 } else {
75 divider = min(255UL, divider / 2 - 1);
76 sm_writel(PM_GCCTRL(id), parent | SM_BIT(CEN) | SM_BIT(DIVEN)
77 | SM_BF(DIV, divider));
78 rate = parent_rate / (2 * (divider + 1));
79 }
80
81 return rate;
82 }