aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/sh/drivers
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/sh/drivers')
-rw-r--r--arch/sh/drivers/Makefile7
-rw-r--r--arch/sh/drivers/dma/Kconfig55
-rw-r--r--arch/sh/drivers/dma/Makefile9
-rw-r--r--arch/sh/drivers/dma/dma-api.c292
-rw-r--r--arch/sh/drivers/dma/dma-g2.c171
-rw-r--r--arch/sh/drivers/dma/dma-isa.c106
-rw-r--r--arch/sh/drivers/dma/dma-pvr2.c109
-rw-r--r--arch/sh/drivers/dma/dma-sh.c267
-rw-r--r--arch/sh/drivers/dma/dma-sh.h52
-rw-r--r--arch/sh/drivers/dma/dma-sysfs.c133
-rw-r--r--arch/sh/drivers/pci/Kconfig41
-rw-r--r--arch/sh/drivers/pci/Makefile16
-rw-r--r--arch/sh/drivers/pci/dma-dreamcast.c71
-rw-r--r--arch/sh/drivers/pci/fixups-dreamcast.c81
-rw-r--r--arch/sh/drivers/pci/fixups-rts7751r2d.c43
-rw-r--r--arch/sh/drivers/pci/fixups-sh03.c61
-rw-r--r--arch/sh/drivers/pci/ops-bigsur.c88
-rw-r--r--arch/sh/drivers/pci/ops-dreamcast.c169
-rw-r--r--arch/sh/drivers/pci/ops-rts7751r2d.c79
-rw-r--r--arch/sh/drivers/pci/ops-sh03.c45
-rw-r--r--arch/sh/drivers/pci/ops-snapgear.c102
-rw-r--r--arch/sh/drivers/pci/pci-auto.c555
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.c417
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.h303
-rw-r--r--arch/sh/drivers/pci/pci-st40.c509
-rw-r--r--arch/sh/drivers/pci/pci-st40.h136
-rw-r--r--arch/sh/drivers/pci/pci.c155
27 files changed, 4072 insertions, 0 deletions
diff --git a/arch/sh/drivers/Makefile b/arch/sh/drivers/Makefile
new file mode 100644
index 000000000000..bd6726cde398
--- /dev/null
+++ b/arch/sh/drivers/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the Linux SuperH-specific device drivers.
3#
4
5obj-$(CONFIG_PCI) += pci/
6obj-$(CONFIG_SH_DMA) += dma/
7
diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig
new file mode 100644
index 000000000000..0f15216cd39d
--- /dev/null
+++ b/arch/sh/drivers/dma/Kconfig
@@ -0,0 +1,55 @@
1menu "DMA support"
2
3config SH_DMA
4 bool "DMA controller (DMAC) support"
5 help
6 Selecting this option will provide same API as PC's Direct Memory
7 Access Controller(8237A) for SuperH DMAC.
8
9 If unsure, say N.
10
11config NR_ONCHIP_DMA_CHANNELS
12 depends on SH_DMA
13 int "Number of on-chip DMAC channels"
14 default "4"
15 help
16 This allows you to specify the number of channels that the on-chip
17 DMAC supports. This will be 4 for SH7750/SH7751 and 8 for the
18 SH7750R/SH7751R.
19
20config NR_DMA_CHANNELS_BOOL
21 depends on SH_DMA
22 bool "Override default number of maximum DMA channels"
23 help
24 This allows you to forcibly update the maximum number of supported
25 DMA channels for a given board. If this is unset, this will default
26 to the number of channels that the on-chip DMAC has.
27
28config NR_DMA_CHANNELS
29 int "Maximum number of DMA channels"
30 depends on SH_DMA && NR_DMA_CHANNELS_BOOL
31 default NR_ONCHIP_DMA_CHANNELS
32 help
33 This allows you to specify the maximum number of DMA channels to
34 support. Setting this to a higher value allows for cascading DMACs
35 with additional channels.
36
37config DMA_PAGE_OPS
38 bool "Use DMAC for page copy/clear"
39 depends on SH_DMA && BROKEN
40 help
41 Selecting this option will use a dual-address mode configured channel
42 in the SH DMAC for copy_page()/clear_page(). Primarily a performance
43 hack.
44
45config DMA_PAGE_OPS_CHANNEL
46 depends on DMA_PAGE_OPS
47 int "DMA channel for sh memory-manager page copy/clear"
48 default "3"
49 help
50 This allows the specification of the dual address dma channel,
51 in case channel 3 is unavailable. On the SH4, channels 1,2, and 3
52 are dual-address capable.
53
54endmenu
55
diff --git a/arch/sh/drivers/dma/Makefile b/arch/sh/drivers/dma/Makefile
new file mode 100644
index 000000000000..065d4c90970e
--- /dev/null
+++ b/arch/sh/drivers/dma/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for the SuperH DMA specific kernel interface routines under Linux.
3#
4
5obj-y += dma-api.o dma-isa.o
6obj-$(CONFIG_SYSFS) += dma-sysfs.o
7obj-$(CONFIG_SH_DMA) += dma-sh.o
8obj-$(CONFIG_SH_DREAMCAST) += dma-pvr2.o dma-g2.o
9
diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c
new file mode 100644
index 000000000000..96e3036ec2bb
--- /dev/null
+++ b/arch/sh/drivers/dma/dma-api.c
@@ -0,0 +1,292 @@
1/*
2 * arch/sh/drivers/dma/dma-api.c
3 *
4 * SuperH-specific DMA management API
5 *
6 * Copyright (C) 2003, 2004 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/interrupt.h>
15#include <linux/spinlock.h>
16#include <linux/proc_fs.h>
17#include <linux/list.h>
18#include <asm/dma.h>
19
20DEFINE_SPINLOCK(dma_spin_lock);
21static LIST_HEAD(registered_dmac_list);
22
23/*
24 * A brief note about the reasons for this API as it stands.
25 *
26 * For starters, the old ISA DMA API didn't work for us for a number of
27 * reasons, for one, the vast majority of channels on the SH DMAC are
28 * dual-address mode only, and both the new and the old DMA APIs are after the
29 * concept of managing a DMA buffer, which doesn't overly fit this model very
30 * well. In addition to which, the new API is largely geared at IOMMUs and
31 * GARTs, and doesn't even support the channel notion very well.
32 *
33 * The other thing that's a marginal issue, is the sheer number of random DMA
34 * engines that are present (ie, in boards like the Dreamcast), some of which
35 * cascade off of the SH DMAC, and others do not. As such, there was a real
36 * need for a scalable subsystem that could deal with both single and
37 * dual-address mode usage, in addition to interoperating with cascaded DMACs.
38 *
39 * There really isn't any reason why this needs to be SH specific, though I'm
40 * not aware of too many other processors (with the exception of some MIPS)
41 * that have the same concept of a dual address mode, or any real desire to
42 * actually make use of the DMAC even if such a subsystem were exposed
43 * elsewhere.
44 *
45 * The idea for this was derived from the ARM port, which acted as an excellent
46 * reference when trying to address these issues.
47 *
48 * It should also be noted that the decision to add Yet Another DMA API(tm) to
49 * the kernel wasn't made easily, and was only decided upon after conferring
50 * with jejb with regards to the state of the old and new APIs as they applied
51 * to these circumstances. Philip Blundell was also a great help in figuring
52 * out some single-address mode DMA semantics that were otherwise rather
53 * confusing.
54 */
55
56struct dma_info *get_dma_info(unsigned int chan)
57{
58 struct list_head *pos, *tmp;
59 unsigned int total = 0;
60
61 /*
62 * Look for each DMAC's range to determine who the owner of
63 * the channel is.
64 */
65 list_for_each_safe(pos, tmp, &registered_dmac_list) {
66 struct dma_info *info = list_entry(pos, struct dma_info, list);
67
68 total += info->nr_channels;
69 if (chan > total)
70 continue;
71
72 return info;
73 }
74
75 return NULL;
76}
77
78struct dma_channel *get_dma_channel(unsigned int chan)
79{
80 struct dma_info *info = get_dma_info(chan);
81
82 if (!info)
83 return ERR_PTR(-EINVAL);
84
85 return info->channels + chan;
86}
87
88int get_dma_residue(unsigned int chan)
89{
90 struct dma_info *info = get_dma_info(chan);
91 struct dma_channel *channel = &info->channels[chan];
92
93 if (info->ops->get_residue)
94 return info->ops->get_residue(channel);
95
96 return 0;
97}
98
99int request_dma(unsigned int chan, const char *dev_id)
100{
101 struct dma_info *info = get_dma_info(chan);
102 struct dma_channel *channel = &info->channels[chan];
103
104 down(&channel->sem);
105
106 if (!info->ops || chan >= MAX_DMA_CHANNELS) {
107 up(&channel->sem);
108 return -EINVAL;
109 }
110
111 atomic_set(&channel->busy, 1);
112
113 strlcpy(channel->dev_id, dev_id, sizeof(channel->dev_id));
114
115 up(&channel->sem);
116
117 if (info->ops->request)
118 return info->ops->request(channel);
119
120 return 0;
121}
122
123void free_dma(unsigned int chan)
124{
125 struct dma_info *info = get_dma_info(chan);
126 struct dma_channel *channel = &info->channels[chan];
127
128 if (info->ops->free)
129 info->ops->free(channel);
130
131 atomic_set(&channel->busy, 0);
132}
133
134void dma_wait_for_completion(unsigned int chan)
135{
136 struct dma_info *info = get_dma_info(chan);
137 struct dma_channel *channel = &info->channels[chan];
138
139 if (channel->flags & DMA_TEI_CAPABLE) {
140 wait_event(channel->wait_queue,
141 (info->ops->get_residue(channel) == 0));
142 return;
143 }
144
145 while (info->ops->get_residue(channel))
146 cpu_relax();
147}
148
149void dma_configure_channel(unsigned int chan, unsigned long flags)
150{
151 struct dma_info *info = get_dma_info(chan);
152 struct dma_channel *channel = &info->channels[chan];
153
154 if (info->ops->configure)
155 info->ops->configure(channel, flags);
156}
157
158int dma_xfer(unsigned int chan, unsigned long from,
159 unsigned long to, size_t size, unsigned int mode)
160{
161 struct dma_info *info = get_dma_info(chan);
162 struct dma_channel *channel = &info->channels[chan];
163
164 channel->sar = from;
165 channel->dar = to;
166 channel->count = size;
167 channel->mode = mode;
168
169 return info->ops->xfer(channel);
170}
171
172#ifdef CONFIG_PROC_FS
173static int dma_read_proc(char *buf, char **start, off_t off,
174 int len, int *eof, void *data)
175{
176 struct list_head *pos, *tmp;
177 char *p = buf;
178
179 if (list_empty(&registered_dmac_list))
180 return 0;
181
182 /*
183 * Iterate over each registered DMAC
184 */
185 list_for_each_safe(pos, tmp, &registered_dmac_list) {
186 struct dma_info *info = list_entry(pos, struct dma_info, list);
187 int i;
188
189 /*
190 * Iterate over each channel
191 */
192 for (i = 0; i < info->nr_channels; i++) {
193 struct dma_channel *channel = info->channels + i;
194
195 if (!(channel->flags & DMA_CONFIGURED))
196 continue;
197
198 p += sprintf(p, "%2d: %14s %s\n", i,
199 info->name, channel->dev_id);
200 }
201 }
202
203 return p - buf;
204}
205#endif
206
207
208int __init register_dmac(struct dma_info *info)
209{
210 int i;
211
212 INIT_LIST_HEAD(&info->list);
213
214 printk(KERN_INFO "DMA: Registering %s handler (%d channel%s).\n",
215 info->name, info->nr_channels,
216 info->nr_channels > 1 ? "s" : "");
217
218 BUG_ON((info->flags & DMAC_CHANNELS_CONFIGURED) && !info->channels);
219
220 /*
221 * Don't touch pre-configured channels
222 */
223 if (!(info->flags & DMAC_CHANNELS_CONFIGURED)) {
224 unsigned int size;
225
226 size = sizeof(struct dma_channel) * info->nr_channels;
227
228 info->channels = kmalloc(size, GFP_KERNEL);
229 if (!info->channels)
230 return -ENOMEM;
231
232 memset(info->channels, 0, size);
233 }
234
235 for (i = 0; i < info->nr_channels; i++) {
236 struct dma_channel *chan = info->channels + i;
237
238 chan->chan = i;
239
240 memcpy(chan->dev_id, "Unused", 7);
241
242 if (info->flags & DMAC_CHANNELS_TEI_CAPABLE)
243 chan->flags |= DMA_TEI_CAPABLE;
244
245 init_MUTEX(&chan->sem);
246 init_waitqueue_head(&chan->wait_queue);
247
248#ifdef CONFIG_SYSFS
249 dma_create_sysfs_files(chan);
250#endif
251 }
252
253 list_add(&info->list, &registered_dmac_list);
254
255 return 0;
256}
257
258void __exit unregister_dmac(struct dma_info *info)
259{
260 if (!(info->flags & DMAC_CHANNELS_CONFIGURED))
261 kfree(info->channels);
262
263 list_del(&info->list);
264}
265
266static int __init dma_api_init(void)
267{
268 printk("DMA: Registering DMA API.\n");
269
270#ifdef CONFIG_PROC_FS
271 create_proc_read_entry("dma", 0, 0, dma_read_proc, 0);
272#endif
273
274 return 0;
275}
276
277subsys_initcall(dma_api_init);
278
279MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
280MODULE_DESCRIPTION("DMA API for SuperH");
281MODULE_LICENSE("GPL");
282
283EXPORT_SYMBOL(request_dma);
284EXPORT_SYMBOL(free_dma);
285EXPORT_SYMBOL(register_dmac);
286EXPORT_SYMBOL(get_dma_residue);
287EXPORT_SYMBOL(get_dma_info);
288EXPORT_SYMBOL(get_dma_channel);
289EXPORT_SYMBOL(dma_xfer);
290EXPORT_SYMBOL(dma_wait_for_completion);
291EXPORT_SYMBOL(dma_configure_channel);
292
diff --git a/arch/sh/drivers/dma/dma-g2.c b/arch/sh/drivers/dma/dma-g2.c
new file mode 100644
index 000000000000..231e3f6fb28f
--- /dev/null
+++ b/arch/sh/drivers/dma/dma-g2.c
@@ -0,0 +1,171 @@
1/*
2 * arch/sh/drivers/dma/dma-g2.c
3 *
4 * G2 bus DMA support
5 *
6 * Copyright (C) 2003, 2004 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/interrupt.h>
16
17#include <asm/mach/sysasic.h>
18#include <asm/mach/dma.h>
19#include <asm/dma.h>
20
21struct g2_channel {
22 unsigned long g2_addr; /* G2 bus address */
23 unsigned long root_addr; /* Root bus (SH-4) address */
24 unsigned long size; /* Size (in bytes), 32-byte aligned */
25 unsigned long direction; /* Transfer direction */
26 unsigned long ctrl; /* Transfer control */
27 unsigned long chan_enable; /* Channel enable */
28 unsigned long xfer_enable; /* Transfer enable */
29 unsigned long xfer_stat; /* Transfer status */
30} __attribute__ ((aligned(32)));
31
32struct g2_status {
33 unsigned long g2_addr;
34 unsigned long root_addr;
35 unsigned long size;
36 unsigned long status;
37} __attribute__ ((aligned(16)));
38
39struct g2_dma_info {
40 struct g2_channel channel[G2_NR_DMA_CHANNELS];
41 unsigned long pad1[G2_NR_DMA_CHANNELS];
42 unsigned long wait_state;
43 unsigned long pad2[10];
44 unsigned long magic;
45 struct g2_status status[G2_NR_DMA_CHANNELS];
46} __attribute__ ((aligned(256)));
47
48static volatile struct g2_dma_info *g2_dma = (volatile struct g2_dma_info *)0xa05f7800;
49
50static irqreturn_t g2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
51{
52 /* FIXME: Do some meaningful completion work here.. */
53 return IRQ_HANDLED;
54}
55
56static struct irqaction g2_dma_irq = {
57 .name = "g2 DMA handler",
58 .handler = g2_dma_interrupt,
59 .flags = SA_INTERRUPT,
60};
61
62static int g2_enable_dma(struct dma_channel *chan)
63{
64 unsigned int chan_nr = chan->chan;
65
66 g2_dma->channel[chan_nr].chan_enable = 1;
67 g2_dma->channel[chan_nr].xfer_enable = 1;
68
69 return 0;
70}
71
72static int g2_disable_dma(struct dma_channel *chan)
73{
74 unsigned int chan_nr = chan->chan;
75
76 g2_dma->channel[chan_nr].chan_enable = 0;
77 g2_dma->channel[chan_nr].xfer_enable = 0;
78
79 return 0;
80}
81
82static int g2_xfer_dma(struct dma_channel *chan)
83{
84 unsigned int chan_nr = chan->chan;
85
86 if (chan->sar & 31) {
87 printk("g2dma: unaligned source 0x%lx\n", chan->sar);
88 return -EINVAL;
89 }
90
91 if (chan->dar & 31) {
92 printk("g2dma: unaligned dest 0x%lx\n", chan->dar);
93 return -EINVAL;
94 }
95
96 /* Align the count */
97 if (chan->count & 31)
98 chan->count = (chan->count + (32 - 1)) & ~(32 - 1);
99
100 /* Fixup destination */
101 chan->dar += 0xa0800000;
102
103 /* Fixup direction */
104 chan->mode = !chan->mode;
105
106 flush_icache_range((unsigned long)chan->sar, chan->count);
107
108 g2_disable_dma(chan);
109
110 g2_dma->channel[chan_nr].g2_addr = chan->dar & 0x1fffffe0;
111 g2_dma->channel[chan_nr].root_addr = chan->sar & 0x1fffffe0;
112 g2_dma->channel[chan_nr].size = (chan->count & ~31) | 0x80000000;
113 g2_dma->channel[chan_nr].direction = chan->mode;
114
115 /*
116 * bit 0 - ???
117 * bit 1 - if set, generate a hardware event on transfer completion
118 * bit 2 - ??? something to do with suspend?
119 */
120 g2_dma->channel[chan_nr].ctrl = 5; /* ?? */
121
122 g2_enable_dma(chan);
123
124 /* debug cruft */
125 pr_debug("count, sar, dar, mode, ctrl, chan, xfer: %ld, 0x%08lx, "
126 "0x%08lx, %ld, %ld, %ld, %ld\n",
127 g2_dma->channel[chan_nr].size,
128 g2_dma->channel[chan_nr].root_addr,
129 g2_dma->channel[chan_nr].g2_addr,
130 g2_dma->channel[chan_nr].direction,
131 g2_dma->channel[chan_nr].ctrl,
132 g2_dma->channel[chan_nr].chan_enable,
133 g2_dma->channel[chan_nr].xfer_enable);
134
135 return 0;
136}
137
138static struct dma_ops g2_dma_ops = {
139 .xfer = g2_xfer_dma,
140};
141
142static struct dma_info g2_dma_info = {
143 .name = "G2 DMA",
144 .nr_channels = 4,
145 .ops = &g2_dma_ops,
146 .flags = DMAC_CHANNELS_TEI_CAPABLE,
147};
148
149static int __init g2_dma_init(void)
150{
151 setup_irq(HW_EVENT_G2_DMA, &g2_dma_irq);
152
153 /* Magic */
154 g2_dma->wait_state = 27;
155 g2_dma->magic = 0x4659404f;
156
157 return register_dmac(&g2_dma_info);
158}
159
160static void __exit g2_dma_exit(void)
161{
162 free_irq(HW_EVENT_G2_DMA, 0);
163}
164
165subsys_initcall(g2_dma_init);
166module_exit(g2_dma_exit);
167
168MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
169MODULE_DESCRIPTION("G2 bus DMA driver");
170MODULE_LICENSE("GPL");
171
diff --git a/arch/sh/drivers/dma/dma-isa.c b/arch/sh/drivers/dma/dma-isa.c
new file mode 100644
index 000000000000..1c9bc45b8bcb
--- /dev/null
+++ b/arch/sh/drivers/dma/dma-isa.c
@@ -0,0 +1,106 @@
1/*
2 * arch/sh/drivers/dma/dma-isa.c
3 *
4 * Generic ISA DMA wrapper for SH DMA API
5 *
6 * Copyright (C) 2003, 2004 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <asm/dma.h>
15
16/*
17 * This implements a small wrapper set to make code using the old ISA DMA API
18 * work with the SH DMA API. Since most of the work in the new API happens
19 * at ops->xfer() time, we simply use the various set_dma_xxx() routines to
20 * fill in per-channel info, and then hand hand this off to ops->xfer() at
21 * enable_dma() time.
22 *
23 * For channels that are doing on-demand data transfer via cascading, the
24 * channel itself will still need to be configured through the new API. As
25 * such, this code is meant for only the simplest of tasks (and shouldn't be
26 * used in any new drivers at all).
27 *
28 * It should also be noted that various functions here are labelled as
29 * being deprecated. This is due to the fact that the ops->xfer() method is
30 * the preferred way of doing things (as well as just grabbing the spinlock
31 * directly). As such, any users of this interface will be warned rather
32 * loudly.
33 */
34
35unsigned long __deprecated claim_dma_lock(void)
36{
37 unsigned long flags;
38
39 spin_lock_irqsave(&dma_spin_lock, flags);
40
41 return flags;
42}
43EXPORT_SYMBOL(claim_dma_lock);
44
45void __deprecated release_dma_lock(unsigned long flags)
46{
47 spin_unlock_irqrestore(&dma_spin_lock, flags);
48}
49EXPORT_SYMBOL(release_dma_lock);
50
51void __deprecated disable_dma(unsigned int chan)
52{
53 /* Nothing */
54}
55EXPORT_SYMBOL(disable_dma);
56
57void __deprecated enable_dma(unsigned int chan)
58{
59 struct dma_info *info = get_dma_info(chan);
60 struct dma_channel *channel = &info->channels[chan];
61
62 info->ops->xfer(channel);
63}
64EXPORT_SYMBOL(enable_dma);
65
66void clear_dma_ff(unsigned int chan)
67{
68 /* Nothing */
69}
70EXPORT_SYMBOL(clear_dma_ff);
71
72void set_dma_mode(unsigned int chan, char mode)
73{
74 struct dma_info *info = get_dma_info(chan);
75 struct dma_channel *channel = &info->channels[chan];
76
77 channel->mode = mode;
78}
79EXPORT_SYMBOL(set_dma_mode);
80
81void set_dma_addr(unsigned int chan, unsigned int addr)
82{
83 struct dma_info *info = get_dma_info(chan);
84 struct dma_channel *channel = &info->channels[chan];
85
86 /*
87 * Single address mode is the only thing supported through
88 * this interface.
89 */
90 if ((channel->mode & DMA_MODE_MASK) == DMA_MODE_READ) {
91 channel->sar = addr;
92 } else {
93 channel->dar = addr;
94 }
95}
96EXPORT_SYMBOL(set_dma_addr);
97
98void set_dma_count(unsigned int chan, unsigned int count)
99{
100 struct dma_info *info = get_dma_info(chan);
101 struct dma_channel *channel = &info->channels[chan];
102
103 channel->count = count;
104}
105EXPORT_SYMBOL(set_dma_count);
106
diff --git a/arch/sh/drivers/dma/dma-pvr2.c b/arch/sh/drivers/dma/dma-pvr2.c
new file mode 100644
index 000000000000..2e1d58f2d1b9
--- /dev/null
+++ b/arch/sh/drivers/dma/dma-pvr2.c
@@ -0,0 +1,109 @@
1/*
2 * arch/sh/boards/dreamcast/dma-pvr2.c
3 *
4 * NEC PowerVR 2 (Dreamcast) DMA support
5 *
6 * Copyright (C) 2003, 2004 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/interrupt.h>
16#include <asm/mach/sysasic.h>
17#include <asm/mach/dma.h>
18#include <asm/dma.h>
19#include <asm/io.h>
20
21static unsigned int xfer_complete = 0;
22static int count = 0;
23
24static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
25{
26 if (get_dma_residue(PVR2_CASCADE_CHAN)) {
27 printk(KERN_WARNING "DMA: SH DMAC did not complete transfer "
28 "on channel %d, waiting..\n", PVR2_CASCADE_CHAN);
29 dma_wait_for_completion(PVR2_CASCADE_CHAN);
30 }
31
32 if (count++ < 10)
33 pr_debug("Got a pvr2 dma interrupt for channel %d\n",
34 irq - HW_EVENT_PVR2_DMA);
35
36 xfer_complete = 1;
37
38 return IRQ_HANDLED;
39}
40
41static int pvr2_request_dma(struct dma_channel *chan)
42{
43 if (ctrl_inl(PVR2_DMA_MODE) != 0)
44 return -EBUSY;
45
46 ctrl_outl(0, PVR2_DMA_LMMODE0);
47
48 return 0;
49}
50
51static int pvr2_get_dma_residue(struct dma_channel *chan)
52{
53 return xfer_complete == 0;
54}
55
56static int pvr2_xfer_dma(struct dma_channel *chan)
57{
58 if (chan->sar || !chan->dar)
59 return -EINVAL;
60
61 xfer_complete = 0;
62
63 ctrl_outl(chan->dar, PVR2_DMA_ADDR);
64 ctrl_outl(chan->count, PVR2_DMA_COUNT);
65 ctrl_outl(chan->mode & DMA_MODE_MASK, PVR2_DMA_MODE);
66
67 return 0;
68}
69
70static struct irqaction pvr2_dma_irq = {
71 .name = "pvr2 DMA handler",
72 .handler = pvr2_dma_interrupt,
73 .flags = SA_INTERRUPT,
74};
75
76static struct dma_ops pvr2_dma_ops = {
77 .request = pvr2_request_dma,
78 .get_residue = pvr2_get_dma_residue,
79 .xfer = pvr2_xfer_dma,
80};
81
82static struct dma_info pvr2_dma_info = {
83 .name = "PowerVR 2 DMA",
84 .nr_channels = 1,
85 .ops = &pvr2_dma_ops,
86 .flags = DMAC_CHANNELS_TEI_CAPABLE,
87};
88
89static int __init pvr2_dma_init(void)
90{
91 setup_irq(HW_EVENT_PVR2_DMA, &pvr2_dma_irq);
92 request_dma(PVR2_CASCADE_CHAN, "pvr2 cascade");
93
94 return register_dmac(&pvr2_dma_info);
95}
96
97static void __exit pvr2_dma_exit(void)
98{
99 free_dma(PVR2_CASCADE_CHAN);
100 free_irq(HW_EVENT_PVR2_DMA, 0);
101}
102
103subsys_initcall(pvr2_dma_init);
104module_exit(pvr2_dma_exit);
105
106MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
107MODULE_DESCRIPTION("NEC PowerVR 2 DMA driver");
108MODULE_LICENSE("GPL");
109
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c
new file mode 100644
index 000000000000..31dacd4444b2
--- /dev/null
+++ b/arch/sh/drivers/dma/dma-sh.c
@@ -0,0 +1,267 @@
1/*
2 * arch/sh/drivers/dma/dma-sh.c
3 *
4 * SuperH On-chip DMAC Support
5 *
6 * Copyright (C) 2000 Takashi YOSHII
7 * Copyright (C) 2003, 2004 Paul Mundt
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13
14#include <linux/config.h>
15#include <linux/init.h>
16#include <linux/irq.h>
17#include <linux/interrupt.h>
18#include <linux/module.h>
19#include <asm/signal.h>
20#include <asm/irq.h>
21#include <asm/dma.h>
22#include <asm/io.h>
23#include "dma-sh.h"
24
25/*
26 * The SuperH DMAC supports a number of transmit sizes, we list them here,
27 * with their respective values as they appear in the CHCR registers.
28 *
29 * Defaults to a 64-bit transfer size.
30 */
31enum {
32 XMIT_SZ_64BIT,
33 XMIT_SZ_8BIT,
34 XMIT_SZ_16BIT,
35 XMIT_SZ_32BIT,
36 XMIT_SZ_256BIT,
37};
38
39/*
40 * The DMA count is defined as the number of bytes to transfer.
41 */
42static unsigned int ts_shift[] = {
43 [XMIT_SZ_64BIT] = 3,
44 [XMIT_SZ_8BIT] = 0,
45 [XMIT_SZ_16BIT] = 1,
46 [XMIT_SZ_32BIT] = 2,
47 [XMIT_SZ_256BIT] = 5,
48};
49
50static inline unsigned int get_dmte_irq(unsigned int chan)
51{
52 unsigned int irq;
53
54 /*
55 * Normally we could just do DMTE0_IRQ + chan outright, though in the
56 * case of the 7751R, the DMTE IRQs for channels > 4 start right above
57 * the SCIF
58 */
59
60 if (chan < 4) {
61 irq = DMTE0_IRQ + chan;
62 } else {
63 irq = DMTE4_IRQ + chan - 4;
64 }
65
66 return irq;
67}
68
69/*
70 * We determine the correct shift size based off of the CHCR transmit size
71 * for the given channel. Since we know that it will take:
72 *
73 * info->count >> ts_shift[transmit_size]
74 *
75 * iterations to complete the transfer.
76 */
77static inline unsigned int calc_xmit_shift(struct dma_channel *chan)
78{
79 u32 chcr = ctrl_inl(CHCR[chan->chan]);
80
81 chcr >>= 4;
82
83 return ts_shift[chcr & 0x0007];
84}
85
86/*
87 * The transfer end interrupt must read the chcr register to end the
88 * hardware interrupt active condition.
89 * Besides that it needs to waken any waiting process, which should handle
90 * setting up the next transfer.
91 */
92static irqreturn_t dma_tei(int irq, void *dev_id, struct pt_regs *regs)
93{
94 struct dma_channel *chan = (struct dma_channel *)dev_id;
95 u32 chcr;
96
97 chcr = ctrl_inl(CHCR[chan->chan]);
98
99 if (!(chcr & CHCR_TE))
100 return IRQ_NONE;
101
102 chcr &= ~(CHCR_IE | CHCR_DE);
103 ctrl_outl(chcr, CHCR[chan->chan]);
104
105 wake_up(&chan->wait_queue);
106
107 return IRQ_HANDLED;
108}
109
110static int sh_dmac_request_dma(struct dma_channel *chan)
111{
112 return request_irq(get_dmte_irq(chan->chan), dma_tei,
113 SA_INTERRUPT, "DMAC Transfer End", chan);
114}
115
116static void sh_dmac_free_dma(struct dma_channel *chan)
117{
118 free_irq(get_dmte_irq(chan->chan), chan);
119}
120
121static void sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr)
122{
123 if (!chcr)
124 chcr = RS_DUAL;
125
126 ctrl_outl(chcr, CHCR[chan->chan]);
127
128 chan->flags |= DMA_CONFIGURED;
129}
130
131static void sh_dmac_enable_dma(struct dma_channel *chan)
132{
133 int irq = get_dmte_irq(chan->chan);
134 u32 chcr;
135
136 chcr = ctrl_inl(CHCR[chan->chan]);
137 chcr |= CHCR_DE | CHCR_IE;
138 ctrl_outl(chcr, CHCR[chan->chan]);
139
140 enable_irq(irq);
141}
142
143static void sh_dmac_disable_dma(struct dma_channel *chan)
144{
145 int irq = get_dmte_irq(chan->chan);
146 u32 chcr;
147
148 disable_irq(irq);
149
150 chcr = ctrl_inl(CHCR[chan->chan]);
151 chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE);
152 ctrl_outl(chcr, CHCR[chan->chan]);
153}
154
155static int sh_dmac_xfer_dma(struct dma_channel *chan)
156{
157 /*
158 * If we haven't pre-configured the channel with special flags, use
159 * the defaults.
160 */
161 if (!(chan->flags & DMA_CONFIGURED))
162 sh_dmac_configure_channel(chan, 0);
163
164 sh_dmac_disable_dma(chan);
165
166 /*
167 * Single-address mode usage note!
168 *
169 * It's important that we don't accidentally write any value to SAR/DAR
170 * (this includes 0) that hasn't been directly specified by the user if
171 * we're in single-address mode.
172 *
173 * In this case, only one address can be defined, anything else will
174 * result in a DMA address error interrupt (at least on the SH-4),
175 * which will subsequently halt the transfer.
176 *
177 * Channel 2 on the Dreamcast is a special case, as this is used for
178 * cascading to the PVR2 DMAC. In this case, we still need to write
179 * SAR and DAR, regardless of value, in order for cascading to work.
180 */
181 if (chan->sar || (mach_is_dreamcast() && chan->chan == 2))
182 ctrl_outl(chan->sar, SAR[chan->chan]);
183 if (chan->dar || (mach_is_dreamcast() && chan->chan == 2))
184 ctrl_outl(chan->dar, DAR[chan->chan]);
185
186 ctrl_outl(chan->count >> calc_xmit_shift(chan), DMATCR[chan->chan]);
187
188 sh_dmac_enable_dma(chan);
189
190 return 0;
191}
192
193static int sh_dmac_get_dma_residue(struct dma_channel *chan)
194{
195 if (!(ctrl_inl(CHCR[chan->chan]) & CHCR_DE))
196 return 0;
197
198 return ctrl_inl(DMATCR[chan->chan]) << calc_xmit_shift(chan);
199}
200
201#if defined(CONFIG_CPU_SH4)
202static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs)
203{
204 unsigned long dmaor = ctrl_inl(DMAOR);
205
206 printk("DMAE: DMAOR=%lx\n", dmaor);
207
208 ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_NMIF, DMAOR);
209 ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_AE, DMAOR);
210 ctrl_outl(ctrl_inl(DMAOR)|DMAOR_DME, DMAOR);
211
212 disable_irq(irq);
213
214 return IRQ_HANDLED;
215}
216#endif
217
218static struct dma_ops sh_dmac_ops = {
219 .request = sh_dmac_request_dma,
220 .free = sh_dmac_free_dma,
221 .get_residue = sh_dmac_get_dma_residue,
222 .xfer = sh_dmac_xfer_dma,
223 .configure = sh_dmac_configure_channel,
224};
225
226static struct dma_info sh_dmac_info = {
227 .name = "SuperH DMAC",
228 .nr_channels = 4,
229 .ops = &sh_dmac_ops,
230 .flags = DMAC_CHANNELS_TEI_CAPABLE,
231};
232
233static int __init sh_dmac_init(void)
234{
235 struct dma_info *info = &sh_dmac_info;
236 int i;
237
238#ifdef CONFIG_CPU_SH4
239 make_ipr_irq(DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
240 i = request_irq(DMAE_IRQ, dma_err, SA_INTERRUPT, "DMAC Address Error", 0);
241 if (i < 0)
242 return i;
243#endif
244
245 for (i = 0; i < info->nr_channels; i++) {
246 int irq = get_dmte_irq(i);
247
248 make_ipr_irq(irq, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
249 }
250
251 ctrl_outl(0x8000 | DMAOR_DME, DMAOR);
252
253 return register_dmac(info);
254}
255
256static void __exit sh_dmac_exit(void)
257{
258#ifdef CONFIG_CPU_SH4
259 free_irq(DMAE_IRQ, 0);
260#endif
261}
262
263subsys_initcall(sh_dmac_init);
264module_exit(sh_dmac_exit);
265
266MODULE_LICENSE("GPL");
267
diff --git a/arch/sh/drivers/dma/dma-sh.h b/arch/sh/drivers/dma/dma-sh.h
new file mode 100644
index 000000000000..dd9d547539a2
--- /dev/null
+++ b/arch/sh/drivers/dma/dma-sh.h
@@ -0,0 +1,52 @@
1/*
2 * arch/sh/drivers/dma/dma-sh.h
3 *
4 * Copyright (C) 2000 Takashi YOSHII
5 * Copyright (C) 2003 Paul Mundt
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11#ifndef __DMA_SH_H
12#define __DMA_SH_H
13
14/* Definitions for the SuperH DMAC */
15#define REQ_L 0x00000000
16#define REQ_E 0x00080000
17#define RACK_H 0x00000000
18#define RACK_L 0x00040000
19#define ACK_R 0x00000000
20#define ACK_W 0x00020000
21#define ACK_H 0x00000000
22#define ACK_L 0x00010000
23#define DM_INC 0x00004000
24#define DM_DEC 0x00008000
25#define SM_INC 0x00001000
26#define SM_DEC 0x00002000
27#define RS_IN 0x00000200
28#define RS_OUT 0x00000300
29#define TM_BURST 0x0000080
30#define TS_8 0x00000010
31#define TS_16 0x00000020
32#define TS_32 0x00000030
33#define TS_64 0x00000000
34#define TS_BLK 0x00000040
35#define CHCR_DE 0x00000001
36#define CHCR_TE 0x00000002
37#define CHCR_IE 0x00000004
38
39/* Define the default configuration for dual address memory-memory transfer.
40 * The 0x400 value represents auto-request, external->external.
41 */
42#define RS_DUAL (DM_INC | SM_INC | 0x400 | TS_32)
43
44#define DMAOR_COD 0x00000008
45#define DMAOR_AE 0x00000004
46#define DMAOR_NMIF 0x00000002
47#define DMAOR_DME 0x00000001
48
49#define MAX_DMAC_CHANNELS (CONFIG_NR_ONCHIP_DMA_CHANNELS)
50
51#endif /* __DMA_SH_H */
52
diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c
new file mode 100644
index 000000000000..71a6d4e7809f
--- /dev/null
+++ b/arch/sh/drivers/dma/dma-sysfs.c
@@ -0,0 +1,133 @@
1/*
2 * arch/sh/drivers/dma/dma-sysfs.c
3 *
4 * sysfs interface for SH DMA API
5 *
6 * Copyright (C) 2004 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/sysdev.h>
15#include <linux/module.h>
16#include <asm/dma.h>
17
18static struct sysdev_class dma_sysclass = {
19 set_kset_name("dma"),
20};
21
22EXPORT_SYMBOL(dma_sysclass);
23
24static ssize_t dma_show_devices(struct sys_device *dev, char *buf)
25{
26 ssize_t len = 0;
27 int i;
28
29 for (i = 0; i < MAX_DMA_CHANNELS; i++) {
30 struct dma_info *info = get_dma_info(i);
31 struct dma_channel *channel = &info->channels[i];
32
33 len += sprintf(buf + len, "%2d: %14s %s\n",
34 channel->chan, info->name,
35 channel->dev_id);
36 }
37
38 return len;
39}
40
41static SYSDEV_ATTR(devices, S_IRUGO, dma_show_devices, NULL);
42
43static int __init dma_sysclass_init(void)
44{
45 int ret;
46
47 ret = sysdev_class_register(&dma_sysclass);
48 if (ret == 0)
49 sysfs_create_file(&dma_sysclass.kset.kobj, &attr_devices.attr);
50
51 return ret;
52}
53
54postcore_initcall(dma_sysclass_init);
55
56static ssize_t dma_show_dev_id(struct sys_device *dev, char *buf)
57{
58 struct dma_channel *channel = to_dma_channel(dev);
59 return sprintf(buf, "%s\n", channel->dev_id);
60}
61
62static ssize_t dma_store_dev_id(struct sys_device *dev,
63 const char *buf, size_t count)
64{
65 struct dma_channel *channel = to_dma_channel(dev);
66 strcpy(channel->dev_id, buf);
67 return count;
68}
69
70static SYSDEV_ATTR(dev_id, S_IRUGO | S_IWUSR, dma_show_dev_id, dma_store_dev_id);
71
72static ssize_t dma_store_config(struct sys_device *dev,
73 const char *buf, size_t count)
74{
75 struct dma_channel *channel = to_dma_channel(dev);
76 unsigned long config;
77
78 config = simple_strtoul(buf, NULL, 0);
79 dma_configure_channel(channel->chan, config);
80
81 return count;
82}
83
84static SYSDEV_ATTR(config, S_IWUSR, NULL, dma_store_config);
85
86static ssize_t dma_show_mode(struct sys_device *dev, char *buf)
87{
88 struct dma_channel *channel = to_dma_channel(dev);
89 return sprintf(buf, "0x%08x\n", channel->mode);
90}
91
92static ssize_t dma_store_mode(struct sys_device *dev,
93 const char *buf, size_t count)
94{
95 struct dma_channel *channel = to_dma_channel(dev);
96 channel->mode = simple_strtoul(buf, NULL, 0);
97 return count;
98}
99
100static SYSDEV_ATTR(mode, S_IRUGO | S_IWUSR, dma_show_mode, dma_store_mode);
101
102#define dma_ro_attr(field, fmt) \
103static ssize_t dma_show_##field(struct sys_device *dev, char *buf) \
104{ \
105 struct dma_channel *channel = to_dma_channel(dev); \
106 return sprintf(buf, fmt, channel->field); \
107} \
108static SYSDEV_ATTR(field, S_IRUGO, dma_show_##field, NULL);
109
110dma_ro_attr(count, "0x%08x\n");
111dma_ro_attr(flags, "0x%08lx\n");
112
113int __init dma_create_sysfs_files(struct dma_channel *chan)
114{
115 struct sys_device *dev = &chan->dev;
116 int ret;
117
118 dev->id = chan->chan;
119 dev->cls = &dma_sysclass;
120
121 ret = sysdev_register(dev);
122 if (ret)
123 return ret;
124
125 sysdev_create_file(dev, &attr_dev_id);
126 sysdev_create_file(dev, &attr_count);
127 sysdev_create_file(dev, &attr_mode);
128 sysdev_create_file(dev, &attr_flags);
129 sysdev_create_file(dev, &attr_config);
130
131 return 0;
132}
133
diff --git a/arch/sh/drivers/pci/Kconfig b/arch/sh/drivers/pci/Kconfig
new file mode 100644
index 000000000000..6d1cbbe6745c
--- /dev/null
+++ b/arch/sh/drivers/pci/Kconfig
@@ -0,0 +1,41 @@
1config PCI
2 bool "PCI support"
3 help
4 Find out whether you have a PCI motherboard. PCI is the name of a
5 bus system, i.e. the way the CPU talks to the other stuff inside
6 your box. If you have PCI, say Y, otherwise N.
7
8 The PCI-HOWTO, available from
9 <http://www.tldp.org/docs.html#howto>, contains valuable
10 information about which PCI hardware does work under Linux and which
11 doesn't.
12
13config SH_PCIDMA_NONCOHERENT
14 bool "Cache and PCI noncoherent"
15 depends on PCI
16 default y
17 help
18 Enable this option if your platform does not have a CPU cache which
19 remains coherent with PCI DMA. It is safest to say 'Y', although you
20 will see better performance if you can say 'N', because the PCI DMA
21 code will not have to flush the CPU's caches. If you have a PCI host
22 bridge integrated with your SH CPU, refer carefully to the chip specs
23 to see if you can say 'N' here. Otherwise, leave it as 'Y'.
24
25# This is also board-specific
26config PCI_AUTO
27 bool
28 depends on PCI
29 default y
30
31config PCI_AUTO_UPDATE_RESOURCES
32 bool
33 depends on PCI_AUTO
34 default y if !SH_DREAMCAST
35 help
36 Selecting this option will cause the PCI auto code to leave your
37 BAR values alone. Otherwise they will be updated automatically. If
38 for some reason, you have a board that simply refuses to work
39 with its resources updated beyond what they are when the device
40 is powered up, set this to N. Everyone else will want this as Y.
41
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile
new file mode 100644
index 000000000000..365bc16a4a83
--- /dev/null
+++ b/arch/sh/drivers/pci/Makefile
@@ -0,0 +1,16 @@
1#
2# Makefile for the PCI specific kernel interface routines under Linux.
3#
4
5obj-y += pci.o
6obj-$(CONFIG_PCI_AUTO) += pci-auto.o
7
8obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += pci-st40.o
9obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o
10
11obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \
12 dma-dreamcast.o
13obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o
14obj-$(CONFIG_SH_BIGSUR) += ops-bigsur.o
15obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o
16obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o
diff --git a/arch/sh/drivers/pci/dma-dreamcast.c b/arch/sh/drivers/pci/dma-dreamcast.c
new file mode 100644
index 000000000000..83de7ef4e7df
--- /dev/null
+++ b/arch/sh/drivers/pci/dma-dreamcast.c
@@ -0,0 +1,71 @@
1/*
2 * arch/sh/pci/dma-dreamcast.c
3 *
4 * PCI DMA support 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
18#include <linux/config.h>
19#include <linux/sched.h>
20#include <linux/kernel.h>
21#include <linux/param.h>
22#include <linux/interrupt.h>
23#include <linux/init.h>
24#include <linux/irq.h>
25#include <linux/pci.h>
26#include <linux/dma-mapping.h>
27#include <linux/device.h>
28
29#include <asm/io.h>
30#include <asm/irq.h>
31#include <asm/mach/pci.h>
32
33static int gapspci_dma_used = 0;
34
35void *dreamcast_consistent_alloc(struct device *dev, size_t size,
36 dma_addr_t *dma_handle, int flag)
37{
38 unsigned long buf;
39
40 if (dev && dev->bus != &pci_bus_type)
41 return NULL;
42
43 if (gapspci_dma_used + size > GAPSPCI_DMA_SIZE)
44 return ERR_PTR(-EINVAL);
45
46 buf = GAPSPCI_DMA_BASE + gapspci_dma_used;
47
48 gapspci_dma_used = PAGE_ALIGN(gapspci_dma_used+size);
49
50 *dma_handle = (dma_addr_t)buf;
51
52 buf = P2SEGADDR(buf);
53
54 /* Flush the dcache before we hand off the buffer */
55 dma_cache_wback_inv((void *)buf, size);
56
57 return (void *)buf;
58}
59
60int dreamcast_consistent_free(struct device *dev, size_t size,
61 void *vaddr, dma_addr_t dma_handle)
62{
63 if (dev && dev->bus != &pci_bus_type)
64 return -EINVAL;
65
66 /* XXX */
67 gapspci_dma_used = 0;
68
69 return 0;
70}
71
diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c
new file mode 100644
index 000000000000..cf30e2fa51be
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-dreamcast.c
@@ -0,0 +1,81 @@
1/*
2 * arch/sh/pci/fixups-dreamcast.c
3 *
4 * PCI fixups 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
18#include <linux/config.h>
19#include <linux/sched.h>
20#include <linux/kernel.h>
21#include <linux/param.h>
22#include <linux/interrupt.h>
23#include <linux/init.h>
24#include <linux/irq.h>
25#include <linux/pci.h>
26
27#include <asm/io.h>
28#include <asm/irq.h>
29#include <asm/mach/pci.h>
30
31static void __init gapspci_fixup_resources(struct pci_dev *dev)
32{
33 struct pci_channel *p = board_pci_channels;
34
35 printk(KERN_NOTICE "PCI: Fixing up device %s\n", pci_name(dev));
36
37 switch (dev->device) {
38 case PCI_DEVICE_ID_SEGA_BBA:
39 /*
40 * We also assume that dev->devfn == 0
41 */
42 dev->resource[1].start = p->io_resource->start + 0x100;
43 dev->resource[1].end = dev->resource[1].start + 0x200 - 1;
44 break;
45 default:
46 printk("PCI: Failed resource fixup\n");
47 }
48}
49
50DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources);
51
52void __init pcibios_fixup_bus(struct pci_bus *bus)
53{
54 /*
55 * We don't have any sub bus to fix up, and this is a rather
56 * stupid place to put general device fixups. Don't do it.
57 * Use the pcibios_fixups table or suffer the consequences.
58 */
59}
60
61void __init pcibios_fixup_irqs(void)
62{
63 struct pci_dev *dev = 0;
64
65 for_each_pci_dev(dev) {
66 /*
67 * The interrupt routing semantics here are quite trivial.
68 *
69 * We basically only support one interrupt, so we only bother
70 * updating a device's interrupt line with this single shared
71 * interrupt. Keeps routing quite simple, doesn't it?
72 */
73 printk(KERN_NOTICE "PCI: Fixing up IRQ routing for device %s\n",
74 pci_name(dev));
75
76 dev->irq = GAPSPCI_IRQ;
77
78 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
79 }
80}
81
diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c
new file mode 100644
index 000000000000..0c590fc7a081
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c
@@ -0,0 +1,43 @@
1/*
2 * arch/sh/drivers/pci/fixups-rts7751r2d.c
3 *
4 * RTS7751R2D PCI fixups
5 *
6 * Copyright (C) 2003 Lineo uSolutions, Inc.
7 * Copyright (C) 2004 Paul Mundt
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include "pci-sh7751.h"
14#include <asm/io.h>
15
16#define PCIMCR_MRSET_OFF 0xBFFFFFFF
17#define PCIMCR_RFSH_OFF 0xFFFFFFFB
18
19int pci_fixup_pcic(void)
20{
21 unsigned long bcr1, mcr;
22
23 bcr1 = inl(SH7751_BCR1);
24 bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */
25 outl(bcr1, PCI_REG(SH7751_PCIBCR1));
26
27 /* Enable all interrupts, so we known what to fix */
28 outl(0x0000c3ff, PCI_REG(SH7751_PCIINTM));
29 outl(0x0000380f, PCI_REG(SH7751_PCIAINTM));
30
31 outl(0xfb900047, PCI_REG(SH7751_PCICONF1));
32 outl(0xab000001, PCI_REG(SH7751_PCICONF4));
33
34 mcr = inl(SH7751_MCR);
35 mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
36 outl(mcr, PCI_REG(SH7751_PCIMCR));
37
38 outl(0x0c000000, PCI_REG(SH7751_PCICONF5));
39 outl(0xd0000000, PCI_REG(SH7751_PCICONF6));
40 outl(0x0c000000, PCI_REG(SH7751_PCILAR0));
41 outl(0x00000000, PCI_REG(SH7751_PCILAR1));
42 return 0;
43}
diff --git a/arch/sh/drivers/pci/fixups-sh03.c b/arch/sh/drivers/pci/fixups-sh03.c
new file mode 100644
index 000000000000..57ac26c2171f
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-sh03.c
@@ -0,0 +1,61 @@
1#include <linux/kernel.h>
2#include <linux/init.h>
3#include <linux/types.h>
4#include <linux/pci.h>
5
6/*
7 * IRQ functions
8 */
9
10int __init pcibios_map_platform_irq(u8 slot, u8 pin, struct pci_dev *dev)
11{
12 int irq;
13
14 if (dev->bus->number == 0) {
15 switch (slot) {
16 case 4: return 5; /* eth0 */
17 case 8: return 5; /* eth1 */
18 case 6: return 2; /* PCI bridge */
19 default:
20 printk("PCI: Bad IRQ mapping request for slot %d\n", slot);
21 return 2;
22 }
23 } else {
24 switch (pin) {
25 case 0: irq = 2; break;
26 case 1: irq = 2; break;
27 case 2: irq = 2; break;
28 case 3: irq = 2; break;
29 case 4: irq = 2; break;
30 default: irq = -1; break;
31 }
32 }
33 return irq;
34}
35
36static u8 __init sh03_no_swizzle(struct pci_dev *dev, u8 *pin)
37{
38 /* no swizzling */
39 return PCI_SLOT(dev->devfn);
40}
41
42static int sh03_pci_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin)
43{
44 int irq = -1;
45
46 /* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */
47 irq = pcibios_map_platform_irq(slot, pin, dev);
48 if( irq < 0 ) {
49 pr_debug("PCI: Error mapping IRQ on device %s\n", pci_name(dev));
50 return irq;
51 }
52
53 pr_debug("Setting IRQ for slot %s to %d\n", pci_name(dev), irq);
54
55 return irq;
56}
57
58void __init pcibios_fixup_irqs(void)
59{
60 pci_fixup_irqs(sh03_no_swizzle, sh03_pci_lookup_irq);
61}
diff --git a/arch/sh/drivers/pci/ops-bigsur.c b/arch/sh/drivers/pci/ops-bigsur.c
new file mode 100644
index 000000000000..9b43da67804b
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-bigsur.c
@@ -0,0 +1,88 @@
1/*
2 * linux/arch/sh/kernel/pci-bigsur.c
3 *
4 * By Dustin McIntire (dustin@sensoria.com) (c)2001
5 *
6 * Ported to new API by Paul Mundt <lethal@linux-sh.org>.
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 *
11 * PCI initialization for the Hitachi Big Sur Evaluation Board
12 */
13
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pci.h>
20
21#include <asm/io.h>
22#include "pci-sh7751.h"
23#include <asm/bigsur/bigsur.h>
24
25#define BIGSUR_PCI_IO 0x4000
26#define BIGSUR_PCI_MEM 0xfd000000
27
28static struct resource sh7751_io_resource = {
29 .name = "SH7751 IO",
30 .start = BIGSUR_PCI_IO,
31 .end = BIGSUR_PCI_IO + (64*1024) - 1,
32 .flags = IORESOURCE_IO,
33};
34
35static struct resource sh7751_mem_resource = {
36 .name = "SH7751 mem",
37 .start = BIGSUR_PCI_MEM,
38 .end = BIGSUR_PCI_MEM + (64*1024*1024) - 1,
39 .flags = IORESOURCE_MEM,
40};
41
42extern struct pci_ops sh7751_pci_ops;
43
44struct pci_channel board_pci_channels[] = {
45 { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
46 { 0, }
47};
48
49static struct sh7751_pci_address_map sh7751_pci_map = {
50 .window0 = {
51 .base = SH7751_CS3_BASE_ADDR,
52 .size = BIGSUR_LSR0_SIZE,
53 },
54
55 .window1 = {
56 .base = SH7751_CS3_BASE_ADDR,
57 .size = BIGSUR_LSR1_SIZE,
58 },
59};
60
61/*
62 * Initialize the Big Sur PCI interface
63 * Setup hardware to be Central Funtion
64 * Copy the BSR regs to the PCI interface
65 * Setup PCI windows into local RAM
66 */
67int __init pcibios_init_platform(void)
68{
69 return sh7751_pcic_init(&sh7751_pci_map);
70}
71
72int pcibios_map_platform_irq(u8 slot, u8 pin)
73{
74 /*
75 * The Big Sur can be used in a CPCI chassis, but the SH7751 PCI
76 * interface is on the wrong end of the board so that it can also
77 * support a V320 CPI interface chip... Therefor the IRQ mapping is
78 * somewhat use dependent... I'l assume a linear map for now, i.e.
79 * INTA=slot0,pin0... INTD=slot3,pin0...
80 */
81 int irq = (slot + pin-1) % 4 + BIGSUR_SH7751_PCI_IRQ_BASE;
82
83 PCIDBG(2, "PCI: Mapping Big Sur IRQ for slot %d, pin %c to irq %d\n",
84 slot, pin-1+'A', irq);
85
86 return irq;
87}
88
diff --git a/arch/sh/drivers/pci/ops-dreamcast.c b/arch/sh/drivers/pci/ops-dreamcast.c
new file mode 100644
index 000000000000..69af80b93e3f
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-dreamcast.c
@@ -0,0 +1,169 @@
1/*
2 * arch/sh/pci/ops-dreamcast.c
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
18#include <linux/config.h>
19#include <linux/sched.h>
20#include <linux/kernel.h>
21#include <linux/param.h>
22#include <linux/interrupt.h>
23#include <linux/init.h>
24#include <linux/irq.h>
25#include <linux/pci.h>
26
27#include <asm/io.h>
28#include <asm/irq.h>
29#include <asm/mach/pci.h>
30
31static 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
38static 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
45static struct pci_ops gapspci_pci_ops;
46
47struct pci_channel board_pci_channels[] = {
48 { &gapspci_pci_ops, &gapspci_io_resource,
49 &gapspci_mem_resource, 0, 1 },
50 { 0, }
51};
52
53/*
54 * The !gapspci_config_access case really shouldn't happen, ever, unless
55 * someone implicitly messes around with the last devfn value.. otherwise we
56 * only support a single device anyways, and if we didn't have a BBA, we
57 * wouldn't make it terribly far through the PCI setup anyways.
58 *
59 * Also, we could very easily support both Type 0 and Type 1 configurations
60 * here, but since it doesn't seem that there is any such implementation in
61 * existance, we don't bother.
62 *
63 * I suppose if someone actually gets around to ripping the chip out of
64 * the BBA and hanging some more devices off of it, then this might be
65 * something to take into consideration. However, due to the cost of the BBA,
66 * and the general lack of activity by DC hardware hackers, this doesn't seem
67 * likely to happen anytime soon.
68 */
69static int gapspci_config_access(unsigned char bus, unsigned int devfn)
70{
71 return (bus == 0) && (devfn == 0);
72}
73
74/*
75 * We can also actually read and write in b/w/l sizes! Thankfully this part
76 * was at least done right, and we don't have to do the stupid masking and
77 * shifting that we do on the 7751! Small wonders never cease to amaze.
78 */
79static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val)
80{
81 *val = 0xffffffff;
82
83 if (!gapspci_config_access(bus->number, devfn))
84 return PCIBIOS_DEVICE_NOT_FOUND;
85
86 switch (size) {
87 case 1: *val = inb(GAPSPCI_BBA_CONFIG+where); break;
88 case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break;
89 case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break;
90 }
91
92 return PCIBIOS_SUCCESSFUL;
93}
94
95static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
96{
97 if (!gapspci_config_access(bus->number, devfn))
98 return PCIBIOS_DEVICE_NOT_FOUND;
99
100 switch (size) {
101 case 1: outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break;
102 case 2: outw((u16)val, GAPSPCI_BBA_CONFIG+where); break;
103 case 4: outl((u32)val, GAPSPCI_BBA_CONFIG+where); break;
104 }
105
106 return PCIBIOS_SUCCESSFUL;
107}
108
109static struct pci_ops gapspci_pci_ops = {
110 .read = gapspci_read,
111 .write = gapspci_write,
112};
113
114/*
115 * gapspci init
116 */
117
118int __init gapspci_init(void)
119{
120 char idbuf[16];
121 int i;
122
123 /*
124 * FIXME: All of this wants documenting to some degree,
125 * even some basic register definitions would be nice.
126 *
127 * I haven't seen anything this ugly since.. maple.
128 */
129
130 for (i=0; i<16; i++)
131 idbuf[i] = inb(GAPSPCI_REGS+i);
132
133 if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16))
134 return -ENODEV;
135
136 outl(0x5a14a501, GAPSPCI_REGS+0x18);
137
138 for (i=0; i<1000000; i++)
139 ;
140
141 if (inl(GAPSPCI_REGS+0x18) != 1)
142 return -EINVAL;
143
144 outl(0x01000000, GAPSPCI_REGS+0x20);
145 outl(0x01000000, GAPSPCI_REGS+0x24);
146
147 outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28);
148 outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c);
149
150 outl(1, GAPSPCI_REGS+0x14);
151 outl(1, GAPSPCI_REGS+0x34);
152
153 /* Setting Broadband Adapter */
154 outw(0xf900, GAPSPCI_BBA_CONFIG+0x06);
155 outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30);
156 outb(0x00, GAPSPCI_BBA_CONFIG+0x3c);
157 outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d);
158 outw(0x0006, GAPSPCI_BBA_CONFIG+0x04);
159 outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10);
160 outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14);
161
162 return 0;
163}
164
165/* Haven't done anything here as yet */
166char * __devinit pcibios_setup(char *str)
167{
168 return str;
169}
diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c
new file mode 100644
index 000000000000..beafa11f4d0c
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-rts7751r2d.c
@@ -0,0 +1,79 @@
1/*
2 * linux/arch/sh/kernel/pci-rts7751r2d.c
3 *
4 * Author: Ian DaSilva (idasilva@mvista.com)
5 *
6 * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 *
11 * PCI initialization for the Renesas SH7751R RTS7751R2D board
12 */
13
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pci.h>
20#include <linux/module.h>
21
22#include <asm/io.h>
23#include "pci-sh7751.h"
24#include <asm/rts7751r2d/rts7751r2d.h>
25
26int __init pcibios_map_platform_irq(u8 slot, u8 pin)
27{
28 switch (slot) {
29 case 0: return IRQ_PCISLOT1; /* PCI Extend slot #1 */
30 case 1: return IRQ_PCISLOT2; /* PCI Extend slot #2 */
31 case 2: return IRQ_PCMCIA; /* PCI Cardbus Bridge */
32 case 3: return IRQ_PCIETH; /* Realtek Ethernet controller */
33 default:
34 printk("PCI: Bad IRQ mapping request for slot %d\n", slot);
35 return -1;
36 }
37}
38
39static struct resource sh7751_io_resource = {
40 .name = "SH7751_IO",
41 .start = 0x4000,
42 .end = 0x4000 + SH7751_PCI_IO_SIZE - 1,
43 .flags = IORESOURCE_IO
44};
45
46static struct resource sh7751_mem_resource = {
47 .name = "SH7751_mem",
48 .start = SH7751_PCI_MEMORY_BASE,
49 .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
50 .flags = IORESOURCE_MEM
51};
52
53extern struct pci_ops sh7751_pci_ops;
54
55struct pci_channel board_pci_channels[] = {
56 { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
57 { NULL, NULL, NULL, 0, 0 },
58};
59EXPORT_SYMBOL(board_pci_channels);
60
61static struct sh7751_pci_address_map sh7751_pci_map = {
62 .window0 = {
63 .base = SH7751_CS3_BASE_ADDR,
64 .size = 0x04000000,
65 },
66
67 .window1 = {
68 .base = 0x00000000, /* Unused */
69 .size = 0x00000000, /* Unused */
70 },
71
72 .flags = SH7751_PCIC_NO_RESET,
73};
74
75int __init pcibios_init_platform(void)
76{
77 return sh7751_pcic_init(&sh7751_pci_map);
78}
79
diff --git a/arch/sh/drivers/pci/ops-sh03.c b/arch/sh/drivers/pci/ops-sh03.c
new file mode 100644
index 000000000000..df2199732348
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-sh03.c
@@ -0,0 +1,45 @@
1/*
2 * linux/arch/sh/drivers/pci/ops-sh03.c
3 *
4 * PCI initialization for the Interface CTP/PCI-SH03 board
5 */
6
7#include <linux/config.h>
8#include <linux/kernel.h>
9#include <linux/types.h>
10#include <linux/init.h>
11#include <linux/delay.h>
12#include <linux/pci.h>
13#include <asm/io.h>
14#include "pci-sh7751.h"
15
16/*
17 * Description: This function sets up and initializes the pcic, sets
18 * up the BARS, maps the DRAM into the address space etc, etc.
19 */
20int __init pcibios_init_platform(void)
21{
22 return 1;
23}
24
25static struct resource sh7751_io_resource = {
26 .name = "SH03 IO",
27 .start = SH7751_PCI_IO_BASE,
28 .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
29 .flags = IORESOURCE_IO
30};
31
32static struct resource sh7751_mem_resource = {
33 .name = "SH03 mem",
34 .start = SH7751_PCI_MEMORY_BASE,
35 .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
36 .flags = IORESOURCE_MEM
37};
38
39extern struct pci_ops sh7751_pci_ops;
40
41struct pci_channel board_pci_channels[] = {
42 { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
43 { NULL, NULL, NULL, 0, 0 },
44};
45
diff --git a/arch/sh/drivers/pci/ops-snapgear.c b/arch/sh/drivers/pci/ops-snapgear.c
new file mode 100644
index 000000000000..6fdb9765c99a
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-snapgear.c
@@ -0,0 +1,102 @@
1/*
2 * arch/sh/drivers/pci/ops-snapgear.c
3 *
4 * Author: David McCullough <davidm@snapgear.com>
5 *
6 * Ported to new API by Paul Mundt <lethal@linux-sh.org>
7 *
8 * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
9 *
10 * May be copied or modified under the terms of the GNU General Public
11 * License. See linux/COPYING for more information.
12 *
13 * PCI initialization for the SnapGear boards
14 */
15
16#include <linux/config.h>
17#include <linux/kernel.h>
18#include <linux/types.h>
19#include <linux/init.h>
20#include <linux/delay.h>
21#include <linux/pci.h>
22
23#include <asm/io.h>
24#include "pci-sh7751.h"
25
26#define SNAPGEAR_PCI_IO 0x4000
27#define SNAPGEAR_PCI_MEM 0xfd000000
28
29/* PCI: default LOCAL memory window sizes (seen from PCI bus) */
30#define SNAPGEAR_LSR0_SIZE (64*(1<<20)) //64MB
31#define SNAPGEAR_LSR1_SIZE (64*(1<<20)) //64MB
32
33static struct resource sh7751_io_resource = {
34 .name = "SH7751 IO",
35 .start = SNAPGEAR_PCI_IO,
36 .end = SNAPGEAR_PCI_IO + (64*1024) - 1, /* 64KiB I/O */
37 .flags = IORESOURCE_IO,
38};
39
40static struct resource sh7751_mem_resource = {
41 .name = "SH7751 mem",
42 .start = SNAPGEAR_PCI_MEM,
43 .end = SNAPGEAR_PCI_MEM + (64*1024*1024) - 1, /* 64MiB mem */
44 .flags = IORESOURCE_MEM,
45};
46
47extern struct pci_ops sh7751_pci_ops;
48
49struct pci_channel board_pci_channels[] = {
50 { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
51 { 0, }
52};
53
54static struct sh7751_pci_address_map sh7751_pci_map = {
55 .window0 = {
56 .base = SH7751_CS2_BASE_ADDR,
57 .size = SNAPGEAR_LSR0_SIZE,
58 },
59
60 .window1 = {
61 .base = SH7751_CS2_BASE_ADDR,
62 .size = SNAPGEAR_LSR1_SIZE,
63 },
64
65 .flags = SH7751_PCIC_NO_RESET,
66};
67
68/*
69 * Initialize the SnapGear PCI interface
70 * Setup hardware to be Central Funtion
71 * Copy the BSR regs to the PCI interface
72 * Setup PCI windows into local RAM
73 */
74int __init pcibios_init_platform(void)
75{
76 return sh7751_pcic_init(&sh7751_pci_map);
77}
78
79int __init pcibios_map_platform_irq(u8 slot, u8 pin)
80{
81 int irq = -1;
82
83 switch (slot) {
84 case 8: /* the PCI bridge */ break;
85 case 11: irq = 8; break; /* USB */
86 case 12: irq = 11; break; /* PCMCIA */
87 case 13: irq = 5; break; /* eth0 */
88 case 14: irq = 8; break; /* eth1 */
89 case 15: irq = 11; break; /* safenet (unused) */
90 }
91
92 printk("PCI: Mapping SnapGear IRQ for slot %d, pin %c to irq %d\n",
93 slot, pin - 1 + 'A', irq);
94
95 return irq;
96}
97
98void __init pcibios_fixup(void)
99{
100 /* Nothing to fixup .. */
101}
102
diff --git a/arch/sh/drivers/pci/pci-auto.c b/arch/sh/drivers/pci/pci-auto.c
new file mode 100644
index 000000000000..4cef4d1d8c84
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-auto.c
@@ -0,0 +1,555 @@
1/*
2 * PCI autoconfiguration library
3 *
4 * Author: Matt Porter <mporter@mvista.com>
5 *
6 * Copyright 2000, 2001 MontaVista Software Inc.
7 * Copyright 2001 Bradley D. LaRonde <brad@ltc.com>
8 * Copyright 2003 Paul Mundt <lethal@linux-sh.org>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16/*
17 * Modified for MIPS by Jun Sun, jsun@mvista.com
18 *
19 * . Simplify the interface between pci_auto and the rest: a single function.
20 * . Assign resources from low address to upper address.
21 * . change most int to u32.
22 *
23 * Further modified to include it as mips generic code, ppopov@mvista.com.
24 *
25 * 2001-10-26 Bradley D. LaRonde <brad@ltc.com>
26 * - Add a top_bus argument to the "early config" functions so that
27 * they can set a fake parent bus pointer to convince the underlying
28 * pci ops to use type 1 configuration for sub busses.
29 * - Set bridge base and limit registers correctly.
30 * - Align io and memory base properly before and after bridge setup.
31 * - Don't fall through to pci_setup_bars for bridge.
32 * - Reformat the debug output to look more like lspci's output.
33 *
34 * Cloned for SuperH by M. R. Brown, mrbrown@0xd6.org
35 *
36 * 2003-08-05 Paul Mundt <lethal@linux-sh.org>
37 * - Don't update the BAR values on systems that already have valid addresses
38 * and don't want these updated for whatever reason, by way of a new config
39 * option check. However, we still read in the old BAR values so that they
40 * can still be reported through the debug output.
41 */
42
43#include <linux/kernel.h>
44#include <linux/init.h>
45#include <linux/types.h>
46#include <linux/pci.h>
47
48#undef DEBUG
49#ifdef DEBUG
50#define DBG(x...) printk(x)
51#else
52#define DBG(x...)
53#endif
54
55/*
56 * These functions are used early on before PCI scanning is done
57 * and all of the pci_dev and pci_bus structures have been created.
58 */
59static struct pci_dev *fake_pci_dev(struct pci_channel *hose,
60 int top_bus, int busnr, int devfn)
61{
62 static struct pci_dev dev;
63 static struct pci_bus bus;
64
65 dev.bus = &bus;
66 dev.sysdata = hose;
67 dev.devfn = devfn;
68 bus.number = busnr;
69 bus.ops = hose->pci_ops;
70
71 if(busnr != top_bus)
72 /* Fake a parent bus structure. */
73 bus.parent = &bus;
74 else
75 bus.parent = NULL;
76
77 return &dev;
78}
79
80#define EARLY_PCI_OP(rw, size, type) \
81int early_##rw##_config_##size(struct pci_channel *hose, \
82 int top_bus, int bus, int devfn, int offset, type value) \
83{ \
84 return pci_##rw##_config_##size( \
85 fake_pci_dev(hose, top_bus, bus, devfn), \
86 offset, value); \
87}
88
89EARLY_PCI_OP(read, byte, u8 *)
90EARLY_PCI_OP(read, word, u16 *)
91EARLY_PCI_OP(read, dword, u32 *)
92EARLY_PCI_OP(write, byte, u8)
93EARLY_PCI_OP(write, word, u16)
94EARLY_PCI_OP(write, dword, u32)
95
96static struct resource *io_resource_inuse;
97static struct resource *mem_resource_inuse;
98
99static u32 pciauto_lower_iospc;
100static u32 pciauto_upper_iospc;
101
102static u32 pciauto_lower_memspc;
103static u32 pciauto_upper_memspc;
104
105static void __init
106pciauto_setup_bars(struct pci_channel *hose,
107 int top_bus,
108 int current_bus,
109 int pci_devfn,
110 int bar_limit)
111{
112 u32 bar_response, bar_size, bar_value;
113 u32 bar, addr_mask, bar_nr = 0;
114 u32 * upper_limit;
115 u32 * lower_limit;
116 int found_mem64 = 0;
117
118 for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) {
119#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
120 u32 bar_addr;
121
122 /* Read the old BAR value */
123 early_read_config_dword(hose, top_bus,
124 current_bus,
125 pci_devfn,
126 bar,
127 &bar_addr);
128#endif
129
130 /* Tickle the BAR and get the response */
131 early_write_config_dword(hose, top_bus,
132 current_bus,
133 pci_devfn,
134 bar,
135 0xffffffff);
136
137 early_read_config_dword(hose, top_bus,
138 current_bus,
139 pci_devfn,
140 bar,
141 &bar_response);
142
143#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
144 /*
145 * Write the old BAR value back out, only update the BAR
146 * if we implicitly want resources to be updated, which
147 * is done by the generic code further down. -- PFM.
148 */
149 early_write_config_dword(hose, top_bus,
150 current_bus,
151 pci_devfn,
152 bar,
153 bar_addr);
154#endif
155
156 /* If BAR is not implemented go to the next BAR */
157 if (!bar_response)
158 continue;
159
160 /*
161 * Workaround for a BAR that doesn't use its upper word,
162 * like the ALi 1535D+ PCI DC-97 Controller Modem (M5457).
163 * bdl <brad@ltc.com>
164 */
165 if (!(bar_response & 0xffff0000))
166 bar_response |= 0xffff0000;
167
168retry:
169 /* Check the BAR type and set our address mask */
170 if (bar_response & PCI_BASE_ADDRESS_SPACE) {
171 addr_mask = PCI_BASE_ADDRESS_IO_MASK;
172 upper_limit = &pciauto_upper_iospc;
173 lower_limit = &pciauto_lower_iospc;
174 DBG(" I/O");
175 } else {
176 if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
177 PCI_BASE_ADDRESS_MEM_TYPE_64)
178 found_mem64 = 1;
179
180 addr_mask = PCI_BASE_ADDRESS_MEM_MASK;
181 upper_limit = &pciauto_upper_memspc;
182 lower_limit = &pciauto_lower_memspc;
183 DBG(" Mem");
184 }
185
186
187 /* Calculate requested size */
188 bar_size = ~(bar_response & addr_mask) + 1;
189
190 /* Allocate a base address */
191 bar_value = ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size;
192
193 if ((bar_value + bar_size) > *upper_limit) {
194 if (bar_response & PCI_BASE_ADDRESS_SPACE) {
195 if (io_resource_inuse->child) {
196 io_resource_inuse =
197 io_resource_inuse->child;
198 pciauto_lower_iospc =
199 io_resource_inuse->start;
200 pciauto_upper_iospc =
201 io_resource_inuse->end + 1;
202 goto retry;
203 }
204
205 } else {
206 if (mem_resource_inuse->child) {
207 mem_resource_inuse =
208 mem_resource_inuse->child;
209 pciauto_lower_memspc =
210 mem_resource_inuse->start;
211 pciauto_upper_memspc =
212 mem_resource_inuse->end + 1;
213 goto retry;
214 }
215 }
216 DBG(" unavailable -- skipping, value %x size %x\n",
217 bar_value, bar_size);
218 continue;
219 }
220
221#ifdef CONFIG_PCI_AUTO_UPDATE_RESOURCES
222 /* Write it out and update our limit */
223 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
224 bar, bar_value);
225#endif
226
227 *lower_limit = bar_value + bar_size;
228
229 /*
230 * If we are a 64-bit decoder then increment to the
231 * upper 32 bits of the bar and force it to locate
232 * in the lower 4GB of memory.
233 */
234 if (found_mem64) {
235 bar += 4;
236 early_write_config_dword(hose, top_bus,
237 current_bus,
238 pci_devfn,
239 bar,
240 0x00000000);
241 }
242
243 DBG(" at 0x%.8x [size=0x%x]\n", bar_value, bar_size);
244
245 bar_nr++;
246 }
247
248}
249
250static void __init
251pciauto_prescan_setup_bridge(struct pci_channel *hose,
252 int top_bus,
253 int current_bus,
254 int pci_devfn,
255 int sub_bus)
256{
257 /* Configure bus number registers */
258 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
259 PCI_PRIMARY_BUS, current_bus);
260 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
261 PCI_SECONDARY_BUS, sub_bus + 1);
262 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
263 PCI_SUBORDINATE_BUS, 0xff);
264
265 /* Align memory and I/O to 1MB and 4KB boundaries. */
266 pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1))
267 & ~(0x100000 - 1);
268 pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1))
269 & ~(0x1000 - 1);
270
271 /* Set base (lower limit) of address range behind bridge. */
272 early_write_config_word(hose, top_bus, current_bus, pci_devfn,
273 PCI_MEMORY_BASE, pciauto_lower_memspc >> 16);
274 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
275 PCI_IO_BASE, (pciauto_lower_iospc & 0x0000f000) >> 8);
276 early_write_config_word(hose, top_bus, current_bus, pci_devfn,
277 PCI_IO_BASE_UPPER16, pciauto_lower_iospc >> 16);
278
279 /* We don't support prefetchable memory for now, so disable */
280 early_write_config_word(hose, top_bus, current_bus, pci_devfn,
281 PCI_PREF_MEMORY_BASE, 0);
282 early_write_config_word(hose, top_bus, current_bus, pci_devfn,
283 PCI_PREF_MEMORY_LIMIT, 0);
284}
285
286static void __init
287pciauto_postscan_setup_bridge(struct pci_channel *hose,
288 int top_bus,
289 int current_bus,
290 int pci_devfn,
291 int sub_bus)
292{
293 u32 temp;
294
295 /*
296 * [jsun] we always bump up baselines a little, so that if there
297 * nothing behind P2P bridge, we don't wind up overlapping IO/MEM
298 * spaces.
299 */
300 pciauto_lower_memspc += 1;
301 pciauto_lower_iospc += 1;
302
303 /* Configure bus number registers */
304 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
305 PCI_SUBORDINATE_BUS, sub_bus);
306
307 /* Set upper limit of address range behind bridge. */
308 early_write_config_word(hose, top_bus, current_bus, pci_devfn,
309 PCI_MEMORY_LIMIT, pciauto_lower_memspc >> 16);
310 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
311 PCI_IO_LIMIT, (pciauto_lower_iospc & 0x0000f000) >> 8);
312 early_write_config_word(hose, top_bus, current_bus, pci_devfn,
313 PCI_IO_LIMIT_UPPER16, pciauto_lower_iospc >> 16);
314
315 /* Align memory and I/O to 1MB and 4KB boundaries. */
316 pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1))
317 & ~(0x100000 - 1);
318 pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1))
319 & ~(0x1000 - 1);
320
321 /* Enable memory and I/O accesses, enable bus master */
322 early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
323 PCI_COMMAND, &temp);
324 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
325 PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY
326 | PCI_COMMAND_MASTER);
327}
328
329static void __init
330pciauto_prescan_setup_cardbus_bridge(struct pci_channel *hose,
331 int top_bus,
332 int current_bus,
333 int pci_devfn,
334 int sub_bus)
335{
336 /* Configure bus number registers */
337 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
338 PCI_PRIMARY_BUS, current_bus);
339 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
340 PCI_SECONDARY_BUS, sub_bus + 1);
341 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
342 PCI_SUBORDINATE_BUS, 0xff);
343
344 /* Align memory and I/O to 4KB and 4 byte boundaries. */
345 pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1))
346 & ~(0x1000 - 1);
347 pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1))
348 & ~(0x4 - 1);
349
350 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
351 PCI_CB_MEMORY_BASE_0, pciauto_lower_memspc);
352 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
353 PCI_CB_IO_BASE_0, pciauto_lower_iospc);
354}
355
356static void __init
357pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose,
358 int top_bus,
359 int current_bus,
360 int pci_devfn,
361 int sub_bus)
362{
363 u32 temp;
364
365#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
366 /*
367 * [jsun] we always bump up baselines a little, so that if there
368 * nothing behind P2P bridge, we don't wind up overlapping IO/MEM
369 * spaces.
370 */
371 pciauto_lower_memspc += 1;
372 pciauto_lower_iospc += 1;
373#endif
374
375 /*
376 * Configure subordinate bus number. The PCI subsystem
377 * bus scan will renumber buses (reserving three additional
378 * for this PCI<->CardBus bridge for the case where a CardBus
379 * adapter contains a P2P or CB2CB bridge.
380 */
381
382 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
383 PCI_SUBORDINATE_BUS, sub_bus);
384
385 /*
386 * Reserve an additional 4MB for mem space and 16KB for
387 * I/O space. This should cover any additional space
388 * requirement of unusual CardBus devices with
389 * additional bridges that can consume more address space.
390 *
391 * Although pcmcia-cs currently will reprogram bridge
392 * windows, the goal is to add an option to leave them
393 * alone and use the bridge window ranges as the regions
394 * that are searched for free resources upon hot-insertion
395 * of a device. This will allow a PCI<->CardBus bridge
396 * configured by this routine to happily live behind a
397 * P2P bridge in a system.
398 */
399#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D)
400 pciauto_lower_memspc += 0x00400000;
401 pciauto_lower_iospc += 0x00004000;
402#endif
403
404 /* Align memory and I/O to 4KB and 4 byte boundaries. */
405 pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1))
406 & ~(0x1000 - 1);
407 pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1))
408 & ~(0x4 - 1);
409 /* Set up memory and I/O filter limits, assume 32-bit I/O space */
410 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
411 PCI_CB_MEMORY_LIMIT_0, pciauto_lower_memspc - 1);
412 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
413 PCI_CB_IO_LIMIT_0, pciauto_lower_iospc - 1);
414
415 /* Enable memory and I/O accesses, enable bus master */
416 early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
417 PCI_COMMAND, &temp);
418 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
419 PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
420 PCI_COMMAND_MASTER);
421}
422
423#define PCIAUTO_IDE_MODE_MASK 0x05
424
425static int __init
426pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
427{
428 int sub_bus;
429 u32 pci_devfn, pci_class, cmdstat, found_multi=0;
430 unsigned short vid, did;
431 unsigned char header_type;
432 int devfn_start = 0;
433 int devfn_stop = 0xff;
434
435 sub_bus = current_bus;
436
437 if (hose->first_devfn)
438 devfn_start = hose->first_devfn;
439 if (hose->last_devfn)
440 devfn_stop = hose->last_devfn;
441
442 for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
443
444 if (PCI_FUNC(pci_devfn) && !found_multi)
445 continue;
446
447 early_read_config_word(hose, top_bus, current_bus, pci_devfn,
448 PCI_VENDOR_ID, &vid);
449
450 if (vid == 0xffff) continue;
451
452 early_read_config_byte(hose, top_bus, current_bus, pci_devfn,
453 PCI_HEADER_TYPE, &header_type);
454
455 if (!PCI_FUNC(pci_devfn))
456 found_multi = header_type & 0x80;
457
458 early_read_config_word(hose, top_bus, current_bus, pci_devfn,
459 PCI_DEVICE_ID, &did);
460
461 early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
462 PCI_CLASS_REVISION, &pci_class);
463
464 DBG("%.2x:%.2x.%x Class %.4x: %.4x:%.4x",
465 current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn),
466 pci_class >> 16, vid, did);
467 if (pci_class & 0xff)
468 DBG(" (rev %.2x)", pci_class & 0xff);
469 DBG("\n");
470
471 if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) {
472 DBG(" Bridge: primary=%.2x, secondary=%.2x\n",
473 current_bus, sub_bus + 1);
474#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D)
475 pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_1);
476#endif
477 pciauto_prescan_setup_bridge(hose, top_bus, current_bus,
478 pci_devfn, sub_bus);
479 DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n",
480 sub_bus + 1,
481 pciauto_lower_iospc, pciauto_lower_memspc);
482 sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1);
483 DBG("Back to bus %.2x\n", current_bus);
484 pciauto_postscan_setup_bridge(hose, top_bus, current_bus,
485 pci_devfn, sub_bus);
486 continue;
487 } else if ((pci_class >> 16) == PCI_CLASS_BRIDGE_CARDBUS) {
488 DBG(" CARDBUS Bridge: primary=%.2x, secondary=%.2x\n",
489 current_bus, sub_bus + 1);
490 DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn));
491 /* Place CardBus Socket/ExCA registers */
492 pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_0);
493
494 pciauto_prescan_setup_cardbus_bridge(hose, top_bus,
495 current_bus, pci_devfn, sub_bus);
496
497 DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n",
498 sub_bus + 1,
499 pciauto_lower_iospc, pciauto_lower_memspc);
500 sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1);
501 DBG("Back to bus %.2x, sub_bus is %x\n", current_bus, sub_bus);
502 pciauto_postscan_setup_cardbus_bridge(hose, top_bus,
503 current_bus, pci_devfn, sub_bus);
504 continue;
505 } else if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) {
506
507 unsigned char prg_iface;
508
509 early_read_config_byte(hose, top_bus, current_bus,
510 pci_devfn, PCI_CLASS_PROG, &prg_iface);
511 if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) {
512 DBG("Skipping legacy mode IDE controller\n");
513 continue;
514 }
515 }
516
517 /*
518 * Found a peripheral, enable some standard
519 * settings
520 */
521 early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
522 PCI_COMMAND, &cmdstat);
523 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
524 PCI_COMMAND, cmdstat | PCI_COMMAND_IO |
525 PCI_COMMAND_MEMORY |
526 PCI_COMMAND_MASTER);
527#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
528 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
529 PCI_LATENCY_TIMER, 0x80);
530#endif
531
532 /* Allocate PCI I/O and/or memory space */
533 pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_5);
534 }
535 return sub_bus;
536}
537
538int __init
539pciauto_assign_resources(int busno, struct pci_channel *hose)
540{
541 /* setup resource limits */
542 io_resource_inuse = hose->io_resource;
543 mem_resource_inuse = hose->mem_resource;
544
545 pciauto_lower_iospc = io_resource_inuse->start;
546 pciauto_upper_iospc = io_resource_inuse->end + 1;
547 pciauto_lower_memspc = mem_resource_inuse->start;
548 pciauto_upper_memspc = mem_resource_inuse->end + 1;
549 DBG("Autoconfig PCI channel 0x%p\n", hose);
550 DBG("Scanning bus %.2x, I/O 0x%.8x:0x%.8x, Mem 0x%.8x:0x%.8x\n",
551 busno, pciauto_lower_iospc, pciauto_upper_iospc,
552 pciauto_lower_memspc, pciauto_upper_memspc);
553
554 return pciauto_bus_scan(hose, busno, busno);
555}
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c
new file mode 100644
index 000000000000..30b14ac7ae5a
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-sh7751.c
@@ -0,0 +1,417 @@
1/*
2 * Low-Level PCI Support for the SH7751
3 *
4 * Dustin McIntire (dustin@sensoria.com)
5 * Derived from arch/i386/kernel/pci-*.c which bore the message:
6 * (c) 1999--2000 Martin Mares <mj@ucw.cz>
7 *
8 * Ported to the new API by Paul Mundt <lethal@linux-sh.org>
9 * With cleanup by Paul van Gool <pvangool@mimotech.com>
10 *
11 * May be copied or modified under the terms of the GNU General Public
12 * License. See linux/COPYING for more information.
13 *
14 */
15
16#undef DEBUG
17
18#include <linux/config.h>
19#include <linux/types.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/pci.h>
23#include <linux/sched.h>
24#include <linux/ioport.h>
25#include <linux/errno.h>
26#include <linux/irq.h>
27#include <linux/delay.h>
28
29#include <asm/machvec.h>
30#include <asm/io.h>
31#include "pci-sh7751.h"
32
33static unsigned int pci_probe = PCI_PROBE_CONF1;
34extern int pci_fixup_pcic(void);
35
36void pcibios_fixup_irqs(void) __attribute__ ((weak));
37
38/*
39 * Direct access to PCI hardware...
40 */
41
42#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
43
44/*
45 * Functions for accessing PCI configuration space with type 1 accesses
46 */
47static int sh7751_pci_read(struct pci_bus *bus, unsigned int devfn,
48 int where, int size, u32 *val)
49{
50 unsigned long flags;
51 u32 data;
52
53 /*
54 * PCIPDR may only be accessed as 32 bit words,
55 * so we must do byte alignment by hand
56 */
57 local_irq_save(flags);
58 outl(CONFIG_CMD(bus,devfn,where), PCI_REG(SH7751_PCIPAR));
59 data = inl(PCI_REG(SH7751_PCIPDR));
60 local_irq_restore(flags);
61
62 switch (size) {
63 case 1:
64 *val = (data >> ((where & 3) << 3)) & 0xff;
65 break;
66 case 2:
67 *val = (data >> ((where & 2) << 3)) & 0xffff;
68 break;
69 case 4:
70 *val = data;
71 break;
72 default:
73 return PCIBIOS_FUNC_NOT_SUPPORTED;
74 }
75
76 return PCIBIOS_SUCCESSFUL;
77}
78
79/*
80 * Since SH7751 only does 32bit access we'll have to do a read,
81 * mask,write operation.
82 * We'll allow an odd byte offset, though it should be illegal.
83 */
84static int sh7751_pci_write(struct pci_bus *bus, unsigned int devfn,
85 int where, int size, u32 val)
86{
87 unsigned long flags;
88 int shift;
89 u32 data;
90
91 local_irq_save(flags);
92 outl(CONFIG_CMD(bus,devfn,where), PCI_REG(SH7751_PCIPAR));
93 data = inl(PCI_REG(SH7751_PCIPDR));
94 local_irq_restore(flags);
95
96 switch (size) {
97 case 1:
98 shift = (where & 3) << 3;
99 data &= ~(0xff << shift);
100 data |= ((val & 0xff) << shift);
101 break;
102 case 2:
103 shift = (where & 2) << 3;
104 data &= ~(0xffff << shift);
105 data |= ((val & 0xffff) << shift);
106 break;
107 case 4:
108 data = val;
109 break;
110 default:
111 return PCIBIOS_FUNC_NOT_SUPPORTED;
112 }
113
114 outl(data, PCI_REG(SH7751_PCIPDR));
115
116 return PCIBIOS_SUCCESSFUL;
117}
118
119#undef CONFIG_CMD
120
121struct pci_ops sh7751_pci_ops = {
122 .read = sh7751_pci_read,
123 .write = sh7751_pci_write,
124};
125
126static int __init pci_check_direct(void)
127{
128 unsigned int tmp, id;
129
130 /* check for SH7751/SH7751R hardware */
131 id = inl(SH7751_PCIREG_BASE+SH7751_PCICONF0);
132 if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) &&
133 id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) {
134 pr_debug("PCI: This is not an SH7751(R) (%x)\n", id);
135 return -ENODEV;
136 }
137
138 /*
139 * Check if configuration works.
140 */
141 if (pci_probe & PCI_PROBE_CONF1) {
142 tmp = inl (PCI_REG(SH7751_PCIPAR));
143 outl (0x80000000, PCI_REG(SH7751_PCIPAR));
144 if (inl (PCI_REG(SH7751_PCIPAR)) == 0x80000000) {
145 outl (tmp, PCI_REG(SH7751_PCIPAR));
146 printk(KERN_INFO "PCI: Using configuration type 1\n");
147 request_region(PCI_REG(SH7751_PCIPAR), 8, "PCI conf1");
148 return 0;
149 }
150 outl (tmp, PCI_REG(SH7751_PCIPAR));
151 }
152
153 pr_debug("PCI: pci_check_direct failed\n");
154 return -EINVAL;
155}
156
157/***************************************************************************************/
158
159/*
160 * Handle bus scanning and fixups ....
161 */
162
163static void __init pci_fixup_ide_bases(struct pci_dev *d)
164{
165 int i;
166
167 /*
168 * PCI IDE controllers use non-standard I/O port decoding, respect it.
169 */
170 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
171 return;
172 pr_debug("PCI: IDE base address fixup for %s\n", pci_name(d));
173 for(i=0; i<4; i++) {
174 struct resource *r = &d->resource[i];
175 if ((r->start & ~0x80) == 0x374) {
176 r->start |= 2;
177 r->end = r->start;
178 }
179 }
180}
181
182DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
183
184/*
185 * Called after each bus is probed, but before its children
186 * are examined.
187 */
188
189void __init pcibios_fixup_bus(struct pci_bus *b)
190{
191 pci_read_bridge_bases(b);
192}
193
194/*
195 * Initialization. Try all known PCI access methods. Note that we support
196 * using both PCI BIOS and direct access: in such cases, we use I/O ports
197 * to access config space.
198 *
199 * Note that the platform specific initialization (BSC registers, and memory
200 * space mapping) will be called via the machine vectors (sh_mv.mv_pci_init()) if it
201 * exitst and via the platform defined function pcibios_init_platform().
202 * See pci_bigsur.c for implementation;
203 *
204 * The BIOS version of the pci functions is not yet implemented but it is left
205 * in for completeness. Currently an error will be genereated at compile time.
206 */
207
208static int __init sh7751_pci_init(void)
209{
210 int ret;
211
212 pr_debug("PCI: Starting intialization.\n");
213 if ((ret = pci_check_direct()) != 0)
214 return ret;
215
216 return pcibios_init_platform();
217}
218
219subsys_initcall(sh7751_pci_init);
220
221static int __init __area_sdram_check(unsigned int area)
222{
223 u32 word;
224
225 word = inl(SH7751_BCR1);
226 /* check BCR for SDRAM in area */
227 if(((word >> area) & 1) == 0) {
228 printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%x\n",
229 area, word);
230 return 0;
231 }
232 outl(word, PCI_REG(SH7751_PCIBCR1));
233
234 word = (u16)inw(SH7751_BCR2);
235 /* check BCR2 for 32bit SDRAM interface*/
236 if(((word >> (area << 1)) & 0x3) != 0x3) {
237 printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%x\n",
238 area, word);
239 return 0;
240 }
241 outl(word, PCI_REG(SH7751_PCIBCR2));
242
243 return 1;
244}
245
246int __init sh7751_pcic_init(struct sh7751_pci_address_map *map)
247{
248 u32 reg;
249 u32 word;
250
251 /* Set the BCR's to enable PCI access */
252 reg = inl(SH7751_BCR1);
253 reg |= 0x80000;
254 outl(reg, SH7751_BCR1);
255
256 /* Turn the clocks back on (not done in reset)*/
257 outl(0, PCI_REG(SH7751_PCICLKR));
258 /* Clear Powerdown IRQ's (not done in reset) */
259 word = SH7751_PCIPINT_D3 | SH7751_PCIPINT_D0;
260 outl(word, PCI_REG(SH7751_PCIPINT));
261
262 /*
263 * This code is unused for some boards as it is done in the
264 * bootloader and doing it here means the MAC addresses loaded
265 * by the bootloader get lost.
266 */
267 if (!(map->flags & SH7751_PCIC_NO_RESET)) {
268 /* toggle PCI reset pin */
269 word = SH7751_PCICR_PREFIX | SH7751_PCICR_PRST;
270 outl(word,PCI_REG(SH7751_PCICR));
271 /* Wait for a long time... not 1 sec. but long enough */
272 mdelay(100);
273 word = SH7751_PCICR_PREFIX;
274 outl(word,PCI_REG(SH7751_PCICR));
275 }
276
277 /* set the command/status bits to:
278 * Wait Cycle Control + Parity Enable + Bus Master +
279 * Mem space enable
280 */
281 word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER |
282 SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES;
283 outl(word, PCI_REG(SH7751_PCICONF1));
284
285 /* define this host as the host bridge */
286 word = SH7751_PCI_HOST_BRIDGE << 24;
287 outl(word, PCI_REG(SH7751_PCICONF2));
288
289 /* Set IO and Mem windows to local address
290 * Make PCI and local address the same for easy 1 to 1 mapping
291 * Window0 = map->window0.size @ non-cached area base = SDRAM
292 * Window1 = map->window1.size @ cached area base = SDRAM
293 */
294 word = map->window0.size - 1;
295 outl(word, PCI_REG(SH7751_PCILSR0));
296 word = map->window1.size - 1;
297 outl(word, PCI_REG(SH7751_PCILSR1));
298 /* Set the values on window 0 PCI config registers */
299 word = P2SEGADDR(map->window0.base);
300 outl(word, PCI_REG(SH7751_PCILAR0));
301 outl(word, PCI_REG(SH7751_PCICONF5));
302 /* Set the values on window 1 PCI config registers */
303 word = PHYSADDR(map->window1.base);
304 outl(word, PCI_REG(SH7751_PCILAR1));
305 outl(word, PCI_REG(SH7751_PCICONF6));
306
307 /* Set the local 16MB PCI memory space window to
308 * the lowest PCI mapped address
309 */
310 word = PCIBIOS_MIN_MEM & SH7751_PCIMBR_MASK;
311 PCIDBG(2,"PCI: Setting upper bits of Memory window to 0x%x\n", word);
312 outl(word , PCI_REG(SH7751_PCIMBR));
313
314 /* Map IO space into PCI IO window
315 * The IO window is 64K-PCIBIOS_MIN_IO in size
316 * IO addresses will be translated to the
317 * PCI IO window base address
318 */
319 PCIDBG(3,"PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", PCIBIOS_MIN_IO,
320 (64*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO);
321
322 /*
323 * XXX: For now, leave this board-specific. In the event we have other
324 * boards that need to do similar work, this can be wrapped.
325 */
326#ifdef CONFIG_SH_BIGSUR
327 bigsur_port_map(PCIBIOS_MIN_IO, (64*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO,0);
328#endif
329
330 /* Make sure the MSB's of IO window are set to access PCI space correctly */
331 word = PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK;
332 PCIDBG(2,"PCI: Setting upper bits of IO window to 0x%x\n", word);
333 outl(word, PCI_REG(SH7751_PCIIOBR));
334
335 /* Set PCI WCRx, BCRx's, copy from BSC locations */
336
337 /* check BCR for SDRAM in specified area */
338 switch (map->window0.base) {
339 case SH7751_CS0_BASE_ADDR: word = __area_sdram_check(0); break;
340 case SH7751_CS1_BASE_ADDR: word = __area_sdram_check(1); break;
341 case SH7751_CS2_BASE_ADDR: word = __area_sdram_check(2); break;
342 case SH7751_CS3_BASE_ADDR: word = __area_sdram_check(3); break;
343 case SH7751_CS4_BASE_ADDR: word = __area_sdram_check(4); break;
344 case SH7751_CS5_BASE_ADDR: word = __area_sdram_check(5); break;
345 case SH7751_CS6_BASE_ADDR: word = __area_sdram_check(6); break;
346 }
347
348 if (!word)
349 return 0;
350
351 /* configure the wait control registers */
352 word = inl(SH7751_WCR1);
353 outl(word, PCI_REG(SH7751_PCIWCR1));
354 word = inl(SH7751_WCR2);
355 outl(word, PCI_REG(SH7751_PCIWCR2));
356 word = inl(SH7751_WCR3);
357 outl(word, PCI_REG(SH7751_PCIWCR3));
358 word = inl(SH7751_MCR);
359 outl(word, PCI_REG(SH7751_PCIMCR));
360
361 /* NOTE: I'm ignoring the PCI error IRQs for now..
362 * TODO: add support for the internal error interrupts and
363 * DMA interrupts...
364 */
365
366#ifdef CONFIG_SH_RTS7751R2D
367 pci_fixup_pcic();
368#endif
369
370 /* SH7751 init done, set central function init complete */
371 /* use round robin mode to stop a device starving/overruning */
372 word = SH7751_PCICR_PREFIX | SH7751_PCICR_CFIN | SH7751_PCICR_ARBM;
373 outl(word,PCI_REG(SH7751_PCICR));
374
375 return 1;
376}
377
378char * __init pcibios_setup(char *str)
379{
380 if (!strcmp(str, "off")) {
381 pci_probe = 0;
382 return NULL;
383 }
384
385 return str;
386}
387
388/*
389 * IRQ functions
390 */
391static u8 __init sh7751_no_swizzle(struct pci_dev *dev, u8 *pin)
392{
393 /* no swizzling */
394 return PCI_SLOT(dev->devfn);
395}
396
397static int sh7751_pci_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin)
398{
399 int irq = -1;
400
401 /* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */
402 irq = pcibios_map_platform_irq(slot,pin);
403 if( irq < 0 ) {
404 pr_debug("PCI: Error mapping IRQ on device %s\n", pci_name(dev));
405 return irq;
406 }
407
408 pr_debug("Setting IRQ for slot %s to %d\n", pci_name(dev), irq);
409
410 return irq;
411}
412
413void __init pcibios_fixup_irqs(void)
414{
415 pci_fixup_irqs(sh7751_no_swizzle, sh7751_pci_lookup_irq);
416}
417
diff --git a/arch/sh/drivers/pci/pci-sh7751.h b/arch/sh/drivers/pci/pci-sh7751.h
new file mode 100644
index 000000000000..1fee5cae10d1
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-sh7751.h
@@ -0,0 +1,303 @@
1/*
2 * Low-Level PCI Support for SH7751 targets
3 *
4 * Dustin McIntire (dustin@sensoria.com) (c) 2001
5 * Paul Mundt (lethal@linux-sh.org) (c) 2003
6 *
7 * May be copied or modified under the terms of the GNU General Public
8 * License. See linux/COPYING for more information.
9 *
10 */
11
12#ifndef _PCI_SH7751_H_
13#define _PCI_SH7751_H_
14
15#include <linux/pci.h>
16
17/* set debug level 4=verbose...1=terse */
18//#define DEBUG_PCI 3
19#undef DEBUG_PCI
20
21#ifdef DEBUG_PCI
22#define PCIDBG(n, x...) { if(DEBUG_PCI>=n) printk(x); }
23#else
24#define PCIDBG(n, x...)
25#endif
26
27/* startup values */
28#define PCI_PROBE_BIOS 1
29#define PCI_PROBE_CONF1 2
30#define PCI_PROBE_CONF2 4
31#define PCI_NO_SORT 0x100
32#define PCI_BIOS_SORT 0x200
33#define PCI_NO_CHECKS 0x400
34#define PCI_ASSIGN_ROMS 0x1000
35#define PCI_BIOS_IRQ_SCAN 0x2000
36
37/* Platform Specific Values */
38#define SH7751_VENDOR_ID 0x1054
39#define SH7751_DEVICE_ID 0x3505
40#define SH7751R_DEVICE_ID 0x350e
41
42/* SH7751 Specific Values */
43#define SH7751_PCI_CONFIG_BASE 0xFD000000 /* Config space base addr */
44#define SH7751_PCI_CONFIG_SIZE 0x1000000 /* Config space size */
45#define SH7751_PCI_MEMORY_BASE 0xFD000000 /* Memory space base addr */
46#define SH7751_PCI_MEM_SIZE 0x01000000 /* Size of Memory window */
47#define SH7751_PCI_IO_BASE 0xFE240000 /* IO space base address */
48#define SH7751_PCI_IO_SIZE 0x40000 /* Size of IO window */
49
50#define SH7751_PCIREG_BASE 0xFE200000 /* PCI regs base address */
51#define PCI_REG(n) (SH7751_PCIREG_BASE+ n)
52
53#define SH7751_PCICONF0 0x0 /* PCI Config Reg 0 */
54 #define SH7751_PCICONF0_DEVID 0xFFFF0000 /* Device ID */
55 #define SH7751_PCICONF0_VNDID 0x0000FFFF /* Vendor ID */
56#define SH7751_PCICONF1 0x4 /* PCI Config Reg 1 */
57 #define SH7751_PCICONF1_DPE 0x80000000 /* Data Parity Error */
58 #define SH7751_PCICONF1_SSE 0x40000000 /* System Error Status */
59 #define SH7751_PCICONF1_RMA 0x20000000 /* Master Abort */
60 #define SH7751_PCICONF1_RTA 0x10000000 /* Target Abort Rx Status */
61 #define SH7751_PCICONF1_STA 0x08000000 /* Target Abort Exec Status */
62 #define SH7751_PCICONF1_DEV 0x06000000 /* Timing Status */
63 #define SH7751_PCICONF1_DPD 0x01000000 /* Data Parity Status */
64 #define SH7751_PCICONF1_FBBC 0x00800000 /* Back 2 Back Status */
65 #define SH7751_PCICONF1_UDF 0x00400000 /* User Defined Status */
66 #define SH7751_PCICONF1_66M 0x00200000 /* 66Mhz Operation Status */
67 #define SH7751_PCICONF1_PM 0x00100000 /* Power Management Status */
68 #define SH7751_PCICONF1_PBBE 0x00000200 /* Back 2 Back Control */
69 #define SH7751_PCICONF1_SER 0x00000100 /* SERR Output Control */
70 #define SH7751_PCICONF1_WCC 0x00000080 /* Wait Cycle Control */
71 #define SH7751_PCICONF1_PER 0x00000040 /* Parity Error Response */
72 #define SH7751_PCICONF1_VPS 0x00000020 /* VGA Pallet Snoop */
73 #define SH7751_PCICONF1_MWIE 0x00000010 /* Memory Write+Invalidate */
74 #define SH7751_PCICONF1_SPC 0x00000008 /* Special Cycle Control */
75 #define SH7751_PCICONF1_BUM 0x00000004 /* Bus Master Control */
76 #define SH7751_PCICONF1_MES 0x00000002 /* Memory Space Control */
77 #define SH7751_PCICONF1_IOS 0x00000001 /* I/O Space Control */
78#define SH7751_PCICONF2 0x8 /* PCI Config Reg 2 */
79 #define SH7751_PCICONF2_BCC 0xFF000000 /* Base Class Code */
80 #define SH7751_PCICONF2_SCC 0x00FF0000 /* Sub-Class Code */
81 #define SH7751_PCICONF2_RLPI 0x0000FF00 /* Programming Interface */
82 #define SH7751_PCICONF2_REV 0x000000FF /* Revision ID */
83#define SH7751_PCICONF3 0xC /* PCI Config Reg 3 */
84 #define SH7751_PCICONF3_BIST7 0x80000000 /* Bist Supported */
85 #define SH7751_PCICONF3_BIST6 0x40000000 /* Bist Executing */
86 #define SH7751_PCICONF3_BIST3_0 0x0F000000 /* Bist Passed */
87 #define SH7751_PCICONF3_HD7 0x00800000 /* Single Funtion device */
88 #define SH7751_PCICONF3_HD6_0 0x007F0000 /* Configuration Layout */
89 #define SH7751_PCICONF3_LAT 0x0000FF00 /* Latency Timer */
90 #define SH7751_PCICONF3_CLS 0x000000FF /* Cache Line Size */
91#define SH7751_PCICONF4 0x10 /* PCI Config Reg 4 */
92 #define SH7751_PCICONF4_BASE 0xFFFFFFFC /* I/O Space Base Addr */
93 #define SH7751_PCICONF4_ASI 0x00000001 /* Address Space Type */
94#define SH7751_PCICONF5 0x14 /* PCI Config Reg 5 */
95 #define SH7751_PCICONF5_BASE 0xFFFFFFF0 /* Mem Space Base Addr */
96 #define SH7751_PCICONF5_LAP 0x00000008 /* Prefetch Enabled */
97 #define SH7751_PCICONF5_LAT 0x00000006 /* Local Memory type */
98 #define SH7751_PCICONF5_ASI 0x00000001 /* Address Space Type */
99#define SH7751_PCICONF6 0x18 /* PCI Config Reg 6 */
100 #define SH7751_PCICONF6_BASE 0xFFFFFFF0 /* Mem Space Base Addr */
101 #define SH7751_PCICONF6_LAP 0x00000008 /* Prefetch Enabled */
102 #define SH7751_PCICONF6_LAT 0x00000006 /* Local Memory type */
103 #define SH7751_PCICONF6_ASI 0x00000001 /* Address Space Type */
104/* PCICONF7 - PCICONF10 are undefined */
105#define SH7751_PCICONF11 0x2C /* PCI Config Reg 11 */
106 #define SH7751_PCICONF11_SSID 0xFFFF0000 /* Subsystem ID */
107 #define SH7751_PCICONF11_SVID 0x0000FFFF /* Subsystem Vendor ID */
108/* PCICONF12 is undefined */
109#define SH7751_PCICONF13 0x34 /* PCI Config Reg 13 */
110 #define SH7751_PCICONF13_CPTR 0x000000FF /* PM function pointer */
111/* PCICONF14 is undefined */
112#define SH7751_PCICONF15 0x3C /* PCI Config Reg 15 */
113 #define SH7751_PCICONF15_IPIN 0x000000FF /* Interrupt Pin */
114#define SH7751_PCICONF16 0x40 /* PCI Config Reg 16 */
115 #define SH7751_PCICONF16_PMES 0xF8000000 /* PME Support */
116 #define SH7751_PCICONF16_D2S 0x04000000 /* D2 Support */
117 #define SH7751_PCICONF16_D1S 0x02000000 /* D1 Support */
118 #define SH7751_PCICONF16_DSI 0x00200000 /* Bit Device Init. */
119 #define SH7751_PCICONF16_PMCK 0x00080000 /* Clock for PME req. */
120 #define SH7751_PCICONF16_VER 0x00070000 /* PM Version */
121 #define SH7751_PCICONF16_NIP 0x0000FF00 /* Next Item Pointer */
122 #define SH7751_PCICONF16_CID 0x000000FF /* Capability Identifier */
123#define SH7751_PCICONF17 0x44 /* PCI Config Reg 17 */
124 #define SH7751_PCICONF17_DATA 0xFF000000 /* Data field for PM */
125 #define SH7751_PCICONF17_PMES 0x00800000 /* PME Status */
126 #define SH7751_PCICONF17_DSCL 0x00600000 /* Data Scaling Value */
127 #define SH7751_PCICONF17_DSEL 0x001E0000 /* Data Select */
128 #define SH7751_PCICONF17_PMEN 0x00010000 /* PME Enable */
129 #define SH7751_PCICONF17_PWST 0x00000003 /* Power State */
130/* SH7715 Internal PCI Registers */
131#define SH7751_PCICR 0x100 /* PCI Control Register */
132 #define SH7751_PCICR_PREFIX 0xA5000000 /* CR prefix for write */
133 #define SH7751_PCICR_TRSB 0x00000200 /* Target Read Single */
134 #define SH7751_PCICR_BSWP 0x00000100 /* Target Byte Swap */
135 #define SH7751_PCICR_PLUP 0x00000080 /* Enable PCI Pullup */
136 #define SH7751_PCICR_ARBM 0x00000040 /* PCI Arbitration Mode */
137 #define SH7751_PCICR_MD 0x00000030 /* MD9 and MD10 status */
138 #define SH7751_PCICR_SERR 0x00000008 /* SERR output assert */
139 #define SH7751_PCICR_INTA 0x00000004 /* INTA output assert */
140 #define SH7751_PCICR_PRST 0x00000002 /* PCI Reset Assert */
141 #define SH7751_PCICR_CFIN 0x00000001 /* Central Fun. Init Done */
142#define SH7751_PCILSR0 0x104 /* PCI Local Space Register0 */
143#define SH7751_PCILSR1 0x108 /* PCI Local Space Register1 */
144#define SH7751_PCILAR0 0x10C /* PCI Local Address Register1 */
145#define SH7751_PCILAR1 0x110 /* PCI Local Address Register1 */
146#define SH7751_PCIINT 0x114 /* PCI Interrupt Register */
147 #define SH7751_PCIINT_MLCK 0x00008000 /* Master Lock Error */
148 #define SH7751_PCIINT_TABT 0x00004000 /* Target Abort Error */
149 #define SH7751_PCIINT_TRET 0x00000200 /* Target Retry Error */
150 #define SH7751_PCIINT_MFDE 0x00000100 /* Master Func. Disable Error */
151 #define SH7751_PCIINT_PRTY 0x00000080 /* Address Parity Error */
152 #define SH7751_PCIINT_SERR 0x00000040 /* SERR Detection Error */
153 #define SH7751_PCIINT_TWDP 0x00000020 /* Tgt. Write Parity Error */
154 #define SH7751_PCIINT_TRDP 0x00000010 /* Tgt. Read Parity Error Det. */
155 #define SH7751_PCIINT_MTABT 0x00000008 /* Master-Tgt. Abort Error */
156 #define SH7751_PCIINT_MMABT 0x00000004 /* Master-Master Abort Error */
157 #define SH7751_PCIINT_MWPD 0x00000002 /* Master Write PERR Detect */
158 #define SH7751_PCIINT_MRPD 0x00000002 /* Master Read PERR Detect */
159#define SH7751_PCIINTM 0x118 /* PCI Interrupt Mask Register */
160#define SH7751_PCIALR 0x11C /* Error Address Register */
161#define SH7751_PCICLR 0x120 /* Error Command/Data Register */
162 #define SH7751_PCICLR_MPIO 0x80000000 /* Error Command/Data Register */
163 #define SH7751_PCICLR_MDMA0 0x40000000 /* DMA0 Transfer Error */
164 #define SH7751_PCICLR_MDMA1 0x20000000 /* DMA1 Transfer Error */
165 #define SH7751_PCICLR_MDMA2 0x10000000 /* DMA2 Transfer Error */
166 #define SH7751_PCICLR_MDMA3 0x08000000 /* DMA3 Transfer Error */
167 #define SH7751_PCICLR_TGT 0x04000000 /* Target Transfer Error */
168 #define SH7751_PCICLR_CMDL 0x0000000F /* PCI Command at Error */
169#define SH7751_PCIAINT 0x130 /* Arbiter Interrupt Register */
170 #define SH7751_PCIAINT_MBKN 0x00002000 /* Master Broken Interrupt */
171 #define SH7751_PCIAINT_TBTO 0x00001000 /* Target Bus Time Out */
172 #define SH7751_PCIAINT_MBTO 0x00001000 /* Master Bus Time Out */
173 #define SH7751_PCIAINT_TABT 0x00000008 /* Target Abort */
174 #define SH7751_PCIAINT_MABT 0x00000004 /* Master Abort */
175 #define SH7751_PCIAINT_RDPE 0x00000002 /* Read Data Parity Error */
176 #define SH7751_PCIAINT_WDPE 0x00000002 /* Write Data Parity Error */
177#define SH7751_PCIAINTM 0x134 /* Arbiter Int. Mask Register */
178#define SH7751_PCIBMLR 0x138 /* Error Bus Master Register */
179 #define SH7751_PCIBMLR_REQ4 0x00000010 /* REQ4 bus master at error */
180 #define SH7751_PCIBMLR_REQ3 0x00000008 /* REQ3 bus master at error */
181 #define SH7751_PCIBMLR_REQ2 0x00000004 /* REQ2 bus master at error */
182 #define SH7751_PCIBMLR_REQ1 0x00000002 /* REQ1 bus master at error */
183 #define SH7751_PCIBMLR_REQ0 0x00000001 /* REQ0 bus master at error */
184#define SH7751_PCIDMABT 0x140 /* DMA Transfer Arb. Register */
185 #define SH7751_PCIDMABT_RRBN 0x00000001 /* DMA Arbitor Round-Robin */
186#define SH7751_PCIDPA0 0x180 /* DMA0 Transfer Addr. Register */
187#define SH7751_PCIDLA0 0x184 /* DMA0 Local Addr. Register */
188#define SH7751_PCIDTC0 0x188 /* DMA0 Transfer Cnt. Register */
189#define SH7751_PCIDCR0 0x18C /* DMA0 Control Register */
190 #define SH7751_PCIDCR_ALGN 0x00000600 /* DMA Alignment Mode */
191 #define SH7751_PCIDCR_MAST 0x00000100 /* DMA Termination Type */
192 #define SH7751_PCIDCR_INTM 0x00000080 /* DMA Interrupt Done Mask*/
193 #define SH7751_PCIDCR_INTS 0x00000040 /* DMA Interrupt Done Status */
194 #define SH7751_PCIDCR_LHLD 0x00000020 /* Local Address Control */
195 #define SH7751_PCIDCR_PHLD 0x00000010 /* PCI Address Control*/
196 #define SH7751_PCIDCR_IOSEL 0x00000008 /* PCI Address Space Type */
197 #define SH7751_PCIDCR_DIR 0x00000004 /* DMA Transfer Direction */
198 #define SH7751_PCIDCR_STOP 0x00000002 /* Force DMA Stop */
199 #define SH7751_PCIDCR_STRT 0x00000001 /* DMA Start */
200#define SH7751_PCIDPA1 0x190 /* DMA1 Transfer Addr. Register */
201#define SH7751_PCIDLA1 0x194 /* DMA1 Local Addr. Register */
202#define SH7751_PCIDTC1 0x198 /* DMA1 Transfer Cnt. Register */
203#define SH7751_PCIDCR1 0x19C /* DMA1 Control Register */
204#define SH7751_PCIDPA2 0x1A0 /* DMA2 Transfer Addr. Register */
205#define SH7751_PCIDLA2 0x1A4 /* DMA2 Local Addr. Register */
206#define SH7751_PCIDTC2 0x1A8 /* DMA2 Transfer Cnt. Register */
207#define SH7751_PCIDCR2 0x1AC /* DMA2 Control Register */
208#define SH7751_PCIDPA3 0x1B0 /* DMA3 Transfer Addr. Register */
209#define SH7751_PCIDLA3 0x1B4 /* DMA3 Local Addr. Register */
210#define SH7751_PCIDTC3 0x1B8 /* DMA3 Transfer Cnt. Register */
211#define SH7751_PCIDCR3 0x1BC /* DMA3 Control Register */
212#define SH7751_PCIPAR 0x1C0 /* PIO Address Register */
213 #define SH7751_PCIPAR_CFGEN 0x80000000 /* Configuration Enable */
214 #define SH7751_PCIPAR_BUSNO 0x00FF0000 /* Config. Bus Number */
215 #define SH7751_PCIPAR_DEVNO 0x0000FF00 /* Config. Device Number */
216 #define SH7751_PCIPAR_REGAD 0x000000FC /* Register Address Number */
217#define SH7751_PCIMBR 0x1C4 /* Memory Base Address Register */
218 #define SH7751_PCIMBR_MASK 0xFF000000 /* Memory Space Mask */
219 #define SH7751_PCIMBR_LOCK 0x00000001 /* Lock Memory Space */
220#define SH7751_PCIIOBR 0x1C8 /* I/O Base Address Register */
221 #define SH7751_PCIIOBR_MASK 0xFFFC0000 /* IO Space Mask */
222 #define SH7751_PCIIOBR_LOCK 0x00000001 /* Lock IO Space */
223#define SH7751_PCIPINT 0x1CC /* Power Mgmnt Int. Register */
224 #define SH7751_PCIPINT_D3 0x00000002 /* D3 Pwr Mgmt. Interrupt */
225 #define SH7751_PCIPINT_D0 0x00000001 /* D0 Pwr Mgmt. Interrupt */
226#define SH7751_PCIPINTM 0x1D0 /* Power Mgmnt Mask Register */
227#define SH7751_PCICLKR 0x1D4 /* Clock Ctrl. Register */
228 #define SH7751_PCICLKR_PCSTP 0x00000002 /* PCI Clock Stop */
229 #define SH7751_PCICLKR_BCSTP 0x00000002 /* BCLK Clock Stop */
230/* For definitions of BCR, MCR see ... */
231#define SH7751_PCIBCR1 0x1E0 /* Memory BCR1 Register */
232#define SH7751_PCIBCR2 0x1E4 /* Memory BCR2 Register */
233#define SH7751_PCIWCR1 0x1E8 /* Wait Control 1 Register */
234#define SH7751_PCIWCR2 0x1EC /* Wait Control 2 Register */
235#define SH7751_PCIWCR3 0x1F0 /* Wait Control 3 Register */
236#define SH7751_PCIMCR 0x1F4 /* Memory Control Register */
237#define SH7751_PCIBCR3 0x1f8 /* Memory BCR3 Register */
238#define SH7751_PCIPCTR 0x200 /* Port Control Register */
239 #define SH7751_PCIPCTR_P2EN 0x000400000 /* Port 2 Enable */
240 #define SH7751_PCIPCTR_P1EN 0x000200000 /* Port 1 Enable */
241 #define SH7751_PCIPCTR_P0EN 0x000100000 /* Port 0 Enable */
242 #define SH7751_PCIPCTR_P2UP 0x000000020 /* Port2 Pull Up Enable */
243 #define SH7751_PCIPCTR_P2IO 0x000000010 /* Port2 Output Enable */
244 #define SH7751_PCIPCTR_P1UP 0x000000008 /* Port1 Pull Up Enable */
245 #define SH7751_PCIPCTR_P1IO 0x000000004 /* Port1 Output Enable */
246 #define SH7751_PCIPCTR_P0UP 0x000000002 /* Port0 Pull Up Enable */
247 #define SH7751_PCIPCTR_P0IO 0x000000001 /* Port0 Output Enable */
248#define SH7751_PCIPDTR 0x204 /* Port Data Register */
249 #define SH7751_PCIPDTR_PB5 0x000000020 /* Port 5 Enable */
250 #define SH7751_PCIPDTR_PB4 0x000000010 /* Port 4 Enable */
251 #define SH7751_PCIPDTR_PB3 0x000000008 /* Port 3 Enable */
252 #define SH7751_PCIPDTR_PB2 0x000000004 /* Port 2 Enable */
253 #define SH7751_PCIPDTR_PB1 0x000000002 /* Port 1 Enable */
254 #define SH7751_PCIPDTR_PB0 0x000000001 /* Port 0 Enable */
255#define SH7751_PCIPDR 0x220 /* Port IO Data Register */
256
257/* Memory Control Registers */
258#define SH7751_BCR1 0xFF800000 /* Memory BCR1 Register */
259#define SH7751_BCR2 0xFF800004 /* Memory BCR2 Register */
260#define SH7751_BCR3 0xFF800050 /* Memory BCR3 Register */
261#define SH7751_BCR4 0xFE0A00F0 /* Memory BCR4 Register */
262#define SH7751_WCR1 0xFF800008 /* Wait Control 1 Register */
263#define SH7751_WCR2 0xFF80000C /* Wait Control 2 Register */
264#define SH7751_WCR3 0xFF800010 /* Wait Control 3 Register */
265#define SH7751_MCR 0xFF800014 /* Memory Control Register */
266
267/* General Memory Config Addresses */
268#define SH7751_CS0_BASE_ADDR 0x0
269#define SH7751_MEM_REGION_SIZE 0x04000000
270#define SH7751_CS1_BASE_ADDR (SH7751_CS0_BASE_ADDR + SH7751_MEM_REGION_SIZE)
271#define SH7751_CS2_BASE_ADDR (SH7751_CS1_BASE_ADDR + SH7751_MEM_REGION_SIZE)
272#define SH7751_CS3_BASE_ADDR (SH7751_CS2_BASE_ADDR + SH7751_MEM_REGION_SIZE)
273#define SH7751_CS4_BASE_ADDR (SH7751_CS3_BASE_ADDR + SH7751_MEM_REGION_SIZE)
274#define SH7751_CS5_BASE_ADDR (SH7751_CS4_BASE_ADDR + SH7751_MEM_REGION_SIZE)
275#define SH7751_CS6_BASE_ADDR (SH7751_CS5_BASE_ADDR + SH7751_MEM_REGION_SIZE)
276
277/* General PCI values */
278#define SH7751_PCI_HOST_BRIDGE 0x6
279
280/* Flags */
281#define SH7751_PCIC_NO_RESET 0x0001
282
283/* External functions defined per platform i.e. Big Sur, SE... (these could be routed
284 * through the machine vectors... */
285extern int pcibios_init_platform(void);
286extern int pcibios_map_platform_irq(u8 slot, u8 pin);
287
288struct sh7751_pci_address_space {
289 unsigned long base;
290 unsigned long size;
291};
292
293struct sh7751_pci_address_map {
294 struct sh7751_pci_address_space window0;
295 struct sh7751_pci_address_space window1;
296 unsigned long flags;
297};
298
299/* arch/sh/drivers/pci/pci-sh7751.c */
300extern int sh7751_pcic_init(struct sh7751_pci_address_map *map);
301
302#endif /* _PCI_SH7751_H_ */
303
diff --git a/arch/sh/drivers/pci/pci-st40.c b/arch/sh/drivers/pci/pci-st40.c
new file mode 100644
index 000000000000..cb6752131156
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-st40.c
@@ -0,0 +1,509 @@
1/*
2 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * Support functions for the ST40 PCI hardware.
8 */
9
10#include <linux/config.h>
11#include <linux/kernel.h>
12#include <linux/smp.h>
13#include <linux/smp_lock.h>
14#include <linux/init.h>
15#include <linux/errno.h>
16#include <linux/pci.h>
17#include <linux/delay.h>
18#include <linux/types.h>
19#include <asm/pci.h>
20#include <linux/irq.h>
21#include <linux/interrupt.h> /* irqreturn_t */
22
23#include "pci-st40.h"
24
25/* This is in P2 of course */
26#define ST40PCI_BASE_ADDRESS (0xb0000000)
27#define ST40PCI_MEM_ADDRESS (ST40PCI_BASE_ADDRESS+0x0)
28#define ST40PCI_IO_ADDRESS (ST40PCI_BASE_ADDRESS+0x06000000)
29#define ST40PCI_REG_ADDRESS (ST40PCI_BASE_ADDRESS+0x07000000)
30
31#define ST40PCI_REG(x) (ST40PCI_REG_ADDRESS+(ST40PCI_##x))
32#define ST40PCI_REG_INDEXED(reg, index) \
33 (ST40PCI_REG(reg##0) + \
34 ((ST40PCI_REG(reg##1) - ST40PCI_REG(reg##0))*index))
35
36#define ST40PCI_WRITE(reg,val) writel((val),ST40PCI_REG(reg))
37#define ST40PCI_WRITE_SHORT(reg,val) writew((val),ST40PCI_REG(reg))
38#define ST40PCI_WRITE_BYTE(reg,val) writeb((val),ST40PCI_REG(reg))
39#define ST40PCI_WRITE_INDEXED(reg, index, val) \
40 writel((val), ST40PCI_REG_INDEXED(reg, index));
41
42#define ST40PCI_READ(reg) readl(ST40PCI_REG(reg))
43#define ST40PCI_READ_SHORT(reg) readw(ST40PCI_REG(reg))
44#define ST40PCI_READ_BYTE(reg) readb(ST40PCI_REG(reg))
45
46#define ST40PCI_SERR_IRQ 64
47#define ST40PCI_ERR_IRQ 65
48
49
50/* Macros to extract PLL params */
51#define PLL_MDIV(reg) ( ((unsigned)reg) & 0xff )
52#define PLL_NDIV(reg) ( (((unsigned)reg)>>8) & 0xff )
53#define PLL_PDIV(reg) ( (((unsigned)reg)>>16) & 0x3 )
54#define PLL_SETUP(reg) ( (((unsigned)reg)>>19) & 0x1ff )
55
56/* Build up the appropriate settings */
57#define PLL_SET(mdiv,ndiv,pdiv,setup) \
58( ((mdiv)&0xff) | (((ndiv)&0xff)<<8) | (((pdiv)&3)<<16)| (((setup)&0x1ff)<<19))
59
60#define PLLPCICR (0xbb040000+0x10)
61
62#define PLLPCICR_POWERON (1<<28)
63#define PLLPCICR_OUT_EN (1<<29)
64#define PLLPCICR_LOCKSELECT (1<<30)
65#define PLLPCICR_LOCK (1<<31)
66
67
68#define PLL_25MHZ 0x793c8512
69#define PLL_33MHZ PLL_SET(18,88,3,295)
70
71static void pci_set_rbar_region(unsigned int region, unsigned long localAddr,
72 unsigned long pciOffset, unsigned long regionSize);
73
74/*
75 * The pcibios_map_platform_irq function is defined in the appropriate
76 * board specific code and referenced here
77 */
78extern int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin);
79
80static __init void SetPCIPLL(void)
81{
82 {
83 /* Lets play with the PLL values */
84 unsigned long pll1cr1;
85 unsigned long mdiv, ndiv, pdiv;
86 unsigned long muxcr;
87 unsigned int muxcr_ratios[4] = { 8, 16, 21, 1 };
88 unsigned int freq;
89
90#define CLKGENA 0xbb040000
91#define CLKGENA_PLL2_MUXCR CLKGENA + 0x48
92 pll1cr1 = ctrl_inl(PLLPCICR);
93 printk("PLL1CR1 %08lx\n", pll1cr1);
94 mdiv = PLL_MDIV(pll1cr1);
95 ndiv = PLL_NDIV(pll1cr1);
96 pdiv = PLL_PDIV(pll1cr1);
97 printk("mdiv %02lx ndiv %02lx pdiv %02lx\n", mdiv, ndiv, pdiv);
98 freq = ((2*27*ndiv)/mdiv) / (1 << pdiv);
99 printk("PLL freq %dMHz\n", freq);
100 muxcr = ctrl_inl(CLKGENA_PLL2_MUXCR);
101 printk("PCI freq %dMhz\n", freq / muxcr_ratios[muxcr & 3]);
102 }
103}
104
105
106struct pci_err {
107 unsigned mask;
108 const char *error_string;
109};
110
111static struct pci_err int_error[]={
112 { INT_MNLTDIM,"MNLTDIM: Master non-lock transfer"},
113 { INT_TTADI, "TTADI: Illegal byte enable in I/O transfer"},
114 { INT_TMTO, "TMTO: Target memory read/write timeout"},
115 { INT_MDEI, "MDEI: Master function disable error"},
116 { INT_APEDI, "APEDI: Address parity error"},
117 { INT_SDI, "SDI: SERR detected"},
118 { INT_DPEITW, "DPEITW: Data parity error target write"},
119 { INT_PEDITR, "PEDITR: PERR detected"},
120 { INT_TADIM, "TADIM: Target abort detected"},
121 { INT_MADIM, "MADIM: Master abort detected"},
122 { INT_MWPDI, "MWPDI: PERR from target at data write"},
123 { INT_MRDPEI, "MRDPEI: Master read data parity error"}
124};
125#define NUM_PCI_INT_ERRS (sizeof(int_error)/sizeof(struct pci_err))
126
127static struct pci_err aint_error[]={
128 { AINT_MBI, "MBI: Master broken"},
129 { AINT_TBTOI, "TBTOI: Target bus timeout"},
130 { AINT_MBTOI, "MBTOI: Master bus timeout"},
131 { AINT_TAI, "TAI: Target abort"},
132 { AINT_MAI, "MAI: Master abort"},
133 { AINT_RDPEI, "RDPEI: Read data parity"},
134 { AINT_WDPE, "WDPE: Write data parity"}
135};
136
137#define NUM_PCI_AINT_ERRS (sizeof(aint_error)/sizeof(struct pci_err))
138
139static void print_pci_errors(unsigned reg,struct pci_err *error,int num_errors)
140{
141 int i;
142
143 for(i=0;i<num_errors;i++) {
144 if(reg & error[i].mask) {
145 printk("%s\n",error[i].error_string);
146 }
147 }
148
149}
150
151
152static char * pci_commands[16]={
153 "Int Ack",
154 "Special Cycle",
155 "I/O Read",
156 "I/O Write",
157 "Reserved",
158 "Reserved",
159 "Memory Read",
160 "Memory Write",
161 "Reserved",
162 "Reserved",
163 "Configuration Read",
164 "Configuration Write",
165 "Memory Read Multiple",
166 "Dual Address Cycle",
167 "Memory Read Line",
168 "Memory Write-and-Invalidate"
169};
170
171static irqreturn_t st40_pci_irq(int irq, void *dev_instance, struct pt_regs *regs)
172{
173 unsigned pci_int, pci_air, pci_cir, pci_aint;
174 static int count=0;
175
176
177 pci_int = ST40PCI_READ(INT);pci_aint = ST40PCI_READ(AINT);
178 pci_cir = ST40PCI_READ(CIR);pci_air = ST40PCI_READ(AIR);
179
180 /* Reset state to stop multiple interrupts */
181 ST40PCI_WRITE(INT, ~0); ST40PCI_WRITE(AINT, ~0);
182
183
184 if(++count>1) return IRQ_HANDLED;
185
186 printk("** PCI ERROR **\n");
187
188 if(pci_int) {
189 printk("** INT register status\n");
190 print_pci_errors(pci_int,int_error,NUM_PCI_INT_ERRS);
191 }
192
193 if(pci_aint) {
194 printk("** AINT register status\n");
195 print_pci_errors(pci_aint,aint_error,NUM_PCI_AINT_ERRS);
196 }
197
198 printk("** Address and command info\n");
199
200 printk("** Command %s : Address 0x%x\n",
201 pci_commands[pci_cir&0xf],pci_air);
202
203 if(pci_cir&CIR_PIOTEM) {
204 printk("CIR_PIOTEM:PIO transfer error for master\n");
205 }
206 if(pci_cir&CIR_RWTET) {
207 printk("CIR_RWTET:Read/Write transfer error for target\n");
208 }
209
210 return IRQ_HANDLED;
211}
212
213
214/* Rounds a number UP to the nearest power of two. Used for
215 * sizing the PCI window.
216 */
217static u32 r2p2(u32 num)
218{
219 int i = 31;
220 u32 tmp = num;
221
222 if (num == 0)
223 return 0;
224
225 do {
226 if (tmp & (1 << 31))
227 break;
228 i--;
229 tmp <<= 1;
230 } while (i >= 0);
231
232 tmp = 1 << i;
233 /* If the original number isn't a power of 2, round it up */
234 if (tmp != num)
235 tmp <<= 1;
236
237 return tmp;
238}
239
240static void __init pci_fixup_ide_bases(struct pci_dev *d)
241{
242 int i;
243
244 /*
245 * PCI IDE controllers use non-standard I/O port decoding, respect it.
246 */
247 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
248 return;
249 printk("PCI: IDE base address fixup for %s\n", pci_name(d));
250 for(i=0; i<4; i++) {
251 struct resource *r = &d->resource[i];
252 if ((r->start & ~0x80) == 0x374) {
253 r->start |= 2;
254 r->end = r->start;
255 }
256 }
257}
258DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
259
260int __init st40pci_init(unsigned memStart, unsigned memSize)
261{
262 u32 lsr0;
263
264 SetPCIPLL();
265
266 /* Initialises the ST40 pci subsystem, performing a reset, then programming
267 * up the address space decoders appropriately
268 */
269
270 /* Should reset core here as well methink */
271
272 ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_SOFT_RESET);
273
274 /* Loop while core resets */
275 while (ST40PCI_READ(CR) & CR_SOFT_RESET);
276
277 /* Switch off interrupts */
278 ST40PCI_WRITE(INTM, 0);
279 ST40PCI_WRITE(AINT, 0);
280
281 /* Now, lets reset all the cards on the bus with extreme prejudice */
282 ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_RSTCTL);
283 udelay(250);
284
285 /* Set bus active, take it out of reset */
286 ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_BMAM | CR_CFINT | CR_PFCS | CR_PFE);
287
288 /* The PCI spec says that no access must be made to the bus until 1 second
289 * after reset. This seem ludicrously long, but some delay is needed here
290 */
291 mdelay(1000);
292
293 /* Switch off interrupts */
294 ST40PCI_WRITE(INTM, 0);
295 ST40PCI_WRITE(AINT, 0);
296
297 /* Allow it to be a master */
298
299 ST40PCI_WRITE_SHORT(CSR_CMD,
300 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
301 PCI_COMMAND_IO);
302
303 /* Accesse to the 0xb0000000 -> 0xb6000000 area will go through to 0x10000000 -> 0x16000000
304 * on the PCI bus. This allows a nice 1-1 bus to phys mapping.
305 */
306
307
308 ST40PCI_WRITE(MBR, 0x10000000);
309 /* Always set the max size 128M (actually, it is only 96MB wide) */
310 ST40PCI_WRITE(MBMR, 0x07ff0000);
311
312 /* I/O addresses are mapped at 0xb6000000 -> 0xb7000000. These are changed to 0, to
313 * allow cards that have legacy io such as vga to function correctly. This gives a
314 * maximum of 64K of io/space as only the bottom 16 bits of the address are copied
315 * over to the bus when the transaction is made. 64K of io space is more than enough
316 */
317 ST40PCI_WRITE(IOBR, 0x0);
318 /* Set up the 64K window */
319 ST40PCI_WRITE(IOBMR, 0x0);
320
321 /* Now we set up the mbars so the PCI bus can see the local memory */
322 /* Expose a 256M window starting at PCI address 0... */
323 ST40PCI_WRITE(CSR_MBAR0, 0);
324 ST40PCI_WRITE(LSR0, 0x0fff0001);
325
326 /* ... and set up the initial incomming window to expose all of RAM */
327 pci_set_rbar_region(7, memStart, memStart, memSize);
328
329 /* Maximise timeout values */
330 ST40PCI_WRITE_BYTE(CSR_TRDY, 0xff);
331 ST40PCI_WRITE_BYTE(CSR_RETRY, 0xff);
332 ST40PCI_WRITE_BYTE(CSR_MIT, 0xff);
333
334 ST40PCI_WRITE_BYTE(PERF,PERF_MASTER_WRITE_POSTING);
335
336 return 1;
337}
338
339char * __init pcibios_setup(char *str)
340{
341 return str;
342}
343
344
345#define SET_CONFIG_BITS(bus,devfn,where)\
346 (((bus) << 16) | ((devfn) << 8) | ((where) & ~3) | (bus!=0))
347
348#define CONFIG_CMD(bus, devfn, where) SET_CONFIG_BITS(bus->number,devfn,where)
349
350
351static int CheckForMasterAbort(void)
352{
353 if (ST40PCI_READ(INT) & INT_MADIM) {
354 /* Should we clear config space version as well ??? */
355 ST40PCI_WRITE(INT, INT_MADIM);
356 ST40PCI_WRITE_SHORT(CSR_STATUS, 0);
357 return 1;
358 }
359
360 return 0;
361}
362
363/* Write to config register */
364static int st40pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
365{
366 ST40PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
367 switch (size) {
368 case 1:
369 *val = (u8)ST40PCI_READ_BYTE(PDR + (where & 3));
370 break;
371 case 2:
372 *val = (u16)ST40PCI_READ_SHORT(PDR + (where & 2));
373 break;
374 case 4:
375 *val = ST40PCI_READ(PDR);
376 break;
377 }
378
379 if (CheckForMasterAbort()){
380 switch (size) {
381 case 1:
382 *val = (u8)0xff;
383 break;
384 case 2:
385 *val = (u16)0xffff;
386 break;
387 case 4:
388 *val = 0xffffffff;
389 break;
390 }
391 }
392
393 return PCIBIOS_SUCCESSFUL;
394}
395
396static int st40pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
397{
398 ST40PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
399
400 switch (size) {
401 case 1:
402 ST40PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
403 break;
404 case 2:
405 ST40PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
406 break;
407 case 4:
408 ST40PCI_WRITE(PDR, val);
409 break;
410 }
411
412 CheckForMasterAbort();
413
414 return PCIBIOS_SUCCESSFUL;
415}
416
417struct pci_ops st40pci_config_ops = {
418 .read = st40pci_read,
419 .write = st40pci_write,
420};
421
422
423/* Everything hangs off this */
424static struct pci_bus *pci_root_bus;
425
426
427static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
428{
429 return PCI_SLOT(dev->devfn);
430}
431
432
433static int __init pcibios_init(void)
434{
435 extern unsigned long memory_start, memory_end;
436
437 printk(KERN_ALERT "pci-st40.c: pcibios_init\n");
438
439 if (sh_mv.mv_init_pci != NULL) {
440 sh_mv.mv_init_pci();
441 }
442
443 /* The pci subsytem needs to know where memory is and how much
444 * of it there is. I've simply made these globals. A better mechanism
445 * is probably needed.
446 */
447 st40pci_init(PHYSADDR(memory_start),
448 PHYSADDR(memory_end) - PHYSADDR(memory_start));
449
450 if (request_irq(ST40PCI_ERR_IRQ, st40_pci_irq,
451 SA_INTERRUPT, "st40pci", NULL)) {
452 printk(KERN_ERR "st40pci: Cannot hook interrupt\n");
453 return -EIO;
454 }
455
456 /* Enable the PCI interrupts on the device */
457 ST40PCI_WRITE(INTM, ~0);
458 ST40PCI_WRITE(AINT, ~0);
459
460 /* Map the io address apprioately */
461#ifdef CONFIG_HD64465
462 hd64465_port_map(PCIBIOS_MIN_IO, (64 * 1024) - PCIBIOS_MIN_IO + 1,
463 ST40_IO_ADDR + PCIBIOS_MIN_IO, 0);
464#endif
465
466 /* ok, do the scan man */
467 pci_root_bus = pci_scan_bus(0, &st40pci_config_ops, NULL);
468 pci_assign_unassigned_resources();
469 pci_fixup_irqs(no_swizzle, pcibios_map_platform_irq);
470
471 return 0;
472}
473
474subsys_initcall(pcibios_init);
475
476void __init pcibios_fixup_bus(struct pci_bus *bus)
477{
478}
479
480/*
481 * Publish a region of local address space over the PCI bus
482 * to other devices.
483 */
484static void pci_set_rbar_region(unsigned int region, unsigned long localAddr,
485 unsigned long pciOffset, unsigned long regionSize)
486{
487 unsigned long mask;
488
489 if (region > 7)
490 return;
491
492 if (regionSize > (512 * 1024 * 1024))
493 return;
494
495 mask = r2p2(regionSize) - 0x10000;
496
497 /* Diable the region (in case currently in use, should never happen) */
498 ST40PCI_WRITE_INDEXED(RSR, region, 0);
499
500 /* Start of local address space to publish */
501 ST40PCI_WRITE_INDEXED(RLAR, region, PHYSADDR(localAddr) );
502
503 /* Start of region in PCI address space as an offset from MBAR0 */
504 ST40PCI_WRITE_INDEXED(RBAR, region, pciOffset);
505
506 /* Size of region */
507 ST40PCI_WRITE_INDEXED(RSR, region, mask | 1);
508}
509
diff --git a/arch/sh/drivers/pci/pci-st40.h b/arch/sh/drivers/pci/pci-st40.h
new file mode 100644
index 000000000000..d729e0c2d5fe
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-st40.h
@@ -0,0 +1,136 @@
1/*
2 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * Defintions for the ST40 PCI hardware.
8 */
9
10#ifndef __PCI_ST40_H__
11#define __PCI_ST40_H__
12
13#define ST40PCI_VCR_STATUS 0x00
14
15#define ST40PCI_VCR_VERSION 0x08
16
17#define ST40PCI_CR 0x10
18
19#define CR_SOFT_RESET (1<<12)
20#define CR_PFCS (1<<11)
21#define CR_PFE (1<<9)
22#define CR_BMAM (1<<6)
23#define CR_HOST (1<<5)
24#define CR_CLKEN (1<<4)
25#define CR_SOCS (1<<3)
26#define CR_IOCS (1<<2)
27#define CR_RSTCTL (1<<1)
28#define CR_CFINT (1<<0)
29#define CR_LOCK_MASK 0x5a000000
30
31
32#define ST40PCI_LSR0 0X14
33#define ST40PCI_LAR0 0x1c
34
35#define ST40PCI_INT 0x24
36#define INT_MNLTDIM (1<<15)
37#define INT_TTADI (1<<14)
38#define INT_TMTO (1<<9)
39#define INT_MDEI (1<<8)
40#define INT_APEDI (1<<7)
41#define INT_SDI (1<<6)
42#define INT_DPEITW (1<<5)
43#define INT_PEDITR (1<<4)
44#define INT_TADIM (1<<3)
45#define INT_MADIM (1<<2)
46#define INT_MWPDI (1<<1)
47#define INT_MRDPEI (1<<0)
48
49
50#define ST40PCI_INTM 0x28
51#define ST40PCI_AIR 0x2c
52
53#define ST40PCI_CIR 0x30
54#define CIR_PIOTEM (1<<31)
55#define CIR_RWTET (1<<26)
56
57#define ST40PCI_AINT 0x40
58#define AINT_MBI (1<<13)
59#define AINT_TBTOI (1<<12)
60#define AINT_MBTOI (1<<11)
61#define AINT_TAI (1<<3)
62#define AINT_MAI (1<<2)
63#define AINT_RDPEI (1<<1)
64#define AINT_WDPE (1<<0)
65
66#define ST40PCI_AINTM 0x44
67#define ST40PCI_BMIR 0x48
68#define ST40PCI_PAR 0x4c
69#define ST40PCI_MBR 0x50
70#define ST40PCI_IOBR 0x54
71#define ST40PCI_PINT 0x58
72#define ST40PCI_PINTM 0x5c
73#define ST40PCI_MBMR 0x70
74#define ST40PCI_IOBMR 0x74
75#define ST40PCI_PDR 0x78
76
77/* H8 specific registers start here */
78#define ST40PCI_WCBAR 0x7c
79#define ST40PCI_LOCCFG_UNLOCK 0x34
80
81#define ST40PCI_RBAR0 0x100
82#define ST40PCI_RSR0 0x104
83#define ST40PCI_RLAR0 0x108
84
85#define ST40PCI_RBAR1 0x110
86#define ST40PCI_RSR1 0x114
87#define ST40PCI_RLAR1 0x118
88
89
90#define ST40PCI_RBAR2 0x120
91#define ST40PCI_RSR2 0x124
92#define ST40PCI_RLAR2 0x128
93
94#define ST40PCI_RBAR3 0x130
95#define ST40PCI_RSR3 0x134
96#define ST40PCI_RLAR3 0x138
97
98#define ST40PCI_RBAR4 0x140
99#define ST40PCI_RSR4 0x144
100#define ST40PCI_RLAR4 0x148
101
102#define ST40PCI_RBAR5 0x150
103#define ST40PCI_RSR5 0x154
104#define ST40PCI_RLAR5 0x158
105
106#define ST40PCI_RBAR6 0x160
107#define ST40PCI_RSR6 0x164
108#define ST40PCI_RLAR6 0x168
109
110#define ST40PCI_RBAR7 0x170
111#define ST40PCI_RSR7 0x174
112#define ST40PCI_RLAR7 0x178
113
114
115#define ST40PCI_RBAR(n) (0x100+(0x10*(n)))
116#define ST40PCI_RSR(n) (0x104+(0x10*(n)))
117#define ST40PCI_RLAR(n) (0x108+(0x10*(n)))
118
119#define ST40PCI_PERF 0x80
120#define PERF_MASTER_WRITE_POSTING (1<<4)
121/* H8 specific registers end here */
122
123
124/* These are configs space registers */
125#define ST40PCI_CSR_VID 0x10000
126#define ST40PCI_CSR_DID 0x10002
127#define ST40PCI_CSR_CMD 0x10004
128#define ST40PCI_CSR_STATUS 0x10006
129#define ST40PCI_CSR_MBAR0 0x10010
130#define ST40PCI_CSR_TRDY 0x10040
131#define ST40PCI_CSR_RETRY 0x10041
132#define ST40PCI_CSR_MIT 0x1000d
133
134#define ST40_IO_ADDR 0xb6000000
135
136#endif /* __PCI_ST40_H__ */
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
new file mode 100644
index 000000000000..c1669905abe4
--- /dev/null
+++ b/arch/sh/drivers/pci/pci.c
@@ -0,0 +1,155 @@
1/* arch/sh/kernel/pci.c
2 * $Id: pci.c,v 1.1 2003/08/24 19:15:45 lethal Exp $
3 *
4 * Copyright (c) 2002 M. R. Brown <mrbrown@linux-sh.org>
5 *
6 *
7 * These functions are collected here to reduce duplication of common
8 * code amongst the many platform-specific PCI support code files.
9 *
10 * These routines require the following board-specific routines:
11 * void pcibios_fixup_irqs();
12 *
13 * See include/asm-sh/pci.h for more information.
14 */
15
16#include <linux/kernel.h>
17#include <linux/pci.h>
18#include <linux/init.h>
19
20static int __init pcibios_init(void)
21{
22 struct pci_channel *p;
23 struct pci_bus *bus;
24 int busno;
25
26#ifdef CONFIG_PCI_AUTO
27 /* assign resources */
28 busno = 0;
29 for (p = board_pci_channels; p->pci_ops != NULL; p++) {
30 busno = pciauto_assign_resources(busno, p) + 1;
31 }
32#endif
33
34 /* scan the buses */
35 busno = 0;
36 for (p= board_pci_channels; p->pci_ops != NULL; p++) {
37 bus = pci_scan_bus(busno, p->pci_ops, p);
38 busno = bus->subordinate+1;
39 }
40
41 /* board-specific fixups */
42 pcibios_fixup_irqs();
43
44 return 0;
45}
46
47subsys_initcall(pcibios_init);
48
49void
50pcibios_update_resource(struct pci_dev *dev, struct resource *root,
51 struct resource *res, int resource)
52{
53 u32 new, check;
54 int reg;
55
56 new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
57 if (resource < 6) {
58 reg = PCI_BASE_ADDRESS_0 + 4*resource;
59 } else if (resource == PCI_ROM_RESOURCE) {
60 res->flags |= IORESOURCE_ROM_ENABLE;
61 new |= PCI_ROM_ADDRESS_ENABLE;
62 reg = dev->rom_base_reg;
63 } else {
64 /* Somebody might have asked allocation of a non-standard resource */
65 return;
66 }
67
68 pci_write_config_dword(dev, reg, new);
69 pci_read_config_dword(dev, reg, &check);
70 if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
71 printk(KERN_ERR "PCI: Error while updating region "
72 "%s/%d (%08x != %08x)\n", pci_name(dev), resource,
73 new, check);
74 }
75}
76
77void pcibios_align_resource(void *data, struct resource *res,
78 unsigned long size, unsigned long align)
79 __attribute__ ((weak));
80
81/*
82 * We need to avoid collisions with `mirrored' VGA ports
83 * and other strange ISA hardware, so we always want the
84 * addresses to be allocated in the 0x000-0x0ff region
85 * modulo 0x400.
86 */
87void pcibios_align_resource(void *data, struct resource *res,
88 unsigned long size, unsigned long align)
89{
90 if (res->flags & IORESOURCE_IO) {
91 unsigned long start = res->start;
92
93 if (start & 0x300) {
94 start = (start + 0x3ff) & ~0x3ff;
95 res->start = start;
96 }
97 }
98}
99
100int pcibios_enable_device(struct pci_dev *dev, int mask)
101{
102 u16 cmd, old_cmd;
103 int idx;
104 struct resource *r;
105
106 pci_read_config_word(dev, PCI_COMMAND, &cmd);
107 old_cmd = cmd;
108 for(idx=0; idx<6; idx++) {
109 if (!(mask & (1 << idx)))
110 continue;
111 r = &dev->resource[idx];
112 if (!r->start && r->end) {
113 printk(KERN_ERR "PCI: Device %s not available because "
114 "of resource collisions\n", pci_name(dev));
115 return -EINVAL;
116 }
117 if (r->flags & IORESOURCE_IO)
118 cmd |= PCI_COMMAND_IO;
119 if (r->flags & IORESOURCE_MEM)
120 cmd |= PCI_COMMAND_MEMORY;
121 }
122 if (dev->resource[PCI_ROM_RESOURCE].start)
123 cmd |= PCI_COMMAND_MEMORY;
124 if (cmd != old_cmd) {
125 printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n",
126 pci_name(dev), old_cmd, cmd);
127 pci_write_config_word(dev, PCI_COMMAND, cmd);
128 }
129 return 0;
130}
131
132/*
133 * If we set up a device for bus mastering, we need to check and set
134 * the latency timer as it may not be properly set.
135 */
136unsigned int pcibios_max_latency = 255;
137
138void pcibios_set_master(struct pci_dev *dev)
139{
140 u8 lat;
141 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
142 if (lat < 16)
143 lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
144 else if (lat > pcibios_max_latency)
145 lat = pcibios_max_latency;
146 else
147 return;
148 printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat);
149 pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
150}
151
152void __init pcibios_update_irq(struct pci_dev *dev, int irq)
153{
154 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
155}