1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter.git synced 2025-03-09 15:40:20 +00:00

Kernel 5.4 RUTX support

This commit is contained in:
Ycarus (Yannick Chabanois) 2023-08-14 17:47:02 +02:00
parent 839fcf1cab
commit cfce9f52b2
7376 changed files with 3902 additions and 546 deletions

View file

@ -0,0 +1,774 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#include <common.h>
#include <command.h>
#include <video_fb.h>
#include "common_util.h"
#include <asm/processor.h>
#include <asm/byteorder.h>
#include <i2c.h>
#include <pci.h>
#include <malloc.h>
#include <bzlib.h>
#ifdef CONFIG_PIP405
#include "../pip405/pip405.h"
#include <asm/4xx_pci.h>
#endif
#ifdef CONFIG_MIP405
#include "../mip405/mip405.h"
#include <asm/4xx_pci.h>
#endif
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_PATI)
#define FIRM_START 0xFFF00000
#endif
extern int mem_test(ulong start, ulong ramsize, int quiet);
#define I2C_BACKUP_ADDR 0x7C00 /* 0x200 bytes for backup */
#define IMAGE_SIZE CONFIG_SYS_MONITOR_LEN /* ugly, but it works for now */
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
/*-----------------------------------------------------------------------
* On PIP/MIP405 we have 3 (4) possible boot mode
*
* - Boot from Flash (Flash CS = CS0, MPS CS = CS1)
* - Boot from MPS (Flash CS = CS1, MPS CS = CS0)
* - Boot from PCI with Flash map (Flash CS = CS0, MPS CS = CS1)
* - Boot from PCI with MPS map (Flash CS = CS1, MPS CS = CS0)
* The flash init is the first board specific routine which is called
* after code relocation (running from SDRAM)
* The first thing we do is to map the Flash CS to the Flash area and
* the MPS CS to the MPS area. Since the flash size is unknown at this
* point, we use the max flash size and the lowest flash address as base.
*
* After flash detection we adjust the size of the CS area accordingly.
* update_flash_size() will fix in wrong values in the flash_info structure,
* misc_init_r() will fix the values in the board info structure
*/
int get_boot_mode(void)
{
unsigned long pbcr;
int res = 0;
pbcr = mfdcr(CPC0_PSR);
if ((pbcr & PSR_ROM_WIDTH_MASK) == 0)
/* boot via MPS or MPS mapping */
res = BOOT_MPS;
if (pbcr & PSR_ROM_LOC)
/* boot via PCI.. */
res |= BOOT_PCI;
return res;
}
/* Map the flash high (in boot area)
This code can only be executed from SDRAM (after relocation).
*/
void setup_cs_reloc(void)
{
int mode;
/*
* since we are relocated, we can set-up the CS finaly
* but first of all, switch off PCI mapping (in case it
* was a PCI boot)
*/
out32r(PMM0MA, 0L);
/* get boot mode */
mode = get_boot_mode();
/*
* we map the flash high in every case
* first find out to which CS the flash is attached to
*/
if (mode & BOOT_MPS) {
/* map flash high on CS1 and MPS on CS0 */
mtdcr(EBC0_CFGADDR, PB0AP);
mtdcr(EBC0_CFGDATA, MPS_AP);
mtdcr(EBC0_CFGADDR, PB0CR);
mtdcr(EBC0_CFGDATA, MPS_CR);
/*
* we use the default values (max values) for the flash
* because its real size is not yet known
*/
mtdcr(EBC0_CFGADDR, PB1AP);
mtdcr(EBC0_CFGDATA, FLASH_AP);
mtdcr(EBC0_CFGADDR, PB1CR);
mtdcr(EBC0_CFGDATA, FLASH_CR_B);
} else {
/* map flash high on CS0 and MPS on CS1 */
mtdcr(EBC0_CFGADDR, PB1AP);
mtdcr(EBC0_CFGDATA, MPS_AP);
mtdcr(EBC0_CFGADDR, PB1CR);
mtdcr(EBC0_CFGDATA, MPS_CR);
/*
* we use the default values (max values) for the flash
* because its real size is not yet known
*/
mtdcr(EBC0_CFGADDR, PB0AP);
mtdcr(EBC0_CFGDATA, FLASH_AP);
mtdcr(EBC0_CFGADDR, PB0CR);
mtdcr(EBC0_CFGDATA, FLASH_CR_B);
}
}
#endif /* #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) */
#ifdef CONFIG_SYS_UPDATE_FLASH_SIZE
/* adjust flash start and protection info */
int update_flash_size(int flash_size)
{
int i = 0, mode;
flash_info_t *info = &flash_info[0];
unsigned long flashcr;
unsigned long flash_base = (0 - flash_size) & 0xFFF00000;
if (flash_size > 128*1024*1024) {
printf("\n ### ERROR, wrong flash size: %X, reset board ###\n",
flash_size);
hang();
}
if ((flash_size >> 20) != 0)
i = __ilog2(flash_size >> 20);
/* set up flash CS according to the size */
mode = get_boot_mode();
if (mode & BOOT_MPS) {
/* flash is on CS1 */
mtdcr(EBC0_CFGADDR, PB1CR);
flashcr = mfdcr(EBC0_CFGDATA);
/* we map the flash high in every case */
flashcr &= 0x0001FFFF; /* mask out address bits */
flashcr |= flash_base; /* start addr */
flashcr |= (i << 17); /* size addr */
mtdcr(EBC0_CFGADDR, PB1CR);
mtdcr(EBC0_CFGDATA, flashcr);
} else {
/* flash is on CS0 */
mtdcr(EBC0_CFGADDR, PB0CR);
flashcr = mfdcr(EBC0_CFGDATA);
/* we map the flash high in every case */
flashcr &= 0x0001FFFF; /* mask out address bits */
flashcr |= flash_base; /* start addr */
flashcr |= (i << 17); /* size addr */
mtdcr(EBC0_CFGADDR, PB0CR);
mtdcr(EBC0_CFGDATA, flashcr);
}
for (i = 0; i < info->sector_count; i++)
/* adjust sector start address */
info->start[i] = flash_base +
(info->start[i] - CONFIG_SYS_FLASH_BASE);
/* unprotect all sectors */
flash_protect(FLAG_PROTECT_CLEAR,
info->start[0],
0xFFFFFFFF,
info);
flash_protect_default();
/* protect reset vector too*/
flash_protect(FLAG_PROTECT_SET,
info->start[info->sector_count-1],
0xFFFFFFFF,
info);
return 0;
}
#endif
static int
mpl_prg(uchar *src, ulong size)
{
ulong start;
flash_info_t *info = &flash_info[0];
int i, rc;
#if defined(CONFIG_PATI)
int start_sect;
#endif
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI)
char *copystr = (char *)src;
ulong *magic = (ulong *)src;
#endif
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI)
if (uimage_to_cpu (magic[0]) != IH_MAGIC) {
puts("Bad Magic number\n");
return -1;
}
/* some more checks before we delete the Flash... */
/* Checking the ISO_STRING prevents to program a
* wrong Firmware Image into the flash.
*/
i = 4; /* skip Magic number */
while (1) {
if (strncmp(&copystr[i], "MEV-", 4) == 0)
break;
if (i++ >= 0x100) {
puts("Firmware Image for unknown Target\n");
return -1;
}
}
/* we have the ISO STRING, check */
if (strncmp(&copystr[i], CONFIG_ISO_STRING, sizeof(CONFIG_ISO_STRING)-1) != 0) {
printf("Wrong Firmware Image: %s\n", &copystr[i]);
return -1;
}
#if !defined(CONFIG_PATI)
start = 0 - size;
/* unprotect sectors used by u-boot */
flash_protect(FLAG_PROTECT_CLEAR,
start,
0xFFFFFFFF,
info);
/* search start sector */
for (i = info->sector_count-1; i > 0; i--)
if (start >= info->start[i])
break;
/* now erase flash */
printf("Erasing at %lx (sector %d) (start %lx)\n",
start,i,info->start[i]);
if ((rc = flash_erase (info, i, info->sector_count-1)) != 0) {
puts("ERROR ");
flash_perror(rc);
return (1);
}
#else /* #if !defined(CONFIG_PATI */
start = FIRM_START;
start_sect = -1;
/* search start sector */
for (i = info->sector_count-1; i > 0; i--)
if (start >= info->start[i])
break;
start_sect = i;
for (i = info->sector_count-1; i > 0; i--)
if ((start + size) >= info->start[i])
break;
/* unprotect sectors used by u-boot */
flash_protect(FLAG_PROTECT_CLEAR,
start,
start + size,
info);
/* now erase flash */
printf ("Erasing at %lx to %lx (sector %d to %d) (%lx to %lx)\n",
start, start + size, start_sect, i,
info->start[start_sect], info->start[i]);
if ((rc = flash_erase (info, start_sect, i)) != 0) {
puts ("ERROR ");
flash_perror (rc);
return (1);
}
#endif /* defined(CONFIG_PATI) */
#elif defined(CONFIG_VCMA9)
start = 0;
/* search end sector */
for (i = 0; i < info->sector_count; i++)
if (size < info->start[i])
break;
flash_protect(FLAG_PROTECT_CLEAR,
start,
size,
info);
/* now erase flash */
printf("Erasing at %lx (sector %d) (start %lx)\n",
start,0,info->start[0]);
if ((rc = flash_erase (info, 0, i)) != 0) {
puts("ERROR ");
flash_perror(rc);
return (1);
}
#endif
printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",
(ulong)src, size);
if ((rc = flash_write ((char *)src, start, size)) != 0) {
puts("ERROR ");
flash_perror(rc);
return (1);
}
puts("OK programming done\n");
return 0;
}
static int
mpl_prg_image(uchar *ld_addr)
{
unsigned long len;
uchar *data;
image_header_t *hdr = (image_header_t *)ld_addr;
int rc;
#if defined(CONFIG_FIT)
if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
puts ("Non legacy image format not supported\n");
return -1;
}
#endif
if (!image_check_magic (hdr)) {
puts("Bad Magic Number\n");
return 1;
}
image_print_contents (hdr);
if (!image_check_os (hdr, IH_OS_U_BOOT)) {
puts("No U-Boot Image\n");
return 1;
}
if (!image_check_type (hdr, IH_TYPE_FIRMWARE)) {
puts("No Firmware Image\n");
return 1;
}
if (!image_check_hcrc (hdr)) {
puts("Bad Header Checksum\n");
return 1;
}
puts("Verifying Checksum ... ");
if (!image_check_dcrc (hdr)) {
puts("Bad Data CRC\n");
return 1;
}
puts("OK\n");
data = (uchar *)image_get_data (hdr);
len = image_get_data_size (hdr);
if (image_get_comp (hdr) != IH_COMP_NONE) {
uchar *buf;
/* reserve space for uncompressed image */
if ((buf = malloc(IMAGE_SIZE)) == NULL) {
puts("Insufficient space for decompression\n");
return 1;
}
switch (image_get_comp (hdr)) {
case IH_COMP_GZIP:
puts("Uncompressing (GZIP) ... ");
rc = gunzip ((void *)(buf), IMAGE_SIZE, data, &len);
if (rc != 0) {
puts("GUNZIP ERROR\n");
free(buf);
return 1;
}
puts("OK\n");
break;
#ifdef CONFIG_BZIP2
case IH_COMP_BZIP2:
puts("Uncompressing (BZIP2) ... ");
{
uint retlen = IMAGE_SIZE;
rc = BZ2_bzBuffToBuffDecompress ((char *)(buf), &retlen,
(char *)data, len, 0, 0);
len = retlen;
}
if (rc != BZ_OK) {
printf ("BUNZIP2 ERROR: %d\n", rc);
free(buf);
return 1;
}
puts("OK\n");
break;
#endif
default:
printf ("Unimplemented compression type %d\n",
image_get_comp (hdr));
free(buf);
return 1;
}
rc = mpl_prg(buf, len);
free(buf);
} else {
rc = mpl_prg(data, len);
}
return(rc);
}
#if !defined(CONFIG_PATI)
void get_backup_values(backup_t *buf)
{
i2c_read(CONFIG_SYS_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)buf,sizeof(backup_t));
}
void set_backup_values(int overwrite)
{
backup_t back;
int i;
get_backup_values(&back);
if(!overwrite) {
if(strncmp(back.signature,"MPL\0",4)==0) {
puts("Not possible to write Backup\n");
return;
}
}
memcpy(back.signature,"MPL\0",4);
i = getenv_f("serial#",back.serial_name,16);
if(i < 0) {
puts("Not possible to write Backup\n");
return;
}
back.serial_name[16]=0;
i = getenv_f("ethaddr",back.eth_addr,20);
if(i < 0) {
puts("Not possible to write Backup\n");
return;
}
back.eth_addr[20]=0;
i2c_write(CONFIG_SYS_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
}
void clear_env_values(void)
{
backup_t back;
unsigned char env_crc[4];
memset(&back,0xff,sizeof(backup_t));
memset(env_crc,0x00,4);
i2c_write(CONFIG_SYS_DEF_EEPROM_ADDR,I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
i2c_write(CONFIG_SYS_DEF_EEPROM_ADDR,CONFIG_ENV_OFFSET,2,(void *)env_crc,4);
}
/*
* check crc of "older" environment
*/
int check_env_old_size(ulong oldsize)
{
ulong crc, len, new;
unsigned off;
uchar buf[64];
/* read old CRC */
eeprom_read (CONFIG_SYS_DEF_EEPROM_ADDR,
CONFIG_ENV_OFFSET,
(uchar *)&crc, sizeof(ulong));
new = 0;
len = oldsize;
off = sizeof(long);
len = oldsize-off;
while (len > 0) {
int n = (len > sizeof(buf)) ? sizeof(buf) : len;
eeprom_read (CONFIG_SYS_DEF_EEPROM_ADDR, CONFIG_ENV_OFFSET+off, buf, n);
new = crc32 (new, buf, n);
len -= n;
off += n;
}
return (crc == new);
}
static ulong oldsizes[] = {
0x200,
0x800,
0
};
void copy_old_env(ulong size)
{
uchar name_buf[64];
uchar value_buf[0x800];
uchar c;
ulong len;
unsigned off;
uchar *name, *value;
name = &name_buf[0];
value = &value_buf[0];
len=size;
off = sizeof(long);
while (len > off) {
eeprom_read (CONFIG_SYS_DEF_EEPROM_ADDR, CONFIG_ENV_OFFSET+off, &c, 1);
if(c != '=') {
*name++=c;
off++;
}
else {
*name++='\0';
off++;
do {
eeprom_read (CONFIG_SYS_DEF_EEPROM_ADDR, CONFIG_ENV_OFFSET+off, &c, 1);
*value++=c;
off++;
if(c == '\0')
break;
} while(len > off);
name = &name_buf[0];
value = &value_buf[0];
if(strncmp((char *)name,"baudrate",8)!=0) {
setenv((char *)name,(char *)value);
}
}
}
}
void check_env(void)
{
char *s;
int i=0;
char buf[32];
backup_t back;
s=getenv("serial#");
if(!s) {
while(oldsizes[i]) {
if(check_env_old_size(oldsizes[i]))
break;
i++;
}
if(!oldsizes[i]) {
/* no old environment has been found */
get_backup_values (&back);
if (strncmp (back.signature, "MPL\0", 4) == 0) {
sprintf (buf, "%s", back.serial_name);
setenv ("serial#", buf);
sprintf (buf, "%s", back.eth_addr);
setenv ("ethaddr", buf);
printf ("INFO: serial# and ethaddr recovered, use saveenv\n");
return;
}
}
else {
copy_old_env(oldsizes[i]);
puts("INFO: old environment ajusted, use saveenv\n");
}
}
else {
/* check if back up is set */
get_backup_values(&back);
if(strncmp(back.signature,"MPL\0",4)!=0) {
set_backup_values(0);
}
}
}
#endif /* #if !defined(CONFIG_PATI) */
int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
ulong ld_addr;
int result;
#if !defined(CONFIG_PATI)
ulong size = IMAGE_SIZE;
ulong src = MULTI_PURPOSE_SOCKET_ADDR;
backup_t back;
#endif
if (strcmp(argv[1], "flash") == 0)
{
#if defined(CONFIG_CMD_FDC)
if (strcmp(argv[2], "floppy") == 0) {
char *local_args[3];
extern int do_fdcboot (cmd_tbl_t *, int, int, char *[]);
puts("\nupdating bootloader image from floppy\n");
local_args[0] = argv[0];
if(argc==4) {
local_args[1] = argv[3];
local_args[2] = NULL;
ld_addr=simple_strtoul(argv[3], NULL, 16);
result=do_fdcboot(cmdtp, 0, 2, local_args);
}
else {
local_args[1] = NULL;
ld_addr=CONFIG_SYS_LOAD_ADDR;
result=do_fdcboot(cmdtp, 0, 1, local_args);
}
result=mpl_prg_image((uchar *)ld_addr);
return result;
}
#endif
if (strcmp(argv[2], "mem") == 0) {
if(argc==4) {
ld_addr=simple_strtoul(argv[3], NULL, 16);
}
else {
ld_addr=load_addr;
}
printf ("\nupdating bootloader image from memory at %lX\n",ld_addr);
result=mpl_prg_image((uchar *)ld_addr);
return result;
}
#if !defined(CONFIG_PATI)
if (strcmp(argv[2], "mps") == 0) {
puts("\nupdating bootloader image from MPS\n");
result=mpl_prg((uchar *)src,size);
return result;
}
#endif /* #if !defined(CONFIG_PATI) */
}
#if !defined(CONFIG_PATI)
if (strcmp(argv[1], "clearenvvalues") == 0)
{
if (strcmp(argv[2], "yes") == 0)
{
clear_env_values();
return 0;
}
}
if (strcmp(argv[1], "getback") == 0) {
get_backup_values(&back);
back.signature[3]=0;
back.serial_name[16]=0;
back.eth_addr[20]=0;
printf("GetBackUp: signature: %s\n",back.signature);
printf(" serial#: %s\n",back.serial_name);
printf(" ethaddr: %s\n",back.eth_addr);
return 0;
}
if (strcmp(argv[1], "setback") == 0) {
set_backup_values(1);
return 0;
}
#endif
return cmd_usage(cmdtp);
}
#if defined(CONFIG_CMD_DOC)
void doc_init (void)
{
doc_probe(MULTI_PURPOSE_SOCKET_ADDR);
}
#endif
#ifdef CONFIG_VIDEO
/******************************************************
* Routines to display the Board information
* to the screen (since the VGA will be initialized as last,
* we must resend the infos)
*/
#ifdef CONFIG_CONSOLE_EXTRA_INFO
extern GraphicDevice ctfb;
extern int get_boot_mode(void);
void video_get_info_str (int line_number, char *info)
{
/* init video info strings for graphic console */
PPC4xx_SYS_INFO sys_info;
char rev;
int i,boot;
unsigned long pvr;
char buf[64];
char buf1[32], buf2[32], buf3[32], buf4[32];
char cpustr[16];
char *s, *e, bc;
switch (line_number)
{
case 2:
/* CPU and board infos */
pvr=get_pvr();
get_sys_info (&sys_info);
switch (pvr) {
case PVR_405GP_RB: rev='B'; break;
case PVR_405GP_RC: rev='C'; break;
case PVR_405GP_RD: rev='D'; break;
case PVR_405GP_RE: rev='E'; break;
case PVR_405GPR_RB: rev='B'; break;
default: rev='?'; break;
}
if(pvr==PVR_405GPR_RB)
sprintf(cpustr,"PPC405GPr %c",rev);
else
sprintf(cpustr,"PPC405GP %c",rev);
/* Board info */
i=0;
s=getenv ("serial#");
#ifdef CONFIG_PIP405
if (!s || strncmp (s, "PIP405", 6)) {
sprintf(buf,"### No HW ID - assuming PIP405");
}
#endif
#ifdef CONFIG_MIP405
if (!s || strncmp (s, "MIP405", 6)) {
sprintf(buf,"### No HW ID - assuming MIP405");
}
#endif
else {
for (e = s; *e; ++e) {
if (*e == ' ')
break;
}
for (; s < e; ++s) {
if (*s == '_') {
++s;
break;
}
buf[i++] = *s;
}
sprintf(&buf[i]," SN ");
i+=4;
for (; s < e; ++s) {
buf[i++] = *s;
}
buf[i++]=0;
}
sprintf (info," %s %s %s MHz (%s/%s/%s MHz)",
buf, cpustr,
strmhz (buf1, gd->cpu_clk),
strmhz (buf2, sys_info.freqPLB),
strmhz (buf3, sys_info.freqPLB / sys_info.pllOpbDiv),
strmhz (buf4, sys_info.freqPLB / sys_info.pllExtBusDiv));
return;
case 3:
/* Memory Info */
boot = get_boot_mode();
bc = in8 (CONFIG_PORT_ADDR);
sprintf(info, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s",
gd->bd->bi_memsize / 0x100000,
gd->bd->bi_flashsize / 0x100000,
bc,
(boot & BOOT_MPS) ? "MPS boot" : "Flash boot",
ctfb.modeIdent);
return;
case 1:
sprintf (buf, "%s",CONFIG_IDENT_STRING);
sprintf (info, " %s", &buf[1]);
return;
}
/* no more info lines */
*info = 0;
return;
}
#endif /* CONFIG_CONSOLE_EXTRA_INFO */
#endif /* CONFIG_VIDEO */

View file

@ -0,0 +1,49 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* 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 _COMMON_UTIL_H_
#define _COMMON_UTIL_H_
typedef struct {
char signature[4];
char serial_name[17]; /* "MIP405_1000xxxxx" */
char eth_addr[21]; /* "00:60:C2:0a:00:00" */
} backup_t;
extern flash_info_t flash_info[]; /* info for FLASH chips */
void get_backup_values(backup_t *buf);
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
#define BOOT_MPS 0x01
#define BOOT_PCI 0x02
int get_boot_mode(void);
void setup_cs_reloc(void);
#endif
void check_env(void);
#if defined(CONFIG_CMD_DOC)
void doc_init (void);
#endif
#endif /* _COMMON_UTIL_H_ */

View file

@ -0,0 +1,494 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland
*
* 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
*
*
* TODO: clean-up
*/
#include <common.h>
#include <asm/processor.h>
#include <stdio_dev.h>
#include "isa.h"
#include "piix4_pci.h"
#include "kbd.h"
#include "video.h"
#undef ISA_DEBUG
#ifdef ISA_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#if defined(CONFIG_PIP405)
extern int drv_isa_kbd_init (void);
/* fdc (logical device 0) */
const SIO_LOGDEV_TABLE sio_fdc[] = {
{0x60, 3}, /* set IO to FDPort (3F0) */
{0x61, 0xF0}, /* set IO to FDPort (3F0) */
{0x70, 06}, /* set IRQ 6 for FDPort */
{0x74, 02}, /* set DMA 2 for FDPort */
{0xF0, 0x05}, /* set to PS2 type */
{0xF1, 0x00}, /* default value */
{0x30, 1}, /* and activate the device */
{0xFF, 0} /* end of device table */
};
/* paralell port (logical device 3) */
const SIO_LOGDEV_TABLE sio_pport[] = {
{0x60, 3}, /* set IO to PPort (378) */
{0x61, 0x78}, /* set IO to PPort (378) */
{0x70, 07}, /* set IRQ 7 for PPort */
{0xF1, 00}, /* set PPort to normal */
{0x30, 1}, /* and activate the device */
{0xFF, 0} /* end of device table */
};
/* paralell port (logical device 3) Floppy assigned to lpt */
const SIO_LOGDEV_TABLE sio_pport_fdc[] = {
{0x60, 3}, /* set IO to PPort (378) */
{0x61, 0x78}, /* set IO to PPort (378) */
{0x70, 07}, /* set IRQ 7 for PPort */
{0xF1, 02}, /* set PPort to Floppy */
{0x30, 1}, /* and activate the device */
{0xFF, 0} /* end of device table */
};
/* uart 1 (logical device 4) */
const SIO_LOGDEV_TABLE sio_com1[] = {
{0x60, 3}, /* set IO to COM1 (3F8) */
{0x61, 0xF8}, /* set IO to COM1 (3F8) */
{0x70, 04}, /* set IRQ 4 for COM1 */
{0x30, 1}, /* and activate the device */
{0xFF, 0} /* end of device table */
};
/* uart 2 (logical device 5) */
const SIO_LOGDEV_TABLE sio_com2[] = {
{0x60, 2}, /* set IO to COM2 (2F8) */
{0x61, 0xF8}, /* set IO to COM2 (2F8) */
{0x70, 03}, /* set IRQ 3 for COM2 */
{0x30, 1}, /* and activate the device */
{0xFF, 0} /* end of device table */
};
/* keyboard controller (logical device 7) */
const SIO_LOGDEV_TABLE sio_keyboard[] = {
{0x70, 1}, /* set IRQ 1 for keyboard */
{0x72, 12}, /* set IRQ 12 for mouse */
{0xF0, 0}, /* disable Port92 (this is a PowerPC!!) */
{0x30, 1}, /* and activate the device */
{0xFF, 0} /* end of device table */
};
/*******************************************************************************
* Config SuperIO FDC37C672
********************************************************************************/
unsigned char open_cfg_super_IO(int address)
{
out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address,0x55); /* open config */
out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address,0x20); /* set address to DEV ID */
if(in8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address | 0x1)==0x40) /* ok Device ID is correct */
return TRUE;
else
return FALSE;
}
void close_cfg_super_IO(int address)
{
out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address,0xAA); /* close config */
}
unsigned char read_cfg_super_IO(int address, unsigned char function, unsigned char regaddr)
{
/* assuming config reg is open */
out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address,0x7); /* points to the function reg */
out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address | 1,function); /* set the function no */
out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address,regaddr); /* sets the address in the function */
return in8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address | 1);
}
void write_cfg_super_IO(int address, unsigned char function, unsigned char regaddr, unsigned char data)
{
/* assuming config reg is open */
out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address,0x7); /* points to the function reg */
out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address | 1,function); /* set the function no */
out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address,regaddr); /* sets the address in the function */
out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS | address | 1,data); /* writes the data */
}
void isa_write_table(SIO_LOGDEV_TABLE *ldt,unsigned char ldev)
{
while (ldt->index != 0xFF) {
write_cfg_super_IO(SIO_CFG_PORT, ldev, ldt->index, ldt->val);
ldt++;
} /* endwhile */
}
void isa_sio_loadtable(void)
{
char *s = getenv("floppy");
/* setup Floppy device 0*/
isa_write_table((SIO_LOGDEV_TABLE *)&sio_fdc,0);
/* setup parallel port device 3 */
if(s && !strncmp(s, "lpt", 3)) {
printf("SIO: Floppy assigned to LPT\n");
/* floppy is assigned to the LPT */
isa_write_table((SIO_LOGDEV_TABLE *)&sio_pport_fdc,3);
}
else {
/*printf("Floppy assigned to internal port\n");*/
isa_write_table((SIO_LOGDEV_TABLE *)&sio_pport,3);
}
/* setup Com1 port device 4 */
isa_write_table((SIO_LOGDEV_TABLE *)&sio_com1,4);
/* setup Com2 port device 5 */
isa_write_table((SIO_LOGDEV_TABLE *)&sio_com2,5);
/* setup keyboards device 7 */
isa_write_table((SIO_LOGDEV_TABLE *)&sio_keyboard,7);
}
void isa_sio_setup(void)
{
if(open_cfg_super_IO(SIO_CFG_PORT)==TRUE)
{
isa_sio_loadtable();
close_cfg_super_IO(0x3F0);
}
}
#endif
/******************************************************************************
* IRQ Controller
* we use the Vector mode
*/
struct isa_irq_action {
interrupt_handler_t *handler;
void *arg;
int count;
};
static struct isa_irq_action isa_irqs[16];
/*
* This contains the irq mask for both 8259A irq controllers,
*/
static unsigned int cached_irq_mask = 0xfff9;
#define cached_imr1 (unsigned char)cached_irq_mask
#define cached_imr2 (unsigned char)(cached_irq_mask>>8)
#define IMR_1 CONFIG_SYS_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT1_OCW1
#define IMR_2 CONFIG_SYS_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT2_OCW1
#define ICW1_1 CONFIG_SYS_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT1_ICW1
#define ICW1_2 CONFIG_SYS_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT2_ICW1
#define ICW2_1 CONFIG_SYS_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT1_ICW2
#define ICW2_2 CONFIG_SYS_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT2_ICW2
#define ICW3_1 ICW2_1
#define ICW3_2 ICW2_2
#define ICW4_1 ICW2_1
#define ICW4_2 ICW2_2
#define ISR_1 ICW1_1
#define ISR_2 ICW1_2
void disable_8259A_irq(unsigned int irq)
{
unsigned int mask = 1 << irq;
cached_irq_mask |= mask;
if (irq & 8)
out8(IMR_2,cached_imr2);
else
out8(IMR_1,cached_imr1);
}
void enable_8259A_irq(unsigned int irq)
{
unsigned int mask = ~(1 << irq);
cached_irq_mask &= mask;
if (irq & 8)
out8(IMR_2,cached_imr2);
else
out8(IMR_1,cached_imr1);
}
/*
int i8259A_irq_pending(unsigned int irq)
{
unsigned int mask = 1<<irq;
int ret;
if (irq < 8)
ret = inb(0x20) & mask;
else
ret = inb(0xA0) & (mask >> 8);
spin_unlock_irqrestore(&i8259A_lock, flags);
return ret;
}
*/
/*
* This function assumes to be called rarely. Switching between
* 8259A registers is slow.
*/
int i8259A_irq_real(unsigned int irq)
{
int value;
int irqmask = 1<<irq;
if (irq < 8) {
out8(ISR_1,0x0B); /* ISR register */
value = in8(ISR_1) & irqmask;
out8(ISR_1,0x0A); /* back to the IRR register */
return value;
}
out8(ISR_2,0x0B); /* ISR register */
value = in8(ISR_2) & (irqmask >> 8);
out8(ISR_2,0x0A); /* back to the IRR register */
return value;
}
/*
* Careful! The 8259A is a fragile beast, it pretty
* much _has_ to be done exactly like this (mask it
* first, _then_ send the EOI, and the order of EOI
* to the two 8259s is important!
*/
void mask_and_ack_8259A(unsigned int irq)
{
unsigned int irqmask = 1 << irq;
unsigned int temp_irqmask = cached_irq_mask;
/*
* Lightweight spurious IRQ detection. We do not want
* to overdo spurious IRQ handling - it's usually a sign
* of hardware problems, so we only do the checks we can
* do without slowing down good hardware unnecesserily.
*
* Note that IRQ7 and IRQ15 (the two spurious IRQs
* usually resulting from the 8259A-1|2 PICs) occur
* even if the IRQ is masked in the 8259A. Thus we
* can check spurious 8259A IRQs without doing the
* quite slow i8259A_irq_real() call for every IRQ.
* This does not cover 100% of spurious interrupts,
* but should be enough to warn the user that there
* is something bad going on ...
*/
if (temp_irqmask & irqmask)
goto spurious_8259A_irq;
temp_irqmask |= irqmask;
handle_real_irq:
if (irq & 8) {
in8(IMR_2); /* DUMMY - (do we need this?) */
out8(IMR_2,(unsigned char)(temp_irqmask>>8));
out8(ISR_2,0x60+(irq&7));/* 'Specific EOI' to slave */
out8(ISR_1,0x62); /* 'Specific EOI' to master-IRQ2 */
out8(IMR_2,cached_imr2); /* turn it on again */
} else {
in8(IMR_1); /* DUMMY - (do we need this?) */
out8(IMR_1,(unsigned char)temp_irqmask);
out8(ISR_1,0x60+irq); /* 'Specific EOI' to master */
out8(IMR_1,cached_imr1); /* turn it on again */
}
return;
spurious_8259A_irq:
/*
* this is the slow path - should happen rarely.
*/
if (i8259A_irq_real(irq))
/*
* oops, the IRQ _is_ in service according to the
* 8259A - not spurious, go handle it.
*/
goto handle_real_irq;
{
static int spurious_irq_mask;
/*
* At this point we can be sure the IRQ is spurious,
* lets ACK and report it. [once per IRQ]
*/
if (!(spurious_irq_mask & irqmask)) {
PRINTF("spurious 8259A interrupt: IRQ%d.\n", irq);
spurious_irq_mask |= irqmask;
}
/* irq_err_count++; */
/*
* Theoretically we do not have to handle this IRQ,
* but in Linux this does not cause problems and is
* simpler for us.
*/
goto handle_real_irq;
}
}
void init_8259A(void)
{
out8(IMR_1,0xff); /* mask all of 8259A-1 */
out8(IMR_2,0xff); /* mask all of 8259A-2 */
out8(ICW1_1,0x11); /* ICW1: select 8259A-1 init */
out8(ICW2_1,0x20 + 0); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
out8(ICW3_1,0x04); /* 8259A-1 (the master) has a slave on IR2 */
out8(ICW4_1,0x01); /* master expects normal EOI */
out8(ICW1_2,0x11); /* ICW2: select 8259A-2 init */
out8(ICW2_2,0x20 + 8); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
out8(ICW3_2,0x02); /* 8259A-2 is a slave on master's IR2 */
out8(ICW4_2,0x01); /* (slave's support for AEOI in flat mode
is to be investigated) */
udelay(10000); /* wait for 8259A to initialize */
out8(IMR_1,cached_imr1); /* restore master IRQ mask */
udelay(10000); /* wait for 8259A to initialize */
out8(IMR_2,cached_imr2); /* restore slave IRQ mask */
}
#define PCI_INT_ACK_ADDR 0xEED00000
int handle_isa_int(void)
{
unsigned long irqack;
unsigned char irq;
/* first we acknokledge the int via the PCI bus */
irqack=in32(PCI_INT_ACK_ADDR);
/* now we get the ISRs */
in8(ISR_2);
in8(ISR_1);
irq=(unsigned char)irqack;
irq-=32;
/* if((irq==7)&&((isr1&0x80)==0)) {
PRINTF("IRQ7 detected but not in ISR\n");
}
else {
*/ /* we should handle cascaded interrupts here also */
{
/* printf("ISA Irq %d\n",irq); */
isa_irqs[irq].count++;
if(irq!=2) { /* just swallow the cascade irq 2 */
if (isa_irqs[irq].handler != NULL)
(*isa_irqs[irq].handler)(isa_irqs[irq].arg); /* call isr */
else {
PRINTF ("bogus interrupt vector 0x%x\n", irq);
}
}
}
/* issue EOI instruction to clear the IRQ */
mask_and_ack_8259A(irq);
return 0;
}
/******************************************************************
* Install and free an ISA interrupt handler.
*/
void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
{
if (isa_irqs[vec].handler != NULL) {
printf ("ISA Interrupt vector %d: handler 0x%x replacing 0x%x\n",
vec, (uint)handler, (uint)isa_irqs[vec].handler);
}
isa_irqs[vec].handler = handler;
isa_irqs[vec].arg = arg;
enable_8259A_irq(vec);
PRINTF ("Install ISA IRQ %d ==> %p, @ %p mask=%04x\n", vec, handler, &isa_irqs[vec].handler,cached_irq_mask);
}
void isa_irq_free_handler(int vec)
{
disable_8259A_irq(vec);
isa_irqs[vec].handler = NULL;
isa_irqs[vec].arg = NULL;
PRINTF ("Free ISA IRQ %d mask=%04x\n", vec, cached_irq_mask);
}
/****************************************************************************/
void isa_init_irq_contr(void)
{
int i;
/* disable all Interrupts */
/* first write icws controller 1 */
for(i=0;i<16;i++)
{
isa_irqs[i].handler=NULL;
isa_irqs[i].arg=NULL;
isa_irqs[i].count=0;
}
init_8259A();
out8(IMR_2,0xFF);
}
/*************************************************************************/
void isa_show_irq(void)
{
int vec;
printf ("\nISA Interrupt-Information:\n");
printf ("Nr Routine Arg Count\n");
for (vec=0; vec<16; vec++) {
if (isa_irqs[vec].handler != NULL) {
printf ("%02d %08lx %08lx %d\n",
vec,
(ulong)isa_irqs[vec].handler,
(ulong)isa_irqs[vec].arg,
isa_irqs[vec].count);
}
}
}
int isa_irq_get_count(int vec)
{
return(isa_irqs[vec].count);
}
/******************************************************************
* Init the ISA bus and devices.
*/
#if defined(CONFIG_PIP405)
int isa_init(void)
{
isa_sio_setup();
isa_init_irq_contr();
drv_isa_kbd_init();
return 0;
}
#endif

View file

@ -0,0 +1,57 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* 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 _ISA_H_
#define _ISA_H_
/* Super IO */
#define SIO_CFG_PORT 0x3F0 /* Config Port Address */
#if defined(CONFIG_PIP405)
/* table fore SIO initialization */
typedef struct {
const uchar index;
const uchar val;
} SIO_LOGDEV_TABLE;
typedef struct {
const uchar ldev;
const SIO_LOGDEV_TABLE *ldev_table;
} SIO_TABLE;
unsigned char open_cfg_super_IO(int address);
unsigned char read_cfg_super_IO(int address, unsigned char function, unsigned char regaddr);
void write_cfg_super_IO(int address, unsigned char function, unsigned char regaddr, unsigned char data);
void close_cfg_super_IO(int address);
void isa_sio_setup(void);
#endif
void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg);
void isa_irq_free_handler(int vec);
int handle_isa_int(void);
void isa_init_irq_contr(void);
void isa_show_irq(void);
int isa_irq_get_count(int vec);
#endif

View file

@ -0,0 +1,645 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* 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
*
*
* Source partly derived from:
* linux/drivers/char/pc_keyb.c
*
*
*/
#include <common.h>
#include <asm/processor.h>
#include <stdio_dev.h>
#include "isa.h"
#include "kbd.h"
unsigned char kbd_read_status(void);
unsigned char kbd_read_input(void);
void kbd_send_data(unsigned char data);
void disable_8259A_irq(unsigned int irq);
void enable_8259A_irq(unsigned int irq);
/* used only by send_data - set by keyboard_interrupt */
#undef KBG_DEBUG
#ifdef KBG_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
#define KBD_STAT_KOBF 0x01
#define KBD_STAT_IBF 0x02
#define KBD_STAT_SYS 0x04
#define KBD_STAT_CD 0x08
#define KBD_STAT_LOCK 0x10
#define KBD_STAT_MOBF 0x20
#define KBD_STAT_TI_OUT 0x40
#define KBD_STAT_PARERR 0x80
#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */
#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */
#define KBD_TIMEOUT 2000 /* Timeout in ms for keyboard command acknowledge */
/*
* Keyboard Controller Commands
*/
#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
initiated by the auxiliary device */
#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
/*
* Keyboard Commands
*/
#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */
#define KBD_CMD_RESET 0xFF /* Reset */
/*
* Keyboard Replies
*/
#define KBD_REPLY_POR 0xAA /* Power on reset */
#define KBD_REPLY_ACK 0xFA /* Command ACK */
#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
/*
* Status Register Bits
*/
#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
#define KBD_STAT_PERR 0x80 /* Parity error */
#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
/*
* Controller Mode Register Bits
*/
#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
#define KBD_MODE_SYS 0x04 /* The system flag (?) */
#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
#define KBD_MODE_RFU 0x80
#define KDB_DATA_PORT 0x60
#define KDB_COMMAND_PORT 0x64
#define LED_SCR 0x01 /* scroll lock led */
#define LED_CAP 0x04 /* caps lock led */
#define LED_NUM 0x02 /* num lock led */
#define KBD_BUFFER_LEN 0x20 /* size of the keyboardbuffer */
static volatile char kbd_buffer[KBD_BUFFER_LEN];
static volatile int in_pointer = 0;
static volatile int out_pointer = 0;
static unsigned char num_lock = 0;
static unsigned char caps_lock = 0;
static unsigned char scroll_lock = 0;
static unsigned char shift = 0;
static unsigned char ctrl = 0;
static unsigned char alt = 0;
static unsigned char e0 = 0;
static unsigned char leds = 0;
#define DEVNAME "kbd"
/* Simple translation table for the keys */
static unsigned char kbd_plain_xlate[] = {
0xff,0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=','\b','\t', /* 0x00 - 0x0f */
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']','\r',0xff, 'a', 's', /* 0x10 - 0x1f */
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';','\'', '`',0xff,'\\', 'z', 'x', 'c', 'v', /* 0x20 - 0x2f */
'b', 'n', 'm', ',', '.', '/',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff, /* 0x30 - 0x3f */
0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */
'2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x50 - 0x5F */
'\r',0xff,0xff
};
static unsigned char kbd_shift_xlate[] = {
0xff,0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+','\b','\t', /* 0x00 - 0x0f */
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}','\r',0xff, 'A', 'S', /* 0x10 - 0x1f */
'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',0xff, '|', 'Z', 'X', 'C', 'V', /* 0x20 - 0x2f */
'B', 'N', 'M', '<', '>', '?',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff, /* 0x30 - 0x3f */
0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */
'2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x50 - 0x5F */
'\r',0xff,0xff
};
static unsigned char kbd_ctrl_xlate[] = {
0xff,0x1b, '1',0x00, '3', '4', '5',0x1E, '7', '8', '9', '0',0x1F, '=','\b','\t', /* 0x00 - 0x0f */
0x11,0x17,0x05,0x12,0x14,0x18,0x15,0x09,0x0f,0x10,0x1b,0x1d,'\n',0xff,0x01,0x13, /* 0x10 - 0x1f */
0x04,0x06,0x08,0x09,0x0a,0x0b,0x0c, ';','\'', '~',0x00,0x1c,0x1a,0x18,0x03,0x16, /* 0x20 - 0x2f */
0x02,0x0e,0x0d, '<', '>', '?',0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x30 - 0x3f */
0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */
'2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x50 - 0x5F */
'\r',0xff,0xff
};
/******************************************************************
* Init
******************************************************************/
int isa_kbd_init(void)
{
char* result;
result=kbd_initialize();
if(result==NULL) {
PRINTF("AT Keyboard initialized\n");
irq_install_handler(25, (interrupt_handler_t *)handle_isa_int, NULL);
isa_irq_install_handler(KBD_INTERRUPT, (interrupt_handler_t *)kbd_interrupt, NULL);
return (1);
} else {
printf("%s\n",result);
return (-1);
}
}
#ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
extern int overwrite_console (void);
#else
int overwrite_console (void)
{
return (0);
}
#endif
int drv_isa_kbd_init (void)
{
int error;
struct stdio_dev kbddev ;
char *stdinname = getenv ("stdin");
if(isa_kbd_init()==-1)
return -1;
memset (&kbddev, 0, sizeof(kbddev));
strcpy(kbddev.name, DEVNAME);
kbddev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
kbddev.putc = NULL ;
kbddev.puts = NULL ;
kbddev.getc = kbd_getc ;
kbddev.tstc = kbd_testc ;
error = stdio_register (&kbddev);
if(error==0) {
/* check if this is the standard input device */
if(strcmp(stdinname,DEVNAME)==0) {
/* reassign the console */
if(overwrite_console()) {
return 1;
}
error=console_assign(stdin,DEVNAME);
if(error==0)
return 1;
else
return error;
}
return 1;
}
return error;
}
/******************************************************************
* Queue handling
******************************************************************/
/* puts character in the queue and sets up the in and out pointer */
void kbd_put_queue(char data)
{
if((in_pointer+1)==KBD_BUFFER_LEN) {
if(out_pointer==0) {
return; /* buffer full */
} else{
in_pointer=0;
}
} else {
if((in_pointer+1)==out_pointer)
return; /* buffer full */
in_pointer++;
}
kbd_buffer[in_pointer]=data;
return;
}
/* test if a character is in the queue */
int kbd_testc(void)
{
if(in_pointer==out_pointer)
return(0); /* no data */
else
return(1);
}
/* gets the character from the queue */
int kbd_getc(void)
{
char c;
while(in_pointer==out_pointer);
if((out_pointer+1)==KBD_BUFFER_LEN)
out_pointer=0;
else
out_pointer++;
c=kbd_buffer[out_pointer];
return (int)c;
}
/* set LEDs */
void kbd_set_leds(void)
{
if(caps_lock==0)
leds&=~LED_CAP; /* switch caps_lock off */
else
leds|=LED_CAP; /* switch on LED */
if(num_lock==0)
leds&=~LED_NUM; /* switch LED off */
else
leds|=LED_NUM; /* switch on LED */
if(scroll_lock==0)
leds&=~LED_SCR; /* switch LED off */
else
leds|=LED_SCR; /* switch on LED */
kbd_send_data(KBD_CMD_SET_LEDS);
kbd_send_data(leds);
}
void handle_keyboard_event (unsigned char scancode)
{
unsigned char keycode;
/* Convert scancode to keycode */
PRINTF ("scancode %x\n", scancode);
if (scancode == 0xe0) {
e0 = 1; /* special charakters */
return;
}
if (e0 == 1) {
e0 = 0; /* delete flag */
if (!(((scancode & 0x7F) == 0x38) || /* the right ctrl key */
((scancode & 0x7F) == 0x1D) || /* the right alt key */
((scancode & 0x7F) == 0x35) || /* the right '/' key */
((scancode & 0x7F) == 0x1C)))
/* the right enter key */
/* we swallow unknown e0 codes */
return;
}
/* special cntrl keys */
switch (scancode) {
case 0x2A:
case 0x36: /* shift pressed */
shift = 1;
return; /* do nothing else */
case 0xAA:
case 0xB6: /* shift released */
shift = 0;
return; /* do nothing else */
case 0x38: /* alt pressed */
alt = 1;
return; /* do nothing else */
case 0xB8: /* alt released */
alt = 0;
return; /* do nothing else */
case 0x1d: /* ctrl pressed */
ctrl = 1;
return; /* do nothing else */
case 0x9d: /* ctrl released */
ctrl = 0;
return; /* do nothing else */
case 0x46: /* scrollock pressed */
scroll_lock = ~scroll_lock;
kbd_set_leds ();
return; /* do nothing else */
case 0x3A: /* capslock pressed */
caps_lock = ~caps_lock;
kbd_set_leds ();
return;
case 0x45: /* numlock pressed */
num_lock = ~num_lock;
kbd_set_leds ();
return;
case 0xC6: /* scroll lock released */
case 0xC5: /* num lock released */
case 0xBA: /* caps lock released */
return; /* just swallow */
}
if ((scancode & 0x80) == 0x80) /* key released */
return;
/* now, decide which table we need */
if (scancode > (sizeof (kbd_plain_xlate) / sizeof (kbd_plain_xlate[0]))) { /* scancode not in list */
PRINTF ("unkown scancode %X\n", scancode);
return; /* swallow it */
}
/* setup plain code first */
keycode = kbd_plain_xlate[scancode];
if (caps_lock == 1) { /* caps_lock is pressed, overwrite plain code */
if (scancode > (sizeof (kbd_shift_xlate) / sizeof (kbd_shift_xlate[0]))) { /* scancode not in list */
PRINTF ("unkown caps-locked scancode %X\n", scancode);
return; /* swallow it */
}
keycode = kbd_shift_xlate[scancode];
if (keycode < 'A') { /* we only want the alphas capital */
keycode = kbd_plain_xlate[scancode];
}
}
if (shift == 1) { /* shift overwrites caps_lock */
if (scancode > (sizeof (kbd_shift_xlate) / sizeof (kbd_shift_xlate[0]))) { /* scancode not in list */
PRINTF ("unkown shifted scancode %X\n", scancode);
return; /* swallow it */
}
keycode = kbd_shift_xlate[scancode];
}
if (ctrl == 1) { /* ctrl overwrites caps_lock and shift */
if (scancode > (sizeof (kbd_ctrl_xlate) / sizeof (kbd_ctrl_xlate[0]))) { /* scancode not in list */
PRINTF ("unkown ctrl scancode %X\n", scancode);
return; /* swallow it */
}
keycode = kbd_ctrl_xlate[scancode];
}
/* check if valid keycode */
if (keycode == 0xff) {
PRINTF ("unkown scancode %X\n", scancode);
return; /* swallow unknown codes */
}
kbd_put_queue (keycode);
PRINTF ("%x\n", keycode);
}
/*
* This reads the keyboard status port, and does the
* appropriate action.
*
*/
unsigned char handle_kbd_event(void)
{
unsigned char status = kbd_read_status();
unsigned int work = 10000;
while ((--work > 0) && (status & KBD_STAT_OBF)) {
unsigned char scancode;
scancode = kbd_read_input();
/* Error bytes must be ignored to make the
Synaptics touchpads compaq use work */
/* Ignore error bytes */
if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR)))
{
if (status & KBD_STAT_MOUSE_OBF)
; /* not supported: handle_mouse_event(scancode); */
else
handle_keyboard_event(scancode);
}
status = kbd_read_status();
}
if (!work)
PRINTF("pc_keyb: controller jammed (0x%02X).\n", status);
return status;
}
/******************************************************************************
* Lowlevel Part of keyboard section
*/
unsigned char kbd_read_status(void)
{
return(in8(CONFIG_SYS_ISA_IO_BASE_ADDRESS + KDB_COMMAND_PORT));
}
unsigned char kbd_read_input(void)
{
return(in8(CONFIG_SYS_ISA_IO_BASE_ADDRESS + KDB_DATA_PORT));
}
void kbd_write_command(unsigned char cmd)
{
out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS + KDB_COMMAND_PORT,cmd);
}
void kbd_write_output(unsigned char data)
{
out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS + KDB_DATA_PORT, data);
}
int kbd_read_data(void)
{
int val;
unsigned char status;
val = -1;
status = kbd_read_status();
if (status & KBD_STAT_OBF) {
val = kbd_read_input();
if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
val = -2;
}
return val;
}
int kbd_wait_for_input(void)
{
unsigned long timeout;
int val;
timeout = KBD_TIMEOUT;
val=kbd_read_data();
while(val < 0)
{
if(timeout--==0)
return -1;
udelay(1000);
val=kbd_read_data();
}
return val;
}
int kb_wait(void)
{
unsigned long timeout = KBC_TIMEOUT * 10;
do {
unsigned char status = handle_kbd_event();
if (!(status & KBD_STAT_IBF))
return 0; /* ok */
udelay(1000);
timeout--;
} while (timeout);
return 1;
}
void kbd_write_command_w(int data)
{
if(kb_wait())
PRINTF("timeout in kbd_write_command_w\n");
kbd_write_command(data);
}
void kbd_write_output_w(int data)
{
if(kb_wait())
PRINTF("timeout in kbd_write_output_w\n");
kbd_write_output(data);
}
void kbd_send_data(unsigned char data)
{
unsigned char status;
disable_8259A_irq(1); /* disable interrupt */
kbd_write_output_w(data);
status = kbd_wait_for_input();
if (status == KBD_REPLY_ACK)
enable_8259A_irq(1); /* enable interrupt */
}
char * kbd_initialize(void)
{
int status;
in_pointer = 0; /* delete in Buffer */
out_pointer = 0;
/*
* Test the keyboard interface.
* This seems to be the only way to get it going.
* If the test is successful a x55 is placed in the input buffer.
*/
kbd_write_command_w(KBD_CCMD_SELF_TEST);
if (kbd_wait_for_input() != 0x55)
return "Kbd: failed self test";
/*
* Perform a keyboard interface test. This causes the controller
* to test the keyboard clock and data lines. The results of the
* test are placed in the input buffer.
*/
kbd_write_command_w(KBD_CCMD_KBD_TEST);
if (kbd_wait_for_input() != 0x00)
return "Kbd: interface failed self test";
/*
* Enable the keyboard by allowing the keyboard clock to run.
*/
kbd_write_command_w(KBD_CCMD_KBD_ENABLE);
status = kbd_wait_for_input();
/*
* Reset keyboard. If the read times out
* then the assumption is that no keyboard is
* plugged into the machine.
* This defaults the keyboard to scan-code set 2.
*
* Set up to try again if the keyboard asks for RESEND.
*/
do {
kbd_write_output_w(KBD_CMD_RESET);
status = kbd_wait_for_input();
if (status == KBD_REPLY_ACK)
break;
if (status != KBD_REPLY_RESEND) {
PRINTF("status: %X\n",status);
return "Kbd: reset failed, no ACK";
}
} while (1);
if (kbd_wait_for_input() != KBD_REPLY_POR)
return "Kbd: reset failed, no POR";
/*
* Set keyboard controller mode. During this, the keyboard should be
* in the disabled state.
*
* Set up to try again if the keyboard asks for RESEND.
*/
do {
kbd_write_output_w(KBD_CMD_DISABLE);
status = kbd_wait_for_input();
if (status == KBD_REPLY_ACK)
break;
if (status != KBD_REPLY_RESEND)
return "Kbd: disable keyboard: no ACK";
} while (1);
kbd_write_command_w(KBD_CCMD_WRITE_MODE);
kbd_write_output_w(KBD_MODE_KBD_INT
| KBD_MODE_SYS
| KBD_MODE_DISABLE_MOUSE
| KBD_MODE_KCC);
/* AMCC powerpc portables need this to use scan-code set 1 -- Cort */
kbd_write_command_w(KBD_CCMD_READ_MODE);
if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
/*
* If the controller does not support conversion,
* Set the keyboard to scan-code set 1.
*/
kbd_write_output_w(0xF0);
kbd_wait_for_input();
kbd_write_output_w(0x01);
kbd_wait_for_input();
}
kbd_write_output_w(KBD_CMD_ENABLE);
if (kbd_wait_for_input() != KBD_REPLY_ACK)
return "Kbd: enable keyboard: no ACK";
/*
* Finally, set the typematic rate to maximum.
*/
kbd_write_output_w(KBD_CMD_SET_RATE);
if (kbd_wait_for_input() != KBD_REPLY_ACK)
return "Kbd: Set rate: no ACK";
kbd_write_output_w(0x00);
if (kbd_wait_for_input() != KBD_REPLY_ACK)
return "Kbd: Set rate: no ACK";
return NULL;
}
void kbd_interrupt(void)
{
handle_kbd_event();
}

View file

@ -0,0 +1,35 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* 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 _KBD_H_
#define _KBD_H_
extern int kbd_testc(void);
extern int kbd_getc(void);
extern void kbd_interrupt(void);
extern char *kbd_initialize(void);
unsigned char kbd_is_init(void);
#define KBD_INTERRUPT 1
#endif

View file

@ -0,0 +1,109 @@
/*-----------------------------------------------------------------------------+
| This source code is dual-licensed. You may use it under the terms of
| the GNU General Public License version 2, or under the license below.
|
| 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
+-----------------------------------------------------------------------------*/
/*
* Adapted for PIP405 03.07.01
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* TODO: Clean-up
*/
#include <common.h>
#include <pci.h>
#include "isa.h"
#ifdef CONFIG_405GP
#ifdef CONFIG_PCI
DECLARE_GLOBAL_DATA_PTR;
#include "piix4_pci.h"
#include "pci_parts.h"
void pci_pip405_write_regs(struct pci_controller *hose, pci_dev_t dev,
struct pci_config_table *entry)
{
struct pci_pip405_config_entry *table;
int i;
table = (struct pci_pip405_config_entry*) entry->priv[0];
for (i=0; table[i].width; i++)
{
#ifdef DEBUG
printf("Reg 0x%02X Value 0x%08lX Width %02d written\n",
table[i].index, table[i].val, table[i].width);
#endif
switch(table[i].width)
{
case 1: pci_hose_write_config_byte(hose, dev, table[i].index, table[i].val); break;
case 2: pci_hose_write_config_word(hose, dev, table[i].index, table[i].val); break;
case 4: pci_hose_write_config_dword(hose, dev, table[i].index, table[i].val); break;
}
}
}
static void pci_pip405_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
{
unsigned char int_line = 0xff;
unsigned char pin;
/*
* Write pci interrupt line register
*/
if(PCI_DEV(dev)==0) /* Device0 = PPC405 -> skip */
return;
pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_PIN, &pin);
if ((pin == 0) || (pin > 4))
return;
int_line = ((PCI_DEV(dev) + (pin-1) + 10) % 4) + 28;
pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, int_line);
#ifdef DEBUG
printf("Fixup IRQ: dev %d (%x) int line %d 0x%x\n",
PCI_DEV(dev),dev,int_line,int_line);
#endif
}
extern void pci_405gp_init(struct pci_controller *hose);
static struct pci_controller hose = {
config_table: pci_pip405_config_table,
fixup_irq: pci_pip405_fixup_irq,
};
void pci_init_board(void)
{
/*we want the ptrs to RAM not flash (ie don't use init list)*/
hose.fixup_irq = pci_pip405_fixup_irq;
hose.config_table = pci_pip405_config_table;
#ifdef DEBUG
printf("Init PCI: fixup_irq=%p config_table=%p hose=%p\n",pci_pip405_fixup_irq,pci_pip405_config_table,hose);
#endif
pci_405gp_init(&hose);
}
#endif /* CONFIG_PCI */
#endif /* CONFIG_405GP */

View file

@ -0,0 +1,193 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* 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 _PCI_PARTS_H_
#define _PCI_PARTS_H_
/* Board specific file containing:
* - PCI Memory Mapping
* - PCI IO Mapping
* - PCI Interrupt Mapping
*/
/* PIP405 PCI INT Routing:
* IRQ0 VECTOR
* PIXX4 IDSEL = AD16 INTA# 28 (Function 2 USB is INTD# = 31)
* VGA IDSEL = AD17 INTB# 29
* SCSI IDSEL = AD18 INTC# 30
* PC104 IDSEL0 = AD20 INTA# 28
* PC104 IDSEL1 = AD21 INTB# 29
* PC104 IDSEL2 = AD22 INTC# 30
* PC104 IDSEL3 = AD23 INTD# 31
*
* busdevfunc = EXXX XXXX BBBB BBBB DDDD DFFF RRRR RR00
* ^ ^ ^ ^ ^
* 31 23 15 10 7
* E = Enabled
* B = Bussnumber
* D = Devicenumber (Device0 = AD10)
* F = Functionnumber
* R = Registernumber
*
* Device = (busdevfunc>>11) + 10
* Vector = devicenumber % 4 + 28
*
*/
#define PCI_HIGHEST_ON_BOARD_ID 19
/*#define PCI_DEV_NUMBER(x) (((x>>11) & 0x1f) + 10) */
#define PCI_IRQ_VECTOR(x) ((PCI_DEV(x) + 10) % 4) + 28
/* PCI Device List for PIP405 */
/* Mapping:
* +-------------+------------+------------+--------------------------------+
* | PCI MemAddr | PCI IOAddr | Local Addr | Device / Function |
* +-------------+------------+------------+--------------------------------+
* | 0x00000000 | | 0xA0000000 | ISA Memory (hard wired) |
* | 0x00FFFFFF | | 0xA0FFFFFF | |
* +-------------+------------+------------+--------------------------------+
* | | 0x00000000 | 0xE8000000 | ISA IO (hard wired) |
* | | 0x0000FFFF | 0xE800FFFF | |
* +-------------+------------+------------+--------------------------------+
* | 0x80000000 | | 0x80000000 | VGA Controller Memory |
* | 0x80FFFFFF | | 0x80FFFFFF | |
* +-------------+------------+------------+--------------------------------+
* | 0x81000000 | | 0x81000000 | SCSI Controller Memory |
* | 0x81FFFFFF | | 0x81FFFFFF | |
* +-------------+------------+------------+--------------------------------+
*/
struct pci_pip405_config_entry {
int index; /* address */
unsigned long val; /* value */
int width; /* data size */
};
extern void pci_pip405_write_regs(struct pci_controller *,
pci_dev_t,
struct pci_config_table *);
/* PIIX4 ISA Bridge Function 0 */
static struct pci_pip405_config_entry piix4_isa_bridge_f0[] = {
{PCI_CFG_PIIX4_SERIRQ, 0xD0, 1}, /* enable Continous SERIRQ Pin */
{PCI_CFG_PIIX4_GENCFG, 0x00018041, 4}, /* enable SERIRQs, ISA, PNP, GPI11 */
{PCI_CFG_PIIX4_TOM, 0xFE, 1}, /* Top of Memory */
{PCI_CFG_PIIX4_XBCS, 0x02C4, 2}, /* disable all peri CS */
{PCI_CFG_PIIX4_RTCCFG, 0x21, 1}, /* enable RTC */
#if defined(CONFIG_PIP405)
{PCI_CFG_PIIX4_MBDMA, 0x82, 1}, /* set MBDMA0 to DMA 2 */
{PCI_CFG_PIIX4_MBDMA+1, 0x83, 1}, /* set MBDMA1 to DMA 3 */
#endif
{PCI_CFG_PIIX4_DLC, 0x0, 1}, /* disable passive release feature */
{ } /* end of device table */
};
/* PIIX4 IDE Controller Function 1 */
static struct pci_pip405_config_entry piix4_ide_cntrl_f1[] = {
{PCI_CFG_PIIX4_BMIBA, 0x0001000, 4}, /* set BMI to a valid address */
{PCI_COMMAND, 0x0001, 2}, /* enable IO access */
#if !defined(CONFIG_MIP405T)
{PCI_CFG_PIIX4_IDETIM, 0x80008000, 4}, /* enable Both IDE channels */
#else
{PCI_CFG_PIIX4_IDETIM, 0x00008000, 4}, /* enable IDE channel0 */
#endif
{ } /* end of device table */
};
/* PIIX4 USB Controller Function 2 */
static struct pci_pip405_config_entry piix4_usb_cntrl_f2[] = {
#if !defined(CONFIG_MIP405T)
{PCI_INTERRUPT_LINE, 31, 1}, /* Int vector = 31 */
{PCI_BASE_ADDRESS_4, 0x0000E001, 4}, /* Set IO Address to 0xe000 to 0xe01F */
{PCI_LATENCY_TIMER, 0x80, 1}, /* Latency Timer 0x80 */
{0xC0, 0x2000, 2}, /* Legacy support */
{PCI_COMMAND, 0x0005, 2}, /* enable IO access and Master */
#endif
{ } /* end of device table */
};
/* PIIX4 Power Management Function 3 */
static struct pci_pip405_config_entry piix4_pmm_cntrl_f3[] = {
{PCI_CFG_PIIX4_PMBA, 0x00004000, 4}, /* set PMBA to "valid" value */
{PCI_CFG_PIIX4_SMBBA, 0x00005000, 4}, /* set SMBBA to "valid" value */
{PCI_CFG_PIIX4_PMMISC, 0x01, 1}, /* enable PMBA IO access */
{PCI_COMMAND, 0x0001, 2}, /* enable IO access */
{ } /* end of device table */
};
/* PPC405 Dummy only used to prevent autosetup on this host bridge */
static struct pci_pip405_config_entry ppc405_dummy[] = {
{ } /* end of device table */
};
void pci_405gp_setup_vga(struct pci_controller *hose, pci_dev_t dev,
struct pci_config_table *entry);
static struct pci_config_table pci_pip405_config_table[]={
{PCI_VENDOR_ID_IBM, /* 405 dummy */
PCI_DEVICE_ID_IBM_405GP,
PCI_ANY_ID,
PCI_ANY_ID, PCI_ANY_ID, 0,
pci_pip405_write_regs, {(unsigned long) ppc405_dummy}},
{PCI_VENDOR_ID_INTEL, /* PIIX4 ISA Bridge Function 0 */
PCI_DEVICE_ID_INTEL_82371AB_0,
PCI_ANY_ID,
PCI_ANY_ID, PCI_ANY_ID, 0,
pci_pip405_write_regs, {(unsigned long) piix4_isa_bridge_f0}},
{PCI_VENDOR_ID_INTEL, /* PIIX4 IDE Controller Function 1 */
PCI_DEVICE_ID_INTEL_82371AB,
PCI_ANY_ID,
PCI_ANY_ID, PCI_ANY_ID, 1,
pci_pip405_write_regs, {(unsigned long) piix4_ide_cntrl_f1}},
{PCI_VENDOR_ID_INTEL, /* PIIX4 USB Controller Function 2 */
PCI_DEVICE_ID_INTEL_82371AB_2,
PCI_ANY_ID,
PCI_ANY_ID, PCI_ANY_ID, 2,
pci_pip405_write_regs, {(unsigned long) piix4_usb_cntrl_f2}},
{PCI_VENDOR_ID_INTEL, /* PIIX4 USB Controller Function 3 */
PCI_DEVICE_ID_INTEL_82371AB_3,
PCI_ANY_ID,
PCI_ANY_ID, PCI_ANY_ID, 3,
pci_pip405_write_regs, {(unsigned long) piix4_pmm_cntrl_f3}},
{PCI_ANY_ID,
PCI_ANY_ID,
PCI_CLASS_DISPLAY_VGA,
PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
pci_405gp_setup_vga},
{PCI_ANY_ID,
PCI_ANY_ID,
PCI_CLASS_NOT_DEFINED_VGA,
PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
pci_405gp_setup_vga},
{ }
};
#endif /* _PCI_PARTS_H_ */

View file

