diff --git a/sys/arch/hpcsh/dev/hd64461/hd64461pcmcia.c b/sys/arch/hpcsh/dev/hd64461/hd64461pcmcia.c index 6880e1e7c257..4b4375f3c17b 100644 --- a/sys/arch/hpcsh/dev/hd64461/hd64461pcmcia.c +++ b/sys/arch/hpcsh/dev/hd64461/hd64461pcmcia.c @@ -1,4 +1,4 @@ -/* $NetBSD: hd64461pcmcia.c,v 1.1 2001/02/21 15:39:09 uch Exp $ */ +/* $NetBSD: hd64461pcmcia.c,v 1.2 2001/03/08 15:13:14 uch Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -63,6 +63,8 @@ #include #include +#include "locators.h" + #ifdef HD64461PCMCIA_DEBUG int hd64461pcmcia_debug = 1; #define DPRINTF(fmt, args...) \ @@ -226,12 +228,13 @@ static void power_on(enum controller_channel); static void memory_window_mode(enum controller_channel, enum memory_window_mode); static void memory_window_16(enum controller_channel, enum memory_window_16); -static void memory_window_32(enum controller_channel, enum memory_window_32) - __attribute__((__unused__)); +/* bus width */ +static void set_bus_width(enum controller_channel, int); #ifdef DEBUG static void hd64461pcmcia_info(struct hd64461pcmcia_softc *); #endif -#define __delay(x) delay((x) * 100) //XXX + +#define DELAY_MS(x) delay((x) * 1000) static int hd64461pcmcia_match(struct device *parent, struct cfdata *cf, void *aux) @@ -323,7 +326,20 @@ static int hd64461pcmcia_submatch(struct device *parent, struct cfdata *cf, void *aux) { struct pcmciabus_attach_args *paa = aux; + struct hd64461pcmcia_channel *ch = + (struct hd64461pcmcia_channel *)paa->pch; + if (ch->ch_channel == CHANNEL_0) { + if (cf->cf_loc[PCMCIABUSCF_CONTROLLER] != + PCMCIABUSCF_CONTROLLER_DEFAULT && + cf->cf_loc[PCMCIABUSCF_CONTROLLER] != 0) + return 0; + } else { + if (cf->cf_loc[PCMCIABUSCF_CONTROLLER] != + PCMCIABUSCF_CONTROLLER_DEFAULT && + cf->cf_loc[PCMCIABUSCF_CONTROLLER] != 1) + return 0; + } paa->pct = (pcmcia_chipset_tag_t)&hd64461pcmcia_functions; return ((*cf->cf_attach->ca_match)(parent, cf, aux)); @@ -366,7 +382,6 @@ hd64461pcmcia_attach_channel(struct hd64461pcmcia_softc *sc, _chip_socket_disable(ch); /* enable CSC interrupt only */ if (channel == CHANNEL_0) { - /* real I/O space */ ch->ch_iobase = 0; ch->ch_iosize = HD64461_PCC0_IOSIZE; ch->ch_iot = bus_space_create("PCMCIA I/O port", @@ -377,13 +392,7 @@ hd64461pcmcia_attach_channel(struct hd64461pcmcia_softc *sc, hd64461_intr_establish(HD64461_IRQ_PCC0, IST_LEVEL, IPL_TTY, hd64461pcmcia_channel0_intr, ch); } else { - /* Compact Flash memory mapped mode (Common memory space) */ - ch->ch_iobase = 0; - ch->ch_iosize = 0x10; /* 16byte (dont' use 0x400-0x7ff) */ - ch->ch_iot = bus_space_create("PCMCIA memory mapped I/O port", - HD64461_PCC1_MEMBASE + - 0x01000000, ch->ch_iosize); - + set_bus_width(CHANNEL_1, PCMCIA_WIDTH_IO16); hd64461_intr_establish(HD64461_IRQ_PCC1, IST_EDGE, IPL_TTY, hd64461pcmcia_channel1_intr, ch); } @@ -561,7 +570,9 @@ _chip_mem_alloc(pcmcia_chipset_handle_t pch, bus_size_t size, pcmhp->memh = ch->ch_memh; pcmhp->size = size; pcmhp->realsize = size; - + + DPRINTF("base 0x%08lx size %#lx\n", pcmhp->addr, size); + return (0); } @@ -578,13 +589,16 @@ _chip_mem_map(pcmcia_chipset_handle_t pch, int kind, bus_addr_t card_addr, { struct hd64461pcmcia_channel *ch = (struct hd64461pcmcia_channel *)pch; struct hd64461pcmcia_window_cookie *cookie; + bus_addr_t ofs; cookie = malloc(sizeof(struct hd64461pcmcia_window_cookie), M_DEVBUF, M_NOWAIT); KASSERT(cookie); memset(cookie, 0, sizeof(struct hd64461pcmcia_window_cookie)); - if (kind == PCMCIA_MEM_ATTR) { + /* Address */ + if ((kind & ~PCMCIA_WIDTH_MEM_MASK) == PCMCIA_MEM_ATTR) { + cookie->wc_tag = ch->ch_memt; if (bus_space_subregion(ch->ch_memt, ch->ch_memh, card_addr, size, &cookie->wc_handle) != 0) goto bad; @@ -595,20 +609,23 @@ _chip_mem_map(pcmcia_chipset_handle_t pch, int kind, bus_addr_t card_addr, int window = card_addr / ch->ch_memsize; KASSERT(window < MEMWIN_16M_MAX); - *offsetp = card_addr - window * ch->ch_memsize; - - if (bus_space_map(ch->ch_cmemt[window], *offsetp, size, 0, + cookie->wc_tag = ch->ch_cmemt[window]; + ofs = card_addr - window * ch->ch_memsize; + if (bus_space_map(cookie->wc_tag, ofs, size, 0, &cookie->wc_handle) != 0) goto bad; - + // XXX bogus. bus_space_tag should be vtbl... memory_window_16(ch->ch_channel, window); + *offsetp = ofs + 0x01000000; /* skip attribute area */ cookie->wc_window = window; } cookie->wc_size = size; *windowp = (int)cookie; - DPRINTF("%#lx-> %#lx+%#lx\n", card_addr, *offsetp, size); + DPRINTF("(%s) %#lx+%#lx-> %#lx+%#lx\n", kind == PCMCIA_MEM_ATTR ? + "attribute" : "common", ch->ch_memh, card_addr, *offsetp, + size); return (0); bad: @@ -626,6 +643,7 @@ _chip_mem_unmap(pcmcia_chipset_handle_t pch, int window) if (cookie->wc_window != -1) bus_space_unmap(cookie->wc_tag, cookie->wc_handle, cookie->wc_size); + DPRINTF("%#lx-%#x\n", cookie->wc_handle, cookie->wc_size); free(cookie, M_DEVBUF); } @@ -635,6 +653,9 @@ _chip_io_alloc(pcmcia_chipset_handle_t pch, bus_addr_t start, bus_size_t size, { struct hd64461pcmcia_channel *ch = (struct hd64461pcmcia_channel *)pch; + if (ch->ch_channel == CHANNEL_1) + return (1); + if (start) { if (bus_space_map(ch->ch_iot, start, size, 0, &pcihp->ioh)) { DPRINTF("couldn't map %#lx+%#lx\n", start, size); @@ -667,18 +688,10 @@ _chip_io_map(pcmcia_chipset_handle_t pch, int width, bus_addr_t offset, #ifdef HD64461PCMCIA_DEBUG static char *width_names[] = { "auto", "io8", "io16" }; #endif - u_int16_t r16; + if (ch->ch_channel == CHANNEL_1) + return (1); - /* Set bus width */ - r16 = SHREG_BCR2; - if (ch->ch_channel == CHANNEL_0) { - r16 &= ~((1 << 13)|(1 << 12)); - r16 |= 1 << (width == PCMCIA_WIDTH_IO8 ? 12 : 13); - } else { - r16 &= ~((1 << 11)|(1 << 10)); - r16 |= 1 << (width == PCMCIA_WIDTH_IO8 ? 10 : 11); - } - SHREG_BCR2 = r16; + set_bus_width(CHANNEL_0, width); DPRINTF("%#lx:%#lx+%#lx %s\n", pcihp->ioh, offset, size, width_names[width]); @@ -689,6 +702,11 @@ _chip_io_map(pcmcia_chipset_handle_t pch, int width, bus_addr_t offset, static void _chip_io_free(pcmcia_chipset_handle_t pch, struct pcmcia_io_handle *pcihp) { + struct hd64461pcmcia_channel *ch = (struct hd64461pcmcia_channel *)pch; + + if (ch->ch_channel == CHANNEL_1) + return; + if (pcihp->flags & PCMCIA_IO_ALLOCATED) bus_space_free(pcihp->iot, pcihp->ioh, pcihp->size); else @@ -728,18 +746,18 @@ _chip_socket_enable(pcmcia_chipset_handle_t pch) /* * hold RESET at least 10us. */ - __delay(20); + DELAY_MS(20); /* clear the reset flag */ r &= ~HD64461_PCCGCR_PCCR; hd64461_reg_write_1(gcr, r); - __delay(20000); + DELAY_MS(2000); /* wait for the chip to finish initializing */ for (i = 0; i < 10000; i++) { if ((hd64461_reg_read_1(isr) & HD64461_PCCISR_READY)) goto reset_ok; - __delay(500); + DELAY_MS(500); if ((i > 5000) && (i % 100 == 99)) printf("."); @@ -816,7 +834,7 @@ power_off(enum controller_channel channel) * wait 300ms until power fails (Tpf). Then, wait 100ms since * we are changing Vcc (Toff). */ - __delay(300 + 100); + DELAY_MS(300 + 100); /* stop clock */ r16 = hd64461_reg_read_2(HD64461_SYSSTBCR_REG16); @@ -856,7 +874,7 @@ power_on(enum controller_channel channel) r16 &= ~(channel == CHANNEL_0 ? HD64461_SYSSTBCR_SPC0ST : HD64461_SYSSTBCR_SPC1ST); hd64461_reg_write_2(HD64461_SYSSTBCR_REG16, r16); - __delay(2000); + DELAY_MS(200); /* detect voltage and supply VCC */ r = hd64461_reg_read_1(isr); @@ -892,7 +910,7 @@ power_on(enum controller_channel channel) * some machines require some more time to be settled * (300ms is added here). */ - __delay(100 + 20 + 300); + DELAY_MS(100 + 20 + 300); /* DRV (external buffer) low level */ r = hd64461_reg_read_1(gcr); @@ -967,6 +985,7 @@ memory_window_16(enum controller_channel channel, enum memory_window_16 window) hd64461_reg_write_1(a, r); } +#if unused static void memory_window_32(enum controller_channel channel, enum memory_window_32 window) { @@ -989,6 +1008,23 @@ memory_window_32(enum controller_channel channel, enum memory_window_32 window) hd64461_reg_write_1(a, r); } +#endif + +static void +set_bus_width(enum controller_channel channel, int width) +{ + u_int16_t r16; + + r16 = SHREG_BCR2; + if (channel == CHANNEL_0) { + r16 &= ~((1 << 13)|(1 << 12)); + r16 |= 1 << (width == PCMCIA_WIDTH_IO8 ? 12 : 13); + } else { + r16 &= ~((1 << 11)|(1 << 10)); + r16 |= 1 << (width == PCMCIA_WIDTH_IO8 ? 10 : 11); + } + SHREG_BCR2 = r16; +} #ifdef DEBUG static void