sh: Add support for R7780RP and R7780MP boards.

This adds support for the Renesas SH7780 development boards,
R7780RP and R7780MP.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
Paul Mundt
2006-09-27 15:59:17 +09:00
parent d7c30c682a
commit 5283ecb5cc
30 changed files with 2684 additions and 49 deletions

View File

@@ -11,6 +11,8 @@ config SH_DMA
config NR_ONCHIP_DMA_CHANNELS
depends on SH_DMA
int "Number of on-chip DMAC channels"
default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R
default "12" if CPU_SUBTYPE_SH7780
default "4"
help
This allows you to specify the number of channels that the on-chip
@@ -52,4 +54,3 @@ config DMA_PAGE_OPS_CHANNEL
are dual-address capable.
endmenu

View File

@@ -11,14 +11,10 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <asm/dreamcast/dma.h>
#include <asm/signal.h>
#include <asm/irq.h>
#include <asm/dma.h>
#include <asm/io.h>
#include "dma-sh.h"

View File

@@ -7,6 +7,7 @@ obj-$(CONFIG_PCI_AUTO) += pci-auto.o
obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += pci-st40.o
obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o
obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o
obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \
dma-dreamcast.o
@@ -14,4 +15,5 @@ obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o
obj-$(CONFIG_SH_BIGSUR) += ops-bigsur.o
obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o
obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o
obj-$(CONFIG_SH_R7780RP) += ops-r7780rp.o fixups-r7780rp.o
obj-$(CONFIG_SH_TITAN) += ops-titan.o

View File

@@ -0,0 +1,39 @@
/*
* arch/sh/drivers/pci/fixups-r7780rp.c
*
* Highlander R7780RP-1 PCI fixups
*
* Copyright (C) 2003 Lineo uSolutions, Inc.
* Copyright (C) 2004 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include "pci-sh7780.h"
#include <asm/io.h>
int pci_fixup_pcic(void)
{
outl(0x000043ff, PCI_REG(SH7780_PCIIMR));
outl(0x0000380f, PCI_REG(SH7780_PCIAINTM));
outl(0xfbb00047, PCI_REG(SH7780_PCICMD));
outl(0x00000000, PCI_REG(SH7780_PCIIBAR));
outl(0x00011912, PCI_REG(SH7780_PCISVID));
outl(0x08000000, PCI_REG(SH7780_PCICSCR0));
outl(0x0000001b, PCI_REG(SH7780_PCICSAR0));
outl(0xfd000000, PCI_REG(SH7780_PCICSCR1));
outl(0x0000000f, PCI_REG(SH7780_PCICSAR1));
outl(0xfd000000, PCI_REG(SH7780_PCIMBR0));
outl(0x00fc0000, PCI_REG(SH7780_PCIMBMR0));
/* Set IOBR for windows containing area specified in pci.h */
outl((PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1)), PCI_REG(SH7780_PCIIOBR));
outl(((SH7780_PCI_IO_SIZE-1) & (7<<18)), PCI_REG(SH7780_PCIIOBMR));
return 0;
}

View File

@@ -0,0 +1,77 @@
/*
* Author: Ian DaSilva (idasilva@mvista.com)
*
* Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* PCI initialization for the Renesas SH7780 Highlander R7780RP-1 board
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/module.h>
#include <asm/io.h>
#include "pci-sh7780.h"
#include <asm/r7780rp/r7780rp.h>
int __init pcibios_map_platform_irq(u8 slot, u8 pin)
{
switch (slot) {
case 0: return IRQ_PCISLOT1; /* PCI Interrupt #1 */
case 1: return IRQ_PCISLOT2; /* PCI Interrupt #2 */
case 2: return IRQ_PCISLOT3; /* PCI Interrupt #3 */
case 3: return IRQ_PCISLOT4; /* PCI Interrupt E4 */
default:
printk("PCI: Bad IRQ mapping request for slot %d, func %d\n", slot, pin-1);
return -1;
}
}
static struct resource sh7780_io_resource = {
.name = "SH7780_IO",
.start = 0x2000,
.end = 0x2000 + SH7780_PCI_IO_SIZE - 1,
.flags = IORESOURCE_IO
};
static struct resource sh7780_mem_resource = {
.name = "SH7780_mem",
.start = SH7780_PCI_MEMORY_BASE,
.end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1,
.flags = IORESOURCE_MEM
};
extern struct pci_ops sh7780_pci_ops;
struct pci_channel board_pci_channels[] = {
{ &sh7780_pci_ops, &sh7780_io_resource, &sh7780_mem_resource, 0, 0xff },
{ NULL, NULL, NULL, 0, 0 },
};
EXPORT_SYMBOL(board_pci_channels);
static struct sh7780_pci_address_map sh7780_pci_map = {
.window0 = {
.base = SH7780_CS2_BASE_ADDR,
.size = 0x04000000,
},
.window1 = {
.base = SH7780_CS3_BASE_ADDR,
.size = 0x04000000,
},
.flags = SH7780_PCIC_NO_RESET,
};
int __init pcibios_init_platform(void)
{
return sh7780_pcic_init(&sh7780_pci_map);
}

