GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / cfe / cfe / arch / mips / board / p5064 / src / dev_pcmcia_pcic.c
blob922cbc4f8e35b832207ca2048804dbce92980b0f
1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
3 *
4 * PCMCIA IDE disk driver File: dev_pcmcia_pcic.c
5 *
6 * This is a stub driver for PCMCIA disks that are connected to
7 * an Intel-style ISA PCIC chip. Don't have one of those on
8 * your BCM12500 eval board? I hope not; this one is just used
9 * on the Algorithmics P5064 so I can learn about the quirks of
10 * real PCMCIA disks. See dev_pcmcia.c for the BCM12500 driver.
12 * Author: Mitch Lichtenberg (mpl@broadcom.com)
14 *********************************************************************
16 * Copyright 2000,2001,2002,2003
17 * Broadcom Corporation. All rights reserved.
19 * This software is furnished under license and may be used and
20 * copied only in accordance with the following terms and
21 * conditions. Subject to these conditions, you may download,
22 * copy, install, use, modify and distribute modified or unmodified
23 * copies of this software in source and/or binary form. No title
24 * or ownership is transferred hereby.
26 * 1) Any source code used, modified or distributed must reproduce
27 * and retain this copyright notice and list of conditions
28 * as they appear in the source file.
30 * 2) No right is granted to use any trade name, trademark, or
31 * logo of Broadcom Corporation. The "Broadcom Corporation"
32 * name may not be used to endorse or promote products derived
33 * from this software without the prior written permission of
34 * Broadcom Corporation.
36 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
37 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
38 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
39 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
40 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
41 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
42 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
44 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
45 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
46 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
47 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
48 * THE POSSIBILITY OF SUCH DAMAGE.
49 ********************************************************************* */
52 #include "sbmips.h"
53 #include "lib_types.h"
54 #include "lib_malloc.h"
55 #include "lib_printf.h"
56 #include "lib_string.h"
57 #include "cfe_timer.h"
58 #include "cfe_iocb.h"
59 #include "cfe_device.h"
60 #include "cfe_ioctl.h"
61 #include "cfe_error.h"
62 #include "cfe_console.h"
64 #include "dev_ide_common.h"
66 #include "dev_ide.h"
68 #include "pcivar.h"
70 /* *********************************************************************
71 * Constants
72 ********************************************************************* */
75 #define PCMCIA_CARDPRESENT 1
76 #define _BYTESWAP_
78 #define OUTB(x,y) outb(x,y)
79 #define INB(x) inb(x)
81 #define PCICSET(reg,val) OUTB(0x3E0,(reg)); OUTB(0x3E1,(val))
82 #define PCICGET(reg,val) OUTB(0x3E0,(reg)); val = INB(0x3E1)
83 #define WINBASE(x) (0x10+(x)*8)
85 /* *********************************************************************
86 * External references
87 ********************************************************************* */
89 extern void _wbflush(void);
91 /* *********************************************************************
92 * Forward declarations
93 ********************************************************************* */
95 static void pcmcia_ata_probe(cfe_driver_t *drv,
96 unsigned long probe_a, unsigned long probe_b,
97 void *probe_ptr);
100 static int pcmcia_ata_open(cfe_devctx_t *ctx);
102 /* *********************************************************************
103 * Device Dispatch
104 ********************************************************************* */
106 const static cfe_devdisp_t pcmcia_ata_dispatch = {
107 pcmcia_ata_open,
108 idecommon_read,
109 idecommon_inpstat,
110 idecommon_write,
111 idecommon_ioctl,
112 idecommon_close,
113 NULL,
114 NULL
117 const cfe_driver_t pcmcia_pcic_drv = {
118 "PCMCIA ATA disk",
119 "pcmcia",
120 CFE_DEV_DISK,
121 &pcmcia_ata_dispatch,
122 pcmcia_ata_probe
126 /* *********************************************************************
127 * Port I/O routines
129 * These routines are called back from the common code to do
130 * I/O cycles to the IDE disk. We provide routines for
131 * reading and writing bytes, words, and strings of words.
132 ********************************************************************* */
135 static uint8_t pcmcia_inb(idecommon_dispatch_t *disp,uint32_t reg)
137 return *((volatile uint8_t *) PHYS_TO_K1(reg+disp->baseaddr));
140 static uint16_t pcmcia_inw(idecommon_dispatch_t *disp,uint32_t reg)
142 return *((volatile uint16_t *) PHYS_TO_K1((reg+disp->baseaddr)));
145 static void pcmcia_ins(idecommon_dispatch_t *disp,uint32_t reg,uint8_t *buf,int len)
147 uint16_t data;
149 while (len > 0) {
150 data = *((volatile uint16_t *) PHYS_TO_K1(reg+disp->baseaddr));
152 #ifdef _BYTESWAP_
153 *buf++ = (data >> 8) & 0xFF;
154 *buf++ = (data & 0xFF);
155 #else
156 *buf++ = (data & 0xFF);
157 *buf++ = (data >> 8) & 0xFF;
158 #endif
159 len--;
160 len--;
165 static void pcmcia_outb(idecommon_dispatch_t *disp,uint32_t reg,uint8_t val)
167 *((volatile uint8_t *) PHYS_TO_K1(reg+disp->baseaddr)) = val;
168 _wbflush();
171 static void pcmcia_outw(idecommon_dispatch_t *disp,uint32_t reg,uint16_t val)
173 *((volatile uint16_t *) PHYS_TO_K1(reg+disp->baseaddr)) = val;
174 _wbflush();
177 static void pcmcia_outs(idecommon_dispatch_t *disp,uint32_t reg,uint8_t *buf,int len)
179 uint16_t data;
181 while (len > 0) {
182 #ifdef _BYTESWAP_
183 data = (uint16_t) buf[1] + ((uint16_t) buf[0] << 8);
184 #else
185 data = (uint16_t) buf[0] + ((uint16_t) buf[1] << 8);
186 #endif
188 *((volatile uint16_t *) PHYS_TO_K1(reg+disp->baseaddr)) = data;
189 _wbflush();
191 buf++;
192 buf++;
193 len--;
194 len--;
199 /* *********************************************************************
200 * pcic_cardpresent()
202 * Returns TRUE if a PCMCIA card (any card) is present in the
203 * slot.
205 * Input parameters:
206 * nothing
208 * Return value:
209 * true if card is present.
210 ********************************************************************* */
212 static int pcic_cardpresent(void)
214 uint8_t det;
216 PCICGET(0x01,det);
218 det &= 0x0C;
220 return (det == 0x0C);
223 /* *********************************************************************
224 * pcic_poweron()
226 * Turn on the power to the PCMCIA slot.
228 * Input parameters:
229 * nothing
231 * Return value:
232 * nothing
233 ********************************************************************* */
235 static void pcic_poweron(void)
237 PCICSET(0x2F,0x70);
238 PCICSET(0x02,0x30);
239 cfe_sleep(CFE_HZ/4);
240 PCICSET(0x02,0xB0);
244 /* *********************************************************************
245 * pcic_mapwin(win,sysstart,sysend,pcmciaoffset,attr)
247 * Map a window using the PCIC.
249 * Input parameters:
250 * win - window number (0-4)
251 * sysstart,sysend - ISA address of the beginning and end of
252 * the window
253 * pcmciaoffset - offset into PCCARD space that the window
254 * should be mapped to
255 * attr - nonzero to map attribute memory
257 * Return value:
258 * nothing
259 ********************************************************************* */
261 static void pcic_mapwin(int win,uint32_t sysstart,uint32_t sysend,uint32_t pcmciaoffset,int attr)
263 uint8_t ena;
264 uint32_t offset;
267 * Disable the window we're mucking with
270 PCICGET(0x06,ena);
271 ena &= ~(1<<win);
272 PCICSET(0x06,ena);
275 * Set the start and stop system address registers
278 PCICSET(WINBASE(win)+0,(sysstart >> 12) & 0xFF);
279 PCICSET(WINBASE(win)+1,((sysstart >> 20) & 0x0F) | 0x80); /* note: 16 bits */
280 PCICSET(WINBASE(win)+2,(sysend >> 12) & 0xFF);
281 PCICSET(WINBASE(win)+3,((sysend >> 20) & 0x0F) | 0x00);
284 * Set the PCMCIA offset and attribute register
287 offset = (uint32_t) ((int32_t) pcmciaoffset - (int32_t) sysstart);
288 PCICSET(WINBASE(win)+4,(offset >> 12) & 0xFF);
289 PCICSET(WINBASE(win)+5,(((offset >> 20) & 0x3F) | (attr ? 0x40 : 0x00)));
292 * Reenable the window
295 ena |= (1<<win);
296 PCICSET(0x06,ena);
300 /* *********************************************************************
301 * pcmcia_ata_poll(x)
303 * Called periodically so we can check for card activity
304 * (report insertions, removals, etc.)
306 * Input parameters:
307 * x - void param, it's our idecommon structure
309 * Return value:
310 * nothing
311 ********************************************************************* */
313 static void pcmcia_ata_poll(void *x)
315 idecommon_t *softc = (idecommon_t *) x;
316 int present;
317 int oldpresent;
319 present = pcic_cardpresent();
320 oldpresent = (softc->idecommon_flags & PCMCIA_CARDPRESENT) ? 1 : 0;
322 if (present == oldpresent) return;
324 if (present) {
325 console_log("PCMCIA: Card inserted");
327 else {
328 console_log("PCMCIA: Card removed");
331 if (present) {
332 softc->idecommon_flags |= PCMCIA_CARDPRESENT;
334 else {
335 softc->idecommon_flags &= ~PCMCIA_CARDPRESENT;
339 /* *********************************************************************
340 * pcmcia_ata_probe(drv,probe_a,probe_b,probe_ptr)
342 * Our probe routine. Attach a PCMCIA ATA device to the firmware.
344 * Input parameters:
345 * drv - driver structure
346 * probe_a - physical address of IDE registers
347 * probe_b - unit number
348 * probe_ptr - not used
350 * Return value:
351 * nothing
352 ********************************************************************* */
354 static void pcmcia_ata_probe(cfe_driver_t *drv,
355 unsigned long probe_a, unsigned long probe_b,
356 void *probe_ptr)
358 idecommon_t *softc;
359 idecommon_dispatch_t *disp;
360 char descr[80];
361 char unitstr[50];
364 * probe_a is the IDE base address
365 * probe_b is the unit number and other flags
366 * probe_ptr is unused.
369 softc = (idecommon_t *) KMALLOC(sizeof(idecommon_t),0);
370 disp = (idecommon_dispatch_t *) KMALLOC(sizeof(idecommon_dispatch_t),0);
371 if (softc && disp) {
372 softc->idecommon_addr = probe_a;
373 softc->idecommon_unit = probe_b;
375 disp->ref = softc;
376 disp->baseaddr = softc->idecommon_addr;
377 softc->idecommon_dispatch = disp;
378 /* always defer probing till later */
379 softc->idecommon_deferprobe = 1;
381 disp->outb = pcmcia_outb;
382 disp->outw = pcmcia_outw;
383 disp->outs = pcmcia_outs;
385 disp->inb = pcmcia_inb;
386 disp->inw = pcmcia_inw;
387 disp->ins = pcmcia_ins;
389 xsprintf(descr,"%s unit %d at %08X",drv->drv_description,probe_b,probe_a);
390 xsprintf(unitstr,"%d",probe_b);
391 cfe_attach(drv,softc,unitstr,descr);
392 softc->idecommon_flags = pcic_cardpresent() ? PCMCIA_CARDPRESENT : 0;
393 cfe_bg_add(pcmcia_ata_poll,softc);
398 /* *********************************************************************
399 * pcmcia_ata_open(ctx)
401 * Open routine for the PCMCIA IDE device. It just hooks in
402 * front of the standard IDE disk open processing so we can turn
403 * on the PCIC slot and test for the card's presence.
405 * Input parameters:
406 * ctx - device context
408 * Return value:
409 * 0 if ok, else error code
410 ********************************************************************* */
412 static int pcmcia_ata_open(cfe_devctx_t *ctx)
414 int res;
415 idecommon_t *softc = ctx->dev_softc;
417 if (!pcic_cardpresent()) return CFE_ERR_NOTREADY;
419 pcic_poweron();
421 pcic_mapwin(0,0xD0000,0xD0FFF,0,0); /* common memory window */
422 pcic_mapwin(1,0xD1000,0xD1FFF,0,1); /* attribute memory window */
424 res = idecommon_devprobe(softc,0);
425 if (res < 0) {
426 return res;
429 return idecommon_open(ctx);