tegra2: fix warning: "assert" redefined
[oweals/u-boot.git] / arch / arm / cpu / armv7 / tegra2 / clock.c
1 /*
2  * Copyright (c) 2011 The Chromium OS Authors.
3  * See file CREDITS for list of people who contributed to this
4  * project.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19  * MA 02111-1307 USA
20  */
21
22 /* Tegra2 Clock control functions */
23
24 #include <asm/io.h>
25 #include <asm/arch/clk_rst.h>
26 #include <asm/arch/clock.h>
27 #include <asm/arch/timer.h>
28 #include <asm/arch/tegra2.h>
29 #include <common.h>
30
31 /*
32  * Get the oscillator frequency, from the corresponding hardware configuration
33  * field.
34  */
35 enum clock_osc_freq clock_get_osc_freq(void)
36 {
37         struct clk_rst_ctlr *clkrst =
38                         (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
39         u32 reg;
40
41         reg = readl(&clkrst->crc_osc_ctrl);
42         return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
43 }
44
45 unsigned long clock_start_pll(enum clock_pll_id clkid, u32 divm, u32 divn,
46                 u32 divp, u32 cpcon, u32 lfcon)
47 {
48         struct clk_rst_ctlr *clkrst =
49                         (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
50         u32 data;
51         struct clk_pll *pll;
52
53         assert(clock_pll_id_isvalid(clkid));
54         pll = &clkrst->crc_pll[clkid];
55
56         /*
57          * We cheat by treating all PLL (except PLLU) in the same fashion.
58          * This works only because:
59          * - same fields are always mapped at same offsets, except DCCON
60          * - DCCON is always 0, doesn't conflict
61          * - M,N, P of PLLP values are ignored for PLLP
62          */
63         data = (cpcon << PLL_CPCON_SHIFT) | (lfcon << PLL_LFCON_SHIFT);
64         writel(data, &pll->pll_misc);
65
66         data = (divm << PLL_DIVM_SHIFT) | (divn << PLL_DIVN_SHIFT) |
67                         (0 << PLL_BYPASS_SHIFT) | (1 << PLL_ENABLE_SHIFT);
68
69         if (clkid == CLOCK_PLL_ID_USB)
70                 data |= divp << PLLU_VCO_FREQ_SHIFT;
71         else
72                 data |= divp << PLL_DIVP_SHIFT;
73         writel(data, &pll->pll_base);
74
75         /* calculate the stable time */
76         return timer_get_us() + CLOCK_PLL_STABLE_DELAY_US;
77 }
78
79 void clock_set_enable(enum periph_id periph_id, int enable)
80 {
81         struct clk_rst_ctlr *clkrst =
82                         (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
83         u32 *clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)];
84         u32 reg;
85
86         /* Enable/disable the clock to this peripheral */
87         assert(clock_periph_id_isvalid(periph_id));
88         reg = readl(clk);
89         if (enable)
90                 reg |= PERIPH_MASK(periph_id);
91         else
92                 reg &= ~PERIPH_MASK(periph_id);
93         writel(reg, clk);
94 }
95
96 void clock_enable(enum periph_id clkid)
97 {
98         clock_set_enable(clkid, 1);
99 }
100
101 void clock_disable(enum periph_id clkid)
102 {
103         clock_set_enable(clkid, 0);
104 }
105
106 void reset_set_enable(enum periph_id periph_id, int enable)
107 {
108         struct clk_rst_ctlr *clkrst =
109                         (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
110         u32 *reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)];
111         u32 reg;
112
113         /* Enable/disable reset to the peripheral */
114         assert(clock_periph_id_isvalid(periph_id));
115         reg = readl(reset);
116         if (enable)
117                 reg |= PERIPH_MASK(periph_id);
118         else
119                 reg &= ~PERIPH_MASK(periph_id);
120         writel(reg, reset);
121 }
122
123 void reset_periph(enum periph_id periph_id, int us_delay)
124 {
125         /* Put peripheral into reset */
126         reset_set_enable(periph_id, 1);
127         udelay(us_delay);
128
129         /* Remove reset */
130         reset_set_enable(periph_id, 0);
131
132         udelay(us_delay);
133 }
134
135 void reset_cmplx_set_enable(int cpu, int which, int reset)
136 {
137         struct clk_rst_ctlr *clkrst =
138                         (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
139         u32 mask;
140
141         /* Form the mask, which depends on the cpu chosen. Tegra2 has 2 */
142         assert(cpu >= 0 && cpu < 2);
143         mask = which << cpu;
144
145         /* either enable or disable those reset for that CPU */
146         if (reset)
147                 writel(mask, &clkrst->crc_cpu_cmplx_set);
148         else
149                 writel(mask, &clkrst->crc_cpu_cmplx_clr);
150 }