- Add basic Marvell/Cavium OcteonTX/TX2 support (Suneel)
- Infrastructure changes to PCI uclass to support these SoC's (Suneel)
- Add PCI, MMC & watchdog driver drivers for OcteonTX/TX2 (Suneel)
- Increase CONFIG_SYS_MALLOC_F_LEN for qemu-x86 (Stefan)
This commit is contained in:
Tom Rini 2020-08-25 10:24:40 -04:00
commit 9f9ecd3e4d
77 changed files with 34981 additions and 94 deletions

View File

@ -1737,6 +1737,24 @@ config ARCH_ROCKCHIP
imply TPL_SYSRESET
imply USB_FUNCTION_FASTBOOT
config ARCH_OCTEONTX
bool "Support OcteonTX SoCs"
select DM
select ARM64
select OF_CONTROL
select OF_LIVE
select BOARD_LATE_INIT
select SYS_CACHE_SHIFT_7
config ARCH_OCTEONTX2
bool "Support OcteonTX2 SoCs"
select DM
select ARM64
select OF_CONTROL
select OF_LIVE
select BOARD_LATE_INIT
select SYS_CACHE_SHIFT_7
config TARGET_THUNDERX_88XX
bool "Support ThunderX 88xx"
select ARM64
@ -1835,6 +1853,10 @@ source "arch/arm/mach-lpc32xx/Kconfig"
source "arch/arm/mach-mvebu/Kconfig"
source "arch/arm/mach-octeontx/Kconfig"
source "arch/arm/mach-octeontx2/Kconfig"
source "arch/arm/cpu/armv7/ls102xa/Kconfig"
source "arch/arm/mach-imx/mx2/Kconfig"
@ -1920,6 +1942,8 @@ source "board/bosch/guardian/Kconfig"
source "board/CarMediaLab/flea3/Kconfig"
source "board/Marvell/aspenite/Kconfig"
source "board/Marvell/gplugd/Kconfig"
source "board/Marvell/octeontx/Kconfig"
source "board/Marvell/octeontx2/Kconfig"
source "board/armadeus/apf27/Kconfig"
source "board/armltd/vexpress/Kconfig"
source "board/armltd/vexpress64/Kconfig"

View File

@ -80,6 +80,8 @@ machine-$(CONFIG_ARCH_STM32MP) += stm32mp
machine-$(CONFIG_ARCH_SUNXI) += sunxi
machine-$(CONFIG_ARCH_TEGRA) += tegra
machine-$(CONFIG_ARCH_U8500) += u8500
machine-$(CONFIG_ARCH_OCTEONTX) += octeontx
machine-$(CONFIG_ARCH_OCTEONTX2) += octeontx2
machine-$(CONFIG_ARCH_UNIPHIER) += uniphier
machine-$(CONFIG_ARCH_VERSAL) += versal
machine-$(CONFIG_ARCH_ZYNQ) += zynq

View File

@ -0,0 +1,123 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#ifndef __BOARD_H__
#define __BOARD_H__
#include <asm/arch/soc.h>
#define MAX_LMAC_PER_BGX 4
#define LMAC_CNT MAX_LMAC_PER_BGX
#if defined(CONFIG_TARGET_OCTEONTX_81XX)
/** Maximum number of BGX interfaces per CPU node */
#define MAX_BGX_PER_NODE 3
#define OCTEONTX_XCV /* RGMII Interface */
#elif defined(CONFIG_TARGET_OCTEONTX_83XX)
/** Maximum number of BGX interfaces per CPU node */
#define MAX_BGX_PER_NODE 4
#endif
/** Reg offsets */
#define RST_BOOT 0x87E006001600ULL
/** Structure definitions */
/**
* Register (RSL) rst_boot
*
* RST Boot Register This register is not accessible through ROM scripts;
* see SCR_WRITE32_S[ADDR].
*/
union rst_boot {
u64 u;
struct rst_boot_s {
u64 rboot_pin : 1;
u64 rboot : 1;
u64 reserved_2_32 : 31;
u64 pnr_mul : 6;
u64 reserved_39 : 1;
u64 c_mul : 7;
u64 reserved_47_52 : 6;
u64 gpio_ejtag : 1;
u64 mcp_jtagdis : 1;
u64 dis_scan : 1;
u64 dis_huk : 1;
u64 vrm_err : 1;
u64 jt_tstmode : 1;
u64 ckill_ppdis : 1;
u64 trusted_mode : 1;
u64 reserved_61_62 : 2;
u64 chipkill : 1;
} s;
struct rst_boot_cn81xx {
u64 rboot_pin : 1;
u64 rboot : 1;
u64 lboot : 10;
u64 lboot_ext23 : 6;
u64 lboot_ext45 : 6;
u64 lboot_jtg : 1;
u64 lboot_ckill : 1;
u64 reserved_26_29 : 4;
u64 lboot_oci : 3;
u64 pnr_mul : 6;
u64 reserved_39 : 1;
u64 c_mul : 7;
u64 reserved_47_54 : 8;
u64 dis_scan : 1;
u64 dis_huk : 1;
u64 vrm_err : 1;
u64 jt_tstmode : 1;
u64 ckill_ppdis : 1;
u64 trusted_mode : 1;
u64 ejtagdis : 1;
u64 jtcsrdis : 1;
u64 chipkill : 1;
} cn81xx;
struct rst_boot_cn83xx {
u64 rboot_pin : 1;
u64 rboot : 1;
u64 lboot : 10;
u64 lboot_ext23 : 6;
u64 lboot_ext45 : 6;
u64 lboot_jtg : 1;
u64 lboot_ckill : 1;
u64 lboot_pf_flr : 4;
u64 lboot_oci : 3;
u64 pnr_mul : 6;
u64 reserved_39 : 1;
u64 c_mul : 7;
u64 reserved_47_54 : 8;
u64 dis_scan : 1;
u64 dis_huk : 1;
u64 vrm_err : 1;
u64 jt_tstmode : 1;
u64 ckill_ppdis : 1;
u64 trusted_mode : 1;
u64 ejtagdis : 1;
u64 jtcsrdis : 1;
u64 chipkill : 1;
} cn83xx;
};
extern unsigned long fdt_base_addr;
/** Function definitions */
void mem_map_fill(void);
int octeontx_board_has_pmp(void);
const char *fdt_get_board_model(void);
const char *fdt_get_board_serial(void);
const char *fdt_get_board_revision(void);
void fdt_parse_phy_info(void);
void fdt_board_get_ethaddr(int bgx, int lmac, unsigned char *eth);
void bgx_set_board_info(int bgx_id, int *mdio_bus, int *phy_addr,
bool *autoneg_dis, bool *lmac_reg, bool *lmac_enable);
#endif /* __BOARD_H__ */

View File

@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#ifndef __CLOCK_H__
#define __CLOCK_H__
/** System PLL reference clock */
#define PLL_REF_CLK 50000000 /* 50 MHz */
#define NS_PER_REF_CLK_TICK (1000000000 / PLL_REF_CLK)
/**
* Returns the I/O clock speed in Hz
*/
u64 octeontx_get_io_clock(void);
/**
* Returns the core clock speed in Hz
*/
u64 octeontx_get_core_clock(void);
#endif /* __CLOCK_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,428 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2020 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#ifndef __CSRS_XCV_H__
#define __CSRS_XCV_H__
/**
* @file
*
* Configuration and status register (CSR) address and type definitions for
* XCV.
*
* This file is auto generated. Do not edit.
*
*/
/**
* Enumeration xcv_bar_e
*
* XCV Base Address Register Enumeration Enumerates the base address
* registers.
*/
#define XCV_BAR_E_XCVX_PF_BAR0(a) (0x87e0db000000ll + 0ll * (a))
#define XCV_BAR_E_XCVX_PF_BAR0_SIZE 0x100000ull
#define XCV_BAR_E_XCVX_PF_BAR4(a) (0x87e0dbf00000ll + 0ll * (a))
#define XCV_BAR_E_XCVX_PF_BAR4_SIZE 0x100000ull
/**
* Enumeration xcv_int_vec_e
*
* XCV MSI-X Vector Enumeration Enumerates the MSI-X interrupt vectors.
*/
#define XCV_INT_VEC_E_INT (0)
/**
* Register (RSL) xcv#_batch_crd_ret
*
* XCV Batch Credit Return Register
*/
union xcvx_batch_crd_ret {
u64 u;
struct xcvx_batch_crd_ret_s {
u64 crd_ret : 1;
u64 reserved_1_63 : 63;
} s;
/* struct xcvx_batch_crd_ret_s cn; */
};
static inline u64 XCVX_BATCH_CRD_RET(u64 a)
__attribute__ ((pure, always_inline));
static inline u64 XCVX_BATCH_CRD_RET(u64 a)
{
return 0x100 + 0 * a;
}
/**
* Register (RSL) xcv#_comp_ctl
*
* XCV Compensation Controller Register This register controls
* programmable compensation.
*/
union xcvx_comp_ctl {
u64 u;
struct xcvx_comp_ctl_s {
u64 nctl_sat : 1;
u64 reserved_1_26 : 26;
u64 nctl_lock : 1;
u64 reserved_28 : 1;
u64 pctl_sat : 1;
u64 pctl_lock : 1;
u64 reserved_31 : 1;
u64 drv_nctl : 5;
u64 reserved_37_39 : 3;
u64 drv_pctl : 5;
u64 reserved_45_47 : 3;
u64 cmp_nctl : 5;
u64 reserved_53_55 : 3;
u64 cmp_pctl : 5;
u64 reserved_61_62 : 2;
u64 drv_byp : 1;
} s;
/* struct xcvx_comp_ctl_s cn; */
};
static inline u64 XCVX_COMP_CTL(u64 a)
__attribute__ ((pure, always_inline));
static inline u64 XCVX_COMP_CTL(u64 a)
{
return 0x20 + 0 * a;
}
/**
* Register (RSL) xcv#_ctl
*
* XCV Control Register This register contains the status control bits.
*/
union xcvx_ctl {
u64 u;
struct xcvx_ctl_s {
u64 speed : 2;
u64 lpbk_int : 1;
u64 lpbk_ext : 1;
u64 reserved_4_63 : 60;
} s;
/* struct xcvx_ctl_s cn; */
};
static inline u64 XCVX_CTL(u64 a)
__attribute__ ((pure, always_inline));
static inline u64 XCVX_CTL(u64 a)
{
return 0x30 + 0 * a;
}
/**
* Register (RSL) xcv#_dll_ctl
*
* XCV DLL Controller Register The RGMII timing specification requires
* that devices transmit clock and data synchronously. The specification
* requires external sources (namely the PC board trace routes) to
* introduce the appropriate 1.5 to 2.0 ns of delay. To eliminate the
* need for the PC board delays, the RGMII interface has optional on-
* board DLLs for both transmit and receive. For correct operation, at
* most one of the transmitter, board, or receiver involved in an RGMII
* link should introduce delay. By default/reset, the RGMII receivers
* delay the received clock, and the RGMII transmitters do not delay the
* transmitted clock. Whether this default works as-is with a given link
* partner depends on the behavior of the link partner and the PC board.
* These are the possible modes of RGMII receive operation: *
* XCV()_DLL_CTL[CLKRX_BYP] = 0 (reset value) - The RGMII receive
* interface introduces clock delay using its internal DLL. This mode is
* appropriate if neither the remote transmitter nor the PC board delays
* the clock. * XCV()_DLL_CTL[CLKRX_BYP] = 1, [CLKRX_SET] = 0x0 - The
* RGMII receive interface introduces no clock delay. This mode is
* appropriate if either the remote transmitter or the PC board delays
* the clock. These are the possible modes of RGMII transmit operation:
* * XCV()_DLL_CTL[CLKTX_BYP] = 1, [CLKTX_SET] = 0x0 (reset value) - The
* RGMII transmit interface introduces no clock delay. This mode is
* appropriate is either the remote receiver or the PC board delays the
* clock. * XCV()_DLL_CTL[CLKTX_BYP] = 0 - The RGMII transmit interface
* introduces clock delay using its internal DLL. This mode is
* appropriate if neither the remote receiver nor the PC board delays the
* clock.
*/
union xcvx_dll_ctl {
u64 u;
struct xcvx_dll_ctl_s {
u64 refclk_sel : 2;
u64 reserved_2_7 : 6;
u64 clktx_set : 7;
u64 clktx_byp : 1;
u64 clkrx_set : 7;
u64 clkrx_byp : 1;
u64 clk_set : 7;
u64 lock : 1;
u64 reserved_32_63 : 32;
} s;
/* struct xcvx_dll_ctl_s cn; */
};
static inline u64 XCVX_DLL_CTL(u64 a)
__attribute__ ((pure, always_inline));
static inline u64 XCVX_DLL_CTL(u64 a)
{
return 0x10 + 0 * a;
}
/**
* Register (RSL) xcv#_eco
*
* INTERNAL: XCV ECO Register
*/
union xcvx_eco {
u64 u;
struct xcvx_eco_s {
u64 eco_rw : 16;
u64 reserved_16_63 : 48;
} s;
/* struct xcvx_eco_s cn; */
};
static inline u64 XCVX_ECO(u64 a)
__attribute__ ((pure, always_inline));
static inline u64 XCVX_ECO(u64 a)
{
return 0x200 + 0 * a;
}
/**
* Register (RSL) xcv#_inbnd_status
*
* XCV Inband Status Register This register contains RGMII inband status.
*/
union xcvx_inbnd_status {
u64 u;
struct xcvx_inbnd_status_s {
u64 link : 1;
u64 speed : 2;
u64 duplex : 1;
u64 reserved_4_63 : 60;
} s;
/* struct xcvx_inbnd_status_s cn; */
};
static inline u64 XCVX_INBND_STATUS(u64 a)
__attribute__ ((pure, always_inline));
static inline u64 XCVX_INBND_STATUS(u64 a)
{
return 0x80 + 0 * a;
}
/**
* Register (RSL) xcv#_int
*
* XCV Interrupt Register This register flags error for TX FIFO overflow,
* TX FIFO underflow and incomplete byte for 10/100 Mode. It also flags
* status change for link duplex, link speed and link up/down.
*/
union xcvx_int {
u64 u;
struct xcvx_int_s {
u64 link : 1;
u64 speed : 1;
u64 reserved_2 : 1;
u64 duplex : 1;
u64 incomp_byte : 1;
u64 tx_undflw : 1;
u64 tx_ovrflw : 1;
u64 reserved_7_63 : 57;
} s;
/* struct xcvx_int_s cn; */
};
static inline u64 XCVX_INT(u64 a)
__attribute__ ((pure, always_inline));
static inline u64 XCVX_INT(u64 a)
{
return 0x40 + 0 * a;
}
/**
* Register (RSL) xcv#_int_ena_w1c
*
* Loopback Error Interrupt Enable Clear Register This register clears
* interrupt enable bits.
*/
union xcvx_int_ena_w1c {
u64 u;
struct xcvx_int_ena_w1c_s {
u64 link : 1;
u64 speed : 1;
u64 reserved_2 : 1;
u64 duplex : 1;
u64 incomp_byte : 1;
u64 tx_undflw : 1;
u64 tx_ovrflw : 1;
u64 reserved_7_63 : 57;
} s;
/* struct xcvx_int_ena_w1c_s cn; */
};
static inline u64 XCVX_INT_ENA_W1C(u64 a)
__attribute__ ((pure, always_inline));
static inline u64 XCVX_INT_ENA_W1C(u64 a)
{
return 0x50 + 0 * a;
}
/**
* Register (RSL) xcv#_int_ena_w1s
*
* Loopback Error Interrupt Enable Set Register This register sets
* interrupt enable bits.
*/
union xcvx_int_ena_w1s {
u64 u;
struct xcvx_int_ena_w1s_s {
u64 link : 1;
u64 speed : 1;
u64 reserved_2 : 1;
u64 duplex : 1;
u64 incomp_byte : 1;
u64 tx_undflw : 1;
u64 tx_ovrflw : 1;
u64 reserved_7_63 : 57;
} s;
/* struct xcvx_int_ena_w1s_s cn; */
};
static inline u64 XCVX_INT_ENA_W1S(u64 a)
__attribute__ ((pure, always_inline));
static inline u64 XCVX_INT_ENA_W1S(u64 a)
{
return 0x58 + 0 * a;
}
/**
* Register (RSL) xcv#_int_w1s
*
* Loopback Error Interrupt Set Register This register sets interrupt
* bits.
*/
union xcvx_int_w1s {
u64 u;
struct xcvx_int_w1s_s {
u64 link : 1;
u64 speed : 1;
u64 reserved_2 : 1;
u64 duplex : 1;
u64 incomp_byte : 1;
u64 tx_undflw : 1;
u64 tx_ovrflw : 1;
u64 reserved_7_63 : 57;
} s;
/* struct xcvx_int_w1s_s cn; */
};
static inline u64 XCVX_INT_W1S(u64 a)
__attribute__ ((pure, always_inline));
static inline u64 XCVX_INT_W1S(u64 a)
{
return 0x48 + 0 * a;
}
/**
* Register (RSL) xcv#_msix_pba#
*
* XCV MSI-X Pending Bit Array Registers This register is the MSI-X PBA
* table; the bit number is indexed by the XCV_INT_VEC_E enumeration.
*/
union xcvx_msix_pbax {
u64 u;
struct xcvx_msix_pbax_s {
u64 pend : 64;
} s;
/* struct xcvx_msix_pbax_s cn; */
};
static inline u64 XCVX_MSIX_PBAX(u64 a, u64 b)
__attribute__ ((pure, always_inline));
static inline u64 XCVX_MSIX_PBAX(u64 a, u64 b)
{
return 0xf0000 + 0 * a + 8 * b;
}
/**
* Register (RSL) xcv#_msix_vec#_addr
*
* XCV MSI-X Vector-Table Address Register This register is the MSI-X
* vector table, indexed by the XCV_INT_VEC_E enumeration.
*/
union xcvx_msix_vecx_addr {
u64 u;
struct xcvx_msix_vecx_addr_s {
u64 secvec : 1;
u64 reserved_1 : 1;
u64 addr : 47;
u64 reserved_49_63 : 15;
} s;
/* struct xcvx_msix_vecx_addr_s cn; */
};
static inline u64 XCVX_MSIX_VECX_ADDR(u64 a, u64 b)
__attribute__ ((pure, always_inline));
static inline u64 XCVX_MSIX_VECX_ADDR(u64 a, u64 b)
{
return 0 + 0 * a + 0x10 * b;
}
/**
* Register (RSL) xcv#_msix_vec#_ctl
*
* XCV MSI-X Vector-Table Control and Data Register This register is the
* MSI-X vector table, indexed by the XCV_INT_VEC_E enumeration.
*/
union xcvx_msix_vecx_ctl {
u64 u;
struct xcvx_msix_vecx_ctl_s {
u64 data : 20;
u64 reserved_20_31 : 12;
u64 mask : 1;
u64 reserved_33_63 : 31;
} s;
/* struct xcvx_msix_vecx_ctl_s cn; */
};
static inline u64 XCVX_MSIX_VECX_CTL(u64 a, u64 b)
__attribute__ ((pure, always_inline));
static inline u64 XCVX_MSIX_VECX_CTL(u64 a, u64 b)
{
return 8 + 0 * a + 0x10 * b;
}
/**
* Register (RSL) xcv#_reset
*
* XCV Reset Registers This register controls reset.
*/
union xcvx_reset {
u64 u;
struct xcvx_reset_s {
u64 rx_dat_rst_n : 1;
u64 rx_pkt_rst_n : 1;
u64 tx_dat_rst_n : 1;
u64 tx_pkt_rst_n : 1;
u64 reserved_4_6 : 3;
u64 comp : 1;
u64 reserved_8_10 : 3;
u64 dllrst : 1;
u64 reserved_12_14 : 3;
u64 clkrst : 1;
u64 reserved_16_62 : 47;
u64 enable : 1;
} s;
/* struct xcvx_reset_s cn; */
};
static inline u64 XCVX_RESET(u64 a)
__attribute__ ((pure, always_inline));
static inline u64 XCVX_RESET(u64 a)
{
return 0 + 0 * a;
}
#endif /* __CSRS_XCV_H__ */