View File

@@ -45,11 +45,11 @@
#include <linux/types.h>
#include <linux/pci.h>
#undef DEBUG
#ifdef DEBUG
#define DEBUG
#ifdef DEBUG
#define DBG(x...) printk(x)
#else
#define DBG(x...)
#define DBG(x...)
#endif
/*
@@ -102,7 +102,7 @@ static u32 pciauto_upper_iospc;
static u32 pciauto_lower_memspc;
static u32 pciauto_upper_memspc;
static void __init
static void __init
pciauto_setup_bars(struct pci_channel *hose,
int top_bus,
int current_bus,
@@ -116,7 +116,6 @@ pciauto_setup_bars(struct pci_channel *hose,
int found_mem64 = 0;
for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) {
#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
u32 bar_addr;
/* Read the old BAR value */
@@ -125,7 +124,6 @@ pciauto_setup_bars(struct pci_channel *hose,
pci_devfn,
bar,
&bar_addr);
#endif
/* Tickle the BAR and get the response */
early_write_config_dword(hose, top_bus,
@@ -140,8 +138,7 @@ pciauto_setup_bars(struct pci_channel *hose,
bar,
&bar_response);
#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
/*
/*
* Write the old BAR value back out, only update the BAR
* if we implicitly want resources to be updated, which
* is done by the generic code further down. -- PFM.
@@ -151,7 +148,6 @@ pciauto_setup_bars(struct pci_channel *hose,
pci_devfn,
bar,
bar_addr);
#endif
/* If BAR is not implemented go to the next BAR */
if (!bar_response)
@@ -177,7 +173,7 @@ retry:
PCI_BASE_ADDRESS_MEM_TYPE_64)
found_mem64 = 1;
addr_mask = PCI_BASE_ADDRESS_MEM_MASK;
addr_mask = PCI_BASE_ADDRESS_MEM_MASK;
upper_limit = &pciauto_upper_memspc;
lower_limit = &pciauto_lower_memspc;
DBG(" Mem");
@@ -193,22 +189,22 @@ retry:
if ((bar_value + bar_size) > *upper_limit) {
if (bar_response & PCI_BASE_ADDRESS_SPACE) {
if (io_resource_inuse->child) {
io_resource_inuse =
io_resource_inuse =
io_resource_inuse->child;
pciauto_lower_iospc =
pciauto_lower_iospc =
io_resource_inuse->start;
pciauto_upper_iospc =
pciauto_upper_iospc =
io_resource_inuse->end + 1;
goto retry;
}
} else {
if (mem_resource_inuse->child) {
mem_resource_inuse =
mem_resource_inuse =
mem_resource_inuse->child;
pciauto_lower_memspc =
pciauto_lower_memspc =
mem_resource_inuse->start;
pciauto_upper_memspc =
pciauto_upper_memspc =
mem_resource_inuse->end + 1;
goto retry;
}
@@ -230,7 +226,7 @@ retry:
* If we are a 64-bit decoder then increment to the
* upper 32 bits of the bar and force it to locate
* in the lower 4GB of memory.
*/
*/
if (found_mem64) {
bar += 4;
early_write_config_dword(hose, top_bus,
@@ -362,7 +358,7 @@ pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose,
{
u32 temp;
#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D) && !defined(CONFIG_SH_R7780RP)
/*
* [jsun] we always bump up baselines a little, so that if there
* nothing behind P2P bridge, we don't wind up overlapping IO/MEM
@@ -396,7 +392,7 @@ pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose,
* configured by this routine to happily live behind a
* P2P bridge in a system.
*/
#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D)
#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D) || defined(CONFIG_SH_R7780RP)
pciauto_lower_memspc += 0x00400000;
pciauto_lower_iospc += 0x00004000;
#endif
@@ -433,12 +429,12 @@ pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
int devfn_stop = 0xff;
sub_bus = current_bus;
if (hose->first_devfn)
devfn_start = hose->first_devfn;
if (hose->last_devfn)
devfn_stop = hose->last_devfn;
for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
if (PCI_FUNC(pci_devfn) && !found_multi)
@@ -471,7 +467,7 @@ pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) {
DBG(" Bridge: primary=%.2x, secondary=%.2x\n",
current_bus, sub_bus + 1);
#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D)
#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D) || defined(CONFIG_SH_R7780RP)
pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_1);
#endif
pciauto_prescan_setup_bridge(hose, top_bus, current_bus,
@@ -490,10 +486,10 @@ pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn));
/* Place CardBus Socket/ExCA registers */
pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_0);
pciauto_prescan_setup_cardbus_bridge(hose, top_bus,
current_bus, pci_devfn, sub_bus);
DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n",
sub_bus + 1,
pciauto_lower_iospc, pciauto_lower_memspc);

View File

@@ -223,7 +223,7 @@ static int __init __area_sdram_check(unsigned int area)
word = inl(SH7751_BCR1);
/* check BCR for SDRAM in area */
if(((word >> area) & 1) == 0) {
if (((word >> area) & 1) == 0) {
printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%x\n",
area, word);
return 0;
@@ -232,7 +232,7 @@ static int __init __area_sdram_check(unsigned int area)
word = (u16)inw(SH7751_BCR2);
/* check BCR2 for 32bit SDRAM interface*/
if(((word >> (area << 1)) & 0x3) != 0x3) {
if (((word >> (area << 1)) & 0x3) != 0x3) {
printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%x\n",
area, word);
return 0;

View File

@@ -0,0 +1,341 @@
/*
* Low-Level PCI Support for the SH7780
*
* Dustin McIntire (dustin@sensoria.com)
* Derived from arch/i386/kernel/pci-*.c which bore the message:
* (c) 1999--2000 Martin Mares <mj@ucw.cz>
*
* Ported to the new API by Paul Mundt <lethal@linux-sh.org>
* With cleanup by Paul van Gool <pvangool@mimotech.com>
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
*/
#undef DEBUG
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <asm/machvec.h>
#include <asm/io.h>
#include "pci-sh7780.h"
static unsigned int pci_probe = PCI_PROBE_CONF1;
extern int pci_fixup_pcic(void);
/*
* Direct access to PCI hardware...
*/
#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
/*
* Functions for accessing PCI configuration space with type 1 accesses
*/
static int sh7780_pci_read(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *val)
{
unsigned long flags;
u32 data;
/*
* PCIPDR may only be accessed as 32 bit words,
* so we must do byte alignment by hand
*/
local_irq_save(flags);
outl(CONFIG_CMD(bus, devfn, where), PCI_REG(SH7780_PCIPAR));
data = inl(PCI_REG(SH7780_PCIPDR));
local_irq_restore(flags);
switch (size) {
case 1:
*val = (data >> ((where & 3) << 3)) & 0xff;
break;
case 2:
*val = (data >> ((where & 2) << 3)) & 0xffff;
break;
case 4:
*val = data;
break;
default:
return PCIBIOS_FUNC_NOT_SUPPORTED;
}
return PCIBIOS_SUCCESSFUL;
}
/*
* Since SH7780 only does 32bit access we'll have to do a read,
* mask,write operation.
* We'll allow an odd byte offset, though it should be illegal.
*/
static int sh7780_pci_write(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 val)
{
unsigned long flags;
int shift;
u32 data;
local_irq_save(flags);
outl(CONFIG_CMD(bus, devfn, where), PCI_REG(SH7780_PCIPAR));
data = inl(PCI_REG(SH7780_PCIPDR));
local_irq_restore(flags);
switch (size) {
case 1:
shift = (where & 3) << 3;
data &= ~(0xff << shift);
data |= ((val & 0xff) << shift);
break;
case 2:
shift = (where & 2) << 3;
data &= ~(0xffff << shift);
data |= ((val & 0xffff) << shift);
break;
case 4:
data = val;
break;
default:
return PCIBIOS_FUNC_NOT_SUPPORTED;
}
outl(data, PCI_REG(SH7780_PCIPDR));
return PCIBIOS_SUCCESSFUL;
}
#undef CONFIG_CMD
struct pci_ops sh7780_pci_ops = {
.read = sh7780_pci_read,
.write = sh7780_pci_write,
};
static int __init pci_check_direct(void)
{
unsigned int tmp, id;
outl(0x00000001, SH7780_PCI_VCR2); /* Enable PCIC */
/* check for SH7780/SH7780R hardware */
id = inl(PCI_REG(SH7780_PCIVID));
if ((id != ((SH7780_DEVICE_ID << 16) | SH7780_VENDOR_ID)) &&
(id != ((SH7781_DEVICE_ID << 16) | SH7780_VENDOR_ID))) {
printk(KERN_ERR "PCI: This is not an SH7780 (%x)\n", id);
return -ENODEV;
}
/*
* Check if configuration works.
*/
if (pci_probe & PCI_PROBE_CONF1) {
tmp = inl(PCI_REG(SH7780_PCIPAR));
outl(0x80000000, PCI_REG(SH7780_PCIPAR));
if (inl(PCI_REG(SH7780_PCIPAR)) == 0x80000000) {
outl(tmp, PCI_REG(SH7780_PCIPAR));
printk(KERN_INFO "PCI: Using configuration type 1\n");
request_region(PCI_REG(SH7780_PCIPAR), 8, "PCI conf1");
return 0;
}
outl(tmp, PCI_REG(SH7780_PCIPAR));
}
pr_debug("PCI: pci_check_direct failed\n");
return -EINVAL;
}
/***************************************************************************************/
/*
* Handle bus scanning and fixups ....
*/
static void __init pci_fixup_ide_bases(struct pci_dev *d)
{
int i;
/*
* PCI IDE controllers use non-standard I/O port decoding, respect it.
*/
if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
return;
pr_debug("PCI: IDE base address fixup for %s\n", pci_name(d));
for(i=0; i<4; i++) {
struct resource *r = &d->resource[i];
if ((r->start & ~0x80) == 0x374) {
r->start |= 2;
r->end = r->start;
}
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
/*
* Called after each bus is probed, but before its children
* are examined.
*/
void __init pcibios_fixup_bus(struct pci_bus *b)
{
pci_read_bridge_bases(b);
}
/*
* Initialization. Try all known PCI access methods. Note that we support
* using both PCI BIOS and direct access: in such cases, we use I/O ports
* to access config space.
*
* Note that the platform specific initialization (BSC registers, and memory
* space mapping) will be called via the machine vectors (sh_mv.mv_pci_init()) if it
* exists and via the platform defined function pcibios_init_platform().
* See pci_bigsur.c for implementation;
*
* The BIOS version of the pci functions is not yet implemented but it is left
* in for completeness. Currently an error will be genereated at compile time.
*/
static int __init sh7780_pci_init(void)
{
int ret;
pr_debug("PCI: Starting intialization.\n");
/* Setup the INTC */
ctrl_outl(0x00200000, INTC_ICR0); /* INTC SH-4 Mode */
ctrl_outl(0x00078000, INTC_INT2MSKCR); /* enable PCIINTA - PCIINTD */
ctrl_outl(0x40000000, INTC_INTMSK1); /* disable IRL4-7 Interrupt */
ctrl_outl(0x0000fffe, INTC_INTMSK2); /* disable IRL4-7 Interrupt */
ctrl_outl(0x80000000, INTC_INTMSKCLR1); /* enable IRL0-3 Interrupt */
ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); /* enable IRL0-3 Interrupt */
if ((ret = pci_check_direct()) != 0)
return ret;
return pcibios_init_platform();
}
core_initcall(sh7780_pci_init);
int __init sh7780_pcic_init(struct sh7780_pci_address_map *map)
{
u32 word;
/*
* This code is unused for some boards as it is done in the
* bootloader and doing it here means the MAC addresses loaded
* by the bootloader get lost.
*/
if (!(map->flags & SH7780_PCIC_NO_RESET)) {
/* toggle PCI reset pin */
word = SH7780_PCICR_PREFIX | SH7780_PCICR_PRST;
outl(word,PCI_REG(SH7780_PCICR));
/* Wait for a long time... not 1 sec. but long enough */
mdelay(100);
word = SH7780_PCICR_PREFIX;
outl(word,PCI_REG(SH7780_PCICR));
}
/* set the command/status bits to:
* Wait Cycle Control + Parity Enable + Bus Master +
* Mem space enable
*/
outl(0x00000046, PCI_REG(SH7780_PCICMD));
/* define this host as the host bridge */
word = SH7780_PCI_HOST_BRIDGE << 24;
outl(word, PCI_REG(SH7780_PCIRID));
/* Set IO and Mem windows to local address
* Make PCI and local address the same for easy 1 to 1 mapping
* Window0 = map->window0.size @ non-cached area base = SDRAM
* Window1 = map->window1.size @ cached area base = SDRAM
*/
word = ((map->window0.size - 1) & 0x1ff00001) | 0x01;
outl(0x07f00001, PCI_REG(SH7780_PCILSR0));
word = ((map->window1.size - 1) & 0x1ff00001) | 0x01;
outl(0x00000001, PCI_REG(SH7780_PCILSR1));
/* Set the values on window 0 PCI config registers */
word = P2SEGADDR(map->window0.base);
outl(0xa8000000, PCI_REG(SH7780_PCILAR0));
outl(0x08000000, PCI_REG(SH7780_PCIMBAR0));
/* Set the values on window 1 PCI config registers */
word = P2SEGADDR(map->window1.base);
outl(0x00000000, PCI_REG(SH7780_PCILAR1));
outl(0x00000000, PCI_REG(SH7780_PCIMBAR1));
/* Map IO space into PCI IO window
* The IO window is 64K-PCIBIOS_MIN_IO in size
* IO addresses will be translated to the
* PCI IO window base address
*/
PCIDBG(3,"PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", PCIBIOS_MIN_IO,
(64*1024), SH7780_PCI_IO_BASE+PCIBIOS_MIN_IO);
/* NOTE: I'm ignoring the PCI error IRQs for now..
* TODO: add support for the internal error interrupts and
* DMA interrupts...
*/
#ifdef CONFIG_SH_R7780RP
pci_fixup_pcic();
#endif
/* SH7780 init done, set central function init complete */
/* use round robin mode to stop a device starving/overruning */
word = SH7780_PCICR_PREFIX | SH7780_PCICR_CFIN | /* SH7780_PCICR_ARBM |*/ SH7780_PCICR_FTO;
outl(word, PCI_REG(SH7780_PCICR));
return 1;
}
char * __init pcibios_setup(char *str)
{
if (!strcmp(str, "off")) {
pci_probe = 0;
return NULL;
}
return str;
}
/*
* IRQ functions
*/
static u8 __init sh7780_no_swizzle(struct pci_dev *dev, u8 *pin)
{
/* no swizzling */
return PCI_SLOT(dev->devfn);
}
static int sh7780_pci_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
int irq = -1;
/* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */
irq = pcibios_map_platform_irq(slot,pin);
if( irq < 0 ) {
pr_debug("PCI: Error mapping IRQ on device %s\n", pci_name(dev));
return irq;
}
pr_debug("Setting IRQ for slot %s to %d\n", pci_name(dev), irq);
return irq;
}
void __init pcibios_fixup_irqs(void)
{
pci_fixup_irqs(sh7780_no_swizzle, sh7780_pci_lookup_irq);
}

View File

@@ -0,0 +1,168 @@
/*
* Low-Level PCI Support for SH7780 targets
*
* Dustin McIntire (dustin@sensoria.com) (c) 2001
* Paul Mundt (lethal@linux-sh.org) (c) 2003
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
*/
#ifndef _PCI_SH7780_H_
#define _PCI_SH7780_H_
#include <linux/pci.h>
/* set debug level 4=verbose...1=terse */
//#define DEBUG_PCI 3
#undef DEBUG_PCI
#ifdef DEBUG_PCI
#define PCIDBG(n, x...) { if(DEBUG_PCI>=n) printk(x); }
#else
#define PCIDBG(n, x...)
#endif
/* startup values */
#define PCI_PROBE_BIOS 1
#define PCI_PROBE_CONF1 2
#define PCI_PROBE_CONF2 4
#define PCI_NO_SORT 0x100
#define PCI_BIOS_SORT 0x200
#define PCI_NO_CHECKS 0x400
#define PCI_ASSIGN_ROMS 0x1000
#define PCI_BIOS_IRQ_SCAN 0x2000
/* Platform Specific Values */
#define SH7780_VENDOR_ID 0x1912
#define SH7780_DEVICE_ID 0x0002
#define SH7781_DEVICE_ID 0x0001
/* SH7780 Control Registers */
#define SH7780_PCI_VCR0 0xFE000000
#define SH7780_PCI_VCR1 0xFE000004
#define SH7780_PCI_VCR2 0xFE000008
/* SH7780 Specific Values */
#define SH7780_PCI_CONFIG_BASE 0xFD000000 /* Config space base addr */
#define SH7780_PCI_CONFIG_SIZE 0x01000000 /* Config space size */
#define SH7780_PCI_MEMORY_BASE 0xFD000000 /* Memory space base addr */
#define SH7780_PCI_MEM_SIZE 0x01000000 /* Size of Memory window */
#if 1
#define SH7780_PCI_IO_BASE 0xFE400000 /* IO space base address */
#define SH7780_PCI_IO_SIZE 0x00400000 /* Size of IO window */
#else
#define SH7780_PCI_IO_BASE 0xFE200000 /* IO space base address */
#define SH7780_PCI_IO_SIZE 0x00200000 /* Size of IO window */
#endif
#define SH7780_PCIREG_BASE 0xFE040000 /* PCI regs base address */
#define PCI_REG(n) (SH7780_PCIREG_BASE+n)
/* SH7780 PCI Config Registers */
#define SH7780_PCIVID 0x000 /* Vendor ID */
#define SH7780_PCIDID 0x002 /* Device ID */
#define SH7780_PCICMD 0x004 /* Command */
#define SH7780_PCISTATUS 0x006 /* Status */
#define SH7780_PCIRID 0x008 /* Revision ID */
#define SH7780_PCIPIF 0x009 /* Program Interface */
#define SH7780_PCISUB 0x00a /* Sub class code */
#define SH7780_PCIBCC 0x00b /* Base class code */
#define SH7780_PCICLS 0x00c /* Cache line size */
#define SH7780_PCILTM 0x00d /* latency timer */
#define SH7780_PCIHDR 0x00e /* Header type */
#define SH7780_PCIBIST 0x00f /* BIST */
#define SH7780_PCIIBAR 0x010 /* IO Base address */
#define SH7780_PCIMBAR0 0x014 /* Memory base address0 */
#define SH7780_PCIMBAR1 0x018 /* Memory base address1 */
#define SH7780_PCISVID 0x02c /* Sub system vendor ID */
#define SH7780_PCISID 0x02e /* Sub system ID */
#define SH7780_PCICP 0x034
#define SH7780_PCIINTLINE 0x03c /* Interrupt line */
#define SH7780_PCIINTPIN 0x03d /* Interrupt pin */
#define SH7780_PCIMINGNT 0x03e /* Minumum grand */
#define SH7780_PCIMAXLAT 0x03f /* Maxmum latency */
#define SH7780_PCICID 0x040
#define SH7780_PCINIP 0x041
#define SH7780_PCIPMC 0x042
#define SH7780_PCIPMCSR 0x044
#define SH7780_PCIPMCSR_BSE 0x046
#define SH7780_PCICDD 0x047
/* SH7780 PCI Local Registers */
#define SH7780_PCICR 0x100 /* PCI Control Register */
#define SH7780_PCICR_PREFIX 0xA5000000 /* CR prefix for write */
#define SH7780_PCICR_PFCS 0x00000800 /* TRDY/IRDY Enable */
#define SH7780_PCICR_FTO 0x00000400 /* TRDY/IRDY Enable */
#define SH7780_PCICR_PFE 0x00000200 /* Target Read Single */
#define SH7780_PCICR_TBS 0x00000100 /* Target Byte Swap */
#define SH7780_PCICR_ARBM 0x00000040 /* PCI Arbitration Mode */
#define SH7780_PCICR_IOCS 0x00000004 /* INTA output assert */
#define SH7780_PCICR_PRST 0x00000002 /* PCI Reset Assert */
#define SH7780_PCICR_CFIN 0x00000001 /* Central Fun. Init Done */
#define SH7780_PCILSR0 0x104 /* PCI Local Space Register0 */
#define SH7780_PCILSR1 0x108 /* PCI Local Space Register1 */
#define SH7780_PCILAR0 0x10C /* PCI Local Address Register1 */
#define SH7780_PCILAR1 0x110 /* PCI Local Address Register1 */
#define SH7780_PCIIR 0x114 /* PCI Interrupt Register */
#define SH7780_PCIIMR 0x118 /* PCI Interrupt Mask Register */
#define SH7780_PCIAIR 0x11C /* Error Address Register */
#define SH7780_PCICIR 0x120 /* Error Command/Data Register */
#define SH7780_PCIAINT 0x130 /* Arbiter Interrupt Register */
#define SH7780_PCIAINTM 0x134 /* Arbiter Int. Mask Register */
#define SH7780_PCIBMIR 0x138 /* Error Bus Master Register */
#define SH7780_PCIPAR 0x1C0 /* PIO Address Register */
#define SH7780_PCIPINT 0x1CC /* Power Management Int. Register */
#define SH7780_PCIPINTM 0x1D0 /* Power Management Mask Register */
#define SH7780_PCIMBR0 0x1E0 /* Memory Bank0 Register */
#define SH7780_PCIMBMR0 0x1E4 /* Memory Bank0 Mask Register */
#define SH7780_PCIMBR1 0x1E8 /* Memory Bank1 Register */
#define SH7780_PCIMBMR1 0x1EC /* Memory Bank1 Mask Register */
#define SH7780_PCIMBR2 0x1F0 /* Memory Bank2 Register */
#define SH7780_PCIMBMR2 0x1F4 /* Memory Bank2 Mask Register */
#define SH7780_PCIIOBR 0x1F8 /* Bank Register */
#define SH7780_PCIIOBMR 0x1FC /* Bank Mask Register */
#define SH7780_PCICSCR0 0x210 /* Cache Snoop1 Cnt. Register */
#define SH7780_PCICSCR1 0x214 /* Cache Snoop2 Cnt. Register */
#define SH7780_PCICSAR0 0x218 /* Cache Snoop1 Addr. Register */
#define SH7780_PCICSAR1 0x21C /* Cache Snoop2 Addr. Register */
#define SH7780_PCIPDR 0x220 /* Port IO Data Register */
/* General Memory Config Addresses */
#define SH7780_CS0_BASE_ADDR 0x0
#define SH7780_MEM_REGION_SIZE 0x04000000
#define SH7780_CS1_BASE_ADDR (SH7780_CS0_BASE_ADDR + SH7780_MEM_REGION_SIZE)
#define SH7780_CS2_BASE_ADDR (SH7780_CS1_BASE_ADDR + SH7780_MEM_REGION_SIZE)
#define SH7780_CS3_BASE_ADDR (SH7780_CS2_BASE_ADDR + SH7780_MEM_REGION_SIZE)
#define SH7780_CS4_BASE_ADDR (SH7780_CS3_BASE_ADDR + SH7780_MEM_REGION_SIZE)
#define SH7780_CS5_BASE_ADDR (SH7780_CS4_BASE_ADDR + SH7780_MEM_REGION_SIZE)
#define SH7780_CS6_BASE_ADDR (SH7780_CS5_BASE_ADDR + SH7780_MEM_REGION_SIZE)
/* General PCI values */
#define SH7780_PCI_HOST_BRIDGE 0x6
/* Flags */
#define SH7780_PCIC_NO_RESET 0x0001
/* External functions defined per platform i.e. Big Sur, SE... (these could be routed
* through the machine vectors... */
extern int pcibios_init_platform(void);
extern int pcibios_map_platform_irq(u8 slot, u8 pin);
struct sh7780_pci_address_space {
unsigned long base;
unsigned long size;
};
struct sh7780_pci_address_map {
struct sh7780_pci_address_space window0;
struct sh7780_pci_address_space window1;
unsigned long flags;
};
/* arch/sh/drivers/pci/pci-sh7780.c */
extern int sh7780_pcic_init(struct sh7780_pci_address_map *map);
#endif /* _PCI_SH7780_H_ */