2014-04-09 03:45:46 +02:00
|
|
|
|
|
|
|
/* * Copyright (c) 2012 - 2013 The Linux Foundation. All rights reserved.* */
|
|
|
|
|
2014-10-20 22:20:49 +02:00
|
|
|
#include <soc/gpio.h>
|
|
|
|
#include <soc/cdp.h>
|
2014-04-23 23:00:59 +02:00
|
|
|
#include <types.h>
|
2014-04-09 03:45:46 +02:00
|
|
|
|
2014-04-23 23:00:59 +02:00
|
|
|
void ipq_configure_gpio(const gpio_func_data_t *gpio, unsigned count)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
gpio_tlmm_config(gpio->gpio, gpio->func, gpio->dir,
|
|
|
|
gpio->pull, gpio->drvstr, gpio->enable);
|
|
|
|
gpio++;
|
|
|
|
}
|
|
|
|
}
|
2014-04-09 03:45:46 +02:00
|
|
|
|
2014-04-23 23:00:59 +02:00
|
|
|
#if 0
|
2014-04-09 03:45:46 +02:00
|
|
|
/* Watchdog bite time set to default reset value */
|
|
|
|
#define RESET_WDT_BITE_TIME 0x31F3
|
|
|
|
|
|
|
|
/* Watchdog bark time value is ketp larger than the watchdog timeout
|
|
|
|
* of 0x31F3, effectively disabling the watchdog bark interrupt
|
|
|
|
*/
|
|
|
|
#define RESET_WDT_BARK_TIME (5 * RESET_WDT_BITE_TIME)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If SMEM is not found, we provide a value, that will prevent the
|
|
|
|
* environment from being written to random location in the flash.
|
|
|
|
*
|
|
|
|
* NAND: In the case of NAND, we do this by setting ENV_RANGE to
|
|
|
|
* zero. If ENV_RANGE < ENV_SIZE, then environment is not written.
|
|
|
|
*
|
|
|
|
* SPI Flash: In the case of SPI Flash, we do this by setting the
|
|
|
|
* flash_index to -1.
|
|
|
|
*/
|
|
|
|
|
|
|
|
loff_t board_env_offset;
|
|
|
|
loff_t board_env_range;
|
|
|
|
extern int nand_env_device;
|
|
|
|
|
|
|
|
board_ipq806x_params_t *gboard_param;
|
|
|
|
extern int ipq_gmac_eth_initialize(const char *ethaddr);
|
|
|
|
uchar ipq_def_enetaddr[6] = {0x00, 0x03, 0x7F, 0xBA, 0xDB, 0xAD};
|
|
|
|
|
|
|
|
/*******************************************************
|
|
|
|
Function description: Board specific initialization.
|
|
|
|
I/P : None
|
|
|
|
O/P : integer, 0 - no error.
|
|
|
|
|
|
|
|
********************************************************/
|
|
|
|
static board_ipq806x_params_t *get_board_param(unsigned int machid)
|
|
|
|
{
|
|
|
|
unsigned int index = 0;
|
|
|
|
|
|
|
|
for (index = 0; index < NUM_IPQ806X_BOARDS; index++) {
|
|
|
|
if (machid == board_params[index].machid)
|
|
|
|
return &board_params[index];
|
|
|
|
}
|
|
|
|
BUG_ON(index == NUM_IPQ806X_BOARDS);
|
|
|
|
printf("cdp: Invalid machine id 0x%x\n", machid);
|
|
|
|
for (;;);
|
|
|
|
}
|
|
|
|
|
|
|
|
int board_init()
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
uint32_t start_blocks;
|
|
|
|
uint32_t size_blocks;
|
|
|
|
loff_t board_env_size;
|
|
|
|
ipq_smem_flash_info_t *sfi = &ipq_smem_flash_info;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* after relocation gboard_param is reset to NULL
|
|
|
|
* initialize again
|
|
|
|
*/
|
|
|
|
gd->bd->bi_boot_params = IPQ_BOOT_PARAMS_ADDR;
|
|
|
|
gd->bd->bi_arch_number = smem_get_board_machtype();
|
|
|
|
gboard_param = get_board_param(gd->bd->bi_arch_number);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Should be inited, before env_relocate() is called,
|
|
|
|
* since env. offset is obtained from SMEM.
|
|
|
|
*/
|
|
|
|
ret = smem_ptable_init();
|
|
|
|
if (ret < 0) {
|
|
|
|
printf("cdp: SMEM init failed\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = smem_get_boot_flash(&sfi->flash_type,
|
|
|
|
&sfi->flash_index,
|
|
|
|
&sfi->flash_chip_select,
|
|
|
|
&sfi->flash_block_size);
|
|
|
|
if (ret < 0) {
|
|
|
|
printf("cdp: get boot flash failed\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sfi->flash_type == SMEM_BOOT_NAND_FLASH) {
|
|
|
|
nand_env_device = CONFIG_IPQ_NAND_NAND_INFO_IDX;
|
|
|
|
} else if (sfi->flash_type == SMEM_BOOT_SPI_FLASH) {
|
|
|
|
nand_env_device = CONFIG_IPQ_SPI_NAND_INFO_IDX;
|
|
|
|
} else {
|
|
|
|
printf("BUG: unsupported flash type : %d\n", sfi->flash_type);
|
|
|
|
BUG();
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = smem_getpart("0:APPSBLENV", &start_blocks, &size_blocks);
|
|
|
|
if (ret < 0) {
|
|
|
|
printf("cdp: get environment part failed\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
board_env_offset = ((loff_t) sfi->flash_block_size) * start_blocks;
|
|
|
|
board_env_size = ((loff_t) sfi->flash_block_size) * size_blocks;
|
|
|
|
board_env_range = CONFIG_ENV_SIZE;
|
|
|
|
BUG_ON(board_env_size < CONFIG_ENV_SIZE);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void enable_caches(void)
|
|
|
|
{
|
|
|
|
icache_enable();
|
|
|
|
/* When dcache is enabled it causes the tftp timeout CR is raised CR.No: 513868.
|
|
|
|
* disabing dcache now to make tftp to work */
|
|
|
|
#if (CONFIG_IPQ_CACHE_ENABLE == 1)
|
|
|
|
dcache_enable();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*******************************************************
|
|
|
|
Function description: DRAM initialization.
|
|
|
|
I/P : None
|
|
|
|
O/P : integer, 0 - no error.
|
|
|
|
|
|
|
|
********************************************************/
|
|
|
|
|
|
|
|
int dram_init(void)
|
|
|
|
{
|
|
|
|
struct smem_ram_ptable rtable;
|
|
|
|
int i;
|
|
|
|
int mx = ARRAY_SIZE(rtable.parts);
|
|
|
|
|
|
|
|
if (smem_ram_ptable_init(&rtable) > 0) {
|
|
|
|
gd->ram_size = 0;
|
|
|
|
for (i = 0; i < mx; i++) {
|
|
|
|
if (rtable.parts[i].category == RAM_PARTITION_SDRAM
|
|
|
|
&& rtable.parts[i].type == RAM_PARTITION_SYS_MEMORY) {
|
|
|
|
gd->ram_size += rtable.parts[i].size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
gboard_param->ddr_size = gd->ram_size;
|
|
|
|
} else {
|
|
|
|
gd->ram_size = gboard_param->ddr_size;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************
|
|
|
|
Function description: initi Dram Bank size
|
|
|
|
I/P : None
|
|
|
|
O/P : integer, 0 - no error.
|
|
|
|
|
|
|
|
********************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
void dram_init_banksize(void)
|
|
|
|
{
|
|
|
|
gd->bd->bi_dram[0].start = IPQ_KERNEL_START_ADDR;
|
|
|
|
gd->bd->bi_dram[0].size = gboard_param->ddr_size - GENERATED_IPQ_RESERVE_SIZE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************
|
|
|
|
Function description: Display board information on console.
|
|
|
|
I/P : None
|
|
|
|
O/P : integer, 0 - no error.
|
|
|
|
|
|
|
|
**********************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_DISPLAY_BOARDINFO
|
|
|
|
int checkboard(void)
|
|
|
|
{
|
|
|
|
printf("Board: %s\n", sysinfo.board_string);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_DISPLAY_BOARDINFO */
|
|
|
|
|
|
|
|
void reset_cpu(ulong addr)
|
|
|
|
{
|
|
|
|
printf("\nResetting with watch dog!\n");
|
|
|
|
|
|
|
|
writel(0, APCS_WDT0_EN);
|
|
|
|
writel(1, APCS_WDT0_RST);
|
|
|
|
writel(RESET_WDT_BARK_TIME, APCS_WDT0_BARK_TIME);
|
|
|
|
writel(RESET_WDT_BITE_TIME, APCS_WDT0_BITE_TIME);
|
|
|
|
writel(1, APCS_WDT0_EN);
|
|
|
|
writel(1, APCS_WDT0_CPU0_WDOG_EXPIRED_ENABLE);
|
|
|
|
|
|
|
|
for(;;);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void configure_nand_gpio(void)
|
|
|
|
{
|
|
|
|
/* EBI2 CS, CLE, ALE, WE, OE */
|
|
|
|
gpio_tlmm_config(34, 1, 0, GPIO_NO_PULL, GPIO_10MA, GPIO_DISABLE);
|
|
|
|
gpio_tlmm_config(35, 1, 0, GPIO_NO_PULL, GPIO_10MA, GPIO_DISABLE);
|
|
|
|
gpio_tlmm_config(36, 1, 0, GPIO_NO_PULL, GPIO_10MA, GPIO_DISABLE);
|
|
|
|
gpio_tlmm_config(37, 1, 0, GPIO_NO_PULL, GPIO_10MA, GPIO_DISABLE);
|
|
|
|
gpio_tlmm_config(38, 1, 0, GPIO_NO_PULL, GPIO_10MA, GPIO_DISABLE);
|
|
|
|
|
|
|
|
/* EBI2 BUSY */
|
|
|
|
gpio_tlmm_config(39, 1, 0, GPIO_PULL_UP, GPIO_10MA, GPIO_DISABLE);
|
|
|
|
|
|
|
|
/* EBI2 D7 - D0 */
|
|
|
|
gpio_tlmm_config(40, 1, 0, GPIO_KEEPER, GPIO_10MA, GPIO_DISABLE);
|
|
|
|
gpio_tlmm_config(41, 1, 0, GPIO_KEEPER, GPIO_10MA, GPIO_DISABLE);
|
|
|
|
gpio_tlmm_config(42, 1, 0, GPIO_KEEPER, GPIO_10MA, GPIO_DISABLE);
|
|
|
|
gpio_tlmm_config(43, 1, 0, GPIO_KEEPER, GPIO_10MA, GPIO_DISABLE);
|
|
|
|
gpio_tlmm_config(44, 1, 0, GPIO_KEEPER, GPIO_10MA, GPIO_DISABLE);
|
|
|
|
gpio_tlmm_config(45, 1, 0, GPIO_KEEPER, GPIO_10MA, GPIO_DISABLE);
|
|
|
|
gpio_tlmm_config(46, 1, 0, GPIO_KEEPER, GPIO_10MA, GPIO_DISABLE);
|
|
|
|
gpio_tlmm_config(47, 1, 0, GPIO_KEEPER, GPIO_10MA, GPIO_DISABLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void board_nand_init(void)
|
|
|
|
{
|
|
|
|
struct ebi2cr_regs *ebi2_regs;
|
|
|
|
extern int ipq_spi_init(void);
|
|
|
|
|
|
|
|
if (gboard_param->flashdesc != NOR_MMC) {
|
|
|
|
|
|
|
|
ebi2_regs = (struct ebi2cr_regs *) EBI2CR_BASE;
|
|
|
|
|
|
|
|
nand_clock_config();
|
|
|
|
configure_nand_gpio();
|
|
|
|
|
|
|
|
/* NAND Flash is connected to CS0 */
|
|
|
|
clrsetbits_le32(&ebi2_regs->chip_select_cfg0, CS0_CFG_MASK,
|
|
|
|
CS0_CFG_SERIAL_FLASH_DEVICE);
|
|
|
|
|
|
|
|
ipq_nand_init(IPQ_NAND_LAYOUT_LINUX);
|
|
|
|
}
|
|
|
|
|
|
|
|
ipq_spi_init();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ipq_get_part_details(void)
|
|
|
|
{
|
|
|
|
int ret, i;
|
|
|
|
uint32_t start; /* block number */
|
|
|
|
uint32_t size; /* no. of blocks */
|
|
|
|
|
|
|
|
ipq_smem_flash_info_t *smem = &ipq_smem_flash_info;
|
|
|
|
|
|
|
|
struct { char *name; ipq_part_entry_t *part; } entries[] = {
|
|
|
|
{ "0:HLOS", &smem->hlos },
|
|
|
|
{ "0:NSS0", &smem->nss[0] },
|
|
|
|
{ "0:NSS1", &smem->nss[1] },
|
|
|
|
};
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(entries); i++) {
|
|
|
|
ret = smem_getpart(entries[i].name, &start, &size);
|
|
|
|
if (ret < 0) {
|
|
|
|
ipq_part_entry_t *part = entries[i].part;
|
|
|
|
printf("cdp: get part failed for %s\n", entries[i].name);
|
|
|
|
part->offset = 0xBAD0FF5E;
|
|
|
|
part->size = 0xBAD0FF5E;
|
|
|
|
}
|
|
|
|
ipq_set_part_entry(smem, entries[i].part, start, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the kernel partition details from SMEM and populate the,
|
|
|
|
* environment with sufficient information for the boot command to
|
|
|
|
* load and execute the kernel.
|
|
|
|
*/
|
|
|
|
int board_late_init(void)
|
|
|
|
{
|
|
|
|
unsigned int machid;
|
|
|
|
|
|
|
|
ipq_get_part_details();
|
|
|
|
|
|
|
|
/* get machine type from SMEM and set in env */
|
|
|
|
machid = gd->bd->bi_arch_number;
|
|
|
|
if (machid != 0) {
|
|
|
|
setenv_addr("machid", (void *)machid);
|
|
|
|
gd->bd->bi_arch_number = machid;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This function is called in the very beginning.
|
|
|
|
* Retreive the machtype info from SMEM and map the board specific
|
|
|
|
* parameters. Shared memory region at Dram address 0x40400000
|
|
|
|
* contains the machine id/ board type data polulated by SBL.
|
|
|
|
*/
|
|
|
|
int board_early_init_f(void)
|
|
|
|
{
|
|
|
|
gboard_param = get_board_param(smem_get_board_machtype());
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Gets the ethernet address from the ART partition table and return the value
|
|
|
|
*/
|
|
|
|
int get_eth_mac_address(uchar *enetaddr, uint no_of_macs)
|
|
|
|
{
|
|
|
|
s32 ret;
|
|
|
|
u32 start_blocks;
|
|
|
|
u32 size_blocks;
|
|
|
|
u32 length = (6 * no_of_macs);
|
|
|
|
u32 flash_type;
|
|
|
|
loff_t art_offset;
|
|
|
|
|
|
|
|
if (ipq_smem_flash_info.flash_type == SMEM_BOOT_SPI_FLASH)
|
|
|
|
flash_type = CONFIG_IPQ_SPI_NAND_INFO_IDX;
|
|
|
|
else if (ipq_smem_flash_info.flash_type == SMEM_BOOT_NAND_FLASH)
|
|
|
|
flash_type = CONFIG_IPQ_NAND_NAND_INFO_IDX;
|
|
|
|
else {
|
|
|
|
printf("Unknown flash type\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = smem_getpart("0:ART", &start_blocks, &size_blocks);
|
|
|
|
if (ret < 0) {
|
|
|
|
printf("No ART partition found\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ART partition 0th position (6 * 4) 24 bytes will contain the
|
|
|
|
* 4 MAC Address. First 0-5 bytes for GMAC0, Second 6-11 bytes
|
|
|
|
* for GMAC1, 12-17 bytes for GMAC2 and 18-23 bytes for GMAC3
|
|
|
|
*/
|
|
|
|
art_offset = ((loff_t) ipq_smem_flash_info.flash_block_size * start_blocks);
|
|
|
|
|
|
|
|
ret = nand_read(&nand_info[flash_type], art_offset, &length, enetaddr);
|
|
|
|
if (ret < 0)
|
|
|
|
printf("ART partition read failed..\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int board_eth_init(bd_t *bis)
|
|
|
|
{
|
|
|
|
int status;
|
|
|
|
|
|
|
|
ipq_gmac_common_init(gboard_param->gmac_cfg);
|
|
|
|
|
|
|
|
ipq_configure_gpio(gboard_param->gmac_gpio,
|
|
|
|
gboard_param->gmac_gpio_count);
|
|
|
|
|
|
|
|
status = ipq_gmac_init(gboard_param->gmac_cfg);
|
|
|
|
return status;
|
|
|
|
}
|
2014-04-23 23:00:59 +02:00
|
|
|
#endif
|