View File

@ -0,0 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/

View File

@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#ifndef __SMC_H__
#define __SMC_H__
/* OcteonTX Service Calls version numbers */
#define OCTEONTX_VERSION_MAJOR 0x1
#define OCTEONTX_VERSION_MINOR 0x0
/* x1 - node number */
#define OCTEONTX_DRAM_SIZE 0xc2000301
ssize_t smc_dram_size(unsigned int node);
#endif /* __SMC_H__ */

View File

@ -0,0 +1,33 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#ifndef __SOC_H__
#define __SOC_H__
/* Product PARTNUM */
#define CN81XX 0xA2
#define CN83XX 0xA3
#define CN96XX 0xB2
#define CN95XX 0xB3
#define otx_is_altpkg() read_alt_pkg()
#define otx_is_soc(soc) (read_partnum() == (soc))
#define otx_is_board(model) (!strcmp(read_board_name(), model))
#define otx_is_platform(platform) (read_platform() == (platform))
enum platform {
PLATFORM_HW = 0,
PLATFORM_EMULATOR = 1,
PLATFORM_ASIM = 3,
};
int read_platform(void);
u8 read_partnum(void);
const char *read_board_name(void);
bool read_alt_pkg(void);
#endif /* __SOC_H */

View File

@ -0,0 +1,128 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#ifndef __BOARD_H__
#define __BOARD_H__
#include <asm/arch/soc.h>
/** Reg offsets */
#define RST_BOOT 0x87E006001600ULL
#define CPC_BOOT_OWNERX(a) 0x86D000000160ULL + (8 * (a))
/** Structure definitions */
/**
* Register (NCB32b) cpc_boot_owner#
*
* CPC Boot Owner Registers These registers control an external arbiter
* for the boot device (SPI/eMMC) across multiple external devices. There
* is a register for each requester: _ \<0\> - SCP - reset on
* SCP reset _ \<1\> - MCP - reset on MCP reset _ \<2\> - AP
* Secure - reset on core reset _ \<3\> - AP Nonsecure - reset on core
* reset These register is only writable to the corresponding
* requestor(s) permitted with CPC_PERMIT.
*/
union cpc_boot_ownerx {
u32 u;
struct cpc_boot_ownerx_s {
u32 boot_req : 1;
u32 reserved_1_7 : 7;
u32 boot_wait : 1;
u32 reserved_9_31 : 23;
} s;
};
/**
* Register (RSL) rst_boot
*
* RST Boot Register This register is not accessible through ROM scripts;
* see SCR_WRITE32_S[ADDR].
*/
union rst_boot {
u64 u;
struct rst_boot_s {
u64 rboot_pin : 1;
u64 rboot : 1;
u64 reserved_2_32 : 31;
u64 pnr_mul : 6;
u64 reserved_39 : 1;
u64 c_mul : 7;
u64 reserved_47_52 : 6;
u64 gpio_ejtag : 1;
u64 mcp_jtagdis : 1;
u64 dis_scan : 1;
u64 dis_huk : 1;
u64 vrm_err : 1;
u64 jt_tstmode : 1;
u64 ckill_ppdis : 1;
u64 trusted_mode : 1;
u64 reserved_61_62 : 2;
u64 chipkill : 1;
} s;
struct rst_boot_cn96xx {
u64 rboot_pin : 1;
u64 rboot : 1;
u64 reserved_2_23 : 22;
u64 cpt_mul : 7;
u64 reserved_31_32 : 2;
u64 pnr_mul : 6;
u64 reserved_39 : 1;
u64 c_mul : 7;
u64 reserved_47_52 : 6;
u64 gpio_ejtag : 1;
u64 mcp_jtagdis : 1;
u64 dis_scan : 1;
u64 dis_huk : 1;
u64 vrm_err : 1;
u64 reserved_58_59 : 2;
u64 trusted_mode : 1;
u64 scp_jtagdis : 1;
u64 jtagdis : 1;
u64 chipkill : 1;
} cn96xx;
struct rst_boot_cnf95xx {
u64 rboot_pin : 1;
u64 rboot : 1;
u64 reserved_2_7 : 6;
u64 bphy_mul : 7;
u64 reserved_15 : 1;
u64 dsp_mul : 7;
u64 reserved_23 : 1;
u64 cpt_mul : 7;
u64 reserved_31_32 : 2;
u64 pnr_mul : 6;
u64 reserved_39 : 1;
u64 c_mul : 7;
u64 reserved_47_52 : 6;
u64 gpio_ejtag : 1;
u64 mcp_jtagdis : 1;
u64 dis_scan : 1;
u64 dis_huk : 1;
u64 vrm_err : 1;
u64 reserved_58_59 : 2;
u64 trusted_mode : 1;
u64 scp_jtagdis : 1;
u64 jtagdis : 1;
u64 chipkill : 1;
} cnf95xx;
};
extern unsigned long fdt_base_addr;
/** Function definitions */
void mem_map_fill(void);
int fdt_get_board_mac_cnt(void);
u64 fdt_get_board_mac_addr(void);
const char *fdt_get_board_model(void);
const char *fdt_get_board_serial(void);
const char *fdt_get_board_revision(void);
void octeontx2_board_get_mac_addr(u8 index, u8 *mac_addr);
void board_acquire_flash_arb(bool acquire);
void cgx_intf_shutdown(void);
#endif /* __BOARD_H__ */

View File

@ -0,0 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#ifndef __CLOCK_H__
/** System PLL reference clock */
#define PLL_REF_CLK 50000000 /* 50 MHz */
#define NS_PER_REF_CLK_TICK (1000000000 / PLL_REF_CLK)
/**
* Returns the I/O clock speed in Hz
*/
u64 octeontx_get_io_clock(void);
/**
* Returns the core clock speed in Hz
*/
u64 octeontx_get_core_clock(void);
#endif /* __CLOCK_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,60 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2020 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#ifndef __CSRS_LMT_H__
#define __CSRS_LMT_H__
/**
* @file
*
* Configuration and status register (CSR) address and type definitions for
* LMT.
*
* This file is auto generated. Do not edit.
*
*/
/**
* Register (RVU_PFVF_BAR2) lmt_lf_lmtcancel
*
* RVU VF LMT Cancel Register
*/
union lmt_lf_lmtcancel {
u64 u;
struct lmt_lf_lmtcancel_s {
u64 data : 64;
} s;
/* struct lmt_lf_lmtcancel_s cn; */
};
static inline u64 LMT_LF_LMTCANCEL(void)
__attribute__ ((pure, always_inline));
static inline u64 LMT_LF_LMTCANCEL(void)
{
return 0x400;
}
/**
* Register (RVU_PFVF_BAR2) lmt_lf_lmtline#
*
* RVU VF LMT Line Registers
*/
union lmt_lf_lmtlinex {
u64 u;
struct lmt_lf_lmtlinex_s {
u64 data : 64;
} s;
/* struct lmt_lf_lmtlinex_s cn; */
};
static inline u64 LMT_LF_LMTLINEX(u64 a)
__attribute__ ((pure, always_inline));
static inline u64 LMT_LF_LMTLINEX(u64 a)
{
return 0 + 8 * a;
}
#endif /* __CSRS_LMT_H__ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/

View File

@ -0,0 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#ifndef __SMC_ID_H__
#define __SMC_ID_H__
/* SMC function IDs for general purpose queries */
#define OCTEONTX2_SVC_CALL_COUNT 0xc200ff00
#define OCTEONTX2_SVC_UID 0xc200ff01
#define OCTEONTX2_SVC_VERSION 0xc200ff03
/* OcteonTX Service Calls version numbers */
#define OCTEONTX2_VERSION_MAJOR 0x1
#define OCTEONTX2_VERSION_MINOR 0x0
/* x1 - node number */
#define OCTEONTX2_DRAM_SIZE 0xc2000301
#define OCTEONTX2_NODE_COUNT 0xc2000601
#define OCTEONTX2_DISABLE_RVU_LFS 0xc2000b01
#define OCTEONTX2_CONFIG_OOO 0xc2000b04
/* fail safe */
#define OCTEONTX2_FSAFE_PR_BOOT_SUCCESS 0xc2000b02
#endif /* __SMC_ID_H__ */

View File

@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#ifndef __SMC_H__
#define __SMC_H__
#include <asm/arch/smc-id.h>
ssize_t smc_configure_ooo(unsigned int val);
ssize_t smc_dram_size(unsigned int node);
ssize_t smc_disable_rvu_lfs(unsigned int node);
ssize_t smc_flsf_fw_booted(void);
#endif

View File

@ -0,0 +1,33 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2019 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#ifndef __SOC_H__
#define __SOC_H__
/* Product PARTNUM */
#define CN81XX 0xA2
#define CN83XX 0xA3
#define CN96XX 0xB2
#define CN95XX 0xB3
/* Register defines */
#define otx_is_soc(soc) (read_partnum() == (soc))
#define otx_is_board(model) (!strcmp(read_board_name(), model))
#define otx_is_platform(platform) (read_platform() == (platform))
enum platform_t {
PLATFORM_HW = 0,
PLATFORM_EMULATOR = 1,
PLATFORM_ASIM = 3,
};
int read_platform(void);
u8 read_partnum(void);
const char *read_board_name(void);
#endif /* __SOC_H */

View File

@ -180,16 +180,20 @@ static inline void __raw_readsl(unsigned long addr, void *data, int longlen)
#define in_le32(a) in_arch(l,le32,a)
#define in_le16(a) in_arch(w,le16,a)
#define out_be64(a,v) out_arch(l,be64,a,v)
#define out_be32(a,v) out_arch(l,be32,a,v)
#define out_be16(a,v) out_arch(w,be16,a,v)
#define in_be64(a) in_arch(l,be64,a)
#define in_be32(a) in_arch(l,be32,a)
#define in_be16(a) in_arch(w,be16,a)
#define out_64(a,v) __raw_writeq(v,a)
#define out_32(a,v) __raw_writel(v,a)
#define out_16(a,v) __raw_writew(v,a)
#define out_8(a,v) __raw_writeb(v,a)
#define in_64(a) __raw_readq(a)
#define in_32(a) __raw_readl(a)
#define in_16(a) __raw_readw(a)
#define in_8(a) __raw_readb(a)
@ -231,6 +235,18 @@ static inline void __raw_readsl(unsigned long addr, void *data, int longlen)
#define setbits_8(addr, set) setbits(8, addr, set)
#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)
#define clrbits_be64(addr, clear) clrbits(be64, addr, clear)
#define setbits_be64(addr, set) setbits(be64, addr, set)
#define clrsetbits_be64(addr, clear, set) clrsetbits(be64, addr, clear, set)
#define clrbits_le64(addr, clear) clrbits(le64, addr, clear)
#define setbits_le64(addr, set) setbits(le64, addr, set)
#define clrsetbits_le64(addr, clear, set) clrsetbits(le64, addr, clear, set)
#define clrbits_64(addr, clear) clrbits(64, addr, clear)
#define setbits_64(addr, set) setbits(64, addr, set)
#define clrsetbits_64(addr, clear, set) clrsetbits(64, addr, clear, set)
/*
* Now, pick up the machine-defined IO definitions
*/

View File

@ -0,0 +1,23 @@
if ARCH_OCTEONTX
choice
prompt "OcteonTX board select"
optional
config TARGET_OCTEONTX_81XX
bool "Marvell OcteonTX CN81XX"
config TARGET_OCTEONTX_83XX
bool "Marvell OcteonTX CN83XX"
endchoice
config SYS_SOC
string
default "octeontx"
config SYS_PCI_64BIT
bool
default y
endif

View File

@ -0,0 +1,9 @@
#/* SPDX-License-Identifier: GPL-2.0
# *
# * Copyright (C) 2018 Marvell International Ltd.
# *
# * https://spdx.org/licenses
# */
obj-y += lowlevel_init.o clock.o cpu.o

View File

@ -0,0 +1,35 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#include <common.h>
#include <asm/io.h>
#include <asm/arch/board.h>
#include <asm/arch/clock.h>
/**
* Returns the I/O clock speed in Hz
*/
u64 octeontx_get_io_clock(void)
{
union rst_boot rst_boot;
rst_boot.u = readq(RST_BOOT);
return rst_boot.s.pnr_mul * PLL_REF_CLK;
}
/**
* Returns the core clock speed in Hz
*/
u64 octeontx_get_core_clock(void)
{
union rst_boot rst_boot;
rst_boot.u = readq(RST_BOOT);
return rst_boot.s.c_mul * PLL_REF_CLK;
}

View File

@ -0,0 +1,76 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#include <common.h>
#include <asm/armv8/mmu.h>
#include <asm/io.h>
#include <asm/arch/board.h>
DECLARE_GLOBAL_DATA_PTR;
#define OTX_MEM_MAP_USED 3
/* 1 for 83xx, +1 is end of list which needs to be empty */
#define OTX_MEM_MAP_MAX (OTX_MEM_MAP_USED + 1 + CONFIG_NR_DRAM_BANKS + 1)
static struct mm_region otx_mem_map[OTX_MEM_MAP_MAX] = {
{
.virt = 0x800000000000UL,
.phys = 0x800000000000UL,
.size = 0x40000000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE
}, {
.virt = 0x840000000000UL,
.phys = 0x840000000000UL,
.size = 0x40000000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE
}, {
.virt = 0x880000000000UL,
.phys = 0x880000000000UL,
.size = 0x40000000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE
}
};
struct mm_region *mem_map = otx_mem_map;
void mem_map_fill(void)
{
int banks = OTX_MEM_MAP_USED;
u32 dram_start = CONFIG_SYS_TEXT_BASE;
if (otx_is_soc(CN83XX)) {
otx_mem_map[banks].virt = 0x8c0000000000UL;
otx_mem_map[banks].phys = 0x8c0000000000UL;
otx_mem_map[banks].size = 0x40000000000UL;
otx_mem_map[banks].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE;
banks = banks + 1;
}
for (int i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
otx_mem_map[banks].virt = dram_start;
otx_mem_map[banks].phys = dram_start;
otx_mem_map[banks].size = gd->ram_size;
otx_mem_map[banks].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_NON_SHARE;
banks = banks + 1;
}
}
u64 get_page_table_size(void)
{
return 0x80000;
}
void reset_cpu(ulong addr)
{
}

View File

@ -0,0 +1,33 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#include <config.h>
#include <linux/linkage.h>
#include <asm/macro.h>
.align 8
.global fdt_base_addr
fdt_base_addr:
.dword 0x0
.global save_boot_params
save_boot_params:
/* Read FDT base from x1 register passed by ATF */
adr x21, fdt_base_addr
str x1, [x21]
/* Returns */
b save_boot_params_ret
ENTRY(lowlevel_init)
mov x29, lr /* Save LR */
/* any lowlevel init should go here */
mov lr, x29 /* Restore LR */
ret
ENDPROC(lowlevel_init)

View File

@ -0,0 +1,23 @@
if ARCH_OCTEONTX2
choice
prompt "OcteonTX2 board select"
optional
config TARGET_OCTEONTX2_95XX
bool "Marvell OcteonTX2 CN95XX"
config TARGET_OCTEONTX2_96XX
bool "Marvell OcteonTX2 CN96XX"
endchoice
config SYS_SOC
string
default "octeontx2"
config SYS_PCI_64BIT
bool
default y
endif

View File

@ -0,0 +1,9 @@
#/*
# * Copyright (C) 2018 Marvell International Ltd.
# *
# * SPDX-License-Identifier: GPL-2.0
# * https://spdx.org/licenses
# */
obj-y += lowlevel_init.o clock.o cpu.o

View File

@ -0,0 +1,35 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#include <common.h>
#include <asm/io.h>
#include <asm/arch/board.h>
#include <asm/arch/clock.h>
/**
* Returns the I/O clock speed in Hz
*/
u64 octeontx_get_io_clock(void)
{
union rst_boot rst_boot;
rst_boot.u = readq(RST_BOOT);
return rst_boot.s.pnr_mul * PLL_REF_CLK;
}
/**
* Returns the core clock speed in Hz
*/
u64 octeontx_get_core_clock(void)
{
union rst_boot rst_boot;
rst_boot.u = readq(RST_BOOT);
return rst_boot.s.c_mul * PLL_REF_CLK;
}

View File

@ -0,0 +1,4 @@
ifeq ($(CONFIG_ARCH_OCTEONTX2),y)
PLATFORM_CPPFLAGS += $(call cc-option,-march=armv8.2-a,)
PLATFORM_CPPFLAGS += $(call cc-option,-mtune=octeontx2,)
endif

View File

@ -0,0 +1,72 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#include <common.h>
#include <asm/armv8/mmu.h>
#include <asm/io.h>
#include <asm/arch/board.h>
DECLARE_GLOBAL_DATA_PTR;
#define OTX2_MEM_MAP_USED 4
/* +1 is end of list which needs to be empty */
#define OTX2_MEM_MAP_MAX (OTX2_MEM_MAP_USED + CONFIG_NR_DRAM_BANKS + 1)
static struct mm_region otx2_mem_map[OTX2_MEM_MAP_MAX] = {
{
.virt = 0x800000000000UL,
.phys = 0x800000000000UL,
.size = 0x40000000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE
}, {
.virt = 0x840000000000UL,
.phys = 0x840000000000UL,
.size = 0x40000000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE
}, {
.virt = 0x880000000000UL,
.phys = 0x880000000000UL,
.size = 0x40000000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE
}, {
.virt = 0x8c0000000000UL,
.phys = 0x8c0000000000UL,
.size = 0x40000000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE
}
};
struct mm_region *mem_map = otx2_mem_map;
void mem_map_fill(void)
{
int banks = OTX2_MEM_MAP_USED;
u32 dram_start = CONFIG_SYS_TEXT_BASE;
for (int i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
otx2_mem_map[banks].virt = dram_start;
otx2_mem_map[banks].phys = dram_start;
otx2_mem_map[banks].size = gd->ram_size;
otx2_mem_map[banks].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_NON_SHARE;
banks = banks + 1;
}
}
u64 get_page_table_size(void)
{
return 0x80000;
}
void reset_cpu(ulong addr)
{
}

View File

@ -0,0 +1,33 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#include <config.h>
#include <linux/linkage.h>
#include <asm/macro.h>
.align 8
.global fdt_base_addr
fdt_base_addr:
.dword 0x0
.global save_boot_params
save_boot_params:
/* Read FDT base from x1 register passed by ATF */
adr x21, fdt_base_addr
str x1, [x21]
/* Returns */
b save_boot_params_ret
ENTRY(lowlevel_init)
mov x29, lr /* Save LR */
/* any lowlevel init should go here */
mov lr, x29 /* Restore LR */
ret
ENDPROC(lowlevel_init)

View File

@ -666,8 +666,9 @@
bus-range = <0x00 0xff>;
#address-cells = <3>;
#size-cells = <2>;
ranges = <0x02000000 0 0x30000000 0x30000000 0 0x2000
0x01000000 0 0x40000000 0x40000000 0 0x2000>;
ranges = <0x02000000 0 0x30000000 0x30000000 0 0x2000 // MEM0
0x02000000 0 0x31000000 0x31000000 0 0x2000 // MEM1
0x01000000 0 0x40000000 0x40000000 0 0x2000>;
sandbox,dev-info = <0x08 0x00 0x1234 0x5678
0x0c 0x00 0x1234 0x5678
0x10 0x00 0x1234 0x5678>;

View File

@ -0,0 +1,14 @@
if TARGET_OCTEONTX_81XX || TARGET_OCTEONTX_83XX
config SYS_VENDOR
string
default "Marvell"
config SYS_BOARD
string
default "octeontx"
config SYS_CONFIG_NAME
default "octeontx_common"
endif

View File

@ -0,0 +1,8 @@
OCTEONTX BOARD
M: Aaron Williams <awilliams@marvell.com>
S: Maintained
F: board/Marvell/octeontx/
F: include/configs/octeontx_81xx.h
F: include/configs/octeontx_83xx.h
F: configs/octeontx_81xx_defconfig
F: configs/octeontx_83xx_defconfig

View File

@ -0,0 +1,9 @@
#/*
# * Copyright (C) 2018 Marvell International Ltd.
# *
# * SPDX-License-Identifier: GPL-2.0
# * https://spdx.org/licenses
# */
obj-y := board.o smc.o soc-utils.o
obj-$(CONFIG_OF_LIBFDT) += board-fdt.o

View File

@ -0,0 +1,311 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#include <errno.h>
#include <env.h>
#include <log.h>
#include <net.h>
#include <asm/io.h>
#include <linux/compiler.h>
#include <linux/libfdt.h>
#include <fdtdec.h>
#include <fdt_support.h>
#include <asm/arch/board.h>
#include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
static int fdt_get_mdio_bus(const void *fdt, int phy_offset)
{
int node, bus = -1;
const u64 *reg;
u64 addr;
if (phy_offset < 0)
return -1;
/* obtain mdio node and get the reg prop */
node = fdt_parent_offset(fdt, phy_offset);
if (node < 0)
return -1;
reg = fdt_getprop(fdt, node, "reg", NULL);
addr = fdt64_to_cpu(*reg);
bus = (addr & (1 << 7)) ? 1 : 0;
return bus;
}
static int fdt_get_phy_addr(const void *fdt, int phy_offset)
{
const u32 *reg;
int addr = -1;
if (phy_offset < 0)
return -1;
reg = fdt_getprop(fdt, phy_offset, "reg", NULL);
addr = fdt32_to_cpu(*reg);
return addr;
}
void fdt_parse_phy_info(void)
{
const void *fdt = gd->fdt_blob;
int offset = 0, node, bgx_id = 0, lmacid = 0;
const u32 *val;
char bgxname[24];
int len, rgx_id = 0, eth_id = 0;
int phandle, phy_offset;
int subnode, i;
int bdknode;
bdknode = fdt_path_offset(fdt, "/cavium,bdk");
if (bdknode < 0) {
printf("%s: bdk node is missing from device tree: %s\n",
__func__, fdt_strerror(bdknode));
}
offset = fdt_node_offset_by_compatible(fdt, -1, "pci-bridge");
if (offset < 1)
return;
for (bgx_id = 0; bgx_id < MAX_BGX_PER_NODE; bgx_id++) {
int phy_addr[LMAC_CNT] = {[0 ... LMAC_CNT - 1] = -1};
bool autoneg_dis[LMAC_CNT] = {[0 ... LMAC_CNT - 1] = 0};
int mdio_bus[LMAC_CNT] = {[0 ... LMAC_CNT - 1] = -1};
bool lmac_reg[LMAC_CNT] = {[0 ... LMAC_CNT - 1] = 0};
bool lmac_enable[LMAC_CNT] = {[0 ... LMAC_CNT - 1] = 0};
snprintf(bgxname, sizeof(bgxname), "bgx%d", bgx_id);
node = fdt_subnode_offset(fdt, offset, bgxname);
if (node < 0) {
/* check if it is rgx node */
snprintf(bgxname, sizeof(bgxname), "rgx%d", rgx_id);
node = fdt_subnode_offset(fdt, offset, bgxname);
if (node < 0) {
debug("bgx%d/rgx0 node not found\n", bgx_id);
return;
}
}
debug("bgx%d node found\n", bgx_id);
/*
* loop through each of the bgx/rgx nodes
* to find PHY nodes
*/
fdt_for_each_subnode(subnode, fdt, node) {
/* Check for reg property */
val = fdt_getprop(fdt, subnode, "reg", &len);
if (val) {
debug("lmacid = %d\n", lmacid);
lmac_reg[lmacid] = 1;
}
/* check for phy-handle property */
val = fdt_getprop(fdt, subnode, "phy-handle", &len);
if (val) {
phandle = fdt32_to_cpu(*val);
if (!phandle) {
debug("phandle not valid %d\n", lmacid);
} else {
phy_offset = fdt_node_offset_by_phandle
(fdt, phandle);
phy_addr[lmacid] = fdt_get_phy_addr
(fdt, phy_offset);
mdio_bus[lmacid] = fdt_get_mdio_bus
(fdt, phy_offset);
}
} else {
debug("phy-handle prop not found %d\n",
lmacid);
}
/* check for autonegotiation property */
val = fdt_getprop(fdt, subnode,
"cavium,disable-autonegotiation",
&len);
if (val)
autoneg_dis[lmacid] = 1;
eth_id++;
lmacid++;
}
for (i = 0; i < MAX_LMAC_PER_BGX; i++) {
const char *str;
snprintf(bgxname, sizeof(bgxname),
"BGX-ENABLE.N0.BGX%d.P%d", bgx_id, i);
if (bdknode >= 0) {
str = fdt_getprop(fdt, bdknode,
bgxname, &len);
if (str)
lmac_enable[i] =
simple_strtol(str, NULL,
10);
}
}
lmacid = 0;
bgx_set_board_info(bgx_id, mdio_bus, phy_addr,
autoneg_dis, lmac_reg, lmac_enable);
}
}
static int fdt_get_bdk_node(void)
{
int node, ret;
const void *fdt = gd->fdt_blob;
if (!fdt) {
printf("ERROR: %s: no valid device tree found\n", __func__);
return 0;
}
ret = fdt_check_header(fdt);
if (ret < 0) {
printf("fdt: %s\n", fdt_strerror(ret));
return 0;
}
node = fdt_path_offset(fdt, "/cavium,bdk");
if (node < 0) {
printf("%s: /cavium,bdk is missing from device tree: %s\n",
__func__, fdt_strerror(node));
return 0;
}
return node;
}
const char *fdt_get_board_serial(void)
{
const void *fdt = gd->fdt_blob;
int node, len = 64;
const char *str = NULL;
node = fdt_get_bdk_node();
if (!node)
return NULL;
str = fdt_getprop(fdt, node, "BOARD-SERIAL", &len);
if (!str)
printf("Error: cannot retrieve board serial from fdt\n");
return str;
}
const char *fdt_get_board_revision(void)
{
const void *fdt = gd->fdt_blob;
int node, len = 64;
const char *str = NULL;
node = fdt_get_bdk_node();
if (!node)
return NULL;
str = fdt_getprop(fdt, node, "BOARD-REVISION", &len);
if (!str)
printf("Error: cannot retrieve board revision from fdt\n");
return str;
}
const char *fdt_get_board_model(void)
{
const void *fdt = gd->fdt_blob;
int node, len = 16;
const char *str = NULL;
node = fdt_get_bdk_node();
if (!node)
return NULL;
str = fdt_getprop(fdt, node, "BOARD-MODEL", &len);
if (!str)
printf("Error: cannot retrieve board model from fdt\n");
return str;
}
void fdt_board_get_ethaddr(int bgx, int lmac, unsigned char *eth)
{
const void *fdt = gd->fdt_blob;
const char *mac = NULL;
int offset = 0, node, len;
int subnode, i = 0;
char bgxname[24];
offset = fdt_node_offset_by_compatible(fdt, -1, "pci-bridge");
if (offset < 0) {
printf("%s couldn't find mrml bridge node in fdt\n",
__func__);
return;
}
if (bgx == 2 && otx_is_soc(CN81XX)) {
snprintf(bgxname, sizeof(bgxname), "rgx%d", 0);
lmac = 0;
} else {
snprintf(bgxname, sizeof(bgxname), "bgx%d", bgx);
}
node = fdt_subnode_offset(fdt, offset, bgxname);
fdt_for_each_subnode(subnode, fdt, node) {
if (i++ != lmac)
continue;
/* check for local-mac-address */
mac = fdt_getprop(fdt, subnode, "local-mac-address", &len);
if (mac) {
debug("%s mac %pM\n", __func__, mac);
memcpy(eth, mac, ARP_HLEN);
} else {
memset(eth, 0, ARP_HLEN);
}
debug("%s eth %pM\n", __func__, eth);
return;
}
}
int arch_fixup_memory_node(void *blob)
{
return 0;
}
int ft_board_setup(void *blob, struct bd_info *bd)
{
/* remove "cavium, bdk" node from DT */
int ret = 0, offset;
ret = fdt_check_header(blob);
if (ret < 0) {
printf("ERROR: %s\n", fdt_strerror(ret));
return ret;
}
if (blob) {
offset = fdt_path_offset(blob, "/cavium,bdk");
if (offset < 0) {
printf("ERROR: FDT BDK node not found\n");
return offset;
}
/* delete node */
ret = fdt_del_node(blob, offset);
if (ret < 0) {
printf("WARNING : could not remove bdk node\n");
return ret;
}
debug("%s deleted bdk node\n", __func__);
}
return 0;
}
/**
* Return the FDT base address that was passed by ATF
*
* @return FDT base address received from ATF in x1 register
*/
void *board_fdt_blob_setup(void)
{
return (void *)fdt_base_addr;
}

View File

@ -0,0 +1,152 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#include <dm.h>
#include <malloc.h>
#include <errno.h>
#include <env.h>
#include <init.h>
#include <log.h>
#include <netdev.h>
#include <pci_ids.h>
#include <asm/io.h>
#include <linux/compiler.h>
#include <linux/libfdt.h>
#include <fdt_support.h>
#include <asm/arch/smc.h>
#include <asm/arch/soc.h>
#include <asm/arch/board.h>
#include <dm/util.h>
DECLARE_GLOBAL_DATA_PTR;
void octeontx_cleanup_ethaddr(void)
{
char ename[32];
for (int i = 0; i < 20; i++) {
sprintf(ename, i ? "eth%daddr" : "ethaddr", i);
if (env_get(ename))
env_set(ename, NULL);
}
}
int octeontx_board_has_pmp(void)
{
return (otx_is_board("sff8104") || otx_is_board("nas8104"));
}
int board_early_init_r(void)
{
pci_init();
return 0;
}
int board_init(void)
{
if (IS_ENABLED(CONFIG_NET_OCTEONTX))
fdt_parse_phy_info();
return 0;
}
int timer_init(void)
{
return 0;
}
int dram_init(void)
{
gd->ram_size = smc_dram_size(0);
gd->ram_size -= CONFIG_SYS_SDRAM_BASE;
mem_map_fill();
return 0;
}
void board_late_probe_devices(void)
{
struct udevice *dev;
int err, bgx_cnt, i;
/* Probe MAC(BGX) and NIC PF devices before Network stack init */
bgx_cnt = otx_is_soc(CN81XX) ? 2 : 4;
for (i = 0; i < bgx_cnt; i++) {
err = dm_pci_find_device(PCI_VENDOR_ID_CAVIUM,
PCI_DEVICE_ID_CAVIUM_BGX, i, &dev);
if (err)
debug("%s BGX%d device not found\n", __func__, i);
}
if (otx_is_soc(CN81XX)) {
err = dm_pci_find_device(PCI_VENDOR_ID_CAVIUM,
PCI_DEVICE_ID_CAVIUM_RGX, 0, &dev);
if (err)
debug("%s RGX device not found\n", __func__);
}
err = dm_pci_find_device(PCI_VENDOR_ID_CAVIUM,
PCI_DEVICE_ID_CAVIUM_NIC, 0, &dev);
if (err)
debug("NIC PF device not found\n");
}
/**
* Board late initialization routine.
*/
int board_late_init(void)
{
char boardname[32];
char boardserial[150], boardrev[150];
bool save_env = false;
const char *str;
/*
* Try to cleanup ethaddr env variables, this is needed
* as with each boot, configuration of network interfaces can change.
*/
octeontx_cleanup_ethaddr();
snprintf(boardname, sizeof(boardname), "%s> ", fdt_get_board_model());
env_set("prompt", boardname);
set_working_fdt_addr(env_get_hex("fdtcontroladdr", fdt_base_addr));
str = fdt_get_board_revision();
if (str) {
snprintf(boardrev, sizeof(boardrev), "%s", str);
if (env_get("boardrev") &&
strcmp(boardrev, env_get("boardrev")))
save_env = true;
env_set("boardrev", boardrev);
}
str = fdt_get_board_serial();
if (str) {
snprintf(boardserial, sizeof(boardserial), "%s", str);
if (env_get("serial#") &&
strcmp(boardserial, env_get("serial#")))
save_env = true;
env_set("serial#", boardserial);
}
if (IS_ENABLED(CONFIG_NET_OCTEONTX))
board_late_probe_devices();
if (save_env)
env_save();
return 0;
}
/*
* Invoked before relocation, so limit to stack variables.
*/
int checkboard(void)
{
printf("Board: %s\n", fdt_get_board_model());
return 0;
}

View File

