Commit 8594ca60 authored by Mark A. Greer's avatar Mark A. Greer Committed by Linus Torvalds

[PATCH] ppc32: Marvell host bridge support (mv64x60)

This patch adds core support for a line of host bridges from Marvell
(formerly Galileo).  This code has been tested with a GT64260a, GT64260b,
MV64360, and MV64460.  Patches for platforms that use these bridges will be
sent separately.

The patch is rather large so a link is provided.
Signed-off-by: default avatarMark A. Greer <mgreer@mvista.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent b595953f
......@@ -509,12 +509,15 @@ config PCORE
config POWERPMC250
bool "Force-PowerPMC250"
config EV64260
bool "Galileo-EV-64260-BP"
config SPRUCE
bool "IBM-Spruce"
config EV64260
bool "Marvell-EV64260BP"
help
Select EV64260 if configuring a Marvell (formerly Galileo)
EV64260BP Evaluation platform.
config LOPEC
bool "Motorola-LoPEC"
......@@ -679,7 +682,8 @@ config PPC_OF
config PPC_GEN550
bool
depends on SANDPOINT || MCPN765 || SPRUCE || PPLUS || PCORE || \
PRPMC750 || K2 || PRPMC800 || LOPEC
PRPMC750 || K2 || PRPMC800 || LOPEC || \
(EV64260 && !SERIAL_MPSC)
default y
config FORCE
......@@ -692,6 +696,40 @@ config GT64260
depends on EV64260
default y
config MV64X60
bool
depends on (GT64260 || MV64360)
default y
menu "Set bridge options"
depends on MV64X60
config NOT_COHERENT_CACHE
bool "Turn off Cache Coherency"
default n
help
Some 64x60 bridges lock up when trying to enforce cache coherency.
When this option is selected, cache coherency will be turned off.
Note that this can cause other problems (e.g., stale data being
speculatively loaded via a cached mapping). Use at your own risk.
config MV64X60_BASE
hex "Set bridge base used by firmware"
default "0xf1000000"
help
A firmware can leave the base address of the bridge's registers at
a non-standard location. If so, set this value to reflect the
address of that non-standard location.
config MV64X60_NEW_BASE
hex "Set bridge base used by kernel"
default "0xf1000000"
help
If the current base address of the bridge's registers is not where
you want it, set this value to the address that you want it moved to.
endmenu
config NONMONARCH_SUPPORT
bool "Enable Non-Monarch Support"
depends on PRPMC800
......
......@@ -143,6 +143,7 @@ boot-$(CONFIG_8xx) += embed_config.o
boot-$(CONFIG_8260) += embed_config.o
boot-$(CONFIG_BSEIP) += iic.o
boot-$(CONFIG_MBX) += iic.o pci.o qspan_pci.o
boot-$(CONFIG_MV64X60) += misc-mv64x60.o
boot-$(CONFIG_RPXCLASSIC) += iic.o pci.o qspan_pci.o
boot-$(CONFIG_RPXLITE) += iic.o
# Different boards need different serial implementations.
......@@ -150,8 +151,8 @@ ifeq ($(CONFIG_SERIAL_CPM_CONSOLE),y)
boot-$(CONFIG_8xx) += m8xx_tty.o
boot-$(CONFIG_8260) += m8260_tty.o
endif
boot-$(CONFIG_SERIAL_MPC52xx_CONSOLE) += mpc52xx_tty.o
boot-$(CONFIG_GT64260_CONSOLE) += gt64260_tty.o
boot-$(CONFIG_SERIAL_MPC52xx_CONSOLE) += mpc52xx_tty.o
boot-$(CONFIG_SERIAL_MPSC_CONSOLE) += mv64x60_tty.o
LIBS := $(common)/lib.a $(bootlib)/lib.a
ifeq ($(CONFIG_PPC_PREP),y)
......
/*
* arch/ppc/boot/simple/misc-mv64x60.S
*
* Code to change the base address of the host bridges and call board specific
* init routine.
*
* Author: Mark Greer <mgreer@mvista.com>
*
* 2002 (c) MontaVista, Software, Inc. This file is licensed under the terms
* of the GNU General Public License version 2. This program is licensed
* "as is" without any warranty of any kind, whether express or implied.
*/
#include <linux/config.h>
#include <asm/ppc_asm.h>
#include <asm/processor.h>
#include <asm/cache.h>
#include <asm/mv64x60_defs.h>
.globl mv64x60_init
mv64x60_init:
mflr r27
#if (CONFIG_MV64X60_NEW_BASE != CONFIG_MV64X60_BASE)
bl move_base
#endif
bl mv64x60_board_init
mtlr r27
blr
#if (CONFIG_MV64X60_NEW_BASE != CONFIG_MV64X60_BASE)
move_base:
li r20,0
li r23,20
/* Relocate bridge's regs */
addis r25,0,CONFIG_MV64X60_BASE@h
ori r25,r25,MV64x60_INTERNAL_SPACE_DECODE
lwbrx r26,0,(r25)
lis r24,0xffff
and r26,r26,r24
addis r24,0,CONFIG_MV64X60_NEW_BASE@h
srw r24,r24,r23
or r26,r26,r24
stwbrx r26,0,(r25)
sync
/* Wait for write to take effect */
addis r25,0,CONFIG_MV64X60_NEW_BASE@h
ori r25,r25,MV64x60_INTERNAL_SPACE_DECODE
1: lwbrx r24,0,(r25)
cmpw r24,r26
bne 1b
blr
#endif
/*
* arch/ppc/boot/simple/mv64x60_stub.c
*
* Stub for board_init() routine called from mv64x60_init().
*
* Author: Mark A. Greer <mgreer@mvista.com>
*
* 2002 (c) MontaVista, Software, Inc. This file is licensed under the terms
* of the GNU General Public License version 2. This program is licensed
* "as is" without any warranty of any kind, whether express or implied.
*/
#include <linux/config.h>
#if defined(CONFIG_SERIAL_MPSC_CONSOLE)
long __attribute__ ((weak)) mv64x60_console_baud = 9600;
long __attribute__ ((weak)) mv64x60_mpsc_clk_src = 8; /* TCLK */
long __attribute__ ((weak)) mv64x60_mpsc_clk_freq = 100000000;
#endif
void __attribute__ ((weak))
mv64x60_board_init(void)
{
}
/*
* arch/ppc/boot/simple/mv64x60_tty.c
*
* Bootloader version of the embedded MPSC/UART driver for the Marvell 64x60.
* Note: Due to a GT64260A erratum, DMA will be used for UART input (via SDMA).
*
* Author: Mark A. Greer <mgreer@mvista.com>
*
* Copyright 2001 MontaVista Software Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
/* This code assumes that the data cache has been disabled (L1, L2, L3). */
#include <linux/config.h>
#include <linux/types.h>
#include <linux/serial_reg.h>
#include <asm/serial.h>
#include <asm/mv64x60_defs.h>
#include "../../../../drivers/serial/mpsc_defs.h"
extern void udelay(long);
static void stop_dma(int chan);
static u32 mv64x60_base = CONFIG_MV64X60_NEW_BASE;
inline unsigned
mv64x60_in_le32(volatile unsigned *addr)
{
unsigned ret;
__asm__ __volatile__("lwbrx %0,0,%1; eieio" : "=r" (ret) :
"r" (addr), "m" (*addr));
return ret;
}
inline void
mv64x60_out_le32(volatile unsigned *addr, int val)
{
__asm__ __volatile__("stwbrx %1,0,%2; eieio" : "=m" (*addr) :
"r" (val), "r" (addr));
}
#define MV64x60_REG_READ(offs) \
(mv64x60_in_le32((volatile uint *)(mv64x60_base + (offs))))
#define MV64x60_REG_WRITE(offs, d) \
(mv64x60_out_le32((volatile uint *)(mv64x60_base + (offs)), (int)(d)))
struct sdma_regs {
u32 sdc;
u32 sdcm;
u32 rx_desc;
u32 rx_buf_ptr;
u32 scrdp;
u32 tx_desc;
u32 sctdp;
u32 sftdp;
};
static struct sdma_regs sdma_regs[2];
#define SDMA_REGS_INIT(s, reg_base) { \
(s)->sdc = (reg_base) + SDMA_SDC; \
(s)->sdcm = (reg_base) + SDMA_SDCM; \
(s)->rx_desc = (reg_base) + SDMA_RX_DESC; \
(s)->rx_buf_ptr = (reg_base) + SDMA_RX_BUF_PTR; \
(s)->scrdp = (reg_base) + SDMA_SCRDP; \
(s)->tx_desc = (reg_base) + SDMA_TX_DESC; \
(s)->sctdp = (reg_base) + SDMA_SCTDP; \
(s)->sftdp = (reg_base) + SDMA_SFTDP; \
}
static u32 mpsc_base[2] = { MV64x60_MPSC_0_OFFSET, MV64x60_MPSC_1_OFFSET };
struct mv64x60_rx_desc {
volatile u16 bufsize;
volatile u16 bytecnt;
volatile u32 cmd_stat;
volatile u32 next_desc_ptr;
volatile u32 buffer;
};
struct mv64x60_tx_desc {
volatile u16 bytecnt;
volatile u16 shadow;
volatile u32 cmd_stat;
volatile u32 next_desc_ptr;
volatile u32 buffer;
};
#define MAX_RESET_WAIT 10000
#define MAX_TX_WAIT 10000
#define RX_NUM_DESC 2
#define TX_NUM_DESC 2
#define RX_BUF_SIZE 32
#define TX_BUF_SIZE 32
static struct mv64x60_rx_desc rd[2][RX_NUM_DESC] __attribute__ ((aligned(32)));
static struct mv64x60_tx_desc td[2][TX_NUM_DESC] __attribute__ ((aligned(32)));
static char rx_buf[2][RX_NUM_DESC * RX_BUF_SIZE] __attribute__ ((aligned(32)));
static char tx_buf[2][TX_NUM_DESC * TX_BUF_SIZE] __attribute__ ((aligned(32)));
static int cur_rd[2] = { 0, 0 };
static int cur_td[2] = { 0, 0 };
static char chan_initialized[2] = { 0, 0 };
#define RX_INIT_RDP(rdp) { \
(rdp)->bufsize = 2; \
(rdp)->bytecnt = 0; \
(rdp)->cmd_stat = SDMA_DESC_CMDSTAT_L | SDMA_DESC_CMDSTAT_F | \
SDMA_DESC_CMDSTAT_O; \
}
unsigned long
serial_init(int chan, void *ignored)
{
u32 mpsc_routing_base, sdma_base, brg_bcr, cdv;
int i;
extern long mv64x60_console_baud;
extern long mv64x60_mpsc_clk_src;
extern long mv64x60_mpsc_clk_freq;
chan = (chan == 1); /* default to chan 0 if anything but 1 */
if (chan_initialized[chan])
return chan;
chan_initialized[chan] = 1;
if (chan == 0) {
sdma_base = MV64x60_SDMA_0_OFFSET;
brg_bcr = MV64x60_BRG_0_OFFSET + BRG_BCR;
SDMA_REGS_INIT(&sdma_regs[0], MV64x60_SDMA_0_OFFSET);
}
else {
sdma_base = MV64x60_SDMA_1_OFFSET;
brg_bcr = MV64x60_BRG_1_OFFSET + BRG_BCR;
SDMA_REGS_INIT(&sdma_regs[0], MV64x60_SDMA_1_OFFSET);
}
mpsc_routing_base = MV64x60_MPSC_ROUTING_OFFSET;
stop_dma(chan);
/* Set up ring buffers */
for (i=0; i<RX_NUM_DESC; i++) {
RX_INIT_RDP(&rd[chan][i]);
rd[chan][i].buffer = (u32)&rx_buf[chan][i * RX_BUF_SIZE];
rd[chan][i].next_desc_ptr = (u32)&rd[chan][i+1];
}
rd[chan][RX_NUM_DESC - 1].next_desc_ptr = (u32)&rd[chan][0];
for (i=0; i<TX_NUM_DESC; i++) {
td[chan][i].bytecnt = 0;
td[chan][i].shadow = 0;
td[chan][i].buffer = (u32)&tx_buf[chan][i * TX_BUF_SIZE];
td[chan][i].cmd_stat = SDMA_DESC_CMDSTAT_F|SDMA_DESC_CMDSTAT_L;
td[chan][i].next_desc_ptr = (u32)&td[chan][i+1];
}
td[chan][TX_NUM_DESC - 1].next_desc_ptr = (u32)&td[chan][0];
/* Set MPSC Routing */
MV64x60_REG_WRITE(mpsc_routing_base + MPSC_MRR, 0x3ffffe38);
#ifdef CONFIG_GT64260
MV64x60_REG_WRITE(GT64260_MPP_SERIAL_PORTS_MULTIPLEX, 0x00001102);
#else /* Must be MV64360 or MV64460 */
{
u32 enables, prot_bits, v;
/* Set up comm unit to memory mapping windows */
/* Note: Assumes MV64x60_CPU2MEM_WINDOWS == 4 */
u32 cpu2mem_tab[MV64x60_CPU2MEM_WINDOWS][2] = {
{ MV64x60_CPU2MEM_0_BASE, MV64x60_CPU2MEM_0_SIZE },
{ MV64x60_CPU2MEM_1_BASE, MV64x60_CPU2MEM_1_SIZE },
{ MV64x60_CPU2MEM_2_BASE, MV64x60_CPU2MEM_2_SIZE },
{ MV64x60_CPU2MEM_3_BASE, MV64x60_CPU2MEM_3_SIZE }
};
u32 com2mem_tab[MV64x60_CPU2MEM_WINDOWS][2] = {
{ MV64360_MPSC2MEM_0_BASE, MV64360_MPSC2MEM_0_SIZE },
{ MV64360_MPSC2MEM_1_BASE, MV64360_MPSC2MEM_1_SIZE },
{ MV64360_MPSC2MEM_2_BASE, MV64360_MPSC2MEM_2_SIZE },
{ MV64360_MPSC2MEM_3_BASE, MV64360_MPSC2MEM_3_SIZE }
};
u32 dram_selects[MV64x60_CPU2MEM_WINDOWS] = { 0xe, 0xd, 0xb, 0x7 };
enables = MV64x60_REG_READ(MV64360_CPU_BAR_ENABLE) & 0xf;
prot_bits = 0;
for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
if (!(enables & (1 << i))) {
v = MV64x60_REG_READ(cpu2mem_tab[i][0]);
v = ((v & 0xffff) << 16) | (dram_selects[i] << 8);
MV64x60_REG_WRITE(com2mem_tab[i][0], v);
v = MV64x60_REG_READ(cpu2mem_tab[i][1]);
v = (v & 0xffff) << 16;
MV64x60_REG_WRITE(com2mem_tab[i][1], v);
prot_bits |= (0x3 << (i << 1)); /* r/w access */
}
}
MV64x60_REG_WRITE(MV64360_MPSC_0_REMAP, 0);
MV64x60_REG_WRITE(MV64360_MPSC_1_REMAP, 0);
MV64x60_REG_WRITE(MV64360_MPSC2MEM_ACC_PROT_0, prot_bits);
MV64x60_REG_WRITE(MV64360_MPSC2MEM_ACC_PROT_1, prot_bits);
MV64x60_REG_WRITE(MV64360_MPSC2MEM_BAR_ENABLE, enables);
}
#endif
/* MPSC 0/1 Rx & Tx get clocks BRG0/1 */
MV64x60_REG_WRITE(mpsc_routing_base + MPSC_RCRR, 0x00000100);
MV64x60_REG_WRITE(mpsc_routing_base + MPSC_TCRR, 0x00000100);
/* clear pending interrupts */
MV64x60_REG_WRITE(MV64x60_SDMA_INTR_OFFSET + SDMA_INTR_MASK, 0);
MV64x60_REG_WRITE(SDMA_SCRDP + sdma_base, &rd[chan][0]);
MV64x60_REG_WRITE(SDMA_SCTDP + sdma_base, &td[chan][TX_NUM_DESC - 1]);
MV64x60_REG_WRITE(SDMA_SFTDP + sdma_base, &td[chan][TX_NUM_DESC - 1]);
MV64x60_REG_WRITE(SDMA_SDC + sdma_base,
SDMA_SDC_RFT | SDMA_SDC_SFM | SDMA_SDC_BLMR | SDMA_SDC_BLMT |
(3 << 12));
cdv = ((mv64x60_mpsc_clk_freq/(32*mv64x60_console_baud))-1);
MV64x60_REG_WRITE(brg_bcr,
((mv64x60_mpsc_clk_src << 18) | (1 << 16) | cdv));
/* Put MPSC into UART mode, no null modem, 16x clock mode */
MV64x60_REG_WRITE(MPSC_MMCRL + mpsc_base[chan], 0x000004c4);
MV64x60_REG_WRITE(MPSC_MMCRH + mpsc_base[chan], 0x04400400);
MV64x60_REG_WRITE(MPSC_CHR_1 + mpsc_base[chan], 0);
MV64x60_REG_WRITE(MPSC_CHR_9 + mpsc_base[chan], 0);
MV64x60_REG_WRITE(MPSC_CHR_10 + mpsc_base[chan], 0);
MV64x60_REG_WRITE(MPSC_CHR_3 + mpsc_base[chan], 4);
MV64x60_REG_WRITE(MPSC_CHR_4 + mpsc_base[chan], 0);
MV64x60_REG_WRITE(MPSC_CHR_5 + mpsc_base[chan], 0);
MV64x60_REG_WRITE(MPSC_CHR_6 + mpsc_base[chan], 0);
MV64x60_REG_WRITE(MPSC_CHR_7 + mpsc_base[chan], 0);
MV64x60_REG_WRITE(MPSC_CHR_8 + mpsc_base[chan], 0);
/* 8 data bits, 1 stop bit */
MV64x60_REG_WRITE(MPSC_MPCR + mpsc_base[chan], (3 << 12));
MV64x60_REG_WRITE(SDMA_SDCM + sdma_base, SDMA_SDCM_ERD);
MV64x60_REG_WRITE(MPSC_CHR_2 + mpsc_base[chan], MPSC_CHR_2_EH);
udelay(100);
return chan;
}
static void
stop_dma(int chan)
{
int i;
/* Abort MPSC Rx (aborting Tx messes things up) */
MV64x60_REG_WRITE(MPSC_CHR_2 + mpsc_base[chan], MPSC_CHR_2_RA);
/* Abort SDMA Rx, Tx */
MV64x60_REG_WRITE(sdma_regs[chan].sdcm, SDMA_SDCM_AR | SDMA_SDCM_STD);
for (i=0; i<MAX_RESET_WAIT; i++) {
if ((MV64x60_REG_READ(sdma_regs[chan].sdcm) &
(SDMA_SDCM_AR | SDMA_SDCM_AT)) == 0)
break;
udelay(100);
}
return;
}
static int
wait_for_ownership(int chan)
{
int i;
for (i=0; i<MAX_TX_WAIT; i++) {
if ((MV64x60_REG_READ(sdma_regs[chan].sdcm) &
SDMA_SDCM_TXD) == 0)
break;
udelay(1000);
}
return (i < MAX_TX_WAIT);
}
void
serial_putc(unsigned long com_port, unsigned char c)
{
struct mv64x60_tx_desc *tdp;
if (wait_for_ownership(com_port) == 0)
return;
tdp = &td[com_port][cur_td[com_port]];
if (++cur_td[com_port] >= TX_NUM_DESC)
cur_td[com_port] = 0;
*(unchar *)(tdp->buffer ^ 7) = c;
tdp->bytecnt = 1;
tdp->shadow = 1;
tdp->cmd_stat = SDMA_DESC_CMDSTAT_L | SDMA_DESC_CMDSTAT_F |
SDMA_DESC_CMDSTAT_O;
MV64x60_REG_WRITE(sdma_regs[com_port].sctdp, tdp);
MV64x60_REG_WRITE(sdma_regs[com_port].sftdp, tdp);
MV64x60_REG_WRITE(sdma_regs[com_port].sdcm,
MV64x60_REG_READ(sdma_regs[com_port].sdcm) | SDMA_SDCM_TXD);
return;
}
unsigned char
serial_getc(unsigned long com_port)
{
struct mv64x60_rx_desc *rdp;
unchar c = '\0';
rdp = &rd[com_port][cur_rd[com_port]];
if ((rdp->cmd_stat & (SDMA_DESC_CMDSTAT_O|SDMA_DESC_CMDSTAT_ES)) == 0) {
c = *(unchar *)(rdp->buffer ^ 7);
RX_INIT_RDP(rdp);
if (++cur_rd[com_port] >= RX_NUM_DESC)
cur_rd[com_port] = 0;
}
return c;
}
int
serial_tstc(unsigned long com_port)
{
struct mv64x60_rx_desc *rdp;
int loop_count = 0;
int rc = 0;
rdp = &rd[com_port][cur_rd[com_port]];
/* Go thru rcv desc's until empty looking for one with data (no error)*/
while (((rdp->cmd_stat & SDMA_DESC_CMDSTAT_O) == 0) &&
(loop_count++ < RX_NUM_DESC)) {
/* If there was an error, reinit the desc & continue */
if ((rdp->cmd_stat & SDMA_DESC_CMDSTAT_ES) != 0) {
RX_INIT_RDP(rdp);
if (++cur_rd[com_port] >= RX_NUM_DESC)
cur_rd[com_port] = 0;
rdp = (struct mv64x60_rx_desc *)rdp->next_desc_ptr;
}
else {
rc = 1;
break;
}
}
return rc;
}
void
serial_close(unsigned long com_port)
{
stop_dma(com_port);
return;
}
......@@ -43,6 +43,7 @@ obj-$(CONFIG_EBONY) += indirect_pci.o pci_auto.o todc_time.o
obj-$(CONFIG_EV64260) += gt64260_common.o gt64260_pic.o \
indirect_pci.o todc_time.o pci_auto.o
obj-$(CONFIG_GEMINI) += open_pic.o indirect_pci.o
obj-$(CONFIG_GT64260) += gt64260_pic.o
obj-$(CONFIG_K2) += i8259.o indirect_pci.o todc_time.o \
pci_auto.o
obj-$(CONFIG_LOPEC) += i8259.o pci_auto.o todc_time.o
......@@ -50,6 +51,8 @@ obj-$(CONFIG_MCPN765) += todc_time.o indirect_pci.o pci_auto.o \
open_pic.o i8259.o hawk_common.o
obj-$(CONFIG_MENF1) += todc_time.o i8259.o mpc10x_common.o \
pci_auto.o indirect_pci.o
obj-$(CONFIG_MV64360) += mv64360_pic.o
obj-$(CONFIG_MV64X60) += mv64x60.o mv64x60_win.o indirect_pci.o
obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o indirect_pci.o \
pci_auto.o hawk_common.o
obj-$(CONFIG_MVME5100_IPMC761_PRESENT) += i8259.o
......
/*
* arch/ppc/syslib/gt64260_common.c
*
* Common routines for the Marvell/Galileo GT64260 (Discovery) host bridge,
* interrupt controller, memory controller, serial controller, enet controller,
* etc.
*
* Author: Mark A. Greer <mgreer@mvista.com>
*
* 2001 (c) MontaVista, Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
/*
* The GT64260 port is the result of hard work from many people from
* many companies. In particular, employees of Marvell/Galileo, Mission
* Critical Linux, Xyterra, and MontaVista Software were heavily involved.
*/
/*
* At last count, the 64260-B-0 has 65 errata and 24 restrictions. The odds of
* you getting it to work well, under stress, for a long period of time are
* low. If nothing else, you will likely run into an interrupt controller
* bug.
*
* The newer 64260A-B-0 is much improved but has its own problems.
* Dave Wilhardt <dwilhardt@zyterra.com> has discovered that you must set
* up your PCI snoop regions to be prefetchable with 4-word bursts AND set the
* "Memory Write and Invalidate bit" (bit 4) in the cmd reg of each PCI device
* before coherency works between PCI and other devices. Many thanks to Dave.
*
* So far this code has been tested on Marvell/Galileo EV-64260-BP and
* an EV-64260A-BP uni-processor boards with 750 and 7400 processors.
* It has not yet been tested with a 7410 or 7450, or on an smp system.
*
* Note: I have not had any luck moving the base register address of the bridge
* with the gt64260_set_base() routine. I move it in the bootloader
* before starting the kernel. I haven't really looked into it so it
* may be an easy fix. -- MAG
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
#include <asm/gt64260.h>
#include <asm/delay.h>
u32 gt64260_base; /* Virtual base address of 64260's regs */
u32 gt64260_revision; /* Revision of the chip */
u8 gt64260_pci_exclude_bridge = TRUE;
/*
*****************************************************************************
*
* Bridge Initialization Routines
*
*****************************************************************************
*/
static void gt64260_check_errata(struct pci_controller *hose_a,
struct pci_controller *hose_b);
/*
* Typical '_find_bridges()' routine for boards with a GT64260 bridge.
*/
int __init
gt64260_find_bridges(u32 phys_base_addr, gt64260_bridge_info_t *info,
int ((*map_irq)(struct pci_dev *, unsigned char, unsigned char)))
{
struct pci_controller *hose_a, *hose_b;
u32 io_base_a, io_base_b;
int rc;
gt64260_base = (u32)ioremap(phys_base_addr,GT64260_INTERNAL_SPACE_SIZE);
hose_a = pcibios_alloc_controller();
if (!hose_a)
return -1;
hose_b = pcibios_alloc_controller();
if (!hose_b)
return -1;
info->hose_a = hose_a;
info->hose_b = hose_b;
/* Ends up mapping PCI Config addr/data pairs twice */
setup_indirect_pci(hose_a,
phys_base_addr + GT64260_PCI_0_CONFIG_ADDR,
phys_base_addr + GT64260_PCI_0_CONFIG_DATA);
setup_indirect_pci(hose_b,
phys_base_addr + GT64260_PCI_1_CONFIG_ADDR,
phys_base_addr + GT64260_PCI_1_CONFIG_DATA);
if ((rc = gt64260_bridge_init(info)) != 0) {
iounmap((void *)hose_a->cfg_addr);
iounmap((void *)hose_a->cfg_data);
iounmap((void *)hose_b->cfg_addr);
iounmap((void *)hose_b->cfg_data);
iounmap((void *)gt64260_base);
return rc;
}
/* ioremap PCI I/O regions */
io_base_b = (u32)ioremap(info->pci_1_io_start_proc,info->pci_1_io_size);
io_base_a = (u32)ioremap(info->pci_0_io_start_proc,info->pci_0_io_size);
isa_io_base = io_base_a;
hose_a->first_busno = 0;
hose_a->last_busno = 0xff;
pci_init_resource(&hose_a->io_resource,
0, /* really: io_base_a - isa_io_base */
info->pci_0_io_size - 1,
IORESOURCE_IO,
"host bridge PCI bus 0");
hose_a->io_space.start = info->pci_0_io_start_pci;
hose_a->io_space.end = info->pci_0_io_start_pci +
info->pci_0_io_size - 1;
hose_a->io_base_virt = (void *)isa_io_base;
pci_init_resource(&hose_a->mem_resources[0],
info->pci_0_mem_start_proc,
info->pci_0_mem_start_proc + info->pci_0_mem_size - 1,
IORESOURCE_MEM,
"host bridge PCI bus 0");
hose_a->mem_space.start = info->pci_0_mem_start_pci_lo;
hose_a->mem_space.end = info->pci_0_mem_start_pci_lo +
info->pci_0_mem_size - 1;
hose_a->pci_mem_offset = (info->pci_0_mem_start_proc -
info->pci_0_mem_start_pci_lo);
hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno);
hose_b->first_busno = hose_a->last_busno + 1;
hose_b->bus_offset = hose_b->first_busno;
hose_b->last_busno = 0xff;
pci_init_resource(&hose_b->io_resource,
io_base_b - isa_io_base,
io_base_b - isa_io_base + info->pci_1_io_size - 1,
IORESOURCE_IO,
"host bridge PCI bus 1");
hose_b->io_space.start = info->pci_1_io_start_pci;
hose_b->io_space.end = info->pci_1_io_start_pci +
info->pci_1_io_size - 1;
hose_b->io_base_virt = (void *)isa_io_base;
pci_init_resource(&hose_b->mem_resources[0],
info->pci_1_mem_start_proc,
info->pci_1_mem_start_proc + info->pci_1_mem_size - 1,
IORESOURCE_MEM,
"host bridge PCI bus 1");
hose_b->mem_space.start = info->pci_1_mem_start_pci_lo;
hose_b->mem_space.end = info->pci_1_mem_start_pci_lo +
info->pci_1_mem_size - 1;
hose_b->pci_mem_offset = (info->pci_1_mem_start_proc -
info->pci_1_mem_start_pci_lo);
hose_b->last_busno = pciauto_bus_scan(hose_b, hose_b->first_busno);
ppc_md.pci_exclude_device = gt64260_pci_exclude_device;
ppc_md.pci_swizzle = common_swizzle;
ppc_md.pci_map_irq = map_irq;
return 0;
} /* gt64260_find_bridges() */
/*
* gt64260_bridge_init()
*
* Perform bridge initialization for a "typical" setup for a PPC system.
*/
int __init
gt64260_bridge_init(gt64260_bridge_info_t *info)
{
int window;
u16 u16_val;
u32 u32_val;
int rc = 0;
u8 save_exclude;
/*
* Count on firmware to set/clear other bits in this register.
*
* Set CPU CONFIG Reg bit:
* bit 13 - Pipeline
* bit 16 - RdOOO
*
* Clear CPU Config Reg bit:
* bit 12 - endianess
* bit 27 - RemapWrDis
*/
u32_val = gt_read(GT64260_CPU_CONFIG);
u32_val |= ((1<<13) | (1<<16));
u32_val &= ~((1<<8) | (1<<12) | (1<<27));
gt_write(GT64260_CPU_CONFIG, u32_val);
/* PCI 0/1 Timeout and Retry limits */
u32_val = gt_read(GT64260_PCI_0_TO_RETRY);
u32_val |= 0x0000ffff;
gt_write(GT64260_PCI_0_TO_RETRY, u32_val);
u32_val = gt_read(GT64260_PCI_1_TO_RETRY);
u32_val |= 0x0000ffff;
gt_write(GT64260_PCI_1_TO_RETRY, u32_val);
save_exclude = gt64260_pci_exclude_bridge;
gt64260_pci_exclude_bridge = FALSE;
/* Set class code to indicate host bridge */
early_read_config_dword(info->hose_a,
info->hose_a->first_busno,
PCI_DEVFN(0,0),
PCI_CLASS_REVISION,
&u32_val);
u32_val &= 0x000000ff;
gt64260_revision = u32_val; /* a 64260 or 64260A? */
u32_val |= (PCI_CLASS_BRIDGE_HOST << 16);
early_write_config_dword(info->hose_a,
info->hose_a->first_busno,
PCI_DEVFN(0,0),
PCI_CLASS_REVISION,
u32_val);
early_read_config_dword(info->hose_b,
info->hose_b->first_busno,
PCI_DEVFN(0,0),
PCI_CLASS_REVISION,
&u32_val);
u32_val &= 0x000000ff;
u32_val |= (PCI_CLASS_BRIDGE_HOST << 16);
early_write_config_dword(info->hose_b,
info->hose_b->first_busno,
PCI_DEVFN(0,0),
PCI_CLASS_REVISION,
u32_val);
/* Enable 64260 to be PCI master & respond to PCI MEM cycles */
early_read_config_word(info->hose_a,
info->hose_a->first_busno,
PCI_DEVFN(0,0),
PCI_COMMAND,
&u16_val);
u16_val |= (PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
early_write_config_word(info->hose_a,
info->hose_a->first_busno,
PCI_DEVFN(0,0),
PCI_COMMAND,
u16_val);
early_read_config_word(info->hose_b,
info->hose_b->first_busno,
PCI_DEVFN(0,0),
PCI_COMMAND,
&u16_val);
u16_val |= (PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
early_write_config_word(info->hose_b,
info->hose_b->first_busno,
PCI_DEVFN(0,0),
PCI_COMMAND,
u16_val);
gt64260_pci_exclude_bridge = save_exclude;
/*
* Disable all CPU windows on the bridge except for SCS 0 which
* is covering all of system memory.:
*/
gt64260_cpu_disable_all_windows();
/*
* Set CPU snoop window to indicate all of system memory
* is covered with wirte-back cache.
*/
gt64260_cpu_snoop_set_window(0,
0x00000000,
info->mem_size,
GT64260_CPU_SNOOP_WB);
/*
* Set up CPU->PCI mappings (so CPU can get at PCI dev regs/mem).
* Will only use one of the four CPU->PCI MEM windows on each bus.
*/
gt64260_cpu_set_pci_io_window(0,
info->pci_0_io_start_proc,
info->pci_0_io_start_pci,
info->pci_0_io_size,
info->pci_0_io_swap);
gt64260_cpu_set_pci_mem_window(0,
0,
info->pci_0_mem_start_proc,
info->pci_0_mem_start_pci_hi,
info->pci_0_mem_start_pci_lo,
info->pci_0_mem_size,
info->pci_0_mem_swap);
gt64260_cpu_set_pci_io_window(1,
info->pci_1_io_start_proc,
info->pci_1_io_start_pci,
info->pci_1_io_size,
info->pci_1_io_swap);
gt64260_cpu_set_pci_mem_window(1,
0,
info->pci_1_mem_start_proc,
info->pci_1_mem_start_pci_hi,
info->pci_1_mem_start_pci_lo,
info->pci_1_mem_size,
info->pci_1_mem_swap);
/*
* Set up PCI MEM->system memory mapping (bridge slave PCI window).
*
* Set BAR enables to allow only the SCS0 slave window to respond
* to PCI read/write cycles.
*/
gt64260_pci_bar_enable(0, GT64260_PCI_SLAVE_BAR_REG_ENABLES_SCS_0);
gt64260_pci_bar_enable(1, GT64260_PCI_SLAVE_BAR_REG_ENABLES_SCS_0);
/*
* For virt_to_bus & bus_to_virt to work correctly, this mapping
* must be the same on both PCI buses.
*/
gt64260_pci_slave_scs_set_window(info->hose_a,
0,
0x00000000,
0x00000000,
info->mem_size);
gt64260_pci_slave_scs_set_window(info->hose_b,
0,
0x00000000,
0x00000000,
info->mem_size);
pci_dram_offset = 0; /* System mem at same addr on PCI & cpu bus */
/* Disable all the access control windows */
for (window=0; window<GT64260_PCI_ACC_CNTL_WINDOWS; window++) {
gt64260_pci_acc_cntl_set_window(0, window, 0, 0, 0, 0);
gt64260_pci_acc_cntl_set_window(1, window, 0, 0, 0, 0);
}
/* Disable all the PCI snoop regions */
for (window=0; window<GT64260_PCI_SNOOP_WINDOWS; window++) {
gt64260_pci_snoop_set_window(0, window, 0, 0, 0, 0);
gt64260_pci_snoop_set_window(1, window, 0, 0, 0, 0);
}
gt64260_pci_acc_cntl_set_window(0,
0,
0x00000000,
0x00000000,
info->mem_size,
(GT64260_PCI_ACC_CNTL_PREFETCHEN |
GT64260_PCI_ACC_CNTL_MBURST_4_WORDS |
GT64260_PCI_ACC_CNTL_SWAP_BYTE));
gt64260_pci_acc_cntl_set_window(1,
0,
0x00000000,
0x00000000,
info->mem_size,
(GT64260_PCI_ACC_CNTL_PREFETCHEN |
GT64260_PCI_ACC_CNTL_MBURST_4_WORDS |
GT64260_PCI_ACC_CNTL_SWAP_BYTE));
gt64260_pci_snoop_set_window(0,
0,
0x00000000,
0x00000000,
info->mem_size,
GT64260_PCI_SNOOP_WB);
gt64260_pci_snoop_set_window(1,
0,
0x00000000,
0x00000000,
info->mem_size,
GT64260_PCI_SNOOP_WB);
gt64260_check_errata(info->hose_a, info->hose_b);
/* Set latency timer (to 64) & cacheline size; clear BIST */
gt64260_pci_exclude_bridge = FALSE;
u32_val = ((0x04 << 8) | (L1_CACHE_LINE_SIZE / 4));
early_write_config_dword(info->hose_a,
info->hose_a->first_busno,
PCI_DEVFN(0,0),
PCI_CACHE_LINE_SIZE,
u32_val);
early_write_config_dword(info->hose_b,
info->hose_b->first_busno,
PCI_DEVFN(0,0),
PCI_CACHE_LINE_SIZE,
u32_val);
gt64260_pci_exclude_bridge = TRUE;
return rc;
} /* gt64260_bridge_init() */
/*
* gt64260_check_errata()
*
* Apply applicable errata and restrictions from 0.5 of the
* Errata and Restrictions document from Marvell/Galileo.
*/
static void __init
gt64260_check_errata(struct pci_controller *hose_a,
struct pci_controller *hose_b)
{
u32 val;
u8 save_exclude;
/* Currently 2 versions, 64260 and 64260A */
if (gt64260_revision == GT64260) {
save_exclude = gt64260_pci_exclude_bridge;
gt64260_pci_exclude_bridge = FALSE;
/* FEr#5, FEr#12 */
early_read_config_dword(hose_a,
hose_a->first_busno,
PCI_DEVFN(0,0),
PCI_COMMAND,
&val);
val &= ~(PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY);
early_write_config_dword(hose_a,
hose_a->first_busno,
PCI_DEVFN(0,0),
PCI_COMMAND,
val);
early_read_config_dword(hose_b,
hose_b->first_busno,
PCI_DEVFN(0,0),
PCI_COMMAND,
&val);
val &= ~(PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY);
early_write_config_dword(hose_b,
hose_b->first_busno,
PCI_DEVFN(0,0),
PCI_COMMAND,
val);
gt64260_pci_exclude_bridge = save_exclude;
/* FEr#12, FEr#13 */
gt_clr_bits(GT64260_PCI_0_CMD, ((1<<4) | (1<<5) | (1<<9)));
gt_clr_bits(GT64260_PCI_1_CMD, ((1<<4) | (1<<5) | (1<<9)));
/* FEr#54 */
gt_clr_bits(GT64260_CPU_SNOOP_BASE_0, 0xfffcf000);
gt_clr_bits(GT64260_CPU_SNOOP_BASE_1, 0xfffcf000);
gt_clr_bits(GT64260_CPU_SNOOP_BASE_2, 0xfffcf000);
gt_clr_bits(GT64260_CPU_SNOOP_BASE_3, 0xfffcf000);
/* R#18 */
gt_set_bits(GT64260_SDRAM_CONFIG, (1<<26));
} else if (gt64260_revision == GT64260A) {
/* R#18 */
gt_set_bits(GT64260_SDRAM_CONFIG, (1<<26));
/* No longer errata so turn on */
gt_set_bits(GT64260_PCI_0_CMD, ((1<<4) | (1<<5) | (1<<9)));
gt_set_bits(GT64260_PCI_1_CMD, ((1<<4) | (1<<5) | (1<<9)));
}
} /* gt64260_check_errata() */
/*
*****************************************************************************
*
* General Window Setting Routines
*
*****************************************************************************
*/
static int
gt64260_set_32bit_window(u32 base_addr,
u32 size,
u32 other_bits,
u32 bot_reg,
u32 top_reg)
{
u32 val;
if (size > 0) {
/* Set up the window on the CPU side */
gt_write(bot_reg, (base_addr >> 20) | other_bits);
gt_write(top_reg, (base_addr + size - 1) >> 20);
} else { /* Disable window */
gt_write(top_reg, 0x00000000);
gt_write(bot_reg, 0x00000fff | other_bits);
}
val = gt_read(bot_reg); /* Flush FIFO */
return 0;
} /* gt64260_set_32bit_window() */
static int
gt64260_set_64bit_window(u32 base_addr_hi,
u32 base_addr_lo,
u32 size,
u32 other_bits,
u32 bot_reg_hi,
u32 bot_reg_lo,
u32 top_reg)
{
int rc;
if ((rc = gt64260_set_32bit_window(base_addr_lo,
size,
other_bits,
bot_reg_lo,
top_reg)) == 0) {
gt_write(bot_reg_hi, base_addr_hi);
base_addr_hi = gt_read(bot_reg_hi); /* Flush FIFO */
}
return rc;
} /* gt64260_set_64bit_window() */
/*
*****************************************************************************
*
* CPU Configuration Routines
*
*****************************************************************************
*/
int
gt64260_cpu_scs_set_window(u32 window,
u32 base_addr,
u32 size)
{
static u32
cpu_scs_windows[GT64260_CPU_SCS_DECODE_WINDOWS][2] = {
{ GT64260_CPU_SCS_DECODE_0_BOT, GT64260_CPU_SCS_DECODE_0_TOP },
{ GT64260_CPU_SCS_DECODE_1_BOT, GT64260_CPU_SCS_DECODE_1_TOP },
{ GT64260_CPU_SCS_DECODE_2_BOT, GT64260_CPU_SCS_DECODE_2_TOP },
{ GT64260_CPU_SCS_DECODE_3_BOT, GT64260_CPU_SCS_DECODE_3_TOP },
}; /* cpu_scs_windows[][] */
int rc = -1;
if (window < GT64260_CPU_SCS_DECODE_WINDOWS) {
rc = gt64260_set_32bit_window(base_addr,
size,
0,
cpu_scs_windows[window][0],
cpu_scs_windows[window][1]);
}
return rc;
} /* gt64260_cpu_scs_set_window() */
int
gt64260_cpu_cs_set_window(u32 window,
u32 base_addr,
u32 size)
{
static u32
cpu_cs_windows[GT64260_CPU_CS_DECODE_WINDOWS][2] = {
{ GT64260_CPU_CS_DECODE_0_BOT, GT64260_CPU_CS_DECODE_0_TOP },
{ GT64260_CPU_CS_DECODE_1_BOT, GT64260_CPU_CS_DECODE_1_TOP },
{ GT64260_CPU_CS_DECODE_2_BOT, GT64260_CPU_CS_DECODE_2_TOP },
{ GT64260_CPU_CS_DECODE_3_BOT, GT64260_CPU_CS_DECODE_3_TOP },
}; /* cpu_cs_windows[][] */
int rc = -1;
if (window < GT64260_CPU_CS_DECODE_WINDOWS) {
rc = gt64260_set_32bit_window(base_addr,
size,
0,
cpu_cs_windows[window][0],
cpu_cs_windows[window][1]);
}
return rc;
} /* gt64260_cpu_cs_set_window() */
int
gt64260_cpu_boot_set_window(u32 base_addr,
u32 size)
{
int rc;
rc = gt64260_set_32bit_window(base_addr,
size,
0,
GT64260_CPU_BOOT_CS_DECODE_0_BOT,
GT64260_CPU_BOOT_CS_DECODE_0_TOP);
return rc;
} /* gt64260_cpu_boot_set_window() */
/*
* gt64260_cpu_set_pci_io_window()
*
* Set up a CPU window into PCI I/O or MEM space.
* Always do Read/Modify/Write to window regs.
*/
static int
gt64260_cpu_pci_set_window(u32 cpu_base_addr,
u32 pci_base_addr,
u32 size,
u32 other_bits,
u32 bot_reg,
u32 top_reg,
u32 remap_reg)
{
u32 val;
int rc;
if ((rc = gt64260_set_32bit_window(cpu_base_addr,
size,
other_bits,
bot_reg,
top_reg)) == 0) {
/* Set up CPU->PCI remapping (on lower 32 bits) */
gt_write(remap_reg, pci_base_addr >> 20);
val = gt_read(bot_reg); /* Flush FIFO */
}
return rc;
} /* gt64260_cpu_pci_set_window() */
/*
* gt64260_cpu_set_pci_io_window()
*
* Set up a CPU window into PCI I/O space.
* Always do Read/Modify/Write to window regs.
*/
int
gt64260_cpu_set_pci_io_window(u32 pci_bus,
u32 cpu_base_addr,
u32 pci_base_addr,
u32 size,
u32 swap)
{
/* 2 PCI buses with 1 I/O window each (from CPU point of view) */
static u32
cpu_pci_io_windows[GT64260_PCI_BUSES][3] = {
{ GT64260_CPU_PCI_0_IO_DECODE_BOT,
GT64260_CPU_PCI_0_IO_DECODE_TOP,
GT64260_CPU_PCI_0_IO_REMAP },
{ GT64260_CPU_PCI_1_IO_DECODE_BOT,
GT64260_CPU_PCI_1_IO_DECODE_TOP,
GT64260_CPU_PCI_1_IO_REMAP },
}; /* cpu_pci_io_windows[][] */
int rc = -1;
if (pci_bus < GT64260_PCI_BUSES) {
rc = gt64260_cpu_pci_set_window(cpu_base_addr,
pci_base_addr,
size,
swap,
cpu_pci_io_windows[pci_bus][0],
cpu_pci_io_windows[pci_bus][1],
cpu_pci_io_windows[pci_bus][2]);
}
return rc;
} /* gt64260_cpu_set_pci_io_window() */
/*
* gt64260_cpu_set_pci_mem_window()
*
* Set up a CPU window into PCI MEM space (4 PCI MEM windows per PCI bus).
* Always do Read/Modify/Write to window regs.
*/
int
gt64260_cpu_set_pci_mem_window(u32 pci_bus,
u32 window,
u32 cpu_base_addr,
u32 pci_base_addr_hi,
u32 pci_base_addr_lo,
u32 size,
u32 swap_64bit)
{
/* 2 PCI buses with 4 memory windows each (from CPU point of view) */
static u32
cpu_pci_mem_windows[GT64260_PCI_BUSES][GT64260_PCI_MEM_WINDOWS_PER_BUS][4] = {
{ /* PCI 0 */
{ GT64260_CPU_PCI_0_MEM_0_DECODE_BOT,
GT64260_CPU_PCI_0_MEM_0_DECODE_TOP,
GT64260_CPU_PCI_0_MEM_0_REMAP_HI,
GT64260_CPU_PCI_0_MEM_0_REMAP_LO },
{ GT64260_CPU_PCI_0_MEM_1_DECODE_BOT,
GT64260_CPU_PCI_0_MEM_1_DECODE_TOP,
GT64260_CPU_PCI_0_MEM_1_REMAP_HI,
GT64260_CPU_PCI_0_MEM_1_REMAP_LO },
{ GT64260_CPU_PCI_0_MEM_2_DECODE_BOT,
GT64260_CPU_PCI_0_MEM_2_DECODE_TOP,
GT64260_CPU_PCI_0_MEM_2_REMAP_HI,
GT64260_CPU_PCI_0_MEM_2_REMAP_LO },
{ GT64260_CPU_PCI_0_MEM_3_DECODE_BOT,
GT64260_CPU_PCI_0_MEM_3_DECODE_TOP,
GT64260_CPU_PCI_0_MEM_3_REMAP_HI,
GT64260_CPU_PCI_0_MEM_3_REMAP_LO }
},
{ /* PCI 1 */
{ GT64260_CPU_PCI_1_MEM_0_DECODE_BOT,
GT64260_CPU_PCI_1_MEM_0_DECODE_TOP,
GT64260_CPU_PCI_1_MEM_0_REMAP_HI,
GT64260_CPU_PCI_1_MEM_0_REMAP_LO },
{ GT64260_CPU_PCI_1_MEM_1_DECODE_BOT,
GT64260_CPU_PCI_1_MEM_1_DECODE_TOP,
GT64260_CPU_PCI_1_MEM_1_REMAP_HI,
GT64260_CPU_PCI_1_MEM_1_REMAP_LO },
{ GT64260_CPU_PCI_1_MEM_2_DECODE_BOT,
GT64260_CPU_PCI_1_MEM_2_DECODE_TOP,
GT64260_CPU_PCI_1_MEM_2_REMAP_HI,
GT64260_CPU_PCI_1_MEM_2_REMAP_LO },
{ GT64260_CPU_PCI_1_MEM_3_DECODE_BOT,
GT64260_CPU_PCI_1_MEM_3_DECODE_TOP,
GT64260_CPU_PCI_1_MEM_3_REMAP_HI,
GT64260_CPU_PCI_1_MEM_3_REMAP_LO },
}
}; /* cpu_pci_mem_windows[][][] */
u32 remap_reg, remap;
int rc = -1;
if ((pci_bus < GT64260_PCI_BUSES) &&
(window < GT64260_PCI_MEM_WINDOWS_PER_BUS)) {
if (gt64260_cpu_pci_set_window(
cpu_base_addr,
pci_base_addr_lo,
size,
swap_64bit,
cpu_pci_mem_windows[pci_bus][window][0],
cpu_pci_mem_windows[pci_bus][window][1],
cpu_pci_mem_windows[pci_bus][window][3]) == 0) {
remap_reg = cpu_pci_mem_windows[pci_bus][window][2];
gt_write(remap_reg, pci_base_addr_hi);
remap = gt_read(remap_reg); /* Flush FIFO */
rc = 0;
}
}
return rc;
} /* gt64260_cpu_set_pci_mem_window() */
int
gt64260_cpu_prot_set_window(u32 window,
u32 base_addr,
u32 size,
u32 access_bits)
{
static u32
cpu_prot_windows[GT64260_CPU_PROT_WINDOWS][2] = {
{ GT64260_CPU_PROT_BASE_0, GT64260_CPU_PROT_TOP_0 },
{ GT64260_CPU_PROT_BASE_1, GT64260_CPU_PROT_TOP_1 },
{ GT64260_CPU_PROT_BASE_2, GT64260_CPU_PROT_TOP_2 },
{ GT64260_CPU_PROT_BASE_3, GT64260_CPU_PROT_TOP_3 },
{ GT64260_CPU_PROT_BASE_4, GT64260_CPU_PROT_TOP_4 },
{ GT64260_CPU_PROT_BASE_5, GT64260_CPU_PROT_TOP_5 },
{ GT64260_CPU_PROT_BASE_6, GT64260_CPU_PROT_TOP_6 },
{ GT64260_CPU_PROT_BASE_7, GT64260_CPU_PROT_TOP_7 },
}; /* cpu_prot_windows[][] */
int rc = -1;
if (window < GT64260_CPU_PROT_WINDOWS) {
rc = gt64260_set_32bit_window(base_addr,
size,
access_bits,
cpu_prot_windows[window][0],
cpu_prot_windows[window][1]);
}
return rc;
} /* gt64260_cpu_prot_set_window() */
int
gt64260_cpu_snoop_set_window(u32 window,
u32 base_addr,
u32 size,
u32 snoop_type)
{
static u32
cpu_snoop_windows[GT64260_CPU_SNOOP_WINDOWS][2] = {
{ GT64260_CPU_SNOOP_BASE_0, GT64260_CPU_SNOOP_TOP_0 },
{ GT64260_CPU_SNOOP_BASE_1, GT64260_CPU_SNOOP_TOP_1 },
{ GT64260_CPU_SNOOP_BASE_2, GT64260_CPU_SNOOP_TOP_2 },
{ GT64260_CPU_SNOOP_BASE_3, GT64260_CPU_SNOOP_TOP_3 },
}; /* cpu_snoop_windows[][] */
int rc = -1;
if ((window < GT64260_CPU_SNOOP_WINDOWS) &&
(snoop_type <= GT64260_CPU_SNOOP_WB)) {
rc = gt64260_set_32bit_window(base_addr,
size,
snoop_type,
cpu_snoop_windows[window][0],
cpu_snoop_windows[window][1]);
}
return rc;
} /* gt64260_cpu_snoop_set_window() */
void
gt64260_cpu_disable_all_windows(void)
{
int pci_bus, window;
/* Don't disable SCS windows b/c we need to access system memory */
for (window=0; window<GT64260_CPU_CS_DECODE_WINDOWS; window++) {
gt64260_cpu_cs_set_window(window, 0, 0);
}
gt64260_cpu_boot_set_window(0, 0);
for (pci_bus=0; pci_bus<GT64260_PCI_BUSES; pci_bus++) {
gt64260_cpu_set_pci_io_window(pci_bus, 0, 0, 0, 0);
for (window=0;window<GT64260_PCI_MEM_WINDOWS_PER_BUS;window++) {
gt64260_cpu_set_pci_mem_window(pci_bus,
window,
0, 0, 0, 0, 0);
}
}
for (window=0; window<GT64260_CPU_PROT_WINDOWS; window++) {
gt64260_cpu_prot_set_window(window, 0, 0, 0);
}
for (window=0; window<GT64260_CPU_SNOOP_WINDOWS; window++) {
gt64260_cpu_snoop_set_window(window, 0, 0, 0);
}
return;
} /* gt64260_cpu_disable_all_windows() */
/*
*****************************************************************************
*
* PCI Slave Window Configuration Routines
*
*****************************************************************************
*/
int
gt64260_pci_bar_enable(u32 pci_bus,
u32 enable_bits)
{
u32 reg, val;
int rc = -1;
if (pci_bus < GT64260_PCI_BUSES) {
reg = (pci_bus == 0) ? GT64260_PCI_0_SLAVE_BAR_REG_ENABLES :
GT64260_PCI_1_SLAVE_BAR_REG_ENABLES;
/* Note: '0' enables, '1' disables */
val = gt_read(reg);
val |= 0xffffffff; /* Disable everything by default */
val &= ~enable_bits;
gt_write(reg, val);
gt_read(reg); /* Flush FIFO */
rc = 0;
}
return rc;
} /* gt64260_pci_bar_enable() */
static int
gt64260_pci_slave_set_window(struct pci_controller *hose,
u32 pci_base_addr,
u32 cpu_base_addr,
u32 bar_size,
u32 pci_cfg_fcn,
u32 pci_cfg_hdr_offset,
u32 bar_size_reg,
u32 remap_reg)
{
u32 val;
int devfn;
u8 save_exclude;
pci_base_addr &= 0xfffff000;
cpu_base_addr &= 0xfffff000;
bar_size &= 0xfffff000;
devfn = PCI_DEVFN(0, pci_cfg_fcn);
gt_write(bar_size_reg, (bar_size - 1) & 0xfffff000);
gt_write(remap_reg, cpu_base_addr);
gt_read(remap_reg); /* Flush FIFO */
save_exclude = gt64260_pci_exclude_bridge;
gt64260_pci_exclude_bridge = FALSE;
early_read_config_dword(hose,
hose->first_busno,
devfn,
pci_cfg_hdr_offset,
&val);
val &= 0x0000000f;
early_write_config_dword(hose,
hose->first_busno,
devfn,
pci_cfg_hdr_offset,
pci_base_addr | val);
gt64260_pci_exclude_bridge = save_exclude;
return 0;
} /* gt64260_pci_slave_set_window() */
int
gt64260_pci_slave_scs_set_window(struct pci_controller *hose,
u32 window,
u32 pci_base_addr,
u32 cpu_base_addr,
u32 size)
{
static u32
pci_scs_windows[GT64260_PCI_BUSES][GT64260_PCI_SCS_WINDOWS][4] = {
{ /* PCI 0 */
{ 0, 0x10,
GT64260_PCI_0_SLAVE_SCS_0_SIZE,
GT64260_PCI_0_SLAVE_SCS_0_REMAP },
{ 0, 0x14,
GT64260_PCI_0_SLAVE_SCS_1_SIZE,
GT64260_PCI_0_SLAVE_SCS_1_REMAP },
{ 0, 0x18,
GT64260_PCI_0_SLAVE_SCS_2_SIZE,
GT64260_PCI_0_SLAVE_SCS_2_REMAP },
{ 0, 0x1c,
GT64260_PCI_0_SLAVE_SCS_3_SIZE,
GT64260_PCI_0_SLAVE_SCS_3_REMAP },
},
{ /* PCI 1 */
{ 0, 0x10,
GT64260_PCI_1_SLAVE_SCS_0_SIZE,
GT64260_PCI_1_SLAVE_SCS_0_REMAP },
{ 0, 0x14,
GT64260_PCI_1_SLAVE_SCS_1_SIZE,
GT64260_PCI_1_SLAVE_SCS_1_REMAP },
{ 0, 0x18,
GT64260_PCI_1_SLAVE_SCS_2_SIZE,
GT64260_PCI_1_SLAVE_SCS_2_REMAP },
{ 0, 0x1c,
GT64260_PCI_1_SLAVE_SCS_3_SIZE,
GT64260_PCI_1_SLAVE_SCS_3_REMAP },
}
}; /* pci_scs_windows[][][] */
int pci_bus;
int rc = -1;
if (window < GT64260_PCI_SCS_WINDOWS) {
pci_bus = (hose->first_busno == 0) ? 0 : 1;
rc = gt64260_pci_slave_set_window(
hose,
pci_base_addr,
cpu_base_addr,
size,
pci_scs_windows[pci_bus][window][0],
pci_scs_windows[pci_bus][window][1],
pci_scs_windows[pci_bus][window][2],
pci_scs_windows[pci_bus][window][3]);
}
return rc;
} /* gt64260_pci_slave_scs_set_window() */
int
gt64260_pci_slave_cs_set_window(struct pci_controller *hose,
u32 window,
u32 pci_base_addr,
u32 cpu_base_addr,
u32 size)
{
static u32
pci_cs_windows[GT64260_PCI_BUSES][GT64260_PCI_CS_WINDOWS][4] = {
{ /* PCI 0 */
{ 1, 0x10,
GT64260_PCI_0_SLAVE_CS_0_SIZE,
GT64260_PCI_0_SLAVE_CS_0_REMAP },
{ 1, 0x14,
GT64260_PCI_0_SLAVE_CS_1_SIZE,
GT64260_PCI_0_SLAVE_CS_1_REMAP },
{ 1, 0x18,
GT64260_PCI_0_SLAVE_CS_2_SIZE,
GT64260_PCI_0_SLAVE_CS_2_REMAP },
{ 1, 0x1c,
GT64260_PCI_0_SLAVE_CS_3_SIZE,
GT64260_PCI_0_SLAVE_CS_3_REMAP },
},
{ /* PCI 1 */
{ 1, 0x10,
GT64260_PCI_1_SLAVE_CS_0_SIZE,
GT64260_PCI_1_SLAVE_CS_0_REMAP },
{ 1, 0x14,
GT64260_PCI_1_SLAVE_CS_1_SIZE,
GT64260_PCI_1_SLAVE_CS_1_REMAP },
{ 1, 0x18,
GT64260_PCI_1_SLAVE_CS_2_SIZE,
GT64260_PCI_1_SLAVE_CS_2_REMAP },
{ 1, 0x1c,
GT64260_PCI_1_SLAVE_CS_3_SIZE,
GT64260_PCI_1_SLAVE_CS_3_REMAP },
}
}; /* pci_cs_windows[][][] */
int pci_bus;
int rc = -1;
if (window < GT64260_PCI_CS_WINDOWS) {
pci_bus = (hose->first_busno == 0) ? 0 : 1;
rc = gt64260_pci_slave_set_window(
hose,
pci_base_addr,
cpu_base_addr,
size,
pci_cs_windows[pci_bus][window][0],
pci_cs_windows[pci_bus][window][1],
pci_cs_windows[pci_bus][window][2],
pci_cs_windows[pci_bus][window][3]);
}
return rc;
} /* gt64260_pci_slave_cs_set_window() */
int
gt64260_pci_slave_boot_set_window(struct pci_controller *hose,
u32 pci_base_addr,
u32 cpu_base_addr,
u32 size)
{
int rc;
rc = gt64260_pci_slave_set_window(hose,
pci_base_addr,
cpu_base_addr,
size,
1,
0x20,
GT64260_PCI_1_SLAVE_BOOT_SIZE,
GT64260_PCI_1_SLAVE_BOOT_REMAP);
return rc;
} /* gt64260_pci_slave_boot_set_window() */
int
gt64260_pci_slave_p2p_mem_set_window(struct pci_controller *hose,
u32 window,
u32 pci_base_addr,
u32 other_bus_base_addr,
u32 size)
{
static u32
pci_p2p_mem_windows[GT64260_PCI_BUSES][GT64260_PCI_P2P_MEM_WINDOWS][4]={
{ /* PCI 0 */
{ 2, 0x10,
GT64260_PCI_0_SLAVE_P2P_MEM_0_SIZE,
GT64260_PCI_0_SLAVE_P2P_MEM_0_REMAP_LO },
{ 2, 0x14,
GT64260_PCI_0_SLAVE_P2P_MEM_1_SIZE,
GT64260_PCI_0_SLAVE_P2P_MEM_1_REMAP_LO },
},
{ /* PCI 1 */
{ 2, 0x10,
GT64260_PCI_1_SLAVE_P2P_MEM_0_SIZE,
GT64260_PCI_1_SLAVE_P2P_MEM_0_REMAP_LO },
{ 2, 0x14,
GT64260_PCI_1_SLAVE_P2P_MEM_1_SIZE,
GT64260_PCI_1_SLAVE_P2P_MEM_1_REMAP_LO },
}
}; /* pci_p2p_mem_windows[][][] */
int pci_bus;
int rc = -1;
if (window < GT64260_PCI_P2P_MEM_WINDOWS) {
pci_bus = (hose->first_busno == 0) ? 0 : 1;
rc = gt64260_pci_slave_set_window(
hose,
pci_base_addr,
other_bus_base_addr,
size,
pci_p2p_mem_windows[pci_bus][window][0],
pci_p2p_mem_windows[pci_bus][window][1],
pci_p2p_mem_windows[pci_bus][window][2],
pci_p2p_mem_windows[pci_bus][window][3]);
}
return rc;
} /* gt64260_pci_slave_p2p_mem_set_window() */
int
gt64260_pci_slave_p2p_io_set_window(struct pci_controller *hose,
u32 pci_base_addr,
u32 other_bus_base_addr,
u32 size)
{
int rc;
rc = gt64260_pci_slave_set_window(hose,
pci_base_addr,
other_bus_base_addr,
size,
2,
0x18,
GT64260_PCI_1_SLAVE_P2P_IO_SIZE,
GT64260_PCI_1_SLAVE_P2P_IO_REMAP);
return rc;
} /* gt64260_pci_slave_p2p_io_set_window() */
int
gt64260_pci_slave_dac_scs_set_window(struct pci_controller *hose,
u32 window,
u32 pci_base_addr_hi,
u32 pci_base_addr_lo,
u32 cpu_base_addr,
u32 size)
{
static u32
pci_dac_scs_windows[GT64260_PCI_BUSES][GT64260_PCI_DAC_SCS_WINDOWS][5]={
{ /* PCI 0 */
{ 4, 0x10, 0x14,
GT64260_PCI_0_SLAVE_DAC_SCS_0_SIZE,
GT64260_PCI_0_SLAVE_DAC_SCS_0_REMAP },
{ 4, 0x18, 0x1c,
GT64260_PCI_0_SLAVE_DAC_SCS_1_SIZE,
GT64260_PCI_0_SLAVE_DAC_SCS_1_REMAP },
{ 5, 0x10, 0x14,
GT64260_PCI_0_SLAVE_DAC_SCS_2_SIZE,
GT64260_PCI_0_SLAVE_DAC_SCS_2_REMAP },
{ 5, 0x18, 0x1c,
GT64260_PCI_0_SLAVE_DAC_SCS_3_SIZE,
GT64260_PCI_0_SLAVE_DAC_SCS_3_REMAP },
},
{ /* PCI 1 */
{ 4, 0x10, 0x14,
GT64260_PCI_1_SLAVE_DAC_SCS_0_SIZE,
GT64260_PCI_1_SLAVE_DAC_SCS_0_REMAP },
{ 4, 0x18, 0x1c,
GT64260_PCI_1_SLAVE_DAC_SCS_1_SIZE,
GT64260_PCI_1_SLAVE_DAC_SCS_1_REMAP },
{ 5, 0x10, 0x14,
GT64260_PCI_1_SLAVE_DAC_SCS_2_SIZE,
GT64260_PCI_1_SLAVE_DAC_SCS_2_REMAP },
{ 5, 0x18, 0x1c,
GT64260_PCI_1_SLAVE_DAC_SCS_3_SIZE,
GT64260_PCI_1_SLAVE_DAC_SCS_3_REMAP },
}
}; /* pci_dac_scs_windows[][][] */
int pci_bus;
int rc = -1;
if (window < GT64260_PCI_DAC_SCS_WINDOWS) {
pci_bus = (hose->first_busno == 0) ? 0 : 1;
rc = gt64260_pci_slave_set_window(
hose,
pci_base_addr_lo,
cpu_base_addr,
size,
pci_dac_scs_windows[pci_bus][window][0],
pci_dac_scs_windows[pci_bus][window][1],
pci_dac_scs_windows[pci_bus][window][3],
pci_dac_scs_windows[pci_bus][window][4]);
early_write_config_dword(
hose,
hose->first_busno,
PCI_DEVFN(0, pci_dac_scs_windows[pci_bus][window][0]),
pci_dac_scs_windows[pci_bus][window][2],
pci_base_addr_hi);
}
return rc;
} /* gt64260_pci_slave_dac_scs_set_window() */
int
gt64260_pci_slave_dac_cs_set_window(struct pci_controller *hose,
u32 window,
u32 pci_base_addr_hi,
u32 pci_base_addr_lo,
u32 cpu_base_addr,
u32 size)
{
static u32
pci_dac_cs_windows[GT64260_PCI_BUSES][GT64260_PCI_DAC_CS_WINDOWS][5] = {
{ /* PCI 0 */
{ 6, 0x10, 0x14,
GT64260_PCI_0_SLAVE_DAC_CS_0_SIZE,
GT64260_PCI_0_SLAVE_DAC_CS_0_REMAP },
{ 6, 0x18, 0x1c,
GT64260_PCI_0_SLAVE_DAC_CS_1_SIZE,
GT64260_PCI_0_SLAVE_DAC_CS_1_REMAP },
{ 6, 0x20, 0x24,
GT64260_PCI_0_SLAVE_DAC_CS_2_SIZE,
GT64260_PCI_0_SLAVE_DAC_CS_2_REMAP },
{ 7, 0x10, 0x14,
GT64260_PCI_0_SLAVE_DAC_CS_3_SIZE,
GT64260_PCI_0_SLAVE_DAC_CS_3_REMAP },
},
{ /* PCI 1 */
{ 6, 0x10, 0x14,
GT64260_PCI_1_SLAVE_DAC_CS_0_SIZE,
GT64260_PCI_1_SLAVE_DAC_CS_0_REMAP },
{ 6, 0x18, 0x1c,
GT64260_PCI_1_SLAVE_DAC_CS_1_SIZE,
GT64260_PCI_1_SLAVE_DAC_CS_1_REMAP },
{ 6, 0x20, 0x24,
GT64260_PCI_1_SLAVE_DAC_CS_2_SIZE,
GT64260_PCI_1_SLAVE_DAC_CS_2_REMAP },
{ 7, 0x10, 0x14,
GT64260_PCI_1_SLAVE_DAC_CS_3_SIZE,
GT64260_PCI_1_SLAVE_DAC_CS_3_REMAP },
}
}; /* pci_dac_cs_windows[][][] */
int pci_bus;
int rc = -1;
if (window < GT64260_PCI_CS_WINDOWS) {
pci_bus = (hose->first_busno == 0) ? 0 : 1;
rc = gt64260_pci_slave_set_window(
hose,
pci_base_addr_lo,
cpu_base_addr,
size,
pci_dac_cs_windows[pci_bus][window][0],
pci_dac_cs_windows[pci_bus][window][1],
pci_dac_cs_windows[pci_bus][window][3],
pci_dac_cs_windows[pci_bus][window][4]);
early_write_config_dword(
hose,
hose->first_busno,
PCI_DEVFN(0, pci_dac_cs_windows[pci_bus][window][0]),
pci_dac_cs_windows[pci_bus][window][2],
pci_base_addr_hi);
}
return rc;
} /* gt64260_pci_slave_dac_cs_set_window() */
int
gt64260_pci_slave_dac_boot_set_window(struct pci_controller *hose,
u32 pci_base_addr_hi,
u32 pci_base_addr_lo,
u32 cpu_base_addr,
u32 size)
{
int rc;
rc = gt64260_pci_slave_set_window(hose,
pci_base_addr_lo,
cpu_base_addr,
size,
7,
0x18,
GT64260_PCI_1_SLAVE_BOOT_SIZE,
GT64260_PCI_1_SLAVE_BOOT_REMAP);
early_write_config_dword(hose,
hose->first_busno,
PCI_DEVFN(0, 7),
0x1c,
pci_base_addr_hi);
return rc;
} /* gt64260_pci_slave_dac_boot_set_window() */
int
gt64260_pci_slave_dac_p2p_mem_set_window(struct pci_controller *hose,
u32 window,
u32 pci_base_addr_hi,
u32 pci_base_addr_lo,
u32 other_bus_base_addr,
u32 size)
{
static u32
pci_dac_p2p_mem_windows[GT64260_PCI_BUSES][GT64260_PCI_DAC_P2P_MEM_WINDOWS][5] = {
{ /* PCI 0 */
{ 4, 0x20, 0x24,
GT64260_PCI_0_SLAVE_DAC_P2P_MEM_0_SIZE,
GT64260_PCI_0_SLAVE_DAC_P2P_MEM_0_REMAP_LO },
{ 5, 0x20, 0x24,
GT64260_PCI_0_SLAVE_DAC_P2P_MEM_1_SIZE,
GT64260_PCI_0_SLAVE_DAC_P2P_MEM_1_REMAP_LO },
},
{ /* PCI 1 */
{ 4, 0xa0, 0xa4,
GT64260_PCI_0_SLAVE_DAC_P2P_MEM_0_SIZE,
GT64260_PCI_0_SLAVE_DAC_P2P_MEM_0_REMAP_LO },
{ 5, 0xa0, 0xa4,
GT64260_PCI_0_SLAVE_DAC_P2P_MEM_1_SIZE,
GT64260_PCI_0_SLAVE_DAC_P2P_MEM_1_REMAP_LO },
}
}; /* pci_dac_p2p_windows[][][] */
int pci_bus;
int rc = -1;
if (window < GT64260_PCI_P2P_MEM_WINDOWS) {
pci_bus = (hose->first_busno == 0) ? 0 : 1;
rc = gt64260_pci_slave_set_window(
hose,
pci_base_addr_lo,
other_bus_base_addr,
size,
pci_dac_p2p_mem_windows[pci_bus][window][0],
pci_dac_p2p_mem_windows[pci_bus][window][1],
pci_dac_p2p_mem_windows[pci_bus][window][3],
pci_dac_p2p_mem_windows[pci_bus][window][4]);
early_write_config_dword(
hose,
hose->first_busno,
PCI_DEVFN(0, pci_dac_p2p_mem_windows[pci_bus][window][0]),
pci_dac_p2p_mem_windows[pci_bus][window][2],
pci_base_addr_hi);
}
return rc;
} /* gt64260_pci_slave_dac_p2p_mem_set_window() */
/*
*****************************************************************************
*
* PCI Control Configuration Routines
*
*****************************************************************************
*/
int
gt64260_pci_acc_cntl_set_window(u32 pci_bus,
u32 window,
u32 base_addr_hi,
u32 base_addr_lo,
u32 size,
u32 features)
{
static u32
pci_acc_cntl_windows[GT64260_PCI_BUSES][GT64260_PCI_ACC_CNTL_WINDOWS][3] = {
{ /* PCI 0 */
{ GT64260_PCI_0_ACC_CNTL_0_BASE_HI,
GT64260_PCI_0_ACC_CNTL_0_BASE_LO,
GT64260_PCI_0_ACC_CNTL_0_TOP },
{ GT64260_PCI_0_ACC_CNTL_1_BASE_HI,
GT64260_PCI_0_ACC_CNTL_1_BASE_LO,
GT64260_PCI_0_ACC_CNTL_1_TOP },
{ GT64260_PCI_0_ACC_CNTL_2_BASE_HI,
GT64260_PCI_0_ACC_CNTL_2_BASE_LO,
GT64260_PCI_0_ACC_CNTL_2_TOP },
{ GT64260_PCI_0_ACC_CNTL_3_BASE_HI,
GT64260_PCI_0_ACC_CNTL_3_BASE_LO,
GT64260_PCI_0_ACC_CNTL_3_TOP },
{ GT64260_PCI_0_ACC_CNTL_4_BASE_HI,
GT64260_PCI_0_ACC_CNTL_4_BASE_LO,
GT64260_PCI_0_ACC_CNTL_4_TOP },
{ GT64260_PCI_0_ACC_CNTL_5_BASE_HI,
GT64260_PCI_0_ACC_CNTL_5_BASE_LO,
GT64260_PCI_0_ACC_CNTL_5_TOP },
{ GT64260_PCI_0_ACC_CNTL_6_BASE_HI,
GT64260_PCI_0_ACC_CNTL_6_BASE_LO,
GT64260_PCI_0_ACC_CNTL_6_TOP },
{ GT64260_PCI_0_ACC_CNTL_7_BASE_HI,
GT64260_PCI_0_ACC_CNTL_7_BASE_LO,
GT64260_PCI_0_ACC_CNTL_7_TOP },
},
{ /* PCI 1 */
{ GT64260_PCI_1_ACC_CNTL_0_BASE_HI,
GT64260_PCI_1_ACC_CNTL_0_BASE_LO,
GT64260_PCI_1_ACC_CNTL_0_TOP },
{ GT64260_PCI_1_ACC_CNTL_1_BASE_HI,
GT64260_PCI_1_ACC_CNTL_1_BASE_LO,
GT64260_PCI_1_ACC_CNTL_1_TOP },
{ GT64260_PCI_1_ACC_CNTL_2_BASE_HI,
GT64260_PCI_1_ACC_CNTL_2_BASE_LO,
GT64260_PCI_1_ACC_CNTL_2_TOP },
{ GT64260_PCI_1_ACC_CNTL_3_BASE_HI,
GT64260_PCI_1_ACC_CNTL_3_BASE_LO,
GT64260_PCI_1_ACC_CNTL_3_TOP },
{ GT64260_PCI_1_ACC_CNTL_4_BASE_HI,
GT64260_PCI_1_ACC_CNTL_4_BASE_LO,
GT64260_PCI_1_ACC_CNTL_4_TOP },
{ GT64260_PCI_1_ACC_CNTL_5_BASE_HI,
GT64260_PCI_1_ACC_CNTL_5_BASE_LO,
GT64260_PCI_1_ACC_CNTL_5_TOP },
{ GT64260_PCI_1_ACC_CNTL_6_BASE_HI,
GT64260_PCI_1_ACC_CNTL_6_BASE_LO,
GT64260_PCI_1_ACC_CNTL_6_TOP },
{ GT64260_PCI_1_ACC_CNTL_7_BASE_HI,
GT64260_PCI_1_ACC_CNTL_7_BASE_LO,
GT64260_PCI_1_ACC_CNTL_7_TOP },
}
}; /* pci_acc_cntl_windows[][][] */
int rc = -1;
if ((pci_bus < GT64260_PCI_BUSES) &&
(window < GT64260_PCI_ACC_CNTL_WINDOWS)) {
rc = gt64260_set_64bit_window(
base_addr_hi,
base_addr_lo,
size,
features,
pci_acc_cntl_windows[pci_bus][window][0],
pci_acc_cntl_windows[pci_bus][window][1],
pci_acc_cntl_windows[pci_bus][window][2]);
}
return rc;
} /* gt64260_pci_acc_cntl_set_window() */
int
gt64260_pci_snoop_set_window(u32 pci_bus,
u32 window,
u32 base_addr_hi,
u32 base_addr_lo,
u32 size,
u32 snoop_type)
{
static u32
pci_snoop_windows[GT64260_PCI_BUSES][GT64260_PCI_SNOOP_WINDOWS][3] = {
{ /* PCI 0 */
{ GT64260_PCI_0_SNOOP_0_BASE_HI,
GT64260_PCI_0_SNOOP_0_BASE_LO,
GT64260_PCI_0_SNOOP_0_TOP },
{ GT64260_PCI_0_SNOOP_1_BASE_HI,
GT64260_PCI_0_SNOOP_1_BASE_LO,
GT64260_PCI_0_SNOOP_1_TOP },
{ GT64260_PCI_0_SNOOP_2_BASE_HI,
GT64260_PCI_0_SNOOP_2_BASE_LO,
GT64260_PCI_0_SNOOP_2_TOP },
{ GT64260_PCI_0_SNOOP_3_BASE_HI,
GT64260_PCI_0_SNOOP_3_BASE_LO,
GT64260_PCI_0_SNOOP_3_TOP },
},
{ /* PCI 1 */
{ GT64260_PCI_1_SNOOP_0_BASE_HI,
GT64260_PCI_1_SNOOP_0_BASE_LO,
GT64260_PCI_1_SNOOP_0_TOP },
{ GT64260_PCI_1_SNOOP_1_BASE_HI,
GT64260_PCI_1_SNOOP_1_BASE_LO,
GT64260_PCI_1_SNOOP_1_TOP },
{ GT64260_PCI_1_SNOOP_2_BASE_HI,
GT64260_PCI_1_SNOOP_2_BASE_LO,
GT64260_PCI_1_SNOOP_2_TOP },
{ GT64260_PCI_1_SNOOP_3_BASE_HI,
GT64260_PCI_1_SNOOP_3_BASE_LO,
GT64260_PCI_1_SNOOP_3_TOP },
},
}; /* pci_snoop_windows[][][] */
int rc = -1;
if ((pci_bus < GT64260_PCI_BUSES) &&
(window < GT64260_PCI_SNOOP_WINDOWS)) {
rc = gt64260_set_64bit_window(
base_addr_hi,
base_addr_lo,
size,
snoop_type,
pci_snoop_windows[pci_bus][window][0],
pci_snoop_windows[pci_bus][window][1],
pci_snoop_windows[pci_bus][window][2]);
}
return rc;
} /* gt64260_pci_snoop_set_window() */
/*
*****************************************************************************
*
* 64260's Register Base Address Routines
*
*****************************************************************************
*/
/*
* gt64260_remap_bridge_regs()
*
* Move the bridge's register to the specified base address.
* Assume that there are no other windows overlapping this area and that
* all but the highest 3 nibbles are 0.
*/
int
gt64260_set_base(u32 new_base)
{
u32 val;
int limit = 100000;
int rc = 0;
val = gt_read(GT64260_INTERNAL_SPACE_DECODE);
val = (new_base >> 20) | (val & 0xffff0000);
gt_write(GT64260_INTERNAL_SPACE_DECODE, val);
iounmap((void *)gt64260_base);
gt64260_base = (u32)ioremap((new_base & 0xfff00000),
GT64260_INTERNAL_SPACE_SIZE);
do { /* Wait for bridge to move its regs */
val = gt_read(GT64260_INTERNAL_SPACE_DECODE);
} while ((val != 0xffffffff) && (limit-- > 0));
if (limit <= 0) {
rc = -1;
}
return rc;
} /* gt64260_remap_bridge_regs() */
/*
* gt64260_get_base()
*
* Return the current virtual base address of the 64260's registers.
*/
int
gt64260_get_base(u32 *base)
{
*base = gt64260_base;
return 0;
} /* gt64260_remap_bridge_regs() */
/*
*****************************************************************************
*
* Exclude PCI config space access to bridge itself
*
*****************************************************************************
*/
/*
* gt64260_exclude_pci_device()
*
* This routine causes the PCI subsystem to skip the PCI device in slot 0
* (which is the 64260 itself) unless explicitly allowed.
*/
int
gt64260_pci_exclude_device(u8 bus, u8 devfn)
{
struct pci_controller *hose;
hose = pci_bus_to_hose(bus);
/* Skip slot 0 and 1 on both hoses */
if ((gt64260_pci_exclude_bridge == TRUE) &&
(PCI_SLOT(devfn) == 0) &&
(hose->first_busno == bus)) {
return PCIBIOS_DEVICE_NOT_FOUND;
}
else {
return PCIBIOS_SUCCESSFUL;
}
} /* gt64260_pci_exclude_device() */
#if defined(CONFIG_SERIAL_TEXT_DEBUG)
/*
* gt64260_putc()
*
* Dump a character out the MPSC port for gt64260_mpsc_progress
* this assumes the baud rate has already been set up and the
* MPSC initialized by the bootloader or firmware.
*/
static inline void
gt_putc(char c){
mb();
gt_write(GT64260_MPSC_0_CHR_1, c);
mb();
gt_write(GT64260_MPSC_0_CHR_2, 0x200);
mb();
udelay(10000);
}
void
puthex(unsigned long val){
int i;
for (i = 7; i >= 0; i--) {
gt_putc("0123456789ABCDEF"[(val>>28) & 0x0f]);
val <<= 4;
}
gt_putc('\r');
gt_putc('\n');
}
void
gt64260_mpsc_progress(char *s, unsigned short hex){
/* spit stuff out the 64260 mpsc */
volatile char c;
while ((c = *s++) != 0){
gt_putc(c);
if ( c == '\n' ) gt_putc('\r');
}
gt_putc('\n');
gt_putc('\r');
return;
}
#endif /* CONFIG_DEBUG_TEXT */
......@@ -3,7 +3,7 @@
*
* Interrupt controller support for Galileo's GT64260.
*
* Author: Chris Zankel <chris@mvista.com>
* Author: Chris Zankel <source@mvista.com>
* Modified by: Mark A. Greer <mgreer@mvista.com>
*
* Based on sources from Rabeeh Khoury / Galileo Technology
......@@ -34,6 +34,7 @@
#include <linux/stddef.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/stddef.h>
......@@ -43,8 +44,11 @@
#include <asm/io.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/gt64260.h>
#include <asm/mv64x60.h>
#define CPU_INTR_STR "gt64260 cpu interface error"
#define PCI0_INTR_STR "gt64260 pci 0 error"
#define PCI1_INTR_STR "gt64260 pci 1 error"
/* ========================== forward declaration ========================== */
......@@ -54,63 +58,55 @@ static void gt64260_mask_irq(unsigned int);
/* ========================== local declarations =========================== */
struct hw_interrupt_type gt64260_pic = {
" GT64260_PIC ", /* typename */
NULL, /* startup */
NULL, /* shutdown */
gt64260_unmask_irq, /* enable */
gt64260_mask_irq, /* disable */
gt64260_mask_irq, /* ack */
NULL, /* end */
NULL /* set_affinity */
.typename = " gt64260_pic ",
.enable = gt64260_unmask_irq,
.disable = gt64260_mask_irq,
.ack = gt64260_mask_irq,
.end = gt64260_unmask_irq,
};
u32 gt64260_irq_base = 0; /* GT64260 handles the next 96 IRQs from here */
u32 gt64260_irq_base = 0; /* GT64260 handles the next 96 IRQs from here */
static struct mv64x60_handle bh;
/* gt64260_init_irq()
*
* This function initializes the interrupt controller. It assigns
* all interrupts from IRQ0 to IRQ95 to the gt64260 interrupt controller.
*
* Input Variable(s):
* None.
*
* Outpu. Variable(s):
* None.
*
* Returns:
* void
*
* Note:
* We register all GPP inputs as interrupt source, but disable them.
*/
__init void
void __init
gt64260_init_irq(void)
{
int i;
if ( ppc_md.progress ) ppc_md.progress("gt64260_init_irq: enter", 0x0);
if (ppc_md.progress)
ppc_md.progress("gt64260_init_irq: enter", 0x0);
bh.v_base = mv64x60_get_bridge_vbase();
ppc_cached_irq_mask[0] = 0;
ppc_cached_irq_mask[1] = 0x0f000000; /* Enable GPP intrs */
ppc_cached_irq_mask[1] = 0x0f000000; /* Enable GPP intrs */
ppc_cached_irq_mask[2] = 0;
/* disable all interrupts and clear current interrupts */
gt_write(GT64260_GPP_INTR_MASK, ppc_cached_irq_mask[2]);
gt_write(GT64260_GPP_INTR_CAUSE,0);
gt_write(GT64260_IC_CPU_INTR_MASK_LO, ppc_cached_irq_mask[0]);
gt_write(GT64260_IC_CPU_INTR_MASK_HI, ppc_cached_irq_mask[1]);
mv64x60_write(&bh, MV64x60_GPP_INTR_MASK, ppc_cached_irq_mask[2]);
mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, 0);
mv64x60_write(&bh, GT64260_IC_CPU_INTR_MASK_LO, ppc_cached_irq_mask[0]);
mv64x60_write(&bh, GT64260_IC_CPU_INTR_MASK_HI, ppc_cached_irq_mask[1]);
/* use the gt64260 for all (possible) interrupt sources */
for( i = gt64260_irq_base; i < (gt64260_irq_base + 96); i++ ) {
for (i = gt64260_irq_base; i < (gt64260_irq_base + 96); i++)
irq_desc[i].handler = &gt64260_pic;
}
if ( ppc_md.progress ) ppc_md.progress("gt64260_init_irq: exit", 0x0);
if (ppc_md.progress)
ppc_md.progress("gt64260_init_irq: exit", 0x0);
}
/* gt64260_get_irq()
/*
* gt64260_get_irq()
*
* This function returns the lowest interrupt number of all interrupts that
* are currently asserted.
......@@ -123,7 +119,6 @@ gt64260_init_irq(void)
*
* Returns:
* int <interrupt number> or -2 (bogus interrupt)
*
*/
int
gt64260_get_irq(struct pt_regs *regs)
......@@ -131,38 +126,41 @@ gt64260_get_irq(struct pt_regs *regs)
int irq;
int irq_gpp;
irq = gt_read(GT64260_IC_MAIN_CAUSE_LO);
irq = mv64x60_read(&bh, GT64260_IC_MAIN_CAUSE_LO);
irq = __ilog2((irq & 0x3dfffffe) & ppc_cached_irq_mask[0]);
if (irq == -1) {
irq = gt_read(GT64260_IC_MAIN_CAUSE_HI);
irq = mv64x60_read(&bh, GT64260_IC_MAIN_CAUSE_HI);
irq = __ilog2((irq & 0x0f000db7) & ppc_cached_irq_mask[1]);
if (irq == -1) {
irq = -2; /* bogus interrupt, should never happen */
} else {
if (irq == -1)
irq = -2; /* bogus interrupt, should never happen */
else {
if (irq >= 24) {
irq_gpp = gt_read(GT64260_GPP_INTR_CAUSE);
irq_gpp = mv64x60_read(&bh,
MV64x60_GPP_INTR_CAUSE);
irq_gpp = __ilog2(irq_gpp &
ppc_cached_irq_mask[2]);
ppc_cached_irq_mask[2]);
if (irq_gpp == -1) {
if (irq_gpp == -1)
irq = -2;
} else {
else {
irq = irq_gpp + 64;
gt_write(GT64260_GPP_INTR_CAUSE, ~(1<<(irq-64)));
mv64x60_write(&bh,
MV64x60_GPP_INTR_CAUSE,
~(1 << (irq - 64)));
}
} else {
} else
irq += 32;
}
}
}
if( irq < 0 ) {
return( irq );
} else {
return( gt64260_irq_base + irq );
}
(void)mv64x60_read(&bh, MV64x60_GPP_INTR_CAUSE);
if (irq < 0)
return (irq);
else
return (gt64260_irq_base + irq);
}
/* gt64260_unmask_irq()
......@@ -178,32 +176,29 @@ gt64260_get_irq(struct pt_regs *regs)
* Returns:
* void
*/
static void
gt64260_unmask_irq(unsigned int irq)
{
irq -= gt64260_irq_base;
if (irq > 31) {
if (irq > 63) {
/* unmask GPP irq */
gt_write(GT64260_GPP_INTR_MASK,
ppc_cached_irq_mask[2] |= (1<<(irq-64)));
} else {
/* mask high interrupt register */
gt_write(GT64260_IC_CPU_INTR_MASK_HI,
ppc_cached_irq_mask[1] |= (1<<(irq-32)));
}
} else {
/* mask low interrupt register */
gt_write(GT64260_IC_CPU_INTR_MASK_LO,
ppc_cached_irq_mask[0] |= (1<<irq));
}
}
if (irq > 31)
if (irq > 63) /* unmask GPP irq */
mv64x60_write(&bh, MV64x60_GPP_INTR_MASK,
ppc_cached_irq_mask[2] |= (1 << (irq - 64)));
else /* mask high interrupt register */
mv64x60_write(&bh, GT64260_IC_CPU_INTR_MASK_HI,
ppc_cached_irq_mask[1] |= (1 << (irq - 32)));
else /* mask low interrupt register */
mv64x60_write(&bh, GT64260_IC_CPU_INTR_MASK_LO,
ppc_cached_irq_mask[0] |= (1 << irq));
(void)mv64x60_read(&bh, MV64x60_GPP_INTR_MASK);
return;
}
/* gt64260_mask_irq()
*
* This funktion disables the requested interrupt.
* This function disables the requested interrupt.
*
* Input Variable(s):
* unsigned int interrupt number (IRQ0...IRQ95).
......@@ -214,28 +209,110 @@ gt64260_unmask_irq(unsigned int irq)
* Returns:
* void
*/
static void
gt64260_mask_irq(unsigned int irq)
{
irq -= gt64260_irq_base;
if (irq > 31) {
if (irq > 63) {
/* mask GPP irq */
gt_write(GT64260_GPP_INTR_MASK,
ppc_cached_irq_mask[2] &= ~(1<<(irq-64)));
} else {
/* mask high interrupt register */
gt_write(GT64260_IC_CPU_INTR_MASK_HI,
ppc_cached_irq_mask[1] &= ~(1<<(irq-32)));
}
} else {
/* mask low interrupt register */
gt_write(GT64260_IC_CPU_INTR_MASK_LO,
ppc_cached_irq_mask[0] &= ~(1<<irq));
}
if (irq == 36) { /* Seems necessary for SDMA interrupts */
udelay(1);
if (irq > 31)
if (irq > 63) /* mask GPP irq */
mv64x60_write(&bh, MV64x60_GPP_INTR_MASK,
ppc_cached_irq_mask[2] &= ~(1 << (irq - 64)));
else /* mask high interrupt register */
mv64x60_write(&bh, GT64260_IC_CPU_INTR_MASK_HI,
ppc_cached_irq_mask[1] &= ~(1 << (irq - 32)));
else /* mask low interrupt register */
mv64x60_write(&bh, GT64260_IC_CPU_INTR_MASK_LO,
ppc_cached_irq_mask[0] &= ~(1 << irq));
(void)mv64x60_read(&bh, MV64x60_GPP_INTR_MASK);
return;
}
static irqreturn_t
gt64260_cpu_error_int_handler(int irq, void *dev_id, struct pt_regs *regs)
{
printk(KERN_ERR "gt64260_cpu_error_int_handler: %s 0x%08x\n",
"Error on CPU interface - Cause regiser",
mv64x60_read(&bh, MV64x60_CPU_ERR_CAUSE));
printk(KERN_ERR "\tCPU error register dump:\n");
printk(KERN_ERR "\tAddress low 0x%08x\n",
mv64x60_read(&bh, MV64x60_CPU_ERR_ADDR_LO));
printk(KERN_ERR "\tAddress high 0x%08x\n",
mv64x60_read(&bh, MV64x60_CPU_ERR_ADDR_HI));
printk(KERN_ERR "\tData low 0x%08x\n",
mv64x60_read(&bh, MV64x60_CPU_ERR_DATA_LO));
printk(KERN_ERR "\tData high 0x%08x\n",
mv64x60_read(&bh, MV64x60_CPU_ERR_DATA_HI));
printk(KERN_ERR "\tParity 0x%08x\n",
mv64x60_read(&bh, MV64x60_CPU_ERR_PARITY));
mv64x60_write(&bh, MV64x60_CPU_ERR_CAUSE, 0);
return IRQ_HANDLED;
}
static irqreturn_t
gt64260_pci_error_int_handler(int irq, void *dev_id, struct pt_regs *regs)
{
u32 val;
unsigned int pci_bus = (unsigned int)dev_id;
if (pci_bus == 0) { /* Error on PCI 0 */
val = mv64x60_read(&bh, MV64x60_PCI0_ERR_CAUSE);
printk(KERN_ERR "%s: Error in PCI %d Interface\n",
"gt64260_pci_error_int_handler", pci_bus);
printk(KERN_ERR "\tPCI %d error register dump:\n", pci_bus);
printk(KERN_ERR "\tCause register 0x%08x\n", val);
printk(KERN_ERR "\tAddress Low 0x%08x\n",
mv64x60_read(&bh, MV64x60_PCI0_ERR_ADDR_LO));
printk(KERN_ERR "\tAddress High 0x%08x\n",
mv64x60_read(&bh, MV64x60_PCI0_ERR_ADDR_HI));
printk(KERN_ERR "\tAttribute 0x%08x\n",
mv64x60_read(&bh, MV64x60_PCI0_ERR_DATA_LO));
printk(KERN_ERR "\tCommand 0x%08x\n",
mv64x60_read(&bh, MV64x60_PCI0_ERR_CMD));
mv64x60_write(&bh, MV64x60_PCI0_ERR_CAUSE, ~val);
}
if (pci_bus == 1) { /* Error on PCI 1 */
val = mv64x60_read(&bh, MV64x60_PCI1_ERR_CAUSE);
printk(KERN_ERR "%s: Error in PCI %d Interface\n",
"gt64260_pci_error_int_handler", pci_bus);
printk(KERN_ERR "\tPCI %d error register dump:\n", pci_bus);
printk(KERN_ERR "\tCause register 0x%08x\n", val);
printk(KERN_ERR "\tAddress Low 0x%08x\n",
mv64x60_read(&bh, MV64x60_PCI1_ERR_ADDR_LO));
printk(KERN_ERR "\tAddress High 0x%08x\n",
mv64x60_read(&bh, MV64x60_PCI1_ERR_ADDR_HI));
printk(KERN_ERR "\tAttribute 0x%08x\n",
mv64x60_read(&bh, MV64x60_PCI1_ERR_DATA_LO));
printk(KERN_ERR "\tCommand 0x%08x\n",
mv64x60_read(&bh, MV64x60_PCI1_ERR_CMD));
mv64x60_write(&bh, MV64x60_PCI1_ERR_CAUSE, ~val);
}
return IRQ_HANDLED;
}
static int __init
gt64260_register_hdlrs(void)
{
/* Register CPU interface error interrupt handler */
request_irq(MV64x60_IRQ_CPU_ERR, gt64260_cpu_error_int_handler,
SA_INTERRUPT, CPU_INTR_STR, 0);
mv64x60_write(&bh, MV64x60_CPU_ERR_MASK, 0);
mv64x60_write(&bh, MV64x60_CPU_ERR_MASK, 0x000000fe);
/* Register PCI 0 error interrupt handler */
request_irq(MV64360_IRQ_PCI0, gt64260_pci_error_int_handler,
SA_INTERRUPT, PCI0_INTR_STR, (void *)0);
mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, 0);
mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, 0x003c0c24);
/* Register PCI 1 error interrupt handler */
request_irq(MV64360_IRQ_PCI1, gt64260_pci_error_int_handler,
SA_INTERRUPT, PCI1_INTR_STR, (void *)1);
mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, 0);
mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, 0x003c0c24);
return 0;
}
arch_initcall(gt64260_register_hdlrs);
/*
* arch/ppc/kernel/mv64360_pic.c
*
* Interrupt controller support for Marvell's MV64360.
*
* Author: Rabeeh Khoury <rabeeh@galileo.co.il>
* Based on MV64360 PIC written by
* Chris Zankel <chris@mvista.com>
* Mark A. Greer <mgreer@mvista.com>
*
* Copyright 2004 MontaVista Software, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
/*
* This file contains the specific functions to support the MV64360
* interrupt controller.
*
* The MV64360 has two main interrupt registers (high and low) that
* summarizes the interrupts generated by the units of the MV64360.
* Each bit is assigned to an interrupt number, where the low register
* are assigned from IRQ0 to IRQ31 and the high cause register
* from IRQ32 to IRQ63
* The GPP (General Purpose Pins) interrupts are assigned from IRQ64 (GPP0)
* to IRQ95 (GPP31).
* get_irq() returns the lowest interrupt number that is currently asserted.
*
* Note:
* - This driver does not initialize the GPP when used as an interrupt
* input.
*/
#include <linux/stddef.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/stddef.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/mv64x60.h>
#ifdef CONFIG_IRQ_ALL_CPUS
#error "The mv64360 does not support distribution of IRQs on all CPUs"
#endif
/* ========================== forward declaration ========================== */
static void mv64360_unmask_irq(unsigned int);
static void mv64360_mask_irq(unsigned int);
static irqreturn_t mv64360_cpu_error_int_handler(int, void *, struct pt_regs *);
static irqreturn_t mv64360_sram_error_int_handler(int, void *,
struct pt_regs *);
static irqreturn_t mv64360_pci_error_int_handler(int, void *, struct pt_regs *);
/* ========================== local declarations =========================== */
struct hw_interrupt_type mv64360_pic = {
.typename = " mv64360_pic ",
.enable = mv64360_unmask_irq,
.disable = mv64360_mask_irq,
.ack = mv64360_mask_irq,
.end = mv64360_unmask_irq,
};
#define CPU_INTR_STR "mv64360 cpu interface error"
#define SRAM_INTR_STR "mv64360 internal sram error"
#define PCI0_INTR_STR "mv64360 pci 0 error"
#define PCI1_INTR_STR "mv64360 pci 1 error"
static struct mv64x60_handle bh;
u32 mv64360_irq_base = 0; /* MV64360 handles the next 96 IRQs from here */
/* mv64360_init_irq()
*
* This function initializes the interrupt controller. It assigns
* all interrupts from IRQ0 to IRQ95 to the mv64360 interrupt controller.
*
* Input Variable(s):
* None.
*
* Outpu. Variable(s):
* None.
*
* Returns:
* void
*
* Note:
* We register all GPP inputs as interrupt source, but disable them.
*/
void __init
mv64360_init_irq(void)
{
int i;
if (ppc_md.progress)
ppc_md.progress("mv64360_init_irq: enter", 0x0);
bh.v_base = mv64x60_get_bridge_vbase();
ppc_cached_irq_mask[0] = 0;
ppc_cached_irq_mask[1] = 0x0f000000; /* Enable GPP intrs */
ppc_cached_irq_mask[2] = 0;
/* disable all interrupts and clear current interrupts */
mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, 0);
mv64x60_write(&bh, MV64x60_GPP_INTR_MASK, ppc_cached_irq_mask[2]);
mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_LO,ppc_cached_irq_mask[0]);
mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_HI,ppc_cached_irq_mask[1]);
/* All interrupts are level interrupts */
for (i = mv64360_irq_base; i < (mv64360_irq_base + 96); i++) {
irq_desc[i].status |= IRQ_LEVEL;
irq_desc[i].handler = &mv64360_pic;
}
if (ppc_md.progress)
ppc_md.progress("mv64360_init_irq: exit", 0x0);
}
/* mv64360_get_irq()
*
* This function returns the lowest interrupt number of all interrupts that
* are currently asserted.
*
* Input Variable(s):
* struct pt_regs* not used
*
* Output Variable(s):
* None.
*
* Returns:
* int <interrupt number> or -2 (bogus interrupt)
*
*/
int
mv64360_get_irq(struct pt_regs *regs)
{
int irq;
int irq_gpp;
#ifdef CONFIG_SMP
/*
* Second CPU gets only doorbell (message) interrupts.
* The doorbell interrupt is BIT28 in the main interrupt low cause reg.
*/
int cpu_nr = smp_processor_id();
if (cpu_nr == 1) {
if (!(mv64x60_read(&bh, MV64360_IC_MAIN_CAUSE_LO) & (1 << 28)))
return -1;
return 28;
}
#endif
irq = mv64x60_read(&bh, MV64360_IC_MAIN_CAUSE_LO);
irq = __ilog2((irq & 0x3dfffffe) & ppc_cached_irq_mask[0]);
if (irq == -1) {
irq = mv64x60_read(&bh, MV64360_IC_MAIN_CAUSE_HI);
irq = __ilog2((irq & 0x1f0003f7) & ppc_cached_irq_mask[1]);
if (irq == -1)
irq = -2; /* bogus interrupt, should never happen */
else {
if ((irq >= 24) && (irq < 28)) {
irq_gpp = mv64x60_read(&bh,
MV64x60_GPP_INTR_CAUSE);
irq_gpp = __ilog2(irq_gpp &
ppc_cached_irq_mask[2]);
if (irq_gpp == -1)
irq = -2;
else {
irq = irq_gpp + 64;
mv64x60_write(&bh,
MV64x60_GPP_INTR_CAUSE,
~(1 << (irq - 64)));
}
}
else
irq += 32;
}
}
(void)mv64x60_read(&bh, MV64x60_GPP_INTR_CAUSE);
if (irq < 0)
return (irq);
else
return (mv64360_irq_base + irq);
}
/* mv64360_unmask_irq()
*
* This function enables an interrupt.
*
* Input Variable(s):
* unsigned int interrupt number (IRQ0...IRQ95).
*
* Output Variable(s):
* None.
*
* Returns:
* void
*/
static void
mv64360_unmask_irq(unsigned int irq)
{
#ifdef CONFIG_SMP
/* second CPU gets only doorbell interrupts */
if ((irq - mv64360_irq_base) == 28) {
mv64x60_set_bits(&bh, MV64360_IC_CPU1_INTR_MASK_LO, (1 << 28));
return;
}
#endif
irq -= mv64360_irq_base;
if (irq > 31) {
if (irq > 63) /* unmask GPP irq */
mv64x60_write(&bh, MV64x60_GPP_INTR_MASK,
ppc_cached_irq_mask[2] |= (1 << (irq - 64)));
else /* mask high interrupt register */
mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_HI,
ppc_cached_irq_mask[1] |= (1 << (irq - 32)));
}
else /* mask low interrupt register */
mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_LO,
ppc_cached_irq_mask[0] |= (1 << irq));
(void)mv64x60_read(&bh, MV64x60_GPP_INTR_MASK);
return;
}
/* mv64360_mask_irq()
*
* This function disables the requested interrupt.
*
* Input Variable(s):
* unsigned int interrupt number (IRQ0...IRQ95).
*
* Output Variable(s):
* None.
*
* Returns:
* void
*/
static void
mv64360_mask_irq(unsigned int irq)
{
#ifdef CONFIG_SMP
if ((irq - mv64360_irq_base) == 28) {
mv64x60_clr_bits(&bh, MV64360_IC_CPU1_INTR_MASK_LO, (1 << 28));
return;
}
#endif
irq -= mv64360_irq_base;
if (irq > 31) {
if (irq > 63) /* mask GPP irq */
mv64x60_write(&bh, MV64x60_GPP_INTR_MASK,
ppc_cached_irq_mask[2] &= ~(1 << (irq - 64)));
else /* mask high interrupt register */
mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_HI,
ppc_cached_irq_mask[1] &= ~(1 << (irq - 32)));
}
else /* mask low interrupt register */
mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_LO,
ppc_cached_irq_mask[0] &= ~(1 << irq));
(void)mv64x60_read(&bh, MV64x60_GPP_INTR_MASK);
return;
}
static irqreturn_t
mv64360_cpu_error_int_handler(int irq, void *dev_id, struct pt_regs *regs)
{
printk(KERN_ERR "mv64360_cpu_error_int_handler: %s 0x%08x\n",
"Error on CPU interface - Cause regiser",
mv64x60_read(&bh, MV64x60_CPU_ERR_CAUSE));
printk(KERN_ERR "\tCPU error register dump:\n");
printk(KERN_ERR "\tAddress low 0x%08x\n",
mv64x60_read(&bh, MV64x60_CPU_ERR_ADDR_LO));
printk(KERN_ERR "\tAddress high 0x%08x\n",
mv64x60_read(&bh, MV64x60_CPU_ERR_ADDR_HI));
printk(KERN_ERR "\tData low 0x%08x\n",
mv64x60_read(&bh, MV64x60_CPU_ERR_DATA_LO));
printk(KERN_ERR "\tData high 0x%08x\n",
mv64x60_read(&bh, MV64x60_CPU_ERR_DATA_HI));
printk(KERN_ERR "\tParity 0x%08x\n",
mv64x60_read(&bh, MV64x60_CPU_ERR_PARITY));
mv64x60_write(&bh, MV64x60_CPU_ERR_CAUSE, 0);
return IRQ_HANDLED;
}
static irqreturn_t
mv64360_sram_error_int_handler(int irq, void *dev_id, struct pt_regs *regs)
{
printk(KERN_ERR "mv64360_sram_error_int_handler: %s 0x%08x\n",
"Error in internal SRAM - Cause register",
mv64x60_read(&bh, MV64360_SRAM_ERR_CAUSE));
printk(KERN_ERR "\tSRAM error register dump:\n");
printk(KERN_ERR "\tAddress Low 0x%08x\n",
mv64x60_read(&bh, MV64360_SRAM_ERR_ADDR_LO));
printk(KERN_ERR "\tAddress High 0x%08x\n",
mv64x60_read(&bh, MV64360_SRAM_ERR_ADDR_HI));
printk(KERN_ERR "\tData Low 0x%08x\n",
mv64x60_read(&bh, MV64360_SRAM_ERR_DATA_LO));
printk(KERN_ERR "\tData High 0x%08x\n",
mv64x60_read(&bh, MV64360_SRAM_ERR_DATA_HI));
printk(KERN_ERR "\tParity 0x%08x\n",
mv64x60_read(&bh, MV64360_SRAM_ERR_PARITY));
mv64x60_write(&bh, MV64360_SRAM_ERR_CAUSE, 0);
return IRQ_HANDLED;
}
static irqreturn_t
mv64360_pci_error_int_handler(int irq, void *dev_id, struct pt_regs *regs)
{
u32 val;
unsigned int pci_bus = (unsigned int)dev_id;
if (pci_bus == 0) { /* Error on PCI 0 */
val = mv64x60_read(&bh, MV64x60_PCI0_ERR_CAUSE);
printk(KERN_ERR "%s: Error in PCI %d Interface\n",
"mv64360_pci_error_int_handler", pci_bus);
printk(KERN_ERR "\tPCI %d error register dump:\n", pci_bus);
printk(KERN_ERR "\tCause register 0x%08x\n", val);
printk(KERN_ERR "\tAddress Low 0x%08x\n",
mv64x60_read(&bh, MV64x60_PCI0_ERR_ADDR_LO));
printk(KERN_ERR "\tAddress High 0x%08x\n",
mv64x60_read(&bh, MV64x60_PCI0_ERR_ADDR_HI));
printk(KERN_ERR "\tAttribute 0x%08x\n",
mv64x60_read(&bh, MV64x60_PCI0_ERR_DATA_LO));
printk(KERN_ERR "\tCommand 0x%08x\n",
mv64x60_read(&bh, MV64x60_PCI0_ERR_CMD));
mv64x60_write(&bh, MV64x60_PCI0_ERR_CAUSE, ~val);
}
if (pci_bus == 1) { /* Error on PCI 1 */
val = mv64x60_read(&bh, MV64x60_PCI1_ERR_CAUSE);
printk(KERN_ERR "%s: Error in PCI %d Interface\n",
"mv64360_pci_error_int_handler", pci_bus);
printk(KERN_ERR "\tPCI %d error register dump:\n", pci_bus);
printk(KERN_ERR "\tCause register 0x%08x\n", val);
printk(KERN_ERR "\tAddress Low 0x%08x\n",
mv64x60_read(&bh, MV64x60_PCI1_ERR_ADDR_LO));
printk(KERN_ERR "\tAddress High 0x%08x\n",
mv64x60_read(&bh, MV64x60_PCI1_ERR_ADDR_HI));
printk(KERN_ERR "\tAttribute 0x%08x\n",
mv64x60_read(&bh, MV64x60_PCI1_ERR_DATA_LO));
printk(KERN_ERR "\tCommand 0x%08x\n",
mv64x60_read(&bh, MV64x60_PCI1_ERR_CMD));
mv64x60_write(&bh, MV64x60_PCI1_ERR_CAUSE, ~val);
}
return IRQ_HANDLED;
}
static int __init
mv64360_register_hdlrs(void)
{
u32 mask;
/* Register CPU interface error interrupt handler */
request_irq(MV64x60_IRQ_CPU_ERR, mv64360_cpu_error_int_handler,
SA_INTERRUPT, CPU_INTR_STR, 0);
mv64x60_write(&bh, MV64x60_CPU_ERR_MASK, 0);
mv64x60_write(&bh, MV64x60_CPU_ERR_MASK, 0x000000ff);
/* Register internal SRAM error interrupt handler */
request_irq(MV64360_IRQ_SRAM_PAR_ERR, mv64360_sram_error_int_handler,
SA_INTERRUPT, SRAM_INTR_STR, 0);
/*
* Bit 0 reserved on 64360 and erratum FEr PCI-#11 (PCI internal
* data parity error set incorrectly) on rev 0 & 1 of 64460 requires
* bit 0 to be cleared.
*/
mask = 0x00a50c24;
if ((mv64x60_get_bridge_type() == MV64x60_TYPE_MV64460) &&
(mv64x60_get_bridge_rev() > 1))
mask |= 0x1; /* enable DPErr on 64460 */
/* Register PCI 0 error interrupt handler */
request_irq(MV64360_IRQ_PCI0, mv64360_pci_error_int_handler,
SA_INTERRUPT, PCI0_INTR_STR, (void *)0);
mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, 0);
mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, mask);
/* Register PCI 1 error interrupt handler */
request_irq(MV64360_IRQ_PCI1, mv64360_pci_error_int_handler,
SA_INTERRUPT, PCI1_INTR_STR, (void *)1);
mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, 0);
mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, mask);
return 0;
}
arch_initcall(mv64360_register_hdlrs);
/*
* arch/ppc/syslib/mv64x60.c
*
* Common routines for the Marvell/Galileo Discovery line of host bridges
* (gt64260, mv64360, mv64460, ...).
*
* Author: Mark A. Greer <mgreer@mvista.com>
*
* 2004 (c) MontaVista, Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/bootmem.h>
#include <linux/spinlock.h>
#include <linux/mv643xx.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
#include <asm/delay.h>
#include <asm/mv64x60.h>
u8 mv64x60_pci_exclude_bridge = 1;
spinlock_t mv64x60_lock; /* Only really used by PIC code once init done */
static u32 mv64x60_bridge_pbase = 0;
static u32 mv64x60_bridge_vbase = 0;
static u32 mv64x60_bridge_type = MV64x60_TYPE_INVALID;
static u32 mv64x60_bridge_rev = 0;
static u32 gt64260_translate_size(u32 base, u32 size, u32 num_bits);
static u32 gt64260_untranslate_size(u32 base, u32 size, u32 num_bits);
static void gt64260_set_pci2mem_window(struct pci_controller *hose, u32 bus,
u32 window, u32 base);
static void gt64260_set_pci2regs_window(struct mv64x60_handle *bh,
struct pci_controller *hose, u32 bus, u32 base);
static u32 gt64260_is_enabled_32bit(struct mv64x60_handle *bh, u32 window);
static void gt64260_enable_window_32bit(struct mv64x60_handle *bh, u32 window);
static void gt64260_disable_window_32bit(struct mv64x60_handle *bh, u32 window);
static void gt64260_enable_window_64bit(struct mv64x60_handle *bh, u32 window);
static void gt64260_disable_window_64bit(struct mv64x60_handle *bh, u32 window);
static void gt64260_disable_all_windows(struct mv64x60_handle *bh,
struct mv64x60_setup_info *si);
static void gt64260a_chip_specific_init(struct mv64x60_handle *bh,
struct mv64x60_setup_info *si);
static void gt64260b_chip_specific_init(struct mv64x60_handle *bh,
struct mv64x60_setup_info *si);
static u32 mv64360_translate_size(u32 base, u32 size, u32 num_bits);
static u32 mv64360_untranslate_size(u32 base, u32 size, u32 num_bits);
static void mv64360_set_pci2mem_window(struct pci_controller *hose, u32 bus,
u32 window, u32 base);
static void mv64360_set_pci2regs_window(struct mv64x60_handle *bh,
struct pci_controller *hose, u32 bus, u32 base);
static u32 mv64360_is_enabled_32bit(struct mv64x60_handle *bh, u32 window);
static void mv64360_enable_window_32bit(struct mv64x60_handle *bh, u32 window);
static void mv64360_disable_window_32bit(struct mv64x60_handle *bh, u32 window);
static void mv64360_enable_window_64bit(struct mv64x60_handle *bh, u32 window);
static void mv64360_disable_window_64bit(struct mv64x60_handle *bh, u32 window);
static void mv64360_disable_all_windows(struct mv64x60_handle *bh,
struct mv64x60_setup_info *si);
static void mv64360_config_io2mem_windows(struct mv64x60_handle *bh,
struct mv64x60_setup_info *si,
u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]);
static void mv64360_set_mpsc2regs_window(struct mv64x60_handle *bh, u32 base);
static void mv64360_chip_specific_init(struct mv64x60_handle *bh,
struct mv64x60_setup_info *si);
static void mv64460_chip_specific_init(struct mv64x60_handle *bh,
struct mv64x60_setup_info *si);
/*
* Define tables that have the chip-specific info for each type of
* Marvell bridge chip.
*/
static struct mv64x60_chip_info gt64260a_ci __initdata = { /* GT64260A */
.translate_size = gt64260_translate_size,
.untranslate_size = gt64260_untranslate_size,
.set_pci2mem_window = gt64260_set_pci2mem_window,
.set_pci2regs_window = gt64260_set_pci2regs_window,
.is_enabled_32bit = gt64260_is_enabled_32bit,
.enable_window_32bit = gt64260_enable_window_32bit,
.disable_window_32bit = gt64260_disable_window_32bit,
.enable_window_64bit = gt64260_enable_window_64bit,
.disable_window_64bit = gt64260_disable_window_64bit,
.disable_all_windows = gt64260_disable_all_windows,
.chip_specific_init = gt64260a_chip_specific_init,
.window_tab_32bit = gt64260_32bit_windows,
.window_tab_64bit = gt64260_64bit_windows,
};
static struct mv64x60_chip_info gt64260b_ci __initdata = { /* GT64260B */
.translate_size = gt64260_translate_size,
.untranslate_size = gt64260_untranslate_size,
.set_pci2mem_window = gt64260_set_pci2mem_window,
.set_pci2regs_window = gt64260_set_pci2regs_window,
.is_enabled_32bit = gt64260_is_enabled_32bit,
.enable_window_32bit = gt64260_enable_window_32bit,
.disable_window_32bit = gt64260_disable_window_32bit,
.enable_window_64bit = gt64260_enable_window_64bit,
.disable_window_64bit = gt64260_disable_window_64bit,
.disable_all_windows = gt64260_disable_all_windows,
.chip_specific_init = gt64260b_chip_specific_init,
.window_tab_32bit = gt64260_32bit_windows,
.window_tab_64bit = gt64260_64bit_windows,
};
static struct mv64x60_chip_info mv64360_ci __initdata = { /* MV64360 */
.translate_size = mv64360_translate_size,
.untranslate_size = mv64360_untranslate_size,
.set_pci2mem_window = mv64360_set_pci2mem_window,
.set_pci2regs_window = mv64360_set_pci2regs_window,
.is_enabled_32bit = mv64360_is_enabled_32bit,
.enable_window_32bit = mv64360_enable_window_32bit,
.disable_window_32bit = mv64360_disable_window_32bit,
.enable_window_64bit = mv64360_enable_window_64bit,
.disable_window_64bit = mv64360_disable_window_64bit,
.disable_all_windows = mv64360_disable_all_windows,
.config_io2mem_windows = mv64360_config_io2mem_windows,
.set_mpsc2regs_window = mv64360_set_mpsc2regs_window,
.chip_specific_init = mv64360_chip_specific_init,
.window_tab_32bit = mv64360_32bit_windows,
.window_tab_64bit = mv64360_64bit_windows,
};
static struct mv64x60_chip_info mv64460_ci __initdata = { /* MV64460 */
.translate_size = mv64360_translate_size,
.untranslate_size = mv64360_untranslate_size,
.set_pci2mem_window = mv64360_set_pci2mem_window,
.set_pci2regs_window = mv64360_set_pci2regs_window,
.is_enabled_32bit = mv64360_is_enabled_32bit,
.enable_window_32bit = mv64360_enable_window_32bit,
.disable_window_32bit = mv64360_disable_window_32bit,
.enable_window_64bit = mv64360_enable_window_64bit,
.disable_window_64bit = mv64360_disable_window_64bit,
.disable_all_windows = mv64360_disable_all_windows,
.config_io2mem_windows = mv64360_config_io2mem_windows,
.set_mpsc2regs_window = mv64360_set_mpsc2regs_window,
.chip_specific_init = mv64460_chip_specific_init,
.window_tab_32bit = mv64360_32bit_windows,
.window_tab_64bit = mv64360_64bit_windows,
};
/*
*****************************************************************************
*
* Platform Device Definitions
*
*****************************************************************************
*/
#ifdef CONFIG_SERIAL_MPSC
static struct mpsc_shared_pd_dd mv64x60_mpsc_shared_pd_dd = {
.mrr_val = 0x3ffffe38,
.rcrr_val = 0,
.tcrr_val = 0,
.intr_cause_val = 0,
.intr_mask_val = 0,
};
static struct resource mv64x60_mpsc_shared_resources[] = {
/* Do not change the order of the IORESOURCE_MEM resources */
[0] = {
.name = "mpsc routing base",
.start = MV64x60_MPSC_ROUTING_OFFSET,
.end = MV64x60_MPSC_ROUTING_OFFSET +
MPSC_ROUTING_REG_BLOCK_SIZE - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.name = "sdma intr base",
.start = MV64x60_SDMA_INTR_OFFSET,
.end = MV64x60_SDMA_INTR_OFFSET +
MPSC_SDMA_INTR_REG_BLOCK_SIZE - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device mpsc_shared_device = { /* Shared device */
.name = MPSC_SHARED_NAME,
.id = 0,
.num_resources = ARRAY_SIZE(mv64x60_mpsc_shared_resources),
.resource = mv64x60_mpsc_shared_resources,
.dev = {
.driver_data = (void *)&mv64x60_mpsc_shared_pd_dd,
},
};
static struct mpsc_pd_dd mv64x60_mpsc0_pd_dd = {
.mirror_regs = 0,
.cache_mgmt = 0,
.max_idle = 0,
.default_baud = 9600,
.default_bits = 8,
.default_parity = 'n',
.default_flow = 'n',
.chr_1_val = 0x00000000,
.chr_2_val = 0x00000000,
.chr_10_val = 0x00000003,
.mpcr_val = 0,
.bcr_val = 0,
.brg_can_tune = 0,
.brg_clk_src = 8, /* Default to TCLK */
.brg_clk_freq = 100000000, /* Default to 100 MHz */
};
static struct resource mv64x60_mpsc0_resources[] = {
/* Do not change the order of the IORESOURCE_MEM resources */
[0] = {
.name = "mpsc 0 base",
.start = MV64x60_MPSC_0_OFFSET,
.end = MV64x60_MPSC_0_OFFSET + MPSC_REG_BLOCK_SIZE - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.name = "sdma 0 base",
.start = MV64x60_SDMA_0_OFFSET,
.end = MV64x60_SDMA_0_OFFSET + MPSC_SDMA_REG_BLOCK_SIZE - 1,
.flags = IORESOURCE_MEM,
},
[2] = {
.name = "brg 0 base",
.start = MV64x60_BRG_0_OFFSET,
.end = MV64x60_BRG_0_OFFSET + MPSC_BRG_REG_BLOCK_SIZE - 1,
.flags = IORESOURCE_MEM,
},
[3] = {
.name = "sdma 0 irq",
.start = MV64x60_IRQ_SDMA_0,
.end = MV64x60_IRQ_SDMA_0,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device mpsc0_device = {
.name = MPSC_CTLR_NAME,
.id = 0,
.num_resources = ARRAY_SIZE(mv64x60_mpsc0_resources),
.resource = mv64x60_mpsc0_resources,
.dev = {
.driver_data = (void *)&mv64x60_mpsc0_pd_dd,
},
};
static struct mpsc_pd_dd mv64x60_mpsc1_pd_dd = {
.mirror_regs = 0,
.cache_mgmt = 0,
.max_idle = 0,
.default_baud = 9600,
.default_bits = 8,
.default_parity = 'n',
.default_flow = 'n',
.chr_1_val = 0x00000000,
.chr_1_val = 0x00000000,
.chr_2_val = 0x00000000,
.chr_10_val = 0x00000003,
.mpcr_val = 0,
.bcr_val = 0,
.brg_can_tune = 0,
.brg_clk_src = 8, /* Default to TCLK */
.brg_clk_freq = 100000000, /* Default to 100 MHz */
};
static struct resource mv64x60_mpsc1_resources[] = {
/* Do not change the order of the IORESOURCE_MEM resources */
[0] = {
.name = "mpsc 1 base",
.start = MV64x60_MPSC_1_OFFSET,
.end = MV64x60_MPSC_1_OFFSET + MPSC_REG_BLOCK_SIZE - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.name = "sdma 1 base",
.start = MV64x60_SDMA_1_OFFSET,
.end = MV64x60_SDMA_1_OFFSET + MPSC_SDMA_REG_BLOCK_SIZE - 1,
.flags = IORESOURCE_MEM,
},
[2] = {
.name = "brg 1 base",
.start = MV64x60_BRG_1_OFFSET,
.end = MV64x60_BRG_1_OFFSET + MPSC_BRG_REG_BLOCK_SIZE - 1,
.flags = IORESOURCE_MEM,
},
[3] = {
.name = "sdma 1 irq",
.start = MV64360_IRQ_SDMA_1,
.end = MV64360_IRQ_SDMA_1,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device mpsc1_device = {
.name = MPSC_CTLR_NAME,
.id = 1,
.num_resources = ARRAY_SIZE(mv64x60_mpsc1_resources),
.resource = mv64x60_mpsc1_resources,
.dev = {
.driver_data = (void *)&mv64x60_mpsc1_pd_dd,
},
};
#endif
static struct platform_device *mv64x60_pd_devs[] __initdata = {
#ifdef CONFIG_SERIAL_MPSC
&mpsc_shared_device,
&mpsc0_device,
&mpsc1_device,
#endif
};
/*
*****************************************************************************
*
* Bridge Initialization Routines
*
*****************************************************************************
*/
/*
* mv64x60_init()
*
* Initialze the bridge based on setting passed in via 'si'. The bridge
* handle, 'bh', will be set so that it can be used to make subsequent
* calls to routines in this file.
*/
int __init
mv64x60_init(struct mv64x60_handle *bh, struct mv64x60_setup_info *si)
{
u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2];
if (ppc_md.progress)
ppc_md.progress("mv64x60 initialization", 0x0);
spin_lock_init(&mv64x60_lock);
mv64x60_early_init(bh, si);
if (mv64x60_get_type(bh) || mv64x60_setup_for_chip(bh)) {
iounmap((void *)bh->v_base);
bh->v_base = 0;
if (ppc_md.progress)
ppc_md.progress("mv64x60_init: Can't determine chip",0);
return -1;
}
bh->ci->disable_all_windows(bh, si);
mv64x60_get_mem_windows(bh, mem_windows);
mv64x60_config_cpu2mem_windows(bh, si, mem_windows);
if (bh->ci->config_io2mem_windows)
bh->ci->config_io2mem_windows(bh, si, mem_windows);
if (bh->ci->set_mpsc2regs_window)
bh->ci->set_mpsc2regs_window(bh, si->phys_reg_base);
if (si->pci_1.enable_bus) {
bh->io_base_b = (u32)ioremap(si->pci_1.pci_io.cpu_base,
si->pci_1.pci_io.size);
isa_io_base = bh->io_base_b;
}
if (si->pci_0.enable_bus) {
bh->io_base_a = (u32)ioremap(si->pci_0.pci_io.cpu_base,
si->pci_0.pci_io.size);
isa_io_base = bh->io_base_a;
mv64x60_alloc_hose(bh, MV64x60_PCI0_CONFIG_ADDR,
MV64x60_PCI0_CONFIG_DATA, &bh->hose_a);
mv64x60_config_resources(bh->hose_a, &si->pci_0, bh->io_base_a);
mv64x60_config_pci_params(bh->hose_a, &si->pci_0);
mv64x60_config_cpu2pci_windows(bh, &si->pci_0, 0);
mv64x60_config_pci2mem_windows(bh, bh->hose_a, &si->pci_0, 0,
mem_windows);
bh->ci->set_pci2regs_window(bh, bh->hose_a, 0,
si->phys_reg_base);
}
if (si->pci_1.enable_bus) {
mv64x60_alloc_hose(bh, MV64x60_PCI1_CONFIG_ADDR,
MV64x60_PCI1_CONFIG_DATA, &bh->hose_b);
mv64x60_config_resources(bh->hose_b, &si->pci_1, bh->io_base_b);
mv64x60_config_pci_params(bh->hose_b, &si->pci_1);
mv64x60_config_cpu2pci_windows(bh, &si->pci_1, 1);
mv64x60_config_pci2mem_windows(bh, bh->hose_b, &si->pci_1, 1,
mem_windows);
bh->ci->set_pci2regs_window(bh, bh->hose_b, 1,
si->phys_reg_base);
}
bh->ci->chip_specific_init(bh, si);
mv64x60_pd_fixup(bh, mv64x60_pd_devs, ARRAY_SIZE(mv64x60_pd_devs));
return 0;
}
/*
* mv64x60_early_init()
*
* Do some bridge work that must take place before we start messing with
* the bridge for real.
*/
void __init
mv64x60_early_init(struct mv64x60_handle *bh, struct mv64x60_setup_info *si)
{
struct pci_controller hose_a, hose_b;
memset(bh, 0, sizeof(*bh));
bh->p_base = si->phys_reg_base;
bh->v_base = (u32)ioremap(bh->p_base, MV64x60_INTERNAL_SPACE_SIZE);
mv64x60_bridge_pbase = bh->p_base;
mv64x60_bridge_vbase = bh->v_base;
/* Assuming pci mode [reserved] bits 4:5 on 64260 are 0 */
bh->pci_mode_a = mv64x60_read(bh, MV64x60_PCI0_MODE) &
MV64x60_PCIMODE_MASK;
bh->pci_mode_b = mv64x60_read(bh, MV64x60_PCI1_MODE) &
MV64x60_PCIMODE_MASK;
/* Need temporary hose structs to call mv64x60_set_bus() */
memset(&hose_a, 0, sizeof(hose_a));
memset(&hose_b, 0, sizeof(hose_b));
setup_indirect_pci_nomap(&hose_a, bh->v_base + MV64x60_PCI0_CONFIG_ADDR,
bh->v_base + MV64x60_PCI0_CONFIG_DATA);
setup_indirect_pci_nomap(&hose_b, bh->v_base + MV64x60_PCI1_CONFIG_ADDR,
bh->v_base + MV64x60_PCI1_CONFIG_DATA);
bh->hose_a = &hose_a;
bh->hose_b = &hose_b;
mv64x60_set_bus(bh, 0, 0);
mv64x60_set_bus(bh, 1, 0);
bh->hose_a = NULL;
bh->hose_b = NULL;
/* Clear bit 0 of PCI addr decode control so PCI->CPU remap 1:1 */
mv64x60_clr_bits(bh, MV64x60_PCI0_PCI_DECODE_CNTL, 0x00000001);
mv64x60_clr_bits(bh, MV64x60_PCI1_PCI_DECODE_CNTL, 0x00000001);
/* Bit 12 MUST be 0; set bit 27--don't auto-update cpu remap regs */
mv64x60_clr_bits(bh, MV64x60_CPU_CONFIG, (1<<12));
mv64x60_set_bits(bh, MV64x60_CPU_CONFIG, (1<<27));
mv64x60_set_bits(bh, MV64x60_PCI0_TO_RETRY, 0xffff);
mv64x60_set_bits(bh, MV64x60_PCI1_TO_RETRY, 0xffff);
return;
}
/*
*****************************************************************************
*
* Window Config Routines
*
*****************************************************************************
*/
/*
* mv64x60_get_32bit_window()
*
* Determine the base address and size of a 32-bit window on the bridge.
*/
void __init
mv64x60_get_32bit_window(struct mv64x60_handle *bh, u32 window,
u32 *base, u32 *size)
{
u32 val, base_reg, size_reg, base_bits, size_bits;
u32 (*get_from_field)(u32 val, u32 num_bits);
base_reg = bh->ci->window_tab_32bit[window].base_reg;
if (base_reg != 0) {
size_reg = bh->ci->window_tab_32bit[window].size_reg;
base_bits = bh->ci->window_tab_32bit[window].base_bits;
size_bits = bh->ci->window_tab_32bit[window].size_bits;
get_from_field= bh->ci->window_tab_32bit[window].get_from_field;
val = mv64x60_read(bh, base_reg);
*base = get_from_field(val, base_bits);
if (size_reg != 0) {
val = mv64x60_read(bh, size_reg);
val = get_from_field(val, size_bits);
*size = bh->ci->untranslate_size(*base, val, size_bits);
}
else
*size = 0;
}
else {
*base = 0;
*size = 0;
}
pr_debug("get 32bit window: %d, base: 0x%x, size: 0x%x\n",
window, *base, *size);
return;
}
/*
* mv64x60_set_32bit_window()
*
* Set the base address and size of a 32-bit window on the bridge.
*/
void __init
mv64x60_set_32bit_window(struct mv64x60_handle *bh, u32 window,
u32 base, u32 size, u32 other_bits)
{
u32 val, base_reg, size_reg, base_bits, size_bits;
u32 (*map_to_field)(u32 val, u32 num_bits);
pr_debug("set 32bit window: %d, base: 0x%x, size: 0x%x, other: 0x%x\n",
window, base, size, other_bits);
base_reg = bh->ci->window_tab_32bit[window].base_reg;
if (base_reg != 0) {
size_reg = bh->ci->window_tab_32bit[window].size_reg;
base_bits = bh->ci->window_tab_32bit[window].base_bits;
size_bits = bh->ci->window_tab_32bit[window].size_bits;
map_to_field = bh->ci->window_tab_32bit[window].map_to_field;
val = map_to_field(base, base_bits) | other_bits;
mv64x60_write(bh, base_reg, val);
if (size_reg != 0) {
val = bh->ci->translate_size(base, size, size_bits);
val = map_to_field(val, size_bits);
mv64x60_write(bh, size_reg, val);
}
(void)mv64x60_read(bh, base_reg); /* Flush FIFO */
}
return;
}
/*
* mv64x60_get_64bit_window()
*
* Determine the base address and size of a 64-bit window on the bridge.
*/
void __init
mv64x60_get_64bit_window(struct mv64x60_handle *bh, u32 window,
u32 *base_hi, u32 *base_lo, u32 *size)
{
u32 val, base_lo_reg, size_reg, base_lo_bits, size_bits;
u32 (*get_from_field)(u32 val, u32 num_bits);
base_lo_reg = bh->ci->window_tab_64bit[window].base_lo_reg;
if (base_lo_reg != 0) {
size_reg = bh->ci->window_tab_64bit[window].size_reg;
base_lo_bits = bh->ci->window_tab_64bit[window].base_lo_bits;
size_bits = bh->ci->window_tab_64bit[window].size_bits;
get_from_field= bh->ci->window_tab_64bit[window].get_from_field;
*base_hi = mv64x60_read(bh,
bh->ci->window_tab_64bit[window].base_hi_reg);
val = mv64x60_read(bh, base_lo_reg);
*base_lo = get_from_field(val, base_lo_bits);
if (size_reg != 0) {
val = mv64x60_read(bh, size_reg);
val = get_from_field(val, size_bits);
*size = bh->ci->untranslate_size(*base_lo, val,
size_bits);
}
else
*size = 0;
}
else {
*base_hi = 0;
*base_lo = 0;
*size = 0;
}
pr_debug("get 64bit window: %d, base hi: 0x%x, base lo: 0x%x, "
"size: 0x%x\n", window, *base_hi, *base_lo, *size);
return;
}
/*
* mv64x60_set_64bit_window()
*
* Set the base address and size of a 64-bit window on the bridge.
*/
void __init
mv64x60_set_64bit_window(struct mv64x60_handle *bh, u32 window,
u32 base_hi, u32 base_lo, u32 size, u32 other_bits)
{
u32 val, base_lo_reg, size_reg, base_lo_bits, size_bits;
u32 (*map_to_field)(u32 val, u32 num_bits);
pr_debug("set 64bit window: %d, base hi: 0x%x, base lo: 0x%x, "
"size: 0x%x, other: 0x%x\n",
window, base_hi, base_lo, size, other_bits);
base_lo_reg = bh->ci->window_tab_64bit[window].base_lo_reg;
if (base_lo_reg != 0) {
size_reg = bh->ci->window_tab_64bit[window].size_reg;
base_lo_bits = bh->ci->window_tab_64bit[window].base_lo_bits;
size_bits = bh->ci->window_tab_64bit[window].size_bits;
map_to_field = bh->ci->window_tab_64bit[window].map_to_field;
mv64x60_write(bh, bh->ci->window_tab_64bit[window].base_hi_reg,
base_hi);
val = map_to_field(base_lo, base_lo_bits) | other_bits;
mv64x60_write(bh, base_lo_reg, val);
if (size_reg != 0) {
val = bh->ci->translate_size(base_lo, size, size_bits);
val = map_to_field(val, size_bits);
mv64x60_write(bh, size_reg, val);
}
(void)mv64x60_read(bh, base_lo_reg); /* Flush FIFO */
}
return;
}
/*
* mv64x60_mask()
*
* Take the high-order 'num_bits' of 'val' & mask off low bits.
*/
u32 __init
mv64x60_mask(u32 val, u32 num_bits)
{
return val & (0xffffffff << (32 - num_bits));
}
/*
* mv64x60_mask_shift_left()
*
* Take the low-order 'num_bits' of 'val', shift left to align at bit 31 (MSB).
*/
u32 __init
mv64x60_shift_left(u32 val, u32 num_bits)
{
return val << (32 - num_bits);
}
/*
* mv64x60_shift_right()
*
* Take the high-order 'num_bits' of 'val', shift right to align at bit 0 (LSB).
*/
u32 __init
mv64x60_shift_right(u32 val, u32 num_bits)
{
return val >> (32 - num_bits);
}
/*
*****************************************************************************
*
* Chip Identification Routines
*
*****************************************************************************
*/
/*
* mv64x60_get_type()
*
* Determine the type of bridge chip we have.
*/
int __init
mv64x60_get_type(struct mv64x60_handle *bh)
{
struct pci_controller hose;
u16 val;
u8 save_exclude;
memset(&hose, 0, sizeof(hose));
setup_indirect_pci_nomap(&hose, bh->v_base + MV64x60_PCI0_CONFIG_ADDR,
bh->v_base + MV64x60_PCI0_CONFIG_DATA);
save_exclude = mv64x60_pci_exclude_bridge;
mv64x60_pci_exclude_bridge = 0;
/* Sanity check of bridge's Vendor ID */
early_read_config_word(&hose, 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID, &val);
if (val != PCI_VENDOR_ID_MARVELL) {
mv64x60_pci_exclude_bridge = save_exclude;
return -1;
}
/* Get the revision of the chip */
early_read_config_word(&hose, 0, PCI_DEVFN(0, 0), PCI_CLASS_REVISION,
&val);
bh->rev = (u32) (val & 0xff);
/* Figure out the type of Marvell bridge it is */
early_read_config_word(&hose, 0, PCI_DEVFN(0, 0), PCI_DEVICE_ID, &val);
mv64x60_pci_exclude_bridge = save_exclude;
switch (val) {
case PCI_DEVICE_ID_MARVELL_GT64260:
switch (bh->rev) {
case GT64260_REV_A:
bh->type = MV64x60_TYPE_GT64260A;
break;
default:
printk(KERN_WARNING "Unsupported GT64260 rev %04x\n",
bh->rev);
/* Assume its similar to a 'B' rev and fallthru */
case GT64260_REV_B:
bh->type = MV64x60_TYPE_GT64260B;
break;
}
break;
case PCI_DEVICE_ID_MARVELL_MV64360:
/* Marvell won't tell me how to distinguish a 64361 & 64362 */
bh->type = MV64x60_TYPE_MV64360;
break;
case PCI_DEVICE_ID_MARVELL_MV64460:
bh->type = MV64x60_TYPE_MV64460;
break;
default:
printk(KERN_ERR "Unknown Marvell bridge type %04x\n", val);
return -1;
}
/* Hang onto bridge type & rev for PIC code */
mv64x60_bridge_type = bh->type;
mv64x60_bridge_rev = bh->rev;
return 0;
}
/*
* mv64x60_setup_for_chip()
*
* Set 'bh' to use the proper set of routine for the bridge chip that we have.
*/
int __init
mv64x60_setup_for_chip(struct mv64x60_handle *bh)
{
int rc = 0;
/* Set up chip-specific info based on the chip/bridge type */
switch(bh->type) {
case MV64x60_TYPE_GT64260A:
bh->ci = &gt64260a_ci;
break;
case MV64x60_TYPE_GT64260B:
bh->ci = &gt64260b_ci;
break;
case MV64x60_TYPE_MV64360:
bh->ci = &mv64360_ci;
break;
case MV64x60_TYPE_MV64460:
bh->ci = &mv64460_ci;
break;
case MV64x60_TYPE_INVALID:
default:
if (ppc_md.progress)
ppc_md.progress("mv64x60: Unsupported bridge", 0x0);
printk(KERN_ERR "mv64x60: Unsupported bridge\n");
rc = -1;
}
return rc;
}
/*
* mv64x60_get_bridge_vbase()
*
* Return the virtual address of the bridge's registers.
*/
u32
mv64x60_get_bridge_vbase(void)
{
return mv64x60_bridge_vbase;
}
/*
* mv64x60_get_bridge_type()
*
* Return the type of bridge on the platform.
*/
u32
mv64x60_get_bridge_type(void)
{
return mv64x60_bridge_type;
}
/*
* mv64x60_get_bridge_rev()
*
* Return the revision of the bridge on the platform.
*/
u32
mv64x60_get_bridge_rev(void)
{
return mv64x60_bridge_rev;
}
/*
*****************************************************************************
*
* System Memory Window Related Routines
*
*****************************************************************************
*/
/*
* mv64x60_get_mem_size()
*
* Calculate the amount of memory that the memory controller is set up for.
* This should only be used by board-specific code if there is no other
* way to determine the amount of memory in the system.
*/
u32 __init
mv64x60_get_mem_size(u32 bridge_base, u32 chip_type)
{
struct mv64x60_handle bh;
u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2];
memset(&bh, 0, sizeof(bh));
bh.type = chip_type;
bh.v_base = bridge_base;
(void)mv64x60_setup_for_chip(&bh);
mv64x60_get_mem_windows(&bh, mem_windows);
return mv64x60_calc_mem_size(&bh, mem_windows);
}
/*
* mv64x60_get_mem_windows()
*
* Get the values in the memory controller & return in the 'mem_windows' array.
*/
void __init
mv64x60_get_mem_windows(struct mv64x60_handle *bh,
u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
{
u32 i, win;
for (win=MV64x60_CPU2MEM_0_WIN,i=0;win<=MV64x60_CPU2MEM_3_WIN;win++,i++)
if (bh->ci->is_enabled_32bit(bh, win))
mv64x60_get_32bit_window(bh, win,
&mem_windows[i][0], &mem_windows[i][1]);
else {
mem_windows[i][0] = 0;
mem_windows[i][1] = 0;
}
return;
}
/*
* mv64x60_calc_mem_size()
*
* Using the memory controller register values in 'mem_windows', determine
* how much memory it is set up for.
*/
u32 __init
mv64x60_calc_mem_size(struct mv64x60_handle *bh,
u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
{
u32 i, total = 0;
for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++)
total += mem_windows[i][1];
return total;
}
/*
*****************************************************************************
*
* CPU->System MEM, PCI Config Routines
*
*****************************************************************************
*/
/*
* mv64x60_config_cpu2mem_windows()
*
* Configure CPU->Memory windows on the bridge.
*/
void __init
mv64x60_config_cpu2mem_windows(struct mv64x60_handle *bh,
struct mv64x60_setup_info *si,
u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
{
u32 i, win;
u32 prot_tab[] = {
MV64x60_CPU_PROT_0_WIN, MV64x60_CPU_PROT_1_WIN,
MV64x60_CPU_PROT_2_WIN, MV64x60_CPU_PROT_3_WIN
};
u32 cpu_snoop_tab[] = {
MV64x60_CPU_SNOOP_0_WIN, MV64x60_CPU_SNOOP_1_WIN,
MV64x60_CPU_SNOOP_2_WIN, MV64x60_CPU_SNOOP_3_WIN
};
/* Set CPU protection & snoop windows */
for (win=MV64x60_CPU2MEM_0_WIN,i=0;win<=MV64x60_CPU2MEM_3_WIN;win++,i++)
if (bh->ci->is_enabled_32bit(bh, win)) {
mv64x60_set_32bit_window(bh, prot_tab[i],
mem_windows[i][0], mem_windows[i][1],
si->cpu_prot_options[i]);
bh->ci->enable_window_32bit(bh, prot_tab[i]);
if (bh->ci->window_tab_32bit[cpu_snoop_tab[i]].
base_reg != 0) {
mv64x60_set_32bit_window(bh, cpu_snoop_tab[i],
mem_windows[i][0], mem_windows[i][1],
si->cpu_snoop_options[i]);
bh->ci->enable_window_32bit(bh,
cpu_snoop_tab[i]);
}
}
return;
}
/*
* mv64x60_config_cpu2pci_windows()
*
* Configure the CPU->PCI windows for one of the PCI buses.
*/
void __init
mv64x60_config_cpu2pci_windows(struct mv64x60_handle *bh,
struct mv64x60_pci_info *pi, u32 bus)
{
int i;
u32 win_tab[2][4] = {
{ MV64x60_CPU2PCI0_IO_WIN, MV64x60_CPU2PCI0_MEM_0_WIN,
MV64x60_CPU2PCI0_MEM_1_WIN,
MV64x60_CPU2PCI0_MEM_2_WIN },
{ MV64x60_CPU2PCI1_IO_WIN, MV64x60_CPU2PCI1_MEM_0_WIN,
MV64x60_CPU2PCI1_MEM_1_WIN,
MV64x60_CPU2PCI1_MEM_2_WIN },
};
u32 remap_tab[2][4] = {
{ MV64x60_CPU2PCI0_IO_REMAP_WIN,
MV64x60_CPU2PCI0_MEM_0_REMAP_WIN,
MV64x60_CPU2PCI0_MEM_1_REMAP_WIN,
MV64x60_CPU2PCI0_MEM_2_REMAP_WIN },
{ MV64x60_CPU2PCI1_IO_REMAP_WIN,
MV64x60_CPU2PCI1_MEM_0_REMAP_WIN,
MV64x60_CPU2PCI1_MEM_1_REMAP_WIN,
MV64x60_CPU2PCI1_MEM_2_REMAP_WIN }
};
if (pi->pci_io.size > 0) {
mv64x60_set_32bit_window(bh, win_tab[bus][0],
pi->pci_io.cpu_base, pi->pci_io.size, pi->pci_io.swap);
mv64x60_set_32bit_window(bh, remap_tab[bus][0],
pi->pci_io.pci_base_lo, 0, 0);
bh->ci->enable_window_32bit(bh, win_tab[bus][0]);
}
else /* Actually, the window should already be disabled */
bh->ci->disable_window_32bit(bh, win_tab[bus][0]);
for (i=0; i<3; i++)
if (pi->pci_mem[i].size > 0) {
mv64x60_set_32bit_window(bh, win_tab[bus][i+1],
pi->pci_mem[i].cpu_base, pi->pci_mem[i].size,
pi->pci_mem[i].swap);
mv64x60_set_64bit_window(bh, remap_tab[bus][i+1],
pi->pci_mem[i].pci_base_hi,
pi->pci_mem[i].pci_base_lo, 0, 0);
bh->ci->enable_window_32bit(bh, win_tab[bus][i+1]);
}
else /* Actually, the window should already be disabled */
bh->ci->disable_window_32bit(bh, win_tab[bus][i+1]);
return;
}
/*
*****************************************************************************
*
* PCI->System MEM Config Routines
*
*****************************************************************************
*/
/*
* mv64x60_config_pci2mem_windows()
*
* Configure the PCI->Memory windows on the bridge.
*/
void __init
mv64x60_config_pci2mem_windows(struct mv64x60_handle *bh,
struct pci_controller *hose, struct mv64x60_pci_info *pi,
u32 bus, u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
{
u32 i, win;
u32 pci_acc_tab[2][4] = {
{ MV64x60_PCI02MEM_ACC_CNTL_0_WIN,
MV64x60_PCI02MEM_ACC_CNTL_1_WIN,
MV64x60_PCI02MEM_ACC_CNTL_2_WIN,
MV64x60_PCI02MEM_ACC_CNTL_3_WIN },
{ MV64x60_PCI12MEM_ACC_CNTL_0_WIN,
MV64x60_PCI12MEM_ACC_CNTL_1_WIN,
MV64x60_PCI12MEM_ACC_CNTL_2_WIN,
MV64x60_PCI12MEM_ACC_CNTL_3_WIN }
};
u32 pci_snoop_tab[2][4] = {
{ MV64x60_PCI02MEM_SNOOP_0_WIN,
MV64x60_PCI02MEM_SNOOP_1_WIN,
MV64x60_PCI02MEM_SNOOP_2_WIN,
MV64x60_PCI02MEM_SNOOP_3_WIN },
{ MV64x60_PCI12MEM_SNOOP_0_WIN,
MV64x60_PCI12MEM_SNOOP_1_WIN,
MV64x60_PCI12MEM_SNOOP_2_WIN,
MV64x60_PCI12MEM_SNOOP_3_WIN }
};
u32 pci_size_tab[2][4] = {
{ MV64x60_PCI0_MEM_0_SIZE, MV64x60_PCI0_MEM_1_SIZE,
MV64x60_PCI0_MEM_2_SIZE, MV64x60_PCI0_MEM_3_SIZE },
{ MV64x60_PCI1_MEM_0_SIZE, MV64x60_PCI1_MEM_1_SIZE,
MV64x60_PCI1_MEM_2_SIZE, MV64x60_PCI1_MEM_3_SIZE }
};
/*
* Set the access control, snoop, BAR size, and window base addresses.
* PCI->MEM windows base addresses will match exactly what the
* CPU->MEM windows are.
*/
for (win=MV64x60_CPU2MEM_0_WIN,i=0;win<=MV64x60_CPU2MEM_3_WIN;win++,i++)
if (bh->ci->is_enabled_32bit(bh, win)) {
mv64x60_set_64bit_window(bh,
pci_acc_tab[bus][i], 0,
mem_windows[i][0], mem_windows[i][1],
pi->acc_cntl_options[i]);
bh->ci->enable_window_64bit(bh, pci_acc_tab[bus][i]);
if (bh->ci->window_tab_64bit[
pci_snoop_tab[bus][i]].base_lo_reg != 0) {
mv64x60_set_64bit_window(bh,
pci_snoop_tab[bus][i], 0,
mem_windows[i][0], mem_windows[i][1],
pi->snoop_options[i]);
bh->ci->enable_window_64bit(bh,
pci_snoop_tab[bus][i]);
}
bh->ci->set_pci2mem_window(hose, bus, i,
mem_windows[i][0]);
mv64x60_write(bh, pci_size_tab[bus][i],
mv64x60_mask(mem_windows[i][1] - 1, 20));
/* Enable the window */
mv64x60_clr_bits(bh, ((bus == 0) ?
MV64x60_PCI0_BAR_ENABLE :
MV64x60_PCI1_BAR_ENABLE), (1 << i));
}
return;
}
/*
*****************************************************************************
*
* Hose & Resource Alloc/Init Routines
*
*****************************************************************************
*/
/*
* mv64x60_alloc_hoses()
*
* Allocate the PCI hose structures for the bridge's PCI buses.
*/
void __init
mv64x60_alloc_hose(struct mv64x60_handle *bh, u32 cfg_addr, u32 cfg_data,
struct pci_controller **hose)
{
*hose = pcibios_alloc_controller();
setup_indirect_pci_nomap(*hose, bh->v_base + cfg_addr,
bh->v_base + cfg_data);
return;
}
/*
* mv64x60_config_resources()
*
* Calculate the offsets, etc. for the hose structures to reflect all of
* the address remapping that happens as you go from CPU->PCI and PCI->MEM.
*/
void __init
mv64x60_config_resources(struct pci_controller *hose,
struct mv64x60_pci_info *pi, u32 io_base)
{
int i;
/* 2 hoses; 4 resources/hose; string <= 64 bytes */
static char s[2][4][64];
if (pi->pci_io.size != 0) {
sprintf(s[hose->index][0], "PCI hose %d I/O Space",
hose->index);
pci_init_resource(&hose->io_resource, io_base - isa_io_base,
io_base - isa_io_base + pi->pci_io.size - 1,
IORESOURCE_IO, s[hose->index][0]);
hose->io_space.start = pi->pci_io.pci_base_lo;
hose->io_space.end = pi->pci_io.pci_base_lo + pi->pci_io.size-1;
hose->io_base_phys = (ulong)pi->pci_io.cpu_base;
hose->io_base_virt = (void *)isa_io_base;
}
for (i=0; i<3; i++)
if (pi->pci_mem[i].size != 0) {
sprintf(s[hose->index][i+1], "PCI hose %d MEM Space %d",
hose->index, i);
pci_init_resource(&hose->mem_resources[i],
pi->pci_mem[i].cpu_base,
pi->pci_mem[i].cpu_base + pi->pci_mem[i].size-1,
IORESOURCE_MEM, s[hose->index][i+1]);
}
hose->mem_space.end = pi->pci_mem[0].pci_base_lo +
pi->pci_mem[0].size - 1;
hose->pci_mem_offset = pi->pci_mem[0].cpu_base -
pi->pci_mem[0].pci_base_lo;
return;
}
/*
* mv64x60_config_pci_params()
*
* Configure a hose's PCI config space parameters.
*/
void __init
mv64x60_config_pci_params(struct pci_controller *hose,
struct mv64x60_pci_info *pi)
{
u32 devfn;
u16 u16_val;
u8 save_exclude;
devfn = PCI_DEVFN(0,0);
save_exclude = mv64x60_pci_exclude_bridge;
mv64x60_pci_exclude_bridge = 0;
/* Set class code to indicate host bridge */
u16_val = PCI_CLASS_BRIDGE_HOST; /* 0x0600 (host bridge) */
early_write_config_word(hose, 0, devfn, PCI_CLASS_DEVICE, u16_val);
/* Enable bridge to be PCI master & respond to PCI MEM cycles */
early_read_config_word(hose, 0, devfn, PCI_COMMAND, &u16_val);
u16_val &= ~(PCI_COMMAND_IO | PCI_COMMAND_INVALIDATE |
PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK);
u16_val |= pi->pci_cmd_bits | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
early_write_config_word(hose, 0, devfn, PCI_COMMAND, u16_val);
/* Set latency timer, cache line size, clear BIST */
u16_val = (pi->latency_timer << 8) | (L1_CACHE_LINE_SIZE >> 2);
early_write_config_word(hose, 0, devfn, PCI_CACHE_LINE_SIZE, u16_val);
mv64x60_pci_exclude_bridge = save_exclude;
return;
}
/*
*****************************************************************************
*
* PCI Related Routine
*
*****************************************************************************
*/
/*
* mv64x60_set_bus()
*
* Set the bus number for the hose directly under the bridge.
*/
void __init
mv64x60_set_bus(struct mv64x60_handle *bh, u32 bus, u32 child_bus)
{
struct pci_controller *hose;
u32 pci_mode, p2p_cfg, pci_cfg_offset, val;
u8 save_exclude;
if (bus == 0) {
pci_mode = bh->pci_mode_a;
p2p_cfg = MV64x60_PCI0_P2P_CONFIG;
pci_cfg_offset = 0x64;
hose = bh->hose_a;
}
else {
pci_mode = bh->pci_mode_b;
p2p_cfg = MV64x60_PCI1_P2P_CONFIG;
pci_cfg_offset = 0xe4;
hose = bh->hose_b;
}
child_bus &= 0xff;
val = mv64x60_read(bh, p2p_cfg);
if (pci_mode == MV64x60_PCIMODE_CONVENTIONAL) {
val &= 0xe0000000; /* Force dev num to 0, turn off P2P bridge */
val |= (child_bus << 16) | 0xff;
mv64x60_write(bh, p2p_cfg, val);
(void)mv64x60_read(bh, p2p_cfg); /* Flush FIFO */
}
else { /* PCI-X */
/*
* Need to use the current bus/dev number (that's in the
* P2P CONFIG reg) to access the bridge's pci config space.
*/
save_exclude = mv64x60_pci_exclude_bridge;
mv64x60_pci_exclude_bridge = 0;
early_write_config_dword(hose, (val & 0x00ff0000) >> 16,
PCI_DEVFN(((val & 0x1f000000) >> 24), 0),
pci_cfg_offset, child_bus << 8);
mv64x60_pci_exclude_bridge = save_exclude;
}
return;
}
/*
* mv64x60_pci_exclude_device()
*
* This routine is used to make the bridge not appear when the
* PCI subsystem is accessing PCI devices (in PCI config space).
*/
int
mv64x60_pci_exclude_device(u8 bus, u8 devfn)
{
struct pci_controller *hose;
hose = pci_bus_to_hose(bus);
/* Skip slot 0 on both hoses */
if ((mv64x60_pci_exclude_bridge == 1) && (PCI_SLOT(devfn) == 0) &&
(hose->first_busno == bus))
return PCIBIOS_DEVICE_NOT_FOUND;
else
return PCIBIOS_SUCCESSFUL;
} /* mv64x60_pci_exclude_device() */
/*
*****************************************************************************
*
* Platform Device Routines
*
*****************************************************************************
*/
/*
* mv64x60_pd_fixup()
*
* Need to add the base addr of where the bridge's regs are mapped in the
* physical addr space so drivers can ioremap() them.
*/
void __init
mv64x60_pd_fixup(struct mv64x60_handle *bh, struct platform_device *pd_devs[],
u32 entries)
{
struct resource *r;
u32 i, j;
for (i=0; i<entries; i++) {
j = 0;
while ((r = platform_get_resource(pd_devs[i],IORESOURCE_MEM,j))
!= NULL) {
r->start += bh->p_base;
r->end += bh->p_base;
j++;
}
}
return;
}
/*
* mv64x60_add_pds()
*
* Add the mv64x60 platform devices to the list of platform devices.
*/
static int __init
mv64x60_add_pds(void)
{
return platform_add_devices(mv64x60_pd_devs,
ARRAY_SIZE(mv64x60_pd_devs));
}
arch_initcall(mv64x60_add_pds);
/*
*****************************************************************************
*
* GT64260-Specific Routines
*
*****************************************************************************
*/
/*
* gt64260_translate_size()
*
* On the GT64260, the size register is really the "top" address of the window.
*/
static u32 __init
gt64260_translate_size(u32 base, u32 size, u32 num_bits)
{
return base + mv64x60_mask(size - 1, num_bits);
}
/*
* gt64260_untranslate_size()
*
* Translate the top address of a window into a window size.
*/
static u32 __init
gt64260_untranslate_size(u32 base, u32 size, u32 num_bits)
{
if (size >= base)
size = size - base + (1 << (32 - num_bits));
else
size = 0;
return size;
}
/*
* gt64260_set_pci2mem_window()
*
* The PCI->MEM window registers are actually in PCI config space so need
* to set them by setting the correct config space BARs.
*/
static void __init
gt64260_set_pci2mem_window(struct pci_controller *hose, u32 bus, u32 window,
u32 base)
{
u32 reg_addrs[2][4] = {
{ 0x10, 0x14, 0x18, 0x1c }, { 0x90, 0x94, 0x98, 0x9c }
};
u8 save_exclude;
pr_debug("set pci->mem window: %d, hose: %d, base: 0x%x\n", window,
hose->index, base);
save_exclude = mv64x60_pci_exclude_bridge;
mv64x60_pci_exclude_bridge = 0;
early_write_config_dword(hose, 0, PCI_DEVFN(0, 0),
reg_addrs[bus][window], mv64x60_mask(base, 20) | 0x8);
mv64x60_pci_exclude_bridge = save_exclude;
return;
}
/*
* gt64260_set_pci2regs_window()
*
* Set where the bridge's registers appear in PCI MEM space.
*/
static void __init
gt64260_set_pci2regs_window(struct mv64x60_handle *bh,
struct pci_controller *hose, u32 bus, u32 base)
{
u32 offset[2] = {0x20, 0xa0};
u8 save_exclude;
pr_debug("set pci->internal regs hose: %d, base: 0x%x\n", hose->index,
base);
save_exclude = mv64x60_pci_exclude_bridge;
mv64x60_pci_exclude_bridge = 0;
early_write_config_dword(hose, 0, PCI_DEVFN(0,0), offset[bus],
(base << 16));
mv64x60_pci_exclude_bridge = save_exclude;
return;
}
/*
* gt64260_is_enabled_32bit()
*
* On a GT64260, a window is enabled iff its top address is >= to its base
* address.
*/
static u32 __init
gt64260_is_enabled_32bit(struct mv64x60_handle *bh, u32 window)
{
u32 rc = 0;
if ((gt64260_32bit_windows[window].base_reg != 0) &&
(gt64260_32bit_windows[window].size_reg != 0) &&
((mv64x60_read(bh, gt64260_32bit_windows[window].size_reg) &
((1 << gt64260_32bit_windows[window].size_bits) - 1)) >=
(mv64x60_read(bh, gt64260_32bit_windows[window].base_reg) &
((1 << gt64260_32bit_windows[window].base_bits) - 1))))
rc = 1;
return rc;
}
/*
* gt64260_enable_window_32bit()
*
* On the GT64260, a window is enabled iff the top address is >= to the base
* address of the window. Since the window has already been configured by
* the time this routine is called, we have nothing to do here.
*/
static void __init
gt64260_enable_window_32bit(struct mv64x60_handle *bh, u32 window)
{
pr_debug("enable 32bit window: %d\n", window);
return;
}
/*
* gt64260_disable_window_32bit()
*
* On a GT64260, you disable a window by setting its top address to be less
* than its base address.
*/
static void __init
gt64260_disable_window_32bit(struct mv64x60_handle *bh, u32 window)
{
pr_debug("disable 32bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n",
window, gt64260_32bit_windows[window].base_reg,
gt64260_32bit_windows[window].size_reg);
if ((gt64260_32bit_windows[window].base_reg != 0) &&
(gt64260_32bit_windows[window].size_reg != 0)) {
/* To disable, make bottom reg higher than top reg */
mv64x60_write(bh, gt64260_32bit_windows[window].base_reg,0xfff);
mv64x60_write(bh, gt64260_32bit_windows[window].size_reg, 0);
}
return;
}
/*
* gt64260_enable_window_64bit()
*
* On the GT64260, a window is enabled iff the top address is >= to the base
* address of the window. Since the window has already been configured by
* the time this routine is called, we have nothing to do here.
*/
static void __init
gt64260_enable_window_64bit(struct mv64x60_handle *bh, u32 window)
{
pr_debug("enable 64bit window: %d\n", window);
return; /* Enabled when window configured (i.e., when top >= base) */
}
/*
* gt64260_disable_window_64bit()
*
* On a GT64260, you disable a window by setting its top address to be less
* than its base address.
*/
static void __init
gt64260_disable_window_64bit(struct mv64x60_handle *bh, u32 window)
{
pr_debug("disable 64bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n",
window, gt64260_64bit_windows[window].base_lo_reg,
gt64260_64bit_windows[window].size_reg);
if ((gt64260_64bit_windows[window].base_lo_reg != 0) &&
(gt64260_64bit_windows[window].size_reg != 0)) {
/* To disable, make bottom reg higher than top reg */
mv64x60_write(bh, gt64260_64bit_windows[window].base_lo_reg,
0xfff);
mv64x60_write(bh, gt64260_64bit_windows[window].base_hi_reg, 0);
mv64x60_write(bh, gt64260_64bit_windows[window].size_reg, 0);
}
return;
}
/*
* gt64260_disable_all_windows()
*
* The GT64260 has several windows that aren't represented in the table of
* windows at the top of this file. This routine turns all of them off
* except for the memory controller windows, of course.
*/
static void __init
gt64260_disable_all_windows(struct mv64x60_handle *bh,
struct mv64x60_setup_info *si)
{
u32 i, preserve;
/* Disable 32bit windows (don't disable cpu->mem windows) */
for (i=MV64x60_CPU2DEV_0_WIN; i<MV64x60_32BIT_WIN_COUNT; i++) {
if (i < 32)
preserve = si->window_preserve_mask_32_lo & (1 << i);
else
preserve = si->window_preserve_mask_32_hi & (1<<(i-32));
if (!preserve)
gt64260_disable_window_32bit(bh, i);
}
/* Disable 64bit windows */
for (i=0; i<MV64x60_64BIT_WIN_COUNT; i++)
if (!(si->window_preserve_mask_64 & (1<<i)))
gt64260_disable_window_64bit(bh, i);
/* Turn off cpu protection windows not in gt64260_32bit_windows[] */
mv64x60_write(bh, GT64260_CPU_PROT_BASE_4, 0xfff);
mv64x60_write(bh, GT64260_CPU_PROT_SIZE_4, 0);
mv64x60_write(bh, GT64260_CPU_PROT_BASE_5, 0xfff);
mv64x60_write(bh, GT64260_CPU_PROT_SIZE_5, 0);
mv64x60_write(bh, GT64260_CPU_PROT_BASE_6, 0xfff);
mv64x60_write(bh, GT64260_CPU_PROT_SIZE_6, 0);
mv64x60_write(bh, GT64260_CPU_PROT_BASE_7, 0xfff);
mv64x60_write(bh, GT64260_CPU_PROT_SIZE_7, 0);
/* Turn off PCI->MEM access cntl wins not in gt64260_64bit_windows[] */
mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_4_BASE_LO, 0xfff);
mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_4_BASE_HI, 0);
mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_4_SIZE, 0);
mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_5_BASE_LO, 0xfff);
mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_5_BASE_HI, 0);
mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_5_SIZE, 0);
mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_6_BASE_LO, 0xfff);
mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_6_BASE_HI, 0);
mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_6_SIZE, 0);
mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_7_BASE_LO, 0xfff);
mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_7_BASE_HI, 0);
mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_7_SIZE, 0);
mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_4_BASE_LO, 0xfff);
mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_4_BASE_HI, 0);
mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_4_SIZE, 0);
mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_5_BASE_LO, 0xfff);
mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_5_BASE_HI, 0);
mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_5_SIZE, 0);
mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_6_BASE_LO, 0xfff);
mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_6_BASE_HI, 0);
mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_6_SIZE, 0);
mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_7_BASE_LO, 0xfff);
mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_7_BASE_HI, 0);
mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_7_SIZE, 0);
/* Disable all PCI-><whatever> windows */
mv64x60_set_bits(bh, MV64x60_PCI0_BAR_ENABLE, 0x07fffdff);
mv64x60_set_bits(bh, MV64x60_PCI1_BAR_ENABLE, 0x07fffdff);
/*
* Some firmwares enable a bunch of intr sources
* for the PCI INT output pins.
*/
mv64x60_write(bh, GT64260_IC_CPU_INTR_MASK_LO, 0);
mv64x60_write(bh, GT64260_IC_CPU_INTR_MASK_HI, 0);
mv64x60_write(bh, GT64260_IC_PCI0_INTR_MASK_LO, 0);
mv64x60_write(bh, GT64260_IC_PCI0_INTR_MASK_HI, 0);
mv64x60_write(bh, GT64260_IC_PCI1_INTR_MASK_LO, 0);
mv64x60_write(bh, GT64260_IC_PCI1_INTR_MASK_HI, 0);
mv64x60_write(bh, GT64260_IC_CPU_INT_0_MASK, 0);
mv64x60_write(bh, GT64260_IC_CPU_INT_1_MASK, 0);
mv64x60_write(bh, GT64260_IC_CPU_INT_2_MASK, 0);
mv64x60_write(bh, GT64260_IC_CPU_INT_3_MASK, 0);
return;
}
/*
* gt64260a_chip_specific_init()
*
* Implement errata work arounds for the GT64260A.
*/
static void __init
gt64260a_chip_specific_init(struct mv64x60_handle *bh,
struct mv64x60_setup_info *si)
{
#ifdef CONFIG_SERIAL_MPSC
struct resource *r;
#endif
#if !defined(CONFIG_NOT_COHERENT_CACHE)
u32 val;
u8 save_exclude;
#endif
if (si->pci_0.enable_bus)
mv64x60_set_bits(bh, MV64x60_PCI0_CMD,
((1<<4) | (1<<5) | (1<<9) | (1<<13)));
if (si->pci_1.enable_bus)
mv64x60_set_bits(bh, MV64x60_PCI1_CMD,
((1<<4) | (1<<5) | (1<<9) | (1<<13)));
/*
* Dave Wilhardt found that bit 4 in the PCI Command registers must
* be set if you are using cache coherency.
*/
#if !defined(CONFIG_NOT_COHERENT_CACHE)
/* Res #MEM-4 -- cpu read buffer to buffer 1 */
if ((mv64x60_read(bh, MV64x60_CPU_MODE) & 0xf0) == 0x40)
mv64x60_set_bits(bh, GT64260_SDRAM_CONFIG, (1<<26));
save_exclude = mv64x60_pci_exclude_bridge;
mv64x60_pci_exclude_bridge = 0;
if (si->pci_0.enable_bus) {
early_read_config_dword(bh->hose_a, 0, PCI_DEVFN(0,0),
PCI_COMMAND, &val);
val |= PCI_COMMAND_INVALIDATE;
early_write_config_dword(bh->hose_a, 0, PCI_DEVFN(0,0),
PCI_COMMAND, val);
}
if (si->pci_1.enable_bus) {
early_read_config_dword(bh->hose_b, 0, PCI_DEVFN(0,0),
PCI_COMMAND, &val);
val |= PCI_COMMAND_INVALIDATE;
early_write_config_dword(bh->hose_b, 0, PCI_DEVFN(0,0),
PCI_COMMAND, val);
}
mv64x60_pci_exclude_bridge = save_exclude;
#endif
/* Disable buffer/descriptor snooping */
mv64x60_clr_bits(bh, 0xf280, (1<< 6) | (1<<14) | (1<<22) | (1<<30));
mv64x60_clr_bits(bh, 0xf2c0, (1<< 6) | (1<<14) | (1<<22) | (1<<30));
#ifdef CONFIG_SERIAL_MPSC
mv64x60_mpsc0_pd_dd.mirror_regs = 1;
mv64x60_mpsc0_pd_dd.cache_mgmt = 1;
mv64x60_mpsc1_pd_dd.mirror_regs = 1;
mv64x60_mpsc1_pd_dd.cache_mgmt = 1;
if ((r = platform_get_resource(&mpsc1_device, IORESOURCE_IRQ, 0))
!= NULL) {
r->start = MV64x60_IRQ_SDMA_0;
r->end = MV64x60_IRQ_SDMA_0;
}
#endif
return;
}
/*
* gt64260b_chip_specific_init()
*
* Implement errata work arounds for the GT64260B.
*/
static void __init
gt64260b_chip_specific_init(struct mv64x60_handle *bh,
struct mv64x60_setup_info *si)
{
#ifdef CONFIG_SERIAL_MPSC
struct resource *r;
#endif
#if !defined(CONFIG_NOT_COHERENT_CACHE)
u32 val;
u8 save_exclude;
#endif
if (si->pci_0.enable_bus)
mv64x60_set_bits(bh, MV64x60_PCI0_CMD,
((1<<4) | (1<<5) | (1<<9) | (1<<13)));
if (si->pci_1.enable_bus)
mv64x60_set_bits(bh, MV64x60_PCI1_CMD,
((1<<4) | (1<<5) | (1<<9) | (1<<13)));
/*
* Dave Wilhardt found that bit 4 in the PCI Command registers must
* be set if you are using cache coherency.
*/
#if !defined(CONFIG_NOT_COHERENT_CACHE)
mv64x60_set_bits(bh, GT64260_CPU_WB_PRIORITY_BUFFER_DEPTH, 0xf);
/* Res #MEM-4 -- cpu read buffer to buffer 1 */
if ((mv64x60_read(bh, MV64x60_CPU_MODE) & 0xf0) == 0x40)
mv64x60_set_bits(bh, GT64260_SDRAM_CONFIG, (1<<26));
save_exclude = mv64x60_pci_exclude_bridge;
mv64x60_pci_exclude_bridge = 0;
if (si->pci_0.enable_bus) {
early_read_config_dword(bh->hose_a, 0, PCI_DEVFN(0,0),
PCI_COMMAND, &val);
val |= PCI_COMMAND_INVALIDATE;
early_write_config_dword(bh->hose_a, 0, PCI_DEVFN(0,0),
PCI_COMMAND, val);
}
if (si->pci_1.enable_bus) {
early_read_config_dword(bh->hose_b, 0, PCI_DEVFN(0,0),
PCI_COMMAND, &val);
val |= PCI_COMMAND_INVALIDATE;
early_write_config_dword(bh->hose_b, 0, PCI_DEVFN(0,0),
PCI_COMMAND, val);
}
mv64x60_pci_exclude_bridge = save_exclude;
#endif
/* Disable buffer/descriptor snooping */
mv64x60_clr_bits(bh, 0xf280, (1<< 6) | (1<<14) | (1<<22) | (1<<30));
mv64x60_clr_bits(bh, 0xf2c0, (1<< 6) | (1<<14) | (1<<22) | (1<<30));
#ifdef CONFIG_SERIAL_MPSC
/*
* The 64260B is not supposed to have the bug where the MPSC & ENET
* can't access cache coherent regions. However, testing has shown
* that the MPSC, at least, still has this bug.
*/
mv64x60_mpsc0_pd_dd.cache_mgmt = 1;
mv64x60_mpsc1_pd_dd.cache_mgmt = 1;
if ((r = platform_get_resource(&mpsc1_device, IORESOURCE_IRQ, 0))
!= NULL) {
r->start = MV64x60_IRQ_SDMA_0;
r->end = MV64x60_IRQ_SDMA_0;
}
#endif
return;
}
/*
*****************************************************************************
*
* MV64360-Specific Routines
*
*****************************************************************************
*/
/*
* mv64360_translate_size()
*
* On the MV64360, the size register is set similar to the size you get
* from a pci config space BAR register. That is, programmed from LSB to MSB
* as a sequence of 1's followed by a sequence of 0's. IOW, "size -1" with the
* assumption that the size is a power of 2.
*/
static u32 __init
mv64360_translate_size(u32 base_addr, u32 size, u32 num_bits)
{
return mv64x60_mask(size - 1, num_bits);
}
/*
* mv64360_untranslate_size()
*
* Translate the size register value of a window into a window size.
*/
static u32 __init
mv64360_untranslate_size(u32 base_addr, u32 size, u32 num_bits)
{
if (size > 0) {
size >>= (32 - num_bits);
size++;
size <<= (32 - num_bits);
}
return size;
}
/*
* mv64360_set_pci2mem_window()
*
* The PCI->MEM window registers are actually in PCI config space so need
* to set them by setting the correct config space BARs.
*/
static void __init
mv64360_set_pci2mem_window(struct pci_controller *hose, u32 bus, u32 window,
u32 base)
{
struct {
u32 fcn;
u32 base_hi_bar;
u32 base_lo_bar;
} reg_addrs[2][4] = {
{{ 0, 0x14, 0x10 }, { 0, 0x1c, 0x18 },
{ 1, 0x14, 0x10 }, { 1, 0x1c, 0x18 }},
{{ 0, 0x94, 0x90 }, { 0, 0x9c, 0x98 },
{ 1, 0x94, 0x90 }, { 1, 0x9c, 0x98 }}
};
u8 save_exclude;
pr_debug("set pci->mem window: %d, hose: %d, base: 0x%x\n", window,
hose->index, base);
save_exclude = mv64x60_pci_exclude_bridge;
mv64x60_pci_exclude_bridge = 0;
early_write_config_dword(hose, 0,
PCI_DEVFN(0, reg_addrs[bus][window].fcn),
reg_addrs[bus][window].base_hi_bar, 0);
early_write_config_dword(hose, 0,
PCI_DEVFN(0, reg_addrs[bus][window].fcn),
reg_addrs[bus][window].base_lo_bar,mv64x60_mask(base,20) | 0xc);
mv64x60_pci_exclude_bridge = save_exclude;
return;
}
/*
* mv64360_set_pci2regs_window()
*
* Set where the bridge's registers appear in PCI MEM space.
*/
static void __init
mv64360_set_pci2regs_window(struct mv64x60_handle *bh,
struct pci_controller *hose, u32 bus, u32 base)
{
u32 offset[2][2] = {{0x20, 0x24}, {0xa0, 0xa4}};
u8 save_exclude;
pr_debug("set pci->internal regs hose: %d, base: 0x%x\n", hose->index,
base);
save_exclude = mv64x60_pci_exclude_bridge;
mv64x60_pci_exclude_bridge = 0;
early_write_config_dword(hose, 0, PCI_DEVFN(0,0), offset[bus][0],
(base << 16));
early_write_config_dword(hose, 0, PCI_DEVFN(0,0), offset[bus][1], 0);
mv64x60_pci_exclude_bridge = save_exclude;
return;
}
/*
* mv64360_is_enabled_32bit()
*
* On a MV64360, a window is enabled by either clearing a bit in the
* CPU BAR Enable reg or setting a bit in the window's base reg.
* Note that this doesn't work for windows on the PCI slave side but we don't
* check those so its okay.
*/
static u32 __init
mv64360_is_enabled_32bit(struct mv64x60_handle *bh, u32 window)
{
u32 extra, rc = 0;
if (((mv64360_32bit_windows[window].base_reg != 0) &&
(mv64360_32bit_windows[window].size_reg != 0)) ||
(window == MV64x60_CPU2SRAM_WIN)) {
extra = mv64360_32bit_windows[window].extra;
switch (extra & MV64x60_EXTRA_MASK) {
case MV64x60_EXTRA_CPUWIN_ENAB:
rc = (mv64x60_read(bh, MV64360_CPU_BAR_ENABLE) &
(1 << (extra & 0x1f))) == 0;
break;
case MV64x60_EXTRA_CPUPROT_ENAB:
rc = (mv64x60_read(bh,
mv64360_32bit_windows[window].base_reg) &
(1 << (extra & 0x1f))) != 0;
break;
case MV64x60_EXTRA_ENET_ENAB:
rc = (mv64x60_read(bh, MV64360_ENET2MEM_BAR_ENABLE) &
(1 << (extra & 0x7))) == 0;
break;
case MV64x60_EXTRA_MPSC_ENAB:
rc = (mv64x60_read(bh, MV64360_MPSC2MEM_BAR_ENABLE) &
(1 << (extra & 0x3))) == 0;
break;
case MV64x60_EXTRA_IDMA_ENAB:
rc = (mv64x60_read(bh, MV64360_IDMA2MEM_BAR_ENABLE) &
(1 << (extra & 0x7))) == 0;
break;
default:
printk(KERN_ERR "mv64360_is_enabled: %s\n",
"32bit table corrupted");
}
}
return rc;
}
/*
* mv64360_enable_window_32bit()
*
* On a MV64360, a window is enabled by either clearing a bit in the
* CPU BAR Enable reg or setting a bit in the window's base reg.
*/
static void __init
mv64360_enable_window_32bit(struct mv64x60_handle *bh, u32 window)
{
u32 extra;
pr_debug("enable 32bit window: %d\n", window);
if (((mv64360_32bit_windows[window].base_reg != 0) &&
(mv64360_32bit_windows[window].size_reg != 0)) ||
(window == MV64x60_CPU2SRAM_WIN)) {
extra = mv64360_32bit_windows[window].extra;
switch (extra & MV64x60_EXTRA_MASK) {
case MV64x60_EXTRA_CPUWIN_ENAB:
mv64x60_clr_bits(bh, MV64360_CPU_BAR_ENABLE,
(1 << (extra & 0x1f)));
break;
case MV64x60_EXTRA_CPUPROT_ENAB:
mv64x60_set_bits(bh,
mv64360_32bit_windows[window].base_reg,
(1 << (extra & 0x1f)));
break;
case MV64x60_EXTRA_ENET_ENAB:
mv64x60_clr_bits(bh, MV64360_ENET2MEM_BAR_ENABLE,
(1 << (extra & 0x7)));
break;
case MV64x60_EXTRA_MPSC_ENAB:
mv64x60_clr_bits(bh, MV64360_MPSC2MEM_BAR_ENABLE,
(1 << (extra & 0x3)));
break;
case MV64x60_EXTRA_IDMA_ENAB:
mv64x60_clr_bits(bh, MV64360_IDMA2MEM_BAR_ENABLE,
(1 << (extra & 0x7)));
break;
default:
printk(KERN_ERR "mv64360_enable: %s\n",
"32bit table corrupted");
}
}
return;
}
/*
* mv64360_disable_window_32bit()
*
* On a MV64360, a window is disabled by either setting a bit in the
* CPU BAR Enable reg or clearing a bit in the window's base reg.
*/
static void __init
mv64360_disable_window_32bit(struct mv64x60_handle *bh, u32 window)
{
u32 extra;
pr_debug("disable 32bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n",
window, mv64360_32bit_windows[window].base_reg,
mv64360_32bit_windows[window].size_reg);
if (((mv64360_32bit_windows[window].base_reg != 0) &&
(mv64360_32bit_windows[window].size_reg != 0)) ||
(window == MV64x60_CPU2SRAM_WIN)) {
extra = mv64360_32bit_windows[window].extra;
switch (extra & MV64x60_EXTRA_MASK) {
case MV64x60_EXTRA_CPUWIN_ENAB:
mv64x60_set_bits(bh, MV64360_CPU_BAR_ENABLE,
(1 << (extra & 0x1f)));
break;
case MV64x60_EXTRA_CPUPROT_ENAB:
mv64x60_clr_bits(bh,
mv64360_32bit_windows[window].base_reg,
(1 << (extra & 0x1f)));
break;
case MV64x60_EXTRA_ENET_ENAB:
mv64x60_set_bits(bh, MV64360_ENET2MEM_BAR_ENABLE,
(1 << (extra & 0x7)));
break;
case MV64x60_EXTRA_MPSC_ENAB:
mv64x60_set_bits(bh, MV64360_MPSC2MEM_BAR_ENABLE,
(1 << (extra & 0x3)));
break;
case MV64x60_EXTRA_IDMA_ENAB:
mv64x60_set_bits(bh, MV64360_IDMA2MEM_BAR_ENABLE,
(1 << (extra & 0x7)));
break;
default:
printk(KERN_ERR "mv64360_disable: %s\n",
"32bit table corrupted");
}
}
return;
}
/*
* mv64360_enable_window_64bit()
*
* On the MV64360, a 64-bit window is enabled by setting a bit in the window's
* base reg.
*/
static void __init
mv64360_enable_window_64bit(struct mv64x60_handle *bh, u32 window)
{
pr_debug("enable 64bit window: %d\n", window);
if ((mv64360_64bit_windows[window].base_lo_reg!= 0) &&
(mv64360_64bit_windows[window].size_reg != 0)) {
if ((mv64360_64bit_windows[window].extra & MV64x60_EXTRA_MASK)
== MV64x60_EXTRA_PCIACC_ENAB)
mv64x60_set_bits(bh,
mv64360_64bit_windows[window].base_lo_reg,
(1 << (mv64360_64bit_windows[window].extra &
0x1f)));
else
printk(KERN_ERR "mv64360_enable: %s\n",
"64bit table corrupted");
}
return;
}
/*
* mv64360_disable_window_64bit()
*
* On a MV64360, a 64-bit window is disabled by clearing a bit in the window's
* base reg.
*/
static void __init
mv64360_disable_window_64bit(struct mv64x60_handle *bh, u32 window)
{
pr_debug("disable 64bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n",
window, mv64360_64bit_windows[window].base_lo_reg,
mv64360_64bit_windows[window].size_reg);
if ((mv64360_64bit_windows[window].base_lo_reg != 0) &&
(mv64360_64bit_windows[window].size_reg != 0)) {
if ((mv64360_64bit_windows[window].extra & MV64x60_EXTRA_MASK)
== MV64x60_EXTRA_PCIACC_ENAB)
mv64x60_clr_bits(bh,
mv64360_64bit_windows[window].base_lo_reg,
(1 << (mv64360_64bit_windows[window].extra &
0x1f)));
else
printk(KERN_ERR "mv64360_disable: %s\n",
"64bit table corrupted");
}
return;
}
/*
* mv64360_disable_all_windows()
*
* The MV64360 has a few windows that aren't represented in the table of
* windows at the top of this file. This routine turns all of them off
* except for the memory controller windows, of course.
*/
static void __init
mv64360_disable_all_windows(struct mv64x60_handle *bh,
struct mv64x60_setup_info *si)
{
u32 preserve, i;
/* Disable 32bit windows (don't disable cpu->mem windows) */
for (i=MV64x60_CPU2DEV_0_WIN; i<MV64x60_32BIT_WIN_COUNT; i++) {
if (i < 32)
preserve = si->window_preserve_mask_32_lo & (1 << i);
else
preserve = si->window_preserve_mask_32_hi & (1<<(i-32));
if (!preserve)
mv64360_disable_window_32bit(bh, i);
}
/* Disable 64bit windows */
for (i=0; i<MV64x60_64BIT_WIN_COUNT; i++)
if (!(si->window_preserve_mask_64 & (1<<i)))
mv64360_disable_window_64bit(bh, i);
/* Turn off PCI->MEM access cntl wins not in mv64360_64bit_windows[] */
mv64x60_clr_bits(bh, MV64x60_PCI0_ACC_CNTL_4_BASE_LO, 0);
mv64x60_clr_bits(bh, MV64x60_PCI0_ACC_CNTL_5_BASE_LO, 0);
mv64x60_clr_bits(bh, MV64x60_PCI1_ACC_CNTL_4_BASE_LO, 0);
mv64x60_clr_bits(bh, MV64x60_PCI1_ACC_CNTL_5_BASE_LO, 0);
/* Disable all PCI-><whatever> windows */
mv64x60_set_bits(bh, MV64x60_PCI0_BAR_ENABLE, 0x0000f9ff);
mv64x60_set_bits(bh, MV64x60_PCI1_BAR_ENABLE, 0x0000f9ff);
return;
}
/*
* mv64360_config_io2mem_windows()
*
* ENET, MPSC, and IDMA ctlrs on the MV64[34]60 have separate windows that
* must be set up so that the respective ctlr can access system memory.
*/
static void __init
mv64360_config_io2mem_windows(struct mv64x60_handle *bh,
struct mv64x60_setup_info *si,
u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
{
u32 i, win;
u32 enet_tab[MV64x60_CPU2MEM_WINDOWS] = {
MV64x60_ENET2MEM_0_WIN, MV64x60_ENET2MEM_1_WIN,
MV64x60_ENET2MEM_2_WIN, MV64x60_ENET2MEM_3_WIN,
};
u32 mpsc_tab[MV64x60_CPU2MEM_WINDOWS] = {
MV64x60_MPSC2MEM_0_WIN, MV64x60_MPSC2MEM_1_WIN,
MV64x60_MPSC2MEM_2_WIN, MV64x60_MPSC2MEM_3_WIN,
};
u32 idma_tab[MV64x60_CPU2MEM_WINDOWS] = {
MV64x60_IDMA2MEM_0_WIN, MV64x60_IDMA2MEM_1_WIN,
MV64x60_IDMA2MEM_2_WIN, MV64x60_IDMA2MEM_3_WIN,
};
u32 dram_selects[MV64x60_CPU2MEM_WINDOWS] = { 0xe, 0xd, 0xb, 0x7 };
pr_debug("config_io2regs_windows: enet, mpsc, idma -> bridge regs\n");
mv64x60_write(bh, MV64360_ENET2MEM_ACC_PROT_0, 0);
mv64x60_write(bh, MV64360_ENET2MEM_ACC_PROT_1, 0);
mv64x60_write(bh, MV64360_ENET2MEM_ACC_PROT_2, 0);
mv64x60_write(bh, MV64360_MPSC2MEM_ACC_PROT_0, 0);
mv64x60_write(bh, MV64360_MPSC2MEM_ACC_PROT_1, 0);
mv64x60_write(bh, MV64360_IDMA2MEM_ACC_PROT_0, 0);
mv64x60_write(bh, MV64360_IDMA2MEM_ACC_PROT_1, 0);
mv64x60_write(bh, MV64360_IDMA2MEM_ACC_PROT_2, 0);
mv64x60_write(bh, MV64360_IDMA2MEM_ACC_PROT_3, 0);
/* Assume that mem ctlr has no more windows than embedded I/O ctlr */
for (win=MV64x60_CPU2MEM_0_WIN,i=0;win<=MV64x60_CPU2MEM_3_WIN;win++,i++)
if (bh->ci->is_enabled_32bit(bh, win)) {
mv64x60_set_32bit_window(bh, enet_tab[i],
mem_windows[i][0], mem_windows[i][1],
(dram_selects[i] << 8) |
(si->enet_options[i] & 0x3000));
bh->ci->enable_window_32bit(bh, enet_tab[i]);
/* Give enet r/w access to memory region */
mv64x60_set_bits(bh, MV64360_ENET2MEM_ACC_PROT_0,
(0x3 << (i << 1)));
mv64x60_set_bits(bh, MV64360_ENET2MEM_ACC_PROT_1,
(0x3 << (i << 1)));
mv64x60_set_bits(bh, MV64360_ENET2MEM_ACC_PROT_2,
(0x3 << (i << 1)));
mv64x60_set_32bit_window(bh, mpsc_tab[i],
mem_windows[i][0], mem_windows[i][1],
(dram_selects[i] << 8) |
(si->mpsc_options[i] & 0x3000));
bh->ci->enable_window_32bit(bh, mpsc_tab[i]);
/* Give mpsc r/w access to memory region */
mv64x60_set_bits(bh, MV64360_MPSC2MEM_ACC_PROT_0,
(0x3 << (i << 1)));
mv64x60_set_bits(bh, MV64360_MPSC2MEM_ACC_PROT_1,
(0x3 << (i << 1)));
mv64x60_set_32bit_window(bh, idma_tab[i],
mem_windows[i][0], mem_windows[i][1],
(dram_selects[i] << 8) |
(si->idma_options[i] & 0x3000));
bh->ci->enable_window_32bit(bh, idma_tab[i]);
/* Give idma r/w access to memory region */
mv64x60_set_bits(bh, MV64360_IDMA2MEM_ACC_PROT_0,
(0x3 << (i << 1)));
mv64x60_set_bits(bh, MV64360_IDMA2MEM_ACC_PROT_1,
(0x3 << (i << 1)));
mv64x60_set_bits(bh, MV64360_IDMA2MEM_ACC_PROT_2,
(0x3 << (i << 1)));
mv64x60_set_bits(bh, MV64360_IDMA2MEM_ACC_PROT_3,
(0x3 << (i << 1)));
}
return;
}
/*
* mv64360_set_mpsc2regs_window()
*
* MPSC has a window to the bridge's internal registers. Call this routine
* to change that window so it doesn't conflict with the windows mapping the
* mpsc to system memory.
*/
static void __init
mv64360_set_mpsc2regs_window(struct mv64x60_handle *bh, u32 base)
{
pr_debug("set mpsc->internal regs, base: 0x%x\n", base);
mv64x60_write(bh, MV64360_MPSC2REGS_BASE, base & 0xffff0000);
return;
}
/*
* mv64360_chip_specific_init()
*
* No errata work arounds for the MV64360 implemented at this point.
*/
static void __init
mv64360_chip_specific_init(struct mv64x60_handle *bh,
struct mv64x60_setup_info *si)
{
#ifdef CONFIG_SERIAL_MPSC
mv64x60_mpsc0_pd_dd.brg_can_tune = 1;
mv64x60_mpsc0_pd_dd.cache_mgmt = 1;
mv64x60_mpsc1_pd_dd.brg_can_tune = 1;
mv64x60_mpsc1_pd_dd.cache_mgmt = 1;
#endif
return;
}
/*
* mv64460_chip_specific_init()
*
* No errata work arounds for the MV64460 implemented at this point.
*/
static void __init
mv64460_chip_specific_init(struct mv64x60_handle *bh,
struct mv64x60_setup_info *si)
{
#ifdef CONFIG_SERIAL_MPSC
mv64x60_mpsc0_pd_dd.brg_can_tune = 1;
mv64x60_mpsc1_pd_dd.brg_can_tune = 1;
#endif
return;
}
/*
* arch/ppc/syslib/mv64x60_dbg.c
*
* KGDB and progress routines for the Marvell/Galileo MV64x60 (Discovery).
*
* Author: Mark A. Greer <mgreer@mvista.com>
*
* 2003 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
/*
*****************************************************************************
*
* Low-level MPSC/UART I/O routines
*
*****************************************************************************
*/
#include <linux/config.h>
#include <linux/irq.h>
#include <asm/delay.h>
#include <asm/mv64x60.h>
#if defined(CONFIG_SERIAL_TEXT_DEBUG)
#define MPSC_CHR_1 0x000c
#define MPSC_CHR_2 0x0010
static struct mv64x60_handle mv64x60_dbg_bh;
void
mv64x60_progress_init(u32 base)
{
mv64x60_dbg_bh.v_base = base;
return;
}
static void
mv64x60_polled_putc(int chan, char c)
{
u32 offset;
if (chan == 0)
offset = 0x8000;
else
offset = 0x9000;
mv64x60_write(&mv64x60_dbg_bh, offset + MPSC_CHR_1, (u32)c);
mv64x60_write(&mv64x60_dbg_bh, offset + MPSC_CHR_2, 0x200);
udelay(2000);
}
void
mv64x60_mpsc_progress(char *s, unsigned short hex)
{
volatile char c;
mv64x60_polled_putc(0, '\r');
while ((c = *s++) != 0)
mv64x60_polled_putc(0, c);
mv64x60_polled_putc(0, '\n');
mv64x60_polled_putc(0, '\r');
return;
}
#endif /* CONFIG_SERIAL_TEXT_DEBUG */
#if defined(CONFIG_KGDB)
#if defined(CONFIG_KGDB_TTYS0)
#define KGDB_PORT 0
#elif defined(CONFIG_KGDB_TTYS1)
#define KGDB_PORT 1
#else
#error "Invalid kgdb_tty port"
#endif
void
putDebugChar(unsigned char c)
{
mv64x60_polled_putc(KGDB_PORT, (char)c);
}
int
getDebugChar(void)
{
unsigned char c;
while (!mv64x60_polled_getc(KGDB_PORT, &c));
return (int)c;
}
void
putDebugString(char* str)
{
while (*str != '\0') {
putDebugChar(*str);
str++;
}
putDebugChar('\r');
return;
}
void
kgdb_interruptible(int enable)
{
}
void
kgdb_map_scc(void)
{
if (ppc_md.early_serial_map)
ppc_md.early_serial_map();
}
#endif /* CONFIG_KGDB */
/*
* arch/ppc/syslib/mv64x60_win.c
*
* Tables with info on how to manipulate the 32 & 64 bit windows on the
* various types of Marvell bridge chips.
*
* Author: Mark A. Greer <mgreer@mvista.com>
*
* 2004 (c) MontaVista, Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/bootmem.h>
#include <linux/mv643xx.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
#include <asm/delay.h>
#include <asm/mv64x60.h>
/*
*****************************************************************************
*
* Tables describing how to set up windows on each type of bridge
*
*****************************************************************************
*/
struct mv64x60_32bit_window
gt64260_32bit_windows[MV64x60_32BIT_WIN_COUNT] __initdata = {
/* CPU->MEM Windows */
[MV64x60_CPU2MEM_0_WIN] = {
.base_reg = MV64x60_CPU2MEM_0_BASE,
.size_reg = MV64x60_CPU2MEM_0_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2MEM_1_WIN] = {
.base_reg = MV64x60_CPU2MEM_1_BASE,
.size_reg = MV64x60_CPU2MEM_1_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2MEM_2_WIN] = {
.base_reg = MV64x60_CPU2MEM_2_BASE,
.size_reg = MV64x60_CPU2MEM_2_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2MEM_3_WIN] = {
.base_reg = MV64x60_CPU2MEM_3_BASE,
.size_reg = MV64x60_CPU2MEM_3_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
/* CPU->Device Windows */
[MV64x60_CPU2DEV_0_WIN] = {
.base_reg = MV64x60_CPU2DEV_0_BASE,
.size_reg = MV64x60_CPU2DEV_0_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2DEV_1_WIN] = {
.base_reg = MV64x60_CPU2DEV_1_BASE,
.size_reg = MV64x60_CPU2DEV_1_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2DEV_2_WIN] = {
.base_reg = MV64x60_CPU2DEV_2_BASE,
.size_reg = MV64x60_CPU2DEV_2_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2DEV_3_WIN] = {
.base_reg = MV64x60_CPU2DEV_3_BASE,
.size_reg = MV64x60_CPU2DEV_3_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
/* CPU->Boot Window */
[MV64x60_CPU2BOOT_WIN] = {
.base_reg = MV64x60_CPU2BOOT_0_BASE,
.size_reg = MV64x60_CPU2BOOT_0_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
/* CPU->PCI 0 Windows */
[MV64x60_CPU2PCI0_IO_WIN] = {
.base_reg = MV64x60_CPU2PCI0_IO_BASE,
.size_reg = MV64x60_CPU2PCI0_IO_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI0_MEM_0_WIN] = {
.base_reg = MV64x60_CPU2PCI0_MEM_0_BASE,
.size_reg = MV64x60_CPU2PCI0_MEM_0_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI0_MEM_1_WIN] = {
.base_reg = MV64x60_CPU2PCI0_MEM_1_BASE,
.size_reg = MV64x60_CPU2PCI0_MEM_1_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI0_MEM_2_WIN] = {
.base_reg = MV64x60_CPU2PCI0_MEM_2_BASE,
.size_reg = MV64x60_CPU2PCI0_MEM_2_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI0_MEM_3_WIN] = {
.base_reg = MV64x60_CPU2PCI0_MEM_3_BASE,
.size_reg = MV64x60_CPU2PCI0_MEM_3_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
/* CPU->PCI 1 Windows */
[MV64x60_CPU2PCI1_IO_WIN] = {
.base_reg = MV64x60_CPU2PCI1_IO_BASE,
.size_reg = MV64x60_CPU2PCI1_IO_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI1_MEM_0_WIN] = {
.base_reg = MV64x60_CPU2PCI1_MEM_0_BASE,
.size_reg = MV64x60_CPU2PCI1_MEM_0_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI1_MEM_1_WIN] = {
.base_reg = MV64x60_CPU2PCI1_MEM_1_BASE,
.size_reg = MV64x60_CPU2PCI1_MEM_1_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI1_MEM_2_WIN] = {
.base_reg = MV64x60_CPU2PCI1_MEM_2_BASE,
.size_reg = MV64x60_CPU2PCI1_MEM_2_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI1_MEM_3_WIN] = {
.base_reg = MV64x60_CPU2PCI1_MEM_3_BASE,
.size_reg = MV64x60_CPU2PCI1_MEM_3_SIZE,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
/* CPU->SRAM Window (64260 has no integrated SRAM) */
/* CPU->PCI 0 Remap I/O Window */
[MV64x60_CPU2PCI0_IO_REMAP_WIN] = {
.base_reg = MV64x60_CPU2PCI0_IO_REMAP,
.size_reg = 0,
.base_bits = 12,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
/* CPU->PCI 1 Remap I/O Window */
[MV64x60_CPU2PCI1_IO_REMAP_WIN] = {
.base_reg = MV64x60_CPU2PCI1_IO_REMAP,
.size_reg = 0,
.base_bits = 12,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
/* CPU Memory Protection Windows */
[MV64x60_CPU_PROT_0_WIN] = {
.base_reg = MV64x60_CPU_PROT_BASE_0,
.size_reg = MV64x60_CPU_PROT_SIZE_0,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU_PROT_1_WIN] = {
.base_reg = MV64x60_CPU_PROT_BASE_1,
.size_reg = MV64x60_CPU_PROT_SIZE_1,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU_PROT_2_WIN] = {
.base_reg = MV64x60_CPU_PROT_BASE_2,
.size_reg = MV64x60_CPU_PROT_SIZE_2,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU_PROT_3_WIN] = {
.base_reg = MV64x60_CPU_PROT_BASE_3,
.size_reg = MV64x60_CPU_PROT_SIZE_3,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
/* CPU Snoop Windows */
[MV64x60_CPU_SNOOP_0_WIN] = {
.base_reg = GT64260_CPU_SNOOP_BASE_0,
.size_reg = GT64260_CPU_SNOOP_SIZE_0,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU_SNOOP_1_WIN] = {
.base_reg = GT64260_CPU_SNOOP_BASE_1,
.size_reg = GT64260_CPU_SNOOP_SIZE_1,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU_SNOOP_2_WIN] = {
.base_reg = GT64260_CPU_SNOOP_BASE_2,
.size_reg = GT64260_CPU_SNOOP_SIZE_2,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU_SNOOP_3_WIN] = {
.base_reg = GT64260_CPU_SNOOP_BASE_3,
.size_reg = GT64260_CPU_SNOOP_SIZE_3,
.base_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
/* PCI 0->System Memory Remap Windows */
[MV64x60_PCI02MEM_REMAP_0_WIN] = {
.base_reg = MV64x60_PCI0_SLAVE_MEM_0_REMAP,
.size_reg = 0,
.base_bits = 20,
.size_bits = 0,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = 0 },
[MV64x60_PCI02MEM_REMAP_1_WIN] = {
.base_reg = MV64x60_PCI0_SLAVE_MEM_1_REMAP,
.size_reg = 0,
.base_bits = 20,
.size_bits = 0,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = 0 },
[MV64x60_PCI02MEM_REMAP_2_WIN] = {
.base_reg = MV64x60_PCI0_SLAVE_MEM_1_REMAP,
.size_reg = 0,
.base_bits = 20,
.size_bits = 0,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = 0 },
[MV64x60_PCI02MEM_REMAP_3_WIN] = {
.base_reg = MV64x60_PCI0_SLAVE_MEM_1_REMAP,
.size_reg = 0,
.base_bits = 20,
.size_bits = 0,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = 0 },
/* PCI 1->System Memory Remap Windows */
[MV64x60_PCI12MEM_REMAP_0_WIN] = {
.base_reg = MV64x60_PCI1_SLAVE_MEM_0_REMAP,
.size_reg = 0,
.base_bits = 20,
.size_bits = 0,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = 0 },
[MV64x60_PCI12MEM_REMAP_1_WIN] = {
.base_reg = MV64x60_PCI1_SLAVE_MEM_1_REMAP,
.size_reg = 0,
.base_bits = 20,
.size_bits = 0,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = 0 },
[MV64x60_PCI12MEM_REMAP_2_WIN] = {
.base_reg = MV64x60_PCI1_SLAVE_MEM_1_REMAP,
.size_reg = 0,
.base_bits = 20,
.size_bits = 0,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = 0 },
[MV64x60_PCI12MEM_REMAP_3_WIN] = {
.base_reg = MV64x60_PCI1_SLAVE_MEM_1_REMAP,
.size_reg = 0,
.base_bits = 20,
.size_bits = 0,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = 0 },
/* ENET->SRAM Window (64260 doesn't have separate windows) */
/* MPSC->SRAM Window (64260 doesn't have separate windows) */
/* IDMA->SRAM Window (64260 doesn't have separate windows) */
};
struct mv64x60_64bit_window
gt64260_64bit_windows[MV64x60_64BIT_WIN_COUNT] __initdata = {
/* CPU->PCI 0 MEM Remap Windows */
[MV64x60_CPU2PCI0_MEM_0_REMAP_WIN] = {
.base_hi_reg = MV64x60_CPU2PCI0_MEM_0_REMAP_HI,
.base_lo_reg = MV64x60_CPU2PCI0_MEM_0_REMAP_LO,
.size_reg = 0,
.base_lo_bits = 12,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI0_MEM_1_REMAP_WIN] = {
.base_hi_reg = MV64x60_CPU2PCI0_MEM_1_REMAP_HI,
.base_lo_reg = MV64x60_CPU2PCI0_MEM_1_REMAP_LO,
.size_reg = 0,
.base_lo_bits = 12,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI0_MEM_2_REMAP_WIN] = {
.base_hi_reg = MV64x60_CPU2PCI0_MEM_2_REMAP_HI,
.base_lo_reg = MV64x60_CPU2PCI0_MEM_2_REMAP_LO,
.size_reg = 0,
.base_lo_bits = 12,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI0_MEM_3_REMAP_WIN] = {
.base_hi_reg = MV64x60_CPU2PCI0_MEM_3_REMAP_HI,
.base_lo_reg = MV64x60_CPU2PCI0_MEM_3_REMAP_LO,
.size_reg = 0,
.base_lo_bits = 12,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
/* CPU->PCI 1 MEM Remap Windows */
[MV64x60_CPU2PCI1_MEM_0_REMAP_WIN] = {
.base_hi_reg = MV64x60_CPU2PCI1_MEM_0_REMAP_HI,
.base_lo_reg = MV64x60_CPU2PCI1_MEM_0_REMAP_LO,
.size_reg = 0,
.base_lo_bits = 12,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI1_MEM_1_REMAP_WIN] = {
.base_hi_reg = MV64x60_CPU2PCI1_MEM_1_REMAP_HI,
.base_lo_reg = MV64x60_CPU2PCI1_MEM_1_REMAP_LO,
.size_reg = 0,
.base_lo_bits = 12,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI1_MEM_2_REMAP_WIN] = {
.base_hi_reg = MV64x60_CPU2PCI1_MEM_2_REMAP_HI,
.base_lo_reg = MV64x60_CPU2PCI1_MEM_2_REMAP_LO,
.size_reg = 0,
.base_lo_bits = 12,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI1_MEM_3_REMAP_WIN] = {
.base_hi_reg = MV64x60_CPU2PCI1_MEM_3_REMAP_HI,
.base_lo_reg = MV64x60_CPU2PCI1_MEM_3_REMAP_LO,
.size_reg = 0,
.base_lo_bits = 12,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
/* PCI 0->MEM Access Control Windows */
[MV64x60_PCI02MEM_ACC_CNTL_0_WIN] = {
.base_hi_reg = MV64x60_PCI0_ACC_CNTL_0_BASE_HI,
.base_lo_reg = MV64x60_PCI0_ACC_CNTL_0_BASE_LO,
.size_reg = MV64x60_PCI0_ACC_CNTL_0_SIZE,
.base_lo_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_PCI02MEM_ACC_CNTL_1_WIN] = {
.base_hi_reg = MV64x60_PCI0_ACC_CNTL_1_BASE_HI,
.base_lo_reg = MV64x60_PCI0_ACC_CNTL_1_BASE_LO,
.size_reg = MV64x60_PCI0_ACC_CNTL_1_SIZE,
.base_lo_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_PCI02MEM_ACC_CNTL_2_WIN] = {
.base_hi_reg = MV64x60_PCI0_ACC_CNTL_2_BASE_HI,
.base_lo_reg = MV64x60_PCI0_ACC_CNTL_2_BASE_LO,
.size_reg = MV64x60_PCI0_ACC_CNTL_2_SIZE,
.base_lo_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_PCI02MEM_ACC_CNTL_3_WIN] = {
.base_hi_reg = MV64x60_PCI0_ACC_CNTL_3_BASE_HI,
.base_lo_reg = MV64x60_PCI0_ACC_CNTL_3_BASE_LO,
.size_reg = MV64x60_PCI0_ACC_CNTL_3_SIZE,
.base_lo_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
/* PCI 1->MEM Access Control Windows */
[MV64x60_PCI12MEM_ACC_CNTL_0_WIN] = {
.base_hi_reg = MV64x60_PCI1_ACC_CNTL_0_BASE_HI,
.base_lo_reg = MV64x60_PCI1_ACC_CNTL_0_BASE_LO,
.size_reg = MV64x60_PCI1_ACC_CNTL_0_SIZE,
.base_lo_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_PCI12MEM_ACC_CNTL_1_WIN] = {
.base_hi_reg = MV64x60_PCI1_ACC_CNTL_1_BASE_HI,
.base_lo_reg = MV64x60_PCI1_ACC_CNTL_1_BASE_LO,
.size_reg = MV64x60_PCI1_ACC_CNTL_1_SIZE,
.base_lo_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_PCI12MEM_ACC_CNTL_2_WIN] = {
.base_hi_reg = MV64x60_PCI1_ACC_CNTL_2_BASE_HI,
.base_lo_reg = MV64x60_PCI1_ACC_CNTL_2_BASE_LO,
.size_reg = MV64x60_PCI1_ACC_CNTL_2_SIZE,
.base_lo_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_PCI12MEM_ACC_CNTL_3_WIN] = {
.base_hi_reg = MV64x60_PCI1_ACC_CNTL_3_BASE_HI,
.base_lo_reg = MV64x60_PCI1_ACC_CNTL_3_BASE_LO,
.size_reg = MV64x60_PCI1_ACC_CNTL_3_SIZE,
.base_lo_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
/* PCI 0->MEM Snoop Windows */
[MV64x60_PCI02MEM_SNOOP_0_WIN] = {
.base_hi_reg = GT64260_PCI0_SNOOP_0_BASE_HI,
.base_lo_reg = GT64260_PCI0_SNOOP_0_BASE_LO,
.size_reg = GT64260_PCI0_SNOOP_0_SIZE,
.base_lo_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_PCI02MEM_SNOOP_1_WIN] = {
.base_hi_reg = GT64260_PCI0_SNOOP_1_BASE_HI,
.base_lo_reg = GT64260_PCI0_SNOOP_1_BASE_LO,
.size_reg = GT64260_PCI0_SNOOP_1_SIZE,
.base_lo_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_PCI02MEM_SNOOP_2_WIN] = {
.base_hi_reg = GT64260_PCI0_SNOOP_2_BASE_HI,
.base_lo_reg = GT64260_PCI0_SNOOP_2_BASE_LO,
.size_reg = GT64260_PCI0_SNOOP_2_SIZE,
.base_lo_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_PCI02MEM_SNOOP_3_WIN] = {
.base_hi_reg = GT64260_PCI0_SNOOP_3_BASE_HI,
.base_lo_reg = GT64260_PCI0_SNOOP_3_BASE_LO,
.size_reg = GT64260_PCI0_SNOOP_3_SIZE,
.base_lo_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
/* PCI 1->MEM Snoop Windows */
[MV64x60_PCI12MEM_SNOOP_0_WIN] = {
.base_hi_reg = GT64260_PCI1_SNOOP_0_BASE_HI,
.base_lo_reg = GT64260_PCI1_SNOOP_0_BASE_LO,
.size_reg = GT64260_PCI1_SNOOP_0_SIZE,
.base_lo_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_PCI12MEM_SNOOP_1_WIN] = {
.base_hi_reg = GT64260_PCI1_SNOOP_1_BASE_HI,
.base_lo_reg = GT64260_PCI1_SNOOP_1_BASE_LO,
.size_reg = GT64260_PCI1_SNOOP_1_SIZE,
.base_lo_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_PCI12MEM_SNOOP_2_WIN] = {
.base_hi_reg = GT64260_PCI1_SNOOP_2_BASE_HI,
.base_lo_reg = GT64260_PCI1_SNOOP_2_BASE_LO,
.size_reg = GT64260_PCI1_SNOOP_2_SIZE,
.base_lo_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_PCI12MEM_SNOOP_3_WIN] = {
.base_hi_reg = GT64260_PCI1_SNOOP_3_BASE_HI,
.base_lo_reg = GT64260_PCI1_SNOOP_3_BASE_LO,
.size_reg = GT64260_PCI1_SNOOP_3_SIZE,
.base_lo_bits = 12,
.size_bits = 12,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
};
struct mv64x60_32bit_window
mv64360_32bit_windows[MV64x60_32BIT_WIN_COUNT] __initdata = {
/* CPU->MEM Windows */
[MV64x60_CPU2MEM_0_WIN] = {
.base_reg = MV64x60_CPU2MEM_0_BASE,
.size_reg = MV64x60_CPU2MEM_0_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 0 },
[MV64x60_CPU2MEM_1_WIN] = {
.base_reg = MV64x60_CPU2MEM_1_BASE,
.size_reg = MV64x60_CPU2MEM_1_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 1 },
[MV64x60_CPU2MEM_2_WIN] = {
.base_reg = MV64x60_CPU2MEM_2_BASE,
.size_reg = MV64x60_CPU2MEM_2_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 2 },
[MV64x60_CPU2MEM_3_WIN] = {
.base_reg = MV64x60_CPU2MEM_3_BASE,
.size_reg = MV64x60_CPU2MEM_3_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 3 },
/* CPU->Device Windows */
[MV64x60_CPU2DEV_0_WIN] = {
.base_reg = MV64x60_CPU2DEV_0_BASE,
.size_reg = MV64x60_CPU2DEV_0_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 4 },
[MV64x60_CPU2DEV_1_WIN] = {
.base_reg = MV64x60_CPU2DEV_1_BASE,
.size_reg = MV64x60_CPU2DEV_1_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 5 },
[MV64x60_CPU2DEV_2_WIN] = {
.base_reg = MV64x60_CPU2DEV_2_BASE,
.size_reg = MV64x60_CPU2DEV_2_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 6 },
[MV64x60_CPU2DEV_3_WIN] = {
.base_reg = MV64x60_CPU2DEV_3_BASE,
.size_reg = MV64x60_CPU2DEV_3_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 7 },
/* CPU->Boot Window */
[MV64x60_CPU2BOOT_WIN] = {
.base_reg = MV64x60_CPU2BOOT_0_BASE,
.size_reg = MV64x60_CPU2BOOT_0_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 8 },
/* CPU->PCI 0 Windows */
[MV64x60_CPU2PCI0_IO_WIN] = {
.base_reg = MV64x60_CPU2PCI0_IO_BASE,
.size_reg = MV64x60_CPU2PCI0_IO_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 9 },
[MV64x60_CPU2PCI0_MEM_0_WIN] = {
.base_reg = MV64x60_CPU2PCI0_MEM_0_BASE,
.size_reg = MV64x60_CPU2PCI0_MEM_0_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 10 },
[MV64x60_CPU2PCI0_MEM_1_WIN] = {
.base_reg = MV64x60_CPU2PCI0_MEM_1_BASE,
.size_reg = MV64x60_CPU2PCI0_MEM_1_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 11 },
[MV64x60_CPU2PCI0_MEM_2_WIN] = {
.base_reg = MV64x60_CPU2PCI0_MEM_2_BASE,
.size_reg = MV64x60_CPU2PCI0_MEM_2_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 12 },
[MV64x60_CPU2PCI0_MEM_3_WIN] = {
.base_reg = MV64x60_CPU2PCI0_MEM_3_BASE,
.size_reg = MV64x60_CPU2PCI0_MEM_3_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 13 },
/* CPU->PCI 1 Windows */
[MV64x60_CPU2PCI1_IO_WIN] = {
.base_reg = MV64x60_CPU2PCI1_IO_BASE,
.size_reg = MV64x60_CPU2PCI1_IO_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 14 },
[MV64x60_CPU2PCI1_MEM_0_WIN] = {
.base_reg = MV64x60_CPU2PCI1_MEM_0_BASE,
.size_reg = MV64x60_CPU2PCI1_MEM_0_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 15 },
[MV64x60_CPU2PCI1_MEM_1_WIN] = {
.base_reg = MV64x60_CPU2PCI1_MEM_1_BASE,
.size_reg = MV64x60_CPU2PCI1_MEM_1_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 16 },
[MV64x60_CPU2PCI1_MEM_2_WIN] = {
.base_reg = MV64x60_CPU2PCI1_MEM_2_BASE,
.size_reg = MV64x60_CPU2PCI1_MEM_2_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 17 },
[MV64x60_CPU2PCI1_MEM_3_WIN] = {
.base_reg = MV64x60_CPU2PCI1_MEM_3_BASE,
.size_reg = MV64x60_CPU2PCI1_MEM_3_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 18 },
/* CPU->SRAM Window */
[MV64x60_CPU2SRAM_WIN] = {
.base_reg = MV64360_CPU2SRAM_BASE,
.size_reg = 0,
.base_bits = 16,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUWIN_ENAB | 19 },
/* CPU->PCI 0 Remap I/O Window */
[MV64x60_CPU2PCI0_IO_REMAP_WIN] = {
.base_reg = MV64x60_CPU2PCI0_IO_REMAP,
.size_reg = 0,
.base_bits = 16,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
/* CPU->PCI 1 Remap I/O Window */
[MV64x60_CPU2PCI1_IO_REMAP_WIN] = {
.base_reg = MV64x60_CPU2PCI1_IO_REMAP,
.size_reg = 0,
.base_bits = 16,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
/* CPU Memory Protection Windows */
[MV64x60_CPU_PROT_0_WIN] = {
.base_reg = MV64x60_CPU_PROT_BASE_0,
.size_reg = MV64x60_CPU_PROT_SIZE_0,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUPROT_ENAB | 31 },
[MV64x60_CPU_PROT_1_WIN] = {
.base_reg = MV64x60_CPU_PROT_BASE_1,
.size_reg = MV64x60_CPU_PROT_SIZE_1,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUPROT_ENAB | 31 },
[MV64x60_CPU_PROT_2_WIN] = {
.base_reg = MV64x60_CPU_PROT_BASE_2,
.size_reg = MV64x60_CPU_PROT_SIZE_2,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUPROT_ENAB | 31 },
[MV64x60_CPU_PROT_3_WIN] = {
.base_reg = MV64x60_CPU_PROT_BASE_3,
.size_reg = MV64x60_CPU_PROT_SIZE_3,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = MV64x60_EXTRA_CPUPROT_ENAB | 31 },
/* CPU Snoop Windows -- don't exist on 64360 */
/* PCI 0->System Memory Remap Windows */
[MV64x60_PCI02MEM_REMAP_0_WIN] = {
.base_reg = MV64x60_PCI0_SLAVE_MEM_0_REMAP,
.size_reg = 0,
.base_bits = 20,
.size_bits = 0,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = 0 },
[MV64x60_PCI02MEM_REMAP_1_WIN] = {
.base_reg = MV64x60_PCI0_SLAVE_MEM_1_REMAP,
.size_reg = 0,
.base_bits = 20,
.size_bits = 0,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = 0 },
[MV64x60_PCI02MEM_REMAP_2_WIN] = {
.base_reg = MV64x60_PCI0_SLAVE_MEM_1_REMAP,
.size_reg = 0,
.base_bits = 20,
.size_bits = 0,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = 0 },
[MV64x60_PCI02MEM_REMAP_3_WIN] = {
.base_reg = MV64x60_PCI0_SLAVE_MEM_1_REMAP,
.size_reg = 0,
.base_bits = 20,
.size_bits = 0,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = 0 },
/* PCI 1->System Memory Remap Windows */
[MV64x60_PCI12MEM_REMAP_0_WIN] = {
.base_reg = MV64x60_PCI1_SLAVE_MEM_0_REMAP,
.size_reg = 0,
.base_bits = 20,
.size_bits = 0,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = 0 },
[MV64x60_PCI12MEM_REMAP_1_WIN] = {
.base_reg = MV64x60_PCI1_SLAVE_MEM_1_REMAP,
.size_reg = 0,
.base_bits = 20,
.size_bits = 0,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = 0 },
[MV64x60_PCI12MEM_REMAP_2_WIN] = {
.base_reg = MV64x60_PCI1_SLAVE_MEM_1_REMAP,
.size_reg = 0,
.base_bits = 20,
.size_bits = 0,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = 0 },
[MV64x60_PCI12MEM_REMAP_3_WIN] = {
.base_reg = MV64x60_PCI1_SLAVE_MEM_1_REMAP,
.size_reg = 0,
.base_bits = 20,
.size_bits = 0,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = 0 },
/* ENET->System Memory Windows */
[MV64x60_ENET2MEM_0_WIN] = {
.base_reg = MV64360_ENET2MEM_0_BASE,
.size_reg = MV64360_ENET2MEM_0_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_ENET_ENAB | 0 },
[MV64x60_ENET2MEM_1_WIN] = {
.base_reg = MV64360_ENET2MEM_1_BASE,
.size_reg = MV64360_ENET2MEM_1_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_ENET_ENAB | 1 },
[MV64x60_ENET2MEM_2_WIN] = {
.base_reg = MV64360_ENET2MEM_2_BASE,
.size_reg = MV64360_ENET2MEM_2_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_ENET_ENAB | 2 },
[MV64x60_ENET2MEM_3_WIN] = {
.base_reg = MV64360_ENET2MEM_3_BASE,
.size_reg = MV64360_ENET2MEM_3_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_ENET_ENAB | 3 },
[MV64x60_ENET2MEM_4_WIN] = {
.base_reg = MV64360_ENET2MEM_4_BASE,
.size_reg = MV64360_ENET2MEM_4_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_ENET_ENAB | 4 },
[MV64x60_ENET2MEM_5_WIN] = {
.base_reg = MV64360_ENET2MEM_5_BASE,
.size_reg = MV64360_ENET2MEM_5_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_ENET_ENAB | 5 },
/* MPSC->System Memory Windows */
[MV64x60_MPSC2MEM_0_WIN] = {
.base_reg = MV64360_MPSC2MEM_0_BASE,
.size_reg = MV64360_MPSC2MEM_0_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_MPSC_ENAB | 0 },
[MV64x60_MPSC2MEM_1_WIN] = {
.base_reg = MV64360_MPSC2MEM_1_BASE,
.size_reg = MV64360_MPSC2MEM_1_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_MPSC_ENAB | 1 },
[MV64x60_MPSC2MEM_2_WIN] = {
.base_reg = MV64360_MPSC2MEM_2_BASE,
.size_reg = MV64360_MPSC2MEM_2_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_MPSC_ENAB | 2 },
[MV64x60_MPSC2MEM_3_WIN] = {
.base_reg = MV64360_MPSC2MEM_3_BASE,
.size_reg = MV64360_MPSC2MEM_3_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_MPSC_ENAB | 3 },
/* IDMA->System Memory Windows */
[MV64x60_IDMA2MEM_0_WIN] = {
.base_reg = MV64360_IDMA2MEM_0_BASE,
.size_reg = MV64360_IDMA2MEM_0_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_IDMA_ENAB | 0 },
[MV64x60_IDMA2MEM_1_WIN] = {
.base_reg = MV64360_IDMA2MEM_1_BASE,
.size_reg = MV64360_IDMA2MEM_1_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_IDMA_ENAB | 1 },
[MV64x60_IDMA2MEM_2_WIN] = {
.base_reg = MV64360_IDMA2MEM_2_BASE,
.size_reg = MV64360_IDMA2MEM_2_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_IDMA_ENAB | 2 },
[MV64x60_IDMA2MEM_3_WIN] = {
.base_reg = MV64360_IDMA2MEM_3_BASE,
.size_reg = MV64360_IDMA2MEM_3_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_IDMA_ENAB | 3 },
[MV64x60_IDMA2MEM_4_WIN] = {
.base_reg = MV64360_IDMA2MEM_4_BASE,
.size_reg = MV64360_IDMA2MEM_4_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_IDMA_ENAB | 4 },
[MV64x60_IDMA2MEM_5_WIN] = {
.base_reg = MV64360_IDMA2MEM_5_BASE,
.size_reg = MV64360_IDMA2MEM_5_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_IDMA_ENAB | 5 },
[MV64x60_IDMA2MEM_6_WIN] = {
.base_reg = MV64360_IDMA2MEM_6_BASE,
.size_reg = MV64360_IDMA2MEM_6_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_IDMA_ENAB | 6 },
[MV64x60_IDMA2MEM_7_WIN] = {
.base_reg = MV64360_IDMA2MEM_7_BASE,
.size_reg = MV64360_IDMA2MEM_7_SIZE,
.base_bits = 16,
.size_bits = 16,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_IDMA_ENAB | 7 },
};
struct mv64x60_64bit_window
mv64360_64bit_windows[MV64x60_64BIT_WIN_COUNT] __initdata = {
/* CPU->PCI 0 MEM Remap Windows */
[MV64x60_CPU2PCI0_MEM_0_REMAP_WIN] = {
.base_hi_reg = MV64x60_CPU2PCI0_MEM_0_REMAP_HI,
.base_lo_reg = MV64x60_CPU2PCI0_MEM_0_REMAP_LO,
.size_reg = 0,
.base_lo_bits = 16,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI0_MEM_1_REMAP_WIN] = {
.base_hi_reg = MV64x60_CPU2PCI0_MEM_1_REMAP_HI,
.base_lo_reg = MV64x60_CPU2PCI0_MEM_1_REMAP_LO,
.size_reg = 0,
.base_lo_bits = 16,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI0_MEM_2_REMAP_WIN] = {
.base_hi_reg = MV64x60_CPU2PCI0_MEM_2_REMAP_HI,
.base_lo_reg = MV64x60_CPU2PCI0_MEM_2_REMAP_LO,
.size_reg = 0,
.base_lo_bits = 16,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI0_MEM_3_REMAP_WIN] = {
.base_hi_reg = MV64x60_CPU2PCI0_MEM_3_REMAP_HI,
.base_lo_reg = MV64x60_CPU2PCI0_MEM_3_REMAP_LO,
.size_reg = 0,
.base_lo_bits = 16,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
/* CPU->PCI 1 MEM Remap Windows */
[MV64x60_CPU2PCI1_MEM_0_REMAP_WIN] = {
.base_hi_reg = MV64x60_CPU2PCI1_MEM_0_REMAP_HI,
.base_lo_reg = MV64x60_CPU2PCI1_MEM_0_REMAP_LO,
.size_reg = 0,
.base_lo_bits = 16,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI1_MEM_1_REMAP_WIN] = {
.base_hi_reg = MV64x60_CPU2PCI1_MEM_1_REMAP_HI,
.base_lo_reg = MV64x60_CPU2PCI1_MEM_1_REMAP_LO,
.size_reg = 0,
.base_lo_bits = 16,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI1_MEM_2_REMAP_WIN] = {
.base_hi_reg = MV64x60_CPU2PCI1_MEM_2_REMAP_HI,
.base_lo_reg = MV64x60_CPU2PCI1_MEM_2_REMAP_LO,
.size_reg = 0,
.base_lo_bits = 16,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
[MV64x60_CPU2PCI1_MEM_3_REMAP_WIN] = {
.base_hi_reg = MV64x60_CPU2PCI1_MEM_3_REMAP_HI,
.base_lo_reg = MV64x60_CPU2PCI1_MEM_3_REMAP_LO,
.size_reg = 0,
.base_lo_bits = 16,
.size_bits = 0,
.get_from_field = mv64x60_shift_left,
.map_to_field = mv64x60_shift_right,
.extra = 0 },
/* PCI 0->MEM Access Control Windows */
[MV64x60_PCI02MEM_ACC_CNTL_0_WIN] = {
.base_hi_reg = MV64x60_PCI0_ACC_CNTL_0_BASE_HI,
.base_lo_reg = MV64x60_PCI0_ACC_CNTL_0_BASE_LO,
.size_reg = MV64x60_PCI0_ACC_CNTL_0_SIZE,
.base_lo_bits = 20,
.size_bits = 20,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_PCIACC_ENAB | 0 },
[MV64x60_PCI02MEM_ACC_CNTL_1_WIN] = {
.base_hi_reg = MV64x60_PCI0_ACC_CNTL_1_BASE_HI,
.base_lo_reg = MV64x60_PCI0_ACC_CNTL_1_BASE_LO,
.size_reg = MV64x60_PCI0_ACC_CNTL_1_SIZE,
.base_lo_bits = 20,
.size_bits = 20,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_PCIACC_ENAB | 0 },
[MV64x60_PCI02MEM_ACC_CNTL_2_WIN] = {
.base_hi_reg = MV64x60_PCI0_ACC_CNTL_2_BASE_HI,
.base_lo_reg = MV64x60_PCI0_ACC_CNTL_2_BASE_LO,
.size_reg = MV64x60_PCI0_ACC_CNTL_2_SIZE,
.base_lo_bits = 20,
.size_bits = 20,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_PCIACC_ENAB | 0 },
[MV64x60_PCI02MEM_ACC_CNTL_3_WIN] = {
.base_hi_reg = MV64x60_PCI0_ACC_CNTL_3_BASE_HI,
.base_lo_reg = MV64x60_PCI0_ACC_CNTL_3_BASE_LO,
.size_reg = MV64x60_PCI0_ACC_CNTL_3_SIZE,
.base_lo_bits = 20,
.size_bits = 20,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_PCIACC_ENAB | 0 },
/* PCI 1->MEM Access Control Windows */
[MV64x60_PCI12MEM_ACC_CNTL_0_WIN] = {
.base_hi_reg = MV64x60_PCI1_ACC_CNTL_0_BASE_HI,
.base_lo_reg = MV64x60_PCI1_ACC_CNTL_0_BASE_LO,
.size_reg = MV64x60_PCI1_ACC_CNTL_0_SIZE,
.base_lo_bits = 20,
.size_bits = 20,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_PCIACC_ENAB | 0 },
[MV64x60_PCI12MEM_ACC_CNTL_1_WIN] = {
.base_hi_reg = MV64x60_PCI1_ACC_CNTL_1_BASE_HI,
.base_lo_reg = MV64x60_PCI1_ACC_CNTL_1_BASE_LO,
.size_reg = MV64x60_PCI1_ACC_CNTL_1_SIZE,
.base_lo_bits = 20,
.size_bits = 20,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_PCIACC_ENAB | 0 },
[MV64x60_PCI12MEM_ACC_CNTL_2_WIN] = {
.base_hi_reg = MV64x60_PCI1_ACC_CNTL_2_BASE_HI,
.base_lo_reg = MV64x60_PCI1_ACC_CNTL_2_BASE_LO,
.size_reg = MV64x60_PCI1_ACC_CNTL_2_SIZE,
.base_lo_bits = 20,
.size_bits = 20,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_PCIACC_ENAB | 0 },
[MV64x60_PCI12MEM_ACC_CNTL_3_WIN] = {
.base_hi_reg = MV64x60_PCI1_ACC_CNTL_3_BASE_HI,
.base_lo_reg = MV64x60_PCI1_ACC_CNTL_3_BASE_LO,
.size_reg = MV64x60_PCI1_ACC_CNTL_3_SIZE,
.base_lo_bits = 20,
.size_bits = 20,
.get_from_field = mv64x60_mask,
.map_to_field = mv64x60_mask,
.extra = MV64x60_EXTRA_PCIACC_ENAB | 0 },
/* PCI 0->MEM Snoop Windows -- don't exist on 64360 */
/* PCI 1->MEM Snoop Windows -- don't exist on 64360 */
};
/*
* include/asm-ppc/mv64x60.h
*
* Prototypes, etc. for the Marvell/Galileo MV64x60 host bridge routines.
*
* Author: Mark A. Greer <mgreer@mvista.com>
*
* 2001-2002 (c) MontaVista, Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef __ASMPPC_MV64x60_H
#define __ASMPPC_MV64x60_H
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/config.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
#include <asm/mv64x60_defs.h>
extern u8 mv64x60_pci_exclude_bridge;
extern spinlock_t mv64x60_lock;
/* 32-bit Window table entry defines */
#define MV64x60_CPU2MEM_0_WIN 0
#define MV64x60_CPU2MEM_1_WIN 1
#define MV64x60_CPU2MEM_2_WIN 2
#define MV64x60_CPU2MEM_3_WIN 3
#define MV64x60_CPU2DEV_0_WIN 4
#define MV64x60_CPU2DEV_1_WIN 5
#define MV64x60_CPU2DEV_2_WIN 6
#define MV64x60_CPU2DEV_3_WIN 7
#define MV64x60_CPU2BOOT_WIN 8
#define MV64x60_CPU2PCI0_IO_WIN 9
#define MV64x60_CPU2PCI0_MEM_0_WIN 10
#define MV64x60_CPU2PCI0_MEM_1_WIN 11
#define MV64x60_CPU2PCI0_MEM_2_WIN 12
#define MV64x60_CPU2PCI0_MEM_3_WIN 13
#define MV64x60_CPU2PCI1_IO_WIN 14
#define MV64x60_CPU2PCI1_MEM_0_WIN 15
#define MV64x60_CPU2PCI1_MEM_1_WIN 16
#define MV64x60_CPU2PCI1_MEM_2_WIN 17
#define MV64x60_CPU2PCI1_MEM_3_WIN 18
#define MV64x60_CPU2SRAM_WIN 19
#define MV64x60_CPU2PCI0_IO_REMAP_WIN 20
#define MV64x60_CPU2PCI1_IO_REMAP_WIN 21
#define MV64x60_CPU_PROT_0_WIN 22
#define MV64x60_CPU_PROT_1_WIN 23
#define MV64x60_CPU_PROT_2_WIN 24
#define MV64x60_CPU_PROT_3_WIN 25
#define MV64x60_CPU_SNOOP_0_WIN 26
#define MV64x60_CPU_SNOOP_1_WIN 27
#define MV64x60_CPU_SNOOP_2_WIN 28
#define MV64x60_CPU_SNOOP_3_WIN 29
#define MV64x60_PCI02MEM_REMAP_0_WIN 30
#define MV64x60_PCI02MEM_REMAP_1_WIN 31
#define MV64x60_PCI02MEM_REMAP_2_WIN 32
#define MV64x60_PCI02MEM_REMAP_3_WIN 33
#define MV64x60_PCI12MEM_REMAP_0_WIN 34
#define MV64x60_PCI12MEM_REMAP_1_WIN 35
#define MV64x60_PCI12MEM_REMAP_2_WIN 36
#define MV64x60_PCI12MEM_REMAP_3_WIN 37
#define MV64x60_ENET2MEM_0_WIN 38
#define MV64x60_ENET2MEM_1_WIN 39
#define MV64x60_ENET2MEM_2_WIN 40
#define MV64x60_ENET2MEM_3_WIN 41
#define MV64x60_ENET2MEM_4_WIN 42
#define MV64x60_ENET2MEM_5_WIN 43
#define MV64x60_MPSC2MEM_0_WIN 44
#define MV64x60_MPSC2MEM_1_WIN 45
#define MV64x60_MPSC2MEM_2_WIN 46
#define MV64x60_MPSC2MEM_3_WIN 47
#define MV64x60_IDMA2MEM_0_WIN 48
#define MV64x60_IDMA2MEM_1_WIN 49
#define MV64x60_IDMA2MEM_2_WIN 50
#define MV64x60_IDMA2MEM_3_WIN 51
#define MV64x60_IDMA2MEM_4_WIN 52
#define MV64x60_IDMA2MEM_5_WIN 53
#define MV64x60_IDMA2MEM_6_WIN 54
#define MV64x60_IDMA2MEM_7_WIN 55
#define MV64x60_32BIT_WIN_COUNT 56
/* 64-bit Window table entry defines */
#define MV64x60_CPU2PCI0_MEM_0_REMAP_WIN 0
#define MV64x60_CPU2PCI0_MEM_1_REMAP_WIN 1
#define MV64x60_CPU2PCI0_MEM_2_REMAP_WIN 2
#define MV64x60_CPU2PCI0_MEM_3_REMAP_WIN 3
#define MV64x60_CPU2PCI1_MEM_0_REMAP_WIN 4
#define MV64x60_CPU2PCI1_MEM_1_REMAP_WIN 5
#define MV64x60_CPU2PCI1_MEM_2_REMAP_WIN 6
#define MV64x60_CPU2PCI1_MEM_3_REMAP_WIN 7
#define MV64x60_PCI02MEM_ACC_CNTL_0_WIN 8
#define MV64x60_PCI02MEM_ACC_CNTL_1_WIN 9
#define MV64x60_PCI02MEM_ACC_CNTL_2_WIN 10
#define MV64x60_PCI02MEM_ACC_CNTL_3_WIN 11
#define MV64x60_PCI12MEM_ACC_CNTL_0_WIN 12
#define MV64x60_PCI12MEM_ACC_CNTL_1_WIN 13
#define MV64x60_PCI12MEM_ACC_CNTL_2_WIN 14
#define MV64x60_PCI12MEM_ACC_CNTL_3_WIN 15
#define MV64x60_PCI02MEM_SNOOP_0_WIN 16
#define MV64x60_PCI02MEM_SNOOP_1_WIN 17
#define MV64x60_PCI02MEM_SNOOP_2_WIN 18
#define MV64x60_PCI02MEM_SNOOP_3_WIN 19
#define MV64x60_PCI12MEM_SNOOP_0_WIN 20
#define MV64x60_PCI12MEM_SNOOP_1_WIN 21
#define MV64x60_PCI12MEM_SNOOP_2_WIN 22
#define MV64x60_PCI12MEM_SNOOP_3_WIN 23
#define MV64x60_64BIT_WIN_COUNT 24
/*
* Define a structure that's used to pass in config information to the
* core routines.
*/
struct mv64x60_pci_window {
u32 cpu_base;
u32 pci_base_hi;
u32 pci_base_lo;
u32 size;
u32 swap;
};
struct mv64x60_pci_info {
u8 enable_bus; /* allow access to this PCI bus? */
struct mv64x60_pci_window pci_io;
struct mv64x60_pci_window pci_mem[3];
u32 acc_cntl_options[MV64x60_CPU2MEM_WINDOWS];
u32 snoop_options[MV64x60_CPU2MEM_WINDOWS];
u16 pci_cmd_bits;
u16 latency_timer;
};
struct mv64x60_setup_info {
u32 phys_reg_base;
u32 window_preserve_mask_32_hi;
u32 window_preserve_mask_32_lo;
u32 window_preserve_mask_64;
u32 cpu_prot_options[MV64x60_CPU2MEM_WINDOWS];
u32 cpu_snoop_options[MV64x60_CPU2MEM_WINDOWS];
u32 enet_options[MV64x60_CPU2MEM_WINDOWS];
u32 mpsc_options[MV64x60_CPU2MEM_WINDOWS];
u32 idma_options[MV64x60_CPU2MEM_WINDOWS];
struct mv64x60_pci_info pci_0;
struct mv64x60_pci_info pci_1;
};
/* Define what the top bits in the extra member of a window entry means. */
#define MV64x60_EXTRA_INVALID 0x00000000
#define MV64x60_EXTRA_CPUWIN_ENAB 0x10000000
#define MV64x60_EXTRA_CPUPROT_ENAB 0x20000000
#define MV64x60_EXTRA_ENET_ENAB 0x30000000
#define MV64x60_EXTRA_MPSC_ENAB 0x40000000
#define MV64x60_EXTRA_IDMA_ENAB 0x50000000
#define MV64x60_EXTRA_PCIACC_ENAB 0x60000000
#define MV64x60_EXTRA_MASK 0xf0000000
/*
* Define the 'handle' struct that will be passed between the 64x60 core
* code and the platform-specific code that will use it. The handle
* will contain pointers to chip-specific routines & information.
*/
struct mv64x60_32bit_window {
u32 base_reg;
u32 size_reg;
u8 base_bits;
u8 size_bits;
u32 (*get_from_field)(u32 val, u32 num_bits);
u32 (*map_to_field)(u32 val, u32 num_bits);
u32 extra;
};
struct mv64x60_64bit_window {
u32 base_hi_reg;
u32 base_lo_reg;
u32 size_reg;
u8 base_lo_bits;
u8 size_bits;
u32 (*get_from_field)(u32 val, u32 num_bits);
u32 (*map_to_field)(u32 val, u32 num_bits);
u32 extra;
};
typedef struct mv64x60_handle mv64x60_handle_t;
struct mv64x60_chip_info {
u32 (*translate_size)(u32 base, u32 size, u32 num_bits);
u32 (*untranslate_size)(u32 base, u32 size, u32 num_bits);
void (*set_pci2mem_window)(struct pci_controller *hose, u32 bus,
u32 window, u32 base);
void (*set_pci2regs_window)(struct mv64x60_handle *bh,
struct pci_controller *hose, u32 bus, u32 base);
u32 (*is_enabled_32bit)(mv64x60_handle_t *bh, u32 window);
void (*enable_window_32bit)(mv64x60_handle_t *bh, u32 window);
void (*disable_window_32bit)(mv64x60_handle_t *bh, u32 window);
void (*enable_window_64bit)(mv64x60_handle_t *bh, u32 window);
void (*disable_window_64bit)(mv64x60_handle_t *bh, u32 window);
void (*disable_all_windows)(mv64x60_handle_t *bh,
struct mv64x60_setup_info *si);
void (*config_io2mem_windows)(mv64x60_handle_t *bh,
struct mv64x60_setup_info *si,
u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]);
void (*set_mpsc2regs_window)(struct mv64x60_handle *bh, u32 base);
void (*chip_specific_init)(mv64x60_handle_t *bh,
struct mv64x60_setup_info *si);
struct mv64x60_32bit_window *window_tab_32bit;
struct mv64x60_64bit_window *window_tab_64bit;
};
struct mv64x60_handle {
u32 type; /* type of bridge */
u32 rev; /* revision of bridge */
u32 v_base; /* virtual base addr of bridge regs */
u32 p_base; /* physical base addr of bridge regs */
u32 pci_mode_a; /* pci bus 0 mode: conventional pci, pci-x */
u32 pci_mode_b; /* pci bus 1 mode: conventional pci, pci-x */
u32 io_base_a; /* vaddr of pci 0's I/O space */
u32 io_base_b; /* vaddr of pci 1's I/O space */
struct pci_controller *hose_a;
struct pci_controller *hose_b;
struct mv64x60_chip_info *ci; /* chip/bridge-specific info */
};
/* Define I/O routines for accessing registers on the 64x60 bridge. */
extern inline void
mv64x60_write(struct mv64x60_handle *bh, u32 offset, u32 val) {
ulong flags;
spin_lock_irqsave(&mv64x60_lock, flags);
out_le32((volatile u32 *)(bh->v_base + offset), val);
spin_unlock_irqrestore(&mv64x60_lock, flags);
}
extern inline u32
mv64x60_read(struct mv64x60_handle *bh, u32 offset) {
ulong flags;
spin_lock_irqsave(&mv64x60_lock, flags);
return in_le32((volatile u32 *)(bh->v_base + offset));
spin_unlock_irqrestore(&mv64x60_lock, flags);
}
extern inline void
mv64x60_modify(struct mv64x60_handle *bh, u32 offs, u32 data, u32 mask)
{
u32 reg;
ulong flags;
spin_lock_irqsave(&mv64x60_lock, flags);
reg = mv64x60_read(bh, offs) & (~mask); /* zero bits we care about */
reg |= data & mask; /* set bits from the data */
mv64x60_write(bh, offs, reg);
spin_unlock_irqrestore(&mv64x60_lock, flags);
}
#define mv64x60_set_bits(bh, offs, bits) mv64x60_modify(bh, offs, ~0, bits)
#define mv64x60_clr_bits(bh, offs, bits) mv64x60_modify(bh, offs, 0, bits)
/* Externally visible function prototypes */
int mv64x60_init(struct mv64x60_handle *bh, struct mv64x60_setup_info *si);
u32 mv64x60_get_mem_size(u32 bridge_base, u32 chip_type);
void mv64x60_early_init(struct mv64x60_handle *bh,
struct mv64x60_setup_info *si);
void mv64x60_alloc_hose(struct mv64x60_handle *bh, u32 cfg_addr, u32 cfg_data,
struct pci_controller **hose);
int mv64x60_get_type(struct mv64x60_handle *bh);
int mv64x60_setup_for_chip(struct mv64x60_handle *bh);
u32 mv64x60_get_bridge_vbase(void);
u32 mv64x60_get_bridge_type(void);
u32 mv64x60_get_bridge_rev(void);
void mv64x60_get_mem_windows(struct mv64x60_handle *bh,
u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]);
void mv64x60_config_cpu2mem_windows(struct mv64x60_handle *bh,
struct mv64x60_setup_info *si,
u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]);
void mv64x60_config_cpu2pci_windows(struct mv64x60_handle *bh,
struct mv64x60_pci_info *pi, u32 bus);
void mv64x60_config_pci2mem_windows(struct mv64x60_handle *bh,
struct pci_controller *hose, struct mv64x60_pci_info *pi, u32 bus,
u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]);
void mv64x60_config_resources(struct pci_controller *hose,
struct mv64x60_pci_info *pi, u32 io_base);
void mv64x60_config_pci_params(struct pci_controller *hose,
struct mv64x60_pci_info *pi);
void mv64x60_pd_fixup(struct mv64x60_handle *bh,
struct platform_device *pd_devs[], u32 entries);
void mv64x60_get_32bit_window(struct mv64x60_handle *bh, u32 window,
u32 *base, u32 *size);
void mv64x60_set_32bit_window(struct mv64x60_handle *bh, u32 window, u32 base,
u32 size, u32 other_bits);
void mv64x60_get_64bit_window(struct mv64x60_handle *bh, u32 window,
u32 *base_hi, u32 *base_lo, u32 *size);
void mv64x60_set_64bit_window(struct mv64x60_handle *bh, u32 window,
u32 base_hi, u32 base_lo, u32 size, u32 other_bits);
void mv64x60_set_bus(struct mv64x60_handle *bh, u32 bus, u32 child_bus);
int mv64x60_pci_exclude_device(u8 bus, u8 devfn);
void gt64260_init_irq(void);
int gt64260_get_irq(struct pt_regs *regs);
void mv64360_init_irq(void);
int mv64360_get_irq(struct pt_regs *regs);
u32 mv64x60_mask(u32 val, u32 num_bits);
u32 mv64x60_shift_left(u32 val, u32 num_bits);
u32 mv64x60_shift_right(u32 val, u32 num_bits);
u32 mv64x60_calc_mem_size(struct mv64x60_handle *bh,
u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]);
void mv64x60_progress_init(u32 base);
void mv64x60_mpsc_progress(char *s, unsigned short hex);
extern struct mv64x60_32bit_window
gt64260_32bit_windows[MV64x60_32BIT_WIN_COUNT];
extern struct mv64x60_64bit_window
gt64260_64bit_windows[MV64x60_64BIT_WIN_COUNT];
extern struct mv64x60_32bit_window
mv64360_32bit_windows[MV64x60_32BIT_WIN_COUNT];
extern struct mv64x60_64bit_window
mv64360_64bit_windows[MV64x60_64BIT_WIN_COUNT];
#endif /* __ASMPPC_MV64x60_H */
/*
* include/asm-ppc/gt64260_defs.h
*
* Register definitions for the Marvell/Galileo GT64260, MV64360, etc.
* host bridges.
*
* Author: Mark A. Greer <mgreer@mvista.com>
*
* 2001-2002 (c) MontaVista, Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef __ASMPPC_MV64x60_DEFS_H
#define __ASMPPC_MV64x60_DEFS_H
/*
* Define the Marvell bridges that are supported
*/
#define MV64x60_TYPE_INVALID 0
#define MV64x60_TYPE_GT64260A 1
#define MV64x60_TYPE_GT64260B 2
#define MV64x60_TYPE_MV64360 3
#define MV64x60_TYPE_MV64361 4
#define MV64x60_TYPE_MV64362 5
#define MV64x60_TYPE_MV64460 6
/* Revisions of each supported chip */
#define GT64260_REV_A 0x10
#define GT64260_REV_B 0x20
#define MV64360 0x01
#define MV64460 0x01
/* Minimum window size supported by 64260 is 1MB */
#define GT64260_WINDOW_SIZE_MIN 0x00100000
#define MV64360_WINDOW_SIZE_MIN 0x00010000
/* IRQ's for embedded controllers */
#define MV64x60_IRQ_DEV 1
#define MV64x60_IRQ_CPU_ERR 3
#define MV64x60_IRQ_TIMER_0_1 8
#define MV64x60_IRQ_TIMER_2_3 9
#define MV64x60_IRQ_TIMER_4_5 10
#define MV64x60_IRQ_TIMER_6_7 11
#define MV64x60_IRQ_ETH_0 32
#define MV64x60_IRQ_ETH_1 33
#define MV64x60_IRQ_ETH_2 34
#define MV64x60_IRQ_SDMA_0 36
#define MV64x60_IRQ_I2C 37
#define MV64x60_IRQ_BRG 39
#define MV64x60_IRQ_MPSC_0 40
#define MV64x60_IRQ_MPSC_1 42
#define MV64x60_IRQ_COMM 43
#define MV64360_IRQ_PCI0 12
#define MV64360_IRQ_SRAM_PAR_ERR 13
#define MV64360_IRQ_PCI1 16
#define MV64360_IRQ_SDMA_1 38
/* Offsets for register blocks */
#define GT64260_ENET_PHY_ADDR 0x2000
#define GT64260_ENET_ESMIR 0x2010
#define GT64260_ENET_0_OFFSET 0x2400
#define GT64260_ENET_1_OFFSET 0x2800
#define GT64260_ENET_2_OFFSET 0x2c00
#define MV64x60_SDMA_0_OFFSET 0x4000
#define MV64x60_SDMA_1_OFFSET 0x6000
#define MV64x60_MPSC_0_OFFSET 0x8000
#define MV64x60_MPSC_1_OFFSET 0x9000
#define MV64x60_MPSC_ROUTING_OFFSET 0xb400
#define MV64x60_SDMA_INTR_OFFSET 0xb800
#define MV64x60_BRG_0_OFFSET 0xb200
#define MV64x60_BRG_1_OFFSET 0xb208
/*
*****************************************************************************
*
* CPU Interface Registers
*
*****************************************************************************
*/
/* CPU physical address of bridge's registers */
#define MV64x60_INTERNAL_SPACE_DECODE 0x0068
#define MV64x60_INTERNAL_SPACE_SIZE 0x10000
#define MV64x60_INTERNAL_SPACE_DEFAULT_ADDR 0x14000000
#define MV64360_CPU_BAR_ENABLE 0x0278
/* CPU Memory Controller Window Registers (4 windows) */
#define MV64x60_CPU2MEM_WINDOWS 4
#define MV64x60_CPU2MEM_0_BASE 0x0008
#define MV64x60_CPU2MEM_0_SIZE 0x0010
#define MV64x60_CPU2MEM_1_BASE 0x0208
#define MV64x60_CPU2MEM_1_SIZE 0x0210
#define MV64x60_CPU2MEM_2_BASE 0x0018
#define MV64x60_CPU2MEM_2_SIZE 0x0020
#define MV64x60_CPU2MEM_3_BASE 0x0218
#define MV64x60_CPU2MEM_3_SIZE 0x0220
/* CPU Device Controller Window Registers (4 windows) */
#define MV64x60_CPU2DEV_WINDOWS 4
#define MV64x60_CPU2DEV_0_BASE 0x0028
#define MV64x60_CPU2DEV_0_SIZE 0x0030
#define MV64x60_CPU2DEV_1_BASE 0x0228
#define MV64x60_CPU2DEV_1_SIZE 0x0230
#define MV64x60_CPU2DEV_2_BASE 0x0248
#define MV64x60_CPU2DEV_2_SIZE 0x0250
#define MV64x60_CPU2DEV_3_BASE 0x0038
#define MV64x60_CPU2DEV_3_SIZE 0x0040
#define MV64x60_CPU2BOOT_0_BASE 0x0238
#define MV64x60_CPU2BOOT_0_SIZE 0x0240
#define MV64360_CPU2SRAM_BASE 0x0268
/* CPU Windows to PCI space (2 PCI buses each w/ 1 I/O & 4 MEM windows) */
#define MV64x60_PCI_BUSES 2
#define MV64x60_PCI_IO_WINDOWS_PER_BUS 1
#define MV64x60_PCI_MEM_WINDOWS_PER_BUS 4
#define MV64x60_CPU2PCI_SWAP_BYTE 0x00000000
#define MV64x60_CPU2PCI_SWAP_NONE 0x01000000
#define MV64x60_CPU2PCI_SWAP_BYTE_WORD 0x02000000
#define MV64x60_CPU2PCI_SWAP_WORD 0x03000000
#define MV64x60_CPU2PCI_MEM_REQ64 (1<<27)
#define MV64x60_CPU2PCI0_IO_BASE 0x0048
#define MV64x60_CPU2PCI0_IO_SIZE 0x0050
#define MV64x60_CPU2PCI0_MEM_0_BASE 0x0058
#define MV64x60_CPU2PCI0_MEM_0_SIZE 0x0060
#define MV64x60_CPU2PCI0_MEM_1_BASE 0x0080
#define MV64x60_CPU2PCI0_MEM_1_SIZE 0x0088
#define MV64x60_CPU2PCI0_MEM_2_BASE 0x0258
#define MV64x60_CPU2PCI0_MEM_2_SIZE 0x0260
#define MV64x60_CPU2PCI0_MEM_3_BASE 0x0280
#define MV64x60_CPU2PCI0_MEM_3_SIZE 0x0288
#define MV64x60_CPU2PCI0_IO_REMAP 0x00f0
#define MV64x60_CPU2PCI0_MEM_0_REMAP_LO 0x00f8
#define MV64x60_CPU2PCI0_MEM_0_REMAP_HI 0x0320
#define MV64x60_CPU2PCI0_MEM_1_REMAP_LO 0x0100
#define MV64x60_CPU2PCI0_MEM_1_REMAP_HI 0x0328
#define MV64x60_CPU2PCI0_MEM_2_REMAP_LO 0x02f8
#define MV64x60_CPU2PCI0_MEM_2_REMAP_HI 0x0330
#define MV64x60_CPU2PCI0_MEM_3_REMAP_LO 0x0300
#define MV64x60_CPU2PCI0_MEM_3_REMAP_HI 0x0338
#define MV64x60_CPU2PCI1_IO_BASE 0x0090
#define MV64x60_CPU2PCI1_IO_SIZE 0x0098
#define MV64x60_CPU2PCI1_MEM_0_BASE 0x00a0
#define MV64x60_CPU2PCI1_MEM_0_SIZE 0x00a8
#define MV64x60_CPU2PCI1_MEM_1_BASE 0x00b0
#define MV64x60_CPU2PCI1_MEM_1_SIZE 0x00b8
#define MV64x60_CPU2PCI1_MEM_2_BASE 0x02a0
#define MV64x60_CPU2PCI1_MEM_2_SIZE 0x02a8
#define MV64x60_CPU2PCI1_MEM_3_BASE 0x02b0
#define MV64x60_CPU2PCI1_MEM_3_SIZE 0x02b8
#define MV64x60_CPU2PCI1_IO_REMAP 0x0108
#define MV64x60_CPU2PCI1_MEM_0_REMAP_LO 0x0110
#define MV64x60_CPU2PCI1_MEM_0_REMAP_HI 0x0340
#define MV64x60_CPU2PCI1_MEM_1_REMAP_LO 0x0118
#define MV64x60_CPU2PCI1_MEM_1_REMAP_HI 0x0348
#define MV64x60_CPU2PCI1_MEM_2_REMAP_LO 0x0310
#define MV64x60_CPU2PCI1_MEM_2_REMAP_HI 0x0350
#define MV64x60_CPU2PCI1_MEM_3_REMAP_LO 0x0318
#define MV64x60_CPU2PCI1_MEM_3_REMAP_HI 0x0358
/* CPU Control Registers */
#define MV64x60_CPU_CONFIG 0x0000
#define MV64x60_CPU_MODE 0x0120
#define MV64x60_CPU_MASTER_CNTL 0x0160
#define MV64x60_CPU_XBAR_CNTL_LO 0x0150
#define MV64x60_CPU_XBAR_CNTL_HI 0x0158
#define MV64x60_CPU_XBAR_TO 0x0168
#define GT64260_CPU_RR_XBAR_CNTL_LO 0x0170
#define GT64260_CPU_RR_XBAR_CNTL_HI 0x0178
#define MV64360_CPU_PADS_CALIBRATION 0x03b4
#define MV64360_CPU_RESET_SAMPLE_LO 0x03c4
#define MV64360_CPU_RESET_SAMPLE_HI 0x03d4
/* SMP Register Map */
#define MV64360_WHO_AM_I 0x0200
#define MV64360_CPU0_DOORBELL 0x0214
#define MV64360_CPU0_DOORBELL_CLR 0x021c
#define MV64360_CPU0_DOORBELL_MASK 0x0234
#define MV64360_CPU1_DOORBELL 0x0224
#define MV64360_CPU1_DOORBELL_CLR 0x022c
#define MV64360_CPU1_DOORBELL_MASK 0x023c
#define MV64360_CPUx_DOORBELL(x) (0x0214 + ((x)*0x10))
#define MV64360_CPUx_DOORBELL_CLR(x) (0x021c + ((x)*0x10))
#define MV64360_CPUx_DOORBELL_MASK(x) (0x0234 + ((x)*0x08))
#define MV64360_SEMAPHORE_0 0x0244
#define MV64360_SEMAPHORE_1 0x024c
#define MV64360_SEMAPHORE_2 0x0254
#define MV64360_SEMAPHORE_3 0x025c
#define MV64360_SEMAPHORE_4 0x0264
#define MV64360_SEMAPHORE_5 0x026c
#define MV64360_SEMAPHORE_6 0x0274
#define MV64360_SEMAPHORE_7 0x027c
/* CPU Sync Barrier Registers */
#define GT64260_CPU_SYNC_BARRIER_PCI0 0x00c0
#define GT64260_CPU_SYNC_BARRIER_PCI1 0x00c8
#define MV64360_CPU0_SYNC_BARRIER_TRIG 0x00c0
#define MV64360_CPU0_SYNC_BARRIER_VIRT 0x00c8
#define MV64360_CPU1_SYNC_BARRIER_TRIG 0x00d0
#define MV64360_CPU1_SYNC_BARRIER_VIRT 0x00d8
/* CPU Deadlock and Ordering registers (Rev B part only) */
#define GT64260_CPU_DEADLOCK_ORDERING 0x02d0
#define GT64260_CPU_WB_PRIORITY_BUFFER_DEPTH 0x02d8
#define GT64260_CPU_COUNTERS_SYNC_BARRIER_ATTRIBUTE 0x02e0
/* CPU Access Protection Registers (gt64260 realy has 8 but don't need) */
#define MV64x260_CPU_PROT_WINDOWS 4
#define GT64260_CPU_PROT_ACCPROTECT (1<<16)
#define GT64260_CPU_PROT_WRPROTECT (1<<17)
#define GT64260_CPU_PROT_CACHEPROTECT (1<<18)
#define MV64360_CPU_PROT_ACCPROTECT (1<<20)
#define MV64360_CPU_PROT_WRPROTECT (1<<21)
#define MV64360_CPU_PROT_CACHEPROTECT (1<<22)
#define MV64360_CPU_PROT_WIN_ENABLE (1<<31)
#define MV64x60_CPU_PROT_BASE_0 0x0180
#define MV64x60_CPU_PROT_SIZE_0 0x0188
#define MV64x60_CPU_PROT_BASE_1 0x0190
#define MV64x60_CPU_PROT_SIZE_1 0x0198
#define MV64x60_CPU_PROT_BASE_2 0x01a0
#define MV64x60_CPU_PROT_SIZE_2 0x01a8
#define MV64x60_CPU_PROT_BASE_3 0x01b0
#define MV64x60_CPU_PROT_SIZE_3 0x01b8
#define GT64260_CPU_PROT_BASE_4 0x01c0
#define GT64260_CPU_PROT_SIZE_4 0x01c8
#define GT64260_CPU_PROT_BASE_5 0x01d0
#define GT64260_CPU_PROT_SIZE_5 0x01d8
#define GT64260_CPU_PROT_BASE_6 0x01e0
#define GT64260_CPU_PROT_SIZE_6 0x01e8
#define GT64260_CPU_PROT_BASE_7 0x01f0
#define GT64260_CPU_PROT_SIZE_7 0x01f8
/* CPU Snoop Control Registers (64260 only) */
#define GT64260_CPU_SNOOP_WINDOWS 4
#define GT64260_CPU_SNOOP_NONE 0x00000000
#define GT64260_CPU_SNOOP_WT 0x00010000
#define GT64260_CPU_SNOOP_WB 0x00020000
#define GT64260_CPU_SNOOP_MASK 0x00030000
#define GT64260_CPU_SNOOP_ALL_BITS GT64260_CPU_SNOOP_MASK
#define GT64260_CPU_SNOOP_BASE_0 0x0380
#define GT64260_CPU_SNOOP_SIZE_0 0x0388
#define GT64260_CPU_SNOOP_BASE_1 0x0390
#define GT64260_CPU_SNOOP_SIZE_1 0x0398
#define GT64260_CPU_SNOOP_BASE_2 0x03a0
#define GT64260_CPU_SNOOP_SIZE_2 0x03a8
#define GT64260_CPU_SNOOP_BASE_3 0x03b0
#define GT64260_CPU_SNOOP_SIZE_3 0x03b8
/* CPU Snoop Control Registers (64360 only) */
#define MV64360_CPU_SNOOP_WINDOWS 4
#define MV64360_CPU_SNOOP_NONE 0x00000000
#define MV64360_CPU_SNOOP_WT 0x00010000
#define MV64360_CPU_SNOOP_WB 0x00020000
#define MV64360_CPU_SNOOP_MASK 0x00030000
#define MV64360_CPU_SNOOP_ALL_BITS MV64360_CPU_SNOOP_MASK
/* CPU Error Report Registers */
#define MV64x60_CPU_ERR_ADDR_LO 0x0070
#define MV64x60_CPU_ERR_ADDR_HI 0x0078
#define MV64x60_CPU_ERR_DATA_LO 0x0128
#define MV64x60_CPU_ERR_DATA_HI 0x0130
#define MV64x60_CPU_ERR_PARITY 0x0138
#define MV64x60_CPU_ERR_CAUSE 0x0140
#define MV64x60_CPU_ERR_MASK 0x0148
/*
*****************************************************************************
*
* SRAM Cotnroller Registers
*
*****************************************************************************
*/
#define MV64360_SRAM_CONFIG 0x0380
#define MV64360_SRAM_TEST_MODE 0x03f4
#define MV64360_SRAM_ERR_CAUSE 0x0388
#define MV64360_SRAM_ERR_ADDR_LO 0x0390
#define MV64360_SRAM_ERR_ADDR_HI 0x03f8
#define MV64360_SRAM_ERR_DATA_LO 0x0398
#define MV64360_SRAM_ERR_DATA_HI 0x03a0
#define MV64360_SRAM_ERR_PARITY 0x03a8
#define MV64360_SRAM_SIZE 0x00040000 /* 256 KB of SRAM */
/*
*****************************************************************************
*
* SDRAM/MEM Cotnroller Registers
*
*****************************************************************************
*/
/* SDRAM Config Registers (64260) */
#define GT64260_SDRAM_CONFIG 0x0448
/* SDRAM Error Report Registers (64260) */
#define GT64260_SDRAM_ERR_DATA_LO 0x0484
#define GT64260_SDRAM_ERR_DATA_HI 0x0480
#define GT64260_SDRAM_ERR_ADDR 0x0490
#define GT64260_SDRAM_ERR_ECC_RCVD 0x0488
#define GT64260_SDRAM_ERR_ECC_CALC 0x048c
#define GT64260_SDRAM_ERR_ECC_CNTL 0x0494
#define GT64260_SDRAM_ERR_ECC_ERR_CNT 0x0498
/* SDRAM Config Registers (64360) */
#define MV64360_SDRAM_CONFIG 0x1400
/* SDRAM Control Registers */
#define MV64360_D_UNIT_CONTROL_LOW 0x1404
#define MV64360_D_UNIT_CONTROL_HIGH 0x1424
/* SDRAM Error Report Registers (64360) */
#define MV64360_SDRAM_ERR_DATA_LO 0x1444
#define MV64360_SDRAM_ERR_DATA_HI 0x1440
#define MV64360_SDRAM_ERR_ADDR 0x1450
#define MV64360_SDRAM_ERR_ECC_RCVD 0x1448
#define MV64360_SDRAM_ERR_ECC_CALC 0x144c
#define MV64360_SDRAM_ERR_ECC_CNTL 0x1454
#define MV64360_SDRAM_ERR_ECC_ERR_CNT 0x1458
/*
*****************************************************************************
*
* Device/BOOT Cotnroller Registers
*
*****************************************************************************
*/
/* Device Control Registers */
#define MV64x60_DEV_BANK_PARAMS_0 0x045c
#define MV64x60_DEV_BANK_PARAMS_1 0x0460
#define MV64x60_DEV_BANK_PARAMS_2 0x0464
#define MV64x60_DEV_BANK_PARAMS_3 0x0468
#define MV64x60_DEV_BOOT_PARAMS 0x046c
#define MV64x60_DEV_IF_CNTL 0x04c0
#define MV64x60_DEV_IF_XBAR_CNTL_LO 0x04c8
#define MV64x60_DEV_IF_XBAR_CNTL_HI 0x04cc
#define MV64x60_DEV_IF_XBAR_CNTL_TO 0x04c4
/* Device Interrupt Registers */
#define MV64x60_DEV_INTR_CAUSE 0x04d0
#define MV64x60_DEV_INTR_MASK 0x04d4
#define MV64x60_DEV_INTR_ERR_ADDR 0x04d8
#define MV64360_DEV_INTR_ERR_DATA 0x04dc
#define MV64360_DEV_INTR_ERR_PAR 0x04e0
/*
*****************************************************************************
*
* PCI Bridge Interface Registers
*
*****************************************************************************
*/
/* PCI Configuration Access Registers */
#define MV64x60_PCI0_CONFIG_ADDR 0x0cf8
#define MV64x60_PCI0_CONFIG_DATA 0x0cfc
#define MV64x60_PCI0_IACK 0x0c34
#define MV64x60_PCI1_CONFIG_ADDR 0x0c78
#define MV64x60_PCI1_CONFIG_DATA 0x0c7c
#define MV64x60_PCI1_IACK 0x0cb4
/* PCI Control Registers */
#define MV64x60_PCI0_CMD 0x0c00
#define MV64x60_PCI0_MODE 0x0d00
#define MV64x60_PCI0_TO_RETRY 0x0c04
#define MV64x60_PCI0_RD_BUF_DISCARD_TIMER 0x0d04
#define MV64x60_PCI0_MSI_TRIGGER_TIMER 0x0c38
#define MV64x60_PCI0_ARBITER_CNTL 0x1d00
#define MV64x60_PCI0_XBAR_CNTL_LO 0x1d08
#define MV64x60_PCI0_XBAR_CNTL_HI 0x1d0c
#define MV64x60_PCI0_XBAR_CNTL_TO 0x1d04
#define MV64x60_PCI0_RD_RESP_XBAR_CNTL_LO 0x1d18
#define MV64x60_PCI0_RD_RESP_XBAR_CNTL_HI 0x1d1c
#define MV64x60_PCI0_SYNC_BARRIER 0x1d10
#define MV64x60_PCI0_P2P_CONFIG 0x1d14
#define MV64x60_PCI0_INTR_MASK
#define GT64260_PCI0_P2P_SWAP_CNTL 0x1d54
#define MV64x60_PCI1_CMD 0x0c80
#define MV64x60_PCI1_MODE 0x0d80
#define MV64x60_PCI1_TO_RETRY 0x0c84
#define MV64x60_PCI1_RD_BUF_DISCARD_TIMER 0x0d84
#define MV64x60_PCI1_MSI_TRIGGER_TIMER 0x0cb8
#define MV64x60_PCI1_ARBITER_CNTL 0x1d80
#define MV64x60_PCI1_XBAR_CNTL_LO 0x1d88
#define MV64x60_PCI1_XBAR_CNTL_HI 0x1d8c
#define MV64x60_PCI1_XBAR_CNTL_TO 0x1d84
#define MV64x60_PCI1_RD_RESP_XBAR_CNTL_LO 0x1d98
#define MV64x60_PCI1_RD_RESP_XBAR_CNTL_HI 0x1d9c
#define MV64x60_PCI1_SYNC_BARRIER 0x1d90
#define MV64x60_PCI1_P2P_CONFIG 0x1d94
#define GT64260_PCI1_P2P_SWAP_CNTL 0x1dd4
/* Different modes that the pci hoses can be in (bits 5:4 in PCI Mode reg) */
#define MV64x60_PCIMODE_CONVENTIONAL 0
#define MV64x60_PCIMODE_PCIX_66 (1 << 4)
#define MV64x60_PCIMODE_PCIX_100 (2 << 4)
#define MV64x60_PCIMODE_PCIX_133 (3 << 4)
#define MV64x60_PCIMODE_MASK (0x3 << 4)
/* PCI Access Control Regions Registers */
#define GT64260_PCI_ACC_CNTL_PREFETCHEN (1<<12)
#define GT64260_PCI_ACC_CNTL_DREADEN (1<<13)
#define GT64260_PCI_ACC_CNTL_RDPREFETCH (1<<16)
#define GT64260_PCI_ACC_CNTL_RDLINEPREFETCH (1<<17)
#define GT64260_PCI_ACC_CNTL_RDMULPREFETCH (1<<18)
#define GT64260_PCI_ACC_CNTL_MBURST_32_BTYES 0x00000000
#define GT64260_PCI_ACC_CNTL_MBURST_64_BYTES 0x00100000
#define GT64260_PCI_ACC_CNTL_MBURST_128_BYTES 0x00200000
#define GT64260_PCI_ACC_CNTL_MBURST_MASK 0x00300000
#define GT64260_PCI_ACC_CNTL_SWAP_BYTE 0x00000000
#define GT64260_PCI_ACC_CNTL_SWAP_NONE 0x01000000
#define GT64260_PCI_ACC_CNTL_SWAP_BYTE_WORD 0x02000000
#define GT64260_PCI_ACC_CNTL_SWAP_WORD 0x03000000
#define GT64260_PCI_ACC_CNTL_SWAP_MASK 0x03000000
#define GT64260_PCI_ACC_CNTL_ACCPROT (1<<28)
#define GT64260_PCI_ACC_CNTL_WRPROT (1<<29)
#define GT64260_PCI_ACC_CNTL_ALL_BITS (GT64260_PCI_ACC_CNTL_PREFETCHEN | \
GT64260_PCI_ACC_CNTL_DREADEN | \
GT64260_PCI_ACC_CNTL_RDPREFETCH | \
GT64260_PCI_ACC_CNTL_RDLINEPREFETCH |\
GT64260_PCI_ACC_CNTL_RDMULPREFETCH | \
GT64260_PCI_ACC_CNTL_MBURST_MASK | \
GT64260_PCI_ACC_CNTL_SWAP_MASK | \
GT64260_PCI_ACC_CNTL_ACCPROT| \
GT64260_PCI_ACC_CNTL_WRPROT)
#define MV64360_PCI_ACC_CNTL_ENABLE (1<<0)
#define MV64360_PCI_ACC_CNTL_REQ64 (1<<1)
#define MV64360_PCI_ACC_CNTL_SNOOP_NONE 0x00000000
#define MV64360_PCI_ACC_CNTL_SNOOP_WT 0x00000004
#define MV64360_PCI_ACC_CNTL_SNOOP_WB 0x00000008
#define MV64360_PCI_ACC_CNTL_SNOOP_MASK 0x0000000c
#define MV64360_PCI_ACC_CNTL_ACCPROT (1<<4)
#define MV64360_PCI_ACC_CNTL_WRPROT (1<<5)
#define MV64360_PCI_ACC_CNTL_SWAP_BYTE 0x00000000
#define MV64360_PCI_ACC_CNTL_SWAP_NONE 0x00000040
#define MV64360_PCI_ACC_CNTL_SWAP_BYTE_WORD 0x00000080
#define MV64360_PCI_ACC_CNTL_SWAP_WORD 0x000000c0
#define MV64360_PCI_ACC_CNTL_SWAP_MASK 0x000000c0
#define MV64360_PCI_ACC_CNTL_MBURST_32_BYTES 0x00000000
#define MV64360_PCI_ACC_CNTL_MBURST_64_BYTES 0x00000100
#define MV64360_PCI_ACC_CNTL_MBURST_128_BYTES 0x00000200
#define MV64360_PCI_ACC_CNTL_MBURST_MASK 0x00000300
#define MV64360_PCI_ACC_CNTL_RDSIZE_32_BYTES 0x00000000
#define MV64360_PCI_ACC_CNTL_RDSIZE_64_BYTES 0x00000400
#define MV64360_PCI_ACC_CNTL_RDSIZE_128_BYTES 0x00000800
#define MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES 0x00000c00
#define MV64360_PCI_ACC_CNTL_RDSIZE_MASK 0x00000c00
#define MV64360_PCI_ACC_CNTL_ALL_BITS (MV64360_PCI_ACC_CNTL_ENABLE | \
MV64360_PCI_ACC_CNTL_REQ64 | \
MV64360_PCI_ACC_CNTL_SNOOP_MASK | \
MV64360_PCI_ACC_CNTL_ACCPROT | \
MV64360_PCI_ACC_CNTL_WRPROT | \
MV64360_PCI_ACC_CNTL_SWAP_MASK | \
MV64360_PCI_ACC_CNTL_MBURST_MASK | \
MV64360_PCI_ACC_CNTL_RDSIZE_MASK)
#define MV64x60_PCI0_ACC_CNTL_0_BASE_LO 0x1e00
#define MV64x60_PCI0_ACC_CNTL_0_BASE_HI 0x1e04
#define MV64x60_PCI0_ACC_CNTL_0_SIZE 0x1e08
#define MV64x60_PCI0_ACC_CNTL_1_BASE_LO 0x1e10
#define MV64x60_PCI0_ACC_CNTL_1_BASE_HI 0x1e14
#define MV64x60_PCI0_ACC_CNTL_1_SIZE 0x1e18
#define MV64x60_PCI0_ACC_CNTL_2_BASE_LO 0x1e20
#define MV64x60_PCI0_ACC_CNTL_2_BASE_HI 0x1e24
#define MV64x60_PCI0_ACC_CNTL_2_SIZE 0x1e28
#define MV64x60_PCI0_ACC_CNTL_3_BASE_LO 0x1e30
#define MV64x60_PCI0_ACC_CNTL_3_BASE_HI 0x1e34
#define MV64x60_PCI0_ACC_CNTL_3_SIZE 0x1e38
#define MV64x60_PCI0_ACC_CNTL_4_BASE_LO 0x1e40
#define MV64x60_PCI0_ACC_CNTL_4_BASE_HI 0x1e44
#define MV64x60_PCI0_ACC_CNTL_4_SIZE 0x1e48
#define MV64x60_PCI0_ACC_CNTL_5_BASE_LO 0x1e50
#define MV64x60_PCI0_ACC_CNTL_5_BASE_HI 0x1e54
#define MV64x60_PCI0_ACC_CNTL_5_SIZE 0x1e58
#define GT64260_PCI0_ACC_CNTL_6_BASE_LO 0x1e60
#define GT64260_PCI0_ACC_CNTL_6_BASE_HI 0x1e64
#define GT64260_PCI0_ACC_CNTL_6_SIZE 0x1e68
#define GT64260_PCI0_ACC_CNTL_7_BASE_LO 0x1e70
#define GT64260_PCI0_ACC_CNTL_7_BASE_HI 0x1e74
#define GT64260_PCI0_ACC_CNTL_7_SIZE 0x1e78
#define MV64x60_PCI1_ACC_CNTL_0_BASE_LO 0x1e80
#define MV64x60_PCI1_ACC_CNTL_0_BASE_HI 0x1e84
#define MV64x60_PCI1_ACC_CNTL_0_SIZE 0x1e88
#define MV64x60_PCI1_ACC_CNTL_1_BASE_LO 0x1e90
#define MV64x60_PCI1_ACC_CNTL_1_BASE_HI 0x1e94
#define MV64x60_PCI1_ACC_CNTL_1_SIZE 0x1e98
#define MV64x60_PCI1_ACC_CNTL_2_BASE_LO 0x1ea0
#define MV64x60_PCI1_ACC_CNTL_2_BASE_HI 0x1ea4
#define MV64x60_PCI1_ACC_CNTL_2_SIZE 0x1ea8
#define MV64x60_PCI1_ACC_CNTL_3_BASE_LO 0x1eb0
#define MV64x60_PCI1_ACC_CNTL_3_BASE_HI 0x1eb4
#define MV64x60_PCI1_ACC_CNTL_3_SIZE 0x1eb8
#define MV64x60_PCI1_ACC_CNTL_4_BASE_LO 0x1ec0
#define MV64x60_PCI1_ACC_CNTL_4_BASE_HI 0x1ec4
#define MV64x60_PCI1_ACC_CNTL_4_SIZE 0x1ec8
#define MV64x60_PCI1_ACC_CNTL_5_BASE_LO 0x1ed0
#define MV64x60_PCI1_ACC_CNTL_5_BASE_HI 0x1ed4
#define MV64x60_PCI1_ACC_CNTL_5_SIZE 0x1ed8
#define GT64260_PCI1_ACC_CNTL_6_BASE_LO 0x1ee0
#define GT64260_PCI1_ACC_CNTL_6_BASE_HI 0x1ee4
#define GT64260_PCI1_ACC_CNTL_6_SIZE 0x1ee8
#define GT64260_PCI1_ACC_CNTL_7_BASE_LO 0x1ef0
#define GT64260_PCI1_ACC_CNTL_7_BASE_HI 0x1ef4
#define GT64260_PCI1_ACC_CNTL_7_SIZE 0x1ef8
/* PCI Snoop Control Registers (64260 only) */
#define GT64260_PCI_SNOOP_NONE 0x00000000
#define GT64260_PCI_SNOOP_WT 0x00001000
#define GT64260_PCI_SNOOP_WB 0x00002000
#define GT64260_PCI0_SNOOP_0_BASE_LO 0x1f00
#define GT64260_PCI0_SNOOP_0_BASE_HI 0x1f04
#define GT64260_PCI0_SNOOP_0_SIZE 0x1f08
#define GT64260_PCI0_SNOOP_1_BASE_LO 0x1f10
#define GT64260_PCI0_SNOOP_1_BASE_HI 0x1f14
#define GT64260_PCI0_SNOOP_1_SIZE 0x1f18
#define GT64260_PCI0_SNOOP_2_BASE_LO 0x1f20
#define GT64260_PCI0_SNOOP_2_BASE_HI 0x1f24
#define GT64260_PCI0_SNOOP_2_SIZE 0x1f28
#define GT64260_PCI0_SNOOP_3_BASE_LO 0x1f30
#define GT64260_PCI0_SNOOP_3_BASE_HI 0x1f34
#define GT64260_PCI0_SNOOP_3_SIZE 0x1f38
#define GT64260_PCI1_SNOOP_0_BASE_LO 0x1f80
#define GT64260_PCI1_SNOOP_0_BASE_HI 0x1f84
#define GT64260_PCI1_SNOOP_0_SIZE 0x1f88
#define GT64260_PCI1_SNOOP_1_BASE_LO 0x1f90
#define GT64260_PCI1_SNOOP_1_BASE_HI 0x1f94
#define GT64260_PCI1_SNOOP_1_SIZE 0x1f98
#define GT64260_PCI1_SNOOP_2_BASE_LO 0x1fa0
#define GT64260_PCI1_SNOOP_2_BASE_HI 0x1fa4
#define GT64260_PCI1_SNOOP_2_SIZE 0x1fa8
#define GT64260_PCI1_SNOOP_3_BASE_LO 0x1fb0
#define GT64260_PCI1_SNOOP_3_BASE_HI 0x1fb4
#define GT64260_PCI1_SNOOP_3_SIZE 0x1fb8
/* PCI Error Report Registers */
#define MV64x60_PCI0_ERR_SERR_MASK 0x0c28
#define MV64x60_PCI0_ERR_ADDR_LO 0x1d40
#define MV64x60_PCI0_ERR_ADDR_HI 0x1d44
#define MV64x60_PCI0_ERR_DATA_LO 0x1d48
#define MV64x60_PCI0_ERR_DATA_HI 0x1d4c
#define MV64x60_PCI0_ERR_CMD 0x1d50
#define MV64x60_PCI0_ERR_CAUSE 0x1d58
#define MV64x60_PCI0_ERR_MASK 0x1d5c
#define MV64x60_PCI1_ERR_SERR_MASK 0x0ca8
#define MV64x60_PCI1_ERR_ADDR_LO 0x1dc0
#define MV64x60_PCI1_ERR_ADDR_HI 0x1dc4
#define MV64x60_PCI1_ERR_DATA_LO 0x1dc8
#define MV64x60_PCI1_ERR_DATA_HI 0x1dcc
#define MV64x60_PCI1_ERR_CMD 0x1dd0
#define MV64x60_PCI1_ERR_CAUSE 0x1dd8
#define MV64x60_PCI1_ERR_MASK 0x1ddc
/* PCI Slave Address Decoding Registers */
#define MV64x60_PCI0_MEM_0_SIZE 0x0c08
#define MV64x60_PCI0_MEM_1_SIZE 0x0d08
#define MV64x60_PCI0_MEM_2_SIZE 0x0c0c
#define MV64x60_PCI0_MEM_3_SIZE 0x0d0c
#define MV64x60_PCI1_MEM_0_SIZE 0x0c88
#define MV64x60_PCI1_MEM_1_SIZE 0x0d88
#define MV64x60_PCI1_MEM_2_SIZE 0x0c8c
#define MV64x60_PCI1_MEM_3_SIZE 0x0d8c
#define MV64x60_PCI0_BAR_ENABLE 0x0c3c
#define MV64x60_PCI1_BAR_ENABLE 0x0cbc
#define MV64x60_PCI0_PCI_DECODE_CNTL 0x0d3c
#define MV64x60_PCI1_PCI_DECODE_CNTL 0x0dbc
#define MV64x60_PCI0_SLAVE_MEM_0_REMAP 0x0c48
#define MV64x60_PCI0_SLAVE_MEM_1_REMAP 0x0d48
#define MV64x60_PCI0_SLAVE_MEM_2_REMAP 0x0c4c
#define MV64x60_PCI0_SLAVE_MEM_3_REMAP 0x0d4c
#define MV64x60_PCI0_SLAVE_DEV_0_REMAP 0x0c50
#define MV64x60_PCI0_SLAVE_DEV_1_REMAP 0x0d50
#define MV64x60_PCI0_SLAVE_DEV_2_REMAP 0x0d58
#define MV64x60_PCI0_SLAVE_DEV_3_REMAP 0x0c54
#define MV64x60_PCI0_SLAVE_BOOT_REMAP 0x0d54
#define MV64x60_PCI0_SLAVE_P2P_MEM_0_REMAP_LO 0x0d5c
#define MV64x60_PCI0_SLAVE_P2P_MEM_0_REMAP_HI 0x0d60
#define MV64x60_PCI0_SLAVE_P2P_MEM_1_REMAP_LO 0x0d64
#define MV64x60_PCI0_SLAVE_P2P_MEM_1_REMAP_HI 0x0d68
#define MV64x60_PCI0_SLAVE_P2P_IO_REMAP 0x0d6c
#define MV64x60_PCI0_SLAVE_CPU_REMAP 0x0d70
#define MV64x60_PCI1_SLAVE_MEM_0_REMAP 0x0cc8
#define MV64x60_PCI1_SLAVE_MEM_1_REMAP 0x0dc8
#define MV64x60_PCI1_SLAVE_MEM_2_REMAP 0x0ccc
#define MV64x60_PCI1_SLAVE_MEM_3_REMAP 0x0dcc
#define MV64x60_PCI1_SLAVE_DEV_0_REMAP 0x0cd0
#define MV64x60_PCI1_SLAVE_DEV_1_REMAP 0x0dd0
#define MV64x60_PCI1_SLAVE_DEV_2_REMAP 0x0dd8
#define MV64x60_PCI1_SLAVE_DEV_3_REMAP 0x0cd4
#define MV64x60_PCI1_SLAVE_BOOT_REMAP 0x0dd4
#define MV64x60_PCI1_SLAVE_P2P_MEM_0_REMAP_LO 0x0ddc
#define MV64x60_PCI1_SLAVE_P2P_MEM_0_REMAP_HI 0x0de0
#define MV64x60_PCI1_SLAVE_P2P_MEM_1_REMAP_LO 0x0de4
#define MV64x60_PCI1_SLAVE_P2P_MEM_1_REMAP_HI 0x0de8
#define MV64x60_PCI1_SLAVE_P2P_IO_REMAP 0x0dec
#define MV64x60_PCI1_SLAVE_CPU_REMAP 0x0df0
/*
*****************************************************************************
*
* ENET Controller Interface Registers
*
*****************************************************************************
*/
/* ENET Controller Window Registers (6 windows) */
#define MV64360_ENET2MEM_WINDOWS 6
#define MV64360_ENET2MEM_0_BASE 0x2200
#define MV64360_ENET2MEM_0_SIZE 0x2204
#define MV64360_ENET2MEM_1_BASE 0x2208
#define MV64360_ENET2MEM_1_SIZE 0x220c
#define MV64360_ENET2MEM_2_BASE 0x2210
#define MV64360_ENET2MEM_2_SIZE 0x2214
#define MV64360_ENET2MEM_3_BASE 0x2218
#define MV64360_ENET2MEM_3_SIZE 0x221c
#define MV64360_ENET2MEM_4_BASE 0x2220
#define MV64360_ENET2MEM_4_SIZE 0x2224
#define MV64360_ENET2MEM_5_BASE 0x2228
#define MV64360_ENET2MEM_5_SIZE 0x222c
#define MV64360_ENET2MEM_SNOOP_NONE 0x00000000
#define MV64360_ENET2MEM_SNOOP_WT 0x00001000
#define MV64360_ENET2MEM_SNOOP_WB 0x00002000
#define MV64360_ENET2MEM_BAR_ENABLE 0x2290
#define MV64360_ENET2MEM_ACC_PROT_0 0x2294
#define MV64360_ENET2MEM_ACC_PROT_1 0x2298
#define MV64360_ENET2MEM_ACC_PROT_2 0x229c
/*
*****************************************************************************
*
* MPSC Controller Interface Registers
*
*****************************************************************************
*/
/* MPSC Controller Window Registers (4 windows) */
#define MV64360_MPSC2MEM_WINDOWS 4
#define MV64360_MPSC2MEM_0_BASE 0xf200
#define MV64360_MPSC2MEM_0_SIZE 0xf204
#define MV64360_MPSC2MEM_1_BASE 0xf208
#define MV64360_MPSC2MEM_1_SIZE 0xf20c
#define MV64360_MPSC2MEM_2_BASE 0xf210
#define MV64360_MPSC2MEM_2_SIZE 0xf214
#define MV64360_MPSC2MEM_3_BASE 0xf218
#define MV64360_MPSC2MEM_3_SIZE 0xf21c
#define MV64360_MPSC_0_REMAP 0xf240
#define MV64360_MPSC_1_REMAP 0xf244
#define MV64360_MPSC2MEM_SNOOP_NONE 0x00000000
#define MV64360_MPSC2MEM_SNOOP_WT 0x00001000
#define MV64360_MPSC2MEM_SNOOP_WB 0x00002000
#define MV64360_MPSC2MEM_BAR_ENABLE 0xf250
#define MV64360_MPSC2MEM_ACC_PROT_0 0xf254
#define MV64360_MPSC2MEM_ACC_PROT_1 0xf258
#define MV64360_MPSC2REGS_BASE 0xf25c
/*
*****************************************************************************
*
* Timer/Counter Interface Registers
*
*****************************************************************************
*/
#define MV64x60_TIMR_CNTR_0 0x0850
#define MV64x60_TIMR_CNTR_1 0x0854
#define MV64x60_TIMR_CNTR_2 0x0858
#define MV64x60_TIMR_CNTR_3 0x085c
#define MV64x60_TIMR_CNTR_0_3_CNTL 0x0864
#define MV64x60_TIMR_CNTR_0_3_INTR_CAUSE 0x0868
#define MV64x60_TIMR_CNTR_0_3_INTR_MASK 0x086c
#define GT64260_TIMR_CNTR_4 0x0950
#define GT64260_TIMR_CNTR_5 0x0954
#define GT64260_TIMR_CNTR_6 0x0958
#define GT64260_TIMR_CNTR_7 0x095c
#define GT64260_TIMR_CNTR_4_7_CNTL 0x0964
#define GT64260_TIMR_CNTR_4_7_INTR_CAUSE 0x0968
#define GT64260_TIMR_CNTR_4_7_INTR_MASK 0x096c
/*
*****************************************************************************
*
* Communications Controller
*
*****************************************************************************
*/
#define GT64260_SER_INIT_PCI_ADDR_HI 0xf320
#define GT64260_SER_INIT_LAST_DATA 0xf324
#define GT64260_SER_INIT_CONTROL 0xf328
#define GT64260_SER_INIT_STATUS 0xf32c
#define MV64x60_COMM_ARBITER_CNTL 0xf300
#define MV64x60_COMM_CONFIG 0xb40c
#define MV64x60_COMM_XBAR_TO 0xf304
#define MV64x60_COMM_INTR_CAUSE 0xf310
#define MV64x60_COMM_INTR_MASK 0xf314
#define MV64x60_COMM_ERR_ADDR 0xf318
#define MV64360_COMM_ARBITER_CNTL 0xf300
/*
*****************************************************************************
*
* IDMA Controller Interface Registers
*
*****************************************************************************
*/
/* IDMA Controller Window Registers (8 windows) */
#define MV64360_IDMA2MEM_WINDOWS 8
#define MV64360_IDMA2MEM_0_BASE 0x0a00
#define MV64360_IDMA2MEM_0_SIZE 0x0a04
#define MV64360_IDMA2MEM_1_BASE 0x0a08
#define MV64360_IDMA2MEM_1_SIZE 0x0a0c
#define MV64360_IDMA2MEM_2_BASE 0x0a10
#define MV64360_IDMA2MEM_2_SIZE 0x0a14
#define MV64360_IDMA2MEM_3_BASE 0x0a18
#define MV64360_IDMA2MEM_3_SIZE 0x0a1c
#define MV64360_IDMA2MEM_4_BASE 0x0a20
#define MV64360_IDMA2MEM_4_SIZE 0x0a24
#define MV64360_IDMA2MEM_5_BASE 0x0a28
#define MV64360_IDMA2MEM_5_SIZE 0x0a2c
#define MV64360_IDMA2MEM_6_BASE 0x0a30
#define MV64360_IDMA2MEM_6_SIZE 0x0a34
#define MV64360_IDMA2MEM_7_BASE 0x0a38
#define MV64360_IDMA2MEM_7_SIZE 0x0a3c
#define MV64360_IDMA2MEM_SNOOP_NONE 0x00000000
#define MV64360_IDMA2MEM_SNOOP_WT 0x00001000
#define MV64360_IDMA2MEM_SNOOP_WB 0x00002000
#define MV64360_IDMA2MEM_BAR_ENABLE 0x0a80
#define MV64360_IDMA2MEM_ACC_PROT_0 0x0a70
#define MV64360_IDMA2MEM_ACC_PROT_1 0x0a74
#define MV64360_IDMA2MEM_ACC_PROT_2 0x0a78
#define MV64360_IDMA2MEM_ACC_PROT_3 0x0a7c
#define MV64x60_IDMA_0_OFFSET 0x0800
#define MV64x60_IDMA_1_OFFSET 0x0804
#define MV64x60_IDMA_2_OFFSET 0x0808
#define MV64x60_IDMA_3_OFFSET 0x080c
#define MV64x60_IDMA_4_OFFSET 0x0900
#define MV64x60_IDMA_5_OFFSET 0x0904
#define MV64x60_IDMA_6_OFFSET 0x0908
#define MV64x60_IDMA_7_OFFSET 0x090c
#define MV64x60_IDMA_BYTE_COUNT (0x0800 - MV64x60_IDMA_0_OFFSET)
#define MV64x60_IDMA_SRC_ADDR (0x0810 - MV64x60_IDMA_0_OFFSET)
#define MV64x60_IDMA_DST_ADDR (0x0820 - MV64x60_IDMA_0_OFFSET)
#define MV64x60_IDMA_NEXT_DESC (0x0830 - MV64x60_IDMA_0_OFFSET)
#define MV64x60_IDMA_CUR_DESC (0x0870 - MV64x60_IDMA_0_OFFSET)
#define MV64x60_IDMA_SRC_PCI_ADDR_HI (0x0890 - MV64x60_IDMA_0_OFFSET)
#define MV64x60_IDMA_DST_PCI_ADDR_HI (0x08a0 - MV64x60_IDMA_0_OFFSET)
#define MV64x60_IDMA_NEXT_DESC_PCI_ADDR_HI (0x08b0 - MV64x60_IDMA_0_OFFSET)
#define MV64x60_IDMA_CONTROL_LO (0x0840 - MV64x60_IDMA_0_OFFSET)
#define MV64x60_IDMA_CONTROL_HI (0x0880 - MV64x60_IDMA_0_OFFSET)
#define MV64x60_IDMA_0_3_ARBITER_CNTL 0x0860
#define MV64x60_IDMA_4_7_ARBITER_CNTL 0x0960
#define MV64x60_IDMA_0_3_XBAR_TO 0x08d0
#define MV64x60_IDMA_4_7_XBAR_TO 0x09d0
#define MV64x60_IDMA_0_3_INTR_CAUSE 0x08c0
#define MV64x60_IDMA_0_3_INTR_MASK 0x08c4
#define MV64x60_IDMA_0_3_ERROR_ADDR 0x08c8
#define MV64x60_IDMA_0_3_ERROR_SELECT 0x08cc
#define MV64x60_IDMA_4_7_INTR_CAUSE 0x09c0
#define MV64x60_IDMA_4_7_INTR_MASK 0x09c4
#define MV64x60_IDMA_4_7_ERROR_ADDR 0x09c8
#define MV64x60_IDMA_4_7_ERROR_SELECT 0x09cc
/*
*****************************************************************************
*
* Watchdog Timer Interface Registers
*
*****************************************************************************
*/
#define MV64x60_WDT_WDC 0xb410
#define MV64x60_WDT_WDV 0xb414
/*
*****************************************************************************
*
* General Purpose Pins Controller Interface Registers
*
*****************************************************************************
*/
#define MV64x60_GPP_IO_CNTL 0xf100
#define MV64x60_GPP_LEVEL_CNTL 0xf110
#define MV64x60_GPP_VALUE 0xf104
#define MV64x60_GPP_INTR_CAUSE 0xf108
#define MV64x60_GPP_INTR_MASK 0xf10c
/*
*****************************************************************************
*
* Multi-Purpose Pins Controller Interface Registers
*
*****************************************************************************
*/
#define MV64x60_MPP_CNTL_0 0xf000
#define MV64x60_MPP_CNTL_1 0xf004
#define MV64x60_MPP_CNTL_2 0xf008
#define MV64x60_MPP_CNTL_3 0xf00c
#define GT64260_MPP_SERIAL_PORTS_MULTIPLEX 0xf010
#define MV64x60_ETH_BAR_GAP 0x8
#define MV64x60_ETH_SIZE_REG_GAP 0x8
#define MV64x60_ETH_HIGH_ADDR_REMAP_REG_GAP 0x4
#define MV64x60_ETH_PORT_ACCESS_CTRL_GAP 0x4
#define MV64x60_EBAR_ATTR_DRAM_CS0 0x00000E00
#define MV64x60_EBAR_ATTR_DRAM_CS1 0x00000D00
#define MV64x60_EBAR_ATTR_DRAM_CS2 0x00000B00
#define MV64x60_EBAR_ATTR_DRAM_CS3 0x00000700
#define MV64x60_EBAR_ATTR_CBS_SRAM_BLOCK0 0x00000000
#define MV64x60_EBAR_ATTR_CBS_SRAM_BLOCK1 0x00000100
#define MV64x60_EBAR_ATTR_CBS_SRAM 0x00000000
#define MV64x60_EBAR_ATTR_CBS_CPU_BUS 0x00000800
/*
*****************************************************************************
*
* Interrupt Controller Interface Registers
*
*****************************************************************************
*/
#define GT64260_IC_OFFSET 0x0c18
#define GT64260_IC_MAIN_CAUSE_LO 0x0c18
#define GT64260_IC_MAIN_CAUSE_HI 0x0c68
#define GT64260_IC_CPU_INTR_MASK_LO 0x0c1c
#define GT64260_IC_CPU_INTR_MASK_HI 0x0c6c
#define GT64260_IC_CPU_SELECT_CAUSE 0x0c70
#define GT64260_IC_PCI0_INTR_MASK_LO 0x0c24
#define GT64260_IC_PCI0_INTR_MASK_HI 0x0c64
#define GT64260_IC_PCI0_SELECT_CAUSE 0x0c74
#define GT64260_IC_PCI1_INTR_MASK_LO 0x0ca4
#define GT64260_IC_PCI1_INTR_MASK_HI 0x0ce4
#define GT64260_IC_PCI1_SELECT_CAUSE 0x0cf4
#define GT64260_IC_CPU_INT_0_MASK 0x0e60
#define GT64260_IC_CPU_INT_1_MASK 0x0e64
#define GT64260_IC_CPU_INT_2_MASK 0x0e68
#define GT64260_IC_CPU_INT_3_MASK 0x0e6c
#define MV64360_IC_OFFSET 0x0000
#define MV64360_IC_MAIN_CAUSE_LO 0x0004
#define MV64360_IC_MAIN_CAUSE_HI 0x000c
#define MV64360_IC_CPU0_INTR_MASK_LO 0x0014
#define MV64360_IC_CPU0_INTR_MASK_HI 0x001c
#define MV64360_IC_CPU0_SELECT_CAUSE 0x0024
#define MV64360_IC_CPU1_INTR_MASK_LO 0x0034
#define MV64360_IC_CPU1_INTR_MASK_HI 0x003c
#define MV64360_IC_CPU1_SELECT_CAUSE 0x0044
#define MV64360_IC_INT0_MASK_LO 0x0054
#define MV64360_IC_INT0_MASK_HI 0x005c
#define MV64360_IC_INT0_SELECT_CAUSE 0x0064
#define MV64360_IC_INT1_MASK_LO 0x0074
#define MV64360_IC_INT1_MASK_HI 0x007c
#define MV64360_IC_INT1_SELECT_CAUSE 0x0084
#endif /* __ASMPPC_MV64x60_DEFS_H */
......@@ -13,8 +13,11 @@
#ifndef __ASM_MV64340_H
#define __ASM_MV64340_H
#ifdef __MIPS__
#include <asm/addrspace.h>
#include <asm/marvell.h>
#endif
#include <asm/types.h>
/****************************************/
/* Processor Address Space */
......@@ -1036,4 +1039,50 @@
extern void mv64340_irq_init(unsigned int base);
/* MPSC Platform Device, Driver Data (Shared register regions) */
#define MPSC_SHARED_NAME "mpsc_shared"
#define MPSC_ROUTING_BASE_ORDER 0
#define MPSC_SDMA_INTR_BASE_ORDER 1
#define MPSC_ROUTING_REG_BLOCK_SIZE 0x000c
#define MPSC_SDMA_INTR_REG_BLOCK_SIZE 0x0084
struct mpsc_shared_pd_dd {
u32 mrr_val;
u32 rcrr_val;
u32 tcrr_val;
u32 intr_cause_val;
u32 intr_mask_val;
};
/* MPSC Platform Device, Driver Data */
#define MPSC_CTLR_NAME "mpsc"
#define MPSC_BASE_ORDER 0
#define MPSC_SDMA_BASE_ORDER 1
#define MPSC_BRG_BASE_ORDER 2
#define MPSC_REG_BLOCK_SIZE 0x0038
#define MPSC_SDMA_REG_BLOCK_SIZE 0x0c18
#define MPSC_BRG_REG_BLOCK_SIZE 0x0008
struct mpsc_pd_dd {
u8 mirror_regs;
u8 cache_mgmt;
u8 max_idle;
int default_baud;
int default_bits;
int default_parity;
int default_flow;
u32 chr_1_val;
u32 chr_2_val;
u32 chr_10_val;
u32 mpcr_val;
u32 bcr_val;
u8 brg_can_tune;
u8 brg_clk_src;
u32 brg_clk_freq;
};
#endif /* __ASM_MV64340_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment