2 * Copyright (c) 2005 Olivier Houchard. All rights reserved.
3 * Copyright (c) 2010 Greg Ansley. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
30 #include <sys/param.h>
31 #include <sys/systm.h>
33 #include <sys/kernel.h>
34 #include <sys/malloc.h>
35 #include <sys/module.h>
37 #define _ARM32_BUS_DMA_PRIVATE
38 #include <machine/bus.h>
40 #include <arm/at91/at91var.h>
41 #include <arm/at91/at91_aicreg.h>
42 #include <arm/at91/at91sam9g20reg.h>
43 #include <arm/at91/at91_pmcreg.h>
44 #include <arm/at91/at91_pmcvar.h>
46 struct at91sam9_softc {
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;
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
60 static const int at91_irq_prio[32] =
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 */
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 */
79 0, /* Timer Counter 0 */
80 0, /* Timer Counter 1 */
81 0, /* Timer Counter 2 */
82 2, /* USB Host port */
84 0, /* Image Sensor Interface */
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 */
96 #define DEVICE(_name, _id, _unit) \
99 AT91SAM9G20_ ## _id ##_BASE, \
100 AT91SAM9G20_ ## _id ## _SIZE, \
101 AT91SAM9G20_IRQ_ ## _id \
104 static const struct cpu_devs at91_devs[] =
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),
132 at91_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)
136 struct at91_ivar *ivar;
138 kid = device_add_child_ordered(dev, prio, name, unit);
140 printf("Can't add child %s%d ordered\n", name, unit);
143 ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
145 device_delete_child(dev, kid);
146 printf("Can't add alloc ivar\n");
149 device_set_ivars(kid, ivar);
150 resource_list_init(&ivar->resources);
152 bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
153 if (irq0 != AT91SAM9G20_IRQ_SYSTEM)
154 at91_pmc_clock_add(device_get_nameunit(kid), irq0, 0);
157 bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
159 bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
160 if (addr != 0 && addr < AT91SAM9G20_BASE)
161 addr += AT91SAM9G20_BASE;
163 bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
167 at91_cpu_add_builtin_children(device_t dev)
170 const struct cpu_devs *walker;
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);
180 at91_pll_outa(int freq)
183 switch (freq / 10000000) {
184 case 747 ... 801: return ((1 << 29) | (0 << 14));
185 case 697 ... 746: return ((1 << 29) | (1 << 14));
186 case 647 ... 696: return ((1 << 29) | (2 << 14));
187 case 597 ... 646: return ((1 << 29) | (3 << 14));
188 case 547 ... 596: return ((1 << 29) | (1 << 14));
189 case 497 ... 546: return ((1 << 29) | (2 << 14));
190 case 447 ... 496: return ((1 << 29) | (3 << 14));
191 case 397 ... 446: return ((1 << 29) | (4 << 14));
192 default: return (1 << 29);
197 at91_pll_outb(int freq)
204 at91_identify(driver_t *drv, device_t parent)
207 if (at91_cpu_is(AT91_CPU_SAM9G20)) {
208 at91_add_child(parent, 0, "at91sam", 9, 0, 0, -1, 0, 0);
209 at91_cpu_add_builtin_children(parent);
214 at91_probe(device_t dev)
217 if (at91_cpu_is(AT91_CPU_SAM9G20)) {
218 device_set_desc(dev, "AT91SAM9G20");
225 at91_attach(device_t dev)
227 struct at91_pmc_clock *clk;
228 struct at91sam9_softc *sc = device_get_softc(dev);
231 struct at91_softc *at91sc = device_get_softc(device_get_parent(dev));
233 sc->sc_st = at91sc->sc_st;
234 sc->sc_sh = at91sc->sc_sh;
238 * XXX These values work for the RM9200, SAM926[01], and SAM9G20
239 * will have to fix this when we want to support anything else. XXX
241 if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9G20_SYS_BASE,
242 AT91SAM9G20_SYS_SIZE, &sc->sc_sys_sh) != 0)
243 panic("Enable to map system registers");
245 if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9G20_DBGU_BASE,
246 AT91SAM9G20_DBGU_SIZE, &sc->sc_dbg_sh) != 0)
247 panic("Enable to map DBGU registers");
249 if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9G20_AIC_BASE,
250 AT91SAM9G20_AIC_SIZE, &sc->sc_aic_sh) != 0)
251 panic("Enable to map system registers");
253 /* XXX Hack to tell atmelarm about the AIC */
254 at91sc->sc_aic_sh = sc->sc_aic_sh;
255 at91sc->sc_irq_system = AT91SAM9G20_IRQ_SYSTEM;
257 for (i = 0; i < 32; i++) {
258 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SVR +
261 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SMR + i * 4,
264 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_EOICR,
268 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SPU, 32);
270 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_DCR, 0);
271 /* Disable and clear all interrupts. */
272 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR, 0xffffffff);
273 bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_ICCR, 0xffffffff);
275 /* Disable all interrupts for DBGU */
276 bus_space_write_4(sc->sc_st, sc->sc_dbg_sh, 0x0c, 0xffffffff);
278 if (bus_space_subregion(sc->sc_st, sc->sc_sh,
279 AT91SAM9G20_MATRIX_BASE, AT91SAM9G20_MATRIX_SIZE,
280 &sc->sc_matrix_sh) != 0)
281 panic("Enable to map matrix registers");
284 i = bus_space_read_4(sc->sc_st, sc->sc_matrix_sh,
286 bus_space_write_4(sc->sc_st, sc->sc_matrix_sh,
288 i | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
291 /* Update USB device port clock info */
292 clk = at91_pmc_clock_ref("udpck");
293 clk->pmc_mask = PMC_SCER_UDP_SAM9;
294 at91_pmc_clock_deref(clk);
296 /* Update USB host port clock info */
297 clk = at91_pmc_clock_ref("uhpck");
298 clk->pmc_mask = PMC_SCER_UHP_SAM9;
299 at91_pmc_clock_deref(clk);
301 /* Each SOC has different PLL contraints */
302 clk = at91_pmc_clock_ref("plla");
303 clk->pll_min_in = SAM9G20_PLL_A_MIN_IN_FREQ; /* 2 MHz */
304 clk->pll_max_in = SAM9G20_PLL_A_MAX_IN_FREQ; /* 32 MHz */
305 clk->pll_min_out = SAM9G20_PLL_A_MIN_OUT_FREQ; /* 400 MHz */
306 clk->pll_max_out = SAM9G20_PLL_A_MAX_OUT_FREQ; /* 800 MHz */
307 clk->pll_mul_shift = SAM9G20_PLL_A_MUL_SHIFT;
308 clk->pll_mul_mask = SAM9G20_PLL_A_MUL_MASK;
309 clk->pll_div_shift = SAM9G20_PLL_A_DIV_SHIFT;
310 clk->pll_div_mask = SAM9G20_PLL_A_DIV_MASK;
311 clk->set_outb = at91_pll_outa;
312 at91_pmc_clock_deref(clk);
314 clk = at91_pmc_clock_ref("pllb");
315 clk->pll_min_in = SAM9G20_PLL_B_MIN_IN_FREQ; /* 2 MHz */
316 clk->pll_max_in = SAM9G20_PLL_B_MAX_IN_FREQ; /* 32 MHz */
317 clk->pll_min_out = SAM9G20_PLL_B_MIN_OUT_FREQ; /* 30 MHz */
318 clk->pll_max_out = SAM9G20_PLL_B_MAX_OUT_FREQ; /* 100 MHz */
319 clk->pll_mul_shift = SAM9G20_PLL_B_MUL_SHIFT;
320 clk->pll_mul_mask = SAM9G20_PLL_B_MUL_MASK;
321 clk->pll_div_shift = SAM9G20_PLL_B_DIV_SHIFT;
322 clk->pll_div_mask = SAM9G20_PLL_B_DIV_MASK;
323 clk->set_outb = at91_pll_outb;
324 at91_pmc_clock_deref(clk);
328 static device_method_t at91_methods[] = {
329 DEVMETHOD(device_probe, at91_probe),
330 DEVMETHOD(device_attach, at91_attach),
331 DEVMETHOD(device_identify, at91_identify),
335 static driver_t at91sam9_driver = {
338 sizeof(struct at91sam9_softc),
341 static devclass_t at91sam9_devclass;
343 DRIVER_MODULE(at91sam, atmelarm, at91sam9_driver, at91sam9_devclass, 0, 0);