@ -0,0 +1,25 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#include <asm/global_data.h>
#include <asm/ptrace.h>
#include <asm/system.h>
#include <asm/arch/smc.h>
DECLARE_GLOBAL_DATA_PTR;
ssize_t smc_dram_size(unsigned int node)
{
struct pt_regs regs;
regs.regs[0] = OCTEONTX_DRAM_SIZE;
regs.regs[1] = node;
smc_call(&regs);
return regs.regs[0];
}

View File

@ -0,0 +1,50 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#include <dm.h>
#include <dm/util.h>
#include <errno.h>
#include <malloc.h>
#include <asm/io.h>
#include <asm/arch/soc.h>
#include <asm/arch/board.h>
int read_platform(void)
{
int plat = PLATFORM_HW;
const char *model = fdt_get_board_model();
if (model && !strncmp(model, "ASIM-", 5))
plat = PLATFORM_ASIM;
if (model && !strncmp(model, "EMUL-", 5))
plat = PLATFORM_EMULATOR;
return plat;
}
static inline u64 read_midr(void)
{
u64 result;
asm ("mrs %[rd],MIDR_EL1" : [rd] "=r" (result));
return result;
}
u8 read_partnum(void)
{
return ((read_midr() >> 4) & 0xFF);
}
const char *read_board_name(void)
{
return fdt_get_board_model();
}
bool read_alt_pkg(void)
{
return false;
}

View File

@ -0,0 +1,14 @@
if TARGET_OCTEONTX2_95XX || TARGET_OCTEONTX2_96XX
config SYS_VENDOR
string
default "Marvell"
config SYS_BOARD
string
default "octeontx2"
config SYS_CONFIG_NAME
default "octeontx2_common"
endif

View File

@ -0,0 +1,8 @@
OCTEONTX2 BOARD
M: Aaron Williams <awilliams@marvell.com>
S: Maintained
F: board/Marvell/octeontx2/
F: include/configs/octeontx2_96xx.h
F: include/configs/octeontx2_95xx.h
F: configs/octeontx2_96xx_defconfig
F: configs/octeontx2_95xx_defconfig

View File

@ -0,0 +1,9 @@
#/* SPDX-License-Identifier: GPL-2.0
# *
# * Copyright (C) 2018 Marvell International Ltd.
# *
# * https://spdx.org/licenses
# */
obj-y := board.o smc.o soc-utils.o
obj-$(CONFIG_OF_LIBFDT) += board-fdt.o

View File

@ -0,0 +1,221 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#include <errno.h>
#include <fdtdec.h>
#include <fdt_support.h>
#include <log.h>
#include <linux/compiler.h>
#include <linux/libfdt.h>
#include <asm/arch/board.h>
#include <asm/arch/smc.h>
#include <asm/global_data.h>
#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
static int fdt_get_bdk_node(void)
{
int node, ret;
const void *fdt = gd->fdt_blob;
if (!fdt) {
printf("ERROR: %s: no valid device tree found\n", __func__);
return 0;
}
ret = fdt_check_header(fdt);
if (ret < 0) {
printf("fdt: %s\n", fdt_strerror(ret));
return 0;
}
node = fdt_path_offset(fdt, "/cavium,bdk");
if (node < 0) {
printf("%s: /cavium,bdk is missing from device tree: %s\n",
__func__, fdt_strerror(node));
return 0;
}
return node;
}
u64 fdt_get_board_mac_addr(void)
{
int node, len = 16;
const char *str = NULL;
const void *fdt = gd->fdt_blob;
u64 mac_addr = 0;
node = fdt_get_bdk_node();
if (!node)
return mac_addr;
str = fdt_getprop(fdt, node, "BOARD-MAC-ADDRESS", &len);
if (str)
mac_addr = simple_strtol(str, NULL, 16);
return mac_addr;
}
int fdt_get_board_mac_cnt(void)
{
int node, len = 16;
const char *str = NULL;
const void *fdt = gd->fdt_blob;
int mac_count = 0;
node = fdt_get_bdk_node();
if (!node)
return mac_count;
str = fdt_getprop(fdt, node, "BOARD-MAC-ADDRESS-NUM", &len);
if (str) {
mac_count = simple_strtol(str, NULL, 10);
if (!mac_count)
mac_count = simple_strtol(str, NULL, 16);
debug("fdt: MAC_NUM %d\n", mac_count);
} else {
printf("Error: cannot retrieve mac count prop from fdt\n");
}
str = fdt_getprop(gd->fdt_blob, node, "BOARD-MAC-ADDRESS-NUM-OVERRIDE",
&len);
if (str) {
if (simple_strtol(str, NULL, 10) >= 0)
mac_count = simple_strtol(str, NULL, 10);
debug("fdt: MAC_NUM %d\n", mac_count);
} else {
printf("Error: cannot retrieve mac num override prop\n");
}
return mac_count;
}
const char *fdt_get_board_serial(void)
{
const void *fdt = gd->fdt_blob;
int node, len = 64;
const char *str = NULL;
node = fdt_get_bdk_node();
if (!node)
return NULL;
str = fdt_getprop(fdt, node, "BOARD-SERIAL", &len);
if (!str)
printf("Error: cannot retrieve board serial from fdt\n");
return str;
}
const char *fdt_get_board_revision(void)
{
const void *fdt = gd->fdt_blob;
int node, len = 64;
const char *str = NULL;
node = fdt_get_bdk_node();
if (!node)
return NULL;
str = fdt_getprop(fdt, node, "BOARD-REVISION", &len);
if (!str)
printf("Error: cannot retrieve board revision from fdt\n");
return str;
}
const char *fdt_get_board_model(void)
{
int node, len = 16;
const char *str = NULL;
const void *fdt = gd->fdt_blob;
node = fdt_get_bdk_node();
if (!node)
return NULL;
str = fdt_getprop(fdt, node, "BOARD-MODEL", &len);
if (!str)
printf("Error: cannot retrieve board model from fdt\n");
return str;
}
int arch_fixup_memory_node(void *blob)
{
return 0;
}
int ft_board_setup(void *blob, struct bd_info *bd)
{
int nodeoff, node, ret, i;
const char *temp;
static const char * const
octeontx_brd_nodes[] = {"BOARD-MODEL",
"BOARD-SERIAL",
"BOARD-MAC-ADDRESS",
"BOARD-REVISION",
"BOARD-MAC-ADDRESS-NUM"
};
char nodes[ARRAY_SIZE(octeontx_brd_nodes)][32];
ret = fdt_check_header(blob);
if (ret < 0) {
printf("ERROR: %s\n", fdt_strerror(ret));
return ret;
}
if (blob) {
nodeoff = fdt_path_offset(blob, "/cavium,bdk");
if (nodeoff < 0) {
printf("ERROR: FDT BDK node not found\n");
return nodeoff;
}
/* Read properties in temporary variables */
for (i = 0; i < ARRAY_SIZE(octeontx_brd_nodes); i++) {
temp = fdt_getprop(blob, nodeoff,
octeontx_brd_nodes[i], NULL);
strncpy(nodes[i], temp, sizeof(nodes[i]));
}
/* Delete cavium,bdk node */
ret = fdt_del_node(blob, nodeoff);
if (ret < 0) {
printf("WARNING : could not remove cavium, bdk node\n");
return ret;
}
debug("%s deleted 'cavium,bdk' node\n", __func__);
/*
* Add a new node at root level which would have
* necessary info
*/
node = fdt_add_subnode(blob, 0, "octeontx_brd");
if (node < 0) {
printf("Cannot create node octeontx_brd: %s\n",
fdt_strerror(node));
return -EIO;
}
/* Populate properties in node */
for (i = 0; i < ARRAY_SIZE(octeontx_brd_nodes); i++) {
if (fdt_setprop_string(blob, node,
octeontx_brd_nodes[i],
nodes[i])) {
printf("Can't set %s\n", nodes[i]);
return -EIO;
}
}
}
return 0;
}
/**
* Return the FDT base address that was passed by ATF
*
* @return FDT base address received from ATF in x1 register
*/
void *board_fdt_blob_setup(void)
{
return (void *)fdt_base_addr;
}

View File

@ -0,0 +1,247 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#include <command.h>
#include <console.h>
#include <cpu_func.h>
#include <dm.h>
#include <dm/uclass-internal.h>
#include <env.h>
#include <init.h>
#include <malloc.h>
#include <net.h>
#include <pci_ids.h>
#include <errno.h>
#include <asm/io.h>
#include <linux/compiler.h>
#include <linux/delay.h>
#include <linux/libfdt.h>
#include <fdt_support.h>
#include <asm/arch/smc.h>
#include <asm/arch/soc.h>
#include <asm/arch/board.h>
#include <dm/util.h>
DECLARE_GLOBAL_DATA_PTR;
void cleanup_env_ethaddr(void)
{
char ename[32];
for (int i = 0; i < 20; i++) {
sprintf(ename, i ? "eth%daddr" : "ethaddr", i);
if (env_get(ename))
env_set(ename, NULL);
}
}
void octeontx2_board_get_mac_addr(u8 index, u8 *mac_addr)
{
u64 tmp_mac, board_mac_addr = fdt_get_board_mac_addr();
static int board_mac_num;
board_mac_num = fdt_get_board_mac_cnt();
if ((!is_zero_ethaddr((u8 *)&board_mac_addr)) && board_mac_num) {
tmp_mac = board_mac_addr;
tmp_mac += index;
tmp_mac = swab64(tmp_mac) >> 16;
memcpy(mac_addr, (u8 *)&tmp_mac, ARP_HLEN);
board_mac_num--;
} else {
memset(mac_addr, 0, ARP_HLEN);
}
debug("%s mac %pM\n", __func__, mac_addr);
}
void board_quiesce_devices(void)
{
struct uclass *uc_dev;
int ret;
/* Removes all RVU PF devices */
ret = uclass_get(UCLASS_ETH, &uc_dev);
if (uc_dev)
ret = uclass_destroy(uc_dev);
if (ret)
printf("couldn't remove rvu pf devices\n");
if (IS_ENABLED(CONFIG_OCTEONTX2_CGX_INTF)) {
/* Bring down all cgx lmac links */
cgx_intf_shutdown();
}
/* Removes all CGX and RVU AF devices */
ret = uclass_get(UCLASS_MISC, &uc_dev);
if (uc_dev)
ret = uclass_destroy(uc_dev);
if (ret)
printf("couldn't remove misc (cgx/rvu_af) devices\n");
/* SMC call - removes all LF<->PF mappings */
smc_disable_rvu_lfs(0);
}
int board_early_init_r(void)
{
pci_init();
return 0;
}
int board_init(void)
{
return 0;
}
int timer_init(void)
{
return 0;
}
int dram_init(void)
{
gd->ram_size = smc_dram_size(0);
gd->ram_size -= CONFIG_SYS_SDRAM_BASE;
mem_map_fill();
return 0;
}
void board_late_probe_devices(void)
{
struct udevice *dev;
int err, cgx_cnt = 3, i;
/* Probe MAC(CGX) and NIC AF devices before Network stack init */
for (i = 0; i < cgx_cnt; i++) {
err = dm_pci_find_device(PCI_VENDOR_ID_CAVIUM,
PCI_DEVICE_ID_CAVIUM_CGX, i, &dev);
if (err)
debug("%s CGX%d device not found\n", __func__, i);
}
err = dm_pci_find_device(PCI_VENDOR_ID_CAVIUM,
PCI_DEVICE_ID_CAVIUM_RVU_AF, 0, &dev);
if (err)
debug("NIC AF device not found\n");
}
/**
* Board late initialization routine.
*/
int board_late_init(void)
{
char boardname[32];
char boardserial[150], boardrev[150];
long val;
bool save_env = false;
const char *str;
debug("%s()\n", __func__);
/*
* Now that pci_init initializes env device.
* Try to cleanup ethaddr env variables, this is needed
* as with each boot, configuration of QLM can change.
*/
cleanup_env_ethaddr();
snprintf(boardname, sizeof(boardname), "%s> ", fdt_get_board_model());
env_set("prompt", boardname);
set_working_fdt_addr(env_get_hex("fdtcontroladdr", fdt_base_addr));
str = fdt_get_board_revision();
if (str) {
snprintf(boardrev, sizeof(boardrev), "%s", str);
if (env_get("boardrev") &&
strcmp(boardrev, env_get("boardrev")))
save_env = true;
env_set("boardrev", boardrev);
}
str = fdt_get_board_serial();
if (str) {
snprintf(boardserial, sizeof(boardserial), "%s", str);
if (env_get("serial#") &&
strcmp(boardserial, env_get("serial#")))
save_env = true;
env_set("serial#", boardserial);
}
val = env_get_hex("disable_ooo", 0);
smc_configure_ooo(val);
if (IS_ENABLED(CONFIG_NET_OCTEONTX2))
board_late_probe_devices();
if (save_env)
env_save();
return 0;
}
/*
* Invoked before relocation, so limit to stack variables.
*/
int checkboard(void)
{
printf("Board: %s\n", fdt_get_board_model());
return 0;
}
void board_acquire_flash_arb(bool acquire)
{
union cpc_boot_ownerx ownerx;
if (!acquire) {
ownerx.u = readl(CPC_BOOT_OWNERX(3));
ownerx.s.boot_req = 0;
writel(ownerx.u, CPC_BOOT_OWNERX(3));
} else {
ownerx.u = 0;
ownerx.s.boot_req = 1;
writel(ownerx.u, CPC_BOOT_OWNERX(3));
udelay(1);
do {
ownerx.u = readl(CPC_BOOT_OWNERX(3));
} while (ownerx.s.boot_wait);
}
}
int last_stage_init(void)
{
(void)smc_flsf_fw_booted();
return 0;
}
static int do_go_uboot(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
typedef void __noreturn (*uboot_entry_t)(ulong, void *);
uboot_entry_t entry;
ulong addr;
void *fdt;
if (argc < 2)
return CMD_RET_USAGE;
addr = simple_strtoul(argv[1], NULL, 16);
fdt = board_fdt_blob_setup();
entry = (uboot_entry_t)addr;
flush_cache((ulong)addr, 1 << 20); /* 1MiB should be enough */
dcache_disable();
printf("## Starting U-Boot at %p (FDT at %p)...\n", entry, fdt);
entry(0, fdt);
return 0;
}
U_BOOT_CMD(go_uboot, 2, 0, do_go_uboot,
"Start U-Boot from RAM (pass FDT via x1 register)",
"");

View File

@ -0,0 +1,58 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#include <asm/global_data.h>
#include <asm/io.h>
#include <asm/psci.h>
#include <asm/ptrace.h>
#include <asm/system.h>
#include <asm/arch/smc.h>
DECLARE_GLOBAL_DATA_PTR;
ssize_t smc_dram_size(unsigned int node)
{
struct pt_regs regs;
regs.regs[0] = OCTEONTX2_DRAM_SIZE;
regs.regs[1] = node;
smc_call(&regs);
return regs.regs[0];
}
ssize_t smc_disable_rvu_lfs(unsigned int node)
{
struct pt_regs regs;
regs.regs[0] = OCTEONTX2_DISABLE_RVU_LFS;
regs.regs[1] = node;
smc_call(&regs);
return regs.regs[0];
}
ssize_t smc_configure_ooo(unsigned int val)
{
struct pt_regs regs;
regs.regs[0] = OCTEONTX2_CONFIG_OOO;
regs.regs[1] = val;
smc_call(&regs);
return regs.regs[0];
}
ssize_t smc_flsf_fw_booted(void)
{
struct pt_regs regs;
regs.regs[0] = OCTEONTX2_FSAFE_PR_BOOT_SUCCESS;
smc_call(&regs);
return regs.regs[0];
}

View File

@ -0,0 +1,49 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#include <common.h>
#include <dm.h>
#include <malloc.h>
#include <errno.h>
#include <asm/io.h>
#include <linux/compiler.h>
#include <asm/arch/soc.h>
#include <asm/arch/board.h>
#include <dm/util.h>
int read_platform(void)
{
int plat = PLATFORM_HW;
const char *model = fdt_get_board_model();
if (model && !strncmp(model, "ASIM-", 5))
plat = PLATFORM_ASIM;
if (model && !strncmp(model, "EMUL-", 5))
plat = PLATFORM_EMULATOR;
return plat;
}
static inline u64 read_midr(void)
{
u64 result;
asm ("mrs %[rd],MIDR_EL1" : [rd] "=r" (result));
return result;
}
u8 read_partnum(void)
{
return ((read_midr() >> 4) & 0xFF);
}
const char *read_board_name(void)
{
return fdt_get_board_model();
}

View File

@ -42,51 +42,4 @@ int dram_init_banksize(void)
return 0;
}
#if CONFIG_IS_ENABLED(OF_BOARD_SETUP) && CONFIG_IS_ENABLED(PCI)
int ft_board_setup(void *blob, struct bd_info *bd)
{
struct udevice *dev;
struct uclass *uc;
fdt_addr_t regs_addr;
int i, off, ret;
ret = uclass_get(UCLASS_PCI, &uc);
if (ret)
return ret;
uclass_foreach_dev(dev, uc) {
struct pci_controller hose = { 0 };
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
if (hose.region_count == MAX_PCI_REGIONS) {
printf("maximum number of regions parsed, aborting\n");
break;
}
if (bd->bi_dram[i].size) {
pci_set_region(&hose.regions[hose.region_count++],
bd->bi_dram[i].start,
bd->bi_dram[i].start,
bd->bi_dram[i].size,
PCI_REGION_MEM |
PCI_REGION_PREFETCH |
PCI_REGION_SYS_MEMORY);
}
}
regs_addr = devfdt_get_addr_index(dev, 0);
off = fdt_node_offset_by_compat_reg(blob,
"renesas,pcie-rcar-gen3", regs_addr);
if (off < 0) {
printf("Failed to find PCIe node@%llx\n", regs_addr);
return off;
}
fdt_pci_dma_ranges(blob, off, &hose);
}
return 0;
}
#endif
#endif

