Deleted Added
full compact
at91sam9260.c (213498) at91sam9260.c (234281)
1/*-
2 * Copyright (c) 2005 Olivier Houchard. All rights reserved.
3 * Copyright (c) 2010 Greg Ansley. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2005 Olivier Houchard. All rights reserved.
3 * Copyright (c) 2010 Greg Ansley. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/arm/at91/at91sam9260.c 213498 2010-10-06 22:40:27Z cognet $");
28__FBSDID("$FreeBSD: head/sys/arm/at91/at91sam9260.c 234281 2012-04-14 11:29:32Z marius $");
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/bus.h>
33#include <sys/kernel.h>
34#include <sys/malloc.h>
35#include <sys/module.h>
36
37#define _ARM32_BUS_DMA_PRIVATE
38#include <machine/bus.h>
39
40#include <arm/at91/at91var.h>
41#include <arm/at91/at91_aicreg.h>
42#include <arm/at91/at91sam9260reg.h>
43#include <arm/at91/at91_pmcreg.h>
44#include <arm/at91/at91_pmcvar.h>
45
46struct at91sam9_softc {
47 device_t dev;
48 bus_space_tag_t sc_st;
49 bus_space_handle_t sc_sh;
50 bus_space_handle_t sc_sys_sh;
51 bus_space_handle_t sc_aic_sh;
52 bus_space_handle_t sc_dbg_sh;
53 bus_space_handle_t sc_matrix_sh;
54};
55
56/*
57 * Standard priority levels for the system. 0 is lowest and 7 is highest.
58 * These values are the ones Atmel uses for its Linux port
59 */
60static const int at91_irq_prio[32] =
61{
62 7, /* Advanced Interrupt Controller */
63 7, /* System Peripherals */
64 1, /* Parallel IO Controller A */
65 1, /* Parallel IO Controller B */
66 1, /* Parallel IO Controller C */
67 0, /* Analog-to-Digital Converter */
68 5, /* USART 0 */
69 5, /* USART 1 */
70 5, /* USART 2 */
71 0, /* Multimedia Card Interface */
72 2, /* USB Device Port */
73 6, /* Two-Wire Interface */
74 5, /* Serial Peripheral Interface 0 */
75 5, /* Serial Peripheral Interface 1 */
76 5, /* Serial Synchronous Controller */
77 0, /* (reserved) */
78 0, /* (reserved) */
79 0, /* Timer Counter 0 */
80 0, /* Timer Counter 1 */
81 0, /* Timer Counter 2 */
82 2, /* USB Host port */
83 3, /* Ethernet */
84 0, /* Image Sensor Interface */
85 5, /* USART 3 */
86 5, /* USART 4 */
87 5, /* USART 5 */
88 0, /* Timer Counter 3 */
89 0, /* Timer Counter 4 */
90 0, /* Timer Counter 5 */
91 0, /* Advanced Interrupt Controller IRQ0 */
92 0, /* Advanced Interrupt Controller IRQ1 */
93 0, /* Advanced Interrupt Controller IRQ2 */
94};
95
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/bus.h>
33#include <sys/kernel.h>
34#include <sys/malloc.h>
35#include <sys/module.h>
36
37#define _ARM32_BUS_DMA_PRIVATE
38#include <machine/bus.h>
39
40#include <arm/at91/at91var.h>
41#include <arm/at91/at91_aicreg.h>
42#include <arm/at91/at91sam9260reg.h>
43#include <arm/at91/at91_pmcreg.h>
44#include <arm/at91/at91_pmcvar.h>
45
46struct at91sam9_softc {
47 device_t dev;
48 bus_space_tag_t sc_st;
49 bus_space_handle_t sc_sh;
50 bus_space_handle_t sc_sys_sh;
51 bus_space_handle_t sc_aic_sh;
52 bus_space_handle_t sc_dbg_sh;
53 bus_space_handle_t sc_matrix_sh;
54};
55
56/*
57 * Standard priority levels for the system. 0 is lowest and 7 is highest.
58 * These values are the ones Atmel uses for its Linux port
59 */
60static const int at91_irq_prio[32] =
61{
62 7, /* Advanced Interrupt Controller */
63 7, /* System Peripherals */
64 1, /* Parallel IO Controller A */
65 1, /* Parallel IO Controller B */
66 1, /* Parallel IO Controller C */
67 0, /* Analog-to-Digital Converter */
68 5, /* USART 0 */
69 5, /* USART 1 */
70 5, /* USART 2 */
71 0, /* Multimedia Card Interface */
72 2, /* USB Device Port */
73 6, /* Two-Wire Interface */
74 5, /* Serial Peripheral Interface 0 */
75 5, /* Serial Peripheral Interface 1 */
76 5, /* Serial Synchronous Controller */
77 0, /* (reserved) */
78 0, /* (reserved) */
79 0, /* Timer Counter 0 */
80 0, /* Timer Counter 1 */
81 0, /* Timer Counter 2 */
82 2, /* USB Host port */
83 3, /* Ethernet */
84 0, /* Image Sensor Interface */
85 5, /* USART 3 */
86 5, /* USART 4 */
87 5, /* USART 5 */
88 0, /* Timer Counter 3 */
89 0, /* Timer Counter 4 */
90 0, /* Timer Counter 5 */
91 0, /* Advanced Interrupt Controller IRQ0 */
92 0, /* Advanced Interrupt Controller IRQ1 */
93 0, /* Advanced Interrupt Controller IRQ2 */
94};
95
96#define DEVICE(_name, _id, _unit) \
96#define DEVICE(_name, _id, _unit) \
97 { \
98 _name, _unit, \
99 AT91SAM9260_ ## _id ##_BASE, \
100 AT91SAM9260_ ## _id ## _SIZE, \
101 AT91SAM9260_IRQ_ ## _id \
102 }
103
104static const struct cpu_devs at91_devs[] =
105{
106 DEVICE("at91_pmc", PMC, 0),
107 DEVICE("at91_wdt", WDT, 0),
108 DEVICE("at91_rst", RSTC, 0),
109 DEVICE("at91_pit", PIT, 0),
110 DEVICE("at91_pio", PIOA, 0),
111 DEVICE("at91_pio", PIOB, 1),
112 DEVICE("at91_pio", PIOC, 2),
113 DEVICE("at91_twi", TWI, 0),
114 DEVICE("at91_mci", MCI, 0),
115 DEVICE("uart", DBGU, 0),
116 DEVICE("uart", USART0, 1),
117 DEVICE("uart", USART1, 2),
118 DEVICE("uart", USART2, 3),
119 DEVICE("uart", USART3, 4),
120 DEVICE("uart", USART4, 5),
121 DEVICE("uart", USART5, 6),
122 DEVICE("spi", SPI0, 0),
123 DEVICE("spi", SPI1, 1),
124 DEVICE("ate", EMAC, 0),
125 DEVICE("macb", EMAC, 0),
126 DEVICE("nand", NAND, 0),
127 DEVICE("ohci", OHCI, 0),
128 { 0, 0, 0, 0, 0 }
129};
130
131static void
132at91_add_child(device_t dev, int prio, const char *name, int unit,
133 bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2)
134{
135 device_t kid;
136 struct at91_ivar *ivar;
137
138 kid = device_add_child_ordered(dev, prio, name, unit);
139 if (kid == NULL) {
140 printf("Can't add child %s%d ordered\n", name, unit);
141 return;
142 }
143 ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
144 if (ivar == NULL) {
145 device_delete_child(dev, kid);
146 printf("Can't add alloc ivar\n");
147 return;
148 }
149 device_set_ivars(kid, ivar);
150 resource_list_init(&ivar->resources);
151 if (irq0 != -1) {
152 bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
153 if (irq0 != AT91SAM9260_IRQ_SYSTEM)
154 at91_pmc_clock_add(device_get_nameunit(kid), irq0, 0);
155 }
156 if (irq1 != 0)
157 bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
158 if (irq2 != 0)
159 bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
97 { \
98 _name, _unit, \
99 AT91SAM9260_ ## _id ##_BASE, \
100 AT91SAM9260_ ## _id ## _SIZE, \
101 AT91SAM9260_IRQ_ ## _id \
102 }
103
104static const struct cpu_devs at91_devs[] =
105{
106 DEVICE("at91_pmc", PMC, 0),
107 DEVICE("at91_wdt", WDT, 0),
108 DEVICE("at91_rst", RSTC, 0),
109 DEVICE("at91_pit", PIT, 0),
110 DEVICE("at91_pio", PIOA, 0),
111 DEVICE("at91_pio", PIOB, 1),
112 DEVICE("at91_pio", PIOC, 2),
113 DEVICE("at91_twi", TWI, 0),
114 DEVICE("at91_mci", MCI, 0),
115 DEVICE("uart", DBGU, 0),
116 DEVICE("uart", USART0, 1),
117 DEVICE("uart", USART1, 2),
118 DEVICE("uart", USART2, 3),
119 DEVICE("uart", USART3, 4),
120 DEVICE("uart", USART4, 5),
121 DEVICE("uart", USART5, 6),
122 DEVICE("spi", SPI0, 0),
123 DEVICE("spi", SPI1, 1),
124 DEVICE("ate", EMAC, 0),
125 DEVICE("macb", EMAC, 0),
126 DEVICE("nand", NAND, 0),
127 DEVICE("ohci", OHCI, 0),
128 { 0, 0, 0, 0, 0 }
129};
130
131static void
132at91_add_child(device_t dev, int prio, const char *name, int unit,
133 bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2)
134{
135 device_t kid;
136 struct at91_ivar *ivar;
137
138 kid = device_add_child_ordered(dev, prio, name, unit);
139 if (kid == NULL) {
140 printf("Can't add child %s%d ordered\n", name, unit);
141 return;
142 }
143 ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
144 if (ivar == NULL) {
145 device_delete_child(dev, kid);
146 printf("Can't add alloc ivar\n");
147 return;
148 }
149 device_set_ivars(kid, ivar);
150 resource_list_init(&ivar->resources);
151 if (irq0 != -1) {
152 bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
153 if (irq0 != AT91SAM9260_IRQ_SYSTEM)
154 at91_pmc_clock_add(device_get_nameunit(kid), irq0, 0);
155 }
156 if (irq1 != 0)
157 bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
158 if (irq2 != 0)
159 bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
160 if (addr != 0 && addr < AT91SAM9260_BASE)
160 if (addr != 0 && addr < AT91SAM9260_BASE)
161 addr += AT91SAM9260_BASE;
162 if (addr != 0)
163 bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
164}
165
166static void
167at91_cpu_add_builtin_children(device_t dev)
168{
169 int i;
170 const struct cpu_devs *walker;
171
172 for (i = 1, walker = at91_devs; walker->name; i++, walker++) {
173 at91_add_child(dev, i, walker->name, walker->unit,
174 walker->mem_base, walker->mem_len, walker->irq0,
175 walker->irq1, walker->irq2);
176 }
177}
178
179static uint32_t
180at91_pll_outa(int freq)
181{
182
183 if (freq > 195000000)
184 return (0x20000000);
161 addr += AT91SAM9260_BASE;
162 if (addr != 0)
163 bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
164}
165
166static void
167at91_cpu_add_builtin_children(device_t dev)
168{
169 int i;
170 const struct cpu_devs *walker;
171
172 for (i = 1, walker = at91_devs; walker->name; i++, walker++) {
173 at91_add_child(dev, i, walker->name, walker->unit,
174 walker->mem_base, walker->mem_len, walker->irq0,
175 walker->irq1, walker->irq2);
176 }
177}
178
179static uint32_t
180at91_pll_outa(int freq)
181{
182
183 if (freq > 195000000)
184 return (0x20000000);
185 else
185 else
186 return (0x20008000);
187}
188
189static uint32_t
190at91_pll_outb(int freq)
191{
186 return (0x20008000);
187}
188
189static uint32_t
190at91_pll_outb(int freq)
191{
192
192 return (0x4000);
193}
194
195static void
196at91_identify(driver_t *drv, device_t parent)
197{
198
199 if (at91_cpu_is(AT91_CPU_SAM9260)) {
200 at91_add_child(parent, 0, "at91sam9260", 0, 0, 0, -1, 0, 0);
201 at91_cpu_add_builtin_children(parent);
202 }
203}
204
205static int
206at91_probe(device_t dev)
207{
208
209 if (at91_cpu_is(AT91_CPU_SAM9260)) {
210 device_set_desc(dev, "AT91SAM9260");
211 return (0);
212 }
213 return (ENXIO);
214}
215
216static int
217at91_attach(device_t dev)
218{
219 struct at91_pmc_clock *clk;
220 struct at91sam9_softc *sc = device_get_softc(dev);
221 int i;
222
223 struct at91_softc *at91sc = device_get_softc(device_get_parent(dev));
224
225 sc->sc_st = at91sc->sc_st;
226 sc->sc_sh = at91sc->sc_sh;
227 sc->dev = dev;
228
193 return (0x4000);
194}
195
196static void
197at91_identify(driver_t *drv, device_t parent)
198{
199
200 if (at91_cpu_is(AT91_CPU_SAM9260)) {
201 at91_add_child(parent, 0, "at91sam9260", 0, 0, 0, -1, 0, 0);
202 at91_cpu_add_builtin_children(parent);
203 }
204}
205
206static int
207at91_probe(device_t dev)
208{
209
210 if (at91_cpu_is(AT91_CPU_SAM9260)) {
211 device_set_desc(dev, "AT91SAM9260");
212 return (0);
213 }
214 return (ENXIO);
215}
216
217static int
218at91_attach(device_t dev)
219{
220 struct at91_pmc_clock *clk;
221 struct at91sam9_softc *sc = device_get_softc(dev);
222 int i;
223
224 struct at91_softc *at91sc = device_get_softc(device_get_parent(dev));
225
226 sc->sc_st = at91sc->sc_st;
227 sc->sc_sh = at91sc->sc_sh;
228 sc->dev = dev;
229
229 /*
230 /*
230 * XXX These values work for the RM9200, SAM926[01], and SAM9260
231 * will have to fix this when we want to support anything else. XXX
232 */
233 if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9260_SYS_BASE,
234 AT91SAM9260_SYS_SIZE, &sc->sc_sys_sh) != 0)
235 panic("Enable to map system registers");
236
237 if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9260_DBGU_BASE,
238 AT91SAM9260_DBGU_SIZE, &sc->sc_dbg_sh) != 0)
239 panic("Enable to map DBGU registers");
240
241 if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9260_AIC_BASE,
242 AT91SAM9260_AIC_SIZE, &sc->sc_aic_sh) != 0)
243 panic("Enable to map system registers");
244
245 /* XXX Hack to tell atmelarm about the AIC */
246 at91sc->sc_aic_sh = sc->sc_aic_sh;
247 at91sc->sc_irq_system = AT91SAM9260_IRQ_SYSTEM;
248
249 for (i = 0; i < 32; i++) {
231 * XXX These values work for the RM9200, SAM926[01], and SAM9260
232 * will have to fix this when we want to support anything else. XXX
233 */
234 if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9260_SYS_BASE,
235 AT91SAM9260_SYS_SIZE, &sc->sc_sys_sh) != 0)
236 panic("Enable to map system registers");
237
238 if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9260_DBGU_BASE,
239 AT91SAM9260_DBGU_SIZE, &sc->sc_dbg_sh) != 0)
240 panic("Enable to map DBGU registers");
241
242 if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9260_AIC_BASE,
243 AT91SAM9260_AIC_SIZE, &sc->sc_aic_sh) != 0)
244 panic("Enable to map system registers");
245
246 /* XXX Hack to tell atmelarm about the AIC */
247 at91sc->sc_aic_sh = sc->sc_aic_sh;
248 at91sc->sc_irq_system = AT91SAM9260_IRQ_SYSTEM;
249
250 for (i = 0; i < 32; i++) {
250 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SVR +
251 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SVR +
251 i * 4, i);
252 /* Priority. */
253 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SMR + i * 4,
254 at91_irq_prio[i]);
255 if (i < 8)
256 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_EOICR,
257 1);
258 }
259
260 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SPU, 32);
261 /* No debug. */
262 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_DCR, 0);
263 /* Disable and clear all interrupts. */
264 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR, 0xffffffff);
265 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_ICCR, 0xffffffff);
266
267 /* Disable all interrupts for DBGU */
268 bus_space_write_4(sc->sc_st, sc->sc_dbg_sh, 0x0c, 0xffffffff);
269
270 if (bus_space_subregion(sc->sc_st, sc->sc_sh,
271 AT91SAM9260_MATRIX_BASE, AT91SAM9260_MATRIX_SIZE,
272 &sc->sc_matrix_sh) != 0)
273 panic("Enable to map matrix registers");
274
275 /* activate NAND*/
276 i = bus_space_read_4(sc->sc_st, sc->sc_matrix_sh,
277 AT91SAM9260_EBICSA);
278 bus_space_write_4(sc->sc_st, sc->sc_matrix_sh,
252 i * 4, i);
253 /* Priority. */
254 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SMR + i * 4,
255 at91_irq_prio[i]);
256 if (i < 8)
257 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_EOICR,
258 1);
259 }
260
261 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SPU, 32);
262 /* No debug. */
263 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_DCR, 0);
264 /* Disable and clear all interrupts. */
265 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR, 0xffffffff);
266 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_ICCR, 0xffffffff);
267
268 /* Disable all interrupts for DBGU */
269 bus_space_write_4(sc->sc_st, sc->sc_dbg_sh, 0x0c, 0xffffffff);
270
271 if (bus_space_subregion(sc->sc_st, sc->sc_sh,
272 AT91SAM9260_MATRIX_BASE, AT91SAM9260_MATRIX_SIZE,
273 &sc->sc_matrix_sh) != 0)
274 panic("Enable to map matrix registers");
275
276 /* activate NAND*/
277 i = bus_space_read_4(sc->sc_st, sc->sc_matrix_sh,
278 AT91SAM9260_EBICSA);
279 bus_space_write_4(sc->sc_st, sc->sc_matrix_sh,
279 AT91SAM9260_EBICSA,
280 AT91SAM9260_EBICSA,
280 i | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
281
281 i | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
282
282
283 /* Update USB device port clock info */
284 clk = at91_pmc_clock_ref("udpck");
285 clk->pmc_mask = PMC_SCER_UDP_SAM9;
286 at91_pmc_clock_deref(clk);
287
288 /* Update USB host port clock info */
289 clk = at91_pmc_clock_ref("uhpck");
290 clk->pmc_mask = PMC_SCER_UHP_SAM9;
291 at91_pmc_clock_deref(clk);
292
293 /* Each SOC has different PLL contraints */
294 clk = at91_pmc_clock_ref("plla");
295 clk->pll_min_in = SAM9260_PLL_A_MIN_IN_FREQ; /* 1 MHz */
296 clk->pll_max_in = SAM9260_PLL_A_MAX_IN_FREQ; /* 32 MHz */
297 clk->pll_min_out = SAM9260_PLL_A_MIN_OUT_FREQ; /* 80 MHz */
298 clk->pll_max_out = SAM9260_PLL_A_MAX_OUT_FREQ; /* 240 MHz */
299 clk->pll_mul_shift = SAM9260_PLL_A_MUL_SHIFT;
300 clk->pll_mul_mask = SAM9260_PLL_A_MUL_MASK;
301 clk->pll_div_shift = SAM9260_PLL_A_DIV_SHIFT;
302 clk->pll_div_mask = SAM9260_PLL_A_DIV_MASK;
303 clk->set_outb = at91_pll_outa;
304 at91_pmc_clock_deref(clk);
305
306 /*
283 /* Update USB device port clock info */
284 clk = at91_pmc_clock_ref("udpck");
285 clk->pmc_mask = PMC_SCER_UDP_SAM9;
286 at91_pmc_clock_deref(clk);
287
288 /* Update USB host port clock info */
289 clk = at91_pmc_clock_ref("uhpck");
290 clk->pmc_mask = PMC_SCER_UHP_SAM9;
291 at91_pmc_clock_deref(clk);
292
293 /* Each SOC has different PLL contraints */
294 clk = at91_pmc_clock_ref("plla");
295 clk->pll_min_in = SAM9260_PLL_A_MIN_IN_FREQ; /* 1 MHz */
296 clk->pll_max_in = SAM9260_PLL_A_MAX_IN_FREQ; /* 32 MHz */
297 clk->pll_min_out = SAM9260_PLL_A_MIN_OUT_FREQ; /* 80 MHz */
298 clk->pll_max_out = SAM9260_PLL_A_MAX_OUT_FREQ; /* 240 MHz */
299 clk->pll_mul_shift = SAM9260_PLL_A_MUL_SHIFT;
300 clk->pll_mul_mask = SAM9260_PLL_A_MUL_MASK;
301 clk->pll_div_shift = SAM9260_PLL_A_DIV_SHIFT;
302 clk->pll_div_mask = SAM9260_PLL_A_DIV_MASK;
303 clk->set_outb = at91_pll_outa;
304 at91_pmc_clock_deref(clk);
305
306 /*
307 * Fudge MAX pll in frequence down below 3.0 Mhz to ensure
308 * PMC alogrithm choose the divisor that causes the input clock
309 * to be near the optimal 2 Mhz per datasheet. We know
310 * we are going to be using this for the USB clock at 96 Mhz.
311 * Causes no extra frequency deviation for all recomended crystal values.
307 * Fudge MAX pll in frequence down below 3.0 MHz to ensure
308 * PMC alogrithm choose the divisor that causes the input clock
309 * to be near the optimal 2 MHz per datasheet. We know
310 * we are going to be using this for the USB clock at 96 MHz.
311 * Causes no extra frequency deviation for all recomended crystal
312 * values.
312 */
313 clk = at91_pmc_clock_ref("pllb");
314 clk->pll_min_in = SAM9260_PLL_B_MIN_IN_FREQ; /* 1 MHz */
315 clk->pll_max_in = SAM9260_PLL_B_MAX_IN_FREQ; /* 5 MHz */
316 clk->pll_max_in = 2999999; /* ~3 MHz */
317 clk->pll_min_out = SAM9260_PLL_B_MIN_OUT_FREQ; /* 70 MHz */
318 clk->pll_max_out = SAM9260_PLL_B_MAX_OUT_FREQ; /* 130 MHz */
319 clk->pll_mul_shift = SAM9260_PLL_B_MUL_SHIFT;
320 clk->pll_mul_mask = SAM9260_PLL_B_MUL_MASK;
321 clk->pll_div_shift = SAM9260_PLL_B_DIV_SHIFT;
322 clk->pll_div_mask = SAM9260_PLL_B_DIV_MASK;
323 clk->set_outb = at91_pll_outb;
324 at91_pmc_clock_deref(clk);
325 return (0);
326}
327
328static device_method_t at91sam9260_methods[] = {
329 DEVMETHOD(device_probe, at91_probe),
330 DEVMETHOD(device_attach, at91_attach),
331 DEVMETHOD(device_identify, at91_identify),
313 */
314 clk = at91_pmc_clock_ref("pllb");
315 clk->pll_min_in = SAM9260_PLL_B_MIN_IN_FREQ; /* 1 MHz */
316 clk->pll_max_in = SAM9260_PLL_B_MAX_IN_FREQ; /* 5 MHz */
317 clk->pll_max_in = 2999999; /* ~3 MHz */
318 clk->pll_min_out = SAM9260_PLL_B_MIN_OUT_FREQ; /* 70 MHz */
319 clk->pll_max_out = SAM9260_PLL_B_MAX_OUT_FREQ; /* 130 MHz */
320 clk->pll_mul_shift = SAM9260_PLL_B_MUL_SHIFT;
321 clk->pll_mul_mask = SAM9260_PLL_B_MUL_MASK;
322 clk->pll_div_shift = SAM9260_PLL_B_DIV_SHIFT;
323 clk->pll_div_mask = SAM9260_PLL_B_DIV_MASK;
324 clk->set_outb = at91_pll_outb;
325 at91_pmc_clock_deref(clk);
326 return (0);
327}
328
329static device_method_t at91sam9260_methods[] = {
330 DEVMETHOD(device_probe, at91_probe),
331 DEVMETHOD(device_attach, at91_attach),
332 DEVMETHOD(device_identify, at91_identify),
332 {0, 0},
333 DEVMETHOD_END
333};
334
335static driver_t at91sam9260_driver = {
336 "at91sam9260",
337 at91sam9260_methods,
338 sizeof(struct at91sam9_softc),
339};
340
341static devclass_t at91sam9260_devclass;
342
334};
335
336static driver_t at91sam9260_driver = {
337 "at91sam9260",
338 at91sam9260_methods,
339 sizeof(struct at91sam9_softc),
340};
341
342static devclass_t at91sam9260_devclass;
343
343DRIVER_MODULE(at91sam9260, atmelarm, at91sam9260_driver, at91sam9260_devclass, 0, 0);
344DRIVER_MODULE(at91sam9260, atmelarm, at91sam9260_driver, at91sam9260_devclass,
345 NULL, NULL);