diff options
Diffstat (limited to 'cpu/mpc8260')
-rw-r--r-- | cpu/mpc8260/Makefile | 53 | ||||
-rw-r--r-- | cpu/mpc8260/bedbug_603e.c | 238 | ||||
-rw-r--r-- | cpu/mpc8260/commproc.c | 221 | ||||
-rw-r--r-- | cpu/mpc8260/config.mk | 30 | ||||
-rw-r--r-- | cpu/mpc8260/cpu.c | 338 | ||||
-rw-r--r-- | cpu/mpc8260/cpu_init.c | 292 | ||||
-rw-r--r-- | cpu/mpc8260/ether_fcc.c | 1190 | ||||
-rw-r--r-- | cpu/mpc8260/ether_scc.c | 387 | ||||
-rw-r--r-- | cpu/mpc8260/i2c.c | 785 | ||||
-rw-r--r-- | cpu/mpc8260/interrupts.c | 279 | ||||
-rw-r--r-- | cpu/mpc8260/kgdb.S | 72 | ||||
-rw-r--r-- | cpu/mpc8260/pci.c | 466 | ||||
-rw-r--r-- | cpu/mpc8260/serial_scc.c | 498 | ||||
-rw-r--r-- | cpu/mpc8260/serial_smc.c | 467 | ||||
-rw-r--r-- | cpu/mpc8260/speed.c | 253 | ||||
-rw-r--r-- | cpu/mpc8260/speed.h | 54 | ||||
-rw-r--r-- | cpu/mpc8260/spi.c | 435 | ||||
-rw-r--r-- | cpu/mpc8260/start.S | 1023 | ||||
-rw-r--r-- | cpu/mpc8260/traps.c | 273 | ||||
-rw-r--r-- | cpu/mpc8260/u-boot.lds | 122 |
20 files changed, 0 insertions, 7476 deletions
diff --git a/cpu/mpc8260/Makefile b/cpu/mpc8260/Makefile deleted file mode 100644 index 9f0c2dd..0000000 --- a/cpu/mpc8260/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# -# (C) Copyright 2000-2008 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# 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 program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# 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., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(CPU).a - -START = start.o kgdb.o -COBJS = traps.o serial_smc.o serial_scc.o cpu.o cpu_init.o speed.o \ - interrupts.o ether_fcc.o i2c.o commproc.o \ - bedbug_603e.o pci.o spi.o - -COBJS-$(CONFIG_ETHER_ON_SCC) = ether_scc.o - -COBJS += $(COBJS-y) - -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(START) $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) $(obj)kgdb.o - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/mpc8260/bedbug_603e.c b/cpu/mpc8260/bedbug_603e.c deleted file mode 100644 index c969ff6..0000000 --- a/cpu/mpc8260/bedbug_603e.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Bedbug Functions specific to the MPC603e core - */ - -#include <common.h> -#include <command.h> -#include <linux/ctype.h> -#include <bedbug/type.h> -#include <bedbug/bedbug.h> -#include <bedbug/regs.h> -#include <bedbug/ppc.h> - -#if defined(CONFIG_CMD_BEDBUG) \ - && (defined(CONFIG_MPC824X) || defined(CONFIG_MPC8260)) - -#define MAX_BREAK_POINTS 1 - -extern CPU_DEBUG_CTX bug_ctx; - -void bedbug603e_init __P((void)); -void bedbug603e_do_break __P((cmd_tbl_t*,int,int,char*[])); -void bedbug603e_break_isr __P((struct pt_regs*)); -int bedbug603e_find_empty __P((void)); -int bedbug603e_set __P((int,unsigned long)); -int bedbug603e_clear __P((int)); - - -/* ====================================================================== - * Initialize the global bug_ctx structure for the processor. Clear all - * of the breakpoints. - * ====================================================================== */ - -void bedbug603e_init( void ) -{ - int i; - /* -------------------------------------------------- */ - - bug_ctx.hw_debug_enabled = 0; - bug_ctx.stopped = 0; - bug_ctx.current_bp = 0; - bug_ctx.regs = NULL; - - bug_ctx.do_break = bedbug603e_do_break; - bug_ctx.break_isr = bedbug603e_break_isr; - bug_ctx.find_empty = bedbug603e_find_empty; - bug_ctx.set = bedbug603e_set; - bug_ctx.clear = bedbug603e_clear; - - for( i = 1; i <= MAX_BREAK_POINTS; ++i ) - (*bug_ctx.clear)( i ); - - puts ("BEDBUG:ready\n"); - return; -} /* bedbug_init_breakpoints */ - - - -/* ====================================================================== - * Set/clear/show the hardware breakpoint for the 603e. The "off" - * string will disable a specific breakpoint. The "show" string will - * display the current breakpoints. Otherwise an address will set a - * breakpoint at that address. Setting a breakpoint uses the CPU-specific - * set routine which will assign a breakpoint number. - * ====================================================================== */ - -void bedbug603e_do_break (cmd_tbl_t *cmdtp, int flag, int argc, - char *argv[]) -{ - long addr; /* Address to break at */ - int which_bp; /* Breakpoint number */ - /* -------------------------------------------------- */ - - if (argc < 2) - { - cmd_usage(cmdtp); - return; - } - - /* Turn off a breakpoint */ - - if( strcmp( argv[ 1 ], "off" ) == 0 ) - { - if( bug_ctx.hw_debug_enabled == 0 ) - { - puts ( "No breakpoints enabled\n" ); - return; - } - - which_bp = simple_strtoul( argv[ 2 ], NULL, 10 ); - - if( bug_ctx.clear ) - (*bug_ctx.clear)( which_bp ); - - printf( "Breakpoint %d removed\n", which_bp ); - return; - } - - /* Show a list of breakpoints */ - - if( strcmp( argv[ 1 ], "show" ) == 0 ) - { - for( which_bp = 1; which_bp <= MAX_BREAK_POINTS; ++which_bp ) - { - - addr = GET_IABR(); - - printf( "Breakpoint [%d]: ", which_bp ); - if( (addr & 0x00000002) == 0 ) - puts ( "NOT SET\n" ); - else - disppc( (unsigned char *)(addr & 0xFFFFFFFC), 0, 1, bedbug_puts, F_RADHEX ); - } - return; - } - - /* Set a breakpoint at the address */ - - if(!(( isdigit( argv[ 1 ][ 0 ] )) || - (( argv[ 1 ][ 0 ] >= 'a' ) && ( argv[ 1 ][ 0 ] <= 'f' )) || - (( argv[ 1 ][ 0 ] >= 'A' ) && ( argv[ 1 ][ 0 ] <= 'F' )))) - { - cmd_usage(cmdtp); - return; - } - - addr = simple_strtoul( argv[ 1 ], NULL, 16 ); - - if(( bug_ctx.set ) && ( which_bp = (*bug_ctx.set)( 0, addr )) > 0 ) - { - printf( "Breakpoint [%d]: ", which_bp ); - disppc( (unsigned char *)addr, 0, 1, bedbug_puts, F_RADHEX ); - } - - return; -} /* bedbug603e_do_break */ - - - -/* ====================================================================== - * Handle a breakpoint. Enter a mini main loop. Stay in the loop until - * the stopped flag in the debug context is cleared. - * ====================================================================== */ - -void bedbug603e_break_isr( struct pt_regs *regs ) -{ - unsigned long addr; /* Address stopped at */ - /* -------------------------------------------------- */ - - bug_ctx.current_bp = 1; - addr = GET_IABR() & 0xFFFFFFFC; - - bedbug_main_loop( addr, regs ); - return; -} /* bedbug603e_break_isr */ - - - -/* ====================================================================== - * See if the hardware breakpoint is available. - * ====================================================================== */ - -int bedbug603e_find_empty( void ) -{ - /* -------------------------------------------------- */ - - if( (GET_IABR() && 0x00000002) == 0 ) - return 1; - - return 0; -} /* bedbug603e_find_empty */ - - - -/* ====================================================================== - * Set a breakpoint. If 'which_bp' is zero then find an unused breakpoint - * number, otherwise reassign the given breakpoint. If hardware debugging - * is not enabled, then turn it on via the MSR and DBCR0. Set the break - * address in the IABR register. - * ====================================================================== */ - -int bedbug603e_set( int which_bp, unsigned long addr ) -{ - /* -------------------------------------------------- */ - - if(( addr & 0x00000003 ) != 0 ) - { - puts ( "Breakpoints must be on a 32 bit boundary\n" ); - return 0; - } - - /* Only look if which_bp == 0, else use which_bp */ - if(( bug_ctx.find_empty ) && ( !which_bp ) && - ( which_bp = (*bug_ctx.find_empty)()) == 0 ) - { - puts ( "All breakpoints in use\n" ); - return 0; - } - - if( which_bp < 1 || which_bp > MAX_BREAK_POINTS ) - { - printf( "Invalid break point # %d\n", which_bp ); - return 0; - } - - if( ! bug_ctx.hw_debug_enabled ) - { - bug_ctx.hw_debug_enabled = 1; - } - - SET_IABR( addr | 0x00000002 ); - - return which_bp; -} /* bedbug603e_set */ - - - -/* ====================================================================== - * Disable a specific breakoint by setting the IABR register to zero. - * ====================================================================== */ - -int bedbug603e_clear( int which_bp ) -{ - /* -------------------------------------------------- */ - - if( which_bp < 1 || which_bp > MAX_BREAK_POINTS ) - { - printf( "Invalid break point # (%d)\n", which_bp ); - return -1; - } - - SET_IABR( 0 ); - - return 0; -} /* bedbug603e_clear */ - - -/* ====================================================================== */ -#endif diff --git a/cpu/mpc8260/commproc.c b/cpu/mpc8260/commproc.c deleted file mode 100644 index 94f6bc2..0000000 --- a/cpu/mpc8260/commproc.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * This file is based on "arch/ppc/8260_io/commproc.c" - here is it's - * copyright notice: - * - * General Purpose functions for the global management of the - * 8260 Communication Processor Module. - * Copyright (c) 1999 Dan Malek (dmalek@jlc.net) - * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com) - * 2.3.99 Updates - * - * In addition to the individual control of the communication - * channels, there are a few functions that globally affect the - * communication processor. - * - * Buffer descriptors must be allocated from the dual ported memory - * space. The allocator for that is here. When the communication - * process is reset, we reclaim the memory available. There is - * currently no deallocator for this memory. - */ -#include <common.h> -#include <asm/cpm_8260.h> - -DECLARE_GLOBAL_DATA_PTR; - -void -m8260_cpm_reset(void) -{ - volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; - volatile ulong count; - - /* Reclaim the DP memory for our use. - */ - gd->dp_alloc_base = CPM_DATAONLY_BASE; - gd->dp_alloc_top = gd->dp_alloc_base + CPM_DATAONLY_SIZE; - - /* - * Reset CPM - */ - immr->im_cpm.cp_cpcr = CPM_CR_RST; - count = 0; - do { /* Spin until command processed */ - __asm__ __volatile__ ("eieio"); - } while ((immr->im_cpm.cp_cpcr & CPM_CR_FLG) && ++count < 1000000); - -#ifdef CONFIG_HARD_I2C - *((unsigned short*)(&immr->im_dprambase[PROFF_I2C_BASE])) = 0; -#endif -} - -/* Allocate some memory from the dual ported ram. - * To help protocols with object alignment restrictions, we do that - * if they ask. - */ -uint -m8260_cpm_dpalloc(uint size, uint align) -{ - volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; - uint retloc; - uint align_mask, off; - uint savebase; - - align_mask = align - 1; - savebase = gd->dp_alloc_base; - - if ((off = (gd->dp_alloc_base & align_mask)) != 0) - gd->dp_alloc_base += (align - off); - - if ((off = size & align_mask) != 0) - size += align - off; - - if ((gd->dp_alloc_base + size) >= gd->dp_alloc_top) { - gd->dp_alloc_base = savebase; - panic("m8260_cpm_dpalloc: ran out of dual port ram!"); - } - - retloc = gd->dp_alloc_base; - gd->dp_alloc_base += size; - - memset((void *)&immr->im_dprambase[retloc], 0, size); - - return(retloc); -} - -/* We also own one page of host buffer space for the allocation of - * UART "fifos" and the like. - */ -uint -m8260_cpm_hostalloc(uint size, uint align) -{ - /* the host might not even have RAM yet - just use dual port RAM */ - return (m8260_cpm_dpalloc(size, align)); -} - -/* Set a baud rate generator. This needs lots of work. There are - * eight BRGs, which can be connected to the CPM channels or output - * as clocks. The BRGs are in two different block of internal - * memory mapped space. - * The baud rate clock is the system clock divided by something. - * It was set up long ago during the initial boot phase and is - * is given to us. - * Baud rate clocks are zero-based in the driver code (as that maps - * to port numbers). Documentation uses 1-based numbering. - */ -#define BRG_INT_CLK gd->brg_clk -#define BRG_UART_CLK (BRG_INT_CLK / 16) - -/* This function is used by UARTs, or anything else that uses a 16x - * oversampled clock. - */ -void -m8260_cpm_setbrg(uint brg, uint rate) -{ - volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; - volatile uint *bp; - uint cd = BRG_UART_CLK / rate; - - if ((BRG_UART_CLK % rate) < (rate / 2)) - cd--; - if (brg < 4) { - bp = (uint *)&immr->im_brgc1; - } - else { - bp = (uint *)&immr->im_brgc5; - brg -= 4; - } - bp += brg; - *bp = (cd << 1) | CPM_BRG_EN; -} - -/* This function is used to set high speed synchronous baud rate - * clocks. - */ -void -m8260_cpm_fastbrg(uint brg, uint rate, int div16) -{ - volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; - volatile uint *bp; - - /* This is good enough to get SMCs running..... - */ - if (brg < 4) { - bp = (uint *)&immr->im_brgc1; - } - else { - bp = (uint *)&immr->im_brgc5; - brg -= 4; - } - bp += brg; - *bp = (((((BRG_INT_CLK+rate-1)/rate)-1)&0xfff)<<1)|CPM_BRG_EN; - if (div16) - *bp |= CPM_BRG_DIV16; -} - -/* This function is used to set baud rate generators using an external - * clock source and 16x oversampling. - */ - -void -m8260_cpm_extcbrg(uint brg, uint rate, uint extclk, int pinsel) -{ - volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; - volatile uint *bp; - - if (brg < 4) { - bp = (uint *)&immr->im_brgc1; - } - else { - bp = (uint *)&immr->im_brgc5; - brg -= 4; - } - bp += brg; - *bp = ((((((extclk/16)+rate-1)/rate)-1)&0xfff)<<1)|CPM_BRG_EN; - if (pinsel == 0) - *bp |= CPM_BRG_EXTC_CLK3_9; - else - *bp |= CPM_BRG_EXTC_CLK5_15; -} - -#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER) - -void post_word_store (ulong a) -{ - volatile ulong *save_addr = - (volatile ulong *)(CONFIG_SYS_IMMR + CPM_POST_WORD_ADDR); - - *save_addr = a; -} - -ulong post_word_load (void) -{ - volatile ulong *save_addr = - (volatile ulong *)(CONFIG_SYS_IMMR + CPM_POST_WORD_ADDR); - - return *save_addr; -} - -#endif /* CONFIG_POST || CONFIG_LOGBUFFER*/ - -#ifdef CONFIG_BOOTCOUNT_LIMIT - -void bootcount_store (ulong a) -{ - volatile ulong *save_addr = - (volatile ulong *)(CONFIG_SYS_IMMR + CPM_BOOTCOUNT_ADDR); - - save_addr[0] = a; - save_addr[1] = BOOTCOUNT_MAGIC; -} - -ulong bootcount_load (void) -{ - volatile ulong *save_addr = - (volatile ulong *)(CONFIG_SYS_IMMR + CPM_BOOTCOUNT_ADDR); - - if (save_addr[1] != BOOTCOUNT_MAGIC) - return 0; - else - return save_addr[0]; -} - -#endif /* CONFIG_BOOTCOUNT_LIMIT */ diff --git a/cpu/mpc8260/config.mk b/cpu/mpc8260/config.mk deleted file mode 100644 index 39d81ee..0000000 --- a/cpu/mpc8260/config.mk +++ /dev/null @@ -1,30 +0,0 @@ -# -# (C) Copyright 2000 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# 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 program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# 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., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -PLATFORM_RELFLAGS += -fPIC -meabi - -PLATFORM_CPPFLAGS += -DCONFIG_8260 -DCONFIG_CPM2 -ffixed-r2 \ - -mstring -mcpu=603e -mmultiple - -# Use default linker script. Board port can override in board/*/config.mk -LDSCRIPT := $(SRCTREE)/cpu/mpc8260/u-boot.lds diff --git a/cpu/mpc8260/cpu.c b/cpu/mpc8260/cpu.c deleted file mode 100644 index aedbf29..0000000 --- a/cpu/mpc8260/cpu.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * (C) Copyright 2000-2006 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * CPU specific code for the MPC825x / MPC826x / MPC827x / MPC828x - * - * written or collected and sometimes rewritten by - * Magnus Damm <damm@bitsmart.com> - * - * modified by - * Wolfgang Denk <wd@denx.de> - * - * modified for 8260 by - * Murray Jensen <Murray.Jensen@cmst.csiro.au> - * - * added 8260 masks by - * Marius Groeger <mag@sysgo.de> - * - * added HiP7 (824x/827x/8280) processors support by - * Yuli Barcohen <yuli@arabellasw.com> - */ - -#include <common.h> -#include <watchdog.h> -#include <command.h> -#include <mpc8260.h> -#include <netdev.h> -#include <asm/processor.h> -#include <asm/cpm_8260.h> - -#if defined(CONFIG_OF_LIBFDT) -#include <libfdt.h> -#include <libfdt_env.h> -#include <fdt_support.h> -#endif - -DECLARE_GLOBAL_DATA_PTR; - -#if defined(CONFIG_GET_CPU_STR_F) -extern int get_cpu_str_f (char *buf); -#endif - -int checkcpu (void) -{ - volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; - ulong clock = gd->cpu_clk; - uint pvr = get_pvr (); - uint immr, rev, m, k; - char buf[32]; - - puts ("CPU: "); - - switch (pvr) { - case PVR_8260: - case PVR_8260_HIP3: - k = 3; - break; - case PVR_8260_HIP4: - k = 4; - break; - case PVR_8260_HIP7R1: - case PVR_8260_HIP7RA: - case PVR_8260_HIP7: - k = 7; - break; - default: - return -1; /* whoops! not an MPC8260 */ - } - rev = pvr & 0xff; - - immr = immap->im_memctl.memc_immr; - if ((immr & IMMR_ISB_MSK) != CONFIG_SYS_IMMR) - return -1; /* whoops! someone moved the IMMR */ - -#if defined(CONFIG_GET_CPU_STR_F) - get_cpu_str_f (buf); - printf ("%s (HiP%d Rev %02x, Mask ", buf, k, rev); -#else - printf (CPU_ID_STR " (HiP%d Rev %02x, Mask ", k, rev); -#endif - - /* - * the bottom 16 bits of the immr are the Part Number and Mask Number - * (4-34); the 16 bits at PROFF_REVNUM (0x8af0) in dual port ram is the - * RISC Microcode Revision Number (13-10). - * For the 8260, Motorola doesn't include the Microcode Revision - * in the mask. - */ - m = immr & (IMMR_PARTNUM_MSK | IMMR_MASKNUM_MSK); - k = *((ushort *) & immap->im_dprambase[PROFF_REVNUM]); - - switch (m) { - case 0x0000: - puts ("0.2 2J24M"); - break; - case 0x0010: - puts ("A.0 K22A"); - break; - case 0x0011: - puts ("A.1 1K22A-XC"); - break; - case 0x0001: - puts ("B.1 1K23A"); - break; - case 0x0021: - puts ("B.2 2K23A-XC"); - break; - case 0x0023: - puts ("B.3 3K23A"); - break; - case 0x0024: - puts ("C.2 6K23A"); - break; - case 0x0060: - puts ("A.0(A) 2K25A"); - break; - case 0x0062: - puts ("B.1 4K25A"); - break; - case 0x0064: - puts ("C.0 5K25A"); - break; - case 0x0A00: - puts ("0.0 0K49M"); - break; - case 0x0A01: - puts ("0.1 1K49M"); - break; - case 0x0A10: - puts ("1.0 1K49M"); - break; - case 0x0C00: - puts ("0.0 0K50M"); - break; - case 0x0C10: - puts ("1.0 1K50M"); - break; - case 0x0D00: - puts ("0.0 0K50M"); - break; - case 0x0D10: - puts ("1.0 1K50M"); - break; - default: - printf ("unknown [immr=0x%04x,k=0x%04x]", m, k); - break; - } - - printf (") at %s MHz\n", strmhz (buf, clock)); - - return 0; -} - -/* ------------------------------------------------------------------------- */ -/* configures a UPM by writing into the UPM RAM array */ -/* uses bank 11 and a dummy physical address (=BRx_BA_MSK) */ -/* NOTE: the physical address chosen must not overlap into any other area */ -/* mapped by the memory controller because bank 11 has the lowest priority */ - -void upmconfig (uint upm, uint * table, uint size) -{ - volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; - volatile memctl8260_t *memctl = &immap->im_memctl; - volatile uchar *dummy = (uchar *) BRx_BA_MSK; /* set all BA bits */ - uint i; - - /* first set up bank 11 to reference the correct UPM at a dummy address */ - - memctl->memc_or11 = ORxU_AM_MSK; /* set all AM bits */ - - switch (upm) { - - case UPMA: - memctl->memc_br11 = - ((uint)dummy & BRx_BA_MSK) | BRx_PS_32 | BRx_MS_UPMA | - BRx_V; - memctl->memc_mamr = MxMR_OP_WARR; - break; - - case UPMB: - memctl->memc_br11 = - ((uint)dummy & BRx_BA_MSK) | BRx_PS_32 | BRx_MS_UPMB | - BRx_V; - memctl->memc_mbmr = MxMR_OP_WARR; - break; - - case UPMC: - memctl->memc_br11 = - ((uint)dummy & BRx_BA_MSK) | BRx_PS_32 | BRx_MS_UPMC | - BRx_V; - memctl->memc_mcmr = MxMR_OP_WARR; - break; - - default: - panic ("upmconfig passed invalid UPM number (%u)\n", upm); - break; - - } - - /* - * at this point, the dummy address is set up to access the selected UPM, - * the MAD pointer is zero, and the MxMR OP is set for writing to RAM - * - * now we simply load the mdr with each word and poke the dummy address. - * the MAD is incremented on each access. - */ - - for (i = 0; i < size; i++) { - memctl->memc_mdr = table[i]; - *dummy = 0; - } - - /* now kill bank 11 */ - memctl->memc_br11 = 0; -} - -/* ------------------------------------------------------------------------- */ - -#if !defined(CONFIG_HAVE_OWN_RESET) -int -do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - ulong msr, addr; - - volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; - - immap->im_clkrst.car_rmr = RMR_CSRE; /* Checkstop Reset enable */ - - /* Interrupts and MMU off */ - __asm__ __volatile__ ("mfmsr %0":"=r" (msr):); - - msr &= ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR); - __asm__ __volatile__ ("mtmsr %0"::"r" (msr)); - - /* - * Trying to execute the next instruction at a non-existing address - * should cause a machine check, resulting in reset - */ -#ifdef CONFIG_SYS_RESET_ADDRESS - addr = CONFIG_SYS_RESET_ADDRESS; -#else - /* - * note: when CONFIG_SYS_MONITOR_BASE points to a RAM address, CONFIG_SYS_MONITOR_BASE - * - sizeof (ulong) is usually a valid address. Better pick an address - * known to be invalid on your system and assign it to CONFIG_SYS_RESET_ADDRESS. - */ - addr = CONFIG_SYS_MONITOR_BASE - sizeof (ulong); -#endif - ((void (*)(void)) addr) (); - return 1; - -} -#endif /* CONFIG_HAVE_OWN_RESET */ - -/* ------------------------------------------------------------------------- */ - -/* - * Get timebase clock frequency (like cpu_clk in Hz) - * - */ -unsigned long get_tbclk (void) -{ - ulong tbclk; - - tbclk = (gd->bus_clk + 3L) / 4L; - - return (tbclk); -} - -/* ------------------------------------------------------------------------- */ - -#if defined(CONFIG_WATCHDOG) -void watchdog_reset (void) -{ - int re_enable = disable_interrupts (); - - reset_8260_watchdog ((immap_t *) CONFIG_SYS_IMMR); - if (re_enable) - enable_interrupts (); -} -#endif /* CONFIG_WATCHDOG */ - -/* ------------------------------------------------------------------------- */ -#if defined(CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP) -void ft_cpu_setup (void *blob, bd_t *bd) -{ -#if defined(CONFIG_HAS_ETH0) || defined(CONFIG_HAS_ETH1) ||\ - defined(CONFIG_HAS_ETH2) || defined(CONFIG_HAS_ETH3) - fdt_fixup_ethernet(blob); -#endif - - do_fixup_by_compat_u32(blob, "fsl,cpm2-brg", - "clock-frequency", bd->bi_brgfreq, 1); - - do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, - "bus-frequency", bd->bi_busfreq, 1); - do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, - "timebase-frequency", OF_TBCLK, 1); - do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, - "clock-frequency", bd->bi_intfreq, 1); - fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); -} -#endif /* CONFIG_OF_LIBFDT */ - -/* - * Initializes on-chip ethernet controllers. - * to override, implement board_eth_init() - */ -int cpu_eth_init(bd_t *bis) -{ -#if defined(CONFIG_ETHER_ON_FCC) - fec_initialize(bis); -#endif -#if defined(CONFIG_ETHER_ON_SCC) - mpc82xx_scc_enet_initialize(bis); -#endif - return 0; -} diff --git a/cpu/mpc8260/cpu_init.c b/cpu/mpc8260/cpu_init.c deleted file mode 100644 index 1d52773..0000000 --- a/cpu/mpc8260/cpu_init.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * (C) Copyright 2000-2002 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <mpc8260.h> -#include <asm/cpm_8260.h> -#include <ioports.h> - -DECLARE_GLOBAL_DATA_PTR; - -#if defined(CONFIG_BOARD_GET_CPU_CLK_F) -extern unsigned long board_get_cpu_clk_f (void); -#endif - -static void config_8260_ioports (volatile immap_t * immr) -{ - int portnum; - - for (portnum = 0; portnum < 4; portnum++) { - uint pmsk = 0, - ppar = 0, - psor = 0, - pdir = 0, - podr = 0, - pdat = 0; - iop_conf_t *iopc = (iop_conf_t *) & iop_conf_tab[portnum][0]; - iop_conf_t *eiopc = iopc + 32; - uint msk = 1; - - /* - * NOTE: - * index 0 refers to pin 31, - * index 31 refers to pin 0 - */ - while (iopc < eiopc) { - if (iopc->conf) { - pmsk |= msk; - if (iopc->ppar) - ppar |= msk; - if (iopc->psor) - psor |= msk; - if (iopc->pdir) - pdir |= msk; - if (iopc->podr) - podr |= msk; - if (iopc->pdat) - pdat |= msk; - } - - msk <<= 1; - iopc++; - } - - if (pmsk != 0) { - volatile ioport_t *iop = ioport_addr (immr, portnum); - uint tpmsk = ~pmsk; - - /* - * the (somewhat confused) paragraph at the - * bottom of page 35-5 warns that there might - * be "unknown behaviour" when programming - * PSORx and PDIRx, if PPARx = 1, so I - * decided this meant I had to disable the - * dedicated function first, and enable it - * last. - */ - iop->ppar &= tpmsk; - iop->psor = (iop->psor & tpmsk) | psor; - iop->podr = (iop->podr & tpmsk) | podr; - iop->pdat = (iop->pdat & tpmsk) | pdat; - iop->pdir = (iop->pdir & tpmsk) | pdir; - iop->ppar |= ppar; - } - } -} - -#define SET_VAL_MASK(a, b, mask) ((a & mask) | (b & ~mask)) -/* - * Breath some life into the CPU... - * - * Set up the memory map, - * initialize a bunch of registers, - * initialize the UPM's - */ -void cpu_init_f (volatile immap_t * immr) -{ -#if !defined(CONFIG_COGENT) /* done in start.S for the cogent */ - uint sccr; -#endif -#if defined(CONFIG_BOARD_GET_CPU_CLK_F) - unsigned long cpu_clk; -#endif - volatile memctl8260_t *memctl = &immr->im_memctl; - extern void m8260_cpm_reset (void); - - /* Pointer is writable since we allocated a register for it */ - gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); - - /* Clear initial global data */ - memset ((void *) gd, 0, sizeof (gd_t)); - - /* RSR - Reset Status Register - clear all status (5-4) */ - gd->reset_status = immr->im_clkrst.car_rsr; - immr->im_clkrst.car_rsr = RSR_ALLBITS; - - /* RMR - Reset Mode Register - contains checkstop reset enable (5-5) */ - immr->im_clkrst.car_rmr = CONFIG_SYS_RMR; - - /* BCR - Bus Configuration Register (4-25) */ -#if defined(CONFIG_SYS_BCR_60x) && (CONFIG_SYS_BCR_SINGLE) - if (immr->im_siu_conf.sc_bcr & BCR_EBM) { - immr->im_siu_conf.sc_bcr = SET_VAL_MASK(immr->im_siu_conf.sc_bcr, CONFIG_SYS_BCR_60x, 0x80000010); - } else { - immr->im_siu_conf.sc_bcr = SET_VAL_MASK(immr->im_siu_conf.sc_bcr, CONFIG_SYS_BCR_SINGLE, 0x80000010); - } -#else - immr->im_siu_conf.sc_bcr = CONFIG_SYS_BCR; -#endif - - /* SIUMCR - contains debug pin configuration (4-31) */ -#if defined(CONFIG_SYS_SIUMCR_LOW) && (CONFIG_SYS_SIUMCR_HIGH) - cpu_clk = board_get_cpu_clk_f (); - if (cpu_clk >= 100000000) { - immr->im_siu_conf.sc_siumcr = SET_VAL_MASK(immr->im_siu_conf.sc_siumcr, CONFIG_SYS_SIUMCR_HIGH, 0x9f3cc000); - } else { - immr->im_siu_conf.sc_siumcr = SET_VAL_MASK(immr->im_siu_conf.sc_siumcr, CONFIG_SYS_SIUMCR_LOW, 0x9f3cc000); - } -#else - immr->im_siu_conf.sc_siumcr = CONFIG_SYS_SIUMCR; -#endif - - config_8260_ioports (immr); - - /* initialize time counter status and control register (4-40) */ - immr->im_sit.sit_tmcntsc = CONFIG_SYS_TMCNTSC; - - /* initialize the PIT (4-42) */ - immr->im_sit.sit_piscr = CONFIG_SYS_PISCR; - -#if !defined(CONFIG_COGENT) /* done in start.S for the cogent */ - /* System clock control register (9-8) */ - sccr = immr->im_clkrst.car_sccr & - (SCCR_PCI_MODE | SCCR_PCI_MODCK | SCCR_PCIDF_MSK); - immr->im_clkrst.car_sccr = sccr | - (CONFIG_SYS_SCCR & ~(SCCR_PCI_MODE | SCCR_PCI_MODCK | SCCR_PCIDF_MSK) ); -#endif /* !CONFIG_COGENT */ - - /* - * Memory Controller: - */ - - /* Map banks 0 and 1 to the FLASH banks 0 and 1 at preliminary - * addresses - these have to be modified later when FLASH size - * has been determined - */ - -#if defined(CONFIG_SYS_OR0_REMAP) - memctl->memc_or0 = CONFIG_SYS_OR0_REMAP; -#endif -#if defined(CONFIG_SYS_OR1_REMAP) - memctl->memc_or1 = CONFIG_SYS_OR1_REMAP; -#endif - - /* now restrict to preliminary range */ - /* the PS came from the HRCW, don´t change it */ - memctl->memc_br0 = SET_VAL_MASK(memctl->memc_br0 , CONFIG_SYS_BR0_PRELIM, BRx_PS_MSK); - memctl->memc_or0 = CONFIG_SYS_OR0_PRELIM; - -#if defined(CONFIG_SYS_BR1_PRELIM) && defined(CONFIG_SYS_OR1_PRELIM) - memctl->memc_or1 = CONFIG_SYS_OR1_PRELIM; - memctl->memc_br1 = CONFIG_SYS_BR1_PRELIM; -#endif - -#if defined(CONFIG_SYS_BR2_PRELIM) && defined(CONFIG_SYS_OR2_PRELIM) - memctl->memc_or2 = CONFIG_SYS_OR2_PRELIM; - memctl->memc_br2 = CONFIG_SYS_BR2_PRELIM; -#endif - -#if defined(CONFIG_SYS_BR3_PRELIM) && defined(CONFIG_SYS_OR3_PRELIM) - memctl->memc_or3 = CONFIG_SYS_OR3_PRELIM; - memctl->memc_br3 = CONFIG_SYS_BR3_PRELIM; -#endif - -#if defined(CONFIG_SYS_BR4_PRELIM) && defined(CONFIG_SYS_OR4_PRELIM) - memctl->memc_or4 = CONFIG_SYS_OR4_PRELIM; - memctl->memc_br4 = CONFIG_SYS_BR4_PRELIM; -#endif - -#if defined(CONFIG_SYS_BR5_PRELIM) && defined(CONFIG_SYS_OR5_PRELIM) - memctl->memc_or5 = CONFIG_SYS_OR5_PRELIM; - memctl->memc_br5 = CONFIG_SYS_BR5_PRELIM; -#endif - -#if defined(CONFIG_SYS_BR6_PRELIM) && defined(CONFIG_SYS_OR6_PRELIM) - memctl->memc_or6 = CONFIG_SYS_OR6_PRELIM; - memctl->memc_br6 = CONFIG_SYS_BR6_PRELIM; -#endif - -#if defined(CONFIG_SYS_BR7_PRELIM) && defined(CONFIG_SYS_OR7_PRELIM) - memctl->memc_or7 = CONFIG_SYS_OR7_PRELIM; - memctl->memc_br7 = CONFIG_SYS_BR7_PRELIM; -#endif - -#if defined(CONFIG_SYS_BR8_PRELIM) && defined(CONFIG_SYS_OR8_PRELIM) - memctl->memc_or8 = CONFIG_SYS_OR8_PRELIM; - memctl->memc_br8 = CONFIG_SYS_BR8_PRELIM; -#endif - -#if defined(CONFIG_SYS_BR9_PRELIM) && defined(CONFIG_SYS_OR9_PRELIM) - memctl->memc_or9 = CONFIG_SYS_OR9_PRELIM; - memctl->memc_br9 = CONFIG_SYS_BR9_PRELIM; -#endif - -#if defined(CONFIG_SYS_BR10_PRELIM) && defined(CONFIG_SYS_OR10_PRELIM) - memctl->memc_or10 = CONFIG_SYS_OR10_PRELIM; - memctl->memc_br10 = CONFIG_SYS_BR10_PRELIM; -#endif - -#if defined(CONFIG_SYS_BR11_PRELIM) && defined(CONFIG_SYS_OR11_PRELIM) - memctl->memc_or11 = CONFIG_SYS_OR11_PRELIM; - memctl->memc_br11 = CONFIG_SYS_BR11_PRELIM; -#endif - - m8260_cpm_reset (); -} - -/* - * initialize higher level parts of CPU like time base and timers - */ -int cpu_init_r (void) -{ - volatile immap_t *immr = (immap_t *) gd->bd->bi_immr_base; - - immr->im_cpm.cp_rccr = CONFIG_SYS_RCCR; - - return (0); -} - -/* - * print out the reason for the reset - */ -int prt_8260_rsr (void) -{ - static struct { - ulong mask; - char *desc; - } bits[] = { - { - RSR_JTRS, "JTAG"}, { - RSR_CSRS, "Check Stop"}, { - RSR_SWRS, "Software Watchdog"}, { - RSR_BMRS, "Bus Monitor"}, { - RSR_ESRS, "External Soft"}, { - RSR_EHRS, "External Hard"} - }; - static int n = sizeof bits / sizeof bits[0]; - ulong rsr = gd->reset_status; - int i; - char *sep; - - puts (CPU_ID_STR " Reset Status:"); - - sep = " "; - for (i = 0; i < n; i++) - if (rsr & bits[i].mask) { - printf ("%s%s", sep, bits[i].desc); - sep = ", "; - } - - puts ("\n\n"); - return (0); -} diff --git a/cpu/mpc8260/ether_fcc.c b/cpu/mpc8260/ether_fcc.c deleted file mode 100644 index 5ac02a0..0000000 --- a/cpu/mpc8260/ether_fcc.c +++ /dev/null @@ -1,1190 +0,0 @@ -/* - * MPC8260 FCC Fast Ethernet - * - * Copyright (c) 2000 MontaVista Software, Inc. Dan Malek (dmalek@jlc.net) - * - * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com> - * Marius Groeger <mgroeger@sysgo.de> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * MPC8260 FCC Fast Ethernet - * Basic ET HW initialization and packet RX/TX routines - * - * This code will not perform the IO port configuration. This should be - * done in the iop_conf_t structure specific for the board. - * - * TODO: - * add a PHY driver to do the negotiation - * reflect negotiation results in FPSMR - * look for ways to configure the board specific stuff elsewhere, eg. - * config_xxx.h or the board directory - */ - -#include <common.h> -#include <malloc.h> -#include <asm/cpm_8260.h> -#include <mpc8260.h> -#include <command.h> -#include <config.h> -#include <net.h> - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) -#include <miiphy.h> -#endif - -DECLARE_GLOBAL_DATA_PTR; - -#if defined(CONFIG_ETHER_ON_FCC) && defined(CONFIG_CMD_NET) && \ - defined(CONFIG_NET_MULTI) - -static struct ether_fcc_info_s -{ - int ether_index; - int proff_enet; - ulong cpm_cr_enet_sblock; - ulong cpm_cr_enet_page; - ulong cmxfcr_mask; - ulong cmxfcr_value; -} - ether_fcc_info[] = -{ -#ifdef CONFIG_ETHER_ON_FCC1 -{ - 0, - PROFF_FCC1, - CPM_CR_FCC1_SBLOCK, - CPM_CR_FCC1_PAGE, - CONFIG_SYS_CMXFCR_MASK1, - CONFIG_SYS_CMXFCR_VALUE1 -}, -#endif - -#ifdef CONFIG_ETHER_ON_FCC2 -{ - 1, - PROFF_FCC2, - CPM_CR_FCC2_SBLOCK, - CPM_CR_FCC2_PAGE, - CONFIG_SYS_CMXFCR_MASK2, - CONFIG_SYS_CMXFCR_VALUE2 -}, -#endif - -#ifdef CONFIG_ETHER_ON_FCC3 -{ - 2, - PROFF_FCC3, - CPM_CR_FCC3_SBLOCK, - CPM_CR_FCC3_PAGE, - CONFIG_SYS_CMXFCR_MASK3, - CONFIG_SYS_CMXFCR_VALUE3 -}, -#endif -}; - -/*---------------------------------------------------------------------*/ - -/* Maximum input DMA size. Must be a should(?) be a multiple of 4. */ -#define PKT_MAXDMA_SIZE 1520 - -/* The FCC stores dest/src/type, data, and checksum for receive packets. */ -#define PKT_MAXBUF_SIZE 1518 -#define PKT_MINBUF_SIZE 64 - -/* Maximum input buffer size. Must be a multiple of 32. */ -#define PKT_MAXBLR_SIZE 1536 - -#define TOUT_LOOP 1000000 - -#define TX_BUF_CNT 2 -#ifdef __GNUC__ -static char txbuf[TX_BUF_CNT][PKT_MAXBLR_SIZE] __attribute__ ((aligned(8))); -#else -#error "txbuf must be 64-bit aligned" -#endif - -static uint rxIdx; /* index of the current RX buffer */ -static uint txIdx; /* index of the current TX buffer */ - -/* - * FCC Ethernet Tx and Rx buffer descriptors. - * Provide for Double Buffering - * Note: PKTBUFSRX is defined in net.h - */ - -typedef volatile struct rtxbd { - cbd_t rxbd[PKTBUFSRX]; - cbd_t txbd[TX_BUF_CNT]; -} RTXBD; - -/* Good news: the FCC supports external BDs! */ -#ifdef __GNUC__ -static RTXBD rtx __attribute__ ((aligned(8))); -#else -#error "rtx must be 64-bit aligned" -#endif - -static int fec_send(struct eth_device* dev, volatile void *packet, int length) -{ - int i; - int result = 0; - - if (length <= 0) { - printf("fec: bad packet size: %d\n", length); - goto out; - } - - for(i=0; rtx.txbd[txIdx].cbd_sc & BD_ENET_TX_READY; i++) { - if (i >= TOUT_LOOP) { - puts ("fec: tx buffer not ready\n"); - goto out; - } - } - - rtx.txbd[txIdx].cbd_bufaddr = (uint)packet; - rtx.txbd[txIdx].cbd_datlen = length; - rtx.txbd[txIdx].cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_LAST | - BD_ENET_TX_WRAP); - - for(i=0; rtx.txbd[txIdx].cbd_sc & BD_ENET_TX_READY; i++) { - if (i >= TOUT_LOOP) { - puts ("fec: tx error\n"); - goto out; - } - } - -#ifdef ET_DEBUG - printf("cycles: %d status: %04x\n", i, rtx.txbd[txIdx].cbd_sc); -#endif - - /* return only status bits */ - result = rtx.txbd[txIdx].cbd_sc & BD_ENET_TX_STATS; - -out: - return result; -} - -static int fec_recv(struct eth_device* dev) -{ - int length; - - for (;;) - { - if (rtx.rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) { - length = -1; - break; /* nothing received - leave for() loop */ - } - length = rtx.rxbd[rxIdx].cbd_datlen; - - if (rtx.rxbd[rxIdx].cbd_sc & 0x003f) { - printf("fec: rx error %04x\n", rtx.rxbd[rxIdx].cbd_sc); - } - else { - /* Pass the packet up to the protocol layers. */ - NetReceive(NetRxPackets[rxIdx], length - 4); - } - - - /* Give the buffer back to the FCC. */ - rtx.rxbd[rxIdx].cbd_datlen = 0; - - /* wrap around buffer index when necessary */ - if ((rxIdx + 1) >= PKTBUFSRX) { - rtx.rxbd[PKTBUFSRX - 1].cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY); - rxIdx = 0; - } - else { - rtx.rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY; - rxIdx++; - } - } - return length; -} - - -static int fec_init(struct eth_device* dev, bd_t *bis) -{ - struct ether_fcc_info_s * info = dev->priv; - int i; - volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; - volatile cpm8260_t *cp = &(immr->im_cpm); - fcc_enet_t *pram_ptr; - unsigned long mem_addr; - -#if 0 - mii_discover_phy(); -#endif - - /* 28.9 - (1-2): ioports have been set up already */ - - /* 28.9 - (3): connect FCC's tx and rx clocks */ - immr->im_cpmux.cmx_uar = 0; - immr->im_cpmux.cmx_fcr = (immr->im_cpmux.cmx_fcr & ~info->cmxfcr_mask) | - info->cmxfcr_value; - - /* 28.9 - (4): GFMR: disable tx/rx, CCITT CRC, Mode Ethernet */ - immr->im_fcc[info->ether_index].fcc_gfmr = - FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32; - - /* 28.9 - (5): FPSMR: enable full duplex, select CCITT CRC for Ethernet */ - immr->im_fcc[info->ether_index].fcc_fpsmr = CONFIG_SYS_FCC_PSMR | FCC_PSMR_ENCRC; - - /* 28.9 - (6): FDSR: Ethernet Syn */ - immr->im_fcc[info->ether_index].fcc_fdsr = 0xD555; - - /* reset indeces to current rx/tx bd (see eth_send()/eth_rx()) */ - rxIdx = 0; - txIdx = 0; - - /* Setup Receiver Buffer Descriptors */ - for (i = 0; i < PKTBUFSRX; i++) - { - rtx.rxbd[i].cbd_sc = BD_ENET_RX_EMPTY; - rtx.rxbd[i].cbd_datlen = 0; - rtx.rxbd[i].cbd_bufaddr = (uint)NetRxPackets[i]; - } - rtx.rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP; - - /* Setup Ethernet Transmitter Buffer Descriptors */ - for (i = 0; i < TX_BUF_CNT; i++) - { - rtx.txbd[i].cbd_sc = (BD_ENET_TX_PAD | BD_ENET_TX_LAST | BD_ENET_TX_TC); - rtx.txbd[i].cbd_datlen = 0; - rtx.txbd[i].cbd_bufaddr = (uint)&txbuf[i][0]; - } - rtx.txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP; - - /* 28.9 - (7): initialise parameter ram */ - pram_ptr = (fcc_enet_t *)&(immr->im_dprambase[info->proff_enet]); - - /* clear whole structure to make sure all reserved fields are zero */ - memset((void*)pram_ptr, 0, sizeof(fcc_enet_t)); - - /* - * common Parameter RAM area - * - * Allocate space in the reserved FCC area of DPRAM for the - * internal buffers. No one uses this space (yet), so we - * can do this. Later, we will add resource management for - * this area. - */ - mem_addr = CPM_FCC_SPECIAL_BASE + ((info->ether_index) * 64); - pram_ptr->fen_genfcc.fcc_riptr = mem_addr; - pram_ptr->fen_genfcc.fcc_tiptr = mem_addr+32; - /* - * Set maximum bytes per receive buffer. - * It must be a multiple of 32. - */ - pram_ptr->fen_genfcc.fcc_mrblr = PKT_MAXBLR_SIZE; - pram_ptr->fen_genfcc.fcc_rstate = (CPMFCR_GBL | CPMFCR_EB | - CONFIG_SYS_CPMFCR_RAMTYPE) << 24; - pram_ptr->fen_genfcc.fcc_rbase = (unsigned int)(&rtx.rxbd[rxIdx]); - pram_ptr->fen_genfcc.fcc_tstate = (CPMFCR_GBL | CPMFCR_EB | - CONFIG_SYS_CPMFCR_RAMTYPE) << 24; - pram_ptr->fen_genfcc.fcc_tbase = (unsigned int)(&rtx.txbd[txIdx]); - - /* protocol-specific area */ - pram_ptr->fen_cmask = 0xdebb20e3; /* CRC mask */ - pram_ptr->fen_cpres = 0xffffffff; /* CRC preset */ - pram_ptr->fen_retlim = 15; /* Retry limit threshold */ - pram_ptr->fen_mflr = PKT_MAXBUF_SIZE; /* maximum frame length register */ - /* - * Set Ethernet station address. - * - * This is supplied in the board information structure, so we - * copy that into the controller. - * So, far we have only been given one Ethernet address. We make - * it unique by setting a few bits in the upper byte of the - * non-static part of the address. - */ -#define ea eth_get_dev()->enetaddr - pram_ptr->fen_paddrh = (ea[5] << 8) + ea[4]; - pram_ptr->fen_paddrm = (ea[3] << 8) + ea[2]; - pram_ptr->fen_paddrl = (ea[1] << 8) + ea[0]; -#undef ea - pram_ptr->fen_minflr = PKT_MINBUF_SIZE; /* minimum frame length register */ - /* pad pointer. use tiptr since we don't need a specific padding char */ - pram_ptr->fen_padptr = pram_ptr->fen_genfcc.fcc_tiptr; - pram_ptr->fen_maxd1 = PKT_MAXDMA_SIZE; /* maximum DMA1 length */ - pram_ptr->fen_maxd2 = PKT_MAXDMA_SIZE; /* maximum DMA2 length */ - pram_ptr->fen_rfthr = 1; - pram_ptr->fen_rfcnt = 1; -#if 0 - printf("pram_ptr->fen_genfcc.fcc_rbase %08lx\n", - pram_ptr->fen_genfcc.fcc_rbase); - printf("pram_ptr->fen_genfcc.fcc_tbase %08lx\n", - pram_ptr->fen_genfcc.fcc_tbase); -#endif - - /* 28.9 - (8): clear out events in FCCE */ - immr->im_fcc[info->ether_index].fcc_fcce = ~0x0; - - /* 28.9 - (9): FCCM: mask all events */ - immr->im_fcc[info->ether_index].fcc_fccm = 0; - - /* 28.9 - (10-12): we don't use ethernet interrupts */ - - /* 28.9 - (13) - * - * Let's re-initialize the channel now. We have to do it later - * than the manual describes because we have just now finished - * the BD initialization. - */ - cp->cp_cpcr = mk_cr_cmd(info->cpm_cr_enet_page, - info->cpm_cr_enet_sblock, - 0x0c, - CPM_CR_INIT_TRX) | CPM_CR_FLG; - do { - __asm__ __volatile__ ("eieio"); - } while (cp->cp_cpcr & CPM_CR_FLG); - - /* 28.9 - (14): enable tx/rx in gfmr */ - immr->im_fcc[info->ether_index].fcc_gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR; - - return 1; -} - -static void fec_halt(struct eth_device* dev) -{ - struct ether_fcc_info_s * info = dev->priv; - volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; - - /* write GFMR: disable tx/rx */ - immr->im_fcc[info->ether_index].fcc_gfmr &= - ~(FCC_GFMR_ENT | FCC_GFMR_ENR); -} - -int fec_initialize(bd_t *bis) -{ - struct eth_device* dev; - int i; - - for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++) - { - dev = (struct eth_device*) malloc(sizeof *dev); - memset(dev, 0, sizeof *dev); - - sprintf(dev->name, "FCC%d ETHERNET", - ether_fcc_info[i].ether_index + 1); - dev->priv = ðer_fcc_info[i]; - dev->init = fec_init; - dev->halt = fec_halt; - dev->send = fec_send; - dev->recv = fec_recv; - - eth_register(dev); - -#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) \ - && defined(CONFIG_BITBANGMII) - miiphy_register(dev->name, - bb_miiphy_read, bb_miiphy_write); -#endif - } - - return 1; -} - -#ifdef CONFIG_ETHER_LOOPBACK_TEST - -#define ELBT_BUFSZ 1024 /* must be multiple of 32 */ - -#define ELBT_CRCSZ 4 - -#define ELBT_NRXBD 4 /* must be at least 2 */ -#define ELBT_NTXBD 4 - -#define ELBT_MAXRXERR 32 -#define ELBT_MAXTXERR 32 - -#define ELBT_CLSWAIT 1000 /* msec to wait for further input frames */ - -typedef - struct { - uint off; - char *lab; - } -elbt_prdesc; - -typedef - struct { - uint _l, _f, m, bc, mc, lg, no, sh, cr, ov, cl; - uint badsrc, badtyp, badlen, badbit; - } -elbt_rxeacc; - -static elbt_prdesc rxeacc_descs[] = { - { offsetof(elbt_rxeacc, _l), "Not Last in Frame" }, - { offsetof(elbt_rxeacc, _f), "Not First in Frame" }, - { offsetof(elbt_rxeacc, m), "Address Miss" }, - { offsetof(elbt_rxeacc, bc), "Broadcast Address" }, - { offsetof(elbt_rxeacc, mc), "Multicast Address" }, - { offsetof(elbt_rxeacc, lg), "Frame Length Violation"}, - { offsetof(elbt_rxeacc, no), "Non-Octet Alignment" }, - { offsetof(elbt_rxeacc, sh), "Short Frame" }, - { offsetof(elbt_rxeacc, cr), "CRC Error" }, - { offsetof(elbt_rxeacc, ov), "Overrun" }, - { offsetof(elbt_rxeacc, cl), "Collision" }, - { offsetof(elbt_rxeacc, badsrc), "Bad Src Address" }, - { offsetof(elbt_rxeacc, badtyp), "Bad Frame Type" }, - { offsetof(elbt_rxeacc, badlen), "Bad Frame Length" }, - { offsetof(elbt_rxeacc, badbit), "Data Compare Errors" }, -}; -static int rxeacc_ndesc = sizeof (rxeacc_descs) / sizeof (rxeacc_descs[0]); - -typedef - struct { - uint def, hb, lc, rl, rc, un, csl; - } -elbt_txeacc; - -static elbt_prdesc txeacc_descs[] = { - { offsetof(elbt_txeacc, def), "Defer Indication" }, - { offsetof(elbt_txeacc, hb), "Heartbeat" }, - { offsetof(elbt_txeacc, lc), "Late Collision" }, - { offsetof(elbt_txeacc, rl), "Retransmission Limit" }, - { offsetof(elbt_txeacc, rc), "Retry Count" }, - { offsetof(elbt_txeacc, un), "Underrun" }, - { offsetof(elbt_txeacc, csl), "Carrier Sense Lost" }, -}; -static int txeacc_ndesc = sizeof (txeacc_descs) / sizeof (txeacc_descs[0]); - -typedef - struct { - uchar rxbufs[ELBT_NRXBD][ELBT_BUFSZ]; - uchar txbufs[ELBT_NTXBD][ELBT_BUFSZ]; - cbd_t rxbd[ELBT_NRXBD]; - cbd_t txbd[ELBT_NTXBD]; - enum { Idle, Running, Closing, Closed } state; - int proff, page, sblock; - uint clstime, nsent, ntxerr, nrcvd, nrxerr; - ushort rxerrs[ELBT_MAXRXERR], txerrs[ELBT_MAXTXERR]; - elbt_rxeacc rxeacc; - elbt_txeacc txeacc; - } __attribute__ ((aligned(8))) -elbt_chan; - -static uchar patbytes[ELBT_NTXBD] = { - 0xff, 0xaa, 0x55, 0x00 -}; -static uint patwords[ELBT_NTXBD] = { - 0xffffffff, 0xaaaaaaaa, 0x55555555, 0x00000000 -}; - -#ifdef __GNUC__ -static elbt_chan elbt_chans[3] __attribute__ ((aligned(8))); -#else -#error "elbt_chans must be 64-bit aligned" -#endif - -#define CPM_CR_GRACEFUL_STOP_TX ((ushort)0x0005) - -static elbt_prdesc epram_descs[] = { - { offsetof(fcc_enet_t, fen_crcec), "CRC Errors" }, - { offsetof(fcc_enet_t, fen_alec), "Alignment Errors" }, - { offsetof(fcc_enet_t, fen_disfc), "Discarded Frames" }, - { offsetof(fcc_enet_t, fen_octc), "Octets" }, - { offsetof(fcc_enet_t, fen_colc), "Collisions" }, - { offsetof(fcc_enet_t, fen_broc), "Broadcast Frames" }, - { offsetof(fcc_enet_t, fen_mulc), "Multicast Frames" }, - { offsetof(fcc_enet_t, fen_uspc), "Undersize Frames" }, - { offsetof(fcc_enet_t, fen_frgc), "Fragments" }, - { offsetof(fcc_enet_t, fen_ospc), "Oversize Frames" }, - { offsetof(fcc_enet_t, fen_jbrc), "Jabbers" }, - { offsetof(fcc_enet_t, fen_p64c), "64 Octet Frames" }, - { offsetof(fcc_enet_t, fen_p65c), "65-127 Octet Frames" }, - { offsetof(fcc_enet_t, fen_p128c), "128-255 Octet Frames" }, - { offsetof(fcc_enet_t, fen_p256c), "256-511 Octet Frames" }, - { offsetof(fcc_enet_t, fen_p512c), "512-1023 Octet Frames" }, - { offsetof(fcc_enet_t, fen_p1024c), "1024-1518 Octet Frames"}, -}; -static int epram_ndesc = sizeof (epram_descs) / sizeof (epram_descs[0]); - -/* - * given an elbt_prdesc array and an array of base addresses, print - * each prdesc down the screen with the values fetched from each - * base address across the screen - */ -static void -print_desc (elbt_prdesc descs[], int ndesc, uchar *bases[], int nbase) -{ - elbt_prdesc *dp = descs, *edp = dp + ndesc; - int i; - - printf ("%32s", ""); - - for (i = 0; i < nbase; i++) - printf (" Channel %d", i); - - putc ('\n'); - - while (dp < edp) { - - printf ("%-32s", dp->lab); - - for (i = 0; i < nbase; i++) { - uint val = *(uint *)(bases[i] + dp->off); - - printf (" %10u", val); - } - - putc ('\n'); - - dp++; - } -} - -/* - * return number of bits that are set in a value; value contains - * nbits (right-justified) bits. - */ -static uint __inline__ -nbs (uint value, uint nbits) -{ - uint cnt = 0; -#if 1 - uint pos = sizeof (uint) * 8; - - __asm__ __volatile__ ("\ - mtctr %2\n\ -1: rlwnm. %2,%1,%4,31,31\n\ - beq 2f\n\ - addi %0,%0,1\n\ -2: subi %4,%4,1\n\ - bdnz 1b" - : "=r"(cnt) - : "r"(value), "r"(nbits), "r"(cnt), "r"(pos) - : "ctr", "cc" ); -#else - uint mask = 1; - - do { - if (value & mask) - cnt++; - mask <<= 1; - } while (--nbits); -#endif - - return (cnt); -} - -static ulong -badbits (uchar *bp, int n, ulong pat) -{ - ulong *lp, cnt = 0; - int nl; - - while (n > 0 && ((ulong)bp & (sizeof (ulong) - 1)) != 0) { - uchar diff; - - diff = *bp++ ^ (uchar)pat; - - if (diff) - cnt += nbs ((ulong)diff, 8); - - n--; - } - - lp = (ulong *)bp; - nl = n / sizeof (ulong); - n -= nl * sizeof (ulong); - - while (nl > 0) { - ulong diff; - - diff = *lp++ ^ pat; - - if (diff) - cnt += nbs (diff, 32); - - nl--; - } - - bp = (uchar *)lp; - - while (n > 0) { - uchar diff; - - diff = *bp++ ^ (uchar)pat; - - if (diff) - cnt += nbs ((ulong)diff, 8); - - n--; - } - - return (cnt); -} - -static inline unsigned short -swap16 (unsigned short x) -{ - return (((x & 0xff) << 8) | ((x & 0xff00) >> 8)); -} - -/* broadcast is not an error - we send them like that */ -#define BD_ENET_RX_ERRS (BD_ENET_RX_STATS & ~BD_ENET_RX_BC) - -void -eth_loopback_test (void) -{ - volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; - volatile cpm8260_t *cp = &(immr->im_cpm); - int c, nclosed; - ulong runtime, nmsec; - uchar *bases[3]; - - puts ("FCC Ethernet External loopback test\n"); - - eth_getenv_enetaddr("ethaddr", NetOurEther); - - /* - * global initialisations for all FCC channels - */ - - /* 28.9 - (1-2): ioports have been set up already */ - -#if defined(CONFIG_HYMOD) - /* - * Attention: this is board-specific - * 0, FCC1 - * 1, FCC2 - * 2, FCC3 - */ -# define FCC_START_LOOP 0 -# define FCC_END_LOOP 2 - - /* - * Attention: this is board-specific - * - FCC1 Rx-CLK is CLK10 - * - FCC1 Tx-CLK is CLK11 - * - FCC2 Rx-CLK is CLK13 - * - FCC2 Tx-CLK is CLK14 - * - FCC3 Rx-CLK is CLK15 - * - FCC3 Tx-CLK is CLK16 - */ - - /* 28.9 - (3): connect FCC's tx and rx clocks */ - immr->im_cpmux.cmx_uar = 0; - immr->im_cpmux.cmx_fcr = CMXFCR_RF1CS_CLK10|CMXFCR_TF1CS_CLK11|\ - CMXFCR_RF2CS_CLK13|CMXFCR_TF2CS_CLK14|\ - CMXFCR_RF3CS_CLK15|CMXFCR_TF3CS_CLK16; -#elif defined(CONFIG_SBC8260) || defined(CONFIG_SACSng) - /* - * Attention: this is board-specific - * 1, FCC2 - */ -# define FCC_START_LOOP 1 -# define FCC_END_LOOP 1 - - /* - * Attention: this is board-specific - * - FCC2 Rx-CLK is CLK13 - * - FCC2 Tx-CLK is CLK14 - */ - - /* 28.9 - (3): connect FCC's tx and rx clocks */ - immr->im_cpmux.cmx_uar = 0; - immr->im_cpmux.cmx_fcr = CMXFCR_RF2CS_CLK13|CMXFCR_TF2CS_CLK14; -#else -#error "eth_loopback_test not supported on your board" -#endif - - puts ("Initialise FCC channels:"); - - for (c = FCC_START_LOOP; c <= FCC_END_LOOP; c++) { - elbt_chan *ecp = &elbt_chans[c]; - volatile fcc_t *fcp = &immr->im_fcc[c]; - volatile fcc_enet_t *fpp; - int i; - ulong addr; - - /* - * initialise channel data - */ - - printf (" %d", c); - - memset ((void *)ecp, 0, sizeof (*ecp)); - - ecp->state = Idle; - - switch (c) { - - case 0: /* FCC1 */ - ecp->proff = PROFF_FCC1; - ecp->page = CPM_CR_FCC1_PAGE; - ecp->sblock = CPM_CR_FCC1_SBLOCK; - break; - - case 1: /* FCC2 */ - ecp->proff = PROFF_FCC2; - ecp->page = CPM_CR_FCC2_PAGE; - ecp->sblock = CPM_CR_FCC2_SBLOCK; - break; - - case 2: /* FCC3 */ - ecp->proff = PROFF_FCC3; - ecp->page = CPM_CR_FCC3_PAGE; - ecp->sblock = CPM_CR_FCC3_SBLOCK; - break; - } - - /* - * set up tx buffers and bds - */ - - for (i = 0; i < ELBT_NTXBD; i++) { - cbd_t *bdp = &ecp->txbd[i]; - uchar *bp = &ecp->txbufs[i][0]; - - bdp->cbd_bufaddr = (uint)bp; - /* room for crc */ - bdp->cbd_datlen = ELBT_BUFSZ - ELBT_CRCSZ; - bdp->cbd_sc = BD_ENET_TX_READY | BD_ENET_TX_PAD | \ - BD_ENET_TX_LAST | BD_ENET_TX_TC; - - memset ((void *)bp, patbytes[i], ELBT_BUFSZ); - NetSetEther (bp, NetBcastAddr, 0x8000); - } - ecp->txbd[ELBT_NTXBD - 1].cbd_sc |= BD_ENET_TX_WRAP; - - /* - * set up rx buffers and bds - */ - - for (i = 0; i < ELBT_NRXBD; i++) { - cbd_t *bdp = &ecp->rxbd[i]; - uchar *bp = &ecp->rxbufs[i][0]; - - bdp->cbd_bufaddr = (uint)bp; - bdp->cbd_datlen = 0; - bdp->cbd_sc = BD_ENET_RX_EMPTY; - - memset ((void *)bp, 0, ELBT_BUFSZ); - } - ecp->rxbd[ELBT_NRXBD - 1].cbd_sc |= BD_ENET_RX_WRAP; - - /* - * set up the FCC channel hardware - */ - - /* 28.9 - (4): GFMR: disable tx/rx, CCITT CRC, Mode Ethernet */ - fcp->fcc_gfmr = FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32; - - /* 28.9 - (5): FPSMR: fd, enet CRC, Promis, RMON, Rx SHort */ - fcp->fcc_fpsmr = FCC_PSMR_FDE | FCC_PSMR_LPB | \ - FCC_PSMR_ENCRC | FCC_PSMR_PRO | \ - FCC_PSMR_MON | FCC_PSMR_RSH; - - /* 28.9 - (6): FDSR: Ethernet Syn */ - fcp->fcc_fdsr = 0xD555; - - /* 29.9 - (7): initialise parameter ram */ - fpp = (fcc_enet_t *)&(immr->im_dprambase[ecp->proff]); - - /* clear whole struct to make sure all resv fields are zero */ - memset ((void *)fpp, 0, sizeof (fcc_enet_t)); - - /* - * common Parameter RAM area - * - * Allocate space in the reserved FCC area of DPRAM for the - * internal buffers. No one uses this space (yet), so we - * can do this. Later, we will add resource management for - * this area. - */ - addr = CPM_FCC_SPECIAL_BASE + (c * 64); - fpp->fen_genfcc.fcc_riptr = addr; - fpp->fen_genfcc.fcc_tiptr = addr + 32; - - /* - * Set maximum bytes per receive buffer. - * It must be a multiple of 32. - * buffers are in 60x bus memory. - */ - fpp->fen_genfcc.fcc_mrblr = PKT_MAXBLR_SIZE; - fpp->fen_genfcc.fcc_rstate = (CPMFCR_GBL | CPMFCR_EB) << 24; - fpp->fen_genfcc.fcc_rbase = (unsigned int)(&ecp->rxbd[0]); - fpp->fen_genfcc.fcc_tstate = (CPMFCR_GBL | CPMFCR_EB) << 24; - fpp->fen_genfcc.fcc_tbase = (unsigned int)(&ecp->txbd[0]); - - /* protocol-specific area */ - fpp->fen_cmask = 0xdebb20e3; /* CRC mask */ - fpp->fen_cpres = 0xffffffff; /* CRC preset */ - fpp->fen_retlim = 15; /* Retry limit threshold */ - fpp->fen_mflr = PKT_MAXBUF_SIZE;/* max frame length register */ - - /* - * Set Ethernet station address. - * - * This is supplied in the board information structure, so we - * copy that into the controller. - * So, far we have only been given one Ethernet address. We use - * the same address for all channels - */ -#define ea NetOurEther - fpp->fen_paddrh = (ea[5] << 8) + ea[4]; - fpp->fen_paddrm = (ea[3] << 8) + ea[2]; - fpp->fen_paddrl = (ea[1] << 8) + ea[0]; -#undef ea - - fpp->fen_minflr = PKT_MINBUF_SIZE; /* min frame len register */ - /* - * pad pointer. use tiptr since we don't need - * a specific padding char - */ - fpp->fen_padptr = fpp->fen_genfcc.fcc_tiptr; - fpp->fen_maxd1 = PKT_MAXDMA_SIZE; /* max DMA1 length */ - fpp->fen_maxd2 = PKT_MAXDMA_SIZE; /* max DMA2 length */ - fpp->fen_rfthr = 1; - fpp->fen_rfcnt = 1; - - /* 28.9 - (8): clear out events in FCCE */ - fcp->fcc_fcce = ~0x0; - - /* 28.9 - (9): FCCM: mask all events */ - fcp->fcc_fccm = 0; - - /* 28.9 - (10-12): we don't use ethernet interrupts */ - - /* 28.9 - (13) - * - * Let's re-initialize the channel now. We have to do it later - * than the manual describes because we have just now finished - * the BD initialization. - */ - cp->cp_cpcr = mk_cr_cmd (ecp->page, ecp->sblock, \ - 0x0c, CPM_CR_INIT_TRX) | CPM_CR_FLG; - do { - __asm__ __volatile__ ("eieio"); - } while (cp->cp_cpcr & CPM_CR_FLG); - } - - puts (" done\nStarting test... (Ctrl-C to Finish)\n"); - - /* - * Note: don't want serial output from here until the end of the - * test - the delays would probably stuff things up. - */ - - clear_ctrlc (); - runtime = get_timer (0); - - do { - nclosed = 0; - - for (c = FCC_START_LOOP; c <= FCC_END_LOOP; c++) { - volatile fcc_t *fcp = &immr->im_fcc[c]; - elbt_chan *ecp = &elbt_chans[c]; - int i; - - switch (ecp->state) { - - case Idle: - /* - * set the channel Running ... - */ - - /* 28.9 - (14): enable tx/rx in gfmr */ - fcp->fcc_gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR; - - ecp->state = Running; - break; - - case Running: - /* - * (while Running only) check for - * termination of the test - */ - - (void)ctrlc (); - - if (had_ctrlc ()) { - /* - * initiate a "graceful stop transmit" - * on the channel - */ - cp->cp_cpcr = mk_cr_cmd (ecp->page, \ - ecp->sblock, 0x0c, \ - CPM_CR_GRACEFUL_STOP_TX) | \ - CPM_CR_FLG; - do { - __asm__ __volatile__ ("eieio"); - } while (cp->cp_cpcr & CPM_CR_FLG); - - ecp->clstime = get_timer (0); - ecp->state = Closing; - } - /* fall through ... */ - - case Closing: - /* - * (while Running or Closing) poll the channel: - * - check for any non-READY tx buffers and - * make them ready - * - check for any non-EMPTY rx buffers and - * check that they were received correctly, - * adjust counters etc, then make empty - */ - - for (i = 0; i < ELBT_NTXBD; i++) { - cbd_t *bdp = &ecp->txbd[i]; - ushort sc = bdp->cbd_sc; - - if ((sc & BD_ENET_TX_READY) != 0) - continue; - - /* - * this frame has finished - * transmitting - */ - ecp->nsent++; - - if (sc & BD_ENET_TX_STATS) { - ulong n; - - /* - * we had an error on - * the transmission - */ - n = ecp->ntxerr++; - if (n < ELBT_MAXTXERR) - ecp->txerrs[n] = sc; - - if (sc & BD_ENET_TX_DEF) - ecp->txeacc.def++; - if (sc & BD_ENET_TX_HB) - ecp->txeacc.hb++; - if (sc & BD_ENET_TX_LC) - ecp->txeacc.lc++; - if (sc & BD_ENET_TX_RL) - ecp->txeacc.rl++; - if (sc & BD_ENET_TX_RCMASK) - ecp->txeacc.rc++; - if (sc & BD_ENET_TX_UN) - ecp->txeacc.un++; - if (sc & BD_ENET_TX_CSL) - ecp->txeacc.csl++; - - bdp->cbd_sc &= \ - ~BD_ENET_TX_STATS; - } - - if (ecp->state == Closing) - ecp->clstime = get_timer (0); - - /* make it ready again */ - bdp->cbd_sc |= BD_ENET_TX_READY; - } - - for (i = 0; i < ELBT_NRXBD; i++) { - cbd_t *bdp = &ecp->rxbd[i]; - ushort sc = bdp->cbd_sc, mask; - - if ((sc & BD_ENET_RX_EMPTY) != 0) - continue; - - /* we have a new frame in this buffer */ - ecp->nrcvd++; - - mask = BD_ENET_RX_LAST|BD_ENET_RX_FIRST; - if ((sc & mask) != mask) { - /* somethings wrong here ... */ - if (!(sc & BD_ENET_RX_LAST)) - ecp->rxeacc._l++; - if (!(sc & BD_ENET_RX_FIRST)) - ecp->rxeacc._f++; - } - - if (sc & BD_ENET_RX_ERRS) { - ulong n; - - /* - * we had some sort of error - * on the frame - */ - n = ecp->nrxerr++; - if (n < ELBT_MAXRXERR) - ecp->rxerrs[n] = sc; - - if (sc & BD_ENET_RX_MISS) - ecp->rxeacc.m++; - if (sc & BD_ENET_RX_BC) - ecp->rxeacc.bc++; - if (sc & BD_ENET_RX_MC) - ecp->rxeacc.mc++; - if (sc & BD_ENET_RX_LG) - ecp->rxeacc.lg++; - if (sc & BD_ENET_RX_NO) - ecp->rxeacc.no++; - if (sc & BD_ENET_RX_SH) - ecp->rxeacc.sh++; - if (sc & BD_ENET_RX_CR) - ecp->rxeacc.cr++; - if (sc & BD_ENET_RX_OV) - ecp->rxeacc.ov++; - if (sc & BD_ENET_RX_CL) - ecp->rxeacc.cl++; - - bdp->cbd_sc &= \ - ~BD_ENET_RX_ERRS; - } - else { - ushort datlen = bdp->cbd_datlen; - Ethernet_t *ehp; - ushort prot; - int ours, tb, n, nbytes; - - ehp = (Ethernet_t *) \ - &ecp->rxbufs[i][0]; - - ours = memcmp (ehp->et_src, \ - NetOurEther, 6); - - prot = swap16 (ehp->et_protlen); - tb = prot & 0x8000; - n = prot & 0x7fff; - - nbytes = ELBT_BUFSZ - \ - offsetof (Ethernet_t, \ - et_dsap) - \ - ELBT_CRCSZ; - - /* check the frame is correct */ - if (datlen != ELBT_BUFSZ) - ecp->rxeacc.badlen++; - else if (!ours) - ecp->rxeacc.badsrc++; - else if (!tb || n >= ELBT_NTXBD) - ecp->rxeacc.badtyp++; - else { - ulong patword = \ - patwords[n]; - uint nbb; - - nbb = badbits ( \ - &ehp->et_dsap, \ - nbytes, \ - patword); - - ecp->rxeacc.badbit += \ - nbb; - } - } - - if (ecp->state == Closing) - ecp->clstime = get_timer (0); - - /* make it empty again */ - bdp->cbd_sc |= BD_ENET_RX_EMPTY; - } - - if (ecp->state != Closing) - break; - - /* - * (while Closing) check to see if - * waited long enough - */ - - if (get_timer (ecp->clstime) >= ELBT_CLSWAIT) { - /* write GFMR: disable tx/rx */ - fcp->fcc_gfmr &= \ - ~(FCC_GFMR_ENT | FCC_GFMR_ENR); - ecp->state = Closed; - } - - break; - - case Closed: - nclosed++; - break; - } - } - - } while (nclosed < (FCC_END_LOOP - FCC_START_LOOP + 1)); - - runtime = get_timer (runtime); - if (runtime <= ELBT_CLSWAIT) { - printf ("Whoops! somehow elapsed time (%ld) is wrong (<= %d)\n", - runtime, ELBT_CLSWAIT); - return; - } - nmsec = runtime - ELBT_CLSWAIT; - - printf ("Test Finished in %ldms (plus %dms close wait period)!\n\n", - nmsec, ELBT_CLSWAIT); - - /* - * now print stats - */ - - for (c = FCC_START_LOOP; c <= FCC_END_LOOP; c++) { - elbt_chan *ecp = &elbt_chans[c]; - uint rxpps, txpps, nerr; - - rxpps = (ecp->nrcvd * 1000) / nmsec; - txpps = (ecp->nsent * 1000) / nmsec; - - printf ("Channel %d: %d rcvd (%d pps, %d rxerrs), " - "%d sent (%d pps, %d txerrs)\n\n", c, - ecp->nrcvd, rxpps, ecp->nrxerr, - ecp->nsent, txpps, ecp->ntxerr); - - if ((nerr = ecp->nrxerr) > 0) { - ulong i; - - printf ("\tFirst %d rx errs:", nerr); - for (i = 0; i < nerr; i++) - printf (" %04x", ecp->rxerrs[i]); - putc ('\n'); - } - - if ((nerr = ecp->ntxerr) > 0) { - ulong i; - - printf ("\tFirst %d tx errs:", nerr); - for (i = 0; i < nerr; i++) - printf (" %04x", ecp->txerrs[i]); - putc ('\n'); - } - } - - puts ("Receive Error Counts:\n"); - for (c = FCC_START_LOOP; c <= FCC_END_LOOP; c++) - bases[c] = (uchar *)&elbt_chans[c].rxeacc; - print_desc (rxeacc_descs, rxeacc_ndesc, bases, 3); - - puts ("\nTransmit Error Counts:\n"); - for (c = FCC_START_LOOP; c <= FCC_END_LOOP; c++) - bases[c] = (uchar *)&elbt_chans[c].txeacc; - print_desc (txeacc_descs, txeacc_ndesc, bases, 3); - - puts ("\nRMON(-like) Counters:\n"); - for (c = FCC_START_LOOP; c <= FCC_END_LOOP; c++) - bases[c] = (uchar *)&immr->im_dprambase[elbt_chans[c].proff]; - print_desc (epram_descs, epram_ndesc, bases, 3); -} - -#endif /* CONFIG_ETHER_LOOPBACK_TEST */ - -#endif diff --git a/cpu/mpc8260/ether_scc.c b/cpu/mpc8260/ether_scc.c deleted file mode 100644 index 432111d..0000000 --- a/cpu/mpc8260/ether_scc.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * MPC8260 SCC Ethernet - * - * Copyright (c) 2000 MontaVista Software, Inc. Dan Malek (dmalek@jlc.net) - * - * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com> - * Marius Groeger <mgroeger@sysgo.de> - * - * (C) Copyright (c) 2001 - * Advent Networks, Inc. <http://www.adventnetworks.com> - * Jay Monkman <jtm@smoothsmoothie.com> - * - * Modified so that it plays nicely when more than one ETHERNET interface - * is in use a la ether_fcc.c. - * (C) Copyright 2008 - * DENX Software Engineerin GmbH - * Gary Jennejohn <garyj@denx.de> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <asm/cpm_8260.h> -#include <mpc8260.h> -#include <malloc.h> -#include <net.h> -#include <command.h> -#include <config.h> - -#ifndef CONFIG_NET_MULTI -#error "CONFIG_NET_MULTI must be defined." -#endif - -#if (CONFIG_ETHER_INDEX == 1) -# define PROFF_ENET PROFF_SCC1 -# define CPM_CR_ENET_PAGE CPM_CR_SCC1_PAGE -# define CPM_CR_ENET_SBLOCK CPM_CR_SCC1_SBLOCK -# define CMXSCR_MASK (CMXSCR_SC1 |\ - CMXSCR_RS1CS_MSK |\ - CMXSCR_TS1CS_MSK) - -#elif (CONFIG_ETHER_INDEX == 2) -# define PROFF_ENET PROFF_SCC2 -# define CPM_CR_ENET_PAGE CPM_CR_SCC2_PAGE -# define CPM_CR_ENET_SBLOCK CPM_CR_SCC2_SBLOCK -# define CMXSCR_MASK (CMXSCR_SC2 |\ - CMXSCR_RS2CS_MSK |\ - CMXSCR_TS2CS_MSK) - -#elif (CONFIG_ETHER_INDEX == 3) -# define PROFF_ENET PROFF_SCC3 -# define CPM_CR_ENET_PAGE CPM_CR_SCC3_PAGE -# define CPM_CR_ENET_SBLOCK CPM_CR_SCC3_SBLOCK -# define CMXSCR_MASK (CMXSCR_SC3 |\ - CMXSCR_RS3CS_MSK |\ - CMXSCR_TS3CS_MSK) -#elif (CONFIG_ETHER_INDEX == 4) -# define PROFF_ENET PROFF_SCC4 -# define CPM_CR_ENET_PAGE CPM_CR_SCC4_PAGE -# define CPM_CR_ENET_SBLOCK CPM_CR_SCC4_SBLOCK -# define CMXSCR_MASK (CMXSCR_SC4 |\ - CMXSCR_RS4CS_MSK |\ - CMXSCR_TS4CS_MSK) - -#endif - - -/* Ethernet Transmit and Receive Buffers */ -#define DBUF_LENGTH 1520 - -#define TX_BUF_CNT 2 - -#if !defined(CONFIG_SYS_SCC_TOUT_LOOP) - #define CONFIG_SYS_SCC_TOUT_LOOP 1000000 -#endif - -static char txbuf[TX_BUF_CNT][ DBUF_LENGTH ]; - -static uint rxIdx; /* index of the current RX buffer */ -static uint txIdx; /* index of the current TX buffer */ - -/* - * SCC Ethernet Tx and Rx buffer descriptors allocated at the - * immr->udata_bd address on Dual-Port RAM - * Provide for Double Buffering - */ - -typedef volatile struct CommonBufferDescriptor { - cbd_t rxbd[PKTBUFSRX]; /* Rx BD */ - cbd_t txbd[TX_BUF_CNT]; /* Tx BD */ -} RTXBD; - -static RTXBD *rtx; - - -static int sec_send(struct eth_device *dev, volatile void *packet, int length) -{ - int i; - int result = 0; - - if (length <= 0) { - printf("scc: bad packet size: %d\n", length); - goto out; - } - - for(i=0; rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY; i++) { - if (i >= CONFIG_SYS_SCC_TOUT_LOOP) { - puts ("scc: tx buffer not ready\n"); - goto out; - } - } - - rtx->txbd[txIdx].cbd_bufaddr = (uint)packet; - rtx->txbd[txIdx].cbd_datlen = length; - rtx->txbd[txIdx].cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_LAST | - BD_ENET_TX_WRAP); - - for(i=0; rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY; i++) { - if (i >= CONFIG_SYS_SCC_TOUT_LOOP) { - puts ("scc: tx error\n"); - goto out; - } - } - - /* return only status bits */ - result = rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_STATS; - - out: - return result; -} - - -static int sec_rx(struct eth_device *dev) -{ - int length; - - for (;;) - { - if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) { - length = -1; - break; /* nothing received - leave for() loop */ - } - - length = rtx->rxbd[rxIdx].cbd_datlen; - - if (rtx->rxbd[rxIdx].cbd_sc & 0x003f) - { - printf("err: %x\n", rtx->rxbd[rxIdx].cbd_sc); - } - else - { - /* Pass the packet up to the protocol layers. */ - NetReceive(NetRxPackets[rxIdx], length - 4); - } - - - /* Give the buffer back to the SCC. */ - rtx->rxbd[rxIdx].cbd_datlen = 0; - - /* wrap around buffer index when necessary */ - if ((rxIdx + 1) >= PKTBUFSRX) { - rtx->rxbd[PKTBUFSRX - 1].cbd_sc = (BD_ENET_RX_WRAP | - BD_ENET_RX_EMPTY); - rxIdx = 0; - } - else { - rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY; - rxIdx++; - } - } - return length; -} - -/************************************************************** - * - * SCC Ethernet Initialization Routine - * - *************************************************************/ - -static int sec_init(struct eth_device *dev, bd_t *bis) -{ - int i; - volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; - scc_enet_t *pram_ptr; - uint dpaddr; - uchar ea[6]; - - rxIdx = 0; - txIdx = 0; - - /* - * Assign static pointer to BD area. - * Avoid exhausting DPRAM, which would cause a panic. - */ - if (rtx == NULL) { - dpaddr = m8260_cpm_dpalloc(sizeof(RTXBD) + 2, 16); - rtx = (RTXBD *)&immr->im_dprambase[dpaddr]; - } - - /* 24.21 - (1-3): ioports have been set up already */ - - /* 24.21 - (4,5): connect SCC's tx and rx clocks, use NMSI for SCC */ - immr->im_cpmux.cmx_uar = 0; - immr->im_cpmux.cmx_scr = ( (immr->im_cpmux.cmx_scr & ~CMXSCR_MASK) | - CONFIG_SYS_CMXSCR_VALUE); - - - /* 24.21 (6) write RBASE and TBASE to parameter RAM */ - pram_ptr = (scc_enet_t *)&(immr->im_dprambase[PROFF_ENET]); - pram_ptr->sen_genscc.scc_rbase = (unsigned int)(&rtx->rxbd[0]); - pram_ptr->sen_genscc.scc_tbase = (unsigned int)(&rtx->txbd[0]); - - pram_ptr->sen_genscc.scc_rfcr = 0x18; /* Nrml Ops and Mot byte ordering */ - pram_ptr->sen_genscc.scc_tfcr = 0x18; /* Mot byte ordering, Nrml access */ - - pram_ptr->sen_genscc.scc_mrblr = DBUF_LENGTH; /* max. package len 1520 */ - - pram_ptr->sen_cpres = ~(0x0); /* Preset CRC */ - pram_ptr->sen_cmask = 0xdebb20e3; /* Constant Mask for CRC */ - - - /* 24.21 - (7): Write INIT RX AND TX PARAMETERS to CPCR */ - while(immr->im_cpm.cp_cpcr & CPM_CR_FLG); - immr->im_cpm.cp_cpcr = mk_cr_cmd(CPM_CR_ENET_PAGE, - CPM_CR_ENET_SBLOCK, - 0x0c, - CPM_CR_INIT_TRX) | CPM_CR_FLG; - - /* 24.21 - (8-18): Set up parameter RAM */ - pram_ptr->sen_crcec = 0x0; /* Error Counter CRC (unused) */ - pram_ptr->sen_alec = 0x0; /* Align Error Counter (unused) */ - pram_ptr->sen_disfc = 0x0; /* Discard Frame Counter (unused) */ - - pram_ptr->sen_pads = 0x8888; /* Short Frame PAD Characters */ - - pram_ptr->sen_retlim = 15; /* Retry Limit Threshold */ - - pram_ptr->sen_maxflr = 1518; /* MAX Frame Length Register */ - pram_ptr->sen_minflr = 64; /* MIN Frame Length Register */ - - pram_ptr->sen_maxd1 = DBUF_LENGTH; /* MAX DMA1 Length Register */ - pram_ptr->sen_maxd2 = DBUF_LENGTH; /* MAX DMA2 Length Register */ - - pram_ptr->sen_gaddr1 = 0x0; /* Group Address Filter 1 (unused) */ - pram_ptr->sen_gaddr2 = 0x0; /* Group Address Filter 2 (unused) */ - pram_ptr->sen_gaddr3 = 0x0; /* Group Address Filter 3 (unused) */ - pram_ptr->sen_gaddr4 = 0x0; /* Group Address Filter 4 (unused) */ - - eth_getenv_enetaddr("ethaddr", ea); - pram_ptr->sen_paddrh = (ea[5] << 8) + ea[4]; - pram_ptr->sen_paddrm = (ea[3] << 8) + ea[2]; - pram_ptr->sen_paddrl = (ea[1] << 8) + ea[0]; - - pram_ptr->sen_pper = 0x0; /* Persistence (unused) */ - - pram_ptr->sen_iaddr1 = 0x0; /* Individual Address Filter 1 (unused) */ - pram_ptr->sen_iaddr2 = 0x0; /* Individual Address Filter 2 (unused) */ - pram_ptr->sen_iaddr3 = 0x0; /* Individual Address Filter 3 (unused) */ - pram_ptr->sen_iaddr4 = 0x0; /* Individual Address Filter 4 (unused) */ - - pram_ptr->sen_taddrh = 0x0; /* Tmp Address (MSB) (unused) */ - pram_ptr->sen_taddrm = 0x0; /* Tmp Address (unused) */ - pram_ptr->sen_taddrl = 0x0; /* Tmp Address (LSB) (unused) */ - - /* 24.21 - (19): Initialize RxBD */ - for (i = 0; i < PKTBUFSRX; i++) - { - rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY; - rtx->rxbd[i].cbd_datlen = 0; /* Reset */ - rtx->rxbd[i].cbd_bufaddr = (uint)NetRxPackets[i]; - } - - rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP; - - /* 24.21 - (20): Initialize TxBD */ - for (i = 0; i < TX_BUF_CNT; i++) - { - rtx->txbd[i].cbd_sc = (BD_ENET_TX_PAD | - BD_ENET_TX_LAST | - BD_ENET_TX_TC); - rtx->txbd[i].cbd_datlen = 0; /* Reset */ - rtx->txbd[i].cbd_bufaddr = (uint)&txbuf[i][0]; - } - - rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP; - - /* 24.21 - (21): Write 0xffff to SCCE */ - immr->im_scc[CONFIG_ETHER_INDEX-1].scc_scce = ~(0x0); - - /* 24.21 - (22): Write to SCCM to enable TXE, RXF, TXB events */ - immr->im_scc[CONFIG_ETHER_INDEX-1].scc_sccm = (SCCE_ENET_TXE | - SCCE_ENET_RXF | - SCCE_ENET_TXB); - - /* 24.21 - (23): we don't use ethernet interrupts */ - - /* 24.21 - (24): Clear GSMR_H to enable normal operations */ - immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrh = 0; - - /* 24.21 - (25): Clear GSMR_L to enable normal operations */ - immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl = (SCC_GSMRL_TCI | - SCC_GSMRL_TPL_48 | - SCC_GSMRL_TPP_10 | - SCC_GSMRL_MODE_ENET); - - /* 24.21 - (26): Initialize DSR */ - immr->im_scc[CONFIG_ETHER_INDEX-1].scc_dsr = 0xd555; - - /* 24.21 - (27): Initialize PSMR2 - * - * Settings: - * CRC = 32-Bit CCITT - * NIB = Begin searching for SFD 22 bits after RENA - * FDE = Full Duplex Enable - * BRO = Reject broadcast packets - * PROMISCOUS = Catch all packets regardless of dest. MAC adress - */ - immr->im_scc[CONFIG_ETHER_INDEX-1].scc_psmr = SCC_PSMR_ENCRC | - SCC_PSMR_NIB22 | -#if defined(CONFIG_SCC_ENET_FULL_DUPLEX) - SCC_PSMR_FDE | -#endif -#if defined(CONFIG_SCC_ENET_NO_BROADCAST) - SCC_PSMR_BRO | -#endif -#if defined(CONFIG_SCC_ENET_PROMISCOUS) - SCC_PSMR_PRO | -#endif - 0; - - /* 24.21 - (28): Write to GSMR_L to enable SCC */ - immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl |= (SCC_GSMRL_ENR | - SCC_GSMRL_ENT); - - return 0; -} - - -static void sec_halt(struct eth_device *dev) -{ - volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; - immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl &= ~(SCC_GSMRL_ENR | - SCC_GSMRL_ENT); -} - -#if 0 -static void sec_restart(void) -{ - volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; - immr->im_cpm.cp_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl |= (SCC_GSMRL_ENR | - SCC_GSMRL_ENT); -} -#endif - -int mpc82xx_scc_enet_initialize(bd_t *bis) -{ - struct eth_device *dev; - - dev = (struct eth_device *) malloc(sizeof *dev); - memset(dev, 0, sizeof *dev); - - sprintf(dev->name, "SCC ETHERNET"); - dev->init = sec_init; - dev->halt = sec_halt; - dev->send = sec_send; - dev->recv = sec_rx; - - eth_register(dev); - - return 1; -} diff --git a/cpu/mpc8260/i2c.c b/cpu/mpc8260/i2c.c deleted file mode 100644 index d2bdcc2..0000000 --- a/cpu/mpc8260/i2c.c +++ /dev/null @@ -1,785 +0,0 @@ -/* - * (C) Copyright 2000 - * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it - * - * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com> - * Marius Groeger <mgroeger@sysgo.de> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> - -#if defined(CONFIG_HARD_I2C) - -#include <asm/cpm_8260.h> -#include <i2c.h> - -/* define to enable debug messages */ -#undef DEBUG_I2C - -DECLARE_GLOBAL_DATA_PTR; - -#if defined(CONFIG_I2C_MULTI_BUS) -static unsigned int i2c_bus_num __attribute__ ((section (".data"))) = 0; -#endif /* CONFIG_I2C_MULTI_BUS */ - -/* uSec to wait between polls of the i2c */ -#define DELAY_US 100 -/* uSec to wait for the CPM to start processing the buffer */ -#define START_DELAY_US 1000 - -/* - * tx/rx per-byte timeout: we delay DELAY_US uSec between polls so the - * timeout will be (tx_length + rx_length) * DELAY_US * TOUT_LOOP - */ -#define TOUT_LOOP 5 - -/*----------------------------------------------------------------------- - * Set default values - */ -#ifndef CONFIG_SYS_I2C_SPEED -#define CONFIG_SYS_I2C_SPEED 50000 -#endif - -/*----------------------------------------------------------------------- - */ - -typedef void (*i2c_ecb_t)(int, int, void *); /* error callback function */ - -/* This structure keeps track of the bd and buffer space usage. */ -typedef struct i2c_state { - int rx_idx; /* index to next free Rx BD */ - int tx_idx; /* index to next free Tx BD */ - void *rxbd; /* pointer to next free Rx BD */ - void *txbd; /* pointer to next free Tx BD */ - int tx_space; /* number of Tx bytes left */ - unsigned char *tx_buf; /* pointer to free Tx area */ - i2c_ecb_t err_cb; /* error callback function */ - void *cb_data; /* private data to be passed */ -} i2c_state_t; - -/* flags for i2c_send() and i2c_receive() */ -#define I2CF_ENABLE_SECONDARY 0x01 /* secondary_address is valid */ -#define I2CF_START_COND 0x02 /* tx: generate start condition */ -#define I2CF_STOP_COND 0x04 /* tx: generate stop condition */ - -/* return codes */ -#define I2CERR_NO_BUFFERS 1 /* no more BDs or buffer space */ -#define I2CERR_MSG_TOO_LONG 2 /* tried to send/receive to much data */ -#define I2CERR_TIMEOUT 3 /* timeout in i2c_doio() */ -#define I2CERR_QUEUE_EMPTY 4 /* i2c_doio called without send/receive */ -#define I2CERR_IO_ERROR 5 /* had an error during comms */ - -/* error callback flags */ -#define I2CECB_RX_ERR 0x10 /* this is a receive error */ -#define I2CECB_RX_OV 0x02 /* receive overrun error */ -#define I2CECB_RX_MASK 0x0f /* mask for error bits */ -#define I2CECB_TX_ERR 0x20 /* this is a transmit error */ -#define I2CECB_TX_CL 0x01 /* transmit collision error */ -#define I2CECB_TX_UN 0x02 /* transmit underflow error */ -#define I2CECB_TX_NAK 0x04 /* transmit no ack error */ -#define I2CECB_TX_MASK 0x0f /* mask for error bits */ -#define I2CECB_TIMEOUT 0x40 /* this is a timeout error */ - -#define ERROR_I2C_NONE 0 -#define ERROR_I2C_LENGTH 1 - -#define I2C_WRITE_BIT 0x00 -#define I2C_READ_BIT 0x01 - -#define I2C_RXTX_LEN 128 /* maximum tx/rx buffer length */ - - -#define NUM_RX_BDS 4 -#define NUM_TX_BDS 4 -#define MAX_TX_SPACE 256 - -typedef struct I2C_BD -{ - unsigned short status; - unsigned short length; - unsigned char *addr; -} I2C_BD; -#define BD_I2C_TX_START 0x0400 /* special status for i2c: Start condition */ - -#define BD_I2C_TX_CL 0x0001 /* collision error */ -#define BD_I2C_TX_UN 0x0002 /* underflow error */ -#define BD_I2C_TX_NAK 0x0004 /* no acknowledge error */ -#define BD_I2C_TX_ERR (BD_I2C_TX_NAK|BD_I2C_TX_UN|BD_I2C_TX_CL) - -#define BD_I2C_RX_ERR BD_SC_OV - -#ifdef DEBUG_I2C -#define PRINTD(x) printf x -#else -#define PRINTD(x) -#endif - -/* - * Returns the best value of I2BRG to meet desired clock speed of I2C with - * input parameters (clock speed, filter, and predivider value). - * It returns computer speed value and the difference between it and desired - * speed. - */ -static inline int -i2c_roundrate(int hz, int speed, int filter, int modval, - int *brgval, int *totspeed) -{ - int moddiv = 1 << (5-(modval & 3)), brgdiv, div; - - PRINTD(("\t[I2C] trying hz=%d, speed=%d, filter=%d, modval=%d\n", - hz, speed, filter, modval)); - - div = moddiv * speed; - brgdiv = (hz + div - 1) / div; - - PRINTD(("\t\tmoddiv=%d, brgdiv=%d\n", moddiv, brgdiv)); - - *brgval = ((brgdiv + 1) / 2) - 3 - (2*filter); - - if ((*brgval < 0) || (*brgval > 255)) { - PRINTD(("\t\trejected brgval=%d\n", *brgval)); - return -1; - } - - brgdiv = 2 * (*brgval + 3 + (2 * filter)); - div = moddiv * brgdiv ; - *totspeed = hz / div; - - PRINTD(("\t\taccepted brgval=%d, totspeed=%d\n", *brgval, *totspeed)); - - return 0; -} - -/* - * Sets the I2C clock predivider and divider to meet required clock speed. - */ -static int i2c_setrate(int hz, int speed) -{ - immap_t *immap = (immap_t *)CONFIG_SYS_IMMR ; - volatile i2c8260_t *i2c = (i2c8260_t *)&immap->im_i2c; - int brgval, - modval, /* 0-3 */ - bestspeed_diff = speed, - bestspeed_brgval=0, - bestspeed_modval=0, - bestspeed_filter=0, - totspeed, - filter = 0; /* Use this fixed value */ - - for (modval = 0; modval < 4; modval++) - { - if (i2c_roundrate (hz, speed, filter, modval, &brgval, &totspeed) == 0) - { - int diff = speed - totspeed ; - - if ((diff >= 0) && (diff < bestspeed_diff)) - { - bestspeed_diff = diff ; - bestspeed_modval = modval; - bestspeed_brgval = brgval; - bestspeed_filter = filter; - } - } - } - - PRINTD(("[I2C] Best is:\n")); - PRINTD(("[I2C] CPU=%dhz RATE=%d F=%d I2MOD=%08x I2BRG=%08x DIFF=%dhz\n", - hz, speed, - bestspeed_filter, bestspeed_modval, bestspeed_brgval, - bestspeed_diff)); - - i2c->i2c_i2mod |= ((bestspeed_modval & 3) << 1) | (bestspeed_filter << 3); - i2c->i2c_i2brg = bestspeed_brgval & 0xff; - - PRINTD(("[I2C] i2mod=%08x i2brg=%08x\n", i2c->i2c_i2mod, i2c->i2c_i2brg)); - - return 1 ; -} - -void i2c_init(int speed, int slaveadd) -{ - volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR ; - volatile cpm8260_t *cp = (cpm8260_t *)&immap->im_cpm; - volatile i2c8260_t *i2c = (i2c8260_t *)&immap->im_i2c; - volatile iic_t *iip; - ulong rbase, tbase; - volatile I2C_BD *rxbd, *txbd; - uint dpaddr; - -#ifdef CONFIG_SYS_I2C_INIT_BOARD - /* call board specific i2c bus reset routine before accessing the */ - /* environment, which might be in a chip on that bus. For details */ - /* about this problem see doc/I2C_Edge_Conditions. */ - i2c_init_board(); -#endif - - dpaddr = *((unsigned short*)(&immap->im_dprambase[PROFF_I2C_BASE])); - if (dpaddr == 0) { - /* need to allocate dual port ram */ - dpaddr = m8260_cpm_dpalloc(64 + - (NUM_RX_BDS * sizeof(I2C_BD)) + (NUM_TX_BDS * sizeof(I2C_BD)) + - MAX_TX_SPACE, 64); - *((unsigned short*)(&immap->im_dprambase[PROFF_I2C_BASE])) = dpaddr; - } - - /* - * initialise data in dual port ram: - * - * dpaddr -> parameter ram (64 bytes) - * rbase -> rx BD (NUM_RX_BDS * sizeof(I2C_BD) bytes) - * tbase -> tx BD (NUM_TX_BDS * sizeof(I2C_BD) bytes) - * tx buffer (MAX_TX_SPACE bytes) - */ - - iip = (iic_t *)&immap->im_dprambase[dpaddr]; - memset((void*)iip, 0, sizeof(iic_t)); - - rbase = dpaddr + 64; - tbase = rbase + NUM_RX_BDS * sizeof(I2C_BD); - - /* Disable interrupts */ - i2c->i2c_i2mod = 0x00; - i2c->i2c_i2cmr = 0x00; - i2c->i2c_i2cer = 0xff; - i2c->i2c_i2add = slaveadd; - - /* - * Set the I2C BRG Clock division factor from desired i2c rate - * and current CPU rate (we assume sccr dfbgr field is 0; - * divide BRGCLK by 1) - */ - PRINTD(("[I2C] Setting rate...\n")); - i2c_setrate (gd->brg_clk, CONFIG_SYS_I2C_SPEED) ; - - /* Set I2C controller in master mode */ - i2c->i2c_i2com = 0x01; - - /* Initialize Tx/Rx parameters */ - iip->iic_rbase = rbase; - iip->iic_tbase = tbase; - rxbd = (I2C_BD *)((unsigned char *)&immap->im_dprambase[iip->iic_rbase]); - txbd = (I2C_BD *)((unsigned char *)&immap->im_dprambase[iip->iic_tbase]); - - PRINTD(("[I2C] rbase = %04x\n", iip->iic_rbase)); - PRINTD(("[I2C] tbase = %04x\n", iip->iic_tbase)); - PRINTD(("[I2C] rxbd = %08x\n", (int)rxbd)); - PRINTD(("[I2C] txbd = %08x\n", (int)txbd)); - - /* Set big endian byte order */ - iip->iic_tfcr = 0x10; - iip->iic_rfcr = 0x10; - - /* Set maximum receive size. */ - iip->iic_mrblr = I2C_RXTX_LEN; - - cp->cp_cpcr = mk_cr_cmd(CPM_CR_I2C_PAGE, - CPM_CR_I2C_SBLOCK, - 0x00, - CPM_CR_INIT_TRX) | CPM_CR_FLG; - do { - __asm__ __volatile__ ("eieio"); - } while (cp->cp_cpcr & CPM_CR_FLG); - - /* Clear events and interrupts */ - i2c->i2c_i2cer = 0xff; - i2c->i2c_i2cmr = 0x00; -} - -static -void i2c_newio(i2c_state_t *state) -{ - volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR ; - volatile iic_t *iip; - uint dpaddr; - - PRINTD(("[I2C] i2c_newio\n")); - - dpaddr = *((unsigned short*)(&immap->im_dprambase[PROFF_I2C_BASE])); - iip = (iic_t *)&immap->im_dprambase[dpaddr]; - state->rx_idx = 0; - state->tx_idx = 0; - state->rxbd = (void*)&immap->im_dprambase[iip->iic_rbase]; - state->txbd = (void*)&immap->im_dprambase[iip->iic_tbase]; - state->tx_space = MAX_TX_SPACE; - state->tx_buf = (uchar*)state->txbd + NUM_TX_BDS * sizeof(I2C_BD); - state->err_cb = NULL; - state->cb_data = NULL; - - PRINTD(("[I2C] rxbd = %08x\n", (int)state->rxbd)); - PRINTD(("[I2C] txbd = %08x\n", (int)state->txbd)); - PRINTD(("[I2C] tx_buf = %08x\n", (int)state->tx_buf)); - - /* clear the buffer memory */ - memset((char *)state->tx_buf, 0, MAX_TX_SPACE); -} - -static -int i2c_send(i2c_state_t *state, - unsigned char address, - unsigned char secondary_address, - unsigned int flags, - unsigned short size, - unsigned char *dataout) -{ - volatile I2C_BD *txbd; - int i,j; - - PRINTD(("[I2C] i2c_send add=%02d sec=%02d flag=%02d size=%d\n", - address, secondary_address, flags, size)); - - /* trying to send message larger than BD */ - if (size > I2C_RXTX_LEN) - return I2CERR_MSG_TOO_LONG; - - /* no more free bds */ - if (state->tx_idx >= NUM_TX_BDS || state->tx_space < (2 + size)) - return I2CERR_NO_BUFFERS; - - txbd = (I2C_BD *)state->txbd; - txbd->addr = state->tx_buf; - - PRINTD(("[I2C] txbd = %08x\n", (int)txbd)); - - if (flags & I2CF_START_COND) - { - PRINTD(("[I2C] Formatting addresses...\n")); - if (flags & I2CF_ENABLE_SECONDARY) - { - txbd->length = size + 2; /* Length of message plus dest addresses */ - txbd->addr[0] = address << 1; - txbd->addr[1] = secondary_address; - i = 2; - } - else - { - txbd->length = size + 1; /* Length of message plus dest address */ - txbd->addr[0] = address << 1; /* Write destination address to BD */ - i = 1; - } - } - else - { - txbd->length = size; /* Length of message */ - i = 0; - } - - /* set up txbd */ - txbd->status = BD_SC_READY; - if (flags & I2CF_START_COND) - txbd->status |= BD_I2C_TX_START; - if (flags & I2CF_STOP_COND) - txbd->status |= BD_SC_LAST | BD_SC_WRAP; - - /* Copy data to send into buffer */ - PRINTD(("[I2C] copy data...\n")); - for(j = 0; j < size; i++, j++) - txbd->addr[i] = dataout[j]; - - PRINTD(("[I2C] txbd: length=0x%04x status=0x%04x addr[0]=0x%02x addr[1]=0x%02x\n", - txbd->length, - txbd->status, - txbd->addr[0], - txbd->addr[1])); - - /* advance state */ - state->tx_buf += txbd->length; - state->tx_space -= txbd->length; - state->tx_idx++; - state->txbd = (void*)(txbd + 1); - - return 0; -} - -static -int i2c_receive(i2c_state_t *state, - unsigned char address, - unsigned char secondary_address, - unsigned int flags, - unsigned short size_to_expect, - unsigned char *datain) -{ - volatile I2C_BD *rxbd, *txbd; - - PRINTD(("[I2C] i2c_receive %02d %02d %02d\n", address, secondary_address, flags)); - - /* Expected to receive too much */ - if (size_to_expect > I2C_RXTX_LEN) - return I2CERR_MSG_TOO_LONG; - - /* no more free bds */ - if (state->tx_idx >= NUM_TX_BDS || state->rx_idx >= NUM_RX_BDS - || state->tx_space < 2) - return I2CERR_NO_BUFFERS; - - rxbd = (I2C_BD *)state->rxbd; - txbd = (I2C_BD *)state->txbd; - - PRINTD(("[I2C] rxbd = %08x\n", (int)rxbd)); - PRINTD(("[I2C] txbd = %08x\n", (int)txbd)); - - txbd->addr = state->tx_buf; - - /* set up TXBD for destination address */ - if (flags & I2CF_ENABLE_SECONDARY) - { - txbd->length = 2; - txbd->addr[0] = address << 1; /* Write data */ - txbd->addr[1] = secondary_address; /* Internal address */ - txbd->status = BD_SC_READY; - } - else - { - txbd->length = 1 + size_to_expect; - txbd->addr[0] = (address << 1) | 0x01; - txbd->status = BD_SC_READY; - memset(&txbd->addr[1], 0, txbd->length); - } - - /* set up rxbd for reception */ - rxbd->status = BD_SC_EMPTY; - rxbd->length = size_to_expect; - rxbd->addr = datain; - - txbd->status |= BD_I2C_TX_START; - if (flags & I2CF_STOP_COND) - { - txbd->status |= BD_SC_LAST | BD_SC_WRAP; - rxbd->status |= BD_SC_WRAP; - } - - PRINTD(("[I2C] txbd: length=0x%04x status=0x%04x addr[0]=0x%02x addr[1]=0x%02x\n", - txbd->length, - txbd->status, - txbd->addr[0], - txbd->addr[1])); - PRINTD(("[I2C] rxbd: length=0x%04x status=0x%04x addr[0]=0x%02x addr[1]=0x%02x\n", - rxbd->length, - rxbd->status, - rxbd->addr[0], - rxbd->addr[1])); - - /* advance state */ - state->tx_buf += txbd->length; - state->tx_space -= txbd->length; - state->tx_idx++; - state->txbd = (void*)(txbd + 1); - state->rx_idx++; - state->rxbd = (void*)(rxbd + 1); - - return 0; -} - - -static -int i2c_doio(i2c_state_t *state) -{ - volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR ; - volatile iic_t *iip; - volatile i2c8260_t *i2c = (i2c8260_t *)&immap->im_i2c; - volatile I2C_BD *txbd, *rxbd; - int n, i, b, rxcnt = 0, rxtimeo = 0, txcnt = 0, txtimeo = 0, rc = 0; - uint dpaddr; - - PRINTD(("[I2C] i2c_doio\n")); - - if (state->tx_idx <= 0 && state->rx_idx <= 0) { - PRINTD(("[I2C] No I/O is queued\n")); - return I2CERR_QUEUE_EMPTY; - } - - dpaddr = *((unsigned short*)(&immap->im_dprambase[PROFF_I2C_BASE])); - iip = (iic_t *)&immap->im_dprambase[dpaddr]; - iip->iic_rbptr = iip->iic_rbase; - iip->iic_tbptr = iip->iic_tbase; - - /* Enable I2C */ - PRINTD(("[I2C] Enabling I2C...\n")); - i2c->i2c_i2mod |= 0x01; - - /* Begin transmission */ - i2c->i2c_i2com |= 0x80; - - /* Loop until transmit & receive completed */ - - if ((n = state->tx_idx) > 0) { - - txbd = ((I2C_BD*)state->txbd) - n; - for (i = 0; i < n; i++) { - txtimeo += TOUT_LOOP * txbd->length; - txbd++; - } - - txbd--; /* wait until last in list is done */ - - PRINTD(("[I2C] Transmitting...(txbd=0x%08lx)\n", (ulong)txbd)); - - udelay(START_DELAY_US); /* give it time to start */ - while((txbd->status & BD_SC_READY) && (++txcnt < txtimeo)) { - udelay(DELAY_US); - if (ctrlc()) - return (-1); - __asm__ __volatile__ ("eieio"); - } - } - - if (txcnt < txtimeo && (n = state->rx_idx) > 0) { - - rxbd = ((I2C_BD*)state->rxbd) - n; - for (i = 0; i < n; i++) { - rxtimeo += TOUT_LOOP * rxbd->length; - rxbd++; - } - - rxbd--; /* wait until last in list is done */ - - PRINTD(("[I2C] Receiving...(rxbd=0x%08lx)\n", (ulong)rxbd)); - - udelay(START_DELAY_US); /* give it time to start */ - while((rxbd->status & BD_SC_EMPTY) && (++rxcnt < rxtimeo)) { - udelay(DELAY_US); - if (ctrlc()) - return (-1); - __asm__ __volatile__ ("eieio"); - } - } - - /* Turn off I2C */ - i2c->i2c_i2mod &= ~0x01; - - if ((n = state->tx_idx) > 0) { - for (i = 0; i < n; i++) { - txbd = ((I2C_BD*)state->txbd) - (n - i); - if ((b = txbd->status & BD_I2C_TX_ERR) != 0) { - if (state->err_cb != NULL) - (*state->err_cb)(I2CECB_TX_ERR|b, i, - state->cb_data); - if (rc == 0) - rc = I2CERR_IO_ERROR; - } - } - } - - if ((n = state->rx_idx) > 0) { - for (i = 0; i < n; i++) { - rxbd = ((I2C_BD*)state->rxbd) - (n - i); - if ((b = rxbd->status & BD_I2C_RX_ERR) != 0) { - if (state->err_cb != NULL) - (*state->err_cb)(I2CECB_RX_ERR|b, i, - state->cb_data); - if (rc == 0) - rc = I2CERR_IO_ERROR; - } - } - } - - if ((txtimeo > 0 && txcnt >= txtimeo) || \ - (rxtimeo > 0 && rxcnt >= rxtimeo)) { - if (state->err_cb != NULL) - (*state->err_cb)(I2CECB_TIMEOUT, -1, state->cb_data); - if (rc == 0) - rc = I2CERR_TIMEOUT; - } - - return (rc); -} - -static void -i2c_probe_callback(int flags, int xnum, void *data) -{ - /* - * the only acceptable errors are a transmit NAK or a receive - * overrun - tx NAK means the device does not exist, rx OV - * means the device must have responded to the slave address - * even though the transfer failed - */ - if (flags == (I2CECB_TX_ERR|I2CECB_TX_NAK)) - *(int *)data |= 1; - if (flags == (I2CECB_RX_ERR|I2CECB_RX_OV)) - *(int *)data |= 2; -} - -int -i2c_probe(uchar chip) -{ - i2c_state_t state; - int rc, err_flag; - uchar buf[1]; - - i2c_newio(&state); - - state.err_cb = i2c_probe_callback; - state.cb_data = (void *) &err_flag; - err_flag = 0; - - rc = i2c_receive(&state, chip, 0, I2CF_START_COND|I2CF_STOP_COND, 1, buf); - - if (rc != 0) - return (rc); /* probe failed */ - - rc = i2c_doio(&state); - - if (rc == 0) - return (0); /* device exists - read succeeded */ - - if (rc == I2CERR_TIMEOUT) - return (-1); /* device does not exist - timeout */ - - if (rc != I2CERR_IO_ERROR || err_flag == 0) - return (rc); /* probe failed */ - - if (err_flag & 1) - return (-1); /* device does not exist - had transmit NAK */ - - return (0); /* device exists - had receive overrun */ -} - - -int -i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) -{ - i2c_state_t state; - uchar xaddr[4]; - int rc; - - xaddr[0] = (addr >> 24) & 0xFF; - xaddr[1] = (addr >> 16) & 0xFF; - xaddr[2] = (addr >> 8) & 0xFF; - xaddr[3] = addr & 0xFF; - -#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW - /* - * EEPROM chips that implement "address overflow" are ones - * like Catalyst 24WC04/08/16 which has 9/10/11 bits of address - * and the extra bits end up in the "chip address" bit slots. - * This makes a 24WC08 (1Kbyte) chip look like four 256 byte - * chips. - * - * Note that we consider the length of the address field to still - * be one byte because the extra address bits are hidden in the - * chip address. - */ - chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); -#endif - - i2c_newio(&state); - - rc = i2c_send(&state, chip, 0, I2CF_START_COND, alen, &xaddr[4-alen]); - if (rc != 0) { - printf("i2c_read: i2c_send failed (%d)\n", rc); - return 1; - } - - rc = i2c_receive(&state, chip, 0, I2CF_STOP_COND, len, buffer); - if (rc != 0) { - printf("i2c_read: i2c_receive failed (%d)\n", rc); - return 1; - } - - rc = i2c_doio(&state); - if (rc != 0) { - printf("i2c_read: i2c_doio failed (%d)\n", rc); - return 1; - } - return 0; -} - -int -i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) -{ - i2c_state_t state; - uchar xaddr[4]; - int rc; - - xaddr[0] = (addr >> 24) & 0xFF; - xaddr[1] = (addr >> 16) & 0xFF; - xaddr[2] = (addr >> 8) & 0xFF; - xaddr[3] = addr & 0xFF; - -#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW - /* - * EEPROM chips that implement "address overflow" are ones - * like Catalyst 24WC04/08/16 which has 9/10/11 bits of address - * and the extra bits end up in the "chip address" bit slots. - * This makes a 24WC08 (1Kbyte) chip look like four 256 byte - * chips. - * - * Note that we consider the length of the address field to still - * be one byte because the extra address bits are hidden in the - * chip address. - */ - chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); -#endif - - i2c_newio(&state); - - rc = i2c_send(&state, chip, 0, I2CF_START_COND, alen, &xaddr[4-alen]); - if (rc != 0) { - printf("i2c_write: first i2c_send failed (%d)\n", rc); - return 1; - } - - rc = i2c_send(&state, 0, 0, I2CF_STOP_COND, len, buffer); - if (rc != 0) { - printf("i2c_write: second i2c_send failed (%d)\n", rc); - return 1; - } - - rc = i2c_doio(&state); - if (rc != 0) { - printf("i2c_write: i2c_doio failed (%d)\n", rc); - return 1; - } - return 0; -} - -#if defined(CONFIG_I2C_MULTI_BUS) -/* - * Functions for multiple I2C bus handling - */ -unsigned int i2c_get_bus_num(void) -{ - return i2c_bus_num; -} - -int i2c_set_bus_num(unsigned int bus) -{ -#if defined(CONFIG_I2C_MUX) - if (bus < CONFIG_SYS_MAX_I2C_BUS) { - i2c_bus_num = bus; - } else { - int ret; - - ret = i2x_mux_select_mux(bus); - if (ret == 0) - i2c_bus_num = bus; - else - return ret; - } -#else - if (bus >= CONFIG_SYS_MAX_I2C_BUS) - return -1; - i2c_bus_num = bus; -#endif - return 0; -} - -#endif /* CONFIG_I2C_MULTI_BUS */ -#endif /* CONFIG_HARD_I2C */ diff --git a/cpu/mpc8260/interrupts.c b/cpu/mpc8260/interrupts.c deleted file mode 100644 index a7700c4..0000000 --- a/cpu/mpc8260/interrupts.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * (C) Copyright 2000-2002 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * Hacked for MPC8260 by Murray.Jensen@cmst.csiro.au, 22-Oct-00 - */ - -#include <common.h> -#include <command.h> -#include <mpc8260.h> -#include <mpc8260_irq.h> -#include <asm/processor.h> - -DECLARE_GLOBAL_DATA_PTR; - -/****************************************************************************/ - -struct irq_action { - interrupt_handler_t *handler; - void *arg; - ulong count; -}; - -static struct irq_action irq_handlers[NR_IRQS]; - -static ulong ppc_cached_irq_mask[NR_MASK_WORDS]; - -/****************************************************************************/ -/* this section was ripped out of arch/ppc/kernel/ppc8260_pic.c in the */ -/* Linux/PPC 2.4.x source. There was no copyright notice in that file. */ - -/* The 8260 internal interrupt controller. It is usually - * the only interrupt controller. - * There are two 32-bit registers (high/low) for up to 64 - * possible interrupts. - * - * Now, the fun starts.....Interrupt Numbers DO NOT MAP - * in a simple arithmetic fashion to mask or pending registers. - * That is, interrupt 4 does not map to bit position 4. - * We create two tables, indexed by vector number, to indicate - * which register to use and which bit in the register to use. - */ -static u_char irq_to_siureg[] = { - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static u_char irq_to_siubit[] = { - 31, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, - 29, 30, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 31, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 15, 14, 13, 12, 11, 10, 9, 8, - 7, 6, 5, 4, 3, 2, 1, 0 -}; - -static void m8260_mask_irq (unsigned int irq_nr) -{ - volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; - int bit, word; - volatile uint *simr; - - bit = irq_to_siubit[irq_nr]; - word = irq_to_siureg[irq_nr]; - - simr = &(immr->im_intctl.ic_simrh); - ppc_cached_irq_mask[word] &= ~(1 << (31 - bit)); - simr[word] = ppc_cached_irq_mask[word]; -} - -static void m8260_unmask_irq (unsigned int irq_nr) -{ - volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; - int bit, word; - volatile uint *simr; - - bit = irq_to_siubit[irq_nr]; - word = irq_to_siureg[irq_nr]; - - simr = &(immr->im_intctl.ic_simrh); - ppc_cached_irq_mask[word] |= (1 << (31 - bit)); - simr[word] = ppc_cached_irq_mask[word]; -} - -static void m8260_mask_and_ack (unsigned int irq_nr) -{ - volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; - int bit, word; - volatile uint *simr, *sipnr; - - bit = irq_to_siubit[irq_nr]; - word = irq_to_siureg[irq_nr]; - - simr = &(immr->im_intctl.ic_simrh); - sipnr = &(immr->im_intctl.ic_sipnrh); - ppc_cached_irq_mask[word] &= ~(1 << (31 - bit)); - simr[word] = ppc_cached_irq_mask[word]; - sipnr[word] = 1 << (31 - bit); -} - -static int m8260_get_irq (struct pt_regs *regs) -{ - volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; - int irq; - unsigned long bits; - - /* For MPC8260, read the SIVEC register and shift the bits down - * to get the irq number. */ - bits = immr->im_intctl.ic_sivec; - irq = bits >> 26; - return irq; -} - -/* end of code ripped out of arch/ppc/kernel/ppc8260_pic.c */ -/****************************************************************************/ - -int interrupt_init_cpu (unsigned *decrementer_count) -{ - volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; - - *decrementer_count = (gd->bus_clk / 4) / CONFIG_SYS_HZ; - - /* Initialize the default interrupt mapping priorities */ - immr->im_intctl.ic_sicr = 0; - immr->im_intctl.ic_siprr = 0x05309770; - immr->im_intctl.ic_scprrh = 0x05309770; - immr->im_intctl.ic_scprrl = 0x05309770; - - /* disable all interrupts and clear all pending bits */ - immr->im_intctl.ic_simrh = ppc_cached_irq_mask[0] = 0; - immr->im_intctl.ic_simrl = ppc_cached_irq_mask[1] = 0; - immr->im_intctl.ic_sipnrh = 0xffffffff; - immr->im_intctl.ic_sipnrl = 0xffffffff; - -#ifdef CONFIG_HYMOD - /* - * ensure all external interrupt sources default to trigger on - * high-to-low transition (i.e. edge triggered active low) - */ - immr->im_intctl.ic_siexr = -1; -#endif - - return (0); -} - -/****************************************************************************/ - -/* - * Handle external interrupts - */ -void external_interrupt (struct pt_regs *regs) -{ - int irq, unmask = 1; - - irq = m8260_get_irq (regs); - - m8260_mask_and_ack (irq); - - enable_interrupts (); - - if (irq_handlers[irq].handler != NULL) - (*irq_handlers[irq].handler) (irq_handlers[irq].arg); - else { - printf ("\nBogus External Interrupt IRQ %d\n", irq); - /* - * turn off the bogus interrupt, otherwise it - * might repeat forever - */ - unmask = 0; - } - - if (unmask) - m8260_unmask_irq (irq); -} - -/****************************************************************************/ - -/* - * Install and free an interrupt handler. - */ - -void -irq_install_handler (int irq, interrupt_handler_t * handler, void *arg) -{ - if (irq < 0 || irq >= NR_IRQS) { - printf ("irq_install_handler: bad irq number %d\n", irq); - return; - } - - if (irq_handlers[irq].handler != NULL) - printf ("irq_install_handler: 0x%08lx replacing 0x%08lx\n", - (ulong) handler, (ulong) irq_handlers[irq].handler); - - irq_handlers[irq].handler = handler; - irq_handlers[irq].arg = arg; - - m8260_unmask_irq (irq); -} - -void irq_free_handler (int irq) -{ - if (irq < 0 || irq >= NR_IRQS) { - printf ("irq_free_handler: bad irq number %d\n", irq); - return; - } - - m8260_mask_irq (irq); - - irq_handlers[irq].handler = NULL; - irq_handlers[irq].arg = NULL; -} - -/****************************************************************************/ - -void timer_interrupt_cpu (struct pt_regs *regs) -{ - /* nothing to do here */ - return; -} - -/****************************************************************************/ - -#if defined(CONFIG_CMD_IRQ) - -/* ripped this out of ppc4xx/interrupts.c */ - -/******************************************************************************* -* -* irqinfo - print information about PCI devices -* -*/ -void -do_irqinfo (cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) -{ - int irq, re_enable; - - re_enable = disable_interrupts (); - - puts ("\nInterrupt-Information:\n" - "Nr Routine Arg Count\n"); - - for (irq = 0; irq < 32; irq++) - if (irq_handlers[irq].handler != NULL) - printf ("%02d %08lx %08lx %ld\n", irq, - (ulong) irq_handlers[irq].handler, - (ulong) irq_handlers[irq].arg, - irq_handlers[irq].count); - - if (re_enable) - enable_interrupts (); -} - -#endif diff --git a/cpu/mpc8260/kgdb.S b/cpu/mpc8260/kgdb.S deleted file mode 100644 index c5936c7..0000000 --- a/cpu/mpc8260/kgdb.S +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2000 Murray Jensen <Murray.Jensen@cmst.csiro.au> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <config.h> -#include <command.h> -#include <mpc8260.h> -#include <version.h> - -#define CONFIG_8260 1 /* needed for Linux kernel header files */ -#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ - -#include <ppc_asm.tmpl> -#include <ppc_defs.h> - -#include <asm/cache.h> -#include <asm/mmu.h> - -#if defined(CONFIG_CMD_KGDB) - - /* - * cache flushing routines for kgdb - */ - - .globl kgdb_flush_cache_all -kgdb_flush_cache_all: - mfspr r3, HID0 - ori r3, r3, HID0_ICFI|HID0_DCI /* Invalidate All */ - SYNC - mtspr HID0, r3 - blr - - .globl kgdb_flush_cache_range -kgdb_flush_cache_range: - li r5,CONFIG_SYS_CACHELINE_SIZE-1 - andc r3,r3,r5 - subf r4,r3,r4 - add r4,r4,r5 - srwi. r4,r4,CONFIG_SYS_CACHELINE_SHIFT - beqlr - mtctr r4 - mr r6,r3 -1: dcbst 0,r3 - addi r3,r3,CONFIG_SYS_CACHELINE_SIZE - bdnz 1b - sync /* wait for dcbst's to get to ram */ - mtctr r4 -2: icbi 0,r6 - addi r6,r6,CONFIG_SYS_CACHELINE_SIZE - bdnz 2b - SYNC - blr - -#endif diff --git a/cpu/mpc8260/pci.c b/cpu/mpc8260/pci.c deleted file mode 100644 index 6a14ba4..0000000 --- a/cpu/mpc8260/pci.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * Copyright (c) 2005 MontaVista Software, Inc. - * Vitaly Bordug <vbordug@ru.mvista.com> - * Added support for PCI bridge on MPC8272ADS - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> - -#ifdef CONFIG_PCI - -#include <pci.h> -#include <mpc8260.h> -#include <asm/m8260_pci.h> -#include <asm/io.h> -#ifdef CONFIG_OF_LIBFDT -#include <libfdt.h> -#include <fdt_support.h> -#endif - -#if defined CONFIG_MPC8266ADS || defined CONFIG_MPC8272 || defined CONFIG_PM826 -DECLARE_GLOBAL_DATA_PTR; -#endif - -/* - * Local->PCI map (from CPU) controlled by - * MPC826x master window - * - * 0x80000000 - 0xBFFFFFFF CPU2PCI space PCIBR0 - * 0xF4000000 - 0xF7FFFFFF CPU2PCI space PCIBR1 - * - * 0x80000000 - 0x9FFFFFFF 0x80000000 - 0x9FFFFFFF (Outbound ATU #1) - * PCI Mem with prefetch - * - * 0xA0000000 - 0xBFFFFFFF 0xA0000000 - 0xBFFFFFFF (Outbound ATU #2) - * PCI Mem w/o prefetch - * - * 0xF4000000 - 0xF7FFFFFF 0x00000000 - 0x03FFFFFF (Outbound ATU #3) - * 32-bit PCI IO - * - * PCI->Local map (from PCI) - * MPC826x slave window controlled by - * - * 0x00000000 - 0x1FFFFFFF 0x00000000 - 0x1FFFFFFF (Inbound ATU #1) - * MPC826x local memory - */ - -/* - * Slave window that allows PCI masters to access MPC826x local memory. - * This window is set up using the first set of Inbound ATU registers - */ - -#ifndef CONFIG_SYS_PCI_SLV_MEM_LOCAL -#define PCI_SLV_MEM_LOCAL CONFIG_SYS_SDRAM_BASE /* Local base */ -#else -#define PCI_SLV_MEM_LOCAL CONFIG_SYS_PCI_SLV_MEM_LOCAL -#endif - -#ifndef CONFIG_SYS_PCI_SLV_MEM_BUS -#define PCI_SLV_MEM_BUS 0x00000000 /* PCI base */ -#else -#define PCI_SLV_MEM_BUS CONFIG_SYS_PCI_SLV_MEM_BUS -#endif - -#ifndef CONFIG_SYS_PICMR0_MASK_ATTRIB -#define PICMR0_MASK_ATTRIB (PICMR_MASK_512MB | PICMR_ENABLE | \ - PICMR_PREFETCH_EN) -#else -#define PICMR0_MASK_ATTRIB CONFIG_SYS_PICMR0_MASK_ATTRIB -#endif - -/* - * These are the windows that allow the CPU to access PCI address space. - * All three PCI master windows, which allow the CPU to access PCI - * prefetch, non prefetch, and IO space (see below), must all fit within - * these windows. - */ - -/* PCIBR0 */ -#ifndef CONFIG_SYS_PCI_MSTR0_LOCAL -#define PCI_MSTR0_LOCAL 0x80000000 /* Local base */ -#else -#define PCI_MSTR0_LOCAL CONFIG_SYS_PCI_MSTR0_LOCAL -#endif - -#ifndef CONFIG_SYS_PCIMSK0_MASK -#define PCIMSK0_MASK PCIMSK_1GB /* Size of window */ -#else -#define PCIMSK0_MASK CONFIG_SYS_PCIMSK0_MASK -#endif - -/* PCIBR1 */ -#ifndef CONFIG_SYS_PCI_MSTR1_LOCAL -#define PCI_MSTR1_LOCAL 0xF4000000 /* Local base */ -#else -#define PCI_MSTR1_LOCAL CONFIG_SYS_PCI_MSTR1_LOCAL -#endif - -#ifndef CONFIG_SYS_PCIMSK1_MASK -#define PCIMSK1_MASK PCIMSK_64MB /* Size of window */ -#else -#define PCIMSK1_MASK CONFIG_SYS_PCIMSK1_MASK -#endif - -/* - * Master window that allows the CPU to access PCI Memory (prefetch). - * This window will be setup with the first set of Outbound ATU registers - * in the bridge. - */ - -#ifndef CONFIG_SYS_PCI_MSTR_MEM_LOCAL -#define PCI_MSTR_MEM_LOCAL 0x80000000 /* Local base */ -#else -#define PCI_MSTR_MEM_LOCAL CONFIG_SYS_PCI_MSTR_MEM_LOCAL -#endif - -#ifndef CONFIG_SYS_PCI_MSTR_MEM_BUS -#define PCI_MSTR_MEM_BUS 0x80000000 /* PCI base */ -#else -#define PCI_MSTR_MEM_BUS CONFIG_SYS_PCI_MSTR_MEM_BUS -#endif - -#ifndef CONFIG_SYS_CPU_PCI_MEM_START -#define CPU_PCI_MEM_START PCI_MSTR_MEM_LOCAL -#else -#define CPU_PCI_MEM_START CONFIG_SYS_CPU_PCI_MEM_START -#endif - -#ifndef CONFIG_SYS_PCI_MSTR_MEM_SIZE -#define PCI_MSTR_MEM_SIZE 0x10000000 /* 256MB */ -#else -#define PCI_MSTR_MEM_SIZE CONFIG_SYS_PCI_MSTR_MEM_SIZE -#endif - -#ifndef CONFIG_SYS_POCMR0_MASK_ATTRIB -#define POCMR0_MASK_ATTRIB (POCMR_MASK_256MB | POCMR_ENABLE | POCMR_PREFETCH_EN) -#else -#define POCMR0_MASK_ATTRIB CONFIG_SYS_POCMR0_MASK_ATTRIB -#endif - -/* - * Master window that allows the CPU to access PCI Memory (non-prefetch). - * This window will be setup with the second set of Outbound ATU registers - * in the bridge. - */ - -#ifndef CONFIG_SYS_PCI_MSTR_MEMIO_LOCAL -#define PCI_MSTR_MEMIO_LOCAL 0x90000000 /* Local base */ -#else -#define PCI_MSTR_MEMIO_LOCAL CONFIG_SYS_PCI_MSTR_MEMIO_LOCAL -#endif - -#ifndef CONFIG_SYS_PCI_MSTR_MEMIO_BUS -#define PCI_MSTR_MEMIO_BUS 0x90000000 /* PCI base */ -#else -#define PCI_MSTR_MEMIO_BUS CONFIG_SYS_PCI_MSTR_MEMIO_BUS -#endif - -#ifndef CONFIG_SYS_CPU_PCI_MEMIO_START -#define CPU_PCI_MEMIO_START PCI_MSTR_MEMIO_LOCAL -#else -#define CPU_PCI_MEMIO_START CONFIG_SYS_CPU_PCI_MEMIO_START -#endif - -#ifndef CONFIG_SYS_PCI_MSTR_MEMIO_SIZE -#define PCI_MSTR_MEMIO_SIZE 0x10000000 /* 256 MB */ -#else -#define PCI_MSTR_MEMIO_SIZE CONFIG_SYS_PCI_MSTR_MEMIO_SIZE -#endif - -#ifndef CONFIG_SYS_POCMR1_MASK_ATTRIB -#define POCMR1_MASK_ATTRIB (POCMR_MASK_512MB | POCMR_ENABLE) -#else -#define POCMR1_MASK_ATTRIB CONFIG_SYS_POCMR1_MASK_ATTRIB -#endif - -/* - * Master window that allows the CPU to access PCI IO space. - * This window will be setup with the third set of Outbound ATU registers - * in the bridge. - */ - -#ifndef CONFIG_SYS_PCI_MSTR_IO_LOCAL -#define PCI_MSTR_IO_LOCAL 0xA0000000 /* Local base */ -#else -#define PCI_MSTR_IO_LOCAL CONFIG_SYS_PCI_MSTR_IO_LOCAL -#endif - -#ifndef CONFIG_SYS_PCI_MSTR_IO_BUS -#define PCI_MSTR_IO_BUS 0xA0000000 /* PCI base */ -#else -#define PCI_MSTR_IO_BUS CONFIG_SYS_PCI_MSTR_IO_BUS -#endif - -#ifndef CONFIG_SYS_CPU_PCI_IO_START -#define CPU_PCI_IO_START PCI_MSTR_IO_LOCAL -#else -#define CPU_PCI_IO_START CONFIG_SYS_CPU_PCI_IO_START -#endif - -#ifndef CONFIG_SYS_PCI_MSTR_IO_SIZE -#define PCI_MSTR_IO_SIZE 0x10000000 /* 256MB */ -#else -#define PCI_MSTR_IO_SIZE CONFIG_SYS_PCI_MSTR_IO_SIZE -#endif - -#ifndef CONFIG_SYS_POCMR2_MASK_ATTRIB -#define POCMR2_MASK_ATTRIB (POCMR_MASK_256MB | POCMR_ENABLE | POCMR_PCI_IO) -#else -#define POCMR2_MASK_ATTRIB CONFIG_SYS_POCMR2_MASK_ATTRIB -#endif - -/* PCI bus configuration registers. - */ - -#define PCI_CLASS_BRIDGE_CTLR 0x06 - - -static inline void pci_outl (u32 addr, u32 data) -{ - *(volatile u32 *) addr = cpu_to_le32 (data); -} - -void pci_mpc8250_init (struct pci_controller *hose) -{ - u16 tempShort; - - volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; - pci_dev_t host_devno = PCI_BDF (0, 0, 0); - - pci_setup_indirect (hose, CONFIG_SYS_IMMR + PCI_CFG_ADDR_REG, - CONFIG_SYS_IMMR + PCI_CFG_DATA_REG); - - /* - * Setting required to enable local bus for PCI (SIUMCR [LBPC]). - */ -#ifdef CONFIG_MPC8266ADS - immap->im_siu_conf.sc_siumcr = - (immap->im_siu_conf.sc_siumcr & ~SIUMCR_LBPC11) - | SIUMCR_LBPC01; -#elif defined(CONFIG_ADSTYPE) && CONFIG_ADSTYPE == CONFIG_SYS_PQ2FADS -/* nothing to do for this board here */ -#elif defined CONFIG_MPC8272 - immap->im_siu_conf.sc_siumcr = (immap->im_siu_conf.sc_siumcr & - ~SIUMCR_BBD & - ~SIUMCR_ESE & - ~SIUMCR_PBSE & - ~SIUMCR_CDIS & - ~SIUMCR_DPPC11 & - ~SIUMCR_L2CPC11 & - ~SIUMCR_LBPC11 & - ~SIUMCR_APPC11 & - ~SIUMCR_CS10PC11 & - ~SIUMCR_BCTLC11 & - ~SIUMCR_MMR11) - | SIUMCR_DPPC11 - | SIUMCR_L2CPC01 - | SIUMCR_LBPC00 - | SIUMCR_APPC10 - | SIUMCR_CS10PC00 - | SIUMCR_BCTLC00 - | SIUMCR_MMR11; -#elif defined(CONFIG_TQM8272) -/* nothing to do for this Board here */ -#else - /* - * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]), - * and local bus for PCI (SIUMCR [LBPC]). - */ - immap->im_siu_conf.sc_siumcr = (immap->im_siu_conf.sc_siumcr & - ~SIUMCR_LBPC11 & - ~SIUMCR_CS10PC11 & - ~SIUMCR_LBPC11) | - SIUMCR_LBPC01 | - SIUMCR_CS10PC01 | - SIUMCR_APPC10; -#endif - - /* Make PCI lowest priority */ - /* Each 4 bits is a device bus request and the MS 4bits - is highest priority */ - /* Bus 4bit value - --- ---------- - CPM high 0b0000 - CPM middle 0b0001 - CPM low 0b0010 - PCI reguest 0b0011 - Reserved 0b0100 - Reserved 0b0101 - Internal Core 0b0110 - External Master 1 0b0111 - External Master 2 0b1000 - External Master 3 0b1001 - The rest are reserved */ - immap->im_siu_conf.sc_ppc_alrh = 0x61207893; - - /* Park bus on core while modifying PCI Bus accesses */ - immap->im_siu_conf.sc_ppc_acr = 0x6; - - /* - * Set up master windows that allow the CPU to access PCI space. These - * windows are set up using the two SIU PCIBR registers. - */ - immap->im_memctl.memc_pcimsk0 = PCIMSK0_MASK; - immap->im_memctl.memc_pcibr0 = PCI_MSTR0_LOCAL | PCIBR_ENABLE; - -#if defined CONFIG_MPC8266ADS || defined CONFIG_MPC8272 - immap->im_memctl.memc_pcimsk1 = PCIMSK1_MASK; - immap->im_memctl.memc_pcibr1 = PCI_MSTR1_LOCAL | PCIBR_ENABLE; -#endif - - /* Release PCI RST (by default the PCI RST signal is held low) */ - immap->im_pci.pci_gcr = cpu_to_le32 (PCIGCR_PCI_BUS_EN); - - /* give it some time */ - { -#if defined CONFIG_MPC8266ADS || defined CONFIG_MPC8272 - /* Give the PCI cards more time to initialize before query - This might be good for other boards also - */ - int i; - - for (i = 0; i < 1000; ++i) -#endif - udelay (1000); - } - - /* - * Set up master window that allows the CPU to access PCI Memory (prefetch) - * space. This window is set up using the first set of Outbound ATU registers. - */ - immap->im_pci.pci_potar0 = cpu_to_le32 (PCI_MSTR_MEM_BUS >> 12); /* PCI base */ - immap->im_pci.pci_pobar0 = cpu_to_le32 (PCI_MSTR_MEM_LOCAL >> 12); /* Local base */ - immap->im_pci.pci_pocmr0 = cpu_to_le32 (POCMR0_MASK_ATTRIB); /* Size & attribute */ - - /* - * Set up master window that allows the CPU to access PCI Memory (non-prefetch) - * space. This window is set up using the second set of Outbound ATU registers. - */ - immap->im_pci.pci_potar1 = cpu_to_le32 (PCI_MSTR_MEMIO_BUS >> 12); /* PCI base */ - immap->im_pci.pci_pobar1 = cpu_to_le32 (PCI_MSTR_MEMIO_LOCAL >> 12); /* Local base */ - immap->im_pci.pci_pocmr1 = cpu_to_le32 (POCMR1_MASK_ATTRIB); /* Size & attribute */ - - /* - * Set up master window that allows the CPU to access PCI IO space. This window - * is set up using the third set of Outbound ATU registers. - */ - immap->im_pci.pci_potar2 = cpu_to_le32 (PCI_MSTR_IO_BUS >> 12); /* PCI base */ - immap->im_pci.pci_pobar2 = cpu_to_le32 (PCI_MSTR_IO_LOCAL >> 12); /* Local base */ - immap->im_pci.pci_pocmr2 = cpu_to_le32 (POCMR2_MASK_ATTRIB); /* Size & attribute */ - - /* - * Set up slave window that allows PCI masters to access MPC826x local memory. - * This window is set up using the first set of Inbound ATU registers - */ - immap->im_pci.pci_pitar0 = cpu_to_le32 (PCI_SLV_MEM_LOCAL >> 12); /* PCI base */ - immap->im_pci.pci_pibar0 = cpu_to_le32 (PCI_SLV_MEM_BUS >> 12); /* Local base */ - immap->im_pci.pci_picmr0 = cpu_to_le32 (PICMR0_MASK_ATTRIB); /* Size & attribute */ - - /* See above for description - puts PCI request as highest priority */ -#ifdef CONFIG_MPC8272 - immap->im_siu_conf.sc_ppc_alrh = 0x01236745; -#else - immap->im_siu_conf.sc_ppc_alrh = 0x03124567; -#endif - - /* Park the bus on the PCI */ - immap->im_siu_conf.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI; - - /* Host mode - specify the bridge as a host-PCI bridge */ - - pci_hose_write_config_byte (hose, host_devno, PCI_CLASS_CODE, - PCI_CLASS_BRIDGE_CTLR); - - /* Enable the host bridge to be a master on the PCI bus, and to act as a PCI memory target */ - pci_hose_read_config_word (hose, host_devno, PCI_COMMAND, &tempShort); - pci_hose_write_config_word (hose, host_devno, PCI_COMMAND, - tempShort | PCI_COMMAND_MASTER | - PCI_COMMAND_MEMORY); - - /* do some bridge init, should be done on all 8260 based bridges */ - pci_hose_write_config_byte (hose, host_devno, PCI_CACHE_LINE_SIZE, - 0x08); - pci_hose_write_config_byte (hose, host_devno, PCI_LATENCY_TIMER, - 0xF8); - - hose->first_busno = 0; - hose->last_busno = 0xff; - - /* System memory space */ -#if defined CONFIG_MPC8266ADS || defined CONFIG_MPC8272 || defined CONFIG_PM826 - pci_set_region (hose->regions + 0, - PCI_SLV_MEM_BUS, - PCI_SLV_MEM_LOCAL, - gd->ram_size, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); -#else - pci_set_region (hose->regions + 0, - CONFIG_SYS_SDRAM_BASE, - CONFIG_SYS_SDRAM_BASE, - 0x4000000, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); -#endif - - /* PCI memory space */ -#if defined CONFIG_MPC8266ADS || defined CONFIG_MPC8272 - pci_set_region (hose->regions + 1, - PCI_MSTR_MEMIO_BUS, - PCI_MSTR_MEMIO_LOCAL, - PCI_MSTR_MEMIO_SIZE, PCI_REGION_MEM); -#else - pci_set_region (hose->regions + 1, - PCI_MSTR_MEM_BUS, - PCI_MSTR_MEM_LOCAL, - PCI_MSTR_MEM_SIZE, PCI_REGION_MEM); -#endif - - /* PCI I/O space */ - pci_set_region (hose->regions + 2, - PCI_MSTR_IO_BUS, - PCI_MSTR_IO_LOCAL, PCI_MSTR_IO_SIZE, PCI_REGION_IO); - - hose->region_count = 3; - - pci_register_hose (hose); - /* Mask off master abort machine checks */ - immap->im_pci.pci_emr &= cpu_to_le32 (~PCI_ERROR_PCI_NO_RSP); - eieio (); - - hose->last_busno = pci_hose_scan (hose); - - - /* clear the error in the error status register */ - immap->im_pci.pci_esr = cpu_to_le32 (PCI_ERROR_PCI_NO_RSP); - - /* unmask master abort machine checks */ - immap->im_pci.pci_emr |= cpu_to_le32 (PCI_ERROR_PCI_NO_RSP); -} - -#if defined(CONFIG_OF_LIBFDT) -void ft_pci_setup(void *blob, bd_t *bd) -{ - do_fixup_by_prop_u32(blob, "device_type", "pci", 4, - "clock-frequency", gd->pci_clk, 1); -} -#endif - -#endif /* CONFIG_PCI */ diff --git a/cpu/mpc8260/serial_scc.c b/cpu/mpc8260/serial_scc.c deleted file mode 100644 index 4ab6a28..0000000 --- a/cpu/mpc8260/serial_scc.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * Hacked for MPC8260 by Murray.Jensen@cmst.csiro.au, 19-Oct-00. - */ - -/* - * Minimal serial functions needed to use one of the SCC ports - * as serial console interface. - */ - -#include <common.h> -#include <mpc8260.h> -#include <asm/cpm_8260.h> - -DECLARE_GLOBAL_DATA_PTR; - -#if defined(CONFIG_CONS_ON_SCC) - -#if CONFIG_CONS_INDEX == 1 /* Console on SCC1 */ - -#define SCC_INDEX 0 -#define PROFF_SCC PROFF_SCC1 -#define CMXSCR_MASK (CMXSCR_GR1|CMXSCR_SC1|\ - CMXSCR_RS1CS_MSK|CMXSCR_TS1CS_MSK) -#define CMXSCR_VALUE (CMXSCR_RS1CS_BRG1|CMXSCR_TS1CS_BRG1) -#define CPM_CR_SCC_PAGE CPM_CR_SCC1_PAGE -#define CPM_CR_SCC_SBLOCK CPM_CR_SCC1_SBLOCK - -#elif CONFIG_CONS_INDEX == 2 /* Console on SCC2 */ - -#define SCC_INDEX 1 -#define PROFF_SCC PROFF_SCC2 -#define CMXSCR_MASK (CMXSCR_GR2|CMXSCR_SC2|\ - CMXSCR_RS2CS_MSK|CMXSCR_TS2CS_MSK) -#define CMXSCR_VALUE (CMXSCR_RS2CS_BRG2|CMXSCR_TS2CS_BRG2) -#define CPM_CR_SCC_PAGE CPM_CR_SCC2_PAGE -#define CPM_CR_SCC_SBLOCK CPM_CR_SCC2_SBLOCK - -#elif CONFIG_CONS_INDEX == 3 /* Console on SCC3 */ - -#define SCC_INDEX 2 -#define PROFF_SCC PROFF_SCC3 -#define CMXSCR_MASK (CMXSCR_GR3|CMXSCR_SC3|\ - CMXSCR_RS3CS_MSK|CMXSCR_TS3CS_MSK) -#define CMXSCR_VALUE (CMXSCR_RS3CS_BRG3|CMXSCR_TS3CS_BRG3) -#define CPM_CR_SCC_PAGE CPM_CR_SCC3_PAGE -#define CPM_CR_SCC_SBLOCK CPM_CR_SCC3_SBLOCK - -#elif CONFIG_CONS_INDEX == 4 /* Console on SCC4 */ - -#define SCC_INDEX 3 -#define PROFF_SCC PROFF_SCC4 -#define CMXSCR_MASK (CMXSCR_GR4|CMXSCR_SC4|\ - CMXSCR_RS4CS_MSK|CMXSCR_TS4CS_MSK) -#define CMXSCR_VALUE (CMXSCR_RS4CS_BRG4|CMXSCR_TS4CS_BRG4) -#define CPM_CR_SCC_PAGE CPM_CR_SCC4_PAGE -#define CPM_CR_SCC_SBLOCK CPM_CR_SCC4_SBLOCK - -#else - -#error "console not correctly defined" - -#endif - -int serial_init (void) -{ - volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; - volatile scc_t *sp; - volatile scc_uart_t *up; - volatile cbd_t *tbdf, *rbdf; - volatile cpm8260_t *cp = &(im->im_cpm); - uint dpaddr; - - /* initialize pointers to SCC */ - - sp = (scc_t *) &(im->im_scc[SCC_INDEX]); - up = (scc_uart_t *)&im->im_dprambase[PROFF_SCC]; - - /* Disable transmitter/receiver. - */ - sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - - /* put the SCC channel into NMSI (non multiplexd serial interface) - * mode and wire the selected SCC Tx and Rx clocks to BRGx (15-15). - */ - im->im_cpmux.cmx_scr = (im->im_cpmux.cmx_scr&~CMXSCR_MASK)|CMXSCR_VALUE; - - /* Set up the baud rate generator. - */ - serial_setbrg (); - - /* Allocate space for two buffer descriptors in the DP ram. - * damm: allocating space after the two buffers for rx/tx data - */ - - dpaddr = m8260_cpm_dpalloc((2 * sizeof (cbd_t)) + 2, 16); - - /* Set the physical address of the host memory buffers in - * the buffer descriptors. - */ - rbdf = (cbd_t *)&im->im_dprambase[dpaddr]; - rbdf->cbd_bufaddr = (uint) (rbdf+2); - rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP; - tbdf = rbdf + 1; - tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1; - tbdf->cbd_sc = BD_SC_WRAP; - - /* Set up the uart parameters in the parameter ram. - */ - up->scc_genscc.scc_rbase = dpaddr; - up->scc_genscc.scc_tbase = dpaddr+sizeof(cbd_t); - up->scc_genscc.scc_rfcr = CPMFCR_EB; - up->scc_genscc.scc_tfcr = CPMFCR_EB; - up->scc_genscc.scc_mrblr = 1; - up->scc_maxidl = 0; - up->scc_brkcr = 1; - up->scc_parec = 0; - up->scc_frmec = 0; - up->scc_nosec = 0; - up->scc_brkec = 0; - up->scc_uaddr1 = 0; - up->scc_uaddr2 = 0; - up->scc_toseq = 0; - up->scc_char1 = up->scc_char2 = up->scc_char3 = up->scc_char4 = 0x8000; - up->scc_char5 = up->scc_char6 = up->scc_char7 = up->scc_char8 = 0x8000; - up->scc_rccm = 0xc0ff; - - /* Mask all interrupts and remove anything pending. - */ - sp->scc_sccm = 0; - sp->scc_scce = 0xffff; - - /* Set 8 bit FIFO, 16 bit oversampling and UART mode. - */ - sp->scc_gsmrh = SCC_GSMRH_RFW; /* 8 bit FIFO */ - sp->scc_gsmrl = \ - SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16 | SCC_GSMRL_MODE_UART; - - /* Set CTS flow control, 1 stop bit, 8 bit character length, - * normal async UART mode, no parity - */ - sp->scc_psmr = SCU_PSMR_FLC | SCU_PSMR_CL; - - /* execute the "Init Rx and Tx params" CP command. - */ - - while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ - ; - - cp->cp_cpcr = mk_cr_cmd(CPM_CR_SCC_PAGE, CPM_CR_SCC_SBLOCK, - 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; - - while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ - ; - - /* Enable transmitter/receiver. - */ - sp->scc_gsmrl |= SCC_GSMRL_ENR | SCC_GSMRL_ENT; - - return (0); -} - -void -serial_setbrg (void) -{ -#if defined(CONFIG_CONS_USE_EXTC) - m8260_cpm_extcbrg(SCC_INDEX, gd->baudrate, - CONFIG_CONS_EXTC_RATE, CONFIG_CONS_EXTC_PINSEL); -#else - m8260_cpm_setbrg(SCC_INDEX, gd->baudrate); -#endif -} - -void -serial_putc(const char c) -{ - volatile scc_uart_t *up; - volatile cbd_t *tbdf; - volatile immap_t *im; - - if (c == '\n') - serial_putc ('\r'); - - im = (immap_t *)CONFIG_SYS_IMMR; - up = (scc_uart_t *)&im->im_dprambase[PROFF_SCC]; - tbdf = (cbd_t *)&im->im_dprambase[up->scc_genscc.scc_tbase]; - - /* Wait for last character to go. - */ - while (tbdf->cbd_sc & BD_SC_READY) - ; - - /* Load the character into the transmit buffer. - */ - *(volatile char *)tbdf->cbd_bufaddr = c; - tbdf->cbd_datlen = 1; - tbdf->cbd_sc |= BD_SC_READY; -} - -void -serial_puts (const char *s) -{ - while (*s) { - serial_putc (*s++); - } -} - -int -serial_getc(void) -{ - volatile cbd_t *rbdf; - volatile scc_uart_t *up; - volatile immap_t *im; - unsigned char c; - - im = (immap_t *)CONFIG_SYS_IMMR; - up = (scc_uart_t *)&im->im_dprambase[PROFF_SCC]; - rbdf = (cbd_t *)&im->im_dprambase[up->scc_genscc.scc_rbase]; - - /* Wait for character to show up. - */ - while (rbdf->cbd_sc & BD_SC_EMPTY) - ; - - /* Grab the char and clear the buffer again. - */ - c = *(volatile unsigned char *)rbdf->cbd_bufaddr; - rbdf->cbd_sc |= BD_SC_EMPTY; - - return (c); -} - -int -serial_tstc() -{ - volatile cbd_t *rbdf; - volatile scc_uart_t *up; - volatile immap_t *im; - - im = (immap_t *)CONFIG_SYS_IMMR; - up = (scc_uart_t *)&im->im_dprambase[PROFF_SCC]; - rbdf = (cbd_t *)&im->im_dprambase[up->scc_genscc.scc_rbase]; - - return ((rbdf->cbd_sc & BD_SC_EMPTY) == 0); -} - -#endif /* CONFIG_CONS_ON_SCC */ - -#if defined(CONFIG_KGDB_ON_SCC) - -#if defined(CONFIG_CONS_ON_SCC) && CONFIG_KGDB_INDEX == CONFIG_CONS_INDEX -#error Whoops! serial console and kgdb are on the same scc serial port -#endif - -#if CONFIG_KGDB_INDEX == 1 /* KGDB Port on SCC1 */ - -#define KGDB_SCC_INDEX 0 -#define KGDB_PROFF_SCC PROFF_SCC1 -#define KGDB_CMXSCR_MASK (CMXSCR_GR1|CMXSCR_SC1|\ - CMXSCR_RS1CS_MSK|CMXSCR_TS1CS_MSK) -#define KGDB_CMXSCR_VALUE (CMXSCR_RS1CS_BRG1|CMXSCR_TS1CS_BRG1) -#define KGDB_CPM_CR_SCC_PAGE CPM_CR_SCC1_PAGE -#define KGDB_CPM_CR_SCC_SBLOCK CPM_CR_SCC1_SBLOCK - -#elif CONFIG_KGDB_INDEX == 2 /* KGDB Port on SCC2 */ - -#define KGDB_SCC_INDEX 1 -#define KGDB_PROFF_SCC PROFF_SCC2 -#define KGDB_CMXSCR_MASK (CMXSCR_GR2|CMXSCR_SC2|\ - CMXSCR_RS2CS_MSK|CMXSCR_TS2CS_MSK) -#define KGDB_CMXSCR_VALUE (CMXSCR_RS2CS_BRG2|CMXSCR_TS2CS_BRG2) -#define KGDB_CPM_CR_SCC_PAGE CPM_CR_SCC2_PAGE -#define KGDB_CPM_CR_SCC_SBLOCK CPM_CR_SCC2_SBLOCK - -#elif CONFIG_KGDB_INDEX == 3 /* KGDB Port on SCC3 */ - -#define KGDB_SCC_INDEX 2 -#define KGDB_PROFF_SCC PROFF_SCC3 -#define KGDB_CMXSCR_MASK (CMXSCR_GR3|CMXSCR_SC3|\ - CMXSCR_RS3CS_MSK|CMXSCR_TS3CS_MSK) -#define KGDB_CMXSCR_VALUE (CMXSCR_RS3CS_BRG3|CMXSCR_TS3CS_BRG3) -#define KGDB_CPM_CR_SCC_PAGE CPM_CR_SCC3_PAGE -#define KGDB_CPM_CR_SCC_SBLOCK CPM_CR_SCC3_SBLOCK - -#elif CONFIG_KGDB_INDEX == 4 /* KGDB Port on SCC4 */ - -#define KGDB_SCC_INDEX 3 -#define KGDB_PROFF_SCC PROFF_SCC4 -#define KGDB_CMXSCR_MASK (CMXSCR_GR4|CMXSCR_SC4|\ - CMXSCR_RS4CS_MSK|CMXSCR_TS4CS_MSK) -#define KGDB_CMXSCR_VALUE (CMXSCR_RS4CS_BRG4|CMXSCR_TS4CS_BRG4) -#define KGDB_CPM_CR_SCC_PAGE CPM_CR_SCC4_PAGE -#define KGDB_CPM_CR_SCC_SBLOCK CPM_CR_SCC4_SBLOCK - -#else - -#error "kgdb serial port not correctly defined" - -#endif - -void -kgdb_serial_init (void) -{ - volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; - volatile scc_t *sp; - volatile scc_uart_t *up; - volatile cbd_t *tbdf, *rbdf; - volatile cpm8260_t *cp = &(im->im_cpm); - uint dpaddr, speed = CONFIG_KGDB_BAUDRATE; - char *s, *e; - - if ((s = getenv("kgdbrate")) != NULL && *s != '\0') { - ulong rate = simple_strtoul(s, &e, 10); - if (e > s && *e == '\0') - speed = rate; - } - - /* initialize pointers to SCC */ - - sp = (scc_t *) &(im->im_scc[KGDB_SCC_INDEX]); - up = (scc_uart_t *)&im->im_dprambase[KGDB_PROFF_SCC]; - - /* Disable transmitter/receiver. - */ - sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - - /* put the SCC channel into NMSI (non multiplexd serial interface) - * mode and wire the selected SCC Tx and Rx clocks to BRGx (15-15). - */ - im->im_cpmux.cmx_scr = \ - (im->im_cpmux.cmx_scr & ~KGDB_CMXSCR_MASK) | KGDB_CMXSCR_VALUE; - - /* Set up the baud rate generator. - */ -#if defined(CONFIG_KGDB_USE_EXTC) - m8260_cpm_extcbrg(KGDB_SCC_INDEX, speed, - CONFIG_KGDB_EXTC_RATE, CONFIG_KGDB_EXTC_PINSEL); -#else - m8260_cpm_setbrg(KGDB_SCC_INDEX, speed); -#endif - - /* Allocate space for two buffer descriptors in the DP ram. - * damm: allocating space after the two buffers for rx/tx data - */ - - dpaddr = m8260_cpm_dpalloc((2 * sizeof (cbd_t)) + 2, 16); - - /* Set the physical address of the host memory buffers in - * the buffer descriptors. - */ - rbdf = (cbd_t *)&im->im_dprambase[dpaddr]; - rbdf->cbd_bufaddr = (uint) (rbdf+2); - rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP; - tbdf = rbdf + 1; - tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1; - tbdf->cbd_sc = BD_SC_WRAP; - - /* Set up the uart parameters in the parameter ram. - */ - up->scc_genscc.scc_rbase = dpaddr; - up->scc_genscc.scc_tbase = dpaddr+sizeof(cbd_t); - up->scc_genscc.scc_rfcr = CPMFCR_EB; - up->scc_genscc.scc_tfcr = CPMFCR_EB; - up->scc_genscc.scc_mrblr = 1; - up->scc_maxidl = 0; - up->scc_brkcr = 1; - up->scc_parec = 0; - up->scc_frmec = 0; - up->scc_nosec = 0; - up->scc_brkec = 0; - up->scc_uaddr1 = 0; - up->scc_uaddr2 = 0; - up->scc_toseq = 0; - up->scc_char1 = up->scc_char2 = up->scc_char3 = up->scc_char4 = 0x8000; - up->scc_char5 = up->scc_char6 = up->scc_char7 = up->scc_char8 = 0x8000; - up->scc_rccm = 0xc0ff; - - /* Mask all interrupts and remove anything pending. - */ - sp->scc_sccm = 0; - sp->scc_scce = 0xffff; - - /* Set 8 bit FIFO, 16 bit oversampling and UART mode. - */ - sp->scc_gsmrh = SCC_GSMRH_RFW; /* 8 bit FIFO */ - sp->scc_gsmrl = \ - SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16 | SCC_GSMRL_MODE_UART; - - /* Set CTS flow control, 1 stop bit, 8 bit character length, - * normal async UART mode, no parity - */ - sp->scc_psmr = SCU_PSMR_FLC | SCU_PSMR_CL; - - /* execute the "Init Rx and Tx params" CP command. - */ - - while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ - ; - - cp->cp_cpcr = mk_cr_cmd(KGDB_CPM_CR_SCC_PAGE, KGDB_CPM_CR_SCC_SBLOCK, - 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; - - while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ - ; - - /* Enable transmitter/receiver. - */ - sp->scc_gsmrl |= SCC_GSMRL_ENR | SCC_GSMRL_ENT; - - printf("SCC%d at %dbps ", CONFIG_KGDB_INDEX, speed); -} - -void -putDebugChar(const char c) -{ - volatile scc_uart_t *up; - volatile cbd_t *tbdf; - volatile immap_t *im; - - if (c == '\n') - putDebugChar ('\r'); - - im = (immap_t *)CONFIG_SYS_IMMR; - up = (scc_uart_t *)&im->im_dprambase[KGDB_PROFF_SCC]; - tbdf = (cbd_t *)&im->im_dprambase[up->scc_genscc.scc_tbase]; - - /* Wait for last character to go. - */ - while (tbdf->cbd_sc & BD_SC_READY) - ; - - /* Load the character into the transmit buffer. - */ - *(volatile char *)tbdf->cbd_bufaddr = c; - tbdf->cbd_datlen = 1; - tbdf->cbd_sc |= BD_SC_READY; -} - -void -putDebugStr (const char *s) -{ - while (*s) { - putDebugChar (*s++); - } -} - -int -getDebugChar(void) -{ - volatile cbd_t *rbdf; - volatile scc_uart_t *up; - volatile immap_t *im; - unsigned char c; - - im = (immap_t *)CONFIG_SYS_IMMR; - up = (scc_uart_t *)&im->im_dprambase[KGDB_PROFF_SCC]; - rbdf = (cbd_t *)&im->im_dprambase[up->scc_genscc.scc_rbase]; - - /* Wait for character to show up. - */ - while (rbdf->cbd_sc & BD_SC_EMPTY) - ; - - /* Grab the char and clear the buffer again. - */ - c = *(volatile unsigned char *)rbdf->cbd_bufaddr; - rbdf->cbd_sc |= BD_SC_EMPTY; - - return (c); -} - -void -kgdb_interruptible(int yes) -{ - return; -} - -#endif /* CONFIG_KGDB_ON_SCC */ diff --git a/cpu/mpc8260/serial_smc.c b/cpu/mpc8260/serial_smc.c deleted file mode 100644 index fbb3fb0..0000000 --- a/cpu/mpc8260/serial_smc.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - * (C) Copyright 2000, 2001, 2002 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * Hacked for MPC8260 by Murray.Jensen@cmst.csiro.au, 19-Oct-00, with - * changes based on the file arch/ppc/mbxboot/m8260_tty.c from the - * Linux/PPC sources (m8260_tty.c had no copyright info in it). - */ - -/* - * Minimal serial functions needed to use one of the SMC ports - * as serial console interface. - */ - -#include <common.h> -#include <mpc8260.h> -#include <asm/cpm_8260.h> - -DECLARE_GLOBAL_DATA_PTR; - -#if defined(CONFIG_CONS_ON_SMC) - -#if CONFIG_CONS_INDEX == 1 /* Console on SMC1 */ - -#define SMC_INDEX 0 -#define PROFF_SMC_BASE PROFF_SMC1_BASE -#define PROFF_SMC PROFF_SMC1 -#define CPM_CR_SMC_PAGE CPM_CR_SMC1_PAGE -#define CPM_CR_SMC_SBLOCK CPM_CR_SMC1_SBLOCK -#define CMXSMR_MASK (CMXSMR_SMC1|CMXSMR_SMC1CS_MSK) -#define CMXSMR_VALUE CMXSMR_SMC1CS_BRG7 - -#elif CONFIG_CONS_INDEX == 2 /* Console on SMC2 */ - -#define SMC_INDEX 1 -#define PROFF_SMC_BASE PROFF_SMC2_BASE -#define PROFF_SMC PROFF_SMC2 -#define CPM_CR_SMC_PAGE CPM_CR_SMC2_PAGE -#define CPM_CR_SMC_SBLOCK CPM_CR_SMC2_SBLOCK -#define CMXSMR_MASK (CMXSMR_SMC2|CMXSMR_SMC2CS_MSK) -#define CMXSMR_VALUE CMXSMR_SMC2CS_BRG8 - -#else - -#error "console not correctly defined" - -#endif - -#if !defined(CONFIG_SYS_SMC_RXBUFLEN) -#define CONFIG_SYS_SMC_RXBUFLEN 1 -#define CONFIG_SYS_MAXIDLE 0 -#else -#if !defined(CONFIG_SYS_MAXIDLE) -#error "you must define CONFIG_SYS_MAXIDLE" -#endif -#endif - -typedef volatile struct serialbuffer { - cbd_t rxbd; /* Rx BD */ - cbd_t txbd; /* Tx BD */ - uint rxindex; /* index for next character to read */ - volatile uchar rxbuf[CONFIG_SYS_SMC_RXBUFLEN];/* rx buffers */ - volatile uchar txbuf; /* tx buffers */ -} serialbuffer_t; - -/* map rs_table index to baud rate generator index */ -static unsigned char brg_map[] = { - 6, /* BRG7 for SMC1 */ - 7, /* BRG8 for SMC2 */ - 0, /* BRG1 for SCC1 */ - 1, /* BRG1 for SCC2 */ - 2, /* BRG1 for SCC3 */ - 3, /* BRG1 for SCC4 */ -}; - -int serial_init (void) -{ - volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; - volatile smc_t *sp; - volatile smc_uart_t *up; - volatile cpm8260_t *cp = &(im->im_cpm); - uint dpaddr; - volatile serialbuffer_t *rtx; - - /* initialize pointers to SMC */ - - sp = (smc_t *) &(im->im_smc[SMC_INDEX]); - *(ushort *)(&im->im_dprambase[PROFF_SMC_BASE]) = PROFF_SMC; - up = (smc_uart_t *)&im->im_dprambase[PROFF_SMC]; - - /* Disable transmitter/receiver. */ - sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - - /* NOTE: I/O port pins are set up via the iop_conf_tab[] table */ - - /* Allocate space for two buffer descriptors in the DP ram. - * damm: allocating space after the two buffers for rx/tx data - */ - - /* allocate size of struct serialbuffer with bd rx/tx, - * buffer rx/tx and rx index - */ - dpaddr = m8260_cpm_dpalloc((sizeof(serialbuffer_t)), 16); - - rtx = (serialbuffer_t *)&im->im_dprambase[dpaddr]; - - /* Set the physical address of the host memory buffers in - * the buffer descriptors. - */ - rtx->rxbd.cbd_bufaddr = (uint) &rtx->rxbuf; - rtx->rxbd.cbd_sc = 0; - - rtx->txbd.cbd_bufaddr = (uint) &rtx->txbuf; - rtx->txbd.cbd_sc = 0; - - /* Set up the uart parameters in the parameter ram. */ - up->smc_rbase = dpaddr; - up->smc_tbase = dpaddr+sizeof(cbd_t); - up->smc_rfcr = CPMFCR_EB; - up->smc_tfcr = CPMFCR_EB; - up->smc_brklen = 0; - up->smc_brkec = 0; - up->smc_brkcr = 0; - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; - - /* Mask all interrupts and remove anything pending. */ - sp->smc_smcm = 0; - sp->smc_smce = 0xff; - - /* put the SMC channel into NMSI (non multiplexd serial interface) - * mode and wire either BRG7 to SMC1 or BRG8 to SMC2 (15-17). - */ - im->im_cpmux.cmx_smr = (im->im_cpmux.cmx_smr&~CMXSMR_MASK)|CMXSMR_VALUE; - - /* Set up the baud rate generator. */ - serial_setbrg (); - - /* Make the first buffer the only buffer. */ - rtx->txbd.cbd_sc |= BD_SC_WRAP; - rtx->rxbd.cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; - - /* single/multi character receive. */ - up->smc_mrblr = CONFIG_SYS_SMC_RXBUFLEN; - up->smc_maxidl = CONFIG_SYS_MAXIDLE; - rtx->rxindex = 0; - - /* Initialize Tx/Rx parameters. */ - - while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ - ; - - cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC_PAGE, CPM_CR_SMC_SBLOCK, - 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; - - while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ - ; - - /* Enable transmitter/receiver. */ - sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; - - return (0); -} - -void -serial_setbrg (void) -{ -#if defined(CONFIG_CONS_USE_EXTC) - m8260_cpm_extcbrg(brg_map[SMC_INDEX], gd->baudrate, - CONFIG_CONS_EXTC_RATE, CONFIG_CONS_EXTC_PINSEL); -#else - m8260_cpm_setbrg(brg_map[SMC_INDEX], gd->baudrate); -#endif -} - -void -serial_putc(const char c) -{ - volatile smc_uart_t *up; - volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; - volatile serialbuffer_t *rtx; - - if (c == '\n') - serial_putc ('\r'); - - up = (smc_uart_t *)&(im->im_dprambase[PROFF_SMC]); - - rtx = (serialbuffer_t *)&im->im_dprambase[up->smc_rbase]; - - /* Wait for last character to go. */ - while (rtx->txbd.cbd_sc & BD_SC_READY & BD_SC_READY) - ; - rtx->txbuf = c; - rtx->txbd.cbd_datlen = 1; - rtx->txbd.cbd_sc |= BD_SC_READY; -} - -void -serial_puts (const char *s) -{ - while (*s) { - serial_putc (*s++); - } -} - -int -serial_getc(void) -{ - volatile smc_uart_t *up; - volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; - volatile serialbuffer_t *rtx; - unsigned char c; - - up = (smc_uart_t *)&(im->im_dprambase[PROFF_SMC]); - - rtx = (serialbuffer_t *)&im->im_dprambase[up->smc_rbase]; - - /* Wait for character to show up. */ - while (rtx->rxbd.cbd_sc & BD_SC_EMPTY) - ; - - /* the characters are read one by one, - * use the rxindex to know the next char to deliver - */ - c = *(unsigned char *) (rtx->rxbd.cbd_bufaddr + rtx->rxindex); - rtx->rxindex++; - - /* check if all char are readout, then make prepare for next receive */ - if (rtx->rxindex >= rtx->rxbd.cbd_datlen) { - rtx->rxindex = 0; - rtx->rxbd.cbd_sc |= BD_SC_EMPTY; - } - return(c); -} - -int -serial_tstc() -{ - volatile smc_uart_t *up; - volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; - volatile serialbuffer_t *rtx; - - up = (smc_uart_t *)&(im->im_dprambase[PROFF_SMC]); - rtx = (serialbuffer_t *)&im->im_dprambase[up->smc_rbase]; - - return !(rtx->rxbd.cbd_sc & BD_SC_EMPTY); -} - -#endif /* CONFIG_CONS_ON_SMC */ - -#if defined(CONFIG_KGDB_ON_SMC) - -#if defined(CONFIG_CONS_ON_SMC) && CONFIG_KGDB_INDEX == CONFIG_CONS_INDEX -#error Whoops! serial console and kgdb are on the same smc serial port -#endif - -#if CONFIG_KGDB_INDEX == 1 /* KGDB Port on SMC1 */ - -#define KGDB_SMC_INDEX 0 -#define KGDB_PROFF_SMC_BASE PROFF_SMC1_BASE -#define KGDB_PROFF_SMC PROFF_SMC1 -#define KGDB_CPM_CR_SMC_PAGE CPM_CR_SMC1_PAGE -#define KGDB_CPM_CR_SMC_SBLOCK CPM_CR_SMC1_SBLOCK -#define KGDB_CMXSMR_MASK (CMXSMR_SMC1|CMXSMR_SMC1CS_MSK) -#define KGDB_CMXSMR_VALUE CMXSMR_SMC1CS_BRG7 - -#elif CONFIG_KGDB_INDEX == 2 /* KGDB Port on SMC2 */ - -#define KGDB_SMC_INDEX 1 -#define KGDB_PROFF_SMC_BASE PROFF_SMC2_BASE -#define KGDB_PROFF_SMC PROFF_SMC2 -#define KGDB_CPM_CR_SMC_PAGE CPM_CR_SMC2_PAGE -#define KGDB_CPM_CR_SMC_SBLOCK CPM_CR_SMC2_SBLOCK -#define KGDB_CMXSMR_MASK (CMXSMR_SMC2|CMXSMR_SMC2CS_MSK) -#define KGDB_CMXSMR_VALUE CMXSMR_SMC2CS_BRG8 - -#else - -#error "console not correctly defined" - -#endif - -void -kgdb_serial_init (void) -{ - volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; - volatile smc_t *sp; - volatile smc_uart_t *up; - volatile cbd_t *tbdf, *rbdf; - volatile cpm8260_t *cp = &(im->im_cpm); - uint dpaddr, speed = CONFIG_KGDB_BAUDRATE; - char *s, *e; - - if ((s = getenv("kgdbrate")) != NULL && *s != '\0') { - ulong rate = simple_strtoul(s, &e, 10); - if (e > s && *e == '\0') - speed = rate; - } - - /* initialize pointers to SMC */ - - sp = (smc_t *) &(im->im_smc[KGDB_SMC_INDEX]); - *(ushort *)(&im->im_dprambase[KGDB_PROFF_SMC_BASE]) = KGDB_PROFF_SMC; - up = (smc_uart_t *)&im->im_dprambase[KGDB_PROFF_SMC]; - - /* Disable transmitter/receiver. */ - sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - - /* NOTE: I/O port pins are set up via the iop_conf_tab[] table */ - - /* Allocate space for two buffer descriptors in the DP ram. - * damm: allocating space after the two buffers for rx/tx data - */ - - dpaddr = m8260_cpm_dpalloc((2 * sizeof (cbd_t)) + 2, 16); - - /* Set the physical address of the host memory buffers in - * the buffer descriptors. - */ - rbdf = (cbd_t *)&im->im_dprambase[dpaddr]; - rbdf->cbd_bufaddr = (uint) (rbdf+2); - rbdf->cbd_sc = 0; - tbdf = rbdf + 1; - tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1; - tbdf->cbd_sc = 0; - - /* Set up the uart parameters in the parameter ram. */ - up->smc_rbase = dpaddr; - up->smc_tbase = dpaddr+sizeof(cbd_t); - up->smc_rfcr = CPMFCR_EB; - up->smc_tfcr = CPMFCR_EB; - up->smc_brklen = 0; - up->smc_brkec = 0; - up->smc_brkcr = 0; - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; - - /* Mask all interrupts and remove anything pending. */ - sp->smc_smcm = 0; - sp->smc_smce = 0xff; - - /* put the SMC channel into NMSI (non multiplexd serial interface) - * mode and wire either BRG7 to SMC1 or BRG8 to SMC2 (15-17). - */ - im->im_cpmux.cmx_smr = - (im->im_cpmux.cmx_smr & ~KGDB_CMXSMR_MASK) | KGDB_CMXSMR_VALUE; - - /* Set up the baud rate generator. */ -#if defined(CONFIG_KGDB_USE_EXTC) - m8260_cpm_extcbrg(brg_map[KGDB_SMC_INDEX], speed, - CONFIG_KGDB_EXTC_RATE, CONFIG_KGDB_EXTC_PINSEL); -#else - m8260_cpm_setbrg(brg_map[KGDB_SMC_INDEX], speed); -#endif - - /* Make the first buffer the only buffer. */ - tbdf->cbd_sc |= BD_SC_WRAP; - rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; - - /* Single character receive. */ - up->smc_mrblr = 1; - up->smc_maxidl = 0; - - /* Initialize Tx/Rx parameters. */ - - while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ - ; - - cp->cp_cpcr = mk_cr_cmd(KGDB_CPM_CR_SMC_PAGE, KGDB_CPM_CR_SMC_SBLOCK, - 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; - - while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ - ; - - /* Enable transmitter/receiver. */ - sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; - - printf("SMC%d at %dbps ", CONFIG_KGDB_INDEX, speed); -} - -void -putDebugChar(const char c) -{ - volatile cbd_t *tbdf; - volatile char *buf; - volatile smc_uart_t *up; - volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; - - if (c == '\n') - putDebugChar ('\r'); - - up = (smc_uart_t *)&(im->im_dprambase[KGDB_PROFF_SMC]); - - tbdf = (cbd_t *)&im->im_dprambase[up->smc_tbase]; - - /* Wait for last character to go. */ - buf = (char *)tbdf->cbd_bufaddr; - while (tbdf->cbd_sc & BD_SC_READY) - ; - - *buf = c; - tbdf->cbd_datlen = 1; - tbdf->cbd_sc |= BD_SC_READY; -} - -void -putDebugStr (const char *s) -{ - while (*s) { - putDebugChar (*s++); - } -} - -int -getDebugChar(void) -{ - volatile cbd_t *rbdf; - volatile unsigned char *buf; - volatile smc_uart_t *up; - volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; - unsigned char c; - - up = (smc_uart_t *)&(im->im_dprambase[KGDB_PROFF_SMC]); - - rbdf = (cbd_t *)&im->im_dprambase[up->smc_rbase]; - - /* Wait for character to show up. */ - buf = (unsigned char *)rbdf->cbd_bufaddr; - while (rbdf->cbd_sc & BD_SC_EMPTY) - ; - c = *buf; - rbdf->cbd_sc |= BD_SC_EMPTY; - - return(c); -} - -void -kgdb_interruptible(int yes) -{ - return; -} - -#endif /* CONFIG_KGDB_ON_SMC */ diff --git a/cpu/mpc8260/speed.c b/cpu/mpc8260/speed.c deleted file mode 100644 index 0e1c2b0..0000000 --- a/cpu/mpc8260/speed.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * (C) Copyright 2000-2002 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <mpc8260.h> -#include <asm/processor.h> - -#if defined(CONFIG_BOARD_GET_CPU_CLK_F) -extern unsigned long board_get_cpu_clk_f (void); -#endif - -DECLARE_GLOBAL_DATA_PTR; - -/* ------------------------------------------------------------------------- */ - -/* Bus-to-Core Multiplier */ -#define _1x 2 -#define _1_5x 3 -#define _2x 4 -#define _2_5x 5 -#define _3x 6 -#define _3_5x 7 -#define _4x 8 -#define _4_5x 9 -#define _5x 10 -#define _5_5x 11 -#define _6x 12 -#define _6_5x 13 -#define _7x 14 -#define _7_5x 15 -#define _8x 16 -#define _byp -1 -#define _off -2 -#define _unk -3 - -typedef struct { - int b2c_mult; - int vco_div; - char *freq_60x; - char *freq_core; -} corecnf_t; - -/* - * this table based on "Errata to MPC8260 PowerQUICC II User's Manual", - * Rev. 1, 8/2000, page 10. - */ -corecnf_t corecnf_tab[] = { - { _1_5x, 4, " 33-100", " 33-100" }, /* 0x00 */ - { _1x, 4, " 50-150", " 50-150" }, /* 0x01 */ - { _1x, 8, " 25-75 ", " 25-75 " }, /* 0x02 */ - { _byp, -1, " ?-? ", " ?-? " }, /* 0x03 */ - { _2x, 2, " 50-150", "100-300" }, /* 0x04 */ - { _2x, 4, " 25-75 ", " 50-150" }, /* 0x05 */ - { _2_5x, 2, " 40-120", "100-240" }, /* 0x06 */ - { _4_5x, 2, " 22-65 ", "100-300" }, /* 0x07 */ - { _3x, 2, " 33-100", "100-300" }, /* 0x08 */ - { _5_5x, 2, " 18-55 ", "100-300" }, /* 0x09 */ - { _4x, 2, " 25-75 ", "100-300" }, /* 0x0A */ - { _5x, 2, " 20-60 ", "100-300" }, /* 0x0B */ - { _1_5x, 8, " 16-50 ", " 16-50 " }, /* 0x0C */ - { _6x, 2, " 16-50 ", "100-300" }, /* 0x0D */ - { _3_5x, 2, " 30-85 ", "100-300" }, /* 0x0E */ - { _off, -1, " ?-? ", " ?-? " }, /* 0x0F */ - { _3x, 4, " 16-50 ", " 50-150" }, /* 0x10 */ - { _2_5x, 4, " 20-60 ", " 50-120" }, /* 0x11 */ - { _6_5x, 2, " 15-46 ", "100-300" }, /* 0x12 */ - { _byp, -1, " ?-? ", " ?-? " }, /* 0x13 */ - { _7x, 2, " 14-43 ", "100-300" }, /* 0x14 */ - { _2x, 4, " 25-75 ", " 50-150" }, /* 0x15 */ - { _7_5x, 2, " 13-40 ", "100-300" }, /* 0x16 */ - { _4_5x, 2, " 22-65 ", "100-300" }, /* 0x17 */ - { _unk, -1, " ?-? ", " ?-? " }, /* 0x18 */ - { _5_5x, 2, " 18-55 ", "100-300" }, /* 0x19 */ - { _4x, 2, " 25-75 ", "100-300" }, /* 0x1A */ - { _5x, 2, " 20-60 ", "100-300" }, /* 0x1B */ - { _8x, 2, " 12-38 ", "100-300" }, /* 0x1C */ - { _6x, 2, " 16-50 ", "100-300" }, /* 0x1D */ - { _3_5x, 2, " 30-85 ", "100-300" }, /* 0x1E */ - { _off, -1, " ?-? ", " ?-? " }, /* 0x1F */ -}; - -/* ------------------------------------------------------------------------- */ - -/* - * - */ - -int get_clocks (void) -{ - volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; - ulong clkin; - ulong sccr, dfbrg; - ulong scmr, corecnf, busdf, cpmdf, plldf, pllmf; - corecnf_t *cp; - -#if !defined(CONFIG_8260_CLKIN) -#error clock measuring not implemented yet - define CONFIG_8260_CLKIN -#else -#if defined(CONFIG_BOARD_GET_CPU_CLK_F) - clkin = board_get_cpu_clk_f (); -#else - clkin = CONFIG_8260_CLKIN; -#endif -#endif - - sccr = immap->im_clkrst.car_sccr; - dfbrg = (sccr & SCCR_DFBRG_MSK) >> SCCR_DFBRG_SHIFT; - - scmr = immap->im_clkrst.car_scmr; - corecnf = (scmr & SCMR_CORECNF_MSK) >> SCMR_CORECNF_SHIFT; - cp = &corecnf_tab[corecnf]; - - busdf = (scmr & SCMR_BUSDF_MSK) >> SCMR_BUSDF_SHIFT; - cpmdf = (scmr & SCMR_CPMDF_MSK) >> SCMR_CPMDF_SHIFT; - - /* HiP7, HiP7 Rev01, HiP7 RevA */ - if ((get_pvr () == PVR_8260_HIP7) || - (get_pvr () == PVR_8260_HIP7R1) || - (get_pvr () == PVR_8260_HIP7RA)) { - pllmf = (scmr & SCMR_PLLMF_MSKH7) >> SCMR_PLLMF_SHIFT; - gd->vco_out = clkin * (pllmf + 1); - } else { /* HiP3, HiP4 */ - pllmf = (scmr & SCMR_PLLMF_MSK) >> SCMR_PLLMF_SHIFT; - plldf = (scmr & SCMR_PLLDF) ? 1 : 0; - gd->vco_out = (clkin * 2 * (pllmf + 1)) / (plldf + 1); - } -#if 0 - if (gd->vco_out / (busdf + 1) != clkin) { - /* aaarrrggghhh!!! */ - return (1); - } -#endif - - gd->cpm_clk = gd->vco_out / 2; - gd->bus_clk = clkin; - gd->scc_clk = gd->vco_out / 4; - gd->brg_clk = gd->vco_out / (1 << (2 * (dfbrg + 1))); - - if (cp->b2c_mult > 0) { - gd->cpu_clk = (clkin * cp->b2c_mult) / 2; - } else { - gd->cpu_clk = clkin; - } - -#ifdef CONFIG_PCI - gd->pci_clk = clkin; - - if (sccr & SCCR_PCI_MODE) { - uint pci_div; - uint pcidf = (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT; - - if (sccr & SCCR_PCI_MODCK) { - pci_div = 2; - if (pcidf == 9) { - pci_div *= 5; - } else if (pcidf == 0xB) { - pci_div *= 6; - } else { - pci_div *= (pcidf + 1); - } - } else { - pci_div = pcidf + 1; - } - - gd->pci_clk = (gd->cpm_clk * 2) / pci_div; - } -#endif - - return (0); -} - -int prt_8260_clks (void) -{ - volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; - ulong sccr, dfbrg; - ulong scmr, corecnf, busdf, cpmdf, plldf, pllmf, pcidf; - corecnf_t *cp; - - sccr = immap->im_clkrst.car_sccr; - dfbrg = (sccr & SCCR_DFBRG_MSK) >> SCCR_DFBRG_SHIFT; - - scmr = immap->im_clkrst.car_scmr; - corecnf = (scmr & SCMR_CORECNF_MSK) >> SCMR_CORECNF_SHIFT; - busdf = (scmr & SCMR_BUSDF_MSK) >> SCMR_BUSDF_SHIFT; - cpmdf = (scmr & SCMR_CPMDF_MSK) >> SCMR_CPMDF_SHIFT; - plldf = (scmr & SCMR_PLLDF) ? 1 : 0; - pllmf = (scmr & SCMR_PLLMF_MSK) >> SCMR_PLLMF_SHIFT; - pcidf = (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT; - - cp = &corecnf_tab[corecnf]; - - puts (CPU_ID_STR " Clock Configuration\n - Bus-to-Core Mult "); - - switch (cp->b2c_mult) { - case _byp: - puts ("BYPASS"); - break; - - case _off: - puts ("OFF"); - break; - - case _unk: - puts ("UNKNOWN"); - break; - - default: - printf ("%d%sx", - cp->b2c_mult / 2, - (cp->b2c_mult % 2) ? ".5" : ""); - break; - } - - printf (", VCO Div %d, 60x Bus Freq %s, Core Freq %s\n", - cp->vco_div, cp->freq_60x, cp->freq_core); - - printf (" - dfbrg %ld, corecnf 0x%02lx, busdf %ld, cpmdf %ld, " - "plldf %ld, pllmf %ld, pcidf %ld\n", - dfbrg, corecnf, busdf, cpmdf, - plldf, pllmf, pcidf); - - printf (" - vco_out %10ld, scc_clk %10ld, brg_clk %10ld\n", - gd->vco_out, gd->scc_clk, gd->brg_clk); - - printf (" - cpu_clk %10ld, cpm_clk %10ld, bus_clk %10ld\n", - gd->cpu_clk, gd->cpm_clk, gd->bus_clk); -#ifdef CONFIG_PCI - printf (" - pci_clk %10ld\n", gd->pci_clk); -#endif - putc ('\n'); - - return (0); -} diff --git a/cpu/mpc8260/speed.h b/cpu/mpc8260/speed.h deleted file mode 100644 index 3f32a14..0000000 --- a/cpu/mpc8260/speed.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/*----------------------------------------------------------------------- - * Timer value for timer 2, ICLK = 10 - * - * SPEED_FCOUNT2 = GCLK / (16 * (TIMER_TMR_PS + 1)) - * SPEED_TMR3_PS = (GCLK / (16 * SPEED_FCOUNT3)) - 1 - * - * SPEED_FCOUNT2 timer 2 counting frequency - * GCLK CPU clock - * SPEED_TMR2_PS prescaler - */ -#define SPEED_TMR2_PS (250 - 1) /* divide by 250 */ - -/*----------------------------------------------------------------------- - * Timer value for PIT - * - * PIT_TIME = SPEED_PITC / PITRTCLK - * PITRTCLK = 8192 - */ -#define SPEED_PITC (82 << 16) /* start counting from 82 */ - -/* - * The new value for PTA is calculated from - * - * PTA = (gclk * Trefresh) / (2 ^ (2 * DFBRG) * PTP * NCS) - * - * gclk CPU clock (not bus clock !) - * Trefresh Refresh cycle * 4 (four word bursts used) - * DFBRG For normal mode (no clock reduction) always 0 - * PTP Prescaler (already adjusted for no. of banks and 4K / 8K refresh) - * NCS Number of SDRAM banks (chip selects) on this UPM. - */ diff --git a/cpu/mpc8260/spi.c b/cpu/mpc8260/spi.c deleted file mode 100644 index f5d2ac3..0000000 --- a/cpu/mpc8260/spi.c +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Copyright (c) 2001 Navin Boppuri / Prashant Patel - * <nboppuri@trinetcommunication.com>, - * <pmpatel@trinetcommunication.com> - * Copyright (c) 2001 Gerd Mennchen <Gerd.Mennchen@icn.siemens.de> - * Copyright (c) 2001-2003 Wolfgang Denk, DENX Software Engineering, <wd@denx.de>. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * MPC8260 CPM SPI interface. - * - * Parts of this code are probably not portable and/or specific to - * the board which I used for the tests. Please send fixes/complaints - * to wd@denx.de - * - */ - -#include <common.h> -#include <asm/cpm_8260.h> -#include <linux/ctype.h> -#include <malloc.h> -#include <post.h> -#include <net.h> - -#if defined(CONFIG_SPI) - -/* Warning: - * You cannot enable DEBUG for early system initalization, i. e. when - * this driver is used to read environment parameters like "baudrate" - * from EEPROM which are used to initialize the serial port which is - * needed to print the debug messages... - */ -#undef DEBUG - -#define SPI_EEPROM_WREN 0x06 -#define SPI_EEPROM_RDSR 0x05 -#define SPI_EEPROM_READ 0x03 -#define SPI_EEPROM_WRITE 0x02 - -/* --------------------------------------------------------------- - * Offset for initial SPI buffers in DPRAM: - * We need a 520 byte scratch DPRAM area to use at an early stage. - * It is used between the two initialization calls (spi_init_f() - * and spi_init_r()). - * The value 0x2000 makes it far enough from the start of the data - * area (as well as from the stack pointer). - * --------------------------------------------------------------- */ -#ifndef CONFIG_SYS_SPI_INIT_OFFSET -#define CONFIG_SYS_SPI_INIT_OFFSET 0x2000 -#endif - -#define CPM_SPI_BASE 0x100 - -#ifdef DEBUG - -#define DPRINT(a) printf a; -/* ----------------------------------------------- - * Helper functions to peek into tx and rx buffers - * ----------------------------------------------- */ -static const char * const hex_digit = "0123456789ABCDEF"; - -static char quickhex (int i) -{ - return hex_digit[i]; -} - -static void memdump (void *pv, int num) -{ - int i; - unsigned char *pc = (unsigned char *) pv; - - for (i = 0; i < num; i++) - printf ("%c%c ", quickhex (pc[i] >> 4), quickhex (pc[i] & 0x0f)); - printf ("\t"); - for (i = 0; i < num; i++) - printf ("%c", isprint (pc[i]) ? pc[i] : '.'); - printf ("\n"); -} -#else /* !DEBUG */ - -#define DPRINT(a) - -#endif /* DEBUG */ - -/* ------------------- - * Function prototypes - * ------------------- */ -void spi_init (void); - -ssize_t spi_read (uchar *, int, uchar *, int); -ssize_t spi_write (uchar *, int, uchar *, int); -ssize_t spi_xfer (size_t); - -/* ------------------- - * Variables - * ------------------- */ - -#define MAX_BUFFER 0x104 - -/* ---------------------------------------------------------------------- - * Initially we place the RX and TX buffers at a fixed location in DPRAM! - * ---------------------------------------------------------------------- */ -static uchar *rxbuf = - (uchar *)&((immap_t *)CONFIG_SYS_IMMR)->im_dprambase - [CONFIG_SYS_SPI_INIT_OFFSET]; -static uchar *txbuf = - (uchar *)&((immap_t *)CONFIG_SYS_IMMR)->im_dprambase - [CONFIG_SYS_SPI_INIT_OFFSET+MAX_BUFFER]; - -/* ************************************************************************** - * - * Function: spi_init_f - * - * Description: Init SPI-Controller (ROM part) - * - * return: --- - * - * *********************************************************************** */ -void spi_init_f (void) -{ - unsigned int dpaddr; - - volatile spi_t *spi; - volatile immap_t *immr; - volatile cpm8260_t *cp; - volatile cbd_t *tbdf, *rbdf; - - immr = (immap_t *) CONFIG_SYS_IMMR; - cp = (cpm8260_t *) &immr->im_cpm; - - *(ushort *)(&immr->im_dprambase[PROFF_SPI_BASE]) = PROFF_SPI; - spi = (spi_t *)&immr->im_dprambase[PROFF_SPI]; - -/* 1 */ - /* ------------------------------------------------ - * Initialize Port D SPI pins - * (we are only in Master Mode !) - * ------------------------------------------------ */ - - /* -------------------------------------------- - * GPIO or per. Function - * PPARD[16] = 1 [0x00008000] (SPIMISO) - * PPARD[17] = 1 [0x00004000] (SPIMOSI) - * PPARD[18] = 1 [0x00002000] (SPICLK) - * PPARD[12] = 0 [0x00080000] -> GPIO: (CS for ATC EEPROM) - * -------------------------------------------- */ - immr->im_ioport.iop_ppard |= 0x0000E000; /* set bits */ - immr->im_ioport.iop_ppard &= ~0x00080000; /* reset bit */ - - /* ---------------------------------------------- - * In/Out or per. Function 0/1 - * PDIRD[16] = 0 [0x00008000] -> PERI1: SPIMISO - * PDIRD[17] = 0 [0x00004000] -> PERI1: SPIMOSI - * PDIRD[18] = 0 [0x00002000] -> PERI1: SPICLK - * PDIRD[12] = 1 [0x00080000] -> GPIO OUT: CS for ATC EEPROM - * ---------------------------------------------- */ - immr->im_ioport.iop_pdird &= ~0x0000E000; - immr->im_ioport.iop_pdird |= 0x00080000; - - /* ---------------------------------------------- - * special option reg. - * PSORD[16] = 1 [0x00008000] -> SPIMISO - * PSORD[17] = 1 [0x00004000] -> SPIMOSI - * PSORD[18] = 1 [0x00002000] -> SPICLK - * ---------------------------------------------- */ - immr->im_ioport.iop_psord |= 0x0000E000; - - /* Initialize the parameter ram. - * We need to make sure many things are initialized to zero - */ - spi->spi_rstate = 0; - spi->spi_rdp = 0; - spi->spi_rbptr = 0; - spi->spi_rbc = 0; - spi->spi_rxtmp = 0; - spi->spi_tstate = 0; - spi->spi_tdp = 0; - spi->spi_tbptr = 0; - spi->spi_tbc = 0; - spi->spi_txtmp = 0; - - /* Allocate space for one transmit and one receive buffer - * descriptor in the DP ram - */ -#ifdef CONFIG_SYS_ALLOC_DPRAM - dpaddr = m8260_cpm_dpalloc (sizeof(cbd_t)*2, 8); -#else - dpaddr = CPM_SPI_BASE; -#endif - -/* 3 */ - /* Set up the SPI parameters in the parameter ram */ - spi->spi_rbase = dpaddr; - spi->spi_tbase = dpaddr + sizeof (cbd_t); - - /***********IMPORTANT******************/ - - /* - * Setting transmit and receive buffer descriptor pointers - * initially to rbase and tbase. Only the microcode patches - * documentation talks about initializing this pointer. This - * is missing from the sample I2C driver. If you dont - * initialize these pointers, the kernel hangs. - */ - spi->spi_rbptr = spi->spi_rbase; - spi->spi_tbptr = spi->spi_tbase; - -/* 4 */ - /* Init SPI Tx + Rx Parameters */ - while (cp->cp_cpcr & CPM_CR_FLG) - ; - cp->cp_cpcr = mk_cr_cmd(CPM_CR_SPI_PAGE, CPM_CR_SPI_SBLOCK, - 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG) - ; - -/* 6 */ - /* Set to big endian. */ - spi->spi_tfcr = CPMFCR_EB; - spi->spi_rfcr = CPMFCR_EB; - -/* 7 */ - /* Set maximum receive size. */ - spi->spi_mrblr = MAX_BUFFER; - -/* 8 + 9 */ - /* tx and rx buffer descriptors */ - tbdf = (cbd_t *) & immr->im_dprambase[spi->spi_tbase]; - rbdf = (cbd_t *) & immr->im_dprambase[spi->spi_rbase]; - - tbdf->cbd_sc &= ~BD_SC_READY; - rbdf->cbd_sc &= ~BD_SC_EMPTY; - - /* Set the bd's rx and tx buffer address pointers */ - rbdf->cbd_bufaddr = (ulong) rxbuf; - tbdf->cbd_bufaddr = (ulong) txbuf; - -/* 10 + 11 */ - immr->im_spi.spi_spie = SPI_EMASK; /* Clear all SPI events */ - immr->im_spi.spi_spim = 0x00; /* Mask all SPI events */ - - - return; -} - -/* ************************************************************************** - * - * Function: spi_init_r - * - * Description: Init SPI-Controller (RAM part) - - * The malloc engine is ready and we can move our buffers to - * normal RAM - * - * return: --- - * - * *********************************************************************** */ -void spi_init_r (void) -{ - volatile spi_t *spi; - volatile immap_t *immr; - volatile cpm8260_t *cp; - volatile cbd_t *tbdf, *rbdf; - - immr = (immap_t *) CONFIG_SYS_IMMR; - cp = (cpm8260_t *) &immr->im_cpm; - - spi = (spi_t *)&immr->im_dprambase[PROFF_SPI]; - - /* tx and rx buffer descriptors */ - tbdf = (cbd_t *) & immr->im_dprambase[spi->spi_tbase]; - rbdf = (cbd_t *) & immr->im_dprambase[spi->spi_rbase]; - - /* Allocate memory for RX and TX buffers */ - rxbuf = (uchar *) malloc (MAX_BUFFER); - txbuf = (uchar *) malloc (MAX_BUFFER); - - rbdf->cbd_bufaddr = (ulong) rxbuf; - tbdf->cbd_bufaddr = (ulong) txbuf; - - return; -} - -/**************************************************************************** - * Function: spi_write - **************************************************************************** */ -ssize_t spi_write (uchar *addr, int alen, uchar *buffer, int len) -{ - int i; - - memset(rxbuf, 0, MAX_BUFFER); - memset(txbuf, 0, MAX_BUFFER); - *txbuf = SPI_EEPROM_WREN; /* write enable */ - spi_xfer(1); - memcpy(txbuf, addr, alen); - *txbuf = SPI_EEPROM_WRITE; /* WRITE memory array */ - memcpy(alen + txbuf, buffer, len); - spi_xfer(alen + len); - /* ignore received data */ - for (i = 0; i < 1000; i++) { - *txbuf = SPI_EEPROM_RDSR; /* read status */ - txbuf[1] = 0; - spi_xfer(2); - if (!(rxbuf[1] & 1)) { - break; - } - udelay(1000); - } - if (i >= 1000) { - printf ("*** spi_write: Time out while writing!\n"); - } - - return len; -} - -/**************************************************************************** - * Function: spi_read - **************************************************************************** */ -ssize_t spi_read (uchar *addr, int alen, uchar *buffer, int len) -{ - memset(rxbuf, 0, MAX_BUFFER); - memset(txbuf, 0, MAX_BUFFER); - memcpy(txbuf, addr, alen); - *txbuf = SPI_EEPROM_READ; /* READ memory array */ - - /* - * There is a bug in 860T (?) that cuts the last byte of input - * if we're reading into DPRAM. The solution we choose here is - * to always read len+1 bytes (we have one extra byte at the - * end of the buffer). - */ - spi_xfer(alen + len + 1); - memcpy(buffer, alen + rxbuf, len); - - return len; -} - -/**************************************************************************** - * Function: spi_xfer - **************************************************************************** */ -ssize_t spi_xfer (size_t count) -{ - volatile immap_t *immr; - volatile cpm8260_t *cp; - volatile spi_t *spi; - cbd_t *tbdf, *rbdf; - int tm; - - DPRINT (("*** spi_xfer entered ***\n")); - - immr = (immap_t *) CONFIG_SYS_IMMR; - cp = (cpm8260_t *) &immr->im_cpm; - - spi = (spi_t *)&immr->im_dprambase[PROFF_SPI]; - - tbdf = (cbd_t *) & immr->im_dprambase[spi->spi_tbase]; - rbdf = (cbd_t *) & immr->im_dprambase[spi->spi_rbase]; - - /* Board-specific: Set CS for device (ATC EEPROM) */ - immr->im_ioport.iop_pdatd &= ~0x00080000; - - /* Setting tx bd status and data length */ - tbdf->cbd_sc = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP; - tbdf->cbd_datlen = count; - - DPRINT (("*** spi_xfer: Bytes to be xferred: %d ***\n", - tbdf->cbd_datlen)); - - /* Setting rx bd status and data length */ - rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP; - rbdf->cbd_datlen = 0; /* rx length has no significance */ - - immr->im_spi.spi_spmode = SPMODE_REV | - SPMODE_MSTR | - SPMODE_EN | - SPMODE_LEN(8) | /* 8 Bits per char */ - SPMODE_PM(0x8) ; /* medium speed */ - immr->im_spi.spi_spie = SPI_EMASK; /* Clear all SPI events */ - immr->im_spi.spi_spim = 0x00; /* Mask all SPI events */ - - /* start spi transfer */ - DPRINT (("*** spi_xfer: Performing transfer ...\n")); - immr->im_spi.spi_spcom |= SPI_STR; /* Start transmit */ - - /* -------------------------------- - * Wait for SPI transmit to get out - * or time out (1 second = 1000 ms) - * -------------------------------- */ - for (tm=0; tm<1000; ++tm) { - if (immr->im_spi.spi_spie & SPI_TXB) { /* Tx Buffer Empty */ - DPRINT (("*** spi_xfer: Tx buffer empty\n")); - break; - } - if ((tbdf->cbd_sc & BD_SC_READY) == 0) { - DPRINT (("*** spi_xfer: Tx BD done\n")); - break; - } - udelay (1000); - } - if (tm >= 1000) { - printf ("*** spi_xfer: Time out while xferring to/from SPI!\n"); - } - DPRINT (("*** spi_xfer: ... transfer ended\n")); - -#ifdef DEBUG - printf ("\nspi_xfer: txbuf after xfer\n"); - memdump ((void *) txbuf, 16); /* dump of txbuf before transmit */ - printf ("spi_xfer: rxbuf after xfer\n"); - memdump ((void *) rxbuf, 16); /* dump of rxbuf after transmit */ - printf ("\n"); -#endif - - /* Clear CS for device */ - immr->im_ioport.iop_pdatd |= 0x00080000; - - return count; -} -#endif /* CONFIG_SPI */ diff --git a/cpu/mpc8260/start.S b/cpu/mpc8260/start.S deleted file mode 100644 index 1fc70bc..0000000 --- a/cpu/mpc8260/start.S +++ /dev/null @@ -1,1023 +0,0 @@ -/* - * Copyright (C) 1998 Dan Malek <dmalek@jlc.net> - * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> - * Copyright (C) 2000, 2001,2002 Wolfgang Denk <wd@denx.de> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * U-Boot - Startup Code for MPC8260 PowerPC based Embedded Boards - */ -#include <config.h> -#include <mpc8260.h> -#include <timestamp.h> -#include <version.h> - -#define CONFIG_8260 1 /* needed for Linux kernel header files */ -#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ - -#include <ppc_asm.tmpl> -#include <ppc_defs.h> - -#include <asm/cache.h> -#include <asm/mmu.h> - -#ifndef CONFIG_IDENT_STRING -#define CONFIG_IDENT_STRING "" -#endif - -/* We don't want the MMU yet. -*/ -#undef MSR_KERNEL -/* Floating Point enable, Machine Check and Recoverable Interr. */ -#ifdef DEBUG -#define MSR_KERNEL (MSR_FP|MSR_RI) -#else -#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI) -#endif - -/* - * Set up GOT: Global Offset Table - * - * Use r12 to access the GOT - */ - START_GOT - GOT_ENTRY(_GOT2_TABLE_) - GOT_ENTRY(_FIXUP_TABLE_) - - GOT_ENTRY(_start) - GOT_ENTRY(_start_of_vectors) - GOT_ENTRY(_end_of_vectors) - GOT_ENTRY(transfer_to_handler) - - GOT_ENTRY(__init_end) - GOT_ENTRY(_end) - GOT_ENTRY(__bss_start) -#if defined(CONFIG_HYMOD) - GOT_ENTRY(environment) -#endif - END_GOT - -/* - * Version string - must be in data segment because MPC8260 uses the first - * 256 bytes for the Hard Reset Configuration Word table (see below). - * Similarly, can't have the U-Boot Magic Number as the first thing in - * the image - don't know how this will affect the image tools, but I guess - * I'll find out soon - */ - .data - .globl version_string -version_string: - .ascii U_BOOT_VERSION - .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" - .ascii CONFIG_IDENT_STRING, "\0" - -/* - * Hard Reset Configuration Word (HRCW) table - * - * The Hard Reset Configuration Word (HRCW) sets a number of useful things - * such as whether there is an external memory controller, whether the - * PowerPC core is disabled (i.e. only the communications processor is - * active, accessed by another CPU on the bus), whether using external - * arbitration, external bus mode, boot port size, core initial prefix, - * internal space base, boot memory space, etc. - * - * These things dictate where the processor begins execution, where the - * boot ROM appears in memory, the memory controller setup when access - * boot ROM, etc. The HRCW is *extremely* important. - * - * The HRCW is read from the bus during reset. One CPU on the bus will - * be a hard reset configuration master, any others will be hard reset - * configuration slaves. The master reads eight HRCWs from flash during - * reset - the first it uses for itself, the other 7 it communicates to - * up to 7 configuration slaves by some complicated mechanism, which is - * not really important here. - * - * The configuration master performs 32 successive reads starting at address - * 0 and incrementing by 8 each read (i.e. on 64 bit boundaries) but only 8 - * bits is read, and always from byte lane D[0-7] (so that port size of the - * boot device does not matter). The first four reads form the 32 bit HRCW - * for the master itself. The second four reads form the HRCW for the first - * slave, and so on, up to seven slaves. The 32 bit HRCW is formed by - * concatenating the four bytes, with the first read placed in byte 0 (the - * most significant byte), and so on with the fourth read placed in byte 3 - * (the least significant byte). - */ -#define _HRCW_TABLE_ENTRY(w) \ - .fill 8,1,(((w)>>24)&0xff); \ - .fill 8,1,(((w)>>16)&0xff); \ - .fill 8,1,(((w)>> 8)&0xff); \ - .fill 8,1,(((w) )&0xff) - .text - .globl _hrcw_table -_hrcw_table: - _HRCW_TABLE_ENTRY(CONFIG_SYS_HRCW_MASTER) - _HRCW_TABLE_ENTRY(CONFIG_SYS_HRCW_SLAVE1) - _HRCW_TABLE_ENTRY(CONFIG_SYS_HRCW_SLAVE2) - _HRCW_TABLE_ENTRY(CONFIG_SYS_HRCW_SLAVE3) - _HRCW_TABLE_ENTRY(CONFIG_SYS_HRCW_SLAVE4) - _HRCW_TABLE_ENTRY(CONFIG_SYS_HRCW_SLAVE5) - _HRCW_TABLE_ENTRY(CONFIG_SYS_HRCW_SLAVE6) - _HRCW_TABLE_ENTRY(CONFIG_SYS_HRCW_SLAVE7) -/* - * After configuration, a system reset exception is executed using the - * vector at offset 0x100 relative to the base set by MSR[IP]. If MSR[IP] - * is 0, the base address is 0x00000000. If MSR[IP] is 1, the base address - * is 0xfff00000. In the case of a Power On Reset or Hard Reset, the value - * of MSR[IP] is determined by the CIP field in the HRCW. - * - * Other bits in the HRCW set up the Base Address and Port Size in BR0. - * This determines the location of the boot ROM (flash or EPROM) in the - * processor's address space at boot time. As long as the HRCW is set up - * so that we eventually end up executing the code below when the processor - * executes the reset exception, the actual values used should not matter. - * - * Once we have got here, the address mask in OR0 is cleared so that the - * bottom 32K of the boot ROM is effectively repeated all throughout the - * processor's address space, after which we can jump to the absolute - * address at which the boot ROM was linked at compile time, and proceed - * to initialise the memory controller without worrying if the rug will be - * pulled out from under us, so to speak (it will be fine as long as we - * configure BR0 with the same boot ROM link address). - */ - . = EXC_OFF_SYS_RESET - - .globl _start -_start: - li r21, BOOTFLAG_COLD /* Normal Power-On: Boot from FLASH*/ - nop - b boot_cold - - . = EXC_OFF_SYS_RESET + 0x10 - - .globl _start_warm -_start_warm: - li r21, BOOTFLAG_WARM /* Software reboot */ - b boot_warm - -boot_cold: -#if defined(CONFIG_MPC8260ADS) && defined(CONFIG_SYS_DEFAULT_IMMR) - lis r3, CONFIG_SYS_DEFAULT_IMMR@h - nop - lwz r4, 0(r3) - nop - rlwinm r4, r4, 0, 8, 5 - nop - oris r4, r4, 0x0200 - nop - stw r4, 0(r3) - nop -#endif /* CONFIG_MPC8260ADS && CONFIG_SYS_DEFAULT_IMMR */ -boot_warm: - mfmsr r5 /* save msr contents */ - -#if defined(CONFIG_COGENT) - /* this is what the cogent EPROM does */ - li r0, 0 - mtmsr r0 - isync - bl cogent_init_8260 -#endif /* CONFIG_COGENT */ - -#if defined(CONFIG_SYS_DEFAULT_IMMR) - lis r3, CONFIG_SYS_IMMR@h - ori r3, r3, CONFIG_SYS_IMMR@l - lis r4, CONFIG_SYS_DEFAULT_IMMR@h - stw r3, 0x1A8(r4) -#endif /* CONFIG_SYS_DEFAULT_IMMR */ - - /* Initialise the MPC8260 processor core */ - /*--------------------------------------------------------------*/ - - bl init_8260_core - -#ifndef CONFIG_SYS_RAMBOOT - /* When booting from ROM (Flash or EPROM), clear the */ - /* Address Mask in OR0 so ROM appears everywhere */ - /*--------------------------------------------------------------*/ - - lis r3, (CONFIG_SYS_IMMR+IM_REGBASE)@h - lwz r4, IM_OR0@l(r3) - li r5, 0x7fff - and r4, r4, r5 - stw r4, IM_OR0@l(r3) - - /* Calculate absolute address in FLASH and jump there */ - /*--------------------------------------------------------------*/ - - lis r3, CONFIG_SYS_MONITOR_BASE@h - ori r3, r3, CONFIG_SYS_MONITOR_BASE@l - addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET - mtlr r3 - blr - -in_flash: -#endif /* CONFIG_SYS_RAMBOOT */ - - /* initialize some things that are hard to access from C */ - /*--------------------------------------------------------------*/ - - lis r3, CONFIG_SYS_IMMR@h /* set up stack in internal DPRAM */ - ori r1, r3, CONFIG_SYS_INIT_SP_OFFSET - li r0, 0 /* Make room for stack frame header and */ - stwu r0, -4(r1) /* clear final stack frame so that */ - stwu r0, -4(r1) /* stack backtraces terminate cleanly */ - - /* let the C-code set up the rest */ - /* */ - /* Be careful to keep code relocatable ! */ - /*--------------------------------------------------------------*/ - - GET_GOT /* initialize GOT access */ - - /* r3: IMMR */ - bl cpu_init_f /* run low-level CPU init code (in Flash)*/ - -#ifdef DEBUG - bl init_debug /* set up debugging stuff */ -#endif - - mr r3, r21 - /* r3: BOOTFLAG */ - bl board_init_f /* run 1st part of board init code (in Flash)*/ - -/* - * Vector Table - */ - - .globl _start_of_vectors -_start_of_vectors: - -/* Machine check */ - STD_EXCEPTION(0x200, MachineCheck, MachineCheckException) - -/* Data Storage exception. */ - STD_EXCEPTION(0x300, DataStorage, UnknownException) - -/* Instruction Storage exception. */ - STD_EXCEPTION(0x400, InstStorage, UnknownException) - -/* External Interrupt exception. */ - STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt) - -/* Alignment exception. */ - . = 0x600 -Alignment: - EXCEPTION_PROLOG(SRR0, SRR1) - mfspr r4,DAR - stw r4,_DAR(r21) - mfspr r5,DSISR - stw r5,_DSISR(r21) - addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE) - -/* Program check exception */ - . = 0x700 -ProgramCheck: - EXCEPTION_PROLOG(SRR0, SRR1) - addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException, - MSR_KERNEL, COPY_EE) - - STD_EXCEPTION(0x800, FPUnavailable, UnknownException) - - /* I guess we could implement decrementer, and may have - * to someday for timekeeping. - */ - STD_EXCEPTION(0x900, Decrementer, timer_interrupt) - - STD_EXCEPTION(0xa00, Trap_0a, UnknownException) - STD_EXCEPTION(0xb00, Trap_0b, UnknownException) - STD_EXCEPTION(0xc00, SystemCall, UnknownException) - STD_EXCEPTION(0xd00, SingleStep, UnknownException) - - STD_EXCEPTION(0xe00, Trap_0e, UnknownException) - STD_EXCEPTION(0xf00, Trap_0f, UnknownException) - - STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException) - STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException) - STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException) -#ifdef DEBUG - . = 0x1300 - /* - * This exception occurs when the program counter matches the - * Instruction Address Breakpoint Register (IABR). - * - * I want the cpu to halt if this occurs so I can hunt around - * with the debugger and look at things. - * - * When DEBUG is defined, both machine check enable (in the MSR) - * and checkstop reset enable (in the reset mode register) are - * turned off and so a checkstop condition will result in the cpu - * halting. - * - * I force the cpu into a checkstop condition by putting an illegal - * instruction here (at least this is the theory). - * - * well - that didnt work, so just do an infinite loop! - */ -1: b 1b -#else - STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException) -#endif - STD_EXCEPTION(0x1400, SMI, UnknownException) - - STD_EXCEPTION(0x1500, Trap_15, UnknownException) - STD_EXCEPTION(0x1600, Trap_16, UnknownException) - STD_EXCEPTION(0x1700, Trap_17, UnknownException) - STD_EXCEPTION(0x1800, Trap_18, UnknownException) - STD_EXCEPTION(0x1900, Trap_19, UnknownException) - STD_EXCEPTION(0x1a00, Trap_1a, UnknownException) - STD_EXCEPTION(0x1b00, Trap_1b, UnknownException) - STD_EXCEPTION(0x1c00, Trap_1c, UnknownException) - STD_EXCEPTION(0x1d00, Trap_1d, UnknownException) - STD_EXCEPTION(0x1e00, Trap_1e, UnknownException) - STD_EXCEPTION(0x1f00, Trap_1f, UnknownException) - STD_EXCEPTION(0x2000, Trap_20, UnknownException) - STD_EXCEPTION(0x2100, Trap_21, UnknownException) - STD_EXCEPTION(0x2200, Trap_22, UnknownException) - STD_EXCEPTION(0x2300, Trap_23, UnknownException) - STD_EXCEPTION(0x2400, Trap_24, UnknownException) - STD_EXCEPTION(0x2500, Trap_25, UnknownException) - STD_EXCEPTION(0x2600, Trap_26, UnknownException) - STD_EXCEPTION(0x2700, Trap_27, UnknownException) - STD_EXCEPTION(0x2800, Trap_28, UnknownException) - STD_EXCEPTION(0x2900, Trap_29, UnknownException) - STD_EXCEPTION(0x2a00, Trap_2a, UnknownException) - STD_EXCEPTION(0x2b00, Trap_2b, UnknownException) - STD_EXCEPTION(0x2c00, Trap_2c, UnknownException) - STD_EXCEPTION(0x2d00, Trap_2d, UnknownException) - STD_EXCEPTION(0x2e00, Trap_2e, UnknownException) - STD_EXCEPTION(0x2f00, Trap_2f, UnknownException) - - - .globl _end_of_vectors -_end_of_vectors: - - . = 0x3000 - -/* - * This code finishes saving the registers to the exception frame - * and jumps to the appropriate handler for the exception. - * Register r21 is pointer into trap frame, r1 has new stack pointer. - */ - .globl transfer_to_handler -transfer_to_handler: - stw r22,_NIP(r21) - lis r22,MSR_POW@h - andc r23,r23,r22 - stw r23,_MSR(r21) - SAVE_GPR(7, r21) - SAVE_4GPRS(8, r21) - SAVE_8GPRS(12, r21) - SAVE_8GPRS(24, r21) - mflr r23 - andi. r24,r23,0x3f00 /* get vector offset */ - stw r24,TRAP(r21) - li r22,0 - stw r22,RESULT(r21) - lwz r24,0(r23) /* virtual address of handler */ - lwz r23,4(r23) /* where to go when done */ - mtspr SRR0,r24 - mtspr SRR1,r20 - mtlr r23 - SYNC - rfi /* jump to handler, enable MMU */ - -int_return: - mfmsr r28 /* Disable interrupts */ - li r4,0 - ori r4,r4,MSR_EE - andc r28,r28,r4 - SYNC /* Some chip revs need this... */ - mtmsr r28 - SYNC - lwz r2,_CTR(r1) - lwz r0,_LINK(r1) - mtctr r2 - mtlr r0 - lwz r2,_XER(r1) - lwz r0,_CCR(r1) - mtspr XER,r2 - mtcrf 0xFF,r0 - REST_10GPRS(3, r1) - REST_10GPRS(13, r1) - REST_8GPRS(23, r1) - REST_GPR(31, r1) - lwz r2,_NIP(r1) /* Restore environment */ - lwz r0,_MSR(r1) - mtspr SRR0,r2 - mtspr SRR1,r0 - lwz r0,GPR0(r1) - lwz r2,GPR2(r1) - lwz r1,GPR1(r1) - SYNC - rfi - -#if defined(CONFIG_COGENT) - -/* - * This code initialises the MPC8260 processor core - * (conforms to PowerPC 603e spec) - */ - - .globl cogent_init_8260 -cogent_init_8260: - - /* Taken from page 14 of CMA282 manual */ - /*--------------------------------------------------------------*/ - - lis r4, (CONFIG_SYS_IMMR+IM_REGBASE)@h - lis r3, CONFIG_SYS_IMMR@h - stw r3, IM_IMMR@l(r4) - lwz r3, IM_IMMR@l(r4) - stw r3, 0(r0) - lis r3, CONFIG_SYS_SYPCR@h - ori r3, r3, CONFIG_SYS_SYPCR@l - stw r3, IM_SYPCR@l(r4) - lwz r3, IM_SYPCR@l(r4) - stw r3, 4(r0) - lis r3, CONFIG_SYS_SCCR@h - ori r3, r3, CONFIG_SYS_SCCR@l - stw r3, IM_SCCR@l(r4) - lwz r3, IM_SCCR@l(r4) - stw r3, 8(r0) - - /* the rest of this was disassembled from the */ - /* EPROM code that came with my CMA282 CPU module */ - /*--------------------------------------------------------------*/ - - lis r1, 0x1234 - ori r1, r1, 0x5678 - stw r1, 0x20(r0) - lwz r1, 0x20(r0) - stw r1, 0x24(r0) - lwz r1, 0x24(r0) - lis r3, 0x0e80 - ori r3, r3, 0 - stw r1, 4(r3) - lwz r1, 4(r3) - - /* Done! */ - /*--------------------------------------------------------------*/ - - blr - -#endif /* CONFIG_COGENT */ - -/* - * This code initialises the MPC8260 processor core - * (conforms to PowerPC 603e spec) - * Note: expects original MSR contents to be in r5. - */ - - .globl init_8260_core -init_8260_core: - - /* Initialize machine status; enable machine check interrupt */ - /*--------------------------------------------------------------*/ - - li r3, MSR_KERNEL /* Set ME and RI flags */ - rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */ -#ifdef DEBUG - rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */ -#endif - SYNC /* Some chip revs need this... */ - mtmsr r3 - SYNC - mtspr SRR1, r3 /* Make SRR1 match MSR */ - - /* Initialise the SYPCR early, and reset the watchdog (if req) */ - /*--------------------------------------------------------------*/ - - lis r3, (CONFIG_SYS_IMMR+IM_REGBASE)@h -#if !defined(CONFIG_COGENT) - lis r4, CONFIG_SYS_SYPCR@h - ori r4, r4, CONFIG_SYS_SYPCR@l - stw r4, IM_SYPCR@l(r3) -#endif /* !CONFIG_COGENT */ -#if defined(CONFIG_WATCHDOG) - li r4, 21868 /* = 0x556c */ - sth r4, IM_SWSR@l(r3) - li r4, -21959 /* = 0xaa39 */ - sth r4, IM_SWSR@l(r3) -#endif /* CONFIG_WATCHDOG */ - - /* Initialize the Hardware Implementation-dependent Registers */ - /* HID0 also contains cache control */ - /*--------------------------------------------------------------*/ - - lis r3, CONFIG_SYS_HID0_INIT@h - ori r3, r3, CONFIG_SYS_HID0_INIT@l - SYNC - mtspr HID0, r3 - - lis r3, CONFIG_SYS_HID0_FINAL@h - ori r3, r3, CONFIG_SYS_HID0_FINAL@l - SYNC - mtspr HID0, r3 - - lis r3, CONFIG_SYS_HID2@h - ori r3, r3, CONFIG_SYS_HID2@l - mtspr HID2, r3 - - /* clear all BAT's */ - /*--------------------------------------------------------------*/ - - li r0, 0 - mtspr DBAT0U, r0 - mtspr DBAT0L, r0 - mtspr DBAT1U, r0 - mtspr DBAT1L, r0 - mtspr DBAT2U, r0 - mtspr DBAT2L, r0 - mtspr DBAT3U, r0 - mtspr DBAT3L, r0 - mtspr IBAT0U, r0 - mtspr IBAT0L, r0 - mtspr IBAT1U, r0 - mtspr IBAT1L, r0 - mtspr IBAT2U, r0 - mtspr IBAT2L, r0 - mtspr IBAT3U, r0 - mtspr IBAT3L, r0 - SYNC - - /* invalidate all tlb's */ - /* */ - /* From the 603e User Manual: "The 603e provides the ability to */ - /* invalidate a TLB entry. The TLB Invalidate Entry (tlbie) */ - /* instruction invalidates the TLB entry indexed by the EA, and */ - /* operates on both the instruction and data TLBs simultaneously*/ - /* invalidating four TLB entries (both sets in each TLB). The */ - /* index corresponds to bits 15-19 of the EA. To invalidate all */ - /* entries within both TLBs, 32 tlbie instructions should be */ - /* issued, incrementing this field by one each time." */ - /* */ - /* "Note that the tlbia instruction is not implemented on the */ - /* 603e." */ - /* */ - /* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 */ - /* incrementing by 0x1000 each time. The code below is sort of */ - /* based on code in "flush_tlbs" from arch/ppc/kernel/head.S */ - /* */ - /*--------------------------------------------------------------*/ - - li r3, 32 - mtctr r3 - li r3, 0 -1: tlbie r3 - addi r3, r3, 0x1000 - bdnz 1b - SYNC - - /* Done! */ - /*--------------------------------------------------------------*/ - - blr - -#ifdef DEBUG - -/* - * initialise things related to debugging. - * - * must be called after the global offset table (GOT) is initialised - * (GET_GOT) and after cpu_init_f() has executed. - */ - - .globl init_debug -init_debug: - - lis r3, (CONFIG_SYS_IMMR+IM_REGBASE)@h - - /* Quick and dirty hack to enable the RAM and copy the */ - /* vectors so that we can take exceptions. */ - /*--------------------------------------------------------------*/ - /* write Memory Refresh Prescaler */ - li r4, CONFIG_SYS_MPTPR - sth r4, IM_MPTPR@l(r3) - /* write 60x Refresh Timer */ - li r4, CONFIG_SYS_PSRT - stb r4, IM_PSRT@l(r3) - /* init the 60x SDRAM Mode Register */ - lis r4, (CONFIG_SYS_PSDMR|PSDMR_OP_NORM)@h - ori r4, r4, (CONFIG_SYS_PSDMR|PSDMR_OP_NORM)@l - stw r4, IM_PSDMR@l(r3) - /* write Precharge All Banks command */ - lis r4, (CONFIG_SYS_PSDMR|PSDMR_OP_PREA)@h - ori r4, r4, (CONFIG_SYS_PSDMR|PSDMR_OP_PREA)@l - stw r4, IM_PSDMR@l(r3) - stb r0, 0(0) - /* write eight CBR Refresh commands */ - lis r4, (CONFIG_SYS_PSDMR|PSDMR_OP_CBRR)@h - ori r4, r4, (CONFIG_SYS_PSDMR|PSDMR_OP_CBRR)@l - stw r4, IM_PSDMR@l(r3) - stb r0, 0(0) - stb r0, 0(0) - stb r0, 0(0) - stb r0, 0(0) - stb r0, 0(0) - stb r0, 0(0) - stb r0, 0(0) - stb r0, 0(0) - /* write Mode Register Write command */ - lis r4, (CONFIG_SYS_PSDMR|PSDMR_OP_MRW)@h - ori r4, r4, (CONFIG_SYS_PSDMR|PSDMR_OP_MRW)@l - stw r4, IM_PSDMR@l(r3) - stb r0, 0(0) - /* write Normal Operation command and enable Refresh */ - lis r4, (CONFIG_SYS_PSDMR|PSDMR_OP_NORM|PSDMR_RFEN)@h - ori r4, r4, (CONFIG_SYS_PSDMR|PSDMR_OP_NORM|PSDMR_RFEN)@l - stw r4, IM_PSDMR@l(r3) - stb r0, 0(0) - /* RAM should now be operational */ - -#define VEC_WRD_CNT ((_end_of_vectors - _start + EXC_OFF_SYS_RESET) / 4) - mflr r3 - GET_GOT - mtlr r3 - lwz r3, GOT(_end_of_vectors) - rlwinm r4, r3, 0, 18, 31 /* _end_of_vectors & 0x3FFF */ - lis r5, VEC_WRD_CNT@h - ori r5, r5, VEC_WRD_CNT@l - mtctr r5 -1: - lwzu r5, -4(r3) - stwu r5, -4(r4) - bdnz 1b - - /* Load the Instruction Address Breakpoint Register (IABR). */ - /* */ - /* The address to load is stored in the first word of dual port */ - /* ram and should be preserved while the power is on, so you */ - /* can plug addresses into that location then reset the cpu and */ - /* this code will load that address into the IABR after the */ - /* reset. */ - /* */ - /* When the program counter matches the contents of the IABR, */ - /* an exception is generated (before the instruction at that */ - /* location completes). The vector for this exception is 0x1300 */ - /*--------------------------------------------------------------*/ - lis r3, CONFIG_SYS_IMMR@h - lwz r3, 0(r3) - mtspr IABR, r3 - - /* Set the entire dual port RAM (where the initial stack */ - /* resides) to a known value - makes it easier to see where */ - /* the stack has been written */ - /*--------------------------------------------------------------*/ - lis r3, (CONFIG_SYS_IMMR + CONFIG_SYS_INIT_SP_OFFSET)@h - ori r3, r3, (CONFIG_SYS_IMMR + CONFIG_SYS_INIT_SP_OFFSET)@l - li r4, ((CONFIG_SYS_INIT_SP_OFFSET - 4) / 4) - mtctr r4 - lis r4, 0xdeadbeaf@h - ori r4, r4, 0xdeadbeaf@l -1: - stwu r4, -4(r3) - bdnz 1b - - /* Done! */ - /*--------------------------------------------------------------*/ - - blr -#endif - -/* Cache functions. - * - * Note: requires that all cache bits in - * HID0 are in the low half word. - */ - .globl icache_enable -icache_enable: - mfspr r3, HID0 - ori r3, r3, HID0_ICE - lis r4, 0 - ori r4, r4, HID0_ILOCK - andc r3, r3, r4 - ori r4, r3, HID0_ICFI - isync - mtspr HID0, r4 /* sets enable and invalidate, clears lock */ - isync - mtspr HID0, r3 /* clears invalidate */ - blr - - .globl icache_disable -icache_disable: - mfspr r3, HID0 - lis r4, 0 - ori r4, r4, HID0_ICE|HID0_ILOCK - andc r3, r3, r4 - ori r4, r3, HID0_ICFI - isync - mtspr HID0, r4 /* sets invalidate, clears enable and lock */ - isync - mtspr HID0, r3 /* clears invalidate */ - blr - - .globl icache_status -icache_status: - mfspr r3, HID0 - rlwinm r3, r3, HID0_ICE_BITPOS + 1, 31, 31 - blr - - .globl dcache_enable -dcache_enable: - mfspr r3, HID0 - ori r3, r3, HID0_DCE - lis r4, 0 - ori r4, r4, HID0_DLOCK - andc r3, r3, r4 - ori r4, r3, HID0_DCI - sync - mtspr HID0, r4 /* sets enable and invalidate, clears lock */ - sync - mtspr HID0, r3 /* clears invalidate */ - blr - - .globl dcache_disable -dcache_disable: - mfspr r3, HID0 - lis r4, 0 - ori r4, r4, HID0_DCE|HID0_DLOCK - andc r3, r3, r4 - ori r4, r3, HID0_DCI - sync - mtspr HID0, r4 /* sets invalidate, clears enable and lock */ - sync - mtspr HID0, r3 /* clears invalidate */ - blr - - .globl dcache_status -dcache_status: - mfspr r3, HID0 - rlwinm r3, r3, HID0_DCE_BITPOS + 1, 31, 31 - blr - - .globl get_pvr -get_pvr: - mfspr r3, PVR - blr - -/*------------------------------------------------------------------------------*/ - -/* - * void relocate_code (addr_sp, gd, addr_moni) - * - * This "function" does not return, instead it continues in RAM - * after relocating the monitor code. - * - * r3 = dest - * r4 = src - * r5 = length in bytes - * r6 = cachelinesize - */ - .globl relocate_code -relocate_code: - mr r1, r3 /* Set new stack pointer */ - mr r9, r4 /* Save copy of Global Data pointer */ - mr r10, r5 /* Save copy of Destination Address */ - - GET_GOT - mr r3, r5 /* Destination Address */ - lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */ - ori r4, r4, CONFIG_SYS_MONITOR_BASE@l - lwz r5, GOT(__init_end) - sub r5, r5, r4 - li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */ - - /* - * Fix GOT pointer: - * - * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address - * - * Offset: - */ - sub r15, r10, r4 - - /* First our own GOT */ - add r12, r12, r15 - /* then the one used by the C code */ - add r30, r30, r15 - - /* - * Now relocate code - */ - - cmplw cr1,r3,r4 - addi r0,r5,3 - srwi. r0,r0,2 - beq cr1,4f /* In place copy is not necessary */ - beq 7f /* Protect against 0 count */ - mtctr r0 - bge cr1,2f - - la r8,-4(r4) - la r7,-4(r3) -1: lwzu r0,4(r8) - stwu r0,4(r7) - bdnz 1b - b 4f - -2: slwi r0,r0,2 - add r8,r4,r0 - add r7,r3,r0 -3: lwzu r0,-4(r8) - stwu r0,-4(r7) - bdnz 3b - -/* - * Now flush the cache: note that we must start from a cache aligned - * address. Otherwise we might miss one cache line. - */ -4: cmpwi r6,0 - add r5,r3,r5 - beq 7f /* Always flush prefetch queue in any case */ - subi r0,r6,1 - andc r3,r3,r0 - mfspr r7,HID0 /* don't do dcbst if dcache is disabled */ - rlwinm r7,r7,HID0_DCE_BITPOS+1,31,31 - cmpwi r7,0 - beq 9f - mr r4,r3 -5: dcbst 0,r4 - add r4,r4,r6 - cmplw r4,r5 - blt 5b - sync /* Wait for all dcbst to complete on bus */ -9: mfspr r7,HID0 /* don't do icbi if icache is disabled */ - rlwinm r7,r7,HID0_ICE_BITPOS+1,31,31 - cmpwi r7,0 - beq 7f - mr r4,r3 -6: icbi 0,r4 - add r4,r4,r6 - cmplw r4,r5 - blt 6b -7: sync /* Wait for all icbi to complete on bus */ - isync - -/* - * We are done. Do not return, instead branch to second part of board - * initialization, now running from RAM. - */ - - addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET - mtlr r0 - blr - -in_ram: - - /* - * Relocation Function, r12 point to got2+0x8000 - * - * Adjust got2 pointers, no need to check for 0, this code - * already puts a few entries in the table. - */ - li r0,__got2_entries@sectoff@l - la r3,GOT(_GOT2_TABLE_) - lwz r11,GOT(_GOT2_TABLE_) - mtctr r0 - sub r11,r3,r11 - addi r3,r3,-4 -1: lwzu r0,4(r3) - cmpwi r0,0 - beq- 2f - add r0,r0,r11 - stw r0,0(r3) -2: bdnz 1b - - /* - * Now adjust the fixups and the pointers to the fixups - * in case we need to move ourselves again. - */ - li r0,__fixup_entries@sectoff@l - lwz r3,GOT(_FIXUP_TABLE_) - cmpwi r0,0 - mtctr r0 - addi r3,r3,-4 - beq 4f -3: lwzu r4,4(r3) - lwzux r0,r4,r11 - add r0,r0,r11 - stw r10,0(r3) - stw r0,0(r4) - bdnz 3b -4: -clear_bss: - /* - * Now clear BSS segment - */ - lwz r3,GOT(__bss_start) -#if defined(CONFIG_HYMOD) - /* - * For HYMOD - the environment is the very last item in flash. - * The real .bss stops just before environment starts, so only - * clear up to that point. - * - * taken from mods for FADS board - */ - lwz r4,GOT(environment) -#else - lwz r4,GOT(_end) -#endif - - cmplw 0, r3, r4 - beq 6f - - li r0, 0 -5: - stw r0, 0(r3) - addi r3, r3, 4 - cmplw 0, r3, r4 - bne 5b -6: - - mr r3, r9 /* Global Data pointer */ - mr r4, r10 /* Destination Address */ - bl board_init_r - - /* - * Copy exception vector code to low memory - * - * r3: dest_addr - * r7: source address, r8: end address, r9: target address - */ - .globl trap_init -trap_init: - mflr r4 /* save link register */ - GET_GOT - lwz r7, GOT(_start) - lwz r8, GOT(_end_of_vectors) - - li r9, 0x100 /* reset vector always at 0x100 */ - - cmplw 0, r7, r8 - bgelr /* return if r7>=r8 - just in case */ -1: - lwz r0, 0(r7) - stw r0, 0(r9) - addi r7, r7, 4 - addi r9, r9, 4 - cmplw 0, r7, r8 - bne 1b - - /* - * relocate `hdlr' and `int_return' entries - */ - li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET - li r8, Alignment - _start + EXC_OFF_SYS_RESET -2: - bl trap_reloc - addi r7, r7, 0x100 /* next exception vector */ - cmplw 0, r7, r8 - blt 2b - - li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET - bl trap_reloc - - li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET - bl trap_reloc - - li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET - li r8, SystemCall - _start + EXC_OFF_SYS_RESET -3: - bl trap_reloc - addi r7, r7, 0x100 /* next exception vector */ - cmplw 0, r7, r8 - blt 3b - - li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET - li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET -4: - bl trap_reloc - addi r7, r7, 0x100 /* next exception vector */ - cmplw 0, r7, r8 - blt 4b - - mfmsr r3 /* now that the vectors have */ - lis r7, MSR_IP@h /* relocated into low memory */ - ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */ - andc r3, r3, r7 /* (if it was on) */ - SYNC /* Some chip revs need this... */ - mtmsr r3 - SYNC - - mtlr r4 /* restore link register */ - blr diff --git a/cpu/mpc8260/traps.c b/cpu/mpc8260/traps.c deleted file mode 100644 index d216f71..0000000 --- a/cpu/mpc8260/traps.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * linux/arch/ppc/kernel/traps.c - * - * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * - * Modified by Cort Dougan (cort@cs.nmt.edu) - * and Paul Mackerras (paulus@cs.anu.edu.au) - * - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * This file handles the architecture-dependent parts of hardware exceptions - */ - -#include <common.h> -#include <command.h> -#include <kgdb.h> -#include <asm/processor.h> -#include <asm/m8260_pci.h> - -/* Returns 0 if exception not found and fixup otherwise. */ -extern unsigned long search_exception_table(unsigned long); - -/* THIS NEEDS CHANGING to use the board info structure. -*/ -#define END_OF_MEM 0x02000000 - -/* - * Trap & Exception support - */ - -void -print_backtrace(unsigned long *sp) -{ - int cnt = 0; - unsigned long i; - - puts ("Call backtrace: "); - while (sp) { - if ((uint)sp > END_OF_MEM) - break; - - i = sp[1]; - if (cnt++ % 7 == 0) - putc ('\n'); - printf("%08lX ", i); - if (cnt > 32) break; - sp = (unsigned long *)*sp; - } - putc ('\n'); -} - -void show_regs(struct pt_regs * regs) -{ - int i; - - printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n", - regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar); - printf("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n", - regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0, - regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0, - regs->msr&MSR_IR ? 1 : 0, - regs->msr&MSR_DR ? 1 : 0); - - putc ('\n'); - for (i = 0; i < 32; i++) { - if ((i % 8) == 0) { - printf("GPR%02d: ", i); - } - - printf("%08lX ", regs->gpr[i]); - if ((i % 8) == 7) { - putc ('\n'); - } - } -} - - -void -_exception(int signr, struct pt_regs *regs) -{ - show_regs(regs); - print_backtrace((unsigned long *)regs->gpr[1]); - panic("Exception in kernel pc %lx signal %d",regs->nip,signr); -} - -#ifdef CONFIG_PCI -void dump_pci (void) -{ - - volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; - - printf ("PCI: err status %x err mask %x err ctrl %x\n", - le32_to_cpu (immap->im_pci.pci_esr), - le32_to_cpu (immap->im_pci.pci_emr), - le32_to_cpu (immap->im_pci.pci_ecr)); - printf (" error address %x error data %x ctrl %x\n", - le32_to_cpu (immap->im_pci.pci_eacr), - le32_to_cpu (immap->im_pci.pci_edcr), - le32_to_cpu (immap->im_pci.pci_eccr)); - -} -#endif - -void -MachineCheckException(struct pt_regs *regs) -{ - unsigned long fixup; - - /* Probing PCI using config cycles cause this exception - * when a device is not present. Catch it and return to - * the PCI exception handler. - */ -#ifdef CONFIG_PCI - volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; -#ifdef DEBUG - dump_pci(); -#endif - /* clear the error in the error status register */ - if(immap->im_pci.pci_esr & cpu_to_le32(PCI_ERROR_PCI_NO_RSP)) { - immap->im_pci.pci_esr = cpu_to_le32(PCI_ERROR_PCI_NO_RSP); - return; - } -#endif - if ((fixup = search_exception_table(regs->nip)) != 0) { - regs->nip = fixup; - return; - } - -#if defined(CONFIG_CMD_KGDB) - if (debugger_exception_handler && (*debugger_exception_handler)(regs)) - return; -#endif - - puts ("Machine check in kernel mode.\n" - "Caused by (from msr): "); - printf("regs %p ",regs); - switch( regs->msr & 0x000F0000) { - case (0x80000000>>12): - puts ("Machine check signal - probably due to mm fault\n" - "with mmu off\n"); - break; - case (0x80000000>>13): - puts ("Transfer error ack signal\n"); - break; - case (0x80000000>>14): - puts ("Data parity signal\n"); - break; - case (0x80000000>>15): - puts ("Address parity signal\n"); - break; - default: - puts ("Unknown values in msr\n"); - } - show_regs(regs); - print_backtrace((unsigned long *)regs->gpr[1]); -#ifdef CONFIG_PCI - dump_pci(); -#endif - panic("machine check"); -} - -void -AlignmentException(struct pt_regs *regs) -{ -#if defined(CONFIG_CMD_KGDB) - if (debugger_exception_handler && (*debugger_exception_handler)(regs)) - return; -#endif - show_regs(regs); - print_backtrace((unsigned long *)regs->gpr[1]); - panic("Alignment Exception"); -} - -void -ProgramCheckException(struct pt_regs *regs) -{ -#if defined(CONFIG_CMD_KGDB) - if (debugger_exception_handler && (*debugger_exception_handler)(regs)) - return; -#endif - show_regs(regs); - print_backtrace((unsigned long *)regs->gpr[1]); - panic("Program Check Exception"); -} - -void -SoftEmuException(struct pt_regs *regs) -{ -#if defined(CONFIG_CMD_KGDB) - if (debugger_exception_handler && (*debugger_exception_handler)(regs)) - return; -#endif - show_regs(regs); - print_backtrace((unsigned long *)regs->gpr[1]); - panic("Software Emulation Exception"); -} - - -void -UnknownException(struct pt_regs *regs) -{ -#if defined(CONFIG_CMD_KGDB) - if (debugger_exception_handler && (*debugger_exception_handler)(regs)) - return; -#endif - printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", - regs->nip, regs->msr, regs->trap); - _exception(0, regs); -} - -#if defined(CONFIG_CMD_BEDBUG) -extern void do_bedbug_breakpoint(struct pt_regs *); -#endif - -void -DebugException(struct pt_regs *regs) -{ - - printf("Debugger trap at @ %lx\n", regs->nip ); - show_regs(regs); -#if defined(CONFIG_CMD_BEDBUG) - do_bedbug_breakpoint( regs ); -#endif -} - -/* Probe an address by reading. If not present, return -1, otherwise - * return 0. - */ -int -addr_probe(uint *addr) -{ -#if 0 - int retval; - - __asm__ __volatile__( \ - "1: lwz %0,0(%1)\n" \ - " eieio\n" \ - " li %0,0\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3: li %0,-1\n" \ - " b 2b\n" \ - ".section __ex_table,\"a\"\n" \ - " .align 2\n" \ - " .long 1b,3b\n" \ - ".text" \ - : "=r" (retval) : "r"(addr)); - - return (retval); -#endif - return 0; -} diff --git a/cpu/mpc8260/u-boot.lds b/cpu/mpc8260/u-boot.lds deleted file mode 100644 index c777cf9..0000000 --- a/cpu/mpc8260/u-boot.lds +++ /dev/null @@ -1,122 +0,0 @@ -/* - * (C) Copyright 2001-2007 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_ARCH(powerpc) -/* Do we need any of these for elf? - __DYNAMIC = 0; */ -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = + SIZEOF_HEADERS; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .rel.text : { *(.rel.text) } - .rela.text : { *(.rela.text) } - .rel.data : { *(.rel.data) } - .rela.data : { *(.rela.data) } - .rel.rodata : { *(.rel.rodata) } - .rela.rodata : { *(.rela.rodata) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.ctors : { *(.rel.ctors) } - .rela.ctors : { *(.rela.ctors) } - .rel.dtors : { *(.rel.dtors) } - .rela.dtors : { *(.rela.dtors) } - .rel.bss : { *(.rel.bss) } - .rela.bss : { *(.rela.bss) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } - .init : { *(.init) } - .plt : { *(.plt) } - .text : - { - cpu/mpc8260/start.o (.text) - *(.text) - *(.got1) - . = ALIGN(16); - *(.eh_frame) - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - .fini : { *(.fini) } =0 - .ctors : { *(.ctors) } - .dtors : { *(.dtors) } - - /* Read-write section, merged into data segment: */ - . = (. + 0x0FFF) & 0xFFFFF000; - _erotext = .; - PROVIDE (erotext = .); - .reloc : - { - *(.got) - _GOT2_TABLE_ = .; - *(.got2) - _FIXUP_TABLE_ = .; - *(.fixup) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; - __fixup_entries = (. - _FIXUP_TABLE_) >> 2; - - .data : - { - *(.data) - *(.data1) - *(.sdata) - *(.sdata2) - *(.dynamic) - CONSTRUCTORS - } - _edata = .; - PROVIDE (edata = .); - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(4096); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(4096); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - *(.sbss) *(.scommon) - *(.dynbss) - *(.bss) - *(COMMON) - . = ALIGN(4); - } - _end = . ; - PROVIDE (end = .); -} |