View File

@ -0,0 +1,105 @@
CONFIG_ARM=y
# CONFIG_ARM64_SUPPORT_AARCH32 is not set
CONFIG_ARCH_OCTEONTX2=y
CONFIG_SYS_TEXT_BASE=0x04000000
CONFIG_SYS_MALLOC_F_LEN=0x4000
CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SIZE=0x8000
CONFIG_ENV_OFFSET=0xF00000
CONFIG_ENV_SECT_SIZE=0x10000
CONFIG_TARGET_OCTEONTX2_95XX=y
CONFIG_DM_GPIO=y
CONFIG_DEBUG_UART_BASE=0x87e028000000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_OF_BOARD_SETUP=y
CONFIG_BOOTDELAY=5
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyAMA0,115200n8 earlycon=pl011,0x87e028000000 maxcpus=6 rootwait rw root=/dev/mmcblk0p2 coherent_pool=16M"
CONFIG_VERSION_VARIABLE=y
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="Marvell> "
# CONFIG_CMD_BOOTEFI_HELLO_COMPILE is not set
CONFIG_CMD_MD5SUM=y
CONFIG_MD5SUM_VERIFY=y
CONFIG_CMD_MX_CYCLIC=y
CONFIG_CMD_MEMTEST=y
CONFIG_SYS_MEMTEST_START=0x04000000
CONFIG_SYS_MEMTEST_END=0x040f0000
CONFIG_CMD_SHA1SUM=y
CONFIG_SHA1SUM_VERIFY=y
CONFIG_CMD_DM=y
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_BKOPS_ENABLE=y
CONFIG_CMD_PART=y
CONFIG_CMD_PCI=y
CONFIG_CMD_SF_TEST=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_TFTPPUT=y
CONFIG_CMD_TFTPSRV=y
CONFIG_CMD_RARP=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_CMD_CDP=y
CONFIG_CMD_SNTP=y
CONFIG_CMD_DNS=y
CONFIG_CMD_LINK_LOCAL=y
CONFIG_CMD_PXE=y
CONFIG_CMD_TIME=y
CONFIG_CMD_EXT2=y
CONFIG_CMD_EXT4=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_EFI_PARTITION=y
CONFIG_PARTITION_TYPE_GUID=y
CONFIG_OF_BOARD=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_USE_ENV_SPI_BUS=y
CONFIG_ENV_SPI_BUS=0
CONFIG_USE_ENV_SPI_CS=y
CONFIG_ENV_SPI_CS=0
CONFIG_USE_ENV_SPI_MAX_HZ=y
CONFIG_ENV_SPI_MAX_HZ=125000000
CONFIG_USE_ENV_SPI_MODE=y
CONFIG_ENV_SPI_MODE=0x0
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_DM_I2C=y
CONFIG_MISC=y
CONFIG_DM_MMC=y
CONFIG_MMC_HS400_SUPPORT=y
CONFIG_MMC_OCTEONTX=y
CONFIG_MTD=y
CONFIG_DM_SPI_FLASH=y
CONFIG_SF_DEFAULT_MODE=0x0
CONFIG_SF_DEFAULT_SPEED=125000000
CONFIG_SPI_FLASH_SFDP_SUPPORT=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_SPANSION=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_DM_ETH=y
CONFIG_PCI=y
CONFIG_DM_PCI=y
CONFIG_DM_PCI_COMPAT=y
CONFIG_PCI_REGION_MULTI_ENTRY=y
CONFIG_PCI_SRIOV=y
CONFIG_PCI_ARID=y
CONFIG_PCI_OCTEONTX=y
CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
CONFIG_DM_RTC=y
CONFIG_DM_SERIAL=y
CONFIG_DEBUG_UART_SKIP_INIT=y
CONFIG_PL01X_SERIAL=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_WDT=y
CONFIG_ERRNO_STR=y

View File

@ -0,0 +1,131 @@
CONFIG_ARM=y
# CONFIG_ARM64_SUPPORT_AARCH32 is not set
CONFIG_ARCH_OCTEONTX2=y
CONFIG_SYS_TEXT_BASE=0x04000000
CONFIG_SYS_MALLOC_F_LEN=0x4000
CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SIZE=0x8000
CONFIG_ENV_OFFSET=0xF00000
CONFIG_ENV_SECT_SIZE=0x10000
CONFIG_TARGET_OCTEONTX2_96XX=y
CONFIG_DM_GPIO=y
CONFIG_DEBUG_UART_BASE=0x87e028000000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
CONFIG_AHCI=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_OF_BOARD_SETUP=y
CONFIG_BOOTDELAY=5
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyAMA0,115200n8 earlycon=pl011,0x87e028000000 maxcpus=24 rootwait rw root=/dev/mmcblk0p2 coherent_pool=16M"
CONFIG_VERSION_VARIABLE=y
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="Marvell> "
# CONFIG_CMD_BOOTEFI_HELLO_COMPILE is not set
CONFIG_CMD_MD5SUM=y
CONFIG_MD5SUM_VERIFY=y
CONFIG_CMD_MX_CYCLIC=y
CONFIG_CMD_MEMTEST=y
CONFIG_CMD_SHA1SUM=y
CONFIG_SHA1SUM_VERIFY=y
CONFIG_CMD_DM=y
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_BKOPS_ENABLE=y
CONFIG_CMD_PART=y
CONFIG_CMD_PCI=y
CONFIG_CMD_SF_TEST=y
CONFIG_CMD_USB=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_TFTPPUT=y
CONFIG_CMD_TFTPSRV=y
CONFIG_CMD_RARP=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_CMD_CDP=y
CONFIG_CMD_SNTP=y
CONFIG_CMD_DNS=y
CONFIG_CMD_LINK_LOCAL=y
CONFIG_CMD_PXE=y
CONFIG_CMD_TIME=y
CONFIG_CMD_EXT2=y
CONFIG_CMD_EXT4=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_EFI_PARTITION=y
CONFIG_PARTITION_TYPE_GUID=y
CONFIG_OF_BOARD=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_USE_ENV_SPI_BUS=y
CONFIG_ENV_SPI_BUS=0
CONFIG_USE_ENV_SPI_CS=y
CONFIG_ENV_SPI_CS=0
CONFIG_USE_ENV_SPI_MAX_HZ=y
CONFIG_ENV_SPI_MAX_HZ=125000000
CONFIG_USE_ENV_SPI_MODE=y
CONFIG_ENV_SPI_MODE=0x0
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SCSI_AHCI=y
CONFIG_AHCI_PCI=y
CONFIG_DM_I2C=y
CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
CONFIG_I2C_MUX=y
CONFIG_I2C_MUX_PCA954x=y
CONFIG_MISC=y
CONFIG_DM_MMC=y
CONFIG_MMC_HS400_SUPPORT=y
CONFIG_MMC_OCTEONTX=y
CONFIG_MTD=y
CONFIG_DM_SPI_FLASH=y
CONFIG_SF_DEFAULT_MODE=0x0
CONFIG_SF_DEFAULT_SPEED=125000000
CONFIG_SPI_FLASH_SFDP_SUPPORT=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_SPANSION=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_PHYLIB=y
CONFIG_PHY_MARVELL=y
CONFIG_PHY_VITESSE=y
CONFIG_DM_ETH=y
CONFIG_E1000=y
CONFIG_E1000_SPI=y
CONFIG_CMD_E1000=y
CONFIG_NVME=y
CONFIG_PCI=y
CONFIG_DM_PCI=y
CONFIG_DM_PCI_COMPAT=y
CONFIG_PCI_REGION_MULTI_ENTRY=y
CONFIG_PCI_SRIOV=y
CONFIG_PCI_ARID=y
CONFIG_PCI_OCTEONTX=y
CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
CONFIG_DM_RTC=y
CONFIG_SCSI=y
CONFIG_DM_SCSI=y
CONFIG_DM_SERIAL=y
CONFIG_DEBUG_UART_SKIP_INIT=y
CONFIG_PL01X_SERIAL=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_OCTEON_SPI=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_PCI=y
CONFIG_USB_STORAGE=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y
CONFIG_USB_ETHER_ASIX88179=y
CONFIG_USB_ETHER_RTL8152=y
CONFIG_WDT=y
CONFIG_ERRNO_STR=y

View File

@ -0,0 +1,131 @@
CONFIG_ARM=y
# CONFIG_ARM64_SUPPORT_AARCH32 is not set
CONFIG_ARCH_OCTEONTX=y
CONFIG_SYS_TEXT_BASE=0x2800000
CONFIG_SYS_MALLOC_F_LEN=0x4000
CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SIZE=0x8000
CONFIG_ENV_OFFSET=0xF00000
CONFIG_ENV_SECT_SIZE=0x10000
CONFIG_TARGET_OCTEONTX_81XX=y
CONFIG_DM_GPIO=y
CONFIG_DEBUG_UART_BASE=0x87e028000000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
CONFIG_AHCI=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_OF_BOARD_SETUP=y
CONFIG_BOOTDELAY=5
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyAMA0,115200n8 earlycon=pl011,0x87e028000000 maxcpus=4 rootwait rw root=/dev/sda2 coherent_pool=16M"
CONFIG_VERSION_VARIABLE=y
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="Marvell> "
# CONFIG_CMD_BOOTEFI_HELLO_COMPILE is not set
CONFIG_CMD_MD5SUM=y
CONFIG_MD5SUM_VERIFY=y
CONFIG_CMD_MX_CYCLIC=y
CONFIG_CMD_MEMTEST=y
CONFIG_SYS_MEMTEST_START=0x2800000
CONFIG_SYS_MEMTEST_END=0x28f0000
CONFIG_CMD_SHA1SUM=y
CONFIG_SHA1SUM_VERIFY=y
CONFIG_CMD_DM=y
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_BKOPS_ENABLE=y
CONFIG_CMD_PART=y
CONFIG_CMD_PCI=y
CONFIG_CMD_SF_TEST=y
CONFIG_CMD_USB=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_TFTPPUT=y
CONFIG_CMD_TFTPSRV=y
CONFIG_CMD_RARP=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_CMD_CDP=y
CONFIG_CMD_SNTP=y
CONFIG_CMD_DNS=y
CONFIG_CMD_LINK_LOCAL=y
CONFIG_CMD_PXE=y
CONFIG_CMD_TIME=y
CONFIG_CMD_EXT2=y
CONFIG_CMD_EXT4=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_EFI_PARTITION=y
CONFIG_PARTITION_TYPE_GUID=y
CONFIG_OF_BOARD=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_USE_ENV_SPI_BUS=y
CONFIG_ENV_SPI_BUS=0
CONFIG_USE_ENV_SPI_CS=y
CONFIG_ENV_SPI_CS=0
CONFIG_USE_ENV_SPI_MAX_HZ=y
CONFIG_ENV_SPI_MAX_HZ=16000000
CONFIG_USE_ENV_SPI_MODE=y
CONFIG_ENV_SPI_MODE=0x0
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SCSI_AHCI=y
CONFIG_AHCI_PCI=y
CONFIG_DM_I2C=y
CONFIG_MISC=y
CONFIG_DM_MMC=y
CONFIG_MMC_OCTEONTX=y
CONFIG_MTD=y
CONFIG_DM_SPI_FLASH=y
CONFIG_SF_DEFAULT_MODE=0x0
CONFIG_SF_DEFAULT_SPEED=16000000
CONFIG_SPI_FLASH_SFDP_SUPPORT=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_SPANSION=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_PHYLIB=y
CONFIG_PHY_AQUANTIA=y
CONFIG_PHY_BROADCOM=y
CONFIG_PHY_MARVELL=y
CONFIG_PHY_MICREL=y
CONFIG_PHY_REALTEK=y
CONFIG_PHY_VITESSE=y
CONFIG_DM_ETH=y
CONFIG_E1000=y
CONFIG_E1000_SPI=y
CONFIG_CMD_E1000=y
CONFIG_NVME=y
CONFIG_PCI=y
CONFIG_DM_PCI=y
CONFIG_DM_PCI_COMPAT=y
CONFIG_PCI_REGION_MULTI_ENTRY=y
CONFIG_PCI_SRIOV=y
CONFIG_PCI_ARID=y
CONFIG_PCI_OCTEONTX=y
CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
CONFIG_DM_RTC=y
CONFIG_SCSI=y
CONFIG_DM_SCSI=y
CONFIG_DM_SERIAL=y
CONFIG_DEBUG_UART_SKIP_INIT=y
CONFIG_PL01X_SERIAL=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_PCI=y
CONFIG_USB_STORAGE=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y
CONFIG_USB_ETHER_ASIX88179=y
CONFIG_USB_ETHER_RTL8152=y
CONFIG_WDT=y
CONFIG_ERRNO_STR=y

View File

@ -0,0 +1,128 @@
CONFIG_ARM=y
# CONFIG_ARM64_SUPPORT_AARCH32 is not set
CONFIG_ARCH_OCTEONTX=y
CONFIG_SYS_TEXT_BASE=0x2800000
CONFIG_SYS_MALLOC_F_LEN=0x4000
CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SIZE=0x8000
CONFIG_ENV_OFFSET=0xF00000
CONFIG_ENV_SECT_SIZE=0x10000
CONFIG_TARGET_OCTEONTX_83XX=y
CONFIG_DM_GPIO=y
CONFIG_DEBUG_UART_BASE=0x87e028000000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
CONFIG_AHCI=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_OF_BOARD_SETUP=y
CONFIG_BOOTDELAY=5
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyAMA0,115200n8 earlycon=pl011,0x87e028000000 maxcpus=24 rootwait rw root=/dev/sda2 coherent_pool=16M"
CONFIG_VERSION_VARIABLE=y
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="Marvell> "
# CONFIG_CMD_BOOTEFI_HELLO_COMPILE is not set
CONFIG_CMD_MD5SUM=y
CONFIG_MD5SUM_VERIFY=y
CONFIG_CMD_MX_CYCLIC=y
CONFIG_CMD_MEMTEST=y
CONFIG_CMD_SHA1SUM=y
CONFIG_SHA1SUM_VERIFY=y
CONFIG_CMD_DM=y
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_BKOPS_ENABLE=y
CONFIG_CMD_PART=y
CONFIG_CMD_PCI=y
CONFIG_CMD_SF_TEST=y
CONFIG_CMD_USB=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_TFTPPUT=y
CONFIG_CMD_TFTPSRV=y
CONFIG_CMD_RARP=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_CMD_CDP=y
CONFIG_CMD_SNTP=y
CONFIG_CMD_DNS=y
CONFIG_CMD_LINK_LOCAL=y
CONFIG_CMD_PXE=y
CONFIG_CMD_EXT2=y
CONFIG_CMD_EXT4=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_EFI_PARTITION=y
CONFIG_PARTITION_TYPE_GUID=y
CONFIG_OF_BOARD=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_USE_ENV_SPI_BUS=y
CONFIG_ENV_SPI_BUS=0
CONFIG_USE_ENV_SPI_CS=y
CONFIG_ENV_SPI_CS=0
CONFIG_USE_ENV_SPI_MAX_HZ=y
CONFIG_ENV_SPI_MAX_HZ=16000000
CONFIG_USE_ENV_SPI_MODE=y
CONFIG_ENV_SPI_MODE=0x0
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SCSI_AHCI=y
CONFIG_AHCI_PCI=y
CONFIG_DM_I2C=y
CONFIG_MISC=y
CONFIG_DM_MMC=y
CONFIG_MMC_OCTEONTX=y
CONFIG_MTD=y
CONFIG_DM_SPI_FLASH=y
CONFIG_SF_DEFAULT_MODE=0x0
CONFIG_SF_DEFAULT_SPEED=16000000
CONFIG_SPI_FLASH_SFDP_SUPPORT=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_SPANSION=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_PHYLIB=y
CONFIG_PHY_AQUANTIA=y
CONFIG_PHY_BROADCOM=y
CONFIG_PHY_MARVELL=y
CONFIG_PHY_MICREL=y
CONFIG_PHY_REALTEK=y
CONFIG_PHY_VITESSE=y
CONFIG_DM_ETH=y
CONFIG_E1000=y
CONFIG_E1000_SPI=y
CONFIG_CMD_E1000=y
CONFIG_NVME=y
CONFIG_PCI=y
CONFIG_DM_PCI=y
CONFIG_DM_PCI_COMPAT=y
CONFIG_PCI_REGION_MULTI_ENTRY=y
CONFIG_PCI_SRIOV=y
CONFIG_PCI_ARID=y
CONFIG_PCI_OCTEONTX=y
CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
CONFIG_DM_RTC=y
CONFIG_SCSI=y
CONFIG_DM_SCSI=y
CONFIG_DM_SERIAL=y
CONFIG_DEBUG_UART_SKIP_INIT=y
CONFIG_PL01X_SERIAL=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_PCI=y
CONFIG_USB_STORAGE=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y
CONFIG_USB_ETHER_ASIX88179=y
CONFIG_USB_ETHER_RTL8152=y
CONFIG_WDT=y
CONFIG_ERRNO_STR=y

View File

@ -1,5 +1,6 @@
CONFIG_X86=y
CONFIG_SYS_TEXT_BASE=0xFFF00000
CONFIG_SYS_MALLOC_F_LEN=0x1000
CONFIG_NR_DRAM_BANKS=8
CONFIG_ENV_SIZE=0x40000
CONFIG_MAX_CPUS=2

