--- /dev/null
+/*
+ * (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
+ */
+
+/*
+ * Yoo. Jonghoon, IPone, yooth@ipone.co.kr
+ * U-Boot port on RPXlite board
+ *
+ * Some of flash control words are modified. (from 2x16bit device
+ * to 4x8bit device)
+ * RPXLite board I tested has only 4 AM29LV800BB devices. Other devices
+ * are not tested.
+ *
+ * (?) Does an RPXLite board which
+ * does not use AM29LV800 flash memory exist ?
+ * I don't know...
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static int write_word (flash_info_t *info, ulong dest, ulong data);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+/* volatile immap_t *immap = (immap_t *)CFG_IMMR; */
+/* volatile memctl8xx_t *memctl = &immap->im_memctl; */
+ unsigned long size_b0 ;
+ int i;
+
+ /* Init: no FLASHes known */
+ for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+ flash_info[i].flash_id = FLASH_UNKNOWN;
+ }
+
+ /* Static FLASH Bank configuration here - FIXME XXX */
+/*
+ size_b0 = flash_get_size((vu_long *)FLASH_BASE_DEBUG, &flash_info[0]);
+
+ if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+ printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+ size_b0, size_b0<<20);
+ }
+*/
+ /* Remap FLASH according to real size */
+/*%%%
+ memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size_b0 & 0xFFFF8000);
+ memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V;
+%%%*/
+ /* Re-do sizing to get full correct info */
+
+ size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
+ flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]);
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+ /* monitor protection ON by default */
+ flash_protect(FLAG_PROTECT_SET,
+ CFG_MONITOR_BASE,
+ CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
+ &flash_info[0]);
+#endif
+
+ flash_info[0].size = size_b0;
+
+ return (size_b0);
+}
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+ int i;
+
+ /* set up sector start address table */
+ if (info->flash_id & FLASH_BTYPE) {
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00010000;
+ info->start[2] = base + 0x00018000;
+ info->start[3] = base + 0x00020000;
+ for (i = 4; i < info->sector_count; i++) {
+ info->start[i] = base + ((i-3) * 0x00040000) ;
+ }
+ } else {
+ /* set sector offsets for top boot block type */
+ i = info->sector_count - 1;
+ info->start[i--] = base + info->size - 0x00010000;
+ info->start[i--] = base + info->size - 0x00018000;
+ info->start[i--] = base + info->size - 0x00020000;
+ for (; i >= 0; i--) {
+ info->start[i] = base + i * 0x00040000;
+ }
+ }
+
+}
+
+/*-----------------------------------------------------------------------
+ */
+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_AMD: printf ("AMD "); break;
+ case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
+ default: printf ("Unknown Vendor "); break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM320B: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\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 (vu_long *addr, flash_info_t *info)
+{
+ short i;
+ ulong value;
+ ulong base = (ulong)addr;
+
+ /* Write auto select command: read Manufacturer ID */
+ addr[0xAAA] = 0x00AA00AA ;
+ addr[0x555] = 0x00550055 ;
+ addr[0xAAA] = 0x00900090 ;
+
+ value = addr[0] ;
+
+ switch (value & 0x00FF00FF) {
+ case AMD_MANUFACT:
+ info->flash_id = FLASH_MAN_AMD;
+ break;
+ case FUJ_MANUFACT:
+ info->flash_id = FLASH_MAN_FUJ;
+ break;
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ info->sector_count = 0;
+ info->size = 0;
+ return (0); /* no or unknown flash */
+ }
+
+ value = addr[2] ; /* device ID */
+
+ switch (value & 0x00FF00FF) {
+ case (AMD_ID_LV400T & 0x00FF00FF):
+ info->flash_id += FLASH_AM400T;
+ info->sector_count = 11;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case (AMD_ID_LV400B & 0x00FF00FF):
+ info->flash_id += FLASH_AM400B;
+ info->sector_count = 11;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case (AMD_ID_LV800T & 0x00FF00FF):
+ info->flash_id += FLASH_AM800T;
+ info->sector_count = 19;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ case (AMD_ID_LV800B & 0x00FF00FF):
+ info->flash_id += FLASH_AM800B;
+ info->sector_count = 19;
+ info->size = 0x00400000; /*%%% Size doubled by yooth */
+ break; /* => 4 MB */
+
+ case (AMD_ID_LV160T & 0x00FF00FF):
+ info->flash_id += FLASH_AM160T;
+ info->sector_count = 35;
+ info->size = 0x00400000;
+ break; /* => 4 MB */
+
+ case (AMD_ID_LV160B & 0x00FF00FF):
+ info->flash_id += FLASH_AM160B;
+ info->sector_count = 35;
+ info->size = 0x00400000;
+ break; /* => 4 MB */
+#if 0 /* enable when device IDs are available */
+ case AMD_ID_LV320T:
+ info->flash_id += FLASH_AM320T;
+ info->sector_count = 67;
+ info->size = 0x00800000;
+ break; /* => 8 MB */
+
+ case AMD_ID_LV320B:
+ info->flash_id += FLASH_AM320B;
+ info->sector_count = 67;
+ info->size = 0x00800000;
+ break; /* => 8 MB */
+#endif
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ return (0); /* => no or unknown flash */
+
+ }
+ /*%%% sector start address modified */
+ /* set up sector start address table */
+ if (info->flash_id & FLASH_BTYPE) {
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00010000;
+ info->start[2] = base + 0x00018000;
+ info->start[3] = base + 0x00020000;
+ for (i = 4; i < info->sector_count; i++) {
+ info->start[i] = base + ((i-3) * 0x00040000) ;
+ }
+ } else {
+ /* set sector offsets for top boot block type */
+ i = info->sector_count - 1;
+ info->start[i--] = base + info->size - 0x00010000;
+ info->start[i--] = base + info->size - 0x00018000;
+ info->start[i--] = base + info->size - 0x00020000;
+ for (; i >= 0; i--) {
+ info->start[i] = base + i * 0x00040000;
+ }
+ }
+
+ /* check for protected sectors */
+ for (i = 0; i < info->sector_count; i++) {
+ /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+ /* D0 = 1 if protected */
+ addr = (volatile unsigned long *)(info->start[i]);
+ info->protect[i] = addr[4] & 1 ;
+ }
+
+ /*
+ * Prevent writes to uninitialized FLASH.
+ */
+ if (info->flash_id != FLASH_UNKNOWN) {
+ addr = (volatile unsigned long *)info->start[0];
+
+ *addr = 0xF0F0F0F0; /* reset bank */
+ }
+
+ return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+ vu_long *addr = (vu_long*)(info->start[0]);
+ int flag, prot, sect, l_sect;
+ ulong start, now, last;
+
+ if ((s_first < 0) || (s_first > s_last)) {
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("- missing\n");
+ } else {
+ printf ("- no sectors to erase\n");
+ }
+ return 1;
+ }
+
+ if ((info->flash_id == FLASH_UNKNOWN) ||
+ (info->flash_id > FLASH_AMD_COMP)) {
+ 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");
+ }
+
+ l_sect = -1;
+
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ addr[0xAAA] = 0xAAAAAAAA;
+ addr[0x555] = 0x55555555;
+ addr[0xAAA] = 0x80808080;
+ addr[0xAAA] = 0xAAAAAAAA;
+ addr[0x555] = 0x55555555;
+
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect<=s_last; sect++) {
+ if (info->protect[sect] == 0) { /* not protected */
+ addr = (vu_long *)(info->start[sect]) ;
+ addr[0] = 0x30303030 ;
+ l_sect = sect;
+ }
+ }
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* wait at least 80us - let's wait 1 ms */
+ udelay (1000);
+
+ /*
+ * We wait for the last triggered sector
+ */
+ if (l_sect < 0)
+ goto DONE;
+
+ start = get_timer (0);
+ last = start;
+ addr = (vu_long *)(info->start[l_sect]);
+ while ((addr[0] & 0x80808080) != 0x80808080) {
+ if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+ printf ("Timeout\n");
+ return 1;
+ }
+ /* show that we're waiting */
+ if ((now - last) > 1000) { /* every second */
+ putc ('.');
+ last = now;
+ }
+ }
+
+DONE:
+ /* reset to read mode */
+ addr = (vu_long *)info->start[0];
+ addr[0] = 0xF0F0F0F0; /* reset bank */
+
+ printf (" done\n");
+ return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+ ulong cp, wp, data;
+ int i, l, rc;
+
+ wp = (addr & ~3); /* get lower word aligned address */
+
+ /*
+ * handle unaligned start bytes
+ */
+ if ((l = addr - wp) != 0) {
+ data = 0;
+ for (i=0, cp=wp; i<l; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+ for (; i<4 && cnt>0; ++i) {
+ data = (data << 8) | *src++;
+ --cnt;
+ ++cp;
+ }
+ for (; cnt==0 && i<4; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ }
+
+ /*
+ * handle word aligned part
+ */
+ while (cnt >= 4) {
+ data = 0;
+ for (i=0; i<4; ++i) {
+ data = (data << 8) | *src++;
+ }
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ cnt -= 4;
+ }
+
+ if (cnt == 0) {
+ return (0);
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+ data = (data << 8) | *src++;
+ --cnt;
+ }
+ for (; i<4; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+
+ return (write_word(info, wp, data));
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+ vu_long *addr = (vu_long *)(info->start[0]);
+ ulong start;
+ int flag;
+
+ /* Check if Flash is (sufficiently) erased */
+ if ((*((vu_long *)dest) & data) != data) {
+ return (2);
+ }
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ addr[0xAAA] = 0xAAAAAAAA;
+ addr[0x555] = 0x55555555;
+ addr[0xAAA] = 0xA0A0A0A0;
+
+ *((vu_long *)dest) = data;
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* data polling for D7 */
+ start = get_timer (0);
+ while ((*((vu_long *)dest) & 0x80808080) != (data & 0x80808080)) {
+ if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+ return (1);
+ }
+ }
+ return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
--- /dev/null
+/* most of this is taken from the file */
+/* hal/powerpc/cogent/current/src/hal_diag.c in the */
+/* Cygnus eCos source. Here is the copyright notice: */
+/* */
+/*============================================================================= */
+/* */
+/* hal_diag.c */
+/* */
+/* HAL diagnostic output code */
+/* */
+/*============================================================================= */
+/*####COPYRIGHTBEGIN#### */
+/* */
+/* ------------------------------------------- */
+/* The contents of this file are subject to the Cygnus eCos Public License */
+/* Version 1.0 (the "License"); you may not use this file except in */
+/* compliance with the License. You may obtain a copy of the License at */
+/* http://sourceware.cygnus.com/ecos */
+/* */
+/* Software distributed under the License is distributed on an "AS IS" */
+/* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the */
+/* License for the specific language governing rights and limitations under */
+/* the License. */
+/* */
+/* The Original Code is eCos - Embedded Cygnus Operating System, released */
+/* September 30, 1998. */
+/* */
+/* The Initial Developer of the Original Code is Cygnus. Portions created */
+/* by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. */
+/* ------------------------------------------- */
+/* */
+/*####COPYRIGHTEND#### */
+/*============================================================================= */
+/*#####DESCRIPTIONBEGIN#### */
+/* */
+/* Author(s): nickg, jskov */
+/* Contributors: nickg, jskov */
+/* Date: 1999-03-23 */
+/* Purpose: HAL diagnostic output */
+/* Description: Implementations of HAL diagnostic output support. */
+/* */
+/*####DESCRIPTIONEND#### */
+/* */
+/*============================================================================= */
+
+/*----------------------------------------------------------------------------- */
+/* Cogent board specific LCD code */
+
+#include <common.h>
+#include <stdarg.h>
+#include <board/cogent/lcd.h>
+
+static char lines[2][LCD_LINE_LENGTH+1];
+static int curline;
+static int linepos;
+static int heartbeat_active;
+/* make the next two strings exactly LCD_LINE_LENGTH (16) chars long */
+/* pad to the right with spaces if necessary */
+static char init_line0[LCD_LINE_LENGTH+1] = "U-Boot Cogent ";
+static char init_line1[LCD_LINE_LENGTH+1] = "mjj, 11 Aug 2000";
+
+static inline unsigned char
+lcd_read_status(cma_mb_lcd *clp)
+{
+ /* read the Busy Status Register */
+ return (cma_mb_reg_read(&clp->lcd_bsr));
+}
+
+static inline void
+lcd_wait_not_busy(cma_mb_lcd *clp)
+{
+ /*
+ * wait for not busy
+ * Note: It seems that the LCD isn't quite ready to process commands
+ * when it clears the BUSY flag. Reading the status address an extra
+ * time seems to give it enough breathing room.
+ */
+
+ while (lcd_read_status(clp) & LCD_STAT_BUSY)
+ ;
+
+ (void)lcd_read_status(clp);
+}
+
+static inline void
+lcd_write_command(cma_mb_lcd *clp, unsigned char cmd)
+{
+ lcd_wait_not_busy(clp);
+
+ /* write the Command Register */
+ cma_mb_reg_write(&clp->lcd_cmd, cmd);
+}
+
+static inline void
+lcd_write_data(cma_mb_lcd *clp, unsigned char data)
+{
+ lcd_wait_not_busy(clp);
+
+ /* write the Current Character Register */
+ cma_mb_reg_write(&clp->lcd_ccr, data);
+}
+
+static inline void
+lcd_dis(int addr, char *string)
+{
+ cma_mb_lcd *clp = (cma_mb_lcd *)CMA_MB_LCD_BASE;
+ int pos, linelen;
+
+ linelen = LCD_LINE_LENGTH;
+ if (heartbeat_active && addr == LCD_LINE0)
+ linelen--;
+
+ lcd_write_command(clp, LCD_CMD_ADD + addr);
+ for (pos = 0; *string != '\0' && pos < linelen; pos++)
+ lcd_write_data(clp, *string++);
+}
+
+void
+lcd_init(void)
+{
+ cma_mb_lcd *clp = (cma_mb_lcd *)CMA_MB_LCD_BASE;
+ int i;
+
+ /* configure the lcd for 8 bits/char, 2 lines and 5x7 dot matrix */
+ lcd_write_command(clp, LCD_CMD_MODE);
+
+ /* turn the LCD display on */
+ lcd_write_command(clp, LCD_CMD_DON);
+
+ curline = 0;
+ linepos = 0;
+
+ for (i = 0; i < LCD_LINE_LENGTH; i++) {
+ lines[0][i] = init_line0[i];
+ lines[1][i] = init_line1[i];
+ }
+
+ lines[0][LCD_LINE_LENGTH] = lines[1][LCD_LINE_LENGTH] = 0;
+
+ lcd_dis(LCD_LINE0, lines[0]);
+ lcd_dis(LCD_LINE1, lines[1]);
+
+ printf("HD44780 2 line x %d char display\n", LCD_LINE_LENGTH);
+}
+
+void
+lcd_write_char(const char c)
+{
+ int i, linelen;
+
+ /* ignore CR */
+ if (c == '\r')
+ return;
+
+ linelen = LCD_LINE_LENGTH;
+ if (heartbeat_active && curline == 0)
+ linelen--;
+
+ if (c == '\n') {
+ lcd_dis(LCD_LINE0, &lines[curline^1][0]);
+ lcd_dis(LCD_LINE1, &lines[curline][0]);
+
+ /* Do a line feed */
+ curline ^= 1;
+ linelen = LCD_LINE_LENGTH;
+ if (heartbeat_active && curline == 0)
+ linelen--;
+ linepos = 0;
+
+ for (i = 0; i < linelen; i++)
+ lines[curline][i] = ' ';
+
+ return;
+ }
+
+ /* Only allow to be output if there is room on the LCD line */
+ if (linepos < linelen)
+ lines[curline][linepos++] = c;
+}
+
+void
+lcd_flush(void)
+{
+ lcd_dis(LCD_LINE1, &lines[curline][0]);
+}
+
+void
+lcd_write_string(const char *s)
+{
+ char *p;
+
+ for (p = (char *)s; *p != '\0'; p++)
+ lcd_write_char(*p);
+}
+
+void
+lcd_printf(const char *fmt, ...)
+{
+ va_list args;
+ char buf[CFG_PBSIZE];
+
+ va_start(args, fmt);
+ (void)vsprintf(buf, fmt, args);
+ va_end(args);
+
+ lcd_write_string(buf);
+}
+
+void
+lcd_heartbeat(void)
+{
+ cma_mb_lcd *clp = (cma_mb_lcd *)CMA_MB_LCD_BASE;
+#if 0
+ static char rotchars[] = { '|', '/', '-', '\\' };
+#else
+ /* HD44780 Rom Code A00 has no backslash */
+ static char rotchars[] = { '|', '/', '-', '\315' };
+#endif
+ static int rotator_index = 0;
+
+ heartbeat_active = 1;
+
+ /* write the address */
+ lcd_write_command(clp, LCD_CMD_ADD + LCD_LINE0 + (LCD_LINE_LENGTH - 1));
+
+ /* write the next char in the sequence */
+ lcd_write_data(clp, rotchars[rotator_index]);
+
+ if (++rotator_index >= (sizeof rotchars / sizeof rotchars[0]))
+ rotator_index = 0;
+}
--- /dev/null
+/* most of this is taken from the file */
+/* hal/powerpc/cogent/current/src/hal_diag.c in the */
+/* Cygnus eCos source. Here is the copyright notice: */
+/* */
+/*============================================================================= */
+/* */
+/* hal_diag.c */
+/* */
+/* HAL diagnostic output code */
+/* */
+/*============================================================================= */
+/*####COPYRIGHTBEGIN#### */
+/* */
+/* ------------------------------------------- */
+/* The contents of this file are subject to the Cygnus eCos Public License */
+/* Version 1.0 (the "License"); you may not use this file except in */
+/* compliance with the License. You may obtain a copy of the License at */
+/* http://sourceware.cygnus.com/ecos */
+/* */
+/* Software distributed under the License is distributed on an "AS IS" */
+/* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the */
+/* License for the specific language governing rights and limitations under */
+/* the License. */
+/* */
+/* The Original Code is eCos - Embedded Cygnus Operating System, released */
+/* September 30, 1998. */
+/* */
+/* The Initial Developer of the Original Code is Cygnus. Portions created */
+/* by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. */
+/* ------------------------------------------- */
+/* */
+/*####COPYRIGHTEND#### */
+/*============================================================================= */
+/*#####DESCRIPTIONBEGIN#### */
+/* */
+/* Author(s): nickg, jskov */
+/* Contributors: nickg, jskov */
+/* Date: 1999-03-23 */
+/* Purpose: HAL diagnostic output */
+/* Description: Implementations of HAL diagnostic output support. */
+/* */
+/*####DESCRIPTIONEND#### */
+/* */
+/*============================================================================= */
+
+/* FEMA 162B 16 character x 2 line LCD */
+
+/* status register bit definitions */
+#define LCD_STAT_BUSY 0x80 /* 1 = display busy */
+#define LCD_STAT_ADD 0x7F /* bits 0-6 return current display address */
+
+/* command register definitions */
+#define LCD_CMD_RST 0x01 /* clear entire display and reset display addr */
+#define LCD_CMD_HOME 0x02 /* reset display address and reset any shifting */
+#define LCD_CMD_ECL 0x04 /* move cursor left one pos on next data write */
+#define LCD_CMD_ESL 0x05 /* shift display left one pos on next data write */
+#define LCD_CMD_ECR 0x06 /* move cursor right one pos on next data write */
+#define LCD_CMD_ESR 0x07 /* shift disp right one pos on next data write */
+#define LCD_CMD_DOFF 0x08 /* display off, cursor off, blinking off */
+#define LCD_CMD_BL 0x09 /* blink character at current cursor position */
+#define LCD_CMD_CUR 0x0A /* enable cursor on */
+#define LCD_CMD_DON 0x0C /* turn display on */
+#define LCD_CMD_CL 0x10 /* move cursor left one position */
+#define LCD_CMD_SL 0x14 /* shift display left one position */
+#define LCD_CMD_CR 0x18 /* move cursor right one position */
+#define LCD_CMD_SR 0x1C /* shift display right one position */
+#define LCD_CMD_MODE 0x38 /* sets 8 bits, 2 lines, 5x7 characters */
+#define LCD_CMD_ACG 0x40 /* bits 0-5 sets character generator address */
+#define LCD_CMD_ADD 0x80 /* bits 0-6 sets display data addr to line 1 + */
+
+/* LCD status values */
+#define LCD_OK 0x00
+#define LCD_ERR 0x01
+
+#define LCD_LINE0 0x00
+#define LCD_LINE1 0x40
+
+#define LCD_LINE_LENGTH 16
+
+extern void lcd_init(void);
+extern void lcd_write_char(const char);
+extern void lcd_flush(void);
+extern void lcd_write_string(const char *);
+extern void lcd_printf(const char *, ...);
--- /dev/null
+/*
+ * (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
+ */
+
+/*
+ * Modified 4/5/2001
+ * Wait for completion of each sector erase command issued
+ * 4/5/2001
+ * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
+ */
+
+/*
+ * Modified July 20, 2001
+ * Strip down to support ONLY the AMD29F032B.
+ * Dave Updegraff - Cray, Inc. dave@cray.com
+ */
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+
+/* The flash chip we use... */
+#define AMD_ID_F032B 0x41 /* 29F032B ID 32 Mbit,64 64Kx8 sectors */
+#define FLASH_AM320B 0x0009
+
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static int write_word (flash_info_t *info, ulong dest, ulong data);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+#define ADDR0 0x5555
+#define ADDR1 0x2aaa
+#define FLASH_WORD_SIZE unsigned char
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+ unsigned long size_b0, size_b1;
+ int i;
+
+ /* Init: no FLASHes known */
+ for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+ flash_info[i].flash_id = FLASH_UNKNOWN;
+ }
+
+ /* Static FLASH Bank configuration here - FIXME XXX */
+
+ size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
+
+ if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+ printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+ size_b0, size_b0<<20);
+ }
+
+ /* Only one bank */
+ if (CFG_MAX_FLASH_BANKS == 1)
+ {
+ /* Setup offsets */
+ flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]);
+
+#if 0
+ /* Monitor protection ON by default */
+ (void)flash_protect(FLAG_PROTECT_SET,
+ FLASH_BASE0_PRELIM,
+ FLASH_BASE0_PRELIM+CFG_MONITOR_LEN-1,
+ &flash_info[0]);
+#endif
+ size_b1 = 0 ;
+ flash_info[0].size = size_b0;
+ }
+
+ return (size_b0 + size_b1);
+}
+
+
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+ int i;
+
+ /* set up sector start address table */
+ for (i = 0; i < info->sector_count; i++)
+ info->start[i] = base + (i * 0x00010000);
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t *info)
+{
+ int i;
+ int k;
+ int size;
+ int erased;
+ volatile unsigned long *flash;
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("missing or unknown FLASH type\n");
+ return;
+ }
+
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case FLASH_MAN_AMD: printf ("AMD "); break;
+ default: printf ("Unknown Vendor "); break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_AM320B:printf ("AM29F032B (32 Mbit 64x64KB uniform sectors)\n");
+ break;
+ default: printf ("Unknown Chip Type\n");
+ break;
+ }
+
+ 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) {
+ /*
+ * Check if whole sector is erased
+ */
+ if (i != (info->sector_count-1))
+ size = info->start[i+1] - info->start[i];
+ else
+ size = info->start[0] + info->size - info->start[i];
+ erased = 1;
+ flash = (volatile unsigned long *)info->start[i];
+ size = size >> 2; /* divide by 4 for longword access */
+ for (k=0; k<size; k++)
+ {
+ if (*flash++ != 0xffffffff)
+ {
+ erased = 0;
+ break;
+ }
+ }
+
+ if ((i % 5) == 0)
+ printf ("\n ");
+
+ printf (" %08lX%s%s",
+ info->start[i],
+ erased ? " E" : " ",
+ info->protect[i] ? "RO " : " "
+ );
+ }
+ printf ("\n");
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info)
+{
+ short i;
+ FLASH_WORD_SIZE value;
+ ulong base = (ulong)addr;
+ volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr;
+
+ /* Write auto select command: read Manufacturer ID */
+ addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ addr2[ADDR0] = (FLASH_WORD_SIZE)0x00900090;
+
+ value = addr2[0];
+
+ switch (value) {
+ case (FLASH_WORD_SIZE)AMD_MANUFACT:
+ info->flash_id = FLASH_MAN_AMD;
+ break;
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ info->sector_count = 0;
+ info->size = 0;
+ return (0); /* no or unknown flash */
+ }
+
+ value = addr2[1]; /* device ID */
+
+ switch (value) {
+ case (FLASH_WORD_SIZE)AMD_ID_F032B:
+ info->flash_id += FLASH_AM320B;
+ info->sector_count = 64;
+ info->size = 0x0400000; /* => 4 MB */
+ break;
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ return (0); /* => no or unknown flash */
+
+ }
+
+ /* set up sector start address table */
+ for (i = 0; i < info->sector_count; i++)
+ info->start[i] = base + (i * 0x00010000);
+
+ /* check for protected sectors */
+ for (i = 0; i < info->sector_count; i++) {
+ /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+ /* D0 = 1 if protected */
+ addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]);
+ info->protect[i] = addr2[2] & 1;
+ }
+
+ /*
+ * Prevent writes to uninitialized FLASH.
+ */
+ if (info->flash_id != FLASH_UNKNOWN) {
+ addr2 = (FLASH_WORD_SIZE *)info->start[0];
+ *addr2 = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
+ }
+
+ return (info->size);
+}
+
+int wait_for_DQ7(flash_info_t *info, int sect)
+{
+ ulong start, now, last;
+ volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]);
+
+ start = get_timer (0);
+ last = start;
+ while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
+ if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+ printf ("Timeout\n");
+ return -1;
+ }
+ /* show that we're waiting */
+ if ((now - last) > 1000) { /* every second */
+ putc ('.');
+ last = now;
+ }
+ }
+ return 0;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+ volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]);
+ volatile FLASH_WORD_SIZE *addr2;
+ int flag, prot, sect, l_sect;
+
+ 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 ("Can't erase unknown flash type - 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");
+ }
+
+ l_sect = -1;
+
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect<=s_last; sect++) {
+ if (info->protect[sect] == 0) { /* not protected */
+ addr2 = (FLASH_WORD_SIZE *)(info->start[sect]);
+ printf("Erasing sector %p\n", addr2);
+
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ addr2[0] = (FLASH_WORD_SIZE)0x00300030; /* sector erase */
+ l_sect = sect;
+ /*
+ * Wait for each sector to complete, it's more
+ * reliable. According to AMD Spec, you must
+ * issue all erase commands within a specified
+ * timeout. This has been seen to fail, especially
+ * if printf()s are included (for debug)!!
+ */
+ wait_for_DQ7(info, sect);
+ }
+ }
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* wait at least 80us - let's wait 1 ms */
+ udelay (1000);
+
+ /* reset to read mode */
+ addr = (FLASH_WORD_SIZE *)info->start[0];
+ addr[0] = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
+
+ printf (" done\n");
+ return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+ ulong cp, wp, data;
+ int i, l, rc;
+
+ wp = (addr & ~3); /* get lower word aligned address */
+
+ /*
+ * handle unaligned start bytes
+ */
+ if ((l = addr - wp) != 0) {
+ data = 0;
+ for (i=0, cp=wp; i<l; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+ for (; i<4 && cnt>0; ++i) {
+ data = (data << 8) | *src++;
+ --cnt;
+ ++cp;
+ }
+ for (; cnt==0 && i<4; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ }
+
+ /*
+ * handle word aligned part
+ */
+ while (cnt >= 4) {
+ data = 0;
+ for (i=0; i<4; ++i) {
+ data = (data << 8) | *src++;
+ }
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ cnt -= 4;
+ }
+
+ if (cnt == 0) {
+ return (0);
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+ data = (data << 8) | *src++;
+ --cnt;
+ }
+ for (; i<4; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+
+ return (write_word(info, wp, data));
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+ volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)(info->start[0]);
+ volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *)dest;
+ volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *)&data;
+ ulong start;
+ int flag;
+ int i;
+
+ /* Check if Flash is (sufficiently) erased */
+ if ((*((volatile FLASH_WORD_SIZE *)dest) &
+ (FLASH_WORD_SIZE)data) != (FLASH_WORD_SIZE)data) {
+ return (2);
+ }
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ for (i=0; i<4/sizeof(FLASH_WORD_SIZE); i++)
+ {
+ addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ addr2[ADDR0] = (FLASH_WORD_SIZE)0x00A000A0;
+
+ dest2[i] = data2[i];
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* data polling for D7 */
+ start = get_timer (0);
+ while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) !=
+ (data2[i] & (FLASH_WORD_SIZE)0x00800080)) {
+ if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+ return (1);
+ }
+ }
+ }
+
+ return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
--- /dev/null
+/*------------------------------------------------------------------------------+ */
+/* */
+/* This source code has been made available to you by IBM on an AS-IS */
+/* basis. Anyone receiving this source is licensed under IBM */
+/* copyrights to use it in any way he or she deems fit, including */
+/* copying it, modifying it, compiling it, and redistributing it either */
+/* with or without modifications. No license under IBM patents or */
+/* patent applications is to be implied by the copyright license. */
+/* */
+/* Any user of this software should understand that IBM cannot provide */
+/* technical support for this software and will not be responsible for */
+/* any consequences resulting from the use of this software. */
+/* */
+/* Any person who transfers this source code or any derivative work */
+/* must include the IBM copyright notice, this paragraph, and the */
+/* preceding two paragraphs in the transferred software. */
+/* */
+/* COPYRIGHT I B M CORPORATION 1995 */
+/* LICENSED MATERIAL - PROGRAM PROPERTY OF I B M */
+/*------------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------- */
+/* Function: ext_bus_cntlr_init */
+/* Description: Initializes the External Bus Controller for the external */
+/* peripherals. IMPORTANT: For pass1 this code must run from */
+/* cache since you can not reliably change a peripheral banks */
+/* timing register (pbxap) while running code from that bank. */
+/* For ex., since we are running from ROM on bank 0, we can NOT */
+/* execute the code that modifies bank 0 timings from ROM, so */
+/* we run it from cache. */
+/* Bank 0 - Flash and SRAM */
+/* Bank 1 - NVRAM/RTC */
+/* Bank 2 - Keyboard/Mouse controller */
+/* Bank 3 - IR controller */
+/* Bank 4 - not used */
+/* Bank 5 - not used */
+/* Bank 6 - not used */
+/* Bank 7 - FPGA registers */
+/*-----------------------------------------------------------------------------#include <config.h> */
+#include <ppc4xx.h>
+
+#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+/* CRAY - L1: only nominally a 'walnut', since ext.Bus.Cntlr is all empty */
+/* except for #1 which we use for DMA'ing to IOCA-like things, so the */
+/* control registers to set that up are determined by what we've */
+/* empirically discovered work there. */
+
+ .globl ext_bus_cntlr_init
+ext_bus_cntlr_init:
+ mflr r4 /* save link register */
+ bl ..getAddr
+..getAddr:
+ mflr r3 /* get address of ..getAddr */
+ mtlr r4 /* restore link register */
+ addi r4,0,14 /* set ctr to 10; used to prefetch */
+ mtctr r4 /* 10 cache lines to fit this function */
+ /* in cache (gives us 8x10=80 instrctns) */
+..ebcloop:
+ icbt r0,r3 /* prefetch cache line for addr in r3 */
+ addi r3,r3,32 /* move to next cache line */
+ bdnz ..ebcloop /* continue for 10 cache lines */
+
+ /*------------------------------------------------------------------- */
+ /* Delay to ensure all accesses to ROM are complete before changing */
+ /* bank 0 timings. 200usec should be enough. */
+ /* 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles */
+ /*------------------------------------------------------------------- */
+ addis r3,0,0x0
+ ori r3,r3,0xA000 /* ensure 200usec have passed since reset */
+ mtctr r3
+..spinlp:
+ bdnz ..spinlp /* spin loop */
+
+
+ /*---------------------------------------------------------------------- */
+ /* Peripheral Bank 0 (Flash) initialization */
+ /*---------------------------------------------------------------------- */
+ /* 0x7F8FFE80 slowest boot */
+ addi r4,0,pb0ap
+ mtdcr ebccfga,r4
+ addis r4,0,0x9B01
+ ori r4,r4,0x5480
+ mtdcr ebccfgd,r4
+
+ addi r4,0,pb0cr
+ mtdcr ebccfga,r4
+ addis r4,0,0xFFC5 /* BAS=0xFFC,BS=0x4(4MB),BU=0x3(R/W), */
+ ori r4,r4,0x8000 /* BW=0x0( 8 bits) */
+ mtdcr ebccfgd,r4
+
+ blr
+
+ /*---------------------------------------------------------------------- */
+ /* Peripheral Bank 1 (NVRAM/RTC) initialization */
+ /* CRAY:the L1 has NOT this bank, it is tied to SV2/IOCA/etc/ instead */
+ /* and we do DMA on it. The ConfigurationRegister part is threfore */
+ /* almost arbitrary, except that our linux driver needs to know the */
+ /* address, but it can query, it.. */
+ /* */
+ /* The AccessParameter is CRITICAL, */
+ /* thouch, since it needs to agree with the electrical timings on the */
+ /* IOCA parallel interface. That value is: 0x0185,4380 */
+ /* BurstModeEnable BME=0 */
+ /* TransferWait TWT=3 */
+ /* ChipSelectOnTiming CSN=1 */
+ /* OutputEnableOnTimimg OEN=1 */
+ /* WriteByteEnableOnTiming WBN=1 */
+ /* WriteByteEnableOffTiming WBF=0 */
+ /* TransferHold TH=1 */
+ /* ReadyEnable RE=1 */
+ /* SampleOnReady SOR=1 */
+ /* ByteEnableMode BEM=0 */
+ /* ParityEnable PEN=0 */
+ /* all reserved bits=0 */
+ /*---------------------------------------------------------------------- */
+ /*---------------------------------------------------------------------- */
+ addi r4,0,pb1ap
+ mtdcr ebccfga,r4
+ addis r4,0,0x0185 /* hiword */
+ ori r4,r4,0x4380 /* loword */
+ mtdcr ebccfgd,r4
+
+ addi r4,0,pb1cr
+ mtdcr ebccfga,r4
+ addis r4,0,0xF001 /* BAS=0xF00,BS=0x0(1MB),BU=0x3(R/W), */
+ ori r4,r4,0x8000 /* BW=0x0( 8 bits) */
+ mtdcr ebccfgd,r4
+
+ blr
+
+/*----------------------------------------------------------------------------- */
+/* Function: sdram_init */
+/* Description: Configures SDRAM memory banks. */
+/* NOTE: for CrayL1 we have ECC memory, so enable it. */
+/*....now done in C in L1.c:init_sdram for readability. */
+/*----------------------------------------------------------------------------- */
+ .globl sdram_init
+
+sdram_init:
+ blr
--- /dev/null
+#
+# DNP/1110 board with SA1100 cpu
+#
+# http://www.dilnetpc.com
+#
+
+#
+# DILNETPC has 1 banks of 32 MB DRAM
+#
+# c000'0000
+#
+# Linux-Kernel is expected to be at c000'8000, entry c000'8000
+#
+# we load ourself to c1f0'0000, the upper 1 MB of the first (only) bank
+#
+
+TEXT_BASE = 0xc1f00000
--- /dev/null
+/*
+ * Memory Setup stuff - taken from blob memsetup.S
+ *
+ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
+ * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
+ *
+ * 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>
+
+
+/* some parameters for the board */
+
+MEM_BASE: .long 0xa0000000
+MEM_START: .long 0xc0000000
+
+#define MDCNFG 0x00
+#define MDCAS0 0x04
+#define MDCAS1 0x08
+#define MDCAS2 0x0c
+#define MSC0 0x10
+#define MSC1 0x14
+#define MECR 0x18
+
+mdcas0: .long 0xc71c703f
+mdcas1: .long 0xffc71c71
+mdcas2: .long 0xffffffff
+/* mdcnfg: .long 0x0bb2bcbf */
+mdcnfg: .long 0x0334b22f @ alt
+/* mcs0: .long 0xfff8fff8 */
+msc0: .long 0xad8c4888 @ alt
+mecr: .long 0x00060006
+/* mecr: .long 0x994a994a @ alt */
+
+/* setting up the memory */
+
+.globl memsetup
+memsetup:
+ ldr r0, MEM_BASE
+
+ /* Setup the flash memory */
+ ldr r1, msc0
+ str r1, [r0, #MSC0]
+
+ /* Set up the DRAM */
+
+ /* MDCAS0 */
+ ldr r1, mdcas0
+ str r1, [r0, #MDCAS0]
+
+ /* MDCAS1 */
+ ldr r1, mdcas1
+ str r1, [r0, #MDCAS1]
+
+ /* MDCAS2 */
+ ldr r1, mdcas2
+ str r1, [r0, #MDCAS2]
+
+ /* MDCNFG */
+ ldr r1, mdcnfg
+ str r1, [r0, #MDCNFG]
+
+ /* Set up PCMCIA space */
+ ldr r1, mecr
+ str r1, [r0, #MECR]
+
+ /* Load something to activate bank */
+ ldr r1, MEM_START
+
+.rept 8
+ ldr r0, [r1]
+.endr
+
+ /* everything is fine now */
+ mov pc, lr
+
--- /dev/null
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002 Jun Gu <jung@artesyncp.com>
+ * Add support for Am29F016D and dynamic switch setting.
+ *
+ * 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
+ */
+
+/*
+ * Modified 4/5/2001
+ * Wait for completion of each sector erase command issued
+ * 4/5/2001
+ * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
+ */
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+
+
+#undef DEBUG
+#ifdef DEBUG
+#define DEBUGF(x...) printf(x)
+#else
+#define DEBUGF(x...)
+#endif /* DEBUG */
+
+#define BOOT_SMALL_FLASH 32 /* 00100000 */
+#define FLASH_ONBD_N 2 /* 00000010 */
+#define FLASH_SRAM_SEL 1 /* 00000001 */
+
+#define BOOT_SMALL_FLASH_VAL 4
+#define FLASH_ONBD_N_VAL 2
+#define FLASH_SRAM_SEL_VAL 1
+
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
+
+static unsigned long flash_addr_table[8][CFG_MAX_FLASH_BANKS] = {
+ {0xffc00000, 0xffe00000, 0xff880000}, /* 0:000: configuraton 3 */
+ {0xffc00000, 0xffe00000, 0xff800000}, /* 1:001: configuraton 4 */
+ {0xffc00000, 0xffe00000, 0x00000000}, /* 2:010: configuraton 7 */
+ {0xffc00000, 0xffe00000, 0x00000000}, /* 3:011: configuraton 8 */
+ {0xff800000, 0xffa00000, 0xfff80000}, /* 4:100: configuraton 1 */
+ {0xff800000, 0xffa00000, 0xfff00000}, /* 5:101: configuraton 2 */
+ {0xffc00000, 0xffe00000, 0x00000000}, /* 6:110: configuraton 5 */
+ {0xffc00000, 0xffe00000, 0x00000000} /* 7:111: configuraton 6 */
+};
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static int write_word (flash_info_t *info, ulong dest, ulong data);
+#if 0
+static void flash_get_offsets (ulong base, flash_info_t *info);
+#endif
+
+#ifdef CONFIG_ADCIOP
+#define ADDR0 0x0aa9
+#define ADDR1 0x0556
+#define FLASH_WORD_SIZE unsigned char
+#endif
+
+#ifdef CONFIG_CPCI405
+#define ADDR0 0x5555
+#define ADDR1 0x2aaa
+#define FLASH_WORD_SIZE unsigned short
+#endif
+
+#ifdef CONFIG_WALNUT405
+#define ADDR0 0x5555
+#define ADDR1 0x2aaa
+#define FLASH_WORD_SIZE unsigned char
+#endif
+
+#ifdef CONFIG_EBONY
+#define ADDR0 0x5555
+#define ADDR1 0x2aaa
+#define FLASH_WORD_SIZE unsigned char
+#endif
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void) {
+ unsigned long total_b = 0;
+ unsigned long size_b[CFG_MAX_FLASH_BANKS];
+ unsigned char * fpga_base = (unsigned char *)CFG_FPGA_BASE;
+ unsigned char switch_status;
+ unsigned short index = 0;
+ int i;
+
+
+ /* read FPGA base register FPGA_REG0 */
+ switch_status = *fpga_base;
+
+ /* check the bitmap of switch status */
+ if (switch_status & BOOT_SMALL_FLASH) {
+ index += BOOT_SMALL_FLASH_VAL;
+ }
+ if (switch_status & FLASH_ONBD_N) {
+ index += FLASH_ONBD_N_VAL;
+ }
+ if (switch_status & FLASH_SRAM_SEL) {
+ index += FLASH_SRAM_SEL_VAL;
+ }
+
+ DEBUGF("\n");
+ DEBUGF("FLASH: Index: %d\n", index);
+
+ /* Init: no FLASHes known */
+ for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+ flash_info[i].flash_id = FLASH_UNKNOWN;
+ flash_info[i].sector_count = -1;
+ flash_info[i].size = 0;
+
+ /* check whether the address is 0 */
+ if (flash_addr_table[index][i] == 0) {
+ continue;
+ }
+
+ /* call flash_get_size() to initialize sector address */
+ size_b[i] = flash_get_size(
+ (vu_long *)flash_addr_table[index][i], &flash_info[i]);
+ flash_info[i].size = size_b[i];
+ if (flash_info[i].flash_id == FLASH_UNKNOWN) {
+ printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
+ i, size_b[i], size_b[i]<<20);
+ flash_info[i].sector_count = -1;
+ flash_info[i].size = 0;
+ }
+
+ total_b += flash_info[i].size;
+ }
+
+ return total_b;
+}
+
+
+
+/*-----------------------------------------------------------------------
+ */
+#if 0
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+ int i;
+
+ /* set up sector start address table */
+ if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
+ (info->flash_id == FLASH_AM040) ||
+ (info->flash_id == FLASH_AMD016)) {
+ for (i = 0; i < info->sector_count; i++)
+ info->start[i] = base + (i * 0x00010000);
+ } else {
+ if (info->flash_id & FLASH_BTYPE) {
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00004000;
+ info->start[2] = base + 0x00006000;
+ info->start[3] = base + 0x00008000;
+ for (i = 4; i < info->sector_count; i++) {
+ info->start[i] = base + (i * 0x00010000) - 0x00030000;
+ }
+ } else {
+ /* set sector offsets for top boot block type */
+ i = info->sector_count - 1;
+ info->start[i--] = base + info->size - 0x00004000;
+ info->start[i--] = base + info->size - 0x00006000;
+ info->start[i--] = base + info->size - 0x00008000;
+ for (; i >= 0; i--) {
+ info->start[i] = base + i * 0x00010000;
+ }
+ }
+ }
+}
+#endif /* 0 */
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t *info)
+{
+ int i;
+ int k;
+ int size;
+ int erased;
+ volatile unsigned long *flash;
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("missing or unknown FLASH type\n");
+ return;
+ }
+
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case FLASH_MAN_AMD: printf ("AMD "); break;
+ case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
+ case FLASH_MAN_SST: printf ("SST "); break;
+ default: printf ("Unknown Vendor "); break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_AMD016: printf ("AM29F016D (16 Mbit, uniform sector size)\n");
+ break;
+ case FLASH_AM040: printf ("AM29F040 (512 Kbit, uniform sector size)\n");
+ break;
+ case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM320B: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\n");
+ break;
+ case FLASH_SST800A: printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
+ break;
+ case FLASH_SST160A: printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
+ break;
+ default: printf ("Unknown Chip Type\n");
+ break;
+ }
+
+ 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) {
+ /*
+ * Check if whole sector is erased
+ */
+ if (i != (info->sector_count-1))
+ size = info->start[i+1] - info->start[i];
+ else
+ size = info->start[0] + info->size - info->start[i];
+ erased = 1;
+ flash = (volatile unsigned long *)info->start[i];
+ size = size >> 2; /* divide by 4 for longword access */
+ for (k=0; k<size; k++)
+ {
+ if (*flash++ != 0xffffffff)
+ {
+ erased = 0;
+ break;
+ }
+ }
+
+ if ((i % 5) == 0)
+ printf ("\n ");
+ printf (" %08lX%s%s",
+ info->start[i],
+ erased ? " E" : " ",
+ info->protect[i] ? "RO " : " "
+ );
+ }
+ printf ("\n");
+ return;
+ }
+
+/*-----------------------------------------------------------------------
+ */
+
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
+ {
+ short i;
+ FLASH_WORD_SIZE value;
+ ulong base = (ulong)addr;
+ volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr;
+
+ DEBUGF("FLASH ADDR: %08x\n", (unsigned)addr );
+
+ /* Write auto select command: read Manufacturer ID */
+ udelay(10000);
+ addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ udelay(1000);
+ addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ udelay(1000);
+ addr2[ADDR0] = (FLASH_WORD_SIZE)0x00900090;
+ udelay(1000);
+
+#ifdef CONFIG_ADCIOP
+ value = addr2[2];
+#else
+ value = addr2[0];
+#endif
+
+ DEBUGF("FLASH MANUFACT: %x\n", value);
+
+ switch (value) {
+ case (FLASH_WORD_SIZE)AMD_MANUFACT:
+ info->flash_id = FLASH_MAN_AMD;
+ break;
+ case (FLASH_WORD_SIZE)FUJ_MANUFACT:
+ info->flash_id = FLASH_MAN_FUJ;
+ break;
+ case (FLASH_WORD_SIZE)SST_MANUFACT:
+ info->flash_id = FLASH_MAN_SST;
+ break;
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ info->sector_count = 0;
+ info->size = 0;
+ return (0); /* no or unknown flash */
+ }
+
+#ifdef CONFIG_ADCIOP
+ value = addr2[0]; /* device ID */
+ debug ("\ndev_code=%x\n", value);
+#else
+ value = addr2[1]; /* device ID */
+#endif
+
+ DEBUGF("\nFLASH DEVICEID: %x\n", value);
+
+ switch (value) {
+ case (FLASH_WORD_SIZE)AMD_ID_F016D:
+ info->flash_id += FLASH_AMD016;
+ info->sector_count = 32;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+ case (FLASH_WORD_SIZE)AMD_ID_F040B:
+ info->flash_id += FLASH_AM040;
+ info->sector_count = 8;
+ info->size = 0x0080000; /* => 512 ko */
+ break;
+ case (FLASH_WORD_SIZE)AMD_ID_LV400T:
+ info->flash_id += FLASH_AM400T;
+ info->sector_count = 11;
+ info->size = 0x00080000;
+ break; /* => 0.5 MB */
+
+ case (FLASH_WORD_SIZE)AMD_ID_LV400B:
+ info->flash_id += FLASH_AM400B;
+ info->sector_count = 11;
+ info->size = 0x00080000;
+ break; /* => 0.5 MB */
+
+ case (FLASH_WORD_SIZE)AMD_ID_LV800T:
+ info->flash_id += FLASH_AM800T;
+ info->sector_count = 19;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case (FLASH_WORD_SIZE)AMD_ID_LV800B:
+ info->flash_id += FLASH_AM800B;
+ info->sector_count = 19;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case (FLASH_WORD_SIZE)AMD_ID_LV160T:
+ info->flash_id += FLASH_AM160T;
+ info->sector_count = 35;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ case (FLASH_WORD_SIZE)AMD_ID_LV160B:
+ info->flash_id += FLASH_AM160B;
+ info->sector_count = 35;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+#if 0 /* enable when device IDs are available */
+ case (FLASH_WORD_SIZE)AMD_ID_LV320T:
+ info->flash_id += FLASH_AM320T;
+ info->sector_count = 67;
+ info->size = 0x00400000;
+ break; /* => 4 MB */
+
+ case (FLASH_WORD_SIZE)AMD_ID_LV320B:
+ info->flash_id += FLASH_AM320B;
+ info->sector_count = 67;
+ info->size = 0x00400000;
+ break; /* => 4 MB */
+#endif
+ case (FLASH_WORD_SIZE)SST_ID_xF800A:
+ info->flash_id += FLASH_SST800A;
+ info->sector_count = 16;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case (FLASH_WORD_SIZE)SST_ID_xF160A:
+ info->flash_id += FLASH_SST160A;
+ info->sector_count = 32;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ return (0); /* => no or unknown flash */
+
+ }
+
+ /* set up sector start address table */
+ if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
+ (info->flash_id == FLASH_AM040) ||
+ (info->flash_id == FLASH_AMD016)) {
+ for (i = 0; i < info->sector_count; i++)
+ info->start[i] = base + (i * 0x00010000);
+ } else {
+ if (info->flash_id & FLASH_BTYPE) {
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00004000;
+ info->start[2] = base + 0x00006000;
+ info->start[3] = base + 0x00008000;
+ for (i = 4; i < info->sector_count; i++) {
+ info->start[i] = base + (i * 0x00010000) - 0x00030000;
+ }
+ } else {
+ /* set sector offsets for top boot block type */
+ i = info->sector_count - 1;
+ info->start[i--] = base + info->size - 0x00004000;
+ info->start[i--] = base + info->size - 0x00006000;
+ info->start[i--] = base + info->size - 0x00008000;
+ for (; i >= 0; i--) {
+ info->start[i] = base + i * 0x00010000;
+ }
+ }
+ }
+
+ /* check for protected sectors */
+ for (i = 0; i < info->sector_count; i++) {
+ /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+ /* D0 = 1 if protected */
+#ifdef CONFIG_ADCIOP
+ addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]);
+ info->protect[i] = addr2[4] & 1;
+#else
+ addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]);
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)
+ info->protect[i] = 0;
+ else
+ info->protect[i] = addr2[2] & 1;
+#endif
+ }
+
+ /*
+ * Prevent writes to uninitialized FLASH.
+ */
+ if (info->flash_id != FLASH_UNKNOWN) {
+#if 0 /* test-only */
+#ifdef CONFIG_ADCIOP
+ addr2 = (volatile unsigned char *)info->start[0];
+ addr2[ADDR0] = 0xAA;
+ addr2[ADDR1] = 0x55;
+ addr2[ADDR0] = 0xF0; /* reset bank */
+#else
+ addr2 = (FLASH_WORD_SIZE *)info->start[0];
+ *addr2 = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
+#endif
+#else /* test-only */
+ addr2 = (FLASH_WORD_SIZE *)info->start[0];
+ *addr2 = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
+#endif /* test-only */
+ }
+
+ return (info->size);
+ }
+
+ int wait_for_DQ7(flash_info_t *info, int sect)
+ {
+ ulong start, now, last;
+ volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]);
+
+ start = get_timer (0);
+ last = start;
+ while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
+ if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+ printf ("Timeout\n");
+ return -1;
+ }
+ /* show that we're waiting */
+ if ((now - last) > 1000) { /* every second */
+ putc ('.');
+ last = now;
+ }
+ }
+ return 0;
+ }
+
+/*-----------------------------------------------------------------------
+ */
+
+ int flash_erase (flash_info_t *info, int s_first, int s_last)
+ {
+ volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]);
+ volatile FLASH_WORD_SIZE *addr2;
+ int flag, prot, sect, l_sect;
+ int i;
+
+ 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 ("Can't erase unknown flash type - 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");
+ }
+
+ l_sect = -1;
+
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect<=s_last; sect++) {
+ if (info->protect[sect] == 0) { /* not protected */
+ addr2 = (FLASH_WORD_SIZE *)(info->start[sect]);
+ printf("Erasing sector %p\n", addr2);
+
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ addr2[0] = (FLASH_WORD_SIZE)0x00500050; /* block erase */
+ for (i=0; i<50; i++)
+ udelay(1000); /* wait 1 ms */
+ } else {
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ addr2[0] = (FLASH_WORD_SIZE)0x00300030; /* sector erase */
+ }
+ l_sect = sect;
+ /*
+ * Wait for each sector to complete, it's more
+ * reliable. According to AMD Spec, you must
+ * issue all erase commands within a specified
+ * timeout. This has been seen to fail, especially
+ * if printf()s are included (for debug)!!
+ */
+ wait_for_DQ7(info, sect);
+ }
+ }
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* wait at least 80us - let's wait 1 ms */
+ udelay (1000);
+
+#if 0
+ /*
+ * We wait for the last triggered sector
+ */
+ if (l_sect < 0)
+ goto DONE;
+ wait_for_DQ7(info, l_sect);
+
+ DONE:
+#endif
+ /* reset to read mode */
+ addr = (FLASH_WORD_SIZE *)info->start[0];
+ addr[0] = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
+
+ printf (" done\n");
+ return 0;
+ }
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+ {
+ ulong cp, wp, data;
+ int i, l, rc;
+
+ wp = (addr & ~3); /* get lower word aligned address */
+
+ /*
+ * handle unaligned start bytes
+ */
+ if ((l = addr - wp) != 0) {
+ data = 0;
+ for (i=0, cp=wp; i<l; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+ for (; i<4 && cnt>0; ++i) {
+ data = (data << 8) | *src++;
+ --cnt;
+ ++cp;
+ }
+ for (; cnt==0 && i<4; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ }
+
+ /*
+ * handle word aligned part
+ */
+ while (cnt >= 4) {
+ data = 0;
+ for (i=0; i<4; ++i) {
+ data = (data << 8) | *src++;
+ }
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ cnt -= 4;
+ }
+
+ if (cnt == 0) {
+ return (0);
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+ data = (data << 8) | *src++;
+ --cnt;
+ }
+ for (; i<4; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+
+ return (write_word(info, wp, data));
+ }
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+ static int write_word (flash_info_t * info, ulong dest, ulong data)
+ {
+ volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) (info->start[0]);
+ volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *) dest;
+ volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data;
+ ulong start;
+ int i;
+
+ /* Check if Flash is (sufficiently) erased */
+ if ((*((volatile FLASH_WORD_SIZE *) dest) &
+ (FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) {
+ return (2);
+ }
+
+ for (i = 0; i < 4 / sizeof (FLASH_WORD_SIZE); i++) {
+ int flag;
+
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts ();
+
+ addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
+ addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
+ addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00A000A0;
+
+ dest2[i] = data2[i];
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts ();
+
+ /* data polling for D7 */
+ start = get_timer (0);
+ while ((dest2[i] & (FLASH_WORD_SIZE) 0x00800080) !=
+ (data2[i] & (FLASH_WORD_SIZE) 0x00800080)) {
+
+ if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
+ return (1);
+ }
+ }
+ }
+
+ return (0);
+ }
+
+/*-----------------------------------------------------------------------
+ */
--- /dev/null
+#
+# (C) Copyright 2000
+# Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+# Marius Groeger <mgroeger@sysgo.de>
+#
+# (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
+#
+
+#
+# MHPC boards
+#
+
+TEXT_BASE = 0xfe000000
+/*TEXT_BASE = 0x00200000 */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/*
+ * (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 <common.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
+
+
+#ifdef CFG_FLASH_16BIT
+#define FLASH_WORD_SIZE unsigned short
+#define FLASH_ID_MASK 0xFFFF
+#else
+#define FLASH_WORD_SIZE unsigned long
+#define FLASH_ID_MASK 0xFFFFFFFF
+#endif
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+/* stolen from esteem192e/flash.c */
+ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info);
+
+#ifndef CFG_FLASH_16BIT
+static int write_word (flash_info_t *info, ulong dest, ulong data);
+#else
+static int write_short (flash_info_t *info, ulong dest, ushort data);
+#endif
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+ unsigned long size_b0, size_b1;
+ int i;
+ uint pbcr;
+ unsigned long base_b0, base_b1;
+
+ /* Init: no FLASHes known */
+ for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+ flash_info[i].flash_id = FLASH_UNKNOWN;
+ }
+
+ /* Static FLASH Bank configuration here - FIXME XXX */
+
+ size_b0 = flash_get_size((volatile FLASH_WORD_SIZE *)FLASH_BASE0_PRELIM, &flash_info[0]);
+
+ if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+ printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+ size_b0, size_b0<<20);
+ }
+
+ /* Only one bank */
+ if (CFG_MAX_FLASH_BANKS == 1)
+ {
+ /* Setup offsets */
+ flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]);
+
+ /* Monitor protection ON by default */
+#if 0 /* sand: */
+ (void)flash_protect(FLAG_PROTECT_SET,
+ FLASH_BASE0_PRELIM-CFG_MONITOR_LEN+size_b0,
+ FLASH_BASE0_PRELIM-1+size_b0,
+ &flash_info[0]);
+#else
+ (void)flash_protect(FLAG_PROTECT_SET,
+ CFG_MONITOR_BASE,
+ CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
+ &flash_info[0]);
+#endif
+ size_b1 = 0 ;
+ flash_info[0].size = size_b0;
+ }
+
+ /* 2 banks */
+ else
+ {
+ size_b1 = flash_get_size((volatile FLASH_WORD_SIZE *)FLASH_BASE1_PRELIM, &flash_info[1]);
+
+ /* Re-do sizing to get full correct info */
+
+ if (size_b1)
+ {
+ mtdcr(ebccfga, pb0cr);
+ pbcr = mfdcr(ebccfgd);
+ mtdcr(ebccfga, pb0cr);
+ base_b1 = -size_b1;
+ pbcr = (pbcr & 0x0001ffff) | base_b1 | (((size_b1/1024/1024)-1)<<17);
+ mtdcr(ebccfgd, pbcr);
+ /* printf("pb1cr = %x\n", pbcr); */
+ }
+
+ if (size_b0)
+ {
+ mtdcr(ebccfga, pb1cr);
+ pbcr = mfdcr(ebccfgd);
+ mtdcr(ebccfga, pb1cr);
+ base_b0 = base_b1 - size_b0;
+ pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
+ mtdcr(ebccfgd, pbcr);
+ /* printf("pb0cr = %x\n", pbcr); */
+ }
+
+ size_b0 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b0, &flash_info[0]);
+
+ flash_get_offsets (base_b0, &flash_info[0]);
+
+ /* monitor protection ON by default */
+#if 0 /* sand: */
+ (void)flash_protect(FLAG_PROTECT_SET,
+ FLASH_BASE0_PRELIM-CFG_MONITOR_LEN+size_b0,
+ FLASH_BASE0_PRELIM-1+size_b0,
+ &flash_info[0]);
+#else
+ (void)flash_protect(FLAG_PROTECT_SET,
+ CFG_MONITOR_BASE,
+ CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
+ &flash_info[0]);
+#endif
+
+ if (size_b1) {
+ /* Re-do sizing to get full correct info */
+ size_b1 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b1, &flash_info[1]);
+
+ flash_get_offsets (base_b1, &flash_info[1]);
+
+ /* monitor protection ON by default */
+ (void)flash_protect(FLAG_PROTECT_SET,
+ base_b1+size_b1-CFG_MONITOR_LEN,
+ base_b1+size_b1-1,
+ &flash_info[1]);
+ /* monitor protection OFF by default (one is enough) */
+ (void)flash_protect(FLAG_PROTECT_CLEAR,
+ base_b0+size_b0-CFG_MONITOR_LEN,
+ base_b0+size_b0-1,
+ &flash_info[0]);
+ } else {
+ flash_info[1].flash_id = FLASH_UNKNOWN;
+ flash_info[1].sector_count = -1;
+ }
+
+ flash_info[0].size = size_b0;
+ flash_info[1].size = size_b1;
+ }/* else 2 banks */
+ return (size_b0 + size_b1);
+}
+
+
+
+/*-----------------------------------------------------------------------
+ */
+
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+ int i;
+
+ /* set up sector start adress table */
+ if ((info->flash_id & FLASH_TYPEMASK) == FLASH_28F320J3A ||
+ (info->flash_id & FLASH_TYPEMASK) == FLASH_28F640J3A ||
+ (info->flash_id & FLASH_TYPEMASK) == FLASH_28F128J3A) {
+ for (i = 0; i < info->sector_count; i++) {
+ info->start[i] = base + (i * info->size/info->sector_count);
+ }
+ } else if (info->flash_id & FLASH_BTYPE) {
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
+
+#ifndef CFG_FLASH_16BIT
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00004000;
+ info->start[2] = base + 0x00008000;
+ info->start[3] = base + 0x0000C000;
+ info->start[4] = base + 0x00010000;
+ info->start[5] = base + 0x00014000;
+ info->start[6] = base + 0x00018000;
+ info->start[7] = base + 0x0001C000;
+ for (i = 8; i < info->sector_count; i++) {
+ info->start[i] = base + (i * 0x00020000) - 0x000E0000;
+ }
+ }
+ else {
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00008000;
+ info->start[2] = base + 0x0000C000;
+ info->start[3] = base + 0x00010000;
+ for (i = 4; i < info->sector_count; i++) {
+ info->start[i] = base + (i * 0x00020000) - 0x00060000;
+ }
+ }
+#else
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00002000;
+ info->start[2] = base + 0x00004000;
+ info->start[3] = base + 0x00006000;
+ info->start[4] = base + 0x00008000;
+ info->start[5] = base + 0x0000A000;
+ info->start[6] = base + 0x0000C000;
+ info->start[7] = base + 0x0000E000;
+ for (i = 8; i < info->sector_count; i++) {
+ info->start[i] = base + (i * 0x00010000) - 0x00070000;
+ }
+ }
+ else {
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00004000;
+ info->start[2] = base + 0x00006000;
+ info->start[3] = base + 0x00008000;
+ for (i = 4; i < info->sector_count; i++) {
+ info->start[i] = base + (i * 0x00010000) - 0x00030000;
+ }
+ }
+#endif
+ } else {
+ /* set sector offsets for top boot block type */
+ i = info->sector_count - 1;
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
+
+#ifndef CFG_FLASH_16BIT
+ info->start[i--] = base + info->size - 0x00004000;
+ info->start[i--] = base + info->size - 0x00008000;
+ info->start[i--] = base + info->size - 0x0000C000;
+ info->start[i--] = base + info->size - 0x00010000;
+ info->start[i--] = base + info->size - 0x00014000;
+ info->start[i--] = base + info->size - 0x00018000;
+ info->start[i--] = base + info->size - 0x0001C000;
+ for (; i >= 0; i--) {
+ info->start[i] = base + i * 0x00020000;
+ }
+
+ } else {
+
+ info->start[i--] = base + info->size - 0x00008000;
+ info->start[i--] = base + info->size - 0x0000C000;
+ info->start[i--] = base + info->size - 0x00010000;
+ for (; i >= 0; i--) {
+ info->start[i] = base + i * 0x00020000;
+ }
+ }
+#else
+ info->start[i--] = base + info->size - 0x00002000;
+ info->start[i--] = base + info->size - 0x00004000;
+ info->start[i--] = base + info->size - 0x00006000;
+ info->start[i--] = base + info->size - 0x00008000;
+ info->start[i--] = base + info->size - 0x0000A000;
+ info->start[i--] = base + info->size - 0x0000C000;
+ info->start[i--] = base + info->size - 0x0000E000;
+ for (; i >= 0; i--) {
+ info->start[i] = base + i * 0x00010000;
+ }
+
+ } else {
+
+ info->start[i--] = base + info->size - 0x00004000;
+ info->start[i--] = base + info->size - 0x00006000;
+ info->start[i--] = base + info->size - 0x00008000;
+ for (; i >= 0; i--) {
+ info->start[i] = base + i * 0x00010000;
+ }
+ }
+#endif
+ }
+
+
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+void flash_print_info (flash_info_t *info)
+{
+ int i;
+ uchar *boottype;
+ uchar botboot[]=", bottom boot sect)\n";
+ uchar topboot[]=", top boot sector)\n";
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("missing or unknown FLASH type\n");
+ return;
+ }
+
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case FLASH_MAN_AMD: printf ("AMD "); break;
+ case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
+ case FLASH_MAN_SST: printf ("SST "); break;
+ case FLASH_MAN_STM: printf ("STM "); break;
+ case FLASH_MAN_INTEL: printf ("INTEL "); break;
+ default: printf ("Unknown Vendor "); break;
+ }
+
+ if (info->flash_id & 0x0001 ) {
+ boottype = botboot;
+ } else {
+ boottype = topboot;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_AM400B: printf ("AM29LV400B (4 Mbit%s",boottype);
+ break;
+ case FLASH_AM400T: printf ("AM29LV400T (4 Mbit%s",boottype);
+ break;
+ case FLASH_AM800B: printf ("AM29LV800B (8 Mbit%s",boottype);
+ break;
+ case FLASH_AM800T: printf ("AM29LV800T (8 Mbit%s",boottype);
+ break;
+ case FLASH_AM160B: printf ("AM29LV160B (16 Mbit%s",boottype);
+ break;
+ case FLASH_AM160T: printf ("AM29LV160T (16 Mbit%s",boottype);
+ break;
+ case FLASH_AM320B: printf ("AM29LV320B (32 Mbit%s",boottype);
+ break;
+ case FLASH_AM320T: printf ("AM29LV320T (32 Mbit%s",boottype);
+ break;
+ case FLASH_INTEL800B: printf ("INTEL28F800B (8 Mbit%s",boottype);
+ break;
+ case FLASH_INTEL800T: printf ("INTEL28F800T (8 Mbit%s",boottype);
+ break;
+ case FLASH_INTEL160B: printf ("INTEL28F160B (16 Mbit%s",boottype);
+ break;
+ case FLASH_INTEL160T: printf ("INTEL28F160T (16 Mbit%s",boottype);
+ break;
+ case FLASH_INTEL320B: printf ("INTEL28F320B (32 Mbit%s",boottype);
+ break;
+ case FLASH_INTEL320T: printf ("INTEL28F320T (32 Mbit%s",boottype);
+ break;
+
+#if 0 /* enable when devices are available */
+
+ case FLASH_INTEL640B: printf ("INTEL28F640B (64 Mbit%s",boottype);
+ break;
+ case FLASH_INTEL640T: printf ("INTEL28F640T (64 Mbit%s",boottype);
+ break;
+#endif
+ case FLASH_28F320J3A: printf ("INTEL28F320J3A (32 Mbit%s",boottype);
+ break;
+ case FLASH_28F640J3A: printf ("INTEL28F640J3A (64 Mbit%s",boottype);
+ break;
+ case FLASH_28F128J3A: printf ("INTEL28F128J3A (128 Mbit%s",boottype);
+ 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!
+ */
+ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info)
+{
+ short i;
+ ulong base = (ulong)addr;
+ FLASH_WORD_SIZE value;
+
+ /* Write auto select command: read Manufacturer ID */
+
+
+#ifndef CFG_FLASH_16BIT
+
+ /*
+ * Note: if it is an AMD flash and the word at addr[0000]
+ * is 0x00890089 this routine will think it is an Intel
+ * flash device and may(most likely) cause trouble.
+ */
+
+ addr[0x0000] = 0x00900090;
+ if(addr[0x0000] != 0x00890089){
+ addr[0x0555] = 0x00AA00AA;
+ addr[0x02AA] = 0x00550055;
+ addr[0x0555] = 0x00900090;
+#else
+
+ /*
+ * Note: if it is an AMD flash and the word at addr[0000]
+ * is 0x0089 this routine will think it is an Intel
+ * flash device and may(most likely) cause trouble.
+ */
+
+ addr[0x0000] = 0x0090;
+
+ if(addr[0x0000] != 0x0089){
+ addr[0x0555] = 0x00AA;
+ addr[0x02AA] = 0x0055;
+ addr[0x0555] = 0x0090;
+#endif
+ }
+ value = addr[0];
+
+ switch (value) {
+ case (AMD_MANUFACT & FLASH_ID_MASK):
+ info->flash_id = FLASH_MAN_AMD;
+ break;
+ case (FUJ_MANUFACT & FLASH_ID_MASK):
+ info->flash_id = FLASH_MAN_FUJ;
+ break;
+ case (STM_MANUFACT & FLASH_ID_MASK):
+ info->flash_id = FLASH_MAN_STM;
+ break;
+ case (SST_MANUFACT & FLASH_ID_MASK):
+ info->flash_id = FLASH_MAN_SST;
+ break;
+ 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;
+ return (0); /* no or unknown flash */
+
+ }
+
+ value = addr[1]; /* device ID */
+
+ switch (value) {
+
+ case (AMD_ID_LV400T & FLASH_ID_MASK):
+ info->flash_id += FLASH_AM400T;
+ info->sector_count = 11;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case (AMD_ID_LV400B & FLASH_ID_MASK):
+ info->flash_id += FLASH_AM400B;
+ info->sector_count = 11;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case (AMD_ID_LV800T & FLASH_ID_MASK):
+ info->flash_id += FLASH_AM800T;
+ info->sector_count = 19;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ case (AMD_ID_LV800B & FLASH_ID_MASK):
+ info->flash_id += FLASH_AM800B;
+ info->sector_count = 19;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ case (AMD_ID_LV160T & FLASH_ID_MASK):
+ info->flash_id += FLASH_AM160T;
+ info->sector_count = 35;
+ info->size = 0x00400000;
+ break; /* => 4 MB */
+
+ case (AMD_ID_LV160B & FLASH_ID_MASK):
+ info->flash_id += FLASH_AM160B;
+ info->sector_count = 35;
+ info->size = 0x00400000;
+ break; /* => 4 MB */
+#if 0 /* enable when device IDs are available */
+ case (AMD_ID_LV320T & FLASH_ID_MASK):
+ info->flash_id += FLASH_AM320T;
+ info->sector_count = 67;
+ info->size = 0x00800000;
+ break; /* => 8 MB */
+
+ case (AMD_ID_LV320B & FLASH_ID_MASK):
+ info->flash_id += FLASH_AM320B;
+ info->sector_count = 67;
+ info->size = 0x00800000;
+ break; /* => 8 MB */
+#endif
+
+ case (INTEL_ID_28F800B3T & FLASH_ID_MASK):
+ info->flash_id += FLASH_INTEL800T;
+ info->sector_count = 23;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ case (INTEL_ID_28F800B3B & FLASH_ID_MASK):
+ info->flash_id += FLASH_INTEL800B;
+ info->sector_count = 23;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ case (INTEL_ID_28F160B3T & FLASH_ID_MASK):
+ info->flash_id += FLASH_INTEL160T;
+ info->sector_count = 39;
+ info->size = 0x00400000;
+ break; /* => 4 MB */
+
+ case (INTEL_ID_28F160B3B & FLASH_ID_MASK):
+ info->flash_id += FLASH_INTEL160B;
+ info->sector_count = 39;
+ info->size = 0x00400000;
+ break; /* => 4 MB */
+
+ case (INTEL_ID_28F320B3T & FLASH_ID_MASK):
+ info->flash_id += FLASH_INTEL320T;
+ info->sector_count = 71;
+ info->size = 0x00800000;
+ break; /* => 8 MB */
+
+ case (INTEL_ID_28F320B3B & FLASH_ID_MASK):
+ info->flash_id += FLASH_AM320B;
+ info->sector_count = 71;
+ info->size = 0x00800000;
+ break; /* => 8 MB */
+
+#if 0 /* enable when devices are available */
+ case (INTEL_ID_28F320B3T & FLASH_ID_MASK):
+ info->flash_id += FLASH_INTEL320T;
+ info->sector_count = 135;
+ info->size = 0x01000000;
+ break; /* => 16 MB */
+
+ case (INTEL_ID_28F320B3B & FLASH_ID_MASK):
+ info->flash_id += FLASH_AM320B;
+ info->sector_count = 135;
+ info->size = 0x01000000;
+ break; /* => 16 MB */
+#endif
+ case (INTEL_ID_28F320J3A & FLASH_ID_MASK):
+ info->flash_id += FLASH_28F320J3A;
+ info->sector_count = 32;
+ info->size = 0x00400000;
+ break; /* => 32 MBit */
+ case (INTEL_ID_28F640J3A & FLASH_ID_MASK):
+ info->flash_id += FLASH_28F640J3A;
+ info->sector_count = 64;
+ info->size = 0x00800000;
+ break; /* => 64 MBit */
+ case (INTEL_ID_28F128J3A & FLASH_ID_MASK):
+ info->flash_id += FLASH_28F128J3A;
+ info->sector_count = 128;
+ info->size = 0x01000000;
+ break; /* => 128 MBit */
+
+ default:
+ /* FIXME*/
+ info->flash_id = FLASH_UNKNOWN;
+ return (0); /* => no or unknown flash */
+ }
+
+ flash_get_offsets(base, info);
+
+ /* check for protected sectors */
+ for (i = 0; i < info->sector_count; i++) {
+ /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+ /* D0 = 1 if protected */
+ addr = (volatile FLASH_WORD_SIZE *)(info->start[i]);
+ info->protect[i] = addr[2] & 1;
+ }
+
+ /*
+ * Prevent writes to uninitialized FLASH.
+ */
+ if (info->flash_id != FLASH_UNKNOWN) {
+ addr = (volatile FLASH_WORD_SIZE *)info->start[0];
+ if( (info->flash_id & 0xFF00) == FLASH_MAN_INTEL){
+ *addr = (0x00F000F0 & FLASH_ID_MASK); /* reset bank */
+ } else {
+ *addr = (0x00FF00FF & FLASH_ID_MASK); /* reset bank */
+ }
+ }
+
+ return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+
+ volatile FLASH_WORD_SIZE *addr=(volatile FLASH_WORD_SIZE*)(info->start[0]);
+ int flag, prot, sect, l_sect, barf;
+ ulong start, now, last;
+ int rcode = 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;
+ }
+
+ if ((info->flash_id == FLASH_UNKNOWN) ||
+ ((info->flash_id > FLASH_AMD_COMP) &&
+ ( (info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL ) ) ){
+ printf ("Can't erase unknown flash type - 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");
+ }
+
+ l_sect = -1;
+
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+ if(info->flash_id < FLASH_AMD_COMP) {
+#ifndef CFG_FLASH_16BIT
+ addr[0x0555] = 0x00AA00AA;
+ addr[0x02AA] = 0x00550055;
+ addr[0x0555] = 0x00800080;
+ addr[0x0555] = 0x00AA00AA;
+ addr[0x02AA] = 0x00550055;
+#else
+ addr[0x0555] = 0x00AA;
+ addr[0x02AA] = 0x0055;
+ addr[0x0555] = 0x0080;
+ addr[0x0555] = 0x00AA;
+ addr[0x02AA] = 0x0055;
+#endif
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect<=s_last; sect++) {
+ if (info->protect[sect] == 0) { /* not protected */
+ addr = (volatile FLASH_WORD_SIZE *)(info->start[sect]);
+ addr[0] = (0x00300030 & FLASH_ID_MASK);
+ l_sect = sect;
+ }
+ }
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* wait at least 80us - let's wait 1 ms */
+ udelay (1000);
+
+ /*
+ * We wait for the last triggered sector
+ */
+ if (l_sect < 0)
+ goto DONE;
+
+ start = get_timer (0);
+ last = start;
+ addr = (volatile FLASH_WORD_SIZE*)(info->start[l_sect]);
+ while ((addr[0] & (0x00800080&FLASH_ID_MASK)) !=
+ (0x00800080&FLASH_ID_MASK) )
+ {
+ if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+ printf ("Timeout\n");
+ return 1;
+ }
+ /* show that we're waiting */
+ if ((now - last) > 1000) { /* every second */
+ serial_putc ('.');
+ last = now;
+ }
+ }
+
+DONE:
+ /* reset to read mode */
+ addr = (volatile FLASH_WORD_SIZE *)info->start[0];
+ addr[0] = (0x00F000F0 & FLASH_ID_MASK); /* reset bank */
+ } else {
+
+
+ for (sect = s_first; sect<=s_last; sect++) {
+ if (info->protect[sect] == 0) { /* not protected */
+ barf = 0;
+#ifndef CFG_FLASH_16BIT
+ addr = (vu_long*)(info->start[sect]);
+ addr[0] = 0x00200020;
+ addr[0] = 0x00D000D0;
+ while(!(addr[0] & 0x00800080)); /* wait for error or finish */
+ if( addr[0] & 0x003A003A) { /* check for error */
+ barf = addr[0] & 0x003A0000;
+ if( barf ) {
+ barf >>=16;
+ } else {
+ barf = addr[0] & 0x0000003A;
+ }
+ }
+#else
+ addr = (vu_short*)(info->start[sect]);
+ addr[0] = 0x0020;
+ addr[0] = 0x00D0;
+ while(!(addr[0] & 0x0080)); /* wait for error or finish */
+ if( addr[0] & 0x003A) /* check for error */
+ barf = addr[0] & 0x003A;
+#endif
+ if(barf) {
+ printf("\nFlash error in sector at %lx\n",(unsigned long)addr);
+ if(barf & 0x0002) printf("Block locked, not erased.\n");
+ if((barf & 0x0030) == 0x0030)
+ printf("Command Sequence error.\n");
+ if((barf & 0x0030) == 0x0020)
+ printf("Block Erase error.\n");
+ if(barf & 0x0008) printf("Vpp Low error.\n");
+ rcode = 1;
+ } else printf(".");
+ l_sect = sect;
+ }
+ addr = (volatile FLASH_WORD_SIZE *)info->start[0];
+ addr[0] = (0x00FF00FF & FLASH_ID_MASK); /* reset bank */
+
+ }
+
+ }
+ printf (" done\n");
+ return rcode;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+/*flash_info_t *addr2info (ulong addr)
+{
+ flash_info_t *info;
+ int i;
+
+ for (i=0, info=&flash_info[0]; i<CFG_MAX_FLASH_BANKS; ++i, ++info) {
+ if ((addr >= info->start[0]) &&
+ (addr < (info->start[0] + info->size)) ) {
+ return (info);
+ }
+ }
+
+ return (NULL);
+}
+*/
+/*-----------------------------------------------------------------------
+ * Copy memory to flash.
+ * Make sure all target addresses are within Flash bounds,
+ * and no protected sectors are hit.
+ * Returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ * 4 - target range includes protected sectors
+ * 8 - target address not in Flash memory
+ */
+
+/*int flash_write (uchar *src, ulong addr, ulong cnt)
+{
+ int i;
+ ulong end = addr + cnt - 1;
+ flash_info_t *info_first = addr2info (addr);
+ flash_info_t *info_last = addr2info (end );
+ flash_info_t *info;
+
+ if (cnt == 0) {
+ return (0);
+ }
+
+ if (!info_first || !info_last) {
+ return (8);
+ }
+
+ for (info = info_first; info <= info_last; ++info) {
+ ulong b_end = info->start[0] + info->size;*/ /* bank end addr */
+/* short s_end = info->sector_count - 1;
+ for (i=0; i<info->sector_count; ++i) {
+ ulong e_addr = (i == s_end) ? b_end : info->start[i + 1];
+
+ if ((end >= info->start[i]) && (addr < e_addr) &&
+ (info->protect[i] != 0) ) {
+ return (4);
+ }
+ }
+ }
+
+*/ /* finally write data to flash */
+/* for (info = info_first; info <= info_last && cnt>0; ++info) {
+ ulong len;
+
+ len = info->start[0] + info->size - addr;
+ if (len > cnt)
+ len = cnt;
+ if ((i = write_buff(info, src, addr, len)) != 0) {
+ return (i);
+ }
+ cnt -= len;
+ addr += len;
+ src += len;
+ }
+ return (0);
+}
+*/
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+#ifndef CFG_FLASH_16BIT
+ ulong cp, wp, data;
+ int l;
+#else
+ ulong cp, wp;
+ ushort data;
+#endif
+ int i, rc;
+
+#ifndef CFG_FLASH_16BIT
+
+
+ wp = (addr & ~3); /* get lower word aligned address */
+
+ /*
+ * handle unaligned start bytes
+ */
+ if ((l = addr - wp) != 0) {
+ data = 0;
+ for (i=0, cp=wp; i<l; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+ for (; i<4 && cnt>0; ++i) {
+ data = (data << 8) | *src++;
+ --cnt;
+ ++cp;
+ }
+ for (; cnt==0 && i<4; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ }
+
+ /*
+ * handle word aligned part
+ */
+ while (cnt >= 4) {
+ data = 0;
+ for (i=0; i<4; ++i) {
+ data = (data << 8) | *src++;
+ }
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ cnt -= 4;
+ }
+
+ if (cnt == 0) {
+ return (0);
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+ data = (data << 8) | *src++;
+ --cnt;
+ }
+ for (; i<4; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+
+ return (write_word(info, wp, data));
+
+#else
+ wp = (addr & ~1); /* get lower word aligned address */
+
+ /*
+ * handle unaligned start byte
+ */
+ if (addr - wp) {
+ data = 0;
+ data = (data << 8) | *src++;
+ --cnt;
+ if ((rc = write_short(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 2;
+ }
+
+ /*
+ * handle word aligned part
+ */
+/* l = 0; used for debuging */
+ while (cnt >= 2) {
+ data = 0;
+ for (i=0; i<2; ++i) {
+ data = (data << 8) | *src++;
+ }
+
+/* if(!l){
+ printf("%x",data);
+ l = 1;
+ } used for debuging */
+
+ if ((rc = write_short(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 2;
+ cnt -= 2;
+ }
+
+ if (cnt == 0) {
+ return (0);
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) {
+ data = (data << 8) | *src++;
+ --cnt;
+ }
+ for (; i<2; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+
+ return (write_short(info, wp, data));
+
+
+#endif
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+#ifndef CFG_FLASH_16BIT
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+ vu_long *addr = (vu_long*)(info->start[0]);
+ ulong start,barf;
+ int flag;
+
+
+ /* Check if Flash is (sufficiently) erased */
+ if ((*((vu_long *)dest) & data) != data) {
+ return (2);
+ }
+
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ if(info->flash_id > FLASH_AMD_COMP) {
+ /* AMD stuff */
+ addr[0x0555] = 0x00AA00AA;
+ addr[0x02AA] = 0x00550055;
+ addr[0x0555] = 0x00A000A0;
+ } else {
+ /* intel stuff */
+ *addr = 0x00400040;
+ }
+ *((vu_long *)dest) = data;
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* data polling for D7 */
+ start = get_timer (0);
+
+ if(info->flash_id > FLASH_AMD_COMP) {
+
+ while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
+ if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+ return (1);
+ }
+ }
+
+ } else {
+
+ while(!(addr[0] & 0x00800080)){ /* wait for error or finish */
+ if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+ return (1);
+ }
+
+ if( addr[0] & 0x003A003A) { /* check for error */
+ barf = addr[0] & 0x003A0000;
+ if( barf ) {
+ barf >>=16;
+ } else {
+ barf = addr[0] & 0x0000003A;
+ }
+ printf("\nFlash write error at address %lx\n",(unsigned long)dest);
+ if(barf & 0x0002) printf("Block locked, not erased.\n");
+ if(barf & 0x0010) printf("Programming error.\n");
+ if(barf & 0x0008) printf("Vpp Low error.\n");
+ return(2);
+ }
+
+
+ }
+
+ return (0);
+
+}
+
+#else
+
+static int write_short (flash_info_t *info, ulong dest, ushort data)
+{
+ vu_short *addr = (vu_short*)(info->start[0]);
+ ulong start,barf;
+ int flag;
+
+ /* Check if Flash is (sufficiently) erased */
+ if ((*((vu_short *)dest) & data) != data) {
+ return (2);
+ }
+
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ if(info->flash_id < FLASH_AMD_COMP) {
+ /* AMD stuff */
+ addr[0x0555] = 0x00AA;
+ addr[0x02AA] = 0x0055;
+ addr[0x0555] = 0x00A0;
+ } else {
+ /* intel stuff */
+ *addr = 0x00D0;
+ *addr = 0x0040;
+ }
+ *((vu_short *)dest) = data;
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* data polling for D7 */
+ start = get_timer (0);
+
+ if(info->flash_id < FLASH_AMD_COMP) {
+ /* AMD stuff */
+ while ((*((vu_short *)dest) & 0x0080) != (data & 0x0080)) {
+ if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+ return (1);
+ }
+ }
+
+ } else {
+ /* intel stuff */
+ while(!(addr[0] & 0x0080)){ /* wait for error or finish */
+ if (get_timer(start) > CFG_FLASH_WRITE_TOUT) return (1);
+ }
+
+ if( addr[0] & 0x003A) { /* check for error */
+ barf = addr[0] & 0x003A;
+ printf("\nFlash write error at address %lx\n",(unsigned long)dest);
+ if(barf & 0x0002) printf("Block locked, not erased.\n");
+ if(barf & 0x0010) printf("Programming error.\n");
+ if(barf & 0x0008) printf("Vpp Low error.\n");
+ return(2);
+ }
+ *addr = 0x00B0;
+ *addr = 0x0070;
+ while(!(addr[0] & 0x0080)){ /* wait for error or finish */
+ if (get_timer(start) > CFG_FLASH_WRITE_TOUT) return (1);
+ }
+
+ *addr = 0x00FF;
+
+ }
+
+ return (0);
+
+}
+
+
+#endif
+
+/*-----------------------------------------------------------------------
+ */
+
--- /dev/null
+/*------------------------------------------------------------------------------+ */
+/* */
+/* This source code has been made available to you by IBM on an AS-IS */
+/* basis. Anyone receiving this source is licensed under IBM */
+/* copyrights to use it in any way he or she deems fit, including */
+/* copying it, modifying it, compiling it, and redistributing it either */
+/* with or without modifications. No license under IBM patents or */
+/* patent applications is to be implied by the copyright license. */
+/* */
+/* Any user of this software should understand that IBM cannot provide */
+/* technical support for this software and will not be responsible for */
+/* any consequences resulting from the use of this software. */
+/* */
+/* Any person who transfers this source code or any derivative work */
+/* must include the IBM copyright notice, this paragraph, and the */
+/* preceding two paragraphs in the transferred software. */
+/* */
+/* COPYRIGHT I B M CORPORATION 1995 */
+/* LICENSED MATERIAL - PROGRAM PROPERTY OF I B M */
+/*------------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------- */
+/* Function: ext_bus_cntlr_init */
+/* Description: Initializes the External Bus Controller for the external */
+/* peripherals. IMPORTANT: For pass1 this code must run from */
+/* cache since you can not reliably change a peripheral banks */
+/* timing register (pbxap) while running code from that bank. */
+/* For ex., since we are running from ROM on bank 0, we can NOT */
+/* execute the code that modifies bank 0 timings from ROM, so */
+/* we run it from cache. */
+/* */
+/*----------------------------------------------------------------------------- */
+#include <config.h>
+#include <ppc4xx.h>
+
+#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+
+ .globl ext_bus_cntlr_init
+ext_bus_cntlr_init:
+ mflr r4 /* save link register */
+ bl ..getAddr
+..getAddr:
+ mflr r3 /* get address of ..getAddr */
+ mtlr r4 /* restore link register */
+ addi r4,0,14 /* set ctr to 10; used to prefetch */
+ mtctr r4 /* 10 cache lines to fit this function */
+ /* in cache (gives us 8x10=80 instrctns) */
+..ebcloop:
+ icbt r0,r3 /* prefetch cache line for addr in r3 */
+ addi r3,r3,32 /* move to next cache line */
+ bdnz ..ebcloop /* continue for 10 cache lines */
+
+ /*------------------------------------------------------------------- */
+ /* Delay to ensure all accesses to ROM are complete before changing */
+ /* bank 0 timings. 200usec should be enough. */
+ /* 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles */
+ /*------------------------------------------------------------------- */
+ addis r3,0,0x0
+ ori r3,r3,0xA000 /* ensure 200usec have passed since reset */
+ mtctr r3
+..spinlp:
+ bdnz ..spinlp /* spin loop */
+
+ /*----------------------------------------------------------------------- */
+ /* Memory Bank 0 (Flash) initialization (from openbios) */
+ /*----------------------------------------------------------------------- */
+
+ addi r4,0,pb0ap
+ mtdcr ebccfga,r4
+ addis r4,0,CS0_AP@h
+ ori r4,r4,CS0_AP@l
+ mtdcr ebccfgd,r4
+
+ addi r4,0,pb0cr
+ mtdcr ebccfga,r4
+ addis r4,0,CS0_CR@h
+ ori r4,r4,CS0_CR@l
+ mtdcr ebccfgd,r4
+
+ /*----------------------------------------------------------------------- */
+ /* Memory Bank 1 (NVRAM/RTC) initialization */
+ /*----------------------------------------------------------------------- */
+
+ addi r4,0,pb1ap
+ mtdcr ebccfga,r4
+ addis r4,0,CS1_AP@h
+ ori r4,r4,CS1_AP@l
+ mtdcr ebccfgd,r4
+
+ addi r4,0,pb1cr
+ mtdcr ebccfga,r4
+ addis r4,0,CS1_CR@h
+ ori r4,r4,CS1_CR@l
+ mtdcr ebccfgd,r4
+
+ /*----------------------------------------------------------------------- */
+ /* Memory Bank 2 (A/D converter) initialization */
+ /*----------------------------------------------------------------------- */
+
+ addi r4,0,pb2ap
+ mtdcr ebccfga,r4
+ addis r4,0,CS2_AP@h
+ ori r4,r4,CS2_AP@l
+ mtdcr ebccfgd,r4
+
+ addi r4,0,pb2cr
+ mtdcr ebccfga,r4
+ addis r4,0,CS2_CR@h
+ ori r4,r4,CS2_CR@l
+ mtdcr ebccfgd,r4
+
+ /*----------------------------------------------------------------------- */
+ /* Memory Bank 3 (Ethernet PHY Reset) initialization */
+ /*----------------------------------------------------------------------- */
+
+ addi r4,0,pb3ap
+ mtdcr ebccfga,r4
+ addis r4,0,CS3_AP@h
+ ori r4,r4,CS3_AP@l
+ mtdcr ebccfgd,r4
+
+ addi r4,0,pb3cr
+ mtdcr ebccfga,r4
+ addis r4,0,CS3_CR@h
+ ori r4,r4,CS3_CR@l
+ mtdcr ebccfgd,r4
+
+ /*----------------------------------------------------------------------- */
+ /* Memory Bank 4 (PC-MIP PRSNT1#) initialization */
+ /*----------------------------------------------------------------------- */
+
+ addi r4,0,pb4ap
+ mtdcr ebccfga,r4
+ addis r4,0,CS4_AP@h
+ ori r4,r4,CS4_AP@l
+ mtdcr ebccfgd,r4
+
+ addi r4,0,pb4cr
+ mtdcr ebccfga,r4
+ addis r4,0,CS4_CR@h
+ ori r4,r4,CS4_CR@l
+ mtdcr ebccfgd,r4
+
+ /*----------------------------------------------------------------------- */
+ /* Memory Bank 5 (PC-MIP PRSNT2#) initialization */
+ /*----------------------------------------------------------------------- */
+
+ addi r4,0,pb5ap
+ mtdcr ebccfga,r4
+ addis r4,0,CS5_AP@h
+ ori r4,r4,CS5_AP@l
+ mtdcr ebccfgd,r4
+
+ addi r4,0,pb5cr
+ mtdcr ebccfga,r4
+ addis r4,0,CS5_CR@h
+ ori r4,r4,CS5_CR@l
+ mtdcr ebccfgd,r4
+
+ /*----------------------------------------------------------------------- */
+ /* Memory Bank 6 (CPU LED0) initialization */
+ /*----------------------------------------------------------------------- */
+
+ addi r4,0,pb6ap
+ mtdcr ebccfga,r4
+ addis r4,0,CS6_AP@h
+ ori r4,r4,CS6_AP@l
+ mtdcr ebccfgd,r4
+
+ addi r4,0,pb6cr
+ mtdcr ebccfga,r4
+ addis r4,0,CS6_CR@h
+ ori r4,r4,CS5_CR@l
+ mtdcr ebccfgd,r4
+
+ /*----------------------------------------------------------------------- */
+ /* Memory Bank 7 (CPU LED1) initialization */
+ /*----------------------------------------------------------------------- */
+
+ addi r4,0,pb7ap
+ mtdcr ebccfga,r4
+ addis r4,0,CS7_AP@h
+ ori r4,r4,CS7_AP@l
+ mtdcr ebccfgd,r4
+
+ addi r4,0,pb7cr
+ mtdcr ebccfga,r4
+ addis r4,0,CS7_CR@h
+ ori r4,r4,CS7_CR@l
+ mtdcr ebccfgd,r4
+
+/* addis r4,r0,FPGA_BRDC@h */
+/* ori r4,r4,FPGA_BRDC@l */
+/* lbz r3,0(r4) //get FPGA board control reg */
+/* eieio */
+/* ori r3,r3,0x01 //set UART1 control to select CTS/RTS */
+/* stb r3,0(r4) */
+
+ nop /* pass2 DCR errata #8 */
+ blr
+
+/*----------------------------------------------------------------------------- */
+/* Function: sdram_init */
+/* Description: Configures SDRAM memory banks on ERIC. */
+/* We do manually init our SDRAM. */
+/* If we have two SDRAM banks, simply undef SINGLE_BANK (ROLF :-) */
+/* It is assumed that a 32MB 12x8(2) SDRAM is used. */
+/*----------------------------------------------------------------------------- */
+ .globl sdram_init
+
+sdram_init:
+
+ mflr r31
+
+#ifdef CFG_SDRAM_MANUALLY
+ /*------------------------------------------------------------------- */
+ /* Set MB0CF for bank 0. (0-32MB) Address Mode 4 since 12x8(2) */
+ /*------------------------------------------------------------------- */
+
+ addi r4,0,mem_mb0cf
+ mtdcr memcfga,r4
+ addis r4,0,MB0CF@h
+ ori r4,r4,MB0CF@l
+ mtdcr memcfgd,r4
+
+ /*------------------------------------------------------------------- */
+ /* Set MB1CF for bank 1. (32MB-64MB) Address Mode 4 since 12x8(2) */
+ /*------------------------------------------------------------------- */
+
+ addi r4,0,mem_mb1cf
+ mtdcr memcfga,r4
+ addis r4,0,MB1CF@h
+ ori r4,r4,MB1CF@l
+ mtdcr memcfgd,r4
+
+ /*------------------------------------------------------------------- */
+ /* Set MB2CF for bank 2. off */
+ /*------------------------------------------------------------------- */
+
+ addi r4,0,mem_mb2cf
+ mtdcr memcfga,r4
+ addis r4,0,MB2CF@h
+ ori r4,r4,MB2CF@l
+ mtdcr memcfgd,r4
+
+ /*------------------------------------------------------------------- */
+ /* Set MB3CF for bank 3. off */
+ /*------------------------------------------------------------------- */
+
+ addi r4,0,mem_mb3cf
+ mtdcr memcfga,r4
+ addis r4,0,MB3CF@h
+ ori r4,r4,MB3CF@l
+ mtdcr memcfgd,r4
+
+ /*------------------------------------------------------------------- */
+ /* Set the SDRAM Timing reg, SDTR1 and the refresh timer reg, RTR. */
+ /* To set the appropriate timings, we need to know the SDRAM speed. */
+ /* We can use the PLB speed since the SDRAM speed is the same as */
+ /* the PLB speed. The PLB speed is the FBK divider times the */
+ /* 405GP reference clock, which on the Walnut board is 33Mhz. */
+ /* Thus, if FBK div is 2, SDRAM is 66Mhz; if FBK div is 3, SDRAM is */
+ /* 100Mhz; if FBK is 3, SDRAM is 133Mhz. */
+ /* NOTE: The Walnut board supports SDRAM speeds of 66Mhz, 100Mhz, and */
+ /* maybe 133Mhz. */
+ /*------------------------------------------------------------------- */
+
+ mfdcr r5,strap /* determine FBK divider */
+ /* via STRAP reg to calc PLB speed. */
+ /* SDRAM speed is the same as the PLB */
+ /* speed. */
+ rlwinm r4,r5,4,0x3 /* get FBK divide bits */
+
+..chk_66:
+ cmpi %cr0,0,r4,0x1
+ bne ..chk_100
+ addis r6,0,SDTR_66@h /* SDTR1 value for 66Mhz */
+ ori r6,r6,SDTR_66@l
+ addis r7,0,RTR_66 /* RTR value for 66Mhz */
+ b ..sdram_ok
+..chk_100:
+ cmpi %cr0,0,r4,0x2
+ bne ..chk_133
+ addis r6,0,SDTR_100@h /* SDTR1 value for 100Mhz */
+ ori r6,r6,SDTR_100@l
+ addis r7,0,RTR_100 /* RTR value for 100Mhz */
+ b ..sdram_ok
+..chk_133:
+ addis r6,0,0x0107 /* SDTR1 value for 133Mhz */
+ ori r6,r6,0x4015
+ addis r7,0,0x07F0 /* RTR value for 133Mhz */
+
+..sdram_ok:
+ /*------------------------------------------------------------------- */
+ /* Set SDTR1 */
+ /*------------------------------------------------------------------- */
+ addi r4,0,mem_sdtr1
+ mtdcr memcfga,r4
+ mtdcr memcfgd,r6
+
+ /*------------------------------------------------------------------- */
+ /* Set RTR */
+ /*------------------------------------------------------------------- */
+ addi r4,0,mem_rtr
+ mtdcr memcfga,r4
+ mtdcr memcfgd,r7
+
+ /*------------------------------------------------------------------- */
+ /* Delay to ensure 200usec have elapsed since reset. Assume worst */
+ /* case that the core is running 200Mhz: */
+ /* 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles */
+ /*------------------------------------------------------------------- */
+ addis r3,0,0x0000
+ ori r3,r3,0xA000 /* ensure 200usec have passed since reset */
+ mtctr r3
+..spinlp2:
+ bdnz ..spinlp2 /* spin loop */
+
+ /*------------------------------------------------------------------- */
+ /* Set memory controller options reg, MCOPT1. */
+ /* Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst */
+ /* read/prefetch. */
+ /*------------------------------------------------------------------- */
+ addi r4,0,mem_mcopt1
+ mtdcr memcfga,r4
+ addis r4,0,0x8080 /* set DC_EN=1 */
+ ori r4,r4,0x0000
+ mtdcr memcfgd,r4
+
+ /*------------------------------------------------------------------- */
+ /* Delay to ensure 10msec have elapsed since reset. This is */
+ /* required for the MPC952 to stabalize. Assume worst */
+ /* case that the core is running 200Mhz: */
+ /* 200,000,000 (cycles/sec) X .010 (sec) = 0x1E8480 cycles */
+ /* This delay should occur before accessing SDRAM. */
+ /*------------------------------------------------------------------- */
+ addis r3,0,0x001E
+ ori r3,r3,0x8480 /* ensure 10msec have passed since reset */
+ mtctr r3
+..spinlp3:
+ bdnz ..spinlp3 /* spin loop */
+
+#else
+/*fixme: do SDRAM Autoconfig from EEPROM here */
+
+#endif
+ mtlr r31 /* restore lr */
+ blr
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@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>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+
+/*
+ * include common flash code (for esd boards)
+ */
+#include "../common/flash.c"
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+ unsigned long size_b0, size_b1;
+ int i;
+ uint pbcr;
+ unsigned long base_b0, base_b1;
+
+ /* Init: no FLASHes known */
+ for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+ flash_info[i].flash_id = FLASH_UNKNOWN;
+ }
+
+ /* Static FLASH Bank configuration here - FIXME XXX */
+
+ base_b0 = FLASH_BASE0_PRELIM;
+ size_b0 = flash_get_size((vu_long *)base_b0, &flash_info[0]);
+
+ if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+ printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+ size_b0, size_b0<<20);
+ }
+
+ base_b1 = FLASH_BASE1_PRELIM;
+ size_b1 = flash_get_size((vu_long *)base_b1, &flash_info[1]);
+
+ /* Re-do sizing to get full correct info */
+
+ if (size_b1)
+ {
+ mtdcr(ebccfga, pb0cr);
+ pbcr = mfdcr(ebccfgd);
+ mtdcr(ebccfga, pb0cr);
+ base_b1 = -size_b1;
+ pbcr = (pbcr & 0x0001ffff) | base_b1 | (((size_b1/1024/1024)-1)<<17);
+ mtdcr(ebccfgd, pbcr);
+ /* printf("pb1cr = %x\n", pbcr); */
+ }
+
+ if (size_b0)
+ {
+ mtdcr(ebccfga, pb1cr);
+ pbcr = mfdcr(ebccfgd);
+ mtdcr(ebccfga, pb1cr);
+ base_b0 = base_b1 - size_b0;
+ pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
+ mtdcr(ebccfgd, pbcr);
+ /* printf("pb0cr = %x\n", pbcr); */
+ }
+
+ size_b0 = flash_get_size((vu_long *)base_b0, &flash_info[0]);
+
+ flash_get_offsets (base_b0, &flash_info[0]);
+
+ /* monitor protection ON by default */
+ (void)flash_protect(FLAG_PROTECT_SET,
+ base_b0+size_b0-CFG_MONITOR_LEN,
+ base_b0+size_b0-1,
+ &flash_info[0]);
+
+ if (size_b1) {
+ /* Re-do sizing to get full correct info */
+ size_b1 = flash_get_size((vu_long *)base_b1, &flash_info[1]);
+
+ flash_get_offsets (base_b1, &flash_info[1]);
+
+ /* monitor protection ON by default */
+ (void)flash_protect(FLAG_PROTECT_SET,
+ base_b1+size_b1-CFG_MONITOR_LEN,
+ base_b1+size_b1-1,
+ &flash_info[1]);
+ /* monitor protection OFF by default (one is enough) */
+ (void)flash_protect(FLAG_PROTECT_CLEAR,
+ base_b0+size_b0-CFG_MONITOR_LEN,
+ base_b0+size_b0-1,
+ &flash_info[0]);
+ } else {
+ flash_info[1].flash_id = FLASH_UNKNOWN;
+ flash_info[1].sector_count = -1;
+ }
+
+ flash_info[0].size = size_b0;
+ flash_info[1].size = size_b1;
+
+ return (size_b0 + size_b1);
+}
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@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>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+
+/*
+ * include common flash code (for esd boards)
+ */
+#include "../common/flash.c"
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+ unsigned long size_b0;
+ int i;
+ uint pbcr;
+ unsigned long base_b0;
+
+ /* Init: no FLASHes known */
+ for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+ flash_info[i].flash_id = FLASH_UNKNOWN;
+ }
+
+ /* Static FLASH Bank configuration here - FIXME XXX */
+
+ size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
+
+ if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+ printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+ size_b0, size_b0<<20);
+ }
+
+ /* Setup offsets */
+ flash_get_offsets (-size_b0, &flash_info[0]);
+
+ /* Re-do sizing to get full correct info */
+ mtdcr(ebccfga, pb0cr);
+ pbcr = mfdcr(ebccfgd);
+ mtdcr(ebccfga, pb0cr);
+ base_b0 = -size_b0;
+ pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
+ mtdcr(ebccfgd, pbcr);
+ /* printf("pb1cr = %x\n", pbcr); */
+
+ /* Monitor protection ON by default */
+ (void)flash_protect(FLAG_PROTECT_SET,
+ -CFG_MONITOR_LEN,
+ 0xffffffff,
+ &flash_info[0]);
+
+ flash_info[0].size = size_b0;
+
+ return (size_b0);
+}
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@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>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+
+/*
+ * include common flash code (for esd boards)
+ */
+#include "../common/flash.c"
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+ unsigned long size_b0;
+ int i;
+ uint pbcr;
+ unsigned long base_b0;
+
+ /* Init: no FLASHes known */
+ for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+ flash_info[i].flash_id = FLASH_UNKNOWN;
+ }
+
+ /* Static FLASH Bank configuration here - FIXME XXX */
+
+ size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
+
+ if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+ printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+ size_b0, size_b0<<20);
+ }
+
+ /* Setup offsets */
+ flash_get_offsets (-size_b0, &flash_info[0]);
+
+ /* Re-do sizing to get full correct info */
+ mtdcr(ebccfga, pb0cr);
+ pbcr = mfdcr(ebccfgd);
+ mtdcr(ebccfga, pb0cr);
+ base_b0 = -size_b0;
+ pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
+ mtdcr(ebccfgd, pbcr);
+ /* printf("pb1cr = %x\n", pbcr); */
+
+ /* Monitor protection ON by default */
+ (void)flash_protect(FLAG_PROTECT_SET,
+ -CFG_MONITOR_LEN,
+ 0xffffffff,
+ &flash_info[0]);
+
+ flash_info[0].size = size_b0;
+
+ return (size_b0);
+}
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@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>
+#include <command.h>
+
+
+#define EEPROM_CAP 0x50000358
+#define EEPROM_DATA 0x5000035c
+
+
+unsigned int eepromReadLong(int offs)
+{
+ unsigned int value;
+ volatile unsigned short ret;
+ int count;
+
+ *(unsigned short *)EEPROM_CAP = offs;
+
+ count = 0;
+
+ for (;;)
+ {
+ count++;
+ ret = *(unsigned short *)EEPROM_CAP;
+
+ if ((ret & 0x8000) != 0)
+ break;
+ }
+
+ value = *(unsigned long *)EEPROM_DATA;
+
+ return value;
+}
+
+
+unsigned char eepromReadByte(int offs)
+{
+ unsigned int valueLong;
+ unsigned char *ptr;
+
+ valueLong = eepromReadLong(offs & ~3);
+ ptr = (unsigned char *)&valueLong;
+
+ return ptr[offs & 3];
+}
+
+
+void eepromWriteLong(int offs, unsigned int value)
+{
+ volatile unsigned short ret;
+ int count;
+
+ count = 0;
+
+ *(unsigned long *)EEPROM_DATA = value;
+ *(unsigned short *)EEPROM_CAP = 0x8000 + offs;
+
+ for (;;)
+ {
+ count++;
+ ret = *(unsigned short *)EEPROM_CAP;
+
+ if ((ret & 0x8000) == 0)
+ break;
+ }
+}
+
+
+void eepromWriteByte(int offs, unsigned char valueByte)
+{
+ unsigned int valueLong;
+ unsigned char *ptr;
+
+ valueLong = eepromReadLong(offs & ~3);
+ ptr = (unsigned char *)&valueLong;
+
+ ptr[offs & 3] = valueByte;
+
+ eepromWriteLong(offs & ~3, valueLong);
+}
+
+
+void i2c_read (uchar *addr, int alen, uchar *buffer, int len)
+{
+ int i;
+ int len2, ptr;
+
+ /* printf("\naddr=%x alen=%x buffer=%x len=%x", addr[0], addr[1], *(short *)addr, alen, buffer, len); // test-only */
+
+ ptr = *(short *)addr;
+
+ /*
+ * Read till lword boundary
+ */
+ len2 = 4 - (*(short *)addr & 0x0003);
+ for (i=0; i<len2; i++)
+ {
+ *buffer++ = eepromReadByte(ptr++);
+ }
+
+ /*
+ * Read all lwords
+ */
+ len2 = (len - len2) >> 2;
+ for (i=0; i<len2; i++)
+ {
+ *(unsigned int *)buffer = eepromReadLong(ptr);
+ buffer += 4;
+ ptr += 4;
+ }
+
+ /*
+ * Read last bytes
+ */
+ len2 = (*(short *)addr + len) & 0x0003;
+ for (i=0; i<len2; i++)
+ {
+ *buffer++ = eepromReadByte(ptr++);
+ }
+}
+
+void i2c_write (uchar *addr, int alen, uchar *buffer, int len)
+{
+ int i;
+ int len2, ptr;
+
+ /* printf("\naddr=%x alen=%x buffer=%x len=%x", addr[0], addr[1], *(short *)addr, alen, buffer, len); // test-only */
+
+ ptr = *(short *)addr;
+
+ /*
+ * Write till lword boundary
+ */
+ len2 = 4 - (*(short *)addr & 0x0003);
+ for (i=0; i<len2; i++)
+ {
+ eepromWriteByte(ptr++, *buffer++);
+ }
+
+ /*
+ * Write all lwords
+ */
+ len2 = (len - len2) >> 2;
+ for (i=0; i<len2; i++)
+ {
+ eepromWriteLong(ptr, *(unsigned int *)buffer);
+ buffer += 4;
+ ptr += 4;
+ }
+
+ /*
+ * Write last bytes
+ */
+ len2 = (*(short *)addr + len) & 0x0003;
+ for (i=0; i<len2; i++)
+ {
+ eepromWriteByte(ptr++, *buffer++);
+ }
+}
--- /dev/null
+#ifdef ECC_TEST
+static inline void ecc_off(void)
+{
+ *(volatile int *)(INTERNAL_REG_BASE_ADDR+0x4b4) &= ~0x00200000;
+}
+
+static inline void ecc_on(void)
+{
+ *(volatile int *)(INTERNAL_REG_BASE_ADDR+0x4b4) |= 0x00200000;
+}
+
+static int putshex(const char *buf, int len)
+{
+ int i;
+ for (i=0;i<len;i++) {
+ printf("%02x", buf[i]);
+ }
+ return 0;
+}
+
+static int char_memcpy(void *d, const void *s, int len)
+{
+ int i;
+ char *cd=d;
+ const char *cs=s;
+ for(i=0;i<len;i++) {
+ *(cd++)=*(cs++);
+ }
+ return 0;
+}
+
+static int memory_test(char *buf)
+{
+ const char src[][16]={
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
+ {0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02},
+ {0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04},
+ {0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08},
+ {0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10},
+ {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20},
+ {0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40},
+ {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80},
+ {0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55},
+ {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa},
+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}
+ };
+ const int foo[] = {0};
+ int i,j,a;
+
+ printf("\ntest @ %d %p\n", foo[0], buf);
+ for(i=0;i<12;i++) {
+ for(a=0;a<8;a++) {
+ const char *s=src[i]+a;
+ int align=(unsigned)(s)&0x7;
+ /* ecc_off(); */
+ memcpy(buf,s,8);
+ /* ecc_on(); */
+ putshex(s,8);
+ if(memcmp(buf,s,8)) {
+ putc('\n');
+ putshex(buf,8);
+ printf(" [FAIL] (%p) align=%d\n", s, align);
+ for(j=0;j<8;j++) {
+ s[j]==buf[j]?puts(" "):printf("%02x", (s[j])^(buf[j]));
+ }
+ putc('\n');
+ } else {
+ printf(" [PASS] (%p) align=%d\n", s, align);
+ }
+ /* ecc_off(); */
+ char_memcpy(buf,s,8);
+ /* ecc_on(); */
+ putshex(s,8);
+ if(memcmp(buf,s,8)) {
+ putc('\n');
+ putshex(buf,8);
+ printf(" [FAIL] (%p) align=%d\n", s, align);
+ for(j=0;j<8;j++) {
+ s[j]==buf[j]?puts(" "):printf("%02x", (s[j])^(buf[j]));
+ }
+ putc('\n');
+ } else {
+ printf(" [PASS] (%p) align=%d\n", s, align);
+ }
+ }
+ }
+
+ return 0;
+}
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * eth.h - header file for the polled mode GT ethernet driver
+ */
+
+#ifndef __GT6426x_ETH_H__
+#define __GT6426x_ETH_H__
+
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <common.h>
+
+typedef struct eth0_tx_desc_struct {
+ volatile __u32 bytecount_reserved;
+ volatile __u32 command_status;
+ volatile struct eth0_tx_desc_struct * next_desc;
+ /* Note - the following will not work for 64 bit addressing */
+ volatile unsigned char * buff_pointer;
+} eth0_tx_desc_single __attribute__ ((packed));
+
+typedef struct eth0_rx_desc_struct {
+ volatile __u32 buff_size_byte_count;
+ volatile __u32 command_status;
+ volatile struct eth0_rx_desc_struct * next_desc;
+ volatile unsigned char * buff_pointer;
+} eth0_rx_desc_single __attribute__ ((packed));
+
+#define NT 20 /* Number of Transmit buffers */
+#define NR 20 /* Number of Receive buffers */
+#define MAX_BUFF_SIZE (1536+2*CACHE_LINE_SIZE) /* 1600 */
+#define ETHERNET_PORTS_DIFFERENCE_OFFSETS 0x400
+
+unsigned long TDN_ETH0 , RDN_ETH0; /* Rx/Tx current Descriptor Number*/
+unsigned int EVB64260_ETH0_irq;
+
+#define CLOSED 0
+#define OPENED 1
+
+#define PORT_ETH0 0
+
+extern eth0_tx_desc_single *eth0_tx_desc;
+extern eth0_rx_desc_single *eth0_rx_desc;
+extern char *eth0_tx_buffer;
+extern char *eth0_rx_buffer[NR];
+extern char *eth_data;
+
+extern int gt6426x_eth_poll(void *v);
+extern int gt6426x_eth_transmit(void *v, volatile char *p, unsigned int s);
+extern void gt6426x_eth_disable(void *v);
+extern int gt6426x_eth_probe(void *v, bd_t *bis);
+
+#endif /* __GT64260x_ETH_H__ */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * John Clemens <clemens@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * mpsc.c - driver for console over the MPSC.
+ */
+
+#include <common.h>
+#include <config.h>
+#include <asm/cache.h>
+
+#include <malloc.h>
+#include "mpsc.h"
+
+int (*mpsc_putchar)(char ch) = mpsc_putchar_early;
+
+static volatile unsigned int *rx_desc_base=NULL;
+static unsigned int rx_desc_index=0;
+static volatile unsigned int *tx_desc_base=NULL;
+static unsigned int tx_desc_index=0;
+
+/* local function declarations */
+static int galmpsc_connect(int channel, int connect);
+static int galmpsc_route_serial(int channel, int connect);
+static int galmpsc_route_rx_clock(int channel, int brg);
+static int galmpsc_route_tx_clock(int channel, int brg);
+static int galmpsc_write_config_regs(int mpsc, int mode);
+static int galmpsc_config_channel_regs(int mpsc);
+static int galmpsc_set_char_length(int mpsc, int value);
+static int galmpsc_set_stop_bit_length(int mpsc, int value);
+static int galmpsc_set_parity(int mpsc, int value);
+static int galmpsc_enter_hunt(int mpsc);
+static int galmpsc_set_brkcnt(int mpsc, int value);
+static int galmpsc_set_tcschar(int mpsc, int value);
+static int galmpsc_set_snoop(int mpsc, int value);
+static int galmpsc_shutdown(int mpsc);
+
+static int galsdma_set_RFT(int channel);
+static int galsdma_set_SFM(int channel);
+static int galsdma_set_rxle(int channel);
+static int galsdma_set_txle(int channel);
+static int galsdma_set_burstsize(int channel, unsigned int value);
+static int galsdma_set_RC(int channel, unsigned int value);
+
+static int galbrg_set_CDV(int channel, int value);
+static int galbrg_enable(int channel);
+static int galbrg_disable(int channel);
+static int galbrg_set_clksrc(int channel, int value);
+static int galbrg_set_CUV(int channel, int value);
+
+static void galsdma_enable_rx(void);
+
+/* static int galbrg_reset(int channel); */
+
+#define SOFTWARE_CACHE_MANAGEMENT
+
+#ifdef SOFTWARE_CACHE_MANAGEMENT
+#define FLUSH_DCACHE(a,b) if(dcache_status()){clean_dcache_range((u32)(a),(u32)(b));}
+#define FLUSH_AND_INVALIDATE_DCACHE(a,b) if(dcache_status()){flush_dcache_range((u32)(a),(u32)(b));}
+#define INVALIDATE_DCACHE(a,b) if(dcache_status()){invalidate_dcache_range((u32)(a),(u32)(b));}
+#else
+#define FLUSH_DCACHE(a,b)
+#define FLUSH_AND_INVALIDATE_DCACHE(a,b)
+#define INVALIDATE_DCACHE(a,b)
+#endif
+
+
+/* GT64240A errata: cant read MPSC/BRG registers... so make mirrors in ram for read/modify write */
+#define MIRROR_HACK ((struct _tag_mirror_hack *)&(gd->mirror_hack))
+
+#define GT_REG_WRITE_MIRROR_G(a,d) {MIRROR_HACK->a ## _M = d; GT_REG_WRITE(a,d);}
+#define GTREGREAD_MIRROR_G(a) (MIRROR_HACK->a ## _M)
+
+#define GT_REG_WRITE_MIRROR(a,i,g,d) {MIRROR_HACK->a ## _M[i] = d; GT_REG_WRITE(a + (i*g),d);}
+#define GTREGREAD_MIRROR(a,i,g) (MIRROR_HACK->a ## _M[i])
+
+/* make sure this isn't bigger than 16 long words (u-boot.h) */
+struct _tag_mirror_hack {
+ unsigned GALMPSC_PROTOCONF_REG_M[2]; /* 8008 */
+ unsigned GALMPSC_CHANNELREG_1_M[2]; /* 800c */
+ unsigned GALMPSC_CHANNELREG_2_M[2]; /* 8010 */
+ unsigned GALBRG_0_CONFREG_M[2]; /* b200 */
+
+ unsigned GALMPSC_ROUTING_REGISTER_M; /* b400 */
+ unsigned GALMPSC_RxC_ROUTE_M; /* b404 */
+ unsigned GALMPSC_TxC_ROUTE_M; /* b408 */
+
+ unsigned int baudrate; /* current baudrate, for tsc delay calc */
+};
+
+/* static struct _tag_mirror_hack *mh = NULL; */
+
+/* special function for running out of flash. doesn't modify any
+ * global variables [josh] */
+int
+mpsc_putchar_early(char ch)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ int mpsc=CHANNEL;
+ int temp=GTREGREAD_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP);
+ galmpsc_set_tcschar(mpsc,ch);
+ GT_REG_WRITE(GALMPSC_CHANNELREG_2+(mpsc*GALMPSC_REG_GAP), temp|0x200);
+
+#define MAGIC_FACTOR (10*1000000)
+
+ udelay(MAGIC_FACTOR / MIRROR_HACK->baudrate);
+ return 0;
+}
+
+/* This is used after relocation, see serial.c and mpsc_init2 */
+static int
+mpsc_putchar_sdma(char ch)
+{
+ volatile unsigned int *p;
+ unsigned int temp;
+
+
+ /* align the descriptor */
+ p = tx_desc_base;
+ memset((void *)p, 0, 8 * sizeof(unsigned int));
+
+ /* fill one 64 bit buffer */
+ /* word swap, pad with 0 */
+ p[4] = 0; /* x */
+ p[5] = (unsigned int)ch; /* x */
+
+ /* CHANGED completely according to GT64260A dox - NTL */
+ p[0] = 0x00010001; /* 0 */
+ p[1] = DESC_OWNER | DESC_FIRST | DESC_LAST; /* 4 */
+ p[2] = 0; /* 8 */
+ p[3] = (unsigned int)&p[4]; /* c */
+
+#if 0
+ p[9] = DESC_FIRST | DESC_LAST;
+ p[10] = (unsigned int)&p[0];
+ p[11] = (unsigned int)&p[12];
+#endif
+
+ FLUSH_DCACHE(&p[0], &p[8]);
+
+ GT_REG_WRITE(GALSDMA_0_CUR_TX_PTR+(CHANNEL*GALSDMA_REG_DIFF),
+ (unsigned int)&p[0]);
+ GT_REG_WRITE(GALSDMA_0_FIR_TX_PTR+(CHANNEL*GALSDMA_REG_DIFF),
+ (unsigned int)&p[0]);
+
+ temp = GTREGREAD(GALSDMA_0_COM_REG+(CHANNEL*GALSDMA_REG_DIFF));
+ temp |= (TX_DEMAND | TX_STOP);
+ GT_REG_WRITE(GALSDMA_0_COM_REG+(CHANNEL*GALSDMA_REG_DIFF), temp);
+
+ INVALIDATE_DCACHE(&p[1], &p[2]);
+
+ while(p[1] & DESC_OWNER) {
+ udelay(100);
+ INVALIDATE_DCACHE(&p[1], &p[2]);
+ }
+
+ return 0;
+}
+
+char
+mpsc_getchar(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ static unsigned int done = 0;
+ volatile char ch;
+ unsigned int len=0, idx=0, temp;
+
+ volatile unsigned int *p;
+
+
+ do {
+ p=&rx_desc_base[rx_desc_index*8];
+
+ INVALIDATE_DCACHE(&p[0], &p[1]);
+ /* Wait for character */
+ while (p[1] & DESC_OWNER){
+ udelay(100);
+ INVALIDATE_DCACHE(&p[0], &p[1]);
+ }
+
+ /* Handle error case */
+ if (p[1] & (1<<15)) {
+ printf("oops, error: %08x\n", p[1]);
+
+ temp = GTREGREAD_MIRROR(GALMPSC_CHANNELREG_2,CHANNEL,GALMPSC_REG_GAP);
+ temp |= (1 << 23);
+ GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_2, CHANNEL,GALMPSC_REG_GAP, temp);
+
+ /* Can't poll on abort bit, so we just wait. */
+ udelay(100);
+
+ galsdma_enable_rx();
+ }
+
+ /* Number of bytes left in this descriptor */
+ len = p[0] & 0xffff;
+
+ if (len) {
+ /* Where to look */
+ idx = 5;
+ if (done > 3) idx = 4;
+ if (done > 7) idx = 7;
+ if (done > 11) idx = 6;
+
+ INVALIDATE_DCACHE(&p[idx], &p[idx+1]);
+ ch = p[idx] & 0xff;
+ done++;
+ }
+
+ if (done < len) {
+ /* this descriptor has more bytes still
+ * shift down the char we just read, and leave the
+ * buffer in place for the next time around
+ */
+ p[idx] = p[idx] >> 8;
+ FLUSH_DCACHE(&p[idx], &p[idx+1]);
+ }
+
+ if (done == len) {
+ /* nothing left in this descriptor.
+ * go to next one
+ */
+ p[1] = DESC_OWNER | DESC_FIRST | DESC_LAST;
+ p[0] = 0x00100000;
+ FLUSH_DCACHE(&p[0], &p[1]);
+ /* Next descriptor */
+ rx_desc_index = (rx_desc_index + 1) % RX_DESC;
+ done = 0;
+ }
+ } while (len==0); /* galileo bug.. len might be zero */
+
+ return ch;
+}
+
+int
+mpsc_test_char(void)
+{
+ volatile unsigned int *p=&rx_desc_base[rx_desc_index*8];
+
+ INVALIDATE_DCACHE(&p[1], &p[2]);
+
+ if (p[1] & DESC_OWNER) return 0;
+ else return 1;
+}
+
+int
+mpsc_init(int baud)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ memset(MIRROR_HACK, 0, sizeof(struct _tag_mirror_hack));
+ MIRROR_HACK->GALMPSC_ROUTING_REGISTER_M=0x3fffffff;
+
+ /* BRG CONFIG */
+ galbrg_set_baudrate(CHANNEL, baud);
+#ifdef CONFIG_ZUMA_V2
+ galbrg_set_clksrc(CHANNEL,0x8); /* connect TCLK -> BRG */
+#else
+ galbrg_set_clksrc(CHANNEL,0);
+#endif
+ galbrg_set_CUV(CHANNEL, 0);
+ galbrg_enable(CHANNEL);
+
+ /* Set up clock routing */
+ galmpsc_connect(CHANNEL, GALMPSC_CONNECT);
+ galmpsc_route_serial(CHANNEL, GALMPSC_CONNECT);
+ galmpsc_route_rx_clock(CHANNEL, CHANNEL);
+ galmpsc_route_tx_clock(CHANNEL, CHANNEL);
+
+ /* reset MPSC state */
+ galmpsc_shutdown(CHANNEL);
+
+ /* SDMA CONFIG */
+ galsdma_set_burstsize(CHANNEL, L1_CACHE_BYTES/8); /* in 64 bit words (8 bytes) */
+ galsdma_set_txle(CHANNEL);
+ galsdma_set_rxle(CHANNEL);
+ galsdma_set_RC(CHANNEL, 0xf);
+ galsdma_set_SFM(CHANNEL);
+ galsdma_set_RFT(CHANNEL);
+
+ /* MPSC CONFIG */
+ galmpsc_write_config_regs(CHANNEL, GALMPSC_UART);
+ galmpsc_config_channel_regs(CHANNEL);
+ galmpsc_set_char_length(CHANNEL, GALMPSC_CHAR_LENGTH_8); /* 8 */
+ galmpsc_set_parity(CHANNEL, GALMPSC_PARITY_NONE); /* N */
+ galmpsc_set_stop_bit_length(CHANNEL, GALMPSC_STOP_BITS_1); /* 1 */
+
+ /* COMM_MPSC CONFIG */
+#ifdef SOFTWARE_CACHE_MANAGEMENT
+ galmpsc_set_snoop(CHANNEL, 0); /* disable snoop */
+#else
+ galmpsc_set_snoop(CHANNEL, 1); /* enable snoop */
+#endif
+
+ return 0;
+}
+
+void
+mpsc_init2(void)
+{
+ int i;
+
+ mpsc_putchar = mpsc_putchar_sdma;
+
+ /* RX descriptors */
+ rx_desc_base = (unsigned int *)malloc(((RX_DESC+1)*8) *
+ sizeof(unsigned int));
+
+ /* align descriptors */
+ rx_desc_base = (unsigned int *)
+ (((unsigned int)rx_desc_base+32) & 0xFFFFFFF0);
+
+ rx_desc_index = 0;
+
+ memset((void *)rx_desc_base, 0, (RX_DESC*8)*sizeof(unsigned int));
+
+ for (i = 0; i < RX_DESC; i++) {
+ rx_desc_base[i*8 + 3] = (unsigned int)&rx_desc_base[i*8 + 4]; /* Buffer */
+ rx_desc_base[i*8 + 2] = (unsigned int)&rx_desc_base[(i+1)*8]; /* Next descriptor */
+ rx_desc_base[i*8 + 1] = DESC_OWNER | DESC_FIRST | DESC_LAST; /* Command & control */
+ rx_desc_base[i*8] = 0x00100000;
+ }
+ rx_desc_base[(i-1)*8 + 2] = (unsigned int)&rx_desc_base[0];
+
+ FLUSH_DCACHE(&rx_desc_base[0], &rx_desc_base[RX_DESC*8]);
+ GT_REG_WRITE(GALSDMA_0_CUR_RX_PTR+(CHANNEL*GALSDMA_REG_DIFF),
+ (unsigned int)&rx_desc_base[0]);
+
+ /* TX descriptors */
+ tx_desc_base = (unsigned int *)malloc(((TX_DESC+1)*8) *
+ sizeof(unsigned int));
+
+ /* align descriptors */
+ tx_desc_base = (unsigned int *)
+ (((unsigned int)tx_desc_base+32) & 0xFFFFFFF0);
+
+ tx_desc_index = -1;
+
+ memset((void *)tx_desc_base, 0, (TX_DESC*8)*sizeof(unsigned int));
+
+ for (i = 0; i < TX_DESC; i++) {
+ tx_desc_base[i*8 + 5] = (unsigned int)0x23232323;
+ tx_desc_base[i*8 + 4] = (unsigned int)0x23232323;
+ tx_desc_base[i*8 + 3] = (unsigned int)&tx_desc_base[i*8 + 4];
+ tx_desc_base[i*8 + 2] = (unsigned int)&tx_desc_base[(i+1)*8];
+ tx_desc_base[i*8 + 1] = DESC_OWNER | DESC_FIRST | DESC_LAST;
+
+ /* set sbytecnt and shadow byte cnt to 1 */
+ tx_desc_base[i*8] = 0x00010001;
+ }
+ tx_desc_base[(i-1)*8 + 2] = (unsigned int)&tx_desc_base[0];
+
+ FLUSH_DCACHE(&tx_desc_base[0], &tx_desc_base[TX_DESC*8]);
+
+ udelay(100);
+
+ galsdma_enable_rx();
+
+ return;
+}
+
+int
+galbrg_set_baudrate(int channel, int rate)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ int clock;
+
+ galbrg_disable(channel);
+
+#ifdef CONFIG_ZUMA_V2
+ /* from tclk */
+ clock = (CFG_BUS_HZ/(16*rate)) - 1;
+#else
+ clock = (3686400/(16*rate)) - 1;
+#endif
+
+ galbrg_set_CDV(channel, clock);
+
+ galbrg_enable(channel);
+
+ MIRROR_HACK->baudrate = rate;
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------ */
+
+/* Below are all the private functions that no one else needs */
+
+static int
+galbrg_set_CDV(int channel, int value)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ unsigned int temp;
+
+ temp = GTREGREAD_MIRROR(GALBRG_0_CONFREG, channel, GALBRG_REG_GAP);
+ temp &= 0xFFFF0000;
+ temp |= (value & 0x0000FFFF);
+ GT_REG_WRITE_MIRROR(GALBRG_0_CONFREG,channel,GALBRG_REG_GAP, temp);
+
+ return 0;
+}
+
+static int
+galbrg_enable(int channel)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ unsigned int temp;
+
+ temp = GTREGREAD_MIRROR(GALBRG_0_CONFREG, channel, GALBRG_REG_GAP);
+ temp |= 0x00010000;
+ GT_REG_WRITE_MIRROR(GALBRG_0_CONFREG, channel, GALBRG_REG_GAP,temp);
+
+ return 0;
+}
+
+static int
+galbrg_disable(int channel)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ unsigned int temp;
+
+ temp = GTREGREAD_MIRROR(GALBRG_0_CONFREG, channel, GALBRG_REG_GAP);
+ temp &= 0xFFFEFFFF;
+ GT_REG_WRITE_MIRROR(GALBRG_0_CONFREG, channel, GALBRG_REG_GAP,temp);
+
+ return 0;
+}
+
+static int
+galbrg_set_clksrc(int channel, int value)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ unsigned int temp;
+
+ temp = GTREGREAD_MIRROR(GALBRG_0_CONFREG,channel, GALBRG_REG_GAP);
+ temp &= 0xFF83FFFF;
+ temp |= (value << 18);
+ GT_REG_WRITE_MIRROR(GALBRG_0_CONFREG,channel, GALBRG_REG_GAP,temp);
+
+ return 0;
+}
+
+static int
+galbrg_set_CUV(int channel, int value)
+{
+ GT_REG_WRITE(GALBRG_0_BTREG + (channel * GALBRG_REG_GAP), value);
+
+ return 0;
+}
+
+#if 0
+static int
+galbrg_reset(int channel)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD(GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP));
+ temp |= 0x20000;
+ GT_REG_WRITE(GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP), temp);
+
+ return 0;
+}
+#endif
+
+static int
+galsdma_set_RFT(int channel)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF));
+ temp |= 0x00000001;
+ GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), temp);
+
+ return 0;
+}
+
+static int
+galsdma_set_SFM(int channel)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF));
+ temp |= 0x00000002;
+ GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), temp);
+
+ return 0;
+}
+
+static int
+galsdma_set_rxle(int channel)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF));
+ temp |= 0x00000040;
+ GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), temp);
+
+ return 0;
+}
+
+static int
+galsdma_set_txle(int channel)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF));
+ temp |= 0x00000080;
+ GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), temp);
+
+ return 0;
+}
+
+static int
+galsdma_set_RC(int channel, unsigned int value)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF));
+ temp &= ~0x0000003c;
+ temp |= (value << 2);
+ GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), temp);
+
+ return 0;
+}
+
+static int
+galsdma_set_burstsize(int channel, unsigned int value)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF));
+ temp &= 0xFFFFCFFF;
+ switch (value) {
+ case 8:
+ GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF),
+ (temp | (0x3 << 12)));
+ break;
+
+ case 4:
+ GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF),
+ (temp | (0x2 << 12)));
+ break;
+
+ case 2:
+ GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF),
+ (temp | (0x1 << 12)));
+ break;
+
+ case 1:
+ GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF),
+ (temp | (0x0 << 12)));
+ break;
+
+ default:
+ return -1;
+ break;
+ }
+
+ return 0;
+}
+
+static int
+galmpsc_connect(int channel, int connect)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ unsigned int temp;
+
+ temp = GTREGREAD_MIRROR_G(GALMPSC_ROUTING_REGISTER);
+
+ if ((channel == 0) && connect)
+ temp &= ~0x00000007;
+ else if ((channel == 1) && connect)
+ temp &= ~(0x00000007 << 6);
+ else if ((channel == 0) && !connect)
+ temp |= 0x00000007;
+ else
+ temp |= (0x00000007 << 6);
+
+ /* Just in case... */
+ temp &= 0x3fffffff;
+
+ GT_REG_WRITE_MIRROR_G(GALMPSC_ROUTING_REGISTER, temp);
+
+ return 0;
+}
+
+static int
+galmpsc_route_serial(int channel, int connect)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD(GALMPSC_SERIAL_MULTIPLEX);
+
+ if ((channel == 0) && connect)
+ temp |= 0x00000100;
+ else if ((channel == 1) && connect)
+ temp |= 0x00001000;
+ else if ((channel == 0) && !connect)
+ temp &= ~0x00000100;
+ else
+ temp &= ~0x00001000;
+
+ GT_REG_WRITE(GALMPSC_SERIAL_MULTIPLEX,temp);
+
+ return 0;
+}
+
+static int
+galmpsc_route_rx_clock(int channel, int brg)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ unsigned int temp;
+
+ temp = GTREGREAD_MIRROR_G(GALMPSC_RxC_ROUTE);
+
+ if (channel == 0)
+ temp |= brg;
+ else
+ temp |= (brg << 8);
+
+ GT_REG_WRITE_MIRROR_G(GALMPSC_RxC_ROUTE,temp);
+
+ return 0;
+}
+
+static int
+galmpsc_route_tx_clock(int channel, int brg)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ unsigned int temp;
+
+ temp = GTREGREAD_MIRROR_G(GALMPSC_TxC_ROUTE);
+
+ if (channel == 0)
+ temp |= brg;
+ else
+ temp |= (brg << 8);
+
+ GT_REG_WRITE_MIRROR_G(GALMPSC_TxC_ROUTE,temp);
+
+ return 0;
+}
+
+static int
+galmpsc_write_config_regs(int mpsc, int mode)
+{
+ if (mode == GALMPSC_UART) {
+ /* Main config reg Low (Null modem, Enable Tx/Rx, UART mode) */
+ GT_REG_WRITE(GALMPSC_MCONF_LOW + (mpsc*GALMPSC_REG_GAP),
+ 0x000004c4);
+
+ /* Main config reg High (32x Rx/Tx clock mode, width=8bits */
+ GT_REG_WRITE(GALMPSC_MCONF_HIGH +(mpsc*GALMPSC_REG_GAP),
+ 0x024003f8);
+ /* 22 2222 1111 */
+ /* 54 3210 9876 */
+ /* 0000 0010 0000 0000 */
+ /* 1 */
+ /* 098 7654 3210 */
+ /* 0000 0011 1111 1000 */
+ } else
+ return -1;
+
+ return 0;
+}
+
+static int
+galmpsc_config_channel_regs(int mpsc)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_1,mpsc,GALMPSC_REG_GAP, 0);
+ GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP, 0);
+ GT_REG_WRITE(GALMPSC_CHANNELREG_3+(mpsc*GALMPSC_REG_GAP), 1);
+ GT_REG_WRITE(GALMPSC_CHANNELREG_4+(mpsc*GALMPSC_REG_GAP), 0);
+ GT_REG_WRITE(GALMPSC_CHANNELREG_5+(mpsc*GALMPSC_REG_GAP), 0);
+ GT_REG_WRITE(GALMPSC_CHANNELREG_6+(mpsc*GALMPSC_REG_GAP), 0);
+ GT_REG_WRITE(GALMPSC_CHANNELREG_7+(mpsc*GALMPSC_REG_GAP), 0);
+ GT_REG_WRITE(GALMPSC_CHANNELREG_8+(mpsc*GALMPSC_REG_GAP), 0);
+ GT_REG_WRITE(GALMPSC_CHANNELREG_9+(mpsc*GALMPSC_REG_GAP), 0);
+ GT_REG_WRITE(GALMPSC_CHANNELREG_10+(mpsc*GALMPSC_REG_GAP), 0);
+
+ galmpsc_set_brkcnt(mpsc, 0x3);
+ galmpsc_set_tcschar(mpsc, 0xab);
+
+ return 0;
+}
+
+static int
+galmpsc_set_brkcnt(int mpsc, int value)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ unsigned int temp;
+
+ temp = GTREGREAD_MIRROR(GALMPSC_CHANNELREG_1,mpsc,GALMPSC_REG_GAP);
+ temp &= 0x0000FFFF;
+ temp |= (value << 16);
+ GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_1,mpsc,GALMPSC_REG_GAP, temp);
+
+ return 0;
+}
+
+static int
+galmpsc_set_tcschar(int mpsc, int value)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ unsigned int temp;
+
+ temp = GTREGREAD_MIRROR(GALMPSC_CHANNELREG_1,mpsc,GALMPSC_REG_GAP);
+ temp &= 0xFFFF0000;
+ temp |= value;
+ GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_1,mpsc,GALMPSC_REG_GAP, temp);
+
+ return 0;
+}
+
+static int
+galmpsc_set_char_length(int mpsc, int value)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ unsigned int temp;
+
+ temp = GTREGREAD_MIRROR(GALMPSC_PROTOCONF_REG,mpsc,GALMPSC_REG_GAP);
+ temp &= 0xFFFFCFFF;
+ temp |= (value << 12);
+ GT_REG_WRITE_MIRROR(GALMPSC_PROTOCONF_REG,mpsc,GALMPSC_REG_GAP, temp);
+
+ return 0;
+}
+
+static int
+galmpsc_set_stop_bit_length(int mpsc, int value)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ unsigned int temp;
+
+ temp = GTREGREAD_MIRROR(GALMPSC_PROTOCONF_REG,mpsc,GALMPSC_REG_GAP);
+ temp |= (value << 14);
+ GT_REG_WRITE_MIRROR(GALMPSC_PROTOCONF_REG,mpsc,GALMPSC_REG_GAP,temp);
+
+ return 0;
+}
+
+static int
+galmpsc_set_parity(int mpsc, int value)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ unsigned int temp;
+
+ temp = GTREGREAD_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP);
+ if (value != -1) {
+ temp &= 0xFFF3FFF3;
+ temp |= ((value << 18) | (value << 2));
+ temp |= ((value << 17) | (value << 1));
+ } else {
+ temp &= 0xFFF1FFF1;
+ }
+
+ GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP, temp);
+
+ return 0;
+}
+
+static int
+galmpsc_enter_hunt(int mpsc)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ int temp;
+
+ temp = GTREGREAD_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP);
+ temp |= 0x80000000;
+ GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP, temp);
+
+ /* Should Poll on Enter Hunt bit, but the register is write-only */
+ /* errata suggests pausing 100 system cycles */
+ udelay(100);
+
+ return 0;
+}
+
+
+static int
+galmpsc_shutdown(int mpsc)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ unsigned int temp;
+
+ /* cause RX abort (clears RX) */
+ temp = GTREGREAD_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP);
+ temp |= MPSC_RX_ABORT | MPSC_TX_ABORT;
+ temp &= ~MPSC_ENTER_HUNT;
+ GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP,temp);
+
+ GT_REG_WRITE(GALSDMA_0_COM_REG, 0);
+ GT_REG_WRITE(GALSDMA_0_COM_REG, SDMA_TX_ABORT | SDMA_RX_ABORT);
+
+ /* shut down the MPSC */
+ GT_REG_WRITE(GALMPSC_MCONF_LOW, 0);
+ GT_REG_WRITE(GALMPSC_MCONF_HIGH, 0);
+ GT_REG_WRITE_MIRROR(GALMPSC_PROTOCONF_REG, mpsc, GALMPSC_REG_GAP,0);
+
+ udelay(100);
+
+ /* shut down the sdma engines. */
+ /* reset config to default */
+ GT_REG_WRITE(GALSDMA_0_CONF_REG, 0x000000fc);
+
+ udelay(100);
+
+ /* clear the SDMA current and first TX and RX pointers */
+ GT_REG_WRITE(GALSDMA_0_CUR_RX_PTR, 0);
+ GT_REG_WRITE(GALSDMA_0_CUR_TX_PTR, 0);
+ GT_REG_WRITE(GALSDMA_0_FIR_TX_PTR, 0);
+
+ udelay(100);
+
+ return 0;
+}
+
+static void
+galsdma_enable_rx(void)
+{
+ int temp;
+
+ /* Enable RX processing */
+ temp = GTREGREAD(GALSDMA_0_COM_REG+(CHANNEL*GALSDMA_REG_DIFF));
+ temp |= RX_ENABLE;
+ GT_REG_WRITE(GALSDMA_0_COM_REG+(CHANNEL*GALSDMA_REG_DIFF), temp);
+
+ galmpsc_enter_hunt(CHANNEL);
+}
+
+static int
+galmpsc_set_snoop(int mpsc, int value)
+{
+ int reg = mpsc ? MPSC_1_ADDRESS_CONTROL_LOW : MPSC_0_ADDRESS_CONTROL_LOW;
+ int temp=GTREGREAD(reg);
+ if(value)
+ temp |= (1<< 6) | (1<<14) | (1<<22) | (1<<30);
+ else
+ temp &= ~((1<< 6) | (1<<14) | (1<<22) | (1<<30));
+ GT_REG_WRITE(reg, temp);
+ return 0;
+}
--- /dev/null
+#include <common.h>
+#include <malloc.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+#include <command.h>
+#include <cmd_bsp.h>
+#endif
+
+#include <pci.h>
+#include <galileo/pci.h>
+#include "zuma_pbb.h"
+
+#undef DEBUG
+
+#define PAT_LO 0x00010203
+#define PAT_HI 0x04050607
+
+static PBB_DMA_REG_MAP *zuma_pbb_reg = NULL;
+
+static char test_buf1[2048];
+static char test_buf2[2048];
+
+int zuma_test_dma (int cmd, int size)
+{
+ static const char *const test_legend[] = {
+ "write", "verify",
+ "copy", "compare",
+ "write inc", "verify inc"
+ };
+ register int i, j;
+ unsigned int p1 = ((unsigned int) test_buf1 + 0xff) & (~0xff);
+ unsigned int p2 = ((unsigned int) test_buf2 + 0xff) & (~0xff);
+ volatile unsigned int *ps = (unsigned int *) p1;
+ volatile unsigned int *pd = (unsigned int *) p2;
+ unsigned int funct, pat_lo = PAT_LO, pat_hi = PAT_HI;
+ DMA_INT_STATUS stat;
+ int ret = 0;
+
+ if (!zuma_pbb_reg) {
+ printf ("not initted\n");
+ return -1;
+ }
+
+ if (cmd < 0 || cmd > 5) {
+ printf ("inv cmd %d\n", cmd);
+ return -1;
+ }
+
+ if (cmd == 2 || cmd == 3) {
+ /* not implemented */
+ return 0;
+ }
+
+ if (size <= 0 || size > 1024)
+ size = 1024;
+
+ size &= (~7); /* throw away bottom 3 bits */
+
+ p1 = ((unsigned int) test_buf1 + 0xff) & (~0xff);
+ p2 = ((unsigned int) test_buf2 + 0xff) & (~0xff);
+
+ memset ((void *) p1, 0, size);
+ memset ((void *) p2, 0, size);
+
+ for (i = 0; i < size / 4; i += 2) {
+ ps[i] = pat_lo;
+ ps[i + 1] = pat_hi;
+ if (cmd == 4 || cmd == 5) {
+ unsigned char *pl = (unsigned char *) &pat_lo;
+ unsigned char *ph = (unsigned char *) &pat_hi;
+
+ for (j = 0; j < 4; j++) {
+ pl[j] += 8;
+ ph[j] += 8;
+ }
+ }
+ }
+
+ funct = (1 << 31) | (cmd << 24) | (size);
+
+ zuma_pbb_reg->int_mask.pci_bits.chan0 =
+ EOF_RX_FLAG | EOF_TX_FLAG | EOB_TX_FLAG;
+
+ zuma_pbb_reg->debug_57 = PAT_LO; /* patl */
+ zuma_pbb_reg->debug_58 = PAT_HI; /* path */
+
+ zuma_pbb_reg->debug_54 = cpu_to_le32 (p1); /* src 0x01b0 */
+ zuma_pbb_reg->debug_55 = cpu_to_le32 (p2); /* dst 0x01b8 */
+ zuma_pbb_reg->debug_56 = cpu_to_le32 (funct); /* func, 0x01c0 */
+
+ /* give DMA time to chew on things.. dont use DRAM or PCI */
+ /* if you can avoid it. */
+ do {
+ for (i = 0; i < 1000 * 10; i++);
+ } while (le32_to_cpu (zuma_pbb_reg->debug_56) & (1 << 31));
+
+ stat.word = zuma_pbb_reg->status.word;
+ zuma_pbb_reg->int_mask.word = 0;
+
+ printf ("stat: %08x (%x)\n", stat.word, stat.pci_bits.chan0);
+
+ printf ("func: %08x\n", le32_to_cpu (zuma_pbb_reg->debug_56));
+ printf ("src @%08x: %08x %08x %08x %08x\n", p1, ps[0], ps[1], ps[2],
+ ps[3]);
+ printf ("dst @%08x: %08x %08x %08x %08x\n", p2, pd[0], pd[1], pd[2],
+ pd[3]);
+ printf ("func: %08x\n", le32_to_cpu (zuma_pbb_reg->debug_56));
+
+
+ if (cmd == 0 || cmd == 4) {
+ /* this is a write */
+ if (!(stat.pci_bits.chan0 & EOF_RX_FLAG) || /* not done */
+ (memcmp ((void *) ps, (void *) pd, size) != 0)) { /* cmp error */
+ for (i = 0; i < size / 4; i += 2) {
+ if ((ps[i] != pd[i]) || (ps[i + 1] != pd[i + 1])) {
+ printf ("s @%p:%08x %08x\n", &ps[i], ps[i], ps[i + 1]);
+ printf ("d @%p:%08x %08x\n", &pd[i], pd[i], pd[i + 1]);
+ }
+ }
+ ret = -1;
+ }
+ } else {
+ /* this is a verify */
+ if (!(stat.pci_bits.chan0 & EOF_TX_FLAG) || /* not done */
+ (stat.pci_bits.chan0 & EOB_TX_FLAG)) { /* cmp error */
+ printf ("%08x: %08x %08x\n",
+ le32_to_cpu (zuma_pbb_reg->debug_63),
+ zuma_pbb_reg->debug_61, zuma_pbb_reg->debug_62);
+ ret = -1;
+ }
+ }
+
+ printf ("%s cmd %d, %d bytes: %s!\n", test_legend[cmd], cmd, size,
+ (ret == 0) ? "PASSED" : "FAILED");
+ return 0;
+}
+
+void zuma_init_pbb (void)
+{
+ unsigned int iobase;
+ pci_dev_t dev =
+ pci_find_device (VENDOR_ID_ZUMA, DEVICE_ID_ZUMA_PBB, 0);
+
+ if (dev == -1) {
+ printf ("no zuma pbb\n");
+ return;
+ }
+
+ pci_read_config_dword (dev, PCI_BASE_ADDRESS_0, &iobase);
+
+ zuma_pbb_reg =
+ (PBB_DMA_REG_MAP *) (iobase & PCI_BASE_ADDRESS_MEM_MASK);
+
+ if (!zuma_pbb_reg) {
+ printf ("zuma pbb bar none! (hah hah, get it?)\n");
+ return;
+ }
+
+ zuma_pbb_reg->int_mask.word = 0;
+
+ printf ("pbb @ %p v%d.%d, timestamp %08x\n", zuma_pbb_reg,
+ zuma_pbb_reg->version.pci_bits.rev_major,
+ zuma_pbb_reg->version.pci_bits.rev_minor,
+ zuma_pbb_reg->timestamp);
+
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+
+static int last_cmd = 4; /* write increment */
+static int last_size = 64;
+
+int
+do_zuma_init_pbb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ zuma_init_pbb ();
+ return 0;
+}
+
+int
+do_zuma_test_dma (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ if (argc > 1) {
+ last_cmd = simple_strtoul (argv[1], NULL, 10);
+ }
+ if (argc > 2) {
+ last_size = simple_strtoul (argv[2], NULL, 10);
+ }
+ zuma_test_dma (last_cmd, last_size);
+ return 0;
+}
+
+int
+do_zuma_init_mbox (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ zuma_mbox_init ();
+ return 0;
+}
+
+#endif /* CFG_CMD_BSP */
--- /dev/null
+#include <common.h>
+#include <galileo/pci.h>
+#include <net.h>
+#include <pci.h>
+
+#include "zuma_pbb.h"
+#include "zuma_pbb_mbox.h"
+
+
+struct _zuma_mbox_dev zuma_mbox_dev;
+
+
+static int zuma_mbox_write(struct _zuma_mbox_dev *dev, unsigned int data)
+{
+ unsigned int status, count = 0, i;
+
+ status = (volatile int)le32_to_cpu(dev->sip->mbox_status);
+
+ while((status & OUT_PENDING) && count < 1000) {
+ count++;
+ for(i=0;i<1000;i++);
+ status = (volatile int)le32_to_cpu(dev->sip->mbox_status);
+ }
+ if(count < 1000) {
+ /* if SET it means msg pending */
+ /* printf("mbox real write %08x\n",data); */
+ dev->sip->mbox_out = cpu_to_le32(data);
+ return 4;
+ }
+
+ printf("mbox tx timeout\n");
+ return 0;
+}
+
+static int zuma_mbox_read(struct _zuma_mbox_dev *dev, unsigned int *data)
+{
+ unsigned int status, count = 0, i;
+
+ status = (volatile int)le32_to_cpu(dev->sip->mbox_status);
+
+ while(!(status & IN_VALID) && count < 1000) {
+ count++;
+ for(i=0;i<1000;i++);
+ status = (volatile int)le32_to_cpu(dev->sip->mbox_status);
+ }
+ if(count < 1000) {
+ /* if SET it means msg pending */
+ *data=le32_to_cpu(dev->sip->mbox_in);
+ /*printf("mbox real read %08x\n", *data); */
+ return 4;
+ }
+ printf("mbox rx timeout\n");
+ return 0;
+}
+
+static int zuma_mbox_do_one_mailbox(unsigned int out, unsigned int *in)
+{
+ int ret;
+ ret=zuma_mbox_write(&zuma_mbox_dev,out);
+ /*printf("write 0x%08x (%d bytes)\n", out, ret); */
+ if(ret!=4) return -1;
+ ret=zuma_mbox_read(&zuma_mbox_dev,in);
+ /*printf("read 0x%08x (%d bytes)\n", *in, ret); */
+ if(ret!=4) return -1;
+ return 0;
+}
+
+
+#define RET_IF_FAILED(x) if ((x) == -1) return -1
+
+static int zuma_mbox_do_all_mailbox(void)
+{
+ unsigned int data_in;
+ unsigned short sdata_in;
+
+ RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_START, &data_in));
+
+ RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_MACL, &data_in));
+ memcpy(zuma_acc_mac+2,&data_in,4);
+ RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_MACH, &data_in));
+ sdata_in=data_in&0xffff;
+ memcpy(zuma_acc_mac,&sdata_in,2);
+
+ RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_IP, &data_in));
+ zuma_ip=data_in;
+
+ RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_SLOT, &data_in));
+ zuma_slot_bac=data_in>>3;
+
+ RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_BAUD, &data_in));
+ zuma_console_baud = data_in & 0xffff;
+ zuma_debug_baud = data_in >> 16;
+
+ RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_ENG_PRV_MACL, &data_in));
+ memcpy(zuma_prv_mac+2,&data_in,4);
+ RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_ENG_PRV_MACH, &data_in));
+ sdata_in=data_in&0xffff;
+ memcpy(zuma_prv_mac,&sdata_in,2);
+
+ RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_DONE, &data_in));
+
+ return 0;
+}
+
+
+static void
+zuma_mbox_dump(void)
+{
+ printf("ACC MAC=%04x%08x\n",*(unsigned short *)(&zuma_acc_mac),*(unsigned int *)((char *)&zuma_acc_mac+2));
+ printf("PRV MAC=%04x%08x\n",*(unsigned short *)(&zuma_prv_mac),*(unsigned int *)((char *)&zuma_prv_mac+2));
+ printf("slot:bac=%d:%d\n",(zuma_slot_bac>>2)&0xf, zuma_slot_bac & 0x3);
+ printf("BAUD1=%d BAUD2=%d\n",zuma_console_baud,zuma_debug_baud);
+}
+
+
+static void
+zuma_mbox_setenv(void)
+{
+ unsigned char *data, buf[32];
+ unsigned char save = 0;
+
+ data = getenv("baudrate");
+
+ if(!data || (zuma_console_baud != simple_strtoul(data, NULL, 10))) {
+ sprintf(buf, "%6d", zuma_console_baud);
+ setenv("baudrate", buf);
+ save=1;
+ printf("baudrate doesn't match from mbox\n");
+ }
+
+ ip_to_string(zuma_ip, buf);
+ setenv("ipaddr", buf);
+
+ sprintf(buf,"%02x:%02x:%02x:%02x:%02x:%02x",
+ zuma_prv_mac[0],
+ zuma_prv_mac[1],
+ zuma_prv_mac[2],
+ zuma_prv_mac[3],
+ zuma_prv_mac[4],
+ zuma_prv_mac[5]);
+ setenv("ethaddr", buf);
+
+ sprintf(buf,"%02x",zuma_slot_bac);
+ setenv("bacslot", buf);
+
+ if(save)
+ saveenv();
+}
+
+/**
+ * zuma_mbox_init:
+ */
+
+int zuma_mbox_init(void)
+{
+ unsigned int iobase;
+ memset(&zuma_mbox_dev, 0, sizeof(struct _zuma_mbox_dev));
+
+ zuma_mbox_dev.dev = pci_find_device(VENDOR_ID_ZUMA, DEVICE_ID_ZUMA_PBB, 0);
+
+ if(zuma_mbox_dev.dev == -1) {
+ printf("no zuma pbb\n");
+ return -1;
+ }
+
+ pci_read_config_dword(zuma_mbox_dev.dev, PCI_BASE_ADDRESS_0, &iobase);
+
+ zuma_mbox_dev.sip = (PBB_DMA_REG_MAP *) (iobase & PCI_BASE_ADDRESS_MEM_MASK);
+
+ zuma_mbox_dev.sip->int_mask.word=0;
+
+ printf("pbb @ %p v%d.%d, timestamp %08x\n", zuma_mbox_dev.sip,
+ zuma_mbox_dev.sip->version.pci_bits.rev_major,
+ zuma_mbox_dev.sip->version.pci_bits.rev_minor,
+ zuma_mbox_dev.sip->timestamp);
+
+ if (zuma_mbox_do_all_mailbox() == -1) {
+ printf("mailbox failed.. no ACC?\n");
+ return -1;
+ }
+
+ zuma_mbox_dump();
+
+ zuma_mbox_setenv();
+
+ return 0;
+}
--- /dev/null
+/*
+ * (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
+ */
+
+#include <common.h>
+#include <config.h>
+#include <mpc8xx.h>
+#include "fads.h"
+
+/* ------------------------------------------------------------------------- */
+
+#define _NOT_USED_ 0xFFFFFFFF
+
+#if defined(CONFIG_DRAM_50MHZ)
+/* 50MHz tables */
+const uint dram_60ns[] =
+{ 0x8fffec24, 0x0fffec04, 0x0cffec04, 0x00ffec04,
+ 0x00ffec00, 0x37ffec47, 0xffffffff, 0xffffffff,
+ 0x8fffec24, 0x0fffec04, 0x08ffec04, 0x00ffec0c,
+ 0x03ffec00, 0x00ffec44, 0x00ffcc08, 0x0cffcc44,
+ 0x00ffec0c, 0x03ffec00, 0x00ffec44, 0x00ffcc00,
+ 0x3fffc847, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x8fafcc24, 0x0fafcc04, 0x0cafcc00, 0x11bfcc47,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x8fafcc24, 0x0fafcc04, 0x0cafcc00, 0x03afcc4c,
+ 0x0cafcc00, 0x03afcc4c, 0x0cafcc00, 0x03afcc4c,
+ 0x0cafcc00, 0x33bfcc4f, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xc0ffcc84, 0x00ffcc04, 0x07ffcc04, 0x3fffcc06,
+ 0xffffcc85, 0xffffcc05, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff };
+
+const uint dram_70ns[] =
+{ 0x8fffcc24, 0x0fffcc04, 0x0cffcc04, 0x00ffcc04,
+ 0x00ffcc00, 0x37ffcc47, 0xffffffff, 0xffffffff,
+ 0x8fffcc24, 0x0fffcc04, 0x0cffcc04, 0x00ffcc04,
+ 0x00ffcc08, 0x0cffcc44, 0x00ffec0c, 0x03ffec00,
+ 0x00ffec44, 0x00ffcc08, 0x0cffcc44, 0x00ffec04,
+ 0x00ffec00, 0x3fffec47, 0xffffffff, 0xffffffff,
+ 0x8fafcc24, 0x0fafcc04, 0x0cafcc00, 0x11bfcc47,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x8fafcc24, 0x0fafcc04, 0x0cafcc00, 0x03afcc4c,
+ 0x0cafcc00, 0x03afcc4c, 0x0cafcc00, 0x03afcc4c,
+ 0x0cafcc00, 0x33bfcc4f, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xe0ffcc84, 0x00ffcc04, 0x00ffcc04, 0x0fffcc04,
+ 0x7fffcc06, 0xffffcc85, 0xffffcc05, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff };
+
+const uint edo_60ns[] =
+{ 0x8ffbec24, 0x0ff3ec04, 0x0cf3ec04, 0x00f3ec04,
+ 0x00f3ec00, 0x37f7ec47, 0xffffffff, 0xffffffff,
+ 0x8fffec24, 0x0ffbec04, 0x0cf3ec04, 0x00f3ec0c,
+ 0x0cf3ec00, 0x00f3ec4c, 0x0cf3ec00, 0x00f3ec4c,
+ 0x0cf3ec00, 0x00f3ec44, 0x03f3ec00, 0x3ff7ec47,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x8fffcc24, 0x0fefcc04, 0x0cafcc00, 0x11bfcc47,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x8fffcc24, 0x0fefcc04, 0x0cafcc00, 0x03afcc4c,
+ 0x0cafcc00, 0x03afcc4c, 0x0cafcc00, 0x03afcc4c,
+ 0x0cafcc00, 0x33bfcc4f, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xc0ffcc84, 0x00ffcc04, 0x07ffcc04, 0x3fffcc06,
+ 0xffffcc85, 0xffffcc05, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff };
+
+const uint edo_70ns[] =
+{ 0x8ffbcc24, 0x0ff3cc04, 0x0cf3cc04, 0x00f3cc04,
+ 0x00f3cc00, 0x37f7cc47, 0xffffffff, 0xffffffff,
+ 0x8fffcc24, 0x0ffbcc04, 0x0cf3cc04, 0x00f3cc0c,
+ 0x03f3cc00, 0x00f3cc44, 0x00f3ec0c, 0x0cf3ec00,
+ 0x00f3ec4c, 0x03f3ec00, 0x00f3ec44, 0x00f3cc00,
+ 0x33f7cc47, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x8fffcc24, 0x0fefcc04, 0x0cafcc00, 0x11bfcc47,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x8fffcc24, 0x0fefcc04, 0x0cafcc00, 0x03afcc4c,
+ 0x0cafcc00, 0x03afcc4c, 0x0cafcc00, 0x03afcc4c,
+ 0x0cafcc00, 0x33bfcc47, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xe0ffcc84, 0x00ffcc04, 0x00ffcc04, 0x0fffcc04,
+ 0x7fffcc04, 0xffffcc86, 0xffffcc05, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff };
+
+#elif defined(CONFIG_DRAM_25MHZ)
+
+/* 25MHz tables */
+
+const uint dram_60ns[] =
+{ 0x0fffcc04, 0x08ffcc00, 0x33ffcc47, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x0fffcc24, 0x0fffcc04, 0x08ffcc00, 0x03ffcc4c,
+ 0x08ffcc00, 0x03ffcc4c, 0x08ffcc00, 0x03ffcc4c,
+ 0x08ffcc00, 0x33ffcc47, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x0fafcc04, 0x08afcc00, 0x3fbfcc47, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x0fafcc04, 0x0cafcc00, 0x01afcc4c, 0x0cafcc00,
+ 0x01afcc4c, 0x0cafcc00, 0x01afcc4c, 0x0cafcc00,
+ 0x31bfcc43, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x80ffcc84, 0x13ffcc04, 0xffffcc87, 0xffffcc05,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff };
+
+const uint dram_70ns[] =
+{ 0x0fffec04, 0x08ffec04, 0x00ffec00, 0x3fffcc47,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x0fffcc24, 0x0fffcc04, 0x08ffcc00, 0x03ffcc4c,
+ 0x08ffcc00, 0x03ffcc4c, 0x08ffcc00, 0x03ffcc4c,
+ 0x08ffcc00, 0x33ffcc47, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x0fafcc04, 0x08afcc00, 0x3fbfcc47, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x0fafcc04, 0x0cafcc00, 0x01afcc4c, 0x0cafcc00,
+ 0x01afcc4c, 0x0cafcc00, 0x01afcc4c, 0x0cafcc00,
+ 0x31bfcc43, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xc0ffcc84, 0x01ffcc04, 0x7fffcc86, 0xffffcc05,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff };
+
+const uint edo_60ns[] =
+{ 0x0ffbcc04, 0x0cf3cc04, 0x00f3cc00, 0x33f7cc47,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x0ffbcc04, 0x09f3cc0c, 0x09f3cc0c, 0x09f3cc0c,
+ 0x08f3cc00, 0x3ff7cc47, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x0fefcc04, 0x08afcc04, 0x00afcc00, 0x3fbfcc47,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x0fefcc04, 0x08afcc00, 0x07afcc48, 0x08afcc48,
+ 0x08afcc48, 0x39bfcc47, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x80ffcc84, 0x13ffcc04, 0xffffcc87, 0xffffcc05,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff };
+
+const uint edo_70ns[] =
+{ 0x0ffbcc04, 0x0cf3cc04, 0x00f3cc00, 0x33f7cc47,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x0ffbec04, 0x08f3ec04, 0x03f3ec48, 0x08f3cc00,
+ 0x0ff3cc4c, 0x08f3cc00, 0x0ff3cc4c, 0x08f3cc00,
+ 0x3ff7cc47, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x0fefcc04, 0x08afcc04, 0x00afcc00, 0x3fbfcc47,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x0fefcc04, 0x08afcc00, 0x07afcc4c, 0x08afcc00,
+ 0x07afcc4c, 0x08afcc00, 0x07afcc4c, 0x08afcc00,
+ 0x37bfcc47, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xc0ffcc84, 0x01ffcc04, 0x7fffcc86, 0xffffcc05,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff };
+
+
+#else
+#error dram not correct defined - use CONFIG_DRAM_25MHZ or CONFIG_DRAM_50MHZ
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+ uint k;
+
+ puts ("Board: ");
+
+#ifdef CONFIG_FADS
+ k = (*((uint *)BCSR3) >> 24) & 0x3f;
+
+ switch(k) {
+ case 0x03 :
+ case 0x20 :
+ case 0x21 :
+ case 0x22 :
+ case 0x23 :
+ case 0x24 :
+ case 0x3f :
+ puts ("FADS");
+ break;
+
+ default :
+ printf("unknown board (0x%02x)\n", k);
+ return -1;
+ }
+
+ printf(" with db ");
+
+ switch(k) {
+ case 0x03 :
+ puts ("MPC823");
+ break;
+ case 0x20 :
+ puts ("MPC801");
+ break;
+ case 0x21 :
+ puts ("MPC850");
+ break;
+ case 0x22 :
+ puts ("MPC821, MPC860 / MPC860SAR / MPC860T");
+ break;
+ case 0x23 :
+ puts ("MPC860SAR");
+ break;
+ case 0x24 :
+ puts ("MPC860T");
+ break;
+ case 0x3f :
+ puts ("MPC850SAR");
+ break;
+ }
+
+ printf(" rev ");
+
+ k = (((*((uint *)BCSR3) >> 23) & 1) << 3)
+ | (((*((uint *)BCSR3) >> 19) & 1) << 2)
+ | (((*((uint *)BCSR3) >> 16) & 3));
+
+ switch(k) {
+ case 0x01 :
+ puts ("ENG or PILOT\n");
+ break;
+
+ default:
+ printf("unknown (0x%x)\n", k);
+ return -1;
+ }
+
+ return 0;
+#endif /* CONFIG_FADS */
+
+#ifdef CONFIG_ADS
+ printf("ADS rev ");
+
+ k = (((*((uint *)BCSR3) >> 23) & 1) << 3)
+ | (((*((uint *)BCSR3) >> 19) & 1) << 2)
+ | (((*((uint *)BCSR3) >> 16) & 3));
+
+ switch(k) {
+ case 0x00 : puts ("ENG - this board sucks, check the errata, not supported\n");
+ return -1;
+ case 0x01 : puts ("PILOT - warning, read errata \n"); break;
+ case 0x02 : puts ("A - warning, read errata \n"); break;
+ case 0x03 : puts ("B \n"); break;
+ default : printf ("unknown revision (0x%x)\n", k); return -1;
+ }
+
+ return 0;
+#endif /* CONFIG_ADS */
+
+}
+
+/* ------------------------------------------------------------------------- */
+int _draminit(uint base, uint noMbytes, uint edo, uint delay)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+
+ /* init upm */
+
+ switch(delay)
+ {
+ case 70:
+ {
+ if(edo)
+ {
+ upmconfig(UPMA, (uint *) edo_70ns, sizeof(edo_70ns)/sizeof(uint));
+ }
+ else
+ {
+ upmconfig(UPMA, (uint *) dram_70ns, sizeof(dram_70ns)/sizeof(uint));
+ }
+
+ break;
+ }
+
+ case 60:
+ {
+ if(edo)
+ {
+ upmconfig(UPMA, (uint *) edo_60ns, sizeof(edo_60ns)/sizeof(uint));
+ }
+ else
+ {
+ upmconfig(UPMA, (uint *) dram_60ns, sizeof(dram_60ns)/sizeof(uint));
+ }
+
+ break;
+ }
+
+ default :
+ return -1;
+ }
+
+ memctl->memc_mptpr = 0x0400; /* divide by 16 */
+
+ switch(noMbytes)
+ {
+
+ case 8: /* 8 Mbyte uses both CS3 and CS2 */
+ {
+ memctl->memc_mamr = 0x13a01114;
+ memctl->memc_or3 = 0xffc00800;
+ memctl->memc_br3 = 0x00400081 + base;
+ memctl->memc_or2 = 0xffc00800;
+ break;
+ }
+
+ case 4: /* 4 Mbyte uses only CS2 */
+ {
+ memctl->memc_mamr = 0x13a01114;
+ memctl->memc_or2 = 0xffc00800;
+ break;
+ }
+
+ case 32: /* 32 Mbyte uses both CS3 and CS2 */
+ {
+ memctl->memc_mamr = 0x13b01114;
+ memctl->memc_or3 = 0xff000800;
+ memctl->memc_br3 = 0x01000081 + base;
+ memctl->memc_or2 = 0xff000800;
+ break;
+ }
+
+ case 16: /* 16 Mbyte uses only CS2 */
+ {
+#ifdef CONFIG_ADS
+ memctl->memc_mamr = 0x60b21114;
+#else
+ memctl->memc_mamr = 0x13b01114;
+#endif
+ memctl->memc_or2 = 0xff000800;
+ break;
+ }
+
+ default:
+ return -1;
+ }
+
+ memctl->memc_br2 = 0x81 + base; /* use upma */
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+void _dramdisable(void)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+
+ memctl->memc_br2 = 0x00000000;
+ memctl->memc_br3 = 0x00000000;
+
+ /* maybe we should turn off upma here or something */
+}
+
+#if defined(CONFIG_SDRAM_100MHZ)
+
+/* ------------------------------------------------------------------------- */
+/* sdram table by Dan Malek */
+
+/* This has the stretched early timing so the 50 MHz
+ * processor can make the 100 MHz timing. This will
+ * work at all processor speeds.
+ */
+
+#define SDRAM_MPTPRVALUE 0x0400
+
+#define SDRAM_MBMRVALUE0 0xc3802114 /* (16-14) 50 MHz */
+#define SDRAM_MBMRVALUE1 SDRAM_MBMRVALUE0
+
+#define SDRAM_OR4VALUE 0xffc00a00
+#define SDRAM_BR4VALUE 0x000000c1 /* base address will be or:ed on */
+
+#define SDRAM_MARVALUE 0x88
+
+#define SDRAM_MCRVALUE0 0x80808111 /* run pattern 0x11 */
+#define SDRAM_MCRVALUE1 SDRAM_MCRVALUE0
+
+
+const uint sdram_table[] =
+{
+ /* single read. (offset 0 in upm RAM) */
+ 0xefebfc24, 0x1f07fc24, 0xeeaefc04, 0x11adfc04,
+ 0xefbbbc00, 0x1ff77c45, 0xffffffff, 0xffffffff,
+
+ /* burst read. (offset 8 in upm RAM) */
+ 0xefebfc24, 0x1f07fc24, 0xeeaefc04, 0x10adfc04,
+ 0xf0affc00, 0xf0affc00, 0xf1affc00, 0xefbbbc00,
+ 0x1ff77c45, 0xeffbbc04, 0x1ff77c34, 0xefeabc34,
+ 0x1fb57c35, 0xffffffff, 0xffffffff, 0xffffffff,
+
+ /* single write. (offset 18 in upm RAM) */
+ 0xefebfc24, 0x1f07fc24, 0xeeaebc00, 0x01b93c04,
+ 0x1ff77c45, 0xffffffff, 0xffffffff, 0xffffffff,
+
+ /* burst write. (offset 20 in upm RAM) */
+ 0xefebfc24, 0x1f07fc24, 0xeeaebc00, 0x10ad7c00,
+ 0xf0affc00, 0xf0affc00, 0xe1bbbc04, 0x1ff77c45,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+
+ /* refresh. (offset 30 in upm RAM) */
+ 0xeffafc84, 0x1ff5fc04, 0xfffffc04, 0xfffffc04,
+ 0xfffffc84, 0xfffffc07, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+
+ /* exception. (offset 3c in upm RAM) */
+ 0xeffffc06, 0x1ffffc07, 0xffffffff, 0xffffffff };
+
+#elif defined(CONFIG_SDRAM_50MHZ)
+
+/* ------------------------------------------------------------------------- */
+/* sdram table stolen from the fads manual */
+/* for chip MB811171622A-100 */
+
+/* this table is for 32-50MHz operation */
+
+#define _not_used_ 0xffffffff
+
+#define SDRAM_MPTPRVALUE 0x0400
+
+#define SDRAM_MBMRVALUE0 0x80802114 /* refresh at 32MHz */
+#define SDRAM_MBMRVALUE1 0x80802118
+
+#define SDRAM_OR4VALUE 0xffc00a00
+#define SDRAM_BR4VALUE 0x000000c1 /* base address will be or:ed on */
+
+#define SDRAM_MARVALUE 0x88
+
+#define SDRAM_MCRVALUE0 0x80808105
+#define SDRAM_MCRVALUE1 0x80808130
+
+const uint sdram_table[] =
+{
+ /* single read. (offset 0 in upm RAM) */
+ 0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
+ 0x1ff77c47,
+
+ /* MRS initialization (offset 5) */
+
+ 0x1ff77c34, 0xefeabc34, 0x1fb57c35,
+
+ /* burst read. (offset 8 in upm RAM) */
+ 0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
+ 0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47,
+ _not_used_, _not_used_, _not_used_, _not_used_,
+ _not_used_, _not_used_, _not_used_, _not_used_,
+
+ /* single write. (offset 18 in upm RAM) */
+ 0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47,
+ _not_used_, _not_used_, _not_used_, _not_used_,
+
+ /* burst write. (offset 20 in upm RAM) */
+ 0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
+ 0xf0affc00, 0xe1bbbc04, 0x1ff77c47, _not_used_,
+ _not_used_, _not_used_, _not_used_, _not_used_,
+ _not_used_, _not_used_, _not_used_, _not_used_,
+
+ /* refresh. (offset 30 in upm RAM) */
+ 0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
+ 0xfffffc84, 0xfffffc07, _not_used_, _not_used_,
+ _not_used_, _not_used_, _not_used_, _not_used_,
+
+ /* exception. (offset 3c in upm RAM) */
+ 0x7ffffc07, _not_used_, _not_used_, _not_used_ };
+
+/* ------------------------------------------------------------------------- */
+#else
+#error SDRAM not correctly configured
+#endif
+
+int _initsdram(uint base, uint noMbytes)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+
+ if(noMbytes != 4)
+ {
+ return -1;
+ }
+
+ upmconfig(UPMB, (uint *)sdram_table,sizeof(sdram_table)/sizeof(uint));
+
+ memctl->memc_mptpr = SDRAM_MPTPRVALUE;
+
+ /* Configure the refresh (mostly). This needs to be
+ * based upon processor clock speed and optimized to provide
+ * the highest level of performance. For multiple banks,
+ * this time has to be divided by the number of banks.
+ * Although it is not clear anywhere, it appears the
+ * refresh steps through the chip selects for this UPM
+ * on each refresh cycle.
+ * We have to be careful changing
+ * UPM registers after we ask it to run these commands.
+ */
+
+ memctl->memc_mbmr = SDRAM_MBMRVALUE0;
+ memctl->memc_mar = SDRAM_MARVALUE; /* MRS code */
+
+ udelay(200);
+
+ /* Now run the precharge/nop/mrs commands.
+ */
+
+ memctl->memc_mcr = 0x80808111; /* run pattern 0x11 */
+
+ udelay(200);
+
+ /* Run 8 refresh cycles */
+
+ memctl->memc_mcr = SDRAM_MCRVALUE0;
+
+ udelay(200);
+
+ memctl->memc_mbmr = SDRAM_MBMRVALUE1;
+ memctl->memc_mcr = SDRAM_MCRVALUE1;
+
+ udelay(200);
+
+ memctl->memc_mbmr = SDRAM_MBMRVALUE0;
+
+ memctl->memc_or4 = SDRAM_OR4VALUE;
+ memctl->memc_br4 = SDRAM_BR4VALUE | base;
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+void _sdramdisable(void)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+
+ memctl->memc_br4 = 0x00000000;
+
+ /* maybe we should turn off upmb here or something */
+}
+
+/* ------------------------------------------------------------------------- */
+
+int initsdram(uint base, uint *noMbytes)
+{
+ uint m = 4;
+
+ *((uint *)BCSR1) |= BCSR1_SDRAM_EN; /* enable sdram */
+ /* _fads_sdraminit needs access to sdram */
+ *noMbytes = m;
+
+ if(!_initsdram(base, m))
+ {
+
+ return 0;
+ }
+ else
+ {
+ *((uint *)BCSR1) &= ~BCSR1_SDRAM_EN; /* disable sdram */
+
+ _sdramdisable();
+
+ return -1;
+ }
+}
+
+long int initdram (int board_type)
+{
+#ifdef CONFIG_ADS
+ /* ADS: has no SDRAM, so start DRAM at 0 */
+ uint base = (unsigned long)0x0;
+#else
+ /* FADS: has 4MB SDRAM, put DRAM above it */
+ uint base = (unsigned long)0x00400000;
+#endif
+ uint k, m, s;
+
+ k = (*((uint *)BCSR2) >> 23) & 0x0f;
+
+ m = 0;
+
+ switch(k & 0x3)
+ {
+ /* "MCM36100 / MT8D132X" */
+ case 0x00 :
+ m = 4;
+ break;
+
+ /* "MCM36800 / MT16D832X" */
+ case 0x01 :
+ m = 32;
+ break;
+ /* "MCM36400 / MT8D432X" */
+ case 0x02 :
+ m = 16;
+ break;
+ /* "MCM36200 / MT16D832X ?" */
+ case 0x03 :
+ m = 8;
+ break;
+
+ }
+
+ switch(k >> 2)
+ {
+ case 0x02 :
+ k = 70;
+ break;
+
+ case 0x03 :
+ k = 60;
+ break;
+
+ default :
+ printf("unknown dramdelay (0x%x) - defaulting to 70 ns", k);
+ k = 70;
+ }
+
+#ifdef CONFIG_FADS
+ /* the FADS is missing this bit, all rams treated as non-edo */
+ s = 0;
+#else
+ s = (*((uint *)BCSR2) >> 27) & 0x01;
+#endif
+
+ if(!_draminit(base, m, s, k))
+ {
+#ifdef CONFIG_FADS
+ uint sdramsz;
+#endif
+ *((uint *)BCSR1) &= ~BCSR1_DRAM_EN; /* enable dram */
+
+#ifdef CONFIG_FADS
+ if (!initsdram(0x00000000, &sdramsz)) {
+ m += sdramsz;
+ printf("(%u MB SDRAM) ", sdramsz);
+ } else {
+ _dramdisable();
+
+ /********************************
+ *DRAM ERROR, HALT PROCESSOR
+ *********************************/
+ while(1);
+
+ return -1;
+ }
+#endif
+
+ return (m << 20);
+ }
+ else
+ {
+ _dramdisable();
+
+ /********************************
+ *DRAM ERROR, HALT PROCESSOR
+ *********************************/
+ while(1);
+
+ return -1;
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+int testdram (void)
+{
+ /* TODO: XXX XXX XXX */
+ printf ("test: 16 MB - ok\n");
+
+ return (0);
+}
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+
+#ifdef CFG_PCMCIA_MEM_ADDR
+volatile unsigned char *pcmcia_mem = (unsigned char*)CFG_PCMCIA_MEM_ADDR;
+#endif
+
+int pcmcia_init(void)
+{
+ volatile pcmconf8xx_t *pcmp;
+ uint v, slota, slotb;
+
+ /*
+ ** Enable the PCMCIA for a Flash card.
+ */
+ pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+
+#if 0
+ pcmp->pcmc_pbr0 = CFG_PCMCIA_MEM_ADDR;
+ pcmp->pcmc_por0 = 0xc00ff05d;
+#endif
+
+ /* Set all slots to zero by default. */
+ pcmp->pcmc_pgcra = 0;
+ pcmp->pcmc_pgcrb = 0;
+#ifdef PCMCIA_SLOT_A
+ pcmp->pcmc_pgcra = 0x40;
+#endif
+#ifdef PCMCIA_SLOT_B
+ pcmp->pcmc_pgcrb = 0x40;
+#endif
+
+ /* enable PCMCIA buffers */
+ *((uint *)BCSR1) &= ~BCSR1_PCCEN;
+
+ /* Check if any PCMCIA card is plugged in. */
+
+ slota = (pcmp->pcmc_pipr & 0x18000000) == 0 ;
+ slotb = (pcmp->pcmc_pipr & 0x00001800) == 0 ;
+
+ if (!(slota || slotb))
+ {
+ printf("No card present\n");
+#ifdef PCMCIA_SLOT_A
+ pcmp->pcmc_pgcra = 0;
+#endif
+#ifdef PCMCIA_SLOT_B
+ pcmp->pcmc_pgcrb = 0;
+#endif
+ return -1;
+ }
+ else
+ printf("Card present (");
+
+ v = 0;
+
+ /* both the ADS and the FADS have a 5V keyed pcmcia connector (?)
+ **
+ ** Paolo - Yes, but i have to insert some 3.3V card in that slot on
+ ** my FADS... :-)
+ */
+
+#if defined(CONFIG_MPC860)
+ switch( (pcmp->pcmc_pipr >> 30) & 3 )
+#elif defined(CONFIG_MPC823) || defined(CONFIG_MPC850)
+ switch( (pcmp->pcmc_pipr >> 14) & 3 )
+#endif
+ {
+ case 0x00 :
+ printf("5V");
+ v = 5;
+ break;
+ case 0x01 :
+ printf("5V and 3V");
+#ifdef CONFIG_FADS
+ v = 3; /* User lower voltage if supported! */
+#else
+ v = 5;
+#endif
+ break;
+ case 0x03 :
+ printf("5V, 3V and x.xV");
+#ifdef CONFIG_FADS
+ v = 3; /* User lower voltage if supported! */
+#else
+ v = 5;
+#endif
+ break;
+ }
+
+ switch(v){
+#ifdef CONFIG_FADS
+ case 3:
+ printf("; using 3V");
+ /*
+ ** Enable 3 volt Vcc.
+ */
+ *((uint *)BCSR1) &= ~BCSR1_PCCVCC1;
+ *((uint *)BCSR1) |= BCSR1_PCCVCC0;
+ break;
+#endif
+ case 5:
+ printf("; using 5V");
+#ifdef CONFIG_ADS
+ /*
+ ** Enable 5 volt Vcc.
+ */
+ *((uint *)BCSR1) &= ~BCSR1_PCCVCCON;
+#endif
+#ifdef CONFIG_FADS
+ /*
+ ** Enable 5 volt Vcc.
+ */
+ *((uint *)BCSR1) &= ~BCSR1_PCCVCC0;
+ *((uint *)BCSR1) |= BCSR1_PCCVCC1;
+#endif
+ break;
+
+ default:
+ *((uint *)BCSR1) |= BCSR1_PCCEN; /* disable pcmcia */
+
+ printf("; unknown voltage");
+ return -1;
+ }
+ printf(")\n");
+ /* disable pcmcia reset after a while */
+
+ udelay(20);
+
+#ifdef MPC860
+ pcmp->pcmc_pgcra = 0;
+#elif MPC823
+ pcmp->pcmc_pgcrb = 0;
+#endif
+
+ /* If you using a real hd you should give a short
+ * spin-up time. */
+#ifdef CONFIG_DISK_SPINUP_TIME
+ udelay(CONFIG_DISK_SPINUP_TIME);
+#endif
+
+ return 0;
+}
+
+#endif /* CFG_CMD_PCMCIA */
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CFG_PC_IDE_RESET
+
+void ide_set_reset(int on)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+
+ /*
+ * Configure PC for IDE Reset Pin
+ */
+ if (on) { /* assert RESET */
+ immr->im_ioport.iop_pcdat &= ~(CFG_PC_IDE_RESET);
+ } else { /* release RESET */
+ immr->im_ioport.iop_pcdat |= CFG_PC_IDE_RESET;
+ }
+
+ /* program port pin as GPIO output */
+ immr->im_ioport.iop_pcpar &= ~(CFG_PC_IDE_RESET);
+ immr->im_ioport.iop_pcso &= ~(CFG_PC_IDE_RESET);
+ immr->im_ioport.iop_pcdir |= CFG_PC_IDE_RESET;
+}
+
+#endif /* CFG_PC_IDE_RESET */
+/* ------------------------------------------------------------------------- */
--- /dev/null
+/*
+ * genietv/genietv.c
+ *
+ * The GENIETV is using the following physical memorymap (copied from
+ * the FADS configuration):
+ *
+ * ff020000 -> ff02ffff : pcmcia
+ * ff010000 -> ff01ffff : BCSR connected to CS1, setup by 8xxROM
+ * ff000000 -> ff00ffff : IMAP internal in the cpu
+ * 02800000 -> 0287ffff : flash connected to CS0
+ * 00000000 -> nnnnnnnn : sdram setup by U-Boot
+ *
+ * CS pins are connected as follows:
+ *
+ * CS0 -512Kb boot flash
+ * CS1 - SDRAM #1
+ * CS2 - SDRAM #2
+ * CS3 - Flash #1
+ * CS4 - Flash #2
+ * CS5 - LON (if present)
+ * CS6 - PCMCIA #1
+ * CS7 - PCMCIA #2
+ *
+ * Ports are configured as follows:
+ *
+ * PA7 - SDRAM banks enable
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+
+#define CFG_PA7 0x0100
+
+/* ------------------------------------------------------------------------- */
+
+static long int dram_size (long int, long int *, long int);
+
+/* ------------------------------------------------------------------------- */
+
+#define _NOT_USED_ 0xFFFFFFFF
+
+const uint sdram_table[] =
+{
+ /*
+ * Single Read. (Offset 0 in UPMB RAM)
+ */
+ 0x1F0DFC04, 0xEEAFBC04, 0x11AF7C04, 0xEFBEEC00,
+ 0x1FFDDC47, /* last */
+ /*
+ * SDRAM Initialization (offset 5 in UPMB RAM)
+ *
+ * This is no UPM entry point. The following definition uses
+ * the remaining space to establish an initialization
+ * sequence, which is executed by a RUN command.
+ *
+ */
+ 0x1FFDDC34, 0xEFEEAC34, 0x1FBD5C35, /* last */
+ /*
+ * Burst Read. (Offset 8 in UPMB RAM)
+ */
+ 0x1F0DFC04, 0xEEAFBC04, 0x10AF7C04, 0xF0AFFC00,
+ 0xF0AFFC00, 0xF1AFFC00, 0xEFBEEC00, 0x1FFDDC47, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Single Write. (Offset 18 in UPMB RAM)
+ */
+ 0x1F2DFC04, 0xEEAFAC00, 0x01BE4C04, 0x1FFDDC47, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Burst Write. (Offset 20 in UPMB RAM)
+ */
+ 0x1F0DFC04, 0xEEAFAC00, 0x10AF5C00, 0xF0AFFC00,
+ 0xF0AFFC00, 0xE1BEEC04, 0x1FFDDC47, /* last */
+ _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Refresh (Offset 30 in UPMB RAM)
+ */
+ 0x1FFD7C84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
+ 0xFFFFFC84, 0xFFFFFC07, /* last */
+ _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Exception. (Offset 3c in UPMB RAM)
+ */
+ 0x7FFFFC07, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_,
+};
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Check Board Identity
+ */
+
+int checkboard (void)
+{
+ puts ("Board: GenieTV\n");
+ return 0;
+}
+
+#if 0
+static void PrintState(void)
+{
+ volatile immap_t *im = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &im->im_memctl;
+
+ printf("\n0 - FLASH: B=%08x O=%08x", memctl->memc_br0, memctl->memc_or0);
+ printf("\n1 - SDRAM: B=%08x O=%08x", memctl->memc_br1, memctl->memc_or1);
+ printf("\n2 - SDRAM: B=%08x O=%08x", memctl->memc_br2, memctl->memc_or2);
+}
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+ volatile immap_t *im = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &im->im_memctl;
+ long int size_b0, size_b1, size8;
+
+ /* Enable SDRAM */
+
+ /* Configuring PA7 for general purpouse output pin */
+ im->im_ioport.iop_papar &= ~CFG_PA7 ; /* 0 = general purpouse */
+ im->im_ioport.iop_padir |= CFG_PA7 ; /* 1 = output */
+
+ /* Enable SDRAM - PA7 = 1 */
+ im->im_ioport.iop_padat |= CFG_PA7 ; /* value of PA7 */
+
+ /*
+ * Preliminary prescaler for refresh (depends on number of
+ * banks): This value is selected for four cycles every 62.4 us
+ * with two SDRAM banks or four cycles every 31.2 us with one
+ * bank. It will be adjusted after memory sizing.
+ */
+ memctl->memc_mptpr = CFG_MPTPR_2BK_4K ;
+
+ memctl->memc_mbmr = CFG_MBMR_8COL;
+
+ upmconfig(UPMB, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
+
+ /*
+ * Map controller banks 1 and 2 to the SDRAM banks 1 and 2 at
+ * preliminary addresses - these have to be modified after the
+ * SDRAM size has been determined.
+ */
+
+ memctl->memc_or1 = 0xF0000000 | CFG_OR_TIMING_SDRAM;
+ memctl->memc_br1 = ((SDRAM_BASE1_PRELIM & BR_BA_MSK) | BR_MS_UPMB | BR_V);
+
+ memctl->memc_or2 = 0xF0000000 | CFG_OR_TIMING_SDRAM;
+ memctl->memc_br2 = ((SDRAM_BASE2_PRELIM & BR_BA_MSK) | BR_MS_UPMB | BR_V);
+
+ /* perform SDRAM initialization sequence */
+ memctl->memc_mar = 0x00000088;
+
+ memctl->memc_mcr = 0x80802105; /* SDRAM bank 0 */
+
+ memctl->memc_mcr = 0x80804105; /* SDRAM bank 1 */
+
+ /* Execute refresh 8 times */
+ memctl->memc_mbmr = (CFG_MBMR_8COL & ~MAMR_TLFB_MSK) | MAMR_TLFB_8X ;
+
+ memctl->memc_mcr = 0x80802130; /* SDRAM bank 0 - execute twice */
+
+ memctl->memc_mcr = 0x80804130; /* SDRAM bank 1 - execute twice */
+
+ /* Execute refresh 4 times */
+ memctl->memc_mbmr = CFG_MBMR_8COL;
+
+ /*
+ * Check Bank 0 Memory Size for re-configuration
+ *
+ * try 8 column mode
+ */
+
+#if 0
+ PrintState();
+#endif
+/* printf ("\nChecking bank1..."); */
+ size8 = dram_size (CFG_MBMR_8COL, (ulong *)SDRAM_BASE1_PRELIM, SDRAM_MAX_SIZE);
+
+ size_b0 = size8 ;
+
+/* printf ("\nChecking bank2..."); */
+ size_b1 = dram_size (memctl->memc_mbmr, (ulong *)SDRAM_BASE2_PRELIM,SDRAM_MAX_SIZE);
+
+ /*
+ * Final mapping: map bigger bank first
+ */
+
+ memctl->memc_or1 = ((-size_b0) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
+ memctl->memc_br1 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMB | BR_V;
+
+ if (size_b1 > 0)
+ {
+ /*
+ * Position Bank 1 immediately above Bank 0
+ */
+ memctl->memc_or2 = ((-size_b1) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
+ memctl->memc_br2 = ((CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMB | BR_V) +
+ (size_b0 & BR_BA_MSK);
+ }
+ else
+ {
+ /*
+ * No bank 1
+ *
+ * invalidate bank
+ */
+ memctl->memc_br2 = 0;
+ /* adjust refresh rate depending on SDRAM type, one bank */
+ memctl->memc_mptpr = CFG_MPTPR_1BK_4K;
+ }
+
+ /* If no memory detected, disable SDRAM */
+ if ((size_b0 + size_b1) == 0)
+ {
+ printf("disabling SDRAM!\n");
+ /* Disable SDRAM - PA7 = 1 */
+ im->im_ioport.iop_padat &= ~CFG_PA7 ; /* value of PA7 */
+ }
+/* else */
+/* printf("done! (%08lx)\n", size_b0 + size_b1); */
+
+#if 0
+ PrintState();
+#endif
+ return (size_b0 + size_b1);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+
+static long int dram_size (long int mbmr_value, long int *base, long int maxsize)
+{
+ volatile long int *addr;
+ long int cnt, val;
+
+ /*memctl->memc_mbmr = mbmr_value; */
+
+ for (cnt = maxsize/sizeof(long); cnt > 0; cnt >>= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ *addr = ~cnt;
+ }
+
+ /* write 0 to base address */
+ addr = base;
+ *addr = 0;
+
+ /* check at base address */
+ if ((val = *addr) != 0) {
+ printf("(0)");
+ return (0);
+ }
+
+ for (cnt = 1; ; cnt <<= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ val = *addr;
+ if (val != (~cnt)) {
+/* printf("(%08lx)", cnt*sizeof(long)); */
+ return (cnt * sizeof(long));
+ }
+ }
+ /* NOTREACHED */
+ return (0);
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+
+#ifdef CFG_PCMCIA_MEM_ADDR
+volatile unsigned char *pcmcia_mem = (unsigned char*)CFG_PCMCIA_MEM_ADDR;
+#endif
+
+int pcmcia_init(void)
+{
+ volatile pcmconf8xx_t *pcmp;
+ uint v, slota, slotb;
+
+ /*
+ ** Enable the PCMCIA for a Flash card.
+ */
+ pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+
+#if 0
+ pcmp->pcmc_pbr0 = CFG_PCMCIA_MEM_ADDR;
+ pcmp->pcmc_por0 = 0xc00ff05d;
+#endif
+
+ /* Set all slots to zero by default. */
+ pcmp->pcmc_pgcra = 0;
+ pcmp->pcmc_pgcrb = 0;
+#ifdef PCMCIA_SLOT_A
+ pcmp->pcmc_pgcra = 0x40;
+#endif
+#ifdef PCMCIA_SLOT_B
+ pcmp->pcmc_pgcrb = 0x40;
+#endif
+
+ /* Check if any PCMCIA card is luged in. */
+ slota = (pcmp->pcmc_pipr & 0x18000000) == 0 ;
+ slotb = (pcmp->pcmc_pipr & 0x00001800) == 0 ;
+
+ if (!(slota || slotb))
+ {
+ printf("No card present\n");
+#ifdef PCMCIA_SLOT_A
+ pcmp->pcmc_pgcra = 0;
+#endif
+#ifdef PCMCIA_SLOT_B
+ pcmp->pcmc_pgcrb = 0;
+#endif
+ return -1;
+ }
+ else
+ printf("Unknown card (");
+
+ v = 0;
+
+ switch( (pcmp->pcmc_pipr >> 14) & 3 )
+ {
+ case 0x00 :
+ printf("5V");
+ v = 5;
+ break;
+ case 0x01 :
+ printf("5V and 3V");
+ v = 3;
+ break;
+ case 0x03 :
+ printf("5V, 3V and x.xV");
+ v = 3;
+ break;
+ }
+
+ switch(v){
+ case 3:
+ printf("; using 3V");
+ /* Enable 3 volt Vcc. */
+
+ break;
+
+ default:
+ printf("; unknown voltage");
+ return -1;
+ }
+ printf(")\n");
+ /* disable pcmcia reset after a while */
+
+ udelay(20);
+
+ pcmp->pcmc_pgcrb = 0;
+
+ /* If you using a real hd you should give a short
+ * spin-up time. */
+#ifdef CONFIG_DISK_SPINUP_TIME
+ udelay(CONFIG_DISK_SPINUP_TIME);
+#endif
+
+ return 0;
+}
+#endif /* CFG_CMD_PCMCIA */
--- /dev/null
+#
+# LART board with SA1100 cpu
+#
+# see http://www.lart.tudelft.nl/ for more information on LART
+#
+
+#
+# LART has 4 banks of 8 MB DRAM
+#
+# c000'0000
+# c100'0000
+# c800'0000
+# c900'0000
+#
+# Linux-Kernel is expected to be at c000'8000, entry c000'8000
+#
+# we load ourself to c170'0000, the upper 1 MB of second bank
+#
+# download areas is c800'0000
+#
+
+
+TEXT_BASE = 0xc1700000
--- /dev/null
+/*
+ * Memory Setup stuff - taken from blob memsetup.S
+ *
+ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
+ * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
+ *
+ * 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>
+
+
+/* some parameters for the board */
+
+MEM_BASE: .long 0xa0000000
+MEM_START: .long 0xc0000000
+
+#define MDCNFG 0x00
+#define MDCAS0 0x04
+#define MDCAS1 0x08
+#define MDCAS2 0x0c
+#define MSC0 0x10
+#define MSC1 0x14
+#define MECR 0x18
+
+mdcas0: .long 0xc71c703f
+mdcas1: .long 0xffc71c71
+mdcas2: .long 0xffffffff
+/* mdcnfg: .long 0x0bb2bcbf */
+mdcnfg: .long 0x0334b22f @ alt
+/* mcs0: .long 0xfff8fff8 */
+msc0: .long 0xad8c4888 @ alt
+mecr: .long 0x00060006
+/* mecr: .long 0x994a994a @ alt */
+
+/* setting up the memory */
+
+.globl memsetup
+memsetup:
+ ldr r0, MEM_BASE
+
+ /* Setup the flash memory */
+ ldr r1, msc0
+ str r1, [r0, #MSC0]
+
+ /* Set up the DRAM */
+
+ /* MDCAS0 */
+ ldr r1, mdcas0
+ str r1, [r0, #MDCAS0]
+
+ /* MDCAS1 */
+ ldr r1, mdcas1
+ str r1, [r0, #MDCAS1]
+
+ /* MDCAS2 */
+ ldr r1, mdcas2
+ str r1, [r0, #MDCAS2]
+
+ /* MDCNFG */
+ ldr r1, mdcnfg
+ str r1, [r0, #MDCNFG]
+
+ /* Set up PCMCIA space */
+ ldr r1, mecr
+ str r1, [r0, #MECR]
+
+ /* Load something to activate bank */
+ ldr r1, MEM_START
+
+.rept 8
+ ldr r0, [r1]
+.endr
+
+ /* everything is fine now */
+ mov pc, lr
+
--- /dev/null
+/*
+ * 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/memsetup.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>
+
+DRAM_SIZE: .long CFG_DRAM_SIZE
+
+/* wait for coprocessor write complete */
+ .macro CPWAIT reg
+ mrc p15,0,\reg,c2,c0,0
+ mov \reg,\reg
+ sub pc,pc,#4
+ .endm
+
+
+.globl memsetup
+memsetup:
+
+ mov r10, lr
+
+ /* 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, =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, =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, =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]
+
+ /* enable GPIO pins */
+ ldr r0, =PSSR
+ ldr r1, =CFG_PSSR_VAL
+ str r1, [r0]
+
+ ldr r3, =MSC1 /* low - bank 2 Lubbock Registers / SRAM */
+ ldr r2, =CFG_MSC1_VAL /* high - bank 3 Ethernet Controller */
+ str r2, [r3] /* need to set MSC1 before trying to write to the HEX LEDs */
+ ldr r2, [r3] /* need to read it back to make sure the value latches (see MSC section of manual) */
+
+ ldr r1, =LED_BLANK
+ mov r0, #0xFF
+ str r0, [r1] /* turn on hex leds */
+
+loop:
+ ldr r0, =0xB0070001
+ ldr r1, =_LED
+ str r0, [r1] /* hex display */
+
+/*********************************************************************
+ Initlialize Memory Controller
+ The sequence below is based on the recommended init steps detailed
+ in the EAS, chapter 5 (Chapter 10, Operating Systems Developers Guide)
+
+
+ pause for 200 uSecs- allow internal clocks to settle
+ *Note: only need this if hard reset... doing it anyway for now
+*/
+
+ @ ---- Wait 200 usec
+ 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:
+ @ get memory controller base address
+ ldr r1, =MEMC_BASE
+
+@****************************************************************************
+@ Step 1
+@
+
+ @ write msc0, read back to ensure data latches
+ @
+ ldr r2, =CFG_MSC0_VAL
+ str r2, [r1, #MSC0_OFFSET]
+ ldr r2, [r1, #MSC0_OFFSET]
+
+ @ write msc1
+ ldr r2, =CFG_MSC1_VAL
+ str r2, [r1, #MSC1_OFFSET]
+ ldr r2, [r1, #MSC1_OFFSET]
+
+ @ write msc2
+ ldr r2, =CFG_MSC2_VAL
+ str r2, [r1, #MSC2_OFFSET]
+ ldr r2, [r1, #MSC2_OFFSET]
+
+ @ write mecr
+ ldr r2, =CFG_MECR_VAL
+ str r2, [r1, #MECR_OFFSET]
+
+ @ write mcmem0
+ ldr r2, =CFG_MCMEM0_VAL
+ str r2, [r1, #MCMEM0_OFFSET]
+
+ @ write mcmem1
+ ldr r2, =CFG_MCMEM1_VAL
+ str r2, [r1, #MCMEM1_OFFSET]
+
+ @ write mcatt0
+ ldr r2, =CFG_MCATT0_VAL
+ str r2, [r1, #MCATT0_OFFSET]
+
+ @ write mcatt1
+ ldr r2, =CFG_MCATT1_VAL
+ str r2, [r1, #MCATT1_OFFSET]
+
+ @ write mcio0
+ ldr r2, =CFG_MCIO0_VAL
+ str r2, [r1, #MCIO0_OFFSET]
+
+ @ write mcio1
+ ldr r2, =CFG_MCIO1_VAL
+ str r2, [r1, #MCIO1_OFFSET]
+
+ @-------------------------------------------------------
+ @ 3rd bullet, Step 1
+ @
+
+ @ get the mdrefr settings
+ ldr r3, =CFG_MDREFR_VAL_100
+
+ @ extract DRI field (we need a valid DRI field)
+ @
+ ldr r2, =0xFFF
+
+ @ valid DRI field in r3
+ @
+ and r3, r3, r2
+
+ @ get the reset state of MDREFR
+ @
+ ldr r4, [r1, #MDREFR_OFFSET]
+
+ @ clear the DRI field
+ @
+ bic r4, r4, r2
+
+ @ insert the valid DRI field loaded above
+ @
+ orr r4, r4, r3
+
+ @ write back mdrefr
+ @
+ str r4, [r1, #MDREFR_OFFSET]
+
+ @ *Note: preserve the mdrefr value in r4 *
+
+@****************************************************************************
+@ Step 2
+@
+ /* This should be for SRAM, why is it commented out??? */
+
+ @ fetch sxcnfg value
+ @
+ @ldr r2, =0
+ @ write back sxcnfg
+ @str r2, [r1, #SXCNFG_OFFSET]
+
+/* @if sxcnfg=0, don't program for synch-static memory */
+ @cmp r2, #0
+ @beq 1f
+
+ @program sxmrs
+ @ldr r2, =SXMRS_SETTINGS
+ @str r2, [r1, #SXMRS_OFFSET]
+
+
+@****************************************************************************
+@ Step 3
+@
+
+ @ Assumes previous mdrefr value in r4, if not then read current mdrefr
+
+ @ clear the free-running clock bits
+ @ (clear K0Free, K1Free, K2Free
+ @
+ bic r4, r4, #(0x00800000 | 0x01000000 | 0x02000000)
+
+ @ set K1RUN if bank 0 installed
+ @
+ orr r4, r4, #0x00010000
+
+
+
+#ifdef THIS
+@<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<
+@<!<!<!<!<!<!<!<!<!<!<! Begin INSERT 1 <!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+ @ Lubbock: Allow the user to select the {T/R/M} with predetermined
+ @ SDCLK. Based on Table 3-1 in PXA250 and PXA210 Dev Man.
+ @
+ @ * = Must set MDREFR.K1DB2 to halve the MemClk for desired SDCLK[1]
+ @
+ @ S25, S26 used to provide all 400 MHz BIN values for Cotulla (0,0 - 1,3)
+ @ S25, S26 used to provide all 200 MHz BIN values for Sabinal
+ @
+ @ S23: Force the halving of MemClk when deriving SDCLK[1]
+ @ DOT: no override !DOT: halve (if not already forced half)
+/* @ *For certain MemClks, SDCLK's derivation is forced to be halved */
+ @
+ @ S24: Run/Turbo.
+ @ DOT: Run mode !DOT: Turbo mode
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+
+ @
+ @ Allow the user to control K1DB2 where applicable
+ @
+ @ Get the value of S23: @ 1 = DOT (unity), 0 = !DOT (halve it)
+ @
+ @ DOT: set K1DB2 (SDCLD = MemClk)
+ @ !DOT: clear K1DB2 (SDCLK = MemClk/2)
+ @
+ @ldr r2, =FPGA_REGS_BASE_PHYSICAL
+
+ bl GET_S23 @ r3, r2 @ get the value of S23 in R0, i put the base adx of fpga in r3
+
+ cmp r3, #0x0 @ is !DOT?
+ orreq r4, r4, #0x00020000 @ SDClk[1] = MemClk/2
+ bicne r4, r4, #0x00020000 @ SDClk[1] = MemClk
+
+ @
+ @ Next, we need to look for S25,S26 selections that necessitate the
+ @ halving of MemClk to derive SDCLK[1]: (S25,S26)={03-0C, 10-13}
+ @ Override above S23-based selection accordingly.
+ @
+ ldr r2, =FPGA_REGS_BASE_PHYSICAL
+ bl GET_S25 @ r0, r2
+ @ get the value of S25 in R0, i put the base adx of fpga in r2
+
+
+
+ ldr r2, =FPGA_REGS_BASE_PHYSICAL
+ BL GET_S26 @ r3, r2
+ @ get the value of S26 in R1, i put the base adx of fpga in r2
+
+ orr r0, r0, r3 @ concatenate S25 & S26 vals
+ and r0, r0, #0xFF
+
+ @ Set K1DB2 for the frequencies that require it
+ @
+ cmp r0, #0x03
+ cmpne r0, #0x04
+ cmpne r0, #0x05
+ cmpne r0, #0x06
+ cmpne r0, #0x07
+ cmpne r0, #0x08
+ cmpne r0, #0x09
+ cmpne r0, #0x0A
+ cmpne r0, #0x0B
+ cmpne r0, #0x0C
+ cmpne r0, #0x10
+ cmpne r0, #0x11
+ cmpne r0, #0x12
+ cmpne r0, #0x13
+ orreq r4, r4, #0x00020000 @ SDCLK[1] = (MemClk)/2 for 03 - 0C @ 10 - 13
+
+ @
+ @ *Must make MSC0&1 adjustments now for MEMClks > 100MHz.
+ @
+ @ Adjust MSC0 for MemClks > 100 MHz
+ @
+ ldreq r0, [r1, #MSC0_OFFSET]
+ ldreq r3, =0x7F007F00
+ biceq r0, r0, r3 @ clear MSC0[14:12, 11:8] (RRR, RDN)
+ ldreq r3, =0x46004600
+ orreq r0, r0, r3 @ set MSC0[14, 10:9] (doubling RRR, RDN)
+ streq r0, [r1, #MSC0_OFFSET]
+ ldreq r0, [r1, #MSC0_OFFSET] @ read it back to ensure that the data latches
+
+ @
+ @ Adjust MSC1.LH for MemClks > 100 MHz
+ @
+ ldreq r0, [r1, #MSC1_OFFSET]
+ ldreq r3, =0x7FF0
+ biceq r0, r0, r3 @ clear MSC1[14:12, 11:8, 7:4] (RRR, RDN, RDF)
+ ldreq r3, =0x4880
+ orreq r0, r0, r3 @ set MSC1[14, 11, 7] (doubling RRR, RDN, RDF)
+ streq r0, [r1, #MSC1_OFFSET]
+ ldreq r0, [r1, #MSC1_OFFSET] @ read it back to ensure that the data latches
+
+ @ @
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#endif
+
+@<!<!<!<!<!<!<!<!<!<!<! End INSERT 1 <!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<
+@<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<
+
+
+ @ write back mdrefr
+ @
+ str r4, [r1, #MDREFR_OFFSET]
+ ldr r4, [r1, #MDREFR_OFFSET]
+
+ @ deassert SLFRSH
+ @
+ bic r4, r4, #0x00400000
+
+ @ write back mdrefr
+ @
+ str r4, [r1, #MDREFR_OFFSET]
+
+ @ assert E1PIN
+ @
+ orr r4, r4, #0x00008000
+
+ @ write back mdrefr
+ @
+ str r4, [r1, #MDREFR_OFFSET]
+ ldr r4, [r1, #MDREFR_OFFSET]
+ nop
+ nop
+
+
+@****************************************************************************
+@ Step 4
+@
+
+ @ fetch platform value of mdcnfg
+ @
+ ldr r2, =CFG_MDCNFG_VAL
+
+ @ disable all sdram banks
+ @
+ bic r2, r2, #(MDCNFG_DE0 | MDCNFG_DE1)
+ bic r2, r2, #(MDCNFG_DE2 | MDCNFG_DE3)
+
+ @ program banks 0/1 for bus width
+ @
+ bic r2, r2, #MDCNFG_DWID0 @0=32-bit
+
+
+ @ write initial value of mdcnfg, w/o enabling sdram banks
+ @
+ str r2, [r1, #MDCNFG_OFFSET]
+
+@ ****************************************************************************
+@ Step 5
+@
+
+ @ pause for 200 uSecs
+ @
+ 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 6
+@
+
+ mov r0, #0x78 @turn everything off
+ mcr p15, 0, r0, c1, c0, 0 @(caches off, MMU off, etc.)
+
+
+@ ****************************************************************************
+@ Step 7
+@
+ @ Access memory *not yet enabled* for CBR refresh cycles (8)
+ @ - CBR is generated for all banks
+
+ ldr r2, =CFG_DRAM_BASE
+ str r2, [r2]
+ str r2, [r2]
+ str r2, [r2]
+ str r2, [r2]
+ str r2, [r2]
+ str r2, [r2]
+ str r2, [r2]
+ str r2, [r2]
+
+
+@ ****************************************************************************
+@ Step 8: NOP (enable dcache if you wanna... we dont)
+@
+
+
+@ ****************************************************************************
+@ Step 9
+@
+
+
+ @get memory controller base address
+ @
+ ldr r1, =MEMC_BASE
+
+ @fetch current mdcnfg value
+ @
+ ldr r3, [r1, #MDCNFG_OFFSET]
+
+ @enable sdram bank 0 if installed (must do for any populated bank)
+ @
+ orr r3, r3, #MDCNFG_DE0
+
+ @write back mdcnfg, enabling the sdram bank(s)
+ @
+ str r3, [r1, #MDCNFG_OFFSET]
+
+
+@****************************************************************************
+@ Step 10
+@
+
+ @ write mdmrs
+ @
+ ldr r2, =CFG_MDMRS_VAL
+ str r2, [r1, #MDMRS_OFFSET]
+
+
+@****************************************************************************
+@ Step 11: Final Step
+@
+
+@INITINTC
+ @********************************************************************
+ @ Disable (mask) all interrupts at the interrupt controller
+ @
+
+ @ clear the interrupt level register (use IRQ, not FIQ)
+ @
+ mov r1, #0
+ ldr r2, =ICLR
+ str r1, [r2]
+
+ @ mask all interrupts at the controller
+ @
+ ldr r2, =ICMR
+ str r1, [r2]
+
+
+@INITCLKS
+ @ ********************************************************************
+ @ Disable the peripheral clocks, and set the core clock
+ @ frequency (hard-coding at 398.12MHz for now).
+ @
+
+ @ Turn Off ALL on-chip peripheral clocks for re-configuration
+ @ *Note: See label 'ENABLECLKS' for the re-enabling
+ @
+ ldr r1, =CKEN
+ mov r2, #0
+ str r2, [r1]
+
+
+ @ default value in case no valid rotary switch setting is found
+ ldr r2, =(CCCR_L27 | CCCR_M2 | CCCR_N10) @ DEFAULT: {200/200/100}
+
+
+ @... and write the core clock config register
+ @
+ ldr r1, =CCCR
+ str r2, [r1]
+
+/* @ 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
+*/
+
+@OSCC_OON_DONE
+
+
+#ifdef A0_COTULLA
+ @****************************************************************************
+ @ !!! Take care of A0 Errata Sighting #4 --
+ @ after a frequency change, the memory controller must be restarted
+ @
+
+ @ get memory controller base address
+ ldr r1, =MEMC_BASE
+
+ @ get the current state of MDREFR
+ @
+ ldr r2, [r1, #MDREFR_OFFSET]
+
+ @ clear E0PIN, E1PIN
+ @
+ bic r3, r2, #(MDREFR_E0PIN | MDREFR_E1PIN)
+
+ @ write MDREFR with E0PIN, E1PIN cleared (disable sdclk[0,1])
+ @
+ str r3, [r1, #MDREFR_OFFSET]
+
+ @ then write MDREFR with E0PIN, E1PIN set (enable sdclk[0,1])
+ @
+ str r2, [r1, #MDREFR_OFFSET]
+
+ @ get the current state of MDCNFG
+ @
+ ldr r3, [r1, #MDCNFG_OFFSET]
+
+ @ disable all SDRAM banks
+ @
+ bic r3, r3, #(MDCNFG_DE0 | MDCNFG_DE1)
+ bic r3, r3, #(MDCNFG_DE2 | MDCNFG_DE3)
+
+ @ write back MDCNFG
+ @
+ ldr r3, [r1, #MDCNFG_OFFSET]
+
+ @ Access memory not yet enabled for CBR refresh cycles (8)
+ @ - CBR is generated for *all* banks
+ ldr r2, =CFG_DRAM_BASE
+ str r2, [r2]
+ str r2, [r2]
+ str r2, [r2]
+ str r2, [r2]
+ str r2, [r2]
+ str r2, [r2]
+ str r2, [r2]
+ str r2, [r2]
+
+ @ fetch current mdcnfg value
+ @
+ ldr r3, [r1, #MDCNFG_OFFSET]
+
+ @ enable sdram bank 0 if installed
+ @
+ orr r3, r3, #MDCNFG_DE0
+
+ @ write back mdcnfg, enabling the sdram bank(s)
+ @
+ str r3, [r1, #MDCNFG_OFFSET]
+
+ @ write mdmrs
+ @
+ ldr r2, =CFG_MDMRS_VAL
+ str r2, [r1, #MDMRS_OFFSET]
+
+
+
+ /* @ errata: don't enable auto power-down */
+ @ get current value of mdrefr
+ @ldr r3, [r1, #MDREFR_OFFSET]
+ @ enable auto-power down
+ @orr r3, r3, #MDREFR_APD
+ @write back mdrefr
+ @str r3, [r1, #MDREFR_OFFSET]
+
+#endif A0_Cotulla
+
+
+ ldr r0, =0x000C0dE3
+ ldr r1, =_LED
+ str r0, [r1] /* hex display */
+
+@ ^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%
+@ ^%^%^%^%^%^%^%^%^% above could be replaced by prememLLI ^%^%^%^%^%^%^%^%^%
+@ ^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%
+
+
+ /* Save SDRAM size */
+ ldr r1, =DRAM_SIZE
+ str r8, [r1]
+
+ ldr r0, =0xC0DE0006
+ ldr r1, =_LED
+ str r0, [r1] /* hex display */
+
+ /* Interrupt init */
+ /* Mask all interrupts */
+ ldr r0, =ICMR /* enable no sources */
+ mov r1, #0
+ str r1, [r0]
+
+#define NODEBUG
+#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
+
+ ldr r0, =0xBEEF001D
+ ldr r1, =_LED
+ str r0, [r1] /* hex display */
+
+ mov pc, r10
+
+@ End memsetup
+
+@ %%%%%%%%%%% Useful subroutines
+GET_S23:
+ @ This macro will read S23 and return its value in r3
+ @ r2 contains the base address of the Lubbock user registers
+ ldr r2, =FPGA_REGS_BASE_PHYSICAL
+
+ /*@ read S23's value */
+ ldr r3, [r2, #USER_SWITCHES_OFFSET]
+
+ @ mask out irrelevant bits
+ and r3, r3, #0x200
+
+ @ get bit into position 0
+ mov r3, r3, LSR #9
+
+ mov pc, lr
+@ End GET_S23
+
+
+GET_S24:
+ @ This macro will read S24 and return its value in r0
+ @ r2 contains the base address of the Lubbock user registers
+ ldr r2, =FPGA_REGS_BASE_PHYSICAL
+
+ /*@ read S24's value */
+ ldr r0, [r2, #USER_SWITCHES_OFFSET]
+
+ @ mask out irrelevant bits
+ and r0, r0, #0x100
+
+ @ get bit into position 0
+ mov r0, r0, LSR #8
+
+ mov pc, lr
+@ End GET_S23
+
+
+GET_S25:
+ @ This macro will read rotary S25 and return its value in r0
+ @ r2 contains the base address of the Lubbock user registers
+ @ read the user switches register
+ ldr r0, [r2, #USER_SWITCHES_OFFSET]
+
+ @ mask out irrelevant bits
+ and r0, r0, #0xF0
+
+ mov pc, lr
+@ End subroutine
+
+
+GET_S26:
+ @ This macro will read rotary S26 and return its value in r3
+ @ r2 contains the base address of the Lubbock user registers
+ @ read the user switches register
+ ldr r3, [r2, #USER_SWITCHES_OFFSET]
+
+ @ mask out irrelevant bits
+ and r3, r3, #0x0F
+
+ mov pc, lr
+@ End subroutine GET_S26
+
+
--- /dev/null
+#
+# (C) Copyright 2000
+# Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+# Marius Groeger <mgroeger@sysgo.de>
+#
+# (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
+#
+
+#
+# MBX8xx boards
+#
+
+TEXT_BASE = 0xfe000000
+/*TEXT_BASE = 0x00200000 */
--- /dev/null
+/*
+ * flash.c: Support code for the flash chips on the Xilinx ML2 board
+ *
+ * Copyright 2002 Mind NV
+ *
+ * http://www.mind.be/
+ *
+ * Author : Peter De Schrijver (p2@mind.be)
+ *
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL) version 2, incorporated herein by
+ * reference. Drivers based on or derived from this code fall under the GPL
+ * and must retain the authorship, copyright and this license notice. This
+ * file is not a complete program and may only be used when the entire program
+ * is licensed under the GPL.
+ *
+ */
+
+#include <common.h>
+#include <asm/u-boot.h>
+#include <configs/ML2.h>
+
+#define FLASH_BANK_SIZE (64*1024*1024)
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
+
+#define SECT_SIZE (512*1024)
+
+#define CMD_READ_ARRAY 0x00FF00FF00FF00FULL
+#define CMD_IDENTIFY 0x0090009000900090ULL
+#define CMD_ERASE_SETUP 0x0020002000200020ULL
+#define CMD_ERASE_CONFIRM 0x00D000D000D000D0ULL
+#define CMD_PROGRAM 0x0040004000400040ULL
+#define CMD_RESUME 0x00D000D000D000D0ULL
+#define CMD_SUSPEND 0x00B000B000B000B0ULL
+#define CMD_STATUS_READ 0x0070007000700070ULL
+#define CMD_STATUS_RESET 0x0050005000500050ULL
+
+#define BIT_BUSY 0x0080008000800080ULL
+#define BIT_ERASE_SUSPEND 0x004000400400040ULL
+#define BIT_ERASE_ERROR 0x0020002000200020ULL
+#define BIT_PROGRAM_ERROR 0x0010001000100010ULL
+#define BIT_VPP_RANGE_ERROR 0x0008000800080008ULL
+#define BIT_PROGRAM_SUSPEND 0x0004000400040004ULL
+#define BIT_PROTECT_ERROR 0x0002000200020002ULL
+#define BIT_UNDEFINED 0x0001000100010001ULL
+
+#define BIT_SEQUENCE_ERROR 0x0030003000300030ULL
+
+#define BIT_TIMEOUT 0x80000000
+
+
+inline void eieio(void) {
+
+ __asm__ __volatile__ ("eieio" : : : "memory");
+
+}
+
+ulong 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 = (INTEL_MANUFACT & FLASH_VENDMASK) |
+ (INTEL_ID_28F128J3A & 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 = CFG_FLASH_BASE;
+ else
+ panic("configured to many flash banks!\n");
+ for (j = 0; j < flash_info[i].sector_count; j++)
+ flash_info[i].start[j]=flashbase + j * SECT_SIZE;
+
+ size += flash_info[i].size;
+ }
+
+ return size;
+}
+
+void flash_print_info (flash_info_t *info) {
+
+ int i;
+
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case (INTEL_MANUFACT & FLASH_VENDMASK):
+ printf("Intel: ");
+ break;
+ default:
+ printf("Unknown Vendor ");
+ break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case (INTEL_ID_28F128J3A & FLASH_TYPEMASK):
+ printf("4x 28F128J3A (128Mbit)\n");
+ break;
+ default:
+ printf("Unknown Chip Type\n");
+ break;
+ }
+
+ printf(" Size: %ld MB in %d Sectors\n", info->size >> 20, info->sector_count);
+ printf(" Sector Start Addresses:");
+ for (i = 0; i < info->sector_count; i++) {
+ if ((i % 5) == 0)
+ printf("\n ");
+ printf (" %08lX%s", info->start[i],
+ info->protect[i] ? " (RO)" : " ");
+ }
+ printf ("\n");
+}
+
+int flash_error (unsigned long long code) {
+
+ if (code & BIT_TIMEOUT) {
+ printf ("Timeout\n");
+ return ERR_TIMOUT;
+ }
+
+ if (~code & BIT_BUSY) {
+ printf ("Busy\n");
+ return ERR_PROG_ERROR;
+ }
+
+ if (code & BIT_VPP_RANGE_ERROR) {
+ printf ("Vpp range error\n");
+ return ERR_PROG_ERROR;
+ }
+
+ if (code & BIT_PROTECT_ERROR) {
+ printf ("Device protect error\n");
+ return ERR_PROG_ERROR;
+ }
+
+ if (code & BIT_SEQUENCE_ERROR) {
+ printf ("Command seqence error\n");
+ return ERR_PROG_ERROR;
+ }
+
+ if (code & BIT_ERASE_ERROR) {
+ printf ("Block erase error\n");
+ return ERR_PROG_ERROR;
+ }
+
+ if (code & BIT_PROGRAM_ERROR) {
+ printf ("Program error\n");
+ return ERR_PROG_ERROR;
+ }
+
+ if (code & BIT_ERASE_SUSPEND) {
+ printf ("Block erase suspended\n");
+ return ERR_PROG_ERROR;
+ }
+
+ if (code & BIT_PROGRAM_SUSPEND) {
+ printf ("Program suspended\n");
+ return ERR_PROG_ERROR;
+ }
+
+ return ERR_OK;
+
+}
+
+int flash_erase (flash_info_t *info, int s_first, int s_last) {
+
+ int rc = ERR_OK;
+ int sect;
+ unsigned long long result;
+
+ 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) != (INTEL_MANUFACT & FLASH_VENDMASK))
+ return ERR_UNKNOWN_FLASH_VENDOR;
+
+ for (sect=s_first; sect<=s_last; ++sect)
+ if (info->protect[sect])
+ return ERR_PROTECTED;
+
+ for (sect = s_first; sect<=s_last && !ctrlc(); sect++) {
+ volatile unsigned long long *addr=
+ (unsigned long long *)(info->start[sect]);
+
+ printf("Erasing sector %2d ... ", sect);
+
+ *addr=CMD_STATUS_RESET;
+ eieio();
+ *addr=CMD_ERASE_SETUP;
+ eieio();
+ *addr=CMD_ERASE_CONFIRM;
+ eieio();
+
+ do {
+ result = *addr;
+ } while(~result & BIT_BUSY);
+
+ *addr=CMD_READ_ARRAY;
+
+ if ((rc = flash_error(result)) == ERR_OK)
+ printf("ok.\n");
+ else
+ break;
+ }
+
+ if (ctrlc())
+ printf("User Interrupt!\n");
+
+ return rc;
+}
+
+volatile static int write_word (flash_info_t *info, ulong dest, unsigned long long data) {
+
+ volatile unsigned long long *addr=(unsigned long long *)dest;
+ unsigned long long result;
+ int rc = ERR_OK;
+
+ result=*addr;
+ if ((result & data) != data)
+ return ERR_NOT_ERASED;
+
+ *addr=CMD_STATUS_RESET;
+ eieio();
+ *addr=CMD_PROGRAM;
+ eieio();
+ *addr=data;
+ eieio();
+
+ do {
+ result=*addr;
+ } while(~result & BIT_BUSY);
+
+ *addr=CMD_READ_ARRAY;
+
+ rc = flash_error(result);
+
+ return rc;
+
+}
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) {
+
+ ulong cp, wp;
+ unsigned long long data;
+ int l;
+ int i,rc;
+
+ wp=(addr & ~7);
+
+ if((l=addr-wp) != 0) {
+ data=0;
+ for(i=0,cp=wp;i<l;++i,++cp)
+ data = (data >> 8) | (*(uchar *)cp << 24);
+
+ for (; i<8 && cnt>0; ++i) {
+ data = (data >> 8) | (*src++ << 24);
+ --cnt;
+ ++cp;
+ }
+
+ for (; i<8; ++i, ++cp)
+ data = (data >> 8) | (*(uchar *)cp << 24);
+
+ if ((rc = write_word(info, wp, data)) != 0)
+ return rc;
+
+ wp+=8;
+ }
+
+ while(cnt>=8) {
+ data=*((unsigned long long *)src);
+ if ((rc = write_word(info, wp, data)) != 0)
+ return rc;
+ src+=8;
+ wp+=8;
+ cnt-=8;
+ }
+
+ if(cnt == 0)
+ return ERR_OK;
+
+ data = 0;
+ for (i=0, cp=wp; i<8 && cnt>0; ++i, ++cp) {
+ data = (data >> 8) | (*src++ << 24);
+ --cnt;
+ }
+ for (; i<8; ++i, ++cp) {
+ data = (data >> 8) | (*(uchar *)cp << 24);
+ }
+
+ return write_word(info, wp, data);
+
+}
+
--- /dev/null
+/*
+ * init.S: Stubs for U-Boot initialization
+ *
+ * Copyright 2002 Mind NV
+ *
+ * http://www.mind.be/
+ *
+ * Author : Peter De Schrijver (p2@mind.be)
+ *
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL) version 2, incorporated herein by
+ * reference. Drivers based on or derived from this code fall under the GPL
+ * and must retain the authorship, copyright and this license notice. This
+ * file is not a complete program and may only be used when the entire
+ * program is licensed under the GPL.
+ *
+ */
+
+#include <ppc4xx.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+
+ .globl ext_bus_cntlr_init
+ext_bus_cntlr_init:
+ blr
+
+ .globl sdram_init
+sdram_init:
+ blr
--- /dev/null
+/*
+ * ml2.c: U-Boot platform support for Xilinx ML2 board
+ *
+ * Copyright 2002 Mind NV
+ *
+ * http://www.mind.be/
+ *
+ * Author : Peter De Schrijver (p2@mind.be)
+ *
+ * Derived from : Other platform support files in this tree
+ *
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL) version 2, incorporated herein by
+ * reference. Drivers based on or derived from this code fall under the GPL
+ * and must retain the authorship, copyright and this license notice. This
+ * file is not a complete program and may only be used when the entire
+ * program is licensed under the GPL.
+ *
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+
+
+
+int board_pre_init (void)
+{
+ return 0;
+}
+
+
+int checkboard (void)
+{
+ unsigned char *s = getenv ("serial#");
+ unsigned char *e;
+
+ if (!s || strncmp (s, "ML2", 9)) {
+ printf ("### No HW ID - assuming ML2");
+ } else {
+ for (e = s; *e; ++e) {
+ if (*e == ' ')
+ break;
+ &nb