~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/arch/avr32/cpu/at32ap700x/clk.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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(255, 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
}