View File

@ -181,6 +181,7 @@ CONFIG_NVME=y
CONFIG_PCI=y
CONFIG_DM_PCI=y
CONFIG_DM_PCI_COMPAT=y
CONFIG_PCI_REGION_MULTI_ENTRY=y
CONFIG_PCI_SANDBOX=y
CONFIG_PHY=y
CONFIG_PHY_SANDBOX=y

View File

@ -136,6 +136,7 @@ CONFIG_NVME=y
CONFIG_PCI=y
CONFIG_DM_PCI=y
CONFIG_DM_PCI_COMPAT=y
CONFIG_PCI_REGION_MULTI_ENTRY=y
CONFIG_PCI_SANDBOX=y
CONFIG_PHY=y
CONFIG_PHY_SANDBOX=y

View File

@ -1198,10 +1198,25 @@ int ahci_probe_scsi(struct udevice *ahci_dev, ulong base)
int ahci_probe_scsi_pci(struct udevice *ahci_dev)
{
ulong base;
u16 vendor, device;
base = (ulong)dm_pci_map_bar(ahci_dev, PCI_BASE_ADDRESS_5,
PCI_REGION_MEM);
/*
* Note:
* Right now, we have only one quirk here, which is not enough to
* introduce a new Kconfig option to select this. Once we have more
* quirks in this AHCI code, we should add a Kconfig option for
* this though.
*/
dm_pci_read_config16(ahci_dev, PCI_VENDOR_ID, &vendor);
dm_pci_read_config16(ahci_dev, PCI_DEVICE_ID, &device);
if (vendor == PCI_VENDOR_ID_CAVIUM &&
device == PCI_DEVICE_ID_CAVIUM_SATA)
base = (uintptr_t)dm_pci_map_bar(ahci_dev, PCI_BASE_ADDRESS_0,
PCI_REGION_MEM);
return ahci_probe_scsi(ahci_dev, base);
}
#endif

View File

