mirror of
https://github.com/CTCaer/switch-l4t-atf.git
synced 2024-11-24 02:09:46 +00:00
Add BL31 support for Broadcom stingray platform
Change-Id: Icfef5b6923dc292e637001045a334c499d346fe9 Signed-off-by: Sheetal Tigadoli <sheetal.tigadoli@broadcom.com>
This commit is contained in:
parent
f29d1e0c72
commit
3942d3a8ea
398
drivers/brcm/chimp.c
Normal file
398
drivers/brcm/chimp.c
Normal file
@ -0,0 +1,398 @@
|
||||
/*
|
||||
* Copyright (c) 2016 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <drivers/delay_timer.h>
|
||||
|
||||
#include <chimp.h>
|
||||
#include <chimp_nv_defs.h>
|
||||
|
||||
#define CHIMP_DEFAULT_STARTUP_ADDR 0xb4300000
|
||||
|
||||
/* ChiMP's view of APE scratchpad memory for fastboot */
|
||||
#define CHIMP_FASTBOOT_ADDR 0x61000000
|
||||
|
||||
#define CHIMP_PREPARE_ACCESS_WINDOW(addr) \
|
||||
(\
|
||||
mmio_write_32(\
|
||||
NIC400_NITRO_CHIMP_S_IDM_IO_CONTROL_DIRECT, \
|
||||
addr & 0xffc00000)\
|
||||
)
|
||||
#define CHIMP_INDIRECT_TGT_ADDR(addr) \
|
||||
(CHIMP_INDIRECT_BASE + (addr & CHIMP_INDIRECT_ADDR_MASK))
|
||||
|
||||
#define CHIMP_CTRL_ADDR(x) (CHIMP_REG_CTRL_BASE + x)
|
||||
|
||||
/* For non-PAXC builds */
|
||||
#ifndef CHIMP_FB1_ENTRY
|
||||
#define CHIMP_FB1_ENTRY 0
|
||||
#endif
|
||||
|
||||
#define CHIMP_DBG VERBOSE
|
||||
|
||||
void bcm_chimp_write(uintptr_t addr, uint32_t value)
|
||||
{
|
||||
CHIMP_PREPARE_ACCESS_WINDOW(addr);
|
||||
mmio_write_32(CHIMP_INDIRECT_TGT_ADDR(addr), value);
|
||||
}
|
||||
|
||||
uint32_t bcm_chimp_read(uintptr_t addr)
|
||||
{
|
||||
CHIMP_PREPARE_ACCESS_WINDOW(addr);
|
||||
return mmio_read_32(CHIMP_INDIRECT_TGT_ADDR(addr));
|
||||
}
|
||||
|
||||
void bcm_chimp_clrbits(uintptr_t addr, uint32_t bits)
|
||||
{
|
||||
CHIMP_PREPARE_ACCESS_WINDOW(addr);
|
||||
mmio_clrbits_32(CHIMP_INDIRECT_TGT_ADDR(addr), bits);
|
||||
}
|
||||
|
||||
void bcm_chimp_setbits(uintptr_t addr, uint32_t bits)
|
||||
{
|
||||
CHIMP_PREPARE_ACCESS_WINDOW(addr);
|
||||
mmio_setbits_32(CHIMP_INDIRECT_TGT_ADDR(addr), bits);
|
||||
}
|
||||
|
||||
int bcm_chimp_is_nic_mode(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
/* Check if ChiMP straps are set */
|
||||
val = mmio_read_32(CDRU_CHIP_STRAP_DATA_LSW);
|
||||
val &= CDRU_CHIP_STRAP_DATA_LSW__NIC_MODE_MASK;
|
||||
|
||||
return val == CDRU_CHIP_STRAP_DATA_LSW__NIC_MODE_MASK;
|
||||
}
|
||||
|
||||
void bcm_chimp_fru_prog_done(bool is_done)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = is_done ? (1 << CHIMP_FRU_PROG_DONE_BIT) : 0;
|
||||
bcm_chimp_setbits(CHIMP_REG_ECO_RESERVED, val);
|
||||
}
|
||||
|
||||
int bcm_chimp_handshake_done(void)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
value = bcm_chimp_read(CHIMP_REG_ECO_RESERVED);
|
||||
value &= (1 << CHIMP_FLASH_ACCESS_DONE_BIT);
|
||||
|
||||
return value != 0;
|
||||
}
|
||||
|
||||
int bcm_chimp_wait_handshake(void)
|
||||
{
|
||||
uint32_t timeout = CHIMP_HANDSHAKE_TIMEOUT_MS;
|
||||
uint32_t status;
|
||||
|
||||
INFO("Waiting for ChiMP handshake...\n");
|
||||
do {
|
||||
if (bcm_chimp_handshake_done())
|
||||
break;
|
||||
/* No need to wait if ChiMP reported an error */
|
||||
status = bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_STAT_REG);
|
||||
if (status & CHIMP_ERROR_MASK) {
|
||||
ERROR("ChiMP error 0x%x. Wait aborted\n", status);
|
||||
break;
|
||||
}
|
||||
mdelay(1);
|
||||
} while (--timeout);
|
||||
|
||||
if (!bcm_chimp_handshake_done()) {
|
||||
if (timeout == 0) {
|
||||
WARN("Timeout waiting for ChiMP handshake\n");
|
||||
}
|
||||
} else {
|
||||
INFO("Got handshake from ChiMP!\n");
|
||||
}
|
||||
|
||||
return bcm_chimp_handshake_done();
|
||||
}
|
||||
|
||||
uint32_t bcm_chimp_read_ctrl(uint32_t offset)
|
||||
{
|
||||
return bcm_chimp_read(CHIMP_CTRL_ADDR(offset));
|
||||
}
|
||||
|
||||
static int bcm_chimp_nitro_reset(void)
|
||||
{
|
||||
uint32_t timeout;
|
||||
|
||||
/* Perform tasks done by M0 in NIC mode */
|
||||
CHIMP_DBG("Taking Nitro out of reset\n");
|
||||
mmio_setbits_32(CDRU_MISC_RESET_CONTROL,
|
||||
/* MHB_RESET_N */
|
||||
(1 << CDRU_MISC_RESET_CONTROL__CDRU_MHB_RESET_N_R) |
|
||||
/* PCI_RESET_N */
|
||||
(1 << CDRU_MISC_RESET_CONTROL__CDRU_PCIE_RESET_N_R) |
|
||||
/* PM_RESET_N */
|
||||
(1 << CDRU_MISC_RESET_CONTROL__CDRU_PM_RESET_N_R) |
|
||||
/* NIC_RESET_N */
|
||||
(1 << CDRU_MISC_RESET_CONTROL__CDRU_NITRO_RESET_N_R)
|
||||
);
|
||||
|
||||
/* Wait until Nitro is out of reset */
|
||||
timeout = NIC_RESET_RELEASE_TIMEOUT_US;
|
||||
do {
|
||||
uint32_t value;
|
||||
|
||||
value = bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_MODE_REG);
|
||||
if ((value & CHIMP_BPE_MODE_ID_MASK) ==
|
||||
CHIMP_BPE_MODE_ID_PATTERN)
|
||||
break;
|
||||
udelay(1);
|
||||
} while (--timeout);
|
||||
|
||||
if (timeout == 0) {
|
||||
ERROR("NIC reset release timed out\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bcm_nitro_secure_mode_enable(void)
|
||||
{
|
||||
mmio_setbits_32(CDRU_NITRO_CONTROL,
|
||||
(1 << CDRU_NITRO_CONTROL__CDRU_NITRO_SEC_MODE_R) |
|
||||
(1 << CDRU_NITRO_CONTROL__CDRU_NITRO_SEC_OVERRIDE_R));
|
||||
mmio_write_32(NITRO_TZPC_TZPCDECPROT0clr,
|
||||
/* NITRO_TZPC */
|
||||
1 << NITRO_TZPC_TZPCDECPROT0clr__DECPROT0_chimp_m_clr_R);
|
||||
}
|
||||
|
||||
static int bcm_chimp_reset_and_initial_setup(void)
|
||||
{
|
||||
|
||||
int err;
|
||||
uint32_t handshake_reg;
|
||||
|
||||
err = bcm_chimp_nitro_reset();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Enable Nitro secure mode */
|
||||
bcm_nitro_secure_mode_enable();
|
||||
|
||||
/* Force ChiMP back into reset */
|
||||
bcm_chimp_setbits(CHIMP_CTRL_ADDR(CHIMP_REG_CTRL_BPE_MODE_REG),
|
||||
1 << CHIMP_REG_CHIMP_REG_CTRL_BPE_MODE_REG__cm3_rst_R);
|
||||
|
||||
handshake_reg = (1 << SR_IN_SMARTNIC_MODE_BIT);
|
||||
|
||||
/* Get OTP secure Chimp boot status */
|
||||
if (mmio_read_32(CRMU_OTP_STATUS) & (1 << CRMU_OTP_STATUS_BIT))
|
||||
handshake_reg |= (1 << SR_CHIMP_SECURE_BOOT_BIT);
|
||||
|
||||
bcm_chimp_write(CHIMP_REG_ECO_RESERVED, handshake_reg);
|
||||
|
||||
CHIMP_DBG("ChiMP reset and initial handshake parameters set\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bcm_nitro_chimp_release_reset(void)
|
||||
{
|
||||
bcm_chimp_clrbits(CHIMP_CTRL_ADDR(CHIMP_REG_CTRL_BPE_MODE_REG),
|
||||
1 << CHIMP_REG_CHIMP_REG_CTRL_BPE_MODE_REG__cm3_rst_R);
|
||||
|
||||
CHIMP_DBG("Nitro Reset Released\n");
|
||||
}
|
||||
|
||||
static void bcm_chimp_set_fastboot(int mode)
|
||||
{
|
||||
uint32_t fb_entry;
|
||||
|
||||
/* 1. Enable fastboot */
|
||||
bcm_chimp_setbits(CHIMP_CTRL_ADDR(CHIMP_REG_CTRL_BPE_MODE_REG),
|
||||
(1 << CHIMP_FAST_BOOT_MODE_BIT));
|
||||
fb_entry = CHIMP_FASTBOOT_ADDR | mode;
|
||||
if (mode == CHIMP_FASTBOOT_JUMP_IN_PLACE)
|
||||
fb_entry = CHIMP_FB1_ENTRY;
|
||||
/* 2. Write startup address and mode */
|
||||
INFO("Setting fastboot type %d entry to 0x%x\n", mode, fb_entry);
|
||||
bcm_chimp_write(
|
||||
CHIMP_CTRL_ADDR(CHIMP_REG_CTRL_FSTBOOT_PTR_REG),
|
||||
fb_entry);
|
||||
}
|
||||
|
||||
#ifndef CHIMPFW_USE_SIDELOAD
|
||||
static void bcm_chimp_load_fw_from_spi(uintptr_t spi_addr, size_t size)
|
||||
{
|
||||
uintptr_t ape_scpad;
|
||||
uintptr_t dest;
|
||||
size_t bytes_left;
|
||||
|
||||
ape_scpad = CHIMP_REG_CHIMP_APE_SCPAD;
|
||||
dest = CHIMP_INDIRECT_TGT_ADDR(CHIMP_REG_CHIMP_APE_SCPAD);
|
||||
bytes_left = size;
|
||||
|
||||
while (bytes_left) {
|
||||
uint32_t delta;
|
||||
|
||||
delta = bytes_left > CHIMP_WINDOW_SIZE ?
|
||||
bytes_left - CHIMP_WINDOW_SIZE : bytes_left;
|
||||
CHIMP_PREPARE_ACCESS_WINDOW(ape_scpad);
|
||||
INFO("Transferring %d byte(s) from 0x%lx to 0x%lx\n",
|
||||
delta, spi_addr, dest);
|
||||
/*
|
||||
* This single memcpy call takes significant amount of time
|
||||
* on Palladium. Be patient
|
||||
*/
|
||||
memcpy((void *)dest, (void *)spi_addr, delta);
|
||||
bytes_left -= delta;
|
||||
INFO("Transferred %d byte(s) from 0x%lx to 0x%lx (%lu%%)\n",
|
||||
delta, spi_addr, dest,
|
||||
((size - bytes_left) * 100)/size);
|
||||
spi_addr += delta;
|
||||
dest += delta;
|
||||
ape_scpad += delta;
|
||||
}
|
||||
}
|
||||
|
||||
static int bcm_chimp_find_fw_in_spi(uintptr_t *addr, size_t *size)
|
||||
{
|
||||
int i;
|
||||
bnxnvm_master_block_header_t *master_block_hdr;
|
||||
bnxnvm_directory_block_header_t *dir_block_hdr;
|
||||
bnxnvm_directory_entry_t *dir_entry;
|
||||
int found;
|
||||
|
||||
found = 0;
|
||||
|
||||
/* Read the master block */
|
||||
master_block_hdr =
|
||||
(bnxnvm_master_block_header_t *)(uintptr_t)QSPI_BASE_ADDR;
|
||||
if (master_block_hdr->sig != BNXNVM_MASTER_BLOCK_SIG) {
|
||||
WARN("Invalid masterblock 0x%x (expected 0x%x)\n",
|
||||
master_block_hdr->sig,
|
||||
BNXNVM_MASTER_BLOCK_SIG);
|
||||
return -NV_NOT_NVRAM;
|
||||
}
|
||||
if ((master_block_hdr->block_size > NV_MAX_BLOCK_SIZE) ||
|
||||
(master_block_hdr->directory_offset >=
|
||||
master_block_hdr->nvram_size)) {
|
||||
WARN("Invalid masterblock block size 0x%x or directory offset 0x%x\n",
|
||||
master_block_hdr->block_size,
|
||||
master_block_hdr->directory_offset);
|
||||
return -NV_BAD_MB;
|
||||
}
|
||||
|
||||
/* Skip to the Directory block start */
|
||||
dir_block_hdr =
|
||||
(bnxnvm_directory_block_header_t *)
|
||||
((uintptr_t)QSPI_BASE_ADDR +
|
||||
master_block_hdr->directory_offset);
|
||||
if (dir_block_hdr->sig != BNXNVM_DIRECTORY_BLOCK_SIG) {
|
||||
WARN("Invalid directory header 0x%x (expected 0x%x)\n",
|
||||
dir_block_hdr->sig,
|
||||
BNXNVM_DIRECTORY_BLOCK_SIG);
|
||||
return -NV_BAD_DIR_HEADER;
|
||||
}
|
||||
|
||||
/* Locate the firmware */
|
||||
for (i = 0; i < dir_block_hdr->entries; i++) {
|
||||
*addr = ((uintptr_t)dir_block_hdr + dir_block_hdr->length +
|
||||
i * dir_block_hdr->entry_length);
|
||||
dir_entry = (bnxnvm_directory_entry_t *)(*addr);
|
||||
if ((dir_entry->type == BNX_DIR_TYPE_BOOTCODE) ||
|
||||
(dir_entry->type == BNX_DIR_TYPE_BOOTCODE_2)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return -NV_FW_NOT_FOUND;
|
||||
|
||||
*addr = QSPI_BASE_ADDR + dir_entry->item_location;
|
||||
*size = dir_entry->data_length;
|
||||
|
||||
INFO("Found chimp firmware at 0x%lx, size %lu byte(s)\n",
|
||||
*addr, *size);
|
||||
|
||||
return NV_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
int bcm_chimp_initiate_fastboot(int fastboot_type)
|
||||
{
|
||||
int err;
|
||||
|
||||
if ((fastboot_type != CHIMP_FASTBOOT_NITRO_RESET) &&
|
||||
(fastboot_type <= CHIMP_FASTBOOT_JUMP_DECOMPRESS)) {
|
||||
CHIMP_DBG("Initiating ChiMP fastboot type %d\n", fastboot_type);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are here, M0 did not setup Nitro because NIC mode
|
||||
* strap was not present
|
||||
*/
|
||||
err = bcm_chimp_reset_and_initial_setup();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (fastboot_type > CHIMP_FASTBOOT_JUMP_DECOMPRESS) {
|
||||
WARN("ChiMP setup deferred\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fastboot_type != CHIMP_FASTBOOT_NITRO_RESET) {
|
||||
|
||||
if ((fastboot_type == CHIMP_FASTBOOT_JUMP_IN_PLACE) &&
|
||||
(CHIMP_FB1_ENTRY == 0)) {
|
||||
ERROR("Missing ESAL entry point for fastboot type 1.\n"
|
||||
"Fastboot failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: We need to think of the way to load the ChiMP fw.
|
||||
* This could be SPI, NAND, etc.
|
||||
* For now we temporarily stick to the SPI load unless
|
||||
* CHIMPFW_USE_SIDELOAD is defined. Note that for the SPI NVRAM
|
||||
* image we need to parse directory and get the image.
|
||||
* When we load image from other media there is no need to
|
||||
* parse because fw image can be directly placed into the APE's
|
||||
* scratchpad.
|
||||
* For sideload method we simply reset the ChiMP, set bpe_reg
|
||||
* to do fastboot with the type we define, and release from
|
||||
* reset so that ROM loader would initiate fastboot immediately
|
||||
*/
|
||||
#ifndef CHIMPFW_USE_SIDELOAD
|
||||
{
|
||||
uintptr_t spi_addr;
|
||||
size_t size;
|
||||
|
||||
err = bcm_chimp_find_fw_in_spi(&spi_addr, &size);
|
||||
if (!err) {
|
||||
INFO("Loading ChiMP firmware, addr 0x%lx, size %lu byte(s)\n",
|
||||
spi_addr, size);
|
||||
bcm_chimp_load_fw_from_spi(spi_addr, size);
|
||||
} else {
|
||||
ERROR("Error %d ChiMP firmware not in NVRAM directory!\n",
|
||||
err);
|
||||
}
|
||||
}
|
||||
#else
|
||||
INFO("Skip ChiMP QSPI fastboot type %d due to sideload requested\n",
|
||||
fastboot_type);
|
||||
#endif
|
||||
if (!err) {
|
||||
INFO("Instruct ChiMP to fastboot\n");
|
||||
bcm_chimp_set_fastboot(fastboot_type);
|
||||
INFO("Fastboot mode set\n");
|
||||
}
|
||||
}
|
||||
|
||||
bcm_nitro_chimp_release_reset();
|
||||
|
||||
return err;
|
||||
}
|
419
include/drivers/brcm/chimp_nv_defs.h
Normal file
419
include/drivers/brcm/chimp_nv_defs.h
Normal file
@ -0,0 +1,419 @@
|
||||
/*
|
||||
* Copyright (c) 2016 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef BNXNVM_DEFS_H
|
||||
#define BNXNVM_DEFS_H
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define PACKED_STRUCT __packed
|
||||
#else /* non-GCC compiler */
|
||||
|
||||
#ifndef DOS_DRIVERS
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
#define PACKED_STRUCT
|
||||
#endif
|
||||
|
||||
typedef uint32_t u32_t;
|
||||
typedef uint8_t u8_t;
|
||||
typedef uint16_t u16_t;
|
||||
|
||||
#define BNXNVM_DEFAULT_BLOCK_SIZE 4096
|
||||
#define BNXNVM_UNUSED_BYTE_VALUE 0xff
|
||||
|
||||
#define NV_MAX_BLOCK_SIZE 16384
|
||||
|
||||
#define BITS_PER_BYTE (8)
|
||||
#define SIZEOF_IN_BITS(x) (sizeof(x)*BITS_PER_BYTE)
|
||||
|
||||
/************************/
|
||||
/* byte-swapping macros */
|
||||
/************************/
|
||||
#define BYTE_SWAP_16(x) \
|
||||
((((u16_t)(x) & 0xff00) >> 8) | \
|
||||
(((u16_t)(x) & 0x00ff) << 8))
|
||||
#define BYTE_SWAP_32(x) \
|
||||
((((u32_t)(x) & 0xff000000) >> 24) | \
|
||||
(((u32_t)(x) & 0x00ff0000) >> 8) | \
|
||||
(((u32_t)(x) & 0x0000ff00) << 8) | \
|
||||
(((u32_t)(x) & 0x000000ff) << 24))
|
||||
|
||||
/* auto-detect integer size */
|
||||
#define BYTE_SWAP_INT(x) \
|
||||
(SIZEOF_IN_BITS(x) == 16 ? BYTE_SWAP_16(x) : \
|
||||
SIZEOF_IN_BITS(x) == 32 ? BYTE_SWAP_32(x) : (x))
|
||||
|
||||
/********************************/
|
||||
/* Architecture-specific macros */
|
||||
/********************************/
|
||||
#ifdef __BIG_ENDIAN__ /* e.g. Motorola */
|
||||
|
||||
#define BE_INT16(x) (x)
|
||||
#define BE_INT32(x) (x)
|
||||
#define BE_INT(x) (x)
|
||||
#define LE_INT16(x) BYTE_SWAP_16(x)
|
||||
#define LE_INT32(x) BYTE_SWAP_32(x)
|
||||
#define LE_INT(x) BYTE_SWAP_INT(x)
|
||||
|
||||
#else /* Little Endian (e.g. Intel) */
|
||||
|
||||
#define LE_INT16(x) (x)
|
||||
#define LE_INT32(x) (x)
|
||||
#define LE_INT(x) (x)
|
||||
#define BE_INT16(x) BYTE_SWAP_16(x)
|
||||
#define BE_INT32(x) BYTE_SWAP_32(x)
|
||||
#define BE_INT(x) BYTE_SWAP_INT(x)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
enum {
|
||||
NV_OK = 0,
|
||||
NV_NOT_NVRAM,
|
||||
NV_BAD_MB,
|
||||
NV_BAD_DIR_HEADER,
|
||||
NV_BAD_DIR_ENTRY,
|
||||
NV_FW_NOT_FOUND,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
#define BNXNVM_MASTER_BLOCK_SIG BE_INT32(0x424E5834) /*"BNX4"*/
|
||||
/* Signature*/
|
||||
u32_t sig;
|
||||
/* Length of Master Block Header, in bytes [32] */
|
||||
u32_t length;
|
||||
/* Block size, in bytes [4096] */
|
||||
u32_t block_size;
|
||||
/* Byte-offset to Directory Block (translated) */
|
||||
u32_t directory_offset;
|
||||
/* Byte-offset to Block Redirection Table (non-translated) */
|
||||
u32_t redirect_offset;
|
||||
/* Size, in bytes of Reserved Blocks region (at end of NVRAM) */
|
||||
u32_t reserved_size;
|
||||
/*
|
||||
* Size of NVRAM (in bytes) - may be used to
|
||||
* override auto-detected size
|
||||
*/
|
||||
u32_t nvram_size;
|
||||
/* CRC-32 (IEEE 802.3 compatible) of the above */
|
||||
u32_t chksum;
|
||||
} PACKED_STRUCT bnxnvm_master_block_header_t;
|
||||
|
||||
typedef struct {
|
||||
#define BNXNVM_DIRECTORY_BLOCK_SIG BE_INT32(0x44697230) /* "Dir0" */
|
||||
/* Signature */
|
||||
u32_t sig;
|
||||
/* Length of Directory Header, in bytes [16] */
|
||||
u32_t length;
|
||||
/* Number of Directory Entries */
|
||||
u32_t entries;
|
||||
/* Length of each Directory Entry, in bytes [24] */
|
||||
u32_t entry_length;
|
||||
} PACKED_STRUCT bnxnvm_directory_block_header_t;
|
||||
|
||||
typedef struct {
|
||||
/* Directory Entry Type (see enum bnxnvm_directory_type) */
|
||||
u16_t type;
|
||||
/* Instance of this Directory Entry type (0-based) */
|
||||
u16_t ordinal;
|
||||
/*
|
||||
* Directory Entry Extension flags used to identify
|
||||
* secondary instances of a type:ordinal combinations
|
||||
*/
|
||||
u16_t ext;
|
||||
/* Directory Entry Attribute flags used to describe the item contents */
|
||||
u16_t attr;
|
||||
/* Item location in NVRAM specified as offset (in bytes) */
|
||||
u32_t item_location;
|
||||
/*
|
||||
* Length of NVRAM item in bytes
|
||||
* (including padding - multiple of block size)
|
||||
*/
|
||||
u32_t item_length;
|
||||
/* Length of item data in bytes (excluding padding) */
|
||||
u32_t data_length;
|
||||
/*
|
||||
* CRC-32 (IEEE 802.3 compatible) of item data
|
||||
* (excluding padding) (optional)
|
||||
*/
|
||||
u32_t data_chksum;
|
||||
} PACKED_STRUCT bnxnvm_directory_entry_t;
|
||||
|
||||
enum bnxnvm_version_format {
|
||||
/* US-ASCII string (not necessarily null-terminated) */
|
||||
BNX_VERSION_FMT_ASCII = 0,
|
||||
/* Each field 16-bits, displayed as unpadded decimal (e.g. "1.2.3.4") */
|
||||
BNX_VERSION_FMT_DEC = 1,
|
||||
/* A single hexadecimal value, up to 64-bits (no dots) */
|
||||
BNX_VERSION_FMT_HEX = 2,
|
||||
/* Multiple version values (three 8-bit version fields) */
|
||||
BNX_VERSION_FMT_MULTI = 3
|
||||
};
|
||||
|
||||
/* This structure definition must not change: */
|
||||
typedef struct {
|
||||
u16_t flags; /* bit-flags (defaults to 0x0000) */
|
||||
u8_t version_format; /* enum bnxnvm_version_format */
|
||||
u8_t version_length; /* in bytes */
|
||||
u8_t version[16]; /* version value */
|
||||
u16_t dir_type; /* enum bnxnvm_directory_type */
|
||||
/* size of the entire trailer (to locate end of component data) */
|
||||
u16_t trailer_length;
|
||||
#define BNXNVM_COMPONENT_TRAILER_SIG BE_INT32(0x54726c72) /* "Trlr" */
|
||||
u32_t sig;
|
||||
u32_t chksum; /* CRC-32 of all bytes to this point */
|
||||
} PACKED_STRUCT bnxnvm_component_trailer_base_t;
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
* new trailer members (e.g. digital signature)
|
||||
* go here (insert at top):
|
||||
*/
|
||||
u8_t rsa_sig[256]; /* 2048-bit RSA-encrypted SHA-256 hash */
|
||||
bnxnvm_component_trailer_base_t base;
|
||||
} PACKED_STRUCT bnxnvm_component_trailer_t;
|
||||
|
||||
#define BNX_MAX_LEN_DIR_NAME 12
|
||||
#define BNX_MAX_LEN_DIR_DESC 50
|
||||
/*********************************************************
|
||||
* NVRAM Directory Entry/Item Types, Names, and Descriptions
|
||||
*
|
||||
* If you see a name or description that needs improvement,
|
||||
* please correct it or raise for discussion.
|
||||
* When adding a new directory type, it would be appreciated
|
||||
* if you also updated ../../libs/nvm/bnxt_nvm_str.c.
|
||||
* DIR_NAME macros may contain up to 12 alpha-numeric
|
||||
* US-ASCII characters only, camelCase is preferred for clarity.
|
||||
* DIR_DESC macros may contain up to 50 US-ASCII characters
|
||||
* providing a verbose description of the directory type.
|
||||
*/
|
||||
enum bnxnvm_directory_type {
|
||||
/* 0x00 Unused directory entry, available for use */
|
||||
BNX_DIR_TYPE_UNUSED = 0,
|
||||
#define BNX_DIR_NAME_UNUSED "unused"
|
||||
#define BNX_DIR_DESC_UNUSED "Deleted directory entry, available for reuse"
|
||||
/* 0x01 Package installation log */
|
||||
BNX_DIR_TYPE_PKG_LOG = 1,
|
||||
#define BNX_DIR_NAME_PKG_LOG "pkgLog"
|
||||
#define BNX_DIR_DESC_PKG_LOG "Package Installation Log"
|
||||
BNX_DIR_TYPE_CHIMP_PATCH = 3,
|
||||
#define BNX_DIR_NAME_CHIMP_PATCH "chimpPatch"
|
||||
#define BNX_DIR_DESC_CHIMP_PATCH "ChiMP Patch Firmware"
|
||||
/* 0x04 ChiMP firmware: Boot Code phase 1 */
|
||||
BNX_DIR_TYPE_BOOTCODE = 4,
|
||||
#define BNX_DIR_NAME_BOOTCODE "chimpBoot"
|
||||
#define BNX_DIR_DESC_BOOTCODE "Chip Management Processor Boot Firmware"
|
||||
/* 0x05 VPD data block */
|
||||
BNX_DIR_TYPE_VPD = 5,
|
||||
#define BNX_DIR_NAME_VPD "VPD"
|
||||
#define BNX_DIR_DESC_VPD "Vital Product Data"
|
||||
/* 0x06 Exp ROM MBA */
|
||||
BNX_DIR_TYPE_EXP_ROM_MBA = 6,
|
||||
#define BNX_DIR_NAME_EXP_ROM_MBA "MBA"
|
||||
#define BNX_DIR_DESC_EXP_ROM_MBA "Multiple Boot Agent Expansion ROM"
|
||||
BNX_DIR_TYPE_AVS = 7, /* 0x07 AVS FW */
|
||||
#define BNX_DIR_NAME_AVS "AVS"
|
||||
#define BNX_DIR_DESC_AVS "Adaptive Voltage Scaling Firmware"
|
||||
BNX_DIR_TYPE_PCIE = 8, /* 0x08 PCIE FW */
|
||||
#define BNX_DIR_NAME_PCIE "PCIEucode"
|
||||
#define BNX_DIR_DESC_PCIE "PCIe Microcode"
|
||||
BNX_DIR_TYPE_PORT_MACRO = 9, /* 0x09 PORT MACRO FW */
|
||||
#define BNX_DIR_NAME_PORT_MACRO "portMacro"
|
||||
#define BNX_DIR_DESC_PORT_MACRO "Port Macro Firmware"
|
||||
BNX_DIR_TYPE_APE_FW = 10, /* 0x0A APE Firmware */
|
||||
#define BNX_DIR_NAME_APE_FW "apeFW"
|
||||
#define BNX_DIR_DESC_APE_FW "Application Processing Engine Firmware"
|
||||
/* 0x0B Patch firmware executed by APE ROM */
|
||||
BNX_DIR_TYPE_APE_PATCH = 11,
|
||||
#define BNX_DIR_NAME_APE_PATCH "apePatch"
|
||||
#define BNX_DIR_DESC_APE_PATCH "APE Patch Firmware"
|
||||
BNX_DIR_TYPE_KONG_FW = 12, /* 0x0C Kong Firmware */
|
||||
#define BNX_DIR_NAME_KONG_FW "kongFW"
|
||||
#define BNX_DIR_DESC_KONG_FW "Kong Firmware"
|
||||
/* 0x0D Patch firmware executed by Kong ROM */
|
||||
BNX_DIR_TYPE_KONG_PATCH = 13,
|
||||
#define BNX_DIR_NAME_KONG_PATCH "kongPatch"
|
||||
#define BNX_DIR_DESC_KONG_PATCH "Kong Patch Firmware"
|
||||
BNX_DIR_TYPE_BONO_FW = 14, /* 0x0E Bono Firmware */
|
||||
#define BNX_DIR_NAME_BONO_FW "bonoFW"
|
||||
#define BNX_DIR_DESC_BONO_FW "Bono Firmware"
|
||||
/* 0x0F Patch firmware executed by Bono ROM */
|
||||
BNX_DIR_TYPE_BONO_PATCH = 15,
|
||||
#define BNX_DIR_NAME_BONO_PATCH "bonoPatch"
|
||||
#define BNX_DIR_DESC_BONO_PATCH "Bono Patch Firmware"
|
||||
BNX_DIR_TYPE_TANG_FW = 16, /* 0x10 Tang firmware */
|
||||
#define BNX_DIR_NAME_TANG_FW "tangFW"
|
||||
#define BNX_DIR_DESC_TANG_FW "Tang Firmware"
|
||||
/* 0x11 Patch firmware executed by Tang ROM */
|
||||
BNX_DIR_TYPE_TANG_PATCH = 17,
|
||||
#define BNX_DIR_NAME_TANG_PATCH "tangPatch"
|
||||
#define BNX_DIR_DESC_TANG_PATCH "Tang Patch Firmware"
|
||||
/* 0x12 ChiMP firmware: Boot Code phase 2 (loaded by phase 1) */
|
||||
BNX_DIR_TYPE_BOOTCODE_2 = 18,
|
||||
#define BNX_DIR_NAME_BOOTCODE_2 "chimpHWRM"
|
||||
#define BNX_DIR_DESC_BOOTCODE_2 "ChiMP Hardware Resource Manager Firmware"
|
||||
BNX_DIR_TYPE_CCM = 19, /* 0x13 CCM ROM binary */
|
||||
#define BNX_DIR_NAME_CCM "CCM"
|
||||
#define BNX_DIR_DESC_CCM "Comprehensive Configuration Management"
|
||||
/* 0x14 PCI-IDs, PCI-related configuration properties */
|
||||
BNX_DIR_TYPE_PCI_CFG = 20,
|
||||
#define BNX_DIR_NAME_PCI_CFG "pciCFG"
|
||||
#define BNX_DIR_DESC_PCI_CFG "PCIe Configuration Data"
|
||||
|
||||
BNX_DIR_TYPE_TSCF_UCODE = 21, /* 0x15 TSCF micro-code */
|
||||
#define BNX_DIR_NAME_TSCF_UCODE "PHYucode"
|
||||
#define BNX_DIR_DESC_TSCF_UCODE "Falcon PHY Microcode"
|
||||
BNX_DIR_TYPE_ISCSI_BOOT = 22, /* 0x16 iSCSI Boot */
|
||||
#define BNX_DIR_NAME_ISCSI_BOOT "iSCSIboot"
|
||||
#define BNX_DIR_DESC_ISCSI_BOOT "iSCSI Boot Software Initiator"
|
||||
/* 0x18 iSCSI Boot IPV6 - ***DEPRECATED*** */
|
||||
BNX_DIR_TYPE_ISCSI_BOOT_IPV6 = 24,
|
||||
/* 0x19 iSCSI Boot IPV4N6 - ***DEPRECATED*** */
|
||||
BNX_DIR_TYPE_ISCSI_BOOT_IPV4N6 = 25,
|
||||
BNX_DIR_TYPE_ISCSI_BOOT_CFG = 26, /* 0x1a iSCSI Boot CFG v6 */
|
||||
#define BNX_DIR_NAME_ISCSI_BOOT_CFG "iSCSIcfg"
|
||||
#define BNX_DIR_DESC_ISCSI_BOOT_CFG "iSCSI Boot Configuration Data"
|
||||
BNX_DIR_TYPE_EXT_PHY = 27, /* 0x1b External PHY FW */
|
||||
#define BNX_DIR_NAME_EXT_PHY "extPHYfw"
|
||||
#define BNX_DIR_DESC_EXT_PHY "External PHY Firmware"
|
||||
BNX_DIR_TYPE_MODULES_PN = 28, /* 0x1c Modules PartNum list */
|
||||
#define BNX_DIR_NAME_MODULES_PN "modPartNums"
|
||||
#define BNX_DIR_DESC_MODULES_PN "Optical Modules Part Number List"
|
||||
BNX_DIR_TYPE_SHARED_CFG = 40, /* 0x28 shared configuration block */
|
||||
#define BNX_DIR_NAME_SHARED_CFG "sharedCFG"
|
||||
#define BNX_DIR_DESC_SHARED_CFG "Shared Configuration Data"
|
||||
BNX_DIR_TYPE_PORT_CFG = 41, /* 0x29 port configuration block */
|
||||
#define BNX_DIR_NAME_PORT_CFG "portCFG"
|
||||
#define BNX_DIR_DESC_PORT_CFG "Port Configuration Data"
|
||||
BNX_DIR_TYPE_FUNC_CFG = 42, /* 0x2A func configuration block */
|
||||
#define BNX_DIR_NAME_FUNC_CFG "funcCFG"
|
||||
#define BNX_DIR_DESC_FUNC_CFG "Function Configuration Data"
|
||||
|
||||
/* Management Firmware (TruManage) related dir entries*/
|
||||
/* 0x30 Management firmware configuration (see BMCFG library)*/
|
||||
BNX_DIR_TYPE_MGMT_CFG = 48,
|
||||
#define BNX_DIR_NAME_MGMT_CFG "mgmtCFG"
|
||||
#define BNX_DIR_DESC_MGMT_CFG "Out-of-band Management Configuration Data"
|
||||
BNX_DIR_TYPE_MGMT_DATA = 49, /* 0x31 "Opaque Management Data" */
|
||||
#define BNX_DIR_NAME_MGMT_DATA "mgmtData"
|
||||
#define BNX_DIR_DESC_MGMT_DATA "Out-of-band Management Data"
|
||||
BNX_DIR_TYPE_MGMT_WEB_DATA = 50, /* 0x32 "Web GUI" file data */
|
||||
#define BNX_DIR_NAME_MGMT_WEB_DATA "webData"
|
||||
#define BNX_DIR_DESC_MGMT_WEB_DATA "Out-of-band Management Web Data"
|
||||
/* 0x33 "Web GUI" file metadata */
|
||||
BNX_DIR_TYPE_MGMT_WEB_META = 51,
|
||||
#define BNX_DIR_NAME_MGMT_WEB_META "webMeta"
|
||||
#define BNX_DIR_DESC_MGMT_WEB_META "Out-of-band Management Web Metadata"
|
||||
/* 0x34 Management firmware Event Log (a.k.a. "SEL") */
|
||||
BNX_DIR_TYPE_MGMT_EVENT_LOG = 52,
|
||||
#define BNX_DIR_NAME_MGMT_EVENT_LOG "eventLog"
|
||||
#define BNX_DIR_DESC_MGMT_EVENT_LOG "Out-of-band Management Event Log"
|
||||
/* 0x35 Management firmware Audit Log */
|
||||
BNX_DIR_TYPE_MGMT_AUDIT_LOG = 53
|
||||
#define BNX_DIR_NAME_MGMT_AUDIT_LOG "auditLog"
|
||||
#define BNX_DIR_DESC_MGMT_AUDIT_LOG "Out-of-band Management Audit Log"
|
||||
|
||||
};
|
||||
|
||||
/* For backwards compatibility only, may be removed later */
|
||||
#define BNX_DIR_TYPE_ISCSI_BOOT_CFG6 BNX_DIR_TYPE_ISCSI_BOOT_CFG
|
||||
|
||||
/* Firmware NVM items of "APE BIN" format are identified with
|
||||
* the following macro:
|
||||
*/
|
||||
#define BNX_DIR_TYPE_IS_APE_BIN_FMT(type)\
|
||||
((type) == BNX_DIR_TYPE_CHIMP_PATCH \
|
||||
|| (type) == BNX_DIR_TYPE_BOOTCODE \
|
||||
|| (type) == BNX_DIR_TYPE_BOOTCODE_2 \
|
||||
|| (type) == BNX_DIR_TYPE_APE_FW \
|
||||
|| (type) == BNX_DIR_TYPE_APE_PATCH \
|
||||
|| (type) == BNX_DIR_TYPE_TANG_FW \
|
||||
|| (type) == BNX_DIR_TYPE_TANG_PATCH \
|
||||
|| (type) == BNX_DIR_TYPE_KONG_FW \
|
||||
|| (type) == BNX_DIR_TYPE_KONG_PATCH \
|
||||
|| (type) == BNX_DIR_TYPE_BONO_FW \
|
||||
|| (type) == BNX_DIR_TYPE_BONO_PATCH \
|
||||
)
|
||||
|
||||
/* Other (non APE BIN) executable NVM items are identified with
|
||||
* the following macro:
|
||||
*/
|
||||
#define BNX_DIR_TYPE_IS_OTHER_EXEC(type)\
|
||||
((type) == BNX_DIR_TYPE_AVS \
|
||||
|| (type) == BNX_DIR_TYPE_EXP_ROM_MBA \
|
||||
|| (type) == BNX_DIR_TYPE_PCIE \
|
||||
|| (type) == BNX_DIR_TYPE_TSCF_UCODE \
|
||||
|| (type) == BNX_DIR_TYPE_EXT_PHY \
|
||||
|| (type) == BNX_DIR_TYPE_CCM \
|
||||
|| (type) == BNX_DIR_TYPE_ISCSI_BOOT \
|
||||
)
|
||||
|
||||
/* Executable NVM items (e.g. microcode, firmware, software) identified
|
||||
* with the following macro
|
||||
*/
|
||||
#define BNX_DIR_TYPE_IS_EXECUTABLE(type) \
|
||||
(BNX_DIR_TYPE_IS_APE_BIN_FMT(type) \
|
||||
|| BNX_DIR_TYPE_IS_OTHER_EXEC(type))
|
||||
|
||||
#define BNX_DIR_ORDINAL_FIRST 0 /* Ordinals are 0-based */
|
||||
|
||||
/* No extension flags for this directory entry */
|
||||
#define BNX_DIR_EXT_NONE 0
|
||||
/* Directory entry is inactive (not used, not hidden,
|
||||
* not available for reuse)
|
||||
*/
|
||||
#define BNX_DIR_EXT_INACTIVE (1 << 0)
|
||||
/* Directory content is a temporary staging location for
|
||||
* updating the primary (non-update) directory entry contents
|
||||
* (e.g. performing a secure firmware update)
|
||||
*/
|
||||
#define BNX_DIR_EXT_UPDATE (1 << 1)
|
||||
|
||||
/* No attribute flags set for this directory entry */
|
||||
#define BNX_DIR_ATTR_NONE 0
|
||||
/* Directory entry checksum of contents is purposely incorrect */
|
||||
#define BNX_DIR_ATTR_NO_CHKSUM (1 << 0)
|
||||
/* Directory contents are in the form of a property-stream
|
||||
* (e.g. configuration properties)
|
||||
*/
|
||||
#define BNX_DIR_ATTR_PROP_STREAM (1 << 1)
|
||||
/* Directory content (e.g. iSCSI boot) supports IPv4 */
|
||||
#define BNX_DIR_ATTR_IPv4 (1 << 2)
|
||||
/* Directory content (e.g. iSCSI boot) supports IPv6 */
|
||||
#define BNX_DIR_ATTR_IPv6 (1 << 3)
|
||||
/* Directory content includes standard NVM component trailer
|
||||
* (bnxnvm_component_trailer_t)
|
||||
*/
|
||||
#define BNX_DIR_ATTR_TRAILER (1 << 4)
|
||||
|
||||
/* Index of tab-delimited fields in each package log
|
||||
* (BNX_DIR_TYPE_PKG_LOG) record (\n-terminated line):
|
||||
*/
|
||||
enum bnxnvm_pkglog_field_index {
|
||||
/* Package installation date/time in ISO-8601 format */
|
||||
BNX_PKG_LOG_FIELD_IDX_INSTALLED_TIMESTAMP = 0,
|
||||
/* Installed package description (from package header) or "N/A" */
|
||||
BNX_PKG_LOG_FIELD_IDX_PKG_DESCRIPTION = 1,
|
||||
/* Installed package version string (from package header) or "N/A" */
|
||||
BNX_PKG_LOG_FIELD_IDX_PKG_VERSION = 2,
|
||||
/* Installed package creation/modification timestamp (ISO-8601) */
|
||||
BNX_PKG_LOG_FIELD_IDX_PKG_TIMESTAMP = 3,
|
||||
/* Installed package checksum in hexadecimal (CRC-32) or "N/A" */
|
||||
BNX_PKG_LOG_FIELD_IDX_PKG_CHECKSUM = 4,
|
||||
/* Total number of packaged items applied in this installation */
|
||||
BNX_PKG_LOG_FIELD_IDX_INSTALLED_ITEMS = 5,
|
||||
/* Hexadecimal bit-mask identifying which items were installed */
|
||||
BNX_PKG_LOG_FIELD_IDX_INSTALLED_MASK = 6
|
||||
};
|
||||
|
||||
#if !defined(__GNUC__)
|
||||
#ifndef DOS_DRIVERS
|
||||
#pragma pack(pop) /* original packing */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* Don't add anything after this line */
|
@ -80,6 +80,10 @@ ifneq (${BL2_LOG_LEVEL},)
|
||||
$(eval $(call add_define,BL2_LOG_LEVEL))
|
||||
endif
|
||||
|
||||
ifneq (${BL31_LOG_LEVEL},)
|
||||
$(eval $(call add_define,BL31_LOG_LEVEL))
|
||||
endif
|
||||
|
||||
# Use CRMU SRAM from iHOST
|
||||
ifneq (${USE_CRMU_SRAM},)
|
||||
$(eval $(call add_define,USE_CRMU_SRAM))
|
||||
@ -123,6 +127,7 @@ BL31_SOURCES += plat/brcm/common/brcm_bl31_setup.c
|
||||
ifeq (${BCM_ELOG},yes)
|
||||
ELOG_SOURCES += plat/brcm/board/common/bcm_elog.c
|
||||
BL2_SOURCES += ${ELOG_SOURCES}
|
||||
BL31_SOURCES += ${ELOG_SOURCES}
|
||||
endif
|
||||
|
||||
ifeq (${DRIVER_OCOTP_ENABLE},1)
|
||||
|
38
plat/brcm/board/stingray/include/bl33_info.h
Normal file
38
plat/brcm/board/stingray/include/bl33_info.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef BL33_INFO_H
|
||||
#define BL33_INFO_H
|
||||
|
||||
/* Increase version number each time this file is modified */
|
||||
#define BL33_INFO_VERSION 4
|
||||
|
||||
struct chip_info {
|
||||
unsigned int chip_id;
|
||||
unsigned int rev_id;
|
||||
};
|
||||
|
||||
struct boot_time_info {
|
||||
unsigned int bl1_start;
|
||||
unsigned int bl1_end;
|
||||
unsigned int bl2_start;
|
||||
unsigned int bl2_end;
|
||||
unsigned int bl31_start;
|
||||
unsigned int bl31_end;
|
||||
unsigned int bl32_start;
|
||||
unsigned int bl32_end;
|
||||
unsigned int bl33_start;
|
||||
unsigned int bl33_prompt;
|
||||
unsigned int bl33_end;
|
||||
};
|
||||
|
||||
struct bl33_info {
|
||||
unsigned int version;
|
||||
struct chip_info chip;
|
||||
struct boot_time_info boot_time_info;
|
||||
};
|
||||
|
||||
#endif
|
37
plat/brcm/board/stingray/include/fsx.h
Normal file
37
plat/brcm/board/stingray/include/fsx.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2017 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef FSX_H
|
||||
#define FSX_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef enum FSX_TYPE {
|
||||
eFS4_RAID,
|
||||
eFS4_CRYPTO,
|
||||
eFS6_PKI,
|
||||
} eFSX_TYPE;
|
||||
|
||||
void fsx_init(eFSX_TYPE fsx_type,
|
||||
unsigned int ring_count,
|
||||
unsigned int dme_count,
|
||||
unsigned int ae_count,
|
||||
unsigned int start_stream_id,
|
||||
unsigned int msi_dev_id,
|
||||
uintptr_t idm_io_control_direct,
|
||||
uintptr_t idm_reset_control,
|
||||
uintptr_t base,
|
||||
uintptr_t dme_base);
|
||||
|
||||
void fsx_meminit(const char *name,
|
||||
uintptr_t idm_io_control_direct,
|
||||
uintptr_t idm_io_status);
|
||||
|
||||
void fs4_disable_clocks(bool disable_sram,
|
||||
bool disable_crypto,
|
||||
bool disable_raid);
|
||||
|
||||
#endif /* FSX_H */
|
19
plat/brcm/board/stingray/include/iommu.h
Normal file
19
plat/brcm/board/stingray/include/iommu.h
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2016 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef IOMMU_H
|
||||
#define IOMMU_H
|
||||
|
||||
enum iommu_domain {
|
||||
PCIE_PAXC,
|
||||
DOMAIN_CRMU,
|
||||
};
|
||||
|
||||
void arm_smmu_create_identity_map(enum iommu_domain dom);
|
||||
void arm_smmu_reserve_secure_cntxt(void);
|
||||
void arm_smmu_enable_secure_client_port(void);
|
||||
|
||||
#endif /* IOMMU_H */
|
32
plat/brcm/board/stingray/include/ncsi.h
Normal file
32
plat/brcm/board/stingray/include/ncsi.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef NCSI_H
|
||||
#define NCSI_H
|
||||
|
||||
/*
|
||||
* There are 10 registers for NCSI IO drivers.
|
||||
*/
|
||||
#define NITRO_NCSI_IOPAD_CONTROL_NUM 10
|
||||
#define NITRO_NCSI_IOPAD_CONTROL_BASE 0x60e05080
|
||||
|
||||
/*
|
||||
* NCSI IO Drive strength
|
||||
* 000 - Drives 2mA
|
||||
* 001 - Drives 4mA
|
||||
* 010 - Drives 6mA
|
||||
* 011 - Drives 8mA
|
||||
* 100 - Drives 10mA
|
||||
* 101 - Drives 12mA
|
||||
* 110 - Drives 14mA
|
||||
* 111 - Drives 16mA
|
||||
*/
|
||||
#define PAD_SELX_VALUE(selx) ((selx) << 1)
|
||||
#define PAD_SELX_MASK (0x7 << 1)
|
||||
|
||||
void brcm_stingray_ncsi_init(void);
|
||||
|
||||
#endif
|
74
plat/brcm/board/stingray/include/paxb.h
Normal file
74
plat/brcm/board/stingray/include/paxb.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2016 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PAXB_H
|
||||
#define PAXB_H
|
||||
|
||||
/* total number of PCIe cores */
|
||||
#define NUM_OF_SR_PCIE_CORES 8
|
||||
#define NUM_OF_NS3Z_PCIE_CORES 1
|
||||
|
||||
/*
|
||||
* List of PCIe core and PAXB wrapper memory power registers
|
||||
*/
|
||||
#define PCIE_CORE_BASE 0x40000800
|
||||
#define PCIE_CORE_SOFT_RST_CFG_BASE (PCIE_CORE_BASE + 0x40)
|
||||
#define PCIE_CORE_SOFT_RST 0x1
|
||||
#define PCIE_CORE_ISO_CFG_BASE (PCIE_CORE_BASE + 0x54)
|
||||
#define PCIE_CORE_MEM_ISO 0x2
|
||||
#define PCIE_CORE_ISO 0x1
|
||||
|
||||
#define PCIE_CORE_MEM_PWR_BASE (PCIE_CORE_BASE + 0x58)
|
||||
#define PCIE_PAXB_MEM_PWR_BASE (PCIE_CORE_BASE + 0x5c)
|
||||
#define PCIE_CORE_PMI_CFG_BASE (PCIE_CORE_BASE + 0x64)
|
||||
#define PCIE_CORE_RESERVED_CFG (PCIE_CORE_BASE + 0x6c)
|
||||
#define PCIE_CORE_MEM_PWR_STATUS_BASE (PCIE_CORE_BASE + 0x74)
|
||||
#define PCIE_PAXB_MEM_PWR_STATUS_BASE (PCIE_CORE_BASE + 0x78)
|
||||
#define PCIE_CORE_PWR_OFFSET 0x100
|
||||
|
||||
#define SR_A0_DEVICE_ID 0xd713
|
||||
#define SR_B0_DEVICE_ID 0xd714
|
||||
/* TODO: Modify device ID once available */
|
||||
#define NS3Z_DEVICE_ID 0xd715
|
||||
|
||||
/* FIXME: change link speed to GEN3 when it's ready */
|
||||
#define GEN1_LINK_SPEED 1
|
||||
#define GEN2_LINK_SPEED 2
|
||||
#define GEN3_LINK_SPEED 3
|
||||
|
||||
typedef struct {
|
||||
uint32_t type;
|
||||
uint32_t device_id;
|
||||
uint32_t pipemux_idx;
|
||||
uint32_t num_cores;
|
||||
int (*pipemux_init)(void);
|
||||
int (*phy_init)(void);
|
||||
int (*core_needs_enable)(unsigned int core_idx);
|
||||
unsigned int (*get_link_width)(unsigned int core_idx);
|
||||
unsigned int (*get_link_speed)(void);
|
||||
} paxb_cfg;
|
||||
|
||||
enum paxb_type {
|
||||
PAXB_SR,
|
||||
PAXB_NS3Z,
|
||||
};
|
||||
|
||||
extern const paxb_cfg *paxb;
|
||||
|
||||
#ifdef USE_PAXB
|
||||
void paxb_init(void);
|
||||
void paxb_rc_cfg_write(unsigned int core_idx, unsigned int where,
|
||||
uint32_t val);
|
||||
unsigned int paxb_rc_cfg_read(unsigned int core_idx, unsigned int where);
|
||||
int pcie_core_needs_enable(unsigned int core_idx);
|
||||
const paxb_cfg *paxb_get_sr_config(void);
|
||||
#else
|
||||
static inline void paxb_init(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PAXB_H */
|
23
plat/brcm/board/stingray/include/paxc.h
Normal file
23
plat/brcm/board/stingray/include/paxc.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2017 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PAXC_H
|
||||
#define PAXC_H
|
||||
|
||||
#ifdef USE_PAXC
|
||||
void paxc_init(void);
|
||||
void paxc_mhb_ns_init(void);
|
||||
#else
|
||||
static inline void paxc_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void paxc_mhb_ns_init(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PAXC_H */
|
247
plat/brcm/board/stingray/include/sdio.h
Normal file
247
plat/brcm/board/stingray/include/sdio.h
Normal file
@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef SDIO_H
|
||||
#define SDIO_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define SR_IPROC_SDIO0_CFG_BASE 0x689006e4
|
||||
#define SR_IPROC_SDIO0_SID_BASE 0x68900b00
|
||||
#define SR_IPROC_SDIO0_PAD_BASE 0x68a4017c
|
||||
#define SR_IPROC_SDIO0_IOCTRL_BASE 0x68e02408
|
||||
|
||||
#define SR_IPROC_SDIO1_CFG_BASE 0x68900734
|
||||
#define SR_IPROC_SDIO1_SID_BASE 0x68900b08
|
||||
#define SR_IPROC_SDIO1_PAD_BASE 0x68a401b4
|
||||
#define SR_IPROC_SDIO1_IOCTRL_BASE 0x68e03408
|
||||
|
||||
#define NS3Z_IPROC_SDIO0_CFG_BASE 0x68a20540
|
||||
#define NS3Z_IPROC_SDIO0_SID_BASE 0x68900b00
|
||||
#define NS3Z_IPROC_SDIO0_TP_OUT_SEL 0x68a20308
|
||||
#define NS3Z_IPROC_SDIO0_PAD_BASE 0x68a20500
|
||||
#define NS3Z_IPROC_SDIO0_IOCTRL_BASE 0x68e02408
|
||||
|
||||
#define PHY_BYPASS BIT(14)
|
||||
#define LEGACY_EN BIT(31)
|
||||
#define PHY_DISABLE (LEGACY_EN | PHY_BYPASS)
|
||||
|
||||
#define NS3Z_IPROC_SDIO1_CFG_BASE 0x68a30540
|
||||
#define NS3Z_IPROC_SDIO1_SID_BASE 0x68900b08
|
||||
#define NS3Z_IPROC_SDIO1_PAD_BASE 0x68a30500
|
||||
#define NS3Z_IPROC_SDIO1_IOCTRL_BASE 0x68e03408
|
||||
|
||||
#define ICFG_SDIO_CAP0 0x10
|
||||
#define ICFG_SDIO_CAP1 0x14
|
||||
#define ICFG_SDIO_STRAPSTATUS_0 0x0
|
||||
#define ICFG_SDIO_STRAPSTATUS_1 0x4
|
||||
#define ICFG_SDIO_STRAPSTATUS_2 0x8
|
||||
#define ICFG_SDIO_STRAPSTATUS_3 0xc
|
||||
#define ICFG_SDIO_STRAPSTATUS_4 0x18
|
||||
|
||||
#define ICFG_SDIO_SID_ARADDR 0x0
|
||||
#define ICFG_SDIO_SID_AWADDR 0x4
|
||||
|
||||
#define ICFG_SDIOx_CAP0__SLOT_TYPE_MASK 0x3
|
||||
#define ICFG_SDIOx_CAP0__SLOT_TYPE_SHIFT 27
|
||||
#define ICFG_SDIOx_CAP0__INT_MODE_SHIFT 26
|
||||
#define ICFG_SDIOx_CAP0__SYS_BUS_64BIT_SHIFT 25
|
||||
#define ICFG_SDIOx_CAP0__VOLTAGE_1P8V_SHIFT 24
|
||||
#define ICFG_SDIOx_CAP0__VOLTAGE_3P0V_SHIFT 23
|
||||
#define ICFG_SDIOx_CAP0__VOLTAGE_3P3V_SHIFT 22
|
||||
#define ICFG_SDIOx_CAP0__SUSPEND_RESUME_SHIFT 21
|
||||
#define ICFG_SDIOx_CAP0__SDMA_SHIFT 20
|
||||
#define ICFG_SDIOx_CAP0__HIGH_SPEED_SHIFT 19
|
||||
#define ICFG_SDIOx_CAP0__ADMA2_SHIFT 18
|
||||
#define ICFG_SDIOx_CAP0__EXTENDED_MEDIA_SHIFT 17
|
||||
#define ICFG_SDIOx_CAP0__MAX_BLOCK_LEN_MASK 0x3
|
||||
#define ICFG_SDIOx_CAP0__MAX_BLOCK_LEN_SHIFT 15
|
||||
#define ICFG_SDIOx_CAP0__BASE_CLK_FREQ_MASK 0xff
|
||||
#define ICFG_SDIOx_CAP0__BASE_CLK_FREQ_SHIFT 7
|
||||
#define ICFG_SDIOx_CAP0__TIMEOUT_UNIT_SHIFT 6
|
||||
#define ICFG_SDIOx_CAP0__TIMEOUT_CLK_FREQ_MASK 0x3f
|
||||
#define ICFG_SDIOx_CAP0__TIMEOUT_CLK_FREQ_SHIFT 0
|
||||
|
||||
#define ICFG_SDIOx_CAP1__SPI_BLOCK_MODE_SHIFT 22
|
||||
#define ICFG_SDIOx_CAP1__SPI_MODE_SHIFT 21
|
||||
#define ICFG_SDIOx_CAP1__CLK_MULT_MASK 0xff
|
||||
#define ICFG_SDIOx_CAP1__CLK_MULT_SHIFT 13
|
||||
#define ICFG_SDIOx_CAP1__RETUNING_MODE_MASK 0x3
|
||||
#define ICFG_SDIOx_CAP1__RETUNING_MODE_SHIFT 11
|
||||
#define ICFG_SDIOx_CAP1__TUNE_SDR50_SHIFT 10
|
||||
#define ICFG_SDIOx_CAP1__TIME_RETUNE_MASK 0xf
|
||||
#define ICFG_SDIOx_CAP1__TIME_RETUNE_SHIFT 6
|
||||
#define ICFG_SDIOx_CAP1__DRIVER_D_SHIFT 5
|
||||
#define ICFG_SDIOx_CAP1__DRIVER_C_SHIFT 4
|
||||
#define ICFG_SDIOx_CAP1__DRIVER_A_SHIFT 3
|
||||
#define ICFG_SDIOx_CAP1__DDR50_SHIFT 2
|
||||
#define ICFG_SDIOx_CAP1__SDR104_SHIFT 1
|
||||
#define ICFG_SDIOx_CAP1__SDR50_SHIFT 0
|
||||
|
||||
#ifdef USE_DDR
|
||||
#define SDIO_DMA 1
|
||||
#else
|
||||
#define SDIO_DMA 0
|
||||
#endif
|
||||
|
||||
#define SDIO0_CAP0_CFG \
|
||||
(0x1 << ICFG_SDIOx_CAP0__SLOT_TYPE_SHIFT) \
|
||||
| (0x0 << ICFG_SDIOx_CAP0__INT_MODE_SHIFT) \
|
||||
| (0x0 << ICFG_SDIOx_CAP0__SYS_BUS_64BIT_SHIFT) \
|
||||
| (0x1 << ICFG_SDIOx_CAP0__VOLTAGE_1P8V_SHIFT) \
|
||||
| (0x1 << ICFG_SDIOx_CAP0__VOLTAGE_3P0V_SHIFT) \
|
||||
| (0x1 << ICFG_SDIOx_CAP0__VOLTAGE_3P3V_SHIFT) \
|
||||
| (0x1 << ICFG_SDIOx_CAP0__SUSPEND_RESUME_SHIFT) \
|
||||
| (SDIO_DMA << ICFG_SDIOx_CAP0__SDMA_SHIFT) \
|
||||
| (SDIO_DMA << ICFG_SDIOx_CAP0__ADMA2_SHIFT) \
|
||||
| (0x1 << ICFG_SDIOx_CAP0__HIGH_SPEED_SHIFT) \
|
||||
| (0x1 << ICFG_SDIOx_CAP0__EXTENDED_MEDIA_SHIFT) \
|
||||
| (0x2 << ICFG_SDIOx_CAP0__MAX_BLOCK_LEN_SHIFT) \
|
||||
| (0xc8 << ICFG_SDIOx_CAP0__BASE_CLK_FREQ_SHIFT) \
|
||||
| (0x1 << ICFG_SDIOx_CAP0__TIMEOUT_UNIT_SHIFT) \
|
||||
| (0x30 << ICFG_SDIOx_CAP0__TIMEOUT_CLK_FREQ_SHIFT)
|
||||
|
||||
#define SDIO0_CAP1_CFG \
|
||||
(0x1 << ICFG_SDIOx_CAP1__SPI_BLOCK_MODE_SHIFT)\
|
||||
| (0x1 << ICFG_SDIOx_CAP1__SPI_MODE_SHIFT)\
|
||||
| (0x0 << ICFG_SDIOx_CAP1__CLK_MULT_SHIFT)\
|
||||
| (0x2 << ICFG_SDIOx_CAP1__RETUNING_MODE_SHIFT)\
|
||||
| (0x1 << ICFG_SDIOx_CAP1__TUNE_SDR50_SHIFT)\
|
||||
| (0x0 << ICFG_SDIOx_CAP1__DRIVER_D_SHIFT)\
|
||||
| (0x0 << ICFG_SDIOx_CAP1__DRIVER_C_SHIFT)\
|
||||
| (0x1 << ICFG_SDIOx_CAP1__DRIVER_A_SHIFT)\
|
||||
| (0x1 << ICFG_SDIOx_CAP1__DDR50_SHIFT)\
|
||||
| (0x1 << ICFG_SDIOx_CAP1__SDR104_SHIFT)\
|
||||
| (0x1 << ICFG_SDIOx_CAP1__SDR50_SHIFT)
|
||||
|
||||
#define SDIO1_CAP0_CFG \
|
||||
(0x0 << ICFG_SDIOx_CAP0__SLOT_TYPE_SHIFT) \
|
||||
| (0x0 << ICFG_SDIOx_CAP0__INT_MODE_SHIFT) \
|
||||
| (0x0 << ICFG_SDIOx_CAP0__SYS_BUS_64BIT_SHIFT) \
|
||||
| (0x1 << ICFG_SDIOx_CAP0__VOLTAGE_1P8V_SHIFT) \
|
||||
| (0x1 << ICFG_SDIOx_CAP0__VOLTAGE_3P0V_SHIFT) \
|
||||
| (0x1 << ICFG_SDIOx_CAP0__VOLTAGE_3P3V_SHIFT) \
|
||||
| (0x1 << ICFG_SDIOx_CAP0__SUSPEND_RESUME_SHIFT) \
|
||||
| (SDIO_DMA << ICFG_SDIOx_CAP0__SDMA_SHIFT) \
|
||||
| (SDIO_DMA << ICFG_SDIOx_CAP0__ADMA2_SHIFT) \
|
||||
| (0x1 << ICFG_SDIOx_CAP0__HIGH_SPEED_SHIFT) \
|
||||
| (0x1 << ICFG_SDIOx_CAP0__EXTENDED_MEDIA_SHIFT) \
|
||||
| (0x2 << ICFG_SDIOx_CAP0__MAX_BLOCK_LEN_SHIFT) \
|
||||
| (0xc8 << ICFG_SDIOx_CAP0__BASE_CLK_FREQ_SHIFT) \
|
||||
| (0x1 << ICFG_SDIOx_CAP0__TIMEOUT_UNIT_SHIFT) \
|
||||
| (0x30 << ICFG_SDIOx_CAP0__TIMEOUT_CLK_FREQ_SHIFT)
|
||||
|
||||
#define SDIO1_CAP1_CFG \
|
||||
(0x1 << ICFG_SDIOx_CAP1__SPI_BLOCK_MODE_SHIFT)\
|
||||
| (0x1 << ICFG_SDIOx_CAP1__SPI_MODE_SHIFT)\
|
||||
| (0x0 << ICFG_SDIOx_CAP1__CLK_MULT_SHIFT)\
|
||||
| (0x2 << ICFG_SDIOx_CAP1__RETUNING_MODE_SHIFT)\
|
||||
| (0x1 << ICFG_SDIOx_CAP1__TUNE_SDR50_SHIFT)\
|
||||
| (0x0 << ICFG_SDIOx_CAP1__DRIVER_D_SHIFT)\
|
||||
| (0x0 << ICFG_SDIOx_CAP1__DRIVER_C_SHIFT)\
|
||||
| (0x1 << ICFG_SDIOx_CAP1__DRIVER_A_SHIFT)\
|
||||
| (0x1 << ICFG_SDIOx_CAP1__DDR50_SHIFT)\
|
||||
| (0x1 << ICFG_SDIOx_CAP1__SDR104_SHIFT)\
|
||||
| (0x1 << ICFG_SDIOx_CAP1__SDR50_SHIFT)
|
||||
|
||||
#define PAD_SDIO_CLK 0x4
|
||||
#define PAD_SDIO_DATA0 0x8
|
||||
#define PAD_SDIO_DATA1 0xc
|
||||
#define PAD_SDIO_DATA2 0x10
|
||||
#define PAD_SDIO_DATA3 0x14
|
||||
#define PAD_SDIO_DATA4 0x18
|
||||
#define PAD_SDIO_DATA5 0x1c
|
||||
#define PAD_SDIO_DATA6 0x20
|
||||
#define PAD_SDIO_DATA7 0x24
|
||||
#define PAD_SDIO_CMD 0x28
|
||||
|
||||
/* 12mA Drive strength*/
|
||||
#define PAD_SDIO_SELX (0x5 << 1)
|
||||
#define PAD_SDIO_SRC (1 << 0)
|
||||
#define PAD_SDIO_MASK (0xF << 0)
|
||||
#define PAD_SDIO_VALUE (PAD_SDIO_SELX | PAD_SDIO_SRC)
|
||||
|
||||
/*
|
||||
* SDIO_PRESETVAL0
|
||||
*
|
||||
* Each 13 Bit filed consists:
|
||||
* drivestrength - 12:11
|
||||
* clkgensel - b10
|
||||
* sdkclkfreqsel - 9:0
|
||||
* Field Bit(s) Description
|
||||
* ============================================================
|
||||
* SDR25_PRESET 25:13 Preset Value for SDR25
|
||||
* SDR50_PRESET 12:0 Preset Value for SDR50
|
||||
*/
|
||||
#define SDIO_PRESETVAL0 0x01005001
|
||||
|
||||
/*
|
||||
* SDIO_PRESETVAL1
|
||||
*
|
||||
* Each 13 Bit filed consists:
|
||||
* drivestrength - 12:11
|
||||
* clkgensel - b10
|
||||
* sdkclkfreqsel - 9:0
|
||||
* Field Bit(s) Description
|
||||
* ============================================================
|
||||
* SDR104_PRESET 25:13 Preset Value for SDR104
|
||||
* SDR12_PRESET 12:0 Preset Value for SDR12
|
||||
*/
|
||||
#define SDIO_PRESETVAL1 0x03000004
|
||||
|
||||
/*
|
||||
* SDIO_PRESETVAL2
|
||||
*
|
||||
* Each 13 Bit filed consists:
|
||||
* drivestrength - 12:11
|
||||
* clkgensel - b10
|
||||
* sdkclkfreqsel - 9:0
|
||||
* Field Bit(s) Description
|
||||
* ============================================================
|
||||
* HIGH_SPEED_PRESET 25:13 Preset Value for High Speed
|
||||
* INIT_PRESET 12:0 Preset Value for Initialization
|
||||
*/
|
||||
#define SDIO_PRESETVAL2 0x010040FA
|
||||
|
||||
/*
|
||||
* SDIO_PRESETVAL3
|
||||
*
|
||||
* Each 13 Bit filed consists:
|
||||
* drivestrength - 12:11
|
||||
* clkgensel - b10
|
||||
* sdkclkfreqsel - 9:0
|
||||
* Field Bit(s) Description
|
||||
* ============================================================
|
||||
* DDR50_PRESET 25:13 Preset Value for DDR50
|
||||
* DEFAULT_PRESET 12:0 Preset Value for Default Speed
|
||||
*/
|
||||
#define SDIO_PRESETVAL3 0x01004004
|
||||
|
||||
/*
|
||||
* SDIO_PRESETVAL4
|
||||
*
|
||||
* Field Bit(s) Description
|
||||
* ============================================================
|
||||
* FORCE_USE_IP_TUNE_CLK 30 Force use IP clock
|
||||
* TUNING_COUNT 29:24 Tuning count
|
||||
* OVERRIDE_1P8V 23:16
|
||||
* OVERRIDE_3P3V 15:8
|
||||
* OVERRIDE_3P0V 7:0
|
||||
*/
|
||||
#define SDIO_PRESETVAL4 0x20010101
|
||||
|
||||
#define SDIO_SID_SHIFT 5
|
||||
|
||||
typedef struct {
|
||||
uintptr_t cfg_base;
|
||||
uintptr_t sid_base;
|
||||
uintptr_t io_ctrl_base;
|
||||
uintptr_t pad_base;
|
||||
} SDIO_CFG;
|
||||
|
||||
void brcm_stingray_sdio_init(void);
|
||||
|
||||
#endif /* SDIO_H */
|
@ -27,8 +27,21 @@ $(eval $(call add_define,DRIVER_CC_ENABLE))
|
||||
# BL31 is in DRAM
|
||||
ARM_BL31_IN_DRAM := 1
|
||||
|
||||
ifneq (${USE_EMULATOR},yes)
|
||||
STINGRAY_EMULATION_SETUP := 0
|
||||
ifeq (${FASTBOOT_TYPE},)
|
||||
override FASTBOOT_TYPE := 0
|
||||
endif
|
||||
USE_PAXB := yes
|
||||
USE_PAXC := yes
|
||||
USE_CHIMP := yes
|
||||
endif
|
||||
|
||||
USE_CRMU_SRAM := yes
|
||||
|
||||
# Disable FS4 clocks - they can be reenabled when needed by linux
|
||||
FS4_DISABLE_CLOCK := yes
|
||||
|
||||
# Enable error logging by default for Stingray
|
||||
BCM_ELOG := yes
|
||||
|
||||
@ -53,6 +66,35 @@ ifeq (${BOARD_CFG},)
|
||||
BOARD_CFG := bcm958742k
|
||||
endif
|
||||
|
||||
# Use PAXB
|
||||
ifeq (${USE_PAXB},yes)
|
||||
$(info Using PAXB)
|
||||
$(eval $(call add_define,USE_PAXB))
|
||||
endif
|
||||
|
||||
# Use FS4
|
||||
ifeq (${USE_FS4},yes)
|
||||
$(info Using FS4)
|
||||
$(eval $(call add_define,USE_FS4))
|
||||
endif
|
||||
|
||||
# Use FS6
|
||||
ifeq (${USE_FS6},yes)
|
||||
$(info Using FS6)
|
||||
$(eval $(call add_define,USE_FS6))
|
||||
endif
|
||||
|
||||
# Disable FS4 clock
|
||||
ifeq (${FS4_DISABLE_CLOCK},yes)
|
||||
$(info Using FS4_DISABLE_CLOCK)
|
||||
$(eval $(call add_define,FS4_DISABLE_CLOCK))
|
||||
endif
|
||||
|
||||
ifneq (${NCSI_IO_DRIVE_STRENGTH_MA},)
|
||||
$(info Using NCSI_IO_DRIVE_STRENGTH_MA)
|
||||
$(eval $(call add_define,NCSI_IO_DRIVE_STRENGTH_MA))
|
||||
endif
|
||||
|
||||
# Use NAND
|
||||
ifeq (${USE_NAND},$(filter yes, ${USE_NAND}))
|
||||
$(info Using NAND)
|
||||
@ -71,6 +113,44 @@ RESET_TO_BL31 := 1
|
||||
$(info Using RESET_TO_BL31)
|
||||
endif
|
||||
|
||||
# BL31 force full frequency for all CPUs
|
||||
ifeq (${BL31_FORCE_CPU_FULL_FREQ},yes)
|
||||
$(info Using BL31_FORCE_CPU_FULL_FREQ)
|
||||
$(eval $(call add_define,BL31_FORCE_CPU_FULL_FREQ))
|
||||
endif
|
||||
|
||||
# Enable non-secure accesses to CCN registers
|
||||
ifeq (${BL31_CCN_NONSECURE},yes)
|
||||
$(info Using BL31_CCN_NONSECURE)
|
||||
$(eval $(call add_define,BL31_CCN_NONSECURE))
|
||||
endif
|
||||
|
||||
# Use ChiMP
|
||||
ifeq (${USE_CHIMP},yes)
|
||||
$(info Using ChiMP)
|
||||
$(eval $(call add_define,USE_CHIMP))
|
||||
endif
|
||||
|
||||
# Use PAXC
|
||||
ifeq (${USE_PAXC},yes)
|
||||
$(info Using PAXC)
|
||||
$(eval $(call add_define,USE_PAXC))
|
||||
ifeq (${CHIMPFW_USE_SIDELOAD},yes)
|
||||
$(info Using ChiMP FW sideload)
|
||||
$(eval $(call add_define,CHIMPFW_USE_SIDELOAD))
|
||||
endif
|
||||
$(eval $(call add_define,FASTBOOT_TYPE))
|
||||
$(eval $(call add_define,CHIMP_FB1_ENTRY))
|
||||
endif
|
||||
|
||||
ifeq (${DEFAULT_SWREG_CONFIG}, 1)
|
||||
$(eval $(call add_define,DEFAULT_SWREG_CONFIG))
|
||||
endif
|
||||
|
||||
ifeq (${CHIMP_ALWAYS_NEEDS_QSPI},yes)
|
||||
$(eval $(call add_define,CHIMP_ALWAYS_NEEDS_QSPI))
|
||||
endif
|
||||
|
||||
# For testing purposes, use memsys stubs. Remove once memsys is fully tested.
|
||||
USE_MEMSYS_STUBS := yes
|
||||
|
||||
@ -100,6 +180,10 @@ PLAT_BL_COMMON_SOURCES += lib/cpus/aarch64/cortex_a72.S \
|
||||
drivers/arm/tzc/tzc400.c \
|
||||
plat/${SOC_DIR}/src/topology.c
|
||||
|
||||
ifeq (${USE_CHIMP},yes)
|
||||
PLAT_BL_COMMON_SOURCES += drivers/brcm/chimp.c
|
||||
endif
|
||||
|
||||
BL2_SOURCES += plat/${SOC_DIR}/driver/ihost_pll_config.c \
|
||||
plat/${SOC_DIR}/src/bl2_setup.c \
|
||||
plat/${SOC_DIR}/driver/swreg.c
|
||||
@ -125,8 +209,25 @@ BL31_SOURCES += \
|
||||
plat/brcm/common/brcm_ccn.c \
|
||||
plat/common/plat_psci_common.c \
|
||||
plat/${SOC_DIR}/driver/ihost_pll_config.c \
|
||||
plat/${SOC_DIR}/src/bl31_setup.c \
|
||||
plat/${SOC_DIR}/src/fsx.c \
|
||||
plat/${SOC_DIR}/src/iommu.c \
|
||||
plat/${SOC_DIR}/src/sdio.c \
|
||||
${BRCM_GIC_SOURCES}
|
||||
|
||||
ifneq (${NCSI_IO_DRIVE_STRENGTH_MA},)
|
||||
BL31_SOURCES += plat/${SOC_DIR}/src/ncsi.c
|
||||
endif
|
||||
|
||||
ifeq (${USE_PAXB},yes)
|
||||
BL31_SOURCES += plat/${SOC_DIR}/src/paxb.c
|
||||
BL31_SOURCES += plat/${SOC_DIR}/src/sr_paxb_phy.c
|
||||
endif
|
||||
|
||||
ifeq (${USE_PAXC},yes)
|
||||
BL31_SOURCES += plat/${SOC_DIR}/src/paxc.c
|
||||
endif
|
||||
|
||||
ifdef SCP_BL2
|
||||
PLAT_INCLUDES += -Iplat/brcm/common/
|
||||
|
||||
@ -150,6 +251,24 @@ BL2_SOURCES += plat/brcm/board/common/bcm_elog_ddr.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq (${BL31_BOOT_PRELOADED_SCP}, 1)
|
||||
ifdef SCP_BL2
|
||||
SCP_CFG_DIR=$(dir ${SCP_BL2})
|
||||
PLAT_INCLUDES += -I${SCP_CFG_DIR}
|
||||
endif
|
||||
PLAT_INCLUDES += -Iplat/brcm/common/
|
||||
|
||||
# By default use OPTEE Assigned memory
|
||||
PRELOADED_SCP_BASE ?= 0x8E000000
|
||||
PRELOADED_SCP_SIZE ?= 0x10000
|
||||
$(eval $(call add_define,PRELOADED_SCP_BASE))
|
||||
$(eval $(call add_define,PRELOADED_SCP_SIZE))
|
||||
$(eval $(call add_define,BL31_BOOT_PRELOADED_SCP))
|
||||
BL31_SOURCES += plat/${SOC_DIR}/src/scp_utils.c \
|
||||
plat/${SOC_DIR}/src/scp_cmd.c \
|
||||
drivers/brcm/scp.c
|
||||
endif
|
||||
|
||||
# Do not execute the startup code on warm reset.
|
||||
PROGRAMMABLE_RESET_ADDRESS := 1
|
||||
|
||||
|
1068
plat/brcm/board/stingray/src/bl31_setup.c
Normal file
1068
plat/brcm/board/stingray/src/bl31_setup.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -16,9 +16,11 @@
|
||||
#include <lib/spinlock.h>
|
||||
|
||||
#include <brcm_scpi.h>
|
||||
#include <chimp.h>
|
||||
#include <cmn_plat_util.h>
|
||||
#include <plat_brcm.h>
|
||||
#include <platform_def.h>
|
||||
#include <sr_utils.h>
|
||||
|
||||
#include "m0_cfg.h"
|
||||
|
||||
@ -280,7 +282,14 @@ static void __dead2 brcm_scp_sys_reset(unsigned int reset_type)
|
||||
|
||||
static void __dead2 brcm_system_reset(void)
|
||||
{
|
||||
brcm_scp_sys_reset(SOFT_SYS_RESET_L1);
|
||||
unsigned int reset_type;
|
||||
|
||||
if (bcm_chimp_is_nic_mode())
|
||||
reset_type = SOFT_RESET_L3;
|
||||
else
|
||||
reset_type = SOFT_SYS_RESET_L1;
|
||||
|
||||
brcm_scp_sys_reset(reset_type);
|
||||
}
|
||||
|
||||
static int brcm_system_reset2(int is_vendor, int reset_type,
|
||||
@ -289,6 +298,11 @@ static int brcm_system_reset2(int is_vendor, int reset_type,
|
||||
if (!is_vendor) {
|
||||
/* Architectural warm boot: only warm reset is supported */
|
||||
reset_type = SOFT_RESET_L3;
|
||||
} else {
|
||||
uint32_t boot_source = (uint32_t)cookie;
|
||||
|
||||
boot_source &= BOOT_SOURCE_MASK;
|
||||
brcm_stingray_set_straps(boot_source);
|
||||
}
|
||||
brcm_scp_sys_reset(reset_type);
|
||||
|
||||
|
477
plat/brcm/board/stingray/src/fsx.c
Normal file
477
plat/brcm/board/stingray/src/fsx.c
Normal file
@ -0,0 +1,477 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/console.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <plat/common/common_def.h>
|
||||
|
||||
#include <fsx.h>
|
||||
#include <platform_def.h>
|
||||
#include <sr_utils.h>
|
||||
|
||||
#define FS4_IDM_IO_CONTROL_DIRECT__SRAM_CLK_EN 0
|
||||
|
||||
#define FS4_IDM_IO_CONTROL_DIRECT__MEM_POWERON 11
|
||||
#define FS4_IDM_IO_CONTROL_DIRECT__MEM_POWEROK 12
|
||||
#define FS4_IDM_IO_CONTROL_DIRECT__MEM_ARRPOWERON 13
|
||||
#define FS4_IDM_IO_CONTROL_DIRECT__MEM_ARRPOWEROK 14
|
||||
#define FS4_IDM_IO_CONTROL_DIRECT__MEM_ISO 15
|
||||
#define FS4_IDM_IO_CONTROL_DIRECT__CLK_EN 31
|
||||
|
||||
#define FS4_IDM_IO_STATUS__MEM_POWERON 0
|
||||
#define FS4_IDM_IO_STATUS__MEM_POWEROK 1
|
||||
#define FS4_IDM_IO_STATUS__MEM_ARRPOWERON 2
|
||||
#define FS4_IDM_IO_STATUS__MEM_ARRPOWEROK 3
|
||||
#define FS4_IDM_IO_STATUS__MEM_ALLOK 0xf
|
||||
|
||||
#define FS4_IDM_RESET_CONTROL__RESET 0
|
||||
|
||||
#define FSX_RINGx_BASE(__b, __i) \
|
||||
((__b) + (__i) * 0x10000)
|
||||
|
||||
#define FSX_RINGx_VERSION_NUMBER(__b, __i) \
|
||||
(FSX_RINGx_BASE(__b, __i) + 0x0)
|
||||
|
||||
#define FSX_RINGx_MSI_DEV_ID(__b, __i) \
|
||||
(FSX_RINGx_BASE(__b, __i) + 0x44)
|
||||
|
||||
#define FSX_COMM_RINGx_BASE(__b, __i) \
|
||||
((__b) + 0x200000 + (__i) * 0x100)
|
||||
|
||||
#define FSX_COMM_RINGx_CONTROL(__b, __i) \
|
||||
(FSX_COMM_RINGx_BASE(__b, __i) + 0x0)
|
||||
#define FSX_COMM_RINGx_CONTROL__AXI_ID 8
|
||||
#define FSX_COMM_RINGx_CONTROL__AXI_ID_MASK 0x1f
|
||||
#define FSX_COMM_RINGx_CONTROL__PRIORITY 4
|
||||
#define FSX_COMM_RINGx_CONTROL__PRIORITY_MASK 0x7
|
||||
#define FSX_COMM_RINGx_CONTROL__AE_GROUP 0
|
||||
#define FSX_COMM_RINGx_CONTROL__AE_GROUP_MASK 0x7
|
||||
|
||||
#define FSX_COMM_RINGx_MSI_DEV_ID(__b, __i) \
|
||||
(FSX_COMM_RINGx_BASE(__b, __i) + 0x4)
|
||||
|
||||
#define FSX_AEx_BASE(__b, __i) \
|
||||
((__b) + 0x202000 + (__i) * 0x100)
|
||||
|
||||
#define FSX_AEx_CONTROL_REGISTER(__b, __i) \
|
||||
(FSX_AEx_BASE(__b, __i) + 0x0)
|
||||
#define FSX_AEx_CONTROL_REGISTER__ACTIVE 4
|
||||
#define FSX_AEx_CONTROL_REGISTER__GROUP_ID 0
|
||||
#define FSX_AEx_CONTROL_REGISTER__GROUP_ID_MASK 0x7
|
||||
|
||||
#define FSX_COMM_RM_RING_SECURITY_SETTING 0x0
|
||||
|
||||
#define FSX_COMM_RM_SSID_CONTROL 0x4
|
||||
#define FSX_COMM_RM_SSID_CONTROL__RING_BITS 5
|
||||
#define FSX_COMM_RM_SSID_CONTROL__MASK 0x3ff
|
||||
|
||||
#define FSX_COMM_RM_CONTROL_REGISTER 0x8
|
||||
#define FSX_COMM_RM_CONTROL_REGISTER__CONFIG_DONE 2
|
||||
#define FSX_COMM_RM_CONTROL_REGISTER__AE_TIMEOUT 5
|
||||
#define FSX_COMM_RM_CONTROL_REGISTER__AE_LOCKING 7
|
||||
|
||||
#define FSX_COMM_RM_TIMER_CONTROL_0 0xc
|
||||
#define FSX_COMM_RM_TIMER_CONTROL_0__FAST 16
|
||||
#define FSX_COMM_RM_TIMER_CONTROL_0__MEDIUM 0
|
||||
|
||||
#define FSX_COMM_RM_TIMER_CONTROL_1 0x10
|
||||
#define FSX_COMM_RM_TIMER_CONTROL_1__SLOW 16
|
||||
#define FSX_COMM_RM_TIMER_CONTROL_1__IDLE 0
|
||||
|
||||
#define FSX_COMM_RM_BURST_BD_THRESHOLD 0x14
|
||||
#define FSX_COMM_RM_BURST_BD_THRESHOLD_LOW 0
|
||||
#define FSX_COMM_RM_BURST_BD_THRESHOLD_HIGH 16
|
||||
|
||||
#define FSX_COMM_RM_BURST_LENGTH 0x18
|
||||
#define FSX_COMM_RM_BURST_LENGTH__FOR_DDR_ADDR_GEN 16
|
||||
#define FSX_COMM_RM_BURST_LENGTH__FOR_DDR_ADDR_GEN_MASK 0x1ff
|
||||
#define FSX_COMM_RM_BURST_LENGTH__FOR_TOGGLE 0
|
||||
#define FSX_COMM_RM_BURST_LENGTH__FOR_TOGGLE_MASK 0x1ff
|
||||
|
||||
#define FSX_COMM_RM_FIFO_THRESHOLD 0x1c
|
||||
#define FSX_COMM_RM_FIFO_THRESHOLD__BD_FIFO_FULL 16
|
||||
#define FSX_COMM_RM_FIFO_THRESHOLD__BD_FIFO_FULL_MASK 0x1ff
|
||||
#define FSX_COMM_RM_FIFO_THRESHOLD__AE_FIFO_FULL 0
|
||||
#define FSX_COMM_RM_FIFO_THRESHOLD__AE_FIFO_FULL_MASK 0x1f
|
||||
|
||||
#define FSX_COMM_RM_AE_TIMEOUT 0x24
|
||||
|
||||
#define FSX_COMM_RM_RING_FLUSH_TIMEOUT 0x2c
|
||||
|
||||
#define FSX_COMM_RM_MEMORY_CONFIGURATION 0x30
|
||||
#define FSX_COMM_RM_MEMORY_CONFIGURATION__ARRPOWERONIN 12
|
||||
#define FSX_COMM_RM_MEMORY_CONFIGURATION__ARRPOWEROKIN 13
|
||||
#define FSX_COMM_RM_MEMORY_CONFIGURATION__POWERONIN 14
|
||||
#define FSX_COMM_RM_MEMORY_CONFIGURATION__POWEROKIN 15
|
||||
|
||||
#define FSX_COMM_RM_AXI_CONTROL 0x34
|
||||
#define FSX_COMM_RM_AXI_CONTROL__WRITE_CHANNEL_EN 28
|
||||
#define FSX_COMM_RM_AXI_CONTROL__READ_CHANNEL_EN 24
|
||||
#define FSX_COMM_RM_AXI_CONTROL__AWQOS 20
|
||||
#define FSX_COMM_RM_AXI_CONTROL__ARQOS 16
|
||||
#define FSX_COMM_RM_AXI_CONTROL__AWPROT 12
|
||||
#define FSX_COMM_RM_AXI_CONTROL__ARPROT 8
|
||||
#define FSX_COMM_RM_AXI_CONTROL__AWCACHE 4
|
||||
#define FSX_COMM_RM_AXI_CONTROL__ARCACHE 0
|
||||
|
||||
#define FSX_COMM_RM_CONFIG_INTERRUPT_STATUS_CLEAR 0x48
|
||||
|
||||
#define FSX_COMM_RM_GROUP_PKT_EXTENSION_SUPPORT 0xc0
|
||||
|
||||
#define FSX_COMM_RM_AXI_READ_BURST_THRESHOLD 0xc8
|
||||
#define FSX_COMM_RM_AXI_READ_BURST_THRESHOLD__MASK 0x1ff
|
||||
#define FSX_COMM_RM_AXI_READ_BURST_THRESHOLD__MAX 16
|
||||
#define FSX_COMM_RM_AXI_READ_BURST_THRESHOLD__MIN 0
|
||||
|
||||
#define FSX_COMM_RM_GROUP_RING_COUNT 0xcc
|
||||
|
||||
#define FSX_COMM_RM_MAIN_HW_INIT_DONE 0x12c
|
||||
#define FSX_COMM_RM_MAIN_HW_INIT_DONE__MASK 0x1
|
||||
|
||||
#define FSX_DMEx_BASE(__b, __i) \
|
||||
((__b) + (__i) * 0x1000)
|
||||
|
||||
#define FSX_DMEx_AXI_CONTROL(__b, __i) \
|
||||
(FSX_DMEx_BASE(__b, __i) + 0x4)
|
||||
#define FSX_DMEx_AXI_CONTROL__WRITE_CHANNEL_EN 28
|
||||
#define FSX_DMEx_AXI_CONTROL__READ_CHANNEL_EN 24
|
||||
#define FSX_DMEx_AXI_CONTROL__AWQOS 20
|
||||
#define FSX_DMEx_AXI_CONTROL__ARQOS 16
|
||||
#define FSX_DMEx_AXI_CONTROL__AWCACHE 4
|
||||
#define FSX_DMEx_AXI_CONTROL__ARCACHE 0
|
||||
|
||||
#define FSX_DMEx_WR_FIFO_THRESHOLD(__b, __i) \
|
||||
(FSX_DMEx_BASE(__b, __i) + 0xc)
|
||||
#define FSX_DMEx_WR_FIFO_THRESHOLD__MASK 0x3ff
|
||||
#define FSX_DMEx_WR_FIFO_THRESHOLD__MAX 10
|
||||
#define FSX_DMEx_WR_FIFO_THRESHOLD__MIN 0
|
||||
|
||||
#define FSX_DMEx_RD_FIFO_THRESHOLD(__b, __i) \
|
||||
(FSX_DMEx_BASE(__b, __i) + 0x14)
|
||||
#define FSX_DMEx_RD_FIFO_THRESHOLD__MASK 0x3ff
|
||||
#define FSX_DMEx_RD_FIFO_THRESHOLD__MAX 10
|
||||
#define FSX_DMEx_RD_FIFO_THRESHOLD__MIN 0
|
||||
|
||||
#define FS6_SUB_TOP_BASE 0x66D8F800
|
||||
#define FS6_PKI_DME_RESET 0x4
|
||||
#define PKI_DME_RESET 1
|
||||
|
||||
char *fsx_type_names[] = {
|
||||
"fs4-raid",
|
||||
"fs4-crypto",
|
||||
"fs6-pki",
|
||||
};
|
||||
|
||||
void fsx_init(eFSX_TYPE fsx_type,
|
||||
unsigned int ring_count,
|
||||
unsigned int dme_count,
|
||||
unsigned int ae_count,
|
||||
unsigned int start_stream_id,
|
||||
unsigned int msi_dev_id,
|
||||
uintptr_t idm_io_control_direct,
|
||||
uintptr_t idm_reset_control,
|
||||
uintptr_t base,
|
||||
uintptr_t dme_base)
|
||||
{
|
||||
int try;
|
||||
unsigned int i, v, data;
|
||||
uintptr_t fs4_idm_io_control_direct = idm_io_control_direct;
|
||||
uintptr_t fs4_idm_reset_control = idm_reset_control;
|
||||
uintptr_t fsx_comm_rm = (base + 0x203000);
|
||||
|
||||
VERBOSE("fsx %s init start\n", fsx_type_names[fsx_type]);
|
||||
|
||||
if (fsx_type == eFS4_RAID || fsx_type == eFS4_CRYPTO) {
|
||||
/* Enable FSx engine clock */
|
||||
VERBOSE(" - enable fsx clock\n");
|
||||
mmio_write_32(fs4_idm_io_control_direct,
|
||||
(1U << FS4_IDM_IO_CONTROL_DIRECT__CLK_EN));
|
||||
udelay(500);
|
||||
|
||||
/* Reset FSx engine */
|
||||
VERBOSE(" - reset fsx\n");
|
||||
v = mmio_read_32(fs4_idm_reset_control);
|
||||
v |= (1 << FS4_IDM_RESET_CONTROL__RESET);
|
||||
mmio_write_32(fs4_idm_reset_control, v);
|
||||
udelay(500);
|
||||
v = mmio_read_32(fs4_idm_reset_control);
|
||||
v &= ~(1 << FS4_IDM_RESET_CONTROL__RESET);
|
||||
mmio_write_32(fs4_idm_reset_control, v);
|
||||
} else {
|
||||
/*
|
||||
* Default RM and AE are out of reset,
|
||||
* So only DME Reset added here
|
||||
*/
|
||||
v = mmio_read_32(FS6_SUB_TOP_BASE + FS6_PKI_DME_RESET);
|
||||
v &= ~(PKI_DME_RESET);
|
||||
mmio_write_32(FS6_SUB_TOP_BASE + FS6_PKI_DME_RESET, v);
|
||||
}
|
||||
|
||||
/* Wait for HW-init done */
|
||||
VERBOSE(" - wait for HW-init done\n");
|
||||
try = 10000;
|
||||
do {
|
||||
udelay(1);
|
||||
data = mmio_read_32(fsx_comm_rm +
|
||||
FSX_COMM_RM_MAIN_HW_INIT_DONE);
|
||||
try--;
|
||||
} while (!(data & FSX_COMM_RM_MAIN_HW_INIT_DONE__MASK) && (try > 0));
|
||||
|
||||
if (try <= 0)
|
||||
ERROR("fsx_comm_rm + 0x%x: 0x%x\n",
|
||||
data, FSX_COMM_RM_MAIN_HW_INIT_DONE);
|
||||
|
||||
/* Make all rings non-secured */
|
||||
VERBOSE(" - make all rings non-secured\n");
|
||||
v = 0xffffffff;
|
||||
mmio_write_32(fsx_comm_rm + FSX_COMM_RM_RING_SECURITY_SETTING, v);
|
||||
|
||||
/* Set start stream-id for rings to */
|
||||
VERBOSE(" - set start stream-id for rings to 0x%x\n",
|
||||
start_stream_id);
|
||||
v = start_stream_id >> FSX_COMM_RM_SSID_CONTROL__RING_BITS;
|
||||
v &= FSX_COMM_RM_SSID_CONTROL__MASK;
|
||||
mmio_write_32(fsx_comm_rm + FSX_COMM_RM_SSID_CONTROL, v);
|
||||
|
||||
/* Set timer configuration */
|
||||
VERBOSE(" - set timer configuration\n");
|
||||
v = 0x0271 << FSX_COMM_RM_TIMER_CONTROL_0__MEDIUM;
|
||||
v |= (0x0138 << FSX_COMM_RM_TIMER_CONTROL_0__FAST);
|
||||
mmio_write_32(fsx_comm_rm + FSX_COMM_RM_TIMER_CONTROL_0, v);
|
||||
v = 0x09c4 << FSX_COMM_RM_TIMER_CONTROL_1__IDLE;
|
||||
v |= (0x04e2 << FSX_COMM_RM_TIMER_CONTROL_1__SLOW);
|
||||
mmio_write_32(fsx_comm_rm + FSX_COMM_RM_TIMER_CONTROL_1, v);
|
||||
v = 0x0000f424;
|
||||
mmio_write_32(fsx_comm_rm + FSX_COMM_RM_RING_FLUSH_TIMEOUT, v);
|
||||
|
||||
/* Set burst length and fifo threshold */
|
||||
VERBOSE(" - set burst length, fifo and bd threshold\n");
|
||||
v = 0x0;
|
||||
v |= (0x8 << FSX_COMM_RM_BURST_LENGTH__FOR_DDR_ADDR_GEN);
|
||||
v |= (0x8 << FSX_COMM_RM_BURST_LENGTH__FOR_TOGGLE);
|
||||
mmio_write_32(fsx_comm_rm + FSX_COMM_RM_BURST_LENGTH, v);
|
||||
v = 0x0;
|
||||
v |= (0x67 << FSX_COMM_RM_FIFO_THRESHOLD__BD_FIFO_FULL);
|
||||
v |= (0x18 << FSX_COMM_RM_FIFO_THRESHOLD__AE_FIFO_FULL);
|
||||
mmio_write_32(fsx_comm_rm + FSX_COMM_RM_FIFO_THRESHOLD, v);
|
||||
v = 0x0;
|
||||
v |= (0x8 << FSX_COMM_RM_BURST_BD_THRESHOLD_LOW);
|
||||
v |= (0x8 << FSX_COMM_RM_BURST_BD_THRESHOLD_HIGH);
|
||||
mmio_write_32(fsx_comm_rm + FSX_COMM_RM_BURST_BD_THRESHOLD, v);
|
||||
|
||||
/* Set memory configuration */
|
||||
VERBOSE(" - set memory configuration\n");
|
||||
v = 0x0;
|
||||
v |= (1 << FSX_COMM_RM_MEMORY_CONFIGURATION__POWERONIN);
|
||||
v |= (1 << FSX_COMM_RM_MEMORY_CONFIGURATION__POWEROKIN);
|
||||
v |= (1 << FSX_COMM_RM_MEMORY_CONFIGURATION__ARRPOWERONIN);
|
||||
v |= (1 << FSX_COMM_RM_MEMORY_CONFIGURATION__ARRPOWEROKIN);
|
||||
mmio_write_32(fsx_comm_rm + FSX_COMM_RM_MEMORY_CONFIGURATION, v);
|
||||
|
||||
/* AXI configuration for RM */
|
||||
v = 0;
|
||||
v |= (0x1 << FSX_COMM_RM_AXI_CONTROL__WRITE_CHANNEL_EN);
|
||||
v |= (0x1 << FSX_COMM_RM_AXI_CONTROL__READ_CHANNEL_EN);
|
||||
v |= (0xe << FSX_COMM_RM_AXI_CONTROL__AWQOS);
|
||||
v |= (0xa << FSX_COMM_RM_AXI_CONTROL__ARQOS);
|
||||
v |= (0x2 << FSX_COMM_RM_AXI_CONTROL__AWPROT);
|
||||
v |= (0x2 << FSX_COMM_RM_AXI_CONTROL__ARPROT);
|
||||
v |= (0xf << FSX_COMM_RM_AXI_CONTROL__AWCACHE);
|
||||
v |= (0xf << FSX_COMM_RM_AXI_CONTROL__ARCACHE);
|
||||
mmio_write_32(fsx_comm_rm + FSX_COMM_RM_AXI_CONTROL, v);
|
||||
VERBOSE(" - set AXI control = 0x%x\n",
|
||||
mmio_read_32(fsx_comm_rm + FSX_COMM_RM_AXI_CONTROL));
|
||||
v = 0x0;
|
||||
v |= (0x10 << FSX_COMM_RM_AXI_READ_BURST_THRESHOLD__MAX);
|
||||
v |= (0x10 << FSX_COMM_RM_AXI_READ_BURST_THRESHOLD__MIN);
|
||||
mmio_write_32(fsx_comm_rm + FSX_COMM_RM_AXI_READ_BURST_THRESHOLD, v);
|
||||
VERBOSE(" - set AXI read burst threshold = 0x%x\n",
|
||||
mmio_read_32(fsx_comm_rm + FSX_COMM_RM_AXI_READ_BURST_THRESHOLD));
|
||||
|
||||
/* Configure group ring count for all groups */
|
||||
/* By default we schedule extended packets
|
||||
* on all AEs/DMEs in a group.
|
||||
*/
|
||||
v = (dme_count & 0xf) << 0;
|
||||
v |= (dme_count & 0xf) << 4;
|
||||
v |= (dme_count & 0xf) << 8;
|
||||
v |= (dme_count & 0xf) << 12;
|
||||
v |= (dme_count & 0xf) << 16;
|
||||
v |= (dme_count & 0xf) << 20;
|
||||
v |= (dme_count & 0xf) << 24;
|
||||
v |= (dme_count & 0xf) << 28;
|
||||
mmio_write_32(fsx_comm_rm + FSX_COMM_RM_GROUP_RING_COUNT, v);
|
||||
|
||||
/*
|
||||
* Due to HW issue spurious interrupts are getting generated.
|
||||
* To fix sw needs to clear the config status interrupts
|
||||
* before setting CONFIG_DONE.
|
||||
*/
|
||||
mmio_write_32(fsx_comm_rm +
|
||||
FSX_COMM_RM_CONFIG_INTERRUPT_STATUS_CLEAR,
|
||||
0xffffffff);
|
||||
|
||||
/* Configure RM control */
|
||||
VERBOSE(" - configure RM control\n");
|
||||
v = mmio_read_32(fsx_comm_rm + FSX_COMM_RM_CONTROL_REGISTER);
|
||||
v |= (1 << FSX_COMM_RM_CONTROL_REGISTER__AE_LOCKING);
|
||||
mmio_write_32(fsx_comm_rm + FSX_COMM_RM_CONTROL_REGISTER, v);
|
||||
v |= (1 << FSX_COMM_RM_CONTROL_REGISTER__CONFIG_DONE);
|
||||
mmio_write_32(fsx_comm_rm + FSX_COMM_RM_CONTROL_REGISTER, v);
|
||||
|
||||
/* Configure AE timeout */
|
||||
VERBOSE(" - configure AE timeout\n");
|
||||
v = 0x00003fff;
|
||||
mmio_write_32(fsx_comm_rm + FSX_COMM_RM_AE_TIMEOUT, v);
|
||||
|
||||
/* Initialize all AEs */
|
||||
for (i = 0; i < ae_count; i++) {
|
||||
VERBOSE(" - initialize AE%d\n", i);
|
||||
v = (0x1 << FSX_AEx_CONTROL_REGISTER__ACTIVE);
|
||||
mmio_write_32(FSX_AEx_CONTROL_REGISTER(base, i), v);
|
||||
}
|
||||
|
||||
/* Initialize all DMEs */
|
||||
for (i = 0; i < dme_count; i++) {
|
||||
VERBOSE(" - initialize DME%d\n", i);
|
||||
v = 0;
|
||||
v |= (0x1 << FSX_DMEx_AXI_CONTROL__WRITE_CHANNEL_EN);
|
||||
v |= (0x1 << FSX_DMEx_AXI_CONTROL__READ_CHANNEL_EN);
|
||||
v |= (0xe << FSX_DMEx_AXI_CONTROL__AWQOS);
|
||||
v |= (0xa << FSX_DMEx_AXI_CONTROL__ARQOS);
|
||||
v |= (0xf << FSX_DMEx_AXI_CONTROL__AWCACHE);
|
||||
v |= (0xf << FSX_DMEx_AXI_CONTROL__ARCACHE);
|
||||
mmio_write_32(FSX_DMEx_AXI_CONTROL(dme_base, i), v);
|
||||
VERBOSE(" -- AXI_CONTROL = 0x%x\n",
|
||||
mmio_read_32(FSX_DMEx_AXI_CONTROL(dme_base, i)));
|
||||
v = 0;
|
||||
v |= (0x4 << FSX_DMEx_WR_FIFO_THRESHOLD__MIN);
|
||||
v |= (0x4 << FSX_DMEx_WR_FIFO_THRESHOLD__MAX);
|
||||
mmio_write_32(FSX_DMEx_WR_FIFO_THRESHOLD(dme_base, i), v);
|
||||
VERBOSE(" -- WR_FIFO_THRESHOLD = 0x%x\n",
|
||||
mmio_read_32(FSX_DMEx_WR_FIFO_THRESHOLD(dme_base, i)));
|
||||
v = 0;
|
||||
v |= (0x4 << FSX_DMEx_RD_FIFO_THRESHOLD__MIN);
|
||||
v |= (0x4 << FSX_DMEx_RD_FIFO_THRESHOLD__MAX);
|
||||
mmio_write_32(FSX_DMEx_RD_FIFO_THRESHOLD(dme_base, i), v);
|
||||
VERBOSE(" -- RD_FIFO_THRESHOLD = 0x%x\n",
|
||||
mmio_read_32(FSX_DMEx_RD_FIFO_THRESHOLD(dme_base, i)));
|
||||
}
|
||||
|
||||
/* Configure ring axi id and msi device id */
|
||||
for (i = 0; i < ring_count; i++) {
|
||||
VERBOSE(" - ring%d version=0x%x\n", i,
|
||||
mmio_read_32(FSX_RINGx_VERSION_NUMBER(base, i)));
|
||||
mmio_write_32(FSX_COMM_RINGx_MSI_DEV_ID(base, i),
|
||||
msi_dev_id);
|
||||
v = 0;
|
||||
v |= ((i & FSX_COMM_RINGx_CONTROL__AXI_ID_MASK) <<
|
||||
FSX_COMM_RINGx_CONTROL__AXI_ID);
|
||||
mmio_write_32(FSX_COMM_RINGx_CONTROL(base, i), v);
|
||||
}
|
||||
|
||||
INFO("fsx %s init done\n", fsx_type_names[fsx_type]);
|
||||
}
|
||||
|
||||
void fsx_meminit(const char *name,
|
||||
uintptr_t idm_io_control_direct,
|
||||
uintptr_t idm_io_status)
|
||||
{
|
||||
int try;
|
||||
unsigned int val;
|
||||
|
||||
VERBOSE("fsx %s meminit start\n", name);
|
||||
|
||||
VERBOSE(" - arrpoweron\n");
|
||||
mmio_setbits_32(idm_io_control_direct,
|
||||
BIT(FS4_IDM_IO_CONTROL_DIRECT__MEM_ARRPOWERON));
|
||||
while (!(mmio_read_32(idm_io_status) &
|
||||
BIT(FS4_IDM_IO_STATUS__MEM_ARRPOWERON)))
|
||||
;
|
||||
|
||||
VERBOSE(" - arrpowerok\n");
|
||||
mmio_setbits_32(idm_io_control_direct,
|
||||
(1 << FS4_IDM_IO_CONTROL_DIRECT__MEM_ARRPOWEROK));
|
||||
while (!(mmio_read_32(idm_io_status) &
|
||||
BIT(FS4_IDM_IO_STATUS__MEM_ARRPOWEROK)))
|
||||
;
|
||||
|
||||
VERBOSE(" - poweron\n");
|
||||
mmio_setbits_32(idm_io_control_direct,
|
||||
(1 << FS4_IDM_IO_CONTROL_DIRECT__MEM_POWERON));
|
||||
while (!(mmio_read_32(idm_io_status) &
|
||||
BIT(FS4_IDM_IO_STATUS__MEM_POWERON)))
|
||||
;
|
||||
|
||||
VERBOSE(" - powerok\n");
|
||||
mmio_setbits_32(idm_io_control_direct,
|
||||
(1 << FS4_IDM_IO_CONTROL_DIRECT__MEM_POWEROK));
|
||||
while (!(mmio_read_32(idm_io_status) &
|
||||
BIT(FS4_IDM_IO_STATUS__MEM_POWEROK)))
|
||||
;
|
||||
|
||||
/* Final check on all power bits */
|
||||
try = 10;
|
||||
do {
|
||||
val = mmio_read_32(idm_io_status);
|
||||
if (val == FS4_IDM_IO_STATUS__MEM_ALLOK)
|
||||
break;
|
||||
|
||||
/* Wait sometime */
|
||||
mdelay(1);
|
||||
|
||||
try--;
|
||||
} while (try > 0);
|
||||
|
||||
/* Remove memory isolation if things are fine. */
|
||||
if (try <= 0) {
|
||||
INFO(" - powerup failed\n");
|
||||
} else {
|
||||
VERBOSE(" - remove isolation\n");
|
||||
mmio_clrbits_32(idm_io_control_direct,
|
||||
(1 << FS4_IDM_IO_CONTROL_DIRECT__MEM_ISO));
|
||||
VERBOSE(" - powerup done\n");
|
||||
}
|
||||
|
||||
INFO("fsx %s meminit done\n", name);
|
||||
}
|
||||
|
||||
void fs4_disable_clocks(bool disable_sram,
|
||||
bool disable_crypto,
|
||||
bool disable_raid)
|
||||
{
|
||||
VERBOSE("fs4 disable clocks start\n");
|
||||
|
||||
if (disable_sram) {
|
||||
VERBOSE(" - disable sram clock\n");
|
||||
mmio_clrbits_32(FS4_SRAM_IDM_IO_CONTROL_DIRECT,
|
||||
(1 << FS4_IDM_IO_CONTROL_DIRECT__SRAM_CLK_EN));
|
||||
}
|
||||
|
||||
if (disable_crypto) {
|
||||
VERBOSE(" - disable crypto clock\n");
|
||||
mmio_setbits_32(CDRU_GENPLL5_CONTROL1,
|
||||
CDRU_GENPLL5_CONTROL1__CHNL1_CRYPTO_AE_CLK);
|
||||
}
|
||||
|
||||
if (disable_raid) {
|
||||
VERBOSE(" - disable raid clock\n");
|
||||
mmio_setbits_32(CDRU_GENPLL5_CONTROL1,
|
||||
CDRU_GENPLL5_CONTROL1__CHNL2_RAID_AE_CLK);
|
||||
}
|
||||
|
||||
if (disable_sram && disable_crypto && disable_raid) {
|
||||
VERBOSE(" - disable root clock\n");
|
||||
mmio_setbits_32(CDRU_GENPLL5_CONTROL1,
|
||||
CDRU_GENPLL5_CONTROL1__CHNL0_DME_CLK);
|
||||
mmio_setbits_32(CDRU_GENPLL2_CONTROL1,
|
||||
CDRU_GENPLL2_CONTROL1__CHNL6_FS4_CLK);
|
||||
}
|
||||
|
||||
INFO("fs4 disable clocks done\n");
|
||||
}
|
536
plat/brcm/board/stingray/src/iommu.c
Normal file
536
plat/brcm/board/stingray/src/iommu.c
Normal file
@ -0,0 +1,536 @@
|
||||
/*
|
||||
* Copyright (c) 2017 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <iommu.h>
|
||||
#include <platform_def.h>
|
||||
|
||||
#define SMMU_BASE 0x64000000
|
||||
#define ARM_SMMU_MAX_NUM_CNTXT_BANK 64
|
||||
#define SMMU_CTX_BANK_IDX_SECURE_CRMU 63
|
||||
#define ARM_SMMU_NUM_SECURE_MASTER 1
|
||||
#define ARM_SMMU_NSNUMCBO (ARM_SMMU_MAX_NUM_CNTXT_BANK - \
|
||||
ARM_SMMU_NUM_SECURE_MASTER)
|
||||
#define ARM_SMMU_NSNUMSMRGO (ARM_SMMU_MAX_NUM_CNTXT_BANK - \
|
||||
ARM_SMMU_NUM_SECURE_MASTER)
|
||||
/* Reserved Banks. */
|
||||
#define SMMU_CTX_BANK_IDX (SMMU_CTX_BANK_IDX_SECURE_CRMU - \
|
||||
ARM_SMMU_NUM_SECURE_MASTER)
|
||||
#define NUM_OF_SMRS 1
|
||||
|
||||
#define STG1_WITH_STG2_BYPASS 1
|
||||
#define ARM_LPAE_PGTBL_PHYS_CRMU 0x880000000
|
||||
#define ARM_LPAE_PGTBL_PHYS 0x880200000
|
||||
#define ARM_LPAE_PGTBL_PTE_CNT 512
|
||||
#define ARM_LPAE_PTE_L1_BLOCK_SIZE 0x40000000
|
||||
#define ARM_LPAE_PTE_L1_ADDR_MASK 0x0000FFFFC0000000UL
|
||||
#define ARM_LPAE_PTE_TABLE 0x2UL
|
||||
#define ARM_LPAE_PTE_VALID 0x1UL
|
||||
#define ARM_LPAE_PTE_ATTRINDX 2
|
||||
#define ARM_LPAE_PTE_NS 5
|
||||
#define ARM_LPAE_PTE_AP 6
|
||||
#define ARM_LPAE_PTE_AP_EL1_RW 0x0
|
||||
#define ARM_LPAE_PTE_AP_EL0_RW 0x1
|
||||
#define ARM_LPAE_PTE_SH 8
|
||||
#define ARM_LPAE_PTE_SH_NON 0x0
|
||||
#define ARM_LPAE_PTE_SH_OUTER 0x2
|
||||
#define ARM_LPAE_PTE_SH_INNER 0x3
|
||||
#define ARM_LPAE_PTE_AF 10
|
||||
#define ARM_SMMU_RES_SIZE 0x80000
|
||||
|
||||
#define ARM_LPAE_PTE_NSTABLE 0x8000000000000000UL
|
||||
#define ARM_LPAE_PTE_L1_INDEX_SHIFT 30
|
||||
#define ARM_LPAE_PTE_L1_INDEX_MASK 0x1ff
|
||||
#define ARM_LPAE_PTE_L0_INDEX_SHIFT 39
|
||||
#define ARM_LPAE_PTE_L0_INDEX_MASK 0x1ff
|
||||
#define ARM_LPAE_PTE_TABLE_MASK ~(0xfffUL)
|
||||
/* Configuration registers */
|
||||
#define ARM_SMMU_GR0_sCR0 0x0
|
||||
#define sCR0_CLIENTPD (1 << 0)
|
||||
#define sCR0_GFRE (1 << 1)
|
||||
#define sCR0_GFIE (1 << 2)
|
||||
#define sCR0_GCFGFRE (1 << 4)
|
||||
#define sCR0_GCFGFIE (1 << 5)
|
||||
#define sCR0_USFCFG (1 << 10)
|
||||
#define sCR0_VMIDPNE (1 << 11)
|
||||
#define sCR0_PTM (1 << 12)
|
||||
#define sCR0_FB (1 << 13)
|
||||
#define sCR0_VMID16EN (1 << 31)
|
||||
#define sCR0_BSU_SHIFT 14
|
||||
#define sCR0_BSU_MASK 0x3
|
||||
#define ARM_SMMU_SMMU_SCR1 0x4
|
||||
#define SCR1_NSNUMCBO_MASK 0xFF
|
||||
#define SCR1_NSNUMCBO_SHIFT 0x0
|
||||
#define SCR1_NSNUMSMRGO_MASK 0xFF00
|
||||
#define SCR1_NSNUMSMRGO_SHIFT 0x8
|
||||
|
||||
/* Identification registers */
|
||||
#define ARM_SMMU_GR0_ID0 0x20
|
||||
#define ARM_SMMU_GR0_ID1 0x24
|
||||
#define ARM_SMMU_GR0_ID2 0x28
|
||||
#define ARM_SMMU_GR0_ID3 0x2c
|
||||
#define ARM_SMMU_GR0_ID4 0x30
|
||||
#define ARM_SMMU_GR0_ID5 0x34
|
||||
#define ARM_SMMU_GR0_ID6 0x38
|
||||
#define ARM_SMMU_GR0_ID7 0x3c
|
||||
#define ARM_SMMU_GR0_sGFSR 0x48
|
||||
#define ARM_SMMU_GR0_sGFSYNR0 0x50
|
||||
#define ARM_SMMU_GR0_sGFSYNR1 0x54
|
||||
#define ARM_SMMU_GR0_sGFSYNR2 0x58
|
||||
|
||||
#define ID1_PAGESIZE (1U << 31)
|
||||
#define ID1_NUMPAGENDXB_SHIFT 28
|
||||
#define ID1_NUMPAGENDXB_MASK 7
|
||||
#define ID1_NUMS2CB_SHIFT 16
|
||||
#define ID1_NUMS2CB_MASK 0xff
|
||||
#define ID1_NUMCB_SHIFT 0
|
||||
#define ID1_NUMCB_MASK 0xff
|
||||
|
||||
/* SMMU global address space */
|
||||
#define ARM_SMMU_GR0(smmu) ((smmu)->base)
|
||||
#define ARM_SMMU_GR1(smmu) ((smmu)->base + (1 << (smmu)->pgshift))
|
||||
|
||||
/* Stream mapping registers */
|
||||
#define ARM_SMMU_GR0_SMR(n) (0x800 + (n << 2))
|
||||
#define SMR_VALID (1U << 31)
|
||||
#define SMR_MASK_SHIFT 16
|
||||
#define SMR_ID_SHIFT 0
|
||||
|
||||
#define ARM_SMMU_GR0_S2CR(n) (0xc00 + (n << 2))
|
||||
#define S2CR_CBNDX_SHIFT 0
|
||||
#define S2CR_CBNDX_MASK 0xff
|
||||
#define S2CR_TYPE_SHIFT 16
|
||||
#define S2CR_TYPE_MASK 0x3
|
||||
|
||||
#define ARM_SMMU_GR1_CBA2R(n) (0x800 + (n << 2))
|
||||
#define CBA2R_RW64_32BIT (0 << 0)
|
||||
#define CBA2R_RW64_64BIT (1 << 0)
|
||||
#define CBA2R_VMID_SHIFT 16
|
||||
#define CBA2R_VMID_MASK 0xffff
|
||||
|
||||
#define ARM_SMMU_GR1_CBAR(n) (0x0 + (n << 2))
|
||||
#define CBAR_VMID_SHIFT 0
|
||||
#define CBAR_VMID_MASK 0xff
|
||||
#define CBAR_S1_BPSHCFG_SHIFT 8
|
||||
#define CBAR_S1_BPSHCFG_MASK 3
|
||||
#define CBAR_S1_BPSHCFG_NSH 3
|
||||
#define CBAR_S1_MEMATTR_SHIFT 12
|
||||
#define CBAR_S1_MEMATTR_MASK 0xf
|
||||
#define CBAR_S1_MEMATTR_WB 0xf
|
||||
#define CBAR_TYPE_SHIFT 16
|
||||
#define CBAR_TYPE_MASK 0x3
|
||||
#define CBAR_TYPE_S2_TRANS (0 << CBAR_TYPE_SHIFT)
|
||||
#define CBAR_TYPE_S1_TRANS_S2_BYPASS (1 << CBAR_TYPE_SHIFT)
|
||||
#define CBAR_TYPE_S1_TRANS_S2_FAULT (2 << CBAR_TYPE_SHIFT)
|
||||
#define CBAR_TYPE_S1_TRANS_S2_TRANS (3 << CBAR_TYPE_SHIFT)
|
||||
#define CBAR_IRPTNDX_SHIFT 24
|
||||
#define CBAR_IRPTNDX_MASK 0xff
|
||||
|
||||
/* Translation context bank */
|
||||
#define ARM_SMMU_CB_BASE(smmu) ((smmu)->base + ((smmu)->size >> 1))
|
||||
#define ARM_SMMU_CB(smmu, n) ((n) * (1 << (smmu)->pgshift))
|
||||
|
||||
#define ARM_SMMU_CB_SCTLR 0x0
|
||||
#define ARM_SMMU_CB_ACTLR 0x4
|
||||
#define ARM_SMMU_CB_RESUME 0x8
|
||||
#define ARM_SMMU_CB_TTBCR2 0x10
|
||||
#define ARM_SMMU_CB_TTBR0 0x20
|
||||
#define ARM_SMMU_CB_TTBR1 0x28
|
||||
#define ARM_SMMU_CB_TTBCR 0x30
|
||||
#define ARM_SMMU_CB_CONTEXTIDR 0x34
|
||||
#define ARM_SMMU_CB_S1_MAIR0 0x38
|
||||
#define ARM_SMMU_CB_S1_MAIR1 0x3c
|
||||
#define ARM_SMMU_CB_PAR 0x50
|
||||
#define ARM_SMMU_CB_FSR 0x58
|
||||
#define ARM_SMMU_CB_FAR 0x60
|
||||
#define ARM_SMMU_CB_FSYNR0 0x68
|
||||
#define ARM_SMMU_CB_S1_TLBIVA 0x600
|
||||
#define ARM_SMMU_CB_S1_TLBIASID 0x610
|
||||
#define ARM_SMMU_CB_S1_TLBIVAL 0x620
|
||||
#define ARM_SMMU_CB_S2_TLBIIPAS2 0x630
|
||||
#define ARM_SMMU_CB_S2_TLBIIPAS2L 0x638
|
||||
#define ARM_SMMU_CB_ATS1PR 0x800
|
||||
#define ARM_SMMU_CB_ATSR 0x8f0
|
||||
|
||||
#define SCTLR_S1_ASIDPNE (1 << 12)
|
||||
#define SCTLR_CFCFG (1 << 7)
|
||||
#define SCTLR_CFIE (1 << 6)
|
||||
#define SCTLR_CFRE (1 << 5)
|
||||
#define SCTLR_E (1 << 4)
|
||||
#define SCTLR_AFE (1 << 2)
|
||||
#define SCTLR_TRE (1 << 1)
|
||||
#define SCTLR_M (1 << 0)
|
||||
|
||||
/* ARM LPAE configuration. */
|
||||
/**************************************************************/
|
||||
/* Register bits */
|
||||
#define ARM_32_LPAE_TCR_EAE (1 << 31)
|
||||
#define ARM_64_LPAE_S2_TCR_RES1 (1 << 31)
|
||||
|
||||
#define ARM_LPAE_TCR_EPD1 (1 << 23)
|
||||
|
||||
#define ARM_LPAE_TCR_TG0_4K (0 << 14)
|
||||
#define ARM_LPAE_TCR_TG0_64K (1 << 14)
|
||||
#define ARM_LPAE_TCR_TG0_16K (2 << 14)
|
||||
|
||||
#define ARM_LPAE_TCR_SH0_SHIFT 12
|
||||
#define ARM_LPAE_TCR_SH0_MASK 0x3
|
||||
#define ARM_LPAE_TCR_SH_NS 0
|
||||
#define ARM_LPAE_TCR_SH_OS 2
|
||||
#define ARM_LPAE_TCR_SH_IS 3
|
||||
|
||||
#define ARM_LPAE_TCR_ORGN0_SHIFT 10
|
||||
#define ARM_LPAE_TCR_IRGN0_SHIFT 8
|
||||
#define ARM_LPAE_TCR_RGN_MASK 0x3
|
||||
#define ARM_LPAE_TCR_RGN_NC 0
|
||||
#define ARM_LPAE_TCR_RGN_WBWA 1
|
||||
#define ARM_LPAE_TCR_RGN_WT 2
|
||||
#define ARM_LPAE_TCR_RGN_WB 3
|
||||
|
||||
#define ARM_LPAE_TCR_SL0_SHIFT 6
|
||||
#define ARM_LPAE_TCR_SL0_MASK 0x3
|
||||
|
||||
#define ARM_LPAE_TCR_T0SZ_SHIFT 0
|
||||
#define ARM_LPAE_TCR_SZ_MASK 0xf
|
||||
|
||||
#define ARM_LPAE_TCR_PS_SHIFT 16
|
||||
#define ARM_LPAE_TCR_PS_MASK 0x7
|
||||
|
||||
#define ARM_LPAE_TCR_IPS_SHIFT 32
|
||||
#define ARM_LPAE_TCR_IPS_MASK 0x7
|
||||
|
||||
#define ARM_LPAE_TCR_PS_32_BIT 0x0ULL
|
||||
#define ARM_LPAE_TCR_PS_36_BIT 0x1ULL
|
||||
#define ARM_LPAE_TCR_PS_40_BIT 0x2ULL
|
||||
#define ARM_LPAE_TCR_PS_42_BIT 0x3ULL
|
||||
#define ARM_LPAE_TCR_PS_44_BIT 0x4ULL
|
||||
#define ARM_LPAE_TCR_PS_48_BIT 0x5ULL
|
||||
|
||||
#define ARM_LPAE_MAIR_ATTR_SHIFT(n) ((n) << 3)
|
||||
#define ARM_LPAE_MAIR_ATTR_MASK 0xff
|
||||
#define ARM_LPAE_MAIR_ATTR_DEVICE 0x04
|
||||
#define ARM_LPAE_MAIR_ATTR_NC 0x44
|
||||
#define ARM_LPAE_MAIR_ATTR_WBRWA 0xff
|
||||
#define ARM_LPAE_MAIR_ATTR_IDX_NC 0
|
||||
#define ARM_LPAE_MAIR_ATTR_IDX_CACHE 1
|
||||
#define ARM_LPAE_MAIR_ATTR_IDX_DEV 2
|
||||
|
||||
#define TTBRn_ASID_SHIFT 48
|
||||
#define TTBCR2_SEP_SHIFT 15
|
||||
#define TTBCR2_SEP_UPSTREAM (0x7 << TTBCR2_SEP_SHIFT)
|
||||
#define TTBCR2_AS (1 << 4)
|
||||
#define TTBCR_T0SZ(ia_bits) (64 - (ia_bits))
|
||||
|
||||
#define S2CR_PRIVCFG_SHIFT 24
|
||||
#define S2CR_PRIVCFG_MASK 0x3
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
uint16_t paxc_stream_ids[] = { 0x2000 };
|
||||
|
||||
uint16_t paxc_stream_ids_mask[] = { 0x1fff };
|
||||
uint16_t crmu_stream_ids[] = { CRMU_STREAM_ID };
|
||||
uint16_t crmu_stream_ids_mask[] = { 0x0 };
|
||||
|
||||
enum arm_smmu_s2cr_type {
|
||||
S2CR_TYPE_TRANS,
|
||||
S2CR_TYPE_BYPASS,
|
||||
S2CR_TYPE_FAULT,
|
||||
};
|
||||
|
||||
enum arm_smmu_s2cr_privcfg {
|
||||
S2CR_PRIVCFG_DEFAULT,
|
||||
S2CR_PRIVCFG_DIPAN,
|
||||
S2CR_PRIVCFG_UNPRIV,
|
||||
S2CR_PRIVCFG_PRIV,
|
||||
};
|
||||
|
||||
struct arm_smmu_smr {
|
||||
uint16_t mask;
|
||||
uint16_t id;
|
||||
uint32_t valid;
|
||||
};
|
||||
|
||||
struct arm_smmu_s2cr {
|
||||
int count;
|
||||
enum arm_smmu_s2cr_type type;
|
||||
enum arm_smmu_s2cr_privcfg privcfg;
|
||||
uint8_t cbndx;
|
||||
};
|
||||
|
||||
struct arm_smmu_cfg {
|
||||
uint8_t cbndx;
|
||||
uint8_t irptndx;
|
||||
uint32_t cbar;
|
||||
};
|
||||
|
||||
struct arm_smmu_device {
|
||||
uint8_t *base;
|
||||
uint32_t streams;
|
||||
unsigned long size;
|
||||
unsigned long pgshift;
|
||||
unsigned long va_size;
|
||||
unsigned long ipa_size;
|
||||
unsigned long pa_size;
|
||||
struct arm_smmu_smr smr[NUM_OF_SMRS];
|
||||
struct arm_smmu_s2cr s2cr[NUM_OF_SMRS];
|
||||
struct arm_smmu_cfg cfg[NUM_OF_SMRS];
|
||||
uint16_t *stream_ids;
|
||||
uint16_t *stream_ids_mask;
|
||||
};
|
||||
|
||||
void arm_smmu_enable_secure_client_port(void)
|
||||
{
|
||||
uintptr_t smmu_base = SMMU_BASE;
|
||||
|
||||
mmio_clrbits_32(smmu_base, sCR0_CLIENTPD);
|
||||
}
|
||||
|
||||
void arm_smmu_reserve_secure_cntxt(void)
|
||||
{
|
||||
uintptr_t smmu_base = SMMU_BASE;
|
||||
|
||||
mmio_clrsetbits_32(smmu_base + ARM_SMMU_SMMU_SCR1,
|
||||
(SCR1_NSNUMSMRGO_MASK | SCR1_NSNUMCBO_MASK),
|
||||
((ARM_SMMU_NSNUMCBO << SCR1_NSNUMCBO_SHIFT) |
|
||||
(ARM_SMMU_NSNUMSMRGO << SCR1_NSNUMSMRGO_SHIFT)));
|
||||
}
|
||||
|
||||
static void arm_smmu_smr_cfg(struct arm_smmu_device *smmu, uint32_t index)
|
||||
{
|
||||
uint32_t idx = smmu->cfg[index].cbndx;
|
||||
struct arm_smmu_smr *smr = &smmu->smr[index];
|
||||
uint32_t reg = smr->id << SMR_ID_SHIFT | smr->mask << SMR_MASK_SHIFT;
|
||||
|
||||
if (smr->valid)
|
||||
reg |= SMR_VALID;
|
||||
|
||||
mmio_write_32((uintptr_t) (ARM_SMMU_GR0(smmu) +
|
||||
ARM_SMMU_GR0_SMR(idx)), reg);
|
||||
}
|
||||
|
||||
static void arm_smmu_s2cr_cfg(struct arm_smmu_device *smmu, uint32_t index)
|
||||
{
|
||||
uint32_t idx = smmu->cfg[index].cbndx;
|
||||
struct arm_smmu_s2cr *s2cr = &smmu->s2cr[index];
|
||||
|
||||
uint32_t reg = (s2cr->type & S2CR_TYPE_MASK) << S2CR_TYPE_SHIFT |
|
||||
(s2cr->cbndx & S2CR_CBNDX_MASK) << S2CR_CBNDX_SHIFT |
|
||||
(s2cr->privcfg & S2CR_PRIVCFG_MASK) << S2CR_PRIVCFG_SHIFT;
|
||||
|
||||
mmio_write_32((uintptr_t) (ARM_SMMU_GR0(smmu) +
|
||||
ARM_SMMU_GR0_S2CR(idx)), reg);
|
||||
}
|
||||
|
||||
static void smmu_set_pgtbl(struct arm_smmu_device *smmu,
|
||||
enum iommu_domain dom,
|
||||
uint64_t *pg_table_base)
|
||||
{
|
||||
int i, l0_index, l1_index;
|
||||
uint64_t addr, *pte, *l0_base, *l1_base;
|
||||
uint64_t addr_space_limit;
|
||||
|
||||
if (dom == PCIE_PAXC) {
|
||||
addr_space_limit = 0xffffffffff;
|
||||
} else if (dom == DOMAIN_CRMU) {
|
||||
addr_space_limit = 0xffffffff;
|
||||
} else {
|
||||
ERROR("dom is not supported\n");
|
||||
return;
|
||||
}
|
||||
|
||||
l0_base = pg_table_base;
|
||||
/* clear L0 descriptors. */
|
||||
for (i = 0; i < ARM_LPAE_PGTBL_PTE_CNT; i++)
|
||||
l0_base[i] = 0x0;
|
||||
|
||||
addr = 0x0;
|
||||
while (addr < addr_space_limit) {
|
||||
/* find L0 pte */
|
||||
l0_index = ((addr >> ARM_LPAE_PTE_L0_INDEX_SHIFT) &
|
||||
ARM_LPAE_PTE_L0_INDEX_MASK);
|
||||
l1_base = l0_base + ((l0_index + 1) * ARM_LPAE_PGTBL_PTE_CNT);
|
||||
|
||||
/* setup L0 pte if required */
|
||||
pte = l0_base + l0_index;
|
||||
if (*pte == 0x0) {
|
||||
*pte |= ((uint64_t)l1_base & ARM_LPAE_PTE_TABLE_MASK);
|
||||
if (dom == PCIE_PAXC)
|
||||
*pte |= ARM_LPAE_PTE_NSTABLE;
|
||||
*pte |= ARM_LPAE_PTE_TABLE;
|
||||
*pte |= ARM_LPAE_PTE_VALID;
|
||||
}
|
||||
|
||||
/* find L1 pte */
|
||||
l1_index = ((addr >> ARM_LPAE_PTE_L1_INDEX_SHIFT) &
|
||||
ARM_LPAE_PTE_L1_INDEX_MASK);
|
||||
pte = l1_base + l1_index;
|
||||
|
||||
/* setup L1 pte */
|
||||
*pte = 0x0;
|
||||
*pte |= (addr & ARM_LPAE_PTE_L1_ADDR_MASK);
|
||||
if (addr < 0x80000000) {
|
||||
*pte |= (ARM_LPAE_MAIR_ATTR_IDX_DEV <<
|
||||
ARM_LPAE_PTE_ATTRINDX);
|
||||
if (dom == PCIE_PAXC)
|
||||
*pte |= (1 << ARM_LPAE_PTE_NS);
|
||||
} else {
|
||||
*pte |= (ARM_LPAE_MAIR_ATTR_IDX_CACHE <<
|
||||
ARM_LPAE_PTE_ATTRINDX);
|
||||
*pte |= (1 << ARM_LPAE_PTE_NS);
|
||||
}
|
||||
*pte |= (ARM_LPAE_PTE_AP_EL0_RW << ARM_LPAE_PTE_AP);
|
||||
*pte |= (ARM_LPAE_PTE_SH_INNER << ARM_LPAE_PTE_SH);
|
||||
*pte |= (1 << ARM_LPAE_PTE_AF);
|
||||
*pte |= ARM_LPAE_PTE_VALID;
|
||||
|
||||
addr += ARM_LPAE_PTE_L1_BLOCK_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
void arm_smmu_create_identity_map(enum iommu_domain dom)
|
||||
{
|
||||
struct arm_smmu_device iommu;
|
||||
struct arm_smmu_device *smmu = &iommu;
|
||||
uint32_t reg, reg2;
|
||||
unsigned long long reg64;
|
||||
uint32_t idx;
|
||||
uint16_t asid;
|
||||
unsigned int context_bank_index;
|
||||
unsigned long long pg_table_base;
|
||||
|
||||
smmu->base = (uint8_t *) SMMU_BASE;
|
||||
reg = mmio_read_32((uintptr_t) (ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_ID1));
|
||||
smmu->pgshift = (reg & ID1_PAGESIZE) ? 16 : 12;
|
||||
smmu->size = ARM_SMMU_RES_SIZE;
|
||||
smmu->stream_ids = NULL;
|
||||
|
||||
switch (dom) {
|
||||
case PCIE_PAXC:
|
||||
smmu->stream_ids = &paxc_stream_ids[0];
|
||||
smmu->stream_ids_mask = &paxc_stream_ids_mask[0];
|
||||
smmu->streams = ARRAY_SIZE(paxc_stream_ids);
|
||||
context_bank_index = SMMU_CTX_BANK_IDX;
|
||||
pg_table_base = ARM_LPAE_PGTBL_PHYS;
|
||||
break;
|
||||
case DOMAIN_CRMU:
|
||||
smmu->stream_ids = &crmu_stream_ids[0];
|
||||
smmu->stream_ids_mask = &crmu_stream_ids_mask[0];
|
||||
smmu->streams = ARRAY_SIZE(crmu_stream_ids);
|
||||
context_bank_index = SMMU_CTX_BANK_IDX_SECURE_CRMU;
|
||||
pg_table_base = ARM_LPAE_PGTBL_PHYS_CRMU;
|
||||
break;
|
||||
default:
|
||||
ERROR("domain not supported\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (smmu->streams > NUM_OF_SMRS) {
|
||||
INFO("can not support more than %d sids\n", NUM_OF_SMRS);
|
||||
return;
|
||||
}
|
||||
|
||||
/* set up iommu dev. */
|
||||
for (idx = 0; idx < smmu->streams; idx++) {
|
||||
/* S2CR. */
|
||||
smmu->s2cr[idx].type = S2CR_TYPE_TRANS;
|
||||
smmu->s2cr[idx].privcfg = S2CR_PRIVCFG_DEFAULT;
|
||||
smmu->s2cr[idx].cbndx = context_bank_index;
|
||||
smmu->cfg[idx].cbndx = context_bank_index;
|
||||
smmu->cfg[idx].cbar = STG1_WITH_STG2_BYPASS << CBAR_TYPE_SHIFT;
|
||||
arm_smmu_s2cr_cfg(smmu, idx);
|
||||
|
||||
/* SMR. */
|
||||
smmu->smr[idx].mask = smmu->stream_ids_mask[idx];
|
||||
smmu->smr[idx].id = smmu->stream_ids[idx];
|
||||
smmu->smr[idx].valid = 1;
|
||||
arm_smmu_smr_cfg(smmu, idx);
|
||||
|
||||
/* CBA2R. 64-bit Translation */
|
||||
mmio_write_32((uintptr_t) (ARM_SMMU_GR1(smmu) +
|
||||
ARM_SMMU_GR1_CBA2R(smmu->cfg[idx].cbndx)),
|
||||
0x1);
|
||||
/* CBAR.*/
|
||||
reg = smmu->cfg[idx].cbar;
|
||||
reg |= (CBAR_S1_BPSHCFG_NSH << CBAR_S1_BPSHCFG_SHIFT) |
|
||||
(CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT);
|
||||
|
||||
mmio_write_32((uintptr_t) (ARM_SMMU_GR1(smmu) +
|
||||
ARM_SMMU_GR1_CBAR(smmu->cfg[idx].cbndx)),
|
||||
reg);
|
||||
|
||||
/* TTBCR. */
|
||||
reg64 = (ARM_LPAE_TCR_SH_IS << ARM_LPAE_TCR_SH0_SHIFT) |
|
||||
(ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_IRGN0_SHIFT) |
|
||||
(ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_ORGN0_SHIFT);
|
||||
reg64 |= ARM_LPAE_TCR_TG0_4K;
|
||||
reg64 |= (ARM_LPAE_TCR_PS_40_BIT << ARM_LPAE_TCR_IPS_SHIFT);
|
||||
/* ias 40 bits.*/
|
||||
reg64 |= TTBCR_T0SZ(40) << ARM_LPAE_TCR_T0SZ_SHIFT;
|
||||
/* Disable speculative walks through TTBR1 */
|
||||
reg64 |= ARM_LPAE_TCR_EPD1;
|
||||
reg = (uint32_t) reg64;
|
||||
reg2 = (uint32_t) (reg64 >> 32);
|
||||
reg2 |= TTBCR2_SEP_UPSTREAM;
|
||||
reg2 |= TTBCR2_AS;
|
||||
|
||||
mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
|
||||
ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
|
||||
ARM_SMMU_CB_TTBCR2), reg2);
|
||||
|
||||
mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
|
||||
ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
|
||||
ARM_SMMU_CB_TTBCR), reg);
|
||||
|
||||
/* TTBR0. */
|
||||
asid = smmu->cfg[idx].cbndx;
|
||||
reg64 = pg_table_base;
|
||||
reg64 |= (unsigned long long) asid << TTBRn_ASID_SHIFT;
|
||||
|
||||
mmio_write_64((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
|
||||
ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
|
||||
ARM_SMMU_CB_TTBR0), reg64);
|
||||
/* TTBR1. */
|
||||
reg64 = 0;
|
||||
reg64 |= (unsigned long long) asid << TTBRn_ASID_SHIFT;
|
||||
|
||||
mmio_write_64((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
|
||||
ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
|
||||
ARM_SMMU_CB_TTBR1), reg64);
|
||||
/* MAIR. */
|
||||
reg = (ARM_LPAE_MAIR_ATTR_NC
|
||||
<< ARM_LPAE_MAIR_ATTR_SHIFT
|
||||
(ARM_LPAE_MAIR_ATTR_IDX_NC)) |
|
||||
(ARM_LPAE_MAIR_ATTR_WBRWA <<
|
||||
ARM_LPAE_MAIR_ATTR_SHIFT
|
||||
(ARM_LPAE_MAIR_ATTR_IDX_CACHE)) |
|
||||
(ARM_LPAE_MAIR_ATTR_DEVICE <<
|
||||
ARM_LPAE_MAIR_ATTR_SHIFT
|
||||
(ARM_LPAE_MAIR_ATTR_IDX_DEV));
|
||||
|
||||
mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
|
||||
ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
|
||||
ARM_SMMU_CB_S1_MAIR0), reg);
|
||||
|
||||
/* MAIR1. */
|
||||
reg = 0;
|
||||
mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
|
||||
ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
|
||||
ARM_SMMU_CB_S1_MAIR1), reg);
|
||||
/* SCTLR. */
|
||||
reg = SCTLR_CFIE | SCTLR_CFRE | SCTLR_AFE | SCTLR_TRE | SCTLR_M;
|
||||
/* stage 1.*/
|
||||
reg |= SCTLR_S1_ASIDPNE;
|
||||
mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
|
||||
ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
|
||||
ARM_SMMU_CB_SCTLR), reg);
|
||||
}
|
||||
smmu_set_pgtbl(smmu, dom, (uint64_t *)pg_table_base);
|
||||
}
|
54
plat/brcm/board/stingray/src/ncsi.c
Normal file
54
plat/brcm/board/stingray/src/ncsi.c
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <ncsi.h>
|
||||
#include <sr_def.h>
|
||||
#include <sr_utils.h>
|
||||
|
||||
static const char *const io_drives[] = {
|
||||
"2mA", "4mA", "6mA", "8mA",
|
||||
"10mA", "12mA", "14mA", "16mA"
|
||||
};
|
||||
|
||||
void brcm_stingray_ncsi_init(void)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
unsigned int selx = 0;
|
||||
|
||||
#if NCSI_IO_DRIVE_STRENGTH_MA == 2
|
||||
selx = 0x0;
|
||||
#elif NCSI_IO_DRIVE_STRENGTH_MA == 4
|
||||
selx = 0x1;
|
||||
#elif NCSI_IO_DRIVE_STRENGTH_MA == 6
|
||||
selx = 0x2;
|
||||
#elif NCSI_IO_DRIVE_STRENGTH_MA == 8
|
||||
selx = 0x3;
|
||||
#elif NCSI_IO_DRIVE_STRENGTH_MA == 10
|
||||
selx = 0x4;
|
||||
#elif NCSI_IO_DRIVE_STRENGTH_MA == 12
|
||||
selx = 0x5;
|
||||
#elif NCSI_IO_DRIVE_STRENGTH_MA == 14
|
||||
selx = 0x6;
|
||||
#elif NCSI_IO_DRIVE_STRENGTH_MA == 16
|
||||
selx = 0x7;
|
||||
#else
|
||||
ERROR("Unsupported NCSI_IO_DRIVE_STRENGTH_MA. Please check it.\n");
|
||||
return;
|
||||
#endif
|
||||
INFO("ncsi io drives: %s\n", io_drives[selx]);
|
||||
|
||||
for (i = 0; i < NITRO_NCSI_IOPAD_CONTROL_NUM; i++) {
|
||||
mmio_clrsetbits_32((NITRO_NCSI_IOPAD_CONTROL_BASE + (i * 4)),
|
||||
PAD_SELX_MASK, PAD_SELX_VALUE(selx));
|
||||
}
|
||||
|
||||
INFO("ncsi init done\n");
|
||||
}
|
911
plat/brcm/board/stingray/src/paxb.c
Normal file
911
plat/brcm/board/stingray/src/paxb.c
Normal file
@ -0,0 +1,911 @@
|
||||
/*
|
||||
* Copyright (c) 2016 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <paxb.h>
|
||||
#include <sr_def.h>
|
||||
#include <sr_utils.h>
|
||||
|
||||
#define PCIE_CORE_PWR_ARR_POWERON 0x8
|
||||
#define PCIE_CORE_PWR_ARR_POWEROK 0x4
|
||||
#define PCIE_CORE_PWR_POWERON 0x2
|
||||
#define PCIE_CORE_PWR_POWEROK 0x1
|
||||
|
||||
#define PCIE_CORE_USER_CFG (PCIE_CORE_BASE + 0x38)
|
||||
#define PCIE_PAXB_SMMU_SID_CFG (PCIE_CORE_BASE + 0x60)
|
||||
#ifdef SID_B8_D1_F1
|
||||
#define PAXB_SMMU_SID_CFG_BUS_WIDTH (0x8 << 8)
|
||||
#define PAXB_SMMU_SID_CFG_DEV_WIDTH (0x1 << 12)
|
||||
#define PAXB_SMMU_SID_CFG_FUN_WIDTH (0x1 << 16)
|
||||
#else
|
||||
#define PAXB_SMMU_SID_CFG_BUS_WIDTH (0x2 << 8)
|
||||
#define PAXB_SMMU_SID_CFG_DEV_WIDTH (0x5 << 12)
|
||||
#define PAXB_SMMU_SID_CFG_FUN_WIDTH (0x3 << 16)
|
||||
#endif
|
||||
|
||||
#define PAXB_APB_TIMEOUT_COUNT_OFFSET 0x034
|
||||
|
||||
/* allow up to 5 ms for each power switch to stabilize */
|
||||
#define PCIE_CORE_PWR_TIMEOUT_MS 5
|
||||
|
||||
/* wait 1 microsecond for PCIe core soft reset */
|
||||
#define PCIE_CORE_SOFT_RST_DELAY_US 1
|
||||
|
||||
/*
|
||||
* List of PAXB APB registers
|
||||
*/
|
||||
#define PAXB_BASE 0x48000000
|
||||
#define PAXB_BASE_OFFSET 0x4000
|
||||
#define PAXB_OFFSET(core) (PAXB_BASE + \
|
||||
(core) * PAXB_BASE_OFFSET)
|
||||
|
||||
#define PAXB_CLK_CTRL_OFFSET 0x000
|
||||
#define PAXB_EP_PERST_SRC_SEL_MASK (1 << 2)
|
||||
#define PAXB_EP_MODE_PERST_MASK (1 << 1)
|
||||
#define PAXB_RC_PCIE_RST_OUT_MASK (1 << 0)
|
||||
|
||||
#define PAXB_MAX_IMAP_WINDOWS 8
|
||||
#define PAXB_IMAP_REG_WIDTH 8
|
||||
#define PAXB_IMAP0_REG_WIDTH 4
|
||||
#define PAXB_AXUSER_REG_WIDTH 4
|
||||
|
||||
#define PAXB_CFG_IND_ADDR_OFFSET 0x120
|
||||
#define PAXB_CFG_IND_DATA_OFFSET 0x124
|
||||
#define PAXB_CFG_IND_ADDR_MASK 0x1ffc
|
||||
#define PAXB_CFG_CFG_TYPE_MASK 0x1
|
||||
|
||||
#define PAXB_EP_CFG_ADDR_OFFSET 0x1f8
|
||||
#define PAXB_EP_CFG_DATA_OFFSET 0x1fc
|
||||
#define PAXB_EP_CFG_ADDR_MASK 0xffc
|
||||
#define PAXB_EP_CFG_TYPE_MASK 0x1
|
||||
|
||||
#define PAXB_0_DEFAULT_IMAP 0xed0
|
||||
#define DEFAULT_ADDR_INVALID BIT(0)
|
||||
#define PAXB_0_DEFAULT_IMAP_AXUSER 0xed8
|
||||
#define PAXB_0_DEFAULT_IMAP_AXCACHE 0xedc
|
||||
#define IMAP_AXCACHE 0xff
|
||||
#define OARR_VALID BIT(0)
|
||||
#define IMAP_VALID BIT(0)
|
||||
|
||||
#define PAXB_IMAP0_BASE_OFFSET 0xc00
|
||||
#define PAXB_IARR0_BASE_OFFSET 0xd00
|
||||
#define PAXB_IMAP0_OFFSET(idx) (PAXB_IMAP0_BASE_OFFSET + \
|
||||
(idx) * PAXB_IMAP0_REG_WIDTH)
|
||||
#define PAXB_IMAP0_WINDOW_SIZE 0x1000
|
||||
|
||||
#define PAXB_IMAP2_OFFSET 0xcc0
|
||||
#define PAXB_IMAP0_REGS_TYPE_OFFSET 0xcd0
|
||||
#define PAXB_IARR2_LOWER_OFFSET 0xd10
|
||||
|
||||
#define PAXB_IMAP3_BASE_OFFSET 0xe08
|
||||
#define PAXB_IMAP3_OFFSET(idx) (PAXB_IMAP3_BASE_OFFSET + \
|
||||
(idx) * PAXB_IMAP_REG_WIDTH)
|
||||
|
||||
#define PAXB_IMAP3_0_AXUSER_B_OFFSET 0xe48
|
||||
#define PAXB_IMAP3_0_AXUSER_OFFSET(idx) (PAXB_IMAP3_0_AXUSER_B_OFFSET + \
|
||||
(idx) * PAXB_AXUSER_REG_WIDTH)
|
||||
|
||||
#define PAXB_IMAP4_BASE_OFFSET 0xe70
|
||||
#define PAXB_IMAP4_OFFSET(idx) (PAXB_IMAP4_BASE_OFFSET + \
|
||||
(idx) * PAXB_IMAP_REG_WIDTH)
|
||||
|
||||
#define PAXB_IMAP4_0_AXUSER_B_OFFSET 0xeb0
|
||||
#define PAXB_IMAP4_0_AXUSER_OFFSET(idx) (PAXB_IMAP4_0_AXUSER_B_OFFSET + \
|
||||
(idx) * PAXB_AXUSER_REG_WIDTH)
|
||||
|
||||
#define PAXB_CFG_LINK_STATUS_OFFSET 0xf0c
|
||||
#define PAXB_CFG_PHYLINKUP_MASK (1 << 3)
|
||||
#define PAXB_CFG_DL_ACTIVE_MASK (1 << 2)
|
||||
|
||||
#define PAXB_IMAP0_0_AXUSER_OFFSET 0xf60
|
||||
#define PAXB_IMAP2_AXUSER_OFFSET 0xfe0
|
||||
|
||||
/* cacheable write-back, allocate on both reads and writes */
|
||||
#define IMAP_ARCACHE 0x0f0
|
||||
#define IMAP_AWCACHE 0xf00
|
||||
/* normal access, nonsecure access, and data access */
|
||||
/* AWQOS:0xe and ARQOS:0xa */
|
||||
/* AWPROT:0x2 and ARPROT:0x1 */
|
||||
#define IMAP_AXUSER 0x002e002a
|
||||
|
||||
/*
|
||||
* List of NIC security and PIPEMUX related registers
|
||||
*/
|
||||
#define SR_PCIE_NIC_SECURITY_BASE 0x58100000
|
||||
#define NS3Z_PCIE_NIC_SECURITY_BASE 0x48100000
|
||||
|
||||
#define GITS_TRANSLATER 0x63c30000
|
||||
|
||||
#define VENDOR_ID 0x14e4
|
||||
#define CFG_RC_DEV_ID 0x434
|
||||
#define CFG_RC_DEV_SUBID 0x438
|
||||
#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c
|
||||
#define PCI_CLASS_BRIDGE_MASK 0xffff00
|
||||
#define PCI_CLASS_BRIDGE_SHIFT 8
|
||||
#define PCI_CLASS_BRIDGE_PCI 0x0604
|
||||
|
||||
/*
|
||||
* List of PAXB RC configuration space registers
|
||||
*/
|
||||
|
||||
/* first capability list entry */
|
||||
#define PCI_CAPABILITY_LIST_OFFSET 0x34
|
||||
#define PCI_CAPABILITY_SPEED_OFFSET 0xc
|
||||
#define PCI_EP_CAPABILITY_OFFSET 0x10
|
||||
|
||||
#define CFG_RC_LINK_STATUS_CTRL_2 0x0dc
|
||||
#define CFG_RC_LINK_SPEED_SHIFT 0
|
||||
#define CFG_RC_LINK_SPEED_MASK (0xf << CFG_RC_LINK_SPEED_SHIFT)
|
||||
|
||||
#define CFG_RC_DEVICE_CAP 0x4d4
|
||||
#define CFG_RC_DEVICE_CAP_MPS_SHIFT 0
|
||||
#define CFG_RC_DEVICE_CAP_MPS_MASK (0x7 << CFG_RC_DEVICE_CAP_MPS_SHIFT)
|
||||
/* MPS 256 bytes */
|
||||
#define CFG_RC_DEVICE_CAP_MPS_256B (0x1 << CFG_RC_DEVICE_CAP_MPS_SHIFT)
|
||||
/* MPS 512 bytes */
|
||||
#define CFG_RC_DEVICE_CAP_MPS_512B (0x2 << CFG_RC_DEVICE_CAP_MPS_SHIFT)
|
||||
|
||||
#define CFG_RC_TL_FCIMM_NP_LIMIT 0xa10
|
||||
#define CFG_RC_TL_FCIMM_NP_VAL 0x01500000
|
||||
#define CFG_RC_TL_FCIMM_P_LIMIT 0xa14
|
||||
#define CFG_RC_TL_FCIMM_P_VAL 0x03408080
|
||||
|
||||
#define CFG_RC_LINK_CAP 0x4dc
|
||||
#define CFG_RC_LINK_CAP_SPEED_SHIFT 0
|
||||
#define CFG_RC_LINK_CAP_SPEED_MASK (0xf << CFG_RC_LINK_CAP_SPEED_SHIFT)
|
||||
#define CFG_RC_LINK_CAP_WIDTH_SHIFT 4
|
||||
#define CFG_RC_LINK_CAP_WIDTH_MASK (0x1f << CFG_RC_LINK_CAP_WIDTH_SHIFT)
|
||||
|
||||
#define CFG_LINK_CAP_RC 0x4f0
|
||||
#define CFG_RC_DL_ACTIVE_SHIFT 0
|
||||
#define CFG_RC_DL_ACTIVE_MASK (0x1 << CFG_RC_DL_ACTIVE_SHIFT)
|
||||
#define CFG_RC_SLOT_CLK_SHIFT 1
|
||||
#define CFG_RC_SLOT_CLK_MASK (0x1 << CFG_RC_SLOT_CLK_SHIFT)
|
||||
|
||||
#define CFG_ROOT_CAP_RC 0x4f8
|
||||
#define CFG_ROOT_CAP_LTR_SHIFT 1
|
||||
#define CFG_ROOT_CAP_LTR_MASK (0x1 << CFG_ROOT_CAP_LTR_SHIFT)
|
||||
|
||||
#define CFG_RC_CLKREQ_ENABLED 0x4fc
|
||||
#define CFG_RC_CLKREQ_ENABLED_SHIFT 0
|
||||
#define CFG_RC_CLKREQ_ENABLED_MASK (0x1 << CFG_RC_CLKREQ_ENABLED_SHIFT)
|
||||
|
||||
#define CFG_RC_COEFF_ADDR 0x638
|
||||
|
||||
#define CFG_RC_TL_CTRL_0 0x800
|
||||
#define RC_MEM_DW_CHK_MASK 0x03fe
|
||||
|
||||
#define CFG_RC_PDL_CTRL_4 0x1010
|
||||
#define NPH_FC_INIT_SHIFT 24
|
||||
#define NPH_FC_INIT_MASK (U(0xff) << NPH_FC_INIT_SHIFT)
|
||||
#define PD_FC_INIT_SHIFT 12
|
||||
#define PD_FC_INIT_MASK (0xffff << PD_FC_INIT_SHIFT)
|
||||
|
||||
#define CFG_RC_PDL_CTRL_5 0x1014
|
||||
#define PH_INIT_SHIFT 0
|
||||
#define PH_INIT_MASK (0xff << PH_INIT_SHIFT)
|
||||
|
||||
#define DL_STATUS_OFFSET 0x1048
|
||||
#define PHYLINKUP BIT(13)
|
||||
|
||||
#define PH_INIT 0x10
|
||||
#define PD_FC_INIT 0x100
|
||||
#define NPH_FC_INIT 0x8
|
||||
|
||||
#define SRP_PH_INIT 0x7F
|
||||
#define SRP_PD_FC_INIT 0x200
|
||||
#define SRP_NPH_FC_INIT 0x7F
|
||||
|
||||
#define CFG_ADDR_BUS_NUM_SHIFT 20
|
||||
#define CFG_ADDR_DEV_NUM_SHIFT 15
|
||||
#define CFG_ADDR_FUNC_NUM_SHIFT 12
|
||||
#define CFG_ADDR_REG_NUM_SHIFT 2
|
||||
#define CFG_ADDR_REG_NUM_MASK 0x00000ffc
|
||||
#define CFG_ADDR_CFG_TYPE_MASK 0x00000003
|
||||
|
||||
#define DL_LINK_UP_TIMEOUT_MS 1000
|
||||
|
||||
#define CFG_RETRY_STATUS 0xffff0001
|
||||
#define CRS_TIMEOUT_MS 5000
|
||||
|
||||
/* create EP config data to write */
|
||||
#define DEF_BUS_NO 1 /* default bus 1 */
|
||||
#define DEF_SLOT_NO 0 /* default slot 0 */
|
||||
#define DEF_FN_NO 0 /* default fn 0 */
|
||||
|
||||
#define EP_CONFIG_VAL(bus_no, slot, fn, where) \
|
||||
(((bus_no) << CFG_ADDR_BUS_NUM_SHIFT) | \
|
||||
((slot) << CFG_ADDR_DEV_NUM_SHIFT) | \
|
||||
((fn) << CFG_ADDR_FUNC_NUM_SHIFT) | \
|
||||
((where) & CFG_ADDR_REG_NUM_MASK) | \
|
||||
(1 & CFG_ADDR_CFG_TYPE_MASK))
|
||||
|
||||
/* PAXB security offset */
|
||||
#define PAXB_SECURITY_IDM_OFFSET 0x1c
|
||||
#define PAXB_SECURITY_APB_OFFSET 0x24
|
||||
#define PAXB_SECURITY_ECAM_OFFSET 0x3c
|
||||
|
||||
#define paxb_get_config(type) paxb_get_##type##_config()
|
||||
|
||||
static unsigned int paxb_sec_reg_offset[] = {
|
||||
0x0c, /* PAXB0 AXI */
|
||||
0x10, /* PAXB1 AXI */
|
||||
0x14, /* PAXB2 AXI */
|
||||
0x18, /* PAXB3 AXI */
|
||||
0x20, /* PAXB4 AXI */
|
||||
0x28, /* PAXB5 AXI */
|
||||
0x2c, /* PAXB6 AXI */
|
||||
0x30, /* PAXB7 AXI */
|
||||
0x24, /* PAXB APB */
|
||||
};
|
||||
|
||||
const paxb_cfg *paxb;
|
||||
|
||||
/*
|
||||
* Given a PIPEMUX strap and PCIe core index, this function returns 1 if a
|
||||
* PCIe core needs to be enabled
|
||||
*/
|
||||
int pcie_core_needs_enable(unsigned int core_idx)
|
||||
{
|
||||
if (paxb->core_needs_enable)
|
||||
return paxb->core_needs_enable(core_idx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pcie_set_default_tx_coeff(uint32_t core_idx, uint32_t link_width)
|
||||
{
|
||||
unsigned int lanes = 0;
|
||||
uint32_t data, addr;
|
||||
|
||||
addr = CFG_RC_COEFF_ADDR;
|
||||
for (lanes = 0; lanes < link_width; lanes = lanes + 2) {
|
||||
data = paxb_rc_cfg_read(core_idx, addr);
|
||||
data &= 0xf0f0f0f0;
|
||||
data |= (7 & 0xf);
|
||||
data |= (7 & 0xf) << 8;
|
||||
data |= (7 & 0xf) << 16;
|
||||
data |= (7 & 0xf) << 24;
|
||||
|
||||
paxb_rc_cfg_write(core_idx, addr, data);
|
||||
addr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static int paxb_rc_link_init(void)
|
||||
{
|
||||
uint32_t val, link_speed;
|
||||
unsigned int link_width;
|
||||
uint32_t core_idx;
|
||||
|
||||
for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
|
||||
if (!pcie_core_needs_enable(core_idx))
|
||||
continue;
|
||||
|
||||
link_width = paxb->get_link_width(core_idx);
|
||||
if (!link_width) {
|
||||
ERROR("Unsupported PIPEMUX\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
link_speed = paxb->get_link_speed();
|
||||
/* program RC's link cap reg to advertise proper link width */
|
||||
val = paxb_rc_cfg_read(core_idx, CFG_RC_LINK_CAP);
|
||||
val &= ~CFG_RC_LINK_CAP_WIDTH_MASK;
|
||||
val |= (link_width << CFG_RC_LINK_CAP_WIDTH_SHIFT);
|
||||
paxb_rc_cfg_write(core_idx, CFG_RC_LINK_CAP, val);
|
||||
|
||||
/* program RC's link cap reg to advertise proper link speed */
|
||||
val = paxb_rc_cfg_read(core_idx, CFG_RC_LINK_CAP);
|
||||
val &= ~CFG_RC_LINK_CAP_SPEED_MASK;
|
||||
val |= link_speed << CFG_RC_LINK_CAP_SPEED_SHIFT;
|
||||
paxb_rc_cfg_write(core_idx, CFG_RC_LINK_CAP, val);
|
||||
|
||||
/* also need to program RC's link status control register */
|
||||
val = paxb_rc_cfg_read(core_idx, CFG_RC_LINK_STATUS_CTRL_2);
|
||||
val &= ~(CFG_RC_LINK_SPEED_MASK);
|
||||
val |= link_speed << CFG_RC_LINK_SPEED_SHIFT;
|
||||
paxb_rc_cfg_write(core_idx, CFG_RC_LINK_STATUS_CTRL_2, val);
|
||||
|
||||
#ifdef WAR_PLX_PRESET_PARITY_FAIL
|
||||
/* WAR to avoid crash with PLX switch in GEN3*/
|
||||
/* While PRESET, PLX switch is not fixing parity so disabled */
|
||||
val = paxb_rc_cfg_read(core_idx, CFG_RC_REG_PHY_CTL_10);
|
||||
val &= ~(PHY_CTL_10_GEN3_MATCH_PARITY);
|
||||
paxb_rc_cfg_write(core_idx, CFG_RC_REG_PHY_CTL_10, val);
|
||||
#endif
|
||||
pcie_set_default_tx_coeff(core_idx, link_width);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef PAXB_LINKUP
|
||||
static void paxb_perst_ctrl(unsigned int core_idx, bool assert)
|
||||
{
|
||||
uint32_t clk_ctrl = PAXB_OFFSET(core_idx) + PAXB_CLK_CTRL_OFFSET;
|
||||
|
||||
if (assert) {
|
||||
mmio_clrbits_32(clk_ctrl, PAXB_EP_PERST_SRC_SEL_MASK |
|
||||
PAXB_EP_MODE_PERST_MASK |
|
||||
PAXB_RC_PCIE_RST_OUT_MASK);
|
||||
udelay(250);
|
||||
} else {
|
||||
mmio_setbits_32(clk_ctrl, PAXB_RC_PCIE_RST_OUT_MASK);
|
||||
mdelay(100);
|
||||
}
|
||||
}
|
||||
|
||||
static void paxb_start_link_up(void)
|
||||
{
|
||||
unsigned int core_idx;
|
||||
uint32_t val, timeout;
|
||||
|
||||
for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
|
||||
if (!pcie_core_needs_enable(core_idx))
|
||||
continue;
|
||||
|
||||
/* toggle PERST */
|
||||
paxb_perst_ctrl(core_idx, true);
|
||||
paxb_perst_ctrl(core_idx, false);
|
||||
|
||||
timeout = DL_LINK_UP_TIMEOUT_MS;
|
||||
/* wait for Link up */
|
||||
do {
|
||||
val = mmio_read_32(PAXB_OFFSET(core_idx) +
|
||||
PAXB_CFG_LINK_STATUS_OFFSET);
|
||||
if (val & PAXB_CFG_DL_ACTIVE_MASK)
|
||||
break;
|
||||
|
||||
mdelay(1);
|
||||
} while (--timeout);
|
||||
|
||||
if (!timeout)
|
||||
ERROR("PAXB core %u link is down\n", core_idx);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void pcie_core_soft_reset(unsigned int core_idx)
|
||||
{
|
||||
uint32_t offset = core_idx * PCIE_CORE_PWR_OFFSET;
|
||||
uintptr_t ctrl = (uintptr_t)(PCIE_CORE_SOFT_RST_CFG_BASE + offset);
|
||||
|
||||
/* Put PCIe core in soft reset */
|
||||
mmio_clrbits_32(ctrl, PCIE_CORE_SOFT_RST);
|
||||
|
||||
/* Wait for 1 us before pulling PCIe core out of soft reset */
|
||||
udelay(PCIE_CORE_SOFT_RST_DELAY_US);
|
||||
|
||||
mmio_setbits_32(ctrl, PCIE_CORE_SOFT_RST);
|
||||
}
|
||||
|
||||
static int pcie_core_pwron_switch(uintptr_t ctrl, uintptr_t status,
|
||||
uint32_t mask)
|
||||
{
|
||||
uint32_t val;
|
||||
unsigned int timeout = PCIE_CORE_PWR_TIMEOUT_MS;
|
||||
|
||||
/* enable switch */
|
||||
mmio_setbits_32(ctrl, mask);
|
||||
|
||||
/* now wait for it to stabilize */
|
||||
do {
|
||||
val = mmio_read_32(status);
|
||||
if ((val & mask) == mask)
|
||||
return 0;
|
||||
mdelay(1);
|
||||
} while (--timeout);
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static int pcie_core_pwr_seq(uintptr_t ctrl, uintptr_t status)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Enable the switch with the following sequence:
|
||||
* 1. Array weak switch output switch
|
||||
* 2. Array strong switch
|
||||
* 3. Weak switch output acknowledge
|
||||
* 4. Strong switch output acknowledge
|
||||
*/
|
||||
ret = pcie_core_pwron_switch(ctrl, status, PCIE_CORE_PWR_ARR_POWERON);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pcie_core_pwron_switch(ctrl, status, PCIE_CORE_PWR_ARR_POWEROK);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pcie_core_pwron_switch(ctrl, status, PCIE_CORE_PWR_POWERON);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pcie_core_pwron_switch(ctrl, status, PCIE_CORE_PWR_POWEROK);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function enables PCIe core and PAXB memory buffer power, and then
|
||||
* remove the PCIe core from isolation
|
||||
*/
|
||||
static int pcie_core_pwr_init(unsigned int core_idx)
|
||||
{
|
||||
int ret;
|
||||
uint32_t offset = core_idx * PCIE_CORE_PWR_OFFSET;
|
||||
uintptr_t ctrl, status;
|
||||
|
||||
/* enable mem power to PCIe core */
|
||||
ctrl = (uintptr_t)(PCIE_CORE_MEM_PWR_BASE + offset);
|
||||
status = (uintptr_t)(PCIE_CORE_MEM_PWR_STATUS_BASE + offset);
|
||||
ret = pcie_core_pwr_seq(ctrl, status);
|
||||
if (ret) {
|
||||
ERROR("PCIe core mem power failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* now enable mem power to PAXB wrapper */
|
||||
ctrl = (uintptr_t)(PCIE_PAXB_MEM_PWR_BASE + offset);
|
||||
status = (uintptr_t)(PCIE_PAXB_MEM_PWR_STATUS_BASE + offset);
|
||||
ret = pcie_core_pwr_seq(ctrl, status);
|
||||
if (ret) {
|
||||
ERROR("PAXB mem power failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* now remove power isolation */
|
||||
ctrl = (uintptr_t)(PCIE_CORE_ISO_CFG_BASE + offset);
|
||||
mmio_clrbits_32(ctrl, PCIE_CORE_ISO | PCIE_CORE_MEM_ISO);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pcie_ss_reset(void)
|
||||
{
|
||||
mmio_setbits_32(CDRU_MISC_RESET_CONTROL,
|
||||
1 << CDRU_MISC_RESET_CONTROL__CDRU_PCIE_RESET_N_R);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function reads the PIPEMUX strap, figures out all the PCIe cores that
|
||||
* need to be enabled and enable the mem power for those cores
|
||||
*/
|
||||
static int pcie_cores_init(void)
|
||||
{
|
||||
int ret;
|
||||
uint32_t core_idx;
|
||||
|
||||
if (paxb->pipemux_init) {
|
||||
ret = paxb->pipemux_init();
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* bring PCIe subsystem out of reset */
|
||||
pcie_ss_reset();
|
||||
|
||||
/* power up all PCIe cores that will be used as RC */
|
||||
for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
|
||||
if (!pcie_core_needs_enable(core_idx))
|
||||
continue;
|
||||
|
||||
ret = pcie_core_pwr_init(core_idx);
|
||||
if (ret) {
|
||||
ERROR("PCIe core %u power up failed\n", core_idx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pcie_core_soft_reset(core_idx);
|
||||
|
||||
VERBOSE("PCIe core %u is powered up\n", core_idx);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void paxb_rc_cfg_write(unsigned int core_idx, unsigned int where,
|
||||
uint32_t val)
|
||||
{
|
||||
mmio_write_32(PAXB_OFFSET(core_idx) + PAXB_CFG_IND_ADDR_OFFSET,
|
||||
(where & PAXB_CFG_IND_ADDR_MASK) |
|
||||
PAXB_CFG_CFG_TYPE_MASK);
|
||||
mmio_write_32(PAXB_OFFSET(core_idx) + PAXB_CFG_IND_DATA_OFFSET, val);
|
||||
}
|
||||
|
||||
unsigned int paxb_rc_cfg_read(unsigned int core_idx, unsigned int where)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
mmio_write_32(PAXB_OFFSET(core_idx) + PAXB_CFG_IND_ADDR_OFFSET,
|
||||
(where & PAXB_CFG_IND_ADDR_MASK) |
|
||||
PAXB_CFG_CFG_TYPE_MASK);
|
||||
val = mmio_read_32(PAXB_OFFSET(core_idx) + PAXB_CFG_IND_DATA_OFFSET);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void paxb_cfg_mps(void)
|
||||
{
|
||||
uint32_t val, core_idx, mps;
|
||||
|
||||
for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
|
||||
if (!pcie_core_needs_enable(core_idx))
|
||||
continue;
|
||||
|
||||
val = paxb_rc_cfg_read(core_idx, CFG_RC_DEVICE_CAP);
|
||||
val &= ~CFG_RC_DEVICE_CAP_MPS_MASK;
|
||||
mps = CFG_RC_DEVICE_CAP_MPS_256B;
|
||||
if (core_idx == 0 || core_idx == 1 ||
|
||||
core_idx == 6 || core_idx == 7) {
|
||||
mps = CFG_RC_DEVICE_CAP_MPS_512B;
|
||||
}
|
||||
val |= mps;
|
||||
paxb_rc_cfg_write(core_idx, CFG_RC_DEVICE_CAP, val);
|
||||
}
|
||||
}
|
||||
|
||||
static void paxb_cfg_dev_id(void)
|
||||
{
|
||||
uint32_t val, core_idx;
|
||||
uint32_t device_id;
|
||||
|
||||
device_id = paxb->device_id;
|
||||
|
||||
for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
|
||||
if (!pcie_core_needs_enable(core_idx))
|
||||
continue;
|
||||
|
||||
/* Set Core in RC mode */
|
||||
mmio_setbits_32(PCIE_CORE_USER_CFG +
|
||||
(core_idx * PCIE_CORE_PWR_OFFSET), 1);
|
||||
|
||||
/* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */
|
||||
val = paxb_rc_cfg_read(core_idx, PCI_BRIDGE_CTRL_REG_OFFSET);
|
||||
val &= ~PCI_CLASS_BRIDGE_MASK;
|
||||
val |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT);
|
||||
paxb_rc_cfg_write(core_idx, PCI_BRIDGE_CTRL_REG_OFFSET, val);
|
||||
|
||||
val = (VENDOR_ID << 16) | device_id;
|
||||
paxb_rc_cfg_write(core_idx, CFG_RC_DEV_ID, val);
|
||||
|
||||
val = (device_id << 16) | VENDOR_ID;
|
||||
paxb_rc_cfg_write(core_idx, CFG_RC_DEV_SUBID, val);
|
||||
}
|
||||
}
|
||||
|
||||
static void paxb_cfg_tgt_trn(void)
|
||||
{
|
||||
uint32_t val, core_idx;
|
||||
|
||||
/*
|
||||
* Disable all mem Rd/Wr size check so it allows target read/write
|
||||
* transactions to be more than stipulated DW. As a result, PAXB root
|
||||
* complex will not abort these read/write transcations beyond
|
||||
* stipulated limit
|
||||
*/
|
||||
for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
|
||||
if (!pcie_core_needs_enable(core_idx))
|
||||
continue;
|
||||
|
||||
val = paxb_rc_cfg_read(core_idx, CFG_RC_TL_CTRL_0);
|
||||
val &= ~(RC_MEM_DW_CHK_MASK);
|
||||
paxb_rc_cfg_write(core_idx, CFG_RC_TL_CTRL_0, val);
|
||||
}
|
||||
}
|
||||
|
||||
static void paxb_cfg_pdl_ctrl(void)
|
||||
{
|
||||
uint32_t val, core_idx;
|
||||
uint32_t nph, ph, pd;
|
||||
|
||||
/* increase the credit counter to 4 for non-posted header */
|
||||
for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
|
||||
if (!pcie_core_needs_enable(core_idx))
|
||||
continue;
|
||||
|
||||
nph = NPH_FC_INIT;
|
||||
ph = PH_INIT;
|
||||
pd = PD_FC_INIT;
|
||||
|
||||
if (core_idx == 0 || core_idx == 1 ||
|
||||
core_idx == 6 || core_idx == 7) {
|
||||
nph = SRP_NPH_FC_INIT;
|
||||
ph = SRP_PH_INIT;
|
||||
pd = SRP_PD_FC_INIT;
|
||||
}
|
||||
val = paxb_rc_cfg_read(core_idx, CFG_RC_PDL_CTRL_4);
|
||||
val &= ~NPH_FC_INIT_MASK;
|
||||
val &= ~PD_FC_INIT_MASK;
|
||||
val = val | (nph << NPH_FC_INIT_SHIFT);
|
||||
val = val | (pd << PD_FC_INIT_SHIFT);
|
||||
paxb_rc_cfg_write(core_idx, CFG_RC_PDL_CTRL_4, val);
|
||||
|
||||
val = paxb_rc_cfg_read(core_idx, CFG_RC_PDL_CTRL_5);
|
||||
val &= ~PH_INIT_MASK;
|
||||
val = val | (ph << PH_INIT_SHIFT);
|
||||
paxb_rc_cfg_write(core_idx, CFG_RC_PDL_CTRL_5, val);
|
||||
|
||||
/*
|
||||
* ASIC to give more optmized value after further investigation.
|
||||
* till then this is important to have to get similar
|
||||
* performance on all the slots.
|
||||
*/
|
||||
paxb_rc_cfg_write(core_idx, CFG_RC_TL_FCIMM_NP_LIMIT,
|
||||
CFG_RC_TL_FCIMM_NP_VAL);
|
||||
|
||||
paxb_rc_cfg_write(core_idx, CFG_RC_TL_FCIMM_P_LIMIT,
|
||||
CFG_RC_TL_FCIMM_P_VAL);
|
||||
}
|
||||
}
|
||||
|
||||
static void paxb_cfg_clkreq(void)
|
||||
{
|
||||
uint32_t val, core_idx;
|
||||
|
||||
for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
|
||||
if (!pcie_core_needs_enable(core_idx))
|
||||
continue;
|
||||
|
||||
val = paxb_rc_cfg_read(core_idx, CFG_RC_CLKREQ_ENABLED);
|
||||
val &= ~CFG_RC_CLKREQ_ENABLED_MASK;
|
||||
paxb_rc_cfg_write(core_idx, CFG_RC_CLKREQ_ENABLED, val);
|
||||
}
|
||||
}
|
||||
|
||||
static void paxb_cfg_dl_active(bool enable)
|
||||
{
|
||||
uint32_t val, core_idx;
|
||||
|
||||
for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
|
||||
if (!pcie_core_needs_enable(core_idx))
|
||||
continue;
|
||||
|
||||
val = paxb_rc_cfg_read(core_idx, CFG_LINK_CAP_RC);
|
||||
if (enable)
|
||||
val |= CFG_RC_DL_ACTIVE_MASK;
|
||||
else
|
||||
val &= ~CFG_RC_DL_ACTIVE_MASK;
|
||||
paxb_rc_cfg_write(core_idx, CFG_LINK_CAP_RC, val);
|
||||
}
|
||||
}
|
||||
|
||||
static void paxb_cfg_LTR(int enable)
|
||||
{
|
||||
uint32_t val, core_idx;
|
||||
|
||||
for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
|
||||
if (!pcie_core_needs_enable(core_idx))
|
||||
continue;
|
||||
|
||||
val = paxb_rc_cfg_read(core_idx, CFG_ROOT_CAP_RC);
|
||||
if (enable)
|
||||
val |= CFG_ROOT_CAP_LTR_MASK;
|
||||
else
|
||||
val &= ~CFG_ROOT_CAP_LTR_MASK;
|
||||
paxb_rc_cfg_write(core_idx, CFG_ROOT_CAP_RC, val);
|
||||
}
|
||||
}
|
||||
|
||||
static void paxb_ib_regs_bypass(void)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0; i < paxb->num_cores; i++) {
|
||||
if (!pcie_core_needs_enable(i))
|
||||
continue;
|
||||
|
||||
/* Configure Default IMAP window */
|
||||
mmio_write_32(PAXB_OFFSET(i) + PAXB_0_DEFAULT_IMAP,
|
||||
DEFAULT_ADDR_INVALID);
|
||||
mmio_write_32(PAXB_OFFSET(i) + PAXB_0_DEFAULT_IMAP_AXUSER,
|
||||
IMAP_AXUSER);
|
||||
mmio_write_32(PAXB_OFFSET(i) + PAXB_0_DEFAULT_IMAP_AXCACHE,
|
||||
IMAP_AXCACHE);
|
||||
|
||||
/* Configure MSI IMAP window */
|
||||
mmio_setbits_32(PAXB_OFFSET(i) +
|
||||
PAXB_IMAP0_REGS_TYPE_OFFSET,
|
||||
0x1);
|
||||
mmio_write_32(PAXB_OFFSET(i) + PAXB_IARR0_BASE_OFFSET,
|
||||
GITS_TRANSLATER | OARR_VALID);
|
||||
for (j = 0; j < PAXB_MAX_IMAP_WINDOWS; j++) {
|
||||
mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP0_OFFSET(j),
|
||||
(GITS_TRANSLATER +
|
||||
(j * PAXB_IMAP0_WINDOW_SIZE)) |
|
||||
IMAP_VALID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void paxb_ib_regs_init(void)
|
||||
{
|
||||
unsigned int core_idx;
|
||||
|
||||
for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
|
||||
if (!pcie_core_needs_enable(core_idx))
|
||||
continue;
|
||||
|
||||
/* initialize IARR2 to zero */
|
||||
mmio_write_32(PAXB_OFFSET(core_idx) + PAXB_IARR2_LOWER_OFFSET,
|
||||
0x0);
|
||||
mmio_setbits_32(PAXB_OFFSET(core_idx) +
|
||||
PAXB_IMAP0_REGS_TYPE_OFFSET,
|
||||
0x1);
|
||||
}
|
||||
}
|
||||
|
||||
static void paxb_cfg_apb_timeout(void)
|
||||
{
|
||||
unsigned int core_idx;
|
||||
|
||||
for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
|
||||
if (!pcie_core_needs_enable(core_idx))
|
||||
continue;
|
||||
|
||||
/* allow unlimited timeout */
|
||||
mmio_write_32(PAXB_OFFSET(core_idx) +
|
||||
PAXB_APB_TIMEOUT_COUNT_OFFSET,
|
||||
0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
static void paxb_smmu_cfg(void)
|
||||
{
|
||||
unsigned int core_idx;
|
||||
uint32_t offset;
|
||||
uint32_t val;
|
||||
|
||||
for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
|
||||
if (!pcie_core_needs_enable(core_idx))
|
||||
continue;
|
||||
|
||||
offset = core_idx * PCIE_CORE_PWR_OFFSET;
|
||||
val = mmio_read_32(PCIE_PAXB_SMMU_SID_CFG + offset);
|
||||
val &= ~(0xFFF00);
|
||||
val |= (PAXB_SMMU_SID_CFG_FUN_WIDTH |
|
||||
PAXB_SMMU_SID_CFG_DEV_WIDTH |
|
||||
PAXB_SMMU_SID_CFG_BUS_WIDTH);
|
||||
mmio_write_32(PCIE_PAXB_SMMU_SID_CFG + offset, val);
|
||||
val = mmio_read_32(PCIE_PAXB_SMMU_SID_CFG + offset);
|
||||
VERBOSE("smmu cfg reg 0x%x\n", val);
|
||||
}
|
||||
}
|
||||
|
||||
static void paxb_cfg_coherency(void)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0; i < paxb->num_cores; i++) {
|
||||
if (!pcie_core_needs_enable(i))
|
||||
continue;
|
||||
|
||||
#ifdef USE_DDR
|
||||
mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP2_OFFSET,
|
||||
IMAP_ARCACHE | IMAP_AWCACHE);
|
||||
#endif
|
||||
|
||||
mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP0_0_AXUSER_OFFSET,
|
||||
IMAP_AXUSER);
|
||||
|
||||
mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP2_AXUSER_OFFSET,
|
||||
IMAP_AXUSER);
|
||||
|
||||
for (j = 0; j < PAXB_MAX_IMAP_WINDOWS; j++) {
|
||||
#ifdef USE_DDR
|
||||
mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP3_OFFSET(j),
|
||||
IMAP_ARCACHE | IMAP_AWCACHE);
|
||||
mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP4_OFFSET(j),
|
||||
IMAP_ARCACHE | IMAP_AWCACHE);
|
||||
#endif
|
||||
/* zero out IMAP0 mapping windows for MSI/MSI-X */
|
||||
mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP0_OFFSET(j),
|
||||
0x0);
|
||||
|
||||
mmio_write_32(PAXB_OFFSET(i) +
|
||||
PAXB_IMAP3_0_AXUSER_OFFSET(j),
|
||||
IMAP_AXUSER);
|
||||
mmio_write_32(PAXB_OFFSET(i) +
|
||||
PAXB_IMAP4_0_AXUSER_OFFSET(j),
|
||||
IMAP_AXUSER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function configures all PAXB related blocks to allow non-secure access
|
||||
*/
|
||||
void paxb_ns_init(enum paxb_type type)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
switch (type) {
|
||||
case PAXB_SR:
|
||||
for (reg = 0; reg < ARRAY_SIZE(paxb_sec_reg_offset); reg++) {
|
||||
|
||||
mmio_setbits_32(SR_PCIE_NIC_SECURITY_BASE +
|
||||
paxb_sec_reg_offset[reg], 0x1);
|
||||
}
|
||||
/* Enabled all PAXB's relevant IDM blocks access in non-secure mode */
|
||||
mmio_setbits_32(SR_PCIE_NIC_SECURITY_BASE + PAXB_SECURITY_IDM_OFFSET,
|
||||
0xffff);
|
||||
break;
|
||||
case PAXB_NS3Z:
|
||||
mmio_setbits_32(NS3Z_PCIE_NIC_SECURITY_BASE +
|
||||
paxb_sec_reg_offset[0], 0x1);
|
||||
mmio_setbits_32(NS3Z_PCIE_NIC_SECURITY_BASE +
|
||||
PAXB_SECURITY_IDM_OFFSET, 0xffff);
|
||||
mmio_setbits_32(NS3Z_PCIE_NIC_SECURITY_BASE +
|
||||
PAXB_SECURITY_APB_OFFSET, 0x7);
|
||||
mmio_setbits_32(NS3Z_PCIE_NIC_SECURITY_BASE +
|
||||
PAXB_SECURITY_ECAM_OFFSET, 0x1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int paxb_set_config(void)
|
||||
{
|
||||
paxb = paxb_get_config(sr);
|
||||
if (paxb)
|
||||
return 0;
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
void paxb_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = paxb_set_config();
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
paxb_ns_init(paxb->type);
|
||||
|
||||
ret = pcie_cores_init();
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
if (paxb->phy_init) {
|
||||
ret = paxb->phy_init();
|
||||
if (ret)
|
||||
return;
|
||||
}
|
||||
|
||||
paxb_cfg_dev_id();
|
||||
paxb_cfg_tgt_trn();
|
||||
paxb_cfg_pdl_ctrl();
|
||||
if (paxb->type == PAXB_SR) {
|
||||
paxb_ib_regs_init();
|
||||
paxb_cfg_coherency();
|
||||
} else
|
||||
paxb_ib_regs_bypass();
|
||||
|
||||
paxb_cfg_apb_timeout();
|
||||
paxb_smmu_cfg();
|
||||
paxb_cfg_clkreq();
|
||||
paxb_rc_link_init();
|
||||
|
||||
/* Stingray Doesn't support LTR */
|
||||
paxb_cfg_LTR(false);
|
||||
paxb_cfg_dl_active(true);
|
||||
|
||||
paxb_cfg_mps();
|
||||
|
||||
#ifdef PAXB_LINKUP
|
||||
paxb_start_link_up();
|
||||
#endif
|
||||
INFO("PAXB init done\n");
|
||||
}
|
267
plat/brcm/board/stingray/src/paxc.c
Normal file
267
plat/brcm/board/stingray/src/paxc.c
Normal file
@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Copyright (c) 2017 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <iommu.h>
|
||||
#include <platform_def.h>
|
||||
#include <sr_utils.h>
|
||||
|
||||
#define PAXC_BASE 0x60400000
|
||||
#define PAXC_AXI_CFG_PF 0x10
|
||||
#define PAXC_AXI_CFG_PF_OFFSET(pf) (PAXC_AXI_CFG_PF + (pf) * 4)
|
||||
#define PAXC_ARPROT_PF_CFG 0x40
|
||||
#define PAXC_AWPROT_PF_CFG 0x44
|
||||
|
||||
#define PAXC_ARQOS_PF_CFG 0x48
|
||||
#define PAXC_ARQOS_VAL 0xaaaaaaaa
|
||||
|
||||
#define PAXC_AWQOS_PF_CFG 0x4c
|
||||
#define PAXC_AWQOS_VAL 0xeeeeeeee
|
||||
|
||||
#define PAXC_CFG_IND_ADDR_OFFSET 0x1f0
|
||||
#define PAXC_CFG_IND_ADDR_MASK 0xffc
|
||||
#define PAXC_CFG_IND_DATA_OFFSET 0x1f4
|
||||
|
||||
/* offsets for PAXC root complex configuration space registers */
|
||||
|
||||
#define PAXC_CFG_ID_OFFSET 0x434
|
||||
#define PAXC_RC_VENDOR_ID 0x14e4
|
||||
#define PAXC_RC_VENDOR_ID_SHIFT 16
|
||||
|
||||
#define PAXC_RC_DEVICE_ID 0xd750
|
||||
|
||||
#define PAXC_CFG_LINK_CAP_OFFSET 0x4dc
|
||||
#define PAXC_RC_LINK_CAP_SPD_SHIFT 0
|
||||
#define PAXC_RC_LINK_CAP_SPD_MASK (0xf << PAXC_RC_LINK_CAP_SPD_SHIFT)
|
||||
#define PAXC_RC_LINK_CAP_SPD 3
|
||||
#define PAXC_RC_LINK_CAP_WIDTH_SHIFT 4
|
||||
#define PAXC_RC_LINK_CAP_WIDTH_MASK (0x1f << PAXC_RC_LINK_CAP_WIDTH_SHIFT)
|
||||
#define PAXC_RC_LINK_CAP_WIDTH 16
|
||||
|
||||
/* offsets for MHB registers */
|
||||
|
||||
#define MHB_BASE 0x60401000
|
||||
#define MHB_MEM_PWR_STATUS_PAXC (MHB_BASE + 0x1c0)
|
||||
#define MHB_PWR_ARR_POWERON 0x8
|
||||
#define MHB_PWR_ARR_POWEROK 0x4
|
||||
#define MHB_PWR_POWERON 0x2
|
||||
#define MHB_PWR_POWEROK 0x1
|
||||
#define MHB_PWR_STATUS_MASK (MHB_PWR_ARR_POWERON | \
|
||||
MHB_PWR_ARR_POWEROK | \
|
||||
MHB_PWR_POWERON | \
|
||||
MHB_PWR_POWEROK)
|
||||
|
||||
/* max number of PFs from Nitro that PAXC sees */
|
||||
#define MAX_NR_NITRO_PF 8
|
||||
|
||||
#ifdef EMULATION_SETUP
|
||||
static void paxc_reg_dump(void)
|
||||
{
|
||||
}
|
||||
#else
|
||||
/* total number of PAXC registers */
|
||||
#define NR_PAXC_REGS 53
|
||||
static void paxc_reg_dump(void)
|
||||
{
|
||||
uint32_t idx, offset = 0;
|
||||
|
||||
VERBOSE("PAXC register dump start\n");
|
||||
for (idx = 0; idx < NR_PAXC_REGS; idx++, offset += 4)
|
||||
VERBOSE("offset: 0x%x val: 0x%x\n", offset,
|
||||
mmio_read_32(PAXC_BASE + offset));
|
||||
VERBOSE("PAXC register dump end\n");
|
||||
}
|
||||
#endif /* EMULATION_SETUP */
|
||||
|
||||
#ifdef EMULATION_SETUP
|
||||
static void mhb_reg_dump(void)
|
||||
{
|
||||
}
|
||||
#else
|
||||
#define NR_MHB_REGS 227
|
||||
static void mhb_reg_dump(void)
|
||||
{
|
||||
uint32_t idx, offset = 0;
|
||||
|
||||
VERBOSE("MHB register dump start\n");
|
||||
for (idx = 0; idx < NR_MHB_REGS; idx++, offset += 4)
|
||||
VERBOSE("offset: 0x%x val: 0x%x\n", offset,
|
||||
mmio_read_32(MHB_BASE + offset));
|
||||
VERBOSE("MHB register dump end\n");
|
||||
}
|
||||
#endif /* EMULATION_SETUP */
|
||||
|
||||
static void paxc_rc_cfg_write(uint32_t where, uint32_t val)
|
||||
{
|
||||
mmio_write_32(PAXC_BASE + PAXC_CFG_IND_ADDR_OFFSET,
|
||||
where & PAXC_CFG_IND_ADDR_MASK);
|
||||
mmio_write_32(PAXC_BASE + PAXC_CFG_IND_DATA_OFFSET, val);
|
||||
}
|
||||
|
||||
static uint32_t paxc_rc_cfg_read(uint32_t where)
|
||||
{
|
||||
mmio_write_32(PAXC_BASE + PAXC_CFG_IND_ADDR_OFFSET,
|
||||
where & PAXC_CFG_IND_ADDR_MASK);
|
||||
return mmio_read_32(PAXC_BASE + PAXC_CFG_IND_DATA_OFFSET);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to program PAXC root complex link capability register
|
||||
*/
|
||||
static void paxc_cfg_link_cap(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = paxc_rc_cfg_read(PAXC_CFG_LINK_CAP_OFFSET);
|
||||
val &= ~(PAXC_RC_LINK_CAP_SPD_MASK | PAXC_RC_LINK_CAP_WIDTH_MASK);
|
||||
val |= (PAXC_RC_LINK_CAP_SPD << PAXC_RC_LINK_CAP_SPD_SHIFT) |
|
||||
(PAXC_RC_LINK_CAP_WIDTH << PAXC_RC_LINK_CAP_WIDTH_SHIFT);
|
||||
paxc_rc_cfg_write(PAXC_CFG_LINK_CAP_OFFSET, val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to program PAXC root complex vendor ID and device ID
|
||||
*/
|
||||
static void paxc_cfg_id(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = (PAXC_RC_VENDOR_ID << PAXC_RC_VENDOR_ID_SHIFT) |
|
||||
PAXC_RC_DEVICE_ID;
|
||||
paxc_rc_cfg_write(PAXC_CFG_ID_OFFSET, val);
|
||||
}
|
||||
|
||||
void paxc_init(void)
|
||||
{
|
||||
unsigned int pf_index;
|
||||
unsigned int val;
|
||||
|
||||
val = mmio_read_32(MHB_MEM_PWR_STATUS_PAXC);
|
||||
if ((val & MHB_PWR_STATUS_MASK) != MHB_PWR_STATUS_MASK) {
|
||||
INFO("PAXC not powered\n");
|
||||
return;
|
||||
}
|
||||
|
||||
paxc_cfg_id();
|
||||
paxc_cfg_link_cap();
|
||||
|
||||
paxc_reg_dump();
|
||||
mhb_reg_dump();
|
||||
|
||||
#ifdef USE_DDR
|
||||
/*
|
||||
* Set AWCACHE and ARCACHE to 0xff (Cacheable write-back,
|
||||
* allocate on both reads and writes) per
|
||||
* recommendation from the ASIC team
|
||||
*/
|
||||
val = 0xff;
|
||||
#else
|
||||
/* disable IO cache if non-DDR memory is used, e.g., external SRAM */
|
||||
val = 0x0;
|
||||
#endif
|
||||
for (pf_index = 0; pf_index < MAX_NR_NITRO_PF; pf_index++)
|
||||
mmio_write_32(PAXC_BASE + PAXC_AXI_CFG_PF_OFFSET(pf_index),
|
||||
val);
|
||||
|
||||
/*
|
||||
* Set ARPROT and AWPROT to enable non-secure access from
|
||||
* PAXC to all PFs, PF0 to PF7
|
||||
*/
|
||||
mmio_write_32(PAXC_BASE + PAXC_ARPROT_PF_CFG, 0x22222222);
|
||||
mmio_write_32(PAXC_BASE + PAXC_AWPROT_PF_CFG, 0x22222222);
|
||||
|
||||
mmio_write_32(PAXC_BASE + PAXC_ARQOS_PF_CFG, PAXC_ARQOS_VAL);
|
||||
mmio_write_32(PAXC_BASE + PAXC_AWQOS_PF_CFG, PAXC_AWQOS_VAL);
|
||||
|
||||
INFO("PAXC init done\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* These defines do not match the regfile but they are renamed in a way such
|
||||
* that they are much more readible
|
||||
*/
|
||||
|
||||
#define MHB_NIC_SECURITY_BASE 0x60500000
|
||||
#define MHB_NIC_PAXC_AXI_NS 0x0008
|
||||
#define MHB_NIC_IDM_NS 0x000c
|
||||
#define MHB_NIC_MHB_APB_NS 0x0010
|
||||
#define MHB_NIC_NITRO_AXI_NS 0x0014
|
||||
#define MHB_NIC_PCIE_AXI_NS 0x0018
|
||||
#define MHB_NIC_PAXC_APB_NS 0x001c
|
||||
#define MHB_NIC_EP_APB_NS 0x0020
|
||||
|
||||
#define MHB_NIC_PAXC_APB_S_IDM_SHIFT 5
|
||||
#define MHB_NIC_EP_APB_S_IDM_SHIFT 4
|
||||
#define MHB_NIC_MHB_APB_S_IDM_SHIFT 3
|
||||
#define MHB_NIC_PAXC_AXI_S_IDM_SHIFT 2
|
||||
#define MHB_NIC_PCIE_AXI_S_IDM_SHIFT 1
|
||||
#define MHB_NIC_NITRO_AXI_S_IDM_SHIFT 0
|
||||
|
||||
#define NIC400_NITRO_TOP_NIC_SECURITY_BASE 0x60d00000
|
||||
|
||||
#define NITRO_NIC_SECURITY_3_SHIFT 0x14
|
||||
#define NITRO_NIC_SECURITY_4_SHIFT 0x18
|
||||
#define NITRO_NIC_SECURITY_5_SHIFT 0x1c
|
||||
#define NITRO_NIC_SECURITY_6_SHIFT 0x20
|
||||
|
||||
void paxc_mhb_ns_init(void)
|
||||
{
|
||||
unsigned int val;
|
||||
uintptr_t mhb_nic_gpv = MHB_NIC_SECURITY_BASE;
|
||||
#ifndef NITRO_SECURE_ACCESS
|
||||
uintptr_t nic400_nitro_gpv = NIC400_NITRO_TOP_NIC_SECURITY_BASE;
|
||||
#endif /* NITRO_SECURE_ACCESS */
|
||||
|
||||
/* set PAXC AXI to allow non-secure access */
|
||||
val = mmio_read_32(mhb_nic_gpv + MHB_NIC_PAXC_AXI_NS);
|
||||
val |= 0x1;
|
||||
mmio_write_32(mhb_nic_gpv + MHB_NIC_PAXC_AXI_NS, val);
|
||||
|
||||
/* set various MHB IDM interfaces to allow non-secure access */
|
||||
val = mmio_read_32(mhb_nic_gpv + MHB_NIC_IDM_NS);
|
||||
val |= (0x1 << MHB_NIC_PAXC_APB_S_IDM_SHIFT);
|
||||
val |= (0x1 << MHB_NIC_EP_APB_S_IDM_SHIFT);
|
||||
val |= (0x1 << MHB_NIC_MHB_APB_S_IDM_SHIFT);
|
||||
val |= (0x1 << MHB_NIC_PAXC_AXI_S_IDM_SHIFT);
|
||||
val |= (0x1 << MHB_NIC_PCIE_AXI_S_IDM_SHIFT);
|
||||
val |= (0x1 << MHB_NIC_NITRO_AXI_S_IDM_SHIFT);
|
||||
mmio_write_32(mhb_nic_gpv + MHB_NIC_IDM_NS, val);
|
||||
|
||||
/* set MHB APB to allow non-secure access */
|
||||
val = mmio_read_32(mhb_nic_gpv + MHB_NIC_MHB_APB_NS);
|
||||
val |= 0x1;
|
||||
mmio_write_32(mhb_nic_gpv + MHB_NIC_MHB_APB_NS, val);
|
||||
|
||||
/* set Nitro AXI to allow non-secure access */
|
||||
val = mmio_read_32(mhb_nic_gpv + MHB_NIC_NITRO_AXI_NS);
|
||||
val |= 0x1;
|
||||
mmio_write_32(mhb_nic_gpv + MHB_NIC_NITRO_AXI_NS, val);
|
||||
|
||||
/* set PCIe AXI to allow non-secure access */
|
||||
val = mmio_read_32(mhb_nic_gpv + MHB_NIC_PCIE_AXI_NS);
|
||||
val |= 0x1;
|
||||
mmio_write_32(mhb_nic_gpv + MHB_NIC_PCIE_AXI_NS, val);
|
||||
|
||||
/* set PAXC APB to allow non-secure access */
|
||||
val = mmio_read_32(mhb_nic_gpv + MHB_NIC_PAXC_APB_NS);
|
||||
val |= 0x1;
|
||||
mmio_write_32(mhb_nic_gpv + MHB_NIC_PAXC_APB_NS, val);
|
||||
|
||||
/* set EP APB to allow non-secure access */
|
||||
val = mmio_read_32(mhb_nic_gpv + MHB_NIC_EP_APB_NS);
|
||||
val |= 0x1;
|
||||
mmio_write_32(mhb_nic_gpv + MHB_NIC_EP_APB_NS, val);
|
||||
|
||||
#ifndef NITRO_SECURE_ACCESS
|
||||
/* Set NIC400 to allow non-secure access */
|
||||
mmio_setbits_32(nic400_nitro_gpv + NITRO_NIC_SECURITY_3_SHIFT, 0x1);
|
||||
mmio_setbits_32(nic400_nitro_gpv + NITRO_NIC_SECURITY_4_SHIFT, 0x1);
|
||||
mmio_setbits_32(nic400_nitro_gpv + NITRO_NIC_SECURITY_5_SHIFT, 0x1);
|
||||
mmio_setbits_32(nic400_nitro_gpv + NITRO_NIC_SECURITY_6_SHIFT, 0x1);
|
||||
#endif /* NITRO_SECURE_ACCESS */
|
||||
}
|
144
plat/brcm/board/stingray/src/sdio.c
Normal file
144
plat/brcm/board/stingray/src/sdio.c
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <sdio.h>
|
||||
#include <sr_def.h>
|
||||
#include <sr_utils.h>
|
||||
|
||||
const SDIO_CFG sr_sdio0_cfg = {
|
||||
.cfg_base = SR_IPROC_SDIO0_CFG_BASE,
|
||||
.sid_base = SR_IPROC_SDIO0_SID_BASE,
|
||||
.io_ctrl_base = SR_IPROC_SDIO0_IOCTRL_BASE,
|
||||
.pad_base = SR_IPROC_SDIO0_PAD_BASE,
|
||||
};
|
||||
const SDIO_CFG sr_sdio1_cfg = {
|
||||
.cfg_base = SR_IPROC_SDIO1_CFG_BASE,
|
||||
.sid_base = SR_IPROC_SDIO1_SID_BASE,
|
||||
.io_ctrl_base = SR_IPROC_SDIO1_IOCTRL_BASE,
|
||||
.pad_base = SR_IPROC_SDIO1_PAD_BASE,
|
||||
};
|
||||
|
||||
void brcm_stingray_sdio_init(void)
|
||||
{
|
||||
unsigned int val;
|
||||
const SDIO_CFG *sdio0_cfg, *sdio1_cfg;
|
||||
|
||||
sdio0_cfg = &sr_sdio0_cfg;
|
||||
sdio1_cfg = &sr_sdio1_cfg;
|
||||
|
||||
INFO("set sdio0 caps\n");
|
||||
/* SDIO0 CAPS0 */
|
||||
val = SDIO0_CAP0_CFG;
|
||||
INFO("caps0 0x%x\n", val);
|
||||
mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_CAP0, val);
|
||||
|
||||
/* SDIO0 CAPS1 */
|
||||
val = SDIO0_CAP1_CFG;
|
||||
INFO("caps1 0x%x\n", val);
|
||||
mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_CAP1, val);
|
||||
|
||||
mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_0,
|
||||
SDIO_PRESETVAL0);
|
||||
mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_1,
|
||||
SDIO_PRESETVAL1);
|
||||
mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_2,
|
||||
SDIO_PRESETVAL2);
|
||||
mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_3,
|
||||
SDIO_PRESETVAL3);
|
||||
mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_4,
|
||||
SDIO_PRESETVAL4);
|
||||
|
||||
val = SR_SID_VAL(0x3, 0x0, 0x2) << SDIO_SID_SHIFT;
|
||||
mmio_write_32(sdio0_cfg->sid_base + ICFG_SDIO_SID_ARADDR, val);
|
||||
mmio_write_32(sdio0_cfg->sid_base + ICFG_SDIO_SID_AWADDR, val);
|
||||
|
||||
val = mmio_read_32(sdio0_cfg->io_ctrl_base);
|
||||
val &= ~(0xff << 23); /* Clear ARCACHE and AWCACHE */
|
||||
val |= (0xb7 << 23); /* Set ARCACHE and AWCACHE */
|
||||
mmio_write_32(sdio0_cfg->io_ctrl_base, val);
|
||||
|
||||
mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_CLK,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA0,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA1,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA2,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA3,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA4,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA5,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA6,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA7,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_CMD,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
|
||||
INFO("set sdio1 caps\n");
|
||||
|
||||
/* SDIO1 CAPS0 */
|
||||
val = SDIO1_CAP0_CFG;
|
||||
INFO("caps0 0x%x\n", val);
|
||||
mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_CAP0, val);
|
||||
/* SDIO1 CAPS1 */
|
||||
val = SDIO1_CAP1_CFG;
|
||||
INFO("caps1 0x%x\n", val);
|
||||
mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_CAP1, val);
|
||||
|
||||
mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_0,
|
||||
SDIO_PRESETVAL0);
|
||||
mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_1,
|
||||
SDIO_PRESETVAL1);
|
||||
mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_2,
|
||||
SDIO_PRESETVAL2);
|
||||
mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_3,
|
||||
SDIO_PRESETVAL3);
|
||||
mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_4,
|
||||
SDIO_PRESETVAL4);
|
||||
|
||||
val = SR_SID_VAL(0x3, 0x0, 0x3) << SDIO_SID_SHIFT;
|
||||
mmio_write_32(sdio1_cfg->sid_base + ICFG_SDIO_SID_ARADDR, val);
|
||||
mmio_write_32(sdio1_cfg->sid_base + ICFG_SDIO_SID_AWADDR, val);
|
||||
|
||||
val = mmio_read_32(sdio1_cfg->io_ctrl_base);
|
||||
val &= ~(0xff << 23); /* Clear ARCACHE and AWCACHE */
|
||||
val |= (0xb7 << 23); /* Set ARCACHE and AWCACHE */
|
||||
mmio_write_32(sdio1_cfg->io_ctrl_base, val);
|
||||
|
||||
mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_CLK,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA0,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA1,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA2,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA3,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA4,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA5,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA6,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA7,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_CMD,
|
||||
PAD_SDIO_MASK, PAD_SDIO_VALUE);
|
||||
|
||||
INFO("sdio init done\n");
|
||||
}
|
806
plat/brcm/board/stingray/src/sr_paxb_phy.c
Normal file
806
plat/brcm/board/stingray/src/sr_paxb_phy.c
Normal file
@ -0,0 +1,806 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <paxb.h>
|
||||
#include <sr_def.h>
|
||||
#include <sr_utils.h>
|
||||
|
||||
/* total number of PCIe Phys */
|
||||
#define NUM_OF_PCIE_SERDES 8
|
||||
|
||||
#define CFG_RC_PMI_ADDR 0x1130
|
||||
#define PMI_RX_TERM_SEQ ((0x1 << 27) | (0x1ff << 16) | (0xd090))
|
||||
#define PMI_RX_TERM_VAL 0x4c00
|
||||
#define PMI_PLL_CTRL_4 0xd0b4
|
||||
#define PMI_SERDES_CLK_ENABLE (1 << 12)
|
||||
|
||||
#define WAR_PLX_PRESET_PARITY_FAIL
|
||||
|
||||
#define CFG_RC_REG_PHY_CTL_10 0x1838
|
||||
#define PHY_CTL_10_GEN3_MATCH_PARITY (1 << 15)
|
||||
|
||||
#define PMI_X8_CORE0_7_PATCH_SEQ ((0x1 << 27) | (0x1ff << 16) | (0xd2a5))
|
||||
#define PMI_X8_CORE0_7_PATCH_VAL 0xd864
|
||||
|
||||
#define PMI_ADDR_BCAST(addr) ((0x1 << 27) | (0x1ff << 16) | (addr))
|
||||
#define PMI_ADDR_LANE0(addr) ((0x1 << 27) | (addr))
|
||||
#define PMI_ADDR_LANE1(addr) ((0x1 << 27) | (0x1 << 16) | (addr))
|
||||
|
||||
#define MERLIN16_PCIE_BLK2_PWRMGMT_7 ((0x1 << 27) | (0x1ff << 16) | 0x1208)
|
||||
#define MERLIN16_PCIE_BLK2_PWRMGMT_8 ((0x1 << 27) | (0x1ff << 16) | 0x1209)
|
||||
#define MERLIN16_AMS_TX_CTRL_5 ((0x1 << 27) | (0x1ff << 16) | 0xd0a5)
|
||||
#define MERLIN16_AMS_TX_CTRL_5_VAL \
|
||||
((1 << 13) | (1 << 12) | (1 << 11) | (1 << 10))
|
||||
#define MERLIN16_PCIE_BLK2_PWRMGMT_7_VAL 0x96
|
||||
#define MERLIN16_PCIE_BLK2_PWRMGMT_8_VAL 0x12c
|
||||
|
||||
#define CFG_RC_PMI_WDATA 0x1134
|
||||
#define CFG_RC_WCMD_SHIFT 31
|
||||
#define CFG_RC_WCMD_MASK ((uint32_t)1U << CFG_RC_WCMD_SHIFT)
|
||||
#define CFG_RC_RCMD_SHIFT 30
|
||||
#define CFG_RC_RCMD_MASK ((uint32_t)1U << CFG_RC_RCMD_SHIFT)
|
||||
#define CFG_RC_RWCMD_MASK (CFG_RC_RCMD_MASK | CFG_RC_WCMD_MASK)
|
||||
#define CFG_RC_PMI_RDATA 0x1138
|
||||
#define CFG_RC_RACK_SHIFT 31
|
||||
#define CFG_RC_RACK_MASK ((uint32_t)1U << CFG_RC_RACK_SHIFT)
|
||||
|
||||
/* allow up to 5 ms for PMI write to finish */
|
||||
#define PMI_TIMEOUT_MS 5
|
||||
|
||||
/* in 2x8 RC mode, one needs to patch up Serdes 3 and 7 for link to come up */
|
||||
#define SERDES_PATCH_PIPEMUX_INDEX 0x3
|
||||
#define SERDES_PATCH_INDEX 0x8
|
||||
|
||||
#define DSC_UC_CTRL 0xd00d
|
||||
#define DSC_UC_CTRL_RDY_CMD (1 << 7)
|
||||
#define LANE_DBG_RST_CTRL 0xd164
|
||||
#define UC_A_CLK_CTRL0 0xd200
|
||||
#define UC_A_RST_CTRL0 0xd201
|
||||
#define UC_A_AHB_CTRL0 0xd202
|
||||
#define UC_A_AHB_STAT0 0xd203
|
||||
#define UC_A_AHB_WADDR_LSW 0xd204
|
||||
#define UC_A_AHB_WADDR_MSW 0xd205
|
||||
#define UC_A_AHB_WDATA_LSW 0xd206
|
||||
#define UC_A_AHB_WDATA_MSW 0xd207
|
||||
#define UC_A_AHB_RADDR_LSW 0xd208
|
||||
#define UC_A_AHB_RADDR_MSW 0xd209
|
||||
#define UC_A_AHB_RDATA_LSW 0xd20a
|
||||
#define UC_A_AHB_RDATA_MSW 0xd20b
|
||||
#define UC_VERSION_NUM 0xd230
|
||||
#define DSC_SM_CTL22 0xd267
|
||||
#define UC_DBG1 0xd251
|
||||
|
||||
#define LOAD_UC_CHECK 0
|
||||
#define UC_RAM_INIT_TIMEOUT 100
|
||||
#define UC_RAM_CONTROL 0xd225
|
||||
#define UC_INIT_TIMEOUT 100
|
||||
#define SIZE_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
|
||||
#define SZ_4 4
|
||||
#define GET_2_BYTES(p, i) ((uint16_t)p[i] | (uint16_t)p[i+1] << 8)
|
||||
|
||||
/*
|
||||
* List of PCIe LCPLL related registers
|
||||
*
|
||||
* LCPLL channel 0 provides the Serdes pad clock when running in RC mode
|
||||
*/
|
||||
#define PCIE_LCPLL_BASE 0x40000000
|
||||
|
||||
#define PCIE_LCPLL_CTRL0_OFFSET 0x00
|
||||
#define PCIE_LCPLL_RESETB_SHIFT 31
|
||||
#define PCIE_LCPLL_RESETB_MASK BIT(PCIE_LCPLL_RESETB_SHIFT)
|
||||
#define PCIE_LCPLL_P_RESETB_SHIFT 30
|
||||
#define PCIE_LCPLL_P_RESETB_MASK BIT(PCIE_LCPLL_P_RESETB_SHIFT)
|
||||
|
||||
#define PCIE_LCPLL_CTRL3_OFFSET 0x0c
|
||||
#define PCIE_LCPLL_EN_CTRL_SHIFT 16
|
||||
#define PCIE_LCPLL_CM_ENA 0x1a
|
||||
#define PCIE_LCPLL_CM_BUF_ENA 0x18
|
||||
#define PCIE_LCPLL_D2C2_ENA 0x2
|
||||
#define PCIE_LCPLL_REF_CLK_SHIFT 1
|
||||
#define PCIE_LCPLL_REF_CLK_MASK BIT(PCIE_LCPLL_REF_CLK_SHIFT)
|
||||
#define PCIE_LCPLL_CTRL13_OFFSET 0x34
|
||||
#define PCIE_LCPLL_D2C2_CTRL_SHIFT 16
|
||||
#define PCIE_LCPLL_D2C2_TERM_DISC 0xe0
|
||||
|
||||
#define PCIE_LCPLL_STATUS_OFFSET 0x40
|
||||
#define PCIE_LCPLL_LOCK_SHIFT 12
|
||||
#define PCIE_LCPLL_LOCK_MASK BIT(PCIE_LCPLL_LOCK_SHIFT)
|
||||
|
||||
#define PCIE_PIPE_MUX_RC_MODE_OVERRIDE_CFG 0x114
|
||||
#define PCIE_TX_CLKMASTER_CTRL_OVERRIDE_CFG 0x11c
|
||||
|
||||
/* wait 500 microseconds for PCIe LCPLL to power up */
|
||||
#define PCIE_LCPLL_DELAY_US 500
|
||||
|
||||
/* allow up to 5 ms for PCIe LCPLL VCO to lock */
|
||||
#define PCIE_LCPLL_TIMEOUT_MS 5
|
||||
|
||||
#define PCIE_PIPE_MUX_CONFIGURATION_CFG 0x4000010c
|
||||
|
||||
#define PCIE_PIPEMUX_SHIFT 19
|
||||
#define PCIE_PIPEMUX_MASK 0xf
|
||||
|
||||
/* keep track of PIPEMUX index to use */
|
||||
static unsigned int pipemux_idx;
|
||||
|
||||
/*
|
||||
* PCIe PIPEMUX lookup table
|
||||
*
|
||||
* Each array index represents a PIPEMUX strap setting
|
||||
* The array element represents a bitmap where a set bit means the PCIe core
|
||||
* needs to be enabled as RC
|
||||
*/
|
||||
static uint8_t pipemux_table[] = {
|
||||
/* PIPEMUX = 0, EP 1x16 */
|
||||
0x00,
|
||||
/* PIPEMUX = 1, EP 1x8 + RC 1x8, core 7 */
|
||||
0x80,
|
||||
/* PIPEMUX = 2, EP 4x4 */
|
||||
0x00,
|
||||
/* PIPEMUX = 3, RC 2x8, cores 0, 7 */
|
||||
0x81,
|
||||
/* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */
|
||||
0xc3,
|
||||
/* PIPEMUX = 5, RC 8x2, all 8 cores */
|
||||
0xff,
|
||||
/* PIPEMUX = 6, RC 3x4 + 2x2, cores 0, 2, 3, 6, 7 */
|
||||
0xcd,
|
||||
/* PIPEMUX = 7, RC 1x4 + 6x2, cores 0, 2, 3, 4, 5, 6, 7 */
|
||||
0xfd,
|
||||
/* PIPEMUX = 8, EP 1x8 + RC 4x2, cores 4, 5, 6, 7 */
|
||||
0xf0,
|
||||
/* PIPEMUX = 9, EP 1x8 + RC 2x4, cores 6, 7 */
|
||||
0xc0,
|
||||
/* PIPEMUX = 10, EP 2x4 + RC 2x4, cores 1, 6 */
|
||||
0x42,
|
||||
/* PIPEMUX = 11, EP 2x4 + RC 4x2, cores 2, 3, 4, 5 */
|
||||
0x3c,
|
||||
/* PIPEMUX = 12, EP 1x4 + RC 6x2, cores 2, 3, 4, 5, 6, 7 */
|
||||
0xfc,
|
||||
/* PIPEMUX = 13, RC 2x4 + RC 1x4 + 2x2, cores 2, 3, 6 */
|
||||
0x4c,
|
||||
};
|
||||
|
||||
/*
|
||||
* Return 1 if pipemux strap is supported
|
||||
*/
|
||||
static int pipemux_strap_is_valid(uint32_t pipemux)
|
||||
{
|
||||
if (pipemux < ARRAY_SIZE(pipemux_table))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the PCIe PIPEMUX from strap
|
||||
*/
|
||||
static uint32_t pipemux_strap_read(void)
|
||||
{
|
||||
uint32_t pipemux;
|
||||
|
||||
pipemux = mmio_read_32(PCIE_PIPE_MUX_CONFIGURATION_CFG);
|
||||
pipemux &= PCIE_PIPEMUX_MASK;
|
||||
if (pipemux == PCIE_PIPEMUX_MASK) {
|
||||
/* read the PCIe PIPEMUX strap setting */
|
||||
pipemux = mmio_read_32(CDRU_CHIP_STRAP_DATA_LSW);
|
||||
pipemux >>= PCIE_PIPEMUX_SHIFT;
|
||||
pipemux &= PCIE_PIPEMUX_MASK;
|
||||
}
|
||||
|
||||
return pipemux;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the PIPEMUX index (set for each boot)
|
||||
*/
|
||||
static void pipemux_save_index(unsigned int idx)
|
||||
{
|
||||
pipemux_idx = idx;
|
||||
}
|
||||
|
||||
static int paxb_sr_core_needs_enable(unsigned int core_idx)
|
||||
{
|
||||
return !!((pipemux_table[pipemux_idx] >> core_idx) & 0x1);
|
||||
}
|
||||
|
||||
static int pipemux_sr_init(void)
|
||||
{
|
||||
uint32_t pipemux;
|
||||
|
||||
/* read the PCIe PIPEMUX strap setting */
|
||||
pipemux = pipemux_strap_read();
|
||||
if (!pipemux_strap_is_valid(pipemux)) {
|
||||
ERROR("Invalid PCIe PIPEMUX strap %u\n", pipemux);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* no PCIe RC is needed */
|
||||
if (!pipemux_table[pipemux]) {
|
||||
WARN("PIPEMUX indicates no PCIe RC required\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* save the PIPEMUX strap */
|
||||
pipemux_save_index(pipemux);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* PCIe RC serdes link width
|
||||
*
|
||||
* The array is first organized in rows as indexed by the PIPEMUX setting.
|
||||
* Within each row, eight lane width entries are specified -- one entry
|
||||
* per PCIe core, from 0 to 7.
|
||||
*
|
||||
* Note: The EP lanes/cores are not mapped in this table! EP cores are
|
||||
* controlled and thus configured by Nitro.
|
||||
*/
|
||||
static uint8_t link_width_table[][NUM_OF_SR_PCIE_CORES] = {
|
||||
/* PIPEMUX = 0, EP 1x16 */
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
/* PIPEMUX = 1, EP 1x8 + RC 1x8, core 7 */
|
||||
{0, 0, 0, 0, 0, 0, 0, 8},
|
||||
/* PIPEMUX = 2, EP 4x4 */
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
/* PIPEMUX = 3, RC 2x8, cores 0, 7 */
|
||||
{8, 0, 0, 0, 0, 0, 0, 8},
|
||||
/* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */
|
||||
{4, 4, 0, 0, 0, 0, 4, 4},
|
||||
/* PIPEMUX = 5, RC 8x2, all 8 cores */
|
||||
{2, 2, 2, 2, 2, 2, 2, 2},
|
||||
/* PIPEMUX = 6, RC 3x4 (cores 0, 6, 7), RC 2x2 (cores 2, 3) */
|
||||
{4, 0, 2, 2, 0, 0, 4, 4},
|
||||
/* PIPEMUX = 7, RC 1x4 (core 0), RC 6x2 (cores 2, 3, 4, 5, 6, 7 */
|
||||
{4, 0, 2, 2, 2, 2, 2, 2},
|
||||
/* PIPEMUX = 8, EP 1x8 + RC 4x2 (cores 4, 5, 6, 7) */
|
||||
{0, 0, 0, 0, 2, 2, 2, 2},
|
||||
/* PIPEMUX = 9, EP 1x8 + RC 2x4 (cores 6, 7) */
|
||||
{0, 0, 0, 0, 0, 0, 4, 4},
|
||||
/* PIPEMUX = 10, EP 2x4 + RC 2x4 (cores 1, 6) */
|
||||
{0, 4, 0, 0, 0, 0, 4, 0},
|
||||
/* PIPEMUX = 11, EP 2x4 + RC 4x2 (cores 2, 3, 4, 5) */
|
||||
{0, 0, 2, 2, 2, 2, 0, 0},
|
||||
/* PIPEMUX = 12, EP 1x4 + RC 6x2 (cores 2, 3, 4, 5, 6, 7) */
|
||||
{0, 0, 2, 2, 2, 2, 2, 2},
|
||||
/* PIPEMUX = 13, EP 2x4 + RC 1x4 (core 6) + RC 2x2 (cores 2, 3) */
|
||||
{0, 0, 2, 2, 0, 0, 4, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
* function for writes to the Serdes registers through the PMI interface
|
||||
*/
|
||||
static int paxb_pmi_write(unsigned int core_idx, uint32_t pmi, uint32_t val)
|
||||
{
|
||||
uint32_t status;
|
||||
unsigned int timeout = PMI_TIMEOUT_MS;
|
||||
|
||||
paxb_rc_cfg_write(core_idx, CFG_RC_PMI_ADDR, pmi);
|
||||
|
||||
val &= ~CFG_RC_RWCMD_MASK;
|
||||
val |= CFG_RC_WCMD_MASK;
|
||||
paxb_rc_cfg_write(core_idx, CFG_RC_PMI_WDATA, val);
|
||||
|
||||
do {
|
||||
status = paxb_rc_cfg_read(core_idx, CFG_RC_PMI_WDATA);
|
||||
|
||||
/* wait for write command bit to clear */
|
||||
if ((status & CFG_RC_WCMD_MASK) == 0)
|
||||
return 0;
|
||||
} while (--timeout);
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/*
|
||||
* function for reads from the Serdes registers through the PMI interface
|
||||
*/
|
||||
static int paxb_pmi_read(unsigned int core_idx, uint32_t pmi, uint32_t *val)
|
||||
{
|
||||
uint32_t status;
|
||||
unsigned int timeout = PMI_TIMEOUT_MS;
|
||||
|
||||
paxb_rc_cfg_write(core_idx, CFG_RC_PMI_ADDR, pmi);
|
||||
|
||||
paxb_rc_cfg_write(core_idx, CFG_RC_PMI_WDATA, CFG_RC_RCMD_MASK);
|
||||
|
||||
do {
|
||||
status = paxb_rc_cfg_read(core_idx, CFG_RC_PMI_RDATA);
|
||||
|
||||
/* wait for read ack bit set */
|
||||
if ((status & CFG_RC_RACK_MASK)) {
|
||||
*val = paxb_rc_cfg_read(core_idx, CFG_RC_PMI_RDATA);
|
||||
return 0;
|
||||
}
|
||||
} while (--timeout);
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
#ifndef BOARD_PCIE_EXT_CLK
|
||||
/*
|
||||
* PCIe Override clock lookup table
|
||||
*
|
||||
* Each array index represents pcie override clock has been done
|
||||
* by CFW or not.
|
||||
*/
|
||||
static uint8_t pcie_override_clk_table[] = {
|
||||
/* PIPEMUX = 0, EP 1x16 */
|
||||
0x0,
|
||||
/* PIPEMUX = 1, EP 1x8 + RC 1x8, core 7 */
|
||||
0x1,
|
||||
/* PIPEMUX = 2, EP 4x4 */
|
||||
0x0,
|
||||
/* PIPEMUX = 3, RC 2x8, cores 0, 7 */
|
||||
0x0,
|
||||
/* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */
|
||||
0x0,
|
||||
/* PIPEMUX = 5, RC 8x2, all 8 cores */
|
||||
0x0,
|
||||
/* PIPEMUX = 6, RC 3x4 + 2x2, cores 0, 2, 3, 6, 7 */
|
||||
0x0,
|
||||
/* PIPEMUX = 7, RC 1x4 + 6x2, cores 0, 2, 3, 4, 5, 6, 7 */
|
||||
0x0,
|
||||
/* PIPEMUX = 8, EP 1x8 + RC 4x2, cores 4, 5, 6, 7 */
|
||||
0x0,
|
||||
/* PIPEMUX = 9, EP 1x8 + RC 2x4, cores 6, 7 */
|
||||
0x0,
|
||||
/* PIPEMUX = 10, EP 2x4 + RC 2x4, cores 1, 6 */
|
||||
0x0,
|
||||
/* PIPEMUX = 11, EP 2x4 + RC 4x2, cores 2, 3, 4, 5 */
|
||||
0x0,
|
||||
/* PIPEMUX = 12, EP 1x4 + RC 6x2, cores 2, 3, 4, 5, 6, 7 */
|
||||
0x0,
|
||||
/* PIPEMUX = 13, RC 2x4 + RC 1x4 + 2x2, cores 2, 3, 6 */
|
||||
0x0,
|
||||
};
|
||||
|
||||
/*
|
||||
* Bring up LCPLL channel 0 reference clock for PCIe serdes used in RC mode
|
||||
*/
|
||||
static int pcie_lcpll_init(void)
|
||||
{
|
||||
uintptr_t reg;
|
||||
unsigned int timeout = PCIE_LCPLL_TIMEOUT_MS;
|
||||
uint32_t val;
|
||||
|
||||
if (pcie_override_clk_table[pipemux_idx]) {
|
||||
/*
|
||||
* Check rc_mode_override again to avoid halt
|
||||
* because of cfw uninitialized lcpll.
|
||||
*/
|
||||
reg = (uintptr_t)(PCIE_LCPLL_BASE +
|
||||
PCIE_PIPE_MUX_RC_MODE_OVERRIDE_CFG);
|
||||
val = mmio_read_32(reg);
|
||||
if (val & 0x1)
|
||||
return 0;
|
||||
else
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* power on PCIe LCPLL and its LDO */
|
||||
reg = (uintptr_t)CRMU_AON_CTRL1;
|
||||
mmio_setbits_32(reg, CRMU_PCIE_LCPLL_PWR_ON_MASK |
|
||||
CRMU_PCIE_LCPLL_PWRON_LDO_MASK);
|
||||
udelay(PCIE_LCPLL_DELAY_US);
|
||||
|
||||
/* remove isolation */
|
||||
mmio_clrbits_32(reg, CRMU_PCIE_LCPLL_ISO_IN_MASK);
|
||||
udelay(PCIE_LCPLL_DELAY_US);
|
||||
|
||||
/* disconnect termination */
|
||||
reg = (uintptr_t)(PCIE_LCPLL_BASE + PCIE_LCPLL_CTRL13_OFFSET);
|
||||
mmio_setbits_32(reg, PCIE_LCPLL_D2C2_TERM_DISC <<
|
||||
PCIE_LCPLL_D2C2_CTRL_SHIFT);
|
||||
|
||||
/* enable CML buf1/2 and D2C2 */
|
||||
reg = (uintptr_t)(PCIE_LCPLL_BASE + PCIE_LCPLL_CTRL3_OFFSET);
|
||||
mmio_setbits_32(reg, PCIE_LCPLL_CM_ENA << PCIE_LCPLL_EN_CTRL_SHIFT);
|
||||
|
||||
/* select diff clock mux out as ref clock */
|
||||
mmio_clrbits_32(reg, PCIE_LCPLL_REF_CLK_MASK);
|
||||
|
||||
/* delay for 500 microseconds per ASIC spec for PCIe LCPLL */
|
||||
udelay(PCIE_LCPLL_DELAY_US);
|
||||
|
||||
/* now bring PCIe LCPLL out of reset */
|
||||
reg = (uintptr_t)(PCIE_LCPLL_BASE + PCIE_LCPLL_CTRL0_OFFSET);
|
||||
mmio_setbits_32(reg, PCIE_LCPLL_RESETB_MASK);
|
||||
|
||||
/* wait for PLL to lock */
|
||||
reg = (uintptr_t)(PCIE_LCPLL_BASE + PCIE_LCPLL_STATUS_OFFSET);
|
||||
do {
|
||||
val = mmio_read_32(reg);
|
||||
if ((val & PCIE_LCPLL_LOCK_MASK) == PCIE_LCPLL_LOCK_MASK) {
|
||||
/* now bring the post divider out of reset */
|
||||
reg = (uintptr_t)(PCIE_LCPLL_BASE +
|
||||
PCIE_LCPLL_CTRL0_OFFSET);
|
||||
mmio_setbits_32(reg, PCIE_LCPLL_P_RESETB_MASK);
|
||||
VERBOSE("PCIe LCPLL locked\n");
|
||||
return 0;
|
||||
}
|
||||
mdelay(1);
|
||||
} while (--timeout);
|
||||
|
||||
ERROR("PCIe LCPLL failed to lock\n");
|
||||
return -EIO;
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* Bring up EXT CLK reference clock for PCIe serdes used in RC mode
|
||||
* XTAL_BYPASS (3 << 0)
|
||||
* INTR_LC_REF (5 << 0)
|
||||
* PD_CML_LC_REF_OUT (1 << 4)
|
||||
* PD_CML_REF_CH_OUT (1 << 8)
|
||||
* CLK_MASTER_SEL (1 << 11)
|
||||
* CLK_MASTER_CTRL_A (1 << 12)
|
||||
* CLK_MASTER_CTRL_B (2 << 14)
|
||||
*/
|
||||
static const uint16_t pcie_ext_clk[][NUM_OF_PCIE_SERDES] = {
|
||||
/* PIPEMUX = 0, EP 1x16 */
|
||||
{0},
|
||||
/* PIPEMUX = 1, EP 1x8 + RC 1x8, core 7 */
|
||||
{0},
|
||||
/* PIPEMUX = 2, EP 4x4 */
|
||||
{0},
|
||||
/* PIPEMUX = 3, RC 2x8, cores 0, 7 */
|
||||
{0x8803, 0x9115, 0x9115, 0x1115, 0x8803, 0x9115, 0x9115, 0x1115},
|
||||
/* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */
|
||||
{0x8803, 0x1115, 0x8915, 0x1115, 0x8803, 0x1115, 0x8915, 0x1115,},
|
||||
/* PIPEMUX = 5, RC 8x2, all 8 cores */
|
||||
{0x0803, 0x0915, 0x0915, 0x0915, 0x0803, 0x0915, 0x0915, 0x0915,},
|
||||
/* PIPEMUX = 6, RC 3x4 + 2x2, cores 0, 2, 3, 6, 7 */
|
||||
{0},
|
||||
/* PIPEMUX = 7, RC 1x4 + 6x2, cores 0, 2, 3, 4, 5, 6, 7 */
|
||||
{0},
|
||||
/* PIPEMUX = 8, EP 1x8 + RC 4x2, cores 4, 5, 6, 7 */
|
||||
{0},
|
||||
/* PIPEMUX = 9, EP 1x8 + RC 2x4, cores 6, 7 */
|
||||
{0},
|
||||
/* PIPEMUX = 10, EP 2x4 + RC 2x4, cores 1, 6 */
|
||||
{0},
|
||||
/* PIPEMUX = 11, EP 2x4 + RC 4x2, cores 2, 3, 4, 5 */
|
||||
{0},
|
||||
/* PIPEMUX = 12, EP 1x4 + RC 6x2, cores 2, 3, 4, 5, 6, 7 */
|
||||
{0},
|
||||
/* PIPEMUX = 13, RC 2x4 + RC 1x4 + 2x2, cores 2, 3, 6 */
|
||||
{0},
|
||||
};
|
||||
|
||||
static void pcie_ext_clk_init(void)
|
||||
{
|
||||
unsigned int serdes;
|
||||
uint32_t val;
|
||||
|
||||
for (serdes = 0; serdes < NUM_OF_PCIE_SERDES; serdes++) {
|
||||
val = pcie_ext_clk[pipemux_idx][serdes];
|
||||
if (!val)
|
||||
return;
|
||||
mmio_write_32(PCIE_CORE_RESERVED_CFG +
|
||||
serdes * PCIE_CORE_PWR_OFFSET, val);
|
||||
}
|
||||
/* disable CML buf1/2 and enable D2C2 */
|
||||
mmio_clrsetbits_32((PCIE_LCPLL_BASE + PCIE_LCPLL_CTRL3_OFFSET),
|
||||
PCIE_LCPLL_CM_BUF_ENA << PCIE_LCPLL_EN_CTRL_SHIFT,
|
||||
PCIE_LCPLL_D2C2_ENA << PCIE_LCPLL_EN_CTRL_SHIFT);
|
||||
mmio_write_32(PCIE_LCPLL_BASE + PCIE_TX_CLKMASTER_CTRL_OVERRIDE_CFG, 1);
|
||||
INFO("Overriding Clocking - using REF clock from PAD...\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static int load_uc(unsigned int core_idx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int paxb_serdes_gate_clock(unsigned int core_idx, int gate_clk)
|
||||
{
|
||||
unsigned int link_width, serdes, nr_serdes;
|
||||
uintptr_t pmi_base;
|
||||
unsigned int rdata;
|
||||
uint32_t core_offset = core_idx * PCIE_CORE_PWR_OFFSET;
|
||||
|
||||
link_width = paxb->get_link_width(core_idx);
|
||||
if (!link_width) {
|
||||
ERROR("Unsupported PIPEMUX\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
nr_serdes = link_width / 2;
|
||||
pmi_base = (uintptr_t)(PCIE_CORE_PMI_CFG_BASE + core_offset);
|
||||
|
||||
for (serdes = 0; serdes < nr_serdes; serdes++) {
|
||||
mmio_write_32(pmi_base, serdes);
|
||||
paxb_pmi_read(core_idx, PMI_ADDR_LANE0(PMI_PLL_CTRL_4), &rdata);
|
||||
if (!gate_clk)
|
||||
rdata |= PMI_SERDES_CLK_ENABLE;
|
||||
else
|
||||
rdata &= ~PMI_SERDES_CLK_ENABLE;
|
||||
paxb_pmi_write(core_idx, PMI_ADDR_BCAST(PMI_PLL_CTRL_4), rdata);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int paxb_gen3_serdes_init(unsigned int core_idx, uint32_t nSerdes)
|
||||
{
|
||||
uint32_t rdata;
|
||||
int serdes;
|
||||
uintptr_t pmi_base;
|
||||
unsigned int timeout;
|
||||
unsigned int reg_d230, reg_d267;
|
||||
|
||||
|
||||
pmi_base = (uintptr_t)(PCIE_CORE_PMI_CFG_BASE +
|
||||
(core_idx * PCIE_CORE_PWR_OFFSET));
|
||||
|
||||
for (serdes = 0; serdes < nSerdes; serdes++) {
|
||||
/* select the PMI interface */
|
||||
mmio_write_32(pmi_base, serdes);
|
||||
|
||||
/* Clock enable */
|
||||
paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_CLK_CTRL0),
|
||||
0x3);
|
||||
|
||||
/* Release reset of master */
|
||||
paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_RST_CTRL0),
|
||||
0x1);
|
||||
|
||||
/* clearing PRAM memory */
|
||||
paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_AHB_CTRL0),
|
||||
0x100);
|
||||
|
||||
timeout = UC_RAM_INIT_TIMEOUT;
|
||||
do {
|
||||
paxb_pmi_read(core_idx,
|
||||
PMI_ADDR_LANE0(UC_A_AHB_STAT0),
|
||||
&rdata);
|
||||
} while ((rdata & 0x01) == 0 && timeout--);
|
||||
|
||||
if (!timeout)
|
||||
return -EIO;
|
||||
|
||||
timeout = UC_RAM_INIT_TIMEOUT;
|
||||
do {
|
||||
paxb_pmi_read(core_idx,
|
||||
PMI_ADDR_LANE1(UC_A_AHB_STAT0),
|
||||
&rdata);
|
||||
} while ((rdata & 0x01) == 0 && timeout--);
|
||||
|
||||
if (!timeout)
|
||||
return -EIO;
|
||||
|
||||
/* clearing PRAM memory */
|
||||
paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_AHB_CTRL0),
|
||||
0);
|
||||
|
||||
/* to identify 2 lane serdes */
|
||||
paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_DBG1), 0x1);
|
||||
|
||||
/* De-Assert Pram & master resets */
|
||||
paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_RST_CTRL0),
|
||||
0x9);
|
||||
|
||||
if (load_uc(core_idx))
|
||||
return -EIO;
|
||||
|
||||
/* UC UC ready for command */
|
||||
paxb_pmi_read(core_idx, PMI_ADDR_LANE0(DSC_UC_CTRL),
|
||||
&rdata);
|
||||
rdata |= DSC_UC_CTRL_RDY_CMD;
|
||||
paxb_pmi_write(core_idx, PMI_ADDR_LANE0(DSC_UC_CTRL),
|
||||
rdata);
|
||||
|
||||
paxb_pmi_read(core_idx, PMI_ADDR_LANE1(DSC_UC_CTRL),
|
||||
&rdata);
|
||||
rdata |= DSC_UC_CTRL_RDY_CMD;
|
||||
paxb_pmi_write(core_idx, PMI_ADDR_LANE1(DSC_UC_CTRL),
|
||||
rdata);
|
||||
|
||||
/* Lane reset */
|
||||
paxb_pmi_write(core_idx,
|
||||
PMI_ADDR_BCAST(LANE_DBG_RST_CTRL), 0x3);
|
||||
|
||||
/* De-Assert Core and Master resets */
|
||||
paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_RST_CTRL0),
|
||||
0x3);
|
||||
|
||||
timeout = UC_INIT_TIMEOUT;
|
||||
while (timeout--) {
|
||||
paxb_pmi_read(core_idx,
|
||||
PMI_ADDR_LANE0(UC_VERSION_NUM),
|
||||
®_d230);
|
||||
paxb_pmi_read(core_idx,
|
||||
PMI_ADDR_LANE0(DSC_SM_CTL22),
|
||||
®_d267);
|
||||
|
||||
if (((reg_d230 & 0xffff) != 0) &
|
||||
((reg_d267 & 0xc000) == 0xc000)) {
|
||||
break;
|
||||
}
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
if (!timeout)
|
||||
return -EIO;
|
||||
|
||||
timeout = UC_INIT_TIMEOUT;
|
||||
while (timeout--) {
|
||||
paxb_pmi_read(core_idx,
|
||||
PMI_ADDR_LANE1(UC_VERSION_NUM),
|
||||
®_d230);
|
||||
paxb_pmi_read(core_idx,
|
||||
PMI_ADDR_LANE1(DSC_SM_CTL22),
|
||||
®_d267);
|
||||
|
||||
if (((reg_d230 & 0xffff) != 0) &
|
||||
((reg_d267 & 0xc000) == 0xc000)) {
|
||||
break;
|
||||
}
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
if (!timeout)
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcie_serdes_requires_patch(unsigned int serdes_idx)
|
||||
{
|
||||
if (pipemux_idx != SERDES_PATCH_PIPEMUX_INDEX)
|
||||
return 0;
|
||||
|
||||
return !!((SERDES_PATCH_INDEX >> serdes_idx) & 0x1);
|
||||
}
|
||||
|
||||
static void pcie_tx_coeff_p7(unsigned int core_idx)
|
||||
{
|
||||
paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd11b), 0x00aa);
|
||||
paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd11c), 0x1155);
|
||||
paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd11d), 0x2449);
|
||||
paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd11e), 0x000f);
|
||||
paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd307), 0x0001);
|
||||
}
|
||||
|
||||
|
||||
static unsigned int paxb_sr_get_rc_link_width(unsigned int core_idx)
|
||||
{
|
||||
return link_width_table[pipemux_idx][core_idx];
|
||||
}
|
||||
|
||||
static uint32_t paxb_sr_get_rc_link_speed(void)
|
||||
{
|
||||
return GEN3_LINK_SPEED;
|
||||
}
|
||||
|
||||
|
||||
static int paxb_serdes_init(unsigned int core_idx, unsigned int nr_serdes)
|
||||
{
|
||||
uint32_t core_offset = core_idx * PCIE_CORE_PWR_OFFSET;
|
||||
unsigned int serdes;
|
||||
uintptr_t pmi_base;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Each serdes has a x2 link width
|
||||
*
|
||||
* Use PAXB to patch the serdes for proper RX termination through the
|
||||
* PMI interface
|
||||
*/
|
||||
pmi_base = (uintptr_t)(PCIE_CORE_PMI_CFG_BASE + core_offset);
|
||||
for (serdes = 0; serdes < nr_serdes; serdes++) {
|
||||
/* select the PMI interface */
|
||||
mmio_write_32(pmi_base, serdes);
|
||||
|
||||
/* patch Serdes for RX termination */
|
||||
ret = paxb_pmi_write(core_idx, PMI_RX_TERM_SEQ,
|
||||
PMI_RX_TERM_VAL);
|
||||
if (ret)
|
||||
goto err_pmi;
|
||||
|
||||
ret = paxb_pmi_write(core_idx, MERLIN16_PCIE_BLK2_PWRMGMT_7,
|
||||
MERLIN16_PCIE_BLK2_PWRMGMT_7_VAL);
|
||||
if (ret)
|
||||
goto err_pmi;
|
||||
|
||||
ret = paxb_pmi_write(core_idx, MERLIN16_PCIE_BLK2_PWRMGMT_8,
|
||||
MERLIN16_PCIE_BLK2_PWRMGMT_8_VAL);
|
||||
if (ret)
|
||||
goto err_pmi;
|
||||
|
||||
ret = paxb_pmi_write(core_idx, MERLIN16_AMS_TX_CTRL_5,
|
||||
MERLIN16_AMS_TX_CTRL_5_VAL);
|
||||
if (ret)
|
||||
goto err_pmi;
|
||||
|
||||
pcie_tx_coeff_p7(core_idx);
|
||||
|
||||
if (pcie_serdes_requires_patch(serdes)) {
|
||||
if (((core_idx == 0) || (core_idx == 7))) {
|
||||
ret = paxb_pmi_write(core_idx,
|
||||
PMI_X8_CORE0_7_PATCH_SEQ,
|
||||
PMI_X8_CORE0_7_PATCH_VAL);
|
||||
if (ret)
|
||||
goto err_pmi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_pmi:
|
||||
ERROR("PCIe PMI write failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int paxb_sr_phy_init(void)
|
||||
{
|
||||
int ret;
|
||||
unsigned int core_idx;
|
||||
|
||||
#ifndef BOARD_PCIE_EXT_CLK
|
||||
ret = pcie_lcpll_init();
|
||||
if (ret)
|
||||
return ret;
|
||||
#else
|
||||
pcie_ext_clk_init();
|
||||
#endif
|
||||
|
||||
for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
|
||||
if (!pcie_core_needs_enable(core_idx))
|
||||
continue;
|
||||
unsigned int link_width;
|
||||
|
||||
paxb_serdes_gate_clock(core_idx, 0);
|
||||
|
||||
link_width = paxb->get_link_width(core_idx);
|
||||
if (!link_width) {
|
||||
ERROR("Unsupported PIPEMUX\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
ret = paxb_serdes_init(core_idx, link_width / 2);
|
||||
if (ret) {
|
||||
ERROR("PCIe serdes initialization failed for core %u\n",
|
||||
core_idx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ret = paxb_gen3_serdes_init(core_idx, link_width / 2);
|
||||
if (ret) {
|
||||
ERROR("PCIe GEN3 serdes initialization failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const paxb_cfg sr_paxb_cfg = {
|
||||
.type = PAXB_SR,
|
||||
.device_id = SR_B0_DEVICE_ID,
|
||||
.pipemux_init = pipemux_sr_init,
|
||||
.phy_init = paxb_sr_phy_init,
|
||||
.core_needs_enable = paxb_sr_core_needs_enable,
|
||||
.num_cores = NUM_OF_SR_PCIE_CORES,
|
||||
.get_link_width = paxb_sr_get_rc_link_width,
|
||||
.get_link_speed = paxb_sr_get_rc_link_speed,
|
||||
};
|
||||
|
||||
const paxb_cfg *paxb_get_sr_config(void)
|
||||
{
|
||||
return &sr_paxb_cfg;
|
||||
}
|
Loading…
Reference in New Issue
Block a user