xref: /openbmc/linux/arch/sh/drivers/pci/pci-dreamcast.c (revision 3444f5ec49bc6cb901ffea38e085db1d76e1189c)
1*3444f5ecSPaul Mundt /*
2*3444f5ecSPaul Mundt  * PCI support for the Sega Dreamcast
3*3444f5ecSPaul Mundt  *
4*3444f5ecSPaul Mundt  * Copyright (C) 2001, 2002  M. R. Brown
5*3444f5ecSPaul Mundt  * Copyright (C) 2002, 2003  Paul Mundt
6*3444f5ecSPaul Mundt  *
7*3444f5ecSPaul Mundt  * This file originally bore the message (with enclosed-$):
8*3444f5ecSPaul Mundt  *	Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp
9*3444f5ecSPaul Mundt  *	Dreamcast PCI: Supports SEGA Broadband Adaptor only.
10*3444f5ecSPaul Mundt  *
11*3444f5ecSPaul Mundt  * This file is subject to the terms and conditions of the GNU General Public
12*3444f5ecSPaul Mundt  * License.  See the file "COPYING" in the main directory of this archive
13*3444f5ecSPaul Mundt  * for more details.
14*3444f5ecSPaul Mundt  */
15*3444f5ecSPaul Mundt 
16*3444f5ecSPaul Mundt #include <linux/sched.h>
17*3444f5ecSPaul Mundt #include <linux/kernel.h>
18*3444f5ecSPaul Mundt #include <linux/param.h>
19*3444f5ecSPaul Mundt #include <linux/interrupt.h>
20*3444f5ecSPaul Mundt #include <linux/init.h>
21*3444f5ecSPaul Mundt #include <linux/irq.h>
22*3444f5ecSPaul Mundt #include <linux/pci.h>
23*3444f5ecSPaul Mundt #include <linux/module.h>
24*3444f5ecSPaul Mundt 
25*3444f5ecSPaul Mundt #include <asm/io.h>
26*3444f5ecSPaul Mundt #include <asm/irq.h>
27*3444f5ecSPaul Mundt #include <mach/pci.h>
28*3444f5ecSPaul Mundt 
29*3444f5ecSPaul Mundt static struct resource gapspci_io_resource = {
30*3444f5ecSPaul Mundt 	.name	= "GAPSPCI IO",
31*3444f5ecSPaul Mundt 	.start	= GAPSPCI_BBA_CONFIG,
32*3444f5ecSPaul Mundt 	.end	= GAPSPCI_BBA_CONFIG + GAPSPCI_BBA_CONFIG_SIZE - 1,
33*3444f5ecSPaul Mundt 	.flags	= IORESOURCE_IO,
34*3444f5ecSPaul Mundt };
35*3444f5ecSPaul Mundt 
36*3444f5ecSPaul Mundt static struct resource gapspci_mem_resource = {
37*3444f5ecSPaul Mundt 	.name	= "GAPSPCI mem",
38*3444f5ecSPaul Mundt 	.start	= GAPSPCI_DMA_BASE,
39*3444f5ecSPaul Mundt 	.end	= GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1,
40*3444f5ecSPaul Mundt 	.flags	= IORESOURCE_MEM,
41*3444f5ecSPaul Mundt };
42*3444f5ecSPaul Mundt 
43*3444f5ecSPaul Mundt /*
44*3444f5ecSPaul Mundt  * gapspci init
45*3444f5ecSPaul Mundt  */
46*3444f5ecSPaul Mundt 
47*3444f5ecSPaul Mundt static int __init gapspci_init(struct pci_channel *chan)
48*3444f5ecSPaul Mundt {
49*3444f5ecSPaul Mundt 	char idbuf[16];
50*3444f5ecSPaul Mundt 	int i;
51*3444f5ecSPaul Mundt 
52*3444f5ecSPaul Mundt 	/*
53*3444f5ecSPaul Mundt 	 * FIXME: All of this wants documenting to some degree,
54*3444f5ecSPaul Mundt 	 * even some basic register definitions would be nice.
55*3444f5ecSPaul Mundt 	 *
56*3444f5ecSPaul Mundt 	 * I haven't seen anything this ugly since.. maple.
57*3444f5ecSPaul Mundt 	 */
58*3444f5ecSPaul Mundt 
59*3444f5ecSPaul Mundt 	for (i=0; i<16; i++)
60*3444f5ecSPaul Mundt 		idbuf[i] = inb(GAPSPCI_REGS+i);
61*3444f5ecSPaul Mundt 
62*3444f5ecSPaul Mundt 	if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16))
63*3444f5ecSPaul Mundt 		return -ENODEV;
64*3444f5ecSPaul Mundt 
65*3444f5ecSPaul Mundt 	outl(0x5a14a501, GAPSPCI_REGS+0x18);
66*3444f5ecSPaul Mundt 
67*3444f5ecSPaul Mundt 	for (i=0; i<1000000; i++)
68*3444f5ecSPaul Mundt 		cpu_relax();
69*3444f5ecSPaul Mundt 
70*3444f5ecSPaul Mundt 	if (inl(GAPSPCI_REGS+0x18) != 1)
71*3444f5ecSPaul Mundt 		return -EINVAL;
72*3444f5ecSPaul Mundt 
73*3444f5ecSPaul Mundt 	outl(0x01000000, GAPSPCI_REGS+0x20);
74*3444f5ecSPaul Mundt 	outl(0x01000000, GAPSPCI_REGS+0x24);
75*3444f5ecSPaul Mundt 
76*3444f5ecSPaul Mundt 	outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28);
77*3444f5ecSPaul Mundt 	outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c);
78*3444f5ecSPaul Mundt 
79*3444f5ecSPaul Mundt 	outl(1, GAPSPCI_REGS+0x14);
80*3444f5ecSPaul Mundt 	outl(1, GAPSPCI_REGS+0x34);
81*3444f5ecSPaul Mundt 
82*3444f5ecSPaul Mundt 	/* Setting Broadband Adapter */
83*3444f5ecSPaul Mundt 	outw(0xf900, GAPSPCI_BBA_CONFIG+0x06);
84*3444f5ecSPaul Mundt 	outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30);
85*3444f5ecSPaul Mundt 	outb(0x00, GAPSPCI_BBA_CONFIG+0x3c);
86*3444f5ecSPaul Mundt 	outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d);
87*3444f5ecSPaul Mundt 	outw(0x0006, GAPSPCI_BBA_CONFIG+0x04);
88*3444f5ecSPaul Mundt 	outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10);
89*3444f5ecSPaul Mundt 	outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14);
90*3444f5ecSPaul Mundt 
91*3444f5ecSPaul Mundt 	return 0;
92*3444f5ecSPaul Mundt }
93*3444f5ecSPaul Mundt 
94*3444f5ecSPaul Mundt struct pci_channel board_pci_channels[] = {
95*3444f5ecSPaul Mundt 	{
96*3444f5ecSPaul Mundt 		.init		= gapspci_init,
97*3444f5ecSPaul Mundt 		.pci_ops	= &gapspci_pci_ops,
98*3444f5ecSPaul Mundt 		.io_resource	= &gapspci_io_resource,
99*3444f5ecSPaul Mundt 		.mem_resource	= &gapspci_mem_resource,
100*3444f5ecSPaul Mundt 		.first_devfn	= 0,
101*3444f5ecSPaul Mundt 		.last_devfn	= 1,
102*3444f5ecSPaul Mundt 	}, {
103*3444f5ecSPaul Mundt 		.init		= NULL,
104*3444f5ecSPaul Mundt 	}
105*3444f5ecSPaul Mundt };
106