qca: ipq40xx: Adding board specific files

Change-Id: I367b352146ad34d1564f6f861b0dd4a902572562
Signed-off-by: Akila N <akilan@codeaurora.org>
This commit is contained in:
Akila N 2016-03-16 15:54:49 +05:30
parent 00a91730cf
commit bbe6202f7c
4 changed files with 2035 additions and 0 deletions

View file

@ -1107,6 +1107,18 @@ extern unsigned int __machine_arch_type;
#define MACH_TYPE_COLIBRI_T30 4493
#define MACH_TYPE_APALIS_T30 4513
#define MACH_TYPE_OMAPL138_LCDK 2495
#define MACH_TYPE_IPQ40XX_AP_DK01_1_S1 0x8010200
#define MACH_TYPE_IPQ40XX_AP_DK01_1_C1 0x8010000
#define MACH_TYPE_IPQ40XX_AP_DK01_1_C2 0x8010100
#define MACH_TYPE_IPQ40XX_AP_DK04_1_C1 0x8010001
#define MACH_TYPE_IPQ40XX_AP_DK04_1_C4 0x8010301
#define MACH_TYPE_IPQ40XX_AP_DK04_1_C2 0x8010101
#define MACH_TYPE_IPQ40XX_AP_DK04_1_C3 0x8010201
#define MACH_TYPE_IPQ40XX_AP_DK06_1_C1 0x8010005
#define MACH_TYPE_IPQ40XX_AP_DK07_1_C1 0x8010006
#define MACH_TYPE_IPQ40XX_DB_DK01_1_C1 0x1010002
#define MACH_TYPE_IPQ40XX_DB_DK02_1_C1 0x1010003
#define MACH_TYPE_IPQ40XX_TB832 0x1010004
#ifdef CONFIG_ARCH_EBSA110
# ifdef machine_arch_type

686
board/qca/ipq40xx/ipq40xx.c Normal file
View file

