diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index e55ce3c09fbb1faa6570c5a46d71283b872f7f54..948e87b4f25bd19ad35578b08bce9b26cc01a606 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -26,7 +26,7 @@ BL33 should be ``~/project/u-boot/u-boot.bin`` *u-boot.bin* should be used and not *u-boot-spl.bin* -Set MSS/SCP image path (mandatory only for A7K/8K/CN913x) +Set MSS/SCP image path (mandatory only for A7K/8K/CN913x when MSS_SUPPORT=1) .. code:: shell diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c index d1c26f8d38de84d5fd6142c40a89f5782ff0b306..c8ba9b8d348d1a8c45fcdfb7d3208bdfe2b85b78 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.c +++ b/drivers/marvell/comphy/phy-comphy-cp110.c @@ -61,6 +61,11 @@ SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET) #define SAR_STATUS_0_REG 200 #define DFX_FROM_COMPHY_ADDR(x) ((x & ~0xffffff) + DFX_BASE) +/* Common Phy training */ +#define COMPHY_TRX_TRAIN_COMPHY_OFFS 0x1000 +#define COMPHY_TRX_TRAIN_RX_TRAIN_ENABLE 0x1 +#define COMPHY_TRX_RELATIVE_ADDR(comphy_index) (comphy_train_base + \ + (comphy_index) * COMPHY_TRX_TRAIN_COMPHY_OFFS) /* The same Units Soft Reset Config register are accessed in all PCIe ports * initialization, so a spin lock is defined in case when more than 1 CPUs @@ -829,7 +834,8 @@ static int mvebu_cp110_comphy_sgmii_power_on(uint64_t comphy_base, static int mvebu_cp110_comphy_xfi_power_on(uint64_t comphy_base, uint8_t comphy_index, - uint32_t comphy_mode) + uint32_t comphy_mode, + uint64_t comphy_train_base) { uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr; uint32_t mask, data, speed = COMPHY_GET_SPEED(comphy_mode); @@ -837,7 +843,6 @@ static int mvebu_cp110_comphy_xfi_power_on(uint64_t comphy_base, uint8_t ap_nr, cp_nr; debug_enter(); - mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base); if (rx_trainng_done[ap_nr][cp_nr][comphy_index]) { @@ -1234,6 +1239,14 @@ static int mvebu_cp110_comphy_xfi_power_on(uint64_t comphy_base, data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET; reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); + /* Force rx training on 10G port */ + data = mmio_read_32(COMPHY_TRX_RELATIVE_ADDR(comphy_index)); + data |= COMPHY_TRX_TRAIN_RX_TRAIN_ENABLE; + mmio_write_32(COMPHY_TRX_RELATIVE_ADDR(comphy_index), data); + mdelay(200); + data &= ~COMPHY_TRX_TRAIN_RX_TRAIN_ENABLE; + mmio_write_32(COMPHY_TRX_RELATIVE_ADDR(comphy_index), data); + debug_exit(); return ret; @@ -2284,7 +2297,6 @@ static int mvebu_cp110_comphy_ap_power_on(uint64_t comphy_base, uint32_t comphy_mode) { uint32_t mask, data; - uint8_t ap_nr, cp_nr; uintptr_t comphy_addr = comphy_addr = COMPHY_ADDR(comphy_base, comphy_index); @@ -2301,10 +2313,16 @@ static int mvebu_cp110_comphy_ap_power_on(uint64_t comphy_base, reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); debug_exit(); - /* Start AP Firmware */ - mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base); - mg_start_ap_fw(cp_nr, comphy_index); +#if MSS_SUPPORT + do { + uint8_t ap_nr, cp_nr; + + /* start ap fw */ + mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base); + mg_start_ap_fw(cp_nr, comphy_index); + } while (0); +#endif return 0; } @@ -2343,8 +2361,10 @@ int mvebu_cp110_comphy_digital_reset(uint64_t comphy_base, return 0; } -int mvebu_cp110_comphy_power_on(uint64_t comphy_base, uint8_t comphy_index, - uint64_t comphy_mode) +int mvebu_cp110_comphy_power_on(uint64_t comphy_base, + uint8_t comphy_index, + uint64_t comphy_mode, + uint64_t comphy_train_base) { int mode = COMPHY_GET_MODE(comphy_mode); int err = 0; @@ -2368,7 +2388,8 @@ int mvebu_cp110_comphy_power_on(uint64_t comphy_base, uint8_t comphy_index, case (COMPHY_SFI_MODE): err = mvebu_cp110_comphy_xfi_power_on(comphy_base, comphy_index, - comphy_mode); + comphy_mode, + comphy_train_base); break; case (COMPHY_PCIE_MODE): err = mvebu_cp110_comphy_pcie_power_on(comphy_base, diff --git a/drivers/marvell/comphy/phy-comphy-cp110.h b/drivers/marvell/comphy/phy-comphy-cp110.h index b4a21024222c89f9776b3f51ce9e97dc566287ab..0be6c261bd2160cd577ec4e322c5f0be82af1e2a 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.h +++ b/drivers/marvell/comphy/phy-comphy-cp110.h @@ -89,8 +89,9 @@ int mvebu_cp110_comphy_is_pll_locked(uint64_t comphy_base, uint8_t comphy_index); int mvebu_cp110_comphy_power_off(uint64_t comphy_base, uint8_t comphy_index, uint64_t comphy_mode); -int mvebu_cp110_comphy_power_on(uint64_t comphy_base, - uint8_t comphy_index, uint64_t comphy_mode); +int mvebu_cp110_comphy_power_on(uint64_t comphy_base, uint8_t comphy_index, + uint64_t comphy_mode, + uint64_t comphy_train_base); int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, uint8_t comphy_index); int mvebu_cp110_comphy_digital_reset(uint64_t comphy_base, uint8_t comphy_index, diff --git a/drivers/marvell/ddr_phy_access.c b/drivers/marvell/ddr_phy_access.c new file mode 100644 index 0000000000000000000000000000000000000000..352d1eff679570374bfb885c540032a26c00344a --- /dev/null +++ b/drivers/marvell/ddr_phy_access.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2021 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include "ddr_phy_access.h" +#include +#include +#include + +#define DDR_PHY_END_ADDRESS 0x100000 + +#ifdef DDR_PHY_DEBUG +#define debug_printf(...) printf(__VA_ARGS__) +#else +#define debug_printf(...) +#endif + + +/* + * This routine writes 'data' to specified 'address' offset, + * with optional debug print support + */ +int snps_fw_write(uintptr_t offset, uint16_t data) +{ + debug_printf("In %s\n", __func__); + + if (offset < DDR_PHY_END_ADDRESS) { + mmio_write_16(DDR_PHY_BASE_ADDR + (2 * offset), data); + return 0; + } + debug_printf("%s: illegal offset value: 0x%x\n", __func__, offset); + return -EINVAL; +} + +int snps_fw_read(uintptr_t offset, uint16_t *read) +{ + debug_printf("In %s\n", __func__); + + if (offset < DDR_PHY_END_ADDRESS) { + *read = mmio_read_16(DDR_PHY_BASE_ADDR + (2 * offset)); + return 0; + } + debug_printf("%s: illegal offset value: 0x%x\n", __func__, offset); + return -EINVAL; +} + +int mvebu_ddr_phy_write(uintptr_t offset, uint16_t data) +{ + return snps_fw_write(offset, data); +} + +int mvebu_ddr_phy_read(uintptr_t offset, uint16_t *read) +{ + return snps_fw_read(offset, read); +} diff --git a/drivers/marvell/ddr_phy_access.h b/drivers/marvell/ddr_phy_access.h new file mode 100644 index 0000000000000000000000000000000000000000..5f9a6689d5faa88f0c447a73ab24d76a0af2d5cc --- /dev/null +++ b/drivers/marvell/ddr_phy_access.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2021 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#define DEVICE_BASE 0xF0000000 +#define DDR_PHY_OFFSET 0x1000000 +#define DDR_PHY_BASE_ADDR (DEVICE_BASE + DDR_PHY_OFFSET) + +int mvebu_ddr_phy_write(uintptr_t offset, uint16_t data); +int mvebu_ddr_phy_read(uintptr_t offset, uint16_t *read); diff --git a/drivers/marvell/mochi/cp110_setup.c b/drivers/marvell/mochi/cp110_setup.c index 906df66809c04769c0a9aa4a26d0cfb9de205fd9..f12da0ef8159433d4333772715ec1a00e6d7cbf8 100644 --- a/drivers/marvell/mochi/cp110_setup.c +++ b/drivers/marvell/mochi/cp110_setup.c @@ -14,6 +14,7 @@ #include #include +#include #include /* @@ -110,6 +111,8 @@ * TRNG Configuration ******************************************************************************/ #define MVEBU_TRNG_BASE (0x760000) +#define MVEBU_EFUSE_TRNG_ENABLE_EFUSE_WORD MVEBU_AP_LDX_220_189_EFUSE_OFFS +#define MVEBU_EFUSE_TRNG_ENABLE_BIT_OFFSET 13 /* LD0[202] */ enum axi_attr { AXI_ADUNIT_ATTR = 0, @@ -389,6 +392,22 @@ static void cp110_trng_init(uintptr_t base) { static bool done; int ret; + uint32_t reg_val, efuse; + + /* Set access to LD0 */ + reg_val = mmio_read_32(MVEBU_AP_EFUSE_SRV_CTRL_REG); + reg_val &= ~EFUSE_SRV_CTRL_LD_SELECT_MASK; + mmio_write_32(MVEBU_AP_EFUSE_SRV_CTRL_REG, reg_val); + + /* Obtain the AP LD0 bit defining TRNG presence */ + efuse = mmio_read_32(MVEBU_EFUSE_TRNG_ENABLE_EFUSE_WORD); + efuse >>= MVEBU_EFUSE_TRNG_ENABLE_BIT_OFFSET; + efuse &= 1; + + if (efuse == 0) { + VERBOSE("TRNG is not present, skipping"); + return; + } if (!done) { ret = eip76_rng_probe(base + MVEBU_TRNG_BASE); diff --git a/drivers/marvell/secure_dfx_access/armada_thermal.c b/drivers/marvell/secure_dfx_access/armada_thermal.c new file mode 100644 index 0000000000000000000000000000000000000000..4f7191b5c0857b5d640c6483c05595f99b647619 --- /dev/null +++ b/drivers/marvell/secure_dfx_access/armada_thermal.c @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2019 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ +#include +#include +#include +#include +#include +#include +#include "dfx.h" + +/* #define DEBUG_DFX */ +#ifdef DEBUG_DFX +#define debug(format...) NOTICE(format) +#else +#define debug(format, arg...) +#endif + +#define TSEN_CTRL0 0xf06f8084 + #define TSEN_CTRL0_START BIT(0) + #define TSEN_CTRL0_RESET BIT(1) + #define TSEN_CTRL0_ENABLE BIT(2) + #define TSEN_CTRL0_AVG_BYPASS BIT(6) + #define TSEN_CTRL0_CHAN_SHIFT 13 + #define TSEN_CTRL0_CHAN_MASK 0xF + #define TSEN_CTRL0_OSR_SHIFT 24 + #define TSEN_CTRL0_OSR_MAX 0x3 + #define TSEN_CTRL0_MODE_SHIFT 30 + #define TSEN_CTRL0_MODE_EXTERNAL 0x2U + #define TSEN_CTRL0_MODE_MASK 0x3U + +#define TSEN_CTRL1 0xf06f8088 + #define TSEN_CTRL1_INT_EN BIT(25) + #define TSEN_CTRL1_HYST_SHIFT 19 + #define TSEN_CTRL1_HYST_MASK (0x3 << TSEN_CTRL1_HYST_SHIFT) + #define TSEN_CTRL1_THRESH_SHIFT 3 + #define TSEN_CTRL1_THRESH_MASK (0x3ff << TSEN_CTRL1_THRESH_SHIFT) + +#define TSEN_STATUS 0xf06f808c + #define TSEN_STATUS_VALID_OFFSET 16 + #define TSEN_STATUS_VALID_MASK (0x1 << TSEN_STATUS_VALID_OFFSET) + #define TSEN_STATUS_TEMP_OUT_OFFSET 0 + #define TSEN_STATUS_TEMP_OUT_MASK (0x3FF << TSEN_STATUS_TEMP_OUT_OFFSET) + +#define DFX_SERVER_IRQ_SUM_MASK_REG 0xf06f8104 + #define DFX_SERVER_IRQ_EN BIT(1) + +#define DFX_IRQ_CAUSE_REG 0xf06f8108 + +#define DFX_IRQ_MASK_REG 0xf06f810c + #define DFX_IRQ_TSEN_OVERHEAT_OFFSET BIT(22) + +#define THERMAL_SEN_OUTPUT_MSB 512 +#define THERMAL_SEN_OUTPUT_COMP 1024 + +#define COEF_M 423 +#define COEF_B -150000LL + +static void armada_ap806_thermal_read(u_register_t *temp) +{ + uint32_t reg; + + reg = mmio_read_32(TSEN_STATUS); + + reg = ((reg & TSEN_STATUS_TEMP_OUT_MASK) >> + TSEN_STATUS_TEMP_OUT_OFFSET); + + /* + * TSEN output format is signed as a 2s complement number + * ranging from-512 to +511. when MSB is set, need to + * calculate the complement number + */ + if (reg >= THERMAL_SEN_OUTPUT_MSB) + reg -= THERMAL_SEN_OUTPUT_COMP; + + *temp = ((COEF_M * ((signed int)reg)) - COEF_B); +} + +static void armada_ap806_thermal_irq(void) +{ + /* Dummy read, register ROC */ + mmio_read_32(DFX_IRQ_CAUSE_REG); +} + +static void armada_ap806_thermal_overheat_irq_init(void) +{ + uint32_t reg; + + /* Clear DFX temperature IRQ cause */ + reg = mmio_read_32(DFX_IRQ_CAUSE_REG); + + /* Enable DFX Temperature IRQ */ + reg = mmio_read_32(DFX_IRQ_MASK_REG); + reg |= DFX_IRQ_TSEN_OVERHEAT_OFFSET; + mmio_write_32(DFX_IRQ_MASK_REG, reg); + + /* Enable DFX server IRQ */ + reg = mmio_read_32(DFX_SERVER_IRQ_SUM_MASK_REG); + reg |= DFX_SERVER_IRQ_EN; + mmio_write_32(DFX_SERVER_IRQ_SUM_MASK_REG, reg); + + /* Enable overheat interrupt */ + reg = mmio_read_32(TSEN_CTRL1); + reg |= TSEN_CTRL1_INT_EN; + mmio_write_32(TSEN_CTRL1, reg); +} + +static unsigned int armada_mc_to_reg_temp(unsigned int temp_mc) +{ + unsigned int sample; + + sample = (temp_mc + COEF_B) / COEF_M; + + return sample & 0x3ff; +} + +/* + * The documentation states: + * high/low watermark = threshold +/- 0.4761 * 2^(hysteresis + 2) + * which is the mathematical derivation for: + * 0x0 <=> 1.9°C, 0x1 <=> 3.8°C, 0x2 <=> 7.6°C, 0x3 <=> 15.2°C + */ +static unsigned int hyst_levels_mc[] = {1900, 3800, 7600, 15200}; + +static unsigned int armada_mc_to_reg_hyst(int hyst_mc) +{ + int i; + + /* + * We will always take the smallest possible hysteresis to avoid risking + * the hardware integrity by enlarging the threshold by +8°C in the + * worst case. + */ + for (i = ARRAY_SIZE(hyst_levels_mc) - 1; i > 0; i--) + if (hyst_mc >= hyst_levels_mc[i]) + break; + + return i; +} + +static void armada_ap806_thermal_threshold(int thresh_mc, int hyst_mc) +{ + uint32_t ctrl1; + unsigned int threshold = armada_mc_to_reg_temp(thresh_mc); + unsigned int hysteresis = armada_mc_to_reg_hyst(hyst_mc); + + ctrl1 = mmio_read_32(TSEN_CTRL1); + /* Set Threshold */ + if (thresh_mc >= 0) { + ctrl1 &= ~(TSEN_CTRL1_THRESH_MASK); + ctrl1 |= threshold << TSEN_CTRL1_THRESH_SHIFT; + } + + /* Set Hysteresis */ + if (hyst_mc >= 0) { + ctrl1 &= ~(TSEN_CTRL1_HYST_MASK); + ctrl1 |= hysteresis << TSEN_CTRL1_HYST_SHIFT; + } + + mmio_write_32(TSEN_CTRL1, ctrl1); +} + +static void armada_select_channel(int channel) +{ + uint32_t ctrl0; + + /* Stop the measurements */ + ctrl0 = mmio_read_32(TSEN_CTRL0); + ctrl0 &= ~TSEN_CTRL0_START; + mmio_write_32(TSEN_CTRL0, ctrl0); + + /* Reset the mode, internal sensor will be automatically selected */ + ctrl0 &= ~(TSEN_CTRL0_MODE_MASK << TSEN_CTRL0_MODE_SHIFT); + + /* Other channels are external and should be selected accordingly */ + if (channel) { + /* Change the mode to external */ + ctrl0 |= TSEN_CTRL0_MODE_EXTERNAL << + TSEN_CTRL0_MODE_SHIFT; + /* Select the sensor */ + ctrl0 &= ~(TSEN_CTRL0_CHAN_MASK << TSEN_CTRL0_CHAN_SHIFT); + ctrl0 |= (channel - 1) << TSEN_CTRL0_CHAN_SHIFT; + } + + /* Actually set the mode/channel */ + mmio_write_32(TSEN_CTRL0, ctrl0); + + /* Re-start the measurements */ + ctrl0 |= TSEN_CTRL0_START; + mmio_write_32(TSEN_CTRL0, ctrl0); +} + +static void armada_ap806_thermal_init(void) +{ + uint32_t reg; + + reg = mmio_read_32(TSEN_CTRL0); + reg &= ~TSEN_CTRL0_RESET; + reg |= TSEN_CTRL0_START | TSEN_CTRL0_ENABLE; + + /* Sample every ~2ms */ + reg |= TSEN_CTRL0_OSR_MAX << TSEN_CTRL0_OSR_SHIFT; + + /* Enable average (2 samples by default) */ + reg &= ~TSEN_CTRL0_AVG_BYPASS; + + mmio_write_32(TSEN_CTRL0, reg); + + debug("thermal: Initialization done\n"); +} + +static void armada_is_valid(u_register_t *read) +{ + *read = (mmio_read_32(TSEN_STATUS) & TSEN_STATUS_VALID_MASK); +} + +int mvebu_dfx_thermal_handle(u_register_t func, u_register_t *read, + u_register_t x2, u_register_t x3) +{ + debug_enter(); + + switch (func) { + case MV_SIP_DFX_THERMAL_INIT: + armada_ap806_thermal_init(); + break; + case MV_SIP_DFX_THERMAL_READ: + armada_ap806_thermal_read(read); + break; + case MV_SIP_DFX_THERMAL_IRQ: + armada_ap806_thermal_irq(); + break; + case MV_SIP_DFX_THERMAL_THRESH: + armada_ap806_thermal_threshold(x2, x3); + armada_ap806_thermal_overheat_irq_init(); + break; + case MV_SIP_DFX_THERMAL_IS_VALID: + armada_is_valid(read); + break; + case MV_SIP_DFX_THERMAL_SEL_CHANNEL: + armada_select_channel(x2); + break; + default: + ERROR("unsupported dfx func\n"); + return -EINVAL; + } + + debug_exit(); + + return 0; +} diff --git a/drivers/marvell/secure_dfx_access/dfx.h b/drivers/marvell/secure_dfx_access/dfx.h new file mode 100644 index 0000000000000000000000000000000000000000..88c4de864704dadad15119b9107b5dcb8e11832c --- /dev/null +++ b/drivers/marvell/secure_dfx_access/dfx.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2019 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +/* DFX sub-FID */ +#define MV_SIP_DFX_THERMAL_INIT 1 +#define MV_SIP_DFX_THERMAL_READ 2 +#define MV_SIP_DFX_THERMAL_IS_VALID 3 +#define MV_SIP_DFX_THERMAL_IRQ 4 +#define MV_SIP_DFX_THERMAL_THRESH 5 +#define MV_SIP_DFX_THERMAL_SEL_CHANNEL 6 + +#define MV_SIP_DFX_SREAD 20 +#define MV_SIP_DFX_SWRITE 21 + +int mvebu_dfx_thermal_handle(u_register_t func, u_register_t *read, + u_register_t x2, u_register_t x3); +int mvebu_dfx_misc_handle(u_register_t func, u_register_t *read, + u_register_t addr, u_register_t val); diff --git a/drivers/marvell/secure_dfx_access/misc_dfx.c b/drivers/marvell/secure_dfx_access/misc_dfx.c new file mode 100644 index 0000000000000000000000000000000000000000..189105f9f2fac7eebfabfa82494c50a23bbac838 --- /dev/null +++ b/drivers/marvell/secure_dfx_access/misc_dfx.c @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2021 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include "dfx.h" +#include +#include +#include + +/* #define DEBUG_DFX */ +#ifdef DEBUG_DFX +#define debug(format...) NOTICE(format) +#else +#define debug(format, arg...) +#endif + +#define SAR_BASE (MVEBU_REGS_BASE + 0x6F8200) +#define SAR_SIZE 0x4 +#define AP_DEV_ID_STATUS_REG (MVEBU_REGS_BASE + 0x6F8240) +#define JTAG_DEV_ID_STATUS_REG (MVEBU_REGS_BASE + 0x6F8244) +#define EFUSE_CTRL (MVEBU_REGS_BASE + 0x6F8008) +#define EFUSE_LD_BASE (MVEBU_REGS_BASE + 0x6F8F00) +#define EFUSE_LD_SIZE 0x1C +#define EFUSE_HD_BASE (MVEBU_REGS_BASE + 0x6F9000) +#define EFUSE_HD_SIZE 0x3F8 + +/* AP806 CPU DFS register mapping*/ +#define AP806_CA72MP2_0_PLL_CR_0_BASE (MVEBU_REGS_BASE + 0x6F8278) +#define AP806_CA72MP2_0_PLL_CR_1_BASE (MVEBU_REGS_BASE + 0x6F8280) +#define AP806_CA72MP2_0_PLL_CR_2_BASE (MVEBU_REGS_BASE + 0x6F8284) +#define AP806_CA72MP2_0_PLL_SR_BASE (MVEBU_REGS_BASE + 0x6F8C94) + +/* AP807 CPU DFS register mapping */ +#define AP807_DEVICE_GENERAL_CR_10_BASE (MVEBU_REGS_BASE + 0x6F8278) +#define AP807_DEVICE_GENERAL_CR_11_BASE (MVEBU_REGS_BASE + 0x6F827C) +#define AP807_DEVICE_GENERAL_STATUS_6_BASE (MVEBU_REGS_BASE + 0x6F8C98) + +#ifdef MVEBU_SOC_AP807 + #define CLUSTER_OFFSET 0x8 + #define CLK_DIVIDER_REG AP807_DEVICE_GENERAL_CR_10_BASE + #define CLK_FORCE_REG AP807_DEVICE_GENERAL_CR_11_BASE + #define CLK_RATIO_REG AP807_DEVICE_GENERAL_CR_11_BASE + #define CLK_RATIO_STATE_REG AP807_DEVICE_GENERAL_STATUS_6_BASE +#else + #define CLUSTER_OFFSET 0x14 + #define CLK_DIVIDER_REG AP806_CA72MP2_0_PLL_CR_0_BASE + #define CLK_FORCE_REG AP806_CA72MP2_0_PLL_CR_1_BASE + #define CLK_RATIO_REG AP806_CA72MP2_0_PLL_CR_2_BASE + #define CLK_RATIO_STATE_REG AP806_CA72MP2_0_PLL_SR_BASE +#endif /* MVEBU_SOC_AP807 */ + +static _Bool is_valid(u_register_t addr) +{ + switch (addr) { + case AP_DEV_ID_STATUS_REG: + case JTAG_DEV_ID_STATUS_REG: + case SAR_BASE ... (SAR_BASE + SAR_SIZE): + case EFUSE_LD_BASE ... (EFUSE_LD_BASE + EFUSE_LD_SIZE): + case EFUSE_HD_BASE ... (EFUSE_HD_BASE + EFUSE_HD_SIZE): + case EFUSE_CTRL: + /* cpu-clk related registers */ + case CLK_DIVIDER_REG: + case CLK_DIVIDER_REG + CLUSTER_OFFSET: + case CLK_FORCE_REG: + case CLK_FORCE_REG + CLUSTER_OFFSET: +#ifndef MVEBU_SOC_AP807 + case CLK_RATIO_REG: + case CLK_RATIO_REG + CLUSTER_OFFSET: +#endif + case CLK_RATIO_STATE_REG: + case CLK_RATIO_STATE_REG + CLUSTER_OFFSET: + return true; + default: + return false; + } +} + +static int armada_dfx_sread(u_register_t *read, u_register_t addr) +{ + if (!is_valid(addr)) + return -EINVAL; + + *read = mmio_read_32(addr); + + return 0; +} + +static int armada_dfx_swrite(u_register_t addr, u_register_t val) +{ + if (!is_valid(addr)) + return -EINVAL; + + mmio_write_32(addr, val); + + return 0; +} + +int mvebu_dfx_misc_handle(u_register_t func, u_register_t *read, + u_register_t addr, u_register_t val) +{ + debug_enter(); + + debug("func %ld, addr 0x%lx, val 0x%lx\n", func, addr, val); + + switch (func) { + case MV_SIP_DFX_SREAD: + return armada_dfx_sread(read, addr); + case MV_SIP_DFX_SWRITE: + return armada_dfx_swrite(addr, val); + default: + ERROR("unsupported dfx misc sub-func\n"); + return -EINVAL; + } + + debug_exit(); + + return 0; +} diff --git a/include/plat/marvell/armada/a8k/common/efuse_def.h b/include/plat/marvell/armada/a8k/common/efuse_def.h new file mode 100644 index 0000000000000000000000000000000000000000..ff1d4a33139234753cf40204781a11516079a381 --- /dev/null +++ b/include/plat/marvell/armada/a8k/common/efuse_def.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2021 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef EFUSE_DEF_H +#define EFUSE_DEF_H + +#include + +#define MVEBU_AP_EFUSE_SRV_CTRL_REG (MVEBU_AP_GEN_MGMT_BASE + 0x8) +#define EFUSE_SRV_CTRL_LD_SELECT_OFFS 6 +#define EFUSE_SRV_CTRL_LD_SELECT_MASK (1 << EFUSE_SRV_CTRL_LD_SELECT_OFFS) + +#define MVEBU_AP_LD_EFUSE_BASE (MVEBU_AP_GEN_MGMT_BASE + 0xF00) +/* Bits [31:0] - 32 data bits total */ +#define MVEBU_AP_LDX_31_0_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE) +/* Bits [62:32] - 31 data bits total 32nd bit is parity for bits [62:0]*/ +#define MVEBU_AP_LDX_62_32_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x4) +/* Bits [94:63] - 32 data bits total */ +#define MVEBU_AP_LDX_94_63_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x8) +/* Bits [125:95] - 31 data bits total, 32nd bit is parity for bits [125:63] */ +#define MVEBU_AP_LDX_125_95_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0xC) +/* Bits [157:126] - 32 data bits total */ +#define MVEBU_AP_LDX_126_157_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x10) +/* Bits [188:158] - 31 data bits total, 32nd bit is parity for bits [188:126] */ +#define MVEBU_AP_LDX_188_158_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x14) +/* Bits [220:189] - 32 data bits total */ +#define MVEBU_AP_LDX_220_189_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x18) + +#endif /* EFUSE_DEF_H */ diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk index 8a463eafe5d77d5488bea7f2d475d0115b02d166..90883f285a4102849eaa1e0ccbcb427c9496f123 100644 --- a/plat/marvell/armada/a8k/common/a8k_common.mk +++ b/plat/marvell/armada/a8k/common/a8k_common.mk @@ -10,13 +10,14 @@ PLAT_COMMON_BASE := plat/marvell/armada/a8k/common MARVELL_DRV_BASE := drivers/marvell MARVELL_COMMON_BASE := plat/marvell/armada/common -MARVELL_SVC_TEST := 0 +MARVELL_SVC_TEST := 0 $(eval $(call add_define,MARVELL_SVC_TEST)) ERRATA_A72_859971 := 1 # Enable MSS support for a8k family MSS_SUPPORT := 1 +$(eval $(call add_define,MSS_SUPPORT)) # Disable EL3 cache for power management BL31_CACHE_DISABLE := 0 @@ -112,11 +113,17 @@ MARVELL_DRV := $(MARVELL_DRV_BASE)/io_win.c \ $(MARVELL_DRV_BASE)/amb_adec.c \ $(MARVELL_DRV_BASE)/ccu.c \ $(MARVELL_DRV_BASE)/cache_llc.c \ - $(MARVELL_DRV_BASE)/comphy/phy-comphy-cp110.c \ - $(MARVELL_DRV_BASE)/mc_trustzone/mc_trustzone.c \ - $(MARVELL_DRV_BASE)/mg_conf_cm3/mg_conf_cm3.c \ + $(MARVELL_DRV_BASE)/comphy/phy-comphy-cp110.c \ + $(MARVELL_DRV_BASE)/mc_trustzone/mc_trustzone.c \ + $(MARVELL_DRV_BASE)/secure_dfx_access/armada_thermal.c \ + $(MARVELL_DRV_BASE)/secure_dfx_access/misc_dfx.c \ + $(MARVELL_DRV_BASE)/ddr_phy_access.c \ drivers/rambus/trng_ip_76.c +ifeq (${MSS_SUPPORT}, 1) +MARVELL_DRV += $(MARVELL_DRV_BASE)/mg_conf_cm3/mg_conf_cm3.c +endif + BL31_PORTING_SOURCES := $(BOARD_DIR)/board/marvell_plat_config.c ifeq ($(SYSTEM_POWER_SUPPORT),1) @@ -139,6 +146,8 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a72.S \ # Add trace functionality for PM BL31_SOURCES += $(PLAT_COMMON_BASE)/plat_pm_trace.c + +ifeq (${MSS_SUPPORT}, 1) # Force builds with BL2 image on a80x0 platforms ifndef SCP_BL2 $(error "Error: SCP_BL2 image is mandatory for a8k family") @@ -146,6 +155,7 @@ endif # MSS (SCP) build include $(PLAT_COMMON_BASE)/mss/mss_a8k.mk +endif # BLE (ROM context execution code, AKA binary extension) BLE_PATH ?= $(PLAT_COMMON_BASE)/ble diff --git a/plat/marvell/armada/a8k/common/include/a8k_plat_def.h b/plat/marvell/armada/a8k/common/include/a8k_plat_def.h index de8031536c0d2b3cd6276d14a41072a7f1c441fe..3a0fd4b9dd2996f2793f61608afdabe01a5564a4 100644 --- a/plat/marvell/armada/a8k/common/include/a8k_plat_def.h +++ b/plat/marvell/armada/a8k/common/include/a8k_plat_def.h @@ -64,7 +64,8 @@ #define MVEBU_AP_GPIO_DATA_IN (MVEBU_AP_GPIO_REGS + 0x10) #define MVEBU_AP_I2C_BASE (MVEBU_REGS_BASE + 0x511000) #define MVEBU_CP0_I2C_BASE (MVEBU_CP_REGS_BASE(0) + 0x701000) -#define MVEBU_AP_EXT_TSEN_BASE (MVEBU_RFU_BASE + 0x8084) +#define MVEBU_AP_GEN_MGMT_BASE (MVEBU_RFU_BASE + 0x8000) +#define MVEBU_AP_EXT_TSEN_BASE (MVEBU_AP_GEN_MGMT_BASE + 0x84) #define MVEBU_AP_MC_TRUSTZONE_REG_LOW(ap, win) (MVEBU_REGS_BASE_AP(ap) + \ 0x20080 + ((win) * 0x8)) diff --git a/plat/marvell/armada/a8k/common/mss/mss_a8k.mk b/plat/marvell/armada/a8k/common/mss/mss_a8k.mk index d8d4921933031d3ace36374a8533654a7cf507cb..315fc874133e286c1305ced2972d48f9bdb028a6 100644 --- a/plat/marvell/armada/a8k/common/mss/mss_a8k.mk +++ b/plat/marvell/armada/a8k/common/mss/mss_a8k.mk @@ -11,7 +11,8 @@ A8K_MSS_SOURCE := $(PLAT_MARVELL)/a8k/common/mss BL2_SOURCES += $(A8K_MSS_SOURCE)/mss_bl2_setup.c \ $(MARVELL_MOCHI_DRV) -BL31_SOURCES += $(A8K_MSS_SOURCE)/mss_pm_ipc.c +BL31_SOURCES += $(A8K_MSS_SOURCE)/mss_pm_ipc.c \ + $(A8K_MSS_SOURCE)/mss_bl31_setup.c PLAT_INCLUDES += -I$(A8K_MSS_SOURCE) diff --git a/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c index 71fa2b86872959c150c6992051f8c0d408a9b35d..dee2d5b0ba95f75654628a5f02402e250605f885 100644 --- a/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c +++ b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c @@ -16,7 +16,7 @@ #include #include /* timer functionality */ - +#include "mss_defs.h" #include "mss_scp_bootloader.h" /* MSS windows configuration */ @@ -30,10 +30,6 @@ #define MSS_EXTERNAL_ADDR_MASK 0xfffffff #define MSS_INTERNAL_ACCESS_BIT 28 -#define MSS_AP_REGS_OFFSET 0x580000 -#define MSS_CP_SRAM_OFFSET 0x220000 -#define MSS_CP_REGS_OFFSET 0x280000 - struct addr_map_win ccu_mem_map[] = { {MVEBU_CP_REGS_BASE(0), 0x4000000, IO_0_TID} }; @@ -130,11 +126,7 @@ uintptr_t bl2_plat_get_cp_mss_regs(int ap_idx, int cp_idx) uintptr_t bl2_plat_get_cp_mss_sram(int ap_idx, int cp_idx) { - if (is_secure()) { - return MVEBU_CP_REGS_BASE(cp_idx) + MSS_CP_SRAM_OFFSET; - } - - return 0; /* SRAM will not be used */ + return MVEBU_CP_REGS_BASE(cp_idx) + MSS_CP_SRAM_OFFSET; } uintptr_t bl2_plat_get_ap_mss_regs(int ap_idx) diff --git a/plat/marvell/armada/a8k/common/mss/mss_bl31_setup.c b/plat/marvell/armada/a8k/common/mss/mss_bl31_setup.c new file mode 100644 index 0000000000000000000000000000000000000000..52a892956df23ff1fc223a913ce38cfbdc14eb4b --- /dev/null +++ b/plat/marvell/armada/a8k/common/mss/mss_bl31_setup.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2021 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include + +#include + +#include "mss_defs.h" + +void mss_start_cp_cm3(int cp) +{ + uint32_t magic; + uintptr_t sram = MVEBU_CP_REGS_BASE(cp) + MSS_CP_SRAM_OFFSET; + uintptr_t regs = MVEBU_CP_REGS_BASE(cp) + MSS_CP_REGS_OFFSET; + + magic = mmio_read_32(sram); + + /* Make sure the FW was loaded */ + if (magic != MSS_FW_READY_MAGIC) { + return; + } + + NOTICE("Starting CP%d MSS CPU\n", cp); + /* remove the magic */ + mmio_write_32(sram, 0); + /* Release M3 from reset */ + mmio_write_32(MSS_M3_RSTCR(regs), + (MSS_M3_RSTCR_RST_OFF << MSS_M3_RSTCR_RST_OFFSET)); +} diff --git a/plat/marvell/armada/a8k/common/mss/mss_defs.h b/plat/marvell/armada/a8k/common/mss/mss_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..6956461a55aafd2a48aaf28a8d6b3bb17ce06006 --- /dev/null +++ b/plat/marvell/armada/a8k/common/mss/mss_defs.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2021 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MSS_DEFS_H +#define MSS_DEFS_H + +#define MSS_DMA_SRCBR(base) (base + 0xC0) +#define MSS_DMA_DSTBR(base) (base + 0xC4) +#define MSS_DMA_CTRLR(base) (base + 0xC8) +#define MSS_M3_RSTCR(base) (base + 0xFC) + +#define MSS_DMA_CTRLR_SIZE_OFFSET (0) +#define MSS_DMA_CTRLR_REQ_OFFSET (15) +#define MSS_DMA_CTRLR_REQ_SET (1) +#define MSS_DMA_CTRLR_ACK_OFFSET (12) +#define MSS_DMA_CTRLR_ACK_MASK (0x1) +#define MSS_DMA_CTRLR_ACK_READY (1) +#define MSS_M3_RSTCR_RST_OFFSET (0) +#define MSS_M3_RSTCR_RST_OFF (1) + +#define MSS_FW_READY_MAGIC 0x46575144 /* FWRD */ + +#define MSS_AP_REGS_OFFSET 0x00580000 +#define MSS_CP_SRAM_OFFSET 0x00220000 +#define MSS_CP_REGS_OFFSET 0x00280000 + +void mss_start_cp_cm3(int cp); + +#endif /* MSS_DEFS_H */ diff --git a/plat/marvell/armada/a8k/common/plat_bl31_setup.c b/plat/marvell/armada/a8k/common/plat_bl31_setup.c index 552c9b298ec3bd56e86ea11f7c336a87eca22d78..db85cce85d8d0e3761ebe2faa9c0cf75fd9372be 100644 --- a/plat/marvell/armada/a8k/common/plat_bl31_setup.c +++ b/plat/marvell/armada/a8k/common/plat_bl31_setup.c @@ -16,8 +16,11 @@ #include #include #include +#if MSS_SUPPORT #include #include +#include +#endif /* In Armada-8k family AP806/AP807, CP0 connected to PIDI * and CP1 connected to IHB via MCI #0 @@ -51,6 +54,7 @@ static void marvell_bl31_mpp_init(int cp) mmio_write_32(MVEBU_CP_MPP_REGS(0, 4), reg | 0x2200000); } +#if MSS_SUPPORT void marvell_bl31_mss_init(void) { struct mss_pm_ctrl_block *mss_pm_crtl = @@ -70,6 +74,7 @@ void marvell_bl31_mss_init(void) if (mss_pm_crtl->ipc_state == IPC_INITIALIZED) mv_pm_ipc_init(mss_pm_crtl->ipc_base_address | MVEBU_REGS_BASE); } +#endif _Bool is_pm_fw_running(void) { @@ -120,16 +125,22 @@ void bl31_plat_arch_setup(void) STREAM_ID_BASE + (cp * MAX_STREAM_ID_PER_CP)); marvell_bl31_mpp_init(cp); + +#if MSS_SUPPORT + /* Release CP MSS CPU from reset once the CP init is done */ + mss_start_cp_cm3(cp); +#endif } for (cp = 1; cp < CP_COUNT; cp++) mci_link_tune(cp - 1); +#if MSS_SUPPORT /* initialize IPC between MSS and ATF */ if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) marvell_bl31_mss_init(); - +#endif /* Configure GPIO */ marvell_gpio_config(); diff --git a/plat/marvell/armada/a8k/common/plat_ble_setup.c b/plat/marvell/armada/a8k/common/plat_ble_setup.c index 41143276a31e46f908449c4232586789e9903ecc..9c5ee153af801efce5c7921e518044d3d6f62d81 100644 --- a/plat/marvell/armada/a8k/common/plat_ble_setup.c +++ b/plat/marvell/armada/a8k/common/plat_ble_setup.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -27,7 +28,6 @@ #define MMAP_RESTORE_SAVED 1 /* SAR clock settings */ -#define MVEBU_AP_GEN_MGMT_BASE (MVEBU_RFU_BASE + 0x8000) #define MVEBU_AP_SAR_REG_BASE(r) (MVEBU_AP_GEN_MGMT_BASE + 0x200 +\ ((r) << 2)) @@ -82,11 +82,6 @@ (0x1 << AVS_SOFT_RESET_OFFSET) | \ (0x1 << AVS_ENABLE_OFFSET)) -#define MVEBU_AP_EFUSE_SRV_CTRL_REG (MVEBU_AP_GEN_MGMT_BASE + 0x8) -#define EFUSE_SRV_CTRL_LD_SELECT_OFFS 6 -#define EFUSE_SRV_CTRL_LD_SEL_USER_MASK (1 << EFUSE_SRV_CTRL_LD_SELECT_OFFS) - - /* * - Identification information in the LD-0 eFuse: * DRO: LD0[74:65] - Not used by the SW @@ -96,14 +91,7 @@ * Cluster 1 PWR: LD0[193] - if set to 1, power down CPU Cluster-1 * resulting in 2 CPUs active only (7020) */ -#define MVEBU_AP_LD_EFUSE_BASE (MVEBU_AP_GEN_MGMT_BASE + 0xF00) -/* Bits [94:63] - 32 data bits total */ -#define MVEBU_AP_LD0_94_63_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x8) -/* Bits [125:95] - 31 data bits total, 32nd bit is parity for bits [125:63] */ -#define MVEBU_AP_LD0_125_95_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0xC) -/* Bits [220:189] - 32 data bits total */ -#define MVEBU_AP_LD0_220_189_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x18) -/* Offsets for the above 2 fields combined into single 64-bit value [125:63] */ +/* Offsets for 2 efuse fields combined into single 64-bit value [125:63] */ #define EFUSE_AP_LD0_DRO_OFFS 2 /* LD0[74:65] */ #define EFUSE_AP_LD0_DRO_MASK 0x3FF #define EFUSE_AP_LD0_REVID_OFFS 12 /* LD0[78:75] */ @@ -376,20 +364,20 @@ static void ble_plat_svc_config(void) uint8_t avs_data_bits, min_sw_ver, svc_fields; unsigned int ap_type; - /* Set access to LD0 */ + /* Get test EERPOM data */ avs_workpoint = avs_update_from_eeprom(0); if (avs_workpoint) goto set_aws_wp; /* Set access to LD0 */ reg_val = mmio_read_32(MVEBU_AP_EFUSE_SRV_CTRL_REG); - reg_val &= ~EFUSE_SRV_CTRL_LD_SELECT_OFFS; + reg_val &= ~EFUSE_SRV_CTRL_LD_SELECT_MASK; mmio_write_32(MVEBU_AP_EFUSE_SRV_CTRL_REG, reg_val); /* Obtain the value of LD0[125:63] */ - efuse = mmio_read_32(MVEBU_AP_LD0_125_95_EFUSE_OFFS); + efuse = mmio_read_32(MVEBU_AP_LDX_125_95_EFUSE_OFFS); efuse <<= 32; - efuse |= mmio_read_32(MVEBU_AP_LD0_94_63_EFUSE_OFFS); + efuse |= mmio_read_32(MVEBU_AP_LDX_94_63_EFUSE_OFFS); /* SW Revision: * Starting from SW revision 1 the SVC flow is supported. @@ -452,7 +440,7 @@ static void ble_plat_svc_config(void) perr[i] = 1; /* register the error */ } - single_cluster = mmio_read_32(MVEBU_AP_LD0_220_189_EFUSE_OFFS); + single_cluster = mmio_read_32(MVEBU_AP_LDX_220_189_EFUSE_OFFS); single_cluster = (single_cluster >> EFUSE_AP_LD0_CLUSTER_DOWN_OFFS) & 1; device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0)); diff --git a/plat/marvell/armada/a8k/common/plat_pm.c b/plat/marvell/armada/a8k/common/plat_pm.c index 96e95c271582f8a9a9c17c64940a4707f63c4e35..9ea92760824b3cd8775adae3b89baf2fc23c10a2 100644 --- a/plat/marvell/armada/a8k/common/plat_pm.c +++ b/plat/marvell/armada/a8k/common/plat_pm.c @@ -18,7 +18,9 @@ #include #include +#if MSS_SUPPORT #include +#endif #include #include @@ -396,6 +398,7 @@ static int a8k_pwr_domain_on(u_register_t mpidr) /* Power up CPU (CPUs 1-3 are powered off at start of BLE) */ plat_marvell_cpu_powerup(mpidr); +#if MSS_SUPPORT if (is_pm_fw_running()) { unsigned int target = ((mpidr & 0xFF) + (((mpidr >> 8) & 0xFF) * 2)); @@ -417,11 +420,12 @@ static int a8k_pwr_domain_on(u_register_t mpidr) /* trace message */ PM_TRACE(TRACE_PWR_DOMAIN_ON | target); - } else { + } else +#endif + { /* proprietary CPU ON exection flow */ plat_marvell_cpu_on(mpidr); } - return 0; } @@ -441,6 +445,7 @@ static int a8k_validate_ns_entrypoint(uintptr_t entrypoint) */ static void a8k_pwr_domain_off(const psci_power_state_t *target_state) { +#if MSS_SUPPORT if (is_pm_fw_running()) { unsigned int idx = plat_my_core_pos(); @@ -466,6 +471,7 @@ static void a8k_pwr_domain_off(const psci_power_state_t *target_state) } else { INFO("%s: is not supported without SCP\n", __func__); } +#endif } /* Get PM config to power off the SoC */ @@ -586,6 +592,7 @@ static void plat_marvell_power_off_prepare(struct power_off_method *pm_cfg, */ static void a8k_pwr_domain_suspend(const psci_power_state_t *target_state) { +#if MSS_SUPPORT if (is_pm_fw_running()) { unsigned int idx; @@ -610,7 +617,9 @@ static void a8k_pwr_domain_suspend(const psci_power_state_t *target_state) /* trace message */ PM_TRACE(TRACE_PWR_DOMAIN_SUSPEND); - } else { + } else +#endif + { uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; INFO("Suspending to RAM\n"); diff --git a/plat/marvell/armada/a8k/common/plat_pm_trace.c b/plat/marvell/armada/a8k/common/plat_pm_trace.c index f589ff31b86ed6a317303e53c394ca0af38beb2f..e02a89386d70fc8f6a5d033f8a9ab488f0a0201f 100644 --- a/plat/marvell/armada/a8k/common/plat_pm_trace.c +++ b/plat/marvell/armada/a8k/common/plat_pm_trace.c @@ -8,10 +8,11 @@ #include #include +#if MSS_SUPPORT #include -#include #ifdef PM_TRACE_ENABLE +#include /* core trace APIs */ core_trace_func funcTbl[PLATFORM_CORE_COUNT] = { @@ -90,3 +91,4 @@ void pm_core_3_trace(unsigned int trace) AP_MSS_ATF_TRACE_SIZE_MASK)); } #endif /* PM_TRACE_ENABLE */ +#endif /* MSS_SUPPORT */ diff --git a/plat/marvell/armada/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk index 04eb51c48d2b060b70873c5401e02f3c05d65b55..f0e6edf2e8781a13d085f9678d36b0b422dcc3b7 100644 --- a/plat/marvell/armada/common/marvell_common.mk +++ b/plat/marvell/armada/common/marvell_common.mk @@ -6,10 +6,6 @@ MARVELL_PLAT_BASE := plat/marvell/armada MARVELL_PLAT_INCLUDE_BASE := include/plat/marvell/armada -include plat/marvell/version.mk - -VERSION_STRING +=(Marvell-${SUBVERSION}) - SEPARATE_CODE_AND_RODATA := 1 # flag to switch from PLL to ARO diff --git a/plat/marvell/armada/common/mrvl_sip_svc.c b/plat/marvell/armada/common/mrvl_sip_svc.c index 64187fb48b4b07fb0384687445fea23565ee8fb9..c4c5c0eeaee1d5bec175cfa76fadf91784c8ed03 100644 --- a/plat/marvell/armada/common/mrvl_sip_svc.c +++ b/plat/marvell/armada/common/mrvl_sip_svc.c @@ -16,6 +16,8 @@ #include #include "comphy/phy-comphy-cp110.h" +#include "secure_dfx_access/dfx.h" +#include "ddr_phy_access.h" #include /* #define DEBUG_COMPHY */ @@ -37,6 +39,9 @@ #define MV_SIP_LLC_ENABLE 0x82000011 #define MV_SIP_PMU_IRQ_ENABLE 0x82000012 #define MV_SIP_PMU_IRQ_DISABLE 0x82000013 +#define MV_SIP_DFX 0x82000014 +#define MV_SIP_DDR_PHY_WRITE 0x82000015 +#define MV_SIP_DDR_PHY_READ 0x82000016 /* TRNG */ #define MV_SIP_RNG_64 0xC200FF11 @@ -45,6 +50,9 @@ #define MVEBU_COMPHY_OFFSET 0x441000 #define MVEBU_CP_BASE_MASK (~0xffffff) +/* Common PHY register */ +#define COMPHY_TRX_TRAIN_CTRL_REG_0_OFFS 0x120a2c + /* This macro is used to identify COMPHY related calls from SMC function ID */ #define is_comphy_fid(fid) \ ((fid) >= MV_SIP_COMPHY_POWER_ON && (fid) <= MV_SIP_COMPHY_DIG_RESET) @@ -71,8 +79,7 @@ uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid, void *handle, u_register_t flags) { - u_register_t ret; - uint32_t w2[2] = {0, 0}; + u_register_t ret, read, x5 = x1; int i; debug("%s: got SMC (0x%x) x1 0x%lx, x2 0x%lx, x3 0x%lx\n", @@ -86,6 +93,7 @@ uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid, SMC_RET1(handle, SMC_UNK); } + x5 = x1 + COMPHY_TRX_TRAIN_CTRL_REG_0_OFFS; x1 += MVEBU_COMPHY_OFFSET; if (x2 >= MAX_LANE_NR) { @@ -100,7 +108,7 @@ uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid, /* Comphy related FID's */ case MV_SIP_COMPHY_POWER_ON: /* x1: comphy_base, x2: comphy_index, x3: comphy_mode */ - ret = mvebu_cp110_comphy_power_on(x1, x2, x3); + ret = mvebu_cp110_comphy_power_on(x1, x2, x3, x5); SMC_RET1(handle, ret); case MV_SIP_COMPHY_POWER_OFF: /* x1: comphy_base, x2: comphy_index */ @@ -136,9 +144,33 @@ uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid, mvebu_pmu_interrupt_disable(); SMC_RET1(handle, 0); #endif + case MV_SIP_DFX: + if (x1 >= MV_SIP_DFX_THERMAL_INIT && + x1 <= MV_SIP_DFX_THERMAL_SEL_CHANNEL) { + ret = mvebu_dfx_thermal_handle(x1, &read, x2, x3); + SMC_RET2(handle, ret, read); + } + if (x1 >= MV_SIP_DFX_SREAD && x1 <= MV_SIP_DFX_SWRITE) { + ret = mvebu_dfx_misc_handle(x1, &read, x2, x3); + SMC_RET2(handle, ret, read); + } + + SMC_RET1(handle, SMC_UNK); + case MV_SIP_DDR_PHY_WRITE: + ret = mvebu_ddr_phy_write(x1, x2); + SMC_RET1(handle, ret); + case MV_SIP_DDR_PHY_READ: + read = 0; + ret = mvebu_ddr_phy_read(x1, (uint16_t *)&read); + SMC_RET2(handle, ret, read); case MV_SIP_RNG_64: - ret = eip76_rng_get_random((uint8_t *)&w2, 4 * (x1 % 2 + 1)); - SMC_RET3(handle, ret, w2[0], w2[1]); + if ((x1 % 2 + 1) > sizeof(read)/4) { + ERROR("%s: Maximum %ld random bytes per SMC call\n", + __func__, sizeof(read)); + SMC_RET1(handle, SMC_UNK); + } + ret = eip76_rng_get_random((uint8_t *)&read, 4 * (x1 % 2 + 1)); + SMC_RET2(handle, ret, read); default: ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); SMC_RET1(handle, SMC_UNK); diff --git a/plat/marvell/armada/common/mss/mss_scp_bootloader.c b/plat/marvell/armada/common/mss/mss_scp_bootloader.c index f669a777bed384d94bd899297f62c4d67c8c1248..fbede1b1a72b2dfcf5bfb20518fa42114d577e47 100644 --- a/plat/marvell/armada/common/mss/mss_scp_bootloader.c +++ b/plat/marvell/armada/common/mss/mss_scp_bootloader.c @@ -19,22 +19,9 @@ #include #include #include +#include #include -#define MSS_DMA_SRCBR(base) (base + 0xC0) -#define MSS_DMA_DSTBR(base) (base + 0xC4) -#define MSS_DMA_CTRLR(base) (base + 0xC8) -#define MSS_M3_RSTCR(base) (base + 0xFC) - -#define MSS_DMA_CTRLR_SIZE_OFFSET (0) -#define MSS_DMA_CTRLR_REQ_OFFSET (15) -#define MSS_DMA_CTRLR_REQ_SET (1) -#define MSS_DMA_CTRLR_ACK_OFFSET (12) -#define MSS_DMA_CTRLR_ACK_MASK (0x1) -#define MSS_DMA_CTRLR_ACK_READY (1) -#define MSS_M3_RSTCR_RST_OFFSET (0) -#define MSS_M3_RSTCR_RST_OFF (1) - #define MSS_DMA_TIMEOUT 1000 #define MSS_EXTERNAL_SPACE 0x50000000 #define MSS_EXTERNAL_ADDR_MASK 0xfffffff @@ -85,9 +72,9 @@ static int mss_iram_dma_load(uint32_t src_addr, uint32_t size, /* Poll DMA_ACK at MSS_DMACTLR until it is ready */ timeout = MSS_DMA_TIMEOUT; while (timeout > 0U) { - if ((mmio_read_32(MSS_DMA_CTRLR(mss_regs)) >> - (MSS_DMA_CTRLR_ACK_OFFSET & - MSS_DMA_CTRLR_ACK_MASK)) + if (((mmio_read_32(MSS_DMA_CTRLR(mss_regs)) >> + MSS_DMA_CTRLR_ACK_OFFSET) & + MSS_DMA_CTRLR_ACK_MASK) == MSS_DMA_CTRLR_ACK_READY) { break; } @@ -161,15 +148,20 @@ static int mss_image_load(uint32_t src_addr, uint32_t size, bl2_plat_configure_mss_windows(mss_regs); - /* Wipe the MSS SRAM after using it as copy buffer */ - if (sram) { + if (sram != 0) { + /* Wipe the MSS SRAM after using it as copy buffer */ memset((void *)sram, 0, MSS_SRAM_SIZE); + NOTICE("CP MSS startup is postponed\n"); + /* FW loaded, but CPU startup postponed until final CP setup */ + mmio_write_32(sram, MSS_FW_READY_MAGIC); + dsb(); + } else { + /* Release M3 from reset */ + mmio_write_32(MSS_M3_RSTCR(mss_regs), + (MSS_M3_RSTCR_RST_OFF << + MSS_M3_RSTCR_RST_OFFSET)); } - /* Release M3 from reset */ - mmio_write_32(MSS_M3_RSTCR(mss_regs), - (MSS_M3_RSTCR_RST_OFF << MSS_M3_RSTCR_RST_OFFSET)); - NOTICE("Done\n"); return 0; diff --git a/plat/marvell/version.mk b/plat/marvell/version.mk deleted file mode 100644 index bb222553724b688c51892f6dbb94016b6081a8bf..0000000000000000000000000000000000000000 --- a/plat/marvell/version.mk +++ /dev/null @@ -1 +0,0 @@ -SUBVERSION = devel-18.12.2