2 * Copyright (C) Eicon Technology Corporation, 2000.
4 * Eicon File Revision : 1.16
6 * This software may be used and distributed according to the terms
7 * of the GNU General Public License, incorporated herein by reference.
14 #include <asm/system.h>
15 #include <linux/slab.h>
16 #include <linux/pci.h>
17 #include <linux/delay.h>
27 //spinlock_t diva_lock = SPIN_LOCK_UNLOCKED;
30 ux_diva_card_t card_pool[MAX_CARDS];
32 void UxPause(long int ms)
34 int timeout = jiffies + ((ms * HZ) / 1000);
36 while (time_before(jiffies, timeout));
39 int UxCardHandleGet(ux_diva_card_t **card, dia_card_t *cfg)
44 if (cfg->bus_type != DIA_BUS_TYPE_PCI)
46 DPRINTF(("divas hw: type not PCI (%d)", cfg->bus_type));
50 for (i = 0; (i < DIM(card_pool)) && (card_pool[i].in_use); i++)
55 if (i == DIM(card_pool))
57 DPRINTF(("divas hw: card_pool exhausted"));
61 c = *card = &card_pool[i];
63 switch (cfg->bus_type)
65 case DIA_BUS_TYPE_PCI:
66 c->bus_num = cfg->bus_num;
67 c->func_num = cfg->func_num;
68 c->io_base = cfg->io_base;
69 c->reset_base = cfg->reset_base;
70 c->card_type = cfg->card_type;
73 c->irq = (int) cfg->irq;
74 c->pDRAM = cfg->memory[DIVAS_RAM_MEMORY];
75 c->pDEVICES = cfg->memory[DIVAS_REG_MEMORY];
76 c->pCONFIG = cfg->memory[DIVAS_CFG_MEMORY];
77 c->pSHARED = cfg->memory[DIVAS_SHARED_MEMORY];
78 c->pCONTROL = cfg->memory[DIVAS_CTL_MEMORY];
80 /* c->bus_type = DIA_BUS_TYPE_PCI;
81 c->bus_num = cfg->bus_num & 0x3f;
83 c->irq = (int) cfg->irq;
84 c->int_priority = (int) cfg->int_priority;
85 c->card_type = cfg->card_type;
86 c->io_base = cfg->io_base;
87 c->reset_base = cfg->reset_base;
88 c->pDRAM = cfg->memory[DIVAS_RAM_MEMORY];
89 c->pDEVICES = cfg->memory[DIVAS_REG_MEMORY];
90 c->pCONFIG = cfg->memory[DIVAS_CFG_MEMORY];
91 c->pSHARED = cfg->memory[DIVAS_SHARED_MEMORY];
92 DPRINTF(("divas hw: pDRAM is 0x%x", c->pDRAM));
93 DPRINTF(("divas hw: pSHARED is 0x%x", c->pSHARED));
94 DPRINTF(("divas hw: pCONFIG is 0x%x", c->pCONFIG));
95 c->cm_key = cm_getbrdkey("Divas", cfg->card_id);*/
106 void UxCardHandleFree(ux_diva_card_t *card)
108 card->in_use = FALSE;
113 #define DIVAS_IOBASE 1
114 void *UxCardMemAttach(ux_diva_card_t *card, int id)
116 if (card->card_type == DIA_CARD_TYPE_DIVA_SERVER)
120 case DIVAS_SHARED_MEMORY:
121 card->mapped = card->pSHARED;
122 return card->pSHARED;
124 case DIVAS_RAM_MEMORY:
125 card->mapped = card->pDRAM;
128 case DIVAS_REG_MEMORY:
129 card->mapped = card->pDEVICES;
130 return card->pDEVICES;
132 case DIVAS_CFG_MEMORY:
133 card->mapped = card->pCONFIG;
134 return card->pCONFIG;
142 else if (card->card_type == DIA_CARD_TYPE_DIVA_SERVER_B)
147 return (void *) card->reset_base;
150 return (void *) card->io_base;
158 else if (card->card_type == DIA_CARD_TYPE_DIVA_SERVER_Q)
162 case DIVAS_SHARED_MEMORY:
163 card->mapped = card->pSHARED;
164 return card->pSHARED;
166 case DIVAS_RAM_MEMORY:
167 card->mapped = card->pDRAM;
170 case DIVAS_REG_MEMORY:
171 card->mapped = (void *) card->io_base;
172 return (void *) card->io_base;
174 case DIVAS_CTL_MEMORY:
175 card->mapped = card->pCONTROL;
176 return card->pCONTROL;
180 DPRINTF(("divas: Trying to attach to mem %d", id));
185 DPRINTF(("divas: Tried to attach to unknown card"));
187 /* Unknown card type */
191 void UxCardMemDetach(ux_diva_card_t *card, void *address)
193 return; // Just a place holder. No un-mapping done.
196 void UxCardLog(int turn_on)
202 * Control Register I/O Routines to be performed on Attached I/O ports
205 void UxCardPortIoOut(ux_diva_card_t *card, void *AttachedBase, int offset, byte the_byte)
207 word base = (word) (dword) AttachedBase;
211 outb(the_byte, base);
214 void UxCardPortIoOutW(ux_diva_card_t *card, void *AttachedBase, int offset, word the_word)
216 word base = (word) (dword) AttachedBase;
220 outw(the_word, base);
223 void UxCardPortIoOutD(ux_diva_card_t *card, void *AttachedBase, int offset, dword the_dword)
225 word base = (word) (dword) AttachedBase;
229 outl(the_dword, base);
232 byte UxCardPortIoIn(ux_diva_card_t *card, void *AttachedBase, int offset)
234 word base = (word) (dword) AttachedBase;
241 word UxCardPortIoInW(ux_diva_card_t *card, void *AttachedBase, int offset)
243 word base = (word) (dword) AttachedBase;
251 * Memory mapped card I/O functions
254 byte UxCardMemIn(ux_diva_card_t *card, void *address)
257 volatile byte* t = (byte*)address;
264 a -= (int) card->mapped;
265 DPRINTF(("divas hw: read 0x%02x from 0x%x (memory mapped)", b & 0xff, a));
271 word UxCardMemInW(ux_diva_card_t *card, void *address)
274 volatile word* t = (word*)address;
281 a -= (int) card->mapped;
282 DPRINTF(("divas hw: read 0x%04x from 0x%x (memory mapped)", w & 0xffff, a));
288 dword UxCardMemInD(ux_diva_card_t *card, void *address)
291 volatile dword* t = (dword*)address;
298 a -= (int) card->mapped;
299 DPRINTF(("divas hw: read 0x%08x from 0x%x (memory mapped)", dw, a));
305 void UxCardMemInBuffer(ux_diva_card_t *card, void *address, void *buffer, int length)
307 volatile byte *pSource = address;
308 byte *pDest = buffer;
312 *pDest++ = *pSource++;
318 a -= (int) card->mapped;
320 DPRINTF(("divas hw: read %02x %02x %02x %02x %02x %02x %02x %02x from 0x%x (memory mapped)",
321 pDest[0] & 0xff, pDest[1] & 0xff, pDest[2] & 0xff, pDest[3] & 0xff,
322 pDest[4] & 0xff, pDest[5] & 0xff, pDest[6] & 0xff, pDest[7] & 0xff,
329 void UxCardMemOut(ux_diva_card_t *card, void *address, byte data)
331 volatile byte* t = (byte*)address;
336 a -= (int) card->mapped;
337 DPRINTF(("divas hw: wrote 0x%02x to 0x%x (memory mapped)", data & 0xff, a));
345 void UxCardMemOutW(ux_diva_card_t *card, void *address, word data)
347 volatile word* t = (word*)address;
352 a -= (int) card->mapped;
353 DPRINTF(("divas hw: wrote 0x%04x to 0x%x (memory mapped)", data & 0xffff, a));
360 void UxCardMemOutD(ux_diva_card_t *card, void *address, dword data)
362 volatile dword* t = (dword*)address;
367 a -= (int) card->mapped;
368 DPRINTF(("divas hw: wrote 0x%08x to 0x%x (memory mapped)", data, a));
375 void UxCardMemOutBuffer(ux_diva_card_t *card, void *address, void *buffer, int length)
377 byte *pSource = buffer;
378 byte *pDest = address;
382 *pDest++ = *pSource++;
388 a -= (int) card->mapped;
390 DPRINTF(("divas hw: wrote %02x %02x %02x %02x %02x %02x %02x %02x to 0x%x (memory mapped)",
391 pDest[0] & 0xff, pDest[1] & 0xff, pDest[2] & 0xff, pDest[3] & 0xff,
392 pDest[4] & 0xff, pDest[5] & 0xff, pDest[6] & 0xff, pDest[7] & 0xff,
400 * Memory mapped card I/O functions
403 byte UxCardIoIn(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address)
408 outb(0xFF, card->io_base + 0xC);
409 outw((word) (dword) address, card->io_base + 4);
411 the_byte = inb(card->io_base);
415 DPRINTF(("divas hw: read 0x%02x from 0x%x (I/O mapped)",
416 the_byte & 0xff, address));
422 word UxCardIoInW(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address)
427 outb(0xFF, card->io_base + 0xC);
428 outw((word) (dword) address, card->io_base + 4);
429 the_word = inw(card->io_base);
433 DPRINTF(("divas hw: read 0x%04x from 0x%x (I/O mapped)",
434 the_word & 0xffff, address));
440 dword UxCardIoInD(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address)
445 outb(0xFF, card->io_base + 0xC);
446 outw((word) (dword) address, card->io_base + 4);
447 the_dword = inl(card->io_base);
451 DPRINTF(("divas hw: read 0x%08x from 0x%x (I/O mapped)",
452 the_dword, address));
458 void UxCardIoInBuffer(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address, void *buffer, int length)
461 byte *pSource = address;
462 byte *pDest = buffer;
464 if ((word) (dword) address & 0x1)
466 outb(0xFF, card->io_base + 0xC);
467 outw((word) (dword) pSource, card->io_base + 4);
468 *pDest = (byte) inb(card->io_base);
478 outb(0xFF, card->io_base + 0xC);
479 outw((word) (dword) pSource, card->io_base + 4);
480 insw(card->io_base, (word *)pDest,length%2 ? (length+1)>>1 : length>>1);
485 DPRINTF(("divas hw: read %02x %02x %02x %02x %02x %02x %02x %02x from 0x%x (I/O mapped)",
486 pDest[0] & 0xff, pDest[1] & 0xff, pDest[2] & 0xff, pDest[3] & 0xff,
487 pDest[4] & 0xff, pDest[5] & 0xff, pDest[6] & 0xff, pDest[7] & 0xff,
496 void UxCardIoOut(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address, byte data)
500 DPRINTF(("divas hw: wrote 0x%02x to 0x%x (I/O mapped)",
501 data & 0xff, address));
504 outb(0xFF, card->io_base + 0xC);
505 outw((word) (dword) address, card->io_base + 4);
506 outb((byte) data & 0xFF, card->io_base);
511 void UxCardIoOutW(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address, word data)
515 DPRINTF(("divas hw: wrote 0x%04x to 0x%x (I/O mapped)",
516 data & 0xffff, address));
519 outb(0xFF, card->io_base + 0xC);
520 outw((word) (dword) address, card->io_base + 4);
521 outw((word) data & 0xFFFF, card->io_base);
526 void UxCardIoOutD(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address, dword data)
530 DPRINTF(("divas hw: wrote 0x%08x to 0x%x (I/O mapped)", data, address));
533 outb(0xFF, card->io_base + 0xC);
534 outw((word) (dword) address, card->io_base + 4);
535 outl((dword) data & 0xFFFFFFFF, card->io_base);
540 void UxCardIoOutBuffer(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address, void *buffer, int length)
543 byte *pSource = buffer;
544 byte *pDest = address;
546 if ((word) (dword) address & 1)
548 outb(0xFF, card->io_base + 0xC);
549 outw((word) (dword) pDest, card->io_base + 4);
550 outb(*pSource, card->io_base);
560 outb(0xFF, card->io_base + 0xC);
561 outw((word) (dword) pDest, card->io_base + 4);
562 outsw(card->io_base, (word *)pSource, length%2 ? (length+1)>>1 : length>>1);
567 DPRINTF(("divas hw: wrote %02x %02x %02x %02x %02x %02x %02x %02x to 0x%x (I/O mapped)",
568 pDest[0] & 0xff, pDest[1] & 0xff, pDest[2] & 0xff, pDest[3] & 0xff,
569 pDest[4] & 0xff, pDest[5] & 0xff, pDest[6] & 0xff, pDest[7] & 0xff,
576 void Divasintr(int arg, void *unused, struct pt_regs *unused_regs)
580 ux_diva_card_t *ux_ref = NULL;
582 for (i = 0; i < DivasCardNext; i++)
585 if (arg == DivasCards[i].cfg.irq)
587 card = &DivasCards[i];
590 if ((ux_ref) && (card->is_live))
592 (*ux_ref->user_isr)(ux_ref->user_isr_arg);
596 DPRINTF(("divas: ISR couldn't locate card"));
605 int UxIsrInstall(ux_diva_card_t *card, isr_fn_t *isr_fn, void *isr_arg)
609 card->user_isr = isr_fn;
610 card->user_isr_arg = isr_arg;
612 result = request_irq(card->irq, Divasintr, SA_INTERRUPT | SA_SHIRQ, "Divas", (void *) isr_arg);
617 void UxIsrRemove(ux_diva_card_t *card, void *dev_id)
619 free_irq(card->irq, card->user_isr_arg);
622 void UxPciConfigWrite(ux_diva_card_t *card, int size, int offset, void *value)
627 pcibios_write_config_byte(card->bus_num, card->func_num, offset, * (byte *) value);
630 pcibios_write_config_word(card->bus_num, card->func_num, offset, * (word *) value);
633 pcibios_write_config_dword(card->bus_num, card->func_num, offset, * (dword *) value);
636 printk(KERN_WARNING "Divas: Invalid size in UxPciConfigWrite\n");
640 void UxPciConfigRead(ux_diva_card_t *card, int size, int offset, void *value)
645 pcibios_read_config_byte(card->bus_num, card->func_num, offset, (byte *) value);
648 pcibios_read_config_word(card->bus_num, card->func_num, offset, (word *) value);
651 pcibios_read_config_dword(card->bus_num, card->func_num, offset, (unsigned int *) value);
654 printk(KERN_WARNING "Divas: Invalid size in UxPciConfigRead\n");
658 void *UxAlloc(unsigned int size)
662 m = kmalloc(size, GFP_ATOMIC);
667 void UxFree(void *ptr)
672 long UxCardLock(ux_diva_card_t *card)
676 //spin_lock_irqsave(&diva_lock, flags);
684 void UxCardUnlock(ux_diva_card_t *card, long ipl)
686 //spin_unlock_irqrestore(&diva_lock, ipl);
692 dword UxTimeGet(void)
697 long UxInterlockedIncrement(ux_diva_card_t *card, long *dst)
699 register volatile long *p;
705 ipl = UxCardLock(card);
710 UxCardUnlock(card,ipl);
716 long UxInterlockedDecrement(ux_diva_card_t *card, long *dst)
718 register volatile long *p;
724 ipl = UxCardLock(card);
729 UxCardUnlock(card,ipl);