Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /* |
f30c2269 | 2 | * arch/sh/drivers/pci/ops-dreamcast.c |
1da177e4 LT |
3 | * |
4 | * PCI operations for the Sega Dreamcast | |
5 | * | |
6 | * Copyright (C) 2001, 2002 M. R. Brown | |
7 | * Copyright (C) 2002, 2003 Paul Mundt | |
8 | * | |
9 | * This file originally bore the message (with enclosed-$): | |
10 | * Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp | |
11 | * Dreamcast PCI: Supports SEGA Broadband Adaptor only. | |
12 | * | |
13 | * This file is subject to the terms and conditions of the GNU General Public | |
14 | * License. See the file "COPYING" in the main directory of this archive | |
15 | * for more details. | |
16 | */ | |
17 | ||
1da177e4 LT |
18 | #include <linux/sched.h> |
19 | #include <linux/kernel.h> | |
20 | #include <linux/param.h> | |
21 | #include <linux/interrupt.h> | |
22 | #include <linux/init.h> | |
23 | #include <linux/irq.h> | |
24 | #include <linux/pci.h> | |
7223ce29 | 25 | #include <linux/module.h> |
1da177e4 LT |
26 | |
27 | #include <asm/io.h> | |
28 | #include <asm/irq.h> | |
f15cbe6f | 29 | #include <mach/pci.h> |
1da177e4 LT |
30 | |
31 | static struct resource gapspci_io_resource = { | |
32 | .name = "GAPSPCI IO", | |
33 | .start = GAPSPCI_BBA_CONFIG, | |
34 | .end = GAPSPCI_BBA_CONFIG + GAPSPCI_BBA_CONFIG_SIZE - 1, | |
35 | .flags = IORESOURCE_IO, | |
36 | }; | |
37 | ||
38 | static struct resource gapspci_mem_resource = { | |
39 | .name = "GAPSPCI mem", | |
40 | .start = GAPSPCI_DMA_BASE, | |
41 | .end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1, | |
42 | .flags = IORESOURCE_MEM, | |
43 | }; | |
44 | ||
45 | static struct pci_ops gapspci_pci_ops; | |
46 | ||
47 | struct pci_channel board_pci_channels[] = { | |
48 | { &gapspci_pci_ops, &gapspci_io_resource, | |
49 | &gapspci_mem_resource, 0, 1 }, | |
50 | { 0, } | |
51 | }; | |
7223ce29 | 52 | EXPORT_SYMBOL(board_pci_channels); |
1da177e4 LT |
53 | |
54 | /* | |
55 | * The !gapspci_config_access case really shouldn't happen, ever, unless | |
56 | * someone implicitly messes around with the last devfn value.. otherwise we | |
57 | * only support a single device anyways, and if we didn't have a BBA, we | |
58 | * wouldn't make it terribly far through the PCI setup anyways. | |
59 | * | |
60 | * Also, we could very easily support both Type 0 and Type 1 configurations | |
61 | * here, but since it doesn't seem that there is any such implementation in | |
e868d612 | 62 | * existence, we don't bother. |
1da177e4 LT |
63 | * |
64 | * I suppose if someone actually gets around to ripping the chip out of | |
65 | * the BBA and hanging some more devices off of it, then this might be | |
66 | * something to take into consideration. However, due to the cost of the BBA, | |
67 | * and the general lack of activity by DC hardware hackers, this doesn't seem | |
68 | * likely to happen anytime soon. | |
69 | */ | |
70 | static int gapspci_config_access(unsigned char bus, unsigned int devfn) | |
71 | { | |
72 | return (bus == 0) && (devfn == 0); | |
73 | } | |
74 | ||
75 | /* | |
76 | * We can also actually read and write in b/w/l sizes! Thankfully this part | |
77 | * was at least done right, and we don't have to do the stupid masking and | |
78 | * shifting that we do on the 7751! Small wonders never cease to amaze. | |
79 | */ | |
80 | static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) | |
81 | { | |
82 | *val = 0xffffffff; | |
83 | ||
84 | if (!gapspci_config_access(bus->number, devfn)) | |
85 | return PCIBIOS_DEVICE_NOT_FOUND; | |
86 | ||
87 | switch (size) { | |
763a495a MD |
88 | case 1: *val = inb(GAPSPCI_BBA_CONFIG+where); break; |
89 | case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break; | |
90 | case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break; | |
1da177e4 LT |
91 | } |
92 | ||
93 | return PCIBIOS_SUCCESSFUL; | |
94 | } | |
95 | ||
96 | static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) | |
97 | { | |
98 | if (!gapspci_config_access(bus->number, devfn)) | |
99 | return PCIBIOS_DEVICE_NOT_FOUND; | |
100 | ||
101 | switch (size) { | |
763a495a MD |
102 | case 1: outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break; |
103 | case 2: outw((u16)val, GAPSPCI_BBA_CONFIG+where); break; | |
104 | case 4: outl((u32)val, GAPSPCI_BBA_CONFIG+where); break; | |
1da177e4 LT |
105 | } |
106 | ||
107 | return PCIBIOS_SUCCESSFUL; | |
108 | } | |
109 | ||
110 | static struct pci_ops gapspci_pci_ops = { | |
111 | .read = gapspci_read, | |
112 | .write = gapspci_write, | |
113 | }; | |
114 | ||
115 | /* | |
116 | * gapspci init | |
117 | */ | |
118 | ||
119 | int __init gapspci_init(void) | |
120 | { | |
121 | char idbuf[16]; | |
122 | int i; | |
123 | ||
124 | /* | |
125 | * FIXME: All of this wants documenting to some degree, | |
126 | * even some basic register definitions would be nice. | |
127 | * | |
128 | * I haven't seen anything this ugly since.. maple. | |
129 | */ | |
130 | ||
131 | for (i=0; i<16; i++) | |
763a495a | 132 | idbuf[i] = inb(GAPSPCI_REGS+i); |
1da177e4 LT |
133 | |
134 | if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16)) | |
135 | return -ENODEV; | |
136 | ||
763a495a | 137 | outl(0x5a14a501, GAPSPCI_REGS+0x18); |
1da177e4 LT |
138 | |
139 | for (i=0; i<1000000; i++) | |
140 | ; | |
141 | ||
763a495a | 142 | if (inl(GAPSPCI_REGS+0x18) != 1) |
1da177e4 LT |
143 | return -EINVAL; |
144 | ||
763a495a MD |
145 | outl(0x01000000, GAPSPCI_REGS+0x20); |
146 | outl(0x01000000, GAPSPCI_REGS+0x24); | |
1da177e4 | 147 | |
763a495a MD |
148 | outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28); |
149 | outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c); | |
1da177e4 | 150 | |
763a495a MD |
151 | outl(1, GAPSPCI_REGS+0x14); |
152 | outl(1, GAPSPCI_REGS+0x34); | |
1da177e4 LT |
153 | |
154 | /* Setting Broadband Adapter */ | |
763a495a MD |
155 | outw(0xf900, GAPSPCI_BBA_CONFIG+0x06); |
156 | outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30); | |
157 | outb(0x00, GAPSPCI_BBA_CONFIG+0x3c); | |
158 | outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d); | |
159 | outw(0x0006, GAPSPCI_BBA_CONFIG+0x04); | |
160 | outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10); | |
161 | outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14); | |
1da177e4 LT |
162 | |
163 | return 0; | |
164 | } | |
165 | ||
166 | /* Haven't done anything here as yet */ | |
167 | char * __devinit pcibios_setup(char *str) | |
168 | { | |
169 | return str; | |
170 | } |