diff options
35 files changed, 8298 insertions, 19 deletions
@@ -114,6 +114,9 @@ endif ifeq ($(CPU),mpc85xx) OBJS += cpu/$(CPU)/resetvec.o endif +ifeq ($(CPU),mpc86xx) +OBJS += cpu/$(CPU)/resetvec.o +endif ifeq ($(CPU),bf533) OBJS += cpu/$(CPU)/start1.o cpu/$(CPU)/interrupt.o cpu/$(CPU)/cache.o OBJS += cpu/$(CPU)/cplbhdlr.o cpu/$(CPU)/cplbmgr.o cpu/$(CPU)/flush.o @@ -1421,6 +1424,14 @@ TQM8560_config: unconfig @./mkconfig -a TQM85xx ppc mpc85xx tqm85xx ######################################################################### +## MPC86xx Systems +######################################################################### + +MPC8641HPCN_config: unconfig + @./mkconfig $(@:_config=) ppc mpc86xx mpc8641hpcn + + +######################################################################### ## 74xx/7xx Systems ######################################################################### diff --git a/board/mpc8641hpcn/Makefile b/board/mpc8641hpcn/Makefile new file mode 100644 index 0000000000..d6037c1c4d --- /dev/null +++ b/board/mpc8641hpcn/Makefile @@ -0,0 +1,57 @@ +# +# (C) Copyright 2001 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(BOARD).a + +OBJS := $(BOARD).o oftree.o +SOBJS := init.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $(OBJS) + +%.dtb: %.dts + dtc -f -V 0x10 -I dts -O dtb $< >$@ + +%.c: %.dtb + xxd -i $< \ + | sed -e "s/^unsigned char/const unsigned char/g" \ + | sed -e "s/^unsigned int/const unsigned int/g" > $@ + + +clean: + rm -f $(OBJS) $(SOBJS) *.dtb oftree.c +.PHONY: distclean +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ +ifeq ($(filter distclean, $(MAKECMDGOALS)),) +-include .depend +endif + +######################################################################### diff --git a/board/mpc8641hpcn/config.mk b/board/mpc8641hpcn/config.mk new file mode 100644 index 0000000000..4bdceec4dc --- /dev/null +++ b/board/mpc8641hpcn/config.mk @@ -0,0 +1,31 @@ +# Copyright 2004 Freescale Semiconductor. +# Modified by Jeff Brown (jeffrey@freescale.com) +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +# +# mpc8641hpcn board +# default CCSRBAR is at 0xff700000 +# assume U-Boot is less than 0.5MB +# +TEXT_BASE = 0xfff01000 + +PLATFORM_CPPFLAGS += -DCONFIG_MPC86xx=1 +PLATFORM_CPPFLAGS += -DCONFIG_MPC8641=1 -maltivec -mabi=altivec -msoft-float diff --git a/board/mpc8641hpcn/flash.c b/board/mpc8641hpcn/flash.c new file mode 100644 index 0000000000..e2f7816e10 --- /dev/null +++ b/board/mpc8641hpcn/flash.c @@ -0,0 +1,550 @@ +/* + * (C) Copyright 2003 Motorola Inc. + * Xianghua Xiao,(X.Xiao@motorola.com) + * + * (C) Copyright 2000, 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2001, Stuart Hughes, Lineo Inc, stuarth@lineo.com + * Add support the Sharp chips on the mpc8260ads. + * I started with board/ip860/flash.c and made changes I found in + * the MTD project by David Schleef. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> + +#if !defined(CFG_NO_FLASH) + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +#if defined(CFG_ENV_IS_IN_FLASH) +# ifndef CFG_ENV_ADDR +# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET) +# endif +# ifndef CFG_ENV_SIZE +# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE +# endif +# ifndef CFG_ENV_SECT_SIZE +# define CFG_ENV_SECT_SIZE CFG_ENV_SIZE +# endif +#endif + +#undef DEBUG + +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size (vu_long *addr, flash_info_t *info); +static int write_word (flash_info_t *info, ulong dest, ulong data); +static int clear_block_lock_bit(vu_long * addr); +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ + unsigned long size; + int i; + + /* Init: enable write, + * or we cannot even write flash commands + */ + for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) { + flash_info[i].flash_id = FLASH_UNKNOWN; + + /* set the default sector offset */ + } + + /* Static FLASH Bank configuration here - FIXME XXX */ + + size = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]); + + if (flash_info[0].flash_id == FLASH_UNKNOWN) { + printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", + size, size<<20); + } + + /* Re-do sizing to get full correct info */ + size = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]); + + flash_info[0].size = size; + +#if CFG_MONITOR_BASE >= CFG_FLASH_BASE + /* monitor protection ON by default */ + flash_protect(FLAG_PROTECT_SET, + CFG_MONITOR_BASE, + CFG_MONITOR_BASE+monitor_flash_len-1, + &flash_info[0]); + +#ifdef CFG_ENV_IS_IN_FLASH + /* ENV protection ON by default */ + flash_protect(FLAG_PROTECT_SET, + CFG_ENV_ADDR, + CFG_ENV_ADDR+CFG_ENV_SECT_SIZE-1, + &flash_info[0]); +#endif +#endif + return (size); +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t *info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_INTEL: printf ("Intel "); break; + case FLASH_MAN_SHARP: printf ("Sharp "); break; + default: printf ("Unknown Vendor "); break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_28F016SV: printf ("28F016SV (16 Mbit, 32 x 64k)\n"); + break; + case FLASH_28F160S3: printf ("28F160S3 (16 Mbit, 32 x 512K)\n"); + break; + case FLASH_28F320S3: printf ("28F320S3 (32 Mbit, 64 x 512K)\n"); + break; + case FLASH_LH28F016SCT: printf ("28F016SC (16 Mbit, 32 x 64K)\n"); + break; + case FLASH_28F640J3A: printf ("28F640J3A (64 Mbit, 64 x 128K)\n"); + break; + default: printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i=0; i<info->sector_count; ++i) { + if ((i % 5) == 0) + printf ("\n "); + printf (" %08lX%s", + info->start[i], + info->protect[i] ? " (RO)" : " " + ); + } + printf ("\n"); +} + +/* + * The following code cannot be run from FLASH! + */ + +static ulong flash_get_size (vu_long *addr, flash_info_t *info) +{ + short i; + ulong value; + ulong base = (ulong)addr; + ulong sector_offset; + +#ifdef DEBUG + printf("Check flash at 0x%08x\n",(uint)addr); +#endif + /* Write "Intelligent Identifier" command: read Manufacturer ID */ + *addr = 0x90909090; + udelay(20); + asm("sync"); + + value = addr[0] & 0x00FF00FF; + +#ifdef DEBUG + printf("manufacturer=0x%x\n",(uint)value); +#endif + switch (value) { + case MT_MANUFACT: /* SHARP, MT or => Intel */ + case INTEL_ALT_MANU: + info->flash_id = FLASH_MAN_INTEL; + break; + default: +#if defined(CONFIG_MPC8641_SIM) + info->flash_id = FLASH_MAN_INTEL; + break; +#else + printf("unknown manufacturer: %x\n", (unsigned int)value); + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + return (0); /* no or unknown flash */ +#endif + } + + value = addr[1] & 0x00FF00FF; /* device ID */ + +#ifdef DEBUG + printf("deviceID=0x%x\n",(uint)value); +#endif + switch (value) { + case (INTEL_ID_28F016S): + info->flash_id += FLASH_28F016SV; + info->sector_count = 32; + info->size = 0x00400000; + sector_offset = 0x20000; + break; /* => 2x2 MB */ + + case (INTEL_ID_28F160S3): + info->flash_id += FLASH_28F160S3; + info->sector_count = 32; + info->size = 0x00400000; + sector_offset = 0x20000; + break; /* => 2x2 MB */ + + case (INTEL_ID_28F320S3): + info->flash_id += FLASH_28F320S3; + info->sector_count = 64; + info->size = 0x00800000; + sector_offset = 0x20000; + break; /* => 2x4 MB */ + + case (INTEL_ID_28F640J3A): + info->flash_id += FLASH_28F640J3A; + info->sector_count = 64; + info->size = 0x01000000; + sector_offset = 0x40000; + break; /* => 2x8 MB */ + + case SHARP_ID_28F016SCL: + case SHARP_ID_28F016SCZ: + info->flash_id = FLASH_MAN_SHARP | FLASH_LH28F016SCT; + info->sector_count = 32; + info->size = 0x00800000; + sector_offset = 0x40000; + break; /* => 4x2 MB */ + + + default: +#if defined(CONFIG_MPC8641_SIM) + info->flash_id += FLASH_28F640J3A; + info->sector_count = 64; + info->size = 0x01000000; + sector_offset = 0x40000; + break; /* => 2x8 MB */ +#else + info->flash_id = FLASH_UNKNOWN; + return (0); /* => no or unknown flash */ +#endif + + } + + /* set up sector start address table */ + for (i = 0; i < info->sector_count; i++) { + info->start[i] = base; + base += sector_offset; + /* don't know how to check sector protection */ + info->protect[i] = 0; + } + + /* + * Prevent writes to uninitialized FLASH. + */ + if (info->flash_id != FLASH_UNKNOWN) { + addr = (vu_long *)info->start[0]; + *addr = 0xFFFFFF; /* reset bank to read array mode */ + asm("sync"); + } + + return (info->size); +} + + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ + int flag, prot, sect; + ulong start, now, last; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + if ( ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) + && ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_SHARP) ) { + printf ("Can't erase unknown flash type %08lx - aborted\n", + info->flash_id); + return 1; + } + + prot = 0; + for (sect=s_first; sect<=s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + +#ifdef DEBUG + printf("\nFlash Erase:\n"); +#endif + /* Make Sure Block Lock Bit is not set. */ + if(clear_block_lock_bit((vu_long *)(info->start[s_first]))){ + return 1; + } + + /* Start erase on unprotected sectors */ +#if defined(DEBUG) + printf("Begin to erase now,s_first=0x%x s_last=0x%x...\n",s_first,s_last); +#endif + for (sect = s_first; sect<=s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + vu_long *addr = (vu_long *)(info->start[sect]); + asm("sync"); + + last = start = get_timer (0); + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + /* Reset Array */ + *addr = 0xffffffff; + asm("sync"); + /* Clear Status Register */ + *addr = 0x50505050; + asm("sync"); + /* Single Block Erase Command */ + *addr = 0x20202020; + asm("sync"); + /* Confirm */ + *addr = 0xD0D0D0D0; + asm("sync"); + + if((info->flash_id & FLASH_TYPEMASK) != FLASH_LH28F016SCT) { + /* Resume Command, as per errata update */ + *addr = 0xD0D0D0D0; + asm("sync"); + } + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000); + while ((*addr & 0x00800080) != 0x00800080) { + if(*addr & 0x00200020){ + printf("Error in Block Erase - Lock Bit may be set!\n"); + printf("Status Register = 0x%X\n", (uint)*addr); + *addr = 0xFFFFFFFF; /* reset bank */ + asm("sync"); + return 1; + } + if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) { + printf ("Timeout\n"); + *addr = 0xFFFFFFFF; /* reset bank */ + asm("sync"); + return 1; + } + /* show that we're waiting */ + if ((now - last) > 1000) { /* every second */ + putc ('.'); + last = now; + } + } + + /* reset to read mode */ + *addr = 0xFFFFFFFF; + asm("sync"); + } + } + + printf ("flash erase done\n"); + return 0; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong cp, wp, data; + int i, l, rc; + + wp = (addr & ~3); /* get lower word aligned address */ + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i=0, cp=wp; i<l; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + for (; i<4 && cnt>0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt==0 && i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + } + + /* + * handle word aligned part + */ + while (cnt >= 4) { + data = 0; + for (i=0; i<4; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + cnt -= 4; + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + return (write_word(info, wp, data)); +} + +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_word (flash_info_t *info, ulong dest, ulong data) +{ + vu_long *addr = (vu_long *)dest; + ulong start, csr; + int flag; + + /* Check if Flash is (sufficiently) erased */ + if ((*addr & data) != data) { + return (2); + } + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + /* Write Command */ + *addr = 0x10101010; + asm("sync"); + + /* Write Data */ + *addr = data; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* data polling for D7 */ + start = get_timer (0); + flag = 0; + + while (((csr = *addr) & 0x00800080) != 0x00800080) { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + flag = 1; + break; + } + } + if (csr & 0x40404040) { + printf ("CSR indicates write error (%08lx) at %08lx\n", csr, (ulong)addr); + flag = 1; + } + + /* Clear Status Registers Command */ + *addr = 0x50505050; + asm("sync"); + /* Reset to read array mode */ + *addr = 0xFFFFFFFF; + asm("sync"); + + return (flag); +} + +/*----------------------------------------------------------------------- + * Clear Block Lock Bit, returns: + * 0 - OK + * 1 - Timeout + */ + +static int clear_block_lock_bit(vu_long * addr) +{ + ulong start, now; + + /* Reset Array */ + *addr = 0xffffffff; + asm("sync"); + /* Clear Status Register */ + *addr = 0x50505050; + asm("sync"); + + *addr = 0x60606060; + asm("sync"); + *addr = 0xd0d0d0d0; + asm("sync"); + + start = get_timer (0); + while((*addr & 0x00800080) != 0x00800080){ + if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) { + printf ("Timeout on clearing Block Lock Bit\n"); + *addr = 0xFFFFFFFF; /* reset bank */ + asm("sync"); + return 1; + } + } + return 0; +} + +#endif /* !CFG_NO_FLASH */ diff --git a/board/mpc8641hpcn/init.S b/board/mpc8641hpcn/init.S new file mode 100644 index 0000000000..4d555a509f --- /dev/null +++ b/board/mpc8641hpcn/init.S @@ -0,0 +1,155 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * Jeff Brown (jeffrey@freescale.com) + * Srikanth Srinivasan (srikanth.srinivasan@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <ppc_asm.tmpl> +#include <ppc_defs.h> +#include <asm/cache.h> +#include <asm/mmu.h> +#include <config.h> +#include <mpc86xx.h> + +/* + * LAW(Local Access Window) configuration: + * + * 0x0000_0000 0x7fff_ffff DDR 2G + * 0x8000_0000 0x9fff_ffff PCI1 MEM 512M + * 0xa000_0000 0xbfff_ffff PCI2 MEM 512M + * 0xc000_0000 0xdfff_ffff RapidIO 512M + * 0xe000_0000 0xe000_ffff CCSR 1M + * 0xe200_0000 0xe2ff_ffff PCI1 IO 16M + * 0xe300_0000 0xe3ff_ffff PCI2 IO 16M + * 0xf000_0000 0xf7ff_ffff SDRAM 128M + * 0xf800_0000 0xf80f_ffff BCSR 1M + * 0xfe00_0000 0xffff_ffff FLASH (boot bank) 32M + * + * Notes: + * CCSRBAR don't need a configured Local Access Window. + * If flash is 8M at default position (last 8M), no LAW needed. + */ + +#if !defined(CONFIG_SPD_EEPROM) +#define LAWBAR1 ((CFG_DDR_SDRAM_BASE>>12) & 0xffffff) +#define LAWAR1 (LAWAR_EN | LAWAR_TRGT_IF_DDR1 | (LAWAR_SIZE & LAWAR_SIZE_256M)) +#else +#define LAWBAR1 0 +#define LAWAR1 ((LAWAR_TRGT_IF_DDR1 | (LAWAR_SIZE & LAWAR_SIZE_512M)) & ~LAWAR_EN) +#endif + +#define LAWBAR2 ((CFG_PCI1_MEM_BASE>>12) & 0xffffff) +#define LAWAR2 (LAWAR_EN | LAWAR_TRGT_IF_PCI1 | (LAWAR_SIZE & LAWAR_SIZE_512M)) + +#define LAWBAR3 ((CFG_PCI2_MEM_BASE>>12) & 0xffffff) +/*#define LAWAR3 (LAWAR_EN | LAWAR_TRGT_IF_PCI2 | (LAWAR_SIZE & LAWAR_SIZE_512M)) */ +#define LAWAR3 (~LAWAR_EN & (LAWAR_TRGT_IF_PCI2 | (LAWAR_SIZE & LAWAR_SIZE_512M))) + +/* + * This is not so much the SDRAM map as it is the whole localbus map. + */ +#define LAWBAR4 ((0xf8100000>>12) & 0xffffff) +#define LAWAR4 (LAWAR_EN | LAWAR_TRGT_IF_LBC | (LAWAR_SIZE & LAWAR_SIZE_2M)) + +#define LAWBAR5 ((CFG_PCI1_IO_BASE>>12) & 0xffffff) +#define LAWAR5 (LAWAR_EN | LAWAR_TRGT_IF_PCI1 | (LAWAR_SIZE & LAWAR_SIZE_16M)) + +#define LAWBAR6 ((CFG_PCI2_IO_BASE>>12) & 0xffffff) +/*#define LAWAR6 (LAWAR_EN | LAWAR_TRGT_IF_PCI2 | (LAWAR_SIZE & LAWAR_SIZE_16M)) */ +#define LAWAR6 (~LAWAR_EN &( LAWAR_TRGT_IF_PCI2 | (LAWAR_SIZE & LAWAR_SIZE_16M))) + + #define LAWBAR7 ((0xfe000000 >>12) & 0xffffff) + #define LAWAR7 (LAWAR_EN | LAWAR_TRGT_IF_LBC | (LAWAR_SIZE & LAWAR_SIZE_32M)) + + + .section .bootpg, "ax" + .globl law_entry +law_entry: + lis r7,CFG_CCSRBAR@h + ori r7,r7,CFG_CCSRBAR@l + + addi r4,r7,0 + addi r5,r7,0 + + /* Skip LAWAR0, start at LAWAR1 */ + lis r6,LAWBAR1@h + ori r6,r6,LAWBAR1@l + stwu r6, 0xc28(r4) + + lis r6,LAWAR1@h + ori r6,r6,LAWAR1@l + stwu r6, 0xc30(r5) + + /* LAWBAR2, LAWAR2 */ + lis r6,LAWBAR2@h + ori r6,r6,LAWBAR2@l + stwu r6, 0x20(r4) + + lis r6,LAWAR2@h + ori r6,r6,LAWAR2@l + stwu r6, 0x20(r5) + + /* LAWBAR3, LAWAR3 */ + lis r6,LAWBAR3@h + ori r6,r6,LAWBAR3@l + stwu r6, 0x20(r4) + + lis r6,LAWAR3@h + ori r6,r6,LAWAR3@l + stwu r6, 0x20(r5) + + /* LAWBAR4, LAWAR4 */ + lis r6,LAWBAR4@h + ori r6,r6,LAWBAR4@l + stwu r6, 0x20(r4) + + lis r6,LAWAR4@h + ori r6,r6,LAWAR4@l + stwu r6, 0x20(r5) + /* LAWBAR5, LAWAR5 */ + lis r6,LAWBAR5@h + ori r6,r6,LAWBAR5@l + stwu r6, 0x20(r4) + + lis r6,LAWAR5@h + ori r6,r6,LAWAR5@l + stwu r6, 0x20(r5) + + /* LAWBAR6, LAWAR6 */ + lis r6,LAWBAR6@h + ori r6,r6,LAWBAR6@l + stwu r6, 0x20(r4) + + lis r6,LAWAR6@h + ori r6,r6,LAWAR6@l + stwu r6, 0x20(r5) + + /* LAWBAR7, LAWAR7 */ + lis r6,LAWBAR7@h + ori r6,r6,LAWBAR7@l + stwu r6, 0x20(r4) + + lis r6,LAWAR7@h + ori r6,r6,LAWAR7@l + stwu r6, 0x20(r5) + + blr + diff --git a/board/mpc8641hpcn/mpc8641hpcn.c b/board/mpc8641hpcn/mpc8641hpcn.c new file mode 100644 index 0000000000..ace6d47fde --- /dev/null +++ b/board/mpc8641hpcn/mpc8641hpcn.c @@ -0,0 +1,306 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * Jeff Brown (jeffrey@freescale.com) + * Srikanth Srinivasan (srikanth.srinivasan@freescale.com) + * + * (C) Copyright 2002 Scott McNutt <smcnutt@artesyncp.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <pci.h> +#include <asm/processor.h> +#include <asm/immap_86xx.h> +#include <spd.h> + +#if defined(CONFIG_OF_FLAT_TREE) +#include <ft_build.h> +extern void ft_cpu_setup(void *blob, bd_t *bd); +#endif + +#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) +extern void ddr_enable_ecc(unsigned int dram_size); +#endif + +extern long int spd_sdram(void); + +void local_bus_init(void); +void sdram_init(void); +long int fixed_sdram(void); + + +int board_early_init_f (void) +{ + return 0; +} + +int checkboard (void) +{ + puts("Board: MPC8641HPCN\n"); + +#ifdef CONFIG_PCI + + volatile immap_t *immap = (immap_t *) CFG_CCSRBAR; + volatile ccsr_gur_t *gur = &immap->im_gur; + volatile ccsr_pex_t *pex1 = &immap->im_pex1; + + uint devdisr = gur->devdisr; + uint io_sel = (gur->pordevsr & MPC86xx_PORDEVSR_IO_SEL) >> 16; + uint host1_agent = (gur->porbmsr & MPC86xx_PORBMSR_HA) >> 17; + uint pex1_agent = (host1_agent == 0) || (host1_agent == 1); + + + if ((io_sel==2 || io_sel==3 || io_sel==5 \ + || io_sel==6 || io_sel==7 || io_sel==0xF) + && !(devdisr & MPC86xx_DEVDISR_PCIEX1)){ + debug ("PCI-EXPRESS 1: %s \n", + pex1_agent ? "Agent" : "Host"); + debug("0x%08x=0x%08x ", &pex1->pme_msg_det,pex1->pme_msg_det); + if (pex1->pme_msg_det) { + pex1->pme_msg_det = 0xffffffff; + debug (" with errors. Clearing. Now 0x%08x", + pex1->pme_msg_det); + } + debug ("\n"); + } else { + printf ("PCI-EXPRESS 1: Disabled\n"); + } + +#else + printf("PCI-EXPRESS1: Disabled\n"); +#endif + + /* + * Initialize local bus. + */ + local_bus_init(); + + return 0; +} + + +long int +initdram(int board_type) +{ + long dram_size = 0; + extern long spd_sdram (void); + +#if defined(CONFIG_SPD_EEPROM) + dram_size = spd_sdram (); +#else + dram_size = fixed_sdram (); +#endif + +#if defined(CFG_RAMBOOT) + puts(" DDR: "); + return dram_size; +#endif + +#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) + /* + * Initialize and enable DDR ECC. + */ + ddr_enable_ecc(dram_size); +#endif + + puts(" DDR: "); + return dram_size; +} + + +/* + * Initialize Local Bus + */ + +void +local_bus_init(void) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_lbc_t *lbc = &immap->im_lbc; + + uint clkdiv; + uint lbc_hz; + sys_info_t sysinfo; + + /* + * Errata LBC11. + * Fix Local Bus clock glitch when DLL is enabled. + * + * If localbus freq is < 66Mhz, DLL bypass mode must be used. + * If localbus freq is > 133Mhz, DLL can be safely enabled. + * Between 66 and 133, the DLL is enabled with an override workaround. + */ + + get_sys_info(&sysinfo); + clkdiv = lbc->lcrr & 0x0f; + lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv; +} + +#if defined(CFG_DRAM_TEST) +int testdram(void) +{ + uint *pstart = (uint *) CFG_MEMTEST_START; + uint *pend = (uint *) CFG_MEMTEST_END; + uint *p; + + printf("SDRAM test phase 1:\n"); + for (p = pstart; p < pend; p++) + *p = 0xaaaaaaaa; + + for (p = pstart; p < pend; p++) { + if (*p != 0xaaaaaaaa) { + printf ("SDRAM test fails at: %08x\n", (uint) p); + return 1; + } + } + + printf("SDRAM test phase 2:\n"); + for (p = pstart; p < pend; p++) + *p = 0x55555555; + + for (p = pstart; p < pend; p++) { + if (*p != 0x55555555) { + printf ("SDRAM test fails at: %08x\n", (uint) p); + return 1; + } + } + + printf("SDRAM test passed.\n"); + return 0; +} +#endif + + +#if !defined(CONFIG_SPD_EEPROM) +/* + * Fixed sdram init -- doesn't use serial presence detect. + */ +long int fixed_sdram(void) +{ +#if !defined(CFG_RAMBOOT) + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_ddr_t *ddr= &immap->im_ddr1; + + ddr->cs0_bnds = CFG_DDR_CS0_BNDS; + ddr->cs0_config = CFG_DDR_CS0_CONFIG; + ddr->ext_refrec = CFG_DDR_EXT_REFRESH; + ddr->timing_cfg_0 = CFG_DDR_TIMING_0; + ddr->timing_cfg_1 = CFG_DDR_TIMING_1; + ddr->timing_cfg_2 = CFG_DDR_TIMING_2; + ddr->sdram_mode_1 = CFG_DDR_MODE_1; + ddr->sdram_mode_2 = CFG_DDR_MODE_2; + ddr->sdram_interval = CFG_DDR_INTERVAL; + ddr->sdram_data_init = CFG_DDR_DATA_INIT; + ddr->sdram_clk_cntl = CFG_DDR_CLK_CTRL; + ddr->sdram_ocd_cntl = CFG_DDR_OCD_CTRL; + ddr->sdram_ocd_status = CFG_DDR_OCD_STATUS; + +#if defined (CONFIG_DDR_ECC) + ddr->err_disable = 0x0000008D; + ddr->err_sbe = 0x00ff0000; +#endif + asm("sync;isync"); + + udelay(500); + +#if defined (CONFIG_DDR_ECC) + /* Enable ECC checking */ + ddr->sdram_cfg_1 = (CFG_DDR_CONTROL | 0x20000000); +#else + ddr->sdram_cfg_1 = CFG_DDR_CONTROL; + ddr->sdram_cfg_2 = CFG_DDR_CONTROL2; +#endif + asm("sync; isync"); + + udelay(500); +#endif + return CFG_SDRAM_SIZE * 1024 * 1024; +} +#endif /* !defined(CONFIG_SPD_EEPROM) */ + + +#if defined(CONFIG_PCI) +/* + * Initialize PCI Devices, report devices found. + */ + +#ifndef CONFIG_PCI_PNP +static struct pci_config_table pci_fsl86xxads_config_table[] = { + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_IDSEL_NUMBER, PCI_ANY_ID, + pci_cfgfunc_config_device, { PCI_ENET0_IOADDR, + PCI_ENET0_MEMADDR, + PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER + } }, + { } +}; +#endif + + +static struct pci_controller hose = { +#ifndef CONFIG_PCI_PNP + config_table: pci_mpc86xxcts_config_table, +#endif +}; + +#endif /* CONFIG_PCI */ + + +void +pci_init_board(void) +{ +#ifdef CONFIG_PCI + extern void pci_mpc86xx_init(struct pci_controller *hose); + + pci_mpc86xx_init(&hose); +#endif /* CONFIG_PCI */ +} + +#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) +void +ft_board_setup(void *blob, bd_t *bd) +{ + u32 *p; + int len; + + ft_cpu_setup(blob, bd); + + p = ft_get_prop(blob, "/memory/reg", &len); + if (p != NULL) { + *p++ = cpu_to_be32(bd->bi_memstart); + *p = cpu_to_be32(bd->bi_memsize); + } + +} +#endif + +void +after_reloc(ulong dest_addr) +{ + DECLARE_GLOBAL_DATA_PTR; + + /* now, jump to the main U-Boot board init code */ + board_init_r ((gd_t *)gd, dest_addr); + + /* NOTREACHED */ +} + + + diff --git a/board/mpc8641hpcn/oftree.dts b/board/mpc8641hpcn/oftree.dts new file mode 100644 index 0000000000..8e38047e72 --- /dev/null +++ b/board/mpc8641hpcn/oftree.dts @@ -0,0 +1,186 @@ +/* + * MPC8641 HPCN Device Tree Source + * + * Copyright 2006 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + + +/ { + model = "MPC8641HPCN"; + compatible = "mpc86xx"; + #address-cells = <1>; + #size-cells = <1>; + linux,phandle = <100>; + + cpus { + #cpus = <1>; + #address-cells = <1>; + #size-cells = <0>; + linux,phandle = <200>; + + PowerPC,8641@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <20>; // 32 bytes + i-cache-line-size = <20>; // 32 bytes + d-cache-size = <8000>; // L1, 32K + i-cache-size = <8000>; // L1, 32K + timebase-frequency = <0>; // 33 MHz, from uboot + bus-frequency = <0>; // 166 MHz + clock-frequency = <0>; // 825 MHz, from uboot + 32-bit; + linux,phandle = <201>; + linux,boot-cpu; + }; + }; + + memory { + device_type = "memory"; + linux,phandle = <300>; + reg = <00000000 10000000>; // 256M at 0x0 + }; + + soc8641@f8000000 { + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <2>; + device_type = "soc"; + ranges = <0 f8000000 00100000>; + reg = <f8000000 00100000>; // CCSRBAR 1M + bus-frequency = <0>; + + i2c@3000 { + device_type = "i2c"; + compatible = "fsl-i2c"; + reg = <3000 100>; + interrupts = <1b 0>; + interrupt-parent = <40000>; + dfsrr; + }; + + mdio@24520 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "mdio"; + compatible = "gianfar"; + reg = <24520 20>; + linux,phandle = <24520>; + ethernet-phy@0 { + linux,phandle = <2452000>; + interrupt-parent = <40000>; + interrupts = <35 0>; + reg = <0>; + device_type = "ethernet-phy"; + }; + ethernet-phy@1 { + linux,phandle = <2452001>; + interrupt-parent = <40000>; + interrupts = <35 0>; + reg = <1>; + device_type = "ethernet-phy"; + }; + ethernet-phy@2 { + linux,phandle = <2452002>; + interrupt-parent = <40000>; + interrupts = <35 0>; + reg = <2>; + device_type = "ethernet-phy"; + }; + ethernet-phy@3 { + linux,phandle = <2452003>; + interrupt-parent = <40000>; + interrupts = <35 0>; + reg = <3>; + device_type = "ethernet-phy"; + }; + }; + + ethernet@24000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <24000 1000>; + address = [ 00 E0 0C 00 73 00 ]; + interrupts = <d 3 e 3 12 3>; + interrupt-parent = <40000>; + phy-handle = <2452000>; + }; + + ethernet@25000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <25000 1000>; + address = [ 00 E0 0C 00 73 01 ]; + interrupts = <13 3 14 3 18 3>; + interrupt-parent = <40000>; + phy-handle = <2452001>; + }; + + ethernet@26000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <26000 1000>; + address = [ 00 E0 0C 00 02 FD ]; + interrupts = <F 3 10 3 11 3>; + interrupt-parent = <40000>; + phy-handle = <2452002>; + }; + + ethernet@27000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <27000 1000>; + address = [ 00 E0 0C 00 03 FD ]; + interrupts = <15 3 16 3 17 3>; + interrupt-parent = <40000>; + phy-handle = <2452003>; + }; + serial@4500 { + device_type = "serial"; + compatible = "ns16550"; + reg = <4500 100>; // reg base, size + clock-frequency = <0>; // should we fill in in uboot? + interrupts = <1a 3>; + interrupt-parent = <40000>; + }; + + serial@4600 { + device_type = "serial"; + compatible = "ns16550"; + reg = <4600 100>; // reg base, size + clock-frequency = <0>; // should we fill in in uboot? + interrupts = <1a 3>; + interrupt-parent = <40000>; + }; + + pic@40000 { + linux,phandle = <40000>; + clock-frequency = <0>; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <2>; + reg = <40000 40000>; + built-in; + compatible = "chrp,open-pic"; + device_type = "open-pic"; + big-endian; + }; + }; +}; + diff --git a/board/mpc8641hpcn/u-boot.lds b/board/mpc8641hpcn/u-boot.lds new file mode 100644 index 0000000000..c5c40e7eb4 --- /dev/null +++ b/board/mpc8641hpcn/u-boot.lds @@ -0,0 +1,148 @@ +/* + * (C) Copyright 2004, Freescale, Inc. + * (C) Copyright 2002,2003, Motorola,Inc. + * Jeff Brown (jeffrey@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + .resetvec 0xFFF00100 : + { + *(.resetvec) + } = 0xffff + + .bootpg 0xFFF70000 : + { + cpu/mpc86xx/start.o (.bootpg) + board/mpc8641hpcn/init.o (.bootpg) + } = 0xffff + + /* Read-only sections, merged into text segment: */ + . = + 1024; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + cpu/mpc86xx/start.o (.text) + board/mpc8641hpcn/init.o (.text) + cpu/mpc86xx/traps.o (.text) + cpu/mpc86xx/interrupts.o (.text) + cpu/mpc86xx/cpu_init.o (.text) + cpu/mpc86xx/cpu.o (.text) + cpu/mpc86xx/speed.o (.text) + cpu/mpc86xx/pci.o (.text) + common/dlmalloc.o (.text) + lib_generic/crc32.o (.text) + lib_ppc/extable.o (.text) + lib_generic/zlib.o (.text) + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; + __fixup_entries = (. - _FIXUP_TABLE_) >> 2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(256); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(256); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} diff --git a/common/ft_build.c b/common/ft_build.c index 9e9c906fc1..782046ddae 100644 --- a/common/ft_build.c +++ b/common/ft_build.c @@ -299,16 +299,16 @@ static void print_data(const void *data, int len) switch (len) { case 1: /* byte */ - printf(" = <0x%02x>", (*(u8 *) data) & 0xff); + printf(" = <%02x>", (*(u8 *) data) & 0xff); break; case 2: /* half-word */ - printf(" = <0x%04x>", be16_to_cpu(*(u16 *) data) & 0xffff); + printf(" = <%04x>", be16_to_cpu(*(u16 *) data) & 0xffff); break; case 4: /* word */ - printf(" = <0x%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU); + printf(" = <%x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU); break; case 8: /* double-word */ - printf(" = <0x%16llx>", be64_to_cpu(*(uint64_t *) data)); + printf(" = <%qx>", be64_to_cpu(*(uint64_t *) data)); break; default: /* anything else... hexdump */ printf(" = ["); @@ -350,7 +350,7 @@ void ft_dump_blob(const void *bphp) if (addr == 0 && size == 0) break; - printf("/memreserve/ 0x%llx 0x%llx;\n", addr, size); + printf("/memreserve/ %qx %qx;\n", addr, size); } p = p_struct; diff --git a/cpu/mpc86xx/Makefile b/cpu/mpc86xx/Makefile new file mode 100644 index 0000000000..0dd099df6a --- /dev/null +++ b/cpu/mpc86xx/Makefile @@ -0,0 +1,48 @@ +# +# (C) Copyright 2002,2003 Motorola Inc. +# Xianghua Xiao,X.Xiao@motorola.com +# +# (C) Copyright 2004 Freescale Semiconductor. (MC86xx Port) +# Jeff Brown (Jeffrey@freescale.com) +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(CPU).a + +START = start.o #resetvec.o +ASOBJS = cache.o +COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o \ + pci.o i2c.o spd_sdram.o +OBJS = $(COBJS) + +all: .depend $(START) $(ASOBJS) $(LIB) + +$(LIB): $(OBJS) + $(AR) crv $@ $(ASOBJS) $(OBJS) + +######################################################################### + +.depend: Makefile $(START:.o=.S) $(ASOBJS:.o=.S) $(COBJS:.o=.c) + $(CC) -M $(CFLAGS) $(START:.o=.S) $(ASOBJS:.o=.S) $(COBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/cpu/mpc86xx/cache.S b/cpu/mpc86xx/cache.S new file mode 100644 index 0000000000..75186b1e4b --- /dev/null +++ b/cpu/mpc86xx/cache.S @@ -0,0 +1,368 @@ +#include <config.h> +#include <mpc86xx.h> +#include <version.h> + +#include <ppc_asm.tmpl> +#include <ppc_defs.h> + +#include <asm/cache.h> +#include <asm/mmu.h> + +#ifndef CACHE_LINE_SIZE +# define CACHE_LINE_SIZE L1_CACHE_BYTES +#endif + +#if CACHE_LINE_SIZE == 128 +#define LG_CACHE_LINE_SIZE 7 +#elif CACHE_LINE_SIZE == 32 +#define LG_CACHE_LINE_SIZE 5 +#elif CACHE_LINE_SIZE == 16 +#define LG_CACHE_LINE_SIZE 4 +#elif CACHE_LINE_SIZE == 8 +#define LG_CACHE_LINE_SIZE 3 +#else +# error "Invalid cache line size!" +#endif + +/* + * Most of this code is taken from 74xx_7xx/cache.S + * and then cleaned up a bit + */ + +/* + * Invalidate L1 instruction cache. + */ +_GLOBAL(invalidate_l1_instruction_cache) + /* use invalidate-all bit in HID0 */ + mfspr r3,HID0 + ori r3,r3,HID0_ICFI + mtspr HID0,r3 + isync + blr + +/* + * Invalidate L1 data cache. + */ +_GLOBAL(invalidate_l1_data_cache) + mfspr r3,HID0 + ori r3,r3,HID0_DCFI + mtspr HID0,r3 + isync + blr + +/* + * Flush data cache. + */ +_GLOBAL(flush_data_cache) + lis r3,0 + lis r5,CACHE_LINE_SIZE +flush: + cmp 0,1,r3,r5 + bge done + lwz r5,0(r3) + lis r5,CACHE_LINE_SIZE + addi r3,r3,0x4 + b flush +done: + blr +/* + * Write any modified data cache blocks out to memory + * and invalidate the corresponding instruction cache blocks. + * This is a no-op on the 601. + * + * flush_icache_range(unsigned long start, unsigned long stop) + */ +_GLOBAL(flush_icache_range) + li r5,CACHE_LINE_SIZE-1 + andc r3,r3,r5 + subf r4,r3,r4 + add r4,r4,r5 + srwi. r4,r4,LG_CACHE_LINE_SIZE + beqlr + mtctr r4 + mr r6,r3 +1: dcbst 0,r3 + addi r3,r3,CACHE_LINE_SIZE + bdnz 1b + sync /* wait for dcbst's to get to ram */ + mtctr r4 +2: icbi 0,r6 + addi r6,r6,CACHE_LINE_SIZE + bdnz 2b + sync /* additional sync needed on g4 */ + isync + blr +/* + * Write any modified data cache blocks out to memory. + * Does not invalidate the corresponding cache lines (especially for + * any corresponding instruction cache). + * + * clean_dcache_range(unsigned long start, unsigned long stop) + */ +_GLOBAL(clean_dcache_range) + li r5,CACHE_LINE_SIZE-1 + andc r3,r3,r5 /* align r3 down to cache line */ + subf r4,r3,r4 /* r4 = offset of stop from start of cache line */ + add r4,r4,r5 /* r4 += cache_line_size-1 */ + srwi. r4,r4,LG_CACHE_LINE_SIZE /* r4 = number of cache lines to flush */ + beqlr /* if r4 == 0 return */ + mtctr r4 /* ctr = r4 */ + + sync +1: dcbst 0,r3 + addi r3,r3,CACHE_LINE_SIZE + bdnz 1b + sync /* wait for dcbst's to get to ram */ + blr + +/* + * Write any modified data cache blocks out to memory + * and invalidate the corresponding instruction cache blocks. + * + * flush_dcache_range(unsigned long start, unsigned long stop) + */ +_GLOBAL(flush_dcache_range) + li r5,CACHE_LINE_SIZE-1 + andc r3,r3,r5 + subf r4,r3,r4 + add r4,r4,r5 + srwi. r4,r4,LG_CACHE_LINE_SIZE + beqlr + mtctr r4 + + sync +1: dcbf 0,r3 + addi r3,r3,CACHE_LINE_SIZE + bdnz 1b + sync /* wait for dcbf's to get to ram */ + blr + +/* + * Like above, but invalidate the D-cache. This is used by the 8xx + * to invalidate the cache so the PPC core doesn't get stale data + * from the CPM (no cache snooping here :-). + * + * invalidate_dcache_range(unsigned long start, unsigned long stop) + */ +_GLOBAL(invalidate_dcache_range) + li r5,CACHE_LINE_SIZE-1 + andc r3,r3,r5 + subf r4,r3,r4 + add r4,r4,r5 + srwi. r4,r4,LG_CACHE_LINE_SIZE + beqlr + mtctr r4 + + sync +1: dcbi 0,r3 + addi r3,r3,CACHE_LINE_SIZE + bdnz 1b + sync /* wait for dcbi's to get to ram */ + blr + +/* + * Flush a particular page from the data cache to RAM. + * Note: this is necessary because the instruction cache does *not* + * snoop from the data cache. + * + * void __flush_page_to_ram(void *page) + */ +_GLOBAL(__flush_page_to_ram) + rlwinm r3,r3,0,0,19 /* Get page base address */ + li r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */ + mtctr r4 + mr r6,r3 +0: dcbst 0,r3 /* Write line to ram */ + addi r3,r3,CACHE_LINE_SIZE + bdnz 0b + sync + mtctr r4 +1: icbi 0,r6 + addi r6,r6,CACHE_LINE_SIZE + bdnz 1b + sync + isync + blr + +/* + * Flush a particular page from the instruction cache. + * Note: this is necessary because the instruction cache does *not* + * snoop from the data cache. + * + * void __flush_icache_page(void *page) + */ +_GLOBAL(__flush_icache_page) + li r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */ + mtctr r4 +1: icbi 0,r3 + addi r3,r3,CACHE_LINE_SIZE + bdnz 1b + sync + isync + blr + +/* + * Clear a page using the dcbz instruction, which doesn't cause any + * memory traffic (except to write out any cache lines which get + * displaced). This only works on cacheable memory. + */ +_GLOBAL(clear_page) + li r0,4096/CACHE_LINE_SIZE + mtctr r0 +1: dcbz 0,r3 + addi r3,r3,CACHE_LINE_SIZE + bdnz 1b + blr + +/* + * Enable L1 Instruction cache + */ +_GLOBAL(icache_enable) + mfspr r3, HID0 + li r5, HID0_ICFI|HID0_ILOCK + andc r3, r3, r5 + ori r3, r3, HID0_ICE + ori r5, r3, HID0_ICFI + mtspr HID0, r5 + mtspr HID0, r3 + isync + blr + +/* + * Disable L1 Instruction cache + */ +_GLOBAL(icache_disable) + mfspr r3, HID0 + li r5, 0 + ori r5, r5, HID0_ICE + andc r3, r3, r5 + mtspr HID0, r3 + isync + blr + +/* + * Is instruction cache enabled? + */ +_GLOBAL(icache_status) + mfspr r3, HID0 + andi. r3, r3, HID0_ICE + blr + + +_GLOBAL(l1dcache_enable) + mfspr r3, HID0 + li r5, HID0_DCFI|HID0_DLOCK + andc r3, r3, r5 + mtspr HID0, r3 /* no invalidate, unlock */ + ori r3, r3, HID0_DCE + ori r5, r3, HID0_DCFI + mtspr HID0, r5 /* enable + invalidate */ + mtspr HID0, r3 /* enable */ + sync + blr + +/* + * Enable data cache(s) - L1 and optionally L2 + * Calls l2cache_enable. LR saved in r5 + */ +_GLOBAL(dcache_enable) + mfspr r3, HID0 + li r5, HID0_DCFI|HID0_DLOCK + andc r3, r3, r5 + mtspr HID0, r3 /* no invalidate, unlock */ + ori r3, r3, HID0_DCE + ori r5, r3, HID0_DCFI + mtspr HID0, r5 /* enable + invalidate */ + mtspr HID0, r3 /* enable */ + sync +#ifdef CFG_L2 + mflr r5 + bl l2cache_enable /* uses r3 and r4 */ + sync + mtlr r5 +#endif + blr + + +/* + * Disable data cache(s) - L1 and optionally L2 + * Calls flush_data_cache and l2cache_disable_no_flush. + * LR saved in r4 + */ +_GLOBAL(dcache_disable) + mflr r4 /* save link register */ + bl flush_data_cache /* uses r3 and r5 */ + sync + mfspr r3, HID0 + li r5, HID0_DCFI|HID0_DLOCK + andc r3, r3, r5 + mtspr HID0, r3 /* no invalidate, unlock */ + li r5, HID0_DCE|HID0_DCFI + andc r3, r3, r5 /* no enable, no invalidate */ + mtspr HID0, r3 + sync +#ifdef CFG_L2 + bl l2cache_disable_no_flush /* uses r3 */ +#endif + mtlr r4 /* restore link register */ + blr + +/* + * Is data cache enabled? + */ +_GLOBAL(dcache_status) + mfspr r3, HID0 + andi. r3, r3, HID0_DCE + blr + +/* + * Invalidate L2 cache using L2I and polling L2IP + */ +_GLOBAL(l2cache_invalidate) + sync + oris r3, r3, L2CR_L2I@h + sync + mtspr l2cr, r3 + sync +invl2: + mfspr r3, l2cr + andi. r3, r3, L2CR_L2IP + bne invl2 + /* turn off the global invalidate bit */ + mfspr r3, l2cr + rlwinm r3, r3, 0, 11, 9 + sync + mtspr l2cr, r3 + sync + blr + +/* + * Enable L2 cache + * Calls l2cache_invalidate. LR is saved in r4 + */ +_GLOBAL(l2cache_enable) + mflr r4 /* save link register */ + bl l2cache_invalidate /* uses r3 */ + sync + lis r3, L2_ENABLE@h + ori r3, r3, L2_ENABLE@l + mtspr l2cr, r3 + isync + mtlr r4 /* restore link register */ + blr + +/* + * Disable L2 cache + * Calls flush_data_cache. LR is saved in r4 + */ +_GLOBAL(l2cache_disable) + mflr r4 /* save link register */ + bl flush_data_cache /* uses r3 and r5 */ + sync + mtlr r4 /* restore link register */ +l2cache_disable_no_flush: /* provide way to disable L2 w/o flushing */ + lis r3, L2_INIT@h + ori r3, r3, L2_INIT@l + mtspr l2cr, r3 + isync + blr diff --git a/cpu/mpc86xx/config.mk b/cpu/mpc86xx/config.mk new file mode 100644 index 0000000000..4ef7ace2f4 --- /dev/null +++ b/cpu/mpc86xx/config.mk @@ -0,0 +1,26 @@ +# +# (C) Copyright 2004 Freescale Semiconductor. +# Jeff Brown <jeffrey@freescale.com> +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi + +PLATFORM_CPPFLAGS += -DCONFIG_MPC86xx -ffixed-r2 -ffixed-r29 -mstring
\ No newline at end of file diff --git a/cpu/mpc86xx/cpu.c b/cpu/mpc86xx/cpu.c new file mode 100644 index 0000000000..36da7774ea --- /dev/null +++ b/cpu/mpc86xx/cpu.c @@ -0,0 +1,653 @@ +/* + * Copyright 2004 Freescale Semiconductor + * Jeff Brown (jeffrey@freescale.com) + * Srikanth Srinivasan (srikanth.srinivasan@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <watchdog.h> +#include <command.h> +#include <asm/cache.h> +#include <mpc86xx.h> + +#if defined(CONFIG_OF_FLAT_TREE) +#include <ft_build.h> +#endif + +extern unsigned long get_board_sys_clk(ulong dummy); + + +static __inline__ unsigned long get_dbat3u (void) +{ + unsigned long dbat3u; + asm volatile("mfspr %0, 542" : "=r" (dbat3u) :); + return dbat3u; +} + +static __inline__ unsigned long get_dbat3l (void) +{ + unsigned long dbat3l; + asm volatile("mfspr %0, 543" : "=r" (dbat3l) :); + return dbat3l; +} + +static __inline__ unsigned long get_msr (void) +{ + unsigned long msr; + asm volatile("mfmsr %0" : "=r" (msr) :); + return msr; +} + + +int checkcpu (void) +{ + sys_info_t sysinfo; + uint pvr, svr; + uint ver; + uint major, minor; + uint lcrr; /* local bus clock ratio register */ + uint clkdiv; /* clock divider portion of lcrr */ + + puts("Freescale PowerPC\n"); + + pvr = get_pvr(); + ver = PVR_VER(pvr); + major = PVR_MAJ(pvr); + minor = PVR_MIN(pvr); + + puts("CPU:\n"); + + printf(" Core: "); + + switch (ver) { + case PVR_VER(PVR_86xx): + puts("E600"); + break; + default: + puts("Unknown"); + break; + } + printf(", Version: %d.%d, (0x%08x)\n", major, minor, pvr); + + svr = get_svr(); + ver = SVR_VER(svr); + major = SVR_MAJ(svr); + minor = SVR_MIN(svr); + + puts(" System: "); + switch (ver) { + case SVR_8641: + puts("8641"); + break; + case SVR_8641D: + puts("8641D"); + break; + default: + puts("Unknown"); + break; + } + printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr); + + get_sys_info(&sysinfo); + + puts(" Clocks: "); + printf("CPU:%4lu MHz, ", sysinfo.freqProcessor / 1000000); + printf("MPX:%4lu MHz, ", sysinfo.freqSystemBus / 1000000); + printf("DDR:%4lu MHz, ", sysinfo.freqSystemBus / 2000000); + +#if defined(CFG_LBC_LCRR) + lcrr = CFG_LBC_LCRR; +#else + { + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_lbc_t *lbc= &immap->im_lbc; + + lcrr = lbc->lcrr; + } +#endif + clkdiv = lcrr & 0x0f; + if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) { + printf("LBC:%4lu MHz\n", + sysinfo.freqSystemBus / 1000000 / clkdiv); + } else { + printf(" LBC: unknown (lcrr: 0x%08x)\n", lcrr); + } + + printf(" L2: "); + if (get_l2cr() & 0x80000000) + printf("Enabled\n"); + else + printf("Disabled\n"); + + return 0; +} + + +/* -------------------------------------------------------------------- */ + +static inline void +soft_restart(unsigned long addr) +{ + +#ifndef CONFIG_MPC8641HPCN + + /* SRR0 has system reset vector, SRR1 has default MSR value */ + /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */ + + __asm__ __volatile__ ("mtspr 26, %0" :: "r" (addr)); + __asm__ __volatile__ ("li 4, (1 << 6)" ::: "r4"); + __asm__ __volatile__ ("mtspr 27, 4"); + __asm__ __volatile__ ("rfi"); + +#else /* CONFIG_MPC8641HPCN */ + out8(PIXIS_BASE+PIXIS_RST,0); +#endif /* !CONFIG_MPC8641HPCN */ + while(1); /* not reached */ +} + + + +#ifdef CONFIG_MPC8641HPCN + +int set_px_sysclk(ulong sysclk) +{ + u8 sysclk_s, sysclk_r, sysclk_v, vclkh, vclkl, sysclk_aux,tmp; + + /* Per table 27, page 58 of MPC8641HPCN spec*/ + switch(sysclk) + { + case 33: + sysclk_s = 0x04; + sysclk_r = 0x04; + sysclk_v = 0x07; + sysclk_aux = 0x00; + break; + case 40: + sysclk_s = 0x01; + sysclk_r = 0x1F; + sysclk_v = 0x20; + sysclk_aux = 0x01; + break; + case 50: + sysclk_s = 0x01; + sysclk_r = 0x1F; + sysclk_v = 0x2A; + sysclk_aux = 0x02; + break; + case 66: + sysclk_s = 0x01; + sysclk_r = 0x04; + sysclk_v = 0x04; + sysclk_aux = 0x03; + break; + case 83: + sysclk_s = 0x01; + sysclk_r = 0x1F; + sysclk_v = 0x4B; + sysclk_aux = 0x04; + break; + case 100: + sysclk_s = 0x01; + sysclk_r = 0x1F; + sysclk_v = 0x5C; + sysclk_aux = 0x05; + break; + case 134: + sysclk_s = 0x06; + sysclk_r = 0x1F; + sysclk_v = 0x3B; + sysclk_aux = 0x06; + break; + case 166: + sysclk_s = 0x06; + sysclk_r = 0x1F; + sysclk_v = 0x4B; + sysclk_aux = 0x07; + break; + default: + printf("Unsupported SYSCLK frequency.\n"); + return 0; + } + + vclkh = (sysclk_s << 5) | sysclk_r ; + vclkl = sysclk_v; + out8(PIXIS_BASE+PIXIS_VCLKH,vclkh); + out8(PIXIS_BASE+PIXIS_VCLKL,vclkl); + + out8(PIXIS_BASE+PIXIS_AUX,sysclk_aux); + + return 1; +} + +int set_px_mpxpll(ulong mpxpll) +{ + u8 tmp; + u8 val; + switch(mpxpll) + { + case 2: + case 4: + case 6: + case 8: + case 10: + case 12: + case 14: + case 16: + val = (u8)mpxpll; + break; + default: + printf("Unsupported MPXPLL ratio.\n"); + return 0; + } + + tmp = in8(PIXIS_BASE+PIXIS_VSPEED1); + tmp = (tmp & 0xF0) | (val & 0x0F); + out8(PIXIS_BASE+PIXIS_VSPEED1,tmp); + + return 1; +} + +int set_px_corepll(ulong corepll) +{ + u8 tmp; + u8 val; + + switch ((int)corepll) { + case 20: + val = 0x08; + break; + case 25: + val = 0x0C; + break; + case 30: + val = 0x10; + break; + case 35: + val = 0x1C; + break; + case 40: + val = 0x14; + break; + case 45: + val = 0x0E; + break; + default: + printf("Unsupported COREPLL ratio.\n"); + return 0; + } + + tmp = in8(PIXIS_BASE+PIXIS_VSPEED0); + tmp = (tmp & 0xE0) | (val & 0x1F); + out8(PIXIS_BASE+PIXIS_VSPEED0,tmp); + + return 1; +} + +void read_from_px_regs(int set) +{ + u8 tmp, mask = 0x1C; + tmp = in8(PIXIS_BASE+PIXIS_VCFGEN0); + if (set) + tmp = tmp | mask; + else + tmp = tmp & ~mask; + out8(PIXIS_BASE+PIXIS_VCFGEN0,tmp); +} + +void read_from_px_regs_altbank(int set) +{ + u8 tmp, mask = 0x04; + tmp = in8(PIXIS_BASE+PIXIS_VCFGEN1); + if (set) + tmp = tmp | mask; + else + tmp = tmp & ~mask; + out8(PIXIS_BASE+PIXIS_VCFGEN1,tmp); +} + +void set_altbank(void) +{ + u8 tmp; + tmp = in8(PIXIS_BASE+PIXIS_VBOOT); + tmp ^= 0x40; + out8(PIXIS_BASE+PIXIS_VBOOT,tmp); + } + + +void set_px_go(void) +{ + u8 tmp; + tmp = in8(PIXIS_BASE+PIXIS_VCTL); + tmp = tmp & 0x1E; + out8(PIXIS_BASE+PIXIS_VCTL,tmp); + tmp = in8(PIXIS_BASE+PIXIS_VCTL); + tmp = tmp | 0x01; + out8(PIXIS_BASE+PIXIS_VCTL,tmp); +} + +void set_px_go_with_watchdog(void) +{ + u8 tmp; + tmp = in8(PIXIS_BASE+PIXIS_VCTL); + tmp = tmp & 0x1E; + out8(PIXIS_BASE+PIXIS_VCTL,tmp); + tmp = in8(PIXIS_BASE+PIXIS_VCTL); + tmp = tmp | 0x09; + out8(PIXIS_BASE+PIXIS_VCTL,tmp); +} + +/* This function takes the non-integral cpu:mpx pll ratio + * and converts it to an integer that can be used to assign + * FPGA register values. + * input: strptr i.e. argv[2] +*/ + +ulong strfractoint(uchar *strptr) +{ + int i,j,retval,intarr_len=0, decarr_len=0, mulconst, no_dec=0; + ulong intval =0, decval=0; + uchar intarr[3], decarr[3]; + + /* Assign the integer part to intarr[] + * If there is no decimal point i.e. + * if the ratio is an integral value + * simply create the intarr. + */ + i=0; + while(strptr[i] != 46) + { + if(strptr[i] == 0) + { + no_dec = 1; + break; /* Break from loop once the end of string is reached */ + } + + intarr[i] = strptr[i]; + i++; + } + + intarr_len = i; /* Assign length of integer part to intarr_len*/ + intarr[i] = '\0'; /* */ + + if(no_dec) + { + mulconst=10; /* Currently needed only for single digit corepll ratios */ + decval = 0; + } + else + { + j=0; + i++; /* Skipping the decimal point */ + while ((strptr[i] > 47) && (strptr[i] < 58)) + { + decarr[j] = strptr[i]; + i++; + j++; + } + + decarr_len = j; + decarr[j] = '\0'; + + mulconst=1; + for(i=0; i<decarr_len;i++) + mulconst = mulconst*10; + decval = simple_strtoul(decarr,NULL,10); + } + + intval = simple_strtoul(intarr,NULL,10); + intval = intval*mulconst; + + retval = intval+decval; + + return retval; + +} + + +#endif /* CONFIG_MPC8641HPCN */ + + +/* no generic way to do board reset. simply call soft_reset. */ +void +do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + char cmd; + ulong addr, val; + ulong corepll; + +#ifdef CFG_RESET_ADDRESS + addr = CFG_RESET_ADDRESS; +#else + /* + * note: when CFG_MONITOR_BASE points to a RAM address, + * CFG_MONITOR_BASE - sizeof (ulong) is usually a valid + * address. Better pick an address known to be invalid on your + * system and assign it to CFG_RESET_ADDRESS. + */ + addr = CFG_MONITOR_BASE - sizeof (ulong); +#endif + +#ifndef CONFIG_MPC8641HPCN + + /* flush and disable I/D cache */ + __asm__ __volatile__ ("mfspr 3, 1008" ::: "r3"); + __asm__ __volatile__ ("ori 5, 5, 0xcc00" ::: "r5"); + __asm__ __volatile__ ("ori 4, 3, 0xc00" ::: "r4"); + __asm__ __volatile__ ("andc 5, 3, 5" ::: "r5"); + __asm__ __volatile__ ("sync"); + __asm__ __volatile__ ("mtspr 1008, 4"); + __asm__ __volatile__ ("isync"); + __asm__ __volatile__ ("sync"); + __asm__ __volatile__ ("mtspr 1008, 5"); + __asm__ __volatile__ ("isync"); + __asm__ __volatile__ ("sync"); + + soft_restart(addr); + +#else /* CONFIG_MPC8641HPCN */ + + if (argc > 1) { + cmd = argv[1][1]; + switch(cmd) { + case 'f': /* reset with frequency changed */ + if (argc < 5) + goto my_usage; + read_from_px_regs(0); + + val = set_px_sysclk(simple_strtoul(argv[2],NULL,10)); + + corepll = strfractoint(argv[3]); + val = val + set_px_corepll(corepll); + val = val + set_px_mpxpll(simple_strtoul(argv[4], + NULL, 10)); + if (val == 3) { + printf("Setting registers VCFGEN0 and VCTL\n"); + read_from_px_regs(1); + printf("Resetting board with values from VSPEED0, VSPEED1, VCLKH, and VCLKL ....\n"); + set_px_go(); + } else + goto my_usage; + + while (1); /* Not reached */ + + case 'l': + if (argv[2][1] == 'f') { + read_from_px_regs(0); + read_from_px_regs_altbank(0); + /* reset with frequency changed */ + val = set_px_sysclk(simple_strtoul(argv[3],NULL,10)); + + corepll = strfractoint(argv[4]); + val = val + set_px_corepll(corepll); + val = val + set_px_mpxpll(simple_strtoul(argv[5],NULL,10)); + if (val == 3) { + printf("Setting registers VCFGEN0, VCFGEN1, VBOOT, and VCTL\n"); + set_altbank(); + read_from_px_regs(1); + read_from_px_regs_altbank(1); + printf("Enabling watchdog timer on the FPGA and resetting board with values from VSPEED0, VSPEED1, VCLKH, and VCLKL to boot from the other bank ....\n"); + set_px_go_with_watchdog(); + } else + goto my_usage; + + while(1); /* Not reached */ + } else { + /* Reset from next bank without changing frequencies */ + read_from_px_regs(0); + read_from_px_regs_altbank(0); + if(argc > 2) + goto my_usage; + printf("Setting registers VCFGEN1, VBOOT, and VCTL\n"); + set_altbank(); + read_from_px_regs_altbank(1); + printf("Enabling watchdog timer on the FPGA and resetting board to boot from the other bank....\n"); + set_px_go_with_watchdog(); + while(1); /* Not reached */ + } + + default: + goto my_usage; + } + +my_usage: + printf("\nUsage: reset cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>\n"); + printf(" reset altbank [cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>]\n"); + printf("For example: reset cf 40 2.5 10\n"); + printf("See MPC8641HPCN Design Workbook for valid values of command line parameters.\n"); + return; + } else + out8(PIXIS_BASE+PIXIS_RST,0); + +#endif /* !CONFIG_MPC8641HPCN */ + + while(1); /* not reached */ +} + + +/* + * Get timebase clock frequency + */ +unsigned long get_tbclk(void) +{ + sys_info_t sys_info; + + get_sys_info(&sys_info); + return (sys_info.freqSystemBus + 3L) / 4L; +} + + +#if defined(CONFIG_WATCHDOG) +void +watchdog_reset(void) +{ +} +#endif /* CONFIG_WATCHDOG */ + + +#if defined(CONFIG_DDR_ECC) +void dma_init(void) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_dma_t *dma = &immap->im_dma; + + dma->satr0 = 0x00040000; + dma->datr0 = 0x00040000; + asm("sync; isync"); + return; +} + +uint dma_check(void) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_dma_t *dma = &immap->im_dma; + volatile uint status = dma->sr0; + + /* While the channel is busy, spin */ + while((status & 4) == 4) { + status = dma->sr0; + } + + if (status != 0) { + printf ("DMA Error: status = %x\n", status); + } + return status; +} + +int dma_xfer(void *dest, uint count, void *src) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_dma_t *dma = &immap->im_dma; + + dma->dar0 = (uint) dest; + dma->sar0 = (uint) src; + dma->bcr0 = count; + dma->mr0 = 0xf000004; + asm("sync;isync"); + dma->mr0 = 0xf000005; + asm("sync;isync"); + return dma_check(); +} + +#endif /* CONFIG_DDR_ECC */ + + +#ifdef CONFIG_OF_FLAT_TREE +void ft_cpu_setup(void *blob, bd_t *bd) +{ + u32 *p; + ulong clock; + int len; + + clock = bd->bi_busfreq; + p = ft_get_prop(blob, "/cpus/" OF_CPU "/bus-frequency", &len); + if (p != NULL) + *p = cpu_to_be32(clock); + + p = ft_get_prop(blob, "/" OF_SOC "/serial@4500/clock-frequency", &len); + if (p != NULL) + *p = cpu_to_be32(clock); + + p = ft_get_prop(blob, "/" OF_SOC "/serial@4600/clock-frequency", &len); + if (p != NULL) + *p = cpu_to_be32(clock); + +#if defined(CONFIG_MPC86XX_TSEC1) + p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/address", &len); + memcpy(p, bd->bi_enetaddr, 6); +#endif + +#if defined(CONFIG_MPC86XX_TSEC2) + p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/address", &len); + memcpy(p, bd->bi_enet1addr, 6); +#endif + +#if defined(CONFIG_MPC86XX_TSEC3) + p = ft_get_prop(blob, "/" OF_SOC "/ethernet@26000/address", &len); + memcpy(p, bd->bi_enet2addr, 6); +#endif + +#if defined(CONFIG_MPC86XX_TSEC4) + p = ft_get_prop(blob, "/" OF_SOC "/ethernet@27000/address", &len); + memcpy(p, bd->bi_enet3addr, 6); +#endif + +} +#endif diff --git a/cpu/mpc86xx/cpu_init.c b/cpu/mpc86xx/cpu_init.c new file mode 100644 index 0000000000..c816c18974 --- /dev/null +++ b/cpu/mpc86xx/cpu_init.c @@ -0,0 +1,131 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * Jeff Brown (jeffrey@freescale.com) + * Srikanth Srinivasan (srikanth.srinivasan@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * cpu_init.c - low level cpu init + */ + +#include <common.h> +#include <mpc86xx.h> + +/* + * Breathe some life into the CPU... + * + * Set up the memory map + * initialize a bunch of registers + */ + +void cpu_init_f(void) +{ + DECLARE_GLOBAL_DATA_PTR; + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_lbc_t *memctl = &immap->im_lbc; + + /* Pointer is writable since we allocated a register for it */ + gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET); + + /* Clear initial global data */ + memset ((void *) gd, 0, sizeof (gd_t)); + + /* 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(CFG_OR0_REMAP) + memctl->or0 = CFG_OR0_REMAP; +#endif +#if defined(CFG_OR1_REMAP) + memctl->or1 = CFG_OR1_REMAP; +#endif + + /* now restrict to preliminary range */ +#if defined(CFG_BR0_PRELIM) && defined(CFG_OR0_PRELIM) + memctl->br0 = CFG_BR0_PRELIM; + memctl->or0 = CFG_OR0_PRELIM; +#endif + +#if defined(CFG_BR1_PRELIM) && defined(CFG_OR1_PRELIM) + memctl->or1 = CFG_OR1_PRELIM; + memctl->br1 = CFG_BR1_PRELIM; +#endif + +#if defined(CFG_BR2_PRELIM) && defined(CFG_OR2_PRELIM) + memctl->or2 = CFG_OR2_PRELIM; + memctl->br2 = CFG_BR2_PRELIM; +#endif + +#if defined(CFG_BR3_PRELIM) && defined(CFG_OR3_PRELIM) + memctl->or3 = CFG_OR3_PRELIM; + memctl->br3 = CFG_BR3_PRELIM; +#endif + +#if defined(CFG_BR4_PRELIM) && defined(CFG_OR4_PRELIM) + memctl->or4 = CFG_OR4_PRELIM; + memctl->br4 = CFG_BR4_PRELIM; +#endif + +#if defined(CFG_BR5_PRELIM) && defined(CFG_OR5_PRELIM) + memctl->or5 = CFG_OR5_PRELIM; + memctl->br5 = CFG_BR5_PRELIM; +#endif + +#if defined(CFG_BR6_PRELIM) && defined(CFG_OR6_PRELIM) + memctl->or6 = CFG_OR6_PRELIM; + memctl->br6 = CFG_BR6_PRELIM; +#endif + +#if defined(CFG_BR7_PRELIM) && defined(CFG_OR7_PRELIM) + memctl->or7 = CFG_OR7_PRELIM; + memctl->br7 = CFG_BR7_PRELIM; +#endif + + /* enable the timebase bit in HID0 */ + set_hid0(get_hid0() | 0x4000000); + + /* enable SYNCBE | ABE bits in HID1 */ + set_hid1(get_hid1() | 0x00000C00); + + /* Since the bats have been set up at this point and + * the local bus registers have been initialized, we + * turn on the WDEN bit in PIXIS_VCTL + */ +/* val = in8(PIXIS_BASE+PIXIS_VCTL); */ + /* Set the WDEN */ +/* val |= 0x08; */ +/* out8(PIXIS_BASE+PIXIS_VCTL,val); */ +} + +/* + * initialize higher level parts of CPU like timers + */ +int cpu_init_r(void) +{ + return 0; +} + + + + + diff --git a/cpu/mpc86xx/i2c.c b/cpu/mpc86xx/i2c.c new file mode 100644 index 0000000000..f2b4b0f6da --- /dev/null +++ b/cpu/mpc86xx/i2c.c @@ -0,0 +1,267 @@ +/* + * (C) Copyright 2003,Motorola Inc. + * Xianghua Xiao <x.xiao@motorola.com> + * Adapted for Motorola 85xx chip. + * + * (C) Copyright 2003 + * Gleb Natapov <gnatapov@mrv.com> + * Some bits are taken from linux driver writen by adrian@humboldt.co.uk + * + * Modified for MPC86xx by Jeff Brown (jeffrey@freescale.com) + * + * Hardware I2C driver for MPC107 PCI bridge. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <asm/io.h> + +#ifdef CONFIG_HARD_I2C +#include <i2c.h> + +#define TIMEOUT (CFG_HZ/4) + +#define I2C_Addr ((u8 *)(CFG_CCSRBAR + 0x3100)) + +#define I2CADR &I2C_Addr[0] +#define I2CFDR &I2C_Addr[4] +#define I2CCCR &I2C_Addr[8] +#define I2CCSR &I2C_Addr[12] +#define I2CCDR &I2C_Addr[16] +#define I2CDFSRR &I2C_Addr[20] + +#define I2C_READ 1 +#define I2C_WRITE 0 + +void +i2c_init(int speed, int slaveadd) +{ + /* stop I2C controller */ + writeb(0x0, I2CCCR); + + /* set clock */ + writeb(0x3f, I2CFDR); + + /* set default filter */ + writeb(0x10,I2CDFSRR); + + /* write slave address */ + writeb(slaveadd, I2CADR); + + /* clear status register */ + writeb(0x0, I2CCSR); + + /* start I2C controller */ + writeb(MPC86xx_I2CCR_MEN, I2CCCR); +} + +static __inline__ int +i2c_wait4bus(void) +{ + ulong timeval = get_timer (0); + + while (readb(I2CCSR) & MPC86xx_I2CSR_MBB) { + if (get_timer(timeval) > TIMEOUT) { + return -1; + } + } + + return 0; +} + +static __inline__ int +i2c_wait(int write) +{ + u32 csr; + ulong timeval = get_timer (0); + + do { + csr = readb(I2CCSR); + if (!(csr & MPC86xx_I2CSR_MIF)) + continue; + + writeb(0x0, I2CCSR); + + if (csr & MPC86xx_I2CSR_MAL) { + debug("i2c_wait: MAL\n"); + return -1; + } + + if (!(csr & MPC86xx_I2CSR_MCF)) { + debug("i2c_wait: unfinished\n"); + return -1; + } + + if (write == I2C_WRITE && (csr & MPC86xx_I2CSR_RXAK)) { + debug("i2c_wait: No RXACK\n"); + return -1; + } + + return 0; + } while (get_timer(timeval) < TIMEOUT); + + debug("i2c_wait: timed out\n"); + return -1; +} + +static __inline__ int +i2c_write_addr (u8 dev, u8 dir, int rsta) +{ + writeb(MPC86xx_I2CCR_MEN | MPC86xx_I2CCR_MSTA | MPC86xx_I2CCR_MTX + | (rsta ? MPC86xx_I2CCR_RSTA : 0), + I2CCCR); + + writeb((dev << 1) | dir, I2CCDR); + + if (i2c_wait(I2C_WRITE) < 0) + return 0; + + return 1; +} + +static __inline__ int +__i2c_write (u8 *data, int length) +{ + int i; + + writeb(MPC86xx_I2CCR_MEN | MPC86xx_I2CCR_MSTA | MPC86xx_I2CCR_MTX, + I2CCCR); + + for (i = 0; i < length; i++) { + writeb(data[i], I2CCDR); + + if (i2c_wait(I2C_WRITE) < 0) + break; + } + + return i; +} + +static __inline__ int +__i2c_read (u8 *data, int length) +{ + int i; + + writeb(MPC86xx_I2CCR_MEN | MPC86xx_I2CCR_MSTA + | ((length == 1) ? MPC86xx_I2CCR_TXAK : 0), + I2CCCR); + + /* dummy read */ + readb(I2CCDR); + + for (i = 0; i < length; i++) { + if (i2c_wait(I2C_READ) < 0) + break; + + /* Generate ack on last next to last byte */ + if (i == length - 2) + writeb(MPC86xx_I2CCR_MEN | MPC86xx_I2CCR_MSTA + | MPC86xx_I2CCR_TXAK, + I2CCCR); + + /* Generate stop on last byte */ + if (i == length - 1) + writeb(MPC86xx_I2CCR_MEN | MPC86xx_I2CCR_TXAK, I2CCCR); + + data[i] = readb(I2CCDR); + } + + return i; +} + +int +i2c_read (u8 dev, uint addr, int alen, u8 *data, int length) +{ + int i = 0; + u8 *a = (u8*)&addr; + + if (i2c_wait4bus() < 0) + goto exit; + + if (i2c_write_addr(dev, I2C_WRITE, 0) == 0) + goto exit; + + if (__i2c_write(&a[4 - alen], alen) != alen) + goto exit; + + if (i2c_write_addr(dev, I2C_READ, 1) == 0) + goto exit; + + i = __i2c_read(data, length); + + exit: + writeb(MPC86xx_I2CCR_MEN, I2CCCR); + + return !(i == length); +} + +int +i2c_write (u8 dev, uint addr, int alen, u8 *data, int length) +{ + int i = 0; + u8 *a = (u8*)&addr; + + if (i2c_wait4bus() < 0) + goto exit; + + if (i2c_write_addr(dev, I2C_WRITE, 0) == 0) + goto exit; + + if (__i2c_write(&a[4 - alen], alen) != alen) + goto exit; + + i = __i2c_write(data, length); + + exit: + writeb(MPC86xx_I2CCR_MEN, I2CCCR); + + return !(i == length); +} + +int i2c_probe (uchar chip) +{ + int tmp; + + /* + * Try to read the first location of the chip. The underlying + * driver doesn't appear to support sending just the chip address + * and looking for an <ACK> back. + */ + udelay(10000); + + return i2c_read(chip, 0, 1, (char *)&tmp, 1); +} + +uchar i2c_reg_read (uchar i2c_addr, uchar reg) +{ + char buf[1]; + + i2c_read(i2c_addr, reg, 1, buf, 1); + + return buf[0]; +} + +void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val) +{ + i2c_write(i2c_addr, reg, 1, &val, 1); +} + +#endif /* CONFIG_HARD_I2C */ diff --git a/cpu/mpc86xx/interrupts.c b/cpu/mpc86xx/interrupts.c new file mode 100644 index 0000000000..b5cd439e53 --- /dev/null +++ b/cpu/mpc86xx/interrupts.c @@ -0,0 +1,222 @@ +/* + * (C) Copyright 2000-2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 (440 port) + * Scott McNutt, Artesyn Communication Producs, smcnutt@artsyncp.com + * + * (C) Copyright 2003 Motorola Inc. (MPC85xx port) + * Xianghua Xiao (X.Xiao@motorola.com) + * + * (C) Copyright 2004 Freescale Semiconductor. (MPC86xx Port) + * Jeff Brown (Jeffrey@freescale.com) + * Srikanth Srinivasan (srikanth.srinivasan@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <mpc86xx.h> +#include <command.h> +#include <asm/processor.h> +#include <ppc_asm.tmpl> + +unsigned long decrementer_count; /* count value for 1e6/HZ microseconds */ + + +unsigned long timestamp; + +static __inline__ unsigned long get_msr (void) +{ + unsigned long msr; + + asm volatile ("mfmsr %0":"=r" (msr):); + + return msr; +} + +static __inline__ void set_msr (unsigned long msr) +{ + asm volatile ("mtmsr %0"::"r" (msr)); +} + +static __inline__ unsigned long get_dec (void) +{ + unsigned long val; + + asm volatile ("mfdec %0":"=r" (val):); + + return val; +} + + +static __inline__ void set_dec (unsigned long val) +{ + if (val) + asm volatile ("mtdec %0"::"r" (val)); +} + +/* interrupt is not supported yet */ +int interrupt_init_cpu (unsigned *decrementer_count) +{ + return 0; +} + + +int interrupt_init (void) +{ + int ret; + + /* call cpu specific function from $(CPU)/interrupts.c */ + ret = interrupt_init_cpu (&decrementer_count); + + if (ret) + return ret; + + decrementer_count = get_tbclk()/CFG_HZ; + debug("interrupt init: tbclk() = %d MHz, decrementer_count = %d\n", (get_tbclk()/1000000), decrementer_count); + + set_dec (decrementer_count); + + set_msr (get_msr () | MSR_EE); + + debug("MSR = 0x%08lx, Decrementer reg = 0x%08lx\n", get_msr(), get_dec()); + + return 0; +} + + +void enable_interrupts (void) +{ + set_msr (get_msr () | MSR_EE); +} + +/* returns flag if MSR_EE was set before */ +int disable_interrupts (void) +{ + ulong msr = get_msr (); + + set_msr (msr & ~MSR_EE); + return (msr & MSR_EE) != 0; +} + + +void increment_timestamp(void) +{ + timestamp++; +} + +/* + * timer_interrupt - gets called when the decrementer overflows, + * with interrupts disabled. + * Trivial implementation - no need to be really accurate. + */ +void +timer_interrupt_cpu (struct pt_regs *regs) +{ + /* nothing to do here */ +} + + +void timer_interrupt (struct pt_regs *regs) +{ + /* call cpu specific function from $(CPU)/interrupts.c */ + timer_interrupt_cpu (regs); + + timestamp++; + + ppcDcbf(×tamp); + + /* Restore Decrementer Count */ + set_dec (decrementer_count); + +#if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG) + if ((timestamp % (CFG_WATCHDOG_FREQ)) == 0) + WATCHDOG_RESET (); +#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */ + +#ifdef CONFIG_STATUS_LED + status_led_tick (timestamp); +#endif /* CONFIG_STATUS_LED */ + +#ifdef CONFIG_SHOW_ACTIVITY + board_show_activity (timestamp); +#endif /* CONFIG_SHOW_ACTIVITY */ + + +} + +void reset_timer (void) +{ + timestamp = 0; +} + +ulong get_timer (ulong base) +{ + return timestamp - base; +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +/* + * Install and free a interrupt handler. Not implemented yet. + */ + +void +irq_install_handler(int vec, interrupt_handler_t *handler, void *arg) +{ +} + +void +irq_free_handler(int vec) +{ +} + + + +/******************************************************************************* + * + * irqinfo - print information about PCI devices,not implemented. + * + */ +int +do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + printf ("\nInterrupt-unsupported:\n"); + + return 0; +} + +/* + * Handle external interrupts + */ +void +external_interrupt(struct pt_regs *regs) +{ + puts("external_interrupt (oops!)\n"); +} + + + + + + diff --git a/cpu/mpc86xx/pci.c b/cpu/mpc86xx/pci.c new file mode 100644 index 0000000000..05976bdd4b --- /dev/null +++ b/cpu/mpc86xx/pci.c @@ -0,0 +1,163 @@ +/* + * Copyright 2005 Freescale Semiconductor. + * Ed Swarthout (ed.swarthout@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * PEX Configuration space access support for PEX Bridge + */ +#include <common.h> +#include <pci.h> + + +#if defined(CONFIG_PCI) + +void +pci_mpc86xx_init(struct pci_controller *hose) +{ + volatile immap_t *immap = (immap_t *)CFG_CCSRBAR; + volatile ccsr_pex_t *pex1 = &immap->im_pex1; + volatile ccsr_gur_t *gur = &immap->im_gur; + uint host1_agent = (gur->porbmsr & MPC86xx_PORBMSR_HA) >> 17; + uint pex1_host = (host1_agent == 2) || (host1_agent == 3); + + u16 reg16, reg16_1, reg16_2, reg16_3; + u32 reg32, i; + + ulong addr, data; + + uint pex1_agent = (host1_agent == 0) || (host1_agent == 1); + uint devdisr = gur->devdisr; + uint io_sel = (gur->pordevsr & MPC86xx_PORDEVSR_IO_SEL) >> 16; + + if ((io_sel==2 || io_sel==3 || io_sel==5 + || io_sel==6 || io_sel==7 || io_sel==0xF ) + && !(devdisr & MPC86xx_DEVDISR_PCIEX1)){ + printf ("PCI-EXPRESS 1: Configured as %s \n", + pex1_agent ? "Agent" : "Host"); + printf (" Scanning PCI bus"); + debug("0x%08x=0x%08x ", &pex1->pme_msg_det,pex1->pme_msg_det); + if (pex1->pme_msg_det) { + pex1->pme_msg_det = 0xffffffff; + debug (" with errors. Clearing. Now 0x%08x", + pex1->pme_msg_det); + } + debug ("\n"); + } + + hose->first_busno = 0; + hose->last_busno = 0x7f; + + pci_set_region(hose->regions + 0, + CFG_PCI1_MEM_BASE, + CFG_PCI1_MEM_PHYS, + CFG_PCI1_MEM_SIZE, + PCI_REGION_MEM); + + pci_set_region(hose->regions + 1, + CFG_PCI1_IO_BASE, + CFG_PCI1_IO_PHYS, + CFG_PCI1_IO_SIZE, + PCI_REGION_IO); + + hose->region_count = 2; + + pci_setup_indirect(hose, + (CFG_IMMR+0x8000), + (CFG_IMMR+0x8004)); + + /* + * Hose scan. + */ + pci_register_hose(hose); + + pci_read_config_word (PCI_BDF(0,0,0), PCI_VENDOR_ID, ®16); + debug("pex_mpc86xx_init: read %2x %4x\n",PCI_VENDOR_ID, reg16); + pci_read_config_word (PCI_BDF(0,0,0), PCI_DEVICE_ID, ®16); + debug("pex_mpc86xx_init: read %2x %4x\n",PCI_DEVICE_ID, reg16); + + pci_read_config_word (PCI_BDF(0,0,0), PCI_COMMAND, ®16); + reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY \ + | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + pci_write_config_word(PCI_BDF(0,0,0), PCI_COMMAND, reg16); + + pci_read_config_word (PCI_BDF(0,0,0), PCI_COMMAND, ®16); + debug("pex_mpc86xx_init: read %2x %4x\n",PCI_COMMAND, reg16); + + /* + * Clear non-reserved bits in status register. + */ + /* + * pci_write_config_word(PCI_BDF(0,0,0), PCI_STATUS, 0xffff); + * pci_write_config_byte(PCI_BDF(0,0,0), PCI_LATENCY_TIMER,0x80); + */ + + pex1->powbar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff; + pex1->powar1 = 0x8004401c; /* 512M MEM space */ + pex1->potar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff; + pex1->potear1 = 0x00000000; + + pex1->powbar2 = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff; + pex1->powar2 = 0x80088017; /* 16M IO space */ + pex1->potar2 = 0x00000000; + pex1->potear2 = 0x00000000; + + if (!pex1->piwar1) { + pex1->pitar1 = 0x00000000; + pex1->piwbar1 = (0x80000000 >> 12 ) & 0x000fffff; + pex1->piwar1 = 0xa0f5501e; /* Enable, Prefetch, Local Mem, + * Snoop R/W, 2G */ + } + + pex1->pitar2 = 0x00000000; + pex1->piwbar2 = (0xe2000000 >> 12 ) & 0x000fffff; + pex1->piwar2 = 0xa0f5501e; /* Enable, Prefetch, Local Mem, + * Snoop R/W, 2G */ + + *(u32 *)(0xf8008000)= 0x80000000; + debug("Received data for addr 0x%08lx is 0x%08lx\n", + *(u32*)(0xf8008000), *(u32*)(0xf8008004)); + + pci_write_config_byte(PCI_BDF(0,0,0), PCI_PRIMARY_BUS,0x20); + pci_write_config_byte(PCI_BDF(0,0,0), PCI_SECONDARY_BUS,0x00); + pci_write_config_byte(PCI_BDF(0,0,0), PCI_SUBORDINATE_BUS,0x1F); + + *(u32 *)(0xf8008000)= 0x80200000; + debug("Received data for addr 0x%08lx is 0x%08lx\n", + *(u32*)(0xf8008000), *(u32*)(0xf8008004)); + + *(u32 *)(0xf8008000)= 0x80200000; + debug("Received data for addr 0x%08lx is 0x%08lx\n", + *(u32*)(0xf8008000), *(u32*)(0xf8008004)); + + *(u32 *)(0xf8008000)= 0x80200000; + debug("Received data for addr 0x%08lx is 0x%08lx\n", + *(u32*)(0xf8008000), *(u32*)(0xf8008004)); + + hose->last_busno = pci_hose_scan(hose); + hose->last_busno = 0x21; + debug("pex_mpc86xx_init: last_busno %x\n",hose->last_busno); + debug("pex_mpc86xx init: current_busno %x\n ",hose->current_busno); + + printf("....PCI scan & enumeration done\n"); +} + +#endif /* CONFIG_PCI */ diff --git a/cpu/mpc86xx/resetvec.S b/cpu/mpc86xx/resetvec.S new file mode 100644 index 0000000000..9a552f6624 --- /dev/null +++ b/cpu/mpc86xx/resetvec.S @@ -0,0 +1,2 @@ + .section .resetvec,"ax" + b _start diff --git a/cpu/mpc86xx/spd_sdram.c b/cpu/mpc86xx/spd_sdram.c new file mode 100644 index 0000000000..9ce31d7c6f --- /dev/null +++ b/cpu/mpc86xx/spd_sdram.c @@ -0,0 +1,1016 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * (C) Copyright 2003 Motorola Inc. + * Xianghua Xiao (X.Xiao@motorola.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/processor.h> +#include <i2c.h> +#include <spd.h> +#include <asm/mmu.h> + + +#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) +extern void dma_init(void); +extern uint dma_check(void); +extern int dma_xfer(void *dest, uint count, void *src); +#endif + +#ifdef CONFIG_SPD_EEPROM + +#ifndef CFG_READ_SPD +#define CFG_READ_SPD i2c_read +#endif + +/* + * Convert picoseconds into clock cycles (rounding up if needed). + */ + +int +picos_to_clk(int picos) +{ + int clks; + + clks = picos / (2000000000 / (get_bus_freq(0) / 1000)); + if (picos % (2000000000 / (get_bus_freq(0) / 1000)) != 0) { + clks++; + } + + return clks; +} + + +/* + * Calculate the Density of each Physical Rank. + * Returned size is in bytes. + * + * Study these table from Byte 31 of JEDEC SPD Spec. + * + * DDR I DDR II + * Bit Size Size + * --- ----- ------ + * 7 high 512MB 512MB + * 6 256MB 256MB + * 5 128MB 128MB + * 4 64MB 16GB + * 3 32MB 8GB + * 2 16MB 4GB + * 1 2GB 2GB + * 0 low 1GB 1GB + * + * Reorder Table to be linear by stripping the bottom + * 2 or 5 bits off and shifting them up to the top. + */ + +unsigned int +compute_banksize(unsigned int mem_type, unsigned char row_dens) +{ + unsigned int bsize; + + if (mem_type == SPD_MEMTYPE_DDR) { + /* Bottom 2 bits up to the top. */ + bsize = ((row_dens >> 2) | ((row_dens & 3) << 6)) << 24; + debug("DDR: DDR I rank density = 0x%08x\n", bsize); + } else { + /* Bottom 5 bits up to the top. */ + bsize = ((row_dens >> 5) | ((row_dens & 31) << 3)) << 27; + debug("DDR: DDR II rank density = 0x%08x\n", bsize); + } + return bsize; +} + + +/* + * Convert a two-nibble BCD value into a cycle time. + * While the spec calls for nano-seconds, picos are returned. + * + * This implements the tables for bytes 9, 23 and 25 for both + * DDR I and II. No allowance for distinguishing the invalid + * fields absent for DDR I yet present in DDR II is made. + * (That is, cycle times of .25, .33, .66 and .75 ns are + * allowed for both DDR II and I.) + */ + +unsigned int +convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val) +{ + /* + * Table look up the lower nibble, allow DDR I & II. + */ + unsigned int tenths_ps[16] = { + 0, + 100, + 200, + 300, + 400, + 500, + 600, + 700, + 800, + 900, + 250, + 330, /* FIXME: Is 333 better/valid? */ + 660, /* FIXME: Is 667 better/valid? */ + 750, + 0, /* undefined */ + 0 /* undefined */ + }; + + unsigned int whole_ns = (spd_val & 0xF0) >> 4; + unsigned int tenth_ns = spd_val & 0x0F; + unsigned int ps = whole_ns * 1000 + tenths_ps[tenth_ns]; + + return ps; +} + + +long int +spd_sdram(void) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_ddr_t *ddr1 = &immap->im_ddr1; + volatile ccsr_gur_t *gur = &immap->im_gur; + spd_eeprom_t spd; + unsigned int n_ranks; + unsigned int rank_density; + unsigned int odt_rd_cfg, odt_wr_cfg; + unsigned int odt_cfg, mode_odt_enable; + unsigned int dqs_cfg; + unsigned char twr_clk, twtr_clk, twr_auto_clk; + unsigned int tCKmin_ps, tCKmax_ps; + unsigned int max_data_rate, effective_data_rate; + unsigned int busfreq; + unsigned sdram_cfg_1; + unsigned int memsize; + unsigned char caslat, caslat_ctrl; + unsigned int trfc, trfc_clk, trfc_low, trfc_high; + unsigned int trcd_clk; + unsigned int trtp_clk; + unsigned char cke_min_clk; + unsigned char add_lat; + unsigned char wr_lat; + unsigned char wr_data_delay; + unsigned char four_act; + unsigned char cpo; + unsigned char burst_len; + unsigned int mode_caslat; + unsigned char sdram_type; + unsigned char d_init; + + + unsigned int law_size; + volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm; + + /* + * Read SPD information. + */ + + CFG_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) &spd, sizeof(spd)); + + /* + * Check for supported memory module types. + */ + if (spd.mem_type != SPD_MEMTYPE_DDR && + spd.mem_type != SPD_MEMTYPE_DDR2) { + printf("Unable to locate DDR I or DDR II module.\n" + " Fundamental memory type is 0x%0x\n", + spd.mem_type); + return 0; + } + + /* + * These test gloss over DDR I and II differences in interpretation + * of bytes 3 and 4, but irrelevantly. Multiple asymmetric banks + * are not supported on DDR I; and not encoded on DDR II. + * + * Also note that the 8548 controller can support: + * 12 <= nrow <= 16 + * and + * 8 <= ncol <= 11 (still, for DDR) + * 6 <= ncol <= 9 (for FCRAM) + */ + if (spd.nrow_addr < 12 || spd.nrow_addr > 14) { + printf("DDR: Unsupported number of Row Addr lines: %d.\n", + spd.nrow_addr); + return 0; + } + if (spd.ncol_addr < 8 || spd.ncol_addr > 11) { + printf("DDR: Unsupported number of Column Addr lines: %d.\n", + spd.ncol_addr); + return 0; + } + + /* + * Determine the number of physical banks controlled by + * different Chip Select signals. This is not quite the + * same as the number of DIMM modules on the board. Feh. + */ + if (spd.mem_type == SPD_MEMTYPE_DDR) { + n_ranks = spd.nrows; + } else { + n_ranks = (spd.nrows & 0x7) + 1; + } + + debug("DDR: number of ranks = %d\n", n_ranks); + + if (n_ranks > 2) { + printf("DDR: Only 2 chip selects are supported: %d\n", + n_ranks); + return 0; + } + + /* + * Adjust DDR II IO voltage biasing. It just makes it work. + */ + if (spd.mem_type == SPD_MEMTYPE_DDR2) { + gur->ddrioovcr = (0 + | 0x80000000 /* Enable */ + | 0x10000000 /* VSEL to 1.8V */ + ); + } + + /* + * Determine the size of each Rank in bytes. + */ + rank_density = compute_banksize(spd.mem_type, spd.row_dens); + + + /* + * Eg: Bounds: 0x0000_0000 to 0x0f000_0000 first 256 Meg + */ + ddr1->cs0_bnds = (rank_density >> 24) - 1; + + /* + * ODT configuration recommendation from DDR Controller Chapter. + */ + odt_rd_cfg = 0; /* Never assert ODT */ + odt_wr_cfg = 0; /* Never assert ODT */ + if (spd.mem_type == SPD_MEMTYPE_DDR2) { + odt_wr_cfg = 1; /* Assert ODT on writes to CS0 */ + } + + ddr1->cs0_config = ( 1 << 31 + | (odt_rd_cfg << 20) + | (odt_wr_cfg << 16) + | (spd.nrow_addr - 12) << 8 + | (spd.ncol_addr - 8) ); + debug("\n"); + debug("DDR: cs0_bnds = 0x%08x\n", ddr1->cs0_bnds); + debug("DDR: cs0_config = 0x%08x\n", ddr1->cs0_config); + + if (n_ranks == 2) { + /* + * Eg: Bounds: 0x0f00_0000 to 0x1e0000_0000, second 256 Meg + */ + ddr1->cs1_bnds = ( (rank_density >> 8) + | ((rank_density >> (24 - 1)) - 1) ); + ddr1->cs1_config = ( 1<<31 + | (odt_rd_cfg << 20) + | (odt_wr_cfg << 16) + | (spd.nrow_addr - 12) << 8 + | (spd.ncol_addr - 8) ); + debug("DDR: cs1_bnds = 0x%08x\n", ddr1->cs1_bnds); + debug("DDR: cs1_config = 0x%08x\n", ddr1->cs1_config); + } + + + /* + * Find the largest CAS by locating the highest 1 bit + * in the spd.cas_lat field. Translate it to a DDR + * controller field value: + * + * CAS Lat DDR I DDR II Ctrl + * Clocks SPD Bit SPD Bit Value + * ------- ------- ------- ----- + * 1.0 0 0001 + * 1.5 1 0010 + * 2.0 2 2 0011 + * 2.5 3 0100 + * 3.0 4 3 0101 + * 3.5 5 0110 + * 4.0 4 0111 + * 4.5 1000 + * 5.0 5 1001 + */ + caslat = __ilog2(spd.cas_lat); + if ((spd.mem_type == SPD_MEMTYPE_DDR) + && (caslat > 5)) { + printf("DDR I: Invalid SPD CAS Latency: 0x%x.\n", spd.cas_lat); + return 0; + + } else if (spd.mem_type == SPD_MEMTYPE_DDR2 + && (caslat < 2 || caslat > 5)) { + printf("DDR II: Invalid SPD CAS Latency: 0x%x.\n", + spd.cas_lat); + return 0; + } + debug("DDR: caslat SPD bit is %d\n", caslat); + + /* + * Calculate the Maximum Data Rate based on the Minimum Cycle time. + * The SPD clk_cycle field (tCKmin) is measured in tenths of + * nanoseconds and represented as BCD. + */ + tCKmin_ps = convert_bcd_tenths_to_cycle_time_ps(spd.clk_cycle); + debug("DDR: tCKmin = %d ps\n", tCKmin_ps); + + /* + * Double-data rate, scaled 1000 to picoseconds, and back down to MHz. + */ + max_data_rate = 2 * 1000 * 1000 / tCKmin_ps; + debug("DDR: Module max data rate = %d Mhz\n", max_data_rate); + + + /* + * Adjust the CAS Latency to allow for bus speeds that + * are slower than the DDR module. + */ + busfreq = get_bus_freq(0) / 1000000; /* MHz */ + + effective_data_rate = max_data_rate; + if (busfreq < 90) { + /* DDR rate out-of-range */ + puts("DDR: platform frequency is not fit for DDR rate\n"); + return 0; + + } else if (90 <= busfreq && busfreq < 230 && max_data_rate >= 230) { + /* + * busfreq 90~230 range, treated as DDR 200. + */ + effective_data_rate = 200; + if (spd.clk_cycle3 == 0xa0) /* 10 ns */ + caslat -= 2; + else if (spd.clk_cycle2 == 0xa0) + caslat--; + + } else if (230 <= busfreq && busfreq < 280 && max_data_rate >= 280) { + /* + * busfreq 230~280 range, treated as DDR 266. + */ + effective_data_rate = 266; + if (spd.clk_cycle3 == 0x75) /* 7.5 ns */ + caslat -= 2; + else if (spd.clk_cycle2 == 0x75) + caslat--; + + } else if (280 <= busfreq && busfreq < 350 && max_data_rate >= 350) { + /* + * busfreq 280~350 range, treated as DDR 333. + */ + effective_data_rate = 333; + if (spd.clk_cycle3 == 0x60) /* 6.0 ns */ + caslat -= 2; + else if (spd.clk_cycle2 == 0x60) + caslat--; + + } else if (350 <= busfreq && busfreq < 460 && max_data_rate >= 460) { + /* + * busfreq 350~460 range, treated as DDR 400. + */ + effective_data_rate = 400; + if (spd.clk_cycle3 == 0x50) /* 5.0 ns */ + caslat -= 2; + else if (spd.clk_cycle2 == 0x50) + caslat--; + + } else if (460 <= busfreq && busfreq < 560 && max_data_rate >= 560) { + /* + * busfreq 460~560 range, treated as DDR 533. + */ + effective_data_rate = 533; + if (spd.clk_cycle3 == 0x3D) /* 3.75 ns */ + caslat -= 2; + else if (spd.clk_cycle2 == 0x3D) + caslat--; + + } else if (560 <= busfreq && busfreq < 700 && max_data_rate >= 700) { + /* + * busfreq 560~700 range, treated as DDR 667. + */ + effective_data_rate = 667; + if (spd.clk_cycle3 == 0x30) /* 3.0 ns */ + caslat -= 2; + else if (spd.clk_cycle2 == 0x30) + caslat--; + + } else if (700 <= busfreq) { + /* + * DDR rate out-of-range + */ + printf("DDR: Bus freq %d MHz is not fit for DDR rate %d MHz\n", + busfreq, max_data_rate); + return 0; + } + + + /* + * Convert caslat clocks to DDR controller value. + * Force caslat_ctrl to be DDR Controller field-sized. + */ + if (spd.mem_type == SPD_MEMTYPE_DDR) { + caslat_ctrl = (caslat + 1) & 0x07; + } else { + caslat_ctrl = (2 * caslat - 1) & 0x0f; + } + + debug("DDR: effective data rate is %d MHz\n", effective_data_rate); + debug("DDR: caslat SPD bit is %d, controller field is 0x%x\n", + caslat, caslat_ctrl); + + /* + * Timing Config 0. + * Avoid writing for DDR I. The new PQ38 DDR controller + * dreams up non-zero default values to be backwards compatible. + */ + if (spd.mem_type == SPD_MEMTYPE_DDR2) { + unsigned char taxpd_clk = 8; /* By the book. */ + unsigned char tmrd_clk = 2; /* By the book. */ + unsigned char act_pd_exit = 2; /* Empirical? */ + unsigned char pre_pd_exit = 6; /* Empirical? */ + + ddr1->timing_cfg_0 = (0 + | ((act_pd_exit & 0x7) << 20) /* ACT_PD_EXIT */ + | ((pre_pd_exit & 0x7) << 16) /* PRE_PD_EXIT */ + | ((taxpd_clk & 0xf) << 8) /* ODT_PD_EXIT */ + | ((tmrd_clk & 0xf) << 0) /* MRS_CYC */ + ); + debug("DDR: timing_cfg_0 = 0x%08x\n", ddr1->timing_cfg_0); + + } else { + } + + + /* + * Some Timing Config 1 values now. + * Sneak Extended Refresh Recovery in here too. + */ + + /* + * For DDR I, WRREC(Twr) and WRTORD(Twtr) are not in SPD, + * use conservative value. + * For DDR II, they are bytes 36 and 37, in quarter nanos. + */ + + if (spd.mem_type == SPD_MEMTYPE_DDR) { + twr_clk = 3; /* Clocks */ + twtr_clk = 1; /* Clocks */ + } else { + twr_clk = picos_to_clk(spd.twr * 250); + twtr_clk = picos_to_clk(spd.twtr * 250); + } + + /* + * Calculate Trfc, in picos. + * DDR I: Byte 42 straight up in ns. + * DDR II: Byte 40 and 42 swizzled some, in ns. + */ + if (spd.mem_type == SPD_MEMTYPE_DDR) { + trfc = spd.trfc * 1000; /* up to ps */ + } else { + unsigned int byte40_table_ps[8] = { + 0, + 250, + 330, + 500, + 660, + 750, + 0, + 0 + }; + + trfc = (((spd.trctrfc_ext & 0x1) * 256) + spd.trfc) * 1000 + + byte40_table_ps[(spd.trctrfc_ext >> 1) & 0x7]; + } + trfc_clk = picos_to_clk(trfc); + + /* + * Trcd, Byte 29, from quarter nanos to ps and clocks. + */ + trcd_clk = picos_to_clk(spd.trcd * 250) & 0x7; + + /* + * Convert trfc_clk to DDR controller fields. DDR I should + * fit in the REFREC field (16-19) of TIMING_CFG_1, but the + * 8548 controller has an extended REFREC field of three bits. + * The controller automatically adds 8 clocks to this value, + * so preadjust it down 8 first before splitting it up. + */ + trfc_low = (trfc_clk - 8) & 0xf; + trfc_high = ((trfc_clk - 8) >> 4) & 0x3; + + /* + * Sneak in some Extended Refresh Recovery. + */ + ddr1->ext_refrec = (trfc_high << 16); + debug("DDR: ext_refrec = 0x%08x\n", ddr1->ext_refrec); + + ddr1->timing_cfg_1 = + (0 + | ((picos_to_clk(spd.trp * 250) & 0x07) << 28) /* PRETOACT */ + | ((picos_to_clk(spd.tras * 1000) & 0x0f ) << 24) /* ACTTOPRE */ + | (trcd_clk << 20) /* ACTTORW */ + | (caslat_ctrl << 16) /* CASLAT */ + | (trfc_low << 12) /* REFEC */ + | ((twr_clk & 0x07) << 8) /* WRRREC */ + | ((picos_to_clk(spd.trrd * 250) & 0x07) << 4) /* ACTTOACT */ + | ((twtr_clk & 0x07) << 0) /* WRTORD */ + ); + + debug("DDR: timing_cfg_1 = 0x%08x\n", ddr1->timing_cfg_1); + + + /* + * Timing_Config_2 + * Was: 0x00000800; + */ + + /* + * Additive Latency + * For DDR I, 0. + * For DDR II, with ODT enabled, use "a value" less than ACTTORW, + * which comes from Trcd, and also note that: + * add_lat + caslat must be >= 4 + */ + add_lat = 0; + if (spd.mem_type == SPD_MEMTYPE_DDR2 + && (odt_wr_cfg || odt_rd_cfg) + && (caslat < 4)) { + add_lat = 4 - caslat; + if (add_lat > trcd_clk) { + add_lat = trcd_clk - 1; + } + } + + /* + * Write Data Delay + * Historically 0x2 == 4/8 clock delay. + * Empirically, 0x3 == 6/8 clock delay is suggested for DDR I 266. + */ + wr_data_delay = 3; + + /* + * Write Latency + * Read to Precharge + * Minimum CKE Pulse Width. + * Four Activate Window + */ + if (spd.mem_type == SPD_MEMTYPE_DDR) { + /* + * This is a lie. It should really be 1, but if it is + * set to 1, bits overlap into the old controller's + * otherwise unused ACSM field. If we leave it 0, then + * the HW will magically treat it as 1 for DDR 1. Oh Yea. + */ + wr_lat = 0; + + trtp_clk = 2; /* By the book. */ + cke_min_clk = 1; /* By the book. */ + four_act = 1; /* By the book. */ + + } else { + wr_lat = caslat - 1; + + /* Convert SPD value from quarter nanos to picos. */ + trtp_clk = picos_to_clk(spd.trtp * 250); + + cke_min_clk = 3; /* By the book. */ + four_act = picos_to_clk(37500); /* By the book. 1k pages? */ + } + + /* + * Empirically set ~MCAS-to-preamble override for DDR 2. + * Your milage will vary. + */ + cpo = 0; + if (spd.mem_type == SPD_MEMTYPE_DDR2) { + if (effective_data_rate == 266 || effective_data_rate == 333) { + cpo = 0x7; /* READ_LAT + 5/4 */ + } else if (effective_data_rate == 400) { + cpo = 0x9; /* READ_LAT + 7/4 */ + } else { + /* Pure speculation */ + cpo = 0xb; + } + } + + ddr1->timing_cfg_2 = (0 + | ((add_lat & 0x7) << 28) /* ADD_LAT */ + | ((cpo & 0x1f) << 23) /* CPO */ + | ((wr_lat & 0x7) << 19) /* WR_LAT */ + | ((trtp_clk & 0x7) << 13) /* RD_TO_PRE */ + | ((wr_data_delay & 0x7) << 10) /* WR_DATA_DELAY */ + | ((cke_min_clk & 0x7) << 6) /* CKE_PLS */ + | ((four_act & 0x1f) << 0) /* FOUR_ACT */ + ); + + debug("DDR: timing_cfg_2 = 0x%08x\n", ddr1->timing_cfg_2); + + + /* + * Determine the Mode Register Set. + * + * This is nominally part specific, but it appears to be + * consistent for all DDR I devices, and for all DDR II devices. + * + * caslat must be programmed + * burst length is always 4 + * burst type is sequential + * + * For DDR I: + * operating mode is "normal" + * + * For DDR II: + * other stuff + */ + + mode_caslat = 0; + + /* + * Table lookup from DDR I or II Device Operation Specs. + */ + if (spd.mem_type == SPD_MEMTYPE_DDR) { + if (1 <= caslat && caslat <= 4) { + unsigned char mode_caslat_table[4] = { + 0x5, /* 1.5 clocks */ + 0x2, /* 2.0 clocks */ + 0x6, /* 2.5 clocks */ + 0x3 /* 3.0 clocks */ + }; + mode_caslat = mode_caslat_table[caslat - 1]; + } else { + puts("DDR I: Only CAS Latencies of 1.5, 2.0, " + "2.5 and 3.0 clocks are supported.\n"); + return 0; + } + + } else { + if (2 <= caslat && caslat <= 5) { + mode_caslat = caslat; + } else { + puts("DDR II: Only CAS Latencies of 2.0, 3.0, " + "4.0 and 5.0 clocks are supported.\n"); + return 0; + } + } + + /* + * Encoded Burst Lenght of 4. + */ + burst_len = 2; /* Fiat. */ + + if (spd.mem_type == SPD_MEMTYPE_DDR) { + twr_auto_clk = 0; /* Historical */ + } else { + /* + * Determine tCK max in picos. Grab tWR and convert to picos. + * Auto-precharge write recovery is: + * WR = roundup(tWR_ns/tCKmax_ns). + * + * Ponder: Is twr_auto_clk different than twr_clk? + */ + tCKmax_ps = convert_bcd_tenths_to_cycle_time_ps(spd.tckmax); + twr_auto_clk = (spd.twr * 250 + tCKmax_ps - 1) / tCKmax_ps; + } + + + /* + * Mode Reg in bits 16 ~ 31, + * Extended Mode Reg 1 in bits 0 ~ 15. + */ + mode_odt_enable = 0x0; /* Default disabled */ + if (odt_wr_cfg || odt_rd_cfg) { + /* + * Bits 6 and 2 in Extended MRS(1) + * Bit 2 == 0x04 == 75 Ohm, with 2 DIMM modules. + * Bit 6 == 0x40 == 150 Ohm, with 1 DIMM module. + */ + mode_odt_enable = 0x40; /* 150 Ohm */ + } + + ddr1->sdram_mode_1 = + (0 + | (add_lat << (16 + 3)) /* Additive Latency in EMRS1 */ + | (mode_odt_enable << 16) /* ODT Enable in EMRS1 */ + | (twr_auto_clk << 9) /* Write Recovery Autopre */ + | (mode_caslat << 4) /* caslat */ + | (burst_len << 0) /* Burst length */ + ); + + debug("DDR: sdram_mode = 0x%08x\n", ddr1->sdram_mode_1); + + + /* + * Clear EMRS2 and EMRS3. + */ + ddr1->sdram_mode_2 = 0; + debug("DDR: sdram_mode_2 = 0x%08x\n", ddr1->sdram_mode_2); + + + /* + * Determine Refresh Rate. Ignore self refresh bit on DDR I. + * Table from SPD Spec, Byte 12, converted to picoseconds and + * filled in with "default" normal values. + */ + { + unsigned int refresh_clk; + unsigned int refresh_time_ns[8] = { + 15625000, /* 0 Normal 1.00x */ + 3900000, /* 1 Reduced .25x */ + 7800000, /* 2 Extended .50x */ + 31300000, /* 3 Extended 2.00x */ + 62500000, /* 4 Extended 4.00x */ + 125000000, /* 5 Extended 8.00x */ + 15625000, /* 6 Normal 1.00x filler */ + 15625000, /* 7 Normal 1.00x filler */ + }; + + refresh_clk = picos_to_clk(refresh_time_ns[spd.refresh & 0x7]); + + /* + * Set BSTOPRE to 0x100 for page mode + * If auto-charge is used, set BSTOPRE = 0 + */ + ddr1->sdram_interval = + (0 + | (refresh_clk & 0x3fff) << 16 + | 0x100 + ); + debug("DDR: sdram_interval = 0x%08x\n", ddr1->sdram_interval); + } + + /* + * Is this an ECC DDR chip? + * But don't mess with it if the DDR controller will init mem. + */ +#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) + if (spd.config == 0x02) { + ddr1->err_disable = 0x0000000d; + ddr1->err_sbe = 0x00ff0000; + } + debug("DDR: err_disable = 0x%08x\n", ddr1->err_disable); + debug("DDR: err_sbe = 0x%08x\n", ddr1->err_sbe); +#endif + + asm("sync;isync"); + udelay(500); + + /* + * SDRAM Cfg 2 + */ + + /* + * When ODT is enabled, Chap 9 suggests asserting ODT to + * internal IOs only during reads. + */ + odt_cfg = 0; + if (odt_rd_cfg | odt_wr_cfg) { + odt_cfg = 0x2; /* ODT to IOs during reads */ + } + + /* + * Try to use differential DQS with DDR II. + */ + if (spd.mem_type == SPD_MEMTYPE_DDR) { + dqs_cfg = 0; /* No Differential DQS for DDR I */ + } else { + dqs_cfg = 0x1; /* Differential DQS for DDR II */ + } + +#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) + /* + * Use the DDR controller to auto initialize memory. + */ + d_init = 1; + ddr1->sdram_data_init = CONFIG_MEM_INIT_VALUE; + debug("DDR: ddr_data_init = 0x%08x\n", ddr1->sdram_data_init); +#else + /* + * Memory will be initialized via DMA, or not at all. + */ + d_init = 0; +#endif + + ddr1->sdram_cfg_2 = (0 + | (dqs_cfg << 26) /* Differential DQS */ + | (odt_cfg << 21) /* ODT */ + | (d_init << 4) /* D_INIT auto init DDR */ + ); + + debug("DDR: sdram_cfg_2 = 0x%08x\n", ddr1->sdram_cfg_2); + + +#ifdef MPC86xx_DDR_SDRAM_CLK_CNTL + { + unsigned char clk_adjust; + + /* + * Setup the clock control. + * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1 + * SDRAM_CLK_CNTL[5-7] = Clock Adjust + * 0110 3/4 cycle late + * 0111 7/8 cycle late + */ + if (spd.mem_type == SPD_MEMTYPE_DDR) { + clk_adjust = 0x6; + } else { + clk_adjust = 0x7; + } + + ddr1->sdram_clk_cntl = (0 + | 0x80000000 + | (clk_adjust << 23) + ); + debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr1->sdram_clk_cntl); + } +#endif + + /* + * Figure out the settings for the sdram_cfg register. + * Build up the entire register in 'sdram_cfg' before writing + * since the write into the register will actually enable the + * memory controller; all settings must be done before enabling. + * + * sdram_cfg[0] = 1 (ddr sdram logic enable) + * sdram_cfg[1] = 1 (self-refresh-enable) + * sdram_cfg[5:7] = (SDRAM type = DDR SDRAM) + * 010 DDR 1 SDRAM + * 011 DDR 2 SDRAM + */ + sdram_type = (spd.mem_type == SPD_MEMTYPE_DDR) ? 2 : 3; + sdram_cfg_1 = (0 + | (1 << 31) /* Enable */ + | (1 << 30) /* Self refresh */ + | (sdram_type << 24) /* SDRAM type */ + ); + + /* + * sdram_cfg[3] = RD_EN - registered DIMM enable + * A value of 0x26 indicates micron registered DIMMS (micron.com) + */ + if (spd.mem_type == SPD_MEMTYPE_DDR && spd.mod_attr == 0x26) { + sdram_cfg_1 |= 0x10000000; /* RD_EN */ + } + +#if defined(CONFIG_DDR_ECC) + /* + * If the user wanted ECC (enabled via sdram_cfg[2]) + */ + if (spd.config == 0x02) { + sdram_cfg_1 |= 0x20000000; /* ECC_EN */ + } +#endif + + /* + * REV1 uses 1T timing. + * REV2 may use 1T or 2T as configured by the user. + */ + { + uint pvr = get_pvr(); + + if (pvr != PVR_85xx_REV1) { +#if defined(CONFIG_DDR_2T_TIMING) + /* + * Enable 2T timing by setting sdram_cfg[16]. + */ + sdram_cfg_1 |= 0x8000; /* 2T_EN */ +#endif + } + } + + /* + * 200 painful micro-seconds must elapse between + * the DDR clock setup and the DDR config enable. + */ + udelay(200); + + /* + * Go! + */ + ddr1->sdram_cfg_1 = sdram_cfg_1; + + asm("sync;isync"); + udelay(500); + + debug("DDR: sdram_cfg = 0x%08x\n", ddr1->sdram_cfg_1); + + +#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) + debug("DDR: memory initializing\n"); + /* + * Poll until memory is initialized. + * 512 Meg at 400 might hit this 200 times or so. + */ + while ((ddr1->sdram_cfg_2 & (d_init << 4)) != 0) { + udelay(1000); + } + debug("DDR: memory initialized\n"); +#endif + + + /* + * Figure out memory size in Megabytes. + */ + memsize = n_ranks * rank_density / 0x100000; + + + /* + * First supported LAW size is 16M, at LAWAR_SIZE_16M == 23. Fnord. + */ + law_size = 19 + __ilog2(memsize); + + /* + * Set up LAWBAR for all of DDR. + */ + mcm->lawbar1 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff); + mcm->lawar1 = (LAWAR_EN + | LAWAR_TRGT_IF_DDR + | (LAWAR_SIZE & law_size)); + debug("DDR: LAWBAR1=0x%08x\n", mcm->lawbar1); + debug("DDR: LARAR1=0x%08x\n", mcm->lawar1); + + return memsize * 1024 * 1024; +} + +#endif /* CONFIG_SPD_EEPROM */ + + +#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) + +/* + * Initialize all of memory for ECC, then enable errors. + */ + +void +ddr_enable_ecc(unsigned int dram_size) +{ + uint *p = 0; + uint i = 0; + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_ddr_t *ddr1= &immap->im_ddr1; + + dma_init(); + + for (*p = 0; p < (uint *)(8 * 1024); p++) { + if (((unsigned int)p & 0x1f) == 0) { + ppcDcbz((unsigned long) p); + } + *p = (unsigned int)CONFIG_MEM_INIT_VALUE; + if (((unsigned int)p & 0x1c) == 0x1c) { + ppcDcbf((unsigned long) p); + } + } + + /* 8K */ + dma_xfer((uint *)0x2000, 0x2000, (uint *)0); + /* 16K */ + dma_xfer((uint *)0x4000, 0x4000, (uint *)0); + /* 32K */ + dma_xfer((uint *)0x8000, 0x8000, (uint *)0); + /* 64K */ + dma_xfer((uint *)0x10000, 0x10000, (uint *)0); + /* 128k */ + dma_xfer((uint *)0x20000, 0x20000, (uint *)0); + /* 256k */ + dma_xfer((uint *)0x40000, 0x40000, (uint *)0); + /* 512k */ + dma_xfer((uint *)0x80000, 0x80000, (uint *)0); + /* 1M */ + dma_xfer((uint *)0x100000, 0x100000, (uint *)0); + /* 2M */ + dma_xfer((uint *)0x200000, 0x200000, (uint *)0); + /* 4M */ + dma_xfer((uint *)0x400000, 0x400000, (uint *)0); + + for (i = 1; i < dram_size / 0x800000; i++) { + dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0); + } + + /* + * Enable errors for ECC. + */ + debug("DMA DDR: err_disable = 0x%08x\n", ddr1->err_disable); + ddr1->err_disable = 0x00000000; + asm("sync;isync;msync"); + debug("DMA DDR: err_disable = 0x%08x\n", ddr1->err_disable); +} + +#endif /* CONFIG_DDR_ECC && ! CONFIG_ECC_INIT_VIA_DDRCONTROLLER */ diff --git a/cpu/mpc86xx/speed.c b/cpu/mpc86xx/speed.c new file mode 100644 index 0000000000..a08ae5f94b --- /dev/null +++ b/cpu/mpc86xx/speed.c @@ -0,0 +1,240 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * Jeff Brown (jeffrey@freescale.com) + * Srikanth Srinivasan (srikanth.srinivasan@freescale.com) + * + * (C) Copyright 2000-2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <mpc86xx.h> +#include <asm/processor.h> + +unsigned long get_board_sys_clk(ulong dummy); +unsigned long get_sysclk_from_px_regs(void); + + +void get_sys_info (sys_info_t *sysInfo) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_gur_t *gur = &immap->im_gur; + uint plat_ratio, e600_ratio; + + plat_ratio = (gur->porpllsr) & 0x0000003e; + plat_ratio >>= 1; + + switch(plat_ratio) { + case 0x0: + sysInfo->freqSystemBus = 16 * CONFIG_SYS_CLK_FREQ; + break; + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x08: + case 0x09: + case 0x0a: + case 0x0c: + case 0x10: + sysInfo->freqSystemBus = plat_ratio * CONFIG_SYS_CLK_FREQ; + break; + default: + sysInfo->freqSystemBus = 0; + break; + } + +#if 0 + printf("assigned system bus freq = %d for plat ratio 0x%08lx\n", + sysInfo->freqSystemBus, plat_ratio); +#endif + + e600_ratio = (gur->porpllsr) & 0x003f0000; + e600_ratio >>= 16; + + switch (e600_ratio) { + case 0x10: + sysInfo->freqProcessor = 2 * sysInfo->freqSystemBus; + break; + case 0x19: + sysInfo->freqProcessor = 5 * sysInfo->freqSystemBus/2; + break; + case 0x20: + sysInfo->freqProcessor = 3 * sysInfo->freqSystemBus; + break; + case 0x39: + sysInfo->freqProcessor = 7 * sysInfo->freqSystemBus/2; + break; + case 0x28: + sysInfo->freqProcessor = 4 * sysInfo->freqSystemBus; + break; + case 0x1d: + sysInfo->freqProcessor = 9 * sysInfo->freqSystemBus/2; + break; + default: + /* JB - Emulator workaround until real cop is plugged in */ + /* sysInfo->freqProcessor = 3 * sysInfo->freqSystemBus; */ + sysInfo->freqProcessor = e600_ratio + sysInfo->freqSystemBus; + break; + } +#if 0 + printf("assigned processor freq = %d for e600 ratio 0x%08lx\n", + sysInfo->freqProcessor, e600_ratio); +#endif +} + + +/* + * Measure CPU clock speed (core clock GCLK1, GCLK2) + * (Approx. GCLK frequency in Hz) + */ + +int get_clocks(void) +{ + DECLARE_GLOBAL_DATA_PTR; + sys_info_t sys_info; + + get_sys_info(&sys_info); + gd->cpu_clk = sys_info.freqProcessor; + gd->bus_clk = sys_info.freqSystemBus; + + if (gd->cpu_clk != 0) + return 0; + else + return 1; +} + + +/* + * get_bus_freq + * Return system bus freq in Hz + */ +ulong get_bus_freq(ulong dummy) +{ + ulong val; + sys_info_t sys_info; + + get_sys_info(&sys_info); + val = sys_info.freqSystemBus; + + return val; +} + +unsigned long get_sysclk_from_px_regs() +{ + ulong val; + u8 vclkh, vclkl; + + vclkh = in8(PIXIS_BASE + PIXIS_VCLKH); + vclkl = in8(PIXIS_BASE + PIXIS_VCLKL); + + if ((vclkh == 0x84) && (vclkl == 0x07)) { + val = 33000000; + } + if ((vclkh == 0x3F) && (vclkl == 0x20)) { + val = 40000000; + } + if ((vclkh == 0x3F) && (vclkl == 0x2A)) { + val = 50000000; + } + if ((vclkh == 0x24) && (vclkl == 0x04)) { + val = 66000000; + } + if ((vclkh == 0x3F) && (vclkl == 0x4B)) { + val = 83000000; + } + if ((vclkh == 0x3F) && (vclkl == 0x5C)) { + val = 100000000; + } + if ((vclkh == 0xDF) && (vclkl == 0x3B)) { + val = 134000000; + } + if ((vclkh == 0xDF) && (vclkl == 0x4B)) { + val = 166000000; + } + + return val; +} + + +/* + * get_board_sys_clk + * Reads the FPGA on board for CONFIG_SYS_CLK_FREQ + */ + +unsigned long get_board_sys_clk(ulong dummy) +{ + u8 i, go_bit, rd_clks; + ulong val; + + go_bit = in8(PIXIS_BASE + PIXIS_VCTL); + go_bit &= 0x01; + + rd_clks = in8(PIXIS_BASE + PIXIS_VCFGEN0); + rd_clks &= 0x1C; + + /* + * Only if both go bit and the SCLK bit in VCFGEN0 are set + * should we be using the AUX register. Remember, we also set the + * GO bit to boot from the alternate bank on the on-board flash + */ + + if (go_bit) { + if (rd_clks == 0x1c) + i = in8(PIXIS_BASE + PIXIS_AUX); + else + i = in8(PIXIS_BASE + PIXIS_SPD); + } else { + i = in8(PIXIS_BASE + PIXIS_SPD); + } + + i &= 0x07; + + switch (i) { + case 0: + val = 33000000; + break; + case 1: + val = 40000000; + break; + case 2: + val = 50000000; + break; + case 3: + val = 66000000; + break; + case 4: + val = 83000000; + break; + case 5: + val = 100000000; + break; + case 6: + val = 134000000; + break; + case 7: + val = 166000000; + break; + } + + return val; +} diff --git a/cpu/mpc86xx/start.S b/cpu/mpc86xx/start.S new file mode 100644 index 0000000000..0a447a76b7 --- /dev/null +++ b/cpu/mpc86xx/start.S @@ -0,0 +1,1240 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * Srikanth Srinivasan <srikanth.srinivaan@freescale.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* U-Boot - Startup Code for 86xx PowerPC based Embedded Boards + * + * + * The processor starts at 0xfff00100 and the code is executed + * from flash. The code is organized to be at an other address + * in memory, but as long we don't jump around before relocating. + * board_init lies at a quite high address and when the cpu has + * jumped there, everything is ok. + */ +#include <config.h> +#include <mpc86xx.h> +#include <version.h> + +#include <ppc_asm.tmpl> +#include <ppc_defs.h> + +#include <asm/cache.h> +#include <asm/mmu.h> + +#ifndef CONFIG_IDENT_STRING +#define CONFIG_IDENT_STRING "" +#endif + +/* We don't want the MMU yet. +*/ +#undef MSR_KERNEL +/* Machine Check and Recoverable Interr. */ +#define MSR_KERNEL ( MSR_ME | MSR_RI ) + +/* + * Set up GOT: Global Offset Table + * + * Use r14 to access the GOT + */ + START_GOT + GOT_ENTRY(_GOT2_TABLE_) + GOT_ENTRY(_FIXUP_TABLE_) + + GOT_ENTRY(_start) + GOT_ENTRY(_start_of_vectors) + GOT_ENTRY(_end_of_vectors) + GOT_ENTRY(transfer_to_handler) + + GOT_ENTRY(__init_end) + GOT_ENTRY(_end) + GOT_ENTRY(__bss_start) + END_GOT + +/* + * r3 - 1st arg to board_init(): IMMP pointer + * r4 - 2nd arg to board_init(): boot flag + */ + .text + .long 0x27051956 /* U-Boot Magic Number */ + .globl version_string +version_string: + .ascii U_BOOT_VERSION + .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii CONFIG_IDENT_STRING, "\0" + + . = EXC_OFF_SYS_RESET + .globl _start +_start: + li r21, BOOTFLAG_COLD /* Normal Power-On: Boot from FLASH */ + b boot_cold + sync + + . = EXC_OFF_SYS_RESET + 0x10 + + .globl _start_warm +_start_warm: + li r21, BOOTFLAG_WARM /* Software reboot */ + b boot_warm + sync + + /* the boot code is located below the exception 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 + mfspr r4,DAR + stw r4,_DAR(r21) + mfspr r5,DSISR + stw r5,_DSISR(r21) + addi r3,r1,STACK_FRAME_OVERHEAD + li r20,MSR_KERNEL + rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ + lwz r6,GOT(transfer_to_handler) + mtlr r6 + blrl +.L_Alignment: + .long AlignmentException - _start + EXC_OFF_SYS_RESET + .long int_return - _start + EXC_OFF_SYS_RESET + +/* Program check exception */ + . = 0x700 +ProgramCheck: + EXCEPTION_PROLOG + addi r3,r1,STACK_FRAME_OVERHEAD + li r20,MSR_KERNEL + rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ + lwz r6,GOT(transfer_to_handler) + mtlr r6 + blrl +.L_ProgramCheck: + .long ProgramCheckException - _start + EXC_OFF_SYS_RESET + .long int_return - _start + EXC_OFF_SYS_RESET + + 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, SoftEmu, SoftEmuException) + STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException) + STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException) + STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException) + STD_EXCEPTION(0x1400, DataTLBError, UnknownException) + STD_EXCEPTION(0x1500, Reserved5, UnknownException) + STD_EXCEPTION(0x1600, Reserved6, UnknownException) + STD_EXCEPTION(0x1700, Reserved7, UnknownException) + STD_EXCEPTION(0x1800, Reserved8, UnknownException) + STD_EXCEPTION(0x1900, Reserved9, UnknownException) + STD_EXCEPTION(0x1a00, ReservedA, UnknownException) + STD_EXCEPTION(0x1b00, ReservedB, UnknownException) + STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException) + STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException) + STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException) + STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException) + + .globl _end_of_vectors +_end_of_vectors: + + . = 0x2000 + +boot_cold: +boot_warm: + + /* if this is a multi-core system we need to check which cpu + * this is, if it is not cpu 0 send the cpu to the linux reset + * vector */ +#if (CONFIG_NUM_CPUS > 1) + mfspr r0, MSSCR0 + andi. r0, r0, 0x0020 + rlwinm r0,r0,27,31,31 + mtspr PIR, r0 + beq 1f + + bl secondary_cpu_setup +#endif + + /* disable everything */ +1: li r0, 0 + mtspr HID0, r0 + sync + mtmsr 0 + bl invalidate_bats + sync + +#ifdef CFG_L2 + /* init the L2 cache */ + addis r3, r0, L2_INIT@h + ori r3, r3, L2_INIT@l + sync + mtspr l2cr, r3 +#ifdef CONFIG_ALTIVEC + dssall +#endif + /* invalidate the L2 cache */ + bl l2cache_invalidate + sync +#endif + + /* + * Calculate absolute address in FLASH and jump there + *------------------------------------------------------*/ + lis r3, CFG_MONITOR_BASE@h + ori r3, r3, CFG_MONITOR_BASE@l + addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET + mtlr r3 + blr + +in_flash: + /* let the C-code set up the rest */ + /* */ + /* Be careful to keep code relocatable ! */ + /*------------------------------------------------------*/ + /* perform low-level init */ + + /* enable extended addressing */ + bl enable_ext_addr + + /* setup the bats */ + bl setup_bats + sync + +#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR) + /* setup ccsrbar */ + bl setup_ccsrbar +#endif + + /* setup the law entries */ + bl law_entry + sync + + /* Don't use this feature due to bug in 8641D PD4 */ + /* Disable ERD_DIS */ + lis r3, CFG_CCSRBAR@h + ori r3, r3, 0x1008 + lwz r4, 0(r3) + oris r4, r4, 0x4000 + stw r4, 0(r3) + sync + +#if (EMULATOR_RUN == 1) + /* On the emulator we want to adjust these ASAP */ + /* otherwise things are sloooow */ + /* Setup OR0 (LALE FIX)*/ + lis r3, CFG_CCSRBAR@h + ori r3, r3, 0x5004 + li r4, 0x0FF3 + stw r4, 0(r3) + sync + + /* Setup LCRR */ + lis r3, CFG_CCSRBAR@h + ori r3, r3, 0x50D4 + lis r4, 0x8000 + ori r4, r4, 0x0002 + stw r4, 0(r3) + sync +#endif +#if 1 + /* make sure timer enabled in guts register too */ + lis r3, CFG_CCSRBAR@h + oris r3,r3, 0xE + ori r3,r3,0x0070 /*Jason from 3*/ + lwz r4, 0(r3) + lis r5,0xFFFC /*Jason from 0xffff*/ + ori r5,r5,0x5FFF + and r4,r4,r5 + stw r4,0(r3) +#endif + /* + * Cache must be enabled here for stack-in-cache trick. + * This means we need to enable the BATS. + * Cache should be turned on after BATs, since by default + * everything is write-through. + */ + + /* enable address translation */ + bl enable_addr_trans + sync + + /* enable and invalidate the data cache */ +/* bl l1dcache_enable */ + bl dcache_enable + sync + +#if 1 + bl icache_enable +#endif + +#ifdef CFG_INIT_RAM_LOCK + bl lock_ram_in_cache + sync +#endif + + /* set up the stack pointer in our newly created + * cache-ram (r1) */ + lis r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h + ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l + + 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 */ + + GET_GOT /* initialize GOT access */ + + /* run low-level CPU init code (from Flash) */ + bl cpu_init_f + sync + +#ifdef RUN_DIAG + + /* Sri: Code to run the diagnostic automatically */ + + /* Load PX_AUX register address in r4 */ + lis r4, 0xf810 + ori r4, r4, 0x6 + /* Load contents of PX_AUX in r3 bits 24 to 31*/ + lbz r3, 0(r4) + + /* Mask and obtain the bit in r3 */ + rlwinm. r3, r3, 0, 24, 24 + /* If not zero, jump and continue with u-boot */ + bne diag_done + + /* Load back contents of PX_AUX in r3 bits 24 to 31 */ + lbz r3, 0(r4) + /* Set the MSB of the register value */ + ori r3, r3, 0x80 + /* Write value in r3 back to PX_AUX */ + stb r3, 0(r4) + + /* Get the address to jump to in r3*/ + lis r3, CFG_DIAG_ADDR@h + ori r3, r3, CFG_DIAG_ADDR@l + + /* Load the LR with the branch address */ + mtlr r3 + + /* Branch to diagnostic */ + blr + +diag_done: +#endif + + /* bl l2cache_enable*/ + mr r3, r21 + + /* r3: BOOTFLAG */ + /* run 1st part of board init code (from Flash) */ + bl board_init_f + sync + + /* NOTREACHED */ + + .globl invalidate_bats +invalidate_bats: + + /* invalidate BATs */ + mtspr IBAT0U, r0 + mtspr IBAT1U, r0 + mtspr IBAT2U, r0 + mtspr IBAT3U, r0 + mtspr IBAT4U, r0 + mtspr IBAT5U, r0 + mtspr IBAT6U, r0 + mtspr IBAT7U, r0 + + isync + mtspr DBAT0U, r0 + mtspr DBAT1U, r0 + mtspr DBAT2U, r0 + mtspr DBAT3U, r0 + mtspr DBAT4U, r0 + mtspr DBAT5U, r0 + mtspr DBAT6U, r0 + mtspr DBAT7U, r0 + + isync + sync + blr + + + /* setup_bats - set them up to some initial state */ + .globl setup_bats +setup_bats: + + addis r0, r0, 0x0000 + + /* IBAT 0 */ + addis r4, r0, CFG_IBAT0L@h + ori r4, r4, CFG_IBAT0L@l + addis r3, r0, CFG_IBAT0U@h + ori r3, r3, CFG_IBAT0U@l + mtspr IBAT0L, r4 + mtspr IBAT0U, r3 + isync + + /* DBAT 0 */ + addis r4, r0, CFG_DBAT0L@h + ori r4, r4, CFG_DBAT0L@l + addis r3, r0, CFG_DBAT0U@h + ori r3, r3, CFG_DBAT0U@l + mtspr DBAT0L, r4 + mtspr DBAT0U, r3 + isync + + /* IBAT 1 */ + addis r4, r0, CFG_IBAT1L@h + ori r4, r4, CFG_IBAT1L@l + addis r3, r0, CFG_IBAT1U@h + ori r3, r3, CFG_IBAT1U@l + mtspr IBAT1L, r4 + mtspr IBAT1U, r3 + isync + + /* DBAT 1 */ + addis r4, r0, CFG_DBAT1L@h + ori r4, r4, CFG_DBAT1L@l + addis r3, r0, CFG_DBAT1U@h + ori r3, r3, CFG_DBAT1U@l + mtspr DBAT1L, r4 + mtspr DBAT1U, r3 + isync + + /* IBAT 2 */ + addis r4, r0, CFG_IBAT2L@h + ori r4, r4, CFG_IBAT2L@l + addis r3, r0, CFG_IBAT2U@h + ori r3, r3, CFG_IBAT2U@l + mtspr IBAT2L, r4 + mtspr IBAT2U, r3 + isync + + /* DBAT 2 */ + addis r4, r0, CFG_DBAT2L@h + ori r4, r4, CFG_DBAT2L@l + addis r3, r0, CFG_DBAT2U@h + ori r3, r3, CFG_DBAT2U@l + mtspr DBAT2L, r4 + mtspr DBAT2U, r3 + isync + + /* IBAT 3 */ + addis r4, r0, CFG_IBAT3L@h + ori r4, r4, CFG_IBAT3L@l + addis r3, r0, CFG_IBAT3U@h + ori r3, r3, CFG_IBAT3U@l + mtspr IBAT3L, r4 + mtspr IBAT3U, r3 + isync + + /* DBAT 3 */ + addis r4, r0, CFG_DBAT3L@h + ori r4, r4, CFG_DBAT3L@l + addis r3, r0, CFG_DBAT3U@h + ori r3, r3, CFG_DBAT3U@l + mtspr DBAT3L, r4 + mtspr DBAT3U, r3 + isync + + /* IBAT 4 */ + addis r4, r0, CFG_IBAT4L@h + ori r4, r4, CFG_IBAT4L@l + addis r3, r0, CFG_IBAT4U@h + ori r3, r3, CFG_IBAT4U@l + mtspr IBAT4L, r4 + mtspr IBAT4U, r3 + isync + + /* DBAT 4 */ + addis r4, r0, CFG_DBAT4L@h + ori r4, r4, CFG_DBAT4L@l + addis r3, r0, CFG_DBAT4U@h + ori r3, r3, CFG_DBAT4U@l + mtspr DBAT4L, r4 + mtspr DBAT4U, r3 + isync + + /* IBAT 5 */ + addis r4, r0, CFG_IBAT5L@h + ori r4, r4, CFG_IBAT5L@l + addis r3, r0, CFG_IBAT5U@h + ori r3, r3, CFG_IBAT5U@l + mtspr IBAT5L, r4 + mtspr IBAT5U, r3 + isync + + /* DBAT 5 */ + addis r4, r0, CFG_DBAT5L@h + ori r4, r4, CFG_DBAT5L@l + addis r3, r0, CFG_DBAT5U@h + ori r3, r3, CFG_DBAT5U@l + mtspr DBAT5L, r4 + mtspr DBAT5U, r3 + isync + + /* IBAT 6 */ + addis r4, r0, CFG_IBAT6L@h + ori r4, r4, CFG_IBAT6L@l + addis r3, r0, CFG_IBAT6U@h + ori r3, r3, CFG_IBAT6U@l + mtspr IBAT6L, r4 + mtspr IBAT6U, r3 + isync + + /* DBAT 6 */ + addis r4, r0, CFG_DBAT6L@h + ori r4, r4, CFG_DBAT6L@l + addis r3, r0, CFG_DBAT6U@h + ori r3, r3, CFG_DBAT6U@l + mtspr DBAT6L, r4 + mtspr DBAT6U, r3 + isync + + /* IBAT 7 */ + addis r4, r0, CFG_IBAT7L@h + ori r4, r4, CFG_IBAT7L@l + addis r3, r0, CFG_IBAT7U@h + ori r3, r3, CFG_IBAT7U@l + mtspr IBAT7L, r4 + mtspr IBAT7U, r3 + isync + + /* DBAT 7 */ + addis r4, r0, CFG_DBAT7L@h + ori r4, r4, CFG_DBAT7L@l + addis r3, r0, CFG_DBAT7U@h + ori r3, r3, CFG_DBAT7U@l + mtspr DBAT7L, r4 + mtspr DBAT7U, r3 + isync + +1: + addis r3, 0, 0x0000 + addis r5, 0, 0x4 /* upper bound of 0x00040000 for 7400/750 */ + isync + +tlblp: + tlbie r3 + sync + addi r3, r3, 0x1000 + cmp 0, 0, r3, r5 + blt tlblp + + blr + + .globl enable_addr_trans +enable_addr_trans: + /* enable address translation */ + mfmsr r5 + ori r5, r5, (MSR_IR | MSR_DR) + mtmsr r5 + isync + blr + + .globl disable_addr_trans +disable_addr_trans: + /* disable address translation */ + mflr r4 + mfmsr r3 + andi. r0, r3, (MSR_IR | MSR_DR) + beqlr + andc r3, r3, r0 + mtspr SRR0, r4 + mtspr SRR1, r3 + rfi + +/* + * 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) + mtspr SPRG2,r22 /* r1 is now kernel sp */ + 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 + + .globl dc_read +dc_read: + blr + + .globl get_pvr +get_pvr: + mfspr r3, PVR + blr + + .globl get_svr +get_svr: + mfspr r3, SVR + blr + + +/*------------------------------------------------------------------------------- */ +/* Function: in8 */ +/* Description: Input 8 bits */ +/*------------------------------------------------------------------------------- */ + .globl in8 +in8: + lbz r3,0x0000(r3) + blr + +/*------------------------------------------------------------------------------- */ +/* Function: out8 */ +/* Description: Output 8 bits */ +/*------------------------------------------------------------------------------- */ + .globl out8 +out8: + stb r4,0x0000(r3) + blr + +/*------------------------------------------------------------------------------- */ +/* Function: out16 */ +/* Description: Output 16 bits */ +/*------------------------------------------------------------------------------- */ + .globl out16 +out16: + sth r4,0x0000(r3) + blr + +/*------------------------------------------------------------------------------- */ +/* Function: out16r */ +/* Description: Byte reverse and output 16 bits */ +/*------------------------------------------------------------------------------- */ + .globl out16r +out16r: + sthbrx r4,r0,r3 + blr + +/*------------------------------------------------------------------------------- */ +/* Function: out32 */ +/* Description: Output 32 bits */ +/*------------------------------------------------------------------------------- */ + .globl out32 +out32: + stw r4,0x0000(r3) + blr + +/*------------------------------------------------------------------------------- */ +/* Function: out32r */ +/* Description: Byte reverse and output 32 bits */ +/*------------------------------------------------------------------------------- */ + .globl out32r +out32r: + stwbrx r4,r0,r3 + blr + +/*------------------------------------------------------------------------------- */ +/* Function: in16 */ +/* Description: Input 16 bits */ +/*------------------------------------------------------------------------------- */ + .globl in16 +in16: + lhz r3,0x0000(r3) + blr + +/*------------------------------------------------------------------------------- */ +/* Function: in16r */ +/* Description: Input 16 bits and byte reverse */ +/*------------------------------------------------------------------------------- */ + .globl in16r +in16r: + lhbrx r3,r0,r3 + blr + +/*------------------------------------------------------------------------------- */ +/* Function: in32 */ +/* Description: Input 32 bits */ +/*------------------------------------------------------------------------------- */ + .globl in32 +in32: + lwz 3,0x0000(3) + blr + +/*------------------------------------------------------------------------------- */ +/* Function: in32r */ +/* Description: Input 32 bits and byte reverse */ +/*------------------------------------------------------------------------------- */ + .globl in32r +in32r: + lwbrx r3,r0,r3 + blr + +/*------------------------------------------------------------------------------- */ +/* Function: ppcDcbf */ +/* Description: Data Cache block flush */ +/* Input: r3 = effective address */ +/* Output: none. */ +/*------------------------------------------------------------------------------- */ + .globl ppcDcbf +ppcDcbf: + dcbf r0,r3 + blr + +/*------------------------------------------------------------------------------- */ +/* Function: ppcDcbi */ +/* Description: Data Cache block Invalidate */ +/* Input: r3 = effective address */ +/* Output: none. */ +/*------------------------------------------------------------------------------- */ + .globl ppcDcbi +ppcDcbi: + dcbi r0,r3 + blr + +/*-------------------------------------------------------------------------- + * Function: ppcDcbz + * Description: Data Cache block zero. + * Input: r3 = effective address + * Output: none. + *-------------------------------------------------------------------------- */ + + .globl ppcDcbz +ppcDcbz: + dcbz r0,r3 + blr + +/*-------------------------------------------------------------------------- */ +/* Function: ppcSync */ +/* Description: Processor Synchronize */ +/* Input: none. */ +/* Output: none. */ +/*-------------------------------------------------------------------------- */ + .globl ppcSync +ppcSync: + sync + 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 */ + + mr r3, r5 /* Destination Address */ + lis r4, CFG_MONITOR_BASE@h /* Source Address */ + ori r4, r4, CFG_MONITOR_BASE@l + lwz r5, GOT(__init_end) + sub r5, r5, r4 + li r6, CFG_CACHELINE_SIZE /* Cache Line Size */ + + /* + * Fix GOT pointer: + * + * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address + * + * Offset: + */ + sub r15, r10, r4 + + /* First our own GOT */ + add r14, r14, r15 + /* then the one used by the C code */ + add r30, r30, r15 + + /* + * Now relocate code + */ +#ifdef CONFIG_ECC + bl board_relocate_rom + sync + mr r3, r10 /* Destination Address */ + lis r4, CFG_MONITOR_BASE@h /* Source Address */ + ori r4, r4, CFG_MONITOR_BASE@l + lwz r5, GOT(__init_end) + sub r5, r5, r4 + li r6, CFG_CACHELINE_SIZE /* Cache Line Size */ +#else + 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 +#endif +/* + * 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 + 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 */ + 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: +#ifdef CONFIG_ECC + bl board_init_ecc +#endif + /* + * Relocation Function, r14 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) + add r0,r0,r11 + stw r0,0(r3) + bdnz 1b + + /* + * Now adjust the fixups and the pointers to the fixups + * in case we need to move ourselves again. + */ +2: li r0,__fixup_entries@sectoff@l + lwz r3,GOT(_FIXUP_TABLE_) + cmpwi r0,0 + mtctr r0 + addi r3,r3,-4 + beq 4f +3: lwzu r4,4(r3) + lwzux r0,r4,r11 + add r0,r0,r11 + stw r10,0(r3) + stw r0,0(r4) + bdnz 3b +4: +/* clear_bss: */ + /* + * Now clear BSS segment + */ + lwz r3,GOT(__bss_start) + lwz r4,GOT(_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, r10 /* Destination Address */ + bl after_reloc + + /* not reached - end relocate_code */ +/*-----------------------------------------------------------------------*/ + + /* + * Copy exception vector code to low memory + * + * r3: dest_addr + * r7: source address, r8: end address, r9: target address + */ + .globl trap_init +trap_init: + 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 */ + + mflr r4 /* save link register */ +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 + + /* enable execptions from RAM vectors */ + mfmsr r7 + li r8,MSR_IP + andc r7,r7,r8 + mtmsr r7 + + mtlr r4 /* restore link register */ + blr + + /* + * Function: relocate entries for one exception vector + */ +trap_reloc: + lwz r0, 0(r7) /* hdlr ... */ + add r0, r0, r3 /* ... += dest_addr */ + stw r0, 0(r7) + + lwz r0, 4(r7) /* int_return ... */ + add r0, r0, r3 /* ... += dest_addr */ + stw r0, 4(r7) + + sync + isync + + blr + +.globl enable_ext_addr +enable_ext_addr: + mfspr r0, HID0 + lis r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@h + ori r0, r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@l + mtspr HID0, r0 + sync + isync + blr + +#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR) +.globl setup_ccsrbar +setup_ccsrbar: + /* Special sequence needed to update CCSRBAR itself */ + lis r4, CFG_CCSRBAR_DEFAULT@h + ori r4, r4, CFG_CCSRBAR_DEFAULT@l + + lis r5, CFG_CCSRBAR@h + ori r5, r5, CFG_CCSRBAR@l + srwi r6,r5,12 + stw r6, 0(r4) + isync + + lis r5, 0xffff + ori r5,r5,0xf000 + lwz r5, 0(r5) + isync + + lis r3, CFG_CCSRBAR@h + lwz r5, CFG_CCSRBAR@l(r3) + isync + + blr +#endif + +#ifdef CFG_INIT_RAM_LOCK +lock_ram_in_cache: + /* Allocate Initial RAM in data cache. + */ + lis r3, (CFG_INIT_RAM_ADDR & ~31)@h + ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l + li r2, ((CFG_INIT_RAM_END & ~31) + \ + (CFG_INIT_RAM_ADDR & 31) + 31) / 32 + mtctr r2 +1: + dcbz r0, r3 + addi r3, r3, 32 + bdnz 1b +#if 1 +/* Lock the data cache */ + mfspr r0, HID0 + ori r0, r0, 0x1000 + sync + mtspr HID0, r0 + sync + blr +#endif +#if 0 + /* Lock the first way of the data cache */ + mfspr r0, LDSTCR + ori r0, r0, 0x0080 +#if defined(CONFIG_ALTIVEC) + dssall +#endif + sync + mtspr LDSTCR, r0 + sync + isync + blr +#endif + +.globl unlock_ram_in_cache +unlock_ram_in_cache: + /* invalidate the INIT_RAM section */ + lis r3, (CFG_INIT_RAM_ADDR & ~31)@h + ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l + li r2, ((CFG_INIT_RAM_END & ~31) + \ + (CFG_INIT_RAM_ADDR & 31) + 31) / 32 + mtctr r2 +1: icbi r0, r3 + addi r3, r3, 32 + bdnz 1b + sync /* Wait for all icbi to complete on bus */ + isync +#if 1 +/* Unlock the data cache and invalidate it */ + mfspr r0, HID0 + li r3,0x1000 + andc r0,r0,r3 + li r3,0x0400 + or r0,r0,r3 + sync + mtspr HID0, r0 + sync + blr +#endif +#if 0 + /* Unlock the first way of the data cache */ + mfspr r0, LDSTCR + li r3,0x0080 + andc r0,r0,r3 +#ifdef CONFIG_ALTIVEC + dssall +#endif + sync + mtspr LDSTCR, r0 + sync + isync + li r3,0x0400 + or r0,r0,r3 + sync + mtspr HID0, r0 + sync + blr +#endif +#endif + +/* If this is a multi-cpu system then we need to handle the + * 2nd cpu. The assumption is that the 2nd cpu is being + * held in boot holdoff mode until the 1st cpu unlocks it + * from Linux. We'll do some basic cpu init and then pass + * it to the Linux Reset Vector. + * Sri: Much of this initialization is not required. Linux + * rewrites the bats, and the sprs and also enables the L1 cache. + */ +#if (CONFIG_NUM_CPUS > 1) +.globl secondary_cpu_setup +secondary_cpu_setup: + /* Do only core setup on all cores except cpu0 */ + bl invalidate_bats + sync + bl enable_ext_addr + +#ifdef CFG_L2 + /* init the L2 cache */ + addis r3, r0, L2_INIT@h + ori r3, r3, L2_INIT@l + sync + mtspr l2cr, r3 +#ifdef CONFIG_ALTIVEC + dssall +#endif + /* invalidate the L2 cache */ + bl l2cache_invalidate + sync +#endif + + /* setup the bats */ + bl setup_bats + sync + /* enable address translation */ + bl enable_addr_trans + sync + + /* enable and invalidate the data cache */ + bl dcache_enable + sync + + /* enable and invalidate the instruction cache*/ + bl icache_enable + sync + + /* Set up MSR and HID0, HID1*/ + /* Enable interrupts */ +/* mfmsr r28 + li r4,0 + ori r4,r4,MSR_EE + or r28,r28,r4 + mtmsr r28 + */ + + /* TBEN in HID0 */ + mfspr r4, HID0 + oris r4, r4, 0x0400 + mtspr HID0, r4 + sync + isync + + /*SYNCBE|ABE in HID1*/ + mfspr r4, HID1 + ori r4, r4, 0x0C00 + mtspr HID1, r4 + sync + isync + + lis r3, CONFIG_LINUX_RESET_VEC@h + ori r3, r3, CONFIG_LINUX_RESET_VEC@l + mtlr r3 + blr + + /* Never Returns, Running in Linux Now */ +#endif + diff --git a/cpu/mpc86xx/traps.c b/cpu/mpc86xx/traps.c new file mode 100644 index 0000000000..8113dfbcc3 --- /dev/null +++ b/cpu/mpc86xx/traps.c @@ -0,0 +1,251 @@ +/* + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Modified by Cort Dougan (cort@cs.nmt.edu) + * and Paul Mackerras (paulus@cs.anu.edu.au) + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * This file handles the architecture-dependent parts of hardware exceptions + */ + +#include <common.h> +#include <command.h> +#include <asm/processor.h> + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +int (*debugger_exception_handler)(struct pt_regs *) = 0; +#endif + +/* Returns 0 if exception not found and fixup otherwise. */ +extern unsigned long search_exception_table(unsigned long); + +#define END_OF_MEM (gd->bd->bi_memstart + gd->bd->bi_memsize) + +/* + * Trap & Exception support + */ + +void +print_backtrace(unsigned long *sp) +{ + DECLARE_GLOBAL_DATA_PTR; + + int cnt = 0; + unsigned long i; + + printf("Call backtrace: "); + while (sp) { + if ((uint)sp > END_OF_MEM) + break; + + i = sp[1]; + if (cnt++ % 7 == 0) + printf("\n"); + printf("%08lX ", i); + if (cnt > 32) break; + sp = (unsigned long *)*sp; + } + printf("\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); + + printf("\n"); + for (i = 0; i < 32; i++) { + if ((i % 8) == 0) + { + printf("GPR%02d: ", i); + } + + printf("%08lX ", regs->gpr[i]); + if ((i % 8) == 7) + { + printf("\n"); + } + } +} + + +void +_exception(int signr, struct pt_regs *regs) +{ + show_regs(regs); + print_backtrace((unsigned long *)regs->gpr[1]); + panic("Exception in kernel pc %lx signal %d",regs->nip,signr); +} + +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. + */ + if ((fixup = search_exception_table(regs->nip)) != 0) { + regs->nip = fixup; + return; + } + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + return; +#endif + + printf("Machine check in kernel mode.\n"); + printf("Caused by (from msr): "); + printf("regs %p ",regs); + switch( regs->msr & 0x000F0000) { + case (0x80000000>>12): + printf("Machine check signal - probably due to mm fault\n" + "with mmu off\n"); + break; + case (0x80000000>>13): + printf("Transfer error ack signal\n"); + break; + case (0x80000000>>14): + printf("Data parity signal\n"); + break; + case (0x80000000>>15): + printf("Address parity signal\n"); + break; + default: + printf("Unknown values in msr\n"); + } + show_regs(regs); + print_backtrace((unsigned long *)regs->gpr[1]); + panic("machine check"); +} + +void +AlignmentException(struct pt_regs *regs) +{ +#if (CONFIG_COMMANDS & CFG_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) +{ + unsigned char *p = regs ? (unsigned char *)(regs->nip) : NULL; + int i, j; + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + return; +#endif + show_regs(regs); + + p = (unsigned char *) ((unsigned long)p & 0xFFFFFFE0); + p -= 32; + for (i = 0; i < 256; i+=16) { + printf("%08x: ", (unsigned int)p+i); + for (j = 0; j < 16; j++) { + printf("%02x ", p[i+j]); + } + printf("\n"); + } + + print_backtrace((unsigned long *)regs->gpr[1]); + panic("Program Check Exception"); +} + +void +SoftEmuException(struct pt_regs *regs) +{ +#if (CONFIG_COMMANDS & CFG_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 (CONFIG_COMMANDS & CFG_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); +} + +/* 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/drivers/tsec.c b/drivers/tsec.c index 7ec565ca67..18778c270a 100644 --- a/drivers/tsec.c +++ b/drivers/tsec.c @@ -14,6 +14,7 @@ #include <config.h> #include <mpc85xx.h> +#include <mpc86xx.h> #include <common.h> #include <malloc.h> #include <net.h> @@ -74,27 +75,33 @@ struct tsec_info_struct { static struct tsec_info_struct tsec_info[] = { #if defined(CONFIG_MPC85XX_TSEC1) || defined(CONFIG_MPC83XX_TSEC1) {TSEC1_PHY_ADDR, TSEC_GIGABIT, TSEC1_PHYIDX}, +#elif defined(CONFIG_MPC86XX_TSEC1) + {TSEC1_PHY_ADDR, TSEC_GIGABIT | TSEC_REDUCED, TSEC1_PHYIDX}, #else { 0, 0, 0}, #endif #if defined(CONFIG_MPC85XX_TSEC2) || defined(CONFIG_MPC83XX_TSEC2) {TSEC2_PHY_ADDR, TSEC_GIGABIT, TSEC2_PHYIDX}, +#elif defined(CONFIG_MPC86XX_TSEC2) + {TSEC2_PHY_ADDR, TSEC_GIGABIT | TSEC_REDUCED, TSEC2_PHYIDX}, #else { 0, 0, 0}, #endif #ifdef CONFIG_MPC85XX_FEC {FEC_PHY_ADDR, 0, FEC_PHYIDX}, #else -# if defined(CONFIG_MPC85XX_TSEC3) || defined(CONFIG_MPC83XX_TSEC3) +#if defined(CONFIG_MPC85XX_TSEC3) || defined(CONFIG_MPC83XX_TSEC3) || defined(CONFIG_MPC86XX_TSEC3) {TSEC3_PHY_ADDR, TSEC_GIGABIT | TSEC_REDUCED, TSEC3_PHYIDX}, -# else +#else { 0, 0, 0}, -# endif -# if defined(CONFIG_MPC85XX_TSEC4) || defined(CONFIG_MPC83XX_TSEC4) +#endif +#if defined(CONFIG_MPC85XX_TSEC4) || defined(CONFIG_MPC83XX_TSEC4) {TSEC4_PHY_ADDR, TSEC_REDUCED, TSEC4_PHYIDX}, -# else +#elif defined(CONFIG_MPC86XX_TSEC4) + {TSEC4_PHY_ADDR, TSEC_GIGABIT | TSEC_REDUCED, TSEC4_PHYIDX}, +#else { 0, 0, 0}, -# endif +#endif #endif }; @@ -467,6 +474,32 @@ uint mii_parse_cis8201(uint mii_reg, struct tsec_private *priv) return 0; } +/* Parse the vsc8244's status register for speed and duplex + * information */ +uint mii_parse_vsc8244(uint mii_reg, struct tsec_private *priv) +{ + uint speed; + + if(mii_reg & MIIM_VSC8244_AUXCONSTAT_DUPLEX) + priv->duplexity = 1; + else + priv->duplexity = 0; + + speed = mii_reg & MIIM_VSC8244_AUXCONSTAT_SPEED; + switch(speed) { + case MIIM_VSC8244_AUXCONSTAT_GBIT: + priv->speed = 1000; + break; + case MIIM_VSC8244_AUXCONSTAT_100: + priv->speed = 100; + break; + default: + priv->speed = 10; + break; + } + + return 0; +} /* Parse the DM9161's status register for speed and duplex @@ -859,6 +892,29 @@ struct phy_info phy_info_cis8201 = { {miim_end,} }, }; +struct phy_info phy_info_VSC8244 = { + 0x3f1b, + "Vitesse VSC8244", + 6, + (struct phy_cmd[]) { /* config */ + /* Override PHY config settings */ + /* Configure some basic stuff */ + {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, + {miim_end,} + }, + (struct phy_cmd[]) { /* startup */ + /* Read the Status (2x to make sure link is right) */ + {MIIM_STATUS, miim_read, NULL}, + /* Auto-negotiate */ + {MIIM_STATUS, miim_read, &mii_parse_sr}, + /* Read the status */ + {MIIM_VSC8244_AUX_CONSTAT, miim_read, &mii_parse_vsc8244}, + {miim_end,} + }, + (struct phy_cmd[]) { /* shutdown */ + {miim_end,} + }, +}; struct phy_info phy_info_dm9161 = { @@ -1001,6 +1057,7 @@ struct phy_info *phy_info[] = { &phy_info_M88E1111S, &phy_info_dm9161, &phy_info_lxt971, + &phy_info_VSC8244, &phy_info_dp83865, NULL }; diff --git a/drivers/tsec.h b/drivers/tsec.h index b55b2992b2..31f18675fb 100644 --- a/drivers/tsec.h +++ b/drivers/tsec.h @@ -27,7 +27,7 @@ #define TSEC_SIZE 0x01000 /* FIXME: Should these be pushed back to 83xx and 85xx config files? */ -#if defined(CONFIG_MPC85xx) +#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) #define TSEC_BASE_ADDR (CFG_IMMR + CFG_TSEC1_OFFSET) #elif defined(CONFIG_MPC83XX) #define TSEC_BASE_ADDR (CFG_IMMRBAR + CFG_TSEC1_OFFSET) @@ -133,6 +133,24 @@ #define MIIM_GBIT_CON 0x09 #define MIIM_GBIT_CON_ADVERT 0x0e00 +/* Entry for Vitesse VSC8244 regs starts here */ +/* Vitesse VSC8244 Auxiliary Control/Status Register */ +#define MIIM_VSC8244_AUX_CONSTAT 0x1c +#define MIIM_VSC8244_AUXCONSTAT_INIT 0x0000 +#define MIIM_VSC8244_AUXCONSTAT_DUPLEX 0x0020 +#define MIIM_VSC8244_AUXCONSTAT_SPEED 0x0018 +#define MIIM_VSC8244_AUXCONSTAT_GBIT 0x0010 +#define MIIM_VSC8244_AUXCONSTAT_100 0x0008 +#define MIIM_CONTROL_INIT_LOOPBACK 0x4000 + +/* Vitesse VSC8244 Extended PHY Control Register 1 */ +#define MIIM_VSC8244_EPHY_CON 0x17 +#define MIIM_VSC8244_EPHYCON_INIT 0x0006 + +/* Vitesse VSC8244 Serial LED Control Register */ +#define MIIM_VSC8244_LED_CON 0x1b +#define MIIM_VSC8244_LEDCON_INIT 0xF011 + /* 88E1011 PHY Status Register */ #define MIIM_88E1011_PHY_STATUS 0x11 #define MIIM_88E1011_PHYSTAT_SPEED 0xc000 diff --git a/include/asm-ppc/immap_86xx.h b/include/asm-ppc/immap_86xx.h new file mode 100644 index 0000000000..6bbe072b2d --- /dev/null +++ b/include/asm-ppc/immap_86xx.h @@ -0,0 +1,1362 @@ +/* + * MPC86xx Internal Memory Map + * + * Copyright(c) 2004 Freescale Semiconductor + * Jeff Brown (Jeffrey@freescale.com) + * Srikanth Srinivasan (srikanth.srinivasan@freescale.com) + * + */ + +#ifndef __IMMAP_86xx__ +#define __IMMAP_86xx__ + + +/* Local-Access Registers and MCM Registers(0x0000-0x2000) */ +typedef struct ccsr_local_mcm { + uint ccsrbar; /* 0x0 - Control Configuration Status Registers Base Address Register */ + char res1[4]; + uint altcbar; /* 0x8 - Alternate Configuration Base Address Register */ + char res2[4]; + uint altcar; /* 0x10 - Alternate Configuration Attribute Register */ + char res3[12]; + uint bptr; /* 0x20 - Boot Page Translation Register */ + char res4[3044]; + uint lawbar0; /* 0xc08 - Local Access Window 0 Base Address Register */ + char res5[4]; + uint lawar0; /* 0xc10 - Local Access Window 0 Attributes Register */ + char res6[20]; + uint lawbar1; /* 0xc28 - Local Access Window 1 Base Address Register */ + char res7[4]; + uint lawar1; /* 0xc30 - Local Access Window 1 Attributes Register */ + char res8[20]; + uint lawbar2; /* 0xc48 - Local Access Window 2 Base Address Register */ + char res9[4]; + uint lawar2; /* 0xc50 - Local Access Window 2 Attributes Register */ + char res10[20]; + uint lawbar3; /* 0xc68 - Local Access Window 3 Base Address Register */ + char res11[4]; + uint lawar3; /* 0xc70 - Local Access Window 3 Attributes Register */ + char res12[20]; + uint lawbar4; /* 0xc88 - Local Access Window 4 Base Address Register */ + char res13[4]; + uint lawar4; /* 0xc90 - Local Access Window 4 Attributes Register */ + char res14[20]; + uint lawbar5; /* 0xca8 - Local Access Window 5 Base Address Register */ + char res15[4]; + uint lawar5; /* 0xcb0 - Local Access Window 5 Attributes Register */ + char res16[20]; + uint lawbar6; /* 0xcc8 - Local Access Window 6 Base Address Register */ + char res17[4]; + uint lawar6; /* 0xcd0 - Local Access Window 6 Attributes Register */ + char res18[20]; + uint lawbar7; /* 0xce8 - Local Access Window 7 Base Address Register */ + char res19[4]; + uint lawar7; /* 0xcf0 - Local Access Window 7 Attributes Register */ + char res20[16]; + uint lawbar8; /* 0xd08 - Local Access Window 8 Base Address Register */ + char res21[4]; + uint lawar8; /* 0xd10 - Local Access Window 8 Attributes Register */ + char res22[20]; + uint lawbar9; /* 0xd28 - Local Access Window 9 Base Address Register */ + char res23[4]; + uint lawar9; /* 0xd30 - Local Access Window 9 Attributes Register */ + char res24[720]; + uint abcr; /* 0x1000 - MCM CCB Address Configuration Register */ + char res25[4]; + uint dbcr; /* 0x1008 - MCM MPX data bus Configuration Register */ + char res26[4]; + uint pcr; /* 0x1010 - MCM CCB Port Configuration Register */ + char res27[44]; + uint hpmr0; /* 0x1040 - MCM HPM Threshold Count Register 0 */ + uint hpmr1; /* 0x1044 - MCM HPM Threshold Count Register 1 */ + uint hpmr2; /* 0x1048 - MCM HPM Threshold Count Register 2 */ + uint hpmr3; /* 0x104c - MCM HPM Threshold Count Register 3 */ + char res28[16]; + uint hpmr4; /* 0x1060 - MCM HPM Threshold Count Register 4 */ + uint hpmr5; /* 0x1064 - MCM HPM Threshold Count Register 5 */ + uint hpmccr; /* 0x1068 - MCM HPM Cycle Count Register */ + char res29[3476]; + uint edr; /* 0x1e00 - MCM Error Detect Register */ + char res30[4]; + uint eer; /* 0x1e08 - MCM Error Enable Register */ + uint eatr; /* 0x1e0c - MCM Error Attributes Capture Register */ + uint eladr; /* 0x1e10 - MCM Error Low Address Capture Register */ + uint ehadr; /* 0x1e14 - MCM Error High Address Capture Register */ + char res31[488]; +} ccsr_local_mcm_t; + +/* DDR memory controller registers(0x2000-0x3000) and (0x6000-0x7000) */ + +typedef struct ccsr_ddr { + uint cs0_bnds; /* 0x2000 - DDR Chip Select 0 Memory Bounds */ + char res1[4]; + uint cs1_bnds; /* 0x2008 - DDR Chip Select 1 Memory Bounds */ + char res2[4]; + uint cs2_bnds; /* 0x2010 - DDR Chip Select 2 Memory Bounds */ + char res3[4]; + uint cs3_bnds; /* 0x2018 - DDR Chip Select 3 Memory Bounds */ + char res4[4]; + uint cs4_bnds; /* 0x2020 - DDR Chip Select 4 Memory Bounds */ + char res5[4]; + uint cs5_bnds; /* 0x2028 - DDR Chip Select 5 Memory Bounds */ + char res6[84]; + uint cs0_config; /* 0x2080 - DDR Chip Select Configuration */ + uint cs1_config; /* 0x2084 - DDR Chip Select Configuration */ + uint cs2_config; /* 0x2088 - DDR Chip Select Configuration */ + uint cs3_config; /* 0x208c - DDR Chip Select Configuration */ + uint cs4_config; /* 0x2090 - DDR Chip Select Configuration */ + uint cs5_config; /* 0x2094 - DDR Chip Select Configuration */ + char res7[104]; + uint ext_refrec; /* 0x2100 - DDR SDRAM extended refresh recovery */ + uint timing_cfg_0; /* 0x2104 - DDR SDRAM Timing Configuration Register 0 */ + uint timing_cfg_1; /* 0x2108 - DDR SDRAM Timing Configuration Register 1 */ + uint timing_cfg_2; /* 0x210c - DDR SDRAM Timing Configuration Register 2 */ + uint sdram_cfg_1; /* 0x2110 - DDR SDRAM Control Configuration 1 */ + uint sdram_cfg_2; /* 0x2114 - DDR SDRAM Control Configuration 2 */ + uint sdram_mode_1; /* 0x2118 - DDR SDRAM Mode Configuration 1 */ + uint sdram_mode_2; /* 0x211c - DDR SDRAM Mode Configuration 2 */ + uint sdram_mode_cntl; /* 0x2120 - DDR SDRAM Mode Control */ + uint sdram_interval; /* 0x2124 - DDR SDRAM Interval Configuration */ + uint sdram_data_init; /* 0x2128 - DDR SDRAM Data Initialization */ + char res8[4]; + uint sdram_clk_cntl; /* 0x2130 - DDR SDRAM Clock Control */ + char res9[12]; + uint sdram_ocd_cntl; /* 0x2140 - DDR SDRAM OCD Control */ + uint sdram_ocd_status; /* 0x2144 - DDR SDRAM OCD Status */ + uint init_addr; /* 0x2148 - DDR training initialzation address */ + uint init_addr_ext; /* 0x214C - DDR training initialzation extended address */ + char res10[2728]; + uint ip_rev1; /* 0x2BF8 - DDR IP Block Revision 1 */ + uint ip_rev2; /* 0x2BFC - DDR IP Block Revision 2 */ + char res11[512]; + uint data_err_inject_hi; /* 0x2e00 - DDR Memory Data Path Error Injection Mask High */ + uint data_err_inject_lo; /* 0x2e04 - DDR Memory Data Path Error Injection Mask Low */ + uint ecc_err_inject; /* 0x2e08 - DDR Memory Data Path Error Injection Mask ECC */ + char res12[20]; + uint capture_data_hi; /* 0x2e20 - DDR Memory Data Path Read Capture High */ + uint capture_data_lo; /* 0x2e24 - DDR Memory Data Path Read Capture Low */ + uint capture_ecc; /* 0x2e28 - DDR Memory Data Path Read Capture ECC */ + char res13[20]; + uint err_detect; /* 0x2e40 - DDR Memory Error Detect */ + uint err_disable; /* 0x2e44 - DDR Memory Error Disable */ + uint err_int_en; /* 0x2e48 - DDR Memory Error Interrupt Enable */ + uint capture_attributes; /* 0x2e4c - DDR Memory Error Attributes Capture */ + uint capture_address; /* 0x2e50 - DDR Memory Error Address Capture */ + uint capture_ext_address; /* 0x2e54 - DDR Memory Error Extended Address Capture */ + uint err_sbe; /* 0x2e58 - DDR Memory Single-Bit ECC Error Management */ + char res14[164]; + uint debug_1; /* 0x2f00 */ + uint debug_2; + uint debug_3; + uint debug_4; + uint debug_5; + char res15[236]; +} ccsr_ddr_t; + + +/* Daul I2C Registers(0x3000-0x4000) */ + +typedef struct ccsr_i2c { + u_char i2cadr1; /* 0x3000 - I2C 1 Address Register */ +#define MPC86xx_I2CADR_MASK 0xFE + char res1[3]; + u_char i2cfdr1; /* 0x3004 - I2C 1 Frequency Divider Register */ +#define MPC86xx_I2CFDR_MASK 0x3F + char res2[3]; + u_char i2ccr1; /* 0x3008 - I2C 1 Control Register */ +#define MPC86xx_I2CCR_MEN 0x80 +#define MPC86xx_I2CCR_MIEN 0x40 +#define MPC86xx_I2CCR_MSTA 0x20 +#define MPC86xx_I2CCR_MTX 0x10 +#define MPC86xx_I2CCR_TXAK 0x08 +#define MPC86xx_I2CCR_RSTA 0x04 +#define MPC86xx_I2CCR_BCST 0x01 + char res3[3]; + u_char i2csr1; /* 0x300c - I2C 1 Status Register */ +#define MPC86xx_I2CSR_MCF 0x80 +#define MPC86xx_I2CSR_MAAS 0x40 +#define MPC86xx_I2CSR_MBB 0x20 +#define MPC86xx_I2CSR_MAL 0x10 +#define MPC86xx_I2CSR_BCSTM 0x08 +#define MPC86xx_I2CSR_SRW 0x04 +#define MPC86xx_I2CSR_MIF 0x02 +#define MPC86xx_I2CSR_RXAK 0x01 + char res4[3]; + u_char i2cdr1; /* 0x3010 - I2C 1 Data Register */ +#define MPC86xx_I2CDR_DATA 0xFF + char res5[3]; + u_char i2cdfsrr1; /* 0x3014 - I2C 1 Digital Filtering Sampling Rate Register */ +#define MPC86xx_I2CDFSRR 0x3F + char res6[235]; + + u_char i2cadr2; /* 0x3100 - I2C 2 Address Register */ + char res7[3]; + u_char i2cfdr2; /* 0x3104 - I2C 2 Frequency Divider Register */ + char res8[3]; + u_char i2ccr2; /* 0x3108 - I2C 2 Control Register */ + char res9[3]; + u_char i2csr2; /* 0x310c - I2C 2 Status Register */ + char res10[3]; + u_char i2cdr2; /* 0x3110 - I2C 2 Data Register */ + char res11[3]; + u_char i2cdfsrr2; /* 0x3114 - I2C 2 Digital Filtering Sampling Rate Register */ + char res12[3819]; +} ccsr_i2c_t; + +/* DUART Registers(0x4000-0x5000) */ +typedef struct ccsr_duart { + char res1[1280]; + u_char urbr1_uthr1_udlb1;/* 0x4500 - URBR1, UTHR1, UDLB1 with the same address offset of 0x04500 */ + u_char uier1_udmb1; /* 0x4501 - UIER1, UDMB1 with the same address offset of 0x04501 */ + u_char uiir1_ufcr1_uafr1;/* 0x4502 - UIIR1, UFCR1, UAFR1 with the same address offset of 0x04502 */ + u_char ulcr1; /* 0x4503 - UART1 Line Control Register */ + u_char umcr1; /* 0x4504 - UART1 Modem Control Register */ + u_char ulsr1; /* 0x4505 - UART1 Line Status Register */ + u_char umsr1; /* 0x4506 - UART1 Modem Status Register */ + u_char uscr1; /* 0x4507 - UART1 Scratch Register */ + char res2[8]; + u_char udsr1; /* 0x4510 - UART1 DMA Status Register */ + char res3[239]; + u_char urbr2_uthr2_udlb2;/* 0x4600 - URBR2, UTHR2, UDLB2 with the same address offset of 0x04600 */ + u_char uier2_udmb2; /* 0x4601 - UIER2, UDMB2 with the same address offset of 0x04601 */ + u_char uiir2_ufcr2_uafr2;/* 0x4602 - UIIR2, UFCR2, UAFR2 with the same address offset of 0x04602 */ + u_char ulcr2; /* 0x4603 - UART2 Line Control Register */ + u_char umcr2; /* 0x4604 - UART2 Modem Control Register */ + u_char ulsr2; /* 0x4605 - UART2 Line Status Register */ + u_char umsr2; /* 0x4606 - UART2 Modem Status Register */ + u_char uscr2; /* 0x4607 - UART2 Scratch Register */ + char res4[8]; + u_char udsr2; /* 0x4610 - UART2 DMA Status Register */ + char res5[2543]; +} ccsr_duart_t; + + +/* Local Bus Controller Registers(0x5000-0x6000) */ +typedef struct ccsr_lbc { + uint br0; /* 0x5000 - LBC Base Register 0 */ + uint or0; /* 0x5004 - LBC Options Register 0 */ + uint br1; /* 0x5008 - LBC Base Register 1 */ + uint or1; /* 0x500c - LBC Options Register 1 */ + uint br2; /* 0x5010 - LBC Base Register 2 */ + uint or2; /* 0x5014 - LBC Options Register 2 */ + uint br3; /* 0x5018 - LBC Base Register 3 */ + uint or3; /* 0x501c - LBC Options Register 3 */ + uint br4; /* 0x5020 - LBC Base Register 4 */ + uint or4; /* 0x5024 - LBC Options Register 4 */ + uint br5; /* 0x5028 - LBC Base Register 5 */ + uint or5; /* 0x502c - LBC Options Register 5 */ + uint br6; /* 0x5030 - LBC Base Register 6 */ + uint or6; /* 0x5034 - LBC Options Register 6 */ + uint br7; /* 0x5038 - LBC Base Register 7 */ + uint or7; /* 0x503c - LBC Options Register 7 */ + char res1[40]; + uint mar; /* 0x5068 - LBC UPM Address Register */ + char res2[4]; + uint mamr; /* 0x5070 - LBC UPMA Mode Register */ + uint mbmr; /* 0x5074 - LBC UPMB Mode Register */ + uint mcmr; /* 0x5078 - LBC UPMC Mode Register */ + char res3[8]; + uint mrtpr; /* 0x5084 - LBC Memory Refresh Timer Prescaler Register */ + uint mdr; /* 0x5088 - LBC UPM Data Register */ + char res4[8]; + uint lsdmr; /* 0x5094 - LBC SDRAM Mode Register */ + char res5[8]; + uint lurt; /* 0x50a0 - LBC UPM Refresh Timer */ + uint lsrt; /* 0x50a4 - LBC SDRAM Refresh Timer */ + char res6[8]; + uint ltesr; /* 0x50b0 - LBC Transfer Error Status Register */ + uint ltedr; /* 0x50b4 - LBC Transfer Error Disable Register */ + uint lteir; /* 0x50b8 - LBC Transfer Error Interrupt Register */ + uint lteatr; /* 0x50bc - LBC Transfer Error Attributes Register */ + uint ltear; /* 0x50c0 - LBC Transfer Error Address Register */ + char res7[12]; + uint lbcr; /* 0x50d0 - LBC Configuration Register */ + uint lcrr; /* 0x50d4 - LBC Clock Ratio Register */ + char res8[3880]; +} ccsr_lbc_t; + +/* PCI Express Registers(0x8000-0x9000) and (0x9000-0xA000) */ +typedef struct ccsr_pex { + uint cfg_addr; /* 0x8000 - PEX Configuration Address Register */ + uint cfg_data; /* 0x8004 - PEX Configuration Data Register */ + char res1[4]; + uint out_comp_to; /* 0x800C - PEX Outbound Completion Timeout Register */ + char res2[16]; + uint pme_msg_det; /* 0x8020 - PEX PME & message detect register */ + uint pme_msg_int_en; /* 0x8024 - PEX PME & message interrupt enable register */ + uint pme_msg_dis; /* 0x802C - PEX PME & message disable register */ + char res3[4]; + uint pm_command; /* 0x8030 - PEX PM Command register */ + char res4[3016]; + uint block_rev1; /* 0x8bf8 - PEX Block Revision register 1 */ + uint block_rev2; /* 0x8bfc - PEX Block Revision register 2 */ + uint potar0; /* 0x8c00 - PEX Outbound Transaction Address Register 0 */ + uint potear0; /* 0x8c04 - PEX Outbound Translation Extended Address Register 0 */ + char res5[8]; + uint powar0; /* 0x8c10 - PEX Outbound Window Attributes Register 0 */ + char res6[12]; + uint potar1; /* 0x8c20 - PEX Outbound Transaction Address Register 1 */ + uint potear1; /* 0x8c24 - PEX Outbound Translation Extended Address Register 1 */ + uint powbar1; /* 0x8c28 - PEX Outbound Window Base Address Register 1 */ + char res7[4]; + uint powar1; /* 0x8c30 - PEX Outbound Window Attributes Register 1 */ + char res8[12]; + uint potar2; /* 0x8c40 - PEX Outbound Transaction Address Register 2 */ + uint potear2; /* 0x8c44 - PEX Outbound Translation Extended Address Register 2 */ + uint powbar2; /* 0x8c48 - PEX Outbound Window Base Address Register 2 */ + char res9[4]; + uint powar2; /* 0x8c50 - PEX Outbound Window Attributes Register 2 */ + char res10[12]; + uint potar3; /* 0x8c60 - PEX Outbound Transaction Address Register 3 */ + uint potear3; /* 0x8c64 - PEX Outbound Translation Extended Address Register 3 */ + uint powbar3; /* 0x8c68 - PEX Outbound Window Base Address Register 3 */ + char res11[4]; + uint powar3; /* 0x8c70 - PEX Outbound Window Attributes Register 3 */ + char res12[12]; + uint potar4; /* 0x8c80 - PEX Outbound Transaction Address Register 4 */ + uint potear4; /* 0x8c84 - PEX Outbound Translation Extended Address Register 4 */ + uint powbar4; /* 0x8c88 - PEX Outbound Window Base Address Register 4 */ + char res13[4]; + uint powar4; /* 0x8c90 - PEX Outbound Window Attributes Register 4 */ + char res14[268]; + uint pitar3; /* 0x8da0 - PEX Inbound Translation Address Register 3 */ + char res15[4]; + uint piwbar3; /* 0x8da8 - PEX Inbound Window Base Address Register 3 */ + uint piwbear3; /* 0x8dac - PEX Inbound Window Base Extended Address Register 3 */ + uint piwar3; /* 0x8db0 - PEX Inbound Window Attributes Register 3 */ + char res16[12]; + uint pitar2; /* 0x8dc0 - PEX Inbound Translation Address Register 2 */ + char res17[4]; + uint piwbar2; /* 0x8dc8 - PEX Inbound Window Base Address Register 2 */ + uint piwbear2; /* 0x8dcc - PEX Inbound Window Base Extended Address Register 2 */ + uint piwar2; /* 0x8dd0 - PEX Inbound Window Attributes Register 2 */ + char res18[12]; + uint pitar1; /* 0x8de0 - PEX Inbound Translation Address Register 1 */ + char res19[4]; + uint piwbar1; /* 0x8de8 - PEX Inbound Window Base Address Register 1 */ + char res20[4]; + uint piwar1; /* 0x8df0 - PEX Inbound Window Attributes Register 1 */ + char res21[12]; + uint pedr; /* 0x8e00 - PEX Error Detect Register */ + uint pecdr; /* 0x8e04 - PEX Error Capture Disable Register */ + uint peer; /* 0x8e08 - PEX Error Enable Register */ + uint perr_cap0; /* 0x8e0c - PEX Error Capture Register 0 */ + uint perr_cap1; /* 0x8e10 - PEX Error Capture Register 1 */ + uint perr_cap2; /* 0x8e14 - PEX Error Capture Register 2 */ + uint perr_cap3; /* 0x8e18 - PEX Error Capture Register 3 */ + char res22[100]; + uint perr_stat; /* 0x8e80 - PEX Error Status Register */ + char res23[124]; + uint pdebug; /* 0x8f00 - PEX Debug Register */ + char res24[248]; //Sri: changed this because of adding 4 bytes before 0x?8020. +} ccsr_pex_t; + +/* Hyper Transport Register Block (0xA000-0xB000) */ +typedef struct ccsr_ht { + uint hcfg_addr; /* 0xa000 - HT Configuration Address register */ + uint hcfg_data; /* 0xa004 - HT Configuration Data register */ + char res1[3064]; + uint howtar0; /* 0xac00 - HT Outbound Window 0 Translation register */ + char res2[12]; + uint howar0; /* 0xac10 - HT Outbound Window 0 Attributes register */ + char res3[12]; + uint howtar1; /* 0xac20 - HT Outbound Window 1 Translation register */ + char res4[4]; + uint howbar1; /* 0xac28 - HT Outbound Window 1 Base Address register */ + char res5[4]; + uint howar1; /* 0xac30 - HT Outbound Window 1 Attributes register */ + char res6[12]; + uint howtar2; /* 0xac40 - HT Outbound Window 2 Translation register */ + char res7[4]; + uint howbar2; /* 0xac48 - HT Outbound Window 2 Base Address register */ + char res8[4]; + uint howar2; /* 0xac50 - HT Outbound Window 2 Attributes register */ + char res9[12]; + uint howtar3; /* 0xac60 - HT Outbound Window 3 Translation register */ + char res10[4]; + uint howbar3; /* 0xac68 - HT Outbound Window 3 Base Address register */ + char res11[4]; + uint howar3; /* 0xac70 - HT Outbound Window 3 Attributes register */ + char res12[12]; + uint howtar4; /* 0xac80 - HT Outbound Window 4 Translation register */ + char res13[4]; + uint howbar4; /* 0xac88 - HT Outbound Window 4 Base Address register */ + char res14[4]; + uint howar4; /* 0xac90 - HT Outbound Window 4 Attributes register */ + char res15[236]; + uint hiwtar4; /* 0xad80 - HT Inbound Window 4 Translation register */ + char res16[4]; + uint hiwbar4; /* 0xad88 - HT Inbound Window 4 Base Address register */ + char res17[4]; + uint hiwar4; /* 0xad90 - HT Inbound Window 4 Attributes register */ + char res18[12]; + uint hiwtar3; /* 0xada0 - HT Inbound Window 3 Translation register */ + char res19[4]; + uint hiwbar3; /* 0xada8 - HT Inbound Window 3 Base Address register */ + char res20[4]; + uint hiwar3; /* 0xadb0 - HT Inbound Window 3 Attributes register */ + char res21[12]; + uint hiwtar2; /* 0xadc0 - HT Inbound Window 2 Translation register */ + char res22[4]; + uint hiwbar2; /* 0xadc8 - HT Inbound Window 2 Base Address register */ + char res23[4]; + uint hiwar2; /* 0xadd0 - HT Inbound Window 2 Attributes register */ + char res24[12]; + uint hiwtar1; /* 0xade0 - HT Inbound Window 1 Translation register */ + char res25[4]; + uint hiwbar1; /* 0xade8 - HT Inbound Window 1 Base Address register */ + char res26[4]; + uint hiwar1; /* 0xadf0 - HT Inbound Window 1 Attributes register */ + char res27[12]; + uint hedr; /* 0xae00 - HT Error Detect register */ + char res28[4]; + uint heier; /* 0xae08 - HT Error Interrupt Enable register */ + char res29[4]; + uint hecdr; /* 0xae10 - HT Error Capture Disbale register */ + char res30[12]; + uint hecsr; /* 0xae20 - HT Error Capture Status register */ + char res31[4]; + uint hec0; /* 0xae28 - HT Error Capture 0 register */ + uint hec1; /* 0xae2c - HT Error Capture 1 register */ + uint hec2; /* 0xae30 - HT Error Capture 2 register */ + char res32[460]; +} ccsr_ht_t; + +/* DMA Registers(0x2_1000-0x2_2000) */ +typedef struct ccsr_dma { + char res1[256]; + uint mr0; /* 0x21100 - DMA 0 Mode Register */ + uint sr0; /* 0x21104 - DMA 0 Status Register */ + char res2[4]; + uint clndar0; /* 0x2110c - DMA 0 Current Link Descriptor Address Register */ + uint satr0; /* 0x21110 - DMA 0 Source Attributes Register */ + uint sar0; /* 0x21114 - DMA 0 Source Address Register */ + uint datr0; /* 0x21118 - DMA 0 Destination Attributes Register */ + uint dar0; /* 0x2111c - DMA 0 Destination Address Register */ + uint bcr0; /* 0x21120 - DMA 0 Byte Count Register */ + char res3[4]; + uint nlndar0; /* 0x21128 - DMA 0 Next Link Descriptor Address Register */ + char res4[8]; + uint clabdar0; /* 0x21134 - DMA 0 Current List - Alternate Base Descriptor Address Register */ + char res5[4]; + uint nlsdar0; /* 0x2113c - DMA 0 Next List Descriptor Address Register */ + uint ssr0; /* 0x21140 - DMA 0 Source Stride Register */ + uint dsr0; /* 0x21144 - DMA 0 Destination Stride Register */ + char res6[56]; + uint mr1; /* 0x21180 - DMA 1 Mode Register */ + uint sr1; /* 0x21184 - DMA 1 Status Register */ + char res7[4]; + uint clndar1; /* 0x2118c - DMA 1 Current Link Descriptor Address Register */ + uint satr1; /* 0x21190 - DMA 1 Source Attributes Register */ + uint sar1; /* 0x21194 - DMA 1 Source Address Register */ + uint datr1; /* 0x21198 - DMA 1 Destination Attributes Register */ + uint dar1; /* 0x2119c - DMA 1 Destination Address Register */ + uint bcr1; /* 0x211a0 - DMA 1 Byte Count Register */ + char res8[4]; + uint nlndar1; /* 0x211a8 - DMA 1 Next Link Descriptor Address Register */ + char res9[8]; + uint clabdar1; /* 0x211b4 - DMA 1 Current List - Alternate Base Descriptor Address Register */ + char res10[4]; + uint nlsdar1; /* 0x211bc - DMA 1 Next List Descriptor Address Register */ + uint ssr1; /* 0x211c0 - DMA 1 Source Stride Register */ + uint dsr1; /* 0x211c4 - DMA 1 Destination Stride Register */ + char res11[56]; + uint mr2; /* 0x21200 - DMA 2 Mode Register */ + uint sr2; /* 0x21204 - DMA 2 Status Register */ + char res12[4]; + uint clndar2; /* 0x2120c - DMA 2 Current Link Descriptor Address Register */ + uint satr2; /* 0x21210 - DMA 2 Source Attributes Register */ + uint sar2; /* 0x21214 - DMA 2 Source Address Register */ + uint datr2; /* 0x21218 - DMA 2 Destination Attributes Register */ + uint dar2; /* 0x2121c - DMA 2 Destination Address Register */ + uint bcr2; /* 0x21220 - DMA 2 Byte Count Register */ + char res13[4]; + uint nlndar2; /* 0x21228 - DMA 2 Next Link Descriptor Address Register */ + char res14[8]; + uint clabdar2; /* 0x21234 - DMA 2 Current List - Alternate Base Descriptor Address Register */ + char res15[4]; + uint nlsdar2; /* 0x2123c - DMA 2 Next List Descriptor Address Register */ + uint ssr2; /* 0x21240 - DMA 2 Source Stride Register */ + uint dsr2; /* 0x21244 - DMA 2 Destination Stride Register */ + char res16[56]; + uint mr3; /* 0x21280 - DMA 3 Mode Register */ + uint sr3; /* 0x21284 - DMA 3 Status Register */ + char res17[4]; + uint clndar3; /* 0x2128c - DMA 3 Current Link Descriptor Address Register */ + uint satr3; /* 0x21290 - DMA 3 Source Attributes Register */ + uint sar3; /* 0x21294 - DMA 3 Source Address Register */ + uint datr3; /* 0x21298 - DMA 3 Destination Attributes Register */ + uint dar3; /* 0x2129c - DMA 3 Destination Address Register */ + uint bcr3; /* 0x212a0 - DMA 3 Byte Count Register */ + char res18[4]; + uint nlndar3; /* 0x212a8 - DMA 3 Next Link Descriptor Address Register */ + char res19[8]; + uint clabdar3; /* 0x212b4 - DMA 3 Current List - Alternate Base Descriptor Address Register */ + char res20[4]; + uint nlsdar3; /* 0x212bc - DMA 3 Next List Descriptor Address Register */ + uint ssr3; /* 0x212c0 - DMA 3 Source Stride Register */ + uint dsr3; /* 0x212c4 - DMA 3 Destination Stride Register */ + char res21[56]; + uint dgsr; /* 0x21300 - DMA General Status Register */ + char res22[3324]; +} ccsr_dma_t; + +/* tsec1-4: 24000-28000 */ +typedef struct ccsr_tsec { + uint id; /* 0x24000 - Controller ID Register */ + char res1[12]; + uint ievent; /* 0x24010 - Interrupt Event Register */ + uint imask; /* 0x24014 - Interrupt Mask Register */ + uint edis; /* 0x24018 - Error Disabled Register */ + char res2[4]; + uint ecntrl; /* 0x24020 - Ethernet Control Register */ + char res2_1[4]; + uint ptv; /* 0x24028 - Pause Time Value Register */ + uint dmactrl; /* 0x2402c - DMA Control Register */ + uint tbipa; /* 0x24030 - TBI PHY Address Register */ + char res3[88]; + uint fifo_tx_thr; /* 0x2408c - FIFO transmit threshold register */ + char res4[8]; + uint fifo_tx_starve; /* 0x24098 - FIFO transmit starve register */ + uint fifo_tx_starve_shutoff;/* 0x2409c - FIFO transmit starve shutoff register */ + char res4_1[4]; + uint fifo_rx_pause; /* 0x240a4 - FIFO receive pause threshold register */ + uint fifo_rx_alarm; /* 0x240a8 - FIFO receive alarm threshold register */ + char res5[84]; + uint tctrl; /* 0x24100 - Transmit Control Register */ + uint tstat; /* 0x24104 - Transmit Status Register */ + uint dfvlan; /* 0x24108 - Default VLAN control word */ + char res6[4]; + uint txic; /* 0x24110 - Transmit interrupt coalescing Register */ + uint tqueue; /* 0x24114 - Transmit Queue Control Register */ + char res7[40]; + uint tr03wt; /* 0x24140 - TxBD Rings 0-3 round-robin weightings */ + uint tw47wt; /* 0x24144 - TxBD Rings 4-7 round-robin weightings */ + char res8[52]; + uint tbdbph; /* 0x2417c - Transmit Data Buffer Pointer High Register */ + char res9[4]; + uint tbptr0; /* 0x24184 - Transmit Buffer Descriptor Pointer for Ring 0 */ + char res10[4]; + uint tbptr1; /* 0x2418C - Transmit Buffer Descriptor Pointer for Ring 1 */ + char res11[4]; + uint tbptr2; /* 0x24194 - Transmit Buffer Descriptor Pointer for Ring 2 */ + char res12[4]; + uint tbptr3; /* 0x2419C - Transmit Buffer Descriptor Pointer for Ring 3 */ + char res13[4]; + uint tbptr4; /* 0x241A4 - Transmit Buffer Descriptor Pointer for Ring 4 */ + char res14[4]; + uint tbptr5; /* 0x241AC - Transmit Buffer Descriptor Pointer for Ring 5 */ + char res15[4]; + uint tbptr6; /* 0x241B4 - Transmit Buffer Descriptor Pointer for Ring 6 */ + char res16[4]; + uint tbptr7; /* 0x241BC - Transmit Buffer Descriptor Pointer for Ring 7 */ + char res17[64]; + uint tbaseh; /* 0x24200 - Transmit Descriptor Base Address High Register */ + uint tbase0; /* 0x24204 - Transmit Descriptor Base Address Register of Ring 0 */ + char res18[4]; + uint tbase1; /* 0x2420C - Transmit Descriptor base address of Ring 1 */ + char res19[4]; + uint tbase2; /* 0x24214 - Transmit Descriptor base address of Ring 2 */ + char res20[4]; + uint tbase3; /* 0x2421C - Transmit Descriptor base address of Ring 3 */ + char res21[4]; + uint tbase4; /* 0x24224 - Transmit Descriptor base address of Ring 4 */ + char res22[4]; + uint tbase5; /* 0x2422C - Transmit Descriptor base address of Ring 5 */ + char res23[4]; + uint tbase6; /* 0x24234 - Transmit Descriptor base address of Ring 6 */ + char res24[4]; + uint tbase7; /* 0x2423C - Transmit Descriptor base address of Ring 7 */ + char res25[192]; + uint rctrl; /* 0x24300 - Receive Control Register */ + uint rstat; /* 0x24304 - Receive Status Register */ + char res26[8]; + uint rxic; /* 0x24310 - Receive Interrupt Coalecing Register */ + uint rqueue; /* 0x24314 - Receive queue control register */ + char res27[24]; + uint rbifx; /* 0x24330 - Receive bit field extract control Register */ + uint rqfar; /* 0x24334 - Receive queue filing table address Register */ + uint rqfcr; /* 0x24338 - Receive queue filing table control Register */ + uint rqfpr; /* 0x2433c - Receive queue filing table property Register */ + uint mrblr; /* 0x24340 - Maximum Receive Buffer Length Register */ + char res28[56]; + uint rbdbph; /* 0x2437C - Receive Data Buffer Pointer High */ + char res29[4]; + uint rbptr0; /* 0x24384 - Receive Buffer Descriptor Pointer for Ring 0 */ + char res30[4]; + uint rbptr1; /* 0x2438C - Receive Buffer Descriptor Pointer for Ring 1 */ + char res31[4]; + uint rbptr2; /* 0x24394 - Receive Buffer Descriptor Pointer for Ring 2 */ + char res32[4]; + uint rbptr3; /* 0x2439C - Receive Buffer Descriptor Pointer for Ring 3 */ + char res33[4]; + uint rbptr4; /* 0x243A4 - Receive Buffer Descriptor Pointer for Ring 4 */ + char res34[4]; + uint rbptr5; /* 0x243AC - Receive Buffer Descriptor Pointer for Ring 5 */ + char res35[4]; + uint rbptr6; /* 0x243B4 - Receive Buffer Descriptor Pointer for Ring 6 */ + char res36[4]; + uint rbptr7; /* 0x243BC - Receive Buffer Descriptor Pointer for Ring 7 */ + char res37[64]; + uint rbaseh; /* 0x24400 - Receive Descriptor Base Address High 0 */ + uint rbase0; /* 0x24404 - Receive Descriptor Base Address of Ring 0 */ + char res38[4]; + uint rbase1; /* 0x2440C - Receive Descriptor Base Address of Ring 1 */ + char res39[4]; + uint rbase2; /* 0x24414 - Receive Descriptor Base Address of Ring 2 */ + char res40[4]; + uint rbase3; /* 0x2441C - Receive Descriptor Base Address of Ring 3 */ + char res41[4]; + uint rbase4; /* 0x24424 - Receive Descriptor Base Address of Ring 4 */ + char res42[4]; + uint rbase5; /* 0x2442C - Receive Descriptor Base Address of Ring 5 */ + char res43[4]; + uint rbase6; /* 0x24434 - Receive Descriptor Base Address of Ring 6 */ + char res44[4]; + uint rbase7; /* 0x2443C - Receive Descriptor Base Address of Ring 7 */ + char res45[192]; + uint maccfg1; /* 0x24500 - MAC Configuration 1 Register */ + uint maccfg2; /* 0x24504 - MAC Configuration 2 Register */ + uint ipgifg; /* 0x24508 - Inter Packet Gap/Inter Frame Gap Register */ + uint hafdup; /* 0x2450c - Half Duplex Register */ + uint maxfrm; /* 0x24510 - Maximum Frame Length Register */ + char res46[12]; + uint miimcfg; /* 0x24520 - MII Management Configuration Register */ + uint miimcom; /* 0x24524 - MII Management Command Register */ + uint miimadd; /* 0x24528 - MII Management Address Register */ + uint miimcon; /* 0x2452c - MII Management Control Register */ + uint miimstat; /* 0x24530 - MII Management Status Register */ + uint miimind; /* 0x24534 - MII Management Indicator Register */ + uint ifctrl; /* 0x24538 - Interface Contrl Register */ + uint ifstat; /* 0x2453c - Interface Status Register */ + uint macstnaddr1; /* 0x24540 - Station Address Part 1 Register */ + uint macstnaddr2; /* 0x24544 - Station Address Part 2 Register */ + uint mac01addr1; /* 0x24548 - MAC exact match address 1, part 1 */ + uint mac01addr2; /* 0x2454C - MAC exact match address 1, part 2 */ + uint mac02addr1; /* 0x24550 - MAC exact match address 2, part 1 */ + uint mac02addr2; /* 0x24554 - MAC exact match address 2, part 2 */ + uint mac03addr1; /* 0x24558 - MAC exact match address 3, part 1 */ + uint mac03addr2; /* 0x2455C - MAC exact match address 3, part 2 */ + uint mac04addr1; /* 0x24560 - MAC exact match address 4, part 1 */ + uint mac04addr2; /* 0x24564 - MAC exact match address 4, part 2 */ + uint mac05addr1; /* 0x24568 - MAC exact match address 5, part 1 */ + uint mac05addr2; /* 0x2456C - MAC exact match address 5, part 2 */ + uint mac06addr1; /* 0x24570 - MAC exact match address 6, part 1 */ + uint mac06addr2; /* 0x24574 - MAC exact match address 6, part 2 */ + uint mac07addr1; /* 0x24578 - MAC exact match address 7, part 1 */ + uint mac07addr2; /* 0x2457C - MAC exact match address 7, part 2 */ + uint mac08addr1; /* 0x24580 - MAC exact match address 8, part 1 */ + uint mac08addr2; /* 0x24584 - MAC exact match address 8, part 2 */ + uint mac09addr1; /* 0x24588 - MAC exact match address 9, part 1 */ + uint mac09addr2; /* 0x2458C - MAC exact match address 9, part 2 */ + uint mac10addr1; /* 0x24590 - MAC exact match address 10, part 1 */ + uint mac10addr2; /* 0x24594 - MAC exact match address 10, part 2 */ + uint mac11addr1; /* 0x24598 - MAC exact match address 11, part 1 */ + uint mac11addr2; /* 0x2459C - MAC exact match address 11, part 2 */ + uint mac12addr1; /* 0x245A0 - MAC exact match address 12, part 1 */ + uint mac12addr2; /* 0x245A4 - MAC exact match address 12, part 2 */ + uint mac13addr1; /* 0x245A8 - MAC exact match address 13, part 1 */ + uint mac13addr2; /* 0x245AC - MAC exact match address 13, part 2 */ + uint mac14addr1; /* 0x245B0 - MAC exact match address 14, part 1 */ + uint mac14addr2; /* 0x245B4 - MAC exact match address 14, part 2 */ + uint mac15addr1; /* 0x245B8 - MAC exact match address 15, part 1 */ + uint mac15addr2; /* 0x245BC - MAC exact match address 15, part 2 */ + char res48[192]; + uint tr64; /* 0x24680 - Transmit and Receive 64-byte Frame Counter */ + uint tr127; /* 0x24684 - Transmit and Receive 65-127 byte Frame Counter */ + uint tr255; /* 0x24688 - Transmit and Receive 128-255 byte Frame Counter */ + uint tr511; /* 0x2468c - Transmit and Receive 256-511 byte Frame Counter */ + uint tr1k; /* 0x24690 - Transmit and Receive 512-1023 byte Frame Counter */ + uint trmax; /* 0x24694 - Transmit and Receive 1024-1518 byte Frame Counter */ + uint trmgv; /* 0x24698 - Transmit and Receive 1519-1522 byte Good VLAN Frame */ + uint rbyt; /* 0x2469c - Receive Byte Counter */ + uint rpkt; /* 0x246a0 - Receive Packet Counter */ + uint rfcs; /* 0x246a4 - Receive FCS Error Counter */ + uint rmca; /* 0x246a8 - Receive Multicast Packet Counter */ + uint rbca; /* 0x246ac - Receive Broadcast Packet Counter */ + uint rxcf; /* 0x246b0 - Receive Control Frame Packet Counter */ + uint rxpf; /* 0x246b4 - Receive Pause Frame Packet Counter */ + uint rxuo; /* 0x246b8 - Receive Unknown OP Code Counter */ + uint raln; /* 0x246bc - Receive Alignment Error Counter */ + uint rflr; /* 0x246c0 - Receive Frame Length Error Counter */ + uint rcde; /* 0x246c4 - Receive Code Error Counter */ + uint rcse; /* 0x246c8 - Receive Carrier Sense Error Counter */ + uint rund; /* 0x246cc - Receive Undersize Packet Counter */ + uint rovr; /* 0x246d0 - Receive Oversize Packet Counter */ + uint rfrg; /* 0x246d4 - Receive Fragments Counter */ + uint rjbr; /* 0x246d8 - Receive Jabber Counter */ + uint rdrp; /* 0x246dc - Receive Drop Counter */ + uint tbyt; /* 0x246e0 - Transmit Byte Counter Counter */ + uint tpkt; /* 0x246e4 - Transmit Packet Counter */ + uint tmca; /* 0x246e8 - Transmit Multicast Packet Counter */ + uint tbca; /* 0x246ec - Transmit Broadcast Packet Counter */ + uint txpf; /* 0x246f0 - Transmit Pause Control Frame Counter */ + uint tdfr; /* 0x246f4 - Transmit Deferral Packet Counter */ + uint tedf; /* 0x246f8 - Transmit Excessive Deferral Packet Counter */ + uint tscl; /* 0x246fc - Transmit Single Collision Packet Counter */ + uint tmcl; /* 0x24700 - Transmit Multiple Collision Packet Counter */ + uint tlcl; /* 0x24704 - Transmit Late Collision Packet Counter */ + uint txcl; /* 0x24708 - Transmit Excessive Collision Packet Counter */ + uint tncl; /* 0x2470c - Transmit Total Collision Counter */ + char res49[4]; + uint tdrp; /* 0x24714 - Transmit Drop Frame Counter */ + uint tjbr; /* 0x24718 - Transmit Jabber Frame Counter */ + uint tfcs; /* 0x2471c - Transmit FCS Error Counter */ + uint txcf; /* 0x24720 - Transmit Control Frame Counter */ + uint tovr; /* 0x24724 - Transmit Oversize Frame Counter */ + uint tund; /* 0x24728 - Transmit Undersize Frame Counter */ + uint tfrg; /* 0x2472c - Transmit Fragments Frame Counter */ + uint car1; /* 0x24730 - Carry Register One */ + uint car2; /* 0x24734 - Carry Register Two */ + uint cam1; /* 0x24738 - Carry Mask Register One */ + uint cam2; /* 0x2473c - Carry Mask Register Two */ + uint rrej; /* 0x24740 - Receive filer rejected packet counter */ + char res50[188]; + uint iaddr0; /* 0x24800 - Indivdual address register 0 */ + uint iaddr1; /* 0x24804 - Indivdual address register 1 */ + uint iaddr2; /* 0x24808 - Indivdual address register 2 */ + uint iaddr3; /* 0x2480c - Indivdual address register 3 */ + uint iaddr4; /* 0x24810 - Indivdual address register 4 */ + uint iaddr5; /* 0x24814 - Indivdual address register 5 */ + uint iaddr6; /* 0x24818 - Indivdual address register 6 */ + uint iaddr7; /* 0x2481c - Indivdual address register 7 */ + char res51[96]; + uint gaddr0; /* 0x24880 - Global address register 0 */ + uint gaddr1; /* 0x24884 - Global address register 1 */ + uint gaddr2; /* 0x24888 - Global address register 2 */ + uint gaddr3; /* 0x2488c - Global address register 3 */ + uint gaddr4; /* 0x24890 - Global address register 4 */ + uint gaddr5; /* 0x24894 - Global address register 5 */ + uint gaddr6; /* 0x24898 - Global address register 6 */ + uint gaddr7; /* 0x2489c - Global address register 7 */ + char res52[352]; + uint fifocfg; /* 0x24A00 - FIFO interface configuration register */ + char res53[500]; + uint attr; /* 0x24BF8 - DMA Attribute register */ + uint attreli; /* 0x24BFC - DMA Attribute extract length and index register */ + char res54[1024]; +} ccsr_tsec_t; + +/* PIC Registers(0x4_0000-0x6_1000) */ + +typedef struct ccsr_pic { + char res1[64]; + uint ipidr0; /* 0x40040 - Interprocessor Interrupt Dispatch Register 0 */ + char res2[12]; + uint ipidr1; /* 0x40050 - Interprocessor Interrupt Dispatch Register 1 */ + char res3[12]; + uint ipidr2; /* 0x40060 - Interprocessor Interrupt Dispatch Register 2 */ + char res4[12]; + uint ipidr3; /* 0x40070 - Interprocessor Interrupt Dispatch Register 3 */ + char res5[12]; + uint ctpr; /* 0x40080 - Current Task Priority Register */ + char res6[12]; + uint whoami; /* 0x40090 - Who Am I Register */ + char res7[12]; + uint iack; /* 0x400a0 - Interrupt Acknowledge Register */ + char res8[12]; + uint eoi; /* 0x400b0 - End Of Interrupt Register */ + char res9[3916]; + uint frr; /* 0x41000 - Feature Reporting Register */ + char res10[28]; + uint gcr; /* 0x41020 - Global Configuration Register */ + char res11[92]; + uint vir; /* 0x41080 - Vendor Identification Register */ + char res12[12]; + uint pir; /* 0x41090 - Processor Initialization Register */ + char res13[12]; + uint ipivpr0; /* 0x410a0 - IPI Vector/Priority Register 0 */ + char res14[12]; + uint ipivpr1; /* 0x410b0 - IPI Vector/Priority Register 1 */ + char res15[12]; + uint ipivpr2; /* 0x410c0 - IPI Vector/Priority Register 2 */ + char res16[12]; + uint ipivpr3; /* 0x410d0 - IPI Vector/Priority Register 3 */ + char res17[12]; + uint svr; /* 0x410e0 - Spurious Vector Register */ + char res18[12]; + uint tfrr; /* 0x410f0 - Timer Frequency Reporting Register */ + char res19[12]; + uint gtccr0; /* 0x41100 - Global Timer Current Count Register 0 */ + char res20[12]; + uint gtbcr0; /* 0x41110 - Global Timer Base Count Register 0 */ + char res21[12]; + uint gtvpr0; /* 0x41120 - Global Timer Vector/Priority Register 0 */ + char res22[12]; + uint gtdr0; /* 0x41130 - Global Timer Destination Register 0 */ + char res23[12]; + uint gtccr1; /* 0x41140 - Global Timer Current Count Register 1 */ + char res24[12]; + uint gtbcr1; /* 0x41150 - Global Timer Base Count Register 1 */ + char res25[12]; + uint gtvpr1; /* 0x41160 - Global Timer Vector/Priority Register 1 */ + char res26[12]; + uint gtdr1; /* 0x41170 - Global Timer Destination Register 1 */ + char res27[12]; + uint gtccr2; /* 0x41180 - Global Timer Current Count Register 2 */ + char res28[12]; + uint gtbcr2; /* 0x41190 - Global Timer Base Count Register 2 */ + char res29[12]; + uint gtvpr2; /* 0x411a0 - Global Timer Vector/Priority Register 2 */ + char res30[12]; + uint gtdr2; /* 0x411b0 - Global Timer Destination Register 2 */ + char res31[12]; + uint gtccr3; /* 0x411c0 - Global Timer Current Count Register 3 */ + char res32[12]; + uint gtbcr3; /* 0x411d0 - Global Timer Base Count Register 3 */ + char res33[12]; + uint gtvpr3; /* 0x411e0 - Global Timer Vector/Priority Register 3 */ + char res34[12]; + uint gtdr3; /* 0x411f0 - Global Timer Destination Register 3 */ + char res35[268]; + uint tcr; /* 0x41300 - Timer Control Register */ + char res36[12]; + uint irqsr0; /* 0x41310 - IRQ_OUT Summary Register 0 */ + char res37[12]; + uint irqsr1; /* 0x41320 - IRQ_OUT Summary Register 1 */ + char res38[12]; + uint cisr0; /* 0x41330 - Critical Interrupt Summary Register 0 */ + char res39[12]; + uint cisr1; /* 0x41340 - Critical Interrupt Summary Register 1 */ + char res40[12]; + uint pm0mr0; /* 0x41350 - Performance monitor 0 mask register 0 */ + char res41[12]; + uint pm0mr1; /* 0x41360 - Performance monitor 0 mask register 1 */ + char res42[12]; + uint pm1mr0; /* 0x41370 - Performance monitor 1 mask register 0 */ + char res43[12]; + uint pm1mr1; /* 0x41380 - Performance monitor 1 mask register 1 */ + char res44[12]; + uint pm2mr0; /* 0x41390 - Performance monitor 2 mask register 0 */ + char res45[12]; + uint pm2mr1; /* 0x413A0 - Performance monitor 2 mask register 1 */ + char res46[12]; + uint pm3mr0; /* 0x413B0 - Performance monitor 3 mask register 0 */ + char res47[12]; + uint pm3mr1; /* 0x413C0 - Performance monitor 3 mask register 1 */ + char res48[60]; + uint msgr0; /* 0x41400 - Message Register 0 */ + char res49[12]; + uint msgr1; /* 0x41410 - Message Register 1 */ + char res50[12]; + uint msgr2; /* 0x41420 - Message Register 2 */ + char res51[12]; + uint msgr3; /* 0x41430 - Message Register 3 */ + char res52[204]; + uint mer; /* 0x41500 - Message Enable Register */ + char res53[12]; + uint msr; /* 0x41510 - Message Status Register */ + char res54[60140]; + uint eivpr0; /* 0x50000 - External Interrupt Vector/Priority Register 0 */ + char res55[12]; + uint eidr0; /* 0x50010 - External Interrupt Destination Register 0 */ + char res56[12]; + uint eivpr1; /* 0x50020 - External Interrupt Vector/Priority Register 1 */ + char res57[12]; + uint eidr1; /* 0x50030 - External Interrupt Destination Register 1 */ + char res58[12]; + uint eivpr2; /* 0x50040 - External Interrupt Vector/Priority Register 2 */ + char res59[12]; + uint eidr2; /* 0x50050 - External Interrupt Destination Register 2 */ + char res60[12]; + uint eivpr3; /* 0x50060 - External Interrupt Vector/Priority Register 3 */ + char res61[12]; + uint eidr3; /* 0x50070 - External Interrupt Destination Register 3 */ + char res62[12]; + uint eivpr4; /* 0x50080 - External Interrupt Vector/Priority Register 4 */ + char res63[12]; + uint eidr4; /* 0x50090 - External Interrupt Destination Register 4 */ + char res64[12]; + uint eivpr5; /* 0x500a0 - External Interrupt Vector/Priority Register 5 */ + char res65[12]; + uint eidr5; /* 0x500b0 - External Interrupt Destination Register 5 */ + char res66[12]; + uint eivpr6; /* 0x500c0 - External Interrupt Vector/Priority Register 6 */ + char res67[12]; + uint eidr6; /* 0x500d0 - External Interrupt Destination Register 6 */ + char res68[12]; + uint eivpr7; /* 0x500e0 - External Interrupt Vector/Priority Register 7 */ + char res69[12]; + uint eidr7; /* 0x500f0 - External Interrupt Destination Register 7 */ + char res70[12]; + uint eivpr8; /* 0x50100 - External Interrupt Vector/Priority Register 8 */ + char res71[12]; + uint eidr8; /* 0x50110 - External Interrupt Destination Register 8 */ + char res72[12]; + uint eivpr9; /* 0x50120 - External Interrupt Vector/Priority Register 9 */ + char res73[12]; + uint eidr9; /* 0x50130 - External Interrupt Destination Register 9 */ + char res74[12]; + uint eivpr10; /* 0x50140 - External Interrupt Vector/Priority Register 10 */ + char res75[12]; + uint eidr10; /* 0x50150 - External Interrupt Destination Register 10 */ + char res76[12]; + uint eivpr11; /* 0x50160 - External Interrupt Vector/Priority Register 11 */ + char res77[12]; + uint eidr11; /* 0x50170 - External Interrupt Destination Register 11 */ + char res78[140]; + uint iivpr0; /* 0x50200 - Internal Interrupt Vector/Priority Register 0 */ + char res79[12]; + uint iidr0; /* 0x50210 - Internal Interrupt Destination Register 0 */ + char res80[12]; + uint iivpr1; /* 0x50220 - Internal Interrupt Vector/Priority Register 1 */ + char res81[12]; + uint iidr1; /* 0x50230 - Internal Interrupt Destination Register 1 */ + char res82[12]; + uint iivpr2; /* 0x50240 - Internal Interrupt Vector/Priority Register 2 */ + char res83[12]; + uint iidr2; /* 0x50250 - Internal Interrupt Destination Register 2 */ + char res84[12]; + uint iivpr3; /* 0x50260 - Internal Interrupt Vector/Priority Register 3 */ + char res85[12]; + uint iidr3; /* 0x50270 - Internal Interrupt Destination Register 3 */ + char res86[12]; + uint iivpr4; /* 0x50280 - Internal Interrupt Vector/Priority Register 4 */ + char res87[12]; + uint iidr4; /* 0x50290 - Internal Interrupt Destination Register 4 */ + char res88[12]; + uint iivpr5; /* 0x502a0 - Internal Interrupt Vector/Priority Register 5 */ + char res89[12]; + uint iidr5; /* 0x502b0 - Internal Interrupt Destination Register 5 */ + char res90[12]; + uint iivpr6; /* 0x502c0 - Internal Interrupt Vector/Priority Register 6 */ + char res91[12]; + uint iidr6; /* 0x502d0 - Internal Interrupt Destination Register 6 */ + char res92[12]; + uint iivpr7; /* 0x502e0 - Internal Interrupt Vector/Priority Register 7 */ + char res93[12]; + uint iidr7; /* 0x502f0 - Internal Interrupt Destination Register 7 */ + char res94[12]; + uint iivpr8; /* 0x50300 - Internal Interrupt Vector/Priority Register 8 */ + char res95[12]; + uint iidr8; /* 0x50310 - Internal Interrupt Destination Register 8 */ + char res96[12]; + uint iivpr9; /* 0x50320 - Internal Interrupt Vector/Priority Register 9 */ + char res97[12]; + uint iidr9; /* 0x50330 - Internal Interrupt Destination Register 9 */ + char res98[12]; + uint iivpr10; /* 0x50340 - Internal Interrupt Vector/Priority Register 10 */ + char res99[12]; + uint iidr10; /* 0x50350 - Internal Interrupt Destination Register 10 */ + char res100[12]; + uint iivpr11; /* 0x50360 - Internal Interrupt Vector/Priority Register 11 */ + char res101[12]; + uint iidr11; /* 0x50370 - Internal Interrupt Destination Register 11 */ + char res102[12]; + uint iivpr12; /* 0x50380 - Internal Interrupt Vector/Priority Register 12 */ + char res103[12]; + uint iidr12; /* 0x50390 - Internal Interrupt Destination Register 12 */ + char res104[12]; + uint iivpr13; /* 0x503a0 - Internal Interrupt Vector/Priority Register 13 */ + char res105[12]; + uint iidr13; /* 0x503b0 - Internal Interrupt Destination Register 13 */ + char res106[12]; + uint iivpr14; /* 0x503c0 - Internal Interrupt Vector/Priority Register 14 */ + char res107[12]; + uint iidr14; /* 0x503d0 - Internal Interrupt Destination Register 14 */ + char res108[12]; + uint iivpr15; /* 0x503e0 - Internal Interrupt Vector/Priority Register 15 */ + char res109[12]; + uint iidr15; /* 0x503f0 - Internal Interrupt Destination Register 15 */ + char res110[12]; + uint iivpr16; /* 0x50400 - Internal Interrupt Vector/Priority Register 16 */ + char res111[12]; + uint iidr16; /* 0x50410 - Internal Interrupt Destination Register 16 */ + char res112[12]; + uint iivpr17; /* 0x50420 - Internal Interrupt Vector/Priority Register 17 */ + char res113[12]; + uint iidr17; /* 0x50430 - Internal Interrupt Destination Register 17 */ + char res114[12]; + uint iivpr18; /* 0x50440 - Internal Interrupt Vector/Priority Register 18 */ + char res115[12]; + uint iidr18; /* 0x50450 - Internal Interrupt Destination Register 18 */ + char res116[12]; + uint iivpr19; /* 0x50460 - Internal Interrupt Vector/Priority Register 19 */ + char res117[12]; + uint iidr19; /* 0x50470 - Internal Interrupt Destination Register 19 */ + char res118[12]; + uint iivpr20; /* 0x50480 - Internal Interrupt Vector/Priority Register 20 */ + char res119[12]; + uint iidr20; /* 0x50490 - Internal Interrupt Destination Register 20 */ + char res120[12]; + uint iivpr21; /* 0x504a0 - Internal Interrupt Vector/Priority Register 21 */ + char res121[12]; + uint iidr21; /* 0x504b0 - Internal Interrupt Destination Register 21 */ + char res122[12]; + uint iivpr22; /* 0x504c0 - Internal Interrupt Vector/Priority Register 22 */ + char res123[12]; + uint iidr22; /* 0x504d0 - Internal Interrupt Destination Register 22 */ + char res124[12]; + uint iivpr23; /* 0x504e0 - Internal Interrupt Vector/Priority Register 23 */ + char res125[12]; + uint iidr23; /* 0x504f0 - Internal Interrupt Destination Register 23 */ + char res126[12]; + uint iivpr24; /* 0x50500 - Internal Interrupt Vector/Priority Register 24 */ + char res127[12]; + uint iidr24; /* 0x50510 - Internal Interrupt Destination Register 24 */ + char res128[12]; + uint iivpr25; /* 0x50520 - Internal Interrupt Vector/Priority Register 25 */ + char res129[12]; + uint iidr25; /* 0x50530 - Internal Interrupt Destination Register 25 */ + char res130[12]; + uint iivpr26; /* 0x50540 - Internal Interrupt Vector/Priority Register 26 */ + char res131[12]; + uint iidr26; /* 0x50550 - Internal Interrupt Destination Register 26 */ + char res132[12]; + uint iivpr27; /* 0x50560 - Internal Interrupt Vector/Priority Register 27 */ + char res133[12]; + uint iidr27; /* 0x50570 - Internal Interrupt Destination Register 27 */ + char res134[12]; + uint iivpr28; /* 0x50580 - Internal Interrupt Vector/Priority Register 28 */ + char res135[12]; + uint iidr28; /* 0x50590 - Internal Interrupt Destination Register 28 */ + char res136[12]; + uint iivpr29; /* 0x505a0 - Internal Interrupt Vector/Priority Register 29 */ + char res137[12]; + uint iidr29; /* 0x505b0 - Internal Interrupt Destination Register 29 */ + char res138[12]; + uint iivpr30; /* 0x505c0 - Internal Interrupt Vector/Priority Register 30 */ + char res139[12]; + uint iidr30; /* 0x505d0 - Internal Interrupt Destination Register 30 */ + char res140[12]; + uint iivpr31; /* 0x505e0 - Internal Interrupt Vector/Priority Register 31 */ + char res141[12]; + uint iidr31; /* 0x505f0 - Internal Interrupt Destination Register 31 */ + char res142[4108]; + uint mivpr0; /* 0x51600 - Messaging Interrupt Vector/Priority Register 0 */ + char res143[12]; + uint midr0; /* 0x51610 - Messaging Interrupt Destination Register 0 */ + char res144[12]; + uint mivpr1; /* 0x51620 - Messaging Interrupt Vector/Priority Register 1 */ + char res145[12]; + uint midr1; /* 0x51630 - Messaging Interrupt Destination Register 1 */ + char res146[12]; + uint mivpr2; /* 0x51640 - Messaging Interrupt Vector/Priority Register 2 */ + char res147[12]; + uint midr2; /* 0x51650 - Messaging Interrupt Destination Register 2 */ + char res148[12]; + uint mivpr3; /* 0x51660 - Messaging Interrupt Vector/Priority Register 3 */ + char res149[12]; + uint midr3; /* 0x51670 - Messaging Interrupt Destination Register 3 */ + char res150[59852]; + uint ipi0dr0; /* 0x60040 - Processor 0 Interprocessor Interrupt Dispatch Register 0 */ + char res151[12]; + uint ipi0dr1; /* 0x60050 - Processor 0 Interprocessor Interrupt Dispatch Register 1 */ + char res152[12]; + uint ipi0dr2; /* 0x60060 - Processor 0 Interprocessor Interrupt Dispatch Register 2 */ + char res153[12]; + uint ipi0dr3; /* 0x60070 - Processor 0 Interprocessor Interrupt Dispatch Register 3 */ + char res154[12]; + uint ctpr0; /* 0x60080 - Current Task Priority Register for Processor 0 */ + char res155[12]; + uint whoami0; /* 0x60090 - Who Am I Register for Processor 0 */ + char res156[12]; + uint iack0; /* 0x600a0 - Interrupt Acknowledge Register for Processor 0 */ + char res157[12]; + uint eoi0; /* 0x600b0 - End Of Interrupt Register for Processor 0 */ + char res158[3916]; +} ccsr_pic_t; + +/* RapidIO Registers(0xc_0000-0xe_0000) */ + +typedef struct ccsr_rio { + uint didcar; /* 0xc0000 - Device Identity Capability Register */ + uint dicar; /* 0xc0004 - Device Information Capability Register */ + uint aidcar; /* 0xc0008 - Assembly Identity Capability Register */ + uint aicar; /* 0xc000c - Assembly Information Capability Register */ + uint pefcar; /* 0xc0010 - Processing Element Features Capability Register */ + uint spicar; /* 0xc0014 - Switch Port Information Capability Register */ + uint socar; /* 0xc0018 - Source Operations Capability Register */ + uint docar; /* 0xc001c - Destination Operations Capability Register */ + char res1[32]; + uint msr; /* 0xc0040 - Mailbox Command And Status Register */ + uint pwdcsr; /* 0xc0044 - Port-Write and Doorbell Command And Status Register */ + char res2[4]; + uint pellccsr; /* 0xc004c - Processing Element Logic Layer Control Command and Status Register */ + char res3[12]; + uint lcsbacsr; /* 0xc005c - Local Configuration Space Base Address Command and Status Register */ + uint bdidcsr; /* 0xc0060 - Base Device ID Command and Status Register */ + char res4[4]; + uint hbdidlcsr; /* 0xc0068 - Host Base Device ID Lock Command and Status Register */ + uint ctcsr; /* 0xc006c - Component Tag Command and Status Register */ + char res5[144]; + uint pmbh0csr; /* 0xc0100 - 8/16 LP-LVDS Port Maintenance Block Header 0 Command and Status Register */ + char res6[28]; + uint pltoccsr; /* 0xc0120 - Port Link Time-out Control Command and Status Register */ + uint prtoccsr; /* 0xc0124 - Port Response Time-out Control Command and Status Register */ + char res7[20]; + uint pgccsr; /* 0xc013c - Port General Command and Status Register */ + uint plmreqcsr; /* 0xc0140 - Port Link Maintenance Request Command and Status Register */ + uint plmrespcsr; /* 0xc0144 - Port Link Maintenance Response Command and Status Register */ + uint plascsr; /* 0xc0148 - Port Local Ackid Status Command and Status Register */ + char res8[12]; + uint pescsr; /* 0xc0158 - Port Error and Status Command and Status Register */ + uint pccsr; /* 0xc015c - Port Control Command and Status Register */ + char res9[1184]; + uint erbh; /* 0xc0600 - Error Reporting Block Header Register */ + char res10[4]; + uint ltledcsr; /* 0xc0608 - Logical/Transport layer error detect status register */ + uint ltleecsr; /* 0xc060c - Logical/Transport layer error enable register */ + char res11[4]; + uint ltlaccsr; /* 0xc0614 - Logical/Transport layer addresss capture register */ + uint ltldidccsr; /* 0xc0618 - Logical/Transport layer device ID capture register */ + uint ltlcccsr; /* 0xc061c - Logical/Transport layer control capture register */ + char res12[32]; + uint edcsr; /* 0xc0640 - Port 0 error detect status register */ + uint erecsr; /* 0xc0644 - Port 0 error rate enable status register */ + uint ecacsr; /* 0xc0648 - Port 0 error capture attributes register */ + uint pcseccsr0; /* 0xc064c - Port 0 packet/control symbol error capture register 0 */ + uint peccsr1; /* 0xc0650 - Port 0 error capture command and status register 1 */ + uint peccsr2; /* 0xc0654 - Port 0 error capture command and status register 2 */ + uint peccsr3; /* 0xc0658 - Port 0 error capture command and status register 3 */ + char res13[12]; + uint ercsr; /* 0xc0668 - Port 0 error rate command and status register */ + uint ertcsr; /* 0xc066C - Port 0 error rate threshold status register*/ + char res14[63892]; + uint llcr; /* 0xd0004 - Logical Layer Configuration Register */ + char res15[12]; + uint epwisr; /* 0xd0010 - Error / Port-Write Interrupt Status Register */ + char res16[12]; + uint lretcr; /* 0xd0020 - Logical Retry Error Threshold Configuration Register */ + char res17[92]; + uint pretcr; /* 0xd0080 - Physical Retry Erorr Threshold Configuration Register */ + char res18[124]; + uint adidcsr; /* 0xd0100 - Port 0 Alt. Device ID Command and Status Register */ + char res19[28]; + uint ptaacr; /* 0xd0120 - Port 0 Pass-Through/Accept-All Configuration Register */ + char res20[12]; + uint iecsr; /* 0xd0130 - Port 0 Implementation Error Status Register */ + char res21[12]; + uint pcr; /* 0xd0140 - Port 0 Phsyical Configuration RegisterRegister */ + char res22[20]; + uint slcsr; /* 0xd0158 - Port 0 Serial Link Command and Status Register */ + char res23[4]; + uint sleir; /* 0xd0160 - Port 0 Serial Link Error Injection Register */ + char res24[2716]; + uint rowtar0; /* 0xd0c00 - RapidIO Outbound Window Translation Address Register 0 */ + uint rowtear0; /* 0xd0c04 - RapidIO Outbound Window Translation Ext. Address Register 0 */ + char res25[8]; + uint rowar0; /* 0xd0c10 - RapidIO Outbound Attributes Register 0 */ + char res26[12]; + uint rowtar1; /* 0xd0c20 - RapidIO Outbound Window Translation Address Register 1 */ + uint rowtear1; /* 0xd0c24 - RapidIO Outbound Window Translation Ext. Address Register 1 */ + uint rowbar1; /* 0xd0c28 - RapidIO Outbound Window Base Address Register 1 */ + char res27[4]; + uint rowar1; /* 0xd0c30 - RapidIO Outbound Attributes Register 1 */ + uint rows1r1; /* 0xd0c34 - RapidIO Outbound Window Segment 1 Register 1 */ + uint rows2r1; /* 0xd0c38 - RapidIO Outbound Window Segment 2 Register 1 */ + uint rows3r1; /* 0xd0c3c - RapidIO Outbound Window Segment 3 Register 1 */ + uint rowtar2; /* 0xd0c40 - RapidIO Outbound Window Translation Address Register 2 */ + uint rowtear2; /* 0xd0c44 - RapidIO Outbound Window Translation Ext. Address Register 2 */ + uint rowbar2; /* 0xd0c48 - RapidIO Outbound Window Base Address Register 2 */ + char res28[4]; + uint rowar2; /* 0xd0c50 - RapidIO Outbound Attributes Register 2 */ + uint rows1r2; /* 0xd0c54 - RapidIO Outbound Window Segment 1 Register 2 */ + uint rows2r2; /* 0xd0c58 - RapidIO Outbound Window Segment 2 Register 2 */ + uint rows3r2; /* 0xd0c5c - RapidIO Outbound Window Segment 3 Register 2 */ + uint rowtar3; /* 0xd0c60 - RapidIO Outbound Window Translation Address Register 3 */ + uint rowtear3; /* 0xd0c64 - RapidIO Outbound Window Translation Ext. Address Register 3 */ + uint rowbar3; /* 0xd0c68 - RapidIO Outbound Window Base Address Register 3 */ + char res29[4]; + uint rowar3; /* 0xd0c70 - RapidIO Outbound Attributes Register 3 */ + uint rows1r3; /* 0xd0c74 - RapidIO Outbound Window Segment 1 Register 3 */ + uint rows2r3; /* 0xd0c78 - RapidIO Outbound Window Segment 2 Register 3 */ + uint rows3r3; /* 0xd0c7c - RapidIO Outbound Window Segment 3 Register 3 */ + uint rowtar4; /* 0xd0c80 - RapidIO Outbound Window Translation Address Register 4 */ + uint rowtear4; /* 0xd0c84 - RapidIO Outbound Window Translation Ext. Address Register 4 */ + uint rowbar4; /* 0xd0c88 - RapidIO Outbound Window Base Address Register 4 */ + char res30[4]; + uint rowar4; /* 0xd0c90 - RapidIO Outbound Attributes Register 4 */ + uint rows1r4; /* 0xd0c94 - RapidIO Outbound Window Segment 1 Register 4 */ + uint rows2r4; /* 0xd0c98 - RapidIO Outbound Window Segment 2 Register 4 */ + uint rows3r4; /* 0xd0c9c - RapidIO Outbound Window Segment 3 Register 4 */ + uint rowtar5; /* 0xd0ca0 - RapidIO Outbound Window Translation Address Register 5 */ + uint rowtear5; /* 0xd0ca4 - RapidIO Outbound Window Translation Ext. Address Register 5 */ + uint rowbar5; /* 0xd0ca8 - RapidIO Outbound Window Base Address Register 5 */ + char res31[4]; + uint rowar5; /* 0xd0cb0 - RapidIO Outbound Attributes Register 5 */ + uint rows1r5; /* 0xd0cb4 - RapidIO Outbound Window Segment 1 Register 5 */ + uint rows2r5; /* 0xd0cb8 - RapidIO Outbound Window Segment 2 Register 5 */ + uint rows3r5; /* 0xd0cbc - RapidIO Outbound Window Segment 3 Register 5 */ + uint rowtar6; /* 0xd0cc0 - RapidIO Outbound Window Translation Address Register 6 */ + uint rowtear6; /* 0xd0cc4 - RapidIO Outbound Window Translation Ext. Address Register 6 */ + uint rowbar6; /* 0xd0cc8 - RapidIO Outbound Window Base Address Register 6 */ + char res32[4]; + uint rowar6; /* 0xd0cd0 - RapidIO Outbound Attributes Register 6 */ + uint rows1r6; /* 0xd0cd4 - RapidIO Outbound Window Segment 1 Register 6 */ + uint rows2r6; /* 0xd0cd8 - RapidIO Outbound Window Segment 2 Register 6 */ + uint rows3r6; /* 0xd0cdc - RapidIO Outbound Window Segment 3 Register 6 */ + uint rowtar7; /* 0xd0ce0 - RapidIO Outbound Window Translation Address Register 7 */ + uint rowtear7; /* 0xd0ce4 - RapidIO Outbound Window Translation Ext. Address Register 7 */ + uint rowbar7; /* 0xd0ce8 - RapidIO Outbound Window Base Address Register 7 */ + char res33[4]; + uint rowar7; /* 0xd0cf0 - RapidIO Outbound Attributes Register 7 */ + uint rows1r7; /* 0xd0cf4 - RapidIO Outbound Window Segment 1 Register 7 */ + uint rows2r7; /* 0xd0cf8 - RapidIO Outbound Window Segment 2 Register 7 */ + uint rows3r7; /* 0xd0cfc - RapidIO Outbound Window Segment 3 Register 7 */ + uint rowtar8; /* 0xd0d00 - RapidIO Outbound Window Translation Address Register 8 */ + uint rowtear8; /* 0xd0d04 - RapidIO Outbound Window Translation Ext. Address Register 8 */ + uint rowbar8; /* 0xd0d08 - RapidIO Outbound Window Base Address Register 8 */ + char res34[4]; + uint rowar8; /* 0xd0d10 - RapidIO Outbound Attributes Register 8 */ + uint rows1r8; /* 0xd0d14 - RapidIO Outbound Window Segment 1 Register 8 */ + uint rows2r8; /* 0xd0d18 - RapidIO Outbound Window Segment 2 Register 8 */ + uint rows3r8; /* 0xd0d1c - RapidIO Outbound Window Segment 3 Register 8 */ + char res35[64]; + uint riwtar4; /* 0xd0d60 - RapidIO Inbound Window Translation Address Register 4 */ + uint riwbar4; /* 0xd0d68 - RapidIO Inbound Window Base Address Register 4 */ + char res36[4]; + uint riwar4; /* 0xd0d70 - RapidIO Inbound Attributes Register 4 */ + char res37[12]; + uint riwtar3; /* 0xd0d80 - RapidIO Inbound Window Translation Address Register 3 */ + char res38[4]; + uint riwbar3; /* 0xd0d88 - RapidIO Inbound Window Base Address Register 3 */ + char res39[4]; + uint riwar3; /* 0xd0d90 - RapidIO Inbound Attributes Register 3 */ + char res40[12]; + uint riwtar2; /* 0xd0da0 - RapidIO Inbound Window Translation Address Register 2 */ + char res41[4]; + uint riwbar2; /* 0xd0da8 - RapidIO Inbound Window Base Address Register 2 */ + char res42[4]; + uint riwar2; /* 0xd0db0 - RapidIO Inbound Attributes Register 2 */ + char res43[12]; + uint riwtar1; /* 0xd0dc0 - RapidIO Inbound Window Translation Address Register 1 */ + char res44[4]; + uint riwbar1; /* 0xd0dc8 - RapidIO Inbound Window Base Address Register 1 */ + char res45[4]; + uint riwar1; /* 0xd0dd0 - RapidIO Inbound Attributes Register 1 */ + char res46[12]; + uint riwtar0; /* 0xd0de0 - RapidIO Inbound Window Translation Address Register 0 */ + char res47[12]; + uint riwar0; /* 0xd0df0 - RapidIO Inbound Attributes Register 0 */ + char res48[12]; + uint pnfedr; /* 0xd0e00 - Port Notification/Fatal Error Detect Register */ + uint pnfedir; /* 0xd0e04 - Port Notification/Fatal Error Detect Register */ + uint pnfeier; /* 0xd0e08 - Port Notification/Fatal Error Interrupt Enable Register */ + uint pecr; /* 0xd0e0c - Port Error Control Register */ + uint pepcsr0; /* 0xd0e10 - Port Error Packet/Control Symbol Register 0 */ + uint pepr1; /* 0xd0e14 - Port Error Packet Register 1 */ + uint pepr2; /* 0xd0e18 - Port Error Packet Register 2 */ + char res49[4]; + uint predr; /* 0xd0e20 - Port Recoverable Error Detect Register */ + char res50[4]; + uint pertr; /* 0xd0e28 - Port Error Recovery Threshold Register */ + uint prtr; /* 0xd0e2c - Port Retry Threshold Register */ + char res51[8656]; + uint omr; /* 0xd3000 - Outbound Mode Register */ + uint osr; /* 0xd3004 - Outbound Status Register */ + uint eodqtpar; /* 0xd3008 - Extended Outbound Descriptor Queue Tail Pointer Address Register */ + uint odqtpar; /* 0xd300c - Outbound Descriptor Queue Tail Pointer Address Register */ + uint eosar; /* 0xd3010 - Extended Outbound Unit Source Address Register */ + uint osar; /* 0xd3014 - Outbound Unit Source Address Register */ + uint odpr; /* 0xd3018 - Outbound Destination Port Register */ + uint odatr; /* 0xd301c - Outbound Destination Attributes Register */ + uint odcr; /* 0xd3020 - Outbound Doubleword Count Register */ + uint eodqhpar; /* 0xd3024 - Extended Outbound Descriptor Queue Head Pointer Address Register */ + uint odqhpar; /* 0xd3028 - Outbound Descriptor Queue Head Pointer Address Register */ + uint oretr; /* 0xd302C - Outbound Retry Error Threshold Register */ + uint omgr; /* 0xd3030 - Outbound Multicast Group Register */ + uint omlr; /* 0xd3034 - Outbound Multicast List Register */ + char res52[40]; + uint imr; /* 0xd3060 - Outbound Mode Register */ + uint isr; /* 0xd3064 - Inbound Status Register */ + uint eidqtpar; /* 0xd3068 - Extended Inbound Descriptor Queue Tail Pointer Address Register */ + uint idqtpar; /* 0xd306c - Inbound Descriptor Queue Tail Pointer Address Register */ + uint eifqhpar; /* 0xd3070 - Extended Inbound Frame Queue Head Pointer Address Register */ + uint ifqhpar; /* 0xd3074 - Inbound Frame Queue Head Pointer Address Register */ + uint imirir; /* 0xd3078 - Inbound Maximum Interrutp Report Interval Register */ + char res53[900]; + uint oddmr; /* 0xd3400 - Outbound Doorbell Mode Register */ + uint oddsr; /* 0xd3404 - Outbound Doorbell Status Register */ + char res54[16]; + uint oddpr; /* 0xd3418 - Outbound Doorbell Destination Port Register */ + uint oddatr; /* 0xd341C - Outbound Doorbell Destination Attributes Register */ + char res55[12]; + uint oddretr; /* 0xd342C - Outbound Doorbell Retry Threshold Configuration Register */ + char res56[48]; + uint idmr; /* 0xd3460 - Inbound Doorbell Mode Register */ + uint idsr; /* 0xd3464 - Inbound Doorbell Status Register */ + uint iedqtpar; /* 0xd3468 - Extended Inbound Doorbell Queue Tail Pointer Address Register */ + uint iqtpar; /* 0xd346c - Inbound Doorbell Queue Tail Pointer Address Register */ + uint iedqhpar; /* 0xd3470 - Extended Inbound Doorbell Queue Head Pointer Address Register */ + uint idqhpar; /* 0xd3474 - Inbound Doorbell Queue Head Pointer Address Register */ + uint idmirir; /* 0xd3478 - Inbound Doorbell Max Interrupt Report Interval Register */ + char res57[100]; + uint pwmr; /* 0xd34e0 - Port-Write Mode Register */ + uint pwsr; /* 0xd34e4 - Port-Write Status Register */ + uint epwqbar; /* 0xd34e8 - Extended Port-Write Queue Base Address Register */ + uint pwqbar; /* 0xd34ec - Port-Write Queue Base Address Register */ + char res58[51984]; +} ccsr_rio_t; + +/* Global Utilities Register Block(0xe_0000-0xf_ffff) */ +typedef struct ccsr_gur { + uint porpllsr; /* 0xe0000 - POR PLL ratio status register */ + uint porbmsr; /* 0xe0004 - POR boot mode status register */ +#define MPC86xx_PORBMSR_HA 0x00060000 + uint porimpscr; /* 0xe0008 - POR I/O impedance status and control register */ + uint pordevsr; /* 0xe000c - POR I/O device status regsiter */ +#define MPC86xx_PORDEVSR_IO_SEL 0x000F0000 + uint pordbgmsr; /* 0xe0010 - POR debug mode status register */ + char res1[12]; + uint gpporcr; /* 0xe0020 - General-purpose POR configuration register */ + char res2[12]; + uint gpiocr; /* 0xe0030 - GPIO control register */ + char res3[12]; + uint gpoutdr; /* 0xe0040 - General-purpose output data register */ + char res4[12]; + uint gpindr; /* 0xe0050 - General-purpose input data register */ + char res5[12]; + uint pmuxcr; /* 0xe0060 - Alternate function signal multiplex control */ + char res6[12]; + uint devdisr; /* 0xe0070 - Device disable control */ +#define MPC86xx_DEVDISR_PCIEX1 0x80000000 +#define MPC86xx_DEVDISR_PCIEX2 0x40000000 + char res7[12]; + uint powmgtcsr; /* 0xe0080 - Power management status and control register */ + char res8[12]; + uint mcpsumr; /* 0xe0090 - Machine check summary register */ + char res9[12]; + uint pvr; /* 0xe00a0 - Processor version register */ + uint svr; /* 0xe00a4 - System version register */ + char res10[3416]; + uint clkocr; /* 0xe0e00 - Clock out select register */ + char res11[12]; + uint ddrdllcr; /* 0xe0e10 - DDR DLL control register */ + char res12[12]; + uint lbcdllcr; /* 0xe0e20 - LBC DLL control register */ + int res13[57]; + uint lynxdcr1; /* 0xe0f08 - Lynx debug control register 1*/ + int res14[6]; + uint ddrioovcr; /* 0xe0f24 - DDR IO Overdrive Control register */ + char res15[61656]; +} ccsr_gur_t; + +typedef struct immap { + ccsr_local_mcm_t im_local_mcm; + ccsr_ddr_t im_ddr1; + ccsr_i2c_t im_i2c; + ccsr_duart_t im_duart; + ccsr_lbc_t im_lbc; + ccsr_ddr_t im_ddr2; + char res1[4096]; + ccsr_pex_t im_pex1; + ccsr_pex_t im_pex2; + ccsr_ht_t im_ht; + char res2[90112]; + ccsr_dma_t im_dma; + char res3[8192]; + ccsr_tsec_t im_tsec1; + ccsr_tsec_t im_tsec2; + ccsr_tsec_t im_tsec3; + ccsr_tsec_t im_tsec4; + char res4[98304]; + ccsr_pic_t im_pic; + char res5[389120]; + ccsr_rio_t im_rio; + ccsr_gur_t im_gur; +} immap_t; + +extern immap_t *immr; + +#endif /*__IMMAP_86xx__*/ diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h index 2606b79a24..612b5df487 100644 --- a/include/asm-ppc/mmu.h +++ b/include/asm-ppc/mmu.h @@ -434,19 +434,28 @@ extern int write_bat(ppc_bat_t bat, unsigned long upper, unsigned long lower); #define BOOKE_PAGESZ_1GB 10 #define BOOKE_PAGESZ_4GB 11 +#if defined(CONFIG_MPC86xx) +#define LAWBAR_BASE_ADDR 0x00FFFFFF +#define LAWAR_TRGT_IF 0x01F00000 +#else #define LAWBAR_BASE_ADDR 0x000FFFFF -#define LAWAR_EN 0x80000000 #define LAWAR_TRGT_IF 0x00F00000 +#endif +#define LAWAR_EN 0x80000000 #define LAWAR_SIZE 0x0000003F #define LAWAR_TRGT_IF_PCI 0x00000000 #define LAWAR_TRGT_IF_PCI1 0x00000000 #define LAWAR_TRGT_IF_PCIX 0x00000000 #define LAWAR_TRGT_IF_PCI2 0x00100000 +#define LAWAR_TRGT_IF_HT 0x00200000 #define LAWAR_TRGT_IF_LBC 0x00400000 #define LAWAR_TRGT_IF_CCSR 0x00800000 +#define LAWAR_TRGT_IF_DDR_INTERLEAVED 0x00B00000 #define LAWAR_TRGT_IF_RIO 0x00c00000 #define LAWAR_TRGT_IF_DDR 0x00f00000 +#define LAWAR_TRGT_IF_DDR1 0x00f00000 +#define LAWAR_TRGT_IF_DDR2 0x01600000 #define LAWAR_SIZE_BASE 0xa #define LAWAR_SIZE_4K (LAWAR_SIZE_BASE+1) @@ -469,5 +478,9 @@ extern int write_bat(ppc_bat_t bat, unsigned long upper, unsigned long lower); #define LAWAR_SIZE_512M (LAWAR_SIZE_BASE+18) #define LAWAR_SIZE_1G (LAWAR_SIZE_BASE+19) #define LAWAR_SIZE_2G (LAWAR_SIZE_BASE+20) +#define LAWAR_SIZE_4G (LAWAR_SIZE_BASE+21) +#define LAWAR_SIZE_8G (LAWAR_SIZE_BASE+22) +#define LAWAR_SIZE_16G (LAWAR_SIZE_BASE+23) +#define LAWAR_SIZE_32G (LAWAR_SIZE_BASE+24) #endif /* _PPC_MMU_H_ */ diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index 811378383d..1848aaf8cd 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -264,6 +264,7 @@ #define SPRN_ICTC 0x3FB /* Instruction Cache Throttling Control Reg */ #define SPRN_IMISS 0x3D4 /* Instruction TLB Miss Register */ #define SPRN_IMMR 0x27E /* Internal Memory Map Register */ +#define SPRN_LDSTCR 0x3F8 /* Load/Store Control Register */ #define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */ #define SPRN_LR 0x008 /* Link Register */ #define SPRN_MBAR 0x137 /* System memory base address */ @@ -443,6 +444,11 @@ #define SPRN_MCSR 0x23c /* Machine Check Syndrome register */ #define ESR_ST 0x00800000 /* Store Operation */ +#if defined(CONFIG_MPC86xx) +#define SPRN_MSSCRO 0x3f6 +#endif + + /* Short-hand versions for a number of the above SPRNs */ #define CTR SPRN_CTR /* Counter Register */ @@ -501,10 +507,14 @@ #define ICMP SPRN_ICMP /* Instruction TLB Compare Register */ #define IMISS SPRN_IMISS /* Instruction TLB Miss Register */ #define IMMR SPRN_IMMR /* PPC 860/821 Internal Memory Map Register */ +#define LDSTCR SPRN_LDSTCR /* Load/Store Control Register */ #define L2CR SPRN_L2CR /* PPC 750 L2 control register */ #define LR SPRN_LR #define MBAR SPRN_MBAR /* System memory base address */ -#if defined(CONFIG_E500) +#if defined(CONFIG_MPC86xx) +#define MSSCR0 SPRN_MSSCRO +#endif +#if defined(CONFIG_E500) || defined(CONFIG_MPC86xx) #define PIR SPRN_PIR #endif #define SVR SPRN_SVR /* System-On-Chip Version Register */ @@ -538,7 +548,7 @@ #define CSRR0 SPRN_CSRR0 #define CSRR1 SPRN_CSRR1 #define IVPR SPRN_IVPR -#define USPRG0 SPRN_USPRG0 +#define USPRG0 SPRN_USPRG #define SPRG4R SPRN_SPRG4R #define SPRG5R SPRN_SPRG5R #define SPRG6R SPRN_SPRG6R @@ -755,6 +765,8 @@ #define PVR_85xx_REV1 (PVR_85xx | 0x0010) #define PVR_85xx_REV2 (PVR_85xx | 0x0020) +#define PVR_86xx 0x80040000 +#define PVR_86xx_REV1 (PVR_86xx | 0x0010) /* * For the 8xx processors, all of them report the same PVR family for @@ -808,6 +820,8 @@ #define SVR_8548 0x8031 #define SVR_8548_E 0x8039 +#define SVR_8641 0x8090 +#define SVR_8641D 0x8091 /* I am just adding a single entry for 8260 boards. I think we may be * able to combine mbx, fads, rpxlite, bseip, and classic into a single diff --git a/include/asm-ppc/u-boot.h b/include/asm-ppc/u-boot.h index f7aa55f334..f335cd856a 100644 --- a/include/asm-ppc/u-boot.h +++ b/include/asm-ppc/u-boot.h @@ -45,7 +45,7 @@ typedef struct bd_info { unsigned long bi_sramstart; /* start of SRAM memory */ unsigned long bi_sramsize; /* size of SRAM memory */ #if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \ - || defined(CONFIG_E500) + || defined(CONFIG_E500) || defined(CONFIG_MPC86xx) unsigned long bi_immr_base; /* base of IMMR register */ #endif #if defined(CONFIG_MPC5xxx) diff --git a/include/common.h b/include/common.h index 5d8b15628b..83ccf7c987 100644 --- a/include/common.h +++ b/include/common.h @@ -79,6 +79,10 @@ typedef volatile unsigned char vu_char; #endif #include <asm/immap_8260.h> #endif +#ifdef CONFIG_MPC86xx +#include <mpc86xx.h> +#include <asm/immap_86xx.h> +#endif #ifdef CONFIG_MPC85xx #include <mpc85xx.h> #include <asm/immap_85xx.h> @@ -366,6 +370,7 @@ void trap_init (ulong); defined (CONFIG_74xx) || \ defined (CONFIG_MPC8220) || \ defined (CONFIG_MPC85xx) || \ + defined (CONFIG_MPC86xx) || \ defined (CONFIG_MPC83XX) unsigned char in8(unsigned int); void out8(unsigned int, unsigned char); @@ -454,6 +459,10 @@ ulong get_bus_freq (ulong); typedef MPC85xx_SYS_INFO sys_info_t; void get_sys_info ( sys_info_t * ); #endif +#if defined(CONFIG_MPC86xx) +typedef MPC86xx_SYS_INFO sys_info_t; +void get_sys_info ( sys_info_t * ); +#endif #if defined(CONFIG_4xx) || defined(CONFIG_IOP480) # if defined(CONFIG_440) @@ -468,7 +477,7 @@ void get_sys_info ( sys_info_t * ); #if defined(CONFIG_8xx) || defined(CONFIG_8260) void cpu_init_f (volatile immap_t *immr); #endif -#if defined(CONFIG_4xx) || defined(CONFIG_MPC85xx) || defined(CONFIG_MCF52x2) +#if defined(CONFIG_4xx) || defined(CONFIG_MPC85xx) || defined(CONFIG_MCF52x2) ||defined(CONFIG_MPC86xx) void cpu_init_f (void); #endif diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h new file mode 100644 index 0000000000..d4a28edf9b --- /dev/null +++ b/include/configs/MPC8641HPCN.h @@ -0,0 +1,592 @@ +/* + * Copyright 2006 Freescale Semiconductor. + * + * Srikanth Srinivasan (srikanth.srinivasan@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * MPC8641HPCN board configuration file + * + * Make sure you change the MAC address and other network params first, + * search for CONFIG_ETHADDR, CONFIG_SERVERIP, etc in this file. + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* High Level Configuration Options */ +#define CONFIG_MPC86xx 1 /* MPC86xx */ +#define CONFIG_MPC8641 1 /* MPC8641 specific */ +#define CONFIG_MPC8641HPCN 1 /* MPC8641HPCN board specific */ +#define CONFIG_NUM_CPUS 2 /* Number of CPUs in the system */ +#define CONFIG_LINUX_RESET_VEC 0x100 /* Reset vector used by Linux */ +#undef DEBUG + +#ifdef RUN_DIAG +#define CFG_DIAG_ADDR 0xff800000 +#endif + +#define CFG_RESET_ADDRESS 0xfff00100 + +#undef CONFIG_PCI + +#define CONFIG_TSEC_ENET /* tsec ethernet support */ +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup*/ +#undef CONFIG_DDR_DLL /* possible DLL fix needed */ +#define CONFIG_DDR_2T_TIMING /* Sets the 2T timing bit */ +#define CONFIG_DDR_ECC /* only for ECC DDR module */ +#define CONFIG_ECC_INIT_VIA_DDRCONTROLLER /* DDR controller or DMA? */ +#define CONFIG_MEM_INIT_VALUE 0xDeadBeef + +#define CONFIG_ALTIVEC 1 + +/* + * L2CR setup -- make sure this is right for your board! + */ +#define CFG_L2 +#define L2_INIT 0 +#define L2_ENABLE (L2CR_L2E) + +#ifndef CONFIG_SYS_CLK_FREQ +#define CONFIG_SYS_CLK_FREQ get_board_sys_clk(0) +#endif + +#define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_pre_init */ + +#undef CFG_DRAM_TEST /* memory test, takes time */ +#define CFG_MEMTEST_START 0x00200000 /* memtest region */ +#define CFG_MEMTEST_END 0x00400000 + + +/* + * Base addresses -- Note these are effective addresses where the + * actual resources get mapped (not physical addresses) + */ +#define CFG_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ +#define CFG_CCSRBAR 0xf8000000 /* relocated CCSRBAR */ +#define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ + + +/* + * DDR Setup + */ +#define CFG_DDR_SDRAM_BASE 0x00000000 /* DDR is system memory*/ +#define CFG_SDRAM_BASE CFG_DDR_SDRAM_BASE + +#define MPC86xx_DDR_SDRAM_CLK_CNTL + +#if defined(CONFIG_SPD_EEPROM) + /* + * Determine DDR configuration from I2C interface. + */ + #define SPD_EEPROM_ADDRESS 0x51 /* DDR DIMM */ + +#else + /* + * Manually set up DDR1 parameters + */ + + #define CFG_SDRAM_SIZE 256 /* DDR is 256MB */ + + #define CFG_DDR_CS0_BNDS 0x0000000F + #define CFG_DDR_CS0_CONFIG 0x80010102 /* Enable, no interleaving */ + #define CFG_DDR_EXT_REFRESH 0x00000000 + #define CFG_DDR_TIMING_0 0x00260802 + #define CFG_DDR_TIMING_1 0x39357322 + #define CFG_DDR_TIMING_2 0x14904cc8 + #define CFG_DDR_MODE_1 0x00480432 + #define CFG_DDR_MODE_2 0x00000000 + #define CFG_DDR_INTERVAL 0x06090100 + #define CFG_DDR_DATA_INIT 0xdeadbeef + #define CFG_DDR_CLK_CTRL 0x03800000 + #define CFG_DDR_OCD_CTRL 0x00000000 + #define CFG_DDR_OCD_STATUS 0x00000000 + #define CFG_DDR_CONTROL 0xe3008000 /* Type = DDR2 */ + #define CFG_DDR_CONTROL2 0x04400000 + + /* Not used in fixed_sdram function */ + + #define CFG_DDR_MODE 0x00000022 + #define CFG_DDR_CS1_BNDS 0x00000000 + #define CFG_DDR_CS2_BNDS 0x00000FFF /* Not done */ + #define CFG_DDR_CS3_BNDS 0x00000FFF /* Not done */ + #define CFG_DDR_CS4_BNDS 0x00000FFF /* Not done */ + #define CFG_DDR_CS5_BNDS 0x00000FFF /* Not done */ +#endif + + +/* + * In MPC8641HPCN, we allocate 16MB flash spaces at fe000000 and ff000000 + * We only have an 8MB flash. In effect, the addresses from fe000000 to fe7fffff + * map to fe800000 to ffffffff, and ff000000 to ff7fffff map to ffffffff. + * However, when u-boot comes up, the flash_init needs hard start addresses + * to build its info table. For user convenience, we have the flash addresses + * as fe800000 and ff800000. That way, when we do flash operations, u-boot + * knows where the flash is and the user can download u-boot code from promjet to + * fef00000 <- more intuitive than fe700000. Note that, on switching the boot + * location, fef00000 becomes fff00000. + */ +#define CFG_FLASH_BASE 0xfe800000 /* start of FLASH 32M */ +#define CFG_FLASH_BASE2 0xff800000 + +#define CFG_FLASH_BANKS_LIST {CFG_FLASH_BASE, CFG_FLASH_BASE2} + +#define CFG_BR0_PRELIM 0xff001001 /* port size 16bit */ +#define CFG_OR0_PRELIM 0xff006ff7 /* 16MB Boot Flash area*/ + +#define CFG_BR1_PRELIM 0xfe001001 /* port size 16bit */ +#define CFG_OR1_PRELIM 0xff006ff7 /* 16MB Alternate Boot Flash area*/ + +#define CFG_BR2_PRELIM 0xf8201001 /* port size 16bit */ +#define CFG_OR2_PRELIM 0xfff06ff7 /* 1MB Compact Flash area*/ + +#define CFG_BR3_PRELIM 0xf8100801 /* port size 8bit */ +#define CFG_OR3_PRELIM 0xfff06ff7 /* 1MB PIXIS area*/ + + +#define PIXIS_BASE 0xf8100000 /* PIXIS registers */ +#define PIXIS_ID 0x0 /* Board ID at offset 0 */ +#define PIXIS_VER 0x1 /* Board version at offset 1 */ +#define PIXIS_PVER 0x2 /* PIXIS FPGA version at offset 2 */ +#define PIXIS_RST 0x4 /* PIXIS Reset Control register */ +#define PIXIS_AUX 0x6 /* PIXIS Auxiliary register; Scratch register */ +#define PIXIS_SPD 0x7 /* Register for SYSCLK speed */ +#define PIXIS_VCTL 0x10 /* VELA Control Register */ +#define PIXIS_VCFGEN0 0x12 /* VELA Config Enable 0 */ +#define PIXIS_VCFGEN1 0x13 /* VELA Config Enable 1 */ +#define PIXIS_VBOOT 0x16 /* VELA VBOOT Register */ +#define PIXIS_VSPEED0 0x17 /* VELA VSpeed 0 */ +#define PIXIS_VSPEED1 0x18 /* VELA VSpeed 1 */ +#define PIXIS_VCLKH 0x19 /* VELA VCLKH register */ +#define PIXIS_VCLKL 0x1A /* VELA VCLKL register */ + +#define CFG_MAX_FLASH_BANKS 2 /* number of banks */ +#define CFG_MAX_FLASH_SECT 128 /* sectors per device */ + +#undef CFG_FLASH_CHECKSUM +#define CFG_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */ +#define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ +#define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */ + +#define CFG_FLASH_CFI_DRIVER +#define CFG_FLASH_CFI +#define CFG_FLASH_EMPTY_INFO + +#if (CFG_MONITOR_BASE < CFG_FLASH_BASE) +#define CFG_RAMBOOT +#else +#undef CFG_RAMBOOT +#endif + +#if !defined(CONFIG_SPD_EEPROM) && !defined(CFG_RAMBOOT) +#undef CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup*/ +#endif + +#undef CONFIG_CLOCKS_IN_MHZ + +#define CONFIG_L1_INIT_RAM +#define CFG_INIT_RAM_LOCK 1 +#ifndef CFG_INIT_RAM_LOCK +#define CFG_INIT_RAM_ADDR 0x0fd00000 /* Initial RAM address */ +#else +#define CFG_INIT_RAM_ADDR 0xf8400000 /* Initial RAM address */ +#endif +#define CFG_INIT_RAM_END 0x4000 /* End of used area in RAM */ + +#define CFG_GBL_DATA_SIZE 128 /* num bytes initial data */ +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET + +#define CFG_MONITOR_LEN (256 * 1024) /* Reserve 256 kB for Mon */ +#define CFG_MALLOC_LEN (128 * 1024) /* Reserved for malloc */ + +/* Serial Port */ +#define CONFIG_CONS_INDEX 1 +#undef CONFIG_SERIAL_SOFTWARE_FIFO +#define CFG_NS16550 +#define CFG_NS16550_SERIAL +#define CFG_NS16550_REG_SIZE 1 +#define CFG_NS16550_CLK get_bus_freq(0) + +#define CFG_BAUDRATE_TABLE \ + {300, 600, 1200, 2400, 4800, 9600, 19200, 38400,115200} + +#define CFG_NS16550_COM1 (CFG_CCSRBAR+0x4500) +#define CFG_NS16550_COM2 (CFG_CCSRBAR+0x4600) + +/* Use the HUSH parser */ +#define CFG_HUSH_PARSER +#ifdef CFG_HUSH_PARSER +#define CFG_PROMPT_HUSH_PS2 "> " +#endif + +/* + * Pass open firmware flat tree to kernel + */ +#define CONFIG_OF_FLAT_TREE 1 +#define CONFIG_OF_BOARD_SETUP 1 + +/* maximum size of the flat tree (8K) */ +#define OF_FLAT_TREE_MAX_SIZE 8192 + +#define OF_CPU "PowerPC,8641@0" +#define OF_SOC "soc8641@f8000000" +#define OF_TBCLK (bd->bi_busfreq / 8) +#define OF_STDOUT_PATH "/soc8641@f8000000/serial@4500" + +#define CFG_64BIT_VSPRINTF 1 +#define CFG_64BIT_STRTOUL 1 + +/* I2C */ +#define CONFIG_HARD_I2C /* I2C with hardware support*/ +#undef CONFIG_SOFT_I2C /* I2C bit-banged */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F +#define CFG_I2C_NOPROBES {0x69} /* Don't probe these addrs */ + +/* RapidIO MMU */ +#define CFG_RIO_MEM_BASE 0xc0000000 /* base address */ +#define CFG_RIO_MEM_PHYS CFG_RIO_MEM_BASE +#define CFG_RIO_MEM_SIZE 0x20000000 /* 128M */ + +/* + * General PCI + * Addresses are mapped 1-1. + */ +#define CFG_PCI1_MEM_BASE 0x80000000 +#define CFG_PCI1_MEM_PHYS CFG_PCI1_MEM_BASE +#define CFG_PCI1_MEM_SIZE 0x20000000 /* 512M */ +#define CFG_PCI1_IO_BASE 0xe2000000 +#define CFG_PCI1_IO_PHYS CFG_PCI1_IO_BASE +#define CFG_PCI1_IO_SIZE 0x1000000 /* 16M */ + +/* For RTL8139 */ +#define _IO_BASE 0x00000000 + +#define CFG_PCI2_MEM_BASE 0xa0000000 +#define CFG_PCI2_MEM_PHYS CFG_PCI2_MEM_BASE +#define CFG_PCI2_MEM_SIZE 0x10000000 /* 256M */ +#define CFG_PCI2_IO_BASE 0xe3000000 +#define CFG_PCI2_IO_PHYS CFG_PCI2_IO_BASE +#define CFG_PCI2_IO_SIZE 0x1000000 /* 16M */ + + +#if defined(CONFIG_PCI) + +#define CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ + +#undef CFG_SCSI_SCAN_BUS_REVERSE + +#define CONFIG_NET_MULTI +#define CONFIG_PCI_PNP /* do pci plug-and-play */ + +#define CONFIG_RTL8139 + +#undef CONFIG_EEPRO100 +#undef CONFIG_TULIP + +#if !defined(CONFIG_PCI_PNP) + #define PCI_ENET0_IOADDR 0xe0000000 + #define PCI_ENET0_MEMADDR 0xe0000000 + #define PCI_IDSEL_NUMBER 0x0c /* slot0->3(IDSEL)=12->15 */ +#endif + +#undef CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ + +#endif /* CONFIG_PCI */ + + +#if defined(CONFIG_TSEC_ENET) + +#ifndef CONFIG_NET_MULTI +#define CONFIG_NET_MULTI 1 +#endif + +#define CONFIG_MII 1 /* MII PHY management */ + +#define CONFIG_MPC86XX_TSEC1 1 +#define CONFIG_MPC86XX_TSEC1_NAME "eTSEC1" +#define CONFIG_MPC86XX_TSEC2 1 +#define CONFIG_MPC86XX_TSEC2_NAME "eTSEC2" +#define CONFIG_MPC86XX_TSEC3 1 +#define CONFIG_MPC86XX_TSEC3_NAME "eTSEC3" +#define CONFIG_MPC86XX_TSEC4 1 +#define CONFIG_MPC86XX_TSEC4_NAME "eTSEC4" + +#define TSEC1_PHY_ADDR 0 +#define TSEC2_PHY_ADDR 1 +#define TSEC3_PHY_ADDR 2 +#define TSEC4_PHY_ADDR 3 +#define TSEC1_PHYIDX 0 +#define TSEC2_PHYIDX 0 +#define TSEC3_PHYIDX 0 +#define TSEC4_PHYIDX 0 + +#define CONFIG_ETHPRIME "eTSEC1" + +#endif /* CONFIG_TSEC_ENET */ + + +/* BAT0 2G Cacheable, non-guarded + * 0x0000_0000 2G DDR + */ +#define CFG_DBAT0L ( BATL_PP_RW | BATL_CACHEINHIBIT \ + | BATL_GUARDEDSTORAGE | BATL_MEMCOHERENCE ) +#define CFG_DBAT0U ( BATU_BL_512M | BATU_VS | BATU_VP ) +#define CFG_IBAT0L ( BATL_PP_RW | BATL_CACHEINHIBIT | BATL_MEMCOHERENCE) +#define CFG_IBAT0U CFG_DBAT0U + +/* BAT1 1G Cache-inhibited, guarded + * 0x8000_0000 512M PCI-Express 1 Memory + * 0xa000_0000 512M PCI-Express 2 Memory + ** SS - Changed it for operating from 0xd0000000 + */ +#define CFG_DBAT1L ( CFG_PCI1_MEM_BASE | BATL_PP_RW \ + | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_DBAT1U (CFG_PCI1_MEM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) +#define CFG_IBAT1L (CFG_PCI1_MEM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT) +#define CFG_IBAT1U CFG_DBAT1U + +/* BAT2 512M Cache-inhibited, guarded + * 0xc000_0000 512M RapidIO Memory + */ +#define CFG_DBAT2L (CFG_RIO_MEM_BASE | BATL_PP_RW \ + | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_DBAT2U (CFG_RIO_MEM_BASE | BATU_BL_512M | BATU_VS | BATU_VP) +#define CFG_IBAT2L (CFG_RIO_MEM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT) +#define CFG_IBAT2U CFG_DBAT2U + +/* BAT3 4M Cache-inhibited, guarded + * 0xf800_0000 4M CCSR + */ +#define CFG_DBAT3L ( CFG_CCSRBAR | BATL_PP_RW \ + | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_DBAT3U (CFG_CCSRBAR | BATU_BL_4M | BATU_VS | BATU_VP) +#define CFG_IBAT3L (CFG_CCSRBAR | BATL_PP_RW | BATL_CACHEINHIBIT) +#define CFG_IBAT3U CFG_DBAT3U + +/* BAT4 32M Cache-inhibited, guarded + * 0xe200_0000 16M PCI-Express 1 I/O + * 0xe300_0000 16M PCI-Express 2 I/0 + ** SS - Note that this is at 0xe0000000 + */ +#define CFG_DBAT4L ( CFG_PCI1_IO_BASE | BATL_PP_RW \ + | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_DBAT4U (CFG_PCI1_IO_BASE | BATU_BL_32M | BATU_VS | BATU_VP) +#define CFG_IBAT4L (CFG_PCI1_IO_BASE | BATL_PP_RW | BATL_CACHEINHIBIT) +#define CFG_IBAT4U CFG_DBAT4U + +/* BAT5 128K Cacheable, non-guarded + * 0xe401_0000 128K Init RAM for stack in the CPU DCache (no backing memory) + */ +#define CFG_DBAT5L (CFG_INIT_RAM_ADDR | BATL_PP_RW | BATL_MEMCOHERENCE) +#define CFG_DBAT5U (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP) +#define CFG_IBAT5L CFG_DBAT5L +#define CFG_IBAT5U CFG_DBAT5U + +/* BAT6 32M Cache-inhibited, guarded + * 0xfe00_0000 32M FLASH + */ +#define CFG_DBAT6L ( CFG_FLASH_BASE | BATL_PP_RW \ + | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_DBAT6U (CFG_FLASH_BASE | BATU_BL_32M | BATU_VS | BATU_VP) +#define CFG_IBAT6L (CFG_FLASH_BASE | BATL_PP_RW | BATL_MEMCOHERENCE) +#define CFG_IBAT6U CFG_DBAT6U + +#define CFG_DBAT7L 0x00000000 +#define CFG_DBAT7U 0x00000000 +#define CFG_IBAT7L 0x00000000 +#define CFG_IBAT7U 0x00000000 + + + + +/* + * Environment + */ +#ifndef CFG_RAMBOOT + #define CFG_ENV_IS_IN_FLASH 1 + #define CFG_ENV_ADDR (CFG_MONITOR_BASE + 0x40000) + #define CFG_ENV_SECT_SIZE 0x40000 /* 256K(one sector) for env */ + #define CFG_ENV_SIZE 0x2000 +#else + #define CFG_NO_FLASH 1 /* Flash is not usable now */ + #define CFG_ENV_IS_NOWHERE 1 /* Store ENV in memory only */ + #define CFG_ENV_ADDR (CFG_MONITOR_BASE - 0x1000) + #define CFG_ENV_SIZE 0x2000 +#endif + +#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ +#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ + +#if defined(CFG_RAMBOOT) + #if defined(CONFIG_PCI) + #define CONFIG_COMMANDS ((CONFIG_CMD_DFL \ + | CFG_CMD_PING \ + | CFG_CMD_PCI \ + | CFG_CMD_I2C) \ + & \ + ~(CFG_CMD_ENV \ + | CFG_CMD_IMLS \ + | CFG_CMD_FLASH \ + | CFG_CMD_LOADS)) + #else + #define CONFIG_COMMANDS ((CONFIG_CMD_DFL \ + | CFG_CMD_PING \ + | CFG_CMD_I2C) \ + & \ + ~(CFG_CMD_ENV \ + | CFG_CMD_IMLS \ + | CFG_CMD_FLASH \ + | CFG_CMD_LOADS)) + #endif +#else + #if defined(CONFIG_PCI) + #define CONFIG_COMMANDS (CONFIG_CMD_DFL \ + | CFG_CMD_PCI \ + | CFG_CMD_PING \ + | CFG_CMD_I2C) + #else + #define CONFIG_COMMANDS (CONFIG_CMD_DFL \ + | CFG_CMD_PING \ + | CFG_CMD_I2C) + #endif +#endif + +#include <cmd_confdefs.h> + +#undef CONFIG_WATCHDOG /* watchdog disabled */ + +/* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_LOAD_ADDR 0x2000000 /* default load address */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + #define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else + #define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif + +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ +#define CFG_HZ 1000 /* decrementer freq: 1ms ticks */ + +/* + * For booting Linux, the board info and command line data + * have to be in the first 8 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux*/ + +/* Cache Configuration */ +#define CFG_DCACHE_SIZE 32768 +#define CFG_CACHELINE_SIZE 32 +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CFG_CACHELINE_SHIFT 5 /*log base 2 of the above value*/ +#endif + +/* + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */ +#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */ +#endif + + +/* + * Environment Configuration + */ + +/* The mac addresses for all ethernet interface */ +#if defined(CONFIG_TSEC_ENET) +#define CONFIG_ETHADDR 00:E0:0C:00:00:01 +#define CONFIG_ETH1ADDR 00:E0:0C:00:01:FD +#define CONFIG_ETH2ADDR 00:E0:0C:00:02:FD +#define CONFIG_ETH3ADDR 00:E0:0C:00:03:FD +#endif + +#define CONFIG_HAS_ETH1 1 +#define CONFIG_HAS_ETH2 1 +#define CONFIG_HAS_ETH3 1 + +#define CONFIG_IPADDR 192.168.1.100 + +#define CONFIG_HOSTNAME unknown +#define CONFIG_ROOTPATH /opt/nfsroot +#define CONFIG_BOOTFILE uImage + +#define CONFIG_SERVERIP 192.168.1.1 +#define CONFIG_GATEWAYIP 192.168.1.1 +#define CONFIG_NETMASK 255.255.255.0 + +/* default location for tftp and bootm */ +#define CONFIG_LOADADDR 1000000 + +#define CONFIG_BOOTDELAY 10 /* -1 disables auto-boot */ +#undef CONFIG_BOOTARGS /* the boot command will set bootargs */ + +#define CONFIG_BAUDRATE 115200 + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "netdev=eth0\0" \ + "consoledev=ttyS0\0" \ + "ramdiskaddr=400000\0" \ + "ramdiskfile=your.ramdisk.u-boot\0" \ + "pex0=echo ---------------------------; echo --------- PCI EXPRESS -----\0"\ + "pexstat=mw f8008000 84000004; echo -expect:- 16000000; md f8008004 1\0" \ + "pex1=pci write 1.0.0 4 146; pci write 1.0.0 10 80000000\0" \ + "pexd=echo -expect:- xxx01002 00100146; pci display 1.0.0 0 2\0" \ + "pex=run pexstat; run pex1; run pexd\0" \ + "en-wd=mw.b f8100010 0x08; echo -expect:- 08; md.b f8100010 1\0" \ + "dis-wd=mw.b f8100010 0x00; echo -expect:- 00; md.b f8100010 1\0" \ + "maxcpus=2" + + +#define CONFIG_NFSBOOTCOMMAND \ + "setenv bootargs root=/dev/nfs rw " \ + "nfsroot=$serverip:$rootpath " \ + "ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \ + "console=$consoledev,$baudrate $othbootargs;" \ + "tftp $loadaddr $bootfile;" \ + "bootm $loadaddr" + +#define CONFIG_RAMBOOTCOMMAND \ + "setenv bootargs root=/dev/ram rw " \ + "console=$consoledev,$baudrate $othbootargs;" \ + "tftp $ramdiskaddr $ramdiskfile;" \ + "tftp $loadaddr $bootfile;" \ + "bootm $loadaddr $ramdiskaddr" + +#define CONFIG_BOOTCOMMAND CONFIG_NFSBOOTCOMMAND + +#endif /* __CONFIG_H */ diff --git a/include/ft_build.h b/include/ft_build.h index 47ca575d9f..5c5e06309b 100644 --- a/include/ft_build.h +++ b/include/ft_build.h @@ -58,7 +58,9 @@ void ft_begin(struct ft_cxt *cxt, void *blob, int max_size); void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size); void ft_setup(void *blob, int size, bd_t * bd, ulong initrd_start, ulong initrd_end); - +#ifdef CONFIG_OF_BOARD_SETUP +void ft_board_setup(void *blob, bd_t *bd); +#endif void ft_dump_blob(const void *bphp); void ft_merge_blob(struct ft_cxt *cxt, void *blob); void *ft_get_prop(void *bphp, const char *propname, int *szp); diff --git a/include/mpc86xx.h b/include/mpc86xx.h new file mode 100644 index 0000000000..4edeae1647 --- /dev/null +++ b/include/mpc86xx.h @@ -0,0 +1,119 @@ +/* + * Copyright 2006 Freescale Semiconductor. + * Jeffrey Brown (jeffrey@freescale.com) + * Srikanth Srinivasan (srikanth.srinivasan@freescale.com) + */ + +#ifndef __MPC86xx_H__ +#define __MPC86xx_H__ + +#define EXC_OFF_SYS_RESET 0x0100 /* System reset offset */ + +/* + * l2cr values. Look in config_<BOARD>.h for the actual setup + */ +#define l2cr 1017 + +#define L2CR_L2E 0x80000000 /* bit 0 - enable */ +#define L2CR_L2PE 0x40000000 /* bit 1 - data parity */ +#define L2CR_L2I 0x00200000 /* bit 10 - global invalidate bit */ +#define L2CR_L2CTL 0x00100000 /* bit 11 - l2 ram control */ +#define L2CR_L2DO 0x00010000 /* bit 15 - data-only mode */ +#define L2CR_REP 0x00001000 /* bit 19 - l2 replacement alg */ +#define L2CR_HWF 0x00000800 /* bit 20 - hardware flush */ +#define L2CR_L2IP 0x00000001 /* global invalidate in progress */ + +/* + * BAT settings. Look in config_<BOARD>.h for the actual setup + */ + +#define BATU_BL_128K 0x00000000 +#define BATU_BL_256K 0x00000004 +#define BATU_BL_512K 0x0000000c +#define BATU_BL_1M 0x0000001c +#define BATU_BL_2M 0x0000003c +#define BATU_BL_4M 0x0000007c +#define BATU_BL_8M 0x000000fc +#define BATU_BL_16M 0x000001fc +#define BATU_BL_32M 0x000003fc +#define BATU_BL_64M 0x000007fc +#define BATU_BL_128M 0x00000ffc +#define BATU_BL_256M 0x00001ffc +#define BATU_BL_512M 0x00003ffc +#define BATU_BL_1G 0x00007ffc +#define BATU_BL_2G 0x0000fffc +#define BATU_BL_4G 0x0001fffc + +#define BATU_VS 0x00000002 +#define BATU_VP 0x00000001 +#define BATU_INVALID 0x00000000 + +#define BATL_WRITETHROUGH 0x00000040 +#define BATL_CACHEINHIBIT 0x00000020 +#define BATL_MEMCOHERENCE 0x00000010 +#define BATL_GUARDEDSTORAGE 0x00000008 +#define BATL_NO_ACCESS 0x00000000 + +#define BATL_PP_MSK 0x00000003 +#define BATL_PP_00 0x00000000 /* No access */ +#define BATL_PP_01 0x00000001 /* Read-only */ +#define BATL_PP_10 0x00000002 /* Read-write */ +#define BATL_PP_11 0x00000003 + +#define BATL_PP_NO_ACCESS BATL_PP_00 +#define BATL_PP_RO BATL_PP_01 +#define BATL_PP_RW BATL_PP_10 + +#define HID0_XBSEN 0x00000100 +#define HID0_HIGH_BAT_EN 0x00800000 +#define HID0_XAEN 0x00020000 + +#ifndef __ASSEMBLY__ + +typedef struct +{ + unsigned long freqProcessor; + unsigned long freqSystemBus; +} MPC86xx_SYS_INFO; + +#define l1icache_enable icache_enable + +void l2cache_enable(void); +void l1dcache_enable(void); + +static __inline__ unsigned long get_hid0 (void) +{ + unsigned long hid0; + asm volatile("mfspr %0, 1008" : "=r" (hid0) :); + return hid0; +} + +static __inline__ unsigned long get_hid1 (void) +{ + unsigned long hid1; + asm volatile("mfspr %0, 1009" : "=r" (hid1) :); + return hid1; +} + +static __inline__ void set_hid0 (unsigned long hid0) +{ + asm volatile("mtspr 1008, %0" : : "r" (hid0)); +} + +static __inline__ void set_hid1 (unsigned long hid1) +{ + asm volatile("mtspr 1009, %0" : : "r" (hid1)); +} + + +static __inline__ unsigned long get_l2cr (void) +{ + unsigned long l2cr_val; + asm volatile("mfspr %0, 1017" : "=r" (l2cr_val) :); + return l2cr_val; +} + +#endif /* _ASMLANGUAGE */ +#endif /* __MPC86xx_H__ */ + + diff --git a/include/pci.h b/include/pci.h index 0fc00e4276..705d1fcd8a 100644 --- a/include/pci.h +++ b/include/pci.h @@ -270,6 +270,12 @@ #define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 4x rate */ #define PCI_AGP_SIZEOF 12 +/* PCI-X registers */ +#define PCI_X_CMD_DPERR_E 0x0001 /* Data Parity Error Recovery Enable */+#define PCI_X_CMD_ERO 0x0002 /* Enable Relaxed Ordering */ +#define PCI_X_CMD_MAX_READ 0x0000 /* Max Memory Read Byte Count */ +#define PCI_X_CMD_MAX_SPLIT 0x0030 /* Max Outstanding Split Transactions */ +#define PCI_X_CMD_VERSION(x) (((x) >> 12) & 3) /* Version */ + /* Slot Identification */ #define PCI_SID_ESR 2 /* Expansion Slot Register */ diff --git a/lib_ppc/board.c b/lib_ppc/board.c index e68cf1fe73..126102bf96 100644 --- a/lib_ppc/board.c +++ b/lib_ppc/board.c @@ -503,7 +503,7 @@ void board_init_f (ulong bootflag) #endif #if defined(CONFIG_8xx) || defined(CONFIG_8260) || defined(CONFIG_5xx) || \ - defined(CONFIG_E500) + defined(CONFIG_E500) || defined(CONFIG_MPC86xx) bd->bi_immr_base = CFG_IMMR; /* base of IMMR register */ #endif #if defined(CONFIG_MPC5xxx) @@ -195,6 +195,22 @@ int eth_initialize(bd_t *bis) tsec_initialize(bis, 3, CONFIG_MPC83XX_TSEC4_NAME); # endif #endif +#if defined(CONFIG_MPC86XX_TSEC1) + tsec_initialize(bis, 0, CONFIG_MPC86XX_TSEC1_NAME); +#endif + +#if defined(CONFIG_MPC86XX_TSEC2) + tsec_initialize(bis, 1, CONFIG_MPC86XX_TSEC2_NAME); +#endif + +#if defined(CONFIG_MPC86XX_TSEC3) + tsec_initialize(bis, 2, CONFIG_MPC86XX_TSEC3_NAME); +#endif + +#if defined(CONFIG_MPC86XX_TSEC4) + tsec_initialize(bis, 3, CONFIG_MPC86XX_TSEC4_NAME); +#endif + #if defined(FEC_ENET) || defined(CONFIG_ETHER_ON_FCC) fec_initialize(bis); #endif |