
This reverts commit 2eb48ff7a210ddd2a39bac23b3b9b39c60c32aef.
Signed-off-by: Christophe Leroy christophe.leroy@c-s.fr --- .travis.yml | 2 + README | 73 +- api/api_platform-powerpc.c | 2 +- arch/powerpc/Kconfig | 6 + arch/powerpc/cpu/mpc8260/Kconfig | 20 + arch/powerpc/cpu/mpc8260/Makefile | 13 + arch/powerpc/cpu/mpc8260/bedbug_603e.c | 236 ++++++ arch/powerpc/cpu/mpc8260/commproc.c | 174 +++++ arch/powerpc/cpu/mpc8260/config.mk | 9 + arch/powerpc/cpu/mpc8260/cpu.c | 323 ++++++++ arch/powerpc/cpu/mpc8260/cpu_init.c | 272 +++++++ arch/powerpc/cpu/mpc8260/ether_fcc.c | 1155 ++++++++++++++++++++++++++++ arch/powerpc/cpu/mpc8260/ether_scc.c | 367 +++++++++ arch/powerpc/cpu/mpc8260/interrupts.c | 255 ++++++ arch/powerpc/cpu/mpc8260/kgdb.S | 52 ++ arch/powerpc/cpu/mpc8260/pci.c | 382 +++++++++ arch/powerpc/cpu/mpc8260/serial_scc.c | 492 ++++++++++++ arch/powerpc/cpu/mpc8260/serial_smc.c | 461 +++++++++++ arch/powerpc/cpu/mpc8260/speed.c | 228 ++++++ arch/powerpc/cpu/mpc8260/spi.c | 408 ++++++++++ arch/powerpc/cpu/mpc8260/start.S | 901 ++++++++++++++++++++++ arch/powerpc/cpu/mpc8260/traps.c | 248 ++++++ arch/powerpc/cpu/mpc8260/u-boot.lds | 74 ++ arch/powerpc/cpu/mpc83xx/start.S | 2 +- arch/powerpc/include/asm/cpm_8260.h | 795 +++++++++++++++++++ arch/powerpc/include/asm/immap_8260.h | 604 +++++++++++++++ arch/powerpc/include/asm/iopin_8260.h | 168 ++++ arch/powerpc/include/asm/m8260_pci.h | 165 ++++ arch/powerpc/include/asm/ppc.h | 5 + arch/powerpc/include/asm/processor.h | 3 + arch/powerpc/include/asm/status_led.h | 4 +- arch/powerpc/lib/Kconfig | 8 + arch/powerpc/lib/Makefile | 1 + arch/powerpc/lib/immap.c | 629 +++++++++++++++ arch/powerpc/lib/kgdb.c | 52 ++ board/keymile/km82xx/Kconfig | 12 + board/keymile/km82xx/MAINTAINERS | 7 + board/keymile/km82xx/Makefile | 8 + board/keymile/km82xx/km82xx.c | 463 +++++++++++ cmd/bdinfo.c | 2 +- cmd/bedbug.c | 7 + common/board_f.c | 2 +- common/lynxkdi.c | 2 +- configs/mgcoge3ne_defconfig | 25 + configs/mgcoge_defconfig | 25 + doc/README.idma2intr | 10 + drivers/bootcount/bootcount.c | 5 + drivers/i2c/soft_i2c.c | 9 + drivers/pci/pci_indirect.c | 17 +- drivers/usb/gadget/gadget_chips.h | 9 + examples/standalone/Makefile | 1 + examples/standalone/mem_to_mem_idma2intr.c | 379 +++++++++ include/asm-generic/u-boot.h | 2 +- include/configs/km82xx.h | 427 ++++++++++ include/i2c.h | 4 +- include/mpc8260.h | 903 ++++++++++++++++++++++ include/mpc8260_irq.h | 48 ++ include/post.h | 4 + include/ppc_asm.tmpl | 26 +- post/drivers/memory.c | 7 + scripts/config_whitelist.txt | 75 ++ 61 files changed, 11051 insertions(+), 17 deletions(-) create mode 100644 arch/powerpc/cpu/mpc8260/Kconfig create mode 100644 arch/powerpc/cpu/mpc8260/Makefile create mode 100644 arch/powerpc/cpu/mpc8260/bedbug_603e.c create mode 100644 arch/powerpc/cpu/mpc8260/commproc.c create mode 100644 arch/powerpc/cpu/mpc8260/config.mk create mode 100644 arch/powerpc/cpu/mpc8260/cpu.c create mode 100644 arch/powerpc/cpu/mpc8260/cpu_init.c create mode 100644 arch/powerpc/cpu/mpc8260/ether_fcc.c create mode 100644 arch/powerpc/cpu/mpc8260/ether_scc.c create mode 100644 arch/powerpc/cpu/mpc8260/interrupts.c create mode 100644 arch/powerpc/cpu/mpc8260/kgdb.S create mode 100644 arch/powerpc/cpu/mpc8260/pci.c create mode 100644 arch/powerpc/cpu/mpc8260/serial_scc.c create mode 100644 arch/powerpc/cpu/mpc8260/serial_smc.c create mode 100644 arch/powerpc/cpu/mpc8260/speed.c create mode 100644 arch/powerpc/cpu/mpc8260/spi.c create mode 100644 arch/powerpc/cpu/mpc8260/start.S create mode 100644 arch/powerpc/cpu/mpc8260/traps.c create mode 100644 arch/powerpc/cpu/mpc8260/u-boot.lds create mode 100644 arch/powerpc/include/asm/cpm_8260.h create mode 100644 arch/powerpc/include/asm/immap_8260.h create mode 100644 arch/powerpc/include/asm/iopin_8260.h create mode 100644 arch/powerpc/include/asm/m8260_pci.h create mode 100644 arch/powerpc/lib/Kconfig create mode 100644 arch/powerpc/lib/immap.c create mode 100644 board/keymile/km82xx/Kconfig create mode 100644 board/keymile/km82xx/MAINTAINERS create mode 100644 board/keymile/km82xx/Makefile create mode 100644 board/keymile/km82xx/km82xx.c create mode 100644 configs/mgcoge3ne_defconfig create mode 100644 configs/mgcoge_defconfig create mode 100644 doc/README.idma2intr create mode 100644 examples/standalone/mem_to_mem_idma2intr.c create mode 100644 include/configs/km82xx.h create mode 100644 include/mpc8260.h create mode 100644 include/mpc8260_irq.h
diff --git a/.travis.yml b/.travis.yml index 3105a6fc73..891528472e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -200,6 +200,8 @@ matrix: - env: - BUILDMAN="mpc5xxx" - env: + - BUILDMAN="mpc8260" + - env: - BUILDMAN="mpc83xx" - env: - BUILDMAN="mpc85xx -x freescale" diff --git a/README b/README index 99ee448a5e..4819696deb 100644 --- a/README +++ b/README @@ -700,6 +700,14 @@ The following options need to be configured: Select one of the baudrates listed in CONFIG_SYS_BAUDRATE_TABLE, see below.
+- Console Rx buffer length + With CONFIG_SYS_SMC_RXBUFLEN it is possible to define + the maximum receive buffer length for the SMC. + This option is actual only for 82xx possible. + If using CONFIG_SYS_SMC_RXBUFLEN also CONFIG_SYS_MAXIDLE + must be defined, to setup the maximum idle timeout for + the SMC. + - Autoboot Command: CONFIG_BOOTCOMMAND Only needed when CONFIG_BOOTDELAY is enabled; @@ -929,9 +937,11 @@ The following options need to be configured: CONFIG_WATCHDOG If this variable is defined, it enables watchdog support for the SoC. There must be support in the SoC - specific code for a watchdog. When supported for a - specific SoC is available, then no further board specific - code should be needed to use it. + specific code for a watchdog. For the 8260 + CPUs, the SIU Watchdog feature is enabled in the SYPCR + register. When supported for a specific SoC is + available, then no further board specific code should + be needed to use it.
CONFIG_HW_WATCHDOG When using a watchdog circuitry external to the used @@ -2098,6 +2108,12 @@ The following options need to be configured:
eg: #define I2C_INIT (immr->im_cpm.cp_pbdir |= PB_SCL)
+ I2C_PORT + + (Only for MPC8260 CPU). The I/O port to use (the code + assumes both bits are on the same port). Valid values + are 0..3 for ports A..D. + I2C_ACTIVE
The code necessary to make the I2C data line active @@ -2386,7 +2402,7 @@ The following options need to be configured:
IVMS8, IVML24, SPD8xx, HERMES, IP860, RPXlite, LWMON, - FLAGADM + FLAGADM, TQM8260
- Access to physical memory region (> 4GB) Some basic support is provided for operations on memory not @@ -3844,6 +3860,16 @@ but it can not erase, write this NOR flash by SRIO or PCIE interface. set. If this value is set, it must be set to the same value as CONFIG_ENV_SIZE.
+- CONFIG_SYS_SPI_INIT_OFFSET + + Defines offset to the initial SPI buffer area in DPRAM. The + area is used at an early stage (ROM part) if the environment + is configured to reside in the SPI EEPROM: We need a 520 byte + scratch DPRAM area. It is used between the two initialization + calls (spi_init_f() and spi_init_r()). A value of 0xB00 seems + to be a good choice since it makes it far enough from the + start of the data area as well as from the stack pointer. + Please note that the environment is read-only until the monitor has been relocated to RAM and a RAM copy of the environment has been created; also, when using EEPROM you will have to use getenv_f() @@ -3897,6 +3923,13 @@ Low Level (hardware related) configuration options: - CONFIG_SYS_CACHELINE_SIZE: Cache Line Size of the CPU.
+- CONFIG_SYS_DEFAULT_IMMR: + Default address of the IMMR after system reset. + + Needed on some 8260 systems (MPC8260ADS, PQ2FADS-ZU, + and RPXsuper) to be able to adjust the position of + the IMMR register after a reset. + - CONFIG_SYS_CCSRBAR_DEFAULT: Default (power-on reset) physical address of CCSR on Freescale PowerPC SOCs. @@ -3905,6 +3938,9 @@ Low Level (hardware related) configuration options: Virtual address of CCSR. On a 32-bit build, this is typically the same value as CONFIG_SYS_CCSRBAR_DEFAULT.
+ CONFIG_SYS_DEFAULT_IMMR must also be set to this value, + for cross-platform code that uses that macro instead. + - CONFIG_SYS_CCSRBAR_PHYS: Physical address of CCSR. CCSR can be relocated to a new physical address, if desired. In this case, this macro should @@ -3980,6 +4016,8 @@ Low Level (hardware related) configuration options: sequences.
U-Boot uses the following memory types: + - MPC8260: IMMR (internal memory of the CPU) + - MPC824X: data cache - PPC4xx: data cache
- CONFIG_SYS_GBL_DATA_OFFSET: @@ -4031,6 +4069,27 @@ Low Level (hardware related) configuration options: CONFIG_SYS_OR3_PRELIM, CONFIG_SYS_BR3_PRELIM: Memory Controller Definitions: BR2/3 and OR2/3 (SDRAM)
+- CONFIG_SYS_MAMR_PTA, CONFIG_SYS_MPTPR_2BK_4K, CONFIG_SYS_MPTPR_1BK_4K, CONFIG_SYS_MPTPR_2BK_8K, + CONFIG_SYS_MPTPR_1BK_8K, CONFIG_SYS_MAMR_8COL, CONFIG_SYS_MAMR_9COL: + Machine Mode Register and Memory Periodic Timer + Prescaler definitions (SDRAM timing) + +- CONFIG_SYS_CPM_POST_WORD_ADDR: (MPC8260 only) + Offset of the bootmode word in DPRAM used by post + (Power On Self Tests). This definition overrides + #define'd default value in commproc.h resp. + cpm_8260.h. + +- CONFIG_SYS_PCI_SLV_MEM_LOCAL, CONFIG_SYS_PCI_SLV_MEM_BUS, CONFIG_SYS_PICMR0_MASK_ATTRIB, + CONFIG_SYS_PCI_MSTR0_LOCAL, CONFIG_SYS_PCIMSK0_MASK, CONFIG_SYS_PCI_MSTR1_LOCAL, + CONFIG_SYS_PCIMSK1_MASK, CONFIG_SYS_PCI_MSTR_MEM_LOCAL, CONFIG_SYS_PCI_MSTR_MEM_BUS, + CONFIG_SYS_CPU_PCI_MEM_START, CONFIG_SYS_PCI_MSTR_MEM_SIZE, CONFIG_SYS_POCMR0_MASK_ATTRIB, + CONFIG_SYS_PCI_MSTR_MEMIO_LOCAL, CONFIG_SYS_PCI_MSTR_MEMIO_BUS, CPU_PCI_MEMIO_START, + CONFIG_SYS_PCI_MSTR_MEMIO_SIZE, CONFIG_SYS_POCMR1_MASK_ATTRIB, CONFIG_SYS_PCI_MSTR_IO_LOCAL, + CONFIG_SYS_PCI_MSTR_IO_BUS, CONFIG_SYS_CPU_PCI_IO_START, CONFIG_SYS_PCI_MSTR_IO_SIZE, + CONFIG_SYS_POCMR2_MASK_ATTRIB: (MPC826x only) + Overrides the default PCI memory map in arch/powerpc/cpu/mpc8260/pci.c if set. + - CONFIG_PCI_DISABLE_PCIE: Disable PCI-Express on systems where it is supported but not required. @@ -5651,9 +5710,9 @@ configuration for CS0# this is a mirror of the on board Flash memory. To be able to re-map memory U-Boot then jumps to its link address. To be able to implement the initialization code in C, a (small!) initial stack is set up in the internal Dual Ported RAM (in case CPUs -which provide such a feature like), or in a locked part of the data -cache. After that, U-Boot initializes the CPU core, the caches and -the SIU. +which provide such a feature like MPC8xx or MPC8260), or in a locked +part of the data cache. After that, U-Boot initializes the CPU core, +the caches and the SIU.
Next, all (potentially) available memory banks are mapped using a preliminary mapping. For example, we put them on 512 MB boundaries diff --git a/api/api_platform-powerpc.c b/api/api_platform-powerpc.c index 307a5f5bc4..71fea5a75a 100644 --- a/api/api_platform-powerpc.c +++ b/api/api_platform-powerpc.c @@ -30,7 +30,7 @@ int platform_sys_info(struct sys_info *si) si->clk_bus = gd->bus_clk; si->clk_cpu = gd->cpu_clk;
-#if defined(CONFIG_5xx) || \ +#if defined(CONFIG_5xx) || defined(CONFIG_MPC8260) || \ defined(CONFIG_E500) || defined(CONFIG_MPC86xx) #define bi_bar bi_immr_base #elif defined(CONFIG_MPC5xxx) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 75594c6a99..671d2cc0cf 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -17,6 +17,9 @@ config 5xx config MPC5xxx bool "MPC5xxx"
+config MPC8260 + bool "MPC8260" + config MPC83xx bool "MPC83xx" select CREATE_ARCH_SYMLINK @@ -45,9 +48,12 @@ config 4xx
endchoice
+source "arch/powerpc/lib/Kconfig" + source "arch/powerpc/cpu/mpc512x/Kconfig" source "arch/powerpc/cpu/mpc5xx/Kconfig" source "arch/powerpc/cpu/mpc5xxx/Kconfig" +source "arch/powerpc/cpu/mpc8260/Kconfig" source "arch/powerpc/cpu/mpc83xx/Kconfig" source "arch/powerpc/cpu/mpc85xx/Kconfig" source "arch/powerpc/cpu/mpc86xx/Kconfig" diff --git a/arch/powerpc/cpu/mpc8260/Kconfig b/arch/powerpc/cpu/mpc8260/Kconfig new file mode 100644 index 0000000000..47bae55b9d --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/Kconfig @@ -0,0 +1,20 @@ +menu "mpc8260 CPU" + depends on MPC8260 + +config SYS_CPU + default "mpc8260" + +choice + prompt "Target select" + optional + +config TARGET_KM82XX + bool "Support km82xx" + imply CMD_CRAMFS + imply FS_CRAMFS + +endchoice + +source "board/keymile/km82xx/Kconfig" + +endmenu diff --git a/arch/powerpc/cpu/mpc8260/Makefile b/arch/powerpc/cpu/mpc8260/Makefile new file mode 100644 index 0000000000..72dd8aba25 --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/Makefile @@ -0,0 +1,13 @@ +# +# (C) Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +extra-y = start.o +obj-y = traps.o serial_smc.o serial_scc.o cpu.o cpu_init.o speed.o \ + interrupts.o ether_fcc.o commproc.o \ + bedbug_603e.o pci.o spi.o kgdb.o + +obj-$(CONFIG_ETHER_ON_SCC) += ether_scc.o diff --git a/arch/powerpc/cpu/mpc8260/bedbug_603e.c b/arch/powerpc/cpu/mpc8260/bedbug_603e.c new file mode 100644 index 0000000000..92f89578b0 --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/bedbug_603e.c @@ -0,0 +1,236 @@ +/* + * 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*const[])); +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 * const 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/arch/powerpc/cpu/mpc8260/commproc.c b/arch/powerpc/cpu/mpc8260/commproc.c new file mode 100644 index 0000000000..ff69881089 --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/commproc.c @@ -0,0 +1,174 @@ +/* + * This file is based on "arch/powerpc/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->arch.dp_alloc_base = CPM_DATAONLY_BASE; + gd->arch.dp_alloc_top = gd->arch.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); +} + +/* 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->arch.dp_alloc_base; + + off = gd->arch.dp_alloc_base & align_mask; + if (off != 0) + gd->arch.dp_alloc_base += (align - off); + + if ((off = size & align_mask) != 0) + size += align - off; + + if ((gd->arch.dp_alloc_base + size) >= gd->arch.dp_alloc_top) { + gd->arch.dp_alloc_base = savebase; + panic("m8260_cpm_dpalloc: ran out of dual port ram!"); + } + + retloc = gd->arch.dp_alloc_base; + gd->arch.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->arch.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; +} diff --git a/arch/powerpc/cpu/mpc8260/config.mk b/arch/powerpc/cpu/mpc8260/config.mk new file mode 100644 index 0000000000..6a1b6e3eb4 --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/config.mk @@ -0,0 +1,9 @@ +# +# (C) Copyright 2000-2010 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +PLATFORM_CPPFLAGS += -DCONFIG_CPM2 \ + -mstring -mcpu=603e -mmultiple diff --git a/arch/powerpc/cpu/mpc8260/cpu.c b/arch/powerpc/cpu/mpc8260/cpu.c new file mode 100644 index 0000000000..7302b37f20 --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/cpu.c @@ -0,0 +1,323 @@ +/* + * (C) Copyright 2000-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * 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 <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]; + int ret; + + ret = prt_8260_rsr(); + if (ret) + return ret; + ret = prt_8260_clks(); + if (ret) + return ret; + 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 = immap->im_dprambase16[PROFF_REVNUM / sizeof(u16)]; + + 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 * const 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 */ + +/* ------------------------------------------------------------------------- */ +#ifdef CONFIG_OF_BOARD_SETUP +void ft_cpu_setup (void *blob, bd_t *bd) +{ + 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_BOARD_SETUP */ + +/* + * 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/arch/powerpc/cpu/mpc8260/cpu_init.c b/arch/powerpc/cpu/mpc8260/cpu_init.c new file mode 100644 index 0000000000..55130f7831 --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/cpu_init.c @@ -0,0 +1,272 @@ +/* + * (C) Copyright 2000-2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#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) +{ + uint sccr; +#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->arch.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; + + /* 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) ); + + /* + * 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 = ARRAY_SIZE(bits); + ulong rsr = gd->arch.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/arch/powerpc/cpu/mpc8260/ether_fcc.c b/arch/powerpc/cpu/mpc8260/ether_fcc.c new file mode 100644 index 0000000000..072eb76150 --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/ether_fcc.c @@ -0,0 +1,1155 @@ +/* + * 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 + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * 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 <console.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) + +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, 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. */ + net_process_received_packet(net_rx_packets[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)net_rx_packets[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_ethaddr() + 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 < ARRAY_SIZE(ether_fcc_info); i++) + { + dev = (struct eth_device*) malloc(sizeof *dev); + memset(dev, 0, sizeof *dev); + + sprintf(dev->name, "FCC%d", + 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) + int retval; + struct mii_dev *mdiodev = mdio_alloc(); + if (!mdiodev) + return -ENOMEM; + strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); + mdiodev->read = bb_miiphy_read; + mdiodev->write = bb_miiphy_write; + + retval = mdio_register(mdiodev); + if (retval < 0) + return retval; +#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 = ARRAY_SIZE(rxeacc_descs); + +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 = ARRAY_SIZE(txeacc_descs); + +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 = ARRAY_SIZE(epram_descs); + +/* + * 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", net_ethaddr); + + /* + * global initialisations for all FCC channels + */ + + /* 28.9 - (1-2): ioports have been set up already */ + +#if 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); + net_set_ether(bp, net_bcast_ethaddr, 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 + */ + fpp->fen_paddrh = (net_ethaddr[5] << 8) + net_ethaddr[4]; + fpp->fen_paddrm = (net_ethaddr[3] << 8) + net_ethaddr[2]; + fpp->fen_paddrl = (net_ethaddr[1] << 8) + net_ethaddr[0]; + + 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; + struct ethernet_hdr *ehp; + ushort prot; + int ours, tb, n, nbytes; + + ehp = (struct ethernet_hdr *) \ + &ecp->rxbufs[i][0]; + + ours = memcmp (ehp->et_src, \ + net_ethaddr, 6); + + prot = swap16 (ehp->et_protlen); + tb = prot & 0x8000; + n = prot & 0x7fff; + + nbytes = ELBT_BUFSZ - + ETHER_HDR_SIZE - + 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( + ((uchar *)&ehp) + + ETHER_HDR_SIZE, + 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/arch/powerpc/cpu/mpc8260/ether_scc.c b/arch/powerpc/cpu/mpc8260/ether_scc.c new file mode 100644 index 0000000000..fff8f2b8d3 --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/ether_scc.c @@ -0,0 +1,367 @@ +/* + * 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 + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/cpm_8260.h> +#include <mpc8260.h> +#include <malloc.h> +#include <net.h> +#include <command.h> +#include <config.h> + +#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, 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. */ + net_process_received_packet(net_rx_packets[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)net_rx_packets[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); + + strcpy(dev->name, "SCC"); + dev->init = sec_init; + dev->halt = sec_halt; + dev->send = sec_send; + dev->recv = sec_rx; + + eth_register(dev); + + return 1; +} diff --git a/arch/powerpc/cpu/mpc8260/interrupts.c b/arch/powerpc/cpu/mpc8260/interrupts.c new file mode 100644 index 0000000000..41d2c04c85 --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/interrupts.c @@ -0,0 +1,255 @@ +/* + * (C) Copyright 2000-2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * 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/powerpc/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/powerpc/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; + + 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 * const 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/arch/powerpc/cpu/mpc8260/kgdb.S b/arch/powerpc/cpu/mpc8260/kgdb.S new file mode 100644 index 0000000000..bc9c62852c --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/kgdb.S @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2000 Murray Jensen Murray.Jensen@cmst.csiro.au + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <command.h> +#include <mpc8260.h> + +#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/arch/powerpc/cpu/mpc8260/pci.c b/arch/powerpc/cpu/mpc8260/pci.c new file mode 100644 index 0000000000..56f290ca92 --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/pci.c @@ -0,0 +1,382 @@ +/* + * (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 + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#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 + +/* + * 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 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; + + /* 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; + + /* 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 */ + { + 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 */ + immap->im_siu_conf.sc_ppc_alrh = 0x03124567; + + /* 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 */ + pci_set_region (hose->regions + 0, + CONFIG_SYS_SDRAM_BASE, + CONFIG_SYS_SDRAM_BASE, + 0x4000000, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + + /* PCI memory space */ + pci_set_region (hose->regions + 1, + PCI_MSTR_MEM_BUS, + PCI_MSTR_MEM_LOCAL, + PCI_MSTR_MEM_SIZE, PCI_REGION_MEM); + + /* 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/arch/powerpc/cpu/mpc8260/serial_scc.c b/arch/powerpc/cpu/mpc8260/serial_scc.c new file mode 100644 index 0000000000..8bfb3dedcb --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/serial_scc.c @@ -0,0 +1,492 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * 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> +#include <serial.h> +#include <linux/compiler.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 + +static int mpc8260_scc_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); +} + +static void mpc8260_scc_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 +} + +static void mpc8260_scc_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; +} + +static int mpc8260_scc_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); +} + +static int mpc8260_scc_serial_tstc(void) +{ + 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); +} + +static struct serial_device mpc8260_scc_serial_drv = { + .name = "mpc8260_scc_uart", + .start = mpc8260_scc_serial_init, + .stop = NULL, + .setbrg = mpc8260_scc_serial_setbrg, + .putc = mpc8260_scc_serial_putc, + .puts = default_serial_puts, + .getc = mpc8260_scc_serial_getc, + .tstc = mpc8260_scc_serial_tstc, +}; + +void mpc8260_scc_serial_initialize(void) +{ + serial_register(&mpc8260_scc_serial_drv); +} + +__weak struct serial_device *default_serial_console(void) +{ + return &mpc8260_scc_serial_drv; +} +#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/arch/powerpc/cpu/mpc8260/serial_smc.c b/arch/powerpc/cpu/mpc8260/serial_smc.c new file mode 100644 index 0000000000..594c5ebf1a --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/serial_smc.c @@ -0,0 +1,461 @@ +/* + * (C) Copyright 2000, 2001, 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Hacked for MPC8260 by Murray.Jensen@cmst.csiro.au, 19-Oct-00, with + * changes based on the file arch/powerpc/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> +#include <serial.h> +#include <linux/compiler.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 */ +}; + +static int mpc8260_smc_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]); + im->im_dprambase16[PROFF_SMC_BASE / sizeof(u16)] = 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); +} + +static void mpc8260_smc_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 +} + +static void mpc8260_smc_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; +} + +static int mpc8260_smc_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); +} + +static int mpc8260_smc_serial_tstc(void) +{ + 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); +} + +static struct serial_device mpc8260_smc_serial_drv = { + .name = "mpc8260_smc_uart", + .start = mpc8260_smc_serial_init, + .stop = NULL, + .setbrg = mpc8260_smc_serial_setbrg, + .putc = mpc8260_smc_serial_putc, + .puts = default_serial_puts, + .getc = mpc8260_smc_serial_getc, + .tstc = mpc8260_smc_serial_tstc, +}; + +void mpc8260_smc_serial_initialize(void) +{ + serial_register(&mpc8260_smc_serial_drv); +} + +__weak struct serial_device *default_serial_console(void) +{ + return &mpc8260_smc_serial_drv; +} +#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]); + im->im_dprambase16[KGDB_PROFF_SMC_BASE / sizeof(u16)] = 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/arch/powerpc/cpu/mpc8260/speed.c b/arch/powerpc/cpu/mpc8260/speed.c new file mode 100644 index 0000000000..0a06c48625 --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/speed.c @@ -0,0 +1,228 @@ +/* + * (C) Copyright 2000-2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#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, 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]; + + /* 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->arch.vco_out = clkin * (pllmf + 1); + } else { /* HiP3, HiP4 */ + pllmf = (scmr & SCMR_PLLMF_MSK) >> SCMR_PLLMF_SHIFT; + plldf = (scmr & SCMR_PLLDF) ? 1 : 0; + gd->arch.vco_out = (clkin * 2 * (pllmf + 1)) / (plldf + 1); + } + + gd->arch.cpm_clk = gd->arch.vco_out / 2; + gd->bus_clk = clkin; + gd->arch.scc_clk = gd->arch.vco_out / 4; + gd->arch.brg_clk = gd->arch.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->arch.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->arch.vco_out, gd->arch.scc_clk, gd->arch.brg_clk); + + printf (" - cpu_clk %10ld, cpm_clk %10ld, bus_clk %10ld\n", + gd->cpu_clk, gd->arch.cpm_clk, gd->bus_clk); +#ifdef CONFIG_PCI + printf (" - pci_clk %10ld\n", gd->pci_clk); +#endif + putc ('\n'); + + return (0); +} diff --git a/arch/powerpc/cpu/mpc8260/spi.c b/arch/powerpc/cpu/mpc8260/spi.c new file mode 100644 index 0000000000..c7fb4e9a6c --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/spi.c @@ -0,0 +1,408 @@ +/* + * 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. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * 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; + + immr->im_dprambase16[PROFF_SPI_BASE / sizeof(u16)] = 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; + + dpaddr = CPM_SPI_BASE; + +/* 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 cbd_t *tbdf, *rbdf; + + immr = (immap_t *) CONFIG_SYS_IMMR; + + 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 spi_t *spi; + cbd_t *tbdf, *rbdf; + int tm; + + DPRINT (("*** spi_xfer entered ***\n")); + + immr = (immap_t *) CONFIG_SYS_IMMR; + + 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/arch/powerpc/cpu/mpc8260/start.S b/arch/powerpc/cpu/mpc8260/start.S new file mode 100644 index 0000000000..d255bdeeb8 --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/start.S @@ -0,0 +1,901 @@ +/* + * 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 + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * U-Boot - Startup Code for MPC8260 PowerPC based Embedded Boards + */ +#include <asm-offsets.h> +#include <config.h> +#include <mpc8260.h> +#include <version.h> + +#include <ppc_asm.tmpl> +#include <ppc_defs.h> + +#include <asm/cache.h> +#include <asm/mmu.h> +#include <asm/u-boot.h> + +/* 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(__bss_end) + GOT_ENTRY(__bss_start) + 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_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: + mfmsr r5 /* save msr contents */ + +#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 + + bl board_init_f /* run 1st part of board init code (in Flash)*/ + + /* NOTREACHED - board_init_f() does not return */ + +/* + * 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 + +/* + * 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 + lis r4, CONFIG_SYS_SYPCR@h + ori r4, r4, CONFIG_SYS_SYPCR@l + stw r4, IM_SYPCR@l(r3) +#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/powerpc/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 + cmpwi r0,0 + add r0,r0,r11 + stw r4,0(r3) + beq- 5f + stw r0,0(r4) +5: bdnz 3b +4: +clear_bss: + /* + * Now clear BSS segment + */ + lwz r3,GOT(__bss_start) + lwz r4,GOT(__bss_end) + + 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/arch/powerpc/cpu/mpc8260/traps.c b/arch/powerpc/cpu/mpc8260/traps.c new file mode 100644 index 0000000000..cbcf533646 --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/traps.c @@ -0,0 +1,248 @@ +/* + * linux/arch/powerpc/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. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * 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 + */ + +static 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'); + } + } +} + + +static 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/arch/powerpc/cpu/mpc8260/u-boot.lds b/arch/powerpc/cpu/mpc8260/u-boot.lds new file mode 100644 index 0000000000..469fc293eb --- /dev/null +++ b/arch/powerpc/cpu/mpc8260/u-boot.lds @@ -0,0 +1,74 @@ +/* + * (C) Copyright 2001-2010 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +OUTPUT_ARCH(powerpc) + +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + .text : + { + arch/powerpc/cpu/mpc8260/start.o (.text*) + *(.text*) + . = ALIGN(16); + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) + } + + /* Read-write section, merged into data segment: */ + . = (. + 0x0FFF) & 0xFFFFF000; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + _GOT2_TABLE_ = .; + KEEP(*(.got2)) + KEEP(*(.got)) + _FIXUP_TABLE_ = .; + KEEP(*(.fixup)) + } + __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1; + __fixup_entries = (. - _FIXUP_TABLE_) >> 2; + + .data : + { + *(.data*) + *(.sdata*) + } + _edata = .; + PROVIDE (edata = .); + + . = .; + + . = ALIGN(4); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } + + + . = .; + __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) : + { + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + } + __bss_end = . ; + PROVIDE (end = .); +} diff --git a/arch/powerpc/cpu/mpc83xx/start.S b/arch/powerpc/cpu/mpc83xx/start.S index 2fed4a1fec..ff312892bc 100644 --- a/arch/powerpc/cpu/mpc83xx/start.S +++ b/arch/powerpc/cpu/mpc83xx/start.S @@ -140,7 +140,7 @@ ppcDWload:
#ifndef CONFIG_DEFAULT_IMMR #error CONFIG_DEFAULT_IMMR must be defined -#endif /* CONFIG_DEFAULT_IMMR */ +#endif /* CONFIG_SYS_DEFAULT_IMMR */ #ifndef CONFIG_SYS_IMMR #define CONFIG_SYS_IMMR CONFIG_DEFAULT_IMMR #endif /* CONFIG_SYS_IMMR */ diff --git a/arch/powerpc/include/asm/cpm_8260.h b/arch/powerpc/include/asm/cpm_8260.h new file mode 100644 index 0000000000..4f78186d9d --- /dev/null +++ b/arch/powerpc/include/asm/cpm_8260.h @@ -0,0 +1,795 @@ +/* + * MPC8260 Communication Processor Module. + * Copyright (c) 1999 Dan Malek (dmalek@jlc.net) + * + * This file contains structures and information for the communication + * processor channels found in the dual port RAM or parameter RAM. + * All CPM control and status is available through the MPC8260 internal + * memory map. See immap.h for details. + */ +#ifndef __CPM_82XX__ +#define __CPM_82XX__ + +#include <asm/immap_8260.h> + +/* CPM Command register. +*/ +#define CPM_CR_RST ((uint)0x80000000) +#define CPM_CR_PAGE ((uint)0x7c000000) +#define CPM_CR_SBLOCK ((uint)0x03e00000) +#define CPM_CR_FLG ((uint)0x00010000) +#define CPM_CR_MCN ((uint)0x00003fc0) +#define CPM_CR_OPCODE ((uint)0x0000000f) + +/* Device sub-block and page codes. +*/ +#define CPM_CR_SCC1_SBLOCK (0x04) +#define CPM_CR_SCC2_SBLOCK (0x05) +#define CPM_CR_SCC3_SBLOCK (0x06) +#define CPM_CR_SCC4_SBLOCK (0x07) +#define CPM_CR_SMC1_SBLOCK (0x08) +#define CPM_CR_SMC2_SBLOCK (0x09) +#define CPM_CR_SPI_SBLOCK (0x0a) +#define CPM_CR_I2C_SBLOCK (0x0b) +#define CPM_CR_TIMER_SBLOCK (0x0f) +#define CPM_CR_RAND_SBLOCK (0x0e) +#define CPM_CR_FCC1_SBLOCK (0x10) +#define CPM_CR_FCC2_SBLOCK (0x11) +#define CPM_CR_FCC3_SBLOCK (0x12) +#define CPM_CR_IDMA1_SBLOCK (0x14) +#define CPM_CR_IDMA2_SBLOCK (0x15) +#define CPM_CR_IDMA3_SBLOCK (0x16) +#define CPM_CR_IDMA4_SBLOCK (0x17) +#define CPM_CR_MCC1_SBLOCK (0x1c) + +#define CPM_CR_SCC1_PAGE (0x00) +#define CPM_CR_SCC2_PAGE (0x01) +#define CPM_CR_SCC3_PAGE (0x02) +#define CPM_CR_SCC4_PAGE (0x03) +#define CPM_CR_SMC1_PAGE (0x07) +#define CPM_CR_SMC2_PAGE (0x08) +#define CPM_CR_SPI_PAGE (0x09) +#define CPM_CR_I2C_PAGE (0x0a) +#define CPM_CR_TIMER_PAGE (0x0a) +#define CPM_CR_RAND_PAGE (0x0a) +#define CPM_CR_FCC1_PAGE (0x04) +#define CPM_CR_FCC2_PAGE (0x05) +#define CPM_CR_FCC3_PAGE (0x06) +#define CPM_CR_IDMA1_PAGE (0x07) +#define CPM_CR_IDMA2_PAGE (0x08) +#define CPM_CR_IDMA3_PAGE (0x09) +#define CPM_CR_IDMA4_PAGE (0x0a) +#define CPM_CR_MCC1_PAGE (0x07) +#define CPM_CR_MCC2_PAGE (0x08) + +/* Some opcodes (there are more...later) +*/ +#define CPM_CR_INIT_TRX ((ushort)0x0000) +#define CPM_CR_INIT_RX ((ushort)0x0001) +#define CPM_CR_INIT_TX ((ushort)0x0002) +#define CPM_CR_HUNT_MODE ((ushort)0x0003) +#define CPM_CR_STOP_TX ((ushort)0x0004) +#define CPM_CR_RESTART_TX ((ushort)0x0006) +#define CPM_CR_SET_GADDR ((ushort)0x0008) + +#define mk_cr_cmd(PG, SBC, MCN, OP) \ + ((PG << 26) | (SBC << 21) | (MCN << 6) | OP) + +/* Dual Port RAM addresses. The first 16K is available for almost + * any CPM use, so we put the BDs there. The first 128 bytes are + * used for SMC1 and SMC2 parameter RAM, so we start allocating + * BDs above that. All of this must change when we start + * downloading RAM microcode. + */ +#define CPM_DATAONLY_BASE ((uint)128) +#define CPM_DP_NOSPACE ((uint)0x7fffffff) +#ifndef CONFIG_MPC8272_FAMILY +#define CPM_DATAONLY_SIZE ((uint)(8 * 1024) - CPM_DATAONLY_BASE) +#define CPM_FCC_SPECIAL_BASE ((uint)0x0000b000) +#else /* 8247/48/71/72 */ +#define CPM_DATAONLY_SIZE ((uint)(4 * 1024) - CPM_DATAONLY_BASE) +#define CPM_FCC_SPECIAL_BASE ((uint)0x00009000) +#endif /* !CONFIG_MPC8272_FAMILY */ + +/* The number of pages of host memory we allocate for CPM. This is + * done early in kernel initialization to get physically contiguous + * pages. + */ +#define NUM_CPM_HOST_PAGES 2 + + +/* Export the base address of the communication processor registers + * and dual port ram. + */ +extern cpm8260_t *cpmp; /* Pointer to comm processor */ +uint m8260_cpm_dpalloc(uint size, uint align); +uint m8260_cpm_hostalloc(uint size, uint align); +void m8260_cpm_setbrg(uint brg, uint rate); +void m8260_cpm_fastbrg(uint brg, uint rate, int div16); +void m8260_cpm_extcbrg(uint brg, uint rate, uint extclk, int pinsel); + +/* Buffer descriptors used by many of the CPM protocols. +*/ +typedef struct cpm_buf_desc { + ushort cbd_sc; /* Status and Control */ + ushort cbd_datlen; /* Data length in buffer */ + uint cbd_bufaddr; /* Buffer address in host memory */ +} cbd_t; + +#define BD_SC_EMPTY ((ushort)0x8000) /* Receive is empty */ +#define BD_SC_READY ((ushort)0x8000) /* Transmit is ready */ +#define BD_SC_WRAP ((ushort)0x2000) /* Last buffer descriptor */ +#define BD_SC_INTRPT ((ushort)0x1000) /* Interrupt on change */ +#define BD_SC_LAST ((ushort)0x0800) /* Last buffer in frame */ +#define BD_SC_CM ((ushort)0x0200) /* Continous mode */ +#define BD_SC_ID ((ushort)0x0100) /* Rec'd too many idles */ +#define BD_SC_P ((ushort)0x0100) /* xmt preamble */ +#define BD_SC_BR ((ushort)0x0020) /* Break received */ +#define BD_SC_FR ((ushort)0x0010) /* Framing error */ +#define BD_SC_PR ((ushort)0x0008) /* Parity error */ +#define BD_SC_OV ((ushort)0x0002) /* Overrun */ +#define BD_SC_CD ((ushort)0x0001) /* ?? */ + +/* Function code bits, usually generic to devices. +*/ +#define CPMFCR_GBL ((u_char)0x20) /* Set memory snooping */ +#define CPMFCR_EB ((u_char)0x10) /* Set big endian byte order */ +#define CPMFCR_TC2 ((u_char)0x04) /* Transfer code 2 value */ +#define CPMFCR_DTB ((u_char)0x02) /* Use local bus for data when set */ +#define CPMFCR_BDB ((u_char)0x01) /* Use local bus for BD when set */ + +/* Parameter RAM offsets from the base. +*/ +#ifndef CONFIG_SYS_CPM_POST_WORD_ADDR +#define CPM_POST_WORD_ADDR 0x80FC /* steal a long at the end of SCC1 */ +#else +#define CPM_POST_WORD_ADDR CONFIG_SYS_CPM_POST_WORD_ADDR +#endif + +#ifndef CONFIG_SYS_CPM_BOOTCOUNT_ADDR +#define CPM_BOOTCOUNT_ADDR (CPM_POST_WORD_ADDR - 2*sizeof(ulong)) +#else +#define CPM_BOOTCOUNT_ADDR CONFIG_SYS_CPM_BOOTCOUNT_ADDR +#endif + +#define PROFF_SCC1 ((uint)0x8000) +#define PROFF_SCC2 ((uint)0x8100) +#define PROFF_SCC3 ((uint)0x8200) +#define PROFF_SCC4 ((uint)0x8300) +#define PROFF_FCC1 ((uint)0x8400) +#define PROFF_FCC2 ((uint)0x8500) +#define PROFF_FCC3 ((uint)0x8600) +#define PROFF_MCC1 ((uint)0x8700) +#define PROFF_SMC1_BASE ((uint)0x87fc) +#define PROFF_IDMA1_BASE ((uint)0x87fe) +#define PROFF_MCC2 ((uint)0x8800) +#define PROFF_SMC2_BASE ((uint)0x88fc) +#define PROFF_IDMA2_BASE ((uint)0x88fe) +#define PROFF_SPI_BASE ((uint)0x89fc) +#define PROFF_IDMA3_BASE ((uint)0x89fe) +#define PROFF_TIMERS ((uint)0x8ae0) +#define PROFF_REVNUM ((uint)0x8af0) +#define PROFF_RAND ((uint)0x8af8) +#define PROFF_I2C_BASE ((uint)0x8afc) +#define PROFF_IDMA4_BASE ((uint)0x8afe) + +/* The SMCs are relocated to any of the first eight DPRAM pages. + * We will fix these at the first locations of DPRAM, until we + * get some microcode patches :-). + * The parameter ram space for the SMCs is fifty-some bytes, and + * they are required to start on a 64 byte boundary. + */ +#define PROFF_SMC1 (0) +#define PROFF_SMC2 (64) +#define PROFF_SPI ((16*1024) - 128) + +/* Define enough so I can at least use the serial port as a UART. + */ +typedef struct smc_uart { + ushort smc_rbase; /* Rx Buffer descriptor base address */ + ushort smc_tbase; /* Tx Buffer descriptor base address */ + u_char smc_rfcr; /* Rx function code */ + u_char smc_tfcr; /* Tx function code */ + ushort smc_mrblr; /* Max receive buffer length */ + uint smc_rstate; /* Internal */ + uint smc_idp; /* Internal */ + ushort smc_rbptr; /* Internal */ + ushort smc_ibc; /* Internal */ + uint smc_rxtmp; /* Internal */ + uint smc_tstate; /* Internal */ + uint smc_tdp; /* Internal */ + ushort smc_tbptr; /* Internal */ + ushort smc_tbc; /* Internal */ + uint smc_txtmp; /* Internal */ + ushort smc_maxidl; /* Maximum idle characters */ + ushort smc_tmpidl; /* Temporary idle counter */ + ushort smc_brklen; /* Last received break length */ + ushort smc_brkec; /* rcv'd break condition counter */ + ushort smc_brkcr; /* xmt break count register */ + ushort smc_rmask; /* Temporary bit mask */ + uint smc_stmp; /* SDMA Temp */ +} smc_uart_t; + +/* SMC uart mode register (Internal memory map). +*/ +#define SMCMR_REN ((ushort)0x0001) +#define SMCMR_TEN ((ushort)0x0002) +#define SMCMR_DM ((ushort)0x000c) +#define SMCMR_SM_GCI ((ushort)0x0000) +#define SMCMR_SM_UART ((ushort)0x0020) +#define SMCMR_SM_TRANS ((ushort)0x0030) +#define SMCMR_SM_MASK ((ushort)0x0030) +#define SMCMR_PM_EVEN ((ushort)0x0100) /* Even parity, else odd */ +#define SMCMR_REVD SMCMR_PM_EVEN +#define SMCMR_PEN ((ushort)0x0200) /* Parity enable */ +#define SMCMR_BS SMCMR_PEN +#define SMCMR_SL ((ushort)0x0400) /* Two stops, else one */ +#define SMCR_CLEN_MASK ((ushort)0x7800) /* Character length */ +#define smcr_mk_clen(C) (((C) << 11) & SMCR_CLEN_MASK) + +/* SMC Event and Mask register. +*/ +#define SMCM_TXE ((unsigned char)0x10) +#define SMCM_BSY ((unsigned char)0x04) +#define SMCM_TX ((unsigned char)0x02) +#define SMCM_RX ((unsigned char)0x01) + +/* Baud rate generators. +*/ +#define CPM_BRG_RST ((uint)0x00020000) +#define CPM_BRG_EN ((uint)0x00010000) +#define CPM_BRG_EXTC_INT ((uint)0x00000000) +#define CPM_BRG_EXTC_CLK3_9 ((uint)0x00004000) +#define CPM_BRG_EXTC_CLK5_15 ((uint)0x00008000) +#define CPM_BRG_ATB ((uint)0x00002000) +#define CPM_BRG_CD_MASK ((uint)0x00001ffe) +#define CPM_BRG_DIV16 ((uint)0x00000001) + +/* SCCs. +*/ +#define SCC_GSMRH_IRP ((uint)0x00040000) +#define SCC_GSMRH_GDE ((uint)0x00010000) +#define SCC_GSMRH_TCRC_CCITT ((uint)0x00008000) +#define SCC_GSMRH_TCRC_BISYNC ((uint)0x00004000) +#define SCC_GSMRH_TCRC_HDLC ((uint)0x00000000) +#define SCC_GSMRH_REVD ((uint)0x00002000) +#define SCC_GSMRH_TRX ((uint)0x00001000) +#define SCC_GSMRH_TTX ((uint)0x00000800) +#define SCC_GSMRH_CDP ((uint)0x00000400) +#define SCC_GSMRH_CTSP ((uint)0x00000200) +#define SCC_GSMRH_CDS ((uint)0x00000100) +#define SCC_GSMRH_CTSS ((uint)0x00000080) +#define SCC_GSMRH_TFL ((uint)0x00000040) +#define SCC_GSMRH_RFW ((uint)0x00000020) +#define SCC_GSMRH_TXSY ((uint)0x00000010) +#define SCC_GSMRH_SYNL16 ((uint)0x0000000c) +#define SCC_GSMRH_SYNL8 ((uint)0x00000008) +#define SCC_GSMRH_SYNL4 ((uint)0x00000004) +#define SCC_GSMRH_RTSM ((uint)0x00000002) +#define SCC_GSMRH_RSYN ((uint)0x00000001) + +#define SCC_GSMRL_SIR ((uint)0x80000000) /* SCC2 only */ +#define SCC_GSMRL_EDGE_NONE ((uint)0x60000000) +#define SCC_GSMRL_EDGE_NEG ((uint)0x40000000) +#define SCC_GSMRL_EDGE_POS ((uint)0x20000000) +#define SCC_GSMRL_EDGE_BOTH ((uint)0x00000000) +#define SCC_GSMRL_TCI ((uint)0x10000000) +#define SCC_GSMRL_TSNC_3 ((uint)0x0c000000) +#define SCC_GSMRL_TSNC_4 ((uint)0x08000000) +#define SCC_GSMRL_TSNC_14 ((uint)0x04000000) +#define SCC_GSMRL_TSNC_INF ((uint)0x00000000) +#define SCC_GSMRL_RINV ((uint)0x02000000) +#define SCC_GSMRL_TINV ((uint)0x01000000) +#define SCC_GSMRL_TPL_128 ((uint)0x00c00000) +#define SCC_GSMRL_TPL_64 ((uint)0x00a00000) +#define SCC_GSMRL_TPL_48 ((uint)0x00800000) +#define SCC_GSMRL_TPL_32 ((uint)0x00600000) +#define SCC_GSMRL_TPL_16 ((uint)0x00400000) +#define SCC_GSMRL_TPL_8 ((uint)0x00200000) +#define SCC_GSMRL_TPL_NONE ((uint)0x00000000) +#define SCC_GSMRL_TPP_ALL1 ((uint)0x00180000) +#define SCC_GSMRL_TPP_01 ((uint)0x00100000) +#define SCC_GSMRL_TPP_10 ((uint)0x00080000) +#define SCC_GSMRL_TPP_ZEROS ((uint)0x00000000) +#define SCC_GSMRL_TEND ((uint)0x00040000) +#define SCC_GSMRL_TDCR_32 ((uint)0x00030000) +#define SCC_GSMRL_TDCR_16 ((uint)0x00020000) +#define SCC_GSMRL_TDCR_8 ((uint)0x00010000) +#define SCC_GSMRL_TDCR_1 ((uint)0x00000000) +#define SCC_GSMRL_RDCR_32 ((uint)0x0000c000) +#define SCC_GSMRL_RDCR_16 ((uint)0x00008000) +#define SCC_GSMRL_RDCR_8 ((uint)0x00004000) +#define SCC_GSMRL_RDCR_1 ((uint)0x00000000) +#define SCC_GSMRL_RENC_DFMAN ((uint)0x00003000) +#define SCC_GSMRL_RENC_MANCH ((uint)0x00002000) +#define SCC_GSMRL_RENC_FM0 ((uint)0x00001000) +#define SCC_GSMRL_RENC_NRZI ((uint)0x00000800) +#define SCC_GSMRL_RENC_NRZ ((uint)0x00000000) +#define SCC_GSMRL_TENC_DFMAN ((uint)0x00000600) +#define SCC_GSMRL_TENC_MANCH ((uint)0x00000400) +#define SCC_GSMRL_TENC_FM0 ((uint)0x00000200) +#define SCC_GSMRL_TENC_NRZI ((uint)0x00000100) +#define SCC_GSMRL_TENC_NRZ ((uint)0x00000000) +#define SCC_GSMRL_DIAG_LE ((uint)0x000000c0) /* Loop and echo */ +#define SCC_GSMRL_DIAG_ECHO ((uint)0x00000080) +#define SCC_GSMRL_DIAG_LOOP ((uint)0x00000040) +#define SCC_GSMRL_DIAG_NORM ((uint)0x00000000) +#define SCC_GSMRL_ENR ((uint)0x00000020) +#define SCC_GSMRL_ENT ((uint)0x00000010) +#define SCC_GSMRL_MODE_ENET ((uint)0x0000000c) +#define SCC_GSMRL_MODE_DDCMP ((uint)0x00000009) +#define SCC_GSMRL_MODE_BISYNC ((uint)0x00000008) +#define SCC_GSMRL_MODE_V14 ((uint)0x00000007) +#define SCC_GSMRL_MODE_AHDLC ((uint)0x00000006) +#define SCC_GSMRL_MODE_PROFIBUS ((uint)0x00000005) +#define SCC_GSMRL_MODE_UART ((uint)0x00000004) +#define SCC_GSMRL_MODE_SS7 ((uint)0x00000003) +#define SCC_GSMRL_MODE_ATALK ((uint)0x00000002) +#define SCC_GSMRL_MODE_HDLC ((uint)0x00000000) + +#define SCC_TODR_TOD ((ushort)0x8000) + +/* SCC Event and Mask register. +*/ +#define SCCM_TXE ((unsigned char)0x10) +#define SCCM_BSY ((unsigned char)0x04) +#define SCCM_TX ((unsigned char)0x02) +#define SCCM_RX ((unsigned char)0x01) + +typedef struct scc_param { + ushort scc_rbase; /* Rx Buffer descriptor base address */ + ushort scc_tbase; /* Tx Buffer descriptor base address */ + u_char scc_rfcr; /* Rx function code */ + u_char scc_tfcr; /* Tx function code */ + ushort scc_mrblr; /* Max receive buffer length */ + uint scc_rstate; /* Internal */ + uint scc_idp; /* Internal */ + ushort scc_rbptr; /* Internal */ + ushort scc_ibc; /* Internal */ + uint scc_rxtmp; /* Internal */ + uint scc_tstate; /* Internal */ + uint scc_tdp; /* Internal */ + ushort scc_tbptr; /* Internal */ + ushort scc_tbc; /* Internal */ + uint scc_txtmp; /* Internal */ + uint scc_rcrc; /* Internal */ + uint scc_tcrc; /* Internal */ +} sccp_t; + +/* CPM Ethernet through SCC1. + */ +typedef struct scc_enet { + sccp_t sen_genscc; + uint sen_cpres; /* Preset CRC */ + uint sen_cmask; /* Constant mask for CRC */ + uint sen_crcec; /* CRC Error counter */ + uint sen_alec; /* alignment error counter */ + uint sen_disfc; /* discard frame counter */ + ushort sen_pads; /* Tx short frame pad character */ + ushort sen_retlim; /* Retry limit threshold */ + ushort sen_retcnt; /* Retry limit counter */ + ushort sen_maxflr; /* maximum frame length register */ + ushort sen_minflr; /* minimum frame length register */ + ushort sen_maxd1; /* maximum DMA1 length */ + ushort sen_maxd2; /* maximum DMA2 length */ + ushort sen_maxd; /* Rx max DMA */ + ushort sen_dmacnt; /* Rx DMA counter */ + ushort sen_maxb; /* Max BD byte count */ + ushort sen_gaddr1; /* Group address filter */ + ushort sen_gaddr2; + ushort sen_gaddr3; + ushort sen_gaddr4; + uint sen_tbuf0data0; /* Save area 0 - current frame */ + uint sen_tbuf0data1; /* Save area 1 - current frame */ + uint sen_tbuf0rba; /* Internal */ + uint sen_tbuf0crc; /* Internal */ + ushort sen_tbuf0bcnt; /* Internal */ + ushort sen_paddrh; /* physical address (MSB) */ + ushort sen_paddrm; + ushort sen_paddrl; /* physical address (LSB) */ + ushort sen_pper; /* persistence */ + ushort sen_rfbdptr; /* Rx first BD pointer */ + ushort sen_tfbdptr; /* Tx first BD pointer */ + ushort sen_tlbdptr; /* Tx last BD pointer */ + uint sen_tbuf1data0; /* Save area 0 - current frame */ + uint sen_tbuf1data1; /* Save area 1 - current frame */ + uint sen_tbuf1rba; /* Internal */ + uint sen_tbuf1crc; /* Internal */ + ushort sen_tbuf1bcnt; /* Internal */ + ushort sen_txlen; /* Tx Frame length counter */ + ushort sen_iaddr1; /* Individual address filter */ + ushort sen_iaddr2; + ushort sen_iaddr3; + ushort sen_iaddr4; + ushort sen_boffcnt; /* Backoff counter */ + + /* NOTE: Some versions of the manual have the following items + * incorrectly documented. Below is the proper order. + */ + ushort sen_taddrh; /* temp address (MSB) */ + ushort sen_taddrm; + ushort sen_taddrl; /* temp address (LSB) */ +} scc_enet_t; + + +/* SCC Event register as used by Ethernet. +*/ +#define SCCE_ENET_GRA ((ushort)0x0080) /* Graceful stop complete */ +#define SCCE_ENET_TXE ((ushort)0x0010) /* Transmit Error */ +#define SCCE_ENET_RXF ((ushort)0x0008) /* Full frame received */ +#define SCCE_ENET_BSY ((ushort)0x0004) /* All incoming buffers full */ +#define SCCE_ENET_TXB ((ushort)0x0002) /* A buffer was transmitted */ +#define SCCE_ENET_RXB ((ushort)0x0001) /* A buffer was received */ + +/* SCC Mode Register (PSMR) as used by Ethernet. +*/ +#define SCC_PSMR_HBC ((ushort)0x8000) /* Enable heartbeat */ +#define SCC_PSMR_FC ((ushort)0x4000) /* Force collision */ +#define SCC_PSMR_RSH ((ushort)0x2000) /* Receive short frames */ +#define SCC_PSMR_IAM ((ushort)0x1000) /* Check individual hash */ +#define SCC_PSMR_ENCRC ((ushort)0x0800) /* Ethernet CRC mode */ +#define SCC_PSMR_PRO ((ushort)0x0200) /* Promiscuous mode */ +#define SCC_PSMR_BRO ((ushort)0x0100) /* Catch broadcast pkts */ +#define SCC_PSMR_SBT ((ushort)0x0080) /* Special backoff timer */ +#define SCC_PSMR_LPB ((ushort)0x0040) /* Set Loopback mode */ +#define SCC_PSMR_SIP ((ushort)0x0020) /* Sample Input Pins */ +#define SCC_PSMR_LCW ((ushort)0x0010) /* Late collision window */ +#define SCC_PSMR_NIB22 ((ushort)0x000a) /* Start frame search */ +#define SCC_PSMR_FDE ((ushort)0x0001) /* Full duplex enable */ + +/* Buffer descriptor control/status used by Ethernet receive. + * Common to SCC and FCC. + */ +#define BD_ENET_RX_EMPTY ((ushort)0x8000) +#define BD_ENET_RX_WRAP ((ushort)0x2000) +#define BD_ENET_RX_INTR ((ushort)0x1000) +#define BD_ENET_RX_LAST ((ushort)0x0800) +#define BD_ENET_RX_FIRST ((ushort)0x0400) +#define BD_ENET_RX_MISS ((ushort)0x0100) +#define BD_ENET_RX_BC ((ushort)0x0080) /* FCC Only */ +#define BD_ENET_RX_MC ((ushort)0x0040) /* FCC Only */ +#define BD_ENET_RX_LG ((ushort)0x0020) +#define BD_ENET_RX_NO ((ushort)0x0010) +#define BD_ENET_RX_SH ((ushort)0x0008) +#define BD_ENET_RX_CR ((ushort)0x0004) +#define BD_ENET_RX_OV ((ushort)0x0002) +#define BD_ENET_RX_CL ((ushort)0x0001) +#define BD_ENET_RX_STATS ((ushort)0x01ff) /* All status bits */ + +/* Buffer descriptor control/status used by Ethernet transmit. + * Common to SCC and FCC. + */ +#define BD_ENET_TX_READY ((ushort)0x8000) +#define BD_ENET_TX_PAD ((ushort)0x4000) +#define BD_ENET_TX_WRAP ((ushort)0x2000) +#define BD_ENET_TX_INTR ((ushort)0x1000) +#define BD_ENET_TX_LAST ((ushort)0x0800) +#define BD_ENET_TX_TC ((ushort)0x0400) +#define BD_ENET_TX_DEF ((ushort)0x0200) +#define BD_ENET_TX_HB ((ushort)0x0100) +#define BD_ENET_TX_LC ((ushort)0x0080) +#define BD_ENET_TX_RL ((ushort)0x0040) +#define BD_ENET_TX_RCMASK ((ushort)0x003c) +#define BD_ENET_TX_UN ((ushort)0x0002) +#define BD_ENET_TX_CSL ((ushort)0x0001) +#define BD_ENET_TX_STATS ((ushort)0x03ff) /* All status bits */ + +/* SCC as UART +*/ +typedef struct scc_uart { + sccp_t scc_genscc; + uint scc_res1; /* Reserved */ + uint scc_res2; /* Reserved */ + ushort scc_maxidl; /* Maximum idle chars */ + ushort scc_idlc; /* temp idle counter */ + ushort scc_brkcr; /* Break count register */ + ushort scc_parec; /* receive parity error counter */ + ushort scc_frmec; /* receive framing error counter */ + ushort scc_nosec; /* receive noise counter */ + ushort scc_brkec; /* receive break condition counter */ + ushort scc_brkln; /* last received break length */ + ushort scc_uaddr1; /* UART address character 1 */ + ushort scc_uaddr2; /* UART address character 2 */ + ushort scc_rtemp; /* Temp storage */ + ushort scc_toseq; /* Transmit out of sequence char */ + ushort scc_char1; /* control character 1 */ + ushort scc_char2; /* control character 2 */ + ushort scc_char3; /* control character 3 */ + ushort scc_char4; /* control character 4 */ + ushort scc_char5; /* control character 5 */ + ushort scc_char6; /* control character 6 */ + ushort scc_char7; /* control character 7 */ + ushort scc_char8; /* control character 8 */ + ushort scc_rccm; /* receive control character mask */ + ushort scc_rccr; /* receive control character register */ + ushort scc_rlbc; /* receive last break character */ +} scc_uart_t; + +/* SCC Event and Mask registers when it is used as a UART. +*/ +#define UART_SCCM_GLR ((ushort)0x1000) +#define UART_SCCM_GLT ((ushort)0x0800) +#define UART_SCCM_AB ((ushort)0x0200) +#define UART_SCCM_IDL ((ushort)0x0100) +#define UART_SCCM_GRA ((ushort)0x0080) +#define UART_SCCM_BRKE ((ushort)0x0040) +#define UART_SCCM_BRKS ((ushort)0x0020) +#define UART_SCCM_CCR ((ushort)0x0008) +#define UART_SCCM_BSY ((ushort)0x0004) +#define UART_SCCM_TX ((ushort)0x0002) +#define UART_SCCM_RX ((ushort)0x0001) + +/* The SCC PSMR when used as a UART. +*/ +#define SCU_PSMR_FLC ((ushort)0x8000) +#define SCU_PSMR_SL ((ushort)0x4000) +#define SCU_PSMR_CL ((ushort)0x3000) +#define SCU_PSMR_UM ((ushort)0x0c00) +#define SCU_PSMR_FRZ ((ushort)0x0200) +#define SCU_PSMR_RZS ((ushort)0x0100) +#define SCU_PSMR_SYN ((ushort)0x0080) +#define SCU_PSMR_DRT ((ushort)0x0040) +#define SCU_PSMR_PEN ((ushort)0x0010) +#define SCU_PSMR_RPM ((ushort)0x000c) +#define SCU_PSMR_REVP ((ushort)0x0008) +#define SCU_PSMR_TPM ((ushort)0x0003) +#define SCU_PSMR_TEVP ((ushort)0x0003) + +/* CPM Transparent mode SCC. + */ +typedef struct scc_trans { + sccp_t st_genscc; + uint st_cpres; /* Preset CRC */ + uint st_cmask; /* Constant mask for CRC */ +} scc_trans_t; + +#define BD_SCC_TX_LAST ((ushort)0x0800) + +/* SCC as HDLC controller - taken from commproc.h + */ +typedef struct scc_hdlc { + sccp_t sh_genscc; + /* + * HDLC specific parameter RAM + */ + uchar res[4]; /* reserved */ + ulong sh_cmask; /* CRC constant */ + ulong sh_cpres; /* CRC preset */ + ushort sh_disfc; /* discarded frame counter */ + ushort sh_crcec; /* CRC error counter */ + ushort sh_abtsc; /* abort sequence counter */ + ushort sh_nmarc; /* nonmatching address rx cnt */ + ushort sh_retrc; /* frame retransmission cnt */ + ushort sh_mflr; /* maximum frame length reg */ + ushort sh_maxcnt; /* maximum length counter */ + ushort sh_rfthr; /* received frames threshold */ + ushort sh_rfcnt; /* received frames count */ + ushort sh_hmask; /* user defined frm addr mask */ + ushort sh_haddr1; /* user defined frm address 1 */ + ushort sh_haddr2; /* user defined frm address 2 */ + ushort sh_haddr3; /* user defined frm address 3 */ + ushort sh_haddr4; /* user defined frm address 4 */ + ushort tmp; /* temp */ + ushort tmp_mb; /* temp */ +} scc_hdlc_t; + +/* How about some FCCs..... +*/ +#define FCC_GFMR_DIAG_NORM ((uint)0x00000000) +#define FCC_GFMR_DIAG_LE ((uint)0x40000000) +#define FCC_GFMR_DIAG_AE ((uint)0x80000000) +#define FCC_GFMR_DIAG_ALE ((uint)0xc0000000) +#define FCC_GFMR_TCI ((uint)0x20000000) +#define FCC_GFMR_TRX ((uint)0x10000000) +#define FCC_GFMR_TTX ((uint)0x08000000) +#define FCC_GFMR_TTX ((uint)0x08000000) +#define FCC_GFMR_CDP ((uint)0x04000000) +#define FCC_GFMR_CTSP ((uint)0x02000000) +#define FCC_GFMR_CDS ((uint)0x01000000) +#define FCC_GFMR_CTSS ((uint)0x00800000) +#define FCC_GFMR_SYNL_NONE ((uint)0x00000000) +#define FCC_GFMR_SYNL_AUTO ((uint)0x00004000) +#define FCC_GFMR_SYNL_8 ((uint)0x00008000) +#define FCC_GFMR_SYNL_16 ((uint)0x0000c000) +#define FCC_GFMR_RTSM ((uint)0x00002000) +#define FCC_GFMR_RENC_NRZ ((uint)0x00000000) +#define FCC_GFMR_RENC_NRZI ((uint)0x00000800) +#define FCC_GFMR_REVD ((uint)0x00000400) +#define FCC_GFMR_TENC_NRZ ((uint)0x00000000) +#define FCC_GFMR_TENC_NRZI ((uint)0x00000100) +#define FCC_GFMR_TCRC_16 ((uint)0x00000000) +#define FCC_GFMR_TCRC_32 ((uint)0x00000080) +#define FCC_GFMR_ENR ((uint)0x00000020) +#define FCC_GFMR_ENT ((uint)0x00000010) +#define FCC_GFMR_MODE_ENET ((uint)0x0000000c) +#define FCC_GFMR_MODE_ATM ((uint)0x0000000a) +#define FCC_GFMR_MODE_HDLC ((uint)0x00000000) + +/* Generic FCC parameter ram. +*/ +typedef struct fcc_param { + ushort fcc_riptr; /* Rx Internal temp pointer */ + ushort fcc_tiptr; /* Tx Internal temp pointer */ + ushort fcc_res1; + ushort fcc_mrblr; /* Max receive buffer length, mod 32 bytes */ + uint fcc_rstate; /* Upper byte is Func code, must be set */ + uint fcc_rbase; /* Receive BD base */ + ushort fcc_rbdstat; /* RxBD status */ + ushort fcc_rbdlen; /* RxBD down counter */ + uint fcc_rdptr; /* RxBD internal data pointer */ + uint fcc_tstate; /* Upper byte is Func code, must be set */ + uint fcc_tbase; /* Transmit BD base */ + ushort fcc_tbdstat; /* TxBD status */ + ushort fcc_tbdlen; /* TxBD down counter */ + uint fcc_tdptr; /* TxBD internal data pointer */ + uint fcc_rbptr; /* Rx BD Internal buf pointer */ + uint fcc_tbptr; /* Tx BD Internal buf pointer */ + uint fcc_rcrc; /* Rx temp CRC */ + uint fcc_res2; + uint fcc_tcrc; /* Tx temp CRC */ +} fccp_t; + + +/* Ethernet controller through FCC. +*/ +typedef struct fcc_enet { + fccp_t fen_genfcc; + uint fen_statbuf; /* Internal status buffer */ + uint fen_camptr; /* CAM address */ + uint fen_cmask; /* Constant mask for CRC */ + uint fen_cpres; /* Preset CRC */ + uint fen_crcec; /* CRC Error counter */ + uint fen_alec; /* alignment error counter */ + uint fen_disfc; /* discard frame counter */ + ushort fen_retlim; /* Retry limit */ + ushort fen_retcnt; /* Retry counter */ + ushort fen_pper; /* Persistence */ + ushort fen_boffcnt; /* backoff counter */ + uint fen_gaddrh; /* Group address filter, high 32-bits */ + uint fen_gaddrl; /* Group address filter, low 32-bits */ + ushort fen_tfcstat; /* out of sequence TxBD */ + ushort fen_tfclen; + uint fen_tfcptr; + ushort fen_mflr; /* Maximum frame length (1518) */ + ushort fen_paddrh; /* MAC address */ + ushort fen_paddrm; + ushort fen_paddrl; + ushort fen_ibdcount; /* Internal BD counter */ + ushort fen_idbstart; /* Internal BD start pointer */ + ushort fen_ibdend; /* Internal BD end pointer */ + ushort fen_txlen; /* Internal Tx frame length counter */ + uint fen_ibdbase[8]; /* Internal use */ + uint fen_iaddrh; /* Individual address filter */ + uint fen_iaddrl; + ushort fen_minflr; /* Minimum frame length (64) */ + ushort fen_taddrh; /* Filter transfer MAC address */ + ushort fen_taddrm; + ushort fen_taddrl; + ushort fen_padptr; /* Pointer to pad byte buffer */ + ushort fen_cftype; /* control frame type */ + ushort fen_cfrange; /* control frame range */ + ushort fen_maxb; /* maximum BD count */ + ushort fen_maxd1; /* Max DMA1 length (1520) */ + ushort fen_maxd2; /* Max DMA2 length (1520) */ + ushort fen_maxd; /* internal max DMA count */ + ushort fen_dmacnt; /* internal DMA counter */ + uint fen_octc; /* Total octect counter */ + uint fen_colc; /* Total collision counter */ + uint fen_broc; /* Total broadcast packet counter */ + uint fen_mulc; /* Total multicast packet count */ + uint fen_uspc; /* Total packets < 64 bytes */ + uint fen_frgc; /* Total packets < 64 bytes with errors */ + uint fen_ospc; /* Total packets > 1518 */ + uint fen_jbrc; /* Total packets > 1518 with errors */ + uint fen_p64c; /* Total packets == 64 bytes */ + uint fen_p65c; /* Total packets 64 < bytes <= 127 */ + uint fen_p128c; /* Total packets 127 < bytes <= 255 */ + uint fen_p256c; /* Total packets 256 < bytes <= 511 */ + uint fen_p512c; /* Total packets 512 < bytes <= 1023 */ + uint fen_p1024c; /* Total packets 1024 < bytes <= 1518 */ + uint fen_cambuf; /* Internal CAM buffer poiner */ + ushort fen_rfthr; /* Received frames threshold */ + ushort fen_rfcnt; /* Received frames count */ +} fcc_enet_t; + +/* FCC Event/Mask register as used by Ethernet. +*/ +#define FCC_ENET_GRA ((ushort)0x0080) /* Graceful stop complete */ +#define FCC_ENET_RXC ((ushort)0x0040) /* Control Frame Received */ +#define FCC_ENET_TXC ((ushort)0x0020) /* Out of seq. Tx sent */ +#define FCC_ENET_TXE ((ushort)0x0010) /* Transmit Error */ +#define FCC_ENET_RXF ((ushort)0x0008) /* Full frame received */ +#define FCC_ENET_BSY ((ushort)0x0004) /* Busy. Rx Frame dropped */ +#define FCC_ENET_TXB ((ushort)0x0002) /* A buffer was transmitted */ +#define FCC_ENET_RXB ((ushort)0x0001) /* A buffer was received */ + +/* FCC Mode Register (FPSMR) as used by Ethernet. +*/ +#define FCC_PSMR_HBC ((uint)0x80000000) /* Enable heartbeat */ +#define FCC_PSMR_FC ((uint)0x40000000) /* Force Collision */ +#define FCC_PSMR_SBT ((uint)0x20000000) /* Stop backoff timer */ +#define FCC_PSMR_LPB ((uint)0x10000000) /* Local protect. 1 = FDX */ +#define FCC_PSMR_LCW ((uint)0x08000000) /* Late collision select */ +#define FCC_PSMR_FDE ((uint)0x04000000) /* Full Duplex Enable */ +#define FCC_PSMR_MON ((uint)0x02000000) /* RMON Enable */ +#define FCC_PSMR_PRO ((uint)0x00400000) /* Promiscuous Enable */ +#define FCC_PSMR_FCE ((uint)0x00200000) /* Flow Control Enable */ +#define FCC_PSMR_RSH ((uint)0x00100000) /* Receive Short Frames */ +#define FCC_PSMR_RMII ((uint)0x00020000) /* Use RMII interface */ +#define FCC_PSMR_CAM ((uint)0x00000400) /* CAM enable */ +#define FCC_PSMR_BRO ((uint)0x00000200) /* Broadcast pkt discard */ +#define FCC_PSMR_ENCRC ((uint)0x00000080) /* Use 32-bit CRC */ + +/* IIC parameter RAM. +*/ +typedef struct iic { + ushort iic_rbase; /* Rx Buffer descriptor base address */ + ushort iic_tbase; /* Tx Buffer descriptor base address */ + u_char iic_rfcr; /* Rx function code */ + u_char iic_tfcr; /* Tx function code */ + ushort iic_mrblr; /* Max receive buffer length */ + uint iic_rstate; /* Internal */ + uint iic_rdp; /* Internal */ + ushort iic_rbptr; /* Internal */ + ushort iic_rbc; /* Internal */ + uint iic_rxtmp; /* Internal */ + uint iic_tstate; /* Internal */ + uint iic_tdp; /* Internal */ + ushort iic_tbptr; /* Internal */ + ushort iic_tbc; /* Internal */ + uint iic_txtmp; /* Internal */ +} iic_t; + +/* SPI parameter RAM. +*/ +typedef struct spi { + ushort spi_rbase; /* Rx Buffer descriptor base address */ + ushort spi_tbase; /* Tx Buffer descriptor base address */ + u_char spi_rfcr; /* Rx function code */ + u_char spi_tfcr; /* Tx function code */ + ushort spi_mrblr; /* Max receive buffer length */ + uint spi_rstate; /* Internal */ + uint spi_rdp; /* Internal */ + ushort spi_rbptr; /* Internal */ + ushort spi_rbc; /* Internal */ + uint spi_rxtmp; /* Internal */ + uint spi_tstate; /* Internal */ + uint spi_tdp; /* Internal */ + ushort spi_tbptr; /* Internal */ + ushort spi_tbc; /* Internal */ + uint spi_txtmp; /* Internal */ + uint spi_res; /* Tx temp. */ + uint spi_res1[4]; /* SDMA temp. */ +} spi_t; + +/* SPI Mode register. +*/ +#define SPMODE_LOOP ((ushort)0x4000) /* Loopback */ +#define SPMODE_CI ((ushort)0x2000) /* Clock Invert */ +#define SPMODE_CP ((ushort)0x1000) /* Clock Phase */ +#define SPMODE_DIV16 ((ushort)0x0800) /* BRG/16 mode */ +#define SPMODE_REV ((ushort)0x0400) /* Reversed Data */ +#define SPMODE_MSTR ((ushort)0x0200) /* SPI Master */ +#define SPMODE_EN ((ushort)0x0100) /* Enable */ +#define SPMODE_LENMSK ((ushort)0x00f0) /* character length */ +#define SPMODE_PMMSK ((ushort)0x000f) /* prescale modulus */ + +#define SPMODE_LEN(x) ((((x)-1)&0xF)<<4) +#define SPMODE_PM(x) ((x) &0xF) + +/* SPI Event/Mask register. +*/ +#define SPI_EMASK 0x37 /* Event Mask */ +#define SPI_MME 0x20 /* Multi-Master Error */ +#define SPI_TXE 0x10 /* Transmit Error */ +#define SPI_BSY 0x04 /* Busy */ +#define SPI_TXB 0x02 /* Tx Buffer Empty */ +#define SPI_RXB 0x01 /* RX Buffer full/closed */ + +#define SPI_STR 0x80 /* SPCOM: Start transmit */ + +#define SPI_EB ((u_char)0x10) /* big endian byte order */ + +#define BD_IIC_START ((ushort)0x0400) + +#endif /* __CPM_82XX__ */ diff --git a/arch/powerpc/include/asm/immap_8260.h b/arch/powerpc/include/asm/immap_8260.h new file mode 100644 index 0000000000..c7021a7095 --- /dev/null +++ b/arch/powerpc/include/asm/immap_8260.h @@ -0,0 +1,604 @@ +/* + * MPC8260 Internal Memory Map + * Copyright (c) 1999 Dan Malek (dmalek@jlc.net) + * + * The Internal Memory Map of the 8260. I don't know how generic + * this will be, as I don't have any knowledge of the subsequent + * parts at this time. I copied this from the 8xx_immap.h. + */ +#ifndef __IMMAP_82XX__ +#define __IMMAP_82XX__ + +/* System configuration registers. +*/ +typedef struct sys_conf { + uint sc_siumcr; + uint sc_sypcr; + char res1[6]; + ushort sc_swsr; + char res2[20]; + uint sc_bcr; + u_char sc_ppc_acr; + char res3[3]; + uint sc_ppc_alrh; + uint sc_ppc_alrl; + u_char sc_lcl_acr; + char res4[3]; + uint sc_lcl_alrh; + uint sc_lcl_alrl; + uint sc_tescr1; + uint sc_tescr2; + uint sc_ltescr1; + uint sc_ltescr2; + uint sc_pdtea; + u_char sc_pdtem; + char res5[3]; + uint sc_ldtea; + u_char sc_ldtem; + char res6[163]; +} sysconf8260_t; + + +/* Memory controller registers. +*/ +typedef struct mem_ctlr { + uint memc_br0; + uint memc_or0; + uint memc_br1; + uint memc_or1; + uint memc_br2; + uint memc_or2; + uint memc_br3; + uint memc_or3; + uint memc_br4; + uint memc_or4; + uint memc_br5; + uint memc_or5; + uint memc_br6; + uint memc_or6; + uint memc_br7; + uint memc_or7; + uint memc_br8; + uint memc_or8; + uint memc_br9; + uint memc_or9; + uint memc_br10; + uint memc_or10; + uint memc_br11; + uint memc_or11; + char res1[8]; + uint memc_mar; + char res2[4]; + uint memc_mamr; + uint memc_mbmr; + uint memc_mcmr; + char res3[8]; + ushort memc_mptpr; + char res4[2]; + uint memc_mdr; + char res5[4]; + uint memc_psdmr; + uint memc_lsdmr; + u_char memc_purt; + char res6[3]; + u_char memc_psrt; + char res7[3]; + u_char memc_lurt; + char res8[3]; + u_char memc_lsrt; + char res9[3]; + uint memc_immr; + uint memc_pcibr0; + uint memc_pcibr1; + char res10[16]; + uint memc_pcimsk0; + uint memc_pcimsk1; + char res11[52]; +} memctl8260_t; + +/* System Integration Timers. +*/ +typedef struct sys_int_timers { + char res1[32]; + ushort sit_tmcntsc; + char res2[2]; + uint sit_tmcnt; + char res3[4]; + uint sit_tmcntal; + char res4[16]; + ushort sit_piscr; + char res5[2]; + uint sit_pitc; + uint sit_pitr; + char res6[94]; + char res7[390]; +} sit8260_t; + +/* PCI + */ +typedef struct pci_config { + uint pci_omisr; + uint pci_ominr; + char res1[8]; + uint pci_ifqpr; + uint pci_ofqpr; + char res2[8]; + uint pci_imr0; + uint pci_imr1; + uint pci_omr0; + uint pci_omr1; + uint pci_odr; + char res3[4]; + uint pci_idr; + char res4[20]; + uint pci_imisr; + uint pci_imimr; + char res5[24]; + uint pci_ifhpr; + char res5_2[4]; + uint pci_iftpr; + char res6[4]; + uint pci_iphpr; + char res6_2[4]; + uint pci_iptpr; + char res7[4]; + uint pci_ofhpr; + char res7_2[4]; + uint pci_oftpr; + char res8[4]; + uint pci_ophpr; + char res8_2[4]; + uint pci_optpr; + char res9[8]; + uint pci_mucr; + char res10[8]; + uint pci_qbar; + char res11[12]; + uint pci_dmamr0; + uint pci_dmasr0; + uint pci_dmacdar0; + char res12[4]; + uint pci_dmasar0; + char res13[4]; + uint pci_dmadar0; + char res14[4]; + uint pci_dmabcr0; + uint pci_dmandar0; + char res15[88]; + uint pci_dmamr1; + uint pci_dmasr1; + uint pci_dmacdar1; + char res16[4]; + uint pci_dmasar1; + char res17[4]; + uint pci_dmadar1; + char res18[4]; + uint pci_dmabcr1; + uint pci_dmandar1; + char res19[88]; + uint pci_dmamr2; + uint pci_dmasr2; + uint pci_dmacdar2; + char res20[4]; + uint pci_dmasar2; + char res21[4]; + uint pci_dmadar2; + char res22[4]; + uint pci_dmabcr2; + uint pci_dmandar2; + char res23[88]; + uint pci_dmamr3; + uint pci_dmasr3; + uint pci_dmacdar3; + char res24[4]; + uint pci_dmasar3; + char res25[4]; + uint pci_dmadar3; + char res26[4]; + uint pci_dmabcr3; + uint pci_dmandar3; + char res27[344]; + uint pci_potar0; + char res28[4]; + uint pci_pobar0; + char res29[4]; + uint pci_pocmr0; + char res30[4]; + uint pci_potar1; + char res31[4]; + uint pci_pobar1; + char res32[4]; + uint pci_pocmr1; + char res33[4]; + uint pci_potar2; + char res34[4]; + uint pci_pobar2; + char res35[4]; + uint pci_pocmr2; + char res36[52]; + uint pci_ptcr; + uint pci_gpcr; + uint pci_gcr; + uint pci_esr; + uint pci_emr; + uint pci_ecr; + uint pci_eacr; + char res37[4]; + uint pci_edcr; + char res38[4]; + uint pci_eccr; + char res39[44]; + uint pci_pitar1; + char res40[4]; + uint pci_pibar1; + char res41[4]; + uint pci_picmr1; + char res42[4]; + uint pci_pitar0; + char res43[4]; + uint pci_pibar0; + char res44[4]; + uint pci_picmr0; + char res45[4]; + uint pci_cfg_addr; + uint pci_cfg_data; + uint pci_int_ack; + char res46[756]; +}pci8260_t; +#define PISCR_PIRQ_MASK ((ushort)0xff00) +#define PISCR_PS ((ushort)0x0080) +#define PISCR_PIE ((ushort)0x0004) +#define PISCR_PTF ((ushort)0x0002) +#define PISCR_PTE ((ushort)0x0001) + +/* Interrupt Controller. +*/ +typedef struct interrupt_controller { + ushort ic_sicr; + char res1[2]; + uint ic_sivec; + uint ic_sipnrh; + uint ic_sipnrl; + uint ic_siprr; + uint ic_scprrh; + uint ic_scprrl; + uint ic_simrh; + uint ic_simrl; + uint ic_siexr; + char res2[88]; +} intctl8260_t; + +/* Clocks and Reset. +*/ +typedef struct clk_and_reset { + uint car_sccr; + char res1[4]; + uint car_scmr; + char res2[4]; + uint car_rsr; + uint car_rmr; + char res[104]; +} car8260_t; + +/* Input/Output Port control/status registers. + * Names consistent with processor manual, although they are different + * from the original 8xx names....... + */ +typedef struct io_port { + uint iop_pdira; + uint iop_ppara; + uint iop_psora; + uint iop_podra; + uint iop_pdata; + char res1[12]; + uint iop_pdirb; + uint iop_pparb; + uint iop_psorb; + uint iop_podrb; + uint iop_pdatb; + char res2[12]; + uint iop_pdirc; + uint iop_pparc; + uint iop_psorc; + uint iop_podrc; + uint iop_pdatc; + char res3[12]; + uint iop_pdird; + uint iop_ppard; + uint iop_psord; + uint iop_podrd; + uint iop_pdatd; + char res4[12]; +} iop8260_t; + +/* Communication Processor Module Timers +*/ +typedef struct cpm_timers { + u_char cpmt_tgcr1; + char res1[3]; + u_char cpmt_tgcr2; + char res2[11]; + ushort cpmt_tmr1; + ushort cpmt_tmr2; + ushort cpmt_trr1; + ushort cpmt_trr2; + ushort cpmt_tcr1; + ushort cpmt_tcr2; + ushort cpmt_tcn1; + ushort cpmt_tcn2; + ushort cpmt_tmr3; + ushort cpmt_tmr4; + ushort cpmt_trr3; + ushort cpmt_trr4; + ushort cpmt_tcr3; + ushort cpmt_tcr4; + ushort cpmt_tcn3; + ushort cpmt_tcn4; + ushort cpmt_ter1; + ushort cpmt_ter2; + ushort cpmt_ter3; + ushort cpmt_ter4; + char res3[584]; +} cpmtimer8260_t; + +/* DMA control/status registers. +*/ +typedef struct sdma_csr { + char res0[24]; + u_char sdma_sdsr; + char res1[3]; + u_char sdma_sdmr; + char res2[3]; + u_char sdma_idsr1; + char res3[3]; + u_char sdma_idmr1; + char res4[3]; + u_char sdma_idsr2; + char res5[3]; + u_char sdma_idmr2; + char res6[3]; + u_char sdma_idsr3; + char res7[3]; + u_char sdma_idmr3; + char res8[3]; + u_char sdma_idsr4; + char res9[3]; + u_char sdma_idmr4; + char res10[707]; +} sdma8260_t; + +/* Fast controllers +*/ +typedef struct fcc { + uint fcc_gfmr; + uint fcc_fpsmr; + ushort fcc_ftodr; + char res1[2]; + ushort fcc_fdsr; + char res2[2]; + ushort fcc_fcce; + char res3[2]; + ushort fcc_fccm; + char res4[2]; + u_char fcc_fccs; + char res5[3]; + u_char fcc_ftirr_phy[4]; +} fcc_t; + +/* Fast controllers continued + */ +typedef struct fcc_c { + uint fcc_firper; + uint fcc_firer; + uint fcc_firsr_hi; + uint fcc_firsr_lo; + u_char fcc_gfemr; + char res1[15]; +} fcc_c_t; + +/* TC Layer + */ +typedef struct tclayer { + ushort tc_tcmode; + ushort tc_cdsmr; + ushort tc_tcer; + ushort tc_rcc; + ushort tc_tcmr; + ushort tc_fcc; + ushort tc_ccc; + ushort tc_icc; + ushort tc_tcc; + ushort tc_ecc; + char res1[12]; +} tclayer_t; + +/* I2C +*/ +typedef struct i2c { + u_char i2c_i2mod; + char res1[3]; + u_char i2c_i2add; + char res2[3]; + u_char i2c_i2brg; + char res3[3]; + u_char i2c_i2com; + char res4[3]; + u_char i2c_i2cer; + char res5[3]; + u_char i2c_i2cmr; + char res6[331]; +} i2c8260_t; + +typedef struct scc { /* Serial communication channels */ + uint scc_gsmrl; + uint scc_gsmrh; + ushort scc_psmr; + char res1[2]; + ushort scc_todr; + ushort scc_dsr; + ushort scc_scce; + char res2[2]; + ushort scc_sccm; + char res3; + u_char scc_sccs; + char res4[8]; +} scc_t; + +typedef struct smc { /* Serial management channels */ + char res1[2]; + ushort smc_smcmr; + char res2[2]; + u_char smc_smce; + char res3[3]; + u_char smc_smcm; + char res4[5]; +} smc_t; + +/* Serial Peripheral Interface. +*/ +typedef struct im_spi { + ushort spi_spmode; + char res1[4]; + u_char spi_spie; + char res2[3]; + u_char spi_spim; + char res3[2]; + u_char spi_spcom; + char res4[82]; +} im_spi_t; + +/* CPM Mux. +*/ +typedef struct cpmux { + u_char cmx_si1cr; + char res1; + u_char cmx_si2cr; + char res2; + uint cmx_fcr; + uint cmx_scr; + u_char cmx_smr; + char res3; + ushort cmx_uar; + char res4[16]; +} cpmux_t; + +/* SIRAM control +*/ +typedef struct siram { + ushort si_amr; + ushort si_bmr; + ushort si_cmr; + ushort si_dmr; + u_char si_gmr; + char res1; + u_char si_cmdr; + char res2; + u_char si_str; + char res3; + ushort si_rsr; +} siramctl_t; + +typedef struct mcc { + ushort mcc_mcce; + char res1[2]; + ushort mcc_mccm; + char res2[2]; + u_char mcc_mccf; + char res3[7]; +} mcc_t; + +typedef struct comm_proc { + uint cp_cpcr; + uint cp_rccr; + char res1[14]; + ushort cp_rter; + char res2[2]; + ushort cp_rtmr; + ushort cp_rtscr; + char res3[2]; + uint cp_rtsr; + char res4[12]; +} cpm8260_t; + +/* ...and the whole thing wrapped up.... +*/ +typedef struct immap { + /* Some references are into the unique and known dpram spaces, + * others are from the generic base. + */ + union { + struct { + u_char im_dpram1[16 * 1024]; + char res1[16 * 1024]; + u_char im_dpram2[4 * 1024]; + char res2[8 * 1024]; + u_char im_dpram3[4 * 1024]; + char res3[16 * 1024]; + }; + u8 im_dprambase[64 * 1024]; + u16 im_dprambase16[32 * 1024]; + }; + + sysconf8260_t im_siu_conf; /* SIU Configuration */ + memctl8260_t im_memctl; /* Memory Controller */ + sit8260_t im_sit; /* System Integration Timers */ + pci8260_t im_pci; /* PCI Configuration */ + intctl8260_t im_intctl; /* Interrupt Controller */ + car8260_t im_clkrst; /* Clocks and reset */ + iop8260_t im_ioport; /* IO Port control/status */ + cpmtimer8260_t im_cpmtimer; /* CPM timers */ + sdma8260_t im_sdma; /* SDMA control/status */ + + fcc_t im_fcc[3]; /* Three FCCs */ + + char res4[32]; + fcc_c_t im_fcc_c[3]; /* Continued FCCs */ + char res4a[32]; + + tclayer_t im_tclayer[8]; /* Eight TCLayers */ + ushort tc_tcgsr; + ushort tc_tcger; + + /* First set of baud rate generators. + */ + char res4b[236]; + uint im_brgc5; + uint im_brgc6; + uint im_brgc7; + uint im_brgc8; + + char res5[608]; + + i2c8260_t im_i2c; /* I2C control/status */ + cpm8260_t im_cpm; /* Communication processor */ + + /* Second set of baud rate generators. + */ + uint im_brgc1; + uint im_brgc2; + uint im_brgc3; + uint im_brgc4; + + scc_t im_scc[4]; /* Four SCCs */ + smc_t im_smc[2]; /* Couple of SMCs */ + im_spi_t im_spi; /* A SPI */ + cpmux_t im_cpmux; /* CPM clock route mux */ + siramctl_t im_siramctl1; /* First SI RAM Control */ + mcc_t im_mcc1; /* First MCC */ + siramctl_t im_siramctl2; /* Second SI RAM Control */ + mcc_t im_mcc2; /* Second MCC */ + + char res6[1184]; + + ushort im_si1txram[256]; + char res7[512]; + ushort im_si1rxram[256]; + char res8[512]; + ushort im_si2txram[256]; + char res9[512]; + ushort im_si2rxram[256]; + char res10[512]; + char res11[4096]; +} immap_t; + +#endif /* __IMMAP_82XX__ */ diff --git a/arch/powerpc/include/asm/iopin_8260.h b/arch/powerpc/include/asm/iopin_8260.h new file mode 100644 index 0000000000..617584d7c7 --- /dev/null +++ b/arch/powerpc/include/asm/iopin_8260.h @@ -0,0 +1,168 @@ +/* + * MPC8260 I/O port pin manipulation functions + */ + +#ifndef _ASM_IOPIN_8260_H_ +#define _ASM_IOPIN_8260_H_ + +#include <linux/types.h> +#include <asm/immap_8260.h> + +#ifdef __KERNEL__ + +typedef + struct { + u_char port:2; /* port number (A=0, B=1, C=2, D=3) */ + u_char pin:5; /* port pin (0-31) */ + u_char flag:1; /* for whatever */ + } +iopin_t; + +#define IOPIN_PORTA 0 +#define IOPIN_PORTB 1 +#define IOPIN_PORTC 2 +#define IOPIN_PORTD 3 + +static __inline__ void +iopin_set_high(iopin_t *iopin) +{ + volatile uint *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pdata; + datp[iopin->port * 8] |= (1 << (31 - iopin->pin)); +} + +static __inline__ void +iopin_set_low(iopin_t *iopin) +{ + volatile uint *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pdata; + datp[iopin->port * 8] &= ~(1 << (31 - iopin->pin)); +} + +static __inline__ uint +iopin_is_high(iopin_t *iopin) +{ + volatile uint *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pdata; + return (datp[iopin->port * 8] >> (31 - iopin->pin)) & 1; +} + +static __inline__ uint +iopin_is_low(iopin_t *iopin) +{ + volatile uint *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pdata; + return ((datp[iopin->port * 8] >> (31 - iopin->pin)) & 1) ^ 1; +} + +static __inline__ void +iopin_set_out(iopin_t *iopin) +{ + volatile uint *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pdira; + dirp[iopin->port * 8] |= (1 << (31 - iopin->pin)); +} + +static __inline__ void +iopin_set_in(iopin_t *iopin) +{ + volatile uint *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pdira; + dirp[iopin->port * 8] &= ~(1 << (31 - iopin->pin)); +} + +static __inline__ uint +iopin_is_out(iopin_t *iopin) +{ + volatile uint *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pdira; + return (dirp[iopin->port * 8] >> (31 - iopin->pin)) & 1; +} + +static __inline__ uint +iopin_is_in(iopin_t *iopin) +{ + volatile uint *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pdira; + return ((dirp[iopin->port * 8] >> (31 - iopin->pin)) & 1) ^ 1; +} + +static __inline__ void +iopin_set_odr(iopin_t *iopin) +{ + volatile uint *odrp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_podra; + odrp[iopin->port * 8] |= (1 << (31 - iopin->pin)); +} + +static __inline__ void +iopin_set_act(iopin_t *iopin) +{ + volatile uint *odrp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_podra; + odrp[iopin->port * 8] &= ~(1 << (31 - iopin->pin)); +} + +static __inline__ uint +iopin_is_odr(iopin_t *iopin) +{ + volatile uint *odrp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_podra; + return (odrp[iopin->port * 8] >> (31 - iopin->pin)) & 1; +} + +static __inline__ uint +iopin_is_act(iopin_t *iopin) +{ + volatile uint *odrp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_podra; + return ((odrp[iopin->port * 8] >> (31 - iopin->pin)) & 1) ^ 1; +} + +static __inline__ void +iopin_set_ded(iopin_t *iopin) +{ + volatile uint *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_ppara; + parp[iopin->port * 8] |= (1 << (31 - iopin->pin)); +} + +static __inline__ void +iopin_set_gen(iopin_t *iopin) +{ + volatile uint *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_ppara; + parp[iopin->port * 8] &= ~(1 << (31 - iopin->pin)); +} + +static __inline__ uint +iopin_is_ded(iopin_t *iopin) +{ + volatile uint *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_ppara; + return (parp[iopin->port * 8] >> (31 - iopin->pin)) & 1; +} + +static __inline__ uint +iopin_is_gen(iopin_t *iopin) +{ + volatile uint *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_ppara; + return ((parp[iopin->port * 8] >> (31 - iopin->pin)) & 1) ^ 1; +} + +static __inline__ void +iopin_set_opt2(iopin_t *iopin) +{ + volatile uint *sorp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_psora; + sorp[iopin->port * 8] |= (1 << (31 - iopin->pin)); +} + +static __inline__ void +iopin_set_opt1(iopin_t *iopin) +{ + volatile uint *sorp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_psora; + sorp[iopin->port * 8] &= ~(1 << (31 - iopin->pin)); +} + +static __inline__ uint +iopin_is_opt2(iopin_t *iopin) +{ + volatile uint *sorp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_psora; + return (sorp[iopin->port * 8] >> (31 - iopin->pin)) & 1; +} + +static __inline__ uint +iopin_is_opt1(iopin_t *iopin) +{ + volatile uint *sorp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_psora; + return ((sorp[iopin->port * 8] >> (31 - iopin->pin)) & 1) ^ 1; +} + +#endif /* __KERNEL__ */ + +#endif /* _ASM_IOPIN_8260_H_ */ diff --git a/arch/powerpc/include/asm/m8260_pci.h b/arch/powerpc/include/asm/m8260_pci.h new file mode 100644 index 0000000000..6daca4f99b --- /dev/null +++ b/arch/powerpc/include/asm/m8260_pci.h @@ -0,0 +1,165 @@ +#ifndef _PPC_KERNEL_M8260_PCI_H +#define _PPC_KERNEL_M8260_PCI_H + +#define M8265_PCIBR0 0x101ac +#define M8265_PCIBR1 0x101b0 +#define M8265_PCIMSK0 0x101c4 +#define M8265_PCIMSK1 0x101c8 + +/* Bit definitions for PCIBR registers */ + +#define PCIBR_ENABLE 0x00000001 + +/* Bit definitions for PCIMSK registers */ + +#define PCIMSK_32KB 0xFFFF8000 /* Size of window, smallest */ +#define PCIMSK_64KB 0xFFFF0000 +#define PCIMSK_128KB 0xFFFE0000 +#define PCIMSK_256KB 0xFFFC0000 +#define PCIMSK_512KB 0xFFF80000 +#define PCIMSK_1MB 0xFFF00000 +#define PCIMSK_2MB 0xFFE00000 +#define PCIMSK_4MB 0xFFC00000 +#define PCIMSK_8MB 0xFF800000 +#define PCIMSK_16MB 0xFF000000 +#define PCIMSK_32MB 0xFE000000 +#define PCIMSK_64MB 0xFC000000 +#define PCIMSK_128MB 0xF8000000 +#define PCIMSK_256MB 0xF0000000 +#define PCIMSK_512MB 0xE0000000 +#define PCIMSK_1GB 0xC0000000 /* Size of window, largest */ + + +#define M826X_SCCR_PCI_MODE_EN 0x100 + + +/* + * Outbound ATU registers (3 sets). These registers control how 60x bus (local) + * addresses are translated to PCI addresses when the MPC826x is a PCI bus + * master (initiator). + */ + +#define POTAR_REG0 0x10800 /* PCI Outbound Translation Addr registers */ +#define POTAR_REG1 0x10818 +#define POTAR_REG2 0x10830 + +#define POBAR_REG0 0x10808 /* PCI Outbound Base Addr registers */ +#define POBAR_REG1 0x10820 +#define POBAR_REG2 0x10838 + +#define POCMR_REG0 0x10810 /* PCI Outbound Comparison Mask registers */ +#define POCMR_REG1 0x10828 +#define POCMR_REG2 0x10840 + +/* Bit definitions for POMCR registers */ + +#define POCMR_MASK_4KB 0x000FFFFF +#define POCMR_MASK_8KB 0x000FFFFE +#define POCMR_MASK_16KB 0x000FFFFC +#define POCMR_MASK_32KB 0x000FFFF8 +#define POCMR_MASK_64KB 0x000FFFF0 +#define POCMR_MASK_128KB 0x000FFFE0 +#define POCMR_MASK_256KB 0x000FFFC0 +#define POCMR_MASK_512KB 0x000FFF80 +#define POCMR_MASK_1MB 0x000FFF00 +#define POCMR_MASK_2MB 0x000FFE00 +#define POCMR_MASK_4MB 0x000FFC00 +#define POCMR_MASK_8MB 0x000FF800 +#define POCMR_MASK_16MB 0x000FF000 +#define POCMR_MASK_32MB 0x000FE000 +#define POCMR_MASK_64MB 0x000FC000 +#define POCMR_MASK_128MB 0x000F8000 +#define POCMR_MASK_256MB 0x000F0000 +#define POCMR_MASK_512MB 0x000E0000 +#define POCMR_MASK_1GB 0x000C0000 + +#define POCMR_ENABLE 0x80000000 +#define POCMR_PCI_IO 0x40000000 +#define POCMR_PREFETCH_EN 0x20000000 + +/* Soft PCI reset */ + +#define PCI_GCR_REG 0x10880 + +/* Bit definitions for PCI_GCR registers */ + +#define PCIGCR_PCI_BUS_EN 0x1 + +/* + * Inbound ATU registers (2 sets). These registers control how PCI addresses + * are translated to 60x bus (local) addresses when the MPC826x is a PCI bus target. + */ + +#define PITAR_REG1 0x108D0 +#define PIBAR_REG1 0x108D8 +#define PICMR_REG1 0x108E0 +#define PITAR_REG0 0x108E8 +#define PIBAR_REG0 0x108F0 +#define PICMR_REG0 0x108F8 + +/* Bit definitions for PCI Inbound Comparison Mask registers */ + +#define PICMR_MASK_4KB 0x000FFFFF +#define PICMR_MASK_8KB 0x000FFFFE +#define PICMR_MASK_16KB 0x000FFFFC +#define PICMR_MASK_32KB 0x000FFFF8 +#define PICMR_MASK_64KB 0x000FFFF0 +#define PICMR_MASK_128KB 0x000FFFE0 +#define PICMR_MASK_256KB 0x000FFFC0 +#define PICMR_MASK_512KB 0x000FFF80 +#define PICMR_MASK_1MB 0x000FFF00 +#define PICMR_MASK_2MB 0x000FFE00 +#define PICMR_MASK_4MB 0x000FFC00 +#define PICMR_MASK_8MB 0x000FF800 +#define PICMR_MASK_16MB 0x000FF000 +#define PICMR_MASK_32MB 0x000FE000 +#define PICMR_MASK_64MB 0x000FC000 +#define PICMR_MASK_128MB 0x000F8000 +#define PICMR_MASK_256MB 0x000F0000 +#define PICMR_MASK_512MB 0x000E0000 +#define PICMR_MASK_1GB 0x000C0000 + +#define PICMR_ENABLE 0x80000000 +#define PICMR_NO_SNOOP_EN 0x40000000 +#define PICMR_PREFETCH_EN 0x20000000 + +/* PCI error Registers */ + +#define PCI_ERROR_STATUS_REG 0x10884 +#define PCI_ERROR_MASK_REG 0x10888 +#define PCI_ERROR_CONTROL_REG 0x1088C +#define PCI_ERROR_ADRS_CAPTURE_REG 0x10890 +#define PCI_ERROR_DATA_CAPTURE_REG 0x10898 +#define PCI_ERROR_CTRL_CAPTURE_REG 0x108A0 + +/* PCI error Register bit defines */ + +#define PCI_ERROR_PCI_ADDR_PAR 0x00000001 +#define PCI_ERROR_PCI_DATA_PAR_WR 0x00000002 +#define PCI_ERROR_PCI_DATA_PAR_RD 0x00000004 +#define PCI_ERROR_PCI_NO_RSP 0x00000008 +#define PCI_ERROR_PCI_TAR_ABT 0x00000010 +#define PCI_ERROR_PCI_SERR 0x00000020 +#define PCI_ERROR_PCI_PERR_RD 0x00000040 +#define PCI_ERROR_PCI_PERR_WR 0x00000080 +#define PCI_ERROR_I2O_OFQO 0x00000100 +#define PCI_ERROR_I2O_IPQO 0x00000200 +#define PCI_ERROR_IRA 0x00000400 +#define PCI_ERROR_NMI 0x00000800 +#define PCI_ERROR_I2O_DBMC 0x00001000 + +/* + * Register pair used to generate configuration cycles on the PCI bus + * and access the MPC826x's own PCI configuration registers. + */ + +#define PCI_CFG_ADDR_REG 0x10900 +#define PCI_CFG_DATA_REG 0x10904 + +/* Bus parking decides where the bus control sits when idle */ +/* If modifying memory controllers for PCI park on the core */ + +#define PPC_ACR_BUS_PARK_CORE 0x6 +#define PPC_ACR_BUS_PARK_PCI 0x3 + +#endif /* _PPC_KERNEL_M8260_PCI_H */ diff --git a/arch/powerpc/include/asm/ppc.h b/arch/powerpc/include/asm/ppc.h index f23ed3e1b4..8abe727bca 100644 --- a/arch/powerpc/include/asm/ppc.h +++ b/arch/powerpc/include/asm/ppc.h @@ -19,6 +19,11 @@ #include <mpc5xxx.h> #elif defined(CONFIG_MPC512X) #include <asm/immap_512x.h> +#elif defined(CONFIG_MPC8260) +#if defined(CONFIG_MPC8247) || defined(CONFIG_MPC8272) +#define CONFIG_MPC8272_FAMILY 1 +#endif +#include <asm/immap_8260.h> #endif #ifdef CONFIG_MPC86xx #include <mpc86xx.h> diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 6549a0936f..aaabae0401 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -1364,6 +1364,9 @@ int prt_8260_clks(void); #if defined(CONFIG_WALNUT) #define _machine _MACH_walnut #define have_of 0 +#elif defined(CONFIG_MPC8260) +#define _machine _MACH_8260 +#define have_of 0 #else #error "Machine not defined correctly" #endif diff --git a/arch/powerpc/include/asm/status_led.h b/arch/powerpc/include/asm/status_led.h index 2767c05297..c151b54060 100644 --- a/arch/powerpc/include/asm/status_led.h +++ b/arch/powerpc/include/asm/status_led.h @@ -9,7 +9,9 @@
/* if not overridden */ #ifndef CONFIG_LED_STATUS_BOARD_SPECIFIC -# if defined(CONFIG_5xx) +# if defined(CONFIG_MPC8260) +# include <mpc8260.h> +# elif defined(CONFIG_5xx) # include <mpc5xx.h> # else # error CPU specific Status LED header file missing. diff --git a/arch/powerpc/lib/Kconfig b/arch/powerpc/lib/Kconfig new file mode 100644 index 0000000000..987cec99cb --- /dev/null +++ b/arch/powerpc/lib/Kconfig @@ -0,0 +1,8 @@ +config CMD_IMMAP + bool "Enable various commands to dump IMMR information" + help + This enables various commands such as: + + siuinfo - print System Interface Unit (SIU) registers + memcinfo - print Memory Controller registers + sitinfo - print System Integration Timers (SIT) registers diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 4dd6b56c14..5e55385e01 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_BAT_RW) += bat_rw.o obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-y += cache.o obj-y += extable.o +obj-$(CONFIG_CMD_IMMAP) += immap.o obj-y += interrupts.o obj-$(CONFIG_CMD_KGDB) += kgdb.o obj-y += stack.o diff --git a/arch/powerpc/lib/immap.c b/arch/powerpc/lib/immap.c new file mode 100644 index 0000000000..85527a1b8f --- /dev/null +++ b/arch/powerpc/lib/immap.c @@ -0,0 +1,629 @@ +/* + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * MPC8xx/MPC8260 Internal Memory Map Functions + */ + +#include <common.h> +#include <command.h> + +#if defined(CONFIG_MPC8260) + +#include <asm/immap_8260.h> +#include <asm/cpm_8260.h> +#include <asm/iopin_8260.h> + +DECLARE_GLOBAL_DATA_PTR; + +static void +unimplemented ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + printf ("Sorry, but the '%s' command has not been implemented\n", + cmdtp->name); +} + +int +do_siuinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; + +#if defined(CONFIG_MPC8260) + volatile sysconf8260_t *sc = &immap->im_siu_conf; +#endif + + printf ("SIUMCR= %08x SYPCR = %08x\n", sc->sc_siumcr, sc->sc_sypcr); +#if defined(CONFIG_MPC8260) + printf ("BCR = %08x\n", sc->sc_bcr); + printf ("P_ACR = %02x P_ALRH= %08x P_ALRL= %08x\n", + sc->sc_ppc_acr, sc->sc_ppc_alrh, sc->sc_ppc_alrl); + printf ("L_ACR = %02x L_ALRH= %08x L_ALRL= %08x\n", + sc->sc_lcl_acr, sc->sc_lcl_alrh, sc->sc_lcl_alrl); + printf ("PTESR1= %08x PTESR2= %08x\n", sc->sc_tescr1, sc->sc_tescr2); + printf ("LTESR1= %08x LTESR2= %08x\n", sc->sc_ltescr1, sc->sc_ltescr2); + printf ("PDTEA = %08x PDTEM = %02x\n", sc->sc_pdtea, sc->sc_pdtem); + printf ("LDTEA = %08x LDTEM = %02x\n", sc->sc_ldtea, sc->sc_ldtem); +#endif + return 0; +} + +int +do_memcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; + +#if defined(CONFIG_MPC8260) + volatile memctl8260_t *memctl = &immap->im_memctl; + int nbanks = 12; +#endif + volatile uint *p = &memctl->memc_br0; + int i; + + for (i = 0; i < nbanks; i++, p += 2) { + if (i < 10) { + printf ("BR%d = %08x OR%d = %08x\n", + i, p[0], i, p[1]); + } else { + printf ("BR%d = %08x OR%d = %08x\n", + i, p[0], i, p[1]); + } + } + + printf ("MAR = %08x", memctl->memc_mar); +#if defined(CONFIG_MPC8260) + putc ('\n'); +#endif + printf ("MAMR = %08x MBMR = %08x", + memctl->memc_mamr, memctl->memc_mbmr); +#if defined(CONFIG_MPC8260) + printf (" MCMR = %08x\n", memctl->memc_mcmr); +#endif + printf ("MPTPR = %04x MDR = %08x\n", + memctl->memc_mptpr, memctl->memc_mdr); +#if defined(CONFIG_MPC8260) + printf ("PSDMR = %08x LSDMR = %08x\n", + memctl->memc_psdmr, memctl->memc_lsdmr); + printf ("PURT = %02x PSRT = %02x\n", + memctl->memc_purt, memctl->memc_psrt); + printf ("LURT = %02x LSRT = %02x\n", + memctl->memc_lurt, memctl->memc_lsrt); + printf ("IMMR = %08x\n", memctl->memc_immr); +#endif + return 0; +} + +int +do_sitinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unimplemented (cmdtp, flag, argc, argv); + return 0; +} + +#ifdef CONFIG_MPC8260 +int +do_icinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unimplemented (cmdtp, flag, argc, argv); + return 0; +} +#endif + +int +do_carinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; + +#if defined(CONFIG_MPC8260) + volatile car8260_t *car = &immap->im_clkrst; +#endif + +#if defined(CONFIG_MPC8260) + printf ("SCCR = %08x\n", car->car_sccr); + printf ("SCMR = %08x\n", car->car_scmr); + printf ("RSR = %08x\n", car->car_rsr); + printf ("RMR = %08x\n", car->car_rmr); +#endif + return 0; +} + +static int counter; + +static void +header(void) +{ + char *data = "\ + -------------------------------- --------------------------------\ + 00000000001111111111222222222233 00000000001111111111222222222233\ + 01234567890123456789012345678901 01234567890123456789012345678901\ + -------------------------------- --------------------------------\ + "; + int i; + + if (counter % 2) + putc('\n'); + counter = 0; + + for (i = 0; i < 4; i++, data += 79) + printf("%.79s\n", data); +} + +static void binary (char *label, uint value, int nbits) +{ + uint mask = 1 << (nbits - 1); + int i, second = (counter++ % 2); + + if (second) + putc (' '); + puts (label); + for (i = 32 + 1; i != nbits; i--) + putc (' '); + + while (mask != 0) { + if (value & mask) + putc ('1'); + else + putc ('0'); + mask >>= 1; + } + + if (second) + putc ('\n'); +} + +#if defined(CONFIG_MPC8260) +#define PA_NBITS 32 +#define PA_NB_ODR 32 +#define PB_NBITS 28 +#define PB_NB_ODR 28 +#define PC_NBITS 32 +#define PD_NBITS 28 +#endif + +int +do_iopinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; + +#if defined(CONFIG_MPC8260) + volatile iop8260_t *iop = &immap->im_ioport; + volatile uint *l, *r; +#endif + volatile uint *R; + + counter = 0; + header (); + + /* + * Ports A & B + */ + +#if defined(CONFIG_MPC8260) + l = &iop->iop_pdira; + R = &iop->iop_pdirb; +#endif + binary ("PA_DIR", *l++, PA_NBITS); + binary ("PB_DIR", *R++, PB_NBITS); + binary ("PA_PAR", *l++, PA_NBITS); + binary ("PB_PAR", *R++, PB_NBITS); +#if defined(CONFIG_MPC8260) + binary ("PA_SOR", *l++, PA_NBITS); + binary ("PB_SOR", *R++, PB_NBITS); +#endif + binary ("PA_ODR", *l++, PA_NB_ODR); + binary ("PB_ODR", *R++, PB_NB_ODR); + binary ("PA_DAT", *l++, PA_NBITS); + binary ("PB_DAT", *R++, PB_NBITS); + + header (); + + /* + * Ports C & D + */ + +#if defined(CONFIG_MPC8260) + l = &iop->iop_pdirc; + r = &iop->iop_pdird; +#endif + binary ("PC_DIR", *l++, PC_NBITS); + binary ("PD_DIR", *r++, PD_NBITS); + binary ("PC_PAR", *l++, PC_NBITS); + binary ("PD_PAR", *r++, PD_NBITS); +#if defined(CONFIG_MPC8260) + binary ("PC_SOR", *l++, PC_NBITS); + binary ("PD_SOR", *r++, PD_NBITS); + binary ("PC_ODR", *l++, PC_NBITS); + binary ("PD_ODR", *r++, PD_NBITS); +#endif + binary ("PC_DAT", *l++, PC_NBITS); + binary ("PD_DAT", *r++, PD_NBITS); + + header (); + return 0; +} + +/* + * set the io pins + * this needs a clean up for smaller tighter code + * use *uint and set the address based on cmd + port + */ +int +do_iopset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + uint rcode = 0; + iopin_t iopin; + static uint port = 0; + static uint pin = 0; + static uint value = 0; + static enum { + DIR, + PAR, + SOR, + ODR, + DAT, + } cmd = DAT; + + if (argc != 5) { + puts ("iopset PORT PIN CMD VALUE\n"); + return 1; + } + port = argv[1][0] - 'A'; + if (port > 3) + port -= 0x20; + if (port > 3) + rcode = 1; + pin = simple_strtol (argv[2], NULL, 10); + if (pin > 31) + rcode = 1; + + + switch (argv[3][0]) { + case 'd': + if (argv[3][1] == 'a') + cmd = DAT; + else if (argv[3][1] == 'i') + cmd = DIR; + else + rcode = 1; + break; + case 'p': + cmd = PAR; + break; + case 'o': + cmd = ODR; + break; + case 's': + cmd = SOR; + break; + default: + printf ("iopset: unknown command %s\n", argv[3]); + rcode = 1; + } + if (argv[4][0] == '1') + value = 1; + else if (argv[4][0] == '0') + value = 0; + else + rcode = 1; + if (rcode == 0) { + iopin.port = port; + iopin.pin = pin; + iopin.flag = 0; + switch (cmd) { + case DIR: + if (value) + iopin_set_out (&iopin); + else + iopin_set_in (&iopin); + break; + case PAR: + if (value) + iopin_set_ded (&iopin); + else + iopin_set_gen (&iopin); + break; + case SOR: + if (value) + iopin_set_opt2 (&iopin); + else + iopin_set_opt1 (&iopin); + break; + case ODR: + if (value) + iopin_set_odr (&iopin); + else + iopin_set_act (&iopin); + break; + case DAT: + if (value) + iopin_set_high (&iopin); + else + iopin_set_low (&iopin); + break; + } + + } + return rcode; +} + +int +do_dmainfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unimplemented (cmdtp, flag, argc, argv); + return 0; +} + +int +do_fccinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unimplemented (cmdtp, flag, argc, argv); + return 0; +} + +static void prbrg (int n, uint val) +{ + uint extc = (val >> 14) & 3; + uint cd = (val & CPM_BRG_CD_MASK) >> 1; + uint div16 = (val & CPM_BRG_DIV16) != 0; + +#if defined(CONFIG_MPC8260) + ulong clock = gd->arch.brg_clk; +#endif + + printf ("BRG%d:", n); + + if (val & CPM_BRG_RST) + puts (" RESET"); + else + puts (" "); + + if (val & CPM_BRG_EN) + puts (" ENABLED"); + else + puts (" DISABLED"); + + printf (" EXTC=%d", extc); + + if (val & CPM_BRG_ATB) + puts (" ATB"); + else + puts (" "); + + printf (" DIVIDER=%4d", cd); + if (extc == 0 && cd != 0) { + uint baudrate; + + if (div16) + baudrate = (clock / 16) / (cd + 1); + else + baudrate = clock / (cd + 1); + + printf ("=%6d bps", baudrate); + } else { + puts (" "); + } + + if (val & CPM_BRG_DIV16) + puts (" DIV16"); + else + puts (" "); + + putc ('\n'); +} + +int +do_brginfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; + +#if defined(CONFIG_MPC8260) + volatile uint *p = &immap->im_brgc1; +#endif + int i = 1; + + while (i <= 4) + prbrg (i++, *p++); + +#if defined(CONFIG_MPC8260) + p = &immap->im_brgc5; + while (i <= 8) + prbrg (i++, *p++); +#endif + return 0; +} + +int +do_i2cinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; + +#if defined(CONFIG_MPC8260) + volatile i2c8260_t *i2c = &immap->im_i2c; + volatile iic_t *iip; + uint dpaddr; + + dpaddr = immap->im_dprambase16[PROFF_I2C_BASE / sizeof(u16)]; + if (dpaddr == 0) + iip = NULL; + else + iip = (iic_t *) & immap->im_dprambase[dpaddr]; +#endif + + printf ("I2MOD = %02x I2ADD = %02x\n", i2c->i2c_i2mod, i2c->i2c_i2add); + printf ("I2BRG = %02x I2COM = %02x\n", i2c->i2c_i2brg, i2c->i2c_i2com); + printf ("I2CER = %02x I2CMR = %02x\n", i2c->i2c_i2cer, i2c->i2c_i2cmr); + + if (iip == NULL) + puts ("i2c parameter ram not allocated\n"); + else { + printf ("RBASE = %08x TBASE = %08x\n", + iip->iic_rbase, iip->iic_tbase); + printf ("RFCR = %02x TFCR = %02x\n", + iip->iic_rfcr, iip->iic_tfcr); + printf ("MRBLR = %04x\n", iip->iic_mrblr); + printf ("RSTATE= %08x RDP = %08x\n", + iip->iic_rstate, iip->iic_rdp); + printf ("RBPTR = %04x RBC = %04x\n", + iip->iic_rbptr, iip->iic_rbc); + printf ("RXTMP = %08x\n", iip->iic_rxtmp); + printf ("TSTATE= %08x TDP = %08x\n", + iip->iic_tstate, iip->iic_tdp); + printf ("TBPTR = %04x TBC = %04x\n", + iip->iic_tbptr, iip->iic_tbc); + printf ("TXTMP = %08x\n", iip->iic_txtmp); + } + return 0; +} + +int +do_sccinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unimplemented (cmdtp, flag, argc, argv); + return 0; +} + +int +do_smcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unimplemented (cmdtp, flag, argc, argv); + return 0; +} + +int +do_spiinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unimplemented (cmdtp, flag, argc, argv); + return 0; +} + +int +do_muxinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unimplemented (cmdtp, flag, argc, argv); + return 0; +} + +int +do_siinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unimplemented (cmdtp, flag, argc, argv); + return 0; +} + +int +do_mccinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unimplemented (cmdtp, flag, argc, argv); + return 0; +} + +/***************************************************/ + +U_BOOT_CMD( + siuinfo, 1, 1, do_siuinfo, + "print System Interface Unit (SIU) registers", + "" +); + +U_BOOT_CMD( + memcinfo, 1, 1, do_memcinfo, + "print Memory Controller registers", + "" +); + +U_BOOT_CMD( + sitinfo, 1, 1, do_sitinfo, + "print System Integration Timers (SIT) registers", + "" +); + +#ifdef CONFIG_MPC8260 +U_BOOT_CMD( + icinfo, 1, 1, do_icinfo, + "print Interrupt Controller registers", + "" +); +#endif + +U_BOOT_CMD( + carinfo, 1, 1, do_carinfo, + "print Clocks and Reset registers", + "" +); + +U_BOOT_CMD( + iopinfo, 1, 1, do_iopinfo, + "print I/O Port registers", + "" +); + +U_BOOT_CMD( + iopset, 5, 0, do_iopset, + "set I/O Port registers", + "PORT PIN CMD VALUE\nPORT: A-D, PIN: 0-31, CMD: [dat|dir|odr|sor], VALUE: 0|1" +); + +U_BOOT_CMD( + dmainfo, 1, 1, do_dmainfo, + "print SDMA/IDMA registers", + "" +); + +U_BOOT_CMD( + fccinfo, 1, 1, do_fccinfo, + "print FCC registers", + "" +); + +U_BOOT_CMD( + brginfo, 1, 1, do_brginfo, + "print Baud Rate Generator (BRG) registers", + "" +); + +U_BOOT_CMD( + i2cinfo, 1, 1, do_i2cinfo, + "print I2C registers", + "" +); + +U_BOOT_CMD( + sccinfo, 1, 1, do_sccinfo, + "print SCC registers", + "" +); + +U_BOOT_CMD( + smcinfo, 1, 1, do_smcinfo, + "print SMC registers", + "" +); + +U_BOOT_CMD( + spiinfo, 1, 1, do_spiinfo, + "print Serial Peripheral Interface (SPI) registers", + "" +); + +U_BOOT_CMD( + muxinfo, 1, 1, do_muxinfo, + "print CPM Multiplexing registers", + "" +); + +U_BOOT_CMD( + siinfo, 1, 1, do_siinfo, + "print Serial Interface (SI) registers", + "" +); + +U_BOOT_CMD( + mccinfo, 1, 1, do_mccinfo, + "print MCC registers", + "" +); + +#endif diff --git a/arch/powerpc/lib/kgdb.c b/arch/powerpc/lib/kgdb.c index 88c2af21eb..01a7708aef 100644 --- a/arch/powerpc/lib/kgdb.c +++ b/arch/powerpc/lib/kgdb.c @@ -159,6 +159,20 @@ kgdb_trap(struct pt_regs *regs)
#define SPACE_REQUIRED ((32*4)+(32*8)+(6*4))
+#ifdef CONFIG_MPC8260 +/* store floating double indexed */ +#define STFDI(n,p) __asm__ __volatile__ ("stfd " #n ",%0" : "=o"(p[2*n])) +/* store floating double multiple */ +#define STFDM(p) { STFDI( 0,p); STFDI( 1,p); STFDI( 2,p); STFDI( 3,p); \ + STFDI( 4,p); STFDI( 5,p); STFDI( 6,p); STFDI( 7,p); \ + STFDI( 8,p); STFDI( 9,p); STFDI(10,p); STFDI(11,p); \ + STFDI(12,p); STFDI(13,p); STFDI(14,p); STFDI(15,p); \ + STFDI(16,p); STFDI(17,p); STFDI(18,p); STFDI(19,p); \ + STFDI(20,p); STFDI(21,p); STFDI(22,p); STFDI(23,p); \ + STFDI(24,p); STFDI(25,p); STFDI(26,p); STFDI(27,p); \ + STFDI(28,p); STFDI(29,p); STFDI(30,p); STFDI(31,p); } +#endif + int kgdb_getregs(struct pt_regs *regs, char *buf, int max) { @@ -176,10 +190,15 @@ kgdb_getregs(struct pt_regs *regs, char *buf, int max) *ptr++ = regs->gpr[i];
/* Floating Point Regs */ +#ifdef CONFIG_MPC8260 + STFDM(ptr); + ptr += 32*2; +#else for (i = 0; i < 32; i++) { *ptr++ = 0; *ptr++ = 0; } +#endif
/* pc, msr, cr, lr, ctr, xer, (mq is unused) */ *ptr++ = regs->nip; @@ -193,6 +212,23 @@ kgdb_getregs(struct pt_regs *regs, char *buf, int max) }
/* set the value of the CPU registers */ + +#ifdef CONFIG_MPC8260 +/* load floating double */ +#define LFD(n,v) __asm__ __volatile__ ("lfd " #n ",%0" :: "o"(v)) +/* load floating double indexed */ +#define LFDI(n,p) __asm__ __volatile__ ("lfd " #n ",%0" :: "o"((p)[2*n])) +/* load floating double multiple */ +#define LFDM(p) { LFDI( 0,p); LFDI( 1,p); LFDI( 2,p); LFDI( 3,p); \ + LFDI( 4,p); LFDI( 5,p); LFDI( 6,p); LFDI( 7,p); \ + LFDI( 8,p); LFDI( 9,p); LFDI(10,p); LFDI(11,p); \ + LFDI(12,p); LFDI(13,p); LFDI(14,p); LFDI(15,p); \ + LFDI(16,p); LFDI(17,p); LFDI(18,p); LFDI(19,p); \ + LFDI(20,p); LFDI(21,p); LFDI(22,p); LFDI(23,p); \ + LFDI(24,p); LFDI(25,p); LFDI(26,p); LFDI(27,p); \ + LFDI(28,p); LFDI(29,p); LFDI(30,p); LFDI(31,p); } +#endif + void kgdb_putreg(struct pt_regs *regs, int regno, char *buf, int length) { @@ -215,6 +251,19 @@ kgdb_putreg(struct pt_regs *regs, int regno, char *buf, int length) if (regno >= 0 && regno < 32) regs->gpr[regno] = *ptr; else switch (regno) { + +#ifdef CONFIG_MPC8260 +#define caseF(n) \ + case (n) + 32: LFD(n, *ptr); break; + +caseF( 0) caseF( 1) caseF( 2) caseF( 3) caseF( 4) caseF( 5) caseF( 6) caseF( 7) +caseF( 8) caseF( 9) caseF(10) caseF(11) caseF(12) caseF(13) caseF(14) caseF(15) +caseF(16) caseF(17) caseF(18) caseF(19) caseF(20) caseF(21) caseF(22) caseF(23) +caseF(24) caseF(25) caseF(26) caseF(27) caseF(28) caseF(29) caseF(30) caseF(31) + +#undef caseF +#endif + case 64: regs->nip = *ptr; break; case 65: regs->msr = *ptr; break; case 66: regs->ccr = *ptr; break; @@ -249,6 +298,9 @@ kgdb_putregs(struct pt_regs *regs, char *buf, int length) regs->gpr[i] = *ptr++;
/* Floating Point Regs */ +#ifdef CONFIG_MPC8260 + LFDM(ptr); +#endif ptr += 32*2;
/* pc, msr, cr, lr, ctr, xer, (mq is unused) */ diff --git a/board/keymile/km82xx/Kconfig b/board/keymile/km82xx/Kconfig new file mode 100644 index 0000000000..c9a093ce02 --- /dev/null +++ b/board/keymile/km82xx/Kconfig @@ -0,0 +1,12 @@ +if TARGET_KM82XX + +config SYS_BOARD + default "km82xx" + +config SYS_VENDOR + default "keymile" + +config SYS_CONFIG_NAME + default "km82xx" + +endif diff --git a/board/keymile/km82xx/MAINTAINERS b/board/keymile/km82xx/MAINTAINERS new file mode 100644 index 0000000000..50e06b261c --- /dev/null +++ b/board/keymile/km82xx/MAINTAINERS @@ -0,0 +1,7 @@ +KM82XX BOARD +M: Holger Brunck holger.brunck@keymile.com +S: Maintained +F: board/keymile/km82xx/ +F: include/configs/km82xx.h +F: configs/mgcoge_defconfig +F: configs/mgcoge3ne_defconfig diff --git a/board/keymile/km82xx/Makefile b/board/keymile/km82xx/Makefile new file mode 100644 index 0000000000..20f193ab1d --- /dev/null +++ b/board/keymile/km82xx/Makefile @@ -0,0 +1,8 @@ +# +# (C) Copyright 2001-2007 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := km82xx.o ../common/common.o ../common/ivm.o diff --git a/board/keymile/km82xx/km82xx.c b/board/keymile/km82xx/km82xx.c new file mode 100644 index 0000000000..f5a98b33e7 --- /dev/null +++ b/board/keymile/km82xx/km82xx.c @@ -0,0 +1,463 @@ +/* + * (C) Copyright 2007 - 2008 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <mpc8260.h> +#include <ioports.h> +#include <malloc.h> +#include <asm/io.h> + +#include <libfdt.h> +#include <i2c.h> +#include "../common/common.h" + +DECLARE_GLOBAL_DATA_PTR; + +static uchar ivm_content[CONFIG_SYS_IVM_EEPROM_MAX_LEN]; + +/* + * I/O Port configuration table + * + * if conf is 1, then that port pin will be configured at boot time + * according to the five values podr/pdir/ppar/psor/pdat for that entry + */ +const iop_conf_t iop_conf_tab[4][32] = { + + /* Port A */ + { /* conf ppar psor pdir podr pdat */ + { 0, 0, 0, 0, 0, 0 }, /* PA31 */ + { 0, 0, 0, 0, 0, 0 }, /* PA30 */ + { 0, 0, 0, 0, 0, 0 }, /* PA29 */ + { 0, 0, 0, 0, 0, 0 }, /* PA28 */ + { 0, 0, 0, 0, 0, 0 }, /* PA27 */ + { 0, 0, 0, 0, 0, 0 }, /* PA26 */ + { 0, 0, 0, 0, 0, 0 }, /* PA25 */ + { 0, 0, 0, 0, 0, 0 }, /* PA24 */ + { 0, 0, 0, 0, 0, 0 }, /* PA23 */ + { 0, 0, 0, 0, 0, 0 }, /* PA22 */ + { 0, 0, 0, 0, 0, 0 }, /* PA21 */ + { 0, 0, 0, 0, 0, 0 }, /* PA20 */ + { 0, 0, 0, 0, 0, 0 }, /* PA19 */ + { 0, 0, 0, 0, 0, 0 }, /* PA18 */ + { 0, 0, 0, 0, 0, 0 }, /* PA17 */ + { 0, 0, 0, 0, 0, 0 }, /* PA16 */ + { 0, 0, 0, 0, 0, 0 }, /* PA15 */ + { 0, 0, 0, 0, 0, 0 }, /* PA14 */ + { 0, 0, 0, 0, 0, 0 }, /* PA13 */ + { 0, 0, 0, 0, 0, 0 }, /* PA12 */ + { 0, 0, 0, 0, 0, 0 }, /* PA11 */ + { 0, 0, 0, 0, 0, 0 }, /* PA10 */ + { 1, 1, 0, 1, 0, 0 }, /* PA9 SMC2 TxD */ + { 1, 1, 0, 0, 0, 0 }, /* PA8 SMC2 RxD */ + { 0, 0, 0, 0, 0, 0 }, /* PA7 */ + { 0, 0, 0, 0, 0, 0 }, /* PA6 */ + { 0, 0, 0, 0, 0, 0 }, /* PA5 */ + { 0, 0, 0, 0, 0, 0 }, /* PA4 */ + { 0, 0, 0, 0, 0, 0 }, /* PA3 */ + { 0, 0, 0, 0, 0, 0 }, /* PA2 */ + { 0, 0, 0, 0, 0, 0 }, /* PA1 */ + { 0, 0, 0, 0, 0, 0 } /* PA0 */ + }, + + /* Port B */ + { /* conf ppar psor pdir podr pdat */ + { 0, 0, 0, 0, 0, 0 }, /* PB31 */ + { 0, 0, 0, 0, 0, 0 }, /* PB30 */ + { 0, 0, 0, 0, 0, 0 }, /* PB29 */ + { 0, 0, 0, 0, 0, 0 }, /* PB28 */ + { 0, 0, 0, 0, 0, 0 }, /* PB27 */ + { 0, 0, 0, 0, 0, 0 }, /* PB26 */ + { 0, 0, 0, 0, 0, 0 }, /* PB25 */ + { 0, 0, 0, 0, 0, 0 }, /* PB24 */ + { 0, 0, 0, 0, 0, 0 }, /* PB23 */ + { 0, 0, 0, 0, 0, 0 }, /* PB22 */ + { 0, 0, 0, 0, 0, 0 }, /* PB21 */ + { 0, 0, 0, 0, 0, 0 }, /* PB20 */ + { 0, 0, 0, 0, 0, 0 }, /* PB19 */ + { 0, 0, 0, 0, 0, 0 }, /* PB18 */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 } /* non-existent */ + }, + + /* Port C */ + { /* conf ppar psor pdir podr pdat */ + { 0, 0, 0, 0, 0, 0 }, /* PC31 */ + { 0, 0, 0, 0, 0, 0 }, /* PC30 */ + { 0, 0, 0, 0, 0, 0 }, /* PC29 */ + { 0, 0, 0, 0, 0, 0 }, /* PC28 */ + { 0, 0, 0, 0, 0, 0 }, /* PC27 */ + { 0, 0, 0, 0, 0, 0 }, /* PC26 */ + { 1, 1, 0, 0, 0, 0 }, /* PC25 RxClk */ + { 1, 1, 0, 0, 0, 0 }, /* PC24 TxClk */ + { 0, 0, 0, 0, 0, 0 }, /* PC23 */ + { 0, 0, 0, 0, 0, 0 }, /* PC22 */ + { 0, 0, 0, 0, 0, 0 }, /* PC21 */ + { 0, 0, 0, 0, 0, 0 }, /* PC20 */ + { 0, 0, 0, 0, 0, 0 }, /* PC19 */ + { 0, 0, 0, 0, 0, 0 }, /* PC18 */ + { 0, 0, 0, 0, 0, 0 }, /* PC17 */ + { 0, 0, 0, 0, 0, 0 }, /* PC16 */ + { 0, 0, 0, 0, 0, 0 }, /* PC15 */ + { 0, 0, 0, 0, 0, 0 }, /* PC14 */ + { 0, 0, 0, 0, 0, 0 }, /* PC13 */ + { 0, 0, 0, 0, 0, 0 }, /* PC12 */ + { 0, 0, 0, 0, 0, 0 }, /* PC11 */ + { 0, 0, 0, 0, 0, 0 }, /* PC10 */ + { 1, 1, 0, 0, 0, 0 }, /* PC9 SCC4: CTS */ + { 1, 1, 0, 0, 0, 0 }, /* PC8 SCC4: CD */ + { 0, 0, 0, 0, 0, 0 }, /* PC7 */ + { 0, 0, 0, 0, 0, 0 }, /* PC6 */ + { 0, 0, 0, 0, 0, 0 }, /* PC5 */ + { 0, 0, 0, 0, 0, 0 }, /* PC4 */ + { 0, 0, 0, 0, 0, 0 }, /* PC3 */ + { 0, 0, 0, 0, 0, 0 }, /* PC2 */ + { 0, 0, 0, 0, 0, 0 }, /* PC1 */ + { 0, 0, 0, 0, 0, 0 }, /* PC0 */ + }, + + /* Port D */ + { /* conf ppar psor pdir podr pdat */ + { 0, 0, 0, 0, 0, 0 }, /* PD31 */ + { 0, 0, 0, 0, 0, 0 }, /* PD30 */ + { 0, 0, 0, 0, 0, 0 }, /* PD29 */ + { 0, 0, 0, 0, 0, 0 }, /* PD28 */ + { 0, 0, 0, 0, 0, 0 }, /* PD27 */ + { 0, 0, 0, 0, 0, 0 }, /* PD26 */ + { 0, 0, 0, 0, 0, 0 }, /* PD25 */ + { 0, 0, 0, 0, 0, 0 }, /* PD24 */ + { 0, 0, 0, 0, 0, 0 }, /* PD23 */ + { 1, 1, 0, 0, 0, 0 }, /* PD22 SCC4: RXD */ + { 1, 1, 0, 1, 0, 0 }, /* PD21 SCC4: TXD */ + { 1, 1, 0, 1, 0, 0 }, /* PD20 SCC4: RTS */ + { 0, 0, 0, 0, 0, 0 }, /* PD19 */ + { 0, 0, 0, 0, 0, 0 }, /* PD18 */ + { 0, 0, 0, 0, 0, 0 }, /* PD17 */ + { 0, 0, 0, 0, 0, 0 }, /* PD16 */ + { 1, 0, 0, 0, 1, 1 }, /* PD15 */ + { 1, 0, 0, 1, 1, 1 }, /* PD14 */ + { 0, 0, 0, 0, 0, 0 }, /* PD13 */ + { 0, 0, 0, 0, 0, 0 }, /* PD12 */ + { 0, 0, 0, 0, 0, 0 }, /* PD11 */ + { 0, 0, 0, 0, 0, 0 }, /* PD10 */ + { 0, 0, 0, 0, 0, 0 }, /* PD9 */ + { 0, 0, 0, 0, 0, 0 }, /* PD8 */ + { 0, 0, 0, 0, 0, 0 }, /* PD7 */ + { 0, 0, 0, 0, 0, 0 }, /* PD6 */ + { 0, 0, 0, 0, 0, 0 }, /* PD5 */ + { 0, 0, 0, 0, 0, 0 }, /* PD4 */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 }, /* non-existent */ + { 0, 0, 0, 0, 0, 0 } /* non-existent */ + } +}; + +/* + * Try SDRAM initialization with P/LSDMR=sdmr and ORx=orx + * + * This routine performs standard 8260 initialization sequence + * and calculates the available memory size. It may be called + * several times to try different SDRAM configurations on both + * 60x and local buses. + */ +static long int try_init(memctl8260_t *memctl, ulong sdmr, + ulong orx, uchar *base) +{ + uchar c = 0xff; + ulong maxsize, size; + int i; + + /* + * We must be able to test a location outsize the maximum legal size + * to find out THAT we are outside; but this address still has to be + * mapped by the controller. That means, that the initial mapping has + * to be (at least) twice as large as the maximum expected size. + */ + maxsize = (1 + (~orx | 0x7fff))/* / 2*/; + + out_be32(&memctl->memc_or1, orx); + + /* + * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35): + * + * "At system reset, initialization software must set up the + * programmable parameters in the memory controller banks registers + * (ORx, BRx, P/LSDMR). After all memory parameters are configured, + * system software should execute the following initialization sequence + * for each SDRAM device. + * + * 1. Issue a PRECHARGE-ALL-BANKS command + * 2. Issue eight CBR REFRESH commands + * 3. Issue a MODE-SET command to initialize the mode register + * + * The initial commands are executed by setting P/LSDMR[OP] and + * accessing the SDRAM with a single-byte transaction." + * + * The appropriate BRx/ORx registers have already been set when we + * get here. The SDRAM can be accessed at the address + * CONFIG_SYS_SDRAM_BASE. + */ + + out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_PREA); + out_8(base, c); + + out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_CBRR); + for (i = 0; i < 8; i++) + out_8(base, c); + + out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_MRW); + /* setting MR on address lines */ + out_8((uchar *)(base + CONFIG_SYS_MRS_OFFS), c); + + out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_NORM | PSDMR_RFEN); + out_8(base, c); + + size = get_ram_size((long *)base, maxsize); + out_be32(&memctl->memc_or1, orx | ~(size - 1)); + + return size; +} + +#ifdef CONFIG_SYS_SDRAM_LIST + +/* + * If CONFIG_SYS_SDRAM_LIST is defined, we cycle through all SDRAM + * configurations therein (should be from high to lower) to find the + * one actually matching the current configuration. + * CONFIG_SYS_PSDMR and CONFIG_SYS_OR1 will contain the base values which are + * common among all possible configurations; values in CONFIG_SYS_SDRAM_LIST + * (defined as the initialization value for the array of struct sdram_conf_s) + * will then be ORed with such base values. + */ + +struct sdram_conf_s { + ulong size; + int or1; + int psdmr; +}; + +static struct sdram_conf_s sdram_conf[] = CONFIG_SYS_SDRAM_LIST; + +static long probe_sdram(memctl8260_t *memctl) +{ + int n = 0; + long psize = 0; + + for (n = 0; n < ARRAY_SIZE(sdram_conf); psize = 0, n++) { + psize = try_init(memctl, + CONFIG_SYS_PSDMR | sdram_conf[n].psdmr, + CONFIG_SYS_OR1 | sdram_conf[n].or1, + (uchar *) CONFIG_SYS_SDRAM_BASE); + debug("Probing %ld bytes returned %ld\n", + sdram_conf[n].size, psize); + if (psize == sdram_conf[n].size) + break; + } + return psize; +} + +#else /* CONFIG_SYS_SDRAM_LIST */ + +static long probe_sdram(memctl8260_t *memctl) +{ + return try_init(memctl, CONFIG_SYS_PSDMR, CONFIG_SYS_OR1, + (uchar *) CONFIG_SYS_SDRAM_BASE); +} +#endif /* CONFIG_SYS_SDRAM_LIST */ + + +int dram_init(void) +{ + immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; + memctl8260_t *memctl = &immap->im_memctl; + + long psize; + + out_8(&memctl->memc_psrt, CONFIG_SYS_PSRT); + out_be16(&memctl->memc_mptpr, CONFIG_SYS_MPTPR); + + /* 60x SDRAM setup: + */ + psize = probe_sdram(memctl); + + icache_enable(); + + gd->ram_size = psize; + + return 0; +} + +int checkboard(void) +{ +#if defined(CONFIG_MGCOGE) + puts("Board: Keymile mgcoge"); +#else + puts("Board: Keymile mgcoge3ne"); +#endif + if (ethernet_present()) + puts(" with PIGGY."); + puts("\n"); + return 0; +} + +int last_stage_init(void) +{ + struct bfticu_iomap *base = + (struct bfticu_iomap *)CONFIG_SYS_FPGA_BASE; + u8 dip_switch; + + dip_switch = in_8(&base->mswitch); + dip_switch &= BFTICU_DIPSWITCH_MASK; + /* dip switch 'full reset' or 'db erase' or 'Local mgmt IP' or any */ + if (dip_switch != 0) { + /* start bootloader */ + puts("DIP: Enabled\n"); + setenv("actual_bank", "0"); + } + set_km_env(); + return 0; +} + +#ifdef CONFIG_MGCOGE3NE +static void set_pin(int state, unsigned long mask, int port); + +/* + * For mgcoge3ne boards, the mgcoge3un control is controlled from + * a GPIO line on the PPC CPU. If bobcatreset is set the line + * will toggle once what forces the mgocge3un part to restart + * immediately. + */ +static void handle_mgcoge3un_reset(void) +{ + char *bobcatreset = getenv("bobcatreset"); + if (bobcatreset) { + if (strcmp(bobcatreset, "true") == 0) { + puts("Forcing bobcat reset\n"); + set_pin(0, 0x00000004, 3); /* clear PD29 (reset arm) */ + udelay(1000); + set_pin(1, 0x00000004, 3); + } else + set_pin(1, 0x00000004, 3); /* don't reset arm */ + } +} +#endif + +int ethernet_present(void) +{ + struct km_bec_fpga *base = + (struct km_bec_fpga *)CONFIG_SYS_KMBEC_FPGA_BASE; + + return in_8(&base->bprth) & PIGGY_PRESENT; +} + +/* + * Early board initalization. + */ +int board_early_init_r(void) +{ + struct km_bec_fpga *base = + (struct km_bec_fpga *)CONFIG_SYS_KMBEC_FPGA_BASE; + + /* setup the UPIOx */ + /* General Unit Reset disabled, Flash Bank enabled, UnitLed on */ + out_8(&base->oprth, (WRG_RESET | H_OPORTS_14 | WRG_LED)); + /* SCC4 enable, halfduplex, FCC1 powerdown */ + out_8(&base->oprtl, (H_OPORTS_SCC4_ENA | H_OPORTS_SCC4_FD_ENA | + H_OPORTS_FCC1_PW_DWN)); + +#ifdef CONFIG_MGCOGE3NE + handle_mgcoge3un_reset(); +#endif + return 0; +} + +int misc_init_r(void) +{ + ivm_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); + return 0; +} + +int hush_init_var(void) +{ + ivm_analyze_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); + return 0; +} + +#define SDA_MASK 0x00010000 +#define SCL_MASK 0x00020000 + +static void set_pin(int state, unsigned long mask, int port) +{ + ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, port); + + if (state) + setbits_be32(&iop->pdat, mask); + else + clrbits_be32(&iop->pdat, mask); + + setbits_be32(&iop->pdir, mask); +} + +static int get_pin(unsigned long mask, int port) +{ + ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, port); + + clrbits_be32(&iop->pdir, mask); + return 0 != (in_be32(&iop->pdat) & mask); +} + +void set_sda(int state) +{ + set_pin(state, SDA_MASK, 3); +} + +void set_scl(int state) +{ + set_pin(state, SCL_MASK, 3); +} + +int get_sda(void) +{ + return get_pin(SDA_MASK, 3); +} + +int get_scl(void) +{ + return get_pin(SCL_MASK, 3); +} + +int ft_board_setup(void *blob, bd_t *bd) +{ + ft_cpu_setup(blob, bd); + + return 0; +} + +#if defined(CONFIG_MGCOGE3NE) +int get_testpin(void) +{ + /* Testpin is Port C pin 29 - enable = low */ + int testpin = !get_pin(0x00000004, 2); + return testpin; +} +#endif diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c index 81967ff5b4..484a8532ed 100644 --- a/cmd/bdinfo.c +++ b/cmd/bdinfo.c @@ -184,7 +184,7 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) print_num("sramstart", bd->bi_sramstart); print_num("sramsize", bd->bi_sramsize); #if defined(CONFIG_5xx) || \ - defined(CONFIG_E500) + defined(CONFIG_MPC8260) || defined(CONFIG_E500) print_num("immr_base", bd->bi_immr_base); #endif print_num("bootflags", bd->bi_bootflags); diff --git a/cmd/bedbug.c b/cmd/bedbug.c index 32067575ed..14663dc95c 100644 --- a/cmd/bedbug.c +++ b/cmd/bedbug.c @@ -54,6 +54,13 @@ void bedbug_init (void) bedbug405_init (); #endif
+#if defined(CONFIG_MPC824X) || defined(CONFIG_MPC8260) + /* Processors that are 603e core based */ + void bedbug603e_init (void); + + bedbug603e_init (); +#endif + return; } /* bedbug_init */
diff --git a/common/board_f.c b/common/board_f.c index e1ec284d75..a8fd9e38fe 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -547,7 +547,7 @@ static int setup_board_part1(void) bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE; /* size of SRAM */ #endif
-#if defined(CONFIG_5xx) || \ +#if defined(CONFIG_MPC8260) || defined(CONFIG_5xx) || \ defined(CONFIG_E500) || defined(CONFIG_MPC86xx) bd->bi_immr_base = CONFIG_SYS_IMMR; /* base of IMMR register */ #endif diff --git a/common/lynxkdi.c b/common/lynxkdi.c index 98560159fe..22ad384ef6 100644 --- a/common/lynxkdi.c +++ b/common/lynxkdi.c @@ -22,7 +22,7 @@
DECLARE_GLOBAL_DATA_PTR;
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR) +#if defined(CONFIG_MPC8260) || defined(CONFIG_440EP) || defined(CONFIG_440GR) void lynxkdi_boot(image_header_t *hdr) { void (*lynxkdi)(void) = (void(*)(void))image_get_ep(hdr); diff --git a/configs/mgcoge3ne_defconfig b/configs/mgcoge3ne_defconfig new file mode 100644 index 0000000000..58d6656df3 --- /dev/null +++ b/configs/mgcoge3ne_defconfig @@ -0,0 +1,25 @@ +CONFIG_PPC=y +CONFIG_MPC8260=y +CONFIG_CMD_IMMAP=y +CONFIG_TARGET_KM82XX=y +CONFIG_FIT=y +CONFIG_OF_BOARD_SETUP=y +CONFIG_SYS_EXTRA_OPTIONS="MGCOGE3NE" +CONFIG_VERSION_VARIABLE=y +CONFIG_HUSH_PARSER=y +CONFIG_AUTOBOOT_KEYED=y +CONFIG_AUTOBOOT_PROMPT="Hit <SPACE> key to stop autoboot in %2ds\n" +CONFIG_AUTOBOOT_STOP_STR=" " +CONFIG_CMD_ASKENV=y +CONFIG_CMD_GREPENV=y +CONFIG_CMD_EEPROM=y +CONFIG_CMD_I2C=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_JFFS2=y +CONFIG_CMD_UBI=y +# CONFIG_MMC is not set +CONFIG_MTD_NOR_FLASH=y +# CONFIG_PCI is not set +CONFIG_OF_LIBFDT=y diff --git a/configs/mgcoge_defconfig b/configs/mgcoge_defconfig new file mode 100644 index 0000000000..c4f39b38c7 --- /dev/null +++ b/configs/mgcoge_defconfig @@ -0,0 +1,25 @@ +CONFIG_PPC=y +CONFIG_MPC8260=y +CONFIG_CMD_IMMAP=y +CONFIG_TARGET_KM82XX=y +CONFIG_FIT=y +CONFIG_OF_BOARD_SETUP=y +CONFIG_SYS_EXTRA_OPTIONS="MGCOGE" +CONFIG_VERSION_VARIABLE=y +CONFIG_HUSH_PARSER=y +CONFIG_AUTOBOOT_KEYED=y +CONFIG_AUTOBOOT_PROMPT="Hit <SPACE> key to stop autoboot in %2ds\n" +CONFIG_AUTOBOOT_STOP_STR=" " +CONFIG_CMD_ASKENV=y +CONFIG_CMD_GREPENV=y +CONFIG_CMD_EEPROM=y +CONFIG_CMD_I2C=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_JFFS2=y +CONFIG_CMD_UBI=y +# CONFIG_MMC is not set +CONFIG_MTD_NOR_FLASH=y +# CONFIG_PCI is not set +CONFIG_OF_LIBFDT=y diff --git a/doc/README.idma2intr b/doc/README.idma2intr new file mode 100644 index 0000000000..1828b51302 --- /dev/null +++ b/doc/README.idma2intr @@ -0,0 +1,10 @@ +(C) 2003 Arun Dharankar ADharankar@ATTBI.Com + +Attached is an IDMA example code for MPC8260/PPCBoot. I had tried to +search around and could not find any for implementing IDMA, so +implemented one. Its not coded in the best way, but works. + +Also, I was able to test the IDMA specific code under Linux also +(with modifications). My requirement was to implement it for +CompactFlash implemented in memory mode, and it works for it under +PPCBoot and Linux. diff --git a/drivers/bootcount/bootcount.c b/drivers/bootcount/bootcount.c index f1425cbd41..f922cfb23c 100644 --- a/drivers/bootcount/bootcount.c +++ b/drivers/bootcount/bootcount.c @@ -24,6 +24,11 @@ #define CONFIG_SYS_BOOTCOUNT_SINGLEWORD #endif /* defined(CONFIG_MPC512X) */
+#if defined(CONFIG_MPC8260) +#include <asm/cpm_8260.h> +#define CONFIG_SYS_BOOTCOUNT_ADDR (CONFIG_SYS_IMMR + CPM_BOOTCOUNT_ADDR) +#endif /* defined(CONFIG_MPC8260) */ + #if defined(CONFIG_QE) #include <linux/immap_qe.h> #define CONFIG_SYS_BOOTCOUNT_ADDR (CONFIG_SYS_IMMR + 0x110000 + \ diff --git a/drivers/i2c/soft_i2c.c b/drivers/i2c/soft_i2c.c index de3758d946..9380a041b2 100644 --- a/drivers/i2c/soft_i2c.c +++ b/drivers/i2c/soft_i2c.c @@ -17,6 +17,10 @@ */
#include <common.h> +#ifdef CONFIG_MPC8260 /* only valid for MPC8260 */ +#include <ioports.h> +#include <asm/io.h> +#endif #if defined(CONFIG_AVR32) #include <asm/arch/portmux.h> #endif @@ -90,7 +94,12 @@ DECLARE_GLOBAL_DATA_PTR;
#ifndef I2C_SOFT_DECLARATIONS +# if defined(CONFIG_MPC8260) +# define I2C_SOFT_DECLARATIONS volatile ioport_t *iop = \ + ioport_addr((immap_t *)CONFIG_SYS_IMMR, I2C_PORT); +# else # define I2C_SOFT_DECLARATIONS +# endif #endif
#if !defined(CONFIG_SYS_I2C_SOFT_SPEED) diff --git a/drivers/pci/pci_indirect.c b/drivers/pci/pci_indirect.c index efa13a2393..aee0bd6d93 100644 --- a/drivers/pci/pci_indirect.c +++ b/drivers/pci/pci_indirect.c @@ -17,7 +17,22 @@ #define cfg_read(val, addr, type, op) *val = op((type)(addr)) #define cfg_write(val, addr, type, op) op((type *)(addr), (val))
-#if defined(CONFIG_E500) || defined(CONFIG_MPC86xx) +#if defined(CONFIG_MPC8260) +#define INDIRECT_PCI_OP(rw, size, type, op, mask) \ +static int \ +indirect_##rw##_config_##size(struct pci_controller *hose, \ + pci_dev_t dev, int offset, type val) \ +{ \ + u32 b, d,f; \ + b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev); \ + b = b - hose->first_busno; \ + dev = PCI_BDF(b, d, f); \ + out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000000); \ + sync(); \ + cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \ + return 0; \ +} +#elif defined(CONFIG_E500) || defined(CONFIG_MPC86xx) #define INDIRECT_PCI_OP(rw, size, type, op, mask) \ static int \ indirect_##rw##_config_##size(struct pci_controller *hose, \ diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index f320708431..0e3ba94730 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h @@ -125,6 +125,13 @@ #define gadget_is_musbhdrc(g) 0 #endif
+/* from Montavista kernel (?) */ +#ifdef CONFIG_USB_GADGET_MPC8272 +#define gadget_is_mpc8272(g) (!strcmp("mpc8272_udc", (g)->name)) +#else +#define gadget_is_mpc8272(g) 0 +#endif + #ifdef CONFIG_USB_GADGET_M66592 #define gadget_is_m66592(g) (!strcmp("m66592_udc", (g)->name)) #else @@ -202,6 +209,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) return 0x14; else if (gadget_is_musbhdrc(gadget)) return 0x15; + else if (gadget_is_mpc8272(gadget)) + return 0x16; else if (gadget_is_atmel_usba(gadget)) return 0x17; else if (gadget_is_fsl_usb2(gadget)) diff --git a/examples/standalone/Makefile b/examples/standalone/Makefile index 810d285d4e..4c25f6f48f 100644 --- a/examples/standalone/Makefile +++ b/examples/standalone/Makefile @@ -10,6 +10,7 @@ extra-$(CONFIG_SMC91111) += smc91111_eeprom extra-$(CONFIG_SMC911X) += smc911x_eeprom extra-$(CONFIG_SPI_FLASH_ATMEL) += atmel_df_pow2 extra-$(CONFIG_MPC5xxx) += interrupt +extra-$(CONFIG_MPC8260) += mem_to_mem_idma2intr extra-$(CONFIG_PPC) += sched
# diff --git a/examples/standalone/mem_to_mem_idma2intr.c b/examples/standalone/mem_to_mem_idma2intr.c new file mode 100644 index 0000000000..ce6e6c4a10 --- /dev/null +++ b/examples/standalone/mem_to_mem_idma2intr.c @@ -0,0 +1,379 @@ +/* The dpalloc function used and implemented in this file was derieved + * from PPCBoot/U-Boot file "arch/powerpc/cpu/mpc8260/commproc.c". + */ + +/* Author: Arun Dharankar ADharankar@ATTBI.Com + * This example is meant to only demonstrate how the IDMA could be used. + */ + +/* + * This file is based on "arch/powerpc/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 <console.h> +#include <exports.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define STANDALONE + +#ifndef STANDALONE /* Linked into/Part of PPCBoot */ +#include <command.h> +#include <watchdog.h> +#else /* Standalone app of PPCBoot */ +#define WATCHDOG_RESET() { \ + *(ushort *)(CONFIG_SYS_IMMR + 0x1000E) = 0x556c; \ + *(ushort *)(CONFIG_SYS_IMMR + 0x1000E) = 0xaa39; \ + } +#endif /* STANDALONE */ + +static int debug = 1; + +#define DEBUG(fmt, args...) { \ + if(debug != 0) { \ + printf("[%s %d %s]: ",__FILE__,__LINE__,__FUNCTION__); \ + printf(fmt, ##args); \ + } \ +} + +#define CPM_CR_IDMA1_SBLOCK (0x14) +#define CPM_CR_IDMA2_SBLOCK (0x15) +#define CPM_CR_IDMA3_SBLOCK (0x16) +#define CPM_CR_IDMA4_SBLOCK (0x17) +#define CPM_CR_IDMA1_PAGE (0x07) +#define CPM_CR_IDMA2_PAGE (0x08) +#define CPM_CR_IDMA3_PAGE (0x09) +#define CPM_CR_IDMA4_PAGE (0x0a) +#define PROFF_IDMA1_BASE ((uint)0x87fe) +#define PROFF_IDMA2_BASE ((uint)0x88fe) +#define PROFF_IDMA3_BASE ((uint)0x89fe) +#define PROFF_IDMA4_BASE ((uint)0x8afe) + +#define CPM_CR_INIT_TRX ((ushort)0x0000) +#define CPM_CR_FLG ((ushort)0x0001) + +#define mk_cr_cmd(PG, SBC, MCN, OP) \ + ((PG << 26) | (SBC << 21) | (MCN << 6) | OP) + + +#pragma pack(1) +typedef struct ibdbits { + unsigned b_valid:1; + unsigned b_resv1:1; + unsigned b_wrap:1; + unsigned b_interrupt:1; + unsigned b_last:1; + unsigned b_resv2:1; + unsigned b_cm:1; + unsigned b_resv3:2; + unsigned b_sdn:1; + unsigned b_ddn:1; + unsigned b_dgbl:1; + unsigned b_dbo:2; + unsigned b_resv4:1; + unsigned b_ddtb:1; + unsigned b_resv5:2; + unsigned b_sgbl:1; + unsigned b_sbo:2; + unsigned b_resv6:1; + unsigned b_sdtb:1; + unsigned b_resv7:9; +} ibdbits_t; + +#pragma pack(1) +typedef union ibdbitsu { + ibdbits_t b; + uint i; +} ibdbitsu_t; + +#pragma pack(1) +typedef struct idma_buf_desc { + ibdbitsu_t ibd_bits; /* Status and Control */ + uint ibd_datlen; /* Data length in buffer */ + uint ibd_sbuf; /* Source buffer addr in host mem */ + uint ibd_dbuf; /* Destination buffer addr in host mem */ +} ibd_t; + + +#pragma pack(1) +typedef struct dcmbits { + unsigned b_fb:1; + unsigned b_lp:1; + unsigned b_resv1:3; + unsigned b_tc2:1; + unsigned b_resv2:1; + unsigned b_wrap:3; + unsigned b_sinc:1; + unsigned b_dinc:1; + unsigned b_erm:1; + unsigned b_dt:1; + unsigned b_sd:2; +} dcmbits_t; + +#pragma pack(1) +typedef union dcmbitsu { + dcmbits_t b; + ushort i; +} dcmbitsu_t; + +#pragma pack(1) +typedef struct pram_idma { + ushort pi_ibase; + dcmbitsu_t pi_dcmbits; + ushort pi_ibdptr; + ushort pi_dprbuf; + ushort pi_bufinv; /* internal to CPM */ + ushort pi_ssmax; + ushort pi_dprinptr; /* internal to CPM */ + ushort pi_sts; + ushort pi_dproutptr; /* internal to CPM */ + ushort pi_seob; + ushort pi_deob; + ushort pi_dts; + ushort pi_retadd; + ushort pi_resv1; /* internal to CPM */ + uint pi_bdcnt; + uint pi_sptr; + uint pi_dptr; + uint pi_istate; +} pram_idma_t; + + +volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; +volatile ibd_t *bdf; +volatile pram_idma_t *piptr; + +volatile int dmadone; +volatile int *dmadonep = &dmadone; +void dmadone_handler (void *); + +int idma_init (void); +void idma_start (int, int, int, uint, uint, int); +uint dpalloc (uint, uint); + + +uint dpinit_done = 0; + + +#ifdef STANDALONE +int ctrlc (void) +{ + if (tstc()) { + switch (getc ()) { + case 0x03: /* ^C - Control C */ + return 1; + default: + break; + } + } + return 0; +} +int memcmp(const void * cs,const void * ct,size_t count) +{ + const unsigned char *su1, *su2; + int res = 0; + for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) + if ((res = *su1 - *su2) != 0) + break; + return res; +} +#endif /* STANDALONE */ + +#ifdef STANDALONE +int mem_to_mem_idma2intr (int argc, char * const argv[]) +#else +int do_idma (bd_t * bd, int argc, char * const argv[]) +#endif /* STANDALONE */ +{ + int i; + + app_startup(argv); + dpinit_done = 0; + + idma_init (); + + DEBUG ("Installing dma handler\n"); + install_hdlr (7, dmadone_handler, (void *) bdf); + + memset ((void *) 0x100000, 'a', 512); + memset ((void *) 0x200000, 'b', 512); + + for (i = 0; i < 32; i++) { + printf ("Startin IDMA, iteration=%d\n", i); + idma_start (1, 1, 512, 0x100000, 0x200000, 3); + } + + DEBUG ("Uninstalling dma handler\n"); + free_hdlr (7); + + return 0; +} + +void +idma_start (int sinc, int dinc, int sz, uint sbuf, uint dbuf, int ttype) +{ + /* ttype is for M-M, M-P, P-M or P-P: not used for now */ + + piptr->pi_istate = 0; /* manual says: clear it before every START_IDMA */ + piptr->pi_dcmbits.b.b_resv1 = 0; + + if (sinc == 1) + piptr->pi_dcmbits.b.b_sinc = 1; + else + piptr->pi_dcmbits.b.b_sinc = 0; + + if (dinc == 1) + piptr->pi_dcmbits.b.b_dinc = 1; + else + piptr->pi_dcmbits.b.b_dinc = 0; + + piptr->pi_dcmbits.b.b_erm = 0; + piptr->pi_dcmbits.b.b_sd = 0x00; /* M-M */ + + bdf->ibd_sbuf = sbuf; + bdf->ibd_dbuf = dbuf; + bdf->ibd_bits.b.b_cm = 0; + bdf->ibd_bits.b.b_interrupt = 1; + bdf->ibd_bits.b.b_wrap = 1; + bdf->ibd_bits.b.b_last = 1; + bdf->ibd_bits.b.b_sdn = 0; + bdf->ibd_bits.b.b_ddn = 0; + bdf->ibd_bits.b.b_dgbl = 0; + bdf->ibd_bits.b.b_ddtb = 0; + bdf->ibd_bits.b.b_sgbl = 0; + bdf->ibd_bits.b.b_sdtb = 0; + bdf->ibd_bits.b.b_dbo = 1; + bdf->ibd_bits.b.b_sbo = 1; + bdf->ibd_bits.b.b_valid = 1; + bdf->ibd_datlen = 512; + + *dmadonep = 0; + + immap->im_sdma.sdma_idmr2 = (uchar) 0xf; + + immap->im_cpm.cp_cpcr = mk_cr_cmd (CPM_CR_IDMA2_PAGE, + CPM_CR_IDMA2_SBLOCK, 0x0, + 0x9) | 0x00010000; + + while (*dmadonep != 1) { + if (ctrlc ()) { + DEBUG ("\nInterrupted waiting for DMA interrupt.\n"); + goto done; + } + printf ("Waiting for DMA interrupt (dmadone=%d b_valid = %d)...\n", + dmadone, bdf->ibd_bits.b.b_valid); + udelay (1000000); + } + printf ("DMA complete notification received!\n"); + + done: + DEBUG ("memcmp(0x%08x, 0x%08x, 512) = %d\n", + sbuf, dbuf, memcmp ((void *) sbuf, (void *) dbuf, 512)); + + return; +} + +#define MAX_INT_BUFSZ 64 +#define DCM_WRAP 0 /* MUST be consistant with MAX_INT_BUFSZ */ + +int idma_init (void) +{ + uint memaddr; + + immap->im_cpm.cp_rccr &= ~0x00F3FFFF; + immap->im_cpm.cp_rccr |= 0x00A00A00; + + memaddr = dpalloc (sizeof (pram_idma_t), 64); + + *(volatile u16 *)&immap->im_dprambase16 + [PROFF_IDMA2_BASE / sizeof(u16)] = memaddr; + piptr = (volatile pram_idma_t *) ((uint) (immap) + memaddr); + + piptr->pi_resv1 = 0; /* manual says: clear it */ + piptr->pi_dcmbits.b.b_fb = 0; + piptr->pi_dcmbits.b.b_lp = 1; + piptr->pi_dcmbits.b.b_erm = 0; + piptr->pi_dcmbits.b.b_dt = 0; + + memaddr = (uint) dpalloc (sizeof (ibd_t), 64); + piptr->pi_ibase = piptr->pi_ibdptr = (volatile short) memaddr; + bdf = (volatile ibd_t *) ((uint) (immap) + memaddr); + bdf->ibd_bits.b.b_valid = 0; + + memaddr = (uint) dpalloc (64, 64); + piptr->pi_dprbuf = (volatile ushort) memaddr; + piptr->pi_dcmbits.b.b_wrap = 4; + piptr->pi_ssmax = 32; + + piptr->pi_sts = piptr->pi_ssmax; + piptr->pi_dts = piptr->pi_ssmax; + + return 1; +} + +void dmadone_handler (void *arg) +{ + immap->im_sdma.sdma_idmr2 = (uchar) 0x0; + + *dmadonep = 1; + + return; +} + + +static uint dpbase = 0; + +uint dpalloc (uint size, uint align) +{ + volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; + uint retloc; + uint align_mask, off; + uint savebase; + + /* Pointer to initial global data area */ + + if (dpinit_done == 0) { + dpbase = gd->arch.dp_alloc_base; + dpinit_done = 1; + } + + align_mask = align - 1; + savebase = dpbase; + + if ((off = (dpbase & align_mask)) != 0) + dpbase += (align - off); + + if ((off = size & align_mask) != 0) + size += align - off; + + if ((dpbase + size) >= gd->arch.dp_alloc_top) { + dpbase = savebase; + printf ("dpalloc: ran out of dual port ram!"); + return 0; + } + + retloc = dpbase; + dpbase += size; + + memset ((void *) &immr->im_dprambase[retloc], 0, size); + + return (retloc); +} diff --git a/include/asm-generic/u-boot.h b/include/asm-generic/u-boot.h index a7797137f3..4374c2ee08 100644 --- a/include/asm-generic/u-boot.h +++ b/include/asm-generic/u-boot.h @@ -41,7 +41,7 @@ typedef struct bd_info { unsigned long bi_dsp_freq; /* dsp core frequency */ unsigned long bi_ddr_freq; /* ddr frequency */ #endif -#if defined(CONFIG_5xx) \ +#if defined(CONFIG_5xx) || defined(CONFIG_MPC8260) \ || defined(CONFIG_E500) || defined(CONFIG_MPC86xx) unsigned long bi_immr_base; /* base of IMMR register */ #endif diff --git a/include/configs/km82xx.h b/include/configs/km82xx.h new file mode 100644 index 0000000000..09c3aa9ca8 --- /dev/null +++ b/include/configs/km82xx.h @@ -0,0 +1,427 @@ +/* + * (C) Copyright 2007-2011 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + * (easy to change) + */ + +#define CONFIG_MPC8247 +/* MGCOGE */ +#if defined(CONFIG_MGCOGE) +#define CONFIG_HOSTNAME mgcoge +#define CONFIG_KM_BOARD_EXTRA_ENV "" + +/* MGCOGE3NE */ +#elif defined(CONFIG_MGCOGE3NE) +#define CONFIG_HOSTNAME mgcoge3ne +#define CONFIG_KM_82XX +#define CONFIG_KM_BOARD_EXTRA_ENV "bobcatreset=true\0" + +#else +#error ("Board unsupported") +#endif + +#define CONFIG_SYS_TEXT_BASE 0xFE000000 + +#define CONFIG_MISC_INIT_R + +/* include common defines/options for all Keymile boards */ +#include "km/keymile-common.h" +#include "km/km-powerpc.h" + +#define CONFIG_SYS_SDRAM_BASE 0x00000000 +#define CONFIG_SYS_FLASH_BASE 0xFE000000 +#define CONFIG_SYS_FLASH_SIZE 32 +#define CONFIG_SYS_FLASH_CFI +#define CONFIG_FLASH_CFI_DRIVER + +/* MGCOGE */ +#if defined(CONFIG_MGCOGE) +#define CONFIG_SYS_MAX_FLASH_BANKS 3 +/* max num of sects on one chip */ +#define CONFIG_SYS_MAX_FLASH_SECT 512 + +#define CONFIG_SYS_FLASH_BASE_1 0x50000000 +#define CONFIG_SYS_FLASH_SIZE_1 32 +#define CONFIG_SYS_FLASH_BASE_2 0x52000000 +#define CONFIG_SYS_FLASH_SIZE_2 32 + +#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE, \ + CONFIG_SYS_FLASH_BASE_1, \ + CONFIG_SYS_FLASH_BASE_2 } +#define MTDIDS_DEFAULT "nor3=app" + +/* + * Bank 1 - 60x bus SDRAM + */ +#define SDRAM_MAX_SIZE 0x08000000 /* max. 128 MB */ +#define CONFIG_SYS_GLOBAL_SDRAM_LIMIT (256 << 20) /* less than 256 MB */ + +/* SDRAM initialization values +*/ + +#define CONFIG_SYS_OR1 ((~(CONFIG_SYS_GLOBAL_SDRAM_LIMIT-1) & \ + ORxS_SDAM_MSK) |\ + ORxS_BPD_8 |\ + ORxS_ROWST_PBI0_A7 |\ + ORxS_NUMR_13) + +#define CONFIG_SYS_PSDMR ( \ + PSDMR_SDAM_A14_IS_A5 |\ + PSDMR_BSMA_A14_A16 |\ + PSDMR_SDA10_PBI0_A9 |\ + PSDMR_RFRC_5_CLK |\ + PSDMR_PRETOACT_2W |\ + PSDMR_ACTTORW_2W |\ + PSDMR_LDOTOPRE_1C |\ + PSDMR_WRC_1C |\ + PSDMR_CL_2) + +/* MGCOGE3NE */ +#elif defined(CONFIG_MGCOGE3NE) +#define CONFIG_SYS_MAX_FLASH_BANKS 2 /* max num of flash banks */ +#define CONFIG_SYS_MAX_FLASH_SECT 1024 /* + * max num of sects on one + * chip + */ + +#define CONFIG_SYS_FLASH_BASE_1 0x50000000 +#define CONFIG_SYS_FLASH_SIZE_1 128 + +#define CONFIG_SYS_FLASH_SIZE_2 0 /* dummy value to calc SYS_OR5 */ + +#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE, \ + CONFIG_SYS_FLASH_BASE_1 } + +#define MTDIDS_DEFAULT "nor2=app" + +/* + * Bank 1 - 60x bus SDRAM + * mgcoge3ne has 256MB + * mgcoge2ne has 128MB + */ +#define SDRAM_MAX_SIZE 0x10000000 /* max. 256 MB */ +#define CONFIG_SYS_GLOBAL_SDRAM_LIMIT (512 << 20) /* less than 512 MB */ + +#define CONFIG_SYS_OR1 ((~(CONFIG_SYS_GLOBAL_SDRAM_LIMIT-1) & \ + ORxS_SDAM_MSK) |\ + ORxS_BPD_4 |\ + ORxS_NUMR_13 |\ + ORxS_IBID) + +#define CONFIG_SYS_PSDMR ( \ + PSDMR_PBI |\ + PSDMR_RFEN |\ + PSDMR_BSMA_A13_A15 |\ + PSDMR_RFRC_5_CLK |\ + PSDMR_PRETOACT_2W |\ + PSDMR_ACTTORW_2W |\ + PSDMR_LDOTOPRE_1C |\ + PSDMR_WRC_1C |\ + PSDMR_CL_2) + +#define CONFIG_SYS_SDRAM_LIST { \ + { .size = 256 << 20, \ + .or1 = ORxS_ROWST_PBI1_A4, \ + .psdmr = PSDMR_SDAM_A17_IS_A5 | PSDMR_SDA10_PBI1_A6, \ + }, \ + { .size = 128 << 20, \ + .or1 = ORxS_ROWST_PBI1_A5, \ + .psdmr = PSDMR_SDAM_A16_IS_A5 | PSDMR_SDA10_PBI1_A7, \ + }, \ +} +#endif /* defined(CONFIG_MGCOGE3NE) */ + +/* include further common stuff for all keymile 82xx boards */ +/* + * Select serial console configuration + * + * If either CONFIG_CONS_ON_SMC or CONFIG_CONS_ON_SCC is selected, then + * CONFIG_CONS_INDEX must be set to the channel number (1-2 for SMC, 1-4 + * for SCC). + */ +#define CONFIG_CONS_ON_SMC /* Console is on SMC */ +#undef CONFIG_CONS_ON_SCC /* It's not on SCC */ +#undef CONFIG_CONS_NONE /* It's not on external UART */ +#define CONFIG_CONS_INDEX 2 /* SMC2 is used for console */ +#define CONFIG_SYS_SMC_RXBUFLEN 128 +#define CONFIG_SYS_MAXIDLE 10 + +/* + * Select ethernet configuration + * + * If either CONFIG_ETHER_ON_SCC or CONFIG_ETHER_ON_FCC is selected, + * then CONFIG_ETHER_INDEX must be set to the channel number (1-4 for + * SCC, 1-3 for FCC) + * + * If CONFIG_ETHER_NONE is defined, then either the ethernet routines + * must be defined elsewhere (as for the console), or CONFIG_CMD_NET + * must be unset. + */ +#define CONFIG_ETHER_ON_SCC /* Ethernet is on SCC */ +#undef CONFIG_ETHER_ON_FCC /* Ethernet is not on FCC */ +#undef CONFIG_ETHER_NONE /* No external Ethernet */ + +#define CONFIG_ETHER_INDEX 4 +#define CONFIG_HAS_ETH0 +#define CONFIG_SYS_SCC_TOUT_LOOP 10000000 + +#define CONFIG_SYS_CMXSCR_VALUE (CMXSCR_RS4CS_CLK7 | CMXSCR_TS4CS_CLK8) + +#ifndef CONFIG_8260_CLKIN +#define CONFIG_8260_CLKIN 66000000 /* in Hz */ +#endif + +#define BOOTFLASH_START 0xFE000000 + +#define CONFIG_KM_CONSOLE_TTY "ttyCPM0" + +#define MTDPARTS_DEFAULT "mtdparts=" \ + "app:" \ + "768k(u-boot)," \ + "128k(env)," \ + "128k(envred)," \ + "3072k(free)," \ + "-(" CONFIG_KM_UBI_PARTITION_NAME_BOOT ")" + +/* + * Default environment settings + */ +#define CONFIG_EXTRA_ENV_SETTINGS \ + CONFIG_KM_BOARD_EXTRA_ENV \ + CONFIG_KM_DEF_ENV \ + "unlock=yes\0" \ + "newenv=" \ + "prot off 0xFE0C0000 +0x40000 && " \ + "era 0xFE0C0000 +0x40000\0" \ + "arch=ppc_82xx\0" \ + "" + +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE + +#define CONFIG_SYS_MONITOR_LEN (768 << 10) + +#define CONFIG_ENV_IS_IN_FLASH + +#ifdef CONFIG_ENV_IS_IN_FLASH +#define CONFIG_ENV_SECT_SIZE 0x20000 +#define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE + \ + CONFIG_SYS_MONITOR_LEN) +#define CONFIG_ENV_OFFSET CONFIG_SYS_MONITOR_LEN + +/* Address and size of Redundant Environment Sector */ +#define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + \ + CONFIG_ENV_SECT_SIZE) +#define CONFIG_ENV_SIZE_REDUND (CONFIG_ENV_SIZE) +#endif /* CONFIG_ENV_IS_IN_FLASH */ + +/* enable I2C and select the hardware/software driver */ +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_SOFT /* I2C bit-banged */ +#define CONFIG_SYS_I2C_INIT_BOARD +#define CONFIG_SYS_NUM_I2C_BUSES 3 +#define CONFIG_SYS_I2C_MAX_HOPS 1 +#define CONFIG_SYS_I2C_SOFT_SPEED 50000 +#define CONFIG_SYS_I2C_SPEED CONFIG_SYS_I2C_SOFT_SPEED +#define CONFIG_SYS_I2C_SOFT_SLAVE 0x7F +#define CONFIG_SYS_I2C_BUSES {{0, {I2C_NULL_HOP} }, \ + {0, {{I2C_MUX_PCA9542, 0x70, 0} } }, \ + {0, {{I2C_MUX_PCA9542, 0x70, 1} } } } + +#define CONFIG_KM_IVM_BUS 1 /* I2C2 (Mux-Port 1)*/ +#define CONFIG_KM_I2C_ABORT + +/* + * Software (bit-bang) I2C driver configuration + */ + +#define I2C_PORT 3 /* Port A=0, B=1, C=2, D=3 */ +#define I2C_ACTIVE (iop->pdir |= 0x00010000) +#define I2C_TRISTATE (iop->pdir &= ~0x00010000) +#define I2C_READ ((iop->pdat & 0x00010000) != 0) +#define I2C_SDA(bit) do { \ + if (bit) \ + iop->pdat |= 0x00010000; \ + else \ + iop->pdat &= ~0x00010000; \ + } while (0) +#define I2C_SCL(bit) do { \ + if (bit) \ + iop->pdat |= 0x00020000; \ + else \ + iop->pdat &= ~0x00020000; \ + } while (0) +#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ + +#ifndef __ASSEMBLY__ +void set_sda(int state); +void set_scl(int state); +int get_sda(void); +int get_scl(void); +#endif + +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1 + +#define CONFIG_SYS_IMMR 0xF0000000 + +#define CONFIG_SYS_INIT_RAM_ADDR CONFIG_SYS_IMMR +#define CONFIG_SYS_INIT_RAM_SIZE 0x2000 /* used size in DPRAM */ +#define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_SIZE - \ + GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET + +/* Hard reset configuration word */ +#define CONFIG_SYS_HRCW_MASTER 0x0604b211 + +/* No slaves */ +#define CONFIG_SYS_HRCW_SLAVE1 0 +#define CONFIG_SYS_HRCW_SLAVE2 0 +#define CONFIG_SYS_HRCW_SLAVE3 0 +#define CONFIG_SYS_HRCW_SLAVE4 0 +#define CONFIG_SYS_HRCW_SLAVE5 0 +#define CONFIG_SYS_HRCW_SLAVE6 0 +#define CONFIG_SYS_HRCW_SLAVE7 0 + +/* Initial Memory map for Linux */ +#define CONFIG_SYS_BOOTMAPSZ (8 << 20) + +#define CONFIG_SYS_CACHELINE_SIZE 32 /* For MPC8260 CPUs */ +#if defined(CONFIG_CMD_KGDB) +# define CONFIG_SYS_CACHELINE_SHIFT 5 /* log base 2 of the above value */ +#endif + +#define CONFIG_SYS_HID0_INIT 0 +#define CONFIG_SYS_HID0_FINAL (HID0_ICE | HID0_IFEM | HID0_ABE) + +#define CONFIG_SYS_HID2 0 + +#define CONFIG_SYS_SIUMCR 0x4020c200 +#define CONFIG_SYS_SYPCR 0xFFFFFF83 +#define CONFIG_SYS_BCR 0x10000000 +#define CONFIG_SYS_SCCR (SCCR_PCI_MODE | SCCR_PCI_MODCK) + +/* + *----------------------------------------------------------------------- + * RMR - Reset Mode Register 5-5 + *----------------------------------------------------------------------- + * turn on Checkstop Reset Enable + */ +#define CONFIG_SYS_RMR 0 + +/* + *----------------------------------------------------------------------- + * TMCNTSC - Time Counter Status and Control 4-40 + *----------------------------------------------------------------------- + * Clear once per Second and Alarm Interrupt Status, Set 32KHz timersclk, + * and enable Time Counter + */ +#define CONFIG_SYS_TMCNTSC (TMCNTSC_SEC|TMCNTSC_ALR|TMCNTSC_TCF|TMCNTSC_TCE) + +/* + *----------------------------------------------------------------------- + * PISCR - Periodic Interrupt Status and Control 4-42 + *----------------------------------------------------------------------- + * Clear Periodic Interrupt Status, Set 32KHz timersclk, and enable + * Periodic timer + */ +#define CONFIG_SYS_PISCR (PISCR_PS|PISCR_PTF|PISCR_PTE) + +/* + *----------------------------------------------------------------------- + * RCCR - RISC Controller Configuration 13-7 + *----------------------------------------------------------------------- + */ +#define CONFIG_SYS_RCCR 0 + +/* + * Init Memory Controller: + * + * Bank Bus Machine PortSz Device + * ---- --- ------- ------ ------ + * 0 60x GPCM 8 bit FLASH + * 1 60x SDRAM 32 bit SDRAM + * 3 60x GPCM 8 bit GPIO/PIGGY + * 5 60x GPCM 16 bit CFG-Flash + * + */ +/* Bank 0 - FLASH + */ +#define CONFIG_SYS_BR0_PRELIM ((CONFIG_SYS_FLASH_BASE & BRx_BA_MSK) |\ + BRx_PS_8 |\ + BRx_MS_GPCM_P |\ + BRx_V) + +#define CONFIG_SYS_OR0_PRELIM (MEG_TO_AM(CONFIG_SYS_FLASH_SIZE) |\ + ORxG_CSNT |\ + ORxG_ACS_DIV2 |\ + ORxG_SCY_5_CLK |\ + ORxG_TRLX) + +#define CONFIG_SYS_MPTPR 0x1800 + +/* + *----------------------------------------------------------------------------- + * Address for Mode Register Set (MRS) command + *----------------------------------------------------------------------------- + */ +#define CONFIG_SYS_MRS_OFFS 0x00000110 +#define CONFIG_SYS_PSRT 0x0e + +#define CONFIG_SYS_BR1_PRELIM ((CONFIG_SYS_SDRAM_BASE & BRx_BA_MSK) |\ + BRx_PS_64 |\ + BRx_MS_SDRAM_P |\ + BRx_V) + +#define CONFIG_SYS_OR1_PRELIM CONFIG_SYS_OR1 + +/* + * UPIO FPGA (GPIO/PIGGY) on CS3 initialization values + */ +#define CONFIG_SYS_KMBEC_FPGA_BASE 0x30000000 +#define CONFIG_SYS_KMBEC_FPGA_SIZE 128 + +#define CONFIG_SYS_BR3_PRELIM ((CONFIG_SYS_KMBEC_FPGA_BASE & BRx_BA_MSK) |\ + BRx_PS_8 | BRx_MS_GPCM_P | BRx_V) + +#define CONFIG_SYS_OR3_PRELIM (MEG_TO_AM(CONFIG_SYS_KMBEC_FPGA_SIZE) |\ + ORxG_CSNT | ORxG_ACS_DIV2 |\ + ORxG_SCY_3_CLK | ORxG_TRLX) + +/* + * BFTICU board FPGA on CS4 initialization values + */ +#define CONFIG_SYS_FPGA_BASE 0x40000000 +#define CONFIG_SYS_FPGA_SIZE 1 /*1KB*/ + +#define CONFIG_SYS_BR4_PRELIM ((CONFIG_SYS_FPGA_BASE & BRx_BA_MSK) |\ + BRx_PS_8 | BRx_MS_GPCM_P | BRx_V) + +#define CONFIG_SYS_OR4_PRELIM (P2SZ_TO_AM(CONFIG_SYS_FPGA_SIZE << 10) |\ + ORxG_CSNT | ORxG_ACS_DIV2 |\ + ORxG_SCY_3_CLK | ORxG_TRLX) + +/* + * CFG-Flash on CS5 initialization values + */ +#define CONFIG_SYS_BR5_PRELIM ((CONFIG_SYS_FLASH_BASE_1 & BRx_BA_MSK) |\ + BRx_PS_16 | BRx_MS_GPCM_P | BRx_V) + +#define CONFIG_SYS_OR5_PRELIM (MEG_TO_AM(CONFIG_SYS_FLASH_SIZE_1 + \ + CONFIG_SYS_FLASH_SIZE_2) |\ + ORxG_CSNT | ORxG_ACS_DIV2 |\ + ORxG_SCY_5_CLK | ORxG_TRLX) + +#define CONFIG_SYS_RESET_ADDRESS 0xFDFFFFFC /* "bad" address */ + +#define OF_TBCLK (bd->bi_busfreq / 4) +#define OF_STDOUT_PATH "/soc/cpm/serial@11a90" + +#endif /* __CONFIG_H */ diff --git a/include/i2c.h b/include/i2c.h index 695cb7655f..fe3dca09b8 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -660,7 +660,9 @@ extern struct i2c_bus_hose i2c_bus[]; #endif
#ifndef I2C_SOFT_DECLARATIONS -# if (defined(CONFIG_AT91RM9200) || \ +# if defined(CONFIG_MPC8260) +# define I2C_SOFT_DECLARATIONS volatile ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, I2C_PORT); +# elif (defined(CONFIG_AT91RM9200) || \ defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9261) || \ defined(CONFIG_AT91SAM9263)) # define I2C_SOFT_DECLARATIONS at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; diff --git a/include/mpc8260.h b/include/mpc8260.h new file mode 100644 index 0000000000..75f1b0c9df --- /dev/null +++ b/include/mpc8260.h @@ -0,0 +1,903 @@ +/* + * (C) Copyright 2000, 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * mpc8260.h + * + * MPC8255 / MPC8260 specific definitions + */ + +#ifndef __MPC8260_H__ +#define __MPC8260_H__ + +#ifdef CONFIG_MPC8255 +#define CPU_ID_STR "MPC8255" +#endif +#ifndef CPU_ID_STR +#if defined(CONFIG_MPC8272_FAMILY) +#ifdef CONFIG_MPC8247 +#define CPU_ID_STR "MPC8247" +#else +#define CPU_ID_STR "MPC8272" +#endif +#else +#define CPU_ID_STR "MPC8260" +#endif +#endif /* !CPU_ID_STR */ + +/*----------------------------------------------------------------------- + * Exception offsets (PowerPC standard) + */ +#define EXC_OFF_SYS_RESET 0x0100 /* System reset */ +#define _START_OFFSET EXC_OFF_SYS_RESET + +/*----------------------------------------------------------------------- + * BCR - Bus Configuration Register 4-25 + */ +#define BCR_EBM 0x80000000 /* External Bus Mode */ +#define BCR_APD_MSK 0x70000000 /* Address Phase Delay Mask */ +#define BCR_L2C 0x08000000 /* Secondary Cache Controller */ +#define BCR_L2D_MSK 0x07000000 /* L2 Cache Hit Delay Mask */ +#define BCR_PLDP 0x00800000 /* Pipeline Maximum Depth */ +#define BCR_EAV 0x00400000 /* Enable Address Visibility */ +#define BCR_ETM 0x00080000 /* Compatibility Mode Enable */ +#define BCR_LETM 0x00040000 /* LocalBus Compatibility Mode Enable*/ +#define BCR_EPAR 0x00020000 /* Even Parity */ +#define BCR_LEPAR 0x00010000 /* Local Bus Even Parity */ +#define BCR_NPQM0 0x00008000 /* Non PowerQUICC-II Master 0 */ +#define BCR_NPQM1 0x00004000 /* Non PowerQUICC-II Master 1 */ +#define BCR_NPQM2 0x00002000 /* Non PowerQUICC-II Master 2 */ +#define BCR_EXDD 0x00000400 /* External Master Delay Disable*/ +#define BCR_ISPS 0x00000010 /* Internal Space Port Size */ + + +/*----------------------------------------------------------------------- + * PPC_ACR - 60x Bus Arbiter Configuration Register 4-28 + */ +#define PPC_ACR_DBGD 0x20 /* Data Bus Grant Delay */ +#define PPC_ACR_EARB 0x10 /* External Arbitration */ +#define PPC_ACR_PRKM_MSK 0x0f /* Parking Master */ + +#define PPC_ACR_PRKM_CPMH 0x00 /* CPM high request level */ +#define PPC_ACR_PRKM_CPMM 0x01 /* CPM middle request level */ +#define PPC_ACR_PRKM_CPML 0x02 /* CPM low request level */ +#define PPC_ACR_PRKM_CORE 0x06 /* Internal Core */ +#define PPC_ACR_PRKM_EXT1 0x07 /* External Master 1 */ +#define PPC_ACR_PRKM_EXT2 0x08 /* External Master 2 */ +#define PPC_ACR_PRKM_EXT3 0x09 /* External Master 3 */ + +/*----------------------------------------------------------------------- + * PPC_ALRH/PPC_ALRL - 60x Bus Arbitration-Level Registers 4-28 + */ +#define PPC_ALRH_PF0_MSK 0xf0000000 /* Priority Field 0 Mask */ +#define PPC_ALRH_PF1_MSK 0x0f000000 /* Priority Field 1 Mask */ +#define PPC_ALRH_PF2_MSK 0x00f00000 /* Priority Field 2 Mask */ +#define PPC_ALRH_PF3_MSK 0x000f0000 /* Priority Field 3 Mask */ +#define PPC_ALRH_PF4_MSK 0x0000f000 /* Priority Field 4 Mask */ +#define PPC_ALRH_PF5_MSK 0x00000f00 /* Priority Field 5 Mask */ +#define PPC_ALRH_PF6_MSK 0x000000f0 /* Priority Field 6 Mask */ +#define PPC_ALRH_PF7_MSK 0x0000000f /* Priority Field 7 Mask */ +#define PPC_ALRL_PF8_MSK 0xf0000000 /* Priority Field 8 Mask */ +#define PPC_ALRL_PF9_MSK 0x0f000000 /* Priority Field 9 Mask */ +#define PPC_ALRL_PF10_MSK 0x00f00000 /* Priority Field 10 Mask */ +#define PPC_ALRL_PF11_MSK 0x000f0000 /* Priority Field 11 Mask */ +#define PPC_ALRL_PF12_MSK 0x0000f000 /* Priority Field 12 Mask */ +#define PPC_ALRL_PF13_MSK 0x00000f00 /* Priority Field 13 Mask */ +#define PPC_ALRL_PF14_MSK 0x000000f0 /* Priority Field 14 Mask */ +#define PPC_ALRL_PF15_MSK 0x0000000f /* Priority Field 15 Mask */ + +/*----------------------------------------------------------------------- + * LCL_ACR - Local Bus Arbiter Configuration Register 4-29 + */ +#define LCL_ACR_DBGD 0x20 /* Data Bus Grant Delay */ +#define LCL_ACR_PRKM_MSK 0x0f /* Parking Master */ + +#define LCL_ACR_PRKM_CPMH 0x00 /* CPM high request level */ +#define LCL_ACR_PRKM_CPMM 0x01 /* CPM middle request level */ +#define LCL_ACR_PRKM_CPML 0x02 /* CPM low request level */ +#define LCL_ACR_PRKM_HOST 0x03 /* Host Bridge */ + +/*----------------------------------------------------------------------- + * LCL_ALRH/LCL_ALRL - Local Bus Arbitration Level Registers 4-30 + */ +#define LCL_ALRH_PF0_MSK 0xf0000000 /* Priority Field 0 Mask */ +#define LCL_ALRH_PF1_MSK 0x0f000000 /* Priority Field 1 Mask */ +#define LCL_ALRH_PF2_MSK 0x00f00000 /* Priority Field 2 Mask */ +#define LCL_ALRH_PF3_MSK 0x000f0000 /* Priority Field 3 Mask */ +#define LCL_ALRH_PF4_MSK 0x0000f000 /* Priority Field 4 Mask */ +#define LCL_ALRH_PF5_MSK 0x00000f00 /* Priority Field 5 Mask */ +#define LCL_ALRH_PF6_MSK 0x000000f0 /* Priority Field 6 Mask */ +#define LCL_ALRH_PF7_MSK 0x0000000f /* Priority Field 7 Mask */ +#define LCL_ALRL_PF8_MSK 0xf0000000 /* Priority Field 8 Mask */ +#define LCL_ALRL_PF9_MSK 0x0f000000 /* Priority Field 9 Mask */ +#define LCL_ALRL_PF10_MSK 0x00f00000 /* Priority Field 10 Mask */ +#define LCL_ALRL_PF11_MSK 0x000f0000 /* Priority Field 11 Mask */ +#define LCL_ALRL_PF12_MSK 0x0000f000 /* Priority Field 12 Mask */ +#define LCL_ALRL_PF13_MSK 0x00000f00 /* Priority Field 13 Mask */ +#define LCL_ALRL_PF14_MSK 0x000000f0 /* Priority Field 14 Mask */ +#define LCL_ALRL_PF15_MSK 0x0000000f /* Priority Field 15 Mask */ + +/*----------------------------------------------------------------------- + * SIUMCR - SIU Module Configuration Register 4-31 + */ +#define SIUMCR_BBD 0x80000000 /* Bus Busy Disable */ +#define SIUMCR_ESE 0x40000000 /* External Snoop Enable */ +#define SIUMCR_PBSE 0x20000000 /* Parity Byte Select Enable */ +#define SIUMCR_CDIS 0x10000000 /* Core Disable */ +#define SIUMCR_DPPC00 0x00000000 /* Data Parity Pins Configuration*/ +#define SIUMCR_DPPC01 0x04000000 /* - " - */ +#define SIUMCR_DPPC10 0x08000000 /* - " - */ +#define SIUMCR_DPPC11 0x0c000000 /* - " - */ +#define SIUMCR_L2CPC00 0x00000000 /* L2 Cache Pins Configuration */ +#define SIUMCR_L2CPC01 0x01000000 /* - " - */ +#define SIUMCR_L2CPC10 0x02000000 /* - " - */ +#define SIUMCR_L2CPC11 0x03000000 /* - " - */ +#define SIUMCR_LBPC00 0x00000000 /* Local Bus Pins Configuration */ +#define SIUMCR_LBPC01 0x00400000 /* - " - */ +#define SIUMCR_LBPC10 0x00800000 /* - " - */ +#define SIUMCR_LBPC11 0x00c00000 /* - " - */ +#define SIUMCR_APPC00 0x00000000 /* Address Parity Pins Configuration*/ +#define SIUMCR_APPC01 0x00100000 /* - " - */ +#define SIUMCR_APPC10 0x00200000 /* - " - */ +#define SIUMCR_APPC11 0x00300000 /* - " - */ +#define SIUMCR_CS10PC00 0x00000000 /* CS10 Pin Configuration */ +#define SIUMCR_CS10PC01 0x00040000 /* - " - */ +#define SIUMCR_CS10PC10 0x00080000 /* - " - */ +#define SIUMCR_CS10PC11 0x000c0000 /* - " - */ +#define SIUMCR_BCTLC00 0x00000000 /* Buffer Control Configuration */ +#define SIUMCR_BCTLC01 0x00010000 /* - " - */ +#define SIUMCR_BCTLC10 0x00020000 /* - " - */ +#define SIUMCR_BCTLC11 0x00030000 /* - " - */ +#define SIUMCR_MMR00 0x00000000 /* Mask Masters Requests */ +#define SIUMCR_MMR01 0x00004000 /* - " - */ +#define SIUMCR_MMR10 0x00008000 /* - " - */ +#define SIUMCR_MMR11 0x0000c000 /* - " - */ +#define SIUMCR_LPBSE 0x00002000 /* LocalBus Parity Byte Select Enable*/ +#define SIUMCR_ABE 0x00000400 /* Address output buffer impedance*/ + +/*----------------------------------------------------------------------- + * IMMR - Internal Memory Map Register 4-34 + */ +#define IMMR_ISB_MSK 0xfffe0000 /* Internal Space base */ +#define IMMR_PARTNUM_MSK 0x0000ff00 /* Part number */ +#define IMMR_MASKNUM_MSK 0x000000ff /* Mask number */ + +/*----------------------------------------------------------------------- + * SYPCR - System Protection Control Register 4-35 + */ +#define SYPCR_SWTC 0xffff0000 /* Software Watchdog Timer Count*/ +#define SYPCR_BMT 0x0000ff00 /* Bus Monitor Timing */ +#define SYPCR_PBME 0x00000080 /* 60x Bus Monitor Enable */ +#define SYPCR_LBME 0x00000040 /* Local Bus Monitor Enable */ +#define SYPCR_SWE 0x00000004 /* Software Watchdog Enable */ +#define SYPCR_SWRI 0x00000002 /* Software Watchdog Reset/Int Select*/ +#define SYPCR_SWP 0x00000001 /* Software Watchdog Prescale */ + +/*----------------------------------------------------------------------- + * TMCNTSC - Time Counter Status and Control Register 4-40 + */ +#define TMCNTSC_SEC 0x0080 /* Once Per Second Interrupt */ +#define TMCNTSC_ALR 0x0040 /* Alarm Interrupt */ +#define TMCNTSC_SIE 0x0008 /* Second Interrupt Enable */ +#define TMCNTSC_ALE 0x0004 /* Alarm Interrupt Enable */ +#define TMCNTSC_TCF 0x0002 /* Time Counter Frequency */ +#define TMCNTSC_TCE 0x0001 /* Time Counter Enable */ + +/*----------------------------------------------------------------------- + * PISCR - Periodic Interrupt Status and Control Register 4-42 + */ +#if 0 /* already defined in asm/immap_8260.h */ +#define PISCR_PS 0x0080 /* Periodic Interrupt Status */ +#define PISCR_PIE 0x0004 /* Periodic Interrupt Enable */ +#define PISCR_PTF 0x0002 /* Periodic Timer Frequency */ +#define PISCR_PTE 0x0001 /* Periodic Timer Enable */ +#endif + +/*----------------------------------------------------------------------- + * RSR - Reset Status Register 5-4 + */ +#define RSR_JTRS 0x00000020 /* JTAG Reset Status */ +#define RSR_CSRS 0x00000010 /* Check Stop Reset Status */ +#define RSR_SWRS 0x00000008 /* Software Watchdog Reset Status*/ +#define RSR_BMRS 0x00000004 /* Bus Monitor Reset Status */ +#define RSR_ESRS 0x00000002 /* External Soft Reset Status */ +#define RSR_EHRS 0x00000001 /* External Hard Reset Status */ + +#define RSR_ALLBITS (RSR_JTRS|RSR_CSRS|RSR_SWRS|RSR_BMRS|RSR_ESRS|RSR_EHRS) + +/*----------------------------------------------------------------------- + * RMR - Reset Mode Register 5-5 + */ +#define RMR_CSRE 0x00000001 /* Checkstop Reset Enable */ + +/*----------------------------------------------------------------------- + * Hard Reset Configuration Word 5-8 + */ +#define HRCW_EARB 0x80000000 /* External Arbitration */ +#define HRCW_EXMC 0x40000000 /* External Memory Controller */ +#define HRCW_CDIS 0x20000000 /* Core Disable */ +#define HRCW_EBM 0x10000000 /* External Bus Mode */ +#define HRCW_BPS00 0x00000000 /* Boot Port Size */ +#define HRCW_BPS01 0x04000000 /* - " - */ +#define HRCW_BPS10 0x08000000 /* - " - */ +#define HRCW_BPS11 0x0c000000 /* - " - */ +#define HRCW_CIP 0x02000000 /* Core Initial Prefix */ +#define HRCW_ISPS 0x01000000 /* Internal Space Port Size */ +#define HRCW_L2CPC00 0x00000000 /* L2 Cache Pins Configuration */ +#define HRCW_L2CPC01 0x00400000 /* - " - */ +#define HRCW_L2CPC10 0x00800000 /* - " - */ +#define HRCW_L2CPC11 0x00c00000 /* - " - */ +#define HRCW_DPPC00 0x00000000 /* Data Parity Pin Configuration*/ +#define HRCW_DPPC01 0x00100000 /* - " - */ +#define HRCW_DPPC10 0x00200000 /* - " - */ +#define HRCW_DPPC11 0x00300000 /* - " - */ +#define HRCW_reserved1 0x00080000 /* reserved */ +#define HRCW_ISB000 0x00000000 /* Initial Internal Space Base */ +#define HRCW_ISB001 0x00010000 /* - " - */ +#define HRCW_ISB010 0x00020000 /* - " - */ +#define HRCW_ISB011 0x00030000 /* - " - */ +#define HRCW_ISB100 0x00040000 /* - " - */ +#define HRCW_ISB101 0x00050000 /* - " - */ +#define HRCW_ISB110 0x00060000 /* - " - */ +#define HRCW_ISB111 0x00070000 /* - " - */ +#define HRCW_BMS 0x00008000 /* Boot Memory Space */ +#define HRCW_BBD 0x00004000 /* Bus Busy Disable */ +#define HRCW_MMR00 0x00000000 /* Mask Masters Requests */ +#define HRCW_MMR01 0x00001000 /* - " - */ +#define HRCW_MMR10 0x00002000 /* - " - */ +#define HRCW_MMR11 0x00003000 /* - " - */ +#define HRCW_LBPC00 0x00000000 /* Local Bus Pin Configuration */ +#define HRCW_LBPC01 0x00000400 /* - " - */ +#define HRCW_LBPC10 0x00000800 /* - " - */ +#define HRCW_LBPC11 0x00000c00 /* - " - */ +#define HRCW_APPC00 0x00000000 /* Address Parity Pin Configuration*/ +#define HRCW_APPC01 0x00000100 /* - " - */ +#define HRCW_APPC10 0x00000200 /* - " - */ +#define HRCW_APPC11 0x00000300 /* - " - */ +#define HRCW_CS10PC00 0x00000000 /* CS10 Pin Configuration */ +#define HRCW_CS10PC01 0x00000040 /* - " - */ +#define HRCW_CS10PC10 0x00000080 /* - " - */ +#define HRCW_CS10PC11 0x000000c0 /* - " - */ +#define HRCW_MODCK_H0000 0x00000000 /* High-order bits of MODCK Bus */ +#define HRCW_MODCK_H0001 0x00000001 /* - " - */ +#define HRCW_MODCK_H0010 0x00000002 /* - " - */ +#define HRCW_MODCK_H0011 0x00000003 /* - " - */ +#define HRCW_MODCK_H0100 0x00000004 /* - " - */ +#define HRCW_MODCK_H0101 0x00000005 /* - " - */ +#define HRCW_MODCK_H0110 0x00000006 /* - " - */ +#define HRCW_MODCK_H0111 0x00000007 /* - " - */ +#define HRCW_MODCK_H1000 0x00000008 /* - " - */ +#define HRCW_MODCK_H1001 0x00000009 /* - " - */ +#define HRCW_MODCK_H1010 0x0000000a /* - " - */ +#define HRCW_MODCK_H1011 0x0000000b /* - " - */ +#define HRCW_MODCK_H1100 0x0000000c /* - " - */ +#define HRCW_MODCK_H1101 0x0000000d /* - " - */ +#define HRCW_MODCK_H1110 0x0000000e /* - " - */ +#define HRCW_MODCK_H1111 0x0000000f /* - " - */ + +/*----------------------------------------------------------------------- + * SCCR - System Clock Control Register 9-8 + */ +#define SCCR_PCI_MODE 0x00000100 /* PCI Mode */ +#define SCCR_PCI_MODCK 0x00000080 /* Value of PCI_MODCK pin */ +#define SCCR_PCIDF_MSK 0x00000078 /* PCI division factor */ +#define SCCR_PCIDF_SHIFT 3 +#define SCCR_CLPD 0x00000004 /* CPM Low Power Disable */ +#define SCCR_DFBRG_MSK 0x00000003 /* Division factor of BRGCLK Mask */ +#define SCCR_DFBRG_SHIFT 0 + +#define SCCR_DFBRG00 0x00000000 /* BRGCLK division by 4 */ +#define SCCR_DFBRG01 0x00000001 /* BRGCLK division by 16 (normal op.)*/ +#define SCCR_DFBRG10 0x00000002 /* BRGCLK division by 64 */ +#define SCCR_DFBRG11 0x00000003 /* BRGCLK division by 128 */ + +/*----------------------------------------------------------------------- + * SCMR - System Clock Mode Register 9-9 + */ +#define SCMR_CORECNF_MSK 0x1f000000 /* Core Configuration Mask */ +#define SCMR_CORECNF_SHIFT 24 +#define SCMR_BUSDF_MSK 0x00f00000 /* 60x Bus Division Factor Mask */ +#define SCMR_BUSDF_SHIFT 20 +#define SCMR_CPMDF_MSK 0x000f0000 /* CPM Division Factor Mask */ +#define SCMR_CPMDF_SHIFT 16 +#define SCMR_PLLDF 0x00001000 /* PLL Pre-divider Value */ +#define SCMR_PLLMF_MSK 0x00000fff /* PLL Multiplication Factor Mask*/ +#define SCMR_PLLMF_MSKH7 0x0000000f /* for HiP7 processors */ +#define SCMR_PLLMF_SHIFT 0 + + +/*----------------------------------------------------------------------- + * MxMR - Machine A/B/C Mode Registers 10-13 + */ +#define MxMR_BSEL 0x80000000 /* Bus Select */ +#define MxMR_RFEN 0x40000000 /* Refresh Enable */ +#define MxMR_OP_MSK 0x30000000 /* Command Opcode Mask */ +#define MxMR_AMx_MSK 0x07000000 /* Addess Multiplex Size Mask */ +#define MxMR_DSx_MSK 0x00c00000 /* Disable Timer Period Mask */ +#define MxMR_G0CLx_MSK 0x00380000 /* General Line 0 Control Mask */ +#define MxMR_GPL_x4DIS 0x00040000 /* GPL_A4 Ouput Line Disable */ +#define MxMR_RLFx_MSK 0x0003c000 /* Read Loop Field Mask */ +#define MxMR_WLFx_MSK 0x00003c00 /* Write Loop Field Mask */ +#define MxMR_TLFx_MSK 0x000003c0 /* Refresh Loop Field Mask */ +#define MxMR_MAD_MSK 0x0000003f /* Machine Address Mask */ + +#define MxMR_OP_NORM 0x00000000 /* Normal Operation */ +#define MxMR_OP_WARR 0x10000000 /* Write to Array */ +#define MxMR_OP_RARR 0x20000000 /* Read from Array */ +#define MxMR_OP_RUNP 0x30000000 /* Run Pattern */ + +#define MxMR_AMx_TYPE_0 0x00000000 /* Addess Multiplexing Type 0 */ +#define MxMR_AMx_TYPE_1 0x01000000 /* Addess Multiplexing Type 1 */ +#define MxMR_AMx_TYPE_2 0x02000000 /* Addess Multiplexing Type 2 */ +#define MxMR_AMx_TYPE_3 0x03000000 /* Addess Multiplexing Type 3 */ +#define MxMR_AMx_TYPE_4 0x04000000 /* Addess Multiplexing Type 4 */ +#define MxMR_AMx_TYPE_5 0x05000000 /* Addess Multiplexing Type 5 */ + +#define MxMR_DSx_1_CYCL 0x00000000 /* 1 cycle Disable Period */ +#define MxMR_DSx_2_CYCL 0x00400000 /* 2 cycle Disable Period */ +#define MxMR_DSx_3_CYCL 0x00800000 /* 3 cycle Disable Period */ +#define MxMR_DSx_4_CYCL 0x00c00000 /* 4 cycle Disable Period */ + +#define MxMR_G0CLx_A12 0x00000000 /* General Line 0 : A12 */ +#define MxMR_G0CLx_A11 0x00080000 /* General Line 0 : A11 */ +#define MxMR_G0CLx_A10 0x00100000 /* General Line 0 : A10 */ +#define MxMR_G0CLx_A9 0x00180000 /* General Line 0 : A9 */ +#define MxMR_G0CLx_A8 0x00200000 /* General Line 0 : A8 */ +#define MxMR_G0CLx_A7 0x00280000 /* General Line 0 : A7 */ +#define MxMR_G0CLx_A6 0x00300000 /* General Line 0 : A6 */ +#define MxMR_G0CLx_A5 0x00380000 /* General Line 0 : A5 */ + +#define MxMR_RLFx_1X 0x00004000 /* Read Loop is executed 1 time */ +#define MxMR_RLFx_2X 0x00008000 /* Read Loop is executed 2 times*/ +#define MxMR_RLFx_3X 0x0000c000 /* Read Loop is executed 3 times*/ +#define MxMR_RLFx_4X 0x00010000 /* Read Loop is executed 4 times*/ +#define MxMR_RLFx_5X 0x00014000 /* Read Loop is executed 5 times*/ +#define MxMR_RLFx_6X 0x00018000 /* Read Loop is executed 6 times*/ +#define MxMR_RLFx_7X 0x0001c000 /* Read Loop is executed 7 times*/ +#define MxMR_RLFx_8X 0x00020000 /* Read Loop is executed 8 times*/ +#define MxMR_RLFx_9X 0x00024000 /* Read Loop is executed 9 times*/ +#define MxMR_RLFx_10X 0x00028000 /* Read Loop is executed 10 times*/ +#define MxMR_RLFx_11X 0x0002c000 /* Read Loop is executed 11 times*/ +#define MxMR_RLFx_12X 0x00030000 /* Read Loop is executed 12 times*/ +#define MxMR_RLFx_13X 0x00034000 /* Read Loop is executed 13 times*/ +#define MxMR_RLFx_14X 0x00038000 /* Read Loop is executed 14 times*/ +#define MxMR_RLFx_15X 0x0003c000 /* Read Loop is executed 15 times*/ +#define MxMR_RLFx_16X 0x00000000 /* Read Loop is executed 16 times*/ + +#define MxMR_WLFx_1X 0x00000400 /* Write Loop is executed 1 time*/ +#define MxMR_WLFx_2X 0x00000800 /* Write Loop is executed 2 times*/ +#define MxMR_WLFx_3X 0x00000c00 /* Write Loop is executed 3 times*/ +#define MxMR_WLFx_4X 0x00001000 /* Write Loop is executed 4 times*/ +#define MxMR_WLFx_5X 0x00001400 /* Write Loop is executed 5 times*/ +#define MxMR_WLFx_6X 0x00001800 /* Write Loop is executed 6 times*/ +#define MxMR_WLFx_7X 0x00001c00 /* Write Loop is executed 7 times*/ +#define MxMR_WLFx_8X 0x00002000 /* Write Loop is executed 8 times*/ +#define MxMR_WLFx_9X 0x00002400 /* Write Loop is executed 9 times*/ +#define MxMR_WLFx_10X 0x00002800 /* Write Loop is executed 10 times*/ +#define MxMR_WLFx_11X 0x00002c00 /* Write Loop is executed 11 times*/ +#define MxMR_WLFx_12X 0x00003000 /* Write Loop is executed 12 times*/ +#define MxMR_WLFx_13X 0x00003400 /* Write Loop is executed 13 times*/ +#define MxMR_WLFx_14X 0x00003800 /* Write Loop is executed 14 times*/ +#define MxMR_WLFx_15X 0x00003c00 /* Write Loop is executed 15 times*/ +#define MxMR_WLFx_16X 0x00000000 /* Write Loop is executed 16 times*/ + +#define MxMR_TLFx_1X 0x00000040 /* Timer Loop is executed 1 time*/ +#define MxMR_TLFx_2X 0x00000080 /* Timer Loop is executed 2 times*/ +#define MxMR_TLFx_3X 0x000000c0 /* Timer Loop is executed 3 times*/ +#define MxMR_TLFx_4X 0x00000100 /* Timer Loop is executed 4 times*/ +#define MxMR_TLFx_5X 0x00000140 /* Timer Loop is executed 5 times*/ +#define MxMR_TLFx_6X 0x00000180 /* Timer Loop is executed 6 times*/ +#define MxMR_TLFx_7X 0x000001c0 /* Timer Loop is executed 7 times*/ +#define MxMR_TLFx_8X 0x00000200 /* Timer Loop is executed 8 times*/ +#define MxMR_TLFx_9X 0x00000240 /* Timer Loop is executed 9 times*/ +#define MxMR_TLFx_10X 0x00000280 /* Timer Loop is executed 10 times*/ +#define MxMR_TLFx_11X 0x000002c0 /* Timer Loop is executed 11 times*/ +#define MxMR_TLFx_12X 0x00000300 /* Timer Loop is executed 12 times*/ +#define MxMR_TLFx_13X 0x00000340 /* Timer Loop is executed 13 times*/ +#define MxMR_TLFx_14X 0x00000380 /* Timer Loop is executed 14 times*/ +#define MxMR_TLFx_15X 0x000003c0 /* Timer Loop is executed 15 times*/ +#define MxMR_TLFx_16X 0x00000000 /* Timer Loop is executed 16 times*/ + + +/*----------------------------------------------------------------------- + * BRx - Memory Controller: Base Register 10-14 + */ +#define BRx_BA_MSK 0xffff8000 /* Base Address Mask */ +#define BRx_PS_MSK 0x00001800 /* Port Size Mask */ +#define BRx_DECC_MSK 0x00000600 /* Data Error Correct+Check Mask*/ +#define BRx_WP 0x00000100 /* Write Protect */ +#define BRx_MS_MSK 0x000000e0 /* Machine Select Mask */ +#define BRx_EMEMC 0x00000010 /* External MEMC Enable */ +#define BRx_ATOM_MSK 0x0000000c /* Atomic Operation Mask */ +#define BRx_DR 0x00000002 /* Data Pipelining */ +#define BRx_V 0x00000001 /* Bank Valid */ + +#define BRx_PS_64 0x00000000 /* 64 bit port size (60x bus only)*/ +#define BRx_PS_8 0x00000800 /* 8 bit port size */ +#define BRx_PS_16 0x00001000 /* 16 bit port size */ +#define BRx_PS_32 0x00001800 /* 32 bit port size */ + +#define BRx_DECC_NONE 0x00000000 /* Data Errors Checking Disabled*/ +#define BRx_DECC_NORMAL 0x00000200 /* Normal Parity Checking */ +#define BRx_DECC_RMWPC 0x00000400 /* Read-Modify-Write Parity Checking*/ +#define BRx_DECC_ECC 0x00000600 /* ECC Correction and Checking */ + +#define BRx_MS_GPCM_P 0x00000000 /* G.P.C.M. 60x Bus Machine Select*/ +#define BRx_MS_GPCM_L 0x00000020 /* G.P.C.M. Local Bus Machine Select*/ +#define BRx_MS_SDRAM_P 0x00000040 /* SDRAM 60x Bus Machine Select */ +#define BRx_MS_SDRAM_L 0x00000060 /* SDRAM Local Bus Machine Select*/ +#define BRx_MS_UPMA 0x00000080 /* U.P.M.A Machine Select */ +#define BRx_MS_UPMB 0x000000a0 /* U.P.M.B Machine Select */ +#define BRx_MS_UPMC 0x000000c0 /* U.P.M.C Machine Select */ + +#define BRx_ATOM_RAWA 0x00000004 /* Read-After-Write-Atomic */ +#define BRx_ATOM_WARA 0x00000008 /* Write-After-Read-Atomic */ + +/*----------------------------------------------------------------------- + * ORx - Memory Controller: Option Register - SDRAM Mode 10-16 + */ +#define ORxS_SDAM_MSK 0xfff00000 /* SDRAM Address Mask Mask */ +#define ORxS_LSDAM_MSK 0x000f8000 /* Lower SDRAM Address Mask Mask*/ +#define ORxS_BPD_MSK 0x00006000 /* Banks Per Device Mask */ +#define ORxS_ROWST_MSK 0x00001e00 /* Row Start Address Bit Mask */ +#define ORxS_NUMR_MSK 0x000001c0 /* Number of Row Addr Lines Mask*/ +#define ORxS_PMSEL 0x00000020 /* Page Mode Select */ +#define ORxS_IBID 0x00000010 /* Internal Bank Interleaving Disable*/ + +#define ORxS_BPD_2 0x00000000 /* 2 Banks Per Device */ +#define ORxS_BPD_4 0x00002000 /* 4 Banks Per Device */ +#define ORxS_BPD_8 0x00004000 /* 8 Banks Per Device */ + +/* ROWST values for xSDMR[PBI] = 0 */ +#define ORxS_ROWST_PBI0_A7 0x00000400 /* Row Start Address Bit is A7 */ +#define ORxS_ROWST_PBI0_A8 0x00000800 /* Row Start Address Bit is A8 */ +#define ORxS_ROWST_PBI0_A9 0x00000c00 /* Row Start Address Bit is A9 */ +#define ORxS_ROWST_PBI0_A10 0x00001000 /* Row Start Address Bit is A10 */ +#define ORxS_ROWST_PBI0_A11 0x00001400 /* Row Start Address Bit is A11 */ +#define ORxS_ROWST_PBI0_A12 0x00001800 /* Row Start Address Bit is A12 */ +#define ORxS_ROWST_PBI0_A13 0x00001c00 /* Row Start Address Bit is A13 */ + +/* ROWST values for xSDMR[PBI] = 1 */ +#define ORxS_ROWST_PBI1_A0 0x00000000 /* Row Start Address Bit is A0 */ +#define ORxS_ROWST_PBI1_A1 0x00000200 /* Row Start Address Bit is A1 */ +#define ORxS_ROWST_PBI1_A2 0x00000400 /* Row Start Address Bit is A2 */ +#define ORxS_ROWST_PBI1_A3 0x00000600 /* Row Start Address Bit is A3 */ +#define ORxS_ROWST_PBI1_A4 0x00000800 /* Row Start Address Bit is A4 */ +#define ORxS_ROWST_PBI1_A5 0x00000a00 /* Row Start Address Bit is A5 */ +#define ORxS_ROWST_PBI1_A6 0x00000c00 /* Row Start Address Bit is A6 */ +#define ORxS_ROWST_PBI1_A7 0x00000e00 /* Row Start Address Bit is A7 */ +#define ORxS_ROWST_PBI1_A8 0x00001000 /* Row Start Address Bit is A8 */ +#define ORxS_ROWST_PBI1_A9 0x00001200 /* Row Start Address Bit is A9 */ +#define ORxS_ROWST_PBI1_A10 0x00001400 /* Row Start Address Bit is A10 */ +#define ORxS_ROWST_PBI1_A11 0x00001600 /* Row Start Address Bit is A11 */ +#define ORxS_ROWST_PBI1_A12 0x00001800 /* Row Start Address Bit is A12 */ + +#define ORxS_NUMR_9 0x00000000 /* 9 Row Address Lines */ +#define ORxS_NUMR_10 0x00000040 /* 10 Row Address Lines */ +#define ORxS_NUMR_11 0x00000080 /* 11 Row Address Lines */ +#define ORxS_NUMR_12 0x000000c0 /* 12 Row Address Lines */ +#define ORxS_NUMR_13 0x00000100 /* 13 Row Address Lines */ +#define ORxS_NUMR_14 0x00000140 /* 14 Row Address Lines */ +#define ORxS_NUMR_15 0x00000180 /* 15 Row Address Lines */ +#define ORxS_NUMR_16 0x000001c0 /* 16 Row Address Lines */ + +/* helper to determine the AM for a given size (SDRAM mode) */ +#define ORxS_SIZE_TO_AM(s) ((~((s) - 1)) & 0xffff8000) /* must be pow of 2 */ + +/*----------------------------------------------------------------------- + * ORx - Memory Controller: Option Register - GPCM Mode 10-18 + */ +#define ORxG_AM_MSK 0xffff8000 /* Address Mask Mask */ +#define ORxG_BCTLD 0x00001000 /* Data Buffer Control Disable */ +#define ORxG_CSNT 0x00000800 /* Chip Select Negation Time */ +#define ORxG_ACS_MSK 0x00000600 /* Address to Chip Select Setup mask*/ +#define ORxG_SCY_MSK 0x000000f0 /* Cycle Lenght in Clocks */ +#define ORxG_SETA 0x00000008 /* External Access Termination */ +#define ORxG_TRLX 0x00000004 /* Timing Relaxed */ +#define ORxG_EHTR 0x00000002 /* Extended Hold Time on Read */ + +#define ORxG_ACS_DIV1 0x00000000 /* CS is output at the same time*/ +#define ORxG_ACS_DIV4 0x00000400 /* CS is output 1/4 a clock later*/ +#define ORxG_ACS_DIV2 0x00000600 /* CS is output 1/2 a clock later*/ + +#define ORxG_SCY_0_CLK 0x00000000 /* 0 clock cycles wait states */ +#define ORxG_SCY_1_CLK 0x00000010 /* 1 clock cycles wait states */ +#define ORxG_SCY_2_CLK 0x00000020 /* 2 clock cycles wait states */ +#define ORxG_SCY_3_CLK 0x00000030 /* 3 clock cycles wait states */ +#define ORxG_SCY_4_CLK 0x00000040 /* 4 clock cycles wait states */ +#define ORxG_SCY_5_CLK 0x00000050 /* 5 clock cycles wait states */ +#define ORxG_SCY_6_CLK 0x00000060 /* 6 clock cycles wait states */ +#define ORxG_SCY_7_CLK 0x00000070 /* 7 clock cycles wait states */ +#define ORxG_SCY_8_CLK 0x00000080 /* 8 clock cycles wait states */ +#define ORxG_SCY_9_CLK 0x00000090 /* 9 clock cycles wait states */ +#define ORxG_SCY_10_CLK 0x000000a0 /* 10 clock cycles wait states */ +#define ORxG_SCY_11_CLK 0x000000b0 /* 11 clock cycles wait states */ +#define ORxG_SCY_12_CLK 0x000000c0 /* 12 clock cycles wait states */ +#define ORxG_SCY_13_CLK 0x000000d0 /* 13 clock cycles wait states */ +#define ORxG_SCY_14_CLK 0x000000e0 /* 14 clock cycles wait states */ +#define ORxG_SCY_15_CLK 0x000000f0 /* 15 clock cycles wait states */ + +/*----------------------------------------------------------------------- + * ORx - Memory Controller: Option Register - UPM Mode 10-20 + */ +#define ORxU_AM_MSK 0xffff8000 /* Address Mask Mask */ +#define ORxU_BCTLD 0x00001000 /* Data Buffer Control Disable */ +#define ORxU_BI 0x00000100 /* Burst Inhibit */ +#define ORxU_EHTR_MSK 0x00000006 /* Extended Hold Time on Read Mask*/ + +#define ORxU_EHTR_NORM 0x00000000 /* Normal Timing */ +#define ORxU_EHTR_1IDLE 0x00000002 /* One Idle Clock Cycle Inserted*/ +#define ORxU_EHTR_4IDLE 0x00000004 /* Four Idle Clock Cycles Inserted*/ +#define ORxU_EHTR_8IDLE 0x00000006 /* Eight Idle Clock Cycles Inserted*/ + + +/* helpers to convert values into an OR address mask (GPCM mode) */ +#define P2SZ_TO_AM(s) ((~((s) - 1)) & 0xffff8000) /* must be pow of 2 */ +#define MEG_TO_AM(m) P2SZ_TO_AM((m) << 20) + + +/*----------------------------------------------------------------------- + * PSDMR - 60x SDRAM Mode Register 10-21 + */ +#define PSDMR_PBI 0x80000000 /* Page-based Interleaving */ +#define PSDMR_RFEN 0x40000000 /* Refresh Enable */ +#define PSDMR_OP_MSK 0x38000000 /* SDRAM Operation Mask */ +#define PSDMR_SDAM_MSK 0x07000000 /* SDRAM Address Multiplex Mask */ +#define PSDMR_BSMA_MSK 0x00e00000 /* Bank Select Muxd Addr Line Mask*/ +#define PSDMR_SDA10_MSK 0x001c0000 /* A10 Control Mask */ +#define PSDMR_RFRC_MSK 0x00038000 /* Refresh Recovery Mask */ +#define PSDMR_PRETOACT_MSK 0x00007000 /* Precharge to Activate Intvl Mask*/ +#define PSDMR_ACTTORW_MSK 0x00000e00 /* Activate to Read/Write Intvl Mask*/ +#define PSDMR_BL 0x00000100 /* Burst Length */ +#define PSDMR_LDOTOPRE_MSK 0x000000c0 /* Last Data Out to Precharge Mask*/ +#define PSDMR_WRC_MSK 0x00000030 /* Write Recovery Time Mask */ +#define PSDMR_EAMUX 0x00000008 /* External Address Multiplexing*/ +#define PSDMR_BUFCMD 0x00000004 /* SDRAM ctl lines asrtd for 2 cycles*/ +#define PSDMR_CL_MSK 0x00000003 /* CAS Latency Mask */ + +#define PSDMR_OP_NORM 0x00000000 /* Normal Operation */ +#define PSDMR_OP_CBRR 0x08000000 /* CBR Refresh */ +#define PSDMR_OP_SELFR 0x10000000 /* Self Refresh */ +#define PSDMR_OP_MRW 0x18000000 /* Mode Register Write */ +#define PSDMR_OP_PREB 0x20000000 /* Precharge Bank */ +#define PSDMR_OP_PREA 0x28000000 /* Precharge All Banks */ +#define PSDMR_OP_ACTB 0x30000000 /* Activate Bank */ +#define PSDMR_OP_RW 0x38000000 /* Read/Write */ + +#define PSDMR_SDAM_A13_IS_A5 0x00000000 /* SDRAM Address Multiplex A13 is A5 */ +#define PSDMR_SDAM_A14_IS_A5 0x01000000 /* SDRAM Address Multiplex A14 is A5 */ +#define PSDMR_SDAM_A15_IS_A5 0x02000000 /* SDRAM Address Multiplex A15 is A5 */ +#define PSDMR_SDAM_A16_IS_A5 0x03000000 /* SDRAM Address Multiplex A16 is A5 */ +#define PSDMR_SDAM_A17_IS_A5 0x04000000 /* SDRAM Address Multiplex A17 is A5 */ +#define PSDMR_SDAM_A18_IS_A5 0x05000000 /* SDRAM Address Multiplex A18 is A5 */ + +#define PSDMR_BSMA_A12_A14 0x00000000 /* A12 - A14 */ +#define PSDMR_BSMA_A13_A15 0x00200000 /* A13 - A15 */ +#define PSDMR_BSMA_A14_A16 0x00400000 /* A14 - A16 */ +#define PSDMR_BSMA_A15_A17 0x00600000 /* A15 - A17 */ +#define PSDMR_BSMA_A16_A18 0x00800000 /* A16 - A18 */ +#define PSDMR_BSMA_A17_A19 0x00a00000 /* A17 - A19 */ +#define PSDMR_BSMA_A18_A20 0x00c00000 /* A18 - A20 */ +#define PSDMR_BSMA_A19_A21 0x00e00000 /* A19 - A21 */ + +/* SDA10 values for xSDMR[PBI] = 0 */ +#define PSDMR_SDA10_PBI0_A12 0x00000000 /* "A10" Control is A12 */ +#define PSDMR_SDA10_PBI0_A11 0x00040000 /* "A10" Control is A11 */ +#define PSDMR_SDA10_PBI0_A10 0x00080000 /* "A10" Control is A10 */ +#define PSDMR_SDA10_PBI0_A9 0x000c0000 /* "A10" Control is A9 */ +#define PSDMR_SDA10_PBI0_A8 0x00100000 /* "A10" Control is A8 */ +#define PSDMR_SDA10_PBI0_A7 0x00140000 /* "A10" Control is A7 */ +#define PSDMR_SDA10_PBI0_A6 0x00180000 /* "A10" Control is A6 */ +#define PSDMR_SDA10_PBI0_A5 0x001c0000 /* "A10" Control is A5 */ + +/* SDA10 values for xSDMR[PBI] = 1 */ +#define PSDMR_SDA10_PBI1_A10 0x00000000 /* "A10" Control is A10 */ +#define PSDMR_SDA10_PBI1_A9 0x00040000 /* "A10" Control is A9 */ +#define PSDMR_SDA10_PBI1_A8 0x00080000 /* "A10" Control is A8 */ +#define PSDMR_SDA10_PBI1_A7 0x000c0000 /* "A10" Control is A7 */ +#define PSDMR_SDA10_PBI1_A6 0x00100000 /* "A10" Control is A6 */ +#define PSDMR_SDA10_PBI1_A5 0x00140000 /* "A10" Control is A5 */ +#define PSDMR_SDA10_PBI1_A4 0x00180000 /* "A10" Control is A4 */ +#define PSDMR_SDA10_PBI1_A3 0x001c0000 /* "A10" Control is A3 */ + +#define PSDMR_RFRC_3_CLK 0x00008000 /* 3 Clocks */ +#define PSDMR_RFRC_4_CLK 0x00010000 /* 4 Clocks */ +#define PSDMR_RFRC_5_CLK 0x00018000 /* 5 Clocks */ +#define PSDMR_RFRC_6_CLK 0x00020000 /* 6 Clocks */ +#define PSDMR_RFRC_7_CLK 0x00028000 /* 7 Clocks */ +#define PSDMR_RFRC_8_CLK 0x00030000 /* 8 Clocks */ +#define PSDMR_RFRC_16_CLK 0x00038000 /* 16 Clocks */ + +#define PSDMR_PRETOACT_8W 0x00000000 /* 8 Clock-cycle Wait States */ +#define PSDMR_PRETOACT_1W 0x00001000 /* 1 Clock-cycle Wait States */ +#define PSDMR_PRETOACT_2W 0x00002000 /* 2 Clock-cycle Wait States */ +#define PSDMR_PRETOACT_3W 0x00003000 /* 3 Clock-cycle Wait States */ +#define PSDMR_PRETOACT_4W 0x00004000 /* 4 Clock-cycle Wait States */ +#define PSDMR_PRETOACT_5W 0x00005000 /* 5 Clock-cycle Wait States */ +#define PSDMR_PRETOACT_6W 0x00006000 /* 6 Clock-cycle Wait States */ +#define PSDMR_PRETOACT_7W 0x00007000 /* 7 Clock-cycle Wait States */ + +#define PSDMR_ACTTORW_8W 0x00000000 /* 8 Clock-cycle Wait States */ +#define PSDMR_ACTTORW_1W 0x00000200 /* 1 Clock-cycle Wait States */ +#define PSDMR_ACTTORW_2W 0x00000400 /* 2 Clock-cycle Wait States */ +#define PSDMR_ACTTORW_3W 0x00000600 /* 3 Clock-cycle Wait States */ +#define PSDMR_ACTTORW_4W 0x00000800 /* 4 Clock-cycle Wait States */ +#define PSDMR_ACTTORW_5W 0x00000a00 /* 5 Clock-cycle Wait States */ +#define PSDMR_ACTTORW_6W 0x00000c00 /* 6 Clock-cycle Wait States */ +#define PSDMR_ACTTORW_7W 0x00000e00 /* 7 Clock-cycle Wait States */ + +#define PSDMR_LDOTOPRE_0C 0x00000000 /* 0 Clock Cycles */ +#define PSDMR_LDOTOPRE_1C 0x00000040 /* 1 Clock Cycles */ +#define PSDMR_LDOTOPRE_2C 0x00000080 /* 2 Clock Cycles */ + +#define PSDMR_WRC_4C 0x00000000 /* 4 Clock Cycles */ +#define PSDMR_WRC_1C 0x00000010 /* 1 Clock Cycles */ +#define PSDMR_WRC_2C 0x00000020 /* 2 Clock Cycles */ +#define PSDMR_WRC_3C 0x00000030 /* 3 Clock Cycles */ + +#define PSDMR_CL_1 0x00000001 /* CAS Latency = 1 */ +#define PSDMR_CL_2 0x00000002 /* CAS Latency = 2 */ +#define PSDMR_CL_3 0x00000003 /* CAS Latency = 3 */ + +/*----------------------------------------------------------------------- + * LSDMR - Local Bus SDRAM Mode Register 10-24 + */ + +/* + * No definitions here - the LSDMR has the same fields as the PSDMR. + */ + +/*----------------------------------------------------------------------- + * MPTPR - Memory Refresh Timer Prescaler Register 10-32 + * See User's Manual Errata for the changed definition (matches the + * 8xx now). The wrong prescaler definition causes excessive refreshes + * (typically "divide by 2" when "divide by 32" is intended) which will + * cause unnecessary memory subsystem slowdown. + */ +#define MPTPR_PTP_MSK 0xff00 /* Periodic Timers Prescaler Mask */ +#define MPTPR_PTP_DIV2 0x2000 /* BRGCLK divided by 2 */ +#define MPTPR_PTP_DIV4 0x1000 /* BRGCLK divided by 4 */ +#define MPTPR_PTP_DIV8 0x0800 /* BRGCLK divided by 8 */ +#define MPTPR_PTP_DIV16 0x0400 /* BRGCLK divided by 16 */ +#define MPTPR_PTP_DIV32 0x0200 /* BRGCLK divided by 32 */ +#define MPTPR_PTP_DIV64 0x0100 /* BRGCLK divided by 64 */ + + +/*----------------------------------------------------------------------- + * TGCR1/TGCR2 - Timer Global Configuration Registers 17-4 + */ +#define TGCR1_CAS2 0x80 /* Cascade Timer 1 and 2 */ +#define TGCR1_STP2 0x20 /* Stop timer 2 */ +#define TGCR1_RST2 0x10 /* Reset timer 2 */ +#define TGCR1_GM1 0x08 /* Gate Mode for Pin 1 */ +#define TGCR1_STP1 0x02 /* Stop timer 1 */ +#define TGCR1_RST1 0x01 /* Reset timer 1 */ +#define TGCR2_CAS4 0x80 /* Cascade Timer 3 and 4 */ +#define TGCR2_STP4 0x20 /* Stop timer 4 */ +#define TGCR2_RST4 0x10 /* Reset timer 4 */ +#define TGCR2_GM2 0x08 /* Gate Mode for Pin 2 */ +#define TGCR2_STP3 0x02 /* Stop timer 3 */ +#define TGCR2_RST3 0x01 /* Reset timer 3 */ + + +/*----------------------------------------------------------------------- + * TMR1-TMR4 - Timer Mode Registers 17-6 + */ +#define TMRx_PS_MSK 0xff00 /* Prescaler Value */ +#define TMRx_CE_MSK 0x00c0 /* Capture Edge and Enable Interrupt*/ +#define TMRx_OM 0x0020 /* Output Mode */ +#define TMRx_ORI 0x0010 /* Output Reference Interrupt Enable*/ +#define TMRx_FRR 0x0008 /* Free Run/Restart */ +#define TMRx_ICLK_MSK 0x0006 /* Timer Input Clock Source mask */ +#define TMRx_GE 0x0001 /* Gate Enable */ + +#define TMRx_CE_INTR_DIS 0x0000 /* Disable Interrupt on capture event*/ +#define TMRx_CE_RISING 0x0040 /* Capture on Rising TINx edge only */ +#define TMRx_CE_FALLING 0x0080 /* Capture on Falling TINx edge only */ +#define TMRx_CE_ANY 0x00c0 /* Capture on any TINx edge */ + +#define TMRx_ICLK_IN_CAS 0x0000 /* Internally cascaded input */ +#define TMRx_ICLK_IN_GEN 0x0002 /* Internal General system clock*/ +#define TMRx_ICLK_IN_GEN_DIV16 0x0004 /* Internal General system clk div 16*/ +#define TMRx_ICLK_TIN_PIN 0x0006 /* TINx pin */ + + +/*----------------------------------------------------------------------- + * CMXFCR - CMX FCC Clock Route Register 15-12 + */ +#define CMXFCR_FC1 0x40000000 /* FCC1 connection */ +#define CMXFCR_RF1CS_MSK 0x38000000 /* Receive FCC1 Clock Source Mask */ +#define CMXFCR_TF1CS_MSK 0x07000000 /* Transmit FCC1 Clock Source Mask */ +#define CMXFCR_FC2 0x00400000 /* FCC2 connection */ +#define CMXFCR_RF2CS_MSK 0x00380000 /* Receive FCC2 Clock Source Mask */ +#define CMXFCR_TF2CS_MSK 0x00070000 /* Transmit FCC2 Clock Source Mask */ +#define CMXFCR_FC3 0x00004000 /* FCC3 connection */ +#define CMXFCR_RF3CS_MSK 0x00003800 /* Receive FCC3 Clock Source Mask */ +#define CMXFCR_TF3CS_MSK 0x00000700 /* Transmit FCC3 Clock Source Mask */ + +#define CMXFCR_RF1CS_BRG5 0x00000000 /* Receive FCC1 Clock Source is BRG5 */ +#define CMXFCR_RF1CS_BRG6 0x08000000 /* Receive FCC1 Clock Source is BRG6 */ +#define CMXFCR_RF1CS_BRG7 0x10000000 /* Receive FCC1 Clock Source is BRG7 */ +#define CMXFCR_RF1CS_BRG8 0x18000000 /* Receive FCC1 Clock Source is BRG8 */ +#define CMXFCR_RF1CS_CLK9 0x20000000 /* Receive FCC1 Clock Source is CLK9 */ +#define CMXFCR_RF1CS_CLK10 0x28000000 /* Receive FCC1 Clock Source is CLK10 */ +#define CMXFCR_RF1CS_CLK11 0x30000000 /* Receive FCC1 Clock Source is CLK11 */ +#define CMXFCR_RF1CS_CLK12 0x38000000 /* Receive FCC1 Clock Source is CLK12 */ + +#define CMXFCR_TF1CS_BRG5 0x00000000 /* Transmit FCC1 Clock Source is BRG5 */ +#define CMXFCR_TF1CS_BRG6 0x01000000 /* Transmit FCC1 Clock Source is BRG6 */ +#define CMXFCR_TF1CS_BRG7 0x02000000 /* Transmit FCC1 Clock Source is BRG7 */ +#define CMXFCR_TF1CS_BRG8 0x03000000 /* Transmit FCC1 Clock Source is BRG8 */ +#define CMXFCR_TF1CS_CLK9 0x04000000 /* Transmit FCC1 Clock Source is CLK9 */ +#define CMXFCR_TF1CS_CLK10 0x05000000 /* Transmit FCC1 Clock Source is CLK10 */ +#define CMXFCR_TF1CS_CLK11 0x06000000 /* Transmit FCC1 Clock Source is CLK11 */ +#define CMXFCR_TF1CS_CLK12 0x07000000 /* Transmit FCC1 Clock Source is CLK12 */ + +#define CMXFCR_RF2CS_BRG5 0x00000000 /* Receive FCC2 Clock Source is BRG5 */ +#define CMXFCR_RF2CS_BRG6 0x00080000 /* Receive FCC2 Clock Source is BRG6 */ +#define CMXFCR_RF2CS_BRG7 0x00100000 /* Receive FCC2 Clock Source is BRG7 */ +#define CMXFCR_RF2CS_BRG8 0x00180000 /* Receive FCC2 Clock Source is BRG8 */ +#define CMXFCR_RF2CS_CLK13 0x00200000 /* Receive FCC2 Clock Source is CLK13 */ +#define CMXFCR_RF2CS_CLK14 0x00280000 /* Receive FCC2 Clock Source is CLK14 */ +#define CMXFCR_RF2CS_CLK15 0x00300000 /* Receive FCC2 Clock Source is CLK15 */ +#define CMXFCR_RF2CS_CLK16 0x00380000 /* Receive FCC2 Clock Source is CLK16 */ + +#define CMXFCR_TF2CS_BRG5 0x00000000 /* Transmit FCC2 Clock Source is BRG5 */ +#define CMXFCR_TF2CS_BRG6 0x00010000 /* Transmit FCC2 Clock Source is BRG6 */ +#define CMXFCR_TF2CS_BRG7 0x00020000 /* Transmit FCC2 Clock Source is BRG7 */ +#define CMXFCR_TF2CS_BRG8 0x00030000 /* Transmit FCC2 Clock Source is BRG8 */ +#define CMXFCR_TF2CS_CLK13 0x00040000 /* Transmit FCC2 Clock Source is CLK13 */ +#define CMXFCR_TF2CS_CLK14 0x00050000 /* Transmit FCC2 Clock Source is CLK14 */ +#define CMXFCR_TF2CS_CLK15 0x00060000 /* Transmit FCC2 Clock Source is CLK15 */ +#define CMXFCR_TF2CS_CLK16 0x00070000 /* Transmit FCC2 Clock Source is CLK16 */ + +#define CMXFCR_RF3CS_BRG5 0x00000000 /* Receive FCC3 Clock Source is BRG5 */ +#define CMXFCR_RF3CS_BRG6 0x00000800 /* Receive FCC3 Clock Source is BRG6 */ +#define CMXFCR_RF3CS_BRG7 0x00001000 /* Receive FCC3 Clock Source is BRG7 */ +#define CMXFCR_RF3CS_BRG8 0x00001800 /* Receive FCC3 Clock Source is BRG8 */ +#define CMXFCR_RF3CS_CLK13 0x00002000 /* Receive FCC3 Clock Source is CLK13 */ +#define CMXFCR_RF3CS_CLK14 0x00002800 /* Receive FCC3 Clock Source is CLK14 */ +#define CMXFCR_RF3CS_CLK15 0x00003000 /* Receive FCC3 Clock Source is CLK15 */ +#define CMXFCR_RF3CS_CLK16 0x00003800 /* Receive FCC3 Clock Source is CLK16 */ + +#define CMXFCR_TF3CS_BRG5 0x00000000 /* Transmit FCC3 Clock Source is BRG5 */ +#define CMXFCR_TF3CS_BRG6 0x00000100 /* Transmit FCC3 Clock Source is BRG6 */ +#define CMXFCR_TF3CS_BRG7 0x00000200 /* Transmit FCC3 Clock Source is BRG7 */ +#define CMXFCR_TF3CS_BRG8 0x00000300 /* Transmit FCC3 Clock Source is BRG8 */ +#define CMXFCR_TF3CS_CLK13 0x00000400 /* Transmit FCC3 Clock Source is CLK13 */ +#define CMXFCR_TF3CS_CLK14 0x00000500 /* Transmit FCC3 Clock Source is CLK14 */ +#define CMXFCR_TF3CS_CLK15 0x00000600 /* Transmit FCC3 Clock Source is CLK15 */ +#define CMXFCR_TF3CS_CLK16 0x00000700 /* Transmit FCC3 Clock Source is CLK16 */ + +/*----------------------------------------------------------------------- + * CMXSCR - CMX SCC Clock Route Register 15-14 + */ +#define CMXSCR_GR1 0x80000000 /* Grant Support of SCC1 */ +#define CMXSCR_SC1 0x40000000 /* SCC1 connection */ +#define CMXSCR_RS1CS_MSK 0x38000000 /* Receive SCC1 Clock Source Mask */ +#define CMXSCR_TS1CS_MSK 0x07000000 /* Transmit SCC1 Clock Source Mask */ +#define CMXSCR_GR2 0x00800000 /* Grant Support of SCC2 */ +#define CMXSCR_SC2 0x00400000 /* SCC2 connection */ +#define CMXSCR_RS2CS_MSK 0x00380000 /* Receive SCC2 Clock Source Mask */ +#define CMXSCR_TS2CS_MSK 0x00070000 /* Transmit SCC2 Clock Source Mask */ +#define CMXSCR_GR3 0x00008000 /* Grant Support of SCC3 */ +#define CMXSCR_SC3 0x00004000 /* SCC3 connection */ +#define CMXSCR_RS3CS_MSK 0x00003800 /* Receive SCC3 Clock Source Mask */ +#define CMXSCR_TS3CS_MSK 0x00000700 /* Transmit SCC3 Clock Source Mask */ +#define CMXSCR_GR4 0x00000080 /* Grant Support of SCC4 */ +#define CMXSCR_SC4 0x00000040 /* SCC4 connection */ +#define CMXSCR_RS4CS_MSK 0x00000038 /* Receive SCC4 Clock Source Mask */ +#define CMXSCR_TS4CS_MSK 0x00000007 /* Transmit SCC4 Clock Source Mask */ + +#define CMXSCR_RS1CS_BRG1 0x00000000 /* SCC1 Rx Clock Source is BRG1 */ +#define CMXSCR_RS1CS_BRG2 0x08000000 /* SCC1 Rx Clock Source is BRG2 */ +#define CMXSCR_RS1CS_BRG3 0x10000000 /* SCC1 Rx Clock Source is BRG3 */ +#define CMXSCR_RS1CS_BRG4 0x18000000 /* SCC1 Rx Clock Source is BRG4 */ +#define CMXSCR_RS1CS_CLK11 0x20000000 /* SCC1 Rx Clock Source is CLK11 */ +#define CMXSCR_RS1CS_CLK12 0x28000000 /* SCC1 Rx Clock Source is CLK12 */ +#define CMXSCR_RS1CS_CLK3 0x30000000 /* SCC1 Rx Clock Source is CLK3 */ +#define CMXSCR_RS1CS_CLK4 0x38000000 /* SCC1 Rx Clock Source is CLK4 */ + +#define CMXSCR_TS1CS_BRG1 0x00000000 /* SCC1 Tx Clock Source is BRG1 */ +#define CMXSCR_TS1CS_BRG2 0x01000000 /* SCC1 Tx Clock Source is BRG2 */ +#define CMXSCR_TS1CS_BRG3 0x02000000 /* SCC1 Tx Clock Source is BRG3 */ +#define CMXSCR_TS1CS_BRG4 0x03000000 /* SCC1 Tx Clock Source is BRG4 */ +#define CMXSCR_TS1CS_CLK11 0x04000000 /* SCC1 Tx Clock Source is CLK11 */ +#define CMXSCR_TS1CS_CLK12 0x05000000 /* SCC1 Tx Clock Source is CLK12 */ +#define CMXSCR_TS1CS_CLK3 0x06000000 /* SCC1 Tx Clock Source is CLK3 */ +#define CMXSCR_TS1CS_CLK4 0x07000000 /* SCC1 Tx Clock Source is CLK4 */ + +#define CMXSCR_RS2CS_BRG1 0x00000000 /* SCC2 Rx Clock Source is BRG1 */ +#define CMXSCR_RS2CS_BRG2 0x00080000 /* SCC2 Rx Clock Source is BRG2 */ +#define CMXSCR_RS2CS_BRG3 0x00100000 /* SCC2 Rx Clock Source is BRG3 */ +#define CMXSCR_RS2CS_BRG4 0x00180000 /* SCC2 Rx Clock Source is BRG4 */ +#define CMXSCR_RS2CS_CLK11 0x00200000 /* SCC2 Rx Clock Source is CLK11 */ +#define CMXSCR_RS2CS_CLK12 0x00280000 /* SCC2 Rx Clock Source is CLK12 */ +#define CMXSCR_RS2CS_CLK3 0x00300000 /* SCC2 Rx Clock Source is CLK3 */ +#define CMXSCR_RS2CS_CLK4 0x00380000 /* SCC2 Rx Clock Source is CLK4 */ + +#define CMXSCR_TS2CS_BRG1 0x00000000 /* SCC2 Tx Clock Source is BRG1 */ +#define CMXSCR_TS2CS_BRG2 0x00010000 /* SCC2 Tx Clock Source is BRG2 */ +#define CMXSCR_TS2CS_BRG3 0x00020000 /* SCC2 Tx Clock Source is BRG3 */ +#define CMXSCR_TS2CS_BRG4 0x00030000 /* SCC2 Tx Clock Source is BRG4 */ +#define CMXSCR_TS2CS_CLK11 0x00040000 /* SCC2 Tx Clock Source is CLK11 */ +#define CMXSCR_TS2CS_CLK12 0x00050000 /* SCC2 Tx Clock Source is CLK12 */ +#define CMXSCR_TS2CS_CLK3 0x00060000 /* SCC2 Tx Clock Source is CLK3 */ +#define CMXSCR_TS2CS_CLK4 0x00070000 /* SCC2 Tx Clock Source is CLK4 */ + +#define CMXSCR_RS3CS_BRG1 0x00000000 /* SCC3 Rx Clock Source is BRG1 */ +#define CMXSCR_RS3CS_BRG2 0x00000800 /* SCC3 Rx Clock Source is BRG2 */ +#define CMXSCR_RS3CS_BRG3 0x00001000 /* SCC3 Rx Clock Source is BRG3 */ +#define CMXSCR_RS3CS_BRG4 0x00001800 /* SCC3 Rx Clock Source is BRG4 */ +#define CMXSCR_RS3CS_CLK5 0x00002000 /* SCC3 Rx Clock Source is CLK5 */ +#define CMXSCR_RS3CS_CLK6 0x00002800 /* SCC3 Rx Clock Source is CLK6 */ +#define CMXSCR_RS3CS_CLK7 0x00003000 /* SCC3 Rx Clock Source is CLK7 */ +#define CMXSCR_RS3CS_CLK8 0x00003800 /* SCC3 Rx Clock Source is CLK8 */ + +#define CMXSCR_TS3CS_BRG1 0x00000000 /* SCC3 Tx Clock Source is BRG1 */ +#define CMXSCR_TS3CS_BRG2 0x00000100 /* SCC3 Tx Clock Source is BRG2 */ +#define CMXSCR_TS3CS_BRG3 0x00000200 /* SCC3 Tx Clock Source is BRG3 */ +#define CMXSCR_TS3CS_BRG4 0x00000300 /* SCC3 Tx Clock Source is BRG4 */ +#define CMXSCR_TS3CS_CLK5 0x00000400 /* SCC3 Tx Clock Source is CLK5 */ +#define CMXSCR_TS3CS_CLK6 0x00000500 /* SCC3 Tx Clock Source is CLK6 */ +#define CMXSCR_TS3CS_CLK7 0x00000600 /* SCC3 Tx Clock Source is CLK7 */ +#define CMXSCR_TS3CS_CLK8 0x00000700 /* SCC3 Tx Clock Source is CLK8 */ + +#define CMXSCR_RS4CS_BRG1 0x00000000 /* SCC4 Rx Clock Source is BRG1 */ +#define CMXSCR_RS4CS_BRG2 0x00000008 /* SCC4 Rx Clock Source is BRG2 */ +#define CMXSCR_RS4CS_BRG3 0x00000010 /* SCC4 Rx Clock Source is BRG3 */ +#define CMXSCR_RS4CS_BRG4 0x00000018 /* SCC4 Rx Clock Source is BRG4 */ +#define CMXSCR_RS4CS_CLK5 0x00000020 /* SCC4 Rx Clock Source is CLK5 */ +#define CMXSCR_RS4CS_CLK6 0x00000028 /* SCC4 Rx Clock Source is CLK6 */ +#define CMXSCR_RS4CS_CLK7 0x00000030 /* SCC4 Rx Clock Source is CLK7 */ +#define CMXSCR_RS4CS_CLK8 0x00000038 /* SCC4 Rx Clock Source is CLK8 */ + +#define CMXSCR_TS4CS_BRG1 0x00000000 /* SCC4 Tx Clock Source is BRG1 */ +#define CMXSCR_TS4CS_BRG2 0x00000001 /* SCC4 Tx Clock Source is BRG2 */ +#define CMXSCR_TS4CS_BRG3 0x00000002 /* SCC4 Tx Clock Source is BRG3 */ +#define CMXSCR_TS4CS_BRG4 0x00000003 /* SCC4 Tx Clock Source is BRG4 */ +#define CMXSCR_TS4CS_CLK5 0x00000004 /* SCC4 Tx Clock Source is CLK5 */ +#define CMXSCR_TS4CS_CLK6 0x00000005 /* SCC4 Tx Clock Source is CLK6 */ +#define CMXSCR_TS4CS_CLK7 0x00000006 /* SCC4 Tx Clock Source is CLK7 */ +#define CMXSCR_TS4CS_CLK8 0x00000007 /* SCC4 Tx Clock Source is CLK8 */ + +/*----------------------------------------------------------------------- + * CMXSMR - CMX SMC Clock Route Register 15-17 + */ +#define CMXSMR_SMC1 0x80 /* SMC1 Connection */ +#define CMXSMR_SMC1CS_MSK 0x30 /* SMC1 Clock Source */ +#define CMXSMR_SMC2 0x08 /* SMC2 Connection */ +#define CMXSMR_SMC2CS_MSK 0x03 /* SMC2 Clock Source */ + +#define CMXSMR_SMC1CS_BRG1 0x00 /* SMC1 Tx and Rx Clocks are BRG1 */ +#define CMXSMR_SMC1CS_BRG7 0x10 /* SMC1 Tx and Rx Clocks are BRG7 */ +#define CMXSMR_SMC1CS_CLK7 0x20 /* SMC1 Tx and Rx Clocks are CLK7 */ +#define CMXSMR_SMC1CS_CLK9 0x30 /* SMC1 Tx and Rx Clocks are CLK9 */ + +#define CMXSMR_SMC2CS_BRG2 0x00 /* SMC2 Tx and Rx Clocks are BRG2 */ +#define CMXSMR_SMC2CS_BRG8 0x01 /* SMC2 Tx and Rx Clocks are BRG8 */ +#define CMXSMR_SMC2CS_CLK19 0x02 /* SMC2 Tx and Rx Clocks are CLK19 */ +#define CMXSMR_SMC2CS_CLK20 0x03 /* SMC2 Tx and Rx Clocks are CLK20 */ + +/*----------------------------------------------------------------------- + * miscellaneous + */ + +#define UPMA 1 +#define UPMB 2 +#define UPMC 3 + +#if !defined(__ASSEMBLY__) && defined(CONFIG_WATCHDOG) +static __inline__ void +reset_8260_watchdog(volatile immap_t *immr) +{ + immr->im_siu_conf.sc_swsr = 0x556c; + immr->im_siu_conf.sc_swsr = 0xaa39; +} +#endif /* !__ASSEMBLY && CONFIG_WATCHDOG */ + +#endif /* __MPC8260_H__ */ diff --git a/include/mpc8260_irq.h b/include/mpc8260_irq.h new file mode 100644 index 0000000000..9bee9a335f --- /dev/null +++ b/include/mpc8260_irq.h @@ -0,0 +1,48 @@ +#ifndef _MPC8260_IRQ_H +#define _MPC8260_IRQ_H + +/****************************************************************************/ +/* most of this was ripped out of include/asm-ppc/irq.h from the Linux/PPC */ +/* source. There was no copyright information in the file. */ + +/* + * this is the # irq's for all ppc arch's (pmac/chrp/prep) + * so it is the max of them all + * + * [let's just worry about 8260 for now - mjj] + */ +#define NR_IRQS 64 + +/* The 8260 has an internal interrupt controller with a maximum of + * 64 IRQs. We will use NR_IRQs from above since it is large enough. + * Don't be confused by the 8260 documentation where they list an + * "interrupt number" and "interrupt vector". We are only interested + * in the interrupt vector. There are "reserved" holes where the + * vector number increases, but the interrupt number in the table does not. + * (Document errata updates have fixed this...make sure you have up to + * date processor documentation -- Dan). + */ +#define NR_SIU_INTS 64 + +/* There are many more than these, we will add them as we need them. +*/ +#define SIU_INT_SMC1 ((uint)0x04) +#define SIU_INT_SMC2 ((uint)0x05) +#define SIU_INT_IRQ1 ((uint)0x13) +#define SIU_INT_IRQ2 ((uint)0x14) +#define SIU_INT_IRQ3 ((uint)0x15) +#define SIU_INT_IRQ4 ((uint)0x16) +#define SIU_INT_IRQ5 ((uint)0x17) +#define SIU_INT_IRQ6 ((uint)0x18) +#define SIU_INT_IRQ7 ((uint)0x19) +#define SIU_INT_FCC1 ((uint)0x20) +#define SIU_INT_FCC2 ((uint)0x21) +#define SIU_INT_FCC3 ((uint)0x22) +#define SIU_INT_SCC1 ((uint)0x28) +#define SIU_INT_SCC2 ((uint)0x29) +#define SIU_INT_SCC3 ((uint)0x2a) +#define SIU_INT_SCC4 ((uint)0x2b) + +#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) + +#endif /* _MPC8260_IRQ_H */ diff --git a/include/post.h b/include/post.h index 8bee125f91..d5b4062787 100644 --- a/include/post.h +++ b/include/post.h @@ -29,6 +29,10 @@ #define _POST_WORD_ADDR \ (CONFIG_SYS_SRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET - 0x4)
+#elif defined(CONFIG_MPC8260) +#include <asm/cpm_8260.h> +#define _POST_WORD_ADDR (CONFIG_SYS_IMMR + CPM_POST_WORD_ADDR) + #elif defined(CONFIG_MPC8360) #include <linux/immap_qe.h> #define _POST_WORD_ADDR (CONFIG_SYS_IMMR + CPM_POST_WORD_ADDR) diff --git a/include/ppc_asm.tmpl b/include/ppc_asm.tmpl index 53141b1f71..82884335ed 100644 --- a/include/ppc_asm.tmpl +++ b/include/ppc_asm.tmpl @@ -93,7 +93,31 @@ #define EID 81 #endif /* CONFIG_5xx */
-#if defined(CONFIG_MPC5xxx) +#if defined(CONFIG_MPC8260) + +#define HID2 1011 + +#define HID0_IFEM (1<<7) + +#define HID0_ICE_BITPOS 16 +#define HID0_DCE_BITPOS 17 + +#define IM_REGBASE 0x10000 +#define IM_SYPCR (IM_REGBASE+0x0004) +#define IM_SWSR (IM_REGBASE+0x000e) +#define IM_BR0 (IM_REGBASE+0x0100) +#define IM_OR0 (IM_REGBASE+0x0104) +#define IM_BR1 (IM_REGBASE+0x0108) +#define IM_OR1 (IM_REGBASE+0x010c) +#define IM_BR2 (IM_REGBASE+0x0110) +#define IM_OR2 (IM_REGBASE+0x0114) +#define IM_MPTPR (IM_REGBASE+0x0184) +#define IM_PSDMR (IM_REGBASE+0x0190) +#define IM_PSRT (IM_REGBASE+0x019c) +#define IM_IMMR (IM_REGBASE+0x01a8) +#define IM_SCCR (IM_REGBASE+0x0c80) + +#elif defined(CONFIG_MPC5xxx)
#define HID0_ICE_BITPOS 16 #define HID0_DCE_BITPOS 17 diff --git a/post/drivers/memory.c b/post/drivers/memory.c index b410502873..89725fabbe 100644 --- a/post/drivers/memory.c +++ b/post/drivers/memory.c @@ -170,7 +170,14 @@ DECLARE_GLOBAL_DATA_PTR; */ static void move64(const unsigned long long *src, unsigned long long *dest) { +#if defined(CONFIG_MPC8260) + asm ("lfd 0, 0(3)\n\t" /* fpr0 = *scr */ + "stfd 0, 0(4)" /* *dest = fpr0 */ + : : : "fr0" ); /* Clobbers fr0 */ + return; +#else *dest = *src; +#endif }
/* diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index c8caf98790..77999750c2 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -35,6 +35,7 @@ CONFIG_5xx_CONS_SCI2 CONFIG_5xx_GCLK_FREQ CONFIG_64BIT_PHYS_ADDR CONFIG_66 +CONFIG_8260_CLKIN CONFIG_8349_CLKIN CONFIG_83XX CONFIG_83XX_CLKIN @@ -434,6 +435,7 @@ CONFIG_CONS_EXTC_PINSEL CONFIG_CONS_EXTC_RATE CONFIG_CONS_NONE CONFIG_CONS_ON_SCC +CONFIG_CONS_ON_SMC CONFIG_CONS_SCIF0 CONFIG_CONS_SCIF1 CONFIG_CONS_SCIF2 @@ -793,11 +795,13 @@ CONFIG_ETH2ADDR CONFIG_ETHADDR CONFIG_ETHBASE CONFIG_ETHER_INDEX +CONFIG_ETHER_LOOPBACK_TEST CONFIG_ETHER_NONE CONFIG_ETHER_ON_FCC CONFIG_ETHER_ON_FCC1 CONFIG_ETHER_ON_FCC2 CONFIG_ETHER_ON_FCC3 +CONFIG_ETHER_ON_SCC CONFIG_ETHPRIME CONFIG_ETH_BUFSIZE CONFIG_ETH_RXSIZE @@ -1068,6 +1072,7 @@ CONFIG_HAS_FSL_MPH_USB CONFIG_HAS_FSL_XHCI_USB CONFIG_HAS_POST CONFIG_HAVE_ACPI_RESUME +CONFIG_HAVE_OWN_RESET CONFIG_HCLK_FREQ CONFIG_HDBOOT CONFIG_HDMI_ENCODER_I2C_ADDR @@ -1352,6 +1357,11 @@ CONFIG_KEYSTONE_NAND_MAX_RBL_SIZE CONFIG_KEYSTONE_RBL_NAND CONFIG_KEY_REVOCATION CONFIG_KGDB_BAUDRATE +CONFIG_KGDB_EXTC_PINSEL +CONFIG_KGDB_EXTC_RATE +CONFIG_KGDB_INDEX +CONFIG_KGDB_ON_SCC +CONFIG_KGDB_ON_SMC CONFIG_KGDB_SER_INDEX CONFIG_KILAUEA CONFIG_KIRKWOOD_EGIGA_INIT @@ -1371,6 +1381,7 @@ CONFIG_KMSUPX5 CONFIG_KMTEGR1 CONFIG_KMTEPR2 CONFIG_KMVECT1 +CONFIG_KM_82XX CONFIG_KM_BOARD_EXTRA_ENV CONFIG_KM_BOARD_NAME CONFIG_KM_COGE5UN @@ -1660,6 +1671,9 @@ CONFIG_MPC555 CONFIG_MPC5xxx_FEC CONFIG_MPC5xxx_FEC_MII10 CONFIG_MPC5xxx_FEC_MII100 +CONFIG_MPC8247 +CONFIG_MPC8255 +CONFIG_MPC8272_FAMILY CONFIG_MPC8308 CONFIG_MPC8308RDB CONFIG_MPC8308_P1M @@ -2759,6 +2773,9 @@ CONFIG_SYS_AUXCORE_BOOTDATA CONFIG_SYS_BARGSIZE CONFIG_SYS_BASE_BAUD CONFIG_SYS_BAUDRATE_TABLE +CONFIG_SYS_BCR +CONFIG_SYS_BCR_60x +CONFIG_SYS_BCR_SINGLE CONFIG_SYS_BCSR CONFIG_SYS_BCSR3_PCIE CONFIG_SYS_BCSR5_PCI66EN @@ -2809,6 +2826,8 @@ CONFIG_SYS_BOOT_RAMDISK_HIGH CONFIG_SYS_BR0_64M CONFIG_SYS_BR0_8M CONFIG_SYS_BR0_PRELIM +CONFIG_SYS_BR10_PRELIM +CONFIG_SYS_BR11_PRELIM CONFIG_SYS_BR1_PRELIM CONFIG_SYS_BR2_PRELIM CONFIG_SYS_BR3_CAN @@ -2820,6 +2839,8 @@ CONFIG_SYS_BR6_64M CONFIG_SYS_BR6_8M CONFIG_SYS_BR6_PRELIM CONFIG_SYS_BR7_PRELIM +CONFIG_SYS_BR8_PRELIM +CONFIG_SYS_BR9_PRELIM CONFIG_SYS_BRIGHTNESS CONFIG_SYS_BUSCLK CONFIG_SYS_CACHELINE_SHIFT @@ -2879,6 +2900,7 @@ CONFIG_SYS_CMXFCR_MASK3 CONFIG_SYS_CMXFCR_VALUE1 CONFIG_SYS_CMXFCR_VALUE2 CONFIG_SYS_CMXFCR_VALUE3 +CONFIG_SYS_CMXSCR_VALUE CONFIG_SYS_CORE_SRAM CONFIG_SYS_CORE_SRAM_SIZE CONFIG_SYS_CORTEX_R4 @@ -2905,10 +2927,14 @@ CONFIG_SYS_CPLD_SIZE CONFIG_SYS_CPMFCR_RAMTYPE CONFIG_SYS_CPM_BOOTCOUNT_ADDR CONFIG_SYS_CPM_INTERRUPT +CONFIG_SYS_CPM_POST_WORD_ADDR CONFIG_SYS_CPRI CONFIG_SYS_CPRI_CLK CONFIG_SYS_CPUSPEED CONFIG_SYS_CPU_CLK +CONFIG_SYS_CPU_PCI_IO_START +CONFIG_SYS_CPU_PCI_MEMIO_START +CONFIG_SYS_CPU_PCI_MEM_START CONFIG_SYS_CS0_BASE CONFIG_SYS_CS0_CFG CONFIG_SYS_CS0_CTRL @@ -3270,6 +3296,7 @@ CONFIG_SYS_DEBUG CONFIG_SYS_DEBUG_SERVER_FW_ADDR CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR CONFIG_SYS_DECREMENT_PATTERNS +CONFIG_SYS_DEFAULT_IMMR CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS CONFIG_SYS_DEFAULT_MBAR CONFIG_SYS_DEFAULT_VIDEO_MODE @@ -4025,6 +4052,14 @@ CONFIG_SYS_HOSTNAME CONFIG_SYS_HRCW_HIGH CONFIG_SYS_HRCW_HIGH_BASE CONFIG_SYS_HRCW_LOW +CONFIG_SYS_HRCW_MASTER +CONFIG_SYS_HRCW_SLAVE1 +CONFIG_SYS_HRCW_SLAVE2 +CONFIG_SYS_HRCW_SLAVE3 +CONFIG_SYS_HRCW_SLAVE4 +CONFIG_SYS_HRCW_SLAVE5 +CONFIG_SYS_HRCW_SLAVE6 +CONFIG_SYS_HRCW_SLAVE7 CONFIG_SYS_HSDRAMC CONFIG_SYS_HWINFO_MAGIC CONFIG_SYS_HWINFO_OFFSET @@ -4466,6 +4501,7 @@ CONFIG_SYS_MATRIX_EBI0CSA_VAL CONFIG_SYS_MATRIX_EBICSA_VAL CONFIG_SYS_MATRIX_MCFG_REMAP CONFIG_SYS_MAXARGS +CONFIG_SYS_MAXIDLE CONFIG_SYS_MAX_DATAFLASH_BANKS CONFIG_SYS_MAX_DDR_BAT_SIZE CONFIG_SYS_MAX_DOC_DEVICE @@ -4680,6 +4716,13 @@ CONFIG_SYS_MPC8xxx_PIC_ADDR CONFIG_SYS_MPC92469AC CONFIG_SYS_MPEG_BASE CONFIG_SYS_MPEG_SIZE +CONFIG_SYS_MPTPR +CONFIG_SYS_MPTPR_1BK_2K +CONFIG_SYS_MPTPR_1BK_4K +CONFIG_SYS_MPTPR_1BK_8K +CONFIG_SYS_MPTPR_2BK_2K +CONFIG_SYS_MPTPR_2BK_4K +CONFIG_SYS_MPTPR_2BK_8K CONFIG_SYS_MRAM_BASE CONFIG_SYS_MRAM_SIZE CONFIG_SYS_MRS_OFFS @@ -4895,6 +4938,8 @@ CONFIG_SYS_OR0_8M CONFIG_SYS_OR0_PRELIM CONFIG_SYS_OR0_REMAP CONFIG_SYS_OR1 +CONFIG_SYS_OR10_PRELIM +CONFIG_SYS_OR11_PRELIM CONFIG_SYS_OR1_PRELIM CONFIG_SYS_OR1_REMAP CONFIG_SYS_OR2_PRELIM @@ -4908,6 +4953,8 @@ CONFIG_SYS_OR6_64M CONFIG_SYS_OR6_8M CONFIG_SYS_OR6_PRELIM CONFIG_SYS_OR7_PRELIM +CONFIG_SYS_OR8_PRELIM +CONFIG_SYS_OR9_PRELIM CONFIG_SYS_OR_TIMING_FLASH CONFIG_SYS_OR_TIMING_FLASH_AT_50MHZ CONFIG_SYS_OR_TIMING_MRAM @@ -5130,6 +5177,8 @@ CONFIG_SYS_PCIE_MMAP_SIZE CONFIG_SYS_PCIE_NR_PORTS CONFIG_SYS_PCIE_PHYS CONFIG_SYS_PCIE_VIRT +CONFIG_SYS_PCIMSK0_MASK +CONFIG_SYS_PCIMSK1_MASK CONFIG_SYS_PCISPEED_66 CONFIG_SYS_PCI_64BIT CONFIG_SYS_PCI_BAR0 @@ -5173,6 +5222,17 @@ CONFIG_SYS_PCI_MEM_SIZE CONFIG_SYS_PCI_MMIO_BASE CONFIG_SYS_PCI_MMIO_PHYS CONFIG_SYS_PCI_MMIO_SIZE +CONFIG_SYS_PCI_MSTR0_LOCAL +CONFIG_SYS_PCI_MSTR1_LOCAL +CONFIG_SYS_PCI_MSTR_IO_BUS +CONFIG_SYS_PCI_MSTR_IO_LOCAL +CONFIG_SYS_PCI_MSTR_IO_SIZE +CONFIG_SYS_PCI_MSTR_MEMIO_BUS +CONFIG_SYS_PCI_MSTR_MEMIO_LOCAL +CONFIG_SYS_PCI_MSTR_MEMIO_SIZE +CONFIG_SYS_PCI_MSTR_MEM_BUS +CONFIG_SYS_PCI_MSTR_MEM_LOCAL +CONFIG_SYS_PCI_MSTR_MEM_SIZE CONFIG_SYS_PCI_NR_INBOUND_WIN CONFIG_SYS_PCI_PHYS CONFIG_SYS_PCI_PTM1LA @@ -5245,6 +5305,7 @@ CONFIG_SYS_PHYS_ADDR_HIGH CONFIG_SYS_PHY_UBOOT_BASE CONFIG_SYS_PIB_BASE CONFIG_SYS_PIB_WINDOW_SIZE +CONFIG_SYS_PICMR0_MASK_ATTRIB CONFIG_SYS_PIOC_ASR_VAL CONFIG_SYS_PIOC_BSR_VAL CONFIG_SYS_PIOC_PDR_VAL @@ -5282,6 +5343,9 @@ CONFIG_SYS_PMAN CONFIG_SYS_PMC_BASE CONFIG_SYS_PMC_BASE_PHYS CONFIG_SYS_PME_CLK +CONFIG_SYS_POCMR0_MASK_ATTRIB +CONFIG_SYS_POCMR1_MASK_ATTRIB +CONFIG_SYS_POCMR2_MASK_ATTRIB CONFIG_SYS_PORTTC CONFIG_SYS_POST_BSPEC1 CONFIG_SYS_POST_BSPEC2 @@ -5331,7 +5395,9 @@ CONFIG_SYS_PSC1 CONFIG_SYS_PSC3 CONFIG_SYS_PSC4 CONFIG_SYS_PSC6 +CONFIG_SYS_PSDMR CONFIG_SYS_PSDPAR +CONFIG_SYS_PSRT CONFIG_SYS_PSSR_VAL CONFIG_SYS_PTCPAR CONFIG_SYS_PTDPAR @@ -5374,6 +5440,7 @@ CONFIG_SYS_RCAR_I2C2_BASE CONFIG_SYS_RCAR_I2C2_SPEED CONFIG_SYS_RCAR_I2C3_BASE CONFIG_SYS_RCAR_I2C3_SPEED +CONFIG_SYS_RCCR CONFIG_SYS_RCWH_PCIHOST CONFIG_SYS_READ_SPD CONFIG_SYS_REDUNDAND_ENVIRONMENT @@ -5390,6 +5457,7 @@ CONFIG_SYS_RIO_MEM_BUS CONFIG_SYS_RIO_MEM_PHYS CONFIG_SYS_RIO_MEM_SIZE CONFIG_SYS_RIO_MEM_VIRT +CONFIG_SYS_RMR CONFIG_SYS_ROM_BASE CONFIG_SYS_ROOTPATH CONFIG_SYS_RSTC_RMR_VAL @@ -5426,6 +5494,7 @@ CONFIG_SYS_SCCR_TSEC2ON CONFIG_SYS_SCCR_TSECCM CONFIG_SYS_SCCR_USBDRCM CONFIG_SYS_SCCR_USBMPHCM +CONFIG_SYS_SCC_TOUT_LOOP CONFIG_SYS_SCR CONFIG_SYS_SCRATCH_VA CONFIG_SYS_SCSI_MAXDEVICE @@ -5591,6 +5660,8 @@ CONFIG_SYS_SICRL CONFIG_SYS_SIL1178_I2C CONFIG_SYS_SIMULATE_SPD_EEPROM CONFIG_SYS_SIUMCR +CONFIG_SYS_SIUMCR_HIGH +CONFIG_SYS_SIUMCR_LOW CONFIG_SYS_SJA1000_BASE CONFIG_SYS_SMALL_FLASH CONFIG_SYS_SMC0_CYCLE0_VAL @@ -5598,6 +5669,7 @@ CONFIG_SYS_SMC0_MODE0_VAL CONFIG_SYS_SMC0_PULSE0_VAL CONFIG_SYS_SMC0_SETUP0_VAL CONFIG_SYS_SMC_CSR0_VAL +CONFIG_SYS_SMC_RXBUFLEN CONFIG_SYS_SMI_BASE CONFIG_SYS_SPANSION_BASE CONFIG_SYS_SPANSION_BOOT @@ -5626,6 +5698,7 @@ CONFIG_SYS_SPI_FLASH_U_BOOT_DST CONFIG_SYS_SPI_FLASH_U_BOOT_OFFS CONFIG_SYS_SPI_FLASH_U_BOOT_SIZE CONFIG_SYS_SPI_FLASH_U_BOOT_START +CONFIG_SYS_SPI_INIT_OFFSET CONFIG_SYS_SPI_KERNEL_OFFS CONFIG_SYS_SPI_MXC_WAIT CONFIG_SYS_SPI_RTC_DEVID @@ -5690,6 +5763,7 @@ CONFIG_SYS_TIMER_COUNTS_DOWN CONFIG_SYS_TIMER_PRESCALER CONFIG_SYS_TIMER_RATE CONFIG_SYS_TLB_FOR_BOOT_FLASH +CONFIG_SYS_TMCNTSC CONFIG_SYS_TMPVIRT CONFIG_SYS_TMRINTR_MASK CONFIG_SYS_TMRINTR_NO @@ -6098,6 +6172,7 @@ CONFIG_USB_GADGET_GOKU CONFIG_USB_GADGET_IMX CONFIG_USB_GADGET_M66592 CONFIG_USB_GADGET_MASS_STORAGE +CONFIG_USB_GADGET_MPC8272 CONFIG_USB_GADGET_MQ11XX CONFIG_USB_GADGET_MUSBHSFC CONFIG_USB_GADGET_N9604