Minor fixes to the MMC driver so that it picks
[freebsd:freebsd-omap.git] / sys / arm / omap / omap4 / omap44xx.c
1 /*-
2  * Copyright (c) 2011
3  *      Ben Gray <ben.r.gray@gmail.com>.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/bus.h>
35 #include <sys/kernel.h>
36 #include <sys/malloc.h>
37 #include <sys/module.h>
38
39 #define _ARM32_BUS_DMA_PRIVATE
40 #include <machine/bus.h>
41
42 #include <arm/omap/omapvar.h>
43 #include <arm/omap/omap4/omap4var.h>
44 #include <arm/omap/omap4/omap44xx_reg.h>
45
46 struct omap4_softc *g_omap4_softc = NULL;
47
48
49
50
51
52
53 /*
54  * Standard priority levels for the system -  0 has the highest priority and 63
55  * is the lowest.  
56  *
57  * Currently these are all set to the same standard value.
58  */
59 static const struct omap4_intr_conf omap44xx_irq_prio[] =
60 {
61         { OMAP44XX_IRQ_L2CACHE,         0,   0x1},      /* L2 cache controller interrupt */
62         { OMAP44XX_IRQ_CTI_0,           0,   0x1},      /* Cross-trigger module 0 (CTI0) interrupt */
63         { OMAP44XX_IRQ_CTI_1,           0,   0x1},      /* Cross-trigger module 1 (CTI1) interrupt */
64         { OMAP44XX_IRQ_ELM,             0,   0x1},      /* Error location process completion */
65         { OMAP44XX_IRQ_SYS_NIRQ,        0,   0x1},      /* External source (active low) */
66         { OMAP44XX_IRQ_L3_DBG,          0,   0x1},      /* L3 interconnect debug error */
67         { OMAP44XX_IRQ_L3_APP,          0,   0x1},      /* L3 interconnect application error */
68         { OMAP44XX_IRQ_PRCM_MPU,        0,   0x1},      /* PRCM module IRQ */
69         { OMAP44XX_IRQ_SDMA0,           0,   0x1},      /* System DMA request 0(3) */
70         { OMAP44XX_IRQ_SDMA1,           0,   0x1},      /* System DMA request 1(3) */
71         { OMAP44XX_IRQ_SDMA2,           0,   0x1},      /* System DMA request 2 */
72         { OMAP44XX_IRQ_SDMA3,           0,   0x1},      /* System DMA request 3 */
73         { OMAP44XX_IRQ_MCBSP4,          0,   0x1},      /* McBSP module 4 IRQ */
74         { OMAP44XX_IRQ_MCBSP1,          0,   0x1},      /* McBSP module 1 IRQ */
75         { OMAP44XX_IRQ_SR1,             0,   0x1},      /* SmartReflex™ 1 */
76         { OMAP44XX_IRQ_SR2,             0,   0x1},      /* SmartReflex™ 2 */
77         { OMAP44XX_IRQ_GPMC,            0,   0x1},      /* General-purpose memory controller module */
78         { OMAP44XX_IRQ_SGX,             0,   0x1},      /* 2D/3D graphics module */
79         { OMAP44XX_IRQ_MCBSP2,          0,   0x1},      /* McBSP module 2 */
80         { OMAP44XX_IRQ_MCBSP3,          0,   0x1},      /* McBSP module 3 */
81         { OMAP44XX_IRQ_ISS5,            0,   0x1},      /* Imaging subsystem interrupt 5 */
82         { OMAP44XX_IRQ_DSS,             0,   0x1},      /* Display subsystem module(3) */
83         { OMAP44XX_IRQ_MAIL_U0,         0,   0x1},      /* Mailbox user 0 request */
84         { OMAP44XX_IRQ_C2C_SSCM,        0,   0x1},      /* C2C status interrupt */
85         { OMAP44XX_IRQ_DSP_MMU,         0,   0x1},      /* DSP MMU */
86         { OMAP44XX_IRQ_GPIO1_MPU,       0,   0x1},      /* GPIO module 1(3) */
87         { OMAP44XX_IRQ_GPIO2_MPU,       0,   0x1},      /* GPIO module 2(3) */
88         { OMAP44XX_IRQ_GPIO3_MPU,       0,   0x1},      /* GPIO module 3(3) */
89         { OMAP44XX_IRQ_GPIO4_MPU,       0,   0x1},      /* GPIO module 4(3) */
90         { OMAP44XX_IRQ_GPIO5_MPU,       0,   0x1},      /* GPIO module 5(3) */
91         { OMAP44XX_IRQ_GPIO6_MPU,       0,   0x1},      /* GPIO module 6(3) */
92         { OMAP44XX_IRQ_WDT3,            0,   0x1},      /* Watchdog timer module 3 overflow */
93         { OMAP44XX_IRQ_GPT1,            0,   0x1},      /* General-purpose timer module 1 */
94         { OMAP44XX_IRQ_GPT2,            0,   0x1},      /* General-purpose timer module 2 */
95         { OMAP44XX_IRQ_GPT3,            0,   0x1},      /* General-purpose timer module 3 */
96         { OMAP44XX_IRQ_GPT4,            0,   0x1},      /* General-purpose timer module 4 */
97         { OMAP44XX_IRQ_GPT5,            0,   0x1},      /* General-purpose timer module 5(3) */
98         { OMAP44XX_IRQ_GPT6,            0,   0x1},      /* General-purpose timer module 6(3) */
99         { OMAP44XX_IRQ_GPT7,            0,   0x1},      /* General-purpose timer module 7(3) */
100         { OMAP44XX_IRQ_GPT8,            0,   0x1},      /* General-purpose timer module 8(3) */
101         { OMAP44XX_IRQ_GPT9,            0,   0x1},      /* General-purpose timer module 9 */
102         { OMAP44XX_IRQ_GPT10,           0,   0x1},      /* General-purpose timer module 10 */
103         { OMAP44XX_IRQ_GPT11,           0,   0x1},      /* General-purpose timer module 11 */
104         { OMAP44XX_IRQ_MCSPI4,          0,   0x1},      /* McSPI module 4 */
105         { OMAP44XX_IRQ_DSS_DSI1,        0,   0x1},      /* Display Subsystem DSI1 interrupt */
106         { OMAP44XX_IRQ_I2C1,            0,   0x1},      /* I2C module 1 */
107         { OMAP44XX_IRQ_I2C2,            0,   0x1},      /* I2C module 2 */
108         { OMAP44XX_IRQ_HDQ,             0,   0x1},      /* HDQ / One-wire */
109         { OMAP44XX_IRQ_MMC5,            0,   0x1},      /* MMC5 interrupt */
110         { OMAP44XX_IRQ_I2C3,            0,   0x1},      /* I2C module 3 */
111         { OMAP44XX_IRQ_I2C4,            0,   0x1},      /* I2C module 4 */
112         { OMAP44XX_IRQ_MCSPI1,          0,   0x1},      /* McSPI module 1 */
113         { OMAP44XX_IRQ_MCSPI2,          0,   0x1},      /* McSPI module 2 */
114         { OMAP44XX_IRQ_HSI_P1,          0,   0x1},      /* HSI Port 1 interrupt */
115         { OMAP44XX_IRQ_HSI_P2,          0,   0x1},      /* HSI Port 2 interrupt */
116         { OMAP44XX_IRQ_FDIF_3,          0,   0x1},      /* Face detect interrupt 3 */
117         { OMAP44XX_IRQ_UART4,           0,   0x1},      /* UART module 4 interrupt */
118         { OMAP44XX_IRQ_HSI_DMA,         0,   0x1},      /* HSI DMA engine MPU request */
119         { OMAP44XX_IRQ_UART1,           0,   0x1},      /* UART module 1 */
120         { OMAP44XX_IRQ_UART2,           0,   0x1},      /* UART module 2 */
121         { OMAP44XX_IRQ_UART3,           0,   0x1},      /* UART module 3 (also infrared)(3) */
122         { OMAP44XX_IRQ_PBIAS,           0,   0x1},      /* Merged interrupt for PBIASlite1 and 2 */
123         { OMAP44XX_IRQ_OHCI,            0,   0x1},      /* OHCI controller HSUSB MP Host Interrupt */
124         { OMAP44XX_IRQ_EHCI,            0,   0x1},      /* EHCI controller HSUSB MP Host Interrupt */
125         { OMAP44XX_IRQ_TLL,             0,   0x1},      /* HSUSB MP TLL Interrupt */
126         { OMAP44XX_IRQ_WDT2,            0,   0x1},      /* WDTIMER2 interrupt */
127         { OMAP44XX_IRQ_MMC1,            0,   0x1},      /* MMC/SD module 1 */
128         { OMAP44XX_IRQ_DSS_DSI2,        0,   0x1},      /* Display subsystem DSI2 interrupt */
129         { OMAP44XX_IRQ_MMC2,            0,   0x1},      /* MMC/SD module 2 */
130         { OMAP44XX_IRQ_MPU_ICR,         0,   0x1},      /* MPU ICR */
131         { OMAP44XX_IRQ_C2C_GPI,         0,   0x1},      /* C2C GPI interrupt */
132         { OMAP44XX_IRQ_FSUSB,           0,   0x1},      /* FS-USB - host controller Interrupt */
133         { OMAP44XX_IRQ_FSUSB_SMI,       0,   0x1},      /* FS-USB - host controller SMI Interrupt */
134         { OMAP44XX_IRQ_MCSPI3,          0,   0x1},      /* McSPI module 3 */
135         { OMAP44XX_IRQ_HSUSB_OTG,       0,   0x1},      /* High-Speed USB OTG controller */
136         { OMAP44XX_IRQ_HSUSB_OTG_DMA,   0,   0x1},      /* High-Speed USB OTG DMA controller */
137         { OMAP44XX_IRQ_MMC3,            0,   0x1},      /* MMC/SD module 3 */
138         { OMAP44XX_IRQ_MMC4,            0,   0x1},      /* MMC4 interrupt */
139         { OMAP44XX_IRQ_SLIMBUS1,        0,   0x1},      /* SLIMBUS1 interrupt */
140         { OMAP44XX_IRQ_SLIMBUS2,        0,   0x1},      /* SLIMBUS2 interrupt */
141         { OMAP44XX_IRQ_ABE,             0,   0x1},      /* Audio back-end interrupt */
142         { OMAP44XX_IRQ_CORTEXM3_MMU,    0,   0x1},      /* Cortex-M3 MMU interrupt */
143         { OMAP44XX_IRQ_DSS_HDMI,        0,   0x1},      /* Display subsystem HDMI interrupt */
144         { OMAP44XX_IRQ_SR_IVA,          0,   0x1},      /* SmartReflex IVA interrupt */
145         { OMAP44XX_IRQ_IVAHD1,          0,   0x1},      /* Sync interrupt from iCONT2 (vDMA) */
146         { OMAP44XX_IRQ_IVAHD2,          0,   0x1},      /* Sync interrupt from iCONT1 */
147         { OMAP44XX_IRQ_IVAHD_MAILBOX0,  0,   0x1},      /* IVAHD mailbox interrupt */
148         { OMAP44XX_IRQ_MCASP1,          0,   0x1},      /* McASP1 transmit interrupt */
149         { OMAP44XX_IRQ_EMIF1,           0,   0x1},      /* EMIF1 interrupt */
150         { OMAP44XX_IRQ_EMIF2,           0,   0x1},      /* EMIF2 interrupt */
151         { OMAP44XX_IRQ_MCPDM,           0,   0x1},      /* MCPDM interrupt */
152         { OMAP44XX_IRQ_DMM,             0,   0x1},      /* DMM interrupt */
153         { OMAP44XX_IRQ_DMIC,            0,   0x1},      /* DMIC interrupt */
154         { OMAP44XX_IRQ_SYS_NIRQ2,       0,   0x1},      /* External source 2 (active low) */
155         { OMAP44XX_IRQ_KBD,             0,   0x1},      /* Keyboard controller interrupt */
156         { -1, 0, 0 },
157 };
158
159
160 static const struct omap_cpu_dev omap44xx_devs[] =
161 {
162         
163         /**     
164          *      OMAP44xx - General Purpose Timers
165          *      This module provides interfaces to the general purpose timers.
166          */
167         {       .name      = "omap_gptimer",
168                 .unit      = 0,
169                 .mem       = { { OMAP44XX_GPTIMER1_HWBASE,  OMAP44XX_GPTIMER_SIZE },
170                                { OMAP44XX_GPTIMER2_HWBASE,  OMAP44XX_GPTIMER_SIZE },
171                                { OMAP44XX_GPTIMER3_HWBASE,  OMAP44XX_GPTIMER_SIZE },
172                                { OMAP44XX_GPTIMER4_HWBASE,  OMAP44XX_GPTIMER_SIZE },
173                                { OMAP44XX_GPTIMER5_HWBASE,  OMAP44XX_GPTIMER_SIZE },
174                                { OMAP44XX_GPTIMER6_HWBASE,  OMAP44XX_GPTIMER_SIZE },
175                                { OMAP44XX_GPTIMER7_HWBASE,  OMAP44XX_GPTIMER_SIZE },
176                                { OMAP44XX_GPTIMER8_HWBASE,  OMAP44XX_GPTIMER_SIZE },
177                                { OMAP44XX_GPTIMER9_HWBASE,  OMAP44XX_GPTIMER_SIZE },
178                                { OMAP44XX_GPTIMER10_HWBASE, OMAP44XX_GPTIMER_SIZE },
179                                { OMAP44XX_GPTIMER11_HWBASE, OMAP44XX_GPTIMER_SIZE },
180                                { 0,  0 }
181                              },
182                 .irqs      = {   OMAP44XX_IRQ_GPT1,
183                                  OMAP44XX_IRQ_GPT2,
184                                  OMAP44XX_IRQ_GPT3,
185                                  OMAP44XX_IRQ_GPT4,
186                                  OMAP44XX_IRQ_GPT5,
187                                  OMAP44XX_IRQ_GPT6,
188                                  OMAP44XX_IRQ_GPT7,
189                                  OMAP44XX_IRQ_GPT8,
190                                  OMAP44XX_IRQ_GPT9,
191                                  OMAP44XX_IRQ_GPT10,
192                                  OMAP44XX_IRQ_GPT11,
193                                  -1,
194                               },
195         },
196
197         /**     
198          *      OMAP44xx - DMA
199          *      This module provides interfaces to the direct memory access 
200          */
201         {       .name      = "omap_dma",
202                 .unit      = 0,
203                 .mem       = { { OMAP44XX_SDMA_HWBASE,  OMAP44XX_SDMA_SIZE },
204                                { 0,  0 }
205                              },
206                 .irqs      = {   OMAP44XX_IRQ_SDMA0,
207                                  OMAP44XX_IRQ_SDMA1,
208                                  OMAP44XX_IRQ_SDMA2,
209                                  OMAP44XX_IRQ_SDMA3,
210                                  -1,
211                               },
212         },
213
214         /**     
215          *      OMAP44xx - I2C
216          *      The OMAP44xx chips contain 4 independant I2C controllers.
217          *      Note: generally this should be the first function sub-device because
218          *            it's used for the TWL power control device.
219          */
220         {       .name      = "omap_i2c",
221                 .unit      = 0,
222                 .mem       = { { OMAP44XX_I2C1_HWBASE,  OMAP44XX_I2C_SIZE },
223                                { 0,  0 }
224                              },
225                 .irqs      = {   OMAP44XX_IRQ_I2C1,
226                                  -1,
227                               },
228         },
229         
230         /**     
231          *      OMAP44xx - MMC/SDIO
232          *      There are a total of 5 MMC modules on OMAP4, however at the moment only
233          *      1 is enabled.
234          */
235         {       .name      = "omap_mmc",
236                 .unit      = 0,
237                 .mem       = { { OMAP44XX_MMCHS1_HWBASE,  OMAP44XX_MMCHS_SIZE },
238                                { 0,  0 }
239                              },
240                 .irqs      = {   OMAP44XX_IRQ_MMC1,
241                                  -1,
242                               },
243         },
244
245         /**     
246          *      OMAP44xx - GPIO
247          *      There are 6 GPIO register sets, with each set representing 32 GPIO
248          *      pins.
249          */
250         {       .name      = "gpio",
251                 .unit      = 0,
252                 .mem       = { { OMAP44XX_GPIO1_HWBASE,   OMAP44XX_GPIO1_SIZE },
253                                { OMAP44XX_GPIO2_HWBASE,   OMAP44XX_GPIO2_SIZE },
254                                { OMAP44XX_GPIO3_HWBASE,   OMAP44XX_GPIO3_SIZE },
255                                { OMAP44XX_GPIO4_HWBASE,   OMAP44XX_GPIO4_SIZE },
256                                { OMAP44XX_GPIO5_HWBASE,   OMAP44XX_GPIO5_SIZE },
257                                { OMAP44XX_GPIO6_HWBASE,   OMAP44XX_GPIO6_SIZE },
258                                { 0,  0 }
259                              },
260                 .irqs      = {   OMAP44XX_IRQ_GPIO1_MPU,
261                                  OMAP44XX_IRQ_GPIO2_MPU,
262                                  OMAP44XX_IRQ_GPIO3_MPU,
263                                  OMAP44XX_IRQ_GPIO4_MPU,
264                                  OMAP44XX_IRQ_GPIO5_MPU,
265                                  OMAP44XX_IRQ_GPIO6_MPU,
266                                  -1,
267                               },
268         },
269
270
271         /**     
272          *      OMAP44xx - USB EHCI
273          *      The OMAP EHCI driver expects three different register sets, one for
274          *      the actual EHCI registers and the other two control the interface.
275          */
276         {       .name      = "ehci",
277                 .unit      = 0,
278                 .mem       = { { OMAP44XX_USB_EHCI_HWBASE,  OMAP44XX_USB_EHCI_SIZE },
279                                { OMAP44XX_USB_UHH_HWBASE,   OMAP44XX_USB_UHH_SIZE },
280                                { OMAP44XX_USB_TLL_HWBASE,   OMAP44XX_USB_TLL_SIZE },
281                                { 0,  0 }
282                              },
283                 .irqs      = {   OMAP44XX_IRQ_EHCI,
284                                  -1,
285                               },
286         },
287
288
289         {       0, 0, { { 0, 0 } }, { -1 } }
290 };
291
292
293 /**
294  *      omap_sdram_size - called from machdep to get the total memory size
295  * 
296  *      Since this function is called very early in the boot, there is none of the
297  *      bus handling code setup. However the boot device map will be setup, so
298  *      we can directly access registers already mapped.
299  *
300  *      This is a bit ugly, but since we need this information early on and the
301  *      only way to get it (appart from hardcoding it or via kernel args) is to read
302  *      from the EMIF_SRAM registers.
303  *
304  *      RETURNS:
305  *      The size of memory in bytes.
306  */
307 unsigned int
308 omap_sdram_size(void)
309 {
310         uint32_t sdram_cfg;
311         uint32_t ibank, ebank, pagesize;
312
313         /* Read the two SDRAM config register */
314         sdram_cfg = *(volatile uint32_t*)(OMAP44XX_L3_EMIF1_VBASE + 0x0008);
315
316         /* Read the REG_EBANK, REG_IBANK and REG_PAGESIZE - together these tell
317          * us the maximum size of memory we can access.
318          */
319         ibank = (sdram_cfg >> 4) & 0x7;
320         ebank = (sdram_cfg >> 3) & 0x1;
321         pagesize = (sdram_cfg >> 0) & 0x7;
322         
323         /* Using the above read values we determine the memory size, this was
324          * gleened from tables 15-106 and 15-107 in the omap44xx tech ref manual.
325          */
326         return (1UL << (25 + ibank + ebank + pagesize));
327 }
328
329
330
331
332 /**
333  *      omap44xx_add_child - add a child item to the root omap device
334  *      @dev: the parent device
335  *      @order: defines roughly the order with which to add the child to the parent
336  *      @name: the name to give to the child item
337  *      @unit: the unit number for the device
338  *      @addr: the base address of the register set for device
339  *      @size: the number of a bytes in register set
340  *      @irq: the IRQ number(s) for the device
341  * 
342  *      Adds a child to the omap base device.
343  *
344  */
345 static void
346 omap44xx_add_child(device_t dev, int prio, const char *name, int unit,
347                    const struct omap_mem_range mem[], const int irqs[])
348 {
349         device_t kid;
350         struct omap_ivar *ivar;
351         unsigned int i;
352         
353         /* Start by adding the actual child to the parent (us) */
354         kid = device_add_child_ordered(dev, prio, name, unit);
355         if (kid == NULL) {
356             printf("Can't add child %s%d ordered\n", name, unit);
357             return;
358         }
359         
360         /* Allocate some memory for the omap_ivar structure */ 
361         ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
362         if (ivar == NULL) {
363                 device_delete_child(dev, kid);
364                 printf("Can't add alloc ivar\n");
365                 return;
366         }
367         
368         /* Assign the ivars to the child item and populate with the device resources */
369         device_set_ivars(kid, ivar);
370         
371         /* Assign the IRQ(s) in the resource list */
372         resource_list_init(&ivar->resources);
373         if (irqs) {
374                 for (i = 0; *irqs != -1; i++, irqs++) {
375                         bus_set_resource(kid, SYS_RES_IRQ, i, *irqs, 1);
376                 }
377         }
378         
379         /* Assign the memory region to the resource list */
380         if (mem) {
381                 for (i = 0; mem->base != 0; i++, mem++) {
382                         bus_set_resource(kid, SYS_RES_MEMORY, i, mem->base, mem->size);
383                 }
384         }
385 }
386
387
388 /**
389  *      omap44xx_cpu_add_builtin_children - adds the SoC child components
390  *      @dev: this device, the one we are adding to
391  * 
392  *      Adds child devices from the omap44xx_devs list.
393  *
394  */
395 static void
396 omap44xx_cpu_add_builtin_children(device_t dev)
397 {
398         int i;
399         const struct omap_cpu_dev *walker;
400         
401         /* Setup all the clock devices - this is not the tick timers, rather it's
402          * the individual functional and interface clocks for the SoC modules.
403          */
404         omap4_clk_init(dev, 1);
405         
406         /* Setup the system control module driver, which basically is just the
407          * padconf (pinmux) for the OMAP44xx devices.
408          */
409         omap4_padconf_init(dev, 1);
410
411         /* Add the rest of the children from the array above */
412         for (i = 5, walker = omap44xx_devs; walker->name; i++, walker++) {
413                 omap44xx_add_child(dev, i, walker->name, walker->unit,
414                                    walker->mem, walker->irqs);
415         }
416 }
417
418
419 /**
420  *      omap44xx_identify - adds the SoC child components
421  *      @dev: this device, the one we are adding to
422  * 
423  *      Adds a child to the omap3 base device.
424  *
425  */
426 static void
427 omap44xx_identify(driver_t *drv, device_t parent)
428 {
429         int omap44xx_irqs[] = { 27, 29, -1 };
430         struct omap_mem_range omap44xx_mem[] = { { OMAP44XX_MPU_SUBSYS_HWBASE,
431                                                    OMAP44XX_MPU_SUBSYS_SIZE    },
432                                                  { 0, 0 } }; 
433
434         /* Add the resources for this "omap44xx" device, we add the memory
435          * and IRQ resources for the ARM cortex devices (timers, l2cache, etc).
436          */
437         omap44xx_add_child(parent, 0, "omap44xx", 0, omap44xx_mem, omap44xx_irqs);
438         
439         /* Add the other SOC components */
440         omap44xx_cpu_add_builtin_children(parent);
441 }
442
443 /**
444  *      omap44xx_probe - called when the device is probed
445  *      @dev: the new device
446  * 
447  *      All we do in this routine is set the description of this device
448  *
449  */
450 static int
451 omap44xx_probe(device_t dev)
452 {
453         device_set_desc(dev, "TI OMAP44XX");
454         return (0);
455 }
456
457 /**
458  *      omap44xx_attach - called when the device is attached
459  *      @dev: the new device
460  * 
461  *      All we do in this routine is set the description of this device
462  *
463  */
464 static int
465 omap44xx_attach(device_t dev)
466 {
467         struct omap_softc *omapsc = device_get_softc(device_get_parent(dev));
468         struct omap4_softc *sc = device_get_softc(dev);
469
470         sc->sc_iotag = omapsc->sc_iotag;
471         sc->sc_dev = dev;
472
473
474         /* Map in the Generic Interrupt Controller (GIC) register set */
475         if (bus_space_map(sc->sc_iotag, OMAP44XX_GIC_CPU_HWBASE,
476                           OMAP44XX_GIC_CPU_SIZE, 0, &sc->sc_gic_cpu_ioh)) {
477                 panic("%s: Cannot map registers", device_get_name(dev));
478         }
479
480         /* Also map in the CPU GIC register set */
481         if (bus_space_map(sc->sc_iotag, OMAP44XX_GIC_DIST_HWBASE,
482                           OMAP44XX_GIC_DIST_SIZE, 0, &sc->sc_gic_dist_ioh)) {
483                 panic("%s: Cannot map registers", device_get_name(dev));
484         }
485
486         /* And the private and global timer register set */
487         if (bus_space_map(sc->sc_iotag, OMAP44XX_PRV_TIMER_HWBASE,
488                           OMAP44XX_PRV_TIMER_SIZE, 0, &sc->sc_prv_timer_ioh)) {
489                 panic("%s: Cannot map registers", device_get_name(dev));
490         }
491         if (bus_space_map(sc->sc_iotag, OMAP44XX_GBL_TIMER_HWBASE,
492                           OMAP44XX_GBL_TIMER_SIZE, 0, &sc->sc_gbl_timer_ioh)) {
493                 panic("%s: Cannot map registers", device_get_name(dev));
494         }
495
496         /* Map in the PL310 (L2 cache controller) as well */
497         if (bus_space_map(sc->sc_iotag, OMAP44XX_PL310_HWBASE,
498                           OMAP44XX_PL310_SIZE, 0, &sc->sc_pl310_ioh)) {
499                 panic("%s: Cannot map registers", device_get_name(dev));
500         }
501
502
503
504         /* Save the device structure globally for the IRQ handling */
505         g_omap4_softc = sc;
506
507         /* Setup the PL310 L2 cache controller */
508         omap4_setup_l2cache_controller(g_omap4_softc);
509
510         /* TODO: Revisit - Install an interrupt post filter */
511         arm_post_filter = omap4_post_filter_intr;
512         
513         /* Setup the ARM GIC interrupt controller */
514         omap4_setup_intr_controller(g_omap4_softc, omap44xx_irq_prio);
515         omap4_setup_gic_cpu(g_omap4_softc, 0xF0);
516
517         return (0);
518 }
519
520
521
522 static device_method_t omap44xx_methods[] = {
523         DEVMETHOD(device_probe, omap44xx_probe),
524         DEVMETHOD(device_attach, omap44xx_attach),
525         DEVMETHOD(device_identify, omap44xx_identify),
526         {0, 0},
527 };
528
529 static driver_t omap44xx_driver = {
530         "omap44xx",
531         omap44xx_methods,
532         sizeof(struct omap4_softc),
533 };
534
535 static devclass_t omap44xx_devclass;
536
537 DRIVER_MODULE(omap44xx, omap, omap44xx_driver, omap44xx_devclass, 0, 0);