xref: /openbmc/linux/arch/sh/drivers/pci/ops-dreamcast.c (revision 597473720f4dc69749542bfcfed4a927a43d935e)
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