@ -0,0 +1,165 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* 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 _PIIX4_PCI_H
#define _PIIX4_PCI_H
/***************************************************************************
* Defines PIIX4 Config Registers
****************************************************************************/
/* Function 0 ISA Bridge */
#define PCI_CFG_PIIX4_IORT 0x4C /* 8 bit ISA Recovery Timer Reg (default 0x4D) */
#define PCI_CFG_PIIX4_XBCS 0x4E /* 16 bit XBus Chip select reg (default 0x0003) */
#define PCI_CFG_PIIX4_PIRQC 0x60 /* PCI IRQ Route Register 4 x 8bit (default )*/
#define PCI_CFG_PIIX4_SERIRQ 0x64
#define PCI_CFG_PIIX4_TOM 0x69
#define PCI_CFG_PIIX4_MSTAT 0x6A
#define PCI_CFG_PIIX4_MBDMA 0x76
#define PCI_CFG_PIIX4_APICBS 0x80
#define PCI_CFG_PIIX4_DLC 0x82
#define PCI_CFG_PIIX4_PDMACFG 0x90
#define PCI_CFG_PIIX4_DDMABS 0x92
#define PCI_CFG_PIIX4_GENCFG 0xB0
#define PCI_CFG_PIIX4_RTCCFG 0xCB
/* IO Addresses */
#define PIIX4_ISA_DMA1_CH0BA 0x00
#define PIIX4_ISA_DMA1_CH0CA 0x01
#define PIIX4_ISA_DMA1_CH1BA 0x02
#define PIIX4_ISA_DMA1_CH1CA 0x03
#define PIIX4_ISA_DMA1_CH2BA 0x04
#define PIIX4_ISA_DMA1_CH2CA 0x05
#define PIIX4_ISA_DMA1_CH3BA 0x06
#define PIIX4_ISA_DMA1_CH3CA 0x07
#define PIIX4_ISA_DMA1_CMDST 0x08
#define PIIX4_ISA_DMA1_REQ 0x09
#define PIIX4_ISA_DMA1_WSBM 0x0A
#define PIIX4_ISA_DMA1_CH_MOD 0x0B
#define PIIX4_ISA_DMA1_CLR_PT 0x0C
#define PIIX4_ISA_DMA1_M_CLR 0x0D
#define PIIX4_ISA_DMA1_CLR_M 0x0E
#define PIIX4_ISA_DMA1_RWAMB 0x0F
#define PIIX4_ISA_DMA2_CH0BA 0xC0
#define PIIX4_ISA_DMA2_CH0CA 0xC1
#define PIIX4_ISA_DMA2_CH1BA 0xC2
#define PIIX4_ISA_DMA2_CH1CA 0xC3
#define PIIX4_ISA_DMA2_CH2BA 0xC4
#define PIIX4_ISA_DMA2_CH2CA 0xC5
#define PIIX4_ISA_DMA2_CH3BA 0xC6
#define PIIX4_ISA_DMA2_CH3CA 0xC7
#define PIIX4_ISA_DMA2_CMDST 0xD0
#define PIIX4_ISA_DMA2_REQ 0xD2
#define PIIX4_ISA_DMA2_WSBM 0xD4
#define PIIX4_ISA_DMA2_CH_MOD 0xD6
#define PIIX4_ISA_DMA2_CLR_PT 0xD8
#define PIIX4_ISA_DMA2_M_CLR 0xDA
#define PIIX4_ISA_DMA2_CLR_M 0xDC
#define PIIX4_ISA_DMA2_RWAMB 0xDE
#define PIIX4_ISA_INT1_ICW1 0x20
#define PIIX4_ISA_INT1_OCW2 0x20
#define PIIX4_ISA_INT1_OCW3 0x20
#define PIIX4_ISA_INT1_ICW2 0x21
#define PIIX4_ISA_INT1_ICW3 0x21
#define PIIX4_ISA_INT1_ICW4 0x21
#define PIIX4_ISA_INT1_OCW1 0x21
#define PIIX4_ISA_INT1_ELCR 0x4D0
#define PIIX4_ISA_INT2_ICW1 0xA0
#define PIIX4_ISA_INT2_OCW2 0xA0
#define PIIX4_ISA_INT2_OCW3 0xA0
#define PIIX4_ISA_INT2_ICW2 0xA1
#define PIIX4_ISA_INT2_ICW3 0xA1
#define PIIX4_ISA_INT2_ICW4 0xA1
#define PIIX4_ISA_INT2_OCW1 0xA1
#define PIIX4_ISA_INT2_IMR 0xA1 /* read only */
#define PIIX4_ISA_INT2_ELCR 0x4D1
#define PIIX4_ISA_TMR0_CNT_ST 0x40
#define PIIX4_ISA_TMR1_CNT_ST 0x41
#define PIIX4_ISA_TMR2_CNT_ST 0x42
#define PIIX4_ISA_TMR_TCW 0x43
#define PIIX4_ISA_RST_XBUS 0x60
#define PIIX4_ISA_NMI_CNT_ST 0x61
#define PIIX4_ISA_NMI_ENABLE 0x70
#define PIIX4_ISA_RTC_INDEX 0x70
#define PIIX4_ISA_RTC_DATA 0x71
#define PIIX4_ISA_RTCEXT_IND 0x70
#define PIIX4_ISA_RTCEXT_DATA 0x71
#define PIIX4_ISA_DMA1_CH2LPG 0x81
#define PIIX4_ISA_DMA1_CH3LPG 0x82
#define PIIX4_ISA_DMA1_CH1LPG 0x83
#define PIIX4_ISA_DMA1_CH0LPG 0x87
#define PIIX4_ISA_DMA2_CH2LPG 0x89
#define PIIX4_ISA_DMA2_CH3LPG 0x8A
#define PIIX4_ISA_DMA2_CH1LPG 0x8B
#define PIIX4_ISA_DMA2_LPGRFR 0x8F
#define PIIX4_ISA_PORT_92 0x92
#define PIIX4_ISA_APM_CONTRL 0xB2
#define PIIX4_ISA_APM_STATUS 0xB3
#define PIIX4_ISA_COCPU_ERROR 0xF0
/* Function 1 IDE Controller */
#define PCI_CFG_PIIX4_BMIBA 0x20
#define PCI_CFG_PIIX4_IDETIM 0x40
#define PCI_CFG_PIIX4_SIDETIM 0x44
#define PCI_CFG_PIIX4_UDMACTL 0x48
#define PCI_CFG_PIIX4_UDMATIM 0x4A
/* Function 2 USB Controller */
#define PCI_CFG_PIIX4_SBRNUM 0x60
#define PCI_CFG_PIIX4_LEGSUP 0xC0
/* Function 3 Power Management */
#define PCI_CFG_PIIX4_PMBA 0x40
#define PCI_CFG_PIIX4_CNTA 0x44
#define PCI_CFG_PIIX4_CNTB 0x48
#define PCI_CFG_PIIX4_GPICTL 0x4C
#define PCI_CFG_PIIX4_DEVRESD 0x50
#define PCI_CFG_PIIX4_DEVACTA 0x54
#define PCI_CFG_PIIX4_DEVACTB 0x58
#define PCI_CFG_PIIX4_DEVRESA 0x5C
#define PCI_CFG_PIIX4_DEVRESB 0x60
#define PCI_CFG_PIIX4_DEVRESC 0x64
#define PCI_CFG_PIIX4_DEVRESE 0x68
#define PCI_CFG_PIIX4_DEVRESF 0x6C
#define PCI_CFG_PIIX4_DEVRESG 0x70
#define PCI_CFG_PIIX4_DEVRESH 0x74
#define PCI_CFG_PIIX4_DEVRESI 0x78
#define PCI_CFG_PIIX4_PMMISC 0x80
#define PCI_CFG_PIIX4_SMBBA 0x90
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,188 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland
*
* 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
*
* Note: Part of this code has been derived from linux
*
*/
#ifndef _USB_UHCI_H_
#define _USB_UHCI_H_
/* Command register */
#define USBCMD 0
#define USBCMD_RS 0x0001 /* Run/Stop */
#define USBCMD_HCRESET 0x0002 /* Host reset */
#define USBCMD_GRESET 0x0004 /* Global reset */
#define USBCMD_EGSM 0x0008 /* Global Suspend Mode */
#define USBCMD_FGR 0x0010 /* Force Global Resume */
#define USBCMD_SWDBG 0x0020 /* SW Debug mode */
#define USBCMD_CF 0x0040 /* Config Flag (sw only) */
#define USBCMD_MAXP 0x0080 /* Max Packet (0 = 32, 1 = 64) */
/* Status register */
#define USBSTS 2
#define USBSTS_USBINT 0x0001 /* Interrupt due to IOC */
#define USBSTS_ERROR 0x0002 /* Interrupt due to error */
#define USBSTS_RD 0x0004 /* Resume Detect */
#define USBSTS_HSE 0x0008 /* Host System Error - basically PCI problems */
#define USBSTS_HCPE 0x0010 /* Host Controller Process Error - the scripts were buggy */
#define USBSTS_HCH 0x0020 /* HC Halted */
/* Interrupt enable register */
#define USBINTR 4
#define USBINTR_TIMEOUT 0x0001 /* Timeout/CRC error enable */
#define USBINTR_RESUME 0x0002 /* Resume interrupt enable */
#define USBINTR_IOC 0x0004 /* Interrupt On Complete enable */
#define USBINTR_SP 0x0008 /* Short packet interrupt enable */
#define USBFRNUM 6
#define USBFLBASEADD 8
#define USBSOF 12
/* USB port status and control registers */
#define USBPORTSC1 16
#define USBPORTSC2 18
#define USBPORTSC_CCS 0x0001 /* Current Connect Status ("device present") */
#define USBPORTSC_CSC 0x0002 /* Connect Status Change */
#define USBPORTSC_PE 0x0004 /* Port Enable */
#define USBPORTSC_PEC 0x0008 /* Port Enable Change */
#define USBPORTSC_LS 0x0030 /* Line Status */
#define USBPORTSC_RD 0x0040 /* Resume Detect */
#define USBPORTSC_LSDA 0x0100 /* Low Speed Device Attached */
#define USBPORTSC_PR 0x0200 /* Port Reset */
#define USBPORTSC_SUSP 0x1000 /* Suspend */
/* Legacy support register */
#define USBLEGSUP 0xc0
#define USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */
#define UHCI_NULL_DATA_SIZE 0x7ff /* for UHCI controller TD */
#define UHCI_PID 0xff /* PID MASK */
#define UHCI_PTR_BITS 0x000F
#define UHCI_PTR_TERM 0x0001
#define UHCI_PTR_QH 0x0002
#define UHCI_PTR_DEPTH 0x0004
/* for TD <status>: */
#define TD_CTRL_SPD (1 << 29) /* Short Packet Detect */
#define TD_CTRL_C_ERR_MASK (3 << 27) /* Error Counter bits */
#define TD_CTRL_LS (1 << 26) /* Low Speed Device */
#define TD_CTRL_IOS (1 << 25) /* Isochronous Select */
#define TD_CTRL_IOC (1 << 24) /* Interrupt on Complete */
#define TD_CTRL_ACTIVE (1 << 23) /* TD Active */
#define TD_CTRL_STALLED (1 << 22) /* TD Stalled */
#define TD_CTRL_DBUFERR (1 << 21) /* Data Buffer Error */
#define TD_CTRL_BABBLE (1 << 20) /* Babble Detected */
#define TD_CTRL_NAK (1 << 19) /* NAK Received */
#define TD_CTRL_CRCTIMEO (1 << 18) /* CRC/Time Out Error */
#define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */
#define TD_CTRL_ACTLEN_MASK 0x7ff /* actual length, encoded as n - 1 */
#define TD_CTRL_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \
TD_CTRL_BABBLE | TD_CTRL_CRCTIME | TD_CTRL_BITSTUFF)
#define TD_TOKEN_TOGGLE 19
/* ------------------------------------------------------------------------------------
Virtual Root HUB
------------------------------------------------------------------------------------ */
/* destination of request */
#define RH_INTERFACE 0x01
#define RH_ENDPOINT 0x02
#define RH_OTHER 0x03
#define RH_CLASS 0x20
#define RH_VENDOR 0x40
/* Requests: bRequest << 8 | bmRequestType */
#define RH_GET_STATUS 0x0080
#define RH_CLEAR_FEATURE 0x0100
#define RH_SET_FEATURE 0x0300
#define RH_SET_ADDRESS 0x0500
#define RH_GET_DESCRIPTOR 0x0680
#define RH_SET_DESCRIPTOR 0x0700
#define RH_GET_CONFIGURATION 0x0880
#define RH_SET_CONFIGURATION 0x0900
#define RH_GET_STATE 0x0280
#define RH_GET_INTERFACE 0x0A80
#define RH_SET_INTERFACE 0x0B00
#define RH_SYNC_FRAME 0x0C80
/* Our Vendor Specific Request */
#define RH_SET_EP 0x2000
/* Hub port features */
#define RH_PORT_CONNECTION 0x00
#define RH_PORT_ENABLE 0x01
#define RH_PORT_SUSPEND 0x02
#define RH_PORT_OVER_CURRENT 0x03
#define RH_PORT_RESET 0x04
#define RH_PORT_POWER 0x08
#define RH_PORT_LOW_SPEED 0x09
#define RH_C_PORT_CONNECTION 0x10
#define RH_C_PORT_ENABLE 0x11
#define RH_C_PORT_SUSPEND 0x12
#define RH_C_PORT_OVER_CURRENT 0x13
#define RH_C_PORT_RESET 0x14
/* Hub features */
#define RH_C_HUB_LOCAL_POWER 0x00
#define RH_C_HUB_OVER_CURRENT 0x01
#define RH_DEVICE_REMOTE_WAKEUP 0x00
#define RH_ENDPOINT_STALL 0x01
/* Our Vendor Specific feature */
#define RH_REMOVE_EP 0x00
#define RH_ACK 0x01
#define RH_REQ_ERR -1
#define RH_NACK 0x00
/* Transfer descriptor structure */
typedef struct {
unsigned long link; /* next td/qh (LE)*/
unsigned long status; /* status of the td */
unsigned long info; /* Max Lenght / Endpoint / device address and PID */
unsigned long buffer; /* pointer to data buffer (LE) */
unsigned long dev_ptr; /* pointer to the assigned device (BE) */
unsigned long res[3]; /* reserved (TDs must be 8Byte aligned) */
} uhci_td_t, *puhci_td_t;
/* Queue Header structure */
typedef struct {
unsigned long head; /* Next QH (LE)*/
unsigned long element; /* Queue element pointer (LE) */
unsigned long res[5]; /* reserved */
unsigned long dev_ptr; /* if 0 no tds have been assigned to this qh */
} uhci_qh_t, *puhci_qh_t;
struct virt_root_hub {
int devnum; /* Address of Root Hub endpoint */
int numports; /* number of ports */
int c_p_r[8]; /* C_PORT_RESET */
};
#endif /* _USB_UHCI_H_ */

View file

@ -0,0 +1,52 @@
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
ifneq ($(OBJTREE),$(SRCTREE))
$(shell mkdir -p $(obj)../common)
endif
LIB = $(obj)lib$(BOARD).o
COBJS = $(BOARD).o cmd_mip405.o \
../common/pci.o \
../common/usb_uhci.o \
../common/common_util.o
SOBJS = init.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
SOBJS := $(addprefix $(obj),$(SOBJS))
$(LIB): $(OBJS) $(SOBJS)
$(call cmd_link_o_target, $(OBJS) $(SOBJS))
#########################################################################
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################

View file

@ -0,0 +1,65 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* 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
*
* hacked for MIP405
*/
#include <common.h>
#include <command.h>
#include "mip405.h"
#include "../common/common_util.h"
extern void print_mip405_info(void);
extern int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
/* ------------------------------------------------------------------------- */
int do_mip405(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
ulong led_on;
if (strcmp(argv[1], "info") == 0)
{
print_mip405_info();
return 0;
}
if (strcmp(argv[1], "led") == 0)
{
led_on = (ulong)simple_strtoul(argv[2], NULL, 10);
user_led0(led_on);
return 0;
}
return (do_mplcommon(cmdtp, flag, argc, argv));
}
U_BOOT_CMD(
mip405, 8, 1, do_mip405,
"MIP405 specific Cmds",
"flash mem [SrcAddr] - updates U-Boot with image in memory\n"
"mip405 flash mps - updates U-Boot with image from MPS\n"
"mip405 info - displays board information\n"
"mip405 led <on> - switches LED on (on=1) or off (on=0)"
);
/* ------------------------------------------------------------------------- */

View file

@ -0,0 +1,221 @@
/*------------------------------------------------------------------------------+
* This source code is dual-licensed. You may use it under the terms of
* the GNU General Public License version 2, or under the license below.
*
* 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 or Multi Purpose Socket
* Bank 1 - Multi Purpose Socket or Flash (set in C-Code)
* Bank 2 - UART 1 (set in C-Code)
* Bank 3 - UART 2 (set in C-Code)
* Bank 4 - not used
* Bank 5 - not used
* Bank 6 - not used
* Bank 7 - PLD Register
*-----------------------------------------------------------------------------*/
#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
#include <configs/MIP405.h>
#include <ppc_asm.tmpl>
#include <ppc_defs.h>
#include <asm/cache.h>
#include <asm/mmu.h>
#include <asm/ppc4xx.h>
#include "mip405.h"
.globl ext_bus_cntlr_init
ext_bus_cntlr_init:
mflr r4 /* save link register */
mfdcr r3,CPC0_PSR /* get strapping reg */
andi. r0, r3, PSR_ROM_LOC /* mask out irrelevant bits */
bnelr /* jump back if PCI boot */
bl ..getAddr
..getAddr:
mflr r3 /* get address of ..getAddr */
mtlr r4 /* restore link register */
addi r4,0,14 /* set ctr to 14; used to prefetch */
mtctr r4 /* 14 cache lines to fit this function */
/* in cache (gives us 8x14=112 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 14 cache lines */
/*-------------------------------------------------------------------
* Delay to ensure all accesses to ROM are complete before changing
* bank 0 timings.
*------------------------------------------------------------------- */
addis r3,0,0x0
ori r3,r3,0xA000
mtctr r3
..spinlp:
bdnz ..spinlp /* spin loop */
/*-----------------------------------------------------------------------
* decide boot up mode
*----------------------------------------------------------------------- */
addi r4,0,PB0CR
mtdcr EBC0_CFGADDR,r4
mfdcr r4,EBC0_CFGDATA
andi. r0, r4, 0x2000 /* mask out irrelevant bits */
beq 0f /* jump if 8 bit bus width */
/* setup 16 bit things
*-----------------------------------------------------------------------
* Memory Bank 0 (16 Bit Flash) initialization
*---------------------------------------------------------------------- */
addi r4,0,PB1AP
mtdcr EBC0_CFGADDR,r4
addis r4,0,(FLASH_AP_B)@h
ori r4,r4,(FLASH_AP_B)@l
mtdcr EBC0_CFGDATA,r4
addi r4,0,PB0CR
mtdcr EBC0_CFGADDR,r4
/* BS=0x010(4MB),BU=0x3(R/W), */
addis r4,0,(FLASH_CR_B)@h
ori r4,r4,(FLASH_CR_B)@l
mtdcr EBC0_CFGDATA,r4
b 1f
0:
/* 8Bit boot mode: */
/*-----------------------------------------------------------------------
* Memory Bank 0 Multi Purpose Socket initialization
*----------------------------------------------------------------------- */
/* 0x7F8FFE80 slowest boot */
addi r4,0,PB1AP
mtdcr EBC0_CFGADDR,r4
addis r4,0,(MPS_AP_B)@h
ori r4,r4,(MPS_AP_B)@l
mtdcr EBC0_CFGDATA,r4
addi r4,0,PB0CR
mtdcr EBC0_CFGADDR,r4
/* BS=0x010(4MB),BU=0x3(R/W), */
addis r4,0,(MPS_CR_B)@h
ori r4,r4,(MPS_CR_B)@l
mtdcr EBC0_CFGDATA,r4
1:
/*-----------------------------------------------------------------------
* Memory Bank 2-3-4-5-6 (not used) initialization
*-----------------------------------------------------------------------*/
addi r4,0,PB1CR
mtdcr EBC0_CFGADDR,r4
addis r4,0,0x0000
ori r4,r4,0x0000
mtdcr EBC0_CFGDATA,r4
addi r4,0,PB2CR
mtdcr EBC0_CFGADDR,r4
addis r4,0,0x0000
ori r4,r4,0x0000
mtdcr EBC0_CFGDATA,r4
addi r4,0,PB3CR
mtdcr EBC0_CFGADDR,r4
addis r4,0,0x0000
ori r4,r4,0x0000
mtdcr EBC0_CFGDATA,r4
addi r4,0,PB4CR
mtdcr EBC0_CFGADDR,r4
addis r4,0,0x0000
ori r4,r4,0x0000
mtdcr EBC0_CFGDATA,r4
addi r4,0,PB5CR
mtdcr EBC0_CFGADDR,r4
addis r4,0,0x0000
ori r4,r4,0x0000
mtdcr EBC0_CFGDATA,r4
addi r4,0,PB6CR
mtdcr EBC0_CFGADDR,r4
addis r4,0,0x0000
ori r4,r4,0x0000
mtdcr EBC0_CFGDATA,r4
addi r4,0,PB7CR
mtdcr EBC0_CFGADDR,r4
addis r4,0,0x0000
ori r4,r4,0x0000
mtdcr EBC0_CFGDATA,r4
nop /* pass2 DCR errata #8 */
blr
#if defined(CONFIG_BOOT_PCI)
.section .bootpg,"ax"
.globl _start_pci
/*******************************************
*/
_start_pci:
/* first handle errata #68 / PCI_18 */
iccci r0, r0 /* invalidate I-cache */
lis r31, 0
mticcr r31 /* ICCR = 0 (all uncachable) */
isync
mfccr0 r28 /* set CCR0[24] = 1 */
ori r28, r28, 0x0080
mtccr0 r28
/* setup PMM0MA (0xEF400004) and PMM0PCIHA (0xEF40000C) */
lis r28, 0xEF40
addi r28, r28, 0x0004
stw r31, 0x0C(r28) /* clear PMM0PCIHA */
lis r29, 0xFFF8 /* open 512 kByte */
addi r29, r29, 0x0001/* and enable this region */
stwbrx r29, r0, r28 /* write PMM0MA */
lis r28, 0xEEC0 /* address of PCIC0_CFGADDR */
addi r29, r28, 4 /* add 4 to r29 -> PCIC0_CFGDATA */
lis r31, 0x8000 /* set en bit bus 0 */
ori r31, r31, 0x304C/* device 6 func 0 reg 4C (XBCS register) */
stwbrx r31, r0, r28 /* write it */
lwbrx r31, r0, r29 /* load XBCS register */
oris r31, r31, 0x02C4/* clear BIOSCS WPE, set lower, extended and 1M extended BIOS enable */
stwbrx r31, r0, r29 /* write back XBCS register */
nop
nop
b _start /* normal start */
#endif

View file

@ -0,0 +1,821 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* 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
*
*
* TODO: clean-up
*/
/*
* How do I program the SDRAM Timing Register (SDRAM0_TR) for a specific SDRAM or DIMM?
*
* As an example, consider a case where PC133 memory with CAS Latency equal to 2 is being
* used with a 200MHz 405GP. For a typical 128Mb, PC133 SDRAM, the relevant minimum
* parameters from the datasheet are:
* Tclk = 7.5ns (CL = 2)
* Trp = 15ns
* Trc = 60ns
* Trcd = 15ns
* Trfc = 66ns
*
* If we are operating the 405GP with the MemClk output frequency set to 100 MHZ, the clock
* period is 10ns and the parameters needed for the Timing Register are:
* CASL = CL = 2 clock cycles
* PTA = Trp = 15ns / 10ns = 2 clock cycles
* CTP = Trc - Trcd - Trp = (60ns - 15ns - 15ns) / 10ns= 3 clock cycles
* LDF = 2 clock cycles (but can be extended to meet board-level timing)
* RFTA = Trfc = 66ns / 10ns= 7 clock cycles
* RCD = Trcd = 15ns / 10ns= 2 clock cycles
*
* The actual bit settings in the register would be:
*
* CASL = 0b01
* PTA = 0b01
* CTP = 0b10
* LDF = 0b01
* RFTA = 0b011
* RCD = 0b01
*
* If Trfc is not specified in the datasheet for PC100 or PC133 memory, set RFTA = Trc
* instead. Figure 24 in the PC SDRAM Specification Rev. 1.7 shows refresh to active delay
* defined as Trc rather than Trfc.
* When using DIMM modules, most but not all of the required timing parameters can be read
* from the Serial Presence Detect (SPD) EEPROM on the module. Specifically, Trc and Trfc
* are not available from the EEPROM
*/
#include <common.h>
#include "mip405.h"
#include <asm/processor.h>
#include <asm/ppc4xx.h>
#include <asm/ppc4xx-i2c.h>
#include <miiphy.h>
#include "../common/common_util.h"
#include <stdio_dev.h>
#include <i2c.h>
#include <rtc.h>
DECLARE_GLOBAL_DATA_PTR;
#undef SDRAM_DEBUG
#define ENABLE_ECC /* for ecc boards */
#define FALSE 0
#define TRUE 1
/* 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
#define PLD_PART_REG PER_PLD_ADDR + 0
#define PLD_VERS_REG PER_PLD_ADDR + 1
#define PLD_BOARD_CFG_REG PER_PLD_ADDR + 2
#define PLD_IRQ_REG PER_PLD_ADDR + 3
#define PLD_COM_MODE_REG PER_PLD_ADDR + 4
#define PLD_EXT_CONF_REG PER_PLD_ADDR + 5
#define MEGA_BYTE (1024*1024)
typedef struct {
unsigned char boardtype; /* Board revision and Population Options */
unsigned char cal; /* cas Latency (will be programmend as cal-1) */
unsigned char trp; /* datain27 in clocks */
unsigned char trcd; /* datain29 in clocks */
unsigned char tras; /* datain30 in clocks */
unsigned char tctp; /* tras - trcd in clocks */
unsigned char am; /* Address Mod (will be programmed as am-1) */
unsigned char sz; /* log binary => Size = (4MByte<<sz) 5 = 128, 4 = 64, 3 = 32, 2 = 16, 1=8 */
unsigned char ecc; /* if true, ecc is enabled */
} sdram_t;
#if defined(CONFIG_MIP405T)
const sdram_t sdram_table[] = {
{ 0x0F, /* MIP405T Rev A, 64MByte -1 Board */
3, /* Case Latenty = 3 */
3, /* trp 20ns / 7.5 ns datain[27] */
3, /* trcd 20ns /7.5 ns (datain[29]) */
6, /* tras 44ns /7.5 ns (datain[30]) */
4, /* tcpt 44 - 20ns = 24ns */
2, /* Address Mode = 2 (12x9x4) */
3, /* size value (32MByte) */
0}, /* ECC disabled */
{ 0xff, /* terminator */
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff }
};
#else
const sdram_t sdram_table[] = {
{ 0x0f, /* Rev A, 128MByte -1 Board */
3, /* Case Latenty = 3 */
3, /* trp 20ns / 7.5 ns datain[27] */
3, /* trcd 20ns /7.5 ns (datain[29]) */
6, /* tras 44ns /7.5 ns (datain[30]) */
4, /* tcpt 44 - 20ns = 24ns */
3, /* Address Mode = 3 */
5, /* size value */
1}, /* ECC enabled */
{ 0x07, /* Rev A, 64MByte -2 Board */
3, /* Case Latenty = 3 */
3, /* trp 20ns / 7.5 ns datain[27] */
3, /* trcd 20ns /7.5 ns (datain[29]) */
6, /* tras 44ns /7.5 ns (datain[30]) */
4, /* tcpt 44 - 20ns = 24ns */
2, /* Address Mode = 2 */
4, /* size value */
1}, /* ECC enabled */
{ 0x03, /* Rev A, 128MByte -4 Board */
3, /* Case Latenty = 3 */
3, /* trp 20ns / 7.5 ns datain[27] */
3, /* trcd 20ns /7.5 ns (datain[29]) */
6, /* tras 44ns /7.5 ns (datain[30]) */
4, /* tcpt 44 - 20ns = 24ns */
3, /* Address Mode = 3 */
5, /* size value */
1}, /* ECC enabled */
{ 0x1f, /* Rev B, 128MByte -3 Board */
3, /* Case Latenty = 3 */
3, /* trp 20ns / 7.5 ns datain[27] */
3, /* trcd 20ns /7.5 ns (datain[29]) */
6, /* tras 44ns /7.5 ns (datain[30]) */
4, /* tcpt 44 - 20ns = 24ns */
3, /* Address Mode = 3 */
5, /* size value */
1}, /* ECC enabled */
{ 0x2f, /* Rev C, 128MByte -3 Board */
3, /* Case Latenty = 3 */
3, /* trp 20ns / 7.5 ns datain[27] */
3, /* trcd 20ns /7.5 ns (datain[29]) */
6, /* tras 44ns /7.5 ns (datain[30]) */
4, /* tcpt 44 - 20ns = 24ns */
3, /* Address Mode = 3 */
5, /* size value */
1}, /* ECC enabled */
{ 0xff, /* terminator */
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff }
};
#endif /*CONFIG_MIP405T */
void SDRAM_err (const char *s)
{
#ifndef SDRAM_DEBUG
(void) get_clocks ();
gd->baudrate = 9600;
serial_init ();
#endif
serial_puts ("\n");
serial_puts (s);
serial_puts ("\n enable SDRAM_DEBUG for more info\n");
for (;;);
}
unsigned char get_board_revcfg (void)
{
out8 (PER_BOARD_ADDR, 0);
return (in8 (PER_BOARD_ADDR));
}
#ifdef SDRAM_DEBUG
void write_hex (unsigned char i)
{
char cc;
cc = i >> 4;
cc &= 0xf;
if (cc > 9)
serial_putc (cc + 55);
else
serial_putc (cc + 48);
cc = i & 0xf;
if (cc > 9)
serial_putc (cc + 55);
else
serial_putc (cc + 48);
}
void write_4hex (unsigned long val)
{
write_hex ((unsigned char) (val >> 24));
write_hex ((unsigned char) (val >> 16));
write_hex ((unsigned char) (val >> 8));
write_hex ((unsigned char) val);
}
#endif
int init_sdram (void)
{
unsigned long tmp, baseaddr;
unsigned short i;
unsigned char trp_clocks,
trcd_clocks,
tras_clocks,
trc_clocks;
unsigned char cal_val;
unsigned char bc;
unsigned long sdram_tim, sdram_bank;
/*i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);*/
(void) get_clocks ();
gd->baudrate = 9600;
serial_init ();
/* set up the pld */
mtdcr (EBC0_CFGADDR, PB7AP);
mtdcr (EBC0_CFGDATA, PLD_AP);
mtdcr (EBC0_CFGADDR, PB7CR);
mtdcr (EBC0_CFGDATA, PLD_CR);
/* THIS IS OBSOLETE */
/* set up the board rev reg*/
mtdcr (EBC0_CFGADDR, PB5AP);
mtdcr (EBC0_CFGDATA, BOARD_AP);
mtdcr (EBC0_CFGADDR, PB5CR);
mtdcr (EBC0_CFGDATA, BOARD_CR);
#ifdef SDRAM_DEBUG
/* get all informations from PLD */
serial_puts ("\nPLD Part 0x");
bc = in8 (PLD_PART_REG);
write_hex (bc);
serial_puts ("\nPLD Vers 0x");
bc = in8 (PLD_VERS_REG);
write_hex (bc);
serial_puts ("\nBoard Rev 0x");
bc = in8 (PLD_BOARD_CFG_REG);
write_hex (bc);
serial_puts ("\n");
#endif
/* check board */
bc = in8 (PLD_PART_REG);
#if defined(CONFIG_MIP405T)
if((bc & 0x80)==0)
SDRAM_err ("U-Boot configured for a MIP405T not for a MIP405!!!\n");
#else
if((bc & 0x80)==0x80)
SDRAM_err ("U-Boot configured for a MIP405 not for a MIP405T!!!\n");
#endif
/* set-up the chipselect machine */
mtdcr (EBC0_CFGADDR, PB0CR); /* get cs0 config reg */
tmp = mfdcr (EBC0_CFGDATA);
if ((tmp & 0x00002000) == 0) {
/* MPS Boot, set up the flash */
mtdcr (EBC0_CFGADDR, PB1AP);
mtdcr (EBC0_CFGDATA, FLASH_AP);
mtdcr (EBC0_CFGADDR, PB1CR);
mtdcr (EBC0_CFGDATA, FLASH_CR);
} else {
/* Flash boot, set up the MPS */
mtdcr (EBC0_CFGADDR, PB1AP);
mtdcr (EBC0_CFGDATA, MPS_AP);
mtdcr (EBC0_CFGADDR, PB1CR);
mtdcr (EBC0_CFGDATA, MPS_CR);
}
/* set up UART0 (CS2) and UART1 (CS3) */
mtdcr (EBC0_CFGADDR, PB2AP);
mtdcr (EBC0_CFGDATA, UART0_AP);
mtdcr (EBC0_CFGADDR, PB2CR);
mtdcr (EBC0_CFGDATA, UART0_CR);
mtdcr (EBC0_CFGADDR, PB3AP);
mtdcr (EBC0_CFGDATA, UART1_AP);
mtdcr (EBC0_CFGADDR, PB3CR);
mtdcr (EBC0_CFGDATA, UART1_CR);
bc = in8 (PLD_BOARD_CFG_REG);
#ifdef SDRAM_DEBUG
serial_puts ("\nstart SDRAM Setup\n");
serial_puts ("\nBoard Rev: ");
write_hex (bc);
serial_puts ("\n");
#endif
i = 0;
baseaddr = CONFIG_SYS_SDRAM_BASE;
while (sdram_table[i].sz != 0xff) {
if (sdram_table[i].boardtype == bc)
break;
i++;
}
if (sdram_table[i].boardtype != bc)
SDRAM_err ("No SDRAM table found for this board!!!\n");
#ifdef SDRAM_DEBUG
serial_puts (" found table ");
write_hex (i);
serial_puts (" \n");
#endif
/* since the ECC initialisation needs some time,
* we show that we're alive
*/
if (sdram_table[i].ecc)
serial_puts ("\nInitializing SDRAM, Please stand by");
cal_val = sdram_table[i].cal - 1; /* Cas Latency */
trp_clocks = sdram_table[i].trp; /* 20ns / 7.5 ns datain[27] */
trcd_clocks = sdram_table[i].trcd; /* 20ns /7.5 ns (datain[29]) */
tras_clocks = sdram_table[i].tras; /* 44ns /7.5 ns (datain[30]) */
/* ctp = ((trp + tras) - trp - trcd) => tras - trcd */
/* trc_clocks is sum of trp_clocks + tras_clocks */
trc_clocks = trp_clocks + tras_clocks;
/* get SDRAM timing register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_TR);
sdram_tim = mfdcr (SDRAM0_CFGDATA) & ~0x018FC01F;
/* insert CASL value */
sdram_tim |= ((unsigned long) (cal_val)) << 23;
/* insert PTA value */
sdram_tim |= ((unsigned long) (trp_clocks - 1)) << 18;
/* insert CTP value */
sdram_tim |=
((unsigned long) (trc_clocks - trp_clocks -
trcd_clocks)) << 16;
/* insert LDF (always 01) */
sdram_tim |= ((unsigned long) 0x01) << 14;
/* insert RFTA value */
sdram_tim |= ((unsigned long) (trc_clocks - 4)) << 2;
/* insert RCD value */
sdram_tim |= ((unsigned long) (trcd_clocks - 1)) << 0;
tmp = ((unsigned long) (sdram_table[i].am - 1) << 13); /* AM = 3 */
/* insert SZ value; */
tmp |= ((unsigned long) sdram_table[i].sz << 17);
/* get SDRAM bank 0 register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_B0CR);
sdram_bank = mfdcr (SDRAM0_CFGDATA) & ~0xFFCEE001;
sdram_bank |= (baseaddr | tmp | 0x01);
#ifdef SDRAM_DEBUG
serial_puts ("sdtr: ");
write_4hex (sdram_tim);
serial_puts ("\n");
#endif
/* write SDRAM timing register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_TR);
mtdcr (SDRAM0_CFGDATA, sdram_tim);
#ifdef SDRAM_DEBUG
serial_puts ("mb0cf: ");
write_4hex (sdram_bank);
serial_puts ("\n");
#endif
/* write SDRAM bank 0 register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_B0CR);
mtdcr (SDRAM0_CFGDATA, sdram_bank);
if (get_bus_freq (tmp) > 110000000) { /* > 110MHz */
/* get SDRAM refresh interval register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_RTR);
tmp = mfdcr (SDRAM0_CFGDATA) & ~0x3FF80000;
tmp |= 0x07F00000;
} else {
/* get SDRAM refresh interval register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_RTR);
tmp = mfdcr (SDRAM0_CFGDATA) & ~0x3FF80000;
tmp |= 0x05F00000;
}
/* write SDRAM refresh interval register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_RTR);
mtdcr (SDRAM0_CFGDATA, tmp);
/* enable ECC if used */
#if defined(ENABLE_ECC) && !defined(CONFIG_BOOT_PCI)
if (sdram_table[i].ecc) {
/* disable checking for all banks */
unsigned long *p;
#ifdef SDRAM_DEBUG
serial_puts ("disable ECC.. ");
#endif
mtdcr (SDRAM0_CFGADDR, SDRAM0_ECCCFG);
tmp = mfdcr (SDRAM0_CFGDATA);
tmp &= 0xff0fffff; /* disable all banks */
mtdcr (SDRAM0_CFGADDR, SDRAM0_ECCCFG);
/* set up SDRAM Controller with ECC enabled */
#ifdef SDRAM_DEBUG
serial_puts ("setup SDRAM Controller.. ");
#endif
mtdcr (SDRAM0_CFGDATA, tmp);
mtdcr (SDRAM0_CFGADDR, SDRAM0_CFG);
tmp = (mfdcr (SDRAM0_CFGDATA) & ~0xFFE00000) | 0x90800000;
mtdcr (SDRAM0_CFGADDR, SDRAM0_CFG);
mtdcr (SDRAM0_CFGDATA, tmp);
udelay (600);
#ifdef SDRAM_DEBUG
serial_puts ("fill the memory..\n");
#endif
serial_puts (".");
/* now, fill all the memory */
tmp = ((4 * MEGA_BYTE) << sdram_table[i].sz);
p = (unsigned long) 0;
while ((unsigned long) p < tmp) {
*p++ = 0L;
if (!((unsigned long) p % 0x00800000)) /* every 8MByte */
serial_puts (".");
}
/* enable bank 0 */
serial_puts (".");
#ifdef SDRAM_DEBUG
serial_puts ("enable ECC\n");
#endif
udelay (400);
mtdcr (SDRAM0_CFGADDR, SDRAM0_ECCCFG);
tmp = mfdcr (SDRAM0_CFGDATA);
tmp |= 0x00800000; /* enable bank 0 */
mtdcr (SDRAM0_CFGDATA, tmp);
udelay (400);
} else
#endif
{
/* enable SDRAM controller with no ECC, 32-bit SDRAM width, 16 byte burst */
mtdcr (SDRAM0_CFGADDR, SDRAM0_CFG);
tmp = (mfdcr (SDRAM0_CFGDATA) & ~0xFFE00000) | 0x80C00000;
mtdcr (SDRAM0_CFGADDR, SDRAM0_CFG);
mtdcr (SDRAM0_CFGDATA, tmp);
udelay (400);
}
serial_puts ("\n");
return (0);
}
int board_early_init_f (void)
{
init_sdram ();
/*-------------------------------------------------------------------------+
| Interrupt controller setup for the PIP405 board.
| Note: IRQ 0-15 405GP internally generated; active high; level sensitive
| IRQ 16 405GP internally generated; active low; level sensitive
| IRQ 17-24 RESERVED
| IRQ 25 (EXT IRQ 0) SouthBridge; active low; level sensitive
| IRQ 26 (EXT IRQ 1) NMI: active low; level sensitive
| IRQ 27 (EXT IRQ 2) SMI: active Low; level sensitive
| IRQ 28 (EXT IRQ 3) PCI SLOT 3; active low; level sensitive
| IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive
| IRQ 30 (EXT IRQ 5) PCI SLOT 1; active low; level sensitive
| IRQ 31 (EXT IRQ 6) PCI SLOT 0; active low; level sensitive
| Note for MIP405 board:
| An interrupt taken for the SouthBridge (IRQ 25) indicates that
| the Interrupt Controller in the South Bridge has caused the
| interrupt. The IC must be read to determine which device
| caused the interrupt.
|
+-------------------------------------------------------------------------*/
mtdcr (UIC0SR, 0xFFFFFFFF); /* clear all ints */
mtdcr (UIC0ER, 0x00000000); /* disable all ints */
mtdcr (UIC0CR, 0x00000000); /* set all to be non-critical (for now) */
mtdcr (UIC0PR, 0xFFFFFF80); /* set int polarities */
mtdcr (UIC0TR, 0x10000000); /* set int trigger levels */
mtdcr (UIC0VCR, 0x00000001); /* set vect base=0,INT0 highest priority */
mtdcr (UIC0SR, 0xFFFFFFFF); /* clear all ints */
return 0;
}
int board_early_init_r(void)
{
int mode;
/*
* since we are relocated, we can finally enable i-cache
* and set up the flash CS correctly
*/
icache_enable();
setup_cs_reloc();
/* get and display boot mode */
mode = get_boot_mode();
if (mode & BOOT_PCI)
printf("PCI Boot %s Map\n", (mode & BOOT_MPS) ?
"MPS" : "Flash");
else
printf("%s Boot\n", (mode & BOOT_MPS) ?
"MPS" : "Flash");
return 0;
}
/*
* Get some PLD Registers
*/
unsigned short get_pld_parvers (void)
{
unsigned short result;
unsigned char rc;
rc = in8 (PLD_PART_REG);
result = (unsigned short) rc << 8;
rc = in8 (PLD_VERS_REG);
result |= rc;
return result;
}
void user_led0 (unsigned char on)
{
if (on)
out8 (PLD_COM_MODE_REG, (in8 (PLD_COM_MODE_REG) | 0x4));
else
out8 (PLD_COM_MODE_REG, (in8 (PLD_COM_MODE_REG) & 0xfb));
}
void ide_set_reset (int idereset)
{
/* if reset = 1 IDE reset will be asserted */
if (idereset)
out8 (PLD_COM_MODE_REG, (in8 (PLD_COM_MODE_REG) | 0x1));
else {
udelay (10000);
out8 (PLD_COM_MODE_REG, (in8 (PLD_COM_MODE_REG) & 0xfe));
}
}
/* ------------------------------------------------------------------------- */
void get_pcbrev_var(unsigned char *pcbrev, unsigned char *var)
{
#if !defined(CONFIG_MIP405T)
unsigned char bc,rc,tmp;
int i;
bc = in8 (PLD_BOARD_CFG_REG);
tmp = ~bc;
tmp &= 0xf;
rc = 0;
for (i = 0; i < 4; i++) {
rc <<= 1;
rc += (tmp & 0x1);
tmp >>= 1;
}
rc++;
if(( (((bc>>4) & 0xf)==0x2) /* Rev C PCB or */
|| (((bc>>4) & 0xf)==0x1)) /* Rev B PCB with */
&& (rc==0x1)) /* Population Option 1 is a -3 */
rc=3;
*pcbrev=(bc >> 4) & 0xf;
*var=rc;
#else
unsigned char bc;
bc = in8 (PLD_BOARD_CFG_REG);
*pcbrev=(bc >> 4) & 0xf;
*var=16-(bc & 0xf);
#endif
}
/*
* Check Board Identity:
*/
/* serial String: "MIP405_1000" OR "MIP405T_1000" */
#if !defined(CONFIG_MIP405T)
#define BOARD_NAME "MIP405"
#else
#define BOARD_NAME "MIP405T"
#endif
int checkboard (void)
{
char s[50];
unsigned char bc, var;
int i;
backup_t *b = (backup_t *) s;
puts ("Board: ");
get_pcbrev_var(&bc,&var);
i = getenv_f("serial#", (char *)s, 32);
if ((i == 0) || strncmp ((char *)s, BOARD_NAME,sizeof(BOARD_NAME))) {
get_backup_values (b);
if (strncmp (b->signature, "MPL\0", 4) != 0) {
puts ("### No HW ID - assuming " BOARD_NAME);
printf ("-%d Rev %c", var, 'A' + bc);
} else {
b->serial_name[sizeof(BOARD_NAME)-1] = 0;
printf ("%s-%d Rev %c SN: %s", b->serial_name, var,
'A' + bc, &b->serial_name[sizeof(BOARD_NAME)]);
}
} else {
s[sizeof(BOARD_NAME)-1] = 0;
printf ("%s-%d Rev %c SN: %s", s, var,'A' + bc,
&s[sizeof(BOARD_NAME)]);
}
bc = in8 (PLD_EXT_CONF_REG);
printf (" Boot Config: 0x%x\n", bc);
return (0);
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/*
initdram(int board_type) reads EEPROM via I2c. EEPROM contains all of
the necessary info for SDRAM controller configuration
*/
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
static int test_dram (unsigned long ramsize);
phys_size_t initdram (int board_type)
{
unsigned long bank_reg[4], tmp, bank_size;
int i;
unsigned long TotalSize;
/* since the DRAM controller is allready set up, calculate the size with the
bank registers */
mtdcr (SDRAM0_CFGADDR, SDRAM0_B0CR);
bank_reg[0] = mfdcr (SDRAM0_CFGDATA);
mtdcr (SDRAM0_CFGADDR, SDRAM0_B1CR);
bank_reg[1] = mfdcr (SDRAM0_CFGDATA);
mtdcr (SDRAM0_CFGADDR, SDRAM0_B2CR);
bank_reg[2] = mfdcr (SDRAM0_CFGDATA);
mtdcr (SDRAM0_CFGADDR, SDRAM0_B3CR);
bank_reg[3] = mfdcr (SDRAM0_CFGDATA);
TotalSize = 0;
for (i = 0; i < 4; i++) {
if ((bank_reg[i] & 0x1) == 0x1) {
tmp = (bank_reg[i] >> 17) & 0x7;
bank_size = 4 << tmp;
TotalSize += bank_size;
}
}
mtdcr (SDRAM0_CFGADDR, SDRAM0_ECCCFG);
tmp = mfdcr (SDRAM0_CFGDATA);
if (!tmp)
printf ("No ");
printf ("ECC ");
test_dram (TotalSize * MEGA_BYTE);
return (TotalSize * MEGA_BYTE);
}
/* ------------------------------------------------------------------------- */
static int test_dram (unsigned long ramsize)
{
#ifdef SDRAM_DEBUG
mem_test (0L, ramsize, 1);
#endif
/* not yet implemented */
return (1);
}
/* used to check if the time in RTC is valid */
static unsigned long start;
static struct rtc_time tm;
int misc_init_r (void)
{
/* adjust flash start and size as well as the offset */
gd->bd->bi_flashstart=0-flash_info[0].size;
gd->bd->bi_flashsize=flash_info[0].size-CONFIG_SYS_MONITOR_LEN;
gd->bd->bi_flashoffset=0;
/* check, if RTC is running */
rtc_get (&tm);
start=get_timer(0);
/* if MIP405 has booted from PCI, reset CCR0[24] as described in errata PCI_18 */
if (mfdcr(CPC0_PSR) & PSR_ROM_LOC)
mtspr(SPRN_CCR0, (mfspr(SPRN_CCR0) & ~0x80));
return (0);
}
void print_mip405_rev (void)
{
unsigned char part, vers, pcbrev, var;
get_pcbrev_var(&pcbrev,&var);
part = in8 (PLD_PART_REG);
vers = in8 (PLD_VERS_REG);
printf ("Rev: " BOARD_NAME "-%d Rev %c PLD %d Vers %d\n",
var, pcbrev + 'A', part & 0x7F, vers);
}
extern int mk_date (char *, struct rtc_time *);
int last_stage_init (void)
{
unsigned long stop;
struct rtc_time newtm;
char *s;
/* write correct LED configuration */
if (miiphy_write("ppc_4xx_eth0", 0x1, 0x14, 0x2402) != 0) {
printf ("Error writing to the PHY\n");
}
/* since LED/CFG2 is not connected on the -2,
* write to correct capability information */
if (miiphy_write("ppc_4xx_eth0", 0x1, 0x4, 0x01E1) != 0) {
printf ("Error writing to the PHY\n");
}
print_mip405_rev ();
stdio_print_current_devices ();
check_env ();
/* check if RTC time is valid */
stop=get_timer(start);
while(stop<1200) { /* we wait 1.2 sec to check if the RTC is running */
udelay(1000);
stop=get_timer(start);
}
rtc_get (&newtm);
if(tm.tm_sec==newtm.tm_sec) {
s=getenv("defaultdate");
if(!s)
mk_date ("010112001970", &newtm);
else
if(mk_date (s, &newtm)!=0) {
printf("RTC: Bad date format in defaultdate\n");
return 0;
}
rtc_reset ();
rtc_set(&newtm);
}
return 0;
}
/***************************************************************************
* some helping routines
*/
int overwrite_console (void)
{
return ((in8 (PLD_EXT_CONF_REG) & 0x1)==0); /* return TRUE if console should be overwritten */
}
/************************************************************************
* Print MIP405 Info
************************************************************************/
void print_mip405_info (void)
{
unsigned char part, vers, cfg, irq_reg, com_mode, ext;
part = in8 (PLD_PART_REG);
vers = in8 (PLD_VERS_REG);
cfg = in8 (PLD_BOARD_CFG_REG);
irq_reg = in8 (PLD_IRQ_REG);
com_mode = in8 (PLD_COM_MODE_REG);
ext = in8 (PLD_EXT_CONF_REG);
printf ("PLD Part %d version %d\n", part & 0x7F, vers);
printf ("Board Revision %c\n", ((cfg >> 4) & 0xf) + 'A');
printf ("Population Options %d %d %d %d\n", (cfg) & 0x1,
(cfg >> 1) & 0x1, (cfg >> 2) & 0x1, (cfg >> 3) & 0x1);
printf ("User LED %s\n", (com_mode & 0x4) ? "on" : "off");
printf ("UART Clocks %d\n", (com_mode >> 4) & 0x3);
#if !defined(CONFIG_MIP405T)
printf ("User Config Switch %d %d %d %d %d %d %d %d\n",
(ext) & 0x1, (ext >> 1) & 0x1, (ext >> 2) & 0x1,
(ext >> 3) & 0x1, (ext >> 4) & 0x1, (ext >> 5) & 0x1,
(ext >> 6) & 0x1, (ext >> 7) & 0x1);
printf ("SER1 uses handshakes %s\n",
(ext & 0x80) ? "DTR/DSR" : "RTS/CTS");
#else
printf ("User Config Switch %d %d %d %d %d %d %d %d\n",
(ext) & 0x1, (ext >> 1) & 0x1, (ext >> 2) & 0x1,
(ext >> 3) & 0x1, (ext >> 4) & 0x1, (ext >> 5) & 0x1,
(ext >> 6) & 0x1,(ext >> 7) & 0x1);
#endif
printf ("IDE Reset %s\n", (ext & 0x01) ? "asserted" : "not asserted");
printf ("IRQs:\n");
printf (" PIIX INTR: %s\n", (irq_reg & 0x80) ? "inactive" : "active");
#if !defined(CONFIG_MIP405T)
printf (" UART0 IRQ: %s\n", (irq_reg & 0x40) ? "inactive" : "active");
printf (" UART1 IRQ: %s\n", (irq_reg & 0x20) ? "inactive" : "active");
#endif
printf (" PIIX SMI: %s\n", (irq_reg & 0x10) ? "inactive" : "active");
printf (" PIIX INIT: %s\n", (irq_reg & 0x8) ? "inactive" : "active");
printf (" PIIX NMI: %s\n", (irq_reg & 0x4) ? "inactive" : "active");
}

View file

@ -0,0 +1,183 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* 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
*
*/
/****************************************************************************
* Global routines used for MIP405
*****************************************************************************/
#ifndef __ASSEMBLY__
/*int switch_cs(unsigned char boot);*/
extern int mem_test(unsigned long start, unsigned long ramsize,int mode);
void user_led0(unsigned char on);
#endif
/* timings */
/* PLD (CS7) */
#define PLD_BME 0 /* Burst disable */
#define PLD_TWE 5 /* 5 * 30ns 120ns Waitstates (access=TWT+1+TH) */
#define PLD_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
#define PLD_OEN 1 /* Cycles from CS low to OE low */
#define PLD_WBN 1 /* Cycles from CS low to WE low */
#define PLD_WBF 1 /* Cycles from WE high to CS high */
#define PLD_TH 2 /* Number of hold cycles after transfer */
#define PLD_RE 0 /* Ready disabled */
#define PLD_SOR 1 /* Sample on Ready disabled */
#define PLD_BEM 0 /* Byte Write only active on Write cycles */
#define PLD_PEN 0 /* Parity disable */
#define PLD_AP ((PLD_BME << 31) + (PLD_TWE << 23) + (PLD_CSN << 18) + (PLD_OEN << 16) + (PLD_WBN << 14) + \
(PLD_WBF << 12) + (PLD_TH << 9) + (PLD_RE << 8) + (PLD_SOR << 7) + (PLD_BEM << 6) + (PLD_PEN << 5))
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
#define PLD_BS 0 /* 1 MByte */
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
#define PLD_BU 3 /* R/W */
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
#define PLD_BW 0 /* 16Bit */
#define PLD_CR ((PER_PLD_ADDR & 0xfff00000) + (PLD_BS << 17) + (PLD_BU << 15) + (PLD_BW << 13))
/* timings */
#define PER_BOARD_ADDR (PER_UART1_ADDR+(1024*1024))
/* Dummy CS to get the board revision */
#define BOARD_BME 0 /* Burst disable */
#define BOARD_TWE 255 /* 255 * 30ns 120ns Waitstates (access=TWT+1+TH) */
#define BOARD_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
#define BOARD_OEN 1 /* Cycles from CS low to OE low */
#define BOARD_WBN 1 /* Cycles from CS low to WE low */
#define BOARD_WBF 1 /* Cycles from WE high to CS high */
#define BOARD_TH 2 /* Number of hold cycles after transfer */
#define BOARD_RE 0 /* Ready disabled */
#define BOARD_SOR 1 /* Sample on Ready disabled */
#define BOARD_BEM 0 /* Byte Write only active on Write cycles */
#define BOARD_PEN 0 /* Parity disable */
#define BOARD_AP ((BOARD_BME << 31) + (BOARD_TWE << 23) + (BOARD_CSN << 18) + (BOARD_OEN << 16) + (BOARD_WBN << 14) + \
(BOARD_WBF << 12) + (BOARD_TH << 9) + (BOARD_RE << 8) + (BOARD_SOR << 7) + (BOARD_BEM << 6) + (BOARD_PEN << 5))
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
#define BOARD_BS 0 /* 1 MByte */
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
#define BOARD_BU 3 /* R/W */
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
#define BOARD_BW 0 /* 16Bit */
#define BOARD_CR ((PER_BOARD_ADDR & 0xfff00000) + (BOARD_BS << 17) + (BOARD_BU << 15) + (BOARD_BW << 13))
/* UART0 CS2 */
#define UART0_BME 0 /* Burst disable */
#define UART0_TWE 7 /* 7 * 30ns 210ns Waitstates (access=TWT+1+TH) */
#define UART0_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
#define UART0_OEN 1 /* Cycles from CS low to OE low */
#define UART0_WBN 1 /* Cycles from CS low to WE low */
#define UART0_WBF 1 /* Cycles from WE high to CS high */
#define UART0_TH 2 /* Number of hold cycles after transfer */
#define UART0_RE 0 /* Ready disabled */
#define UART0_SOR 1 /* Sample on Ready disabled */
#define UART0_BEM 0 /* Byte Write only active on Write cycles */
#define UART0_PEN 0 /* Parity disable */
#define UART0_AP ((UART0_BME << 31) + (UART0_TWE << 23) + (UART0_CSN << 18) + (UART0_OEN << 16) + (UART0_WBN << 14) + \
(UART0_WBF << 12) + (UART0_TH << 9) + (UART0_RE << 8) + (UART0_SOR << 7) + (UART0_BEM << 6) + (UART0_PEN << 5))
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
#define UART0_BS 0 /* 1 MByte */
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
#define UART0_BU 3 /* R/W */
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
#define UART0_BW 0 /* 8Bit */
#define UART0_CR ((PER_UART0_ADDR & 0xfff00000) + (UART0_BS << 17) + (UART0_BU << 15) + (UART0_BW << 13))
/* UART1 CS3 */
#define UART1_AP UART0_AP /* same timing as UART0 */
#define UART1_CR ((PER_UART1_ADDR & 0xfff00000) + (UART0_BS << 17) + (UART0_BU << 15) + (UART0_BW << 13))
/* Flash CS0 or CS 1 */
/* 0x7F8FFE80 slowest timing at all... */
#define FLASH_BME_B 1 /* Burst enable */
#define FLASH_FWT_B 0x6 /* 6 * 30ns 210ns First Wait Access */
#define FLASH_BWT_B 0x6 /* 6 * 30ns 210ns Burst Wait Access */
#define FLASH_BME 0 /* Burst disable */
#define FLASH_TWE 0xb/* 11 * 30ns 330ns Waitstates (access=TWT+1+TH) */
#define FLASH_CSN 0 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
#define FLASH_OEN 1 /* Cycles from CS low to OE low */
#define FLASH_WBN 1 /* Cycles from CS low to WE low */
#define FLASH_WBF 1 /* Cycles from WE high to CS high */
#define FLASH_TH 2 /* Number of hold cycles after transfer */
#define FLASH_RE 0 /* Ready disabled */
#define FLASH_SOR 1 /* Sample on Ready disabled */
#define FLASH_BEM 0 /* Byte Write only active on Write cycles */
#define FLASH_PEN 0 /* Parity disable */
/* Access Parameter Register for non Boot */
#define FLASH_AP ((FLASH_BME << 31) + (FLASH_TWE << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \
(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
/* Access Parameter Register for Boot */
#define FLASH_AP_B ((FLASH_BME_B << 31) + (FLASH_FWT_B << 26) + (FLASH_BWT_B << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \
(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
#define FLASH_BS FLASH_SIZE_PRELIM /* 4 MByte */
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
#define FLASH_BU 3 /* R/W */
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
#define FLASH_BW 1 /* 16Bit */
/* CR register for Boot */
#define FLASH_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
/* CR register for non Boot */
#define FLASH_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
/* MPS CS1 or CS0 */
/* Boot CS: */
#define MPS_BME_B 1 /* Burst enable */
#define MPS_FWT_B 0x6/* 6 * 30ns 210ns First Wait Access */
#define MPS_BWT_B 0x6 /* 6 * 30ns 210ns Burst Wait Access */
#define MPS_BME 0 /* Burst disable */
#define MPS_TWE 0xb/* 11 * 30ns 330ns Waitstates (access=TWT+1+TH) */
#define MPS_CSN 0 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
#define MPS_OEN 1 /* Cycles from CS low to OE low */
#define MPS_WBN 1 /* Cycles from CS low to WE low */
#define MPS_WBF 1 /* Cycles from WE high to CS high */
#define MPS_TH 2 /* Number of hold cycles after transfer */
#define MPS_RE 0 /* Ready disabled */
#define MPS_SOR 1 /* Sample on Ready disabled */
#define MPS_BEM 0 /* Byte Write only active on Write cycles */
#define MPS_PEN 0 /* Parity disable */
/* Access Parameter Register for non Boot */
#define MPS_AP ((MPS_BME << 31) + (MPS_TWE << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
(MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
/* Access Parameter Register for Boot */
#define MPS_AP_B ((MPS_BME_B << 31) + (MPS_FWT_B << 26) + (MPS_BWT_B << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
(MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
#define MPS_BS 2 /* 4 MByte */
#define MPS_BS_B FLASH_SIZE_PRELIM /* 1 MByte */
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
#define MPS_BU 3 /* R/W */
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
#define MPS_BW 0 /* 8Bit */
/* CR register for Boot */
#define MPS_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (MPS_BS_B << 17) + (MPS_BU << 15) + (MPS_BW << 13))
/* CR register for non Boot */
#define MPS_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))

View file

@ -0,0 +1,48 @@
#
# (C) Copyright 2001-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
ifneq ($(OBJTREE),$(SRCTREE))
$(shell mkdir -p $(obj)../common)
endif
LIB = $(obj)lib$(BOARD).o
COBJS := $(BOARD).o cmd_pati.o \
../common/common_util.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
SOBJS := $(addprefix $(obj),$(SOBJS))
$(LIB): $(obj).depend $(OBJS)
$(call cmd_link_o_target, $(OBJS))
#########################################################################
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################

View file

@ -0,0 +1,449 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* 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
*
* Adapted for PATI
*/
#include <common.h>
#include <command.h>
#define PLX9056_LOC
#include "plx9056.h"
#include "pati.h"
#include "pci_eeprom.h"
extern void show_pld_regs(void);
extern int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
extern void user_led0(int led_on);
extern void user_led1(int led_on);
/* ------------------------------------------------------------------------- */
#if defined(CONFIG_SYS_PCI_CON_DEVICE)
extern void pci_con_disc(void);
extern void pci_con_connect(void);
#endif
/******************************************************************************
* Eeprom Support
******************************************************************************/
unsigned long get32(unsigned long addr)
{
unsigned long *p=(unsigned long *)addr;
return *p;
}
void set32(unsigned long addr,unsigned long data)
{
unsigned long *p=(unsigned long *)addr;
*p=data;
}
#define PCICFG_GET_REG(x) (get32((x) + PCI_CONFIG_BASE))
#define PCICFG_SET_REG(x,y) (set32((x) + PCI_CONFIG_BASE,(y)))
/******************************************************************************
* reload_pci_eeprom
******************************************************************************/
static void reload_pci_eeprom(void)
{
unsigned long reg;
/* Set Bit 29 and clear it again */
reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
udelay(1);
/* set it*/
reg|=(1<<29);
PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
/* EECLK @ 33MHz = 125kHz
* -> extra long load = 32 * 16bit = 512Bit @ 125kHz = 4.1msec
* use 20msec
*/
udelay(20000); /* wait 20ms */
reg &= ~(1<<29); /* set it low */
PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
udelay(1); /* wait some time */
}
/******************************************************************************
* clock_pci_eeprom
******************************************************************************/
static void clock_pci_eeprom(void)
{
unsigned long reg;
/* clock is low, data is valid */
reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
udelay(1);
/* set clck high */
reg|=(1<<24);
PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
udelay(1); /* wait some time */
reg &= ~(1<<24); /* set clock low */
PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
udelay(1); /* wait some time */
}
/******************************************************************************
* send_pci_eeprom_cmd
******************************************************************************/
static void send_pci_eeprom_cmd(unsigned long cmd, unsigned char len)
{
unsigned long reg;
int i;
reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
/* Clear all EEPROM bits */
reg &= ~(0xF << 24);
/* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
udelay(1); /* wait some time */
/* Enable EEPROM Chip Select */
reg |= (1 << 25);
PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
/* Send EEPROM command - one bit at a time */
for (i = (int)(len-1); i >= 0; i--) {
/* Check if current bit is 0 or 1 */
if (cmd & (1 << i))
PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,(reg | (1<<26)));
else
PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
clock_pci_eeprom();
}
}
/******************************************************************************
* write_pci_eeprom_offs
******************************************************************************/
static void write_pci_eeprom_offs(unsigned short offset, unsigned short value)
{
unsigned long reg;
int bitpos, cmdshft, cmdlen, timeout;
/* we're using the Eeprom 93CS66 */
cmdshft = 2;
cmdlen = EE66_CMD_LEN;
/* Send Write_Enable command to EEPROM */
send_pci_eeprom_cmd((EE_WREN << cmdshft),cmdlen);
/* Send EEPROM Write command and offset to EEPROM */
send_pci_eeprom_cmd((EE_WRITE << cmdshft) | (offset / 2),cmdlen);
reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
/* Clear all EEPROM bits */
reg &= ~(0xF << 24);
/* Make sure EEDO Input is disabled for some PLX chips */
reg &= ~(1 << 31);
/* Enable EEPROM Chip Select */
reg |= (1 << 25);
/* Write 16-bit value to EEPROM - one bit at a time */
for (bitpos = 15; bitpos >= 0; bitpos--) {
/* Get bit value and shift into result */
if (value & (1 << bitpos))
PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,(reg | (1<<26)));
else
PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg );
clock_pci_eeprom();
} /* for */
/* Deselect Chip */
PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg & ~(1 << 25));
/* Re-select Chip */
PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg | (1 << 25));
/* A small delay is needed to let EEPROM complete */
timeout = 0;
do {
udelay(10);
reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
timeout++;
} while (((reg & (1 << 27)) == 0) && timeout < 20000);
/* Send Write_Disable command to EEPROM */
send_pci_eeprom_cmd((EE_WDS << cmdshft),cmdlen);
/* Clear Chip Select and all other EEPROM bits */
PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg & ~(0xF << 24));
}
/******************************************************************************
* read_pci_eeprom_offs
******************************************************************************/
static void read_pci_eeprom_offs(unsigned short offset, unsigned short *pvalue)
{
unsigned long reg;
int bitpos, cmdshft, cmdlen;
/* we're using the Eeprom 93CS66 */
cmdshft = 2;
cmdlen = EE66_CMD_LEN;
/* Send EEPROM read command and offset to EEPROM */
send_pci_eeprom_cmd((EE_READ << cmdshft) | (offset / 2),cmdlen);
/* Set EEPROM write output bit */
reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
/* Set EEDO Input enable */
reg |= (1 << 31);
PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg | (1 << 26));
/* Get 16-bit value from EEPROM - one bit at a time */
for (bitpos = 0; bitpos < 16; bitpos++) {
clock_pci_eeprom();
udelay(10);
reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
/* Get bit value and shift into result */
if (reg & (1 << 27))
*pvalue = (unsigned short)((*pvalue << 1) | 1);
else
*pvalue = (unsigned short)(*pvalue << 1);
}
/* Clear EEDO Input enable */
reg &= ~(1 << 31);
/* Clear Chip Select and all other EEPROM bits */
PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg & ~(0xF << 24));
}
/******************************************************************************
* EEPROM read/writes
******************************************************************************/
#undef EEPROM_DBG
static int pati_pci_eeprom_erase(void)
{
int i;
printf("Erasing EEPROM ");
for( i=0; i < PATI_EEPROM_LAST_OFFSET; i+=2) {
write_pci_eeprom_offs(i,0xffff);
if((i%0x10))
printf(".");
}
printf("\nDone\n");
return 0;
}
static int pati_pci_eeprom_prg(void)
{
int i;
i=0;
printf("Programming EEPROM ");
while(pati_eeprom[i].offset<0xffff) {
write_pci_eeprom_offs(pati_eeprom[i].offset,pati_eeprom[i].value);
#ifdef EEPROM_DBG
printf("0x%04X: 0x%04X\n",pati_eeprom[i].offset, pati_eeprom[i].value);
#else
if((i%0x10))
printf(".");
#endif
i++;
}
printf("\nDone\n");
return 0;
}
static int pati_pci_eeprom_write(unsigned short offset, unsigned long addr, unsigned short size)
{
int i;
unsigned short value;
unsigned short *buffer =(unsigned short *)addr;
if((offset + size) > PATI_EEPROM_LAST_OFFSET) {
size = PATI_EEPROM_LAST_OFFSET - offset;
}
printf("Write To EEPROM from 0x%lX to 0x%X 0x%X words\n", addr, offset, size/2);
for( i = offset; i< (offset + size); i+=2) {
value = *buffer++;
write_pci_eeprom_offs(i,value);
#ifdef EEPROM_DBG
printf("0x%04X: 0x%04X\n",i, value);
#else
if((i%0x10))
printf(".");
#endif
}
printf("\nDone\n");
return 0;
}
static int pati_pci_eeprom_read(unsigned short offset, unsigned long addr, unsigned short size)
{
int i;
unsigned short value = 0;
unsigned short *buffer =(unsigned short *)addr;
if((offset + size) > PATI_EEPROM_LAST_OFFSET) {
size = PATI_EEPROM_LAST_OFFSET - offset;
}
printf("Read from EEPROM from 0x%X to 0x%lX 0x%X words\n", offset, addr, size/2);
for( i = offset; i< (offset + size); i+=2) {
read_pci_eeprom_offs(i,&value);
*buffer++=value;
#ifdef EEPROM_DBG
printf("0x%04X: 0x%04X\n",i, value);
#else
if((i%0x10))
printf(".");
#endif
}
printf("\nDone\n");
return 0;
}
/******************************************************************************
* PCI Bridge Registers Dump
*******************************************************************************/
static void display_pci_regs(void)
{
printf(" PCI9056_SPACE0_RANGE %08lX\n",PCICFG_GET_REG(PCI9056_SPACE0_RANGE));
printf(" PCI9056_SPACE0_REMAP %08lX\n",PCICFG_GET_REG(PCI9056_SPACE0_REMAP));
printf(" PCI9056_LOCAL_DMA_ARBIT %08lX\n",PCICFG_GET_REG(PCI9056_LOCAL_DMA_ARBIT));
printf(" PCI9056_ENDIAN_DESC %08lX\n",PCICFG_GET_REG(PCI9056_ENDIAN_DESC));
printf(" PCI9056_EXP_ROM_RANGE %08lX\n",PCICFG_GET_REG(PCI9056_EXP_ROM_RANGE));
printf(" PCI9056_EXP_ROM_REMAP %08lX\n",PCICFG_GET_REG(PCI9056_EXP_ROM_REMAP));
printf(" PCI9056_SPACE0_ROM_DESC %08lX\n",PCICFG_GET_REG(PCI9056_SPACE0_ROM_DESC));
printf(" PCI9056_DM_RANGE %08lX\n",PCICFG_GET_REG(PCI9056_DM_RANGE));
printf(" PCI9056_DM_MEM_BASE %08lX\n",PCICFG_GET_REG(PCI9056_DM_MEM_BASE));
printf(" PCI9056_DM_IO_BASE %08lX\n",PCICFG_GET_REG(PCI9056_DM_IO_BASE));
printf(" PCI9056_DM_PCI_MEM_REMAP %08lX\n",PCICFG_GET_REG(PCI9056_DM_PCI_MEM_REMAP));
printf(" PCI9056_DM_PCI_IO_CONFIG %08lX\n",PCICFG_GET_REG(PCI9056_DM_PCI_IO_CONFIG));
printf(" PCI9056_SPACE1_RANGE %08lX\n",PCICFG_GET_REG(PCI9056_SPACE1_RANGE));
printf(" PCI9056_SPACE1_REMAP %08lX\n",PCICFG_GET_REG(PCI9056_SPACE1_REMAP));
printf(" PCI9056_SPACE1_DESC %08lX\n",PCICFG_GET_REG(PCI9056_SPACE1_DESC));
printf(" PCI9056_DM_DAC %08lX\n",PCICFG_GET_REG(PCI9056_DM_DAC));
printf(" PCI9056_MAILBOX0 %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX0));
printf(" PCI9056_MAILBOX1 %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX1));
printf(" PCI9056_MAILBOX2 %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX2));
printf(" PCI9056_MAILBOX3 %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX3));
printf(" PCI9056_MAILBOX4 %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX4));
printf(" PCI9056_MAILBOX5 %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX5));
printf(" PCI9056_MAILBOX6 %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX6));
printf(" PCI9056_MAILBOX7 %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX7));
printf(" PCI9056_PCI_TO_LOC_DBELL %08lX\n",PCICFG_GET_REG(PCI9056_PCI_TO_LOC_DBELL));
printf(" PCI9056_LOC_TO_PCI_DBELL %08lX\n",PCICFG_GET_REG(PCI9056_LOC_TO_PCI_DBELL));
printf(" PCI9056_INT_CTRL_STAT %08lX\n",PCICFG_GET_REG(PCI9056_INT_CTRL_STAT));
printf(" PCI9056_EEPROM_CTRL_STAT %08lX\n",PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT));
printf(" PCI9056_PERM_VENDOR_ID %08lX\n",PCICFG_GET_REG(PCI9056_PERM_VENDOR_ID));
printf(" PCI9056_REVISION_ID %08lX\n",PCICFG_GET_REG(PCI9056_REVISION_ID));
printf(" \n");
printf(" PCI9056_VENDOR_ID %08lX\n",PCICFG_GET_REG(PCI9056_VENDOR_ID));
printf(" PCI9056_COMMAND %08lX\n",PCICFG_GET_REG(PCI9056_COMMAND));
printf(" PCI9056_REVISION %08lX\n",PCICFG_GET_REG(PCI9056_REVISION));
printf(" PCI9056_CACHE_SIZE %08lX\n",PCICFG_GET_REG(PCI9056_CACHE_SIZE));
printf(" PCI9056_RTR_BASE %08lX\n",PCICFG_GET_REG(PCI9056_RTR_BASE));
printf(" PCI9056_RTR_IO_BASE %08lX\n",PCICFG_GET_REG(PCI9056_RTR_IO_BASE));
printf(" PCI9056_LOCAL_BASE0 %08lX\n",PCICFG_GET_REG(PCI9056_LOCAL_BASE0));
printf(" PCI9056_LOCAL_BASE1 %08lX\n",PCICFG_GET_REG(PCI9056_LOCAL_BASE1));
printf(" PCI9056_UNUSED_BASE1 %08lX\n",PCICFG_GET_REG(PCI9056_UNUSED_BASE1));
printf(" PCI9056_UNUSED_BASE2 %08lX\n",PCICFG_GET_REG(PCI9056_UNUSED_BASE2));
printf(" PCI9056_CIS_PTR %08lX\n",PCICFG_GET_REG(PCI9056_CIS_PTR));
printf(" PCI9056_SUB_ID %08lX\n",PCICFG_GET_REG(PCI9056_SUB_ID));
printf(" PCI9056_EXP_ROM_BASE %08lX\n",PCICFG_GET_REG(PCI9056_EXP_ROM_BASE));
printf(" PCI9056_CAP_PTR %08lX\n",PCICFG_GET_REG(PCI9056_CAP_PTR));
printf(" PCI9056_INT_LINE %08lX\n",PCICFG_GET_REG(PCI9056_INT_LINE));
printf(" PCI9056_PM_CAP_ID %08lX\n",PCICFG_GET_REG(PCI9056_PM_CAP_ID));
printf(" PCI9056_PM_CSR %08lX\n",PCICFG_GET_REG(PCI9056_PM_CSR));
printf(" PCI9056_HS_CAP_ID %08lX\n",PCICFG_GET_REG(PCI9056_HS_CAP_ID));
printf(" PCI9056_VPD_CAP_ID %08lX\n",PCICFG_GET_REG(PCI9056_VPD_CAP_ID));
printf(" PCI9056_VPD_DATA %08lX\n",PCICFG_GET_REG(PCI9056_VPD_DATA));
}
int do_pati(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
if (strcmp(argv[1], "info") == 0)
{
show_pld_regs();
return 0;
}
if (strcmp(argv[1], "pci") == 0)
{
display_pci_regs();
return 0;
}
if (strcmp(argv[1], "led") == 0)
{
int led_nr,led_on;
led_nr = (int)simple_strtoul(argv[2], NULL, 10);
led_on = (int)simple_strtoul(argv[3], NULL, 10);
if(!led_nr)
user_led0(led_on);
else
user_led1(led_on);
return 0;
}
#if defined(CONFIG_SYS_PCI_CON_DEVICE)
if (strcmp(argv[1], "con") == 0) {
pci_con_connect();
return 0;
}
if (strcmp(argv[1], "disc") == 0) {
pci_con_disc();
return 0;
}
#endif
if (strcmp(argv[1], "eeprom") == 0) {
unsigned long addr;
int size, offset;
offset = 0;
size = PATI_EEPROM_LAST_OFFSET;
if(argc>2) {
if(argc>3) {
addr = simple_strtoul(argv[3], NULL, 16);
if(argc>4)
offset = (int) simple_strtoul(argv[4], NULL, 16);
if(argc>5)
size = (int) simple_strtoul(argv[5], NULL, 16);
if (strcmp(argv[2], "read") == 0) {
return (pati_pci_eeprom_read(offset, addr, size));
}
if (strcmp(argv[2], "write") == 0) {
return (pati_pci_eeprom_write(offset, addr, size));
}
}
if (strcmp(argv[2], "prg") == 0) {
return (pati_pci_eeprom_prg());
}
if (strcmp(argv[2], "era") == 0) {
return (pati_pci_eeprom_erase());
}
if (strcmp(argv[2], "reload") == 0) {
reload_pci_eeprom();
return 0;
}
}
}
return (do_mplcommon(cmdtp, flag, argc, argv));
}
U_BOOT_CMD(
pati, 8, 1, do_pati,
"PATI specific Cmds",
"info - displays board information\n"
"pati pci - displays PCI registers\n"
"pati led <nr> <on> \n"
" - switch LED <nr> <on>\n"
"pati flash mem [SrcAddr]\n"
" - updates U-Boot with image in memory\n"
"pati eeprom <cmd> - PCI EEPROM sub-system\n"
" read <addr> <offset> <size>\n"
" - read PCI EEPROM to <addr> from <offset> <size> words\n"
" write <addr> <offset> <size>\n"
" - write PCI EEPROM from <addr> to <offset> <size> words\n"
" prg - programm PCI EEPROM with default values\n"
" era - erase PCI EEPROM (write all word to 0xffff)\n"
" reload- Reload PCI Bridge with EEPROM Values\n"
" NOTE: <addr> must start on word boundary\n"
" <offset> and <size> must be even byte values"
);
/* ------------------------------------------------------------------------- */

View file

@ -0,0 +1,616 @@
/*
* (C) Copyright 2003
* Martin Winistoerfer, martinwinistoerfer@gmx.ch.
* Atapted for PATI
* Denis Peter, d.peter@mpl.ch
* 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
*/
/***********************************************************************************
* Bits for the SDRAM controller
* -----------------------------
*
* CAL: CAS Latency. If cleared to 0 (default) the SDRAM controller asserts TA# on
* the 2nd Clock after ACTIVE command (CAS Latency = 2). If set to 1 the SDRAM
* controller asserts TA# on the 3rd Clock after ACTIVE command (CAS Latency = 3).
* RCD: RCD ACTIVE to READ or WRITE Delay (Ras to Cas Delay). If cleared 0 (default)
* tRCD of the SDRAM must equal or less 25ns. If set to 1 tRCD must be equal or less 50ns.
* WREC:Write Recovery. If cleared 0 (default) tWR of the SDRAM must equal or less 25ns.
* If set to 1 tWR must be equal or less 50ns.
* RP: Precharge Command Time. If cleared 0 (default) tRP of the SDRAM must equal or less
* 25ns. If set to 1 tRP must be equal or less 50ns.
* RC: Auto Refresh to Active Time. If cleared 0 (default) tRC of the SDRAM must equal
* or less 75ns. If set to 1 tRC must be equal or less 100ns.
* LMR: Bit to set the Mode Register of the SDRAM. If set, the next access to the SDRAM
* is the Load Mode Register Command.
* IIP: Init in progress. Set to 1 for starting the init sequence
* (Precharge All). As long this bit is set, the Precharge All is still in progress.
* After command has completed, wait at least for 8 refresh (200usec) before proceed.
**********************************************************************************/
#include <common.h>
#include <mpc5xx.h>
#include <stdio_dev.h>
#include <pci_ids.h>
#define PLX9056_LOC
#include "plx9056.h"
#include "pati.h"
#if defined(__APPLE__)
/* Leading underscore on symbols */
# define SYM_CHAR "_"
#else /* No leading character on symbols */
# define SYM_CHAR
#endif
#undef SDRAM_DEBUG
/*
* Macros to generate global absolutes.
*/
#define GEN_SYMNAME(str) SYM_CHAR #str
#define GEN_VALUE(str) #str
#define GEN_ABS(name, value) \
asm (".globl " GEN_SYMNAME(name)); \
asm (GEN_SYMNAME(name) " = " GEN_VALUE(value))
/************************************************************************
* Early debug routines
*/
void write_hex (unsigned char i)
{
char cc;
cc = i >> 4;
cc &= 0xf;
if (cc > 9)
serial_putc (cc + 55);
else
serial_putc (cc + 48);
cc = i & 0xf;
if (cc > 9)
serial_putc (cc + 55);
else
serial_putc (cc + 48);
}
#if defined(SDRAM_DEBUG)
void write_4hex (unsigned long val)
{
write_hex ((unsigned char) (val >> 24));
write_hex ((unsigned char) (val >> 16));
write_hex ((unsigned char) (val >> 8));
write_hex ((unsigned char) val);
}
#endif
unsigned long in32(unsigned long addr)
{
unsigned long *p=(unsigned long *)addr;
return *p;
}
void out32(unsigned long addr,unsigned long data)
{
unsigned long *p=(unsigned long *)addr;
*p=data;
}
typedef struct {
unsigned short boardtype; /* Board revision and Population Options */
unsigned char cal; /* cas Latency 0:CAL=2 1:CAL=3 */
unsigned char rcd; /* ras to cas delay 0:<25ns 1:<50ns*/
unsigned char wrec; /* write recovery 0:<25ns 1:<50ns */
unsigned char pr; /* Precharge Command Time 0:<25ns 1:<50ns */
unsigned char rc; /* Auto Refresh to Active Time 0:<75ns 1:<100ns */
unsigned char sz; /* log binary => Size = (4MByte<<sz) 5 = 128, 4 = 64, 3 = 32, 2 = 16, 1=8 */
} sdram_t;
const sdram_t sdram_table[] = {
{ 0x0000, /* PATI Rev A, 16MByte -1 Board */
1, /* Case Latenty = 3 */
0, /* ras to cas delay 0 (20ns) */
0, /* write recovery 0:<25ns 1:<50ns*/
0, /* Precharge Command Time 0 (20ns) */
0, /* Auto Refresh to Active Time 0 (68) */
2 /* log binary => Size 2 = 16MByte, 1=8 */
},
{ 0xffff, /* terminator */
0xff,
0xff,
0xff,
0xff,
0xff,
0xff }
};
extern int mem_test (unsigned long start, unsigned long ramsize, int quiet);
/*
* Get RAM size.
*/
phys_size_t initdram(int board_type)
{
unsigned char board_rev;
unsigned long reg;
unsigned long lmr;
int i,timeout;
#if defined(SDRAM_DEBUG)
reg=in32(PLD_CONFIG_BASE+PLD_PART_ID);
puts("\n\nSYSTEM part 0x"); write_4hex(SYSCNTR_PART(reg));
puts(" Vers 0x"); write_4hex(SYSCNTR_ID(reg));
puts("\nSDRAM part 0x"); write_4hex(SDRAM_PART(reg));
puts(" Vers 0x"); write_4hex(SDRAM_ID(reg));
reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
puts("\nBoard rev. 0x"); write_4hex(SYSCNTR_BREV(reg));
putc('\n');
#endif
reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
board_rev=(unsigned char)(SYSCNTR_BREV(reg));
i=0;
while(1) {
if(sdram_table[i].boardtype==0xffff) {
puts("ERROR, found no table for Board 0x");
write_hex(board_rev);
while(1);
}
if(sdram_table[i].boardtype==(unsigned char)board_rev)
break;
i++;
}
/* Set CAL, RCD, WREQ, PR and RC Bits */
#if defined(SDRAM_DEBUG)
puts("Set CAL, RCD, WREQ, PR and RC Bits\n");
#endif
/* mask bits */
reg &= ~(SET_REG_BIT(1,SDRAM_CAL) | SET_REG_BIT(1,SDRAM_RCD) | SET_REG_BIT(1,SDRAM_WREQ) |
SET_REG_BIT(1,SDRAM_PR) | SET_REG_BIT(1,SDRAM_RC) | SET_REG_BIT(1,SDRAM_LMR) |
SET_REG_BIT(1,SDRAM_IIP) | SET_REG_BIT(1,SDRAM_RES0));
/* set bits */
reg |= (SET_REG_BIT(sdram_table[i].cal,SDRAM_CAL) |
SET_REG_BIT(sdram_table[i].rcd,SDRAM_RCD) |
SET_REG_BIT(sdram_table[i].wrec,SDRAM_WREQ) |
SET_REG_BIT(sdram_table[i].pr,SDRAM_PR) |
SET_REG_BIT(sdram_table[i].rc,SDRAM_RC));
out32(PLD_CONFIG_BASE+PLD_BOARD_TIMING,reg);
/* step 2 set IIP */
#if defined(SDRAM_DEBUG)
puts("step 2 set IIP\n");
#endif
/* step 2 set IIP */
reg |= SET_REG_BIT(1,SDRAM_IIP);
timeout=0;
while (timeout!=0xffff) {
__asm__ volatile("eieio");
reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
if((reg & SET_REG_BIT(1,SDRAM_IIP))==0)
break;
timeout++;
udelay(1);
}
/* wait for at least 8 refresh */
udelay(1000);
/* set LMR */
reg |= SET_REG_BIT(1,SDRAM_LMR);
out32(PLD_CONFIG_BASE+PLD_BOARD_TIMING,reg);
__asm__ volatile("eieio");
lmr=0x00000002; /* sequential burst 4 data */
if(sdram_table[i].cal==1)
lmr|=0x00000030; /* cal = 3 */
else
lmr|=0000000020; /* cal = 2 */
/* rest standard operation programmed write burst length */
/* we have a x32 bit bus to the SDRAM, so shift the addr with 2 */
lmr<<=2;
in32(CONFIG_SYS_SDRAM_BASE + lmr);
/* ok, we're done, return SDRAM size */
return ((0x400000 << sdram_table[i].sz)); /* log2 value of 4MByte */
}
void set_flash_vpp(int ext_vpp, int ext_wp, int int_vpp)
{
unsigned long reg;
reg=in32(PLD_CONF_REG2+PLD_CONFIG_BASE);
reg &= ~(SET_REG_BIT(1,SYSCNTR_CPU_VPP) |
SET_REG_BIT(1,SYSCNTR_FL_VPP) |
SET_REG_BIT(1,SYSCNTR_FL_WP));
reg |= (SET_REG_BIT(int_vpp,SYSCNTR_CPU_VPP) |
SET_REG_BIT(ext_vpp,SYSCNTR_FL_VPP) |
SET_REG_BIT(ext_wp,SYSCNTR_FL_WP));
out32(PLD_CONF_REG2+PLD_CONFIG_BASE,reg);
udelay(100);
}
void show_pld_regs(void)
{
unsigned long reg,reg1;
reg=in32(PLD_CONFIG_BASE+PLD_PART_ID);
printf("\nSYSTEM part %ld, Vers %ld\n",SYSCNTR_PART(reg),SYSCNTR_ID(reg));
printf("SDRAM part %ld, Vers %ld\n",SDRAM_PART(reg),SDRAM_ID(reg));
reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
printf("Board rev. %c\n",(char) (SYSCNTR_BREV(reg)+'A'));
printf("Waitstates %ld\n",GET_SYSCNTR_FLWAIT(reg));
printf("SDRAM: CAL=%ld RCD=%ld WREQ=%ld PR=%ld\n RC=%ld LMR=%ld IIP=%ld\n",
GET_REG_BIT(reg,SDRAM_CAL),GET_REG_BIT(reg,SDRAM_RCD),
GET_REG_BIT(reg,SDRAM_WREQ),GET_REG_BIT(reg,SDRAM_PR),
GET_REG_BIT(reg,SDRAM_RC),GET_REG_BIT(reg,SDRAM_LMR),
GET_REG_BIT(reg,SDRAM_IIP));
reg=in32(PLD_CONFIG_BASE+PLD_CONF_REG1);
reg1=in32(PLD_CONFIG_BASE+PLD_CONF_REG2);
printf("HW Config: FLAG=%ld IP=%ld index=%ld PRPM=%ld\n ICW=%ld ISB=%ld BDIS=%ld PCIM=%ld\n",
GET_REG_BIT(reg,SYSCNTR_FLAG),GET_REG_BIT(reg,SYSCNTR_IP),
GET_SYSCNTR_BOOTIND(reg),GET_REG_BIT(reg,SYSCNTR_PRM),
GET_REG_BIT(reg,SYSCNTR_ICW),GET_SYSCNTR_ISB(reg),
GET_REG_BIT(reg1,SYSCNTR_BDIS),GET_REG_BIT(reg1,SYSCNTR_PCIM));
printf("Switches: MUX=%ld PCI_DIS=%ld Boot_EN=%ld Config=%ld\n",GET_SDRAM_MUX(reg),
GET_REG_BIT(reg,SDRAM_PDIS),GET_REG_BIT(reg1,SYSCNTR_BOOTEN),
GET_SYSCNTR_CFG(reg1));
printf("Misc: RIP=%ld CPU_VPP=%ld FLSH_VPP=%ld FLSH_WP=%ld\n\n",
GET_REG_BIT(reg,SDRAM_RIP),GET_REG_BIT(reg1,SYSCNTR_CPU_VPP),
GET_REG_BIT(reg1,SYSCNTR_FL_VPP),GET_REG_BIT(reg1,SYSCNTR_FL_WP));
}
/****************************************************************
* Setting IOs
* -----------
* GPIO6 is User LED1
* GPIO7 is Interrupt PLX (Output)
* GPIO5 is User LED0
* GPIO2 is PLX USERi (Output)
* GPIO1 is PLX Interrupt (Input)
****************************************************************/
void init_ios(void)
{
volatile immap_t * immr = (immap_t *) CONFIG_SYS_IMMR;
volatile sysconf5xx_t *sysconf = &immr->im_siu_conf;
unsigned long reg;
reg=sysconf->sc_sgpiocr; /* Data direction register */
reg &= ~0x67000000;
reg |= 0x27000000; /* set outpupts */
sysconf->sc_sgpiocr=reg; /* Data direction register */
reg=sysconf->sc_sgpiodt2; /* Data register */
/* set output to 0 */
reg &= ~0x27000000;
/* set IRQ and USERi to 1 */
reg |= 0x28000000;
sysconf->sc_sgpiodt2=reg; /* Data register */
}
void user_led0(int led_on)
{
volatile immap_t * immr = (immap_t *) CONFIG_SYS_IMMR;
volatile sysconf5xx_t *sysconf = &immr->im_siu_conf;
unsigned long reg;
reg=sysconf->sc_sgpiodt2; /* Data register */
if(led_on) /* set output to 1 */
reg |= 0x04000000;
else
reg &= ~0x04000000;
sysconf->sc_sgpiodt2=reg; /* Data register */
}
void user_led1(int led_on)
{
volatile immap_t * immr = (immap_t *) CONFIG_SYS_IMMR;
volatile sysconf5xx_t *sysconf = &immr->im_siu_conf;
unsigned long reg;
reg=sysconf->sc_sgpiodt2; /* Data register */
if(led_on) /* set output to 1 */
reg |= 0x02000000;
else
reg &= ~0x02000000;
sysconf->sc_sgpiodt2=reg; /* Data register */
}
/****************************************************************
* Last Stage Init
****************************************************************/
int last_stage_init (void)
{
init_ios();
return 0;
}
/****************************************************************
* Check the board
****************************************************************/
#define BOARD_NAME "PATI"
int checkboard (void)
{
char s[50];
ulong reg;
char rev;
int i;
puts ("\nBoard: ");
reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
rev=(char)(SYSCNTR_BREV(reg)+'A');
i = getenv_f("serial#", s, 32);
if ((i == -1)) {
puts ("### No HW ID - assuming " BOARD_NAME);
printf(" Rev. %c\n",rev);
}
else {
s[sizeof(BOARD_NAME)-1] = 0;
printf ("%s-1 Rev %c SN: %s\n", s,rev,
&s[sizeof(BOARD_NAME)]);
}
set_flash_vpp(1,0,0); /* set Flash VPP */
return 0;
}
#ifdef CONFIG_SYS_PCI_CON_DEVICE
/************************************************************************
* PCI Communication
*
* Alive (Pinging):
* ----------------
* PCI Host sends message ALIVE, Local acknowledges with ALIVE
*
* PCI_CON console over PCI:
* -------------------------
* Local side:
* - uses PCI9056_LOC_TO_PCI_DBELL register to signal that
* data is avaible (PCIMSG_CONN)
* - uses PCI9056_MAILBOX1 to send data
* - uses PCI9056_MAILBOX0 to receive data
* PCI side:
* - uses PCI9056_PCI_TO_LOC_DBELL register to signal that
* data is avaible (PCIMSG_CONN)
* - uses PCI9056_MAILBOX0 to send data
* - uses PCI9056_MAILBOX1 to receive data
*
* How it works:
* Send:
* - check if PCICON_TRANSMIT_REG is empty
* - write data or'ed with 0x80000000 into the PCICON_TRANSMIT_REG
* - write PCIMSG_CONN into the PCICON_DBELL_REG to signal a data
* is waiting
* Receive:
* - get an interrupt via the PCICON_ACK_REG register message
* PCIMSG_CONN
* - write the data from the PCICON_RECEIVE_REG into the receive
* buffer and if the receive buffer is not full, clear the
* PCICON_RECEIVE_REG (this allows the counterpart to write more data)
* - Clear the interrupt by writing 0xFFFFFFFF to the PCICON_ACK_REG
*
* The PCICON_RECEIVE_REG must be cleared by the routine which reads
* the receive buffer if the buffer is not full any more
*
*/
#undef PCI_CON_DEBUG
#ifdef PCI_CON_DEBUG
#define PCI_CON_PRINTF(fmt,args...) serial_printf (fmt ,##args)
#else
#define PCI_CON_PRINTF(fmt,args...)
#endif
/*********************************************************
* we work only with a receive buffer on eiter side.
* Transmit buffer is free, if mailbox is cleared.
* Transmit character is or'ed with 0x80000000
* PATI receive register MAILBOX0
* PATI transmit register MAILBOX1
*********************************************************/
#define PCICON_RECEIVE_REG PCI9056_MAILBOX0
#define PCICON_TRANSMIT_REG PCI9056_MAILBOX1
#define PCICON_DBELL_REG PCI9056_LOC_TO_PCI_DBELL
#define PCICON_ACK_REG PCI9056_PCI_TO_LOC_DBELL
#define PCIMSG_ALIVE 0x1
#define PCIMSG_CONN 0x2
#define PCIMSG_DISC 0x3
#define PCIMSG_CON_DATA 0x5
#define PCICON_GET_REG(x) (in32(x + PCI_CONFIG_BASE))
#define PCICON_SET_REG(x,y) (out32(x + PCI_CONFIG_BASE,y))
#define PCICON_TX_FLAG 0x80000000
#define REC_BUFFER_SIZE 0x100
int recbuf[REC_BUFFER_SIZE];
static int r_ptr = 0;
int w_ptr;
struct stdio_dev pci_con_dev;
int conn=0;
int buff_full=0;
void pci_con_put_it(const char c)
{
/* Test for completition */
unsigned long reg;
do {
reg=PCICON_GET_REG(PCICON_TRANSMIT_REG);
}while(reg);
reg=PCICON_TX_FLAG + c;
PCICON_SET_REG(PCICON_TRANSMIT_REG,reg);
PCICON_SET_REG(PCICON_DBELL_REG,PCIMSG_CON_DATA);
}
void pci_con_putc(const char c)
{
pci_con_put_it(c);
if(c == '\n')
pci_con_put_it('\r');
}
int pci_con_getc(void)
{
int res;
int diff;
while(r_ptr==(volatile int)w_ptr);
res=recbuf[r_ptr++];
if(r_ptr==REC_BUFFER_SIZE)
r_ptr=0;
if(w_ptr<r_ptr)
diff=r_ptr+REC_BUFFER_SIZE-w_ptr;
else
diff=r_ptr-w_ptr;
if((diff<(REC_BUFFER_SIZE-4)) && buff_full) {
/* clear Mail box */
buff_full=0;
PCICON_SET_REG(PCICON_RECEIVE_REG,0L);
}
return res;
}
int pci_con_tstc(void)
{
if(r_ptr==(volatile int)w_ptr)
return 0;
return 1;
}
void pci_con_puts (const char *s)
{
while (*s) {
pci_con_putc(*s);
++s;
}
}
void pci_con_init (void)
{
w_ptr = 0;
r_ptr = 0;
PCICON_SET_REG(PCICON_RECEIVE_REG,0L);
conn=1;
}
/*******************************************
* IRQ routine
******************************************/
int pci_dorbell_irq(void)
{
unsigned long reg,data;
int diff;
reg=PCICON_GET_REG(PCI9056_INT_CTRL_STAT);
PCI_CON_PRINTF(" PCI9056_INT_CTRL_STAT = %08lX\n",reg);
if(reg & (1<<20) ) {
/* read doorbell */
reg=PCICON_GET_REG(PCICON_ACK_REG);
switch(reg) {
case PCIMSG_ALIVE:
PCI_CON_PRINTF(" Alive\n");
PCICON_SET_REG(PCICON_DBELL_REG,PCIMSG_ALIVE);
break;
case PCIMSG_CONN:
PCI_CON_PRINTF(" Conn %d",conn);
w_ptr = 0;
r_ptr = 0;
buff_full=0;
PCICON_SET_REG(PCICON_RECEIVE_REG,0L);
conn=1;
PCI_CON_PRINTF(" ... %d\n",conn);
break;
case PCIMSG_CON_DATA:
data=PCICON_GET_REG(PCICON_RECEIVE_REG);
recbuf[w_ptr++]=(int)(data&0xff);
PCI_CON_PRINTF(" Data Console %lX, %X %d %d %X\n",data,((int)(data&0xFF)),
r_ptr,w_ptr,recbuf[w_ptr-1]);
if(w_ptr==REC_BUFFER_SIZE)
w_ptr=0;
if(w_ptr<r_ptr)
diff=r_ptr+REC_BUFFER_SIZE-w_ptr;
else
diff=r_ptr-w_ptr;
if(diff>(REC_BUFFER_SIZE-4))
buff_full=1;
else
/* clear Mail box */
PCICON_SET_REG(PCICON_RECEIVE_REG,0L);
break;
default:
serial_printf(" PCI9056_PCI_TO_LOC_DBELL = %08lX\n",reg);
}
/* clear IRQ */
PCICON_SET_REG(PCICON_ACK_REG,~0L);
}
return 0;
}
void pci_con_connect(void)
{
unsigned long reg;
conn=0;
reg=PCICON_GET_REG(PCI9056_INT_CTRL_STAT);
/* default 0x0f010180 */
reg &= 0xff000000;
reg |= 0x00030000; /* enable local dorbell */
reg |= 0x00000300; /* enable PCI dorbell */
PCICON_SET_REG(PCI9056_INT_CTRL_STAT , reg);
irq_install_handler (0x2, (interrupt_handler_t *) pci_dorbell_irq,NULL);
memset (&pci_con_dev, 0, sizeof (pci_con_dev));
strcpy (pci_con_dev.name, "pci_con");
pci_con_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
pci_con_dev.putc = pci_con_putc;
pci_con_dev.puts = pci_con_puts;
pci_con_dev.getc = pci_con_getc;
pci_con_dev.tstc = pci_con_tstc;
stdio_register (&pci_con_dev);
printf("PATI ready for PCI connection, type ctrl-c for exit\n");
do {
udelay(10);
if((volatile int)conn)
break;
if(ctrlc()) {
irq_free_handler(0x2);
return;
}
}while(1);
console_assign(stdin,"pci_con");
console_assign(stderr,"pci_con");
console_assign(stdout,"pci_con");
}
void pci_con_disc(void)
{
console_assign(stdin,"serial");
console_assign(stderr,"serial");
console_assign(stdout,"serial");
PCICON_SET_REG(PCICON_DBELL_REG,PCIMSG_DISC);
/* reconnection */
irq_free_handler(0x02);
pci_con_connect();
}
#endif /* #ifdef CONFIG_SYS_PCI_CON_DEVICE */
/*
* Absolute environment address for linker file.
*/
GEN_ABS(env_start, CONFIG_ENV_OFFSET + CONFIG_SYS_FLASH_BASE);

View file

@ -0,0 +1,440 @@
/*
* (C) Copyright 2003
* Denis Peter, d.peter@mpl.ch
* 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
*/
/************************************************************************
* MACROS and register definitions for PATI Registers
************************************************************************/
#ifndef __PATI_H_
#define __PATI_H_ 1
#define PLD_PART_ID 0x0
#define PLD_BOARD_TIMING 0x4
#define PLD_CONF_REG1 0x8
#define PLD_CONF_REG2 0xC
#define PLD_CONF_RES 0x10
#define SET_REG_BIT(y,x) (y<<(31-x))
#define GET_REG_BIT(y,x) ((y>>(31-x)) & 0x1L)
/* SDRAM Controller PLD_PART_ID */
/* 9 10 11 12 13 14 19 31 */
#define SDRAM_PART3 9
#define SDRAM_PART2 10
#define SDRAM_PART1 11
#define SDRAM_PART0 12
#define SDRAM_ID3 13
#define SDRAM_ID2 14
#define SDRAM_ID1 19
#define SDRAM_ID0 31
#define SDRAM_PART(x) ( \
(GET_REG_BIT(x,SDRAM_PART3)<<3) |\
(GET_REG_BIT(x,SDRAM_PART2)<<2) |\
(GET_REG_BIT(x,SDRAM_PART1)<<1) |\
(GET_REG_BIT(x,SDRAM_PART0)))
#define SDRAM_ID(x) ( \
(GET_REG_BIT(x,SDRAM_ID3)<<3) |\
(GET_REG_BIT(x,SDRAM_ID2)<<2) |\
(GET_REG_BIT(x,SDRAM_ID1)<<1) |\
(GET_REG_BIT(x,SDRAM_ID0)))
/* System Controller */
/* 0 1 3 4 5 16 20 28 29 30 */
#define SYSCNTR_PART4 0
#define SYSCNTR_PART3 1
#define SYSCNTR_PART2 3
#define SYSCNTR_PART1 4
#define SYSCNTR_PART0 5
#define SYSCNTR_ID4 16
#define SYSCNTR_ID3 20
#define SYSCNTR_ID2 28
#define SYSCNTR_ID1 29
#define SYSCNTR_ID0 30
#define SYSCNTR_PART(x) ( \
(GET_REG_BIT(x,SYSCNTR_PART4)<<4) |\
(GET_REG_BIT(x,SYSCNTR_PART3)<<3) |\
(GET_REG_BIT(x,SYSCNTR_PART2)<<2) |\
(GET_REG_BIT(x,SYSCNTR_PART1)<<1) |\
(GET_REG_BIT(x,SYSCNTR_PART0)))
#define SYSCNTR_ID(x) ( \
(GET_REG_BIT(x,SYSCNTR_ID4)<<4) |\
(GET_REG_BIT(x,SYSCNTR_ID3)<<3) |\
(GET_REG_BIT(x,SYSCNTR_ID2)<<2) |\
(GET_REG_BIT(x,SYSCNTR_ID1)<<1) |\
(GET_REG_BIT(x,SYSCNTR_ID0)))
/* SDRAM Controller PLD_BOARD_TIMING */
/* 9 10 11 12 13 14 19 31 */
#define SDRAM_CAL 9
#define SDRAM_RCD 10
#define SDRAM_WREQ 11
#define SDRAM_PR 12
#define SDRAM_RC 13
#define SDRAM_LMR 14
#define SDRAM_IIP 19
#define SDRAM_RES0 31
/* System Controller */
/* 0 1 3 4 5 16 20 28 29 30 */
#define SYSCNTR_BREV0 0
#define SYSCNTR_BREV1 1
#define SYSCNTR_BREV2 3
#define SYSCNTR_BREV3 4
#define SYSCNTR_RES0 5
#define SYSCNTR_RES1 16
#define SYSCNTR_RES2 20
#define SYSCNTR_FLWAIT2 28
#define SYSCNTR_FLWAIT1 29
#define SYSCNTR_FLWAIT0 30
#define SYSCNTR_BREV(x) ( \
(GET_REG_BIT(x,SYSCNTR_BREV3)<<3) |\
(GET_REG_BIT(x,SYSCNTR_BREV2)<<2) |\
(GET_REG_BIT(x,SYSCNTR_BREV1)<<1) |\
(GET_REG_BIT(x,SYSCNTR_BREV0)))
#define GET_SYSCNTR_FLWAIT(x) ( \
(GET_REG_BIT(x,SYSCNTR_FLWAIT2)<<2) |\
(GET_REG_BIT(x,SYSCNTR_FLWAIT1)<<1) |\
(GET_REG_BIT(x,SYSCNTR_FLWAIT0)))
#define SET_SYSCNTR_FLWAIT(x) ( \
(SET_REG_BIT(((x & 0x04)!=0),SYSCNTR_FLWAIT2)) |\
(SET_REG_BIT(((x & 0x02)!=0)x,SYSCNTR_FLWAIT1)) |\
(SET_REG_BIT(((x & 0x01)!=0)x,SYSCNTR_FLWAIT0)))
/* SDRAM Controller REG 2*/
/* 9 10 11 12 13 14 19 31 */
#define SDRAM_MUX0 9
#define SDRAM_MUX1 10
#define SDRAM_PDIS 11
#define SDRAM_RES1 12
#define SDRAM_RES2 13
#define SDRAM_RES3 14
#define SDRAM_RES4 19
#define SDRAM_RIP 31
#define GET_SDRAM_MUX(x) ( \
(GET_REG_BIT(x,SDRAM_MUX1)<<1)| \
(GET_REG_BIT(x,SDRAM_MUX0)))
/* System Controller */
/* 0 1 3 4 5 16 20 28 29 30 */
#define SYSCNTR_FLAG 0
#define SYSCNTR_IP 1
#define SYSCNTR_BIND2 3
#define SYSCNTR_BIND1 4
#define SYSCNTR_BIND0 5
#define SYSCNTR_PRM 16
#define SYSCNTR_ICW 20
#define SYSCNTR_ISB2 28
#define SYSCNTR_ISB1 29
#define SYSCNTR_ISB0 30
#define GET_SYSCNTR_BOOTIND(x) ( \
(GET_REG_BIT(x,SYSCNTR_BIND2)<<2) |\
(GET_REG_BIT(x,SYSCNTR_BIND1)<<1) |\
(GET_REG_BIT(x,SYSCNTR_BIND0)))
#define SET_SYSCNTR_BOOTIND(x) ( \
(SET_REG_BIT(((x & 0x04)!=0),SYSCNTR_BIND2)) |\
(SET_REG_BIT(((x & 0x02)!=0)x,SYSCNTR_BIND1))| \
(SET_REG_BIT(((x & 0x01)!=0)x,SYSCNTR_BIND0)))
#define GET_SYSCNTR_ISB(x) ( \
(GET_REG_BIT(x,SYSCNTR_ISB2)<<2)| \
(GET_REG_BIT(x,SYSCNTR_ISB1)<<1)| \
(GET_REG_BIT(x,SYSCNTR_ISB0)))
#define SET_SYSCNTR_ISB(x) ( \
(SET_REG_BIT(((x & 0x04)!=0),SYSCNTR_ISB2))| \
(SET_REG_BIT(((x & 0x02)!=0)x,SYSCNTR_ISB))| \
(SET_REG_BIT(((x & 0x01)!=0)x,SYSCNTR_ISB0)))
/* SDRAM Controller REG 3*/
/* 9 10 11 12 13 14 19 31 */
#define SDRAM_RES5 9
#define SDRAM_CFG1 10
#define SDRAM_CFG2 11
#define SDRAM_CFG3 12
#define SDRAM_RES6 13
#define SDRAM_CFG5 14
#define SDRAM_CFG6 19
#define SDRAM_RES7 31
#define GET_SDRAM_CFG(x) ( \
(GET_REG_BIT(x,SDRAM_CFG6)<<4) |\
(GET_REG_BIT(x,SDRAM_CFG5)<<3) |\
(GET_REG_BIT(x,SDRAM_CFG3)<<2) |\
(GET_REG_BIT(x,SDRAM_CFG2)<<1) |\
(GET_REG_BIT(x,SDRAM_CFG1)))
/* System Controller */
/* 0 1 3 4 5 16 20 28 29 30 */
#define SYSCNTR_BDIS 0
#define SYSCNTR_PCIM 1
#define SYSCNTR_CFG0 3
#define SYSCNTR_CFG1 4
#define SYSCNTR_CFG2 5
#define SYSCNTR_CFG3 16
#define SYSCNTR_BOOTEN 20
#define SYSCNTR_CPU_VPP 28
#define SYSCNTR_FL_VPP 29
#define SYSCNTR_FL_WP 30
#define GET_SYSCNTR_CFG(x) ( \
(GET_REG_BIT(x,SYSCNTR_CFG3)<<3)| \
(GET_REG_BIT(x,SYSCNTR_CFG2)<<2)| \
(GET_REG_BIT(x,SYSCNTR_CFG1)<<1)| \
(GET_REG_BIT(x,SYSCNTR_CFG0)))
/***************************************************************
* MISC Defines
***************************************************************/
#define PCI_VENDOR_ID_MPL 0x18E6
#define PCI_DEVICE_ID_PATI 0x00DA
#if defined(CONFIG_MIP405)
#define PATI_FIRMWARE_START_OFFSET 0x00300000
#define PATI_ISO_STRING "MEV-10084-001"
#endif
#define PATI_ENDIAN_MODE 0x3E
/*******************************************
* PATI Mapping:
* -------------
* PCI Map:
* -------
* All addreses are mapped into the memory area
* (IO Area on some areas may also be possible)
* - pci_cfg_mem_base: fixed address to the PLX config area size 512Bytes
* - pci_space0_addr: configurable
* - pci_space1_addr configurable
*
* Local Map:
* ----------
* Local addresses (Remap)
* - SDRAM 0x06000000 Size 16MByte mask 0xff000000
* - EPLD CFG 0x07000000 Size 512Bytes
* - FLASH 0x03000000 Size up to 8MByte
* - CPU 0x01000000 Size 4MByte (only accessable if special configured)
*
* Implemention:
* -------------
* To prevent using large resources reservation on the host following
* PCI mapping is choosed:
* - pci_cfg_mem_base: fixed address to the PLX config area size 512Bytes
* - pci_space0_addr: configured to the EPLD Config Area size 256Bytes
* - pci_space1_addr: configured to the SDRAM Area size 1MBytes, this
* space is used to switch between SDRAM, Flash and CPU
*
*/
/* Attribute definitions */
#define PATI_BUS_SIZE_8 0
#define PATI_BUS_SIZE_16 1
#define PATI_BUS_SIZE_32 3
#define PATI_SPACE0_MASK (0xFEFFFE00) /* Mask Attributes */
#define PATI_SPACE1_MASK (0x00000000) /* Mask Attributes */
#define PATI_EXTRA_LONG_EEPROM 1
#define SPACE0_TA_ENABLE (1<<6)
#define SPACE1_TA_ENABLE (1<<6)
/* Config Area */
#define PATI_LOC_CFG_ADDR 0x07000000 /* Local Address */
#define PATI_LOC_CFG_MASK 0xFFFFFF00 /* 256 Bytes */
/* Attributes */
#define PATI_LOC_CFG_BUS_SIZE PATI_BUS_SIZE_32 /* 32 Bit */
#define PATI_LOC_CFG_BURST 0 /* No Burst */
#define PATI_LOC_CFG_NO_PREFETCH 1 /* No Prefetch */
#define PATI_LOC_CFG_TA_ENABLE 1 /* Enable TA */
#define PATI_LOC_CFG_SPACE0_ATTR ( \
PATI_LOC_CFG_BUS_SIZE | \
(PATI_LOC_CFG_TA_ENABLE << 6) | \
(PATI_LOC_CFG_NO_PREFETCH << 8) | \
(PATI_LOC_CFG_BURST << 24) | \
(PATI_EXTRA_LONG_EEPROM << 25))
/* should never be used */
#define PATI_LOC_CFG_SPACE1_ATTR ( \
PATI_LOC_CFG_BUS_SIZE | \
(PATI_LOC_CFG_TA_ENABLE << 6) | \
(PATI_LOC_CFG_NO_PREFETCH << 9) | \
(PATI_LOC_CFG_BURST << 8))
/* SDRAM Area */
#define PATI_LOC_SDRAM_ADDR 0x06000000 /* Local Address */
#define PATI_LOC_SDRAM_MASK 0xFFF00000 /* 1MByte */
/* Attributes */
#define PATI_LOC_SDRAM_BUS_SIZE PATI_BUS_SIZE_32 /* 32 Bit */
#define PATI_LOC_SDRAM_BURST 0 /* No Burst */
#define PATI_LOC_SDRAM_NO_PREFETCH 0 /* Prefetch */
#define PATI_LOC_SDRAM_TA_ENABLE 1 /* Enable TA */
/* should never be used */
#define PATI_LOC_SDRAM_SPACE0_ATTR ( \
PATI_LOC_SDRAM_BUS_SIZE | \
(PATI_LOC_SDRAM_TA_ENABLE << 6) | \
(PATI_LOC_SDRAM_NO_PREFETCH << 8) | \
(PATI_LOC_SDRAM_BURST << 24) | \
(PATI_EXTRA_LONG_EEPROM << 25))
#define PATI_LOC_SDRAM_SPACE1_ATTR ( \
PATI_LOC_SDRAM_BUS_SIZE | \
(PATI_LOC_SDRAM_TA_ENABLE << 6) | \
(PATI_LOC_SDRAM_NO_PREFETCH << 9) | \
(PATI_LOC_SDRAM_BURST << 8))
/* Flash Area */
#define PATI_LOC_FLASH_ADDR 0x03000000 /* Local Address */
#define PATI_LOC_FLASH_MASK 0xFFF00000 /* 1MByte */
/* Attributes */
#define PATI_LOC_FLASH_BUS_SIZE PATI_BUS_SIZE_16 /* 16 Bit */
#define PATI_LOC_FLASH_BURST 0 /* No Burst */
#define PATI_LOC_FLASH_NO_PREFETCH 1 /* No Prefetch */
#define PATI_LOC_FLASH_TA_ENABLE 1 /* Enable TA */
/* should never be used */
#define PATI_LOC_FLASH_SPACE0_ATTR ( \
PATI_LOC_FLASH_BUS_SIZE | \
(PATI_LOC_FLASH_TA_ENABLE << 6) | \
(PATI_LOC_FLASH_NO_PREFETCH << 8) | \
(PATI_LOC_FLASH_BURST << 24) | \
(PATI_EXTRA_LONG_EEPROM << 25))
#define PATI_LOC_FLASH_SPACE1_ATTR ( \
PATI_LOC_FLASH_BUS_SIZE | \
(PATI_LOC_FLASH_TA_ENABLE << 6) | \
(PATI_LOC_FLASH_NO_PREFETCH << 9) | \
(PATI_LOC_FLASH_BURST << 8))
/* CPU Area */
#define PATI_LOC_CPU_ADDR 0x01000000 /* Local Address */
#define PATI_LOC_CPU_MASK 0xFFF00000 /* 1Mbyte */
/* Attributes */
#define PATI_LOC_CPU_BUS_SIZE PATI_BUS_SIZE_32 /* 32 Bit */
#define PATI_LOC_CPU_BURST 0 /* No Burst */
#define PATI_LOC_CPU_NO_PREFETCH 1 /* No Prefetch */
#define PATI_LOC_CPU_TA_ENABLE 1 /* Enable TA */
/* should never be used */
#define PATI_LOC_CPU_SPACE0_ATTR ( \
PATI_LOC_CPU_BUS_SIZE | \
(PATI_LOC_CPU_TA_ENABLE << 6) | \
(PATI_LOC_CPU_NO_PREFETCH << 8) | \
(PATI_LOC_CPU_BURST << 24) | \
(PATI_EXTRA_CPU_EEPROM << 25))
#define PATI_LOC_CPU_SPACE1_ATTR ( \
PATI_LOC_CPU_BUS_SIZE | \
(PATI_LOC_CPU_TA_ENABLE << 6) | \
(PATI_LOC_CPU_NO_PREFETCH << 9) | \
(PATI_LOC_CPU_BURST << 8))
/***************************************************
* Hardware Config word definition
***************************************************/
#define BOOT_EXT_FLASH 0x00000000
#define BOOT_INT_FLASH 0x00000004
#define BOOT_FROM_PCI 0x00000006
#define BOOT_FROM_SDRAM 0x00000005
#define ENABLE_INT_ARB 0x00000008
#define INITIAL_IRQ_PREF 0x00000010
#define INITIAL_MEM_0M 0x00000000
#define INITIAL_MEM_4M 0x00000080
#define INITIAL_MEM_8M 0x00000040
#define INITIAL_MEM_12M 0x000000C0
#define INITIAL_MEM_16M 0x00000020
#define INITIAL_MEM_20M 0x000000A0
#define INITIAL_MEM_24M 0x00000060
#define INITIAL_MEM_28M 0x000000E0
/* CONF */
#define INTERNAL_HWCONF 0x00000100
/* PRPM */
#define LOCAL_CPU_SLAVE 0x00000200
/* BDIS */
#define DISABLE_MEM_CNTR 0x00000400
/* PCIM */
#define PCI_MASTER_ONLY 0x00000800
#define PATI_HW_START ((BOOT_EXT_FLASH | INITIAL_MEM_28M | INITIAL_IRQ_PREF))
#define PATI_HW_PCI_ONLY ((BOOT_EXT_FLASH | INITIAL_MEM_28M | INITIAL_IRQ_PREF | PCI_MASTER_ONLY))
#define PATI_HW_CPU_ACC ((BOOT_EXT_FLASH | INITIAL_MEM_12M | INITIAL_IRQ_PREF | PCI_MASTER_ONLY))
#define PATI_HW_CPU_SLAVE ((BOOT_EXT_FLASH | INITIAL_MEM_12M | INITIAL_IRQ_PREF | PCI_MASTER_ONLY | LOCAL_CPU_SLAVE))
/***************************************************
* Direct Master Config
***************************************************/
#define PATI_DMASTER_PCI_ADDR 0x01000000
#define PATI_BUS_MASTER 1
#define PATI_DMASTER_MASK 0xFFF00000 /* 1MByte */
#define PATI_DMASTER_ADDR 0x01000000 /* Local Address */
#define PATI_DMASTER_MEMORY_EN 0x00000001 /* 0x00000001 */
#define PATI_DMASTER_READ_AHEAD 0x00000004 /* 0x00000004 */
#define PATI_DMASTER_READ_NOT_AHEAD 0x00000000 /* 0x00000004 */
#define PATI_DMASTER_PRE_SIZE_CNTRL_0 0x00000000
#define PATI_DMASTER_PRE_SIZE_CNTRL_4 0x00000008
#define PATI_DMASTER_PRE_SIZE_CNTRL_8 0x00001000
#define PATI_DMASTER_PRE_SIZE_CNTRL_16 0x00001008
#define PATI_DMASTER_REL_PCI 0x00000000
#define PATI_DMASTER_NOT_REL_PCI 0x00000010
#define PATI_DMASTER_WR_INVAL 0x00000200
#define PATI_DMASTER_NOT_WR_INVAL 0x00000000
#define PATI_DMASTER_PRE_LIMIT 0x00000800
#define PATI_DMASTER_PRE_CONT 0x00000000
#define PATI_DMASTER_DELAY_WR_0 0x00000000
#define PATI_DMASTER_DELAY_WR_4 0x00004000
#define PATI_DMASTER_DELAY_WR_8 0x00008000
#define PATI_DMASTER_DELAY_WR_16 0x0000C000
#define PATI_DMASTER_PCI_ADDR_MASK 0xFFFF0000
#define PATI_DMASTER_ATTR \
PATI_DMASTER_MEMORY_EN | \
PATI_DMASTER_READ_AHEAD | \
PATI_DMASTER_PRE_SIZE_CNTRL_4 | \
PATI_DMASTER_REL_PCI | \
PATI_DMASTER_NOT_WR_INVAL | \
PATI_DMASTER_PRE_LIMIT | \
PATI_DMASTER_DELAY_WR_0
#endif /* #ifndef __PATI_H_ */

