avionic design with actual uboot and tooling

submodule of avionic design uboot bootloader and with included tools to
get you started , read readme.md and readme-tk1-loader.md
This commit is contained in:
2026-03-03 21:46:32 +02:00
parent fe3ba02c96
commit 68d74d3181
11967 changed files with 2221897 additions and 0 deletions

View File

@@ -0,0 +1,757 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* SPDX-License-Identifier: GPL-2.0+
*/
#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)) {
strcpy(buf,"### No HW ID - assuming PIP405");
}
#endif
#ifdef CONFIG_MIP405
if (!s || strncmp (s, "MIP405", 6)) {
strcpy(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;
}
strcpy(&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:
strcpy(buf, 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,32 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* SPDX-License-Identifier: GPL-2.0+
*/
#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,470 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland
*
* SPDX-License-Identifier: GPL-2.0+
*
* 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
#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,41 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* SPDX-License-Identifier: GPL-2.0+
*/
#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,625 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* SPDX-License-Identifier: GPL-2.0+
*
* Source partly derived from:
* linux/drivers/char/pc_keyb.c
*/
#include <common.h>
#include <console.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;
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(struct stdio_dev *dev)
{
if(in_pointer==out_pointer)
return(0); /* no data */
else
return(1);
}
/* gets the character from the queue */
int kbd_getc(struct stdio_dev *dev)
{
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,20 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _KBD_H_
#define _KBD_H_
struct stdio_dev;
int kbd_testc(struct stdio_dev *sdev);
int kbd_getc(struct stdio_dev *sdev);
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,90 @@
/*
* SPDX-License-Identifier: GPL-2.0 IBM-pibs
*/
/*
* 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,176 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* SPDX-License-Identifier: GPL-2.0+
*/
#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,149 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* SPDX-License-Identifier: GPL-2.0+
*/
#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,171 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland
*
* SPDX-License-Identifier: GPL-2.0+
*
* 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,12 @@
if TARGET_MIP405
config SYS_BOARD
default "mip405"
config SYS_VENDOR
default "mpl"
config SYS_CONFIG_NAME
default "MIP405"
endif

View File

@@ -0,0 +1,7 @@
MIP405 BOARD
M: Denis Peter <d.peter@mpl.ch>
S: Maintained
F: board/mpl/mip405/
F: include/configs/MIP405.h
F: configs/MIP405_defconfig
F: configs/MIP405T_defconfig

View File

@@ -0,0 +1,12 @@
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y = mip405.o cmd_mip405.o \
../common/pci.o \
../common/usb_uhci.o \
../common/common_util.o
obj-y += init.o

View File

@@ -0,0 +1,49 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* SPDX-License-Identifier: GPL-2.0+
*
* 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,200 @@
/*
* SPDX-License-Identifier: GPL-2.0 IBM-pibs
*/
/*-----------------------------------------------------------------------------
* 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
*-----------------------------------------------------------------------------*/
#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,803 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* SPDX-License-Identifier: GPL-2.0+
*
* 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 */
/* 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 true if console should be overwritten */
return ((in8(PLD_EXT_CONF_REG) & 0x1) == 0);
}
/************************************************************************
* 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,166 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* SPDX-License-Identifier: GPL-2.0+
*/
/****************************************************************************
* 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,12 @@
if TARGET_PATI
config SYS_BOARD
default "pati"
config SYS_VENDOR
default "mpl"
config SYS_CONFIG_NAME
default "PATI"
endif

View File

@@ -0,0 +1,6 @@
PATI BOARD
#M: -
S: Maintained
F: board/mpl/pati/
F: include/configs/PATI.h
F: configs/PATI_defconfig

View File

@@ -0,0 +1,9 @@
#
# (C) Copyright 2001-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := pati.o cmd_pati.o \
../common/common_util.o

View File

@@ -0,0 +1,433 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* SPDX-License-Identifier: GPL-2.0+
*
* 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,606 @@
/*
* (C) Copyright 2003
* Martin Winistoerfer, martinwinistoerfer@gmx.ch.
* Atapted for PATI
* Denis Peter, d.peter@mpl.ch
* SPDX-License-Identifier: GPL-2.0+
*/
/***********************************************************************************
* 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 <console.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 */
}
int board_early_init_f(void)
{
spi_init_f();
return 0;
}
/****************************************************************
* 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(struct stdio_dev *dev, const char c)
{
pci_con_put_it(c);
if(c == '\n')
pci_con_put_it('\r');
}
int pci_con_getc(struct stdio_dev *dev)
{
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(struct stdio_dev *dev)
{
if(r_ptr==(volatile int)w_ptr)
return 0;
return 1;
}
void pci_con_puts(struct stdio_dev *dev, 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;
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,424 @@
/*
* (C) Copyright 2003
* Denis Peter, d.peter@mpl.ch
* SPDX-License-Identifier: GPL-2.0+
*/
/************************************************************************
* 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,90 @@
#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,95 @@
/*
* (C) Copyright 2003
* Denis Peter, d.peter@mpl.ch
* SPDX-License-Identifier: GPL-2.0+
*/
/* 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,12 @@
if TARGET_PIP405
config SYS_BOARD
default "pip405"
config SYS_VENDOR
default "mpl"
config SYS_CONFIG_NAME
default "PIP405"
endif

View File

@@ -0,0 +1,6 @@
PIP405 BOARD
M: Denis Peter <d.peter@mpl.ch>
S: Maintained
F: board/mpl/pip405/
F: include/configs/PIP405.h
F: configs/PIP405_defconfig

View File

@@ -0,0 +1,14 @@
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y = pip405.o cmd_pip405.o \
../common/pci.o \
../common/isa.o \
../common/kbd.o \
../common/usb_uhci.o \
../common/common_util.o
obj-y += init.o

View File

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

View File

@@ -0,0 +1,53 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* SPDX-License-Identifier: GPL-2.0+
*
* 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,197 @@
/*
* SPDX-License-Identifier: GPL-2.0 IBM-pibs
*/
/*-----------------------------------------------------------------------------
* 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
*-----------------------------------------------------------------------------*/
#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,956 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* SPDX-License-Identifier: GPL-2.0+
*
* 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
/* 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_set_bus_num(0);
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 true if console should be overwritten */
return in8(CONFIG_PORT_ADDR) & 0x1;
}
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 occurred %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,131 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* SPDX-License-Identifier: GPL-2.0+
*/
/****************************************************************************
* 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,121 @@
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
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 = .);
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
}
__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,15 @@
if TARGET_VCMA9
config SYS_BOARD
default "vcma9"
config SYS_VENDOR
default "mpl"
config SYS_SOC
default "s3c24x0"
config SYS_CONFIG_NAME
default "VCMA9"
endif

View File

@@ -0,0 +1,6 @@
VCMA9 BOARD
M: David Müller <d.mueller@elsoft.ch>
S: Maintained
F: board/mpl/vcma9/
F: include/configs/VCMA9.h
F: configs/VCMA9_defconfig

View File

@@ -0,0 +1,11 @@
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := ../common/common_util.o
obj-y += vcma9.o cmd_vcma9.o
obj-y += lowlevel_init.o

View File

@@ -0,0 +1,119 @@
/*
* (C) Copyright 2002
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
*
* adapted for VCMA9
* David Mueller, ELSOFT AG, d.mueller@elsoft.ch
*
* SPDX-License-Identifier: GPL-2.0+
*/
#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,500 @@
/*
* 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
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <config.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
/**************************************/
.globl lowlevel_init
lowlevel_init:
/* use r0 to relocate DATA read/write to flash rather than memory ! */
ldr r0, =CONFIG_SYS_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,209 @@
/*
* (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>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#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,28 @@
/*
* (C) Copyright 2002, 2003
* David Mueller, ELSOFT AG, d.mueller@elsoft.ch
*
* SPDX-License-Identifier: GPL-2.0+
*/
/****************************************************************************
* 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)