Commit 1e66bacb authored by Konstantin Porotchkin's avatar Konstantin Porotchkin
Browse files

plat: marvell: Add support for Armada-37xx SoC platform



Add supprot for Marvell platforms based on Armada-37xx SoC.
This includes support for the official Armada-3720 modular
development board and EspressoBin community board.
The Armada-37xx SoC contains dual Cortex-A53 Application CPU,
single secure CPU (Cortex-M3) and the following interfaces:
- SATA 3.0
- USB 3.0 and USB 2.0
- PCIe
- SDIO (supports boot from eMMC)
- SPI
- UART
- I2c
- Gigabit Ethernet
Signed-off-by: default avatarKonstantin Porotchkin <kostap@marvell.com>
parent 19112b79
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
* https://spdx.org/licenses
*/
#ifndef __PLAT_MACROS_S__
#define __PLAT_MACROS_S__
#include <marvell_macros.S>
/* ---------------------------------------------
* The below macro prints out relevant GIC and
* CCI registers registers whenever an unhandled
* exception is taken in BL31.
* ---------------------------------------------
*/
.macro plat_crash_print_regs
mov_imm x17, MVEBU_GICC_BASE
mov_imm x16, MVEBU_GICD_BASE
marvell_print_gic_regs
print_cci_regs
.endm
#endif /* __PLAT_MACROS_S__ */
/*
* Copyright (C) 2016 Marvell International Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
* https://spdx.org/licenses
*/
#ifndef __PLATFORM_DEF_H__
#define __PLATFORM_DEF_H__
#include <board_marvell_def.h>
#include <mvebu_def.h>
#ifndef __ASSEMBLY__
#include <stdio.h>
#endif /* __ASSEMBLY__ */
/*
* Most platform porting definitions provided by included headers
*/
/*
* DRAM Memory layout:
* +-----------------------+
* : :
* : Linux :
* 0x04X00000-->+-----------------------+
* | BL3-3(u-boot) |>>}>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
* |-----------------------| } |
* | BL3-[0,1, 2] | }---------------------------------> |
* |-----------------------| } || |
* | BL2 | }->FIP (loaded by || |
* |-----------------------| } BootROM to DRAM) || |
* | FIP_TOC | } || |
* 0x04120000-->|-----------------------| || |
* | BL1 (RO) | || |
* 0x04100000-->+-----------------------+ || |
* : : || |
* : Trusted SRAM section : \/ |
* 0x04040000-->+-----------------------+ Replaced by BL2 +----------------+ |
* | BL1 (RW) | <<<<<<<<<<<<<<<< | BL3-1 NOBITS | |
* 0x04037000-->|-----------------------| <<<<<<<<<<<<<<<< |----------------| |
* | | <<<<<<<<<<<<<<<< | BL3-1 PROGBITS | |
* 0x04023000-->|-----------------------| +----------------+ |
* | BL2 | |
* |-----------------------| |
* | | |
* 0x04001000-->|-----------------------| |
* | Shared | |
* 0x04000000-->+-----------------------+ |
* : : |
* : Linux : |
* : : |
* |-----------------------| |
* | | U-Boot(BL3-3) Loaded by BL2 |
* | U-Boot | <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
* 0x00000000-->+-----------------------+
*
* Trusted SRAM section 0x4000000..0x4200000:
* ----------------------------------------
* SRAM_BASE = 0x4001000
* BL2_BASE = 0x4006000
* BL2_LIMIT = BL31_BASE
* BL31_BASE = 0x4023000 = (64MB + 256KB - 0x1D000)
* BL31_PROGBITS_LIMIT = BL1_RW_BASE
* BL1_RW_BASE = 0x4037000 = (64MB + 256KB - 0x9000)
* BL1_RW_LIMIT = BL31_LIMIT = 0x4040000
*
*
* PLAT_MARVELL_FIP_BASE = 0x4120000
*/
#define PLAT_MARVELL_ATF_BASE 0x4000000
#define PLAT_MARVELL_ATF_LOAD_ADDR \
(PLAT_MARVELL_ATF_BASE + 0x100000)
#define PLAT_MARVELL_FIP_BASE \
(PLAT_MARVELL_ATF_LOAD_ADDR + 0x20000)
#define PLAT_MARVELL_FIP_MAX_SIZE 0x4000000
#define PLAT_MARVELL_CLUSTER_CORE_COUNT 2
/* DRAM[2MB..66MB] is used as Trusted ROM */
#define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR
/* 64 MB TODO: reduce this to minimum needed according to fip image size*/
#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x04000000
/* Reserve 16M for SCP (Secure PayLoad) Trusted DRAM */
#define PLAT_MARVELL_TRUSTED_DRAM_BASE 0x04400000
#define PLAT_MARVELL_TRUSTED_DRAM_SIZE 0x01000000 /* 16 MB */
/*
* PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
* plus a little space for growth.
*/
#define PLAT_MARVELL_MAX_BL1_RW_SIZE 0xA000
/*
* PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
* little space for growth.
*/
#define PLAT_MARVELL_MAX_BL2_SIZE 0xF000
/*
* PLAT_ARM_MAX_BL31_SIZE is calculated using the current BL31 debug size plus a
* little space for growth.
*/
#define PLAT_MARVEL_MAX_BL31_SIZE 0x5D000
#define PLAT_MARVELL_CPU_ENTRY_ADDR BL1_RO_BASE
/* GIC related definitions */
#define PLAT_MARVELL_GICD_BASE (MVEBU_REGS_BASE + MVEBU_GICD_BASE)
#define PLAT_MARVELL_GICR_BASE (MVEBU_REGS_BASE + MVEBU_GICR_BASE)
#define PLAT_MARVELL_GICC_BASE (MVEBU_REGS_BASE + MVEBU_GICC_BASE)
#define PLAT_MARVELL_G0_IRQ_PROPS(grp) \
INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \
GIC_INTR_CFG_LEVEL), \
INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \
GIC_INTR_CFG_LEVEL)
#define PLAT_MARVELL_G1S_IRQ_PROPS(grp) \
INTR_PROP_DESC(MARVELL_IRQ_SEC_PHY_TIMER, \
GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \
GIC_INTR_CFG_LEVEL), \
INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \
GIC_INTR_CFG_LEVEL), \
INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \
GIC_INTR_CFG_LEVEL), \
INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \
GIC_INTR_CFG_LEVEL), \
INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \
GIC_INTR_CFG_LEVEL), \
INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \
GIC_INTR_CFG_LEVEL)
#define PLAT_MARVELL_SHARED_RAM_CACHED 1
/* CCI related constants */
#define PLAT_MARVELL_CCI_BASE (MVEBU_REGS_BASE + MVEBU_CCI_BASE)
#define PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX 3
#define PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX 4
/*
* Load address of BL3-3 for this platform port
*/
#define PLAT_MARVELL_NS_IMAGE_OFFSET 0x0
/* System Reference Clock*/
#define PLAT_REF_CLK_IN_HZ COUNTER_FREQUENCY
/*
* PL011 related constants
*/
#define PLAT_MARVELL_BOOT_UART_BASE (MVEBU_REGS_BASE + 0x12000)
#define PLAT_MARVELL_BOOT_UART_CLK_IN_HZ 25804800
#define PLAT_MARVELL_CRASH_UART_BASE PLAT_MARVELL_BOOT_UART_BASE
#define PLAT_MARVELL_CRASH_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ
#define PLAT_MARVELL_BL31_RUN_UART_BASE PLAT_MARVELL_BOOT_UART_BASE
#define PLAT_MARVELL_BL31_RUN_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ
/* Required platform porting definitions */
#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1
/* System timer related constants */
#define PLAT_MARVELL_NSTIMER_FRAME_ID 1
/* Mailbox base address */
#define PLAT_MARVELL_MAILBOX_BASE \
(MARVELL_TRUSTED_SRAM_BASE + 0x400)
#define PLAT_MARVELL_MAILBOX_SIZE 0x100
#define PLAT_MARVELL_MAILBOX_MAGIC_NUM 0x6D72766C /* mrvl */
/* DRAM CS memory map registers related constants */
#define MVEBU_CS_MMAP_LOW(cs_num) \
(MVEBU_CS_MMAP_REG_BASE + (cs_num) * 0x8)
#define MVEBU_CS_MMAP_ENABLE 0x1
#define MVEBU_CS_MMAP_AREA_LEN_OFFS 16
#define MVEBU_CS_MMAP_AREA_LEN_MASK \
(0x1f << MVEBU_CS_MMAP_AREA_LEN_OFFS)
#define MVEBU_CS_MMAP_START_ADDR_LOW_OFFS 23
#define MVEBU_CS_MMAP_START_ADDR_LOW_MASK \
(0x1ff << MVEBU_CS_MMAP_START_ADDR_LOW_OFFS)
#define MVEBU_CS_MMAP_HIGH(cs_num) \
(MVEBU_CS_MMAP_REG_BASE + 0x4 + (cs_num) * 0x8)
/* DRAM max CS number */
#define MVEBU_MAX_CS_MMAP_NUM (2)
/* CPU decoder window related constants */
#define CPU_DEC_WIN_CTRL_REG(win_num) \
(MVEBU_CPU_DEC_WIN_REG_BASE + (win_num) * 0x10)
#define CPU_DEC_CR_WIN_ENABLE 0x1
#define CPU_DEC_CR_WIN_TARGET_OFFS 4
#define CPU_DEC_CR_WIN_TARGET_MASK \
(0xf << CPU_DEC_CR_WIN_TARGET_OFFS)
#define CPU_DEC_WIN_SIZE_REG(win_num) \
(MVEBU_CPU_DEC_WIN_REG_BASE + 0x4 + (win_num) * 0x10)
#define CPU_DEC_CR_WIN_SIZE_OFFS 0
#define CPU_DEC_CR_WIN_SIZE_MASK \
(0xffff << CPU_DEC_CR_WIN_SIZE_OFFS)
#define CPU_DEC_CR_WIN_SIZE_ALIGNMENT 0x10000
#define CPU_DEC_WIN_BASE_REG(win_num) \
(MVEBU_CPU_DEC_WIN_REG_BASE + 0x8 + (win_num) * 0x10)
#define CPU_DEC_BR_BASE_OFFS 0
#define CPU_DEC_BR_BASE_MASK \
(0xffff << CPU_DEC_BR_BASE_OFFS)
#define CPU_DEC_REMAP_LOW_REG(win_num) \
(MVEBU_CPU_DEC_WIN_REG_BASE + 0xC + (win_num) * 0x10)
#define CPU_DEC_RLR_REMAP_LOW_OFFS 0
#define CPU_DEC_RLR_REMAP_LOW_MASK \
(0xffff << CPU_DEC_BR_BASE_OFFS)
/* Securities */
#define IRQ_SEC_OS_TICK_INT MARVELL_IRQ_SEC_PHY_TIMER
#define TRUSTED_DRAM_BASE PLAT_MARVELL_TRUSTED_DRAM_BASE
#define TRUSTED_DRAM_SIZE PLAT_MARVELL_TRUSTED_DRAM_SIZE
#ifdef BL32
#define BL32_BASE TRUSTED_DRAM_BASE
#define BL32_LIMIT TRUSTED_DRAM_SIZE
#endif
#endif /* __PLATFORM_DEF_H__ */
/*
* Copyright (C) 2016 Marvell International Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
* https://spdx.org/licenses
*/
#include <debug.h>
#include <io_addr_dec.h>
#include <mmio.h>
#include <plat_marvell.h>
#define MVEBU_DEC_WIN_CTRL_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \
(win) * (off))
#define MVEBU_DEC_WIN_BASE_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \
(win) * (off) + 0x4)
#define MVEBU_DEC_WIN_REMAP_REG(base, win, off) (MVEBU_REGS_BASE + (base) + \
(win) * (off) + 0x8)
#define MVEBU_DEC_WIN_CTRL_SIZE_OFF (16)
#define MVEBU_DEC_WIN_ENABLE (0x1)
#define MVEBU_DEC_WIN_CTRL_ATTR_OFF (8)
#define MVEBU_DEC_WIN_CTRL_TARGET_OFF (4)
#define MVEBU_DEC_WIN_CTRL_EN_OFF (0)
#define MVEBU_DEC_WIN_BASE_OFF (16)
#define MVEBU_WIN_BASE_SIZE_ALIGNMENT (0x10000)
/* There are up to 14 IO unit which need address decode in Armada-3700 */
#define IO_UNIT_NUM_MAX (14)
#define MVEBU_MAX_ADDRSS_4GB (0x100000000ULL)
static void set_io_addr_dec_win(int win_id, uintptr_t base_addr,
uintptr_t win_size,
struct dec_win_config *dec_win)
{
uint32_t ctrl = 0;
uint32_t base = 0;
/* set size */
ctrl = ((win_size / MVEBU_WIN_BASE_SIZE_ALIGNMENT) - 1) <<
MVEBU_DEC_WIN_CTRL_SIZE_OFF;
/* set attr according to IO decode window */
ctrl |= dec_win->win_attr << MVEBU_DEC_WIN_CTRL_ATTR_OFF;
/* set target */
ctrl |= DRAM_CPU_DEC_TARGET_NUM << MVEBU_DEC_WIN_CTRL_TARGET_OFF;
/* set base */
base = (base_addr / MVEBU_WIN_BASE_SIZE_ALIGNMENT) <<
MVEBU_DEC_WIN_BASE_OFF;
/* set base address*/
mmio_write_32(MVEBU_DEC_WIN_BASE_REG(dec_win->dec_reg_base,
win_id, dec_win->win_offset),
base);
/* set remap window, some unit does not have remap window */
if (win_id < dec_win->max_remap)
mmio_write_32(MVEBU_DEC_WIN_REMAP_REG(dec_win->dec_reg_base,
win_id, dec_win->win_offset), base);
/* set control register */
mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base,
win_id, dec_win->win_offset), ctrl);
/* enable the address decode window at last to make it effective */
ctrl |= MVEBU_DEC_WIN_ENABLE << MVEBU_DEC_WIN_CTRL_EN_OFF;
mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base,
win_id, dec_win->win_offset), ctrl);
INFO("set_io_addr_dec %d result: ctrl(0x%x) base(0x%x)",
win_id, mmio_read_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base,
win_id, dec_win->win_offset)),
mmio_read_32(MVEBU_DEC_WIN_BASE_REG(dec_win->dec_reg_base,
win_id, dec_win->win_offset)));
if (win_id < dec_win->max_remap)
INFO(" remap(%x)\n",
mmio_read_32(MVEBU_DEC_WIN_REMAP_REG(dec_win->dec_reg_base,
win_id, dec_win->win_offset)));
else
INFO("\n");
}
/* Set io decode window */
static int set_io_addr_dec(struct dram_win_map *win_map,
struct dec_win_config *dec_win)
{
struct dram_win *win;
int id;
/* disable all windows first */
for (id = 0; id < dec_win->max_dram_win; id++)
mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, id,
dec_win->win_offset), 0);
/* configure IO decode windows for DRAM, inheritate DRAM size,
* base and target from CPU-DRAM decode window and others
* from hard coded IO decode window settings array.
*/
if (win_map->dram_win_num > dec_win->max_dram_win) {
/*
* If cpu dram windows number exceeds the io decode windows
* max number, then fill the first io decode window
* with base(0) and size(4GB).
*/
set_io_addr_dec_win(0, 0, MVEBU_MAX_ADDRSS_4GB, dec_win);
return 0;
}
for (id = 0; id < win_map->dram_win_num; id++, win++) {
win = &win_map->dram_windows[id];
set_io_addr_dec_win(id, win->base_addr, win->win_size, dec_win);
}
return 0;
}
/*
* init_io_addr_dec
*
* This function initializes io address decoder windows by
* cpu dram window mapping information
*
* @input: N/A
* - dram_wins_map: cpu dram windows mapping
* - io_dec_config: io address decoder windows configuration
* - io_unit_num: io address decoder unit number
* @output: N/A
*
* @return: 0 on success and others on failure
*/
int init_io_addr_dec(struct dram_win_map *dram_wins_map,
struct dec_win_config *io_dec_config, uint32_t io_unit_num)
{
int32_t index;
struct dec_win_config *io_dec_win;
int32_t ret;
INFO("Initializing IO address decode windows\n");
if (io_dec_config == NULL || io_unit_num == 0) {
ERROR("No IO address decoder windows configurations!\n");
return -1;
}
if (io_unit_num > IO_UNIT_NUM_MAX) {
ERROR("IO address decoder windows number %d is over max %d\n",
io_unit_num, IO_UNIT_NUM_MAX);
return -1;
}
if (dram_wins_map == NULL) {
ERROR("No cpu dram decoder windows map!\n");
return -1;
}
for (index = 0; index < dram_wins_map->dram_win_num; index++)
INFO("DRAM mapping %d base(0x%lx) size(0x%lx)\n",
index, dram_wins_map->dram_windows[index].base_addr,
dram_wins_map->dram_windows[index].win_size);
/* Set address decode window for each IO */
for (index = 0; index < io_unit_num; index++) {
io_dec_win = io_dec_config + index;
ret = set_io_addr_dec(dram_wins_map, io_dec_win);
if (ret) {
ERROR("Failed to set IO address decode\n");
return -1;
}
INFO("Set IO decode window successfully, base(0x%x)",
io_dec_win->dec_reg_base);
INFO(" win_attr(%x) max_dram_win(%d) max_remap(%d)",
io_dec_win->win_attr, io_dec_win->max_dram_win,
io_dec_win->max_remap);
INFO(" win_offset(%d)\n", io_dec_win->win_offset);
}
return 0;
}
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
* https://spdx.org/licenses
*/
#include <bl_common.h>
#include <io_addr_dec.h>
#include <mvebu_def.h>
struct dec_win_config io_dec_win_conf[] = {
/* dec_reg_base win_attr max_dram_win max_remap win_offset */
{0xc000, 0x3d, 2, 0, 0x08}, /* USB */
{0xc100, 0x3d, 3, 0, 0x10}, /* USB3 */
{0xc200, 0x3d, 2, 0, 0x10}, /* DMA */
{0xc300, 0x3d, 2, 0, 0x10}, /* NETA0 */
{0xc400, 0x3d, 2, 0, 0x10}, /* NETA1 */
{0xc500, 0x3d, 2, 0, 0x10}, /* PCIe */
{0xc800, 0x3d, 3, 0, 0x10}, /* SATA */
{0xca00, 0x3d, 3, 0, 0x08}, /* SD */
{0xcb00, 0x3d, 3, 0, 0x10}, /* eMMC */
{0xce00, 0x3d, 2, 0, 0x08}, /* EIP97 */
};
int marvell_get_io_dec_win_conf(struct dec_win_config **win, uint32_t *size)
{
*win = io_dec_win_conf;
*size = sizeof(io_dec_win_conf)/sizeof(struct dec_win_config);
return 0;
}
This diff is collapsed.
/*
* Copyright (C) 2018 Marvell International Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
* https://spdx.org/licenses
*/
#include <debug.h>
#include <gicv3.h>
#include <interrupt_props.h>
#include <marvell_def.h>
#include <plat_marvell.h>
#include <platform.h>
#include <platform_def.h>
/******************************************************************************
* The following functions are defined as weak to allow a platform to override
* the way the GICv3 driver is initialised and used.
******************************************************************************
*/
#pragma weak plat_marvell_gic_driver_init
#pragma weak plat_marvell_gic_init
#pragma weak plat_marvell_gic_cpuif_enable
#pragma weak plat_marvell_gic_cpuif_disable
#pragma weak plat_marvell_gic_pcpu_init
/* The GICv3 driver only needs to be initialized in EL3 */
static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
static const interrupt_prop_t marvell_interrupt_props[] = {
PLAT_MARVELL_G1S_IRQ_PROPS(INTR_GROUP1S),
PLAT_MARVELL_G0_IRQ_PROPS(INTR_GROUP0)
};
/*
* We save and restore the GICv3 context on system suspend. Allocate the
* data in the designated EL3 Secure carve-out memory
*/
static gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram");
static gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram");
/*
* MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
* to core position.
*
* Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity
* values read from GICR_TYPER don't have an MT field. To reuse the same
* translation used for CPUs, we insert MT bit read from the PE's MPIDR into
* that read from GICR_TYPER.
*
* Assumptions:
*
* - All CPUs implemented in the system have MPIDR_EL1.MT bit set;
* - No CPUs implemented in the system use affinity level 3.
*/
static unsigned int marvell_gicv3_mpidr_hash(u_register_t mpidr)
{
mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
return plat_marvell_calc_core_pos(mpidr);
}
const gicv3_driver_data_t marvell_gic_data = {
.gicd_base = PLAT_MARVELL_GICD_BASE,
.gicr_base = PLAT_MARVELL_GICR_BASE,
.interrupt_props = marvell_interrupt_props,
.interrupt_props_num = ARRAY_SIZE(marvell_interrupt_props),
.rdistif_num = PLATFORM_CORE_COUNT,
.rdistif_base_addrs = rdistif_base_addrs,
.mpidr_to_core_pos = marvell_gicv3_mpidr_hash
};
void plat_marvell_gic_driver_init(void)
{
/*
* The GICv3 driver is initialized in EL3 and does not need
* to be initialized again in SEL1. This is because the S-EL1
* can use GIC system registers to manage interrupts and does
* not need GIC interface base addresses to be configured.
*/
#if IMAGE_BL31
gicv3_driver_init(&marvell_gic_data);
#endif
}
/******************************************************************************
* Marvell common helper to initialize the GIC. Only invoked by BL31
******************************************************************************
*/
void plat_marvell_gic_init(void)
{
/* Initialize GIC-600 Multi Chip feature,
* only if the maximum number of north bridges
* is more than 1 - otherwise no need for multi
* chip feature initialization
*/
#if (PLAT_MARVELL_NORTHB_COUNT > 1)
if (gic600_multi_chip_init())
ERROR("GIC-600 Multi Chip initialization failed\n");
#endif
gicv3_distif_init();
gicv3_rdistif_init(plat_my_core_pos());
gicv3_cpuif_enable(plat_my_core_pos());
}
/******************************************************************************
* Marvell common helper to enable the GIC CPU interface
******************************************************************************
*/
void plat_marvell_gic_cpuif_enable(void)
{
gicv3_cpuif_enable(plat_my_core_pos());
}
/******************************************************************************
* Marvell common helper to disable the GIC CPU interface
******************************************************************************
*/
void plat_marvell_gic_cpuif_disable(void)
{
gicv3_cpuif_disable(plat_my_core_pos());
}
/******************************************************************************
* Marvell common helper to init. the per-cpu redistributor interface in GICv3
******************************************************************************
*/
void plat_marvell_gic_pcpu_init(void)
{
gicv3_rdistif_init(plat_my_core_pos());
}
/******************************************************************************
* Marvell common helper to save SPI irq states in GICv3
******************************************************************************
*/
void plat_marvell_gic_irq_save(void)
{
/*
* If an ITS is available, save its context before
* the Redistributor using:
* gicv3_its_save_disable(gits_base, &its_ctx[i])
* Additionally, an implementation-defined sequence may
* be required to save the whole ITS state.
*/
/*
* Save the GIC Redistributors and ITS contexts before the
* Distributor context. As we only handle SYSTEM SUSPEND API,
* we only need to save the context of the CPU that is issuing
* the SYSTEM SUSPEND call, i.e. the current CPU.
*/
gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx);
/* Save the GIC Distributor context */
gicv3_distif_save(&dist_ctx);
/*
* From here, all the components of the GIC can be safely powered down
* as long as there is an alternate way to handle wakeup interrupt
* sources.
*/
}
/******************************************************************************
* Marvell common helper to restore SPI irq states in GICv3
******************************************************************************
*/
void plat_marvell_gic_irq_restore(void)
{
/* Restore the GIC Distributor context */
gicv3_distif_init_restore(&dist_ctx);
/*
* Restore the GIC Redistributor and ITS contexts after the
* Distributor context. As we only handle SYSTEM SUSPEND API,
* we only need to restore the context of the CPU that issued
* the SYSTEM SUSPEND call.
*/
gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx);
/*
* If an ITS is available, restore its context after
* the Redistributor using:
* gicv3_its_restore(gits_base, &its_ctx[i])
* An implementation-defined sequence may be required to
* restore the whole ITS state. The ITS must also be
* re-enabled after this sequence has been executed.
*/
}
/******************************************************************************
* Marvell common helper to save per-cpu PPI irq states in GICv3
******************************************************************************
*/
void plat_marvell_gic_irq_pcpu_save(void)
{
gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx);
}
/******************************************************************************
* Marvell common helper to restore per-cpu PPI irq states in GICv3
******************************************************************************
*/
void plat_marvell_gic_irq_pcpu_restore(void)
{
gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx);
}
......@@ -49,6 +49,6 @@ mrvl_clean:
${DOIMAGETOOL}: mrvl_clean
@$(DOIMAGE_LIBS_CHECK)
${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH} WTMI_IMG=$(WTMI_IMG)
${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH} VERSION=$(SUBVERSION) WTMI_IMG=$(WTMI_IMG)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment