11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2f30c2269544bffc7bf1b0d7c0abe5be1be83b8cbUwe Zeisberger * arch/sh/drivers/pci/fixups-dreamcast.c
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PCI fixups for the Sega Dreamcast
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2001, 2002  M. R. Brown
7959f85f8a3223c116bbe95dd8a9b207790b5d4d3Paul Mundt * Copyright (C) 2002, 2003, 2006  Paul Mundt
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file originally bore the message (with enclosed-$):
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Dreamcast PCI: Supports SEGA Broadband Adaptor only.
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file is subject to the terms and conditions of the GNU General Public
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * License.  See the file "COPYING" in the main directory of this archive
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for more details.
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/sched.h>
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h>
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/param.h>
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h>
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/irq.h>
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pci.h>
25a724605cb7a66d423a494a395f9a8ba871b8a1ebMagnus Damm#include <linux/dma-mapping.h>
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h>
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/irq.h>
29f15cbe6f1a4b4d9df59142fc8e4abb973302cf44Paul Mundt#include <mach/pci.h>
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
31b881bc469bdbdcca60e75047885509eb9886d3a2Greg Kroah-Hartmanstatic void gapspci_fixup_resources(struct pci_dev *dev)
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
33951a681bda844491de8699b3bdc6c3899cbd4c9fPaul Mundt	struct pci_channel *p = dev->sysdata;
34ace4b3fd67e771951d495aa1f1b1000984083362Bjorn Helgaas	struct resource res;
35ace4b3fd67e771951d495aa1f1b1000984083362Bjorn Helgaas	struct pci_bus_region region;
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk(KERN_NOTICE "PCI: Fixing up device %s\n", pci_name(dev));
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (dev->device) {
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case PCI_DEVICE_ID_SEGA_BBA:
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * We also assume that dev->devfn == 0
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
44b6c58b1d987a5795086c5c2babd8c7367d2fdb8cPaul Mundt		dev->resource[1].start	= p->resources[0].start  + 0x100;
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dev->resource[1].end	= dev->resource[1].start + 0x200 - 1;
46d556fcc101c4b0d57ac9742ab806a6bfed78eac1Paul Mundt
47d556fcc101c4b0d57ac9742ab806a6bfed78eac1Paul Mundt		/*
48d556fcc101c4b0d57ac9742ab806a6bfed78eac1Paul Mundt		 * This is not a normal BAR, prevent any attempts to move
49d556fcc101c4b0d57ac9742ab806a6bfed78eac1Paul Mundt		 * the BAR, as this will result in a bus lock.
50d556fcc101c4b0d57ac9742ab806a6bfed78eac1Paul Mundt		 */
51d556fcc101c4b0d57ac9742ab806a6bfed78eac1Paul Mundt		dev->resource[1].flags |= IORESOURCE_PCI_FIXED;
52d556fcc101c4b0d57ac9742ab806a6bfed78eac1Paul Mundt
53a724605cb7a66d423a494a395f9a8ba871b8a1ebMagnus Damm		/*
54a724605cb7a66d423a494a395f9a8ba871b8a1ebMagnus Damm		 * Redirect dma memory allocations to special memory window.
55ace4b3fd67e771951d495aa1f1b1000984083362Bjorn Helgaas		 *
56ace4b3fd67e771951d495aa1f1b1000984083362Bjorn Helgaas		 * If this GAPSPCI region were mapped by a BAR, the CPU
57ace4b3fd67e771951d495aa1f1b1000984083362Bjorn Helgaas		 * phys_addr_t would be pci_resource_start(), and the bus
58ace4b3fd67e771951d495aa1f1b1000984083362Bjorn Helgaas		 * address would be pci_bus_address(pci_resource_start()).
59ace4b3fd67e771951d495aa1f1b1000984083362Bjorn Helgaas		 * But apparently there's no BAR mapping it, so we just
60ace4b3fd67e771951d495aa1f1b1000984083362Bjorn Helgaas		 * "know" its CPU address is GAPSPCI_DMA_BASE.
61a724605cb7a66d423a494a395f9a8ba871b8a1ebMagnus Damm		 */
62ace4b3fd67e771951d495aa1f1b1000984083362Bjorn Helgaas		res.start = GAPSPCI_DMA_BASE;
63ace4b3fd67e771951d495aa1f1b1000984083362Bjorn Helgaas		res.end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1;
64ace4b3fd67e771951d495aa1f1b1000984083362Bjorn Helgaas		res.flags = IORESOURCE_MEM;
65ace4b3fd67e771951d495aa1f1b1000984083362Bjorn Helgaas		pcibios_resource_to_bus(dev->bus, &region, &res);
66a724605cb7a66d423a494a395f9a8ba871b8a1ebMagnus Damm		BUG_ON(!dma_declare_coherent_memory(&dev->dev,
67ace4b3fd67e771951d495aa1f1b1000984083362Bjorn Helgaas						res.start,
68ace4b3fd67e771951d495aa1f1b1000984083362Bjorn Helgaas						region.start,
69ace4b3fd67e771951d495aa1f1b1000984083362Bjorn Helgaas						resource_size(&res),
70a724605cb7a66d423a494a395f9a8ba871b8a1ebMagnus Damm						DMA_MEMORY_MAP |
71a724605cb7a66d423a494a395f9a8ba871b8a1ebMagnus Damm						DMA_MEMORY_EXCLUSIVE));
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("PCI: Failed resource fixup\n");
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsDECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources);
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
79d5341942d784134f2997b3ff82cd63cf71d1f932Ralf Baechleint __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
81959f85f8a3223c116bbe95dd8a9b207790b5d4d3Paul Mundt	/*
82959f85f8a3223c116bbe95dd8a9b207790b5d4d3Paul Mundt	 * The interrupt routing semantics here are quite trivial.
83959f85f8a3223c116bbe95dd8a9b207790b5d4d3Paul Mundt	 *
84959f85f8a3223c116bbe95dd8a9b207790b5d4d3Paul Mundt	 * We basically only support one interrupt, so we only bother
85959f85f8a3223c116bbe95dd8a9b207790b5d4d3Paul Mundt	 * updating a device's interrupt line with this single shared
86959f85f8a3223c116bbe95dd8a9b207790b5d4d3Paul Mundt	 * interrupt. Keeps routing quite simple, doesn't it?
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
88959f85f8a3223c116bbe95dd8a9b207790b5d4d3Paul Mundt	return GAPSPCI_IRQ;
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
90