summaryrefslogtreecommitdiffstats
path: root/sys/arm/s3c2xx0
diff options
context:
space:
mode:
authorandrew <andrew@FreeBSD.org>2010-07-22 23:12:19 +0000
committerandrew <andrew@FreeBSD.org>2010-07-22 23:12:19 +0000
commit621cb47cb7c730cb440fc3208c574c78ae05c003 (patch)
tree435740aac9f96863c4f01a48e90d07fba38a5e3c /sys/arm/s3c2xx0
parent9f037cc06a87e61c57a650c2ed9d1cc1a4204832 (diff)
downloadFreeBSD-src-621cb47cb7c730cb440fc3208c574c78ae05c003.zip
FreeBSD-src-621cb47cb7c730cb440fc3208c574c78ae05c003.tar.gz
Rework how device memory is allocated on the s3c24x0 CPU's.
The device virtual addresses are now able to be allocated at runtime rather than from the static pmap_devmap at boot. The only exception is memory required before we have had a chance to dynamically allocate it. While here reduce the space between the statically allocated devices by reducing the distance between the virtual addresses. Approved by: imp (mentor)
Diffstat (limited to 'sys/arm/s3c2xx0')
-rw-r--r--sys/arm/s3c2xx0/s3c24x0.c89
-rw-r--r--sys/arm/s3c2xx0/s3c24x0_machdep.c30
-rw-r--r--sys/arm/s3c2xx0/s3c24x0reg.h18
-rw-r--r--sys/arm/s3c2xx0/s3c2xx0_space.c4
-rw-r--r--sys/arm/s3c2xx0/s3c2xx0var.h7
5 files changed, 67 insertions, 81 deletions
diff --git a/sys/arm/s3c2xx0/s3c24x0.c b/sys/arm/s3c2xx0/s3c24x0.c
index b0e338a..c896bcf 100644
--- a/sys/arm/s3c2xx0/s3c24x0.c
+++ b/sys/arm/s3c2xx0/s3c24x0.c
@@ -83,22 +83,22 @@ static struct {
{ "timer", 0, -1, { { 0 }, } },
{ "uart", 1, 0, {
{ SYS_RES_IRQ, S3C24X0_INT_UART0, 1 },
- { SYS_RES_IOPORT, S3C24X0_UART_BASE(0),
+ { SYS_RES_IOPORT, S3C24X0_UART_PA_BASE(0),
S3C24X0_UART_BASE(1) - S3C24X0_UART_BASE(0) },
} },
{ "uart", 1, 1, {
{ SYS_RES_IRQ, S3C24X0_INT_UART1, 1 },
- { SYS_RES_IOPORT, S3C24X0_UART_BASE(1),
+ { SYS_RES_IOPORT, S3C24X0_UART_PA_BASE(1),
S3C24X0_UART_BASE(2) - S3C24X0_UART_BASE(1) },
} },
{ "uart", 1, 2, {
{ SYS_RES_IRQ, S3C24X0_INT_UART2, 1 },
- { SYS_RES_IOPORT, S3C24X0_UART_BASE(2),
+ { SYS_RES_IOPORT, S3C24X0_UART_PA_BASE(2),
S3C24X0_UART_BASE(3) - S3C24X0_UART_BASE(2) },
} },
{ "ohci", 0, -1, {
{ SYS_RES_IRQ, S3C24X0_INT_USBH, 0 },
- { SYS_RES_IOPORT, S3C24X0_USBHC_BASE, S3C24X0_USBHC_SIZE },
+ { SYS_RES_IOPORT, S3C24X0_USBHC_PA_BASE, S3C24X0_USBHC_SIZE },
} },
{ NULL },
};
@@ -257,8 +257,18 @@ s3c24x0_alloc_resource(device_t bus, device_t child, int type, int *rid,
res = rman_reserve_resource(
&s3c2xx0_softc->s3c2xx0_mem_rman,
start, end, count, flags, child);
+ if (res == NULL)
+ panic("Unable to map address space %#lX-%#lX", start,
+ end);
+
rman_set_bustag(res, &s3c2xx0_bs_tag);
rman_set_bushandle(res, start);
+ if (flags & RF_ACTIVE) {
+ if (bus_activate_resource(child, type, *rid, res)) {
+ rman_release_resource(res);
+ return (NULL);
+ }
+ }
break;
}
@@ -279,6 +289,16 @@ static int
s3c24x0_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
+ bus_space_handle_t p;
+ int error;
+
+ if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+ error = bus_space_map(rman_get_bustag(r),
+ rman_get_bushandle(r), rman_get_size(r), 0, &p);
+ if (error)
+ return (error);
+ rman_set_bushandle(r, p);
+ }
return (rman_activate_resource(r));
}
@@ -335,32 +355,29 @@ s3c24x0_attach(device_t dev)
s3c2xx0_softc = &(sc->sc_sx);
sc->sc_sx.sc_iot = iot = &s3c2xx0_bs_tag;
+ s3c2xx0_softc->s3c2xx0_irq_rman.rm_type = RMAN_ARRAY;
+ s3c2xx0_softc->s3c2xx0_irq_rman.rm_descr = "S3C24X0 IRQs";
+ s3c2xx0_softc->s3c2xx0_mem_rman.rm_type = RMAN_ARRAY;
+ s3c2xx0_softc->s3c2xx0_mem_rman.rm_descr = "S3C24X0 Device Registers";
+ if (rman_init(&s3c2xx0_softc->s3c2xx0_irq_rman) != 0 ||
+ rman_manage_region(&s3c2xx0_softc->s3c2xx0_irq_rman, 0,
+ S3C2410_SUBIRQ_MAX) != 0) /* XXX Change S3C2440_SUBIRQ_MAX depending on micro */
+ panic("s3c24x0_attach: failed to set up IRQ rman");
+ /* Manage the registor memory space */
+ if ((rman_init(&s3c2xx0_softc->s3c2xx0_mem_rman) != 0) ||
+ (rman_manage_region(&s3c2xx0_softc->s3c2xx0_mem_rman,
+ S3C24X0_DEV_VA_OFFSET,
+ S3C24X0_DEV_VA_OFFSET + S3C24X0_DEV_VA_SIZE) != 0) ||
+ (rman_manage_region(&s3c2xx0_softc->s3c2xx0_mem_rman,
+ S3C24X0_DEV_START, S3C24X0_DEV_STOP) != 0))
+ panic("s3c24x0_attach: failed to set up register rman");
- if (bus_space_map(iot,
- S3C24X0_INTCTL_PA_BASE, S3C24X0_INTCTL_SIZE,
- BUS_SPACE_MAP_LINEAR, &sc->sc_sx.sc_intctl_ioh))
- panic("Cannot map the interrupt controller");
-
- /* Map the GPIO registers */
- if (bus_space_map(iot, S3C24X0_GPIO_PA_BASE, S3C2410_GPIO_SIZE,
- 0, &sc->sc_sx.sc_gpio_ioh))
- panic("Cannot map the GPIO");
- /* Clock manager */
- if (bus_space_map(iot, S3C24X0_CLKMAN_PA_BASE,
- S3C24X0_CLKMAN_SIZE, 0, &sc->sc_sx.sc_clkman_ioh))
- panic("cannot map the clock");
-
- if (bus_space_map(iot, S3C24X0_TIMER_PA_BASE,
- S3C24X0_TIMER_SIZE, 0, &sc->sc_timer_ioh))
- panic("cannot map the TIMER");
-
- if (bus_space_map(iot, S3C24X0_USBHC_PA_BASE,
- S3C24X0_USBHC_SIZE, 0, &sc->sc_sx.sc_ohci_ioh))
- panic("cannot map the USB Host");
-
- if (bus_space_map(iot, S3C24X0_WDT_PA_BASE,
- S3C24X0_WDT_SIZE, 0, &sc->sc_sx.sc_wdt_ioh))
- panic("cannot map the watchdog timer");
+ /* These are needed for things without a proper device to attach to */
+ sc->sc_sx.sc_intctl_ioh = S3C24X0_INTCTL_BASE;
+ sc->sc_sx.sc_gpio_ioh = S3C24X0_GPIO_BASE;
+ sc->sc_sx.sc_clkman_ioh = S3C24X0_CLKMAN_BASE;
+ sc->sc_sx.sc_wdt_ioh = S3C24X0_WDT_BASE;
+ sc->sc_timer_ioh = S3C24X0_TIMER_BASE;
/*
* Identify the CPU
@@ -376,20 +393,6 @@ s3c24x0_attach(device_t dev)
/*
* Attach children devices
*/
- s3c2xx0_softc->s3c2xx0_irq_rman.rm_type = RMAN_ARRAY;
- s3c2xx0_softc->s3c2xx0_irq_rman.rm_descr = "S3C24X0 IRQs";
- s3c2xx0_softc->s3c2xx0_mem_rman.rm_type = RMAN_ARRAY;
- s3c2xx0_softc->s3c2xx0_mem_rman.rm_descr = "S3C24X0 Memory";
- if (rman_init(&s3c2xx0_softc->s3c2xx0_irq_rman) != 0 ||
- rman_manage_region(&s3c2xx0_softc->s3c2xx0_irq_rman, 0,
- S3C2410_SUBIRQ_MAX) != 0)
- panic("s3c24x0_attach: failed to set up IRQ rman");
- /* Manage the registor memory space */
- if ((rman_init(&s3c2xx0_softc->s3c2xx0_mem_rman) != 0) ||
- (rman_manage_region(&s3c2xx0_softc->s3c2xx0_mem_rman,
- S3C24X0_DEV_VA_OFFSET,
- S3C24X0_DEV_VA_OFFSET + S3C24X0_DEV_VA_SIZE) != 0))
- panic("s3c24x0_attach: failed to set up register rman");
for (i = 0; s3c24x0_children[i].name != NULL; i++) {
child = s3c24x0_add_child(dev, s3c24x0_children[i].prio,
diff --git a/sys/arm/s3c2xx0/s3c24x0_machdep.c b/sys/arm/s3c2xx0/s3c24x0_machdep.c
index 2c73842..899222f 100644
--- a/sys/arm/s3c2xx0/s3c24x0_machdep.c
+++ b/sys/arm/s3c2xx0/s3c24x0_machdep.c
@@ -146,6 +146,9 @@ static struct trapframe proc0_tf;
/* Static device mappings. */
static const struct pmap_devmap s3c24x0_devmap[] = {
+ /*
+ * Map the devices we need early on.
+ */
{
_A(S3C24X0_CLKMAN_BASE),
_A(S3C24X0_CLKMAN_PA_BASE),
@@ -161,13 +164,6 @@ static const struct pmap_devmap s3c24x0_devmap[] = {
PTE_NOCACHE,
},
{
- _A(S3C24X0_IIC_BASE),
- _A(S3C24X0_IIC_PA_BASE),
- _S(S3C24X0_IIC_SIZE),
- VM_PROT_READ|VM_PROT_WRITE,
- PTE_NOCACHE,
- },
- {
_A(S3C24X0_INTCTL_BASE),
_A(S3C24X0_INTCTL_PA_BASE),
_S(S3C24X0_INTCTL_SIZE),
@@ -175,16 +171,9 @@ static const struct pmap_devmap s3c24x0_devmap[] = {
PTE_NOCACHE,
},
{
- _A(S3C24X0_LCDC_BASE),
- _A(S3C24X0_LCDC_PA_BASE),
- _S(S3C24X0_LCDC_SIZE),
- VM_PROT_READ|VM_PROT_WRITE,
- PTE_NOCACHE,
- },
- {
- _A(S3C24X0_SDI_BASE),
- _A(S3C24X0_SDI_PA_BASE),
- _S(S3C2410_SDI_SIZE),
+ _A(S3C24X0_TIMER_BASE),
+ _A(S3C24X0_TIMER_PA_BASE),
+ _S(S3C24X0_TIMER_SIZE),
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
@@ -196,13 +185,6 @@ static const struct pmap_devmap s3c24x0_devmap[] = {
PTE_NOCACHE,
},
{
- _A(S3C24X0_USBHC_BASE),
- _A(S3C24X0_USBHC_PA_BASE),
- _S(S3C24X0_USBHC_SIZE),
- VM_PROT_READ|VM_PROT_WRITE,
- PTE_NOCACHE,
- },
- {
_A(S3C24X0_WDT_BASE),
_A(S3C24X0_WDT_PA_BASE),
_S(S3C24X0_WDT_SIZE),
diff --git a/sys/arm/s3c2xx0/s3c24x0reg.h b/sys/arm/s3c2xx0/s3c24x0reg.h
index 3b8dc6e..25bee39 100644
--- a/sys/arm/s3c2xx0/s3c24x0reg.h
+++ b/sys/arm/s3c2xx0/s3c24x0reg.h
@@ -46,13 +46,21 @@
#include <arm/s3c2xx0/s3c2xx0reg.h>
/*
- * Map the device registers into kernel space
+ * Map the device registers into kernel space.
+ *
+ * As most devices use less than 1 page of memory reduce
+ * the distance between allocations by right shifting
+ * S3C24X0_DEV_SHIFT bits. Because the UART takes 3*0x4000
+ * bytes the upper limit on S3C24X0_DEV_SHIFT is 4.
+ * TODO: Fix the UART code so we can increase this value.
*/
#define S3C24X0_DEV_START 0x48000000
#define S3C24X0_DEV_STOP 0x60000000
-#define S3C24X0_DEV_VA_OFFSET 0xD0000000
-#define S3C24X0_DEV_VA_SIZE (S3C24X0_DEV_STOP - S3C24X0_DEV_START)
-#define S3C24X0_DEV_PA_TO_VA(x) (x - S3C24X0_DEV_START + S3C24X0_DEV_VA_OFFSET)
+#define S3C24X0_DEV_VA_OFFSET 0xD8000000
+#define S3C24X0_DEV_SHIFT 4
+#define S3C24X0_DEV_PA_SIZE (S3C24X0_DEV_STOP - S3C24X0_DEV_START)
+#define S3C24X0_DEV_VA_SIZE (S3C24X0_DEV_PA_SIZE >> S3C24X0_DEV_SHIFT)
+#define S3C24X0_DEV_PA_TO_VA(x) ((x >> S3C24X0_DEV_SHIFT) - S3C24X0_DEV_START + S3C24X0_DEV_VA_OFFSET)
/*
* Physical address of integrated peripherals
@@ -77,7 +85,7 @@
#define S3C24X0_UART0_PA_BASE 0x50000000
#define S3C24X0_UART0_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_UART0_PA_BASE)
#define S3C24X0_UART_PA_BASE(n) (S3C24X0_UART0_PA_BASE+0x4000*(n))
-#define S3C24X0_UART_BASE(n) S3C24X0_DEV_PA_TO_VA(S3C24X0_UART_PA_BASE(n))
+#define S3C24X0_UART_BASE(n) (S3C24X0_UART0_BASE+0x4000*(n))
#define S3C24X0_TIMER_PA_BASE 0x51000000
#define S3C24X0_TIMER_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_TIMER_PA_BASE)
#define S3C24X0_USBDC_PA_BASE 0x5200140
diff --git a/sys/arm/s3c2xx0/s3c2xx0_space.c b/sys/arm/s3c2xx0/s3c2xx0_space.c
index 2349672..958e658 100644
--- a/sys/arm/s3c2xx0/s3c2xx0_space.c
+++ b/sys/arm/s3c2xx0/s3c2xx0_space.c
@@ -182,9 +182,7 @@ s3c2xx0_bs_map(void *t, bus_addr_t bpa, bus_size_t size,
startpa = trunc_page(bpa);
endpa = round_page(bpa + size);
- /* XXX use extent manager to check duplicate mapping */
-
- va = kmem_alloc(kernel_map, endpa - startpa);
+ va = kmem_alloc_nofault(kernel_map, endpa - startpa);
if (!va)
return (ENOMEM);
diff --git a/sys/arm/s3c2xx0/s3c2xx0var.h b/sys/arm/s3c2xx0/s3c2xx0var.h
index fea800e..fea0982 100644
--- a/sys/arm/s3c2xx0/s3c2xx0var.h
+++ b/sys/arm/s3c2xx0/s3c2xx0var.h
@@ -53,13 +53,8 @@ struct s3c2xx0_softc {
bus_space_tag_t sc_iot;
bus_space_handle_t sc_intctl_ioh;
- bus_space_handle_t sc_clkman_ioh; /* Clock manager */
bus_space_handle_t sc_gpio_ioh; /* GPIO */
- bus_space_handle_t sc_lcd_ioh; /* LCD */
- bus_space_handle_t sc_rtc_ioh; /* real time clock */
- bus_space_handle_t sc_mci_ioh; /* MMC/SD */
- bus_space_handle_t sc_iic_ioh; /* IIC */
- bus_space_handle_t sc_ohci_ioh; /* USB/OHCI */
+ bus_space_handle_t sc_clkman_ioh; /* Clock manager */
bus_space_handle_t sc_wdt_ioh; /* Watchdog Timer */
bus_dma_tag_t sc_dmat;
OpenPOWER on IntegriCloud