View file

@ -0,0 +1,91 @@
#ifndef __PCI_EEPROM_H_
#define __PCI_EEPROM_H_ 1
#include "pati.h"
/******************************************************************************
* Eeprom Support
******************************************************************************/
/**********************************************
* Definitions
**********************************************/
#define EE46_CMD_LEN 9 /* Bits in instructions */
#define EE56_CMD_LEN 11 /* Bits in instructions */
#define EE66_CMD_LEN 11 /* Bits in instructions */
#define EE_READ 0x0180 /* 01 1000 0000 read instruction */
#define EE_WRITE 0x0140 /* 01 0100 0000 write instruction */
#define EE_WREN 0x0130 /* 01 0011 0000 write enable instruction */
#define EE_WRALL 0x0110 /* 01 0001 0000 write all registers */
#define EE_PRREAD 0x0180 /* 01 1000 0000 read address stored in Protect Register */
#define EE_PRWRITE 0x0140 /* 01 0100 0000 write the address into PR */
#define EE_WDS 0x0100 /* 01 0000 0000 write disable instruction */
#define EE_PREN 0x0130 /* 01 0011 0000 protect enable instruction */
#define EE_PRCLEAR 0x01FF /* 01 1111 1111 clear protect register instr */
#define EE_PRDS 0x0100 /* 01 0000 0000 ONE TIME ONLY, permenant */
/***************************************************
* EEPROM
***************************************************/
#define LOW_WORD(x) (((x) & 0xFFFF))
#define HIGH_WORD(x) (((x) >> 16) & 0xFFFF)
typedef struct pci_eeprom_t {
unsigned short offset;
unsigned short value;
} pci_eeprom;
static pci_eeprom pati_eeprom[] = {
{ 0x00,PCI_DEVICE_ID_PATI }, /* PCI Device ID PCIIDR[31:16] */
{ 0x02,PCI_VENDOR_ID_MPL }, /* PCI Vendor ID PCIIDR[15:0] */
{ 0x04,PCI_CLASS_PROCESSOR_POWERPC }, /* PCI Class Code PCICCR[23:8] */
{ 0x06,0x00BA }, /* PCI Class Code / PCI Revision ID PCICCR[7:0] / PCIREV[7:0] */
{ 0x08,0x0007 }, /* PCI Maximum Latency / PCI Minimum Grant PCIMLR[7:0] / PCIMGR[7:0] */
{ 0x0A,0x0100 }, /* PCI Interrupt Pin / PCI Interrupt Line PCIIPR[7:0] / PCIILR[7:0] */
{ 0x0C,0x0000 }, /* MSW of Mailbox 0 (User Defined) PCI9056_MAILBOX0[31:16] */
{ 0x0E,0x0000 }, /* LSW of Mailbox 0 (User Defined) PCI9056_MAILBOX0[15:0] */
{ 0x10,0x0000 }, /* MSW of Mailbox 1 (User Defined) PCI9056_MAILBOX1[31:16] */
{ 0x12,0x0000 }, /* LSW of Mailbox 1 (User Defined) PCI9056_MAILBOX1[15:0] */
{ 0x14,HIGH_WORD(PATI_LOC_CFG_MASK) }, /* MSW of Direct Slave Local Address Space 0 Range LAS0RR[31:16] */
{ 0x16,LOW_WORD(PATI_LOC_CFG_MASK) }, /* LSW of Direct Slave Local Address Space 0 Range LAS0RR[15:0] */
{ 0x18,HIGH_WORD(PATI_LOC_CFG_ADDR) }, /* MSW of Direct Slave Local Address Space 0 Local Base Address (Remap) LAS0BA[31:16] (CFG) */
{ 0x1A,LOW_WORD(PATI_LOC_CFG_ADDR)|1 }, /* LSW of Direct Slave Local Address Space 0 Local Base Address (Remap) LAS0BA[15:2, 0], Reserved [1] */
{ 0x1C,0x0000 }, /* MSW of Mode/DMA Arbitration MARBR[31, 29:16] or DMAARB[31, 29:16], Reserved [30] */
{ 0x1E,0x0000 }, /* LSW of Mode/DMA Arbitration MARBR[15:0] or DMAARB[15:0] */
{ 0x20,0x0030 }, /* Local Miscellaneous Control 2 / Serial EEPROM WP Addr Boundary LMISC2[5:0], Res[7:6] / PROT_AREA[6:0], Res[7] */
{ 0x22,0x0510 }, /* Local Miscellaneous Control 1 / Local Bus Big/Little Endian Descriptor LMISC1[7:0] / BIGEND[7:0] */
{ 0x24,0x0000 }, /* MSW of Direct Slave Expansion ROM Range EROMRR[31:16] */
{ 0x26,0x0000 }, /* LSW of Direct Slave Expansion ROM Range EROMRR[15:11, 0], Reserved [10:1] */
{ 0x28,0x0000 }, /* MSW of Direct Slave Expansion ROM Local Base Address (Remap) and BREQo Control EROMBA[31:16] */
{ 0x2A,0x0000 }, /* LSW of Direct Slave Expansion ROM Local Base Address (Remap) and BREQo Control EROMBA[15:11, 5:0], Reserved [10:6] */
{ 0x2C,(0x4243 | HIGH_WORD((PATI_LOC_CFG_SPACE0_ATTR))) }, /* MSW of Local Address Space 0/Expansion ROM Bus Region Descriptor LBRD0[31:16] */
{ 0x2E,LOW_WORD(PATI_LOC_CFG_SPACE0_ATTR) }, /* LSW of Local Address Space 0/Expansion ROM Bus Region Descriptor LBRD0[15:0] */
{ 0x30,HIGH_WORD(PATI_DMASTER_MASK) }, /* MSW of Local Range for Direct Master-to-PCI DMRR[31:16] */
{ 0x32,LOW_WORD(PATI_DMASTER_MASK) }, /* LSW of Local Range for Direct Master-to-PCI (Reserved) DMRR[15:0] */
{ 0x34,HIGH_WORD(PATI_DMASTER_ADDR) }, /* MSW of Local Base Address for Direct Master-to-PCI Memory DMLBAM[31:16] */
{ 0x36,LOW_WORD(PATI_DMASTER_ADDR) }, /* LSW of Local Base Address for Direct Master-to-PCI Memory (Reserved) DMLBAM[15:0] */
{ 0x38,0x0000 }, /* MSW of Local Bus Address for Direct Master-to-PCI I/O Configuration DMLBAI[31:16] */
{ 0x3A,0x0000 }, /* LSW of Local Bus Address for Direct Master-to-PCI I/O Configuration (Reserved) DMLBAI[15:0] */
{ 0x3C,0x0000 }, /* MSW of PCI Base Address (Remap) for Direct Master-to-PCI Memory DMPBAM[31:16] */
{ 0x3E,0x0000 }, /* LSW of PCI Base Address (Remap) for Direct Master-to-PCI Memory DMPBAM[15:0] */
{ 0x40,0x0000 }, /* MSW of PCI Configuration Address for Direct Master-to-PCI I/O Configuration DMCFGA[31, 23:16] Reserved [30:24]*/
{ 0x42,0x0000 }, /* LSW of PCI Configuration Address for Direct Master-to-PCI I/O Configuration DMCFGA[15:0] */
{ 0x44,0x0000 }, /* PCI Subsystem ID PCISID[15:0] */
{ 0x46,0x0000 }, /* PCI Subsystem Vendor ID PCISVID[15:0] */
{ 0x48,HIGH_WORD(PATI_LOC_SDRAM_MASK) }, /* MSW of Direct Slave Local Address Space 1 Range (1 MB) LAS1RR[31:16] */
{ 0x4A,LOW_WORD(PATI_LOC_SDRAM_MASK) }, /* LSW of Direct Slave Local Address Space 1 Range (1 MB) LAS1RR[15:0] */
{ 0x4C,HIGH_WORD(PATI_LOC_SDRAM_ADDR) }, /* MSW of Direct Slave Local Address Space 1 Local Base Address (Remap) LAS1BA[31:16] (SDRAM) */
{ 0x4E,LOW_WORD(PATI_LOC_SDRAM_ADDR) | 0x1 }, /* LSW of Direct Slave Local Address Space 1 Local Base Address (Remap) LAS1BA[15:2, 0], Reserved [1] */
{ 0x50,HIGH_WORD(PATI_LOC_SDRAM_SPACE1_ATTR) }, /* MSW of Local Address Space 1 Bus Region Descriptor LBRD1[31:16] */
{ 0x52,LOW_WORD(PATI_LOC_SDRAM_SPACE1_ATTR) }, /* LSW of Local Address Space 1 Bus Region Descriptor (Reserved) LBRD1[15:0] */
{ 0x54,0x0000 }, /* Hot Swap Control/Status (Reserved) Reserved */
{ 0x56,0x0000 }, /* Hot Swap Next Capability Pointer / Hot Swap Control HS_NEXT[7:0] / HS_CNTL[7:0] */
{ 0x58,0x0000 }, /* Reserved Reserved */
{ 0x5A,0x0000 }, /* PCI Arbiter Control PCIARB[3:0], Reserved [15:4] */
{ 0x5C,0x0000 }, /* Power Management Capabilities PMC[15:9, 2:0] */
{ 0x5E,0x0000 }, /* Power Management Next Capability Pointer (Reserved) / Power Management Capability ID (Reserved) Reserved*/
{ 0x60,0x0000 }, /* Power Management Data / PMCSR Bridge Support Extension (Reserved) PMDATA[7:0] / Reserved */
{ 0x62,0x0000 }, /* Power Management Control/Status PMCSR[14:8] */
{ 0xFFFF,0xFFFF} /* terminaror */
};
#define PATI_EEPROM_LAST_OFFSET 0x64
#endif /* #ifndef __PCI_EEPROM_H_ */

