summaryrefslogtreecommitdiff
path: root/sys/arch/loongson/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/loongson/dev')
-rw-r--r--sys/arch/loongson/dev/bonito.c108
-rw-r--r--sys/arch/loongson/dev/bonitoreg.h45
-rw-r--r--sys/arch/loongson/dev/smfb.c20
3 files changed, 143 insertions, 30 deletions
diff --git a/sys/arch/loongson/dev/bonito.c b/sys/arch/loongson/dev/bonito.c
index 9e141c78cc5..83b52cab3dd 100644
--- a/sys/arch/loongson/dev/bonito.c
+++ b/sys/arch/loongson/dev/bonito.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bonito.c,v 1.11 2010/02/24 22:33:20 miod Exp $ */
+/* $OpenBSD: bonito.c,v 1.12 2010/02/28 21:35:41 miod Exp $ */
/* $NetBSD: bonito_mainbus.c,v 1.11 2008/04/28 20:23:10 martin Exp $ */
/* $NetBSD: bonito_pci.c,v 1.5 2008/04/28 20:23:28 martin Exp $ */
@@ -165,6 +165,8 @@ struct machine_bus_dma_tag bonito_bus_dma_tag = {
int bonito_io_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
bus_space_handle_t *);
+int bonito_mem_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
+ bus_space_handle_t *);
struct mips_bus_space bonito_pci_io_space_tag = {
.bus_base = PHYS_TO_XKPHYS(BONITO_PCIIO_BASE, CCA_NC),
@@ -189,7 +191,7 @@ struct mips_bus_space bonito_pci_io_space_tag = {
};
struct mips_bus_space bonito_pci_mem_space_tag = {
- .bus_base = PHYS_TO_XKPHYS(BONITO_PCILO_BASE, CCA_NC),
+ .bus_base = PHYS_TO_XKPHYS(0, CCA_NC),
._space_read_1 = generic_space_read_1,
._space_write_1 = generic_space_write_1,
._space_read_2 = generic_space_read_2,
@@ -204,7 +206,7 @@ struct mips_bus_space bonito_pci_mem_space_tag = {
._space_write_raw_4 = generic_space_write_raw_4,
._space_read_raw_8 = generic_space_read_raw_8,
._space_write_raw_8 = generic_space_write_raw_8,
- ._space_map = generic_space_map,
+ ._space_map = bonito_mem_map,
._space_unmap = generic_space_unmap,
._space_subregion = generic_space_region,
._space_vaddr = generic_space_vaddr
@@ -1136,6 +1138,106 @@ bonito_io_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size, int flags,
}
/*
+ * PCI memory access.
+ * Things are a bit complicated here, as we can either use one of the 64MB
+ * windows in PCILO space (making sure ranges spanning multiple windows will
+ * turn contiguous), or a direct access within the PCIHI space.
+ * Note that, on 2F systems, only the PCIHI range for which CPU->PCI accesses
+ * are enabled in the crossbar is usable.
+ */
+
+int
+bonito_mem_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size, int flags,
+ bus_space_handle_t *bshp)
+{
+ uint32_t pcimap;
+ bus_addr_t pcilo_w[3];
+ bus_addr_t ws, we, w;
+ bus_addr_t end = offs + size - 1;
+ int is2f, pcilo_window;
+
+ /*
+ * Decode PCIMAP, and figure out what PCILO mappings are
+ * possible.
+ */
+
+ pcimap = REGVAL(BONITO_PCIMAP);
+ pcilo_w[0] = (pcimap & BONITO_PCIMAP_PCIMAP_LO0) >>
+ BONITO_PCIMAP_PCIMAP_LO0_SHIFT;
+ pcilo_w[1] = (pcimap & BONITO_PCIMAP_PCIMAP_LO1) >>
+ BONITO_PCIMAP_PCIMAP_LO1_SHIFT;
+ pcilo_w[2] = (pcimap & BONITO_PCIMAP_PCIMAP_LO2) >>
+ BONITO_PCIMAP_PCIMAP_LO2_SHIFT;
+
+ /*
+ * Check if the 64MB areas we want to span are all available as
+ * contiguous PCILO mappings.
+ */
+
+ ws = offs >> 26;
+ we = end >> 26;
+
+ pcilo_window = -1;
+ if (ws == pcilo_w[0])
+ pcilo_window = 0;
+ else if (ws == pcilo_w[1])
+ pcilo_window = 1;
+ else if (ws == pcilo_w[2])
+ pcilo_window = 2;
+
+ if (pcilo_window >= 0) {
+ /* contiguous area test */
+ for (w = ws + 1; w <= we; w++) {
+ if (pcilo_window + (w - ws) > 2 ||
+ w != pcilo_w[pcilo_window + (w - ws)]) {
+ pcilo_window = -1;
+ break;
+ }
+ }
+ }
+
+ if (pcilo_window >= 0) {
+ *bshp = t->bus_base + BONITO_PCILO_BASE +
+ BONITO_PCIMAP_WINBASE(pcilo_window) +
+ BONITO_PCIMAP_WINOFFSET(offs);
+ return 0;
+ }
+
+ /*
+ * No luck, try a PCIHI mapping.
+ */
+
+ /* may be used before curcpu() points to valid data */
+ if ((cp0_get_prid() & 0xffff) ==
+ ((MIPS_LOONGSON2 << 8) | (0x2f - 0x2c)))
+ is2f = 1;
+ else
+ is2f = 0;
+
+ if (is2f) {
+ if (offs >= LS2F_PCIHI_BASE && end <= LS2F_PCIHI_TOP) {
+ *bshp = t->bus_base + offs;
+ return 0;
+ }
+ } else {
+ /* PCI1.5 */
+ if (offs >= BONITO_PCIHI_BASE && end <= BONITO_PCIHI_TOP) {
+ *bshp = t->bus_base + offs;
+ return 0;
+ }
+
+ /* PCI2 */
+ w = pcimap & BONITO_PCIMAP_PCIMAP_2 ? 0x80000000UL : 0;
+ if (offs >= w && end < (w + 0x80000000UL)) {
+ *bshp = t->bus_base + 0x80000000UL + (offs - w);
+ return 0;
+ }
+ }
+
+ return EINVAL;
+}
+
+/*
* PCI resource handling
*/
diff --git a/sys/arch/loongson/dev/bonitoreg.h b/sys/arch/loongson/dev/bonitoreg.h
index c0ea9a43ff0..d542523f9d5 100644
--- a/sys/arch/loongson/dev/bonitoreg.h
+++ b/sys/arch/loongson/dev/bonitoreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bonitoreg.h,v 1.5 2010/02/23 20:41:33 miod Exp $ */
+/* $OpenBSD: bonitoreg.h,v 1.6 2010/02/28 21:35:41 miod Exp $ */
/* $NetBSD: bonitoreg.h,v 1.6 2005/12/24 20:07:19 perry Exp $ */
/*
@@ -34,35 +34,35 @@
#define REGVAL(x) *((volatile u_int32_t *)PHYS_TO_XKPHYS(x, CCA_NC))
-#define BONITO_FLASH_BASE 0x1c000000
-#define BONITO_FLASH_SIZE 0x02000000
+#define BONITO_FLASH_BASE 0x1c000000UL
+#define BONITO_FLASH_SIZE 0x02000000UL
#define BONITO_FLASH_TOP (BONITO_FLASH_BASE+BONITO_FLASH_SIZE-1)
-#define BONITO_BOOT_BASE 0x1fc00000
-#define BONITO_BOOT_SIZE 0x00100000
+#define BONITO_BOOT_BASE 0x1fc00000UL
+#define BONITO_BOOT_SIZE 0x00100000UL
#define BONITO_BOOT_TOP (BONITO_BOOT_BASE+BONITO_BOOT_SIZE-1)
-#define BONITO_REG_BASE 0x1fe00000
-#define BONITO_REG_SIZE 0x00040000
+#define BONITO_REG_BASE 0x1fe00000UL
+#define BONITO_REG_SIZE 0x00040000UL
#define BONITO_REG_TOP (BONITO_REG_BASE+BONITO_REG_SIZE-1)
-#define BONITO_PCILO_BASE 0x10000000
-#define BONITO_PCILO_SIZE 0x0c000000
+#define BONITO_PCILO_BASE 0x10000000UL
+#define BONITO_PCILO_SIZE 0x0c000000UL
#define BONITO_PCILO_TOP (BONITO_PCILO_BASE+BONITO_PCILO_SIZE-1)
-#define BONITO_PCILO0_BASE 0x10000000
-#define BONITO_PCILO1_BASE 0x14000000
-#define BONITO_PCILO2_BASE 0x18000000
-#define BONITO_PCIHI_BASE 0x20000000
-#define BONITO_PCIHI_SIZE 0x20000000
+#define BONITO_PCILO0_BASE 0x10000000UL
+#define BONITO_PCILO1_BASE 0x14000000UL
+#define BONITO_PCILO2_BASE 0x18000000UL
+#define BONITO_PCIHI_BASE 0x20000000UL
+#define BONITO_PCIHI_SIZE 0x60000000UL
#define BONITO_PCIHI_TOP (BONITO_PCIHI_BASE+BONITO_PCIHI_SIZE-1)
-#define LS2F_PCIHI_BASE 0x40000000
-#define LS2F_PCIHI_SIZE 0x40000000
+#define LS2F_PCIHI_BASE 0x40000000UL
+#define LS2F_PCIHI_SIZE 0x40000000UL
#define LS2F_PCIHI_TOP (LS2F_PCIHI_BASE+LS2F_PCIHI_SIZE-1)
-#define BONITO_PCIIO_BASE 0x1fd00000
-#define BONITO_PCIIO_LEGACY 0x00004000
-#define BONITO_PCIIO_SIZE 0x00100000
+#define BONITO_PCIIO_BASE 0x1fd00000UL
+#define BONITO_PCIIO_LEGACY 0x00004000UL
+#define BONITO_PCIIO_SIZE 0x00100000UL
#define BONITO_PCIIO_TOP (BONITO_PCIIO_BASE+BONITO_PCIIO_SIZE-1)
-#define BONITO_PCICFG_BASE 0x1fe80000
-#define BONITO_PCICFG_SIZE 0x00080000
+#define BONITO_PCICFG_BASE 0x1fe80000UL
+#define BONITO_PCICFG_SIZE 0x00080000UL
#define BONITO_PCICFG_TOP (BONITO_PCICFG_BASE+BONITO_PCICFG_SIZE-1)
/* Bonito Register Bases */
@@ -149,8 +149,9 @@
#define BONITO_PCIMAP_PCIMAP_LO1_SHIFT 6
#define BONITO_PCIMAP_PCIMAP_LO2 0x0003f000
#define BONITO_PCIMAP_PCIMAP_LO2_SHIFT 12
+#define BONITO_PCIMAP_PCIMAP_2 0x00040000 /* real bonito only */
#define BONITO_PCIMAP_WIN(WIN,ADDR) ((((ADDR)>>26) & BONITO_PCIMAP_PCIMAP_LO0) << ((WIN)*6))
-#define BONITO_PCIMAP_WINSIZE (1<<26)
+#define BONITO_PCIMAP_WINSIZE (1UL<<26)
#define BONITO_PCIMAP_WINOFFSET(ADDR) ((ADDR) & (BONITO_PCIMAP_WINSIZE - 1))
#define BONITO_PCIMAP_WINBASE(ADDR) ((ADDR) << 26)
diff --git a/sys/arch/loongson/dev/smfb.c b/sys/arch/loongson/dev/smfb.c
index 47496d92747..aeec1208a72 100644
--- a/sys/arch/loongson/dev/smfb.c
+++ b/sys/arch/loongson/dev/smfb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smfb.c,v 1.6 2010/02/26 14:53:11 miod Exp $ */
+/* $OpenBSD: smfb.c,v 1.7 2010/02/28 21:35:41 miod Exp $ */
/*
* Copyright (c) 2009, 2010 Miodrag Vallat.
@@ -543,13 +543,15 @@ smfb_wait(struct smfb *fb)
* Early console code
*/
-int smfb_cnattach(bus_space_tag_t, pcitag_t, pcireg_t);
+int smfb_cnattach(bus_space_tag_t, bus_space_tag_t, pcitag_t, pcireg_t);
int
-smfb_cnattach(bus_space_tag_t memt, pcitag_t tag, pcireg_t id)
+smfb_cnattach(bus_space_tag_t memt, bus_space_tag_t iot, pcitag_t tag,
+ pcireg_t id)
{
long defattr;
struct rasops_info *ri;
+ bus_space_handle_t fbh, regh;
vaddr_t fbbase, regbase;
pcireg_t bar;
int rc, is5xx;
@@ -571,13 +573,21 @@ smfb_cnattach(bus_space_tag_t memt, pcitag_t tag, pcireg_t id)
bar = pci_conf_read_early(tag, PCI_MAPREG_START);
if (PCI_MAPREG_TYPE(bar) != PCI_MAPREG_TYPE_MEM)
return EINVAL;
- fbbase = memt->bus_base + PCI_MAPREG_MEM_ADDR(bar);
+ rc = bus_space_map(memt, PCI_MAPREG_MEM_ADDR(bar), 1 /* XXX */,
+ BUS_SPACE_MAP_LINEAR, &fbh);
+ if (rc != 0)
+ return rc;
+ fbbase = (vaddr_t)bus_space_vaddr(memt, fbh);
if (smfbcn.is5xx) {
bar = pci_conf_read_early(tag, PCI_MAPREG_START + 0x04);
if (PCI_MAPREG_TYPE(bar) != PCI_MAPREG_TYPE_MEM)
return EINVAL;
- regbase = memt->bus_base + PCI_MAPREG_MEM_ADDR(bar);
+ rc = bus_space_map(memt, PCI_MAPREG_MEM_ADDR(bar), 1 /* XXX */,
+ BUS_SPACE_MAP_LINEAR, &regh);
+ if (rc != 0)
+ return rc;
+ regbase = (vaddr_t)bus_space_vaddr(memt, regh);
} else {
regbase = 0;
}