@ -0,0 +1,686 @@
/*
* Copyright (c) 2015, 2016 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* 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 <asm/global_data.h>
#include <asm/io.h>
#include <asm/errno.h>
#include <environment.h>
#include <configs/ipq40xx.h>
#include "ipq40xx.h"
#include "ipq40xx_board_param.h"
#include <part.h>
#include <asm/arch-ipq40xx/smem.h>
DECLARE_GLOBAL_DATA_PTR;
/*
* Don't have this as a '.bss' variable. The '.bss' and '.rel.dyn'
* sections seem to overlap.
*
* $ arm-none-linux-gnueabi-objdump -h u-boot
* . . .
* 8 .rel.dyn 00004ba8 40630b0c 40630b0c 00038b0c 2**2
* CONTENTS, ALLOC, LOAD, READONLY, DATA
* 9 .bss 0000559c 40630b0c 40630b0c 00000000 2**3
* ALLOC
* . . .
*
* board_early_init_f() initializes this variable, resulting in one
* of the relocation entries present in '.rel.dyn' section getting
* corrupted. Hence, when relocate_code()'s 'fixrel' executes, it
* patches a wrong address, which incorrectly modifies some global
* variable resulting in a crash.
*
* Moral of the story: Global variables that are written before
* relocate_code() gets executed cannot be in '.bss'
*/
board_ipq40xx_params_t *gboard_param = (board_ipq40xx_params_t *)0xbadb0ad;
#define DLOAD_DISABLE 0x1
#define RESERVE_ADDRESS_START 0x87B00000 /*TZAPPS, SMEM and TZ Regions */
#define RESERVE_ADDRESS_SIZE 0x500000
#define SET_MAGIC 0x1
#define CLEAR_MAGIC 0x0
#define SCM_CMD_TZ_CONFIG_HW_FOR_RAM_DUMP_ID 0x9
#define SCM_CMD_TZ_FORCE_DLOAD_ID 0x10
#define BOOT_VERSION 0
#define TZ_VERSION 1
/*******************************************************
Function description: Board specific initialization.
I/P : None
O/P : integer, 0 - no error.
********************************************************/
static board_ipq40xx_params_t *get_board_param(unsigned int machid)
{
unsigned int index;
printf("machid : 0x%0x\n", machid);
for (index = 0; index < NUM_IPQ40XX_BOARDS; index++) {
if (machid == board_params[index].machid)
return &board_params[index];
}
BUG_ON(index == NUM_IPQ40XX_BOARDS);
printf("cdp: Invalid machine id 0x%x\n", machid);
for (;;);
}
int board_init(void)
{
return 0;
}
int board_late_init(void)
{
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)
{
/*Retrieve the machid of the board from smem*/
gboard_param = get_board_param(smem_get_board_platform_type());
return 0;
}
void enable_caches(void)
{
icache_enable();
}
void clear_l2cache_err(void)
{
return;
}
void reset_cpu(ulong addr)
{
}
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;
}
int board_eth_init(bd_t *bis)
{
return 0;
}
#ifdef CONFIG_OF_BOARD_SETUP
struct flash_node_info {
const char *compat; /* compatible string */
int type; /* mtd flash type */
int idx; /* flash index */
};
int ipq_fdt_fixup_spi_nor_params(void *blob)
{
int nodeoff, ret;
qca_smem_flash_info_t sfi;
uint32_t val;
/* Get flash parameters from smem */
smem_get_boot_flash(&sfi.flash_type,
&sfi.flash_index,
&sfi.flash_chip_select,
&sfi.flash_block_size,
&sfi.flash_density);
nodeoff = fdt_node_offset_by_compatible(blob, -1, "n25q128a11");
if (nodeoff < 0) {
printf("ipq: fdt fixup unable to find compatible node\n");
return nodeoff;
}
val = cpu_to_fdt32(sfi.flash_block_size);
ret = fdt_setprop(blob, nodeoff, "sector-size",
&val, sizeof(uint32_t));
if (ret) {
printf("%s: unable to set sector size\n", __func__);
return -1;
}
val = cpu_to_fdt32(sfi.flash_density);
ret = fdt_setprop(blob, nodeoff, "density",
&val, sizeof(uint32_t));
if (ret) {
printf("%s: unable to set density\n", __func__);
return -1;
}
return 0;
}
void ipq_fdt_mem_rsvd_fixup(void *blob)
{
u32 val[2], dload;
int nodeoff, ret;
dload = htonl(DLOAD_DISABLE);
val[0] = htonl(RESERVE_ADDRESS_START);
val[1] = htonl(RESERVE_ADDRESS_SIZE);
/* Reserve only the TZ and SMEM memory region and free the rest */
nodeoff = fdt_path_offset(blob, "/reserved-memory/rsvd2");
if (nodeoff < 0) {
debug("ipq: fdt fixup unable to find compatible node\n");
return;
}
ret = fdt_del_node(blob, nodeoff);
if (ret != 0) {
debug("ipq: fdt fixup unable to delete node\n");
return;
}
nodeoff = fdt_path_offset(blob, "/reserved-memory/wifi_dump");
if (nodeoff < 0) {
debug("ipq: fdt fixup unable to find compatible node\n");
return;
}
ret = fdt_del_node(blob, nodeoff);
if (ret != 0) {
debug("ipq: fdt fixup unable to delete node\n");
return;
}
nodeoff = fdt_path_offset(blob, "/reserved-memory/rsvd1");
if (nodeoff < 0) {
debug("ipq: fdt fixup unable to find compatible node\n");
return;
}
ret = fdt_setprop(blob, nodeoff, "reg", val, sizeof(val));
if (ret != 0) {
debug("ipq: fdt fixup unable to find compatible node\n");
return;
}
/* Set the dload_status to DLOAD_DISABLE */
nodeoff = fdt_path_offset(blob, "/soc/qca,scm_restart_reason");
if (nodeoff < 0) {
debug("ipq: fdt fixup unable to find compatible node\n");
return;
}
ret = fdt_setprop(blob, nodeoff, "dload_status", &dload, sizeof(dload));
if (ret != 0) {
debug("ipq: fdt fixup unable to find compatible node\n");
return;
}
reset_crashdump();
}
void ipq_fdt_fixup_version(void *blob)
{
int nodeoff, ret;
char ver[OEM_VERSION_STRING_LENGTH + VERSION_STRING_LENGTH + 1];
nodeoff = fdt_node_offset_by_compatible(blob, -1, "qcom,ipq40xx");
if (nodeoff < 0) {
debug("ipq: fdt fixup unable to find compatible node\n");
return;
}
if (!smem_get_build_version(ver, sizeof(ver), BOOT_VERSION)) {
debug("BOOT Build Version: %s\n", ver);
ret = fdt_setprop(blob, nodeoff, "boot_version",
ver, strlen(ver));
if (ret)
debug("%s: unable to set Boot version\n", __func__);
}
if (!smem_get_build_version(ver, sizeof(ver), TZ_VERSION)) {
debug("TZ Build Version: %s\n", ver);
ret = fdt_setprop(blob, nodeoff, "tz_version",
ver, strlen(ver));
if (ret)
debug("%s: unable to set TZ version\n", __func__);
}
}
void ipq_fdt_fixup_mtdparts(void *blob, struct flash_node_info *ni)
{
struct mtd_device *dev;
char *parts;
int noff;
parts = getenv("mtdparts");
if (!parts)
return;
if (mtdparts_init() != 0)
return;
for (; ni->compat; ni++) {
noff = fdt_node_offset_by_compatible(blob, -1, ni->compat);
while (noff != -FDT_ERR_NOTFOUND) {
dev = device_find(ni->type, ni->idx);
if (dev) {
if (fdt_node_set_part_info(blob, noff, dev))
return; /* return on error */
}
/* Jump to next flash node */
noff = fdt_node_offset_by_compatible(blob, noff,
ni->compat);
}
}
}
/*
* For newer kernel that boot with device tree (3.14+), all of memory is
* described in the /memory node, including areas that the kernel should not be
* touching.
*
* By default, u-boot will walk the dram bank info and populate the /memory
* node; here, overwrite this behavior so we describe all of memory instead.
*/
void ft_board_setup(void *blob, bd_t *bd)
{
u64 memory_start = CONFIG_SYS_SDRAM_BASE;
u64 memory_size = gboard_param->ddr_size;
char *mtdparts = NULL;
char parts_str[256];
qca_smem_flash_info_t *sfi = &qca_smem_flash_info;
struct flash_node_info nodes[] = {
{ "qcom,msm-nand", MTD_DEV_TYPE_NAND, 0 },
{ "spinand,mt29f", MTD_DEV_TYPE_NAND, 1 },
{ "n25q128a11", MTD_DEV_TYPE_NAND, 2 },
{ NULL, 0, -1 }, /* Terminator */
};
fdt_fixup_memory_banks(blob, &memory_start, &memory_size, 1);
ipq_fdt_fixup_version(blob);
#ifndef CONFIG_QCA_APPSBL_DLOAD
ipq_fdt_mem_rsvd_fixup(blob);
#endif
if (sfi->flash_type == SMEM_BOOT_NAND_FLASH) {
mtdparts = "mtdparts=nand0";
} else if (sfi->flash_type == SMEM_BOOT_SPI_FLASH) {
/* Patch NOR block size and density for
* generic probe case */
ipq_fdt_fixup_spi_nor_params(blob);
if (gboard_param->spi_nand_available &&
get_which_flash_param("rootfs") == 0) {
sprintf(parts_str,
"mtdparts=nand1:0x%x@0(rootfs);spi0.0",
IPQ_NAND_ROOTFS_SIZE);
mtdparts = parts_str;
} else if (gboard_param->nor_nand_available &&
get_which_flash_param("rootfs") == 0) {
sprintf(parts_str,
"mtdparts=nand0:0x%x@0(rootfs);spi0.0",
IPQ_NAND_ROOTFS_SIZE);
mtdparts = parts_str;
} else {
mtdparts = "mtdparts=spi0.0";
}
}
if (mtdparts) {
mtdparts = qca_smem_part_to_mtdparts(mtdparts);
if (mtdparts != NULL) {
debug("mtdparts = %s\n", mtdparts);
setenv("mtdparts", mtdparts);
}
setenv("mtdids", gboard_param->mtdids);
ipq_fdt_fixup_mtdparts(blob, nodes);
}
dcache_disable();
ipq40xx_set_ethmac_addr();
fdt_fixup_ethernet(blob);
#ifdef CONFIG_QCA_MMC
board_mmc_deinit();
#endif
}
#endif /* CONFIG_OF_BOARD_SETUP */
#ifdef CONFIG_QCA_MMC
int board_mmc_env_init(void)
{
block_dev_desc_t *blk_dev;
disk_partition_t disk_info;
int ret;
if (mmc_init(mmc_host.mmc)) {
/* The HS mode command(cmd6) is getting timed out. So mmc card is
* not getting initialized properly. Since the env partition is not
* visible, the env default values are writing into the default
* partition (start of the mmc device). So do a reset again.
*/
if (mmc_init(mmc_host.mmc)) {
printf("MMC init failed \n");
return -1;
}
}
blk_dev = mmc_get_dev(mmc_host.dev_num);
ret = find_part_efi(blk_dev, "0:APPSBLENV", &disk_info);
if (ret > 0) {
board_env_offset = disk_info.start * disk_info.blksz;
board_env_size = disk_info.size * disk_info.blksz;
board_env_range = board_env_size;
BUG_ON(board_env_size > CONFIG_ENV_SIZE_MAX);
}
return ret;
}
int board_mmc_init(bd_t *bis)
{
int ret;
qca_smem_flash_info_t *sfi = &qca_smem_flash_info;
if (!gboard_param->mmc_gpio_count)
return 0;
qca_configure_gpio(gboard_param->mmc_gpio,
gboard_param->mmc_gpio_count);
mmc_host.base = MSM_SDC1_BASE;
mmc_host.clk_mode = MMC_IDENTIFY_MODE;
emmc_clock_config(mmc_host.clk_mode);
ret = qca_mmc_init(bis, &mmc_host);
if (!ret && sfi->flash_type == SMEM_BOOT_MMC_FLASH) {
ret = board_mmc_env_init();
}
return ret;
}
void board_mmc_deinit(void)
{
emmc_clock_disable();
}
#endif
#ifdef CONFIG_IPQ40XX_PCI
void pcie_config_gpio(pcie_params_t *cfg, int enable)
{
int i;
gpio_func_data_t *gpio_data;
gpio_data = cfg->pci_gpio;
for (i = 0; i < cfg->pci_gpio_count; i++) {
if (enable)
gpio_tlmm_config(gpio_data->gpio, gpio_data->func,
gpio_data->out, gpio_data->pull,
gpio_data->drvstr, gpio_data->oe,
gpio_data->gpio_vm, gpio_data->gpio_od_en,
gpio_data->gpio_pu_res);
else
gpio_tlmm_config(gpio_data->gpio, gpio_data->func,
GPIO_OUT_LOW, GPIO_NO_PULL,
GPIO_2MA, GPIO_OE_DISABLE,
GPIO_VM_DISABLE, GPIO_OD_DISABLE,
gpio_data->gpio_pu_res);
gpio_data++;
}
}
void pcie_controller_reset(int id)
{
uint32_t val;
pcie_params_t *cfg;
cfg = &gboard_param->pcie_cfg[id];
/* Enable PCIE CLKS */
pcie_clock_enable(GCC_PCIE_SLEEP_CBCR);
pcie_clock_enable(GCC_PCIE_AXI_M_CBCR);
pcie_clock_enable(GCC_PCIE_AXI_S_CBCR);
pcie_clock_enable(GCC_PCIE_AHB_CBCR);
/* Assert cc_pcie20_core_ares */
writel(PCIE_RST_CTRL_PIPE_ARES, cfg->pcie_rst);
/* Assert cc_pcie20_core_sticky_area */
val = readl(cfg->pcie_rst);
val |= PCIE_RST_CTRL_PIPE_STICKY_ARES;
writel(val, cfg->pcie_rst);
/* Assert cc_pcie20_phy_ahb_ares */
val = readl(cfg->pcie_rst);
val |= PCIE_RST_CTRL_PIPE_PHY_AHB_ARES;
writel(val, cfg->pcie_rst);
gpio_set_value(PCIE_RST_GPIO, GPIO_OUT_LOW);
/* Assert cc_pcie20_mstr_axi_ares */
val = readl(cfg->pcie_rst);
val |= PCIE_RST_CTRL_AXI_M_ARES;
writel(val, cfg->pcie_rst);
/* Assert cc_pcie20_mstr_sticky_ares */
val = readl(cfg->pcie_rst);
val |= PCIE_RST_CTRL_AXI_M_STICKY_ARES;
writel(val, cfg->pcie_rst);
/* Assert cc_pcie20_slv_axi_ares */
val = readl(cfg->pcie_rst);
val |= PCIE_RST_CTRL_AXI_S_ARES;
writel(val, cfg->pcie_rst);
/* Assert cc_pcie20_ahb_ares; */
val = readl(cfg->pcie_rst);
val |= PCIE_RST_CTRL_AHB_ARES;
writel(val, cfg->pcie_rst);
/* DeAssert cc_pcie20_phy_ahb_ares */
val = readl(cfg->pcie_rst);
val &= ~(PCIE_RST_CTRL_AHB_ARES);
writel(val, cfg->pcie_rst);
/* DeAssert cc_pcie20_pciephy_phy_ares*/
val = readl(cfg->pcie_rst);
val &= ~(PCIE_RST_CTRL_PIPE_ARES);
writel(val, cfg->pcie_rst);
/* DeAssert cc_pcie20_core_sticky_ares */
val = readl(cfg->pcie_rst);
val &= ~(PCIE_RST_CTRL_PIPE_STICKY_ARES);
writel(val, cfg->pcie_rst);
mdelay(5);
gpio_set_value(PCIE_RST_GPIO, GPIO_OUT_HIGH);
/* DeAssert cc_pcie20_mstr_axi_ares */
val = readl(cfg->pcie_rst);
val &= ~(PCIE_RST_CTRL_AXI_M_ARES);
writel(val, cfg->pcie_rst);
/* DeAssert cc_pcie20_mstr_axi_ares */
val = readl(cfg->pcie_rst);
val &= ~(PCIE_RST_CTRL_AXI_M_STICKY_ARES);
writel(val, cfg->pcie_rst);
/* DeAssert cc_pcie20_slv_axi_ares */
val = readl(cfg->pcie_rst);
val &= ~(PCIE_RST_CTRL_AXI_S_ARES);
writel(val, cfg->pcie_rst);
/* DeAssert cc_pcie20_ahb_ares */
val = readl(cfg->pcie_rst);
val &= ~(PCIE_RST_CTRL_PIPE_PHY_AHB_ARES);
writel(val, cfg->pcie_rst);
}
static void ipq_pcie_config_controller(int id)
{
pcie_params_t *cfg;
cfg = &gboard_param->pcie_cfg[id];
/*
* program and enable address translation region 0 (device config
* address space); region type config;
* axi config address range to device config address range
*/
writel(0, cfg->pcie20 + PCIE20_PLR_IATU_VIEWPORT);
writel(4, cfg->pcie20 + PCIE20_PLR_IATU_CTRL1);
writel((1 << 31), cfg->pcie20 + PCIE20_PLR_IATU_CTRL2);
writel(cfg->axi_conf , cfg->pcie20 + PCIE20_PLR_IATU_LBAR);
writel(0, cfg->pcie20 + PCIE20_PLR_IATU_UBAR);
writel((cfg->axi_conf + PCIE_AXI_CONF_SIZE - 1),
cfg->pcie20 + PCIE20_PLR_IATU_LAR);
writel(MSM_PCIE_DEV_CFG_ADDR,
cfg->pcie20 + PCIE20_PLR_IATU_LTAR);
writel(0, cfg->pcie20 + PCIE20_PLR_IATU_UTAR);
/*
* program and enable address translation region 2 (device resource
* address space); region type memory;
* axi device bar address range to device bar address range
*/
writel(2, cfg->pcie20 + PCIE20_PLR_IATU_VIEWPORT);
writel(0, cfg->pcie20 + PCIE20_PLR_IATU_CTRL1);
writel((1 << 31), cfg->pcie20 + PCIE20_PLR_IATU_CTRL2);
writel(cfg->axi_bar_start, cfg->pcie20 + PCIE20_PLR_IATU_LBAR);
writel(0, cfg->pcie20 + PCIE20_PLR_IATU_UBAR);
writel((cfg->axi_bar_start + cfg->axi_bar_size
- PCIE_AXI_CONF_SIZE - 1), cfg->pcie20 + PCIE20_PLR_IATU_LAR);
writel(cfg->axi_bar_start, cfg->pcie20 + PCIE20_PLR_IATU_LTAR);
writel(0, cfg->pcie20 + PCIE20_PLR_IATU_UTAR);
/* 1K PCIE buffer setting */
writel(0x3, cfg->pcie20 + PCIE20_AXI_MSTR_RESP_COMP_CTRL0);
writel(0x1, cfg->pcie20 + PCIE20_AXI_MSTR_RESP_COMP_CTRL1);
}
void pcie_linkup(int id)
{
int j, val;
pcie_params_t *cfg;
cfg = &gboard_param->pcie_cfg[id];
pcie_clock_enable(GCC_PCIE_SLEEP_CBCR);
pcie_clock_enable(GCC_PCIE_AXI_M_CBCR);
pcie_clock_enable(GCC_PCIE_AXI_S_CBCR);
pcie_clock_enable(GCC_PCIE_AHB_CBCR);
pcie_controller_reset(id);
mdelay(200);
writel(SLV_ADDR_SPACE_SZ, cfg->parf + PARF_SLV_ADDR_SPACE_SIZE);
mdelay(100);
writel(0x0, cfg->pcie20 + PCIE_0_PORT_FORCE_REG);
val = (L1_ENTRANCE_LATENCY(3) |
L0_ENTRANCE_LATENCY(3) |
COMMON_CLK_N_FTS(128) |
ACK_N_FTS(128));
writel(val, cfg->pcie20 + PCIE_0_ACK_F_ASPM_CTRL_REG);
val = (FAST_TRAINING_SEQ(128) |
NUM_OF_LANES(2) |
DIRECT_SPEED_CHANGE);
writel(val, cfg->pcie20 + PCIE_0_GEN2_CTRL_REG);
writel(PCI_TYPE0_BUS_MASTER_EN,
cfg->pcie20 + PCIE_0_TYPE0_STATUS_COMMAND_REG_1);
writel(DBI_RO_WR_EN, cfg->pcie20 + PCIE_0_MISC_CONTROL_1_REG);
writel(0x0002FD7F, cfg->pcie20 + 0x84);
val = (PCIE_CAP_ASPM_OPT_COMPLIANCE |
PCIE_CAP_LINK_BW_NOT_CAP |
PCIE_CAP_DLL_ACTIVE_REP_CAP |
PCIE_CAP_L1_EXIT_LATENCY(4) |
PCIE_CAP_L0S_EXIT_LATENCY(4) |
PCIE_CAP_MAX_LINK_WIDTH(1) |
PCIE_CAP_MAX_LINK_SPEED(1));
writel(val, cfg->pcie20 + PCIE_0_LINK_CAPABILITIES_REG);
writel(PCIE_CAP_CPL_TIMEOUT_DISABLE,
cfg->pcie20 + PCIE_0_DEVICE_CONTROL2_DEVICE_STATUS2_REG);
writel(0x10110008, cfg->pcie20 + PCIE_0_TYPE0_LINK_CONTROL_LINK_STATUS_REG_1);
writel(LTSSM_EN, cfg->parf + PCIE_0_PCIE20_PARF_LTSSM);
mdelay(200);
for (j = 0; j < 400; j++) {
val = readl(cfg->pcie20 + PCIE_0_TYPE0_LINK_CONTROL_LINK_STATUS_REG_1);
if (val & (1 << 29)) {
printf("PCI%d Link Intialized\n", id);
cfg->linkup = 1;
break;
}
udelay(100);
}
ipq_pcie_config_controller(id);
}
void board_pci_init()
{
int i;
pcie_params_t *cfg;
for (i = 0; i < PCI_MAX_DEVICES; i++) {
cfg = &gboard_param->pcie_cfg[i];
pcie_config_gpio(cfg, ENABLE);
pcie_controller_reset(i);
pcie_linkup(i);
}
}
void board_pci_deinit(void)
{
int i;
pcie_params_t *cfg;
for (i = 0; i < PCI_MAX_DEVICES; i++) {
cfg = &gboard_param->pcie_cfg[i];
writel(1, cfg->parf + PCIE20_PARF_PHY_CTRL);
pcie_config_gpio(cfg, DISABLE);
}
/* Disable PCIE CLKS */
pcie_clock_disable(GCC_PCIE_SLEEP_CBCR);
pcie_clock_disable(GCC_PCIE_AXI_M_CBCR);
pcie_clock_disable(GCC_PCIE_AXI_S_CBCR);
pcie_clock_disable(GCC_PCIE_AHB_CBCR);
}
#endif /* CONFIG_IPQ40XX_PCI */