View file

@ -0,0 +1,111 @@
/*
* (C) Copyright 2003
* Denis Peter, d.peter@mpl.ch
* 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
*/
/* PLX9096 register definitions
*/
#ifndef __PLX9056_H_
#define __PLX9056_H_ 1
#include <pci.h>
#ifdef PLX9056_LOC
#define LOCAL_OFFSET 0x080
/* PCI Config regs */
#else
#define LOCAL_OFFSET 0x000
#endif
#define PCI9056_VENDOR_ID PCI_VENDOR_ID
/*#define PCI9656_DEVICE_ID PCI_DEVICE_ID */
#define PCI9056_COMMAND PCI_COMMAND
/*#define PCI9656_STATUS PCI_STATUS */
#define PCI9056_REVISION PCI_REVISION_ID
#define PCI9056_CACHE_SIZE PCI_CACHE_LINE_SIZE
#define PCI9056_RTR_BASE PCI_BASE_ADDRESS_0
#define PCI9056_RTR_IO_BASE PCI_BASE_ADDRESS_1
#define PCI9056_LOCAL_BASE0 PCI_BASE_ADDRESS_2
#define PCI9056_LOCAL_BASE1 PCI_BASE_ADDRESS_3
#define PCI9056_UNUSED_BASE1 PCI_BASE_ADDRESS_4
#define PCI9056_UNUSED_BASE2 PCI_BASE_ADDRESS_5
#define PCI9056_CIS_PTR PCI_CARDBUS_CIS
#define PCI9056_SUB_ID PCI_SUBSYSTEM_VENDOR_ID
#define PCI9056_EXP_ROM_BASE PCI_ROM_ADDRESS
#define PCI9056_CAP_PTR PCI_CAPABILITY_LIST
#define PCI9056_INT_LINE PCI_INTERRUPT_LINE
#if defined(PLX9056_LOC)
#define PCI9056_PM_CAP_ID 0x180
#define PCI9056_PM_CSR 0x184
#define PCI9056_HS_CAP_ID 0x188
#define PCI9056_VPD_CAP_ID 0x18C
#define PCI9056_VPD_DATA 0x190
#endif
#define PCI_DEVICE_ID_PLX9056 0x9056
/* Local Configuration Registers Accessible via the PCI Base address + Variable */
#define PCI9056_SPACE0_RANGE (0x000 + LOCAL_OFFSET)
#define PCI9056_SPACE0_REMAP (0x004 + LOCAL_OFFSET)
#define PCI9056_LOCAL_DMA_ARBIT (0x008 + LOCAL_OFFSET)
#define PCI9056_ENDIAN_DESC (0x00c + LOCAL_OFFSET)
#define PCI9056_EXP_ROM_RANGE (0x010 + LOCAL_OFFSET)
#define PCI9056_EXP_ROM_REMAP (0x014 + LOCAL_OFFSET)
#define PCI9056_SPACE0_ROM_DESC (0x018 + LOCAL_OFFSET)
#define PCI9056_DM_RANGE (0x01c + LOCAL_OFFSET)
#define PCI9056_DM_MEM_BASE (0x020 + LOCAL_OFFSET)
#define PCI9056_DM_IO_BASE (0x024 + LOCAL_OFFSET)
#define PCI9056_DM_PCI_MEM_REMAP (0x028 + LOCAL_OFFSET)
#define PCI9056_DM_PCI_IO_CONFIG (0x02c + LOCAL_OFFSET)
#define PCI9056_SPACE1_RANGE (0x0f0 + LOCAL_OFFSET)
#define PCI9056_SPACE1_REMAP (0x0f4 + LOCAL_OFFSET)
#define PCI9056_SPACE1_DESC (0x0f8 + LOCAL_OFFSET)
#define PCI9056_DM_DAC (0x0fc + LOCAL_OFFSET)
#ifdef PLX9056_LOC
#define PCI9056_ARBITER_CTRL 0x1A0
#define PCI9056_ABORT_ADDRESS 0x1A4
#endif
/* Runtime registers PCI Address + LOCAL_OFFSET */
#ifdef PLX9056_LOC
#define PCI9056_MAILBOX0 0x0C0
#define PCI9056_MAILBOX1 0x0C4
#else
#define PCI9056_MAILBOX0 0x078
#define PCI9056_MAILBOX1 0x07c
#endif
#define PCI9056_MAILBOX2 (0x048 + LOCAL_OFFSET)
#define PCI9056_MAILBOX3 (0x04c + LOCAL_OFFSET)
#define PCI9056_MAILBOX4 (0x050 + LOCAL_OFFSET)
#define PCI9056_MAILBOX5 (0x054 + LOCAL_OFFSET)
#define PCI9056_MAILBOX6 (0x058 + LOCAL_OFFSET)
#define PCI9056_MAILBOX7 (0x05c + LOCAL_OFFSET)
#define PCI9056_PCI_TO_LOC_DBELL (0x060 + LOCAL_OFFSET)
#define PCI9056_LOC_TO_PCI_DBELL (0x064 + LOCAL_OFFSET)
#define PCI9056_INT_CTRL_STAT (0x068 + LOCAL_OFFSET)
#define PCI9056_EEPROM_CTRL_STAT (0x06c + LOCAL_OFFSET)
#define PCI9056_PERM_VENDOR_ID (0x070 + LOCAL_OFFSET)
#define PCI9056_REVISION_ID (0x074 + LOCAL_OFFSET)
#endif /* #ifndef __PLX9056_H_ */

View file

@ -0,0 +1,54 @@
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
ifneq ($(OBJTREE),$(SRCTREE))
$(shell mkdir -p $(obj)../common)
endif
LIB = $(obj)lib$(BOARD).o
COBJS = $(BOARD).o cmd_pip405.o \
../common/pci.o \
../common/isa.o \
../common/kbd.o \
../common/usb_uhci.o \
../common/common_util.o
SOBJS = init.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
SOBJS := $(addprefix $(obj),$(SOBJS))
$(LIB): $(OBJS) $(SOBJS)
$(call cmd_link_o_target, $(OBJS) $(SOBJS))
#########################################################################
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################

View file

@ -0,0 +1,69 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* 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
*
* hacked for PIP405
*/
#include <common.h>
#include <command.h>
#include "pip405.h"
#include "../common/common_util.h"
extern void print_pip405_info(void);
extern int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
/* ------------------------------------------------------------------------- */
int do_pip405(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
ulong led_on,led_nr;
if (strcmp(argv[1], "info") == 0)
{
print_pip405_info();
return 0;
}
if (strcmp(argv[1], "led") == 0)
{
led_nr = (ulong)simple_strtoul(argv[2], NULL, 10);
led_on = (ulong)simple_strtoul(argv[3], NULL, 10);
if(!led_nr)
user_led0(led_on);
else
user_led1(led_on);
return 0;
}
return (do_mplcommon(cmdtp, flag, argc, argv));
}
U_BOOT_CMD(
pip405, 6, 1, do_pip405,
"PIP405 specific Cmds",
"flash mem [SrcAddr] - updates U-Boot with image in memory\n"
"pip405 flash floppy [SrcAddr] - updates U-Boot with image from floppy\n"
"pip405 flash mps - updates U-Boot with image from MPS"
);
/* ------------------------------------------------------------------------- */

View file

@ -0,0 +1,218 @@
/*------------------------------------------------------------------------------+
* This source code is dual-licensed. You may use it under the terms of
* the GNU General Public License version 2, or under the license below.
*
* 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 or Multi Purpose Socket
* Bank 1 - Multi Purpose Socket or Flash
* Bank 2 - not used
* Bank 3 - not used
* Bank 4 - not used
* Bank 5 - not used
* Bank 6 - used to switch on the 12V for the Multipurpose socket
* Bank 7 - Config Register
*-----------------------------------------------------------------------------*/
#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
#include <configs/PIP405.h>
#include <ppc_asm.tmpl>
#include <ppc_defs.h>
#include <asm/cache.h>
#include <asm/mmu.h>
#include <asm/ppc4xx.h>
#include "pip405.h"
.globl ext_bus_cntlr_init
ext_bus_cntlr_init:
mflr r4 /* save link register */
mfdcr r3,CPC0_PSR /* get strapping reg */
andi. r0, r3, PSR_ROM_LOC /* mask out irrelevant bits */
bnelr /* jump back if PCI boot */
bl ..getAddr
..getAddr:
mflr r3 /* get address of ..getAddr */
mtlr r4 /* restore link register */
addi r4,0,14 /* set ctr to 14; used to prefetch */
mtctr r4 /* 14 cache lines to fit this function */
/* in cache (gives us 8x14=112 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 14 cache lines */
/*-------------------------------------------------------------------
* Delay to ensure all accesses to ROM are complete before changing
* bank 0 timings.
*------------------------------------------------------------------- */
addis r3,0,0x0
ori r3,r3,0xA000
mtctr r3
..spinlp:
bdnz ..spinlp /* spin loop */
/*-----------------------------------------------------------------------
* decide boot up mode
*----------------------------------------------------------------------- */
addi r4,0,PB0CR
mtdcr EBC0_CFGADDR,r4
mfdcr r4,EBC0_CFGDATA
andi. r0, r4, 0x2000 /* mask out irrelevant bits */
beq 0f /* jump if 8 bit bus width */
/* setup 16 bit things
*-----------------------------------------------------------------------
* Memory Bank 0 (16 Bit Flash) initialization
*---------------------------------------------------------------------- */
addi r4,0,PB1AP
mtdcr EBC0_CFGADDR,r4
addis r4,0,(FLASH_AP_B)@h
ori r4,r4,(FLASH_AP_B)@l
mtdcr EBC0_CFGDATA,r4
addi r4,0,PB0CR
mtdcr EBC0_CFGADDR,r4
/* BS=0x010(4MB),BU=0x3(R/W), */
addis r4,0,(FLASH_CR_B)@h
ori r4,r4,(FLASH_CR_B)@l
mtdcr EBC0_CFGDATA,r4
b 1f
0:
/* 8Bit boot mode: */
/*-----------------------------------------------------------------------
* Memory Bank 0 Multi Purpose Socket initialization
*----------------------------------------------------------------------- */
/* 0x7F8FFE80 slowest boot */
addi r4,0,PB1AP
mtdcr EBC0_CFGADDR,r4
addis r4,0,(MPS_AP_B)@h
ori r4,r4,(MPS_AP_B)@l
mtdcr EBC0_CFGDATA,r4
addi r4,0,PB0CR
mtdcr EBC0_CFGADDR,r4
/* BS=0x010(4MB),BU=0x3(R/W), */
addis r4,0,(MPS_CR_B)@h
ori r4,r4,(MPS_CR_B)@l
mtdcr EBC0_CFGDATA,r4
1:
/*-----------------------------------------------------------------------
* Memory Bank 2-3-4-5-6 (not used) initialization
*-----------------------------------------------------------------------*/
addi r4,0,PB1CR
mtdcr EBC0_CFGADDR,r4
addis r4,0,0x0000
ori r4,r4,0x0000
mtdcr EBC0_CFGDATA,r4
addi r4,0,PB2CR
mtdcr EBC0_CFGADDR,r4
addis r4,0,0x0000
ori r4,r4,0x0000
mtdcr EBC0_CFGDATA,r4
addi r4,0,PB3CR
mtdcr EBC0_CFGADDR,r4
addis r4,0,0x0000
ori r4,r4,0x0000
mtdcr EBC0_CFGDATA,r4
addi r4,0,PB4CR
mtdcr EBC0_CFGADDR,r4
addis r4,0,0x0000
ori r4,r4,0x0000
mtdcr EBC0_CFGDATA,r4
addi r4,0,PB5CR
mtdcr EBC0_CFGADDR,r4
addis r4,0,0x0000
ori r4,r4,0x0000
mtdcr EBC0_CFGDATA,r4
addi r4,0,PB6CR
mtdcr EBC0_CFGADDR,r4
addis r4,0,0x0000
ori r4,r4,0x0000
mtdcr EBC0_CFGDATA,r4
addi r4,0,PB7CR
mtdcr EBC0_CFGADDR,r4
addis r4,0,0x0000
ori r4,r4,0x0000
mtdcr EBC0_CFGDATA,r4
nop /* pass2 DCR errata #8 */
blr
#if defined(CONFIG_BOOT_PCI)
.section .bootpg,"ax"
.globl _start_pci
/*******************************************
*/
_start_pci:
/* first handle errata #68 / PCI_18 */
iccci r0, r0 /* invalidate I-cache */
lis r31, 0
mticcr r31 /* ICCR = 0 (all uncachable) */
isync
mfccr0 r28 /* set CCR0[24] = 1 */
ori r28, r28, 0x0080
mtccr0 r28
/* setup PMM0MA (0xEF400004) and PMM0PCIHA (0xEF40000C) */
lis r28, 0xEF40
addi r28, r28, 0x0004
stw r31, 0x0C(r28) /* clear PMM0PCIHA */
lis r29, 0xFFF8 /* open 512 kByte */
addi r29, r29, 0x0001/* and enable this region */
stwbrx r29, r0, r28 /* write PMM0MA */
lis r28, 0xEEC0 /* address of PCIC0_CFGADDR */
addi r29, r28, 4 /* add 4 to r29 -> PCIC0_CFGDATA */
lis r31, 0x8000 /* set en bit bus 0 */
ori r31, r31, 0x304C/* device 6 func 0 reg 4C (XBCS register) */
stwbrx r31, r0, r28 /* write it */
lwbrx r31, r0, r29 /* load XBCS register */
oris r31, r31, 0x02C4/* clear BIOSCS WPE, set lower, extended and 1M extended BIOS enable */
stwbrx r31, r0, r29 /* write back XBCS register */
nop
nop
b _start /* normal start */
#endif

