9
0
Fork 0

Initial revision

This commit is contained in:
wdenk 2002-11-03 00:38:21 +00:00
parent f9087a3213
commit fe8c2806cd
124 changed files with 48888 additions and 0 deletions

524
board/RPXlite/flash.c Normal file
View File

@ -0,0 +1,524 @@
/*
* (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);
}
/*-----------------------------------------------------------------------
*/

231
board/cogent/lcd.c Normal file
View File

@ -0,0 +1,231 @@
/* 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;
}

84
board/cogent/lcd.h Normal file
View File

@ -0,0 +1,84 @@
/* 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 *, ...);

471
board/cray/L1/flash.c Normal file
View File

@ -0,0 +1,471 @@
/*
* (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);
}
/*-----------------------------------------------------------------------
*/

147
board/cray/L1/init.S Normal file
View File

@ -0,0 +1,147 @@
/*------------------------------------------------------------------------------+ */
/* */
/* 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

17
board/dnp1110/config.mk Normal file
View File

@ -0,0 +1,17 @@
#
# 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

96
board/dnp1110/memsetup.S Normal file
View File

@ -0,0 +1,96 @@
/*
* 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

736
board/ebony/flash.c Normal file
View File

@ -0,0 +1,736 @@
/*
* (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);
}
/*-----------------------------------------------------------------------
*/

View File

@ -0,0 +1,49 @@
#
# (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 */

1130
board/eric/flash.c Normal file

File diff suppressed because it is too large Load Diff

355
board/eric/init.S Normal file
View File

@ -0,0 +1,355 @@
/*------------------------------------------------------------------------------+ */
/* */
/* 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

126
board/esd/ar405/flash.c Normal file
View File

@ -0,0 +1,126 @@
/*
* (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);
}

84
board/esd/canbt/flash.c Normal file
View File

@ -0,0 +1,84 @@
/*
* (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);
}

View File

@ -0,0 +1,84 @@
/*
* (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);
}

181
board/esd/dasa_sim/eeprom.c Normal file
View File

@ -0,0 +1,181 @@
/*
* (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++);
}
}

91
board/evb64260/ecctest.c Normal file
View File

@ -0,0 +1,91 @@
#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

75
board/evb64260/eth.h Normal file
View File

@ -0,0 +1,75 @@
/*
* (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__ */

864
board/evb64260/mpsc.c Normal file
View File

@ -0,0 +1,864 @@
/*
* (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;
}

200
board/evb64260/zuma_pbb.c Normal file
View File

@ -0,0 +1,200 @@
#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 */

View File

@ -0,0 +1,187 @@
#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;
}

876
board/fads/fads.c Normal file
View File

@ -0,0 +1,876 @@
/*
* (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 */
/* ------------------------------------------------------------------------- */

375
board/genietv/genietv.c Normal file
View File

@ -0,0 +1,375 @@
/*
* 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 */

23
board/lart/config.mk Normal file
View File

@ -0,0 +1,23 @@
#
# 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

96
board/lart/memsetup.S Normal file
View File

@ -0,0 +1,96 @@
/*
* 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

749
board/lubbock/memsetup.S Normal file
View File

@ -0,0 +1,749 @@
/*
* 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

33
board/mbx8xx/config.mk Normal file
View File

@ -0,0 +1,33 @@
#
# (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 */

301
board/ml2/flash.c Normal file
View File

@ -0,0 +1,301 @@
/*
* 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);
}

34
board/ml2/init.S Normal file
View File

@ -0,0 +1,34 @@
/*
* 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

67
board/ml2/ml2.c Normal file
View File

@ -0,0 +1,67 @@
/*
* 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;
}
for (; s < e; ++s) {
putc (*s);
}
}
putc ('\n');
return (0);
}
long int initdram (int board_type)
{
return 32 * 1024 * 1024;
}
int testdram (void)
{
printf ("test: xxx MB - ok\n");
return (0);
}

350
board/mousse/README Normal file
View File

@ -0,0 +1,350 @@
U-Boot for MOUSSE/MPC8240 (KAHLUA)
----------------------------------
James Dougherty (jfd@broadcom.com), 09/10/01
The Broadcom/Vooha Mousse board is a 3U Compact PCI system board
which uses the MPC8240, a 64MB SDRAM SIMM, and has onboard
DEC 21143, NS16550 UART, an SGS M48T59Y TOD, and 4MB FLASH.
See also: http://www.vooha.com/
* NVRAM setenv/printenv/savenv supported.
* Date Command
* Serial Console support
* Network support
* FLASH of kernel images is supported.
* FLASH of U-Boot to onboard and PLCC boot region.
* Kernel command line options from NVRAM is supported.
* IP PNP options supported.
U-Boot Loading...
U-Boot 1.0.5 (Sep 10 2001 - 00:22:25)
CPU: MPC8240 Revision 1.1 at 198 MHz: 16 kB I-Cache 16 kB D-Cache
Board: MOUSSE MPC8240/KAHLUA - CHRP (MAP B)
Built: Sep 10 2001 at 01:01:50
MPLD: Revision 127
Local Bus: 33 MHz
RTC: M48T589 TOD/NVRAM (8176) bytes
Current date/time: 9/10/2001 0:18:52
DRAM: 64 MB
FLASH: 1.960 MB
PCI: scanning bus0 ...
bus dev fn venID devID class rev MBAR0 MBAR1 IPIN ILINE
00 00 00 1057 0003 060000 11 00000008 00000000 01 00
00 0d 00 1011 0019 020000 41 80000001 80000000 01 01
00 0e 00 105a 4d38 018000 01 a0000001 a0001001 01 03
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 0
=>
I. Root FileSystem/IP Configuration
bootcmd=tftp 100000 vmlinux.img;bootm
bootdelay=3
baudrate=9600
ipaddr=<IP ADDRESS>
netmask=<NETMASK>
hostname=<NAME>
serverip=<NFS SERVER IP ADDRESS>
ethaddr=00:00:10:20:30:44
nfsroot=<NFS SERVER IP ADDRESS>:/boot/root-fs
gateway=<IP ADDRESS>
root=/dev/nfs
stdin=serial
stdout=serial
stderr=serial
NVRAM environment variables.
use the command:
setenv <attribute> <value>
type "saveenv" to write to NVRAM.
II. To boot from a hard drive:
setenv root /dev/hda1
III. IP options which configure the network:
ipaddr=<IP ADDRESS OF MACHINE>
netmask=<NETMASK>
hostname=mousse
ethaddr=00:00:10:20:30:44
gateway=<IP ADDRESS OF GATEWAY/ROUTER>
IV. IP Options which configure NFS Root/Boot Support
root=/dev/nfs
serverip=<NFS SERVER IP ADDRESS>
nfsroot=<NFS SERVER IP ADDRESS>:/boot/root-fs
V. U-Boot Image Support
The U-Boot boot loader assumes that after you build
your kernel (vmlinux), you will create a U-Boot image
using the following commands or script:
#!/bin/csh
/bin/touch vmlinux.img
/bin/rm vmlinux.img
set path=($TOOLBASE/bin $path)
set path=($U_BOOT/tools $path)
powerpc-linux-objcopy -S -O binary vmlinux vmlinux.bin
gzip -vf vmlinux.bin
mkimage -A ppc -O linux -T kernel -C gzip -a 0 -e 0 -n vmlinux.bin.gz -d vmlinux.bin.gz vmlinux.img
ls -l vmlinux.img
VI. ONBOARD FLASH Support
FLASH support is provided for the onboard FLASH chip Bootrom area.
U-Boot is loaded into either the ROM boot region of the FLASH chip,
after first being boot-strapped from a pre-progammed AMD29F040 PLCC
bootrom. The PLCC needs to be programmed with a ROM burner using
AMD 29F040 ROM parts and the u-boot.bin or u-boot.hex (S-Record)
images.
The PLCC overlays this same region of flash as the onboard FLASH,
the jumper J100 is a chip-select for which flash chip you want to
progam. When jumper J100 is connected to pins 2-3, you boot from
PLCC FLASH.
To bringup a system, simply flash a flash an AMD29F040 PLCC
bootrom, and put this in the PLCC socket. Move jumper J100 to
pins 2-3 and boot from the PLCC.
Now, while the system is running, move Jumper J100 to
pins 1-2 and follow the procedure below to FLASH a bootrom
(u-boot.bin) image into the onboard bootrom region (AMD29LV160DB):
tftp 100000 u-boot.bin
protect off FFF00000 FFF7FFFF
erase FFF00000 FFF7FFFF
cp.b 100000 FFF00000 \$(filesize)\
Here is an example:
=>tftp 100000 u-boot.bin
eth_halt
eth0: DC21143 Ethernet adapter(bus=0, device=13, func=0)
DEC Ethernet iobase=0x80000000
ARP broadcast 1
Filename 'u-boot.bin'.
Load address: 0x100000
Loading: #########################
done
Bytes transferred = 123220 (1e154 hex)
eth_halt
=>protect off FFF00000 FFF7FFFF
Un-Protected 8 sectors
=>erase FFF00000 FFF7FFFF
Erase Flash from 0xfff00000 to 0xfff7ffff
Erase FLASH[PLCC_BOOT] -8 sectors:........ done
Erased 8 sectors
=>cp.b 100000 FFF00000 1e154
Copy to Flash... FLASH[PLCC_BOOT]:..done
=>
B. FLASH RAMDISK REGION
FLASH support is provided for an Onboard 512K RAMDISK region.
TThe following commands will FLASH a bootrom (u-boot.bin) image
into the onboard FLASH region (AMD29LV160DB 2MB FLASH):
tftp 100000 u-boot.bin
protect off FFF80000 FFFFFFFF
erase FFF80000 FFFFFFFF
cp.b 100000 FFF80000 \$(filesize)\
C. FLASH KERNEL REGION (960KB)
FLASH support is provided for the 960KB onboard FLASH1 segment.
This allows flashing of kernel images which U-Boot can load
and run (standalone) from the onboard FLASH chip. It also assumes
The following commands will FLASH a kernel image to 0xffe10000
tftp 100000 vmlinux.img
protect off FFE10000 FFEFFFFF
erase FFE10000 FFEFFFFF
cp.b 100000 FFE10000 \$(filesize)\
reset
Here is an example:
=>tftp 100000 vmlinux.img
eth_halt
eth0: DC21143 Ethernet adapter(bus=0, device=13, func=0)
DEC Ethernet iobase=0x80000000
ARP broadcast 1
TFTP from server 209.128.93.133; our IP address is 209.128.93.138
Filename 'vmlinux.img'.
Load address: 0x100000
Loading: #####################################################################################################################################################
done
Bytes transferred = 760231 (b99a7 hex)
eth_halt
=>protect off FFE10000 FFEFFFFF
Un-Protected 15 sectors
=>erase FFE10000 FFEFFFFF
Erase Flash from 0xffe10000 to 0xffefffff
Erase FLASH[F0_SA3(KERNEL)] -15 sectors:............... done
Erased 15 sectors
=>cp.b 100000 FFE10000 b99a7
Copy to Flash... FLASH[F0_SA3(KERNEL)]:............done
=>
When finished, use the command:
bootm ffe10000
to start the kernel.
Finally, to make this the default boot command, use
the following commands:
setenv bootcmd bootm ffe10000
savenv
to make it automatically boot the kernel from FLASH.
To go back to development mode (NFS boot)
setenv bootcmd tftp 100000 vmlinux.img\;bootm
savenv
=>tftp 100000 vmlinux.img
eth0: DC21143 Ethernet adapter(bus=0, device=13, func=0)
DEC Ethernet iobase=0x80000000
ARP broadcast 1
Filename 'vmlinux.img'.
Load address: 0x100000
Loading: ####################################################################################################################################################
done
Bytes transferred = 752717 (b7c4d hex)
eth_halt
=>protect off FFE10000 FFEFFFFF
Un-Protected 15 sectors
=>erase FFE10000 FFEFFFFF
Erase Flash from 0xffe10000 to 0xffefffff
Erase FLASH[F0_SA3(KERNEL)] -15 sectors:............... done
Erased 15 sectors
=>cp.b 100000 FFE10000 b7c4d
Copy to Flash... FLASH[F0_SA3(KERNEL)]:............done
=>bootm ffe10000
## Booting image at ffe10000 ...
Image Name: vmlinux.bin.gz
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 752653 Bytes = 735 kB = 0 MB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK
Total memory = 64MB; using 0kB for hash table (at 00000000)
Linux version 2.4.2_hhl20 (jfd@atlantis) (gcc version 2.95.2 19991024 (release)) #597 Wed Sep 5 23:23:23 PDT 2001
cpu0: MPC8240/KAHLUA : MOUSSE Platform : 64MB RAM: MPLD Rev. 7f
Sandpoint port (C) 2000, 2001 MontaVista Software, Inc. (source@mvista.com)
IP PNP: 802.3 Ethernet Address=<0:0:10:20:30:44>
NOTICE: mounting root file system via NFS
On node 0 totalpages: 16384
zone(0): 16384 pages.
zone(1): 0 pages.
zone(2): 0 pages.
time_init: decrementer frequency = 16.665914 MHz
time_init: MPC8240 PCI Bus frequency = 33.331828 MHz
Calibrating delay loop... 133.12 BogoMIPS
Memory: 62436k available (1336k kernel code, 500k data, 88k init, 0k highmem)
Dentry-cache hash table entries: 8192 (order: 4, 65536 bytes)
Buffer-cache hash table entries: 4096 (order: 2, 16384 bytes)
Page-cache hash table entries: 16384 (order: 4, 65536 bytes)
Inode-cache hash table entries: 4096 (order: 3, 32768 bytes)
POSIX conformance testing by UNIFIX
PCI: Probing PCI hardware
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Initializing RT netlink socket
Starting kswapd v1.8
pty: 256 Unix98 ptys configured
block: queued sectors max/low 41394kB/13798kB, 128 slots per queue
Uniform Multi-Platform E-IDE driver Revision: 6.31
ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx
PDC20262: IDE controller on PCI bus 00 dev 70
PDC20262: chipset revision 1
PDC20262: not 100% native mode: will probe irqs later
PDC20262: ROM enabled at 0x000d0000
PDC20262: (U)DMA Burst Bit DISABLED Primary PCI Mode Secondary PCI Mode.
PDC20262: FORCING BURST BIT 0x00 -> 0x01 ACTIVE
PDC20262: irq=3 dev->irq=3
ide0: BM-DMA at 0xbfff00-0xbfff07, BIOS settings: hda:DMA, hdb:DMA
ide1: BM-DMA at 0xbfff08-0xbfff0f, BIOS settings: hdc:pio, hdd:pio
hda: WDC WD300AB-00BVA0, ATA DISK drive
hdc: SONY CD-RW CRX160E, ATAPI CD/DVD-ROM drive
ide0 at 0xbfff78-0xbfff7f,0xbfff76 on irq 3
ide1 at 0xbfff68-0xbfff6f,0xbfff66 on irq 3
hda: 58633344 sectors (30020 MB) w/2048KiB Cache, CHS=58168/16/63, UDMA(66)
hdc: ATAPI 32X CD-ROM CD-R/RW drive, 4096kB Cache
Uniform CD-ROM driver Revision: 3.12
Partition check:
/dev/ide/host0/bus0/target0/lun0: p1 p2
hd: unable to get major 3 for hard disk
udf: registering filesystem
loop: loaded (max 8 devices)
Serial driver version 5.02 (2000-08-09) with MANY_PORTS SHARE_IRQ SERIAL_PCI enabled
ttyS00 at 0xffe08080 (irq = 4) is a ST16650
Linux Tulip driver version 0.9.13a (January 20, 2001)
eth0: Digital DS21143 Tulip rev 65 at 0xbfff80, EEPROM not present, 00:00:10:20:30:44, IRQ 1.
eth0: MII transceiver #0 config 3000 status 7829 advertising 01e1.
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 4096 bind 4096)
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
devfs: v0.102 (20000622) Richard Gooch (rgooch@atnf.csiro.au)
devfs: boot_options: 0x0
VFS: Mounted root (nfs filesystem).
Mounted devfs on /dev
Freeing unused kernel memory: 88k init 4k openfirmware
eth0: Setting full-duplex based on MII#0 link partner capability of 45e1.
INIT: version 2.78 booting
INIT: Entering runlevel: 2
Welcome to Linux/PPC
MPC8240/MOUSSE
mousse login: root
Password:
PAM_unix[13]: (login) session opened for user root by LOGIN(uid=0)
Last login: Thu Sep 6 00:16:51 2001 on console
Welcome to Linux/PPC
MPC8240/MOUSSE
mousse#

259
board/mousse/mousse.h Normal file
View File

@ -0,0 +1,259 @@
/*
* MOUSSE/MPC8240 Board definitions.
* For more info, see http://www.vooha.com/
*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2001
* James Dougherty (jfd@cs.stanford.edu)
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef __MOUSSE_H
#define __MOUSSE_H
/* System addresses */
#define PCI_SPECIAL_BASE 0xfe000000
#define PCI_SPECIAL_SIZE 0x01000000
/* PORTX Device Addresses for Mousse */
#define PORTX_DEV_BASE 0xff000000
#define PORTX_DEV_SIZE 0x01000000
#define ENET_DEV_BASE 0x80000000
#define PLD_REG_BASE (PORTX_DEV_BASE | 0xe09000)
#define PLD_REG(off) (*(volatile unsigned char *) \
(PLD_REG_BASE + (off)))
#define PLD_REVID_B1 0x7f
#define PLD_REVID_B2 0x01
/* MPLD */
#define SYS_HARD_RESET() { for (;;) PLD_REG(0) = 0; } /* clr 0x80 bit */
#define SYS_REVID_GET() ((int) PLD_REG(0) & 0x7f)
#define SYS_LED_OFF() (PLD_REG(1) |= 0x80)
#define SYS_LED_ON() (PLD_REG(1) &= ~0x80)
#define SYS_WATCHDOG_IRQ3() (PLD_REG(2) |= 0x80)
#define SYS_WATCHDOG_RESET() (PLD_REG(2) &= ~0x80)
#define SYS_TOD_PROTECT() (PLD_REG(3) |= 0x80)
#define SYS_TOD_UNPROTECT() (PLD_REG(3) &= ~0x80)
/* SGS M48T59Y */
#define TOD_BASE (PORTX_DEV_BASE | 0xe0a000)
#define TOD_REG_BASE (TOD_BASE | 0x1ff0)
#define TOD_NVRAM_BASE TOD_BASE
#define TOD_NVRAM_SIZE 0x1ff0
#define TOD_NVRAM_LIMIT (TOD_NVRAM_BASE + TOD_NVRAM_SIZE)
/* NS16552 SIO */
#define SERIAL_BASE(_x) (PORTX_DEV_BASE | 0xe08000 | ((_x) ? 0 : 0x80))
#define N_SIO_CHANNELS 2
#define N_COM_PORTS N_SIO_CHANNELS
/*
* On-board Dec21143 PCI Ethernet
* Note: The PCI MBAR chosen here was used from MPC8240UM which states
* that PCI memory is at: 0x80000 - 0xFDFFFFFF, if AMBOR[CPU_FD_ALIAS]
* is set, then PCI memory maps 1-1 with this address range in the
* correct byte order.
*/
#define PCI_ENET_IOADDR 0x80000000
#define PCI_ENET_MEMADDR 0x80000000
/*
* Flash Memory Layout
*
* 2 MB Flash Bank 0 runs in 8-bit mode. In Flash Bank 0, the 32 kB
* sector SA3 is obscured by the 32 kB serial/TOD access space, and
* the 64 kB sectors SA19-SA26 are obscured by the 512 kB PLCC
* containing the fixed boot ROM. (If the 512 kB PLCC is
* deconfigured by jumper, this window to Flash Bank 0 becomes
* visible, but it still contains the fixed boot code and should be
* considered read-only). Flash Bank 0 sectors SA0 (16 kB), SA1 (8
* kB), and SA2 (8 kB) are currently unused.
*
* 2 MB Flash Bank 1 runs in 16-bit mode. Flash Bank 1 is fully
* usable, but it's a 16-bit wide device on a 64-bit bus. Therefore
* 16-bit words only exist at addresses that are multiples of 8. All
* PROM data and control addresses must be multiplied by 8.
*
* See flashMap.c for description of flash filesystem layout.
*/
/*
* FLASH memory address space: 8-bit wide FLASH memory spaces.
*/
#define FLASH0_SEG0_START 0xffe00000 /* Baby 32Kb segment */
#define FLASH0_SEG0_END 0xffe07fff /* 16 kB + 8 kB + 8 kB */
#define FLASH0_SEG0_SIZE 0x00008000 /* (sectors SA0-SA2) */
#define FLASH0_SEG1_START 0xffe10000 /* 1MB - 64Kb FLASH0 seg */
#define FLASH0_SEG1_END 0xffefffff /* 960 kB */
#define FLASH0_SEG1_SIZE 0x000f0000
#define FLASH0_SEG2_START 0xfff00000 /* Boot Loader stored here */
#define FLASH0_SEG2_END 0xfff7ffff /* 512 kB FLASH0/PLCC seg */
#define FLASH0_SEG2_SIZE 0x00080000
#define FLASH0_SEG3_START 0xfff80000 /* 512 kB FLASH0 seg */
#define FLASH0_SEG3_END 0xffffffff
#define FLASH0_SEG3_SIZE 0x00080000
/* Where Kahlua starts */
#define FLASH_RESET_VECT 0xfff00100
/*
* CHRP / PREP (MAP A/B) definitions.
*/
#define PREP_REG_ADDR 0x80000cf8 /* MPC107 Config, Map A */
#define PREP_REG_DATA 0x80000cfc /* MPC107 Config, Map A */
/* MPC107 (MPC8240 internal EUMBBAR mapped) */
#define CHRP_REG_ADDR 0xfec00000 /* MPC106 Config, Map B */
#define CHRP_REG_DATA 0xfee00000 /* MPC106 Config, Map B */
/*
* Mousse PCI IDSEL Assignments (Device Number)
*/
#define MOUSSE_IDSEL_ENET 13 /* On-board 21143 Ethernet */
#define MOUSSE_IDSEL_LPCI 14 /* On-board PCI slot */
#define MOUSSE_IDSEL_82371 15 /* That other thing */
#define MOUSSE_IDSEL_CPCI2 31 /* CPCI slot 2 */
#define MOUSSE_IDSEL_CPCI3 30 /* CPCI slot 3 */
#define MOUSSE_IDSEL_CPCI4 29 /* CPCI slot 4 */
#define MOUSSE_IDSEL_CPCI5 28 /* CPCI slot 5 */
#define MOUSSE_IDSEL_CPCI6 27 /* CPCI slot 6 */
/*
* Mousse Interrupt Mapping:
*
* IRQ1 Enet (intA|intB|intC|intD)
* IRQ2 CPCI intA (See below)
* IRQ3 Local PCI slot intA|intB|intC|intD
* IRQ4 COM1 Serial port (Actually higher addressed port on duart)
*
* PCI Interrupt Mapping in CPCI chassis:
*
* | CPCI Slot
* | 1 (CPU) 2 3 4 5 6
* -----------+--------+-------+-------+-------+-------+-------+
* intA | X X X
* intB | X X X
* intC | X X X
* intD | X X X
*/
#define EPIC_VECTOR_EXT0 0
#define EPIC_VECTOR_EXT1 1
#define EPIC_VECTOR_EXT2 2
#define EPIC_VECTOR_EXT3 3
#define EPIC_VECTOR_EXT4 4
#define EPIC_VECTOR_TM0 16
#define EPIC_VECTOR_TM1 17
#define EPIC_VECTOR_TM2 18
#define EPIC_VECTOR_TM3 19
#define EPIC_VECTOR_I2C 20
#define EPIC_VECTOR_DMA0 21
#define EPIC_VECTOR_DMA1 22
#define EPIC_VECTOR_I2O 23
#define INT_VEC_IRQ0 0
#define INT_NUM_IRQ0 INT_VEC_IRQ0
#define MOUSSE_IRQ_ENET EPIC_VECTOR_EXT1 /* Hardwired */
#define MOUSSE_IRQ_CPCI EPIC_VECTOR_EXT2 /* Hardwired */
#define MOUSSE_IRQ_LPCI EPIC_VECTOR_EXT3 /* Hardwired */
#define MOUSSE_IRQ_DUART EPIC_VECTOR_EXT4 /* Hardwired */
/* Onboard DEC 21143 Ethernet */
#define PCI_ENET_MEMADDR 0x80000000
#define PCI_ENET_IOADDR 0x80000000
/* Some other PCI device */
#define PCI_SLOT_MEMADDR 0x81000000
#define PCI_SLOT_IOADDR 0x81000000
/* Promise ATA66 PCI Device (ATA controller) */
#define PROMISE_MBAR0 0xa0000000
#define PROMISE_MBAR1 (PROMISE_MBAR0 + 0x1000)
#define PROMISE_MBAR2 (PROMISE_MBAR0 + 0x2000)
#define PROMISE_MBAR3 (PROMISE_MBAR0 + 0x3000)
#define PROMISE_MBAR4 (PROMISE_MBAR0 + 0x4000)
#define PROMISE_MBAR5 (PROMISE_MBAR0 + 0x5000)
/* ATA/66 Controller offsets */
#define CFG_ATA_BASE_ADDR PROMISE_MBAR0
#define CFG_IDE_MAXBUS 2 /* ide0/ide1 */
#define CFG_IDE_MAXDEVICE 2 /* 2 drives per controller */
#define CFG_ATA_IDE0_OFFSET 0
#define CFG_ATA_IDE1_OFFSET 0x3000
/*
* Definitions for accessing IDE controller registers
*/
#define CFG_ATA_DATA_OFFSET 0
#define CFG_ATA_REG_OFFSET 0
#define CFG_ATA_ALT_OFFSET (0x1000)
/*
* The constants ROM_TEXT_ADRS, ROM_SIZE, RAM_HIGH_ADRS, and RAM_LOW_ADRS
* are defined in config.h and Makefile.
* All definitions for these constants must be identical.
*/
#define ROM_BASE_ADRS 0xfff00000 /* base address of ROM */
#define ROM_TEXT_ADRS (ROM_BASE_ADRS+0x0100) /* with PC & SP */
#define ROM_WARM_ADRS (ROM_TEXT_ADRS+0x0004) /* warm reboot entry */
#define ROM_SIZE 0x00080000 /* 512KB ROM space */
#define RAM_LOW_ADRS 0x00010000 /* RAM address for vxWorks */
#define RAM_HIGH_ADRS 0x00c00000 /* RAM address for bootrom */
/*
* NVRAM configuration
* NVRAM is implemented via the SGS Thomson M48T59Y
* 64Kbit (8Kbx8) Timekeeper SRAM.
* This 8KB NVRAM also has a TOD. See m48t59y.{h,c} for more information.
*/
#define NV_RAM_ADRS TOD_NVRAM_BASE
#define NV_RAM_INTRVL 1
#define NV_RAM_WR_ENBL SYS_TOD_UNPROTECT()
#define NV_RAM_WR_DSBL SYS_TOD_PROTECT()
#define NV_OFF_BOOT0 0x0000 /* Boot string 0 (256b) */
#define NV_OFF_BOOT1 0x0100 /* Boot string 1 (256b) */
#define NV_OFF_BOOT2 0x0200 /* Boot string 2 (256b)*/
#define NV_OFF_MACADDR 0x0400 /* 21143 MAC address (6b) */
#define NV_OFF_ACTIVEBOOT 0x0406 /* Active boot string, 0 to 2 (1b) */
#define NV_OFF_UNUSED1 0x0407 /* Unused (1b) */
#define NV_OFF_BINDFIX 0x0408 /* See sysLib.c:sysBindFix() (1b) */
#define NV_OFF_UNUSED2 0x0409 /* Unused (7b) */
#define NV_OFF_TIMEZONE 0x0410 /* TIMEZONE env var (64b) */
#define NV_OFF_VXWORKS_END 0x07FF /* 2047 VxWorks Total */
#define NV_OFF_U_BOOT 0x0800 /* 2048 U-Boot boot-loader */
#define NV_OFF_U_BOOT_ADDR (TOD_BASE + NV_OFF_U_BOOT) /* sysaddr*/
#define NV_U_BOOT_ENV_SIZE 2048 /* 2K - U-Boot Total */
#define NV_OFF__next_free (NV_U_BOOT_ENVSIZE +1)
#define NV_RAM_SIZE 8176 /* NVRAM End */
#endif /* __MOUSSE_H */

15
board/mvs1/README Normal file
View File

@ -0,0 +1,15 @@
This port is for the MATRIX Vision mvSensor.
It is an mpc823-based universal image processing board
with CMOS or CCD sensor, 4MB FLASH and 16-64MB RAM.
See http://www.matrix-vision.de for more details or mail...
mvsensor@matrix-vision.de
Howard Gray
MATRIX Vision GmbH
Talstr. 16
D-71570
Oppenweiler
Germany

404
board/mvs1/mvs1.c Normal file
View File

@ -0,0 +1,404 @@
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* Changes for MATRIX Vision MVsensor (C) Copyright 2001
* MATRIX Vision GmbH / hg, info@matrix-vision.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 <mpc8xx.h>
/* ------------------------------------------------------------------------- */
static long int dram_size (long int, long int *, long int);
/* ------------------------------------------------------------------------- */
#define _NOT_USED_ 0xFFFFFFFF
const uint sdram_table[] =
{
/*
* Single Read. (Offset 0 in UPMA RAM)
*/
0x1F0DFC04, 0xEEAFBC04, 0x11AF7C04, 0xEFBAFC00,
0x1FF5FC47, /* last */
/*
* SDRAM Initialization (offset 5 in UPMA 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.
*
*/
0x1FF5FC34, 0xEFEABC34, 0x1FB57C35, /* last */
/*
* Burst Read. (Offset 8 in UPMA RAM)
*/
0x1F0DFC04, 0xEEAFBC04, 0x10AF7C04, 0xF0AFFC00,
0xF0AFFC00, 0xF1AFFC00, 0xEFBAFC00, 0x1FF5FC47, /* last */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/*
* Single Write. (Offset 18 in UPMA RAM)
*/
0x1F0DFC04 /*0x1F2DFC04??*/, 0xEEABBC00, 0x01B27C04, 0x1FF5FC47, /* last */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/*
* Burst Write. (Offset 20 in UPMA RAM)
*/
0x1F0DFC04, 0xEEABBC00, 0x10A77C00, 0xF0AFFC00,
0xF0AFFC00, 0xE1BAFC04, 0x1FF5FC47, /* last */
_NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/*
* Refresh (Offset 30 in UPMA RAM)
*/
0x1FFD7C84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
0xFFFFFC84, 0xFFFFFC07, /* last */
_NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/*
* Exception. (Offset 3c in UPMA RAM)
*/
0x7FFFFC07, /* last */
_NOT_USED_, _NOT_USED_, _NOT_USED_,
};
/* ------------------------------------------------------------------------- */
/*
* Check Board Identity:
*/
int checkboard (void)
{
puts ("Board: MATRIX Vision MVsensor\n");
return 0;
}
#ifdef DO_RAM_TEST
/* ------------------------------------------------------------------------- */
/*
* Test SDRAM by writing its address to itself and reading several times
*/
#define READ_RUNS 4
static void test_dram (unsigned long *start, unsigned long *end)
{
unsigned long *addr;
unsigned long value;
int read_runs, errors, addr_errors;
printf ("\nChecking SDRAM from %p to %p\n", start, end);
udelay (1000000);
for (addr = start; addr < end; addr++)
*addr = (unsigned long) addr;
for (addr = start, addr_errors = 0; addr < end; addr++) {
for (read_runs = READ_RUNS, errors = 0; read_runs > 0; read_runs--) {
if ((value = *addr) != (unsigned long) addr)
errors++;
}
if (errors > 0) {
addr_errors++;
printf ("SDRAM errors (%d) at %p, last read = %ld\n",
errors, addr, value);
udelay (10000);
}
}
printf ("SDRAM check finished, total errors = %d\n", addr_errors);
}
#endif /* DO_RAM_TEST */
/* ------------------------------------------------------------------------- */
long int initdram (int board_type)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
long int size_b0, size_b1, size8, size9;
upmconfig (UPMA, (uint *) sdram_table,
sizeof (sdram_table) / sizeof (uint));
/*
* 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_8K;
memctl->memc_mar = 0x00000088;
/*
* Map controller banks 2 and 3 to the SDRAM banks 2 and 3 at
* preliminary addresses - these have to be modified after the
* SDRAM size has been determined.
*/
memctl->memc_or2 = CFG_OR2_PRELIM;
memctl->memc_br2 = CFG_BR2_PRELIM;
#if defined (CFG_OR3_PRELIM) && defined (CFG_BR3_PRELIM)
if (board_type == 0) { /* "L" type boards have only one bank SDRAM */
memctl->memc_or3 = CFG_OR3_PRELIM;
memctl->memc_br3 = CFG_BR3_PRELIM;
}
#endif
memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */
udelay (200);
/* perform SDRAM initializsation sequence */
memctl->memc_mcr = 0x80004105; /* SDRAM bank 0 */
udelay (1);
memctl->memc_mcr = 0x80004230; /* SDRAM bank 0 - execute twice */
udelay (1);
if (board_type == 0) { /* "L" type boards have only one bank SDRAM */
memctl->memc_mcr = 0x80006105; /* SDRAM bank 1 */
udelay (1);
memctl->memc_mcr = 0x80006230; /* SDRAM bank 1 - execute twice */
udelay (1);
}
memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
udelay (1000);
/*
* Check Bank 0 Memory Size for re-configuration
*
* try 8 column mode
*/
size8 = dram_size (CFG_MAMR_8COL, (ulong *) SDRAM_BASE2_PRELIM,
SDRAM_MAX_SIZE);
udelay (1000);
/*
* try 9 column mode
*/
size9 = dram_size (CFG_MAMR_9COL, (ulong *) SDRAM_BASE2_PRELIM,
SDRAM_MAX_SIZE);
if (size8 < size9) { /* leave configuration at 9 columns */
size_b0 = size9;
} else { /* back to 8 columns */
size_b0 = size8;
memctl->memc_mamr = CFG_MAMR_8COL;
udelay (500);
}
if (board_type == 0) { /* "L" type boards have only one bank SDRAM */
/*
* Check Bank 1 Memory Size
* use current column settings
* [9 column SDRAM may also be used in 8 column mode,
* but then only half the real size will be used.]
*/
#if defined (SDRAM_BASE3_PRELIM)
size_b1 =
dram_size (memctl->memc_mamr, (ulong *) SDRAM_BASE3_PRELIM,
SDRAM_MAX_SIZE);
#else
size_b1 = 0;
#endif
} else {
size_b1 = 0;
}
udelay (1000);
/*
* Adjust refresh rate depending on SDRAM type, both banks
* For types > 128 MBit leave it at the current (fast) rate
*/
if ((size_b0 < 0x02000000) && (size_b1 < 0x02000000)) {
/* reduce to 15.6 us (62.4 us / quad) */
memctl->memc_mptpr = CFG_MPTPR_2BK_4K;
udelay (1000);
}
/*
* Final mapping: map bigger bank first
*/
if (size_b1 > size_b0) { /* SDRAM Bank 1 is bigger - map first */
memctl->memc_or3 = ((-size_b1) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
memctl->memc_br3 =
(CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
if (size_b0 > 0) {
/*
* Position Bank 0 immediately above Bank 1
*/
memctl->memc_or2 =
((-size_b0) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
memctl->memc_br2 =
((CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V)
+ size_b1;
} else {
unsigned long reg;
/*
* No bank 0
*
* invalidate bank
*/
memctl->memc_br2 = 0;
/* adjust refresh rate depending on SDRAM type, one bank */
reg = memctl->memc_mptpr;
reg >>= 1; /* reduce to CFG_MPTPR_1BK_8K / _4K */
memctl->memc_mptpr = reg;
}
} else { /* SDRAM Bank 0 is bigger - map first */
memctl->memc_or2 = ((-size_b0) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
memctl->memc_br2 =
(CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
if (size_b1 > 0) {
/*
* Position Bank 1 immediately above Bank 0
*/
memctl->memc_or3 =
((-size_b1) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
memctl->memc_br3 =
((CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V)
+ size_b0;
} else {
unsigned long reg;
/*
* No bank 1
*
* invalidate bank
*/
memctl->memc_br3 = 0;
/* adjust refresh rate depending on SDRAM type, one bank */
reg = memctl->memc_mptpr;
reg >>= 1; /* reduce to CFG_MPTPR_1BK_8K / _4K */
memctl->memc_mptpr = reg;
}
}
udelay (10000);
#ifdef DO_RAM_TEST
if (size_b0 > 0)
test_dram ((unsigned long *) CFG_SDRAM_BASE,
(unsigned long *) (CFG_SDRAM_BASE + size_b0));
#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 mamr_value, long int *base,
long int maxsize)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
volatile long int *addr;
long int cnt, val;
memctl->memc_mamr = mamr_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) {
return (0);
}
for (cnt = 1;; cnt <<= 1) {
addr = base + cnt; /* pointer arith! */
val = *addr;
if (val != (~cnt)) {
return (cnt * sizeof (long));
}
}
/* NOTREACHED */
}
/* ------------------------------------------------------------------------- */
u8 *dhcp_vendorex_prep (u8 * e)
{
char *ptr;
/* DHCP vendor-class-identifier = 60 */
if ((ptr = getenv ("dhcp_vendor-class-identifier"))) {
*e++ = 60;
*e++ = strlen (ptr);
while (*ptr)
*e++ = *ptr++;
}
/* my DHCP_CLIENT_IDENTIFIER = 61 */
if ((ptr = getenv ("dhcp_client_id"))) {
*e++ = 61;
*e++ = strlen (ptr);
while (*ptr)
*e++ = *ptr++;
}
return e;
}
/* ------------------------------------------------------------------------- */
u8 *dhcp_vendorex_proc (u8 * popt)
{
return NULL;
}

307
board/ppmc8260/ppmc8260.c Normal file
View File

@ -0,0 +1,307 @@
/*
* (C) Copyright 2000
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright 2001
* Advent Networks, Inc. <http://www.adventnetworks.com>
* Jay Monkman <jtm@smoothsmoothie.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 <ioports.h>
#include <mpc8260.h>
/*
* I/O Port configuration table
*
* if conf is 1, then that port pin will be configured at boot time
* according to the five values podr/pdir/ppar/psor/pdat for that entry
*/
const iop_conf_t iop_conf_tab[4][32] = {
/* Port A configuration */
{ /* conf ppar psor pdir podr pdat */
/* PA31 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 *ATMTXEN */
/* PA30 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTCA */
/* PA29 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTSOC */
/* PA28 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 *ATMRXEN */
/* PA27 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRSOC */
/* PA26 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRCA */
/* PA25 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[0] */
/* PA24 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[1] */
/* PA23 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[2] */
/* PA22 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[3] */
/* PA21 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[4] */
/* PA20 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[5] */
/* PA19 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[6] */
/* PA18 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[7] */
/* PA17 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[7] */
/* PA16 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[6] */
/* PA15 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[5] */
/* PA14 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[4] */
/* PA13 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[3] */
/* PA12 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[2] */
/* PA11 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[1] */
/* PA10 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[0] */
/* PA9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC2 TXD */
/* PA8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC2 RXD */
/* PA7 */ { 1, 0, 0, 1, 0, 0 }, /* TDM_A1:L1TSYNC */
/* PA6 */ { 1, 0, 0, 1, 0, 0 }, /* TDN_A1:L1RSYNC */
/* PA5 */ { 0, 0, 0, 0, 0, 0 }, /* PA5 */
/* PA4 */ { 0, 0, 0, 0, 0, 0 }, /* PA4 */
/* PA3 */ { 0, 0, 0, 0, 0, 0 }, /* PA3 */
/* PA2 */ { 0, 0, 0, 0, 0, 0 }, /* PA2 */
/* PA1 */ { 0, 0, 0, 0, 0, 0 }, /* PA1 */
/* PA0 */ { 0, 0, 0, 0, 0, 0 } /* PA0 */
},
/* Port B configuration */
{ /* conf ppar psor pdir podr pdat */
/* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TX_ER */
/* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */
/* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */
/* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */
/* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */
/* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */
/* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */
/* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */
/* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */
/* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */
/* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */
/* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */
/* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */
/* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */
/* PB17 */ { 0, 0, 0, 0, 0, 0 }, /* PB17 */
/* PB16 */ { 1, 0, 0, 0, 0, 0 }, /* TDM_A1:L1CLK0 */
/* PB15 */ { 1, 0, 0, 1, 0, 1 }, /* /FETHRST */
/* PB14 */ { 1, 0, 0, 1, 0, 0 }, /* FETHDIS */
/* PB13 */ { 0, 0, 0, 0, 0, 0 }, /* PB13 */
/* PB12 */ { 1, 0, 0, 1, 0, 0 }, /* TDM_B1:L1CLK0 */
/* PB11 */ { 1, 0, 0, 1, 0, 0 }, /* TDM_D1:L1TXD */
/* PB10 */ { 1, 0, 0, 1, 0, 0 }, /* TDM_D1:L1RXD */
/* PB9 */ { 1, 0, 0, 1, 0, 0 }, /* TDM_D1:L1TSYNC */
/* PB8 */ { 1, 0, 0, 1, 0, 0 }, /* TDM_D1:L1RSYNC */
/* PB7 */ { 0, 0, 0, 0, 0, 0 }, /* PB7 */
/* PB6 */ { 0, 0, 0, 0, 0, 0 }, /* PB6 */
/* PB5 */ { 0, 0, 0, 0, 0, 0 }, /* PB5 */
/* PB4 */ { 0, 0, 0, 0, 0, 0 }, /* PB4 */
/* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
},
/* Port C */
{ /* conf ppar psor pdir podr pdat */
/* PC31 */ { 0, 0, 0, 0, 0, 0 }, /* PC31 */
/* PC30 */ { 0, 0, 0, 0, 0, 0 }, /* PC30 */
/* PC29 */ { 0, 0, 0, 0, 0, 0 }, /* PC28 */
/* PC28 */ { 1, 1, 0, 0, 0, 0 }, /* CLK4 */
/* PC27 */ { 0, 0, 0, 0, 0, 0 }, /* PC27 */
/* PC26 */ { 0, 0, 0, 0, 0, 0 }, /* PC26 */
/* PC25 */ { 1, 1, 0, 0, 0, 0 }, /* CLK7 */
/* PC24 */ { 0, 0, 0, 0, 0, 0 }, /* PC24 */
/* PC23 */ { 1, 0, 0, 1, 0, 0 }, /* ATMTFCLK */
/* PC22 */ { 0, 0, 0, 0, 0, 0 }, /* PC22 */
/* PC21 */ { 0, 0, 0, 0, 0, 0 }, /* PC23 */
/* PC20 */ { 0, 0, 0, 0, 0, 0 }, /* PC24 */
/* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_CLK */
/* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII TX_CLK */
/* PC17 */ { 0, 0, 0, 0, 0, 0 }, /* PC17 */
/* PC16 */ { 0, 0, 0, 0, 0, 0 }, /* PC16 */
/* PC15 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1:TxAddr[0] */
/* PC14 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1:RxAddr[0] */
/* PC13 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1:TxAddr[1] */
/* PC12 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1:RxAddr[1] */
/* PC11 */ { 1, 1, 0, 1, 0, 0 }, /* TDM_D1:L1CLK0 */
/* PC10 */ { 1, 0, 0, 1, 0, 0 }, /* FCC2 MDC */
/* PC9 */ { 1, 0, 0, 1, 0, 0 }, /* FCC2 MDIO */
/* PC8 */ { 0, 0, 0, 0, 0, 0 }, /* PC8 */
/* PC7 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1:TxAddr[2]*/
/* PC6 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1:RxAddr[2] */
/* PC5 */ { 0, 0, 0, 0, 0, 0 }, /* PC5 */
/* PC4 */ { 0, 0, 0, 0, 0, 0 }, /* PC4 */
/* PC3 */ { 1, 0, 0, 1, 0, 0 }, /* IDMA2:DACK */
/* PC2 */ { 1, 0, 0, 1, 0, 0 }, /* IDMA2:DONE */
/* PC1 */ { 1, 0, 0, 1, 0, 0 }, /* IDMA2:DREQ */
/* PC0 */ { 1, 0, 0, 1, 0, 0 }, /* IDMA1:DREQ */
},
/* Port D */
{ /* conf ppar psor pdir podr pdat */
/* PD31 */ { 0, 0, 0, 0, 0, 0 }, /* PD31 */
/* PD30 */ { 0, 0, 0, 0, 0, 0 }, /* PD30 */
/* PD29 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1:RxAddr[3] */
/* PD28 */ { 0, 0, 0, 0, 0, 0 }, /* PD28 */
/* PD27 */ { 0, 0, 0, 0, 0, 0 }, /* PD27 */
/* PD26 */ { 1, 0, 0, 1, 0, 0 }, /* TDM_C1:L1RSYNC */
/* PD25 */ { 0, 0, 0, 0, 0, 0 }, /* PD25 */
/* PD24 */ { 0, 0, 0, 0, 0, 0 }, /* PD24 */
/* PD23 */ { 0, 0, 0, 0, 0, 0 }, /* PD23 */
/* PD22 */ { 0, 0, 0, 0, 0, 0 }, /* PD22 */
/* PD21 */ { 0, 0, 0, 0, 0, 0 }, /* PD21 */
/* PD20 */ { 0, 0, 0, 0, 0, 0 }, /* PD20 */
/* PD19 */ { 0, 0, 0, 0, 0, 0 }, /* PD19 */
/* PD18 */ { 0, 0, 0, 0, 0, 0 }, /* PD19 */
/* PD17 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */
/* PD16 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXPRTY */
/* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */
/* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */
/* PD13 */ { 1, 0, 0, 0, 0, 0 }, /* TDM_B1:L1TXD */
/* PD12 */ { 1, 0, 0, 0, 0, 0 }, /* TDM_B1:L1RXD */
/* PD11 */ { 1, 0, 0, 0, 0, 0 }, /* TDM_B1:L1TSYNC */
/* PD10 */ { 1, 0, 0, 0, 0, 0 }, /* TDM_B1:L1RSYNC*/
/* PD9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC1:TXD */
/* PD8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC1:RXD */
/* PD7 */ { 1, 1, 0, 0, 0, 0 }, /* SMC1:SMSYN */
/* PD6 */ { 1, 0, 0, 1, 0, 0 }, /* IDMA1:DACK */
/* PD5 */ { 1, 0, 0, 1, 0, 0 }, /* IDMA1:DONE */
/* PD4 */ { 0, 0, 0, 0, 0, 0 }, /* PD4 */
/* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
}
};
/* ------------------------------------------------------------------------- */
/*
* Check Board Identity:
*/
int checkboard (void)
{
puts ("Board: Wind River PPMC8260\n");
return 0;
}
/* ------------------------------------------------------------------------- */
long int initdram (int board_type)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile memctl8260_t *memctl = &immap->im_memctl;
volatile uchar c = 0xff;
volatile uchar *ramaddr0 = (uchar *) (CFG_SDRAM0_BASE);
volatile uchar *ramaddr1 = (uchar *) (CFG_SDRAM1_BASE);
ulong psdmr = CFG_PSDMR;
volatile uchar *ramaddr2 = (uchar *) (CFG_SDRAM2_BASE);
ulong lsdmr = CFG_LSDMR;
int i;
/*
* Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
*
* "At system reset, initialization software must set up the
* programmable parameters in the memory controller banks registers
* (ORx, BRx, P/LSDMR). After all memory parameters are configured,
* system software should execute the following initialization sequence
* for each SDRAM device.
*
* 1. Issue a PRECHARGE-ALL-BANKS command
* 2. Issue eight CBR REFRESH commands
* 3. Issue a MODE-SET command to initialize the mode register
*
* The initial commands are executed by setting P/LSDMR[OP] and
* accessing the SDRAM with a single-byte transaction."
*
* The appropriate BRx/ORx registers have already been set when we
* get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE.
*/
memctl->memc_psrt = CFG_PSRT;
memctl->memc_mptpr = CFG_MPTPR;
#ifndef CFG_RAMBOOT
memctl->memc_psdmr = psdmr | PSDMR_OP_PREA;
*ramaddr0++ = c;
*ramaddr1++ = c;
memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR;
for (i = 0; i < 8; i++) {
*ramaddr0++ = c;
*ramaddr1++ = c;
}
memctl->memc_psdmr = psdmr | PSDMR_OP_MRW;
ramaddr0 = (uchar *) (CFG_SDRAM0_BASE + 0x110);
ramaddr1 = (uchar *) (CFG_SDRAM1_BASE + 0x110);
*ramaddr0 = c;
*ramaddr1 = c;
memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN;
*ramaddr0 = c;
*ramaddr1 = c;
memctl->memc_lsdmr = lsdmr | PSDMR_OP_PREA;
*ramaddr2++ = c;
memctl->memc_lsdmr = lsdmr | PSDMR_OP_CBRR;
for (i = 0; i < 8; i++) {
*ramaddr2++ = c;
}
memctl->memc_lsdmr = lsdmr | PSDMR_OP_MRW;
*ramaddr2++ = c;
memctl->memc_lsdmr = lsdmr | PSDMR_OP_NORM | PSDMR_RFEN;
*ramaddr2 = c;
#endif
/* return total ram size */
return ((CFG_SDRAM0_SIZE + CFG_SDRAM1_SIZE) * 1024 * 1024);
}
#ifdef CONFIG_MISC_INIT_R
/* ------------------------------------------------------------------------- */
int misc_init_r (void)
{
#ifdef CFG_LED_BASE
uchar ds = *(unsigned char *) (CFG_LED_BASE + 1);
uchar ss;
uchar tmp[64];
int res;
if ((ds != 0) && (ds != 0xff)) {
res = getenv_r ("ethaddr", tmp, sizeof (tmp));
if (res > 0) {
ss = ((ds >> 4) & 0x0f);
ss += ss < 0x0a ? '0' : ('a' - 10);
tmp[15] = ss;
ss = (ds & 0x0f);
ss += ss < 0x0a ? '0' : ('a' - 10);
tmp[16] = ss;
tmp[17] = '\0';
setenv ("ethaddr", tmp);
/* set the led to show the address */
*((unsigned char *) (CFG_LED_BASE + 1)) = ds;
}
}
#endif /* CFG_LED_BASE */
return (0);
}
#endif /* CONFIG_MISC_INIT_R */

View File

@ -0,0 +1,755 @@
/*
* (C) Copyright 2002
* Brad Kemp, Seranoa Networks, Brad.Kemp@seranoa.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 <mpc8260.h>
#include <asm/processor.h>
#undef DEBUG_FLASH
/*
* This file implements a Common Flash Interface (CFI) driver for U-Boot.
* The width of the port and the width of the chips are determined at initialization.
* These widths are used to calculate the address for access CFI data structures.
* It has been tested on an Intel Strataflash implementation.
*
* References
* JEDEC Standard JESD68 - Common Flash Interface (CFI)
* JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes
* Intel Application Note 646 Common Flash Interface (CFI) and Command Sets
* Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet
*
* TODO
* Use Primary Extended Query table (PRI) and Alternate Algorithm Query Table (ALT) to determine if protection is available
* Add support for other command sets Use the PRI and ALT to determine command set
* Verify erase and program timeouts.
*/
#define FLASH_CMD_CFI 0x98
#define FLASH_CMD_READ_ID 0x90
#define FLASH_CMD_RESET 0xff
#define FLASH_CMD_BLOCK_ERASE 0x20
#define FLASH_CMD_ERASE_CONFIRM 0xD0
#define FLASH_CMD_WRITE 0x40
#define FLASH_CMD_PROTECT 0x60
#define FLASH_CMD_PROTECT_SET 0x01
#define FLASH_CMD_PROTECT_CLEAR 0xD0
#define FLASH_CMD_CLEAR_STATUS 0x50
#define FLASH_CMD_WRITE_TO_BUFFER 0xE8
#define FLASH_CMD_WRITE_BUFFER_CONFIRM 0xD0
#define FLASH_STATUS_DONE 0x80
#define FLASH_STATUS_ESS 0x40
#define FLASH_STATUS_ECLBS 0x20
#define FLASH_STATUS_PSLBS 0x10
#define FLASH_STATUS_VPENS 0x08
#define FLASH_STATUS_PSS 0x04
#define FLASH_STATUS_DPS 0x02
#define FLASH_STATUS_R 0x01
#define FLASH_STATUS_PROTECT 0x01
#define FLASH_OFFSET_CFI 0x55
#define FLASH_OFFSET_CFI_RESP 0x10
#define FLASH_OFFSET_WTOUT 0x1F
#define FLASH_OFFSET_WBTOUT 0x20
#define FLASH_OFFSET_ETOUT 0x21
#define FLASH_OFFSET_CETOUT 0x22
#define FLASH_OFFSET_WMAX_TOUT 0x23
#define FLASH_OFFSET_WBMAX_TOUT 0x24
#define FLASH_OFFSET_EMAX_TOUT 0x25
#define FLASH_OFFSET_CEMAX_TOUT 0x26
#define FLASH_OFFSET_SIZE 0x27
#define FLASH_OFFSET_INTERFACE 0x28
#define FLASH_OFFSET_BUFFER_SIZE 0x2A
#define FLASH_OFFSET_NUM_ERASE_REGIONS 0x2C
#define FLASH_OFFSET_ERASE_REGIONS 0x2D
#define FLASH_OFFSET_PROTECT 0x02
#define FLASH_OFFSET_USER_PROTECTION 0x85
#define FLASH_OFFSET_INTEL_PROTECTION 0x81
#define FLASH_MAN_CFI 0x01000000
typedef union {
unsigned char c;
unsigned short w;
unsigned long l;
} cfiword_t;
typedef union {
unsigned char * cp;
unsigned short *wp;
unsigned long *lp;
} cfiptr_t;
#define NUM_ERASE_REGIONS 4
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/*-----------------------------------------------------------------------
* Functions
*/
static void flash_add_byte(flash_info_t *info, cfiword_t * cword, uchar c);
static void flash_make_cmd(flash_info_t * info, uchar cmd, void * cmdbuf);
static void flash_write_cmd(flash_info_t * info, int sect, uchar offset, uchar cmd);
static int flash_isequal(flash_info_t * info, int sect, uchar offset, uchar cmd);
static int flash_isset(flash_info_t * info, int sect, uchar offset, uchar cmd);
static int flash_detect_cfi(flash_info_t * info);
static ulong flash_get_size (ulong base, int banknum);
static int flash_write_cfiword (flash_info_t *info, ulong dest, cfiword_t cword);
static int flash_full_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt);
#ifdef CFG_FLASH_USE_BUFFER_WRITE
static int flash_write_cfibuffer(flash_info_t * info, ulong dest, uchar * cp, int len);
#endif
/*-----------------------------------------------------------------------
* create an address based on the offset and the port width
*/
inline uchar * flash_make_addr(flash_info_t * info, int sect, int offset)
{
return ((uchar *)(info->start[sect] + (offset * info->portwidth)));
}
/*-----------------------------------------------------------------------
* read a character at a port width address
*/
inline uchar flash_read_uchar(flash_info_t * info, uchar offset)
{
uchar *cp;
cp = flash_make_addr(info, 0, offset);
return (cp[info->portwidth - 1]);
}
/*-----------------------------------------------------------------------
* read a short word by swapping for ppc format.
*/
ushort flash_read_ushort(flash_info_t * info, int sect, uchar offset)
{
uchar * addr;
addr = flash_make_addr(info, sect, offset);
return ((addr[(2*info->portwidth) - 1] << 8) | addr[info->portwidth - 1]);
}
/*-----------------------------------------------------------------------
* read a long word by picking the least significant byte of each maiximum
* port size word. Swap for ppc format.
*/
ulong flash_read_long(flash_info_t * info, int sect, uchar offset)
{
uchar * addr;
addr = flash_make_addr(info, sect, offset);
return ( (addr[(2*info->portwidth) - 1] << 24 ) | (addr[(info->portwidth) -1] << 16) |
(addr[(4*info->portwidth) - 1] << 8) | addr[(3*info->portwidth) - 1]);
}
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
unsigned long size;
int i;
unsigned long address;
/* The flash is positioned back to back, with the demultiplexing of the chip
* based on the A24 address line.
*
*/
address = CFG_FLASH_BASE;
size = 0;
/* Init: no FLASHes known */
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
size += flash_info[i].size = flash_get_size(address, i);
address += CFG_FLASH_INCREMENT;
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",i,
flash_info[0].size, flash_info[i].size<<20);
}
}
/* Monitor protection ON by default */
#if (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
for(i=0; flash_info[0].start[i] < CFG_MONITOR_BASE+CFG_MONITOR_LEN-1; i++)
(void)flash_real_protect(&flash_info[0], i, 1);
#endif
return (size);
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
int rcode = 0;
int prot;
int sect;
if( info->flash_id != FLASH_MAN_CFI) {
printf ("Can't erase unknown flash type - aborted\n");
return 1;
}
if ((s_first < 0) || (s_first > s_last)) {
printf ("- no sectors to erase\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");
}
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
flash_write_cmd(info, sect, 0, FLASH_CMD_CLEAR_STATUS);
flash_write_cmd(info, sect, 0, FLASH_CMD_BLOCK_ERASE);
flash_write_cmd(info, sect, 0, FLASH_CMD_ERASE_CONFIRM);
if(flash_full_status_check(info, sect, info->erase_blk_tout, "erase")) {
rcode = 1;
} else
printf(".");
}
}
printf (" done\n");
return rcode;
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
{
int i;
if (info->flash_id != FLASH_MAN_CFI) {
printf ("missing or unknown FLASH type\n");
return;
}
printf("CFI conformant FLASH (%d x %d)",
(info->portwidth << 3 ), (info->chipwidth << 3 ));
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf(" Erase timeout %ld ms, write timeout %ld ms, buffer write timeout %ld ms, buffer size %d\n",
info->erase_blk_tout, info->write_tout, info->buffer_write_tout, info->buffer_size);
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n");
printf (" %08lX%5s",
info->start[i],
info->protect[i] ? " (RO)" : " "
);
}
printf ("\n");
return;
}
/*-----------------------------------------------------------------------
* 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 wp;
ulong cp;
int aln;
cfiword_t cword;
int i, rc;
/* get lower aligned address */
wp = (addr & ~(info->portwidth - 1));
/* handle unaligned start */
if((aln = addr - wp) != 0) {
cword.l = 0;
cp = wp;
for(i=0;i<aln; ++i, ++cp)
flash_add_byte(info, &cword, (*(uchar *)cp));
for(; (i< info->portwidth) && (cnt > 0) ; i++) {
flash_add_byte(info, &cword, *src++);
cnt--;
cp++;
}
for(; (cnt == 0) && (i < info->portwidth); ++i, ++cp)
flash_add_byte(info, &cword, (*(uchar *)cp));
if((rc = flash_write_cfiword(info, wp, cword)) != 0)
return rc;
wp = cp;
}
#ifdef CFG_FLASH_USE_BUFFER_WRITE
while(cnt >= info->portwidth) {
i = info->buffer_size > cnt? cnt: info->buffer_size;
if((rc = flash_write_cfibuffer(info, wp, src,i)) != ERR_OK)
return rc;
wp += i;
src += i;
cnt -=i;
}
#else
/* handle the aligned part */
while(cnt >= info->portwidth) {
cword.l = 0;
for(i = 0; i < info->portwidth; i++) {
flash_add_byte(info, &cword, *src++);
}
if((rc = flash_write_cfiword(info, wp, cword)) != 0)
return rc;
wp += info->portwidth;
cnt -= info->portwidth;
}
#endif /* CFG_FLASH_USE_BUFFER_WRITE */
if (cnt == 0) {
return (0);
}
/*
* handle unaligned tail bytes
*/
cword.l = 0;
for (i=0, cp=wp; (i<info->portwidth) && (cnt>0); ++i, ++cp) {
flash_add_byte(info, &cword, *src++);
--cnt;
}
for (; i<info->portwidth; ++i, ++cp) {
flash_add_byte(info, & cword, (*(uchar *)cp));
}
return flash_write_cfiword(info, wp, cword);
}
/*-----------------------------------------------------------------------
*/
int flash_real_protect(flash_info_t *info, long sector, int prot)
{
int retcode = 0;
flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT);
if(prot)
flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_SET);
else
flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_CLEAR);
if((retcode = flash_full_status_check(info, sector, info->erase_blk_tout,
prot?"protect":"unprotect")) == 0) {
info->protect[sector] = prot;
/* Intel's unprotect unprotects all locking */
if(prot == 0) {
int i;
for(i = 0 ; i<info->sector_count; i++) {
if(info->protect[i])
flash_real_protect(info, i, 1);
}
}
}
return retcode;
}
/*-----------------------------------------------------------------------
* wait for XSR.7 to be set. Time out with an error if it does not.
* This routine does not set the flash to read-array mode.
*/
static int flash_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt)
{
ulong start;
/* Wait for command completion */
start = get_timer (0);
while(!flash_isset(info, sector, 0, FLASH_STATUS_DONE)) {
if (get_timer(start) > info->erase_blk_tout) {
printf("Flash %s timeout at address %lx\n", prompt, info->start[sector]);
flash_write_cmd(info, sector, 0, FLASH_CMD_RESET);
return ERR_TIMOUT;
}
}
return ERR_OK;
}
/*-----------------------------------------------------------------------
* Wait for XSR.7 to be set, if it times out print an error, otherwise do a full status check.
* This routine sets the flash to read-array mode.
*/
static int flash_full_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt)
{
int retcode;
retcode = flash_status_check(info, sector, tout, prompt);
if((retcode == ERR_OK) && !flash_isequal(info,sector, 0, FLASH_STATUS_DONE)) {
retcode = ERR_INVAL;
printf("Flash %s error at address %lx\n", prompt,info->start[sector]);
if(flash_isset(info, sector, 0, FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)){
printf("Command Sequence Error.\n");
} else if(flash_isset(info, sector, 0, FLASH_STATUS_ECLBS)){
printf("Block Erase Error.\n");
retcode = ERR_NOT_ERASED;
} else if (flash_isset(info, sector, 0, FLASH_STATUS_PSLBS)) {
printf("Locking Error\n");
}
if(flash_isset(info, sector, 0, FLASH_STATUS_DPS)){
printf("Block locked.\n");
retcode = ERR_PROTECTED;
}
if(flash_isset(info, sector, 0, FLASH_STATUS_VPENS))
printf("Vpp Low Error.\n");
}
flash_write_cmd(info, sector, 0, FLASH_CMD_RESET);
return retcode;
}
/*-----------------------------------------------------------------------
*/
static void flash_add_byte(flash_info_t *info, cfiword_t * cword, uchar c)
{
switch(info->portwidth) {
case FLASH_CFI_8BIT:
cword->c = c;
break;
case FLASH_CFI_16BIT:
cword->w = (cword->w << 8) | c;
break;
case FLASH_CFI_32BIT:
cword->l = (cword->l << 8) | c;
}
}
/*-----------------------------------------------------------------------
* make a proper sized command based on the port and chip widths
*/
static void flash_make_cmd(flash_info_t * info, uchar cmd, void * cmdbuf)
{
int i;
uchar *cp = (uchar *)cmdbuf;
for(i=0; i< info->portwidth; i++)
*cp++ = ((i+1) % info->chipwidth) ? '\0':cmd;
}
/*
* Write a proper sized command to the correct address
*/
static void flash_write_cmd(flash_info_t * info, int sect, uchar offset, uchar cmd)
{
volatile cfiptr_t addr;
cfiword_t cword;
addr.cp = flash_make_addr(info, sect, offset);
flash_make_cmd(info, cmd, &cword);
switch(info->portwidth) {
case FLASH_CFI_8BIT:
*addr.cp = cword.c;
break;
case FLASH_CFI_16BIT:
*addr.wp = cword.w;
break;
case FLASH_CFI_32BIT:
*addr.lp = cword.l;
break;
}
}
/*-----------------------------------------------------------------------
*/
static int flash_isequal(flash_info_t * info, int sect, uchar offset, uchar cmd)
{
cfiptr_t cptr;
cfiword_t cword;
int retval;
cptr.cp = flash_make_addr(info, sect, offset);
flash_make_cmd(info, cmd, &cword);
switch(info->portwidth) {
case FLASH_CFI_8BIT:
retval = (cptr.cp[0] == cword.c);
break;
case FLASH_CFI_16BIT:
retval = (cptr.wp[0] == cword.w);
break;
case FLASH_CFI_32BIT:
retval = (cptr.lp[0] == cword.l);
break;
default:
retval = 0;
break;
}
return retval;
}
/*-----------------------------------------------------------------------
*/
static int flash_isset(flash_info_t * info, int sect, uchar offset, uchar cmd)
{
cfiptr_t cptr;
cfiword_t cword;
int retval;
cptr.cp = flash_make_addr(info, sect, offset);
flash_make_cmd(info, cmd, &cword);
switch(info->portwidth) {
case FLASH_CFI_8BIT:
retval = ((cptr.cp[0] & cword.c) == cword.c);
break;
case FLASH_CFI_16BIT:
retval = ((cptr.wp[0] & cword.w) == cword.w);
break;
case FLASH_CFI_32BIT:
retval = ((cptr.lp[0] & cword.l) == cword.l);
break;
default:
retval = 0;
break;
}
return retval;
}
/*-----------------------------------------------------------------------
* detect if flash is compatible with the Common Flash Interface (CFI)
* http://www.jedec.org/download/search/jesd68.pdf
*
*/
static int flash_detect_cfi(flash_info_t * info)
{
for(info->portwidth=FLASH_CFI_8BIT; info->portwidth <= FLASH_CFI_32BIT;
info->portwidth <<= 1) {
for(info->chipwidth =FLASH_CFI_BY8;
info->chipwidth <= info->portwidth;
info->chipwidth <<= 1) {
flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
flash_write_cmd(info, 0, FLASH_OFFSET_CFI, FLASH_CMD_CFI);
if(flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP,'Q') &&
flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R') &&
flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y'))
return 1;
}
}
return 0;
}
/*
* The following code cannot be run from FLASH!
*
*/
static ulong flash_get_size (ulong base, int banknum)
{
flash_info_t * info = &flash_info[banknum];
int i, j;
int sect_cnt;
unsigned long sector;
unsigned long tmp;
int size_ratio;
uchar num_erase_regions;
int erase_region_size;
int erase_region_count;
info->start[0] = base;
if(flash_detect_cfi(info)){
size_ratio = info->portwidth / info->chipwidth;
num_erase_regions = flash_read_uchar(info, FLASH_OFFSET_NUM_ERASE_REGIONS);
#ifdef DEBUG_FLASH
printf("found %d erase regions\n", num_erase_regions);
#endif
sect_cnt = 0;
sector = base;
for(i = 0 ; i < num_erase_regions; i++) {
if(i > NUM_ERASE_REGIONS) {
printf("%d erase regions found, only %d used\n",
num_erase_regions, NUM_ERASE_REGIONS);
break;
}
tmp = flash_read_long(info, 0, FLASH_OFFSET_ERASE_REGIONS);
erase_region_size = (tmp & 0xffff)? ((tmp & 0xffff) * 256): 128;
tmp >>= 16;
erase_region_count = (tmp & 0xffff) +1;
for(j = 0; j< erase_region_count; j++) {
info->start[sect_cnt] = sector;
sector += (erase_region_size * size_ratio);
info->protect[sect_cnt] = flash_isset(info, sect_cnt, FLASH_OFFSET_PROTECT, FLASH_STATUS_PROTECT);
sect_cnt++;
}
}
info->sector_count = sect_cnt;
/* multiply the size by the number of chips */
info->size = (1 << flash_read_uchar(info, FLASH_OFFSET_SIZE)) * size_ratio;
info->buffer_size = (1 << flash_read_ushort(info, 0, FLASH_OFFSET_BUFFER_SIZE));
tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_ETOUT);
info->erase_blk_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_EMAX_TOUT)));
tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WBTOUT);
info->buffer_write_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_WBMAX_TOUT)));
tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WTOUT);
info->write_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_WMAX_TOUT)))/ 1000;
info->flash_id = FLASH_MAN_CFI;
}
flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
return(info->size);
}
/*-----------------------------------------------------------------------
*/
static int flash_write_cfiword (flash_info_t *info, ulong dest, cfiword_t cword)
{
cfiptr_t ctladdr;
cfiptr_t cptr;
int flag;
ctladdr.cp = flash_make_addr(info, 0, 0);
cptr.cp = (uchar *)dest;
/* Check if Flash is (sufficiently) erased */
switch(info->portwidth) {
case FLASH_CFI_8BIT:
flag = ((cptr.cp[0] & cword.c) == cword.c);
break;
case FLASH_CFI_16BIT:
flag = ((cptr.wp[0] & cword.w) == cword.w);
break;
case FLASH_CFI_32BIT:
flag = ((cptr.lp[0] & cword.l) == cword.l);
break;
default:
return 2;
}
if(!flag)
return 2;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
flash_write_cmd(info, 0, 0, FLASH_CMD_CLEAR_STATUS);
flash_write_cmd(info, 0, 0, FLASH_CMD_WRITE);
switch(info->portwidth) {
case FLASH_CFI_8BIT:
cptr.cp[0] = cword.c;
break;
case FLASH_CFI_16BIT:
cptr.wp[0] = cword.w;
break;
case FLASH_CFI_32BIT:
cptr.lp[0] = cword.l;
break;
}
/* re-enable interrupts if necessary */
if(flag)
enable_interrupts();
return flash_full_status_check(info, 0, info->write_tout, "write");
}
#ifdef CFG_FLASH_USE_BUFFER_WRITE
/* loop through the sectors from the highest address
* when the passed address is greater or equal to the sector address
* we have a match
*/
static int find_sector(flash_info_t *info, ulong addr)
{
int sector;
for(sector = info->sector_count - 1; sector >= 0; sector--) {
if(addr >= info->start[sector])
break;
}
return sector;
}
static int flash_write_cfibuffer(flash_info_t * info, ulong dest, uchar * cp, int len)
{
int sector;
int cnt;
int retcode;
volatile cfiptr_t src;
volatile cfiptr_t dst;
src.cp = cp;
dst.cp = (uchar *)dest;
sector = find_sector(info, dest);
flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
flash_write_cmd(info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER);
if((retcode = flash_status_check(info, sector, info->buffer_write_tout,
"write to buffer")) == ERR_OK) {
switch(info->portwidth) {
case FLASH_CFI_8BIT:
cnt = len;
break;
case FLASH_CFI_16BIT:
cnt = len >> 1;
break;
case FLASH_CFI_32BIT:
cnt = len >> 2;
break;
default:
return ERR_INVAL;
break;
}
flash_write_cmd(info, sector, 0, (uchar)cnt-1);
while(cnt-- > 0) {
switch(info->portwidth) {
case FLASH_CFI_8BIT:
*dst.cp++ = *src.cp++;
break;
case FLASH_CFI_16BIT:
*dst.wp++ = *src.wp++;
break;
case FLASH_CFI_32BIT:
*dst.lp++ = *src.lp++;
break;
default:
return ERR_INVAL;
break;
}
}
flash_write_cmd(info, sector, 0, FLASH_CMD_WRITE_BUFFER_CONFIRM);
retcode = flash_full_status_check(info, sector, info->buffer_write_tout,
"buffer write");
}
flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
return retcode;
}
#endif /* CFG_USE_FLASH_BUFFER_WRITE */

305
board/rpxsuper/rpxsuper.c Normal file
View File

@ -0,0 +1,305 @@
/*
* (C) Copyright 2000
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright 2001
* Advent Networks, Inc. <http://www.adventnetworks.com>
* Jay Monkman <jtm@smoothsmoothie.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 <ioports.h>
#include <mpc8260.h>
#include "rpxsuper.h"
/*
* I/O Port configuration table
*
* if conf is 1, then that port pin will be configured at boot time
* according to the five values podr/pdir/ppar/psor/pdat for that entry
*/
const iop_conf_t iop_conf_tab[4][32] = {
/* Port A configuration */
{ /* conf ppar psor pdir podr pdat */
/* PA31 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 *ATMTXEN */
/* PA30 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTCA */
/* PA29 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTSOC */
/* PA28 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 *ATMRXEN */
/* PA27 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRSOC */
/* PA26 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRCA */
/* PA25 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[0] */
/* PA24 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[1] */
/* PA23 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[2] */
/* PA22 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[3] */
/* PA21 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[4] */
/* PA20 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[5] */
/* PA19 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[6] */
/* PA18 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[7] */
/* PA17 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[7] */
/* PA16 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[6] */
/* PA15 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[5] */
/* PA14 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[4] */
/* PA13 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[3] */
/* PA12 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[2] */
/* PA11 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[1] */
/* PA10 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[0] */
/* PA9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC2 TXD */
/* PA8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC2 RXD */
/* PA7 */ { 1, 0, 0, 0, 0, 0 }, /* PA7 */
/* PA6 */ { 1, 0, 0, 0, 0, 0 }, /* PA6 */
/* PA5 */ { 1, 0, 0, 0, 0, 0 }, /* PA5 */
/* PA4 */ { 1, 0, 0, 0, 0, 0 }, /* PA4 */
/* PA3 */ { 1, 0, 0, 0, 0, 0 }, /* PA3 */
/* PA2 */ { 1, 0, 0, 0, 0, 0 }, /* PA2 */
/* PA1 */ { 1, 0, 0, 0, 0, 0 }, /* PA1 */
/* PA0 */ { 1, 0, 0, 0, 0, 0 } /* PA0 */
},
/* Port B configuration */
{ /* conf ppar psor pdir podr pdat */
/* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TX_ER */
/* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */
/* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */
/* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */
/* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */
/* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */
/* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */
/* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */
/* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */
/* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */
/* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */
/* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */
/* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */
/* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */
/* PB17 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RX_DV */
/* PB16 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RX_ER */
/* PB15 */ { 1, 1, 0, 1, 0, 0 }, /* FCC3 MII TX_ER */
/* PB14 */ { 1, 1, 0, 1, 0, 0 }, /* FCC3 MII TX_EN */
/* PB13 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII COL */
/* PB12 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII CRS */
/* PB11 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RxD[3] */
/* PB10 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RxD[2] */
/* PB9 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RxD[1] */
/* PB8 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RxD[0] */
/* PB7 */ { 0, 0, 0, 0, 0, 0 }, /* PB7 */
/* PB6 */ { 1, 1, 0, 1, 0, 0 }, /* FCC3 MII TxD[1] */
/* PB5 */ { 1, 1, 0, 1, 0, 0 }, /* FCC3 MII TxD[2] */
/* PB4 */ { 1, 1, 0, 1, 0, 0 }, /* FCC3 MII TxD[3] */
/* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
},
/* Port C */
{ /* conf ppar psor pdir podr pdat */
/* PC31 */ { 1, 0, 0, 1, 0, 0 }, /* PC31 */
/* PC30 */ { 1, 0, 0, 1, 0, 0 }, /* PC30 */
/* PC29 */ { 1, 1, 1, 0, 0, 0 }, /* SCC1 EN *CLSN */
/* PC28 */ { 1, 0, 0, 1, 0, 0 }, /* PC28 */
/* PC27 */ { 1, 1, 0, 1, 0, 0 }, /* FCC3 MII TxD[0] */
/* PC26 */ { 1, 0, 0, 1, 0, 0 }, /* PC26 */
/* PC25 */ { 1, 0, 0, 1, 0, 0 }, /* PC25 */
/* PC24 */ { 1, 0, 0, 1, 0, 0 }, /* PC24 */
/* PC23 */ { 1, 1, 0, 1, 0, 0 }, /* ATMTFCLK */
/* PC22 */ { 1, 1, 0, 0, 0, 0 }, /* ATMRFCLK */
/* PC21 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN RXCLK */
/* PC20 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN TXCLK */
/* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_CLK */
/* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII TX_CLK */
/* PC17 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RX_CLK */
/* PC16 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII TX_CLK */
/* PC15 */ { 1, 0, 0, 0, 0, 0 }, /* PC15 */
/* PC14 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN *CD */
/* PC13 */ { 1, 0, 0, 1, 0, 0 }, /* PC13 */
/* PC12 */ { 1, 0, 0, 1, 0, 0 }, /* PC12 */
/* PC11 */ { 1, 0, 0, 1, 0, 0 }, /* PC11 */
/* PC10 */ { 1, 0, 0, 1, 0, 0 }, /* FCC2 MDC */
/* PC9 */ { 1, 0, 0, 1, 0, 0 }, /* FCC2 MDIO */
/* PC8 */ { 1, 0, 0, 1, 0, 0 }, /* PC8 */
/* PC7 */ { 1, 0, 0, 1, 0, 0 }, /* PC7 */
/* PC6 */ { 1, 0, 0, 1, 0, 0 }, /* PC6 */
/* PC5 */ { 1, 0, 0, 1, 0, 0 }, /* PC5 */
/* PC4 */ { 1, 0, 0, 1, 0, 0 }, /* PC4 */
/* PC3 */ { 1, 0, 0, 1, 0, 0 }, /* PC3 */
/* PC2 */ { 1, 0, 0, 1, 0, 1 }, /* ENET FDE */
/* PC1 */ { 1, 0, 0, 1, 0, 0 }, /* ENET DSQE */
/* PC0 */ { 1, 0, 0, 1, 0, 0 }, /* ENET LBK */
},
/* Port D */
{ /* conf ppar psor pdir podr pdat */
/* PD31 */ { 1, 0, 0, 0, 0, 0 }, /* SCC1 EN RxD */
/* PD30 */ { 1, 0, 0, 0, 0, 0 }, /* SCC1 EN TxD */
/* PD29 */ { 1, 0, 0, 0, 0, 0 }, /* SCC1 EN TENA */
/* PD28 */ { 1, 0, 0, 0, 0, 0 }, /* PD28 */
/* PD27 */ { 1, 0, 0, 0, 0, 0 }, /* PD27 */
/* PD26 */ { 1, 0, 0, 0, 0, 0 }, /* PD26 */
/* PD25 */ { 1, 0, 0, 0, 0, 0 }, /* PD25 */
/* PD24 */ { 1, 0, 0, 0, 0, 0 }, /* PD24 */
/* PD23 */ { 1, 0, 0, 0, 0, 0 }, /* PD23 */
/* PD22 */ { 1, 0, 0, 0, 0, 0 }, /* PD22 */
/* PD21 */ { 1, 0, 0, 0, 0, 0 }, /* PD21 */
/* PD20 */ { 1, 0, 0, 0, 0, 0 }, /* PD20 */
/* PD19 */ { 1, 0, 0, 0, 0, 0 }, /* PD19 */
/* PD18 */ { 1, 0, 0, 0, 0, 0 }, /* PD19 */
/* PD17 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */
/* PD16 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXPRTY */
/* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */
/* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */
/* PD13 */ { 1, 0, 0, 0, 0, 0 }, /* PD13 */
/* PD12 */ { 1, 0, 0, 0, 0, 0 }, /* PD12 */
/* PD11 */ { 1, 0, 0, 0, 0, 0 }, /* PD11 */
/* PD10 */ { 1, 0, 0, 0, 0, 0 }, /* PD10 */
/* PD9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC1 TXD */
/* PD8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC1 RXD */
/* PD7 */ { 1, 0, 0, 0, 0, 0 }, /* PD7 */
/* PD6 */ { 1, 0, 0, 0, 0, 0 }, /* PD6 */
/* PD5 */ { 1, 0, 0, 0, 0, 0 }, /* PD5 */
/* PD4 */ { 1, 0, 0, 0, 0, 0 }, /* PD4 */
/* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
}
};
/* ------------------------------------------------------------------------- */
/*
* Setup CS4 to enable the Board Control/Status registers.
* Otherwise the smcs won't work.
*/
int board_pre_init (void)
{
volatile t_rpx_regs *regs = (t_rpx_regs*)CFG_REGS_BASE;
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile memctl8260_t *memctl = &immap->im_memctl;
memctl->memc_br4 = CFG_BR4_PRELIM;
memctl->memc_or4 = CFG_OR4_PRELIM;
regs->bcsr1 = 0x70; /* to enable terminal no SMC1 */
regs->bcsr2 = 0x20; /* mut be written to enable writing FLASH */
return 0;
}
void
reset_phy(void)
{
volatile t_rpx_regs *regs = (t_rpx_regs*)CFG_REGS_BASE;
regs->bcsr4 = 0xC3;
}
/*
* Check Board Identity:
*/
int checkboard(void)
{
volatile t_rpx_regs *regs = (t_rpx_regs*)CFG_REGS_BASE;
printf ("Board: Embedded Planet RPX Super, Revision %d\n",
regs->bcsr0 >> 4);
return 0;
}
/* ------------------------------------------------------------------------- */
long int initdram(int board_type)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile memctl8260_t *memctl = &immap->im_memctl;
volatile uchar c = 0, *ramaddr;
ulong psdmr, lsdmr, bcr;
long size = 0;
int i;
psdmr = CFG_PSDMR;
lsdmr = CFG_LSDMR;
/*
* Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
*
* "At system reset, initialization software must set up the
* programmable parameters in the memory controller banks registers
* (ORx, BRx, P/LSDMR). After all memory parameters are configured,
* system software should execute the following initialization sequence
* for each SDRAM device.
*
* 1. Issue a PRECHARGE-ALL-BANKS command
* 2. Issue eight CBR REFRESH commands
* 3. Issue a MODE-SET command to initialize the mode register
*
* The initial commands are executed by setting P/LSDMR[OP] and
* accessing the SDRAM with a single-byte transaction."
*
* The appropriate BRx/ORx registers have already been set when we
* get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE.
*/
size = CFG_SDRAM0_SIZE;
bcr = immap->im_siu_conf.sc_bcr;
immap->im_siu_conf.sc_bcr = (bcr & ~BCR_EBM);
memctl->memc_mptpr = CFG_MPTPR;
ramaddr = (uchar *)(CFG_SDRAM0_BASE);
memctl->memc_psrt = CFG_PSRT;
memctl->memc_psdmr = psdmr | PSDMR_OP_PREA;
*ramaddr = c;
memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR;
for (i = 0; i < 8; i++)
*ramaddr = c;
memctl->memc_psdmr = psdmr | PSDMR_OP_MRW;
*ramaddr = c;
memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN;
*ramaddr = c;
immap->im_siu_conf.sc_bcr = bcr;
#ifndef CFG_RAMBOOT
/* size += CFG_SDRAM1_SIZE; */
ramaddr = (uchar *)(CFG_SDRAM1_BASE);
memctl->memc_lsrt = CFG_LSRT;
memctl->memc_lsdmr = lsdmr | PSDMR_OP_PREA;
*ramaddr = c;
memctl->memc_lsdmr = lsdmr | PSDMR_OP_CBRR;
for (i = 0; i < 8; i++)
*ramaddr = c;
memctl->memc_lsdmr = lsdmr | PSDMR_OP_MRW;
*ramaddr = c;
memctl->memc_lsdmr = lsdmr | PSDMR_OP_NORM | PSDMR_RFEN;
*ramaddr = c;
#endif
/* return total ram size */
return (size * 1024 * 1024);
}

33
board/rsdproto/config.mk Normal file
View File

@ -0,0 +1,33 @@
#
# (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 = 0xff000000
/*TEXT_BASE = 0x00200000 */

378
board/rsdproto/rsdproto.c Normal file
View File

@ -0,0 +1,378 @@
/*
* (C) Copyright 2000
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <ioports.h>
#include <mpc8260.h>
#include <i2c.h>
/* define to initialise the SDRAM on the local bus */
#undef INIT_LOCAL_BUS_SDRAM
/* I2C Bus adresses for PPC & Protocol board */
#define PPC8260_I2C_ADR 0x30 /*(0)011.0000 */
#define LM84_PPC_I2C_ADR 0x2A /*(0)010.1010 */
#define LM84_SHARC_I2C_ADR 0x29 /*(0)010.1001 */
#define VIRTEX_I2C_ADR 0x25 /*(0)010.0101 */
#define X24645_PPC_I2C_ADR 0x00 /*(0)00X.XXXX -> be careful ! No other i2c-chip should have an adress beginning with (0)00 !!! */
#define RS5C372_PPC_I2C_ADR 0x32 /*(0)011.0010 -> this adress is programmed by the manufacturer and cannot be changed !!! */
/*
* I/O Port configuration table
*
* if conf is 1, then that port pin will be configured at boot time
* according to the five values podr/pdir/ppar/psor/pdat for that entry
*/
const iop_conf_t iop_conf_tab[4][32] = {
/* Port A configuration */
{ /* conf ppar psor pdir podr pdat */
/* PA31 */ { 0, 0, 0, 0, 0, 0 },
/* PA30 */ { 0, 0, 0, 0, 0, 0 },
/* PA29 */ { 0, 0, 0, 0, 0, 0 },
/* PA28 */ { 0, 0, 0, 0, 0, 0 },
/* PA27 */ { 0, 0, 0, 0, 0, 0 },
/* PA26 */ { 0, 0, 0, 0, 0, 0 },
/* PA25 */ { 0, 0, 0, 0, 0, 0 },
/* PA24 */ { 0, 0, 0, 0, 0, 0 },
/* PA23 */ { 0, 0, 0, 0, 0, 0 },
/* PA22 */ { 0, 0, 0, 0, 0, 0 },
/* PA21 */ { 0, 0, 0, 0, 0, 0 },
/* PA20 */ { 0, 0, 0, 0, 0, 0 },
/* PA19 */ { 0, 0, 0, 0, 0, 0 },
/* PA18 */ { 0, 0, 0, 0, 0, 0 },
/* PA17 */ { 0, 0, 0, 0, 0, 0 },
/* PA16 */ { 0, 0, 0, 0, 0, 0 },
/* PA15 */ { 0, 0, 0, 0, 0, 0 },
/* PA14 */ { 0, 0, 0, 0, 0, 0 },
/* PA13 */ { 0, 0, 0, 0, 0, 0 },
/* PA12 */ { 0, 0, 0, 0, 0, 0 },
/* PA11 */ { 0, 0, 0, 0, 0, 0 },
/* PA10 */ { 0, 0, 0, 0, 0, 0 },
/* PA9 */ { 0, 0, 0, 0, 0, 0 },
/* PA8 */ { 0, 0, 0, 0, 0, 0 },
/* PA7 */ { 0, 0, 0, 0, 0, 0 },
/* PA6 */ { 0, 0, 0, 0, 0, 0 },
/* PA5 */ { 0, 0, 0, 0, 0, 0 },
/* PA4 */ { 0, 0, 0, 0, 0, 0 },
/* PA3 */ { 0, 0, 0, 0, 0, 0 },
/* PA2 */ { 0, 0, 0, 0, 0, 0 },
/* PA1 */ { 0, 0, 0, 0, 0, 0 },
/* PA0 */ { 0, 0, 0, 0, 0, 0 }
},
{ /* conf ppar psor pdir podr pdat */
/* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TX_ER */
/* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */
/* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */
/* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */
/* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */
/* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */
/* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */
/* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */
/* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */
/* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */
/* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */
/* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */
/* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */
/* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */
/* PB17 */ { 0, 0, 0, 0, 0, 0 },
/* PB16 */ { 0, 0, 0, 0, 0, 0 },
/* PB15 */ { 0, 0, 0, 0, 0, 0 },
/* PB14 */ { 0, 0, 0, 0, 0, 0 },
/* PB13 */ { 0, 0, 0, 0, 0, 0 },
/* PB12 */ { 0, 0, 0, 0, 0, 0 },
/* PB11 */ { 0, 0, 0, 0, 0, 0 },
/* PB10 */ { 0, 0, 0, 0, 0, 0 },
/* PB9 */ { 0, 0, 0, 0, 0, 0 },
/* PB8 */ { 0, 0, 0, 0, 0, 0 },
/* PB7 */ { 0, 0, 0, 0, 0, 0 },
/* PB6 */ { 0, 0, 0, 0, 0, 0 },
/* PB5 */ { 0, 0, 0, 0, 0, 0 },
/* PB4 */ { 0, 0, 0, 0, 0, 0 },
/* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
},
{ /* conf ppar psor pdir podr pdat */
/* PC31 */ { 0, 0, 0, 0, 0, 0 },
/* PC30 */ { 0, 0, 0, 0, 0, 0 },
/* PC29 */ { 0, 0, 0, 0, 0, 0 },
/* PC28 */ { 0, 0, 0, 0, 0, 0 },
/* PC27 */ { 0, 0, 0, 0, 0, 0 },
/* PC26 */ { 0, 0, 0, 0, 0, 0 },
/* PC25 */ { 0, 0, 0, 0, 0, 0 },
/* PC24 */ { 0, 0, 0, 0, 0, 0 },
/* PC23 */ { 0, 0, 0, 0, 0, 0 },
/* PC22 */ { 0, 0, 0, 0, 0, 0 },
/* PC21 */ { 0, 0, 0, 0, 0, 0 },
/* PC20 */ { 0, 0, 0, 0, 0, 0 },
/* PC19 */ { 1, 1, 0, 0, 0, 0 },
/* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* ETHRXCLK: CLK14 */
/* PC17 */ { 0, 0, 0, 0, 0, 0 }, /* ETHTXCLK: CLK15 */
/* PC16 */ { 0, 0, 0, 0, 0, 0 },
/* PC15 */ { 0, 0, 0, 0, 0, 0 },
/* PC14 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 UART CD/ */
/* PC13 */ { 0, 0, 0, 0, 0, 0 },
/* PC12 */ { 0, 0, 0, 0, 0, 0 },
/* PC11 */ { 0, 0, 0, 0, 0, 0 },
/* PC10 */ { 1, 0, 0, 1, 0, 0 }, /* ETHMDC: GP */
/* PC9 */ { 1, 0, 0, 1, 0, 0 }, /* ETHMDIO: GP */
/* PC8 */ { 0, 0, 0, 0, 0, 0 },
/* PC7 */ { 0, 0, 0, 0, 0, 0 },
/* PC6 */ { 0, 0, 0, 0, 0, 0 },
/* PC5 */ { 0, 0, 0, 0, 0, 0 },
/* PC4 */ { 0, 0, 0, 0, 0, 0 },
/* PC3 */ { 0, 0, 0, 0, 0, 0 },
/* PC2 */ { 0, 0, 0, 0, 0, 0 },
/* PC1 */ { 0, 0, 0, 0, 0, 0 },
/* PC0 */ { 0, 0, 0, 0, 0, 0 }
},
{ /* conf ppar psor pdir podr pdat */
/* PD31 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 UART RxD */
/* PD30 */ { 1, 1, 1, 1, 0, 0 }, /* SCC1 UART TxD */
/* PD29 */ { 0, 0, 0, 0, 0, 0 },
/* PD28 */ { 0, 0, 0, 0, 0, 0 },
/* PD27 */ { 0, 0, 0, 0, 0, 0 },
/* PD26 */ { 0, 0, 0, 0, 0, 0 },
/* PD25 */ { 0, 0, 0, 0, 0, 0 },
/* PD24 */ { 0, 0, 0, 0, 0, 0 },
/* PD23 */ { 0, 0, 0, 0, 0, 0 },
/* PD22 */ { 0, 0, 0, 0, 0, 0 },
/* PD21 */ { 0, 0, 0, 0, 0, 0 },
/* PD20 */ { 0, 0, 0, 0, 0, 0 },
/* PD19 */ { 0, 0, 0, 0, 0, 0 },
/* PD18 */ { 0, 0, 0, 0, 0, 0 },
/* PD17 */ { 0, 0, 0, 0, 0, 0 },
/* PD16 */ { 0, 0, 0, 0, 0, 0 },
/* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */
/* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */
/* PD13 */ { 0, 0, 0, 0, 0, 0 },
/* PD12 */ { 0, 0, 0, 0, 0, 0 },
/* PD11 */ { 0, 0, 0, 0, 0, 0 },
/* PD10 */ { 0, 0, 0, 0, 0, 0 },
/* PD9 */ { 0, 0, 0, 0, 0, 0 },
/* PD8 */ { 0, 0, 0, 0, 0, 0 },
/* PD7 */ { 0, 0, 0, 0, 0, 0 },
/* PD6 */ { 0, 0, 0, 0, 0, 0 },
/* PD5 */ { 0, 0, 0, 0, 0, 0 },
/* PD4 */ { 0, 0, 0, 0, 0, 0 },
/* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
}
};
/* ------------------------------------------------------------------------- */
struct tm {
unsigned int tm_sec;
unsigned int tm_min;
unsigned int tm_hour;
unsigned int tm_wday;
unsigned int tm_mday;
unsigned int tm_mon;
unsigned int tm_year;
};
void read_RS5C372_time (struct tm *timedate)
{
unsigned char buffer[8];
#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
if (i2c_read (RS5C372_PPC_I2C_ADR, 0, 1, buffer, sizeof (buffer))) {
timedate->tm_sec = BCD_TO_BIN (buffer[0]);
timedate->tm_min = BCD_TO_BIN (buffer[1]);
timedate->tm_hour = BCD_TO_BIN (buffer[2]);
timedate->tm_wday = BCD_TO_BIN (buffer[3]);
timedate->tm_mday = BCD_TO_BIN (buffer[4]);
timedate->tm_mon = BCD_TO_BIN (buffer[5]);
timedate->tm_year = BCD_TO_BIN (buffer[6]) + 2000;
} else {
/*printf("i2c error %02x\n", rc); */
memset (timedate, 0, sizeof (struct tm));
}
}
/* ------------------------------------------------------------------------- */
int read_LM84_temp (int address)
{
unsigned char buffer[8];
/*int rc;*/
if (i2c_read (address, 0, 1, buffer, 1)) {
return (int) buffer[0];
} else {
/*printf("i2c error %02x\n", rc); */
return -42;
}
}
/* ------------------------------------------------------------------------- */
/*
* Check Board Identity:
*/
int checkboard (void)
{
struct tm timedate;
unsigned int ppctemp, prottemp;
puts ("Board: Rohde & Schwarz 8260 Protocol Board\n");
/* initialise i2c */
i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
read_RS5C372_time (&timedate);
printf (" Time: %02d:%02d:%02d\n",
timedate.tm_hour, timedate.tm_min, timedate.tm_sec);
printf (" Date: %02d-%02d-%04d\n",
timedate.tm_mday, timedate.tm_mon, timedate.tm_year);
ppctemp = read_LM84_temp (LM84_PPC_I2C_ADR);
prottemp = read_LM84_temp (LM84_SHARC_I2C_ADR);
printf (" Temp: PPC %d C, Protocol Board %d C\n",
ppctemp, prottemp);
return 0;
}
/* ------------------------------------------------------------------------- */
/*
* Miscelaneous platform dependent initialisations while still
* running in flash
*/
int misc_init_f (void)
{
return 0;
}
/* ------------------------------------------------------------------------- */
long int initdram (int board_type)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile memctl8260_t *memctl = &immap->im_memctl;
#ifdef INIT_LOCAL_BUS_SDRAM
volatile uchar *ramaddr8;
#endif
volatile ulong *ramaddr32;
ulong sdmr;
int i;
/*
* Only initialize SDRAM when running from FLASH.
* When running from RAM, don't touch it.
*/
if ((ulong) initdram & 0xff000000) {
immap->im_siu_conf.sc_ppc_acr = 0x02;
immap->im_siu_conf.sc_ppc_alrh = 0x01267893;
immap->im_siu_conf.sc_ppc_alrl = 0x89ABCDEF;
immap->im_siu_conf.sc_lcl_acr = 0x02;
immap->im_siu_conf.sc_lcl_alrh = 0x01234567;
immap->im_siu_conf.sc_lcl_alrl = 0x89ABCDEF;
/*
* Program local/60x bus Transfer Error Status and Control Regs:
* Disable parity errors
*/
immap->im_siu_conf.sc_tescr1 = 0x00040000;
immap->im_siu_conf.sc_ltescr1 = 0x00040000;
/*
* Perform Power-Up Initialisation of SDRAM (see 8260 UM, 10.4.2)
*
* The appropriate BRx/ORx registers have already
* been set when we get here (see cpu_init_f). The
* SDRAM can be accessed at the address CFG_SDRAM_BASE.
*/
memctl->memc_mptpr = 0x2000;
memctl->memc_mar = 0x0200;
#ifdef INIT_LOCAL_BUS_SDRAM
/* initialise local bus ram
*
* (using the PSRMR_ definitions is NOT an error here
* - the LSDMR has the same fields as the PSDMR!)
*/
memctl->memc_lsrt = 0x0b;
memctl->memc_lurt = 0x00;
ramaddr = (uchar *) PHYS_SDRAM_LOCAL;
sdmr = CFG_LSDMR & ~(PSDMR_OP_MSK | PSDMR_RFEN | PSDMR_PBI);
memctl->memc_lsdmr = sdmr | PSDMR_OP_PREA;
*ramaddr = 0xff;
for (i = 0; i < 8; i++) {
memctl->memc_lsdmr = sdmr | PSDMR_OP_CBRR;
*ramaddr = 0xff;
}
memctl->memc_lsdmr = sdmr | PSDMR_OP_MRW;
*ramaddr = 0xff;
memctl->memc_lsdmr = CFG_LSDMR | PSDMR_OP_NORM;
#endif
/* initialise 60x bus ram */
memctl->memc_psrt = 0x0b;
memctl->memc_purt = 0x08;
ramaddr32 = (ulong *) PHYS_SDRAM_60X;
sdmr = CFG_PSDMR & ~(PSDMR_OP_MSK | PSDMR_RFEN | PSDMR_PBI);
memctl->memc_psdmr = sdmr | PSDMR_OP_PREA;
ramaddr32[0] = 0x00ff00ff;
ramaddr32[1] = 0x00ff00ff;
memctl->memc_psdmr = sdmr | PSDMR_OP_CBRR;
for (i = 0; i < 8; i++) {
ramaddr32[0] = 0x00ff00ff;
ramaddr32[1] = 0x00ff00ff;
}
memctl->memc_psdmr = sdmr | PSDMR_OP_MRW;
ramaddr32[0] = 0x00ff00ff;
ramaddr32[1] = 0x00ff00ff;
memctl->memc_psdmr = sdmr | PSDMR_OP_NORM | PSDMR_RFEN;
}
/* return the size of the 60x bus ram */
return PHYS_SDRAM_60X_SIZE;
}
/* ------------------------------------------------------------------------- */
/*
* Miscelaneous platform dependent initialisations after monitor
* has been relocated into ram
*/
int misc_init_r (void)
{
printf ("misc_init_r\n");
return (0);
}

801
board/sacsng/sacsng.c Normal file
View File

@ -0,0 +1,801 @@
/*
* (C) Copyright 2002
* Custom IDEAS, Inc. <www.cideas.com>
* Gerald Van Baren <vanbaren@cideas.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 <asm/u-boot.h>
#include <common.h>
#include <ioports.h>
#include <mpc8260.h>
/*NO// #include <memtest.h> */
#include <i2c.h>
#include <spi.h>
#ifdef CONFIG_SHOW_BOOT_PROGRESS
#include <status_led.h>
#endif
#include "clkinit.h"
#include "ioconfig.h" /* I/O configuration table */
/*
* PBI Page Based Interleaving
* PSDMR_PBI page based interleaving
* 0 bank based interleaving
* External Address Multiplexing (EAMUX) adds a clock to address cycles
* (this can help with marginal board layouts)
* PSDMR_EAMUX adds a clock
* 0 no extra clock
* Buffer Command (BUFCMD) adds a clock to command cycles.
* PSDMR_BUFCMD adds a clock
* 0 no extra clock
*/
#define CONFIG_PBI PSDMR_PBI
#define PESSIMISTIC_SDRAM 0
#define EAMUX 0 /* EST requires EAMUX */
#define BUFCMD 0
/*
* ADC/DAC Defines:
*/
#define INITIAL_SAMPLE_RATE 10016 /* Initial Daq sample rate */
#define INITIAL_RIGHT_JUST 0 /* Initial DAC right justification */
#define INITIAL_MCLK_DIVIDE 0 /* Initial MCLK Divide */
#define INITIAL_SAMPLE_64X 1 /* Initial 64x clocking mode */
#define INITIAL_SAMPLE_128X 0 /* Initial 128x clocking mode */
/*
* ADC Defines:
*/
#define I2C_ADC_1_ADDR 0x0E /* I2C Address of the ADC #1 */
#define I2C_ADC_2_ADDR 0x0F /* I2C Address of the ADC #2 */
#define ADC_SDATA1_MASK 0x00020000 /* PA14 - CH12SDATA_PU */
#define ADC_SDATA2_MASK 0x00010000 /* PA15 - CH34SDATA_PU */
#define ADC_VREF_CAP 100 /* VREF capacitor in uF */
#define ADC_INITIAL_DELAY (10 * ADC_VREF_CAP) /* 10 usec per uF, in usec */
#define ADC_SDATA_DELAY 100 /* ADC SDATA release delay in usec */
#define ADC_CAL_DELAY (1000000 / INITIAL_SAMPLE_RATE * 4500)
/* Wait at least 4100 LRCLK's */
#define ADC_REG1_FRAME_START 0x80 /* Frame start */
#define ADC_REG1_GROUND_CAL 0x40 /* Ground calibration enable */
#define ADC_REG1_ANA_MOD_PDOWN 0x20 /* Analog modulator section in power down */
#define ADC_REG1_DIG_MOD_PDOWN 0x10 /* Digital modulator section in power down */
#define ADC_REG2_128x 0x80 /* Oversample at 128x */
#define ADC_REG2_CAL 0x40 /* System calibration enable */
#define ADC_REG2_CHANGE_SIGN 0x20 /* Change sign enable */
#define ADC_REG2_LR_DISABLE 0x10 /* Left/Right output disable */
#define ADC_REG2_HIGH_PASS_DIS 0x08 /* High pass filter disable */
#define ADC_REG2_SLAVE_MODE 0x04 /* Slave mode */
#define ADC_REG2_DFS 0x02 /* Digital format select */
#define ADC_REG2_MUTE 0x01 /* Mute */
#define ADC_REG7_ADDR_ENABLE 0x80 /* Address enable */
#define ADC_REG7_PEAK_ENABLE 0x40 /* Peak enable */
#define ADC_REG7_PEAK_UPDATE 0x20 /* Peak update */
#define ADC_REG7_PEAK_FORMAT 0x10 /* Peak display format */
#define ADC_REG7_DIG_FILT_PDOWN 0x04 /* Digital filter power down enable */
#define ADC_REG7_FIR2_IN_EN 0x02 /* External FIR2 input enable */
#define ADC_REG7_PSYCHO_EN 0x01 /* External pyscho filter input enable */
/*
* DAC Defines:
*/
#define I2C_DAC_ADDR 0x11 /* I2C Address of the DAC */
#define DAC_RST_MASK 0x00008000 /* PA16 - DAC_RST* */
#define DAC_RESET_DELAY 100 /* DAC reset delay in usec */
#define DAC_INITIAL_DELAY 5000 /* DAC initialization delay in usec */
#define DAC_REG1_AMUTE 0x80 /* Auto-mute */
#define DAC_REG1_LEFT_JUST_24_BIT (0 << 4) /* Fmt 0: Left justified 24 bit */
#define DAC_REG1_I2S_24_BIT (1 << 4) /* Fmt 1: I2S up to 24 bit */
#define DAC_REG1_RIGHT_JUST_16BIT (2 << 4) /* Fmt 2: Right justified 16 bit */
#define DAC_REG1_RIGHT_JUST_24BIT (3 << 4) /* Fmt 3: Right justified 24 bit */
#define DAC_REG1_RIGHT_JUST_20BIT (4 << 4) /* Fmt 4: Right justified 20 bit */
#define DAC_REG1_RIGHT_JUST_18BIT (5 << 4) /* Fmt 5: Right justified 18 bit */
#define DAC_REG1_DEM_NO (0 << 2) /* No De-emphasis */
#define DAC_REG1_DEM_44KHZ (1 << 2) /* 44.1KHz De-emphasis */
#define DAC_REG1_DEM_48KHZ (2 << 2) /* 48KHz De-emphasis */
#define DAC_REG1_DEM_32KHZ (3 << 2) /* 32KHz De-emphasis */
#define DAC_REG1_SINGLE 0 /* 4- 50KHz sample rate */
#define DAC_REG1_DOUBLE 1 /* 50-100KHz sample rate */
#define DAC_REG1_QUAD 2 /* 100-200KHz sample rate */
#define DAC_REG1_DSD 3 /* Direct Stream Data, DSD */
#define DAC_REG5_INVERT_A 0x80 /* Invert channel A */
#define DAC_REG5_INVERT_B 0x40 /* Invert channel B */
#define DAC_REG5_I2C_MODE 0x20 /* Control port (I2C) mode */
#define DAC_REG5_POWER_DOWN 0x10 /* Power down mode */
#define DAC_REG5_MUTEC_A_B 0x08 /* Mutec A=B */
#define DAC_REG5_FREEZE 0x04 /* Freeze */
#define DAC_REG5_MCLK_DIV 0x02 /* MCLK divide by 2 */
#define DAC_REG5_RESERVED 0x01 /* Reserved */
/* ------------------------------------------------------------------------- */
/*
* Check Board Identity:
*/
int checkboard(void)
{
printf ("SACSng\n");
return 0;
}
/* ------------------------------------------------------------------------- */
long int initdram(int board_type)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile memctl8260_t *memctl = &immap->im_memctl;
volatile uchar c = 0;
volatile uchar *ramaddr = (uchar *)(CFG_SDRAM_BASE + 0x8);
uint psdmr = CFG_PSDMR;
int i;
uint psrt = 14; /* for no SPD */
uint chipselects = 1; /* for no SPD */
uint sdram_size = CFG_SDRAM0_SIZE * 1024 * 1024; /* for no SPD */
uint or = CFG_OR2_PRELIM; /* for no SPD */
#ifdef SDRAM_SPD_ADDR
uint data_width;
uint rows;
uint banks;
uint cols;
uint caslatency;
uint width;
uint rowst;
uint sdam;
uint bsma;
uint sda10;
u_char spd_size;
u_char data;
u_char cksum;
int j;
#endif
#ifdef SDRAM_SPD_ADDR
/* Keep the compiler from complaining about potentially uninitialized vars */
data_width = chipselects = rows = banks = cols = caslatency = psrt = 0;
/*
* Read the SDRAM SPD EEPROM via I2C.
*/
i2c_read(SDRAM_SPD_ADDR, 0, 1, &data, 1);
spd_size = data;
cksum = data;
for(j = 1; j < 64; j++) { /* read only the checksummed bytes */
/* note: the I2C address autoincrements when alen == 0 */
i2c_read(SDRAM_SPD_ADDR, 0, 0, &data, 1);
if(j == 5) chipselects = data & 0x0F;
else if(j == 6) data_width = data;
else if(j == 7) data_width |= data << 8;
else if(j == 3) rows = data & 0x0F;
else if(j == 4) cols = data & 0x0F;
else if(j == 12) {
/*
* Refresh rate: this assumes the prescaler is set to
* approximately 1uSec per tick.
*/
switch(data & 0x7F) {
default:
case 0: psrt = 14 ; /* 15.625uS */ break;
case 1: psrt = 2; /* 3.9uS */ break;
case 2: psrt = 6; /* 7.8uS */ break;
case 3: psrt = 29; /* 31.3uS */ break;
case 4: psrt = 60; /* 62.5uS */ break;
case 5: psrt = 120; /* 125uS */ break;
}
}
else if(j == 17) banks = data;
else if(j == 18) {
caslatency = 3; /* default CL */
#if(PESSIMISTIC_SDRAM)
if((data & 0x04) != 0) caslatency = 3;
else if((data & 0x02) != 0) caslatency = 2;
else if((data & 0x01) != 0) caslatency = 1;
#else
if((data & 0x01) != 0) caslatency = 1;
else if((data & 0x02) != 0) caslatency = 2;
else if((data & 0x04) != 0) caslatency = 3;
#endif
else {
printf ("WARNING: Unknown CAS latency 0x%02X, using 3\n",
data);
}
}
else if(j == 63) {
if(data != cksum) {
printf ("WARNING: Configuration data checksum failure:"
" is 0x%02x, calculated 0x%02x\n",
data, cksum);
}
}
cksum += data;
}
/* We don't trust CL less than 2 (only saw it on an old 16MByte DIMM) */
if(caslatency < 2) {
printf("CL was %d, forcing to 2\n", caslatency);
caslatency = 2;
}
if(rows > 14) {
printf("This doesn't look good, rows = %d, should be <= 14\n", rows);
rows = 14;
}
if(cols > 11) {
printf("This doesn't look good, columns = %d, should be <= 11\n", cols);
cols = 11;
}
if((data_width != 64) && (data_width != 72))
{
printf("WARNING: SDRAM width unsupported, is %d, expected 64 or 72.\n",
data_width);
}
width = 3; /* 2^3 = 8 bytes = 64 bits wide */
/*
* Convert banks into log2(banks)
*/
if (banks == 2) banks = 1;
else if(banks == 4) banks = 2;
else if(banks == 8) banks = 3;
sdram_size = 1 << (rows + cols + banks + width);
#if(CONFIG_PBI == 0) /* bank-based interleaving */
rowst = ((32 - 6) - (rows + cols + width)) * 2;
#else
rowst = 32 - (rows + banks + cols + width);
#endif
or = ~(sdram_size - 1) | /* SDAM address mask */
((banks-1) << 13) | /* banks per device */
(rowst << 9) | /* rowst */
((rows - 9) << 6); /* numr */
memctl->memc_or2 = or;
/*
* SDAM specifies the number of columns that are multiplexed
* (reference AN2165/D), defined to be (columns - 6) for page
* interleave, (columns - 8) for bank interleave.
*
* BSMA is 14 - max(rows, cols). The bank select lines come
* into play above the highest "address" line going into the
* the SDRAM.
*/
#if(CONFIG_PBI == 0) /* bank-based interleaving */
sdam = cols - 8;
bsma = ((31 - width) - 14) - ((rows > cols) ? rows : cols);
sda10 = sdam + 2;
#else
sdam = cols - 6;
bsma = ((31 - width) - 14) - ((rows > cols) ? rows : cols);
sda10 = sdam;
#endif
#if(PESSIMISTIC_SDRAM)
psdmr = (CONFIG_PBI |\
PSDMR_RFEN |\
PSDMR_RFRC_16_CLK |\
PSDMR_PRETOACT_8W |\
PSDMR_ACTTORW_8W |\
PSDMR_WRC_4C |\
PSDMR_EAMUX |\
PSDMR_BUFCMD) |\
caslatency |\
((caslatency - 1) << 6) | /* LDOTOPRE is CL - 1 */ \
(sdam << 24) |\
(bsma << 21) |\
(sda10 << 18);
#else
psdmr = (CONFIG_PBI |\
PSDMR_RFEN |\
PSDMR_RFRC_7_CLK |\
PSDMR_PRETOACT_3W | /* 1 for 7E parts (fast PC-133) */ \
PSDMR_ACTTORW_2W | /* 1 for 7E parts (fast PC-133) */ \
PSDMR_WRC_1C | /* 1 clock + 7nSec */
EAMUX |\
BUFCMD) |\
caslatency |\
((caslatency - 1) << 6) | /* LDOTOPRE is CL - 1 */ \
(sdam << 24) |\
(bsma << 21) |\
(sda10 << 18);
#endif
#endif
/*
* Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
*
* "At system reset, initialization software must set up the
* programmable parameters in the memory controller banks registers
* (ORx, BRx, P/LSDMR). After all memory parameters are configured,
* system software should execute the following initialization sequence
* for each SDRAM device.
*
* 1. Issue a PRECHARGE-ALL-BANKS command
* 2. Issue eight CBR REFRESH commands
* 3. Issue a MODE-SET command to initialize the mode register
*
* Quote from Micron MT48LC8M16A2 data sheet:
*
* "...the SDRAM requires a 100uS delay prior to issuing any
* command other than a COMMAND INHIBIT or NOP. Starting at some
* point during this 100uS period and continuing at least through
* the end of this period, COMMAND INHIBIT or NOP commands should
* be applied."
*
* "Once the 100uS delay has been satisfied with at least one COMMAND
* INHIBIT or NOP command having been applied, a /PRECHARGE command/
* should be applied. All banks must then be precharged, thereby
* placing the device in the all banks idle state."
*
* "Once in the idle state, /two/ AUTO REFRESH cycles must be
* performed. After the AUTO REFRESH cycles are complete, the
* SDRAM is ready for mode register programming."
*
* (/emphasis/ mine, gvb)
*
* The way I interpret this, Micron start up sequence is:
* 1. Issue a PRECHARGE-BANK command (initial precharge)
* 2. Issue a PRECHARGE-ALL-BANKS command ("all banks ... precharged")
* 3. Issue two (presumably, doing eight is OK) CBR REFRESH commands
* 4. Issue a MODE-SET command to initialize the mode register
*
* --------
*
* The initial commands are executed by setting P/LSDMR[OP] and
* accessing the SDRAM with a single-byte transaction."
*
* The appropriate BRx/ORx registers have already been set when we
* get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE.
*/
memctl->memc_mptpr = CFG_MPTPR;
memctl->memc_psrt = psrt;
memctl->memc_psdmr = psdmr | PSDMR_OP_PREA;
*ramaddr = c;
memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR;
for (i = 0; i < 8; i++)
*ramaddr = c;
memctl->memc_psdmr = psdmr | PSDMR_OP_MRW;
*ramaddr = c;
memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN;
*ramaddr = c;
/*
* Do it a second time for the second set of chips if the DIMM has
* two chip selects (double sided).
*/
if(chipselects > 1) {
ramaddr += sdram_size;
memctl->memc_br3 = CFG_BR3_PRELIM + sdram_size;
memctl->memc_or3 = or;
memctl->memc_psdmr = psdmr | PSDMR_OP_PREA;
*ramaddr = c;
memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR;
for (i = 0; i < 8; i++)
*ramaddr = c;
memctl->memc_psdmr = psdmr | PSDMR_OP_MRW;
*ramaddr = c;
memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN;
*ramaddr = c;
}
/* return total ram size */
return (sdram_size * chipselects);
}
/*-----------------------------------------------------------------------
* Board Control Functions
*/
void board_poweroff (void)
{
while (1); /* hang forever */
}
#ifdef CONFIG_MISC_INIT_R
/* ------------------------------------------------------------------------- */
int misc_init_r(void)
{
/*
* Note: iop is used by the I2C macros, and iopa by the ADC/DAC initialization.
*/
volatile ioport_t *iopa = ioport_addr((immap_t *)CFG_IMMR, 0 /* port A */);
volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT);
int reg; /* I2C register value */
char *ep; /* Environment pointer */
char str_buf[12] ; /* sprintf output buffer */
int sample_rate; /* ADC/DAC sample rate */
int sample_64x; /* Use 64/4 clocking for the ADC/DAC */
int sample_128x; /* Use 128/4 clocking for the ADC/DAC */
int right_just; /* Is the data to the DAC right justified? */
int mclk_divide; /* MCLK Divide */
/*
* SACSng custom initialization:
* Start the ADC and DAC clocks, since the Crystal parts do not
* work on the I2C bus until the clocks are running.
*/
sample_rate = INITIAL_SAMPLE_RATE;
if ((ep = getenv("DaqSampleRate")) != NULL) {
sample_rate = simple_strtol(ep, NULL, 10);
}
sample_64x = INITIAL_SAMPLE_64X;
sample_128x = INITIAL_SAMPLE_128X;
if ((ep = getenv("Daq64xSampling")) != NULL) {
sample_64x = simple_strtol(ep, NULL, 10);
if (sample_64x) {
sample_128x = 0;
}
else {
sample_128x = 1;
}
}
else {
if ((ep = getenv("Daq128xSampling")) != NULL) {
sample_128x = simple_strtol(ep, NULL, 10);
if (sample_128x) {
sample_64x = 0;
}
else {
sample_64x = 1;
}
}
}
Daq_Init_Clocks(sample_rate, sample_64x);
sample_rate = Daq_Get_SampleRate();
Daq_Start_Clocks(sample_rate);
sprintf(str_buf, "%d", sample_rate);
setenv("DaqSampleRate", str_buf);
if (sample_64x) {
setenv("Daq64xSampling", "1");
setenv("Daq128xSampling", NULL);
}
else {
setenv("Daq64xSampling", NULL);
setenv("Daq128xSampling", "1");
}
/* Display the ADC/DAC clocking information */
Daq_Display_Clocks();
/*
* Determine the DAC data justification
*/
right_just = INITIAL_RIGHT_JUST;
if ((ep = getenv("DaqDACRightJustified")) != NULL) {
right_just = simple_strtol(ep, NULL, 10);
}
sprintf(str_buf, "%d", right_just);
setenv("DaqDACRightJustified", str_buf);
/*
* Determine the DAC MCLK Divide
*/
mclk_divide = INITIAL_MCLK_DIVIDE;
if ((ep = getenv("DaqDACMClockDivide")) != NULL) {
mclk_divide = simple_strtol(ep, NULL, 10);
}
sprintf(str_buf, "%d", mclk_divide);
setenv("DaqDACMClockDivide", str_buf);
/*
* Initializing the I2C address in the Crystal A/Ds:
*
* 1) Wait for VREF cap to settle (10uSec per uF)
* 2) Release pullup on SDATA
* 3) Write the I2C address to register 6
* 4) Enable address matching by setting the MSB in register 7
*/
printf("Initializing the ADC...\n");
udelay(ADC_INITIAL_DELAY); /* 10uSec per uF of VREF cap */
iopa->pdat &= ~ADC_SDATA1_MASK; /* release SDATA1 */
udelay(ADC_SDATA_DELAY); /* arbitrary settling time */
i2c_reg_write(0x00, 0x06, I2C_ADC_1_ADDR); /* set address */
i2c_reg_write(I2C_ADC_1_ADDR, 0x07, /* turn on ADDREN */
ADC_REG7_ADDR_ENABLE);
i2c_reg_write(I2C_ADC_1_ADDR, 0x02, /* 128x, slave mode, !HPEN */
(sample_64x ? 0 : ADC_REG2_128x) |
ADC_REG2_HIGH_PASS_DIS |
ADC_REG2_SLAVE_MODE);
reg = i2c_reg_read(I2C_ADC_1_ADDR, 0x06) & 0x7F;
if(reg != I2C_ADC_1_ADDR)
printf("Init of ADC U10 failed: address is 0x%02X should be 0x%02X\n",
reg, I2C_ADC_1_ADDR);
iopa->pdat &= ~ADC_SDATA2_MASK; /* release SDATA2 */
udelay(ADC_SDATA_DELAY); /* arbitrary settling time */
i2c_reg_write(0x00, 0x06, I2C_ADC_2_ADDR); /* set address (do not set ADDREN yet) */
i2c_reg_write(I2C_ADC_2_ADDR, 0x02, /* 64x, slave mode, !HPEN */
(sample_64x ? 0 : ADC_REG2_128x) |
ADC_REG2_HIGH_PASS_DIS |
ADC_REG2_SLAVE_MODE);
reg = i2c_reg_read(I2C_ADC_2_ADDR, 0x06) & 0x7F;
if(reg != I2C_ADC_2_ADDR)
printf("Init of ADC U15 failed: address is 0x%02X should be 0x%02X\n",
reg, I2C_ADC_2_ADDR);
i2c_reg_write(I2C_ADC_1_ADDR, 0x01, /* set FSTART and GNDCAL */
ADC_REG1_FRAME_START |
ADC_REG1_GROUND_CAL);
i2c_reg_write(I2C_ADC_1_ADDR, 0x02, /* Start calibration */
(sample_64x ? 0 : ADC_REG2_128x) |
ADC_REG2_CAL |
ADC_REG2_HIGH_PASS_DIS |
ADC_REG2_SLAVE_MODE);
udelay(ADC_CAL_DELAY); /* a minimum of 4100 LRCLKs */
i2c_reg_write(I2C_ADC_1_ADDR, 0x01, 0x00); /* remove GNDCAL */
/*
* Now that we have synchronized the ADC's, enable address
* selection on the second ADC as well as the first.
*/
i2c_reg_write(I2C_ADC_2_ADDR, 0x07, ADC_REG7_ADDR_ENABLE);
/*
* Initialize the Crystal DAC
*
* Two of the config lines are used for I2C so we have to set them
* to the proper initialization state without inadvertantly
* sending an I2C "start" sequence. When we bring the I2C back to
* the normal state, we send an I2C "stop" sequence.
*/
printf("Initializing the DAC...\n");
/*
* Bring the I2C clock and data lines low for initialization
*/
I2C_SCL(0);
I2C_DELAY;
I2C_SDA(0);
I2C_ACTIVE;
I2C_DELAY;
/* Reset the DAC */
iopa->pdat &= ~DAC_RST_MASK;
udelay(DAC_RESET_DELAY);
/* Release the DAC reset */
iopa->pdat |= DAC_RST_MASK;
udelay(DAC_INITIAL_DELAY);
/*
* Cause the DAC to:
* Enable control port (I2C mode)
* Going into power down
*/
i2c_reg_write(I2C_DAC_ADDR, 0x05,
DAC_REG5_I2C_MODE |
DAC_REG5_POWER_DOWN);
/*
* Cause the DAC to:
* Enable control port (I2C mode)
* Going into power down
* . MCLK divide by 1
* . MCLK divide by 2
*/
i2c_reg_write(I2C_DAC_ADDR, 0x05,
DAC_REG5_I2C_MODE |
DAC_REG5_POWER_DOWN |
(mclk_divide ? DAC_REG5_MCLK_DIV : 0));
/*
* Cause the DAC to:
* Auto-mute disabled
* . Format 0, left justified 24 bits
* . Format 3, right justified 24 bits
* No de-emphasis
* . Single speed mode
* . Double speed mode
*/
i2c_reg_write(I2C_DAC_ADDR, 0x01,
(right_just ? DAC_REG1_RIGHT_JUST_24BIT :
DAC_REG1_LEFT_JUST_24_BIT) |
DAC_REG1_DEM_NO |
(sample_rate >= 50000 ? DAC_REG1_DOUBLE : DAC_REG1_SINGLE));
sprintf(str_buf, "%d",
sample_rate >= 50000 ? DAC_REG1_DOUBLE : DAC_REG1_SINGLE);
setenv("DaqDACFunctionalMode", str_buf);
/*
* Cause the DAC to:
* Enable control port (I2C mode)
* Remove power down
* . MCLK divide by 1
* . MCLK divide by 2
*/
i2c_reg_write(I2C_DAC_ADDR, 0x05,
DAC_REG5_I2C_MODE |
(mclk_divide ? DAC_REG5_MCLK_DIV : 0));
/*
* Create a I2C stop condition:
* low->high on data while clock is high.
*/
I2C_SCL(1);
I2C_DELAY;
I2C_SDA(1);
I2C_DELAY;
I2C_TRISTATE;
printf("\n");
#ifdef CONFIG_SHOW_BOOT_PROGRESS
/*
* Turn off the RED fail LED now that we are up and running.
*/
status_led_set(STATUS_LED_RED, STATUS_LED_OFF);
#endif
return 0;
}
#ifdef CONFIG_SHOW_BOOT_PROGRESS
/*
* Show boot status: flash the LED if something goes wrong, indicating
* that last thing that worked and thus, by implication, what is broken.
*
* This stores the last OK value in RAM so this will not work properly
* before RAM is initialized. Since it is being used for indicating
* boot status (i.e. after RAM is initialized), that is OK.
*/
static void flash_code(uchar number, uchar modulo, uchar digits)
{
int j;
/*
* Recursively do upper digits.
*/
if(digits > 1) {
flash_code(number / modulo, modulo, digits - 1);
}
number = number % modulo;
/*
* Zero is indicated by one long flash (dash).
*/
if(number == 0) {
status_led_set(STATUS_LED_BOOT, STATUS_LED_ON);
udelay(1000000);
status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF);
udelay(200000);
} else {
/*
* Non-zero is indicated by short flashes, one per count.
*/
for(j = 0; j < number; j++) {
status_led_set(STATUS_LED_BOOT, STATUS_LED_ON);
udelay(100000);
status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF);
udelay(200000);
}
}
/*
* Inter-digit pause: we've already waited 200 mSec, wait 1 sec total
*/
udelay(700000);
}
static int last_boot_progress;
void show_boot_progress (int status)
{
if(status != -1) {
last_boot_progress = status;
} else {
/*
* Houston, we have a problem. Blink the last OK status which
* indicates where things failed.
*/
status_led_set(STATUS_LED_RED, STATUS_LED_ON);
flash_code(last_boot_progress, 5, 3);
udelay(1000000);
status_led_set(STATUS_LED_RED, STATUS_LED_BLINKING);
}
}
#endif /* CONFIG_SHOW_BOOT_PROGRESS */
/*
* The following are used to control the SPI chip selects for the SPI command.
*/
#if (CONFIG_COMMANDS & CFG_CMD_SPI)
#define SPI_ADC_CS_MASK 0x00000800
#define SPI_DAC_CS_MASK 0x00001000
void spi_adc_chipsel(int cs)
{
volatile ioport_t *iopd = ioport_addr((immap_t *)CFG_IMMR, 3 /* port D */);
if(cs)
iopd->pdat &= ~SPI_ADC_CS_MASK; /* activate the chip select */
else
iopd->pdat |= SPI_ADC_CS_MASK; /* deactivate the chip select */
}
void spi_dac_chipsel(int cs)
{
volatile ioport_t *iopd = ioport_addr((immap_t *)CFG_IMMR, 3 /* port D */);
if(cs)
iopd->pdat &= ~SPI_DAC_CS_MASK; /* activate the chip select */
else
iopd->pdat |= SPI_DAC_CS_MASK; /* deactivate the chip select */
}
/*
* The SPI command uses this table of functions for controlling the SPI
* chip selects: it calls the appropriate function to control the SPI
* chip selects.
*/
spi_chipsel_type spi_chipsel[2] = {
spi_adc_chipsel,
spi_dac_chipsel
};
#endif /* CFG_CMD_SPI */
#endif /* CONFIG_MISC_INIT_R */

766
board/sandpoint/flash.c Normal file
View File

@ -0,0 +1,766 @@
/*
* (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 <mpc824x.h>
#include <asm/processor.h>
#include <asm/pci_io.h>
#include <w83c553f.h>
#define ROM_CS0_START 0xFF800000
#define ROM_CS1_START 0xFF000000
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
#if defined(CFG_ENV_IS_IN_FLASH)
# ifndef CFG_ENV_ADDR
# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
# endif
# ifndef CFG_ENV_SIZE
# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
# endif
# ifndef CFG_ENV_SECT_SIZE
# define CFG_ENV_SECT_SIZE CFG_ENV_SIZE
# endif
#endif
/*-----------------------------------------------------------------------
* Functions
*/
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 /* 0 */
/*flash command address offsets*/
#if 0
#define ADDR0 (0x555)
#define ADDR1 (0x2AA)
#define ADDR3 (0x001)
#else
#define ADDR0 (0xAAA)
#define ADDR1 (0x555)
#define ADDR3 (0x001)
#endif
#define FLASH_WORD_SIZE unsigned char
/*-----------------------------------------------------------------------
*/
#if 0
static int byte_parity_odd(unsigned char x) __attribute__ ((const));
#endif /* 0 */
static unsigned long flash_id(unsigned char mfct, unsigned char chip) __attribute__ ((const));
typedef struct
{
FLASH_WORD_SIZE extval;
unsigned short intval;
} map_entry;
#if 0
static int
byte_parity_odd(unsigned char x)
{
x ^= x >> 4;
x ^= x >> 2;
x ^= x >> 1;
return (x & 0x1) != 0;
}
#endif /* 0 */
static unsigned long
flash_id(unsigned char mfct, unsigned char chip)
{
static const map_entry mfct_map[] =
{
{(FLASH_WORD_SIZE) AMD_MANUFACT, (unsigned short) ((unsigned long) FLASH_MAN_AMD >> 16)},
{(FLASH_WORD_SIZE) FUJ_MANUFACT, (unsigned short) ((unsigned long) FLASH_MAN_FUJ >> 16)},
{(FLASH_WORD_SIZE) STM_MANUFACT, (unsigned short) ((unsigned long) FLASH_MAN_STM >> 16)},
{(FLASH_WORD_SIZE) MT_MANUFACT, (unsigned short) ((unsigned long) FLASH_MAN_MT >> 16)},
{(FLASH_WORD_SIZE) INTEL_MANUFACT,(unsigned short) ((unsigned long) FLASH_MAN_INTEL >> 16)},
{(FLASH_WORD_SIZE) INTEL_ALT_MANU,(unsigned short) ((unsigned long) FLASH_MAN_INTEL >> 16)}
};
static const map_entry chip_map[] =
{
{AMD_ID_F040B, FLASH_AM040},
{(FLASH_WORD_SIZE) STM_ID_x800AB, FLASH_STM800AB}
};
const map_entry *p;
unsigned long result = FLASH_UNKNOWN;
/* find chip id */
for(p = &chip_map[0]; p < &chip_map[sizeof chip_map / sizeof chip_map[0]]; p++)
if(p->extval == chip)
{
result = FLASH_VENDMASK | p->intval;
break;
}
/* find vendor id */
for(p = &mfct_map[0]; p < &mfct_map[sizeof mfct_map / sizeof mfct_map[0]]; p++)
if(p->extval == mfct)
{
result &= ~FLASH_VENDMASK;
result |= (unsigned long) p->intval << 16;
break;
}
return result;
}
unsigned long
flash_init(void)
{
unsigned long i;
unsigned char j;
static const ulong flash_banks[] = CFG_FLASH_BANKS;
/* Init: no FLASHes known */
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
{
flash_info_t * const pflinfo = &flash_info[i];
pflinfo->flash_id = FLASH_UNKNOWN;
pflinfo->size = 0;
pflinfo->sector_count = 0;
}
/* Enable writes to Sandpoint flash */
{
register unsigned char temp;
CONFIG_READ_BYTE(CFG_WINBOND_ISA_CFG_ADDR + WINBOND_CSCR, temp);
temp &= ~0x20; /* clear BIOSWP bit */
CONFIG_WRITE_BYTE(CFG_WINBOND_ISA_CFG_ADDR + WINBOND_CSCR, temp);
}
for(i = 0; i < sizeof flash_banks / sizeof flash_banks[0]; i++)
{
flash_info_t * const pflinfo = &flash_info[i];
const unsigned long base_address = flash_banks[i];
volatile FLASH_WORD_SIZE * const flash = (FLASH_WORD_SIZE *) base_address;
#if 0
volatile FLASH_WORD_SIZE * addr2;
#endif
#if 0
/* write autoselect sequence */
flash[0x5555] = 0xaa;
flash[0x2aaa] = 0x55;
flash[0x5555] = 0x90;
#else
flash[0xAAA << (3 * i)] = 0xaa;
flash[0x555 << (3 * i)] = 0x55;
flash[0xAAA << (3 * i)] = 0x90;
#endif
__asm__ __volatile__("sync");
#if 0
pflinfo->flash_id = flash_id(flash[0x0], flash[0x1]);
#else
pflinfo->flash_id = flash_id(flash[0x0], flash[0x2 + 14 * i]);
#endif
switch(pflinfo->flash_id & FLASH_TYPEMASK)
{
case FLASH_AM040:
pflinfo->size = 0x00080000;
pflinfo->sector_count = 8;
for(j = 0; j < 8; j++)
{
pflinfo->start[j] = base_address + 0x00010000 * j;
pflinfo->protect[j] = flash[(j << 16) | 0x2];
}
break;
case FLASH_STM800AB:
pflinfo->size = 0x00100000;
pflinfo->sector_count = 19;
pflinfo->start[0] = base_address;
pflinfo->start[1] = base_address + 0x4000;
pflinfo->start[2] = base_address + 0x6000;
pflinfo->start[3] = base_address + 0x8000;
for(j = 1; j < 16; j++)
{
pflinfo->start[j+3] = base_address + 0x00010000 * j;
}
#if 0
/* check for protected sectors */
for (j = 0; j < pflinfo->sector_count; j++) {
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
/* D0 = 1 if protected */
addr2 = (volatile FLASH_WORD_SIZE *)(pflinfo->start[j]);
if (pflinfo->flash_id & FLASH_MAN_SST)
pflinfo->protect[j] = 0;
else
pflinfo->protect[j] = addr2[2] & 1;
}
#endif
break;
}
/* Protect monitor and environment sectors
*/
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1,
&flash_info[0]);
#endif
#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
&flash_info[0]);
#endif
/* reset device to read mode */
flash[0x0000] = 0xf0;
__asm__ __volatile__("sync");
}
return flash_info[0].size + flash_info[1].size;
}
#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_MAN_SST)
{
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)
{
static const char unk[] = "Unknown";
const char *mfct = unk, *type = unk;
unsigned int i;
if(info->flash_id != FLASH_UNKNOWN)
{
switch(info->flash_id & FLASH_VENDMASK)
{
case FLASH_MAN_AMD: mfct = "AMD"; break;
case FLASH_MAN_FUJ: mfct = "FUJITSU"; break;
case FLASH_MAN_STM: mfct = "STM"; break;
case FLASH_MAN_SST: mfct = "SST"; break;
case FLASH_MAN_BM: mfct = "Bright Microelectonics"; break;
case FLASH_MAN_INTEL: mfct = "Intel"; break;
}
switch(info->flash_id & FLASH_TYPEMASK)
{
case FLASH_AM040: type = "AM29F040B (512K * 8, uniform sector size)"; break;
case FLASH_AM400B: type = "AM29LV400B (4 Mbit, bottom boot sect)"; break;
case FLASH_AM400T: type = "AM29LV400T (4 Mbit, top boot sector)"; break;
case FLASH_AM800B: type = "AM29LV800B (8 Mbit, bottom boot sect)"; break;
case FLASH_AM800T: type = "AM29LV800T (8 Mbit, top boot sector)"; break;
case FLASH_AM160T: type = "AM29LV160T (16 Mbit, top boot sector)"; break;
case FLASH_AM320B: type = "AM29LV320B (32 Mbit, bottom boot sect)"; break;
case FLASH_AM320T: type = "AM29LV320T (32 Mbit, top boot sector)"; break;
case FLASH_STM800AB: type = "M29W800AB (8 Mbit, bottom boot sect)"; break;
case FLASH_SST800A: type = "SST39LF/VF800 (8 Mbit, uniform sector size)"; break;
case FLASH_SST160A: type = "SST39LF/VF160 (16 Mbit, uniform sector size)"; break;
}
}
printf(
"\n Brand: %s Type: %s\n"
" Size: %lu KB in %d Sectors\n",
mfct,
type,
info->size >> 10,
info->sector_count
);
printf (" Sector Start Addresses:");
for (i = 0; i < info->sector_count; i++)
{
unsigned long size;
unsigned int erased;
unsigned long * flash = (unsigned long *) info->start[i];
/*
* Check if whole sector is erased
*/
size =
(i != (info->sector_count - 1)) ?
(info->start[i + 1] - info->start[i]) >> 2 :
(info->start[0] + info->size - info->start[i]) >> 2;
for(
flash = (unsigned long *) info->start[i], erased = 1;
(flash != (unsigned long *) info->start[i] + size) && erased;
flash++
)
erased = *flash == ~0x0UL;
printf(
"%s %08lX %s %s",
(i % 5) ? "" : "\n ",
info->start[i],
erased ? "E" : " ",
info->protect[i] ? "RO" : " "
);
}
puts("\n");
return;
}
#if 0
/*
* The following code cannot be run from FLASH!
*/
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;
printf("flash_get_size: \n");
/* Write auto select command: read Manufacturer ID */
eieio();
addr2[ADDR0] = (FLASH_WORD_SIZE)0xAA;
addr2[ADDR1] = (FLASH_WORD_SIZE)0x55;
addr2[ADDR0] = (FLASH_WORD_SIZE)0x90;
value = addr2[0];
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 */
}
printf("recognised manufacturer");
value = addr2[ADDR3]; /* device ID */
debug ("\ndev_code=%x\n", value);
switch (value) {
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 */
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 */
case (FLASH_WORD_SIZE)AMD_ID_F040B:
info->flash_id += FLASH_AM040;
info->sector_count = 8;
info->size = 0x00080000;
break; /* => 0.5 MB */
default:
info->flash_id = FLASH_UNKNOWN;
return (0); /* => no or unknown flash */
}
printf("flash id %lx; sector count %x, size %lx\n", info->flash_id,info->sector_count,info->size);
/* set up sector start address table */
if (info->flash_id & FLASH_MAN_SST)
{
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 */
addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]);
if (info->flash_id & FLASH_MAN_SST)
info->protect[i] = 0;
else
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);
}
#endif
int
flash_erase(flash_info_t *info, int s_first, int s_last)
{
volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]);
int flag, prot, sect, l_sect;
ulong start, now, last;
unsigned char sh8b;
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_MAN_STM | FLASH_AMD_COMP))) {
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;
/* Check the ROM CS */
if ((info->start[0] >= ROM_CS1_START) && (info->start[0] < ROM_CS0_START))
sh8b = 3;
else
sh8b = 0;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA;
addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055;
addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00800080;
addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA;
addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055;
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
addr = (FLASH_WORD_SIZE *)(info->start[0] + (
(info->start[sect] - info->start[0]) << sh8b));
if (info->flash_id & FLASH_MAN_SST)
{
addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA;
addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055;
addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00800080;
addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA;
addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055;
addr[0] = (FLASH_WORD_SIZE)0x00500050; /* block erase */
udelay(30000); /* wait 30 ms */
}
else
addr[0] = (FLASH_WORD_SIZE)0x00300030; /* sector erase */
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 = (FLASH_WORD_SIZE *)(info->start[0] + (
(info->start[l_sect] - info->start[0]) << sh8b));
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 */
serial_putc ('.');
last = now;
}
}
DONE:
/* 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;
volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *)&data;
ulong start;
int flag;
int i;
unsigned char sh8b;
/* Check the ROM CS */
if ((info->start[0] >= ROM_CS1_START) && (info->start[0] < ROM_CS0_START))
sh8b = 3;
else
sh8b = 0;
dest2 = (FLASH_WORD_SIZE *)(((dest - info->start[0]) << sh8b) +
info->start[0]);
/* Check if Flash is (sufficiently) erased */
if ((*dest2 & (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 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA;
addr2[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055;
addr2[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00A000A0;
dest2[i << sh8b] = data2[i];
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* data polling for D7 */
start = get_timer (0);
while ((dest2[i << sh8b] & (FLASH_WORD_SIZE)0x00800080) !=
(data2[i] & (FLASH_WORD_SIZE)0x00800080)) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
return (1);
}
}
}
return (0);
}
/*-----------------------------------------------------------------------
*/

392
board/sbc8260/flash.c Normal file
View File

@ -0,0 +1,392 @@
/*
* (C) Copyright 2000
* Marius Groeger <mgroeger@sysgo.de>
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* Flash Routines for AMD 29F080B devices
*
*--------------------------------------------------------------------
* 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 <mpc8xx.h>
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
/*-----------------------------------------------------------------------
* 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);
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
unsigned long size;
int i;
/* Init: no FLASHes known */
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
}
/* for now, only support the 4 MB Flash SIMM */
size = flash_get_size((vu_long *)CFG_FLASH0_BASE, &flash_info[0]);
/*
* protect monitor and environment sectors
*/
#if CFG_MONITOR_BASE >= CFG_FLASH0_BASE
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
&flash_info[0]);
#endif
#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
# ifndef CFG_ENV_SIZE
# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
# endif
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
&flash_info[0]);
#endif
return /*size*/ (CFG_FLASH0_SIZE * 1024 * 1024);
}
/*-----------------------------------------------------------------------
*/
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 >> 16) & 0xff) {
case 0x1:
printf ("AMD ");
break;
default:
printf ("Unknown Vendor ");
break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case AMD_ID_F040B:
printf ("AM29F040B (4 Mbit)\n");
break;
case AMD_ID_F080B:
printf ("AM29F080B (8 Mbit)\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;
vu_long vendor, devid;
ulong base = (ulong)addr;
/* printf("addr = %08lx\n", (unsigned long)addr); */
/* Reset and Write auto select command: read Manufacturer ID */
addr[0] = 0xf0f0f0f0;
addr[0x0555] = 0xAAAAAAAA;
addr[0x02AA] = 0x55555555;
addr[0x0555] = 0x90909090;
udelay (1000);
vendor = addr[0];
/* printf("vendor = %08lx\n", vendor); */
if (vendor != 0x01010101) {
info->size = 0;
goto out;
}
devid = addr[1];
/* printf("devid = %08lx\n", devid); */
if ((devid & 0xff) == AMD_ID_F080B) {
info->flash_id = (vendor & 0xff) << 16 | AMD_ID_F080B;
/* we have 16 sectors with 64KB each x 4 */
info->sector_count = 16;
info->size = 4 * info->sector_count * 64*1024;
}
else {
info->size = 0;
goto out;
}
/* check for protected sectors */
for (i = 0; i < info->sector_count; i++) {
/* sector base address */
info->start[i] = base + i * (info->size / info->sector_count);
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
/* D0 = 1 if protected */
addr = (volatile unsigned long *)(info->start[i]);
info->protect[i] = addr[2] & 1;
}
/* reset command */
addr = (vu_long *)info->start[0];
out:
addr[0] = 0xf0f0f0f0;
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;
}
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[0x0555] = 0xAAAAAAAA;
addr[0x02AA] = 0x55555555;
addr[0x0555] = 0x80808080;
addr[0x0555] = 0xAAAAAAAA;
addr[0x02AA] = 0x55555555;
udelay (100);
/* 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 */
serial_putc ('.');
last = now;
}
}
DONE:
/* reset to read mode */
addr = (volatile unsigned 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[0x0555] = 0xAAAAAAAA;
addr[0x02AA] = 0x55555555;
addr[0x0555] = 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);
}
/*-----------------------------------------------------------------------
*/

289
board/sbc8260/sbc8260.c Normal file
View File

@ -0,0 +1,289 @@
/*
* (C) Copyright 2000
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright 2001
* Advent Networks, Inc. <http://www.adventnetworks.com>
* Jay Monkman <jtm@smoothsmoothie.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 <ioports.h>
#include <mpc8260.h>
/*
* I/O Port configuration table
*
* if conf is 1, then that port pin will be configured at boot time
* according to the five values podr/pdir/ppar/psor/pdat for that entry
*/
const iop_conf_t iop_conf_tab[4][32] = {
/* Port A configuration */
{ /* conf ppar psor pdir podr pdat */
/* PA31 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 *ATMTXEN */
/* PA30 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTCA */
/* PA29 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTSOC */
/* PA28 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 *ATMRXEN */
/* PA27 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRSOC */
/* PA26 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRCA */
/* PA25 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[0] */
/* PA24 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[1] */
/* PA23 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[2] */
/* PA22 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[3] */
/* PA21 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[4] */
/* PA20 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[5] */
/* PA19 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[6] */
/* PA18 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[7] */
/* PA17 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[7] */
/* PA16 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[6] */
/* PA15 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[5] */
/* PA14 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[4] */
/* PA13 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[3] */
/* PA12 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[2] */
/* PA11 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[1] */
/* PA10 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[0] */
/* PA9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC2 TXD */
/* PA8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC2 RXD */
/* PA7 */ { 1, 0, 0, 1, 0, 0 }, /* PA7 */
/* PA6 */ { 1, 0, 0, 1, 0, 0 }, /* PA6 */
/* PA5 */ { 1, 0, 0, 1, 0, 0 }, /* PA5 */
/* PA4 */ { 1, 0, 0, 1, 0, 0 }, /* PA4 */
/* PA3 */ { 1, 0, 0, 1, 0, 0 }, /* PA3 */
/* PA2 */ { 1, 0, 0, 1, 0, 0 }, /* PA2 */
/* PA1 */ { 1, 0, 0, 1, 0, 0 }, /* PA1 */
/* PA0 */ { 1, 0, 0, 1, 0, 0 } /* PA0 */
},
/* Port B configuration */
{ /* conf ppar psor pdir podr pdat */
/* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TX_ER */
/* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */
/* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */
/* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */
/* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */
/* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */
/* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */
/* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */
/* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */
/* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */
/* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */
/* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */
/* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */
/* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */
/* PB17 */ { 1, 0, 0, 1, 0, 0 }, /* PB17 */
/* PB16 */ { 1, 0, 0, 1, 0, 0 }, /* PB16 */
/* PB15 */ { 1, 0, 0, 1, 0, 0 }, /* PB15 */
/* PB14 */ { 1, 0, 0, 1, 0, 0 }, /* PB14 */
/* PB13 */ { 1, 0, 0, 1, 0, 0 }, /* PB13 */
/* PB12 */ { 1, 0, 0, 1, 0, 0 }, /* PB12 */
/* PB11 */ { 1, 0, 0, 1, 0, 0 }, /* PB11 */
/* PB10 */ { 1, 0, 0, 1, 0, 0 }, /* PB10 */
/* PB9 */ { 1, 0, 0, 1, 0, 0 }, /* PB9 */
/* PB8 */ { 1, 0, 0, 1, 0, 0 }, /* PB8 */
/* PB7 */ { 1, 0, 0, 1, 0, 0 }, /* PB7 */
/* PB6 */ { 1, 0, 0, 1, 0, 0 }, /* PB6 */
/* PB5 */ { 1, 0, 0, 1, 0, 0 }, /* PB5 */
/* PB4 */ { 1, 0, 0, 1, 0, 0 }, /* PB4 */
/* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
},
/* Port C */
{ /* conf ppar psor pdir podr pdat */
/* PC31 */ { 1, 0, 0, 1, 0, 0 }, /* PC31 */
/* PC30 */ { 1, 0, 0, 1, 0, 0 }, /* PC30 */
/* PC29 */ { 1, 1, 1, 0, 0, 0 }, /* SCC1 EN *CLSN */
/* PC28 */ { 1, 0, 0, 1, 0, 0 }, /* PC28 */
/* PC27 */ { 1, 0, 0, 1, 0, 0 }, /* PC27 */
/* PC26 */ { 1, 0, 0, 1, 0, 0 }, /* PC26 */
/* PC25 */ { 1, 0, 0, 1, 0, 0 }, /* PC25 */
/* PC24 */ { 1, 0, 0, 1, 0, 0 }, /* PC24 */
/* PC23 */ { 1, 1, 0, 1, 0, 0 }, /* ATMTFCLK */
/* PC22 */ { 1, 1, 0, 0, 0, 0 }, /* ATMRFCLK */
/* PC21 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN RXCLK */
/* PC20 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN TXCLK */
/* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_CLK */
/* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII TX_CLK */
/* PC17 */ { 1, 0, 0, 1, 0, 0 }, /* PC17 */
/* PC16 */ { 1, 0, 0, 1, 0, 0 }, /* PC16 */
/* PC15 */ { 1, 0, 0, 1, 0, 0 }, /* PC15 */
/* PC14 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN *CD */
/* PC13 */ { 1, 0, 0, 1, 0, 0 }, /* PC13 */
/* PC12 */ { 1, 0, 0, 1, 0, 0 }, /* PC12 */
/* PC11 */ { 1, 0, 0, 1, 0, 0 }, /* PC11 */
/* PC10 */ { 1, 0, 0, 1, 0, 0 }, /* FCC2 MDC */
/* PC9 */ { 1, 0, 0, 1, 0, 0 }, /* FCC2 MDIO */
/* PC8 */ { 1, 0, 0, 1, 0, 0 }, /* PC8 */
/* PC7 */ { 1, 0, 0, 1, 0, 0 }, /* PC7 */
/* PC6 */ { 1, 0, 0, 1, 0, 0 }, /* PC6 */
/* PC5 */ { 1, 0, 0, 1, 0, 0 }, /* PC5 */
/* PC4 */ { 1, 0, 0, 1, 0, 0 }, /* PC4 */
/* PC3 */ { 1, 0, 0, 1, 0, 0 }, /* PC3 */
/* PC2 */ { 1, 0, 0, 1, 0, 1 }, /* ENET FDE */
/* PC1 */ { 1, 0, 0, 1, 0, 0 }, /* ENET DSQE */
/* PC0 */ { 1, 0, 0, 1, 0, 0 }, /* ENET LBK */
},
/* Port D */
{ /* conf ppar psor pdir podr pdat */
/* PD31 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN RxD */
/* PD30 */ { 1, 1, 1, 1, 0, 0 }, /* SCC1 EN TxD */
/* PD29 */ { 1, 1, 0, 1, 0, 0 }, /* SCC1 EN TENA */
/* PD28 */ { 1, 0, 0, 1, 0, 0 }, /* PD28 */
/* PD27 */ { 1, 0, 0, 1, 0, 0 }, /* PD27 */
/* PD26 */ { 1, 0, 0, 1, 0, 0 }, /* PD26 */
/* PD25 */ { 1, 0, 0, 1, 0, 0 }, /* PD25 */
/* PD24 */ { 1, 0, 0, 1, 0, 0 }, /* PD24 */
/* PD23 */ { 1, 0, 0, 1, 0, 0 }, /* PD23 */
/* PD22 */ { 1, 0, 0, 1, 0, 0 }, /* PD22 */
/* PD21 */ { 1, 0, 0, 1, 0, 0 }, /* PD21 */
/* PD20 */ { 1, 0, 0, 1, 0, 0 }, /* PD20 */
/* PD19 */ { 1, 0, 0, 1, 0, 0 }, /* PD19 */
/* PD18 */ { 1, 0, 0, 1, 0, 0 }, /* PD18 */
/* PD17 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */
/* PD16 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXPRTY */
#if defined(CONFIG_SOFT_I2C)
/* PD15 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SDA */
/* PD14 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SCL */
#else
#if defined(CONFIG_HARD_I2C)
/* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */
/* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */
#else /* normal I/O port pins */
/* PD15 */ { 1, 0, 0, 1, 0, 0 }, /* I2C SDA */
/* PD14 */ { 1, 0, 0, 1, 0, 0 }, /* I2C SCL */
#endif
#endif
/* PD13 */ { 1, 0, 0, 0, 0, 0 }, /* PD13 */
/* PD12 */ { 1, 0, 0, 0, 0, 0 }, /* PD12 */
/* PD11 */ { 1, 0, 0, 0, 0, 0 }, /* PD11 */
/* PD10 */ { 1, 0, 0, 0, 0, 0 }, /* PD10 */
/* PD9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC1 TXD */
/* PD8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC1 RXD */
/* PD7 */ { 1, 0, 0, 1, 0, 1 }, /* PD7 */
/* PD6 */ { 1, 0, 0, 1, 0, 1 }, /* PD6 */
/* PD5 */ { 1, 0, 0, 1, 0, 1 }, /* PD5 */
/* PD4 */ { 1, 0, 0, 1, 0, 1 }, /* PD4 */
/* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
/* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
}
};
/* ------------------------------------------------------------------------- */
/*
* Check Board Identity:
*/
int checkboard (void)
{
puts ("Board: EST SBC8260\n");
return 0;
}
/* ------------------------------------------------------------------------- */
long int initdram (int board_type)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile memctl8260_t *memctl = &immap->im_memctl;
volatile uchar c = 0, *ramaddr = (uchar *) (CFG_SDRAM_BASE + 0x8);
ulong psdmr = CFG_PSDMR;
int i;
/*
* Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
*
* "At system reset, initialization software must set up the
* programmable parameters in the memory controller banks registers
* (ORx, BRx, P/LSDMR). After all memory parameters are configured,
* system software should execute the following initialization sequence
* for each SDRAM device.
*
* 1. Issue a PRECHARGE-ALL-BANKS command
* 2. Issue eight CBR REFRESH commands
* 3. Issue a MODE-SET command to initialize the mode register
*
* The initial commands are executed by setting P/LSDMR[OP] and
* accessing the SDRAM with a single-byte transaction."
*
* The appropriate BRx/ORx registers have already been set when we
* get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE.
*/
memctl->memc_psrt = CFG_PSRT;
memctl->memc_mptpr = CFG_MPTPR;
memctl->memc_psdmr = psdmr | PSDMR_OP_PREA;
*ramaddr = c;
memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR;
for (i = 0; i < 8; i++)
*ramaddr = c;
memctl->memc_psdmr = psdmr | PSDMR_OP_MRW;
*ramaddr = c;
memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN;
*ramaddr = c;
/* return total ram size */
return (CFG_SDRAM0_SIZE * 1024 * 1024);
}
#ifdef CONFIG_MISC_INIT_R
/* ------------------------------------------------------------------------- */
int misc_init_r (void)
{
#ifdef CFG_LED_BASE
uchar ds = *(unsigned char *) (CFG_LED_BASE + 1);
uchar ss;
uchar tmp[64];
int res;
if ((ds != 0) && (ds != 0xff)) {
res = getenv_r ("ethaddr", tmp, sizeof (tmp));
if (res > 0) {
ss = ((ds >> 4) & 0x0f);
ss += ss < 0x0a ? '0' : ('a' - 10);
tmp[15] = ss;
ss = (ds & 0x0f);
ss += ss < 0x0a ? '0' : ('a' - 10);
tmp[16] = ss;
tmp[17] = '\0';
setenv ("ethaddr", tmp);
/* set the led to show the address */
*((unsigned char *) (CFG_LED_BASE + 1)) = ds;
}
}
#endif /* CFG_LED_BASE */
return (0);
}
#endif /* CONFIG_MISC_INIT_R */

23
board/shannon/config.mk Normal file
View File

@ -0,0 +1,23 @@
#
# LART board with SA1100 cpu
#
# see http://www.lart.tudelft.nl/ for more information on LART
#
#
# Tuxscreen has 4 banks of 4 MB DRAM each
#
# c000'0000
# c800'0000
# d000'0000
# d800'0000
#
# Linux-Kernel is expected to be at c000'8000, entry c000'8000
#
# we load ourself to d830'0000, the upper 1 MB of the last (4th) bank
#
# download areas is c800'0000
#
TEXT_BASE = 0xd8300000

94
board/shannon/memsetup.S Normal file
View File

@ -0,0 +1,94 @@
/*
* 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 @ cccccccf
mdcas1: .long 0xffc71c71 @ fffffffc
mdcas2: .long 0xffffffff @ ffffffff
mdcnfg: .long 0x0334b21f @ 9326991f
msc0: .long 0xfff84458 @ 42304230
msc1: .long 0xffffffff @ 20182018
mecr: .long 0x7fff7fff @ 01000000
/* 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

View File

@ -0,0 +1,33 @@
#
# (C) Copyright 2000
# Sysgo Real-Time Solutions, GmbH <www.elinos.com>
# Marius Groeger <mgroeger@sysgo.de>
#
# (C) Copyright 2000, 2001, 2002
# 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
#
#
# iad210 boards
#
TEXT_BASE = 0x08000000
/*TEXT_BASE = 0x00200000 */

25
board/smdk2400/config.mk Normal file
View File

@ -0,0 +1,25 @@
#
# (C) Copyright 2002
# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
#
# SAMSUNG board with S3C2400X (ARM920T) CPU
#
# see http://www.samsung.com/ for more information on SAMSUNG
#
#
# SAMSUNG has 1 bank of 32 MB DRAM
#
# 0C00'0000 to 0E00'0000
#
# Linux-Kernel is expected to be at 0cf0'0000, entry 0cf0'0000
# optionally with a ramdisk at 0c80'0000
#
# we load ourself to 0CF00000 (must be high enough not to be
# overwritten by the uncompessing Linux kernel)
#
# download area is 0C80'0000
#
TEXT_BASE = 0x0CF00000

165
board/smdk2400/memsetup.S Normal file
View File

@ -0,0 +1,165 @@
/*
* 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)
*
* Modified for the Samsung development board by
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <gj@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 <config.h>
#include <version.h>
/* some parameters for the board */
/*
*
* Taken from linux/arch/arm/boot/compressed/head-s3c2400.S
*
* Copyright (C) 2001 Samsung Electronics by chc, 010406
*
* S3C2400 specific tweaks.
*
*/
/* memory controller */
#define BWSCON 0x14000000
#define BANKCON3 0x14000010 /* for cs8900, ethernet */
/* Bank0 */
#define B0_Tacs 0x0 /* 0 clk */
#define B0_Tcos 0x0 /* 0 clk */
#define B0_Tacc 0x7 /* 14 clk */
#define B0_Tcoh 0x0 /* 0 clk */
#define B0_Tah 0x0 /* 0 clk */
#define B0_Tacp 0x0
#define B0_PMC 0x0 /* normal */
/* Bank1 */
#define B1_Tacs 0x0 /* 0 clk */
#define B1_Tcos 0x0 /* 0 clk */
#define B1_Tacc 0x7 /* 14 clk */
#define B1_Tcoh 0x0 /* 0 clk */
#define B1_Tah 0x0 /* 0 clk */
#define B1_Tacp 0x0
#define B1_PMC 0x0 /* normal */
/* Bank2 */
#define B2_Tacs 0x0 /* 0 clk */
#define B2_Tcos 0x0 /* 0 clk */
#define B2_Tacc 0x7 /* 14 clk */
#define B2_Tcoh 0x0 /* 0 clk */
#define B2_Tah 0x0 /* 0 clk */
#define B2_Tacp 0x0
#define B2_PMC 0x0 /* normal */
/* Bank3 - setup for the cs8900 */
#define B3_Tacs 0x0 /* 0 clk */
#define B3_Tcos 0x3 /* 4 clk */
#define B3_Tacc 0x7 /* 14 clk */
#define B3_Tcoh 0x1 /* 1 clk */
#define B3_Tah 0x0 /* 0 clk */
#define B3_Tacp 0x3 /* 6 clk */
#define B3_PMC 0x0 /* normal */
/* Bank4 */
#define B4_Tacs 0x0 /* 0 clk */
#define B4_Tcos 0x0 /* 0 clk */
#define B4_Tacc 0x7 /* 14 clk */
#define B4_Tcoh 0x0 /* 0 clk */
#define B4_Tah 0x0 /* 0 clk */
#define B4_Tacp 0x0
#define B4_PMC 0x0 /* normal */
/* Bank5 */
#define B5_Tacs 0x0 /* 0 clk */
#define B5_Tcos 0x0 /* 0 clk */
#define B5_Tacc 0x7 /* 14 clk */
#define B5_Tcoh 0x0 /* 0 clk */
#define B5_Tah 0x0 /* 0 clk */
#define B5_Tacp 0x0
#define B5_PMC 0x0 /* normal */
/* Bank6 */
#define B6_MT 0x3 /* SDRAM */
#define B6_Trcd 0x1 /* 3clk */
#define B6_SCAN 0x1 /* 9 bit */
/* Bank7 */
#define B7_MT 0x3 /* SDRAM */
#define B7_Trcd 0x1 /* 3clk */
#define B7_SCAN 0x1 /* 9 bit */
/* refresh parameter */
#define REFEN 0x1 /* enable refresh */
#define TREFMD 0x0 /* CBR(CAS before RAS)/auto refresh */
#define Trp 0x0 /* 2 clk */
#define Trc 0x3 /* 7 clk */
#define Tchr 0x2 /* 3 clk */
#define REFCNT 1113 /* period=15.6 us, HCLK=60Mhz, (2048+1-15.6*66) */
_TEXT_BASE:
.word TEXT_BASE
.globl memsetup
memsetup:
/* memory control configuration */
/* make r0 relative the current location so that it */
/* reads SMRDATA out of FLASH rather than memory ! */
ldr r0, =SMRDATA
ldr r1, _TEXT_BASE
sub r0, r0, r1
ldr r1, =BWSCON /* Bus Width Status Controller */
add r2, r0, #52
0:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne 0b
/* everything is fine now */
mov pc, lr
.ltorg
/* the literal pools origin */
SMRDATA:
.word 0x2211d114 /* d->Ethernet, BUSWIDTH=32 */
.word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) /* GCS0 */
.word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) /* GCS1 */
.word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) /* GCS2 */
.word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) /* GCS3 */
.word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) /* GCS4 */
.word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) /* GCS5 */
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) /* GCS6 */
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) /* GCS7 */
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
.word 0x10 /* BUSWIDTH=32, SCLK power saving mode, BANKSIZE 32M/32M */
.word 0x30 /* MRSR6, CL=3clk */
.word 0x30 /* MRSR7 */

25
board/smdk2410/config.mk Normal file
View File

@ -0,0 +1,25 @@
#
# (C) Copyright 2002
# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
#
# SAMSUNG SMDK2410 board with S3C2410X (ARM920T) cpu
#
# see http://www.samsung.com/ for more information on SAMSUNG
#
#
# SMDK2410 has 1 bank of 64 MB DRAM
#
# 3000'0000 to 3400'0000
#
# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
# optionally with a ramdisk at 3080'0000
#
# we load ourself to 33F0'0000
#
# download area is 3300'0000
#
TEXT_BASE = 0x33F00000

23
board/trab/config.mk Normal file
View File

@ -0,0 +1,23 @@
#
# (C) Copyright 2002
# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
#
# TRAB board with S3C2400X (arm920t) cpu
#
# see http://www.samsung.com/ for more information on SAMSUNG
#
#
# TRAB has 1 bank of 16 MB DRAM
#
# 0c00'0000 to 0e00'0000
#
# Linux-Kernel is expected to be at 0c00'8000, entry 0c00'8000
#
# we load ourself to 0cf0'0000
#
# download areas is 0c80'0000
#
TEXT_BASE = 0x0cf00000

168
board/trab/memsetup.S Normal file
View File

@ -0,0 +1,168 @@
/*
* 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)
*
* Modified for the TRAB board by
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <gj@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 <config.h>
#include <version.h>
/* some parameters for the board */
/*
*
* Copied from linux/arch/arm/boot/compressed/head-s3c2400.S
*
* Copyright (C) 2001 Samsung Electronics by chc, 010406
*
* TRAB specific tweaks.
*
*/
/* memory controller */
#define BWSCON 0x14000000
/* Bank0 */
#define B0_Tacs 0x0 /* 0 clk */
#define B0_Tcos 0x0 /* 0 clk */
#define B0_Tacc 0x7 /* 14 clk */
#define B0_Tcoh 0x0 /* 0 clk */
#define B0_Tah 0x0 /* 0 clk */
#define B0_Tacp 0x0
#define B0_PMC 0x0 /* normal */
/* Bank1 - SRAM */
#define B1_Tacs 0x0 /* 0 clk */
#define B1_Tcos 0x0 /* 0 clk */
#define B1_Tacc 0x7 /* 14 clk */
#define B1_Tcoh 0x0 /* 0 clk */
#define B1_Tah 0x0 /* 0 clk */
#define B1_Tacp 0x0
#define B1_PMC 0x0 /* normal */
/* Bank2 - CPLD */
#define B2_Tacs 0x0 /* 0 clk */
#define B2_Tcos 0x4 /* 4 clk */
#define B2_Tacc 0x7 /* 14 clk */
#define B2_Tcoh 0x4 /* 4 clk */
#define B2_Tah 0x0 /* 0 clk */
#define B2_Tacp 0x0
#define B2_PMC 0x0 /* normal */
/* Bank3 - setup for the cs8900 */
#define B3_Tacs 0x3 /* 4 clk */
#define B3_Tcos 0x3 /* 4 clk */
#define B3_Tacc 0x7 /* 14 clk */
#define B3_Tcoh 0x1 /* 1 clk */
#define B3_Tah 0x0 /* 0 clk */
#define B3_Tacp 0x3 /* 6 clk */
#define B3_PMC 0x0 /* normal */
/* Bank4 */
#define B4_Tacs 0x0 /* 0 clk */
#define B4_Tcos 0x0 /* 0 clk */
#define B4_Tacc 0x7 /* 14 clk */
#define B4_Tcoh 0x0 /* 0 clk */
#define B4_Tah 0x0 /* 0 clk */
#define B4_Tacp 0x0
#define B4_PMC 0x0 /* normal */
/* Bank5 */
#define B5_Tacs 0x0 /* 0 clk */
#define B5_Tcos 0x0 /* 0 clk */
#define B5_Tacc 0x7 /* 14 clk */
#define B5_Tcoh 0x0 /* 0 clk */
#define B5_Tah 0x0 /* 0 clk */
#define B5_Tacp 0x0
#define B5_PMC 0x0 /* normal */
/* Bank6 */
#define B6_MT 0x3 /* SDRAM */
#define B6_Trcd 0x1 /* 2clk */
#define B6_SCAN 0x0 /* 8 bit */
/* Bank7 */
#define B7_MT 0x3 /* SDRAM */
#define B7_Trcd 0x1 /* 2clk */
#define B7_SCAN 0x0 /* 8 bit */
/* refresh parameter */
#define REFEN 0x1 /* enable refresh */
#define TREFMD 0x0 /* CBR(CAS before RAS)/auto refresh */
#define Trp 0x0 /* 2 clk */
#define Trc 0x3 /* 7 clk */
#define Tchr 0x2 /* 3 clk */
#ifdef CONFIG_TRAB_50MHZ
#define REFCNT 1269 /* period=15.6 us, HCLK=50Mhz, (2048+1-15.6*50) */
#else
#define REFCNT 1011 /* period=15.6 us, HCLK=66.5Mhz, (2048+1-15.6*66.5) */
#endif
_TEXT_BASE:
.word TEXT_BASE
.globl memsetup
memsetup:
/* memory control configuration */
/* make r0 relative the current location so that it */
/* reads SMRDATA out of FLASH rather than memory ! */
ldr r0, =SMRDATA
ldr r1, _TEXT_BASE
sub r0, r0, r1
ldr r1, =BWSCON /* Bus Width Status Controller */
add r2, r0, #52
0:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne 0b
/* everything is fine now */
mov pc, lr
.ltorg
/* the literal pools origin */
SMRDATA:
.word 0x2211d644 /* d->Ethernet, 6->CPLD, 4->SRAM, 4->FLASH */
.word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) /* GCS0 */
.word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) /* GCS1 */
.word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) /* GCS2 */
.word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) /* GCS3 */
.word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) /* GCS4 */
.word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) /* GCS5 */
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) /* GCS6 */
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) /* GCS7 */
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
.word 0x17 /* BUSWIDTH=32, SCLK power saving mode, BANKSIZE 16M/16M */
.word 0x30 /* MRSR6, CL=3clk */
.word 0x30 /* MRSR7 */

491
board/utx8245/flash.c Normal file
View File

@ -0,0 +1,491 @@
/*
* (C) Copyright 2001
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2002
* Gregory E. Allen, gallen@arlut.utexas.edu
* Matthew E. Karger, karger@arlut.utexas.edu
* Applied Research Laboratories, The University of Texas at Austin
*
* 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 <mpc824x.h>
#include <asm/processor.h>
#define ROM_CS0_START 0xFF800000
#define ROM_CS1_START 0xFF000000
#if defined(CFG_ENV_IS_IN_FLASH)
# ifndef CFG_ENV_ADDR
# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
# endif
# ifndef CFG_ENV_SIZE
# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
# endif
# ifndef CFG_ENV_SECT_SIZE
# define CFG_ENV_SECT_SIZE CFG_ENV_SIZE
# endif
#endif
#define FLASH_BANK_SIZE 0x200000
#define MAIN_SECT_SIZE 0x10000
#define SECT_SIZE_32KB 0x8000
#define SECT_SIZE_8KB 0x2000
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
static int write_word (flash_info_t *info, ulong dest, ulong data);
static __inline__ unsigned long get_msr(void)
{ unsigned long msr;
__asm__ __volatile__ ("mfmsr %0" : "=r" (msr) :);
return msr;
}
static __inline__ void set_msr(unsigned long msr)
{
__asm__ __volatile__ ("mtmsr %0" : : "r" (msr));
}
/*flash command address offsets*/
#define ADDR0 (0x555)
#define ADDR1 (0xAAA)
#define ADDR3 (0x001)
#define FLASH_WORD_SIZE unsigned char
/*---------------------------------------------------------------------*/
/*#define DEBUG_FLASH 1 */
/*---------------------------------------------------------------------*/
unsigned long flash_init(void)
{
int i, j;
ulong size = 0;
unsigned char manuf_id, device_id;
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
{
vu_char *addr = (vu_char *)(CFG_FLASH_BASE + i * FLASH_BANK_SIZE);
addr[0x555] = 0xAA; /* 3 cycles to read device info. See */
addr[0x2AA] = 0x55; /* AM29LV116D datasheet for list of */
addr[0x555] = 0x90; /* available commands. */
manuf_id = addr[0];
device_id = addr[1];
#if defined DEBUG_FLASH
printf("manuf_id = %x, device_id = %x\n", manuf_id, device_id);
#endif
if ( (manuf_id == (uchar)(AMD_MANUFACT)) &&
( device_id == AMD_ID_LV116DT))
{
flash_info[i].flash_id = ((FLASH_MAN_AMD & FLASH_VENDMASK) << 16) |
(AMD_ID_LV116DT & FLASH_TYPEMASK);
} else {
flash_info[i].flash_id = FLASH_UNKNOWN;
addr[0] = (long)0xFFFFFFFF;
goto Done;
}
#if defined DEBUG_FLASH
printf ("flash_id = 0x%08lX\n", flash_info[i].flash_id);
#endif
addr[0] = (long)0xFFFFFFFF;
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);
for (j = 0; j < flash_info[i].sector_count; j++)
{
if (j < (CFG_MAX_FLASH_SECT - 3) )
flash_info[i].start[j] = CFG_FLASH_BASE + i * FLASH_BANK_SIZE +
j * MAIN_SECT_SIZE;
else if (j == (CFG_MAX_FLASH_SECT - 3) )
flash_info[i].start[j] = flash_info[i].start[j-1] + SECT_SIZE_32KB;
else
flash_info[i].start[j] = flash_info[i].start[j-1] + SECT_SIZE_8KB;
}
size += flash_info[i].size;
}
/* Protect monitor and environment sectors
*/
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
flash_protect(FLAG_PROTECT_SET, CFG_MONITOR_BASE,
CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1, &flash_info[0]);
#endif
#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
flash_protect(FLAG_PROTECT_SET, CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
#endif
Done:
return size;
}
/*-----------------------------------------------------------------------
*/
void flash_print_info(flash_info_t *info)
{
static const char unk[] = "Unknown";
const char *mfct = unk, *type = unk;
unsigned int i;
if(info->flash_id != FLASH_UNKNOWN)
{
switch(info->flash_id & FLASH_VENDMASK)
{
case FLASH_MAN_AMD: mfct = "AMD"; break;
case FLASH_MAN_FUJ: mfct = "FUJITSU"; break;
case FLASH_MAN_STM: mfct = "STM"; break;
case FLASH_MAN_SST: mfct = "SST"; break;
case FLASH_MAN_BM: mfct = "Bright Microelectonics"; break;
case FLASH_MAN_INTEL: mfct = "Intel"; break;
}
switch(info->flash_id & FLASH_TYPEMASK)
{
case FLASH_AM040: type = "AM29F040B (512K * 8, uniform sector size)"; break;
case FLASH_AM400B: type = "AM29LV400B (4 Mbit, bottom boot sect)"; break;
case FLASH_AM400T: type = "AM29LV400T (4 Mbit, top boot sector)"; break;
case FLASH_AM800B: type = "AM29LV800B (8 Mbit, bottom boot sect)"; break;
case FLASH_AM800T: type = "AM29LV800T (8 Mbit, top boot sector)"; break;
case FLASH_AM160T: type = "AM29LV160T (16 Mbit, top boot sector)"; break;
case FLASH_AM320B: type = "AM29LV320B (32 Mbit, bottom boot sect)"; break;
case FLASH_AM320T: type = "AM29LV320T (32 Mbit, top boot sector)"; break;
case FLASH_STM800AB: type = "M29W800AB (8 Mbit, bottom boot sect)"; break;
case FLASH_SST800A: type = "SST39LF/VF800 (8 Mbit, uniform sector size)"; break;
case FLASH_SST160A: type = "SST39LF/VF160 (16 Mbit, uniform sector size)"; break;
}
}
printf(
"\n Brand: %s Type: %s\n"
" Size: %lu KB in %d Sectors\n",
mfct,
type,
info->size >> 10,
info->sector_count
);
printf (" Sector Start Addresses:");
for (i = 0; i < info->sector_count; i++)
{
unsigned long size;
unsigned int erased;
unsigned long * flash = (unsigned long *) info->start[i];
/*
* Check if whole sector is erased
*/
size =
(i != (info->sector_count - 1)) ?
(info->start[i + 1] - info->start[i]) >> 2 :
(info->start[0] + info->size - info->start[i]) >> 2;
for(
flash = (unsigned long *) info->start[i], erased = 1;
(flash != (unsigned long *) info->start[i] + size) && erased;
flash++
)
erased = *flash == ~0x0UL;
printf(
"%s %08lX %s %s",
(i % 5) ? "" : "\n ",
info->start[i],
erased ? "E" : " ",
info->protect[i] ? "RO" : " "
);
}
puts("\n");
return;
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]);
int flag, prot, sect, l_sect;
ulong start, now, last;
unsigned char sh8b;
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_MAN_STM | FLASH_AMD_COMP))) {
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;
/* Check the ROM CS */
if ((info->start[0] >= ROM_CS1_START) && (info->start[0] < ROM_CS0_START))
sh8b = 3;
else
sh8b = 0;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA;
addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055;
addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00800080;
addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA;
addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055;
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++)
{
if (info->protect[sect] == 0)
{ /* not protected */
addr = (FLASH_WORD_SIZE *)(info->start[0] + (
(info->start[sect] - info->start[0]) << sh8b));
if (info->flash_id & FLASH_MAN_SST)
{
addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA;
addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055;
addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00800080;
addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA;
addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055;
addr[0] = (FLASH_WORD_SIZE)0x00500050; /* block erase */
udelay(30000); /* wait 30 ms */
}
else
addr[0] = (FLASH_WORD_SIZE)0x00300030; /* sector erase */
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 = (FLASH_WORD_SIZE *)(info->start[0] + (
(info->start[l_sect] - info->start[0]) << sh8b));
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 */
serial_putc ('.');
last = now;
}
}
DONE:
/* 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;
volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *)&data;
ulong start;
int flag;
int i;
unsigned char sh8b;
/* Check the ROM CS */
if ((info->start[0] >= ROM_CS1_START) && (info->start[0] < ROM_CS0_START))
sh8b = 3;
else
sh8b = 0;
dest2 = (FLASH_WORD_SIZE *)(((dest - info->start[0]) << sh8b) +
info->start[0]);
/* Check if Flash is (sufficiently) erased */
if ((*dest2 & (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 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA;
addr2[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055;
addr2[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00A000A0;
dest2[i << sh8b] = data2[i];
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* data polling for D7 */
start = get_timer (0);
while ((dest2[i << sh8b] & (FLASH_WORD_SIZE)0x00800080) !=
(data2[i] & (FLASH_WORD_SIZE)0x00800080)) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
return (1);
}
}
}
return (0);
}
/*-----------------------------------------------------------------------
*/

730
board/walnut405/flash.c Normal file
View File

@ -0,0 +1,730 @@
/*
* (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
*/
#include <common.h>
#include <ppc4xx.h>
#include <asm/processor.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);
#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
/*-----------------------------------------------------------------------
*/
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((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]);
/* Monitor protection ON by default */
(void)flash_protect(FLAG_PROTECT_SET,
FLASH_BASE0_PRELIM,
FLASH_BASE0_PRELIM+CFG_MONITOR_LEN-1,
&flash_info[0]);
size_b1 = 0 ;
flash_info[0].size = size_b0;
}
/* 2 banks */
else
{
size_b1 = flash_get_size((vu_long *)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((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;
}/* 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 address table */
if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
(info->flash_id == FLASH_AM040)){
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;
}
}
}
}
/*-----------------------------------------------------------------------
*/
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_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 ");
#if 0 /* test-only */
printf (" %08lX%s",
info->start[i],
info->protect[i] ? " (RO)" : " "
#else
printf (" %08lX%s%s",
info->start[i],
erased ? " E" : " ",
info->protect[i] ? "RO " : " "
#endif
);
}
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;
/* 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;
#ifdef CONFIG_ADCIOP
value = addr2[2];
#else
value = addr2[0];
#endif
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 */
/* printf("\ndev_code=%x\n", value); */
#else
value = addr2[1]; /* device ID */
#endif
switch (value) {
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)){
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); /* CLH */
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);
}
/*-----------------------------------------------------------------------
*/

99
board/walnut405/init.S Normal file
View File

@ -0,0 +1,99 @@
/*------------------------------------------------------------------------------+ */
/* */
/* 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 <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:
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 and SRAM) initialization */
/*----------------------------------------------------------------------- */
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,0xFFF1 /* BAS=0xFFF,BS=0x0(1MB),BU=0x3(R/W), */
ori r4,r4,0x8000 /* BW=0x0( 8 bits) */
mtdcr ebccfgd,r4
blr
/*----------------------------------------------------------------------------- */
/* Function: sdram_init */
/* Description: Dummy implementation here - done in C later */
/*----------------------------------------------------------------------------- */
.globl sdram_init
sdram_init:
blr

1103
common/cmd_boot.c Normal file

File diff suppressed because it is too large Load Diff

3461
common/hush.c Normal file

File diff suppressed because it is too large Load Diff

381
cpu/74xx_7xx/cache.S Normal file
View File

@ -0,0 +1,381 @@
#include <config.h>
#include <mpc74xx.h>
#include <version.h>
#include <ppc_asm.tmpl>
#include <ppc_defs.h>
#include <asm/cache.h>
#include <asm/mmu.h>
#ifndef CACHE_LINE_SIZE
# define CACHE_LINE_SIZE L1_CACHE_BYTES
#endif
#if CACHE_LINE_SIZE == 128
#define LG_CACHE_LINE_SIZE 7
#elif CACHE_LINE_SIZE == 32
#define LG_CACHE_LINE_SIZE 5
#elif CACHE_LINE_SIZE == 16
#define LG_CACHE_LINE_SIZE 4
#elif CACHE_LINE_SIZE == 8
#define LG_CACHE_LINE_SIZE 3
#else
# error "Invalid cache line size!"
#endif
/*
* Invalidate L1 instruction cache.
*/
_GLOBAL(invalidate_l1_instruction_cache)
mfspr r3,PVR
rlwinm r3,r3,16,16,31
cmpi 0,r3,1
beqlr /* for 601, do nothing */
/* 603/604 processor - use invalidate-all bit in HID0 */
mfspr r3,HID0
ori r3,r3,HID0_ICFI
mtspr HID0,r3
isync
blr
/*
* Invalidate L1 data cache.
*/
_GLOBAL(invalidate_l1_data_cache)
mfspr r3,HID0
ori r3,r3,HID0_DCFI
mtspr HID0,r3
isync
blr
/*
* Flush data cache.
*/
_GLOBAL(flush_data_cache)
lis r3,0
lis r5,CACHE_LINE_SIZE
flush:
cmp 0,1,r3,r5
bge done
lwz r5,0(r3)
lis r5,CACHE_LINE_SIZE
addi r3,r3,0x4
b flush
done:
blr
/*
* Write any modified data cache blocks out to memory
* and invalidate the corresponding instruction cache blocks.
* This is a no-op on the 601.
*
* flush_icache_range(unsigned long start, unsigned long stop)
*/
_GLOBAL(flush_icache_range)
mfspr r5,PVR
rlwinm r5,r5,16,16,31
cmpi 0,r5,1
beqlr /* for 601, do nothing */
li r5,CACHE_LINE_SIZE-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
srwi. r4,r4,LG_CACHE_LINE_SIZE
beqlr
mtctr r4
mr r6,r3
1: dcbst 0,r3
addi r3,r3,CACHE_LINE_SIZE
bdnz 1b
sync /* wait for dcbst's to get to ram */
mtctr r4
2: icbi 0,r6
addi r6,r6,CACHE_LINE_SIZE
bdnz 2b
sync /* additional sync needed on g4 */
isync
blr
/*
* Write any modified data cache blocks out to memory.
* Does not invalidate the corresponding cache lines (especially for
* any corresponding instruction cache).
*
* clean_dcache_range(unsigned long start, unsigned long stop)
*/
_GLOBAL(clean_dcache_range)
li r5,CACHE_LINE_SIZE-1
andc r3,r3,r5 /* align r3 down to cache line */
subf r4,r3,r4 /* r4 = offset of stop from start of cache line */
add r4,r4,r5 /* r4 += cache_line_size-1 */
srwi. r4,r4,LG_CACHE_LINE_SIZE /* r4 = number of cache lines to flush */
beqlr /* if r4 == 0 return */
mtctr r4 /* ctr = r4 */
sync
1: dcbst 0,r3
addi r3,r3,CACHE_LINE_SIZE
bdnz 1b
sync /* wait for dcbst's to get to ram */
blr
/*
* Write any modified data cache blocks out to memory
* and invalidate the corresponding instruction cache blocks.
*
* flush_dcache_range(unsigned long start, unsigned long stop)
*/
_GLOBAL(flush_dcache_range)
li r5,CACHE_LINE_SIZE-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
srwi. r4,r4,LG_CACHE_LINE_SIZE
beqlr
mtctr r4
sync
1: dcbf 0,r3
addi r3,r3,CACHE_LINE_SIZE
bdnz 1b
sync /* wait for dcbf's to get to ram */
blr
/*
* Like above, but invalidate the D-cache. This is used by the 8xx
* to invalidate the cache so the PPC core doesn't get stale data
* from the CPM (no cache snooping here :-).
*
* invalidate_dcache_range(unsigned long start, unsigned long stop)
*/
_GLOBAL(invalidate_dcache_range)
li r5,CACHE_LINE_SIZE-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
srwi. r4,r4,LG_CACHE_LINE_SIZE
beqlr
mtctr r4
sync
1: dcbi 0,r3
addi r3,r3,CACHE_LINE_SIZE
bdnz 1b
sync /* wait for dcbi's to get to ram */
blr
/*
* Flush a particular page from the data cache to RAM.
* Note: this is necessary because the instruction cache does *not*
* snoop from the data cache.
* This is a no-op on the 601 which has a unified cache.
*
* void __flush_page_to_ram(void *page)
*/
_GLOBAL(__flush_page_to_ram)
mfspr r5,PVR
rlwinm r5,r5,16,16,31
cmpi 0,r5,1
beqlr /* for 601, do nothing */
rlwinm r3,r3,0,0,19 /* Get page base address */
li r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */
mtctr r4
mr r6,r3
0: dcbst 0,r3 /* Write line to ram */
addi r3,r3,CACHE_LINE_SIZE
bdnz 0b
sync
mtctr r4
1: icbi 0,r6
addi r6,r6,CACHE_LINE_SIZE
bdnz 1b
sync
isync
blr
/*
* Flush a particular page from the instruction cache.
* Note: this is necessary because the instruction cache does *not*
* snoop from the data cache.
* This is a no-op on the 601 which has a unified cache.
*
* void __flush_icache_page(void *page)
*/
_GLOBAL(__flush_icache_page)
mfspr r5,PVR
rlwinm r5,r5,16,16,31
cmpi 0,r5,1
beqlr /* for 601, do nothing */
li r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */
mtctr r4
1: icbi 0,r3
addi r3,r3,CACHE_LINE_SIZE
bdnz 1b
sync
isync
blr
/*
* Clear a page using the dcbz instruction, which doesn't cause any
* memory traffic (except to write out any cache lines which get
* displaced). This only works on cacheable memory.
*/
_GLOBAL(clear_page)
li r0,4096/CACHE_LINE_SIZE
mtctr r0
1: dcbz 0,r3
addi r3,r3,CACHE_LINE_SIZE
bdnz 1b
blr
/*
* Enable L1 Instruction cache
*/
_GLOBAL(icache_enable)
mfspr r3, HID0
li r5, HID0_ICFI|HID0_ILOCK
andc r3, r3, r5
ori r3, r3, HID0_ICE
ori r5, r3, HID0_ICFI
mtspr HID0, r5
mtspr HID0, r3
isync
blr
/*
* Disable L1 Instruction cache
*/
_GLOBAL(icache_disable)
mfspr r3, HID0
li r5, 0
ori r5, r5, HID0_ICE
andc r3, r3, r5
mtspr HID0, r3
isync
blr
/*
* Is instruction cache enabled?
*/
_GLOBAL(icache_status)
mfspr r3, HID0
andi. r3, r3, HID0_ICE
blr
_GLOBAL(l1dcache_enable)
mfspr r3, HID0
li r5, HID0_DCFI|HID0_DLOCK
andc r3, r3, r5
mtspr HID0, r3 /* no invalidate, unlock */
ori r3, r3, HID0_DCE
ori r5, r3, HID0_DCFI
mtspr HID0, r5 /* enable + invalidate */
mtspr HID0, r3 /* enable */
sync
blr
/*
* Enable data cache(s) - L1 and optionally L2
* Calls l2cache_enable. LR saved in r5
*/
_GLOBAL(dcache_enable)
mfspr r3, HID0
li r5, HID0_DCFI|HID0_DLOCK
andc r3, r3, r5
mtspr HID0, r3 /* no invalidate, unlock */
ori r3, r3, HID0_DCE
ori r5, r3, HID0_DCFI
mtspr HID0, r5 /* enable + invalidate */
mtspr HID0, r3 /* enable */
sync
#ifdef CFG_L2
mflr r5
bl l2cache_enable /* uses r3 and r4 */
sync
mtlr r5
#endif
blr
/*
* Disable data cache(s) - L1 and optionally L2
* Calls flush_data_cache and l2cache_disable_no_flush.
* LR saved in r4
*/
_GLOBAL(dcache_disable)
mflr r4 /* save link register */
bl flush_data_cache /* uses r3 and r5 */
sync
mfspr r3, HID0
li r5, HID0_DCFI|HID0_DLOCK
andc r3, r3, r5
mtspr HID0, r3 /* no invalidate, unlock */
li r5, HID0_DCE|HID0_DCFI
andc r3, r3, r5 /* no enable, no invalidate */
mtspr HID0, r3
sync
#ifdef CFG_L2
bl l2cache_disable_no_flush /* uses r3 */
#endif
mtlr r4 /* restore link register */
blr
/*
* Is data cache enabled?
*/
_GLOBAL(dcache_status)
mfspr r3, HID0
andi. r3, r3, HID0_DCE
blr
/*
* Invalidate L2 cache using L2I and polling L2IP
*/
_GLOBAL(l2cache_invalidate)
sync
oris r3, r3, L2CR_L2I@h
sync
mtspr l2cr, r3
sync
invl2:
mfspr r3, l2cr
andi. r3, r3, L2CR_L2IP
bne invl2
/* turn off the global invalidate bit */
mfspr r3, l2cr
rlwinm r3, r3, 0, 11, 9
sync
mtspr l2cr, r3
sync
blr
/*
* Enable L2 cache
* Calls l2cache_invalidate. LR is saved in r4
*/
_GLOBAL(l2cache_enable)
mflr r4 /* save link register */
bl l2cache_invalidate /* uses r3 */
sync
lis r3, L2_ENABLE@h
ori r3, r3, L2_ENABLE@l
mtspr l2cr, r3
isync
mtlr r4 /* restore link register */
blr
/*
* Disable L2 cache
* Calls flush_data_cache. LR is saved in r4
*/
_GLOBAL(l2cache_disable)
mflr r4 /* save link register */
bl flush_data_cache /* uses r3 and r5 */
sync
mtlr r4 /* restore link register */
l2cache_disable_no_flush: /* provide way to disable L2 w/o flushing */
lis r3, L2_INIT@h
ori r3, r3, L2_INIT@l
mtspr l2cr, r3
isync
blr

429
cpu/arm720t/start.S Normal file
View File

@ -0,0 +1,429 @@
/*
* armboot - Startup Code for ARM720 CPU-core
*
* Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
* Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <config.h>
#include <version.h>
/*
*************************************************************************
*
* Jump vector table as in table 3.1 in [1]
*
*************************************************************************
*/
.globl _start
_start: b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
.balignl 16,0xdeadbeef
/*
*************************************************************************
*
* Startup Code (reset vector)
*
* do important init only if we don't start from memory!
* relocate armboot to ram
* setup stack
* jump to second stage
*
*************************************************************************
*/
/*
* CFG_MEM_END is in the board dependent config-file (configs/config_BOARD.h)
*/
_TEXT_BASE:
.word TEXT_BASE
.globl _armboot_start
_armboot_start:
.word _start
/*
* Note: _armboot_end_data and _armboot_end are defined
* by the (board-dependent) linker script.
* _armboot_end_data is the first usable FLASH address after armboot
*/
.globl _armboot_end_data
_armboot_end_data:
.word armboot_end_data
.globl _armboot_end
_armboot_end:
.word armboot_end
/*
* _armboot_real_end is the first usable RAM address behind armboot
* and the various stacks
*/
.globl _armboot_real_end
_armboot_real_end:
.word 0x0badc0de
#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de
/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif
/*
* the actual reset code
*/
reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0x13
msr cpsr,r0
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
#ifdef CONFIG_INIT_CRITICAL
bl cpu_init_crit
#endif
relocate:
/*
* relocate armboot to RAM
*/
adr r0, _start /* r0 <- current position of code */
ldr r2, _armboot_start
ldr r3, _armboot_end
sub r2, r3, r2 /* r2 <- size of armboot */
ldr r1, _TEXT_BASE /* r1 <- destination address */
add r2, r0, r2 /* r2 <- source end address */
/*
* r0 = source address
* r1 = target address
* r2 = source end address
*/
copy_loop:
ldmia r0!, {r3-r10}
stmia r1!, {r3-r10}
cmp r0, r2
ble copy_loop
/* set up the stack */
ldr r0, _armboot_end
add r0, r0, #CONFIG_STACKSIZE
sub sp, r0, #12 /* leave 3 words for abort-stack */
ldr pc, _start_armboot
_start_armboot: .word start_armboot
/*
*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/
/* Interupt-Controller base addresses */
INTMR1: .word 0x80000280 @ 32 bit size
INTMR2: .word 0x80001280 @ 16 bit size
INTMR3: .word 0x80002280 @ 8 bit size
/* SYSCONs */
SYSCON1: .word 0x80000100
SYSCON2: .word 0x80001100
SYSCON3: .word 0x80002200
#define CLKCTL 0x6 /* mask */
#define CLKCTL_18 0x0 /* 18.432 MHz */
#define CLKCTL_36 0x2 /* 36.864 MHz */
#define CLKCTL_49 0x4 /* 49.152 MHz */
#define CLKCTL_73 0x6 /* 73.728 MHz */
cpu_init_crit:
/*
* mask all IRQs by clearing all bits in the INTMRs
*/
mov r1, #0x00
ldr r0, INTMR1
str r1, [r0]
ldr r0, INTMR2
str r1, [r0]
ldr r0, INTMR3
str r1, [r0]
/*
* flush v4 I/D caches
*/
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
/*
* disable MMU stuff and caches
*/
mrc p15,0,r0,c1,c0
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0, #0x0000008f @ clear bits 7, 3:0 (B--- WCAM)
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
mcr p15,0,r0,c1,c0
#ifdef CONFIG_ARM7_REVD
/* set clock speed */
/* !!! we run @ 36 MHz due to a hardware flaw in Rev. D processors */
/* !!! not doing DRAM refresh properly! */
ldr r0, SYSCON3
ldr r1, [r0]
bic r1, r1, #CLKCTL
orr r1, r1, #CLKCTL_36
str r1, [r0]
#endif
/*
* before relocating, we have to setup RAM timing
* because memory timing is board-dependend, you will
* find a memsetup.S in your board directory.
*/
mov ip, lr
bl memsetup
mov lr, ip
mov pc, lr
/*
*************************************************************************
*
* Interrupt handling
*
*************************************************************************
*/
@
@ IRQ stack frame.
@
#define S_FRAME_SIZE 72
#define S_OLD_R0 68
#define S_PSR 64
#define S_PC 60
#define S_LR 56
#define S_SP 52
#define S_IP 48
#define S_FP 44
#define S_R10 40
#define S_R9 36
#define S_R8 32
#define S_R7 28
#define S_R6 24
#define S_R5 20
#define S_R4 16
#define S_R3 12
#define S_R2 8
#define S_R1 4
#define S_R0 0
#define MODE_SVC 0x13
#define I_BIT 0x80
/*
* use bad_save_user_regs for abort/prefetch/undef/swi ...
* use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
*/
.macro bad_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12
add r8, sp, #S_PC
ldr r2, _armboot_end
add r2, r2, #CONFIG_STACKSIZE
sub r2, r2, #8
ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0
add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
add r5, sp, #S_SP
mov r1, lr
stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_r
mov r0, sp
.endm
.macro irq_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12
add r8, sp, #S_PC
stmdb r8, {sp, lr}^ @ Calling SP, LR
str lr, [r8, #0] @ Save calling PC
mrs r6, spsr
str r6, [r8, #4] @ Save CPSR
str r0, [r8, #8] @ Save OLD_R0
mov r0, sp
.endm
.macro irq_restore_user_regs
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
mov r0, r0
ldr lr, [sp, #S_PC] @ Get PC
add sp, sp, #S_FRAME_SIZE
subs pc, lr, #4 @ return & move spsr_svc into cpsr
.endm
.macro get_bad_stack
ldr r13, _armboot_end @ setup our mode stack
add r13, r13, #CONFIG_STACKSIZE @ resides at top of normal stack
sub r13, r13, #8
str lr, [r13] @ save caller lr / spsr
mrs lr, spsr
str lr, [r13, #4]
mov r13, #MODE_SVC @ prepare SVC-Mode
msr spsr_c, r13
mov lr, pc
movs pc, lr
.endm
.macro get_irq_stack @ setup IRQ stack
ldr sp, IRQ_STACK_START
.endm
.macro get_fiq_stack @ setup FIQ stack
ldr sp, FIQ_STACK_START
.endm
/*
* exception handlers
*/
.align 5
undefined_instruction:
get_bad_stack
bad_save_user_regs
bl do_undefined_instruction
.align 5
software_interrupt:
get_bad_stack
bad_save_user_regs
bl do_software_interrupt
.align 5
prefetch_abort:
get_bad_stack
bad_save_user_regs
bl do_prefetch_abort
.align 5
data_abort:
get_bad_stack
bad_save_user_regs
bl do_data_abort
.align 5
not_used:
get_bad_stack
bad_save_user_regs
bl do_not_used
#ifdef CONFIG_USE_IRQ
.align 5
irq:
get_irq_stack
irq_save_user_regs
bl do_irq
irq_restore_user_regs
.align 5
fiq:
get_fiq_stack
/* someone ought to write a more effiction fiq_save_user_regs */
irq_save_user_regs
bl do_fiq
irq_restore_user_regs
#else
.align 5
irq:
get_bad_stack
bad_save_user_regs
bl do_irq
.align 5
fiq:
get_bad_stack
bad_save_user_regs
bl do_fiq
#endif
.align 5
.globl reset_cpu
reset_cpu:
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate cache
mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4)
mrc p15, 0, ip, c1, c0, 0 @ get ctrl register
bic ip, ip, #0x000f @ ............wcam
bic ip, ip, #0x2100 @ ..v....s........
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
mov pc, r0

475
cpu/arm920t/start.S Normal file
View File

@ -0,0 +1,475 @@
/*
* armboot - Startup Code for ARM920 CPU-core
*
* Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
* Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
* Copyright (c) 2002 Gary Jennejohn <gj@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 <config.h>
#include <version.h>
/*
*************************************************************************
*
* Jump vector table as in table 3.1 in [1]
*
*************************************************************************
*/
.globl _start
_start: b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
.balignl 16,0xdeadbeef
/*
*************************************************************************
*
* Startup Code (reset vector)
*
* do important init only if we don't start from memory!
* relocate armboot to ram
* setup stack
* jump to second stage
*
*************************************************************************
*/
/*
* CFG_MEM_END is in the board dependent config-file (configs/config_BOARD.h)
*/
_TEXT_BASE:
.word TEXT_BASE
.globl _armboot_start
_armboot_start:
.word _start
/*
* Note: _armboot_end_data and _armboot_end are defined
* by the (board-dependent) linker script.
* _armboot_end_data is the first usable FLASH address after armboot
*/
.globl _armboot_end_data
_armboot_end_data:
.word armboot_end_data
.globl _armboot_end
_armboot_end:
.word armboot_end
/*
* _armboot_real_end is the first usable RAM address behind armboot
* and the various stacks
*/
.globl _armboot_real_end
_armboot_real_end:
.word 0x0badc0de
#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de
/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif
/*
* the actual reset code
*/
reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0
/* turn off the watchdog */
#if defined(CONFIG_S3C2400)
#define pWTCON 0x15300000
/* Interupt-Controller base addresses */
#define INTMSK 0x14400008
/* clock divisor register */
#define CLKDIVN 0x14800014
#elif defined(CONFIG_S3C2410)
#define pWTCON 0x53000000
/* Interupt-Controller base addresses */
#define INTMSK 0x4A000008
#define INTSUBMSK 0x4A00001C
/* clock divisor register */
#define CLKDIVN 0x4C000014
#endif
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
/*
* mask all IRQs by setting all bits in the INTMR - default
*/
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
#if defined(CONFIG_S3C2410)
ldr r1, =0x3ff
ldr r0, =INTSUBMSK
str r1, [r0]
#endif
/* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
#ifdef CONFIG_INIT_CRITICAL
bl cpu_init_crit
#endif
relocate:
/*
* relocate armboot to RAM
*/
adr r0, _start /* r0 <- current position of code */
ldr r2, _armboot_start
ldr r3, _armboot_end
sub r2, r3, r2 /* r2 <- size of armboot */
ldr r1, _TEXT_BASE /* r1 <- destination address */
add r2, r0, r2 /* r2 <- source end address */
/*
* r0 = source address
* r1 = target address
* r2 = source end address
*/
copy_loop:
ldmia r0!, {r3-r10}
stmia r1!, {r3-r10}
cmp r0, r2
ble copy_loop
#if 0
/* try doing this stuff after the relocation */
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
/*
* mask all IRQs by setting all bits in the INTMR - default
*/
mov r1, #0xffffffff
ldr r0, =INTMR
str r1, [r0]
/* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
/* END stuff after relocation */
#endif
/* set up the stack */
ldr r0, _armboot_end
add r0, r0, #CONFIG_STACKSIZE
sub sp, r0, #12 /* leave 3 words for abort-stack */
ldr pc, _start_armboot
_start_armboot: .word start_armboot
/*
*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/
cpu_init_crit:
/*
* flush v4 I/D caches
*/
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
mcr p15, 0, r0, c1, c0, 0
/*
* before relocating, we have to setup RAM timing
* because memory timing is board-dependend, you will
* find a memsetup.S in your board directory.
*/
mov ip, lr
bl memsetup
mov lr, ip
mov pc, lr
/*
*************************************************************************
*
* Interrupt handling
*
*************************************************************************
*/
@
@ IRQ stack frame.
@
#define S_FRAME_SIZE 72
#define S_OLD_R0 68
#define S_PSR 64
#define S_PC 60
#define S_LR 56
#define S_SP 52
#define S_IP 48
#define S_FP 44
#define S_R10 40
#define S_R9 36
#define S_R8 32
#define S_R7 28
#define S_R6 24
#define S_R5 20
#define S_R4 16
#define S_R3 12
#define S_R2 8
#define S_R1 4
#define S_R0 0
#define MODE_SVC 0x13
#define I_BIT 0x80
/*
* use bad_save_user_regs for abort/prefetch/undef/swi ...
* use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
*/
.macro bad_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12
add r8, sp, #S_PC
ldr r2, _armboot_end
add r2, r2, #CONFIG_STACKSIZE
sub r2, r2, #8
ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0
add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
add r5, sp, #S_SP
mov r1, lr
stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_r
mov r0, sp
.endm
.macro irq_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12
add r8, sp, #S_PC
stmdb r8, {sp, lr}^ @ Calling SP, LR
str lr, [r8, #0] @ Save calling PC
mrs r6, spsr
str r6, [r8, #4] @ Save CPSR
str r0, [r8, #8] @ Save OLD_R0
mov r0, sp
.endm
.macro irq_restore_user_regs
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
mov r0, r0
ldr lr, [sp, #S_PC] @ Get PC
add sp, sp, #S_FRAME_SIZE
subs pc, lr, #4 @ return & move spsr_svc into cpsr
.endm
.macro get_bad_stack
ldr r13, _armboot_end @ setup our mode stack
add r13, r13, #CONFIG_STACKSIZE @ resides at top of normal stack
sub r13, r13, #8
str lr, [r13] @ save caller lr / spsr
mrs lr, spsr
str lr, [r13, #4]
mov r13, #MODE_SVC @ prepare SVC-Mode
@ msr spsr_c, r13
msr spsr, r13
mov lr, pc
movs pc, lr
.endm
.macro get_irq_stack @ setup IRQ stack
ldr sp, IRQ_STACK_START
.endm
.macro get_fiq_stack @ setup FIQ stack
ldr sp, FIQ_STACK_START
.endm
/*
* exception handlers
*/
.align 5
undefined_instruction:
get_bad_stack
bad_save_user_regs
bl do_undefined_instruction
.align 5
software_interrupt:
get_bad_stack
bad_save_user_regs
bl do_software_interrupt
.align 5
prefetch_abort:
get_bad_stack
bad_save_user_regs
bl do_prefetch_abort
.align 5
data_abort:
get_bad_stack
bad_save_user_regs
bl do_data_abort
.align 5
not_used:
get_bad_stack
bad_save_user_regs
bl do_not_used
#ifdef CONFIG_USE_IRQ
.align 5
irq:
get_irq_stack
irq_save_user_regs
bl do_irq
irq_restore_user_regs
.align 5
fiq:
get_fiq_stack
/* someone ought to write a more effiction fiq_save_user_regs */
irq_save_user_regs
bl do_fiq
irq_restore_user_regs
#else
.align 5
irq:
get_bad_stack
bad_save_user_regs
bl do_irq
.align 5
fiq:
get_bad_stack
bad_save_user_regs
bl do_fiq
#endif
.align 5
.globl reset_cpu
reset_cpu:
#ifdef CONFIG_S3C2400
bl disable_interrupts
ldr r1, _rWTCON
ldr r2, _rWTCNT
/* Disable watchdog */
mov r3, #0x0000
str r3, [r1]
/* Initialize watchdog timer count register */
mov r3, #0x0001
str r3, [r2]
/* Enable watchdog timer; assert reset at timer timeout */
mov r3, #0x0021
str r3, [r1]
_loop_forever:
b _loop_forever
_rWTCON:
.word 0x15300000
_rWTCNT:
.word 0x15300008
#else /* ! CONFIG_S3C2400 */
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate cache
mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4)
mrc p15, 0, ip, c1, c0, 0 @ get ctrl register
bic ip, ip, #0x000f @ ............wcam
bic ip, ip, #0x2100 @ ..v....s........
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
mov pc, r0
#endif /* CONFIG_S3C2400 */

358
cpu/mpc8260/ether_scc.c Normal file
View File

@ -0,0 +1,358 @@
/*
* MPC8260 SCC Ethernet
*
* Copyright (c) 2000 MontaVista Software, Inc. Dan Malek (dmalek@jlc.net)
*
* (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright (c) 2001
* Advent Networks, Inc. <http://www.adventnetworks.com>
* Jay Monkman <jtm@smoothsmoothie.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/cpm_8260.h>
#include <mpc8260.h>
#include <net.h>
#include <command.h>
#include <config.h>
#if defined(CONFIG_ETHER_ON_SCC) && (CONFIG_COMMANDS & CFG_CMD_NET)
#if (CONFIG_ETHER_INDEX == 1)
# define PROFF_ENET PROFF_SCC1
# define CPM_CR_ENET_PAGE CPM_CR_SCC1_PAGE
# define CPM_CR_ENET_SBLOCK CPM_CR_SCC1_SBLOCK
# define CMXSCR_MASK (CMXSCR_SC1 |\
CMXSCR_RS1CS_MSK |\
CMXSCR_TS1CS_MSK)
#elif (CONFIG_ETHER_INDEX == 2)
# define PROFF_ENET PROFF_SCC2
# define CPM_CR_ENET_PAGE CPM_CR_SCC2_PAGE
# define CPM_CR_ENET_SBLOCK CPM_CR_SCC2_SBLOCK
# define CMXSCR_MASK (CMXSCR_SC2 |\
CMXSCR_RS2CS_MSK |\
CMXSCR_TS2CS_MSK)
#elif (CONFIG_ETHER_INDEX == 3)
# define PROFF_ENET PROFF_SCC3
# define CPM_CR_ENET_PAGE CPM_CR_SCC3_PAGE
# define CPM_CR_ENET_SBLOCK CPM_CR_SCC3_SBLOCK
# define CMXSCR_MASK (CMXSCR_SC3 |\
CMXSCR_RS3CS_MSK |\
CMXSCR_TS3CS_MSK)
#elif (CONFIG_ETHER_INDEX == 4)
# define PROFF_ENET PROFF_SCC4
# define CPM_CR_ENET_PAGE CPM_CR_SCC4_PAGE
# define CPM_CR_ENET_SBLOCK CPM_CR_SCC4_SBLOCK
# define CMXSCR_MASK (CMXSCR_SC4 |\
CMXSCR_RS4CS_MSK |\
CMXSCR_TS4CS_MSK)
#endif
/* Ethernet Transmit and Receive Buffers */
#define DBUF_LENGTH 1520
#define TX_BUF_CNT 2
#define TOUT_LOOP 1000000
static char txbuf[TX_BUF_CNT][ DBUF_LENGTH ];
static uint rxIdx; /* index of the current RX buffer */
static uint txIdx; /* index of the current TX buffer */
/*
* SCC Ethernet Tx and Rx buffer descriptors allocated at the
* immr->udata_bd address on Dual-Port RAM
* Provide for Double Buffering
*/
typedef volatile struct CommonBufferDescriptor {
cbd_t rxbd[PKTBUFSRX]; /* Rx BD */
cbd_t txbd[TX_BUF_CNT]; /* Tx BD */
} RTXBD;
static RTXBD *rtx;
int eth_send(volatile void *packet, int length)
{
int i;
int result = 0;
if (length <= 0) {
printf("scc: bad packet size: %d\n", length);
goto out;
}
for(i=0; rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY; i++) {
if (i >= TOUT_LOOP) {
printf("scc: tx buffer not ready\n");
goto out;
}
}
rtx->txbd[txIdx].cbd_bufaddr = (uint)packet;
rtx->txbd[txIdx].cbd_datlen = length;
rtx->txbd[txIdx].cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_LAST |
BD_ENET_TX_WRAP);
for(i=0; rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY; i++) {
if (i >= TOUT_LOOP) {
printf("scc: tx error\n");
goto out;
}
}
/* return only status bits */
result = rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_STATS;
out:
return result;
}
int eth_rx(void)
{
int length;
for (;;)
{
if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
length = -1;
break; /* nothing received - leave for() loop */
}
length = rtx->rxbd[rxIdx].cbd_datlen;
if (rtx->rxbd[rxIdx].cbd_sc & 0x003f)
{
printf("err: %x\n", rtx->rxbd[rxIdx].cbd_sc);
}
else
{
/* Pass the packet up to the protocol layers. */
NetReceive(NetRxPackets[rxIdx], length - 4);
}
/* Give the buffer back to the SCC. */
rtx->rxbd[rxIdx].cbd_datlen = 0;
/* wrap around buffer index when necessary */
if ((rxIdx + 1) >= PKTBUFSRX) {
rtx->rxbd[PKTBUFSRX - 1].cbd_sc = (BD_ENET_RX_WRAP |
BD_ENET_RX_EMPTY);
rxIdx = 0;
}
else {
rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
rxIdx++;
}
}
return length;
}
/**************************************************************
*
* SCC Ethernet Initialization Routine
*
*************************************************************/
int eth_init(bd_t *bis)
{
int i;
volatile immap_t *immr = (immap_t *)CFG_IMMR;
scc_enet_t *pram_ptr;
uint dpaddr;
rxIdx = 0;
txIdx = 0;
/* assign static pointer to BD area */
dpaddr = m8260_cpm_dpalloc(sizeof(RTXBD) + 2, 16);
rtx = (RTXBD *)&immr->im_dprambase[dpaddr];
/* 24.21 - (1-3): ioports have been set up already */
/* 24.21 - (4,5): connect SCC's tx and rx clocks, use NMSI for SCC */
immr->im_cpmux.cmx_uar = 0;
immr->im_cpmux.cmx_scr = ( (immr->im_cpmux.cmx_scr & ~CMXSCR_MASK) |
CFG_CMXSCR_VALUE);
/* 24.21 (6) write RBASE and TBASE to parameter RAM */
pram_ptr = (scc_enet_t *)&(immr->im_dprambase[PROFF_ENET]);
pram_ptr->sen_genscc.scc_rbase = (unsigned int)(&rtx->rxbd[0]);
pram_ptr->sen_genscc.scc_tbase = (unsigned int)(&rtx->txbd[0]);
pram_ptr->sen_genscc.scc_rfcr = 0x18; /* Nrml Ops and Mot byte ordering */
pram_ptr->sen_genscc.scc_tfcr = 0x18; /* Mot byte ordering, Nrml access */
pram_ptr->sen_genscc.scc_mrblr = DBUF_LENGTH; /* max. package len 1520 */
pram_ptr->sen_cpres = ~(0x0); /* Preset CRC */
pram_ptr->sen_cmask = 0xdebb20e3; /* Constant Mask for CRC */
/* 24.21 - (7): Write INIT RX AND TX PARAMETERS to CPCR */
while(immr->im_cpm.cp_cpcr & CPM_CR_FLG);
immr->im_cpm.cp_cpcr = mk_cr_cmd(CPM_CR_ENET_PAGE,
CPM_CR_ENET_SBLOCK,
0x0c,
CPM_CR_INIT_TRX) | CPM_CR_FLG;
/* 24.21 - (8-18): Set up parameter RAM */
pram_ptr->sen_crcec = 0x0; /* Error Counter CRC (unused) */
pram_ptr->sen_alec = 0x0; /* Align Error Counter (unused) */
pram_ptr->sen_disfc = 0x0; /* Discard Frame Counter (unused) */
pram_ptr->sen_pads = 0x8888; /* Short Frame PAD Characters */
pram_ptr->sen_retlim = 15; /* Retry Limit Threshold */
pram_ptr->sen_maxflr = 1518; /* MAX Frame Length Register */
pram_ptr->sen_minflr = 64; /* MIN Frame Length Register */
pram_ptr->sen_maxd1 = DBUF_LENGTH; /* MAX DMA1 Length Register */
pram_ptr->sen_maxd2 = DBUF_LENGTH; /* MAX DMA2 Length Register */
pram_ptr->sen_gaddr1 = 0x0; /* Group Address Filter 1 (unused) */
pram_ptr->sen_gaddr2 = 0x0; /* Group Address Filter 2 (unused) */
pram_ptr->sen_gaddr3 = 0x0; /* Group Address Filter 3 (unused) */
pram_ptr->sen_gaddr4 = 0x0; /* Group Address Filter 4 (unused) */
# define ea bis->bi_enetaddr
pram_ptr->sen_paddrh = (ea[5] << 8) + ea[4];
pram_ptr->sen_paddrm = (ea[3] << 8) + ea[2];
pram_ptr->sen_paddrl = (ea[1] << 8) + ea[0];
# undef ea
pram_ptr->sen_pper = 0x0; /* Persistence (unused) */
pram_ptr->sen_iaddr1 = 0x0; /* Individual Address Filter 1 (unused) */
pram_ptr->sen_iaddr2 = 0x0; /* Individual Address Filter 2 (unused) */
pram_ptr->sen_iaddr3 = 0x0; /* Individual Address Filter 3 (unused) */
pram_ptr->sen_iaddr4 = 0x0; /* Individual Address Filter 4 (unused) */
pram_ptr->sen_taddrh = 0x0; /* Tmp Address (MSB) (unused) */
pram_ptr->sen_taddrm = 0x0; /* Tmp Address (unused) */
pram_ptr->sen_taddrl = 0x0; /* Tmp Address (LSB) (unused) */
/* 24.21 - (19): Initialize RxBD */
for (i = 0; i < PKTBUFSRX; i++)
{
rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
rtx->rxbd[i].cbd_datlen = 0; /* Reset */
rtx->rxbd[i].cbd_bufaddr = (uint)NetRxPackets[i];
}
rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
/* 24.21 - (20): Initialize TxBD */
for (i = 0; i < TX_BUF_CNT; i++)
{
rtx->txbd[i].cbd_sc = (BD_ENET_TX_PAD |
BD_ENET_TX_LAST |
BD_ENET_TX_TC);
rtx->txbd[i].cbd_datlen = 0; /* Reset */
rtx->txbd[i].cbd_bufaddr = (uint)&txbuf[i][0];
}
rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
/* 24.21 - (21): Write 0xffff to SCCE */
immr->im_scc[CONFIG_ETHER_INDEX-1].scc_scce = ~(0x0);
/* 24.21 - (22): Write to SCCM to enable TXE, RXF, TXB events */
immr->im_scc[CONFIG_ETHER_INDEX-1].scc_sccm = (SCCE_ENET_TXE |
SCCE_ENET_RXF |
SCCE_ENET_TXB);
/* 24.21 - (23): we don't use ethernet interrupts */
/* 24.21 - (24): Clear GSMR_H to enable normal operations */
immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrh = 0;
/* 24.21 - (25): Clear GSMR_L to enable normal operations */
immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl = (SCC_GSMRL_TCI |
SCC_GSMRL_TPL_48 |
SCC_GSMRL_TPP_10 |
SCC_GSMRL_MODE_ENET);
/* 24.21 - (26): Initialize DSR */
immr->im_scc[CONFIG_ETHER_INDEX-1].scc_dsr = 0xd555;
/* 24.21 - (27): Initialize PSMR2
*
* Settings:
* CRC = 32-Bit CCITT
* NIB = Begin searching for SFD 22 bits after RENA
* FDE = Full Duplex Enable
* BRO = Reject broadcast packets
* PROMISCOUS = Catch all packets regardless of dest. MAC adress
*/
immr->im_scc[CONFIG_ETHER_INDEX-1].scc_psmr = SCC_PSMR_ENCRC |
SCC_PSMR_NIB22 |
#if defined(CONFIG_SCC_ENET_FULL_DUPLEX)
SCC_PSMR_FDE |
#endif
#if defined(CONFIG_SCC_ENET_NO_BROADCAST)
SCC_PSMR_BRO |
#endif
#if defined(CONFIG_SCC_ENET_PROMISCOUS)
SCC_PSMR_PRO |
#endif
0;
/* 24.21 - (28): Write to GSMR_L to enable SCC */
immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl |= (SCC_GSMRL_ENR |
SCC_GSMRL_ENT);
return 1;
}
void eth_halt(void)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl &= ~(SCC_GSMRL_ENR |
SCC_GSMRL_ENT);
}
#if 0
void restart(void)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
immr->im_cpm.cp_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl |= (SCC_GSMRL_ENR |
SCC_GSMRL_ENT);
}
#endif
#endif /* CONFIG_ETHER_ON_SCC && CFG_CMD_NET */

78
cpu/ppc4xx/kgdb.S Normal file
View File

@ -0,0 +1,78 @@
/*
* Copyright (C) 2000 Murray Jensen <Murray.Jensen@cmst.csiro.au>
*
* 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 <command.h>
#include <ppc4xx.h>
#include <version.h>
#define CONFIG_405GP 1 /* needed for Linux kernel header files */
#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>
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
/*
* cache flushing routines for kgdb
*/
.globl kgdb_flush_cache_all
kgdb_flush_cache_all:
/* icache */
iccci r0,r0 /* iccci invalidates the entire I cache */
/* dcache */
addi r6,0,0x0000 /* clear GPR 6 */
addi r7,r0, 128 /* do loop for # of dcache lines */
/* NOTE: dccci invalidates both */
mtctr r7 /* ways in the D cache */
..dcloop:
dccci 0,r6 /* invalidate line */
addi r6,r6, 32 /* bump to next line */
bdnz ..dcloop
blr
.globl kgdb_flush_cache_range
kgdb_flush_cache_range:
li r5,CFG_CACHELINE_SIZE-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
srwi. r4,r4,CFG_CACHELINE_SHIFT
beqlr
mtctr r4
mr r6,r3
1: dcbst 0,r3
addi r3,r3,CFG_CACHELINE_SIZE
bdnz 1b
sync /* wait for dcbst's to get to ram */
mtctr r4
2: icbi 0,r6
addi r6,r6,CFG_CACHELINE_SIZE
bdnz 2b
SYNC
blr
#endif /* CFG_CMD_KGDB */

10
cpu/ppc4xx/resetvec.S Normal file
View File

@ -0,0 +1,10 @@
/* Copyright MontaVista Software Incorporated, 2000 */
.section .resetvec,"ax"
#if defined(CONFIG_440)
b _start_440
#else
b _start
#endif

808
cpu/ppc4xx/serial.c Normal file
View File

@ -0,0 +1,808 @@
/*
* (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
*/
/*------------------------------------------------------------------------------+ */
/*
* 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
*/
/*------------------------------------------------------------------------------- */
#include <common.h>
#include <commproc.h>
#include <asm/processor.h>
#include <watchdog.h>
#include "vecnum.h"
#if CONFIG_SERIAL_SOFTWARE_FIFO
#include <malloc.h>
#endif
/*****************************************************************************/
#ifdef CONFIG_IOP480
#define SPU_BASE 0x40000000
#define spu_LineStat_rc 0x00 /* Line Status Register (Read/Clear) */
#define spu_LineStat_w 0x04 /* Line Status Register (Set) */
#define spu_Handshk_rc 0x08 /* Handshake Status Register (Read/Clear) */
#define spu_Handshk_w 0x0c /* Handshake Status Register (Set) */
#define spu_BRateDivh 0x10 /* Baud rate divisor high */
#define spu_BRateDivl 0x14 /* Baud rate divisor low */
#define spu_CtlReg 0x18 /* Control Register */
#define spu_RxCmd 0x1c /* Rx Command Register */
#define spu_TxCmd 0x20 /* Tx Command Register */
#define spu_RxBuff 0x24 /* Rx data buffer */
#define spu_TxBuff 0x24 /* Tx data buffer */
/*-----------------------------------------------------------------------------+
| Line Status Register.
+-----------------------------------------------------------------------------*/
#define asyncLSRport1 0x40000000
#define asyncLSRport1set 0x40000004
#define asyncLSRDataReady 0x80
#define asyncLSRFramingError 0x40
#define asyncLSROverrunError 0x20
#define asyncLSRParityError 0x10
#define asyncLSRBreakInterrupt 0x08
#define asyncLSRTxHoldEmpty 0x04
#define asyncLSRTxShiftEmpty 0x02
/*-----------------------------------------------------------------------------+
| Handshake Status Register.
+-----------------------------------------------------------------------------*/
#define asyncHSRport1 0x40000008
#define asyncHSRport1set 0x4000000c
#define asyncHSRDsr 0x80
#define asyncLSRCts 0x40
/*-----------------------------------------------------------------------------+
| Control Register.
+-----------------------------------------------------------------------------*/
#define asyncCRport1 0x40000018
#define asyncCRNormal 0x00
#define asyncCRLoopback 0x40
#define asyncCRAutoEcho 0x80
#define asyncCRDtr 0x20
#define asyncCRRts 0x10
#define asyncCRWordLength7 0x00
#define asyncCRWordLength8 0x08
#define asyncCRParityDisable 0x00
#define asyncCRParityEnable 0x04
#define asyncCREvenParity 0x00
#define asyncCROddParity 0x02
#define asyncCRStopBitsOne 0x00
#define asyncCRStopBitsTwo 0x01
#define asyncCRDisableDtrRts 0x00
/*-----------------------------------------------------------------------------+
| Receiver Command Register.
+-----------------------------------------------------------------------------*/
#define asyncRCRport1 0x4000001c
#define asyncRCRDisable 0x00
#define asyncRCREnable 0x80
#define asyncRCRIntDisable 0x00
#define asyncRCRIntEnabled 0x20
#define asyncRCRDMACh2 0x40
#define asyncRCRDMACh3 0x60
#define asyncRCRErrorInt 0x10
#define asyncRCRPauseEnable 0x08
/*-----------------------------------------------------------------------------+
| Transmitter Command Register.
+-----------------------------------------------------------------------------*/
#define asyncTCRport1 0x40000020
#define asyncTCRDisable 0x00
#define asyncTCREnable 0x80
#define asyncTCRIntDisable 0x00
#define asyncTCRIntEnabled 0x20
#define asyncTCRDMACh2 0x40
#define asyncTCRDMACh3 0x60
#define asyncTCRTxEmpty 0x10
#define asyncTCRErrorInt 0x08
#define asyncTCRStopPause 0x04
#define asyncTCRBreakGen 0x02
/*-----------------------------------------------------------------------------+
| Miscellanies defines.
+-----------------------------------------------------------------------------*/
#define asyncTxBufferport1 0x40000024
#define asyncRxBufferport1 0x40000024
#define asyncDLABLsbport1 0x40000014
#define asyncDLABMsbport1 0x40000010
#define asyncXOFFchar 0x13
#define asyncXONchar 0x11
/*
* Minimal serial functions needed to use one of the SMC ports
* as serial console interface.
*/
int serial_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
volatile char val;
unsigned short br_reg;
br_reg = ((((CONFIG_CPUCLOCK * 1000000) / 16) / gd->baudrate) - 1);
/*
* Init onboard UART
*/
out8 (SPU_BASE + spu_LineStat_rc, 0x78); /* Clear all bits in Line Status Reg */
out8 (SPU_BASE + spu_BRateDivl, (br_reg & 0x00ff)); /* Set baud rate divisor... */
out8 (SPU_BASE + spu_BRateDivh, ((br_reg & 0xff00) >> 8)); /* ... */
out8 (SPU_BASE + spu_CtlReg, 0x08); /* Set 8 bits, no parity and 1 stop bit */
out8 (SPU_BASE + spu_RxCmd, 0xb0); /* Enable Rx */
out8 (SPU_BASE + spu_TxCmd, 0x9c); /* Enable Tx */
out8 (SPU_BASE + spu_Handshk_rc, 0xff); /* Clear Handshake */
val = in8 (SPU_BASE + spu_RxBuff); /* Dummy read, to clear receiver */
return (0);
}
void serial_setbrg (void)
{
DECLARE_GLOBAL_DATA_PTR;
unsigned short br_reg;
br_reg = ((((CONFIG_CPUCLOCK * 1000000) / 16) / gd->baudrate) - 1);
out8 (SPU_BASE + spu_BRateDivl, (br_reg & 0x00ff)); /* Set baud rate divisor... */
out8 (SPU_BASE + spu_BRateDivh, ((br_reg & 0xff00) >> 8)); /* ... */
}
void serial_putc (const char c)
{
if (c == '\n')
serial_putc ('\r');
/* load status from handshake register */
if (in8 (SPU_BASE + spu_Handshk_rc) != 00)
out8 (SPU_BASE + spu_Handshk_rc, 0xff); /* Clear Handshake */
out8 (SPU_BASE + spu_TxBuff, c); /* Put char */
while ((in8 (SPU_BASE + spu_LineStat_rc) & 04) != 04) {
if (in8 (SPU_BASE + spu_Handshk_rc) != 00)
out8 (SPU_BASE + spu_Handshk_rc, 0xff); /* Clear Handshake */
}
}
void serial_puts (const char *s)
{
while (*s) {
serial_putc (*s++);
}
}
int serial_getc ()
{
unsigned char status = 0;
while (1) {
status = in8 (asyncLSRport1);
if ((status & asyncLSRDataReady) != 0x0) {
break;
}
if ((status & ( asyncLSRFramingError |
asyncLSROverrunError |
asyncLSRParityError |
asyncLSRBreakInterrupt )) != 0) {
(void) out8 (asyncLSRport1,
asyncLSRFramingError |
asyncLSROverrunError |
asyncLSRParityError |
asyncLSRBreakInterrupt );
}
}
return (0x000000ff & (int) in8 (asyncRxBufferport1));
}
int serial_tstc ()
{
unsigned char status;
status = in8 (asyncLSRport1);
if ((status & asyncLSRDataReady) != 0x0) {
return (1);
}
if ((status & ( asyncLSRFramingError |
asyncLSROverrunError |
asyncLSRParityError |
asyncLSRBreakInterrupt )) != 0) {
(void) out8 (asyncLSRport1,
asyncLSRFramingError |
asyncLSROverrunError |
asyncLSRParityError |
asyncLSRBreakInterrupt);
}
return 0;
}
#endif /* CONFIG_IOP480 */
/*****************************************************************************/
#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440)
#if defined(CONFIG_440)
#define UART0_BASE CFG_PERIPHERAL_BASE + 0x00000200
#define UART1_BASE CFG_PERIPHERAL_BASE + 0x00000300
#define CR0_MASK 0x3fff0000
#define CR0_EXTCLK_ENA 0x00600000
#define CR0_UDIV_POS 16
#else
#define UART_BASE_PTR 0xF800FFFC; /* pointer to uart base */
#define UART0_BASE 0xef600300
#define UART1_BASE 0xef600400
#define CR0_MASK 0x00001fff
#define CR0_EXTCLK_ENA 0x00000c00
#define CR0_UDIV_POS 1
#endif
#define UART_RBR 0x00
#define UART_THR 0x00
#define UART_IER 0x01
#define UART_IIR 0x02
#define UART_FCR 0x02
#define UART_LCR 0x03
#define UART_MCR 0x04
#define UART_LSR 0x05
#define UART_MSR 0x06
#define UART_SCR 0x07
#define UART_DLL 0x00
#define UART_DLM 0x01
/*-----------------------------------------------------------------------------+
| Line Status Register.
+-----------------------------------------------------------------------------*/
/*#define asyncLSRport1 UART0_BASE+0x05 */
#define asyncLSRDataReady1 0x01
#define asyncLSROverrunError1 0x02
#define asyncLSRParityError1 0x04
#define asyncLSRFramingError1 0x08
#define asyncLSRBreakInterrupt1 0x10
#define asyncLSRTxHoldEmpty1 0x20
#define asyncLSRTxShiftEmpty1 0x40
#define asyncLSRRxFifoError1 0x80
/*-----------------------------------------------------------------------------+
| Miscellanies defines.
+-----------------------------------------------------------------------------*/
/*#define asyncTxBufferport1 UART0_BASE+0x00 */
/*#define asyncRxBufferport1 UART0_BASE+0x00 */
#if CONFIG_SERIAL_SOFTWARE_FIFO
/*-----------------------------------------------------------------------------+
| Fifo
+-----------------------------------------------------------------------------*/
typedef struct {
char *rx_buffer;
ulong rx_put;
ulong rx_get;
} serial_buffer_t;
volatile static serial_buffer_t buf_info;
#endif
#if defined(CONFIG_440) && !defined(CFG_EXT_SERIAL_CLOCK)
static void serial_divs (int baudrate, unsigned long *pudiv,
unsigned short *pbdiv )
{
sys_info_t sysinfo;
unsigned long div; /* total divisor udiv * bdiv */
unsigned long umin; /* minimum udiv */
unsigned short diff; /* smallest diff */
unsigned long udiv; /* best udiv */
unsigned short idiff; /* current diff */
unsigned short ibdiv; /* current bdiv */
unsigned long i;
unsigned long est; /* current estimate */
get_sys_info( &sysinfo );
udiv = 32; /* Assume lowest possible serial clk */
div = sysinfo.freqPLB/(16*baudrate); /* total divisor */
umin = sysinfo.pllOpbDiv<<1; /* 2 x OPB divisor */
diff = 32; /* highest possible */
/* i is the test udiv value -- start with the largest
* possible (32) to minimize serial clock and constrain
* search to umin.
*/
for( i = 32; i > umin; i-- ){
ibdiv = div/i;
est = i * ibdiv;
idiff = (est > div) ? (est-div) : (div-est);
if( idiff == 0 ){
udiv = i;
break; /* can't do better */
}
else if( idiff < diff ){
udiv = i; /* best so far */
diff = idiff; /* update lowest diff*/
}
}
*pudiv = udiv;
*pbdiv = div/udiv;
}
#endif /* defined(CONFIG_440) && !defined(CFG_EXT_SERIAL_CLK */
/*
* Minimal serial functions needed to use one of the SMC ports
* as serial console interface.
*/
#if defined(CONFIG_440)
int serial_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
unsigned long reg;
unsigned long udiv;
unsigned short bdiv;
volatile char val;
#ifdef CFG_EXT_SERIAL_CLOCK
unsigned long tmp;
#endif
reg = mfdcr(cntrl0) & ~CR0_MASK;
#ifdef CFG_EXT_SERIAL_CLOCK
reg |= CR0_EXTCLK_ENA;
udiv = 1;
tmp = gd->baudrate * 16;
bdiv = (CFG_EXT_SERIAL_CLOCK + tmp / 2) / tmp;
#else
/* For 440, the cpu clock is on divider chain A, UART on divider
* chain B ... so cpu clock is irrelevant. Get the "optimized"
* values that are subject to the 1/2 opb clock constraint
*/
serial_divs (gd->baudrate, &udiv, &bdiv);
#endif
reg |= (udiv - 1) << CR0_UDIV_POS; /* set the UART divisor */
mtdcr (cntrl0, reg);
out8 (UART0_BASE + UART_LCR, 0x80); /* set DLAB bit */
out8 (UART0_BASE + UART_DLL, bdiv); /* set baudrate divisor */
out8 (UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */
out8 (UART0_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
out8 (UART0_BASE + UART_FCR, 0x00); /* disable FIFO */
out8 (UART0_BASE + UART_MCR, 0x00); /* no modem control DTR RTS */
val = in8 (UART0_BASE + UART_LSR); /* clear line status */
val = in8 (UART0_BASE + UART_RBR); /* read receive buffer */
out8 (UART0_BASE + UART_SCR, 0x00); /* set scratchpad */
out8 (UART0_BASE + UART_IER, 0x00); /* set interrupt enable reg */
return (0);
}
#else /* !defined(CONFIG_440) */
int serial_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
unsigned long reg;
unsigned long tmp;
unsigned long clk;
unsigned long udiv;
unsigned short bdiv;
volatile char val;
reg = mfdcr(cntrl0) & ~CR0_MASK;
#ifdef CFG_EXT_SERIAL_CLOCK
clk = CFG_EXT_SERIAL_CLOCK;
udiv = 1;
reg |= CR0_EXTCLK_ENA;
#else
clk = gd->cpu_clk;
#ifdef CFG_405_UART_ERRATA_59
udiv = 31; /* Errata 59: stuck at 31 */
#else
tmp = CFG_BASE_BAUD * 16;
udiv = (clk + tmp / 2) / tmp;
#endif
#endif
reg |= (udiv - 1) << CR0_UDIV_POS; /* set the UART divisor */
mtdcr (cntrl0, reg);
tmp = gd->baudrate * udiv * 16;
bdiv = (clk + tmp / 2) / tmp;
out8 (UART0_BASE + UART_LCR, 0x80); /* set DLAB bit */
out8 (UART0_BASE + UART_DLL, bdiv); /* set baudrate divisor */
out8 (UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */
out8 (UART0_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
out8 (UART0_BASE + UART_FCR, 0x00); /* disable FIFO */
out8 (UART0_BASE + UART_MCR, 0x00); /* no modem control DTR RTS */
val = in8 (UART0_BASE + UART_LSR); /* clear line status */
val = in8 (UART0_BASE + UART_RBR); /* read receive buffer */
out8 (UART0_BASE + UART_SCR, 0x00); /* set scratchpad */
out8 (UART0_BASE + UART_IER, 0x00); /* set interrupt enable reg */
return (0);
}
#endif /* if defined(CONFIG_440) */
void serial_setbrg (void)
{
DECLARE_GLOBAL_DATA_PTR;
unsigned long tmp;
unsigned long clk;
unsigned long udiv;
unsigned short bdiv;
#ifdef CFG_EXT_SERIAL_CLOCK
clk = CFG_EXT_SERIAL_CLOCK;
#else
clk = gd->cpu_clk;
#endif
udiv = ((mfdcr (cntrl0) & 0x3e) >> 1) + 1;
tmp = gd->baudrate * udiv * 16;
bdiv = (clk + tmp / 2) / tmp;
out8 (UART0_BASE + UART_LCR, 0x80); /* set DLAB bit */
out8 (UART0_BASE + UART_DLL, bdiv); /* set baudrate divisor */
out8 (UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */
out8 (UART0_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
}
void serial_putc (const char c)
{
int i;
if (c == '\n')
serial_putc ('\r');
/* check THRE bit, wait for transmiter available */
for (i = 1; i < 3500; i++) {
if ((in8 (UART0_BASE + UART_LSR) & 0x20) == 0x20)
break;
udelay (100);
}
out8 (UART0_BASE + UART_THR, c); /* put character out */
}
void serial_puts (const char *s)
{
while (*s) {
serial_putc (*s++);
}
}
int serial_getc ()
{
unsigned char status = 0;
while (1) {
#if defined(CONFIG_HW_WATCHDOG)
WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */
#endif /* CONFIG_HW_WATCHDOG */
status = in8 (UART0_BASE + UART_LSR);
if ((status & asyncLSRDataReady1) != 0x0) {
break;
}
if ((status & ( asyncLSRFramingError1 |
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1 )) != 0) {
out8 (UART0_BASE + UART_LSR,
asyncLSRFramingError1 |
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1);
}
}
return (0x000000ff & (int) in8 (UART0_BASE));
}
int serial_tstc ()
{
unsigned char status;
status = in8 (UART0_BASE + UART_LSR);
if ((status & asyncLSRDataReady1) != 0x0) {
return (1);
}
if ((status & ( asyncLSRFramingError1 |
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1 )) != 0) {
out8 (UART0_BASE + UART_LSR,
asyncLSRFramingError1 |
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1);
}
return 0;
}
#if CONFIG_SERIAL_SOFTWARE_FIFO
void serial_isr (void *arg)
{
int space;
int c;
const int rx_get = buf_info.rx_get;
int rx_put = buf_info.rx_put;
if (rx_get <= rx_put) {
space = CONFIG_SERIAL_SOFTWARE_FIFO - (rx_put - rx_get);
} else {
space = rx_get - rx_put;
}
while (serial_tstc ()) {
c = serial_getc ();
if (space) {
buf_info.rx_buffer[rx_put++] = c;
space--;
}
if (rx_put == CONFIG_SERIAL_SOFTWARE_FIFO)
rx_put = 0;
if (space < CONFIG_SERIAL_SOFTWARE_FIFO / 4) {
/* Stop flow by setting RTS inactive */
out8 (UART0_BASE + UART_MCR,
in8 (UART0_BASE + UART_MCR) & (0xFF ^ 0x02));
}
}
buf_info.rx_put = rx_put;
}
void serial_buffered_init (void)
{
serial_puts ("Switching to interrupt driven serial input mode.\n");
buf_info.rx_buffer = malloc (CONFIG_SERIAL_SOFTWARE_FIFO);
buf_info.rx_put = 0;
buf_info.rx_get = 0;
if (in8 (UART0_BASE + UART_MSR) & 0x10) {
serial_puts ("Check CTS signal present on serial port: OK.\n");
} else {
serial_puts ("WARNING: CTS signal not present on serial port.\n");
}
irq_install_handler ( VECNUM_U0 /*UART0 */ /*int vec */ ,
serial_isr /*interrupt_handler_t *handler */ ,
(void *) &buf_info /*void *arg */ );
/* Enable "RX Data Available" Interrupt on UART */
/* out8(UART0_BASE + UART_IER, in8(UART0_BASE + UART_IER) |0x01); */
out8 (UART0_BASE + UART_IER, 0x01);
/* Set DTR active */
out8 (UART0_BASE + UART_MCR, in8 (UART0_BASE + UART_MCR) | 0x01);
/* Start flow by setting RTS active */
out8 (UART0_BASE + UART_MCR, in8 (UART0_BASE + UART_MCR) | 0x02);
/* Setup UART FIFO: RX trigger level: 4 byte, Enable FIFO */
out8 (UART0_BASE + UART_FCR, (1 << 6) | 1);
}
void serial_buffered_putc (const char c)
{
/* Wait for CTS */
#if defined(CONFIG_HW_WATCHDOG)
while (!(in8 (UART0_BASE + UART_MSR) & 0x10))
WATCHDOG_RESET ();
#else
while (!(in8 (UART0_BASE + UART_MSR) & 0x10));
#endif
serial_putc (c);
}
void serial_buffered_puts (const char *s)
{
serial_puts (s);
}
int serial_buffered_getc (void)
{
int space;
int c;
int rx_get = buf_info.rx_get;
int rx_put;
#if defined(CONFIG_HW_WATCHDOG)
while (rx_get == buf_info.rx_put)
WATCHDOG_RESET ();
#else
while (rx_get == buf_info.rx_put);
#endif
c = buf_info.rx_buffer[rx_get++];
if (rx_get == CONFIG_SERIAL_SOFTWARE_FIFO)
rx_get = 0;
buf_info.rx_get = rx_get;
rx_put = buf_info.rx_put;
if (rx_get <= rx_put) {
space = CONFIG_SERIAL_SOFTWARE_FIFO - (rx_put - rx_get);
} else {
space = rx_get - rx_put;
}
if (space > CONFIG_SERIAL_SOFTWARE_FIFO / 2) {
/* Start flow by setting RTS active */
out8 (UART0_BASE + UART_MCR, in8 (UART0_BASE + UART_MCR) | 0x02);
}
return c;
}
int serial_buffered_tstc (void)
{
return (buf_info.rx_get != buf_info.rx_put) ? 1 : 0;
}
#endif /* CONFIG_SERIAL_SOFTWARE_FIFO */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
/*
AS HARNOIS : according to CONFIG_KGDB_SER_INDEX kgdb uses serial port
number 0 or number 1
- if CONFIG_KGDB_SER_INDEX = 1 => serial port number 0 :
configuration has been already done
- if CONFIG_KGDB_SER_INDEX = 2 => serial port number 1 :
configure port 1 for serial I/O with rate = CONFIG_KGDB_BAUDRATE
*/
#if (CONFIG_KGDB_SER_INDEX & 2)
void kgdb_serial_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
volatile char val;
unsigned short br_reg;
get_clocks ();
br_reg = (((((gd->cpu_clk / 16) / 18) * 10) / CONFIG_KGDB_BAUDRATE) +
5) / 10;
/*
* Init onboard 16550 UART
*/
out8 (UART1_BASE + UART_LCR, 0x80); /* set DLAB bit */
out8 (UART1_BASE + UART_DLL, (br_reg & 0x00ff)); /* set divisor for 9600 baud */
out8 (UART1_BASE + UART_DLM, ((br_reg & 0xff00) >> 8)); /* set divisor for 9600 baud */
out8 (UART1_BASE + UART_LCR, 0x03); /* line control 8 bits no parity */
out8 (UART1_BASE + UART_FCR, 0x00); /* disable FIFO */
out8 (UART1_BASE + UART_MCR, 0x00); /* no modem control DTR RTS */
val = in8 (UART1_BASE + UART_LSR); /* clear line status */
val = in8 (UART1_BASE + UART_RBR); /* read receive buffer */
out8 (UART1_BASE + UART_SCR, 0x00); /* set scratchpad */
out8 (UART1_BASE + UART_IER, 0x00); /* set interrupt enable reg */
}
void putDebugChar (const char c)
{
if (c == '\n')
serial_putc ('\r');
out8 (UART1_BASE + UART_THR, c); /* put character out */
/* check THRE bit, wait for transfer done */
while ((in8 (UART1_BASE + UART_LSR) & 0x20) != 0x20);
}
void putDebugStr (const char *s)
{
while (*s) {
serial_putc (*s++);
}
}
int getDebugChar (void)
{
unsigned char status = 0;
while (1) {
status = in8 (UART1_BASE + UART_LSR);
if ((status & asyncLSRDataReady1) != 0x0) {
break;
}
if ((status & ( asyncLSRFramingError1 |
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1 )) != 0) {
out8 (UART1_BASE + UART_LSR,
asyncLSRFramingError1 |
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1);
}
}
return (0x000000ff & (int) in8 (UART1_BASE));
}
void kgdb_interruptible (int yes)
{
return;
}
#else /* ! (CONFIG_KGDB_SER_INDEX & 2) */
void kgdb_serial_init (void)
{
serial_printf ("[on serial] ");
}
void putDebugChar (int c)
{
serial_putc (c);
}
void putDebugStr (const char *str)
{
serial_puts (str);
}
int getDebugChar (void)
{
return serial_getc ();
}
void kgdb_interruptible (int yes)
{
return;
}
#endif /* (CONFIG_KGDB_SER_INDEX & 2) */
#endif /* CFG_CMD_KGDB */
#endif /* CONFIG_405GP || CONFIG_405CR */

1764
cpu/ppc4xx/spd_sdram.c Normal file

File diff suppressed because it is too large Load Diff

158
cpu/sa1100/serial.c Normal file
View File

@ -0,0 +1,158 @@
/*
* (C) Copyright 2002
* Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Alex Zuepke <azu@sysgo.de>
*
* Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
*
* 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 <SA-1100.h>
void serial_setbrg (void)
{
DECLARE_GLOBAL_DATA_PTR;
unsigned int reg = 0;
if (gd->baudrate == 1200)
reg = 191;
else if (gd->baudrate == 9600)
reg = 23;
else if (gd->baudrate == 19200)
reg = 11;
else if (gd->baudrate == 38400)
reg = 5;
else if (gd->baudrate == 57600)
reg = 3;
else if (gd->baudrate == 115200)
reg = 1;
else
hang ();
#ifdef CONFIG_SERIAL1
/* Wait until port is ready ... */
while (Ser1UTSR1 & UTSR1_TBY) {
}
/* init serial serial 1 */
Ser1UTCR3 = 0x00;
Ser1UTSR0 = 0xff;
Ser1UTCR0 = (UTCR0_1StpBit | UTCR0_8BitData);
Ser1UTCR1 = 0;
Ser1UTCR2 = (u32) reg;
Ser1UTCR3 = (UTCR3_RXE | UTCR3_TXE);
#elif CONFIG_SERIAL3
/* Wait until port is ready ... */
while (Ser3UTSR1 & UTSR1_TBY) {
}
/* init serial serial 3 */
Ser3UTCR3 = 0x00;
Ser3UTSR0 = 0xff;
Ser3UTCR0 = (UTCR0_1StpBit | UTCR0_8BitData);
Ser3UTCR1 = 0;
Ser3UTCR2 = (u32) reg;
Ser3UTCR3 = (UTCR3_RXE | UTCR3_TXE);
#else
#error "Bad: you didn't configured serial ..."
#endif
}
/*
* Initialise the serial port with the given baudrate. The settings
* are always 8 data bits, no parity, 1 stop bit, no start bits.
*
*/
int serial_init (void)
{
serial_setbrg ();
return (0);
}
/*
* Output a single byte to the serial port.
*/
void serial_putc (const char c)
{
#ifdef CONFIG_SERIAL1
/* wait for room in the tx FIFO on SERIAL1 */
while ((Ser1UTSR0 & UTSR0_TFS) == 0);
Ser1UTDR = c;
#elif CONFIG_SERIAL3
/* wait for room in the tx FIFO on SERIAL3 */
while ((Ser3UTSR0 & UTSR0_TFS) == 0);
Ser3UTDR = c;
#endif
/* If \n, also do \r */
if (c == '\n')
serial_putc ('\r');
}
/*
* Read a single byte from the serial port. Returns 1 on success, 0
* otherwise. When the function is succesfull, the character read is
* written into its argument c.
*/
int serial_tstc (void)
{
#ifdef CONFIG_SERIAL1
return Ser1UTSR1 & UTSR1_RNE;
#elif CONFIG_SERIAL3
return Ser3UTSR1 & UTSR1_RNE;
#endif
}
/*
* Read a single byte from the serial port. Returns 1 on success, 0
* otherwise. When the function is succesfull, the character read is
* written into its argument c.
*/
int serial_getc (void)
{
#ifdef CONFIG_SERIAL1
while (!(Ser1UTSR1 & UTSR1_RNE));
return (char) Ser1UTDR & 0xff;
#elif CONFIG_SERIAL3
while (!(Ser3UTSR1 & UTSR1_RNE));
return (char) Ser3UTDR & 0xff;
#endif
}
void
serial_puts (const char *s)
{
while (*s) {
serial_putc (*s++);
}
}

422
cpu/sa1100/start.S Normal file
View File

@ -0,0 +1,422 @@
/*
* armboot - Startup Code for SA1100 CPU
*
* Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
* Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
* Copyright (C) 2000 Wolfgang Denk <wd@denx.de>
* Copyright (c) 2001 Alex Züpke <azu@sysgo.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <config.h>
#include <version.h>
/*
*************************************************************************
*
* Jump vector table as in table 3.1 in [1]
*
*************************************************************************
*/
.globl _start
_start: b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
.balignl 16,0xdeadbeef
/*
*************************************************************************
*
* Startup Code (reset vector)
*
* do important init only if we don't start from memory!
* relocate armboot to ram
* setup stack
* jump to second stage
*
*************************************************************************
*/
/*
* CFG_MEM_END is in the board dependent config-file (configs/config_BOARD.h)
*/
_TEXT_BASE:
.word TEXT_BASE
.globl _armboot_start
_armboot_start:
.word _start
/*
* Note: _armboot_end_data and _armboot_end are defined
* by the (board-dependent) linker script.
* _armboot_end_data is the first usable FLASH address after armboot
*/
.globl _armboot_end_data
_armboot_end_data:
.word armboot_end_data
.globl _armboot_end
_armboot_end:
.word armboot_end
/*
* _armboot_real_end is the first usable RAM address behind armboot
* and the various stacks
*/
.globl _armboot_real_end
_armboot_real_end:
.word 0x0badc0de
#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de
/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif
/*
* the actual reset code
*/
reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0x13
msr cpsr,r0
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
#ifdef CONFIG_INIT_CRITICAL
bl cpu_init_crit
#endif
relocate:
/*
* relocate armboot to RAM
*/
adr r0, _start /* r0 <- current position of code */
ldr r2, _armboot_start
ldr r3, _armboot_end
sub r2, r3, r2 /* r2 <- size of armboot */
ldr r1, _TEXT_BASE /* r1 <- destination address */
add r2, r0, r2 /* r2 <- source end address */
/*
* r0 = source address
* r1 = target address
* r2 = source end address
*/
copy_loop:
ldmia r0!, {r3-r10}
stmia r1!, {r3-r10}
cmp r0, r2
ble copy_loop
/* set up the stack */
ldr r0, _armboot_end
add r0, r0, #CONFIG_STACKSIZE
sub sp, r0, #12 /* leave 3 words for abort-stack */
ldr pc, _start_armboot
_start_armboot: .word start_armboot
/*
*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/
/* Interupt-Controller base address */
IC_BASE: .word 0x90050000
#define ICMR 0x04
/* Reset-Controller */
RST_BASE: .word 0x90030000
#define RSRR 0x00
#define RCSR 0x04
/* PWR */
PWR_BASE: .word 0x90020000
#define PSPR 0x08
#define PPCR 0x14
cpuspeed: .word CFG_CPUSPEED
cpu_init_crit:
/*
* mask all IRQs
*/
ldr r0, IC_BASE
mov r1, #0x00
str r1, [r0, #ICMR]
/* set clock speed */
ldr r0, PWR_BASE
ldr r1, cpuspeed
str r1, [r0, #PPCR]
/*
* before relocating, we have to setup RAM timing
* because memory timing is board-dependend, you will
* find a memsetup.S in your board directory.
*/
mov ip, lr
bl memsetup
mov lr, ip
/*
* disable MMU stuff and enable I-cache
*/
mrc p15,0,r0,c1,c0
bic r0, r0, #0x00002000 @ clear bit 13 (X)
bic r0, r0, #0x0000000f @ clear bits 3-0 (WCAM)
orr r0, r0, #0x00001000 @ set bit 12 (I) Icache
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
mcr p15,0,r0,c1,c0
/*
* flush v4 I/D caches
*/
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
mov pc, lr
/*
*************************************************************************
*
* Interrupt handling
*
*************************************************************************
*/
@
@ IRQ stack frame.
@
#define S_FRAME_SIZE 72
#define S_OLD_R0 68
#define S_PSR 64
#define S_PC 60
#define S_LR 56
#define S_SP 52
#define S_IP 48
#define S_FP 44
#define S_R10 40
#define S_R9 36
#define S_R8 32
#define S_R7 28
#define S_R6 24
#define S_R5 20
#define S_R4 16
#define S_R3 12
#define S_R2 8
#define S_R1 4
#define S_R0 0
#define MODE_SVC 0x13
#define I_BIT 0x80
/*
* use bad_save_user_regs for abort/prefetch/undef/swi ...
* use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
*/
.macro bad_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12
add r8, sp, #S_PC
ldr r2, _armboot_end
add r2, r2, #CONFIG_STACKSIZE
sub r2, r2, #8
ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0
add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
add r5, sp, #S_SP
mov r1, lr
stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_r
mov r0, sp
.endm
.macro irq_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12
add r8, sp, #S_PC
stmdb r8, {sp, lr}^ @ Calling SP, LR
str lr, [r8, #0] @ Save calling PC
mrs r6, spsr
str r6, [r8, #4] @ Save CPSR
str r0, [r8, #8] @ Save OLD_R0
mov r0, sp
.endm
.macro irq_restore_user_regs
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
mov r0, r0
ldr lr, [sp, #S_PC] @ Get PC
add sp, sp, #S_FRAME_SIZE
subs pc, lr, #4 @ return & move spsr_svc into cpsr
.endm
.macro get_bad_stack
ldr r13, _armboot_end @ setup our mode stack
add r13, r13, #CONFIG_STACKSIZE @ resides at top of normal stack
sub r13, r13, #8
str lr, [r13] @ save caller lr / spsr
mrs lr, spsr
str lr, [r13, #4]
mov r13, #MODE_SVC @ prepare SVC-Mode
msr spsr_c, r13
mov lr, pc
movs pc, lr
.endm
.macro get_irq_stack @ setup IRQ stack
ldr sp, IRQ_STACK_START
.endm
.macro get_fiq_stack @ setup FIQ stack
ldr sp, FIQ_STACK_START
.endm
/*
* exception handlers
*/
.align 5
undefined_instruction:
get_bad_stack
bad_save_user_regs
bl do_undefined_instruction
.align 5
software_interrupt:
get_bad_stack
bad_save_user_regs
bl do_software_interrupt
.align 5
prefetch_abort:
get_bad_stack
bad_save_user_regs
bl do_prefetch_abort
.align 5
data_abort:
get_bad_stack
bad_save_user_regs
bl do_data_abort
.align 5
not_used:
get_bad_stack
bad_save_user_regs
bl do_not_used
#ifdef CONFIG_USE_IRQ
.align 5
irq:
get_irq_stack
irq_save_user_regs
bl do_irq
irq_restore_user_regs
.align 5
fiq:
get_fiq_stack
/* someone ought to write a more effiction fiq_save_user_regs */
irq_save_user_regs
bl do_fiq
irq_restore_user_regs
#else
.align 5
irq:
get_bad_stack
bad_save_user_regs
bl do_irq
.align 5
fiq:
get_bad_stack
bad_save_user_regs
bl do_fiq
#endif
.align 5
.globl reset_cpu
reset_cpu:
ldr r0, RST_BASE
mov r1, #0x0 @ set bit 3-0 ...
str r1, [r0, #RCSR] @ ... to clear in RCSR
mov r1, #0x1
str r1, [r0, #RSRR] @ and perform reset
b reset_cpu @ silly, but repeat endlessly

233
disk/part_dos.c Normal file
View File

@ -0,0 +1,233 @@
/*
* (C) Copyright 2001
* Raymond Lo, lo@routefree.com
* 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
*/
/*
* Support for harddisk partitions.
*
* To be compatible with LinuxPPC and Apple we use the standard Apple
* SCSI disk partitioning scheme. For more information see:
* http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92
*/
#include <common.h>
#include <command.h>
#include <ide.h>
#include <cmd_disk.h>
#include "part_dos.h"
#if ((CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)) && defined(CONFIG_DOS_PARTITION)
/* Convert char[4] in little endian format to the host format integer
*/
static inline int le32_to_int(unsigned char *le32)
{
return ((le32[3] << 24) +
(le32[2] << 16) +
(le32[1] << 8) +
le32[0]
);
}
static inline int is_extended(int part_type)
{
return (part_type == 0x5 ||
part_type == 0xf ||
part_type == 0x85);
}
static void print_one_part (dos_partition_t *p, int ext_part_sector, int part_num)
{
int lba_start = ext_part_sector + le32_to_int (p->start4);
int lba_size = le32_to_int (p->size4);
printf ("%5d\t\t%10d\t%10d\t%2x%s\n",
part_num, lba_start, lba_size, p->sys_ind,
(is_extended (p->sys_ind) ? " Extd" : ""));
}
int test_part_dos (block_dev_desc_t *dev_desc)
{
unsigned char buffer[DEFAULT_SECTOR_SIZE];
if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) ||
(buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
(buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) {
return (-1);
}
return (0);
}
/* Print a partition that is relative to its Extended partition table
*/
static void print_partition_extended (block_dev_desc_t *dev_desc, int ext_part_sector, int relative,
int part_num)
{
unsigned char buffer[DEFAULT_SECTOR_SIZE];
dos_partition_t *pt;
int i;
if (dev_desc->block_read(dev_desc->dev, ext_part_sector, 1, (ulong *) buffer) != 1) {
printf ("** Can't read partition table on %d:%d **\n",
dev_desc->dev, ext_part_sector);
return;
}
if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 ||
buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) {
printf ("bad MBR sector signature 0x%02x%02x\n",
buffer[DOS_PART_MAGIC_OFFSET],
buffer[DOS_PART_MAGIC_OFFSET + 1]);
return;
}
/* Print all primary/logical partitions */
pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
for (i = 0; i < 4; i++, pt++) {
/*
* fdisk does not show the extended partitions that
* are not in the MBR
*/
if ((pt->sys_ind != 0) &&
(ext_part_sector == 0 || !is_extended (pt->sys_ind)) ) {
print_one_part (pt, ext_part_sector, part_num);
}
/* Reverse engr the fdisk part# assignment rule! */
if ((ext_part_sector == 0) ||
(pt->sys_ind != 0 && !is_extended (pt->sys_ind)) ) {
part_num++;
}
}
/* Follows the extended partitions */
pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
for (i = 0; i < 4; i++, pt++) {
if (is_extended (pt->sys_ind)) {
int lba_start = le32_to_int (pt->start4) + relative;
print_partition_extended (dev_desc, lba_start,
ext_part_sector == 0 ? lba_start
: relative,
part_num);
}
}
return;
}
/* Print a partition that is relative to its Extended partition table
*/
static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part_sector,
int relative, int part_num,
int which_part, disk_partition_t *info)
{
unsigned char buffer[DEFAULT_SECTOR_SIZE];
dos_partition_t *pt;
int i;
if (dev_desc->block_read (dev_desc->dev, ext_part_sector, 1, (ulong *) buffer) != 1) {
printf ("** Can't read partition table on %d:%d **\n",
dev_desc->dev, ext_part_sector);
return -1;
}
if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 ||
buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) {
printf ("bad MBR sector signature 0x%02x%02x\n",
buffer[DOS_PART_MAGIC_OFFSET],
buffer[DOS_PART_MAGIC_OFFSET + 1]);
return -1;
}
/* Print all primary/logical partitions */
pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
for (i = 0; i < 4; i++, pt++) {
/*
* fdisk does not show the extended partitions that
* are not in the MBR
*/
if (pt->sys_ind != 0 && part_num == which_part) {
info->blksz = 512;
info->start = ext_part_sector + le32_to_int (pt->start4);
info->size = le32_to_int (pt->size4);
switch(dev_desc->if_type) {
case IF_TYPE_IDE:
case IF_TYPE_ATAPI:
sprintf (info->name, "hd%c%d\n", 'a' + dev_desc->dev, part_num);
break;
case IF_TYPE_SCSI:
sprintf (info->name, "sd%c%d\n", 'a' + dev_desc->dev, part_num);
break;
case IF_TYPE_USB:
sprintf (info->name, "usbd%c%d\n", 'a' + dev_desc->dev, part_num);
break;
case IF_TYPE_DOC:
sprintf (info->name, "docd%c%d\n", 'a' + dev_desc->dev, part_num);
break;
default:
sprintf (info->name, "xx%c%d\n", 'a' + dev_desc->dev, part_num);
break;
}
/* sprintf(info->type, "%d, pt->sys_ind); */
sprintf (info->type, "U-Boot");
return 0;
}
/* Reverse engr the fdisk part# assignment rule! */
if ((ext_part_sector == 0) ||
(pt->sys_ind != 0 && !is_extended (pt->sys_ind)) ) {
part_num++;
}
}
/* Follows the extended partitions */
pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
for (i = 0; i < 4; i++, pt++) {
if (is_extended (pt->sys_ind)) {
int lba_start = le32_to_int (pt->start4) + relative;
return get_partition_info_extended (dev_desc, lba_start,
ext_part_sector == 0 ? lba_start : relative,
part_num, which_part, info);
}
}
return -1;
}
void print_part_dos (block_dev_desc_t *dev_desc)
{
printf ("Partition Start Sector Num Sectors Type\n");
print_partition_extended (dev_desc, 0, 0, 1);
}
int get_partition_info_dos (block_dev_desc_t *dev_desc, int part, disk_partition_t * info)
{
return get_partition_info_extended (dev_desc, 0, 0, 1, part, info);
}
#endif /* (CONFIG_COMMANDS & CFG_CMD_IDE) && CONFIG_DOS_PARTITION */

251
disk/part_mac.c Normal file
View File

@ -0,0 +1,251 @@
/*
* (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
*/
/*
* Support for harddisk partitions.
*
* To be compatible with LinuxPPC and Apple we use the standard Apple
* SCSI disk partitioning scheme. For more information see:
* http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92
*/
#include <common.h>
#include <command.h>
#include <ide.h>
#include <cmd_disk.h>
#include "part_mac.h"
#if ((CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)) && defined(CONFIG_MAC_PARTITION)
/* stdlib.h causes some compatibility problems; should fixe these! -- wd */
#ifndef __ldiv_t_defined
typedef struct {
long int quot; /* Quotient */
long int rem; /* Remainder */
} ldiv_t;
extern ldiv_t ldiv (long int __numer, long int __denom);
# define __ldiv_t_defined 1
#endif
static int part_mac_read_ddb (block_dev_desc_t *dev_desc, mac_driver_desc_t *ddb_p);
static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partition_t *pdb_p);
/*
* Test for a valid MAC partition
*/
int test_part_mac (block_dev_desc_t *dev_desc)
{
mac_driver_desc_t ddesc;
mac_partition_t mpart;
ulong i, n;
if (part_mac_read_ddb (dev_desc, &ddesc)) {
/* error reading Driver Desriptor Block, or no valid Signature */
return (-1);
}
n = 1; /* assuming at least one partition */
for (i=1; i<=n; ++i) {
if ((dev_desc->block_read(dev_desc->dev, i, 1, (ulong *)&mpart) != 1) ||
(mpart.signature != MAC_PARTITION_MAGIC) ) {
return (-1);
}
/* update partition count */
n = mpart.map_count;
}
return (0);
}
void print_part_mac (block_dev_desc_t *dev_desc)
{
ulong i, n;
mac_driver_desc_t ddesc;
mac_partition_t mpart;
ldiv_t mb, gb;
if (part_mac_read_ddb (dev_desc, &ddesc)) {
/* error reading Driver Desriptor Block, or no valid Signature */
return;
}
n = ddesc.blk_count;
mb = ldiv(n, ((1024 * 1024) / ddesc.blk_size)); /* MB */
/* round to 1 digit */
mb.rem *= 10 * ddesc.blk_size;
mb.rem += 512 * 1024;
mb.rem /= 1024 * 1024;
gb = ldiv(10 * mb.quot + mb.rem, 10240);
gb.rem += 512;
gb.rem /= 1024;
printf ("Block Size=%d, Number of Blocks=%d, "
"Total Capacity: %ld.%ld MB = %ld.%ld GB\n"
"DeviceType=0x%x, DeviceId=0x%x\n\n"
" #: type name"
" length base (size)\n",
ddesc.blk_size,
ddesc.blk_count,
mb.quot, mb.rem, gb.quot, gb.rem,
ddesc.dev_type, ddesc.dev_id
);
n = 1; /* assuming at least one partition */
for (i=1; i<=n; ++i) {
ulong bytes;
char c;
printf ("%4ld: ", i);
if (dev_desc->block_read (dev_desc->dev, i, 1, (ulong *)&mpart) != 1) {
printf ("** Can't read Partition Map on %d:%ld **\n",
dev_desc->dev, i);
return;
}
if (mpart.signature != MAC_PARTITION_MAGIC) {
printf ("** Bad Signature on %d:%ld - "
"expected 0x%04x, got 0x%04x\n",
dev_desc->dev, i, MAC_PARTITION_MAGIC, mpart.signature);
return;
}
/* update partition count */
n = mpart.map_count;
c = 'k';
bytes = mpart.block_count;
bytes /= (1024 / ddesc.blk_size); /* kB; assumes blk_size == 512 */
if (bytes >= 1024) {
bytes >>= 10;
c = 'M';
}
if (bytes >= 1024) {
bytes >>= 10;
c = 'G';
}
printf ("%20.32s %-18.32s %10u @ %-10u (%3ld%c)\n",
mpart.type,
mpart.name,
mpart.block_count,
mpart.start_block,
bytes, c
);
}
return;
}
/*
* Read Device Descriptor Block
*/
static int part_mac_read_ddb (block_dev_desc_t *dev_desc, mac_driver_desc_t *ddb_p)
{
if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)ddb_p) != 1) {
printf ("** Can't read Driver Desriptor Block **\n");
return (-1);
}
if (ddb_p->signature != MAC_DRIVER_MAGIC) {
#if 0
printf ("** Bad Signature: expected 0x%04x, got 0x%04x\n",
MAC_DRIVER_MAGIC, ddb_p->signature);
#endif
return (-1);
}
return (0);
}
/*
* Read Partition Descriptor Block
*/
static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partition_t *pdb_p)
{
int n = 1;
for (;;) {
/*
* We must always read the descritpor block for
* partition 1 first since this is the only way to
* know how many partitions we have.
*/
if (dev_desc->block_read (dev_desc->dev, n, 1, (ulong *)pdb_p) != 1) {
printf ("** Can't read Partition Map on %d:%d **\n",
dev_desc->dev, n);
return (-1);
}
if (pdb_p->signature != MAC_PARTITION_MAGIC) {
printf ("** Bad Signature on %d:%d: "
"expected 0x%04x, got 0x%04x\n",
dev_desc->dev, n, MAC_PARTITION_MAGIC, pdb_p->signature);
return (-1);
}
if (n == part)
return (0);
if ((part < 1) || (part > pdb_p->map_count)) {
printf ("** Invalid partition %d:%d [%d:1...%d:%d only]\n",
dev_desc->dev, part,
dev_desc->dev,
dev_desc->dev, pdb_p->map_count);
return (-1);
}
/* update partition count */
n = part;
}
/* NOTREACHED */
}
int get_partition_info_mac (block_dev_desc_t *dev_desc, int part, disk_partition_t *info)
{
mac_driver_desc_t ddesc;
mac_partition_t mpart;
if (part_mac_read_ddb (dev_desc, &ddesc)) {
return (-1);
}
info->blksz = ddesc.blk_size;
if (part_mac_read_pdb (dev_desc, part, &mpart)) {
return (-1);
}
info->start = mpart.start_block;
info->size = mpart.block_count;
memcpy (info->type, mpart.type, sizeof(info->type));
memcpy (info->name, mpart.name, sizeof(info->name));
return (0);
}
#endif /* (CONFIG_COMMANDS & CFG_CMD_IDE) && CONFIG_MAC_PARTITION */

96
disk/part_mac.h Normal file
View File

@ -0,0 +1,96 @@
/*
* (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
*/
/*
* See also Linux sources, fs/partitions/mac.h
*
* This file describes structures and values related to the standard
* Apple SCSI disk partitioning scheme. For more information see:
* http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92
*/
#ifndef _DISK_PART_MAC_H
#define _DISK_PART_MAC_H
#define MAC_DRIVER_MAGIC 0x4552
/*
* Driver Descriptor Structure, in block 0.
* This block is (and shall remain) 512 bytes long.
* Note that there is an alignment problem for the driver descriptor map!
*/
typedef struct mac_driver_desc {
__u16 signature; /* expected to be MAC_DRIVER_MAGIC */
__u16 blk_size; /* block size of device */
__u32 blk_count; /* number of blocks on device */
__u16 dev_type; /* device type */
__u16 dev_id; /* device id */
__u32 data; /* reserved */
__u16 drvr_cnt; /* number of driver descriptor entries */
__u16 drvr_map[247]; /* driver descriptor map */
} mac_driver_desc_t;
/*
* Device Driver Entry
* (Cannot be included in mac_driver_desc because of alignment problems)
*/
typedef struct mac_driver_entry {
__u32 block; /* block number of starting block */
__u16 size; /* size of driver, in 512 byte blocks */
__u16 type; /* OS Type */
} mac_driver_entry_t;
#define MAC_PARTITION_MAGIC 0x504d
/* type field value for A/UX or other Unix partitions */
#define APPLE_AUX_TYPE "Apple_UNIX_SVR2"
/*
* Each Partition Map entry (in blocks 1 ... N) has this format:
*/
typedef struct mac_partition {
__u16 signature; /* expected to be MAC_PARTITION_MAGIC */
__u16 sig_pad; /* reserved */
__u32 map_count; /* # blocks in partition map */
__u32 start_block; /* abs. starting block # of partition */
__u32 block_count; /* number of blocks in partition */
uchar name[32]; /* partition name */
uchar type[32]; /* string type description */
__u32 data_start; /* rel block # of first data block */
__u32 data_count; /* number of data blocks */
__u32 status; /* partition status bits */
__u32 boot_start; /* first block of boot code */
__u32 boot_size; /* size of boot code, in bytes */
__u32 boot_load; /* boot code load address */
__u32 boot_load2; /* reserved */
__u32 boot_entry; /* boot code entry point */
__u32 boot_entry2; /* reserved */
__u32 boot_cksum; /* boot code checksum */
uchar processor[16]; /* Type of Processor */
__u16 part_pad[188]; /* reserved */
} mac_partition_t;
#define MAC_STATUS_BOOTABLE 8 /* partition is bootable */
#endif /* _DISK_PART_MAC_H */

385
doc/README.PIP405 Normal file
View File

@ -0,0 +1,385 @@
U-Boot Changes due to PIP405 Port:
===================================
Changed files:
==============
- MAKEALL added PIP405
- makefile added PIP405
- common/Makefile added Floppy disk and SCSI support
- common/board.c added PIP405, SCSI support, get_PCI_freq()
- common/bootm.c added IH_OS_U_BOOT, IH_TYPE_FIRMWARE
- common/cmd_i2c.c added "defined(CONFIG_PIP405)"
- common/cmd_ide.c changed div. functions to work with block device
description
added ATAPI support
- common/command.c added SCSI and Floppy support
- common/console.c replaced // with /* comments
added console settings from environment
- common/devices.c added ISA keyboard init
- common/main.c corrected the read of bootdelay
- cpu/ppc4xx/405gp_pci.c excluded file from PIP405
- cpu/ppc4xx/i2c.c added 16bit read write I2C support
added page write
- cpu/ppc4xx/speed.c added get_PCI_freq
- cpu/ppc4xx/start.S added CONFIG_IDENT_STRING
- disk/Makefile added part_iso for CD support
- disk/part.c changed to work with block device description
added ISO CD support
added dev_print (was ide_print in cmd_ide.c)
- disk/part_dos.c changed to work with block device description
- disk/part_mac.c changed to work with block device description
- include/ata.h added ATAPI commands
- include/cmd_bsp.h added PIP405 commands definitions
- include/cmd_condefs.h added Floppy and SCSI support
- include/cmd_disk.h changed to work with block device description
- include/config_LANTEC.h excluded CFG_CMD_FDC and CFG_CMD_SCSI from
CONFIG_CMD_FULL
- include/config_hymod.h excluded CFG_CMD_FDC and CFG_CMD_SCSI from
CONFIG_CMD_FULL
- include/flash.h added INTEL_ID_28F320C3T 0x88C488C4
- include/i2c.h added "defined(CONFIG_PIP405)"
- include/image.h added IH_OS_U_BOOT, IH_TYPE_FIRMWARE
- include/u-boot.h moved partitions functions definitions to part.h
added "defined(CONFIG_PIP405)"
added get_PCI_freq() definition
- rtc/Makefile added MC146818 RTC support
- tools/mkimage.c added IH_OS_U_BOOT, IH_TYPE_FIRMWARE
Added files:
============
- board/pip405 directory for PIP405
- board/pip405/cmd_pip405.c board specific commands
- board/pip405/config.mk config make
- board/pip405/flash.c flash support
- board/pip405/init.s start-up
- board/pip405/kbd.c keyboard support
- board/pip405/kbd.h keyboard support
- board/pip405/Makefile Makefile
- board/pip405/pci_piix4.h southbridge definitions
- board/pip405/pci_pip405.c PCI support for PIP405
- board/pip405/pci_pip405.h PCI support for PIP405
- board/pip405/pip405.c PIP405 board init
- board/pip405/pip405.h PIP405 board init
- board/pip405/pip405_isa.c ISA support
- board/pip405/pip405_isa.h ISA support
- board/pip405/u-boot.lds Linker description
- board/pip405/u-boot.lds.debugLinker description debug
- board/pip405/sym53c8xx.c SYM53C810A support
- board/pip405/sym53c8xx_defs.h SYM53C810A definitions
- board/pip405/vga_table.h definitions of tables for VGA
- board/pip405/video.c CT69000 support
- board/pip405/video.h CT69000 support
- common/cmd_fdc.c Floppy disk support
- common/cmd_scsi.c SCSI support
- disk/part_iso.c ISO CD ROM support
- disk/part_iso.h ISO CD ROM support
- include/cmd_fdc.h command forFloppy disk support
- include/cmd_scsi.h command for SCSI support
- include/part.h partitions functions definitions
(was part of u-boot.h)
- include/scsi.h SCSI support
- rtc/mc146818.c MC146818 RTC support
New Config Switches:
====================
For detailed description, refer to the corresponding paragraph in the
section "Changes".
New Commands:
-------------
CFG_CMD_SCSI SCSI Support
CFG_CMF_FDC Floppy disk support
IDE additions:
--------------
CONFIG_IDE_RESET_ROUTINE defines that instead of a reset Pin,
the routine ide_set_reset(int idereset) is used.
ATAPI support (experimental)
----------------------------
CONFIG_ATAPI enables ATAPI Support
SCSI support (experimental) only SYM53C8xx supported
----------------------------------------------------
CONFIG_SCSI_SYM53C8XX type of SCSI controller
CFG_SCSI_MAX_LUN 8 number of supported LUNs
CFG_SCSI_MAX_SCSI_ID 7 maximum SCSI ID (0..6)
CFG_SCSI_MAX_DEVICE CFG_SCSI_MAX_SCSI_ID * CFG_SCSI_MAX_LUN
maximum of Target devices (multiple LUN support
for boot)
ISO (CD-Boot) partition support (Experimental)
----------------------------------------------
CONFIG_ISO_PARTITION CD-boot support
RTC
----
CONFIG_RTC_MC146818 MC146818 RTC support
Keyboard:
---------
CONFIG_ISA_KEYBOARD Standard (PC-Style) Keyboard support
Video:
------
CONFIG_VIDEO_CT69000 Enable Chips & Technologies 69000 Video chip
CONFIG_VIDEO must be defined also
External peripheral base address:
---------------------------------
CFG_ISA_IO_BASE_ADDRESS address of all ISA-bus related parts
_must_ be defined for ISA-bus parts
Identify:
---------
CONFIG_IDENT_STRING added to the U_BOOT_VERSION String
I2C stuff:
----------
CFG_EEPROM_PAGE_WRITE_ENABLE enables page write of the I2C EEPROM
CFG_EEPROM_PAGE_WRITE_BITS _must_ be
defined.
Environment / Console:
----------------------
CFG_CONSOLE_IS_IN_ENV if defined, stdin, stdout and stderr used from
the values stored in the evironment.
CFG_CONSOLE_OVERWRITE_ROUTINE if defined, console_overwrite() decides if the
values stored in the environment or the standard
serial in/out put should be assigned to the console.
CFG_CONSOLE_ENV_OVERWRITE if defined, the start-up console switching
are stored in the environment.
PIP405 specific:
----------------
CONFIG_PORT_ADDR address used to read boot configuration
MULTI_PURPOSE_SOCKET_ADDR address of the multi purpose socked
SDRAM_EEPROM_WRITE_ADDRESS addresses of the serial presence detect
SDRAM_EEPROM_READ_ADDRESS EEPROM on the SDRAM module.
Changes:
========
Added Devices:
==============
Floppy support:
---------------
Support of a standard floppy disk controller at address CFG_ISA_IO_BASE_ADDRESS
+ 0x3F0. Enabled with define CFG_CMD_FDC. Reads a unformated floppy disk with a
image header (see: mkimage). No interrupts and no DMA are used for this.
Added files:
- common/cmd_fdc.c
- include/cmd_fdc.h
SCSI support:
-------------
Support for Symbios SYM53C810A chip. Implemented as follows:
- without disconnect
- only asynchrounous
- multiple LUN support (caution, needs a lot of RAM. define CFG_SCSI_MAX_LUN 1 to
save RAM)
- multiple SCSI ID support
- no write support
- analyses the MAC, DOS and ISO pratition similar to the IDE support
- allows booting from SCSI devices similar to the IDE support.
The device numbers are not assigned like they are within the IDE support. The first
device found will get the number 0, the next 1 etc. If all SCSI IDs (0..6) and all
LUNs (8) are enabled, 56 boot devices are possible. This uses a lot of RAM since the
device descriptors are not yet dynamically allocated. 56 boot devices are overkill
anyway. Please refer to the section "Todo" chapter "block device support enhancement".
The SYM53C810A uses 1 Interrupt and must be able of mastering the PCI bus.
Added files:
- common/cmd_scsi.c
- common/board.c
- include/cmd_scsi.h
- include/scsi.h
- board/pip405/sym53c8xx.c
- board/pip405/sym53c8xx_defs.h
ATAPI support (IDE changes):
----------------------------
Added ATAPI support (with CONFIG_ATAPI) in the file cmd_ide.c.
To support a hardreset, when the IDE reset pin is not connected to the
CFG_PC_IDE_RESET pin, the switch CONFIG_IDE_RESET_ROUTINE has been added. When
this switch is enabled the routine void ide_set_reset(int idereset) must be
within the board specific files.
Only read from ATAPI devices are supported.
Found out that the function trim_trail cuts off the last character if the whole
string is filled. Added function cpy_ident instead, which trims also leading
spaces and copies the string in the buffer.
Changed files:
- common/cmd_ide.c
- include/ata.h
ISO partition support:
----------------------
Added CD boot support for El-Torito bootable ISO CDs. The bootfile image must contain
the U-Boot image header. Since CDs do not have "partitions", the boot partition is 0.
The bootcatalog feature has not been tested so far. CD Boot is supported for ATAPI
("diskboot") and SCSI ("scsiboot") devices.
Added files:
- disk/iso_part.c
- disk/iso_part.h
Block device changes:
---------------------
To allow the use of dos_part.c, mac_part.c and iso_part.c, the parameter
block_dev_desc will be used when accessing the functions in these files. The block
device descriptor (block_dev_desc) contains a pointer to the read routine of the
device, which will be used to read blocks from the device.
Renamed function ide_print to dev_print and moved it to the file disk/part.c to use
it for IDE ATAPI and SCSI devices.
Please refer to the section "Todo" chapter "block device support enhancement".
Added files:
- include/part.h
changed files:
- disk/dos_part.c
- disk/dos_part.h
- disk/mac_part.c
- disk/mac_part.h
- disk/part.c
- common/cmd_ide.c
- include/u-boot.h
MC146818 RTC support:
---------------------
Added support for MC146818 RTC with defining CONFIG_RTC_MC146818. The ISA bus IO
base address must be defined with CFG_ISA_IO_BASE_ADDRESS.
Added files:
- rtc/mc146818.c
Standard ISA bus Keyboard support:
----------------------------------
Added support for the standard PC kyeboard controller. For the PIP405 the superIO
controller must be set up previously. The keyboard uses the standard ISA IRQ, so
the ISA PIC must also be set up.
Added files:
- board/pip405/kbd.c
- board/pip405/kbd.h
- board/pip405/pip405_isa.c
- board/pip405/pip405_isa.h
Chips and Technologie 69000 VGA controller support:
---------------------------------------------------
Added support for the CT69000 VGA controller.
Added files:
- board/pip405/video.c
- board/pip405/video.h
- board/pip405/vga_table.h
Changed Items:
==============
Identify:
---------
Added the config variable CONFIG_IDENT_STRING which will be added to the
"U_BOOT_VERSION __TIME__ DATE___ " String, to allows to identify intermidiate
and custom versions.
Changed files:
- cpu/ppc4xx/start.s
Firmware Image:
---------------
Added IH_OS_U_BOOT and IH_TYPE_FIRMWARE to the image definitions to allows the
U-Boot update with prior CRC check.
Changed files:
- include/image.h
- tools/mkimage.c
- common/cmd_bootm.c
Correct PCI Frequency for PPC405:
---------------------------------
Added function (in cpu/ppc4xx/speed.c) to get the PCI frequency for PPC405 CPU.
The PCI Frequency will now be set correct in the board description in common/board.c.
(was set to the busfreq before).
Changed files:
- cpu/ppc4xx/speed.c
- common/board.c
I2C Stuff:
----------
Added defined(CONFIG_PIP405) at several points in common/cmd_i2c.c.
Added 16bit read/write support for I2C (PPC405), and page write to
I2C EEPROM if defined CFG_EEPROM_PAGE_WRITE_ENABLE.
Changed files:
- cpu/ppc4xx/i2c.c
- common/cmd_i2c.c
Environment / Console:
----------------------
Although in README.console described, the U-Boot has not assinged the values
found in the environment to the console. Corrected this behavior, but only if
CFG_CONSOLE_IS_IN_ENV is defined.
If CFG_CONSOLE_OVERWRITE_ROUTINE is defined, console_overwrite() decides if the
values stored in the environment or the standard serial in/output should be
assigned to the console. This is useful if the environment values are not correct.
If CFG_CONSOLE_ENV_OVERWRITE is defined the devices assigned to the console at
start-up time will be written to the environment. This means that if the
environment values are overwritten by the overwrite_console() routine, they will be
stored in the environment.
Changed files:
- common/console.c
Correct bootdelay intepretation:
--------------------------------
Changed bootdelay read from the environment from simple_strtoul (unsigned) to
simple_strtol (signed), to be able to get a bootdelay of -1.
Changed files:
- common/main.c
Todo:
=====
Block device support enhancement:
---------------------------------
Consider to unify the block device handling. Instead of using diskboot for IDE,
scsiboot for SCSI and fdcboot for floppy disks, it would make sense to use only
one command ("devboot" ???) with a parameter of the desired device ("hda1", "sda1",
"fd0" ???) to boot from. The other ide commands can be handled in the same way
("dev hda read.." instead of "ide read.." or "dev sda read.." instead of
"scsi read..."). Todo this, a common way of assign a block device to its name
(first found ide device = hda, second found hdb etc., or hda is device 0 on bus 0,
hdb is device 1 on bus 0 etc.) as well as the names (hdx for ide, sdx for scsi, fx for
floppy ???) must be defined.
Maybe there are better ideas to do this.
Console assingment:
-------------------
Consider to initialize and assign the console stdin, stdout and stderr as soon as
possible to see the boot messages also on an other console than serial.
Todo for PIP405:
================
LCD support for VGA:
--------------------
Add LCD support for the CT69000
Default environment:
--------------------
Consider to write a default environment to the OTP part of the EEPROM and use it
if the normal environment is not valid. Useful for serial# and ethaddr values.
Watchdog:
---------
Implement Watchdog.
Files clean-up:
---------------
Following files needs to be cleaned up:
- cmd_pip405.c
- flash.c
- pci_pip405.c
- pip405.c
- pip405_isa.c
Consider to split up the files in their functions.

887
doc/README.RPXlite Normal file
View File

@ -0,0 +1,887 @@
# Porting U-Boot onto RPXlite board
# Written by Yoo. Jonghoon
# E-Mail : yooth@ipone.co.kr
# IP ONE Inc.
# Since 2001. 1. 29
# Shell : bash
# Cross-compile tools : Montavista Hardhat
# Debugging tools : Windriver VisionProbe (PowerPC BDM)
# ppcboot ver. : ppcboot-0.8.1
###############################################################
# 1. Hardware setting
###############################################################
1.1. Board, BDM settings
Install board, BDM, connect each other
1.2. Save Register value
Boot with board-on monitor program and save the
register values with BDM.
1.3. Configure flash programmer
Check flash memory area in the memory map.
0xFFC00000 - 0xFFFFFFFF
Boot monitor program is at
0xFFF00000
You can program on-board flash memory with VisionClick
flash programmer. Set the target flash device as:
29DL800B
(?) The flash memory device in the board *is* 29LV800B,
but I cannot program it with '29LV800B' option.
(in VisionClick flash programming tools)
I don't know why...
1.4. Save boot monitor program *IMPORTANT*
Upload boot monitor program from board to file.
boot monitor program starts at 0xFFF00000
1.5. Test flash memory programming
Try to erase boot program in the flash memory,
and re-write them.
*WARNING* YOU MUST SAVE BOOT PROGRAM TO FILE
BEFORE ERASING FLASH
###############################################################
# 2. U-Boot setting
###############################################################
2.1. Download U-Boot tarball at
ftp://ftp.denx.de
(The latest version is ppcboot-0.8.1.tar.bz2)
To extract the archive use the following syntax :
> bzip2 -cd ppcboot-0.8.1.tar.bz2 | tar xf -
2.2. Add the following lines in '.profile'
export PATH=$PATH:/opt/hardhat/devkit/ppc/8xx/bin
2.3. Make board specific config, for example:
> cd ppcboot-0.8.1
> make TQM860L_config
Now we can build ppcboot bin files.
After make all, you must see these files in your
ppcboot root directory.
ppcboot
ppcboot.bin
ppcboot.srec
ppcboot.map
2.4. Make your own board directory into the
ppcboot-0.8.1/board
and make your board-specific files here.
For exmanple, tqm8xx files are composed of
.depend : Nothing
Makefile : To make config file
config.mk : Sets base address
flash.c : Flash memory control files
ppcboot.lds : linker(ld) script? (I don't know this yet)
tqm8xx.c : DRAM control and board check routines
And, add your board config lines in the
ppcboot-0.8.1/Makefile
Finally, add config_(your board).h file in the
ppcboot-0.8.1/include/
I've made board/rpxlite directory, and just copied
tqm8xx settings for now.
Rebuild ppcboot for rpxlite board:
> make rpxlite_config
> make
###############################################################
# 3. U-Boot porting
###############################################################
3.1. My RPXlite files are based on tqm8xx board files.
> cd board
> cp -r tqm8xx RPXLITE
> cd RPXLITE
> mv tqm8xx.c RPXLITE.c
> cd ../../include
> cp config_tqm8xx.h config_RPXLITE.h
3.2. Modified files are:
board/RPXLITE/RPXLITE.c /* DRAM-related routines */
board/RPXLITE/flash.c /* flash-related routines */
board/RPXLITE/config.mk /* set text base address */
cpu/mpc8xx/serial.c /* board specific register setting */
include/config_RPXLITE.h /* board specific registers */
See 'reg_config.txt' for register values in detail.
###############################################################
# 4. Running Linux
###############################################################
###############################################################
# Misc Information
###############################################################
mem_config.txt:
===============
Flash memory device : AM29LV800BB (1Mx8Bit) x 4 device
manufacturer id : 01 (AMD)
device id : 5B (AM29LV800B)
size : 4Mbyte
sector # : 19
Sector information :
number start addr. size
00 FFC0_0000 64
01 FFC1_0000 32
02 FFC1_8000 32
03 FFC2_0000 128
04 FFC4_0000 256
05 FFC8_0000 256
06 FFCC_0000 256
07 FFD0_0000 256
08 FFD4_0000 256
09 FFD8_0000 256
10 FFDC_0000 256
11 FFE0_0000 256
12 FFE4_0000 256
13 FFE8_0000 256
14 FFEC_0000 256
15 FFF0_0000 256
16 FFF4_0000 256
17 FFF8_0000 256
18 FFFC_0000 256
reg_config.txt:
===============
/*------------------------------------------------------------------- */
/*------------------------------------------------------------------- */
/* SIU (System Interface Unit) */
/* */
/*------------------------------------------------------------------- */
/*------------------------------------------------------------------- */
/*### IMMR */
/*### Internal Memory Map Register */
/*### Chap. 11.4.1 */
ISB = 0xFA20 /* Set the Immap base = 0xFA20 0000 */
PARTNUM = 0x21
MASKNUM = 0x00
=> 0xFA20 2100
---------------------------------------------------------------------
/*### SIUMCR */
/*### SIU Module Configuration Register */
/*### Chap. 11.4.2 */
/*### Offset : 0x0000 0000 */
EARB = 0
EARP = 0
DSHW = 0
DBGC = 0
DBPC = 0
FRC = 0
DLK = 0
OPAR = 0
PNCS = 0
DPC = 0
MPRE = 0
MLRC = 10 /* ~KR/~RETRY/~IRQ4/SPKROUT functions as ~KR/~TRTRY */
AEME = 0
SEME = 0
BSC = 0
GB5E = 0
B2DD = 0
B3DD = 0
=> 0x0000 0800
---------------------------------------------------------------------
/*### SYPCR */
/*### System Protection Control Register */
/*### Chap. 11.4.3 */
/*### Offset : 0x0000 0004 */
SWTC = 0xFFFF /* SW watchdog timer count = 0xFFFF */
BMT = 0x06 /* BUS monitoring timing */
BME = 1 /* BUS monitor enable */
SWF = 1
SWE = 0 /* SW watchdog disable */
SWRI = 0
SWP = 1
=> 0xFFFF 0689
---------------------------------------------------------------------
/*### TESR */
/*### Transfer Error Status Register */
/*### Chap. 11.4.4 */
/*### Offset : 0x0000 0020 */
IEXT = 0
ITMT = 0
IPB = 0000
DEXT = 0
DTMT = 0
DPB = 0000
=> 0x0000 0000
---------------------------------------------------------------------
/*### SIPEND */
/*### SIU Interrupt Pending Register */
/*### Chap. 11.5.4.1 */
/*### Offset : 0x0000 0010 */
IRQ0~IRQ7 = 0
LVL0~LVL7 = 0
=> 0x0000 0000
---------------------------------------------------------------------
/*### SIMASK */
/*### SIU Interrupt Mask Register */
/*### Chap. 11.5.4.2 */
/*### Offset : 0x0000 0014 */
IRM0~IRM7 = 0 /* Mask all interrupts */
LVL0~LVL7 = 0
=> 0x0000 0000
---------------------------------------------------------------------
/*### SIEL */
/*### SIU Interrupt Edge/Level Register */
/*### Chap. 11.5.4.3 */
/*### Offset : 0x0000 0018 */
ED0~ED7 = 0 /* Low level triggered */
WMn0~WMn7 = 0 /* Not allowed to exit from low-power mode */
=> 0x0000 0000
---------------------------------------------------------------------
/*### SIVEC */
/*### SIU Interrupt Vector Register */
/*### Chap. 11.5.4.4 */
/*### Offset : 0x0000 001C */
INTC = 3C /* The lowest interrupt is pending..(?) */
=> 0x3C00 0000
---------------------------------------------------------------------
/*### SWSR */
/*### Software Service Register */
/*### Chap. 11.7.1 */
/*### Offset : 0x0000 001E */
SEQ = 0
=> 0x0000
---------------------------------------------------------------------
/*### SDCR */
/*### SDMA Configuration Register */
/*### Chap. 20.2.1 */
/*### Offset : 0x0000 0032 */
FRZ = 0
RAID = 01 /* Priority level 5 (BR5) (normal operation) */
=> 0x0000 0001
/*------------------------------------------------------------------- */
/*------------------------------------------------------------------- */
/* UPMA (User Programmable Machine A) */
/* */
/*------------------------------------------------------------------- */
/*------------------------------------------------------------------- */
/*### Chap. 16.6.4.1 */
/*### Offset = 0x0000 017c */
T0 = CFFF CC24 /* Single Read */
T1 = 0FFF CC04
T2 = 0CAF CC04
T3 = 03AF CC08
T4 = 3FBF CC27 /* last */
T5 = FFFF CC25
T6 = FFFF CC25
T7 = FFFF CC25
T8 = CFFF CC24 /* Burst Read */
T9 = 0FFF CC04
T10 = 0CAF CC84
T11 = 03AF CC88
T12 = 3FBF CC27 /* last */
T13 = FFFF CC25
T14 = FFFF CC25
T15 = FFFF CC25
T16 = FFFF CC25
T17 = FFFF CC25
T18 = FFFF CC25
T19 = FFFF CC25
T20 = FFFF CC25
T21 = FFFF CC25
T22 = FFFF CC25
T23 = FFFF CC25
T24 = CFFF CC24 /* Single Write */
T25 = 0FFF CC04
T26 = 0CFF CC04
T27 = 03FF CC00
T28 = 3FFF CC27 /* last */
T29 = FFFF CC25
T30 = FFFF CC25
T31 = FFFF CC25
T32 = CFFF CC24 /* Burst Write */
T33 = 0FFF CC04
T34 = 0CFF CC80
T35 = 03FF CC8C
T36 = 0CFF CC00
T37 = 33FF CC27 /* last */
T38 = FFFF CC25
T39 = FFFF CC25
T40 = FFFF CC25
T41 = FFFF CC25
T42 = FFFF CC25
T43 = FFFF CC25
T44 = FFFF CC25
T45 = FFFF CC25
T46 = FFFF CC25
T47 = FFFF CC25
T48 = C0FF CC24 /* Refresh */
T49 = 03FF CC24
T50 = 0FFF CC24
T51 = 0FFF CC24
T52 = 3FFF CC27 /* last */
T53 = FFFF CC25
T54 = FFFF CC25
T55 = FFFF CC25
T56 = FFFF CC25
T57 = FFFF CC25
T58 = FFFF CC25
T59 = FFFF CC25
T60 = FFFF CC25 /* Exception */
T61 = FFFF CC25
T62 = FFFF CC25
T63 = FFFF CC25
/*------------------------------------------------------------------- */
/*------------------------------------------------------------------- */
/* UPMB */
/* */
/*------------------------------------------------------------------- */
/*------------------------------------------------------------------- */
---------------------------------------------------------------------
/*### Chap. 16.6.4.1 */
/*------------------------------------------------------------------- */
/*------------------------------------------------------------------- */
/* MEMC */
/* */
/*------------------------------------------------------------------- */
/*------------------------------------------------------------------- */
---------------------------------------------------------------------
/*### BR0 & OR0 */
/*### Base Registers & Option Registers */
/*### Chap. 16.4.1 & 16.4.2 */
/*### Offset : BR0(0x0000 0100) & OR0(0x0000 0104) */
/*### Flash memory */
BA = 1111 1110 0000 0000 0 /* Base addr = 0xFE00 0000 */
AT = 000
PS = 00
PARE = 0
WP = 0
MS = 0 /* GPCM */
V = 1 /* Valid */
=> 0xFE00 0001
AM = 1111 1110 0000 0000 0 /* 32MBytes */
ATM = 000
CSNT/SAM = 0
ACS/G5LA,G5LS = 00
BIH = 1 /* Burst inhibited */
SCY = 0100 /* cycle length = 4 */
SETA = 0
TRLX = 0
EHTR = 0
=> 0xFE00 0140
/*### BR1 & OR1 */
/*### Base Registers & Option Registers */
/*### Chap. 16.4.1 & 16.4.2 */
/*### Offset : BR1(0x0000 0108) & OR1(0x0000 010C) */
/*### SDRAM */
BA = 0000 0000 0000 0000 0 /* Base addr = 0x0000 0000 */
AT = 000
PS = 00
PARE = 0
WP = 0
MS = 1 /* UPMA */
V = 1 /* Valid */
=> 0x0000 0081
AM = 1111 1110 0000 0000 /* 32MBytes */
ATM = 000
CSNT/SAM = 1
ACS/G5LA,G5LS = 11
BIH = 0
SCY = 0000 /* cycle length = 0 */
SETA = 0
TRLX = 0
EHTR = 0
=> 0xFE00 0E00
/*### BR2 & OR2 */
/*### Base Registers & Option Registers */
/*### Chap. 16.4.1 & 16.4.2 */
/*### Offset : BR2(0x0000 0110) & OR2(0x0000 0114) */
BR2 & OR2 = 0x0000 0000 /* Not used */
/*### BR3 & OR3 */
/*### Base Registers & Option Registers */
/*### Chap. 16.4.1 & 16.4.2 */
/*### Offset : BR3(0x0000 0118) & OR3(0x0000 011C) */
/*### BCSR */
BA = 1111 1010 0100 0000 0 /* Base addr = 0xFA40 0000 */
AT = 000
PS = 00
PARE = 0
WP = 0
MS = 0 /* GPCM */
V = 1 /* Valid */
=> 0xFA40 0001
AM = 1111 1111 0111 1111 1 /* (?) */
ATM = 000
CSNT/SAM = 1
ACS/G5LA,G5LS = 00
BIH = 1 /* Burst inhibited */
SCY = 0001 /* cycle length = 1 */
SETA = 0
TRLX = 0
=> 0xFF7F 8910
/*### BR4 & OR4 */
/*### Base Registers & Option Registers */
/*### Chap. 16.4.1 & 16.4.2 */
/*### Offset : BR4(0x0000 0120) & OR4(0x0000 0124) */
/*### NVRAM & SRAM */
BA = 1111 1010 0000 0000 0 /* Base addr = 0xFA00 0000 */
AT = 000
PS = 01
PARE = 0
WP = 0
MS = 0 /* GPCM */
V = 1 /* Valid */
=> 0xFA00 0401
AM = 1111 1111 1111 1000 0 /* 8MByte */
ATM = 000
CSNT/SAM = 1
ACS/G5LA,G5LS = 00
BIH = 1 /* Burst inhibited */
SCY = 0111 /* cycle length = 7 */
SETA = 0
TRLX = 0
=> 0xFFF8 0970
/*### BR5 & OR5 */
/*### Base Registers & Option Registers */
/*### Chap. 16.4.1 & 16.4.2 */
/*### Offset : BR2(0x0000 0128) & OR2(0x0000 012C) */
BR5 & OR5 = 0x0000 0000 /* Not used */
/*### BR6 & OR6 */
/*### Base Registers & Option Registers */
/*### Chap. 16.4.1 & 16.4.2 */
/*### Offset : BR2(0x0000 0130) & OR2(0x0000 0134) */
BR6 & OR6 = 0x0000 0000 /* Not used */
/*### BR7 & OR7 */
/*### Base Registers & Option Registers */
/*### Chap. 16.4.1 & 16.4.2 */
/*### Offset : BR7(0x0000 0138) & OR7(0x0000 013C) */
BR7 & OR7 = 0x0000 0000 /* Not used */
/*### MAR */
/*### Memory Address Register */
/*### Chap. 16.4.7 */
/*### Offset : 0x0000 0164 */
MA = External memory address
/*### MCR */
/*### Memory Command Register */
/*### Chap. 16.4.5 */
/*### Offset : 0x0000 0168 */
OP = xx /* Command op code */
UM = 1 /* Select UPMA */
MB = 001 /* Select CS1 */
MCLF = xxxx /* Loop times */
MAD = xx xxxx /* Memory array index */
/*### MAMR */
/*### Machine A Mode Register */
/*### Chap. 16.4.4 */
/*### Offset : 0x0000 0170 */
PTA = 0101 1000
PTAE = 1 /* Periodic timer A enabled */
AMA = 010
DSA = 00
G0CLA = 000
GPLA4DIS = 1
RLFA = 0100
WLFA = 0011
TLFA = 0000
=> 0x58A0 1430
/*### MBMR */
/*### Machine B Mode Register */
/*### Chap. 16.4.4 */
/*### Offset : 0x0000 0174 */
PTA = 0100 1110
PTAE = 0 /* Periodic timer B disabled */
AMA = 000
DSA = 00
G0CLA = 000
GPLA4DIS = 1
RLFA = 0000
WLFA = 0000
TLFA = 0000
=> 0x4E00 1000
/*### MSTAT */
/*### Memory Status Register */
/*### Chap. 16.4.3 */
/*### Offset : 0x0000 0178 */
PER0~PER7 = Parity error
WPER = Write protection error
=> 0x0000
/*### MPTPR */
/*### Memory Periodic Timer Prescaler Register */
/*### Chap. 16.4.8 */
/*### Offset : 0x0000 017A */
PTP = 0000 1000 /* Divide by 8 */
=> 0x0800
/*### MDR */
/*### Memory Data Register */
/*### Chap. 16.4.6 */
/*### Offset : 0x0000 017C */
MD = Memory data contains the RAM array word
/*------------------------------------------------------------------- */
/*------------------------------------------------------------------- */
/* TIMERS */
/* */
/*------------------------------------------------------------------- */
/*------------------------------------------------------------------- */
---------------------------------------------------------------------
/*### TBREFx */
/*### Timebase Reference Registers */
/*### Chap. 11.9.2 */
/*### Offset : TBREFF0(0x0000 0204)/TBREFF1(0x0000 0208) */
/*### (Locked) */
TBREFF0 = 0xFFFF FFFF
TBREFF1 = 0xFFFF FFFF
---------------------------------------------------------------------
/*### TBSCR */
/*### Timebase Status and Control Registers */
/*### Chap. 11.9.3 */
/*### Offset : 0x0000 0200 */
/*### (Locked) */
TBIRQ = 00000000
REF0 = 0
REF1 = 0
REFE0 = 0 /* Reference interrupt disable */
REFE1 = 0
TBF = 1
TBE = 1 /* Timebase enable */
=> 0x0003
---------------------------------------------------------------------
/*### RTCSC */
/*### Real-Time Clock Status and Control Registers */
/*### Chap. 11.10.1 */
/*### Offset : 0x0000 0220 */
/*### (Locked) */
RTCIRQ = 00000000
SEC = 1
ALR = 0
38K = 0 /* PITRTCLK is driven by 32.768KHz */
SIE = 0
ALE = 0
RTF = 0
RTE = 1 /* Real-Time clock enabled */
=> 0x0081
---------------------------------------------------------------------
/*### RTC */
/*### Real-Time Clock Registers */
/*### Chap. 11.10.2 */
/*### Offset : 0x0000 0224 */
/*### (Locked) */
RTC = Real time clock measured in second
---------------------------------------------------------------------
/*### RTCAL */
/*### Real-Time Clock Alarm Registers */
/*### Chap. 11.10.3 */
/*### Offset : 0x0000 022C */
/*### (Locked) */
ALARM = 0xFFFF FFFF
---------------------------------------------------------------------
/*### RTSEC */
/*### Real-Time Clock Alarm Second Registers */
/*### Chap. 11.10.4 */
/*### Offset : 0x0000 0228 */
/*### (Locked) */
COUNTER = Counter bits(fraction of a second)
---------------------------------------------------------------------
/*### PISCR */
/*### Periodic Interrupt Status and Control Register */
/*### Chap. 11.11.1 */
/*### Offset : 0x0000 0240 */
/*### (Locked) */
PIRQ = 0
PS = 0 /* Write 1 to clear */
PIE = 0
PITF = 1
PTE = 0 /* PIT disabled */
---------------------------------------------------------------------
/*### PITC */
/*### PIT Count Register */
/*### Chap. 11.11.2 */
/*### Offset : 0x0000 0244 */
/*### (Locked) */
PITC = PIT count
---------------------------------------------------------------------
/*### PITR */
/*### PIT Register */
/*### Chap. 11.11.3 */
/*### Offset : 0x0000 0248 */
/*### (Locked) */
PIT = PIT count /* Read only */
/*------------------------------------------------------------------- */
/*------------------------------------------------------------------- */
/* CLOCKS */
/* */
/*------------------------------------------------------------------- */
/*------------------------------------------------------------------- */
---------------------------------------------------------------------
---------------------------------------------------------------------
/*### SCCR */
/*### System Clock and Reset Control Register */
/*### Chap. 15.6.1 */
/*### Offset : 0x0000 0280 */
/*### (Locked) */
COM = 11 /* Clock output disabled */
TBS = 1 /* Timebase frequency source is GCLK2 divided by 16 */
RTDIV = 0 /* The clock is divided by 4 */
RTSEL = 0 /* OSCM(Crystal oscillator) is selected */
CRQEN = 0
PRQEN = 0
EBDF = 00 /* CLKOUT is GCLK2 divided by 1 */
DFSYNC = 00 /* Divided by 1 (normal operation) */
DFBRG = 00 /* Divided by 1 (normal operation) */
DFNL = 000
DFNH = 000
=> 0x6200 0000
---------------------------------------------------------------------
/*### PLPRCR */
/*### PLL, Low-Power, and Reset Control Register */
/*### Chap. 15.6.2 */
/*### Offset : 0x0000 0284 */
/*### (Locked) */
MF = 0x005 /* 48MHz (?) ( = 8MHz * (MF+1) ) */
SPLSS = 0
TEXPS = 0
TMIST = 0
CSRC = 0 /* The general system clock is generated by the DFNH field */
LPM = 00 /* Normal high/normal low mode */
CSR = 0
LOLRE = 0
FIOPD = 0
=> 0x0050 0000
---------------------------------------------------------------------
/*### RSR */
/*### Reset Status Register */
/*### Chap. 12.2 */
/*### Offset : 0x0000 0288 */
/*### (Locked) */
EHRS = External hard reset
ESRS = External soft reset
LLRS = Loss-of-lock reset
SWRS = Software watchdog reset
CSRS = Check stop reset
DBHRS = Debug port hard reset
DBSRS = Debug port soft reset
JTRS = JTAG reset
/*------------------------------------------------------------------- */
/*------------------------------------------------------------------- */
/* DMA */
/* */
/*------------------------------------------------------------------- */
/*------------------------------------------------------------------- */
---------------------------------------------------------------------
/*### SDSR */
/*### SDMA Status Register */
/*### Chap. 20.2.2 */
/*### Offset : 0x0000 0908 */
SBER = 0 /* SDMA channel bus error */
DSP2 = 0 /* DSP chain2 (Tx) interrupt */
DSP1 = 0 /* DSP chain1 (Rx) interrupt */
=> 0x00
/*### SDMR */
/*### SDMA Mask Register */
/*### Chap. 20.2.3 */
/*### Offset : 0x0000 090C */
SBER = 0
DSP2 = 0
DSP1 = 0 /* All interrupts are masked */
=> 0x00
/*### SDAR */
/*### SDMA Address Register */
/*### Chap. 20.2.4 */
/*### Offset : 0x0000 0904 */
AR = 0xxxxx xxxx /* current system address */
=> 0xFA20 23AC
/*### IDSRx */
/*### IDMA Status Register */
/*### Chap. 20.3.3.2 */
/*### Offset : IDSR1(0x0000 0910) & IDSR2(0x0000 0918) */
AD = 0
DONE = 0
OB = 0
=> 0x00
/*### IDMRx */
/*### IDMA Mask Register */
/*### Chap. 20.3.3.3 */
/*### Offset : IDMR1(0x0000 0914) & IDMR2(0x0000 091C) */
AD = 0
DONE = 0
OB = 0

397
doc/README.Sandpoint8240 Normal file
View File

@ -0,0 +1,397 @@
The port was tested on a Sandpoint 8240 X3 board, with U-Boot
installed in the flash memory of the CPU card. Please use the
following DIP switch settings:
Motherboard:
SW1.1: on SW1.2: on SW1.3: on SW1.4: on
SW1.5: on SW1.6: on SW1.7: on SW1.8: on
SW2.1: on SW2.2: on SW2.3: on SW2.4: on
SW2.5: on SW2.6: on SW2.7: on SW2.8: on
CPU Card:
SW2.1: OFF SW2.2: OFF SW2.3: on SW2.4: on
SW2.5: OFF SW2.6: OFF SW2.7: OFF SW2.8: OFF
SW3.1: OFF SW3.2: on SW3.3: OFF SW3.4: OFF
SW3.5: on SW3.6: OFF SW3.7: OFF SW3.8: on
The followind detailed description of installation and initial steps
with U-Boot and QNX was provided by Jim Sandoz <sandoz@lucent.com>:
Directions for installing U-Boot on Sandpoint+Unity8240
using the Abatron BDI2000 BDM/JTAG debugger ...
Background and Reference info:
http://u-boot.sourceforge.net/
http://www.abatron.ch/
http://www.abatron.ch/BDI/bdihw.html
http://www.abatron.ch/DataSheets/BDI2000.pdf
http://www.abatron.ch/Manuals/ManGdbCOP-2000C.pdf
http://e-www.motorola.com/collateral/SPX3UM.pdf
http://e-www.motorola.com/collateral/UNITYX4CONFIG.pdf
Connection Diagram:
===========
=== ===== |----- |
| | <---------------> | | | | |
|PC | rs232 | BDI |=============[] | |
| | |2000 | BDM probe | | |
| | <---------------> | | |----- |
=== ethernet ===== | |
| |
===========
Sandpoint X3 with
Unity 8240 proc
PART 1)
DIP Switch Settings:
Sandpoint X3 8240 processor board DIP switch settings, with
U-Boot to be installed in the flash memory of the CPU card:
Motorola Sandpoint X3 Motherboard:
SW1.1: on SW1.2: on SW1.3: on SW1.4: on
SW1.5: on SW1.6: on SW1.7: on SW1.8: on
SW2.1: on SW2.2: on SW2.3: on SW2.4: on
SW2.5: on SW2.6: on SW2.7: on SW2.8: on
Motorola Unity 8240 CPU Card:
SW2.1: OFF SW2.2: OFF SW2.3: on SW2.4: on
SW2.5: OFF SW2.6: OFF SW2.7: OFF SW2.8: OFF
SW3.1: OFF SW3.2: on SW3.3: OFF SW3.4: OFF
SW3.5: on SW3.6: OFF SW3.7: OFF SW3.8: on
PART 2)
Connect the BDI2000 Cable to the Sandpoint/Unity 8240:
BDM Pin 1 on the Unity 8240 processor board is towards the
PCI PMC connectors, or away from the socketed SDRAM, i.e.:
====================
| ---------------- |
| | SDRAM | |
| | | |
| ---------------- |
| |~| |
| |B| ++++++ |
| |D| + uP + |
| |M| +8240+ |
| ~ 1 ++++++ |
| |
| |
| |
| PMC conn ====== |
| ===== ====== |
| |
====================
PART 3)
Setting up the BDI2000, and preparing for TCP/IP network comms:
Connect the BDI2000 to the PC using the supplied serial cable.
Download the BDI2000 software and install it using setup.exe.
[Note: of course you can also use the Linux command line tool
"bdisetup" to configure your BDI2000 - the sources are included on
the floppy disk that comes with your BDI2000. Just in case you don't
have any Windows PC's - like me :-) -- wd ]
Power up the BDI2000; then follow directions to assign the IP
address and related network information. Note that U-Boot
will be loaded to the Sandpoint via tftp. You need to either
use the Abatron-provided tftp application or provide a tftp
server (e.g. Linux/Solaris/*BSD) somewhere on your network.
Once the IP address etc are assigned via the RS232 port,
further communication with the BDI2000 will happen via the
ethernet connection.
PART 4)
Making a TCP/IP network connection to the Abatron BDI2000:
Telnet to the Abatron BDI2000. Assuming that all of the
networking info was loaded via RS232 correctly, you will see
the following (scrolling):
- TARGET: waiting for target Vcc
- TARGET: waiting for target Vcc
PART 5)
Power up the target Sandpoint:
If the BDM connections are correct, the following will now appear:
- TARGET: waiting for target Vcc
- TARGET: waiting for target Vcc
- TARGET: processing power-up delay
- TARGET: processing user reset request
- BDI asserts HRESET
- Reset JTAG controller passed
- Bypass check: 0x55 => 0xAA
- Bypass check: 0x55 => 0xAA
- JTAG exists check passed
- Target PVR is 0x00810101
- COP status is 0x01
- Check running state passed
- BDI scans COP freeze command
- BDI removes HRESET
- COP status is 0x05
- Check stopped state passed
- Check LSRL length passed
- BDI sets breakpoint at 0xFFF00100
- BDI resumes program execution
- Waiting for target stop passed
- TARGET: Target PVR is 0x00810101
- TARGET: reseting target passed
- TARGET: processing target startup ....
- TARGET: processing target startup passed
BDI>
PART 6)
Erase the current contents of the flash memory:
BDI>era 0xFFF00000
Erasing flash at 0xfff00000
Erasing flash passed
BDI>era 0xFFF04000
Erasing flash at 0xfff04000
Erasing flash passed
BDI>era 0xFFF06000
Erasing flash at 0xfff06000
Erasing flash passed
BDI>era 0xFFF08000
Erasing flash at 0xfff08000
Erasing flash passed
BDI>era 0xFFF10000
Erasing flash at 0xfff10000
Erasing flash passed
BDI>era 0xFFF20000
Erasing flash at 0xfff20000
Erasing flash passed
PART 7)
Program the flash memory with the U-Boot image:
BDI>prog 0xFFF00000 u-boot.bin bin
Programming u-boot.bin , please wait ....
Programming flash passed
PART 8)
Connect PC to Sandpoint:
Using a crossover serial cable, attach the PC serial port to the
Sandpoint's COM1. Set communications parameters to 8N1 / 9600 baud.
PART 9)
Reset the Unity and begin U-Boot execution:
BDI>reset
- TARGET: processing user reset request
- TARGET: Target PVR is 0x00810101
- TARGET: reseting target passed
- TARGET: processing target init list ....
- TARGET: processing target init list passed
BDI>go
Now see output from U-Boot running, sent via serial port:
U-Boot 1.1.4 (Jan 23 2002 - 18:29:19)
CPU: MPC8240 Revision 1.1 at 264 MHz: 16 kB I-Cache 16 kB D-Cache
Board: Sandpoint 8240 Unity
DRAM: 64 MB
FLASH: 2 MB
PCI: scanning bus0 ...
bus dev fn venID devID class rev MBAR0 MBAR1 IPIN ILINE
00 00 00 1057 0003 060000 13 00000008 00000000 01 00
00 0b 00 10ad 0565 060100 10 00000000 00000000 00 00
00 0f 00 8086 1229 020000 08 80000000 80000001 01 00
In: serial
Out: serial
Err: serial
=>
PART 10)
Set and save any required environmental variables, examples of some:
=> setenv ethaddr 00:03:47:97:D0:79
=> setenv bootfile your_qnx_image_here
=> setenv hostname sandpointX
=> setenv netmask 255.255.255.0
=> setenv ipaddr 192.168.0.11
=> setenv serverip 192.168.0.10
=> setenv gatewayip=192.168.0.1
=> saveenv
Saving Enviroment to Flash...
Un-Protected 1 sectors
Erasing Flash...
done
Erased 1 sectors
Writing to Flash... done
Protected 1 sectors
=>
**** Example environment: ****
=> printenv
baudrate=9600
bootfile=telemetry
hostname=sp1
ethaddr=00:03:47:97:E4:6B
load=tftp 100000 u-boot.bin
update=protect off all;era FFF00000 FFF3FFFF;cp.b 100000 FFF00000 $(filesize);saveenv
filesize=1f304
gatewayip=145.17.228.1
netmask=255.255.255.0
ipaddr=145.17.228.42
serverip=145.17.242.46
stdin=serial
stdout=serial
stderr=serial
Environment size: 332/8188 bytes
=>
here's some text useful stuff for cut-n-paste:
setenv hostname sandpoint1
setenv netmask 255.255.255.0
setenv ipaddr 145.17.228.81
setenv serverip 145.17.242.46
setenv gatewayip 145.17.228.1
saveenv
PART 11)
Test U-Boot by tftp'ing new U-Boot, overwriting current:
=> protect off all
Un-Protect Flash Bank # 1
=> tftp 100000 u-boot.bin
eth: Intel i82559 PCI EtherExpressPro @0x80000000(bus=0, device=15, func=0)
ARP broadcast 1
TFTP from server 145.17.242.46; our IP address is 145.17.228.42; sending through
gateway 145.17.228.1
Filename 'u-boot.bin'.
Load address: 0x100000
Loading: #########################
done
Bytes transferred = 127628 (1f28c hex)
=> era all
Erase Flash Bank # 1
done
Erase Flash Bank # 2 - missing
=> cp.b 0x100000 FFF00000 1f28c
Copy to Flash... done
=> saveenv
Saving Enviroment to Flash...
Un-Protected 1 sectors
Erasing Flash...
done
Erased 1 sectors
Writing to Flash... done
Protected 1 sectors
=> reset
You can put these commands into some environment variables;
=> setenv load tftp 100000 u-boot.bin
=> setenv update protect off all\;era FFF00000 FFF3FFFF\;cp.b 100000 FFF00000 \$(filesize)\;saveenv
=> saveenv
Then you just have to type "run load" then "run update"
=> run load
eth: Intel i82559 PCI EtherExpressPro @0x80000000(bus=0, device=15, func=0)
ARP broadcast 1
TFTP from server 145.17.242.46; our IP address is 145.17.228.42; sending through
gateway 145.17.228.1
Filename 'u-boot.bin'.
Load address: 0x100000
Loading: #########################
done
Bytes transferred = 127748 (1f304 hex)
=> run update
Un-Protect Flash Bank # 1
Un-Protect Flash Bank # 2
Erase Flash from 0xfff00000 to 0xfff3ffff
done
Erased 7 sectors
Copy to Flash... done
Saving Enviroment to Flash...
Un-Protected 1 sectors
Erasing Flash...
done
Erased 1 sectors
Writing to Flash... done
Protected 1 sectors
=>
PART 12)
Load OS image (ELF format) via U-Boot using tftp
=> tftp 800000 sandpoint-simple.elf
eth: Intel i82559 PCI EtherExpressPro @0x80000000(bus=0, device=15, func=0)
ARP broadcast 1
TFTP from server 145.17.242.46; our IP address is 145.17.228.42; sending through
gateway 145.17.228.1
Filename 'sandpoint-simple.elf'.
Load address: 0x800000
Loading: #################################################################
#################################################################
#################################################################
########################
done
Bytes transferred = 1120284 (11181c hex)
==>
PART 13)
Begin OS image execution: (note that unless you have the
serial parameters of your OS image set to 9600 (i.e. same as
the U-Boot binary) you will get garbage here until you change
the serial communications speed.
=> bootelf 800000
Loading @ 0x001f0100 (1120028 bytes)
## Starting application at 0x001f1d28 ...
Replace init_hwinfo() with a board specific version
Loading QNX6....
Header size=0x0000009c, Total Size=0x000005c0, #Cpu=1, Type=1
<...loader and kernel messages snipped...>
Welcome to Neutrino on the Sandpoint
#
other information:
CVS Retrieval Notes:
U-Boot's SourceForge CVS repository can be checked out
through anonymous (pserver) CVS with the following
instruction set. The module you wish to check out must
be specified as the modulename. When prompted for a
password for anonymous, simply press the Enter key.
cvs -d:pserver:anonymous@cvs.u-boot.sourceforge.net:/cvsroot/u-boot login
cvs -z6 -d:pserver:anonymous@cvs.u-boot.sourceforge.net:/cvsroot/u-boot co -P u-boot

522
drivers/3c589.c Normal file
View File

@ -0,0 +1,522 @@
/*------------------------------------------------------------------------
. 3c589.c
. This is a driver for 3Com's 3C589 (Etherlink III) PCMCIA Ethernet device.
.
. (C) Copyright 2002
. Sysgo Real-Time Solutions, GmbH <www.elinos.com>
. Rolf Offermanns <rof@sysgo.de>
.
. This program is free software; you can redistribute it and/or modify
. it under the terms of the GNU General Public License as published by
. the Free Software Foundation; either version 2 of the License, or
. (at your option) any later version.
.
. This program is distributed in the hope that it will be useful,
. but WITHOUT ANY WARRANTY; without even the implied warranty of
. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
. GNU General Public License for more details.
.
. You should have received a copy of the GNU General Public License
. along with this program; if not, write to the Free Software
. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
.
----------------------------------------------------------------------------*/
#include <common.h>
#include <command.h>
#include <net.h>
#ifdef CONFIG_DRIVER_3C589
#include "3c589.h"
/* Use power-down feature of the chip */
#define POWER_DOWN 0
#define NO_AUTOPROBE
static const char version[] =
"Your ad here! :P\n";
#undef EL_DEBUG
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned long int dword;
/*------------------------------------------------------------------------
.
. Configuration options, for the experienced user to change.
.
-------------------------------------------------------------------------*/
/*
. Wait time for memory to be free. This probably shouldn't be
. tuned that much, as waiting for this means nothing else happens
. in the system
*/
#define MEMORY_WAIT_TIME 16
#if (EL_DEBUG > 2 )
#define PRINTK3(args...) printf(args)
#else
#define PRINTK3(args...)
#endif
#if EL_DEBUG > 1
#define PRINTK2(args...) printf(args)
#else
#define PRINTK2(args...)
#endif
#ifdef EL_DEBUG
#define PRINTK(args...) printf(args)
#else
#define PRINTK(args...)
#endif
#define outb(args...) mmio_outb(args)
#define mmio_outb(value, addr) (*((volatile byte *)(addr)) = value)
#define inb(args...) mmio_inb(args)
#define mmio_inb(addr) (*((volatile byte *)(addr)))
#define outw(args...) mmio_outw(args)
#define mmio_outw(value, addr) (*((volatile word *)(addr)) = value)
#define inw(args...) mmio_inw(args)
#define mmio_inw(addr) (*((volatile word *)(addr)))
#define outsw(args...) mmio_outsw(args)
#define mmio_outsw(r,b,l) ({ int __i; \
word *__b2; \
__b2 = (word *) b; \
for (__i = 0; __i < l; __i++) { \
mmio_outw( *(__b2 + __i), r); \
} \
})
#define insw(args...) mmio_insw(args)
#define mmio_insw(r,b,l) ({ int __i ; \
word *__b2; \
__b2 = (word *) b; \
for (__i = 0; __i < l; __i++) { \
*(__b2 + __i) = mmio_inw(r); \
mmio_inw(0); \
}; \
})
/*------------------------------------------------------------------------
.
. The internal workings of the driver. If you are changing anything
. here with the 3Com stuff, you should have the datasheet and know
. what you are doing.
.
-------------------------------------------------------------------------*/
#define EL_BASE_ADDR 0x20000000
/* Offsets from base I/O address. */
#define EL3_DATA 0x00
#define EL3_TIMER 0x0a
#define EL3_CMD 0x0e
#define EL3_STATUS 0x0e
#define EEPROM_READ 0x0080
#define EL3WINDOW(win_num) mmio_outw(SelectWindow + (win_num), EL_BASE_ADDR + EL3_CMD)
/* The top five bits written to EL3_CMD are a command, the lower
11 bits are the parameter, if applicable. */
enum c509cmd {
TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11,
RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, RxDiscard = 8<<11,
TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11,
FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11,
SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11,
StatsDisable = 22<<11, StopCoax = 23<<11,
};
enum c509status {
IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
IntReq = 0x0040, StatsFull = 0x0080, CmdBusy = 0x1000
};
/* The SetRxFilter command accepts the following classes: */
enum RxFilter {
RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8
};
/* Register window 1 offsets, the window used in normal operation. */
#define TX_FIFO 0x00
#define RX_FIFO 0x00
#define RX_STATUS 0x08
#define TX_STATUS 0x0B
#define TX_FREE 0x0C /* Remaining free bytes in Tx buffer. */
/*
Read a word from the EEPROM using the regular EEPROM access register.
Assume that we are in register window zero.
*/
static word read_eeprom(dword ioaddr, int index)
{
int i;
outw(EEPROM_READ + index, ioaddr + 0xa);
/* Reading the eeprom takes 162 us */
for (i = 1620; i >= 0; i--)
if ((inw(ioaddr + 10) & EEPROM_BUSY) == 0)
break;
return inw(ioaddr + 0xc);
}
static void el_get_mac_addr( unsigned char *mac_addr )
{
int i;
union
{
word w;
unsigned char b[2];
} wrd;
unsigned char old_window = inw( EL_BASE_ADDR + EL3_STATUS ) >> 13;
GO_WINDOW(0);
VX_BUSY_WAIT;
for (i = 0; i < 3; i++)
{
wrd.w = read_eeprom(EL_BASE_ADDR, 0xa+i);
#ifdef __BIG_ENDIAN
mac_addr[2*i] = wrd.b[0];
mac_addr[2*i+1] = wrd.b[1];
#else
mac_addr[2*i] = wrd.b[1];
mac_addr[2*i+1] = wrd.b[0];
#endif
}
GO_WINDOW(old_window);
VX_BUSY_WAIT;
}
#if EL_DEBUG > 1
static void print_packet( byte * buf, int length )
{
int i;
int remainder;
int lines;
PRINTK2("Packet of length %d \n", length );
lines = length / 16;
remainder = length % 16;
for ( i = 0; i < lines ; i ++ ) {
int cur;
for ( cur = 0; cur < 8; cur ++ ) {
byte a, b;
a = *(buf ++ );
b = *(buf ++ );
PRINTK2("%02x%02x ", a, b );
}
PRINTK2("\n");
}
for ( i = 0; i < remainder/2 ; i++ ) {
byte a, b;
a = *(buf ++ );
b = *(buf ++ );
PRINTK2("%02x%02x ", a, b );
}
PRINTK2("\n");
}
#endif /* EL_DEBUG > 1 */
/**************************************************************************
ETH_RESET - Reset adapter
***************************************************************************/
static void el_reset(bd_t *bd)
{
/***********************************************************
Reset 3Com 595 card
*************************************************************/
/* QUICK HACK
* - adjust timing for 3c589
* - enable io for PCMCIA */
outw(0x0004, 0xa0000018);
udelay(100);
outw(0x0041, 0x28010000);
udelay(100);
/* issue global reset */
outw(GLOBAL_RESET, BASE + VX_COMMAND);
/* must wait for at least 1ms */
udelay(100000000);
/* set mac addr */
{
unsigned char *mac_addr = bd->bi_enetaddr;
int i;
el_get_mac_addr( mac_addr );
GO_WINDOW(2);
VX_BUSY_WAIT;
printf("3C589 MAC Addr.: ");
for (i = 0; i < 6; i++)
{
printf("%02x", mac_addr[i]);
outb(mac_addr[i], BASE + VX_W2_ADDR_0 + i);
VX_BUSY_WAIT;
}
printf("\n\n");
}
/* set RX filter */
outw(SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST, BASE + VX_COMMAND);
VX_BUSY_WAIT;
/* set irq mask and read_zero */
outw(SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
VX_BUSY_WAIT;
outw(SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
VX_BUSY_WAIT;
/* enable TP Linkbeat */
GO_WINDOW(4);
VX_BUSY_WAIT;
outw( ENABLE_UTP, BASE + VX_W4_MEDIA_TYPE);
VX_BUSY_WAIT;
/*
* Attempt to get rid of any stray interrupts that occured during
* configuration. On the i386 this isn't possible because one may
* already be queued. However, a single stray interrupt is
* unimportant.
*/
outw(ACK_INTR | 0xff, BASE + VX_COMMAND);
VX_BUSY_WAIT;
/* enable TX and RX */
outw( RX_ENABLE, BASE + VX_COMMAND );
VX_BUSY_WAIT;
outw( TX_ENABLE, BASE + VX_COMMAND );
VX_BUSY_WAIT;
/* print the diag. regs. */
PRINTK2("Diag. Regs\n");
PRINTK2("--> MEDIA_TYPE: %04x\n", inw(BASE + VX_W4_MEDIA_TYPE));
PRINTK2("--> NET_DIAG: %04x\n", inw(BASE + VX_W4_NET_DIAG));
PRINTK2("--> FIFO_DIAG: %04x\n", inw(BASE + VX_W4_FIFO_DIAG));
PRINTK2("--> CTRLR_STATUS: %04x\n", inw(BASE + VX_W4_CTRLR_STATUS));
PRINTK2("\n\n");
/* enter working mode */
GO_WINDOW(1);
VX_BUSY_WAIT;
/* wait for another 1ms */
udelay(100000000);
}
/*-----------------------------------------------------------------
.
. The driver can be entered at any of the following entry points.
.
.------------------------------------------------------------------ */
extern int eth_init(bd_t *bd);
extern void eth_halt(void);
extern int eth_rx(void);
extern int eth_send(volatile void *packet, int length);
/*
------------------------------------------------------------
.
. Internal routines
.
------------------------------------------------------------
*/
int eth_init(bd_t *bd)
{
el_reset(bd);
return 0;
}
void eth_halt() {
return;
}
#define EDEBUG 1
/**************************************************************************
ETH_POLL - Wait for a frame
***************************************************************************/
int eth_rx()
{
word status, rx_status, packet_size;
VX_BUSY_WAIT;
status = inw( BASE + VX_STATUS );
if ( (status & S_RX_COMPLETE) == 0 ) return 0; /* nothing to do */
/* Packet waiting -> check RX_STATUS */
rx_status = inw( BASE + VX_W1_RX_STATUS );
if ( rx_status & ERR_RX )
{
/* error in packet -> discard */
PRINTK("[ERROR] Invalid packet -> discarding\n");
PRINTK("-- error code 0x%02x\n", rx_status & ERR_MASK);
PRINTK("-- rx bytes 0x%04d\n", rx_status & ((1<<11) - 1));
PRINTK("[ERROR] Invalid packet -> discarding\n");
outw( RX_DISCARD_TOP_PACK, BASE + VX_COMMAND );
return 0;
}
/* correct pack. waiting in fifo */
packet_size = rx_status & RX_BYTES_MASK;
PRINTK("Correct packet waiting in fifo, size: %d\n", packet_size);
{
volatile word *packet_start = (word *)(BASE + VX_W1_RX_PIO_RD_1);
word *RcvBuffer = (word *)(NetRxPackets[0]);
int wcount = 0;
for (wcount = 0; wcount < (packet_size >> 1); wcount++)
{
*RcvBuffer++ = *(packet_start);
}
/* handle odd packets */
if ( packet_size & 1 )
{
*RcvBuffer++ = *(packet_start);
}
}
/* fifo should now be empty (besides the padding bytes) */
if ( ((*((word *)(BASE + VX_W1_RX_STATUS))) & RX_BYTES_MASK) > 3 )
{
PRINTK("[ERROR] Fifo not empty after packet read (remaining pkts: %d)\n",
(((*(word *)(BASE + VX_W1_RX_STATUS))) & RX_BYTES_MASK));
}
/* discard packet */
*((word *)(BASE + VX_COMMAND)) = RX_DISCARD_TOP_PACK;
/* Pass Packets to upper Layer */
NetReceive(NetRxPackets[0], packet_size);
return packet_size;
}
/**************************************************************************
ETH_TRANSMIT - Transmit a frame
***************************************************************************/
static char padmap[] = {
0, 3, 2, 1};
int eth_send(volatile void *packet, int length) {
int pad;
int status;
volatile word *buf = (word *)packet;
int dummy = 0;
/* padding stuff */
pad = padmap[length & 3];
PRINTK("eth_send(), length: %d\n", length);
/* drop acknowledgements */
while(( status=inb(EL_BASE_ADDR + VX_W1_TX_STATUS) )& TXS_COMPLETE ) {
if(status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {
outw(TX_RESET, EL_BASE_ADDR + VX_COMMAND);
outw(TX_ENABLE, EL_BASE_ADDR + VX_COMMAND);
PRINTK("Bad status, resetting and reenabling transmitter\n");
}
outb(0x0, EL_BASE_ADDR + VX_W1_TX_STATUS);
}
while (inw(EL_BASE_ADDR + VX_W1_FREE_TX) < length + pad + 4) {
/* no room in FIFO */
if (dummy == 0)
{
PRINTK("No room in FIFO, waiting...\n");
dummy++;
}
}
PRINTK(" ---> FIFO ready\n");
outw(length, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
/* Second dword meaningless */
outw(0x0, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
#if EL_DEBUG > 1
print_packet((byte *)buf, length);
#endif
/* write packet */
{
unsigned int i, totw;
totw = ((length + 1) >> 1);
PRINTK("Buffer: (totw = %d)\n", totw);
for (i = 0; i < totw; i++) {
outw( *(buf+i), EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
udelay(10);
}
if(totw & 1)
{ /* pad to double word length */
outw( 0, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
udelay(10);
}
PRINTK("\n\n");
}
/* wait for Tx complete */
PRINTK("Waiting for Tx to complete...\n");
while(((status = inw(EL_BASE_ADDR + VX_STATUS)) & S_COMMAND_IN_PROGRESS) != 0)
{
udelay(10);
}
PRINTK(" ---> Tx completed, status = 0x%04x\n", status);
return length;
}
#endif /* CONFIG_DRIVER_3C589 */

444
drivers/bcm570x_autoneg.c Normal file
View File

@ -0,0 +1,444 @@
/******************************************************************************/
/* */
/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2001 Broadcom */
/* Corporation. */
/* All rights reserved. */
/* */
/* 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, located in the file LICENSE. */
/* */
/* History: */
/******************************************************************************/
#if !defined(CONFIG_NET_MULTI)
#if INCLUDE_TBI_SUPPORT
#include "bcm570x_autoneg.h"
#include "bcm570x_mm.h"
/******************************************************************************/
/* Description: */
/* */
/* Return: */
/******************************************************************************/
void
MM_AnTxConfig(
PAN_STATE_INFO pAnInfo)
{
PLM_DEVICE_BLOCK pDevice;
pDevice = (PLM_DEVICE_BLOCK) pAnInfo->pContext;
REG_WR(pDevice, MacCtrl.TxAutoNeg, (LM_UINT32) pAnInfo->TxConfig.AsUSHORT);
pDevice->MacMode |= MAC_MODE_SEND_CONFIGS;
REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
}
/******************************************************************************/
/* Description: */
/* */
/* Return: */
/******************************************************************************/
void
MM_AnTxIdle(
PAN_STATE_INFO pAnInfo)
{
PLM_DEVICE_BLOCK pDevice;
pDevice = (PLM_DEVICE_BLOCK) pAnInfo->pContext;
pDevice->MacMode &= ~MAC_MODE_SEND_CONFIGS;
REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
}
/******************************************************************************/
/* Description: */
/* */
/* Return: */
/******************************************************************************/
char
MM_AnRxConfig(
PAN_STATE_INFO pAnInfo,
unsigned short *pRxConfig)
{
PLM_DEVICE_BLOCK pDevice;
LM_UINT32 Value32;
char Retcode;
Retcode = AN_FALSE;
pDevice = (PLM_DEVICE_BLOCK) pAnInfo->pContext;
Value32 = REG_RD(pDevice, MacCtrl.Status);
if(Value32 & MAC_STATUS_RECEIVING_CFG)
{
Value32 = REG_RD(pDevice, MacCtrl.RxAutoNeg);
*pRxConfig = (unsigned short) Value32;
Retcode = AN_TRUE;
}
return Retcode;
}
/******************************************************************************/
/* Description: */
/* */
/* Return: */
/******************************************************************************/
void
AutonegInit(
PAN_STATE_INFO pAnInfo)
{
unsigned long j;
for(j = 0; j < sizeof(AN_STATE_INFO); j++)
{
((unsigned char *) pAnInfo)[j] = 0;
}
/* Initialize the default advertisement register. */
pAnInfo->mr_adv_full_duplex = 1;
pAnInfo->mr_adv_sym_pause = 1;
pAnInfo->mr_adv_asym_pause = 1;
pAnInfo->mr_an_enable = 1;
}
/******************************************************************************/
/* Description: */
/* */
/* Return: */
/******************************************************************************/
AUTONEG_STATUS
Autoneg8023z(
PAN_STATE_INFO pAnInfo)
{
unsigned short RxConfig;
unsigned long Delta_us;
AUTONEG_STATUS AnRet;
/* Get the current time. */
if(pAnInfo->State == AN_STATE_UNKNOWN)
{
pAnInfo->RxConfig.AsUSHORT = 0;
pAnInfo->CurrentTime_us = 0;
pAnInfo->LinkTime_us = 0;
pAnInfo->AbilityMatchCfg = 0;
pAnInfo->AbilityMatchCnt = 0;
pAnInfo->AbilityMatch = AN_FALSE;
pAnInfo->IdleMatch = AN_FALSE;
pAnInfo->AckMatch = AN_FALSE;
}
/* Increment the timer tick. This function is called every microsecon. */
/* pAnInfo->CurrentTime_us++; */
/* Set the AbilityMatch, IdleMatch, and AckMatch flags if their */
/* corresponding conditions are satisfied. */
if(MM_AnRxConfig(pAnInfo, &RxConfig))
{
if(RxConfig != pAnInfo->AbilityMatchCfg)
{
pAnInfo->AbilityMatchCfg = RxConfig;
pAnInfo->AbilityMatch = AN_FALSE;
pAnInfo->AbilityMatchCnt = 0;
}
else
{
pAnInfo->AbilityMatchCnt++;
if(pAnInfo->AbilityMatchCnt > 1)
{
pAnInfo->AbilityMatch = AN_TRUE;
pAnInfo->AbilityMatchCfg = RxConfig;
}
}
if(RxConfig & AN_CONFIG_ACK)
{
pAnInfo->AckMatch = AN_TRUE;
}
else
{
pAnInfo->AckMatch = AN_FALSE;
}
pAnInfo->IdleMatch = AN_FALSE;
}
else
{
pAnInfo->IdleMatch = AN_TRUE;
pAnInfo->AbilityMatchCfg = 0;
pAnInfo->AbilityMatchCnt = 0;
pAnInfo->AbilityMatch = AN_FALSE;
pAnInfo->AckMatch = AN_FALSE;
RxConfig = 0;
}
/* Save the last Config. */
pAnInfo->RxConfig.AsUSHORT = RxConfig;
/* Default return code. */
AnRet = AUTONEG_STATUS_OK;
/* Autoneg state machine as defined in 802.3z section 37.3.1.5. */
switch(pAnInfo->State)
{
case AN_STATE_UNKNOWN:
if(pAnInfo->mr_an_enable || pAnInfo->mr_restart_an)
{
pAnInfo->CurrentTime_us = 0;
pAnInfo->State = AN_STATE_AN_ENABLE;
}
/* Fall through.*/
case AN_STATE_AN_ENABLE:
pAnInfo->mr_an_complete = AN_FALSE;
pAnInfo->mr_page_rx = AN_FALSE;
if(pAnInfo->mr_an_enable)
{
pAnInfo->LinkTime_us = 0;
pAnInfo->AbilityMatchCfg = 0;
pAnInfo->AbilityMatchCnt = 0;
pAnInfo->AbilityMatch = AN_FALSE;
pAnInfo->IdleMatch = AN_FALSE;
pAnInfo->AckMatch = AN_FALSE;
pAnInfo->State = AN_STATE_AN_RESTART_INIT;
}
else
{
pAnInfo->State = AN_STATE_DISABLE_LINK_OK;
}
break;
case AN_STATE_AN_RESTART_INIT:
pAnInfo->LinkTime_us = pAnInfo->CurrentTime_us;
pAnInfo->mr_np_loaded = AN_FALSE;
pAnInfo->TxConfig.AsUSHORT = 0;
MM_AnTxConfig(pAnInfo);
AnRet = AUTONEG_STATUS_TIMER_ENABLED;
pAnInfo->State = AN_STATE_AN_RESTART;
/* Fall through.*/
case AN_STATE_AN_RESTART:
/* Get the current time and compute the delta with the saved */
/* link timer. */
Delta_us = pAnInfo->CurrentTime_us - pAnInfo->LinkTime_us;
if(Delta_us > AN_LINK_TIMER_INTERVAL_US)
{
pAnInfo->State = AN_STATE_ABILITY_DETECT_INIT;
}
else
{
AnRet = AUTONEG_STATUS_TIMER_ENABLED;
}
break;
case AN_STATE_DISABLE_LINK_OK:
AnRet = AUTONEG_STATUS_DONE;
break;
case AN_STATE_ABILITY_DETECT_INIT:
/* Note: in the state diagram, this variable is set to */
/* mr_adv_ability<12>. Is this right?. */
pAnInfo->mr_toggle_tx = AN_FALSE;
/* Send the config as advertised in the advertisement register. */
pAnInfo->TxConfig.AsUSHORT = 0;
pAnInfo->TxConfig.D5_FD = pAnInfo->mr_adv_full_duplex;
pAnInfo->TxConfig.D6_HD = pAnInfo->mr_adv_half_duplex;
pAnInfo->TxConfig.D7_PS1 = pAnInfo->mr_adv_sym_pause;
pAnInfo->TxConfig.D8_PS2 = pAnInfo->mr_adv_asym_pause;
pAnInfo->TxConfig.D12_RF1 = pAnInfo->mr_adv_remote_fault1;
pAnInfo->TxConfig.D13_RF2 = pAnInfo->mr_adv_remote_fault2;
pAnInfo->TxConfig.D15_NP = pAnInfo->mr_adv_next_page;
MM_AnTxConfig(pAnInfo);
pAnInfo->State = AN_STATE_ABILITY_DETECT;
break;
case AN_STATE_ABILITY_DETECT:
if(pAnInfo->AbilityMatch == AN_TRUE &&
pAnInfo->RxConfig.AsUSHORT != 0)
{
pAnInfo->State = AN_STATE_ACK_DETECT_INIT;
}
break;
case AN_STATE_ACK_DETECT_INIT:
pAnInfo->TxConfig.D14_ACK = 1;
MM_AnTxConfig(pAnInfo);
pAnInfo->State = AN_STATE_ACK_DETECT;
/* Fall through. */
case AN_STATE_ACK_DETECT:
if(pAnInfo->AckMatch == AN_TRUE)
{
if((pAnInfo->RxConfig.AsUSHORT & ~AN_CONFIG_ACK) ==
(pAnInfo->AbilityMatchCfg & ~AN_CONFIG_ACK))
{
pAnInfo->State = AN_STATE_COMPLETE_ACK_INIT;
}
else
{
pAnInfo->State = AN_STATE_AN_ENABLE;
}
}
else if(pAnInfo->AbilityMatch == AN_TRUE &&
pAnInfo->RxConfig.AsUSHORT == 0)
{
pAnInfo->State = AN_STATE_AN_ENABLE;
}
break;
case AN_STATE_COMPLETE_ACK_INIT:
/* Make sure invalid bits are not set. */
if(pAnInfo->RxConfig.bits.D0 || pAnInfo->RxConfig.bits.D1 ||
pAnInfo->RxConfig.bits.D2 || pAnInfo->RxConfig.bits.D3 ||
pAnInfo->RxConfig.bits.D4 || pAnInfo->RxConfig.bits.D9 ||
pAnInfo->RxConfig.bits.D10 || pAnInfo->RxConfig.bits.D11)
{
AnRet = AUTONEG_STATUS_FAILED;
break;
}
/* Set up the link partner advertisement register. */
pAnInfo->mr_lp_adv_full_duplex = pAnInfo->RxConfig.D5_FD;
pAnInfo->mr_lp_adv_half_duplex = pAnInfo->RxConfig.D6_HD;
pAnInfo->mr_lp_adv_sym_pause = pAnInfo->RxConfig.D7_PS1;
pAnInfo->mr_lp_adv_asym_pause = pAnInfo->RxConfig.D8_PS2;
pAnInfo->mr_lp_adv_remote_fault1 = pAnInfo->RxConfig.D12_RF1;
pAnInfo->mr_lp_adv_remote_fault2 = pAnInfo->RxConfig.D13_RF2;
pAnInfo->mr_lp_adv_next_page = pAnInfo->RxConfig.D15_NP;
pAnInfo->LinkTime_us = pAnInfo->CurrentTime_us;
pAnInfo->mr_toggle_tx = !pAnInfo->mr_toggle_tx;
pAnInfo->mr_toggle_rx = pAnInfo->RxConfig.bits.D11;
pAnInfo->mr_np_rx = pAnInfo->RxConfig.D15_NP;
pAnInfo->mr_page_rx = AN_TRUE;
pAnInfo->State = AN_STATE_COMPLETE_ACK;
AnRet = AUTONEG_STATUS_TIMER_ENABLED;
break;
case AN_STATE_COMPLETE_ACK:
if(pAnInfo->AbilityMatch == AN_TRUE &&
pAnInfo->RxConfig.AsUSHORT == 0)
{
pAnInfo->State = AN_STATE_AN_ENABLE;
break;
}
Delta_us = pAnInfo->CurrentTime_us - pAnInfo->LinkTime_us;
if(Delta_us > AN_LINK_TIMER_INTERVAL_US)
{
if(pAnInfo->mr_adv_next_page == 0 ||
pAnInfo->mr_lp_adv_next_page == 0)
{
pAnInfo->State = AN_STATE_IDLE_DETECT_INIT;
}
else
{
if(pAnInfo->TxConfig.bits.D15 == 0 &&
pAnInfo->mr_np_rx == 0)
{
pAnInfo->State = AN_STATE_IDLE_DETECT_INIT;
}
else
{
AnRet = AUTONEG_STATUS_FAILED;
}
}
}
break;
case AN_STATE_IDLE_DETECT_INIT:
pAnInfo->LinkTime_us = pAnInfo->CurrentTime_us;
MM_AnTxIdle(pAnInfo);
pAnInfo->State = AN_STATE_IDLE_DETECT;
AnRet = AUTONEG_STATUS_TIMER_ENABLED;
break;
case AN_STATE_IDLE_DETECT:
if(pAnInfo->AbilityMatch == AN_TRUE &&
pAnInfo->RxConfig.AsUSHORT == 0)
{
pAnInfo->State = AN_STATE_AN_ENABLE;
break;
}
Delta_us = pAnInfo->CurrentTime_us - pAnInfo->LinkTime_us;
if(Delta_us > AN_LINK_TIMER_INTERVAL_US)
{
#if 0
/* if(pAnInfo->IdleMatch == AN_TRUE) */
/* { */
#endif
pAnInfo->State = AN_STATE_LINK_OK;
#if 0
/* } */
/* else */
/* { */
/* AnRet = AUTONEG_STATUS_FAILED; */
/* break; */
/* } */
#endif
}
break;
case AN_STATE_LINK_OK:
pAnInfo->mr_an_complete = AN_TRUE;
pAnInfo->mr_link_ok = AN_TRUE;
AnRet = AUTONEG_STATUS_DONE;
break;
case AN_STATE_NEXT_PAGE_WAIT_INIT:
break;
case AN_STATE_NEXT_PAGE_WAIT:
break;
default:
AnRet = AUTONEG_STATUS_FAILED;
break;
}
return AnRet;
}
#endif /* INCLUDE_TBI_SUPPORT */
#endif /* !defined(CONFIG_NET_MULTI) */

256
drivers/cs8900.h Normal file
View File

@ -0,0 +1,256 @@
/*
* Cirrus Logic CS8900A Ethernet
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* Copyright (C) 1999 Ben Williamson <benw@pobox.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is loaded into SRAM in bootstrap mode, where it waits
* for commands on UART1 to read and write memory, jump to code etc.
* A design goal for this program is to be entirely independent of the
* target board. Anything with a CL-PS7111 or EP7211 should be able to run
* this code in bootstrap mode. All the board specifics can be handled on
* the host.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <asm/types.h>
#include <config.h>
#ifdef CONFIG_DRIVER_CS8900
/* although the registers are 16 bit, they are 32-bit aligned on the
EDB7111. so we have to read them as 32-bit registers and ignore the
upper 16-bits. i'm not sure if this holds for the EDB7211. */
#ifdef CS8900_BUS16
/* 16 bit aligned registers, 16 bit wide */
#define CS8900_REG u16
#define CS8900_OFF 0x02
#define CS8900_BUS16_0 *(volatile u8 *)(CS8900_BASE+0x00)
#define CS8900_BUS16_1 *(volatile u8 *)(CS8900_BASE+0x01)
#elif CS8900_BUS32
/* 32 bit aligned registers, 16 bit wide (we ignore upper 16 bits) */
#define CS8900_REG u32
#define CS8900_OFF 0x04
#else
#error unknown bussize ...
#endif
#define CS8900_RTDATA *(volatile CS8900_REG *)(CS8900_BASE+0x00*CS8900_OFF)
#define CS8900_TxCMD *(volatile CS8900_REG *)(CS8900_BASE+0x02*CS8900_OFF)
#define CS8900_TxLEN *(volatile CS8900_REG *)(CS8900_BASE+0x03*CS8900_OFF)
#define CS8900_ISQ *(volatile CS8900_REG *)(CS8900_BASE+0x04*CS8900_OFF)
#define CS8900_PPTR *(volatile CS8900_REG *)(CS8900_BASE+0x05*CS8900_OFF)
#define CS8900_PDATA *(volatile CS8900_REG *)(CS8900_BASE+0x06*CS8900_OFF)
#define ISQ_RxEvent 0x04
#define ISQ_TxEvent 0x08
#define ISQ_BufEvent 0x0C
#define ISQ_RxMissEvent 0x10
#define ISQ_TxColEvent 0x12
#define ISQ_EventMask 0x3F
/* packet page register offsets */
/* bus interface registers */
#define PP_ChipID 0x0000 /* Chip identifier - must be 0x630E */
#define PP_ChipRev 0x0002 /* Chip revision, model codes */
#define PP_IntReg 0x0022 /* Interrupt configuration */
#define PP_IntReg_IRQ0 0x0000 /* Use INTR0 pin */
#define PP_IntReg_IRQ1 0x0001 /* Use INTR1 pin */
#define PP_IntReg_IRQ2 0x0002 /* Use INTR2 pin */
#define PP_IntReg_IRQ3 0x0003 /* Use INTR3 pin */
/* status and control registers */
#define PP_RxCFG 0x0102 /* Receiver configuration */
#define PP_RxCFG_Skip1 0x0040 /* Skip (i.e. discard) current frame */
#define PP_RxCFG_Stream 0x0080 /* Enable streaming mode */
#define PP_RxCFG_RxOK 0x0100 /* RxOK interrupt enable */
#define PP_RxCFG_RxDMAonly 0x0200 /* Use RxDMA for all frames */
#define PP_RxCFG_AutoRxDMA 0x0400 /* Select RxDMA automatically */
#define PP_RxCFG_BufferCRC 0x0800 /* Include CRC characters in frame */
#define PP_RxCFG_CRC 0x1000 /* Enable interrupt on CRC error */
#define PP_RxCFG_RUNT 0x2000 /* Enable interrupt on RUNT frames */
#define PP_RxCFG_EXTRA 0x4000 /* Enable interrupt on frames with extra data */
#define PP_RxCTL 0x0104 /* Receiver control */
#define PP_RxCTL_IAHash 0x0040 /* Accept frames that match hash */
#define PP_RxCTL_Promiscuous 0x0080 /* Accept any frame */
#define PP_RxCTL_RxOK 0x0100 /* Accept well formed frames */
#define PP_RxCTL_Multicast 0x0200 /* Accept multicast frames */
#define PP_RxCTL_IA 0x0400 /* Accept frame that matches IA */
#define PP_RxCTL_Broadcast 0x0800 /* Accept broadcast frames */
#define PP_RxCTL_CRC 0x1000 /* Accept frames with bad CRC */
#define PP_RxCTL_RUNT 0x2000 /* Accept runt frames */
#define PP_RxCTL_EXTRA 0x4000 /* Accept frames that are too long */
#define PP_TxCFG 0x0106 /* Transmit configuration */
#define PP_TxCFG_CRS 0x0040 /* Enable interrupt on loss of carrier */
#define PP_TxCFG_SQE 0x0080 /* Enable interrupt on Signal Quality Error */
#define PP_TxCFG_TxOK 0x0100 /* Enable interrupt on successful xmits */
#define PP_TxCFG_Late 0x0200 /* Enable interrupt on "out of window" */
#define PP_TxCFG_Jabber 0x0400 /* Enable interrupt on jabber detect */
#define PP_TxCFG_Collision 0x0800 /* Enable interrupt if collision */
#define PP_TxCFG_16Collisions 0x8000 /* Enable interrupt if > 16 collisions */
#define PP_TxCmd 0x0108 /* Transmit command status */
#define PP_TxCmd_TxStart_5 0x0000 /* Start after 5 bytes in buffer */
#define PP_TxCmd_TxStart_381 0x0040 /* Start after 381 bytes in buffer */
#define PP_TxCmd_TxStart_1021 0x0080 /* Start after 1021 bytes in buffer */
#define PP_TxCmd_TxStart_Full 0x00C0 /* Start after all bytes loaded */
#define PP_TxCmd_Force 0x0100 /* Discard any pending packets */
#define PP_TxCmd_OneCollision 0x0200 /* Abort after a single collision */
#define PP_TxCmd_NoCRC 0x1000 /* Do not add CRC */
#define PP_TxCmd_NoPad 0x2000 /* Do not pad short packets */
#define PP_BufCFG 0x010A /* Buffer configuration */
#define PP_BufCFG_SWI 0x0040 /* Force interrupt via software */
#define PP_BufCFG_RxDMA 0x0080 /* Enable interrupt on Rx DMA */
#define PP_BufCFG_TxRDY 0x0100 /* Enable interrupt when ready for Tx */
#define PP_BufCFG_TxUE 0x0200 /* Enable interrupt in Tx underrun */
#define PP_BufCFG_RxMiss 0x0400 /* Enable interrupt on missed Rx packets */
#define PP_BufCFG_Rx128 0x0800 /* Enable Rx interrupt after 128 bytes */
#define PP_BufCFG_TxCol 0x1000 /* Enable int on Tx collision ctr overflow */
#define PP_BufCFG_Miss 0x2000 /* Enable int on Rx miss ctr overflow */
#define PP_BufCFG_RxDest 0x8000 /* Enable int on Rx dest addr match */
#define PP_LineCTL 0x0112 /* Line control */
#define PP_LineCTL_Rx 0x0040 /* Enable receiver */
#define PP_LineCTL_Tx 0x0080 /* Enable transmitter */
#define PP_LineCTL_AUIonly 0x0100 /* AUI interface only */
#define PP_LineCTL_AutoAUI10BT 0x0200 /* Autodetect AUI or 10BaseT interface */
#define PP_LineCTL_ModBackoffE 0x0800 /* Enable modified backoff algorithm */
#define PP_LineCTL_PolarityDis 0x1000 /* Disable Rx polarity autodetect */
#define PP_LineCTL_2partDefDis 0x2000 /* Disable two-part defferal */
#define PP_LineCTL_LoRxSquelch 0x4000 /* Reduce receiver squelch threshold */
#define PP_SelfCTL 0x0114 /* Chip self control */
#define PP_SelfCTL_Reset 0x0040 /* Self-clearing reset */
#define PP_SelfCTL_SWSuspend 0x0100 /* Initiate suspend mode */
#define PP_SelfCTL_HWSleepE 0x0200 /* Enable SLEEP input */
#define PP_SelfCTL_HWStandbyE 0x0400 /* Enable standby mode */
#define PP_SelfCTL_HC0E 0x1000 /* use HCB0 for LINK LED */
#define PP_SelfCTL_HC1E 0x2000 /* use HCB1 for BSTATUS LED */
#define PP_SelfCTL_HCB0 0x4000 /* control LINK LED if HC0E set */
#define PP_SelfCTL_HCB1 0x8000 /* control BSTATUS LED if HC1E set */
#define PP_BusCTL 0x0116 /* Bus control */
#define PP_BusCTL_ResetRxDMA 0x0040 /* Reset RxDMA pointer */
#define PP_BusCTL_DMAextend 0x0100 /* Extend DMA cycle */
#define PP_BusCTL_UseSA 0x0200 /* Assert MEMCS16 on address decode */
#define PP_BusCTL_MemoryE 0x0400 /* Enable memory mode */
#define PP_BusCTL_DMAburst 0x0800 /* Limit DMA access burst */
#define PP_BusCTL_IOCHRDYE 0x1000 /* Set IOCHRDY high impedence */
#define PP_BusCTL_RxDMAsize 0x2000 /* Set DMA buffer size 64KB */
#define PP_BusCTL_EnableIRQ 0x8000 /* Generate interrupt on interrupt event */
#define PP_TestCTL 0x0118 /* Test control */
#define PP_TestCTL_DisableLT 0x0080 /* Disable link status */
#define PP_TestCTL_ENDECloop 0x0200 /* Internal loopback */
#define PP_TestCTL_AUIloop 0x0400 /* AUI loopback */
#define PP_TestCTL_DisBackoff 0x0800 /* Disable backoff algorithm */
#define PP_TestCTL_FDX 0x4000 /* Enable full duplex mode */
#define PP_ISQ 0x0120 /* Interrupt Status Queue */
#define PP_RER 0x0124 /* Receive event */
#define PP_RER_IAHash 0x0040 /* Frame hash match */
#define PP_RER_Dribble 0x0080 /* Frame had 1-7 extra bits after last byte */
#define PP_RER_RxOK 0x0100 /* Frame received with no errors */
#define PP_RER_Hashed 0x0200 /* Frame address hashed OK */
#define PP_RER_IA 0x0400 /* Frame address matched IA */
#define PP_RER_Broadcast 0x0800 /* Broadcast frame */
#define PP_RER_CRC 0x1000 /* Frame had CRC error */
#define PP_RER_RUNT 0x2000 /* Runt frame */
#define PP_RER_EXTRA 0x4000 /* Frame was too long */
#define PP_TER 0x0128 /* Transmit event */
#define PP_TER_CRS 0x0040 /* Carrier lost */
#define PP_TER_SQE 0x0080 /* Signal Quality Error */
#define PP_TER_TxOK 0x0100 /* Packet sent without error */
#define PP_TER_Late 0x0200 /* Out of window */
#define PP_TER_Jabber 0x0400 /* Stuck transmit? */
#define PP_TER_NumCollisions 0x7800 /* Number of collisions */
#define PP_TER_16Collisions 0x8000 /* > 16 collisions */
#define PP_BER 0x012C /* Buffer event */
#define PP_BER_SWint 0x0040 /* Software interrupt */
#define PP_BER_RxDMAFrame 0x0080 /* Received framed DMAed */
#define PP_BER_Rdy4Tx 0x0100 /* Ready for transmission */
#define PP_BER_TxUnderrun 0x0200 /* Transmit underrun */
#define PP_BER_RxMiss 0x0400 /* Received frame missed */
#define PP_BER_Rx128 0x0800 /* 128 bytes received */
#define PP_BER_RxDest 0x8000 /* Received framed passed address filter */
#define PP_RxMiss 0x0130 /* Receiver miss counter */
#define PP_TxCol 0x0132 /* Transmit collision counter */
#define PP_LineSTAT 0x0134 /* Line status */
#define PP_LineSTAT_LinkOK 0x0080 /* Line is connected and working */
#define PP_LineSTAT_AUI 0x0100 /* Connected via AUI */
#define PP_LineSTAT_10BT 0x0200 /* Connected via twisted pair */
#define PP_LineSTAT_Polarity 0x1000 /* Line polarity OK (10BT only) */
#define PP_LineSTAT_CRS 0x4000 /* Frame being received */
#define PP_SelfSTAT 0x0136 /* Chip self status */
#define PP_SelfSTAT_33VActive 0x0040 /* supply voltage is 3.3V */
#define PP_SelfSTAT_InitD 0x0080 /* Chip initialization complete */
#define PP_SelfSTAT_SIBSY 0x0100 /* EEPROM is busy */
#define PP_SelfSTAT_EEPROM 0x0200 /* EEPROM present */
#define PP_SelfSTAT_EEPROM_OK 0x0400 /* EEPROM checks out */
#define PP_SelfSTAT_ELPresent 0x0800 /* External address latch logic available */
#define PP_SelfSTAT_EEsize 0x1000 /* Size of EEPROM */
#define PP_BusSTAT 0x0138 /* Bus status */
#define PP_BusSTAT_TxBid 0x0080 /* Tx error */
#define PP_BusSTAT_TxRDY 0x0100 /* Ready for Tx data */
#define PP_TDR 0x013C /* AUI Time Domain Reflectometer */
/* initiate transmit registers */
#define PP_TxCommand 0x0144 /* Tx Command */
#define PP_TxLength 0x0146 /* Tx Length */
/* address filter registers */
#define PP_LAF 0x0150 /* Logical address filter (6 bytes) */
#define PP_IA 0x0158 /* Individual address (MAC) */
/* EEPROM Kram */
#define SI_BUSY 0x0100
#define PP_SelfST 0x0136 /* Self State register */
#define PP_EECMD 0x0040 /* NVR Interface Command register */
#define PP_EEData 0x0042 /* NVR Interface Data Register */
#define EEPROM_WRITE_EN 0x00F0
#define EEPROM_WRITE_DIS 0x0000
#define EEPROM_WRITE_CMD 0x0100
#define EEPROM_READ_CMD 0x0200
#endif /* CONFIG_DRIVER_CS8900 */

881
drivers/natsemi.c Normal file
View File

@ -0,0 +1,881 @@
/*
natsemi.c: A U-Boot driver for the NatSemi DP8381x series.
Author: Mark A. Rakes (mark_rakes@vivato.net)
Adapted from an Etherboot driver written by:
Copyright (C) 2001 Entity Cyber, Inc.
This development of this Etherboot driver was funded by
Sicom Systems: http://www.sicompos.com/
Author: Marty Connor (mdc@thinguin.org)
Adapted from a Linux driver which was written by Donald Becker
This software may be used and distributed according to the terms
of the GNU Public License (GPL), incorporated herein by reference.
Original Copyright Notice:
Written/copyright 1999-2001 by Donald Becker.
This software may be used and distributed according to the terms of
the GNU General Public License (GPL), incorporated herein by reference.
Drivers based on or derived from this code fall under the GPL and must
retain the authorship, copyright and license notice. This file is not
a complete program and may only be used when the entire operating
system is licensed under the GPL. License for under other terms may be
available. Contact the original author for details.
The original author may be reached as becker@scyld.com, or at
Scyld Computing Corporation
410 Severn Ave., Suite 210
Annapolis MD 21403
Support information and updates available at
http://www.scyld.com/network/netsemi.html
References:
http://www.scyld.com/expert/100mbps.html
http://www.scyld.com/expert/NWay.html
Datasheet is available from:
http://www.national.com/pf/DP/DP83815.html
*/
/* Revision History
* October 2002 mar 1.0
* Initial U-Boot Release. Tested with Netgear FA311 board
* and dp83815 chipset on custom board
*/
/* Includes */
#include <common.h>
#include <malloc.h>
#include <net.h>
#include <asm/io.h>
#include <pci.h>
#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
defined(CONFIG_NATSEMI)
/* defines */
#define EEPROM_SIZE 0xb /*12 16-bit chunks, or 24 bytes*/
#define DSIZE 0x00000FFF
#define ETH_ALEN 6
#define CRC_SIZE 4
#define TOUT_LOOP 500000
#define TX_BUF_SIZE 1536
#define RX_BUF_SIZE 1536
#define NUM_RX_DESC 4 /* Number of Rx descriptor registers. */
/* Offsets to the device registers.
Unlike software-only systems, device drivers interact with complex hardware.
It's not useful to define symbolic names for every register bit in the
device. */
enum register_offsets {
ChipCmd = 0x00,
ChipConfig = 0x04,
EECtrl = 0x08,
IntrMask = 0x14,
IntrEnable = 0x18,
TxRingPtr = 0x20,
TxConfig = 0x24,
RxRingPtr = 0x30,
RxConfig = 0x34,
ClkRun = 0x3C,
RxFilterAddr = 0x48,
RxFilterData = 0x4C,
SiliconRev = 0x58,
PCIPM = 0x44,
BasicControl = 0x80,
BasicStatus = 0x84,
/* These are from the spec, around page 78... on a separate table. */
PGSEL = 0xCC,
PMDCSR = 0xE4,
TSTDAT = 0xFC,
DSPCFG = 0xF4,
SDCFG = 0x8C
};
/* Bit in ChipCmd. */
enum ChipCmdBits {
ChipReset = 0x100,
RxReset = 0x20,
TxReset = 0x10,
RxOff = 0x08,
RxOn = 0x04,
TxOff = 0x02,
TxOn = 0x01
};
enum ChipConfigBits {
LinkSts = 0x80000000,
HundSpeed = 0x40000000,
FullDuplex = 0x20000000,
TenPolarity = 0x10000000,
AnegDone = 0x08000000,
AnegEnBothBoth = 0x0000E000,
AnegDis100Full = 0x0000C000,
AnegEn100Both = 0x0000A000,
AnegDis100Half = 0x00008000,
AnegEnBothHalf = 0x00006000,
AnegDis10Full = 0x00004000,
AnegEn10Both = 0x00002000,
DuplexMask = 0x00008000,
SpeedMask = 0x00004000,
AnegMask = 0x00002000,
AnegDis10Half = 0x00000000,
ExtPhy = 0x00001000,
PhyRst = 0x00000400,
PhyDis = 0x00000200,
BootRomDisable = 0x00000004,
BEMode = 0x00000001,
};
enum TxConfig_bits {
TxDrthMask = 0x3f,
TxFlthMask = 0x3f00,
TxMxdmaMask = 0x700000,
TxMxdma_512 = 0x0,
TxMxdma_4 = 0x100000,
TxMxdma_8 = 0x200000,
TxMxdma_16 = 0x300000,
TxMxdma_32 = 0x400000,
TxMxdma_64 = 0x500000,
TxMxdma_128 = 0x600000,
TxMxdma_256 = 0x700000,
TxCollRetry = 0x800000,
TxAutoPad = 0x10000000,
TxMacLoop = 0x20000000,
TxHeartIgn = 0x40000000,
TxCarrierIgn = 0x80000000
};
enum RxConfig_bits {
RxDrthMask = 0x3e,
RxMxdmaMask = 0x700000,
RxMxdma_512 = 0x0,
RxMxdma_4 = 0x100000,
RxMxdma_8 = 0x200000,
RxMxdma_16 = 0x300000,
RxMxdma_32 = 0x400000,
RxMxdma_64 = 0x500000,
RxMxdma_128 = 0x600000,
RxMxdma_256 = 0x700000,
RxAcceptLong = 0x8000000,
RxAcceptTx = 0x10000000,
RxAcceptRunt = 0x40000000,
RxAcceptErr = 0x80000000
};
/* Bits in the RxMode register. */
enum rx_mode_bits {
AcceptErr = 0x20,
AcceptRunt = 0x10,
AcceptBroadcast = 0xC0000000,
AcceptMulticast = 0x00200000,
AcceptAllMulticast = 0x20000000,
AcceptAllPhys = 0x10000000,
AcceptMyPhys = 0x08000000
};
typedef struct _BufferDesc {
u32 link;
vu_long cmdsts;
u32 bufptr;
u32 software_use;
} BufferDesc;
/* Bits in network_desc.status */
enum desc_status_bits {
DescOwn = 0x80000000, DescMore = 0x40000000, DescIntr = 0x20000000,
DescNoCRC = 0x10000000, DescPktOK = 0x08000000,
DescSizeMask = 0xfff,
DescTxAbort = 0x04000000, DescTxFIFO = 0x02000000,
DescTxCarrier = 0x01000000, DescTxDefer = 0x00800000,
DescTxExcDefer = 0x00400000, DescTxOOWCol = 0x00200000,
DescTxExcColl = 0x00100000, DescTxCollCount = 0x000f0000,
DescRxAbort = 0x04000000, DescRxOver = 0x02000000,
DescRxDest = 0x01800000, DescRxLong = 0x00400000,
DescRxRunt = 0x00200000, DescRxInvalid = 0x00100000,
DescRxCRC = 0x00080000, DescRxAlign = 0x00040000,
DescRxLoop = 0x00020000, DesRxColl = 0x00010000,
};
/* Globals */
#ifdef NATSEMI_DEBUG
static int natsemi_debug = 0; /* 1 verbose debugging, 0 normal */
#endif
static u32 SavedClkRun;
static unsigned int cur_rx;
static unsigned int advertising;
static unsigned int rx_config;
static unsigned int tx_config;
/* Note: transmit and receive buffers and descriptors must be
longword aligned */
static BufferDesc txd __attribute__ ((aligned(4)));
static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(4)));
static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(4)));
static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE]
__attribute__ ((aligned(4)));
/* Function Prototypes */
#if 0
static void write_eeprom(struct eth_device *dev, long addr, int location,
short value);
#endif
static int read_eeprom(struct eth_device *dev, long addr, int location);
static int mdio_read(struct eth_device *dev, int phy_id, int location);
static int natsemi_init(struct eth_device *dev, bd_t * bis);
static void natsemi_reset(struct eth_device *dev);
static void natsemi_init_rxfilter(struct eth_device *dev);
static void natsemi_init_txd(struct eth_device *dev);
static void natsemi_init_rxd(struct eth_device *dev);
static void natsemi_set_rx_mode(struct eth_device *dev);
static void natsemi_check_duplex(struct eth_device *dev);
static int natsemi_send(struct eth_device *dev, volatile void *packet,
int length);
static int natsemi_poll(struct eth_device *dev);
static void natsemi_disable(struct eth_device *dev);
static struct pci_device_id supported[] = {
{PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815},
{}
};
#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a)
#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
static inline int
INW(struct eth_device *dev, u_long addr)
{
return le16_to_cpu(*(vu_short *) (addr + dev->iobase));
}
static int
INL(struct eth_device *dev, u_long addr)
{
return le32_to_cpu(*(vu_long *) (addr + dev->iobase));
}
static inline void
OUTW(struct eth_device *dev, int command, u_long addr)
{
*(vu_short *) ((addr + dev->iobase)) = cpu_to_le16(command);
}
static inline void
OUTL(struct eth_device *dev, int command, u_long addr)
{
*(vu_long *) ((addr + dev->iobase)) = cpu_to_le32(command);
}
/*
* Function: natsemi_initialize
*
* Description: Retrieves the MAC address of the card, and sets up some
* globals required by other routines, and initializes the NIC, making it
* ready to send and receive packets.
*
* Side effects:
* leaves the natsemi initialized, and ready to recieve packets.
*
* Returns: struct eth_device *: pointer to NIC data structure
*/
int
natsemi_initialize(bd_t * bis)
{
pci_dev_t devno;
int card_number = 0;
struct eth_device *dev;
u32 iobase, status, chip_config;
int i, idx = 0;
int prev_eedata;
u32 tmp;
while (1) {
/* Find PCI device(s) */
if ((devno = pci_find_devices(supported, idx++)) < 0) {
break;
}
pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase);
iobase &= ~0x3; /* 1: unused and 0:I/O Space Indicator */
pci_write_config_dword(devno, PCI_COMMAND,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
/* Check if I/O accesses and Bus Mastering are enabled. */
pci_read_config_dword(devno, PCI_COMMAND, &status);
if (!(status & PCI_COMMAND_MEMORY)) {
printf("Error: Can not enable MEM access.\n");
continue;
} else if (!(status & PCI_COMMAND_MASTER)) {
printf("Error: Can not enable Bus Mastering.\n");
continue;
}
dev = (struct eth_device *) malloc(sizeof *dev);
sprintf(dev->name, "dp83815#%d", card_number);
dev->iobase = bus_to_phys(iobase);
#ifdef NATSEMI_DEBUG
printf("natsemi: NatSemi ns8381[56] @ %#x\n", dev->iobase);
#endif
dev->priv = (void *) devno;
dev->init = natsemi_init;
dev->halt = natsemi_disable;
dev->send = natsemi_send;
dev->recv = natsemi_poll;
eth_register(dev);
card_number++;
/* Set the latency timer for value. */
pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20);
udelay(10 * 1000);
/* natsemi has a non-standard PM control register
* in PCI config space. Some boards apparently need
* to be brought to D0 in this manner. */
pci_read_config_dword(devno, PCIPM, &tmp);
if (tmp & (0x03 | 0x100)) {
/* D0 state, disable PME assertion */
u32 newtmp = tmp & ~(0x03 | 0x100);
pci_write_config_dword(devno, PCIPM, newtmp);
}
printf("natsemi: EEPROM contents:\n");
for (i = 0; i <= EEPROM_SIZE; i++) {
short eedata = read_eeprom(dev, EECtrl, i);
printf(" %04hx", eedata);
}
printf("\n");
/* get MAC address */
prev_eedata = read_eeprom(dev, EECtrl, 6);
for (i = 0; i < 3; i++) {
int eedata = read_eeprom(dev, EECtrl, i + 7);
dev->enetaddr[i*2] = (eedata << 1) + (prev_eedata >> 15);
dev->enetaddr[i*2+1] = eedata >> 7;
prev_eedata = eedata;
}
/* Reset the chip to erase any previous misconfiguration. */
OUTL(dev, ChipReset, ChipCmd);
advertising = mdio_read(dev, 1, 4);
chip_config = INL(dev, ChipConfig);
#ifdef NATSEMI_DEBUG
printf("%s: Transceiver status %#08X advertising %#08X\n",
dev->name, (int) INL(dev, BasicStatus), advertising);
printf("%s: Transceiver default autoneg. %s 10%s %s duplex.\n",
dev->name, chip_config & AnegMask ? "enabled, advertise" :
"disabled, force", chip_config & SpeedMask ? "0" : "",
chip_config & DuplexMask ? "full" : "half");
#endif
chip_config |= AnegEnBothBoth;
#ifdef NATSEMI_DEBUG
printf("%s: changed to autoneg. %s 10%s %s duplex.\n",
dev->name, chip_config & AnegMask ? "enabled, advertise" :
"disabled, force", chip_config & SpeedMask ? "0" : "",
chip_config & DuplexMask ? "full" : "half");
#endif
/*write new autoneg bits, reset phy*/
OUTL(dev, (chip_config | PhyRst), ChipConfig);
/*un-reset phy*/
OUTL(dev, chip_config, ChipConfig);
/* Disable PME:
* The PME bit is initialized from the EEPROM contents.
* PCI cards probably have PME disabled, but motherboard
* implementations may have PME set to enable WakeOnLan.
* With PME set the chip will scan incoming packets but
* nothing will be written to memory. */
SavedClkRun = INL(dev, ClkRun);
OUTL(dev, SavedClkRun & ~0x100, ClkRun);
}
return card_number;
}
/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
The EEPROM code is for common 93c06/46 EEPROMs w/ 6bit addresses. */
/* Delay between EEPROM clock transitions.
No extra delay is needed with 33Mhz PCI, but future 66Mhz
access may need a delay. */
#define eeprom_delay(ee_addr) INL(dev, ee_addr)
enum EEPROM_Ctrl_Bits {
EE_ShiftClk = 0x04,
EE_DataIn = 0x01,
EE_ChipSelect = 0x08,
EE_DataOut = 0x02
};
#define EE_Write0 (EE_ChipSelect)
#define EE_Write1 (EE_ChipSelect | EE_DataIn)
/* The EEPROM commands include the alway-set leading bit. */
enum EEPROM_Cmds {
EE_WrEnCmd = (4 << 6), EE_WriteCmd = (5 << 6),
EE_ReadCmd = (6 << 6), EE_EraseCmd = (7 << 6),
};
#if 0
static void
write_eeprom(struct eth_device *dev, long addr, int location, short value)
{
int i;
int ee_addr = (typeof(ee_addr))addr;
short wren_cmd = EE_WrEnCmd | 0x30; /*wren is 100 + 11XXXX*/
short write_cmd = location | EE_WriteCmd;
#ifdef NATSEMI_DEBUG
printf("write_eeprom: %08x, %04hx, %04hx\n",
dev->iobase + ee_addr, write_cmd, value);
#endif
/* Shift the write enable command bits out. */
for (i = 9; i >= 0; i--) {
short cmdval = (wren_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
OUTL(dev, cmdval, ee_addr);
eeprom_delay(ee_addr);
OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
eeprom_delay(ee_addr);
}
OUTL(dev, 0, ee_addr); /*bring chip select low*/
OUTL(dev, EE_ShiftClk, ee_addr);
eeprom_delay(ee_addr);
/* Shift the write command bits out. */
for (i = 9; i >= 0; i--) {
short cmdval = (write_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
OUTL(dev, cmdval, ee_addr);
eeprom_delay(ee_addr);
OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
eeprom_delay(ee_addr);
}
for (i = 0; i < 16; i++) {
short cmdval = (value & (1 << i)) ? EE_Write1 : EE_Write0;
OUTL(dev, cmdval, ee_addr);
eeprom_delay(ee_addr);
OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
eeprom_delay(ee_addr);
}
OUTL(dev, 0, ee_addr); /*bring chip select low*/
OUTL(dev, EE_ShiftClk, ee_addr);
for (i = 0; i < 200000; i++) {
OUTL(dev, EE_Write0, ee_addr); /*poll for done*/
if (INL(dev, ee_addr) & EE_DataOut) {
break; /*finished*/
}
}
eeprom_delay(ee_addr);
/* Terminate the EEPROM access. */
OUTL(dev, EE_Write0, ee_addr);
OUTL(dev, 0, ee_addr);
return;
}
#endif
static int
read_eeprom(struct eth_device *dev, long addr, int location)
{
int i;
int retval = 0;
int ee_addr = (typeof(ee_addr))addr;
int read_cmd = location | EE_ReadCmd;
OUTL(dev, EE_Write0, ee_addr);
/* Shift the read command bits out. */
for (i = 10; i >= 0; i--) {
short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
OUTL(dev, dataval, ee_addr);
eeprom_delay(ee_addr);
OUTL(dev, dataval | EE_ShiftClk, ee_addr);
eeprom_delay(ee_addr);
}
OUTL(dev, EE_ChipSelect, ee_addr);
eeprom_delay(ee_addr);
for (i = 0; i < 16; i++) {
OUTL(dev, EE_ChipSelect | EE_ShiftClk, ee_addr);
eeprom_delay(ee_addr);
retval |= (INL(dev, ee_addr) & EE_DataOut) ? 1 << i : 0;
OUTL(dev, EE_ChipSelect, ee_addr);
eeprom_delay(ee_addr);
}
/* Terminate the EEPROM access. */
OUTL(dev, EE_Write0, ee_addr);
OUTL(dev, 0, ee_addr);
#ifdef NATSEMI_DEBUG
if (natsemi_debug)
printf("read_eeprom: %08x, %08x, retval %08x\n",
dev->iobase + ee_addr, read_cmd, retval);
#endif
return retval;
}
/* MII transceiver control section.
The 83815 series has an internal transceiver, and we present the
management registers as if they were MII connected. */
static int
mdio_read(struct eth_device *dev, int phy_id, int location)
{
if (phy_id == 1 && location < 32)
return INL(dev, BasicControl+(location<<2))&0xffff;
else
return 0xffff;
}
/* Function: natsemi_init
*
* Description: resets the ethernet controller chip and configures
* registers and data structures required for sending and receiving packets.
*
* Arguments: struct eth_device *dev: NIC data structure
*
* returns: int.
*/
static int
natsemi_init(struct eth_device *dev, bd_t * bis)
{
natsemi_reset(dev);
/* Disable PME:
* The PME bit is initialized from the EEPROM contents.
* PCI cards probably have PME disabled, but motherboard
* implementations may have PME set to enable WakeOnLan.
* With PME set the chip will scan incoming packets but
* nothing will be written to memory. */
OUTL(dev, SavedClkRun & ~0x100, ClkRun);
natsemi_init_rxfilter(dev);
natsemi_init_txd(dev);
natsemi_init_rxd(dev);
/* Configure the PCI bus bursts and FIFO thresholds. */
tx_config = TxAutoPad | TxCollRetry | TxMxdma_256 | (0x1002);
rx_config = RxMxdma_256 | 0x20;
#ifdef NATSEMI_DEBUG
printf("%s: Setting TxConfig Register %#08X\n", dev->name, tx_config);
printf("%s: Setting RxConfig Register %#08X\n", dev->name, rx_config);
#endif
OUTL(dev, tx_config, TxConfig);
OUTL(dev, rx_config, RxConfig);
natsemi_check_duplex(dev);
natsemi_set_rx_mode(dev);
OUTL(dev, (RxOn | TxOn), ChipCmd);
return 1;
}
/*
* Function: natsemi_reset
*
* Description: soft resets the controller chip
*
* Arguments: struct eth_device *dev: NIC data structure
*
* Returns: void.
*/
static void
natsemi_reset(struct eth_device *dev)
{
OUTL(dev, ChipReset, ChipCmd);
/* On page 78 of the spec, they recommend some settings for "optimum
performance" to be done in sequence. These settings optimize some
of the 100Mbit autodetection circuitry. Also, we only want to do
this for rev C of the chip. */
if (INL(dev, SiliconRev) == 0x302) {
OUTW(dev, 0x0001, PGSEL);
OUTW(dev, 0x189C, PMDCSR);
OUTW(dev, 0x0000, TSTDAT);
OUTW(dev, 0x5040, DSPCFG);
OUTW(dev, 0x008C, SDCFG);
}
/* Disable interrupts using the mask. */
OUTL(dev, 0, IntrMask);
OUTL(dev, 0, IntrEnable);
}
/* Function: natsemi_init_rxfilter
*
* Description: sets receive filter address to our MAC address
*
* Arguments: struct eth_device *dev: NIC data structure
*
* returns: void.
*/
static void
natsemi_init_rxfilter(struct eth_device *dev)
{
int i;
for (i = 0; i < ETH_ALEN; i += 2) {
OUTL(dev, i, RxFilterAddr);
OUTW(dev, dev->enetaddr[i] + (dev->enetaddr[i + 1] << 8),
RxFilterData);
}
}
/*
* Function: natsemi_init_txd
*
* Description: initializes the Tx descriptor
*
* Arguments: struct eth_device *dev: NIC data structure
*
* returns: void.
*/
static void
natsemi_init_txd(struct eth_device *dev)
{
txd.link = (u32) 0;
txd.cmdsts = (u32) 0;
txd.bufptr = (u32) & txb[0];
/* load Transmit Descriptor Register */
OUTL(dev, (u32) & txd, TxRingPtr);
#ifdef NATSEMI_DEBUG
printf("natsemi_init_txd: TX descriptor reg loaded with: %#08X\n",
INL(dev, TxRingPtr));
#endif
}
/* Function: natsemi_init_rxd
*
* Description: initializes the Rx descriptor ring
*
* Arguments: struct eth_device *dev: NIC data structure
*
* Returns: void.
*/
static void
natsemi_init_rxd(struct eth_device *dev)
{
int i;
cur_rx = 0;
/* init RX descriptor */
for (i = 0; i < NUM_RX_DESC; i++) {
rxd[i].link =
cpu_to_le32((i + 1 <
NUM_RX_DESC) ? (u32) & rxd[i +
1] : (u32) &
rxd[0]);
rxd[i].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE);
rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]);
#ifdef NATSEMI_DEBUG
printf
("natsemi_init_rxd: rxd[%d]=%p link=%X cmdsts=%lX bufptr=%X\n",
i, &rxd[i], le32_to_cpu(rxd[i].link),
rxd[i].cmdsts, rxd[i].bufptr);
#endif
}
/* load Receive Descriptor Register */
OUTL(dev, (u32) & rxd[0], RxRingPtr);
#ifdef NATSEMI_DEBUG
printf("natsemi_init_rxd: RX descriptor register loaded with: %X\n",
INL(dev, RxRingPtr));
#endif
}
/* Function: natsemi_set_rx_mode
*
* Description:
* sets the receive mode to accept all broadcast packets and packets
* with our MAC address, and reject all multicast packets.
*
* Arguments: struct eth_device *dev: NIC data structure
*
* Returns: void.
*/
static void
natsemi_set_rx_mode(struct eth_device *dev)
{
u32 rx_mode = AcceptBroadcast | AcceptMyPhys;
OUTL(dev, rx_mode, RxFilterAddr);
}
static void
natsemi_check_duplex(struct eth_device *dev)
{
int duplex = INL(dev, ChipConfig) & FullDuplex ? 1 : 0;
#ifdef NATSEMI_DEBUG
printf("%s: Setting %s-duplex based on negotiated link"
" capability.\n", dev->name, duplex ? "full" : "half");
#endif
if (duplex) {
rx_config |= RxAcceptTx;
tx_config |= (TxCarrierIgn | TxHeartIgn);
} else {
rx_config &= ~RxAcceptTx;
tx_config &= ~(TxCarrierIgn | TxHeartIgn);
}
OUTL(dev, tx_config, TxConfig);
OUTL(dev, rx_config, RxConfig);
}
/* Function: natsemi_send
*
* Description: transmits a packet and waits for completion or timeout.
*
* Returns: void. */
static int
natsemi_send(struct eth_device *dev, volatile void *packet, int length)
{
u32 i, status = 0;
u32 tx_status = 0;
/* Stop the transmitter */
OUTL(dev, TxOff, ChipCmd);
#ifdef NATSEMI_DEBUG
if (natsemi_debug)
printf("natsemi_send: sending %d bytes\n", (int) length);
#endif
/* set the transmit buffer descriptor and enable Transmit State Machine */
txd.link = cpu_to_le32(0);
txd.bufptr = cpu_to_le32(phys_to_bus((u32) packet));
txd.cmdsts = cpu_to_le32(DescOwn | length);
/* load Transmit Descriptor Register */
OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr);
#ifdef NATSEMI_DEBUG
if (natsemi_debug)
printf("natsemi_send: TX descriptor register loaded with: %#08X\n",
INL(dev, TxRingPtr));
#endif
/* restart the transmitter */
OUTL(dev, TxOn, ChipCmd);
for (i = 0;
((vu_long)tx_status = le32_to_cpu(txd.cmdsts)) & DescOwn;
i++) {
if (i >= TOUT_LOOP) {
printf
("%s: tx error buffer not ready: txd.cmdsts == %#X\n",
dev->name, tx_status);
goto Done;
}
}
if (!(tx_status & DescPktOK)) {
printf("natsemi_send: Transmit error, Tx status %X.\n",
tx_status);
goto Done;
}
status = 1;
Done:
return status;
}
/* Function: natsemi_poll
*
* Description: checks for a received packet and returns it if found.
*
* Arguments: struct eth_device *dev: NIC data structure
*
* Returns: 1 if packet was received.
* 0 if no packet was received.
*
* Side effects:
* Returns (copies) the packet to the array dev->packet.
* Returns the length of the packet.
*/
static int
natsemi_poll(struct eth_device *dev)
{
int retstat = 0;
int length = 0;
u32 rx_status = le32_to_cpu(rxd[cur_rx].cmdsts);
if (!(rx_status & (u32) DescOwn))
return retstat;
#ifdef NATSEMI_DEBUG
if (natsemi_debug)
printf("natsemi_poll: got a packet: cur_rx:%d, status:%X\n",
cur_rx, rx_status);
#endif
length = (rx_status & DSIZE) - CRC_SIZE;
if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) {
printf
("natsemi_poll: Corrupted packet received, buffer status = %X\n",
rx_status);
retstat = 0;
} else { /* give packet to higher level routine */
NetReceive((rxb + cur_rx * RX_BUF_SIZE), length);
retstat = 1;
}
/* return the descriptor and buffer to receive ring */
rxd[cur_rx].cmdsts = cpu_to_le32(RX_BUF_SIZE);
rxd[cur_rx].bufptr = cpu_to_le32((u32) & rxb[cur_rx * RX_BUF_SIZE]);
if (++cur_rx == NUM_RX_DESC)
cur_rx = 0;
/* re-enable the potentially idle receive state machine */
OUTL(dev, RxOn, ChipCmd);
return retstat;
}
/* Function: natsemi_disable
*
* Description: Turns off interrupts and stops Tx and Rx engines
*
* Arguments: struct eth_device *dev: NIC data structure
*
* Returns: void.
*/
static void
natsemi_disable(struct eth_device *dev)
{
/* Disable interrupts using the mask. */
OUTL(dev, 0, IntrMask);
OUTL(dev, 0, IntrEnable);
/* Stop the chip's Tx and Rx processes. */
OUTL(dev, RxOff | TxOff, ChipCmd);
/* Restore PME enable bit */
OUTL(dev, SavedClkRun, ClkRun);
}
#endif

110
drivers/nicext.h Normal file
View File

@ -0,0 +1,110 @@
/****************************************************************************
* Copyright(c) 2000-2001 Broadcom Corporation. All rights reserved.
*
* 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.
*
* Name: nicext.h
*
* Description: Broadcom Network Interface Card Extension (NICE) is an
* extension to Linux NET device kernel mode drivers.
* NICE is designed to provide additional functionalities,
* such as receive packet intercept. To support Broadcom NICE,
* the network device driver can be modified by adding an
* device ioctl handler and by indicating receiving packets
* to the NICE receive handler. Broadcom NICE will only be
* enabled by a NICE-aware intermediate driver, such as
* Broadcom Advanced Server Program Driver (BASP). When NICE
* is not enabled, the modified network device drivers
* functions exactly as other non-NICE aware drivers.
*
* Author: Frankie Fan
*
* Created: September 17, 2000
*
****************************************************************************/
#ifndef _nicext_h_
#define _nicext_h_
/*
* ioctl for NICE
*/
#define SIOCNICE SIOCDEVPRIVATE+7
/*
* SIOCNICE:
*
* The following structure needs to be less than IFNAMSIZ (16 bytes) because
* we're overloading ifreq.ifr_ifru.
*
* If 16 bytes is not enough, we should consider relaxing this because
* this is no field after ifr_ifru in the ifreq structure. But we may
* run into future compatiability problem in case of changing struct ifreq.
*/
struct nice_req
{
__u32 cmd;
union
{
#ifdef __KERNEL__
/* cmd = NICE_CMD_SET_RX or NICE_CMD_GET_RX */
struct
{
void (*nrqus1_rx)( struct sk_buff*, void* );
void* nrqus1_ctx;
} nrqu_nrqus1;
/* cmd = NICE_CMD_QUERY_SUPPORT */
struct
{
__u32 nrqus2_magic;
__u32 nrqus2_support_rx:1;
__u32 nrqus2_support_vlan:1;
__u32 nrqus2_support_get_speed:1;
} nrqu_nrqus2;
#endif
/* cmd = NICE_CMD_GET_SPEED */
struct
{
unsigned int nrqus3_speed; /* 0 if link is down, */
/* otherwise speed in Mbps */
} nrqu_nrqus3;
/* cmd = NICE_CMD_BLINK_LED */
struct
{
unsigned int nrqus4_blink_time; /* blink duration in seconds */
} nrqu_nrqus4;
} nrq_nrqu;
};
#define nrq_rx nrq_nrqu.nrqu_nrqus1.nrqus1_rx
#define nrq_ctx nrq_nrqu.nrqu_nrqus1.nrqus1_ctx
#define nrq_support_rx nrq_nrqu.nrqu_nrqus2.nrqus2_support_rx
#define nrq_magic nrq_nrqu.nrqu_nrqus2.nrqus2_magic
#define nrq_support_vlan nrq_nrqu.nrqu_nrqus2.nrqus2_support_vlan
#define nrq_support_get_speed nrq_nrqu.nrqu_nrqus2.nrqus2_support_get_speed
#define nrq_speed nrq_nrqu.nrqu_nrqus3.nrqus3_speed
#define nrq_blink_time nrq_nrqu.nrqu_nrqus4.nrqus4_blink_time
/*
* magic constants
*/
#define NICE_REQUESTOR_MAGIC 0x4543494E /* NICE in ascii */
#define NICE_DEVICE_MAGIC 0x4E494345 /* ECIN in ascii */
/*
* command field
*/
#define NICE_CMD_QUERY_SUPPORT 0x00000001
#define NICE_CMD_SET_RX 0x00000002
#define NICE_CMD_GET_RX 0x00000003
#define NICE_CMD_GET_SPEED 0x00000004
#define NICE_CMD_BLINK_LED 0x00000005
#endif /* _nicext_h_ */

863
drivers/ns8382x.c Normal file
View File

@ -0,0 +1,863 @@
/*
ns8382x.c: A U-Boot driver for the NatSemi DP8382[01].
ported by: Mark A. Rakes (mark_rakes@vivato.net)
Adapted from:
1. an Etherboot driver for DP8381[56] written by:
Copyright (C) 2001 Entity Cyber, Inc.
This development of this Etherboot driver was funded by
Sicom Systems: http://www.sicompos.com/
Author: Marty Connor (mdc@thinguin.org)
Adapted from a Linux driver which was written by Donald Becker
This software may be used and distributed according to the terms
of the GNU Public License (GPL), incorporated herein by reference.
2. A Linux driver by Donald Becker, ns820.c:
Written/copyright 1999-2002 by Donald Becker.
This software may be used and distributed according to the terms of
the GNU General Public License (GPL), incorporated herein by reference.
Drivers based on or derived from this code fall under the GPL and must
retain the authorship, copyright and license notice. This file is not
a complete program and may only be used when the entire operating
system is licensed under the GPL. License for under other terms may be
available. Contact the original author for details.
The original author may be reached as becker@scyld.com, or at
Scyld Computing Corporation
410 Severn Ave., Suite 210
Annapolis MD 21403
Support information and updates available at
http://www.scyld.com/network/netsemi.html
Datasheets available from:
http://www.national.com/pf/DP/DP83820.html
http://www.national.com/pf/DP/DP83821.html
*/
/* Revision History
* October 2002 mar 1.0
* Initial U-Boot Release.
* Tested with Netgear GA622T (83820)
* and SMC9452TX (83821)
* NOTE: custom boards with these chips may (likely) require
* a programmed EEPROM device (if present) in order to work
* correctly.
*/
/* Includes */
#include <common.h>
#include <malloc.h>
#include <net.h>
#include <asm/io.h>
#include <pci.h>
#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
defined(CONFIG_NS8382X)
/* defines */
#define DSIZE 0x00000FFF
#define ETH_ALEN 6
#define CRC_SIZE 4
#define TOUT_LOOP 500000
#define TX_BUF_SIZE 1536
#define RX_BUF_SIZE 1536
#define NUM_RX_DESC 4 /* Number of Rx descriptor registers. */
enum register_offsets {
ChipCmd = 0x00,
ChipConfig = 0x04,
EECtrl = 0x08,
IntrMask = 0x14,
IntrEnable = 0x18,
TxRingPtr = 0x20,
TxRingPtrHi = 0x24,
TxConfig = 0x28,
RxRingPtr = 0x30,
RxRingPtrHi = 0x34,
RxConfig = 0x38,
PriQueue = 0x3C,
RxFilterAddr = 0x48,
RxFilterData = 0x4C,
ClkRun = 0xCC,
PCIPM = 0x44,
};
enum ChipCmdBits {
ChipReset = 0x100,
RxReset = 0x20,
TxReset = 0x10,
RxOff = 0x08,
RxOn = 0x04,
TxOff = 0x02,
TxOn = 0x01
};
enum ChipConfigBits {
LinkSts = 0x80000000,
GigSpeed = 0x40000000,
HundSpeed = 0x20000000,
FullDuplex = 0x10000000,
TBIEn = 0x01000000,
Mode1000 = 0x00400000,
T64En = 0x00004000,
D64En = 0x00001000,
M64En = 0x00000800,
PhyRst = 0x00000400,
PhyDis = 0x00000200,
ExtStEn = 0x00000100,
BEMode = 0x00000001,
};
#define SpeedStatus_Polarity ( GigSpeed | HundSpeed | FullDuplex)
enum TxConfig_bits {
TxDrthMask = 0x000000ff,
TxFlthMask = 0x0000ff00,
TxMxdmaMask = 0x00700000,
TxMxdma_8 = 0x00100000,
TxMxdma_16 = 0x00200000,
TxMxdma_32 = 0x00300000,
TxMxdma_64 = 0x00400000,
TxMxdma_128 = 0x00500000,
TxMxdma_256 = 0x00600000,
TxMxdma_512 = 0x00700000,
TxMxdma_1024 = 0x00000000,
TxCollRetry = 0x00800000,
TxAutoPad = 0x10000000,
TxMacLoop = 0x20000000,
TxHeartIgn = 0x40000000,
TxCarrierIgn = 0x80000000
};
enum RxConfig_bits {
RxDrthMask = 0x0000003e,
RxMxdmaMask = 0x00700000,
RxMxdma_8 = 0x00100000,
RxMxdma_16 = 0x00200000,
RxMxdma_32 = 0x00300000,
RxMxdma_64 = 0x00400000,
RxMxdma_128 = 0x00500000,
RxMxdma_256 = 0x00600000,
RxMxdma_512 = 0x00700000,
RxMxdma_1024 = 0x00000000,
RxAcceptLenErr = 0x04000000,
RxAcceptLong = 0x08000000,
RxAcceptTx = 0x10000000,
RxStripCRC = 0x20000000,
RxAcceptRunt = 0x40000000,
RxAcceptErr = 0x80000000,
};
/* Bits in the RxMode register. */
enum rx_mode_bits {
RxFilterEnable = 0x80000000,
AcceptAllBroadcast = 0x40000000,
AcceptAllMulticast = 0x20000000,
AcceptAllUnicast = 0x10000000,
AcceptPerfectMatch = 0x08000000,
};
typedef struct _BufferDesc {
u32 link;
u32 bufptr;
vu_long cmdsts;
u32 extsts; /*not used here */
} BufferDesc;
/* Bits in network_desc.status */
enum desc_status_bits {
DescOwn = 0x80000000, DescMore = 0x40000000, DescIntr = 0x20000000,
DescNoCRC = 0x10000000, DescPktOK = 0x08000000,
DescSizeMask = 0xfff,
DescTxAbort = 0x04000000, DescTxFIFO = 0x02000000,
DescTxCarrier = 0x01000000, DescTxDefer = 0x00800000,
DescTxExcDefer = 0x00400000, DescTxOOWCol = 0x00200000,
DescTxExcColl = 0x00100000, DescTxCollCount = 0x000f0000,
DescRxAbort = 0x04000000, DescRxOver = 0x02000000,
DescRxDest = 0x01800000, DescRxLong = 0x00400000,
DescRxRunt = 0x00200000, DescRxInvalid = 0x00100000,
DescRxCRC = 0x00080000, DescRxAlign = 0x00040000,
DescRxLoop = 0x00020000, DesRxColl = 0x00010000,
};
/* Bits in MEAR */
enum mii_reg_bits {
MDIO_ShiftClk = 0x0040,
MDIO_EnbOutput = 0x0020,
MDIO_Data = 0x0010,
};
/* PHY Register offsets. */
enum phy_reg_offsets {
BMCR = 0x00,
BMSR = 0x01,
PHYIDR1 = 0x02,
PHYIDR2 = 0x03,
ANAR = 0x04,
KTCR = 0x09,
};
/* basic mode control register bits */
enum bmcr_bits {
Bmcr_Reset = 0x8000,
Bmcr_Loop = 0x4000,
Bmcr_Speed0 = 0x2000,
Bmcr_AutoNegEn = 0x1000, /*if set ignores Duplex, Speed[01] */
Bmcr_RstAutoNeg = 0x0200,
Bmcr_Duplex = 0x0100,
Bmcr_Speed1 = 0x0040,
Bmcr_Force10H = 0x0000,
Bmcr_Force10F = 0x0100,
Bmcr_Force100H = 0x2000,
Bmcr_Force100F = 0x2100,
Bmcr_Force1000H = 0x0040,
Bmcr_Force1000F = 0x0140,
};
/* auto negotiation advertisement register */
enum anar_bits {
anar_adv_100F = 0x0100,
anar_adv_100H = 0x0080,
anar_adv_10F = 0x0040,
anar_adv_10H = 0x0020,
anar_ieee_8023 = 0x0001,
};
/* 1K-base T control register */
enum ktcr_bits {
ktcr_adv_1000H = 0x0100,
ktcr_adv_1000F = 0x0200,
};
/* Globals */
static u32 SavedClkRun;
static unsigned int cur_rx;
static unsigned int rx_config;
static unsigned int tx_config;
/* Note: transmit and receive buffers and descriptors must be
long long word aligned */
static BufferDesc txd __attribute__ ((aligned(8)));
static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(8)));
static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(8)));
static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE]
__attribute__ ((aligned(8)));
/* Function Prototypes */
static int mdio_read(struct eth_device *dev, int phy_id, int addr);
static void mdio_write(struct eth_device *dev, int phy_id, int addr, int value);
static void mdio_sync(struct eth_device *dev, u32 offset);
static int ns8382x_init(struct eth_device *dev, bd_t * bis);
static void ns8382x_reset(struct eth_device *dev);
static void ns8382x_init_rxfilter(struct eth_device *dev);
static void ns8382x_init_txd(struct eth_device *dev);
static void ns8382x_init_rxd(struct eth_device *dev);
static void ns8382x_set_rx_mode(struct eth_device *dev);
static void ns8382x_check_duplex(struct eth_device *dev);
static int ns8382x_send(struct eth_device *dev, volatile void *packet,
int length);
static int ns8382x_poll(struct eth_device *dev);
static void ns8382x_disable(struct eth_device *dev);
static struct pci_device_id supported[] = {
{PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_8382x},
{}
};
#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a)
#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
static inline int
INW(struct eth_device *dev, u_long addr)
{
return le16_to_cpu(*(vu_short *) (addr + dev->iobase));
}
static int
INL(struct eth_device *dev, u_long addr)
{
return le32_to_cpu(*(vu_long *) (addr + dev->iobase));
}
static inline void
OUTW(struct eth_device *dev, int command, u_long addr)
{
*(vu_short *) ((addr + dev->iobase)) = cpu_to_le16(command);
}
static inline void
OUTL(struct eth_device *dev, int command, u_long addr)
{
*(vu_long *) ((addr + dev->iobase)) = cpu_to_le32(command);
}
/* Function: ns8382x_initialize
* Description: Retrieves the MAC address of the card, and sets up some
* globals required by other routines, and initializes the NIC, making it
* ready to send and receive packets.
* Side effects: initializes ns8382xs, ready to recieve packets.
* Returns: int: number of cards found
*/
int
ns8382x_initialize(bd_t * bis)
{
pci_dev_t devno;
int card_number = 0;
struct eth_device *dev;
u32 iobase, status;
int i, idx = 0;
u32 phyAddress;
u32 tmp;
u32 chip_config;
while (1) { /* Find PCI device(s) */
if ((devno = pci_find_devices(supported, idx++)) < 0)
break;
pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase);
iobase &= ~0x3; /* 1: unused and 0:I/O Space Indicator */
#ifdef NS8382X_DEBUG
printf("ns8382x: NatSemi dp8382x @ 0x%x\n", iobase);
#endif
pci_write_config_dword(devno, PCI_COMMAND,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
/* Check if I/O accesses and Bus Mastering are enabled. */
pci_read_config_dword(devno, PCI_COMMAND, &status);
if (!(status & PCI_COMMAND_MEMORY)) {
printf("Error: Can not enable MEM access.\n");
continue;
} else if (!(status & PCI_COMMAND_MASTER)) {
printf("Error: Can not enable Bus Mastering.\n");
continue;
}
dev = (struct eth_device *) malloc(sizeof *dev);
sprintf(dev->name, "dp8382x#%d", card_number);
dev->iobase = bus_to_phys(iobase);
dev->priv = (void *) devno;
dev->init = ns8382x_init;
dev->halt = ns8382x_disable;
dev->send = ns8382x_send;
dev->recv = ns8382x_poll;
/* ns8382x has a non-standard PM control register
* in PCI config space. Some boards apparently need
* to be brought to D0 in this manner. */
pci_read_config_dword(devno, PCIPM, &tmp);
if (tmp & (0x03 | 0x100)) { /* D0 state, disable PME assertion */
u32 newtmp = tmp & ~(0x03 | 0x100);
pci_write_config_dword(devno, PCIPM, newtmp);
}
/* get MAC address */
for (i = 0; i < 3; i++) {
u32 data;
char *mac = &dev->enetaddr[i * 2];
OUTL(dev, i * 2, RxFilterAddr);
data = INL(dev, RxFilterData);
*mac++ = data;
*mac++ = data >> 8;
}
/* get PHY address, can't be zero */
for (phyAddress = 1; phyAddress < 32; phyAddress++) {
u32 rev, phy1;
phy1 = mdio_read(dev, phyAddress, PHYIDR1);
if (phy1 == 0x2000) { /*check for 83861/91 */
rev = mdio_read(dev, phyAddress, PHYIDR2);
if ((rev & ~(0x000f)) == 0x00005c50 ||
(rev & ~(0x000f)) == 0x00005c60) {
#ifdef NS8382X_DEBUG
printf("phy rev is %x\n", rev);
printf("phy address is %x\n",
phyAddress);
#endif
break;
}
}
}
/* set phy to autonegotiate && advertise everything */
mdio_write(dev, phyAddress, KTCR,
(ktcr_adv_1000H | ktcr_adv_1000F));
mdio_write(dev, phyAddress, ANAR,
(anar_adv_100F | anar_adv_100H | anar_adv_10H |
anar_adv_10F | anar_ieee_8023));
mdio_write(dev, phyAddress, BMCR, 0x0); /*restore */
mdio_write(dev, phyAddress, BMCR,
(Bmcr_AutoNegEn | Bmcr_RstAutoNeg));
/* Reset the chip to erase any previous misconfiguration. */
OUTL(dev, (ChipReset), ChipCmd);
chip_config = INL(dev, ChipConfig);
/* reset the phy */
OUTL(dev, (chip_config | PhyRst), ChipConfig);
/* power up and initialize transceiver */
OUTL(dev, (chip_config & ~(PhyDis)), ChipConfig);
mdio_sync(dev, EECtrl);
#ifdef NS8382X_DEBUG
{
u32 chpcfg =
INL(dev, ChipConfig) ^ SpeedStatus_Polarity;
printf("%s: Transceiver 10%s %s duplex.\n", dev->name,
(chpcfg & GigSpeed) ? "00" : (chpcfg & HundSpeed)
? "0" : "",
chpcfg & FullDuplex ? "full" : "half");
printf("%s: %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
dev->enetaddr[0], dev->enetaddr[1],
dev->enetaddr[2], dev->enetaddr[3],
dev->enetaddr[4], dev->enetaddr[5]);
}
#endif
/* Disable PME:
* The PME bit is initialized from the EEPROM contents.
* PCI cards probably have PME disabled, but motherboard
* implementations may have PME set to enable WakeOnLan.
* With PME set the chip will scan incoming packets but
* nothing will be written to memory. */
SavedClkRun = INL(dev, ClkRun);
OUTL(dev, SavedClkRun & ~0x100, ClkRun);
eth_register(dev);
card_number++;
pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x60);
udelay(10 * 1000);
}
return card_number;
}
/* MII transceiver control section.
Read and write MII registers using software-generated serial MDIO
protocol. See the MII specifications or DP83840A data sheet for details.
The maximum data clock rate is 2.5 Mhz. To meet minimum timing we
must flush writes to the PCI bus with a PCI read. */
#define mdio_delay(mdio_addr) INL(dev, mdio_addr)
#define MDIO_EnbIn (0)
#define MDIO_WRITE0 (MDIO_EnbOutput)
#define MDIO_WRITE1 (MDIO_Data | MDIO_EnbOutput)
/* Generate the preamble required for initial synchronization and
a few older transceivers. */
static void
mdio_sync(struct eth_device *dev, u32 offset)
{
int bits = 32;
/* Establish sync by sending at least 32 logic ones. */
while (--bits >= 0) {
OUTL(dev, MDIO_WRITE1, offset);
mdio_delay(offset);
OUTL(dev, MDIO_WRITE1 | MDIO_ShiftClk, offset);
mdio_delay(offset);
}
}
static int
mdio_read(struct eth_device *dev, int phy_id, int addr)
{
int mii_cmd = (0xf6 << 10) | (phy_id << 5) | addr;
int i, retval = 0;
/* Shift the read command bits out. */
for (i = 15; i >= 0; i--) {
int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
OUTL(dev, dataval, EECtrl);
mdio_delay(EECtrl);
OUTL(dev, dataval | MDIO_ShiftClk, EECtrl);
mdio_delay(EECtrl);
}
/* Read the two transition, 16 data, and wire-idle bits. */
for (i = 19; i > 0; i--) {
OUTL(dev, MDIO_EnbIn, EECtrl);
mdio_delay(EECtrl);
retval =
(retval << 1) | ((INL(dev, EECtrl) & MDIO_Data) ? 1 : 0);
OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl);
mdio_delay(EECtrl);
}
return (retval >> 1) & 0xffff;
}
static void
mdio_write(struct eth_device *dev, int phy_id, int addr, int value)
{
int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (addr << 18) | value;
int i;
/* Shift the command bits out. */
for (i = 31; i >= 0; i--) {
int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
OUTL(dev, dataval, EECtrl);
mdio_delay(EECtrl);
OUTL(dev, dataval | MDIO_ShiftClk, EECtrl);
mdio_delay(EECtrl);
}
/* Clear out extra bits. */
for (i = 2; i > 0; i--) {
OUTL(dev, MDIO_EnbIn, EECtrl);
mdio_delay(EECtrl);
OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl);
mdio_delay(EECtrl);
}
return;
}
/* Function: ns8382x_init
* Description: resets the ethernet controller chip and configures
* registers and data structures required for sending and receiving packets.
* Arguments: struct eth_device *dev: NIC data structure
* returns: int.
*/
static int
ns8382x_init(struct eth_device *dev, bd_t * bis)
{
u32 config;
ns8382x_reset(dev);
/* Disable PME:
* The PME bit is initialized from the EEPROM contents.
* PCI cards probably have PME disabled, but motherboard
* implementations may have PME set to enable WakeOnLan.
* With PME set the chip will scan incoming packets but
* nothing will be written to memory. */
OUTL(dev, SavedClkRun & ~0x100, ClkRun);
ns8382x_init_rxfilter(dev);
ns8382x_init_txd(dev);
ns8382x_init_rxd(dev);
/*set up ChipConfig */
config = INL(dev, ChipConfig);
/*turn off 64 bit ops && Ten-bit interface
* && big-endian mode && extended status */
config &= ~(TBIEn | Mode1000 | T64En | D64En | M64En | BEMode | PhyDis | ExtStEn);
OUTL(dev, config, ChipConfig);
/* Configure the PCI bus bursts and FIFO thresholds. */
tx_config = TxCarrierIgn | TxHeartIgn | TxAutoPad
| TxCollRetry | TxMxdma_1024 | (0x1002);
rx_config = RxMxdma_1024 | 0x20;
#ifdef NS8382X_DEBUG
printf("%s: Setting TxConfig Register %#08X\n", dev->name, tx_config);
printf("%s: Setting RxConfig Register %#08X\n", dev->name, rx_config);
#endif
OUTL(dev, tx_config, TxConfig);
OUTL(dev, rx_config, RxConfig);
/*turn off priority queueing */
OUTL(dev, 0x0, PriQueue);
ns8382x_check_duplex(dev);
ns8382x_set_rx_mode(dev);
OUTL(dev, (RxOn | TxOn), ChipCmd);
return 1;
}
/* Function: ns8382x_reset
* Description: soft resets the controller chip
* Arguments: struct eth_device *dev: NIC data structure
* Returns: void.
*/
static void
ns8382x_reset(struct eth_device *dev)
{
OUTL(dev, ChipReset, ChipCmd);
while (INL(dev, ChipCmd))
/*wait until done */ ;
OUTL(dev, 0, IntrMask);
OUTL(dev, 0, IntrEnable);
}
/* Function: ns8382x_init_rxfilter
* Description: sets receive filter address to our MAC address
* Arguments: struct eth_device *dev: NIC data structure
* returns: void.
*/
static void
ns8382x_init_rxfilter(struct eth_device *dev)
{
int i;
for (i = 0; i < ETH_ALEN; i += 2) {
OUTL(dev, i, RxFilterAddr);
OUTW(dev, dev->enetaddr[i] + (dev->enetaddr[i + 1] << 8),
RxFilterData);
}
}
/* Function: ns8382x_init_txd
* Description: initializes the Tx descriptor
* Arguments: struct eth_device *dev: NIC data structure
* returns: void.
*/
static void
ns8382x_init_txd(struct eth_device *dev)
{
txd.link = (u32) 0;
txd.bufptr = cpu_to_le32((u32) & txb[0]);
txd.cmdsts = (u32) 0;
txd.extsts = (u32) 0;
OUTL(dev, 0x0, TxRingPtrHi);
OUTL(dev, phys_to_bus((u32)&txd), TxRingPtr);
#ifdef NS8382X_DEBUG
printf("ns8382x_init_txd: TX descriptor register loaded with: %#08X (&txd: %p)\n",
INL(dev, TxRingPtr), &txd);
#endif
}
/* Function: ns8382x_init_rxd
* Description: initializes the Rx descriptor ring
* Arguments: struct eth_device *dev: NIC data structure
* Returns: void.
*/
static void
ns8382x_init_rxd(struct eth_device *dev)
{
int i;
OUTL(dev, 0x0, RxRingPtrHi);
cur_rx = 0;
for (i = 0; i < NUM_RX_DESC; i++) {
rxd[i].link =
cpu_to_le32((i + 1 <
NUM_RX_DESC) ? (u32) & rxd[i +
1] : (u32) &
rxd[0]);
rxd[i].extsts = cpu_to_le32((u32) 0x0);
rxd[i].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE);
rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]);
#ifdef NS8382X_DEBUG
printf
("ns8382x_init_rxd: rxd[%d]=%p link=%X cmdsts=%X bufptr=%X\n",
i, &rxd[i], le32_to_cpu(rxd[i].link),
le32_to_cpu(rxd[i].cmdsts), le32_to_cpu(rxd[i].bufptr));
#endif
}
OUTL(dev, phys_to_bus((u32) & rxd), RxRingPtr);
#ifdef NS8382X_DEBUG
printf("ns8382x_init_rxd: RX descriptor register loaded with: %X\n",
INL(dev, RxRingPtr));
#endif
}
/* Function: ns8382x_set_rx_mode
* Description:
* sets the receive mode to accept all broadcast packets and packets
* with our MAC address, and reject all multicast packets.
* Arguments: struct eth_device *dev: NIC data structure
* Returns: void.
*/
static void
ns8382x_set_rx_mode(struct eth_device *dev)
{
u32 rx_mode = 0x0;
/*spec says RxFilterEnable has to be 0 for rest of
* this stuff to be properly configured. Linux driver
* seems to support this*/
/* OUTL(dev, rx_mode, RxFilterAddr);*/
rx_mode = (RxFilterEnable | AcceptAllBroadcast | AcceptPerfectMatch);
OUTL(dev, rx_mode, RxFilterAddr);
printf("ns8382x_set_rx_mode: set to %X\n", rx_mode);
/*now we turn RxFilterEnable back on */
/*rx_mode |= RxFilterEnable;
OUTL(dev, rx_mode, RxFilterAddr);*/
}
static void
ns8382x_check_duplex(struct eth_device *dev)
{
int gig = 0;
int hun = 0;
int duplex = 0;
int config = (INL(dev, ChipConfig) ^ SpeedStatus_Polarity);
duplex = (config & FullDuplex) ? 1 : 0;
gig = (config & GigSpeed) ? 1 : 0;
hun = (config & HundSpeed) ? 1 : 0;
#ifdef NS8382X_DEBUG
printf("%s: Setting 10%s %s-duplex based on negotiated link"
" capability.\n", dev->name, (gig) ? "00" : (hun) ? "0" : "",
duplex ? "full" : "half");
#endif
if (duplex) {
rx_config |= RxAcceptTx;
tx_config |= (TxCarrierIgn | TxHeartIgn);
} else {
rx_config &= ~RxAcceptTx;
tx_config &= ~(TxCarrierIgn | TxHeartIgn);
}
#ifdef NS8382X_DEBUG
printf("%s: Resetting TxConfig Register %#08X\n", dev->name, tx_config);
printf("%s: Resetting RxConfig Register %#08X\n", dev->name, rx_config);
#endif
OUTL(dev, tx_config, TxConfig);
OUTL(dev, rx_config, RxConfig);
/*if speed is 10 or 100, remove MODE1000,
* if it's 1000, then set it */
config = INL(dev, ChipConfig);
if (gig)
config |= Mode1000;
else
config &= ~Mode1000;
#ifdef NS8382X_DEBUG
printf("%s: %setting Mode1000\n", dev->name, (gig) ? "S" : "Uns");
#endif
OUTL(dev, config, ChipConfig);
}
/* Function: ns8382x_send
* Description: transmits a packet and waits for completion or timeout.
* Returns: void. */
static int
ns8382x_send(struct eth_device *dev, volatile void *packet, int length)
{
u32 i, status = 0;
u32 tx_stat = 0;
/* Stop the transmitter */
OUTL(dev, TxOff, ChipCmd);
#ifdef NS8382X_DEBUG
printf("ns8382x_send: sending %d bytes\n", (int)length);
#endif
/* set the transmit buffer descriptor and enable Transmit State Machine */
txd.link = cpu_to_le32(0x0);
txd.bufptr = cpu_to_le32(phys_to_bus((u32)packet));
txd.extsts = cpu_to_le32(0x0);
txd.cmdsts = cpu_to_le32(DescOwn | length);
/* load Transmit Descriptor Register */
OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr);
#ifdef NS8382X_DEBUG
printf("ns8382x_send: TX descriptor register loaded with: %#08X\n",
INL(dev, TxRingPtr));
printf("\ttxd.link:%X\tbufp:%X\texsts:%X\tcmdsts:%X\n",
le32_to_cpu(txd.link), le32_to_cpu(txd.bufptr),
le32_to_cpu(txd.extsts), le32_to_cpu(txd.cmdsts));
#endif
/* restart the transmitter */
OUTL(dev, TxOn, ChipCmd);
for (i = 0; ((vu_long)tx_stat = le32_to_cpu(txd.cmdsts)) & DescOwn; i++) {
if (i >= TOUT_LOOP) {
printf ("%s: tx error buffer not ready: txd.cmdsts %#X\n",
dev->name, tx_stat);
goto Done;
}
}
if (!(tx_stat & DescPktOK)) {
printf("ns8382x_send: Transmit error, Tx status %X.\n", tx_stat);
goto Done;
}
#ifdef NS8382X_DEBUG
printf("ns8382x_send: tx_stat: %#08X\n", tx_stat);
#endif
status = 1;
Done:
return status;
}
/* Function: ns8382x_poll
* Description: checks for a received packet and returns it if found.
* Arguments: struct eth_device *dev: NIC data structure
* Returns: 1 if packet was received.
* 0 if no packet was received.
* Side effects:
* Returns (copies) the packet to the array dev->packet.
* Returns the length of the packet.
*/
static int
ns8382x_poll(struct eth_device *dev)
{
int retstat = 0;
int length = 0;
vu_long rx_status = le32_to_cpu(rxd[cur_rx].cmdsts);
if (!(rx_status & (u32) DescOwn))
return retstat;
#ifdef NS8382X_DEBUG
printf("ns8382x_poll: got a packet: cur_rx:%u, status:%lx\n",
cur_rx, rx_status);
#endif
length = (rx_status & DSIZE) - CRC_SIZE;
if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) {
/* corrupted packet received */
printf("ns8382x_poll: Corrupted packet, status:%lx\n", rx_status);
retstat = 0;
} else {
/* give packet to higher level routine */
NetReceive((rxb + cur_rx * RX_BUF_SIZE), length);
retstat = 1;
}
/* return the descriptor and buffer to receive ring */
rxd[cur_rx].cmdsts = cpu_to_le32(RX_BUF_SIZE);
rxd[cur_rx].bufptr = cpu_to_le32((u32) & rxb[cur_rx * RX_BUF_SIZE]);
if (++cur_rx == NUM_RX_DESC)
cur_rx = 0;
/* re-enable the potentially idle receive state machine */
OUTL(dev, RxOn, ChipCmd);
return retstat;
}
/* Function: ns8382x_disable
* Description: Turns off interrupts and stops Tx and Rx engines
* Arguments: struct eth_device *dev: NIC data structure
* Returns: void.
*/
static void
ns8382x_disable(struct eth_device *dev)
{
/* Disable interrupts using the mask. */
OUTL(dev, 0, IntrMask);
OUTL(dev, 0, IntrEnable);
/* Stop the chip's Tx and Rx processes. */
OUTL(dev, (RxOff | TxOff), ChipCmd);
/* Restore PME enable bit */
OUTL(dev, SavedClkRun, ClkRun);
}
#endif

1383
drivers/smc91111.c Normal file

File diff suppressed because it is too large Load Diff

619
drivers/smc91111.h Normal file
View File

@ -0,0 +1,619 @@
/*------------------------------------------------------------------------
. smc91111.h - macros for the LAN91C111 Ethernet Driver
.
. (C) Copyright 2002
. Sysgo Real-Time Solutions, GmbH <www.elinos.com>
. Rolf Offermanns <rof@sysgo.de>
. Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
. Developed by Simple Network Magic Corporation (SNMC)
. Copyright (C) 1996 by Erik Stahlman (ES)
.
. 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
.
. This file contains register information and access macros for
. the LAN91C111 single chip ethernet controller. It is a modified
. version of the smc9194.h file.
.
. Information contained in this file was obtained from the LAN91C111
. manual from SMC. To get a copy, if you really want one, you can find
. information under www.smsc.com.
.
. Authors
. Erik Stahlman ( erik@vt.edu )
. Daris A Nevil ( dnevil@snmc.com )
.
. History
. 03/16/01 Daris A Nevil Modified for use with LAN91C111 device
.
---------------------------------------------------------------------------*/
#ifndef _SMC91111_H_
#define _SMC91111_H_
#include <asm/types.h>
#include <config.h>
/*
* This function may be called by the board specific initialisation code
* in order to override the default mac address.
*/
void smc_set_mac_addr(const char *addr);
/* I want some simple types */
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned long int dword;
/*
. DEBUGGING LEVELS
.
. 0 for normal operation
. 1 for slightly more details
. >2 for various levels of increasingly useless information
. 2 for interrupt tracking, status flags
. 3 for packet info
. 4 for complete packet dumps
*/
/*#define SMC_DEBUG 0 */
/* Because of bank switching, the LAN91xxx uses only 16 I/O ports */
#define SMC_IO_EXTENT 16
#ifdef CONFIG_PXA250
#define SMC_inl(r) (*((volatile dword *)(SMC_BASE_ADDRESS+(r))))
#define SMC_inw(r) (*((volatile word *)(SMC_BASE_ADDRESS+(r))))
#define SMC_inb(p) ({ \
unsigned int __p = (unsigned int)(SMC_BASE_ADDRESS + (p)); \
unsigned int __v = *(volatile unsigned short *)((SMC_BASE_ADDRESS + __p) & ~1); \
if (__p & 1) __v >>= 8; \
else __v &= 0xff; \
__v; })
#define SMC_outl(d,r) (*((volatile dword *)(SMC_BASE_ADDRESS+(r))) = d)
#define SMC_outw(d,r) (*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d)
#define SMC_outb(d,r) ({ word __d = (byte)(d); \
word __w = SMC_inw((r)&~1); \
__w &= ((r)&1) ? 0x00FF : 0xFF00; \
__w |= ((r)&1) ? __d<<8 : __d; \
SMC_outw(__w,(r)&~1); \
})
#define SMC_outsl(r,b,l) ({ int __i; \
dword *__b2; \
__b2 = (dword *) b; \
for (__i = 0; __i < l; __i++) { \
SMC_outl( *(__b2 + __i), r); \
} \
})
#define SMC_outsw(r,b,l) ({ int __i; \
word *__b2; \
__b2 = (word *) b; \
for (__i = 0; __i < l; __i++) { \
SMC_outw( *(__b2 + __i), r); \
} \
})
#define SMC_insl(r,b,l) ({ int __i ; \
dword *__b2; \
__b2 = (dword *) b; \
for (__i = 0; __i < l; __i++) { \
*(__b2 + __i) = SMC_inl(r); \
SMC_inl(0); \
}; \
})
#define SMC_insw(r,b,l) ({ int __i ; \
word *__b2; \
__b2 = (word *) b; \
for (__i = 0; __i < l; __i++) { \
*(__b2 + __i) = SMC_inw(r); \
SMC_inw(0); \
}; \
})
#define SMC_insb(r,b,l) ({ int __i ; \
byte *__b2; \
__b2 = (byte *) b; \
for (__i = 0; __i < l; __i++) { \
*(__b2 + __i) = SMC_inb(r); \
SMC_inb(0); \
}; \
})
#else /* if not CONFIG_PXA250 */
/*
* We have only 16 Bit PCMCIA access on Socket 0
*/
#define SMC_inw(r) (*((volatile word *)(SMC_BASE_ADDRESS+(r))))
#define SMC_inb(r) (((r)&1) ? SMC_inw((r)&~1)>>8 : SMC_inw(r)&0xFF)
#define SMC_outw(d,r) (*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d)
#define SMC_outb(d,r) ({ word __d = (byte)(d); \
word __w = SMC_inw((r)&~1); \
__w &= ((r)&1) ? 0x00FF : 0xFF00; \
__w |= ((r)&1) ? __d<<8 : __d; \
SMC_outw(__w,(r)&~1); \
})
#if 0
#define SMC_outsw(r,b,l) outsw(SMC_BASE_ADDRESS+(r), (b), (l))
#else
#define SMC_outsw(r,b,l) ({ int __i; \
word *__b2; \
__b2 = (word *) b; \
for (__i = 0; __i < l; __i++) { \
SMC_outw( *(__b2 + __i), r); \
} \
})
#endif
#if 0
#define SMC_insw(r,b,l) insw(SMC_BASE_ADDRESS+(r), (b), (l))
#else
#define SMC_insw(r,b,l) ({ int __i ; \
word *__b2; \
__b2 = (word *) b; \
for (__i = 0; __i < l; __i++) { \
*(__b2 + __i) = SMC_inw(r); \
SMC_inw(0); \
}; \
})
#endif
#endif
/*---------------------------------------------------------------
.
. A description of the SMSC registers is probably in order here,
. although for details, the SMC datasheet is invaluable.
.
. Basically, the chip has 4 banks of registers ( 0 to 3 ), which
. are accessed by writing a number into the BANK_SELECT register
. ( I also use a SMC_SELECT_BANK macro for this ).
.
. The banks are configured so that for most purposes, bank 2 is all
. that is needed for simple run time tasks.
-----------------------------------------------------------------------*/
/*
. Bank Select Register:
.
. yyyy yyyy 0000 00xx
. xx = bank number
. yyyy yyyy = 0x33, for identification purposes.
*/
#define BANK_SELECT 14
/* Transmit Control Register */
/* BANK 0 */
#define TCR_REG 0x0000 /* transmit control register */
#define TCR_ENABLE 0x0001 /* When 1 we can transmit */
#define TCR_LOOP 0x0002 /* Controls output pin LBK */
#define TCR_FORCOL 0x0004 /* When 1 will force a collision */
#define TCR_PAD_EN 0x0080 /* When 1 will pad tx frames < 64 bytes w/0 */
#define TCR_NOCRC 0x0100 /* When 1 will not append CRC to tx frames */
#define TCR_MON_CSN 0x0400 /* When 1 tx monitors carrier */
#define TCR_FDUPLX 0x0800 /* When 1 enables full duplex operation */
#define TCR_STP_SQET 0x1000 /* When 1 stops tx if Signal Quality Error */
#define TCR_EPH_LOOP 0x2000 /* When 1 enables EPH block loopback */
#define TCR_SWFDUP 0x8000 /* When 1 enables Switched Full Duplex mode */
#define TCR_CLEAR 0 /* do NOTHING */
/* the default settings for the TCR register : */
/* QUESTION: do I want to enable padding of short packets ? */
#define TCR_DEFAULT TCR_ENABLE
/* EPH Status Register */
/* BANK 0 */
#define EPH_STATUS_REG 0x0002
#define ES_TX_SUC 0x0001 /* Last TX was successful */
#define ES_SNGL_COL 0x0002 /* Single collision detected for last tx */
#define ES_MUL_COL 0x0004 /* Multiple collisions detected for last tx */
#define ES_LTX_MULT 0x0008 /* Last tx was a multicast */
#define ES_16COL 0x0010 /* 16 Collisions Reached */
#define ES_SQET 0x0020 /* Signal Quality Error Test */
#define ES_LTXBRD 0x0040 /* Last tx was a broadcast */
#define ES_TXDEFR 0x0080 /* Transmit Deferred */
#define ES_LATCOL 0x0200 /* Late collision detected on last tx */
#define ES_LOSTCARR 0x0400 /* Lost Carrier Sense */
#define ES_EXC_DEF 0x0800 /* Excessive Deferral */
#define ES_CTR_ROL 0x1000 /* Counter Roll Over indication */
#define ES_LINK_OK 0x4000 /* Driven by inverted value of nLNK pin */
#define ES_TXUNRN 0x8000 /* Tx Underrun */
/* Receive Control Register */
/* BANK 0 */
#define RCR_REG 0x0004
#define RCR_RX_ABORT 0x0001 /* Set if a rx frame was aborted */
#define RCR_PRMS 0x0002 /* Enable promiscuous mode */
#define RCR_ALMUL 0x0004 /* When set accepts all multicast frames */
#define RCR_RXEN 0x0100 /* IFF this is set, we can receive packets */
#define RCR_STRIP_CRC 0x0200 /* When set strips CRC from rx packets */
#define RCR_ABORT_ENB 0x0200 /* When set will abort rx on collision */
#define RCR_FILT_CAR 0x0400 /* When set filters leading 12 bit s of carrier */
#define RCR_SOFTRST 0x8000 /* resets the chip */
/* the normal settings for the RCR register : */
#define RCR_DEFAULT (RCR_STRIP_CRC | RCR_RXEN)
#define RCR_CLEAR 0x0 /* set it to a base state */
/* Counter Register */
/* BANK 0 */
#define COUNTER_REG 0x0006
/* Memory Information Register */
/* BANK 0 */
#define MIR_REG 0x0008
/* Receive/Phy Control Register */
/* BANK 0 */
#define RPC_REG 0x000A
#define RPC_SPEED 0x2000 /* When 1 PHY is in 100Mbps mode. */
#define RPC_DPLX 0x1000 /* When 1 PHY is in Full-Duplex Mode */
#define RPC_ANEG 0x0800 /* When 1 PHY is in Auto-Negotiate Mode */
#define RPC_LSXA_SHFT 5 /* Bits to shift LS2A,LS1A,LS0A to lsb */
#define RPC_LSXB_SHFT 2 /* Bits to get LS2B,LS1B,LS0B to lsb */
#define RPC_LED_100_10 (0x00) /* LED = 100Mbps OR's with 10Mbps link detect */
#define RPC_LED_RES (0x01) /* LED = Reserved */
#define RPC_LED_10 (0x02) /* LED = 10Mbps link detect */
#define RPC_LED_FD (0x03) /* LED = Full Duplex Mode */
#define RPC_LED_TX_RX (0x04) /* LED = TX or RX packet occurred */
#define RPC_LED_100 (0x05) /* LED = 100Mbps link dectect */
#define RPC_LED_TX (0x06) /* LED = TX packet occurred */
#define RPC_LED_RX (0x07) /* LED = RX packet occurred */
#define RPC_DEFAULT (RPC_ANEG | (RPC_LED_100 << RPC_LSXA_SHFT) | (RPC_LED_FD << RPC_LSXB_SHFT) | RPC_SPEED | RPC_DPLX)
/* Bank 0 0x000C is reserved */
/* Bank Select Register */
/* All Banks */
#define BSR_REG 0x000E
/* Configuration Reg */
/* BANK 1 */
#define CONFIG_REG 0x0000
#define CONFIG_EXT_PHY 0x0200 /* 1=external MII, 0=internal Phy */
#define CONFIG_GPCNTRL 0x0400 /* Inverse value drives pin nCNTRL */
#define CONFIG_NO_WAIT 0x1000 /* When 1 no extra wait states on ISA bus */
#define CONFIG_EPH_POWER_EN 0x8000 /* When 0 EPH is placed into low power mode. */
/* Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low */
#define CONFIG_DEFAULT (CONFIG_EPH_POWER_EN)
/* Base Address Register */
/* BANK 1 */
#define BASE_REG 0x0002
/* Individual Address Registers */
/* BANK 1 */
#define ADDR0_REG 0x0004
#define ADDR1_REG 0x0006
#define ADDR2_REG 0x0008
/* General Purpose Register */
/* BANK 1 */
#define GP_REG 0x000A
/* Control Register */
/* BANK 1 */
#define CTL_REG 0x000C
#define CTL_RCV_BAD 0x4000 /* When 1 bad CRC packets are received */
#define CTL_AUTO_RELEASE 0x0800 /* When 1 tx pages are released automatically */
#define CTL_LE_ENABLE 0x0080 /* When 1 enables Link Error interrupt */
#define CTL_CR_ENABLE 0x0040 /* When 1 enables Counter Rollover interrupt */
#define CTL_TE_ENABLE 0x0020 /* When 1 enables Transmit Error interrupt */
#define CTL_EEPROM_SELECT 0x0004 /* Controls EEPROM reload & store */
#define CTL_RELOAD 0x0002 /* When set reads EEPROM into registers */
#define CTL_STORE 0x0001 /* When set stores registers into EEPROM */
#define CTL_DEFAULT (0x1210)
/* MMU Command Register */
/* BANK 2 */
#define MMU_CMD_REG 0x0000
#define MC_BUSY 1 /* When 1 the last release has not completed */
#define MC_NOP (0<<5) /* No Op */
#define MC_ALLOC (1<<5) /* OR with number of 256 byte packets */
#define MC_RESET (2<<5) /* Reset MMU to initial state */
#define MC_REMOVE (3<<5) /* Remove the current rx packet */
#define MC_RELEASE (4<<5) /* Remove and release the current rx packet */
#define MC_FREEPKT (5<<5) /* Release packet in PNR register */
#define MC_ENQUEUE (6<<5) /* Enqueue the packet for transmit */
#define MC_RSTTXFIFO (7<<5) /* Reset the TX FIFOs */
/* Packet Number Register */
/* BANK 2 */
#define PN_REG 0x0002
/* Allocation Result Register */
/* BANK 2 */
#define AR_REG 0x0003
#define AR_FAILED 0x80 /* Alocation Failed */
/* RX FIFO Ports Register */
/* BANK 2 */
#define RXFIFO_REG 0x0004 /* Must be read as a word */
#define RXFIFO_REMPTY 0x8000 /* RX FIFO Empty */
/* TX FIFO Ports Register */
/* BANK 2 */
#define TXFIFO_REG RXFIFO_REG /* Must be read as a word */
#define TXFIFO_TEMPTY 0x80 /* TX FIFO Empty */
/* Pointer Register */
/* BANK 2 */
#define PTR_REG 0x0006
#define PTR_RCV 0x8000 /* 1=Receive area, 0=Transmit area */
#define PTR_AUTOINC 0x4000 /* Auto increment the pointer on each access */
#define PTR_READ 0x2000 /* When 1 the operation is a read */
/* Data Register */
/* BANK 2 */
#define SMC91111_DATA_REG 0x0008
/* Interrupt Status/Acknowledge Register */
/* BANK 2 */
#define SMC91111_INT_REG 0x000C
/* Interrupt Mask Register */
/* BANK 2 */
#define IM_REG 0x000D
#define IM_MDINT 0x80 /* PHY MI Register 18 Interrupt */
#define IM_ERCV_INT 0x40 /* Early Receive Interrupt */
#define IM_EPH_INT 0x20 /* Set by Etheret Protocol Handler section */
#define IM_RX_OVRN_INT 0x10 /* Set by Receiver Overruns */
#define IM_ALLOC_INT 0x08 /* Set when allocation request is completed */
#define IM_TX_EMPTY_INT 0x04 /* Set if the TX FIFO goes empty */
#define IM_TX_INT 0x02 /* Transmit Interrrupt */
#define IM_RCV_INT 0x01 /* Receive Interrupt */
/* Multicast Table Registers */
/* BANK 3 */
#define MCAST_REG1 0x0000
#define MCAST_REG2 0x0002
#define MCAST_REG3 0x0004
#define MCAST_REG4 0x0006
/* Management Interface Register (MII) */
/* BANK 3 */
#define MII_REG 0x0008
#define MII_MSK_CRS100 0x4000 /* Disables CRS100 detection during tx half dup */
#define MII_MDOE 0x0008 /* MII Output Enable */
#define MII_MCLK 0x0004 /* MII Clock, pin MDCLK */
#define MII_MDI 0x0002 /* MII Input, pin MDI */
#define MII_MDO 0x0001 /* MII Output, pin MDO */
/* Revision Register */
/* BANK 3 */
#define REV_REG 0x000A /* ( hi: chip id low: rev # ) */
/* Early RCV Register */
/* BANK 3 */
/* this is NOT on SMC9192 */
#define ERCV_REG 0x000C
#define ERCV_RCV_DISCRD 0x0080 /* When 1 discards a packet being received */
#define ERCV_THRESHOLD 0x001F /* ERCV Threshold Mask */
/* External Register */
/* BANK 7 */
#define EXT_REG 0x0000
#define CHIP_9192 3
#define CHIP_9194 4
#define CHIP_9195 5
#define CHIP_9196 6
#define CHIP_91100 7
#define CHIP_91100FD 8
#define CHIP_91111FD 9
#if 0
static const char * chip_ids[ 15 ] = {
NULL, NULL, NULL,
/* 3 */ "SMC91C90/91C92",
/* 4 */ "SMC91C94",
/* 5 */ "SMC91C95",
/* 6 */ "SMC91C96",
/* 7 */ "SMC91C100",
/* 8 */ "SMC91C100FD",
/* 9 */ "SMC91C111",
NULL, NULL,
NULL, NULL, NULL};
#endif
/*
. Transmit status bits
*/
#define TS_SUCCESS 0x0001
#define TS_LOSTCAR 0x0400
#define TS_LATCOL 0x0200
#define TS_16COL 0x0010
/*
. Receive status bits
*/
#define RS_ALGNERR 0x8000
#define RS_BRODCAST 0x4000
#define RS_BADCRC 0x2000
#define RS_ODDFRAME 0x1000 /* bug: the LAN91C111 never sets this on receive */
#define RS_TOOLONG 0x0800
#define RS_TOOSHORT 0x0400
#define RS_MULTICAST 0x0001
#define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
/* PHY Types */
enum {
PHY_LAN83C183 = 1, /* LAN91C111 Internal PHY */
PHY_LAN83C180
};
/* PHY Register Addresses (LAN91C111 Internal PHY) */
/* PHY Control Register */
#define PHY_CNTL_REG 0x00
#define PHY_CNTL_RST 0x8000 /* 1=PHY Reset */
#define PHY_CNTL_LPBK 0x4000 /* 1=PHY Loopback */
#define PHY_CNTL_SPEED 0x2000 /* 1=100Mbps, 0=10Mpbs */
#define PHY_CNTL_ANEG_EN 0x1000 /* 1=Enable Auto negotiation */
#define PHY_CNTL_PDN 0x0800 /* 1=PHY Power Down mode */
#define PHY_CNTL_MII_DIS 0x0400 /* 1=MII 4 bit interface disabled */
#define PHY_CNTL_ANEG_RST 0x0200 /* 1=Reset Auto negotiate */
#define PHY_CNTL_DPLX 0x0100 /* 1=Full Duplex, 0=Half Duplex */
#define PHY_CNTL_COLTST 0x0080 /* 1= MII Colision Test */
/* PHY Status Register */
#define PHY_STAT_REG 0x01
#define PHY_STAT_CAP_T4 0x8000 /* 1=100Base-T4 capable */
#define PHY_STAT_CAP_TXF 0x4000 /* 1=100Base-X full duplex capable */
#define PHY_STAT_CAP_TXH 0x2000 /* 1=100Base-X half duplex capable */
#define PHY_STAT_CAP_TF 0x1000 /* 1=10Mbps full duplex capable */
#define PHY_STAT_CAP_TH 0x0800 /* 1=10Mbps half duplex capable */
#define PHY_STAT_CAP_SUPR 0x0040 /* 1=recv mgmt frames with not preamble */
#define PHY_STAT_ANEG_ACK 0x0020 /* 1=ANEG has completed */
#define PHY_STAT_REM_FLT 0x0010 /* 1=Remote Fault detected */
#define PHY_STAT_CAP_ANEG 0x0008 /* 1=Auto negotiate capable */
#define PHY_STAT_LINK 0x0004 /* 1=valid link */
#define PHY_STAT_JAB 0x0002 /* 1=10Mbps jabber condition */
#define PHY_STAT_EXREG 0x0001 /* 1=extended registers implemented */
/* PHY Identifier Registers */
#define PHY_ID1_REG 0x02 /* PHY Identifier 1 */
#define PHY_ID2_REG 0x03 /* PHY Identifier 2 */
/* PHY Auto-Negotiation Advertisement Register */
#define PHY_AD_REG 0x04
#define PHY_AD_NP 0x8000 /* 1=PHY requests exchange of Next Page */
#define PHY_AD_ACK 0x4000 /* 1=got link code word from remote */
#define PHY_AD_RF 0x2000 /* 1=advertise remote fault */
#define PHY_AD_T4 0x0200 /* 1=PHY is capable of 100Base-T4 */
#define PHY_AD_TX_FDX 0x0100 /* 1=PHY is capable of 100Base-TX FDPLX */
#define PHY_AD_TX_HDX 0x0080 /* 1=PHY is capable of 100Base-TX HDPLX */
#define PHY_AD_10_FDX 0x0040 /* 1=PHY is capable of 10Base-T FDPLX */
#define PHY_AD_10_HDX 0x0020 /* 1=PHY is capable of 10Base-T HDPLX */
#define PHY_AD_CSMA 0x0001 /* 1=PHY is capable of 802.3 CMSA */
/* PHY Auto-negotiation Remote End Capability Register */
#define PHY_RMT_REG 0x05
/* Uses same bit definitions as PHY_AD_REG */
/* PHY Configuration Register 1 */
#define PHY_CFG1_REG 0x10
#define PHY_CFG1_LNKDIS 0x8000 /* 1=Rx Link Detect Function disabled */
#define PHY_CFG1_XMTDIS 0x4000 /* 1=TP Transmitter Disabled */
#define PHY_CFG1_XMTPDN 0x2000 /* 1=TP Transmitter Powered Down */
#define PHY_CFG1_BYPSCR 0x0400 /* 1=Bypass scrambler/descrambler */
#define PHY_CFG1_UNSCDS 0x0200 /* 1=Unscramble Idle Reception Disable */
#define PHY_CFG1_EQLZR 0x0100 /* 1=Rx Equalizer Disabled */
#define PHY_CFG1_CABLE 0x0080 /* 1=STP(150ohm), 0=UTP(100ohm) */
#define PHY_CFG1_RLVL0 0x0040 /* 1=Rx Squelch level reduced by 4.5db */
#define PHY_CFG1_TLVL_SHIFT 2 /* Transmit Output Level Adjust */
#define PHY_CFG1_TLVL_MASK 0x003C
#define PHY_CFG1_TRF_MASK 0x0003 /* Transmitter Rise/Fall time */
/* PHY Configuration Register 2 */
#define PHY_CFG2_REG 0x11
#define PHY_CFG2_APOLDIS 0x0020 /* 1=Auto Polarity Correction disabled */
#define PHY_CFG2_JABDIS 0x0010 /* 1=Jabber disabled */
#define PHY_CFG2_MREG 0x0008 /* 1=Multiple register access (MII mgt) */
#define PHY_CFG2_INTMDIO 0x0004 /* 1=Interrupt signaled with MDIO pulseo */
/* PHY Status Output (and Interrupt status) Register */
#define PHY_INT_REG 0x12 /* Status Output (Interrupt Status) */
#define PHY_INT_INT 0x8000 /* 1=bits have changed since last read */
#define PHY_INT_LNKFAIL 0x4000 /* 1=Link Not detected */
#define PHY_INT_LOSSSYNC 0x2000 /* 1=Descrambler has lost sync */
#define PHY_INT_CWRD 0x1000 /* 1=Invalid 4B5B code detected on rx */
#define PHY_INT_SSD 0x0800 /* 1=No Start Of Stream detected on rx */
#define PHY_INT_ESD 0x0400 /* 1=No End Of Stream detected on rx */
#define PHY_INT_RPOL 0x0200 /* 1=Reverse Polarity detected */
#define PHY_INT_JAB 0x0100 /* 1=Jabber detected */
#define PHY_INT_SPDDET 0x0080 /* 1=100Base-TX mode, 0=10Base-T mode */
#define PHY_INT_DPLXDET 0x0040 /* 1=Device in Full Duplex */
/* PHY Interrupt/Status Mask Register */
#define PHY_MASK_REG 0x13 /* Interrupt Mask */
/* Uses the same bit definitions as PHY_INT_REG */
/*-------------------------------------------------------------------------
. I define some macros to make it easier to do somewhat common
. or slightly complicated, repeated tasks.
--------------------------------------------------------------------------*/
/* select a register bank, 0 to 3 */
#define SMC_SELECT_BANK(x) { SMC_outw( x, BANK_SELECT ); }
/* this enables an interrupt in the interrupt mask register */
#define SMC_ENABLE_INT(x) {\
unsigned char mask;\
SMC_SELECT_BANK(2);\
mask = SMC_inb( IM_REG );\
mask |= (x);\
SMC_outb( mask, IM_REG ); \
}
/* this disables an interrupt from the interrupt mask register */
#define SMC_DISABLE_INT(x) {\
unsigned char mask;\
SMC_SELECT_BANK(2);\
mask = SMC_inb( IM_REG );\
mask &= ~(x);\
SMC_outb( mask, IM_REG ); \
}
/*----------------------------------------------------------------------
. Define the interrupts that I want to receive from the card
.
. I want:
. IM_EPH_INT, for nasty errors
. IM_RCV_INT, for happy received packets
. IM_RX_OVRN_INT, because I have to kick the receiver
. IM_MDINT, for PHY Register 18 Status Changes
--------------------------------------------------------------------------*/
#define SMC_INTERRUPT_MASK (IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT | \
IM_MDINT)
#endif /* _SMC_91111_H_ */

91
fs/jffs2/compr_rtime.c Normal file
View File

@ -0,0 +1,91 @@
/*
* JFFS2 -- Journalling Flash File System, Version 2.
*
* Copyright (C) 2001 Red Hat, Inc.
*
* Created by Arjan van de Ven <arjanv@redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: compr_rtime.c,v 1.2 2002/01/24 22:58:42 rfeany Exp $
*
*
* Very simple lz77-ish encoder.
*
* Theory of operation: Both encoder and decoder have a list of "last
* occurances" for every possible source-value; after sending the
* first source-byte, the second byte indicated the "run" length of
* matches
*
* The algorithm is intended to only send "whole bytes", no bit-messing.
*
*/
#include <config.h>
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
#include <jffs2/jffs2.h>
void rtime_decompress(unsigned char *data_in, unsigned char *cpage_out,
u32 srclen, u32 destlen)
{
int positions[256];
int outpos;
int pos;
int i;
outpos = pos = 0;
for (i = 0; i < 256; positions[i++] = 0);
while (outpos<destlen) {
unsigned char value;
int backoffs;
int repeat;
value = data_in[pos++];
cpage_out[outpos++] = value; /* first the verbatim copied byte */
repeat = data_in[pos++];
backoffs = positions[value];
positions[value]=outpos;
if (repeat) {
if (backoffs + repeat >= outpos) {
while(repeat) {
cpage_out[outpos++] = cpage_out[backoffs++];
repeat--;
}
} else {
for (i = 0; i < repeat; i++)
*(cpage_out + outpos + i) = *(cpage_out + backoffs + i);
outpos+=repeat;
}
}
}
}
#endif /* CFG_CMD_JFFS2 */

124
fs/jffs2/compr_rubin.c Normal file
View File

@ -0,0 +1,124 @@
/*
* JFFS2 -- Journalling Flash File System, Version 2.
*
* Copyright (C) 2001 Red Hat, Inc.
*
* Created by Arjan van de Ven <arjanv@redhat.com>
*
* Heavily modified by Russ Dill <Russ.Dill@asu.edu> in an attempt at
* a little more speed.
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: compr_rubin.c,v 1.2 2002/01/24 22:58:42 rfeany Exp $
*
*/
#include <config.h>
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
#include <jffs2/jffs2.h>
#include <jffs2/compr_rubin.h>
void rubin_do_decompress(unsigned char *bits, unsigned char *in,
unsigned char *page_out, __u32 destlen)
{
register char *curr = page_out;
char *end = page_out + destlen;
register unsigned long temp;
register unsigned long result;
register unsigned long p;
register unsigned long q;
register unsigned long rec_q;
register unsigned long bit;
register long i0;
unsigned long i;
/* init_pushpull */
temp = *(u32 *) in;
bit = 16;
/* init_rubin */
q = 0;
p = (long) (2 * UPPER_BIT_RUBIN);
/* init_decode */
rec_q = (in[0] << 8) | in[1];
while (curr < end) {
/* in byte */
result = 0;
for (i = 0; i < 8; i++) {
/* decode */
while ((q & UPPER_BIT_RUBIN) || ((p + q) <= UPPER_BIT_RUBIN)) {
q &= ~UPPER_BIT_RUBIN;
q <<= 1;
p <<= 1;
rec_q &= ~UPPER_BIT_RUBIN;
rec_q <<= 1;
rec_q |= (temp >> (bit++ ^ 7)) & 1;
if (bit > 31) {
bit = 0;
temp = *(++((u32 *) in));
}
}
i0 = (bits[i] * p) >> 8;
if (i0 <= 0) i0 = 1;
/* if it fails, it fails, we have our crc
if (i0 >= p) i0 = p - 1; */
result >>= 1;
if (rec_q < q + i0) {
/* result |= 0x00; */
p = i0;
} else {
result |= 0x80;
p -= i0;
q += i0;
}
}
*(curr++) = result;
}
}
void dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out,
unsigned long sourcelen, unsigned long dstlen)
{
unsigned char bits[8];
int c;
for (c=0; c<8; c++)
bits[c] = (256 - data_in[c]);
rubin_do_decompress(bits, data_in+8, cpage_out, dstlen);
}
#endif /* CFG_CMD_JFFS2 */

52
fs/jffs2/compr_zlib.c Normal file
View File

@ -0,0 +1,52 @@
/*
* JFFS2 -- Journalling Flash File System, Version 2.
*
* Copyright (C) 2001 Red Hat, Inc.
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: compr_zlib.c,v 1.2 2002/01/24 22:58:42 rfeany Exp $
*
*/
#include <common.h>
#include <config.h>
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
#include <jffs2/jffs2.h>
#include <jffs2/mini_inflate.h>
long zlib_decompress(unsigned char *data_in, unsigned char *cpage_out,
__u32 srclen, __u32 destlen)
{
return (decompress_block(cpage_out, data_in + 2, ldr_memcpy));
}
#endif /* CFG_CMD_JFFS2 */

995
fs/jffs2/jffs2_1pass.c Normal file
View File

@ -0,0 +1,995 @@
/*
-------------------------------------------------------------------------
* Filename: jffs2.c
* Version: $Id: jffs2_1pass.c,v 1.7 2002/01/25 01:56:47 nyet Exp $
* Copyright: Copyright (C) 2001, Russ Dill
* Author: Russ Dill <Russ.Dill@asu.edu>
* Description: Module to load kernel from jffs2
*-----------------------------------------------------------------------*/
/*
* some portions of this code are taken from jffs2, and as such, the
* following copyright notice is included.
*
* JFFS2 -- Journalling Flash File System, Version 2.
*
* Copyright (C) 2001 Red Hat, Inc.
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: jffs2_1pass.c,v 1.7 2002/01/25 01:56:47 nyet Exp $
*
*/
/* Ok, so anyone who knows the jffs2 code will probably want to get a papar
* bag to throw up into before reading this code. I looked through the jffs2
* code, the caching scheme is very elegant. I tried to keep the version
* for a bootloader as small and simple as possible. Instead of worring about
* unneccesary data copies, node scans, etc, I just optimized for the known
* common case, a kernel, which looks like:
* (1) most pages are 4096 bytes
* (2) version numbers are somewhat sorted in acsending order
* (3) multiple compressed blocks making up one page is uncommon
*
* So I create a linked list of decending version numbers (insertions at the
* head), and then for each page, walk down the list, until a matching page
* with 4096 bytes is found, and then decompress the watching pages in
* reverse order.
*
*/
/*
* Adapted by Nye Liu <nyet@zumanetworks.com> and
* Rex Feany <rfeany@zumanetworks.com>
* on Jan/2002 for U-Boot.
*
* Clipped out all the non-1pass functions, cleaned up warnings,
* wrappers, etc. No major changes to the code.
* Please, he really means it when he said have a paper bag
* handy. We needed it ;).
*
*/
#include <common.h>
#include <config.h>
#include <malloc.h>
#include <linux/stat.h>
#include <linux/time.h>
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
#include <jffs2/jffs2.h>
#include <jffs2/jffs2_1pass.h>
#include "jffs2_private.h"
/* Compression names */
static char *compr_names[] = {
"NONE",
"ZERO",
"RTIME",
"RUBINMIPS",
"COPY",
"DYNRUBIN",
"ZLIB" };
static char spinner[] = { '|', '\\', '-', '/' };
#define DEBUG
#ifdef DEBUG
# define DEBUGF(fmt,args...) printf(fmt ,##args)
#else
# define DEBUGF(fmt,args...)
#endif
#define MALLOC_CHUNK (10*1024)
static struct b_node *
add_node(struct b_node *tail, u32 * count, u32 * memBase)
{
u32 index;
u32 memLimit;
struct b_node *b;
index = (*count) * sizeof(struct b_node) % MALLOC_CHUNK;
memLimit = MALLOC_CHUNK;
#if 0
putLabeledWord("add_node: index = ", index);
putLabeledWord("add_node: memLimit = ", memLimit);
putLabeledWord("add_node: memBase = ", *memBase);
#endif
/* we need not keep a list of bases since we'll never free the */
/* memory, just jump the the kernel */
if ((index == 0) || (index > memLimit)) { /* we need mode space before we continue */
if ((*memBase = (u32) mmalloc(MALLOC_CHUNK)) == (u32) NULL) {
putstr("add_node: malloc failed\n");
return NULL;
}
#if 0
putLabeledWord("add_node: alloced a new membase at ", *memBase);
#endif
}
/* now we have room to add it. */
b = (struct b_node *) (*memBase + index);
/* null on first call */
if (tail)
tail->next = b;
#if 0
putLabeledWord("add_node: tail = ", (u32) tail);
if (tail)
putLabeledWord("add_node: tail->next = ", (u32) tail->next);
#endif
#if 0
putLabeledWord("add_node: mb+i = ", (u32) (*memBase + index));
putLabeledWord("add_node: b = ", (u32) b);
#endif
(*count)++;
b->next = (struct b_node *) NULL;
return b;
}
/* we know we have empties at the start offset so we will hop */
/* t points that would be non F if there were a node here to speed this up. */
struct jffs2_empty_node {
u32 first;
u32 second;
};
static u32
jffs2_scan_empty(u32 start_offset, struct part_info *part)
{
u32 max = part->size - sizeof(struct jffs2_raw_inode);
/* this would be either dir node_crc or frag isize */
u32 offset = start_offset + 32;
struct jffs2_empty_node *node;
start_offset += 4;
while (offset < max) {
node = (struct jffs2_empty_node *) (part->offset + offset);
if ((node->first == 0xFFFFFFFF) && (node->second == 0xFFFFFFFF)) {
/* we presume that there were no nodes in between and advance in a hop */
/* putLabeledWord("\t\tjffs2_scan_empty: empty at offset=",offset); */
start_offset = offset + 4;
offset = start_offset + 32; /* orig 32 + 4 bytes for the second==0xfffff */
} else {
return start_offset;
}
}
return start_offset;
}
static u32
jffs_init_1pass_list(struct part_info *part)
{
if ( 0 != ( part->jffs2_priv=malloc(sizeof(struct b_lists)))){
struct b_lists *pL =(struct b_lists *)part->jffs2_priv;
pL->dirListHead = pL->dirListTail = NULL;
pL->fragListHead = pL->fragListTail = NULL;
pL->dirListCount = 0;
pL->dirListMemBase = 0;
pL->fragListCount = 0;
pL->fragListMemBase = 0;
pL->partOffset = 0x0;
}
return 0;
}
/* find the inode from the slashless name given a parent */
static long
jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest)
{
struct b_node *b;
struct jffs2_raw_inode *jNode;
u32 totalSize = 1;
u32 oldTotalSize = 0;
u32 size = 0;
char *lDest = (char *) dest;
char *src;
long ret;
int i;
u32 counter = 0;
char totalSizeSet = 0;
#if 0
b = pL->fragListHead;
while (b) {
jNode = (struct jffs2_raw_inode *) (b->offset);
if ((inode == jNode->ino)) {
putLabeledWord("\r\n\r\nread_inode: totlen = ", jNode->totlen);
putLabeledWord("read_inode: inode = ", jNode->ino);
putLabeledWord("read_inode: version = ", jNode->version);
putLabeledWord("read_inode: isize = ", jNode->isize);
putLabeledWord("read_inode: offset = ", jNode->offset);
putLabeledWord("read_inode: csize = ", jNode->csize);
putLabeledWord("read_inode: dsize = ", jNode->dsize);
putLabeledWord("read_inode: compr = ", jNode->compr);
putLabeledWord("read_inode: usercompr = ", jNode->usercompr);
putLabeledWord("read_inode: flags = ", jNode->flags);
}
b = b->next;
}
#endif
#if 1
b = pL->fragListHead;
while (b && (size < totalSize)) {
jNode = (struct jffs2_raw_inode *) (b->offset);
if ((inode == jNode->ino)) {
if ((jNode->isize == oldTotalSize) && (jNode->isize > totalSize)) {
/* 2 consecutive isizes indicate file length */
totalSize = jNode->isize;
totalSizeSet = 1;
} else if (!totalSizeSet) {
totalSize = size + jNode->dsize + 1;
}
oldTotalSize = jNode->isize;
if(dest) {
src = ((char *) jNode) + sizeof(struct jffs2_raw_inode);
/* lDest = (char *) (dest + (jNode->offset & ~3)); */
lDest = (char *) (dest + jNode->offset);
#if 0
putLabeledWord("\r\n\r\nread_inode: src = ", src);
putLabeledWord("read_inode: dest = ", lDest);
putLabeledWord("read_inode: dsize = ", jNode->dsize);
putLabeledWord("read_inode: csize = ", jNode->csize);
putLabeledWord("read_inode: version = ", jNode->version);
putLabeledWord("read_inode: isize = ", jNode->isize);
putLabeledWord("read_inode: offset = ", jNode->offset);
putLabeledWord("read_inode: compr = ", jNode->compr);
putLabeledWord("read_inode: flags = ", jNode->flags);
#endif
switch (jNode->compr) {
case JFFS2_COMPR_NONE:
#if 0
{
int i;
if ((dest > 0xc0092ff0) && (dest < 0xc0093000))
for (i = 0; i < first->length; i++) {
putLabeledWord("\tCOMPR_NONE: src =", src + i);
putLabeledWord("\tCOMPR_NONE: length =", first->length);
putLabeledWord("\tCOMPR_NONE: dest =", dest + i);
putLabeledWord("\tCOMPR_NONE: data =", (unsigned char) *(src + i));
}
}
#endif
ret = (unsigned long) ldr_memcpy(lDest, src, jNode->dsize);
break;
case JFFS2_COMPR_ZERO:
ret = 0;
for (i = 0; i < jNode->dsize; i++)
*(lDest++) = 0;
break;
case JFFS2_COMPR_RTIME:
ret = 0;
rtime_decompress(src, lDest, jNode->csize, jNode->dsize);
break;
case JFFS2_COMPR_DYNRUBIN:
/* this is slow but it works */
ret = 0;
dynrubin_decompress(src, lDest, jNode->csize, jNode->dsize);
break;
case JFFS2_COMPR_ZLIB:
ret = zlib_decompress(src, lDest, jNode->csize, jNode->dsize);
break;
default:
/* unknown */
putLabeledWord("UNKOWN COMPRESSION METHOD = ", jNode->compr);
return -1;
break;
}
}
size += jNode->dsize;
#if 0
putLabeledWord("read_inode: size = ", size);
putLabeledWord("read_inode: totalSize = ", totalSize);
putLabeledWord("read_inode: compr ret = ", ret);
#endif
}
b = b->next;
counter++;
}
#endif
#if 0
putLabeledWord("read_inode: returning = ", size);
#endif
return size;
}
/* find the inode from the slashless name given a parent */
static u32
jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino)
{
struct b_node *b;
struct jffs2_raw_dirent *jDir;
int len;
u32 counter;
u32 version = 0;
u32 inode = 0;
/* name is assumed slash free */
len = strlen(name);
counter = 0;
/* we need to search all and return the inode with the highest version */
for(b = pL->dirListHead;b;b=b->next,counter++) {
jDir = (struct jffs2_raw_dirent *) (b->offset);
if ((pino == jDir->pino) && (len == jDir->nsize) && (jDir->ino) && /* 0 for unlink */
(!strncmp(jDir->name, name, len))) { /* a match */
if (jDir->version < version) continue;
if(jDir->version==0) {
/* Is this legal? */
putstr(" ** WARNING ** ");
putnstr(jDir->name, jDir->nsize);
putstr(" is version 0 (in find, ignoring)\r\n");
} else if(jDir->version==version) {
/* Im pretty sure this isn't ... */
putstr(" ** ERROR ** ");
putnstr(jDir->name, jDir->nsize);
putLabeledWord(" has dup version =", version);
}
inode = jDir->ino;
version = jDir->version;
}
#if 0
putstr("\r\nfind_inode:p&l ->");
putnstr(jDir->name, jDir->nsize);
putstr("\r\n");
putLabeledWord("pino = ", jDir->pino);
putLabeledWord("nsize = ", jDir->nsize);
putLabeledWord("b = ", (u32) b);
putLabeledWord("counter = ", counter);
#endif
}
return inode;
}
static char *mkmodestr(unsigned long mode, char *str)
{
static const char *l="xwr";
int mask=1, i;
char c;
switch (mode & S_IFMT) {
case S_IFDIR: str[0]='d'; break;
case S_IFBLK: str[0]='b'; break;
case S_IFCHR: str[0]='c'; break;
case S_IFIFO: str[0]='f'; break;
case S_IFLNK: str[0]='l'; break;
case S_IFSOCK: str[0]='s'; break;
case S_IFREG: str[0]='-'; break;
default: str[0]='?';
}
for(i=0;i<9;i++) {
c=l[i%3];
str[9-i]=(mode & mask)?c:'-';
mask=mask<<1;
}
if(mode & S_ISUID) str[3]=(mode & S_IXUSR)?'s':'S';
if(mode & S_ISGID) str[6]=(mode & S_IXGRP)?'s':'S';
if(mode & S_ISVTX) str[9]=(mode & S_IXOTH)?'t':'T';
str[10]='\0';
return str;
}
static inline void dump_stat(struct stat *st, const char *name)
{
char str[20];
char s[64], *p;
if (st->st_mtime == (time_t)(-1)) /* some ctimes really hate -1 */
st->st_mtime = 1;
ctime_r(&st->st_mtime, s/*, 64*/); /* newlib ctime doesn't have buflen */
if((p=strchr(s,'\n'))!=NULL) *p='\0';
if((p=strchr(s,'\r'))!=NULL) *p='\0';
/*
printf("%6lo %s %8ld %s %s\n", st->st_mode, mkmodestr(st->st_mode, str),
st->st_size, s, name);
*/
printf(" %s %8ld %s %s", mkmodestr(st->st_mode,str), st->st_size, s, name);
}
static inline u32 dump_inode(struct b_lists * pL, struct jffs2_raw_dirent *d, struct jffs2_raw_inode *i)
{
char fname[256];
struct stat st;
if(!d || !i) return -1;
strncpy(fname, d->name, d->nsize);
fname[d->nsize]='\0';
memset(&st,0,sizeof(st));
st.st_mtime=i->mtime;
st.st_mode=i->mode;
st.st_ino=i->ino;
/* neither dsize nor isize help us.. do it the long way */
st.st_size=jffs2_1pass_read_inode(pL, i->ino, NULL);
dump_stat(&st, fname);
if (d->type == DT_LNK) {
unsigned char *src = (unsigned char *) (&i[1]);
putstr(" -> ");
putnstr(src, (int)i->dsize);
}
putstr("\r\n");
return 0;
}
/* list inodes with the given pino */
static u32
jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino)
{
struct b_node *b;
struct jffs2_raw_dirent *jDir;
for(b = pL->dirListHead;b;b=b->next) {
jDir = (struct jffs2_raw_dirent *) (b->offset);
if ((pino == jDir->pino) && (jDir->ino)) { /* 0 inode for unlink */
u32 i_version=0;
struct jffs2_raw_inode *jNode, *i=NULL;
struct b_node *b2 = pL->fragListHead;
while (b2) {
jNode = (struct jffs2_raw_inode *) (b2->offset);
if (jNode->ino == jDir->ino
&& jNode->version>=i_version)
i=jNode;
b2 = b2->next;
}
dump_inode(pL, jDir, i);
}
}
return pino;
}
static u32
jffs2_1pass_search_inode(struct b_lists * pL, const char *fname, u32 pino)
{
int i;
char tmp[256];
char working_tmp[256];
char *c;
/* discard any leading slash */
i = 0;
while (fname[i] == '/')
i++;
strcpy(tmp, &fname[i]);
while ((c = (char *) strchr(tmp, '/'))) /* we are still dired searching */
{
strncpy(working_tmp, tmp, c - tmp);
working_tmp[c - tmp] = '\0';
#if 0
putstr("search_inode: tmp = ");
putstr(tmp);
putstr("\r\n");
putstr("search_inode: wtmp = ");
putstr(working_tmp);
putstr("\r\n");
putstr("search_inode: c = ");
putstr(c);
putstr("\r\n");
#endif
for (i = 0; i < strlen(c) - 1; i++)
tmp[i] = c[i + 1];
tmp[i] = '\0';
#if 0
putstr("search_inode: post tmp = ");
putstr(tmp);
putstr("\r\n");
#endif
if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino))) {
putstr("find_inode failed for name=");
putstr(working_tmp);
putstr("\r\n");
return 0;
}
}
/* this is for the bare filename, directories have already been mapped */
if (!(pino = jffs2_1pass_find_inode(pL, tmp, pino))) {
putstr("find_inode failed for name=");
putstr(tmp);
putstr("\r\n");
return 0;
}
return pino;
}
static u32
jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino)
{
struct b_node *b;
struct b_node *b2;
struct jffs2_raw_dirent *jDir;
struct jffs2_raw_inode *jNode;
struct jffs2_raw_dirent *jDirFound = NULL;
char tmp[256];
u32 version = 0;
u32 pino;
unsigned char *src;
/* we need to search all and return the inode with the highest version */
for(b = pL->dirListHead; b; b=b->next) {
jDir = (struct jffs2_raw_dirent *) (b->offset);
if (ino == jDir->ino) {
if(jDir->version < version) continue;
if(jDir->version == 0) {
/* Is this legal? */
putstr(" ** WARNING ** ");
putnstr(jDir->name, jDir->nsize);
putstr(" is version 0 (in resolve, ignoring)\r\n");
} else if(jDir->version == version) {
/* Im pretty sure this isn't ... */
putstr(" ** ERROR ** ");
putnstr(jDir->name, jDir->nsize);
putLabeledWord(" has dup version (resolve) = ",
version);
}
jDirFound = jDir;
version = jDir->version;
}
}
/* now we found the right entry again. (shoulda returned inode*) */
if (jDirFound->type != DT_LNK)
return jDirFound->ino;
/* so its a soft link so we follow it again. */
b2 = pL->fragListHead;
while (b2) {
jNode = (struct jffs2_raw_inode *) (b2->offset);
if (jNode->ino == jDirFound->ino) {
src = (unsigned char *) (b2->offset + sizeof(struct jffs2_raw_inode));
#if 0
putLabeledWord("\t\t dsize = ", jNode->dsize);
putstr("\t\t target = ");
putnstr(src, jNode->dsize);
putstr("\r\n");
#endif
strncpy(tmp, src, jNode->dsize);
tmp[jNode->dsize] = '\0';
break;
}
b2 = b2->next;
}
/* ok so the name of the new file to find is in tmp */
/* if it starts with a slash it is root based else shared dirs */
if (tmp[0] == '/')
pino = 1;
else
pino = jDirFound->pino;
return jffs2_1pass_search_inode(pL, tmp, pino);
}
static u32
jffs2_1pass_search_list_inodes(struct b_lists * pL, const char *fname, u32 pino)
{
int i;
char tmp[256];
char working_tmp[256];
char *c;
/* discard any leading slash */
i = 0;
while (fname[i] == '/')
i++;
strcpy(tmp, &fname[i]);
working_tmp[0] = '\0';
while ((c = (char *) strchr(tmp, '/'))) /* we are still dired searching */
{
strncpy(working_tmp, tmp, c - tmp);
working_tmp[c - tmp] = '\0';
for (i = 0; i < strlen(c) - 1; i++)
tmp[i] = c[i + 1];
tmp[i] = '\0';
/* only a failure if we arent looking at top level */
if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino)) && (working_tmp[0])) {
putstr("find_inode failed for name=");
putstr(working_tmp);
putstr("\r\n");
return 0;
}
}
if (tmp[0] && !(pino = jffs2_1pass_find_inode(pL, tmp, pino))) {
putstr("find_inode failed for name=");
putstr(tmp);
putstr("\r\n");
return 0;
}
/* this is for the bare filename, directories have already been mapped */
if (!(pino = jffs2_1pass_list_inodes(pL, pino))) {
putstr("find_inode failed for name=");
putstr(tmp);
putstr("\r\n");
return 0;
}
return pino;
}
unsigned char
jffs2_1pass_rescan_needed(struct part_info *part)
{
struct b_node *b;
struct jffs2_unknown_node *node;
struct b_lists *pL=(struct b_lists *)part->jffs2_priv;
if (part->jffs2_priv == 0){
DEBUGF ("rescan: First time in use\n");
return 1;
}
/* if we have no list, we need to rescan */
if (pL->fragListCount == 0) {
DEBUGF ("rescan: fraglist zero\n");
return 1;
}
/* or if we are scanninga new partition */
if (pL->partOffset != part->offset) {
DEBUGF ("rescan: different partition\n");
return 1;
}
/* but suppose someone reflashed the root partition at the same offset... */
b = pL->dirListHead;
while (b) {
node = (struct jffs2_unknown_node *) (b->offset);
if (node->nodetype != JFFS2_NODETYPE_DIRENT) {
DEBUGF ("rescan: fs changed beneath me? (%lx)\n", (unsigned long) b->offset);
return 1;
}
b = b->next;
}
return 0;
}
static u32
jffs2_1pass_build_lists(struct part_info * part)
{
struct b_lists *pL;
struct jffs2_unknown_node *node;
u32 offset;
u32 max = part->size - sizeof(struct jffs2_raw_inode);
u32 counter = 0;
u32 counter4 = 0;
u32 counterF = 0;
u32 counterN = 0;
/* turn off the lcd. Refreshing the lcd adds 50% overhead to the */
/* jffs2 list building enterprise nope. in newer versions the overhead is */
/* only about 5 %. not enough to inconvenience people for. */
/* lcd_off(); */
/* if we are building a list we need to refresh the cache. */
/* note that since we don't free our memory, eventually this will be bad. */
/* but we're a bootldr so what the hell. */
jffs_init_1pass_list(part);
pL=(struct b_lists *)part->jffs2_priv;
pL->partOffset = part->offset;
offset = 0;
printf("Scanning JFFS2 FS: ");
/* start at the beginning of the partition */
while (offset < max) {
if (! (++counter%10000))
printf("\b\b%c ", spinner[(counter / 10000) % 4]);
node = (struct jffs2_unknown_node *) (part->offset + offset);
if (node->magic == JFFS2_MAGIC_BITMASK && hdr_crc(node)) {
/* if its a fragment add it */
if (node->nodetype == JFFS2_NODETYPE_INODE && inode_crc((struct jffs2_raw_inode *) node)) {
if (!(pL->fragListTail = add_node(pL->fragListTail, &(pL->fragListCount),
&(pL->fragListMemBase)))) {
putstr("add_node failed!\r\n");
return 0;
}
pL->fragListTail->offset = (u32) (part->offset + offset);
if (!pL->fragListHead)
pL->fragListHead = pL->fragListTail;
} else if (node->nodetype == JFFS2_NODETYPE_DIRENT &&
dirent_crc((struct jffs2_raw_dirent *) node) &&
dirent_name_crc((struct jffs2_raw_dirent *) node)) {
if (! (counterN%100))
printf("\b\b. ");
#if 0
printf("Found DIRENT @ 0x%lx\n", offset);
putstr("\r\nbuild_lists:p&l ->");
putnstr(((struct jffs2_raw_dirent *) node)->name, ((struct jffs2_raw_dirent *) node)->nsize);
putstr("\r\n");
putLabeledWord("\tpino = ", ((struct jffs2_raw_dirent *) node)->pino);
putLabeledWord("\tnsize = ", ((struct jffs2_raw_dirent *) node)->nsize);
#endif
if (!(pL->dirListTail = add_node(pL->dirListTail, &(pL->dirListCount), &(pL->dirListMemBase)))) {
putstr("add_node failed!\r\n");
return 0;
}
pL->dirListTail->offset = (u32) (part->offset + offset);
#if 0
putLabeledWord("\ttail = ", (u32) pL->dirListTail);
putstr("\ttailName ->");
putnstr(((struct jffs2_raw_dirent *) (pL->dirListTail->offset))->name,
((struct jffs2_raw_dirent *) (pL->dirListTail->offset))->nsize);
putstr("\r\n");
#endif
if (!pL->dirListHead)
pL->dirListHead = pL->dirListTail;
counterN++;
} else if (node->nodetype == JFFS2_NODETYPE_CLEANMARKER) {
if (node->totlen != sizeof(struct jffs2_unknown_node))
printf("OOPS Cleanmarker has bad size %d != %d\n", node->totlen, sizeof(struct jffs2_unknown_node));
} else {
printf("Unknown node type: %x len %d offset 0x%x\n", node->nodetype, node->totlen, offset);
}
offset += ((node->totlen + 3) & ~3);
counterF++;
} else if (node->magic == JFFS2_EMPTY_BITMASK && node->nodetype == JFFS2_EMPTY_BITMASK) {
offset = jffs2_scan_empty(offset, part);
} else { /* if we know nothing of the filesystem, we just step and look. */
offset += 4;
counter4++;
}
/* printf("unknown node magic %4.4x %4.4x @ %lx\n", node->magic, node->nodetype, (unsigned long)node); */
}
putstr("\b\b done.\r\n"); /* close off the dots */
/* turn the lcd back on. */
/* splash(); */
#if 0
putLabeledWord("dir entries = ", pL->dirListCount);
putLabeledWord("frag entries = ", pL->fragListCount);
putLabeledWord("+4 increments = ", counter4);
putLabeledWord("+file_offset increments = ", counterF);
#endif
#undef SHOW_ALL
#undef SHOW_ALL_FRAGMENTS
#ifdef SHOW_ALL
{
struct b_node *b;
struct b_node *b2;
struct jffs2_raw_dirent *jDir;
struct jffs2_raw_inode *jNode;
putstr("\r\n\r\n******The directory Entries******\r\n");
b = pL->dirListHead;
while (b) {
jDir = (struct jffs2_raw_dirent *) (b->offset);
putstr("\r\n");
putnstr(jDir->name, jDir->nsize);
putLabeledWord("\r\n\tbuild_list: magic = ", jDir->magic);
putLabeledWord("\tbuild_list: nodetype = ", jDir->nodetype);
putLabeledWord("\tbuild_list: hdr_crc = ", jDir->hdr_crc);
putLabeledWord("\tbuild_list: pino = ", jDir->pino);
putLabeledWord("\tbuild_list: version = ", jDir->version);
putLabeledWord("\tbuild_list: ino = ", jDir->ino);
putLabeledWord("\tbuild_list: mctime = ", jDir->mctime);
putLabeledWord("\tbuild_list: nsize = ", jDir->nsize);
putLabeledWord("\tbuild_list: type = ", jDir->type);
putLabeledWord("\tbuild_list: node_crc = ", jDir->node_crc);
putLabeledWord("\tbuild_list: name_crc = ", jDir->name_crc);
b = b->next;
}
#ifdef SHOW_ALL_FRAGMENTS
putstr("\r\n\r\n******The fragment Entries******\r\n");
b = pL->fragListHead;
while (b) {
jNode = (struct jffs2_raw_inode *) (b->offset);
putLabeledWord("\r\n\tbuild_list: FLASH_OFFSET = ", b->offset);
putLabeledWord("\tbuild_list: totlen = ", jNode->totlen);
putLabeledWord("\tbuild_list: inode = ", jNode->ino);
putLabeledWord("\tbuild_list: version = ", jNode->version);
putLabeledWord("\tbuild_list: isize = ", jNode->isize);
putLabeledWord("\tbuild_list: atime = ", jNode->atime);
putLabeledWord("\tbuild_list: offset = ", jNode->offset);
putLabeledWord("\tbuild_list: csize = ", jNode->csize);
putLabeledWord("\tbuild_list: dsize = ", jNode->dsize);
putLabeledWord("\tbuild_list: compr = ", jNode->compr);
putLabeledWord("\tbuild_list: usercompr = ", jNode->usercompr);
putLabeledWord("\tbuild_list: flags = ", jNode->flags);
b = b->next;
}
#endif /* SHOW_ALL_FRAGMENTS */
}
#endif /* SHOW_ALL */
/* give visual feedback that we are done scanning the flash */
led_blink(0x0, 0x0, 0x1, 0x1); /* off, forever, on 100ms, off 100ms */
return 1;
}
static u32
jffs2_1pass_fill_info(struct b_lists * pL, struct b_jffs2_info * piL)
{
struct b_node *b;
struct jffs2_raw_inode *jNode;
int i;
b = pL->fragListHead;
for (i = 0; i < JFFS2_NUM_COMPR; i++) {
piL->compr_info[i].num_frags = 0;
piL->compr_info[i].compr_sum = 0;
piL->compr_info[i].decompr_sum = 0;
}
while (b) {
jNode = (struct jffs2_raw_inode *) (b->offset);
if (jNode->compr < JFFS2_NUM_COMPR) {
piL->compr_info[jNode->compr].num_frags++;
piL->compr_info[jNode->compr].compr_sum += jNode->csize;
piL->compr_info[jNode->compr].decompr_sum += jNode->dsize;
}
b = b->next;
}
return 0;
}
static struct b_lists *
jffs2_get_list(struct part_info * part, const char *who)
{
if (jffs2_1pass_rescan_needed(part)) {
if (!jffs2_1pass_build_lists(part)) {
printf("%s: Failed to scan JFFSv2 file structure\n", who);
return NULL;
}
}
return (struct b_lists *)part->jffs2_priv;
}
/* Print directory / file contents */
u32
jffs2_1pass_ls(struct part_info * part, const char *fname)
{
struct b_lists *pl;
long ret = 0;
u32 inode;
if (! (pl = jffs2_get_list(part, "ls")))
return 0;
if (! (inode = jffs2_1pass_search_list_inodes(pl, fname, 1))) {
putstr("ls: Failed to scan jffs2 file structure\r\n");
return 0;
}
#if 0
putLabeledWord("found file at inode = ", inode);
putLabeledWord("read_inode returns = ", ret);
#endif
return ret;
}
/* Load a file from flash into memory. fname can be a full path */
u32
jffs2_1pass_load(char *dest, struct part_info * part, const char *fname)
{
struct b_lists *pl;
long ret = 0;
u32 inode;
if (! (pl = jffs2_get_list(part, "load")))
return 0;
if (! (inode = jffs2_1pass_search_inode(pl, fname, 1))) {
putstr("load: Failed to find inode\r\n");
return 0;
}
/* Resolve symlinks */
if (! (inode = jffs2_1pass_resolve_inode(pl, inode))) {
putstr("load: Failed to resolve inode structure\r\n");
return 0;
}
if ((ret = jffs2_1pass_read_inode(pl, inode, dest)) < 0) {
putstr("load: Failed to read inode\r\n");
return 0;
}
DEBUGF ("load: loaded '%s' to 0x%lx (%ld bytes)\n", fname,
(unsigned long) dest, ret);
return ret;
}
/* Return information about the fs on this partition */
u32
jffs2_1pass_info(struct part_info * part)
{
struct b_jffs2_info info;
struct b_lists *pl;
int i;
if (! (pl = jffs2_get_list(part, "info")))
return 0;
jffs2_1pass_fill_info(pl, &info);
for (i=0; i < JFFS2_NUM_COMPR; i++) {
printf("Compression: %s\n", compr_names[i]);
printf("\tfrag count: %d\n", info.compr_info[i].num_frags);
printf("\tcompressed sum: %d\n", info.compr_info[i].compr_sum);
printf("\tuncompressed sum: %d\n", info.compr_info[i].decompr_sum);
}
return 1;
}
#endif /* CFG_CMD_JFFS2 */

643
include/asm-ppc/pnp.h Normal file
View File

@ -0,0 +1,643 @@
/* 11/02/95 */
/*----------------------------------------------------------------------------*/
/* Plug and Play header definitions */
/*----------------------------------------------------------------------------*/
/* Structure map for PnP on PowerPC Reference Platform */
/* See Plug and Play ISA Specification, Version 1.0, May 28, 1993. It */
/* (or later versions) is available on Compuserve in the PLUGPLAY area. */
/* This code has extensions to that specification, namely new short and */
/* long tag types for platform dependent information */
/* Warning: LE notation used throughout this file */
/* For enum's: if given in hex then they are bit significant, i.e. */
/* only one bit is on for each enum */
#ifndef _PNP_
#define _PNP_
#ifndef __ASSEMBLY__
#define MAX_MEM_REGISTERS 9
#define MAX_IO_PORTS 20
#define MAX_IRQS 7
/*#define MAX_DMA_CHANNELS 7*/
/* Interrupt controllers */
#define PNPinterrupt0 "PNP0000" /* AT Interrupt Controller */
#define PNPinterrupt1 "PNP0001" /* EISA Interrupt Controller */
#define PNPinterrupt2 "PNP0002" /* MCA Interrupt Controller */
#define PNPinterrupt3 "PNP0003" /* APIC */
#define PNPExtInt "IBM000D" /* PowerPC Extended Interrupt Controller */
/* Timers */
#define PNPtimer0 "PNP0100" /* AT Timer */
#define PNPtimer1 "PNP0101" /* EISA Timer */
#define PNPtimer2 "PNP0102" /* MCA Timer */
/* DMA controllers */
#define PNPdma0 "PNP0200" /* AT DMA Controller */
#define PNPdma1 "PNP0201" /* EISA DMA Controller */
#define PNPdma2 "PNP0202" /* MCA DMA Controller */
/* start of August 15, 1994 additions */
/* CMOS */
#define PNPCMOS "IBM0009" /* CMOS */
/* L2 Cache */
#define PNPL2 "IBM0007" /* L2 Cache */
/* NVRAM */
#define PNPNVRAM "IBM0008" /* NVRAM */
/* Power Management */
#define PNPPM "IBM0005" /* Power Management */
/* end of August 15, 1994 additions */
/* Keyboards */
#define PNPkeyboard0 "PNP0300" /* IBM PC/XT KB Cntlr (83 key, no mouse) */
#define PNPkeyboard1 "PNP0301" /* Olivetti ICO (102 key) */
#define PNPkeyboard2 "PNP0302" /* IBM PC/AT KB Cntlr (84 key) */
#define PNPkeyboard3 "PNP0303" /* IBM Enhanced (101/2 key, PS/2 mouse) */
#define PNPkeyboard4 "PNP0304" /* Nokia 1050 KB Cntlr */
#define PNPkeyboard5 "PNP0305" /* Nokia 9140 KB Cntlr */
#define PNPkeyboard6 "PNP0306" /* Standard Japanese KB Cntlr */
#define PNPkeyboard7 "PNP0307" /* Microsoft Windows (R) KB Cntlr */
/* Parallel port controllers */
#define PNPparallel0 "PNP0400" /* Standard LPT Parallel Port */
#define PNPparallel1 "PNP0401" /* ECP Parallel Port */
#define PNPepp "IBM001C" /* EPP Parallel Port */
/* Serial port controllers */
#define PNPserial0 "PNP0500" /* Standard PC Serial port */
#define PNPSerial1 "PNP0501" /* 16550A Compatible Serial port */
/* Disk controllers */
#define PNPdisk0 "PNP0600" /* Generic ESDI/IDE/ATA Compat HD Cntlr */
#define PNPdisk1 "PNP0601" /* Plus Hardcard II */
#define PNPdisk2 "PNP0602" /* Plus Hardcard IIXL/EZ */
/* Diskette controllers */
#define PNPdiskette0 "PNP0700" /* PC Standard Floppy Disk Controller */
/* Display controllers */
#define PNPdisplay0 "PNP0900" /* VGA Compatible */
#define PNPdisplay1 "PNP0901" /* Video Seven VGA */
#define PNPdisplay2 "PNP0902" /* 8514/A Compatible */
#define PNPdisplay3 "PNP0903" /* Trident VGA */
#define PNPdisplay4 "PNP0904" /* Cirrus Logic Laptop VGA */
#define PNPdisplay5 "PNP0905" /* Cirrus Logic VGA */
#define PNPdisplay6 "PNP0906" /* Tseng ET4000 or ET4000/W32 */
#define PNPdisplay7 "PNP0907" /* Western Digital VGA */
#define PNPdisplay8 "PNP0908" /* Western Digital Laptop VGA */
#define PNPdisplay9 "PNP0909" /* S3 */
#define PNPdisplayA "PNP090A" /* ATI Ultra Pro/Plus (Mach 32) */
#define PNPdisplayB "PNP090B" /* ATI Ultra (Mach 8) */
#define PNPdisplayC "PNP090C" /* XGA Compatible */
#define PNPdisplayD "PNP090D" /* ATI VGA Wonder */
#define PNPdisplayE "PNP090E" /* Weitek P9000 Graphics Adapter */
#define PNPdisplayF "PNP090F" /* Oak Technology VGA */
/* Peripheral busses */
#define PNPbuses0 "PNP0A00" /* ISA Bus */
#define PNPbuses1 "PNP0A01" /* EISA Bus */
#define PNPbuses2 "PNP0A02" /* MCA Bus */
#define PNPbuses3 "PNP0A03" /* PCI Bus */
#define PNPbuses4 "PNP0A04" /* VESA/VL Bus */
/* RTC, BIOS, planar devices */
#define PNPspeaker0 "PNP0800" /* AT Style Speaker Sound */
#define PNPrtc0 "PNP0B00" /* AT RTC */
#define PNPpnpbios0 "PNP0C00" /* PNP BIOS (only created by root enum) */
#define PNPpnpbios1 "PNP0C01" /* System Board Memory Device */
#define PNPpnpbios2 "PNP0C02" /* Math Coprocessor */
#define PNPpnpbios3 "PNP0C03" /* PNP BIOS Event Notification Interrupt */
/* PCMCIA controller */
#define PNPpcmcia0 "PNP0E00" /* Intel 82365 Compatible PCMCIA Cntlr */
/* Mice */
#define PNPmouse0 "PNP0F00" /* Microsoft Bus Mouse */
#define PNPmouse1 "PNP0F01" /* Microsoft Serial Mouse */
#define PNPmouse2 "PNP0F02" /* Microsoft Inport Mouse */
#define PNPmouse3 "PNP0F03" /* Microsoft PS/2 Mouse */
#define PNPmouse4 "PNP0F04" /* Mousesystems Mouse */
#define PNPmouse5 "PNP0F05" /* Mousesystems 3 Button Mouse - COM2 */
#define PNPmouse6 "PNP0F06" /* Genius Mouse - COM1 */
#define PNPmouse7 "PNP0F07" /* Genius Mouse - COM2 */
#define PNPmouse8 "PNP0F08" /* Logitech Serial Mouse */
#define PNPmouse9 "PNP0F09" /* Microsoft Ballpoint Serial Mouse */
#define PNPmouseA "PNP0F0A" /* Microsoft PNP Mouse */
#define PNPmouseB "PNP0F0B" /* Microsoft PNP Ballpoint Mouse */
/* Modems */
#define PNPmodem0 "PNP9000" /* Specific IDs TBD */
/* Network controllers */
#define PNPnetworkC9 "PNP80C9" /* IBM Token Ring */
#define PNPnetworkCA "PNP80CA" /* IBM Token Ring II */
#define PNPnetworkCB "PNP80CB" /* IBM Token Ring II/Short */
#define PNPnetworkCC "PNP80CC" /* IBM Token Ring 4/16Mbs */
#define PNPnetwork27 "PNP8327" /* IBM Token Ring (All types) */
#define PNPnetworket "IBM0010" /* IBM Ethernet used by Power PC */
#define PNPneteisaet "IBM2001" /* IBM Ethernet EISA adapter */
#define PNPAMD79C970 "IBM0016" /* AMD 79C970 (PCI Ethernet) */
/* SCSI controllers */
#define PNPscsi0 "PNPA000" /* Adaptec 154x Compatible SCSI Cntlr */
#define PNPscsi1 "PNPA001" /* Adaptec 174x Compatible SCSI Cntlr */
#define PNPscsi2 "PNPA002" /* Future Domain 16-700 Compat SCSI Cntlr*/
#define PNPscsi3 "PNPA003" /* Panasonic CDROM Adapter (SBPro/SB16) */
#define PNPscsiF "IBM000F" /* NCR 810 SCSI Controller */
#define PNPscsi825 "IBM001B" /* NCR 825 SCSI Controller */
#define PNPscsi875 "IBM0018" /* NCR 875 SCSI Controller */
/* Sound/Video, Multimedia */
#define PNPmm0 "PNPB000" /* Sound Blaster Compatible Sound Device */
#define PNPmm1 "PNPB001" /* MS Windows Sound System Compat Device */
#define PNPmmF "IBM000E" /* Crystal CS4231 Audio Device */
#define PNPv7310 "IBM0015" /* ASCII V7310 Video Capture Device */
#define PNPmm4232 "IBM0017" /* Crystal CS4232 Audio Device */
#define PNPpmsyn "IBM001D" /* YMF 289B chip (Yamaha) */
#define PNPgp4232 "IBM0012" /* Crystal CS4232 Game Port */
#define PNPmidi4232 "IBM0013" /* Crystal CS4232 MIDI */
/* Operator Panel */
#define PNPopctl "IBM000B" /* Operator's panel */
/* Service Processor */
#define PNPsp "IBM0011" /* IBM Service Processor */
#define PNPLTsp "IBM001E" /* Lightning/Terlingua Support Processor */
#define PNPLTmsp "IBM001F" /* Lightning/Terlingua Mini-SP */
/* Memory Controller */
#define PNPmemctl "IBM000A" /* Memory controller */
/* Graphics Assist */
#define PNPg_assist "IBM0014" /* Graphics Assist */
/* Miscellaneous Device Controllers */
#define PNPtablet "IBM0019" /* IBM Tablet Controller */
/* PNP Packet Handles */
#define S1_Packet 0x0A /* Version resource */
#define S2_Packet 0x15 /* Logical DEVID (without flags) */
#define S2_Packet_flags 0x16 /* Logical DEVID (with flags) */
#define S3_Packet 0x1C /* Compatible device ID */
#define S4_Packet 0x22 /* IRQ resource (without flags) */
#define S4_Packet_flags 0x23 /* IRQ resource (with flags) */
#define S5_Packet 0x2A /* DMA resource */
#define S6_Packet 0x30 /* Depend funct start (w/o priority) */
#define S6_Packet_priority 0x31 /* Depend funct start (w/ priority) */
#define S7_Packet 0x38 /* Depend funct end */
#define S8_Packet 0x47 /* I/O port resource (w/o fixed loc) */
#define S9_Packet_fixed 0x4B /* I/O port resource (w/ fixed loc) */
#define S14_Packet 0x71 /* Vendor defined */
#define S15_Packet 0x78 /* End of resource (w/o checksum) */
#define S15_Packet_checksum 0x79 /* End of resource (w/ checksum) */
#define L1_Packet 0x81 /* Memory range */
#define L1_Shadow 0x20 /* Memory is shadowable */
#define L1_32bit_mem 0x18 /* 32-bit memory only */
#define L1_8_16bit_mem 0x10 /* 8- and 16-bit supported */
#define L1_Decode_Hi 0x04 /* decode supports high address */
#define L1_Cache 0x02 /* read cacheable, write-through */
#define L1_Writeable 0x01 /* Memory is writeable */
#define L2_Packet 0x82 /* ANSI ID string */
#define L3_Packet 0x83 /* Unicode ID string */
#define L4_Packet 0x84 /* Vendor defined */
#define L5_Packet 0x85 /* Large I/O */
#define L6_Packet 0x86 /* 32-bit Fixed Loc Mem Range Desc */
#define END_TAG 0x78 /* End of resource */
#define DF_START_TAG 0x30 /* Dependent function start */
#define DF_START_TAG_priority 0x31 /* Dependent function start */
#define DF_END_TAG 0x38 /* Dependent function end */
#define SUBOPTIMAL_CONFIGURATION 0x2 /* Priority byte sub optimal config */
/* Device Base Type Codes */
typedef enum _PnP_BASE_TYPE {
Reserved = 0,
MassStorageDevice = 1,
NetworkInterfaceController = 2,
DisplayController = 3,
MultimediaController = 4,
MemoryController = 5,
BridgeController = 6,
CommunicationsDevice = 7,
SystemPeripheral = 8,
InputDevice = 9,
ServiceProcessor = 0x0A, /* 11/2/95 */
} PnP_BASE_TYPE;
/* Device Sub Type Codes */
typedef enum _PnP_SUB_TYPE {
SCSIController = 0,
IDEController = 1,
FloppyController = 2,
IPIController = 3,
OtherMassStorageController = 0x80,
EthernetController = 0,
TokenRingController = 1,
FDDIController = 2,
OtherNetworkController = 0x80,
VGAController= 0,
SVGAController= 1,
XGAController= 2,
OtherDisplayController = 0x80,
VideoController = 0,
AudioController = 1,
OtherMultimediaController = 0x80,
RAM = 0,
FLASH = 1,
OtherMemoryDevice = 0x80,
HostProcessorBridge = 0,
ISABridge = 1,
EISABridge = 2,
MicroChannelBridge = 3,
PCIBridge = 4,
PCMCIABridge = 5,
VMEBridge = 6,
OtherBridgeDevice = 0x80,
RS232Device = 0,
ATCompatibleParallelPort = 1,
OtherCommunicationsDevice = 0x80,
ProgrammableInterruptController = 0,
DMAController = 1,
SystemTimer = 2,
RealTimeClock = 3,
L2Cache = 4,
NVRAM = 5,
PowerManagement = 6,
CMOS = 7,
OperatorPanel = 8,
ServiceProcessorClass1 = 9,
ServiceProcessorClass2 = 0xA,
ServiceProcessorClass3 = 0xB,
GraphicAssist = 0xC,
SystemPlanar = 0xF, /* 10/5/95 */
OtherSystemPeripheral = 0x80,
KeyboardController = 0,
Digitizer = 1,
MouseController = 2,
TabletController = 3, /* 10/27/95 */
OtherInputController = 0x80,
GeneralMemoryController = 0,
} PnP_SUB_TYPE;
/* Device Interface Type Codes */
typedef enum _PnP_INTERFACE {
General = 0,
GeneralSCSI = 0,
GeneralIDE = 0,
ATACompatible = 1,
GeneralFloppy = 0,
Compatible765 = 1,
NS398_Floppy = 2, /* NS Super I/O wired to use index
register at port 398 and data
register at port 399 */
NS26E_Floppy = 3, /* Ports 26E and 26F */
NS15C_Floppy = 4, /* Ports 15C and 15D */
NS2E_Floppy = 5, /* Ports 2E and 2F */
CHRP_Floppy = 6, /* CHRP Floppy in PR*P system */
GeneralIPI = 0,
GeneralEther = 0,
GeneralToken = 0,
GeneralFDDI = 0,
GeneralVGA = 0,
GeneralSVGA = 0,
GeneralXGA = 0,
GeneralVideo = 0,
GeneralAudio = 0,
CS4232Audio = 1, /* CS 4232 Plug 'n Play Configured */
GeneralRAM = 0,
GeneralFLASH = 0,
PCIMemoryController = 0, /* PCI Config Method */
RS6KMemoryController = 1, /* RS6K Config Method */
GeneralHostBridge = 0,
GeneralISABridge = 0,
GeneralEISABridge = 0,
GeneralMCABridge = 0,
GeneralPCIBridge = 0,
PCIBridgeDirect = 0,
PCIBridgeIndirect = 1,
PCIBridgeRS6K = 2,
GeneralPCMCIABridge = 0,
GeneralVMEBridge = 0,
GeneralRS232 = 0,
COMx = 1,
Compatible16450 = 2,
Compatible16550 = 3,
NS398SerPort = 4, /* NS Super I/O wired to use index
register at port 398 and data
register at port 399 */
NS26ESerPort = 5, /* Ports 26E and 26F */
NS15CSerPort = 6, /* Ports 15C and 15D */
NS2ESerPort = 7, /* Ports 2E and 2F */
GeneralParPort = 0,
LPTx = 1,
NS398ParPort = 2, /* NS Super I/O wired to use index
register at port 398 and data
register at port 399 */
NS26EParPort = 3, /* Ports 26E and 26F */
NS15CParPort = 4, /* Ports 15C and 15D */
NS2EParPort = 5, /* Ports 2E and 2F */
GeneralPIC = 0,
ISA_PIC = 1,
EISA_PIC = 2,
MPIC = 3,
RS6K_PIC = 4,
GeneralDMA = 0,
ISA_DMA = 1,
EISA_DMA = 2,
GeneralTimer = 0,
ISA_Timer = 1,
EISA_Timer = 2,
GeneralRTC = 0,
ISA_RTC = 1,
StoreThruOnly = 1,
StoreInEnabled = 2,
RS6KL2Cache = 3,
IndirectNVRAM = 0, /* Indirectly addressed */
DirectNVRAM = 1, /* Memory Mapped */
IndirectNVRAM24 = 2, /* Indirectly addressed - 24 bit */
GeneralPowerManagement = 0,
EPOWPowerManagement = 1,
PowerControl = 2, /* d1378 */
GeneralCMOS = 0,
GeneralOPPanel = 0,
HarddiskLight = 1,
CDROMLight = 2,
PowerLight = 3,
KeyLock = 4,
ANDisplay = 5, /* AlphaNumeric Display */
SystemStatusLED = 6, /* 3 digit 7 segment LED */
CHRP_SystemStatusLED = 7, /* CHRP LEDs in PR*P system */
GeneralServiceProcessor = 0,
TransferData = 1,
IGMC32 = 2,
IGMC64 = 3,
GeneralSystemPlanar = 0, /* 10/5/95 */
} PnP_INTERFACE;
/* PnP resources */
/* Compressed ASCII is 5 bits per char; 00001=A ... 11010=Z */
typedef struct _SERIAL_ID {
unsigned char VendorID0; /* Bit(7)=0 */
/* Bits(6:2)=1st character in */
/* compressed ASCII */
/* Bits(1:0)=2nd character in */
/* compressed ASCII bits(4:3) */
unsigned char VendorID1; /* Bits(7:5)=2nd character in */
/* compressed ASCII bits(2:0) */
/* Bits(4:0)=3rd character in */
/* compressed ASCII */
unsigned char VendorID2; /* Product number - vendor assigned */
unsigned char VendorID3; /* Product number - vendor assigned */
/* Serial number is to provide uniqueness if more than one board of same */
/* type is in system. Must be "FFFFFFFF" if feature not supported. */
unsigned char Serial0; /* Unique serial number bits (7:0) */
unsigned char Serial1; /* Unique serial number bits (15:8) */
unsigned char Serial2; /* Unique serial number bits (23:16) */
unsigned char Serial3; /* Unique serial number bits (31:24) */
unsigned char Checksum;
} SERIAL_ID;
typedef enum _PnPItemName {
Unused = 0,
PnPVersion = 1,
LogicalDevice = 2,
CompatibleDevice = 3,
IRQFormat = 4,
DMAFormat = 5,
StartDepFunc = 6,
EndDepFunc = 7,
IOPort = 8,
FixedIOPort = 9,
Res1 = 10,
Res2 = 11,
Res3 = 12,
SmallVendorItem = 14,
EndTag = 15,
MemoryRange = 1,
ANSIIdentifier = 2,
UnicodeIdentifier = 3,
LargeVendorItem = 4,
MemoryRange32 = 5,
MemoryRangeFixed32 = 6,
} PnPItemName;
/* Define a bunch of access functions for the bits in the tag field */
/* Tag type - 0 = small; 1 = large */
#define tag_type(t) (((t) & 0x80)>>7)
#define set_tag_type(t,v) (t = (t & 0x7f) | ((v)<<7))
/* Small item name is 4 bits - one of PnPItemName enum above */
#define tag_small_item_name(t) (((t) & 0x78)>>3)
#define set_tag_small_item_name(t,v) (t = (t & 0x07) | ((v)<<3))
/* Small item count is 3 bits - count of further bytes in packet */
#define tag_small_count(t) ((t) & 0x07)
#define set_tag_count(t,v) (t = (t & 0x78) | (v))
/* Large item name is 7 bits - one of PnPItemName enum above */
#define tag_large_item_name(t) ((t) & 0x7f)
#define set_tag_large_item_name(t,v) (t = (t | 0x80) | (v))
/* a PnP resource is a bunch of contiguous TAG packets ending with an end tag */
typedef union _PnP_TAG_PACKET {
struct _S1_Pack{ /* VERSION PACKET */
unsigned char Tag; /* small tag = 0x0a */
unsigned char Version[2]; /* PnP version, Vendor version */
} S1_Pack;
struct _S2_Pack{ /* LOGICAL DEVICE ID PACKET */
unsigned char Tag; /* small tag = 0x15 or 0x16 */
unsigned char DevId[4]; /* Logical device id */
unsigned char Flags[2]; /* bit(0) boot device; */
/* bit(7:1) cmd in range x31-x37 */
/* bit(7:0) cmd in range x28-x3f (opt)*/
} S2_Pack;
struct _S3_Pack{ /* COMPATIBLE DEVICE ID PACKET */
unsigned char Tag; /* small tag = 0x1c */
unsigned char CompatId[4]; /* Compatible device id */
} S3_Pack;
struct _S4_Pack{ /* IRQ PACKET */
unsigned char Tag; /* small tag = 0x22 or 0x23 */
unsigned char IRQMask[2]; /* bit(0) is IRQ0, ...; */
/* bit(0) is IRQ8 ... */
unsigned char IRQInfo; /* optional; assume bit(0)=1; else */
/* bit(0) - high true edge sensitive */
/* bit(1) - low true edge sensitive */
/* bit(2) - high true level sensitive*/
/* bit(3) - low true level sensitive */
/* bit(7:4) - must be 0 */
} S4_Pack;
struct _S5_Pack{ /* DMA PACKET */
unsigned char Tag; /* small tag = 0x2a */
unsigned char DMAMask; /* bit(0) is channel 0 ... */
unsigned char DMAInfo;
} S5_Pack;
struct _S6_Pack{ /* START DEPENDENT FUNCTION PACKET */
unsigned char Tag; /* small tag = 0x30 or 0x31 */
unsigned char Priority; /* Optional; if missing then x01; else*/
/* x00 = best possible */
/* x01 = acceptible */
/* x02 = sub-optimal but functional */
} S6_Pack;
struct _S7_Pack{ /* END DEPENDENT FUNCTION PACKET */
unsigned char Tag; /* small tag = 0x38 */
} S7_Pack;
struct _S8_Pack{ /* VARIABLE I/O PORT PACKET */
unsigned char Tag; /* small tag x47 */
unsigned char IOInfo; /* x0 = decode only bits(9:0); */
#define ISAAddr16bit 0x01 /* x01 = decode bits(15:0) */
unsigned char RangeMin[2]; /* Min base address */
unsigned char RangeMax[2]; /* Max base address */
unsigned char IOAlign; /* base alignmt, incr in 1B blocks */
unsigned char IONum; /* number of contiguous I/O ports */
} S8_Pack;
struct _S9_Pack{ /* FIXED I/O PORT PACKET */
unsigned char Tag; /* small tag = 0x4b */
unsigned char Range[2]; /* base address 10 bits */
unsigned char IONum; /* number of contiguous I/O ports */
} S9_Pack;
struct _S14_Pack{ /* VENDOR DEFINED PACKET */
unsigned char Tag; /* small tag = 0x7m m = 1-7 */
union _S14_Data{
unsigned char Data[7]; /* Vendor defined */
struct _S14_PPCPack{ /* Pr*p s14 pack */
unsigned char Type; /* 00=non-IBM */
unsigned char PPCData[6]; /* Vendor defined */
} S14_PPCPack;
} S14_Data;
} S14_Pack;
struct _S15_Pack{ /* END PACKET */
unsigned char Tag; /* small tag = 0x78 or 0x79 */
unsigned char Check; /* optional - checksum */
} S15_Pack;
struct _L1_Pack{ /* MEMORY RANGE PACKET */
unsigned char Tag; /* large tag = 0x81 */
unsigned char Count0; /* x09 */
unsigned char Count1; /* x00 */
unsigned char Data[9]; /* a variable array of bytes, */
/* count in tag */
} L1_Pack;
struct _L2_Pack{ /* ANSI ID STRING PACKET */
unsigned char Tag; /* large tag = 0x82 */
unsigned char Count0; /* Length of string */
unsigned char Count1;
unsigned char Identifier[1]; /* a variable array of bytes, */
/* count in tag */
} L2_Pack;
struct _L3_Pack{ /* UNICODE ID STRING PACKET */
unsigned char Tag; /* large tag = 0x83 */
unsigned char Count0; /* Length + 2 of string */
unsigned char Count1;
unsigned char Country0; /* TBD */
unsigned char Country1; /* TBD */
unsigned char Identifier[1]; /* a variable array of bytes, */
/* count in tag */
} L3_Pack;
struct _L4_Pack{ /* VENDOR DEFINED PACKET */
unsigned char Tag; /* large tag = 0x84 */
unsigned char Count0;
unsigned char Count1;
union _L4_Data{
unsigned char Data[1]; /* a variable array of bytes, */
/* count in tag */
struct _L4_PPCPack{ /* Pr*p L4 packet */
unsigned char Type; /* 00=non-IBM */
unsigned char PPCData[1]; /* a variable array of bytes, */
/* count in tag */
} L4_PPCPack;
} L4_Data;
} L4_Pack;
struct _L5_Pack{
unsigned char Tag; /* large tag = 0x85 */
unsigned char Count0; /* Count = 17 */
unsigned char Count1;
unsigned char Data[17];
} L5_Pack;
struct _L6_Pack{
unsigned char Tag; /* large tag = 0x86 */
unsigned char Count0; /* Count = 9 */
unsigned char Count1;
unsigned char Data[9];
} L6_Pack;
} PnP_TAG_PACKET;
#endif /* __ASSEMBLY__ */
#endif /* ndef _PNP_ */

246
include/ata.h Normal file
View File

@ -0,0 +1,246 @@
/*
* (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
*/
/*
* Most of the following information was derived from the document
* "Information Technology - AT Attachment-3 Interface (ATA-3)"
* which can be found at:
* http://www.dt.wdc.com/ata/ata-3/ata3r5v.zip
* ftp://poctok.iae.nsk.su/pub/asm/Documents/IDE/ATA3R5V.ZIP
* ftp://ftp.fee.vutbr.cz/pub/doc/io/ata/ata-3/ata3r5v.zip
*/
#ifndef _ATA_H
#define _ATA_H
/* Register addressing depends on the hardware design; for instance,
* 8-bit (register) and 16-bit (data) accesses might use different
* address spaces. This is implemented by the following definitions.
*/
#define ATA_IO_DATA(x) (CFG_ATA_DATA_OFFSET+(x))
#define ATA_IO_REG(x) (CFG_ATA_REG_OFFSET +(x))
#define ATA_IO_ALT(x) (CFG_ATA_ALT_OFFSET +(x))
/*
* I/O Register Descriptions
*/
#define ATA_DATA_REG ATA_IO_DATA(0)
#define ATA_ERROR_REG ATA_IO_REG(1)
#define ATA_SECT_CNT ATA_IO_REG(2)
#define ATA_SECT_NUM ATA_IO_REG(3)
#define ATA_CYL_LOW ATA_IO_REG(4)
#define ATA_CYL_HIGH ATA_IO_REG(5)
#define ATA_DEV_HD ATA_IO_REG(6)
#define ATA_COMMAND ATA_IO_REG(7)
#define ATA_STATUS ATA_COMMAND
#define ATA_DEV_CTL ATA_IO_ALT(6)
#define ATA_LBA_LOW ATA_SECT_NUM
#define ATA_LBA_MID ATA_CYL_LOW
#define ATA_LBA_HIGH ATA_CYL_HIGH
#define ATA_LBA_SEL ATA_DEV_CTL
/*
* Status register bits
*/
#define ATA_STAT_BUSY 0x80 /* Device Busy */
#define ATA_STAT_READY 0x40 /* Device Ready */
#define ATA_STAT_FAULT 0x20 /* Device Fault */
#define ATA_STAT_SEEK 0x10 /* Device Seek Complete */
#define ATA_STAT_DRQ 0x08 /* Data Request (ready) */
#define ATA_STAT_CORR 0x04 /* Corrected Data Error */
#define ATA_STAT_INDEX 0x02 /* Vendor specific */
#define ATA_STAT_ERR 0x01 /* Error */
/*
* Device / Head Register Bits
*/
#define ATA_DEVICE(x) ((x & 1)<<4)
#define ATA_LBA 0xE0
/*
* ATA Commands (only mandatory commands listed here)
*/
#define ATA_CMD_READ 0x20 /* Read Sectors (with retries) */
#define ATA_CMD_READN 0x21 /* Read Sectors ( no retries) */
#define ATA_CMD_WRITE 0x30 /* Write Sectores (with retries)*/
#define ATA_CMD_WRITEN 0x31 /* Write Sectors ( no retries)*/
#define ATA_CMD_VRFY 0x40 /* Read Verify (with retries) */
#define ATA_CMD_VRFYN 0x41 /* Read verify ( no retries) */
#define ATA_CMD_SEEK 0x70 /* Seek */
#define ATA_CMD_DIAG 0x90 /* Execute Device Diagnostic */
#define ATA_CMD_INIT 0x91 /* Initialize Device Parameters */
#define ATA_CMD_RD_MULT 0xC4 /* Read Multiple */
#define ATA_CMD_WR_MULT 0xC5 /* Write Multiple */
#define ATA_CMD_SETMULT 0xC6 /* Set Multiple Mode */
#define ATA_CMD_RD_DMA 0xC8 /* Read DMA (with retries) */
#define ATA_CMD_RD_DMAN 0xC9 /* Read DMS ( no retries) */
#define ATA_CMD_WR_DMA 0xCA /* Write DMA (with retries) */
#define ATA_CMD_WR_DMAN 0xCB /* Write DMA ( no retires) */
#define ATA_CMD_IDENT 0xEC /* Identify Device */
#define ATA_CMD_SETF 0xEF /* Set Features */
#define ATA_CMD_CHK_PWR 0xE5 /* Check Power Mode */
/*
* ATAPI Commands
*/
#define ATAPI_CMD_IDENT 0xA1 /* Identify AT Atachment Packed Interface Device */
#define ATAPI_CMD_PACKET 0xA0 /* Packed Command */
#define ATAPI_CMD_INQUIRY 0x12
#define ATAPI_CMD_REQ_SENSE 0x03
#define ATAPI_CMD_READ_CAP 0x25
#define ATAPI_CMD_START_STOP 0x1B
#define ATAPI_CMD_READ_12 0xA8
#define ATA_GET_ERR() inb(ATA_STATUS)
#define ATA_GET_STAT() inb(ATA_STATUS)
#define ATA_OK_STAT(stat,good,bad) (((stat)&((good)|(bad)))==(good))
#define ATA_BAD_R_STAT (ATA_STAT_BUSY | ATA_STAT_ERR)
#define ATA_BAD_W_STAT (ATA_BAD_R_STAT | ATA_STAT_FAULT)
#define ATA_BAD_STAT (ATA_BAD_R_STAT | ATA_STAT_DRQ)
#define ATA_DRIVE_READY (ATA_READY_STAT | ATA_STAT_SEEK)
#define ATA_DATA_READY (ATA_STAT_DRQ)
#define ATA_BLOCKSIZE 512 /* bytes */
#define ATA_BLOCKSHIFT 9 /* 2 ^ ATA_BLOCKSIZESHIFT = 512 */
#define ATA_SECTORWORDS (512 / sizeof(unsigned long))
#ifndef ATA_RESET_TIME
#define ATA_RESET_TIME 60 /* spec allows up to 31 seconds */
#endif
/* ------------------------------------------------------------------------- */
/*
* structure returned by ATA_CMD_IDENT, as per ANSI ATA2 rev.2f spec
*/
typedef struct hd_driveid {
unsigned short config; /* lots of obsolete bit flags */
unsigned short cyls; /* "physical" cyls */
unsigned short reserved2; /* reserved (word 2) */
unsigned short heads; /* "physical" heads */
unsigned short track_bytes; /* unformatted bytes per track */
unsigned short sector_bytes; /* unformatted bytes per sector */
unsigned short sectors; /* "physical" sectors per track */
unsigned short vendor0; /* vendor unique */
unsigned short vendor1; /* vendor unique */
unsigned short vendor2; /* vendor unique */
unsigned char serial_no[20]; /* 0 = not_specified */
unsigned short buf_type;
unsigned short buf_size; /* 512 byte increments; 0 = not_specified */
unsigned short ecc_bytes; /* for r/w long cmds; 0 = not_specified */
unsigned char fw_rev[8]; /* 0 = not_specified */
unsigned char model[40]; /* 0 = not_specified */
unsigned char max_multsect; /* 0=not_implemented */
unsigned char vendor3; /* vendor unique */
unsigned short dword_io; /* 0=not_implemented; 1=implemented */
unsigned char vendor4; /* vendor unique */
unsigned char capability; /* bits 0:DMA 1:LBA 2:IORDYsw 3:IORDYsup*/
unsigned short reserved50; /* reserved (word 50) */
unsigned char vendor5; /* vendor unique */
unsigned char tPIO; /* 0=slow, 1=medium, 2=fast */
unsigned char vendor6; /* vendor unique */
unsigned char tDMA; /* 0=slow, 1=medium, 2=fast */
unsigned short field_valid; /* bits 0:cur_ok 1:eide_ok */
unsigned short cur_cyls; /* logical cylinders */
unsigned short cur_heads; /* logical heads */
unsigned short cur_sectors; /* logical sectors per track */
unsigned short cur_capacity0; /* logical total sectors on drive */
unsigned short cur_capacity1; /* (2 words, misaligned int) */
unsigned char multsect; /* current multiple sector count */
unsigned char multsect_valid; /* when (bit0==1) multsect is ok */
unsigned int lba_capacity; /* total number of sectors */
unsigned short dma_1word; /* single-word dma info */
unsigned short dma_mword; /* multiple-word dma info */
unsigned short eide_pio_modes; /* bits 0:mode3 1:mode4 */
unsigned short eide_dma_min; /* min mword dma cycle time (ns) */
unsigned short eide_dma_time; /* recommended mword dma cycle time (ns) */
unsigned short eide_pio; /* min cycle time (ns), no IORDY */
unsigned short eide_pio_iordy; /* min cycle time (ns), with IORDY */
unsigned short words69_70[2]; /* reserved words 69-70 */
unsigned short words71_74[4]; /* reserved words 71-74 */
unsigned short queue_depth; /* */
unsigned short words76_79[4]; /* reserved words 76-79 */
unsigned short major_rev_num; /* */
unsigned short minor_rev_num; /* */
unsigned short command_set_1; /* bits 0:Smart 1:Security 2:Removable 3:PM */
unsigned short command_set_2; /* bits 14:Smart Enabled 13:0 zero */
unsigned short cfsse; /* command set-feature supported extensions */
unsigned short cfs_enable_1; /* command set-feature enabled */
unsigned short cfs_enable_2; /* command set-feature enabled */
unsigned short csf_default; /* command set-feature default */
unsigned short dma_ultra; /* */
unsigned short word89; /* reserved (word 89) */
unsigned short word90; /* reserved (word 90) */
unsigned short CurAPMvalues; /* current APM values */
unsigned short word92; /* reserved (word 92) */
unsigned short hw_config; /* hardware config */
unsigned short words94_125[32];/* reserved words 94-125 */
unsigned short last_lun; /* reserved (word 126) */
unsigned short word127; /* reserved (word 127) */
unsigned short dlf; /* device lock function
* 15:9 reserved
* 8 security level 1:max 0:high
* 7:6 reserved
* 5 enhanced erase
* 4 expire
* 3 frozen
* 2 locked
* 1 en/disabled
* 0 capability
*/
unsigned short csfo; /* current set features options
* 15:4 reserved
* 3 auto reassign
* 2 reverting
* 1 read-look-ahead
* 0 write cache
*/
unsigned short words130_155[26];/* reserved vendor words 130-155 */
unsigned short word156;
unsigned short words157_159[3];/* reserved vendor words 157-159 */
unsigned short words160_255[95];/* reserved words 160-255 */
} hd_driveid_t;
/*
* PIO Mode Configuration
*
* See ATA-3 (AT Attachment-3 Interface) documentation, Figure 14 / Table 21
*/
typedef struct {
unsigned int t_setup; /* Setup Time in [ns] or clocks */
unsigned int t_length; /* Length Time in [ns] or clocks */
unsigned int t_hold; /* Hold Time in [ns] or clocks */
}
pio_config_t;
#define IDE_MAX_PIO_MODE 4 /* max suppurted PIO mode */
/* ------------------------------------------------------------------------- */
#endif /* _ATA_H */

1593
include/commproc.h Normal file

File diff suppressed because it is too large Load Diff

246
include/configs/ML2.h Normal file
View File

@ -0,0 +1,246 @@
/*
* ML2.h: ML2 specific config options
*
* Copyright 2002 Mind NV
*
* http://www.mind.be/
*
* Author : Peter De Schrijver (p2@mind.be)
*
* Derived from : other configuration header 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.
*
*/
#ifndef __CONFIG_H
#define __CONFIG_H
/*
* High Level Configuration Options
* (easy to change)
*/
#define CONFIG_405 1 /* This is a PPC405 CPU */
#define CONFIG_4xx 1 /* ...member of PPC4xx family */
#define CONFIG_ML2 1 /* ...on a ML2 board */
#define CFG_ENV_IS_IN_FLASH 1
#ifdef CFG_ENV_IS_IN_NVRAM
#undef CFG_ENV_IS_IN_FLASH
#else
#ifdef CFG_ENV_IS_IN_FLASH
#undef CFG_ENV_IS_IN_NVRAM
#endif
#endif
#define CONFIG_BAUDRATE 9600
#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
#if 1
#define CONFIG_BOOTCOMMAND "bootm" /* autoboot command */
#else
#define CONFIG_BOOTCOMMAND "bootp" /* autoboot command */
#endif
#define CONFIG_PREBOOT "fsload 0x00100000 /boot/image"
/* Size (bytes) of interrupt driven serial port buffer.
* Set to 0 to use polling instead of interrupts.
* Setting to 0 will also disable RTS/CTS handshaking.
*/
#if 0
#define CONFIG_SERIAL_SOFTWARE_FIFO 4000
#else
#undef CONFIG_SERIAL_SOFTWARE_FIFO
#endif
#if 0
#define CONFIG_BOOTARGS "root=/dev/nfs " \
"ip=192.168.2.176:192.168.2.190:192.168.2.79:255.255.255.0 " \
"nfsroot=192.168.2.190:/home/stefan/cpci405/target_ftest4"
#else
#define CONFIG_BOOTARGS "root=/dev/mtdblock2 " \
"console=ttyS0 console=tty"
#endif
#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */
#define CONFIG_COMMANDS ( (CONFIG_CMD_DFL & (~CFG_CMD_NET) & \
(~CFG_CMD_RTC) & ~(CFG_CMD_PCI) & ~(CFG_CMD_I2C)) | \
CFG_CMD_IRQ | \
CFG_CMD_KGDB | \
CFG_CMD_BEDBUG | \
CFG_CMD_ELF | CFG_CMD_JFFS2 )
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
#undef CONFIG_WATCHDOG /* watchdog disabled */
#define CONFIG_SYS_CLK_FREQ 50000000
#define CONFIG_SPD_EEPROM 1 /* use SPD EEPROM for setup */
/*
* Miscellaneous configurable options
*/
#define CFG_LONGHELP /* undef to save memory */
#define CFG_PROMPT "=> " /* Monitor Command Prompt */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
#else
#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
#endif
#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
#define CFG_MAXARGS 16 /* max number of command args */
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
#define CFG_MEMTEST_START 0x0400000 /* memtest works on */
#define CFG_MEMTEST_END 0x0C00000 /* 4 ... 12 MB in DRAM */
/*
* If CFG_EXT_SERIAL_CLOCK, then the UART divisor is 1.
* If CFG_405_UART_ERRATA_59, then UART divisor is 31.
* Otherwise, UART divisor is determined by CPU Clock and CFG_BASE_BAUD value.
* The Linux BASE_BAUD define should match this configuration.
* baseBaud = cpuClock/(uartDivisor*16)
* If CFG_405_UART_ERRATA_59 and 200MHz CPU clock,
* set Linux BASE_BAUD to 403200.
*/
#undef CFG_EXT_SERIAL_CLOCK /* external serial clock */
#undef CFG_405_UART_ERRATA_59 /* 405GP/CR Rev. D silicon */
#define CFG_BASE_BAUD (3125000*16)
#define CFG_NS16550_CLK CFG_BASE_BAUD
#define CFG_DUART_CHAN 0
#define CFG_NS16550_COM1 0xa0001003
#define CFG_NS16550_COM2 0xa0011003
#define CFG_NS16550_REG_SIZE -4
#define CFG_NS16550 1
#define CFG_INIT_CHAN1 1
#define CFG_INIT_CHAN2 1
/* The following table includes the supported baudrates */
#define CFG_BAUDRATE_TABLE \
{300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400}
#define CFG_LOAD_ADDR 0x100000 /* default load address */
#define CFG_EXTBDINFO 1 /* To use extended board_into (bd_t) */
#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
/*-----------------------------------------------------------------------
* Start addresses for the final memory configuration
* (Set up by the startup code)
* Please note that CFG_SDRAM_BASE _must_ start at 0
*/
#define CFG_SDRAM_BASE 0x00000000
#define CFG_FLASH_BASE 0x18000000
#define CFG_MONITOR_BASE CFG_FLASH_BASE
#define CFG_MONITOR_LEN (192 * 1024) /* Reserve 196 kB for Monitor */
#define CFG_MALLOC_LEN (128 * 1024) /* Reserve 128 kB for malloc() */
/*
* For booting Linux, the board info and command line data
* have to be in the first 8 MB of memory, since this is
* the maximum mapped by the Linux kernel during initialization.
*/
#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
/*-----------------------------------------------------------------------
* FLASH organization
*/
#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
#define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip */
#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
/* BEG ENVIRONNEMENT FLASH */
#ifdef CFG_ENV_IS_IN_FLASH
#define CFG_ENV_OFFSET 0x00050000 /* Offset of Environment Sector */
#define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
#define CFG_ENV_SECT_SIZE 0x10000 /* see README - env sector total size */
#endif
/* END ENVIRONNEMENT FLASH */
/*-----------------------------------------------------------------------
* NVRAM organization
*/
#define CFG_NVRAM_BASE_ADDR 0xf0000000 /* NVRAM base address */
#define CFG_NVRAM_SIZE 0x1ff8 /* NVRAM size */
#ifdef CFG_ENV_IS_IN_NVRAM
#define CFG_ENV_SIZE 0x1000 /* Size of Environment vars */
#define CFG_ENV_ADDR \
(CFG_NVRAM_BASE_ADDR+CFG_NVRAM_SIZE-CFG_ENV_SIZE) /* Env */
#endif
/*-----------------------------------------------------------------------
* Cache Configuration
*/
#define CFG_DCACHE_SIZE 8192 /* For IBM 405 CPUs */
#define CFG_CACHELINE_SIZE 32 /* ... */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
#endif
/*
* Init Memory Controller:
*
* BR0/1 and OR0/1 (FLASH)
*/
#define FLASH_BASE0_PRELIM CFG_FLASH_BASE /* FLASH bank #0 */
#define FLASH_BASE1_PRELIM 0 /* FLASH bank #1 */
/* Configuration Port location */
#define CONFIG_PORT_ADDR 0xF0000500
/*-----------------------------------------------------------------------
* Definitions for initial stack pointer and data area (in DPRAM)
*/
#define CFG_INIT_RAM_ADDR 0x800000 /* inside of SDRAM */
#define CFG_INIT_RAM_END 0x2000 /* End of used area in RAM */
#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
/*-----------------------------------------------------------------------
* Definitions for Serial Presence Detect EEPROM address
* (to get SDRAM settings)
*/
#define SPD_EEPROM_ADDRESS 0x50
/*
* Internal Definitions
*
* Boot Flags
*/
#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
#define BOOTFLAG_WARM 0x02 /* Software reboot */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */
#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */
#endif
/* JFFS2 stuff */
#define CFG_JFFS2_FIRST_BANK 0
#define CFG_JFFS2_NUM_BANKS 1
#define CFG_JFFS2_FIRST_SECTOR 1
#endif /* __CONFIG_H */

332
include/configs/MOUSSE.h Normal file
View File

@ -0,0 +1,332 @@
/*
* (C) Copyright 2000, 2001
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2001
* James F. Dougherty (jfd@cs.stanford.edu)
*
* 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
*/
/*
*
* Configuration settings for the MOUSSE board.
* See also: http://www.vooha.com/
*
*/
/* ------------------------------------------------------------------------- */
/*
* board/config.h - configuration options, board specific
*/
#ifndef __CONFIG_H
#define __CONFIG_H
/*
* High Level Configuration Options
* (easy to change)
*/
#define CONFIG_MPC824X 1
#define CONFIG_MPC8240 1
#define CONFIG_MOUSSE 1
#define CFG_ADDR_MAP_B 1
#define CONFIG_CONS_INDEX 1
#define CONFIG_BAUDRATE 9600
#if 1
#define CONFIG_BOOTCOMMAND "tftp 100000 vmlinux.img;bootm" /* autoboot command */
#else
#define CONFIG_BOOTCOMMAND "bootm ffe10000"
#endif
#define CONFIG_BOOTARGS "console=ttyS0 root=/dev/nfs rw nfsroot=209.128.93.133:/boot nfsaddrs=209.128.93.133:209.128.93.138"
#define CONFIG_BOOTDELAY 3
#define CONFIG_COMMANDS (CONFIG_CMD_DFL|CFG_CMD_ASKENV|CFG_CMD_DATE)
#define CONFIG_ENV_OVERWRITE 1
#define CONFIG_ETH_ADDR "00:10:18:10:00:06"
#define CONFIG_DOS_PARTITION 1 /* MSDOS bootable partitiion support */
/* This must be included AFTER the definition of CONFIG_COMMANDS (if any)
*/
#include <cmd_confdefs.h>
#include "../board/mousse/mousse.h"
/*
* Miscellaneous configurable options
*/
#undef CFG_LONGHELP /* undef to save memory */
#define CFG_PROMPT "=>" /* Monitor Command Prompt */
#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16)
#define CFG_MAXARGS 8 /* Max number of command args */
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
#define CFG_LOAD_ADDR 0x00100000 /* Default load address */
/*-----------------------------------------------------------------------
* Start addresses for the final memory configuration
* (Set up by the startup code)
* Please note that CFG_SDRAM_BASE _must_ start at 0
*/
#define CFG_SDRAM_BASE 0x00000000
#ifdef DEBUG
#define CFG_MONITOR_BASE CFG_SDRAM_BASE
#else
#define CFG_MONITOR_BASE CFG_FLASH_BASE
#endif
#ifdef DEBUG
#define CFG_MONITOR_LEN (4 << 20) /* lots of mem ... */
#else
#define CFG_MONITOR_LEN (512 << 10) /* 512K PLCC bootrom */
#endif
#define CFG_MALLOC_LEN (2*(4096 << 10)) /* 2*4096kB for malloc() */
#define CFG_MEMTEST_START 0x00004000 /* memtest works on */
#define CFG_MEMTEST_END 0x02000000 /* 0 ... 32 MB in DRAM */
#define CFG_EUMB_ADDR 0xFC000000
#define CFG_ISA_MEM 0xFD000000
#define CFG_ISA_IO 0xFE000000
#define CFG_FLASH_BASE 0xFFF00000
#define CFG_FLASH_SIZE ((uint)(512 * 1024))
#define CFG_RESET_ADDRESS 0xFFF00100
#define FLASH_BASE0_PRELIM 0xFFF00000 /* 512K PLCC FLASH/AM29F040*/
#define FLASH_BASE0_SIZE 0x80000 /* 512K */
#define FLASH_BASE1_PRELIM 0xFFE10000 /* AMD 29LV160DB
1MB - 64K FLASH0 SEG =960K
(size=0xf0000)*/
#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
/*
* NS16550 Configuration
*/
#define CFG_NS16550
#define CFG_NS16550_SERIAL
#define CFG_NS16550_REG_SIZE 1
#define CFG_NS16550_CLK 18432000
#define CFG_NS16550_COM1 0xFFE08080
/*-----------------------------------------------------------------------
* Definitions for initial stack pointer and data area (in DPRAM)
*/
#define CFG_INIT_RAM_ADDR CFG_SDRAM_BASE + CFG_MONITOR_LEN
#define CFG_INIT_RAM_END 0x2F00 /* End of used area in DPRAM */
#define CFG_GBL_DATA_SIZE 64 /* size in bytes reserved for initial data */
#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
/*
* Low Level Configuration Settings
* (address mappings, register initial values, etc.)
* You should know what you are doing if you make changes here.
* For the detail description refer to the MPC8240 user's manual.
*/
#define CONFIG_SYS_CLK_FREQ 33000000 /* external frequency to pll */
#define CONFIG_PLL_PCI_TO_MEM_MULTIPLIER 2
#define CFG_HZ 1000
#define CFG_ETH_DEV_FN 0x00
#define CFG_ETH_IOBASE 0x00104000
/* Bit-field values for MCCR1.
*/
#define CFG_ROMNAL 8
#define CFG_ROMFAL 8
/* Bit-field values for MCCR2.
*/
#define CFG_REFINT 0xf5 /* Refresh interval */
/* Burst To Precharge. Bits of this value go to MCCR3 and MCCR4.
*/
#define CFG_BSTOPRE 0x79
#ifdef INCLUDE_ECC
#define USE_ECC 1
#else /* INCLUDE_ECC */
#define USE_ECC 0
#endif /* INCLUDE_ECC */
/* Bit-field values for MCCR3.
*/
#define CFG_REFREC 8 /* Refresh to activate interval */
#define CFG_RDLAT (4+USE_ECC) /* Data latancy from read command */
/* Bit-field values for MCCR4.
*/
#define CFG_PRETOACT 3 /* Precharge to activate interval */
#define CFG_ACTTOPRE 5 /* Activate to Precharge interval */
#define CFG_SDMODE_CAS_LAT 3 /* SDMODE CAS latancy */
#define CFG_SDMODE_WRAP 0 /* SDMODE wrap type */
#define CFG_SDMODE_BURSTLEN 2 /* SDMODE Burst length */
#define CFG_ACTORW 2
#define CFG_REGISTERD_TYPE_BUFFER (1-USE_ECC)
/* Memory bank settings.
* Only bits 20-29 are actually used from these vales to set the
* start/end addresses. The upper two bits will always be 0, and the lower
* 20 bits will be 0x00000 for a start address, or 0xfffff for an end
* address. Refer to the MPC8240 book.
*/
#define CFG_RAM_SIZE 0x04000000 /* 64MB */
#define CFG_BANK0_START 0x00000000
#define CFG_BANK0_END (CFG_RAM_SIZE - 1)
#define CFG_BANK0_ENABLE 1
#define CFG_BANK1_START 0x3ff00000
#define CFG_BANK1_END 0x3fffffff
#define CFG_BANK1_ENABLE 0
#define CFG_BANK2_START 0x3ff00000
#define CFG_BANK2_END 0x3fffffff
#define CFG_BANK2_ENABLE 0
#define CFG_BANK3_START 0x3ff00000
#define CFG_BANK3_END 0x3fffffff
#define CFG_BANK3_ENABLE 0
#define CFG_BANK4_START 0x3ff00000
#define CFG_BANK4_END 0x3fffffff
#define CFG_BANK4_ENABLE 0
#define CFG_BANK5_START 0x3ff00000
#define CFG_BANK5_END 0x3fffffff
#define CFG_BANK5_ENABLE 0
#define CFG_BANK6_START 0x3ff00000
#define CFG_BANK6_END 0x3fffffff
#define CFG_BANK6_ENABLE 0
#define CFG_BANK7_START 0x3ff00000
#define CFG_BANK7_END 0x3fffffff
#define CFG_BANK7_ENABLE 0
#define CFG_ODCR 0x7f
#define CFG_PGMAX 0x32 /* how long the 8240 reatins the currently accessed page in memory
see 8240 book for details*/
#define PCI_MEM_SPACE1_START 0x80000000
#define PCI_MEM_SPACE2_START 0xfd000000
/* IBAT/DBAT Configuration */
/* Ram: 64MB, starts at address-0, r/w instruction/data */
#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_64M | BATU_VS | BATU_VP)
#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
#define CFG_DBAT0U CFG_IBAT0U
#define CFG_DBAT0L CFG_IBAT0L
/* MPLD/Port-X I/O Space : data and instruction read/write, cache-inhibit */
#define CFG_IBAT1U (PORTX_DEV_BASE | BATU_BL_128M | BATU_VS | BATU_VP)
#if 0
#define CFG_IBAT1L (PORTX_DEV_BASE | BATL_PP_10 | BATL_MEMCOHERENCE |\
BATL_WRITETHROUGH | BATL_CACHEINHIBIT)
#else
#define CFG_IBAT1L (PORTX_DEV_BASE | BATL_PP_10 |BATL_CACHEINHIBIT)
#endif
#define CFG_DBAT1U CFG_IBAT1U
#define CFG_DBAT1L CFG_IBAT1L
/* PCI Memory region 1: 0x8XXX_XXXX PCI Mem space: EUMBAR, etc - 16MB */
#define CFG_IBAT2U (PCI_MEM_SPACE1_START|BATU_BL_16M | BATU_VS | BATU_VP)
#define CFG_IBAT2L (PCI_MEM_SPACE1_START|BATL_PP_10 | BATL_GUARDEDSTORAGE|BATL_CACHEINHIBIT)
#define CFG_DBAT2U CFG_IBAT2U
#define CFG_DBAT2L CFG_IBAT2L
/* PCI Memory region 2: PCI Devices in 0xFD space */
#define CFG_IBAT3U (PCI_MEM_SPACE2_START|BATU_BL_16M | BATU_VS | BATU_VP)
#define CFG_IBAT3L (PCI_MEM_SPACE2_START|BATL_PP_10 | BATL_GUARDEDSTORAGE | BATL_CACHEINHIBIT)
#define CFG_DBAT3U CFG_IBAT3U
#define CFG_DBAT3L CFG_IBAT3L
/*
* For booting Linux, the board info and command line data
* have to be in the first 8 MB of memory, since this is
* the maximum mapped by the Linux kernel during initialization.
*/
#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
/*-----------------------------------------------------------------------
* FLASH organization
*/
#define CFG_MAX_FLASH_BANKS 3 /* Max number of flash banks */
#define CFG_MAX_FLASH_SECT 64 /* Max number of sectors in one bank */
#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
#if 0
#define CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_OFFSET 0x8000 /* Offset of the Environment Sector */
#define CFG_ENV_SIZE 0x4000 /* Size of the Environment Sector */
#else
#define CFG_ENV_IS_IN_NVRAM 1
#define CFG_ENV_ADDR NV_OFF_U_BOOT_ADDR /* PortX NVM Free addr*/
#define CFG_ENV_OFFSET CFG_ENV_ADDR
#define CFG_ENV_SIZE NV_U_BOOT_ENV_SIZE /* 2K */
#endif
/*-----------------------------------------------------------------------
* Cache Configuration
*/
#define CFG_CACHELINE_SIZE 16
/*
* Internal Definitions
*
* Boot Flags
*/
#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
#define BOOTFLAG_WARM 0x02 /* Software reboot */
/* Localizations */
#if 0
#define CONFIG_ETHADDR 0:0:0:0:1:d
#define CONFIG_IPADDR 172.16.40.113
#define CONFIG_SERVERIP 172.16.40.111
#else
#define CONFIG_ETHADDR 0:0:0:0:1:d
#define CONFIG_IPADDR 209.128.93.138
#define CONFIG_SERVERIP 209.128.93.133
#endif
/*-----------------------------------------------------------------------
* PCI stuff
*-----------------------------------------------------------------------
*/
#define CONFIG_PCI /* include pci support */
#undef CONFIG_PCI_PNP
#define CONFIG_NET_MULTI /* Multi ethernet cards support */
#define CONFIG_TULIP
#endif /* __CONFIG_H */

213
include/configs/csb226.h Normal file
View File

@ -0,0 +1,213 @@
/*
* (C) Copyright 2000, 2001, 2002
* Robert Schwebel, Pengutronix, r.schwebel@pengutronix.de.
*
* Configuration for the Cogent CSB226 board. For details see
* http://www.cogcomp.com/csb_csb226.htm
*
* 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/configs/csb226.h - configuration options, board specific
*/
#ifndef __CONFIG_H
#define __CONFIG_H
/*
* If we are developing, we might want to start U-Boot from ram
* so we MUST NOT initialize critical regs like mem-timing ...
*/
#define CONFIG_INIT_CRITICAL /* undef for developing */
/*
* High Level Configuration Options
* (easy to change)
*/
#define CONFIG_PXA250 1 /* This is an PXA250 CPU */
#define CONFIG_CSB226 1 /* on a CSB226 board */
#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
/* for timer/console/ethernet */
/*
* Hardware drivers
*/
/*
* select serial console configuration
*/
#define CONFIG_FFUART 1 /* we use FFUART on CSB226 */
/* allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE
#define CONFIG_BAUDRATE 19200
#define CONFIG_COMMANDS (CONFIG_CMD_DFL & ~CFG_CMD_NET)
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
#define CONFIG_BOOTDELAY 10
#define CONFIG_BOOTARGS "root=ramfs devfs=mount console=ttySA0,115200"
#define CONFIG_ETHADDR FF:FF:FF:FF:FF:FF
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.1.56
#define CONFIG_SERVERIP 192.168.1.2
#define CONFIG_BOOTCOMMAND ""
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */
#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */
#endif
/*
* Miscellaneous configurable options
*/
/*
* Size of malloc() pool; this lives below the uppermost 128 KiB which are
* used for the RAM copy of the uboot code
*
*/
#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024)
#define CFG_LONGHELP /* undef to save memory */
#define CFG_PROMPT "=> " /* Monitor Command Prompt */
#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
#define CFG_MAXARGS 16 /* max number of command args */
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
#define CFG_MEMTEST_START 0xa0400000 /* memtest works on */
#define CFG_MEMTEST_END 0xa0800000 /* 4 ... 8 MB in DRAM */
#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */
#define CFG_LOAD_ADDR 0xa7fe0000 /* default load address */
/* RS: where is this documented? */
/* RS: is this where U-Boot is */
/* RS: relocated to in RAM? */
#define CFG_HZ 3686400 /* incrementer freq: 3.6864 MHz */
/* RS: the oscillator is actually 3680130?? */
#define CFG_CPUSPEED 0x141 /* set core clock to 200/200/100 MHz */
/* 0101000001 */
/* ^^^^^ Memory Speed 99.53 MHz */
/* ^^ Run Mode Speed = 2x Mem Speed */
/* ^^ Turbo Mode Sp. = 1x Run M. Sp. */
#define CFG_MONITOR_LEN 0x20000 /* 128 KiB */
/* valid baudrates */
#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
/*
* Stack sizes
*
* The stack sizes are set up in start.S using the settings below
*/
#define CONFIG_STACKSIZE (128*1024) /* regular stack */
#ifdef CONFIG_USE_IRQ
#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
#endif
/*
* Physical Memory Map
*/
#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
#define PHYS_SDRAM_1 0xa0000000 /* SDRAM Bank #1 */
#define PHYS_SDRAM_1_SIZE 0x02000000 /* 32 MB */
#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */
#define PHYS_FLASH_SIZE 0x02000000 /* 32 MB */
#define CFG_DRAM_BASE 0xa0000000 /* RAM starts here */
#define CFG_DRAM_SIZE 0x02000000
#define CFG_FLASH_BASE PHYS_FLASH_1
/*
* GPIO settings
*/
#define CFG_GPSR0_VAL 0xFFFFFFFF
#define CFG_GPSR1_VAL 0xFFFFFFFF
#define CFG_GPSR2_VAL 0xFFFFFFFF
#define CFG_GPCR0_VAL 0x08022080
#define CFG_GPCR1_VAL 0x00000000
#define CFG_GPCR2_VAL 0x00000000
#define CFG_GPDR0_VAL 0xCD82A858
#define CFG_GPDR1_VAL 0xFCFFAB80
#define CFG_GPDR2_VAL 0x0001FFFF
#define CFG_GAFR0_L_VAL 0x80000000
#define CFG_GAFR0_U_VAL 0xA5254010
#define CFG_GAFR1_L_VAL 0x599A9550
#define CFG_GAFR1_U_VAL 0xAAA5AAAA
#define CFG_GAFR2_L_VAL 0xAAAAAAAA
#define CFG_GAFR2_U_VAL 0x00000002
/* FIXME: set GPIO_RER/FER */
#define CFG_PSSR_VAL 0x20
/*
* Memory settings
*/
#define CFG_MSC0_VAL 0x2EF025D0
#define CFG_MSC1_VAL 0x00003F64
#define CFG_MSC2_VAL 0x00000000
#define CFG_MDCNFG_VAL 0x09a909a9
#define CFG_MDREFR_VAL 0x03ca0030
/* #define CFG_MDREFR_VAL_100 ??? */
#define CFG_MDMRS_VAL 0x00220022
/*
* PCMCIA and CF Interfaces
*/
#define CFG_MECR_VAL 0x00000000
#define CFG_MCMEM0_VAL 0x00000000
#define CFG_MCMEM1_VAL 0x00000000
#define CFG_MCATT0_VAL 0x00000000
#define CFG_MCATT1_VAL 0x00000000
#define CFG_MCIO0_VAL 0x00000000
#define CFG_MCIO1_VAL 0x00000000
/*
#define _LED 0x08000010
#define LED_BLANK (0x08000040)
*/
/*
* FLASH and environment organization
*/
#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
#define CFG_MAX_FLASH_SECT 128 /* max number of sect. on one chip */
/* timeout values are in ticks */
#define CFG_FLASH_ERASE_TOUT (2*CFG_HZ) /* Timeout for Flash Erase */
#define CFG_FLASH_WRITE_TOUT (2*CFG_HZ) /* Timeout for Flash Write */
#define CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_ADDR (PHYS_FLASH_1 + 0x1C000)
/* Addr of Environment Sector */
#define CFG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */
#endif /* __CONFIG_H */

820
include/configs/gw8260.h Normal file
View File

@ -0,0 +1,820 @@
/*
* (C) Copyright 2000
* Murray Jensen <Murray.Jensen@cmst.csiro.au>
*
* (C) Copyright 2000
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright 2001
* Advent Networks, Inc. <http://www.adventnetworks.com>
* Jay Monkman <jmonkman@adventnetworks.com>
*
* (C) Copyright 2001
* Advent Networks, Inc. <http://www.adventnetworks.com>
* Oliver Brown <obrown@adventnetworks.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
*/
/*********************************************************************/
/* DESCRIPTION:
* This file contains the board configuartion for the GW8260 board.
*
* MODULE DEPENDENCY:
* None
*
* RESTRICTIONS/LIMITATIONS:
* None
*
* Copyright (c) 2001, Advent Networks, Inc.
*/
/*********************************************************************/
#ifndef __CONFIG_H
#define __CONFIG_H
/* Enable debug prints */
#undef DEBUG /* General debug */
#undef DEBUG_BOOTP_EXT /* Debug received vendor fields */
/* What is the oscillator's (UX2) frequency in Hz? */
#define CONFIG_8260_CLKIN (66 * 1000 * 1000)
/*-----------------------------------------------------------------------
* MODCK_H & MODCLK[1-3] - Ref: Section 9.2 in MPC8206 User Manual
*-----------------------------------------------------------------------
* What should MODCK_H be? It is dependent on the oscillator
* frequency, MODCK[1-3], and desired CPM and core frequencies.
* Here are some example values (all frequencies are in MHz):
*
* MODCK_H MODCK[1-3] Osc CPM Core S2-6 S2-7 S2-8
* ------- ---------- --- --- ---- ----- ----- -----
* 0x5 0x5 66 133 133 Open Close Open
* 0x5 0x6 66 133 166 Open Open Close
* 0x5 0x7 66 133 200 Open Open Open
* 0x6 0x0 66 133 233 Close Close Close
* 0x6 0x1 66 133 266 Close Close Open
* 0x6 0x2 66 133 300 Close Open Close
*/
#define CFG_SBC_MODCK_H 0x05
/* Define this if you want to boot from 0x00000100. If you don't define
* this, you will need to program the bootloader to 0xfff00000, and
* get the hardware reset config words at 0xfe000000. The simplest
* way to do that is to program the bootloader at both addresses.
* It is suggested that you just let U-Boot live at 0x00000000.
*/
#define CFG_SBC_BOOT_LOW 1
/* What should the base address of the main FLASH be and how big is
* it (in MBytes)? This must contain TEXT_BASE from board/sbc8260/config.mk
* The main FLASH is whichever is connected to *CS0. U-Boot expects
* this to be the SIMM.
*/
#define CFG_FLASH0_BASE 0x40000000
#define CFG_FLASH0_SIZE 8
/* Define CFG_FLASH_CHECKSUM to enable flash checksum during boot.
* Note: the 'flashchecksum' environment variable must also be set to 'y'.
*/
#define CFG_FLASH_CHECKSUM
/* What should be the base address of SDRAM DIMM and how big is
* it (in Mbytes)?
*/
#define CFG_SDRAM0_BASE 0x00000000
#define CFG_SDRAM0_SIZE 64
/*
* DRAM tests
* CFG_DRAM_TEST - enables the following tests.
*
* CFG_DRAM_TEST_DATA - Enables test for shorted or open data lines
* Environment variable 'test_dram_data' must be
* set to 'y'.
* CFG_DRAM_TEST_DATA - Enables test to verify that each word is uniquely
* addressable. Environment variable
* 'test_dram_address' must be set to 'y'.
* CFG_DRAM_TEST_WALK - Enables test a 64-bit walking ones pattern test.
* This test takes about 6 minutes to test 64 MB.
* Environment variable 'test_dram_walk' must be
* set to 'y'.
*/
#define CFG_DRAM_TEST
#if defined(CFG_DRAM_TEST)
#define CFG_DRAM_TEST_DATA
#define CFG_DRAM_TEST_ADDRESS
#define CFG_DRAM_TEST_WALK
#endif /* CFG_DRAM_TEST */
/*
* GW8260 with 16 MB DIMM:
*
* 0x0000 0000 Exception Vector code, 8k
* :
* 0x0000 1FFF
* 0x0000 2000 Free for Application Use
* :
* :
*
* :
* :
* 0x00F5 FF30 Monitor Stack (Growing downward)
* Monitor Stack Buffer (0x80)
* 0x00F5 FFB0 Board Info Data
* 0x00F6 0000 Malloc Arena
* : CFG_ENV_SECT_SIZE, 256k
* : CFG_MALLOC_LEN, 128k
* 0x00FC 0000 RAM Copy of Monitor Code
* : CFG_MONITOR_LEN, 256k
* 0x00FF FFFF [End of RAM], CFG_SDRAM_SIZE - 1
*/
/*
* GW8260 with 64 MB DIMM:
*
* 0x0000 0000 Exception Vector code, 8k
* :
* 0x0000 1FFF
* 0x0000 2000 Free for Application Use
* :
* :
*
* :
* :
* 0x03F5 FF30 Monitor Stack (Growing downward)
* Monitor Stack Buffer (0x80)
* 0x03F5 FFB0 Board Info Data
* 0x03F6 0000 Malloc Arena
* : CFG_ENV_SECT_SIZE, 256k
* : CFG_MALLOC_LEN, 128k
* 0x03FC 0000 RAM Copy of Monitor Code
* : CFG_MONITOR_LEN, 256k
* 0x03FF FFFF [End of RAM], CFG_SDRAM_SIZE - 1
*/
/*
* select serial console configuration
*
* if either CONFIG_CONS_ON_SMC or CONFIG_CONS_ON_SCC is selected, then
* CONFIG_CONS_INDEX must be set to the channel number (1-2 for SMC, 1-4
* for SCC).
*
* if CONFIG_CONS_NONE is defined, then the serial console routines must
* defined elsewhere.
*/
#define CONFIG_CONS_ON_SMC 1 /* define if console on SMC */
#undef CONFIG_CONS_ON_SCC /* define if console on SCC */
#undef CONFIG_CONS_NONE /* define if console on neither */
#define CONFIG_CONS_INDEX 1 /* which SMC/SCC channel for console */
/*
* select ethernet configuration
*
* if either CONFIG_ETHER_ON_SCC or CONFIG_ETHER_ON_FCC is selected, then
* CONFIG_ETHER_INDEX must be set to the channel number (1-4 for SCC, 1-3
* for FCC)
*
* if CONFIG_ETHER_NONE is defined, then either the ethernet routines must be
* defined elsewhere (as for the console), or CFG_CMD_NET must be removed
* from CONFIG_COMMANDS to remove support for networking.
*/
#undef CONFIG_ETHER_ON_SCC
#define CONFIG_ETHER_ON_FCC
#undef CONFIG_ETHER_NONE /* define if ethernet on neither */
#ifdef CONFIG_ETHER_ON_SCC
#define CONFIG_ETHER_INDEX 1 /* which SCC/FCC channel for ethernet */
#endif /* CONFIG_ETHER_ON_SCC */
#ifdef CONFIG_ETHER_ON_FCC
#define CONFIG_ETHER_INDEX 2 /* which SCC/FCC channel for ethernet */
#define CONFIG_MII /* MII PHY management */
#define CONFIG_BITBANGMII /* bit-bang MII PHY management */
/*
* Port pins used for bit-banged MII communictions (if applicable).
*/
#define MDIO_PORT 2 /* Port C */
#define MDIO_ACTIVE (iop->pdir |= 0x00400000)
#define MDIO_TRISTATE (iop->pdir &= ~0x00400000)
#define MDIO_READ ((iop->pdat & 0x00400000) != 0)
#define MDIO(bit) if(bit) iop->pdat |= 0x00400000; \
else iop->pdat &= ~0x00400000
#define MDC(bit) if(bit) iop->pdat |= 0x00200000; \
else iop->pdat &= ~0x00200000
#define MIIDELAY udelay(1)
#endif /* CONFIG_ETHER_ON_FCC */
#if defined(CONFIG_ETHER_ON_FCC) && (CONFIG_ETHER_INDEX == 2)
/*
* - Rx-CLK is CLK13
* - Tx-CLK is CLK14
* - Select bus for bd/buffers (see 28-13)
* - Enable Full Duplex in FSMR
*/
# define CFG_CMXFCR_MASK (CMXFCR_FC2|CMXFCR_RF2CS_MSK|CMXFCR_TF2CS_MSK)
# define CFG_CMXFCR_VALUE (CMXFCR_RF2CS_CLK13|CMXFCR_TF2CS_CLK14)
# define CFG_CPMFCR_RAMTYPE 0
# define CFG_FCC_PSMR (FCC_PSMR_FDE | FCC_PSMR_LPB)
#elif defined(CONFIG_ETHER_ON_FCC) && (CONFIG_ETHER_INDEX == 3)
/*
* - Rx-CLK is CLK15
* - Tx-CLK is CLK16
* - Select bus for bd/buffers (see 28-13)
* - Enable Full Duplex in FSMR
*/
# define CFG_CMXFCR_MASK (CMXFCR_FC3|CMXFCR_RF3CS_MSK|CMXFCR_TF3CS_MSK)
# define CFG_CMXFCR_VALUE (CMXFCR_RF3CS_CLK15|CMXFCR_TF3CS_CLK16)
# define CFG_CPMFCR_RAMTYPE 0
# define CFG_FCC_PSMR (FCC_PSMR_FDE | FCC_PSMR_LPB)
#endif /* CONFIG_ETHER_ON_FCC, CONFIG_ETHER_INDEX */
/* Define this to reserve an entire FLASH sector (256 KB) for
* environment variables. Otherwise, the environment will be
* put in the same sector as U-Boot, and changing variables
* will erase U-Boot temporarily
*/
#define CFG_ENV_IN_OWN_SECT
/* Define to allow the user to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE
/* What should the console's baud rate be? */
#define CONFIG_BAUDRATE 115200
/* Ethernet MAC address - This is set to all zeros to force an
* an error if we use BOOTP without setting
* the MAC address
*/
#define CONFIG_ETHADDR 00:00:00:00:00:00
/* Set to a positive value to delay for running BOOTCOMMAND */
#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */
/* Be selective on what keys can delay or stop the autoboot process
* To stop use: " "
*/
#define CONFIG_AUTOBOOT_KEYED
#define CONFIG_AUTOBOOT_PROMPT "Autobooting in %d seconds, press \" \" to stop\n"
#define CONFIG_AUTOBOOT_STOP_STR " "
#undef CONFIG_AUTOBOOT_DELAY_STR
#define DEBUG_BOOTKEYS 0
/* Add support for a few extra bootp options like:
* - File size
* - DNS
*/
#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | \
CONFIG_BOOTP_BOOTFILESIZE | \
CONFIG_BOOTP_DNS)
/* undef this to save memory */
#define CFG_LONGHELP
/* Monitor Command Prompt */
#define CFG_PROMPT "=> "
/* What U-Boot subsytems do you want enabled? */
#define CONFIG_COMMANDS (((CONFIG_CMD_DFL & ~(CFG_CMD_KGDB))) | \
CFG_CMD_BEDBUG | \
CFG_CMD_ELF | \
CFG_CMD_ASKENV | \
CFG_CMD_ECHO | \
CFG_CMD_REGINFO | \
CFG_CMD_IMMAP | \
CFG_CMD_MII)
/* Where do the internal registers live? */
#define CFG_IMMR 0xf0000000
/* Use the HUSH parser */
#define CFG_HUSH_PARSER
#ifdef CFG_HUSH_PARSER
#define CFG_PROMPT_HUSH_PS2 "> "
#endif
/* What is the address of IO controller */
#define CFG_IO_BASE 0xe0000000
/*****************************************************************************
*
* You should not have to modify any of the following settings
*
*****************************************************************************/
#define CONFIG_MPC8260 1 /* This is an MPC8260 CPU */
#define CONFIG_GW8260 1 /* on an GW8260 Board */
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
/*
* Miscellaneous configurable options
*/
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
# define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
#else
# define CFG_CBSIZE 256 /* Console I/O Buffer Size */
#endif
/* Print Buffer Size */
#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT)+16)
#define CFG_MAXARGS 8 /* max number of command args */
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
/* Convert clocks to MHZ when passing board info to kernel.
* This must be defined for eariler 2.4 kernels (~2.4.4).
*/
#define CONFIG_CLOCKS_IN_MHZ
#define CFG_LOAD_ADDR 0x100000 /* default load address */
#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
/* memtest works from the end of the exception vector table
* to the end of the DRAM less monitor and malloc area
*/
#define CFG_MEMTEST_START 0x2000
#define CFG_STACK_USAGE 0x10000 /* Reserve 64k for the stack usage */
#define CFG_MEM_END_USAGE ( CFG_MONITOR_LEN \
+ CFG_MALLOC_LEN \
+ CFG_ENV_SECT_SIZE \
+ CFG_STACK_USAGE )
#define CFG_MEMTEST_END ( CFG_SDRAM_SIZE * 1024 * 1024 \
- CFG_MEM_END_USAGE )
/* valid baudrates */
#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
/*
* Low Level Configuration Settings
* (address mappings, register initial values, etc.)
* You should know what you are doing if you make changes here.
*/
#define CFG_FLASH_BASE CFG_FLASH0_BASE
#define CFG_FLASH_SIZE CFG_FLASH0_SIZE
#define CFG_SDRAM_BASE CFG_SDRAM0_BASE
#define CFG_SDRAM_SIZE CFG_SDRAM0_SIZE
/*-----------------------------------------------------------------------
* Hard Reset Configuration Words
*/
#if defined(CFG_SBC_BOOT_LOW)
# define CFG_SBC_HRCW_BOOT_FLAGS (HRCW_CIP | HRCW_BMS)
#else
# define CFG_SBC_HRCW_BOOT_FLAGS (0)
#endif /* defined(CFG_SBC_BOOT_LOW) */
/* get the HRCW ISB field from CFG_IMMR */
#define CFG_SBC_HRCW_IMMR ( ((CFG_IMMR & 0x10000000) >> 10) | \
((CFG_IMMR & 0x01000000) >> 7) | \
((CFG_IMMR & 0x00100000) >> 4) )
#define CFG_HRCW_MASTER ( HRCW_BPS11 | \
HRCW_DPPC11 | \
CFG_SBC_HRCW_IMMR | \
HRCW_MMR00 | \
HRCW_LBPC11 | \
HRCW_APPC10 | \
HRCW_CS10PC00 | \
(CFG_SBC_MODCK_H & HRCW_MODCK_H1111) | \
CFG_SBC_HRCW_BOOT_FLAGS )
/* no slaves */
#define CFG_HRCW_SLAVE1 0
#define CFG_HRCW_SLAVE2 0
#define CFG_HRCW_SLAVE3 0
#define CFG_HRCW_SLAVE4 0
#define CFG_HRCW_SLAVE5 0
#define CFG_HRCW_SLAVE6 0
#define CFG_HRCW_SLAVE7 0
/*-----------------------------------------------------------------------
* Definitions for initial stack pointer and data area (in DPRAM)
*/
#define CFG_INIT_RAM_ADDR CFG_IMMR
#define CFG_INIT_RAM_END 0x4000 /* End of used area in DPRAM */
#define CFG_GBL_DATA_SIZE 128 /* bytes reserved for initial data */
#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
/*-----------------------------------------------------------------------
* Start addresses for the final memory configuration
* (Set up by the startup code)
* Please note that CFG_SDRAM_BASE _must_ start at 0
* Note also that the logic that sets CFG_RAMBOOT is platform dependent.
*/
#define CFG_MONITOR_BASE CFG_FLASH0_BASE
#define CFG_MONITOR_LEN (256 * 1024) /* Reserve 256 kB for Monitor */
#define CFG_MALLOC_LEN (128 * 1024) /* Reserve 128 kB for malloc() */
/*
* For booting Linux, the board info and command line data
* have to be in the first 8 MB of memory, since this is
* the maximum mapped by the Linux kernel during initialization.
*/
#define CFG_BOOTMAPSZ (8 * 1024 * 1024) /* Initial Memory map for Linux */
/*-----------------------------------------------------------------------
* FLASH and environment organization
*/
#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
#define CFG_MAX_FLASH_SECT 32 /* max number of sectors on one chip */
#define CFG_FLASH_ERASE_TOUT 8000 /* Timeout for Flash Erase (in ms) */
#define CFG_FLASH_WRITE_TOUT 1 /* Timeout for Flash Write (in ms) */
#define CFG_ENV_IS_IN_FLASH 1
#ifdef CFG_ENV_IN_OWN_SECT
# define CFG_ENV_ADDR (CFG_MONITOR_BASE + (256 * 1024))
# define CFG_ENV_SECT_SIZE (256 * 1024)
#else
# define CFG_ENV_SIZE (16 * 1024)/* Size of Environment Sector */
# define CFG_ENV_ADD ((CFG_MONITOR_BASE + CFG_MONITOR_LEN) - CFG_ENV_SIZE)
# define CFG_ENV_SECT_SIZE (256 * 1024)/* see README - env sect real size */
#endif /* CFG_ENV_IN_OWN_SECT */
/*-----------------------------------------------------------------------
* Cache Configuration
*/
#define CFG_CACHELINE_SIZE 32 /* For MPC8260 CPU */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
#endif
/*-----------------------------------------------------------------------
* HIDx - Hardware Implementation-dependent Registers 2-11
*-----------------------------------------------------------------------
* HID0 also contains cache control - initially enable both caches and
* invalidate contents, then the final state leaves only the instruction
* cache enabled. Note that Power-On and Hard reset invalidate the caches,
* but Soft reset does not.
*
* HID1 has only read-only information - nothing to set.
*/
#define CFG_HID0_INIT (HID0_ICE |\
HID0_DCE |\
HID0_ICFI |\
HID0_DCI |\
HID0_IFEM |\
HID0_ABE)
#define CFG_HID0_FINAL (HID0_ICE |\
HID0_IFEM |\
HID0_ABE |\
HID0_EMCP)
#define CFG_HID2 0
/*-----------------------------------------------------------------------
* RMR - Reset Mode Register
*-----------------------------------------------------------------------
*/
#define CFG_RMR 0
/*-----------------------------------------------------------------------
* BCR - Bus Configuration 4-25
*-----------------------------------------------------------------------
*/
#define CFG_BCR (BCR_ETM)
/*-----------------------------------------------------------------------
* SIUMCR - SIU Module Configuration 4-31
*-----------------------------------------------------------------------
*/
#define CFG_SIUMCR (SIUMCR_DPPC11 |\
SIUMCR_L2CPC00 |\
SIUMCR_APPC10 |\
SIUMCR_MMR00)
/*-----------------------------------------------------------------------
* SYPCR - System Protection Control 11-9
* SYPCR can only be written once after reset!
*-----------------------------------------------------------------------
* Watchdog & Bus Monitor Timer max, 60x Bus Monitor enable
*/
#define CFG_SYPCR (SYPCR_SWTC |\
SYPCR_BMT |\
SYPCR_PBME |\
SYPCR_LBME |\
SYPCR_SWRI |\
SYPCR_SWP)
/*-----------------------------------------------------------------------
* TMCNTSC - Time Counter Status and Control 4-40
*-----------------------------------------------------------------------
* Clear once per Second and Alarm Interrupt Status, Set 32KHz timersclk,
* and enable Time Counter
*/
#define CFG_TMCNTSC (TMCNTSC_SEC |\
TMCNTSC_ALR |\
TMCNTSC_TCF |\
TMCNTSC_TCE)
/*-----------------------------------------------------------------------
* PISCR - Periodic Interrupt Status and Control 4-42
*-----------------------------------------------------------------------
* Clear Periodic Interrupt Status, Set 32KHz timersclk, and enable
* Periodic timer
*/
#define CFG_PISCR (PISCR_PS |\
PISCR_PTF |\
PISCR_PTE)
/*-----------------------------------------------------------------------
* SCCR - System Clock Control 9-8
*-----------------------------------------------------------------------
*/
#define CFG_SCCR 0
/*-----------------------------------------------------------------------
* RCCR - RISC Controller Configuration 13-7
*-----------------------------------------------------------------------
*/
#define CFG_RCCR 0
/*
* Initialize Memory Controller:
*
* Bank Bus Machine PortSz Device
* ---- --- ------- ------ ------
* 0 60x GPCM 32 bit FLASH (SIMM - 4MB)
* 1 60x GPCM 32 bit unused
* 2 60x SDRAM 64 bit SDRAM (DIMM - 16MB or 64MB)
* 3 60x SDRAM 64 bit unused
* 4 Local GPCM 8 bit IO (on board - 64k)
* 5 60x GPCM 8 bit unused
* 6 60x GPCM 8 bit unused
* 7 60x GPCM 8 bit unused
*
*/
/*-----------------------------------------------------------------------
* BR0 - Base Register
* Ref: Section 10.3.1 on page 10-14
* OR0 - Option Register
* Ref: Section 10.3.2 on page 10-18
*-----------------------------------------------------------------------
*/
/* Bank 0,1 - FLASH SIMM
*
* This expects the FLASH SIMM to be connected to *CS0
* It consists of 4 AM29F016D parts.
*
* Note: For the 8 MB SIMM, *CS1 is unused.
*/
/* BR0 is configured as follows:
*
* - Base address of 0x40000000
* - 32 bit port size
* - Data errors checking is disabled
* - Read and write access
* - GPCM 60x bus
* - Access are handled by the memory controller according to MSEL
* - Not used for atomic operations
* - No data pipelining is done
* - Valid
*/
#define CFG_BR0_PRELIM ((CFG_FLASH0_BASE & BRx_BA_MSK) |\
BRx_PS_32 |\
BRx_MS_GPCM_P |\
BRx_V)
/* OR0 is configured as follows:
*
* - 8 MB
* - *BCTL0 is asserted upon access to the current memory bank
* - *CW / *WE are negated a quarter of a clock earlier
* - *CS is output at the same time as the address lines
* - Uses a clock cycle length of 5
* - *PSDVAL is generated internally by the memory controller
* unless *GTA is asserted earlier externally.
* - Relaxed timing is generated by the GPCM for accesses
* initiated to this memory region.
* - One idle clock is inserted between a read access from the
* current bank and the next access.
*/
#define CFG_OR0_PRELIM (MEG_TO_AM(CFG_FLASH0_SIZE) |\
ORxG_CSNT |\
ORxG_ACS_DIV1 |\
ORxG_SCY_5_CLK |\
ORxG_TRLX |\
ORxG_EHTR)
/*-----------------------------------------------------------------------
* BR2 - Base Register
* Ref: Section 10.3.1 on page 10-14
* OR2 - Option Register
* Ref: Section 10.3.2 on page 10-16
*-----------------------------------------------------------------------
*/
/* Bank 2 - SDRAM DIMM
*
* 16MB DIMM: P/N
* 64MB DIMM: P/N 1W-8864X8-4-P1-EST or
* MT4LSDT864AG-10EB1 (Micron)
*
* Note: *CS3 is unused for this DIMM
*/
/* With a 16 MB or 64 MB DIMM, the BR2 is configured as follows:
*
* - Base address of 0x00000000
* - 64 bit port size (60x bus only)
* - Data errors checking is disabled
* - Read and write access
* - SDRAM 60x bus
* - Access are handled by the memory controller according to MSEL
* - Not used for atomic operations
* - No data pipelining is done
* - Valid
*/
#define CFG_BR2_PRELIM ((CFG_SDRAM0_BASE & BRx_BA_MSK) |\
BRx_PS_64 |\
BRx_MS_SDRAM_P |\
BRx_V)
/* With a 16 MB DIMM, the OR2 is configured as follows:
*
* - 16 MB
* - 2 internal banks per device
* - Row start address bit is A9 with PSDMR[PBI] = 0
* - 11 row address lines
* - Back-to-back page mode
* - Internal bank interleaving within save device enabled
*/
#if (CFG_SDRAM0_SIZE == 16)
#define CFG_OR2_PRELIM (MEG_TO_AM(CFG_SDRAM0_SIZE) |\
ORxS_BPD_2 |\
ORxS_ROWST_PBI0_A9 |\
ORxS_NUMR_11)
/* With a 16 MB DIMM, the PSDMR is configured as follows:
*
* - Page Based Interleaving,
* - Refresh Enable,
* - Address Multiplexing where A5 is output on A14 pin
* (A6 on A15, and so on),
* - use address pins A16-A18 as bank select,
* - A9 is output on SDA10 during an ACTIVATE command,
* - earliest timing for ACTIVATE command after REFRESH command is 7 clocks,
* - earliest timing for ACTIVATE or REFRESH command after PRECHARGE command
* is 3 clocks,
* - earliest timing for READ/WRITE command after ACTIVATE command is
* 2 clocks,
* - earliest timing for PRECHARGE after last data was read is 1 clock,
* - earliest timing for PRECHARGE after last data was written is 1 clock,
* - CAS Latency is 2.
*/
/*-----------------------------------------------------------------------
* PSDMR - 60x Bus SDRAM Mode Register
* Ref: Section 10.3.3 on page 10-21
*-----------------------------------------------------------------------
*/
#define CFG_PSDMR (PSDMR_RFEN |\
PSDMR_SDAM_A14_IS_A5 |\
PSDMR_BSMA_A16_A18 |\
PSDMR_SDA10_PBI0_A9 |\
PSDMR_RFRC_7_CLK |\
PSDMR_PRETOACT_3W |\
PSDMR_ACTTORW_2W |\
PSDMR_LDOTOPRE_1C |\
PSDMR_WRC_1C |\
PSDMR_CL_2)
#endif /* (CFG_SDRAM0_SIZE == 16) */
/* With a 64 MB DIMM, the OR2 is configured as follows:
*
* - 64 MB
* - 4 internal banks per device
* - Row start address bit is A8 with PSDMR[PBI] = 0
* - 12 row address lines
* - Back-to-back page mode
* - Internal bank interleaving within save device enabled
*/
#if (CFG_SDRAM0_SIZE == 64)
#define CFG_OR2_PRELIM (MEG_TO_AM(CFG_SDRAM0_SIZE) |\
ORxS_BPD_4 |\
ORxS_ROWST_PBI0_A8 |\
ORxS_NUMR_12)
/* With a 64 MB DIMM, the PSDMR is configured as follows:
*
* - Page Based Interleaving,
* - Refresh Enable,
* - Address Multiplexing where A5 is output on A14 pin
* (A6 on A15, and so on),
* - use address pins A14-A16 as bank select,
* - A9 is output on SDA10 during an ACTIVATE command,
* - earliest timing for ACTIVATE command after REFRESH command is 7 clocks,
* - earliest timing for ACTIVATE or REFRESH command after PRECHARGE command
* is 3 clocks,
* - earliest timing for READ/WRITE command after ACTIVATE command is
* 2 clocks,
* - earliest timing for PRECHARGE after last data was read is 1 clock,
* - earliest timing for PRECHARGE after last data was written is 1 clock,
* - CAS Latency is 2.
*/
/*-----------------------------------------------------------------------
* PSDMR - 60x Bus SDRAM Mode Register
* Ref: Section 10.3.3 on page 10-21
*-----------------------------------------------------------------------
*/
#define CFG_PSDMR (PSDMR_RFEN |\
PSDMR_SDAM_A14_IS_A5 |\
PSDMR_BSMA_A14_A16 |\
PSDMR_SDA10_PBI0_A9 |\
PSDMR_RFRC_7_CLK |\
PSDMR_PRETOACT_3W |\
PSDMR_ACTTORW_2W |\
PSDMR_LDOTOPRE_1C |\
PSDMR_WRC_1C |\
PSDMR_CL_2)
#endif /* (CFG_SDRAM0_SIZE == 64) */
#define CFG_PSRT 0x0e
#define CFG_MPTPR MPTPR_PTP_DIV32
/*-----------------------------------------------------------------------
* BR4 - Base Register
* Ref: Section 10.3.1 on page 10-14
* OR4 - Option Register
* Ref: Section 10.3.2 on page 10-18
*-----------------------------------------------------------------------
*/
/* Bank 4 - Onboard Memory Mapped IO controller
*
* This expects the onboard IO controller to connected to *CS4 and
* the local bus.
* - Base address of 0xe0000000
* - 8 bit port size (local bus only)
* - Read and write access
* - GPCM local bus
* - Not used for atomic operations
* - No data pipelining is done
* - Valid
* - extended hold time
* - 11 wait states
*/
#ifdef CFG_IO_BASE
# define CFG_BR4_PRELIM ((CFG_IO_BASE & BRx_BA_MSK) |\
BRx_PS_8 |\
BRx_MS_GPCM_L |\
BRx_V)
# define CFG_OR4_PRELIM (ORxG_AM_MSK |\
ORxG_SCY_11_CLK |\
ORxG_EHTR)
#endif /* CFG_IO_BASE */
/*
* Internal Definitions
*
* Boot Flags
*/
#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
#define BOOTFLAG_WARM 0x02 /* Software reboot */
#endif /* __CONFIG_H */

1004
include/configs/ppmc8260.h Normal file

File diff suppressed because it is too large Load Diff

1000
include/configs/sacsng.h Normal file

File diff suppressed because it is too large Load Diff

980
include/configs/sbc8260.h Normal file
View File

@ -0,0 +1,980 @@
/*
* (C) Copyright 2000
* Murray Jensen <Murray.Jensen@cmst.csiro.au>
*
* (C) Copyright 2000
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright 2001
* Advent Networks, Inc. <http://www.adventnetworks.com>
* Jay Monkman <jtm@smoothsmoothie.com>
*
* Configuration settings for the WindRiver SBC8260 board.
* See http://www.windriver.com/products/html/sbc8260.html
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef __CONFIG_H
#define __CONFIG_H
/* Enable debug prints */
#undef DEBUG /* General debug */
#undef DEBUG_BOOTP_EXT /* Debug received vendor fields */
/*****************************************************************************
*
* These settings must match the way _your_ board is set up
*
*****************************************************************************/
/* What is the oscillator's (UX2) frequency in Hz? */
#define CONFIG_8260_CLKIN (66 * 1000 * 1000)
/*-----------------------------------------------------------------------
* MODCK_H & MODCLK[1-3] - Ref: Section 9.2 in MPC8206 User Manual
*-----------------------------------------------------------------------
* What should MODCK_H be? It is dependent on the oscillator
* frequency, MODCK[1-3], and desired CPM and core frequencies.
* Here are some example values (all frequencies are in MHz):
*
* MODCK_H MODCK[1-3] Osc CPM Core S2-6 S2-7 S2-8
* ------- ---------- --- --- ---- ----- ----- -----
* 0x1 0x5 33 100 133 Open Close Open
* 0x1 0x6 33 100 166 Open Open Close
* 0x1 0x7 33 100 200 Open Open Open
*
* 0x2 0x2 33 133 133 Close Open Close
* 0x2 0x3 33 133 166 Close Open Open
* 0x2 0x4 33 133 200 Open Close Close
* 0x2 0x5 33 133 233 Open Close Open
* 0x2 0x6 33 133 266 Open Open Close
*
* 0x5 0x5 66 133 133 Open Close Open
* 0x5 0x6 66 133 166 Open Open Close
* 0x5 0x7 66 133 200 Open Open Open
* 0x6 0x0 66 133 233 Close Close Close
* 0x6 0x1 66 133 266 Close Close Open
* 0x6 0x2 66 133 300 Close Open Close
*/
#define CFG_SBC_MODCK_H 0x05
/* Define this if you want to boot from 0x00000100. If you don't define
* this, you will need to program the bootloader to 0xfff00000, and
* get the hardware reset config words at 0xfe000000. The simplest
* way to do that is to program the bootloader at both addresses.
* It is suggested that you just let U-Boot live at 0x00000000.
*/
#define CFG_SBC_BOOT_LOW 1
/* What should the base address of the main FLASH be and how big is
* it (in MBytes)? This must contain TEXT_BASE from board/sbc8260/config.mk
* The main FLASH is whichever is connected to *CS0. U-Boot expects
* this to be the SIMM.
*/
#define CFG_FLASH0_BASE 0x40000000
#define CFG_FLASH0_SIZE 4
/* What should the base address of the secondary FLASH be and how big
* is it (in Mbytes)? The secondary FLASH is whichever is connected
* to *CS6. U-Boot expects this to be the on board FLASH. If you don't
* want it enabled, don't define these constants.
*/
#define CFG_FLASH1_BASE 0x60000000
#define CFG_FLASH1_SIZE 2
/* What should be the base address of SDRAM DIMM and how big is
* it (in Mbytes)?
*/
#define CFG_SDRAM0_BASE 0x00000000
#define CFG_SDRAM0_SIZE 64
/* What should be the base address of the LEDs and switch S0?
* If you don't want them enabled, don't define this.
*/
#define CFG_LED_BASE 0xa0000000
/*
* SBC8260 with 16 MB DIMM:
*
* 0x0000 0000 Exception Vector code, 8k
* :
* 0x0000 1FFF
* 0x0000 2000 Free for Application Use
* :
* :
*
* :
* :
* 0x00F5 FF30 Monitor Stack (Growing downward)
* Monitor Stack Buffer (0x80)
* 0x00F5 FFB0 Board Info Data
* 0x00F6 0000 Malloc Arena
* : CFG_ENV_SECT_SIZE, 256k
* : CFG_MALLOC_LEN, 128k
* 0x00FC 0000 RAM Copy of Monitor Code
* : CFG_MONITOR_LEN, 256k
* 0x00FF FFFF [End of RAM], CFG_SDRAM_SIZE - 1
*/
/*
* SBC8260 with 64 MB DIMM:
*
* 0x0000 0000 Exception Vector code, 8k
* :
* 0x0000 1FFF
* 0x0000 2000 Free for Application Use
* :
* :
*
* :
* :
* 0x03F5 FF30 Monitor Stack (Growing downward)
* Monitor Stack Buffer (0x80)
* 0x03F5 FFB0 Board Info Data
* 0x03F6 0000 Malloc Arena
* : CFG_ENV_SECT_SIZE, 256k
* : CFG_MALLOC_LEN, 128k
* 0x03FC 0000 RAM Copy of Monitor Code
* : CFG_MONITOR_LEN, 256k
* 0x03FF FFFF [End of RAM], CFG_SDRAM_SIZE - 1
*/
/*
* select serial console configuration
*
* if either CONFIG_CONS_ON_SMC or CONFIG_CONS_ON_SCC is selected, then
* CONFIG_CONS_INDEX must be set to the channel number (1-2 for SMC, 1-4
* for SCC).
*
* if CONFIG_CONS_NONE is defined, then the serial console routines must
* defined elsewhere.
*/
#define CONFIG_CONS_ON_SMC 1 /* define if console on SMC */
#undef CONFIG_CONS_ON_SCC /* define if console on SCC */
#undef CONFIG_CONS_NONE /* define if console on neither */
#define CONFIG_CONS_INDEX 1 /* which SMC/SCC channel for console */
/*
* select ethernet configuration
*
* if either CONFIG_ETHER_ON_SCC or CONFIG_ETHER_ON_FCC is selected, then
* CONFIG_ETHER_INDEX must be set to the channel number (1-4 for SCC, 1-3
* for FCC)
*
* if CONFIG_ETHER_NONE is defined, then either the ethernet routines must be
* defined elsewhere (as for the console), or CFG_CMD_NET must be removed
* from CONFIG_COMMANDS to remove support for networking.
*/
#undef CONFIG_ETHER_ON_SCC
#define CONFIG_ETHER_ON_FCC
#undef CONFIG_ETHER_NONE /* define if ethernet on neither */
#ifdef CONFIG_ETHER_ON_SCC
#define CONFIG_ETHER_INDEX 1 /* which SCC/FCC channel for ethernet */
#endif /* CONFIG_ETHER_ON_SCC */
#ifdef CONFIG_ETHER_ON_FCC
#define CONFIG_ETHER_INDEX 2 /* which SCC/FCC channel for ethernet */
#define CONFIG_MII /* MII PHY management */
#define CONFIG_BITBANGMII /* bit-bang MII PHY management */
/*
* Port pins used for bit-banged MII communictions (if applicable).
*/
#define MDIO_PORT 2 /* Port C */
#define MDIO_ACTIVE (iop->pdir |= 0x00400000)
#define MDIO_TRISTATE (iop->pdir &= ~0x00400000)
#define MDIO_READ ((iop->pdat & 0x00400000) != 0)
#define MDIO(bit) if(bit) iop->pdat |= 0x00400000; \
else iop->pdat &= ~0x00400000
#define MDC(bit) if(bit) iop->pdat |= 0x00200000; \
else iop->pdat &= ~0x00200000
#define MIIDELAY udelay(1)
#endif /* CONFIG_ETHER_ON_FCC */
#if defined(CONFIG_ETHER_ON_SCC) && (CONFIG_ETHER_INDEX == 1)
/*
* - RX clk is CLK11
* - TX clk is CLK12
*/
# define CFG_CMXSCR_VALUE (CMXSCR_RS1CS_CLK11 | CMXSCR_TS1CS_CLK12)
#elif defined(CONFIG_ETHER_ON_FCC) && (CONFIG_ETHER_INDEX == 2)
/*
* - Rx-CLK is CLK13
* - Tx-CLK is CLK14
* - Select bus for bd/buffers (see 28-13)
* - Enable Full Duplex in FSMR
*/
# define CFG_CMXFCR_MASK (CMXFCR_FC2|CMXFCR_RF2CS_MSK|CMXFCR_TF2CS_MSK)
# define CFG_CMXFCR_VALUE (CMXFCR_RF2CS_CLK13|CMXFCR_TF2CS_CLK14)
# define CFG_CPMFCR_RAMTYPE 0
# define CFG_FCC_PSMR (FCC_PSMR_FDE | FCC_PSMR_LPB)
#endif /* CONFIG_ETHER_ON_FCC, CONFIG_ETHER_INDEX */
/*
* select SPI support configuration
*/
#undef CONFIG_SPI /* enable SPI driver */
/*
* select i2c support configuration
*
* Supported configurations are {none, software, hardware} drivers.
* If the software driver is chosen, there are some additional
* configuration items that the driver uses to drive the port pins.
*/
#undef CONFIG_HARD_I2C /* I2C with hardware support */
#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */
#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */
#define CFG_I2C_SLAVE 0x7F
/*
* Software (bit-bang) I2C driver configuration
*/
#ifdef CONFIG_SOFT_I2C
#define I2C_PORT 3 /* Port A=0, B=1, C=2, D=3 */
#define I2C_ACTIVE (iop->pdir |= 0x00010000)
#define I2C_TRISTATE (iop->pdir &= ~0x00010000)
#define I2C_READ ((iop->pdat & 0x00010000) != 0)
#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00010000; \
else iop->pdat &= ~0x00010000
#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00020000; \
else iop->pdat &= ~0x00020000
#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */
#endif /* CONFIG_SOFT_I2C */
/* Define this to reserve an entire FLASH sector (256 KB) for
* environment variables. Otherwise, the environment will be
* put in the same sector as U-Boot, and changing variables
* will erase U-Boot temporarily
*/
#define CFG_ENV_IN_OWN_SECT 1
/* Define to allow the user to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE
/* What should the console's baud rate be? */
#define CONFIG_BAUDRATE 9600
/* Ethernet MAC address */
#define CONFIG_ETHADDR 00:a0:1e:a8:7b:cb
/*
* Define this to set the last octet of the ethernet address from the
* DS0-DS7 switch and light the LEDs with the result. The DS0-DS7
* switch and the LEDs are backwards with respect to each other. DS7
* is on the board edge side of both the LED strip and the DS0-DS7
* switch.
*/
#if 0
# define CONFIG_MISC_INIT_R
#endif
/* Set to a positive value to delay for running BOOTCOMMAND */
#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */
#if 0
/* Be selective on what keys can delay or stop the autoboot process
* To stop use: " "
*/
# define CONFIG_AUTOBOOT_KEYED
# define CONFIG_AUTOBOOT_PROMPT "Autobooting in %d seconds, press \" \" to stop\n"
# define CONFIG_AUTOBOOT_STOP_STR " "
# undef CONFIG_AUTOBOOT_DELAY_STR
# define DEBUG_BOOTKEYS 0
#endif
/* Define a command string that is automatically executed when no character
* is read on the console interface withing "Boot Delay" after reset.
*/
#define CONFIG_BOOT_ROOT_INITRD 0 /* Use ram disk for the root file system */
#define CONFIG_BOOT_ROOT_NFS 1 /* Use a NFS mounted root file system */
#if CONFIG_BOOT_ROOT_INITRD
#define CONFIG_BOOTCOMMAND \
"version;" \
"echo;" \
"bootp;" \
"setenv bootargs root=/dev/ram0 rw " \
"ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off;" \
"bootm"
#endif /* CONFIG_BOOT_ROOT_INITRD */
#if CONFIG_BOOT_ROOT_NFS
#define CONFIG_BOOTCOMMAND \
"version;" \
"echo;" \
"bootp;" \
"setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \
"ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off;" \
"bootm"
#endif /* CONFIG_BOOT_ROOT_NFS */
/* Add support for a few extra bootp options like:
* - File size
* - DNS
*/
#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | \
CONFIG_BOOTP_BOOTFILESIZE | \
CONFIG_BOOTP_DNS)
/* undef this to save memory */
#define CFG_LONGHELP
/* Monitor Command Prompt */
#define CFG_PROMPT "=> "
/* What U-Boot subsytems do you want enabled? */
#ifdef CONFIG_ETHER_ON_FCC
# define CONFIG_COMMANDS (((CONFIG_CMD_DFL & ~(CFG_CMD_KGDB))) | \
CFG_CMD_ELF | \
CFG_CMD_ASKENV | \
CFG_CMD_ECHO | \
CFG_CMD_I2C | \
CFG_CMD_SDRAM | \
CFG_CMD_REGINFO | \
CFG_CMD_IMMAP | \
CFG_CMD_MII )
#else
# define CONFIG_COMMANDS (((CONFIG_CMD_DFL & ~(CFG_CMD_KGDB))) | \
CFG_CMD_ELF | \
CFG_CMD_ASKENV | \
CFG_CMD_ECHO | \
CFG_CMD_I2C | \
CFG_CMD_SDRAM | \
CFG_CMD_REGINFO | \
CFG_CMD_IMMAP )
#endif /* CONFIG_ETHER_ON_FCC */
/* Where do the internal registers live? */
#define CFG_IMMR 0xF0000000
/*****************************************************************************
*
* You should not have to modify any of the following settings
*
*****************************************************************************/
#define CONFIG_MPC8260 1 /* This is an MPC8260 CPU */
#define CONFIG_SBC8260 1 /* on an EST SBC8260 Board */
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
/*
* Miscellaneous configurable options
*/
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
# define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
#else
# define CFG_CBSIZE 256 /* Console I/O Buffer Size */
#endif
/* Print Buffer Size */
#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT)+16)
#define CFG_MAXARGS 32 /* max number of command args */
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
#define CFG_LOAD_ADDR 0x140000 /* default load address */
#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
#define CFG_MEMTEST_START 0x2000 /* memtest works from the end of */
/* the exception vector table */
/* to the end of the DRAM */
/* less monitor and malloc area */
#define CFG_STACK_USAGE 0x10000 /* Reserve 64k for the stack usage */
#define CFG_MEM_END_USAGE ( CFG_MONITOR_LEN \
+ CFG_MALLOC_LEN \
+ CFG_ENV_SECT_SIZE \
+ CFG_STACK_USAGE )
#define CFG_MEMTEST_END ( CFG_SDRAM_SIZE * 1024 * 1024 \
- CFG_MEM_END_USAGE )
/* valid baudrates */
#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
/*
* Low Level Configuration Settings
* (address mappings, register initial values, etc.)
* You should know what you are doing if you make changes here.
*/
#define CFG_FLASH_BASE CFG_FLASH0_BASE
#define CFG_FLASH_SIZE CFG_FLASH0_SIZE
#define CFG_SDRAM_BASE CFG_SDRAM0_BASE
#define CFG_SDRAM_SIZE CFG_SDRAM0_SIZE
/*-----------------------------------------------------------------------
* Hard Reset Configuration Words
*/
#if defined(CFG_SBC_BOOT_LOW)
# define CFG_SBC_HRCW_BOOT_FLAGS (HRCW_CIP | HRCW_BMS)
#else
# define CFG_SBC_HRCW_BOOT_FLAGS (0)
#endif /* defined(CFG_SBC_BOOT_LOW) */
/* get the HRCW ISB field from CFG_IMMR */
#define CFG_SBC_HRCW_IMMR ( ((CFG_IMMR & 0x10000000) >> 10) | \
((CFG_IMMR & 0x01000000) >> 7) | \
((CFG_IMMR & 0x00100000) >> 4) )
#define CFG_HRCW_MASTER ( HRCW_BPS11 | \
HRCW_DPPC11 | \
CFG_SBC_HRCW_IMMR | \
HRCW_MMR00 | \
HRCW_LBPC11 | \
HRCW_APPC10 | \
HRCW_CS10PC00 | \
(CFG_SBC_MODCK_H & HRCW_MODCK_H1111) | \
CFG_SBC_HRCW_BOOT_FLAGS )
/* no slaves */
#define CFG_HRCW_SLAVE1 0
#define CFG_HRCW_SLAVE2 0
#define CFG_HRCW_SLAVE3 0
#define CFG_HRCW_SLAVE4 0
#define CFG_HRCW_SLAVE5 0
#define CFG_HRCW_SLAVE6 0
#define CFG_HRCW_SLAVE7 0
/*-----------------------------------------------------------------------
* Definitions for initial stack pointer and data area (in DPRAM)
*/
#define CFG_INIT_RAM_ADDR CFG_IMMR
#define CFG_INIT_RAM_END 0x4000 /* End of used area in DPRAM */
#define CFG_GBL_DATA_SIZE 128 /* bytes reserved for initial data */
#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
/*-----------------------------------------------------------------------
* Start addresses for the final memory configuration
* (Set up by the startup code)
* Please note that CFG_SDRAM_BASE _must_ start at 0
* Note also that the logic that sets CFG_RAMBOOT is platform dependent.
*/
#define CFG_MONITOR_BASE CFG_FLASH0_BASE
#if (CFG_MONITOR_BASE < CFG_FLASH_BASE)
# define CFG_RAMBOOT
#endif
#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */
#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */
/*
* For booting Linux, the board info and command line data
* have to be in the first 8 MB of memory, since this is
* the maximum mapped by the Linux kernel during initialization.
*/
#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
/*-----------------------------------------------------------------------
* FLASH and environment organization
*/
#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
#define CFG_MAX_FLASH_SECT 16 /* max number of sectors on one chip */
#define CFG_FLASH_ERASE_TOUT 8000 /* Timeout for Flash Erase (in ms) */
#define CFG_FLASH_WRITE_TOUT 1 /* Timeout for Flash Write (in ms) */
#ifndef CFG_RAMBOOT
# define CFG_ENV_IS_IN_FLASH 1
# ifdef CFG_ENV_IN_OWN_SECT
# define CFG_ENV_ADDR (CFG_MONITOR_BASE + 0x40000)
# define CFG_ENV_SECT_SIZE 0x40000
# else
# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_MONITOR_LEN - CFG_ENV_SECT_SIZE)
# define CFG_ENV_SIZE 0x1000 /* Total Size of Environment Sector */
# define CFG_ENV_SECT_SIZE 0x10000 /* see README - env sect real size */
# endif /* CFG_ENV_IN_OWN_SECT */
#else
# define CFG_ENV_IS_IN_NVRAM 1
# define CFG_ENV_ADDR (CFG_MONITOR_BASE - 0x1000)
# define CFG_ENV_SIZE 0x200
#endif /* CFG_RAMBOOT */
/*-----------------------------------------------------------------------
* Cache Configuration
*/
#define CFG_CACHELINE_SIZE 32 /* For MPC8260 CPU */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
#endif
/*-----------------------------------------------------------------------
* HIDx - Hardware Implementation-dependent Registers 2-11
*-----------------------------------------------------------------------
* HID0 also contains cache control - initially enable both caches and
* invalidate contents, then the final state leaves only the instruction
* cache enabled. Note that Power-On and Hard reset invalidate the caches,
* but Soft reset does not.
*
* HID1 has only read-only information - nothing to set.
*/
#define CFG_HID0_INIT (HID0_ICE |\
HID0_DCE |\
HID0_ICFI |\
HID0_DCI |\
HID0_IFEM |\
HID0_ABE)
#define CFG_HID0_FINAL (HID0_ICE |\
HID0_IFEM |\
HID0_ABE |\
HID0_EMCP)
#define CFG_HID2 0
/*-----------------------------------------------------------------------
* RMR - Reset Mode Register
*-----------------------------------------------------------------------
*/
#define CFG_RMR 0
/*-----------------------------------------------------------------------
* BCR - Bus Configuration 4-25
*-----------------------------------------------------------------------
*/
#define CFG_BCR (BCR_ETM)
/*-----------------------------------------------------------------------
* SIUMCR - SIU Module Configuration 4-31
*-----------------------------------------------------------------------
*/
#define CFG_SIUMCR (SIUMCR_DPPC11 |\
SIUMCR_L2CPC00 |\
SIUMCR_APPC10 |\
SIUMCR_MMR00)
/*-----------------------------------------------------------------------
* SYPCR - System Protection Control 11-9
* SYPCR can only be written once after reset!
*-----------------------------------------------------------------------
* Watchdog & Bus Monitor Timer max, 60x Bus Monitor enable
*/
#define CFG_SYPCR (SYPCR_SWTC |\
SYPCR_BMT |\
SYPCR_PBME |\
SYPCR_LBME |\
SYPCR_SWRI |\
SYPCR_SWP)
/*-----------------------------------------------------------------------
* TMCNTSC - Time Counter Status and Control 4-40
*-----------------------------------------------------------------------
* Clear once per Second and Alarm Interrupt Status, Set 32KHz timersclk,
* and enable Time Counter
*/
#define CFG_TMCNTSC (TMCNTSC_SEC |\
TMCNTSC_ALR |\
TMCNTSC_TCF |\
TMCNTSC_TCE)
/*-----------------------------------------------------------------------
* PISCR - Periodic Interrupt Status and Control 4-42
*-----------------------------------------------------------------------
* Clear Periodic Interrupt Status, Set 32KHz timersclk, and enable
* Periodic timer
*/
#define CFG_PISCR (PISCR_PS |\
PISCR_PTF |\
PISCR_PTE)
/*-----------------------------------------------------------------------
* SCCR - System Clock Control 9-8
*-----------------------------------------------------------------------
*/
#define CFG_SCCR 0
/*-----------------------------------------------------------------------
* RCCR - RISC Controller Configuration 13-7
*-----------------------------------------------------------------------
*/
#define CFG_RCCR 0
/*
* Initialize Memory Controller:
*
* Bank Bus Machine PortSz Device
* ---- --- ------- ------ ------
* 0 60x GPCM 32 bit FLASH (SIMM - 4MB) *
* 1 60x GPCM 32 bit FLASH (SIMM - Unused)
* 2 60x SDRAM 64 bit SDRAM (DIMM - 16MB or 64MB)
* 3 60x SDRAM 64 bit SDRAM (DIMM - Unused)
* 4 Local SDRAM 32 bit SDRAM (on board - 4MB)
* 5 60x GPCM 8 bit EEPROM (8KB)
* 6 60x GPCM 8 bit FLASH (on board - 2MB) *
* 7 60x GPCM 8 bit LEDs, switches
*
* (*) This configuration requires the SBC8260 be configured
* so that *CS0 goes to the FLASH SIMM, and *CS6 goes to
* the on board FLASH. In other words, JP24 should have
* pins 1 and 2 jumpered and pins 3 and 4 jumpered.
*
*/
/*-----------------------------------------------------------------------
* BR0,BR1 - Base Register
* Ref: Section 10.3.1 on page 10-14
* OR0,OR1 - Option Register
* Ref: Section 10.3.2 on page 10-18
*-----------------------------------------------------------------------
*/
/* Bank 0,1 - FLASH SIMM
*
* This expects the FLASH SIMM to be connected to *CS0
* It consists of 4 AM29F080B parts.
*
* Note: For the 4 MB SIMM, *CS1 is unused.
*/
/* BR0 is configured as follows:
*
* - Base address of 0x40000000
* - 32 bit port size
* - Data errors checking is disabled
* - Read and write access
* - GPCM 60x bus
* - Access are handled by the memory controller according to MSEL
* - Not used for atomic operations
* - No data pipelining is done
* - Valid
*/
#define CFG_BR0_PRELIM ((CFG_FLASH0_BASE & BRx_BA_MSK) |\
BRx_PS_32 |\
BRx_MS_GPCM_P |\
BRx_V)
/* OR0 is configured as follows:
*
* - 4 MB
* - *BCTL0 is asserted upon access to the current memory bank
* - *CW / *WE are negated a quarter of a clock earlier
* - *CS is output at the same time as the address lines
* - Uses a clock cycle length of 5
* - *PSDVAL is generated internally by the memory controller
* unless *GTA is asserted earlier externally.
* - Relaxed timing is generated by the GPCM for accesses
* initiated to this memory region.
* - One idle clock is inserted between a read access from the
* current bank and the next access.
*/
#define CFG_OR0_PRELIM (MEG_TO_AM(CFG_FLASH0_SIZE) |\
ORxG_CSNT |\
ORxG_ACS_DIV1 |\
ORxG_SCY_5_CLK |\
ORxG_TRLX |\
ORxG_EHTR)
/*-----------------------------------------------------------------------
* BR2,BR3 - Base Register
* Ref: Section 10.3.1 on page 10-14
* OR2,OR3 - Option Register
* Ref: Section 10.3.2 on page 10-16
*-----------------------------------------------------------------------
*/
/* Bank 2,3 - SDRAM DIMM
*
* 16MB DIMM: P/N
* 64MB DIMM: P/N 1W-8864X8-4-P1-EST
*
* Note: *CS3 is unused for this DIMM
*/
/* With a 16 MB or 64 MB DIMM, the BR2 is configured as follows:
*
* - Base address of 0x00000000
* - 64 bit port size (60x bus only)
* - Data errors checking is disabled
* - Read and write access
* - SDRAM 60x bus
* - Access are handled by the memory controller according to MSEL
* - Not used for atomic operations
* - No data pipelining is done
* - Valid
*/
#define CFG_BR2_PRELIM ((CFG_SDRAM0_BASE & BRx_BA_MSK) |\
BRx_PS_64 |\
BRx_MS_SDRAM_P |\
BRx_V)
#define CFG_BR3_PRELIM ((CFG_SDRAM0_BASE & BRx_BA_MSK) |\
BRx_PS_64 |\
BRx_MS_SDRAM_P |\
BRx_V)
/* With a 16 MB DIMM, the OR2 is configured as follows:
*
* - 16 MB
* - 2 internal banks per device
* - Row start address bit is A9 with PSDMR[PBI] = 0
* - 11 row address lines
* - Back-to-back page mode
* - Internal bank interleaving within save device enabled
*/
#if (CFG_SDRAM0_SIZE == 16)
#define CFG_OR2_PRELIM (MEG_TO_AM(CFG_SDRAM0_SIZE) |\
ORxS_BPD_2 |\
ORxS_ROWST_PBI0_A9 |\
ORxS_NUMR_11)
#endif
/* With a 64 MB DIMM, the OR2 is configured as follows:
*
* - 64 MB
* - 4 internal banks per device
* - Row start address bit is A8 with PSDMR[PBI] = 0
* - 12 row address lines
* - Back-to-back page mode
* - Internal bank interleaving within save device enabled
*/
#if (CFG_SDRAM0_SIZE == 64)
#define CFG_OR2_PRELIM (MEG_TO_AM(CFG_SDRAM0_SIZE) |\
ORxS_BPD_4 |\
ORxS_ROWST_PBI0_A8 |\
ORxS_NUMR_12)
#endif
/*-----------------------------------------------------------------------
* PSDMR - 60x Bus SDRAM Mode Register
* Ref: Section 10.3.3 on page 10-21
*-----------------------------------------------------------------------
*/
/* Address that the DIMM SPD memory lives at.
*/
#define SDRAM_SPD_ADDR 0x54
#if (CFG_SDRAM0_SIZE == 16)
/* With a 16 MB DIMM, the PSDMR is configured as follows:
*
* - Bank Based Interleaving,
* - Refresh Enable,
* - Address Multiplexing where A5 is output on A14 pin
* (A6 on A15, and so on),
* - use address pins A16-A18 as bank select,
* - A9 is output on SDA10 during an ACTIVATE command,
* - earliest timing for ACTIVATE command after REFRESH command is 7 clocks,
* - earliest timing for ACTIVATE or REFRESH command after PRECHARGE command
* is 3 clocks,
* - earliest timing for READ/WRITE command after ACTIVATE command is
* 2 clocks,
* - earliest timing for PRECHARGE after last data was read is 1 clock,
* - earliest timing for PRECHARGE after last data was written is 1 clock,
* - CAS Latency is 2.
*/
#define CFG_PSDMR (PSDMR_RFEN |\
PSDMR_SDAM_A14_IS_A5 |\
PSDMR_BSMA_A16_A18 |\
PSDMR_SDA10_PBI0_A9 |\
PSDMR_RFRC_7_CLK |\
PSDMR_PRETOACT_3W |\
PSDMR_ACTTORW_2W |\
PSDMR_LDOTOPRE_1C |\
PSDMR_WRC_1C |\
PSDMR_CL_2)
#endif
#if (CFG_SDRAM0_SIZE == 64)
/* With a 64 MB DIMM, the PSDMR is configured as follows:
*
* - Bank Based Interleaving,
* - Refresh Enable,
* - Address Multiplexing where A5 is output on A14 pin
* (A6 on A15, and so on),
* - use address pins A14-A16 as bank select,
* - A9 is output on SDA10 during an ACTIVATE command,
* - earliest timing for ACTIVATE command after REFRESH command is 7 clocks,
* - earliest timing for ACTIVATE or REFRESH command after PRECHARGE command
* is 3 clocks,
* - earliest timing for READ/WRITE command after ACTIVATE command is
* 2 clocks,
* - earliest timing for PRECHARGE after last data was read is 1 clock,
* - earliest timing for PRECHARGE after last data was written is 1 clock,
* - CAS Latency is 2.
*/
#define CFG_PSDMR (PSDMR_RFEN |\
PSDMR_SDAM_A14_IS_A5 |\
PSDMR_BSMA_A14_A16 |\
PSDMR_SDA10_PBI0_A9 |\
PSDMR_RFRC_7_CLK |\
PSDMR_PRETOACT_3W |\
PSDMR_ACTTORW_2W |\
PSDMR_LDOTOPRE_1C |\
PSDMR_WRC_1C |\
PSDMR_CL_2)
#endif
/*
* Shoot for approximately 1MHz on the prescaler.
*/
#if (CONFIG_8260_CLKIN == (66 * 1000 * 1000))
#define CFG_MPTPR MPTPR_PTP_DIV64
#elif (CONFIG_8260_CLKIN == (33 * 1000 * 1000))
#define CFG_MPTPR MPTPR_PTP_DIV32
#else
#warning "Unconfigured bus clock freq: check CFG_MPTPR and CFG_PSRT are OK"
#define CFG_MPTPR MPTPR_PTP_DIV32
#endif
#define CFG_PSRT 14
/* Bank 4 - On board SDRAM
*
* This is not implemented yet.
*/
/*-----------------------------------------------------------------------
* BR6 - Base Register
* Ref: Section 10.3.1 on page 10-14
* OR6 - Option Register
* Ref: Section 10.3.2 on page 10-18
*-----------------------------------------------------------------------
*/
/* Bank 6 - On board FLASH
*
* This expects the on board FLASH SIMM to be connected to *CS6
* It consists of 1 AM29F016A part.
*/
#if (defined(CFG_FLASH1_BASE) && defined(CFG_FLASH1_SIZE))
/* BR6 is configured as follows:
*
* - Base address of 0x60000000
* - 8 bit port size
* - Data errors checking is disabled
* - Read and write access
* - GPCM 60x bus
* - Access are handled by the memory controller according to MSEL
* - Not used for atomic operations
* - No data pipelining is done
* - Valid
*/
# define CFG_BR6_PRELIM ((CFG_FLASH1_BASE & BRx_BA_MSK) |\
BRx_PS_8 |\
BRx_MS_GPCM_P |\
BRx_V)
/* OR6 is configured as follows:
*
* - 2 MB
* - *BCTL0 is asserted upon access to the current memory bank
* - *CW / *WE are negated a quarter of a clock earlier
* - *CS is output at the same time as the address lines
* - Uses a clock cycle length of 5
* - *PSDVAL is generated internally by the memory controller
* unless *GTA is asserted earlier externally.
* - Relaxed timing is generated by the GPCM for accesses
* initiated to this memory region.
* - One idle clock is inserted between a read access from the
* current bank and the next access.
*/
# define CFG_OR6_PRELIM (MEG_TO_AM(CFG_FLASH1_SIZE) |\
ORxG_CSNT |\
ORxG_ACS_DIV1 |\
ORxG_SCY_5_CLK |\
ORxG_TRLX |\
ORxG_EHTR)
#endif /* (defined(CFG_FLASH1_BASE) && defined(CFG_FLASH1_SIZE)) */
/*-----------------------------------------------------------------------
* BR7 - Base Register
* Ref: Section 10.3.1 on page 10-14
* OR7 - Option Register
* Ref: Section 10.3.2 on page 10-18
*-----------------------------------------------------------------------
*/
/* Bank 7 - LEDs and switches
*
* LEDs are at 0x00001 (write only)
* switches are at 0x00001 (read only)
*/
#ifdef CFG_LED_BASE
/* BR7 is configured as follows:
*
* - Base address of 0xA0000000
* - 8 bit port size
* - Data errors checking is disabled
* - Read and write access
* - GPCM 60x bus
* - Access are handled by the memory controller according to MSEL
* - Not used for atomic operations
* - No data pipelining is done
* - Valid
*/
# define CFG_BR7_PRELIM ((CFG_LED_BASE & BRx_BA_MSK) |\
BRx_PS_8 |\
BRx_MS_GPCM_P |\
BRx_V)
/* OR7 is configured as follows:
*
* - 1 byte
* - *BCTL0 is asserted upon access to the current memory bank
* - *CW / *WE are negated a quarter of a clock earlier
* - *CS is output at the same time as the address lines
* - Uses a clock cycle length of 15
* - *PSDVAL is generated internally by the memory controller
* unless *GTA is asserted earlier externally.
* - Relaxed timing is generated by the GPCM for accesses
* initiated to this memory region.
* - One idle clock is inserted between a read access from the
* current bank and the next access.
*/
# define CFG_OR7_PRELIM (ORxG_AM_MSK |\
ORxG_CSNT |\
ORxG_ACS_DIV1 |\
ORxG_SCY_15_CLK |\
ORxG_TRLX |\
ORxG_EHTR)
#endif /* CFG_LED_BASE */
/*
* Internal Definitions
*
* Boot Flags
*/
#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
#define BOOTFLAG_WARM 0x02 /* Software reboot */
#endif /* __CONFIG_H */

113
include/galileo/pci.h Normal file
View File

@ -0,0 +1,113 @@
/* PCI.h - PCI functions header file */
/* Copyright - Galileo technology. */
#ifndef __INCpcih
#define __INCpcih
/* includes */
#include "core.h"
#include "memory.h"
/* According to PCI REV 2.1 MAX agents allowed on the bus are -21- */
#define PCI_MAX_DEVICES 22
/* Macros */
#define SELF 32
/* Defines for the access regions. */
#define PREFETCH_ENABLE BIT12
#define PREFETCH_DISABLE NO_BIT
#define DELAYED_READ_ENABLE BIT13
/* #define CACHING_ENABLE BIT14 */
/* aggressive prefetch: PCI slave prefetch two burst in advance*/
#define AGGRESSIVE_PREFETCH BIT16
/* read line aggresive prefetch: PCI slave prefetch two burst in advance*/
#define READ_LINE_AGGRESSIVE_PREFETCH BIT17
/* read multiple aggresive prefetch: PCI slave prefetch two burst in advance*/
#define READ_MULTI_AGGRESSIVE_PREFETCH BIT18
#define MAX_BURST_4 NO_BIT
#define MAX_BURST_8 BIT20 /* Bits[21:20] = 01 */
#define MAX_BURST_16 BIT21 /* Bits[21:20] = 10 */
#define PCI_BYTE_SWAP NO_BIT /* Bits[25:24] = 00 */
#define PCI_NO_SWAP BIT24 /* Bits[25:24] = 01 */
#define PCI_BYTE_AND_WORD_SWAP BIT25 /* Bits[25:24] = 10 */
#define PCI_WORD_SWAP (BIT24 | BIT25) /* Bits[25:24] = 11 */
#define PCI_ACCESS_PROTECT BIT28
#define PCI_WRITE_PROTECT BIT29
/* typedefs */
typedef enum __pciAccessRegions{REGION0,REGION1,REGION2,REGION3,REGION4,REGION5,
REGION6,REGION7} PCI_ACCESS_REGIONS;
typedef enum __pciAgentPrio{LOW_AGENT_PRIO,HI_AGENT_PRIO} PCI_AGENT_PRIO;
typedef enum __pciAgentPark{PARK_ON_AGENT,DONT_PARK_ON_AGENT} PCI_AGENT_PARK;
typedef enum __pciSnoopType{PCI_NO_SNOOP,PCI_SNOOP_WT,PCI_SNOOP_WB}
PCI_SNOOP_TYPE;
typedef enum __pciSnoopRegion{PCI_SNOOP_REGION0,PCI_SNOOP_REGION1,
PCI_SNOOP_REGION2,PCI_SNOOP_REGION3}
PCI_SNOOP_REGION;
typedef enum __memPciHost{PCI_HOST0,PCI_HOST1} PCI_HOST;
typedef enum __memPciRegion{PCI_REGION0,PCI_REGION1,
PCI_REGION2,PCI_REGION3,
PCI_IO}
PCI_REGION;
/* read/write configuration registers on local PCI bus. */
void pciWriteConfigReg(PCI_HOST host, unsigned int regOffset,
unsigned int pciDevNum, unsigned int data);
unsigned int pciReadConfigReg (PCI_HOST host, unsigned int regOffset,
unsigned int pciDevNum);
/* read/write configuration registers on another PCI bus. */
void pciOverBridgeWriteConfigReg(PCI_HOST host,
unsigned int regOffset,
unsigned int pciDevNum,
unsigned int busNum,unsigned int data);
unsigned int pciOverBridgeReadConfigReg(PCI_HOST host,
unsigned int regOffset,
unsigned int pciDevNum,
unsigned int busNum);
/* Master`s memory space */
bool pciMapSpace(PCI_HOST host, PCI_REGION region,
unsigned int remapBase,
unsigned int deviceBase,
unsigned int deviceLength);
unsigned int pciGetSpaceBase(PCI_HOST host, PCI_REGION region);
unsigned int pciGetSpaceSize(PCI_HOST host, PCI_REGION region);
/* Slave`s memory space */
void pciMapMemoryBank(PCI_HOST host, MEMORY_BANK bank,
unsigned int pci0Dram0Base, unsigned int pci0Dram0Size);
/* PCI region options */
bool pciSetRegionFeatures(PCI_HOST host, PCI_ACCESS_REGIONS region,
unsigned int features, unsigned int baseAddress,
unsigned int regionLength);
void pciDisableAccessRegion(PCI_HOST host, PCI_ACCESS_REGIONS region);
/* PCI arbiter */
bool pciArbiterEnable(PCI_HOST host);
bool pciArbiterDisable(PCI_HOST host);
bool pciParkingDisable(PCI_HOST host, PCI_AGENT_PARK internalAgent,
PCI_AGENT_PARK externalAgent0,
PCI_AGENT_PARK externalAgent1,
PCI_AGENT_PARK externalAgent2,
PCI_AGENT_PARK externalAgent3,
PCI_AGENT_PARK externalAgent4,
PCI_AGENT_PARK externalAgent5);
bool pciSetRegionSnoopMode(PCI_HOST host, PCI_SNOOP_REGION region,
PCI_SNOOP_TYPE snoopType,
unsigned int baseAddress,
unsigned int regionLength);
#endif /* __INCpcih */

208
include/jffs2/jffs2.h Normal file
View File

@ -0,0 +1,208 @@
/*
* JFFS2 -- Journalling Flash File System, Version 2.
*
* Copyright (C) 2001 Red Hat, Inc.
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* The original JFFS, from which the design for JFFS2 was derived,
* was designed and implemented by Axis Communications AB.
*
* The contents of this file are subject to the Red Hat eCos Public
* License Version 1.1 (the "Licence"); you may not use this file
* except in compliance with the Licence. You may obtain a copy of
* the Licence at http://www.redhat.com/
*
* Software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the Licence for the specific language governing rights and
* limitations under the Licence.
*
* The Original Code is JFFS2 - Journalling Flash File System, version 2
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the RHEPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
* $Id: jffs2.h,v 1.2 2002/01/17 00:53:20 nyet Exp $
*
*/
#ifndef __LINUX_JFFS2_H__
#define __LINUX_JFFS2_H__
#include <asm/types.h>
#include <jffs2/load_kernel.h>
#define JFFS2_SUPER_MAGIC 0x72b6
/* Values we may expect to find in the 'magic' field */
#define JFFS2_OLD_MAGIC_BITMASK 0x1984
#define JFFS2_MAGIC_BITMASK 0x1985
#define KSAMTIB_CIGAM_2SFFJ 0x5981 /* For detecting wrong-endian fs */
#define JFFS2_EMPTY_BITMASK 0xffff
#define JFFS2_DIRTY_BITMASK 0x0000
/* We only allow a single char for length, and 0xFF is empty flash so
we don't want it confused with a real length. Hence max 254.
*/
#define JFFS2_MAX_NAME_LEN 254
/* How small can we sensibly write nodes? */
#define JFFS2_MIN_DATA_LEN 128
#define JFFS2_COMPR_NONE 0x00
#define JFFS2_COMPR_ZERO 0x01
#define JFFS2_COMPR_RTIME 0x02
#define JFFS2_COMPR_RUBINMIPS 0x03
#define JFFS2_COMPR_COPY 0x04
#define JFFS2_COMPR_DYNRUBIN 0x05
#define JFFS2_COMPR_ZLIB 0x06
#define JFFS2_NUM_COMPR 7
/* Compatibility flags. */
#define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */
#define JFFS2_NODE_ACCURATE 0x2000
/* INCOMPAT: Fail to mount the filesystem */
#define JFFS2_FEATURE_INCOMPAT 0xc000
/* ROCOMPAT: Mount read-only */
#define JFFS2_FEATURE_ROCOMPAT 0x8000
/* RWCOMPAT_COPY: Mount read/write, and copy the node when it's GC'd */
#define JFFS2_FEATURE_RWCOMPAT_COPY 0x4000
/* RWCOMPAT_DELETE: Mount read/write, and delete the node when it's GC'd */
#define JFFS2_FEATURE_RWCOMPAT_DELETE 0x0000
#define JFFS2_NODETYPE_DIRENT (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 1)
#define JFFS2_NODETYPE_INODE (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 2)
#define JFFS2_NODETYPE_CLEANMARKER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3)
/* Maybe later... */
/*#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) */
/*#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4) */
/* Same as the non_ECC versions, but with extra space for real
* ECC instead of just the checksum. For use on NAND flash
*/
/*#define JFFS2_NODETYPE_DIRENT_ECC (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 5) */
/*#define JFFS2_NODETYPE_INODE_ECC (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 6) */
#define JFFS2_INO_FLAG_PREREAD 1 /* Do read_inode() for this one at
mount time, don't wait for it to
happen later */
#define JFFS2_INO_FLAG_USERCOMPR 2 /* User has requested a specific
compression type */
struct jffs2_unknown_node
{
/* All start like this */
__u16 magic;
__u16 nodetype;
__u32 totlen; /* So we can skip over nodes we don't grok */
__u32 hdr_crc;
} __attribute__((packed));
struct jffs2_raw_dirent
{
__u16 magic;
__u16 nodetype; /* == JFFS_NODETYPE_DIRENT */
__u32 totlen;
__u32 hdr_crc;
__u32 pino;
__u32 version;
__u32 ino; /* == zero for unlink */
__u32 mctime;
__u8 nsize;
__u8 type;
__u8 unused[2];
__u32 node_crc;
__u32 name_crc;
__u8 name[0];
} __attribute__((packed));
/* The JFFS2 raw inode structure: Used for storage on physical media. */
/* The uid, gid, atime, mtime and ctime members could be longer, but
are left like this for space efficiency. If and when people decide
they really need them extended, it's simple enough to add support for
a new type of raw node.
*/
struct jffs2_raw_inode
{
__u16 magic; /* A constant magic number. */
__u16 nodetype; /* == JFFS_NODETYPE_INODE */
__u32 totlen; /* Total length of this node (inc data, etc.) */
__u32 hdr_crc;
__u32 ino; /* Inode number. */
__u32 version; /* Version number. */
__u32 mode; /* The file's type or mode. */
__u16 uid; /* The file's owner. */
__u16 gid; /* The file's group. */
__u32 isize; /* Total resultant size of this inode (used for truncations) */
__u32 atime; /* Last access time. */
__u32 mtime; /* Last modification time. */
__u32 ctime; /* Change time. */
__u32 offset; /* Where to begin to write. */
__u32 csize; /* (Compressed) data size */
__u32 dsize; /* Size of the node's data. (after decompression) */
__u8 compr; /* Compression algorithm used */
__u8 usercompr; /* Compression algorithm requested by the user */
__u16 flags; /* See JFFS2_INO_FLAG_* */
__u32 data_crc; /* CRC for the (compressed) data. */
__u32 node_crc; /* CRC for the raw inode (excluding data) */
/* __u8 data[dsize]; */
} __attribute__((packed));
union jffs2_node_union {
struct jffs2_raw_inode i;
struct jffs2_raw_dirent d;
struct jffs2_unknown_node u;
} __attribute__((packed));
enum
{
DT_UNKNOWN = 0,
# define DT_UNKNOWN DT_UNKNOWN
DT_FIFO = 1,
# define DT_FIFO DT_FIFO
DT_CHR = 2,
# define DT_CHR DT_CHR
DT_DIR = 4,
# define DT_DIR DT_DIR
DT_BLK = 6,
# define DT_BLK DT_BLK
DT_REG = 8,
# define DT_REG DT_REG
DT_LNK = 10,
# define DT_LNK DT_LNK
DT_SOCK = 12,
# define DT_SOCK DT_SOCK
DT_WHT = 14
# define DT_WHT DT_WHT
};
u32 jffs2_1pass_ls(struct part_info *part,const char *fname);
u32 jffs2_1pass_load(char *dest, struct part_info *part,const char *fname);
u32 jffs2_1pass_info(struct part_info *part);
void rtime_decompress(unsigned char *data_in, unsigned char *cpage_out, u32
srclen, u32 destlen);
void rubin_do_decompress(unsigned char *bits, unsigned char *in, unsigned char
*page_out, __u32 destlen);
void dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out,
unsigned long sourcelen, unsigned long dstlen);
long zlib_decompress(unsigned char *data_in, unsigned char *cpage_out,
__u32 srclen, __u32 destlen);
#endif /* __LINUX_JFFS2_H__ */

View File

@ -0,0 +1,76 @@
#ifndef load_kernel_h
#define load_kernel_h
/*-------------------------------------------------------------------------
* Filename: load_kernel.h
* Version: $Id: load_kernel.h,v 1.3 2002/01/25 01:34:11 nyet Exp $
* Copyright: Copyright (C) 2001, Russ Dill
* Author: Russ Dill <Russ.Dill@asu.edu>
* Description: header for load kernel modules
*-----------------------------------------------------------------------*/
/*
*
* 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
*
*/
/* this struct is very similar to mtd_info */
struct part_info {
u32 size; /* Total size of the Partition */
/* "Major" erase size for the device. Naïve users may take this
* to be the only erase size available, or may use the more detailed
* information below if they desire
*/
u32 erasesize;
/* Where in memory does this partition start? */
char *offset;
/* used by jffs2 set to NULL */
void *jffs2_priv;
/* private filed used by user */
void *usr_priv;
};
struct part_info*
jffs2_part_info(int part_num);
struct kernel_loader {
/* Return true if there is a kernel contained at src */
int (* check_magic)(struct part_info *part);
/* load the kernel from the partition part to dst, return the number
* of bytes copied if successful, zero if not */
u32 (* load_kernel)(u32 *dst, struct part_info *part, const char *kernel_filename);
/* A brief description of the module (ie, "cramfs") */
char *name;
};
#define ldr_strlen strlen
#define ldr_strncmp strncmp
#define ldr_memcpy memcpy
#define putstr(x) printf("%s", x)
#define mmalloc malloc
#define UDEBUG printf
#define putnstr(str, size) printf("%*.*s", size, size, str)
#define ldr_output_string(x) puts(x)
#define putLabeledWord(x, y) printf("%s %08x\n", x, (unsigned int)y)
#define led_blink(x, y, z, a)
#endif /* load_kernel_h */

39
include/lcd.h Normal file
View File

@ -0,0 +1,39 @@
/*
* MPC823 LCD Controller
*
* Modeled after video interface by Paolo Scaffardi
*
*
* (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
*/
#ifndef _LCD_H_
#define _LCD_H_
/* Video functions */
int lcd_init (void *lcdbase);
void lcd_putc (const char c);
void lcd_puts (const char *s);
void lcd_printf (const char *fmt, ...);
#endif

1524
include/pci_ids.h Normal file

File diff suppressed because it is too large Load Diff

148
include/video_ad7177.h Normal file
View File

@ -0,0 +1,148 @@
/*
* (C) Copyright 2000
* Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef _VIDEO_AD7177_H_
#define _VIDEO_AD7177_H_
/*#define VIDEO_DEBUG_DISABLE_COLORS 0 */
#define VIDEO_ENCODER_NAME "Analog Devices AD7177"
#define VIDEO_ENCODER_I2C_RATE 100000 /* Max rate is 100Khz */
#define VIDEO_ENCODER_CB_Y_CR_Y /* Use CB Y CR Y format... */
#define VIDEO_MODE_YUYV /* The only mode supported by this encoder */
#undef VIDEO_MODE_RGB
#define VIDEO_MODE_BPP 16
#ifdef VIDEO_MODE_PAL
#define VIDEO_ACTIVE_COLS 720
#define VIDEO_ACTIVE_ROWS 576
#define VIDEO_VISIBLE_COLS 640
#define VIDEO_VISIBLE_ROWS 480
#endif
#ifdef VIDEO_MODE_NTSC
#define VIDEO_ACTIVE_COLS 720
#define VIDEO_ACTIVE_ROWS 525
#define VIDEO_VISIBLE_COLS 640
#define VIDEO_VISIBLE_ROWS 400
#endif
static unsigned char
video_encoder_data[] = {
#ifdef VIDEO_MODE_NTSC
0x04, /* Mode Register 0 */
#ifdef VIDEO_DEBUG_COLORBARS
0xc2,
#else
0x42, /* Mode Register 1 */
#endif
0x16, /* Subcarrier Freq 0 */
0x7c, /* Subcarrier Freq 1 */
0xf0, /* Subcarrier Freq 2 */
0x21, /* Subcarrier Freq 3 */
0x00, /* Subcarrier phase */
0x02, /* Timing Register 0 */
0x00, /* Extended Captioning 0 */
0x00, /* Extended Captioning 1 */
0x00, /* Closed Captioning 0 */
0x00, /* Closed Captioning 1 */
0x00, /* Timing Register 1 */
0x08, /* Mode Register 2 */
0x00, /* Pedestal Register 0 */
0x00, /* Pedestal Register 1 */
0x00, /* Pedestal Register 2 */
0x00, /* Pedestal Register 3 */
0x08 /* Mode Register 3 */
#endif
#ifdef VIDEO_MODE_PAL
#ifdef VIDEO_MODE_RGB_OUT
0x69, /* Mode Register 0 */
#ifdef VIDEO_DEBUG_COLORBARS
0xc0, /* Mode Register 1 (c0) */
#else
0x40, /* Mode Register 1 (c0) */
#endif
0xcb, /* Subcarrier Freq 0 */
0x8a, /* Subcarrier Freq 1 */
0x09, /* Subcarrier Freq 2 */
0x2a, /* Subcarrier Freq 3 */
0x00, /* Subcarrier phase */
0x02, /* Timing Register 0 */
0x00, /* Extended Captioning 0 */
0x00, /* Extended Captioning 1 */
0x00, /* Closed Captioning 0 */
0x00, /* Closed Captioning 1 */
0x00, /* Timing Register 1 */
0x28, /* Mode Register 2 */
0x00, /* Pedestal Register 0 */
0x00, /* Pedestal Register 1 */
0x00, /* Pedestal Register 2 */
0x00, /* Pedestal Register 3 */
0x08 /* Mode Register 3 */
#else
0x09, /* Mode Register 0 (was 01) */
#ifdef VIDEO_DEBUG_COLORBARS
0xd8, /* */
#else
0x59, /* Mode Register 1 (was 58) */
#endif
0xcb, /* Subcarrier Freq 0 */
0x8a, /* Subcarrier Freq 1 */
0x09, /* Subcarrier Freq 2 */
0x2a, /* Subcarrier Freq 3 */
0x00, /* Subcarrier phase */
0x02, /* Timing Register 0 (was a) */
0x00, /* Extended Captioning 0 */
0x00, /* Extended Captioning 1 */
0x00, /* Closed Captioning 0 */
0x00, /* Closed Captioning 1 */
0x00, /* Timing Register 1 */
#ifdef VIDEO_DEBUG_LOWPOWER
#ifdef VIDEO_DEBUG_DISABLE_COLORS
0x98, /* Mode Register 2 */
#else
0x88, /* Mode Register 2 */
#endif
#else
#ifdef VIDEO_DEBUG_DISABLE_COLORS
0x18, /* Mode Register 2 */
#else
0x08, /* Mode Register 2 */
#endif
#endif
0x00, /* Pedestal Register 0 */
0x00, /* Pedestal Register 1 */
0x00, /* Pedestal Register 2 */
0x00, /* Pedestal Register 3 */
0x08 /* Mode Register 3 */
#endif
#endif
} ;
#endif

1951
include/video_logo.h Normal file

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More