1*ff4a7481SKuninori Morimoto // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * PCI operations for the Sega Dreamcast
41da177e4SLinus Torvalds *
51da177e4SLinus Torvalds * Copyright (C) 2001, 2002 M. R. Brown
61da177e4SLinus Torvalds * Copyright (C) 2002, 2003 Paul Mundt
71da177e4SLinus Torvalds */
81da177e4SLinus Torvalds
91da177e4SLinus Torvalds #include <linux/sched.h>
101da177e4SLinus Torvalds #include <linux/kernel.h>
111da177e4SLinus Torvalds #include <linux/param.h>
121da177e4SLinus Torvalds #include <linux/interrupt.h>
131da177e4SLinus Torvalds #include <linux/init.h>
141da177e4SLinus Torvalds #include <linux/irq.h>
151da177e4SLinus Torvalds #include <linux/pci.h>
167223ce29SAdrian Bunk #include <linux/module.h>
173444f5ecSPaul Mundt #include <linux/io.h>
18f15cbe6fSPaul Mundt #include <mach/pci.h>
191da177e4SLinus Torvalds
201da177e4SLinus Torvalds /*
211da177e4SLinus Torvalds * The !gapspci_config_access case really shouldn't happen, ever, unless
221da177e4SLinus Torvalds * someone implicitly messes around with the last devfn value.. otherwise we
231da177e4SLinus Torvalds * only support a single device anyways, and if we didn't have a BBA, we
241da177e4SLinus Torvalds * wouldn't make it terribly far through the PCI setup anyways.
251da177e4SLinus Torvalds *
261da177e4SLinus Torvalds * Also, we could very easily support both Type 0 and Type 1 configurations
271da177e4SLinus Torvalds * here, but since it doesn't seem that there is any such implementation in
28e868d612SSimon Arlott * existence, we don't bother.
291da177e4SLinus Torvalds *
301da177e4SLinus Torvalds * I suppose if someone actually gets around to ripping the chip out of
311da177e4SLinus Torvalds * the BBA and hanging some more devices off of it, then this might be
321da177e4SLinus Torvalds * something to take into consideration. However, due to the cost of the BBA,
331da177e4SLinus Torvalds * and the general lack of activity by DC hardware hackers, this doesn't seem
341da177e4SLinus Torvalds * likely to happen anytime soon.
351da177e4SLinus Torvalds */
gapspci_config_access(unsigned char bus,unsigned int devfn)361da177e4SLinus Torvalds static int gapspci_config_access(unsigned char bus, unsigned int devfn)
371da177e4SLinus Torvalds {
381da177e4SLinus Torvalds return (bus == 0) && (devfn == 0);
391da177e4SLinus Torvalds }
401da177e4SLinus Torvalds
411da177e4SLinus Torvalds /*
421da177e4SLinus Torvalds * We can also actually read and write in b/w/l sizes! Thankfully this part
431da177e4SLinus Torvalds * was at least done right, and we don't have to do the stupid masking and
441da177e4SLinus Torvalds * shifting that we do on the 7751! Small wonders never cease to amaze.
451da177e4SLinus Torvalds */
gapspci_read(struct pci_bus * bus,unsigned int devfn,int where,int size,u32 * val)461da177e4SLinus Torvalds static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val)
471da177e4SLinus Torvalds {
481da177e4SLinus Torvalds *val = 0xffffffff;
491da177e4SLinus Torvalds
501da177e4SLinus Torvalds if (!gapspci_config_access(bus->number, devfn))
511da177e4SLinus Torvalds return PCIBIOS_DEVICE_NOT_FOUND;
521da177e4SLinus Torvalds
531da177e4SLinus Torvalds switch (size) {
54763a495aSMagnus Damm case 1: *val = inb(GAPSPCI_BBA_CONFIG+where); break;
55763a495aSMagnus Damm case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break;
56763a495aSMagnus Damm case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break;
571da177e4SLinus Torvalds }
581da177e4SLinus Torvalds
591da177e4SLinus Torvalds return PCIBIOS_SUCCESSFUL;
601da177e4SLinus Torvalds }
611da177e4SLinus Torvalds
gapspci_write(struct pci_bus * bus,unsigned int devfn,int where,int size,u32 val)621da177e4SLinus Torvalds static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
631da177e4SLinus Torvalds {
641da177e4SLinus Torvalds if (!gapspci_config_access(bus->number, devfn))
651da177e4SLinus Torvalds return PCIBIOS_DEVICE_NOT_FOUND;
661da177e4SLinus Torvalds
671da177e4SLinus Torvalds switch (size) {
68763a495aSMagnus Damm case 1: outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break;
69763a495aSMagnus Damm case 2: outw((u16)val, GAPSPCI_BBA_CONFIG+where); break;
70763a495aSMagnus Damm case 4: outl((u32)val, GAPSPCI_BBA_CONFIG+where); break;
711da177e4SLinus Torvalds }
721da177e4SLinus Torvalds
731da177e4SLinus Torvalds return PCIBIOS_SUCCESSFUL;
741da177e4SLinus Torvalds }
751da177e4SLinus Torvalds
763444f5ecSPaul Mundt struct pci_ops gapspci_pci_ops = {
771da177e4SLinus Torvalds .read = gapspci_read,
781da177e4SLinus Torvalds .write = gapspci_write,
791da177e4SLinus Torvalds };
80