View file

@ -0,0 +1,975 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* 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
*
*
* TODO: clean-up
*/
#include <common.h>
#include "pip405.h"
#include <asm/processor.h>
#include <i2c.h>
#include <stdio_dev.h>
#include "../common/isa.h"
#include "../common/common_util.h"
DECLARE_GLOBAL_DATA_PTR;
#undef SDRAM_DEBUG
#define FALSE 0
#define TRUE 1
/* 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
typedef enum {
SDRAM_NO_ERR,
SDRAM_SPD_COMM_ERR,
SDRAM_SPD_CHKSUM_ERR,
SDRAM_UNSUPPORTED_ERR,
SDRAM_UNKNOWN_ERR
} SDRAM_ERR;
typedef struct {
const unsigned char mode;
const unsigned char row;
const unsigned char col;
const unsigned char bank;
} SDRAM_SETUP;
static const SDRAM_SETUP sdram_setup_table[] = {
{1, 11, 9, 2},
{1, 11, 10, 2},
{2, 12, 9, 4},
{2, 12, 10, 4},
{3, 13, 9, 4},
{3, 13, 10, 4},
{3, 13, 11, 4},
{4, 12, 8, 2},
{4, 12, 8, 4},
{5, 11, 8, 2},
{5, 11, 8, 4},
{6, 13, 8, 2},
{6, 13, 8, 4},
{7, 13, 9, 2},
{7, 13, 10, 2},
{0, 0, 0, 0}
};
static const unsigned char cal_indextable[] = {
9, 23, 25
};
/*
* translate ns.ns/10 coding of SPD timing values
* into 10 ps unit values
*/
unsigned short NS10to10PS (unsigned char spd_byte, unsigned char spd_version)
{
unsigned short ns, ns10;
/* isolate upper nibble */
ns = (spd_byte >> 4) & 0x0F;
/* isolate lower nibble */
ns10 = (spd_byte & 0x0F);
return (ns * 100 + ns10 * 10);
}
/*
* translate ns.ns/4 coding of SPD timing values
* into 10 ps unit values
*/
unsigned short NS4to10PS (unsigned char spd_byte, unsigned char spd_version)
{
unsigned short ns, ns4;
/* isolate upper 6 bits */
ns = (spd_byte >> 2) & 0x3F;
/* isloate lower 2 bits */
ns4 = (spd_byte & 0x03);
return (ns * 100 + ns4 * 25);
}
/*
* translate ns coding of SPD timing values
* into 10 ps unit values
*/
unsigned short NSto10PS (unsigned char spd_byte)
{
return (spd_byte * 100);
}
void SDRAM_err (const char *s)
{
#ifndef SDRAM_DEBUG
(void) get_clocks ();
gd->baudrate = 9600;
serial_init ();
#endif
serial_puts ("\n");
serial_puts (s);
serial_puts ("\n enable SDRAM_DEBUG for more info\n");
for (;;);
}
#ifdef SDRAM_DEBUG
void write_hex (unsigned char i)
{
char cc;
cc = i >> 4;
cc &= 0xf;
if (cc > 9)
serial_putc (cc + 55);
else
serial_putc (cc + 48);
cc = i & 0xf;
if (cc > 9)
serial_putc (cc + 55);
else
serial_putc (cc + 48);
}
void write_4hex (unsigned long val)
{
write_hex ((unsigned char) (val >> 24));
write_hex ((unsigned char) (val >> 16));
write_hex ((unsigned char) (val >> 8));
write_hex ((unsigned char) val);
}
#endif
int board_early_init_f (void)
{
unsigned char datain[128];
unsigned long sdram_size = 0;
SDRAM_SETUP *t = (SDRAM_SETUP *) sdram_setup_table;
unsigned long memclk;
unsigned long tmemclk = 0;
unsigned long tmp, bank, baseaddr, bank_size;
unsigned short i;
unsigned char rows, cols, banks, sdram_banks, density;
unsigned char supported_cal, trp_clocks, trcd_clocks, tras_clocks,
trc_clocks;
unsigned char cal_index, cal_val, spd_version, spd_chksum;
unsigned char buf[8];
#ifdef SDRAM_DEBUG
unsigned char tctp_clocks;
#endif
/* set up the config port */
mtdcr (EBC0_CFGADDR, PB7AP);
mtdcr (EBC0_CFGDATA, CONFIG_PORT_AP);
mtdcr (EBC0_CFGADDR, PB7CR);
mtdcr (EBC0_CFGDATA, CONFIG_PORT_CR);
memclk = get_bus_freq (tmemclk);
tmemclk = 1000000000 / (memclk / 100); /* in 10 ps units */
#ifdef SDRAM_DEBUG
(void) get_clocks ();
gd->baudrate = 9600;
serial_init ();
serial_puts ("\nstart SDRAM Setup\n");
#endif
/* Read Serial Presence Detect Information */
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
for (i = 0; i < 128; i++)
datain[i] = 127;
i2c_read(SPD_EEPROM_ADDRESS,0,1,datain,128);
#ifdef SDRAM_DEBUG
serial_puts ("\ni2c_read returns ");
write_hex (i);
serial_puts ("\n");
#endif
#ifdef SDRAM_DEBUG
for (i = 0; i < 128; i++) {
write_hex (datain[i]);
serial_puts (" ");
if (((i + 1) % 16) == 0)
serial_puts ("\n");
}
serial_puts ("\n");
#endif
spd_chksum = 0;
for (i = 0; i < 63; i++) {
spd_chksum += datain[i];
} /* endfor */
if (datain[63] != spd_chksum) {
#ifdef SDRAM_DEBUG
serial_puts ("SPD chksum: 0x");
write_hex (datain[63]);
serial_puts (" != calc. chksum: 0x");
write_hex (spd_chksum);
serial_puts ("\n");
#endif
SDRAM_err ("SPD checksum Error");
}
/* SPD seems to be ok, use it */
/* get SPD version */
spd_version = datain[62];
/* do some sanity checks on the kind of RAM */
if ((datain[0] < 0x80) || /* less than 128 valid bytes in SPD */
(datain[2] != 0x04) || /* if not SDRAM */
(!((datain[6] == 0x40) || (datain[6] == 0x48))) || /* or not (64 Bit or 72 Bit) */
(datain[7] != 0x00) || (datain[8] != 0x01) || /* or not LVTTL signal levels */
(datain[126] == 0x66)) /* or a 66MHz modules */
SDRAM_err ("unsupported SDRAM");
#ifdef SDRAM_DEBUG
serial_puts ("SDRAM sanity ok\n");
#endif
/* get number of rows/cols/banks out of byte 3+4+5 */
rows = datain[3];
cols = datain[4];
banks = datain[5];
/* get number of SDRAM banks out of byte 17 and
supported CAS latencies out of byte 18 */
sdram_banks = datain[17];
supported_cal = datain[18] & ~0x81;
while (t->mode != 0) {
if ((t->row == rows) && (t->col == cols)
&& (t->bank == sdram_banks))
break;
t++;
} /* endwhile */
#ifdef SDRAM_DEBUG
serial_puts ("rows: ");
write_hex (rows);
serial_puts (" cols: ");
write_hex (cols);
serial_puts (" banks: ");
write_hex (banks);
serial_puts (" mode: ");
write_hex (t->mode);
serial_puts ("\n");
#endif
if (t->mode == 0)
SDRAM_err ("unsupported SDRAM");
/* get tRP, tRCD, tRAS and density from byte 27+29+30+31 */
#ifdef SDRAM_DEBUG
serial_puts ("tRP: ");
write_hex (datain[27]);
serial_puts ("\ntRCD: ");
write_hex (datain[29]);
serial_puts ("\ntRAS: ");
write_hex (datain[30]);
serial_puts ("\n");
#endif
trp_clocks = (NSto10PS (datain[27]) + (tmemclk - 1)) / tmemclk;
trcd_clocks = (NSto10PS (datain[29]) + (tmemclk - 1)) / tmemclk;
tras_clocks = (NSto10PS (datain[30]) + (tmemclk - 1)) / tmemclk;
density = datain[31];
/* trc_clocks is sum of trp_clocks + tras_clocks */
trc_clocks = trp_clocks + tras_clocks;
#ifdef SDRAM_DEBUG
/* ctp = ((trp + tras) - trp - trcd) => tras - trcd */
tctp_clocks =
((NSto10PS (datain[30]) - NSto10PS (datain[29])) +
(tmemclk - 1)) / tmemclk;
serial_puts ("c_RP: ");
write_hex (trp_clocks);
serial_puts ("\nc_RCD: ");
write_hex (trcd_clocks);
serial_puts ("\nc_RAS: ");
write_hex (tras_clocks);
serial_puts ("\nc_RC: (RP+RAS): ");
write_hex (trc_clocks);
serial_puts ("\nc_CTP: ((RP+RAS)-RP-RCD): ");
write_hex (tctp_clocks);
serial_puts ("\nt_CTP: RAS - RCD: ");
write_hex ((unsigned
char) ((NSto10PS (datain[30]) -
NSto10PS (datain[29])) >> 8));
write_hex ((unsigned char) (NSto10PS (datain[30]) - NSto10PS (datain[29])));
serial_puts ("\ntmemclk: ");
write_hex ((unsigned char) (tmemclk >> 8));
write_hex ((unsigned char) (tmemclk));
serial_puts ("\n");
#endif
cal_val = 255;
for (i = 6, cal_index = 0; (i > 0) && (cal_index < 3); i--) {
/* is this CAS latency supported ? */
if ((supported_cal >> i) & 0x01) {
buf[0] = datain[cal_indextable[cal_index]];
if (cal_index < 2) {
if (NS10to10PS (buf[0], spd_version) <= tmemclk)
cal_val = i;
} else {
/* SPD bytes 25+26 have another format */
if (NS4to10PS (buf[0], spd_version) <= tmemclk)
cal_val = i;
} /* endif */
cal_index++;
} /* endif */
} /* endfor */
#ifdef SDRAM_DEBUG
serial_puts ("CAL: ");
write_hex (cal_val + 1);
serial_puts ("\n");
#endif
if (cal_val == 255)
SDRAM_err ("unsupported SDRAM");
/* get SDRAM timing register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_TR);
tmp = mfdcr (SDRAM0_CFGDATA) & ~0x018FC01F;
/* insert CASL value */
/* tmp |= ((unsigned long)cal_val) << 23; */
tmp |= ((unsigned long) cal_val) << 23;
/* insert PTA value */
tmp |= ((unsigned long) (trp_clocks - 1)) << 18;
/* insert CTP value */
/* tmp |= ((unsigned long)(trc_clocks - trp_clocks - trcd_clocks - 1)) << 16; */
tmp |= ((unsigned long) (trc_clocks - trp_clocks - trcd_clocks)) << 16;
/* insert LDF (always 01) */
tmp |= ((unsigned long) 0x01) << 14;
/* insert RFTA value */
tmp |= ((unsigned long) (trc_clocks - 4)) << 2;
/* insert RCD value */
tmp |= ((unsigned long) (trcd_clocks - 1)) << 0;
#ifdef SDRAM_DEBUG
serial_puts ("sdtr: ");
write_4hex (tmp);
serial_puts ("\n");
#endif
/* write SDRAM timing register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_TR);
mtdcr (SDRAM0_CFGDATA, tmp);
baseaddr = CONFIG_SYS_SDRAM_BASE;
bank_size = (((unsigned long) density) << 22) / 2;
/* insert AM value */
tmp = ((unsigned long) t->mode - 1) << 13;
/* insert SZ value; */
switch (bank_size) {
case 0x00400000:
tmp |= ((unsigned long) 0x00) << 17;
break;
case 0x00800000:
tmp |= ((unsigned long) 0x01) << 17;
break;
case 0x01000000:
tmp |= ((unsigned long) 0x02) << 17;
break;
case 0x02000000:
tmp |= ((unsigned long) 0x03) << 17;
break;
case 0x04000000:
tmp |= ((unsigned long) 0x04) << 17;
break;
case 0x08000000:
tmp |= ((unsigned long) 0x05) << 17;
break;
case 0x10000000:
tmp |= ((unsigned long) 0x06) << 17;
break;
default:
SDRAM_err ("unsupported SDRAM");
} /* endswitch */
/* get SDRAM bank 0 register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_B0CR);
bank = mfdcr (SDRAM0_CFGDATA) & ~0xFFCEE001;
bank |= (baseaddr | tmp | 0x01);
#ifdef SDRAM_DEBUG
serial_puts ("bank0: baseaddr: ");
write_4hex (baseaddr);
serial_puts (" banksize: ");
write_4hex (bank_size);
serial_puts (" mb0cf: ");
write_4hex (bank);
serial_puts ("\n");
#endif
baseaddr += bank_size;
sdram_size += bank_size;
/* write SDRAM bank 0 register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_B0CR);
mtdcr (SDRAM0_CFGDATA, bank);
/* get SDRAM bank 1 register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_B1CR);
bank = mfdcr (SDRAM0_CFGDATA) & ~0xFFCEE001;
sdram_size = 0;
#ifdef SDRAM_DEBUG
serial_puts ("bank1: baseaddr: ");
write_4hex (baseaddr);
serial_puts (" banksize: ");
write_4hex (bank_size);
#endif
if (banks == 2) {
bank |= (baseaddr | tmp | 0x01);
baseaddr += bank_size;
sdram_size += bank_size;
} /* endif */
#ifdef SDRAM_DEBUG
serial_puts (" mb1cf: ");
write_4hex (bank);
serial_puts ("\n");
#endif
/* write SDRAM bank 1 register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_B1CR);
mtdcr (SDRAM0_CFGDATA, bank);
/* get SDRAM bank 2 register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_B2CR);
bank = mfdcr (SDRAM0_CFGDATA) & ~0xFFCEE001;
bank |= (baseaddr | tmp | 0x01);
#ifdef SDRAM_DEBUG
serial_puts ("bank2: baseaddr: ");
write_4hex (baseaddr);
serial_puts (" banksize: ");
write_4hex (bank_size);
serial_puts (" mb2cf: ");
write_4hex (bank);
serial_puts ("\n");
#endif
baseaddr += bank_size;
sdram_size += bank_size;
/* write SDRAM bank 2 register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_B2CR);
mtdcr (SDRAM0_CFGDATA, bank);
/* get SDRAM bank 3 register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_B3CR);
bank = mfdcr (SDRAM0_CFGDATA) & ~0xFFCEE001;
#ifdef SDRAM_DEBUG
serial_puts ("bank3: baseaddr: ");
write_4hex (baseaddr);
serial_puts (" banksize: ");
write_4hex (bank_size);
#endif
if (banks == 2) {
bank |= (baseaddr | tmp | 0x01);
baseaddr += bank_size;
sdram_size += bank_size;
}
/* endif */
#ifdef SDRAM_DEBUG
serial_puts (" mb3cf: ");
write_4hex (bank);
serial_puts ("\n");
#endif
/* write SDRAM bank 3 register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_B3CR);
mtdcr (SDRAM0_CFGDATA, bank);
/* get SDRAM refresh interval register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_RTR);
tmp = mfdcr (SDRAM0_CFGDATA) & ~0x3FF80000;
if (tmemclk < NSto10PS (16))
tmp |= 0x05F00000;
else
tmp |= 0x03F80000;
/* write SDRAM refresh interval register */
mtdcr (SDRAM0_CFGADDR, SDRAM0_RTR);
mtdcr (SDRAM0_CFGDATA, tmp);
/* enable SDRAM controller with no ECC, 32-bit SDRAM width, 16 byte burst */
mtdcr (SDRAM0_CFGADDR, SDRAM0_CFG);
tmp = (mfdcr (SDRAM0_CFGDATA) & ~0xFFE00000) | 0x80E00000;
mtdcr (SDRAM0_CFGADDR, SDRAM0_CFG);
mtdcr (SDRAM0_CFGDATA, tmp);
/*-------------------------------------------------------------------------+
| Interrupt controller setup for the PIP405 board.
| Note: IRQ 0-15 405GP internally generated; active high; level sensitive
| IRQ 16 405GP internally generated; active low; level sensitive
| IRQ 17-24 RESERVED
| IRQ 25 (EXT IRQ 0) SouthBridg; active low; level sensitive
| IRQ 26 (EXT IRQ 1) NMI: active low; level sensitive
| IRQ 27 (EXT IRQ 2) SMI: active Low; level sensitive
| IRQ 28 (EXT IRQ 3) PCI SLOT 3; active low; level sensitive
| IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive
| IRQ 30 (EXT IRQ 5) PCI SLOT 1; active low; level sensitive
| IRQ 31 (EXT IRQ 6) PCI SLOT 0; active low; level sensitive
| Note for PIP405 board:
| An interrupt taken for the SouthBridge (IRQ 25) indicates that
| the Interrupt Controller in the South Bridge has caused the
| interrupt. The IC must be read to determine which device
| caused the interrupt.
|
+-------------------------------------------------------------------------*/
mtdcr (UIC0SR, 0xFFFFFFFF); /* clear all ints */
mtdcr (UIC0ER, 0x00000000); /* disable all ints */
mtdcr (UIC0CR, 0x00000000); /* set all to be non-critical (for now) */
mtdcr (UIC0PR, 0xFFFFFF80); /* set int polarities */
mtdcr (UIC0TR, 0x10000000); /* set int trigger levels */
mtdcr (UIC0VCR, 0x00000001); /* set vect base=0,INT0 highest priority */
mtdcr (UIC0SR, 0xFFFFFFFF); /* clear all ints */
return 0;
}
int board_early_init_r(void)
{
int mode;
/*
* since we are relocated, we can finally enable i-cache
* and set up the flash CS correctly
*/
icache_enable();
setup_cs_reloc();
/* get and display boot mode */
mode = get_boot_mode();
if (mode & BOOT_PCI)
printf("PCI Boot %s Map\n", (mode & BOOT_MPS) ?
"MPS" : "Flash");
else
printf("%s Boot\n", (mode & BOOT_MPS) ?
"MPS" : "Flash");
return 0;
}
/* ------------------------------------------------------------------------- */
/*
* Check Board Identity:
*/
int checkboard (void)
{
char s[50];
unsigned char bc;
int i;
backup_t *b = (backup_t *) s;
puts ("Board: ");
i = getenv_f("serial#", (char *)s, 32);
if ((i == 0) || strncmp ((char *)s, "PIP405", 6)) {
get_backup_values (b);
if (strncmp (b->signature, "MPL\0", 4) != 0) {
puts ("### No HW ID - assuming PIP405");
} else {
b->serial_name[6] = 0;
printf ("%s SN: %s", b->serial_name,
&b->serial_name[7]);
}
} else {
s[6] = 0;
printf ("%s SN: %s", s, &s[7]);
}
bc = in8 (CONFIG_PORT_ADDR);
printf (" Boot Config: 0x%x\n", bc);
return (0);
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/*
initdram(int board_type) reads EEPROM via I2c. EEPROM contains all of
the necessary info for SDRAM controller configuration
*/
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
static int test_dram (unsigned long ramsize);
phys_size_t initdram (int board_type)
{
unsigned long bank_reg[4], tmp, bank_size;
int i, ds;
unsigned long TotalSize;
ds = 0;
/* since the DRAM controller is allready set up,
* calculate the size with the bank registers
*/
mtdcr (SDRAM0_CFGADDR, SDRAM0_B0CR);
bank_reg[0] = mfdcr (SDRAM0_CFGDATA);
mtdcr (SDRAM0_CFGADDR, SDRAM0_B1CR);
bank_reg[1] = mfdcr (SDRAM0_CFGDATA);
mtdcr (SDRAM0_CFGADDR, SDRAM0_B2CR);
bank_reg[2] = mfdcr (SDRAM0_CFGDATA);
mtdcr (SDRAM0_CFGADDR, SDRAM0_B3CR);
bank_reg[3] = mfdcr (SDRAM0_CFGDATA);
TotalSize = 0;
for (i = 0; i < 4; i++) {
if ((bank_reg[i] & 0x1) == 0x1) {
tmp = (bank_reg[i] >> 17) & 0x7;
bank_size = 4 << tmp;
TotalSize += bank_size;
} else
ds = 1;
}
if (ds == 1)
printf ("single-sided DIMM ");
else
printf ("double-sided DIMM ");
test_dram (TotalSize * 1024 * 1024);
/* bank 2 (SDRAM Clock 2) is not usable if 133MHz SDRAM IF */
(void) get_clocks();
if (gd->cpu_clk > 220000000)
TotalSize /= 2;
return (TotalSize * 1024 * 1024);
}
/* ------------------------------------------------------------------------- */
static int test_dram (unsigned long ramsize)
{
/* not yet implemented */
return (1);
}
int misc_init_r (void)
{
/* adjust flash start and size as well as the offset */
gd->bd->bi_flashstart=0-flash_info[0].size;
gd->bd->bi_flashsize=flash_info[0].size-CONFIG_SYS_MONITOR_LEN;
gd->bd->bi_flashoffset=0;
/* if PIP405 has booted from PCI, reset CCR0[24] as described in errata PCI_18 */
if (mfdcr(CPC0_PSR) & PSR_ROM_LOC)
mtspr(SPRN_CCR0, (mfspr(SPRN_CCR0) & ~0x80));
return (0);
}
/***************************************************************************
* some helping routines
*/
int overwrite_console (void)
{
return (in8 (CONFIG_PORT_ADDR) & 0x1); /* return TRUE if console should be overwritten */
}
extern int isa_init (void);
void print_pip405_rev (void)
{
unsigned char part, vers, cfg;
part = in8 (PLD_PART_REG);
vers = in8 (PLD_VERS_REG);
cfg = in8 (PLD_BOARD_CFG_REG);
printf ("Rev: PIP405-%d Rev %c PLD%d %d PLD%d %d\n",
16 - ((cfg >> 4) & 0xf), (cfg & 0xf) + 'A', part & 0xf,
vers & 0xf, (part >> 4) & 0xf, (vers >> 4) & 0xf);
}
extern void check_env(void);
int last_stage_init (void)
{
print_pip405_rev ();
isa_init ();
stdio_print_current_devices ();
check_env();
return 0;
}
/************************************************************************
* Print PIP405 Info
************************************************************************/
void print_pip405_info (void)
{
unsigned char part, vers, cfg, ledu, sysman, flashcom, can, serpwr,
compwr, nicvga, scsirst;
part = in8 (PLD_PART_REG);
vers = in8 (PLD_VERS_REG);
cfg = in8 (PLD_BOARD_CFG_REG);
ledu = in8 (PLD_LED_USER_REG);
sysman = in8 (PLD_SYS_MAN_REG);
flashcom = in8 (PLD_FLASH_COM_REG);
can = in8 (PLD_CAN_REG);
serpwr = in8 (PLD_SER_PWR_REG);
compwr = in8 (PLD_COM_PWR_REG);
nicvga = in8 (PLD_NIC_VGA_REG);
scsirst = in8 (PLD_SCSI_RST_REG);
printf ("PLD Part %d version %d\n",
part & 0xf, vers & 0xf);
printf ("PLD Part %d version %d\n",
(part >> 4) & 0xf, (vers >> 4) & 0xf);
printf ("Board Revision %c\n", (cfg & 0xf) + 'A');
printf ("Population Options %d %d %d %d\n",
(cfg >> 4) & 0x1, (cfg >> 5) & 0x1,
(cfg >> 6) & 0x1, (cfg >> 7) & 0x1);
printf ("User LED0 %s User LED1 %s\n",
((ledu & 0x1) == 0x1) ? "on" : "off",
((ledu & 0x2) == 0x2) ? "on" : "off");
printf ("Additionally Options %d %d\n",
(ledu >> 2) & 0x1, (ledu >> 3) & 0x1);
printf ("User Config Switch %d %d %d %d\n",
(ledu >> 4) & 0x1, (ledu >> 5) & 0x1,
(ledu >> 6) & 0x1, (ledu >> 7) & 0x1);
switch (sysman & 0x3) {
case 0:
printf ("PCI Clocks are running\n");
break;
case 1:
printf ("PCI Clocks are stopped in POS State\n");
break;
case 2:
printf ("PCI Clocks are stopped when PCI_STP# is asserted\n");
break;
case 3:
printf ("PCI Clocks are stopped\n");
break;
}
switch ((sysman >> 2) & 0x3) {
case 0:
printf ("Main Clocks are running\n");
break;
case 1:
printf ("Main Clocks are stopped in POS State\n");
break;
case 2:
case 3:
printf ("PCI Clocks are stopped\n");
break;
}
printf ("INIT asserts %sINT2# (SMI)\n",
((sysman & 0x10) == 0x10) ? "" : "not ");
printf ("INIT asserts %sINT1# (NMI)\n",
((sysman & 0x20) == 0x20) ? "" : "not ");
printf ("INIT occured %d\n", (sysman >> 6) & 0x1);
printf ("SER1 is routed to %s\n",
((flashcom & 0x1) == 0x1) ? "RS485" : "RS232");
printf ("COM2 is routed to %s\n",
((flashcom & 0x2) == 0x2) ? "RS485" : "RS232");
printf ("RS485 is configured as %s duplex\n",
((flashcom & 0x4) == 0x4) ? "full" : "half");
printf ("RS485 is connected to %s\n",
((flashcom & 0x8) == 0x8) ? "COM1" : "COM2");
printf ("SER1 uses handshakes %s\n",
((flashcom & 0x10) == 0x10) ? "DTR/DSR" : "RTS/CTS");
printf ("Bootflash is %swriteprotected\n",
((flashcom & 0x20) == 0x20) ? "not " : "");
printf ("Bootflash VPP is %s\n",
((flashcom & 0x40) == 0x40) ? "on" : "off");
printf ("Bootsector is %swriteprotected\n",
((flashcom & 0x80) == 0x80) ? "not " : "");
switch ((can) & 0x3) {
case 0:
printf ("CAN Controller is on address 0x1000..0x10FF\n");
break;
case 1:
printf ("CAN Controller is on address 0x8000..0x80FF\n");
break;
case 2:
printf ("CAN Controller is on address 0xE000..0xE0FF\n");
break;
case 3:
printf ("CAN Controller is disabled\n");
break;
}
switch ((can >> 2) & 0x3) {
case 0:
printf ("CAN Controller Reset is ISA Reset\n");
break;
case 1:
printf ("CAN Controller Reset is ISA Reset and POS State\n");
break;
case 2:
case 3:
printf ("CAN Controller is in reset\n");
break;
}
if (((can >> 4) < 3) || ((can >> 4) == 8) || ((can >> 4) == 13))
printf ("CAN Interrupt is disabled\n");
else
printf ("CAN Interrupt is ISA INT%d\n", (can >> 4) & 0xf);
switch (serpwr & 0x3) {
case 0:
printf ("SER0 Drivers are enabled\n");
break;
case 1:
printf ("SER0 Drivers are disabled in the POS state\n");
break;
case 2:
case 3:
printf ("SER0 Drivers are disabled\n");
break;
}
switch ((serpwr >> 2) & 0x3) {
case 0:
printf ("SER1 Drivers are enabled\n");
break;
case 1:
printf ("SER1 Drivers are disabled in the POS state\n");
break;
case 2:
case 3:
printf ("SER1 Drivers are disabled\n");
break;
}
switch (compwr & 0x3) {
case 0:
printf ("COM1 Drivers are enabled\n");
break;
case 1:
printf ("COM1 Drivers are disabled in the POS state\n");
break;
case 2:
case 3:
printf ("COM1 Drivers are disabled\n");
break;
}
switch ((compwr >> 2) & 0x3) {
case 0:
printf ("COM2 Drivers are enabled\n");
break;
case 1:
printf ("COM2 Drivers are disabled in the POS state\n");
break;
case 2:
case 3:
printf ("COM2 Drivers are disabled\n");
break;
}
switch ((nicvga) & 0x3) {
case 0:
printf ("PHY is running\n");
break;
case 1:
printf ("PHY is in Power save mode in POS state\n");
break;
case 2:
case 3:
printf ("PHY is in Power save mode\n");
break;
}
switch ((nicvga >> 2) & 0x3) {
case 0:
printf ("VGA is running\n");
break;
case 1:
printf ("VGA is in Power save mode in POS state\n");
break;
case 2:
case 3:
printf ("VGA is in Power save mode\n");
break;
}
printf ("PHY is %sreseted\n", ((nicvga & 0x10) == 0x10) ? "" : "not ");
printf ("VGA is %sreseted\n", ((nicvga & 0x20) == 0x20) ? "" : "not ");
printf ("Reserved Configuration is %d %d\n", (nicvga >> 6) & 0x1,
(nicvga >> 7) & 0x1);
switch ((scsirst) & 0x3) {
case 0:
printf ("SCSI Controller is running\n");
break;
case 1:
printf ("SCSI Controller is in Power save mode in POS state\n");
break;
case 2:
case 3:
printf ("SCSI Controller is in Power save mode\n");
break;
}
printf ("SCSI termination is %s\n",
((scsirst & 0x4) == 0x4) ? "disabled" : "enabled");
printf ("SCSI Controller is %sreseted\n",
((scsirst & 0x10) == 0x10) ? "" : "not ");
printf ("IDE disks are %sreseted\n",
((scsirst & 0x20) == 0x20) ? "" : "not ");
printf ("ISA Bus is %sreseted\n",
((scsirst & 0x40) == 0x40) ? "" : "not ");
printf ("Super IO is %sreseted\n",
((scsirst & 0x80) == 0x80) ? "" : "not ");
}
void user_led0 (unsigned char on)
{
if (on == TRUE)
out8 (PLD_LED_USER_REG, (in8 (PLD_LED_USER_REG) | 0x1));
else
out8 (PLD_LED_USER_REG, (in8 (PLD_LED_USER_REG) & 0xfe));
}
void user_led1 (unsigned char on)
{
if (on == TRUE)
out8 (PLD_LED_USER_REG, (in8 (PLD_LED_USER_REG) | 0x2));
else
out8 (PLD_LED_USER_REG, (in8 (PLD_LED_USER_REG) & 0xfd));
}
void ide_set_reset (int idereset)
{
/* if reset = 1 IDE reset will be asserted */
unsigned char resreg;
resreg = in8 (PLD_SCSI_RST_REG);
if (idereset == 1)
resreg |= 0x20;
else {
udelay(10000);
resreg &= 0xdf;
}
out8 (PLD_SCSI_RST_REG, resreg);
}

View file

@ -0,0 +1,148 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* 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
*
*/
/****************************************************************************
* Global routines used for PIP405
*****************************************************************************/
#ifndef __ASSEMBLY__
extern int mem_test(unsigned long start, unsigned long ramsize,int mode);
void print_pip405_info(void);
void user_led0(unsigned char on);
void user_led1(unsigned char on);
#define PLD_BASE_ADDRESS CONFIG_SYS_ISA_IO_BASE_ADDRESS + 0x800
#define PLD_PART_REG PLD_BASE_ADDRESS + 0
#define PLD_VERS_REG PLD_BASE_ADDRESS + 1
#define PLD_BOARD_CFG_REG PLD_BASE_ADDRESS + 2
#define PLD_LED_USER_REG PLD_BASE_ADDRESS + 3
#define PLD_SYS_MAN_REG PLD_BASE_ADDRESS + 4
#define PLD_FLASH_COM_REG PLD_BASE_ADDRESS + 5
#define PLD_CAN_REG PLD_BASE_ADDRESS + 6
#define PLD_SER_PWR_REG PLD_BASE_ADDRESS + 7
#define PLD_COM_PWR_REG PLD_BASE_ADDRESS + 8
#define PLD_NIC_VGA_REG PLD_BASE_ADDRESS + 9
#define PLD_SCSI_RST_REG PLD_BASE_ADDRESS + 0xA
#define PIIX4_VENDOR_ID 0x8086
#define PIIX4_IDE_DEV_ID 0x7111
#endif
/* timings */
/* CS Config register (CS7) */
#define CONFIG_PORT_BME 0 /* Burst disable */
#define CONFIG_PORT_TWE 255 /* 255 * 30ns 120ns Waitstates (access=TWT+1+TH) */
#define CONFIG_PORT_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
#define CONFIG_PORT_OEN 1 /* Cycles from CS low to OE low */
#define CONFIG_PORT_WBN 1 /* Cycles from CS low to WE low */
#define CONFIG_PORT_WBF 1 /* Cycles from WE high to CS high */
#define CONFIG_PORT_TH 2 /* Number of hold cycles after transfer */
#define CONFIG_PORT_RE 0 /* Ready disabled */
#define CONFIG_PORT_SOR 1 /* Sample on Ready disabled */
#define CONFIG_PORT_BEM 0 /* Byte Write only active on Write cycles */
#define CONFIG_PORT_PEN 0 /* Parity disable */
#define CONFIG_PORT_AP ((CONFIG_PORT_BME << 31) + (CONFIG_PORT_TWE << 23) + (CONFIG_PORT_CSN << 18) + (CONFIG_PORT_OEN << 16) + (CONFIG_PORT_WBN << 14) + \
(CONFIG_PORT_WBF << 12) + (CONFIG_PORT_TH << 9) + (CONFIG_PORT_RE << 8) + (CONFIG_PORT_SOR << 7) + (CONFIG_PORT_BEM << 6) + (CONFIG_PORT_PEN << 5))
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
#define CONFIG_PORT_BS 0 /* 1 MByte */
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
#define CONFIG_PORT_BU 3 /* R/W */
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
#define CONFIG_PORT_BW 0 /* 16Bit */
#define CONFIG_PORT_CR ((CONFIG_PORT_ADDR & 0xfff00000) + (CONFIG_PORT_BS << 17) + (CONFIG_PORT_BU << 15) + (CONFIG_PORT_BW << 13))
/* Flash CS0 or CS 1 */
/* 0x7F8FFE80 slowest timing at all... */
#define FLASH_BME_B 1 /* Burst enable */
#define FLASH_FWT_B 0x6 /* 6 * 30ns 210ns First Wait Access */
#define FLASH_BWT_B 0x6 /* 6 * 30ns 210ns Burst Wait Access */
#define FLASH_BME 0 /* Burst disable */
#define FLASH_TWE 0xb/* 11 * 30ns 330ns Waitstates (access=TWT+1+TH) */
#define FLASH_CSN 0 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
#define FLASH_OEN 1 /* Cycles from CS low to OE low */
#define FLASH_WBN 1 /* Cycles from CS low to WE low */
#define FLASH_WBF 1 /* Cycles from WE high to CS high */
#define FLASH_TH 2 /* Number of hold cycles after transfer */
#define FLASH_RE 0 /* Ready disabled */
#define FLASH_SOR 1 /* Sample on Ready disabled */
#define FLASH_BEM 0 /* Byte Write only active on Write cycles */
#define FLASH_PEN 0 /* Parity disable */
/* Access Parameter Register for non Boot */
#define FLASH_AP ((FLASH_BME << 31) + (FLASH_TWE << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \
(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
/* Access Parameter Register for Boot */
#define FLASH_AP_B ((FLASH_BME_B << 31) + (FLASH_FWT_B << 26) + (FLASH_BWT_B << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \
(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
#define FLASH_BS FLASH_SIZE_PRELIM /* 4 MByte */
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
#define FLASH_BU 3 /* R/W */
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
#define FLASH_BW 1 /* 16Bit */
/* CR register for Boot */
#define FLASH_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
/* CR register for non Boot */
#define FLASH_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
/* MPS CS1 or CS0 */
/* Boot CS: */
#define MPS_BME_B 1 /* Burst enable */
#define MPS_FWT_B 0x6/* 6 * 30ns 210ns First Wait Access */
#define MPS_BWT_B 0x6 /* 6 * 30ns 210ns Burst Wait Access */
#define MPS_BME 0 /* Burst disable */
#define MPS_TWE 0xb/* 11 * 30ns 330ns Waitstates (access=TWT+1+TH) */
#define MPS_CSN 0 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
#define MPS_OEN 1 /* Cycles from CS low to OE low */
#define MPS_WBN 1 /* Cycles from CS low to WE low */
#define MPS_WBF 1 /* Cycles from WE high to CS high */
#define MPS_TH 2 /* Number of hold cycles after transfer */
#define MPS_RE 0 /* Ready disabled */
#define MPS_SOR 1 /* Sample on Ready disabled */
#define MPS_BEM 0 /* Byte Write only active on Write cycles */
#define MPS_PEN 0 /* Parity disable */
/* Access Parameter Register for non Boot */
#define MPS_AP ((MPS_BME << 31) + (MPS_TWE << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
(MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
/* Access Parameter Register for Boot */
#define MPS_AP_B ((MPS_BME_B << 31) + (MPS_FWT_B << 26) + (MPS_BWT_B << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
(MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
#define MPS_BS 2 /* 4 MByte */
#define MPS_BS_B FLASH_SIZE_PRELIM /* 1 MByte */
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
#define MPS_BU 3 /* R/W */
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
#define MPS_BW 0 /* 8Bit */
/* CR register for Boot */
#define MPS_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
/* CR register for non Boot */
#define MPS_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))

View file

@ -0,0 +1,135 @@
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
OUTPUT_ARCH(powerpc)
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
.rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
.rela.data : { *(.rela.data) }
.rel.rodata : { *(.rel.rodata) }
.rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init : { *(.init) }
.plt : { *(.plt) }
.text :
{
/* WARNING - the following is hand-optimized to fit within */
/* the sector layout of our flash chips! XXX FIXME XXX */
mpc8xx/start.o (.text)
common/dlmalloc.o (.text)
lib/vsprintf.o (.text)
lib/crc32.o (.text)
arch/powerpc/lib/extable.o (.text)
common/env_embedded.o(.text)
*(.text)
*(.got1)
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(.rodata)
*(.rodata1)
*(.rodata.str1.4)
*(.eh_frame)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x0FFF) & 0xFFFFF000;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
*(.got)
_GOT2_TABLE_ = .;
*(.got2)
_FIXUP_TABLE_ = .;
*(.fixup)
}
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.dynamic)
CONSTRUCTORS
}
_edata = .;
PROVIDE (edata = .);
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
. = ALIGN(4096);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(4096);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
__bss_end__ = . ;
PROVIDE (end = .);
}