@ -10,6 +10,7 @@
#include <mapmem.h>
#include <asm/types.h>
#include <asm/io.h>
#include <linux/ioport.h>
int dev_read_u32(const struct udevice *dev, const char *propname, u32 *outp)
{
@ -359,3 +360,19 @@ int dev_get_child_count(const struct udevice *dev)
{
return ofnode_get_child_count(dev_ofnode(dev));
}
int dev_read_pci_bus_range(const struct udevice *dev,
struct resource *res)
{
const u32 *values;
int len;
values = dev_read_prop(dev, "bus-range", &len);
if (!values || len < sizeof(*values) * 2)
return -EINVAL;
res->start = *values++;
res->end = *values;
return 0;
}

View File

@ -305,6 +305,15 @@ config MMC_PCI
This selects PCI-based MMC controllers.
If you have an MMC controller on a PCI bus, say Y here.
config MMC_OCTEONTX
bool "Marvell OcteonTX Multimedia Card Interface support"
depends on (ARCH_OCTEONTX || ARCH_OCTEONTX2)
depends on DM_MMC
help
This selects the OcteonTX Multimedia card Interface.
If you have an OcteonTX/TX2 board with a Multimedia Card slot,
say Y here.
If unsure, say N.
config PXA_MMC_GENERIC

View File

@ -36,6 +36,7 @@ obj-$(CONFIG_MVEBU_MMC) += mvebu_mmc.o
obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o
obj-$(CONFIG_MMC_MXC) += mxcmmc.o
obj-$(CONFIG_MMC_MXS) += mxsmmc.o
obj-$(CONFIG_MMC_OCTEONTX) += octeontx_hsmmc.o
obj-$(CONFIG_MMC_PCI) += pci_mmc.o
obj-$(CONFIG_PXA_MMC_GENERIC) += pxa_mmc_gen.o
obj-$(CONFIG_$(SPL_TPL_)SUPPORT_EMMC_RPMB) += rpmb.o

3897
drivers/mmc/octeontx_hsmmc.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,207 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2019 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#ifndef __OCTEONTX_HSMMC_H__
#define __OCTEONTX_HSMMC_H__
#include <asm/gpio.h>
/** Name of our driver */
#define OCTEONTX_MMC_DRIVER_NAME "octeontx-hsmmc"
/** Maximum supported MMC slots */
#define OCTEONTX_MAX_MMC_SLOT 3
#define POWER_ON_TIME 40 /** See SD 4.1 spec figure 6-5 */
/**
* Timeout used when waiting for commands to complete. We need to keep this
* above the hardware watchdog timeout which is usually limited to 1000ms
*/
#define WATCHDOG_COUNT (1100) /* in msecs */
/**
* Long timeout for commands which might take a while to complete.
*/
#define MMC_TIMEOUT_LONG 1000
/**
* Short timeout used for most commands in msecs
*/
#define MMC_TIMEOUT_SHORT 20
#define NSEC_PER_SEC 1000000000L
#define MAX_NO_OF_TAPS 64
#define EXT_CSD_POWER_CLASS 187 /* R/W */
/* default HS400 tuning block number */
#define DEFAULT_HS400_TUNING_BLOCK 1
struct octeontx_mmc_host;
/** MMC/SD slot data structure */
struct octeontx_mmc_slot {
struct mmc mmc;
struct mmc_config cfg;
struct octeontx_mmc_host *host;
struct udevice *dev;
void *base_addr; /** Same as host base_addr */
u64 clock;
int bus_id; /** slot number */
uint bus_width;
uint max_width;
int hs200_tap_adj;
int hs400_tap_adj;
int hs400_tuning_block;
struct gpio_desc cd_gpio;
struct gpio_desc wp_gpio;
struct gpio_desc power_gpio;
enum bus_mode mode;
union mio_emm_switch cached_switch;
union mio_emm_switch want_switch;
union mio_emm_rca cached_rca;
union mio_emm_timing taps; /* otx2: MIO_EMM_TIMING */
union mio_emm_timing hs200_taps;
union mio_emm_timing hs400_taps;
/* These are used to see if our tuning is still valid or not */
enum bus_mode last_mode;
u32 last_clock;
u32 block_len;
u32 block_count;
int cmd_clk_skew;
int dat_clk_skew;
uint cmd_cnt; /* otx: sample cmd in delay */
uint dat_cnt; /* otx: sample data in delay */
uint drive; /* Current drive */
uint slew; /* clock skew */
uint cmd_out_hs200_delay;
uint data_out_hs200_delay;
uint cmd_out_hs400_delay;
uint data_out_hs400_delay;
uint clk_period;
bool valid:1;
bool is_acmd:1;
bool tuned:1;
bool hs200_tuned:1;
bool hs400_tuned:1;
bool is_1_8v:1;
bool is_3_3v:1;
bool is_ddr:1;
bool is_asim:1;
bool is_emul:1;
bool cd_inverted:1;
bool wp_inverted:1;
bool disable_ddr:1;
bool non_removable:1;
};
struct octeontx_mmc_cr_mods {
u8 ctype_xor;
u8 rtype_xor;
};
struct octeontx_mmc_cr {
u8 c;
u8 r;
};
struct octeontx_sd_mods {
struct octeontx_mmc_cr mmc;
struct octeontx_mmc_cr sd;
struct octeontx_mmc_cr sdacmd;
};
/** Host controller data structure */
struct octeontx_mmc_host {
struct udevice *dev;
void *base_addr;
struct octeontx_mmc_slot slots[OCTEONTX_MAX_MMC_SLOT + 1];
pci_dev_t pdev;
u64 sys_freq;
union mio_emm_cfg emm_cfg;
u64 timing_taps;
struct mmc *last_mmc; /** Last mmc used */
ofnode node;
int cur_slotid;
int last_slotid;
int max_width;
uint per_tap_delay;
uint num_slots;
uint dma_wait_delay; /* Delay before polling DMA in usecs */
bool initialized:1;
bool timing_calibrated:1;
bool is_asim:1;
bool is_emul:1;
bool calibrate_glitch:1;
bool cond_clock_glitch:1;
bool tap_requires_noclk:1;
bool hs400_skew_needed:1;
};
/*
* NOTE: This was copied from the Linux kernel.
*
* MMC status in R1, for native mode (SPI bits are different)
* Type
* e:error bit
* s:status bit
* r:detected and set for the actual command response
* x:detected and set during command execution. the host must poll
* the card by sending status command in order to read these bits.
* Clear condition
* a:according to the card state
* b:always related to the previous command. Reception of
* a valid command will clear it (with a delay of one command)
* c:clear by read
*/
#define R1_OUT_OF_RANGE BIT(31) /* er, c */
#define R1_ADDRESS_ERROR BIT(30) /* erx, c */
#define R1_BLOCK_LEN_ERROR BIT(29) /* er, c */
#define R1_ERASE_SEQ_ERROR BIT(28) /* er, c */
#define R1_ERASE_PARAM BIT(27) /* ex, c */
#define R1_WP_VIOLATION BIT(26) /* erx, c */
#define R1_CARD_IS_LOCKED BIT(25) /* sx, a */
#define R1_LOCK_UNLOCK_FAILED BIT(24) /* erx, c */
#define R1_COM_CRC_ERROR BIT(23) /* er, b */
/*#define R1_ILLEGAL_COMMAND BIT(22)*/ /* er, b */
#define R1_CARD_ECC_FAILED BIT(21) /* ex, c */
#define R1_CC_ERROR BIT(20) /* erx, c */
#define R1_ERROR BIT(19) /* erx, c */
#define R1_UNDERRUN BIT(18) /* ex, c */
#define R1_OVERRUN BIT(17) /* ex, c */
#define R1_CID_CSD_OVERWRITE BIT(16) /* erx, c, CID/CSD overwrite */
#define R1_WP_ERASE_SKIP BIT(15) /* sx, c */
#define R1_CARD_ECC_DISABLED BIT(14) /* sx, a */
#define R1_ERASE_RESET BIT(13) /* sr, c */
#define R1_STATUS(x) ((x) & 0xFFFFE000)
#define R1_CURRENT_STATE(x) (((x) & 0x00001E00) >> 9) /* sx, b (4 bits) */
#define R1_READY_FOR_DATA BIT(8) /* sx, a */
#define R1_SWITCH_ERROR BIT(7) /* sx, c */
#define R1_BLOCK_READ_MASK R1_OUT_OF_RANGE | \
R1_ADDRESS_ERROR | \
R1_BLOCK_LEN_ERROR | \
R1_CARD_IS_LOCKED | \
R1_COM_CRC_ERROR | \
R1_ILLEGAL_COMMAND | \
R1_CARD_ECC_FAILED | \
R1_CC_ERROR | \
R1_ERROR
#define R1_BLOCK_WRITE_MASK R1_OUT_OF_RANGE | \
R1_ADDRESS_ERROR | \
R1_BLOCK_LEN_ERROR | \
R1_WP_VIOLATION | \
R1_CARD_IS_LOCKED | \
R1_COM_CRC_ERROR | \
R1_ILLEGAL_COMMAND | \
R1_CARD_ECC_FAILED | \
R1_CC_ERROR | \
R1_ERROR | \
R1_UNDERRUN | \
R1_OVERRUN
#endif /* __OCTEONTX_HSMMC_H__ */

View File

@ -43,6 +43,35 @@ config PCI_PNP
help
Enable PCI memory and I/O space resource allocation and assignment.
config PCI_REGION_MULTI_ENTRY
bool "Enable Multiple entries of region type MEMORY in ranges for PCI"
depends on PCI || DM_PCI
default n
help
Enable PCI memory regions to be of multiple entry. Multiple entry
here refers to allow more than one count of address ranges for MEMORY
region type. This helps to add support for SoC's like OcteonTX/TX2
where every peripheral is on the PCI bus.
config PCI_SRIOV
bool "Enable Single Root I/O Virtualization support for PCI"
depends on PCI || DM_PCI
default n
help
Say Y here if you want to enable PCI Single Root I/O Virtualization
capability support. This helps to enumerate Virtual Function devices
if available on a PCI Physical Function device and probe for
applicable drivers.
config PCI_ARID
bool "Enable Alternate Routing-ID support for PCI"
depends on PCI || DM_PCI
default n
help
Say Y here if you want to enable Alternate Routing-ID capability
support on PCI devices. This helps to skip some devices in BDF
scan that are not present.
config PCIE_ECAM_GENERIC
bool "Generic ECAM-based PCI host controller support"
default n
@ -120,6 +149,14 @@ config PCI_TEGRA
with a total of 5 lanes. Some boards require this for Ethernet
support to work (e.g. beaver, jetson-tk1).
config PCI_OCTEONTX
bool "OcteonTX PCI support"
depends on (ARCH_OCTEONTX || ARCH_OCTEONTX2)
help
Enable support for the OcteonTX/TX2 SoC family ECAM/PEM controllers.
These controllers provide PCI configuration access to all on-board
peripherals so it should only be disabled for testing purposes
config PCI_XILINX
bool "Xilinx AXI Bridge for PCI Express"
depends on DM_PCI

View File

@ -49,3 +49,4 @@ obj-$(CONFIG_PCI_KEYSTONE) += pcie_dw_ti.o
obj-$(CONFIG_PCIE_MEDIATEK) += pcie_mediatek.o
obj-$(CONFIG_PCIE_ROCKCHIP) += pcie_rockchip.o
obj-$(CONFIG_PCI_BRCMSTB) += pcie_brcmstb.o
obj-$(CONFIG_PCI_OCTEONTX) += pci_octeontx.o

View File

@ -539,7 +539,8 @@ int pci_auto_config_devices(struct udevice *bus)
int ret;
debug("%s: device %s\n", __func__, dev->name);
if (dev_read_bool(dev, "pci,no-autoconfig"))
if (dev_of_valid(dev) &&
dev_read_bool(dev, "pci,no-autoconfig"))
continue;
ret = dm_pciauto_config_device(dev);
if (ret < 0)
@ -620,10 +621,19 @@ int dm_pci_hose_probe_bus(struct udevice *bus)
{
int sub_bus;
int ret;
int ea_pos;
u8 reg;
debug("%s\n", __func__);
sub_bus = pci_get_bus_max() + 1;
ea_pos = dm_pci_find_capability(bus, PCI_CAP_ID_EA);
if (ea_pos) {
dm_pci_read_config8(bus, ea_pos + sizeof(u32) + sizeof(u8),
&reg);
sub_bus = reg;
} else {
sub_bus = pci_get_bus_max() + 1;
}
debug("%s: bus = %d/%s\n", __func__, sub_bus, bus->name);
dm_pciauto_prescan_setup_bridge(bus, sub_bus);
@ -633,12 +643,15 @@ int dm_pci_hose_probe_bus(struct udevice *bus)
ret);
return ret;
}
if (sub_bus != bus->seq) {
printf("%s: Internal error, bus '%s' got seq %d, expected %d\n",
__func__, bus->name, bus->seq, sub_bus);
return -EPIPE;
if (!ea_pos) {
if (sub_bus != bus->seq) {
debug("%s: Internal error, bus '%s' got seq %d, expected %d\n",
__func__, bus->name, bus->seq, sub_bus);
return -EPIPE;
}
sub_bus = pci_get_bus_max();
}
sub_bus = pci_get_bus_max();
dm_pciauto_postscan_setup_bridge(bus, sub_bus);
return sub_bus;
@ -696,7 +709,8 @@ static int pci_find_and_bind_driver(struct udevice *parent,
find_id->vendor, find_id->device);
/* Determine optional OF node */
pci_dev_find_ofnode(parent, bdf, &node);
if (ofnode_valid(dev_ofnode(parent)))
pci_dev_find_ofnode(parent, bdf, &node);
if (ofnode_valid(node) && !ofnode_is_available(node)) {
debug("%s: Ignoring disabled device\n", __func__);
@ -785,6 +799,7 @@ int pci_bind_bus_devices(struct udevice *bus)
ulong header_type;
pci_dev_t bdf, end;
bool found_multi;
int ari_off;
int ret;
found_multi = false;
@ -858,6 +873,31 @@ int pci_bind_bus_devices(struct udevice *bus)
pplat->vendor = vendor;
pplat->device = device;
pplat->class = class;
if (IS_ENABLED(CONFIG_PCI_ARID)) {
ari_off = dm_pci_find_ext_capability(dev,
PCI_EXT_CAP_ID_ARI);
if (ari_off) {
u16 ari_cap;
/*
* Read Next Function number in ARI Cap
* Register
*/
dm_pci_read_config16(dev, ari_off + 4,
&ari_cap);
/*
* Update next scan on this function number,
* subtract 1 in BDF to satisfy loop increment.
*/
if (ari_cap & 0xff00) {
bdf = PCI_BDF(PCI_BUS(bdf),
PCI_DEV(ari_cap),
PCI_FUNC(ari_cap));
bdf = bdf - 0x100;
}
}
}
}
return 0;
@ -871,8 +911,10 @@ static void decode_regions(struct pci_controller *hose, ofnode parent_node,
ofnode node)
{
int pci_addr_cells, addr_cells, size_cells;
struct bd_info *bd = gd->bd;
int cells_per_record;
const u32 *prop;
int max_regions;
int len;
int i;
@ -892,7 +934,13 @@ static void decode_regions(struct pci_controller *hose, ofnode parent_node,
hose->region_count = 0;
debug("%s: len=%d, cells_per_record=%d\n", __func__, len,
cells_per_record);
for (i = 0; i < MAX_PCI_REGIONS; i++, len -= cells_per_record) {
/* Dynamically allocate the regions array */
max_regions = len / cells_per_record + CONFIG_NR_DRAM_BANKS;
hose->regions = (struct pci_region *)
calloc(1, max_regions * sizeof(struct pci_region));
for (i = 0; i < max_regions; i++, len -= cells_per_record) {
u64 pci_addr, addr, size;
int space_code;
u32 flags;
@ -927,10 +975,13 @@ static void decode_regions(struct pci_controller *hose, ofnode parent_node,
}
pos = -1;
for (i = 0; i < hose->region_count; i++) {
if (hose->regions[i].flags == type)
pos = i;
if (!IS_ENABLED(CONFIG_PCI_REGION_MULTI_ENTRY)) {
for (i = 0; i < hose->region_count; i++) {
if (hose->regions[i].flags == type)
pos = i;
}
}
if (pos == -1)
pos = hose->region_count++;
debug(" - type=%d, pos=%d\n", type, pos);
@ -938,18 +989,10 @@ static void decode_regions(struct pci_controller *hose, ofnode parent_node,
}
/* Add a region for our local memory */
#ifdef CONFIG_NR_DRAM_BANKS
struct bd_info *bd = gd->bd;
if (!bd)
return;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) {
if (hose->region_count == MAX_PCI_REGIONS) {
pr_err("maximum number of regions parsed, aborting\n");
break;
}
if (bd->bi_dram[i].size) {
pci_set_region(hose->regions + hose->region_count++,
bd->bi_dram[i].start,
@ -958,19 +1001,6 @@ static void decode_regions(struct pci_controller *hose, ofnode parent_node,
PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
}
}
#else
phys_addr_t base = 0, size;
size = gd->ram_size;
#ifdef CONFIG_SYS_SDRAM_BASE
base = CONFIG_SYS_SDRAM_BASE;
#endif
if (gd->pci_ram_top && gd->pci_ram_top < base + size)
size = gd->pci_ram_top - base;
if (size)
pci_set_region(hose->regions + hose->region_count++, base,
base, size, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
#endif
return;
}
@ -996,8 +1026,11 @@ static int pci_uclass_pre_probe(struct udevice *bus)
hose->bus = bus;
hose->first_busno = bus->seq;
hose->last_busno = bus->seq;
hose->skip_auto_config_until_reloc =
dev_read_bool(bus, "u-boot,skip-auto-config-until-reloc");
if (dev_of_valid(bus)) {
hose->skip_auto_config_until_reloc =
dev_read_bool(bus,
"u-boot,skip-auto-config-until-reloc");
}
return 0;
}
@ -1406,14 +1439,55 @@ pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t phys_addr,
return bus_addr;
}
static phys_addr_t dm_pci_map_ea_virt(struct udevice *dev, int ea_off,
struct pci_child_platdata *pdata)
{
phys_addr_t addr = 0;
/*
* In the case of a Virtual Function device using BAR
* base and size, add offset for VFn BAR(1, 2, 3...n)
*/
if (pdata->is_virtfn) {
size_t sz;
u32 ea_entry;
/* MaxOffset, 1st DW */
dm_pci_read_config32(dev, ea_off + 8, &ea_entry);
sz = ea_entry & PCI_EA_FIELD_MASK;
/* Fill up lower 2 bits */
sz |= (~PCI_EA_FIELD_MASK);
if (ea_entry & PCI_EA_IS_64) {
/* MaxOffset 2nd DW */
dm_pci_read_config32(dev, ea_off + 16, &ea_entry);
sz |= ((u64)ea_entry) << 32;
}
addr = (pdata->virtid - 1) * (sz + 1);
}
return addr;
}
static void *dm_pci_map_ea_bar(struct udevice *dev, int bar, int flags,
int ea_off)
int ea_off, struct pci_child_platdata *pdata)
{
int ea_cnt, i, entry_size;
int bar_id = (bar - PCI_BASE_ADDRESS_0) >> 2;
u32 ea_entry;
phys_addr_t addr;
if (IS_ENABLED(CONFIG_PCI_SRIOV)) {
/*
* In the case of a Virtual Function device, device is
* Physical function, so pdata will point to required VF
* specific data.
*/
if (pdata->is_virtfn)
bar_id += PCI_EA_BEI_VF_BAR0;
}
/* EA capability structure header */
dm_pci_read_config32(dev, ea_off, &ea_entry);
ea_cnt = (ea_entry >> 16) & PCI_EA_NUM_ENT_MASK;
@ -1436,8 +1510,11 @@ static void *dm_pci_map_ea_bar(struct udevice *dev, int bar, int flags,
addr |= ((u64)ea_entry) << 32;
}
if (IS_ENABLED(CONFIG_PCI_SRIOV))
addr += dm_pci_map_ea_virt(dev, ea_off, pdata);
/* size ignored for now */
return map_physmem(addr, flags, 0);
return map_physmem(addr, 0, flags);
}
return 0;
@ -1445,29 +1522,42 @@ static void *dm_pci_map_ea_bar(struct udevice *dev, int bar, int flags,
void *dm_pci_map_bar(struct udevice *dev, int bar, int flags)
{
struct pci_child_platdata *pdata = dev_get_parent_platdata(dev);
struct udevice *udev = dev;
pci_addr_t pci_bus_addr;
u32 bar_response;
int ea_off;
if (IS_ENABLED(CONFIG_PCI_SRIOV)) {
/*
* In case of Virtual Function devices, use PF udevice
* as EA capability is defined in Physical Function
*/
if (pdata->is_virtfn)
udev = pdata->pfdev;
}
/*
* if the function supports Enhanced Allocation use that instead of
* BARs
* Incase of virtual functions, pdata will help read VF BEI
* and EA entry size.
*/
ea_off = dm_pci_find_capability(dev, PCI_CAP_ID_EA);
ea_off = dm_pci_find_capability(udev, PCI_CAP_ID_EA);
if (ea_off)
return dm_pci_map_ea_bar(dev, bar, flags, ea_off);
return dm_pci_map_ea_bar(udev, bar, flags, ea_off, pdata);
/* read BAR address */
dm_pci_read_config32(dev, bar, &bar_response);
dm_pci_read_config32(udev, bar, &bar_response);
pci_bus_addr = (pci_addr_t)(bar_response & ~0xf);
/*
* Pass "0" as the length argument to pci_bus_to_virt. The arg
* isn't actualy used on any platform because u-boot assumes a static
* isn't actually used on any platform because U-Boot assumes a static
* linear mapping. In the future, this could read the BAR size
* and pass that as the size if needed.
*/
return dm_pci_bus_to_virt(dev, pci_bus_addr, flags, 0, MAP_NOCACHE);
return dm_pci_bus_to_virt(udev, pci_bus_addr, flags, 0, MAP_NOCACHE);
}
static int _dm_pci_find_next_capability(struct udevice *dev, u8 pos, int cap)
@ -1583,6 +1673,120 @@ int dm_pci_flr(struct udevice *dev)
return 0;
}
#if defined(CONFIG_PCI_SRIOV)
int pci_sriov_init(struct udevice *pdev, int vf_en)
{
u16 vendor, device;
struct udevice *bus;
struct udevice *dev;
pci_dev_t bdf;
u16 ctrl;
u16 num_vfs;
u16 total_vf;
u16 vf_offset;
u16 vf_stride;
int vf, ret;
int pos;
pos = dm_pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
if (!pos) {
debug("Error: SRIOV capability not found\n");
return -ENOENT;
}
dm_pci_read_config16(pdev, pos + PCI_SRIOV_CTRL, &ctrl);
dm_pci_read_config16(pdev, pos + PCI_SRIOV_TOTAL_VF, &total_vf);
if (vf_en > total_vf)
vf_en = total_vf;
dm_pci_write_config16(pdev, pos + PCI_SRIOV_NUM_VF, vf_en);
ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE;
dm_pci_write_config16(pdev, pos + PCI_SRIOV_CTRL, ctrl);
dm_pci_read_config16(pdev, pos + PCI_SRIOV_NUM_VF, &num_vfs);
if (num_vfs > vf_en)
num_vfs = vf_en;
dm_pci_read_config16(pdev, pos + PCI_SRIOV_VF_OFFSET, &vf_offset);
dm_pci_read_config16(pdev, pos + PCI_SRIOV_VF_STRIDE, &vf_stride);
dm_pci_read_config16(pdev, PCI_VENDOR_ID, &vendor);
dm_pci_read_config16(pdev, pos + PCI_SRIOV_VF_DID, &device);
bdf = dm_pci_get_bdf(pdev);
pci_get_bus(PCI_BUS(bdf), &bus);
if (!bus)
return -ENODEV;
bdf += PCI_BDF(0, 0, vf_offset);
for (vf = 0; vf < num_vfs; vf++) {
struct pci_child_platdata *pplat;
ulong class;
pci_bus_read_config(bus, bdf, PCI_CLASS_DEVICE,
&class, PCI_SIZE_16);
debug("%s: bus %d/%s: found VF %x:%x\n", __func__,
bus->seq, bus->name, PCI_DEV(bdf), PCI_FUNC(bdf));
/* Find this device in the device tree */
ret = pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), &dev);
if (ret == -ENODEV) {
struct pci_device_id find_id;
memset(&find_id, '\0', sizeof(find_id));
find_id.vendor = vendor;
find_id.device = device;
find_id.class = class;
ret = pci_find_and_bind_driver(bus, &find_id,
bdf, &dev);
if (ret)
return ret;
}
/* Update the platform data */
pplat = dev_get_parent_platdata(dev);
pplat->devfn = PCI_MASK_BUS(bdf);
pplat->vendor = vendor;
pplat->device = device;
pplat->class = class;
pplat->is_virtfn = true;
pplat->pfdev = pdev;
pplat->virtid = vf * vf_stride + vf_offset;
debug("%s: bus %d/%s: found VF %x:%x %x:%x class %lx id %x\n",
__func__, dev->seq, dev->name, PCI_DEV(bdf),
PCI_FUNC(bdf), vendor, device, class, pplat->virtid);
bdf += PCI_BDF(0, 0, vf_stride);
}
return 0;
}
int pci_sriov_get_totalvfs(struct udevice *pdev)
{
u16 total_vf;
int pos;
pos = dm_pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
if (!pos) {
debug("Error: SRIOV capability not found\n");
return -ENOENT;
}
dm_pci_read_config16(pdev, pos + PCI_SRIOV_TOTAL_VF, &total_vf);
return total_vf;
}
#endif /* SRIOV */
UCLASS_DRIVER(pci) = {
.id = UCLASS_PCI,
.name = "pci",

364
drivers/pci/pci_octeontx.c Normal file
View File

@ -0,0 +1,364 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
#include <log.h>
#include <malloc.h>
#include <pci.h>
#include <asm/io.h>
#include <linux/ioport.h>
DECLARE_GLOBAL_DATA_PTR;
/*
* This driver supports multiple types of operations / host bridges / busses:
*
* OTX_ECAM: Octeon TX & TX2 ECAM (Enhanced Configuration Access Mechanism)
* Used to access the internal on-chip devices which are connected
* to internal buses
* OTX_PEM: Octeon TX PEM (PCI Express MAC)
* Used to access the external (off-chip) PCI devices
* OTX2_PEM: Octeon TX2 PEM (PCI Express MAC)
* Used to access the external (off-chip) PCI devices
*/
enum {
OTX_ECAM,
OTX_PEM,
OTX2_PEM,
};
/**
* struct octeontx_pci - Driver private data
* @type: Device type matched via compatible (e.g. OTX_ECAM etc)
* @cfg: Config resource
* @bus: Bus resource
*/
struct octeontx_pci {
unsigned int type;
struct resource cfg;
struct resource bus;
};
static uintptr_t octeontx_cfg_addr(struct octeontx_pci *pcie,
int bus_offs, int shift_offs,
pci_dev_t bdf, uint offset)
{
u32 bus, dev, func;
uintptr_t address;
bus = PCI_BUS(bdf) + bus_offs;
dev = PCI_DEV(bdf);
func = PCI_FUNC(bdf);
address = (bus << (20 + shift_offs)) |
(dev << (15 + shift_offs)) |
(func << (12 + shift_offs)) | offset;
address += pcie->cfg.start;
return address;
}
static ulong readl_size(uintptr_t addr, enum pci_size_t size)
{
ulong val;
switch (size) {
case PCI_SIZE_8:
val = readb(addr);
break;
case PCI_SIZE_16:
val = readw(addr);
break;
case PCI_SIZE_32:
val = readl(addr);
break;
default:
printf("Invalid size\n");
return -EINVAL;
};
return val;
}
static void writel_size(uintptr_t addr, enum pci_size_t size, ulong valuep)
{
switch (size) {
case PCI_SIZE_8:
writeb(valuep, addr);
break;
case PCI_SIZE_16:
writew(valuep, addr);
break;
case PCI_SIZE_32:
writel(valuep, addr);
break;
default:
printf("Invalid size\n");
};
}
static bool octeontx_bdf_invalid(pci_dev_t bdf)
{
if (PCI_BUS(bdf) == 1 && PCI_DEV(bdf) > 0)
return true;
return false;
}
static int octeontx_ecam_read_config(const struct udevice *bus, pci_dev_t bdf,
uint offset, ulong *valuep,
enum pci_size_t size)
{
struct octeontx_pci *pcie = (struct octeontx_pci *)dev_get_priv(bus);
struct pci_controller *hose = dev_get_uclass_priv(bus);
uintptr_t address;
address = octeontx_cfg_addr(pcie, pcie->bus.start - hose->first_busno,
0, bdf, offset);
*valuep = readl_size(address, size);
debug("%02x.%02x.%02x: u%d %x -> %lx\n",
PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), size, offset, *valuep);
return 0;
}
static int octeontx_ecam_write_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong value,
enum pci_size_t size)
{
struct octeontx_pci *pcie = (struct octeontx_pci *)dev_get_priv(bus);
struct pci_controller *hose = dev_get_uclass_priv(bus);
uintptr_t address;
address = octeontx_cfg_addr(pcie, pcie->bus.start - hose->first_busno,
0, bdf, offset);
writel_size(address, size, value);
debug("%02x.%02x.%02x: u%d %x <- %lx\n",
PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), size, offset, value);
return 0;
}
static int octeontx_pem_read_config(const struct udevice *bus, pci_dev_t bdf,
uint offset, ulong *valuep,
enum pci_size_t size)
{
struct octeontx_pci *pcie = (struct octeontx_pci *)dev_get_priv(bus);
struct pci_controller *hose = dev_get_uclass_priv(bus);
uintptr_t address;
u8 hdrtype;
u8 pri_bus = pcie->bus.start + 1 - hose->first_busno;
u32 bus_offs = (pri_bus << 16) | (pri_bus << 8) | (pri_bus << 0);
address = octeontx_cfg_addr(pcie, 1 - hose->first_busno, 4,
bdf, 0);
*valuep = pci_conv_32_to_size(~0UL, offset, size);
if (octeontx_bdf_invalid(bdf))
return -EPERM;
*valuep = readl_size(address + offset, size);
hdrtype = readb(address + PCI_HEADER_TYPE);
if (hdrtype == PCI_HEADER_TYPE_BRIDGE &&
offset >= PCI_PRIMARY_BUS &&
offset <= PCI_SUBORDINATE_BUS &&
*valuep != pci_conv_32_to_size(~0UL, offset, size))
*valuep -= pci_conv_32_to_size(bus_offs, offset, size);
return 0;
}
static int octeontx_pem_write_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong value,
enum pci_size_t size)
{
struct octeontx_pci *pcie = (struct octeontx_pci *)dev_get_priv(bus);
struct pci_controller *hose = dev_get_uclass_priv(bus);
uintptr_t address;
u8 hdrtype;
u8 pri_bus = pcie->bus.start + 1 - hose->first_busno;
u32 bus_offs = (pri_bus << 16) | (pri_bus << 8) | (pri_bus << 0);
address = octeontx_cfg_addr(pcie, 1 - hose->first_busno, 4, bdf, 0);
hdrtype = readb(address + PCI_HEADER_TYPE);
if (hdrtype == PCI_HEADER_TYPE_BRIDGE &&
offset >= PCI_PRIMARY_BUS &&
offset <= PCI_SUBORDINATE_BUS &&
value != pci_conv_32_to_size(~0UL, offset, size))
value += pci_conv_32_to_size(bus_offs, offset, size);
if (octeontx_bdf_invalid(bdf))
return -EPERM;
writel_size(address + offset, size, value);
debug("%02x.%02x.%02x: u%d %x (%lx) <- %lx\n",
PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), size, offset,
address, value);
return 0;
}
static int octeontx2_pem_read_config(const struct udevice *bus, pci_dev_t bdf,
uint offset, ulong *valuep,
enum pci_size_t size)
{
struct octeontx_pci *pcie = (struct octeontx_pci *)dev_get_priv(bus);
struct pci_controller *hose = dev_get_uclass_priv(bus);
uintptr_t address;
address = octeontx_cfg_addr(pcie, 1 - hose->first_busno, 0,
bdf, 0);
*valuep = pci_conv_32_to_size(~0UL, offset, size);
if (octeontx_bdf_invalid(bdf))
return -EPERM;
*valuep = readl_size(address + offset, size);
debug("%02x.%02x.%02x: u%d %x (%lx) -> %lx\n",
PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), size, offset,
address, *valuep);
return 0;
}
static int octeontx2_pem_write_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong value,
enum pci_size_t size)
{
struct octeontx_pci *pcie = (struct octeontx_pci *)dev_get_priv(bus);
struct pci_controller *hose = dev_get_uclass_priv(bus);
uintptr_t address;
address = octeontx_cfg_addr(pcie, 1 - hose->first_busno, 0,
bdf, 0);
if (octeontx_bdf_invalid(bdf))
return -EPERM;
writel_size(address + offset, size, value);
debug("%02x.%02x.%02x: u%d %x (%lx) <- %lx\n",
PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), size, offset,
address, value);
return 0;
}
int pci_octeontx_read_config(const struct udevice *bus, pci_dev_t bdf,
uint offset, ulong *valuep,
enum pci_size_t size)
{
struct octeontx_pci *pcie = (struct octeontx_pci *)dev_get_priv(bus);
int ret = -EIO;
switch (pcie->type) {
case OTX_ECAM:
ret = octeontx_ecam_read_config(bus, bdf, offset, valuep,
size);
break;
case OTX_PEM:
ret = octeontx_pem_read_config(bus, bdf, offset, valuep,
size);
break;
case OTX2_PEM:
ret = octeontx2_pem_read_config(bus, bdf, offset, valuep,
size);
break;
}
return ret;
}
int pci_octeontx_write_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong value,
enum pci_size_t size)
{
struct octeontx_pci *pcie = (struct octeontx_pci *)dev_get_priv(bus);
int ret = -EIO;
switch (pcie->type) {
case OTX_ECAM:
ret = octeontx_ecam_write_config(bus, bdf, offset, value,
size);
break;
case OTX_PEM:
ret = octeontx_pem_write_config(bus, bdf, offset, value,
size);
break;
case OTX2_PEM:
ret = octeontx2_pem_write_config(bus, bdf, offset, value,
size);
break;
}
return ret;
}
static int pci_octeontx_ofdata_to_platdata(struct udevice *dev)
{
return 0;
}
static int pci_octeontx_probe(struct udevice *dev)
{
struct octeontx_pci *pcie = (struct octeontx_pci *)dev_get_priv(dev);
int err;
pcie->type = dev_get_driver_data(dev);
err = dev_read_resource(dev, 0, &pcie->cfg);
if (err) {
debug("Error reading resource: %s\n", fdt_strerror(err));
return err;
}
err = dev_read_pci_bus_range(dev, &pcie->bus);
if (err) {
debug("Error reading resource: %s\n", fdt_strerror(err));
return err;
}
return 0;
}
static const struct dm_pci_ops pci_octeontx_ops = {
.read_config = pci_octeontx_read_config,
.write_config = pci_octeontx_write_config,
};
static const struct udevice_id pci_octeontx_ids[] = {
{ .compatible = "cavium,pci-host-thunder-ecam", .data = OTX_ECAM },
{ .compatible = "cavium,pci-host-octeontx-ecam", .data = OTX_ECAM },
{ .compatible = "pci-host-ecam-generic", .data = OTX_ECAM },
{ .compatible = "cavium,pci-host-thunder-pem", .data = OTX_PEM },
{ .compatible = "marvell,pci-host-octeontx2-pem", .data = OTX2_PEM },
{ }
};
U_BOOT_DRIVER(pci_octeontx) = {
.name = "pci_octeontx",
.id = UCLASS_PCI,
.of_match = pci_octeontx_ids,
.ops = &pci_octeontx_ops,
.ofdata_to_platdata = pci_octeontx_ofdata_to_platdata,
.probe = pci_octeontx_probe,
.priv_auto_alloc_size = sizeof(struct octeontx_pci),
.flags = DM_FLAG_PRE_RELOC,
};

