diff options
author | wdenk <wdenk> | 2004-10-10 21:21:55 +0000 |
---|---|---|
committer | wdenk <wdenk> | 2004-10-10 21:21:55 +0000 |
commit | 03f5c55021c2d6297e66cc11bfea75f149a5d71c (patch) | |
tree | 658bdbc75b90b7a122c061fa2aca6d6eb94dfb67 /board | |
parent | cf33678e51e02143ed67850b3f13646fd51fb489 (diff) | |
download | u-boot-imx-03f5c55021c2d6297e66cc11bfea75f149a5d71c.zip u-boot-imx-03f5c55021c2d6297e66cc11bfea75f149a5d71c.tar.gz u-boot-imx-03f5c55021c2d6297e66cc11bfea75f149a5d71c.tar.bz2 |
Patches by Jon Loeliger, 24 Aug 2004:
- Add support for the MPC8541 and MPC8555 CDS boards
- Cleanup eth?addr handling: make dependent on CONFIG_ETH?ADDR
Diffstat (limited to 'board')
-rw-r--r-- | board/cds/common/cadmus.c | 95 | ||||
-rw-r--r-- | board/cds/common/cadmus.h | 54 | ||||
-rw-r--r-- | board/cds/common/eeprom.c | 60 | ||||
-rw-r--r-- | board/cds/common/eeprom.h | 50 | ||||
-rw-r--r-- | board/cds/mpc8541cds/Makefile | 51 | ||||
-rw-r--r-- | board/cds/mpc8541cds/config.mk | 30 | ||||
-rw-r--r-- | board/cds/mpc8541cds/init.S | 255 | ||||
-rw-r--r-- | board/cds/mpc8541cds/mpc8541cds.c | 373 | ||||
-rw-r--r-- | board/cds/mpc8541cds/u-boot.lds | 147 | ||||
-rw-r--r-- | board/cds/mpc8555cds/Makefile | 51 | ||||
-rw-r--r-- | board/cds/mpc8555cds/config.mk | 30 | ||||
-rw-r--r-- | board/cds/mpc8555cds/init.S | 255 | ||||
-rw-r--r-- | board/cds/mpc8555cds/mpc8555cds.c | 371 | ||||
-rw-r--r-- | board/cds/mpc8555cds/u-boot.lds | 147 | ||||
-rw-r--r-- | board/mpc8540ads/flash.c | 537 | ||||
-rw-r--r-- | board/mpc8560ads/flash.c | 537 |
16 files changed, 1969 insertions, 1074 deletions
diff --git a/board/cds/common/cadmus.c b/board/cds/common/cadmus.c new file mode 100644 index 0000000..5f86de5 --- /dev/null +++ b/board/cds/common/cadmus.c @@ -0,0 +1,95 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * + * 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> + + +/* + * CADMUS Board System Registers + */ +#ifndef CFG_CADMUS_BASE_REG +#define CFG_CADMUS_BASE_REG (CADMUS_BASE_ADDR + 0x4000) +#endif + +typedef struct cadmus_reg { + u_char cm_ver; /* Board version */ + u_char cm_csr; /* General control/status */ + u_char cm_rst; /* Reset control */ + u_char cm_hsclk; /* High speed clock */ + u_char cm_hsxclk; /* High speed clock extended */ + u_char cm_led; /* LED data */ + u_char cm_pci; /* PCI control/status */ + u_char cm_dma; /* DMA control */ + u_char cm_reserved[248]; /* Total 256 bytes */ +} cadmus_reg_t; + + +unsigned int +get_board_version(void) +{ + volatile cadmus_reg_t *cadmus = (cadmus_reg_t *)CFG_CADMUS_BASE_REG; + + return cadmus->cm_ver; +} + + +unsigned long +get_clock_freq(void) +{ + volatile cadmus_reg_t *cadmus = (cadmus_reg_t *)CFG_CADMUS_BASE_REG; + + uint pci1_speed = (cadmus->cm_pci >> 2) & 0x3; /* PSPEED in [4:5] */ + + if (pci1_speed == 0) { + return 33000000; + } else if (pci1_speed == 1) { + return 66000000; + } else { + /* Really, unknown. Be safe? */ + return 33000000; + } +} + + +unsigned int +get_pci_slot(void) +{ + volatile cadmus_reg_t *cadmus = (cadmus_reg_t *)CFG_CADMUS_BASE_REG; + + /* + * PCI slot in USER bits CSR[6:7] by convention. + */ + return ((cadmus->cm_csr >> 6) & 0x3) + 1; +} + + +unsigned int +get_pci_dual(void) +{ + volatile cadmus_reg_t *cadmus = (cadmus_reg_t *)CFG_CADMUS_BASE_REG; + + /* + * PCI DUAL in CM_PCI[3] + */ + return cadmus->cm_pci & 0x10; +} diff --git a/board/cds/common/cadmus.h b/board/cds/common/cadmus.h new file mode 100644 index 0000000..217ea64 --- /dev/null +++ b/board/cds/common/cadmus.h @@ -0,0 +1,54 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * + * 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 + */ + +#ifndef __CADMUS_H_ +#define __CADMUS_H_ + + +/* + * CADMUS Board System Register interface. + */ + +/* + * Returns board version register. + */ +extern unsigned int get_board_version(void); + +/* + * Returns either 33000000 or 66000000 as the SYS_CLK_FREQ. + */ +extern unsigned long get_clock_freq(void); + + +/* + * Returns 1 - 4, as found in the USER CSR[6:7] bits. + */ +extern unsigned int get_pci_slot(void); + + +/* + * Returns PCI DUAL as found in CM_PCI[3]. + */ +extern unsigned int get_pci_dual(void); + + +#endif /* __CADMUS_H_ */ diff --git a/board/cds/common/eeprom.c b/board/cds/common/eeprom.c new file mode 100644 index 0000000..5034e0c --- /dev/null +++ b/board/cds/common/eeprom.c @@ -0,0 +1,60 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * + * 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 <i2c.h> + +#include "eeprom.h" + + +typedef struct { + char idee_pcbid[4]; /* "CCID" for CDC v1.X */ + u8 idee_major; + u8 idee_minor; + char idee_serial[10]; + char idee_errata[2]; + char idee_date[8]; /* yyyymmdd */ + /* The rest of the EEPROM space is reserved */ +} id_eeprom_t; + + +unsigned int +get_cpu_board_revision(void) +{ + uint major = 0; + uint minor = 0; + + id_eeprom_t id_eeprom; + + i2c_read(CFG_I2C_EEPROM_ADDR, 0, 2, + (uchar *) &id_eeprom, sizeof(id_eeprom)); + + major = id_eeprom.idee_major; + minor = id_eeprom.idee_minor; + + if (major == 0xff && minor == 0xff) { + major = minor = 0; + } + + return MPC85XX_CPU_BOARD_REV(major,minor); +} diff --git a/board/cds/common/eeprom.h b/board/cds/common/eeprom.h new file mode 100644 index 0000000..12a0789 --- /dev/null +++ b/board/cds/common/eeprom.h @@ -0,0 +1,50 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * + * 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 + */ + +#ifndef __EEPROM_H_ +#define __EEPROM_H_ + + +/* + * EEPROM Board System Register interface. + */ + + +/* + * CPU Board Revision + */ +#define MPC85XX_CPU_BOARD_REV(maj, min) ((((maj)&0xff) << 8) | ((min) & 0xff)) +#define MPC85XX_CPU_BOARD_MAJOR(rev) (((rev) >> 8) & 0xff) +#define MPC85XX_CPU_BOARD_MINOR(rev) ((rev) & 0xff) + +#define MPC85XX_CPU_BOARD_REV_UNKNOWN MPC85XX_CPU_BOARD_REV(0,0) +#define MPC85XX_CPU_BOARD_REV_1_0 MPC85XX_CPU_BOARD_REV(1,0) +#define MPC85XX_CPU_BOARD_REV_1_1 MPC85XX_CPU_BOARD_REV(1,1) + +/* + * Returns CPU board revision register as a 16-bit value with + * the Major in the high byte, and Minor in the low byte. + */ +extern unsigned int get_cpu_board_revision(void); + + +#endif /* __CADMUS_H_ */ diff --git a/board/cds/mpc8541cds/Makefile b/board/cds/mpc8541cds/Makefile new file mode 100644 index 0000000..0d4abbd --- /dev/null +++ b/board/cds/mpc8541cds/Makefile @@ -0,0 +1,51 @@ +# +# Copyright 2004 Freescale Semiconductor. +# (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 \ + ../common/cadmus.o \ + ../common/eeprom.o + +SOBJS := init.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $(OBJS) + +clean: + rm -f $(OBJS) $(SOBJS) + +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) > $@ + +-include .depend + +######################################################################### diff --git a/board/cds/mpc8541cds/config.mk b/board/cds/mpc8541cds/config.mk new file mode 100644 index 0000000..17cc8bc --- /dev/null +++ b/board/cds/mpc8541cds/config.mk @@ -0,0 +1,30 @@ +# +# Copyright 2004 Freescale Semiconductor. +# +# 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 +# + +# +# mpc8541cds board +# +TEXT_BASE = 0xfff80000 + +PLATFORM_CPPFLAGS += -DCONFIG_E500=1 +PLATFORM_CPPFLAGS += -DCONFIG_MPC85xx=1 +PLATFORM_CPPFLAGS += -DCONFIG_MPC8541=1 diff --git a/board/cds/mpc8541cds/init.S b/board/cds/mpc8541cds/init.S new file mode 100644 index 0000000..53dcd0d --- /dev/null +++ b/board/cds/mpc8541cds/init.S @@ -0,0 +1,255 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * Copyright 2002,2003, Motorola Inc. + * + * 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 <mpc85xx.h> + + +/* + * TLB0 and TLB1 Entries + * + * Out of reset, TLB1's Entry 0 maps the highest 4K for CCSRBAR. + * However, CCSRBAR is then relocated to CFG_CCSRBAR right after + * these TLB entries are established. + * + * The TLB entries for DDR are dynamically setup in spd_sdram() + * and use TLB1 Entries 8 through 15 as needed according to the + * size of DDR memory. + * + * MAS0: tlbsel, esel, nv + * MAS1: valid, iprot, tid, ts, tsize + * MAS2: epn, sharen, x0, x1, w, i, m, g, e + * MAS3: rpn, u0-u3, ux, sx, uw, sw, ur, sr + */ + +#define entry_start \ + mflr r1 ; \ + bl 0f ; + +#define entry_end \ +0: mflr r0 ; \ + mtlr r1 ; \ + blr ; + + + .section .bootpg, "ax" + .globl tlb1_entry +tlb1_entry: + entry_start + + /* + * Number of TLB0 and TLB1 entries in the following table + */ + .long 13 + +#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR) + /* + * TLB0 4K Non-cacheable, guarded + * 0xff700000 4K Initial CCSRBAR mapping + * + * This ends up at a TLB0 Index==0 entry, and must not collide + * with other TLB0 Entries. + */ + .long TLB1_MAS0(0, 0, 0) + .long TLB1_MAS1(1, 0, 0, 0, 0) + .long TLB1_MAS2(E500_TLB_EPN(CFG_CCSRBAR_DEFAULT), 0,0,0,0,1,0,1,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_CCSRBAR_DEFAULT), 0,0,0,0,0,1,0,1,0,1) +#else +#error("Update the number of table entries in tlb1_entry") +#endif + + /* + * TLB0 16K Cacheable, non-guarded + * 0xd001_0000 16K Temporary Global data for initialization + * + * Use four 4K TLB0 entries. These entries must be cacheable + * as they provide the bootstrap memory before the memory + * controler and real memory have been configured. + * + * These entries end up at TLB0 Indicies 0x10, 0x14, 0x18 and 0x1c, + * and must not collide with other TLB0 entries. + */ + .long TLB1_MAS0(0, 0, 0) + .long TLB1_MAS1(1, 0, 0, 0, 0) + .long TLB1_MAS2(E500_TLB_EPN(CFG_INIT_RAM_ADDR), + 0,0,0,0,0,0,0,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_INIT_RAM_ADDR), + 0,0,0,0,0,1,0,1,0,1) + + .long TLB1_MAS0(0, 0, 0) + .long TLB1_MAS1(1, 0, 0, 0, 0) + .long TLB1_MAS2(E500_TLB_EPN(CFG_INIT_RAM_ADDR + 4 * 1024), + 0,0,0,0,0,0,0,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_INIT_RAM_ADDR + 4 * 1024), + 0,0,0,0,0,1,0,1,0,1) + + .long TLB1_MAS0(0, 0, 0) + .long TLB1_MAS1(1, 0, 0, 0, 0) + .long TLB1_MAS2(E500_TLB_EPN(CFG_INIT_RAM_ADDR + 8 * 1024), + 0,0,0,0,0,0,0,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_INIT_RAM_ADDR + 8 * 1024), + 0,0,0,0,0,1,0,1,0,1) + + .long TLB1_MAS0(0, 0, 0) + .long TLB1_MAS1(1, 0, 0, 0, 0) + .long TLB1_MAS2(E500_TLB_EPN(CFG_INIT_RAM_ADDR + 12 * 1024), + 0,0,0,0,0,0,0,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_INIT_RAM_ADDR + 12 * 1024), + 0,0,0,0,0,1,0,1,0,1) + + + /* + * TLB 0: 16M Non-cacheable, guarded + * 0xff000000 16M FLASH + * Out of reset this entry is only 4K. + */ + .long TLB1_MAS0(1, 0, 0) + .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_16M) + .long TLB1_MAS2(E500_TLB_EPN(CFG_FLASH_BASE), 0,0,0,0,1,0,1,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_FLASH_BASE), 0,0,0,0,0,1,0,1,0,1) + + /* + * TLB 1: 256M Non-cacheable, guarded + * 0x80000000 256M PCI1 MEM First half + */ + .long TLB1_MAS0(1, 1, 0) + .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M) + .long TLB1_MAS2(E500_TLB_EPN(CFG_PCI1_MEM_BASE), 0,0,0,0,1,0,1,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_PCI1_MEM_BASE), 0,0,0,0,0,1,0,1,0,1) + + /* + * TLB 2: 256M Non-cacheable, guarded + * 0x90000000 256M PCI1 MEM Second half + */ + .long TLB1_MAS0(1, 2, 0) + .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M) + .long TLB1_MAS2(E500_TLB_EPN(CFG_PCI1_MEM_BASE + 0x10000000), + 0,0,0,0,1,0,1,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_PCI1_MEM_BASE + 0x10000000), + 0,0,0,0,0,1,0,1,0,1) + + /* + * TLB 3: 256M Non-cacheable, guarded + * 0xa0000000 256M PCI2 MEM First half + */ + .long TLB1_MAS0(1, 3, 0) + .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M) + .long TLB1_MAS2(E500_TLB_EPN(CFG_PCI2_MEM_BASE), 0,0,0,0,1,0,1,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_PCI2_MEM_BASE), 0,0,0,0,0,1,0,1,0,1) + + /* + * TLB 4: 256M Non-cacheable, guarded + * 0xb0000000 256M PCI2 MEM Second half + */ + .long TLB1_MAS0(1, 4, 0) + .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M) + .long TLB1_MAS2(E500_TLB_EPN(CFG_PCI2_MEM_BASE + 0x10000000), + 0,0,0,0,1,0,1,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_PCI2_MEM_BASE + 0x10000000), + 0,0,0,0,0,1,0,1,0,1) + + /* + * TLB 5: 64M Non-cacheable, guarded + * 0xe000_0000 1M CCSRBAR + * 0xe200_0000 16M PCI1 IO + * 0xe300_0000 16M PCI2 IO + */ + .long TLB1_MAS0(1, 5, 0) + .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_64M) + .long TLB1_MAS2(E500_TLB_EPN(CFG_CCSRBAR), 0,0,0,0,1,0,1,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_CCSRBAR), 0,0,0,0,0,1,0,1,0,1) + + /* + * TLB 6: 64M Cacheable, non-guarded + * 0xf000_0000 64M LBC SDRAM + */ + .long TLB1_MAS0(1, 6, 0) + .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_64M) + .long TLB1_MAS2(E500_TLB_EPN(CFG_LBC_SDRAM_BASE), 0,0,0,0,0,0,0,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_LBC_SDRAM_BASE), 0,0,0,0,0,1,0,1,0,1) + + /* + * TLB 7: 1M Non-cacheable, guarded + * 0xf8000000 1M CADMUS registers + */ + .long TLB1_MAS0(1, 7, 0) + .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_1M) + .long TLB1_MAS2(E500_TLB_EPN(CADMUS_BASE_ADDR), 0,0,0,0,1,0,1,0) + .long TLB1_MAS3(E500_TLB_RPN(CADMUS_BASE_ADDR), 0,0,0,0,0,1,0,1,0,1) + + entry_end + +/* + * 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 + * 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 NVRAM/CADMUS (*) 1M + * 0xff00_0000 0xff7f_ffff FLASH (2nd bank) 8M + * 0xff80_0000 0xffff_ffff FLASH (boot bank) 8M + * + * Notes: + * CCSRBAR and L2-as-SRAM don't need a configured Local Access Window. + * If flash is 8M at default position (last 8M), no LAW needed. + * + * The defines below are 1-off of the actual LAWAR0 usage. + * So LAWAR3 define uses the LAWAR4 register in the ECM. + */ + +#define LAWBAR0 0 +#define LAWAR0 ((LAWAR_TRGT_IF_DDR | (LAWAR_SIZE & LAWAR_SIZE_128M)) & ~LAWAR_EN) + +#define LAWBAR1 ((CFG_PCI1_MEM_BASE>>12) & 0xfffff) +#define LAWAR1 (LAWAR_EN | LAWAR_TRGT_IF_PCI1 | (LAWAR_SIZE & LAWAR_SIZE_512M)) + +#define LAWBAR2 ((CFG_PCI2_MEM_BASE>>12) & 0xfffff) +#define LAWAR2 (LAWAR_EN | LAWAR_TRGT_IF_PCI2 | (LAWAR_SIZE & LAWAR_SIZE_512M)) + +#define LAWBAR3 ((CFG_PCI1_IO_BASE>>12) & 0xfffff) +#define LAWAR3 (LAWAR_EN | LAWAR_TRGT_IF_PCI1 | (LAWAR_SIZE & LAWAR_SIZE_16M)) + +#define LAWBAR4 ((CFG_PCI2_IO_BASE>>12) & 0xfffff) +#define LAWAR4 (LAWAR_EN | LAWAR_TRGT_IF_PCI2 | (LAWAR_SIZE & LAWAR_SIZE_16M)) + +/* LBC window - maps 256M 0xf0000000 -> 0xffffffff */ +#define LAWBAR5 ((CFG_LBC_SDRAM_BASE>>12) & 0xfffff) +#define LAWAR5 (LAWAR_EN | LAWAR_TRGT_IF_LBC | (LAWAR_SIZE & LAWAR_SIZE_256M)) + + .section .bootpg, "ax" + .globl law_entry + +law_entry: + entry_start + .long 6 + .long LAWBAR0,LAWAR0,LAWBAR1,LAWAR1,LAWBAR2,LAWAR2,LAWBAR3,LAWAR3 + .long LAWBAR4,LAWAR4,LAWBAR5,LAWAR5 + entry_end diff --git a/board/cds/mpc8541cds/mpc8541cds.c b/board/cds/mpc8541cds/mpc8541cds.c new file mode 100644 index 0000000..b824b3d --- /dev/null +++ b/board/cds/mpc8541cds/mpc8541cds.c @@ -0,0 +1,373 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * + * (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_85xx.h> +#include <spd.h> + +#include "../common/cadmus.h" +#include "../common/eeprom.h" + +#if defined(CONFIG_DDR_ECC) +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); + + + +int +board_early_init_f(void) +{ + return 0; +} + + +int +checkboard(void) +{ + volatile immap_t *immap = (immap_t *)CFG_CCSRBAR; + volatile ccsr_gur_t *gur = &immap->im_gur; + + /* PCI slot in USER bits CSR[6:7] by convention. */ + uint pci_slot = get_pci_slot(); + + uint pci_dual = get_pci_dual(); /* PCI DUAL in CM_PCI[3] */ + uint pci1_32 = gur->pordevsr & 0x10000; /* PORDEVSR[15] */ + uint pci1_clk_sel = gur->porpllsr & 0x8000; /* PORPLLSR[16] */ + uint pci2_clk_sel = gur->porpllsr & 0x4000; /* PORPLLSR[17] */ + + uint pci1_speed = get_clock_freq(); /* PCI PSPEED in [4:5] */ + + uint cpu_board_rev = get_cpu_board_revision(); + + printf("Board: CDS Version 0x%02x, PCI Slot %d\n", + get_board_version(), + pci_slot); + + printf("CPU Board Revision %d.%d (0x%04x)\n", + MPC85XX_CPU_BOARD_MAJOR(cpu_board_rev), + MPC85XX_CPU_BOARD_MINOR(cpu_board_rev), + cpu_board_rev); + + printf(" PCI1: %d bit, %s MHz, %s\n", + (pci1_32) ? 32 : 64, + (pci1_speed == 33000000) ? "33" : + (pci1_speed == 66000000) ? "66" : "unknown", + pci1_clk_sel ? "sync" : "async" + ); + + if (pci_dual) { + printf(" PCI2: 32 bit, 66 MHz, %s\n", + pci2_clk_sel ? "sync" : "async" + ); + } else { + printf(" PCI2: disabled\n"); + } + + /* + * Initialize local bus. + */ + local_bus_init(); + + return 0; +} + + +long int +initdram(int board_type) +{ + long dram_size = 0; + volatile immap_t *immap = (immap_t *)CFG_IMMR; + + puts("Initializing\n"); + +#if defined(CONFIG_DDR_DLL) + { + /* + * Work around to stabilize DDR DLL MSYNC_IN. + * Errata DDR9 seems to have been fixed. + * This is now the workaround for Errata DDR11: + * Override DLL = 1, Course Adj = 1, Tap Select = 0 + */ + + volatile ccsr_gur_t *gur= &immap->im_gur; + + gur->ddrdllcr = 0x81000000; + asm("sync;isync;msync"); + udelay(200); + } +#endif + + dram_size = spd_sdram(); + + +#if defined(CONFIG_DDR_ECC) + /* + * Initialize and enable DDR ECC. + */ + ddr_enable_ecc(dram_size); +#endif + + + /* + * SDRAM Initialization + */ + sdram_init(); + + puts(" DDR: "); + return dram_size; +} + + +/* + * Initialize Local Bus + */ + +void +local_bus_init(void) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_gur_t *gur = &immap->im_gur; + volatile ccsr_lbc_t *lbc = &immap->im_lbc; + + uint clkdiv; + uint lbc_hz; + sys_info_t sysinfo; + uint temp_lbcdll; + + /* + * 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 (lbc_hz < 66) { + lbc->lcrr |= 0x80000000; /* DLL Bypass */ + + } else if (lbc_hz >= 133) { + lbc->lcrr &= (~0x80000000); /* DLL Enabled */ + + } else { + lbc->lcrr &= (~0x8000000); /* DLL Enabled */ + udelay(200); + + /* + * Sample LBC DLL ctrl reg, upshift it to set the + * override bits. + */ + temp_lbcdll = gur->lbcdllcr; + gur->lbcdllcr = (((temp_lbcdll & 0xff) << 16) | 0x80000000); + asm("sync;isync;msync"); + } +} + + +/* + * Initialize SDRAM memory on the Local Bus. + */ + +void +sdram_init(void) +{ +#if defined(CFG_OR2_PRELIM) && defined(CFG_BR2_PRELIM) + + uint idx; + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_lbc_t *lbc = &immap->im_lbc; + uint *sdram_addr = (uint *)CFG_LBC_SDRAM_BASE; + uint cpu_board_rev; + uint lsdmr_common; + + puts(" SDRAM: "); + + print_size (CFG_LBC_SDRAM_SIZE * 1024 * 1024, "\n"); + + /* + * Setup SDRAM Base and Option Registers + */ + lbc->or2 = CFG_OR2_PRELIM; + asm("msync"); + + lbc->br2 = CFG_BR2_PRELIM; + asm("msync"); + + lbc->lbcr = CFG_LBC_LBCR; + asm("msync"); + + + lbc->lsrt = CFG_LBC_LSRT; + lbc->mrtpr = CFG_LBC_MRTPR; + asm("msync"); + + /* + * Determine which address lines to use baed on CPU board rev. + */ + cpu_board_rev = get_cpu_board_revision(); + lsdmr_common = CFG_LBC_LSDMR_COMMON; + if (cpu_board_rev == MPC85XX_CPU_BOARD_REV_1_0) { + lsdmr_common |= CFG_LBC_LSDMR_BSMA1617; + } else if (cpu_board_rev == MPC85XX_CPU_BOARD_REV_1_1) { + lsdmr_common |= CFG_LBC_LSDMR_BSMA1516; + } else { + /* + * Assume something unable to identify itself is + * really old, and likely has lines 16/17 mapped. + */ + lsdmr_common |= CFG_LBC_LSDMR_BSMA1617; + } + + /* + * Issue PRECHARGE ALL command. + */ + lbc->lsdmr = lsdmr_common | CFG_LBC_LSDMR_OP_PCHALL; + asm("sync;msync"); + *sdram_addr = 0xff; + ppcDcbf((unsigned long) sdram_addr); + udelay(100); + + /* + * Issue 8 AUTO REFRESH commands. + */ + for (idx = 0; idx < 8; idx++) { + lbc->lsdmr = lsdmr_common | CFG_LBC_LSDMR_OP_ARFRSH; + asm("sync;msync"); + *sdram_addr = 0xff; + ppcDcbf((unsigned long) sdram_addr); + udelay(100); + } + + /* + * Issue 8 MODE-set command. + */ + lbc->lsdmr = lsdmr_common | CFG_LBC_LSDMR_OP_MRW; + asm("sync;msync"); + *sdram_addr = 0xff; + ppcDcbf((unsigned long) sdram_addr); + udelay(100); + + /* + * Issue NORMAL OP command. + */ + lbc->lsdmr = lsdmr_common | CFG_LBC_LSDMR_OP_NORMAL; + asm("sync;msync"); + *sdram_addr = 0xff; + ppcDcbf((unsigned long) sdram_addr); + udelay(200); /* Overkill. Must wait > 200 bus cycles */ + +#endif /* enable SDRAM init */ +} + + +#if defined(CFG_DRAM_TEST) +int +testdram(void) +{ + uint *pstart = (uint *) CFG_MEMTEST_START; + uint *pend = (uint *) CFG_MEMTEST_END; + uint *p; + + printf("Testing DRAM from 0x%08x to 0x%08x\n", + CFG_MEMTEST_START, + CFG_MEMTEST_END); + + printf("DRAM test phase 1:\n"); + for (p = pstart; p < pend; p++) + *p = 0xaaaaaaaa; + + for (p = pstart; p < pend; p++) { + if (*p != 0xaaaaaaaa) { + printf ("DRAM test fails at: %08x\n", (uint) p); + return 1; + } + } + + printf("DRAM test phase 2:\n"); + for (p = pstart; p < pend; p++) + *p = 0x55555555; + + for (p = pstart; p < pend; p++) { + if (*p != 0x55555555) { + printf ("DRAM test fails at: %08x\n", (uint) p); + return 1; + } + } + + printf("DRAM test passed.\n"); + return 0; +} +#endif + + + +#if defined(CONFIG_PCI) + +/* + * Initialize PCI Devices, report devices found. + */ + +#ifndef CONFIG_PCI_PNP +static struct pci_config_table pci_mpc85xxcds_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_mpc85xxcds_config_table, +#endif +}; + +#endif /* CONFIG_PCI */ + + +void +pci_init_board(void) +{ +#ifdef CONFIG_PCI + extern void pci_mpc85xx_init(struct pci_controller *hose); + + pci_mpc85xx_init(&hose); +#endif +} diff --git a/board/cds/mpc8541cds/u-boot.lds b/board/cds/mpc8541cds/u-boot.lds new file mode 100644 index 0000000..f8cee53 --- /dev/null +++ b/board/cds/mpc8541cds/u-boot.lds @@ -0,0 +1,147 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * + * 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 0xFFFFFFFC : + { + *(.resetvec) + } = 0xffff + + .bootpg 0xFFFFF000 : + { + cpu/mpc85xx/start.o (.bootpg) + board/cds/mpc8541cds/init.o (.bootpg) + } = 0xffff + + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + cpu/mpc85xx/start.o (.text) + board/cds/mpc8541cds/init.o (.text) + cpu/mpc85xx/traps.o (.text) + cpu/mpc85xx/interrupts.o (.text) + cpu/mpc85xx/cpu_init.o (.text) + cpu/mpc85xx/cpu.o (.text) + cpu/mpc85xx/tsec.o (.text) + cpu/mpc85xx/speed.o (.text) + cpu/mpc85xx/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/board/cds/mpc8555cds/Makefile b/board/cds/mpc8555cds/Makefile new file mode 100644 index 0000000..0d4abbd --- /dev/null +++ b/board/cds/mpc8555cds/Makefile @@ -0,0 +1,51 @@ +# +# Copyright 2004 Freescale Semiconductor. +# (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 \ + ../common/cadmus.o \ + ../common/eeprom.o + +SOBJS := init.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $(OBJS) + +clean: + rm -f $(OBJS) $(SOBJS) + +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) > $@ + +-include .depend + +######################################################################### diff --git a/board/cds/mpc8555cds/config.mk b/board/cds/mpc8555cds/config.mk new file mode 100644 index 0000000..5dcaa77 --- /dev/null +++ b/board/cds/mpc8555cds/config.mk @@ -0,0 +1,30 @@ +# +# Copyright 2004 Freescale Semiconductor. +# +# 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 +# + +# +# mpc8555cds board +# +TEXT_BASE = 0xfff80000 + +PLATFORM_CPPFLAGS += -DCONFIG_E500=1 +PLATFORM_CPPFLAGS += -DCONFIG_MPC85xx=1 +PLATFORM_CPPFLAGS += -DCONFIG_MPC8555=1 diff --git a/board/cds/mpc8555cds/init.S b/board/cds/mpc8555cds/init.S new file mode 100644 index 0000000..53dcd0d --- /dev/null +++ b/board/cds/mpc8555cds/init.S @@ -0,0 +1,255 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * Copyright 2002,2003, Motorola Inc. + * + * 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 <mpc85xx.h> + + +/* + * TLB0 and TLB1 Entries + * + * Out of reset, TLB1's Entry 0 maps the highest 4K for CCSRBAR. + * However, CCSRBAR is then relocated to CFG_CCSRBAR right after + * these TLB entries are established. + * + * The TLB entries for DDR are dynamically setup in spd_sdram() + * and use TLB1 Entries 8 through 15 as needed according to the + * size of DDR memory. + * + * MAS0: tlbsel, esel, nv + * MAS1: valid, iprot, tid, ts, tsize + * MAS2: epn, sharen, x0, x1, w, i, m, g, e + * MAS3: rpn, u0-u3, ux, sx, uw, sw, ur, sr + */ + +#define entry_start \ + mflr r1 ; \ + bl 0f ; + +#define entry_end \ +0: mflr r0 ; \ + mtlr r1 ; \ + blr ; + + + .section .bootpg, "ax" + .globl tlb1_entry +tlb1_entry: + entry_start + + /* + * Number of TLB0 and TLB1 entries in the following table + */ + .long 13 + +#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR) + /* + * TLB0 4K Non-cacheable, guarded + * 0xff700000 4K Initial CCSRBAR mapping + * + * This ends up at a TLB0 Index==0 entry, and must not collide + * with other TLB0 Entries. + */ + .long TLB1_MAS0(0, 0, 0) + .long TLB1_MAS1(1, 0, 0, 0, 0) + .long TLB1_MAS2(E500_TLB_EPN(CFG_CCSRBAR_DEFAULT), 0,0,0,0,1,0,1,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_CCSRBAR_DEFAULT), 0,0,0,0,0,1,0,1,0,1) +#else +#error("Update the number of table entries in tlb1_entry") +#endif + + /* + * TLB0 16K Cacheable, non-guarded + * 0xd001_0000 16K Temporary Global data for initialization + * + * Use four 4K TLB0 entries. These entries must be cacheable + * as they provide the bootstrap memory before the memory + * controler and real memory have been configured. + * + * These entries end up at TLB0 Indicies 0x10, 0x14, 0x18 and 0x1c, + * and must not collide with other TLB0 entries. + */ + .long TLB1_MAS0(0, 0, 0) + .long TLB1_MAS1(1, 0, 0, 0, 0) + .long TLB1_MAS2(E500_TLB_EPN(CFG_INIT_RAM_ADDR), + 0,0,0,0,0,0,0,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_INIT_RAM_ADDR), + 0,0,0,0,0,1,0,1,0,1) + + .long TLB1_MAS0(0, 0, 0) + .long TLB1_MAS1(1, 0, 0, 0, 0) + .long TLB1_MAS2(E500_TLB_EPN(CFG_INIT_RAM_ADDR + 4 * 1024), + 0,0,0,0,0,0,0,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_INIT_RAM_ADDR + 4 * 1024), + 0,0,0,0,0,1,0,1,0,1) + + .long TLB1_MAS0(0, 0, 0) + .long TLB1_MAS1(1, 0, 0, 0, 0) + .long TLB1_MAS2(E500_TLB_EPN(CFG_INIT_RAM_ADDR + 8 * 1024), + 0,0,0,0,0,0,0,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_INIT_RAM_ADDR + 8 * 1024), + 0,0,0,0,0,1,0,1,0,1) + + .long TLB1_MAS0(0, 0, 0) + .long TLB1_MAS1(1, 0, 0, 0, 0) + .long TLB1_MAS2(E500_TLB_EPN(CFG_INIT_RAM_ADDR + 12 * 1024), + 0,0,0,0,0,0,0,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_INIT_RAM_ADDR + 12 * 1024), + 0,0,0,0,0,1,0,1,0,1) + + + /* + * TLB 0: 16M Non-cacheable, guarded + * 0xff000000 16M FLASH + * Out of reset this entry is only 4K. + */ + .long TLB1_MAS0(1, 0, 0) + .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_16M) + .long TLB1_MAS2(E500_TLB_EPN(CFG_FLASH_BASE), 0,0,0,0,1,0,1,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_FLASH_BASE), 0,0,0,0,0,1,0,1,0,1) + + /* + * TLB 1: 256M Non-cacheable, guarded + * 0x80000000 256M PCI1 MEM First half + */ + .long TLB1_MAS0(1, 1, 0) + .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M) + .long TLB1_MAS2(E500_TLB_EPN(CFG_PCI1_MEM_BASE), 0,0,0,0,1,0,1,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_PCI1_MEM_BASE), 0,0,0,0,0,1,0,1,0,1) + + /* + * TLB 2: 256M Non-cacheable, guarded + * 0x90000000 256M PCI1 MEM Second half + */ + .long TLB1_MAS0(1, 2, 0) + .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M) + .long TLB1_MAS2(E500_TLB_EPN(CFG_PCI1_MEM_BASE + 0x10000000), + 0,0,0,0,1,0,1,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_PCI1_MEM_BASE + 0x10000000), + 0,0,0,0,0,1,0,1,0,1) + + /* + * TLB 3: 256M Non-cacheable, guarded + * 0xa0000000 256M PCI2 MEM First half + */ + .long TLB1_MAS0(1, 3, 0) + .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M) + .long TLB1_MAS2(E500_TLB_EPN(CFG_PCI2_MEM_BASE), 0,0,0,0,1,0,1,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_PCI2_MEM_BASE), 0,0,0,0,0,1,0,1,0,1) + + /* + * TLB 4: 256M Non-cacheable, guarded + * 0xb0000000 256M PCI2 MEM Second half + */ + .long TLB1_MAS0(1, 4, 0) + .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M) + .long TLB1_MAS2(E500_TLB_EPN(CFG_PCI2_MEM_BASE + 0x10000000), + 0,0,0,0,1,0,1,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_PCI2_MEM_BASE + 0x10000000), + 0,0,0,0,0,1,0,1,0,1) + + /* + * TLB 5: 64M Non-cacheable, guarded + * 0xe000_0000 1M CCSRBAR + * 0xe200_0000 16M PCI1 IO + * 0xe300_0000 16M PCI2 IO + */ + .long TLB1_MAS0(1, 5, 0) + .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_64M) + .long TLB1_MAS2(E500_TLB_EPN(CFG_CCSRBAR), 0,0,0,0,1,0,1,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_CCSRBAR), 0,0,0,0,0,1,0,1,0,1) + + /* + * TLB 6: 64M Cacheable, non-guarded + * 0xf000_0000 64M LBC SDRAM + */ + .long TLB1_MAS0(1, 6, 0) + .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_64M) + .long TLB1_MAS2(E500_TLB_EPN(CFG_LBC_SDRAM_BASE), 0,0,0,0,0,0,0,0) + .long TLB1_MAS3(E500_TLB_RPN(CFG_LBC_SDRAM_BASE), 0,0,0,0,0,1,0,1,0,1) + + /* + * TLB 7: 1M Non-cacheable, guarded + * 0xf8000000 1M CADMUS registers + */ + .long TLB1_MAS0(1, 7, 0) + .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_1M) + .long TLB1_MAS2(E500_TLB_EPN(CADMUS_BASE_ADDR), 0,0,0,0,1,0,1,0) + .long TLB1_MAS3(E500_TLB_RPN(CADMUS_BASE_ADDR), 0,0,0,0,0,1,0,1,0,1) + + entry_end + +/* + * 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 + * 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 NVRAM/CADMUS (*) 1M + * 0xff00_0000 0xff7f_ffff FLASH (2nd bank) 8M + * 0xff80_0000 0xffff_ffff FLASH (boot bank) 8M + * + * Notes: + * CCSRBAR and L2-as-SRAM don't need a configured Local Access Window. + * If flash is 8M at default position (last 8M), no LAW needed. + * + * The defines below are 1-off of the actual LAWAR0 usage. + * So LAWAR3 define uses the LAWAR4 register in the ECM. + */ + +#define LAWBAR0 0 +#define LAWAR0 ((LAWAR_TRGT_IF_DDR | (LAWAR_SIZE & LAWAR_SIZE_128M)) & ~LAWAR_EN) + +#define LAWBAR1 ((CFG_PCI1_MEM_BASE>>12) & 0xfffff) +#define LAWAR1 (LAWAR_EN | LAWAR_TRGT_IF_PCI1 | (LAWAR_SIZE & LAWAR_SIZE_512M)) + +#define LAWBAR2 ((CFG_PCI2_MEM_BASE>>12) & 0xfffff) +#define LAWAR2 (LAWAR_EN | LAWAR_TRGT_IF_PCI2 | (LAWAR_SIZE & LAWAR_SIZE_512M)) + +#define LAWBAR3 ((CFG_PCI1_IO_BASE>>12) & 0xfffff) +#define LAWAR3 (LAWAR_EN | LAWAR_TRGT_IF_PCI1 | (LAWAR_SIZE & LAWAR_SIZE_16M)) + +#define LAWBAR4 ((CFG_PCI2_IO_BASE>>12) & 0xfffff) +#define LAWAR4 (LAWAR_EN | LAWAR_TRGT_IF_PCI2 | (LAWAR_SIZE & LAWAR_SIZE_16M)) + +/* LBC window - maps 256M 0xf0000000 -> 0xffffffff */ +#define LAWBAR5 ((CFG_LBC_SDRAM_BASE>>12) & 0xfffff) +#define LAWAR5 (LAWAR_EN | LAWAR_TRGT_IF_LBC | (LAWAR_SIZE & LAWAR_SIZE_256M)) + + .section .bootpg, "ax" + .globl law_entry + +law_entry: + entry_start + .long 6 + .long LAWBAR0,LAWAR0,LAWBAR1,LAWAR1,LAWBAR2,LAWAR2,LAWBAR3,LAWAR3 + .long LAWBAR4,LAWAR4,LAWBAR5,LAWAR5 + entry_end diff --git a/board/cds/mpc8555cds/mpc8555cds.c b/board/cds/mpc8555cds/mpc8555cds.c new file mode 100644 index 0000000..e4f9d65 --- /dev/null +++ b/board/cds/mpc8555cds/mpc8555cds.c @@ -0,0 +1,371 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * + * 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_85xx.h> +#include <spd.h> + +#include "../common/cadmus.h" +#include "../common/eeprom.h" + +#if defined(CONFIG_DDR_ECC) +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); + + + +int +board_early_init_f(void) +{ + return 0; +} + + +int +checkboard(void) +{ + volatile immap_t *immap = (immap_t *)CFG_CCSRBAR; + volatile ccsr_gur_t *gur = &immap->im_gur; + + /* PCI slot in USER bits CSR[6:7] by convention. */ + uint pci_slot = get_pci_slot(); + + uint pci_dual = get_pci_dual(); /* PCI DUAL in CM_PCI[3] */ + uint pci1_32 = gur->pordevsr & 0x10000; /* PORDEVSR[15] */ + uint pci1_clk_sel = gur->porpllsr & 0x8000; /* PORPLLSR[16] */ + uint pci2_clk_sel = gur->porpllsr & 0x4000; /* PORPLLSR[17] */ + + uint pci1_speed = get_clock_freq(); /* PCI PSPEED in [4:5] */ + + uint cpu_board_rev = get_cpu_board_revision(); + + printf("Board: CDS Version 0x%02x, PCI Slot %d\n", + get_board_version(), + pci_slot); + + printf("CPU Board Revision %d.%d (0x%04x)\n", + MPC85XX_CPU_BOARD_MAJOR(cpu_board_rev), + MPC85XX_CPU_BOARD_MINOR(cpu_board_rev), + cpu_board_rev); + + printf(" PCI1: %d bit, %s MHz, %s\n", + (pci1_32) ? 32 : 64, + (pci1_speed == 33000000) ? "33" : + (pci1_speed == 66000000) ? "66" : "unknown", + pci1_clk_sel ? "sync" : "async" + ); + + if (pci_dual) { + printf(" PCI2: 32 bit, 66 MHz, %s\n", + pci2_clk_sel ? "sync" : "async" + ); + } else { + printf(" PCI2: disabled\n"); + } + + /* + * Initialize local bus. + */ + local_bus_init(); + + return 0; +} + + +long int +initdram(int board_type) +{ + long dram_size = 0; + volatile immap_t *immap = (immap_t *)CFG_IMMR; + + puts("Initializing\n"); + +#if defined(CONFIG_DDR_DLL) + { + /* + * Work around to stabilize DDR DLL MSYNC_IN. + * Errata DDR9 seems to have been fixed. + * This is now the workaround for Errata DDR11: + * Override DLL = 1, Course Adj = 1, Tap Select = 0 + */ + + volatile ccsr_gur_t *gur= &immap->im_gur; + + gur->ddrdllcr = 0x81000000; + asm("sync;isync;msync"); + udelay(200); + } +#endif + + dram_size = spd_sdram(); + + +#if defined(CONFIG_DDR_ECC) + /* + * Initialize and enable DDR ECC. + */ + ddr_enable_ecc(dram_size); +#endif + + + /* + * SDRAM Initialization + */ + sdram_init(); + + puts(" DDR: "); + return dram_size; +} + + +/* + * Initialize Local Bus + */ + +void +local_bus_init(void) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_gur_t *gur = &immap->im_gur; + volatile ccsr_lbc_t *lbc = &immap->im_lbc; + + uint clkdiv; + uint lbc_hz; + sys_info_t sysinfo; + uint temp_lbcdll; + + /* + * 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 (lbc_hz < 66) { + lbc->lcrr |= 0x80000000; /* DLL Bypass */ + + } else if (lbc_hz >= 133) { + lbc->lcrr &= (~0x80000000); /* DLL Enabled */ + + } else { + lbc->lcrr &= (~0x8000000); /* DLL Enabled */ + udelay(200); + + /* + * Sample LBC DLL ctrl reg, upshift it to set the + * override bits. + */ + temp_lbcdll = gur->lbcdllcr; + gur->lbcdllcr = (((temp_lbcdll & 0xff) << 16) | 0x80000000); + asm("sync;isync;msync"); + } +} + + +/* + * Initialize SDRAM memory on the Local Bus. + */ + +void +sdram_init(void) +{ +#if defined(CFG_OR2_PRELIM) && defined(CFG_BR2_PRELIM) + + uint idx; + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_lbc_t *lbc = &immap->im_lbc; + uint *sdram_addr = (uint *)CFG_LBC_SDRAM_BASE; + uint cpu_board_rev; + uint lsdmr_common; + + puts(" SDRAM: "); + + print_size (CFG_LBC_SDRAM_SIZE * 1024 * 1024, "\n"); + + /* + * Setup SDRAM Base and Option Registers + */ + lbc->or2 = CFG_OR2_PRELIM; + asm("msync"); + + lbc->br2 = CFG_BR2_PRELIM; + asm("msync"); + + lbc->lbcr = CFG_LBC_LBCR; + asm("msync"); + + + lbc->lsrt = CFG_LBC_LSRT; + lbc->mrtpr = CFG_LBC_MRTPR; + asm("msync"); + + /* + * Determine which address lines to use baed on CPU board rev. + */ + cpu_board_rev = get_cpu_board_revision(); + lsdmr_common = CFG_LBC_LSDMR_COMMON; + if (cpu_board_rev == MPC85XX_CPU_BOARD_REV_1_0) { + lsdmr_common |= CFG_LBC_LSDMR_BSMA1617; + } else if (cpu_board_rev == MPC85XX_CPU_BOARD_REV_1_1) { + lsdmr_common |= CFG_LBC_LSDMR_BSMA1516; + } else { + /* + * Assume something unable to identify itself is + * really old, and likely has lines 16/17 mapped. + */ + lsdmr_common |= CFG_LBC_LSDMR_BSMA1617; + } + + /* + * Issue PRECHARGE ALL command. + */ + lbc->lsdmr = lsdmr_common | CFG_LBC_LSDMR_OP_PCHALL; + asm("sync;msync"); + *sdram_addr = 0xff; + ppcDcbf((unsigned long) sdram_addr); + udelay(100); + + /* + * Issue 8 AUTO REFRESH commands. + */ + for (idx = 0; idx < 8; idx++) { + lbc->lsdmr = lsdmr_common | CFG_LBC_LSDMR_OP_ARFRSH; + asm("sync;msync"); + *sdram_addr = 0xff; + ppcDcbf((unsigned long) sdram_addr); + udelay(100); + } + + /* + * Issue 8 MODE-set command. + */ + lbc->lsdmr = lsdmr_common | CFG_LBC_LSDMR_OP_MRW; + asm("sync;msync"); + *sdram_addr = 0xff; + ppcDcbf((unsigned long) sdram_addr); + udelay(100); + + /* + * Issue NORMAL OP command. + */ + lbc->lsdmr = lsdmr_common | CFG_LBC_LSDMR_OP_NORMAL; + asm("sync;msync"); + *sdram_addr = 0xff; + ppcDcbf((unsigned long) sdram_addr); + udelay(200); /* Overkill. Must wait > 200 bus cycles */ + +#endif /* enable SDRAM init */ +} + + +#if defined(CFG_DRAM_TEST) +int +testdram(void) +{ + uint *pstart = (uint *) CFG_MEMTEST_START; + uint *pend = (uint *) CFG_MEMTEST_END; + uint *p; + + printf("Testing DRAM from 0x%08x to 0x%08x\n", + CFG_MEMTEST_START, + CFG_MEMTEST_END); + + printf("DRAM test phase 1:\n"); + for (p = pstart; p < pend; p++) + *p = 0xaaaaaaaa; + + for (p = pstart; p < pend; p++) { + if (*p != 0xaaaaaaaa) { + printf ("DRAM test fails at: %08x\n", (uint) p); + return 1; + } + } + + printf("DRAM test phase 2:\n"); + for (p = pstart; p < pend; p++) + *p = 0x55555555; + + for (p = pstart; p < pend; p++) { + if (*p != 0x55555555) { + printf ("DRAM test fails at: %08x\n", (uint) p); + return 1; + } + } + + printf("DRAM test passed.\n"); + return 0; +} +#endif + + + +#if defined(CONFIG_PCI) + +/* + * Initialize PCI Devices, report devices found. + */ + +#ifndef CONFIG_PCI_PNP +static struct pci_config_table pci_mpc85xxcds_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_mpc85xxcds_config_table, +#endif +}; + +#endif /* CONFIG_PCI */ + + +void +pci_init_board(void) +{ +#ifdef CONFIG_PCI + extern void pci_mpc85xx_init(struct pci_controller *hose); + + pci_mpc85xx_init(&hose); +#endif +} diff --git a/board/cds/mpc8555cds/u-boot.lds b/board/cds/mpc8555cds/u-boot.lds new file mode 100644 index 0000000..d14cb9c --- /dev/null +++ b/board/cds/mpc8555cds/u-boot.lds @@ -0,0 +1,147 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * + * 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 0xFFFFFFFC : + { + *(.resetvec) + } = 0xffff + + .bootpg 0xFFFFF000 : + { + cpu/mpc85xx/start.o (.bootpg) + board/cds/mpc8555cds/init.o (.bootpg) + } = 0xffff + + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + cpu/mpc85xx/start.o (.text) + board/cds/mpc8555cds/init.o (.text) + cpu/mpc85xx/traps.o (.text) + cpu/mpc85xx/interrupts.o (.text) + cpu/mpc85xx/cpu_init.o (.text) + cpu/mpc85xx/cpu.o (.text) + cpu/mpc85xx/tsec.o (.text) + cpu/mpc85xx/speed.o (.text) + cpu/mpc85xx/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/board/mpc8540ads/flash.c b/board/mpc8540ads/flash.c deleted file mode 100644 index c7d318c..0000000 --- a/board/mpc8540ads/flash.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * (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: - 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 */ - } - - 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: - info->flash_id = FLASH_UNKNOWN; - return (0); /* => no or unknown flash */ - - } - - /* 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/mpc8560ads/flash.c b/board/mpc8560ads/flash.c deleted file mode 100644 index 4dbbf9d..0000000 --- a/board/mpc8560ads/flash.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * (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: - 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 */ - } - - 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; /* => 8 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: - info->flash_id = FLASH_UNKNOWN; - return (0); /* => no or unknown flash */ - - } - - /* 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 */ |