xref: /netbsd/sys/arch/evbmips/alchemy/omsal400.c (revision 6550d01e)
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