diff options
author | Jon Loeliger <jdl@freescale.com> | 2008-03-05 18:05:45 -0600 |
---|---|---|
committer | Wolfgang Denk <wd@denx.de> | 2008-03-25 23:00:00 +0100 |
commit | b7e24d283e34727c2a6cdfdac2e09a426c579b73 (patch) | |
tree | 99a18ef12fe560626e74fc504c5b76f05087a3ba /board/freescale | |
parent | 6a8a5dc4759867c45aa95580deb8bf26669a5d97 (diff) |
FSL: Move board/mpc8260ads under board/freescale
Signed-off-by: Jon Loeliger <jdl@freescale.com>
Diffstat (limited to 'board/freescale')
-rw-r--r-- | board/freescale/mpc8260ads/Makefile | 51 | ||||
-rw-r--r-- | board/freescale/mpc8260ads/config.mk | 37 | ||||
-rw-r--r-- | board/freescale/mpc8260ads/flash.c | 492 | ||||
-rw-r--r-- | board/freescale/mpc8260ads/mpc8260ads.c | 546 |
4 files changed, 1126 insertions, 0 deletions
diff --git a/board/freescale/mpc8260ads/Makefile b/board/freescale/mpc8260ads/Makefile new file mode 100644 index 0000000000..de7d847a5f --- /dev/null +++ b/board/freescale/mpc8260ads/Makefile @@ -0,0 +1,51 @@ + +# +# (C) Copyright 2001-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS := $(BOARD).o flash.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/freescale/mpc8260ads/config.mk b/board/freescale/mpc8260ads/config.mk new file mode 100644 index 0000000000..e99e181dda --- /dev/null +++ b/board/freescale/mpc8260ads/config.mk @@ -0,0 +1,37 @@ +# +# (C) Copyright 2001-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# Modified by, Stuart Hughes, Lineo Inc, stuarth@lineo.com +# +# Modified by, Yuli Barcohen, Arabella Software Ltd., yuli@arabellasw.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 +# + +# +# MPC8260ADS, MPC8266ADS, and PQ2FADS-ZU/VR boards +# + +sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp + +ifndef TEXT_BASE +## Standard: boot high +TEXT_BASE = 0xFFF00000 +endif diff --git a/board/freescale/mpc8260ads/flash.c b/board/freescale/mpc8260ads/flash.c new file mode 100644 index 0000000000..59997aac4f --- /dev/null +++ b/board/freescale/mpc8260ads/flash.c @@ -0,0 +1,492 @@ +/* + * (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. + * + * (C) Copyright 2003 Arabella Software Ltd. + * Yuli Barcohen <yuli@arabellasw.com> + * Re-written to support multi-bank flash SIMMs. + * Added support for real protection and JFFS2. + * + * 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> + +/* Intel-compatible flash ID */ +#define INTEL_COMPAT 0x89898989 +#define INTEL_ALT 0xB0B0B0B0 + +/* Intel-compatible flash commands */ +#define INTEL_PROGRAM 0x10101010 +#define INTEL_ERASE 0x20202020 +#define INTEL_CLEAR 0x50505050 +#define INTEL_LOCKBIT 0x60606060 +#define INTEL_PROTECT 0x01010101 +#define INTEL_STATUS 0x70707070 +#define INTEL_READID 0x90909090 +#define INTEL_CONFIRM 0xD0D0D0D0 +#define INTEL_RESET 0xFFFFFFFF + +/* Intel-compatible flash status bits */ +#define INTEL_FINISHED 0x80808080 +#define INTEL_OK 0x80808080 + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +/*----------------------------------------------------------------------- + * This board supports 32-bit wide flash SIMMs (4x8-bit configuration.) + * Up to 32MB of flash supported (up to 4 banks.) + * BCSR is used for flash presence detect (page 4-65 of the User's Manual) + * + * The following code can not run from flash! + */ +unsigned long flash_init (void) +{ + ulong size = 0, sect_start, sect_size = 0, bank_size; + ushort sect_count = 0; + int i, j, nbanks; + vu_long *addr = (vu_long *)CFG_FLASH_BASE; + vu_long *bcsr = (vu_long *)CFG_BCSR; + + switch (bcsr[2] & 0xF) { + case 0: + nbanks = 4; + break; + case 1: + nbanks = 2; + break; + case 2: + nbanks = 1; + break; + default: /* Unsupported configurations */ + nbanks = CFG_MAX_FLASH_BANKS; + } + + if (nbanks > CFG_MAX_FLASH_BANKS) + nbanks = CFG_MAX_FLASH_BANKS; + + for (i = 0; i < nbanks; i++) { + *addr = INTEL_READID; /* Read Intelligent Identifier */ + if ((addr[0] == INTEL_COMPAT) || (addr[0] == INTEL_ALT)) { + switch (addr[1]) { + case SHARP_ID_28F016SCL: + case SHARP_ID_28F016SCZ: + flash_info[i].flash_id = FLASH_MAN_SHARP | FLASH_LH28F016SCT; + sect_count = 32; + sect_size = 0x40000; + break; + default: + flash_info[i].flash_id = FLASH_UNKNOWN; + sect_count = CFG_MAX_FLASH_SECT; + sect_size = + CFG_FLASH_SIZE / CFG_MAX_FLASH_BANKS / CFG_MAX_FLASH_SECT; + } + } + else + flash_info[i].flash_id = FLASH_UNKNOWN; + if (flash_info[i].flash_id == FLASH_UNKNOWN) { + printf("### Unknown flash ID %08lX %08lX at address %08lX ###\n", + addr[0], addr[1], (ulong)addr); + size = 0; + *addr = INTEL_RESET; /* Reset bank to Read Array mode */ + break; + } + flash_info[i].sector_count = sect_count; + flash_info[i].size = bank_size = sect_size * sect_count; + size += bank_size; + sect_start = (ulong)addr; + for (j = 0; j < sect_count; j++) { + addr = (vu_long *)sect_start; + flash_info[i].start[j] = sect_start; + flash_info[i].protect[j] = (addr[2] == 0x01010101); + sect_start += sect_size; + } + *addr = INTEL_RESET; /* Reset bank to Read Array mode */ + addr = (vu_long *)sect_start; + } + + if (size == 0) { /* Unknown flash, fill with hard-coded values */ + sect_start = CFG_FLASH_BASE; + for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { + flash_info[i].flash_id = FLASH_UNKNOWN; + flash_info[i].size = CFG_FLASH_SIZE / CFG_MAX_FLASH_BANKS; + flash_info[i].sector_count = sect_count; + for (j = 0; j < sect_count; j++) { + flash_info[i].start[j] = sect_start; + flash_info[i].protect[j] = 0; + sect_start += sect_size; + } + } + size = CFG_FLASH_SIZE; + } + else + for (i = nbanks; i < CFG_MAX_FLASH_BANKS; i++) { + flash_info[i].flash_id = FLASH_UNKNOWN; + flash_info[i].size = 0; + flash_info[i].sector_count = 0; + } + +#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]); +#endif + +#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 + 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; + 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"); +} + +/*----------------------------------------------------------------------- + */ +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"); + } + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect<=s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + vu_long *addr = (vu_long *)(info->start[sect]); + + last = start = get_timer (0); + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + /* Clear Status Register */ + *addr = INTEL_CLEAR; + /* Single Block Erase Command */ + *addr = INTEL_ERASE; + /* Confirm */ + *addr = INTEL_CONFIRM; + + if((info->flash_id & FLASH_TYPEMASK) != FLASH_LH28F016SCT) { + /* Resume Command, as per errata update */ + *addr = INTEL_CONFIRM; + } + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) { + if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) { + printf ("Timeout\n"); + *addr = INTEL_RESET; /* reset bank */ + return 1; + } + /* show that we're waiting */ + if ((now - last) > 1000) { /* every second */ + putc ('.'); + last = now; + } + } + + if (*addr != INTEL_OK) { + printf("Block erase failed at %08X, CSR=%08X\n", + (uint)addr, (uint)*addr); + *addr = INTEL_RESET; /* reset bank */ + return 1; + } + + /* reset to read mode */ + *addr = INTEL_RESET; + } + } + + printf (" done\n"); + return 0; +} + +/*----------------------------------------------------------------------- + * 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) +{ + ulong start; + int rc = 0; + int flag; + vu_long *addr = (vu_long *)dest; + + /* Check if Flash is (sufficiently) erased */ + if ((*addr & data) != data) { + return (2); + } + + *addr = INTEL_CLEAR; /* Clear status register */ + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + /* Write Command */ + *addr = INTEL_PROGRAM; + + /* Write Data */ + *addr = data; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* data polling for D7 */ + start = get_timer (0); + while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + printf("Write timed out\n"); + rc = 1; + break; + } + } + if (*addr != INTEL_OK) { + printf ("Write failed at %08X, CSR=%08X\n", (uint)addr, (uint)*addr); + rc = 1; + } + + *addr = INTEL_RESET; /* Reset to read array mode */ + + return rc; +} + +/*----------------------------------------------------------------------- + * 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 */ + + *(vu_long *)wp = INTEL_RESET; /* Reset to read array mode */ + + /* + * 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); + } + + rc = write_word(info, wp, data); + + return rc; +} + +/*----------------------------------------------------------------------- + * Set/Clear sector's lock bit, returns: + * 0 - OK + * 1 - Error (timeout, voltage problems, etc.) + */ +int flash_real_protect(flash_info_t *info, long sector, int prot) +{ + ulong start; + int i; + int rc = 0; + vu_long *addr = (vu_long *)(info->start[sector]); + int flag = disable_interrupts(); + + *addr = INTEL_CLEAR; /* Clear status register */ + if (prot) { /* Set sector lock bit */ + *addr = INTEL_LOCKBIT; /* Sector lock bit */ + *addr = INTEL_PROTECT; /* set */ + } + else { /* Clear sector lock bit */ + *addr = INTEL_LOCKBIT; /* All sectors lock bits */ + *addr = INTEL_CONFIRM; /* clear */ + } + + start = get_timer(0); + while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) { + if (get_timer(start) > CFG_FLASH_UNLOCK_TOUT) { + printf("Flash lock bit operation timed out\n"); + rc = 1; + break; + } + } + + if (*addr != INTEL_OK) { + printf("Flash lock bit operation failed at %08X, CSR=%08X\n", + (uint)addr, (uint)*addr); + rc = 1; + } + + if (!rc) + info->protect[sector] = prot; + + /* + * Clear lock bit command clears all sectors lock bits, so + * we have to restore lock bits of protected sectors. + */ + if (!prot) + for (i = 0; i < info->sector_count; i++) + if (info->protect[i]) { + addr = (vu_long *)(info->start[i]); + *addr = INTEL_LOCKBIT; /* Sector lock bit */ + *addr = INTEL_PROTECT; /* set */ + udelay(CFG_FLASH_LOCK_TOUT * 1000); + } + + if (flag) + enable_interrupts(); + + *addr = INTEL_RESET; /* Reset to read array mode */ + + return rc; +} diff --git a/board/freescale/mpc8260ads/mpc8260ads.c b/board/freescale/mpc8260ads/mpc8260ads.c new file mode 100644 index 0000000000..93550e2ad0 --- /dev/null +++ b/board/freescale/mpc8260ads/mpc8260ads.c @@ -0,0 +1,546 @@ +/* + * (C) Copyright 2001-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Modified during 2001 by + * Advanced Communications Technologies (Australia) Pty. Ltd. + * Howard Walker, Tuong Vu-Dinh + * + * (C) Copyright 2001, Stuart Hughes, Lineo Inc, stuarth@lineo.com + * Added support for the 16M dram simm on the 8260ads boards + * + * (C) Copyright 2003-2004 Arabella Software Ltd. + * Yuli Barcohen <yuli@arabellasw.com> + * Added support for SDRAM DIMMs SPD EEPROM, MII, Ethernet PHY init. + * + * Copyright (c) 2005 MontaVista Software, Inc. + * Vitaly Bordug <vbordug@ru.mvista.com> + * Added support for PCI. + * + * 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 <ioports.h> +#include <mpc8260.h> +#include <asm/m8260_pci.h> +#include <i2c.h> +#include <spd.h> +#include <miiphy.h> +#ifdef CONFIG_PCI +#include <pci.h> +#endif + +/* + * I/O Port configuration table + * + * if conf is 1, then that port pin will be configured at boot time + * according to the five values podr/pdir/ppar/psor/pdat for that entry + */ + +#define CFG_FCC1 (CONFIG_ETHER_INDEX == 1) +#define CFG_FCC2 (CONFIG_ETHER_INDEX == 2) +#define CFG_FCC3 (CONFIG_ETHER_INDEX == 3) + +const iop_conf_t iop_conf_tab[4][32] = { + + /* Port A configuration */ + { /* conf ppar psor pdir podr pdat */ + /* PA31 */ { CFG_FCC1, 1, 1, 0, 0, 0 }, /* FCC1 MII COL */ + /* PA30 */ { CFG_FCC1, 1, 1, 0, 0, 0 }, /* FCC1 MII CRS */ + /* PA29 */ { CFG_FCC1, 1, 1, 1, 0, 0 }, /* FCC1 MII TX_ER */ + /* PA28 */ { CFG_FCC1, 1, 1, 1, 0, 0 }, /* FCC1 MII TX_EN */ + /* PA27 */ { CFG_FCC1, 1, 1, 0, 0, 0 }, /* FCC1 MII RX_DV */ + /* PA26 */ { CFG_FCC1, 1, 1, 0, 0, 0 }, /* FCC1 MII RX_ER */ + /* PA25 */ { 0, 0, 0, 0, 0, 0 }, /* PA25 */ + /* PA24 */ { 0, 0, 0, 0, 0, 0 }, /* PA24 */ + /* PA23 */ { 0, 0, 0, 0, 0, 0 }, /* PA23 */ + /* PA22 */ { 0, 0, 0, 0, 0, 0 }, /* PA22 */ + /* PA21 */ { CFG_FCC1, 1, 0, 1, 0, 0 }, /* FCC1 MII TxD[3] */ + /* PA20 */ { CFG_FCC1, 1, 0, 1, 0, 0 }, /* FCC1 MII TxD[2] */ + /* PA19 */ { CFG_FCC1, 1, 0, 1, 0, 0 }, /* FCC1 MII TxD[1] */ + /* PA18 */ { CFG_FCC1, 1, 0, 1, 0, 0 }, /* FCC1 MII TxD[0] */ + /* PA17 */ { CFG_FCC1, 1, 0, 0, 0, 0 }, /* FCC1 MII RxD[0] */ + /* PA16 */ { CFG_FCC1, 1, 0, 0, 0, 0 }, /* FCC1 MII RxD[1] */ + /* PA15 */ { CFG_FCC1, 1, 0, 0, 0, 0 }, /* FCC1 MII RxD[2] */ + /* PA14 */ { CFG_FCC1, 1, 0, 0, 0, 0 }, /* FCC1 MII RxD[3] */ + /* PA13 */ { 0, 0, 0, 0, 0, 0 }, /* PA13 */ + /* PA12 */ { 0, 0, 0, 0, 0, 0 }, /* PA12 */ + /* PA11 */ { 0, 0, 0, 0, 0, 0 }, /* PA11 */ + /* PA10 */ { 0, 0, 0, 0, 0, 0 }, /* PA10 */ + /* PA9 */ { 0, 0, 0, 0, 0, 0 }, /* PA9 */ + /* PA8 */ { 0, 0, 0, 0, 0, 0 }, /* PA8 */ + /* PA7 */ { 0, 0, 0, 1, 0, 0 }, /* PA7 */ + /* PA6 */ { 0, 0, 0, 0, 0, 0 }, /* PA6 */ + /* PA5 */ { 0, 0, 0, 1, 0, 0 }, /* PA5 */ + /* PA4 */ { 0, 0, 0, 1, 0, 0 }, /* PA4 */ + /* PA3 */ { 0, 0, 0, 1, 0, 0 }, /* PA3 */ + /* PA2 */ { 0, 0, 0, 1, 0, 0 }, /* PA2 */ + /* PA1 */ { 0, 0, 0, 0, 0, 0 }, /* PA1 */ + /* PA0 */ { 0, 0, 0, 1, 0, 0 } /* PA0 */ + }, + + /* Port B configuration */ + { /* conf ppar psor pdir podr pdat */ + /* PB31 */ { CFG_FCC2, 1, 0, 1, 0, 0 }, /* FCC2 MII TX_ER */ + /* PB30 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */ + /* PB29 */ { CFG_FCC2, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */ + /* PB28 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */ + /* PB27 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */ + /* PB26 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */ + /* PB25 */ { CFG_FCC2, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */ + /* PB24 */ { CFG_FCC2, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */ + /* PB23 */ { CFG_FCC2, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */ + /* PB22 */ { CFG_FCC2, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */ + /* PB21 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */ + /* PB20 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */ + /* PB19 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */ + /* PB18 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */ + /* PB17 */ { CFG_FCC3, 1, 0, 0, 0, 0 }, /* FCC3:RX_DIV */ + /* PB16 */ { CFG_FCC3, 1, 0, 0, 0, 0 }, /* FCC3:RX_ERR */ + /* PB15 */ { CFG_FCC3, 1, 0, 1, 0, 0 }, /* FCC3:TX_ERR */ + /* PB14 */ { CFG_FCC3, 1, 0, 1, 0, 0 }, /* FCC3:TX_EN */ + /* PB13 */ { CFG_FCC3, 1, 0, 0, 0, 0 }, /* FCC3:COL */ + /* PB12 */ { CFG_FCC3, 1, 0, 0, 0, 0 }, /* FCC3:CRS */ + /* PB11 */ { CFG_FCC3, 1, 0, 0, 0, 0 }, /* FCC3:RXD */ + /* PB10 */ { CFG_FCC3, 1, 0, 0, 0, 0 }, /* FCC3:RXD */ + /* PB9 */ { CFG_FCC3, 1, 0, 0, 0, 0 }, /* FCC3:RXD */ + /* PB8 */ { CFG_FCC3, 1, 0, 0, 0, 0 }, /* FCC3:RXD */ + /* PB7 */ { CFG_FCC3, 1, 0, 1, 0, 0 }, /* FCC3:TXD */ + /* PB6 */ { CFG_FCC3, 1, 0, 1, 0, 0 }, /* FCC3:TXD */ + /* PB5 */ { CFG_FCC3, 1, 0, 1, 0, 0 }, /* FCC3:TXD */ + /* PB4 */ { CFG_FCC3, 1, 0, 1, 0, 0 }, /* FCC3:TXD */ + /* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */ + }, + + /* Port C */ + { /* conf ppar psor pdir podr pdat */ + /* PC31 */ { 0, 0, 0, 0, 0, 0 }, /* PC31 */ + /* PC30 */ { 0, 0, 0, 0, 0, 0 }, /* PC30 */ + /* PC29 */ { 0, 0, 0, 0, 0, 0 }, /* PC29 */ + /* PC28 */ { 0, 0, 0, 0, 0, 0 }, /* PC28 */ + /* PC27 */ { 0, 0, 0, 0, 0, 0 }, /* PC27 */ + /* PC26 */ { 0, 0, 0, 0, 0, 0 }, /* PC26 */ + /* PC25 */ { 0, 0, 0, 0, 0, 0 }, /* PC25 */ + /* PC24 */ { 0, 0, 0, 0, 0, 0 }, /* PC24 */ + /* PC23 */ { 0, 0, 0, 0, 0, 0 }, /* PC23 */ + /* PC22 */ { CFG_FCC1, 1, 0, 0, 0, 0 }, /* FCC1 MII Tx Clock (CLK10) */ + /* PC21 */ { CFG_FCC1, 1, 0, 0, 0, 0 }, /* FCC1 MII Rx Clock (CLK11) */ + /* PC20 */ { 0, 0, 0, 0, 0, 0 }, /* PC20 */ +#if CONFIG_ADSTYPE == CFG_8272ADS + /* PC19 */ { 1, 0, 0, 1, 0, 0 }, /* FETHMDC */ + /* PC18 */ { 1, 0, 0, 0, 0, 0 }, /* FETHMDIO */ + /* PC17 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII Rx Clock (CLK15) */ + /* PC16 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII Tx Clock (CLK16) */ +#else + /* PC19 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII Rx Clock (CLK13) */ + /* PC18 */ { CFG_FCC2, 1, 0, 0, 0, 0 }, /* FCC2 MII Tx Clock (CLK14) */ + /* PC17 */ { 0, 0, 0, 0, 0, 0 }, /* PC17 */ + /* PC16 */ { 0, 0, 0, 0, 0, 0 }, /* PC16 */ +#endif /* CONFIG_ADSTYPE == CFG_8272ADS */ + /* PC15 */ { 0, 0, 0, 0, 0, 0 }, /* PC15 */ + /* PC14 */ { 0, 0, 0, 0, 0, 0 }, /* PC14 */ + /* PC13 */ { 0, 0, 0, 0, 0, 0 }, /* PC13 */ + /* PC12 */ { 0, 0, 0, 0, 0, 0 }, /* PC12 */ + /* PC11 */ { 0, 0, 0, 0, 0, 0 }, /* PC11 */ +#if CONFIG_ADSTYPE == CFG_8272ADS + /* PC10 */ { 0, 0, 0, 0, 0, 0 }, /* PC10 */ + /* PC9 */ { 0, 0, 0, 0, 0, 0 }, /* PC9 */ +#else + /* PC10 */ { 1, 0, 0, 1, 0, 0 }, /* FETHMDC */ + /* PC9 */ { 1, 0, 0, 0, 0, 0 }, /* FETHMDIO */ +#endif /* CONFIG_ADSTYPE == CFG_8272ADS */ + /* PC8 */ { 0, 0, 0, 0, 0, 0 }, /* PC8 */ + /* PC7 */ { 0, 0, 0, 0, 0, 0 }, /* PC7 */ + /* PC6 */ { 0, 0, 0, 0, 0, 0 }, /* PC6 */ + /* PC5 */ { 0, 0, 0, 0, 0, 0 }, /* PC5 */ + /* PC4 */ { 0, 0, 0, 0, 0, 0 }, /* PC4 */ + /* PC3 */ { 0, 0, 0, 0, 0, 0 }, /* PC3 */ + /* PC2 */ { 0, 0, 0, 0, 0, 0 }, /* PC2 */ + /* PC1 */ { 0, 0, 0, 0, 0, 0 }, /* PC1 */ + /* PC0 */ { 0, 0, 0, 0, 0, 0 }, /* PC0 */ + }, + + /* Port D */ + { /* conf ppar psor pdir podr pdat */ + /* PD31 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 UART RxD */ + /* PD30 */ { 1, 1, 1, 1, 0, 0 }, /* SCC1 UART TxD */ + /* PD29 */ { 0, 0, 0, 0, 0, 0 }, /* PD29 */ + /* PD28 */ { 0, 1, 0, 0, 0, 0 }, /* PD28 */ + /* PD27 */ { 0, 1, 1, 1, 0, 0 }, /* PD27 */ + /* PD26 */ { 0, 0, 0, 1, 0, 0 }, /* PD26 */ + /* PD25 */ { 0, 0, 0, 1, 0, 0 }, /* PD25 */ + /* PD24 */ { 0, 0, 0, 1, 0, 0 }, /* PD24 */ + /* PD23 */ { 0, 0, 0, 1, 0, 0 }, /* PD23 */ + /* PD22 */ { 0, 0, 0, 1, 0, 0 }, /* PD22 */ + /* PD21 */ { 0, 0, 0, 1, 0, 0 }, /* PD21 */ + /* PD20 */ { 0, 0, 0, 1, 0, 0 }, /* PD20 */ + /* PD19 */ { 0, 0, 0, 1, 0, 0 }, /* PD19 */ + /* PD18 */ { 0, 0, 0, 1, 0, 0 }, /* PD18 */ + /* PD17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */ + /* PD16 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXPRTY */ + /* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */ + /* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */ + /* PD13 */ { 0, 0, 0, 0, 0, 0 }, /* PD13 */ + /* PD12 */ { 0, 0, 0, 0, 0, 0 }, /* PD12 */ + /* PD11 */ { 0, 0, 0, 0, 0, 0 }, /* PD11 */ + /* PD10 */ { 0, 0, 0, 0, 0, 0 }, /* PD10 */ + /* PD9 */ { 0, 1, 0, 1, 0, 0 }, /* SMC1 TXD */ + /* PD8 */ { 0, 1, 0, 0, 0, 0 }, /* SMC1 RXD */ + /* PD7 */ { 0, 0, 0, 1, 0, 1 }, /* PD7 */ + /* PD6 */ { 0, 0, 0, 1, 0, 1 }, /* PD6 */ + /* PD5 */ { 0, 0, 0, 1, 0, 1 }, /* PD5 */ + /* PD4 */ { 0, 0, 0, 1, 0, 1 }, /* PD4 */ + /* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */ + } +}; + +void reset_phy (void) +{ + vu_long *bcsr = (vu_long *)CFG_BCSR; + + /* Reset the PHY */ +#if CFG_PHY_ADDR == 0 + bcsr[1] &= ~(FETHIEN1 | FETH1_RST); + udelay(2); + bcsr[1] |= FETH1_RST; +#else + bcsr[3] &= ~(FETHIEN2 | FETH2_RST); + udelay(2); + bcsr[3] |= FETH2_RST; +#endif /* CFG_PHY_ADDR == 0 */ + udelay(1000); +#ifdef CONFIG_MII +#if CONFIG_ADSTYPE >= CFG_PQ2FADS + /* + * Do not bypass Rx/Tx (de)scrambler (fix configuration error) + * Enable autonegotiation. + */ + bb_miiphy_write(NULL, CFG_PHY_ADDR, 16, 0x610); + bb_miiphy_write(NULL, CFG_PHY_ADDR, PHY_BMCR, + PHY_BMCR_AUTON | PHY_BMCR_RST_NEG); +#else + /* + * Ethernet PHY is configured (by means of configuration pins) + * to work at 10Mb/s only. We reconfigure it using MII + * to advertise all capabilities, including 100Mb/s, and + * restart autonegotiation. + */ + + /* Advertise all capabilities */ + bb_miiphy_write(NULL, CFG_PHY_ADDR, PHY_ANAR, 0x01E1); + + /* Do not bypass Rx/Tx (de)scrambler */ + bb_miiphy_write(NULL, CFG_PHY_ADDR, PHY_DCR, 0x0000); + + bb_miiphy_write(NULL, CFG_PHY_ADDR, PHY_BMCR, + PHY_BMCR_AUTON | PHY_BMCR_RST_NEG); +#endif /* CONFIG_ADSTYPE == CFG_PQ2FADS */ +#endif /* CONFIG_MII */ +} + +#ifdef CONFIG_PCI +typedef struct pci_ic_s { + unsigned long pci_int_stat; + unsigned long pci_int_mask; +}pci_ic_t; +#endif + +int board_early_init_f (void) +{ + vu_long *bcsr = (vu_long *)CFG_BCSR; + +#ifdef CONFIG_PCI + volatile pci_ic_t* pci_ic = (pci_ic_t *) CFG_PCI_INT; + + /* mask alll the PCI interrupts */ + pci_ic->pci_int_mask |= 0xfff00000; +#endif +#if (CONFIG_CONS_INDEX == 1) || (CONFIG_KGDB_INDEX == 1) + bcsr[1] &= ~RS232EN_1; +#endif +#if (CONFIG_CONS_INDEX > 1) || (CONFIG_KGDB_INDEX > 1) + bcsr[1] &= ~RS232EN_2; +#endif + +#if CONFIG_ADSTYPE != CFG_8260ADS /* PCI mode can be selected */ +#if CONFIG_ADSTYPE == CFG_PQ2FADS + if ((bcsr[3] & BCSR_PCI_MODE) == 0) /* PCI mode selected by JP9 */ +#endif /* CONFIG_ADSTYPE == CFG_PQ2FADS */ + { + volatile immap_t *immap = (immap_t *) CFG_IMMR; + + immap->im_clkrst.car_sccr |= M826X_SCCR_PCI_MODE_EN; + immap->im_siu_conf.sc_siumcr = + (immap->im_siu_conf.sc_siumcr & ~SIUMCR_LBPC11) + | SIUMCR_LBPC01; + } +#endif /* CONFIG_ADSTYPE != CFG_8260ADS */ + + return 0; +} + +#define ns2clk(ns) (ns / (1000000000 / CONFIG_8260_CLKIN) + 1) + +long int initdram (int board_type) +{ +#if CONFIG_ADSTYPE == CFG_PQ2FADS + long int msize = 32; +#elif CONFIG_ADSTYPE == CFG_8272ADS + long int msize = 64; +#else + long int msize = 16; +#endif + +#ifndef CFG_RAMBOOT + volatile immap_t *immap = (immap_t *) CFG_IMMR; + volatile memctl8260_t *memctl = &immap->im_memctl; + volatile uchar *ramaddr, c = 0xff; + uint or; + uint psdmr; + uint psrt; + + int i; + + immap->im_siu_conf.sc_ppc_acr = 0x00000002; + immap->im_siu_conf.sc_ppc_alrh = 0x01267893; + immap->im_siu_conf.sc_tescr1 = 0x00004000; + + memctl->memc_mptpr = CFG_MPTPR; +#ifdef CFG_LSDRAM_BASE + /* + Initialise local bus SDRAM only if the pins + are configured as local bus pins and not as PCI. + The configuration is determined by the HRCW. + */ + if ((immap->im_siu_conf.sc_siumcr & SIUMCR_LBPC11) == SIUMCR_LBPC00) { + memctl->memc_lsrt = CFG_LSRT; +#if CONFIG_ADSTYPE == CFG_PQ2FADS /* CS3 */ + memctl->memc_or3 = 0xFF803280; + memctl->memc_br3 = CFG_LSDRAM_BASE | 0x00001861; +#else /* CS4 */ + memctl->memc_or4 = 0xFFC01480; + memctl->memc_br4 = CFG_LSDRAM_BASE | 0x00001861; +#endif /* CONFIG_ADSTYPE == CFG_PQ2FADS */ + memctl->memc_lsdmr = CFG_LSDMR | 0x28000000; + ramaddr = (uchar *) CFG_LSDRAM_BASE; + *ramaddr = c; + memctl->memc_lsdmr = CFG_LSDMR | 0x08000000; + for (i = 0; i < 8; i++) + *ramaddr = c; + memctl->memc_lsdmr = CFG_LSDMR | 0x18000000; + *ramaddr = c; + memctl->memc_lsdmr = CFG_LSDMR | 0x40000000; + } +#endif /* CFG_LSDRAM_BASE */ + + /* Init 60x bus SDRAM */ +#ifdef CONFIG_SPD_EEPROM + { + spd_eeprom_t spd; + uint pbi, bsel, rowst, lsb, tmp; + + i2c_read (CONFIG_SPD_ADDR, 0, 1, (uchar *) & spd, sizeof (spd)); + + /* Bank-based interleaving is not supported for physical bank + sizes greater than 128MB which is encoded as 0x20 in SPD + */ + pbi = (spd.row_dens > 32) ? 1 : CONFIG_SDRAM_PBI; + msize = spd.nrows * (4 * spd.row_dens); /* Mixed size not supported */ + or = ~(msize - 1) << 20; /* SDAM */ + switch (spd.nbanks) { /* BPD */ + case 2: + bsel = 1; + break; + case 4: + bsel = 2; + or |= 0x00002000; + break; + case 8: + bsel = 3; + or |= 0x00004000; + break; + } + lsb = 3; /* For 64-bit port, lsb is 3 bits */ + + if (pbi) { /* Bus partition depends on interleaving */ + rowst = 32 - (spd.nrow_addr + spd.ncol_addr + bsel + lsb); + or |= (rowst << 9); /* ROWST */ + } else { + rowst = 32 - (spd.nrow_addr + spd.ncol_addr + lsb); + or |= ((rowst * 2 - 12) << 9); /* ROWST */ + } + or |= ((spd.nrow_addr - 9) << 6); /* NUMR */ + + psdmr = (pbi << 31); /* PBI */ + /* Bus multiplexing parameters */ + tmp = 32 - (lsb + spd.nrow_addr); /* Tables 10-19 and 10-20 */ + psdmr |= ((tmp - (rowst - 5) - 13) << 24); /* SDAM */ + psdmr |= ((tmp - 3 - 12) << 21); /* BSMA */ + + tmp = (31 - lsb - 10) - tmp; + /* Pin connected to SDA10 is (31 - lsb - 10). + rowst is multiplexed over (32 - (lsb + spd.nrow_addr)), + so (rowst + tmp) alternates with AP. + */ + if (pbi) /* Table 10-7 */ + psdmr |= ((10 - (rowst + tmp)) << 18); /* SDA10 */ + else + psdmr |= ((12 - (rowst + tmp)) << 18); /* SDA10 */ + + /* SDRAM device-specific parameters */ + tmp = ns2clk (70); /* Refresh recovery is not in SPD, so assume 70ns */ + switch (tmp) { /* RFRC */ + case 1: + case 2: + psdmr |= (1 << 15); + break; + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + psdmr |= ((tmp - 2) << 15); + break; + default: + psdmr |= (7 << 15); + } + psdmr |= (ns2clk (spd.trp) % 8 << 12); /* PRETOACT */ + psdmr |= (ns2clk (spd.trcd) % 8 << 9); /* ACTTORW */ + /* BL=0 because for 64-bit SDRAM burst length must be 4 */ + /* LDOTOPRE ??? */ + for (i = 0, tmp = spd.write_lat; (i < 4) && ((tmp & 1) == 0); i++) + tmp >>= 1; + switch (i) { /* WRC */ + case 0: + case 1: + psdmr |= (1 << 4); + break; + case 2: + case 3: + psdmr |= (i << 4); + break; + } + /* EAMUX=0 - no external address multiplexing */ + /* BUFCMD=0 - no external buffers */ + for (i = 1, tmp = spd.cas_lat; (i < 3) && ((tmp & 1) == 0); i++) + tmp >>= 1; + psdmr |= i; /* CL */ + + switch (spd.refresh & 0x7F) { + case 1: + tmp = 3900; + break; + case 2: + tmp = 7800; + break; + case 3: + tmp = 31300; + break; + case 4: + tmp = 62500; + break; + case 5: + tmp = 125000; + break; + default: + tmp = 15625; + } + psrt = tmp / (1000000000 / CONFIG_8260_CLKIN * + ((memctl->memc_mptpr >> 8) + 1)) - 1; +#ifdef SPD_DEBUG + printf ("\nDIMM type: %-18.18s\n", spd.mpart); + printf ("SPD size: %d\n", spd.info_size); + printf ("EEPROM size: %d\n", 1 << spd.chip_size); + printf ("Memory type: %d\n", spd.mem_type); + printf ("Row addr: %d\n", spd.nrow_addr); + printf ("Column addr: %d\n", spd.ncol_addr); + printf ("# of rows: %d\n", spd.nrows); + printf ("Row density: %d\n", spd.row_dens); + printf ("# of banks: %d\n", spd.nbanks); + printf ("Data width: %d\n", + 256 * spd.dataw_msb + spd.dataw_lsb); + printf ("Chip width: %d\n", spd.primw); + printf ("Refresh rate: %02X\n", spd.refresh); + printf ("CAS latencies: %02X\n", spd.cas_lat); + printf ("Write latencies: %02X\n", spd.write_lat); + printf ("tRP: %d\n", spd.trp); + printf ("tRCD: %d\n", spd.trcd); + + printf ("OR=%X, PSDMR=%08X, PSRT=%0X\n", or, psdmr, psrt); +#endif /* SPD_DEBUG */ + } +#else /* !CONFIG_SPD_EEPROM */ + or = CFG_OR2; + psdmr = CFG_PSDMR; + psrt = CFG_PSRT; +#endif /* CONFIG_SPD_EEPROM */ + memctl->memc_psrt = psrt; + memctl->memc_or2 = or; + memctl->memc_br2 = CFG_SDRAM_BASE | 0x00000041; + ramaddr = (uchar *) CFG_SDRAM_BASE; + memctl->memc_psdmr = psdmr | 0x28000000; /* Precharge all banks */ + *ramaddr = c; + memctl->memc_psdmr = psdmr | 0x08000000; /* CBR refresh */ + for (i = 0; i < 8; i++) + *ramaddr = c; + + memctl->memc_psdmr = psdmr | 0x18000000; /* Mode Register write */ + *ramaddr = c; + memctl->memc_psdmr = psdmr | 0x40000000; /* Refresh enable */ + *ramaddr = c; +#endif /* CFG_RAMBOOT */ + + /* return total 60x bus SDRAM size */ + return (msize * 1024 * 1024); +} + +int checkboard (void) +{ +#if CONFIG_ADSTYPE == CFG_8260ADS + puts ("Board: Motorola MPC8260ADS\n"); +#elif CONFIG_ADSTYPE == CFG_8266ADS + puts ("Board: Motorola MPC8266ADS\n"); +#elif CONFIG_ADSTYPE == CFG_PQ2FADS + puts ("Board: Motorola PQ2FADS-ZU\n"); +#elif CONFIG_ADSTYPE == CFG_8272ADS + puts ("Board: Motorola MPC8272ADS\n"); +#else + puts ("Board: unknown\n"); +#endif + return 0; +} + +#ifdef CONFIG_PCI +struct pci_controller hose; + +extern void pci_mpc8250_init(struct pci_controller *); + +void pci_init_board(void) +{ + pci_mpc8250_init(&hose); +} +#endif |