mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-15 06:33:45 +09:00
![Stefan Roese](/assets/img/avatar_default.png)
The t3corp board has an Xilinx DS617 flash chip connected to the onboard FPGA. This patch adds support for these chips. Board specific flash accessor functions are needed, since the chips can only be read correctly in 16bit mode. Additionally the FPGA chip-selects are configured for device-paced transfers (ready is enabled). Signed-off-by: Stefan Roese <sr@denx.de>
232 lines
6.2 KiB
C
232 lines
6.2 KiB
C
/*
|
|
* (C) Copyright 2010
|
|
* Stefan Roese, DENX Software Engineering, 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
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <asm/ppc440.h>
|
|
#include <libfdt.h>
|
|
#include <fdt_support.h>
|
|
#include <i2c.h>
|
|
#include <mtd/cfi_flash.h>
|
|
#include <asm/processor.h>
|
|
#include <asm/io.h>
|
|
#include <asm/mmu.h>
|
|
#include <asm/4xx_pcie.h>
|
|
#include <asm/ppc4xx-gpio.h>
|
|
|
|
int board_early_init_f(void)
|
|
{
|
|
/*
|
|
* Setup the interrupt controller polarities, triggers, etc.
|
|
*/
|
|
mtdcr(UIC0SR, 0xffffffff); /* clear all */
|
|
mtdcr(UIC0ER, 0x00000000); /* disable all */
|
|
mtdcr(UIC0CR, 0x00000005); /* ATI & UIC1 crit are critical */
|
|
mtdcr(UIC0PR, 0xffffffff); /* per ref-board manual */
|
|
mtdcr(UIC0TR, 0x00000000); /* per ref-board manual */
|
|
mtdcr(UIC0VR, 0x00000000); /* int31 highest, base=0x000 */
|
|
mtdcr(UIC0SR, 0xffffffff); /* clear all */
|
|
|
|
mtdcr(UIC1SR, 0xffffffff); /* clear all */
|
|
mtdcr(UIC1ER, 0x00000000); /* disable all */
|
|
mtdcr(UIC1CR, 0x00000000); /* all non-critical */
|
|
mtdcr(UIC1PR, 0x7fffffff); /* per ref-board manual */
|
|
mtdcr(UIC1TR, 0x00000000); /* per ref-board manual */
|
|
mtdcr(UIC1VR, 0x00000000); /* int31 highest, base=0x000 */
|
|
mtdcr(UIC1SR, 0xffffffff); /* clear all */
|
|
|
|
mtdcr(UIC2SR, 0xffffffff); /* clear all */
|
|
mtdcr(UIC2ER, 0x00000000); /* disable all */
|
|
mtdcr(UIC2CR, 0x00000000); /* all non-critical */
|
|
mtdcr(UIC2PR, 0xffffffff); /* per ref-board manual */
|
|
mtdcr(UIC2TR, 0x00000000); /* per ref-board manual */
|
|
mtdcr(UIC2VR, 0x00000000); /* int31 highest, base=0x000 */
|
|
mtdcr(UIC2SR, 0xffffffff); /* clear all */
|
|
|
|
mtdcr(UIC3SR, 0xffffffff); /* clear all */
|
|
mtdcr(UIC3ER, 0x00000000); /* disable all */
|
|
mtdcr(UIC3CR, 0x00000000); /* all non-critical */
|
|
mtdcr(UIC3PR, 0xffffffff); /* per ref-board manual */
|
|
mtdcr(UIC3TR, 0x00000000); /* per ref-board manual */
|
|
mtdcr(UIC3VR, 0x00000000); /* int31 highest, base=0x000 */
|
|
mtdcr(UIC3SR, 0xffffffff); /* clear all */
|
|
|
|
/*
|
|
* Configure PFC (Pin Function Control) registers
|
|
* enable GPIO 49-63
|
|
* UART0: 4 pins
|
|
*/
|
|
mtsdr(SDR0_PFC0, 0x00007fff);
|
|
mtsdr(SDR0_PFC1, 0x00040000);
|
|
|
|
/* Enable PCI host functionality in SDR0_PCI0 */
|
|
mtsdr(SDR0_PCI0, 0xe0000000);
|
|
|
|
mtsdr(SDR0_SRST1, 0); /* Pull AHB out of reset default=1 */
|
|
|
|
/* Setup PLB4-AHB bridge based on the system address map */
|
|
mtdcr(AHB_TOP, 0x8000004B);
|
|
mtdcr(AHB_BOT, 0x8000004B);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int checkboard(void)
|
|
{
|
|
char *s = getenv("serial#");
|
|
|
|
printf("Board: T3CORP");
|
|
|
|
if (s != NULL) {
|
|
puts(", serial# ");
|
|
puts(s);
|
|
}
|
|
putc('\n');
|
|
|
|
return 0;
|
|
}
|
|
|
|
int board_early_init_r(void)
|
|
{
|
|
/*
|
|
* T3CORP has 64MBytes of NOR flash (Spansion 29GL512), but the
|
|
* boot EBC mapping only supports a maximum of 16MBytes
|
|
* (4.ff00.0000 - 4.ffff.ffff).
|
|
* To solve this problem, the flash has to get remapped to another
|
|
* EBC address which accepts bigger regions:
|
|
*
|
|
* 0xfn00.0000 -> 4.cn00.0000
|
|
*/
|
|
|
|
/* Remap the NOR flash to 0xcn00.0000 ... 0xcfff.ffff */
|
|
mtebc(PB0CR, CONFIG_SYS_FLASH_BASE_PHYS_L | EBC_BXCR_BS_64MB |
|
|
EBC_BXCR_BU_RW | EBC_BXCR_BW_16BIT);
|
|
|
|
/* Remove TLB entry of boot EBC mapping */
|
|
remove_tlb(CONFIG_SYS_BOOT_BASE_ADDR, 16 << 20);
|
|
|
|
/* Add TLB entry for 0xfn00.0000 -> 0x4.cn00.0000 */
|
|
program_tlb(CONFIG_SYS_FLASH_BASE_PHYS, CONFIG_SYS_FLASH_BASE,
|
|
CONFIG_SYS_FLASH_SIZE, TLB_WORD2_I_ENABLE);
|
|
|
|
/*
|
|
* Now accessing of the whole 64Mbytes of NOR flash at virtual address
|
|
* 0xfc00.0000 is possible
|
|
*/
|
|
|
|
/*
|
|
* Clear potential errors resulting from auto-calibration.
|
|
* If not done, then we could get an interrupt later on when
|
|
* exceptions are enabled.
|
|
*/
|
|
set_mcsr(get_mcsr());
|
|
|
|
return 0;
|
|
}
|
|
|
|
int misc_init_r(void)
|
|
{
|
|
u32 sdr0_srst1 = 0;
|
|
u32 eth_cfg;
|
|
|
|
/*
|
|
* Set EMAC mode/configuration (GMII, SGMII, RGMII...).
|
|
* This is board specific, so let's do it here.
|
|
*/
|
|
mfsdr(SDR0_ETH_CFG, eth_cfg);
|
|
/* disable SGMII mode */
|
|
eth_cfg &= ~(SDR0_ETH_CFG_SGMII2_ENABLE |
|
|
SDR0_ETH_CFG_SGMII1_ENABLE |
|
|
SDR0_ETH_CFG_SGMII0_ENABLE);
|
|
/* Set the for 2 RGMII mode */
|
|
/* GMC0 EMAC4_0, GMC0 EMAC4_1, RGMII Bridge 0 */
|
|
eth_cfg &= ~SDR0_ETH_CFG_GMC0_BRIDGE_SEL;
|
|
eth_cfg &= ~SDR0_ETH_CFG_GMC1_BRIDGE_SEL;
|
|
mtsdr(SDR0_ETH_CFG, eth_cfg);
|
|
|
|
/*
|
|
* The AHB Bridge core is held in reset after power-on or reset
|
|
* so enable it now
|
|
*/
|
|
mfsdr(SDR0_SRST1, sdr0_srst1);
|
|
sdr0_srst1 &= ~SDR0_SRST1_AHB;
|
|
mtsdr(SDR0_SRST1, sdr0_srst1);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int board_pcie_last(void)
|
|
{
|
|
/*
|
|
* Only PCIe0 for now, PCIe1 hangs on this board
|
|
*/
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Board specific WRDTR and CLKTR values used by the auto-
|
|
* calibration code (4xx_ibm_ddr2_autocalib.c).
|
|
*/
|
|
static struct sdram_timing board_scan_options[] = {
|
|
{1, 2},
|
|
{-1, -1}
|
|
};
|
|
|
|
struct sdram_timing *ddr_scan_option(struct sdram_timing *default_val)
|
|
{
|
|
return board_scan_options;
|
|
}
|
|
|
|
/*
|
|
* Accessor functions replacing the "weak" functions in
|
|
* drivers/mtd/cfi_flash.c
|
|
*
|
|
* The NOR flash devices "behind" the FPGA's (Xilinx DS617)
|
|
* can only be read correctly in 16bit mode. We need to emulate
|
|
* 8bit and 32bit reads here in the board specific code.
|
|
*/
|
|
u8 flash_read8(void *addr)
|
|
{
|
|
u16 val = __raw_readw((void *)((u32)addr & ~1));
|
|
|
|
if ((u32)addr & 1)
|
|
return val;
|
|
|
|
return val >> 8;
|
|
}
|
|
|
|
u32 flash_read32(void *addr)
|
|
{
|
|
return (__raw_readw(addr) << 16) | __raw_readw((void *)((u32)addr + 2));
|
|
}
|
|
|
|
void flash_cmd_reset(flash_info_t *info)
|
|
{
|
|
/*
|
|
* FLASH at address CONFIG_SYS_FLASH_BASE is a Spansion chip and
|
|
* needs the Spansion type reset commands. The other flash chip
|
|
* is located behind a FPGA (Xilinx DS617) and needs the Intel type
|
|
* reset command.
|
|
*/
|
|
if (info->start[0] == CONFIG_SYS_FLASH_BASE)
|
|
flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
|
|
else
|
|
flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
|
|
}
|