u-boot/board/keymile/km82xx/km82xx.c
Simon Glass 52c411805c board_f: Drop board_type parameter from initdram()
It looks like only cm5200 and tqm8xx use this feature, so we don't really
need it in generic code. Drop it and have the users access gd->board_type
directly.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Stefan Roese <sr@denx.de>
2017-04-05 13:58:44 -04:00

464 lines
14 KiB
C

/*
* (C) Copyright 2007 - 2008
* Heiko Schocher, DENX Software Engineering, hs@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <mpc8260.h>
#include <ioports.h>
#include <malloc.h>
#include <asm/io.h>
#include <libfdt.h>
#include <i2c.h>
#include "../common/common.h"
static uchar ivm_content[CONFIG_SYS_IVM_EEPROM_MAX_LEN];
/*
* I/O Port configuration table
*
* if conf is 1, then that port pin will be configured at boot time
* according to the five values podr/pdir/ppar/psor/pdat for that entry
*/
const iop_conf_t iop_conf_tab[4][32] = {
/* Port A */
{ /* conf ppar psor pdir podr pdat */
{ 0, 0, 0, 0, 0, 0 }, /* PA31 */
{ 0, 0, 0, 0, 0, 0 }, /* PA30 */
{ 0, 0, 0, 0, 0, 0 }, /* PA29 */
{ 0, 0, 0, 0, 0, 0 }, /* PA28 */
{ 0, 0, 0, 0, 0, 0 }, /* PA27 */
{ 0, 0, 0, 0, 0, 0 }, /* PA26 */
{ 0, 0, 0, 0, 0, 0 }, /* PA25 */
{ 0, 0, 0, 0, 0, 0 }, /* PA24 */
{ 0, 0, 0, 0, 0, 0 }, /* PA23 */
{ 0, 0, 0, 0, 0, 0 }, /* PA22 */
{ 0, 0, 0, 0, 0, 0 }, /* PA21 */
{ 0, 0, 0, 0, 0, 0 }, /* PA20 */
{ 0, 0, 0, 0, 0, 0 }, /* PA19 */
{ 0, 0, 0, 0, 0, 0 }, /* PA18 */
{ 0, 0, 0, 0, 0, 0 }, /* PA17 */
{ 0, 0, 0, 0, 0, 0 }, /* PA16 */
{ 0, 0, 0, 0, 0, 0 }, /* PA15 */
{ 0, 0, 0, 0, 0, 0 }, /* PA14 */
{ 0, 0, 0, 0, 0, 0 }, /* PA13 */
{ 0, 0, 0, 0, 0, 0 }, /* PA12 */
{ 0, 0, 0, 0, 0, 0 }, /* PA11 */
{ 0, 0, 0, 0, 0, 0 }, /* PA10 */
{ 1, 1, 0, 1, 0, 0 }, /* PA9 SMC2 TxD */
{ 1, 1, 0, 0, 0, 0 }, /* PA8 SMC2 RxD */
{ 0, 0, 0, 0, 0, 0 }, /* PA7 */
{ 0, 0, 0, 0, 0, 0 }, /* PA6 */
{ 0, 0, 0, 0, 0, 0 }, /* PA5 */
{ 0, 0, 0, 0, 0, 0 }, /* PA4 */
{ 0, 0, 0, 0, 0, 0 }, /* PA3 */
{ 0, 0, 0, 0, 0, 0 }, /* PA2 */
{ 0, 0, 0, 0, 0, 0 }, /* PA1 */
{ 0, 0, 0, 0, 0, 0 } /* PA0 */
},
/* Port B */
{ /* conf ppar psor pdir podr pdat */
{ 0, 0, 0, 0, 0, 0 }, /* PB31 */
{ 0, 0, 0, 0, 0, 0 }, /* PB30 */
{ 0, 0, 0, 0, 0, 0 }, /* PB29 */
{ 0, 0, 0, 0, 0, 0 }, /* PB28 */
{ 0, 0, 0, 0, 0, 0 }, /* PB27 */
{ 0, 0, 0, 0, 0, 0 }, /* PB26 */
{ 0, 0, 0, 0, 0, 0 }, /* PB25 */
{ 0, 0, 0, 0, 0, 0 }, /* PB24 */
{ 0, 0, 0, 0, 0, 0 }, /* PB23 */
{ 0, 0, 0, 0, 0, 0 }, /* PB22 */
{ 0, 0, 0, 0, 0, 0 }, /* PB21 */
{ 0, 0, 0, 0, 0, 0 }, /* PB20 */
{ 0, 0, 0, 0, 0, 0 }, /* PB19 */
{ 0, 0, 0, 0, 0, 0 }, /* PB18 */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 } /* non-existent */
},
/* Port C */
{ /* conf ppar psor pdir podr pdat */
{ 0, 0, 0, 0, 0, 0 }, /* PC31 */
{ 0, 0, 0, 0, 0, 0 }, /* PC30 */
{ 0, 0, 0, 0, 0, 0 }, /* PC29 */
{ 0, 0, 0, 0, 0, 0 }, /* PC28 */
{ 0, 0, 0, 0, 0, 0 }, /* PC27 */
{ 0, 0, 0, 0, 0, 0 }, /* PC26 */
{ 1, 1, 0, 0, 0, 0 }, /* PC25 RxClk */
{ 1, 1, 0, 0, 0, 0 }, /* PC24 TxClk */
{ 0, 0, 0, 0, 0, 0 }, /* PC23 */
{ 0, 0, 0, 0, 0, 0 }, /* PC22 */
{ 0, 0, 0, 0, 0, 0 }, /* PC21 */
{ 0, 0, 0, 0, 0, 0 }, /* PC20 */
{ 0, 0, 0, 0, 0, 0 }, /* PC19 */
{ 0, 0, 0, 0, 0, 0 }, /* PC18 */
{ 0, 0, 0, 0, 0, 0 }, /* PC17 */
{ 0, 0, 0, 0, 0, 0 }, /* PC16 */
{ 0, 0, 0, 0, 0, 0 }, /* PC15 */
{ 0, 0, 0, 0, 0, 0 }, /* PC14 */
{ 0, 0, 0, 0, 0, 0 }, /* PC13 */
{ 0, 0, 0, 0, 0, 0 }, /* PC12 */
{ 0, 0, 0, 0, 0, 0 }, /* PC11 */
{ 0, 0, 0, 0, 0, 0 }, /* PC10 */
{ 1, 1, 0, 0, 0, 0 }, /* PC9 SCC4: CTS */
{ 1, 1, 0, 0, 0, 0 }, /* PC8 SCC4: CD */
{ 0, 0, 0, 0, 0, 0 }, /* PC7 */
{ 0, 0, 0, 0, 0, 0 }, /* PC6 */
{ 0, 0, 0, 0, 0, 0 }, /* PC5 */
{ 0, 0, 0, 0, 0, 0 }, /* PC4 */
{ 0, 0, 0, 0, 0, 0 }, /* PC3 */
{ 0, 0, 0, 0, 0, 0 }, /* PC2 */
{ 0, 0, 0, 0, 0, 0 }, /* PC1 */
{ 0, 0, 0, 0, 0, 0 }, /* PC0 */
},
/* Port D */
{ /* conf ppar psor pdir podr pdat */
{ 0, 0, 0, 0, 0, 0 }, /* PD31 */
{ 0, 0, 0, 0, 0, 0 }, /* PD30 */
{ 0, 0, 0, 0, 0, 0 }, /* PD29 */
{ 0, 0, 0, 0, 0, 0 }, /* PD28 */
{ 0, 0, 0, 0, 0, 0 }, /* PD27 */
{ 0, 0, 0, 0, 0, 0 }, /* PD26 */
{ 0, 0, 0, 0, 0, 0 }, /* PD25 */
{ 0, 0, 0, 0, 0, 0 }, /* PD24 */
{ 0, 0, 0, 0, 0, 0 }, /* PD23 */
{ 1, 1, 0, 0, 0, 0 }, /* PD22 SCC4: RXD */
{ 1, 1, 0, 1, 0, 0 }, /* PD21 SCC4: TXD */
{ 1, 1, 0, 1, 0, 0 }, /* PD20 SCC4: RTS */
{ 0, 0, 0, 0, 0, 0 }, /* PD19 */
{ 0, 0, 0, 0, 0, 0 }, /* PD18 */
{ 0, 0, 0, 0, 0, 0 }, /* PD17 */
{ 0, 0, 0, 0, 0, 0 }, /* PD16 */
#if defined(CONFIG_HARD_I2C)
{ 1, 1, 1, 0, 1, 0 }, /* PD15 I2C SDA */
{ 1, 1, 1, 0, 1, 0 }, /* PD14 I2C SCL */
#else
{ 1, 0, 0, 0, 1, 1 }, /* PD15 */
{ 1, 0, 0, 1, 1, 1 }, /* PD14 */
#endif
{ 0, 0, 0, 0, 0, 0 }, /* PD13 */
{ 0, 0, 0, 0, 0, 0 }, /* PD12 */
{ 0, 0, 0, 0, 0, 0 }, /* PD11 */
{ 0, 0, 0, 0, 0, 0 }, /* PD10 */
{ 0, 0, 0, 0, 0, 0 }, /* PD9 */
{ 0, 0, 0, 0, 0, 0 }, /* PD8 */
{ 0, 0, 0, 0, 0, 0 }, /* PD7 */
{ 0, 0, 0, 0, 0, 0 }, /* PD6 */
{ 0, 0, 0, 0, 0, 0 }, /* PD5 */
{ 0, 0, 0, 0, 0, 0 }, /* PD4 */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 }, /* non-existent */
{ 0, 0, 0, 0, 0, 0 } /* non-existent */
}
};
/*
* Try SDRAM initialization with P/LSDMR=sdmr and ORx=orx
*
* This routine performs standard 8260 initialization sequence
* and calculates the available memory size. It may be called
* several times to try different SDRAM configurations on both
* 60x and local buses.
*/
static long int try_init(memctl8260_t *memctl, ulong sdmr,
ulong orx, uchar *base)
{
uchar c = 0xff;
ulong maxsize, size;
int i;
/*
* We must be able to test a location outsize the maximum legal size
* to find out THAT we are outside; but this address still has to be
* mapped by the controller. That means, that the initial mapping has
* to be (at least) twice as large as the maximum expected size.
*/
maxsize = (1 + (~orx | 0x7fff))/* / 2*/;
out_be32(&memctl->memc_or1, orx);
/*
* Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
*
* "At system reset, initialization software must set up the
* programmable parameters in the memory controller banks registers
* (ORx, BRx, P/LSDMR). After all memory parameters are configured,
* system software should execute the following initialization sequence
* for each SDRAM device.
*
* 1. Issue a PRECHARGE-ALL-BANKS command
* 2. Issue eight CBR REFRESH commands
* 3. Issue a MODE-SET command to initialize the mode register
*
* The initial commands are executed by setting P/LSDMR[OP] and
* accessing the SDRAM with a single-byte transaction."
*
* The appropriate BRx/ORx registers have already been set when we
* get here. The SDRAM can be accessed at the address
* CONFIG_SYS_SDRAM_BASE.
*/
out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_PREA);
out_8(base, c);
out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_CBRR);
for (i = 0; i < 8; i++)
out_8(base, c);
out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_MRW);
/* setting MR on address lines */
out_8((uchar *)(base + CONFIG_SYS_MRS_OFFS), c);
out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_NORM | PSDMR_RFEN);
out_8(base, c);
size = get_ram_size((long *)base, maxsize);
out_be32(&memctl->memc_or1, orx | ~(size - 1));
return size;
}
#ifdef CONFIG_SYS_SDRAM_LIST
/*
* If CONFIG_SYS_SDRAM_LIST is defined, we cycle through all SDRAM
* configurations therein (should be from high to lower) to find the
* one actually matching the current configuration.
* CONFIG_SYS_PSDMR and CONFIG_SYS_OR1 will contain the base values which are
* common among all possible configurations; values in CONFIG_SYS_SDRAM_LIST
* (defined as the initialization value for the array of struct sdram_conf_s)
* will then be ORed with such base values.
*/
struct sdram_conf_s {
ulong size;
int or1;
int psdmr;
};
static struct sdram_conf_s sdram_conf[] = CONFIG_SYS_SDRAM_LIST;
static long probe_sdram(memctl8260_t *memctl)
{
int n = 0;
long psize = 0;
for (n = 0; n < ARRAY_SIZE(sdram_conf); psize = 0, n++) {
psize = try_init(memctl,
CONFIG_SYS_PSDMR | sdram_conf[n].psdmr,
CONFIG_SYS_OR1 | sdram_conf[n].or1,
(uchar *) CONFIG_SYS_SDRAM_BASE);
debug("Probing %ld bytes returned %ld\n",
sdram_conf[n].size, psize);
if (psize == sdram_conf[n].size)
break;
}
return psize;
}
#else /* CONFIG_SYS_SDRAM_LIST */
static long probe_sdram(memctl8260_t *memctl)
{
return try_init(memctl, CONFIG_SYS_PSDMR, CONFIG_SYS_OR1,
(uchar *) CONFIG_SYS_SDRAM_BASE);
}
#endif /* CONFIG_SYS_SDRAM_LIST */
phys_size_t initdram(void)
{
immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
memctl8260_t *memctl = &immap->im_memctl;
long psize;
out_8(&memctl->memc_psrt, CONFIG_SYS_PSRT);
out_be16(&memctl->memc_mptpr, CONFIG_SYS_MPTPR);
/* 60x SDRAM setup:
*/
psize = probe_sdram(memctl);
icache_enable();
return psize;
}
int checkboard(void)
{
#if defined(CONFIG_MGCOGE)
puts("Board: Keymile mgcoge");
#else
puts("Board: Keymile mgcoge3ne");
#endif
if (ethernet_present())
puts(" with PIGGY.");
puts("\n");
return 0;
}
int last_stage_init(void)
{
struct bfticu_iomap *base =
(struct bfticu_iomap *)CONFIG_SYS_FPGA_BASE;
u8 dip_switch;
dip_switch = in_8(&base->mswitch);
dip_switch &= BFTICU_DIPSWITCH_MASK;
/* dip switch 'full reset' or 'db erase' or 'Local mgmt IP' or any */
if (dip_switch != 0) {
/* start bootloader */
puts("DIP: Enabled\n");
setenv("actual_bank", "0");
}
set_km_env();
return 0;
}
#ifdef CONFIG_MGCOGE3NE
static void set_pin(int state, unsigned long mask, int port);
/*
* For mgcoge3ne boards, the mgcoge3un control is controlled from
* a GPIO line on the PPC CPU. If bobcatreset is set the line
* will toggle once what forces the mgocge3un part to restart
* immediately.
*/
static void handle_mgcoge3un_reset(void)
{
char *bobcatreset = getenv("bobcatreset");
if (bobcatreset) {
if (strcmp(bobcatreset, "true") == 0) {
puts("Forcing bobcat reset\n");
set_pin(0, 0x00000004, 3); /* clear PD29 (reset arm) */
udelay(1000);
set_pin(1, 0x00000004, 3);
} else
set_pin(1, 0x00000004, 3); /* don't reset arm */
}
}
#endif
int ethernet_present(void)
{
struct km_bec_fpga *base =
(struct km_bec_fpga *)CONFIG_SYS_KMBEC_FPGA_BASE;
return in_8(&base->bprth) & PIGGY_PRESENT;
}
/*
* Early board initalization.
*/
int board_early_init_r(void)
{
struct km_bec_fpga *base =
(struct km_bec_fpga *)CONFIG_SYS_KMBEC_FPGA_BASE;
/* setup the UPIOx */
/* General Unit Reset disabled, Flash Bank enabled, UnitLed on */
out_8(&base->oprth, (WRG_RESET | H_OPORTS_14 | WRG_LED));
/* SCC4 enable, halfduplex, FCC1 powerdown */
out_8(&base->oprtl, (H_OPORTS_SCC4_ENA | H_OPORTS_SCC4_FD_ENA |
H_OPORTS_FCC1_PW_DWN));
#ifdef CONFIG_MGCOGE3NE
handle_mgcoge3un_reset();
#endif
return 0;
}
int misc_init_r(void)
{
ivm_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
return 0;
}
int hush_init_var(void)
{
ivm_analyze_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
return 0;
}
#define SDA_MASK 0x00010000
#define SCL_MASK 0x00020000
static void set_pin(int state, unsigned long mask, int port)
{
ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, port);
if (state)
setbits_be32(&iop->pdat, mask);
else
clrbits_be32(&iop->pdat, mask);
setbits_be32(&iop->pdir, mask);
}
static int get_pin(unsigned long mask, int port)
{
ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, port);
clrbits_be32(&iop->pdir, mask);
return 0 != (in_be32(&iop->pdat) & mask);
}
void set_sda(int state)
{
set_pin(state, SDA_MASK, 3);
}
void set_scl(int state)
{
set_pin(state, SCL_MASK, 3);
}
int get_sda(void)
{
return get_pin(SDA_MASK, 3);
}
int get_scl(void)
{
return get_pin(SCL_MASK, 3);
}
int ft_board_setup(void *blob, bd_t *bd)
{
ft_cpu_setup(blob, bd);
return 0;
}
#if defined(CONFIG_MGCOGE3NE)
int get_testpin(void)
{
/* Testpin is Port C pin 29 - enable = low */
int testpin = !get_pin(0x00000004, 2);
return testpin;
}
#endif