Commit d249e539 authored by Paul Mundt's avatar Paul Mundt Committed by Linus Torvalds

[PATCH] Move SH board-specific code around

This patch moves the old board-specific SH code
parent 47050253
#
# Makefile for ADX boards
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := mach.o setup.o io.o irq.o irq_maskreq.o
...@@ -173,6 +173,7 @@ void adx_iounmap(void *addr) ...@@ -173,6 +173,7 @@ void adx_iounmap(void *addr)
EXPORT_SYMBOL(adx_iounmap); EXPORT_SYMBOL(adx_iounmap);
#ifdef CONFIG_IDE
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
extern void *cf_io_base; extern void *cf_io_base;
...@@ -190,3 +191,5 @@ unsigned long adx_isa_port2addr(unsigned long offset) ...@@ -190,3 +191,5 @@ unsigned long adx_isa_port2addr(unsigned long offset)
return offset + 0xb0000000; /* IOBUS (AREA 4)*/ return offset + 0xb0000000; /* IOBUS (AREA 4)*/
} }
#endif
/*
* linux/arch/sh/boards/adx/irq.c
*
* Copyright (C) 2001 A&D Co., Ltd.
*
* I/O routine and setup routines for A&D ADX Board
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
*/
#include <asm/irq.h>
void init_adx_IRQ(void)
{
int i;
/* printk("init_adx_IRQ()\n");*/
/* setup irq_mask_register */
irq_mask_register = (unsigned short *)0xa6000008;
/* cover all external interrupt area by maskreg_irq_type
* (Actually, irq15 doesn't exist)
*/
for (i = 0; i < 16; i++) {
make_maskreg_irq(i);
disable_irq(i);
}
}
...@@ -65,11 +65,11 @@ static void disable_maskreg_irq(unsigned int irq) ...@@ -65,11 +65,11 @@ static void disable_maskreg_irq(unsigned int irq)
unsigned short val, mask = 0x01 << irq; unsigned short val, mask = 0x01 << irq;
/* Set "irq"th bit */ /* Set "irq"th bit */
save_and_cli(flags); local_irq_save(flags);
val = ctrl_inw((unsigned long)irq_mask_register); val = ctrl_inw((unsigned long)irq_mask_register);
val |= mask; val |= mask;
ctrl_outw(val, (unsigned long)irq_mask_register); ctrl_outw(val, (unsigned long)irq_mask_register);
restore_flags(flags); local_irq_restore(flags);
} }
} }
...@@ -80,11 +80,11 @@ static void enable_maskreg_irq(unsigned int irq) ...@@ -80,11 +80,11 @@ static void enable_maskreg_irq(unsigned int irq)
unsigned short val, mask = ~(0x01 << irq); unsigned short val, mask = ~(0x01 << irq);
/* Clear "irq"th bit */ /* Clear "irq"th bit */
save_and_cli(flags); local_irq_save(flags);
val = ctrl_inw((unsigned long)irq_mask_register); val = ctrl_inw((unsigned long)irq_mask_register);
val &= mask; val &= mask;
ctrl_outw(val, (unsigned long)irq_mask_register); ctrl_outw(val, (unsigned long)irq_mask_register);
restore_flags(flags); local_irq_restore(flags);
} }
} }
......
...@@ -15,9 +15,8 @@ ...@@ -15,9 +15,8 @@
#include <asm/machvec.h> #include <asm/machvec.h>
#include <asm/rtc.h> #include <asm/rtc.h>
#include <asm/machvec_init.h> #include <asm/machvec_init.h>
#include <asm/io_adx.h> #include <asm/adx/io.h>
extern void setup_adx(void);
extern void init_adx_IRQ(void); extern void init_adx_IRQ(void);
/* /*
...@@ -25,49 +24,43 @@ extern void init_adx_IRQ(void); ...@@ -25,49 +24,43 @@ extern void init_adx_IRQ(void);
*/ */
struct sh_machine_vector mv_adx __initmv = { struct sh_machine_vector mv_adx __initmv = {
.mv_name = "A&D_ADX", mv_nr_irqs: 48,
.mv_nr_irqs = 48, mv_inb: adx_inb,
mv_inw: adx_inw,
mv_inl: adx_inl,
mv_outb: adx_outb,
mv_outw: adx_outw,
mv_outl: adx_outl,
.mv_inb = adx_inb, mv_inb_p: adx_inb_p,
.mv_inw = adx_inw, mv_inw_p: adx_inw,
.mv_inl = adx_inl, mv_inl_p: adx_inl,
.mv_outb = adx_outb, mv_outb_p: adx_outb_p,
.mv_outw = adx_outw, mv_outw_p: adx_outw,
.mv_outl = adx_outl, mv_outl_p: adx_outl,
.mv_inb_p = adx_inb_p, mv_insb: adx_insb,
.mv_inw_p = adx_inw, mv_insw: adx_insw,
.mv_inl_p = adx_inl, mv_insl: adx_insl,
.mv_outb_p = adx_outb_p, mv_outsb: adx_outsb,
.mv_outw_p = adx_outw, mv_outsw: adx_outsw,
.mv_outl_p = adx_outl, mv_outsl: adx_outsl,
.mv_insb = adx_insb, mv_readb: adx_readb,
.mv_insw = adx_insw, mv_readw: adx_readw,
.mv_insl = adx_insl, mv_readl: adx_readl,
.mv_outsb = adx_outsb, mv_writeb: adx_writeb,
.mv_outsw = adx_outsw, mv_writew: adx_writew,
.mv_outsl = adx_outsl, mv_writel: adx_writel,
.mv_readb = adx_readb, mv_ioremap: adx_ioremap,
.mv_readw = adx_readw, mv_iounmap: adx_iounmap,
.mv_readl = adx_readl,
.mv_writeb = adx_writeb,
.mv_writew = adx_writew,
.mv_writel = adx_writel,
.mv_ioremap = adx_ioremap, mv_isa_port2addr: adx_isa_port2addr,
.mv_iounmap = adx_iounmap,
.mv_isa_port2addr = adx_isa_port2addr, mv_init_irq: init_adx_IRQ,
.mv_init_arch = setup_adx, mv_hw_adx: 1,
.mv_init_irq = init_adx_IRQ,
.mv_rtc_gettimeofday = sh_rtc_gettimeofday,
.mv_rtc_settimeofday = sh_rtc_settimeofday,
.mv_hw_adx = 1,
}; };
ALIAS_MV(adx) ALIAS_MV(adx)
/* /*
* linux/arch/sh/kernel/setup_adx.c * linux/arch/sh/board/adx/setup.c
* *
* Copyright (C) 2001 A&D Co., Ltd. * Copyright (C) 2001 A&D Co., Ltd.
* *
...@@ -11,30 +11,14 @@ ...@@ -11,30 +11,14 @@
* *
*/ */
#include <asm/io.h>
#include <asm/machvec.h> #include <asm/machvec.h>
#include <asm/irq.h>
#include <linux/module.h> #include <linux/module.h>
void setup_adx(void) const char *get_system_type(void)
{ {
/* nothing to do just yet */ return "A&D ADX";
/* printk("setup_adx()\n");*/
} }
void init_adx_IRQ(void) void platform_setup(void)
{ {
int i;
/* printk("init_adx_IRQ()\n");*/
/* setup irq_mask_register */
irq_mask_register = (unsigned short *)0xa6000008;
/* cover all external interrupt area by maskreg_irq_type
* (Actually, irq15 doesn't exist)
*/
for (i = 0; i < 16; i++) {
make_maskreg_irq(i);
disable_irq(i);
}
} }
#
# Makefile for the BigSur specific parts of the kernel
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := mach.o setup.o io.o irq.o led.o
obj-$(CONFIG_PCI) += pci.o
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <asm/machvec.h> #include <asm/machvec.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/bigsur.h> #include <asm/bigsur/bigsur.h>
//#define BIGSUR_DEBUG 2 //#define BIGSUR_DEBUG 2
#undef BIGSUR_DEBUG #undef BIGSUR_DEBUG
......
This diff is collapsed.
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/bigsur.h> #include <asm/bigsur/bigsur.h>
static void mach_led(int position, int value) static void mach_led(int position, int value)
{ {
......
...@@ -18,60 +18,55 @@ ...@@ -18,60 +18,55 @@
#include <asm/rtc.h> #include <asm/rtc.h>
#include <asm/machvec_init.h> #include <asm/machvec_init.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/io_bigsur.h> #include <asm/bigsur/io.h>
#include <asm/irq.h> #include <asm/irq.h>
/* /*
* The Machine Vector * The Machine Vector
*/ */
extern void heartbeat_bigsur(void); extern void heartbeat_bigsur(void);
extern void setup_bigsur(void);
extern void init_bigsur_IRQ(void); extern void init_bigsur_IRQ(void);
struct sh_machine_vector mv_bigsur __initmv = { struct sh_machine_vector mv_bigsur __initmv = {
.mv_name = "Big Sur", mv_nr_irqs: NR_IRQS, // Defined in <asm/irq.h>
.mv_nr_irqs = NR_IRQS, // Defined in <asm/irq.h> mv_inb: bigsur_inb,
.mv_inb = bigsur_inb, mv_inw: bigsur_inw,
.mv_inw = bigsur_inw, mv_inl: bigsur_inl,
.mv_inl = bigsur_inl, mv_outb: bigsur_outb,
.mv_outb = bigsur_outb, mv_outw: bigsur_outw,
.mv_outw = bigsur_outw, mv_outl: bigsur_outl,
.mv_outl = bigsur_outl,
.mv_inb_p = bigsur_inb_p, mv_inb_p: bigsur_inb_p,
.mv_inw_p = bigsur_inw, mv_inw_p: bigsur_inw,
.mv_inl_p = bigsur_inl, mv_inl_p: bigsur_inl,
.mv_outb_p = bigsur_outb_p, mv_outb_p: bigsur_outb_p,
.mv_outw_p = bigsur_outw, mv_outw_p: bigsur_outw,
.mv_outl_p = bigsur_outl, mv_outl_p: bigsur_outl,
.mv_insb = bigsur_insb, mv_insb: bigsur_insb,
.mv_insw = bigsur_insw, mv_insw: bigsur_insw,
.mv_insl = bigsur_insl, mv_insl: bigsur_insl,
.mv_outsb = bigsur_outsb, mv_outsb: bigsur_outsb,
.mv_outsw = bigsur_outsw, mv_outsw: bigsur_outsw,
.mv_outsl = bigsur_outsl, mv_outsl: bigsur_outsl,
.mv_readb = generic_readb, mv_readb: generic_readb,
.mv_readw = generic_readw, mv_readw: generic_readw,
.mv_readl = generic_readl, mv_readl: generic_readl,
.mv_writeb = generic_writeb, mv_writeb: generic_writeb,
.mv_writew = generic_writew, mv_writew: generic_writew,
.mv_writel = generic_writel, mv_writel: generic_writel,
.mv_ioremap = generic_ioremap, mv_ioremap: generic_ioremap,
.mv_iounmap = generic_iounmap, mv_iounmap: generic_iounmap,
.mv_isa_port2addr = bigsur_isa_port2addr, mv_isa_port2addr: bigsur_isa_port2addr,
.mv_irq_demux = bigsur_irq_demux, mv_irq_demux: bigsur_irq_demux,
.mv_init_arch = setup_bigsur, mv_init_irq: init_bigsur_IRQ,
.mv_init_irq = init_bigsur_IRQ,
#ifdef CONFIG_HEARTBEAT #ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_bigsur, mv_heartbeat: heartbeat_bigsur,
#endif #endif
.mv_rtc_gettimeofday = sh_rtc_gettimeofday,
.mv_rtc_settimeofday = sh_rtc_settimeofday,
}; };
ALIAS_MV(bigsur) ALIAS_MV(bigsur)
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/pci-sh7751.h> #include <asm/pci-sh7751.h>
#include <asm/bigsur.h> #include <asm/bigsur/bigsur.h>
#define PCI_REG(reg) (SH7751_PCIREG_BASE+reg) #define PCI_REG(reg) (SH7751_PCIREG_BASE+reg)
......
/*
*
* By Dustin McIntire (dustin@sensoria.com) (c)2001
*
* Setup and IRQ handling code for the HD64465 companion chip.
* by Greg Banks <gbanks@pocketpenguins.com>
* Copyright (c) 2000 PocketPenguins Inc
*
* Derived from setup_hd64465.c which bore the message:
* Greg Banks <gbanks@pocketpenguins.com>
* Copyright (c) 2000 PocketPenguins Inc and
* Copyright (C) 2000 YAEGASHI Takeshi
* and setup_cqreek.c which bore message:
* Copyright (C) 2000 Niibe Yutaka
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Setup functions for a Hitachi Big Sur Evaluation Board.
*
*/
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/bitops.h>
#include <asm/bigsur/io.h>
#include <asm/hd64465/hd64465.h>
#include <asm/bigsur/bigsur.h>
//#define BIGSUR_DEBUG 3
#undef BIGSUR_DEBUG
#ifdef BIGSUR_DEBUG
#define DPRINTK(args...) printk(args)
#define DIPRINTK(n, args...) if (BIGSUR_DEBUG>(n)) printk(args)
#else
#define DPRINTK(args...)
#define DIPRINTK(n, args...)
#endif /* BIGSUR_DEBUG */
/*===========================================================*/
// Big Sur Init Routines
/*===========================================================*/
const char *get_system_type(void)
{
return "Big Sur";
}
int __init platform_setup(void)
{
static int done = 0; /* run this only once */
if (!MACH_BIGSUR || done) return 0;
done = 1;
/* Mask all 2nd level IRQ's */
outb(-1,BIGSUR_IMR0);
outb(-1,BIGSUR_IMR1);
outb(-1,BIGSUR_IMR2);
outb(-1,BIGSUR_IMR3);
/* Mask 1st level interrupts */
outb(-1,BIGSUR_IRLMR0);
outb(-1,BIGSUR_IRLMR1);
#if defined (CONFIG_HD64465) && defined (CONFIG_SERIAL)
/* remap IO ports for first ISA serial port to HD64465 UART */
bigsur_port_map(0x3f8, 8, CONFIG_HD64465_IOBASE + 0x8000, 1);
#endif /* CONFIG_HD64465 && CONFIG_SERIAL */
/* TODO: setup IDE registers */
bigsur_port_map(BIGSUR_IDECTL_IOPORT, 2, BIGSUR_ICTL, 8);
/* Setup the Ethernet port to BIGSUR_ETHER_IOPORT */
bigsur_port_map(BIGSUR_ETHER_IOPORT, 16, BIGSUR_ETHR+BIGSUR_ETHER_IOPORT, 0);
/* set page to 1 */
outw(1, BIGSUR_ETHR+0xe);
/* set the IO port to BIGSUR_ETHER_IOPORT */
outw(BIGSUR_ETHER_IOPORT<<3, BIGSUR_ETHR+0x2);
return 0;
}
module_init(setup_bigsur);
#
# Makefile for the CAT-68701 specific parts of the kernel
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := mach.o setup.o io.o irq.o
/* /*
* linux/arch/sh/kernel/io_cat68701.c * linux/arch/sh/boards/cat68701/io.c
* *
* Copyright (C) 2000 Niibe Yutaka * Copyright (C) 2000 Niibe Yutaka
* 2001 Yutaro Ebihara * 2001 Yutaro Ebihara
* *
* I/O routine and setup routines for A-ONE Corp CAT-68701 SH7708 Board * I/O routines for A-ONE Corp CAT-68701 SH7708 Board
* *
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
...@@ -205,45 +205,3 @@ unsigned long cat68701_isa_port2addr(unsigned long offset) ...@@ -205,45 +205,3 @@ unsigned long cat68701_isa_port2addr(unsigned long offset)
return offset + 0xb4000000; /* other I/O (EREA 5)*/ return offset + 0xb4000000; /* other I/O (EREA 5)*/
} }
int cat68701_irq_demux(int irq)
{
if(irq==13) return 14;
if(irq==7) return 10;
return irq;
}
/*-------------------------------------------------------*/
void setup_cat68701(){
/* dummy read erea5 (CS8900A) */
}
void init_cat68701_IRQ(){
make_imask_irq(10);
make_imask_irq(14);
}
#ifdef CONFIG_HEARTBEAT
#include <linux/sched.h>
void heartbeat_cat68701()
{
static unsigned int cnt = 0, period = 0 , bit = 0;
cnt += 1;
if (cnt < period) {
return;
}
cnt = 0;
/* Go through the points (roughly!):
* f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
*/
period = 110 - ( (300<<FSHIFT)/
((avenrun[0]/5) + (3<<FSHIFT)) );
if(bit){ bit=0; }else{ bit=1; }
outw(bit<<15,0x3fe);
}
#endif /* CONFIG_HEARTBEAT */
/*
* linux/arch/sh/boards/cat68701/irq.c
*
* Copyright (C) 2000 Niibe Yutaka
* 2001 Yutaro Ebihara
*
* Setup routines for A-ONE Corp CAT-68701 SH7708 Board
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
*/
#include <asm/irq.h>
int cat68701_irq_demux(int irq)
{
if(irq==13) return 14;
if(irq==7) return 10;
return irq;
}
void init_cat68701_IRQ()
{
make_imask_irq(10);
make_imask_irq(14);
}
/* /*
* linux/arch/sh/kernel/mach_cat68701.c * linux/arch/sh/boards/cat68701/mach.c
* *
* Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
* 2001 Yutaro Ebihara (ebihara@si-linux.com) * 2001 Yutaro Ebihara (ebihara@si-linux.com)
...@@ -16,57 +16,51 @@ ...@@ -16,57 +16,51 @@
#include <asm/machvec.h> #include <asm/machvec.h>
#include <asm/rtc.h> #include <asm/rtc.h>
#include <asm/machvec_init.h> #include <asm/machvec_init.h>
#include <asm/io_cat68701.h> #include <asm/cat68701/io.h>
/* /*
* The Machine Vector * The Machine Vector
*/ */
struct sh_machine_vector mv_cat68701 __initmv = { struct sh_machine_vector mv_cat68701 __initmv = {
.mv_name = "CAT-68701", mv_nr_irqs: 32,
.mv_nr_irqs = 32, mv_inb: cat68701_inb,
.mv_inb = cat68701_inb, mv_inw: cat68701_inw,
.mv_inw = cat68701_inw, mv_inl: cat68701_inl,
.mv_inl = cat68701_inl, mv_outb: cat68701_outb,
.mv_outb = cat68701_outb, mv_outw: cat68701_outw,
.mv_outw = cat68701_outw, mv_outl: cat68701_outl,
.mv_outl = cat68701_outl,
.mv_inb_p = cat68701_inb_p, mv_inb_p: cat68701_inb_p,
.mv_inw_p = cat68701_inw, mv_inw_p: cat68701_inw,
.mv_inl_p = cat68701_inl, mv_inl_p: cat68701_inl,
.mv_outb_p = cat68701_outb_p, mv_outb_p: cat68701_outb_p,
.mv_outw_p = cat68701_outw, mv_outw_p: cat68701_outw,
.mv_outl_p = cat68701_outl, mv_outl_p: cat68701_outl,
.mv_insb = cat68701_insb, mv_insb: cat68701_insb,
.mv_insw = cat68701_insw, mv_insw: cat68701_insw,
.mv_insl = cat68701_insl, mv_insl: cat68701_insl,
.mv_outsb = cat68701_outsb, mv_outsb: cat68701_outsb,
.mv_outsw = cat68701_outsw, mv_outsw: cat68701_outsw,
.mv_outsl = cat68701_outsl, mv_outsl: cat68701_outsl,
.mv_readb = cat68701_readb, mv_readb: cat68701_readb,
.mv_readw = cat68701_readw, mv_readw: cat68701_readw,
.mv_readl = cat68701_readl, mv_readl: cat68701_readl,
.mv_writeb = cat68701_writeb, mv_writeb: cat68701_writeb,
.mv_writew = cat68701_writew, mv_writew: cat68701_writew,
.mv_writel = cat68701_writel, mv_writel: cat68701_writel,
.mv_ioremap = cat68701_ioremap, mv_ioremap: cat68701_ioremap,
.mv_iounmap = cat68701_iounmap, mv_iounmap: cat68701_iounmap,
.mv_isa_port2addr = cat68701_isa_port2addr, mv_isa_port2addr: cat68701_isa_port2addr,
.mv_irq_demux = cat68701_irq_demux, mv_irq_demux: cat68701_irq_demux,
.mv_init_arch = setup_cat68701, mv_init_irq: init_cat68701_IRQ,
.mv_init_irq = init_cat68701_IRQ,
#ifdef CONFIG_HEARTBEAT #ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_cat68701, mv_heartbeat: heartbeat_cat68701,
#endif #endif
.mv_rtc_gettimeofday = sh_rtc_gettimeofday,
.mv_rtc_settimeofday = sh_rtc_settimeofday,
}; };
ALIAS_MV(cat68701) ALIAS_MV(cat68701)
/*
* linux/arch/sh/boards/cat68701/setup.c
*
* Copyright (C) 2000 Niibe Yutaka
* 2001 Yutaro Ebihara
*
* Setup routines for A-ONE Corp CAT-68701 SH7708 Board
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
*/
#include <asm/io.h>
#include <asm/machvec.h>
#include <linux/config.h>
#include <linux/module.h>
const char *get_system_type(void)
{
return "CAT-68701";
}
void platform_setup()
{
/* dummy read erea5 (CS8900A) */
}
#ifdef CONFIG_HEARTBEAT
#include <linux/sched.h>
void heartbeat_cat68701()
{
static unsigned int cnt = 0, period = 0 , bit = 0;
cnt += 1;
if (cnt < period) {
return;
}
cnt = 0;
/* Go through the points (roughly!):
* f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
*/
period = 110 - ( (300<<FSHIFT)/
((avenrun[0]/5) + (3<<FSHIFT)) );
if(bit){ bit=0; }else{ bit=1; }
outw(bit<<15,0x3fe);
}
#endif /* CONFIG_HEARTBEAT */
#
# Makefile for the CqREEK specific parts of the kernel
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := mach.o setup.o io.o irq.o
#define IDE_OFFSET 0xA4000000UL
#define ISA_OFFSET 0xA4A00000UL
unsigned long cqreek_port2addr(unsigned long port)
{
if (0x0000<=port && port<=0x0040)
return IDE_OFFSET + port;
if ((0x01f0<=port && port<=0x01f7) || port == 0x03f6)
return IDE_OFFSET + port;
return ISA_OFFSET + port;
}
/* $Id: setup_cqreek.c,v 1.9 2001/07/30 12:43:28 gniibe Exp $ /* $Id: irq.c,v 1.1.2.4 2002/11/04 20:33:56 lethal Exp $
* *
* arch/sh/kernel/setup_cqreek.c * arch/sh/boards/cqreek/irq.c
* *
* Copyright (C) 2000 Niibe Yutaka * Copyright (C) 2000 Niibe Yutaka
* *
...@@ -8,11 +8,10 @@ ...@@ -8,11 +8,10 @@
* *
*/ */
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/init.h>
#include <asm/cqreek/cqreek.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/io_generic.h> #include <asm/io_generic.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -20,31 +19,6 @@ ...@@ -20,31 +19,6 @@
#include <asm/machvec_init.h> #include <asm/machvec_init.h>
#include <asm/rtc.h> #include <asm/rtc.h>
#define BRIDGE_FEATURE 0x0002
#define BRIDGE_IDE_CTRL 0x0018
#define BRIDGE_IDE_INTR_LVL 0x001A
#define BRIDGE_IDE_INTR_MASK 0x001C
#define BRIDGE_IDE_INTR_STAT 0x001E
#define BRIDGE_ISA_CTRL 0x0028
#define BRIDGE_ISA_INTR_LVL 0x002A
#define BRIDGE_ISA_INTR_MASK 0x002C
#define BRIDGE_ISA_INTR_STAT 0x002E
#define IDE_OFFSET 0xA4000000UL
#define ISA_OFFSET 0xA4A00000UL
static unsigned long cqreek_port2addr(unsigned long port)
{
if (0x0000<=port && port<=0x0040)
return IDE_OFFSET + port;
if ((0x01f0<=port && port<=0x01f7) || port == 0x03f6)
return IDE_OFFSET + port;
return ISA_OFFSET + port;
}
struct cqreek_irq_data { struct cqreek_irq_data {
unsigned short mask_port; /* Port of Interrupt Mask Register */ unsigned short mask_port; /* Port of Interrupt Mask Register */
unsigned short stat_port; /* Port of Interrupt Status Register */ unsigned short stat_port; /* Port of Interrupt Status Register */
...@@ -59,11 +33,11 @@ static void disable_cqreek_irq(unsigned int irq) ...@@ -59,11 +33,11 @@ static void disable_cqreek_irq(unsigned int irq)
unsigned short mask_port = cqreek_irq_data[irq].mask_port; unsigned short mask_port = cqreek_irq_data[irq].mask_port;
unsigned short bit = cqreek_irq_data[irq].bit; unsigned short bit = cqreek_irq_data[irq].bit;
save_and_cli(flags); local_irq_save(flags);
/* Disable IRQ */ /* Disable IRQ */
mask = inw(mask_port) & ~bit; mask = inw(mask_port) & ~bit;
outw_p(mask, mask_port); outw_p(mask, mask_port);
restore_flags(flags); local_irq_restore(flags);
} }
static void enable_cqreek_irq(unsigned int irq) static void enable_cqreek_irq(unsigned int irq)
...@@ -73,11 +47,11 @@ static void enable_cqreek_irq(unsigned int irq) ...@@ -73,11 +47,11 @@ static void enable_cqreek_irq(unsigned int irq)
unsigned short mask_port = cqreek_irq_data[irq].mask_port; unsigned short mask_port = cqreek_irq_data[irq].mask_port;
unsigned short bit = cqreek_irq_data[irq].bit; unsigned short bit = cqreek_irq_data[irq].bit;
save_and_cli(flags); local_irq_save(flags);
/* Enable IRQ */ /* Enable IRQ */
mask = inw(mask_port) | bit; mask = inw(mask_port) | bit;
outw_p(mask, mask_port); outw_p(mask, mask_port);
restore_flags(flags); local_irq_restore(flags);
} }
static void mask_and_ack_cqreek(unsigned int irq) static void mask_and_ack_cqreek(unsigned int irq)
...@@ -118,13 +92,13 @@ static struct hw_interrupt_type cqreek_irq_type = { ...@@ -118,13 +92,13 @@ static struct hw_interrupt_type cqreek_irq_type = {
end_cqreek_irq end_cqreek_irq
}; };
static int has_ide, has_isa; int cqreek_has_ide, cqreek_has_isa;
/* XXX: This is just for test for my NE2000 ISA board /* XXX: This is just for test for my NE2000 ISA board
What we really need is virtualized IRQ and demultiplexer like HP600 port */ What we really need is virtualized IRQ and demultiplexer like HP600 port */
void __init init_cqreek_IRQ(void) void __init init_cqreek_IRQ(void)
{ {
if (has_ide) { if (cqreek_has_ide) {
cqreek_irq_data[14].mask_port = BRIDGE_IDE_INTR_MASK; cqreek_irq_data[14].mask_port = BRIDGE_IDE_INTR_MASK;
cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT; cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT;
cqreek_irq_data[14].bit = 1; cqreek_irq_data[14].bit = 1;
...@@ -137,7 +111,7 @@ void __init init_cqreek_IRQ(void) ...@@ -137,7 +111,7 @@ void __init init_cqreek_IRQ(void)
disable_cqreek_irq(14); disable_cqreek_irq(14);
} }
if (has_isa) { if (cqreek_has_isa) {
cqreek_irq_data[10].mask_port = BRIDGE_ISA_INTR_MASK; cqreek_irq_data[10].mask_port = BRIDGE_ISA_INTR_MASK;
cqreek_irq_data[10].stat_port = BRIDGE_ISA_INTR_STAT; cqreek_irq_data[10].stat_port = BRIDGE_ISA_INTR_STAT;
cqreek_irq_data[10].bit = (1 << 10); cqreek_irq_data[10].bit = (1 << 10);
...@@ -152,101 +126,3 @@ void __init init_cqreek_IRQ(void) ...@@ -152,101 +126,3 @@ void __init init_cqreek_IRQ(void)
} }
} }
/*
* Initialize the board
*/
void __init setup_cqreek(void)
{
int i;
/* udelay is not available at setup time yet... */
#define DELAY() do {for (i=0; i<10000; i++) ctrl_inw(0xa0000000);} while(0)
if ((inw (BRIDGE_FEATURE) & 1)) { /* We have IDE interface */
outw_p(0, BRIDGE_IDE_INTR_LVL);
outw_p(0, BRIDGE_IDE_INTR_MASK);
outw_p(0, BRIDGE_IDE_CTRL);
DELAY();
outw_p(0x8000, BRIDGE_IDE_CTRL);
DELAY();
outw_p(0xffff, BRIDGE_IDE_INTR_STAT); /* Clear interrupt status */
outw_p(0x0f-14, BRIDGE_IDE_INTR_LVL); /* Use 14 IPR */
outw_p(1, BRIDGE_IDE_INTR_MASK); /* Enable interrupt */
has_ide=1;
}
if ((inw (BRIDGE_FEATURE) & 2)) { /* We have ISA interface */
outw_p(0, BRIDGE_ISA_INTR_LVL);
outw_p(0, BRIDGE_ISA_INTR_MASK);
outw_p(0, BRIDGE_ISA_CTRL);
DELAY();
outw_p(0x8000, BRIDGE_ISA_CTRL);
DELAY();
outw_p(0xffff, BRIDGE_ISA_INTR_STAT); /* Clear interrupt status */
outw_p(0x0f-10, BRIDGE_ISA_INTR_LVL); /* Use 10 IPR */
outw_p(0xfff8, BRIDGE_ISA_INTR_MASK); /* Enable interrupt */
has_isa=1;
}
printk(KERN_INFO "CqREEK Setup (IDE=%d, ISA=%d)...done\n", has_ide, has_isa);
}
/*
* The Machine Vector
*/
struct sh_machine_vector mv_cqreek __initmv = {
.mv_name = "CqREEK",
#if defined(__SH4__)
.mv_nr_irqs = 48,
#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
.mv_nr_irqs = 32,
#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
.mv_nr_irqs = 61,
#endif
.mv_inb = generic_inb,
.mv_inw = generic_inw,
.mv_inl = generic_inl,
.mv_outb = generic_outb,
.mv_outw = generic_outw,
.mv_outl = generic_outl,
.mv_inb_p = generic_inb_p,
.mv_inw_p = generic_inw_p,
.mv_inl_p = generic_inl_p,
.mv_outb_p = generic_outb_p,
.mv_outw_p = generic_outw_p,
.mv_outl_p = generic_outl_p,
.mv_insb = generic_insb,
.mv_insw = generic_insw,
.mv_insl = generic_insl,
.mv_outsb = generic_outsb,
.mv_outsw = generic_outsw,
.mv_outsl = generic_outsl,
.mv_readb = generic_readb,
.mv_readw = generic_readw,
.mv_readl = generic_readl,
.mv_writeb = generic_writeb,
.mv_writew = generic_writew,
.mv_writel = generic_writel,
.mv_init_arch = setup_cqreek,
.mv_init_irq = init_cqreek_IRQ,
.mv_isa_port2addr = cqreek_port2addr,
.mv_ioremap = generic_ioremap,
.mv_iounmap = generic_iounmap,
.mv_rtc_gettimeofday = sh_rtc_gettimeofday,
.mv_rtc_settimeofday = sh_rtc_settimeofday,
};
ALIAS_MV(cqreek)
/* $Id: mach.c,v 1.1.2.4.2.1 2003/01/10 17:26:32 lethal Exp $
*
* arch/sh/kernel/setup_cqreek.c
*
* Copyright (C) 2000 Niibe Yutaka
*
* CqREEK IDE/ISA Bridge Support.
*
*/
#include <asm/rtc.h>
#include <asm/io.h>
#include <asm/io_generic.h>
#include <asm/machvec.h>
#include <asm/machvec_init.h>
#include <asm/cqreek/cqreek.h>
/*
* The Machine Vector
*/
struct sh_machine_vector mv_cqreek __initmv = {
#if defined(CONFIG_CPU_SH4)
mv_nr_irqs: 48,
#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
mv_nr_irqs: 32,
#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
mv_nr_irqs: 61,
#endif
mv_inb: generic_inb,
mv_inw: generic_inw,
mv_inl: generic_inl,
mv_outb: generic_outb,
mv_outw: generic_outw,
mv_outl: generic_outl,
mv_inb_p: generic_inb_p,
mv_inw_p: generic_inw_p,
mv_inl_p: generic_inl_p,
mv_outb_p: generic_outb_p,
mv_outw_p: generic_outw_p,
mv_outl_p: generic_outl_p,
mv_insb: generic_insb,
mv_insw: generic_insw,
mv_insl: generic_insl,
mv_outsb: generic_outsb,
mv_outsw: generic_outsw,
mv_outsl: generic_outsl,
mv_readb: generic_readb,
mv_readw: generic_readw,
mv_readl: generic_readl,
mv_writeb: generic_writeb,
mv_writew: generic_writew,
mv_writel: generic_writel,
mv_init_irq: init_cqreek_IRQ,
mv_isa_port2addr: cqreek_port2addr,
mv_ioremap: generic_ioremap,
mv_iounmap: generic_iounmap,
};
ALIAS_MV(cqreek)
/* $Id: setup.c,v 1.1.2.5 2002/03/02 21:57:07 lethal Exp $
*
* arch/sh/kernel/setup_cqreek.c
*
* Copyright (C) 2000 Niibe Yutaka
*
* CqREEK IDE/ISA Bridge Support.
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/cqreek/cqreek.h>
#include <asm/io.h>
#include <asm/io_generic.h>
#include <asm/irq.h>
#include <asm/rtc.h>
const char *get_system_type(void)
{
return "CqREEK";
}
/*
* Initialize the board
*/
void __init platform_setup(void)
{
int i;
/* udelay is not available at setup time yet... */
#define DELAY() do {for (i=0; i<10000; i++) ctrl_inw(0xa0000000);} while(0)
if ((inw (BRIDGE_FEATURE) & 1)) { /* We have IDE interface */
outw_p(0, BRIDGE_IDE_INTR_LVL);
outw_p(0, BRIDGE_IDE_INTR_MASK);
outw_p(0, BRIDGE_IDE_CTRL);
DELAY();
outw_p(0x8000, BRIDGE_IDE_CTRL);
DELAY();
outw_p(0xffff, BRIDGE_IDE_INTR_STAT); /* Clear interrupt status */
outw_p(0x0f-14, BRIDGE_IDE_INTR_LVL); /* Use 14 IPR */
outw_p(1, BRIDGE_IDE_INTR_MASK); /* Enable interrupt */
cqreek_has_ide=1;
}
if ((inw (BRIDGE_FEATURE) & 2)) { /* We have ISA interface */
outw_p(0, BRIDGE_ISA_INTR_LVL);
outw_p(0, BRIDGE_ISA_INTR_MASK);
outw_p(0, BRIDGE_ISA_CTRL);
DELAY();
outw_p(0x8000, BRIDGE_ISA_CTRL);
DELAY();
outw_p(0xffff, BRIDGE_ISA_INTR_STAT); /* Clear interrupt status */
outw_p(0x0f-10, BRIDGE_ISA_INTR_LVL); /* Use 10 IPR */
outw_p(0xfff8, BRIDGE_ISA_INTR_MASK); /* Enable interrupt */
cqreek_has_isa=1;
}
printk(KERN_INFO "CqREEK Setup (IDE=%d, ISA=%d)...done\n", cqreek_has_ide, cqreek_has_isa);
}
#
# Makefile for the DataMyte Industrial Digital Assistant(tm) specific parts
# of the kernel
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := mach.o
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include <asm/machvec_init.h> #include <asm/machvec_init.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/hd64465.h> #include <asm/hd64465/hd64465.h>
#include <asm/irq.h> #include <asm/irq.h>
/* /*
...@@ -30,44 +30,44 @@ ...@@ -30,44 +30,44 @@
*/ */
struct sh_machine_vector mv_dmida __initmv = { struct sh_machine_vector mv_dmida __initmv = {
.mv_name = "DMIDA", mv_name: "DMIDA",
.mv_nr_irqs = HD64465_IRQ_BASE+HD64465_IRQ_NUM, mv_nr_irqs: HD64465_IRQ_BASE+HD64465_IRQ_NUM,
.mv_inb = hd64465_inb, mv_inb: hd64465_inb,
.mv_inw = hd64465_inw, mv_inw: hd64465_inw,
.mv_inl = hd64465_inl, mv_inl: hd64465_inl,
.mv_outb = hd64465_outb, mv_outb: hd64465_outb,
.mv_outw = hd64465_outw, mv_outw: hd64465_outw,
.mv_outl = hd64465_outl, mv_outl: hd64465_outl,
.mv_inb_p = hd64465_inb_p, mv_inb_p: hd64465_inb_p,
.mv_inw_p = hd64465_inw, mv_inw_p: hd64465_inw,
.mv_inl_p = hd64465_inl, mv_inl_p: hd64465_inl,
.mv_outb_p = hd64465_outb_p, mv_outb_p: hd64465_outb_p,
.mv_outw_p = hd64465_outw, mv_outw_p: hd64465_outw,
.mv_outl_p = hd64465_outl, mv_outl_p: hd64465_outl,
.mv_insb = hd64465_insb, mv_insb: hd64465_insb,
.mv_insw = hd64465_insw, mv_insw: hd64465_insw,
.mv_insl = hd64465_insl, mv_insl: hd64465_insl,
.mv_outsb = hd64465_outsb, mv_outsb: hd64465_outsb,
.mv_outsw = hd64465_outsw, mv_outsw: hd64465_outsw,
.mv_outsl = hd64465_outsl, mv_outsl: hd64465_outsl,
.mv_readb = generic_readb, mv_readb: generic_readb,
.mv_readw = generic_readw, mv_readw: generic_readw,
.mv_readl = generic_readl, mv_readl: generic_readl,
.mv_writeb = generic_writeb, mv_writeb: generic_writeb,
.mv_writew = generic_writew, mv_writew: generic_writew,
.mv_writel = generic_writel, mv_writel: generic_writel,
.mv_irq_demux = hd64465_irq_demux, mv_irq_demux: hd64465_irq_demux,
.mv_rtc_gettimeofday = sh_rtc_gettimeofday, mv_rtc_gettimeofday: sh_rtc_gettimeofday,
.mv_rtc_settimeofday = sh_rtc_settimeofday, mv_rtc_settimeofday: sh_rtc_settimeofday,
.mv_hw_hd64465 = 1, mv_hw_hd64465: 1,
}; };
ALIAS_MV(dmida) ALIAS_MV(dmida)
#
# Makefile for the Sega Dreamcast specific parts of the kernel
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := mach.o setup.o io.o irq.o rtc.o
obj-$(CONFIG_PCI) += pci.o
/* /*
* $Id: io_dc.c,v 1.2 2001/05/24 00:13:47 gniibe Exp $ * $Id: io.c,v 1.1.2.1 2002/01/19 23:54:19 mrbrown Exp $
* I/O routines for SEGA Dreamcast * I/O routines for SEGA Dreamcast
*/ */
......
/* arch/sh/kernel/setup_dc.c /*
* arch/sh/boards/dreamcast/irq.c
* *
* Hardware support for the Sega Dreamcast. * Holly IRQ support for the Sega Dreamcast.
* *
* Copyright (c) 2001 M. R. Brown <mrbrown@linuxdc.org> * Copyright (c) 2001, 2002 M. R. Brown <mrbrown@0xd6.org>
* *
* This file is part of the LinuxDC project (www.linuxdc.org) * This file is part of the LinuxDC project (www.linuxdc.org)
* * Released under the terms of the GNU GPL v2.0
* Released under the terms of the GNU GPL v2.0.
*
* This file originally bore the message (with enclosed-$):
* Id: setup_dc.c,v 1.5 2001/05/24 05:09:16 mrbrown Exp
* SEGA Dreamcast support
*/ */
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/dc_sysasic.h> #include <asm/dreamcast/sysasic.h>
int __init gapspci_init(void);
#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
/* Dreamcast System ASIC Hardware Events - /* Dreamcast System ASIC Hardware Events -
The Dreamcast's System ASIC (located on the PowerVR2 chip) is responsible The Dreamcast's System ASIC (a.k.a. Holly) is responsible for receiving
for receiving hardware events from system peripherals and triggering an hardware events from system peripherals and triggering an SH7750 IRQ.
SH7750 IRQ. Hardware events can trigger IRQs 13, 11, or 9 depending on Hardware events can trigger IRQs 13, 11, or 9 depending on which bits are
which bits are set in the Event Mask Registers (EMRs). When a hardware set in the Event Mask Registers (EMRs). When a hardware event is
event is triggered, it's corresponding bit in the Event Status Registers triggered, it's corresponding bit in the Event Status Registers (ESRs)
(ESRs) is set, and that bit should be rewritten to the ESR to acknowledge is set, and that bit should be rewritten to the ESR to acknowledge that
that event. event.
There are three 32-bit ESRs located at 0xa05f8900 - 0xa05f6908. Event There are three 32-bit ESRs located at 0xa05f8900 - 0xa05f6908. Event
types can be found in include/asm-sh/dc_sysasic.h. There are three groups types can be found in include/asm-sh/dc_sysasic.h. There are three groups
...@@ -70,66 +57,66 @@ int __init gapspci_init(void); ...@@ -70,66 +57,66 @@ int __init gapspci_init(void);
/* Disable the hardware event by masking its bit in its EMR */ /* Disable the hardware event by masking its bit in its EMR */
static inline void disable_systemasic_irq(unsigned int irq) static inline void disable_systemasic_irq(unsigned int irq)
{ {
unsigned long flags; unsigned long flags;
__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2); __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
__u32 mask; __u32 mask;
save_and_cli(flags); local_irq_save(flags);
mask = inl(emr); mask = inl(emr);
mask &= ~(1 << EVENT_BIT(irq)); mask &= ~(1 << EVENT_BIT(irq));
outl(mask, emr); outl(mask, emr);
restore_flags(flags); local_irq_restore(flags);
} }
/* Enable the hardware event by setting its bit in its EMR */ /* Enable the hardware event by setting its bit in its EMR */
static inline void enable_systemasic_irq(unsigned int irq) static inline void enable_systemasic_irq(unsigned int irq)
{ {
unsigned long flags; unsigned long flags;
__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2); __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
__u32 mask; __u32 mask;
save_and_cli(flags); local_irq_save(flags);
mask = inl(emr); mask = inl(emr);
mask |= (1 << EVENT_BIT(irq)); mask |= (1 << EVENT_BIT(irq));
outl(mask, emr); outl(mask, emr);
restore_flags(flags); local_irq_restore(flags);
} }
/* Acknowledge a hardware event by writing its bit back to its ESR */ /* Acknowledge a hardware event by writing its bit back to its ESR */
static void ack_systemasic_irq(unsigned int irq) static void ack_systemasic_irq(unsigned int irq)
{ {
__u32 esr = ESR_BASE + (LEVEL(irq) << 2); __u32 esr = ESR_BASE + (LEVEL(irq) << 2);
disable_systemasic_irq(irq); disable_systemasic_irq(irq);
outl((1 << EVENT_BIT(irq)), esr); outl((1 << EVENT_BIT(irq)), esr);
} }
/* After a IRQ has been ack'd and responded to, it needs to be renabled */ /* After a IRQ has been ack'd and responded to, it needs to be renabled */
static void end_systemasic_irq(unsigned int irq) static void end_systemasic_irq(unsigned int irq)
{ {
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_systemasic_irq(irq); enable_systemasic_irq(irq);
} }
static unsigned int startup_systemasic_irq(unsigned int irq) static unsigned int startup_systemasic_irq(unsigned int irq)
{ {
enable_systemasic_irq(irq); enable_systemasic_irq(irq);
return 0; return 0;
} }
static void shutdown_systemasic_irq(unsigned int irq) static void shutdown_systemasic_irq(unsigned int irq)
{ {
disable_systemasic_irq(irq); disable_systemasic_irq(irq);
} }
static struct hw_interrupt_type systemasic_int = { struct hw_interrupt_type systemasic_int = {
.typename = "System ASIC", typename: "System ASIC",
.startup = startup_systemasic_irq, startup: startup_systemasic_irq,
.shutdown = shutdown_systemasic_irq, shutdown: shutdown_systemasic_irq,
.enable = enable_systemasic_irq, enable: enable_systemasic_irq,
.disable = disable_systemasic_irq, disable: disable_systemasic_irq,
.ack = ack_systemasic_irq, ack: ack_systemasic_irq,
.end = end_systemasic_irq, end: end_systemasic_irq,
}; };
/* /*
...@@ -137,77 +124,37 @@ static struct hw_interrupt_type systemasic_int = { ...@@ -137,77 +124,37 @@ static struct hw_interrupt_type systemasic_int = {
*/ */
int systemasic_irq_demux(int irq) int systemasic_irq_demux(int irq)
{ {
__u32 emr, esr, status, level; __u32 emr, esr, status, level;
__u32 j, bit; __u32 j, bit;
switch (irq) { switch (irq) {
case 13: case 13:
level = 0; level = 0;
break; break;
case 11: case 11:
level = 1; level = 1;
break; break;
case 9: case 9:
level = 2; level = 2;
break; break;
default: default:
return irq; return irq;
} }
emr = EMR_BASE + (level << 4) + (level << 2); emr = EMR_BASE + (level << 4) + (level << 2);
esr = ESR_BASE + (level << 2); esr = ESR_BASE + (level << 2);
/* Mask the ESR to filter any spurious, unwanted interrtupts */ /* Mask the ESR to filter any spurious, unwanted interrtupts */
status = inl(esr); status = inl(esr);
status &= inl(emr); status &= inl(emr);
/* Now scan and find the first set bit as the event to map */ /* Now scan and find the first set bit as the event to map */
for (bit = 1, j = 0; j < 32; bit <<= 1, j++) { for (bit = 1, j = 0; j < 32; bit <<= 1, j++) {
if (status & bit) { if (status & bit) {
irq = HW_EVENT_IRQ_BASE + j + (level << 5); irq = HW_EVENT_IRQ_BASE + j + (level << 5);
return irq; return irq;
} }
} }
/* Not reached */ /* Not reached */
return irq; return irq;
}
int __init setup_dreamcast(void)
{
int i;
/* Mask all hardware events */
/* XXX */
/* Acknowledge any previous events */
/* XXX */
/* Assign all virtual IRQs to the System ASIC int. handler */
for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++)
irq_desc[i].handler = &systemasic_int;
#ifdef CONFIG_PCI
gapspci_init();
#endif
printk(KERN_INFO "SEGA Dreamcast support.\n");
#if 0
printk(KERN_INFO "BCR1: 0x%08x\n", ctrl_inl(0xff800000));
printk(KERN_INFO "BCR2: 0x%08x\n", ctrl_inw(0xff800004));
printk(KERN_INFO "WCR1: 0x%08x\n", ctrl_inl(0xff800008));
printk(KERN_INFO "WCR2: 0x%08x\n", ctrl_inl(0xff80000c));
printk(KERN_INFO "WCR3: 0x%08x\n", ctrl_inl(0xff800010));
printk(KERN_INFO "MCR: 0x%08x\n", ctrl_inl(0xff800014));
printk(KERN_INFO "PCR: 0x%08x\n", ctrl_inw(0xff800018));
/*
* BCR1: 0xa3020008
* BCR2: 0x0001
* WCR1: 0x01110111
* WCR2: 0x618066d8
* WCR3: 0x07777777
* MCR: 0xc00a0e24
* PCR: 0x0000
*/
#endif
return 0;
} }
/*
* $Id: mach.c,v 1.1.2.5 2002/03/01 11:22:17 lethal Exp $
* SEGA Dreamcast machine vector
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/time.h>
#include <asm/machvec.h>
#include <asm/machvec_init.h>
#include <asm/io_generic.h>
#include <asm/dreamcast/io.h>
#include <asm/irq.h>
void __init dreamcast_pcibios_init(void);
/*
* The Machine Vector
*/
struct sh_machine_vector mv_dreamcast __initmv = {
mv_nr_irqs: NR_IRQS,
mv_inb: generic_inb,
mv_inw: generic_inw,
mv_inl: generic_inl,
mv_outb: generic_outb,
mv_outw: generic_outw,
mv_outl: generic_outl,
mv_inb_p: generic_inb_p,
mv_inw_p: generic_inw,
mv_inl_p: generic_inl,
mv_outb_p: generic_outb_p,
mv_outw_p: generic_outw,
mv_outl_p: generic_outl,
mv_insb: generic_insb,
mv_insw: generic_insw,
mv_insl: generic_insl,
mv_outsb: generic_outsb,
mv_outsw: generic_outsw,
mv_outsl: generic_outsl,
mv_readb: generic_readb,
mv_readw: generic_readw,
mv_readl: generic_readl,
mv_writeb: generic_writeb,
mv_writew: generic_writew,
mv_writel: generic_writel,
mv_ioremap: generic_ioremap,
mv_iounmap: generic_iounmap,
mv_isa_port2addr: dreamcast_isa_port2addr,
mv_irq_demux: systemasic_irq_demux,
mv_hw_dreamcast: 1,
};
ALIAS_MV(dreamcast)
/* /*
$ $Id: pci-dc.c,v 1.5 2001/08/24 12:38:19 dwmw2 Exp $ $ $Id: pci.c,v 1.1.2.4.2.1 2003/03/31 14:33:18 lethal Exp $
* Dreamcast PCI: Supports SEGA Broadband Adaptor only. * Dreamcast PCI: Supports SEGA Broadband Adaptor only.
*/ */
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/dc_sysasic.h> #include <asm/dreamcast/sysasic.h>
#define GAPSPCI_REGS 0x01001400 #define GAPSPCI_REGS 0x01001400
#define GAPSPCI_DMA_BASE 0x01840000 #define GAPSPCI_DMA_BASE 0x01840000
...@@ -25,7 +25,26 @@ ...@@ -25,7 +25,26 @@
static int gapspci_dma_used; static int gapspci_dma_used;
static struct pci_bus *pci_root_bus; /* XXX: Uh... */
static struct resource gapspci_io_resource = {
"GAPSPCI IO",
0x01001600,
0x010016ff,
IORESOURCE_IO
};
static struct resource gapspci_mem_resource = {
"GAPSPCI mem",
0x01840000,
0x01847fff,
IORESOURCE_MEM
};
static struct pci_ops gapspci_pci_ops;
struct pci_channel board_pci_channels[] = {
{&gapspci_pci_ops, &gapspci_io_resource, &gapspci_mem_resource, 0, 1},
{NULL, NULL, NULL, 0, 0},
};
struct pci_fixup pcibios_fixups[] = { struct pci_fixup pcibios_fixups[] = {
{0, 0, 0, NULL} {0, 0, 0, NULL}
...@@ -39,23 +58,23 @@ static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int ...@@ -39,23 +58,23 @@ static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int
case 1: case 1:
if (BBA_SELECTED(bus, devfn)) if (BBA_SELECTED(bus, devfn))
*val = (u8)inb(GAPSPCI_BBA_CONFIG+where); *val = (u8)inb(GAPSPCI_BBA_CONFIG+where);
else else
*val = (u8)0xff; *val = (u8)0xff;
break; break;
case 2: case 2:
if (BBA_SELECTED(bus, devfn)) if (BBA_SELECTED(bus, devfn))
*val = (u16)inw(GAPSPCI_BBA_CONFIG+where); *val = (u16)inw(GAPSPCI_BBA_CONFIG+where);
else else
*val = (u16)0xffff; *val = (u16)0xffff;
break; break;
case 4: case 4:
if (BBA_SELECTED(bus, devfn)) if (BBA_SELECTED(bus, devfn))
*val = inl(GAPSPCI_BBA_CONFIG+where); *val = inl(GAPSPCI_BBA_CONFIG+where);
else else
*val = 0xffffffff; *val = 0xffffffff;
break; break;
} }
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
...@@ -72,14 +91,14 @@ static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int ...@@ -72,14 +91,14 @@ static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int
break; break;
case 4: case 4:
if (BBA_SELECTED(bus, devfn)) if (BBA_SELECTED(bus, devfn))
outl(val, GAPSPCI_BBA_CONFIG+where); outl(val, GAPSPCI_BBA_CONFIG+where);
break; break;
} }
} }
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static struct pci_ops pci_config_ops = { static struct pci_ops gapspci_pci_ops = {
.read = gapspci_read, .read = gapspci_read,
.write = gapspci_write, .write = gapspci_write,
}; };
...@@ -122,7 +141,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) ...@@ -122,7 +141,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
dev = pci_dev_b(ln); dev = pci_dev_b(ln);
if (!BBA_SELECTED(bus, dev->devfn)) continue; if (!BBA_SELECTED(bus, dev->devfn)) continue;
printk("PCI: MMIO fixup to %s\n", dev->name); printk("PCI: MMIO fixup to %s\n", dev->dev.name);
dev->resource[1].start=0x01001700; dev->resource[1].start=0x01001700;
dev->resource[1].end=0x010017ff; dev->resource[1].end=0x010017ff;
} }
...@@ -140,22 +159,13 @@ static int __init map_dc_irq(struct pci_dev *dev, u8 slot, u8 pin) ...@@ -140,22 +159,13 @@ static int __init map_dc_irq(struct pci_dev *dev, u8 slot, u8 pin)
return GAPSPCI_IRQ; return GAPSPCI_IRQ;
} }
void __init pcibios_fixup(void) { /* Do nothing. */ }
void __init pcibios_init(void) void __init pcibios_fixup_irqs(void)
{ {
pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
/* pci_assign_unassigned_resources(); */
pci_fixup_irqs(no_swizzle, map_dc_irq); pci_fixup_irqs(no_swizzle, map_dc_irq);
} }
/* Haven't done anything here as yet */
char * __init pcibios_setup(char *str)
{
return str;
}
int __init gapspci_init(void) int __init gapspci_init(void)
{ {
int i; int i;
...@@ -196,3 +206,9 @@ int __init gapspci_init(void) ...@@ -196,3 +206,9 @@ int __init gapspci_init(void)
return 0; return 0;
} }
/* Haven't done anything here as yet */
char * __devinit pcibios_setup(char *str)
{
return str;
}
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
* *
* Dreamcast AICA RTC routines. * Dreamcast AICA RTC routines.
* *
* Copyright (c) 2001 M. R. Brown <mrbrown@0xd6.org> * Copyright (c) 2001, 2002 M. R. Brown <mrbrown@0xd6.org>
* Copyright (c) 2002 Paul Mundt <lethal@chaoticdreams.org>
* *
* Released under the terms of the GNU GPL v2.0. * Released under the terms of the GNU GPL v2.0.
* *
...@@ -12,6 +13,9 @@ ...@@ -12,6 +13,9 @@
#include <asm/io.h> #include <asm/io.h>
extern void (*rtc_get_time)(struct timespec *);
extern int (*rtc_set_time)(const time_t);
/* The AICA RTC has an Epoch of 1/1/1950, so we must subtract 20 years (in /* The AICA RTC has an Epoch of 1/1/1950, so we must subtract 20 years (in
seconds to get the standard Unix Epoch when getting the time, and add 20 seconds to get the standard Unix Epoch when getting the time, and add 20
years when setting the time. */ years when setting the time. */
...@@ -28,7 +32,7 @@ ...@@ -28,7 +32,7 @@
* *
* Grabs the current RTC seconds counter and adjusts it to the Unix Epoch. * Grabs the current RTC seconds counter and adjusts it to the Unix Epoch.
*/ */
void aica_rtc_gettimeofday(struct timeval *tv) { void aica_rtc_gettimeofday(struct timespec *ts) {
unsigned long val1, val2; unsigned long val1, val2;
do { do {
...@@ -39,10 +43,10 @@ void aica_rtc_gettimeofday(struct timeval *tv) { ...@@ -39,10 +43,10 @@ void aica_rtc_gettimeofday(struct timeval *tv) {
(ctrl_inl(AICA_RTC_SECS_L) & 0xffff); (ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
} while (val1 != val2); } while (val1 != val2);
tv->tv_sec = val1 - TWENTY_YEARS; ts->tv_sec = val1 - TWENTY_YEARS;
/* Can't get microseconds with just a seconds counter. */ /* Can't get nanoseconds with just a seconds counter. */
tv->tv_usec = 0; ts->tv_nsec = 0;
} }
/** /**
...@@ -51,13 +55,13 @@ void aica_rtc_gettimeofday(struct timeval *tv) { ...@@ -51,13 +55,13 @@ void aica_rtc_gettimeofday(struct timeval *tv) {
* *
* Adjusts the given @tv to the AICA Epoch and sets the RTC seconds counter. * Adjusts the given @tv to the AICA Epoch and sets the RTC seconds counter.
*/ */
int aica_rtc_settimeofday(const struct timeval *tv) { int aica_rtc_settimeofday(const time_t secs) {
unsigned long val1, val2; unsigned long val1, val2;
unsigned long secs = tv->tv_sec + TWENTY_YEARS; unsigned long adj = secs + TWENTY_YEARS;
do { do {
ctrl_outl((secs & 0xffff0000) >> 16, AICA_RTC_SECS_H); ctrl_outl((adj & 0xffff0000) >> 16, AICA_RTC_SECS_H);
ctrl_outl((secs & 0xffff), AICA_RTC_SECS_L); ctrl_outl((adj & 0xffff), AICA_RTC_SECS_L);
val1 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) | val1 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
(ctrl_inl(AICA_RTC_SECS_L) & 0xffff); (ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
...@@ -68,3 +72,10 @@ int aica_rtc_settimeofday(const struct timeval *tv) { ...@@ -68,3 +72,10 @@ int aica_rtc_settimeofday(const struct timeval *tv) {
return 0; return 0;
} }
void aica_time_init(void)
{
rtc_get_time = aica_rtc_gettimeofday;
rtc_set_time = aica_rtc_settimeofday;
}
/* arch/sh/kernel/setup_dc.c
*
* Hardware support for the Sega Dreamcast.
*
* Copyright (c) 2001, 2002 M. R. Brown <mrbrown@linuxdc.org>
* Copyright (c) 2002 Paul Mundt <lethal@chaoticdreams.org>
*
* This file is part of the LinuxDC project (www.linuxdc.org)
*
* Released under the terms of the GNU GPL v2.0.
*
* This file originally bore the message (with enclosed-$):
* Id: setup_dc.c,v 1.5 2001/05/24 05:09:16 mrbrown Exp
* SEGA Dreamcast support
*/
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/dreamcast/sysasic.h>
extern struct hw_interrupt_type systemasic_int;
/* XXX: Move this into it's proper header. */
extern void (*board_time_init)(void);
extern void aica_time_init(void);
const char *get_system_type(void)
{
return "Sega Dreamcast";
}
#ifdef CONFIG_PCI
extern int gapspci_init(void);
#endif
int __init platform_setup(void)
{
int i;
/* Mask all hardware events */
/* XXX */
/* Acknowledge any previous events */
/* XXX */
/* Assign all virtual IRQs to the System ASIC int. handler */
for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++)
irq_desc[i].handler = &systemasic_int;
board_time_init = aica_time_init;
#ifdef CONFIG_PCI
if (gapspci_init() < 0)
printk(KERN_WARNING "GAPSPCI was not detected.\n");
#endif
return 0;
}
#
# Makefile for the EC3104 specific parts of the kernel
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := mach.o setup.o io.o irq.o
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/ec3104.h> #include <asm/ec3104/ec3104.h>
/* /*
* EC3104 has a real ISA bus which we redirect low port accesses to (the * EC3104 has a real ISA bus which we redirect low port accesses to (the
......
/* /*
* linux/arch/sh/kernel/setup_ec3104.c * linux/arch/sh/boards/ec3104/irq.c
* EC3104 companion chip support * EC3104 companion chip support
* *
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
* *
*/ */
/* EC3104 note:
* This code was written without any documentation about the EC3104 chip. While
* I hope I got most of the basic functionality right, the register names I use
* are most likely completely different from those in the chip documentation.
*
* If you have any further information about the EC3104, please tell me
* (prumpf@tux.org).
*/
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/types.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/ec3104.h> #include <asm/ec3104/ec3104.h>
/* This is for debugging mostly; here's the table that I intend to keep /* This is for debugging mostly; here's the table that I intend to keep
* in here: * in here:
* *
* index function base addr power interrupt bit * index function base addr power interrupt bit
* 0 power b0ec0000 --- 00000001 (unused) * 0 power b0ec0000 --- 00000001 (unused)
* 1 irqs b0ec1000 --- 00000002 (unused) * 1 irqs b0ec1000 --- 00000002 (unused)
* 2 ?? b0ec2000 b0ec0008 00000004 * 2 ?? b0ec2000 b0ec0008 00000004
* 3 PS2 (1) b0ec3000 b0ec000c 00000008 * 3 PS2 (1) b0ec3000 b0ec000c 00000008
* 4 PS2 (2) b0ec4000 b0ec0010 00000010 * 4 PS2 (2) b0ec4000 b0ec0010 00000010
* 5 ?? b0ec5000 b0ec0014 00000020 * 5 ?? b0ec5000 b0ec0014 00000020
* 6 I2C b0ec6000 b0ec0018 00000040 * 6 I2C b0ec6000 b0ec0018 00000040
* 7 serial (1) b0ec7000 b0ec001c 00000080 * 7 serial (1) b0ec7000 b0ec001c 00000080
* 8 serial (2) b0ec8000 b0ec0020 00000100 * 8 serial (2) b0ec8000 b0ec0020 00000100
* 9 serial (3) b0ec9000 b0ec0024 00000200 * 9 serial (3) b0ec9000 b0ec0024 00000200
* 10 serial (4) b0eca000 b0ec0028 00000400 * 10 serial (4) b0eca000 b0ec0028 00000400
* 12 GPIO (1) b0ecc000 b0ec0030 * 12 GPIO (1) b0ecc000 b0ec0030
* 13 GPIO (2) b0ecc000 b0ec0030 * 13 GPIO (2) b0ecc000 b0ec0030
* 16 pcmcia (1) b0ed0000 b0ec0040 00010000 * 16 pcmcia (1) b0ed0000 b0ec0040 00010000
* 17 pcmcia (2) b0ed1000 b0ec0044 00020000 * 17 pcmcia (2) b0ed1000 b0ec0044 00020000
*/ */
/* I used the register names from another interrupt controller I worked with, /* I used the register names from another interrupt controller I worked with,
...@@ -69,174 +53,144 @@ ...@@ -69,174 +53,144 @@
static char *ec3104_name(unsigned index) static char *ec3104_name(unsigned index)
{ {
switch(index) { switch(index) {
case 0: case 0:
return "power management"; return "power management";
case 1: case 1:
return "interrupts"; return "interrupts";
case 3: case 3:
return "PS2 (1)"; return "PS2 (1)";
case 4: case 4:
return "PS2 (2)"; return "PS2 (2)";
case 5: case 5:
return "I2C (1)"; return "I2C (1)";
case 6: case 6:
return "I2C (2)"; return "I2C (2)";
case 7: case 7:
return "serial (1)"; return "serial (1)";
case 8: case 8:
return "serial (2)"; return "serial (2)";
case 9: case 9:
return "serial (3)"; return "serial (3)";
case 10: case 10:
return "serial (4)"; return "serial (4)";
case 16: case 16:
return "pcmcia (1)"; return "pcmcia (1)";
case 17: case 17:
return "pcmcia (2)"; return "pcmcia (2)";
default: { default: {
static char buf[32]; static char buf[32];
sprintf(buf, "unknown (%d)", index); sprintf(buf, "unknown (%d)", index);
return buf; return buf;
} }
} }
} }
int get_pending_interrupts(char *buf) int get_pending_interrupts(char *buf)
{ {
u32 ipr; u32 ipr;
u32 bit; u32 bit;
char *p = buf; char *p = buf;
p += sprintf(p, "pending: ("); p += sprintf(p, "pending: (");
ipr = ctrl_inl(EC3104_IPR);
for (bit = 1; bit < 32; bit++) ipr = ctrl_inl(EC3104_IPR);
if (!(ipr & (1<<bit)))
p += sprintf(p, "%s ", ec3104_name(bit)); for (bit = 1; bit < 32; bit++)
if (!(ipr & (1<<bit)))
p += sprintf(p, ")\n"); p += sprintf(p, "%s ", ec3104_name(bit));
p += sprintf(p, ")\n");
return p - buf; return p - buf;
} }
static inline u32 ec3104_irq2mask(unsigned int irq) static inline u32 ec3104_irq2mask(unsigned int irq)
{ {
return (1 << (irq - EC3104_IRQBASE)); return (1 << (irq - EC3104_IRQBASE));
} }
static inline void mask_ec3104_irq(unsigned int irq) static inline void mask_ec3104_irq(unsigned int irq)
{ {
u32 mask; u32 mask;
mask = ctrl_readl(EC3104_IMR);
mask = ctrl_readl(EC3104_IMR); mask |= ec3104_irq2mask(irq);
mask |= ec3104_irq2mask(irq); ctrl_writel(mask, EC3104_IMR);
ctrl_writel(mask, EC3104_IMR);
} }
static inline void unmask_ec3104_irq(unsigned int irq) static inline void unmask_ec3104_irq(unsigned int irq)
{ {
u32 mask; u32 mask;
mask = ctrl_readl(EC3104_IMR); mask = ctrl_readl(EC3104_IMR);
mask &= ~ec3104_irq2mask(irq); mask &= ~ec3104_irq2mask(irq);
ctrl_writel(mask, EC3104_IMR); ctrl_writel(mask, EC3104_IMR);
} }
static void disable_ec3104_irq(unsigned int irq) static void disable_ec3104_irq(unsigned int irq)
{ {
mask_ec3104_irq(irq); mask_ec3104_irq(irq);
} }
static void enable_ec3104_irq(unsigned int irq) static void enable_ec3104_irq(unsigned int irq)
{ {
unmask_ec3104_irq(irq); unmask_ec3104_irq(irq);
} }
static void mask_and_ack_ec3104_irq(unsigned int irq) static void mask_and_ack_ec3104_irq(unsigned int irq)
{ {
mask_ec3104_irq(irq); mask_ec3104_irq(irq);
} }
static void end_ec3104_irq(unsigned int irq) static void end_ec3104_irq(unsigned int irq)
{ {
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
unmask_ec3104_irq(irq); unmask_ec3104_irq(irq);
} }
static unsigned int startup_ec3104_irq(unsigned int irq) static unsigned int startup_ec3104_irq(unsigned int irq)
{ {
unmask_ec3104_irq(irq); unmask_ec3104_irq(irq);
return 0; return 0;
} }
static void shutdown_ec3104_irq(unsigned int irq) static void shutdown_ec3104_irq(unsigned int irq)
{ {
mask_ec3104_irq(irq); mask_ec3104_irq(irq);
} }
static struct hw_interrupt_type ec3104_int = { static struct hw_interrupt_type ec3104_int = {
.typename = "EC3104", typename: "EC3104",
.enable = enable_ec3104_irq, enable: enable_ec3104_irq,
.disable = disable_ec3104_irq, disable: disable_ec3104_irq,
.ack = mask_and_ack_ec3104_irq, ack: mask_and_ack_ec3104_irq,
.end = end_ec3104_irq, end: end_ec3104_irq,
.startup = startup_ec3104_irq, startup: startup_ec3104_irq,
.shutdown = shutdown_ec3104_irq, shutdown: shutdown_ec3104_irq,
}; };
/* Yuck. the _demux API is ugly */ /* Yuck. the _demux API is ugly */
int ec3104_irq_demux(int irq) int ec3104_irq_demux(int irq)
{ {
if (irq == EC3104_IRQ) { if (irq == EC3104_IRQ) {
unsigned int mask; unsigned int mask;
mask = ctrl_readl(EC3104_IRR); mask = ctrl_readl(EC3104_IRR);
if (mask == 0xffffffff) if (mask == 0xffffffff)
return EC3104_IRQ; return EC3104_IRQ;
else else
return EC3104_IRQBASE + ffz(mask); return EC3104_IRQBASE + ffz(mask);
} }
return irq; return irq;
} }
int __init setup_ec3104(void)
{
char str[8];
int i;
if (!MACH_EC3104)
printk("!MACH_EC3104\n");
if (0)
return 0;
for (i=0; i<8; i++)
str[i] = ctrl_readb(EC3104_BASE + i);
for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++)
irq_desc[i].handler = &ec3104_int;
printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n",
str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE);
/* mask all interrupts. this should have been done by the boot
* loader for us but we want to be sure ... */
ctrl_writel(0xffffffff, EC3104_IMR);
return 0;
}
module_init(setup_ec3104);
...@@ -28,42 +28,42 @@ ...@@ -28,42 +28,42 @@
*/ */
struct sh_machine_vector mv_ec3104 __initmv = { struct sh_machine_vector mv_ec3104 __initmv = {
.mv_name = "EC3104", mv_name: "EC3104",
.mv_nr_irqs = 96, mv_nr_irqs: 96,
.mv_inb = ec3104_inb, mv_inb: ec3104_inb,
.mv_inw = ec3104_inw, mv_inw: ec3104_inw,
.mv_inl = ec3104_inl, mv_inl: ec3104_inl,
.mv_outb = ec3104_outb, mv_outb: ec3104_outb,
.mv_outw = ec3104_outw, mv_outw: ec3104_outw,
.mv_outl = ec3104_outl, mv_outl: ec3104_outl,
.mv_inb_p = generic_inb_p, mv_inb_p: generic_inb_p,
.mv_inw_p = generic_inw, mv_inw_p: generic_inw,
.mv_inl_p = generic_inl, mv_inl_p: generic_inl,
.mv_outb_p = generic_outb_p, mv_outb_p: generic_outb_p,
.mv_outw_p = generic_outw, mv_outw_p: generic_outw,
.mv_outl_p = generic_outl, mv_outl_p: generic_outl,
.mv_insb = generic_insb, mv_insb: generic_insb,
.mv_insw = generic_insw, mv_insw: generic_insw,
.mv_insl = generic_insl, mv_insl: generic_insl,
.mv_outsb = generic_outsb, mv_outsb: generic_outsb,
.mv_outsw = generic_outsw, mv_outsw: generic_outsw,
.mv_outsl = generic_outsl, mv_outsl: generic_outsl,
.mv_readb = generic_readb, mv_readb: generic_readb,
.mv_readw = generic_readw, mv_readw: generic_readw,
.mv_readl = generic_readl, mv_readl: generic_readl,
.mv_writeb = generic_writeb, mv_writeb: generic_writeb,
.mv_writew = generic_writew, mv_writew: generic_writew,
.mv_writel = generic_writel, mv_writel: generic_writel,
.mv_irq_demux = ec3104_irq_demux, mv_irq_demux: ec3104_irq_demux,
.mv_rtc_gettimeofday = sh_rtc_gettimeofday, mv_rtc_gettimeofday: sh_rtc_gettimeofday,
.mv_rtc_settimeofday = sh_rtc_settimeofday, mv_rtc_settimeofday: sh_rtc_settimeofday,
}; };
ALIAS_MV(ec3104) ALIAS_MV(ec3104)
/*
* linux/arch/sh/boards/ec3104/setup.c
* EC3104 companion chip support
*
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
*
*/
/* EC3104 note:
* This code was written without any documentation about the EC3104 chip. While
* I hope I got most of the basic functionality right, the register names I use
* are most likely completely different from those in the chip documentation.
*
* If you have any further information about the EC3104, please tell me
* (prumpf@tux.org).
*/
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/types.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/ec3104/ec3104.h>
int __init setup_ec3104(void)
{
char str[8];
int i;
if (!MACH_EC3104)
printk("!MACH_EC3104\n");
if (0)
return 0;
for (i=0; i<8; i++)
str[i] = ctrl_readb(EC3104_BASE + i);
for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++)
irq_desc[i].handler = &ec3104_int;
printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n",
str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE);
/* mask all interrupts. this should have been done by the boot
* loader for us but we want to be sure ... */
ctrl_writel(0xffffffff, EC3104_IMR);
return 0;
}
module_init(setup_ec3104);
# #
# Makefile for STMicroelectronics board specific parts of the kernel # Makefile for STMicroelectronics board specific parts of the kernel
# #
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := irq.o setup.o mach.o led.o obj-y := irq.o setup.o mach.o led.o
obj-$(CONFIG_PCI) += pcidma.o
...@@ -15,8 +15,7 @@ ...@@ -15,8 +15,7 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/harp/harp.h>
#include "harp.h"
#define NUM_EXTERNAL_IRQS 16 #define NUM_EXTERNAL_IRQS 16
...@@ -68,14 +67,14 @@ static void disable_harp_irq(unsigned int irq) ...@@ -68,14 +67,14 @@ static void disable_harp_irq(unsigned int irq)
pri -= 8; pri -= 8;
} }
save_and_cli(flags); local_irq_save(flags);
mask = ctrl_inl(maskReg); mask = ctrl_inl(maskReg);
mask &= (~(1 << pri)); mask &= (~(1 << pri));
#if defined(INVERT_INTMASK_WRITES) #if defined(INVERT_INTMASK_WRITES)
mask ^= 0xff; mask ^= 0xff;
#endif #endif
ctrl_outl(mask, maskReg); ctrl_outl(mask, maskReg);
restore_flags(flags); local_irq_restore(flags);
} }
static void enable_harp_irq(unsigned int irq) static void enable_harp_irq(unsigned int irq)
...@@ -97,7 +96,7 @@ static void enable_harp_irq(unsigned int irq) ...@@ -97,7 +96,7 @@ static void enable_harp_irq(unsigned int irq)
pri -= 8; pri -= 8;
} }
save_and_cli(flags); local_irq_save(flags);
mask = ctrl_inl(maskReg); mask = ctrl_inl(maskReg);
...@@ -108,7 +107,7 @@ static void enable_harp_irq(unsigned int irq) ...@@ -108,7 +107,7 @@ static void enable_harp_irq(unsigned int irq)
#endif #endif
ctrl_outl(mask, maskReg); ctrl_outl(mask, maskReg);
restore_flags(flags); local_irq_restore(flags);
} }
/* This functions sets the desired irq handler to be an overdrive type */ /* This functions sets the desired irq handler to be an overdrive type */
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <asm/io.h> #include <asm/io.h>
#include "harp.h" #include <asm/harp/harp.h>
/* Harp: Flash LD10 (front pannel) connected to EPLD (IC8) */ /* Harp: Flash LD10 (front pannel) connected to EPLD (IC8) */
/* Overdrive: Flash LD1 (front panel) connected to EPLD (IC4) */ /* Overdrive: Flash LD1 (front panel) connected to EPLD (IC4) */
......
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
#include <asm/machvec.h> #include <asm/machvec.h>
#include <asm/rtc.h> #include <asm/rtc.h>
#include <asm/machvec_init.h> #include <asm/machvec_init.h>
#include <asm/io_hd64465.h> #include <asm/hd64465.h/io.h>
#include <asm/hd64465.h> #include <asm/hd64465/hd64465.h>
void setup_harp(void); void setup_harp(void);
void init_harp_irq(void); void init_harp_irq(void);
...@@ -26,52 +26,47 @@ void heartbeat_harp(void); ...@@ -26,52 +26,47 @@ void heartbeat_harp(void);
*/ */
struct sh_machine_vector mv_harp __initmv = { struct sh_machine_vector mv_harp __initmv = {
.mv_name = "STB1 Harp", mv_nr_irqs: 89 + HD64465_IRQ_NUM,
.mv_nr_irqs = 89 + HD64465_IRQ_NUM, mv_inb: hd64465_inb,
mv_inw: hd64465_inw,
mv_inl: hd64465_inl,
mv_outb: hd64465_outb,
mv_outw: hd64465_outw,
mv_outl: hd64465_outl,
.mv_inb = hd64465_inb, mv_inb_p: hd64465_inb_p,
.mv_inw = hd64465_inw, mv_inw_p: hd64465_inw,
.mv_inl = hd64465_inl, mv_inl_p: hd64465_inl,
.mv_outb = hd64465_outb, mv_outb_p: hd64465_outb_p,
.mv_outw = hd64465_outw, mv_outw_p: hd64465_outw,
.mv_outl = hd64465_outl, mv_outl_p: hd64465_outl,
.mv_inb_p = hd64465_inb_p, mv_insb: hd64465_insb,
.mv_inw_p = hd64465_inw, mv_insw: hd64465_insw,
.mv_inl_p = hd64465_inl, mv_insl: hd64465_insl,
.mv_outb_p = hd64465_outb_p, mv_outsb: hd64465_outsb,
.mv_outw_p = hd64465_outw, mv_outsw: hd64465_outsw,
.mv_outl_p = hd64465_outl, mv_outsl: hd64465_outsl,
.mv_insb = hd64465_insb, mv_readb: generic_readb,
.mv_insw = hd64465_insw, mv_readw: generic_readw,
.mv_insl = hd64465_insl, mv_readl: generic_readl,
.mv_outsb = hd64465_outsb, mv_writeb: generic_writeb,
.mv_outsw = hd64465_outsw, mv_writew: generic_writew,
.mv_outsl = hd64465_outsl, mv_writel: generic_writel,
.mv_readb = generic_readb, mv_ioremap: generic_ioremap,
.mv_readw = generic_readw, mv_iounmap: generic_iounmap,
.mv_readl = generic_readl,
.mv_writeb = generic_writeb,
.mv_writew = generic_writew,
.mv_writel = generic_writel,
.mv_ioremap = generic_ioremap,
.mv_iounmap = generic_iounmap,
.mv_isa_port2addr = hd64465_isa_port2addr, mv_isa_port2addr: hd64465_isa_port2addr,
.mv_init_arch = setup_harp,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.mv_init_irq = init_harp_irq, mv_init_irq: init_harp_irq,
#endif #endif
#ifdef CONFIG_HEARTBEAT #ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_harp, mv_heartbeat: heartbeat_harp,
#endif #endif
.mv_rtc_gettimeofday = sh_rtc_gettimeofday,
.mv_rtc_settimeofday = sh_rtc_settimeofday,
}; };
ALIAS_MV(harp) ALIAS_MV(harp)
...@@ -24,7 +24,7 @@ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, ...@@ -24,7 +24,7 @@ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
ret = (void *) __get_free_pages(gfp, get_order(size)); ret = (void *) __get_free_pages(gfp, get_order(size));
if (ret != NULL) { if (ret != NULL) {
/* Is it necessary to do the memset? */ /* Is it neccessary to do the memset? */
memset(ret, 0, size); memset(ret, 0, size);
*dma_handle = virt_to_bus(ret); *dma_handle = virt_to_bus(ret);
} }
......
...@@ -13,11 +13,17 @@ ...@@ -13,11 +13,17 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/io.h> #include <asm/io.h>
#include "harp.h" #include <asm/harp/harp.h>
const char *get_system_type(void)
{
return "STB1 Harp";
}
/* /*
* Initialize the board * Initialize the board
*/ */
int __init setup_harp(void) int __init platform_setup(void)
{ {
#ifdef CONFIG_SH_STB1_HARP #ifdef CONFIG_SH_STB1_HARP
unsigned long ic8_version, ic36_version; unsigned long ic8_version, ic36_version;
......
#
# Makefile for the HP620 specific parts of the kernel
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := mach.o
/*
* linux/arch/sh/boards/hp6xx/hp620/mach.c
*
* Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Machine vector for the HP620
*/
#include <linux/init.h>
#include <asm/machvec.h>
#include <asm/rtc.h>
#include <asm/machvec_init.h>
#include <asm/io.h>
#include <asm/hd64461/hd64461.h>
#include <asm/irq.h>
/*
* The Machine Vector
*/
struct sh_machine_vector mv_hp620 __initmv = {
mv_name: "hp620",
mv_nr_irqs: HD64461_IRQBASE+HD64461_IRQ_NUM,
mv_inb: hd64461_inb,
mv_inw: hd64461_inw,
mv_inl: hd64461_inl,
mv_outb: hd64461_outb,
mv_outw: hd64461_outw,
mv_outl: hd64461_outl,
mv_inb_p: hd64461_inb_p,
mv_inw_p: hd64461_inw,
mv_inl_p: hd64461_inl,
mv_outb_p: hd64461_outb_p,
mv_outw_p: hd64461_outw,
mv_outl_p: hd64461_outl,
mv_insb: hd64461_insb,
mv_insw: hd64461_insw,
mv_insl: hd64461_insl,
mv_outsb: hd64461_outsb,
mv_outsw: hd64461_outsw,
mv_outsl: hd64461_outsl,
mv_readb: generic_readb,
mv_readw: generic_readw,
mv_readl: generic_readl,
mv_writeb: generic_writeb,
mv_writew: generic_writew,
mv_writel: generic_writel,
mv_irq_demux: hd64461_irq_demux,
mv_rtc_gettimeofday: sh_rtc_gettimeofday,
mv_rtc_settimeofday: sh_rtc_settimeofday,
mv_hw_hp600: 1,
mv_hw_hp620: 1,
mv_hw_hd64461: 1,
};
ALIAS_MV(hp620)
#
# Makefile for the HP680 specific parts of the kernel
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := mach.o
/*
* linux/arch/sh/boards/hp6xx/hp680/mach.c
*
* Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Machine vector for the HP680
*/
#include <linux/init.h>
#include <asm/machvec.h>
#include <asm/rtc.h>
#include <asm/machvec_init.h>
#include <asm/io.h>
#include <asm/hd64461/hd64461.h>
#include <asm/irq.h>
struct sh_machine_vector mv_hp680 __initmv = {
mv_name: "hp680",
mv_nr_irqs: HD64461_IRQBASE+HD64461_IRQ_NUM,
mv_inb: hd64461_inb,
mv_inw: hd64461_inw,
mv_inl: hd64461_inl,
mv_outb: hd64461_outb,
mv_outw: hd64461_outw,
mv_outl: hd64461_outl,
mv_inb_p: hd64461_inb_p,
mv_inw_p: hd64461_inw,
mv_inl_p: hd64461_inl,
mv_outb_p: hd64461_outb_p,
mv_outw_p: hd64461_outw,
mv_outl_p: hd64461_outl,
mv_insb: hd64461_insb,
mv_insw: hd64461_insw,
mv_insl: hd64461_insl,
mv_outsb: hd64461_outsb,
mv_outsw: hd64461_outsw,
mv_outsl: hd64461_outsl,
mv_readb: generic_readb,
mv_readw: generic_readw,
mv_readl: generic_readl,
mv_writeb: generic_writeb,
mv_writew: generic_writew,
mv_writel: generic_writel,
mv_irq_demux: hd64461_irq_demux,
mv_rtc_gettimeofday: sh_rtc_gettimeofday,
mv_rtc_settimeofday: sh_rtc_settimeofday,
mv_hw_hp600: 1,
mv_hw_hp680: 1,
mv_hw_hd64461: 1,
};
ALIAS_MV(hp680)
#
# Makefile for the HP690 specific parts of the kernel
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := mach.o
/*
* linux/arch/sh/boards/hp6xx/hp690/mach.c
*
* Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Machine vector for the HP690
*/
#include <linux/init.h>
#include <asm/machvec.h>
#include <asm/rtc.h>
#include <asm/machvec_init.h>
#include <asm/io.h>
#include <asm/hd64461/hd64461.h>
#include <asm/irq.h>
struct sh_machine_vector mv_hp690 __initmv = {
mv_name: "hp690",
mv_nr_irqs: HD64461_IRQBASE+HD64461_IRQ_NUM,
mv_inb: hd64461_inb,
mv_inw: hd64461_inw,
mv_inl: hd64461_inl,
mv_outb: hd64461_outb,
mv_outw: hd64461_outw,
mv_outl: hd64461_outl,
mv_inb_p: hd64461_inb_p,
mv_inw_p: hd64461_inw,
mv_inl_p: hd64461_inl,
mv_outb_p: hd64461_outb_p,
mv_outw_p: hd64461_outw,
mv_outl_p: hd64461_outl,
mv_insb: hd64461_insb,
mv_insw: hd64461_insw,
mv_insl: hd64461_insl,
mv_outsb: hd64461_outsb,
mv_outsw: hd64461_outsw,
mv_outsl: hd64461_outsl,
mv_readb: generic_readb,
mv_readw: generic_readw,
mv_readl: generic_readl,
mv_writeb: generic_writeb,
mv_writew: generic_writew,
mv_writel: generic_writel,
mv_irq_demux: hd64461_irq_demux,
mv_rtc_gettimeofday: sh_rtc_gettimeofday,
mv_rtc_settimeofday: sh_rtc_settimeofday,
mv_hw_hp600: 1,
mv_hw_hp690: 1,
mv_hw_hd64461: 1,
};
ALIAS_MV(hp690)
#
# Makefile for the STMicroelectronics Overdrive specific parts of the kernel
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := mach.o setup.o io.o irq.o led.o time.o
obj-$(CONFIG_PCI) += fpga.o galileo.o pcidma.o
/*
* Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* This file handles programming up the Altera Flex10K that interfaces to
* the Galileo, and does the PS/2 keyboard and mouse
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <asm/overdriver/gt64111.h>
#include <asm/overdrive/overdrive.h>
#include <asm/overdrive/fpga.h>
#define FPGA_NotConfigHigh() (*FPGA_ControlReg) = (*FPGA_ControlReg) | ENABLE_FPGA_BIT
#define FPGA_NotConfigLow() (*FPGA_ControlReg) = (*FPGA_ControlReg) & RESET_FPGA_MASK
/* I need to find out what (if any) the real delay factor here is */
/* The delay is definately not critical */
#define long_delay() {int i;for(i=0;i<10000;i++);}
#define short_delay() {int i;for(i=0;i<100;i++);}
static void __init program_overdrive_fpga(const unsigned char *fpgacode,
int size)
{
int timeout = 0;
int i, j;
unsigned char b;
static volatile unsigned char *FPGA_ControlReg =
(volatile unsigned char *) (OVERDRIVE_CTRL);
static volatile unsigned char *FPGA_ProgramReg =
(volatile unsigned char *) (FPGA_DCLK_ADDRESS);
printk("FPGA: Commencing FPGA Programming\n");
/* The PCI reset but MUST be low when programming the FPGA !!! */
b = (*FPGA_ControlReg) & RESET_PCI_MASK;
(*FPGA_ControlReg) = b;
/* Prepare FPGA to program */
FPGA_NotConfigHigh();
long_delay();
FPGA_NotConfigLow();
short_delay();
while ((*FPGA_ProgramReg & FPGA_NOT_STATUS) != 0) {
printk("FPGA: Waiting for NotStatus to go Low ... \n");
}
FPGA_NotConfigHigh();
/* Wait for FPGA "ready to be programmed" signal */
printk("FPGA: Waiting for NotStatus to go high (FPGA ready)... \n");
for (timeout = 0;
(((*FPGA_ProgramReg & FPGA_NOT_STATUS) == 0)
&& (timeout < FPGA_TIMEOUT)); timeout++);
/* Check if timeout condition occured - i.e. an error */
if (timeout == FPGA_TIMEOUT) {
printk
("FPGA: Failed to program - Timeout waiting for notSTATUS to go high\n");
return;
}
printk("FPGA: Copying data to FPGA ... %d bytes\n", size);
/* Copy array to FPGA - bit at a time */
for (i = 0; i < size; i++) {
volatile unsigned w = 0;
for (j = 0; j < 8; j++) {
*FPGA_ProgramReg = (fpgacode[i] >> j) & 0x01;
short_delay();
}
if ((i & 0x3ff) == 0) {
printk(".");
}
}
/* Waiting for CONFDONE to go high - means the program is complete */
for (timeout = 0;
(((*FPGA_ProgramReg & FPGA_CONFDONE) == 0)
&& (timeout < FPGA_TIMEOUT)); timeout++) {
*FPGA_ProgramReg = 0x0;
long_delay();
}
if (timeout == FPGA_TIMEOUT) {
printk
("FPGA: Failed to program - Timeout waiting for CONFDONE to go high\n");
return;
} else { /* Clock another 10 times - gets the device into a working state */
for (i = 0; i < 10; i++) {
*FPGA_ProgramReg = 0x0;
short_delay();
}
}
printk("FPGA: Programming complete\n");
}
static const unsigned char __init fpgacode[] = {
#include "./overdrive.ttf" /* Code from maxplus2 compiler */
, 0, 0
};
int __init init_overdrive_fpga(void)
{
program_overdrive_fpga(fpgacode, sizeof(fpgacode));
return 0;
}
This diff is collapsed.
/*
* Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* This file contains the I/O routines for use on the overdrive board
*
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/addrspace.h>
#include <asm/overdrive/overdrive.h>
/*
* readX/writeX() are used to access memory mapped devices. On some
* architectures the memory mapped IO stuff needs to be accessed
* differently. On the SuperH architecture, we just read/write the
* memory location directly.
*/
#define dprintk(x...)
/* Translates an IO address to where it is mapped in memory */
#define io_addr(x) (((unsigned)(x))|PCI_GTIO_BASE)
unsigned char od_inb(unsigned long port)
{
dprintk("od_inb(%x)\n", port);
return readb(io_addr(port)) & 0xff;
}
unsigned short od_inw(unsigned long port)
{
dprintk("od_inw(%x)\n", port);
return readw(io_addr(port)) & 0xffff;
}
unsigned int od_inl(unsigned long port)
{
dprintk("od_inl(%x)\n", port);
return readl(io_addr(port));
}
void od_outb(unsigned char value, unsigned long port)
{
dprintk("od_outb(%x, %x)\n", value, port);
writeb(value, io_addr(port));
}
void od_outw(unsigned short value, unsigned long port)
{
dprintk("od_outw(%x, %x)\n", value, port);
writew(value, io_addr(port));
}
void od_outl(unsigned int value, unsigned long port)
{
dprintk("od_outl(%x, %x)\n", value, port);
writel(value, io_addr(port));
}
/* This is horrible at the moment - needs more work to do something sensible */
#define IO_DELAY() udelay(10)
#define OUT_DELAY(x,type) \
void od_out##x##_p(unsigned type value,unsigned long port){out##x(value,port);IO_DELAY();}
#define IN_DELAY(x,type) \
unsigned type od_in##x##_p(unsigned long port) {unsigned type tmp=in##x(port);IO_DELAY();return tmp;}
OUT_DELAY(b,char)
OUT_DELAY(w,short)
OUT_DELAY(l,int)
IN_DELAY(b,char)
IN_DELAY(w,short)
IN_DELAY(l,int)
/* Now for the string version of these functions */
void od_outsb(unsigned long port, const void *addr, unsigned long count)
{
int i;
unsigned char *p = (unsigned char *) addr;
for (i = 0; i < count; i++, p++) {
outb(*p, port);
}
}
void od_insb(unsigned long port, void *addr, unsigned long count)
{
int i;
unsigned char *p = (unsigned char *) addr;
for (i = 0; i < count; i++, p++) {
*p = inb(port);
}
}
/* For the 16 and 32 bit string functions, we have to worry about alignment.
* The SH does not do unaligned accesses, so we have to read as bytes and
* then write as a word or dword.
* This can be optimised a lot more, especially in the case where the data
* is aligned
*/
void od_outsw(unsigned long port, const void *addr, unsigned long count)
{
int i;
unsigned short tmp;
unsigned char *p = (unsigned char *) addr;
for (i = 0; i < count; i++, p += 2) {
tmp = (*p) | ((*(p + 1)) << 8);
outw(tmp, port);
}
}
void od_insw(unsigned long port, void *addr, unsigned long count)
{
int i;
unsigned short tmp;
unsigned char *p = (unsigned char *) addr;
for (i = 0; i < count; i++, p += 2) {
tmp = inw(port);
p[0] = tmp & 0xff;
p[1] = (tmp >> 8) & 0xff;
}
}
void od_outsl(unsigned long port, const void *addr, unsigned long count)
{
int i;
unsigned tmp;
unsigned char *p = (unsigned char *) addr;
for (i = 0; i < count; i++, p += 4) {
tmp = (*p) | ((*(p + 1)) << 8) | ((*(p + 2)) << 16) |
((*(p + 3)) << 24);
outl(tmp, port);
}
}
void od_insl(unsigned long port, void *addr, unsigned long count)
{
int i;
unsigned tmp;
unsigned char *p = (unsigned char *) addr;
for (i = 0; i < count; i++, p += 4) {
tmp = inl(port);
p[0] = tmp & 0xff;
p[1] = (tmp >> 8) & 0xff;
p[2] = (tmp >> 16) & 0xff;
p[3] = (tmp >> 24) & 0xff;
}
}
/*
* Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Looks after interrupts on the overdrive board.
*
* Bases on the IPR irq system
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/overdrive/overdrive.h>
struct od_data {
int overdrive_irq;
int irq_mask;
};
#define NUM_EXTERNAL_IRQS 16
#define EXTERNAL_IRQ_NOT_IN_USE (-1)
#define EXTERNAL_IRQ_NOT_ASSIGNED (-1)
/*
* This table is used to determine what to program into the FPGA's CT register
* for the specified Linux IRQ.
*
* The irq_mask gives the interrupt number from the PCI board (PCI_Int(6:0))
* but is one greater than that because the because the FPGA treats 0
* as disabled, a value of 1 asserts PCI_Int0, and so on.
*
* The overdrive_irq specifies which of the eight interrupt sources generates
* that interrupt, and but is multiplied by four to give the bit offset into
* the CT register.
*
* The seven interrupts levels (SH4 IRL's) we have available here is hardwired
* by the EPLD. The assignments here of which PCI interrupt generates each
* level is arbitary.
*/
static struct od_data od_data_table[NUM_EXTERNAL_IRQS] = {
/* overdrive_irq , irq_mask */
{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 0 */
{EXTERNAL_IRQ_NOT_ASSIGNED, 7}, /* 1 */
{EXTERNAL_IRQ_NOT_ASSIGNED, 6}, /* 2 */
{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 3 */
{EXTERNAL_IRQ_NOT_ASSIGNED, 5}, /* 4 */
{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 5 */
{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 6 */
{EXTERNAL_IRQ_NOT_ASSIGNED, 4}, /* 7 */
{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 8 */
{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 9 */
{EXTERNAL_IRQ_NOT_ASSIGNED, 3}, /* 10 */
{EXTERNAL_IRQ_NOT_ASSIGNED, 2}, /* 11 */
{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 12 */
{EXTERNAL_IRQ_NOT_ASSIGNED, 1}, /* 13 */
{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 14 */
{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE} /* 15 */
};
static void set_od_data(int overdrive_irq, int irq)
{
if (irq >= NUM_EXTERNAL_IRQS || irq < 0)
return;
od_data_table[irq].overdrive_irq = overdrive_irq << 2;
}
static void enable_od_irq(unsigned int irq);
void disable_od_irq(unsigned int irq);
/* shutdown is same as "disable" */
#define shutdown_od_irq disable_od_irq
static void mask_and_ack_od(unsigned int);
static void end_od_irq(unsigned int irq);
static unsigned int startup_od_irq(unsigned int irq)
{
enable_od_irq(irq);
return 0; /* never anything pending */
}
static struct hw_interrupt_type od_irq_type = {
"Overdrive-IRQ",
startup_od_irq,
shutdown_od_irq,
enable_od_irq,
disable_od_irq,
mask_and_ack_od,
end_od_irq
};
static void disable_od_irq(unsigned int irq)
{
unsigned val, flags;
int overdrive_irq;
unsigned mask;
/* Not a valid interrupt */
if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
return;
/* Is is necessary to use a cli here? Would a spinlock not be
* mroe efficient?
*/
local_irq_save(flags);
overdrive_irq = od_data_table[irq].overdrive_irq;
if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) {
mask = ~(0x7 << overdrive_irq);
val = ctrl_inl(OVERDRIVE_INT_CT);
val &= mask;
ctrl_outl(val, OVERDRIVE_INT_CT);
}
local_irq_restore(flags);
}
static void enable_od_irq(unsigned int irq)
{
unsigned val, flags;
int overdrive_irq;
unsigned mask;
/* Not a valid interrupt */
if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
return;
/* Set priority in OD back to original value */
local_irq_save(flags);
/* This one is not in use currently */
overdrive_irq = od_data_table[irq].overdrive_irq;
if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) {
val = ctrl_inl(OVERDRIVE_INT_CT);
mask = ~(0x7 << overdrive_irq);
val &= mask;
mask = od_data_table[irq].irq_mask << overdrive_irq;
val |= mask;
ctrl_outl(val, OVERDRIVE_INT_CT);
}
local_irq_restore(flags);
}
/* this functions sets the desired irq handler to be an overdrive type */
static void __init make_od_irq(unsigned int irq)
{
disable_irq_nosync(irq);
irq_desc[irq].handler = &od_irq_type;
disable_od_irq(irq);
}
static void mask_and_ack_od(unsigned int irq)
{
disable_od_irq(irq);
}
static void end_od_irq(unsigned int irq)
{
enable_od_irq(irq);
}
void __init init_overdrive_irq(void)
{
int i;
/* Disable all interrupts */
ctrl_outl(0, OVERDRIVE_INT_CT);
/* Update interrupt pin mode to use encoded interrupts */
i = ctrl_inw(INTC_ICR);
i &= ~INTC_ICR_IRLM;
ctrl_outw(i, INTC_ICR);
for (i = 0; i < NUM_EXTERNAL_IRQS; i++) {
if (od_data_table[i].irq_mask != EXTERNAL_IRQ_NOT_IN_USE) {
make_od_irq(i);
} else if (i != 15) { // Cannot use imask on level 15
make_imask_irq(i);
}
}
/* Set up the interrupts */
set_od_data(OVERDRIVE_PCI_INTA, OVERDRIVE_PCI_IRQ1);
set_od_data(OVERDRIVE_PCI_INTB, OVERDRIVE_PCI_IRQ2);
set_od_data(OVERDRIVE_AUDIO_INT, OVERDRIVE_ESS_IRQ);
}
/*
* linux/arch/sh/overdrive/led.c
*
* Copyright (C) 1999 Stuart Menefy <stuart.menefy@st.com>
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* This file contains an Overdrive specific LED feature.
*/
#include <linux/config.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/overdrive/overdrive.h>
static void mach_led(int position, int value)
{
unsigned long flags;
unsigned long reg;
local_irq_save(flags);
reg = readl(OVERDRIVE_CTRL);
if (value) {
reg |= (1<<3);
} else {
reg &= ~(1<<3);
}
writel(reg, OVERDRIVE_CTRL);
local_irq_restore(flags);
}
#ifdef CONFIG_HEARTBEAT
#include <linux/sched.h>
/* acts like an actual heart beat -- ie thump-thump-pause... */
void heartbeat_od(void)
{
static unsigned cnt = 0, period = 0, dist = 0;
if (cnt == 0 || cnt == dist)
mach_led( -1, 1);
else if (cnt == 7 || cnt == dist+7)
mach_led( -1, 0);
if (++cnt > period) {
cnt = 0;
/* The hyperbolic function below modifies the heartbeat period
* length in dependency of the current (5min) load. It goes
* through the points f(0)=126, f(1)=86, f(5)=51,
* f(inf)->30. */
period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
dist = period / 4;
}
}
#endif /* CONFIG_HEARTBEAT */
/*
* linux/arch/sh/overdrive/mach.c
*
* Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Machine vector for the STMicroelectronics Overdrive
*/
#include <linux/init.h>
#include <asm/machvec.h>
#include <asm/rtc.h>
#include <asm/machvec_init.h>
#include <asm/io_unknown.h>
#include <asm/io_generic.h>
#include <asm/overdrive/io.h>
void heartbeat_od(void);
void init_overdrive_irq(void);
void galileo_pcibios_init(void);
/*
* The Machine Vector
*/
struct sh_machine_vector mv_od __initmv = {
mv_nr_irqs: 48,
mv_inb: od_inb,
mv_inw: od_inw,
mv_inl: od_inl,
mv_outb: od_outb,
mv_outw: od_outw,
mv_outl: od_outl,
mv_inb_p: od_inb_p,
mv_inw_p: od_inw_p,
mv_inl_p: od_inl_p,
mv_outb_p: od_outb_p,
mv_outw_p: od_outw_p,
mv_outl_p: od_outl_p,
mv_insb: od_insb,
mv_insw: od_insw,
mv_insl: od_insl,
mv_outsb: od_outsb,
mv_outsw: od_outsw,
mv_outsl: od_outsl,
mv_readb: generic_readb,
mv_readw: generic_readw,
mv_readl: generic_readl,
mv_writeb: generic_writeb,
mv_writew: generic_writew,
mv_writel: generic_writel,
mv_ioremap: generic_ioremap,
mv_iounmap: generic_iounmap,
mv_isa_port2addr: generic_isa_port2addr,
#ifdef CONFIG_PCI
mv_init_irq: init_overdrive_irq,
#endif
#ifdef CONFIG_HEARTBEAT
mv_heartbeat: heartbeat_od,
#endif
};
ALIAS_MV(od)
/*
* Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Dynamic DMA mapping support.
*
* On the overdrive, we can only DMA from memory behind the PCI bus!
* this means that all DMA'able memory must come from there.
* this restriction will not apply to later boards.
*/
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <asm/io.h>
void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t * dma_handle)
{
void *ret;
int gfp = GFP_ATOMIC;
printk("BUG: pci_alloc_consistent() called - not yet supported\n");
/* We ALWAYS need DMA memory on the overdrive hardware,
* due to it's extreme wierdness
* Need to flush the cache here as well, since the memory
* can still be seen through the cache!
*/
gfp |= GFP_DMA;
ret = (void *) __get_free_pages(gfp, get_order(size));
if (ret != NULL) {
memset(ret, 0, size);
*dma_handle = virt_to_bus(ret);
}
return ret;
}
void pci_free_consistent(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle)
{
free_pages((unsigned long) vaddr, get_order(size));
}
/*
* arch/sh/overdrive/setup.c
*
* Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* STMicroelectronics Overdrive Support.
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/overdrive/overdrive.h>
#include <asm/overdrive/fpga.h>
extern void od_time_init(void);
const char *get_system_type(void)
{
return "SH7750 Overdrive";
}
/*
* Initialize the board
*/
int __init platform_setup(void)
{
#ifdef CONFIG_PCI
init_overdrive_fpga();
galileo_init();
#endif
board_time_init = od_time_init;
/* Enable RS232 receive buffers */
writel(0x1e, OVERDRIVE_CTRL);
}
/*
* arch/sh/boards/overdrive/time.c
*
* Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
* Copyright (C) 2002 Paul Mundt (lethal@chaoticdreams.org)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* STMicroelectronics Overdrive Support.
*/
void od_time_init(void)
{
struct frqcr_data {
unsigned short frqcr;
struct {
unsigned char multiplier;
unsigned char divisor;
} factor[3];
};
static struct frqcr_data st40_frqcr_table[] = {
{ 0x000, {{1,1}, {1,1}, {1,2}}},
{ 0x002, {{1,1}, {1,1}, {1,4}}},
{ 0x004, {{1,1}, {1,1}, {1,8}}},
{ 0x008, {{1,1}, {1,2}, {1,2}}},
{ 0x00A, {{1,1}, {1,2}, {1,4}}},
{ 0x00C, {{1,1}, {1,2}, {1,8}}},
{ 0x011, {{1,1}, {2,3}, {1,6}}},
{ 0x013, {{1,1}, {2,3}, {1,3}}},
{ 0x01A, {{1,1}, {1,2}, {1,4}}},
{ 0x01C, {{1,1}, {1,2}, {1,8}}},
{ 0x023, {{1,1}, {2,3}, {1,3}}},
{ 0x02C, {{1,1}, {1,2}, {1,8}}},
{ 0x048, {{1,2}, {1,2}, {1,4}}},
{ 0x04A, {{1,2}, {1,2}, {1,6}}},
{ 0x04C, {{1,2}, {1,2}, {1,8}}},
{ 0x05A, {{1,2}, {1,3}, {1,6}}},
{ 0x05C, {{1,2}, {1,3}, {1,6}}},
{ 0x063, {{1,2}, {1,4}, {1,4}}},
{ 0x06C, {{1,2}, {1,4}, {1,8}}},
{ 0x091, {{1,3}, {1,3}, {1,6}}},
{ 0x093, {{1,3}, {1,3}, {1,6}}},
{ 0x0A3, {{1,3}, {1,6}, {1,6}}},
{ 0x0DA, {{1,4}, {1,4}, {1,8}}},
{ 0x0DC, {{1,4}, {1,4}, {1,8}}},
{ 0x0EC, {{1,4}, {1,8}, {1,8}}},
{ 0x123, {{1,4}, {1,4}, {1,8}}},
{ 0x16C, {{1,4}, {1,8}, {1,8}}},
};
struct memclk_data {
unsigned char multiplier;
unsigned char divisor;
};
static struct memclk_data st40_memclk_table[8] = {
{1,1}, // 000
{1,2}, // 001
{1,3}, // 010
{2,3}, // 011
{1,4}, // 100
{1,6}, // 101
{1,8}, // 110
{1,8} // 111
};
unsigned long pvr;
/*
* This should probably be moved into the SH3 probing code, and then
* use the processor structure to determine which CPU we are running
* on.
*/
pvr = ctrl_inl(CCN_PVR);
printk("PVR %08x\n", pvr);
if (((pvr >> CCN_PVR_CHIP_SHIFT) & CCN_PVR_CHIP_MASK) == CCN_PVR_CHIP_ST40STB1) {
/*
* Unfortunatly the STB1 FRQCR values are different from the
* 7750 ones.
*/
struct frqcr_data *d;
int a;
unsigned long memclkcr;
struct memclk_data *e;
for (a=0; a<ARRAY_SIZE(st40_frqcr_table); a++) {
d = &st40_frqcr_table[a];
if (d->frqcr == (frqcr & 0x1ff))
break;
}
if (a == ARRAY_SIZE(st40_frqcr_table)) {
d = st40_frqcr_table;
printk("ERROR: Unrecognised FRQCR value, using default multipliers\n");
}
memclkcr = ctrl_inl(CLOCKGEN_MEMCLKCR);
e = &st40_memclk_table[memclkcr & MEMCLKCR_RATIO_MASK];
printk("Clock multipliers: CPU: %d/%d Bus: %d/%d Mem: %d/%d Periph: %d/%d\n",
d->factor[0].multiplier, d->factor[0].divisor,
d->factor[1].multiplier, d->factor[1].divisor,
e->multiplier, e->divisor,
d->factor[2].multiplier, d->factor[2].divisor);
current_cpu_data.master_clock = current_cpu_data.module_clock *
d->factor[2].divisor /
d->factor[2].multiplier;
current_cpu_data.bus_clock = current_cpu_data.master_clock *
d->factor[1].multiplier /
d->factor[1].divisor;
current_cpu_data.memory_clock = current_cpu_data.master_clock *
e->multiplier / e->divisor;
current_cpu_data.cpu_clock = current_cpu_data.master_clock *
d->factor[0].multiplier /
d->factor[0].divisor;
}
#
# Makefile for the Sega Saturn specific parts of the kernel
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := mach.o setup.o io.o irq.o
obj-$(CONFIG_SMP) += smp.o
/*
* arch/sh/boards/saturn/io.c
*
* I/O routines for the Sega Saturn.
*
* Copyright (C) 2002 Paul Mundt
*
* Released under the terms of the GNU GPL v2.0.
*/
#include <asm/saturn/io.h>
#include <asm/machvec.h>
unsigned long saturn_isa_port2addr(unsigned long offset)
{
return offset;
}
void *saturn_ioremap(unsigned long offset, unsigned long size)
{
return (void *)offset;
}
void saturn_iounmap(void *addr)
{
}
/*
* arch/sh/boards/saturn/irq.c
*
* Copyright (C) 2002 Paul Mundt
*
* Released under the terms of the GNU GPL v2.0.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/saturn/saturn.h>
#include <asm/saturn/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
/*
* Interrupts map out as follows:
*
* Vector Name Mask
*
* 64 VBLANKIN 0x0001
* 65 VBLANKOUT 0x0002
* 66 HBLANKIN 0x0004
* 67 TIMER0 0x0008
* 68 TIMER1 0x0010
* 69 DSPEND 0x0020
* 70 SOUNDREQUEST 0x0040
* 71 SYSTEMMANAGER 0x0080
* 72 PAD 0x0100
* 73 LEVEL2DMAEND 0x0200
* 74 LEVEL1DMAEND 0x0400
* 75 LEVEL0DMAEND 0x0800
* 76 DMAILLEGAL 0x1000
* 77 SRITEDRAWEND 0x2000
* 78 ABUS 0x8000
*
*/
#define SATURN_IRQ_MIN 64 /* VBLANKIN */
#define SATURN_IRQ_MAX 78 /* ABUS */
#define SATURN_IRQ_MASK 0xbfff
static inline u32 saturn_irq_mask(unsigned int irq_nr)
{
u32 mask;
mask = (1 << (irq_nr - SATURN_IRQ_MIN));
mask <<= (irq_nr == SATURN_IRQ_MAX);
mask &= SATURN_IRQ_MASK;
return mask;
}
static inline void mask_saturn_irq(unsigned int irq_nr)
{
u32 mask;
mask = ctrl_inl(SATURN_IMR);
mask |= saturn_irq_mask(irq_nr);
ctrl_outl(mask, SATURN_IMR);
}
static inline void unmask_saturn_irq(unsigned int irq_nr)
{
u32 mask;
mask = ctrl_inl(SATURN_IMR);
mask &= ~saturn_irq_mask(irq_nr);
ctrl_outl(SATURN_IMR);
}
static void disable_saturn_irq(unsigned int irq_nr)
{
mask_saturn_irq(irq_nr);
}
static void enable_saturn_irq(unsigned int irq_nr)
{
unmask_saturn_irq(irq_nr);
}
static void mask_and_ack_saturn_irq(unsigned int irq_nr)
{
mask_saturn_irq(irq_nr);
}
static void end_saturn_irq(unsigned int irq_nr)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
unmask_saturn_irq(irq_nr);
}
static unsigned int startup_saturn_irq(unsigned int irq_nr)
{
unmask_saturn_irq(irq_nr);
return 0;
}
static void shutdown_saturn_irq(unsigned int irq_nr)
{
mask_saturn_irq(irq_nr);
}
static struct hw_interrupt_type saturn_int = {
typename: "Saturn",
enable: enable_saturn_irq,
disable: disable_saturn_irq,
ack: mask_and_ack_saturn_irq,
end: end_saturn_irq,
startup: startup_saturn_irq,
shutdown: shutdown_saturn_irq,
};
int saturn_irq_demux(int irq_nr)
{
/* FIXME */
return irq_nr;
}
/*
* arch/sh/boards/saturn/mach.c
*
* machvec definitions for the Sega Saturn.
*
* Copyright (C) 2002 Paul Mundt
*
* Released under the terms of the GNU GPL v2.0.
*/
#include <asm/io.h>
#include <asm/io_generic.h>
#include <asm/machvec.h>
#include <asm/machvec_init.h>
#include <asm/rtc.h>
#include <asm/saturn/io.h>
/*
* The Machine Vector
*/
struct sh_machine_vector mv_saturn __initmv = {
mv_nr_irqs: 80, /* Fix this later */
mv_inb: generic_inb,
mv_inw: generic_inw,
mv_inl: generic_inl,
mv_outb: generic_outb,
mv_outw: generic_outw,
mv_outl: generic_outl,
mv_inb_p: generic_inb_p,
mv_inw_p: generic_inw_p,
mv_inl_p: generic_inl_p,
mv_outb_p: generic_outb_p,
mv_outw_p: generic_outw_p,
mv_outl_p: generic_outl_p,
mv_insb: generic_insb,
mv_insw: generic_insw,
mv_insl: generic_insl,
mv_outsb: generic_outsb,
mv_outsw: generic_outsw,
mv_outsl: generic_outsl,
mv_readb: generic_readb,
mv_readw: generic_readw,
mv_readl: generic_readl,
mv_writeb: generic_writeb,
mv_writew: generic_writew,
mv_writel: generic_writel,
mv_isa_port2addr: saturn_isa_port2addr,
mv_irq_demux: saturn_irq_demux,
mv_ioremap: saturn_ioremap,
mv_iounmap: saturn_iounmap,
mv_hw_saturn: 1,
};
ALIAS_MV(saturn)
/*
* arch/sh/boards/saturn/setup.c
*
* Hardware support for the Sega Saturn.
*
* Copyright (c) 2002 Paul Mundt
*
* Released under the terms of the GNU GPL v2.0.
*/
#include <linux/kernel.h>
#include <linux/init.h>
const char *get_system_type(void)
{
return "Sega Saturn";
}
int __init platform_setup(void)
{
return 0;
}
/*
* arch/sh/boards/saturn/smp.c
*
* SMP support for the Sega Saturn.
*
* Copyright (c) 2002 Paul Mundt
*
* Released under the terms of the GNU GPL v2.0.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <asm/saturn/smpc.h>
extern void start_secondary(void);
void __smp_send_ipi(unsigned int cpu, unsigned int action)
{
/* Nothing here yet .. */
}
unsigned int __smp_probe_cpus(void)
{
/*
* This is just a straightforward master/slave configuration,
* and probing isn't really supported..
*/
return 2;
}
/*
* We're only allowed to do byte-access to SMPC registers. In
* addition to which, we treat them as write-only, since
* reading from them will return undefined data.
*/
static inline void smpc_slave_off(unsigned int cpu)
{
smpc_barrier();
ctrl_outb(1, SMPC_STATUS);
ctrl_outb(SMPC_CMD_SSHOFF, SMPC_COMMAND);
smpc_barrier();
}
static inline void smpc_slave_on(unsigned int cpu)
{
ctrl_outb(1, SMPC_STATUS);
ctrl_outb(SMPC_CMD_SSHON, SMPC_COMMAND);
smpc_barrier();
}
void __smp_slave_init(unsigned int cpu)
{
register unsigned long vbr;
void **entry;
__asm__ __volatile__ ("stc vbr, %0\n\t" : "=r" (vbr));
entry = (void **)(vbr + 0x310 + 0x94);
smpc_slave_stop(cpu);
*(void **)entry = (void *)start_secondary;
smpc_slave_start(cpu);
}
#
# Makefile for the 770x SolutionEngine specific parts of the kernel
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := mach.o setup.o io.o irq.o led.o
/* $Id: io_se.c,v 1.12 2001/08/11 01:23:28 jzs Exp $ /* $Id: io.c,v 1.1.2.2 2002/01/20 05:03:25 mrbrown Exp $
* *
* linux/arch/sh/kernel/io_se.c * linux/arch/sh/kernel/io_se.c
* *
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/hitachi_se.h> #include <asm/se/se.h>
/* SH pcmcia io window base, start and end. */ /* SH pcmcia io window base, start and end. */
int sh_pcic_io_wbase = 0xb8400000; int sh_pcic_io_wbase = 0xb8400000;
......
/* $Id: irq.c,v 1.1.2.2 2002/10/29 00:56:09 lethal Exp $
*
* linux/arch/sh/boards/se/770x/irq.c
*
* Copyright (C) 2000 Kazumoto Kojima
*
* Hitachi SolutionEngine Support.
*
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/hitachi_se.h>
/*
* Initialize IRQ setting
*/
void __init init_se_IRQ(void)
{
/*
* Super I/O (Just mimic PC):
* 1: keyboard
* 3: serial 0
* 4: serial 1
* 5: printer
* 6: floppy
* 8: rtc
* 12: mouse
* 14: ide0
*/
make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14);
make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12);
make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8);
make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6);
make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5);
make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4);
make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3);
make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1);
make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */
make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */
make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */
make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */
make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */
/* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
/* NOTE: #2 and #13 are not used on PC */
make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */
make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */
}
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <asm/hitachi_se.h> #include <asm/se/se.h>
static void mach_led(int position, int value) static void mach_led(int position, int value)
{ {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <asm/rtc.h> #include <asm/rtc.h>
#include <asm/machvec_init.h> #include <asm/machvec_init.h>
#include <asm/io_se.h> #include <asm/se/io.h>
void heartbeat_se(void); void heartbeat_se(void);
void setup_se(void); void setup_se(void);
...@@ -27,58 +27,51 @@ void init_se_IRQ(void); ...@@ -27,58 +27,51 @@ void init_se_IRQ(void);
*/ */
struct sh_machine_vector mv_se __initmv = { struct sh_machine_vector mv_se __initmv = {
.mv_name = "SolutionEngine", #if defined(CONFIG_CPU_SH4)
mv_nr_irqs: 48,
#if defined(__SH4__)
.mv_nr_irqs = 48,
#elif defined(CONFIG_CPU_SUBTYPE_SH7708) #elif defined(CONFIG_CPU_SUBTYPE_SH7708)
.mv_nr_irqs = 32, mv_nr_irqs: 32,
#elif defined(CONFIG_CPU_SUBTYPE_SH7709) #elif defined(CONFIG_CPU_SUBTYPE_SH7709)
.mv_nr_irqs = 61, mv_nr_irqs: 61,
#endif #endif
.mv_inb = se_inb, mv_inb: se_inb,
.mv_inw = se_inw, mv_inw: se_inw,
.mv_inl = se_inl, mv_inl: se_inl,
.mv_outb = se_outb, mv_outb: se_outb,
.mv_outw = se_outw, mv_outw: se_outw,
.mv_outl = se_outl, mv_outl: se_outl,
.mv_inb_p = se_inb_p, mv_inb_p: se_inb_p,
.mv_inw_p = se_inw, mv_inw_p: se_inw,
.mv_inl_p = se_inl, mv_inl_p: se_inl,
.mv_outb_p = se_outb_p, mv_outb_p: se_outb_p,
.mv_outw_p = se_outw, mv_outw_p: se_outw,
.mv_outl_p = se_outl, mv_outl_p: se_outl,
.mv_insb = se_insb, mv_insb: se_insb,
.mv_insw = se_insw, mv_insw: se_insw,
.mv_insl = se_insl, mv_insl: se_insl,
.mv_outsb = se_outsb, mv_outsb: se_outsb,
.mv_outsw = se_outsw, mv_outsw: se_outsw,
.mv_outsl = se_outsl, mv_outsl: se_outsl,
.mv_readb = se_readb, mv_readb: se_readb,
.mv_readw = se_readw, mv_readw: se_readw,
.mv_readl = se_readl, mv_readl: se_readl,
.mv_writeb = se_writeb, mv_writeb: se_writeb,
.mv_writew = se_writew, mv_writew: se_writew,
.mv_writel = se_writel, mv_writel: se_writel,
.mv_ioremap = generic_ioremap, mv_ioremap: generic_ioremap,
.mv_iounmap = generic_iounmap, mv_iounmap: generic_iounmap,
.mv_isa_port2addr = se_isa_port2addr, mv_isa_port2addr: se_isa_port2addr,
.mv_init_arch = setup_se, mv_init_irq: init_se_IRQ,
.mv_init_irq = init_se_IRQ,
#ifdef CONFIG_HEARTBEAT #ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_se, mv_heartbeat: heartbeat_se,
#endif #endif
mv_hw_se: 1,
.mv_rtc_gettimeofday = sh_rtc_gettimeofday,
.mv_rtc_settimeofday = sh_rtc_settimeofday,
.mv_hw_se = 1,
}; };
ALIAS_MV(se) ALIAS_MV(se)
/* $Id: setup_se.c,v 1.6 2000/05/14 08:41:25 gniibe Exp $ /* $Id: setup.c,v 1.1.2.4 2002/03/02 21:57:07 lethal Exp $
* *
* linux/arch/sh/kernel/setup_se.c * linux/arch/sh/boards/se/770x/setup.c
* *
* Copyright (C) 2000 Kazumoto Kojima * Copyright (C) 2000 Kazumoto Kojima
* *
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
#include <linux/hdreg.h> #include <linux/hdreg.h>
#include <linux/ide.h> #include <linux/ide.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/hitachi_se.h> #include <asm/se/se.h>
#include <asm/smc37c93x.h> #include <asm/se/smc37c93x.h>
/* /*
* Configure the Super I/O chip * Configure the Super I/O chip
...@@ -70,49 +70,15 @@ static void __init init_smsc(void) ...@@ -70,49 +70,15 @@ static void __init init_smsc(void)
outb_p(CONFIG_EXIT, CONFIG_PORT); outb_p(CONFIG_EXIT, CONFIG_PORT);
} }
/* const char *get_system_type(void)
* Initialize IRQ setting
*/
void __init init_se_IRQ(void)
{ {
/* return "SolutionEngine";
* Super I/O (Just mimic PC):
* 1: keyboard
* 3: serial 0
* 4: serial 1
* 5: printer
* 6: floppy
* 8: rtc
* 12: mouse
* 14: ide0
*/
make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14);
make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12);
make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8);
make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6);
make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5);
make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4);
make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3);
make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1);
make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */
make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */
make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */
make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */
make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */
/* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
/* NOTE: #2 and #13 are not used on PC */
make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */
make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */
} }
/* /*
* Initialize the board * Initialize the board
*/ */
void __init setup_se(void) void __init platform_setup(void)
{ {
init_smsc(); init_smsc();
/* XXX: RTC setting comes here */ /* XXX: RTC setting comes here */
......
#
# Makefile for the 7751 SolutionEngine specific parts of the kernel
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := mach.o setup.o io.o irq.o led.o
obj-$(CONFIG_PCI) += pci.o
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/hitachi_7751se.h> #include <asm/se7751/se7751.h>
#include <asm/addrspace.h> #include <asm/addrspace.h>
#include <linux/pci.h> #include <linux/pci.h>
...@@ -97,7 +97,7 @@ shifted_port(unsigned long port) ...@@ -97,7 +97,7 @@ shifted_port(unsigned long port)
#define CHECK_SH7751_PCIIO(port) \ #define CHECK_SH7751_PCIIO(port) \
((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
#else #else
#define CHECK_SH_7751_PCIIO(port) (0) #define CHECK_SH7751_PCIIO(port) (0)
#endif #endif
/* /*
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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