18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * arch/sh/drivers/pci/fixups-dreamcast.c
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * PCI fixups for the Sega Dreamcast
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Copyright (C) 2001, 2002  M. R. Brown
88c2ecf20Sopenharmony_ci * Copyright (C) 2002, 2003, 2006  Paul Mundt
98c2ecf20Sopenharmony_ci *
108c2ecf20Sopenharmony_ci * This file originally bore the message (with enclosed-$):
118c2ecf20Sopenharmony_ci *	Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp
128c2ecf20Sopenharmony_ci *	Dreamcast PCI: Supports SEGA Broadband Adaptor only.
138c2ecf20Sopenharmony_ci */
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#include <linux/sched.h>
168c2ecf20Sopenharmony_ci#include <linux/kernel.h>
178c2ecf20Sopenharmony_ci#include <linux/param.h>
188c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
198c2ecf20Sopenharmony_ci#include <linux/init.h>
208c2ecf20Sopenharmony_ci#include <linux/irq.h>
218c2ecf20Sopenharmony_ci#include <linux/pci.h>
228c2ecf20Sopenharmony_ci#include <linux/dma-map-ops.h>
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci#include <asm/io.h>
258c2ecf20Sopenharmony_ci#include <asm/irq.h>
268c2ecf20Sopenharmony_ci#include <mach/pci.h>
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_cistatic void gapspci_fixup_resources(struct pci_dev *dev)
298c2ecf20Sopenharmony_ci{
308c2ecf20Sopenharmony_ci	struct pci_channel *p = dev->sysdata;
318c2ecf20Sopenharmony_ci	struct resource res;
328c2ecf20Sopenharmony_ci	struct pci_bus_region region;
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci	printk(KERN_NOTICE "PCI: Fixing up device %s\n", pci_name(dev));
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	switch (dev->device) {
378c2ecf20Sopenharmony_ci	case PCI_DEVICE_ID_SEGA_BBA:
388c2ecf20Sopenharmony_ci		/*
398c2ecf20Sopenharmony_ci		 * We also assume that dev->devfn == 0
408c2ecf20Sopenharmony_ci		 */
418c2ecf20Sopenharmony_ci		dev->resource[1].start	= p->resources[0].start  + 0x100;
428c2ecf20Sopenharmony_ci		dev->resource[1].end	= dev->resource[1].start + 0x200 - 1;
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci		/*
458c2ecf20Sopenharmony_ci		 * This is not a normal BAR, prevent any attempts to move
468c2ecf20Sopenharmony_ci		 * the BAR, as this will result in a bus lock.
478c2ecf20Sopenharmony_ci		 */
488c2ecf20Sopenharmony_ci		dev->resource[1].flags |= IORESOURCE_PCI_FIXED;
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci		/*
518c2ecf20Sopenharmony_ci		 * Redirect dma memory allocations to special memory window.
528c2ecf20Sopenharmony_ci		 *
538c2ecf20Sopenharmony_ci		 * If this GAPSPCI region were mapped by a BAR, the CPU
548c2ecf20Sopenharmony_ci		 * phys_addr_t would be pci_resource_start(), and the bus
558c2ecf20Sopenharmony_ci		 * address would be pci_bus_address(pci_resource_start()).
568c2ecf20Sopenharmony_ci		 * But apparently there's no BAR mapping it, so we just
578c2ecf20Sopenharmony_ci		 * "know" its CPU address is GAPSPCI_DMA_BASE.
588c2ecf20Sopenharmony_ci		 */
598c2ecf20Sopenharmony_ci		res.start = GAPSPCI_DMA_BASE;
608c2ecf20Sopenharmony_ci		res.end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1;
618c2ecf20Sopenharmony_ci		res.flags = IORESOURCE_MEM;
628c2ecf20Sopenharmony_ci		pcibios_resource_to_bus(dev->bus, &region, &res);
638c2ecf20Sopenharmony_ci		BUG_ON(dma_declare_coherent_memory(&dev->dev,
648c2ecf20Sopenharmony_ci						res.start,
658c2ecf20Sopenharmony_ci						region.start,
668c2ecf20Sopenharmony_ci						resource_size(&res)));
678c2ecf20Sopenharmony_ci		break;
688c2ecf20Sopenharmony_ci	default:
698c2ecf20Sopenharmony_ci		printk("PCI: Failed resource fixup\n");
708c2ecf20Sopenharmony_ci	}
718c2ecf20Sopenharmony_ci}
728c2ecf20Sopenharmony_ciDECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources);
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ciint pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
758c2ecf20Sopenharmony_ci{
768c2ecf20Sopenharmony_ci	/*
778c2ecf20Sopenharmony_ci	 * The interrupt routing semantics here are quite trivial.
788c2ecf20Sopenharmony_ci	 *
798c2ecf20Sopenharmony_ci	 * We basically only support one interrupt, so we only bother
808c2ecf20Sopenharmony_ci	 * updating a device's interrupt line with this single shared
818c2ecf20Sopenharmony_ci	 * interrupt. Keeps routing quite simple, doesn't it?
828c2ecf20Sopenharmony_ci	 */
838c2ecf20Sopenharmony_ci	return GAPSPCI_IRQ;
848c2ecf20Sopenharmony_ci}
85