View File

@ -139,6 +139,16 @@ config WDT_MTK
The watchdog timer is stopped when initialized.
It performs full SoC reset.
config WDT_OCTEONTX
bool "OcteonTX core watchdog support"
depends on WDT && (ARCH_OCTEONTX || ARCH_OCTEONTX2)
default y
imply WATCHDOG
help
This enables OcteonTX watchdog driver, which can be
found on OcteonTX/TX2 chipsets and inline with driver model.
Only supports watchdog reset.
config WDT_OMAP3
bool "TI OMAP watchdog timer support"
depends on WDT && ARCH_OMAP2PLUS

View File

@ -26,6 +26,7 @@ obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o
obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o
obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o
obj-$(CONFIG_WDT_MTK) += mtk_wdt.o
obj-$(CONFIG_WDT_OCTEONTX) += octeontx_wdt.o
obj-$(CONFIG_WDT_OMAP3) += omap_wdt.o
obj-$(CONFIG_WDT_SBSA) += sbsa_gwdt.o
obj-$(CONFIG_WDT_K3_RTI) += rti_wdt.o

View File

@ -0,0 +1,66 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2019 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#include <dm.h>
#include <errno.h>
#include <wdt.h>
#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
#define CORE0_POKE_OFFSET 0x50000
#define CORE0_POKE_OFFSET_MASK 0xfffffULL
struct octeontx_wdt {
void __iomem *reg;
};
static int octeontx_wdt_reset(struct udevice *dev)
{
struct octeontx_wdt *priv = dev_get_priv(dev);
writeq(~0ULL, priv->reg);
return 0;
}
static int octeontx_wdt_probe(struct udevice *dev)
{
struct octeontx_wdt *priv = dev_get_priv(dev);
priv->reg = dev_remap_addr(dev);
if (!priv->reg)
return -EINVAL;
/*
* Save core poke register address in reg (its not 0xa0000 as
* extracted from the DT but 0x50000 instead)
*/
priv->reg = (void __iomem *)(((u64)priv->reg &
~CORE0_POKE_OFFSET_MASK) |
CORE0_POKE_OFFSET);
return 0;
}
static const struct wdt_ops octeontx_wdt_ops = {
.reset = octeontx_wdt_reset,
};
static const struct udevice_id octeontx_wdt_ids[] = {
{ .compatible = "arm,sbsa-gwdt" },
{}
};
U_BOOT_DRIVER(wdt_octeontx) = {
.name = "wdt_octeontx",
.id = UCLASS_WDT,
.of_match = octeontx_wdt_ids,
.ops = &octeontx_wdt_ops,
.priv_auto_alloc_size = sizeof(struct octeontx_wdt),
.probe = octeontx_wdt_probe,
};

View File

@ -0,0 +1,71 @@
/* SPDX-License-Identifier: GPL-2.0
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#ifndef __OCTEONTX2_COMMON_H__
#define __OCTEONTX2_COMMON_H__
#define CONFIG_SUPPORT_RAW_INITRD
/** Maximum size of image supported for bootm (and bootable FIT images) */
#define CONFIG_SYS_BOOTM_LEN (256 << 20)
/** Memory base address */
#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_TEXT_BASE
/** Stack starting address */
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0xffff0)
/** Heap size for U-Boot */
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 64 * 1024 * 1024)
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE
#define CONFIG_LAST_STAGE_INIT
/* Allow environment variable to be overwritten */
#define CONFIG_ENV_OVERWRITE
/** Reduce hashes printed out */
#define CONFIG_TFTP_TSIZE
/* Autoboot options */
#define CONFIG_RESET_TO_RETRY
#define CONFIG_BOOT_RETRY_TIME -1
#define CONFIG_BOOT_RETRY_MIN 30
/* BOOTP options */
#define CONFIG_BOOTP_BOOTFILESIZE
/** Extra environment settings */
#define CONFIG_EXTRA_ENV_SETTINGS \
"loadaddr=20080000\0" \
"ethrotate=yes\0" \
"autoload=0\0"
/** Environment defines */
#if defined(CONFIG_ENV_IS_IN_MMC)
#define CONFIG_SYS_MMC_ENV_DEV 0
#endif
/* Monitor Command Prompt */
#define CONFIG_SYS_CBSIZE 1024 /** Console I/O Buffer Size */
#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
#define CONFIG_SYS_MAXARGS 64 /** max command args */
#define CONFIG_SYS_MMC_MAX_BLK_COUNT 8192
#undef CONFIG_SYS_PROMPT
#define CONFIG_SYS_PROMPT env_get("prompt")
#if defined(CONFIG_MMC_OCTEONTX)
#define MMC_SUPPORTS_TUNING
/** EMMC specific defines */
#define CONFIG_SUPPORT_EMMC_BOOT
#define CONFIG_SUPPORT_EMMC_RPMB
#endif
#endif /* __OCTEONTX2_COMMON_H__ */

View File

@ -0,0 +1,88 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018 Marvell International Ltd.
*
* https://spdx.org/licenses
*/
#ifndef __OCTEONTX_COMMON_H__
#define __OCTEONTX_COMMON_H__
#define CONFIG_SUPPORT_RAW_INITRD
/** Maximum size of image supported for bootm (and bootable FIT images) */
#define CONFIG_SYS_BOOTM_LEN (256 << 20)
/** Memory base address */
#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_TEXT_BASE
/** Stack starting address */
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0xffff0)
/** Heap size for U-Boot */
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 64 * 1024 * 1024)
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE
/* Allow environment variable to be overwritten */
#define CONFIG_ENV_OVERWRITE
/** Reduce hashes printed out */
#define CONFIG_TFTP_TSIZE
/* Autoboot options */
#define CONFIG_RESET_TO_RETRY
#define CONFIG_BOOT_RETRY_TIME -1
#define CONFIG_BOOT_RETRY_MIN 30
/* BOOTP options */
#define CONFIG_BOOTP_BOOTFILESIZE
/* AHCI support Definitions */
#ifdef CONFIG_DM_SCSI
/** Enable 48-bit SATA addressing */
# define CONFIG_LBA48
/** Enable 64-bit addressing */
# define CONFIG_SYS_64BIT_LBA
#endif
/***** SPI Defines *********/
#ifdef CONFIG_DM_SPI_FLASH
# define CONFIG_SF_DEFAULT_BUS 0
# define CONFIG_SF_DEFAULT_CS 0
#endif
/** Extra environment settings */
#define CONFIG_EXTRA_ENV_SETTINGS \
"loadaddr=20080000\0" \
"autoload=0\0"
/** Environment defines */
#if defined(CONFIG_ENV_IS_IN_MMC)
#define CONFIG_SYS_MMC_ENV_DEV 0
#endif
/* Monitor Command Prompt */
#define CONFIG_SYS_CBSIZE 1024 /** Console I/O Buffer Size */
#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
#define CONFIG_SYS_MAXARGS 64 /** max command args */
#define CONFIG_SYS_MMC_MAX_BLK_COUNT 8192
#undef CONFIG_SYS_PROMPT
#define CONFIG_SYS_PROMPT env_get("prompt")
/** EMMC specific defines */
#if defined(CONFIG_MMC_OCTEONTX)
#define CONFIG_SUPPORT_EMMC_BOOT
#define CONFIG_SUPPORT_EMMC_RPMB
#endif
#if defined(CONFIG_NAND_OCTEONTX)
/*#define CONFIG_MTD_CONCAT */
#define CONFIG_SYS_MAX_NAND_DEVICE 8
#define CONFIG_SYS_NAND_ONFI_DETECTION
#endif
#endif /* __OCTEONTX_COMMON_H__ */

View File

@ -680,6 +680,18 @@ int dev_read_alias_highest_id(const char *stem);
*/
int dev_get_child_count(const struct udevice *dev);
/**
* dev_read_pci_bus_range - Read PCI bus-range resource
*
* Look at the bus range property of a device node and return the pci bus
* range for this node.
*
* @dev: device to examine
* @res returns the resource
* @return 0 if ok, negative on error
*/
int dev_read_pci_bus_range(const struct udevice *dev, struct resource *res);
#else /* CONFIG_DM_DEV_READ_INLINE is enabled */
static inline int dev_read_u32(const struct udevice *dev,

View File

@ -444,6 +444,19 @@ int fdtdec_get_pci_vendev(const void *blob, int node,
int fdtdec_get_pci_bar32(const struct udevice *dev, struct fdt_pci_addr *addr,
u32 *bar);
/**
* Look at the bus range property of a device node and return the pci bus
* range for this node.
* The property must hold one fdt_pci_addr with a length.
* @param blob FDT blob
* @param node node to examine
* @param res the resource structure to return the bus range
* @return 0 if ok, negative on error
*/
int fdtdec_get_pci_bus_range(const void *blob, int node,
struct fdt_resource *res);
/**
* Look up a 32-bit integer property in a node and return it. The property
* must have at least 4 bytes of data. The value of the first cell is

View File

@ -465,6 +465,9 @@
#define PCI_EA_FIRST_ENT 4 /* First EA Entry in List */
#define PCI_EA_ES 0x00000007 /* Entry Size */
#define PCI_EA_BEI 0x000000f0 /* BAR Equivalent Indicator */
/* 9-14 map to VF BARs 0-5 respectively */
#define PCI_EA_BEI_VF_BAR0 9
#define PCI_EA_BEI_VF_BAR5 14
/* Base, MaxOffset registers */
/* bit 0 is reserved */
#define PCI_EA_IS_64 0x00000002 /* 64-bit field flag */
@ -493,6 +496,17 @@
#define PCI_EXP_SLTCAP 20 /* Slot Capabilities */
#define PCI_EXP_SLTCAP_PSN 0xfff80000 /* Physical Slot Number */
#define PCI_EXP_LNKCTL2 48 /* Link Control 2 */
/* Single Root I/O Virtualization Registers */
#define PCI_SRIOV_CAP 0x04 /* SR-IOV Capabilities */
#define PCI_SRIOV_CTRL 0x08 /* SR-IOV Control */
#define PCI_SRIOV_CTRL_VFE 0x01 /* VF Enable */
#define PCI_SRIOV_CTRL_MSE 0x08 /* VF Memory Space Enable */
#define PCI_SRIOV_INITIAL_VF 0x0c /* Initial VFs */
#define PCI_SRIOV_TOTAL_VF 0x0e /* Total VFs */
#define PCI_SRIOV_NUM_VF 0x10 /* Number of VFs */
#define PCI_SRIOV_VF_OFFSET 0x14 /* First VF Offset */
#define PCI_SRIOV_VF_STRIDE 0x16 /* Following VF Stride */
#define PCI_SRIOV_VF_DID 0x1a /* VF Device ID */
/* Include the ID list */
@ -590,8 +604,6 @@ extern void pci_cfgfunc_do_nothing(struct pci_controller* hose, pci_dev_t dev,
extern void pci_cfgfunc_config_device(struct pci_controller* hose, pci_dev_t dev,
struct pci_config_table *);
#define MAX_PCI_REGIONS 7
#define INDIRECT_TYPE_NO_PCIE_LINK 1
/**
@ -632,7 +644,7 @@ struct pci_controller {
* for PCI controllers and a separate UCLASS (or perhaps
* UCLASS_PCI_GENERIC) is used for bridges.
*/
struct pci_region regions[MAX_PCI_REGIONS];
struct pci_region *regions;
int region_count;
struct pci_config_table *config_table;
@ -892,12 +904,20 @@ struct udevice;
* @vendor: PCI vendor ID (see pci_ids.h)
* @device: PCI device ID (see pci_ids.h)
* @class: PCI class, 3 bytes: (base, sub, prog-if)
* @is_virtfn: True for Virtual Function device
* @pfdev: Handle to Physical Function device
* @virtid: Virtual Function Index
*/
struct pci_child_platdata {
int devfn;
unsigned short vendor;
unsigned short device;
unsigned int class;
/* Variables for CONFIG_PCI_SRIOV */
bool is_virtfn;
struct udevice *pfdev;
int virtid;
};
/* PCI bus operations */
@ -1210,6 +1230,25 @@ int pci_generic_mmap_read_config(
ulong *valuep,
enum pci_size_t size);
#if defined(CONFIG_PCI_SRIOV)
/**
* pci_sriov_init() - Scan Virtual Function devices
*
* @pdev: Physical Function udevice handle
* @vf_en: Number of Virtual Function devices to enable
* @return 0 on success, -ve on error
*/
int pci_sriov_init(struct udevice *pdev, int vf_en);
/**
* pci_sriov_get_totalvfs() - Get total available Virtual Function devices
*
* @pdev: Physical Function udevice handle
* @return count on success, -ve on error
*/
int pci_sriov_get_totalvfs(struct udevice *pdev);
#endif
#ifdef CONFIG_DM_PCI_COMPAT
/* Compatibility with old naming */
static inline int pci_write_config_dword(pci_dev_t pcidev, int offset,

View File

@ -243,6 +243,22 @@ int fdtdec_get_pci_bar32(const struct udevice *dev, struct fdt_pci_addr *addr,
return 0;
}
int fdtdec_get_pci_bus_range(const void *blob, int node,
struct fdt_resource *res)
{
const u32 *values;
int len;
values = fdt_getprop(blob, node, "bus-range", &len);
if (!values || len < sizeof(*values) * 2)
return -EINVAL;
res->start = fdt32_to_cpu(*values++);
res->end = fdt32_to_cpu(*values);
return 0;
}
#endif
uint64_t fdtdec_get_uint64(const void *blob, int node, const char *prop_name,

View File

@ -354,3 +354,25 @@ static int dm_test_pci_on_bus(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_pci_on_bus, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
/*
* Test support for multiple memory regions enabled via
* CONFIG_PCI_REGION_MULTI_ENTRY. When this feature is not enabled,
* only the last region of one type is stored. In this test-case,
* we have 2 memory regions, the first at 0x3000.0000 and the 2nd
* at 0x3100.0000. A correct test results now in BAR1 located at
* 0x3000.0000.
*/
static int dm_test_pci_region_multi(struct unit_test_state *uts)
{
struct udevice *dev;
ulong mem_addr;
/* Test memory BAR1 on bus#1 */
ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x08, 0), &dev));
mem_addr = dm_pci_read_bar32(dev, 1);
ut_asserteq(mem_addr, 0x30000000);
return 0;
}
DM_TEST(dm_test_pci_region_multi, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);