2 * Copyright (C) 2005-2008 Atmel Corporation
4 * SPDX-License-Identifier: GPL-2.0+
10 #include <asm/arch/clk.h>
11 #include <asm/arch/hardware.h>
12 #include <asm/arch/portmux.h>
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));
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)
34 while (!(sm_readl(PM_ISR) & SM_BIT(LOCK0))) ;
37 /* Set up clocks for the CPU and all peripheral buses */
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);
50 /* Use PLL0 as main clock */
51 sm_writel(PM_MCCTRL, SM_BIT(PLLSEL));
54 /* Set up pixel clock for the LCDC */
55 sm_writel(PM_GCCTRL(7), SM_BIT(PLLSEL) | SM_BIT(CEN));
60 unsigned long __gclk_set_rate(unsigned int id, enum gclk_parent parent,
61 unsigned long rate, unsigned long parent_rate)
63 unsigned long divider;
65 if (rate == 0 || parent_rate == 0) {
66 sm_writel(PM_GCCTRL(id), 0);
70 divider = (parent_rate + rate / 2) / rate;
72 sm_writel(PM_GCCTRL(id), parent | SM_BIT(CEN));
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));