commit
e825b100d2
@ -0,0 +1,72 @@ |
||||
/*
|
||||
* Copyright (C) 2013 Stefan Roese <sr@denx.de> |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <spl.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
/*
|
||||
* Return selected boot device. On PPC4xx its only NOR flash right now. |
||||
*/ |
||||
u32 spl_boot_device(void) |
||||
{ |
||||
return BOOT_DEVICE_NOR; |
||||
} |
||||
|
||||
/*
|
||||
* SPL version of board_init_f() |
||||
*/ |
||||
void board_init_f(ulong bootflag) |
||||
{ |
||||
/*
|
||||
* First we need to initialize the SDRAM, so that the real |
||||
* U-Boot or the OS (Linux) can be loaded |
||||
*/ |
||||
initdram(0); |
||||
|
||||
/* Clear bss */ |
||||
memset(__bss_start, '\0', __bss_end - __bss_start); |
||||
|
||||
/*
|
||||
* Init global_data pointer. Has to be done before calling |
||||
* get_clocks(), as it stores some clock values into gd needed |
||||
* later on in the serial driver. |
||||
*/ |
||||
/* Pointer is writable since we allocated a register for it */ |
||||
gd = (gd_t *)(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); |
||||
/* Clear initial global data */ |
||||
memset((void *)gd, 0, sizeof(gd_t)); |
||||
|
||||
/*
|
||||
* get_clocks() needs to be called so that the serial driver |
||||
* works correctly |
||||
*/ |
||||
get_clocks(); |
||||
|
||||
/*
|
||||
* Do rudimental console / serial setup |
||||
*/ |
||||
preloader_console_init(); |
||||
|
||||
/*
|
||||
* Call board_init_r() (SPL framework version) to load and boot |
||||
* real U-Boot or OS |
||||
*/ |
||||
board_init_r(NULL, 0); |
||||
/* Does not return!!! */ |
||||
} |
@ -0,0 +1,74 @@ |
||||
/* |
||||
* Copyright 2012-2013 Stefan Roese <sr@denx.de> |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
*/ |
||||
|
||||
MEMORY |
||||
{ |
||||
sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, |
||||
LENGTH = CONFIG_SPL_BSS_MAX_SIZE |
||||
flash : ORIGIN = CONFIG_SPL_TEXT_BASE, |
||||
LENGTH = CONFIG_SYS_SPL_MAX_LEN |
||||
} |
||||
|
||||
OUTPUT_ARCH(powerpc) |
||||
ENTRY(_start) |
||||
SECTIONS |
||||
{ |
||||
#ifdef CONFIG_440 |
||||
.bootpg 0xfffff000 : |
||||
{ |
||||
arch/powerpc/cpu/ppc4xx/start.o (.bootpg) |
||||
|
||||
/* |
||||
* PPC440 board need a board specific object with the |
||||
* TLB definitions. This needs to get included right after |
||||
* start.o, since the first shadow TLB only covers 4k |
||||
* of address space. |
||||
*/ |
||||
CONFIG_BOARDDIR/init.o (.bootpg) |
||||
} > flash |
||||
#endif |
||||
|
||||
.resetvec 0xFFFFFFFC : |
||||
{ |
||||
KEEP(*(.resetvec)) |
||||
} > flash |
||||
|
||||
.text : |
||||
{ |
||||
__start = .; |
||||
arch/powerpc/cpu/ppc4xx/start.o (.text) |
||||
CONFIG_BOARDDIR/init.o (.text) |
||||
*(.text*) |
||||
} > flash |
||||
|
||||
. = ALIGN(4); |
||||
.data : { *(SORT_BY_ALIGNMENT(.data*)) } > flash |
||||
|
||||
. = ALIGN(4); |
||||
.rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } > flash |
||||
|
||||
.bss : |
||||
{ |
||||
. = ALIGN(4); |
||||
__bss_start = .; |
||||
*(.bss*) |
||||
. = ALIGN(4); |
||||
__bss_end = .; |
||||
} > sdram |
||||
} |
@ -1,285 +0,0 @@ |
||||
/*
|
||||
* Copyright (c) 2011 The Chromium OS Authors. |
||||
* |
||||
* (C) Copyright 2002-2006 |
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
||||
* |
||||
* (C) Copyright 2002 |
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com> |
||||
* Marius Groeger <mgroeger@sysgo.de> |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
*/ |
||||
|
||||
/*
|
||||
* This file was taken from ARM and changed to remove things we don't |
||||
* need. This is most of it, so have tried to avoid being over-zealous! |
||||
* For example, we want to have an emulation of the 'DRAM' used by |
||||
* U-Boot. |
||||
* |
||||
* has been talk upstream of unifying the architectures w.r.t board.c, |
||||
* so the less change here the better. |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <command.h> |
||||
#include <malloc.h> |
||||
#include <stdio_dev.h> |
||||
#include <timestamp.h> |
||||
#include <version.h> |
||||
#include <serial.h> |
||||
|
||||
#include <os.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
static gd_t gd_mem; |
||||
|
||||
/************************************************************************
|
||||
* Init Utilities * |
||||
************************************************************************ |
||||
* Some of this code should be moved into the core functions, |
||||
* or dropped completely, |
||||
* but let's get it working (again) first... |
||||
*/ |
||||
|
||||
static int display_banner(void) |
||||
{ |
||||
display_options(); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/**
|
||||
* Configure and report on the DRAM configuration, which in our case is |
||||
* fairly simple. |
||||
*/ |
||||
static int display_dram_config(void) |
||||
{ |
||||
ulong size = 0; |
||||
int i; |
||||
|
||||
debug("RAM Configuration:\n"); |
||||
|
||||
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { |
||||
#ifdef DEBUG |
||||
printf("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start); |
||||
print_size(gd->bd->bi_dram[i].size, "\n"); |
||||
#endif |
||||
size += gd->bd->bi_dram[i].size; |
||||
} |
||||
puts("DRAM: "); |
||||
print_size(size, "\n"); |
||||
return 0; |
||||
} |
||||
|
||||
/*
|
||||
* Breathe some life into the board... |
||||
* |
||||
* Initialize a serial port as console, and carry out some hardware |
||||
* tests. |
||||
* |
||||
* The first part of initialization is running from Flash memory; |
||||
* its main purpose is to initialize the RAM so that we |
||||
* can relocate the monitor code to RAM. |
||||
*/ |
||||
|
||||
/*
|
||||
* All attempts to come up with a "common" initialization sequence |
||||
* that works for all boards and architectures failed: some of the |
||||
* requirements are just _too_ different. To get rid of the resulting |
||||
* mess of board dependent #ifdef'ed code we now make the whole |
||||
* initialization sequence configurable to the user. |
||||
* |
||||
* The requirements for any new initalization function is simple: it |
||||
* receives a pointer to the "global data" structure as it's only |
||||
* argument, and returns an integer return code, where 0 means |
||||
* "continue" and != 0 means "fatal error, hang the system". |
||||
*/ |
||||
typedef int (init_fnc_t) (void); |
||||
|
||||
void __dram_init_banksize(void) |
||||
{ |
||||
gd->bd->bi_dram[0].start = 0; |
||||
gd->bd->bi_dram[0].size = gd->ram_size; |
||||
} |
||||
|
||||
void dram_init_banksize(void) |
||||
__attribute__((weak, alias("__dram_init_banksize"))); |
||||
|
||||
init_fnc_t *init_sequence[] = { |
||||
#if defined(CONFIG_ARCH_CPU_INIT) |
||||
arch_cpu_init, /* basic arch cpu dependent setup */ |
||||
#endif |
||||
#if defined(CONFIG_BOARD_EARLY_INIT_F) |
||||
board_early_init_f, |
||||
#endif |
||||
timer_init, /* initialize timer */ |
||||
env_init, /* initialize environment */ |
||||
serial_init, /* serial communications setup */ |
||||
console_init_f, /* stage 1 init of console */ |
||||
sandbox_early_getopt_check, /* process command line flags (err/help) */ |
||||
display_banner, /* say that we are here */ |
||||
#if defined(CONFIG_DISPLAY_CPUINFO) |
||||
print_cpuinfo, /* display cpu info (and speed) */ |
||||
#endif |
||||
#if defined(CONFIG_DISPLAY_BOARDINFO) |
||||
checkboard, /* display board info */ |
||||
#endif |
||||
dram_init, /* configure available RAM banks */ |
||||
NULL, |
||||
}; |
||||
|
||||
void board_init_f(ulong bootflag) |
||||
{ |
||||
init_fnc_t **init_fnc_ptr; |
||||
uchar *mem; |
||||
unsigned long addr_sp, addr, size; |
||||
|
||||
gd = &gd_mem; |
||||
assert(gd); |
||||
|
||||
memset((void *)gd, 0, sizeof(gd_t)); |
||||
|
||||
#if defined(CONFIG_OF_EMBED) |
||||
/* Get a pointer to the FDT */ |
||||
gd->fdt_blob = _binary_dt_dtb_start; |
||||
#elif defined(CONFIG_OF_SEPARATE) |
||||
/* FDT is at end of image */ |
||||
gd->fdt_blob = (void *)(_end_ofs + _TEXT_BASE); |
||||
#endif |
||||
|
||||
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { |
||||
if ((*init_fnc_ptr)() != 0) |
||||
hang(); |
||||
} |
||||
|
||||
size = CONFIG_SYS_SDRAM_SIZE; |
||||
mem = os_malloc(CONFIG_SYS_SDRAM_SIZE); |
||||
|
||||
assert(mem); |
||||
gd->arch.ram_buf = mem; |
||||
addr = (ulong)(mem + size); |
||||
|
||||
/*
|
||||
* reserve memory for malloc() arena |
||||
*/ |
||||
addr_sp = addr - TOTAL_MALLOC_LEN; |
||||
debug("Reserving %dk for malloc() at: %08lx\n", |
||||
TOTAL_MALLOC_LEN >> 10, addr_sp); |
||||
/*
|
||||
* (permanently) allocate a Board Info struct |
||||
* and a permanent copy of the "global" data |
||||
*/ |
||||
addr_sp -= sizeof(bd_t); |
||||
gd->bd = (bd_t *) addr_sp; |
||||
debug("Reserving %zu Bytes for Board Info at: %08lx\n", |
||||
sizeof(bd_t), addr_sp); |
||||
|
||||
/* Ram ist board specific, so move it to board code ... */ |
||||
dram_init_banksize(); |
||||
display_dram_config(); /* and display it */ |
||||
|
||||
/* We don't relocate, so just run the post-relocation code */ |
||||
board_init_r(NULL, 0); |
||||
|
||||
/* NOTREACHED - no way out of command loop except booting */ |
||||
} |
||||
|
||||
/************************************************************************
|
||||
* |
||||
* This is the next part if the initialization sequence: we are now |
||||
* running from RAM and have a "normal" C environment, i. e. global |
||||
* data can be written, BSS has been cleared, the stack size in not |
||||
* that critical any more, etc. |
||||
* |
||||
************************************************************************ |
||||
*/ |
||||
|
||||
void board_init_r(gd_t *id, ulong dest_addr) |
||||
{ |
||||
|
||||
if (id) |
||||
gd = id; |
||||
|
||||
gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ |
||||
|
||||
serial_initialize(); |
||||
|
||||
#ifdef CONFIG_POST |
||||
post_output_backlog(); |
||||
#endif |
||||
|
||||
/* The Malloc area is at the top of simulated DRAM */ |
||||
mem_malloc_init((ulong)gd->arch.ram_buf + gd->ram_size - |
||||
TOTAL_MALLOC_LEN, TOTAL_MALLOC_LEN); |
||||
|
||||
/* initialize environment */ |
||||
env_relocate(); |
||||
|
||||
stdio_init(); /* get the devices list going. */ |
||||
|
||||
jumptable_init(); |
||||
|
||||
console_init_r(); /* fully init console as a device */ |
||||
|
||||
#if defined(CONFIG_DISPLAY_BOARDINFO_LATE) |
||||
checkboard(); |
||||
#endif |
||||
|
||||
#if defined(CONFIG_ARCH_MISC_INIT) |
||||
/* miscellaneous arch dependent initialisations */ |
||||
arch_misc_init(); |
||||
#endif |
||||
#if defined(CONFIG_MISC_INIT_R) |
||||
/* miscellaneous platform dependent initialisations */ |
||||
misc_init_r(); |
||||
#endif |
||||
|
||||
/* set up exceptions */ |
||||
interrupt_init(); |
||||
/* enable exceptions */ |
||||
enable_interrupts(); |
||||
|
||||
#ifdef CONFIG_BOARD_LATE_INIT |
||||
board_late_init(); |
||||
#endif |
||||
|
||||
#ifdef CONFIG_POST |
||||
post_run(NULL, POST_RAM | post_bootmode_get(0)); |
||||
#endif |
||||
|
||||
sandbox_main_loop_init(); |
||||
|
||||
/*
|
||||
* For now, run the main loop. Later we might let this be done |
||||
* in the main program. |
||||
*/ |
||||
while (1) |
||||
main_loop(); |
||||
|
||||
/* NOTREACHED - no way out of command loop except booting */ |
||||
} |
||||
|
||||
void hang(void) |
||||
{ |
||||
puts("### ERROR ### Please RESET the board ###\n"); |
||||
for (;;) |
||||
; |
||||
} |
@ -0,0 +1,129 @@ |
||||
/*
|
||||
* Copyright 2011 Freescale Semiconductor, Inc. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
* |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <ns16550.h> |
||||
#include <asm/io.h> |
||||
#include <nand.h> |
||||
#include <asm/fsl_law.h> |
||||
#include <asm/fsl_ddr_sdram.h> |
||||
|
||||
|
||||
/*
|
||||
* Fixed sdram init -- doesn't use serial presence detect. |
||||
*/ |
||||
void sdram_init(void) |
||||
{ |
||||
volatile ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC8xxx_DDR_ADDR; |
||||
|
||||
__raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds); |
||||
__raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config); |
||||
#if CONFIG_CHIP_SELECTS_PER_CTRL > 1 |
||||
__raw_writel(CONFIG_SYS_DDR_CS1_BNDS, &ddr->cs1_bnds); |
||||
__raw_writel(CONFIG_SYS_DDR_CS1_CONFIG, &ddr->cs1_config); |
||||
#endif |
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_3, &ddr->timing_cfg_3); |
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_0, &ddr->timing_cfg_0); |
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_1, &ddr->timing_cfg_1); |
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_2, &ddr->timing_cfg_2); |
||||
|
||||
__raw_writel(CONFIG_SYS_DDR_CONTROL_2, &ddr->sdram_cfg_2); |
||||
__raw_writel(CONFIG_SYS_DDR_MODE_1, &ddr->sdram_mode); |
||||
__raw_writel(CONFIG_SYS_DDR_MODE_2, &ddr->sdram_mode_2); |
||||
|
||||
__raw_writel(CONFIG_SYS_DDR_INTERVAL, &ddr->sdram_interval); |
||||
__raw_writel(CONFIG_SYS_DDR_DATA_INIT, &ddr->sdram_data_init); |
||||
__raw_writel(CONFIG_SYS_DDR_CLK_CTRL, &ddr->sdram_clk_cntl); |
||||
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_4, &ddr->timing_cfg_4); |
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_5, &ddr->timing_cfg_5); |
||||
__raw_writel(CONFIG_SYS_DDR_ZQ_CONTROL, &ddr->ddr_zq_cntl); |
||||
__raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL, &ddr->ddr_wrlvl_cntl); |
||||
|
||||
/* Set, but do not enable the memory */ |
||||
__raw_writel(CONFIG_SYS_DDR_CONTROL & ~SDRAM_CFG_MEM_EN, |
||||
&ddr->sdram_cfg); |
||||
|
||||
in_be32(&ddr->sdram_cfg); |
||||
udelay(500); |
||||
|
||||
/* Let the controller go */ |
||||
out_be32(&ddr->sdram_cfg, in_be32(&ddr->sdram_cfg) | SDRAM_CFG_MEM_EN); |
||||
in_be32(&ddr->sdram_cfg); |
||||
|
||||
set_next_law(0, CONFIG_SYS_SDRAM_SIZE_LAW, LAW_TRGT_IF_DDR_1); |
||||
} |
||||
|
||||
const static u32 sysclk_tbl[] = { |
||||
66666000, 7499900, 83332500, 8999900, |
||||
99999000, 11111000, 12499800, 13333200 |
||||
}; |
||||
|
||||
void board_init_f(ulong bootflag) |
||||
{ |
||||
int px_spd; |
||||
u32 plat_ratio, sys_clk, bus_clk; |
||||
ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; |
||||
|
||||
/* for FPGA */ |
||||
set_lbc_br(2, CONFIG_SYS_BR2_PRELIM); |
||||
set_lbc_or(2, CONFIG_SYS_OR2_PRELIM); |
||||
|
||||
/* initialize selected port with appropriate baud rate */ |
||||
px_spd = in_8((unsigned char *)(PIXIS_BASE + PIXIS_SPD)); |
||||
sys_clk = sysclk_tbl[px_spd & PIXIS_SPD_SYSCLK_MASK]; |
||||
plat_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_PLAT_RATIO; |
||||
bus_clk = sys_clk * plat_ratio / 2; |
||||
|
||||
NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1, |
||||
bus_clk / 16 / CONFIG_BAUDRATE); |
||||
|
||||
puts("\nNAND boot... "); |
||||
|
||||
/* Initialize the DDR3 */ |
||||
sdram_init(); |
||||
|
||||
/* copy code to RAM and jump to it - this should not return */ |
||||
/* NOTE - code has to be copied out of NAND buffer before
|
||||
* other blocks can be read. |
||||
*/ |
||||
relocate_code(CONFIG_SPL_RELOC_STACK, 0, |
||||
CONFIG_SPL_RELOC_TEXT_BASE); |
||||
} |
||||
|
||||
void board_init_r(gd_t *gd, ulong dest_addr) |
||||
{ |
||||
nand_boot(); |
||||
} |
||||
|
||||
void putc(char c) |
||||
{ |
||||
if (c == '\n') |
||||
NS16550_putc((NS16550_t)CONFIG_SYS_NS16550_COM1, '\r'); |
||||
|
||||
NS16550_putc((NS16550_t)CONFIG_SYS_NS16550_COM1, c); |
||||
} |
||||
|
||||
void puts(const char *str) |
||||
{ |
||||
while (*str) |
||||
putc(*str++); |
||||
} |
@ -0,0 +1,199 @@ |
||||
Overview |
||||
========= |
||||
The P1010RDB is a Freescale reference design board that hosts the P1010 SoC. |
||||
|
||||
The P1010 is a cost-effective, low-power, highly integrated host processor |
||||
based on a Power Architecture e500v2 core (maximum core frequency 800/1000 MHz), |
||||
that addresses the requirements of several routing, gateways, storage, consumer, |
||||
and industrial applications. Applications of interest include the main CPUs and |
||||
I/O processors in network attached storage (NAS), the voice over IP (VoIP) |
||||
router/gateway, and wireless LAN (WLAN) and industrial controllers. |
||||
|
||||
The P1010RDB board features are as follows: |
||||
Memory subsystem: |
||||
- 1Gbyte unbuffered DDR3 SDRAM discrete devices (32-bit bus) |
||||
- 32 Mbyte NOR flash single-chip memory |
||||
- 32 Mbyte NAND flash memory |
||||
- 256 Kbit M24256 I2C EEPROM |
||||
- 16 Mbyte SPI memory |
||||
- I2C Board EEPROM 128x8 bit memory |
||||
- SD/MMC connector to interface with the SD memory card |
||||
Interfaces: |
||||
- PCIe: |
||||
- Lane0: x1 mini-PCIe slot |
||||
- Lane1: x1 PCIe standard slot |
||||
- SATA: |
||||
- 1 internal SATA connector to 2.5" 160G SATA2 HDD |
||||
- 1 eSATA connector to rear panel |
||||
- 10/100/1000 BaseT Ethernet ports: |
||||
- eTSEC1, RGMII: one 10/100/1000 port using Vitesse VSC8641XKO |
||||
- eTSEC2, SGMII: one 10/100/1000 port using Vitesse VSC8221 |
||||
- eTSEC3, SGMII: one 10/100/1000 port using Vitesse VSC8221 |
||||
- USB 2.0 port: |
||||
- x1 USB2.0 port: via an ULPI PHY to micro-AB connector |
||||
- x1 USB2.0 poort via an internal PHY to micro-AB connector |
||||
- FlexCAN ports: |
||||
- x2 DB-9 female connectors for FlexCAN bus(revision 2.0B) |
||||
interface; |
||||
- DUART interface: |
||||
- DUART interface: supports two UARTs up to 115200 bps for |
||||
console display |
||||
- J45 connectors are used for these 2 UART ports. |
||||
- TDM |
||||
- 2 FXS ports connected via an external SLIC to the TDM |
||||
interface. SLIC is controllled via SPI. |
||||
- 1 FXO port connected via a relay to FXS for switchover to |
||||
POTS |
||||
Board connectors: |
||||
- Mini-ITX power supply connector |
||||
- JTAG/COP for debugging |
||||
IEEE Std. 1588 signals for test and measurement |
||||
Real-time clock on I2C bus |
||||
POR |
||||
- support critical POR setting changed via switch on board |
||||
PCB |
||||
- 6-layer routing (4-layer signals, 2-layer power and ground) |
||||
|
||||
|
||||
Serial Port Configuration on P1010RDB |
||||
===================================== |
||||
Configure the serial port of the attached computer with the following values: |
||||
-Data rate: 115200 bps |
||||
-Number of data bits: 8 |
||||
-Parity: None |
||||
-Number of Stop bits: 1 |
||||
-Flow Control: Hardware/None |
||||
|
||||
|
||||
Settings of DIP-switch |
||||
====================== |
||||
SW4[1:4]= 1111 and SW6[4]=0 for boot from 16bit NOR flash |
||||
SW4[1:4]= 1000 and SW6[4]=1 for boot from 8bit NAND flash |
||||
SW4[1:4]= 0110 and SW6[4]=0 for boot from SPI flash |
||||
Note: 1 stands for 'on', 0 stands for 'off' |
||||
|
||||
|
||||
Setting of hwconfig |
||||
=================== |
||||
If FlexCAN or TDM is needed, please set "fsl_p1010mux:tdm_can=can" or |
||||
"fsl_p1010mux:tdm_can=tdm" explicitly in u-booot prompt as below for example: |
||||
setenv hwconfig "fsl_p1010mux:tdm_can=tdm;usb1:dr_mode=host,phy_type=utmi" |
||||
By default, don't set fsl_p1010mux:tdm_can, in this case, spi chip selection |
||||
is set to spi-flash instead of to SLIC/TDM/DAC and tdm_can_sel is set to TDM |
||||
instead of to CAN/UART1. |
||||
|
||||
|
||||
Build and burn u-boot to NOR flash |
||||
================================== |
||||
1. Build u-boot.bin image |
||||
export ARCH=powerpc |
||||
export CROSS_COMPILE=/your_path/powerpc-linux-gnu- |
||||
make P1010RDB_NOR |
||||
|
||||
2. Burn u-boot.bin into NOR flash |
||||
=> tftp $loadaddr $uboot |
||||
=> protect off eff80000 +$filesize |
||||
=> erase eff80000 +$filesize |
||||
=> cp.b $loadaddr eff80000 $filesize |
||||
|
||||
3. Check SW4[1:4]= 1111 and SW6[4]=0, then power on. |
||||
|
||||
|
||||
Alternate NOR bank |
||||
============================ |
||||
1. Burn u-boot.bin into alternate NOR bank |
||||
=> tftp $loadaddr $uboot |
||||
=> protect off eef80000 +$filesize |
||||
=> erase eef80000 +$filesize |
||||
=> cp.b $loadaddr eef80000 $filesize |
||||
|
||||
2. Switch to alternate NOR bank |
||||
=> mw.b ffb00009 1 |
||||
=> reset |
||||
or set SW1[8]= ON |
||||
|
||||
SW1[8]= OFF: Upper bank used for booting start |
||||
SW1[8]= ON: Lower bank used for booting start |
||||
CPLD NOR bank selection register address 0xFFB00009 Bit[0]: |
||||
0 - boot from upper 4 sectors |
||||
1 - boot from lower 4 sectors |
||||
|
||||
|
||||
Build and burn u-boot to NAND flash |
||||
=================================== |
||||
1. Build u-boot.bin image |
||||
export ARCH=powerpc |
||||
export CROSS_COMPILE=/your_path/powerpc-linux-gnu- |
||||
make P1010RDB_NAND |
||||
|
||||
2. Burn u-boot-nand.bin into NAND flash |
||||
=> tftp $loadaddr $uboot-nand |
||||
=> nand erase 0 $filesize |
||||
=> nand write $loadaddr 0 $filesize |
||||
|
||||
3. Check SW4[1:4]= 1000 and SW6[4]=1, then power on. |
||||
|
||||
|
||||
|
||||
Build and burn u-boot to SPI flash |
||||
================================== |
||||
1. Build u-boot-spi.bin image |
||||
make P1010RDB_SPIFLASH_config; make |
||||
Boot up kernel with rootfs.ext2.gz.uboot.p1010rdb |
||||
Download u-boot.bin to linux and you can find some config files |
||||
under /usr/share such as config_xx.dat. Do below command: |
||||
boot_format config_ddr3_1gb_p1010rdb_800M.dat u-boot.bin -spi \ |
||||
u-boot-spi.bin |
||||
to generate u-boot-spi.bin. |
||||
|
||||
2. Burn u-boot-spi.bin into SPI flash |
||||
=> tftp $loadaddr $uboot-spi |
||||
=> sf erase 0 100000 |
||||
=> sf write $loadaddr 0 $filesize |
||||
|
||||
3. Check SW4[1:4]= 0110 and SW6[4]=0, then power on. |
||||
|
||||
|
||||
|
||||
CPLD POR setting registers |
||||
========================== |
||||
1. Set POR switch selection register (addr 0xFFB00011) to 0. |
||||
2. Write CPLD POR registers (BCSR0~BCSR3, addr 0xFFB00014~0xFFB00017) with |
||||
proper values. |
||||
If change boot ROM location to NOR or NAND flash, need write the IFC_CS0 |
||||
switch command by I2C. |
||||
3. Send reset command. |
||||
After reset, the new POR setting will be implemented. |
||||
|
||||
Two examples are given in below: |
||||
Switch from NOR to NAND boot with default frequency: |
||||
=> i2c dev 0 |
||||
=> i2c mw 18 1 f9 |
||||
=> i2c mw 18 3 f0 |
||||
=> mw.b ffb00011 0 |
||||
=> mw.b ffb00017 1 |
||||
=> reset |
||||
Switch from NAND to NOR boot with Core/CCB/DDR (800/400/667 MHz): |
||||
=> i2c dev 0 |
||||
=> i2c mw 18 1 f1 |
||||
=> i2c mw 18 3 f0 |
||||
=> mw.b ffb00011 0 |
||||
=> mw.b ffb00014 2 |
||||
=> mw.b ffb00015 5 |
||||
=> mw.b ffb00016 3 |
||||
=> mw.b ffb00017 f |
||||
=> reset |
||||
|
||||
|
||||
|
||||
Boot Linux from network using TFTP on P1010RDB |
||||
============================================== |
||||
Place uImage, p1010rdb.dtb and rootfs files in the TFTP disk area. |
||||
=> tftp 1000000 uImage |
||||
=> tftp 2000000 p1010rdb.dtb |
||||
=> tftp 3000000 rootfs.ext2.gz.uboot.p1010rdb |
||||
=> bootm 1000000 3000000 2000000 |
||||
|
||||
|
||||
Please contact your local field applications engineer or sales representative |
||||
to obtain related documents, such as P1010-RDB User Guide for details. |
@ -0,0 +1,102 @@ |
||||
RAMBOOT for MPC85xx Platforms |
||||
============================== |
||||
|
||||
RAMBOOT literally means boot from DDR. But since DDR is volatile memory some |
||||
pre-mechanism is required to load the DDR with the bootloader binary. |
||||
- In case of SD and SPI boot this is done by BootROM code inside the chip |
||||
itself. |
||||
- In case of NAND boot FCM supports loading initial 4K code from NAND flash |
||||
which can initialize the DDR and get the complete bootloader copied to DDR. |
||||
|
||||
In addition to the above there could be some more methods to initialize the DDR |
||||
and load it manually. |
||||
Two of them are described below.There is also an explanation as to where these |
||||
methods could be handy. |
||||
1. Load the RAM based bootloader onto DDR via JTAG/BDI interface. And then |
||||
execute the bootloader from DDR. |
||||
This may be handy in the following cases: |
||||
- In very early stage of platform bringup where other boot options are not |
||||
functional because of various reasons. |
||||
- In case the support to program the flashes on the board is not available. |
||||
|
||||
2. Load the RAM based bootloader onto DDR using already existing bootloader on |
||||
the board.And then execute the bootloader from DDR. |
||||
Some usecases where this may be used: |
||||
- While developing some new feature of u-boot, for example USB driver or |
||||
SPI driver. |
||||
Suppose the board already has a working bootloader on it. And you would |
||||
prefer to keep it intact, at the same time want to test your bootloader. |
||||
In this case you can get your test bootloader binary into DDR via tftp |
||||
for example. Then execute the test bootloader. |
||||
- Suppose a platform already has a propreitery bootloader which does not |
||||
support for example AMP boot. In this case also RAM boot loader can be |
||||
utilized. |
||||
|
||||
So basically when the original bootloader is required to be kept intact |
||||
RAM based bootloader can offer an updated bootloader on the system. |
||||
|
||||
Both the above Bootloaders are slight variants of SDcard or SPI Flash |
||||
bootloader or for that matter even NAND bootloader. |
||||
All of them define CONFIG_SYS_RAMBOOT. |
||||
The main difference among all of them is the way the pre-environment is getting |
||||
configured and who is doing that. |
||||
- In case of SD card and SPI flash bootloader this is done by On Chip BootROM inside the Si itself. |
||||
- In case of NAND boot SPL/TPL code does it with some support from Si itself. |
||||
- In case of the pure RAM based bootloaders we have to do it by JTAG manually or already existing bootloader. |
||||
|
||||
How to use them: |
||||
1. Using JTAG |
||||
Boot up in core hold off mode or stop the core after reset using JTAG |
||||
interface. |
||||
Preconfigure DDR/L2SRAM through JTAG interface. |
||||
- setup DDR controller registers. |
||||
- setup DDR LAWs |
||||
- setup DDR TLB |
||||
Load the RAM based boot loader to the proper location in DDR/L2SRAM. |
||||
set up IAR (Instruction counter properly) |
||||
Enable the core to execute. |
||||
|
||||
2. Using already existing bootloader. |
||||
get the rambased boot loader binary into DDR/L2SRAM via tftp. |
||||
execute the RAM based bootloader. |
||||
=> tftp 11000000 u-boot-ram.bin |
||||
=> go 1107f000 |
||||
|
||||
Please note that L2SRAM can also be used instead of DDR if the SOC has |
||||
sufficient size of L2SRAM. |
||||
|
||||
Necessary Code changes Required: |
||||
===================================== |
||||
Please note that below mentioned changes are for 85xx platforms. |
||||
They have been tested on P1020/P2020/P1010 RDB. |
||||
|
||||
The main difference between the above two methods from technical perspective is |
||||
that in 1st case SOC is just out of reset so it is in default configuration. |
||||
(CCSRBAR is at 0xff700000). |
||||
In the 2nd case bootloader has already re-located CCSRBAR to 0xffe00000 |
||||
|
||||
1. File name-> boards.cfg |
||||
There can be added specific Make options for RAMBoot. We can keep different |
||||
options for the two cases mentioned above. |
||||
for example |
||||
P1020RDB_JTAG_RAMBOOT and P1020RDB_GO_RAMBOOT. |
||||
|
||||
2. platform config file |
||||
for example include/configs/P1_P2_RDB.h |
||||
|
||||
#ifdef CONFIG_RAMBOOT |
||||
#define CONFIG_SDCARD |
||||
#endif |
||||
|
||||
This will finally use the CONFIG_SYS_RAMBOOT. |
||||
|
||||
3. File name-> arch/powerpc/include/asm/config_mpc85xx.h |
||||
In the section of the particular SOC, for example P1020, |
||||
|
||||
#if defined(CONFIG_GO) |
||||
#define CONFIG_SYS_CCSRBAR_DEFAULT 0xffe00000 |
||||
#else |
||||
#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 |
||||
#endif |
||||
|
||||
For JTAG RAMBOOT this is not required because CCSRBAR is at ff700000. |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,222 @@ |
||||
/*
|
||||
* SPL driver for Diskonchip G4 nand flash |
||||
* |
||||
* Copyright (C) 2013 Mike Dunn <mikedunn@newsguy.com> |
||||
* |
||||
* This file is released under the terms of GPL v2 and any later version. |
||||
* See the file COPYING in the root directory of the source tree for details. |
||||
* |
||||
* |
||||
* This driver basically mimics the load functionality of a typical IPL (initial |
||||
* program loader) resident in the 2k NOR-like region of the docg4 that is |
||||
* mapped to the reset vector. It allows the u-boot SPL to continue loading if |
||||
* the IPL loads a fixed number of flash blocks that is insufficient to contain |
||||
* the entire u-boot image. In this case, a concatenated spl + u-boot image is |
||||
* written at the flash offset from which the IPL loads an image, and when the |
||||
* IPL jumps to the SPL, the SPL resumes loading where the IPL left off. See |
||||
* the palmtreo680 for an example. |
||||
* |
||||
* This driver assumes that the data was written to the flash using the device's |
||||
* "reliable" mode, and also assumes that each 512 byte page is stored |
||||
* redundantly in the subsequent page. This storage format is likely to be used |
||||
* by all boards that boot from the docg4. The format compensates for the lack |
||||
* of ecc in the IPL. |
||||
* |
||||
* Reliable mode reduces the capacity of a block by half, and the redundant |
||||
* pages reduce it by half again. As a result, the normal 256k capacity of a |
||||
* block is reduced to 64k for the purposes of the IPL/SPL. |
||||
*/ |
||||
|
||||
#include <asm/io.h> |
||||
#include <linux/mtd/docg4.h> |
||||
|
||||
/* forward declarations */ |
||||
static inline void write_nop(void __iomem *docptr); |
||||
static int poll_status(void __iomem *docptr); |
||||
static void write_addr(void __iomem *docptr, uint32_t docg4_addr); |
||||
static void address_sequence(unsigned int g4_page, unsigned int g4_index, |
||||
void __iomem *docptr); |
||||
static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr); |
||||
|
||||
int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst) |
||||
{ |
||||
void *load_addr = dst; |
||||
uint32_t flash_offset = offs; |
||||
const unsigned int block_count = |
||||
(size + DOCG4_BLOCK_CAPACITY_SPL - 1) |
||||
/ DOCG4_BLOCK_CAPACITY_SPL; |
||||
int i; |
||||
|
||||
for (i = 0; i < block_count; i++) { |
||||
int ret = docg4_load_block_reliable(flash_offset, load_addr); |
||||
if (ret) |
||||
return ret; |
||||
load_addr += DOCG4_BLOCK_CAPACITY_SPL; |
||||
flash_offset += DOCG4_BLOCK_SIZE; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
static inline void write_nop(void __iomem *docptr) |
||||
{ |
||||
writew(0, docptr + DOC_NOP); |
||||
} |
||||
|
||||
static int poll_status(void __iomem *docptr) |
||||
{ |
||||
/*
|
||||
* Busy-wait for the FLASHREADY bit to be set in the FLASHCONTROL |
||||
* register. Operations known to take a long time (e.g., block erase) |
||||
* should sleep for a while before calling this. |
||||
*/ |
||||
|
||||
uint8_t flash_status; |
||||
|
||||
/* hardware quirk requires reading twice initially */ |
||||
flash_status = readb(docptr + DOC_FLASHCONTROL); |
||||
|
||||
do { |
||||
flash_status = readb(docptr + DOC_FLASHCONTROL); |
||||
} while (!(flash_status & DOC_CTRL_FLASHREADY)); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static void write_addr(void __iomem *docptr, uint32_t docg4_addr) |
||||
{ |
||||
/* write the four address bytes packed in docg4_addr to the device */ |
||||
|
||||
writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); |
||||
docg4_addr >>= 8; |
||||
writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); |
||||
docg4_addr >>= 8; |
||||
writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); |
||||
docg4_addr >>= 8; |
||||
writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); |
||||
} |
||||
|
||||
static void address_sequence(unsigned int g4_page, unsigned int g4_index, |
||||
void __iomem *docptr) |
||||
{ |
||||
writew(DOCG4_SEQ_PAGE_READ, docptr + DOC_FLASHSEQUENCE); |
||||
writew(DOCG4_CMD_PAGE_READ, docptr + DOC_FLASHCOMMAND); |
||||
write_nop(docptr); |
||||
write_addr(docptr, ((uint32_t)g4_page << 16) | g4_index); |
||||
write_nop(docptr); |
||||
} |
||||
|
||||
static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr) |
||||
{ |
||||
void __iomem *docptr = (void *)CONFIG_SYS_NAND_BASE; |
||||
unsigned int g4_page = flash_offset >> 11; /* 2k page */ |
||||
const unsigned int last_g4_page = g4_page + 0x80; /* last in block */ |
||||
int g4_index = 0; |
||||
uint16_t flash_status; |
||||
uint16_t *buf; |
||||
uint16_t discard, magic_high, magic_low; |
||||
|
||||
/* flash_offset must be aligned to the start of a block */ |
||||
if (flash_offset & 0x3ffff) |
||||
return -1; |
||||
|
||||
writew(DOC_SEQ_RESET, docptr + DOC_FLASHSEQUENCE); |
||||
writew(DOC_CMD_RESET, docptr + DOC_FLASHCOMMAND); |
||||
write_nop(docptr); |
||||
write_nop(docptr); |
||||
poll_status(docptr); |
||||
write_nop(docptr); |
||||
writew(0x45, docptr + DOC_FLASHSEQUENCE); |
||||
writew(0xa3, docptr + DOC_FLASHCOMMAND); |
||||
write_nop(docptr); |
||||
writew(0x22, docptr + DOC_FLASHCOMMAND); |
||||
write_nop(docptr); |
||||
|
||||
/* read 1st 4 oob bytes of first subpage of block */ |
||||
address_sequence(g4_page, 0x0100, docptr); /* index at oob */ |
||||
write_nop(docptr); |
||||
flash_status = readw(docptr + DOC_FLASHCONTROL); |
||||
flash_status = readw(docptr + DOC_FLASHCONTROL); |
||||
if (flash_status & 0x06) /* sequence or protection errors */ |
||||
return -1; |
||||
writew(DOCG4_CMD_READ2, docptr + DOC_FLASHCOMMAND); |
||||
write_nop(docptr); |
||||
write_nop(docptr); |
||||
poll_status(docptr); |
||||
writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0); |
||||
write_nop(docptr); |
||||
write_nop(docptr); |
||||
write_nop(docptr); |
||||
write_nop(docptr); |
||||
write_nop(docptr); |
||||
|
||||
/*
|
||||
* Here we read the first four oob bytes of the first page of the block. |
||||
* The IPL on the palmtreo680 requires that this contain a 32 bit magic |
||||
* number, or the load aborts. We'll ignore it. |
||||
*/ |
||||
discard = readw(docptr + 0x103c); /* hw quirk; 1st read discarded */ |
||||
magic_low = readw(docptr + 0x103c); |
||||
magic_high = readw(docptr + DOCG4_MYSTERY_REG); |
||||
writew(0, docptr + DOC_DATAEND); |
||||
write_nop(docptr); |
||||
write_nop(docptr); |
||||
|
||||
/* load contents of block to memory */ |
||||
buf = (uint16_t *)dest_addr; |
||||
do { |
||||
int i; |
||||
|
||||
address_sequence(g4_page, g4_index, docptr); |
||||
writew(DOCG4_CMD_READ2, |
||||
docptr + DOC_FLASHCOMMAND); |
||||
write_nop(docptr); |
||||
write_nop(docptr); |
||||
poll_status(docptr); |
||||
writew(DOC_ECCCONF0_READ_MODE | |
||||
DOC_ECCCONF0_ECC_ENABLE | |
||||
DOCG4_BCH_SIZE, |
||||
docptr + DOC_ECCCONF0); |
||||
write_nop(docptr); |
||||
write_nop(docptr); |
||||
write_nop(docptr); |
||||
write_nop(docptr); |
||||
write_nop(docptr); |
||||
|
||||
/* read the 512 bytes of page data, 2 bytes at a time */ |
||||
discard = readw(docptr + 0x103c); |
||||
for (i = 0; i < 256; i++) |
||||
*buf++ = readw(docptr + 0x103c); |
||||
|
||||
/* read oob, but discard it */ |
||||
for (i = 0; i < 7; i++) |
||||
discard = readw(docptr + 0x103c); |
||||
discard = readw(docptr + DOCG4_OOB_6_7); |
||||
discard = readw(docptr + DOCG4_OOB_6_7); |
||||
|
||||
writew(0, docptr + DOC_DATAEND); |
||||
write_nop(docptr); |
||||
write_nop(docptr); |
||||
|
||||
if (!(g4_index & 0x100)) { |
||||
/* not redundant subpage read; check for ecc error */ |
||||
write_nop(docptr); |
||||
flash_status = readw(docptr + DOC_ECCCONF1); |
||||
flash_status = readw(docptr + DOC_ECCCONF1); |
||||
if (flash_status & 0x80) { /* ecc error */ |
||||
g4_index += 0x108; /* read redundant subpage */ |
||||
buf -= 256; /* back up ram ptr */ |
||||
continue; |
||||
} else /* no ecc error */ |
||||
g4_index += 0x210; /* skip redundant subpage */ |
||||
} else /* redundant page was just read; skip ecc error check */ |
||||
g4_index += 0x108; |
||||
|
||||
if (g4_index == 0x420) { /* finished with 2k page */ |
||||
g4_index = 0; |
||||
g4_page += 2; /* odd-numbered 2k pages skipped */ |
||||
} |
||||
|
||||
} while (g4_page != last_g4_page); /* while still on same block */ |
||||
|
||||
return 0; |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue