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
--- 11 unchanged lines hidden (view full) ---
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 $");
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
--- 51 unchanged lines hidden (view full) ---
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) \
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[] =
--- 47 unchanged lines hidden (view full) ---
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)
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{
--- 8 unchanged lines hidden (view full) ---
177}
178
179static uint32_t
180at91_pll_outa(int freq)
181{
182
183 if (freq > 195000000)
184 return (0x20000000);
185 else
186 return (0x20008000);
187}
188
189static uint32_t
190at91_pll_outb(int freq)
191{
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)) {
--- 21 unchanged lines hidden (view full) ---
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
229 /*
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,
--- 4 unchanged lines hidden (view full) ---
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++) {
250 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 }
--- 12 unchanged lines hidden (view full) ---
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,
279 AT91SAM9260_EBICSA,
280 i | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
281
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;
--- 8 unchanged lines hidden (view full) ---
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.
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;
--- 4 unchanged lines hidden (view full) ---
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),
332 {0, 0},
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
343DRIVER_MODULE(at91sam9260, atmelarm, at91sam9260_driver, at91sam9260_devclass, 0, 0);
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
--- 11 unchanged lines hidden (view full) ---
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 $");
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
--- 51 unchanged lines hidden (view full) ---
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) \
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[] =
--- 47 unchanged lines hidden (view full) ---
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)
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{
--- 8 unchanged lines hidden (view full) ---
177}
178
179static uint32_t
180at91_pll_outa(int freq)
181{
182
183 if (freq > 195000000)
184 return (0x20000000);
185 else
186 return (0x20008000);
187}
188
189static uint32_t
190at91_pll_outb(int freq)
191{
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)) {
--- 21 unchanged lines hidden (view full) ---
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
229 /*
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,
--- 4 unchanged lines hidden (view full) ---
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++) {
250 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 }
--- 12 unchanged lines hidden (view full) ---
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,
279 AT91SAM9260_EBICSA,
280 i | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
281
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;
--- 8 unchanged lines hidden (view full) ---
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.
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;
--- 4 unchanged lines hidden (view full) ---
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),
332 {0, 0},
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
343DRIVER_MODULE(at91sam9260, atmelarm, at91sam9260_driver, at91sam9260_devclass, 0, 0);