mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-11 13:56:30 +00:00
e895a4b06f
This function can fail if the device tree runs out of space. Rather than silently booting with an incomplete device tree, allow the failure to be detected. Unfortunately this involves changing a lot of places in the code. I have not changed behvaiour to return an error where one is not currently returned, to avoid unexpected breakage. Eventually it would be nice to allow boards to register functions to be called to update the device tree. This would avoid all the many functions to do this. However it's not clear yet if this should be done using driver model or with a linker list. This work is left for later. Signed-off-by: Simon Glass <sjg@chromium.org> Acked-by: Anatolij Gustschin <agust@denx.de>
242 lines
5.1 KiB
C
242 lines
5.1 KiB
C
/*
|
|
* Copyright 2004 Freescale Semiconductor.
|
|
* (C) Copyright 2002,2003, Motorola Inc.
|
|
* Xianghua Xiao, (X.Xiao@motorola.com)
|
|
*
|
|
* (C) Copyright 2002 Scott McNutt <smcnutt@artesyncp.com>
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
*/
|
|
|
|
|
|
#include <common.h>
|
|
#include <pci.h>
|
|
#include <asm/processor.h>
|
|
#include <asm/mmu.h>
|
|
#include <asm/immap_85xx.h>
|
|
#include <fsl_ddr_sdram.h>
|
|
#include <libfdt.h>
|
|
#include <fdt_support.h>
|
|
|
|
#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
|
|
extern void ddr_enable_ecc(unsigned int dram_size);
|
|
#endif
|
|
|
|
void local_bus_init(void);
|
|
|
|
int checkboard (void)
|
|
{
|
|
puts("Board: ADS\n");
|
|
|
|
#ifdef CONFIG_PCI
|
|
printf("PCI1: 32 bit, %d MHz (compiled)\n",
|
|
CONFIG_SYS_CLK_FREQ / 1000000);
|
|
#else
|
|
printf("PCI1: disabled\n");
|
|
#endif
|
|
|
|
/*
|
|
* Initialize local bus.
|
|
*/
|
|
local_bus_init();
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Initialize Local Bus
|
|
*/
|
|
|
|
void
|
|
local_bus_init(void)
|
|
{
|
|
volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
|
|
volatile fsl_lbc_t *lbc = LBC_BASE_ADDR;
|
|
|
|
uint clkdiv;
|
|
uint lbc_hz;
|
|
sys_info_t sysinfo;
|
|
|
|
/*
|
|
* Errata LBC11.
|
|
* Fix Local Bus clock glitch when DLL is enabled.
|
|
*
|
|
* If localbus freq is < 66MHz, DLL bypass mode must be used.
|
|
* If localbus freq is > 133MHz, DLL can be safely enabled.
|
|
* Between 66 and 133, the DLL is enabled with an override workaround.
|
|
*/
|
|
|
|
get_sys_info(&sysinfo);
|
|
clkdiv = lbc->lcrr & LCRR_CLKDIV;
|
|
lbc_hz = sysinfo.freq_systembus / 1000000 / clkdiv;
|
|
|
|
if (lbc_hz < 66) {
|
|
lbc->lcrr = CONFIG_SYS_LBC_LCRR | LCRR_DBYP; /* DLL Bypass */
|
|
|
|
} else if (lbc_hz >= 133) {
|
|
lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~LCRR_DBYP); /* DLL Enabled */
|
|
|
|
} else {
|
|
/*
|
|
* On REV1 boards, need to change CLKDIV before enable DLL.
|
|
* Default CLKDIV is 8, change it to 4 temporarily.
|
|
*/
|
|
uint pvr = get_pvr();
|
|
uint temp_lbcdll = 0;
|
|
|
|
if (pvr == PVR_85xx_REV1) {
|
|
/* FIXME: Justify the high bit here. */
|
|
lbc->lcrr = 0x10000004;
|
|
}
|
|
|
|
lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~LCRR_DBYP); /* DLL Enabled */
|
|
udelay(200);
|
|
|
|
/*
|
|
* Sample LBC DLL ctrl reg, upshift it to set the
|
|
* override bits.
|
|
*/
|
|
temp_lbcdll = gur->lbcdllcr;
|
|
gur->lbcdllcr = (((temp_lbcdll & 0xff) << 16) | 0x80000000);
|
|
asm("sync;isync;msync");
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* Initialize SDRAM memory on the Local Bus.
|
|
*/
|
|
void lbc_sdram_init(void)
|
|
{
|
|
volatile fsl_lbc_t *lbc = LBC_BASE_ADDR;
|
|
uint *sdram_addr = (uint *)CONFIG_SYS_LBC_SDRAM_BASE;
|
|
|
|
puts("LBC SDRAM: ");
|
|
print_size(CONFIG_SYS_LBC_SDRAM_SIZE * 1024 * 1024,
|
|
"\n ");
|
|
|
|
/*
|
|
* Setup SDRAM Base and Option Registers
|
|
*/
|
|
set_lbc_or(2, CONFIG_SYS_OR2_PRELIM);
|
|
set_lbc_br(2, CONFIG_SYS_BR2_PRELIM);
|
|
lbc->lbcr = CONFIG_SYS_LBC_LBCR;
|
|
asm("msync");
|
|
|
|
lbc->lsrt = CONFIG_SYS_LBC_LSRT;
|
|
lbc->mrtpr = CONFIG_SYS_LBC_MRTPR;
|
|
asm("sync");
|
|
|
|
/*
|
|
* Configure the SDRAM controller.
|
|
*/
|
|
lbc->lsdmr = CONFIG_SYS_LBC_LSDMR_1;
|
|
asm("sync");
|
|
*sdram_addr = 0xff;
|
|
ppcDcbf((unsigned long) sdram_addr);
|
|
udelay(100);
|
|
|
|
lbc->lsdmr = CONFIG_SYS_LBC_LSDMR_2;
|
|
asm("sync");
|
|
*sdram_addr = 0xff;
|
|
ppcDcbf((unsigned long) sdram_addr);
|
|
udelay(100);
|
|
|
|
lbc->lsdmr = CONFIG_SYS_LBC_LSDMR_3;
|
|
asm("sync");
|
|
*sdram_addr = 0xff;
|
|
ppcDcbf((unsigned long) sdram_addr);
|
|
udelay(100);
|
|
|
|
lbc->lsdmr = CONFIG_SYS_LBC_LSDMR_4;
|
|
asm("sync");
|
|
*sdram_addr = 0xff;
|
|
ppcDcbf((unsigned long) sdram_addr);
|
|
udelay(100);
|
|
|
|
lbc->lsdmr = CONFIG_SYS_LBC_LSDMR_5;
|
|
asm("sync");
|
|
*sdram_addr = 0xff;
|
|
ppcDcbf((unsigned long) sdram_addr);
|
|
udelay(100);
|
|
}
|
|
|
|
#if !defined(CONFIG_SPD_EEPROM)
|
|
/*************************************************************************
|
|
* fixed sdram init -- doesn't use serial presence detect.
|
|
************************************************************************/
|
|
phys_size_t fixed_sdram(void)
|
|
{
|
|
#ifndef CONFIG_SYS_RAMBOOT
|
|
struct ccsr_ddr __iomem *ddr =
|
|
(struct ccsr_ddr __iomem *)(CONFIG_SYS_FSL_DDR_ADDR);
|
|
|
|
ddr->cs0_bnds = CONFIG_SYS_DDR_CS0_BNDS;
|
|
ddr->cs0_config = CONFIG_SYS_DDR_CS0_CONFIG;
|
|
ddr->timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1;
|
|
ddr->timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2;
|
|
ddr->sdram_mode = CONFIG_SYS_DDR_MODE;
|
|
ddr->sdram_interval = CONFIG_SYS_DDR_INTERVAL;
|
|
#if defined (CONFIG_DDR_ECC)
|
|
ddr->err_disable = 0x0000000D;
|
|
ddr->err_sbe = 0x00ff0000;
|
|
#endif
|
|
asm("sync;isync;msync");
|
|
udelay(500);
|
|
#if defined (CONFIG_DDR_ECC)
|
|
/* Enable ECC checking */
|
|
ddr->sdram_cfg = (CONFIG_SYS_DDR_CONTROL | 0x20000000);
|
|
#else
|
|
ddr->sdram_cfg = CONFIG_SYS_DDR_CONTROL;
|
|
#endif
|
|
asm("sync; isync; msync");
|
|
udelay(500);
|
|
#endif
|
|
return CONFIG_SYS_SDRAM_SIZE * 1024 * 1024;
|
|
}
|
|
#endif /* !defined(CONFIG_SPD_EEPROM) */
|
|
|
|
|
|
#if defined(CONFIG_PCI)
|
|
/*
|
|
* Initialize PCI Devices, report devices found.
|
|
*/
|
|
|
|
|
|
static struct pci_controller hose;
|
|
|
|
#endif /* CONFIG_PCI */
|
|
|
|
|
|
void
|
|
pci_init_board(void)
|
|
{
|
|
#ifdef CONFIG_PCI
|
|
pci_mpc85xx_init(&hose);
|
|
#endif /* CONFIG_PCI */
|
|
}
|
|
|
|
|
|
#if defined(CONFIG_OF_BOARD_SETUP)
|
|
int ft_board_setup(void *blob, bd_t *bd)
|
|
{
|
|
int node, tmp[2];
|
|
const char *path;
|
|
|
|
ft_cpu_setup(blob, bd);
|
|
|
|
node = fdt_path_offset(blob, "/aliases");
|
|
tmp[0] = 0;
|
|
if (node >= 0) {
|
|
#ifdef CONFIG_PCI
|
|
path = fdt_getprop(blob, node, "pci0", NULL);
|
|
if (path) {
|
|
tmp[1] = hose.last_busno - hose.first_busno;
|
|
do_fixup_by_path(blob, path, "bus-range", &tmp, 8, 1);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif
|