939 lines
20 KiB
C
939 lines
20 KiB
C
/* Board specific functions for those embedded 8xx boards that do
|
|
* not have boot monitor support for board information.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
* option) any later version.
|
|
*/
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/string.h>
|
|
#include <asm/reg.h>
|
|
#ifdef CONFIG_8xx
|
|
#include <asm/mpc8xx.h>
|
|
#endif
|
|
#ifdef CONFIG_8260
|
|
#include <asm/mpc8260.h>
|
|
#include <asm/immap_cpm2.h>
|
|
#endif
|
|
#ifdef CONFIG_40x
|
|
#include <asm/io.h>
|
|
#endif
|
|
#ifdef CONFIG_XILINX_VIRTEX
|
|
#include <platforms/4xx/xparameters/xparameters.h>
|
|
#endif
|
|
extern unsigned long timebase_period_ns;
|
|
|
|
/* For those boards that don't provide one.
|
|
*/
|
|
#if !defined(CONFIG_MBX)
|
|
static bd_t bdinfo;
|
|
#endif
|
|
|
|
/* IIC functions.
|
|
* These are just the basic master read/write operations so we can
|
|
* examine serial EEPROM.
|
|
*/
|
|
extern void iic_read(uint devaddr, u_char *buf, uint offset, uint count);
|
|
|
|
/* Supply a default Ethernet address for those eval boards that don't
|
|
* ship with one. This is an address from the MBX board I have, so
|
|
* it is unlikely you will find it on your network.
|
|
*/
|
|
static ushort def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };
|
|
|
|
#if defined(CONFIG_MBX)
|
|
|
|
/* The MBX hands us a pretty much ready to go board descriptor. This
|
|
* is where the idea started in the first place.
|
|
*/
|
|
void
|
|
embed_config(bd_t **bdp)
|
|
{
|
|
u_char *mp;
|
|
u_char eebuf[128];
|
|
int i = 8;
|
|
bd_t *bd;
|
|
|
|
bd = *bdp;
|
|
|
|
/* Read the first 128 bytes of the EEPROM. There is more,
|
|
* but this is all we need.
|
|
*/
|
|
iic_read(0xa4, eebuf, 0, 128);
|
|
|
|
/* All we are looking for is the Ethernet MAC address. The
|
|
* first 8 bytes are 'MOTOROLA', so check for part of that.
|
|
* Next, the VPD describes a MAC 'packet' as being of type 08
|
|
* and size 06. So we look for that and the MAC must follow.
|
|
* If there are more than one, we still only care about the first.
|
|
* If it's there, assume we have a valid MAC address. If not,
|
|
* grab our default one.
|
|
*/
|
|
if ((*(uint *)eebuf) == 0x4d4f544f) {
|
|
while (i < 127 && !(eebuf[i] == 0x08 && eebuf[i + 1] == 0x06))
|
|
i += eebuf[i + 1] + 2; /* skip this packet */
|
|
|
|
if (i == 127) /* Couldn't find. */
|
|
mp = (u_char *)def_enet_addr;
|
|
else
|
|
mp = &eebuf[i + 2];
|
|
}
|
|
else
|
|
mp = (u_char *)def_enet_addr;
|
|
|
|
for (i=0; i<6; i++)
|
|
bd->bi_enetaddr[i] = *mp++;
|
|
|
|
/* The boot rom passes these to us in MHz. Linux now expects
|
|
* them to be in Hz.
|
|
*/
|
|
bd->bi_intfreq *= 1000000;
|
|
bd->bi_busfreq *= 1000000;
|
|
|
|
/* Stuff a baud rate here as well.
|
|
*/
|
|
bd->bi_baudrate = 9600;
|
|
}
|
|
#endif /* CONFIG_MBX */
|
|
|
|
#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || \
|
|
defined(CONFIG_RPX8260) || defined(CONFIG_EP405)
|
|
/* Helper functions for Embedded Planet boards.
|
|
*/
|
|
/* Because I didn't find anything that would do this.......
|
|
*/
|
|
u_char
|
|
aschex_to_byte(u_char *cp)
|
|
{
|
|
u_char byte, c;
|
|
|
|
c = *cp++;
|
|
|
|
if ((c >= 'A') && (c <= 'F')) {
|
|
c -= 'A';
|
|
c += 10;
|
|
} else if ((c >= 'a') && (c <= 'f')) {
|
|
c -= 'a';
|
|
c += 10;
|
|
} else
|
|
c -= '0';
|
|
|
|
byte = c * 16;
|
|
|
|
c = *cp;
|
|
|
|
if ((c >= 'A') && (c <= 'F')) {
|
|
c -= 'A';
|
|
c += 10;
|
|
} else if ((c >= 'a') && (c <= 'f')) {
|
|
c -= 'a';
|
|
c += 10;
|
|
} else
|
|
c -= '0';
|
|
|
|
byte += c;
|
|
|
|
return(byte);
|
|
}
|
|
|
|
static void
|
|
rpx_eth(bd_t *bd, u_char *cp)
|
|
{
|
|
int i;
|
|
|
|
for (i=0; i<6; i++) {
|
|
bd->bi_enetaddr[i] = aschex_to_byte(cp);
|
|
cp += 2;
|
|
}
|
|
}
|
|
|
|
#ifdef CONFIG_RPX8260
|
|
static uint
|
|
rpx_baseten(u_char *cp)
|
|
{
|
|
uint retval;
|
|
|
|
retval = 0;
|
|
|
|
while (*cp != '\n') {
|
|
retval *= 10;
|
|
retval += (*cp) - '0';
|
|
cp++;
|
|
}
|
|
return(retval);
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
|
|
static void
|
|
rpx_brate(bd_t *bd, u_char *cp)
|
|
{
|
|
uint rate;
|
|
|
|
rate = 0;
|
|
|
|
while (*cp != '\n') {
|
|
rate *= 10;
|
|
rate += (*cp) - '0';
|
|
cp++;
|
|
}
|
|
|
|
bd->bi_baudrate = rate * 100;
|
|
}
|
|
|
|
static void
|
|
rpx_cpuspeed(bd_t *bd, u_char *cp)
|
|
{
|
|
uint num, den;
|
|
|
|
num = den = 0;
|
|
|
|
while (*cp != '\n') {
|
|
num *= 10;
|
|
num += (*cp) - '0';
|
|
cp++;
|
|
if (*cp == '/') {
|
|
cp++;
|
|
den = (*cp) - '0';
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* I don't know why the RPX just can't state the actual
|
|
* CPU speed.....
|
|
*/
|
|
if (den) {
|
|
num /= den;
|
|
num *= den;
|
|
}
|
|
bd->bi_intfreq = bd->bi_busfreq = num * 1000000;
|
|
|
|
/* The 8xx can only run a maximum 50 MHz bus speed (until
|
|
* Motorola changes this :-). Greater than 50 MHz parts
|
|
* run internal/2 for bus speed.
|
|
*/
|
|
if (num > 50)
|
|
bd->bi_busfreq /= 2;
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || defined(CONFIG_EP405)
|
|
static void
|
|
rpx_memsize(bd_t *bd, u_char *cp)
|
|
{
|
|
uint size;
|
|
|
|
size = 0;
|
|
|
|
while (*cp != '\n') {
|
|
size *= 10;
|
|
size += (*cp) - '0';
|
|
cp++;
|
|
}
|
|
|
|
bd->bi_memsize = size * 1024 * 1024;
|
|
}
|
|
#endif /* LITE || CLASSIC || EP405 */
|
|
#if defined(CONFIG_EP405)
|
|
static void
|
|
rpx_nvramsize(bd_t *bd, u_char *cp)
|
|
{
|
|
uint size;
|
|
|
|
size = 0;
|
|
|
|
while (*cp != '\n') {
|
|
size *= 10;
|
|
size += (*cp) - '0';
|
|
cp++;
|
|
}
|
|
|
|
bd->bi_nvramsize = size * 1024;
|
|
}
|
|
#endif /* CONFIG_EP405 */
|
|
|
|
#endif /* Embedded Planet boards */
|
|
|
|
#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
|
|
|
|
/* Read the EEPROM on the RPX-Lite board.
|
|
*/
|
|
void
|
|
embed_config(bd_t **bdp)
|
|
{
|
|
u_char eebuf[256], *cp;
|
|
bd_t *bd;
|
|
|
|
/* Read the first 256 bytes of the EEPROM. I think this
|
|
* is really all there is, and I hope if it gets bigger the
|
|
* info we want is still up front.
|
|
*/
|
|
bd = &bdinfo;
|
|
*bdp = bd;
|
|
|
|
#if 1
|
|
iic_read(0xa8, eebuf, 0, 128);
|
|
iic_read(0xa8, &eebuf[128], 128, 128);
|
|
|
|
/* We look for two things, the Ethernet address and the
|
|
* serial baud rate. The records are separated by
|
|
* newlines.
|
|
*/
|
|
cp = eebuf;
|
|
for (;;) {
|
|
if (*cp == 'E') {
|
|
cp++;
|
|
if (*cp == 'A') {
|
|
cp += 2;
|
|
rpx_eth(bd, cp);
|
|
}
|
|
}
|
|
if (*cp == 'S') {
|
|
cp++;
|
|
if (*cp == 'B') {
|
|
cp += 2;
|
|
rpx_brate(bd, cp);
|
|
}
|
|
}
|
|
if (*cp == 'D') {
|
|
cp++;
|
|
if (*cp == '1') {
|
|
cp += 2;
|
|
rpx_memsize(bd, cp);
|
|
}
|
|
}
|
|
if (*cp == 'H') {
|
|
cp++;
|
|
if (*cp == 'Z') {
|
|
cp += 2;
|
|
rpx_cpuspeed(bd, cp);
|
|
}
|
|
}
|
|
|
|
/* Scan to the end of the record.
|
|
*/
|
|
while ((*cp != '\n') && (*cp != 0xff))
|
|
cp++;
|
|
|
|
/* If the next character is a 0 or ff, we are done.
|
|
*/
|
|
cp++;
|
|
if ((*cp == 0) || (*cp == 0xff))
|
|
break;
|
|
}
|
|
bd->bi_memstart = 0;
|
|
#else
|
|
/* For boards without initialized EEPROM.
|
|
*/
|
|
bd->bi_memstart = 0;
|
|
bd->bi_memsize = (8 * 1024 * 1024);
|
|
bd->bi_intfreq = 48000000;
|
|
bd->bi_busfreq = 48000000;
|
|
bd->bi_baudrate = 9600;
|
|
#endif
|
|
}
|
|
#endif /* RPXLITE || RPXCLASSIC */
|
|
|
|
#ifdef CONFIG_BSEIP
|
|
/* Build a board information structure for the BSE ip-Engine.
|
|
* There is more to come since we will add some environment
|
|
* variables and a function to read them.
|
|
*/
|
|
void
|
|
embed_config(bd_t **bdp)
|
|
{
|
|
u_char *cp;
|
|
int i;
|
|
bd_t *bd;
|
|
|
|
bd = &bdinfo;
|
|
*bdp = bd;
|
|
|
|
/* Baud rate and processor speed will eventually come
|
|
* from the environment variables.
|
|
*/
|
|
bd->bi_baudrate = 9600;
|
|
|
|
/* Get the Ethernet station address from the Flash ROM.
|
|
*/
|
|
cp = (u_char *)0xfe003ffa;
|
|
for (i=0; i<6; i++) {
|
|
bd->bi_enetaddr[i] = *cp++;
|
|
}
|
|
|
|
/* The rest of this should come from the environment as well.
|
|
*/
|
|
bd->bi_memstart = 0;
|
|
bd->bi_memsize = (16 * 1024 * 1024);
|
|
bd->bi_intfreq = 48000000;
|
|
bd->bi_busfreq = 48000000;
|
|
}
|
|
#endif /* BSEIP */
|
|
|
|
#ifdef CONFIG_FADS
|
|
/* Build a board information structure for the FADS.
|
|
*/
|
|
void
|
|
embed_config(bd_t **bdp)
|
|
{
|
|
u_char *cp;
|
|
int i;
|
|
bd_t *bd;
|
|
|
|
bd = &bdinfo;
|
|
*bdp = bd;
|
|
|
|
/* Just fill in some known values.
|
|
*/
|
|
bd->bi_baudrate = 9600;
|
|
|
|
/* Use default enet.
|
|
*/
|
|
cp = (u_char *)def_enet_addr;
|
|
for (i=0; i<6; i++) {
|
|
bd->bi_enetaddr[i] = *cp++;
|
|
}
|
|
|
|
bd->bi_memstart = 0;
|
|
bd->bi_memsize = (8 * 1024 * 1024);
|
|
bd->bi_intfreq = 40000000;
|
|
bd->bi_busfreq = 40000000;
|
|
}
|
|
#endif /* FADS */
|
|
|
|
#ifdef CONFIG_8260
|
|
/* Compute 8260 clock values if the rom doesn't provide them.
|
|
*/
|
|
static unsigned char bus2core_8260[] = {
|
|
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
|
3, 2, 2, 2, 4, 4, 5, 9, 6, 11, 8, 10, 3, 12, 7, 2,
|
|
6, 5, 13, 2, 14, 4, 15, 2, 3, 11, 8, 10, 16, 12, 7, 2,
|
|
};
|
|
|
|
static void
|
|
clk_8260(bd_t *bd)
|
|
{
|
|
uint scmr, vco_out, clkin;
|
|
uint plldf, pllmf, corecnf;
|
|
volatile cpm2_map_t *ip;
|
|
|
|
ip = (cpm2_map_t *)CPM_MAP_ADDR;
|
|
scmr = ip->im_clkrst.car_scmr;
|
|
|
|
/* The clkin is always bus frequency.
|
|
*/
|
|
clkin = bd->bi_busfreq;
|
|
|
|
/* Collect the bits from the scmr.
|
|
*/
|
|
plldf = (scmr >> 12) & 1;
|
|
pllmf = scmr & 0xfff;
|
|
corecnf = (scmr >> 24) &0x1f;
|
|
|
|
/* This is arithmetic from the 8260 manual.
|
|
*/
|
|
vco_out = clkin / (plldf + 1);
|
|
vco_out *= 2 * (pllmf + 1);
|
|
bd->bi_vco = vco_out; /* Save for later */
|
|
|
|
bd->bi_cpmfreq = vco_out / 2; /* CPM Freq, in MHz */
|
|
bd->bi_intfreq = bd->bi_busfreq * bus2core_8260[corecnf] / 2;
|
|
|
|
/* Set Baud rate divisor. The power up default is divide by 16,
|
|
* but we set it again here in case it was changed.
|
|
*/
|
|
ip->im_clkrst.car_sccr = 1; /* DIV 16 BRG */
|
|
bd->bi_brgfreq = vco_out / 16;
|
|
}
|
|
|
|
static unsigned char bus2core_8280[] = {
|
|
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
|
3, 2, 2, 2, 4, 4, 5, 9, 6, 11, 8, 10, 3, 12, 7, 2,
|
|
6, 5, 13, 2, 14, 2, 15, 2, 3, 2, 2, 2, 16, 2, 2, 2,
|
|
};
|
|
|
|
static void
|
|
clk_8280(bd_t *bd)
|
|
{
|
|
uint scmr, main_clk, clkin;
|
|
uint pllmf, corecnf;
|
|
volatile cpm2_map_t *ip;
|
|
|
|
ip = (cpm2_map_t *)CPM_MAP_ADDR;
|
|
scmr = ip->im_clkrst.car_scmr;
|
|
|
|
/* The clkin is always bus frequency.
|
|
*/
|
|
clkin = bd->bi_busfreq;
|
|
|
|
/* Collect the bits from the scmr.
|
|
*/
|
|
pllmf = scmr & 0xf;
|
|
corecnf = (scmr >> 24) & 0x1f;
|
|
|
|
/* This is arithmetic from the 8280 manual.
|
|
*/
|
|
main_clk = clkin * (pllmf + 1);
|
|
|
|
bd->bi_cpmfreq = main_clk / 2; /* CPM Freq, in MHz */
|
|
bd->bi_intfreq = bd->bi_busfreq * bus2core_8280[corecnf] / 2;
|
|
|
|
/* Set Baud rate divisor. The power up default is divide by 16,
|
|
* but we set it again here in case it was changed.
|
|
*/
|
|
ip->im_clkrst.car_sccr = (ip->im_clkrst.car_sccr & 0x3) | 0x1;
|
|
bd->bi_brgfreq = main_clk / 16;
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_SBC82xx
|
|
void
|
|
embed_config(bd_t **bdp)
|
|
{
|
|
u_char *cp;
|
|
int i;
|
|
bd_t *bd;
|
|
unsigned long pvr;
|
|
|
|
bd = *bdp;
|
|
|
|
bd = &bdinfo;
|
|
*bdp = bd;
|
|
bd->bi_baudrate = 9600;
|
|
bd->bi_memsize = 256 * 1024 * 1024; /* just a guess */
|
|
|
|
cp = (void*)SBC82xx_MACADDR_NVRAM_SCC1;
|
|
memcpy(bd->bi_enetaddr, cp, 6);
|
|
|
|
/* can busfreq be calculated? */
|
|
pvr = mfspr(SPRN_PVR);
|
|
if ((pvr & 0xffff0000) == 0x80820000) {
|
|
bd->bi_busfreq = 100000000;
|
|
clk_8280(bd);
|
|
} else {
|
|
bd->bi_busfreq = 66000000;
|
|
clk_8260(bd);
|
|
}
|
|
|
|
}
|
|
#endif /* SBC82xx */
|
|
|
|
#if defined(CONFIG_EST8260) || defined(CONFIG_TQM8260)
|
|
void
|
|
embed_config(bd_t **bdp)
|
|
{
|
|
u_char *cp;
|
|
int i;
|
|
bd_t *bd;
|
|
|
|
bd = *bdp;
|
|
#if 0
|
|
/* This is actually provided by my boot rom. I have it
|
|
* here for those people that may load the kernel with
|
|
* a JTAG/COP tool and not the rom monitor.
|
|
*/
|
|
bd->bi_baudrate = 115200;
|
|
bd->bi_intfreq = 200000000;
|
|
bd->bi_busfreq = 66666666;
|
|
bd->bi_cpmfreq = 66666666;
|
|
bd->bi_brgfreq = 33333333;
|
|
bd->bi_memsize = 16 * 1024 * 1024;
|
|
#else
|
|
/* The boot rom passes these to us in MHz. Linux now expects
|
|
* them to be in Hz.
|
|
*/
|
|
bd->bi_intfreq *= 1000000;
|
|
bd->bi_busfreq *= 1000000;
|
|
bd->bi_cpmfreq *= 1000000;
|
|
bd->bi_brgfreq *= 1000000;
|
|
#endif
|
|
|
|
cp = (u_char *)def_enet_addr;
|
|
for (i=0; i<6; i++) {
|
|
bd->bi_enetaddr[i] = *cp++;
|
|
}
|
|
}
|
|
#endif /* EST8260 */
|
|
|
|
#ifdef CONFIG_SBS8260
|
|
void
|
|
embed_config(bd_t **bdp)
|
|
{
|
|
u_char *cp;
|
|
int i;
|
|
bd_t *bd;
|
|
|
|
/* This should provided by the boot rom.
|
|
*/
|
|
bd = &bdinfo;
|
|
*bdp = bd;
|
|
bd->bi_baudrate = 9600;
|
|
bd->bi_memsize = 64 * 1024 * 1024;
|
|
|
|
/* Set all of the clocks. We have to know the speed of the
|
|
* external clock. The development board had 66 MHz.
|
|
*/
|
|
bd->bi_busfreq = 66666666;
|
|
clk_8260(bd);
|
|
|
|
/* I don't know how to compute this yet.
|
|
*/
|
|
bd->bi_intfreq = 133000000;
|
|
|
|
|
|
cp = (u_char *)def_enet_addr;
|
|
for (i=0; i<6; i++) {
|
|
bd->bi_enetaddr[i] = *cp++;
|
|
}
|
|
}
|
|
#endif /* SBS8260 */
|
|
|
|
#ifdef CONFIG_RPX8260
|
|
void
|
|
embed_config(bd_t **bdp)
|
|
{
|
|
u_char *cp, *keyvals;
|
|
int i;
|
|
bd_t *bd;
|
|
|
|
keyvals = (u_char *)*bdp;
|
|
|
|
bd = &bdinfo;
|
|
*bdp = bd;
|
|
|
|
/* This is almost identical to the RPX-Lite/Classic functions
|
|
* on the 8xx boards. It would be nice to have a key lookup
|
|
* function in a string, but the format of all of the fields
|
|
* is slightly different.
|
|
*/
|
|
cp = keyvals;
|
|
for (;;) {
|
|
if (*cp == 'E') {
|
|
cp++;
|
|
if (*cp == 'A') {
|
|
cp += 2;
|
|
rpx_eth(bd, cp);
|
|
}
|
|
}
|
|
if (*cp == 'S') {
|
|
cp++;
|
|
if (*cp == 'B') {
|
|
cp += 2;
|
|
bd->bi_baudrate = rpx_baseten(cp);
|
|
}
|
|
}
|
|
if (*cp == 'D') {
|
|
cp++;
|
|
if (*cp == '1') {
|
|
cp += 2;
|
|
bd->bi_memsize = rpx_baseten(cp) * 1024 * 1024;
|
|
}
|
|
}
|
|
if (*cp == 'X') {
|
|
cp++;
|
|
if (*cp == 'T') {
|
|
cp += 2;
|
|
bd->bi_busfreq = rpx_baseten(cp);
|
|
}
|
|
}
|
|
if (*cp == 'N') {
|
|
cp++;
|
|
if (*cp == 'V') {
|
|
cp += 2;
|
|
bd->bi_nvsize = rpx_baseten(cp) * 1024 * 1024;
|
|
}
|
|
}
|
|
|
|
/* Scan to the end of the record.
|
|
*/
|
|
while ((*cp != '\n') && (*cp != 0xff))
|
|
cp++;
|
|
|
|
/* If the next character is a 0 or ff, we are done.
|
|
*/
|
|
cp++;
|
|
if ((*cp == 0) || (*cp == 0xff))
|
|
break;
|
|
}
|
|
bd->bi_memstart = 0;
|
|
|
|
/* The memory size includes both the 60x and local bus DRAM.
|
|
* I don't want to use the local bus DRAM for real memory,
|
|
* so subtract it out. It would be nice if they were separate
|
|
* keys.
|
|
*/
|
|
bd->bi_memsize -= 32 * 1024 * 1024;
|
|
|
|
/* Set all of the clocks. We have to know the speed of the
|
|
* external clock.
|
|
*/
|
|
clk_8260(bd);
|
|
|
|
/* I don't know how to compute this yet.
|
|
*/
|
|
bd->bi_intfreq = 200000000;
|
|
}
|
|
#endif /* RPX6 for testing */
|
|
|
|
#ifdef CONFIG_ADS8260
|
|
void
|
|
embed_config(bd_t **bdp)
|
|
{
|
|
u_char *cp;
|
|
int i;
|
|
bd_t *bd;
|
|
|
|
/* This should provided by the boot rom.
|
|
*/
|
|
bd = &bdinfo;
|
|
*bdp = bd;
|
|
bd->bi_baudrate = 9600;
|
|
bd->bi_memsize = 16 * 1024 * 1024;
|
|
|
|
/* Set all of the clocks. We have to know the speed of the
|
|
* external clock. The development board had 66 MHz.
|
|
*/
|
|
bd->bi_busfreq = 66666666;
|
|
clk_8260(bd);
|
|
|
|
/* I don't know how to compute this yet.
|
|
*/
|
|
bd->bi_intfreq = 200000000;
|
|
|
|
|
|
cp = (u_char *)def_enet_addr;
|
|
for (i=0; i<6; i++) {
|
|
bd->bi_enetaddr[i] = *cp++;
|
|
}
|
|
}
|
|
#endif /* ADS8260 */
|
|
|
|
#ifdef CONFIG_WILLOW
|
|
void
|
|
embed_config(bd_t **bdp)
|
|
{
|
|
u_char *cp;
|
|
int i;
|
|
bd_t *bd;
|
|
|
|
/* Willow has Open Firmware....I should learn how to get this
|
|
* information from it.
|
|
*/
|
|
bd = &bdinfo;
|
|
*bdp = bd;
|
|
bd->bi_baudrate = 9600;
|
|
bd->bi_memsize = 32 * 1024 * 1024;
|
|
|
|
/* Set all of the clocks. We have to know the speed of the
|
|
* external clock. The development board had 66 MHz.
|
|
*/
|
|
bd->bi_busfreq = 66666666;
|
|
clk_8260(bd);
|
|
|
|
/* I don't know how to compute this yet.
|
|
*/
|
|
bd->bi_intfreq = 200000000;
|
|
|
|
|
|
cp = (u_char *)def_enet_addr;
|
|
for (i=0; i<6; i++) {
|
|
bd->bi_enetaddr[i] = *cp++;
|
|
}
|
|
}
|
|
#endif /* WILLOW */
|
|
|
|
#if defined(CONFIG_XILINX_ML300) || defined(CONFIG_XILINX_ML403)
|
|
void
|
|
embed_config(bd_t ** bdp)
|
|
{
|
|
static const unsigned long line_size = 32;
|
|
static const unsigned long congruence_classes = 256;
|
|
unsigned long addr;
|
|
unsigned long dccr;
|
|
uint8_t* cp;
|
|
bd_t *bd;
|
|
int i;
|
|
|
|
/*
|
|
* Invalidate the data cache if the data cache is turned off.
|
|
* - The 405 core does not invalidate the data cache on power-up
|
|
* or reset but does turn off the data cache. We cannot assume
|
|
* that the cache contents are valid.
|
|
* - If the data cache is turned on this must have been done by
|
|
* a bootloader and we assume that the cache contents are
|
|
* valid.
|
|
*/
|
|
__asm__("mfdccr %0": "=r" (dccr));
|
|
if (dccr == 0) {
|
|
for (addr = 0;
|
|
addr < (congruence_classes * line_size);
|
|
addr += line_size) {
|
|
__asm__("dccci 0,%0": :"b"(addr));
|
|
}
|
|
}
|
|
|
|
bd = &bdinfo;
|
|
*bdp = bd;
|
|
bd->bi_memsize = XPAR_DDR_0_SIZE;
|
|
bd->bi_intfreq = XPAR_CORE_CLOCK_FREQ_HZ;
|
|
bd->bi_busfreq = XPAR_PLB_CLOCK_FREQ_HZ;
|
|
bd->bi_pci_busfreq = XPAR_PCI_0_CLOCK_FREQ_HZ;
|
|
|
|
/* Copy the default ethernet address */
|
|
cp = (u_char *)def_enet_addr;
|
|
for (i=0; i<6; i++)
|
|
bd->bi_enetaddr[i] = *cp++;
|
|
|
|
timebase_period_ns = 1000000000 / bd->bi_tbfreq;
|
|
/* see bi_tbfreq definition in arch/ppc/platforms/4xx/xilinx_ml300.h */
|
|
}
|
|
#endif /* CONFIG_XILINX_ML300 || CONFIG_XILINX_ML403 */
|
|
|
|
#ifdef CONFIG_IBM_OPENBIOS
|
|
/* This could possibly work for all treeboot roms.
|
|
*/
|
|
#if defined(CONFIG_BUBINGA)
|
|
#define BOARD_INFO_VECTOR 0xFFF80B50 /* openbios 1.19 moved this vector down - armin */
|
|
#else
|
|
#define BOARD_INFO_VECTOR 0xFFFE0B50
|
|
#endif
|
|
|
|
void
|
|
embed_config(bd_t **bdp)
|
|
{
|
|
u_char *cp;
|
|
int i;
|
|
bd_t *bd, *treeboot_bd;
|
|
bd_t *(*get_board_info)(void) =
|
|
(bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR);
|
|
#if !defined(CONFIG_STB03xxx)
|
|
|
|
/* shut down the Ethernet controller that the boot rom
|
|
* sometimes leaves running.
|
|
*/
|
|
mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); /* 1st reset MAL */
|
|
while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; /* wait for the reset */
|
|
out_be32((volatile u32*)EMAC0_BASE,0x20000000); /* then reset EMAC */
|
|
#endif
|
|
|
|
bd = &bdinfo;
|
|
*bdp = bd;
|
|
if ((treeboot_bd = get_board_info()) != NULL) {
|
|
memcpy(bd, treeboot_bd, sizeof(bd_t));
|
|
}
|
|
else {
|
|
/* Hmmm...better try to stuff some defaults.
|
|
*/
|
|
bd->bi_memsize = 16 * 1024 * 1024;
|
|
cp = (u_char *)def_enet_addr;
|
|
for (i=0; i<6; i++) {
|
|
/* I should probably put different ones here,
|
|
* hopefully only one is used.
|
|
*/
|
|
bd->BD_EMAC_ADDR(0,i) = *cp;
|
|
|
|
#ifdef CONFIG_PCI
|
|
bd->bi_pci_enetaddr[i] = *cp++;
|
|
#endif
|
|
}
|
|
bd->bi_tbfreq = 200 * 1000 * 1000;
|
|
bd->bi_intfreq = 200000000;
|
|
bd->bi_busfreq = 100000000;
|
|
#ifdef CONFIG_PCI
|
|
bd->bi_pci_busfreq = 66666666;
|
|
#endif
|
|
}
|
|
/* Yeah, this look weird, but on Redwood 4 they are
|
|
* different object in the structure. Sincr Redwwood 5
|
|
* and Redwood 6 use OpenBIOS, it requires a special value.
|
|
*/
|
|
#if defined(CONFIG_REDWOOD_5) || defined (CONFIG_REDWOOD_6)
|
|
bd->bi_tbfreq = 27 * 1000 * 1000;
|
|
#endif
|
|
timebase_period_ns = 1000000000 / bd->bi_tbfreq;
|
|
}
|
|
#endif /* CONFIG_IBM_OPENBIOS */
|
|
|
|
#ifdef CONFIG_EP405
|
|
#include <linux/serial_reg.h>
|
|
|
|
void
|
|
embed_config(bd_t **bdp)
|
|
{
|
|
u32 chcr0;
|
|
u_char *cp;
|
|
bd_t *bd;
|
|
|
|
/* Different versions of the PlanetCore firmware vary in how
|
|
they set up the serial port - in particular whether they
|
|
use the internal or external serial clock for UART0. Make
|
|
sure the UART is in a known state. */
|
|
/* FIXME: We should use the board's 11.0592MHz external serial
|
|
clock - it will be more accurate for serial rates. For
|
|
now, however the baud rates in ep405.h are for the internal
|
|
clock. */
|
|
chcr0 = mfdcr(DCRN_CHCR0);
|
|
if ( (chcr0 & 0x1fff) != 0x103e ) {
|
|
mtdcr(DCRN_CHCR0, (chcr0 & 0xffffe000) | 0x103e);
|
|
/* The following tricks serial_init() into resetting the baud rate */
|
|
writeb(0, UART0_IO_BASE + UART_LCR);
|
|
}
|
|
|
|
/* We haven't seen actual problems with the EP405 leaving the
|
|
* EMAC running (as we have on Walnut). But the registers
|
|
* suggest it may not be left completely quiescent. Reset it
|
|
* just to be sure. */
|
|
mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); /* 1st reset MAL */
|
|
while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; /* wait for the reset */
|
|
out_be32((unsigned *)EMAC0_BASE,0x20000000); /* then reset EMAC */
|
|
|
|
bd = &bdinfo;
|
|
*bdp = bd;
|
|
#if 1
|
|
cp = (u_char *)0xF0000EE0;
|
|
for (;;) {
|
|
if (*cp == 'E') {
|
|
cp++;
|
|
if (*cp == 'A') {
|
|
cp += 2;
|
|
rpx_eth(bd, cp);
|
|
}
|
|
}
|
|
|
|
if (*cp == 'D') {
|
|
cp++;
|
|
if (*cp == '1') {
|
|
cp += 2;
|
|
rpx_memsize(bd, cp);
|
|
}
|
|
}
|
|
|
|
if (*cp == 'N') {
|
|
cp++;
|
|
if (*cp == 'V') {
|
|
cp += 2;
|
|
rpx_nvramsize(bd, cp);
|
|
}
|
|
}
|
|
while ((*cp != '\n') && (*cp != 0xff))
|
|
cp++;
|
|
|
|
cp++;
|
|
if ((*cp == 0) || (*cp == 0xff))
|
|
break;
|
|
}
|
|
bd->bi_intfreq = 200000000;
|
|
bd->bi_busfreq = 100000000;
|
|
bd->bi_pci_busfreq= 33000000 ;
|
|
#else
|
|
|
|
bd->bi_memsize = 64000000;
|
|
bd->bi_intfreq = 200000000;
|
|
bd->bi_busfreq = 100000000;
|
|
bd->bi_pci_busfreq= 33000000 ;
|
|
#endif
|
|
}
|
|
#endif
|