View file

@ -0,0 +1,50 @@
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
ifneq ($(OBJTREE),$(SRCTREE))
$(shell mkdir -p $(obj)../common)
endif
LIB = $(obj)lib$(BOARD).o
COBJS := ../common/common_util.o
COBJS += $(BOARD).o cmd_$(BOARD).o
SOBJS := lowlevel_init.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
SOBJS := $(addprefix $(obj),$(SOBJS))
$(LIB): $(obj).depend $(OBJS) $(SOBJS)
$(call cmd_link_o_target, $(OBJS) $(SOBJS))
#########################################################################
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################

View file

@ -0,0 +1,136 @@
/*
* (C) Copyright 2002
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* adapted for VCMA9
* David Mueller, ELSOFT AG, d.mueller@elsoft.ch
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#include <common.h>
#include <command.h>
#include <net.h>
#include "vcma9.h"
#include "../common/common_util.h"
#if defined(CONFIG_CS8900)
#include <../drivers/net/cs8900.h>
static uchar cs8900_chksum(ushort data)
{
return((data >> 8) & 0x00FF) + (data & 0x00FF);
}
#endif
DECLARE_GLOBAL_DATA_PTR;
/* ------------------------------------------------------------------------- */
int do_vcma9(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
struct eth_device *dev;
char cs8900_name[10];
if (strcmp(argv[1], "info") == 0)
{
vcma9_print_info();
return 0;
}
#if defined(CONFIG_CS8900)
if (strcmp(argv[1], "cs8900") == 0) {
sprintf(cs8900_name, "%s-0", CS8900_DRIVERNAME);
dev = eth_get_dev_by_name(cs8900_name);
if (!dev) {
printf("Couldn't find CS8900 driver");
return 0;
}
if (strcmp(argv[2], "read") == 0) {
uchar addr; ushort data;
addr = simple_strtoul(argv[3], NULL, 16);
cs8900_e2prom_read(dev, addr, &data);
printf("0x%2.2X: 0x%4.4X\n", addr, data);
} else if (strcmp(argv[2], "write") == 0) {
uchar addr; ushort data;
addr = simple_strtoul(argv[3], NULL, 16);
data = simple_strtoul(argv[4], NULL, 16);
cs8900_e2prom_write(dev, addr, data);
} else if (strcmp(argv[2], "setaddr") == 0) {
uchar addr, i, csum; ushort data;
uchar ethaddr[6];
/* check for valid ethaddr */
if (eth_getenv_enetaddr("ethaddr", ethaddr)) {
addr = 1;
data = 0x2158;
cs8900_e2prom_write(dev, addr, data);
csum = cs8900_chksum(data);
addr++;
for (i = 0; i < 6; i+=2) {
data = ethaddr[i+1] << 8 |
ethaddr[i];
cs8900_e2prom_write(dev, addr, data);
csum += cs8900_chksum(data);
addr++;
}
/* calculate header link byte */
data = 0xA100 | (addr * 2);
cs8900_e2prom_write(dev, 0, data);
csum += cs8900_chksum(data);
/* write checksum word */
cs8900_e2prom_write(dev, addr, (0 - csum) << 8);
} else {
puts("\nplease defined 'ethaddr'\n");
}
} else if (strcmp(argv[2], "dump") == 0) {
uchar addr = 0, endaddr, csum; ushort data;
puts("Dump of CS8900 config device: ");
cs8900_e2prom_read(dev, addr, &data);
if ((data & 0xE000) == 0xA000) {
endaddr = (data & 0x00FF) / 2;
csum = cs8900_chksum(data);
for (addr = 1; addr <= endaddr; addr++) {
cs8900_e2prom_read(dev, addr, &data);
printf("\n0x%2.2X: 0x%4.4X", addr, data);
csum += cs8900_chksum(data);
}
printf("\nChecksum: %s", (csum == 0) ? "ok" : "wrong");
} else {
puts("no valid config found");
}
puts("\n");
}
return 0;
}
#endif
return (do_mplcommon(cmdtp, flag, argc, argv));
}
U_BOOT_CMD(
vcma9, 6, 1, do_vcma9,
"VCMA9 specific commands",
"flash mem [SrcAddr] - updates U-Boot with image in memory\n"
"vcma9 info - displays board information"
);

View file

@ -0,0 +1,521 @@
/*
* 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 MPL VCMA9 by
* David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
* (C) Copyright 2002, 2003, 2004, 2005
*
* 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>
/* register definitions */
#define PLD_BASE 0x28000000
#define MISC_REG 0x103
#define SDRAM_REG 0x106
#define BWSCON 0x48000000
#define CLKBASE 0x4C000000
#define LOCKTIME 0x0
#define MPLLCON 0x4
#define UPLLCON 0x8
#define GPIOBASE 0x56000000
#define GSTATUS1 0xB0
#define FASTCPU 0x02
/* some parameters for the board */
/* BWSCON */
#define DW8 (0x0)
#define DW16 (0x1)
#define DW32 (0x2)
#define WAIT (0x1<<2)
#define UBLB (0x1<<3)
/* BANKSIZE */
#define BURST_EN (0x1<<7)
/* BANK0CON 200 */
#define B0_Tacs_200 0x0 /* 0clk (or 0x1 1clk) */
#define B0_Tcos_200 0x1 /* 1clk (or 0x2 2clk) */
#define B0_Tacc_200 0x5 /* 8clk (or 0x6 10clk) */
#define B0_Tcoh_200 0x0 /* 0clk */
#define B0_Tcah_200 0x3 /* 4clk (or0x01 1clk) */
#define B0_Tacp_200 0x0 /* page mode is not used */
#define B0_PMC_200 0x0 /* page mode disabled */
/* BANK0CON 250 */
#define B0_Tacs_250 0x0 /* 0clk (or 0x1 1clk) */
#define B0_Tcos_250 0x1 /* 1clk (or 0x2 2clk) */
#define B0_Tacc_250 0x5 /* 8clk (or 0x7 14clk) */
#define B0_Tcoh_250 0x0 /* 0clk */
#define B0_Tcah_250 0x3 /* 4clk (or 0x1 1clk) */
#define B0_Tacp_250 0x0 /* page mode is not used */
#define B0_PMC_250 0x0 /* page mode disabled */
/* BANK0CON 266 */
#define B0_Tacs_266 0x0 /* 0clk (or 0x1 1clk) */
#define B0_Tcos_266 0x1 /* 1clk (or 0x2 2clk) */
#define B0_Tacc_266 0x6 /* 10clk (or 0x7 14clk) */
#define B0_Tcoh_266 0x0 /* 0clk */
#define B0_Tcah_266 0x3 /* 4clk (or 0x1 1clk) */
#define B0_Tacp_266 0x0 /* page mode is not used */
#define B0_PMC_266 0x0 /* page mode disabled */
/* BANK1CON 200 */
#define B1_Tacs_200 0x0 /* 0clk (or 0x1 1clk) */
#define B1_Tcos_200 0x1 /* 1clk (or 0x2 2clk) */
#define B1_Tacc_200 0x5 /* 8clk (or 0x6 10clk) */
#define B1_Tcoh_200 0x0 /* 0clk */
#define B1_Tcah_200 0x3 /* 4clk (or 0x1 1clk) */
#define B1_Tacp_200 0x0 /* page mode is not used */
#define B1_PMC_200 0x0 /* page mode disabled */
/* BANK1CON 250 */
#define B1_Tacs_250 0x0 /* 0clk (or 0x1 1clk) */
#define B1_Tcos_250 0x1 /* 1clk (or 0x2 2clk) */
#define B1_Tacc_250 0x5 /* 8clk (or 0x7 14clk) */
#define B1_Tcoh_250 0x0 /* 0clk */
#define B1_Tcah_250 0x3 /* 4clk (or 0x1 1clk) */
#define B1_Tacp_250 0x0 /* page mode is not used */
#define B1_PMC_250 0x0 /* page mode disabled */
/* BANK1CON 266 */
#define B1_Tacs_266 0x0 /* 0clk (or 0x1 1clk) */
#define B1_Tcos_266 0x1 /* 1clk (or 0x2 2clk) */
#define B1_Tacc_266 0x6 /* 10clk (or 0x7 14clk) */
#define B1_Tcoh_266 0x0 /* 0clk */
#define B1_Tcah_266 0x3 /* 4clk (or 0x1 1clk) */
#define B1_Tacp_266 0x0 /* page mode is not used */
#define B1_PMC_266 0x0 /* page mode disabled */
/* BANK2CON 200 + 250 + 266 */
#define B2_Tacs 0x3 /* 4clk */
#define B2_Tcos 0x3 /* 4clk */
#define B2_Tacc 0x7 /* 14clk */
#define B2_Tcoh 0x3 /* 4clk */
#define B2_Tcah 0x3 /* 4clk */
#define B2_Tacp 0x0 /* page mode is not used */
#define B2_PMC 0x0 /* page mode disabled */
/* BANK3CON 200 + 250 + 266 */
#define B3_Tacs 0x3 /* 4clk */
#define B3_Tcos 0x3 /* 4clk */
#define B3_Tacc 0x7 /* 14clk */
#define B3_Tcoh 0x3 /* 4clk */
#define B3_Tcah 0x3 /* 4clk */
#define B3_Tacp 0x0 /* page mode is not used */
#define B3_PMC 0x0 /* page mode disabled */
/* BANK4CON 200 */
#define B4_Tacs_200 0x1 /* 1clk */
#define B4_Tcos_200 0x3 /* 4clk */
#define B4_Tacc_200 0x7 /* 14clk */
#define B4_Tcoh_200 0x3 /* 4clk */
#define B4_Tcah_200 0x2 /* 2clk */
#define B4_Tacp_200 0x0 /* page mode is not used */
#define B4_PMC_200 0x0 /* page mode disabled */
/* BANK4CON 250 */
#define B4_Tacs_250 0x1 /* 1clk */
#define B4_Tcos_250 0x3 /* 4clk */
#define B4_Tacc_250 0x7 /* 14clk */
#define B4_Tcoh_250 0x3 /* 4clk */
#define B4_Tcah_250 0x2 /* 2clk */
#define B4_Tacp_250 0x0 /* page mode is not used */
#define B4_PMC_250 0x0 /* page mode disabled */
/* BANK4CON 266 */
#define B4_Tacs_266 0x1 /* 1clk */
#define B4_Tcos_266 0x3 /* 4clk */
#define B4_Tacc_266 0x7 /* 14clk */
#define B4_Tcoh_266 0x3 /* 4clk */
#define B4_Tcah_266 0x2 /* 2clk */
#define B4_Tacp_266 0x0 /* page mode is not used */
#define B4_PMC_266 0x0 /* page mode disabled */
/* BANK5CON 200 */
#define B5_Tacs_200 0x0 /* 0clk */
#define B5_Tcos_200 0x3 /* 4clk */
#define B5_Tacc_200 0x4 /* 6clk */
#define B5_Tcoh_200 0x3 /* 4clk */
#define B5_Tcah_200 0x1 /* 1clk */
#define B5_Tacp_200 0x0 /* page mode is not used */
#define B5_PMC_200 0x0 /* page mode disabled */
/* BANK5CON 250 */
#define B5_Tacs_250 0x0 /* 0clk */
#define B5_Tcos_250 0x3 /* 4clk */
#define B5_Tacc_250 0x5 /* 8clk */
#define B5_Tcoh_250 0x3 /* 4clk */
#define B5_Tcah_250 0x1 /* 1clk */
#define B5_Tacp_250 0x0 /* page mode is not used */
#define B5_PMC_250 0x0 /* page mode disabled */
/* BANK5CON 266 */
#define B5_Tacs_266 0x0 /* 0clk */
#define B5_Tcos_266 0x3 /* 4clk */
#define B5_Tacc_266 0x5 /* 8clk */
#define B5_Tcoh_266 0x3 /* 4clk */
#define B5_Tcah_266 0x1 /* 1clk */
#define B5_Tacp_266 0x0 /* page mode is not used */
#define B5_PMC_266 0x0 /* page mode disabled */
#define B6_MT 0x3 /* SDRAM */
#define B6_Trcd_200 0x0 /* 2clk */
#define B6_Trcd_250 0x1 /* 3clk */
#define B6_Trcd_266 0x1 /* 3clk */
#define B6_SCAN 0x2 /* 10bit */
#define B7_MT 0x3 /* SDRAM */
#define B7_Trcd_200 0x0 /* 2clk */
#define B7_Trcd_250 0x1 /* 3clk */
#define B7_Trcd_266 0x1 /* 3clk */
#define B7_SCAN 0x2 /* 10bit */
/* REFRESH parameter */
#define REFEN 0x1 /* Refresh enable */
#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */
#define Trp_200 0x0 /* 2clk */
#define Trp_250 0x1 /* 3clk */
#define Trp_266 0x1 /* 3clk */
#define Tsrc_200 0x1 /* 5clk */
#define Tsrc_250 0x2 /* 6clk */
#define Tsrc_266 0x3 /* 7clk */
/* period=15.6us, HCLK=100Mhz, (2048+1-15.6*100) */
#define REFCNT_200 489
/* period=15.6us, HCLK=125Mhz, (2048+1-15.6*125) */
#define REFCNT_250 99
/* period=15.6us, HCLK=133Mhz, (2048+1-15.6*133) */
#define REFCNT_266 0
/**************************************/
_TEXT_BASE:
.word CONFIG_SYS_TEXT_BASE
.globl lowlevel_init
lowlevel_init:
/* use r0 to relocate DATA read/write to flash rather than memory ! */
ldr r0, _TEXT_BASE
ldr r13, =BWSCON
/* enable minimal access to PLD */
ldr r1, [r13] /* load default BWSCON */
orr r1, r1, #(DW8 + UBLB) << 20 /* set necessary CS attrs */
str r1, [r13] /* set BWSCON */
ldr r1, =0x7FF0 /* select slowest timing */
str r1, [r13, #0x18] /* set BANKCON5 */
ldr r1, =PLD_BASE
ldr r2, =SETUPDATA
ldrb r1, [r1, #MISC_REG]
sub r2, r2, r0
tst r1, #FASTCPU /* FASTCPU available ? */
addeq r2, r2, #SETUPENTRY_SIZE
/* memory control configuration */
/* r2 = pointer into timing table */
/* r13 = pointer to MEM controller regs (starting with BWSCON) */
add r3, r2, #CSDATA_OFFSET
add r4, r3, #CSDATAENTRY_SIZE
0:
ldr r1, [r3], #4
str r1, [r13], #4
cmp r3, r4
bne 0b
/* PLD access is now possible */
/* r3 = SDRAMDATA
/* r13 = pointer to MEM controller regs */
ldr r1, =PLD_BASE
mov r4, #SDRAMENTRY_SIZE
ldrb r1, [r1, #SDRAM_REG]
/* calculate start and end point */
mla r3, r4, r1, r3
add r4, r3, r4
0:
ldr r1, [r3], #4
str r1, [r13], #4
cmp r3, r4
bne 0b
/* setup MPLL registers */
ldr r1, =CLKBASE
ldr r4, =0xFFFFFF
add r3, r2, #4 /* r3 points to PLL values */
str r4, [r1, #LOCKTIME]
ldmia r3, {r4,r5}
str r5, [r1, #UPLLCON] /* writing PLL register */
/* !! order seems to be important !! */
/* a little delay */
ldr r3, =0x4000
0:
subs r3, r3, #1
bne 0b
str r4, [r1, #MPLLCON] /* writing PLL register */
/* !! order seems to be important !! */
/* a little delay */
ldr r3, =0x4000
0:
subs r3, r3, #1
bne 0b
/* everything is fine now */
mov pc, lr
.ltorg
/* the literal pools origin */
#define MK_BWSCON(bws1, bws2, bws3, bws4, bws5, bws6, bws7) \
((bws1) << 4) + \
((bws2) << 8) + \
((bws3) << 12) + \
((bws4) << 16) + \
((bws5) << 20) + \
((bws6) << 24) + \
((bws7) << 28)
#define MK_BANKCON(tacs, tcos, tacc, tcoh, tcah, tacp, pmc) \
((tacs) << 13) + \
((tcos) << 11) + \
((tacc) << 8) + \
((tcoh) << 6) + \
((tcah) << 4) + \
((tacp) << 2) + \
(pmc)
#define MK_BANKCON_SDRAM(trcd, scan) \
((0x03) << 15) + \
((trcd) << 2) + \
(scan)
#define MK_SDRAM_REFRESH(enable, trefmd, trp, tsrc, cnt) \
((enable) << 23) + \
((trefmd) << 22) + \
((trp) << 20) + \
((tsrc) << 18) + \
(cnt)
SETUPDATA:
.word 0x32410002
/* PLL values (MDIV, PDIV, SDIV) for 250 MHz */
.word (0x75 << 12) + (0x01 << 4) + (0x01 << 0)
/* PLL values for USB clock */
.word (0x48 << 12) + (0x03 << 4) + (0x02 << 0)
/* timing for 250 MHz*/
0:
.equiv CSDATA_OFFSET, (. - SETUPDATA)
.word MK_BWSCON(DW16, \
DW32, \
DW32, \
DW16 + WAIT + UBLB, \
DW8 + UBLB, \
DW32, \
DW32)
.word MK_BANKCON(B0_Tacs_250, \
B0_Tcos_250, \
B0_Tacc_250, \
B0_Tcoh_250, \
B0_Tcah_250, \
B0_Tacp_250, \
B0_PMC_250)
.word MK_BANKCON(B1_Tacs_250, \
B1_Tcos_250, \
B1_Tacc_250, \
B1_Tcoh_250, \
B1_Tcah_250, \
B1_Tacp_250, \
B1_PMC_250)
.word MK_BANKCON(B2_Tacs, \
B2_Tcos, \
B2_Tacc, \
B2_Tcoh, \
B2_Tcah, \
B2_Tacp, \
B2_PMC)
.word MK_BANKCON(B3_Tacs, \
B3_Tcos, \
B3_Tacc, \
B3_Tcoh, \
B3_Tcah, \
B3_Tacp, \
B3_PMC)
.word MK_BANKCON(B4_Tacs_250, \
B4_Tcos_250, \
B4_Tacc_250, \
B4_Tcoh_250, \
B4_Tcah_250, \
B4_Tacp_250, \
B4_PMC_250)
.word MK_BANKCON(B5_Tacs_250, \
B5_Tcos_250, \
B5_Tacc_250, \
B5_Tcoh_250, \
B5_Tcah_250, \
B5_Tacp_250, \
B5_PMC_250)
.equiv CSDATAENTRY_SIZE, (. - 0b)
/* 4Mx8x4 */
0:
.word MK_BANKCON_SDRAM(B6_Trcd_250, B6_SCAN)
.word MK_BANKCON_SDRAM(B7_Trcd_250, B7_SCAN)
.word MK_SDRAM_REFRESH(REFEN, TREFMD, Trp_250, Tsrc_250, REFCNT_250)
.word 0x32 + BURST_EN
.word 0x30
.word 0x30
.equiv SDRAMENTRY_SIZE, (. - 0b)
/* 8Mx8x4 */
.word MK_BANKCON_SDRAM(B6_Trcd_250, B6_SCAN)
.word MK_BANKCON_SDRAM(B7_Trcd_250, B7_SCAN)
.word MK_SDRAM_REFRESH(REFEN, TREFMD, Trp_250, Tsrc_250, REFCNT_250)
.word 0x32 + BURST_EN
.word 0x30
.word 0x30
/* 2Mx8x4 */
.word MK_BANKCON_SDRAM(B6_Trcd_250, B6_SCAN)
.word MK_BANKCON_SDRAM(B7_Trcd_250, B7_SCAN)
.word MK_SDRAM_REFRESH(REFEN, TREFMD, Trp_250, Tsrc_250, REFCNT_250)
.word 0x32 + BURST_EN
.word 0x30
.word 0x30
/* 4Mx8x2 */
.word MK_BANKCON_SDRAM(B6_Trcd_250, B6_SCAN)
.word MK_BANKCON_SDRAM(B7_Trcd_250, B7_SCAN)
.word MK_SDRAM_REFRESH(REFEN, TREFMD, Trp_250, Tsrc_250, REFCNT_250)
.word 0x32 + BURST_EN
.word 0x30
.word 0x30
.equiv SETUPENTRY_SIZE, (. - SETUPDATA)
.word 0x32410000
/* PLL values (MDIV, PDIV, SDIV) for 200 MHz (Fout = 202.8MHz) */
.word (0xA1 << 12) + (0x03 << 4) + (0x01 << 0)
/* PLL values for USB clock */
.word (0x48 << 12) + (0x03 << 4) + (0x02 << 0)
/* timing for 200 MHz and default*/
.word MK_BWSCON(DW16, \
DW32, \
DW32, \
DW16 + WAIT + UBLB, \
DW8 + UBLB, \
DW32, \
DW32)
.word MK_BANKCON(B0_Tacs_200, \
B0_Tcos_200, \
B0_Tacc_200, \
B0_Tcoh_200, \
B0_Tcah_200, \
B0_Tacp_200, \
B0_PMC_200)
.word MK_BANKCON(B1_Tacs_200, \
B1_Tcos_200, \
B1_Tacc_200, \
B1_Tcoh_200, \
B1_Tcah_200, \
B1_Tacp_200, \
B1_PMC_200)
.word MK_BANKCON(B2_Tacs, \
B2_Tcos, \
B2_Tacc, \
B2_Tcoh, \
B2_Tcah, \
B2_Tacp, \
B2_PMC)
.word MK_BANKCON(B3_Tacs, \
B3_Tcos, \
B3_Tacc, \
B3_Tcoh, \
B3_Tcah, \
B3_Tacp, \
B3_PMC)
.word MK_BANKCON(B4_Tacs_200, \
B4_Tcos_200, \
B4_Tacc_200, \
B4_Tcoh_200, \
B4_Tcah_200, \
B4_Tacp_200, \
B4_PMC_200)
.word MK_BANKCON(B5_Tacs_200, \
B5_Tcos_200, \
B5_Tacc_200, \
B5_Tcoh_200, \
B5_Tcah_200, \
B5_Tacp_200, \
B5_PMC_200)
/* 4Mx8x4 */
.word MK_BANKCON_SDRAM(B6_Trcd_200, B6_SCAN)
.word MK_BANKCON_SDRAM(B7_Trcd_200, B7_SCAN)
.word MK_SDRAM_REFRESH(REFEN, TREFMD, Trp_200, Tsrc_200, REFCNT_200)
.word 0x32 + BURST_EN
.word 0x30
.word 0x30
/* 8Mx8x4 */
.word MK_BANKCON_SDRAM(B6_Trcd_200, B6_SCAN)
.word MK_BANKCON_SDRAM(B7_Trcd_200, B7_SCAN)
.word MK_SDRAM_REFRESH(REFEN, TREFMD, Trp_200, Tsrc_200, REFCNT_200)
.word 0x32 + BURST_EN
.word 0x30
.word 0x30
/* 2Mx8x4 */
.word MK_BANKCON_SDRAM(B6_Trcd_200, B6_SCAN)
.word MK_BANKCON_SDRAM(B7_Trcd_200, B7_SCAN)
.word MK_SDRAM_REFRESH(REFEN, TREFMD, Trp_200, Tsrc_200, REFCNT_200)
.word 0x32 + BURST_EN
.word 0x30
.word 0x30
/* 4Mx8x2 */
.word MK_BANKCON_SDRAM(B6_Trcd_200, B6_SCAN)
.word MK_BANKCON_SDRAM(B7_Trcd_200, B7_SCAN)
.word MK_SDRAM_REFRESH(REFEN, TREFMD, Trp_200, Tsrc_200, REFCNT_200)
.word 0x32 + BURST_EN
.word 0x30
.word 0x30
.equiv SETUPDATA_SIZE, (. - SETUPDATA)

View file

@ -0,0 +1,225 @@
/*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright 2002, 2010
* David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
*
* 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 <netdev.h>
#include <i2c.h>
#include <asm/io.h>
#include <asm/arch/s3c24x0_cpu.h>
#include "vcma9.h"
#include "../common/common_util.h"
DECLARE_GLOBAL_DATA_PTR;
/*
* Miscellaneous platform dependent initialisations
*/
int board_early_init_f(void)
{
struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
/* set up the I/O ports */
writel(0x007FFFFF, &gpio->gpacon);
writel(0x002AAAAA, &gpio->gpbcon);
writel(0x000002BF, &gpio->gpbup);
writel(0xAAAAAAAA, &gpio->gpccon);
writel(0x0000FFFF, &gpio->gpcup);
writel(0xAAAAAAAA, &gpio->gpdcon);
writel(0x0000FFFF, &gpio->gpdup);
writel(0xAAAAAAAA, &gpio->gpecon);
writel(0x000037F7, &gpio->gpeup);
writel(0x00000000, &gpio->gpfcon);
writel(0x00000000, &gpio->gpfup);
writel(0xFFEAFF5A, &gpio->gpgcon);
writel(0x0000F0DC, &gpio->gpgup);
writel(0x0028AAAA, &gpio->gphcon);
writel(0x00000656, &gpio->gphup);
/* setup correct IRQ modes for NIC (rising edge mode) */
writel((readl(&gpio->extint2) & ~(7<<8)) | (4<<8), &gpio->extint2);
/* select USB port 2 to be host or device (setup as host for now) */
writel(readl(&gpio->misccr) | 0x08, &gpio->misccr);
return 0;
}
int board_init(void)
{
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x30000100;
icache_enable();
dcache_enable();
return 0;
}
/*
* Get some Board/PLD Info
*/
static u8 get_pld_reg(enum vcma9_pld_regs reg)
{
return readb(VCMA9_PLD_BASE + reg);
}
static u8 get_pld_version(void)
{
return (get_pld_reg(VCMA9_PLD_ID) >> 4) & 0x0F;
}
static u8 get_pld_revision(void)
{
return get_pld_reg(VCMA9_PLD_ID) & 0x0F;
}
static uchar get_board_pcb(void)
{
return ((get_pld_reg(VCMA9_PLD_BOARD) >> 4) & 0x03) + 'A';
}
static u8 get_nr_chips(void)
{
switch ((get_pld_reg(VCMA9_PLD_SDRAM) >> 4) & 0x0F) {
case 0: return 4;
case 1: return 1;
case 2: return 2;
default: return 0;
}
}
static ulong get_chip_size(void)
{
switch (get_pld_reg(VCMA9_PLD_SDRAM) & 0x0F) {
case 0: return 16 * (1024*1024);
case 1: return 32 * (1024*1024);
case 2: return 8 * (1024*1024);
case 3: return 8 * (1024*1024);
default: return 0;
}
}
static const char *get_chip_geom(void)
{
switch (get_pld_reg(VCMA9_PLD_SDRAM) & 0x0F) {
case 0: return "4Mx8x4";
case 1: return "8Mx8x4";
case 2: return "2Mx8x4";
case 3: return "4Mx8x2";
default: return "unknown";
}
}
static void vcma9_show_info(char *board_name, char *serial)
{
printf("Board: %s SN: %s PCB Rev: %c PLD(%d,%d)\n",
board_name, serial,
get_board_pcb(), get_pld_version(), get_pld_revision());
printf("SDRAM: %d chips %s\n", get_nr_chips(), get_chip_geom());
}
int dram_init(void)
{
/* dram_init must store complete ramsize in gd->ram_size */
gd->ram_size = get_chip_size() * get_nr_chips();
return 0;
}
/*
* Check Board Identity:
*/
int checkboard(void)
{
char s[50];
int i;
backup_t *b = (backup_t *) s;
i = getenv_f("serial#", s, 32);
if ((i < 0) || strncmp (s, "VCMA9", 5)) {
get_backup_values (b);
if (strncmp (b->signature, "MPL\0", 4) != 0) {
puts ("### No HW ID - assuming VCMA9");
} else {
b->serial_name[5] = 0;
vcma9_show_info(b->serial_name, &b->serial_name[6]);
}
} else {
s[5] = 0;
vcma9_show_info(s, &s[6]);
}
return 0;
}
int board_late_init(void)
{
/*
* check if environment is healthy, otherwise restore values
* from shadow copy
*/
check_env();
return 0;
}
void vcma9_print_info(void)
{
char *s = getenv("serial#");
if (!s) {
puts ("### No HW ID - assuming VCMA9");
} else {
s[5] = 0;
vcma9_show_info(s, &s[6]);
}
}
#ifdef CONFIG_CMD_NET
int board_eth_init(bd_t *bis)
{
int rc = 0;
#ifdef CONFIG_CS8900
rc = cs8900_initialize(0, CONFIG_CS8900_BASE);
#endif
return rc;
}
#endif
/*
* Hardcoded flash setup:
* Flash 0 is a non-CFI AMD AM29F400BB flash.
*/
ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
{
info->portwidth = FLASH_CFI_16BIT;
info->chipwidth = FLASH_CFI_BY16;
info->interface = FLASH_CFI_X16;
return 1;
}

View file

@ -0,0 +1,45 @@
/*
* (C) Copyright 2002, 2003
* David Mueller, ELSOFT AG, d.mueller@elsoft.ch
*
* 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
*
*/
/****************************************************************************
* Global routines used for VCMA9
*****************************************************************************/
#include <asm/arch/s3c24x0_cpu.h>
extern void vcma9_print_info(void);
extern int do_mplcommon(cmd_tbl_t *cmdtp, int flag,
int argc, char *const argv[]);
/* VCMA9 PLD registers */
enum vcma9_pld_regs {
VCMA9_PLD_ID,
VCMA9_PLD_NIC,
VCMA9_PLD_CAN,
VCMA9_PLD_MISC,
VCMA9_PLD_GPCD,
VCMA9_PLD_BOARD,
VCMA9_PLD_SDRAM
};
#define VCMA9_PLD_BASE (0x2C000100)