122
board/qca/ipq40xx/ipq40xx.h Normal file
View file

@ -0,0 +1,122 @@
/*
* Copyright (c) 2015, 2016 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* 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.
*/
#ifndef _IPQ40XX_CDP_H_
#define _IPQ40XX_CDP_H_
#include <configs/ipq40xx.h>
#include <asm/arch-qcom-common/gpio.h>
#include <asm/u-boot.h>
#include <phy.h>
#define NO_OF_DBG_UART_GPIOS 2
#ifdef CONFIG_IPQ40XX_I2C
#define NO_OF_I2C_GPIOS 2
#endif
#define MAX_CONF_NAME 5
unsigned int smem_get_board_machtype(void);
#define IPQ40XX_EDMA_DEV 1
typedef struct {
uint count;
u8 addr[7];
} ipq40xx_edma_phy_addr_t;
/* ipq40xx edma Paramaters */
typedef struct {
uint base;
int unit;
uint mac_conn_to_phy;
phy_interface_t phy;
ipq40xx_edma_phy_addr_t phy_addr;
const char phy_name[MDIO_NAME_LEN];
} ipq40xx_edma_board_cfg_t;
typedef struct {
int gpio;
unsigned int func;
unsigned int out;
unsigned int pull;
unsigned int drvstr;
unsigned int oe;
unsigned int gpio_vm;
unsigned int gpio_od_en;
unsigned int gpio_pu_res;
} gpio_func_data_t;
typedef struct {
unsigned int uart_dm_base;
gpio_func_data_t *dbg_uart_gpio;
} uart_cfg_t;
#ifdef CONFIG_IPQ40XX_I2C
typedef struct {
unsigned int i2c_base;
gpio_func_data_t *i2c_gpio;
} i2c_cfg_t;
#endif
#ifdef CONFIG_IPQ40XX_PCI
#define PCI_MAX_DEVICES 1
typedef struct {
gpio_func_data_t *pci_gpio;
uint32_t pci_gpio_count;
uint32_t parf;
uint32_t elbi;
uint32_t pcie20;
uint32_t axi_bar_start;
uint32_t axi_bar_size;
uint32_t pcie_rst;
uint32_t axi_conf;
int linkup;
} pcie_params_t;
void board_pci_init(void);
#endif /* CONFIG_IPQ40XX_PCI */
/* Board specific parameters */
typedef struct {
unsigned int machid;
unsigned int ddr_size;
const char *mtdids;
gpio_func_data_t *spi_nor_gpio;
unsigned int spi_nor_gpio_count;
gpio_func_data_t *nand_gpio;
unsigned int nand_gpio_count;
gpio_func_data_t *sw_gpio;
unsigned int sw_gpio_count;
gpio_func_data_t *rgmii_gpio;
unsigned int rgmii_gpio_count;
ipq40xx_edma_board_cfg_t edma_cfg[IPQ40XX_EDMA_DEV];
uart_cfg_t *uart_cfg;
uart_cfg_t *console_uart_cfg;
#ifdef CONFIG_IPQ40XX_I2C
i2c_cfg_t *i2c_cfg;
#endif
gpio_func_data_t *mmc_gpio;
unsigned int mmc_gpio_count;
unsigned int spi_nand_available;
unsigned int nor_nand_available;
unsigned int nor_emmc_available;
#ifdef CONFIG_IPQ40XX_PCI
pcie_params_t pcie_cfg[PCI_MAX_DEVICES];
#endif
const char *dtb_config_name[MAX_CONF_NAME];
} __attribute__ ((__packed__)) board_ipq40xx_params_t;
extern board_ipq40xx_params_t *gboard_param;
unsigned int get_board_index(unsigned int machid);
#endif

File diff suppressed because it is too large Load diff