1 /* $NetBSD: omsal400.c,v 1.5 2007/02/23 13:34:34 kiyohara Exp $ */ 2 3 /*- 4 * Copyright (c) 2006 Itronix Inc. 5 * Copyright (c) 2006 Shigeyuki Fukushima. 6 * All rights reserved. 7 * 8 * Written by Garrett D'Amore for Itronix Inc 9 * Written by Shigeyuki Fukushima. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above 17 * copyright notice, this list of conditions and the following 18 * disclaimer in the documentation and/or other materials provided 19 * with the distribution. 20 * 3. The name of the author may not be used to endorse or promote 21 * products derived from this software without specific prior 22 * written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 25 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 28 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 30 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37 38 #include <sys/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: omsal400.c,v 1.5 2007/02/23 13:34:34 kiyohara Exp $"); 40 41 #include <sys/param.h> 42 #include <machine/bus.h> 43 #include <machine/locore.h> 44 #include <mips/alchemy/dev/augpiovar.h> 45 #include <mips/alchemy/dev/aupcmciavar.h> 46 #include <evbmips/alchemy/obiovar.h> 47 #include <evbmips/alchemy/board.h> 48 #include <evbmips/alchemy/omsal400reg.h> 49 50 #define GET16(x) \ 51 (*((volatile uint16_t *)MIPS_PHYS_TO_KSEG1(x))) 52 #define PUT16(x, v) \ 53 (*((volatile uint16_t *)MIPS_PHYS_TO_KSEG1(x)) = (v)) 54 55 static void omsal400_init(void); 56 static int omsal400_pci_intr_map(struct pci_attach_args *, 57 pci_intr_handle_t *); 58 static void omsal400_poweroff(void); 59 static void omsal400_reboot(void); 60 static bus_addr_t omsal400_slot_offset(int); 61 static int omsal400_slot_irq(int, int); 62 static void omsal400_slot_enable(int); 63 static void omsal400_slot_disable(int); 64 static int omsal400_slot_status(int); 65 static const char *omsal400_slot_name(int); 66 67 static const struct obiodev omsal400_devices[] = { 68 { NULL }, 69 }; 70 71 static struct aupcmcia_machdep omsal400_pcmcia = { 72 1, /* nslots */ 73 omsal400_slot_offset, 74 omsal400_slot_irq, 75 omsal400_slot_enable, 76 omsal400_slot_disable, 77 omsal400_slot_status, 78 omsal400_slot_name, 79 }; 80 81 static struct alchemy_board omsal400_info = { 82 "Plathome Open Micro Server AL400/AMD Alchemy Au1550", 83 omsal400_devices, 84 omsal400_init, 85 omsal400_pci_intr_map, 86 omsal400_reboot, 87 omsal400_poweroff, 88 &omsal400_pcmcia, 89 }; 90 91 const struct alchemy_board * 92 board_info(void) 93 { 94 95 return &omsal400_info; 96 } 97 98 void 99 omsal400_init(void) 100 { 101 /* uint16_t whoami; */ 102 103 if (MIPS_PRID_COPTS(cpu_id) != MIPS_AU1550) 104 panic("omsal400: CPU not Au1550"); 105 106 #if 0 /* XXX: TODO borad identification */ 107 /* check the whoami register for a match */ 108 whoami = GET16(DBAU1550_WHOAMI); 109 110 if (DBAU1550_WHOAMI_BOARD(whoami) != DBAU1550_WHOAMI_DBAU1550_REV1) 111 panic("dbau1550: WHOAMI (%x) not DBAu1550!", whoami); 112 113 printf("DBAu1550 (cabernet), CPLDv%d, ", 114 DBAU1550_WHOAMI_CPLD(whoami)); 115 116 if (DBAU1550_WHOAMI_DAUGHTER(whoami) != 0xf) 117 printf("daughtercard 0x%x\n", 118 DBAU1550_WHOAMI_DAUGHTER(whoami)); 119 else 120 printf("no daughtercard\n"); 121 #endif 122 123 /* leave console and clocks alone -- YAMON should have got it right! */ 124 } 125 126 int 127 omsal400_pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 128 { 129 /* 130 * This platform has 4 PCI devices: 131 * dev 1 (PCI_INTD): PCI Connector 132 * dev 2 (PCI_INTC): NEC USB 2.0 uPD720101 133 * dev 3 (PCI_INTB): Intel GB Ether 82541PI 134 * dev 4 (PCI_INTA): Intel GB Ether 82541PI 135 */ 136 static const int irqmap[4/*device*/][4/*pin*/] = { 137 { 6, -1, -1, -1 }, /* 1: PCI Connecter (not used) */ 138 { 5, 5, 5, -1 }, /* 2: NEC USB 2.0 */ 139 { 2, -1, -1, -1 }, /* 3: Intel GbE */ 140 { 1, -1, -1, -1 }, /* 4: Intel GbE */ 141 }; 142 143 int pin, dev, irq; 144 145 /* if interrupt pin not used... */ 146 if ((pin = pa->pa_intrpin) == 0) 147 return 1; 148 149 if (pin > 4) { 150 printf("pci: bad interrupt pin %d\n", pin); 151 return 1; 152 } 153 154 pci_decompose_tag(pa->pa_pc, pa->pa_intrtag, NULL, &dev, NULL); 155 156 if ((dev < 1) || (dev > 4)) { 157 printf("pci: bad device %d\n", dev); 158 return 1; 159 } 160 161 if ((irq = irqmap[dev - 1][pin - 1]) == -1) { 162 printf("pci: no IRQ routing for device %d pin %d\n", dev, pin); 163 return 1; 164 } 165 166 *ihp = irq; 167 return 0; 168 } 169 170 void 171 omsal400_reboot(void) 172 { 173 174 /* XXX */ 175 } 176 177 void 178 omsal400_poweroff(void) 179 { 180 181 printf("\n- poweroff -\n"); 182 /* XXX */ 183 } 184 185 186 int 187 omsal400_slot_irq(int slot, int which) 188 { 189 static const int irqmap[1/*slot*/][2/*which*/] = { 190 { 35, 37 }, /* Slot 0: CF connector Type2 */ 191 }; 192 193 if ((slot >= 1) || (which >= 2)) 194 return -1; 195 196 return irqmap[slot][which]; 197 } 198 199 bus_addr_t 200 omsal400_slot_offset(int slot) 201 { 202 203 switch (slot) { 204 case 0: 205 return (0); /* offset 0 */ 206 } 207 return (bus_addr_t)-1; 208 } 209 210 void 211 omsal400_slot_enable(int slot) 212 { 213 214 /* nothing todo */ 215 } 216 217 void 218 omsal400_slot_disable(int slot) 219 { 220 221 /* nothing todo */ 222 } 223 224 int 225 omsal400_slot_status(int slot) 226 { 227 uint16_t inserted = 0; 228 229 switch (slot) { 230 case 0: 231 inserted = !AUGPIO_READ(5); /* pin 5 */ 232 break; 233 } 234 235 return inserted; 236 } 237 238 const char * 239 omsal400_slot_name(int slot) 240 { 241 switch (slot) { 242 case 0: 243 return "CF connector Type2 on Static BUS#3"; 244 default: 245 return "???"; 246 } 247 } 248