diff options
author | wdenk <wdenk> | 2005-05-30 23:55:42 +0000 |
---|---|---|
committer | wdenk <wdenk> | 2005-05-30 23:55:42 +0000 |
commit | ba91e26a1923dfc703d4b96ae9428067b7447ff2 (patch) | |
tree | e7a9fe997185c6ff44f39dc1d7a1539dbde5d507 /board/funkwerk/vovpn-gw | |
parent | 2eab48f511b5445383009131c64141800720eb5e (diff) |
Patch by Juergen Selent, 17 May 2005:
Add support for Funkwerk VoVPN gateway module.
Diffstat (limited to 'board/funkwerk/vovpn-gw')
-rw-r--r-- | board/funkwerk/vovpn-gw/Makefile | 46 | ||||
-rw-r--r-- | board/funkwerk/vovpn-gw/config.mk | 21 | ||||
-rw-r--r-- | board/funkwerk/vovpn-gw/flash.c | 506 | ||||
-rw-r--r-- | board/funkwerk/vovpn-gw/m88e6060.c | 262 | ||||
-rw-r--r-- | board/funkwerk/vovpn-gw/m88e6060.h | 94 | ||||
-rw-r--r-- | board/funkwerk/vovpn-gw/u-boot.lds | 122 | ||||
-rw-r--r-- | board/funkwerk/vovpn-gw/vovpn-gw.c | 375 |
7 files changed, 1426 insertions, 0 deletions
diff --git a/board/funkwerk/vovpn-gw/Makefile b/board/funkwerk/vovpn-gw/Makefile new file mode 100644 index 00000000000..f77cc60a94b --- /dev/null +++ b/board/funkwerk/vovpn-gw/Makefile @@ -0,0 +1,46 @@ +# +# (C) Copyright 2001 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(BOARD).a + +OBJS := $(BOARD).o flash.o m88e6060.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $(OBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +-include .depend + +######################################################################### diff --git a/board/funkwerk/vovpn-gw/config.mk b/board/funkwerk/vovpn-gw/config.mk new file mode 100644 index 00000000000..e59b4831da3 --- /dev/null +++ b/board/funkwerk/vovpn-gw/config.mk @@ -0,0 +1,21 @@ +# (C) Copyright 2004 +# Elmeg Communications Systems GmbH, Juergen Selent (j.selent@elmeg.de) +# +# Support for the Elmeg VoVPN Gateway Module +# +# 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 = 0xfff00000 diff --git a/board/funkwerk/vovpn-gw/flash.c b/board/funkwerk/vovpn-gw/flash.c new file mode 100644 index 00000000000..1e53d45877c --- /dev/null +++ b/board/funkwerk/vovpn-gw/flash.c @@ -0,0 +1,506 @@ +/* + * (C) Copyright 2004 + * Elmeg Communications Systems GmbH, Juergen Selent (j.selent@elmeg.de) + * + * Support for the Elmeg VoVPN Gateway Module + * ------------------------------------------ + * This is a signle bank flashdriver for INTEL 28F320J3, 28F640J3 + * and 28F128J3A flashs working in 8 Bit mode. + * + * Most of this code is taken from existing u-boot source code. + * + * 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> + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + +#define FLASH_CMD_READ_ID 0x90 +#define FLASH_CMD_READ_STATUS 0x70 +#define FLASH_CMD_RESET 0xff +#define FLASH_CMD_BLOCK_ERASE 0x20 +#define FLASH_CMD_ERASE_CONFIRM 0xd0 +#define FLASH_CMD_CLEAR_STATUS 0x50 +#define FLASH_CMD_SUSPEND_ERASE 0xb0 +#define FLASH_CMD_WRITE 0x40 +#define FLASH_CMD_WRITE_BUFF 0xe8 +#define FLASH_CMD_PROG_RESUME 0xd0 +#define FLASH_CMD_PROTECT 0x60 +#define FLASH_CMD_PROTECT_SET 0x01 +#define FLASH_CMD_PROTECT_CLEAR 0xd0 +#define FLASH_STATUS_DONE 0x80 + +#define FLASH_WRITE_BUFFER_SIZE 32 + +#ifdef CFG_FLASH_16BIT +#define FLASH_WORD_SIZE unsigned short +#define FLASH_ID_MASK 0xffff +#define FLASH_CMD_ADDR_SHIFT 0 +#else +#define FLASH_WORD_SIZE unsigned char +#define FLASH_ID_MASK 0xff +/* A0 is not used in either 8x or 16x for READ ID */ +#define FLASH_CMD_ADDR_SHIFT 1 +#endif + + +static unsigned long +flash_get(volatile FLASH_WORD_SIZE *addr, flash_info_t *info) +{ + volatile FLASH_WORD_SIZE *p; + FLASH_WORD_SIZE value; + int i; + + addr[0] = FLASH_CMD_READ_ID; + + /* manufactor */ + value = addr[0 << FLASH_CMD_ADDR_SHIFT]; + switch (value) { + case (INTEL_MANUFACT & FLASH_ID_MASK): + info->flash_id = FLASH_MAN_INTEL; + break; + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + *addr = FLASH_CMD_RESET; + return (0); + + } + + /* device */ + value = addr[1 << FLASH_CMD_ADDR_SHIFT]; + switch (value) { + case (INTEL_ID_28F320J3A & FLASH_ID_MASK): + info->flash_id += FLASH_28F320J3A; + info->sector_count = 32; + info->size = 0x00400000; + break; + case (INTEL_ID_28F640J3A & FLASH_ID_MASK): + info->flash_id += FLASH_28F640J3A; + info->sector_count = 64; + info->size = 0x00800000; + break; + case (INTEL_ID_28F128J3A & FLASH_ID_MASK): + info->flash_id += FLASH_28F128J3A; + info->sector_count = 128; + info->size = 0x01000000; + break; + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + *addr = FLASH_CMD_RESET; + return (0); + } + + /* setup sectors */ + for (i = 0; i < info->sector_count; i++) { + info->start[i] = (unsigned long)addr + (i * info->size/info->sector_count); + } + + /* check protected sectors */ + for (i = 0; i < info->sector_count; i++) { + p = (volatile FLASH_WORD_SIZE *)(info->start[i]); + info->protect[i] = p[2 << FLASH_CMD_ADDR_SHIFT] & 1; + } + + /* reset bank */ + *addr = FLASH_CMD_RESET; + return (info->size); +} + +unsigned long +flash_init(void) +{ + unsigned long size; + int i; + + for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) { + flash_info[i].flash_id = FLASH_UNKNOWN; + } + size = flash_get((volatile FLASH_WORD_SIZE *)CFG_FLASH_BASE, &flash_info[0]); + if (flash_info[0].flash_id == FLASH_UNKNOWN) { + printf ("## Unknown FLASH Size=0x%08lx\n", size); + return (0); + } + + /* always protect 1 sector containing the HRCW */ + flash_protect(FLAG_PROTECT_SET, + flash_info[0].start[0], + flash_info[0].start[1] - 1, + &flash_info[0]); + +#if CFG_MONITOR_BASE >= CFG_FLASH_BASE + flash_protect(FLAG_PROTECT_SET, + CFG_MONITOR_FLASH, + CFG_MONITOR_FLASH+CFG_MONITOR_LEN-1, + &flash_info[0]); +#endif +#ifdef CFG_ENV_IS_IN_FLASH + flash_protect(FLAG_PROTECT_SET, + CFG_ENV_ADDR, + CFG_ENV_ADDR+CFG_ENV_SECT_SIZE-1, + &flash_info[0]); +#endif + return (size); +} + +void +flash_print_info(flash_info_t *info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_INTEL: printf ("INTEL "); break; + default: printf ("Unknown Vendor "); break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_28F320J3A: printf ("28F320JA3 (32 Mbit)\n"); + break; + case FLASH_28F640J3A: printf ("28F640JA3 (64 Mbit)\n"); + break; + case FLASH_28F128J3A: printf ("28F128JA3 (128 Mbit)\n"); + break; + default: printf ("Unknown Chip Type"); + break; + } + + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i=0; i<info->sector_count; ++i) { + if ((i % 5) == 0) + printf ("\n "); + printf (" %08lX%s", + info->start[i], + info->protect[i] ? " (RO)" : " " + ); + } + printf ("\n"); +} + +int +flash_erase(flash_info_t *info, int s_first, int s_last) +{ + unsigned long start, now, last; + int flag, prot, sect; + volatile FLASH_WORD_SIZE *addr; + FLASH_WORD_SIZE status; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return (1); + } + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("Cannot erase unknown flash - aborted\n"); + 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; + + for (sect = s_first; sect<=s_last; sect++) { + if (info->protect[sect]) { + continue; + } + + addr = (volatile FLASH_WORD_SIZE *)(info->start[sect]); + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + +#ifdef DEBUG + printf("Erase sector %d at start addr 0x%08X", sect, (unsigned int)info->start[sect]); +#endif + + *addr = FLASH_CMD_CLEAR_STATUS; + *addr = FLASH_CMD_BLOCK_ERASE; + *addr = FLASH_CMD_ERASE_CONFIRM; + + /* re-enable interrupts if necessary */ + if (flag) { + enable_interrupts(); + } + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000); + + while (((status = *addr) & FLASH_STATUS_DONE) != FLASH_STATUS_DONE) { + if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) { + printf("Flash erase timeout at address %lx\n", info->start[sect]); + *addr = FLASH_CMD_SUSPEND_ERASE; + *addr = FLASH_CMD_RESET; + return (1); + } + + /* show that we're waiting */ + if ((now - last) > 1000) { /* every second */ + putc ('.'); + last = now; + } + } + *addr = FLASH_CMD_RESET; + } + printf (" done\n"); + return (0); +} + +static int +write_buff2( volatile FLASH_WORD_SIZE *dst, + volatile FLASH_WORD_SIZE *src, + unsigned long cnt ) +{ + unsigned long start; + FLASH_WORD_SIZE status; + int flag, i; + + start = get_timer (0); + while (1) { + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + dst[0] = FLASH_CMD_WRITE_BUFF; + if ((status = *dst) & FLASH_STATUS_DONE) { + break; + } + + /* re-enable interrupts if necessary */ + if (flag) { + enable_interrupts(); + } + + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + return (-1); + } + } + dst[0] = (FLASH_WORD_SIZE)(cnt - 1); + for (i=0; i<cnt; i++) { + dst[i] = src[i]; + } + dst[0] = FLASH_CMD_PROG_RESUME; + + if (flag) { + enable_interrupts(); + } + + return( 0 ); +} + +static int +poll_status( volatile FLASH_WORD_SIZE *addr ) +{ + unsigned long start; + + start = get_timer (0); + /* wait for error or finish */ + while (1) { + if (*addr == FLASH_STATUS_DONE) { + if (*addr == FLASH_STATUS_DONE) { + break; + } + } + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + *addr = FLASH_CMD_RESET; + return (-1); + } + } + *addr = FLASH_CMD_RESET; + return (0); +} + +/* + * write_buff return values: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 4 - Flash not identified + */ +int +write_buff(flash_info_t *info, uchar *src, ulong udst, ulong cnt) +{ + volatile FLASH_WORD_SIZE *addr, *dst; + unsigned long bcnt; + int flag, i; + + if (info->flash_id == FLASH_UNKNOWN) { + return (4); + } + + addr = (volatile FLASH_WORD_SIZE *)(info->start[0]); + dst = (volatile FLASH_WORD_SIZE *) udst; + +#ifdef CFG_FLASH_16BIT +#error NYI +#else + while (cnt > 0) { + /* Check if buffer write is possible */ + if (cnt > 1 && (((unsigned long)dst & (FLASH_WRITE_BUFFER_SIZE - 1)) == 0)) { + bcnt = cnt > FLASH_WRITE_BUFFER_SIZE ? FLASH_WRITE_BUFFER_SIZE : cnt; + /* Check if Flash is (sufficiently) erased */ + for (i=0; i<bcnt; i++) { + if ((dst[i] & src[i]) != src[i]) { + return (2); + } + } + if (write_buff2( dst,src,bcnt ) != 0) { + addr[0] = FLASH_CMD_READ_STATUS; + } + if (poll_status( dst ) != 0) { + return (1); + } + cnt -= bcnt; + dst += bcnt; + src += bcnt; + continue; + } + + /* Check if Flash is (sufficiently) erased */ + if ((*dst & *src) != *src) { + return (2); + } + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + addr[0] = FLASH_CMD_ERASE_CONFIRM; + addr[0] = FLASH_CMD_WRITE; + *dst++ = *src++; + /* re-enable interrupts if necessary */ + if (flag) { + enable_interrupts(); + } + + if (poll_status( dst ) != 0) { + return (1); + } + cnt --; + } +#endif + return (0); +} + +int +flash_real_protect(flash_info_t *info, long sector, int prot) +{ + volatile FLASH_WORD_SIZE *addr; + unsigned long start; + + addr = (volatile FLASH_WORD_SIZE *)(info->start[sector]); + *addr = FLASH_CMD_CLEAR_STATUS; + *addr = FLASH_CMD_PROTECT; + + if(prot) { + *addr = FLASH_CMD_PROTECT_SET; + } else { + *addr = FLASH_CMD_PROTECT_CLEAR; + } + + /* wait for error or finish */ + start = get_timer (0); + while(!(addr[0] & FLASH_STATUS_DONE)){ + if (get_timer(start) > CFG_FLASH_ERASE_TOUT) { + printf("Flash protect timeout at address %lx\n", info->start[sector]); + addr[0] = FLASH_CMD_RESET; + return (1); + } + } + + /* Set software protect flag */ + info->protect[sector] = prot; + *addr = FLASH_CMD_RESET; + return (0); +} + +/*----------------------------------------------------------------------- + * Support for flash file system (JFFS2) + * + * We use custom partition info function because we have to fit the + * file system image between first sector (containing hard reset + * configuration word) and the sector containing U-Boot image. Standard + * partition info function does not allow for last sector specification + * and assumes that the file system occupies flash bank up to and + * including bank's last sector. + */ +#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CFG_JFFS_CUSTOM_PART) +#error TODO + +#ifndef CFG_JFFS2_FIRST_SECTOR +#define CFG_JFFS2_FIRST_SECTOR 0 +#endif +#ifndef CFG_JFFS2_FIRST_BANK +#define CFG_JFFS2_FIRST_BANK 0 +#endif +#ifndef CFG_JFFS2_NUM_BANKS +#define CFG_JFFS2_NUM_BANKS 1 +#endif +#define CFG_JFFS2_LAST_BANK (CFG_JFFS2_FIRST_BANK + CFG_JFFS2_NUM_BANKS - 1) + +#include <jffs2/jffs2.h> + +static struct part_info partition; + +struct part_info *jffs2_part_info(int part_num) +{ + int i; + + if (part_num == 0) { + if (partition.usr_priv == 0) { + partition.offset = + (unsigned char *) flash_info[CFG_JFFS2_FIRST_BANK].start[CFG_JFFS2_FIRST_SECTOR]; + for (i = CFG_JFFS2_FIRST_BANK; i <= CFG_JFFS2_LAST_BANK; i++) + partition.size += flash_info[i].size; + partition.size -= + flash_info[CFG_JFFS2_FIRST_BANK].start[CFG_JFFS2_FIRST_SECTOR] - + flash_info[CFG_JFFS2_FIRST_BANK].start[0]; +#ifdef CFG_JFFS2_LAST_SECTOR + i = flash_info[CFG_JFFS2_LAST_BANK].sector_count - 1; + partition.size -= + flash_info[CFG_JFFS2_LAST_BANK].start[i] - + flash_info[CFG_JFFS2_LAST_BANK].start[CFG_JFFS2_LAST_SECTOR]; +#endif + + partition.usr_priv = (void *)1; + } + return &partition; + } + return 0; +} + +#endif /* JFFS2 */ diff --git a/board/funkwerk/vovpn-gw/m88e6060.c b/board/funkwerk/vovpn-gw/m88e6060.c new file mode 100644 index 00000000000..e4ff3c37c50 --- /dev/null +++ b/board/funkwerk/vovpn-gw/m88e6060.c @@ -0,0 +1,262 @@ +/* + * (C) Copyright 2004 + * Elmeg Communications Systems GmbH, Juergen Selent (j.selent@elmeg.de) + * + * Support for the Elmeg VoVPN Gateway Module + * ------------------------------------------ + * Initialize Marvell M88E6060 Switch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <ioports.h> +#include <mpc8260.h> +#include <asm/m8260_pci.h> +#include <net.h> +#include <miiphy.h> + +#include "m88e6060.h" + +#if (CONFIG_COMMANDS & CFG_CMD_NET) +static int prtTab[M88X_PRT_CNT] = { 8, 9, 10, 11, 12, 13 }; +static int phyTab[M88X_PHY_CNT] = { 0, 1, 2, 3, 4 }; + +static m88x_regCfg_t prtCfg0[] = { + { 4, 0x3e7c, 0x8000 }, + { 4, 0x3e7c, 0x8003 }, + { 6, 0x0fc0, 0x001e }, + { -1, 0xffff, 0x0000 } +}; + +static m88x_regCfg_t prtCfg1[] = { + { 4, 0x3e7c, 0x8000 }, + { 4, 0x3e7c, 0x8003 }, + { 6, 0x0fc0, 0x001d }, + { -1, 0xffff, 0x0000 } +}; + +static m88x_regCfg_t prtCfg2[] = { + { 4, 0x3e7c, 0x8000 }, + { 4, 0x3e7c, 0x8003 }, + { 6, 0x0fc0, 0x001b }, + { -1, 0xffff, 0x0000 } +}; + +static m88x_regCfg_t prtCfg3[] = { + { 4, 0x3e7c, 0x8000 }, + { 4, 0x3e7c, 0x8003 }, + { 6, 0x0fc0, 0x0017 }, + { -1, 0xffff, 0x0000 } +}; + +static m88x_regCfg_t prtCfg4[] = { + { 4, 0x3e7c, 0x8000 }, + { 4, 0x3e7c, 0x8003 }, + { 6, 0x0fc0, 0x000f }, + { -1, 0xffff, 0x0000 } +}; + +static m88x_regCfg_t *prtCfg[M88X_PRT_CNT] = { + prtCfg0,prtCfg1,prtCfg2,prtCfg3,prtCfg4,NULL +}; + +static m88x_regCfg_t phyCfgX[] = { + { 4, 0xfa1f, 0x01e0 }, + { 0, 0x213f, 0x1200 }, + { 24, 0x81ff, 0x1200 }, + { -1, 0xffff, 0x0000 } +}; + +static m88x_regCfg_t *phyCfg[M88X_PHY_CNT] = { + phyCfgX,phyCfgX,phyCfgX,phyCfgX,NULL +}; + +#if 0 +static void +m88e6060_dump( int devAddr ) +{ + int i, j; + unsigned short val[6]; + + printf( "M88E6060 Register Dump\n" ); + printf( "====================================\n" ); + printf( "PortNo 0 1 2 3 4 5\n" ); + for (i=0; i<6; i++) + miiphy_read( devAddr+prtTab[i],M88X_PRT_STAT,&val[i] ); + printf( "STAT %04hx %04hx %04hx %04hx %04hx %04hx\n", + val[0],val[1],val[2],val[3],val[4],val[5] ); + + for (i=0; i<6; i++) + miiphy_read( devAddr+prtTab[i],M88X_PRT_ID,&val[i] ); + printf( "ID %04hx %04hx %04hx %04hx %04hx %04hx\n", + val[0],val[1],val[2],val[3],val[4],val[5] ); + + for (i=0; i<6; i++) + miiphy_read( devAddr+prtTab[i],M88X_PRT_CNTL,&val[i] ); + printf( "CNTL %04hx %04hx %04hx %04hx %04hx %04hx\n", + val[0],val[1],val[2],val[3],val[4],val[5] ); + + for (i=0; i<6; i++) + miiphy_read( devAddr+prtTab[i],M88X_PRT_VLAN,&val[i] ); + printf( "VLAN %04hx %04hx %04hx %04hx %04hx %04hx\n", + val[0],val[1],val[2],val[3],val[4],val[5] ); + + for (i=0; i<6; i++) + miiphy_read( devAddr+prtTab[i],M88X_PRT_PAV,&val[i] ); + printf( "PAV %04hx %04hx %04hx %04hx %04hx %04hx\n", + val[0],val[1],val[2],val[3],val[4],val[5] ); + + for (i=0; i<6; i++) + miiphy_read( devAddr+prtTab[i],M88X_PRT_RX,&val[i] ); + printf( "RX %04hx %04hx %04hx %04hx %04hx %04hx\n", + val[0],val[1],val[2],val[3],val[4],val[5] ); + + for (i=0; i<6; i++) + miiphy_read( devAddr+prtTab[i],M88X_PRT_TX,&val[i] ); + printf( "TX %04hx %04hx %04hx %04hx %04hx %04hx\n", + val[0],val[1],val[2],val[3],val[4],val[5] ); + + printf( "------------------------------------\n" ); + printf( "PhyNo 0 1 2 3 4\n" ); + for (i=0; i<9; i++) { + for (j=0; j<5; j++) { + miiphy_read( devAddr+phyTab[j],i,&val[j] ); + } + printf( "0x%02x %04hx %04hx %04hx %04hx %04hx\n", + i,val[0],val[1],val[2],val[3],val[4] ); + } + for (i=0x10; i<0x1d; i++) { + for (j=0; j<5; j++) { + miiphy_read( devAddr+phyTab[j],i,&val[j] ); + } + printf( "0x%02x %04hx %04hx %04hx %04hx %04hx\n", + i,val[0],val[1],val[2],val[3],val[4] ); + } +} +#endif + +int +m88e6060_initialize( int devAddr ) +{ + static char *_f = "m88e6060_initialize:"; + m88x_regCfg_t *p; + int err; + int i; + unsigned short val; + + /*** reset all phys into powerdown ************************************/ + for (i=0, err=0; i<M88X_PHY_CNT; i++) { + err += miiphy_read( devAddr+phyTab[i],M88X_PHY_CNTL,&val ); + /* keep SpeedLSB, Duplex */ + val &= 0x2100; + /* set SWReset, AnegEn, PwrDwn, RestartAneg */ + val |= 0x9a00; + err += miiphy_write( devAddr+phyTab[i],M88X_PHY_CNTL,val ); + } + if (err) { + printf( "%s [ERR] reset phys\n",_f ); + return( -1 ); + } + + /*** disable all ports ************************************************/ + for (i=0, err=0; i<M88X_PRT_CNT; i++) { + err += miiphy_read( devAddr+prtTab[i],M88X_PRT_CNTL,&val ); + val &= 0xfffc; + err += miiphy_write( devAddr+prtTab[i],M88X_PRT_CNTL,val ); + } + if (err) { + printf( "%s [ERR] disable ports\n",_f ); + return( -1 ); + } + + /*** initialize switch ************************************************/ + /* set switch mac addr */ +#define ea eth_get_dev()->enetaddr + val = (ea[4] << 8) | ea[5]; + err = miiphy_write( devAddr+15,M88X_GLB_MAC45,val ); + val = (ea[2] << 8) | ea[3]; + err += miiphy_write( devAddr+15,M88X_GLB_MAC23,val ); + val = (ea[0] << 8) | ea[1]; +#undef ea + val &= 0xfeff; /* clear DiffAddr */ + err += miiphy_write( devAddr+15,M88X_GLB_MAC01,val ); + if (err) { + printf( "%s [ERR] switch mac address register\n",_f ); + return( -1 ); + } + + /* !DiscardExcessive, MaxFrameSize, CtrMode */ + err = miiphy_read( devAddr+15,M88X_GLB_CNTL,&val ); + val &= 0xd870; + val |= 0x0500; + err += miiphy_write( devAddr+15,M88X_GLB_CNTL,val ); + if (err) { + printf( "%s [ERR] switch global control register\n",_f ); + return( -1 ); + } + + /* LernDis off, ATUSize 1024, AgeTime 5min */ + err = miiphy_read( devAddr+15,M88X_ATU_CNTL,&val ); + val &= 0x000f; + val |= 0x2130; + err += miiphy_write( devAddr+15,M88X_ATU_CNTL,val ); + if (err) { + printf( "%s [ERR] atu control register\n",_f ); + return( -1 ); + } + + /*** initialize ports *************************************************/ + for (i=0; i<M88X_PRT_CNT; i++) { + if ((p = prtCfg[i]) == NULL) { + continue; + } + while (p->reg != -1) { + err = 0; + err += miiphy_read( devAddr+prtTab[i],p->reg,&val ); + val &= p->msk; + val |= p->val; + err += miiphy_write( devAddr+prtTab[i],p->reg,val ); + if (err) { + printf( "%s [ERR] config port %d register %d\n",_f,i,p->reg ); + /* XXX what todo */ + } + p++; + } + } + + /*** initialize phys **************************************************/ + for (i=0; i<M88X_PHY_CNT; i++) { + if ((p = phyCfg[i]) == NULL) { + continue; + } + while (p->reg != -1) { + err = 0; + err += miiphy_read( devAddr+phyTab[i],p->reg,&val ); + val &= p->msk; + val |= p->val; + err += miiphy_write( devAddr+phyTab[i],p->reg,val ); + if (err) { + printf( "%s [ERR] config phy %d register %d\n",_f,i,p->reg ); + /* XXX what todo */ + } + p++; + } + } + udelay(100000); + return( 0 ); +} +#endif diff --git a/board/funkwerk/vovpn-gw/m88e6060.h b/board/funkwerk/vovpn-gw/m88e6060.h new file mode 100644 index 00000000000..563a5e0f1c0 --- /dev/null +++ b/board/funkwerk/vovpn-gw/m88e6060.h @@ -0,0 +1,94 @@ +/* + * (C) Copyright 2004 + * Elmeg Communications Systems GmbH, Juergen Selent (j.selent@elmeg.de) + * + * Support for the Elmeg VoVPN Gateway Module + * ------------------------------------------ + * Initialize Marvell M88E6060 Switch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _INC_m88e6060_h_ +#define _INC_m88e6060_h_ + +/* ************************************************************************** */ +/* *** DEFINES ************************************************************** */ + +/* switch hw */ +#define M88X_PRT_CNT 6 +#define M88X_PHY_CNT 5 + +/* phy register offsets */ +#define M88X_PHY_CNTL 0x00 +#define M88X_PHY_STAT 0x00 +#define M88X_PHY_ID0 0x02 +#define M88X_PHY_ID1 0x03 +#define M88X_PHY_ANEG_ADV 0x04 +#define M88X_PHY_LPA 0x05 +#define M88X_PHY_ANEG_EXP 0x06 +#define M88X_PHY_NPT 0x07 +#define M88X_PHY_LPNP 0x08 + +/* port register offsets */ +#define M88X_PRT_STAT 0x00 +#define M88X_PRT_ID 0x03 +#define M88X_PRT_CNTL 0x04 +#define M88X_PRT_VLAN 0x06 +#define M88X_PRT_PAV 0x0b +#define M88X_PRT_RX 0x10 +#define M88X_PRT_TX 0x11 + +/* global/atu register offsets */ +#define M88X_GLB_STAT 0x00 +#define M88X_GLB_MAC01 0x01 +#define M88X_GLB_MAC23 0x02 +#define M88X_GLB_MAC45 0x03 +#define M88X_GLB_CNTL 0x04 +#define M88X_ATU_CNTL 0x0a +#define M88X_ATU_OP 0x0b + +/* id0 register - 0x02 */ +#define M88X_PHY_ID0_VALUE 0x0141 + +/* id1 register - 0x03 */ +#define M88X_PHY_ID1_VALUE 0x0c80 /* without revision ! */ + + +/* misc */ +#define M88E6060_ID ((M88X_PHY_ID0_VALUE<<16) | M88X_PHY_ID1_VALUE) + + + +/* ************************************************************************** */ +/* *** TYPEDEFS ************************************************************* */ + +typedef struct { + int reg; + unsigned short msk; + unsigned short val; +} m88x_regCfg_t; + + + +/* ************************************************************************** */ +/* *** PROTOTYPES *********************************************************** */ + +extern int m88e6060_initialize( int ); + + + +#endif /* _INC_m88e6060_h_ */ diff --git a/board/funkwerk/vovpn-gw/u-boot.lds b/board/funkwerk/vovpn-gw/u-boot.lds new file mode 100644 index 00000000000..098c0464cc8 --- /dev/null +++ b/board/funkwerk/vovpn-gw/u-boot.lds @@ -0,0 +1,122 @@ +/* + * (C) Copyright 2001-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Modified by Yuli Barcohen <yuli@arabellasw.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(powerpc) +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 : + { + cpu/mpc8260/start.o (.text) + *(.text) + *(.fixup) + *(.got1) + . = ALIGN(16); + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x0FFF) & 0xFFFFF000; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; + __fixup_entries = (. - _FIXUP_TABLE_) >> 2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(4096); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} +ENTRY(_start) diff --git a/board/funkwerk/vovpn-gw/vovpn-gw.c b/board/funkwerk/vovpn-gw/vovpn-gw.c new file mode 100644 index 00000000000..03b3cdfae32 --- /dev/null +++ b/board/funkwerk/vovpn-gw/vovpn-gw.c @@ -0,0 +1,375 @@ +/* + * (C) Copyright 2004 + * Elmeg Communications Systems GmbH, Juergen Selent (j.selent@elmeg.de) + * + * Support for the Elmeg VoVPN Gateway Module + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <ioports.h> +#include <mpc8260.h> +#include <asm/m8260_pci.h> +#include <miiphy.h> + +#include "m88e6060.h" + +/* + * I/O Port configuration table + * + * if conf is 1, then that port pin will be configured at boot time + * according to the five values podr/pdir/ppar/psor/pdat for that entry + */ + +const iop_conf_t iop_conf_tab[4][32] = { + /* Port A configuration */ + { /* conf ppar psor pdir podr pdat */ + /* PA31 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1252 */ + /* PA30 */ { 1, 0, 0, 0, 0, 0 }, /* GPI BP_RES */ + /* PA29 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1253 */ + /* PA28 */ { 1, 1, 1, 1, 0, 0 }, /* FCC1 RMII TX_EN */ + /* PA27 */ { 1, 1, 1, 0, 0, 0 }, /* FCC1 RMII CRS_DV */ + /* PA26 */ { 1, 1, 1, 0, 0, 0 }, /* FCC1 RMII RX_ERR */ + /* PA25 */ { 1, 0, 0, 0, 0, 0 }, /* GPI HWID */ + /* PA24 */ { 1, 0, 0, 0, 0, 0 }, /* GPI HWID */ + /* PA23 */ { 1, 0, 0, 0, 0, 0 }, /* GPI HWID */ + /* PA22 */ { 1, 0, 0, 0, 0, 0 }, /* GPI HWID */ + /* PA21 */ { 1, 0, 0, 0, 0, 0 }, /* GPI HWID */ + /* PA20 */ { 1, 0, 0, 1, 0, 1 }, /* GPO LED STATUS */ + /* PA19 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 RMII TxD[1] */ + /* PA18 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 RMII TxD[0] */ + /* PA17 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 RMII RxD[0] */ + /* PA16 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 RMII RxD[1] */ + /* PA15 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1255 */ + /* PA14 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP???? */ + /* PA13 */ { 1, 0, 0, 1, 0, 1 }, /* GPO EN_BCTL1 XXX jse */ + /* PA12 */ { 1, 0, 0, 1, 0, 0 }, /* GPO SWITCH RESET */ + /* PA11 */ { 1, 0, 0, 1, 0, 0 }, /* GPO DSP SL1 RESET */ + /* PA10 */ { 1, 0, 0, 1, 0, 0 }, /* GPO DSP SL2 RESET */ + /* PA9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC2 TXD */ + /* PA8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC2 RXD */ + /* PA7 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exit */ + /* PA6 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exit */ + /* PA5 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exit */ + /* PA4 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exit */ + /* PA3 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exit */ + /* PA2 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exit */ + /* PA1 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exit */ + /* PA0 */ { 0, 0, 0, 0, 0, 0 } /* pin does not exit */ + }, + + /* Port B configuration */ + { /* conf ppar psor pdir podr pdat */ + /* PB31 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1257 */ + /* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RMII CRS_DV */ + /* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 RMII TX_EN */ + /* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RMII RX_ERR */ + /* PB27 */ { 1, 1, 1, 0, 1, 0 }, /* TDM_B2 L1TXD XXX val=0 */ + /* PB26 */ { 1, 1, 1, 0, 1, 0 }, /* TDM_B2 L1RXD XXX val,dr */ + /* PB25 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1259 */ + /* PB24 */ { 1, 1, 1, 0, 0, 0 }, /* TDM_B2 L1RSYNC */ + /* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 RMII TxD[1] */ + /* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 RMII TxD[0] */ + /* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RMII RxD[0] */ + /* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RMII RxD[1] */ + /* PB19 */ { 1, 0, 0, 1, 0, 1 }, /* GPO PHY MDC */ + /* PB18 */ { 1, 0, 0, 0, 0, 0 }, /* GPIO PHY MDIO */ + /* PB17 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PB16 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PB15 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PB14 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PB13 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PB12 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PB11 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PB10 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PB9 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PB8 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PB7 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PB6 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PB5 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PB4 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin does not exist */ + }, + + /* Port C */ + { /* conf ppar psor pdir podr pdat */ + /* PC31 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PC30 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PC29 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1183 */ + /* PC28 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1184 */ + /* PC27 */ { 1, 1, 0, 0, 0, 0 }, /* CLK5 TDM_A1 RX */ + /* PC26 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1185 */ + /* PC25 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1178 */ + /* PC24 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1186 */ + /* PC23 */ { 1, 1, 0, 0, 0, 0 }, /* CLK9 TDM_B2 RX */ + /* PC22 */ { 1, 1, 0, 0, 0, 0 }, /* CLK10 FCC1 RMII REFCLK */ + /* PC21 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1187 */ + /* PC20 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1182 */ + /* PC19 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1188 */ + /* PC18 */ { 1, 0, 0, 1, 0, 0 }, /* GPO HW RESET */ + /* PC17 */ { 1, 1, 0, 1, 0, 0 }, /* BRG8 SWITCH CLKIN */ + /* PC16 */ { 1, 1, 0, 0, 0, 0 }, /* CLK16 FCC2 RMII REFCLK */ + /* PC15 */ { 1, 0, 0, 0, 0, 0 }, /* GPI SL1_MTYPE_3 */ + /* PC14 */ { 1, 0, 0, 0, 0, 0 }, /* GPI SL1_MTYPE_2 */ + /* PC13 */ { 1, 0, 0, 0, 0, 0 }, /* GPI SL1_MTYPE_1 */ + /* PC12 */ { 1, 0, 0, 0, 0, 0 }, /* GPI SL1_MTYPE_0 */ + /* PC11 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1176 */ + /* PC10 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1177 */ + /* PC9 */ { 1, 0, 0, 0, 0, 0 }, /* GPI SL2_MTYPE_3 */ + /* PC8 */ { 1, 0, 0, 0, 0, 0 }, /* GPI SL2_MTYPE_2 */ + /* PC7 */ { 1, 0, 0, 0, 0, 0 }, /* GPI SL2_MTYPE_1 */ + /* PC6 */ { 1, 0, 0, 0, 0, 0 }, /* GPI SL2_MTYPE_0 */ + /* PC5 */ { 1, 1, 0, 1, 0, 0 }, /* SMC1 TXD */ + /* PC4 */ { 1, 1, 0, 0, 0, 0 }, /* SMC1 RXD */ + /* PC3 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PC2 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PC1 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1192 */ + /* PC0 */ { 1, 0, 0, 0, 0, 0 }, /* GPI RACK */ + }, + + /* Port D */ + { /* conf ppar psor pdir podr pdat */ + /* PD31 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1193 */ + /* PD30 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1194 */ + /* PD29 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1195 */ + /* PD28 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PD27 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PD26 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PD25 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1179 */ + /* PD24 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1180 */ + /* PD23 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1181 */ + /* PD22 */ { 1, 1, 1, 0, 1, 0 }, /* TDM_A2 L1TXD */ + /* PD21 */ { 1, 1, 1, 0, 1, 0 }, /* TDM_A2 L1RXD */ + /* PD20 */ { 1, 1, 1, 0, 0, 0 }, /* TDM_A2 L1RSYNC */ + /* PD19 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1196 */ + /* PD18 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1197 */ + /* PD17 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1198 */ + /* PD16 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1199 */ + /* PD15 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1250 */ + /* PD14 */ { 1, 0, 0, 1, 0, 0 }, /* GPO TP1251 */ + /* PD13 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PD12 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PD11 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PD10 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PD9 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PD8 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PD7 */ { 0, 0, 0, 1, 0, 0 }, /* GPO FL_BYTE */ + /* PD6 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PD5 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PD4 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin does not exist */ + /* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin does not exist */ + } +}; + +void reset_phy (void) +{ + volatile ioport_t *iop; +#if (CONFIG_COMMANDS & CFG_CMD_NET) + int i; + unsigned short val; +#endif + + iop = ioport_addr((immap_t *)CFG_IMMR, 0); + + /* Reset the PHY */ + iop->pdat &= 0xfff7ffff; /* PA12 = |SWITCH_RESET */ +#if (CONFIG_COMMANDS & CFG_CMD_NET) + udelay(20000); + iop->pdat |= 0x00080000; + for (i=0; i<100; i++) { + udelay(20000); + if (miiphy_read( CFG_PHY_ADDR,2,&val ) == 0) { + break; + } + } + /* initialize switch */ + m88e6060_initialize( CFG_PHY_ADDR ); +#endif +} + +static unsigned long UPMATable[] = { + 0x8fffec00, 0x0ffcfc00, 0x0ffcfc00, 0x0ffcfc00, //Words 0 to 3 + 0x0ffcfc04, 0x3ffdfc00, 0xfffffc01, 0xfffffc01, //Words 4 to 7 + 0xfffffc00, 0xfffffc04, 0xfffffc01, 0xfffffc00, //Words 8 to 11 + 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 12 to 15 + 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 16 to 19 + 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, //Words 20 to 23 + 0x8fffec00, 0x00fffc00, 0x00fffc00, 0x00fffc00, //Words 24 to 27 + 0x0ffffc04, 0xfffffc01, 0xfffffc01, 0xfffffc01, //Words 28 to 31 + 0xfffffc00, 0xfffffc01, 0xfffffc01, 0xfffffc00, //Words 32 to 35 + 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 36 to 39 + 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 40 to 43 + 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, //Words 44 to 47 + 0xfffffc00, 0xfffffc04, 0xfffffc01, 0xfffffc00, //Words 48 to 51 + 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 52 to 55 + 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, //Words 56 to 59 + 0xffffec00, 0xffffec04, 0xffffec00, 0xfffffc01 //Words 60 to 63 +}; + +int board_early_init_f (void) +{ + volatile immap_t *immap; + volatile memctl8260_t *memctl; + volatile unsigned char *dummy; + int i; + + immap = (immap_t *) CFG_IMMR; + memctl = &immap->im_memctl; + +#if 0 + /* CS2-5 - DSP via UPMA */ + dummy = (volatile unsigned char *) (memctl->memc_br2 & BRx_BA_MSK); + memctl->memc_mar = 0; + memctl->memc_mamr = MxMR_OP_WARR; + for (i = 0; i < 64; i++) { + memctl->memc_mdr = UPMATable[i]; + *dummy = 0; + } + memctl->memc_mamr = 0x00044440; +#else + /* CS7 - DPRAM via UPMA */ + dummy = (volatile unsigned char *) (memctl->memc_br7 & BRx_BA_MSK); + memctl->memc_mar = 0; + memctl->memc_mamr = MxMR_OP_WARR; + for (i = 0; i < 64; i++) { + memctl->memc_mdr = UPMATable[i]; + *dummy = 0; + } + memctl->memc_mamr = 0x00044440; +#endif + return 0; +} + +int misc_init_r (void) +{ + volatile ioport_t *iop; + unsigned char temp; +#if 0 + /* DUMP UPMA RAM */ + volatile immap_t *immap; + volatile memctl8260_t *memctl; + volatile unsigned char *dummy; + unsigned char c; + int i; + + immap = (immap_t *) CFG_IMMR; + memctl = &immap->im_memctl; + + + dummy = (volatile unsigned char *) (memctl->memc_br7 & BRx_BA_MSK); + memctl->memc_mar = 0; + memctl->memc_mamr = MxMR_OP_RARR; + for (i = 0; i < 64; i++) { + c = *dummy; + printf( "UPMA[%02d]: 0x%08lx,0x%08lx: 0x%08lx\n",i, + memctl->memc_mamr, + memctl->memc_mar, + memctl->memc_mdr ); + } + memctl->memc_mamr = 0x00044440; +#endif + /* enable buffers (DSP, DPRAM) */ + iop = ioport_addr((immap_t *)CFG_IMMR, 0); + iop->pdat &= 0xfffbffff; /* PA13 = |EN_M_BCTL1 */ + + /* destroy DPRAM magic */ + *(volatile unsigned char *)0xf0500000 = 0x00; + + /* clear any pending DPRAM irq */ + temp = *(volatile unsigned char *)0xf05003ff; + + /* write module-id into DPRAM */ + *(volatile unsigned char *)0xf0500201 = 0x50; + + return 0; +} + +#if defined(CONFIG_HAVE_OWN_RESET) +int +do_reset (void *cmdtp, int flag, int argc, char *argv[]) +{ + volatile ioport_t *iop; + + iop = ioport_addr((immap_t *)CFG_IMMR, 2); + iop->pdat |= 0x00002000; /* PC18 = HW_RESET */ + return 1; +} +#endif /* CONFIG_HAVE_OWN_RESET */ + +#define ns2clk(ns) (ns / (1000000000 / CONFIG_8260_CLKIN) + 1) + +long int initdram (int board_type) +{ +#ifndef CFG_RAMBOOT + volatile immap_t *immap; + volatile memctl8260_t *memctl; + volatile uchar *ramaddr; + int i; + uchar c; + + immap = (immap_t *) CFG_IMMR; + memctl = &immap->im_memctl; + ramaddr = (uchar *) CFG_SDRAM_BASE; + c = 0xff; + + immap->im_siu_conf.sc_ppc_acr = 0x02; + immap->im_siu_conf.sc_ppc_alrh = 0x01267893; + immap->im_siu_conf.sc_ppc_alrl = 0x89abcdef; + immap->im_siu_conf.sc_tescr1 = 0x00000000; + immap->im_siu_conf.sc_tescr2 = 0x00000000; + + memctl->memc_mptpr = CFG_MPTPR; + memctl->memc_psrt = CFG_PSRT; + memctl->memc_or1 = CFG_OR1_PRELIM; + memctl->memc_br1 = CFG_SDRAM_BASE | CFG_BR1_PRELIM; + + /* Precharge all banks */ + memctl->memc_psdmr = CFG_PSDMR | 0x28000000; + *ramaddr = c; + + /* CBR refresh */ + memctl->memc_psdmr = CFG_PSDMR | 0x08000000; + for (i = 0; i < 8; i++) + *ramaddr = c; + + /* Mode Register write */ + memctl->memc_psdmr = CFG_PSDMR | 0x18000000; + *ramaddr = c; + + /* Refresh enable */ + memctl->memc_psdmr = CFG_PSDMR | 0x40000000; + *ramaddr = c; +#endif /* CFG_RAMBOOT */ + + return (CFG_SDRAM_SIZE); +} + +int checkboard (void) +{ +#ifdef CONFIG_CLKIN_66MHz + puts ("Board: Elmeg VoVPN Gateway Module (66MHz)\n"); +#else + puts ("Board: Elmeg VoVPN Gateway Module (100MHz)\n"); +#endif + return 0; +} |