diff options
Diffstat (limited to 'board')
148 files changed, 8548 insertions, 1551 deletions
diff --git a/board/BuS/EB+MCF-EV123/Makefile b/board/BuS/EB+MCF-EV123/Makefile index ed3ac07..ceeffa7 100644 --- a/board/BuS/EB+MCF-EV123/Makefile +++ b/board/BuS/EB+MCF-EV123/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -COBJS = $(BOARD).o cfm_flash.o flash.o VCxK.o +COBJS = $(BOARD).o cfm_flash.o flash.o VCxK.o mii.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/BuS/EB+MCF-EV123/mii.c b/board/BuS/EB+MCF-EV123/mii.c new file mode 100644 index 0000000..ebd3ed9 --- /dev/null +++ b/board/BuS/EB+MCF-EV123/mii.c @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/fec.h> +#include <asm/immap.h> + +#include <config.h> +#include <net.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) +#undef MII_DEBUG +#undef ET_DEBUG + +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + if (setclear) { + MCFGPIO_PASPAR |= 0x0F00; + MCFGPIO_PEHLPAR = CFG_PEHLPAR; + } else { + MCFGPIO_PASPAR &= 0xF0FF; + MCFGPIO_PEHLPAR &= ~CFG_PEHLPAR; + } + return 0; +} + +#if defined(CFG_DISCOVER_PHY) || defined(CONFIG_CMD_MII) +#include <miiphy.h> + +/* Make MII read/write commands for the FEC. */ +#define mk_mii_read(ADDR, REG) (0x60020000 | ((ADDR << 23) | (REG & 0x1f) << 18)) + +#define mk_mii_write(ADDR, REG, VAL) (0x50020000 | ((ADDR << 23) | (REG & 0x1f) << 18) | (VAL & 0xffff)) + +/* PHY identification */ +#define PHY_ID_LXT970 0x78100000 /* LXT970 */ +#define PHY_ID_LXT971 0x001378e0 /* LXT971 and 972 */ +#define PHY_ID_82555 0x02a80150 /* Intel 82555 */ +#define PHY_ID_QS6612 0x01814400 /* QS6612 */ +#define PHY_ID_AMD79C784 0x00225610 /* AMD 79C784 */ +#define PHY_ID_AMD79C874VC 0x0022561B /* AMD 79C874 */ +#define PHY_ID_LSI80225 0x0016f870 /* LSI 80225 */ +#define PHY_ID_LSI80225B 0x0016f880 /* LSI 80225/B */ +#define PHY_ID_DP83848VV 0x20005C90 /* National 83848 */ +#define PHY_ID_DP83849 0x20005CA2 /* National 82849 */ + +#define STR_ID_LXT970 "LXT970" +#define STR_ID_LXT971 "LXT971" +#define STR_ID_82555 "Intel82555" +#define STR_ID_QS6612 "QS6612" +#define STR_ID_AMD79C784 "AMD79C784" +#define STR_ID_AMD79C874VC "AMD79C874VC" +#define STR_ID_LSI80225 "LSI80225" +#define STR_ID_LSI80225B "LSI80225/B" +#define STR_ID_DP83848VV "N83848" +#define STR_ID_DP83849 "N83849" + +/**************************************************************************** + * mii_init -- Initialize the MII for MII command without ethernet + * This function is a subset of eth_init + **************************************************************************** + */ +void mii_reset(struct fec_info_s *info) +{ + volatile fec_t *fecp = (fec_t *) (info->miibase); + int i; + + fecp->ecr = FEC_ECR_RESET; + for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i) { + udelay(1); + } + if (i == FEC_RESET_DELAY) { + printf("FEC_RESET_DELAY timeout\n"); + } +} + +/* send command to phy using mii, wait for result */ +uint mii_send(uint mii_cmd) +{ + struct fec_info_s *info; + struct eth_device *dev; + volatile fec_t *ep; + uint mii_reply; + int j = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + ep = (fec_t *) info->miibase; + + ep->mmfr = mii_cmd; /* command to phy */ + + /* wait for mii complete */ + while (!(ep->eir & FEC_EIR_MII) && (j < MCFFEC_TOUT_LOOP)) { + udelay(1); + j++; + } + if (j >= MCFFEC_TOUT_LOOP) { + printf("MII not complete\n"); + return -1; + } + + mii_reply = ep->mmfr; /* result from phy */ + ep->eir = FEC_EIR_MII; /* clear MII complete */ +#ifdef ET_DEBUG + printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n", + __FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply); +#endif + + return (mii_reply & 0xffff); /* data read from phy */ +} +#endif /* CFG_DISCOVER_PHY || (CONFIG_COMMANDS & CONFIG_CMD_MII) */ + +#if defined(CFG_DISCOVER_PHY) +int mii_discover_phy(struct eth_device *dev) +{ +#define MAX_PHY_PASSES 11 + struct fec_info_s *info = dev->priv; + int phyaddr, pass; + uint phyno, phytype; + + if (info->phyname_init) + return info->phy_addr; + + phyaddr = -1; /* didn't find a PHY yet */ + for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) { + if (pass > 1) { + /* PHY may need more time to recover from reset. + * The LXT970 needs 50ms typical, no maximum is + * specified, so wait 10ms before try again. + * With 11 passes this gives it 100ms to wake up. + */ + udelay(10000); /* wait 10ms */ + } + + for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) { + + phytype = mii_send(mk_mii_read(phyno, PHY_PHYIDR1)); +#ifdef ET_DEBUG + printf("PHY type 0x%x pass %d type\n", phytype, pass); +#endif + if (phytype != 0xffff) { + phyaddr = phyno; + phytype <<= 16; + phytype |= + mii_send(mk_mii_read(phyno, PHY_PHYIDR2)); + + switch (phytype & 0xffffffff) { + case PHY_ID_AMD79C874VC: + strcpy(info->phy_name, + STR_ID_AMD79C874VC); + info->phyname_init = 1; + break; + default: + strcpy(info->phy_name, "unknown"); + info->phyname_init = 1; + break; + } + +#ifdef ET_DEBUG + printf("PHY @ 0x%x pass %d type ", phyno, pass); + switch (phytype & 0xffffffff) { + case PHY_ID_AMD79C874VC: + printf(STR_ID_AMD79C874VC); + break; + default: + printf("0x%08x\n", phytype); + break; + } +#endif + } + } + } + if (phyaddr < 0) + printf("No PHY device found.\n"); + + return phyaddr; +} +#endif /* CFG_DISCOVER_PHY */ + +int mii_init(void) __attribute__((weak,alias("__mii_init"))); + +void __mii_init(void) +{ + volatile fec_t *fecp; + struct fec_info_s *info; + struct eth_device *dev; + int miispd = 0, i = 0; + u16 autoneg = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + fecp = (fec_t *) info->miibase; + + fecpin_setclear(dev, 1); + + mii_reset(info); + + /* We use strictly polling mode only */ + fecp->eimr = 0; + + /* Clear any pending interrupt */ + fecp->eir = 0xffffffff; + + /* Set MII speed */ + miispd = (gd->bus_clk / 1000000) / 5; + fecp->mscr = miispd << 1; + + info->phy_addr = mii_discover_phy(dev); + +#define AUTONEGLINK (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS) + while (i < MCFFEC_TOUT_LOOP) { + autoneg = 0; + miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &autoneg); + i++; + + if ((autoneg & AUTONEGLINK) == AUTONEGLINK) + break; + + udelay(500); + } + if (i >= MCFFEC_TOUT_LOOP) { + printf("Auto Negotiation not complete\n"); + } + + /* adapt to the half/full speed settings */ + info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16; + info->dup_spd |= miiphy_speed(dev->name, info->phy_addr); +} + +/***************************************************************************** + * Read and write a MII PHY register, routines used by MII Utilities + * + * FIXME: These routines are expected to return 0 on success, but mii_send + * does _not_ return an error code. Maybe 0xFFFF means error, i.e. + * no PHY connected... + * For now always return 0. + * FIXME: These routines only work after calling eth_init() at least once! + * Otherwise they hang in mii_send() !!! Sorry! + *****************************************************************************/ + +int mcffec_miiphy_read(char *devname, unsigned char addr, unsigned char reg, + unsigned short *value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_read(0x%x) @ 0x%x = ", reg, addr); +#endif + rdreg = mii_send(mk_mii_read(addr, reg)); + + *value = rdreg; + +#ifdef MII_DEBUG + printf("0x%04x\n", *value); +#endif + + return 0; +} + +int mcffec_miiphy_write(char *devname, unsigned char addr, unsigned char reg, + unsigned short value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_write(0x%x) @ 0x%x = ", reg, addr); +#endif + + rdreg = mii_send(mk_mii_write(addr, reg, value)); + +#ifdef MII_DEBUG + printf("0x%04x\n", value); +#endif + + return 0; +} + +#endif /* CONFIG_CMD_NET, FEC_ENET & NET_MULTI */ diff --git a/board/MAI/bios_emulator/scitech/bin-linux/glibc/dmake b/board/MAI/bios_emulator/scitech/bin-linux/glibc/dmake Binary files differdeleted file mode 100755 index 4d6ccb3..0000000 --- a/board/MAI/bios_emulator/scitech/bin-linux/glibc/dmake +++ /dev/null diff --git a/board/MAI/bios_emulator/scitech/bin-linux/glibc/k_cp b/board/MAI/bios_emulator/scitech/bin-linux/glibc/k_cp Binary files differdeleted file mode 100755 index d372949..0000000 --- a/board/MAI/bios_emulator/scitech/bin-linux/glibc/k_cp +++ /dev/null diff --git a/board/MAI/bios_emulator/scitech/bin-linux/glibc/k_echo b/board/MAI/bios_emulator/scitech/bin-linux/glibc/k_echo Binary files differdeleted file mode 100755 index 6f65d41..0000000 --- a/board/MAI/bios_emulator/scitech/bin-linux/glibc/k_echo +++ /dev/null diff --git a/board/MAI/bios_emulator/scitech/bin-linux/glibc/k_rm b/board/MAI/bios_emulator/scitech/bin-linux/glibc/k_rm Binary files differdeleted file mode 100755 index 7de5030..0000000 --- a/board/MAI/bios_emulator/scitech/bin-linux/glibc/k_rm +++ /dev/null diff --git a/board/MAI/bios_emulator/scitech/bin-linux/glibc/makedep b/board/MAI/bios_emulator/scitech/bin-linux/glibc/makedep Binary files differdeleted file mode 100755 index 5451b22..0000000 --- a/board/MAI/bios_emulator/scitech/bin-linux/glibc/makedep +++ /dev/null diff --git a/board/MAI/bios_emulator/scitech/bin-linux/glibc/nasm b/board/MAI/bios_emulator/scitech/bin-linux/glibc/nasm Binary files differdeleted file mode 100755 index fbd3352..0000000 --- a/board/MAI/bios_emulator/scitech/bin-linux/glibc/nasm +++ /dev/null diff --git a/board/MAI/bios_emulator/scitech/bin-linux/glibc/ndisasm b/board/MAI/bios_emulator/scitech/bin-linux/glibc/ndisasm Binary files differdeleted file mode 100755 index dd14a7a..0000000 --- a/board/MAI/bios_emulator/scitech/bin-linux/glibc/ndisasm +++ /dev/null diff --git a/board/MAI/bios_emulator/scitech/bin-linux/glibc/trans b/board/MAI/bios_emulator/scitech/bin-linux/glibc/trans Binary files differdeleted file mode 100755 index a1aea4f..0000000 --- a/board/MAI/bios_emulator/scitech/bin-linux/glibc/trans +++ /dev/null diff --git a/board/MAI/bios_emulator/scitech/bin-linux/libc/dmake b/board/MAI/bios_emulator/scitech/bin-linux/libc/dmake Binary files differdeleted file mode 100755 index f198f29..0000000 --- a/board/MAI/bios_emulator/scitech/bin-linux/libc/dmake +++ /dev/null diff --git a/board/MAI/bios_emulator/scitech/bin-linux/libc/nasm b/board/MAI/bios_emulator/scitech/bin-linux/libc/nasm Binary files differdeleted file mode 100755 index e312a0b..0000000 --- a/board/MAI/bios_emulator/scitech/bin-linux/libc/nasm +++ /dev/null diff --git a/board/MAI/bios_emulator/scitech/bin-linux/libc/ndisasm b/board/MAI/bios_emulator/scitech/bin-linux/libc/ndisasm Binary files differdeleted file mode 100755 index 9fe81a3..0000000 --- a/board/MAI/bios_emulator/scitech/bin-linux/libc/ndisasm +++ /dev/null diff --git a/board/MAI/bios_emulator/scitech/bin-linux/libc/trans b/board/MAI/bios_emulator/scitech/bin-linux/libc/trans Binary files differdeleted file mode 100755 index e536c04..0000000 --- a/board/MAI/bios_emulator/scitech/bin-linux/libc/trans +++ /dev/null diff --git a/board/MAI/bios_emulator/scitech/makedefs/makedefs.prj b/board/MAI/bios_emulator/scitech/makedefs/makedefs.prj Binary files differdeleted file mode 100644 index edd8809..0000000 --- a/board/MAI/bios_emulator/scitech/makedefs/makedefs.prj +++ /dev/null diff --git a/board/MAI/bios_emulator/scitech/src/pm/os2/dossctl.obj b/board/MAI/bios_emulator/scitech/src/pm/os2/dossctl.obj Binary files differdeleted file mode 100644 index 5533346..0000000 --- a/board/MAI/bios_emulator/scitech/src/pm/os2/dossctl.obj +++ /dev/null diff --git a/board/ads5121/u-boot.lds b/board/ads5121/u-boot.lds index 038d849..34ceb0f 100644 --- a/board/ads5121/u-boot.lds +++ b/board/ads5121/u-boot.lds @@ -51,7 +51,6 @@ SECTIONS { cpu/mpc512x/start.o (.text) *(.text) - *(.fixup) *(.got1) . = ALIGN(16); *(.rodata) diff --git a/board/amcc/katmai/init.S b/board/amcc/katmai/init.S index 5202ae6..e3f3da6 100644 --- a/board/amcc/katmai/init.S +++ b/board/amcc/katmai/init.S @@ -67,9 +67,9 @@ tlbtabA: tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I) tlbentry(CFG_PCIE_BASE, SZ_16K, 0x20000000, 0xC, AC_R|AC_W|SA_G|SA_I) - tlbentry(CFG_PCIE0_CFGBASE, SZ_1K, 0x40000000, 0xC, AC_R|AC_W|SA_G|SA_I) - tlbentry(CFG_PCIE1_CFGBASE, SZ_1K, 0x80000000, 0xC, AC_R|AC_W|SA_G|SA_I) - tlbentry(CFG_PCIE2_CFGBASE, SZ_1K, 0xC0000000, 0xC, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE0_CFGBASE, SZ_16M, 0x40000000, 0xC, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE1_CFGBASE, SZ_16M, 0x80000000, 0xC, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE2_CFGBASE, SZ_16M, 0xC0000000, 0xC, AC_R|AC_W|SA_G|SA_I) tlbentry(CFG_PCIE0_XCFGBASE, SZ_1K, 0x50000000, 0xC, AC_R|AC_W|SA_G|SA_I) tlbentry(CFG_PCIE1_XCFGBASE, SZ_1K, 0x90000000, 0xC, AC_R|AC_W|SA_G|SA_I) tlbentry(CFG_PCIE2_XCFGBASE, SZ_1K, 0xD0000000, 0xC, AC_R|AC_W|SA_G|SA_I) @@ -109,9 +109,9 @@ tlbtabB: tlbentry(CFG_PCI_MEMBASE, SZ_256M, 0x10000000, 0xC, AC_R|AC_W|SA_G|SA_I) tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I) - tlbentry(CFG_PCIE0_CFGBASE, SZ_1K, 0x00100000, 0xD, AC_R|AC_W|SA_G|SA_I) - tlbentry(CFG_PCIE1_CFGBASE, SZ_1K, 0x20100000, 0xD, AC_R|AC_W|SA_G|SA_I) - tlbentry(CFG_PCIE2_CFGBASE, SZ_1K, 0x40100000, 0xD, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE0_CFGBASE, SZ_16M, 0x00000000, 0xD, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE1_CFGBASE, SZ_16M, 0x20000000, 0xD, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE2_CFGBASE, SZ_16M, 0x40000000, 0xD, AC_R|AC_W|SA_G|SA_I) tlbentry(CFG_PCIE0_XCFGBASE, SZ_1K, 0x10000000, 0xD, AC_R|AC_W|SA_G|SA_I) tlbentry(CFG_PCIE1_XCFGBASE, SZ_1K, 0x30000000, 0xD, AC_R|AC_W|SA_G|SA_I) tlbentry(CFG_PCIE2_XCFGBASE, SZ_1K, 0x50000000, 0xD, AC_R|AC_W|SA_G|SA_I) diff --git a/board/amcc/katmai/katmai.c b/board/amcc/katmai/katmai.c index b804d55..afd60ec 100644 --- a/board/amcc/katmai/katmai.c +++ b/board/amcc/katmai/katmai.c @@ -392,16 +392,18 @@ int katmai_pcie_card_present(int port) static struct pci_controller pcie_hose[3] = {{0},{0},{0}}; -void pcie_setup_hoses(void) +void pcie_setup_hoses(int busno) { struct pci_controller *hose; int i, bus; + char *env; + unsigned int delay; /* * assume we're called after the PCIX hose is initialized, which takes * bus ID 0 and therefore start numbering PCIe's from 1. */ - bus = 1; + bus = busno; for (i = 0; i <= 2; i++) { /* Check for katmai card presence */ if (!katmai_pcie_card_present(i)) @@ -418,8 +420,8 @@ void pcie_setup_hoses(void) hose = &pcie_hose[i]; hose->first_busno = bus; - hose->last_busno = bus; - bus++; + hose->last_busno = bus; + hose->current_busno = bus; /* setup mem resource */ pci_set_region(hose->regions + 0, @@ -439,10 +441,21 @@ void pcie_setup_hoses(void) */ #else ppc440spe_setup_pcie_rootpoint(hose, i); + + env = getenv ("pciscandelay"); + if (env != NULL) { + delay = simple_strtoul (env, NULL, 10); + if (delay > 5) + printf ("Warning, expect noticable delay before PCIe" + "scan due to 'pciscandelay' value!\n"); + mdelay (delay * 1000); + } + /* * Config access can only go down stream */ hose->last_busno = pci_hose_scan(hose); + bus = hose->last_busno + 1; #endif } } diff --git a/board/amcc/sequoia/cmd_sequoia.c b/board/amcc/sequoia/cmd_sequoia.c index 6fc60ea..f3803c0 100644 --- a/board/amcc/sequoia/cmd_sequoia.c +++ b/board/amcc/sequoia/cmd_sequoia.c @@ -26,76 +26,185 @@ #include <command.h> #include <i2c.h> -static u8 boot_533_nor[] = { - 0x87, 0x78, 0x82, 0x52, 0x09, 0x57, 0xa0, 0x30, - 0x40, 0x08, 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00 -}; +/* + * There are 2 versions of production Sequoia & Rainier platforms. + * The primary difference is the reference clock. Those with + * 33333333 reference clocks will also have 667MHz rated + * processors. Not enough differences to have unique clock + * settings. + * + * NOR and NAND boot options change bytes 6, 7, 8, 9, 11. The + * values are independent of the rest of the clock settings. + * + * All Sequoias & Rainiers select from two possible EEPROMs in Boot + * Config F. One for 33MHz PCI, one for 66MHz PCI. The following + * values are for the 33MHz PCI configuration. Byte 5 (0 base) is + * the only value affected for a 66MHz PCI and simply needs a +0x10. + */ + +#define NAND_COMPATIBLE 0x01 +#define NOR_COMPATIBLE 0x02 + +/* check with Stefan on CFG_I2C_EEPROM_ADDR */ +#define I2C_EEPROM_ADDR 0x52 -static u8 boot_533_nand[] = { - 0x87, 0x78, 0x82, 0x52, 0x09, 0x57, 0xd0, 0x10, - 0xa0, 0x68, 0x23, 0x58, 0x0d, 0x05, 0x00, 0x00 +static char *config_labels[] = { + "CPU: 333 PLB: 133 OPB: 66 EBC: 66", + "CPU: 333 PLB: 166 OPB: 83 EBC: 55", + "CPU: 400 PLB: 133 OPB: 66 EBC: 66", + "CPU: 400 PLB: 160 OPB: 80 EBC: 53", + "CPU: 416 PLB: 166 OPB: 83 EBC: 55", + "CPU: 500 PLB: 166 OPB: 83 EBC: 55", + "CPU: 533 PLB: 133 OPB: 66 EBC: 66", + "CPU: 667 PLB: 166 OPB: 83 EBC: 55", + NULL }; -static u8 boot_667_nor[] = { - 0x87, 0x78, 0xa2, 0x52, 0x09, 0xd7, 0xa0, 0x30, - 0x40, 0x08, 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00 +static u8 boot_configs[][17] = { + { + (NOR_COMPATIBLE), + 0x84, 0x70, 0xa2, 0xa6, 0x05, 0x57, 0xa0, 0x10, 0x40, + 0x08, 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00 + }, + { + (NAND_COMPATIBLE | NOR_COMPATIBLE), + 0xc7, 0x78, 0xf3, 0x4e, 0x05, 0xd7, 0xa0, 0x30, 0x40, + 0x08, 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00 + }, + { + (NOR_COMPATIBLE), + 0x86, 0x78, 0xc2, 0xc6, 0x05, 0x57, 0xa0, 0x30, 0x40, + 0x08, 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00 + }, + { + (NOR_COMPATIBLE), + 0x86, 0x78, 0xc2, 0xa6, 0x05, 0xd7, 0xa0, 0x10, 0x40, + 0x08, 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00 + }, + { + (NAND_COMPATIBLE | NOR_COMPATIBLE), + 0xc6, 0x78, 0x52, 0xa6, 0x05, 0xd7, 0xa0, 0x10, 0x40, + 0x08, 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00 + }, + { + (NAND_COMPATIBLE | NOR_COMPATIBLE), + 0xc7, 0x78, 0x52, 0xc6, 0x05, 0xd7, 0xa0, 0x30, 0x40, + 0x08, 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00 + }, + { + (NOR_COMPATIBLE), + 0x87, 0x78, 0x82, 0x52, 0x09, 0x57, 0xa0, 0x30, 0x40, + 0x08, 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00 + }, + { + (NAND_COMPATIBLE | NOR_COMPATIBLE), + 0x87, 0x78, 0xa2, 0x52, 0x09, 0xd7, 0xa0, 0x30, 0x40, + 0x08, 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00 + }, + { + 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } }; -static u8 boot_667_nand[] = { - 0x87, 0x78, 0xa2, 0x52, 0x09, 0xd7, 0xd0, 0x10, - 0xa0, 0x68, 0x23, 0x58, 0x0d, 0x05, 0x00, 0x00 +/* + * Bytes 6,8,9,11 change for NAND boot + */ +static u8 nand_boot[] = { + 0xd0, 0xa0, 0x68, 0x58 }; static int do_bootstrap(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { - u8 chip; - u8 *buf; - int cpu_freq; + u8 *buf, bNAND; + int x, y, nbytes, selcfg; + extern char console_buffer[]; - if (argc < 3) { + if (argc < 2) { printf("Usage:\n%s\n", cmdtp->usage); return 1; } - cpu_freq = simple_strtol(argv[1], NULL, 10); - if (!((cpu_freq == 533) || (cpu_freq == 667))) { - printf("Unsupported cpu-frequency - only 533 and 667 supported\n"); + if ((strcmp(argv[1], "nor") != 0) && + (strcmp(argv[1], "nand") != 0)) { + printf("Unsupported boot-device - only nor|nand support\n"); return 1; } - /* use 0x52 as I2C EEPROM address for now */ - chip = 0x52; + /* set the nand flag based on provided input */ + if ((strcmp(argv[1], "nand") == 0)) + bNAND = 1; + else + bNAND = 0; - if ((strcmp(argv[2], "nor") != 0) && - (strcmp(argv[2], "nand") != 0)) { - printf("Unsupported boot-device - only nor|nand support\n"); - return 1; - } + printf("Available configurations: \n\n"); - if (strcmp(argv[2], "nand") == 0) { - switch (cpu_freq) { - default: - case 533: - buf = boot_533_nand; - break; - case 667: - buf = boot_667_nand; - break; + if (bNAND) { + for(x = 0, y = 0; boot_configs[x][0] != 0; x++) { + /* filter on nand compatible */ + if (boot_configs[x][0] & NAND_COMPATIBLE) { + printf(" %d - %s\n", (y+1), config_labels[x]); + y++; + } } } else { - switch (cpu_freq) { - default: - case 533: - buf = boot_533_nor; - break; - case 667: - buf = boot_667_nor; - break; + for(x = 0, y = 0; boot_configs[x][0] != 0; x++) { + /* filter on nor compatible */ + if (boot_configs[x][0] & NOR_COMPATIBLE) { + printf(" %d - %s\n", (y+1), config_labels[x]); + y++; + } } } - if (i2c_write(chip, 0, 1, buf, 16) != 0) - printf("Error writing to EEPROM at address 0x%x\n", chip); + do { + nbytes = readline(" Selection [1-x / quit]: "); + + if (nbytes) { + if (strcmp(console_buffer, "quit") == 0) + return 0; + selcfg = simple_strtol(console_buffer, NULL, 10); + if ((selcfg < 1) || (selcfg > y)) + nbytes = 0; + } + } while (nbytes == 0); + + + y = (selcfg - 1); + + for (x = 0; boot_configs[x][0] != 0; x++) { + if (bNAND) { + if (boot_configs[x][0] & NAND_COMPATIBLE) { + if (y > 0) + y--; + else if (y < 1) + break; + } + } else { + if (boot_configs[x][0] & NOR_COMPATIBLE) { + if (y > 0) + y--; + else if (y < 1) + break; + } + } + } + + buf = &boot_configs[x][1]; + + if (bNAND) { + buf[6] = nand_boot[0]; + buf[8] = nand_boot[1]; + buf[9] = nand_boot[2]; + buf[11] = nand_boot[3]; + } + + /* check CPLD register +5 for PCI 66MHz flag */ + if (in8(CFG_BCSR_BASE + 5) & 0x01) + buf[5] += 0x10; + + if (i2c_write(I2C_EEPROM_ADDR, 0, 1, buf, 16) != 0) + printf("Error writing to EEPROM at address 0x%x\n", I2C_EEPROM_ADDR); udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000); printf("Done\n"); @@ -105,7 +214,7 @@ static int do_bootstrap(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } U_BOOT_CMD( - bootstrap, 3, 0, do_bootstrap, + bootstrap, 2, 0, do_bootstrap, "bootstrap - program the I2C bootstrap EEPROM\n", - "<cpu-freq> <nor|nand> - program the I2C bootstrap EEPROM\n" + "<nand|nor> - strap to boot from NAND or NOR flash\n" ); diff --git a/board/amcc/sequoia/init.S b/board/amcc/sequoia/init.S index 45bcd4b..5fe3af9 100644 --- a/board/amcc/sequoia/init.S +++ b/board/amcc/sequoia/init.S @@ -126,6 +126,9 @@ tlbtab: /* TLB-entry for peripherals */ tlbentry( 0xEF000000, SZ_16M, 0xEF000000, 1, AC_R|AC_W|AC_X|SA_G|SA_I) + /* TLB-entry PCI IO Space - from sr@denx.de */ + tlbentry(0xE8000000, SZ_64K, 0xE8000000, 1, AC_R|AC_W|AC_X|SA_G|SA_I) + tlbtab_end #if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) diff --git a/board/amcc/yucca/init.S b/board/amcc/yucca/init.S index c92dcf7..67e8f8f 100644 --- a/board/amcc/yucca/init.S +++ b/board/amcc/yucca/init.S @@ -70,9 +70,9 @@ tlbtabA: tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I) tlbentry(CFG_PCIE_BASE, SZ_16K, 0x20000000, 0xC, AC_R|AC_W|SA_G|SA_I) - tlbentry(CFG_PCIE0_CFGBASE, SZ_1K, 0x40000000, 0xC, AC_R|AC_W|SA_G|SA_I) - tlbentry(CFG_PCIE1_CFGBASE, SZ_1K, 0x80000000, 0xC, AC_R|AC_W|SA_G|SA_I) - tlbentry(CFG_PCIE2_CFGBASE, SZ_1K, 0xC0000000, 0xC, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE0_CFGBASE, SZ_16M, 0x40000000, 0xC, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE1_CFGBASE, SZ_16M, 0x80000000, 0xC, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE2_CFGBASE, SZ_16M, 0xC0000000, 0xC, AC_R|AC_W|SA_G|SA_I) tlbentry(CFG_PCIE0_XCFGBASE, SZ_1K, 0x50000000, 0xC, AC_R|AC_W|SA_G|SA_I) tlbentry(CFG_PCIE1_XCFGBASE, SZ_1K, 0x90000000, 0xC, AC_R|AC_W|SA_G|SA_I) tlbentry(CFG_PCIE2_XCFGBASE, SZ_1K, 0xD0000000, 0xC, AC_R|AC_W|SA_G|SA_I) @@ -112,9 +112,9 @@ tlbtabB: tlbentry(CFG_PCI_MEMBASE, SZ_256M, 0x10000000, 0xC, AC_R|AC_W|SA_G|SA_I) tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I) - tlbentry(CFG_PCIE0_CFGBASE, SZ_1K, 0x00100000, 0xD, AC_R|AC_W|SA_G|SA_I) - tlbentry(CFG_PCIE1_CFGBASE, SZ_1K, 0x20100000, 0xD, AC_R|AC_W|SA_G|SA_I) - tlbentry(CFG_PCIE2_CFGBASE, SZ_1K, 0x40100000, 0xD, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE0_CFGBASE, SZ_16M, 0x00000000, 0xD, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE1_CFGBASE, SZ_16M, 0x20000000, 0xD, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE2_CFGBASE, SZ_16M, 0x40000000, 0xD, AC_R|AC_W|SA_G|SA_I) tlbentry(CFG_PCIE0_XCFGBASE, SZ_1K, 0x10000000, 0xD, AC_R|AC_W|SA_G|SA_I) tlbentry(CFG_PCIE1_XCFGBASE, SZ_1K, 0x30000000, 0xD, AC_R|AC_W|SA_G|SA_I) tlbentry(CFG_PCIE2_XCFGBASE, SZ_1K, 0x50000000, 0xD, AC_R|AC_W|SA_G|SA_I) diff --git a/board/amcc/yucca/yucca.c b/board/amcc/yucca/yucca.c index d08fcf3..397b018 100644 --- a/board/amcc/yucca/yucca.c +++ b/board/amcc/yucca/yucca.c @@ -846,16 +846,18 @@ void yucca_setup_pcie_fpga_endpoint(int port) static struct pci_controller pcie_hose[3] = {{0},{0},{0}}; -void pcie_setup_hoses(void) +void pcie_setup_hoses(int busno) { struct pci_controller *hose; int i, bus; + char *env; + unsigned int delay; /* * assume we're called after the PCIX hose is initialized, which takes * bus ID 0 and therefore start numbering PCIe's from 1. */ - bus = 1; + bus = busno; for (i = 0; i <= 2; i++) { /* Check for yucca card presence */ if (!yucca_pcie_card_present(i)) @@ -874,8 +876,8 @@ void pcie_setup_hoses(void) hose = &pcie_hose[i]; hose->first_busno = bus; - hose->last_busno = bus; - bus++; + hose->last_busno = bus; + hose->current_busno = bus; /* setup mem resource */ pci_set_region(hose->regions + 0, @@ -895,10 +897,21 @@ void pcie_setup_hoses(void) */ #else ppc440spe_setup_pcie_rootpoint(hose, i); + + env = getenv ("pciscandelay"); + if (env != NULL) { + delay = simple_strtoul (env, NULL, 10); + if (delay > 5) + printf ("Warning, expect noticable delay before PCIe" + "scan due to 'pciscandelay' value!\n"); + mdelay (delay * 1000); + } + /* * Config access can only go down stream */ hose->last_busno = pci_hose_scan(hose); + bus = hose->last_busno + 1; #endif } } diff --git a/board/cds/mpc8548cds/mpc8548cds.c b/board/cds/mpc8548cds/mpc8548cds.c index 48753d7..36d7e1e 100644 --- a/board/cds/mpc8548cds/mpc8548cds.c +++ b/board/cds/mpc8548cds/mpc8548cds.c @@ -362,20 +362,28 @@ pci_init_board(void) ); - /* outbound memory */ + /* inbound */ pci_set_region(hose->regions + 0, + CFG_PCI_MEMORY_BUS, + CFG_PCI_MEMORY_PHYS, + CFG_PCI_MEMORY_SIZE, + PCI_REGION_MEM | PCI_REGION_MEMORY); + + + /* outbound memory */ + pci_set_region(hose->regions + 1, CFG_PCI1_MEM_BASE, CFG_PCI1_MEM_PHYS, CFG_PCI1_MEM_SIZE, PCI_REGION_MEM); /* outbound io */ - pci_set_region(hose->regions + 1, + pci_set_region(hose->regions + 2, CFG_PCI1_IO_BASE, CFG_PCI1_IO_PHYS, CFG_PCI1_IO_SIZE, PCI_REGION_IO); - hose->region_count = 2; + hose->region_count = 3; /* relocate config table pointers */ hose->config_table = \ @@ -534,7 +542,7 @@ ft_pci_setup(void *blob, bd_t *bd) #endif #ifdef CONFIG_PCIE1 - p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@a000/bus-range", &len); + p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pcie@a000/bus-range", &len); if (p != NULL) { p[0] = 0; p[1] = pcie1_hose.last_busno - pcie1_hose.first_busno; diff --git a/board/cobra5272/Makefile b/board/cobra5272/Makefile index cf07cf4..be704b7 100644 --- a/board/cobra5272/Makefile +++ b/board/cobra5272/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -COBJS = $(BOARD).o flash.o +COBJS = $(BOARD).o flash.o mii.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/cobra5272/cobra5272.c b/board/cobra5272/cobra5272.c index 26adb4a..86c7ee1 100644 --- a/board/cobra5272/cobra5272.c +++ b/board/cobra5272/cobra5272.c @@ -22,8 +22,7 @@ */ #include <common.h> -#include <asm/m5272.h> -#include <asm/immap_5272.h> +#include <asm/immap.h> int checkboard (void) @@ -35,7 +34,7 @@ int checkboard (void) long int initdram (int board_type) { - volatile sdramctrl_t *sdp = (sdramctrl_t *) (CFG_MBAR + MCFSIM_SDCR); + volatile sdramctrl_t *sdp = (sdramctrl_t *) (MMAP_SDRAM); sdp->sdram_sdtr = 0xf539; sdp->sdram_sdcr = 0x4211; diff --git a/board/cobra5272/mii.c b/board/cobra5272/mii.c new file mode 100644 index 0000000..fadcbb3 --- /dev/null +++ b/board/cobra5272/mii.c @@ -0,0 +1,303 @@ +/* + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/fec.h> +#include <asm/immap.h> + +#include <config.h> +#include <net.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) +#undef MII_DEBUG +#undef ET_DEBUG + +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + if (setclear) { + gpio->gpio_pbcnt |= GPIO_PBCNT_E_MDC | GPIO_PBCNT_E_RXER | GPIO_PBCNT_E_RXD1 | GPIO_PBCNT_E_RXD2 | GPIO_PBCNT_E_RXD3 | GPIO_PBCNT_E_TXD1 | GPIO_PBCNT_E_TXD2 | GPIO_PBCNT_E_TXD3; + } else { + } + return 0; +} + +#if defined(CFG_DISCOVER_PHY) || defined(CONFIG_CMD_MII) +#include <miiphy.h> + +/* Make MII read/write commands for the FEC. */ +#define mk_mii_read(ADDR, REG) (0x60020000 | ((ADDR << 23) | (REG & 0x1f) << 18)) + +#define mk_mii_write(ADDR, REG, VAL) (0x50020000 | ((ADDR << 23) | (REG & 0x1f) << 18) | (VAL & 0xffff)) + +/* PHY identification */ +#define PHY_ID_LXT970 0x78100000 /* LXT970 */ +#define PHY_ID_LXT971 0x001378e0 /* LXT971 and 972 */ +#define PHY_ID_82555 0x02a80150 /* Intel 82555 */ +#define PHY_ID_QS6612 0x01814400 /* QS6612 */ +#define PHY_ID_AMD79C784 0x00225610 /* AMD 79C784 */ +#define PHY_ID_AMD79C874VC 0x0022561B /* AMD 79C874 */ +#define PHY_ID_LSI80225 0x0016f870 /* LSI 80225 */ +#define PHY_ID_LSI80225B 0x0016f880 /* LSI 80225/B */ +#define PHY_ID_DP83848VV 0x20005C90 /* National 83848 */ +#define PHY_ID_DP83849 0x20005CA2 /* National 82849 */ + +#define STR_ID_LXT970 "LXT970" +#define STR_ID_LXT971 "LXT971" +#define STR_ID_82555 "Intel82555" +#define STR_ID_QS6612 "QS6612" +#define STR_ID_AMD79C784 "AMD79C784" +#define STR_ID_AMD79C874VC "AMD79C874VC" +#define STR_ID_LSI80225 "LSI80225" +#define STR_ID_LSI80225B "LSI80225/B" +#define STR_ID_DP83848VV "N83848" +#define STR_ID_DP83849 "N83849" + +/**************************************************************************** + * mii_init -- Initialize the MII for MII command without ethernet + * This function is a subset of eth_init + **************************************************************************** + */ +void mii_reset(struct fec_info_s *info) +{ + volatile fec_t *fecp = (fec_t *) (info->miibase); + int i; + + fecp->ecr = FEC_ECR_RESET; + for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i) { + udelay(1); + } + if (i == FEC_RESET_DELAY) { + printf("FEC_RESET_DELAY timeout\n"); + } +} + +/* send command to phy using mii, wait for result */ +uint mii_send(uint mii_cmd) +{ + struct fec_info_s *info; + struct eth_device *dev; + volatile fec_t *ep; + uint mii_reply; + int j = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + ep = (fec_t *) info->miibase; + + ep->mmfr = mii_cmd; /* command to phy */ + + /* wait for mii complete */ + while (!(ep->eir & FEC_EIR_MII) && (j < MCFFEC_TOUT_LOOP)) { + udelay(1); + j++; + } + if (j >= MCFFEC_TOUT_LOOP) { + printf("MII not complete\n"); + return -1; + } + + mii_reply = ep->mmfr; /* result from phy */ + ep->eir = FEC_EIR_MII; /* clear MII complete */ +#ifdef ET_DEBUG + printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n", + __FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply); +#endif + + return (mii_reply & 0xffff); /* data read from phy */ +} +#endif /* CFG_DISCOVER_PHY || (CONFIG_COMMANDS & CONFIG_CMD_MII) */ + +#if defined(CFG_DISCOVER_PHY) +int mii_discover_phy(struct eth_device *dev) +{ +#define MAX_PHY_PASSES 11 + struct fec_info_s *info = dev->priv; + int phyaddr, pass; + uint phyno, phytype; + + if (info->phyname_init) + return info->phy_addr; + + phyaddr = -1; /* didn't find a PHY yet */ + for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) { + if (pass > 1) { + /* PHY may need more time to recover from reset. + * The LXT970 needs 50ms typical, no maximum is + * specified, so wait 10ms before try again. + * With 11 passes this gives it 100ms to wake up. + */ + udelay(10000); /* wait 10ms */ + } + + for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) { + + phytype = mii_send(mk_mii_read(phyno, PHY_PHYIDR1)); +#ifdef ET_DEBUG + printf("PHY type 0x%x pass %d type\n", phytype, pass); +#endif + if (phytype != 0xffff) { + phyaddr = phyno; + phytype <<= 16; + phytype |= + mii_send(mk_mii_read(phyno, PHY_PHYIDR2)); + + switch (phytype & 0xffffffff) { + case PHY_ID_AMD79C874VC: + strcpy(info->phy_name, + STR_ID_AMD79C874VC); + info->phyname_init = 1; + break; + default: + strcpy(info->phy_name, "unknown"); + info->phyname_init = 1; + break; + } + +#ifdef ET_DEBUG + printf("PHY @ 0x%x pass %d type ", phyno, pass); + switch (phytype & 0xffffffff) { + case PHY_ID_AMD79C874VC: + printf(STR_ID_AMD79C874VC); + break; + default: + printf("0x%08x\n", phytype); + break; + } +#endif + } + } + } + if (phyaddr < 0) + printf("No PHY device found.\n"); + + return phyaddr; +} +#endif /* CFG_DISCOVER_PHY */ + +int mii_init(void) __attribute__((weak,alias("__mii_init"))); + +void __mii_init(void) +{ + volatile fec_t *fecp; + struct fec_info_s *info; + struct eth_device *dev; + int miispd = 0, i = 0; + u16 autoneg = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + fecp = (fec_t *) info->miibase; + + fecpin_setclear(dev, 1); + + mii_reset(info); + + /* We use strictly polling mode only */ + fecp->eimr = 0; + + /* Clear any pending interrupt */ + fecp->eir = 0xffffffff; + + /* Set MII speed */ + miispd = (gd->bus_clk / 1000000) / 5; + fecp->mscr = miispd << 1; + + info->phy_addr = mii_discover_phy(dev); + +#define AUTONEGLINK (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS) + while (i < MCFFEC_TOUT_LOOP) { + autoneg = 0; + miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &autoneg); + i++; + + if ((autoneg & AUTONEGLINK) == AUTONEGLINK) + break; + + udelay(500); + } + if (i >= MCFFEC_TOUT_LOOP) { + printf("Auto Negotiation not complete\n"); + } + + /* adapt to the half/full speed settings */ + info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16; + info->dup_spd |= miiphy_speed(dev->name, info->phy_addr); +} + +/***************************************************************************** + * Read and write a MII PHY register, routines used by MII Utilities + * + * FIXME: These routines are expected to return 0 on success, but mii_send + * does _not_ return an error code. Maybe 0xFFFF means error, i.e. + * no PHY connected... + * For now always return 0. + * FIXME: These routines only work after calling eth_init() at least once! + * Otherwise they hang in mii_send() !!! Sorry! + *****************************************************************************/ + +int mcffec_miiphy_read(char *devname, unsigned char addr, unsigned char reg, + unsigned short *value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_read(0x%x) @ 0x%x = ", reg, addr); +#endif + rdreg = mii_send(mk_mii_read(addr, reg)); + + *value = rdreg; + +#ifdef MII_DEBUG + printf("0x%04x\n", *value); +#endif + + return 0; +} + +int mcffec_miiphy_write(char *devname, unsigned char addr, unsigned char reg, + unsigned short value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_write(0x%x) @ 0x%x = ", reg, addr); +#endif + + rdreg = mii_send(mk_mii_write(addr, reg, value)); + +#ifdef MII_DEBUG + printf("0x%04x\n", value); +#endif + + return 0; +} + +#endif /* CONFIG_CMD_NET, FEC_ENET & NET_MULTI */ diff --git a/board/esd/ash405/Makefile b/board/esd/ash405/Makefile index 4d75868..308f752 100644 --- a/board/esd/ash405/Makefile +++ b/board/esd/ash405/Makefile @@ -28,7 +28,9 @@ endif LIB = $(obj)lib$(BOARD).a -COBJS = $(BOARD).o flash.o ../common/misc.o +COBJS = $(BOARD).o flash.o \ + ../common/misc.o \ + ../common/esd405ep_nand.o \ SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/esd/ash405/ash405.c b/board/esd/ash405/ash405.c index f41eb7b..8a5b03b 100644 --- a/board/esd/ash405/ash405.c +++ b/board/esd/ash405/ash405.c @@ -23,6 +23,7 @@ #include <common.h> #include <asm/processor.h> +#include <asm/io.h> #include <command.h> #include <malloc.h> @@ -33,6 +34,7 @@ #endif extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +extern void lxt971_no_sleep(void); /* fpga configuration data - gzip compressed and generated by bin2c */ const unsigned char fpgadata[] = @@ -164,18 +166,12 @@ int misc_init_r (void) /* * Reset external DUARTs */ - out32(GPIO0_OR, in32(GPIO0_OR) | CFG_DUART_RST); /* set reset to high */ + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_DUART_RST); udelay(10); /* wait 10us */ - out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_DUART_RST); /* set reset to low */ + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CFG_DUART_RST); udelay(1000); /* wait 1ms */ /* - * Set NAND-FLASH GPIO signals to default - */ - out32(GPIO0_OR, in32(GPIO0_OR) & ~(CFG_NAND_CLE | CFG_NAND_ALE)); - out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND_CE); - - /* * Enable interrupts in exar duart mcr[3] */ *duart0_mcr = 0x08; @@ -218,35 +214,17 @@ long int initdram (int board_type) mtdcr(memcfga, mem_mb0cf); val = mfdcr(memcfgd); -#if 0 - printf("\nmb0cf=%x\n", val); /* test-only */ - printf("strap=%x\n", mfdcr(strap)); /* test-only */ -#endif - return (4*1024*1024 << ((val & 0x000e0000) >> 17)); } /* ------------------------------------------------------------------------- */ -int testdram (void) +void reset_phy(void) { - /* TODO: XXX XXX XXX */ - printf ("test: 16 MB - ok\n"); - - return (0); -} - -/* ------------------------------------------------------------------------- */ - -#if defined(CONFIG_CMD_NAND) -#include <linux/mtd/nand_legacy.h> -extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; - -void nand_init(void) -{ - nand_probe(CFG_NAND_BASE); - if (nand_dev_desc[0].ChipID != NAND_ChipID_UNKNOWN) { - print_size(nand_dev_desc[0].totlen, "\n"); - } -} +#ifdef CONFIG_LXT971_NO_SLEEP + /* + * Disable sleep mode in LXT971 + */ + lxt971_no_sleep(); #endif +} diff --git a/board/esd/cms700/Makefile b/board/esd/cms700/Makefile index df48766..0d4ab2d 100644 --- a/board/esd/cms700/Makefile +++ b/board/esd/cms700/Makefile @@ -33,7 +33,10 @@ CPLD = ../common/xilinx_jtag/lenval.o \ ../common/xilinx_jtag/micro.o \ ../common/xilinx_jtag/ports.o -COBJS = $(BOARD).o flash.o ../common/misc.o $(CPLD) +COBJS = $(BOARD).o flash.o \ + ../common/misc.o \ + $(CPLD) \ + ../common/esd405ep_nand.o \ SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/esd/cms700/cms700.c b/board/esd/cms700/cms700.c index 635ba2f..2cdd7be 100644 --- a/board/esd/cms700/cms700.c +++ b/board/esd/cms700/cms700.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2005 + * (C) Copyright 2005-2007 * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com * * See file CREDITS for list of people who contributed to this @@ -23,6 +23,7 @@ #include <common.h> #include <asm/processor.h> +#include <asm/io.h> #include <command.h> #include <malloc.h> @@ -68,9 +69,9 @@ int board_early_init_f (void) /* * Reset CPLD via GPIO12 (CS3) pin */ - out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_PLD_RESET); + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CFG_PLD_RESET); udelay(1000); /* wait 1ms */ - out32(GPIO0_OR, in32(GPIO0_OR) | CFG_PLD_RESET); + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_PLD_RESET); udelay(1000); /* wait 1ms */ return 0; @@ -94,13 +95,7 @@ int misc_init_r (void) /* * Setup and enable EEPROM write protection */ - out32(GPIO0_OR, in32(GPIO0_OR) | CFG_EEPROM_WP); - - /* - * Set NAND-FLASH GPIO signals to default - */ - out32(GPIO0_OR, in32(GPIO0_OR) & ~(CFG_NAND_CLE | CFG_NAND_ALE)); - out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND_CE); + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_EEPROM_WP); return (0); } @@ -153,11 +148,6 @@ long int initdram (int board_type) mtdcr(memcfga, mem_mb0cf); val = mfdcr(memcfgd); -#if 0 - printf("\nmb0cf=%x\n", val); /* test-only */ - printf("strap=%x\n", mfdcr(strap)); /* test-only */ -#endif - return (4*1024*1024 << ((val & 0x000e0000) >> 17)); } @@ -180,17 +170,17 @@ int eeprom_write_enable (unsigned dev_addr, int state) switch (state) { case 1: /* Enable write access, clear bit GPIO_SINT2. */ - out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_EEPROM_WP); + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CFG_EEPROM_WP); state = 0; break; case 0: /* Disable write access, set bit GPIO_SINT2. */ - out32(GPIO0_OR, in32(GPIO0_OR) | CFG_EEPROM_WP); + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_EEPROM_WP); state = 0; break; default: /* Read current status back. */ - state = (0 == (in32(GPIO0_OR) & CFG_EEPROM_WP)); + state = (0 == (in_be32((void *)GPIO0_OR) & CFG_EEPROM_WP)); break; } } @@ -235,19 +225,6 @@ U_BOOT_CMD(eepwren, 2, 0, do_eep_wren, /* ------------------------------------------------------------------------- */ -#if defined(CONFIG_CMD_NAND) -#include <linux/mtd/nand_legacy.h> -extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; - -void nand_init(void) -{ - nand_probe(CFG_NAND_BASE); - if (nand_dev_desc[0].ChipID != NAND_ChipID_UNKNOWN) { - print_size(nand_dev_desc[0].totlen, "\n"); - } -} -#endif - void reset_phy(void) { #ifdef CONFIG_LXT971_NO_SLEEP diff --git a/board/esd/common/auto_update.c b/board/esd/common/auto_update.c index 62f6c20..a76b00f 100644 --- a/board/esd/common/auto_update.c +++ b/board/esd/common/auto_update.c @@ -24,14 +24,12 @@ #include <common.h> -#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY) -#warning CFG_NAND_LEGACY not defined in a file using the legacy NAND support! -#endif - #include <command.h> #include <image.h> #include <asm/byteorder.h> +#if defined(CFG_NAND_LEGACY) #include <linux/mtd/nand_legacy.h> +#endif #include <fat.h> #include <part.h> @@ -294,6 +292,8 @@ int au_do_update(int i, long sz) rc = nand_legacy_rw(nand_dev_desc, NANDRW_WRITE | NANDRW_JFFS2, start, nbytes, (size_t *)&total, (uchar *)addr); debug ("nand_legacy_rw: ret=%x total=%d nbytes=%d\n", rc, total, nbytes); +#else + rc = -1; #endif } if (rc != 0) { diff --git a/board/esd/common/esd405ep_nand.c b/board/esd/common/esd405ep_nand.c new file mode 100644 index 0000000..7bf6847 --- /dev/null +++ b/board/esd/common/esd405ep_nand.c @@ -0,0 +1,87 @@ +/* + * (C) Copyright 2007 + * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.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> + +#if defined(CONFIG_CMD_NAND) +#include <asm/io.h> +#include <nand.h> + +/* + * hardware specific access to control-lines + */ +static void esd405ep_nand_hwcontrol(struct mtd_info *mtdinfo, int cmd) +{ + switch(cmd) { + case NAND_CTL_SETCLE: + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_NAND_CLE); + break; + case NAND_CTL_CLRCLE: + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CFG_NAND_CLE); + break; + case NAND_CTL_SETALE: + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_NAND_ALE); + break; + case NAND_CTL_CLRALE: + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CFG_NAND_ALE); + break; + case NAND_CTL_SETNCE: + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CFG_NAND_CE); + break; + case NAND_CTL_CLRNCE: + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_NAND_CE); + break; + } +} + + +/* + * read device ready pin + */ +static int esd405ep_nand_device_ready(struct mtd_info *mtdinfo) +{ + if (in_be32((void *)GPIO0_IR) & CFG_NAND_RDY) + return 1; + return 0; +} + + +int board_nand_init(struct nand_chip *nand) +{ + /* + * Set NAND-FLASH GPIO signals to defaults + */ + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~(CFG_NAND_CLE | CFG_NAND_ALE)); + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_NAND_CE); + + /* + * Initialize nand_chip structure + */ + nand->hwcontrol = esd405ep_nand_hwcontrol; + nand->dev_ready = esd405ep_nand_device_ready; + nand->eccmode = NAND_ECC_SOFT; + nand->chip_delay = NAND_BIG_DELAY_US; + nand->options = NAND_SAMSUNG_LP_OPTIONS; + return 0; +} +#endif diff --git a/board/esd/cpci750/cpci750.c b/board/esd/cpci750/cpci750.c index 17e3568..298aa6a 100644 --- a/board/esd/cpci750/cpci750.c +++ b/board/esd/cpci750/cpci750.c @@ -55,6 +55,71 @@ #define DP(x) #endif +static char show_config_tab[][15] = {{"PCI0DLL_2 "}, /* 31 */ + {"PCI0DLL_1 "}, /* 30 */ + {"PCI0DLL_0 "}, /* 29 */ + {"PCI1DLL_2 "}, /* 28 */ + {"PCI1DLL_1 "}, /* 27 */ + {"PCI1DLL_0 "}, /* 26 */ + {"BbEP2En "}, /* 25 */ + {"SDRAMRdDataDel"}, /* 24 */ + {"SDRAMRdDel "}, /* 23 */ + {"SDRAMSync "}, /* 22 */ + {"SDRAMPipeSel_1"}, /* 21 */ + {"SDRAMPipeSel_0"}, /* 20 */ + {"SDRAMAddDel "}, /* 19 */ + {"SDRAMClkSel "}, /* 18 */ + {"Reserved(1!) "}, /* 17 */ + {"PCIRty "}, /* 16 */ + {"BootCSWidth_1 "}, /* 15 */ + {"BootCSWidth_0 "}, /* 14 */ + {"PCI1PadsCal "}, /* 13 */ + {"PCI0PadsCal "}, /* 12 */ + {"MultiMVId_1 "}, /* 11 */ + {"MultiMVId_0 "}, /* 10 */ + {"MultiGTEn "}, /* 09 */ + {"Int60xArb "}, /* 08 */ + {"CPUBusConfig_1"}, /* 07 */ + {"CPUBusConfig_0"}, /* 06 */ + {"DefIntSpc "}, /* 05 */ + {0 }, /* 04 */ + {"SROMAdd_1 "}, /* 03 */ + {"SROMAdd_0 "}, /* 02 */ + {"DRAMPadCal "}, /* 01 */ + {"SInitEn "}, /* 00 */ + {0 }, /* 31 */ + {0 }, /* 30 */ + {0 }, /* 29 */ + {0 }, /* 28 */ + {0 }, /* 27 */ + {0 }, /* 26 */ + {0 }, /* 25 */ + {0 }, /* 24 */ + {0 }, /* 23 */ + {0 }, /* 22 */ + {"JTAGCalBy "}, /* 21 */ + {"GB2Sel "}, /* 20 */ + {"GB1Sel "}, /* 19 */ + {"DRAMPLL_MDiv_5"}, /* 18 */ + {"DRAMPLL_MDiv_4"}, /* 17 */ + {"DRAMPLL_MDiv_3"}, /* 16 */ + {"DRAMPLL_MDiv_2"}, /* 15 */ + {"DRAMPLL_MDiv_1"}, /* 14 */ + {"DRAMPLL_MDiv_0"}, /* 13 */ + {"GB0Sel "}, /* 12 */ + {"DRAMPLLPU "}, /* 11 */ + {"DRAMPLL_HIKVCO"}, /* 10 */ + {"DRAMPLLNP "}, /* 09 */ + {"DRAMPLL_NDiv_7"}, /* 08 */ + {"DRAMPLL_NDiv_6"}, /* 07 */ + {"CPUPadCal "}, /* 06 */ + {"DRAMPLL_NDiv_5"}, /* 05 */ + {"DRAMPLL_NDiv_4"}, /* 04 */ + {"DRAMPLL_NDiv_3"}, /* 03 */ + {"DRAMPLL_NDiv_2"}, /* 02 */ + {"DRAMPLL_NDiv_1"}, /* 01 */ + {"DRAMPLL_NDiv_0"}}; /* 00 */ + extern void flush_data_cache (void); extern void invalidate_l1_instruction_cache (void); extern flash_info_t flash_info[]; @@ -901,21 +966,37 @@ void board_prebootm_init () dcache_disable (); } - -int do_show_cfg(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_show_config(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { unsigned int reset_sample_low; unsigned int reset_sample_high; + unsigned int l, l1, l2; GT_REG_READ(0x3c4, &reset_sample_low); GT_REG_READ(0x3d4, &reset_sample_high); printf("Reset configuration 0x%08x 0x%08x\n", reset_sample_low, reset_sample_high); + l2 = 0; + for (l=0; l<63; l++) { + if (show_config_tab[l][0] != 0) { + printf("%14s:%1x ", show_config_tab[l], + ((reset_sample_low >> (31 - (l & 0x1f)))) & 0x01); + l2++; + if ((l2 % 4) == 0) + printf("\n"); + } else { + l1++; + } + if (l == 32) + reset_sample_low = reset_sample_high; + } + printf("\n"); + return(0); } U_BOOT_CMD( - show_cfg, 1, 1, do_show_cfg, - "show_cfg- Show Marvell strapping register\n", + show_config, 1, 1, do_show_config, + "show_config - Show Marvell strapping register\n", "Show Marvell strapping register (ResetSampleLow ResetSampleHigh)\n" ); diff --git a/board/esd/cpci750/ide.c b/board/esd/cpci750/ide.c index 01b90c6..0adafe2 100644 --- a/board/esd/cpci750/ide.c +++ b/board/esd/cpci750/ide.c @@ -43,6 +43,8 @@ int ide_preinit (void) ide_bus_offset[l] = -ATA_STATUS; } devbusfn = pci_find_device (0x1103, 0x0004, 0); + if (devbusfn == -1) + devbusfn = pci_find_device (0x1095, 0x3114, 0); if (devbusfn != -1) { status = 0; diff --git a/board/esd/hh405/Makefile b/board/esd/hh405/Makefile index ce7876c..0e5e57a 100644 --- a/board/esd/hh405/Makefile +++ b/board/esd/hh405/Makefile @@ -28,7 +28,10 @@ endif LIB = $(obj)lib$(BOARD).a -COBJS = $(BOARD).o flash.o ../common/misc.o ../common/auto_update.o +COBJS = $(BOARD).o flash.o \ + ../common/misc.o \ + ../common/esd405ep_nand.o \ + ../common/auto_update.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/esd/hh405/hh405.c b/board/esd/hh405/hh405.c index 9ef5907..67b5d54 100644 --- a/board/esd/hh405/hh405.c +++ b/board/esd/hh405/hh405.c @@ -5,7 +5,7 @@ * (C) Copyright 2005 * Stefan Roese, DENX Software Engineering, sr@denx.de. * - * (C) Copyright 2006 + * (C) Copyright 2006-2007 * Matthias Fuchs, esd GmbH, matthias.fuchs@esd-electronics.com * * See file CREDITS for list of people who contributed to this @@ -477,12 +477,6 @@ int misc_init_r (void) out32(GPIO0_OR, in32(GPIO0_OR) | CFG_EEPROM_WP); /* - * Set NAND-FLASH GPIO signals to default - */ - out32(GPIO0_OR, in32(GPIO0_OR) & ~(CFG_NAND_CLE | CFG_NAND_ALE)); - out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND_CE); - - /* * Reset touch-screen controller */ out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_TOUCH_RST); @@ -690,20 +684,6 @@ void ide_set_reset(int on) #endif /* CONFIG_IDE_RESET */ -#if defined(CONFIG_CMD_NAND) -#include <linux/mtd/nand_legacy.h> -extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; - -void nand_init(void) -{ - nand_probe(CFG_NAND_BASE); - if (nand_dev_desc[0].ChipID != NAND_ChipID_UNKNOWN) { - print_size(nand_dev_desc[0].totlen, "\n"); - } -} -#endif - - #if defined(CFG_EEPROM_WREN) /* Input: <dev_addr> I2C address of EEPROM device to enable. * <state> -1: deliver current state diff --git a/board/esd/hub405/Makefile b/board/esd/hub405/Makefile index 4d75868..308f752 100644 --- a/board/esd/hub405/Makefile +++ b/board/esd/hub405/Makefile @@ -28,7 +28,9 @@ endif LIB = $(obj)lib$(BOARD).a -COBJS = $(BOARD).o flash.o ../common/misc.o +COBJS = $(BOARD).o flash.o \ + ../common/misc.o \ + ../common/esd405ep_nand.o \ SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/esd/hub405/hub405.c b/board/esd/hub405/hub405.c index dd3706e..25c8068 100644 --- a/board/esd/hub405/hub405.c +++ b/board/esd/hub405/hub405.c @@ -153,12 +153,6 @@ int misc_init_r (void) out32(GPIO0_OR, val); /* - * Set NAND-FLASH GPIO signals to default - */ - out32(GPIO0_OR, in32(GPIO0_OR) & ~(CFG_NAND_CLE | CFG_NAND_ALE)); - out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND_CE); - - /* * check board type and setup AP power */ str = getenv("bd_type"); /* this is only set on non prototype hardware */ @@ -242,33 +236,5 @@ long int initdram (int board_type) mtdcr(memcfga, mem_mb0cf); val = mfdcr(memcfgd); -#if 0 - printf("\nmb0cf=%x\n", val); /* test-only */ - printf("strap=%x\n", mfdcr(strap)); /* test-only */ -#endif - return (4*1024*1024 << ((val & 0x000e0000) >> 17)); } - - -int testdram (void) -{ - /* TODO: XXX XXX XXX */ - printf ("test: 16 MB - ok\n"); - - return (0); -} - - -#if defined(CONFIG_CMD_NAND) -#include <linux/mtd/nand_legacy.h> -extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; - -void nand_init(void) -{ - nand_probe(CFG_NAND_BASE); - if (nand_dev_desc[0].ChipID != NAND_ChipID_UNKNOWN) { - print_size(nand_dev_desc[0].totlen, "\n"); - } -} -#endif diff --git a/board/esd/plu405/Makefile b/board/esd/plu405/Makefile index ce7876c..0e5e57a 100644 --- a/board/esd/plu405/Makefile +++ b/board/esd/plu405/Makefile @@ -28,7 +28,10 @@ endif LIB = $(obj)lib$(BOARD).a -COBJS = $(BOARD).o flash.o ../common/misc.o ../common/auto_update.o +COBJS = $(BOARD).o flash.o \ + ../common/misc.o \ + ../common/esd405ep_nand.o \ + ../common/auto_update.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/esd/plu405/plu405.c b/board/esd/plu405/plu405.c index 920f717..f026a7a 100644 --- a/board/esd/plu405/plu405.c +++ b/board/esd/plu405/plu405.c @@ -23,6 +23,7 @@ #include <common.h> #include <asm/processor.h> +#include <asm/io.h> #include <command.h> #include <malloc.h> @@ -31,6 +32,8 @@ #define FPGA_DEBUG #endif +DECLARE_GLOBAL_DATA_PTR; + extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); extern void lxt971_no_sleep(void); @@ -114,6 +117,10 @@ int misc_init_r (void) int index; int i; + /* adjust flash start and offset */ + gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize; + gd->bd->bi_flashoffset = 0; + dst = malloc(CFG_FPGA_MAX_SIZE); if (gunzip (dst, CFG_FPGA_MAX_SIZE, (uchar *)fpgadata, &len) != 0) { printf ("GUNZIP ERROR - must RESET board to recover\n"); @@ -177,18 +184,12 @@ int misc_init_r (void) /* * Reset external DUARTs */ - out32(GPIO0_OR, in32(GPIO0_OR) | CFG_DUART_RST); /* set reset to high */ + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_DUART_RST); udelay(10); /* wait 10us */ - out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_DUART_RST); /* set reset to low */ + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CFG_DUART_RST); udelay(1000); /* wait 1ms */ /* - * Set NAND-FLASH GPIO signals to default - */ - out32(GPIO0_OR, in32(GPIO0_OR) & ~(CFG_NAND_CLE | CFG_NAND_ALE)); - out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND_CE); - - /* * Enable interrupts in exar duart mcr[3] */ *duart0_mcr = 0x08; @@ -226,24 +227,10 @@ long int initdram (int board_type) mtdcr(memcfga, mem_mb0cf); val = mfdcr(memcfgd); -#if 0 - printf("\nmb0cf=%x\n", val); /* test-only */ - printf("strap=%x\n", mfdcr(strap)); /* test-only */ -#endif - return (4*1024*1024 << ((val & 0x000e0000) >> 17)); } -int testdram (void) -{ - /* TODO: XXX XXX XXX */ - printf ("test: 16 MB - ok\n"); - - return (0); -} - - #ifdef CONFIG_IDE_RESET void ide_set_reset(int on) { @@ -262,31 +249,6 @@ void ide_set_reset(int on) #endif /* CONFIG_IDE_RESET */ -#if defined(CONFIG_CMD_NAND) -#include <linux/mtd/nand_legacy.h> -extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; - -void nand_init(void) -{ - nand_probe(CFG_NAND_BASE); - if (nand_dev_desc[0].ChipID != NAND_ChipID_UNKNOWN) { - print_size(nand_dev_desc[0].totlen, "\n"); - } -} -#endif - - -#ifdef CONFIG_AUTO_UPDATE_SHOW -void board_auto_update_show(int au_active) -{ - if (au_active) { - printf("\n Dies ist die board-funktion: Updating!!!\n"); - } else { - printf("\n Dies ist die board-funktion: Updating done!!!\n"); - } -} -#endif - void reset_phy(void) { #ifdef CONFIG_LXT971_NO_SLEEP diff --git a/board/esd/voh405/Makefile b/board/esd/voh405/Makefile index 4d75868..308f752 100644 --- a/board/esd/voh405/Makefile +++ b/board/esd/voh405/Makefile @@ -28,7 +28,9 @@ endif LIB = $(obj)lib$(BOARD).a -COBJS = $(BOARD).o flash.o ../common/misc.o +COBJS = $(BOARD).o flash.o \ + ../common/misc.o \ + ../common/esd405ep_nand.o \ SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/esd/voh405/voh405.c b/board/esd/voh405/voh405.c index 3e118e7..2857a0be 100644 --- a/board/esd/voh405/voh405.c +++ b/board/esd/voh405/voh405.c @@ -195,12 +195,6 @@ int misc_init_r (void) udelay(1000); /* wait 1ms */ /* - * Set NAND-FLASH GPIO signals to default - */ - out32(GPIO0_OR, in32(GPIO0_OR) & ~(CFG_NAND_CLE | CFG_NAND_ALE)); - out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND_CE); - - /* * Enable interrupts in exar duart mcr[3] */ *duart0_mcr = 0x08; @@ -340,17 +334,3 @@ void ide_set_reset(int on) } } #endif /* CONFIG_IDE_RESET */ - - -#if defined(CONFIG_CMD_NAND) -#include <linux/mtd/nand_legacy.h> -extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; - -void nand_init(void) -{ - nand_probe(CFG_NAND_BASE); - if (nand_dev_desc[0].ChipID != NAND_ChipID_UNKNOWN) { - print_size(nand_dev_desc[0].totlen, "\n"); - } -} -#endif diff --git a/board/esd/wuh405/Makefile b/board/esd/wuh405/Makefile index 4d75868..308f752 100644 --- a/board/esd/wuh405/Makefile +++ b/board/esd/wuh405/Makefile @@ -28,7 +28,9 @@ endif LIB = $(obj)lib$(BOARD).a -COBJS = $(BOARD).o flash.o ../common/misc.o +COBJS = $(BOARD).o flash.o \ + ../common/misc.o \ + ../common/esd405ep_nand.o \ SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/esd/wuh405/wuh405.c b/board/esd/wuh405/wuh405.c index 61d1d6c..dba3ce8 100644 --- a/board/esd/wuh405/wuh405.c +++ b/board/esd/wuh405/wuh405.c @@ -170,12 +170,6 @@ int misc_init_r (void) udelay(1000); /* wait 1ms */ /* - * Set NAND-FLASH GPIO signals to default - */ - out32(GPIO0_OR, in32(GPIO0_OR) & ~(CFG_NAND_CLE | CFG_NAND_ALE)); - out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND_CE); - - /* * Enable interrupts in exar duart mcr[3] */ *duart0_mcr = 0x08; @@ -218,35 +212,5 @@ long int initdram (int board_type) mtdcr(memcfga, mem_mb0cf); val = mfdcr(memcfgd); -#if 0 - printf("\nmb0cf=%x\n", val); /* test-only */ - printf("strap=%x\n", mfdcr(strap)); /* test-only */ -#endif - return (4*1024*1024 << ((val & 0x000e0000) >> 17)); } - -/* ------------------------------------------------------------------------- */ - -int testdram (void) -{ - /* TODO: XXX XXX XXX */ - printf ("test: 16 MB - ok\n"); - - return (0); -} - -/* ------------------------------------------------------------------------- */ - -#if defined(CONFIG_CMD_NAND) -#include <linux/mtd/nand_legacy.h> -extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; - -void nand_init(void) -{ - nand_probe(CFG_NAND_BASE); - if (nand_dev_desc[0].ChipID != NAND_ChipID_UNKNOWN) { - print_size(nand_dev_desc[0].totlen, "\n"); - } -} -#endif diff --git a/board/fads/fads.h b/board/fads/fads.h index c6f7ccd..a7fe2e9 100644 --- a/board/fads/fads.h +++ b/board/fads/fads.h @@ -71,7 +71,10 @@ #undef CONFIG_BOOTARGS #undef CONFIG_WATCHDOG /* watchdog disabled */ + +#if !defined(CONFIG_MPC885ADS) #define CONFIG_BZIP2 /* include support for bzip2 compressed images */ +#endif /* * New MPC86xADS and MPC885ADS provide two Ethernet connectivity options: diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile new file mode 100644 index 0000000..44f613e --- /dev/null +++ b/board/freescale/common/Makefile @@ -0,0 +1,56 @@ +# +# (C) Copyright 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 + +ifneq ($(OBJTREE),$(SRCTREE)) +$(shell mkdir -p $(obj)board/$(VENDOR)/common) +endif + +LIB = $(obj)lib$(VENDOR).a + +COBJS := sys_eeprom.o \ + pixis.o \ + pq-mds-pib.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/common/pixis.c b/board/freescale/common/pixis.c index 99cc2ee..ae4bef1 100644 --- a/board/freescale/common/pixis.c +++ b/board/freescale/common/pixis.c @@ -27,6 +27,8 @@ #include <watchdog.h> #include <asm/cache.h> +#ifdef CONFIG_FSL_PIXIS + #include "pixis.h" @@ -470,3 +472,4 @@ U_BOOT_CMD( " pixis_reset altbank cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>\n" " pixis_reset cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>\n" ); +#endif /* CONFIG_FSL_PIXIS */ diff --git a/board/freescale/common/pq-mds-pib.c b/board/freescale/common/pq-mds-pib.c new file mode 100644 index 0000000..d79f2eb --- /dev/null +++ b/board/freescale/common/pq-mds-pib.c @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2007 Freescale Semiconductor, Inc. + * + * Tony Li <tony.li@freescale.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + */ + +#include <common.h> +#include <i2c.h> +#include <asm/io.h> + +#ifdef CONFIG_PQ_MDS_PIB + +#include "pq-mds-pib.h" + +int pib_init(void) +{ + u8 val8; + u8 orig_i2c_bus; + + /* Switch temporarily to I2C bus #2 */ + orig_i2c_bus = i2c_get_bus_num(); + i2c_set_bus_num(1); + + val8 = 0; +#if defined(CONFIG_PCI) && !defined(CONFIG_PCISLAVE) + /* Assign PIB PMC slot to desired PCI bus */ + i2c_write(0x23, 0x6, 1, &val8, 1); + i2c_write(0x23, 0x7, 1, &val8, 1); + val8 = 0xff; + i2c_write(0x23, 0x2, 1, &val8, 1); + i2c_write(0x23, 0x3, 1, &val8, 1); + + val8 = 0; + i2c_write(0x26, 0x6, 1, &val8, 1); + val8 = 0x34; + i2c_write(0x26, 0x7, 1, &val8, 1); +#if defined(CONFIG_MPC832XEMDS) + val8 = 0xf9; /* PMC2, PMC3 slot to PCI bus */ +#else + val8 = 0xf3; /* PMC1, PMC2, PMC3 slot to PCI bus */ +#endif + i2c_write(0x26, 0x2, 1, &val8, 1); + val8 = 0xff; + i2c_write(0x26, 0x3, 1, &val8, 1); + + val8 = 0; + i2c_write(0x27, 0x6, 1, &val8, 1); + i2c_write(0x27, 0x7, 1, &val8, 1); + val8 = 0xff; + i2c_write(0x27, 0x2, 1, &val8, 1); + val8 = 0xef; + i2c_write(0x27, 0x3, 1, &val8, 1); + + eieio(); + +#if defined(CONFIG_MPC832XEMDS) + printf("PCI 32bit bus on PMC2 &PMC3\n"); +#else + printf("PCI 32bit bus on PMC1 & PMC2 &PMC3\n"); +#endif +#endif + +#if defined(CONFIG_PQ_MDS_PIB_ATM) +#if defined(CONFIG_MPC8360EMDS) + val8 = 0; + i2c_write(0x20, 0x6, 1, &val8, 1); + i2c_write(0x20, 0x7, 1, &val8, 1); + + val8 = 0xdf; + i2c_write(0x20, 0x2, 1, &val8, 1); + val8 = 0xf7; + i2c_write(0x20, 0x3, 1, &val8, 1); + + eieio(); + + printf("QOC3 ATM card on PMC0\n"); +#elif defined(CONFIG_MPC832XEMDS) + val = 0; + i2c_write(0x26, 0x7, 1, &val, 1); + val = 0xf7; + i2c_write(0x26, 0x3, 1, &val, 1); + + val = 0; + i2c_write(0x21, 0x6, 1, &val, 1); + i2c_write(0x21, 0x7, 1, &val, 1); + + val = 0xdf; + i2c_write(0x21, 0x2, 1, &val, 1); + val = 0xef; + i2c_write(0x21, 0x3, 1, &val, 1); + + eieio(); + + printf("QOC3 ATM card on PMC1\n"); +#endif +#endif + /* Reset to original I2C bus */ + i2c_set_bus_num(orig_i2c_bus); + return 0; +} +#endif /* CONFIG_PQ_MDS_PIB */ diff --git a/board/freescale/common/pq-mds-pib.h b/board/freescale/common/pq-mds-pib.h new file mode 100644 index 0000000..67066fd --- /dev/null +++ b/board/freescale/common/pq-mds-pib.h @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2007 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + */ + +extern int pib_init(void); diff --git a/board/mpc8641hpcn/sys_eeprom.c b/board/freescale/common/sys_eeprom.c index 7bc663b..7bc663b 100644 --- a/board/mpc8641hpcn/sys_eeprom.c +++ b/board/freescale/common/sys_eeprom.c diff --git a/board/freescale/m5235evb/Makefile b/board/freescale/m5235evb/Makefile new file mode 100644 index 0000000..74c2528 --- /dev/null +++ b/board/freescale/m5235evb/Makefile @@ -0,0 +1,44 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS = $(BOARD).o mii.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/freescale/m5235evb/config.mk b/board/freescale/m5235evb/config.mk new file mode 100644 index 0000000..ada38dd --- /dev/null +++ b/board/freescale/m5235evb/config.mk @@ -0,0 +1,28 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# Coldfire contribution by Bernhard Kuhn <bkuhn@metrowerks.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 +# + +/*TEXT_BASE = 0xFFC00000*/ +sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp + +PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)
\ No newline at end of file diff --git a/board/freescale/m5235evb/m5235evb.c b/board/freescale/m5235evb/m5235evb.c new file mode 100644 index 0000000..585854c --- /dev/null +++ b/board/freescale/m5235evb/m5235evb.c @@ -0,0 +1,117 @@ +/* + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <common.h> +#include <asm/immap.h> + +DECLARE_GLOBAL_DATA_PTR; + +int checkboard(void) +{ + puts("Board: "); + puts("Freescale M5235 EVB\n"); + return 0; +}; + +long int initdram(int board_type) +{ + volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); + volatile gpio_t *gpio = (volatile gpio_t *)(MMAP_GPIO); + u32 dramsize, i, dramclk; + + /* + * When booting from external Flash, the port-size is less than + * the port-size of SDRAM. In this case it is necessary to enable + * Data[15:0] on Port Address/Data. + */ + gpio->par_ad = + GPIO_PAR_AD_ADDR23 | GPIO_PAR_AD_ADDR22 | GPIO_PAR_AD_ADDR21 | + GPIO_PAR_AD_DATAL; + + /* Initialize PAR to enable SDRAM signals */ + gpio->par_sdram = + GPIO_PAR_SDRAM_SDWE | GPIO_PAR_SDRAM_SCAS | GPIO_PAR_SDRAM_SRAS | + GPIO_PAR_SDRAM_SCKE | GPIO_PAR_SDRAM_SDCS(3); + + dramsize = CFG_SDRAM_SIZE * 0x100000; + for (i = 0x13; i < 0x20; i++) { + if (dramsize == (1 << i)) + break; + } + i--; + + if (!(sdram->dacr0 & SDRAMC_DARCn_RE)) { + dramclk = gd->bus_clk / (CFG_HZ * CFG_HZ); + + /* Initialize DRAM Control Register: DCR */ + sdram->dcr = SDRAMC_DCR_RTIM_9CLKS | + SDRAMC_DCR_RTIM_6CLKS | SDRAMC_DCR_RC((15 * dramclk) >> 4); + + /* Initialize DACR0 */ + sdram->dacr0 = + SDRAMC_DARCn_BA(CFG_SDRAM_BASE) | SDRAMC_DARCn_CASL_C1 | + SDRAMC_DARCn_CBM_CMD20 | SDRAMC_DARCn_PS_32; + + /* Initialize DMR0 */ + sdram->dmr0 = ((dramsize - 1) & 0xFFFC0000) | SDRAMC_DMRn_V; + + /* Set IP (bit 3) in DACR */ + sdram->dacr0 |= SDRAMC_DARCn_IP; + + /* Wait 30ns to allow banks to precharge */ + for (i = 0; i < 5; i++) { + asm("nop"); + } + + /* Write to this block to initiate precharge */ + *(u32 *) (CFG_SDRAM_BASE) = 0xA5A59696; + + /* Set RE (bit 15) in DACR */ + sdram->dacr0 |= SDRAMC_DARCn_RE; + + /* Wait for at least 8 auto refresh cycles to occur */ + for (i = 0; i < 0x2000; i++) { + asm("nop"); + } + + /* Finish the configuration by issuing the MRS. */ + sdram->dacr0 |= SDRAMC_DARCn_IMRS; + + /* Write to the SDRAM Mode Register */ + *(u32 *) (CFG_SDRAM_BASE + 0x400) = 0xA5A59696; + } + + return dramsize; +}; + +int testdram(void) +{ + /* TODO: XXX XXX XXX */ + printf("DRAM test not implemented!\n"); + + return (0); +} diff --git a/board/freescale/m5235evb/mii.c b/board/freescale/m5235evb/mii.c new file mode 100644 index 0000000..58fabdf --- /dev/null +++ b/board/freescale/m5235evb/mii.c @@ -0,0 +1,307 @@ +/* + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/fec.h> +#include <asm/immap.h> + +#include <config.h> +#include <net.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) +#undef MII_DEBUG +#undef ET_DEBUG + +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + if (setclear) { + gpio->par_feci2c |= + (GPIO_PAR_FECI2C_EMDC_FECEMDC | GPIO_PAR_FECI2C_EMDIO_FECEMDIO); + } else { + gpio->par_feci2c &= + ~(GPIO_PAR_FECI2C_EMDC_MASK | GPIO_PAR_FECI2C_EMDIO_MASK); + } + + return 0; +} + +#if defined(CFG_DISCOVER_PHY) || defined(CONFIG_MII) +#include <miiphy.h> + +/* Make MII read/write commands for the FEC. */ +#define mk_mii_read(ADDR, REG) (0x60020000 | ((ADDR << 23) | (REG & 0x1f) << 18)) + +#define mk_mii_write(ADDR, REG, VAL) (0x50020000 | ((ADDR << 23) | (REG & 0x1f) << 18) | (VAL & 0xffff)) + +/* PHY identification */ +#define PHY_ID_LXT970 0x78100000 /* LXT970 */ +#define PHY_ID_LXT971 0x001378e0 /* LXT971 and 972 */ +#define PHY_ID_82555 0x02a80150 /* Intel 82555 */ +#define PHY_ID_QS6612 0x01814400 /* QS6612 */ +#define PHY_ID_AMD79C784 0x00225610 /* AMD 79C784 */ +#define PHY_ID_LSI80225 0x0016f870 /* LSI 80225 */ +#define PHY_ID_LSI80225B 0x0016f880 /* LSI 80225/B */ +#define PHY_ID_DP83848VV 0x20005C90 /* National 83848 */ +#define PHY_ID_DP83849 0x20005CA2 /* National 82849 */ +#define PHY_ID_KS8721BL 0x00221619 /* Micrel KS8721BL/SL */ + +#define STR_ID_LXT970 "LXT970" +#define STR_ID_LXT971 "LXT971" +#define STR_ID_82555 "Intel82555" +#define STR_ID_QS6612 "QS6612" +#define STR_ID_AMD79C784 "AMD79C784" +#define STR_ID_LSI80225 "LSI80225" +#define STR_ID_LSI80225B "LSI80225/B" +#define STR_ID_DP83848VV "N83848" +#define STR_ID_DP83849 "N83849" +#define STR_ID_KS8721BL "KS8721BL" + +/**************************************************************************** + * mii_init -- Initialize the MII for MII command without ethernet + * This function is a subset of eth_init + **************************************************************************** + */ +void mii_reset(struct fec_info_s *info) +{ + volatile fec_t *fecp = (fec_t *) (info->miibase); + int i; + + fecp->ecr = FEC_ECR_RESET; + for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i) { + udelay(1); + } + if (i == FEC_RESET_DELAY) { + printf("FEC_RESET_DELAY timeout\n"); + } +} + +/* send command to phy using mii, wait for result */ +uint mii_send(uint mii_cmd) +{ + struct fec_info_s *info; + struct eth_device *dev; + volatile fec_t *ep; + uint mii_reply; + int j = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + ep = (fec_t *) info->miibase; + + ep->mmfr = mii_cmd; /* command to phy */ + + /* wait for mii complete */ + while (!(ep->eir & FEC_EIR_MII) && (j < MCFFEC_TOUT_LOOP)) { + udelay(1); + j++; + } + if (j >= MCFFEC_TOUT_LOOP) { + printf("MII not complete\n"); + return -1; + } + + mii_reply = ep->mmfr; /* result from phy */ + ep->eir = FEC_EIR_MII; /* clear MII complete */ +#ifdef ET_DEBUG + printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n", + __FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply); +#endif + + return (mii_reply & 0xffff); /* data read from phy */ +} +#endif /* CFG_DISCOVER_PHY || (CONFIG_MII) */ + +#if defined(CFG_DISCOVER_PHY) +int mii_discover_phy(struct eth_device *dev) +{ +#define MAX_PHY_PASSES 11 + struct fec_info_s *info = dev->priv; + int phyaddr, pass; + uint phyno, phytype; + + if (info->phyname_init) + return info->phy_addr; + + phyaddr = -1; /* didn't find a PHY yet */ + for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) { + if (pass > 1) { + /* PHY may need more time to recover from reset. + * The LXT970 needs 50ms typical, no maximum is + * specified, so wait 10ms before try again. + * With 11 passes this gives it 100ms to wake up. + */ + udelay(10000); /* wait 10ms */ + } + + for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) { + + phytype = mii_send(mk_mii_read(phyno, PHY_PHYIDR1)); +#ifdef ET_DEBUG + printf("PHY type 0x%x pass %d type\n", phytype, pass); +#endif + if (phytype != 0xffff) { + phyaddr = phyno; + phytype <<= 16; + phytype |= + mii_send(mk_mii_read(phyno, PHY_PHYIDR2)); + + switch (phytype & 0xffffffff) { + case PHY_ID_KS8721BL: + strcpy(info->phy_name, + STR_ID_KS8721BL); + info->phyname_init = 1; + break; + default: + strcpy(info->phy_name, "unknown"); + info->phyname_init = 1; + break; + } + +#ifdef ET_DEBUG + printf("PHY @ 0x%x pass %d type ", phyno, pass); + switch (phytype & 0xffffffff) { + case PHY_ID_KS8721BL: + printf(STR_ID_KS8721BL); + break; + default: + printf("0x%08x\n", phytype); + break; + } +#endif + } + } + } + if (phyaddr < 0) + printf("No PHY device found.\n"); + + return phyaddr; +} +#endif /* CFG_DISCOVER_PHY */ + +int mii_init(void) __attribute__((weak,alias("__mii_init"))); + +void __mii_init(void) +{ + volatile fec_t *fecp; + struct fec_info_s *info; + struct eth_device *dev; + int miispd = 0, i = 0; + u16 autoneg = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + fecp = (fec_t *) info->miibase; + + fecpin_setclear(dev, 1); + + mii_reset(info); + + /* We use strictly polling mode only */ + fecp->eimr = 0; + + /* Clear any pending interrupt */ + fecp->eir = 0xffffffff; + + /* Set MII speed */ + miispd = (gd->bus_clk / 1000000) / 5; + fecp->mscr = miispd << 1; + + info->phy_addr = mii_discover_phy(dev); + +#define AUTONEGLINK (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS) + while (i < MCFFEC_TOUT_LOOP) { + autoneg = 0; + miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &autoneg); + i++; + + if ((autoneg & AUTONEGLINK) == AUTONEGLINK) + break; + + udelay(500); + } + if (i >= MCFFEC_TOUT_LOOP) { + printf("Auto Negotiation not complete\n"); + } + + /* adapt to the half/full speed settings */ + info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16; + info->dup_spd |= miiphy_speed(dev->name, info->phy_addr); +} + +/***************************************************************************** + * Read and write a MII PHY register, routines used by MII Utilities + * + * FIXME: These routines are expected to return 0 on success, but mii_send + * does _not_ return an error code. Maybe 0xFFFF means error, i.e. + * no PHY connected... + * For now always return 0. + * FIXME: These routines only work after calling eth_init() at least once! + * Otherwise they hang in mii_send() !!! Sorry! + *****************************************************************************/ + +int mcffec_miiphy_read(char *devname, unsigned char addr, unsigned char reg, + unsigned short *value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_read(0x%x) @ 0x%x = ", reg, addr); +#endif + rdreg = mii_send(mk_mii_read(addr, reg)); + + *value = rdreg; + +#ifdef MII_DEBUG + printf("0x%04x\n", *value); +#endif + + return 0; +} + +int mcffec_miiphy_write(char *devname, unsigned char addr, unsigned char reg, + unsigned short value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_write(0x%x) @ 0x%x = ", reg, addr); +#endif + + rdreg = mii_send(mk_mii_write(addr, reg, value)); + +#ifdef MII_DEBUG + printf("0x%04x\n", value); +#endif + + return 0; +} + +#endif /* CONFIG_CMD_NET, FEC_ENET & NET_MULTI */ diff --git a/board/freescale/m5235evb/u-boot.16 b/board/freescale/m5235evb/u-boot.16 new file mode 100644 index 0000000..8ffd326 --- /dev/null +++ b/board/freescale/m5235evb/u-boot.16 @@ -0,0 +1,145 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(m68k) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector layout of our flash chips! XXX FIXME XXX */ + + cpu/mcf523x/start.o (.text) + cpu/mcf523x/cpu_init.o (.text) + lib_m68k/traps.o (.text) + lib_m68k/interrupts.o (.text) + common/dlmalloc.o (.text) + lib_generic/zlib.o (.text) + + . = DEFINED(env_offset) ? env_offset : .; + common/environment.o (.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + + .reloc : + { + __got_start = .; + *(.got) + __got_end = .; + _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 = .; + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + . = ALIGN(4); + _ebss = .; + } + _end = . ; + PROVIDE (end = .); +} diff --git a/board/freescale/m5235evb/u-boot.32 b/board/freescale/m5235evb/u-boot.32 new file mode 100644 index 0000000..9b72f66 --- /dev/null +++ b/board/freescale/m5235evb/u-boot.32 @@ -0,0 +1,153 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(m68k) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector layout of our flash chips! XXX FIXME XXX */ + + cpu/mcf523x/start.o (.text) + cpu/mcf523x/cpu.o (.text) + cpu/mcf523x/cpu_init.o (.text) + cpu/mcf523x/interrupts.o (.text) + cpu/mcf523x/speed.o (.text) + lib_m68k/libm68k.a (.text) + common/dlmalloc.o (.text) + common/cmd_bootm.o (.text) + common/cmd_flash.o (.text) + common/cmd_elf.o (.text) + common/cmd_mem.o (.text) + common/console.o (.text) + common/main.o (.text) + lib_generic/libgeneric.a (.text) + + . = DEFINED(env_offset) ? env_offset : .; + common/environment.o (.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + + .reloc : + { + __got_start = .; + *(.got) + __got_end = .; + _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 = .; + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + . = ALIGN(4); + _ebss = .; + } + _end = . ; + PROVIDE (end = .); +} diff --git a/board/freescale/m5235evb/u-boot.lds b/board/freescale/m5235evb/u-boot.lds new file mode 100644 index 0000000..8ffd326 --- /dev/null +++ b/board/freescale/m5235evb/u-boot.lds @@ -0,0 +1,145 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(m68k) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector layout of our flash chips! XXX FIXME XXX */ + + cpu/mcf523x/start.o (.text) + cpu/mcf523x/cpu_init.o (.text) + lib_m68k/traps.o (.text) + lib_m68k/interrupts.o (.text) + common/dlmalloc.o (.text) + lib_generic/zlib.o (.text) + + . = DEFINED(env_offset) ? env_offset : .; + common/environment.o (.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + + .reloc : + { + __got_start = .; + *(.got) + __got_end = .; + _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 = .; + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + . = ALIGN(4); + _ebss = .; + } + _end = . ; + PROVIDE (end = .); +} diff --git a/board/freescale/m5249evb/Makefile b/board/freescale/m5249evb/Makefile new file mode 100644 index 0000000..424ab1c --- /dev/null +++ b/board/freescale/m5249evb/Makefile @@ -0,0 +1,44 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS = $(BOARD).o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/freescale/m5249evb/config.mk b/board/freescale/m5249evb/config.mk new file mode 100644 index 0000000..ccb2cf7 --- /dev/null +++ b/board/freescale/m5249evb/config.mk @@ -0,0 +1,25 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# Coldfire contribution by Bernhard Kuhn <bkuhn@metrowerks.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 +# + +TEXT_BASE = 0xffe00000 diff --git a/board/freescale/m5249evb/m5249evb.c b/board/freescale/m5249evb/m5249evb.c new file mode 100644 index 0000000..e8f621b --- /dev/null +++ b/board/freescale/m5249evb/m5249evb.c @@ -0,0 +1,113 @@ +/* + * (C) Copyright 2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <malloc.h> +#include <asm/immap.h> + + +/* Prototypes */ +int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + +int checkboard (void) { + ulong val; + uchar val8; + + puts ("Board: "); + puts("Freescale M5249EVB"); + val8 = ((uchar)~((uchar)mbar2_readLong(MCFSIM_GPIO1_READ) >> 4)) & 0xf; + printf(" (Switch=%1X)\n", val8); + + /* + * Set LED on + */ + val = mbar2_readLong(MCFSIM_GPIO1_OUT) & ~CFG_GPIO1_LED; + mbar2_writeLong(MCFSIM_GPIO1_OUT, val); /* Set LED on */ + + return 0; +}; + + +long int initdram (int board_type) { + unsigned long junk = 0xa5a59696; + + /* + * Note: + * RC = ([(RefreshTime/#rows) / (1/BusClk)] / 16) - 1 + */ + +#ifdef CFG_FAST_CLK + /* + * Busclk=70MHz, RefreshTime=64ms, #rows=4096 (4K) + * SO=1, NAM=0, COC=0, RTIM=01 (6clk refresh), RC=39 + */ + mbar_writeShort(MCFSIM_DCR, 0x8239); +#elif CFG_PLL_BYPASS + /* + * Busclk=5.6448MHz, RefreshTime=64ms, #rows=8192 (8K) + * SO=1, NAM=0, COC=0, RTIM=01 (6clk refresh), RC=02 + */ + mbar_writeShort(MCFSIM_DCR, 0x8202); +#else + /* + * Busclk=36MHz, RefreshTime=64ms, #rows=4096 (4K) + * SO=1, NAM=0, COC=0, RTIM=01 (6clk refresh), RC=22 (562 bus clock cycles) + */ + mbar_writeShort(MCFSIM_DCR, 0x8222); +#endif + + /* + * SDRAM starts at 0x0000_0000, CASL=10, CBM=010, PS=10 (16bit port), + * PM=1 (continuous page mode) + */ + + /* RE=0 (keep auto-refresh disabled while setting up registers) */ + mbar_writeLong(MCFSIM_DACR0, 0x00003324); + + /* BAM=007c (bits 22,21 are bank selects; 256kB blocks) */ + mbar_writeLong(MCFSIM_DMR0, 0x01fc0001); + + /** Precharge sequence **/ + mbar_writeLong(MCFSIM_DACR0, 0x0000332c); /* Set DACR0[IP] (bit 3) */ + *((volatile unsigned long *) 0x00) = junk; /* write to a memory location to init. precharge */ + udelay(0x10); /* Allow several Precharge cycles */ + + /** Refresh Sequence **/ + mbar_writeLong(MCFSIM_DACR0, 0x0000b324); /* Enable the refresh bit, DACR0[RE] (bit 15) */ + udelay(0x7d0); /* Allow gobs of refresh cycles */ + + /** Mode Register initialization **/ + mbar_writeLong(MCFSIM_DACR0, 0x0000b364); /* Enable DACR0[IMRS] (bit 6); RE remains enabled */ + *((volatile unsigned long *) 0x800) = junk; /* Access RAM to initialize the mode register */ + + return CFG_SDRAM_SIZE * 1024 * 1024; +}; + + +int testdram (void) { + /* TODO: XXX XXX XXX */ + printf ("DRAM test not implemented!\n"); + + return (0); +} diff --git a/board/freescale/m5249evb/u-boot.lds b/board/freescale/m5249evb/u-boot.lds new file mode 100644 index 0000000..a803b1c --- /dev/null +++ b/board/freescale/m5249evb/u-boot.lds @@ -0,0 +1,146 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(m68k) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector layout of our flash chips! XXX FIXME XXX */ + + cpu/mcf52x2/start.o (.text) + lib_m68k/traps.o (.text) + cpu/mcf52x2/interrupts.o (.text) + common/dlmalloc.o (.text) + lib_generic/zlib.o (.text) + + . = DEFINED(env_offset) ? env_offset : .; + common/environment.o (.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + *(.eh_frame) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + + .reloc : + { + __got_start = .; + *(.got) + __got_end = .; + _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 = .; + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + . = ALIGN(4); + _ebss = .; + } + _end = . ; + PROVIDE (end = .); +} diff --git a/board/freescale/m5253evbe/Makefile b/board/freescale/m5253evbe/Makefile new file mode 100644 index 0000000..424ab1c --- /dev/null +++ b/board/freescale/m5253evbe/Makefile @@ -0,0 +1,44 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS = $(BOARD).o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/freescale/m5253evbe/config.mk b/board/freescale/m5253evbe/config.mk new file mode 100644 index 0000000..ccb2cf7 --- /dev/null +++ b/board/freescale/m5253evbe/config.mk @@ -0,0 +1,25 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# Coldfire contribution by Bernhard Kuhn <bkuhn@metrowerks.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 +# + +TEXT_BASE = 0xffe00000 diff --git a/board/freescale/m5253evbe/m5253evbe.c b/board/freescale/m5253evbe/m5253evbe.c new file mode 100644 index 0000000..43aa84d --- /dev/null +++ b/board/freescale/m5253evbe/m5253evbe.c @@ -0,0 +1,132 @@ +/* + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Hayden Fraser (Hayden.Fraser@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/immap.h> + +int checkboard(void) +{ + puts("Board: "); + puts("Freescale MCF5253 EVBE\n"); + return 0; +}; + +long int initdram(int board_type) +{ + int i; + + /* + * Check to see if the SDRAM has already been initialized + * by a run control tool + */ + if (!(mbar_readLong(MCFSIM_DCR) & 0x8000)) { + u32 RC, dramsize; + + RC = (CFG_CLK / 1000000) >> 1; + RC = (RC * 15) >> 4; + + /* Initialize DRAM Control Register: DCR */ + mbar_writeShort(MCFSIM_DCR, (0x8400 | RC)); + + mbar_writeLong(MCFSIM_DACR0, 0x00003224); + + /* Initialize DMR0 */ + dramsize = ((CFG_SDRAM_SIZE << 20) - 1) & 0xFFFC0000; + mbar_writeLong(MCFSIM_DMR0, dramsize | 1); + + mbar_writeLong(MCFSIM_DACR0, 0x0000322c); + + /* Write to this block to initiate precharge */ + *(u32 *) (CFG_SDRAM_BASE) = 0xa5a5a5a5; + + /* Set RE bit in DACR */ + mbar_writeLong(MCFSIM_DACR0, + mbar_readLong(MCFSIM_DACR0) | 0x8000); + + /* Wait for at least 8 auto refresh cycles to occur */ + udelay(500); + + /* Finish the configuration by issuing the MRS */ + mbar_writeLong(MCFSIM_DACR0, + mbar_readLong(MCFSIM_DACR0) | 0x0040); + + *(u32 *) (CFG_SDRAM_BASE + 0x800) = 0xa5a5a5a5; + } + + return CFG_SDRAM_SIZE * 1024 * 1024; +} + +int testdram(void) +{ + /* TODO: XXX XXX XXX */ + printf("DRAM test not implemented!\n"); + + return (0); +} + +#ifdef CONFIG_CMD_IDE +#include <ata.h> +int ide_preinit(void) +{ + return (0); +} + +void ide_set_reset(int idereset) +{ + volatile atac_t *ata = (atac_t *) CFG_ATA_BASE_ADDR; + long period; + /* t1, t2, t3, t4, t5, t6, t9, tRD, tA */ + int piotms[5][9] = { {70, 165, 60, 30, 50, 5, 20, 0, 35}, /* PIO 0 */ + {50, 125, 45, 20, 35, 5, 15, 0, 35}, /* PIO 1 */ + {30, 100, 30, 15, 20, 5, 10, 0, 35}, /* PIO 2 */ + {30, 80, 30, 10, 20, 5, 10, 0, 35}, /* PIO 3 */ + {25, 70, 20, 10, 20, 5, 10, 0, 35} /* PIO 4 */ + }; + + if (idereset) { + ata->cr = 0; /* control reset */ + udelay(100); + } else { + mbar2_writeLong(CIM_MISCCR, CIM_MISCCR_CPUEND); + +#define CALC_TIMING(t) (t + period - 1) / period + period = 1000000000 / (CFG_CLK / 2); /* period in ns */ + + /*ata->ton = CALC_TIMING (180); */ + ata->t1 = CALC_TIMING(piotms[2][0]); + ata->t2w = CALC_TIMING(piotms[2][1]); + ata->t2r = CALC_TIMING(piotms[2][1]); + ata->ta = CALC_TIMING(piotms[2][8]); + ata->trd = CALC_TIMING(piotms[2][7]); + ata->t4 = CALC_TIMING(piotms[2][3]); + ata->t9 = CALC_TIMING(piotms[2][6]); + + ata->cr = 0x40; /* IORDY enable */ + udelay(2000); + ata->cr |= 0x01; /* IORDY enable */ + } +} +#endif /* CONFIG_CMD_IDE */ diff --git a/board/freescale/m5253evbe/u-boot.lds b/board/freescale/m5253evbe/u-boot.lds new file mode 100644 index 0000000..e2fd070 --- /dev/null +++ b/board/freescale/m5253evbe/u-boot.lds @@ -0,0 +1,144 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(m68k) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector layout of our flash chips! XXX FIXME XXX */ + + cpu/mcf52x2/start.o (.text) + lib_m68k/traps.o (.text) + cpu/mcf52x2/interrupts.o (.text) + common/dlmalloc.o (.text) + lib_generic/zlib.o (.text) + + . = DEFINED(env_offset) ? env_offset : .; + common/environment.o (.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + + .reloc : + { + __got_start = .; + *(.got) + __got_end = .; + _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 = .; + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + . = ALIGN(4); + _ebss = .; + } + _end = . ; + PROVIDE (end = .); +} diff --git a/board/freescale/m5329evb/Makefile b/board/freescale/m5329evb/Makefile new file mode 100644 index 0000000..ab0f11e --- /dev/null +++ b/board/freescale/m5329evb/Makefile @@ -0,0 +1,44 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS = $(BOARD).o mii.o nand.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/freescale/m5329evb/config.mk b/board/freescale/m5329evb/config.mk new file mode 100644 index 0000000..ce014ed --- /dev/null +++ b/board/freescale/m5329evb/config.mk @@ -0,0 +1,25 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# Coldfire contribution by Bernhard Kuhn <bkuhn@metrowerks.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 +# + +TEXT_BASE = 0 diff --git a/board/freescale/m5329evb/m5329evb.c b/board/freescale/m5329evb/m5329evb.c new file mode 100644 index 0000000..242eb1a --- /dev/null +++ b/board/freescale/m5329evb/m5329evb.c @@ -0,0 +1,88 @@ +/* + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <common.h> +#include <asm/immap.h> + +DECLARE_GLOBAL_DATA_PTR; + +int checkboard(void) +{ + puts("Board: "); + puts("Freescale FireEngine 5329 EVB\n"); + return 0; +}; + +long int initdram(int board_type) +{ + volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); + u32 dramsize, i; + + dramsize = CFG_SDRAM_SIZE * 0x100000; + + for (i = 0x13; i < 0x20; i++) { + if (dramsize == (1 << i)) + break; + } + i--; + + sdram->cs0 = (CFG_SDRAM_BASE | i); + sdram->cfg1 = CFG_SDRAM_CFG1; + sdram->cfg2 = CFG_SDRAM_CFG2; + + /* Issue PALL */ + sdram->ctrl = CFG_SDRAM_CTRL | 2; + + /* Issue LEMR */ + sdram->mode = CFG_SDRAM_EMOD; + sdram->mode = (CFG_SDRAM_MODE | 0x04000000); + + udelay(500); + + /* Issue PALL */ + sdram->ctrl = (CFG_SDRAM_CTRL | 2); + + /* Perform two refresh cycles */ + sdram->ctrl = CFG_SDRAM_CTRL | 4; + sdram->ctrl = CFG_SDRAM_CTRL | 4; + + sdram->mode = CFG_SDRAM_MODE; + + sdram->ctrl = (CFG_SDRAM_CTRL & ~0x80000000) | 0x10000c00; + + udelay(100); + + return dramsize; +}; + +int testdram(void) +{ + /* TODO: XXX XXX XXX */ + printf("DRAM test not implemented!\n"); + + return (0); +} diff --git a/board/freescale/m5329evb/mii.c b/board/freescale/m5329evb/mii.c new file mode 100644 index 0000000..31f1510 --- /dev/null +++ b/board/freescale/m5329evb/mii.c @@ -0,0 +1,306 @@ +/* + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/fec.h> +#include <asm/immap.h> + +#include <config.h> +#include <net.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) +#undef MII_DEBUG +#undef ET_DEBUG + +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + if (setclear) { + gpio->par_fec |= GPIO_PAR_FEC_7W_FEC | GPIO_PAR_FEC_MII_FEC; + gpio->par_feci2c |= + GPIO_PAR_FECI2C_MDC_EMDC | GPIO_PAR_FECI2C_MDIO_EMDIO; + } else { + gpio->par_fec &= ~(GPIO_PAR_FEC_7W_FEC | GPIO_PAR_FEC_MII_FEC); + gpio->par_feci2c &= + ~(GPIO_PAR_FECI2C_MDC_EMDC | GPIO_PAR_FECI2C_MDIO_EMDIO); + } + return 0; +} + +#if defined(CFG_DISCOVER_PHY) || defined(CONFIG_CMD_MII) +#include <miiphy.h> + +/* Make MII read/write commands for the FEC. */ +#define mk_mii_read(ADDR, REG) (0x60020000 | ((ADDR << 23) | (REG & 0x1f) << 18)) + +#define mk_mii_write(ADDR, REG, VAL) (0x50020000 | ((ADDR << 23) | (REG & 0x1f) << 18) | (VAL & 0xffff)) + +/* PHY identification */ +#define PHY_ID_LXT970 0x78100000 /* LXT970 */ +#define PHY_ID_LXT971 0x001378e0 /* LXT971 and 972 */ +#define PHY_ID_82555 0x02a80150 /* Intel 82555 */ +#define PHY_ID_QS6612 0x01814400 /* QS6612 */ +#define PHY_ID_AMD79C784 0x00225610 /* AMD 79C784 */ +#define PHY_ID_LSI80225 0x0016f870 /* LSI 80225 */ +#define PHY_ID_LSI80225B 0x0016f880 /* LSI 80225/B */ +#define PHY_ID_DP83848VV 0x20005C90 /* National 83848 */ +#define PHY_ID_DP83849 0x20005CA2 /* National 82849 */ + +#define STR_ID_LXT970 "LXT970" +#define STR_ID_LXT971 "LXT971" +#define STR_ID_82555 "Intel82555" +#define STR_ID_QS6612 "QS6612" +#define STR_ID_AMD79C784 "AMD79C784" +#define STR_ID_LSI80225 "LSI80225" +#define STR_ID_LSI80225B "LSI80225/B" +#define STR_ID_DP83848VV "N83848" +#define STR_ID_DP83849 "N83849" + +/**************************************************************************** + * mii_init -- Initialize the MII for MII command without ethernet + * This function is a subset of eth_init + **************************************************************************** + */ +void mii_reset(struct fec_info_s *info) +{ + volatile fec_t *fecp = (fec_t *) (info->miibase); + int i; + + fecp->ecr = FEC_ECR_RESET; + for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i) { + udelay(1); + } + if (i == FEC_RESET_DELAY) { + printf("FEC_RESET_DELAY timeout\n"); + } +} + +/* send command to phy using mii, wait for result */ +uint mii_send(uint mii_cmd) +{ + struct fec_info_s *info; + struct eth_device *dev; + volatile fec_t *ep; + uint mii_reply; + int j = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + ep = (fec_t *) info->miibase; + + ep->mmfr = mii_cmd; /* command to phy */ + + /* wait for mii complete */ + while (!(ep->eir & FEC_EIR_MII) && (j < MCFFEC_TOUT_LOOP)) { + udelay(1); + j++; + } + if (j >= MCFFEC_TOUT_LOOP) { + printf("MII not complete\n"); + return -1; + } + + mii_reply = ep->mmfr; /* result from phy */ + ep->eir = FEC_EIR_MII; /* clear MII complete */ +#ifdef ET_DEBUG + printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n", + __FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply); +#endif + + return (mii_reply & 0xffff); /* data read from phy */ +} +#endif /* CFG_DISCOVER_PHY || CONFIG_CMD_MII */ + +#if defined(CFG_DISCOVER_PHY) +int mii_discover_phy(struct eth_device *dev) +{ +#define MAX_PHY_PASSES 11 + struct fec_info_s *info = dev->priv; + int phyaddr, pass; + uint phyno, phytype; + + if (info->phyname_init) + return info->phy_addr; + + phyaddr = -1; /* didn't find a PHY yet */ + for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) { + if (pass > 1) { + /* PHY may need more time to recover from reset. + * The LXT970 needs 50ms typical, no maximum is + * specified, so wait 10ms before try again. + * With 11 passes this gives it 100ms to wake up. + */ + udelay(10000); /* wait 10ms */ + } + + for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) { + + phytype = mii_send(mk_mii_read(phyno, PHY_PHYIDR1)); +#ifdef ET_DEBUG + printf("PHY type 0x%x pass %d type\n", phytype, pass); +#endif + if (phytype != 0xffff) { + phyaddr = phyno; + phytype <<= 16; + phytype |= + mii_send(mk_mii_read(phyno, PHY_PHYIDR2)); + + switch (phytype & 0xffffffff) { + case PHY_ID_DP83848VV: + strcpy(info->phy_name, + STR_ID_DP83848VV); + info->phyname_init = 1; + break; + default: + strcpy(info->phy_name, "unknown"); + info->phyname_init = 1; + break; + } + +#ifdef ET_DEBUG + printf("PHY @ 0x%x pass %d type ", phyno, pass); + switch (phytype & 0xffffffff) { + case PHY_ID_DP83848VV: + printf(STR_ID_DP83848VV); + break; + default: + printf("0x%08x\n", phytype); + break; + } +#endif + } + } + } + if (phyaddr < 0) + printf("No PHY device found.\n"); + + return phyaddr; +} +#endif /* CFG_DISCOVER_PHY */ + +int mii_init(void) __attribute__((weak,alias("__mii_init"))); + +void __mii_init(void) +{ + volatile fec_t *fecp; + struct fec_info_s *info; + struct eth_device *dev; + int miispd = 0, i = 0; + u16 autoneg = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + fecp = (fec_t *) info->miibase; + + fecpin_setclear(dev, 1); + + mii_reset(info); + + /* We use strictly polling mode only */ + fecp->eimr = 0; + + /* Clear any pending interrupt */ + fecp->eir = 0xffffffff; + + /* Set MII speed */ + miispd = (gd->bus_clk / 1000000) / 5; + fecp->mscr = miispd << 1; + + info->phy_addr = mii_discover_phy(dev); + +#define AUTONEGLINK (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS) + while (i < MCFFEC_TOUT_LOOP) { + autoneg = 0; + miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &autoneg); + i++; + + if ((autoneg & AUTONEGLINK) == AUTONEGLINK) + break; + + udelay(500); + } + if (i >= MCFFEC_TOUT_LOOP) { + printf("Auto Negotiation not complete\n"); + } + + /* adapt to the half/full speed settings */ + info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16; + info->dup_spd |= miiphy_speed(dev->name, info->phy_addr); +} + +/***************************************************************************** + * Read and write a MII PHY register, routines used by MII Utilities + * + * FIXME: These routines are expected to return 0 on success, but mii_send + * does _not_ return an error code. Maybe 0xFFFF means error, i.e. + * no PHY connected... + * For now always return 0. + * FIXME: These routines only work after calling eth_init() at least once! + * Otherwise they hang in mii_send() !!! Sorry! + *****************************************************************************/ + +int mcffec_miiphy_read(char *devname, unsigned char addr, unsigned char reg, + unsigned short *value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_read(0x%x) @ 0x%x = ", reg, addr); +#endif + rdreg = mii_send(mk_mii_read(addr, reg)); + + *value = rdreg; + +#ifdef MII_DEBUG + printf("0x%04x\n", *value); +#endif + + return 0; +} + +int mcffec_miiphy_write(char *devname, unsigned char addr, unsigned char reg, + unsigned short value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_write(0x%x) @ 0x%x = ", reg, addr); +#endif + + rdreg = mii_send(mk_mii_write(addr, reg, value)); + +#ifdef MII_DEBUG + printf("0x%04x\n", value); +#endif + + return 0; +} + +#endif /* CONFIG_CMD_NET, FEC_ENET & NET_MULTI */ diff --git a/board/freescale/m5329evb/nand.c b/board/freescale/m5329evb/nand.c new file mode 100644 index 0000000..fefb42e --- /dev/null +++ b/board/freescale/m5329evb/nand.c @@ -0,0 +1,114 @@ +/* + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <common.h> +#include <asm/io.h> +#include <asm/immap.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_CMD_NAND) +#include <nand.h> +#include <linux/mtd/mtd.h> + +#define SET_CLE 0x10 +#define CLR_CLE ~SET_CLE +#define SET_ALE 0x08 +#define CLR_ALE ~SET_ALE + +static void nand_hwcontrol(struct mtd_info *mtdinfo, int cmd) +{ + struct nand_chip *this = mtdinfo->priv; + volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + u32 nand_baseaddr = (u32) this->IO_ADDR_W; + + switch (cmd) { + case NAND_CTL_SETNCE: + case NAND_CTL_CLRNCE: + break; + case NAND_CTL_SETCLE: + nand_baseaddr |= SET_CLE; + break; + case NAND_CTL_CLRCLE: + nand_baseaddr &= CLR_CLE; + break; + case NAND_CTL_SETALE: + nand_baseaddr |= SET_ALE; + break; + case NAND_CTL_CLRALE: + nand_baseaddr |= CLR_ALE; + break; + case NAND_CTL_SETWP: + fbcs->csmr2 |= CSMR_WP; + break; + case NAND_CTL_CLRWP: + fbcs->csmr2 &= ~CSMR_WP; + break; + } + this->IO_ADDR_W = (void __iomem *)(nand_baseaddr); +} + +static void nand_write_byte(struct mtd_info *mtdinfo, u_char byte) +{ + struct nand_chip *this = mtdinfo->priv; + *((volatile u8 *)(this->IO_ADDR_W)) = byte; +} + +static u8 nand_read_byte(struct mtd_info *mtdinfo) +{ + struct nand_chip *this = mtdinfo->priv; + return (u8) (*((volatile u8 *)this->IO_ADDR_R)); +} + +static int nand_dev_ready(struct mtd_info *mtdinfo) +{ + return 1; +} + +int board_nand_init(struct nand_chip *nand) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + *((volatile u16 *)CFG_LATCH_ADDR) |= 0x0004; + + /* set up pin configuration */ + gpio->par_timer &= ~GPIO_PAR_TIN3_TIN3; + gpio->pddr_timer |= 0x08; + gpio->ppd_timer |= 0x08; + gpio->pclrr_timer = 0; + gpio->podr_timer = 0; + + nand->chip_delay = 50; + nand->eccmode = NAND_ECC_SOFT; + nand->hwcontrol = nand_hwcontrol; + nand->read_byte = nand_read_byte; + nand->write_byte = nand_write_byte; + nand->dev_ready = nand_dev_ready; + + return 0; +} +#endif diff --git a/board/freescale/m5329evb/u-boot.lds b/board/freescale/m5329evb/u-boot.lds new file mode 100644 index 0000000..9b994a0 --- /dev/null +++ b/board/freescale/m5329evb/u-boot.lds @@ -0,0 +1,144 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(m68k) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector layout of our flash chips! XXX FIXME XXX */ + + cpu/mcf532x/start.o (.text) + lib_m68k/traps.o (.text) + lib_m68k/interrupts.o (.text) + common/dlmalloc.o (.text) + lib_generic/zlib.o (.text) + + . = DEFINED(env_offset) ? env_offset : .; + common/environment.o (.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + + .reloc : + { + __got_start = .; + *(.got) + __got_end = .; + _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 = .; + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + . = ALIGN(4); + _ebss = .; + } + _end = . ; + PROVIDE (end = .); +} diff --git a/board/freescale/m54455evb/Makefile b/board/freescale/m54455evb/Makefile new file mode 100644 index 0000000..ca9a772 --- /dev/null +++ b/board/freescale/m54455evb/Makefile @@ -0,0 +1,44 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS = $(BOARD).o flash.o mii.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
\ No newline at end of file diff --git a/board/freescale/m54455evb/config.mk b/board/freescale/m54455evb/config.mk new file mode 100644 index 0000000..ce014ed --- /dev/null +++ b/board/freescale/m54455evb/config.mk @@ -0,0 +1,25 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# Coldfire contribution by Bernhard Kuhn <bkuhn@metrowerks.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 +# + +TEXT_BASE = 0 diff --git a/board/freescale/m54455evb/flash.c b/board/freescale/m54455evb/flash.c new file mode 100644 index 0000000..de2cca8 --- /dev/null +++ b/board/freescale/m54455evb/flash.c @@ -0,0 +1,974 @@ +/* + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> + +#include <asm/immap.h> + +#ifndef CFG_FLASH_CFI +typedef unsigned char FLASH_PORT_WIDTH; +typedef volatile unsigned char FLASH_PORT_WIDTHV; + +#define FPW FLASH_PORT_WIDTH +#define FPWV FLASH_PORT_WIDTHV + +#define CFG_FLASH_CFI_WIDTH FLASH_CFI_8BIT +#define CFG_FLASH_NONCFI_WIDTH FLASH_CFI_8BIT + +/* Intel-compatible flash commands */ +#define INTEL_PROGRAM 0x00100010 +#define INTEL_ERASE 0x00200020 +#define INTEL_WRSETUP 0x00400040 +#define INTEL_CLEAR 0x00500050 +#define INTEL_LOCKBIT 0x00600060 +#define INTEL_PROTECT 0x00010001 +#define INTEL_STATUS 0x00700070 +#define INTEL_READID 0x00900090 +#define INTEL_CFIQRY 0x00980098 +#define INTEL_SUSERASE 0x00B000B0 +#define INTEL_PROTPROG 0x00C000C0 +#define INTEL_CONFIRM 0x00D000D0 +#define INTEL_WRBLK 0x00e800e8 +#define INTEL_RESET 0x00FF00FF + +/* Intel-compatible flash status bits */ +#define INTEL_FINISHED 0x00800080 +#define INTEL_OK 0x00800080 +#define INTEL_ERASESUS 0x00600060 +#define INTEL_WSM_SUS (INTEL_FINISHED | INTEL_ERASESUS) + +/* 28F160C3B CFI Data offset - This could vary */ +#define INTEL_CFI_MFG 0x00 /* Manufacturer ID */ +#define INTEL_CFI_PART 0x01 /* Product ID */ +#define INTEL_CFI_LOCK 0x02 /* */ +#define INTEL_CFI_TWPRG 0x1F /* Typical Single Word Program Timeout 2^n us */ +#define INTEL_CFI_MBUFW 0x20 /* Typical Max Buffer Write Timeout 2^n us */ +#define INTEL_CFI_TERB 0x21 /* Typical Block Erase Timeout 2^n ms */ +#define INTEL_CFI_MWPRG 0x23 /* Maximum Word program timeout 2^n us */ +#define INTEL_CFI_MERB 0x25 /* Maximum Block Erase Timeout 2^n s */ +#define INTEL_CFI_SIZE 0x27 /* Device size 2^n bytes */ +#define INTEL_CFI_CAP 0x28 +#define INTEL_CFI_WRBUF 0x2A +#define INTEL_CFI_BANK 0x2C /* Number of Bank */ +#define INTEL_CFI_BLK1A 0x2D /* Number of Blocks */ +#define INTEL_CFI_BLK1B 0x2E /* Number of Blocks */ +#define INTEL_CFI_SZ1A 0x2F /* Block Region Size */ +#define INTEL_CFI_SZ1B 0x30 +#define INTEL_CFI_BLK2A 0x31 +#define INTEL_CFI_BLK2B 0x32 +#define INTEL_CFI_SZ2A 0x33 +#define INTEL_CFI_SZ2B 0x34 + +#define FLASH_CYCLE1 0x0555 +#define FLASH_CYCLE2 0x0aaa + +#define WR_BLOCK 0x20 + +/* not in the flash.h yet */ +#define FLASH_28F64P30T 0x00B9 /* Intel 28F64P30T ( 64M) */ +#define FLASH_28F64P30B 0x00BA /* Intel 28F64P30B ( 64M) */ +#define FLASH_28F128P30T 0x00BB /* Intel 28F128P30T ( 128M = 8M x 16 ) */ +#define FLASH_28F128P30B 0x00BC /* Intel 28F128P30B ( 128M = 8M x 16 ) */ +#define FLASH_28F256P30T 0x00BD /* Intel 28F256P30T ( 256M = 16M x 16 ) */ +#define FLASH_28F256P30B 0x00BE /* Intel 28F256P30B ( 256M = 16M x 16 ) */ + +#define SYNC __asm__("nop") + +/*----------------------------------------------------------------------- + * Functions + */ + +ulong flash_get_size(FPWV * addr, flash_info_t * info); +int flash_get_offsets(ulong base, flash_info_t * info); +int flash_cmd_rd(volatile u16 * addr, int index); +int write_data(flash_info_t * info, ulong dest, FPW data); +int write_data_block(flash_info_t * info, ulong src, ulong dest); +int write_word_atm(flash_info_t * info, volatile u8 * dest, u16 data); +void inline spin_wheel(void); +void flash_sync_real_protect(flash_info_t * info); +uchar intel_sector_protected(flash_info_t * info, ushort sector); + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + +ulong flash_init(void) +{ + int i; + ulong size = 0; + ulong fbase = 0; + + for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { + memset(&flash_info[i], 0, sizeof(flash_info_t)); + + switch (i) { + case 0: + fbase = (ulong) CFG_FLASH0_BASE; + break; + case 1: + fbase = (ulong) CFG_FLASH1_BASE; + break; + } + + flash_get_size((FPWV *) fbase, &flash_info[i]); + flash_get_offsets((ulong) fbase, &flash_info[i]); + fbase += flash_info[i].size; + size += flash_info[i].size; + + /* get the h/w and s/w protection status in sync */ + flash_sync_real_protect(&flash_info[i]); + } + + /* Protect monitor and environment sectors */ + flash_protect(FLAG_PROTECT_SET, + CFG_MONITOR_BASE, + CFG_MONITOR_BASE + monitor_flash_len - 1, &flash_info[0]); + + return size; +} + +int flash_get_offsets(ulong base, flash_info_t * info) +{ + int i, j, k; + int sectors, bs, banks; + ulong start; + + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_ATM) { + int sect[] = CFG_ATMEL_SECT; + int sectsz[] = CFG_ATMEL_SECTSZ; + + info->start[0] = base; + for (k = 0, i = 0; i < CFG_ATMEL_REGION; i++) { + for (j = 0; j < sect[i]; j++, k++) { + info->start[k + 1] = info->start[k] + sectsz[i]; + info->protect[k] = 0; + } + } + } + + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { + volatile u16 *addr16 = (volatile u16 *)base; + + *addr16 = (FPW) INTEL_RESET; /* restore read mode */ + *addr16 = (FPW) INTEL_READID; + + banks = addr16[INTEL_CFI_BANK] & 0xff; + + sectors = 0; + info->start[0] = base; + + for (k = 0, i = 0; i < banks; i++) { + /* Geometry y1 = y1 + 1, y2 = y2 + 1, CFI spec. + * To be exact, Z = [0x2f 0x30] (LE) * 256 bytes * [0x2D 0x2E] block count + * Z = [0x33 0x34] (LE) * 256 bytes * [0x31 0x32] block count + */ + bs = ((((addr16[INTEL_CFI_SZ1B + (i * 4)] & 0xff) << 8) + | (addr16[INTEL_CFI_SZ1A + (i * 4)] & 0xff)) * + 0x100); + sectors = + (addr16[INTEL_CFI_BLK1A + (i * 4)] & 0xff) + 1; + + for (j = 0; j < sectors; j++, k++) { + info->start[k + 1] = info->start[k] + bs; + } + } + + *addr16 = (FPW) INTEL_RESET; /* restore read mode */ + } + + return ERR_OK; +} + +void flash_print_info(flash_info_t * info) +{ + int i; + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_INTEL: + printf("INTEL "); + break; + case FLASH_MAN_ATM: + printf("ATMEL "); + break; + default: + printf("Unknown Vendor "); + break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_AT040: + printf("AT49BV040A\n"); + break; + case FLASH_28F128J3A: + printf("Intel 28F128J3A\n"); + break; + default: + printf("Unknown Chip Type\n"); + return; + } + + if (info->size > 0x100000) { + int remainder; + + printf(" Size: %ld", info->size >> 20); + + remainder = (info->size % 0x100000); + if (remainder) { + remainder >>= 10; + remainder = (int)((float) + (((float)remainder / (float)1024) * + 10000)); + printf(".%d ", remainder); + } + + printf("MB in %d Sectors\n", info->sector_count); + } else + printf(" Size: %ld KB in %d Sectors\n", + info->size >> 10, 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! + */ +ulong flash_get_size(FPWV * addr, flash_info_t * info) +{ + volatile u16 *addr16 = (volatile u16 *)addr; + int intel = 0, banks = 0; + u16 value; + int i; + + addr[FLASH_CYCLE1] = (FPWV) 0x00AA00AA; /* for Atmel, Intel ignores this */ + addr[FLASH_CYCLE2] = (FPWV) 0x00550055; /* for Atmel, Intel ignores this */ + addr[FLASH_CYCLE1] = (FPWV) 0x00900090; /* selects Intel or Atmel */ + + switch (addr[0] & 0xff) { + case (u8) ATM_MANUFACT: + info->flash_id = FLASH_MAN_ATM; + value = addr[1]; + break; + case (u8) INTEL_MANUFACT: + /* Terminate Atmel ID read */ + addr[0] = (FPWV) 0x00F000F0; + /* Write auto select command: read Manufacturer ID */ + /* Write auto select command sequence and test FLASH answer */ + *addr16 = (FPW) INTEL_RESET; /* restore read mode */ + *addr16 = (FPW) INTEL_READID; + + info->flash_id = FLASH_MAN_INTEL; + value = (addr16[INTEL_CFI_MFG] << 8); + value |= addr16[INTEL_CFI_PART] & 0xff; + intel = 1; + break; + default: + printf("Unknown Flash\n"); + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + + *addr = (FPW) 0x00F000F0; + *addr = (FPW) INTEL_RESET; /* restore read mode */ + return (0); /* no or unknown flash */ + } + + switch (value) { + case (u8) ATM_ID_LV040: + info->flash_id += FLASH_AT040; + break; + case (u16) INTEL_ID_28F128J3: + info->flash_id += FLASH_28F128J3A; + break; + case (u16) INTEL_ID_28F64P30T: + info->flash_id += FLASH_28F64P30T; + break; + case (u16) INTEL_ID_28F64P30B: + info->flash_id += FLASH_28F64P30B; + break; + case (u16) INTEL_ID_28F128P30T: + info->flash_id += FLASH_28F128P30T; + break; + case (u16) INTEL_ID_28F128P30B: + info->flash_id += FLASH_28F128P30B; + break; + case (u16) INTEL_ID_28F256P30T: + info->flash_id += FLASH_28F256P30T; + break; + case (u16) INTEL_ID_28F256P30B: + info->flash_id += FLASH_28F256P30B; + break; + default: + info->flash_id = FLASH_UNKNOWN; + break; + } + + if (intel) { + /* Intel spec. under CFI section */ + u32 sz; + int sectors, bs; + + banks = addr16[INTEL_CFI_BANK] & 0xff; + + sectors = sz = 0; + for (i = 0; i < banks; i++) { + /* Geometry y1 = y1 + 1, y2 = y2 + 1, CFI spec. + * To be exact, Z = [0x2f 0x30] (LE) * 256 bytes * [0x2D 0x2E] block count + * Z = [0x33 0x34] (LE) * 256 bytes * [0x31 0x32] block count + */ + bs = ((((addr16[INTEL_CFI_SZ1B + (i * 4)] & 0xff) << 8) + | (addr16[INTEL_CFI_SZ1A + (i * 4)] & 0xff)) * + 0x100); + sectors += + (addr16[INTEL_CFI_BLK1A + (i * 4)] & 0xff) + 1; + sz += (bs * sectors); + } + + info->sector_count = sectors; + info->size = sz; + *addr = (FPW) INTEL_RESET; /* restore read mode */ + } else { + int sect[] = CFG_ATMEL_SECT; + int sectsz[] = CFG_ATMEL_SECTSZ; + + info->sector_count = 0; + info->size = 0; + for (i = 0; i < CFG_ATMEL_REGION; i++) { + info->sector_count += sect[i]; + info->size += sect[i] * sectsz[i]; + } + + /* reset ID mode */ + addr[0] = (FPWV) 0x00F000F0; + } + + if (info->sector_count > CFG_MAX_FLASH_SECT) { + printf("** ERROR: sector count %d > max (%d) **\n", + info->sector_count, CFG_MAX_FLASH_SECT); + info->sector_count = CFG_MAX_FLASH_SECT; + } + + return (info->size); +} + +int flash_cmd_rd(volatile u16 * addr, int index) +{ + return (int)addr[index]; +} + +/* + * This function gets the u-boot flash sector protection status + * (flash_info_t.protect[]) in sync with the sector protection + * status stored in hardware. + */ +void flash_sync_real_protect(flash_info_t * info) +{ + int i; + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_28F160C3B: + case FLASH_28F160C3T: + case FLASH_28F320C3B: + case FLASH_28F320C3T: + case FLASH_28F640C3B: + case FLASH_28F640C3T: + for (i = 0; i < info->sector_count; ++i) { + info->protect[i] = intel_sector_protected(info, i); + } + break; + default: + /* no h/w protect support */ + break; + } +} + +/* + * checks if "sector" in bank "info" is protected. Should work on intel + * strata flash chips 28FxxxJ3x in 8-bit mode. + * Returns 1 if sector is protected (or timed-out while trying to read + * protection status), 0 if it is not. + */ +uchar intel_sector_protected(flash_info_t * info, ushort sector) +{ + FPWV *addr; + FPWV *lock_conf_addr; + ulong start; + unsigned char ret; + + /* + * first, wait for the WSM to be finished. The rationale for + * waiting for the WSM to become idle for at most + * CFG_FLASH_ERASE_TOUT is as follows. The WSM can be busy + * because of: (1) erase, (2) program or (3) lock bit + * configuration. So we just wait for the longest timeout of + * the (1)-(3), i.e. the erase timeout. + */ + + /* wait at least 35ns (W12) before issuing Read Status Register */ + /*udelay(1); */ + addr = (FPWV *) info->start[sector]; + *addr = (FPW) INTEL_STATUS; + + start = get_timer(0); + while ((*addr & (FPW) INTEL_FINISHED) != (FPW) INTEL_FINISHED) { + if (get_timer(start) > CFG_FLASH_UNLOCK_TOUT) { + *addr = (FPW) INTEL_RESET; /* restore read mode */ + printf("WSM busy too long, can't get prot status\n"); + return 1; + } + } + + /* issue the Read Identifier Codes command */ + *addr = (FPW) INTEL_READID; + + /* Intel example code uses offset of 4 for 8-bit flash */ + lock_conf_addr = (FPWV *) info->start[sector]; + ret = (lock_conf_addr[INTEL_CFI_LOCK] & (FPW) INTEL_PROTECT) ? 1 : 0; + + /* put flash back in read mode */ + *addr = (FPW) INTEL_RESET; + + return ret; +} + +int flash_erase(flash_info_t * info, int s_first, int s_last) +{ + int flag, prot, sect; + ulong type, start, last; + int rcode = 0, intel = 0; + + 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; + } + + type = (info->flash_id & FLASH_VENDMASK); + + if (type != (FLASH_MAN_INTEL & FLASH_VENDMASK)) { + if (type != (FLASH_MAN_ATM & FLASH_VENDMASK)) { + type = (info->flash_id & FLASH_VENDMASK); + printf + ("Can't erase unknown flash type %08lx - aborted\n", + info->flash_id); + return 1; + } + } + + if (type == FLASH_MAN_INTEL) + intel = 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 = get_timer(0); + last = start; + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + + FPWV *addr = (FPWV *) (info->start[sect]); + int min = 0; + + printf("."); + + /* arm simple, non interrupt dependent timer */ + start = get_timer(0); + + if (intel) { + *addr = (FPW) INTEL_READID; + min = addr[INTEL_CFI_TERB] & 0xff; + min = 1 << min; /* ms */ + min = (min / info->sector_count) * 1000; + + /* start erase block */ + *addr = (FPW) INTEL_CLEAR; /* clear status register */ + *addr = (FPW) INTEL_ERASE; /* erase setup */ + *addr = (FPW) INTEL_CONFIRM; /* erase confirm */ + + while ((*addr & (FPW) INTEL_FINISHED) != + (FPW) INTEL_FINISHED) { + + if (get_timer(start) > + CFG_FLASH_ERASE_TOUT) { + printf("Timeout\n"); + *addr = (FPW) INTEL_SUSERASE; /* suspend erase */ + *addr = (FPW) INTEL_RESET; /* reset to read mode */ + + rcode = 1; + break; + } + } + + *addr = (FPW) INTEL_RESET; /* resest to read mode */ + } else { + FPWV *base; /* first address in bank */ + FPWV *atmeladdr; + + flag = disable_interrupts(); + + atmeladdr = (FPWV *) addr; /* concatenate to 8 bit */ + base = (FPWV *) (CFG_ATMEL_BASE); /* First sector */ + + base[FLASH_CYCLE1] = (u8) 0x00AA00AA; /* unlock */ + base[FLASH_CYCLE2] = (u8) 0x00550055; /* unlock */ + base[FLASH_CYCLE1] = (u8) 0x00800080; /* erase mode */ + base[FLASH_CYCLE1] = (u8) 0x00AA00AA; /* unlock */ + base[FLASH_CYCLE2] = (u8) 0x00550055; /* unlock */ + *atmeladdr = (u8) 0x00300030; /* erase sector */ + + if (flag) + enable_interrupts(); + + while ((*atmeladdr & (u8) 0x00800080) != + (u8) 0x00800080) { + if (get_timer(start) > + CFG_FLASH_ERASE_TOUT) { + printf("Timeout\n"); + *atmeladdr = (u8) 0x00F000F0; /* reset to read mode */ + + rcode = 1; + break; + } + } + + *atmeladdr = (u8) 0x00F000F0; /* reset to read mode */ + } /* Atmel or Intel */ + } + } + printf(" done\n"); + + return rcode; +} + +int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt) +{ + if (info->flash_id == FLASH_UNKNOWN) + return 4; + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_ATM: + { + u16 data = 0; + int bytes; /* number of bytes to program in current word */ + int left; /* number of bytes left to program */ + int i, res; + + for (left = cnt, res = 0; + left > 0 && res == 0; + addr += sizeof(data), left -= + sizeof(data) - bytes) { + + bytes = addr & (sizeof(data) - 1); + addr &= ~(sizeof(data) - 1); + + /* combine source and destination data so can program + * an entire word of 16 or 32 bits + */ + for (i = 0; i < sizeof(data); i++) { + data <<= 8; + if (i < bytes || i - bytes >= left) + data += *((uchar *) addr + i); + else + data += *src++; + } + + data = (data >> 8) | (data << 8); + res = write_word_atm(info, (FPWV *) addr, data); + } + return res; + } /* case FLASH_MAN_ATM */ + + case FLASH_MAN_INTEL: + { + ulong cp, wp; + u16 data; + int count, i, l, rc, port_width; + + /* get lower word aligned address */ + wp = addr; + port_width = sizeof(FPW); + + /* + * 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 < port_width && cnt > 0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + + for (; cnt == 0 && i < port_width; ++i, ++cp) + data = (data << 8) | (*(uchar *) cp); + + if ((rc = write_data(info, wp, data)) != 0) + return (rc); + + wp += port_width; + } + + if (cnt > WR_BLOCK) { + /* + * handle word aligned part + */ + count = 0; + while (cnt >= WR_BLOCK) { + + if ((rc = + write_data_block(info, + (ulong) src, + wp)) != 0) + return (rc); + + wp += WR_BLOCK; + src += WR_BLOCK; + cnt -= WR_BLOCK; + + if (count++ > 0x800) { + spin_wheel(); + count = 0; + } + } + } + + /* handle word aligned part */ + if (cnt < WR_BLOCK) { + /* + * handle word aligned part + */ + count = 0; + while (cnt >= port_width) { + data = 0; + for (i = 0; i < port_width; ++i) + data = (data << 8) | *src++; + + if ((rc = + write_data(info, + (ulong) ((FPWV *) wp), + (FPW) (data))) != 0) + return (rc); + + wp += port_width; + cnt -= port_width; + if (count++ > 0x800) { + spin_wheel(); + count = 0; + } + } + } + + if (cnt == 0) + return ERR_OK; + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i = 0, cp = wp; i < port_width && cnt > 0; + ++i, ++cp) { + data = (data << 8) | (*src++); + --cnt; + } + for (; i < port_width; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + + return write_data(info, (ulong) ((FPWV *) wp), + (FPW) data); + + } /* case FLASH_MAN_INTEL */ + + } /* switch */ + + return ERR_OK; +} + +/*----------------------------------------------------------------------- + * Write a word or halfword to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +int write_data_block(flash_info_t * info, ulong src, ulong dest) +{ + FPWV *srcaddr = (FPWV *) src; + FPWV *dstaddr = (FPWV *) dest; + ulong start; + int flag, i; + + /* Check if Flash is (sufficiently) erased */ + for (i = 0; i < WR_BLOCK; i++) + if ((*dstaddr++ & 0xff) != 0xff) { + printf("not erased at %08lx (%lx)\n", + (ulong) dstaddr, *dstaddr); + return (2); + } + + dstaddr = (FPWV *) dest; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + *dstaddr = (FPW) INTEL_WRBLK; /* write block setup */ + + if (flag) + enable_interrupts(); + + /* arm simple, non interrupt dependent timer */ + start = get_timer(0); + + /* wait while polling the status register */ + while ((*dstaddr & (FPW) INTEL_FINISHED) != (FPW) INTEL_OK) { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + *dstaddr = (FPW) INTEL_RESET; /* restore read mode */ + return (1); + } + } + + *dstaddr = (FPW) WR_BLOCK - 1; /* write 32 to buffer */ + for (i = 0; i < WR_BLOCK; i++) + *dstaddr++ = *srcaddr++; + + dstaddr -= 1; + *dstaddr = (FPW) INTEL_CONFIRM; /* write 32 to buffer */ + + /* arm simple, non interrupt dependent timer */ + start = get_timer(0); + + /* wait while polling the status register */ + while ((*dstaddr & (FPW) INTEL_FINISHED) != (FPW) INTEL_OK) { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + *dstaddr = (FPW) INTEL_RESET; /* restore read mode */ + return (1); + } + } + + *dstaddr = (FPW) INTEL_RESET; /* restore read mode */ + + return (0); +} + +/*----------------------------------------------------------------------- + * Write a word or halfword to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +int write_data(flash_info_t * info, ulong dest, FPW data) +{ + FPWV *addr = (FPWV *) dest; + ulong start; + int flag; + + /* Check if Flash is (sufficiently) erased */ + if ((*addr & data) != data) { + printf("not erased at %08lx (%lx)\n", (ulong) addr, + (ulong) * addr); + return (2); + } + + /* Disable interrupts which might cause a timeout here */ + flag = (int)disable_interrupts(); + + *addr = (FPW) INTEL_CLEAR; + *addr = (FPW) INTEL_RESET; + + *addr = (FPW) INTEL_WRSETUP; /* write setup */ + *addr = data; + + if (flag) + enable_interrupts(); + + /* arm simple, non interrupt dependent timer */ + start = get_timer(0); + + /* wait while polling the status register */ + while ((*addr & (FPW) INTEL_OK) != (FPW) INTEL_OK) { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + *addr = (FPW) INTEL_SUSERASE; /* suspend mode */ + *addr = (FPW) INTEL_CLEAR; /* clear status */ + *addr = (FPW) INTEL_RESET; /* reset */ + return (1); + } + } + + *addr = (FPW) INTEL_CLEAR; /* clear status */ + *addr = (FPW) INTEL_RESET; /* restore read mode */ + + return (0); +} + +/*----------------------------------------------------------------------- + * Write a word to Flash for ATMEL FLASH + * A word is 16 bits, whichever the bus width of the flash bank + * (not an individual chip) is. + * + * returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +int write_word_atm(flash_info_t * info, volatile u8 * dest, u16 data) +{ + ulong start; + int flag, i; + int res = 0; /* result, assume success */ + FPWV *base; /* first address in flash bank */ + + /* Check if Flash is (sufficiently) erased */ + if ((*((volatile u16 *)dest) & data) != data) { + return (2); + } + + base = (FPWV *) (CFG_ATMEL_BASE); + + for (i = 0; i < sizeof(u16); i++) { + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + base[FLASH_CYCLE1] = (u8) 0x00AA00AA; /* unlock */ + base[FLASH_CYCLE2] = (u8) 0x00550055; /* unlock */ + base[FLASH_CYCLE1] = (u8) 0x00A000A0; /* selects program mode */ + + *dest = data; /* start programming the data */ + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + start = get_timer(0); + + /* data polling for D7 */ + while (res == 0 + && (*dest & (u8) 0x00800080) != + (data & (u8) 0x00800080)) { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + *dest = (u8) 0x00F000F0; /* reset bank */ + res = 1; + } + } + + *dest++ = (u8) 0x00F000F0; /* reset bank */ + data >>= 8; + } + + return (res); +} + +void inline spin_wheel(void) +{ + static int p = 0; + static char w[] = "\\/-"; + + printf("\010%c", w[p]); + (++p == 3) ? (p = 0) : 0; +} + +#ifdef CFG_FLASH_PROTECTION +/*----------------------------------------------------------------------- + */ +int flash_real_protect(flash_info_t * info, long sector, int prot) +{ + int rcode = 0; /* assume success */ + FPWV *addr; /* address of sector */ + FPW value; + + addr = (FPWV *) (info->start[sector]); + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_28F160C3B: + case FLASH_28F160C3T: + case FLASH_28F320C3B: + case FLASH_28F320C3T: + case FLASH_28F640C3B: + case FLASH_28F640C3T: + *addr = (FPW) INTEL_RESET; /* make sure in read mode */ + *addr = (FPW) INTEL_LOCKBIT; /* lock command setup */ + + if (prot) + *addr = (FPW) INTEL_PROTECT; /* lock sector */ + else + *addr = (FPW) INTEL_CONFIRM; /* unlock sector */ + + /* now see if it really is locked/unlocked as requested */ + *addr = (FPW) INTEL_READID; + + /* read sector protection at sector address, (A7 .. A0) = 0x02. + * D0 = 1 for each device if protected. + * If at least one device is protected the sector is marked + * protected, but return failure. Mixed protected and + * unprotected devices within a sector should never happen. + */ + value = addr[2] & (FPW) INTEL_PROTECT; + if (value == 0) + info->protect[sector] = 0; + else if (value == (FPW) INTEL_PROTECT) + info->protect[sector] = 1; + else { + /* error, mixed protected and unprotected */ + rcode = 1; + info->protect[sector] = 1; + } + if (info->protect[sector] != prot) + rcode = 1; /* failed to protect/unprotect as requested */ + + /* reload all protection bits from hardware for now */ + flash_sync_real_protect(info); + break; + + default: + /* no hardware protect that we support */ + info->protect[sector] = prot; + break; + } + + return rcode; +} +#endif +#endif diff --git a/board/freescale/m54455evb/m54455evb.c b/board/freescale/m54455evb/m54455evb.c new file mode 100644 index 0000000..6a02782 --- /dev/null +++ b/board/freescale/m54455evb/m54455evb.c @@ -0,0 +1,164 @@ +/* + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <pci.h> +#include <asm/immap.h> + +DECLARE_GLOBAL_DATA_PTR; + +int checkboard(void) +{ + puts("Board: "); + puts("Freescale M54455 EVB\n"); + return 0; +}; + +long int initdram(int board_type) +{ + volatile sdramc_t *sdram = (volatile sdramc_t *)(MMAP_SDRAM); + volatile gpio_t *gpio = (volatile gpio_t *)(MMAP_GPIO); + u32 dramsize, i; + + dramsize = CFG_SDRAM_SIZE * 0x100000 >> 1; + + for (i = 0x13; i < 0x20; i++) { + if (dramsize == (1 << i)) + break; + } + i--; + + gpio->mscr_sdram = 0xAA; + + sdram->sdcs0 = (CFG_SDRAM_BASE | i); + sdram->sdcs1 = (CFG_SDRAM_BASE1 | i); + + sdram->sdcfg1 = CFG_SDRAM_CFG1; + sdram->sdcfg2 = CFG_SDRAM_CFG2; + + /* Issue PALL */ + sdram->sdcr = CFG_SDRAM_CTRL | 2; + + /* Issue LEMR */ + sdram->sdmr = CFG_SDRAM_EMOD | 0x408; + sdram->sdmr = CFG_SDRAM_MODE | 0x300; + + udelay(500); + + /* Issue PALL */ + sdram->sdcr = CFG_SDRAM_CTRL | 2; + + /* Perform two refresh cycles */ + sdram->sdcr = CFG_SDRAM_CTRL | 4; + sdram->sdcr = CFG_SDRAM_CTRL | 4; + + sdram->sdmr = CFG_SDRAM_MODE | 0x200; + + sdram->sdcr = (CFG_SDRAM_CTRL & ~0x80000000) | 0x10000c00; + + udelay(100); + + return (dramsize << 1); +}; + +int testdram(void) +{ + /* TODO: XXX XXX XXX */ + printf("DRAM test not implemented!\n"); + + return (0); +} + +#if defined(CONFIG_CMD_IDE) +#include <ata.h> + +int ide_preinit(void) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + gpio->par_fec |= (gpio->par_fec & GPIO_PAR_FEC_FEC1_MASK) | 0x10; + gpio->par_feci2c |= + (gpio->par_feci2c & 0xF0FF) | (GPIO_PAR_FECI2C_MDC1_ATA_DIOR | + GPIO_PAR_FECI2C_MDIO1_ATA_DIOW); + gpio->par_ata |= + (GPIO_PAR_ATA_BUFEN | GPIO_PAR_ATA_CS1 | GPIO_PAR_ATA_CS0 | + GPIO_PAR_ATA_DA2 | GPIO_PAR_ATA_DA1 | GPIO_PAR_ATA_DA0 + | GPIO_PAR_ATA_RESET_RESET | GPIO_PAR_ATA_DMARQ_DMARQ | + GPIO_PAR_ATA_IORDY_IORDY); + gpio->par_pci |= + (GPIO_PAR_PCI_GNT3_ATA_DMACK | GPIO_PAR_PCI_REQ3_ATA_INTRQ); + + return (0); +} + +void ide_set_reset(int idereset) +{ + volatile atac_t *ata = (atac_t *) MMAP_ATA; + long period; + /* t1, t2, t3, t4, t5, t6, t9, tRD, tA */ + int piotms[5][9] = { + {70, 165, 60, 30, 50, 5, 20, 0, 35}, /* PIO 0 */ + {50, 125, 45, 20, 35, 5, 15, 0, 35}, /* PIO 1 */ + {30, 100, 30, 15, 20, 5, 10, 0, 35}, /* PIO 2 */ + {30, 80, 30, 10, 20, 5, 10, 0, 35}, /* PIO 3 */ + {25, 70, 20, 10, 20, 5, 10, 0, 35} + }; /* PIO 4 */ + + if (idereset) { + ata->cr = 0; /* control reset */ + udelay(10000); + } else { +#define CALC_TIMING(t) (t + period - 1) / period + period = 1000000000 / gd->bus_clk; /* period in ns */ + + /*ata->ton = CALC_TIMING (180); */ + ata->t1 = CALC_TIMING(piotms[2][0]); + ata->t2w = CALC_TIMING(piotms[2][1]); + ata->t2r = CALC_TIMING(piotms[2][1]); + ata->ta = CALC_TIMING(piotms[2][8]); + ata->trd = CALC_TIMING(piotms[2][7]); + ata->t4 = CALC_TIMING(piotms[2][3]); + ata->t9 = CALC_TIMING(piotms[2][6]); + + ata->cr = 0x40; /* IORDY enable */ + udelay(200000); + ata->cr |= 0x01; /* IORDY enable */ + } +} +#endif + +#if defined(CONFIG_PCI) +/* + * Initialize PCI devices, report devices found. + */ +static struct pci_controller hose; +extern void pci_mcf5445x_init(struct pci_controller *hose); + +void pci_init_board(void) +{ + pci_mcf5445x_init(&hose); +} +#endif /* CONFIG_PCI */ diff --git a/board/freescale/m54455evb/mii.c b/board/freescale/m54455evb/mii.c new file mode 100644 index 0000000..c067183 --- /dev/null +++ b/board/freescale/m54455evb/mii.c @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/fec.h> +#include <asm/immap.h> + +#include <config.h> +#include <net.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) +#undef MII_DEBUG +#undef ET_DEBUG + +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + struct fec_info_s *info = (struct fec_info_s *)dev->priv; + + if (setclear) { + gpio->par_feci2c |= + (GPIO_PAR_FECI2C_MDC0_MDC0 | GPIO_PAR_FECI2C_MDIO0_MDIO0); + + if (info->iobase == CFG_FEC0_IOBASE) + gpio->par_fec |= GPIO_PAR_FEC_FEC0_RMII_GPIO; + else + gpio->par_fec |= GPIO_PAR_FEC_FEC1_RMII_ATA; + } else { + gpio->par_feci2c &= + ~(GPIO_PAR_FECI2C_MDC0_MDC0 | GPIO_PAR_FECI2C_MDIO0_MDIO0); + + if (info->iobase == CFG_FEC0_IOBASE) + gpio->par_fec &= GPIO_PAR_FEC_FEC0_MASK; + else + gpio->par_fec &= GPIO_PAR_FEC_FEC1_MASK; + } + return 0; +} + +#if defined(CFG_DISCOVER_PHY) || defined(CONFIG_CMD_MII) +#include <miiphy.h> + +/* Make MII read/write commands for the FEC. */ +#define mk_mii_read(ADDR, REG) (0x60020000 | ((ADDR << 23) | (REG & 0x1f) << 18)) + +#define mk_mii_write(ADDR, REG, VAL) (0x50020000 | ((ADDR << 23) | (REG & 0x1f) << 18) | (VAL & 0xffff)) + +/* PHY identification */ +#define PHY_ID_LXT970 0x78100000 /* LXT970 */ +#define PHY_ID_LXT971 0x001378e0 /* LXT971 and 972 */ +#define PHY_ID_82555 0x02a80150 /* Intel 82555 */ +#define PHY_ID_QS6612 0x01814400 /* QS6612 */ +#define PHY_ID_AMD79C784 0x00225610 /* AMD 79C784 */ +#define PHY_ID_LSI80225 0x0016f870 /* LSI 80225 */ +#define PHY_ID_LSI80225B 0x0016f880 /* LSI 80225/B */ +#define PHY_ID_DP83848VV 0x20005C90 /* National 83848 */ +#define PHY_ID_DP83849 0x20005CA2 /* National 82849 */ + +#define STR_ID_LXT970 "LXT970" +#define STR_ID_LXT971 "LXT971" +#define STR_ID_82555 "Intel82555" +#define STR_ID_QS6612 "QS6612" +#define STR_ID_AMD79C784 "AMD79C784" +#define STR_ID_LSI80225 "LSI80225" +#define STR_ID_LSI80225B "LSI80225/B" +#define STR_ID_DP83848VV "N83848" +#define STR_ID_DP83849 "N83849" + +/**************************************************************************** + * mii_init -- Initialize the MII for MII command without ethernet + * This function is a subset of eth_init + **************************************************************************** + */ +void mii_reset(struct fec_info_s *info) +{ + volatile fec_t *fecp = (fec_t *) (info->miibase); + struct eth_device *dev; + int i, miispd; + u16 rst = 0; + + dev = eth_get_dev(); + + miispd = (gd->bus_clk / 1000000) / 5; + fecp->mscr = miispd << 1; + + miiphy_write(dev->name, info->phy_addr, PHY_BMCR, PHY_BMCR_RESET); + for (i = 0; i < FEC_RESET_DELAY; ++i) { + udelay(500); + miiphy_read(dev->name, info->phy_addr, PHY_BMCR, &rst); + if ((rst & PHY_BMCR_RESET) == 0) + break; + } + if (i == FEC_RESET_DELAY) + printf("Mii reset timeout %d\n", i); +} + +/* send command to phy using mii, wait for result */ +uint mii_send(uint mii_cmd) +{ + struct fec_info_s *info; + struct eth_device *dev; + volatile fec_t *ep; + uint mii_reply; + int j = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + ep = (fec_t *) info->miibase; + + ep->mmfr = mii_cmd; /* command to phy */ + + /* wait for mii complete */ + while (!(ep->eir & FEC_EIR_MII) && (j < MCFFEC_TOUT_LOOP)) { + udelay(1); + j++; + } + if (j >= MCFFEC_TOUT_LOOP) { + printf("MII not complete\n"); + return -1; + } + + mii_reply = ep->mmfr; /* result from phy */ + ep->eir = FEC_EIR_MII; /* clear MII complete */ +#ifdef ET_DEBUG + printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n", + __FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply); +#endif + + return (mii_reply & 0xffff); /* data read from phy */ +} +#endif /* CFG_DISCOVER_PHY || (CONFIG_MII) */ + +#if defined(CFG_DISCOVER_PHY) +int mii_discover_phy(struct eth_device *dev) +{ +#define MAX_PHY_PASSES 11 + struct fec_info_s *info = dev->priv; + int phyaddr, pass; + uint phyno, phytype; + + if (info->phyname_init) + return info->phy_addr; + + phyaddr = -1; /* didn't find a PHY yet */ + for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) { + if (pass > 1) { + /* PHY may need more time to recover from reset. + * The LXT970 needs 50ms typical, no maximum is + * specified, so wait 10ms before try again. + * With 11 passes this gives it 100ms to wake up. + */ + udelay(10000); /* wait 10ms */ + } + + for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) { + + phytype = mii_send(mk_mii_read(phyno, PHY_PHYIDR1)); +#ifdef ET_DEBUG + printf("PHY type 0x%x pass %d type\n", phytype, pass); +#endif + if (phytype != 0xffff) { + phyaddr = phyno; + phytype <<= 16; + phytype |= + mii_send(mk_mii_read(phyno, PHY_PHYIDR2)); + + switch (phytype & 0xffffffff) { + case PHY_ID_DP83848VV: + strcpy(info->phy_name, + STR_ID_DP83848VV); + info->phyname_init = 1; + break; + default: + strcpy(info->phy_name, "unknown"); + info->phyname_init = 1; + break; + } + +#ifdef ET_DEBUG + printf("PHY @ 0x%x pass %d type ", phyno, pass); + switch (phytype & 0xffffffff) { + case PHY_ID_DP83848VV: + printf(STR_ID_DP83848VV); + break; + default: + printf("0x%08x\n", phytype); + break; + } +#endif + } + } + } + if (phyaddr < 0) + printf("No PHY device found.\n"); + + return phyaddr; +} +#endif /* CFG_DISCOVER_PHY */ + +int mii_init(void) __attribute__((weak,alias("__mii_init"))); + +void __mii_init(void) +{ + volatile fec_t *fecp; + struct fec_info_s *info; + struct eth_device *dev; + int miispd = 0, i = 0; + u16 autoneg = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + fecp = (fec_t *) info->miibase; + + /* We use strictly polling mode only */ + fecp->eimr = 0; + + /* Clear any pending interrupt */ + fecp->eir = 0xffffffff; + + /* Set MII speed */ + miispd = (gd->bus_clk / 1000000) / 5; + fecp->mscr = miispd << 1; + + info->phy_addr = mii_discover_phy(dev); + +#define AUTONEGLINK (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS) + while (i < MCFFEC_TOUT_LOOP) { + autoneg = 0; + miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &autoneg); + i++; + + if ((autoneg & AUTONEGLINK) == AUTONEGLINK) + break; + + udelay(500); + } + if (i >= MCFFEC_TOUT_LOOP) { + printf("Auto Negotiation not complete\n"); + } + + /* adapt to the half/full speed settings */ + info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16; + info->dup_spd |= miiphy_speed(dev->name, info->phy_addr); +} + +/***************************************************************************** + * Read and write a MII PHY register, routines used by MII Utilities + * + * FIXME: These routines are expected to return 0 on success, but mii_send + * does _not_ return an error code. Maybe 0xFFFF means error, i.e. + * no PHY connected... + * For now always return 0. + * FIXME: These routines only work after calling eth_init() at least once! + * Otherwise they hang in mii_send() !!! Sorry! + *****************************************************************************/ + +int mcffec_miiphy_read(char *devname, unsigned char addr, unsigned char reg, + unsigned short *value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_read(0x%x) @ 0x%x = ", reg, addr); +#endif + rdreg = mii_send(mk_mii_read(addr, reg)); + + *value = rdreg; + +#ifdef MII_DEBUG + printf("0x%04x\n", *value); +#endif + + return 0; +} + +int mcffec_miiphy_write(char *devname, unsigned char addr, unsigned char reg, + unsigned short value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_write(0x%x) @ 0x%x = ", reg, addr); +#endif + + rdreg = mii_send(mk_mii_write(addr, reg, value)); + +#ifdef MII_DEBUG + printf("0x%04x\n", value); +#endif + + return 0; +} + +#endif /* CONFIG_CMD_NET, FEC_ENET & NET_MULTI */ diff --git a/board/freescale/m54455evb/u-boot.lds b/board/freescale/m54455evb/u-boot.lds new file mode 100644 index 0000000..bda68e4 --- /dev/null +++ b/board/freescale/m54455evb/u-boot.lds @@ -0,0 +1,144 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(m68k) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector layout of our flash chips! XXX FIXME XXX */ + + cpu/mcf5445x/start.o (.text) + lib_m68k/traps.o (.text) + lib_m68k/interrupts.o (.text) + common/dlmalloc.o (.text) + lib_generic/zlib.o (.text) + + . = DEFINED(env_offset) ? env_offset : .; + common/environment.o (.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + + .reloc : + { + __got_start = .; + *(.got) + __got_end = .; + _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 = .; + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + . = ALIGN(4); + _ebss = .; + } + _end = . ; + PROVIDE (end = .); +} diff --git a/board/mpc8313erdb/Makefile b/board/freescale/mpc8313erdb/Makefile index a987e510..a987e510 100644 --- a/board/mpc8313erdb/Makefile +++ b/board/freescale/mpc8313erdb/Makefile diff --git a/board/mpc8313erdb/config.mk b/board/freescale/mpc8313erdb/config.mk index f768264..f768264 100644 --- a/board/mpc8313erdb/config.mk +++ b/board/freescale/mpc8313erdb/config.mk diff --git a/board/mpc8313erdb/mpc8313erdb.c b/board/freescale/mpc8313erdb/mpc8313erdb.c index 999fe9e..861c143 100644 --- a/board/mpc8313erdb/mpc8313erdb.c +++ b/board/freescale/mpc8313erdb/mpc8313erdb.c @@ -23,7 +23,11 @@ */ #include <common.h> +#if defined(CONFIG_OF_FLAT_TREE) #include <ft_build.h> +#elif defined(CONFIG_OF_LIBFDT) +#include <libfdt.h> +#endif #include <pci.h> #include <mpc83xx.h> @@ -96,21 +100,22 @@ void pci_init_board(void) mpc83xx_pci_init(1, reg, warmboot); } -#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) +#if defined(CONFIG_OF_BOARD_SETUP) void ft_board_setup(void *blob, bd_t *bd) { +#if defined(CONFIG_OF_FLAT_TREE) u32 *p; int len; -#ifdef CONFIG_PCI - ft_pci_setup(blob, bd); -#endif - ft_cpu_setup(blob, bd); - p = ft_get_prop(blob, "/memory/reg", &len); - if (p) { + if (p != NULL) { *p++ = cpu_to_be32(bd->bi_memstart); *p = cpu_to_be32(bd->bi_memsize); } +#endif + ft_cpu_setup(blob, bd); +#ifdef CONFIG_PCI + ft_pci_setup(blob, bd); +#endif } #endif diff --git a/board/mpc8313erdb/sdram.c b/board/freescale/mpc8313erdb/sdram.c index 4b67788..e6e8410 100644 --- a/board/mpc8313erdb/sdram.c +++ b/board/freescale/mpc8313erdb/sdram.c @@ -112,8 +112,6 @@ long int initdram(int board_type) if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im) return -1; - puts("Initializing\n"); - /* DDR SDRAM - Main SODIMM */ msize = fixed_sdram(); @@ -127,7 +125,6 @@ long int initdram(int board_type) resume_from_sleep(); #endif - puts(" DDR RAM: "); /* return total bus SDRAM size(bytes) -- DDR */ return msize; } diff --git a/board/freescale/mpc8323erdb/mpc8323erdb.c b/board/freescale/mpc8323erdb/mpc8323erdb.c index 1886f19..e738613 100644 --- a/board/freescale/mpc8323erdb/mpc8323erdb.c +++ b/board/freescale/mpc8323erdb/mpc8323erdb.c @@ -17,7 +17,6 @@ #include <miiphy.h> #include <command.h> #include <libfdt.h> -#include <libfdt_env.h> #if defined(CONFIG_PCI) #include <pci.h> #endif @@ -92,8 +91,6 @@ long int initdram(int board_type) msize = fixed_sdram(); - puts("\n DDR RAM: "); - /* return total bus SDRAM size(bytes) -- DDR */ return (msize * 1024 * 1024); } @@ -185,33 +182,21 @@ void pci_init_board(void) } #if defined(CONFIG_OF_BOARD_SETUP) - -/* - * Prototypes of functions that we use. - */ -void ft_cpu_setup(void *blob, bd_t *bd); - -#ifdef CONFIG_PCI -void ft_pci_setup(void *blob, bd_t *bd); -#endif - -void -ft_board_setup(void *blob, bd_t *bd) +void ft_board_setup(void *blob, bd_t *bd) { - int nodeoffset; - int tmp[2]; - - nodeoffset = fdt_find_node_by_path(blob, "/memory"); - if (nodeoffset >= 0) { - tmp[0] = cpu_to_be32(bd->bi_memstart); - tmp[1] = cpu_to_be32(bd->bi_memsize); - fdt_setprop(blob, nodeoffset, "reg", tmp, sizeof(tmp)); +#if defined(CONFIG_OF_FLAT_TREE) + u32 *p; + int len; + + p = ft_get_prop(blob, "/memory/reg", &len); + if (p != NULL) { + *p++ = cpu_to_be32(bd->bi_memstart); + *p = cpu_to_be32(bd->bi_memsize); } - +#endif ft_cpu_setup(blob, bd); - #ifdef CONFIG_PCI ft_pci_setup(blob, bd); #endif } -#endif /* CONFIG_OF_BOARD_SETUP */ +#endif diff --git a/board/mpc832xemds/Makefile b/board/freescale/mpc832xemds/Makefile index 5ec7a87..5ec7a87 100644 --- a/board/mpc832xemds/Makefile +++ b/board/freescale/mpc832xemds/Makefile diff --git a/board/mpc832xemds/config.mk b/board/freescale/mpc832xemds/config.mk index 6c3eca7..6c3eca7 100644 --- a/board/mpc832xemds/config.mk +++ b/board/freescale/mpc832xemds/config.mk diff --git a/board/mpc832xemds/mpc832xemds.c b/board/freescale/mpc832xemds/mpc832xemds.c index 772da67..6ba25d4 100644 --- a/board/mpc832xemds/mpc832xemds.c +++ b/board/freescale/mpc832xemds/mpc832xemds.c @@ -29,6 +29,11 @@ #endif #if defined(CONFIG_OF_FLAT_TREE) #include <ft_build.h> +#elif defined(CONFIG_OF_LIBFDT) +#include <libfdt.h> +#endif +#if defined(CONFIG_PQ_MDS_PIB) +#include "../common/pq-mds-pib.h" #endif const qe_iop_conf_t qe_iop_conf_tab[] = { @@ -86,6 +91,14 @@ int board_early_init_f(void) return 0; } +int board_early_init_r(void) +{ +#ifdef CONFIG_PQ_MDS_PIB + pib_init(); +#endif + return 0; +} + int fixed_sdram(void); long int initdram(int board_type) @@ -101,8 +114,6 @@ long int initdram(int board_type) msize = fixed_sdram(); - puts("\n DDR RAM: "); - /* return total bus SDRAM size(bytes) -- DDR */ return (msize * 1024 * 1024); } @@ -155,22 +166,22 @@ int checkboard(void) return 0; } -#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) -void -ft_board_setup(void *blob, bd_t *bd) +#if defined(CONFIG_OF_BOARD_SETUP) +void ft_board_setup(void *blob, bd_t *bd) { +#if defined(CONFIG_OF_FLAT_TREE) u32 *p; int len; -#ifdef CONFIG_PCI - ft_pci_setup(blob, bd); -#endif - ft_cpu_setup(blob, bd); - p = ft_get_prop(blob, "/memory/reg", &len); if (p != NULL) { *p++ = cpu_to_be32(bd->bi_memstart); *p = cpu_to_be32(bd->bi_memsize); } +#endif + ft_cpu_setup(blob, bd); +#ifdef CONFIG_PCI + ft_pci_setup(blob, bd); +#endif } #endif diff --git a/board/mpc832xemds/pci.c b/board/freescale/mpc832xemds/pci.c index d0a407a..6bc35c7 100644 --- a/board/mpc832xemds/pci.c +++ b/board/freescale/mpc832xemds/pci.c @@ -20,6 +20,8 @@ #include <i2c.h> #if defined(CONFIG_OF_FLAT_TREE) #include <ft_build.h> +#elif defined(CONFIG_OF_LIBFDT) +#include <libfdt.h> #endif #include <asm/fsl_i2c.h> @@ -129,7 +131,6 @@ void pci_init_board(void) volatile pcictrl83xx_t *pci_ctrl; volatile pciconf83xx_t *pci_conf; - u8 val8, orig_i2c_bus; u16 reg16; u32 val32; u32 dev; @@ -198,43 +199,6 @@ void pci_init_board(void) PIWAR_IWS_2G; /* - * Assign PIB PMC slot to desired PCI bus - */ - - /* Switch temporarily to I2C bus #2 */ - orig_i2c_bus = i2c_get_bus_num(); - i2c_set_bus_num(1); - - val8 = 0; - i2c_write(0x23, 0x6, 1, &val8, 1); - i2c_write(0x23, 0x7, 1, &val8, 1); - val8 = 0xff; - i2c_write(0x23, 0x2, 1, &val8, 1); - i2c_write(0x23, 0x3, 1, &val8, 1); - - val8 = 0; - i2c_write(0x26, 0x6, 1, &val8, 1); - val8 = 0x34; - i2c_write(0x26, 0x7, 1, &val8, 1); - - val8 = 0xf9; /* PMC2, PMC3 slot to PCI bus */ - i2c_write(0x26, 0x2, 1, &val8, 1); - val8 = 0xff; - i2c_write(0x26, 0x3, 1, &val8, 1); - - val8 = 0; - i2c_write(0x27, 0x6, 1, &val8, 1); - i2c_write(0x27, 0x7, 1, &val8, 1); - val8 = 0xff; - i2c_write(0x27, 0x2, 1, &val8, 1); - val8 = 0xef; - i2c_write(0x27, 0x3, 1, &val8, 1); - asm("eieio"); - - /* Reset to original I2C bus */ - i2c_set_bus_num(orig_i2c_bus); - - /* * Release PCI RST Output signal */ udelay(2000); @@ -290,8 +254,6 @@ void pci_init_board(void) pci_hose_write_config_byte(&hose[0], dev, PCI_LATENCY_TIMER, 0x80); pci_hose_write_config_byte(&hose[0], dev, PCI_CACHE_LINE_SIZE, 0x08); - printf("PCI 32bit bus on PMC2 & PMC3\n"); - /* * Hose scan. */ @@ -299,7 +261,27 @@ void pci_init_board(void) } #endif /* CONFIG_PCISLAVE */ -#ifdef CONFIG_OF_FLAT_TREE +#if defined(CONFIG_OF_LIBFDT) +void +ft_pci_setup(void *blob, bd_t *bd) +{ + int nodeoffset; + int err; + int tmp[2]; + + nodeoffset = fdt_find_node_by_path(blob, "/" OF_SOC "/pci@8500"); + if (nodeoffset >= 0) { + tmp[0] = cpu_to_be32(hose[0].first_busno); + tmp[1] = cpu_to_be32(hose[0].last_busno); + err = fdt_setprop(blob, nodeoffset, "bus-range", + tmp, sizeof(tmp)); + + tmp[0] = cpu_to_be32(gd->pci_clk); + err = fdt_setprop(blob, nodeoffset, "clock-frequency", + tmp, sizeof(tmp[0])); + } +} +#elif defined(CONFIG_OF_FLAT_TREE) void ft_pci_setup(void *blob, bd_t *bd) { diff --git a/board/mpc8349emds/Makefile b/board/freescale/mpc8349emds/Makefile index 5ec7a87..5ec7a87 100644 --- a/board/mpc8349emds/Makefile +++ b/board/freescale/mpc8349emds/Makefile diff --git a/board/mpc8349emds/config.mk b/board/freescale/mpc8349emds/config.mk index edf64d1..edf64d1 100644 --- a/board/mpc8349emds/config.mk +++ b/board/freescale/mpc8349emds/config.mk diff --git a/board/mpc8349emds/mpc8349emds.c b/board/freescale/mpc8349emds/mpc8349emds.c index 521d1bb..39c0916 100644 --- a/board/mpc8349emds/mpc8349emds.c +++ b/board/freescale/mpc8349emds/mpc8349emds.c @@ -34,6 +34,8 @@ #endif #if defined(CONFIG_OF_FLAT_TREE) #include <ft_build.h> +#elif defined(CONFIG_OF_LIBFDT) +#include <libfdt.h> #endif int fixed_sdram(void); @@ -68,8 +70,6 @@ long int initdram (int board_type) if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im) return -1; - puts("Initializing\n"); - /* DDR SDRAM - Main SODIMM */ im->sysconf.ddrlaw[0].bar = CFG_DDR_BASE & LAWBAR_BAR; #if defined(CONFIG_SPD_EEPROM) @@ -88,7 +88,7 @@ long int initdram (int board_type) */ ddr_enable_ecc(msize * 1024 * 1024); #endif - puts(" DDR RAM: "); + /* return total bus SDRAM size(bytes) -- DDR */ return (msize * 1024 * 1024); } @@ -189,9 +189,6 @@ void sdram_init(void) volatile lbus83xx_t *lbc= &immap->lbus; uint *sdram_addr = (uint *)CFG_LBC_SDRAM_BASE; - puts("\n SDRAM on Local Bus: "); - print_size (CFG_LBC_SDRAM_SIZE * 1024 * 1024, "\n"); - /* * Setup SDRAM Base and Option Registers, already done in cpu_init.c */ @@ -253,26 +250,25 @@ void sdram_init(void) #else void sdram_init(void) { - puts(" SDRAM on Local Bus is NOT available!\n"); } #endif -#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) -void -ft_board_setup(void *blob, bd_t *bd) +#if defined(CONFIG_OF_BOARD_SETUP) +void ft_board_setup(void *blob, bd_t *bd) { +#if defined(CONFIG_OF_FLAT_TREE) u32 *p; int len; -#ifdef CONFIG_PCI - ft_pci_setup(blob, bd); -#endif - ft_cpu_setup(blob, bd); - p = ft_get_prop(blob, "/memory/reg", &len); if (p != NULL) { *p++ = cpu_to_be32(bd->bi_memstart); *p = cpu_to_be32(bd->bi_memsize); } +#endif + ft_cpu_setup(blob, bd); +#ifdef CONFIG_PCI + ft_pci_setup(blob, bd); +#endif } #endif diff --git a/board/mpc8349emds/pci.c b/board/freescale/mpc8349emds/pci.c index d6a12b8..ae94a2f 100644 --- a/board/mpc8349emds/pci.c +++ b/board/freescale/mpc8349emds/pci.c @@ -25,6 +25,12 @@ #include <pci.h> #include <asm/mpc8349_pci.h> #include <i2c.h> +#if defined(CONFIG_OF_FLAT_TREE) +#include <ft_build.h> +#elif defined(CONFIG_OF_LIBFDT) +#include <libfdt.h> +#endif + DECLARE_GLOBAL_DATA_PTR; @@ -382,7 +388,40 @@ pci_init_board(void) } -#ifdef CONFIG_OF_FLAT_TREE +#if defined(CONFIG_OF_LIBFDT) +void +ft_pci_setup(void *blob, bd_t *bd) +{ + int nodeoffset; + int err; + int tmp[2]; + + nodeoffset = fdt_find_node_by_path(blob, "/" OF_SOC "/pci@8500"); + if (nodeoffset >= 0) { + tmp[0] = cpu_to_be32(pci_hose[0].first_busno); + tmp[1] = cpu_to_be32(pci_hose[0].last_busno); + err = fdt_setprop(blob, nodeoffset, "bus-range", + tmp, sizeof(tmp)); + + tmp[0] = cpu_to_be32(gd->pci_clk); + err = fdt_setprop(blob, nodeoffset, "clock-frequency", + tmp, sizeof(tmp[0])); + } +#ifdef CONFIG_MPC83XX_PCI2 + nodeoffset = fdt_find_node_by_path(blob, "/" OF_SOC "/pci@8600"); + if (nodeoffset >= 0) { + tmp[0] = cpu_to_be32(pci_hose[1].first_busno); + tmp[1] = cpu_to_be32(pci_hose[1].last_busno); + err = fdt_setprop(blob, nodeoffset, "bus-range", + tmp, sizeof(tmp)); + + tmp[0] = cpu_to_be32(gd->pci_clk); + err = fdt_setprop(blob, nodeoffset, "clock-frequency", + tmp, sizeof(tmp[0])); + } +#endif +} +#elif defined(CONFIG_OF_FLAT_TREE) void ft_pci_setup(void *blob, bd_t *bd) { diff --git a/board/mpc8349itx/Makefile b/board/freescale/mpc8349itx/Makefile index 31bcdb8..31bcdb8 100644 --- a/board/mpc8349itx/Makefile +++ b/board/freescale/mpc8349itx/Makefile diff --git a/board/mpc8349itx/config.mk b/board/freescale/mpc8349itx/config.mk index 79f1765..79f1765 100644 --- a/board/mpc8349itx/config.mk +++ b/board/freescale/mpc8349itx/config.mk diff --git a/board/mpc8349itx/mpc8349itx.c b/board/freescale/mpc8349itx/mpc8349itx.c index 178b1d3..c82f784 100644 --- a/board/mpc8349itx/mpc8349itx.c +++ b/board/freescale/mpc8349itx/mpc8349itx.c @@ -39,6 +39,8 @@ #endif #if defined(CONFIG_OF_FLAT_TREE) #include <ft_build.h> +#elif defined(CONFIG_OF_LIBFDT) +#include <libfdt.h> #endif #ifndef CONFIG_SPD_EEPROM @@ -74,7 +76,7 @@ int fixed_sdram(void) im->ddr.timing_cfg_1 = CFG_DDR_TIMING_1; im->ddr.timing_cfg_2 = CFG_DDR_TIMING_2;/* Was "2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT" */ - im->ddr.sdram_cfg = SDRAM_CFG_SREN | SDRAM_CFG_SDRAM_TYPE_DDR; + im->ddr.sdram_cfg = SDRAM_CFG_SREN | SDRAM_CFG_SDRAM_TYPE_DDR1; im->ddr.sdram_mode = (0x0000 << SDRAM_MODE_ESD_SHIFT) | (0x0032 << SDRAM_MODE_SD_SHIFT); im->ddr.sdram_interval = @@ -160,7 +162,6 @@ long int initdram(int board_type) ddr_enable_ecc(msize * 1048576); #endif - puts(" DDR RAM: "); /* return total bus RAM size(bytes) */ return msize * 1024 * 1024; } @@ -385,22 +386,22 @@ int misc_init_r(void) return rc; } -#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) -void -ft_board_setup(void *blob, bd_t *bd) +#if defined(CONFIG_OF_BOARD_SETUP) +void ft_board_setup(void *blob, bd_t *bd) { +#if defined(CONFIG_OF_FLAT_TREE) u32 *p; int len; -#ifdef CONFIG_PCI - ft_pci_setup(blob, bd); -#endif - ft_cpu_setup(blob, bd); - p = ft_get_prop(blob, "/memory/reg", &len); if (p != NULL) { *p++ = cpu_to_be32(bd->bi_memstart); *p = cpu_to_be32(bd->bi_memsize); } +#endif + ft_cpu_setup(blob, bd); +#ifdef CONFIG_PCI + ft_pci_setup(blob, bd); +#endif } #endif diff --git a/board/mpc8349itx/pci.c b/board/freescale/mpc8349itx/pci.c index e81ad27..5ca094d 100644 --- a/board/mpc8349itx/pci.c +++ b/board/freescale/mpc8349itx/pci.c @@ -31,6 +31,8 @@ #include <i2c.h> #if defined(CONFIG_OF_FLAT_TREE) #include <ft_build.h> +#elif defined(CONFIG_OF_LIBFDT) +#include <libfdt.h> #endif DECLARE_GLOBAL_DATA_PTR; @@ -332,8 +334,40 @@ void pci_init_board(void) #endif } -#endif /* CONFIG_PCI */ -#ifdef CONFIG_OF_FLAT_TREE +#if defined(CONFIG_OF_LIBFDT) +void +ft_pci_setup(void *blob, bd_t *bd) +{ + int nodeoffset; + int err; + int tmp[2]; + + nodeoffset = fdt_find_node_by_path(blob, "/" OF_SOC "/pci@8500"); + if (nodeoffset >= 0) { + tmp[0] = cpu_to_be32(pci_hose[0].first_busno); + tmp[1] = cpu_to_be32(pci_hose[0].last_busno); + err = fdt_setprop(blob, nodeoffset, "bus-range", + tmp, sizeof(tmp)); + + tmp[0] = cpu_to_be32(gd->pci_clk); + err = fdt_setprop(blob, nodeoffset, "clock-frequency", + tmp, sizeof(tmp[0])); + } +#ifdef CONFIG_MPC83XX_PCI2 + nodeoffset = fdt_find_node_by_path(blob, "/" OF_SOC "/pci@8500"); + if (nodeoffset >= 0) { + tmp[0] = cpu_to_be32(pci_hose[1].first_busno); + tmp[1] = cpu_to_be32(pci_hose[1].last_busno); + err = fdt_setprop(blob, nodeoffset, "bus-range", + tmp, sizeof(tmp)); + + tmp[0] = cpu_to_be32(gd->pci_clk); + err = fdt_setprop(blob, nodeoffset, "clock-frequency", + tmp, sizeof(tmp[0])); + } +#endif +} +#elif defined(CONFIG_OF_FLAT_TREE) void ft_pci_setup(void *blob, bd_t *bd) { @@ -355,3 +389,4 @@ ft_pci_setup(void *blob, bd_t *bd) #endif } #endif /* CONFIG_OF_FLAT_TREE */ +#endif /* CONFIG_PCI */ diff --git a/board/mpc8360emds/Makefile b/board/freescale/mpc8360emds/Makefile index 5ec7a87..5ec7a87 100644 --- a/board/mpc8360emds/Makefile +++ b/board/freescale/mpc8360emds/Makefile diff --git a/board/mpc8360emds/config.mk b/board/freescale/mpc8360emds/config.mk index 9ace886..9ace886 100644 --- a/board/mpc8360emds/config.mk +++ b/board/freescale/mpc8360emds/config.mk diff --git a/board/mpc8360emds/mpc8360emds.c b/board/freescale/mpc8360emds/mpc8360emds.c index 3fa093d..e050cd4 100644 --- a/board/mpc8360emds/mpc8360emds.c +++ b/board/freescale/mpc8360emds/mpc8360emds.c @@ -29,7 +29,9 @@ #include <ft_build.h> #elif defined(CONFIG_OF_LIBFDT) #include <libfdt.h> -#include <libfdt_env.h> +#endif +#if defined(CONFIG_PQ_MDS_PIB) +#include "../common/pq-mds-pib.h" #endif const qe_iop_conf_t qe_iop_conf_tab[] = { @@ -107,6 +109,14 @@ int board_early_init_f(void) return 0; } +int board_early_init_r(void) +{ +#ifdef CONFIG_PQ_MDS_PIB + pib_init(); +#endif + return 0; +} + #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC) extern void ddr_enable_ecc(unsigned int dram_size); #endif @@ -139,7 +149,7 @@ long int initdram(int board_type) * Initialize SDRAM if it is on local bus. */ sdram_init(); - puts(" DDR RAM: "); + /* return total bus SDRAM size(bytes) -- DDR */ return (msize * 1024 * 1024); } @@ -224,8 +234,6 @@ void sdram_init(void) volatile lbus83xx_t *lbc = &immap->lbus; uint *sdram_addr = (uint *) CFG_LBC_SDRAM_BASE; - puts("\n SDRAM on Local Bus: "); - print_size(CFG_LBC_SDRAM_SIZE * 1024 * 1024, "\n"); /* * Setup SDRAM Base and Option Registers, already done in cpu_init.c */ @@ -281,36 +289,13 @@ void sdram_init(void) #else void sdram_init(void) { - puts("SDRAM on Local Bus is NOT available!\n"); } #endif -#if (defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)) \ - && defined(CONFIG_OF_BOARD_SETUP) - -/* - * Prototypes of functions that we use. - */ -void ft_cpu_setup(void *blob, bd_t *bd); - -#ifdef CONFIG_PCI -void ft_pci_setup(void *blob, bd_t *bd); -#endif - -void -ft_board_setup(void *blob, bd_t *bd) +#if defined(CONFIG_OF_BOARD_SETUP) +void ft_board_setup(void *blob, bd_t *bd) { -#if defined(CONFIG_OF_LIBFDT) - int nodeoffset; - int tmp[2]; - - nodeoffset = fdt_find_node_by_path(blob, "/memory"); - if (nodeoffset >= 0) { - tmp[0] = cpu_to_be32(bd->bi_memstart); - tmp[1] = cpu_to_be32(bd->bi_memsize); - fdt_setprop(blob, nodeoffset, "reg", tmp, sizeof(tmp)); - } -#else +#if defined(CONFIG_OF_FLAT_TREE) u32 *p; int len; @@ -320,10 +305,9 @@ ft_board_setup(void *blob, bd_t *bd) *p = cpu_to_be32(bd->bi_memsize); } #endif - + ft_cpu_setup(blob, bd); #ifdef CONFIG_PCI ft_pci_setup(blob, bd); #endif - ft_cpu_setup(blob, bd); } -#endif /* CONFIG_OF_x */ +#endif diff --git a/board/mpc8360emds/pci.c b/board/freescale/mpc8360emds/pci.c index 8f90471..cf7ef90 100644 --- a/board/mpc8360emds/pci.c +++ b/board/freescale/mpc8360emds/pci.c @@ -22,7 +22,6 @@ #include <ft_build.h> #elif defined(CONFIG_OF_LIBFDT) #include <libfdt.h> -#include <libfdt_env.h> #endif #include <asm/fsl_i2c.h> @@ -132,7 +131,6 @@ void pci_init_board(void) volatile pcictrl83xx_t *pci_ctrl; volatile pciconf83xx_t *pci_conf; - u8 val8, orig_i2c_bus; u16 reg16; u32 val32; u32 dev; @@ -201,43 +199,6 @@ void pci_init_board(void) PIWAR_IWS_2G; /* - * Assign PIB PMC slot to desired PCI bus - */ - - /* Switch temporarily to I2C bus #2 */ - orig_i2c_bus = i2c_get_bus_num(); - i2c_set_bus_num(1); - - val8 = 0; - i2c_write(0x23, 0x6, 1, &val8, 1); - i2c_write(0x23, 0x7, 1, &val8, 1); - val8 = 0xff; - i2c_write(0x23, 0x2, 1, &val8, 1); - i2c_write(0x23, 0x3, 1, &val8, 1); - - val8 = 0; - i2c_write(0x26, 0x6, 1, &val8, 1); - val8 = 0x34; - i2c_write(0x26, 0x7, 1, &val8, 1); - - val8 = 0xf3; /*PMC1, PMC2, PMC3 slot to PCI bus */ - i2c_write(0x26, 0x2, 1, &val8, 1); - val8 = 0xff; - i2c_write(0x26, 0x3, 1, &val8, 1); - - val8 = 0; - i2c_write(0x27, 0x6, 1, &val8, 1); - i2c_write(0x27, 0x7, 1, &val8, 1); - val8 = 0xff; - i2c_write(0x27, 0x2, 1, &val8, 1); - val8 = 0xef; - i2c_write(0x27, 0x3, 1, &val8, 1); - asm("eieio"); - - /* Reset to original I2C bus */ - i2c_set_bus_num(orig_i2c_bus); - - /* * Release PCI RST Output signal */ udelay(2000); @@ -293,8 +254,6 @@ void pci_init_board(void) pci_hose_write_config_byte(&hose[0], dev, PCI_LATENCY_TIMER, 0x80); pci_hose_write_config_byte(&hose[0], dev, PCI_CACHE_LINE_SIZE, 0x08); - printf("PCI 32bit bus on PMC1 & PMC2 & PMC3\n"); - /* * Hose scan. */ @@ -314,7 +273,12 @@ ft_pci_setup(void *blob, bd_t *bd) if (nodeoffset >= 0) { tmp[0] = cpu_to_be32(hose[0].first_busno); tmp[1] = cpu_to_be32(hose[0].last_busno); - err = fdt_setprop(blob, nodeoffset, "bus-range", tmp, sizeof(tmp)); + err = fdt_setprop(blob, nodeoffset, "bus-range", + tmp, sizeof(tmp)); + + tmp[0] = cpu_to_be32(gd->pci_clk); + err = fdt_setprop(blob, nodeoffset, "clock-frequency", + tmp, sizeof(tmp[0])); } } #elif defined(CONFIG_OF_FLAT_TREE) diff --git a/board/freescale/mpc8544ds/Makefile b/board/freescale/mpc8544ds/Makefile index 308f707..006fdc9 100644 --- a/board/freescale/mpc8544ds/Makefile +++ b/board/freescale/mpc8544ds/Makefile @@ -24,14 +24,9 @@ include $(TOPDIR)/config.mk -ifneq ($(OBJTREE),$(SRCTREE)) -$(shell mkdir -p $(obj)../common) -endif - LIB = $(obj)lib$(BOARD).a -COBJS := $(BOARD).o \ - ../common/pixis.o +COBJS := $(BOARD).o SOBJS := init.o diff --git a/board/freescale/mpc8544ds/init.S b/board/freescale/mpc8544ds/init.S index ea7d54d..68ccba7 100644 --- a/board/freescale/mpc8544ds/init.S +++ b/board/freescale/mpc8544ds/init.S @@ -218,7 +218,7 @@ law_entry: .long LAWAR_EN | LAWAR_TRGT_PCI1 | (LAWAR_SIZE & LAWAR_SIZE_512M) .long (CFG_PCI1_IO_PHYS>>12) & 0xfffff - .long LAWAR_EN | LAWAR_TRGT_PCI1 | (LAWAR_SIZE & LAWAR_SIZE_16M) + .long LAWAR_EN | LAWAR_TRGT_PCI1 | (LAWAR_SIZE & LAWAR_SIZE_64K) .long (CFG_LBC_CACHE_BASE>>12) & 0xfffff .long LAWAR_EN | LAWAR_TRGT_LBC | (LAWAR_SIZE & LAWAR_SIZE_256M) @@ -226,18 +226,17 @@ law_entry: .long (CFG_PCIE1_MEM_PHYS>>12) & 0xfffff .long LAWAR_EN | LAWAR_TRGT_PCIE1 | (LAWAR_SIZE & LAWAR_SIZE_256M) - /* To keep to 10 LAWs, PCIE1_IO_PHYS must use top of mem region */ + .long (CFG_PCIE1_IO_PHYS>>12) & 0xfffff + .long LAWAR_EN | LAWAR_TRGT_PCIE1 | (LAWAR_SIZE & LAWAR_SIZE_64K) .long (CFG_PCIE2_MEM_PHYS>>12) & 0xfffff .long LAWAR_EN | LAWAR_TRGT_PCIE2 | (LAWAR_SIZE & LAWAR_SIZE_512M) .long (CFG_PCIE2_IO_PHYS>>12) & 0xfffff - .long LAWAR_EN | LAWAR_TRGT_PCIE2 | (LAWAR_SIZE & LAWAR_SIZE_16M) + .long LAWAR_EN | LAWAR_TRGT_PCIE2 | (LAWAR_SIZE & LAWAR_SIZE_64K) + /* contains both PCIE3 MEM & IO space */ .long (CFG_PCIE3_MEM_PHYS>>12) & 0xfffff - .long LAWAR_EN | LAWAR_TRGT_PCIE3 | (LAWAR_SIZE & LAWAR_SIZE_256M) - - .long (CFG_PCIE3_IO_PHYS>>12) & 0xfffff - .long LAWAR_EN | LAWAR_TRGT_PCIE3 | (LAWAR_SIZE & LAWAR_SIZE_16M) + .long LAWAR_EN | LAWAR_TRGT_PCIE3 | (LAWAR_SIZE & LAWAR_SIZE_4M) 4: entry_end diff --git a/board/freescale/mpc8544ds/mpc8544ds.c b/board/freescale/mpc8544ds/mpc8544ds.c index 8ddbb01..76d9091 100644 --- a/board/freescale/mpc8544ds/mpc8544ds.c +++ b/board/freescale/mpc8544ds/mpc8544ds.c @@ -26,6 +26,7 @@ #include <asm/processor.h> #include <asm/immap_85xx.h> #include <asm/immap_fsl_pci.h> +#include <asm/io.h> #include <spd.h> #include <miiphy.h> @@ -222,6 +223,11 @@ pci_init_board(void) printf (" PCIE3 on bus %02x - %02x\n", hose->first_busno,hose->last_busno); + /* + * Activate ULI1575 legacy chip by performing a fake + * memory access. Needed to make ULI RTC work. + */ + in_be32(CFG_PCIE3_MEM_BASE); } else { printf (" PCIE3: disabled\n"); } @@ -516,8 +522,16 @@ ft_board_setup(void *blob, bd_t *bd) *p++ = cpu_to_be32(bd->bi_memstart); *p = cpu_to_be32(bd->bi_memsize); } +#ifdef CONFIG_PCI1 + p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8000/bus-range", &len); + if (p != NULL) { + p[0] = 0; + p[1] = pci1_hose.last_busno - pci1_hose.first_busno; + debug("PCI@8000 first_busno=%d last_busno=%d\n",p[0],p[1]); + } +#endif #ifdef CONFIG_PCIE1 - p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@a000/bus-range", &len); + p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pcie@a000/bus-range", &len); if (p != NULL) { p[0] = 0; p[1] = pcie1_hose.last_busno - pcie1_hose.first_busno; @@ -525,7 +539,7 @@ ft_board_setup(void *blob, bd_t *bd) } #endif #ifdef CONFIG_PCIE2 - p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@9000/bus-range", &len); + p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pcie@9000/bus-range", &len); if (p != NULL) { p[0] = 0; p[1] = pcie2_hose.last_busno - pcie2_hose.first_busno; @@ -533,19 +547,12 @@ ft_board_setup(void *blob, bd_t *bd) } #endif #ifdef CONFIG_PCIE3 - p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@b000/bus-range", &len); + p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pcie@b000/bus-range", &len); if (p != NULL) { p[0] = 0; p[1] = pcie3_hose.last_busno - pcie3_hose.first_busno;; debug("PCI@b000 first_busno=%d last_busno=%d\n",p[0],p[1]); } #endif - ft_cpu_setup(blob, bd); - - p = ft_get_prop(blob, "/memory/reg", &len); - if (p != NULL) { - *p++ = cpu_to_be32(bd->bi_memstart); - *p = cpu_to_be32(bd->bi_memsize); - } } #endif diff --git a/board/mpc8641hpcn/Makefile b/board/freescale/mpc8641hpcn/Makefile index df56b31..201da3e 100644 --- a/board/mpc8641hpcn/Makefile +++ b/board/freescale/mpc8641hpcn/Makefile @@ -23,14 +23,9 @@ include $(TOPDIR)/config.mk -ifneq ($(OBJTREE),$(SRCTREE)) -$(shell mkdir -p $(obj)../freescale/common) -endif - LIB = $(obj)lib$(BOARD).a -COBJS := $(BOARD).o sys_eeprom.o \ - ../freescale/common/pixis.o +COBJS := $(BOARD).o SOBJS := init.o diff --git a/board/mpc8641hpcn/config.mk b/board/freescale/mpc8641hpcn/config.mk index f778dcb..f778dcb 100644 --- a/board/mpc8641hpcn/config.mk +++ b/board/freescale/mpc8641hpcn/config.mk diff --git a/board/mpc8641hpcn/init.S b/board/freescale/mpc8641hpcn/init.S index cb21ba6..cb21ba6 100644 --- a/board/mpc8641hpcn/init.S +++ b/board/freescale/mpc8641hpcn/init.S diff --git a/board/mpc8641hpcn/mpc8641hpcn.c b/board/freescale/mpc8641hpcn/mpc8641hpcn.c index 1bfbe88..931be9f 100644 --- a/board/mpc8641hpcn/mpc8641hpcn.c +++ b/board/freescale/mpc8641hpcn/mpc8641hpcn.c @@ -33,7 +33,7 @@ extern void ft_cpu_setup(void *blob, bd_t *bd); #endif -#include "../freescale/common/pixis.h" +#include "../common/pixis.h" #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) extern void ddr_enable_ecc(unsigned int dram_size); @@ -338,6 +338,22 @@ ft_board_setup(void *blob, bd_t *bd) *p++ = cpu_to_be32(bd->bi_memstart); *p = cpu_to_be32(bd->bi_memsize); } +#ifdef CONFIG_PCI1 + p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pcie@8000/bus-range", &len); + if (p != NULL) { + p[0] = 0; + p[1] = pci1_hose.last_busno - pci1_hose.first_busno; + debug("PCI@8000 first_busno=%d last_busno=%d\n",p[0],p[1]); + } +#endif +#ifdef CONFIG_PCI2 + p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pcie@9000/bus-range", &len); + if (p != NULL) { + p[0] = 0; + p[1] = pci2_hose.last_busno - pci2_hose.first_busno; + debug("PCI@9000 first_busno=%d last_busno=%d\n",p[0],p[1]); + } +#endif } #endif diff --git a/board/mpc8641hpcn/u-boot.lds b/board/freescale/mpc8641hpcn/u-boot.lds index 5864464..fd16362 100644 --- a/board/mpc8641hpcn/u-boot.lds +++ b/board/freescale/mpc8641hpcn/u-boot.lds @@ -51,7 +51,7 @@ SECTIONS .text : { cpu/mpc86xx/start.o (.text) - board/mpc8641hpcn/init.o (.bootpg) + board/freescale/mpc8641hpcn/init.o (.bootpg) cpu/mpc86xx/traps.o (.text) cpu/mpc86xx/interrupts.o (.text) cpu/mpc86xx/cpu_init.o (.text) diff --git a/board/icecube/icecube.c b/board/icecube/icecube.c index c027f6f..07ba245 100644 --- a/board/icecube/icecube.c +++ b/board/icecube/icecube.c @@ -28,10 +28,7 @@ #include <mpc5xxx.h> #include <pci.h> #include <asm/processor.h> - -#if defined(CONFIG_OF_FLAT_TREE) -#include <ft_build.h> -#endif +#include <libfdt.h> #if defined(CONFIG_LITE5200B) #include "mt46v32m16.h" @@ -386,7 +383,7 @@ void ide_set_reset (int idereset) } #endif -#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) void ft_board_setup(void *blob, bd_t *bd) { diff --git a/board/idmr/Makefile b/board/idmr/Makefile index cf07cf4..be704b7 100644 --- a/board/idmr/Makefile +++ b/board/idmr/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -COBJS = $(BOARD).o flash.o +COBJS = $(BOARD).o flash.o mii.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/idmr/idmr.c b/board/idmr/idmr.c index 58cdba1..081c375 100644 --- a/board/idmr/idmr.c +++ b/board/idmr/idmr.c @@ -22,8 +22,7 @@ */ #include <common.h> -#include <asm/m5271.h> -#include <asm/immap_5271.h> +#include <asm/immap.h> int checkboard (void) { puts ("Board: iDMR\n"); diff --git a/board/idmr/mii.c b/board/idmr/mii.c new file mode 100644 index 0000000..f6c63c3 --- /dev/null +++ b/board/idmr/mii.c @@ -0,0 +1,303 @@ +/* + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/fec.h> +#include <asm/immap.h> + +#include <config.h> +#include <net.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) +#undef MII_DEBUG +#undef ET_DEBUG + +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + if (setclear) { + /* Enable Ethernet pins */ + mbar_writeByte(MCF_GPIO_PAR_FECI2C, CFG_FECI2C); + } else { + } + + return 0; +} + +#if defined(CFG_DISCOVER_PHY) || defined(CONFIG_CMD_MII) +#include <miiphy.h> + +/* Make MII read/write commands for the FEC. */ +#define mk_mii_read(ADDR, REG) (0x60020000 | ((ADDR << 23) | (REG & 0x1f) << 18)) + +#define mk_mii_write(ADDR, REG, VAL) (0x50020000 | ((ADDR << 23) | (REG & 0x1f) << 18) | (VAL & 0xffff)) + +/* PHY identification */ +#define PHY_ID_LXT970 0x78100000 /* LXT970 */ +#define PHY_ID_LXT971 0x001378e0 /* LXT971 and 972 */ +#define PHY_ID_82555 0x02a80150 /* Intel 82555 */ +#define PHY_ID_QS6612 0x01814400 /* QS6612 */ +#define PHY_ID_AMD79C784 0x00225610 /* AMD 79C784 */ +#define PHY_ID_LSI80225 0x0016f870 /* LSI 80225 */ +#define PHY_ID_LSI80225B 0x0016f880 /* LSI 80225/B */ +#define PHY_ID_DP83848VV 0x20005C90 /* National 83848 */ +#define PHY_ID_DP83849 0x20005CA2 /* National 82849 */ +#define PHY_ID_KS8721BL 0x00221619 /* Micrel KS8721BL/SL */ + +#define STR_ID_LXT970 "LXT970" +#define STR_ID_LXT971 "LXT971" +#define STR_ID_82555 "Intel82555" +#define STR_ID_QS6612 "QS6612" +#define STR_ID_AMD79C784 "AMD79C784" +#define STR_ID_LSI80225 "LSI80225" +#define STR_ID_LSI80225B "LSI80225/B" +#define STR_ID_DP83848VV "N83848" +#define STR_ID_DP83849 "N83849" +#define STR_ID_KS8721BL "KS8721BL" + +/**************************************************************************** + * mii_init -- Initialize the MII for MII command without ethernet + * This function is a subset of eth_init + **************************************************************************** + */ +void mii_reset(struct fec_info_s *info) +{ + volatile fec_t *fecp = (fec_t *) (info->miibase); + int i; + + fecp->ecr = FEC_ECR_RESET; + for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i) { + udelay(1); + } + if (i == FEC_RESET_DELAY) { + printf("FEC_RESET_DELAY timeout\n"); + } +} + +/* send command to phy using mii, wait for result */ +uint mii_send(uint mii_cmd) +{ + struct fec_info_s *info; + struct eth_device *dev; + volatile fec_t *ep; + uint mii_reply; + int j = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + ep = (fec_t *) info->miibase; + + ep->mmfr = mii_cmd; /* command to phy */ + + /* wait for mii complete */ + while (!(ep->eir & FEC_EIR_MII) && (j < MCFFEC_TOUT_LOOP)) { + udelay(1); + j++; + } + if (j >= MCFFEC_TOUT_LOOP) { + printf("MII not complete\n"); + return -1; + } + + mii_reply = ep->mmfr; /* result from phy */ + ep->eir = FEC_EIR_MII; /* clear MII complete */ +#ifdef ET_DEBUG + printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n", + __FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply); +#endif + + return (mii_reply & 0xffff); /* data read from phy */ +} +#endif /* CFG_DISCOVER_PHY || (CONFIG_COMMANDS & CONFIG_CMD_MII) */ + +#if defined(CFG_DISCOVER_PHY) +int mii_discover_phy(struct eth_device *dev) +{ +#define MAX_PHY_PASSES 11 + struct fec_info_s *info = dev->priv; + int phyaddr, pass; + uint phyno, phytype; + + if (info->phyname_init) + return info->phy_addr; + + phyaddr = -1; /* didn't find a PHY yet */ + for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) { + if (pass > 1) { + /* PHY may need more time to recover from reset. + * The LXT970 needs 50ms typical, no maximum is + * specified, so wait 10ms before try again. + * With 11 passes this gives it 100ms to wake up. + */ + udelay(10000); /* wait 10ms */ + } + + for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) { + + phytype = mii_send(mk_mii_read(phyno, PHY_PHYIDR1)); +#ifdef ET_DEBUG + printf("PHY type 0x%x pass %d type\n", phytype, pass); +#endif + if (phytype != 0xffff) { + phyaddr = phyno; + phytype <<= 16; + phytype |= + mii_send(mk_mii_read(phyno, PHY_PHYIDR2)); + + switch (phytype & 0xffffffff) { + case PHY_ID_KS8721BL: + strcpy(info->phy_name, + STR_ID_KS8721BL); + info->phyname_init = 1; + break; + default: + strcpy(info->phy_name, "unknown"); + info->phyname_init = 1; + break; + } + +#ifdef ET_DEBUG + printf("PHY @ 0x%x pass %d type ", phyno, pass); + switch (phytype & 0xffffffff) { + case PHY_ID_KS8721BL: + printf(STR_ID_KS8721BL); + break; + default: + printf("0x%08x\n", phytype); + break; + } +#endif + } + } + } + if (phyaddr < 0) + printf("No PHY device found.\n"); + + return phyaddr; +} +#endif /* CFG_DISCOVER_PHY */ + +int mii_init(void) __attribute__((weak,alias("__mii_init"))); + +void __mii_init(void) +{ + volatile fec_t *fecp; + struct fec_info_s *info; + struct eth_device *dev; + int miispd = 0, i = 0; + u16 autoneg = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + fecp = (fec_t *) info->miibase; + + fecpin_setclear(dev, 1); + + mii_reset(info); + + /* We use strictly polling mode only */ + fecp->eimr = 0; + + /* Clear any pending interrupt */ + fecp->eir = 0xffffffff; + + /* Set MII speed */ + miispd = (gd->bus_clk / 1000000) / 5; + fecp->mscr = miispd << 1; + + info->phy_addr = mii_discover_phy(dev); + +#define AUTONEGLINK (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS) + while (i < MCFFEC_TOUT_LOOP) { + autoneg = 0; + miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &autoneg); + i++; + + if ((autoneg & AUTONEGLINK) == AUTONEGLINK) + break; + + udelay(500); + } + if (i >= MCFFEC_TOUT_LOOP) { + printf("Auto Negotiation not complete\n"); + } + + /* adapt to the half/full speed settings */ + info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16; + info->dup_spd |= miiphy_speed(dev->name, info->phy_addr); +} + +/***************************************************************************** + * Read and write a MII PHY register, routines used by MII Utilities + * + * FIXME: These routines are expected to return 0 on success, but mii_send + * does _not_ return an error code. Maybe 0xFFFF means error, i.e. + * no PHY connected... + * For now always return 0. + * FIXME: These routines only work after calling eth_init() at least once! + * Otherwise they hang in mii_send() !!! Sorry! + *****************************************************************************/ + +int mcffec_miiphy_read(char *devname, unsigned char addr, unsigned char reg, + unsigned short *value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_read(0x%x) @ 0x%x = ", reg, addr); +#endif + rdreg = mii_send(mk_mii_read(addr, reg)); + + *value = rdreg; + +#ifdef MII_DEBUG + printf("0x%04x\n", *value); +#endif + + return 0; +} + +int mcffec_miiphy_write(char *devname, unsigned char addr, unsigned char reg, + unsigned short value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_write(0x%x) @ 0x%x = ", reg, addr); +#endif + + rdreg = mii_send(mk_mii_write(addr, reg, value)); + +#ifdef MII_DEBUG + printf("0x%04x\n", value); +#endif + + return 0; +} + +#endif /* CONFIG_CMD_NET, FEC_ENET & NET_MULTI */ diff --git a/board/jupiter/jupiter.c b/board/jupiter/jupiter.c index b227487..efdc333 100644 --- a/board/jupiter/jupiter.c +++ b/board/jupiter/jupiter.c @@ -28,11 +28,7 @@ #include <mpc5xxx.h> #include <pci.h> #include <asm/processor.h> - -#if defined(CONFIG_OF_FLAT_TREE) -#include <ft_build.h> -#endif - +#include <libfdt.h> #define SDRAM_DDR 0 #if 1 @@ -308,7 +304,7 @@ void ide_set_reset (int idereset) } #endif -#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) void ft_board_setup(void *blob, bd_t *bd) { diff --git a/board/lwmon5/Makefile b/board/lwmon5/Makefile index 06ef7f9..2a93571 100644 --- a/board/lwmon5/Makefile +++ b/board/lwmon5/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -COBJS = $(BOARD).o sdram.o +COBJS = $(BOARD).o kbd.o sdram.o SOBJS = init.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/board/lwmon5/kbd.c b/board/lwmon5/kbd.c new file mode 100644 index 0000000..1e5349a --- /dev/null +++ b/board/lwmon5/kbd.c @@ -0,0 +1,458 @@ +/* + * (C) Copyright 2007 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * (C) Copyright 2001, 2002 + * DENX Software Engineering + * Wolfgang Denk, wd@denx.de + * + * 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 + */ + +/* define DEBUG for debugging output (obviously ;-)) */ +#if 0 +#define DEBUG +#endif + +#include <common.h> +#include <i2c.h> +#include <command.h> +#include <post.h> +#include <serial.h> +#include <malloc.h> + +#include <linux/types.h> +#include <linux/string.h> /* for strdup */ + +DECLARE_GLOBAL_DATA_PTR; + +static void kbd_init (void); +static int compare_magic (uchar *kbd_data, uchar *str); + +/*--------------------- Local macros and constants --------------------*/ +#define _NOT_USED_ 0xFFFFFFFF + +/*------------------------- Keyboard controller -----------------------*/ +/* command codes */ +#define KEYBD_CMD_READ_KEYS 0x01 +#define KEYBD_CMD_READ_VERSION 0x02 +#define KEYBD_CMD_READ_STATUS 0x03 +#define KEYBD_CMD_RESET_ERRORS 0x10 + +/* status codes */ +#define KEYBD_STATUS_MASK 0x3F +#define KEYBD_STATUS_H_RESET 0x20 +#define KEYBD_STATUS_BROWNOUT 0x10 +#define KEYBD_STATUS_WD_RESET 0x08 +#define KEYBD_STATUS_OVERLOAD 0x04 +#define KEYBD_STATUS_ILLEGAL_WR 0x02 +#define KEYBD_STATUS_ILLEGAL_RD 0x01 + +/* Number of bytes returned from Keyboard Controller */ +#define KEYBD_VERSIONLEN 2 /* version information */ + +/* + * This is different from the "old" lwmon dsPIC kbd controller + * implementation. Now the controller still answers with 9 bytes, + * but the last 3 bytes are always "0x06 0x07 0x08". So we just + * set the length to compare to 6 instead of 9. + */ +#define KEYBD_DATALEN 6 /* normal key scan data */ + +/* maximum number of "magic" key codes that can be assigned */ + +static uchar kbd_addr = CFG_I2C_KEYBD_ADDR; + +static uchar *key_match (uchar *); + +#define KEYBD_SET_DEBUGMODE '#' /* Magic key to enable debug output */ + +/*********************************************************************** +F* Function: int board_postclk_init (void) P*A*Z* + * +P* Parameters: none +P* +P* Returnvalue: int +P* - 0 is always returned. + * +Z* Intention: This function is the board_postclk_init() method implementation +Z* for the lwmon board. + * + ***********************************************************************/ +int board_postclk_init (void) +{ + kbd_init(); + + return (0); +} + +static void kbd_init (void) +{ + uchar kbd_data[KEYBD_DATALEN]; + uchar tmp_data[KEYBD_DATALEN]; + uchar val, errcd; + int i; + + i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); + + gd->kbd_status = 0; + + /* Forced by PIC. Delays <= 175us loose */ + udelay(1000); + + /* Read initial keyboard error code */ + val = KEYBD_CMD_READ_STATUS; + i2c_write (kbd_addr, 0, 0, &val, 1); + i2c_read (kbd_addr, 0, 0, &errcd, 1); + /* clear unused bits */ + errcd &= KEYBD_STATUS_MASK; + /* clear "irrelevant" bits. Recommended by Martin Rajek, LWN */ + errcd &= ~(KEYBD_STATUS_H_RESET|KEYBD_STATUS_BROWNOUT); + if (errcd) { + gd->kbd_status |= errcd << 8; + } + /* Reset error code and verify */ + val = KEYBD_CMD_RESET_ERRORS; + i2c_write (kbd_addr, 0, 0, &val, 1); + udelay(1000); /* delay NEEDED by keyboard PIC !!! */ + + val = KEYBD_CMD_READ_STATUS; + i2c_write (kbd_addr, 0, 0, &val, 1); + i2c_read (kbd_addr, 0, 0, &val, 1); + + val &= KEYBD_STATUS_MASK; /* clear unused bits */ + if (val) { /* permanent error, report it */ + gd->kbd_status |= val; + return; + } + + /* + * Read current keyboard state. + * + * After the error reset it may take some time before the + * keyboard PIC picks up a valid keyboard scan - the total + * scan time is approx. 1.6 ms (information by Martin Rajek, + * 28 Sep 2002). We read a couple of times for the keyboard + * to stabilize, using a big enough delay. + * 10 times should be enough. If the data is still changing, + * we use what we get :-( + */ + + memset (tmp_data, 0xFF, KEYBD_DATALEN); /* impossible value */ + for (i=0; i<10; ++i) { + val = KEYBD_CMD_READ_KEYS; + i2c_write (kbd_addr, 0, 0, &val, 1); + i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN); + + if (memcmp(kbd_data, tmp_data, KEYBD_DATALEN) == 0) { + /* consistent state, done */ + break; + } + /* remeber last state, delay, and retry */ + memcpy (tmp_data, kbd_data, KEYBD_DATALEN); + udelay (5000); + } +} + +/*********************************************************************** +F* Function: int misc_init_r (void) P*A*Z* + * +P* Parameters: none +P* +P* Returnvalue: int +P* - 0 is always returned, even in the case of a keyboard +P* error. + * +Z* Intention: This function is the misc_init_r() method implementation +Z* for the lwmon board. +Z* The keyboard controller is initialized and the result +Z* of a read copied to the environment variable "keybd". +Z* If KEYBD_SET_DEBUGMODE is defined, a check is made for +Z* this key, and if found display to the LCD will be enabled. +Z* The keys in "keybd" are checked against the magic +Z* keycommands defined in the environment. +Z* See also key_match(). + * +D* Design: wd@denx.de +C* Coding: wd@denx.de +V* Verification: dzu@denx.de + ***********************************************************************/ +int misc_init_r_kbd (void) +{ + uchar kbd_data[KEYBD_DATALEN]; + char keybd_env[2 * KEYBD_DATALEN + 1]; + uchar kbd_init_status = gd->kbd_status >> 8; + uchar kbd_status = gd->kbd_status; + uchar val; + char *str; + int i; + + if (kbd_init_status) { + printf ("KEYBD: Error %02X\n", kbd_init_status); + } + if (kbd_status) { /* permanent error, report it */ + printf ("*** Keyboard error code %02X ***\n", kbd_status); + sprintf (keybd_env, "%02X", kbd_status); + setenv ("keybd", keybd_env); + return 0; + } + + /* + * Now we know that we have a working keyboard, so disable + * all output to the LCD except when a key press is detected. + */ + + if ((console_assign (stdout, "serial") < 0) || + (console_assign (stderr, "serial") < 0)) { + printf ("Can't assign serial port as output device\n"); + } + + /* Read Version */ + val = KEYBD_CMD_READ_VERSION; + i2c_write (kbd_addr, 0, 0, &val, 1); + i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_VERSIONLEN); + printf ("KEYBD: Version %d.%d\n", kbd_data[0], kbd_data[1]); + + /* Read current keyboard state */ + val = KEYBD_CMD_READ_KEYS; + i2c_write (kbd_addr, 0, 0, &val, 1); + i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN); + + for (i = 0; i < KEYBD_DATALEN; ++i) { + sprintf (keybd_env + i + i, "%02X", kbd_data[i]); + } + setenv ("keybd", keybd_env); + + str = strdup ((char *)key_match (kbd_data)); /* decode keys */ +#ifdef KEYBD_SET_DEBUGMODE + if (kbd_data[0] == KEYBD_SET_DEBUGMODE) { /* set debug mode */ + if ((console_assign (stdout, "lcd") < 0) || + (console_assign (stderr, "lcd") < 0)) { + printf ("Can't assign LCD display as output device\n"); + } + } +#endif /* KEYBD_SET_DEBUGMODE */ +#ifdef CONFIG_PREBOOT /* automatically configure "preboot" command on key match */ + setenv ("preboot", str); /* set or delete definition */ +#endif /* CONFIG_PREBOOT */ + if (str != NULL) { + free (str); + } + return (0); +} + +#ifdef CONFIG_PREBOOT + +static uchar kbd_magic_prefix[] = "key_magic"; +static uchar kbd_command_prefix[] = "key_cmd"; + +static int compare_magic (uchar *kbd_data, uchar *str) +{ + uchar compare[KEYBD_DATALEN-1]; + char *nxt; + int i; + + /* Don't include modifier byte */ + memcpy (compare, kbd_data+1, KEYBD_DATALEN-1); + + for (; str != NULL; str = (*nxt) ? (uchar *)(nxt+1) : (uchar *)nxt) { + uchar c; + int k; + + c = (uchar) simple_strtoul ((char *)str, (char **) (&nxt), 16); + + if (str == (uchar *)nxt) { /* invalid character */ + break; + } + + /* + * Check if this key matches the input. + * Set matches to zero, so they match only once + * and we can find duplicates or extra keys + */ + for (k = 0; k < sizeof(compare); ++k) { + if (compare[k] == '\0') /* only non-zero entries */ + continue; + if (c == compare[k]) { /* found matching key */ + compare[k] = '\0'; + break; + } + } + if (k == sizeof(compare)) { + return -1; /* unmatched key */ + } + } + + /* + * A full match leaves no keys in the `compare' array, + */ + for (i = 0; i < sizeof(compare); ++i) { + if (compare[i]) + { + return -1; + } + } + + return 0; +} + +/*********************************************************************** +F* Function: static uchar *key_match (uchar *kbd_data) P*A*Z* + * +P* Parameters: uchar *kbd_data +P* - The keys to match against our magic definitions +P* +P* Returnvalue: uchar * +P* - != NULL: Pointer to the corresponding command(s) +P* NULL: No magic is about to happen + * +Z* Intention: Check if pressed key(s) match magic sequence, +Z* and return the command string associated with that key(s). +Z* +Z* If no key press was decoded, NULL is returned. +Z* +Z* Note: the first character of the argument will be +Z* overwritten with the "magic charcter code" of the +Z* decoded key(s), or '\0'. +Z* +Z* Note: the string points to static environment data +Z* and must be saved before you call any function that +Z* modifies the environment. + * +D* Design: wd@denx.de +C* Coding: wd@denx.de +V* Verification: dzu@denx.de + ***********************************************************************/ +static uchar *key_match (uchar *kbd_data) +{ + char magic[sizeof (kbd_magic_prefix) + 1]; + uchar *suffix; + char *kbd_magic_keys; + + /* + * The following string defines the characters that can pe appended + * to "key_magic" to form the names of environment variables that + * hold "magic" key codes, i. e. such key codes that can cause + * pre-boot actions. If the string is empty (""), then only + * "key_magic" is checked (old behaviour); the string "125" causes + * checks for "key_magic1", "key_magic2" and "key_magic5", etc. + */ + if ((kbd_magic_keys = getenv ("magic_keys")) == NULL) + kbd_magic_keys = ""; + + /* loop over all magic keys; + * use '\0' suffix in case of empty string + */ + for (suffix=(uchar *)kbd_magic_keys; *suffix || suffix==(uchar *)kbd_magic_keys; ++suffix) { + sprintf (magic, "%s%c", kbd_magic_prefix, *suffix); + debug ("### Check magic \"%s\"\n", magic); + if (compare_magic(kbd_data, (uchar *)getenv(magic)) == 0) { + char cmd_name[sizeof (kbd_command_prefix) + 1]; + char *cmd; + + sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix); + + cmd = getenv (cmd_name); + debug ("### Set PREBOOT to $(%s): \"%s\"\n", + cmd_name, cmd ? cmd : "<<NULL>>"); + *kbd_data = *suffix; + return ((uchar *)cmd); + } + } + debug ("### Delete PREBOOT\n"); + *kbd_data = '\0'; + return (NULL); +} +#endif /* CONFIG_PREBOOT */ + +/*********************************************************************** +F* Function: int do_kbd (cmd_tbl_t *cmdtp, int flag, +F* int argc, char *argv[]) P*A*Z* + * +P* Parameters: cmd_tbl_t *cmdtp +P* - Pointer to our command table entry +P* int flag +P* - If the CMD_FLAG_REPEAT bit is set, then this call is +P* a repetition +P* int argc +P* - Argument count +P* char *argv[] +P* - Array of the actual arguments +P* +P* Returnvalue: int +P* - 0 is always returned. + * +Z* Intention: Implement the "kbd" command. +Z* The keyboard status is read. The result is printed on +Z* the console and written into the "keybd" environment +Z* variable. + * +D* Design: wd@denx.de +C* Coding: wd@denx.de +V* Verification: dzu@denx.de + ***********************************************************************/ +int do_kbd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + uchar kbd_data[KEYBD_DATALEN]; + char keybd_env[2 * KEYBD_DATALEN + 1]; + uchar val; + int i; + +#if 0 /* Done in kbd_init */ + i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); +#endif + + /* Read keys */ + val = KEYBD_CMD_READ_KEYS; + i2c_write (kbd_addr, 0, 0, &val, 1); + i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN); + + puts ("Keys:"); + for (i = 0; i < KEYBD_DATALEN; ++i) { + sprintf (keybd_env + i + i, "%02X", kbd_data[i]); + printf (" %02x", kbd_data[i]); + } + putc ('\n'); + setenv ("keybd", keybd_env); + return 0; +} + +U_BOOT_CMD( + kbd, 1, 1, do_kbd, + "kbd - read keyboard status\n", + NULL +); + +/*----------------------------- Utilities -----------------------------*/ + +#ifdef CONFIG_POST +/* + * Returns 1 if keys pressed to start the power-on long-running tests + * Called from board_init_f(). + */ +int post_hotkeys_pressed(void) +{ + uchar kbd_data[KEYBD_DATALEN]; + uchar val; + + /* Read keys */ + val = KEYBD_CMD_READ_KEYS; + i2c_write (kbd_addr, 0, 0, &val, 1); + i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN); + + return (compare_magic(kbd_data, (uchar *)CONFIG_POST_KEY_MAGIC) == 0); +} +#endif diff --git a/board/lwmon5/lwmon5.c b/board/lwmon5/lwmon5.c index 830ec19..77f9989 100644 --- a/board/lwmon5/lwmon5.c +++ b/board/lwmon5/lwmon5.c @@ -19,6 +19,7 @@ */ #include <common.h> +#include <command.h> #include <ppc440.h> #include <asm/processor.h> #include <asm/gpio.h> @@ -28,7 +29,8 @@ DECLARE_GLOBAL_DATA_PTR; extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ -ulong flash_get_size (ulong base, int banknum); +ulong flash_get_size(ulong base, int banknum); +int misc_init_r_kbd(void); int board_early_init_f(void) { @@ -295,6 +297,11 @@ int misc_init_r(void) out_be32((void *)0xc4000024, 0x64); out_be32((void *)0xc4000020, 0x701); + /* + * Init matrix keyboard + */ + misc_init_r_kbd(); + return 0; } @@ -522,13 +529,28 @@ void hw_watchdog_reset(void) gpio_write_bit(CFG_GPIO_WATCHDOG, val); } -#ifdef CONFIG_POST -/* - * Returns 1 if keys pressed to start the power-on long-running tests - * Called from board_init_f(). - */ -int post_hotkeys_pressed(void) +int do_eeprom_wp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { - return (ctrlc()); + if (argc < 2) { + printf("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + if ((strcmp(argv[1], "on") == 0)) { + gpio_write_bit(CFG_GPIO_EEPROM_EXT_WP, 1); + } else if ((strcmp(argv[1], "off") == 0)) { + gpio_write_bit(CFG_GPIO_EEPROM_EXT_WP, 0); + } else { + printf("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + + return 0; } -#endif + +U_BOOT_CMD( + eepromwp, 2, 0, do_eeprom_wp, + "eepromwp- eeprom write protect off/on\n", + "<on|off> - enable (on) or disable (off) I2C EEPROM write protect\n" +); diff --git a/board/lwmon5/sdram.c b/board/lwmon5/sdram.c index f906b85..d4547e2 100644 --- a/board/lwmon5/sdram.c +++ b/board/lwmon5/sdram.c @@ -57,7 +57,6 @@ void dcbz_area(u32 start_address, u32 num_bytes); void dflush(void); -#ifdef CONFIG_ADD_RAM_INFO static u32 is_ecc_enabled(void) { u32 val; @@ -87,7 +86,6 @@ void board_add_ram_info(int use_default) val = DDR0_03_CASLAT_DECODE(val); printf(", CL%d)", val); } -#endif static int wait_for_dlllock(void) { diff --git a/board/m5271evb/Makefile b/board/m5271evb/Makefile index 424ab1c..2ec71ee 100644 --- a/board/m5271evb/Makefile +++ b/board/m5271evb/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -COBJS = $(BOARD).o +COBJS = $(BOARD).o mii.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/m5271evb/m5271evb.c b/board/m5271evb/m5271evb.c index c26c91d..9caad63 100644 --- a/board/m5271evb/m5271evb.c +++ b/board/m5271evb/m5271evb.c @@ -22,8 +22,7 @@ */ #include <common.h> -#include <asm/m5271.h> -#include <asm/immap_5271.h> +#include <asm/immap.h> int checkboard (void) { puts ("Board: Freescale M5271EVB\n"); diff --git a/board/m5271evb/mii.c b/board/m5271evb/mii.c new file mode 100644 index 0000000..f6c63c3 --- /dev/null +++ b/board/m5271evb/mii.c @@ -0,0 +1,303 @@ +/* + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/fec.h> +#include <asm/immap.h> + +#include <config.h> +#include <net.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) +#undef MII_DEBUG +#undef ET_DEBUG + +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + if (setclear) { + /* Enable Ethernet pins */ + mbar_writeByte(MCF_GPIO_PAR_FECI2C, CFG_FECI2C); + } else { + } + + return 0; +} + +#if defined(CFG_DISCOVER_PHY) || defined(CONFIG_CMD_MII) +#include <miiphy.h> + +/* Make MII read/write commands for the FEC. */ +#define mk_mii_read(ADDR, REG) (0x60020000 | ((ADDR << 23) | (REG & 0x1f) << 18)) + +#define mk_mii_write(ADDR, REG, VAL) (0x50020000 | ((ADDR << 23) | (REG & 0x1f) << 18) | (VAL & 0xffff)) + +/* PHY identification */ +#define PHY_ID_LXT970 0x78100000 /* LXT970 */ +#define PHY_ID_LXT971 0x001378e0 /* LXT971 and 972 */ +#define PHY_ID_82555 0x02a80150 /* Intel 82555 */ +#define PHY_ID_QS6612 0x01814400 /* QS6612 */ +#define PHY_ID_AMD79C784 0x00225610 /* AMD 79C784 */ +#define PHY_ID_LSI80225 0x0016f870 /* LSI 80225 */ +#define PHY_ID_LSI80225B 0x0016f880 /* LSI 80225/B */ +#define PHY_ID_DP83848VV 0x20005C90 /* National 83848 */ +#define PHY_ID_DP83849 0x20005CA2 /* National 82849 */ +#define PHY_ID_KS8721BL 0x00221619 /* Micrel KS8721BL/SL */ + +#define STR_ID_LXT970 "LXT970" +#define STR_ID_LXT971 "LXT971" +#define STR_ID_82555 "Intel82555" +#define STR_ID_QS6612 "QS6612" +#define STR_ID_AMD79C784 "AMD79C784" +#define STR_ID_LSI80225 "LSI80225" +#define STR_ID_LSI80225B "LSI80225/B" +#define STR_ID_DP83848VV "N83848" +#define STR_ID_DP83849 "N83849" +#define STR_ID_KS8721BL "KS8721BL" + +/**************************************************************************** + * mii_init -- Initialize the MII for MII command without ethernet + * This function is a subset of eth_init + **************************************************************************** + */ +void mii_reset(struct fec_info_s *info) +{ + volatile fec_t *fecp = (fec_t *) (info->miibase); + int i; + + fecp->ecr = FEC_ECR_RESET; + for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i) { + udelay(1); + } + if (i == FEC_RESET_DELAY) { + printf("FEC_RESET_DELAY timeout\n"); + } +} + +/* send command to phy using mii, wait for result */ +uint mii_send(uint mii_cmd) +{ + struct fec_info_s *info; + struct eth_device *dev; + volatile fec_t *ep; + uint mii_reply; + int j = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + ep = (fec_t *) info->miibase; + + ep->mmfr = mii_cmd; /* command to phy */ + + /* wait for mii complete */ + while (!(ep->eir & FEC_EIR_MII) && (j < MCFFEC_TOUT_LOOP)) { + udelay(1); + j++; + } + if (j >= MCFFEC_TOUT_LOOP) { + printf("MII not complete\n"); + return -1; + } + + mii_reply = ep->mmfr; /* result from phy */ + ep->eir = FEC_EIR_MII; /* clear MII complete */ +#ifdef ET_DEBUG + printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n", + __FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply); +#endif + + return (mii_reply & 0xffff); /* data read from phy */ +} +#endif /* CFG_DISCOVER_PHY || (CONFIG_COMMANDS & CONFIG_CMD_MII) */ + +#if defined(CFG_DISCOVER_PHY) +int mii_discover_phy(struct eth_device *dev) +{ +#define MAX_PHY_PASSES 11 + struct fec_info_s *info = dev->priv; + int phyaddr, pass; + uint phyno, phytype; + + if (info->phyname_init) + return info->phy_addr; + + phyaddr = -1; /* didn't find a PHY yet */ + for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) { + if (pass > 1) { + /* PHY may need more time to recover from reset. + * The LXT970 needs 50ms typical, no maximum is + * specified, so wait 10ms before try again. + * With 11 passes this gives it 100ms to wake up. + */ + udelay(10000); /* wait 10ms */ + } + + for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) { + + phytype = mii_send(mk_mii_read(phyno, PHY_PHYIDR1)); +#ifdef ET_DEBUG + printf("PHY type 0x%x pass %d type\n", phytype, pass); +#endif + if (phytype != 0xffff) { + phyaddr = phyno; + phytype <<= 16; + phytype |= + mii_send(mk_mii_read(phyno, PHY_PHYIDR2)); + + switch (phytype & 0xffffffff) { + case PHY_ID_KS8721BL: + strcpy(info->phy_name, + STR_ID_KS8721BL); + info->phyname_init = 1; + break; + default: + strcpy(info->phy_name, "unknown"); + info->phyname_init = 1; + break; + } + +#ifdef ET_DEBUG + printf("PHY @ 0x%x pass %d type ", phyno, pass); + switch (phytype & 0xffffffff) { + case PHY_ID_KS8721BL: + printf(STR_ID_KS8721BL); + break; + default: + printf("0x%08x\n", phytype); + break; + } +#endif + } + } + } + if (phyaddr < 0) + printf("No PHY device found.\n"); + + return phyaddr; +} +#endif /* CFG_DISCOVER_PHY */ + +int mii_init(void) __attribute__((weak,alias("__mii_init"))); + +void __mii_init(void) +{ + volatile fec_t *fecp; + struct fec_info_s *info; + struct eth_device *dev; + int miispd = 0, i = 0; + u16 autoneg = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + fecp = (fec_t *) info->miibase; + + fecpin_setclear(dev, 1); + + mii_reset(info); + + /* We use strictly polling mode only */ + fecp->eimr = 0; + + /* Clear any pending interrupt */ + fecp->eir = 0xffffffff; + + /* Set MII speed */ + miispd = (gd->bus_clk / 1000000) / 5; + fecp->mscr = miispd << 1; + + info->phy_addr = mii_discover_phy(dev); + +#define AUTONEGLINK (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS) + while (i < MCFFEC_TOUT_LOOP) { + autoneg = 0; + miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &autoneg); + i++; + + if ((autoneg & AUTONEGLINK) == AUTONEGLINK) + break; + + udelay(500); + } + if (i >= MCFFEC_TOUT_LOOP) { + printf("Auto Negotiation not complete\n"); + } + + /* adapt to the half/full speed settings */ + info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16; + info->dup_spd |= miiphy_speed(dev->name, info->phy_addr); +} + +/***************************************************************************** + * Read and write a MII PHY register, routines used by MII Utilities + * + * FIXME: These routines are expected to return 0 on success, but mii_send + * does _not_ return an error code. Maybe 0xFFFF means error, i.e. + * no PHY connected... + * For now always return 0. + * FIXME: These routines only work after calling eth_init() at least once! + * Otherwise they hang in mii_send() !!! Sorry! + *****************************************************************************/ + +int mcffec_miiphy_read(char *devname, unsigned char addr, unsigned char reg, + unsigned short *value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_read(0x%x) @ 0x%x = ", reg, addr); +#endif + rdreg = mii_send(mk_mii_read(addr, reg)); + + *value = rdreg; + +#ifdef MII_DEBUG + printf("0x%04x\n", *value); +#endif + + return 0; +} + +int mcffec_miiphy_write(char *devname, unsigned char addr, unsigned char reg, + unsigned short value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_write(0x%x) @ 0x%x = ", reg, addr); +#endif + + rdreg = mii_send(mk_mii_write(addr, reg, value)); + +#ifdef MII_DEBUG + printf("0x%04x\n", value); +#endif + + return 0; +} + +#endif /* CONFIG_CMD_NET, FEC_ENET & NET_MULTI */ diff --git a/board/m5272c3/Makefile b/board/m5272c3/Makefile index cf07cf4..be704b7 100644 --- a/board/m5272c3/Makefile +++ b/board/m5272c3/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -COBJS = $(BOARD).o flash.o +COBJS = $(BOARD).o flash.o mii.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/m5272c3/m5272c3.c b/board/m5272c3/m5272c3.c index 0dfeaf2..6dcda4f 100644 --- a/board/m5272c3/m5272c3.c +++ b/board/m5272c3/m5272c3.c @@ -22,18 +22,17 @@ */ #include <common.h> -#include <asm/m5272.h> -#include <asm/immap_5272.h> +#include <asm/immap.h> int checkboard (void) { puts ("Board: "); - puts("MOTOROLA MCF5272C3 EVB\n"); + puts ("Freescale MCF5272C3 EVB\n"); return 0; }; long int initdram (int board_type) { - volatile sdramctrl_t * sdp = (sdramctrl_t *)(CFG_MBAR + MCFSIM_SDCR); + volatile sdramctrl_t * sdp = (sdramctrl_t *)(MMAP_SDRAM); sdp->sdram_sdtr = 0xf539; sdp->sdram_sdcr = 0x4211; diff --git a/board/m5272c3/mii.c b/board/m5272c3/mii.c new file mode 100644 index 0000000..fadcbb3 --- /dev/null +++ b/board/m5272c3/mii.c @@ -0,0 +1,303 @@ +/* + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/fec.h> +#include <asm/immap.h> + +#include <config.h> +#include <net.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) +#undef MII_DEBUG +#undef ET_DEBUG + +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + if (setclear) { + gpio->gpio_pbcnt |= GPIO_PBCNT_E_MDC | GPIO_PBCNT_E_RXER | GPIO_PBCNT_E_RXD1 | GPIO_PBCNT_E_RXD2 | GPIO_PBCNT_E_RXD3 | GPIO_PBCNT_E_TXD1 | GPIO_PBCNT_E_TXD2 | GPIO_PBCNT_E_TXD3; + } else { + } + return 0; +} + +#if defined(CFG_DISCOVER_PHY) || defined(CONFIG_CMD_MII) +#include <miiphy.h> + +/* Make MII read/write commands for the FEC. */ +#define mk_mii_read(ADDR, REG) (0x60020000 | ((ADDR << 23) | (REG & 0x1f) << 18)) + +#define mk_mii_write(ADDR, REG, VAL) (0x50020000 | ((ADDR << 23) | (REG & 0x1f) << 18) | (VAL & 0xffff)) + +/* PHY identification */ +#define PHY_ID_LXT970 0x78100000 /* LXT970 */ +#define PHY_ID_LXT971 0x001378e0 /* LXT971 and 972 */ +#define PHY_ID_82555 0x02a80150 /* Intel 82555 */ +#define PHY_ID_QS6612 0x01814400 /* QS6612 */ +#define PHY_ID_AMD79C784 0x00225610 /* AMD 79C784 */ +#define PHY_ID_AMD79C874VC 0x0022561B /* AMD 79C874 */ +#define PHY_ID_LSI80225 0x0016f870 /* LSI 80225 */ +#define PHY_ID_LSI80225B 0x0016f880 /* LSI 80225/B */ +#define PHY_ID_DP83848VV 0x20005C90 /* National 83848 */ +#define PHY_ID_DP83849 0x20005CA2 /* National 82849 */ + +#define STR_ID_LXT970 "LXT970" +#define STR_ID_LXT971 "LXT971" +#define STR_ID_82555 "Intel82555" +#define STR_ID_QS6612 "QS6612" +#define STR_ID_AMD79C784 "AMD79C784" +#define STR_ID_AMD79C874VC "AMD79C874VC" +#define STR_ID_LSI80225 "LSI80225" +#define STR_ID_LSI80225B "LSI80225/B" +#define STR_ID_DP83848VV "N83848" +#define STR_ID_DP83849 "N83849" + +/**************************************************************************** + * mii_init -- Initialize the MII for MII command without ethernet + * This function is a subset of eth_init + **************************************************************************** + */ +void mii_reset(struct fec_info_s *info) +{ + volatile fec_t *fecp = (fec_t *) (info->miibase); + int i; + + fecp->ecr = FEC_ECR_RESET; + for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i) { + udelay(1); + } + if (i == FEC_RESET_DELAY) { + printf("FEC_RESET_DELAY timeout\n"); + } +} + +/* send command to phy using mii, wait for result */ +uint mii_send(uint mii_cmd) +{ + struct fec_info_s *info; + struct eth_device *dev; + volatile fec_t *ep; + uint mii_reply; + int j = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + ep = (fec_t *) info->miibase; + + ep->mmfr = mii_cmd; /* command to phy */ + + /* wait for mii complete */ + while (!(ep->eir & FEC_EIR_MII) && (j < MCFFEC_TOUT_LOOP)) { + udelay(1); + j++; + } + if (j >= MCFFEC_TOUT_LOOP) { + printf("MII not complete\n"); + return -1; + } + + mii_reply = ep->mmfr; /* result from phy */ + ep->eir = FEC_EIR_MII; /* clear MII complete */ +#ifdef ET_DEBUG + printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n", + __FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply); +#endif + + return (mii_reply & 0xffff); /* data read from phy */ +} +#endif /* CFG_DISCOVER_PHY || (CONFIG_COMMANDS & CONFIG_CMD_MII) */ + +#if defined(CFG_DISCOVER_PHY) +int mii_discover_phy(struct eth_device *dev) +{ +#define MAX_PHY_PASSES 11 + struct fec_info_s *info = dev->priv; + int phyaddr, pass; + uint phyno, phytype; + + if (info->phyname_init) + return info->phy_addr; + + phyaddr = -1; /* didn't find a PHY yet */ + for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) { + if (pass > 1) { + /* PHY may need more time to recover from reset. + * The LXT970 needs 50ms typical, no maximum is + * specified, so wait 10ms before try again. + * With 11 passes this gives it 100ms to wake up. + */ + udelay(10000); /* wait 10ms */ + } + + for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) { + + phytype = mii_send(mk_mii_read(phyno, PHY_PHYIDR1)); +#ifdef ET_DEBUG + printf("PHY type 0x%x pass %d type\n", phytype, pass); +#endif + if (phytype != 0xffff) { + phyaddr = phyno; + phytype <<= 16; + phytype |= + mii_send(mk_mii_read(phyno, PHY_PHYIDR2)); + + switch (phytype & 0xffffffff) { + case PHY_ID_AMD79C874VC: + strcpy(info->phy_name, + STR_ID_AMD79C874VC); + info->phyname_init = 1; + break; + default: + strcpy(info->phy_name, "unknown"); + info->phyname_init = 1; + break; + } + +#ifdef ET_DEBUG + printf("PHY @ 0x%x pass %d type ", phyno, pass); + switch (phytype & 0xffffffff) { + case PHY_ID_AMD79C874VC: + printf(STR_ID_AMD79C874VC); + break; + default: + printf("0x%08x\n", phytype); + break; + } +#endif + } + } + } + if (phyaddr < 0) + printf("No PHY device found.\n"); + + return phyaddr; +} +#endif /* CFG_DISCOVER_PHY */ + +int mii_init(void) __attribute__((weak,alias("__mii_init"))); + +void __mii_init(void) +{ + volatile fec_t *fecp; + struct fec_info_s *info; + struct eth_device *dev; + int miispd = 0, i = 0; + u16 autoneg = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + fecp = (fec_t *) info->miibase; + + fecpin_setclear(dev, 1); + + mii_reset(info); + + /* We use strictly polling mode only */ + fecp->eimr = 0; + + /* Clear any pending interrupt */ + fecp->eir = 0xffffffff; + + /* Set MII speed */ + miispd = (gd->bus_clk / 1000000) / 5; + fecp->mscr = miispd << 1; + + info->phy_addr = mii_discover_phy(dev); + +#define AUTONEGLINK (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS) + while (i < MCFFEC_TOUT_LOOP) { + autoneg = 0; + miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &autoneg); + i++; + + if ((autoneg & AUTONEGLINK) == AUTONEGLINK) + break; + + udelay(500); + } + if (i >= MCFFEC_TOUT_LOOP) { + printf("Auto Negotiation not complete\n"); + } + + /* adapt to the half/full speed settings */ + info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16; + info->dup_spd |= miiphy_speed(dev->name, info->phy_addr); +} + +/***************************************************************************** + * Read and write a MII PHY register, routines used by MII Utilities + * + * FIXME: These routines are expected to return 0 on success, but mii_send + * does _not_ return an error code. Maybe 0xFFFF means error, i.e. + * no PHY connected... + * For now always return 0. + * FIXME: These routines only work after calling eth_init() at least once! + * Otherwise they hang in mii_send() !!! Sorry! + *****************************************************************************/ + +int mcffec_miiphy_read(char *devname, unsigned char addr, unsigned char reg, + unsigned short *value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_read(0x%x) @ 0x%x = ", reg, addr); +#endif + rdreg = mii_send(mk_mii_read(addr, reg)); + + *value = rdreg; + +#ifdef MII_DEBUG + printf("0x%04x\n", *value); +#endif + + return 0; +} + +int mcffec_miiphy_write(char *devname, unsigned char addr, unsigned char reg, + unsigned short value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_write(0x%x) @ 0x%x = ", reg, addr); +#endif + + rdreg = mii_send(mk_mii_write(addr, reg, value)); + +#ifdef MII_DEBUG + printf("0x%04x\n", value); +#endif + + return 0; +} + +#endif /* CONFIG_CMD_NET, FEC_ENET & NET_MULTI */ diff --git a/board/m5282evb/Makefile b/board/m5282evb/Makefile index cf07cf4..2ec71ee 100644 --- a/board/m5282evb/Makefile +++ b/board/m5282evb/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -COBJS = $(BOARD).o flash.o +COBJS = $(BOARD).o mii.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/m5282evb/config.mk b/board/m5282evb/config.mk index 8484307..0aa2361 100644 --- a/board/m5282evb/config.mk +++ b/board/m5282evb/config.mk @@ -22,4 +22,4 @@ # MA 02111-1307 USA # -TEXT_BASE = 0x20000 +TEXT_BASE = 0xFFE00000 diff --git a/board/m5282evb/flash.c b/board/m5282evb/flash.c deleted file mode 100644 index 36a7c31..0000000 --- a/board/m5282evb/flash.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * (C) Copyright 2000-2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> - -#define PHYS_FLASH_1 CFG_FLASH_BASE -#define FLASH_BANK_SIZE 0x200000 - -flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; - -void flash_print_info (flash_info_t * info) -{ - int i; - - switch (info->flash_id & FLASH_VENDMASK) { - case (AMD_MANUFACT & FLASH_VENDMASK): - printf ("AMD: "); - break; - default: - printf ("Unknown Vendor "); - break; - } - - switch (info->flash_id & FLASH_TYPEMASK) { - case (AMD_ID_PL160CB & FLASH_TYPEMASK): - printf ("AM29PL160CB (16Mbit)\n"); - break; - default: - printf ("Unknown Chip Type\n"); - goto Done; - 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"); - - Done: - return; -} - - -unsigned long flash_init (void) -{ - int i, j; - ulong size = 0; - - for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { - ulong flashbase = 0; - - flash_info[i].flash_id = - (AMD_MANUFACT & FLASH_VENDMASK) | - (AMD_ID_PL160CB & FLASH_TYPEMASK); - flash_info[i].size = FLASH_BANK_SIZE; - flash_info[i].sector_count = CFG_MAX_FLASH_SECT; - memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT); - if (i == 0) - flashbase = PHYS_FLASH_1; - else - panic ("configured to many flash banks!\n"); - - for (j = 0; j < flash_info[i].sector_count; j++) { - if (j == 0) { - /* 1st is 16 KiB */ - flash_info[i].start[j] = flashbase; - } - if ((j >= 1) && (j <= 2)) { - /* 2nd and 3rd are 8 KiB */ - flash_info[i].start[j] = - flashbase + 0x4000 + 0x2000 * (j - 1); - } - if (j == 3) { - /* 4th is 32 KiB */ - flash_info[i].start[j] = flashbase + 0x8000; - } - if ((j >= 4) && (j <= 34)) { - /* rest is 256 KiB */ - flash_info[i].start[j] = - flashbase + 0x10000 + 0x10000 * (j - - 4); - } - } - size += flash_info[i].size; - } - - flash_protect (FLAG_PROTECT_SET, - CFG_FLASH_BASE, - CFG_FLASH_BASE + 0xffff, &flash_info[0]); - - return size; -} - - -#define CMD_READ_ARRAY 0x00F0 -#define CMD_UNLOCK1 0x00AA -#define CMD_UNLOCK2 0x0055 -#define CMD_ERASE_SETUP 0x0080 -#define CMD_ERASE_CONFIRM 0x0030 -#define CMD_PROGRAM 0x00A0 -#define CMD_UNLOCK_BYPASS 0x0020 - -#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CFG_FLASH_BASE + (0x00000555<<1))) -#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CFG_FLASH_BASE + (0x000002AA<<1))) - -#define BIT_ERASE_DONE 0x0080 -#define BIT_RDY_MASK 0x0080 -#define BIT_PROGRAM_ERROR 0x0020 -#define BIT_TIMEOUT 0x80000000 /* our flag */ - -#define READY 1 -#define ERR 2 -#define TMO 4 - - -int flash_erase (flash_info_t * info, int s_first, int s_last) -{ - ulong result; - int iflag, cflag, prot, sect; - int rc = ERR_OK; - int chip1; - - /* first look for protection bits */ - - if (info->flash_id == FLASH_UNKNOWN) - return ERR_UNKNOWN_FLASH_TYPE; - - if ((s_first < 0) || (s_first > s_last)) { - return ERR_INVAL; - } - - if ((info->flash_id & FLASH_VENDMASK) != - (AMD_MANUFACT & FLASH_VENDMASK)) { - return ERR_UNKNOWN_FLASH_VENDOR; - } - - prot = 0; - for (sect = s_first; sect <= s_last; ++sect) { - if (info->protect[sect]) { - prot++; - } - } - if (prot) - return ERR_PROTECTED; - - /* - * Disable interrupts which might cause a timeout - * here. Remember that our exception vectors are - * at address 0 in the flash, and we don't want a - * (ticker) exception to happen while the flash - * chip is in programming mode. - */ - - cflag = icache_status (); - icache_disable (); - iflag = disable_interrupts (); - - printf ("\n"); - - /* Start erase on unprotected sectors */ - for (sect = s_first; sect <= s_last && !ctrlc (); sect++) { - printf ("Erasing sector %2d ... ", sect); - - /* arm simple, non interrupt dependent timer */ - set_timer (0); - - if (info->protect[sect] == 0) { /* not protected */ - volatile u16 *addr = - (volatile u16 *) (info->start[sect]); - - MEM_FLASH_ADDR1 = CMD_UNLOCK1; - MEM_FLASH_ADDR2 = CMD_UNLOCK2; - MEM_FLASH_ADDR1 = CMD_ERASE_SETUP; - - MEM_FLASH_ADDR1 = CMD_UNLOCK1; - MEM_FLASH_ADDR2 = CMD_UNLOCK2; - *addr = CMD_ERASE_CONFIRM; - - /* wait until flash is ready */ - chip1 = 0; - - do { - result = *addr; - - /* check timeout */ - if (get_timer (0) > CFG_FLASH_ERASE_TOUT) { - MEM_FLASH_ADDR1 = CMD_READ_ARRAY; - chip1 = TMO; - break; - } - - if (!chip1 - && (result & 0xFFFF) & BIT_ERASE_DONE) - chip1 = READY; - - } while (!chip1); - - MEM_FLASH_ADDR1 = CMD_READ_ARRAY; - - if (chip1 == ERR) { - rc = ERR_PROG_ERROR; - goto outahere; - } - if (chip1 == TMO) { - rc = ERR_TIMOUT; - goto outahere; - } - - printf ("ok.\n"); - } else { /* it was protected */ - - printf ("protected!\n"); - } - } - - if (ctrlc ()) - printf ("User Interrupt!\n"); - - outahere: - /* allow flash to settle - wait 10 ms */ - udelay (10000); - - if (iflag) - enable_interrupts (); - - if (cflag) - icache_enable (); - - return rc; -} - -static int write_word (flash_info_t * info, ulong dest, ulong data) -{ - volatile u16 *addr = (volatile u16 *) dest; - ulong result; - int rc = ERR_OK; - int cflag, iflag; - int chip1; - - /* - * Check if Flash is (sufficiently) erased - */ - result = *addr; - if ((result & data) != data) - return ERR_NOT_ERASED; - - - /* - * Disable interrupts which might cause a timeout - * here. Remember that our exception vectors are - * at address 0 in the flash, and we don't want a - * (ticker) exception to happen while the flash - * chip is in programming mode. - */ - - cflag = icache_status (); - icache_disable (); - iflag = disable_interrupts (); - - MEM_FLASH_ADDR1 = CMD_UNLOCK1; - MEM_FLASH_ADDR2 = CMD_UNLOCK2; - MEM_FLASH_ADDR1 = CMD_PROGRAM; - *addr = data; - - /* arm simple, non interrupt dependent timer */ - set_timer (0); - - /* wait until flash is ready */ - chip1 = 0; - do { - result = *addr; - - /* check timeout */ - if (get_timer (0) > CFG_FLASH_ERASE_TOUT) { - chip1 = ERR | TMO; - break; - } - if (!chip1 && ((result & 0x80) == (data & 0x80))) - chip1 = READY; - - } while (!chip1); - - *addr = CMD_READ_ARRAY; - - if (chip1 == ERR || *addr != data) - rc = ERR_PROG_ERROR; - - if (iflag) - enable_interrupts (); - - if (cflag) - icache_enable (); - - return rc; -} - - -int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) -{ - ulong wp, data; - int rc; - - if (addr & 1) { - printf ("unaligned destination not supported\n"); - return ERR_ALIGN; - } - -#if 0 - if (cnt & 1) { - printf ("odd transfer sizes not supported\n"); - return ERR_ALIGN; - } -#endif - - wp = addr; - - if (addr & 1) { - data = (*((volatile u8 *) addr) << 8) | *((volatile u8 *) - src); - if ((rc = write_word (info, wp - 1, data)) != 0) { - return (rc); - } - src += 1; - wp += 1; - cnt -= 1; - } - - while (cnt >= 2) { - data = *((volatile u16 *) src); - if ((rc = write_word (info, wp, data)) != 0) { - return (rc); - } - src += 2; - wp += 2; - cnt -= 2; - } - - if (cnt == 1) { - data = (*((volatile u8 *) src) << 8) | - *((volatile u8 *) (wp + 1)); - if ((rc = write_word (info, wp, data)) != 0) { - return (rc); - } - src += 1; - wp += 1; - cnt -= 1; - } - - return ERR_OK; -} diff --git a/board/m5282evb/m5282evb.c b/board/m5282evb/m5282evb.c index a08af68..243d6a4 100644 --- a/board/m5282evb/m5282evb.c +++ b/board/m5282evb/m5282evb.c @@ -22,14 +22,71 @@ */ #include <common.h> +#include <asm/immap.h> + +DECLARE_GLOBAL_DATA_PTR; int checkboard (void) { - puts ("MOTOROLA M5272EVB Evaluation Board\n"); + puts ("Board: Freescale M5282EVB Evaluation Board\n"); return 0; } long int initdram (int board_type) { - return 0x1000000; + u32 dramsize, i, dramclk; + + dramsize = CFG_SDRAM_SIZE * 0x100000; + for (i = 0x13; i < 0x20; i++) { + if (dramsize == (1 << i)) + break; + } + i--; + + if (!(MCFSDRAMC_DACR0 & MCFSDRAMC_DACR_RE)) + { + dramclk = gd->bus_clk / (CFG_HZ * CFG_HZ); + + /* Initialize DRAM Control Register: DCR */ + MCFSDRAMC_DCR = (0 + | MCFSDRAMC_DCR_RTIM_6 + | MCFSDRAMC_DCR_RC((15 * dramclk)>>4)); + + /* Initialize DACR0 */ + MCFSDRAMC_DACR0 = (0 + | MCFSDRAMC_DACR_BASE(CFG_SDRAM_BASE) + | MCFSDRAMC_DACR_CASL(1) + | MCFSDRAMC_DACR_CBM(3) + | MCFSDRAMC_DACR_PS_32); + + /* Initialize DMR0 */ + MCFSDRAMC_DMR0 = (0 + | ((dramsize - 1) & 0xFFFC0000) + | MCFSDRAMC_DMR_V); + + /* Set IP (bit 3) in DACR */ + MCFSDRAMC_DACR0 |= MCFSDRAMC_DACR_IP; + + /* Wait 30ns to allow banks to precharge */ + for (i = 0; i < 5; i++) { + asm ("nop"); + } + + /* Write to this block to initiate precharge */ + *(u32 *)(CFG_SDRAM_BASE) = 0xA5A59696; + + /* Set RE (bit 15) in DACR */ + MCFSDRAMC_DACR0 |= MCFSDRAMC_DACR_RE; + + /* Wait for at least 8 auto refresh cycles to occur */ + for (i = 0; i < 2000; i++) { + asm(" nop"); + } + + /* Finish the configuration by issuing the IMRS. */ + MCFSDRAMC_DACR0 |= MCFSDRAMC_DACR_IMRS; + + /* Write to the SDRAM Mode Register */ + *(u32 *)(CFG_SDRAM_BASE + 0x400) = 0xA5A59696; + } } diff --git a/board/m5282evb/mii.c b/board/m5282evb/mii.c new file mode 100644 index 0000000..ebd3ed9 --- /dev/null +++ b/board/m5282evb/mii.c @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/fec.h> +#include <asm/immap.h> + +#include <config.h> +#include <net.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) +#undef MII_DEBUG +#undef ET_DEBUG + +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + if (setclear) { + MCFGPIO_PASPAR |= 0x0F00; + MCFGPIO_PEHLPAR = CFG_PEHLPAR; + } else { + MCFGPIO_PASPAR &= 0xF0FF; + MCFGPIO_PEHLPAR &= ~CFG_PEHLPAR; + } + return 0; +} + +#if defined(CFG_DISCOVER_PHY) || defined(CONFIG_CMD_MII) +#include <miiphy.h> + +/* Make MII read/write commands for the FEC. */ +#define mk_mii_read(ADDR, REG) (0x60020000 | ((ADDR << 23) | (REG & 0x1f) << 18)) + +#define mk_mii_write(ADDR, REG, VAL) (0x50020000 | ((ADDR << 23) | (REG & 0x1f) << 18) | (VAL & 0xffff)) + +/* PHY identification */ +#define PHY_ID_LXT970 0x78100000 /* LXT970 */ +#define PHY_ID_LXT971 0x001378e0 /* LXT971 and 972 */ +#define PHY_ID_82555 0x02a80150 /* Intel 82555 */ +#define PHY_ID_QS6612 0x01814400 /* QS6612 */ +#define PHY_ID_AMD79C784 0x00225610 /* AMD 79C784 */ +#define PHY_ID_AMD79C874VC 0x0022561B /* AMD 79C874 */ +#define PHY_ID_LSI80225 0x0016f870 /* LSI 80225 */ +#define PHY_ID_LSI80225B 0x0016f880 /* LSI 80225/B */ +#define PHY_ID_DP83848VV 0x20005C90 /* National 83848 */ +#define PHY_ID_DP83849 0x20005CA2 /* National 82849 */ + +#define STR_ID_LXT970 "LXT970" +#define STR_ID_LXT971 "LXT971" +#define STR_ID_82555 "Intel82555" +#define STR_ID_QS6612 "QS6612" +#define STR_ID_AMD79C784 "AMD79C784" +#define STR_ID_AMD79C874VC "AMD79C874VC" +#define STR_ID_LSI80225 "LSI80225" +#define STR_ID_LSI80225B "LSI80225/B" +#define STR_ID_DP83848VV "N83848" +#define STR_ID_DP83849 "N83849" + +/**************************************************************************** + * mii_init -- Initialize the MII for MII command without ethernet + * This function is a subset of eth_init + **************************************************************************** + */ +void mii_reset(struct fec_info_s *info) +{ + volatile fec_t *fecp = (fec_t *) (info->miibase); + int i; + + fecp->ecr = FEC_ECR_RESET; + for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i) { + udelay(1); + } + if (i == FEC_RESET_DELAY) { + printf("FEC_RESET_DELAY timeout\n"); + } +} + +/* send command to phy using mii, wait for result */ +uint mii_send(uint mii_cmd) +{ + struct fec_info_s *info; + struct eth_device *dev; + volatile fec_t *ep; + uint mii_reply; + int j = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + ep = (fec_t *) info->miibase; + + ep->mmfr = mii_cmd; /* command to phy */ + + /* wait for mii complete */ + while (!(ep->eir & FEC_EIR_MII) && (j < MCFFEC_TOUT_LOOP)) { + udelay(1); + j++; + } + if (j >= MCFFEC_TOUT_LOOP) { + printf("MII not complete\n"); + return -1; + } + + mii_reply = ep->mmfr; /* result from phy */ + ep->eir = FEC_EIR_MII; /* clear MII complete */ +#ifdef ET_DEBUG + printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n", + __FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply); +#endif + + return (mii_reply & 0xffff); /* data read from phy */ +} +#endif /* CFG_DISCOVER_PHY || (CONFIG_COMMANDS & CONFIG_CMD_MII) */ + +#if defined(CFG_DISCOVER_PHY) +int mii_discover_phy(struct eth_device *dev) +{ +#define MAX_PHY_PASSES 11 + struct fec_info_s *info = dev->priv; + int phyaddr, pass; + uint phyno, phytype; + + if (info->phyname_init) + return info->phy_addr; + + phyaddr = -1; /* didn't find a PHY yet */ + for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) { + if (pass > 1) { + /* PHY may need more time to recover from reset. + * The LXT970 needs 50ms typical, no maximum is + * specified, so wait 10ms before try again. + * With 11 passes this gives it 100ms to wake up. + */ + udelay(10000); /* wait 10ms */ + } + + for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) { + + phytype = mii_send(mk_mii_read(phyno, PHY_PHYIDR1)); +#ifdef ET_DEBUG + printf("PHY type 0x%x pass %d type\n", phytype, pass); +#endif + if (phytype != 0xffff) { + phyaddr = phyno; + phytype <<= 16; + phytype |= + mii_send(mk_mii_read(phyno, PHY_PHYIDR2)); + + switch (phytype & 0xffffffff) { + case PHY_ID_AMD79C874VC: + strcpy(info->phy_name, + STR_ID_AMD79C874VC); + info->phyname_init = 1; + break; + default: + strcpy(info->phy_name, "unknown"); + info->phyname_init = 1; + break; + } + +#ifdef ET_DEBUG + printf("PHY @ 0x%x pass %d type ", phyno, pass); + switch (phytype & 0xffffffff) { + case PHY_ID_AMD79C874VC: + printf(STR_ID_AMD79C874VC); + break; + default: + printf("0x%08x\n", phytype); + break; + } +#endif + } + } + } + if (phyaddr < 0) + printf("No PHY device found.\n"); + + return phyaddr; +} +#endif /* CFG_DISCOVER_PHY */ + +int mii_init(void) __attribute__((weak,alias("__mii_init"))); + +void __mii_init(void) +{ + volatile fec_t *fecp; + struct fec_info_s *info; + struct eth_device *dev; + int miispd = 0, i = 0; + u16 autoneg = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + fecp = (fec_t *) info->miibase; + + fecpin_setclear(dev, 1); + + mii_reset(info); + + /* We use strictly polling mode only */ + fecp->eimr = 0; + + /* Clear any pending interrupt */ + fecp->eir = 0xffffffff; + + /* Set MII speed */ + miispd = (gd->bus_clk / 1000000) / 5; + fecp->mscr = miispd << 1; + + info->phy_addr = mii_discover_phy(dev); + +#define AUTONEGLINK (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS) + while (i < MCFFEC_TOUT_LOOP) { + autoneg = 0; + miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &autoneg); + i++; + + if ((autoneg & AUTONEGLINK) == AUTONEGLINK) + break; + + udelay(500); + } + if (i >= MCFFEC_TOUT_LOOP) { + printf("Auto Negotiation not complete\n"); + } + + /* adapt to the half/full speed settings */ + info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16; + info->dup_spd |= miiphy_speed(dev->name, info->phy_addr); +} + +/***************************************************************************** + * Read and write a MII PHY register, routines used by MII Utilities + * + * FIXME: These routines are expected to return 0 on success, but mii_send + * does _not_ return an error code. Maybe 0xFFFF means error, i.e. + * no PHY connected... + * For now always return 0. + * FIXME: These routines only work after calling eth_init() at least once! + * Otherwise they hang in mii_send() !!! Sorry! + *****************************************************************************/ + +int mcffec_miiphy_read(char *devname, unsigned char addr, unsigned char reg, + unsigned short *value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_read(0x%x) @ 0x%x = ", reg, addr); +#endif + rdreg = mii_send(mk_mii_read(addr, reg)); + + *value = rdreg; + +#ifdef MII_DEBUG + printf("0x%04x\n", *value); +#endif + + return 0; +} + +int mcffec_miiphy_write(char *devname, unsigned char addr, unsigned char reg, + unsigned short value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_write(0x%x) @ 0x%x = ", reg, addr); +#endif + + rdreg = mii_send(mk_mii_write(addr, reg, value)); + +#ifdef MII_DEBUG + printf("0x%04x\n", value); +#endif + + return 0; +} + +#endif /* CONFIG_CMD_NET, FEC_ENET & NET_MULTI */ diff --git a/board/motionpro/motionpro.c b/board/motionpro/motionpro.c index 6eb5fe9..f83998e 100644 --- a/board/motionpro/motionpro.c +++ b/board/motionpro/motionpro.c @@ -29,9 +29,7 @@ #include <common.h> #include <mpc5xxx.h> #include <miiphy.h> -#if defined(CONFIG_OF_FLAT_TREE) -#include <ft_build.h> -#endif +#include <libfdt.h> #if defined(CONFIG_STATUS_LED) #include <status_led.h> @@ -196,12 +194,12 @@ int checkboard(void) } -#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) void ft_board_setup(void *blob, bd_t *bd) { ft_cpu_setup(blob, bd); } -#endif /* defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) */ +#endif /* defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) */ #if defined(CONFIG_STATUS_LED) diff --git a/board/netstal/common/flash.c b/board/netstal/common/hcu_flash.c index be2cb37..be2cb37 100644 --- a/board/netstal/common/flash.c +++ b/board/netstal/common/hcu_flash.c diff --git a/board/netstal/hcu4/Makefile b/board/netstal/hcu4/Makefile index d9825a5..af90821 100644 --- a/board/netstal/hcu4/Makefile +++ b/board/netstal/hcu4/Makefile @@ -22,16 +22,20 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -vpath flash.c ../common -COBJS = $(BOARD).o flash.o +vpath hcu_flash.c ../common + +# NOBJS : Netstal common objects +NOBJS = hcu_flash.o +COBJS = $(BOARD).o SOBJS = -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) ../common/$(NOBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) +NOBJS := $(addprefix $(obj),$(NOBJS)) SOBJS := $(addprefix $(obj),$(SOBJS)) -$(LIB): $(OBJS) $(SOBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) +$(LIB): $(OBJS) $(SOBJS) $(NOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) $(NOBJS) clean: rm -f $(SOBJS) $(OBJS) diff --git a/board/netstal/hcu4/hcu4.c b/board/netstal/hcu4/hcu4.c index 2b95604..48a3f13 100644 --- a/board/netstal/hcu4/hcu4.c +++ b/board/netstal/hcu4/hcu4.c @@ -43,7 +43,7 @@ enum { HW_GENERATION_MCU25 = 0x09, }; -void sysLedSet(u32 value); +void hcu_led_set(u32 value); long int spd_sdram(int(read_spd)(uint addr)); #ifdef CONFIG_SPD_EEPROM @@ -121,22 +121,24 @@ int checkboard (void) printf ("HCU3: index %d\n\n", index); else if (generation == HW_GENERATION_HCU4) printf ("HCU4: index %d\n\n", index); - /* GPIO here noch nicht richtig initialisert !!! */ - sysLedSet(0); + hcu_led_set(0); for (j = 0; j < 7; j++) { - sysLedSet(1 << j); + hcu_led_set(1 << j); udelay(50 * 1000); } return 0; } -u32 sysLedGet(void) +u32 hcu_led_get(void) { return (~((*(u32 *)GPIO0_OR)) >> 23) & 0xff; } -void sysLedSet(u32 value /* value to place in LEDs */) +/*---------------------------------------------------------------------------+ + * hcu_led_set value to be placed into the LEDs (max 6 bit) + *---------------------------------------------------------------------------*/ +void hcu_led_set(u32 value) { u32 tmp = ~value; u32 *ledReg; @@ -243,9 +245,9 @@ long int fixed_hcu4_sdram (int board_type) } /*---------------------------------------------------------------------------+ - * getSerialNr + * hcu_serial_number *---------------------------------------------------------------------------*/ -static u32 getSerialNr(void) +static u32 hcu_serial_number(void) { u32 *serial = (u32 *)CFG_FLASH_BASE; @@ -265,7 +267,7 @@ int misc_init_r(void) char *s = getenv("ethaddr"); char *e; int i; - u32 serial = getSerialNr(); + u32 serial = hcu_serial_number(); for (i = 0; i < 6; ++i) { gd->bd->bi_enetaddr[i] = s ? simple_strtoul (s, &e, 16) : 0; diff --git a/board/netstal/hcu5/Makefile b/board/netstal/hcu5/Makefile index eee310b..27398b9 100644 --- a/board/netstal/hcu5/Makefile +++ b/board/netstal/hcu5/Makefile @@ -22,16 +22,20 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -vpath flash.c ../common -COBJS = $(BOARD).o sdram.o flash.o +vpath hcu_flash.c ../common + +# NOBJS : Netstal common objects +NOBJS = hcu_flash.o +COBJS = $(BOARD).o sdram.o SOBJS = init.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) ../common/$(NOBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) +NOBJS := $(addprefix $(obj),$(NOBJS)) SOBJS := $(addprefix $(obj),$(SOBJS)) -$(LIB): $(OBJS) $(SOBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) +$(LIB): $(OBJS) $(SOBJS) $(NOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) $(NOBJS) clean: rm -f $(SOBJS) $(OBJS) diff --git a/board/netstal/hcu5/hcu5.c b/board/netstal/hcu5/hcu5.c index 23df081..b9b10fd 100644 --- a/board/netstal/hcu5/hcu5.c +++ b/board/netstal/hcu5/hcu5.c @@ -22,10 +22,11 @@ #include <asm/processor.h> #include <ppc440.h> #include <asm/mmu.h> +#include <net.h> DECLARE_GLOBAL_DATA_PTR; -void sysLedSet(u32 value); +void hcu_led_set(u32 value); extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; @@ -41,7 +42,8 @@ extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; #define SDR0_ECID2 0x0082 #define SDR0_ECID3 0x0083 -#define SYS_IO_ADDRESS 0xcce00000 +#define SYS_IO_ADDRESS (CFG_CS_2 + 0x00e00000) +#define SYS_SLOT_ADDRESS (CFG_CPLD + 0x00400000) #define DEFAULT_ETH_ADDR "ethaddr" /* ethaddr for first or etha1ddr for second ethernet */ @@ -182,11 +184,14 @@ int board_early_init_f(void) return 0; } +#ifdef CONFIG_BOARD_PRE_INIT int board_pre_init(void) { return board_early_init_f(); } +#endif + int checkboard(void) { unsigned int j; @@ -211,38 +216,51 @@ int checkboard(void) printf("Chip ID 0x%x 0x%x 0x%x 0x%x\n", ecid0, ecid1, ecid2, ecid3); for (j = 0;j < 6; j++) { - sysLedSet(1 << j); + hcu_led_set(1 << j); udelay(200 * 1000); } return 0; } -u32 sysLedGet(void) +u32 hcu_led_get(void) { return in16(SYS_IO_ADDRESS) & 0x3f; } -void sysLedSet(u32 value /* value to place in LEDs */) +/*---------------------------------------------------------------------------+ + * hcu_led_set value to be placed into the LEDs (max 6 bit) + *---------------------------------------------------------------------------*/ +void hcu_led_set(u32 value) { out16(SYS_IO_ADDRESS, value); } /*---------------------------------------------------------------------------+ - * getSerialNr + * get_serial_number *---------------------------------------------------------------------------*/ -static u32 getSerialNr(void) +static u32 get_serial_number(void) { u32 *serial = (u32 *)CFG_FLASH_BASE; if (*serial == 0xffffffff) - return get_ticks(); + return 0; return *serial; } /*---------------------------------------------------------------------------+ + * hcu_get_slot + *---------------------------------------------------------------------------*/ +u32 hcu_get_slot(void) +{ + u16 *slot = (u16 *)SYS_SLOT_ADDRESS; + return (*slot) & 0x7f; +} + + +/*---------------------------------------------------------------------------+ * misc_init_r. *---------------------------------------------------------------------------*/ int misc_init_r(void) @@ -250,7 +268,7 @@ int misc_init_r(void) char *s = getenv(DEFAULT_ETH_ADDR); char *e; int i; - u32 serial = getSerialNr(); + u32 serial = get_serial_number(); unsigned long usb2d0cr = 0; unsigned long usb2phy0cr, usb2h0cr = 0; unsigned long sdr0_pfc1; @@ -272,8 +290,7 @@ int misc_init_r(void) gd->bd->bi_enetaddr[2] = 0x13; gd->bd->bi_enetaddr[3] = (serial >> 16) & 0xff; gd->bd->bi_enetaddr[4] = (serial >> 8) & 0xff; - /* byte[5].bit 0 must be zero */ - gd->bd->bi_enetaddr[5] = (serial >> 0) & 0xfe; + gd->bd->bi_enetaddr[5] = hcu_get_slot(); sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X\0", gd->bd->bi_enetaddr[0], gd->bd->bi_enetaddr[1], gd->bd->bi_enetaddr[2], gd->bd->bi_enetaddr[3], @@ -283,6 +300,25 @@ int misc_init_r(void) setenv(DEFAULT_ETH_ADDR, ethaddr); } + /* IP-Adress update */ + { + IPaddr_t ipaddr; + char *ipstring; + + ipstring = getenv("ipaddr"); + if (ipstring == 0) + ipaddr = string_to_ip("172.25.1.99"); + else + ipaddr = string_to_ip(ipstring); + if ((ipaddr & 0xff) != (32 + hcu_get_slot())) { + char tmp[22]; + + ipaddr = (ipaddr & 0xffffff00) + 32 + hcu_get_slot(); + ip_to_string (ipaddr, tmp); + printf("%s: enforce %s\n", __FUNCTION__, tmp); + setenv("ipaddr", tmp); + } + } #ifdef CFG_ENV_IS_IN_FLASH /* Monitor protection ON by default */ (void)flash_protect(FLAG_PROTECT_SET, @@ -346,6 +382,7 @@ int misc_init_r(void) return 0; } +#if defined(CONFIG_PCI) /************************************************************************* * pci_pre_init * @@ -358,7 +395,6 @@ int misc_init_r(void) * certain pre-initialization actions. * ************************************************************************/ -#if defined(CONFIG_PCI) int pci_pre_init(struct pci_controller *hose) { unsigned long addr; @@ -411,7 +447,6 @@ int pci_pre_init(struct pci_controller *hose) return 1; } -#endif /* defined(CONFIG_PCI) */ /************************************************************************* * pci_target_init @@ -421,7 +456,6 @@ int pci_pre_init(struct pci_controller *hose) * may not be sufficient for a given board. * ************************************************************************/ -#if defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) void pci_target_init(struct pci_controller *hose) { /*-------------------------------------------------------------+ @@ -478,13 +512,11 @@ void pci_target_init(struct pci_controller *hose) pci_write_config_dword(0, PCI_BRDGOPT2, 0x00000101); } -#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) */ /************************************************************************* * pci_master_init * ************************************************************************/ -#if defined(CONFIG_PCI) && defined(CFG_PCI_MASTER_INIT) void pci_master_init(struct pci_controller *hose) { unsigned short temp_short; @@ -499,8 +531,6 @@ void pci_master_init(struct pci_controller *hose) temp_short | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); } -#endif -/* defined(CONFIG_PCI) && defined(CFG_PCI_MASTER_INIT) */ /************************************************************************* * is_pci_host @@ -517,9 +547,8 @@ void pci_master_init(struct pci_controller *hose) * * ************************************************************************/ -#if defined(CONFIG_PCI) int is_pci_host(struct pci_controller *hose) { return 1; } -#endif /* defined(CONFIG_PCI) */ +#endif /* defined(CONFIG_PCI) */ diff --git a/board/netstal/hcu5/sdram.c b/board/netstal/hcu5/sdram.c index 4039195..9ee9ab5 100644 --- a/board/netstal/hcu5/sdram.c +++ b/board/netstal/hcu5/sdram.c @@ -36,7 +36,7 @@ #include <asm/mmu.h> #include <ppc440.h> -void sysLedSet(u32 value); +void hcu_led_set(u32 value); void dcbz_area(u32 start_address, u32 num_bytes); void dflush(void); @@ -70,7 +70,6 @@ void dflush(void); void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value); -#ifdef CONFIG_ADD_RAM_INFO void board_add_ram_info(int use_default) { PPC440_SYS_INFO board_cfg; @@ -99,7 +98,6 @@ void board_add_ram_info(int use_default) val = DDR0_03_CASLAT_DECODE(val); printf(", CL%d)", val); } -#endif /*-------------------------------------------------------------------- * wait_for_dlllock. @@ -138,7 +136,7 @@ static int wait_for_dlllock(void) void sdram_panic(const char *reason) { printf("\n%s: reason %s", __FUNCTION__, reason); - sysLedSet(0xff); + hcu_led_set(0xff); while (1) { } /* Never return */ @@ -197,6 +195,13 @@ static void program_ecc(unsigned long start_address, unsigned long num_bytes, mfsdram(DDR0_00, val); mtsdram(DDR0_00, val | DDR0_00_INT_ACK_ALL); + /* + * Clear possible errors + * If not done, then we could get an interrupt later on when + * exceptions are enabled. + */ + mtspr(mcsr, mfspr(mcsr)); + /* Set 'int_mask' parameter to functionnal value */ mfsdram(DDR0_01, val); mtsdram(DDR0_01, ((val &~ DDR0_01_INT_MASK_MASK) | @@ -244,7 +249,6 @@ long int initdram (int board_type) sdram_panic(INVALID_HW_CONFIG); break; } - dram_size -= 16 * 1024 * 1024; mtsdram(DDR0_07, 0x00090100); /* * TCPD=200 cycles of clock input is required to lock the DLL. @@ -283,6 +287,7 @@ long int initdram (int board_type) /* * Program tlb entries for this size (dynamic) */ + remove_tlb(CFG_SDRAM_BASE, 256 << 20); program_tlb(0, 0, dram_size, MY_TLB_WORD2_I_ENABLE); /* @@ -291,6 +296,8 @@ long int initdram (int board_type) */ program_tlb(0, CFG_DDR_CACHED_ADDR, dram_size, 0); + /* Diminish RAM to initialize */ + dram_size = dram_size - 32 ; #ifdef CONFIG_DDR_ECC /* * If ECC is enabled, initialize the parity bits. diff --git a/board/omap2420h4/flash.c b/board/omap2420h4/flash.c deleted file mode 100644 index d5e106a..0000000 --- a/board/omap2420h4/flash.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * (C) Copyright 2001 - * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net - * - * (C) Copyright 2001-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * (C) Copyright 2003 - * Texas Instruments, <www.ti.com> - * Kshitij Gupta <Kshitij@ti.com> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <asm/arch/sizes.h> -#include <linux/byteorder/swab.h> - -#define PHYS_FLASH_SECT_SIZE SZ_128K -flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ - -/* Board support for 1 or 2 flash devices */ -#undef FLASH_PORT_WIDTH32 -#define FLASH_PORT_WIDTH16 - -#ifdef FLASH_PORT_WIDTH16 -# define FLASH_PORT_WIDTH ushort -# define FLASH_PORT_WIDTHV vu_short -# define SWAP(x) __swab16(x) -#else -# define FLASH_PORT_WIDTH ulong -# define FLASH_PORT_WIDTHV vu_long -# define SWAP(x) __swab32(x) -#endif - -#define FPW FLASH_PORT_WIDTH -#define FPWV FLASH_PORT_WIDTHV - -#define mb() __asm__ __volatile__ ("" : : : "memory") - - -/* Flash Organization Structure */ -typedef struct OrgDef { - unsigned int sector_number; - unsigned int sector_size; -} OrgDef; - - -/* Flash Organizations */ -OrgDef OrgIntel_28F256L18T[] = { - {4, SZ_32K}, /* 4 * 32kBytes sectors */ - {255, SZ_128K}, /* 255 * 128kBytes sectors */ -}; - - -/*----------------------------------------------------------------------- - * Functions - */ -unsigned long flash_init (void); -static ulong flash_get_size (FPW * addr, flash_info_t * info); -static int write_data (flash_info_t * info, ulong dest, FPW data); -static void flash_get_offsets (ulong base, flash_info_t * info); -void inline spin_wheel (void); -void flash_print_info (flash_info_t * info); -void flash_unprotect_sectors (FPWV * addr); -int flash_erase (flash_info_t * info, int s_first, int s_last); -int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt); -void flash_unlock(flash_info_t * info, int bank); -int flash_probe(void); - -/*----------------------------------------------------------------------- - */ - -/* see if flash is ok */ -int flash_probe(void) -{ - return(flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[0])); -} - -unsigned long flash_init (void) -{ - int i; - ulong size = 0; - for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { - switch (i) { - case 0: - flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]); - flash_get_offsets (PHYS_FLASH_1, &flash_info[i]); - /* to reset the lock bit */ - flash_unlock(&flash_info[i],i); - break; - case 1: - flash_get_size ((FPW *) PHYS_FLASH_2, &flash_info[i]); - flash_get_offsets (PHYS_FLASH_2, &flash_info[i]); - /* to reset the lock bit */ - flash_unlock(&flash_info[i],i); - break; - - default: - panic ("configured too many flash banks!\n"); - break; - } - size += flash_info[i].size; - } - -#ifdef CFG_ENV_IS_IN_FLASH - /* Protect monitor and environment sectors - */ - flash_protect (FLAG_PROTECT_SET, - CFG_FLASH_BASE, - CFG_FLASH_BASE + monitor_flash_len - 1, &flash_info[0]); - - flash_protect (FLAG_PROTECT_SET, - CFG_ENV_ADDR, - CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]); -#endif - return size; -} - -/*----------------------------------------------------------------------- - */ -void flash_unlock(flash_info_t * info, int bank) -{ - int j; - if (!bank) - j=2; /* leave 0,1 locked for boot bank */ - else - j=0; /* get the whole bank for #2 */ - - for (;j<CFG_MAX_FLASH_SECT;j++) { - FPWV *addr = (FPWV *) (info->start[j]); - if (addr == NULL) { - printf("Warning Flash probe failed\n"); - break; - } - flash_unprotect_sectors (addr); - *addr = (FPW) 0x00500050;/* clear status register */ - *addr = (FPW) 0x00FF00FF;/* resest to read mode */ - } -} - -/*----------------------------------------------------------------------- - */ -static void flash_get_offsets (ulong base, flash_info_t * info) -{ - int i; - volatile int r; /* gcc 3.4.0-1 strangeness, need to follow up.*/ - - if (info->flash_id == FLASH_UNKNOWN) { - return; - } - - if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { - for (i = 0; i < info->sector_count; i++) { - if (i > 254) { /* 255,256,257,258 */ - r=i; - info->start[i] = base + (((r-(int)255) * SZ_32K) + (255*PHYS_FLASH_SECT_SIZE)); - info->protect[i] = 0; - } else { - info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE); - info->protect[i] = 0; - } - } - } -} - -/*----------------------------------------------------------------------- - */ -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; - default: - printf ("Unknown Vendor "); - break; - } - - switch (info->flash_id & FLASH_TYPEMASK) { - case FLASH_28F256L18T: - printf ("FLASH 28F256L18T\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"); - return; -} - -/* - * The following code cannot be run from FLASH! - */ -static ulong flash_get_size (FPW * addr, flash_info_t * info) -{ - volatile FPW value; - /* mb(); this one makes ARM11 err go away, but I want it :) as a guide to problems */ - - /* Write auto select command: read Manufacturer ID */ - addr[0x5555] = (FPW) 0x00AA00AA; - addr[0x2AAA] = (FPW) 0x00550055; - addr[0x5555] = (FPW) 0x00900090; - - mb (); - value = addr[0] & 0xFF; /* just looking for 89 (8989 is hw pat)*/ - - switch (value) { - - case (FPW) INTEL_MANUFACT: - info->flash_id = FLASH_MAN_INTEL; - break; - - default: - info->flash_id = FLASH_UNKNOWN; - info->sector_count = 0; - info->size = 0; - addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ - return(0); /* no or unknown flash */ - } - - mb (); - value = addr[1]; /* device ID */ - switch (value) { - - case (FPW) (INTEL_ID_28F256L18T): /* 880D */ - info->flash_id += FLASH_28F256L18T; - info->sector_count = 259; /*0-258*/ - info->size = SZ_32M; - break; /* => 32 MB */ - - default: - info->flash_id = FLASH_UNKNOWN; - break; - } - - if (info->sector_count > CFG_MAX_FLASH_SECT) { - printf ("** ERROR: sector count %d > max (%d) **\n", - info->sector_count, CFG_MAX_FLASH_SECT); - info->sector_count = CFG_MAX_FLASH_SECT; - } - - addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ - - return(info->size); -} - - -/* unprotects a sector for write and erase - * on some intel parts, this unprotects the entire chip, but it - * wont hurt to call this additional times per sector... - */ -void flash_unprotect_sectors (FPWV * addr) -{ -#define PD_FINTEL_WSMS_READY_MASK 0x0080 - - *addr = (FPW) 0x00500050; /* clear status register */ - - /* this sends the clear lock bit command */ - *addr = (FPW) 0x00600060; - *addr = (FPW) 0x00D000D0; -} - - -/*----------------------------------------------------------------------- - */ - -int flash_erase (flash_info_t * info, int s_first, int s_last) -{ - int prot, sect; - ulong type, start, last; - int rcode = 0; -#ifdef CONFIG_USE_IRQ - int iflag; -#endif - - 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; - } - - type = (info->flash_id & FLASH_VENDMASK); - if ((type != FLASH_MAN_INTEL)) { - 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 = get_timer (0); - last = start; - -#ifdef CONFIG_USE_IRQ - /* Disable interrupts which might cause a timeout here */ - iflag = disable_interrupts (); -#endif - - /* Start erase on unprotected sectors */ - for (sect = s_first; sect <= s_last; sect++) { - if (info->protect[sect] == 0) { /* not protected */ - FPWV *addr = (FPWV *) (info->start[sect]); - FPW status; - - printf ("Erasing sector %2d ... ", sect); - - flash_unprotect_sectors (addr); - - /* arm simple, non interrupt dependent timer */ - reset_timer_masked (); - - *addr = (FPW) 0x00500050;/* clear status register */ - *addr = (FPW) 0x00200020;/* erase setup */ - *addr = (FPW) 0x00D000D0;/* erase confirm */ - - while (((status = - *addr) & (FPW) 0x00800080) != - (FPW) 0x00800080) { - if (get_timer_masked () > - CFG_FLASH_ERASE_TOUT) { - printf ("Timeout\n"); - /* suspend erase */ - *addr = (FPW) 0x00B000B0; - /* reset to read mode */ - *addr = (FPW) 0x00FF00FF; - rcode = 1; - break; - } - } - - /* clear status register cmd. */ - *addr = (FPW) 0x00500050; - *addr = (FPW) 0x00FF00FF;/* resest to read mode */ - printf (" done\n"); - } - } -#ifdef CONFIG_USE_IRQ - if (iflag) - enable_interrupts(); -#endif - - return rcode; -} - -/*----------------------------------------------------------------------- - * Copy memory to flash, returns: - * 0 - OK - * 1 - write timeout - * 2 - Flash not erased - * 4 - Flash not identified - */ - -int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) -{ - ulong cp, wp; - FPW data; - int count, i, l, rc, port_width; - - if (info->flash_id == FLASH_UNKNOWN) { - return 4; - } -/* get lower word aligned address */ -#ifdef FLASH_PORT_WIDTH16 - wp = (addr & ~1); - port_width = 2; -#else - wp = (addr & ~3); - port_width = 4; -#endif - - /* - * 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 < port_width && cnt > 0; ++i) { - data = (data << 8) | *src++; - --cnt; - ++cp; - } - for (; cnt == 0 && i < port_width; ++i, ++cp) { - data = (data << 8) | (*(uchar *) cp); - } - - if ((rc = write_data (info, wp, SWAP (data))) != 0) { - return(rc); - } - wp += port_width; - } - - /* - * handle word aligned part - */ - count = 0; - while (cnt >= port_width) { - data = 0; - for (i = 0; i < port_width; ++i) { - data = (data << 8) | *src++; - } - if ((rc = write_data (info, wp, SWAP (data))) != 0) { - return(rc); - } - wp += port_width; - cnt -= port_width; - if (count++ > 0x800) { - spin_wheel (); - count = 0; - } - } - - if (cnt == 0) { - return(0); - } - - /* - * handle unaligned tail bytes - */ - data = 0; - for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) { - data = (data << 8) | *src++; - --cnt; - } - for (; i < port_width; ++i, ++cp) { - data = (data << 8) | (*(uchar *) cp); - } - - return(write_data (info, wp, SWAP (data))); -} - -/*----------------------------------------------------------------------- - * Write a word or halfword to Flash, returns: - * 0 - OK - * 1 - write timeout - * 2 - Flash not erased - */ -static int write_data (flash_info_t * info, ulong dest, FPW data) -{ - FPWV *addr = (FPWV *) dest; - ulong status; -#ifdef CONFIG_USE_IRQ - int iflag; -#endif - - /* Check if Flash is (sufficiently) erased */ - if ((*addr & data) != data) { - printf ("not erased at %08lx (%x)\n", (ulong) addr, *addr); - return(2); - } - /* Disable interrupts which might cause a timeout here */ -#ifdef CONFIG_USE_IRQ - iflag = disable_interrupts (); -#endif - *addr = (FPW) 0x00400040; /* write setup */ - *addr = data; - - /* arm simple, non interrupt dependent timer */ - reset_timer_masked (); - - /* wait while polling the status register */ - while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) { - if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) { - *addr = (FPW) 0x00FF00FF; /* restore read mode */ - return(1); - } - } - *addr = (FPW) 0x00FF00FF; /* restore read mode */ - -#ifdef CONFIG_USE_IRQ - if (iflag) - enable_interrupts(); -#endif - - return(0); -} - -void inline spin_wheel (void) -{ - static int p = 0; - static char w[] = "\\/-"; - - printf ("\010%c", w[p]); - (++p == 3) ? (p = 0) : 0; -} diff --git a/board/pcs440ep/pcs440ep.c b/board/pcs440ep/pcs440ep.c index e247fee..90e99d3 100644 --- a/board/pcs440ep/pcs440ep.c +++ b/board/pcs440ep/pcs440ep.c @@ -30,6 +30,7 @@ #include <spd_sdram.h> #include <status_led.h> #include <sha1.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; @@ -867,6 +868,29 @@ U_BOOT_CMD( ); #endif +#if defined (CONFIG_CMD_IDE) +/* These addresses need to be shifted one place to the left + * ( bus per_addr 20 -30 is connectsd on CF bus A10-A0) + * These values are shifted + */ +extern ulong *ide_bus_offset; +void inline ide_outb(int dev, int port, unsigned char val) +{ + debug ("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n", + dev, port, val, (ATA_CURR_BASE(dev)+port)); + + out_be16((u16 *)(ATA_CURR_BASE(dev)+(port << 1)), val); +} +unsigned char inline ide_inb(int dev, int port) +{ + uchar val; + val = in_be16((u16 *)(ATA_CURR_BASE(dev)+(port << 1))); + debug ("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n", + dev, port, (ATA_CURR_BASE(dev)+port), val); + return (val); +} +#endif + #ifdef CONFIG_IDE_PREINIT int ide_preinit (void) { diff --git a/board/r5200/Makefile b/board/r5200/Makefile index 424ab1c..2ec71ee 100644 --- a/board/r5200/Makefile +++ b/board/r5200/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -COBJS = $(BOARD).o +COBJS = $(BOARD).o mii.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/r5200/mii.c b/board/r5200/mii.c new file mode 100644 index 0000000..706c90f --- /dev/null +++ b/board/r5200/mii.c @@ -0,0 +1,303 @@ +/* + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/fec.h> +#include <asm/immap.h> + +#include <config.h> +#include <net.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) +#undef MII_DEBUG +#undef ET_DEBUG + +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + if (setclear) { + /* Enable Ethernet pins */ + mbar_writeByte(MCF_GPIO_PAR_FECI2C, CFG_FECI2C); + } else { + } + + return 0; +} + +#if defined(CFG_DISCOVER_PHY) || defined(CONFIG_CMD_MII) +#include <miiphy.h> + +/* Make MII read/write commands for the FEC. */ +#define mk_mii_read(ADDR, REG) (0x60020000 | ((ADDR << 23) | (REG & 0x1f) << 18)) + +#define mk_mii_write(ADDR, REG, VAL) (0x50020000 | ((ADDR << 23) | (REG & 0x1f) << 18) | (VAL & 0xffff)) + +/* PHY identification */ +#define PHY_ID_LXT970 0x78100000 /* LXT970 */ +#define PHY_ID_LXT971 0x001378e0 /* LXT971 and 972 */ +#define PHY_ID_82555 0x02a80150 /* Intel 82555 */ +#define PHY_ID_QS6612 0x01814400 /* QS6612 */ +#define PHY_ID_AMD79C784 0x00225610 /* AMD 79C784 */ +#define PHY_ID_LSI80225 0x0016f870 /* LSI 80225 */ +#define PHY_ID_LSI80225B 0x0016f880 /* LSI 80225/B */ +#define PHY_ID_DP83848VV 0x20005C90 /* National 83848 */ +#define PHY_ID_DP83849 0x20005CA2 /* National 82849 */ +#define PHY_ID_KS8721BL 0x00221619 /* Micrel KS8721BL/SL */ + +#define STR_ID_LXT970 "LXT970" +#define STR_ID_LXT971 "LXT971" +#define STR_ID_82555 "Intel82555" +#define STR_ID_QS6612 "QS6612" +#define STR_ID_AMD79C784 "AMD79C784" +#define STR_ID_LSI80225 "LSI80225" +#define STR_ID_LSI80225B "LSI80225/B" +#define STR_ID_DP83848VV "N83848" +#define STR_ID_DP83849 "N83849" +#define STR_ID_KS8721BL "KS8721BL" + +/**************************************************************************** + * mii_init -- Initialize the MII for MII command without ethernet + * This function is a subset of eth_init + **************************************************************************** + */ +void mii_reset(struct fec_info_s *info) +{ + volatile fec_t *fecp = (fec_t *) (info->miibase); + int i; + + fecp->ecr = FEC_ECR_RESET; + for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i) { + udelay(1); + } + if (i == FEC_RESET_DELAY) { + printf("FEC_RESET_DELAY timeout\n"); + } +} + +/* send command to phy using mii, wait for result */ +uint mii_send(uint mii_cmd) +{ + struct fec_info_s *info; + struct eth_device *dev; + volatile fec_t *ep; + uint mii_reply; + int j = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + ep = (fec_t *) info->miibase; + + ep->mmfr = mii_cmd; /* command to phy */ + + /* wait for mii complete */ + while (!(ep->eir & FEC_EIR_MII) && (j < MCFFEC_TOUT_LOOP)) { + udelay(1); + j++; + } + if (j >= MCFFEC_TOUT_LOOP) { + printf("MII not complete\n"); + return -1; + } + + mii_reply = ep->mmfr; /* result from phy */ + ep->eir = FEC_EIR_MII; /* clear MII complete */ +#ifdef ET_DEBUG + printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n", + __FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply); +#endif + + return (mii_reply & 0xffff); /* data read from phy */ +} +#endif /* CFG_DISCOVER_PHY || (CONFIG_CMD_MII) */ + +#if defined(CFG_DISCOVER_PHY) +int mii_discover_phy(struct eth_device *dev) +{ +#define MAX_PHY_PASSES 11 + struct fec_info_s *info = dev->priv; + int phyaddr, pass; + uint phyno, phytype; + + if (info->phyname_init) + return info->phy_addr; + + phyaddr = -1; /* didn't find a PHY yet */ + for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) { + if (pass > 1) { + /* PHY may need more time to recover from reset. + * The LXT970 needs 50ms typical, no maximum is + * specified, so wait 10ms before try again. + * With 11 passes this gives it 100ms to wake up. + */ + udelay(10000); /* wait 10ms */ + } + + for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) { + + phytype = mii_send(mk_mii_read(phyno, PHY_PHYIDR1)); +#ifdef ET_DEBUG + printf("PHY type 0x%x pass %d type\n", phytype, pass); +#endif + if (phytype != 0xffff) { + phyaddr = phyno; + phytype <<= 16; + phytype |= + mii_send(mk_mii_read(phyno, PHY_PHYIDR2)); + + switch (phytype & 0xffffffff) { + case PHY_ID_KS8721BL: + strcpy(info->phy_name, + STR_ID_KS8721BL); + info->phyname_init = 1; + break; + default: + strcpy(info->phy_name, "unknown"); + info->phyname_init = 1; + break; + } + +#ifdef ET_DEBUG + printf("PHY @ 0x%x pass %d type ", phyno, pass); + switch (phytype & 0xffffffff) { + case PHY_ID_KS8721BL: + printf(STR_ID_KS8721BL); + break; + default: + printf("0x%08x\n", phytype); + break; + } +#endif + } + } + } + if (phyaddr < 0) + printf("No PHY device found.\n"); + + return phyaddr; +} +#endif /* CFG_DISCOVER_PHY */ + +int mii_init(void) __attribute__((weak,alias("__mii_init"))); + +void __mii_init(void) +{ + volatile fec_t *fecp; + struct fec_info_s *info; + struct eth_device *dev; + int miispd = 0, i = 0; + u16 autoneg = 0; + + /* retrieve from register structure */ + dev = eth_get_dev(); + info = dev->priv; + + fecp = (fec_t *) info->miibase; + + fecpin_setclear(dev, 1); + + mii_reset(info); + + /* We use strictly polling mode only */ + fecp->eimr = 0; + + /* Clear any pending interrupt */ + fecp->eir = 0xffffffff; + + /* Set MII speed */ + miispd = (gd->bus_clk / 1000000) / 5; + fecp->mscr = miispd << 1; + + info->phy_addr = mii_discover_phy(dev); + +#define AUTONEGLINK (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS) + while (i < MCFFEC_TOUT_LOOP) { + autoneg = 0; + miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &autoneg); + i++; + + if ((autoneg & AUTONEGLINK) == AUTONEGLINK) + break; + + udelay(500); + } + if (i >= MCFFEC_TOUT_LOOP) { + printf("Auto Negotiation not complete\n"); + } + + /* adapt to the half/full speed settings */ + info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16; + info->dup_spd |= miiphy_speed(dev->name, info->phy_addr); +} + +/***************************************************************************** + * Read and write a MII PHY register, routines used by MII Utilities + * + * FIXME: These routines are expected to return 0 on success, but mii_send + * does _not_ return an error code. Maybe 0xFFFF means error, i.e. + * no PHY connected... + * For now always return 0. + * FIXME: These routines only work after calling eth_init() at least once! + * Otherwise they hang in mii_send() !!! Sorry! + *****************************************************************************/ + +int mcffec_miiphy_read(char *devname, unsigned char addr, unsigned char reg, + unsigned short *value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_read(0x%x) @ 0x%x = ", reg, addr); +#endif + rdreg = mii_send(mk_mii_read(addr, reg)); + + *value = rdreg; + +#ifdef MII_DEBUG + printf("0x%04x\n", *value); +#endif + + return 0; +} + +int mcffec_miiphy_write(char *devname, unsigned char addr, unsigned char reg, + unsigned short value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf("miiphy_write(0x%x) @ 0x%x = ", reg, addr); +#endif + + rdreg = mii_send(mk_mii_write(addr, reg, value)); + +#ifdef MII_DEBUG + printf("0x%04x\n", value); +#endif + + return 0; +} + +#endif /* CONFIG_CMD_NET, FEC_ENET & NET_MULTI */ diff --git a/board/sbc8349/sbc8349.c b/board/sbc8349/sbc8349.c index 4cd447e..86166ea 100644 --- a/board/sbc8349/sbc8349.c +++ b/board/sbc8349/sbc8349.c @@ -64,8 +64,6 @@ long int initdram (int board_type) if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im) return -1; - puts("Initializing\n"); - /* DDR SDRAM - Main SODIMM */ im->sysconf.ddrlaw[0].bar = CFG_DDR_BASE & LAWBAR_BAR; #if defined(CONFIG_SPD_EEPROM) @@ -84,7 +82,6 @@ long int initdram (int board_type) */ ddr_enable_ecc(msize * 1024 * 1024); #endif - puts(" DDR RAM: "); /* return total bus SDRAM size(bytes) -- DDR */ return (msize * 1024 * 1024); } @@ -130,7 +127,7 @@ int fixed_sdram(void) #if defined(CONFIG_DDR_2T_TIMING) | SDRAM_CFG_2T_EN #endif - | 2 << SDRAM_CFG_SDRAM_TYPE_SHIFT; + | SDRAM_CFG_SDRAM_TYPE_DDR1; #if defined (CONFIG_DDR_32BIT) /* for 32-bit mode burst length is 8 */ im->ddr.sdram_cfg |= (SDRAM_CFG_32_BE | SDRAM_CFG_8_BE); diff --git a/board/tqm5200/tqm5200.c b/board/tqm5200/tqm5200.c index 51f4aeb..21f67aa 100644 --- a/board/tqm5200/tqm5200.c +++ b/board/tqm5200/tqm5200.c @@ -31,10 +31,7 @@ #include <mpc5xxx.h> #include <pci.h> #include <asm/processor.h> - -#if defined(CONFIG_OF_FLAT_TREE) -#include <ft_build.h> -#endif +#include <libfdt.h> #ifdef CONFIG_VIDEO_SM501 #include <sm501.h> @@ -780,9 +777,9 @@ int board_get_height (void) #endif /* CONFIG_VIDEO_SM501 */ -#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) void ft_board_setup(void *blob, bd_t *bd) { ft_cpu_setup(blob, bd); } -#endif /* defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) */ +#endif /* defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) */ diff --git a/board/tqm834x/tqm834x.c b/board/tqm834x/tqm834x.c index 9c35e22..7d0b055 100644 --- a/board/tqm834x/tqm834x.c +++ b/board/tqm834x/tqm834x.c @@ -114,7 +114,7 @@ long int initdram (int board_type) /* enable DDR controller */ im->ddr.sdram_cfg = (SDRAM_CFG_MEM_EN | SDRAM_CFG_SREN | - SDRAM_CFG_SDRAM_TYPE_DDR); + SDRAM_CFG_SDRAM_TYPE_DDR1); SYNC; /* size detection */ @@ -388,7 +388,7 @@ static void set_ddr_config(void) { /* don't enable DDR controller yet */ im->ddr.sdram_cfg = SDRAM_CFG_SREN | - SDRAM_CFG_SDRAM_TYPE_DDR; + SDRAM_CFG_SDRAM_TYPE_DDR1; SYNC; /* Set SDRAM mode */ diff --git a/board/trizepsiv/Makefile b/board/trizepsiv/Makefile new file mode 100644 index 0000000..115e17d --- /dev/null +++ b/board/trizepsiv/Makefile @@ -0,0 +1,51 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS := conxs.o eeprom.o +SOBJS := lowlevel_init.o pxavoltage.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) + +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/trizepsiv/config.mk b/board/trizepsiv/config.mk new file mode 100644 index 0000000..4486f6b --- /dev/null +++ b/board/trizepsiv/config.mk @@ -0,0 +1,3 @@ +TEXT_BASE =0xa1f00000 +# 0xa1700000 +#TEXT_BASE = 0 diff --git a/board/trizepsiv/conxs.c b/board/trizepsiv/conxs.c new file mode 100644 index 0000000..7c6c855 --- /dev/null +++ b/board/trizepsiv/conxs.c @@ -0,0 +1,146 @@ +/* + * (C) Copyright 2007 + * Stefano Babic, DENX Gmbh, sbabic@denx.de + * + * (C) Copyright 2004 + * Robert Whaley, Applied Data Systems, Inc. rwhaley@applieddata.net + * + * (C) Copyright 2002 + * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/arch/pxa-regs.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define RH_A_PSM (1 << 8) /* power switching mode */ +#define RH_A_NPS (1 << 9) /* no power switching */ + +extern struct serial_device serial_ffuart_device; +extern struct serial_device serial_btuart_device; +extern struct serial_device serial_stuart_device; + +/* ------------------------------------------------------------------------- */ + +/* + * Miscelaneous platform dependent initialisations + */ + +void usb_board_init(void) +{ + UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) & + ~(UHCHR_SSEP0 | UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE); + + UHCHR |= UHCHR_FSBIR; + + while (UHCHR & UHCHR_FSBIR); + + UHCHR &= ~UHCHR_SSE; + UHCHIE = (UHCHIE_UPRIE | UHCHIE_RWIE); + + /* Clear any OTG Pin Hold */ + if (PSSR & PSSR_OTGPH) + PSSR |= PSSR_OTGPH; + + UHCRHDA &= ~(RH_A_NPS); + UHCRHDA |= RH_A_PSM; + + /* Set port power control mask bits, only 3 ports. */ + UHCRHDB |= (0x7<<17); +} + +void usb_board_init_fail(void) +{ + return; +} + +void usb_board_stop(void) +{ + UHCHR |= UHCHR_FHR; + udelay(11); + UHCHR &= ~UHCHR_FHR; + + UHCCOMS |= 1; + udelay(10); + + CKEN &= ~CKEN10_USBHOST; + + puts("Called USB STOP\n"); + return; +} + +int board_init (void) +{ + /* memory and cpu-speed are setup before relocation */ + /* so we do _nothing_ here */ + + /* arch number of ConXS Board */ + gd->bd->bi_arch_number = 776; + + /* adress of boot parameters */ + gd->bd->bi_boot_params = 0xa000003c; + + return 0; +} + +int board_late_init(void) +{ +#if defined(CONFIG_SERIAL_MULTI) + char *console=getenv("boot_console"); + + if ((strcmp(console,"serial_btuart") == 0) || + (strcmp(console,"serial_stuart") == 0) || + (strcmp(console,"serial_ffuart") == 0)) { + setenv("stdout",console); + setenv("stdin", console); + setenv("stderr",console); + } else { + setenv("stdout", "serial"); + setenv("stdin", "serial"); + setenv("stderr", "serial"); + } +#endif + return 0; +} + +struct serial_device *default_serial_console (void) +{ + return &serial_ffuart_device; +} + +int dram_init (void) +{ + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + gd->bd->bi_dram[1].start = PHYS_SDRAM_2; + gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; + gd->bd->bi_dram[2].start = PHYS_SDRAM_3; + gd->bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE; + gd->bd->bi_dram[3].start = PHYS_SDRAM_4; + gd->bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE; + + return 0; +} diff --git a/board/trizepsiv/eeprom.c b/board/trizepsiv/eeprom.c new file mode 100644 index 0000000..3d3bc00 --- /dev/null +++ b/board/trizepsiv/eeprom.c @@ -0,0 +1,85 @@ +/* + * (C) Copyright 2007 + * Stefano Babic, DENX Software Engineering, sbabic@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> + +static unsigned char srom[128]; +extern u16 read_srom_word(int); +extern void write_srom_word(int offset, u16 val); + +static int do_read_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { + int i; + + for (i=0; i < 0x40; i++) { + if (!(i % 0x10)) + printf("\n%08lx:", i); + printf(" %04x", read_srom_word(i)); + } + printf ("\n"); + return (0); +} + +static int do_write_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { + int offset,value; + + if (argc < 4) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + offset=simple_strtoul(argv[2],NULL,16); + value=simple_strtoul(argv[3],NULL,16); + if (offset > 0x40) { + printf("Wrong offset : 0x%x\n",offset); + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + write_srom_word(offset, value); + return (0); +} + +int do_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { + if (argc < 2) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + if (strcmp (argv[1],"read") == 0) { + return (do_read_dm9000_eeprom(cmdtp,flag,argc,argv)); + } else if (strcmp (argv[1],"write") == 0) { + return (do_write_dm9000_eeprom(cmdtp,flag,argc,argv)); + } else { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } +} + +U_BOOT_CMD( + dm9000ee,4,1,do_dm9000_eeprom, + "dm9000ee- Read/Write eeprom connected to Ethernet Controller\n", + "\ndm9000ee write <word offset> <value> \n" + "\tdm9000ee read \n" + "\tword:\t\t00-02 : MAC Address\n" + "\t\t\t03-07 : DM9000 Configuration\n" + "\t\t\t08-63 : User data\n"); diff --git a/board/trizepsiv/lowlevel_init.S b/board/trizepsiv/lowlevel_init.S new file mode 100644 index 0000000..d886938 --- /dev/null +++ b/board/trizepsiv/lowlevel_init.S @@ -0,0 +1,503 @@ +/* + * This was originally from the Lubbock u-boot port. + * + * Most of this taken from Redboot hal_platform_setup.h with cleanup + * + * NOTE: I haven't clean this up considerably, just enough to get it + * running. See hal_platform_setup.h for the source. See + * board/cradle/lowlevel_init.S for another PXA250 setup that is + * much cleaner. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <version.h> +#include <asm/arch/pxa-regs.h> + +/* wait for coprocessor write complete */ + .macro CPWAIT reg + mrc p15,0,\reg,c2,c0,0 + mov \reg,\reg + sub pc,pc,#4 + .endm + + +/* + * Memory setup + */ + +.globl lowlevel_init +lowlevel_init: + + /* Set up GPIO pins first ----------------------------------------- */ + + ldr r0, =GPSR0 + ldr r1, =CFG_GPSR0_VAL + str r1, [r0] + + ldr r0, =GPSR1 + ldr r1, =CFG_GPSR1_VAL + str r1, [r0] + + ldr r0, =GPSR2 + ldr r1, =CFG_GPSR2_VAL + str r1, [r0] + + ldr r0, =GPSR3 + ldr r1, =CFG_GPSR3_VAL + str r1, [r0] + + ldr r0, =GPCR0 + ldr r1, =CFG_GPCR0_VAL + str r1, [r0] + + ldr r0, =GPCR1 + ldr r1, =CFG_GPCR1_VAL + str r1, [r0] + + ldr r0, =GPCR2 + ldr r1, =CFG_GPCR2_VAL + str r1, [r0] + + ldr r0, =GPCR3 + ldr r1, =CFG_GPCR3_VAL + str r1, [r0] + + ldr r0, =GRER0 + ldr r1, =CFG_GRER0_VAL + str r1, [r0] + + ldr r0, =GRER1 + ldr r1, =CFG_GRER1_VAL + str r1, [r0] + + ldr r0, =GRER2 + ldr r1, =CFG_GRER2_VAL + str r1, [r0] + + ldr r0, =GRER3 + ldr r1, =CFG_GRER3_VAL + str r1, [r0] + + ldr r0, =GFER0 + ldr r1, =CFG_GFER0_VAL + str r1, [r0] + + ldr r0, =GFER1 + ldr r1, =CFG_GFER1_VAL + str r1, [r0] + + ldr r0, =GFER2 + ldr r1, =CFG_GFER2_VAL + str r1, [r0] + + ldr r0, =GFER3 + ldr r1, =CFG_GFER3_VAL + str r1, [r0] + + ldr r0, =GPDR0 + ldr r1, =CFG_GPDR0_VAL + str r1, [r0] + + ldr r0, =GPDR1 + ldr r1, =CFG_GPDR1_VAL + str r1, [r0] + + ldr r0, =GPDR2 + ldr r1, =CFG_GPDR2_VAL + str r1, [r0] + + ldr r0, =GPDR3 + ldr r1, =CFG_GPDR3_VAL + str r1, [r0] + + ldr r0, =GAFR0_L + ldr r1, =CFG_GAFR0_L_VAL + str r1, [r0] + + ldr r0, =GAFR0_U + ldr r1, =CFG_GAFR0_U_VAL + str r1, [r0] + + ldr r0, =GAFR1_L + ldr r1, =CFG_GAFR1_L_VAL + str r1, [r0] + + ldr r0, =GAFR1_U + ldr r1, =CFG_GAFR1_U_VAL + str r1, [r0] + + ldr r0, =GAFR2_L + ldr r1, =CFG_GAFR2_L_VAL + str r1, [r0] + + ldr r0, =GAFR2_U + ldr r1, =CFG_GAFR2_U_VAL + str r1, [r0] + + ldr r0, =GAFR3_L + ldr r1, =CFG_GAFR3_L_VAL + str r1, [r0] + + ldr r0, =GAFR3_U + ldr r1, =CFG_GAFR3_U_VAL + str r1, [r0] + + ldr r0, =PSSR /* enable GPIO pins */ + ldr r1, =CFG_PSSR_VAL + str r1, [r0] + + /* ---------------------------------------------------------------- */ + /* Enable memory interface */ + /* */ + /* The sequence below is based on the recommended init steps */ + /* detailed in the Intel PXA250 Operating Systems Developers Guide, */ + /* Chapter 10. */ + /* ---------------------------------------------------------------- */ + + /* ---------------------------------------------------------------- */ + /* Step 1: Wait for at least 200 microsedonds to allow internal */ + /* clocks to settle. Only necessary after hard reset... */ + /* FIXME: can be optimized later */ + /* ---------------------------------------------------------------- */ + + ldr r3, =OSCR /* reset the OS Timer Count to zero */ + mov r2, #0 + str r2, [r3] + ldr r4, =0x300 /* really 0x2E1 is about 200usec, */ + /* so 0x300 should be plenty */ +1: + ldr r2, [r3] + cmp r4, r2 + bgt 1b + +mem_init: + + ldr r1, =MEMC_BASE /* get memory controller base addr. */ + + /* ---------------------------------------------------------------- */ + /* Step 2a: Initialize Asynchronous static memory controller */ + /* ---------------------------------------------------------------- */ + + /* MSC registers: timing, bus width, mem type */ + + /* MSC0: nCS(0,1) */ + ldr r2, =CFG_MSC0_VAL + str r2, [r1, #MSC0_OFFSET] + ldr r2, [r1, #MSC0_OFFSET] /* read back to ensure */ + /* that data latches */ + /* MSC1: nCS(2,3) */ + ldr r2, =CFG_MSC1_VAL + str r2, [r1, #MSC1_OFFSET] + ldr r2, [r1, #MSC1_OFFSET] + + /* MSC2: nCS(4,5) */ + ldr r2, =CFG_MSC2_VAL + str r2, [r1, #MSC2_OFFSET] + ldr r2, [r1, #MSC2_OFFSET] + + /* ---------------------------------------------------------------- */ + /* Step 2b: Initialize Card Interface */ + /* ---------------------------------------------------------------- */ + + /* MECR: Memory Expansion Card Register */ + ldr r2, =CFG_MECR_VAL + str r2, [r1, #MECR_OFFSET] + ldr r2, [r1, #MECR_OFFSET] + + /* MCMEM0: Card Interface slot 0 timing */ + ldr r2, =CFG_MCMEM0_VAL + str r2, [r1, #MCMEM0_OFFSET] + ldr r2, [r1, #MCMEM0_OFFSET] + + /* MCMEM1: Card Interface slot 1 timing */ + ldr r2, =CFG_MCMEM1_VAL + str r2, [r1, #MCMEM1_OFFSET] + ldr r2, [r1, #MCMEM1_OFFSET] + + /* MCATT0: Card Interface Attribute Space Timing, slot 0 */ + ldr r2, =CFG_MCATT0_VAL + str r2, [r1, #MCATT0_OFFSET] + ldr r2, [r1, #MCATT0_OFFSET] + + /* MCATT1: Card Interface Attribute Space Timing, slot 1 */ + ldr r2, =CFG_MCATT1_VAL + str r2, [r1, #MCATT1_OFFSET] + ldr r2, [r1, #MCATT1_OFFSET] + + /* MCIO0: Card Interface I/O Space Timing, slot 0 */ + ldr r2, =CFG_MCIO0_VAL + str r2, [r1, #MCIO0_OFFSET] + ldr r2, [r1, #MCIO0_OFFSET] + + /* MCIO1: Card Interface I/O Space Timing, slot 1 */ + ldr r2, =CFG_MCIO1_VAL + str r2, [r1, #MCIO1_OFFSET] + ldr r2, [r1, #MCIO1_OFFSET] + + /* ---------------------------------------------------------------- */ + /* Step 2c: Write FLYCNFG FIXME: what's that??? */ + /* ---------------------------------------------------------------- */ + ldr r2, =CFG_FLYCNFG_VAL + str r2, [r1, #FLYCNFG_OFFSET] + str r2, [r1, #FLYCNFG_OFFSET] + + /* ---------------------------------------------------------------- */ + /* Step 2d: Initialize Timing for Sync Memory (SDCLK0) */ + /* ---------------------------------------------------------------- */ + + /* Before accessing MDREFR we need a valid DRI field, so we set */ + /* this to power on defaults + DRI field. */ + + ldr r4, [r1, #MDREFR_OFFSET] + ldr r2, =0xFFF + bic r4, r4, r2 + + ldr r3, =CFG_MDREFR_VAL + and r3, r3, r2 + + orr r4, r4, r3 + str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */ + + orr r4, r4, #MDREFR_K0RUN + orr r4, r4, #MDREFR_K0DB4 + orr r4, r4, #MDREFR_K0FREE + orr r4, r4, #MDREFR_K0DB2 + orr r4, r4, #MDREFR_K1DB2 + bic r4, r4, #MDREFR_K1FREE + bic r4, r4, #MDREFR_K2FREE + + str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */ + ldr r4, [r1, #MDREFR_OFFSET] + + /* Note: preserve the mdrefr value in r4 */ + + + /* ---------------------------------------------------------------- */ + /* Step 3: Initialize Synchronous Static Memory (Flash/Peripherals) */ + /* ---------------------------------------------------------------- */ + + /* Initialize SXCNFG register. Assert the enable bits */ + + /* Write SXMRS to cause an MRS command to all enabled banks of */ + /* synchronous static memory. Note that SXLCR need not be written */ + /* at this time. */ + + ldr r2, =CFG_SXCNFG_VAL + str r2, [r1, #SXCNFG_OFFSET] + + /* ---------------------------------------------------------------- */ + /* Step 4: Initialize SDRAM */ + /* ---------------------------------------------------------------- */ + + bic r4, r4, #(MDREFR_K2FREE |MDREFR_K1FREE | MDREFR_K0FREE) + + orr r4, r4, #MDREFR_K1RUN + bic r4, r4, #MDREFR_K2DB2 + str r4, [r1, #MDREFR_OFFSET] + ldr r4, [r1, #MDREFR_OFFSET] + + bic r4, r4, #MDREFR_SLFRSH + str r4, [r1, #MDREFR_OFFSET] + ldr r4, [r1, #MDREFR_OFFSET] + + orr r4, r4, #MDREFR_E1PIN + str r4, [r1, #MDREFR_OFFSET] + ldr r4, [r1, #MDREFR_OFFSET] + + nop + nop + + + /* Step 4d: write MDCNFG with MDCNFG:DEx deasserted (set to 0), to */ + /* configure but not enable each SDRAM partition pair. */ + + ldr r4, =CFG_MDCNFG_VAL + bic r4, r4, #(MDCNFG_DE0|MDCNFG_DE1) + bic r4, r4, #(MDCNFG_DE2|MDCNFG_DE3) + + str r4, [r1, #MDCNFG_OFFSET] /* write back MDCNFG */ + ldr r4, [r1, #MDCNFG_OFFSET] + + + /* Step 4e: Wait for the clock to the SDRAMs to stabilize, */ + /* 100..200 µsec. */ + + ldr r3, =OSCR /* reset the OS Timer Count to zero */ + mov r2, #0 + str r2, [r3] + ldr r4, =0x300 /* really 0x2E1 is about 200usec, */ + /* so 0x300 should be plenty */ +1: + ldr r2, [r3] + cmp r4, r2 + bgt 1b + + + /* Step 4f: Trigger a number (usually 8) refresh cycles by */ + /* attempting non-burst read or write accesses to disabled */ + /* SDRAM, as commonly specified in the power up sequence */ + /* documented in SDRAM data sheets. The address(es) used */ + /* for this purpose must not be cacheable. */ + + ldr r3, =CFG_DRAM_BASE + str r2, [r3] + str r2, [r3] + str r2, [r3] + str r2, [r3] + str r2, [r3] + str r2, [r3] + str r2, [r3] + str r2, [r3] + + + /* Step 4g: Write MDCNFG with enable bits asserted */ + /* (MDCNFG:DEx set to 1). */ + + ldr r3, [r1, #MDCNFG_OFFSET] + mov r4, r3 + orr r3, r3, #MDCNFG_DE0 + str r3, [r1, #MDCNFG_OFFSET] + mov r0, r3 + + /* Step 4h: Write MDMRS. */ + + ldr r2, =CFG_MDMRS_VAL + str r2, [r1, #MDMRS_OFFSET] + + /* enable APD */ + ldr r3, [r1, #MDREFR_OFFSET] + orr r3, r3, #MDREFR_APD + str r3, [r1, #MDREFR_OFFSET] + + /* We are finished with Intel's memory controller initialisation */ + + +setvoltage: + + mov r10, lr + bl initPXAvoltage /* In case the board is rebooting with a */ + mov lr, r10 /* low voltage raise it up to a good one. */ + +#if 1 + b initirqs +#endif + +wakeup: + /* Are we waking from sleep? */ + ldr r0, =RCSR + ldr r1, [r0] + and r1, r1, #(RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR) + str r1, [r0] + teq r1, #RCSR_SMR + + bne initirqs + + ldr r0, =PSSR + mov r1, #PSSR_PH + str r1, [r0] + + /* if so, resume at PSPR */ + ldr r0, =PSPR + ldr r1, [r0] + mov pc, r1 + + /* ---------------------------------------------------------------- */ + /* Disable (mask) all interrupts at interrupt controller */ + /* ---------------------------------------------------------------- */ + +initirqs: + + mov r1, #0 /* clear int. level register (IRQ, not FIQ) */ + ldr r2, =ICLR + str r1, [r2] + + ldr r2, =ICMR /* mask all interrupts at the controller */ + str r1, [r2] + + /* ---------------------------------------------------------------- */ + /* Clock initialisation */ + /* ---------------------------------------------------------------- */ + +initclks: + + /* Disable the peripheral clocks, and set the core clock frequency */ + + /* Turn Off on-chip peripheral clocks (except for memory) */ + /* for re-configuration. */ + ldr r1, =CKEN + ldr r2, =CFG_CKEN + str r2, [r1] + + /* ... and write the core clock config register */ + ldr r2, =CFG_CCCR + ldr r1, =CCCR + str r2, [r1] + + /* Turn on turbo mode */ + mrc p14, 0, r2, c6, c0, 0 + orr r2, r2, #0xB /* Turbo, Fast-Bus, Freq change**/ + mcr p14, 0, r2, c6, c0, 0 + + /* Re-write MDREFR */ + ldr r1, =MEMC_BASE + ldr r2, [r1, #MDREFR_OFFSET] + str r2, [r1, #MDREFR_OFFSET] +#ifdef RTC + /* enable the 32Khz oscillator for RTC and PowerManager */ + ldr r1, =OSCC + mov r2, #OSCC_OON + str r2, [r1] + + /* NOTE: spin here until OSCC.OOK get set, meaning the PLL */ + /* has settled. */ +60: + ldr r2, [r1] + ands r2, r2, #1 + beq 60b +#else +#error "RTC not defined" +#endif + + /* Interrupt init: Mask all interrupts */ + ldr r0, =ICMR /* enable no sources */ + mov r1, #0 + str r1, [r0] + /* FIXME */ + +#ifdef NODEBUG + /*Disable software and data breakpoints */ + mov r0,#0 + mcr p15,0,r0,c14,c8,0 /* ibcr0 */ + mcr p15,0,r0,c14,c9,0 /* ibcr1 */ + mcr p15,0,r0,c14,c4,0 /* dbcon */ + + /*Enable all debug functionality */ + mov r0,#0x80000000 + mcr p14,0,r0,c10,c0,0 /* dcsr */ +#endif + + /* ---------------------------------------------------------------- */ + /* End lowlevel_init */ + /* ---------------------------------------------------------------- */ + +endlowlevel_init: + + mov pc, lr diff --git a/board/trizepsiv/pxavoltage.S b/board/trizepsiv/pxavoltage.S new file mode 100644 index 0000000..9659c2b --- /dev/null +++ b/board/trizepsiv/pxavoltage.S @@ -0,0 +1,29 @@ +/* + * (C) Copyright 2007 + * Stefano Babic, DENX Gmbh, sbabic@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 <asm/arch/pxa-regs.h> + + .global initPXAvoltage + +initPXAvoltage: + mov pc, lr diff --git a/board/trizepsiv/u-boot.lds b/board/trizepsiv/u-boot.lds new file mode 100644 index 0000000..f010239 --- /dev/null +++ b/board/trizepsiv/u-boot.lds @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + cpu/pxa/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +} |