[MIPS] Support for several more SNI RM models.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
5759906ca9
commit
c066a32a89
17 changed files with 1875 additions and 396 deletions
|
@ -726,15 +726,16 @@ config SNI_RM
|
|||
select BOOT_ELF32
|
||||
select DMA_NONCOHERENT
|
||||
select GENERIC_ISA_DMA
|
||||
select HAVE_STD_PC_SERIAL_PORT
|
||||
select HW_HAS_EISA
|
||||
select HW_HAS_PCI
|
||||
select IRQ_CPU
|
||||
select I8253
|
||||
select I8259
|
||||
select ISA
|
||||
select SWAP_IO_SPACE if CPU_BIG_ENDIAN
|
||||
select SYS_HAS_CPU_R4X00
|
||||
select SYS_HAS_CPU_R5000
|
||||
select SYS_HAS_CPU_R10000
|
||||
select R5000_CPU_SCACHE
|
||||
select SYS_SUPPORTS_32BIT_KERNEL
|
||||
select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
|
||||
|
@ -1066,7 +1067,7 @@ config BOOT_ELF32
|
|||
|
||||
config MIPS_L1_CACHE_SHIFT
|
||||
int
|
||||
default "4" if MACH_DECSTATION
|
||||
default "4" if MACH_DECSTATION || SNI_RM
|
||||
default "7" if SGI_IP27
|
||||
default "5"
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include <asm/sni.h>
|
||||
|
||||
/*
|
||||
* Shortcuts ...
|
||||
* PCIMT Shortcuts ...
|
||||
*/
|
||||
#define SCSI PCIMT_IRQ_SCSI
|
||||
#define ETH PCIMT_IRQ_ETHERNET
|
||||
|
@ -67,6 +67,50 @@ static char irq_tab_rm300d[8][5] __initdata = {
|
|||
{ 0, INTD, INTA, INTB, INTC }, /* Slot 4 */
|
||||
};
|
||||
|
||||
static char irq_tab_rm300e[5][5] __initdata = {
|
||||
/* INTA INTB INTC INTD */
|
||||
{ 0, 0, 0, 0, 0 }, /* HOST bridge */
|
||||
{ SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */
|
||||
{ 0, INTC, INTD, INTA, INTB }, /* Bridge/i960 */
|
||||
{ 0, INTD, INTA, INTB, INTC }, /* Slot 1 */
|
||||
{ 0, INTA, INTB, INTC, INTD }, /* Slot 2 */
|
||||
};
|
||||
#undef SCSI
|
||||
#undef ETH
|
||||
#undef INTA
|
||||
#undef INTB
|
||||
#undef INTC
|
||||
#undef INTD
|
||||
|
||||
|
||||
/*
|
||||
* PCIT Shortcuts ...
|
||||
*/
|
||||
#define SCSI0 PCIT_IRQ_SCSI0
|
||||
#define SCSI1 PCIT_IRQ_SCSI1
|
||||
#define ETH PCIT_IRQ_ETHERNET
|
||||
#define INTA PCIT_IRQ_INTA
|
||||
#define INTB PCIT_IRQ_INTB
|
||||
#define INTC PCIT_IRQ_INTC
|
||||
#define INTD PCIT_IRQ_INTD
|
||||
|
||||
static char irq_tab_pcit[13][5] __initdata = {
|
||||
/* INTA INTB INTC INTD */
|
||||
{ 0, 0, 0, 0, 0 }, /* HOST bridge */
|
||||
{ SCSI0, SCSI0, SCSI0, SCSI0, SCSI0 }, /* SCSI */
|
||||
{ SCSI1, SCSI1, SCSI1, SCSI1, SCSI1 }, /* SCSI */
|
||||
{ ETH, ETH, ETH, ETH, ETH }, /* Ethernet */
|
||||
{ 0, INTA, INTB, INTC, INTD }, /* PCI-PCI bridge */
|
||||
{ 0, 0, 0, 0, 0 }, /* Unused */
|
||||
{ 0, 0, 0, 0, 0 }, /* Unused */
|
||||
{ 0, 0, 0, 0, 0 }, /* Unused */
|
||||
{ 0, INTA, INTB, INTC, INTD }, /* Slot 1 */
|
||||
{ 0, INTB, INTC, INTD, INTA }, /* Slot 2 */
|
||||
{ 0, INTC, INTD, INTA, INTB }, /* Slot 3 */
|
||||
{ 0, INTD, INTA, INTB, INTC }, /* Slot 4 */
|
||||
{ 0, INTA, INTB, INTC, INTD }, /* Slot 5 */
|
||||
};
|
||||
|
||||
static inline int is_rm300_revd(void)
|
||||
{
|
||||
unsigned char csmsr = *(volatile unsigned char *)PCIMT_CSMSR;
|
||||
|
@ -76,10 +120,24 @@ static inline int is_rm300_revd(void)
|
|||
|
||||
int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
|
||||
{
|
||||
if (is_rm300_revd())
|
||||
return irq_tab_rm300d[slot][pin];
|
||||
switch (sni_brd_type) {
|
||||
case SNI_BRD_PCI_TOWER:
|
||||
case SNI_BRD_PCI_TOWER_CPLUS:
|
||||
return irq_tab_pcit[slot][pin];
|
||||
|
||||
return irq_tab_rm200[slot][pin];
|
||||
case SNI_BRD_PCI_MTOWER:
|
||||
if (is_rm300_revd())
|
||||
return irq_tab_rm300d[slot][pin];
|
||||
/* fall through */
|
||||
|
||||
case SNI_BRD_PCI_DESKTOP:
|
||||
return irq_tab_rm200[slot][pin];
|
||||
|
||||
case SNI_BRD_PCI_MTOWER_CPLUS:
|
||||
return irq_tab_rm300e[slot][pin];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Do platform specific device initialization at pci_enable_device() time */
|
||||
|
|
|
@ -83,7 +83,82 @@ static int pcimt_write(struct pci_bus *bus, unsigned int devfn, int reg,
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct pci_ops sni_pci_ops = {
|
||||
struct pci_ops sni_pcimt_ops = {
|
||||
.read = pcimt_read,
|
||||
.write = pcimt_write,
|
||||
};
|
||||
|
||||
static int pcit_set_config_address(unsigned int busno, unsigned int devfn, int reg)
|
||||
{
|
||||
if ((devfn > 255) || (reg > 255) || (busno > 255))
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
|
||||
outl ((1 << 31) | ((busno & 0xff) << 16) | ((devfn & 0xff) << 8) | (reg & 0xfc), 0xcf8);
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int pcit_read(struct pci_bus *bus, unsigned int devfn, int reg,
|
||||
int size, u32 * val)
|
||||
{
|
||||
int res;
|
||||
|
||||
/*
|
||||
* on bus 0 we need to check, whether there is a device answering
|
||||
* for the devfn by doing a config write and checking the result. If
|
||||
* we don't do it, we will get a data bus error
|
||||
*/
|
||||
if (bus->number == 0) {
|
||||
pcit_set_config_address (0, 0, 0x68);
|
||||
outl (inl (0xcfc) | 0xc0000000, 0xcfc);
|
||||
if ((res = pcit_set_config_address(0, devfn, 0)))
|
||||
return res;
|
||||
outl (0xffffffff, 0xcfc);
|
||||
pcit_set_config_address (0, 0, 0x68);
|
||||
if (inl(0xcfc) & 0x100000)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
}
|
||||
if ((res = pcit_set_config_address(bus->number, devfn, reg)))
|
||||
return res;
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
*val = inb(PCIMT_CONFIG_DATA + (reg & 3));
|
||||
break;
|
||||
case 2:
|
||||
*val = inw(PCIMT_CONFIG_DATA + (reg & 2));
|
||||
break;
|
||||
case 4:
|
||||
*val = inl(PCIMT_CONFIG_DATA);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcit_write(struct pci_bus *bus, unsigned int devfn, int reg,
|
||||
int size, u32 val)
|
||||
{
|
||||
int res;
|
||||
|
||||
if ((res = pcit_set_config_address(bus->number, devfn, reg)))
|
||||
return res;
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
outb (val, PCIMT_CONFIG_DATA + (reg & 3));
|
||||
break;
|
||||
case 2:
|
||||
outw (val, PCIMT_CONFIG_DATA + (reg & 2));
|
||||
break;
|
||||
case 4:
|
||||
outl (val, PCIMT_CONFIG_DATA);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct pci_ops sni_pcit_ops = {
|
||||
.read = pcit_read,
|
||||
.write = pcit_write,
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Makefile for the SNI specific part of the kernel
|
||||
#
|
||||
|
||||
obj-y += irq.o pcimt_scache.o reset.o setup.o
|
||||
obj-y += irq.o reset.o setup.o ds1216.o a20r.o rm200.o pcimt.o pcit.o time.o
|
||||
obj-$(CONFIG_CPU_BIG_ENDIAN) += sniprom.o
|
||||
|
||||
EXTRA_AFLAGS := $(CFLAGS)
|
||||
|
|
227
arch/mips/sni/a20r.c
Normal file
227
arch/mips/sni/a20r.c
Normal file
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
* A20R specific code
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/serial_8250.h>
|
||||
|
||||
#include <asm/sni.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/ds1216.h>
|
||||
|
||||
#define PORT(_base,_irq) \
|
||||
{ \
|
||||
.iobase = _base, \
|
||||
.irq = _irq, \
|
||||
.uartclk = 1843200, \
|
||||
.iotype = UPIO_PORT, \
|
||||
.flags = UPF_BOOT_AUTOCONF, \
|
||||
}
|
||||
|
||||
static struct plat_serial8250_port a20r_data[] = {
|
||||
PORT(0x3f8, 4),
|
||||
PORT(0x2f8, 3),
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct platform_device a20r_serial8250_device = {
|
||||
.name = "serial8250",
|
||||
.id = PLAT8250_DEV_PLATFORM,
|
||||
.dev = {
|
||||
.platform_data = a20r_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource snirm_82596_rsrc[] = {
|
||||
{
|
||||
.start = 0xb8000000,
|
||||
.end = 0xb8000004,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
{
|
||||
.start = 0xb8010000,
|
||||
.end = 0xb8010004,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
{
|
||||
.start = 0xbff00000,
|
||||
.end = 0xbff00020,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
{
|
||||
.start = 22,
|
||||
.end = 22,
|
||||
.flags = IORESOURCE_IRQ
|
||||
},
|
||||
{
|
||||
.flags = 0x01 /* 16bit mpu port access */
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device snirm_82596_pdev = {
|
||||
.name = "snirm_82596",
|
||||
.num_resources = ARRAY_SIZE(snirm_82596_rsrc),
|
||||
.resource = snirm_82596_rsrc
|
||||
};
|
||||
|
||||
static struct resource snirm_53c710_rsrc[] = {
|
||||
{
|
||||
.start = 0xb9000000,
|
||||
.end = 0xb90fffff,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
{
|
||||
.start = 19,
|
||||
.end = 19,
|
||||
.flags = IORESOURCE_IRQ
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device snirm_53c710_pdev = {
|
||||
.name = "snirm_53c710",
|
||||
.num_resources = ARRAY_SIZE(snirm_53c710_rsrc),
|
||||
.resource = snirm_53c710_rsrc
|
||||
};
|
||||
|
||||
static struct resource sc26xx_rsrc[] = {
|
||||
{
|
||||
.start = 0xbc070000,
|
||||
.end = 0xbc0700ff,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
{
|
||||
.start = 20,
|
||||
.end = 20,
|
||||
.flags = IORESOURCE_IRQ
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device sc26xx_pdev = {
|
||||
.name = "SC26xx",
|
||||
.num_resources = ARRAY_SIZE(sc26xx_rsrc),
|
||||
.resource = sc26xx_rsrc
|
||||
};
|
||||
|
||||
static u32 a20r_ack_hwint(void)
|
||||
{
|
||||
u32 status = read_c0_status();
|
||||
|
||||
write_c0_status (status | 0x00010000);
|
||||
asm volatile(
|
||||
" .set push \n"
|
||||
" .set noat \n"
|
||||
" .set noreorder \n"
|
||||
" lw $1, 0(%0) \n"
|
||||
" sb $0, 0(%1) \n"
|
||||
" sync \n"
|
||||
" lb %1, 0(%1) \n"
|
||||
" b 1f \n"
|
||||
" ori %1, $1, 2 \n"
|
||||
" .align 8 \n"
|
||||
"1: \n"
|
||||
" nop \n"
|
||||
" sw %1, 0(%0) \n"
|
||||
" sync \n"
|
||||
" li %1, 0x20 \n"
|
||||
"2: \n"
|
||||
" nop \n"
|
||||
" bnez %1,2b \n"
|
||||
" addiu %1, -1 \n"
|
||||
" sw $1, 0(%0) \n"
|
||||
" sync \n"
|
||||
".set pop \n"
|
||||
:
|
||||
: "Jr" (PCIMT_UCONF), "Jr" (0xbc000000));
|
||||
write_c0_status(status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static inline void unmask_a20r_irq(unsigned int irq)
|
||||
{
|
||||
set_c0_status(0x100 << (irq - SNI_A20R_IRQ_BASE));
|
||||
irq_enable_hazard();
|
||||
}
|
||||
|
||||
static inline void mask_a20r_irq(unsigned int irq)
|
||||
{
|
||||
clear_c0_status(0x100 << (irq - SNI_A20R_IRQ_BASE));
|
||||
irq_disable_hazard();
|
||||
}
|
||||
|
||||
static void end_a20r_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
|
||||
a20r_ack_hwint();
|
||||
unmask_a20r_irq(irq);
|
||||
}
|
||||
}
|
||||
|
||||
static struct irq_chip a20r_irq_type = {
|
||||
.typename = "A20R",
|
||||
.ack = mask_a20r_irq,
|
||||
.mask = mask_a20r_irq,
|
||||
.mask_ack = mask_a20r_irq,
|
||||
.unmask = unmask_a20r_irq,
|
||||
.end = end_a20r_irq,
|
||||
};
|
||||
|
||||
/*
|
||||
* hwint 0 receive all interrupts
|
||||
*/
|
||||
static void a20r_hwint(void)
|
||||
{
|
||||
u32 cause, status;
|
||||
int irq;
|
||||
|
||||
clear_c0_status (IE_IRQ0);
|
||||
status = a20r_ack_hwint();
|
||||
cause = read_c0_cause();
|
||||
|
||||
irq = ffs(((cause & status) >> 8) & 0xf8);
|
||||
if (likely(irq > 0))
|
||||
do_IRQ(SNI_A20R_IRQ_BASE + irq - 1);
|
||||
set_c0_status(IE_IRQ0);
|
||||
}
|
||||
|
||||
void __init sni_a20r_irq_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = SNI_A20R_IRQ_BASE + 2 ; i < SNI_A20R_IRQ_BASE + 8; i++)
|
||||
set_irq_chip(i, &a20r_irq_type);
|
||||
sni_hwint = a20r_hwint;
|
||||
change_c0_status(ST0_IM, IE_IRQ0);
|
||||
setup_irq (SNI_A20R_IRQ_BASE + 3, &sni_isa_irq);
|
||||
}
|
||||
|
||||
void sni_a20r_init(void)
|
||||
{
|
||||
ds1216_base = (volatile unsigned char *) SNI_DS1216_A20R_BASE;
|
||||
rtc_mips_get_time = ds1216_get_cmos_time;
|
||||
}
|
||||
|
||||
static int __init snirm_a20r_setup_devinit(void)
|
||||
{
|
||||
switch (sni_brd_type) {
|
||||
case SNI_BRD_TOWER_OASIC:
|
||||
case SNI_BRD_MINITOWER:
|
||||
platform_device_register(&snirm_82596_pdev);
|
||||
platform_device_register(&snirm_53c710_pdev);
|
||||
platform_device_register(&sc26xx_pdev);
|
||||
platform_device_register(&a20r_serial8250_device);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
device_initcall(snirm_a20r_setup_devinit);
|
81
arch/mips/sni/ds1216.c
Normal file
81
arch/mips/sni/ds1216.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
|
||||
#include <linux/bcd.h>
|
||||
#include <linux/time.h>
|
||||
|
||||
#include <asm/ds1216.h>
|
||||
|
||||
volatile unsigned char *ds1216_base;
|
||||
|
||||
/*
|
||||
* Read the 64 bit we'd like to have - It a series
|
||||
* of 64 bits showing up in the LSB of the base register.
|
||||
*
|
||||
*/
|
||||
static unsigned char *ds1216_read(void)
|
||||
{
|
||||
static unsigned char rdbuf[8];
|
||||
unsigned char c;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
c = 0x0;
|
||||
for (j = 0; j < 8; j++) {
|
||||
c |= (*ds1216_base & 0x1) << j;
|
||||
}
|
||||
rdbuf[i] = c;
|
||||
}
|
||||
|
||||
return rdbuf;
|
||||
}
|
||||
|
||||
static void ds1216_switch_ds_to_clock(void)
|
||||
{
|
||||
unsigned char magic[] = {
|
||||
0xc5, 0x3a, 0xa3, 0x5c, 0xc5, 0x3a, 0xa3, 0x5c
|
||||
};
|
||||
int i,j,c;
|
||||
|
||||
/* Reset magic pointer */
|
||||
c = *ds1216_base;
|
||||
|
||||
/* Write 64 bit magic to DS1216 */
|
||||
for (i = 0; i < 8; i++) {
|
||||
c = magic[i];
|
||||
for (j = 0; j < 8; j++) {
|
||||
*ds1216_base = c;
|
||||
c = c >> 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long ds1216_get_cmos_time(void)
|
||||
{
|
||||
unsigned char *rdbuf;
|
||||
unsigned int year, month, date, hour, min, sec;
|
||||
|
||||
ds1216_switch_ds_to_clock();
|
||||
rdbuf = ds1216_read();
|
||||
|
||||
sec = BCD2BIN(DS1216_SEC(rdbuf));
|
||||
min = BCD2BIN(DS1216_MIN(rdbuf));
|
||||
hour = BCD2BIN(DS1216_HOUR(rdbuf));
|
||||
date = BCD2BIN(DS1216_DATE(rdbuf));
|
||||
month = BCD2BIN(DS1216_MONTH(rdbuf));
|
||||
year = BCD2BIN(DS1216_YEAR(rdbuf));
|
||||
|
||||
if (DS1216_1224(rdbuf) && DS1216_AMPM(rdbuf))
|
||||
hour+=12;
|
||||
|
||||
if (year < 70)
|
||||
year += 2000;
|
||||
else
|
||||
year += 1900;
|
||||
|
||||
return mktime(year, month, date, hour, min, sec);
|
||||
}
|
||||
|
||||
int ds1216_set_rtc_mmss(unsigned long nowtime)
|
||||
{
|
||||
printk("ds1216_set_rtc_mmss called but not implemented\n");
|
||||
return -1;
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
*
|
||||
* Copyright (C) 1992 Linus Torvalds
|
||||
* Copyright (C) 1994 - 2000 Ralf Baechle
|
||||
* Copyright (C) 2006 Thomas Bogendoerfer
|
||||
*/
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
|
@ -15,153 +16,35 @@
|
|||
#include <asm/i8259.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/sni.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/irq_cpu.h>
|
||||
|
||||
static void enable_pciasic_irq(unsigned int irq)
|
||||
{
|
||||
unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2);
|
||||
|
||||
*(volatile u8 *) PCIMT_IRQSEL |= mask;
|
||||
}
|
||||
|
||||
void disable_pciasic_irq(unsigned int irq)
|
||||
{
|
||||
unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2));
|
||||
|
||||
*(volatile u8 *) PCIMT_IRQSEL &= mask;
|
||||
}
|
||||
|
||||
static void end_pciasic_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
|
||||
enable_pciasic_irq(irq);
|
||||
}
|
||||
|
||||
static struct irq_chip pciasic_irq_type = {
|
||||
.name = "ASIC-PCI",
|
||||
.ack = disable_pciasic_irq,
|
||||
.mask = disable_pciasic_irq,
|
||||
.mask_ack = disable_pciasic_irq,
|
||||
.unmask = enable_pciasic_irq,
|
||||
.end = end_pciasic_irq,
|
||||
};
|
||||
|
||||
/*
|
||||
* hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
|
||||
* button interrupts. Later ...
|
||||
*/
|
||||
static void pciasic_hwint0(void)
|
||||
{
|
||||
panic("Received int0 but no handler yet ...");
|
||||
}
|
||||
|
||||
/* This interrupt was used for the com1 console on the first prototypes. */
|
||||
static void pciasic_hwint2(void)
|
||||
{
|
||||
/* I think this shouldn't happen on production machines. */
|
||||
panic("hwint2 and no handler yet");
|
||||
}
|
||||
|
||||
/* hwint5 is the r4k count / compare interrupt */
|
||||
static void pciasic_hwint5(void)
|
||||
{
|
||||
panic("hwint5 and no handler yet");
|
||||
}
|
||||
|
||||
static unsigned int ls1bit8(unsigned int x)
|
||||
{
|
||||
int b = 7, s;
|
||||
|
||||
s = 4; if ((x & 0x0f) == 0) s = 0; b -= s; x <<= s;
|
||||
s = 2; if ((x & 0x30) == 0) s = 0; b -= s; x <<= s;
|
||||
s = 1; if ((x & 0x40) == 0) s = 0; b -= s;
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/*
|
||||
* hwint 1 deals with EISA and SCSI interrupts,
|
||||
*
|
||||
* The EISA_INT bit in CSITPEND is high active, all others are low active.
|
||||
*/
|
||||
static void pciasic_hwint1(void)
|
||||
{
|
||||
u8 pend = *(volatile char *)PCIMT_CSITPEND;
|
||||
unsigned long flags;
|
||||
|
||||
if (pend & IT_EISA) {
|
||||
int irq;
|
||||
/*
|
||||
* Note: ASIC PCI's builtin interrupt achknowledge feature is
|
||||
* broken. Using it may result in loss of some or all i8259
|
||||
* interupts, so don't use PCIMT_INT_ACKNOWLEDGE ...
|
||||
*/
|
||||
irq = i8259_irq();
|
||||
if (unlikely(irq < 0))
|
||||
return;
|
||||
|
||||
do_IRQ(irq);
|
||||
}
|
||||
|
||||
if (!(pend & IT_SCSI)) {
|
||||
flags = read_c0_status();
|
||||
clear_c0_status(ST0_IM);
|
||||
do_IRQ(PCIMT_IRQ_SCSI);
|
||||
write_c0_status(flags);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* hwint 3 should deal with the PCI A - D interrupts,
|
||||
*/
|
||||
static void pciasic_hwint3(void)
|
||||
{
|
||||
u8 pend = *(volatile char *)PCIMT_CSITPEND;
|
||||
int irq;
|
||||
|
||||
pend &= (IT_INTA | IT_INTB | IT_INTC | IT_INTD);
|
||||
clear_c0_status(IE_IRQ3);
|
||||
irq = PCIMT_IRQ_INT2 + ls1bit8(pend);
|
||||
do_IRQ(irq);
|
||||
set_c0_status(IE_IRQ3);
|
||||
}
|
||||
|
||||
/*
|
||||
* hwint 4 is used for only the onboard PCnet 32.
|
||||
*/
|
||||
static void pciasic_hwint4(void)
|
||||
{
|
||||
clear_c0_status(IE_IRQ4);
|
||||
do_IRQ(PCIMT_IRQ_ETHERNET);
|
||||
set_c0_status(IE_IRQ4);
|
||||
}
|
||||
void (*sni_hwint)(void);
|
||||
|
||||
asmlinkage void plat_irq_dispatch(void)
|
||||
{
|
||||
unsigned int pending = read_c0_status() & read_c0_cause();
|
||||
static unsigned char led_cache;
|
||||
|
||||
*(volatile unsigned char *) PCIMT_CSLED = ++led_cache;
|
||||
|
||||
if (pending & 0x0800)
|
||||
pciasic_hwint1();
|
||||
else if (pending & 0x4000)
|
||||
pciasic_hwint4();
|
||||
else if (pending & 0x2000)
|
||||
pciasic_hwint3();
|
||||
else if (pending & 0x1000)
|
||||
pciasic_hwint2();
|
||||
else if (pending & 0x8000)
|
||||
pciasic_hwint5();
|
||||
else if (pending & 0x0400)
|
||||
pciasic_hwint0();
|
||||
sni_hwint();
|
||||
}
|
||||
|
||||
void __init init_pciasic(void)
|
||||
/* ISA irq handler */
|
||||
static irqreturn_t sni_isa_irq_handler(int dummy, void *p)
|
||||
{
|
||||
* (volatile u8 *) PCIMT_IRQSEL =
|
||||
IT_EISA | IT_INTA | IT_INTB | IT_INTC | IT_INTD;
|
||||
int irq;
|
||||
|
||||
irq = i8259_irq();
|
||||
if (unlikely(irq < 0))
|
||||
return IRQ_NONE;
|
||||
|
||||
do_IRQ(irq);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
struct irqaction sni_isa_irq = {
|
||||
.handler = sni_isa_irq_handler,
|
||||
.name = "ISA",
|
||||
.flags = SA_SHIRQ
|
||||
};
|
||||
|
||||
/*
|
||||
* On systems with i8259-style interrupt controllers we assume for
|
||||
* driver compatibility reasons interrupts 0 - 15 to be the i8295
|
||||
|
@ -169,14 +52,31 @@ void __init init_pciasic(void)
|
|||
*/
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
init_i8259_irqs(); /* Integrated i8259 */
|
||||
init_pciasic();
|
||||
switch (sni_brd_type) {
|
||||
case SNI_BRD_10:
|
||||
case SNI_BRD_10NEW:
|
||||
case SNI_BRD_TOWER_OASIC:
|
||||
case SNI_BRD_MINITOWER:
|
||||
sni_a20r_irq_init();
|
||||
break;
|
||||
|
||||
/* Actually we've got more interrupts to handle ... */
|
||||
for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_ETHERNET; i++)
|
||||
set_irq_chip(i, &pciasic_irq_type);
|
||||
case SNI_BRD_PCI_TOWER:
|
||||
sni_pcit_irq_init();
|
||||
break;
|
||||
|
||||
change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ2|IE_IRQ3|IE_IRQ4);
|
||||
case SNI_BRD_PCI_TOWER_CPLUS:
|
||||
sni_pcit_cplus_irq_init();
|
||||
break;
|
||||
|
||||
case SNI_BRD_RM200:
|
||||
sni_rm200_irq_init();
|
||||
break;
|
||||
|
||||
case SNI_BRD_PCI_MTOWER:
|
||||
case SNI_BRD_PCI_DESKTOP:
|
||||
case SNI_BRD_PCI_MTOWER_CPLUS:
|
||||
sni_pcimt_irq_init();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
390
arch/mips/sni/pcimt.c
Normal file
390
arch/mips/sni/pcimt.c
Normal file
|
@ -0,0 +1,390 @@
|
|||
/*
|
||||
* PCIMT specific code
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org)
|
||||
* Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/serial_8250.h>
|
||||
|
||||
#include <asm/mc146818-time.h>
|
||||
#include <asm/sni.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/i8259.h>
|
||||
#include <asm/irq_cpu.h>
|
||||
|
||||
#define cacheconf (*(volatile unsigned int *)PCIMT_CACHECONF)
|
||||
#define invspace (*(volatile unsigned int *)PCIMT_INVSPACE)
|
||||
|
||||
static void __init sni_pcimt_sc_init(void)
|
||||
{
|
||||
unsigned int scsiz, sc_size;
|
||||
|
||||
scsiz = cacheconf & 7;
|
||||
if (scsiz == 0) {
|
||||
printk("Second level cache is deactived.\n");
|
||||
return;
|
||||
}
|
||||
if (scsiz >= 6) {
|
||||
printk("Invalid second level cache size configured, "
|
||||
"deactivating second level cache.\n");
|
||||
cacheconf = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
sc_size = 128 << scsiz;
|
||||
printk("%dkb second level cache detected, deactivating.\n", sc_size);
|
||||
cacheconf = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* A bit more gossip about the iron we're running on ...
|
||||
*/
|
||||
static inline void sni_pcimt_detect(void)
|
||||
{
|
||||
char boardtype[80];
|
||||
unsigned char csmsr;
|
||||
char *p = boardtype;
|
||||
unsigned int asic;
|
||||
|
||||
csmsr = *(volatile unsigned char *)PCIMT_CSMSR;
|
||||
|
||||
p += sprintf(p, "%s PCI", (csmsr & 0x80) ? "RM200" : "RM300");
|
||||
if ((csmsr & 0x80) == 0)
|
||||
p += sprintf(p, ", board revision %s",
|
||||
(csmsr & 0x20) ? "D" : "C");
|
||||
asic = csmsr & 0x80;
|
||||
asic = (csmsr & 0x08) ? asic : !asic;
|
||||
p += sprintf(p, ", ASIC PCI Rev %s", asic ? "1.0" : "1.1");
|
||||
printk("%s.\n", boardtype);
|
||||
}
|
||||
|
||||
#define PORT(_base,_irq) \
|
||||
{ \
|
||||
.iobase = _base, \
|
||||
.irq = _irq, \
|
||||
.uartclk = 1843200, \
|
||||
.iotype = UPIO_PORT, \
|
||||
.flags = UPF_BOOT_AUTOCONF, \
|
||||
}
|
||||
|
||||
static struct plat_serial8250_port pcimt_data[] = {
|
||||
PORT(0x3f8, 4),
|
||||
PORT(0x2f8, 3),
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct platform_device pcimt_serial8250_device = {
|
||||
.name = "serial8250",
|
||||
.id = PLAT8250_DEV_PLATFORM,
|
||||
.dev = {
|
||||
.platform_data = pcimt_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource sni_io_resource = {
|
||||
.start = 0x00001000UL,
|
||||
.end = 0x03bfffffUL,
|
||||
.name = "PCIMT IO MEM",
|
||||
.flags = IORESOURCE_IO,
|
||||
};
|
||||
|
||||
static struct resource pcimt_io_resources[] = {
|
||||
{
|
||||
.start = 0x00,
|
||||
.end = 0x1f,
|
||||
.name = "dma1",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x40,
|
||||
.end = 0x5f,
|
||||
.name = "timer",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x60,
|
||||
.end = 0x6f,
|
||||
.name = "keyboard",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x80,
|
||||
.end = 0x8f,
|
||||
.name = "dma page reg",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0xc0,
|
||||
.end = 0xdf,
|
||||
.name = "dma2",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0xcfc,
|
||||
.end = 0xcff,
|
||||
.name = "PCI config data",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}
|
||||
};
|
||||
|
||||
static struct resource sni_mem_resource = {
|
||||
.start = 0x10000000UL,
|
||||
.end = 0xffffffffUL,
|
||||
.name = "PCIMT PCI MEM",
|
||||
.flags = IORESOURCE_MEM
|
||||
};
|
||||
|
||||
/*
|
||||
* The RM200/RM300 has a few holes in it's PCI/EISA memory address space used
|
||||
* for other purposes. Be paranoid and allocate all of the before the PCI
|
||||
* code gets a chance to to map anything else there ...
|
||||
*
|
||||
* This leaves the following areas available:
|
||||
*
|
||||
* 0x10000000 - 0x1009ffff (640kB) PCI/EISA/ISA Bus Memory
|
||||
* 0x10100000 - 0x13ffffff ( 15MB) PCI/EISA/ISA Bus Memory
|
||||
* 0x18000000 - 0x1fbfffff (124MB) PCI/EISA Bus Memory
|
||||
* 0x1ff08000 - 0x1ffeffff (816kB) PCI/EISA Bus Memory
|
||||
* 0xa0000000 - 0xffffffff (1.5GB) PCI/EISA Bus Memory
|
||||
*/
|
||||
static struct resource pcimt_mem_resources[] = {
|
||||
{
|
||||
.start = 0x100a0000,
|
||||
.end = 0x100bffff,
|
||||
.name = "Video RAM area",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x100c0000,
|
||||
.end = 0x100fffff,
|
||||
.name = "ISA Reserved",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x14000000,
|
||||
.end = 0x17bfffff,
|
||||
.name = "PCI IO",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x17c00000,
|
||||
.end = 0x17ffffff,
|
||||
.name = "Cache Replacement Area",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1a000000,
|
||||
.end = 0x1a000003,
|
||||
.name = "PCI INT Acknowledge",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1fc00000,
|
||||
.end = 0x1fc7ffff,
|
||||
.name = "Boot PROM",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1fc80000,
|
||||
.end = 0x1fcfffff,
|
||||
.name = "Diag PROM",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1fd00000,
|
||||
.end = 0x1fdfffff,
|
||||
.name = "X-Bus",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1fe00000,
|
||||
.end = 0x1fefffff,
|
||||
.name = "BIOS map",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1ff00000,
|
||||
.end = 0x1ff7ffff,
|
||||
.name = "NVRAM / EEPROM",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1fff0000,
|
||||
.end = 0x1fffefff,
|
||||
.name = "ASIC PCI",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1ffff000,
|
||||
.end = 0x1fffffff,
|
||||
.name = "MP Agent",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x20000000,
|
||||
.end = 0x9fffffff,
|
||||
.name = "Main Memory",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}
|
||||
};
|
||||
|
||||
static void __init sni_pcimt_resource_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* request I/O space for devices used on all i[345]86 PCs */
|
||||
for (i = 0; i < ARRAY_SIZE(pcimt_io_resources); i++)
|
||||
request_resource(&ioport_resource, pcimt_io_resources + i);
|
||||
|
||||
/* request mem space for pcimt-specific devices */
|
||||
for (i = 0; i < ARRAY_SIZE(pcimt_mem_resources); i++)
|
||||
request_resource(&sni_mem_resource, pcimt_mem_resources + i);
|
||||
|
||||
ioport_resource.end = sni_io_resource.end;
|
||||
}
|
||||
|
||||
extern struct pci_ops sni_pcimt_ops;
|
||||
|
||||
static struct pci_controller sni_controller = {
|
||||
.pci_ops = &sni_pcimt_ops,
|
||||
.mem_resource = &sni_mem_resource,
|
||||
.mem_offset = 0x10000000UL,
|
||||
.io_resource = &sni_io_resource,
|
||||
.io_offset = 0x00000000UL
|
||||
};
|
||||
|
||||
static void enable_pcimt_irq(unsigned int irq)
|
||||
{
|
||||
unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2);
|
||||
|
||||
*(volatile u8 *) PCIMT_IRQSEL |= mask;
|
||||
}
|
||||
|
||||
void disable_pcimt_irq(unsigned int irq)
|
||||
{
|
||||
unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2));
|
||||
|
||||
*(volatile u8 *) PCIMT_IRQSEL &= mask;
|
||||
}
|
||||
|
||||
static void end_pcimt_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
|
||||
enable_pcimt_irq(irq);
|
||||
}
|
||||
|
||||
static struct irq_chip pcimt_irq_type = {
|
||||
.typename = "PCIMT",
|
||||
.ack = disable_pcimt_irq,
|
||||
.mask = disable_pcimt_irq,
|
||||
.mask_ack = disable_pcimt_irq,
|
||||
.unmask = enable_pcimt_irq,
|
||||
.end = end_pcimt_irq,
|
||||
};
|
||||
|
||||
/*
|
||||
* hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
|
||||
* button interrupts. Later ...
|
||||
*/
|
||||
static void pcimt_hwint0(void)
|
||||
{
|
||||
panic("Received int0 but no handler yet ...");
|
||||
}
|
||||
|
||||
/*
|
||||
* hwint 1 deals with EISA and SCSI interrupts,
|
||||
*
|
||||
* The EISA_INT bit in CSITPEND is high active, all others are low active.
|
||||
*/
|
||||
static void pcimt_hwint1(void)
|
||||
{
|
||||
u8 pend = *(volatile char *)PCIMT_CSITPEND;
|
||||
unsigned long flags;
|
||||
|
||||
if (pend & IT_EISA) {
|
||||
int irq;
|
||||
/*
|
||||
* Note: ASIC PCI's builtin interrupt achknowledge feature is
|
||||
* broken. Using it may result in loss of some or all i8259
|
||||
* interupts, so don't use PCIMT_INT_ACKNOWLEDGE ...
|
||||
*/
|
||||
irq = i8259_irq();
|
||||
if (unlikely(irq < 0))
|
||||
return;
|
||||
|
||||
do_IRQ(irq);
|
||||
}
|
||||
|
||||
if (!(pend & IT_SCSI)) {
|
||||
flags = read_c0_status();
|
||||
clear_c0_status(ST0_IM);
|
||||
do_IRQ(PCIMT_IRQ_SCSI);
|
||||
write_c0_status(flags);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* hwint 3 should deal with the PCI A - D interrupts,
|
||||
*/
|
||||
static void pcimt_hwint3(void)
|
||||
{
|
||||
u8 pend = *(volatile char *)PCIMT_CSITPEND;
|
||||
int irq;
|
||||
|
||||
pend &= (IT_INTA | IT_INTB | IT_INTC | IT_INTD);
|
||||
pend ^= (IT_INTA | IT_INTB | IT_INTC | IT_INTD);
|
||||
clear_c0_status(IE_IRQ3);
|
||||
irq = PCIMT_IRQ_INT2 + ffs(pend) - 1;
|
||||
do_IRQ(irq);
|
||||
set_c0_status(IE_IRQ3);
|
||||
}
|
||||
|
||||
static void sni_pcimt_hwint(void)
|
||||
{
|
||||
u32 pending = (read_c0_cause() & read_c0_status());
|
||||
|
||||
if (pending & C_IRQ5)
|
||||
do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 7);
|
||||
else if (pending & C_IRQ4)
|
||||
do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 6);
|
||||
else if (pending & C_IRQ3)
|
||||
pcimt_hwint3();
|
||||
else if (pending & C_IRQ1)
|
||||
pcimt_hwint1();
|
||||
else if (pending & C_IRQ0) {
|
||||
pcimt_hwint0();
|
||||
}
|
||||
}
|
||||
|
||||
void __init sni_pcimt_irq_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
*(volatile u8 *) PCIMT_IRQSEL = IT_ETH | IT_EISA;
|
||||
mips_cpu_irq_init();
|
||||
/* Actually we've got more interrupts to handle ... */
|
||||
for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_SCSI; i++)
|
||||
set_irq_chip(i, &pcimt_irq_type);
|
||||
sni_hwint = sni_pcimt_hwint;
|
||||
change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3);
|
||||
}
|
||||
|
||||
void sni_pcimt_init(void)
|
||||
{
|
||||
sni_pcimt_resource_init();
|
||||
sni_pcimt_detect();
|
||||
sni_pcimt_sc_init();
|
||||
rtc_mips_get_time = mc146818_get_cmos_time;
|
||||
rtc_mips_set_time = mc146818_set_rtc_mmss;
|
||||
board_time_init = sni_cpu_time_init;
|
||||
#ifdef CONFIG_PCI
|
||||
register_pci_controller(&sni_controller);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int __init snirm_pcimt_setup_devinit(void)
|
||||
{
|
||||
switch (sni_brd_type) {
|
||||
case SNI_BRD_PCI_MTOWER:
|
||||
case SNI_BRD_PCI_DESKTOP:
|
||||
case SNI_BRD_PCI_MTOWER_CPLUS:
|
||||
platform_device_register(&pcimt_serial8250_device);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
device_initcall(snirm_pcimt_setup_devinit);
|
351
arch/mips/sni/pcit.c
Normal file
351
arch/mips/sni/pcit.c
Normal file
|
@ -0,0 +1,351 @@
|
|||
/*
|
||||
* PCI Tower specific code
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/serial_8250.h>
|
||||
|
||||
#include <asm/mc146818-time.h>
|
||||
#include <asm/sni.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/irq_cpu.h>
|
||||
|
||||
|
||||
#define PORT(_base,_irq) \
|
||||
{ \
|
||||
.iobase = _base, \
|
||||
.irq = _irq, \
|
||||
.uartclk = 1843200, \
|
||||
.iotype = UPIO_PORT, \
|
||||
.flags = UPF_BOOT_AUTOCONF, \
|
||||
}
|
||||
|
||||
static struct plat_serial8250_port pcit_data[] = {
|
||||
PORT(0x3f8, 0),
|
||||
PORT(0x2f8, 3),
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct platform_device pcit_serial8250_device = {
|
||||
.name = "serial8250",
|
||||
.id = PLAT8250_DEV_PLATFORM,
|
||||
.dev = {
|
||||
.platform_data = pcit_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct plat_serial8250_port pcit_cplus_data[] = {
|
||||
PORT(0x3f8, 4),
|
||||
PORT(0x2f8, 3),
|
||||
PORT(0x3e8, 4),
|
||||
PORT(0x2e8, 3),
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct platform_device pcit_cplus_serial8250_device = {
|
||||
.name = "serial8250",
|
||||
.id = PLAT8250_DEV_PLATFORM,
|
||||
.dev = {
|
||||
.platform_data = pcit_cplus_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource sni_io_resource = {
|
||||
.start = 0x00001000UL,
|
||||
.end = 0x03bfffffUL,
|
||||
.name = "PCIT IO MEM",
|
||||
.flags = IORESOURCE_IO,
|
||||
};
|
||||
|
||||
static struct resource pcit_io_resources[] = {
|
||||
{
|
||||
.start = 0x00,
|
||||
.end = 0x1f,
|
||||
.name = "dma1",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x40,
|
||||
.end = 0x5f,
|
||||
.name = "timer",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x60,
|
||||
.end = 0x6f,
|
||||
.name = "keyboard",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x80,
|
||||
.end = 0x8f,
|
||||
.name = "dma page reg",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0xc0,
|
||||
.end = 0xdf,
|
||||
.name = "dma2",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0xcfc,
|
||||
.end = 0xcff,
|
||||
.name = "PCI config data",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}
|
||||
};
|
||||
|
||||
static struct resource sni_mem_resource = {
|
||||
.start = 0x10000000UL,
|
||||
.end = 0xffffffffUL,
|
||||
.name = "PCIT PCI MEM",
|
||||
.flags = IORESOURCE_MEM
|
||||
};
|
||||
|
||||
/*
|
||||
* The RM200/RM300 has a few holes in it's PCI/EISA memory address space used
|
||||
* for other purposes. Be paranoid and allocate all of the before the PCI
|
||||
* code gets a chance to to map anything else there ...
|
||||
*
|
||||
* This leaves the following areas available:
|
||||
*
|
||||
* 0x10000000 - 0x1009ffff (640kB) PCI/EISA/ISA Bus Memory
|
||||
* 0x10100000 - 0x13ffffff ( 15MB) PCI/EISA/ISA Bus Memory
|
||||
* 0x18000000 - 0x1fbfffff (124MB) PCI/EISA Bus Memory
|
||||
* 0x1ff08000 - 0x1ffeffff (816kB) PCI/EISA Bus Memory
|
||||
* 0xa0000000 - 0xffffffff (1.5GB) PCI/EISA Bus Memory
|
||||
*/
|
||||
static struct resource pcit_mem_resources[] = {
|
||||
{
|
||||
.start = 0x14000000,
|
||||
.end = 0x17bfffff,
|
||||
.name = "PCI IO",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x17c00000,
|
||||
.end = 0x17ffffff,
|
||||
.name = "Cache Replacement Area",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x180a0000,
|
||||
.end = 0x180bffff,
|
||||
.name = "Video RAM area",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x180c0000,
|
||||
.end = 0x180fffff,
|
||||
.name = "ISA Reserved",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x19000000,
|
||||
.end = 0x1fbfffff,
|
||||
.name = "PCI MEM",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1fc00000,
|
||||
.end = 0x1fc7ffff,
|
||||
.name = "Boot PROM",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1fc80000,
|
||||
.end = 0x1fcfffff,
|
||||
.name = "Diag PROM",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1fd00000,
|
||||
.end = 0x1fdfffff,
|
||||
.name = "X-Bus",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1fe00000,
|
||||
.end = 0x1fefffff,
|
||||
.name = "BIOS map",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1ff00000,
|
||||
.end = 0x1ff7ffff,
|
||||
.name = "NVRAM / EEPROM",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1fff0000,
|
||||
.end = 0x1fffefff,
|
||||
.name = "MAUI ASIC",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1ffff000,
|
||||
.end = 0x1fffffff,
|
||||
.name = "MP Agent",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x20000000,
|
||||
.end = 0x9fffffff,
|
||||
.name = "Main Memory",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}
|
||||
};
|
||||
|
||||
static void __init sni_pcit_resource_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* request I/O space for devices used on all i[345]86 PCs */
|
||||
for (i = 0; i < ARRAY_SIZE(pcit_io_resources); i++)
|
||||
request_resource(&ioport_resource, pcit_io_resources + i);
|
||||
|
||||
/* request mem space for pcimt-specific devices */
|
||||
for (i = 0; i < ARRAY_SIZE(pcit_mem_resources); i++)
|
||||
request_resource(&sni_mem_resource, pcit_mem_resources + i);
|
||||
|
||||
ioport_resource.end = sni_io_resource.end;
|
||||
}
|
||||
|
||||
|
||||
extern struct pci_ops sni_pcit_ops;
|
||||
|
||||
static struct pci_controller sni_pcit_controller = {
|
||||
.pci_ops = &sni_pcit_ops,
|
||||
.mem_resource = &sni_mem_resource,
|
||||
.mem_offset = 0x10000000UL,
|
||||
.io_resource = &sni_io_resource,
|
||||
.io_offset = 0x00000000UL
|
||||
};
|
||||
|
||||
static void enable_pcit_irq(unsigned int irq)
|
||||
{
|
||||
u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24);
|
||||
|
||||
*(volatile u32 *)SNI_PCIT_INT_REG |= mask;
|
||||
}
|
||||
|
||||
void disable_pcit_irq(unsigned int irq)
|
||||
{
|
||||
u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24);
|
||||
|
||||
*(volatile u32 *)SNI_PCIT_INT_REG &= ~mask;
|
||||
}
|
||||
|
||||
void end_pcit_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
|
||||
enable_pcit_irq(irq);
|
||||
}
|
||||
|
||||
static struct irq_chip pcit_irq_type = {
|
||||
.typename = "PCIT",
|
||||
.ack = disable_pcit_irq,
|
||||
.mask = disable_pcit_irq,
|
||||
.mask_ack = disable_pcit_irq,
|
||||
.unmask = enable_pcit_irq,
|
||||
.end = end_pcit_irq,
|
||||
};
|
||||
|
||||
static void pcit_hwint1(void)
|
||||
{
|
||||
u32 pending = *(volatile u32 *)SNI_PCIT_INT_REG;
|
||||
int irq;
|
||||
|
||||
clear_c0_status(IE_IRQ1);
|
||||
irq = ffs((pending >> 16) & 0x7f);
|
||||
|
||||
if (likely(irq > 0))
|
||||
do_IRQ (irq + SNI_PCIT_INT_START - 1);
|
||||
set_c0_status (IE_IRQ1);
|
||||
}
|
||||
|
||||
static void pcit_hwint0(void)
|
||||
{
|
||||
u32 pending = *(volatile u32 *)SNI_PCIT_INT_REG;
|
||||
int irq;
|
||||
|
||||
clear_c0_status(IE_IRQ0);
|
||||
irq = ffs((pending >> 16) & 0x7f);
|
||||
|
||||
if (likely(irq > 0))
|
||||
do_IRQ (irq + SNI_PCIT_INT_START - 1);
|
||||
set_c0_status (IE_IRQ0);
|
||||
}
|
||||
|
||||
static void sni_pcit_hwint(void)
|
||||
{
|
||||
u32 pending = (read_c0_cause() & read_c0_status());
|
||||
|
||||
if (pending & C_IRQ1)
|
||||
pcit_hwint1();
|
||||
else if (pending & C_IRQ2)
|
||||
do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 4);
|
||||
else if (pending & C_IRQ3)
|
||||
do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 5);
|
||||
else if (pending & C_IRQ5)
|
||||
do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 7);
|
||||
}
|
||||
|
||||
static void sni_pcit_hwint_cplus(void)
|
||||
{
|
||||
u32 pending = (read_c0_cause() & read_c0_status());
|
||||
|
||||
if (pending & C_IRQ0)
|
||||
pcit_hwint0();
|
||||
else if (pending & C_IRQ2)
|
||||
do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 4);
|
||||
else if (pending & C_IRQ3)
|
||||
do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 5);
|
||||
else if (pending & C_IRQ5)
|
||||
do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 7);
|
||||
}
|
||||
|
||||
void __init sni_pcit_irq_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
mips_cpu_irq_init();
|
||||
for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
|
||||
set_irq_chip(i, &pcit_irq_type);
|
||||
*(volatile u32 *)SNI_PCIT_INT_REG = 0;
|
||||
sni_hwint = sni_pcit_hwint;
|
||||
change_c0_status(ST0_IM, IE_IRQ1);
|
||||
setup_irq (SNI_PCIT_INT_START + 6, &sni_isa_irq);
|
||||
}
|
||||
|
||||
void __init sni_pcit_cplus_irq_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
mips_cpu_irq_init();
|
||||
for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
|
||||
set_irq_chip(i, &pcit_irq_type);
|
||||
*(volatile u32 *)SNI_PCIT_INT_REG = 0;
|
||||
sni_hwint = sni_pcit_hwint_cplus;
|
||||
change_c0_status(ST0_IM, IE_IRQ0);
|
||||
setup_irq (SNI_PCIT_INT_START + 6, &sni_isa_irq);
|
||||
}
|
||||
|
||||
void sni_pcit_init(void)
|
||||
{
|
||||
sni_pcit_resource_init();
|
||||
rtc_mips_get_time = mc146818_get_cmos_time;
|
||||
rtc_mips_set_time = mc146818_set_rtc_mmss;
|
||||
board_time_init = sni_cpu_time_init;
|
||||
#ifdef CONFIG_PCI
|
||||
register_pci_controller(&sni_pcit_controller);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int __init snirm_pcit_setup_devinit(void)
|
||||
{
|
||||
switch (sni_brd_type) {
|
||||
case SNI_BRD_PCI_TOWER:
|
||||
platform_device_register(&pcit_serial8250_device);
|
||||
break;
|
||||
|
||||
case SNI_BRD_PCI_TOWER_CPLUS:
|
||||
platform_device_register(&pcit_cplus_serial8250_device);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
device_initcall(snirm_pcit_setup_devinit);
|
|
@ -13,12 +13,11 @@
|
|||
* controller to pulse the reset-line low. We try that for a while,
|
||||
* and if it doesn't work, we do some other stupid things.
|
||||
*/
|
||||
static inline void
|
||||
kb_wait(void)
|
||||
static inline void kb_wait(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<0x10000; i++)
|
||||
for (i = 0; i < 0x10000; i++)
|
||||
if ((inb_p(0x64) & 0x02) == 0)
|
||||
break;
|
||||
}
|
||||
|
@ -32,9 +31,9 @@ void sni_machine_restart(char *command)
|
|||
We can do that easier ... */
|
||||
local_irq_disable();
|
||||
for (;;) {
|
||||
for (i=0; i<100; i++) {
|
||||
for (i = 0; i < 100; i++) {
|
||||
kb_wait();
|
||||
for(j = 0; j < 100000 ; j++)
|
||||
for (j = 0; j < 100000 ; j++)
|
||||
/* nothing */;
|
||||
outb_p(0xfe,0x64); /* pulse reset low */
|
||||
}
|
||||
|
|
186
arch/mips/sni/rm200.c
Normal file
186
arch/mips/sni/rm200.c
Normal file
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* RM200 specific code
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/serial_8250.h>
|
||||
|
||||
#include <asm/sni.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/ds1216.h>
|
||||
#include <asm/irq_cpu.h>
|
||||
|
||||
#define PORT(_base,_irq) \
|
||||
{ \
|
||||
.iobase = _base, \
|
||||
.irq = _irq, \
|
||||
.uartclk = 1843200, \
|
||||
.iotype = UPIO_PORT, \
|
||||
.flags = UPF_BOOT_AUTOCONF, \
|
||||
}
|
||||
|
||||
static struct plat_serial8250_port rm200_data[] = {
|
||||
PORT(0x3f8, 4),
|
||||
PORT(0x2f8, 3),
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct platform_device rm200_serial8250_device = {
|
||||
.name = "serial8250",
|
||||
.id = PLAT8250_DEV_PLATFORM,
|
||||
.dev = {
|
||||
.platform_data = rm200_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource snirm_82596_rm200_rsrc[] = {
|
||||
{
|
||||
.start = 0xb8000000,
|
||||
.end = 0xb80fffff,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
{
|
||||
.start = 0xbb000000,
|
||||
.end = 0xbb000004,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
{
|
||||
.start = 0xbff00000,
|
||||
.end = 0xbff00020,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
{
|
||||
.start = 27,
|
||||
.end = 27,
|
||||
.flags = IORESOURCE_IRQ
|
||||
},
|
||||
{
|
||||
.flags = 0x00
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device snirm_82596_rm200_pdev = {
|
||||
.name = "snirm_82596",
|
||||
.num_resources = ARRAY_SIZE(snirm_82596_rm200_rsrc),
|
||||
.resource = snirm_82596_rm200_rsrc
|
||||
};
|
||||
|
||||
static struct resource snirm_53c710_rm200_rsrc[] = {
|
||||
{
|
||||
.start = 0xb9000000,
|
||||
.end = 0xb90fffff,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
{
|
||||
.start = 26,
|
||||
.end = 26,
|
||||
.flags = IORESOURCE_IRQ
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device snirm_53c710_rm200_pdev = {
|
||||
.name = "snirm_53c710",
|
||||
.num_resources = ARRAY_SIZE(snirm_53c710_rm200_rsrc),
|
||||
.resource = snirm_53c710_rm200_rsrc
|
||||
};
|
||||
|
||||
static int __init snirm_setup_devinit(void)
|
||||
{
|
||||
if (sni_brd_type == SNI_BRD_RM200) {
|
||||
platform_device_register(&rm200_serial8250_device);
|
||||
platform_device_register(&snirm_82596_rm200_pdev);
|
||||
platform_device_register(&snirm_53c710_rm200_pdev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
device_initcall(snirm_setup_devinit);
|
||||
|
||||
|
||||
#define SNI_RM200_INT_STAT_REG 0xbc000000
|
||||
#define SNI_RM200_INT_ENA_REG 0xbc080000
|
||||
|
||||
#define SNI_RM200_INT_START 24
|
||||
#define SNI_RM200_INT_END 28
|
||||
|
||||
static void enable_rm200_irq(unsigned int irq)
|
||||
{
|
||||
unsigned int mask = 1 << (irq - SNI_RM200_INT_START);
|
||||
|
||||
*(volatile u8 *)SNI_RM200_INT_ENA_REG &= ~mask;
|
||||
}
|
||||
|
||||
void disable_rm200_irq(unsigned int irq)
|
||||
{
|
||||
unsigned int mask = 1 << (irq - SNI_RM200_INT_START);
|
||||
|
||||
*(volatile u8 *)SNI_RM200_INT_ENA_REG |= mask;
|
||||
}
|
||||
|
||||
void end_rm200_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
|
||||
enable_rm200_irq(irq);
|
||||
}
|
||||
|
||||
static struct irq_chip rm200_irq_type = {
|
||||
.typename = "RM200",
|
||||
.ack = disable_rm200_irq,
|
||||
.mask = disable_rm200_irq,
|
||||
.mask_ack = disable_rm200_irq,
|
||||
.unmask = enable_rm200_irq,
|
||||
.end = end_rm200_irq,
|
||||
};
|
||||
|
||||
static void sni_rm200_hwint(void)
|
||||
{
|
||||
u32 pending = read_c0_cause() & read_c0_status();
|
||||
u8 mask;
|
||||
u8 stat;
|
||||
int irq;
|
||||
|
||||
if (pending & C_IRQ5)
|
||||
do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 7);
|
||||
else if (pending & C_IRQ0) {
|
||||
clear_c0_status (IE_IRQ0);
|
||||
mask = *(volatile u8 *)SNI_RM200_INT_ENA_REG ^ 0x1f;
|
||||
stat = *(volatile u8 *)SNI_RM200_INT_STAT_REG ^ 0x14;
|
||||
irq = ffs(stat & mask & 0x1f);
|
||||
|
||||
if (likely(irq > 0))
|
||||
do_IRQ (irq + SNI_RM200_INT_START - 1);
|
||||
set_c0_status (IE_IRQ0);
|
||||
}
|
||||
}
|
||||
|
||||
void __init sni_rm200_irq_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
* (volatile u8 *)SNI_RM200_INT_ENA_REG = 0x1f;
|
||||
|
||||
mips_cpu_irq_init();
|
||||
/* Actually we've got more interrupts to handle ... */
|
||||
for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++)
|
||||
set_irq_chip(i, &rm200_irq_type);
|
||||
sni_hwint = sni_rm200_hwint;
|
||||
change_c0_status(ST0_IM, IE_IRQ0);
|
||||
setup_irq (SNI_RM200_INT_START + 0, &sni_isa_irq);
|
||||
}
|
||||
|
||||
void sni_rm200_init(void)
|
||||
{
|
||||
set_io_port_base(SNI_PORT_BASE + 0x02000000);
|
||||
ioport_resource.end += 0x02000000;
|
||||
ds1216_base = (volatile unsigned char *) SNI_DS1216_RM200_BASE;
|
||||
rtc_mips_get_time = ds1216_get_cmos_time;
|
||||
board_time_init = sni_cpu_time_init;
|
||||
}
|
|
@ -6,16 +6,10 @@
|
|||
* for more details.
|
||||
*
|
||||
* Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org)
|
||||
* Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
|
||||
*/
|
||||
#include <linux/eisa.h>
|
||||
#include <linux/hdreg.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mc146818rtc.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/screen_info.h>
|
||||
|
@ -25,52 +19,16 @@
|
|||
#include <asm/sgialib.h>
|
||||
#endif
|
||||
|
||||
#include <asm/bcache.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mc146818-time.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/sni.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/traps.h>
|
||||
|
||||
unsigned int sni_brd_type;
|
||||
|
||||
extern void sni_machine_restart(char *command);
|
||||
extern void sni_machine_halt(void);
|
||||
extern void sni_machine_power_off(void);
|
||||
|
||||
void __init plat_timer_setup(struct irqaction *irq)
|
||||
{
|
||||
/* set the clock to 100 Hz */
|
||||
outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
|
||||
outb_p(LATCH & 0xff , 0x40); /* LSB */
|
||||
outb(LATCH >> 8 , 0x40); /* MSB */
|
||||
setup_irq(0, irq);
|
||||
}
|
||||
|
||||
/*
|
||||
* A bit more gossip about the iron we're running on ...
|
||||
*/
|
||||
static inline void sni_pcimt_detect(void)
|
||||
{
|
||||
char boardtype[80];
|
||||
unsigned char csmsr;
|
||||
char *p = boardtype;
|
||||
unsigned int asic;
|
||||
|
||||
csmsr = *(volatile unsigned char *)PCIMT_CSMSR;
|
||||
|
||||
p += sprintf(p, "%s PCI", (csmsr & 0x80) ? "RM200" : "RM300");
|
||||
if ((csmsr & 0x80) == 0)
|
||||
p += sprintf(p, ", board revision %s",
|
||||
(csmsr & 0x20) ? "D" : "C");
|
||||
asic = csmsr & 0x80;
|
||||
asic = (csmsr & 0x08) ? asic : !asic;
|
||||
p += sprintf(p, ", ASIC PCI Rev %s", asic ? "1.0" : "1.1");
|
||||
printk("%s.\n", boardtype);
|
||||
}
|
||||
|
||||
static void __init sni_display_setup(void)
|
||||
{
|
||||
#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) && defined(CONFIG_ARC)
|
||||
|
@ -90,175 +48,11 @@ static void __init sni_display_setup(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static struct resource sni_io_resource = {
|
||||
.start = 0x00001000UL,
|
||||
.end = 0x03bfffffUL,
|
||||
.name = "PCIMT IO MEM",
|
||||
.flags = IORESOURCE_IO,
|
||||
};
|
||||
|
||||
static struct resource pcimt_io_resources[] = {
|
||||
{
|
||||
.start = 0x00,
|
||||
.end = 0x1f,
|
||||
.name = "dma1",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x40,
|
||||
.end = 0x5f,
|
||||
.name = "timer",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x60,
|
||||
.end = 0x6f,
|
||||
.name = "keyboard",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x80,
|
||||
.end = 0x8f,
|
||||
.name = "dma page reg",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0xc0,
|
||||
.end = 0xdf,
|
||||
.name = "dma2",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0xcfc,
|
||||
.end = 0xcff,
|
||||
.name = "PCI config data",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}
|
||||
};
|
||||
|
||||
static struct resource sni_mem_resource = {
|
||||
.start = 0x10000000UL,
|
||||
.end = 0xffffffffUL,
|
||||
.name = "PCIMT PCI MEM",
|
||||
.flags = IORESOURCE_MEM
|
||||
};
|
||||
|
||||
/*
|
||||
* The RM200/RM300 has a few holes in it's PCI/EISA memory address space used
|
||||
* for other purposes. Be paranoid and allocate all of the before the PCI
|
||||
* code gets a chance to to map anything else there ...
|
||||
*
|
||||
* This leaves the following areas available:
|
||||
*
|
||||
* 0x10000000 - 0x1009ffff (640kB) PCI/EISA/ISA Bus Memory
|
||||
* 0x10100000 - 0x13ffffff ( 15MB) PCI/EISA/ISA Bus Memory
|
||||
* 0x18000000 - 0x1fbfffff (124MB) PCI/EISA Bus Memory
|
||||
* 0x1ff08000 - 0x1ffeffff (816kB) PCI/EISA Bus Memory
|
||||
* 0xa0000000 - 0xffffffff (1.5GB) PCI/EISA Bus Memory
|
||||
*/
|
||||
static struct resource pcimt_mem_resources[] = {
|
||||
{
|
||||
.start = 0x100a0000,
|
||||
.end = 0x100bffff,
|
||||
.name = "Video RAM area",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x100c0000,
|
||||
.end = 0x100fffff,
|
||||
.name = "ISA Reserved",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x14000000,
|
||||
.end = 0x17bfffff,
|
||||
.name = "PCI IO",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x17c00000,
|
||||
.end = 0x17ffffff,
|
||||
.name = "Cache Replacement Area",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1a000000,
|
||||
.end = 0x1a000003,
|
||||
.name = "PCI INT Acknowledge",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1fc00000,
|
||||
.end = 0x1fc7ffff,
|
||||
.name = "Boot PROM",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1fc80000,
|
||||
.end = 0x1fcfffff,
|
||||
.name = "Diag PROM",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1fd00000,
|
||||
.end = 0x1fdfffff,
|
||||
.name = "X-Bus",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1fe00000,
|
||||
.end = 0x1fefffff,
|
||||
.name = "BIOS map",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1ff00000,
|
||||
.end = 0x1ff7ffff,
|
||||
.name = "NVRAM / EEPROM",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1fff0000,
|
||||
.end = 0x1fffefff,
|
||||
.name = "ASIC PCI",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x1ffff000,
|
||||
.end = 0x1fffffff,
|
||||
.name = "MP Agent",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}, {
|
||||
.start = 0x20000000,
|
||||
.end = 0x9fffffff,
|
||||
.name = "Main Memory",
|
||||
.flags = IORESOURCE_BUSY
|
||||
}
|
||||
};
|
||||
|
||||
static void __init sni_resource_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* request I/O space for devices used on all i[345]86 PCs */
|
||||
for (i = 0; i < ARRAY_SIZE(pcimt_io_resources); i++)
|
||||
request_resource(&ioport_resource, pcimt_io_resources + i);
|
||||
|
||||
/* request mem space for pcimt-specific devices */
|
||||
for (i = 0; i < ARRAY_SIZE(pcimt_mem_resources); i++)
|
||||
request_resource(&sni_mem_resource, pcimt_mem_resources + i);
|
||||
|
||||
ioport_resource.end = sni_io_resource.end;
|
||||
}
|
||||
|
||||
extern struct pci_ops sni_pci_ops;
|
||||
|
||||
static struct pci_controller sni_controller = {
|
||||
.pci_ops = &sni_pci_ops,
|
||||
.mem_resource = &sni_mem_resource,
|
||||
.mem_offset = 0x10000000UL,
|
||||
.io_resource = &sni_io_resource,
|
||||
.io_offset = 0x00000000UL
|
||||
};
|
||||
|
||||
static inline void sni_pcimt_time_init(void)
|
||||
{
|
||||
rtc_mips_get_time = mc146818_get_cmos_time;
|
||||
rtc_mips_set_time = mc146818_set_rtc_mmss;
|
||||
}
|
||||
|
||||
void __init plat_mem_setup(void)
|
||||
{
|
||||
sni_pcimt_detect();
|
||||
sni_pcimt_sc_init();
|
||||
sni_pcimt_time_init();
|
||||
|
||||
set_io_port_base(SNI_PORT_BASE);
|
||||
ioport_resource.end = sni_io_resource.end;
|
||||
// ioport_resource.end = sni_io_resource.end;
|
||||
|
||||
/*
|
||||
* Setup (E)ISA I/O memory access stuff
|
||||
|
@ -268,15 +62,33 @@ void __init plat_mem_setup(void)
|
|||
EISA_bus = 1;
|
||||
#endif
|
||||
|
||||
sni_resource_init();
|
||||
switch (sni_brd_type) {
|
||||
case SNI_BRD_10:
|
||||
case SNI_BRD_10NEW:
|
||||
case SNI_BRD_TOWER_OASIC:
|
||||
case SNI_BRD_MINITOWER:
|
||||
sni_a20r_init();
|
||||
break;
|
||||
|
||||
case SNI_BRD_PCI_TOWER:
|
||||
case SNI_BRD_PCI_TOWER_CPLUS:
|
||||
sni_pcit_init();
|
||||
break;
|
||||
|
||||
case SNI_BRD_RM200:
|
||||
sni_rm200_init();
|
||||
break;
|
||||
|
||||
case SNI_BRD_PCI_MTOWER:
|
||||
case SNI_BRD_PCI_DESKTOP:
|
||||
case SNI_BRD_PCI_MTOWER_CPLUS:
|
||||
sni_pcimt_init();
|
||||
break;
|
||||
}
|
||||
|
||||
_machine_restart = sni_machine_restart;
|
||||
_machine_halt = sni_machine_halt;
|
||||
pm_power_off = sni_machine_power_off;
|
||||
|
||||
sni_display_setup();
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
register_pci_controller(&sni_controller);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/console.h>
|
||||
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/sni.h>
|
||||
|
@ -31,7 +32,7 @@
|
|||
#define PROM_ENTRY(x) (PROM_VEC + (x))
|
||||
|
||||
|
||||
#undef DEBUG
|
||||
#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#define DBG_PRINTF(x...) prom_printf(x)
|
||||
#else
|
||||
|
@ -93,14 +94,14 @@ static void sni_idprom_dump(void)
|
|||
{
|
||||
int i;
|
||||
|
||||
prom_printf("SNI IDProm dump (first 128byte):\n");
|
||||
for(i=0;i<128;i++) {
|
||||
prom_printf("SNI IDProm dump:\n");
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (i%16 == 0)
|
||||
prom_printf("%04x ", i);
|
||||
|
||||
prom_printf("%02x ", *(unsigned char *) (SNI_IDPROM_BASE+i));
|
||||
prom_printf("%02x ", *(unsigned char *) (SNI_IDPROM_BASE + i));
|
||||
|
||||
if (i%16 == 15)
|
||||
if (i % 16 == 15)
|
||||
prom_printf("\n");
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +119,7 @@ static void sni_mem_init(void )
|
|||
} memconf[8];
|
||||
|
||||
/* MemSIZE from prom in 16MByte chunks */
|
||||
memsize=*((unsigned char *) SNI_IDPROM_MEMSIZE) * 16;
|
||||
memsize = *((unsigned char *) SNI_IDPROM_MEMSIZE) * 16;
|
||||
|
||||
DBG_PRINTF("IDProm memsize: %lu MByte\n", memsize);
|
||||
|
||||
|
@ -126,26 +127,134 @@ static void sni_mem_init(void )
|
|||
__prom_get_memconf(&memconf);
|
||||
|
||||
DBG_PRINTF("prom_get_mem_conf memory configuration:\n");
|
||||
for(i=0;i<8 && memconf[i].size;i++) {
|
||||
prom_printf("Bank%d: %08x @ %08x\n", i,
|
||||
for (i = 0;i < 8 && memconf[i].size; i++) {
|
||||
if (sni_brd_type == SNI_BRD_PCI_TOWER ||
|
||||
sni_brd_type == SNI_BRD_PCI_TOWER_CPLUS) {
|
||||
if (memconf[i].base >= 0x20000000 &&
|
||||
memconf[i].base < 0x30000000) {
|
||||
memconf[i].base -= 0x20000000;
|
||||
}
|
||||
}
|
||||
DBG_PRINTF("Bank%d: %08x @ %08x\n", i,
|
||||
memconf[i].size, memconf[i].base);
|
||||
add_memory_region(memconf[i].base, memconf[i].size, BOOT_MEM_RAM);
|
||||
}
|
||||
}
|
||||
|
||||
static void __init sni_console_setup(void)
|
||||
{
|
||||
char *ctype;
|
||||
char *cdev;
|
||||
char *baud;
|
||||
int port;
|
||||
static char options[8];
|
||||
|
||||
cdev = prom_getenv ("console_dev");
|
||||
if (strncmp (cdev, "tty", 3) == 0) {
|
||||
ctype = prom_getenv ("console");
|
||||
switch (*ctype) {
|
||||
default:
|
||||
case 'l':
|
||||
port = 0;
|
||||
baud = prom_getenv("lbaud");
|
||||
break;
|
||||
case 'r':
|
||||
port = 1;
|
||||
baud = prom_getenv("rbaud");
|
||||
break;
|
||||
}
|
||||
if (baud)
|
||||
strcpy(options, baud);
|
||||
add_preferred_console("ttyS", port, baud ? options : NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void __init prom_init(void)
|
||||
{
|
||||
int argc = fw_arg0;
|
||||
char **argv = (void *)fw_arg1;
|
||||
unsigned int sni_brd_type = *(unsigned char *) SNI_IDPROM_BRDTYPE;
|
||||
int i;
|
||||
int cputype;
|
||||
|
||||
DBG_PRINTF("Found SNI brdtype %02x\n", sni_brd_type);
|
||||
sni_brd_type = *(unsigned char *)SNI_IDPROM_BRDTYPE;
|
||||
cputype = *(unsigned char *)SNI_IDPROM_CPUTYPE;
|
||||
switch (sni_brd_type) {
|
||||
case SNI_BRD_TOWER_OASIC:
|
||||
switch (cputype) {
|
||||
case SNI_CPU_M8030:
|
||||
systype = "RM400-330";
|
||||
break;
|
||||
case SNI_CPU_M8031:
|
||||
systype = "RM400-430";
|
||||
break;
|
||||
case SNI_CPU_M8037:
|
||||
systype = "RM400-530";
|
||||
break;
|
||||
case SNI_CPU_M8034:
|
||||
systype = "RM400-730";
|
||||
break;
|
||||
default:
|
||||
systype = "RM400-xxx";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SNI_BRD_MINITOWER:
|
||||
switch (cputype) {
|
||||
case SNI_CPU_M8021:
|
||||
case SNI_CPU_M8043:
|
||||
systype = "RM400-120";
|
||||
break;
|
||||
case SNI_CPU_M8040:
|
||||
systype = "RM400-220";
|
||||
break;
|
||||
case SNI_CPU_M8053:
|
||||
systype = "RM400-225";
|
||||
break;
|
||||
case SNI_CPU_M8050:
|
||||
systype = "RM400-420";
|
||||
break;
|
||||
default:
|
||||
systype = "RM400-xxx";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SNI_BRD_PCI_TOWER:
|
||||
systype = "RM400-Cxx";
|
||||
break;
|
||||
case SNI_BRD_RM200:
|
||||
systype = "RM200-xxx";
|
||||
break;
|
||||
case SNI_BRD_PCI_MTOWER:
|
||||
systype = "RM300-Cxx";
|
||||
break;
|
||||
case SNI_BRD_PCI_DESKTOP:
|
||||
switch (read_c0_prid() & 0xff00) {
|
||||
case PRID_IMP_R4600:
|
||||
case PRID_IMP_R4700:
|
||||
systype = "RM200-C20";
|
||||
break;
|
||||
case PRID_IMP_R5000:
|
||||
systype = "RM200-C40";
|
||||
break;
|
||||
default:
|
||||
systype = "RM200-Cxx";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SNI_BRD_PCI_TOWER_CPLUS:
|
||||
systype = "RM400-Exx";
|
||||
break;
|
||||
case SNI_BRD_PCI_MTOWER_CPLUS:
|
||||
systype = "RM300-Exx";
|
||||
break;
|
||||
}
|
||||
DBG_PRINTF("Found SNI brdtype %02x name %s\n", sni_brd_type,systype);
|
||||
|
||||
#ifdef DEBUG
|
||||
sni_idprom_dump();
|
||||
#endif
|
||||
sni_mem_init();
|
||||
sni_console_setup();
|
||||
|
||||
/* copy prom cmdline parameters to kernel cmdline */
|
||||
for (i = 1; i < argc; i++) {
|
||||
|
|
148
arch/mips/sni/time.c
Normal file
148
arch/mips/sni/time.c
Normal file
|
@ -0,0 +1,148 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/time.h>
|
||||
|
||||
#include <asm/sni.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
#define SNI_CLOCK_TICK_RATE 3686400
|
||||
#define SNI_COUNTER2_DIV 64
|
||||
#define SNI_COUNTER0_DIV ((SNI_CLOCK_TICK_RATE / SNI_COUNTER2_DIV) / HZ)
|
||||
|
||||
static void sni_a20r_timer_ack(void)
|
||||
{
|
||||
*(volatile u8 *)A20R_PT_TIM0_ACK = 0x0; wmb();
|
||||
}
|
||||
|
||||
/*
|
||||
* a20r platform uses 2 counters to divide the input frequency.
|
||||
* Counter 2 output is connected to Counter 0 & 1 input.
|
||||
*/
|
||||
static void __init sni_a20r_timer_setup(struct irqaction *irq)
|
||||
{
|
||||
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0x34; wmb();
|
||||
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = (SNI_COUNTER0_DIV) & 0xff; wmb();
|
||||
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = (SNI_COUNTER0_DIV >> 8) & 0xff; wmb();
|
||||
|
||||
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0xb4; wmb();
|
||||
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = (SNI_COUNTER2_DIV) & 0xff; wmb();
|
||||
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = (SNI_COUNTER2_DIV >> 8) & 0xff; wmb();
|
||||
|
||||
setup_irq(SNI_A20R_IRQ_TIMER, irq);
|
||||
mips_timer_ack = sni_a20r_timer_ack;
|
||||
}
|
||||
|
||||
#define SNI_8254_TICK_RATE 1193182UL
|
||||
|
||||
#define SNI_8254_TCSAMP_COUNTER ((SNI_8254_TICK_RATE / HZ) + 255)
|
||||
|
||||
static __init unsigned long dosample(void)
|
||||
{
|
||||
u32 ct0, ct1;
|
||||
volatile u8 msb, lsb;
|
||||
|
||||
/* Start the counter. */
|
||||
outb_p (0x34, 0x43);
|
||||
outb_p(SNI_8254_TCSAMP_COUNTER & 0xff, 0x40);
|
||||
outb (SNI_8254_TCSAMP_COUNTER >> 8, 0x40);
|
||||
|
||||
/* Get initial counter invariant */
|
||||
ct0 = read_c0_count();
|
||||
|
||||
/* Latch and spin until top byte of counter0 is zero */
|
||||
do {
|
||||
outb (0x00, 0x43);
|
||||
lsb = inb (0x40);
|
||||
msb = inb (0x40);
|
||||
ct1 = read_c0_count();
|
||||
} while (msb);
|
||||
|
||||
/* Stop the counter. */
|
||||
outb (0x38, 0x43);
|
||||
/*
|
||||
* Return the difference, this is how far the r4k counter increments
|
||||
* for every 1/HZ seconds. We round off the nearest 1 MHz of master
|
||||
* clock (= 1000000 / HZ / 2).
|
||||
*/
|
||||
/*return (ct1 - ct0 + (500000/HZ/2)) / (500000/HZ) * (500000/HZ);*/
|
||||
return (ct1 - ct0) / (500000/HZ) * (500000/HZ);
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we need to calibrate the cycle counter to at least be close.
|
||||
*/
|
||||
__init void sni_cpu_time_init(void)
|
||||
{
|
||||
unsigned long r4k_ticks[3];
|
||||
unsigned long r4k_tick;
|
||||
|
||||
/*
|
||||
* Figure out the r4k offset, the algorithm is very simple and works in
|
||||
* _all_ cases as long as the 8254 counter register itself works ok (as
|
||||
* an interrupt driving timer it does not because of bug, this is why
|
||||
* we are using the onchip r4k counter/compare register to serve this
|
||||
* purpose, but for r4k_offset calculation it will work ok for us).
|
||||
* There are other very complicated ways of performing this calculation
|
||||
* but this one works just fine so I am not going to futz around. ;-)
|
||||
*/
|
||||
printk(KERN_INFO "Calibrating system timer... ");
|
||||
dosample(); /* Prime cache. */
|
||||
dosample(); /* Prime cache. */
|
||||
/* Zero is NOT an option. */
|
||||
do {
|
||||
r4k_ticks[0] = dosample();
|
||||
} while (!r4k_ticks[0]);
|
||||
do {
|
||||
r4k_ticks[1] = dosample();
|
||||
} while (!r4k_ticks[1]);
|
||||
|
||||
if (r4k_ticks[0] != r4k_ticks[1]) {
|
||||
printk("warning: timer counts differ, retrying... ");
|
||||
r4k_ticks[2] = dosample();
|
||||
if (r4k_ticks[2] == r4k_ticks[0]
|
||||
|| r4k_ticks[2] == r4k_ticks[1])
|
||||
r4k_tick = r4k_ticks[2];
|
||||
else {
|
||||
printk("disagreement, using average... ");
|
||||
r4k_tick = (r4k_ticks[0] + r4k_ticks[1]
|
||||
+ r4k_ticks[2]) / 3;
|
||||
}
|
||||
} else
|
||||
r4k_tick = r4k_ticks[0];
|
||||
|
||||
printk("%d [%d.%04d MHz CPU]\n", (int) r4k_tick,
|
||||
(int) (r4k_tick / (500000 / HZ)),
|
||||
(int) (r4k_tick % (500000 / HZ)));
|
||||
|
||||
mips_hpt_frequency = r4k_tick * HZ;
|
||||
}
|
||||
|
||||
/*
|
||||
* R4k counter based timer interrupt. Works on RM200-225 and possibly
|
||||
* others but not on RM400
|
||||
*/
|
||||
static void __init sni_cpu_timer_setup(struct irqaction *irq)
|
||||
{
|
||||
setup_irq(SNI_MIPS_IRQ_CPU_TIMER, irq);
|
||||
}
|
||||
|
||||
void __init plat_timer_setup(struct irqaction *irq)
|
||||
{
|
||||
switch (sni_brd_type) {
|
||||
case SNI_BRD_10:
|
||||
case SNI_BRD_10NEW:
|
||||
case SNI_BRD_TOWER_OASIC:
|
||||
case SNI_BRD_MINITOWER:
|
||||
sni_a20r_timer_setup (irq);
|
||||
break;
|
||||
|
||||
case SNI_BRD_PCI_TOWER:
|
||||
case SNI_BRD_RM200:
|
||||
case SNI_BRD_PCI_MTOWER:
|
||||
case SNI_BRD_PCI_DESKTOP:
|
||||
case SNI_BRD_PCI_TOWER_CPLUS:
|
||||
case SNI_BRD_PCI_MTOWER_CPLUS:
|
||||
sni_cpu_timer_setup (irq);
|
||||
break;
|
||||
}
|
||||
}
|
31
include/asm-mips/ds1216.h
Normal file
31
include/asm-mips/ds1216.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef _DS1216_H
|
||||
#define _DS1216_H
|
||||
|
||||
extern volatile unsigned char *ds1216_base;
|
||||
unsigned long ds1216_get_cmos_time(void);
|
||||
int ds1216_set_rtc_mmss(unsigned long nowtime);
|
||||
|
||||
#define DS1216_SEC_BYTE 1
|
||||
#define DS1216_MIN_BYTE 2
|
||||
#define DS1216_HOUR_BYTE 3
|
||||
#define DS1216_HOUR_MASK (0x1f)
|
||||
#define DS1216_AMPM_MASK (1<<5)
|
||||
#define DS1216_1224_MASK (1<<7)
|
||||
#define DS1216_DAY_BYTE 4
|
||||
#define DS1216_DAY_MASK (0x7)
|
||||
#define DS1216_DATE_BYTE 5
|
||||
#define DS1216_DATE_MASK (0x3f)
|
||||
#define DS1216_MONTH_BYTE 6
|
||||
#define DS1216_MONTH_MASK (0x1f)
|
||||
#define DS1216_YEAR_BYTE 7
|
||||
|
||||
#define DS1216_SEC(buf) (buf[DS1216_SEC_BYTE])
|
||||
#define DS1216_MIN(buf) (buf[DS1216_MIN_BYTE])
|
||||
#define DS1216_HOUR(buf) (buf[DS1216_HOUR_BYTE] & DS1216_HOUR_MASK)
|
||||
#define DS1216_AMPM(buf) (buf[DS1216_HOUR_BYTE] & DS1216_AMPM_MASK)
|
||||
#define DS1216_1224(buf) (buf[DS1216_HOUR_BYTE] & DS1216_1224_MASK)
|
||||
#define DS1216_DATE(buf) (buf[DS1216_DATE_BYTE] & DS1216_DATE_MASK)
|
||||
#define DS1216_MONTH(buf) (buf[DS1216_MONTH_BYTE] & DS1216_MONTH_MASK)
|
||||
#define DS1216_YEAR(buf) (buf[DS1216_YEAR_BYTE])
|
||||
|
||||
#endif
|
|
@ -21,9 +21,7 @@
|
|||
#define cpu_has_watch 0
|
||||
#define cpu_has_mips16 0
|
||||
#define cpu_has_divec 0
|
||||
#define cpu_has_vce 0
|
||||
#define cpu_has_cache_cdex_p 1
|
||||
#define cpu_has_cache_cdex_s 0
|
||||
#define cpu_has_prefetch 0
|
||||
#define cpu_has_mcheck 0
|
||||
#define cpu_has_ejtag 0
|
||||
|
@ -35,9 +33,6 @@
|
|||
#define cpu_has_nofpuex 0
|
||||
#define cpu_has_64bits 1
|
||||
|
||||
#define cpu_dcache_line_size() 32
|
||||
#define cpu_icache_line_size() 32
|
||||
|
||||
#define cpu_has_mips32r1 0
|
||||
#define cpu_has_mips32r2 0
|
||||
#define cpu_has_mips64r1 0
|
||||
|
|
|
@ -6,12 +6,72 @@
|
|||
* for more details.
|
||||
*
|
||||
* Copyright (C) 1997, 1998 by Ralf Baechle
|
||||
* Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
|
||||
*/
|
||||
#ifndef __ASM_SNI_H
|
||||
#define __ASM_SNI_H
|
||||
|
||||
extern unsigned int sni_brd_type;
|
||||
|
||||
#define SNI_BRD_10 2
|
||||
#define SNI_BRD_10NEW 3
|
||||
#define SNI_BRD_TOWER_OASIC 4
|
||||
#define SNI_BRD_MINITOWER 5
|
||||
#define SNI_BRD_PCI_TOWER 6
|
||||
#define SNI_BRD_RM200 7
|
||||
#define SNI_BRD_PCI_MTOWER 8
|
||||
#define SNI_BRD_PCI_DESKTOP 9
|
||||
#define SNI_BRD_PCI_TOWER_CPLUS 10
|
||||
#define SNI_BRD_PCI_MTOWER_CPLUS 11
|
||||
|
||||
/* RM400 cpu types */
|
||||
#define SNI_CPU_M8021 0x01
|
||||
#define SNI_CPU_M8030 0x04
|
||||
#define SNI_CPU_M8031 0x06
|
||||
#define SNI_CPU_M8034 0x0f
|
||||
#define SNI_CPU_M8037 0x07
|
||||
#define SNI_CPU_M8040 0x05
|
||||
#define SNI_CPU_M8043 0x09
|
||||
#define SNI_CPU_M8050 0x0b
|
||||
#define SNI_CPU_M8053 0x0d
|
||||
|
||||
#define SNI_PORT_BASE 0xb4000000
|
||||
|
||||
#ifndef __MIPSEL__
|
||||
/*
|
||||
* ASIC PCI registers for big endian configuration.
|
||||
*/
|
||||
#define PCIMT_UCONF 0xbfff0004
|
||||
#define PCIMT_IOADTIMEOUT2 0xbfff000c
|
||||
#define PCIMT_IOMEMCONF 0xbfff0014
|
||||
#define PCIMT_IOMMU 0xbfff001c
|
||||
#define PCIMT_IOADTIMEOUT1 0xbfff0024
|
||||
#define PCIMT_DMAACCESS 0xbfff002c
|
||||
#define PCIMT_DMAHIT 0xbfff0034
|
||||
#define PCIMT_ERRSTATUS 0xbfff003c
|
||||
#define PCIMT_ERRADDR 0xbfff0044
|
||||
#define PCIMT_SYNDROME 0xbfff004c
|
||||
#define PCIMT_ITPEND 0xbfff0054
|
||||
#define IT_INT2 0x01
|
||||
#define IT_INTD 0x02
|
||||
#define IT_INTC 0x04
|
||||
#define IT_INTB 0x08
|
||||
#define IT_INTA 0x10
|
||||
#define IT_EISA 0x20
|
||||
#define IT_SCSI 0x40
|
||||
#define IT_ETH 0x80
|
||||
#define PCIMT_IRQSEL 0xbfff005c
|
||||
#define PCIMT_TESTMEM 0xbfff0064
|
||||
#define PCIMT_ECCREG 0xbfff006c
|
||||
#define PCIMT_CONFIG_ADDRESS 0xbfff0074
|
||||
#define PCIMT_ASIC_ID 0xbfff007c /* read */
|
||||
#define PCIMT_SOFT_RESET 0xbfff007c /* write */
|
||||
#define PCIMT_PIA_OE 0xbfff0084
|
||||
#define PCIMT_PIA_DATAOUT 0xbfff008c
|
||||
#define PCIMT_PIA_DATAIN 0xbfff0094
|
||||
#define PCIMT_CACHECONF 0xbfff009c
|
||||
#define PCIMT_INVSPACE 0xbfff00a4
|
||||
#else
|
||||
/*
|
||||
* ASIC PCI registers for little endian configuration.
|
||||
*/
|
||||
|
@ -45,6 +105,8 @@
|
|||
#define PCIMT_PIA_DATAIN 0xbfff0090
|
||||
#define PCIMT_CACHECONF 0xbfff0098
|
||||
#define PCIMT_INVSPACE 0xbfff00a0
|
||||
#endif
|
||||
|
||||
#define PCIMT_PCI_CONF 0xbfff0100
|
||||
|
||||
/*
|
||||
|
@ -72,6 +134,36 @@
|
|||
#define PCIMT_CSTIMER 0xbfde0000
|
||||
#define PCIMT_PWDN 0xbfdf0000
|
||||
|
||||
/*
|
||||
* A20R based boards
|
||||
*/
|
||||
#define A20R_PT_CLOCK_BASE 0xbc040000
|
||||
#define A20R_PT_TIM0_ACK 0xbc050000
|
||||
#define A20R_PT_TIM1_ACK 0xbc060000
|
||||
|
||||
#define SNI_MIPS_IRQ_CPU_BASE 16
|
||||
#define SNI_MIPS_IRQ_CPU_TIMER (SNI_MIPS_IRQ_CPU_BASE+7)
|
||||
|
||||
#define SNI_A20R_IRQ_BASE SNI_MIPS_IRQ_CPU_BASE
|
||||
#define SNI_A20R_IRQ_TIMER (SNI_A20R_IRQ_BASE+5)
|
||||
|
||||
#define SNI_DS1216_A20R_BASE 0xbc081ffc
|
||||
#define SNI_DS1216_RM200_BASE 0xbcd41ffc
|
||||
|
||||
#define SNI_PCIT_INT_REG 0xbfff000c
|
||||
|
||||
#define SNI_PCIT_INT_START 24
|
||||
#define SNI_PCIT_INT_END 30
|
||||
|
||||
#define PCIT_IRQ_ETHERNET (SNI_MIPS_IRQ_CPU_BASE + 5)
|
||||
#define PCIT_IRQ_INTA (SNI_PCIT_INT_START + 0)
|
||||
#define PCIT_IRQ_INTB (SNI_PCIT_INT_START + 1)
|
||||
#define PCIT_IRQ_INTC (SNI_PCIT_INT_START + 2)
|
||||
#define PCIT_IRQ_INTD (SNI_PCIT_INT_START + 3)
|
||||
#define PCIT_IRQ_SCSI0 (SNI_PCIT_INT_START + 4)
|
||||
#define PCIT_IRQ_SCSI1 (SNI_PCIT_INT_START + 5)
|
||||
|
||||
|
||||
/*
|
||||
* Interrupt 0-16 are EISA interrupts. Interrupts from 16 on are assigned
|
||||
* to the other interrupts generated by ASIC PCI.
|
||||
|
@ -80,18 +172,22 @@
|
|||
* ASIC PCI interrupt.
|
||||
*/
|
||||
#define PCIMT_KEYBOARD_IRQ 1
|
||||
#define PCIMT_IRQ_INT2 16
|
||||
#define PCIMT_IRQ_INTD 17
|
||||
#define PCIMT_IRQ_INTC 18
|
||||
#define PCIMT_IRQ_INTB 19
|
||||
#define PCIMT_IRQ_INTA 20
|
||||
#define PCIMT_IRQ_EISA 21
|
||||
#define PCIMT_IRQ_SCSI 22
|
||||
#define PCIMT_IRQ_ETHERNET 23
|
||||
#define PCIMT_IRQ_INT2 24
|
||||
#define PCIMT_IRQ_INTD 25
|
||||
#define PCIMT_IRQ_INTC 26
|
||||
#define PCIMT_IRQ_INTB 27
|
||||
#define PCIMT_IRQ_INTA 28
|
||||
#define PCIMT_IRQ_EISA 29
|
||||
#define PCIMT_IRQ_SCSI 30
|
||||
|
||||
#define PCIMT_IRQ_ETHERNET (SNI_MIPS_IRQ_CPU_BASE+6)
|
||||
|
||||
#if 0
|
||||
#define PCIMT_IRQ_TEMPERATURE 24
|
||||
#define PCIMT_IRQ_EISA_NMI 25
|
||||
#define PCIMT_IRQ_POWER_OFF 26
|
||||
#define PCIMT_IRQ_BUTTON 27
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Base address for the mapped 16mb EISA bus segment.
|
||||
|
@ -101,4 +197,24 @@
|
|||
/* PCI EISA Interrupt acknowledge */
|
||||
#define PCIMT_INT_ACKNOWLEDGE 0xba000000
|
||||
|
||||
/* board specific init functions */
|
||||
extern void sni_a20r_init (void);
|
||||
extern void sni_pcit_init (void);
|
||||
extern void sni_rm200_init (void);
|
||||
extern void sni_pcimt_init (void);
|
||||
|
||||
/* board specific irq init functions */
|
||||
extern void sni_a20r_irq_init (void);
|
||||
extern void sni_pcit_irq_init (void);
|
||||
extern void sni_pcit_cplus_irq_init (void);
|
||||
extern void sni_rm200_irq_init (void);
|
||||
extern void sni_pcimt_irq_init (void);
|
||||
|
||||
/* timer inits */
|
||||
extern void sni_cpu_time_init(void);
|
||||
|
||||
/* common irq stuff */
|
||||
extern void (*sni_hwint)(void);
|
||||
extern struct irqaction sni_isa_irq;
|
||||
|
||||
#endif /* __ASM_SNI_H */
|
||||
|
|
Loading…
Reference in a new issue