diff options
Diffstat (limited to 'sys/arch/loongson/dev')
-rw-r--r-- | sys/arch/loongson/dev/bonito.c | 108 | ||||
-rw-r--r-- | sys/arch/loongson/dev/bonitoreg.h | 45 | ||||
-rw-r--r-- | sys/arch/loongson/dev/smfb.c | 20 |
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, ®h); + if (rc != 0) + return rc; + regbase = (vaddr_t)bus_space_vaddr(memt, regh); } else { regbase = 0; } |