Update of /cvsroot/linux-vax/kernel-2.4/arch/mips/gt64120/momenco_ocelot In directory usw-pr-cvs1:/tmp/cvs-serv20728/mips/gt64120/momenco_ocelot Added Files: Makefile dbg_io.c int-handler.S irq.c ocelot_pld.h pci.c prom.c reset.c setup.c Log Message: synch 2.4.15 commit 39 --- NEW FILE --- # # Makefile for Momentum's Ocelot board. # # 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). # .S.s: $(CPP) $(CFLAGS) $< -o $*.s .S.o: $(CC) $(CFLAGS) -c $< -o $*.o O_TARGET:= momenco_ocelot.o obj-y += int-handler.o irq.o pci.o prom.o reset.o setup.o obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o include $(TOPDIR)/Rules.make --- NEW FILE --- #include <linux/config.h> #if defined(CONFIG_REMOTE_DEBUG) /* --- CONFIG --- */ typedef unsigned char uint8; typedef unsigned int uint32; /* --- END OF CONFIG --- */ #define UART16550_BAUD_2400 2400 #define UART16550_BAUD_4800 4800 #define UART16550_BAUD_9600 9600 #define UART16550_BAUD_19200 19200 #define UART16550_BAUD_38400 38400 #define UART16550_BAUD_57600 57600 #define UART16550_BAUD_115200 115200 #define UART16550_PARITY_NONE 0 #define UART16550_PARITY_ODD 0x08 #define UART16550_PARITY_EVEN 0x18 #define UART16550_PARITY_MARK 0x28 #define UART16550_PARITY_SPACE 0x38 #define UART16550_DATA_5BIT 0x0 #define UART16550_DATA_6BIT 0x1 #define UART16550_DATA_7BIT 0x2 #define UART16550_DATA_8BIT 0x3 #define UART16550_STOP_1BIT 0x0 #define UART16550_STOP_2BIT 0x4 /* ----------------------------------------------------- */ /* === CONFIG === */ /* [jsun] we use the second serial port for kdb */ #define BASE 0xbd000020 #define MAX_BAUD 115200 /* === END OF CONFIG === */ #define REG_OFFSET 4 /* register offset */ #define OFS_RCV_BUFFER 0 #define OFS_TRANS_HOLD 0 #define OFS_SEND_BUFFER 0 #define OFS_INTR_ENABLE (1*REG_OFFSET) #define OFS_INTR_ID (2*REG_OFFSET) #define OFS_DATA_FORMAT (3*REG_OFFSET) #define OFS_LINE_CONTROL (3*REG_OFFSET) #define OFS_MODEM_CONTROL (4*REG_OFFSET) #define OFS_RS232_OUTPUT (4*REG_OFFSET) #define OFS_LINE_STATUS (5*REG_OFFSET) #define OFS_MODEM_STATUS (6*REG_OFFSET) #define OFS_RS232_INPUT (6*REG_OFFSET) #define OFS_SCRATCH_PAD (7*REG_OFFSET) #define OFS_DIVISOR_LSB (0*REG_OFFSET) #define OFS_DIVISOR_MSB (1*REG_OFFSET) /* memory-mapped read/write of the port */ #define UART16550_READ(y) (*((volatile uint8*)(BASE + y))) #define UART16550_WRITE(y, z) ((*((volatile uint8*)(BASE + y))) = z) void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) { /* disable interrupts */ UART16550_WRITE(OFS_INTR_ENABLE, 0); /* set up buad rate */ { uint32 divisor; /* set DIAB bit */ UART16550_WRITE(OFS_LINE_CONTROL, 0x80); /* set divisor */ divisor = MAX_BAUD / baud; UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff); UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8); /* clear DIAB bit */ UART16550_WRITE(OFS_LINE_CONTROL, 0x0); } /* set data format */ UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop); } static int remoteDebugInitialized = 0; uint8 getDebugChar(void) { if (!remoteDebugInitialized) { remoteDebugInitialized = 1; debugInit(UART16550_BAUD_38400, UART16550_DATA_8BIT, UART16550_PARITY_NONE, UART16550_STOP_1BIT); } while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0); return UART16550_READ(OFS_RCV_BUFFER); } int putDebugChar(uint8 byte) { if (!remoteDebugInitialized) { remoteDebugInitialized = 1; debugInit(UART16550_BAUD_9600, UART16550_DATA_8BIT, UART16550_PARITY_NONE, UART16550_STOP_1BIT); } while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0); UART16550_WRITE(OFS_SEND_BUFFER, byte); return 1; } #endif --- NEW FILE --- /* * Copyright 2001 MontaVista Software Inc. * Author: js...@mv... or js...@ju... * * First-level interrupt dispatcher for ocelot board. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ #include <linux/config.h> #include <asm/asm.h> #include <asm/mipsregs.h> #include <asm/addrspace.h> #include <asm/regdef.h> #include <asm/stackframe.h> /* * first level interrupt dispatcher for ocelot board - * We check for the timer first, then check PCI ints A and D. * Then check for serial IRQ and fall through. */ .align 5 NESTED(ocelot_handle_int, PT_SIZE, sp) SAVE_ALL CLI .set at mfc0 t0, CP0_CAUSE mfc0 t2, CP0_STATUS and t0, t2 andi t1, t0, STATUSF_IP2 /* int0 hardware line */ bnez t1, ll_pri_enet_irq andi t1, t0, STATUSF_IP3 /* int1 hardware line */ bnez t1, ll_sec_enet_irq andi t1, t0, STATUSF_IP4 /* int2 hardware line */ bnez t1, ll_uart1_irq andi t1, t0, STATUSF_IP5 /* int3 hardware line */ bnez t1, ll_cpci_irq andi t1, t0, STATUSF_IP6 /* int4 hardware line */ bnez t1, ll_galileo_irq andi t1, t0, STATUSF_IP7 /* cpu timer */ bnez t1, ll_cputimer_irq /* now look at the extended interrupts */ mfc0 t0, CP0_CAUSE cfc0 t1, CP0_S1_INTCONTROL /* shift the mask 8 bits left to line up the bits */ sll t2, t1, 8 and t0, t2 srl t0, t0, 16 andi t1, t0, STATUSF_IP8 /* int6 hardware line */ bnez t1, ll_pmc1_irq andi t1, t0, STATUSF_IP9 /* int7 hardware line */ bnez t1, ll_pmc2_irq andi t1, t0, STATUSF_IP10 /* int8 hardware line */ bnez t1, ll_cpci_abcd_irq andi t1, t0, STATUSF_IP11 /* int9 hardware line */ bnez t1, ll_uart2_irq .set reorder /* wrong alarm or masked ... */ j spurious_interrupt nop END(ocelot_handle_int) .align 5 ll_pri_enet_irq: li a0, 2 move a1, sp jal do_IRQ j ret_from_irq ll_sec_enet_irq: li a0, 3 move a1, sp jal do_IRQ j ret_from_irq ll_uart1_irq: li a0, 4 move a1, sp jal do_IRQ j ret_from_irq ll_cpci_irq: li a0, 5 move a1, sp jal do_IRQ j ret_from_irq ll_galileo_irq: li a0, 6 move a1, sp jal do_IRQ j ret_from_irq ll_cputimer_irq: li a0, 7 move a1, sp jal do_IRQ j ret_from_irq ll_pmc1_irq: li a0, 8 move a1, sp jal do_IRQ j ret_from_irq ll_pmc2_irq: li a0, 9 move a1, sp jal do_IRQ j ret_from_irq ll_cpci_abcd_irq: li a0, 10 move a1, sp jal do_IRQ j ret_from_irq ll_uart2_irq: li a0, 11 move a1, sp jal do_IRQ j ret_from_irq --- NEW FILE --- /* * Copyright (C) 2000 RidgeRun, Inc. * Author: RidgeRun, Inc. * gl...@ri..., sk...@ri..., st...@ri... * * Copyright 2001 MontaVista Software Inc. * Author: Jun Sun, js...@mv... or js...@ju... * Copyright (C) 2000, 2001 Ralf Baechle (ra...@gn...) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <linux/errno.h> #include <linux/init.h> #include <linux/kernel_stat.h> #include <linux/module.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/types.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/timex.h> #include <linux/slab.h> #include <linux/random.h> #include <linux/irq.h> #include <asm/bitops.h> #include <asm/bootinfo.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/mipsregs.h> #include <asm/system.h> static spinlock_t rm7000_irq_lock = SPIN_LOCK_UNLOCKED; /* Function for careful CP0 interrupt mask access */ static inline void modify_cp0_intmask(unsigned clr_mask_in, unsigned set_mask_in) { unsigned long status; unsigned clr_mask; unsigned set_mask; /* do the low 8 bits first */ clr_mask = 0xff & clr_mask_in; set_mask = 0xff & set_mask_in; status = read_32bit_cp0_register(CP0_STATUS); status &= ~((clr_mask & 0xFF) << 8); status |= (set_mask & 0xFF) << 8; write_32bit_cp0_register(CP0_STATUS, status); /* do the high 8 bits */ clr_mask = 0xff & (clr_mask_in >> 8); set_mask = 0xff & (set_mask_in >> 8); status = read_32bit_cp0_set1_register(CP0_S1_INTCONTROL); status &= ~((clr_mask & 0xFF) << 8); status |= (set_mask & 0xFF) << 8; write_32bit_cp0_set1_register(CP0_S1_INTCONTROL, status); } static inline void mask_irq(unsigned int irq) { modify_cp0_intmask(irq, 0); } static inline void unmask_irq(unsigned int irq) { modify_cp0_intmask(0, irq); } static void enable_cp7000_irq(unsigned int irq) { unsigned long flags; spin_lock_irqsave(&rm7000_irq_lock, flags); unmask_irq(1 << irq); spin_unlock_irqrestore(&rm7000_irq_lock, flags); } static unsigned int startup_cp7000_irq(unsigned int irq) { enable_cp7000_irq(irq); return 0; /* never anything pending */ } static void disable_cp7000_irq(unsigned int irq) { unsigned long flags; spin_lock_irqsave(&rm7000_irq_lock, flags); mask_irq(1 << irq); spin_unlock_irqrestore(&rm7000_irq_lock, flags); } #define shutdown_cp7000_irq disable_cp7000_irq static void mask_and_ack_cp7000_irq(unsigned int irq) { mask_irq(1 << irq); } static void end_cp7000_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) unmask_irq(1 << irq); } static struct hw_interrupt_type cp7000_hpcdma_irq_type = { "CP7000", startup_cp7000_irq, shutdown_cp7000_irq, enable_cp7000_irq, disable_cp7000_irq, mask_and_ack_cp7000_irq, end_cp7000_irq, NULL }; extern asmlinkage void ocelot_handle_int(void); extern void gt64120_irq_init(void); void __init init_IRQ(void) { int i; /* * Clear all of the interrupts while we change the able around a bit. * int-handler is not on bootstrap */ clear_cp0_status(ST0_IM | ST0_BEV); __cli(); /* Sets the first-level interrupt dispatcher. */ set_except_vector(0, ocelot_handle_int); init_generic_irq(); for (i = 0; i <= 15; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; irq_desc[i].handler = &cp7000_hpcdma_irq_type; } gt64120_irq_init(); #ifdef CONFIG_REMOTE_DEBUG printk("start kgdb ...\n"); set_debug_traps(); breakpoint(); /* you may move this line to whereever you want :-) */ #endif #ifdef CONFIG_GDB_CONSOLE register_gdb_console(); #endif } --- NEW FILE --- /* * $Id: ocelot_pld.h,v 1.1 2002/04/10 14:47:29 atp Exp $ * * Ocelot Board Register Definitions * * (C) 2001 Red Hat, Inc. * * GPL'd * */ #ifndef __MOMENCO_OCELOT_PLD_H__ #define __MOMENCO_OCELOT_PLD_H__ #define OCELOT_CS0_ADDR (0xe0020000) #define OCELOT_REG_BOARDREV (0) #define OCELOT_REG_PLD1_ID (1) #define OCELOT_REG_PLD2_ID (2) #define OCELOT_REG_RESET_STATUS (3) #define OCELOT_REG_BOARD_STATUS (4) #define OCELOT_REG_CPCI_ID (5) #define OCELOT_REG_I2C_CTRL (8) #define OCELOT_REG_EEPROM_MODE (9) #define OCELOT_REG_INTMASK (10) #define OCELOT_REG_INTSTATUS (11) #define OCELOT_REG_INTSET (12) #define OCELOT_REG_INTCLR (13) #define OCELOT_PLD_WRITE(x, y) writeb(x, OCELOT_CS0_ADDR + OCELOT_REG_##y) #define OCELOT_PLD_READ(x) readb(OCELOT_CS0_ADDR + OCELOT_REG_##x) #endif /* __MOMENCO_OCELOT_PLD_H__ */ --- NEW FILE --- /* * Copyright 2001 MontaVista Software Inc. * Author: Jun Sun, js...@mv... or js...@ju... * * arch/mips/gt64120/momenco_ocelot/pci.c * Board-specific PCI routines for gt64120 controller. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ #include <linux/types.h> #include <linux/pci.h> #include <linux/kernel.h> #include <linux/version.h> #include <linux/init.h> #include <asm/pci.h> void __init gt64120_board_pcibios_fixup_bus(struct pci_bus *bus) { struct pci_bus *current_bus = bus; struct pci_dev *devices; struct list_head *devices_link; u16 cmd; list_for_each(devices_link, &(current_bus->devices)) { devices = pci_dev_b(devices_link); if (devices == NULL) continue; if (PCI_SLOT(devices->devfn) == 1) { /* * Slot 1 is primary ether port, i82559 * we double-check against that assumption */ if ((devices->vendor != 0x8086) || (devices->device != 0x1209) ) { panic("gt64120_board_pcibios_fixup_bus: found " "unexpected PCI device in slot 1."); } devices->irq = 2; /* irq_nr is 2 for INT0 */ } else if (PCI_SLOT(devices->devfn) == 2) { /* * Slot 2 is secondary ether port, i21143 * we double-check against that assumption */ if ((devices->vendor != 0x1011) || (devices->device != 0x19) ) { panic("galileo_pcibios_fixup_bus: " "found unexpected PCI device in slot 2."); } devices->irq = 3; /* irq_nr is 3 for INT1 */ } else if (PCI_SLOT(devices->devfn) == 4) { /* PMC Slot 1 */ devices->irq = 8; /* irq_nr is 8 for INT6 */ } else if (PCI_SLOT(devices->devfn) == 5) { /* PMC Slot 1 */ devices->irq = 9; /* irq_nr is 9 for INT7 */ } else { /* We don't have assign interrupts for other devices. */ devices->irq = 0xff; } /* Assign an interrupt number for the device */ bus->ops->write_byte(devices, PCI_INTERRUPT_LINE, devices->irq); /* enable master */ bus->ops->read_word(devices, PCI_COMMAND, &cmd); cmd |= PCI_COMMAND_MASTER; bus->ops->write_word(devices, PCI_COMMAND, cmd); } } --- NEW FILE --- /* * Copyright 2001 MontaVista Software Inc. * Author: js...@mv... or js...@ju... * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ #include <linux/init.h> #include <linux/mm.h> #include <linux/sched.h> #include <linux/bootmem.h> #include <asm/addrspace.h> #include <asm/bootinfo.h> #define PLD_BASE 0xbc000000 #define REV 0x0 /* Board Assembly Revision */ #define PLD1ID 0x1 /* PLD 1 ID */ #define PLD2ID 0x2 /* PLD 2 ID */ #define RESET_STAT 0x3 /* Reset Status Register */ #define BOARD_STAT 0x4 /* Board Status Register */ #define CPCI_ID 0x5 /* Compact PCI ID Register */ #define CONTROL 0x8 /* Control Register */ #define CPU_EEPROM 0x9 /* CPU Configuration EEPROM Register */ #define INTMASK 0xA /* Interrupt Mask Register */ #define INTSTAT 0xB /* Interrupt Status Register */ #define INTSET 0xC /* Interrupt Set Register */ #define INTCLR 0xD /* Interrupt Clear Register */ #define PLD_REG(x) ((uint8_t*)(PLD_BASE+(x))) char arcs_cmdline[COMMAND_LINE_SIZE]; /* [js...@ju...] PMON passes arguments in C main() style */ void __init prom_init(int argc, const char **arg) { int i; /* arg[0] is "g", the rest is boot parameters */ arcs_cmdline[0] = '\0'; for (i = 1; i < argc; i++) { if (strlen(arcs_cmdline) + strlen(arg[i] + 1) >= sizeof(arcs_cmdline)) break; strcat(arcs_cmdline, arg[i]); strcat(arcs_cmdline, " "); } mips_machgroup = MACH_GROUP_MOMENCO; mips_machtype = MACH_MOMENCO_OCELOT; /* turn off the Bit Error LED, which comes on automatically * at power-up reset */ *PLD_REG(INTCLR) = 0x80; /* All the boards have at least 64MiB. If there's more, we detect and register it later */ add_memory_region(0, 64 << 20, BOOT_MEM_RAM); } void __init prom_free_prom_memory(void) { } void __init prom_fixup_mem_map(unsigned long start, unsigned long end) { } --- NEW FILE --- /* * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * Copyright (C) 1997, 2001 Ralf Baechle * Copyright 2001 MontaVista Software Inc. * Author: js...@mv... or js...@ju... */ #include <linux/sched.h> #include <linux/mm.h> #include <asm/io.h> #include <asm/pgtable.h> #include <asm/processor.h> #include <asm/reboot.h> #include <asm/system.h> void momenco_ocelot_restart(char *command) { *(volatile char *) 0xbc000000 = 0x0f; /* * Ouch, we're still alive ... This time we take the silver bullet ... * ... and find that we leave the hardware in a state in which the * kernel in the flush locks up somewhen during of after the PCI * detection stuff. */ clear_cp0_status(ST0_BEV | ST0_ERL); change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); flush_cache_all(); write_32bit_cp0_register(CP0_WIRED, 0); __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); } void momenco_ocelot_halt(void) { printk(KERN_NOTICE "\n** You can safely turn off the power\n"); while (1) __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0"); } void momenco_ocelot_power_off(void) { momenco_ocelot_halt(); } --- NEW FILE --- /* * setup.c * * BRIEF MODULE DESCRIPTION * Galileo Evaluation Boards - board dependent boot routines * * Copyright (C) 1996, 1997, 2001 Ralf Baechle * Copyright (C) 2000 RidgeRun, Inc. * Copyright (C) 2001 Red Hat, Inc. * * Author: RidgeRun, Inc. * gl...@ri..., sk...@ri..., st...@ri... * * Copyright 2001 MontaVista Software Inc. * Author: js...@mv... or js...@ju... * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <linux/init.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/mc146818rtc.h> #include <linux/mm.h> #include <linux/swap.h> #include <linux/ioport.h> #include <linux/sched.h> #include <linux/interrupt.h> #include <linux/pci.h> #include <linux/timex.h> #include <linux/vmalloc.h> #include <asm/time.h> #include <asm/bootinfo.h> #include <asm/page.h> #include <asm/bootinfo.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/pci.h> #include <asm/processor.h> #include <asm/ptrace.h> #include <asm/reboot.h> #include <asm/mc146818rtc.h> #include <linux/version.h> #include <linux/bootmem.h> #include <linux/blk.h> #include <asm/gt64120/gt64120.h> #include "ocelot_pld.h" extern struct rtc_ops no_rtc_ops; unsigned long gt64120_base = KSEG1ADDR(GT_DEF_BASE); /* These functions are used for rebooting or halting the machine*/ extern void momenco_ocelot_restart(char *command); extern void momenco_ocelot_halt(void); extern void momenco_ocelot_power_off(void); extern void gt64120_time_init(void); extern void momenco_ocelot_irq_setup(void); static char reset_reason; #define ENTRYLO(x) ((pte_val(mk_pte_phys((x), PAGE_KERNEL_UNCACHED)) >> 6)|1) static void __init setup_l3cache(unsigned long size); void __init momenco_ocelot_setup(void) { void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache); unsigned int tmpword; board_time_init = gt64120_time_init; _machine_restart = momenco_ocelot_restart; _machine_halt = momenco_ocelot_halt; _machine_power_off = momenco_ocelot_power_off; /* * initrd_start = (ulong)ocelot_initrd_start; * initrd_end = (ulong)ocelot_initrd_start + (ulong)ocelot_initrd_size; * initrd_below_start_ok = 1; */ rtc_ops = &no_rtc_ops; /* A wired TLB entry for the GT64120A and the serial port. The GT64120A is going to be hit on every IRQ anyway - there's absolutely no point in letting it be a random TLB entry, as it'll just cause needless churning of the TLB. And we use the other half for the serial port, which is just a PITA otherwise :) Device Physical Virtual GT64120 Internal Regs 0x24000000 0xe0000000 UARTs (CS2) 0x2d000000 0xe0001000 */ add_wired_entry(ENTRYLO(0x24000000), ENTRYLO(0x2D000000), 0xe0000000, PM_4K); /* Also a temporary entry to let us talk to the Ocelot PLD and NVRAM in the CS[012] region. We can't use ioremap() yet. The NVRAM appears to be one of the variants of ST M48T35 - see http://www.st.com/stonline/bin/sftab.exe?table=172&filter0=M48T35 Ocelot PLD (CS0) 0x2c000000 0xe0020000 NVRAM 0x2c800000 0xe0030000 */ add_temporary_entry(ENTRYLO(0x2C000000), ENTRYLO(0x2d000000), 0xe0020000, PM_64K); /* Relocate the CS3/BootCS region */ GT_WRITE( GT_CS3BOOTLD_OFS, 0x2f000000 >> 21); /* Relocate CS[012] */ GT_WRITE(GT_CS20LD_OFS, 0x2c000000 >> 21); /* Relocate the GT64120A itself... */ GT_WRITE(GT_ISD_OFS, 0x24000000 >> 21); mb(); gt64120_base = 0xe0000000; /* ...and the PCI0 view of it. */ GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000020); GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x24000000); GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000024); GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x24000001); /* Relocate PCI0 I/O and Mem0 */ GT_WRITE(GT_PCI0IOLD_OFS, 0x20000000 >> 21); GT_WRITE(GT_PCI0M0LD_OFS, 0x22000000 >> 21); /* Relocate PCI0 Mem1 */ GT_WRITE(GT_PCI0M1LD_OFS, 0x36000000 >> 21); /* Relocate all the PCI1 stuff, not that we use it */ GT_WRITE(GT_PCI1IOLD_OFS, 0x30000000 >> 21); GT_WRITE(GT_PCI1M0LD_OFS, 0x32000000 >> 21); GT_WRITE(GT_PCI1M1LD_OFS, 0x34000000 >> 21); /* Relocate the CPU's view of the RAM... */ GT_WRITE(GT_SCS10LD_OFS, 0); GT_WRITE(GT_SCS10HD_OFS, 0x0fe00000 >> 21); GT_WRITE(GT_SCS32LD_OFS, 0x10000000 >> 21); GT_WRITE(GT_SCS32HD_OFS, 0x0fe00000 >> 21); GT_WRITE(GT_SCS1LD_OFS, 0xff); GT_WRITE(GT_SCS1HD_OFS, 0x00); GT_WRITE(GT_SCS0LD_OFS, 0); GT_WRITE(GT_SCS0HD_OFS, 0xff); GT_WRITE(GT_SCS3LD_OFS, 0xff); GT_WRITE(GT_SCS3HD_OFS, 0x00); GT_WRITE(GT_SCS2LD_OFS, 0); GT_WRITE(GT_SCS2HD_OFS, 0xff); /* ...and the PCI0 view of it. */ GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000010); GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x00000000); GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000014); GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x10000000); GT_WRITE(GT_PCI0_BS_SCS10_OFS, 0x0ffff000); GT_WRITE(GT_PCI0_BS_SCS32_OFS, 0x0ffff000); tmpword = OCELOT_PLD_READ(BOARDREV); if (tmpword < 26) printk("Momenco Ocelot: Board Assembly Rev. %c\n", 'A'+tmpword); else printk("Momenco Ocelot: Board Assembly Revision #0x%x\n", tmpword); tmpword = OCELOT_PLD_READ(PLD1_ID); printk("PLD 1 ID: %d.%d\n", tmpword>>4, tmpword&15); tmpword = OCELOT_PLD_READ(PLD2_ID); printk("PLD 2 ID: %d.%d\n", tmpword>>4, tmpword&15); tmpword = OCELOT_PLD_READ(RESET_STATUS); printk("Reset reason: 0x%x\n", tmpword); reset_reason = tmpword; OCELOT_PLD_WRITE(0xff, RESET_STATUS); tmpword = OCELOT_PLD_READ(BOARD_STATUS); printk("Board Status register: 0x%02x\n", tmpword); printk(" - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent"); printk(" - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent"); printk(" - Tulip PHY %s connected\n", (tmpword&0x10)?"is":"not"); printk(" - L3 Cache size: %d MiB\n", (1<<((tmpword&12) >> 2))&~1); printk(" - SDRAM size: %d MiB\n", 1<<(6+(tmpword&3))); if (tmpword&12) l3func((1<<(((tmpword&12) >> 2)+20))); switch(tmpword &3) { case 3: /* 512MiB */ add_memory_region(256<<20, 256<<20, BOOT_MEM_RAM); case 2: /* 256MiB */ /* FIXME: Is it actually here, or at 0x10000000? */ add_memory_region(128<<20, 128<<20, BOOT_MEM_RAM); case 1: /* 128MiB */ add_memory_region(64<<20, 64<<20, BOOT_MEM_RAM); case 0: /* 64MiB */ ; } /* Fix up the DiskOnChip mapping */ GT_WRITE(0x468, 0xfef73); } extern int rm7k_tcache_enabled; /* * This runs in KSEG1. See the verbiage in rm7k.c::probe_scache() */ #define Page_Invalidate_T 0x16 static void __init setup_l3cache(unsigned long size) { int register i; unsigned long tmp; printk("Enabling L3 cache..."); /* Enable the L3 cache in the GT64120A's CPU Configuration register */ GT_READ(0, &tmp); GT_WRITE(0, tmp | (1<<14)); /* Enable the L3 cache in the CPU */ set_cp0_config(1<<12 /* CONF_TE */); /* Clear the cache */ set_taglo(0); set_taghi(0); for (i=0; i < size; i+= 4096) { __asm__ __volatile__ ( ".set noreorder\n\t" ".set mips3\n\t" "cache %1, (%0)\n\t" ".set mips0\n\t" ".set reorder" : : "r" (KSEG0ADDR(i)), "i" (Page_Invalidate_T)); } /* Let the RM7000 MM code know that the tertiary cache is enabled */ rm7k_tcache_enabled = 1; printk("Done\n"); } /* This needs to be one of the first initcalls, because no I/O port access can work before this */ static int io_base_ioremap(void) { void *io_remap_range = ioremap(GT_PCI_IO_BASE, GT_PCI_IO_SIZE); if (!io_remap_range) { panic("Could not ioremap I/O port range\n"); } mips_io_port_base = io_remap_range - GT_PCI_IO_BASE; return 0; } module_init(io_base_ioremap); |