162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * PCI support for the Sega Dreamcast 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2001, 2002 M. R. Brown 662306a36Sopenharmony_ci * Copyright (C) 2002, 2003 Paul Mundt 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * This file originally bore the message (with enclosed-$): 962306a36Sopenharmony_ci * Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp 1062306a36Sopenharmony_ci * Dreamcast PCI: Supports SEGA Broadband Adaptor only. 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <linux/sched.h> 1462306a36Sopenharmony_ci#include <linux/kernel.h> 1562306a36Sopenharmony_ci#include <linux/param.h> 1662306a36Sopenharmony_ci#include <linux/interrupt.h> 1762306a36Sopenharmony_ci#include <linux/init.h> 1862306a36Sopenharmony_ci#include <linux/irq.h> 1962306a36Sopenharmony_ci#include <linux/pci.h> 2062306a36Sopenharmony_ci#include <linux/module.h> 2162306a36Sopenharmony_ci#include <asm/io.h> 2262306a36Sopenharmony_ci#include <asm/irq.h> 2362306a36Sopenharmony_ci#include <mach/pci.h> 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cistatic struct resource gapspci_resources[] = { 2662306a36Sopenharmony_ci { 2762306a36Sopenharmony_ci .name = "GAPSPCI IO", 2862306a36Sopenharmony_ci .start = GAPSPCI_BBA_CONFIG, 2962306a36Sopenharmony_ci .end = GAPSPCI_BBA_CONFIG + GAPSPCI_BBA_CONFIG_SIZE - 1, 3062306a36Sopenharmony_ci .flags = IORESOURCE_IO, 3162306a36Sopenharmony_ci }, { 3262306a36Sopenharmony_ci .name = "GAPSPCI mem", 3362306a36Sopenharmony_ci .start = GAPSPCI_DMA_BASE, 3462306a36Sopenharmony_ci .end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1, 3562306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 3662306a36Sopenharmony_ci }, 3762306a36Sopenharmony_ci}; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic struct pci_channel dreamcast_pci_controller = { 4062306a36Sopenharmony_ci .pci_ops = &gapspci_pci_ops, 4162306a36Sopenharmony_ci .resources = gapspci_resources, 4262306a36Sopenharmony_ci .nr_resources = ARRAY_SIZE(gapspci_resources), 4362306a36Sopenharmony_ci .io_offset = 0x00000000, 4462306a36Sopenharmony_ci .mem_offset = 0x00000000, 4562306a36Sopenharmony_ci}; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci/* 4862306a36Sopenharmony_ci * gapspci init 4962306a36Sopenharmony_ci */ 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistatic int __init gapspci_init(void) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci char idbuf[16]; 5462306a36Sopenharmony_ci int i; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci /* 5762306a36Sopenharmony_ci * FIXME: All of this wants documenting to some degree, 5862306a36Sopenharmony_ci * even some basic register definitions would be nice. 5962306a36Sopenharmony_ci * 6062306a36Sopenharmony_ci * I haven't seen anything this ugly since.. maple. 6162306a36Sopenharmony_ci */ 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci for (i=0; i<16; i++) 6462306a36Sopenharmony_ci idbuf[i] = inb(GAPSPCI_REGS+i); 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16)) 6762306a36Sopenharmony_ci return -ENODEV; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci outl(0x5a14a501, GAPSPCI_REGS+0x18); 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci for (i=0; i<1000000; i++) 7262306a36Sopenharmony_ci cpu_relax(); 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci if (inl(GAPSPCI_REGS+0x18) != 1) 7562306a36Sopenharmony_ci return -EINVAL; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci outl(0x01000000, GAPSPCI_REGS+0x20); 7862306a36Sopenharmony_ci outl(0x01000000, GAPSPCI_REGS+0x24); 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28); 8162306a36Sopenharmony_ci outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c); 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci outl(1, GAPSPCI_REGS+0x14); 8462306a36Sopenharmony_ci outl(1, GAPSPCI_REGS+0x34); 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci /* Setting Broadband Adapter */ 8762306a36Sopenharmony_ci outw(0xf900, GAPSPCI_BBA_CONFIG+0x06); 8862306a36Sopenharmony_ci outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30); 8962306a36Sopenharmony_ci outb(0x00, GAPSPCI_BBA_CONFIG+0x3c); 9062306a36Sopenharmony_ci outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d); 9162306a36Sopenharmony_ci outw(0x0006, GAPSPCI_BBA_CONFIG+0x04); 9262306a36Sopenharmony_ci outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10); 9362306a36Sopenharmony_ci outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14); 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci return register_pci_controller(&dreamcast_pci_controller); 9662306a36Sopenharmony_ci} 9762306a36Sopenharmony_ciarch_initcall(gapspci_init); 98