162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * arch/sh/drivers/pci/fixups-dreamcast.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * PCI fixups for the Sega Dreamcast
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Copyright (C) 2001, 2002  M. R. Brown
862306a36Sopenharmony_ci * Copyright (C) 2002, 2003, 2006  Paul Mundt
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci * This file originally bore the message (with enclosed-$):
1162306a36Sopenharmony_ci *	Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp
1262306a36Sopenharmony_ci *	Dreamcast PCI: Supports SEGA Broadband Adaptor only.
1362306a36Sopenharmony_ci */
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/sched.h>
1662306a36Sopenharmony_ci#include <linux/kernel.h>
1762306a36Sopenharmony_ci#include <linux/param.h>
1862306a36Sopenharmony_ci#include <linux/interrupt.h>
1962306a36Sopenharmony_ci#include <linux/init.h>
2062306a36Sopenharmony_ci#include <linux/irq.h>
2162306a36Sopenharmony_ci#include <linux/pci.h>
2262306a36Sopenharmony_ci#include <linux/dma-map-ops.h>
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#include <asm/io.h>
2562306a36Sopenharmony_ci#include <asm/irq.h>
2662306a36Sopenharmony_ci#include <mach/pci.h>
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_cistatic void gapspci_fixup_resources(struct pci_dev *dev)
2962306a36Sopenharmony_ci{
3062306a36Sopenharmony_ci	struct pci_channel *p = dev->sysdata;
3162306a36Sopenharmony_ci	struct resource res;
3262306a36Sopenharmony_ci	struct pci_bus_region region;
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	printk(KERN_NOTICE "PCI: Fixing up device %s\n", pci_name(dev));
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	switch (dev->device) {
3762306a36Sopenharmony_ci	case PCI_DEVICE_ID_SEGA_BBA:
3862306a36Sopenharmony_ci		/*
3962306a36Sopenharmony_ci		 * We also assume that dev->devfn == 0
4062306a36Sopenharmony_ci		 */
4162306a36Sopenharmony_ci		dev->resource[1].start	= p->resources[0].start  + 0x100;
4262306a36Sopenharmony_ci		dev->resource[1].end	= dev->resource[1].start + 0x200 - 1;
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci		/*
4562306a36Sopenharmony_ci		 * This is not a normal BAR, prevent any attempts to move
4662306a36Sopenharmony_ci		 * the BAR, as this will result in a bus lock.
4762306a36Sopenharmony_ci		 */
4862306a36Sopenharmony_ci		dev->resource[1].flags |= IORESOURCE_PCI_FIXED;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci		/*
5162306a36Sopenharmony_ci		 * Redirect dma memory allocations to special memory window.
5262306a36Sopenharmony_ci		 *
5362306a36Sopenharmony_ci		 * If this GAPSPCI region were mapped by a BAR, the CPU
5462306a36Sopenharmony_ci		 * phys_addr_t would be pci_resource_start(), and the bus
5562306a36Sopenharmony_ci		 * address would be pci_bus_address(pci_resource_start()).
5662306a36Sopenharmony_ci		 * But apparently there's no BAR mapping it, so we just
5762306a36Sopenharmony_ci		 * "know" its CPU address is GAPSPCI_DMA_BASE.
5862306a36Sopenharmony_ci		 */
5962306a36Sopenharmony_ci		res.start = GAPSPCI_DMA_BASE;
6062306a36Sopenharmony_ci		res.end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1;
6162306a36Sopenharmony_ci		res.flags = IORESOURCE_MEM;
6262306a36Sopenharmony_ci		pcibios_resource_to_bus(dev->bus, &region, &res);
6362306a36Sopenharmony_ci		BUG_ON(dma_declare_coherent_memory(&dev->dev,
6462306a36Sopenharmony_ci						res.start,
6562306a36Sopenharmony_ci						region.start,
6662306a36Sopenharmony_ci						resource_size(&res)));
6762306a36Sopenharmony_ci		break;
6862306a36Sopenharmony_ci	default:
6962306a36Sopenharmony_ci		printk("PCI: Failed resource fixup\n");
7062306a36Sopenharmony_ci	}
7162306a36Sopenharmony_ci}
7262306a36Sopenharmony_ciDECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources);
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ciint pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
7562306a36Sopenharmony_ci{
7662306a36Sopenharmony_ci	/*
7762306a36Sopenharmony_ci	 * The interrupt routing semantics here are quite trivial.
7862306a36Sopenharmony_ci	 *
7962306a36Sopenharmony_ci	 * We basically only support one interrupt, so we only bother
8062306a36Sopenharmony_ci	 * updating a device's interrupt line with this single shared
8162306a36Sopenharmony_ci	 * interrupt. Keeps routing quite simple, doesn't it?
8262306a36Sopenharmony_ci	 */
8362306a36Sopenharmony_ci	return GAPSPCI_IRQ;
8462306a36Sopenharmony_ci}
85