aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/arm/css/scp/css_pm_scmi.c2
-rw-r--r--drivers/arm/ethosn/ethosn_smc.c58
-rw-r--r--drivers/arm/gic/v3/gic-x00.c10
-rw-r--r--drivers/arm/gic/v3/gic600_multichip.c26
-rw-r--r--drivers/arm/gic/v3/gic600_multichip_private.h26
-rw-r--r--drivers/arm/gic/v3/gic600ae_fmu.c244
-rw-r--r--drivers/arm/gic/v3/gic600ae_fmu_helpers.c260
-rw-r--r--drivers/arm/gic/v3/gicv3.mk11
-rw-r--r--drivers/arm/gic/v3/gicv3_helpers.c26
-rw-r--r--drivers/arm/gic/v3/gicv3_main.c10
-rw-r--r--drivers/arm/tzc/tzc400.c28
-rw-r--r--drivers/arm/tzc/tzc_common_private.h23
-rw-r--r--drivers/auth/cryptocell/713/cryptocell_crypto.c1
-rw-r--r--drivers/auth/tbbr/tbbr_cot_bl1_r64.c177
-rw-r--r--drivers/brcm/emmc/emmc_csl_sdcard.c6
-rw-r--r--drivers/marvell/amb_adec.c13
-rw-r--r--drivers/marvell/ccu.c9
-rw-r--r--drivers/marvell/comphy/comphy-cp110.h2
-rw-r--r--drivers/marvell/comphy/phy-comphy-3700.c205
-rw-r--r--drivers/marvell/comphy/phy-comphy-common.h2
-rw-r--r--drivers/marvell/comphy/phy-comphy-cp110.c32
-rw-r--r--drivers/marvell/gwin.c9
-rw-r--r--drivers/marvell/io_win.c9
-rw-r--r--drivers/marvell/iob.c9
-rw-r--r--drivers/marvell/mc_trustzone/mc_trustzone.c7
-rw-r--r--drivers/measured_boot/event_log/event_log.c (renamed from drivers/measured_boot/event_log.c)213
-rw-r--r--drivers/measured_boot/event_log/event_log.mk (renamed from drivers/measured_boot/measured_boot.mk)22
-rw-r--r--drivers/measured_boot/event_log/event_print.c (renamed from drivers/measured_boot/event_print.c)2
-rw-r--r--drivers/measured_boot/measured_boot.c39
-rw-r--r--drivers/mtd/nand/spi_nand.c10
-rw-r--r--drivers/mtd/spi-mem/spi_mem.c4
-rw-r--r--drivers/nxp/ddr/nxp-ddr/ddr.c9
-rw-r--r--drivers/nxp/sfp/fuse_prov.c2
-rw-r--r--drivers/partition/partition.c3
-rw-r--r--drivers/renesas/common/console/rcar_console.S4
-rw-r--r--drivers/renesas/common/ddr/ddr_a/ddr_init_d3.c74
-rw-r--r--drivers/renesas/common/io/io_rcar.c27
-rw-r--r--drivers/renesas/common/pwrc/pwrc.c32
-rw-r--r--drivers/renesas/common/scif/scif.S26
-rw-r--r--drivers/renesas/common/watchdog/swdt.c6
-rw-r--r--drivers/st/clk/stm32mp1_clk.c41
-rw-r--r--drivers/st/clk/stm32mp_clkfunc.c12
-rw-r--r--drivers/st/mmc/stm32_sdmmc2.c39
-rw-r--r--drivers/st/pmic/stpmic1.c45
-rw-r--r--drivers/st/spi/stm32_qspi.c3
-rw-r--r--drivers/st/uart/aarch32/stm32_console.S11
-rw-r--r--drivers/st/usb/stm32mp1_usb.c1091
-rw-r--r--drivers/ufs/ufs.c122
-rw-r--r--drivers/usb/usb_device.c845
49 files changed, 3339 insertions, 548 deletions
diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c
index aeb7eda30..5de2604cb 100644
--- a/drivers/arm/css/scp/css_pm_scmi.c
+++ b/drivers/arm/css/scp/css_pm_scmi.c
@@ -357,7 +357,7 @@ void __init plat_arm_pwrc_setup(void)
unsigned int composite_id, idx;
for (idx = 0; idx < PLAT_ARM_SCMI_CHANNEL_COUNT; idx++) {
- INFO("Initializing driver on Channel %d\n", idx);
+ INFO("Initializing SCMI driver on channel %d\n", idx);
scmi_channels[idx].info = plat_css_get_scmi_info(idx);
scmi_channels[idx].lock = ARM_SCMI_LOCK_GET_INSTANCE;
diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c
index 299d07c02..60364cdb2 100644
--- a/drivers/arm/ethosn/ethosn_smc.c
+++ b/drivers/arm/ethosn/ethosn_smc.c
@@ -14,11 +14,10 @@
#include <lib/mmio.h>
#include <plat/arm/common/fconf_ethosn_getter.h>
-/* Arm Ethos-N NPU (NPU) status */
-#define ETHOSN_STATUS \
- FCONF_GET_PROPERTY(hw_config, ethosn_config, status)
-
-/* Number of NPU cores available */
+/*
+ * Number of Arm Ethos-N NPU (NPU) cores available for a
+ * particular parent device
+ */
#define ETHOSN_NUM_CORES \
FCONF_GET_PROPERTY(hw_config, ethosn_config, num_cores)
@@ -51,6 +50,17 @@
#define SEC_SYSCTRL0_SOFT_RESET U(3U << 29)
#define SEC_SYSCTRL0_HARD_RESET U(1U << 31)
+static bool ethosn_is_core_addr_valid(uintptr_t core_addr)
+{
+ for (uint32_t core_idx = 0U; core_idx < ETHOSN_NUM_CORES; core_idx++) {
+ if (ETHOSN_CORE_ADDR(core_idx) == core_addr) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
static void ethosn_delegate_to_ns(uintptr_t core_addr)
{
mmio_setbits_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_SECCTLR_REG),
@@ -66,9 +76,9 @@ static void ethosn_delegate_to_ns(uintptr_t core_addr)
SEC_DEL_ADDR_EXT_VAL);
}
-static int ethosn_is_sec(void)
+static int ethosn_is_sec(uintptr_t core_addr)
{
- if ((mmio_read_32(ETHOSN_CORE_SEC_REG(ETHOSN_CORE_ADDR(0), SEC_DEL_REG))
+ if ((mmio_read_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_DEL_REG))
& SEC_DEL_EXCC_MASK) != 0U) {
return 0;
}
@@ -101,7 +111,7 @@ static bool ethosn_reset(uintptr_t core_addr, int hard_reset)
}
uintptr_t ethosn_smc_handler(uint32_t smc_fid,
- u_register_t core_idx,
+ u_register_t core_addr,
u_register_t x2,
u_register_t x3,
u_register_t x4,
@@ -109,8 +119,8 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid,
void *handle,
u_register_t flags)
{
- uintptr_t core_addr;
int hard_reset = 0;
+ const uint32_t fid = smc_fid & FUNCID_NUM_MASK;
/* Only SiP fast calls are expected */
if ((GET_SMC_TYPE(smc_fid) != SMC_TYPE_FAST) ||
@@ -120,7 +130,7 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid,
/* Truncate parameters to 32-bits for SMC32 */
if (GET_SMC_CC(smc_fid) == SMC_32) {
- core_idx &= 0xFFFFFFFF;
+ core_addr &= 0xFFFFFFFF;
x2 &= 0xFFFFFFFF;
x3 &= 0xFFFFFFFF;
x4 &= 0xFFFFFFFF;
@@ -130,33 +140,29 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid,
SMC_RET1(handle, SMC_UNK);
}
- if (ETHOSN_STATUS == ETHOSN_STATUS_DISABLED) {
- WARN("ETHOSN: Arm Ethos-N NPU not available\n");
- SMC_RET1(handle, ETHOSN_NOT_SUPPORTED);
- }
-
- switch (smc_fid & FUNCID_NUM_MASK) {
+ /* Commands that do not require a valid core address */
+ switch (fid) {
case ETHOSN_FNUM_VERSION:
SMC_RET2(handle, ETHOSN_VERSION_MAJOR, ETHOSN_VERSION_MINOR);
+ }
+
+ if (!ethosn_is_core_addr_valid(core_addr)) {
+ WARN("ETHOSN: Unknown core address given to SMC call.\n");
+ SMC_RET1(handle, ETHOSN_UNKNOWN_CORE_ADDRESS);
+ }
+
+ /* Commands that require a valid addr */
+ switch (fid) {
case ETHOSN_FNUM_IS_SEC:
- SMC_RET1(handle, ethosn_is_sec());
+ SMC_RET1(handle, ethosn_is_sec(core_addr));
case ETHOSN_FNUM_HARD_RESET:
hard_reset = 1;
/* Fallthrough */
case ETHOSN_FNUM_SOFT_RESET:
- if (core_idx >= ETHOSN_NUM_CORES) {
- WARN("ETHOSN: core index out of range\n");
- SMC_RET1(handle, ETHOSN_CORE_IDX_OUT_OF_RANGE);
- }
-
- core_addr = ETHOSN_CORE_ADDR(core_idx);
-
if (!ethosn_reset(core_addr, hard_reset)) {
SMC_RET1(handle, ETHOSN_FAILURE);
}
-
ethosn_delegate_to_ns(core_addr);
-
SMC_RET1(handle, ETHOSN_SUCCESS);
default:
SMC_RET1(handle, SMC_UNK);
diff --git a/drivers/arm/gic/v3/gic-x00.c b/drivers/arm/gic/v3/gic-x00.c
index 6e106babf..aaef485ff 100644
--- a/drivers/arm/gic/v3/gic-x00.c
+++ b/drivers/arm/gic/v3/gic-x00.c
@@ -16,15 +16,13 @@
#include <assert.h>
#include <arch_helpers.h>
+#include <drivers/arm/arm_gicv3_common.h>
#include <drivers/arm/gicv3.h>
#include "gicv3_private.h"
/* GIC-600 specific register offsets */
#define GICR_PWRR 0x24U
-#define IIDR_MODEL_ARM_GIC_600 U(0x0200043b)
-#define IIDR_MODEL_ARM_GIC_600AE U(0x0300043b)
-#define IIDR_MODEL_ARM_GIC_CLAYTON U(0x0400043b)
/* GICR_PWRR fields */
#define PWRR_RDPD_SHIFT 0
@@ -46,7 +44,7 @@
#if GICV3_SUPPORT_GIC600
-/* GIC-600/Clayton specific accessor functions */
+/* GIC-600/700 specific accessor functions */
static void gicr_write_pwrr(uintptr_t base, unsigned int val)
{
mmio_write_32(base + GICR_PWRR, val);
@@ -123,12 +121,12 @@ static bool gicv3_redists_need_power_mgmt(uintptr_t gicr_base)
uint32_t reg = mmio_read_32(gicr_base + GICR_IIDR);
/*
- * The Arm GIC-600 and GIC-Clayton models have their redistributors
+ * The Arm GIC-600 and GIC-700 models have their redistributors
* powered down at reset.
*/
return (((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600) ||
((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600AE) ||
- ((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_CLAYTON));
+ ((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_700));
}
#endif /* GICV3_SUPPORT_GIC600 */
diff --git a/drivers/arm/gic/v3/gic600_multichip.c b/drivers/arm/gic/v3/gic600_multichip.c
index ca7c43bf9..5f42ad994 100644
--- a/drivers/arm/gic/v3/gic600_multichip.c
+++ b/drivers/arm/gic/v3/gic600_multichip.c
@@ -11,14 +11,13 @@
#include <assert.h>
#include <common/debug.h>
+#include <drivers/arm/arm_gicv3_common.h>
#include <drivers/arm/gic600_multichip.h>
#include <drivers/arm/gicv3.h>
#include "../common/gic_common_private.h"
#include "gic600_multichip_private.h"
-#warning "GIC-600 Multichip driver is currently experimental and the API may change in future."
-
/*******************************************************************************
* GIC-600 multichip operation related helper functions
******************************************************************************/
@@ -73,6 +72,7 @@ static void set_gicd_chipr_n(uintptr_t base,
unsigned int spi_id_max)
{
unsigned int spi_block_min, spi_blocks;
+ unsigned int gicd_iidr_val = gicd_read_iidr(base);
uint64_t chipr_n_val;
/*
@@ -100,8 +100,24 @@ static void set_gicd_chipr_n(uintptr_t base,
spi_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min);
spi_blocks = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max);
- chipr_n_val = (GICD_CHIPR_VALUE(chip_addr, spi_block_min, spi_blocks)) |
- GICD_CHIPRx_SOCKET_STATE;
+ switch ((gicd_iidr_val & IIDR_MODEL_MASK)) {
+ case IIDR_MODEL_ARM_GIC_600:
+ chipr_n_val = GICD_CHIPR_VALUE_GIC_600(chip_addr,
+ spi_block_min,
+ spi_blocks);
+ break;
+ case IIDR_MODEL_ARM_GIC_700:
+ chipr_n_val = GICD_CHIPR_VALUE_GIC_700(chip_addr,
+ spi_block_min,
+ spi_blocks);
+ break;
+ default:
+ ERROR("Unsupported GIC model 0x%x for multichip setup.\n",
+ gicd_iidr_val);
+ panic();
+ break;
+ }
+ chipr_n_val |= GICD_CHIPRx_SOCKET_STATE;
/*
* Wait for DCHIPR.PUP to be zero before commencing writes to
@@ -194,8 +210,6 @@ void gic600_multichip_init(struct gic600_multichip_data *multichip_data)
gic600_multichip_validate_data(multichip_data);
- INFO("GIC-600 Multichip driver is experimental\n");
-
/*
* Ensure that G0/G1S/G1NS interrupts are disabled. This also ensures
* that GIC-600 Multichip configuration is done first.
diff --git a/drivers/arm/gic/v3/gic600_multichip_private.h b/drivers/arm/gic/v3/gic600_multichip_private.h
index fe4134cba..5d1ff6a19 100644
--- a/drivers/arm/gic/v3/gic600_multichip_private.h
+++ b/drivers/arm/gic/v3/gic600_multichip_private.h
@@ -27,17 +27,11 @@
#define GICD_CHIPSR_RTS_SHIFT 4
#define GICD_DCHIPR_RT_OWNER_SHIFT 4
-/*
- * If GIC v4 extension is enabled, then use SPI macros specific to GIC-Clayton.
- * Other shifts and mask remains same between GIC-600 and GIC-Clayton.
- */
-#if GIC_ENABLE_V4_EXTN
-#define GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT 9
-#define GICD_CHIPRx_SPI_BLOCKS_SHIFT 3
-#else
-#define GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT 10
-#define GICD_CHIPRx_SPI_BLOCKS_SHIFT 5
-#endif
+/* Other shifts and masks remain the same between GIC-600 and GIC-700. */
+#define GIC_700_SPI_BLOCK_MIN_SHIFT 9
+#define GIC_700_SPI_BLOCKS_SHIFT 3
+#define GIC_600_SPI_BLOCK_MIN_SHIFT 10
+#define GIC_600_SPI_BLOCKS_SHIFT 5
#define GICD_CHIPSR_RTS_STATE_DISCONNECTED U(0)
#define GICD_CHIPSR_RTS_STATE_UPDATING U(1)
@@ -59,10 +53,14 @@
#define SPI_BLOCKS_VALUE(spi_id_min, spi_id_max) \
(((spi_id_max) - (spi_id_min) + 1) / \
GIC600_SPI_ID_MIN)
-#define GICD_CHIPR_VALUE(chip_addr, spi_block_min, spi_blocks) \
+#define GICD_CHIPR_VALUE_GIC_700(chip_addr, spi_block_min, spi_blocks) \
+ (((chip_addr) << GICD_CHIPRx_ADDR_SHIFT) | \
+ ((spi_block_min) << GIC_700_SPI_BLOCK_MIN_SHIFT) | \
+ ((spi_blocks) << GIC_700_SPI_BLOCKS_SHIFT))
+#define GICD_CHIPR_VALUE_GIC_600(chip_addr, spi_block_min, spi_blocks) \
(((chip_addr) << GICD_CHIPRx_ADDR_SHIFT) | \
- ((spi_block_min) << GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT) | \
- ((spi_blocks) << GICD_CHIPRx_SPI_BLOCKS_SHIFT))
+ ((spi_block_min) << GIC_600_SPI_BLOCK_MIN_SHIFT) | \
+ ((spi_blocks) << GIC_600_SPI_BLOCKS_SHIFT))
/*
* Multichip data assertion macros
diff --git a/drivers/arm/gic/v3/gic600ae_fmu.c b/drivers/arm/gic/v3/gic600ae_fmu.c
new file mode 100644
index 000000000..13979fa4d
--- /dev/null
+++ b/drivers/arm/gic/v3/gic600ae_fmu.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Driver for GIC-600AE Fault Management Unit
+ */
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/gic600ae_fmu.h>
+#include <drivers/arm/gicv3.h>
+
+/* GIC-600 AE FMU specific register offsets */
+
+/* GIC-600 AE FMU specific macros */
+#define FMU_ERRIDR_NUM U(44)
+#define FMU_ERRIDR_NUM_MASK U(0xFFFF)
+
+/* Safety mechanisms for GICD block */
+static char *gicd_sm_info[] = {
+ "Reserved",
+ "GICD dual lockstep error",
+ "GICD AXI4 slave interface error",
+ "GICD-PPI AXI4-Stream interface error",
+ "GICD-ITS AXI4-Stream interface error",
+ "GICD-SPI-Collator AXI4-Stream interface error",
+ "GICD AXI4 master interface error",
+ "SPI RAM DED error",
+ "SGI RAM DED error",
+ "Reserved",
+ "LPI RAM DED error",
+ "GICD-remote-GICD AXI4-Stream interface error",
+ "GICD Q-Channel interface error",
+ "GICD P-Channel interface error",
+ "SPI RAM address decode error",
+ "SGI RAM address decode error",
+ "Reserved",
+ "LPI RAM address decode error",
+ "FMU dual lockstep error",
+ "FMU ping ACK error",
+ "FMU APB parity error",
+ "GICD-Wake AXI4-Stream interface error",
+ "GICD PageOffset or Chip ID error",
+ "MBIST REQ error",
+ "SPI RAM SEC error",
+ "SGI RAM SEC error",
+ "Reserved",
+ "LPI RAM SEC error",
+ "User custom SM0 error",
+ "User custom SM1 error",
+ "GICD-ITS Monolithic switch error",
+ "GICD-ITS Q-Channel interface error",
+ "GICD-ITS Monolithic interface error",
+ "GICD FMU ClkGate override"
+};
+
+/* Safety mechanisms for PPI block */
+static char *ppi_sm_info[] = {
+ "Reserved",
+ "PPI dual lockstep error",
+ "PPI-GICD AXI4-Stream interface error",
+ "PPI-CPU-IF AXI4-Stream interface error",
+ "PPI Q-Channel interface error",
+ "PPI RAM DED error",
+ "PPI RAM address decode error",
+ "PPI RAM SEC error",
+ "PPI User0 SM",
+ "PPI User1 SM",
+ "MBIST REQ error",
+ "PPI interrupt parity protection error",
+ "PPI FMU ClkGate override"
+};
+
+/* Safety mechanisms for ITS block */
+static char *its_sm_info[] = {
+ "Reserved",
+ "ITS dual lockstep error",
+ "ITS-GICD AXI4-Stream interface error",
+ "ITS AXI4 slave interface error",
+ "ITS AXI4 master interface error",
+ "ITS Q-Channel interface error",
+ "ITS RAM DED error",
+ "ITS RAM address decode error",
+ "Bypass ACE switch error",
+ "ITS RAM SEC error",
+ "ITS User0 SM",
+ "ITS User1 SM",
+ "ITS-GICD Monolithic interface error",
+ "MBIST REQ error",
+ "ITS FMU ClkGate override"
+};
+
+/* Safety mechanisms for SPI Collator block */
+static char *spicol_sm_info[] = {
+ "Reserved",
+ "SPI Collator dual lockstep error",
+ "SPI-Collator-GICD AXI4-Stream interface error",
+ "SPI Collator Q-Channel interface error",
+ "SPI Collator Q-Channel clock error",
+ "SPI interrupt parity error"
+};
+
+/* Safety mechanisms for Wake Request block */
+static char *wkrqst_sm_info[] = {
+ "Reserved",
+ "Wake dual lockstep error",
+ "Wake-GICD AXI4-Stream interface error"
+};
+
+/*
+ * Initialization sequence for the FMU
+ *
+ * 1. enable error detection for error records that are passed in the blk_present_mask
+ * 2. enable MBIST REQ and FMU Clk Gate override safety mechanisms for error records
+ * that are present on the platform
+ *
+ * The platforms are expected to pass `errctlr_ce_en` and `errctlr_ue_en`.
+ */
+void gic600_fmu_init(uint64_t base, uint64_t blk_present_mask,
+ bool errctlr_ce_en, bool errctlr_ue_en)
+{
+ unsigned int num_blk = gic_fmu_read_erridr(base) & FMU_ERRIDR_NUM_MASK;
+ uint64_t errctlr;
+ uint32_t smen;
+
+ INFO("GIC600-AE FMU supports %d error records\n", num_blk);
+
+ assert(num_blk == FMU_ERRIDR_NUM);
+
+ /* sanitize block present mask */
+ blk_present_mask &= FMU_BLK_PRESENT_MASK;
+
+ /* Enable error detection for all error records */
+ for (unsigned int i = 0U; i < num_blk; i++) {
+
+ /* Skip next steps if the block is not present */
+ if ((blk_present_mask & BIT(i)) == 0U) {
+ continue;
+ }
+
+ /* Read the error record control register */
+ errctlr = gic_fmu_read_errctlr(base, i);
+
+ /* Enable error reporting and logging, if it is disabled */
+ if ((errctlr & FMU_ERRCTLR_ED_BIT) == 0U) {
+ errctlr |= FMU_ERRCTLR_ED_BIT;
+ }
+
+ /* Enable client provided ERRCTLR settings */
+ errctlr |= (errctlr_ce_en ? (FMU_ERRCTLR_CI_BIT | FMU_ERRCTLR_CE_EN_BIT) : 0);
+ errctlr |= (errctlr_ue_en ? FMU_ERRCTLR_UI_BIT : 0U);
+
+ gic_fmu_write_errctlr(base, i, errctlr);
+ }
+
+ /*
+ * Enable MBIST REQ error and FMU CLK gate override safety mechanisms for
+ * all blocks
+ *
+ * GICD, SMID 23 and SMID 33
+ * PPI, SMID 10 and SMID 12
+ * ITS, SMID 13 and SMID 14
+ */
+ if ((blk_present_mask & BIT(FMU_BLK_GICD)) != 0U) {
+ smen = (GICD_MBIST_REQ_ERROR << FMU_SMEN_SMID_SHIFT) |
+ (FMU_BLK_GICD << FMU_SMEN_BLK_SHIFT);
+ gic_fmu_write_smen(base, smen);
+
+ smen = (GICD_FMU_CLKGATE_ERROR << FMU_SMEN_SMID_SHIFT) |
+ (FMU_BLK_GICD << FMU_SMEN_BLK_SHIFT);
+ gic_fmu_write_smen(base, smen);
+ }
+
+ for (unsigned int i = FMU_BLK_PPI0; i < FMU_BLK_PPI31; i++) {
+ if ((blk_present_mask & BIT(i)) != 0U) {
+ smen = (PPI_MBIST_REQ_ERROR << FMU_SMEN_SMID_SHIFT) |
+ (i << FMU_SMEN_BLK_SHIFT);
+ gic_fmu_write_smen(base, smen);
+
+ smen = (PPI_FMU_CLKGATE_ERROR << FMU_SMEN_SMID_SHIFT) |
+ (i << FMU_SMEN_BLK_SHIFT);
+ gic_fmu_write_smen(base, smen);
+ }
+ }
+
+ for (unsigned int i = FMU_BLK_ITS0; i < FMU_BLK_ITS7; i++) {
+ if ((blk_present_mask & BIT(i)) != 0U) {
+ smen = (ITS_MBIST_REQ_ERROR << FMU_SMEN_SMID_SHIFT) |
+ (i << FMU_SMEN_BLK_SHIFT);
+ gic_fmu_write_smen(base, smen);
+
+ smen = (ITS_FMU_CLKGATE_ERROR << FMU_SMEN_SMID_SHIFT) |
+ (i << FMU_SMEN_BLK_SHIFT);
+ gic_fmu_write_smen(base, smen);
+ }
+ }
+}
+
+/*
+ * This function enable the GICD background ping engine. The GICD sends ping
+ * messages to each remote GIC block, and expects a PING_ACK back within the
+ * specified timeout. Pings need to be enabled after programming the timeout
+ * value.
+ */
+void gic600_fmu_enable_ping(uint64_t base, uint64_t blk_present_mask,
+ unsigned int timeout_val, unsigned int interval_diff)
+{
+ /*
+ * Populate the PING Mask to skip a specific block while generating
+ * background ping messages and enable the ping mechanism.
+ */
+ gic_fmu_write_pingmask(base, ~blk_present_mask);
+ gic_fmu_write_pingctlr(base, (interval_diff << FMU_PINGCTLR_INTDIFF_SHIFT) |
+ (timeout_val << FMU_PINGCTLR_TIMEOUTVAL_SHIFT) | FMU_PINGCTLR_EN_BIT);
+}
+
+/* Print the safety mechanism description for a given block */
+void gic600_fmu_print_sm_info(uint64_t base, unsigned int blk, unsigned int smid)
+{
+ if (blk == FMU_BLK_GICD && smid <= FMU_SMID_GICD_MAX) {
+ INFO("GICD, SMID %d: %s\n", smid, gicd_sm_info[smid]);
+ }
+
+ if (blk == FMU_BLK_SPICOL && smid <= FMU_SMID_SPICOL_MAX) {
+ INFO("SPI Collator, SMID %d: %s\n", smid, spicol_sm_info[smid]);
+ }
+
+ if (blk == FMU_BLK_WAKERQ && (smid <= FMU_SMID_WAKERQ_MAX)) {
+ INFO("Wake Request, SMID %d: %s\n", smid, wkrqst_sm_info[smid]);
+ }
+
+ if (((blk >= FMU_BLK_ITS0) && (blk <= FMU_BLK_ITS7)) && (smid <= FMU_SMID_ITS_MAX)) {
+ INFO("ITS, SMID %d: %s\n", smid, its_sm_info[smid]);
+ }
+
+ if (((blk >= FMU_BLK_PPI0) && (blk <= FMU_BLK_PPI31)) && (smid <= FMU_SMID_PPI_MAX)) {
+ INFO("PPI, SMID %d: %s\n", smid, ppi_sm_info[smid]);
+ }
+}
diff --git a/drivers/arm/gic/v3/gic600ae_fmu_helpers.c b/drivers/arm/gic/v3/gic600ae_fmu_helpers.c
new file mode 100644
index 000000000..4aa0efb32
--- /dev/null
+++ b/drivers/arm/gic/v3/gic600ae_fmu_helpers.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <drivers/arm/gic600ae_fmu.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#define GICFMU_IDLE_TIMEOUT_US U(2000000)
+
+/* Macro to write 32-bit FMU registers */
+#define GIC_FMU_WRITE_32(base, reg, val) \
+ do { \
+ /* \
+ * This register receives the unlock key that is required for \
+ * writes to FMU registers to be successful. \
+ */ \
+ mmio_write_32(base + GICFMU_KEY, 0xBE); \
+ /* Perform the actual write */ \
+ mmio_write_32((base) + (reg), (val)); \
+ } while (false)
+
+/* Macro to write 64-bit FMU registers */
+#define GIC_FMU_WRITE_64(base, reg, n, val) \
+ do { \
+ /* \
+ * This register receives the unlock key that is required for \
+ * writes to FMU registers to be successful. \
+ */ \
+ mmio_write_32(base + GICFMU_KEY, 0xBE); \
+ /* \
+ * APB bus is 32-bit wide; so split the 64-bit write into \
+ * two 32-bit writes \
+ */ \
+ mmio_write_32((base) + reg##_LO + (n * 64), (val)); \
+ mmio_write_32((base) + reg##_HI + (n * 64), (val)); \
+ } while (false)
+
+/* Helper function to wait until FMU is ready to accept the next command */
+static void wait_until_fmu_is_idle(uintptr_t base)
+{
+ uint32_t timeout_count = GICFMU_IDLE_TIMEOUT_US;
+ uint64_t status;
+
+ /* wait until status is 'busy' */
+ do {
+ status = (gic_fmu_read_status(base) & BIT(0));
+
+ if (timeout_count-- == 0U) {
+ ERROR("GIC600 AE FMU is not responding\n");
+ panic();
+ }
+
+ udelay(1U);
+
+ } while (status == U(0));
+}
+
+#define GIC_FMU_WRITE_ON_IDLE_32(base, reg, val) \
+ do { \
+ /* Wait until FMU is ready */ \
+ wait_until_fmu_is_idle(base); \
+ /* Actual register write */ \
+ GIC_FMU_WRITE_32(base, reg, val); \
+ /* Wait until FMU is ready */ \
+ wait_until_fmu_is_idle(base); \
+ } while (false)
+
+#define GIC_FMU_WRITE_ON_IDLE_64(base, reg, n, val) \
+ do { \
+ /* Wait until FMU is ready */ \
+ wait_until_fmu_is_idle(base); \
+ /* Actual register write */ \
+ GIC_FMU_WRITE_64(base, reg, n, val); \
+ /* Wait until FMU is ready */ \
+ wait_until_fmu_is_idle(base); \
+ } while (false)
+
+/*******************************************************************************
+ * GIC FMU functions for accessing the Fault Management Unit registers
+ ******************************************************************************/
+
+/*
+ * Accessors to read the Error Record Feature Register bits corresponding
+ * to an error record 'n'
+ */
+uint64_t gic_fmu_read_errfr(uintptr_t base, unsigned int n)
+{
+ /*
+ * APB bus is 32-bit wide; so split the 64-bit read into
+ * two 32-bit reads
+ */
+ uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRFR_LO + n * 64U);
+
+ reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRFR_HI + n * 64U) << 32);
+ return reg_val;
+}
+
+/*
+ * Accessors to read the Error Record Control Register bits corresponding
+ * to an error record 'n'
+ */
+uint64_t gic_fmu_read_errctlr(uintptr_t base, unsigned int n)
+{
+ /*
+ * APB bus is 32-bit wide; so split the 64-bit read into
+ * two 32-bit reads
+ */
+ uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRCTLR_LO + n * 64U);
+
+ reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRCTLR_HI + n * 64U) << 32);
+ return reg_val;
+}
+
+/*
+ * Accessors to read the Error Record Primary Status Register bits
+ * corresponding to an error record 'n'
+ */
+uint64_t gic_fmu_read_errstatus(uintptr_t base, unsigned int n)
+{
+ /*
+ * APB bus is 32-bit wide; so split the 64-bit read into
+ * two 32-bit reads
+ */
+ uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRSTATUS_LO + n * 64U);
+
+ reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRSTATUS_HI + n * 64U) << 32);
+ return reg_val;
+}
+
+/*
+ * Accessors to read the Error Group Status Register
+ */
+uint64_t gic_fmu_read_errgsr(uintptr_t base)
+{
+ /*
+ * APB bus is 32-bit wide; so split the 64-bit read into
+ * two 32-bit reads
+ */
+ uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRGSR_LO);
+
+ reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRGSR_HI) << 32);
+ return reg_val;
+}
+
+/*
+ * Accessors to read the Ping Control Register
+ */
+uint32_t gic_fmu_read_pingctlr(uintptr_t base)
+{
+ return mmio_read_32(base + GICFMU_PINGCTLR);
+}
+
+/*
+ * Accessors to read the Ping Now Register
+ */
+uint32_t gic_fmu_read_pingnow(uintptr_t base)
+{
+ return mmio_read_32(base + GICFMU_PINGNOW);
+}
+
+/*
+ * Accessors to read the Ping Mask Register
+ */
+uint64_t gic_fmu_read_pingmask(uintptr_t base)
+{
+ /*
+ * APB bus is 32-bit wide; so split the 64-bit read into
+ * two 32-bit reads
+ */
+ uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_PINGMASK_LO);
+
+ reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_PINGMASK_HI) << 32);
+ return reg_val;
+}
+
+/*
+ * Accessors to read the FMU Status Register
+ */
+uint32_t gic_fmu_read_status(uintptr_t base)
+{
+ return mmio_read_32(base + GICFMU_STATUS);
+}
+
+/*
+ * Accessors to read the Error Record ID Register
+ */
+uint32_t gic_fmu_read_erridr(uintptr_t base)
+{
+ return mmio_read_32(base + GICFMU_ERRIDR);
+}
+
+/*
+ * Accessors to write a 64 bit value to the Error Record Control Register
+ */
+void gic_fmu_write_errctlr(uintptr_t base, unsigned int n, uint64_t val)
+{
+ GIC_FMU_WRITE_64(base, GICFMU_ERRCTLR, n, val);
+}
+
+/*
+ * Accessors to write a 64 bit value to the Error Record Primary Status
+ * Register
+ */
+void gic_fmu_write_errstatus(uintptr_t base, unsigned int n, uint64_t val)
+{
+ /* Wait until FMU is ready before writing */
+ GIC_FMU_WRITE_ON_IDLE_64(base, GICFMU_ERRSTATUS, n, val);
+}
+
+/*
+ * Accessors to write a 32 bit value to the Ping Control Register
+ */
+void gic_fmu_write_pingctlr(uintptr_t base, uint32_t val)
+{
+ GIC_FMU_WRITE_32(base, GICFMU_PINGCTLR, val);
+}
+
+/*
+ * Accessors to write a 32 bit value to the Ping Now Register
+ */
+void gic_fmu_write_pingnow(uintptr_t base, uint32_t val)
+{
+ /* Wait until FMU is ready before writing */
+ GIC_FMU_WRITE_ON_IDLE_32(base, GICFMU_PINGNOW, val);
+}
+
+/*
+ * Accessors to write a 32 bit value to the Safety Mechanism Enable Register
+ */
+void gic_fmu_write_smen(uintptr_t base, uint32_t val)
+{
+ /* Wait until FMU is ready before writing */
+ GIC_FMU_WRITE_ON_IDLE_32(base, GICFMU_SMEN, val);
+}
+
+/*
+ * Accessors to write a 32 bit value to the Safety Mechanism Inject Error
+ * Register
+ */
+void gic_fmu_write_sminjerr(uintptr_t base, uint32_t val)
+{
+ /* Wait until FMU is ready before writing */
+ GIC_FMU_WRITE_ON_IDLE_32(base, GICFMU_SMINJERR, val);
+}
+
+/*
+ * Accessors to write a 64 bit value to the Ping Mask Register
+ */
+void gic_fmu_write_pingmask(uintptr_t base, uint64_t val)
+{
+ GIC_FMU_WRITE_64(base, GICFMU_PINGMASK, 0, val);
+}
diff --git a/drivers/arm/gic/v3/gicv3.mk b/drivers/arm/gic/v3/gicv3.mk
index a2fc16f9c..d7e3536db 100644
--- a/drivers/arm/gic/v3/gicv3.mk
+++ b/drivers/arm/gic/v3/gicv3.mk
@@ -1,11 +1,13 @@
#
# Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
# Default configuration values
GICV3_SUPPORT_GIC600 ?= 0
+GICV3_SUPPORT_GIC600AE_FMU ?= 0
GICV3_IMPL_GIC600_MULTICHIP ?= 0
GICV3_OVERRIDE_DISTIF_PWR_OPS ?= 0
GIC_ENABLE_V4_EXTN ?= 0
@@ -16,6 +18,11 @@ GICV3_SOURCES += drivers/arm/gic/v3/gicv3_main.c \
drivers/arm/gic/v3/gicdv3_helpers.c \
drivers/arm/gic/v3/gicrv3_helpers.c
+ifeq (${GICV3_SUPPORT_GIC600AE_FMU}, 1)
+GICV3_SOURCES += drivers/arm/gic/v3/gic600ae_fmu.c \
+ drivers/arm/gic/v3/gic600ae_fmu_helpers.c
+endif
+
ifeq (${GICV3_OVERRIDE_DISTIF_PWR_OPS}, 0)
GICV3_SOURCES += drivers/arm/gic/v3/arm_gicv3_common.c
endif
@@ -29,6 +36,10 @@ endif
$(eval $(call assert_boolean,GICV3_SUPPORT_GIC600))
$(eval $(call add_define,GICV3_SUPPORT_GIC600))
+# Set GIC-600AE FMU support
+$(eval $(call assert_boolean,GICV3_SUPPORT_GIC600AE_FMU))
+$(eval $(call add_define,GICV3_SUPPORT_GIC600AE_FMU))
+
# Set GICv4 extension
$(eval $(call assert_boolean,GIC_ENABLE_V4_EXTN))
$(eval $(call add_define,GIC_ENABLE_V4_EXTN))
diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c
index a0f44e966..753d995d7 100644
--- a/drivers/arm/gic/v3/gicv3_helpers.c
+++ b/drivers/arm/gic/v3/gicv3_helpers.c
@@ -86,8 +86,7 @@ void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs,
if (proc_num < rdistif_num) {
rdistif_base_addrs[proc_num] = rdistif_base;
}
-
- rdistif_base += (1U << GICR_PCPUBASE_SHIFT);
+ rdistif_base += gicv3_redist_size(typer_val);
} while ((typer_val & TYPER_LAST_BIT) == 0U);
}
@@ -383,12 +382,29 @@ unsigned int gicv3_rdistif_get_number_frames(const uintptr_t gicr_frame)
uintptr_t rdistif_base = gicr_frame;
unsigned int count;
- for (count = 1; count < PLATFORM_CORE_COUNT; count++) {
- if ((gicr_read_typer(rdistif_base) & TYPER_LAST_BIT) != 0U) {
+ for (count = 1U; count < PLATFORM_CORE_COUNT; count++) {
+ uint64_t typer_val = gicr_read_typer(rdistif_base);
+
+ if ((typer_val & TYPER_LAST_BIT) != 0U) {
break;
}
- rdistif_base += (1U << GICR_PCPUBASE_SHIFT);
+ rdistif_base += gicv3_redist_size(typer_val);
}
return count;
}
+
+unsigned int gicv3_get_component_partnum(const uintptr_t gic_frame)
+{
+ unsigned int part_id;
+
+ /*
+ * The lower 8 bits of PIDR0, complemented by the lower 4 bits of
+ * PIDR1 contain a part number identifying the GIC component at a
+ * particular base address.
+ */
+ part_id = mmio_read_32(gic_frame + GICD_PIDR0_GICV3) & 0xff;
+ part_id |= (mmio_read_32(gic_frame + GICD_PIDR1_GICV3) << 8) & 0xf00;
+
+ return part_id;
+}
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index b1139b5e9..53a8fae3b 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -123,13 +123,7 @@ void __init gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data)
gic_version &= PIDR2_ARCH_REV_MASK;
/* Check GIC version */
-#if GIC_ENABLE_V4_EXTN
- assert(gic_version == ARCH_REV_GICV4);
-
- /* GICv4 supports Direct Virtual LPI injection */
- assert((gicd_read_typer(plat_driver_data->gicd_base)
- & TYPER_DVIS) != 0);
-#else
+#if !GIC_ENABLE_V4_EXTN
assert(gic_version == ARCH_REV_GICV3);
#endif
/*
@@ -1298,7 +1292,7 @@ int gicv3_rdistif_probe(const uintptr_t gicr_frame)
gicr_frame_found = true;
break;
}
- rdistif_base += (uintptr_t)(ULL(1) << GICR_PCPUBASE_SHIFT);
+ rdistif_base += gicv3_redist_size(typer_val);
} while ((typer_val & TYPER_LAST_BIT) == 0U);
if (!gicr_frame_found) {
diff --git a/drivers/arm/tzc/tzc400.c b/drivers/arm/tzc/tzc400.c
index 9fc1578a1..e4fc8c927 100644
--- a/drivers/arm/tzc/tzc400.c
+++ b/drivers/arm/tzc/tzc400.c
@@ -68,6 +68,7 @@ DEFINE_TZC_COMMON_WRITE_REGION_BASE(400, 400)
DEFINE_TZC_COMMON_WRITE_REGION_TOP(400, 400)
DEFINE_TZC_COMMON_WRITE_REGION_ATTRIBUTES(400, 400)
DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(400, 400)
+DEFINE_TZC_COMMON_UPDATE_FILTERS(400, 400)
DEFINE_TZC_COMMON_CONFIGURE_REGION0(400)
DEFINE_TZC_COMMON_CONFIGURE_REGION(400)
@@ -271,6 +272,15 @@ void tzc400_configure_region(unsigned int filters,
sec_attr, nsaid_permissions);
}
+void tzc400_update_filters(unsigned int region, unsigned int filters)
+{
+ /* Do range checks on filters and regions. */
+ assert(((filters >> tzc400.num_filters) == 0U) &&
+ (region < tzc400.num_regions));
+
+ _tzc400_update_filters(tzc400.base, region, tzc400.num_filters, filters);
+}
+
void tzc400_enable_filters(void)
{
unsigned int state;
@@ -281,6 +291,11 @@ void tzc400_enable_filters(void)
for (filter = 0U; filter < tzc400.num_filters; filter++) {
state = _tzc400_get_gate_keeper(tzc400.base, filter);
if (state != 0U) {
+ /* Filter 0 is special and cannot be disabled.
+ * So here we allow it being already enabled. */
+ if (filter == 0U) {
+ continue;
+ }
/*
* The TZC filter is already configured. Changing the
* programmer's view in an active system can cause
@@ -302,14 +317,17 @@ void tzc400_enable_filters(void)
void tzc400_disable_filters(void)
{
unsigned int filter;
+ unsigned int state;
+ unsigned int start = 0U;
assert(tzc400.base != 0U);
- /*
- * We don't do the same state check as above as the Gatekeepers are
- * disabled after reset.
- */
- for (filter = 0; filter < tzc400.num_filters; filter++)
+ /* Filter 0 is special and cannot be disabled. */
+ state = _tzc400_get_gate_keeper(tzc400.base, 0);
+ if (state != 0U) {
+ start++;
+ }
+ for (filter = start; filter < tzc400.num_filters; filter++)
_tzc400_set_gate_keeper(tzc400.base, filter, 0);
}
diff --git a/drivers/arm/tzc/tzc_common_private.h b/drivers/arm/tzc/tzc_common_private.h
index 1d99077ad..2090944a7 100644
--- a/drivers/arm/tzc/tzc_common_private.h
+++ b/drivers/arm/tzc/tzc_common_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -90,6 +90,27 @@
}
/*
+ * It is used to modify the filters status for a defined region.
+ */
+#define DEFINE_TZC_COMMON_UPDATE_FILTERS(fn_name, macro_name) \
+ static inline void _tzc##fn_name##_update_filters( \
+ uintptr_t base, \
+ unsigned int region_no, \
+ unsigned int nbfilters, \
+ unsigned int filters) \
+ { \
+ uint32_t filters_mask = GENMASK(nbfilters - 1U, 0); \
+ \
+ mmio_clrsetbits_32(base + \
+ TZC_REGION_OFFSET( \
+ TZC_##macro_name##_REGION_SIZE, \
+ region_no) + \
+ TZC_##macro_name##_REGION_ATTR_0_OFFSET, \
+ filters_mask << TZC_REGION_ATTR_F_EN_SHIFT, \
+ filters << TZC_REGION_ATTR_F_EN_SHIFT); \
+ }
+
+/*
* It is used to program region 0 ATTRIBUTES and ACCESS register.
*/
#define DEFINE_TZC_COMMON_CONFIGURE_REGION0(fn_name) \
diff --git a/drivers/auth/cryptocell/713/cryptocell_crypto.c b/drivers/auth/cryptocell/713/cryptocell_crypto.c
index 5f390a226..077317e7b 100644
--- a/drivers/auth/cryptocell/713/cryptocell_crypto.c
+++ b/drivers/auth/cryptocell/713/cryptocell_crypto.c
@@ -13,6 +13,7 @@
#include <drivers/auth/crypto_mod.h>
#include <mbedtls/oid.h>
+#include <mbedtls/x509.h>
#define LIB_NAME "CryptoCell 713 SBROM"
#define RSA_SALT_LEN 32
diff --git a/drivers/auth/tbbr/tbbr_cot_bl1_r64.c b/drivers/auth/tbbr/tbbr_cot_bl1_r64.c
new file mode 100644
index 000000000..e8e017c8d
--- /dev/null
+++ b/drivers/auth/tbbr/tbbr_cot_bl1_r64.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+#include <drivers/auth/auth_mod.h>
+#include <drivers/auth/mbedtls/mbedtls_config.h>
+#include <drivers/auth/tbbr_cot_common.h>
+
+#if USE_TBBR_DEFS
+#include <tools_share/tbbr_oid.h>
+#else
+#include <platform_oid.h>
+#endif
+#include <platform_def.h>
+
+
+static unsigned char trusted_world_pk_buf[PK_DER_LEN];
+static unsigned char non_trusted_world_pk_buf[PK_DER_LEN];
+static unsigned char content_pk_buf[PK_DER_LEN];
+static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN];
+
+static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
+static auth_param_type_desc_t trusted_world_pk = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_PUB_KEY, TRUSTED_WORLD_PK_OID);
+static auth_param_type_desc_t non_trusted_world_pk = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_PUB_KEY, NON_TRUSTED_WORLD_PK_OID);
+static auth_param_type_desc_t nt_fw_content_pk = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_PUB_KEY, NON_TRUSTED_FW_CONTENT_CERT_PK_OID);
+static auth_param_type_desc_t nt_world_bl_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID);
+static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID);
+/*
+ * Trusted key certificate
+ */
+static const auth_img_desc_t trusted_key_cert = {
+ .img_id = TRUSTED_KEY_CERT_ID,
+ .img_type = IMG_CERT,
+ .parent = NULL,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_SIG,
+ .param.sig = {
+ .pk = &subject_pk,
+ .sig = &sig,
+ .alg = &sig_alg,
+ .data = &raw_data
+ }
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &trusted_nv_ctr,
+ .plat_nv_ctr = &trusted_nv_ctr
+ }
+ }
+ },
+ .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+ [0] = {
+ .type_desc = &trusted_world_pk,
+ .data = {
+ .ptr = (void *)trusted_world_pk_buf,
+ .len = (unsigned int)PK_DER_LEN
+ }
+ },
+ [1] = {
+ .type_desc = &non_trusted_world_pk,
+ .data = {
+ .ptr = (void *)non_trusted_world_pk_buf,
+ .len = (unsigned int)PK_DER_LEN
+ }
+ }
+ }
+};
+/*
+ * Non-Trusted Firmware
+ */
+static const auth_img_desc_t non_trusted_fw_key_cert = {
+ .img_id = NON_TRUSTED_FW_KEY_CERT_ID,
+ .img_type = IMG_CERT,
+ .parent = &trusted_key_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_SIG,
+ .param.sig = {
+ .pk = &non_trusted_world_pk,
+ .sig = &sig,
+ .alg = &sig_alg,
+ .data = &raw_data
+ }
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &non_trusted_nv_ctr,
+ .plat_nv_ctr = &non_trusted_nv_ctr
+ }
+ }
+ },
+ .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+ [0] = {
+ .type_desc = &nt_fw_content_pk,
+ .data = {
+ .ptr = (void *)content_pk_buf,
+ .len = (unsigned int)PK_DER_LEN
+ }
+ }
+ }
+};
+static const auth_img_desc_t non_trusted_fw_content_cert = {
+ .img_id = NON_TRUSTED_FW_CONTENT_CERT_ID,
+ .img_type = IMG_CERT,
+ .parent = &non_trusted_fw_key_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_SIG,
+ .param.sig = {
+ .pk = &nt_fw_content_pk,
+ .sig = &sig,
+ .alg = &sig_alg,
+ .data = &raw_data
+ }
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &non_trusted_nv_ctr,
+ .plat_nv_ctr = &non_trusted_nv_ctr
+ }
+ }
+ },
+ .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+ [0] = {
+ .type_desc = &nt_world_bl_hash,
+ .data = {
+ .ptr = (void *)nt_world_bl_hash_buf,
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ },
+ [1] = {
+ .type_desc = &nt_fw_config_hash,
+ .data = {
+ .ptr = (void *)nt_fw_config_hash_buf,
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ }
+ }
+};
+static const auth_img_desc_t bl33_image = {
+ .img_id = BL33_IMAGE_ID,
+ .img_type = IMG_RAW,
+ .parent = &non_trusted_fw_content_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_HASH,
+ .param.hash = {
+ .data = &raw_data,
+ .hash = &nt_world_bl_hash
+ }
+ }
+ }
+};
+
+static const auth_img_desc_t * const cot_desc[] = {
+ [TRUSTED_KEY_CERT_ID] = &trusted_key_cert,
+ [NON_TRUSTED_FW_KEY_CERT_ID] = &non_trusted_fw_key_cert,
+ [NON_TRUSTED_FW_CONTENT_CERT_ID] = &non_trusted_fw_content_cert,
+ [BL33_IMAGE_ID] = &bl33_image,
+};
+
+/* Register the CoT in the authentication module */
+REGISTER_COT(cot_desc);
diff --git a/drivers/brcm/emmc/emmc_csl_sdcard.c b/drivers/brcm/emmc/emmc_csl_sdcard.c
index d6ad4bc9c..9e2c618d9 100644
--- a/drivers/brcm/emmc/emmc_csl_sdcard.c
+++ b/drivers/brcm/emmc/emmc_csl_sdcard.c
@@ -4,9 +4,11 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
-#include <stddef.h>
#include <arch_helpers.h>
#include <lib/mmio.h>
@@ -521,7 +523,7 @@ static int xfer_data(struct sd_handle *handle,
{
int rc = SD_OK;
- VERBOSE("XFER: dest: 0x%llx, addr: 0x%x, size: 0x%x bytes\n",
+ VERBOSE("XFER: dest: 0x%" PRIx64 ", addr: 0x%x, size: 0x%x bytes\n",
(uint64_t)base, addr, length);
if ((length / handle->device->cfg.blockSize) > 1) {
diff --git a/drivers/marvell/amb_adec.c b/drivers/marvell/amb_adec.c
index 1f671058d..d78fa2517 100644
--- a/drivers/marvell/amb_adec.c
+++ b/drivers/marvell/amb_adec.c
@@ -7,6 +7,9 @@
/* AXI to M-Bridge decoding unit driver for Marvell Armada 8K and 8K+ SoCs */
+#include <inttypes.h>
+#include <stdint.h>
+
#include <common/debug.h>
#include <lib/mmio.h>
@@ -44,10 +47,10 @@ static void amb_check_win(struct addr_map_win *win, uint32_t win_num)
/* make sure the base address is in 16-bit range */
if (win->base_addr > AMB_BASE_ADDR_MASK) {
- WARN("Window %d: base address is too big 0x%llx\n",
+ WARN("Window %d: base address is too big 0x%" PRIx64 "\n",
win_num, win->base_addr);
win->base_addr = AMB_BASE_ADDR_MASK;
- WARN("Set the base address to 0x%llx\n", win->base_addr);
+ WARN("Set the base address to 0x%" PRIx64 "\n", win->base_addr);
}
base_addr = win->base_addr << AMB_BASE_OFFSET;
@@ -57,15 +60,15 @@ static void amb_check_win(struct addr_map_win *win, uint32_t win_num)
win->base_addr = ALIGN_UP(base_addr, AMB_WIN_ALIGNMENT_1M);
WARN("Window %d: base address unaligned to 0x%x\n",
win_num, AMB_WIN_ALIGNMENT_1M);
- WARN("Align up the base address to 0x%llx\n", win->base_addr);
+ WARN("Align up the base address to 0x%" PRIx64 "\n", win->base_addr);
}
/* size parameter validity check */
if (!IS_POWER_OF_2(win->win_size)) {
- WARN("Window %d: window size is not power of 2 (0x%llx)\n",
+ WARN("Window %d: window size is not power of 2 (0x%" PRIx64 ")\n",
win_num, win->win_size);
win->win_size = ROUND_UP_TO_POW_OF_2(win->win_size);
- WARN("Rounding size to 0x%llx\n", win->win_size);
+ WARN("Rounding size to 0x%" PRIx64 "\n", win->win_size);
}
}
diff --git a/drivers/marvell/ccu.c b/drivers/marvell/ccu.c
index b4251f49b..c206f1168 100644
--- a/drivers/marvell/ccu.c
+++ b/drivers/marvell/ccu.c
@@ -7,6 +7,9 @@
/* CCU unit device driver for Marvell AP807, AP807 and AP810 SoCs */
+#include <inttypes.h>
+#include <stdint.h>
+
#include <common/debug.h>
#include <drivers/marvell/ccu.h>
#include <lib/mmio.h>
@@ -84,7 +87,7 @@ static void dump_ccu(int ap_index)
win_id));
start = ((uint64_t)alr << ADDRESS_SHIFT);
end = (((uint64_t)ahr + 0x10) << ADDRESS_SHIFT);
- printf("\tccu%d %02x 0x%016llx 0x%016llx\n",
+ printf("\tccu%d %02x 0x%016" PRIx64 " 0x%016" PRIx64 "\n",
win_id, target_id, start, end);
}
}
@@ -99,14 +102,14 @@ void ccu_win_check(struct addr_map_win *win)
/* check if address is aligned to 1M */
if (IS_NOT_ALIGN(win->base_addr, CCU_WIN_ALIGNMENT)) {
win->base_addr = ALIGN_UP(win->base_addr, CCU_WIN_ALIGNMENT);
- NOTICE("%s: Align up the base address to 0x%llx\n",
+ NOTICE("%s: Align up the base address to 0x%" PRIx64 "\n",
__func__, win->base_addr);
}
/* size parameter validity check */
if (IS_NOT_ALIGN(win->win_size, CCU_WIN_ALIGNMENT)) {
win->win_size = ALIGN_UP(win->win_size, CCU_WIN_ALIGNMENT);
- NOTICE("%s: Aligning size to 0x%llx\n",
+ NOTICE("%s: Aligning size to 0x%" PRIx64 "\n",
__func__, win->win_size);
}
}
diff --git a/drivers/marvell/comphy/comphy-cp110.h b/drivers/marvell/comphy/comphy-cp110.h
index 9b10619ed..af5c71518 100644
--- a/drivers/marvell/comphy/comphy-cp110.h
+++ b/drivers/marvell/comphy/comphy-cp110.h
@@ -54,7 +54,7 @@
#define COMMON_SELECTOR_PIPE_COMPHY_USBH 0x1
#define COMMON_SELECTOR_PIPE_COMPHY_USBD 0x2
-/* SGMII/HS-SGMII/SFI/RXAUI */
+/* SGMII/Base-X/SFI/RXAUI */
#define COMMON_SELECTOR_COMPHY0_1_2_NETWORK 0x1
#define COMMON_SELECTOR_COMPHY3_RXAUI 0x1
#define COMMON_SELECTOR_COMPHY3_SGMII 0x2
diff --git a/drivers/marvell/comphy/phy-comphy-3700.c b/drivers/marvell/comphy/phy-comphy-3700.c
index 7377e5e3d..a3e414c4b 100644
--- a/drivers/marvell/comphy/phy-comphy-3700.c
+++ b/drivers/marvell/comphy/phy-comphy-3700.c
@@ -118,7 +118,7 @@ static uint16_t sgmii_phy_init[512] = {
};
/* PHY selector configures with corresponding modes */
-static void mvebu_a3700_comphy_set_phy_selector(uint8_t comphy_index,
+static int mvebu_a3700_comphy_set_phy_selector(uint8_t comphy_index,
uint32_t comphy_mode)
{
uint32_t reg;
@@ -135,7 +135,7 @@ static void mvebu_a3700_comphy_set_phy_selector(uint8_t comphy_index,
break;
case (COMPHY_SGMII_MODE):
- case (COMPHY_HS_SGMII_MODE):
+ case (COMPHY_2500BASEX_MODE):
if (comphy_index == COMPHY_LANE0)
reg &= ~COMPHY_SELECTOR_USB3_GBE1_SEL_BIT;
else if (comphy_index == COMPHY_LANE1)
@@ -168,9 +168,10 @@ static void mvebu_a3700_comphy_set_phy_selector(uint8_t comphy_index,
}
mmio_write_32(MVEBU_COMPHY_REG_BASE + COMPHY_SELECTOR_PHY_REG, reg);
- return;
+ return 0;
error:
ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index, mode);
+ return -EINVAL;
}
/*
@@ -183,7 +184,7 @@ error:
* with COMPHY_USB3D_MODE or COMPHY_USB3H_MODE. (The usb3 phy initialization
* code does not differentiate between these modes.)
* Also it returns COMPHY_SGMII_MODE even if the phy was configures with
- * COMPHY_HS_SGMII_MODE. (The sgmii phy initialization code does differentiate
+ * COMPHY_2500BASEX_MODE. (The sgmii phy initialization code does differentiate
* between these modes, but it is irrelevant when powering the phy off.)
*/
static int mvebu_a3700_comphy_get_mode(uint8_t comphy_index)
@@ -214,7 +215,7 @@ static int mvebu_a3700_comphy_get_mode(uint8_t comphy_index)
/* It is only used for SATA and USB3 on comphy lane2. */
static void comphy_set_indirect(uintptr_t addr, uint32_t offset, uint16_t data,
- uint16_t mask, int mode)
+ uint16_t mask, bool is_sata)
{
/*
* When Lane 2 PHY is for USB3, access the PHY registers
@@ -224,27 +225,38 @@ static void comphy_set_indirect(uintptr_t addr, uint32_t offset, uint16_t data,
* within the SATA Host Controller registers, Lane 2 base register
* offset is 0x200
*/
- if (mode == COMPHY_UNUSED)
- return;
-
- if (mode == COMPHY_SATA_MODE)
+ if (is_sata) {
mmio_write_32(addr + COMPHY_LANE2_INDIR_ADDR_OFFSET, offset);
- else
+ } else {
mmio_write_32(addr + COMPHY_LANE2_INDIR_ADDR_OFFSET,
offset + USB3PHY_LANE2_REG_BASE_OFFSET);
+ }
reg_set(addr + COMPHY_LANE2_INDIR_DATA_OFFSET, data, mask);
}
-/* It is only used USB3 direct access not on comphy lane2. */
+/* It is only used for SATA on comphy lane2. */
+static void comphy_sata_set_indirect(uintptr_t addr, uint32_t reg_offset,
+ uint16_t data, uint16_t mask)
+{
+ comphy_set_indirect(addr, reg_offset, data, mask, true);
+}
+
+/* It is only used for USB3 indirect access on comphy lane2. */
+static void comphy_usb3_set_indirect(uintptr_t addr, uint32_t reg_offset,
+ uint16_t data, uint16_t mask)
+{
+ comphy_set_indirect(addr, reg_offset, data, mask, false);
+}
+
+/* It is only used for USB3 direct access not on comphy lane2. */
static void comphy_usb3_set_direct(uintptr_t addr, uint32_t reg_offset,
- uint16_t data, uint16_t mask, int mode)
+ uint16_t data, uint16_t mask)
{
reg_set16((reg_offset * PHY_SHFT(USB3) + addr), data, mask);
}
-static void comphy_sgmii_phy_init(uint32_t comphy_index, uint32_t mode,
- uintptr_t sd_ip_addr)
+static void comphy_sgmii_phy_init(uintptr_t sd_ip_addr, bool is_1gbps)
{
const int fix_arr_sz = ARRAY_SIZE(sgmii_phy_init_fix);
int addr, fix_idx;
@@ -259,8 +271,7 @@ static void comphy_sgmii_phy_init(uint32_t comphy_index, uint32_t mode,
* comparison to 3.125 Gbps values. These register values are
* stored in "sgmii_phy_init_fix" array.
*/
- if ((mode != COMPHY_SGMII_MODE) &&
- (sgmii_phy_init_fix[fix_idx].addr == addr)) {
+ if (!is_1gbps && sgmii_phy_init_fix[fix_idx].addr == addr) {
/* Use new value */
val = sgmii_phy_init_fix[fix_idx].value;
if (fix_idx < fix_arr_sz)
@@ -276,21 +287,22 @@ static void comphy_sgmii_phy_init(uint32_t comphy_index, uint32_t mode,
static int mvebu_a3700_comphy_sata_power_on(uint8_t comphy_index,
uint32_t comphy_mode)
{
- int ret = 0;
+ int ret;
uint32_t offset, data = 0, ref_clk;
uintptr_t comphy_indir_regs = COMPHY_INDIRECT_REG;
- int mode = COMPHY_GET_MODE(comphy_mode);
int invert = COMPHY_GET_POLARITY_INVERT(comphy_mode);
debug_enter();
/* Configure phy selector for SATA */
- mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode);
+ ret = mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode);
+ if (ret) {
+ return ret;
+ }
/* Clear phy isolation mode to make it work in normal mode */
offset = COMPHY_ISOLATION_CTRL_REG + SATAPHY_LANE2_REG_BASE_OFFSET;
- comphy_set_indirect(comphy_indir_regs, offset, 0, PHY_ISOLATE_MODE,
- mode);
+ comphy_sata_set_indirect(comphy_indir_regs, offset, 0, PHY_ISOLATE_MODE);
/* 0. Check the Polarity invert bits */
if (invert & COMPHY_POLARITY_TXD_INVERT)
@@ -299,13 +311,13 @@ static int mvebu_a3700_comphy_sata_power_on(uint8_t comphy_index,
data |= RXD_INVERT_BIT;
offset = COMPHY_SYNC_PATTERN_REG + SATAPHY_LANE2_REG_BASE_OFFSET;
- comphy_set_indirect(comphy_indir_regs, offset, data, TXD_INVERT_BIT |
- RXD_INVERT_BIT, mode);
+ comphy_sata_set_indirect(comphy_indir_regs, offset, data, TXD_INVERT_BIT |
+ RXD_INVERT_BIT);
/* 1. Select 40-bit data width width */
offset = COMPHY_LOOPBACK_REG0 + SATAPHY_LANE2_REG_BASE_OFFSET;
- comphy_set_indirect(comphy_indir_regs, offset, DATA_WIDTH_40BIT,
- SEL_DATA_WIDTH_MASK, mode);
+ comphy_sata_set_indirect(comphy_indir_regs, offset, DATA_WIDTH_40BIT,
+ SEL_DATA_WIDTH_MASK);
/* 2. Select reference clock(25M) and PHY mode (SATA) */
offset = COMPHY_POWER_PLL_CTRL + SATAPHY_LANE2_REG_BASE_OFFSET;
@@ -314,17 +326,17 @@ static int mvebu_a3700_comphy_sata_power_on(uint8_t comphy_index,
else
ref_clk = REF_CLOCK_SPEED_25M;
- comphy_set_indirect(comphy_indir_regs, offset, ref_clk | PHY_MODE_SATA,
- REF_FREF_SEL_MASK | PHY_MODE_MASK, mode);
+ comphy_sata_set_indirect(comphy_indir_regs, offset, ref_clk | PHY_MODE_SATA,
+ REF_FREF_SEL_MASK | PHY_MODE_MASK);
/* 3. Use maximum PLL rate (no power save) */
offset = COMPHY_KVCO_CAL_CTRL + SATAPHY_LANE2_REG_BASE_OFFSET;
- comphy_set_indirect(comphy_indir_regs, offset, USE_MAX_PLL_RATE_BIT,
- USE_MAX_PLL_RATE_BIT, mode);
+ comphy_sata_set_indirect(comphy_indir_regs, offset, USE_MAX_PLL_RATE_BIT,
+ USE_MAX_PLL_RATE_BIT);
/* 4. Reset reserved bit */
- comphy_set_indirect(comphy_indir_regs, COMPHY_RESERVED_REG, 0,
- PHYCTRL_FRM_PIN_BIT, mode);
+ comphy_sata_set_indirect(comphy_indir_regs, COMPHY_RESERVED_REG, 0,
+ PHYCTRL_FRM_PIN_BIT);
/* 5. Set vendor-specific configuration (It is done in sata driver) */
/* XXX: in U-Boot below sequence was executed in this place, in Linux
@@ -346,17 +358,21 @@ static int mvebu_a3700_comphy_sata_power_on(uint8_t comphy_index,
COMPHY_LANE2_INDIR_DATA_OFFSET,
PLL_READY_TX_BIT, PLL_READY_TX_BIT,
COMPHY_PLL_TIMEOUT, REG_32BIT);
+ if (ret) {
+ return -ETIMEDOUT;
+ }
debug_exit();
- return ret;
+ return 0;
}
static int mvebu_a3700_comphy_sgmii_power_on(uint8_t comphy_index,
uint32_t comphy_mode)
{
- int ret = 0;
- uint32_t mask, data, offset;
+ int ret;
+ uint32_t mask, data;
+ uintptr_t offset;
uintptr_t sd_ip_addr;
int mode = COMPHY_GET_MODE(comphy_mode);
int invert = COMPHY_GET_POLARITY_INVERT(comphy_mode);
@@ -364,7 +380,10 @@ static int mvebu_a3700_comphy_sgmii_power_on(uint8_t comphy_index,
debug_enter();
/* Set selector */
- mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode);
+ ret = mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode);
+ if (ret) {
+ return ret;
+ }
/* Serdes IP Base address
* COMPHY Lane0 -- USB3/GBE1
@@ -401,8 +420,8 @@ static int mvebu_a3700_comphy_sgmii_power_on(uint8_t comphy_index,
/* SGMII 1G, SerDes speed 1.25G */
data |= SD_SPEED_1_25_G << GEN_RX_SEL_OFFSET;
data |= SD_SPEED_1_25_G << GEN_TX_SEL_OFFSET;
- } else if (mode == COMPHY_HS_SGMII_MODE) {
- /* HS SGMII (2.5G), SerDes speed 3.125G */
+ } else if (mode == COMPHY_2500BASEX_MODE) {
+ /* 2500Base-X, SerDes speed 3.125G */
data |= SD_SPEED_2_5_G << GEN_RX_SEL_OFFSET;
data |= SD_SPEED_2_5_G << GEN_TX_SEL_OFFSET;
} else {
@@ -479,9 +498,9 @@ static int mvebu_a3700_comphy_sgmii_power_on(uint8_t comphy_index,
* 25 MHz the default values stored in PHY registers are OK.
*/
debug("Running C-DPI phy init %s mode\n",
- mode == COMPHY_HS_SGMII_MODE ? "2G5" : "1G");
+ mode == COMPHY_2500BASEX_MODE ? "2G5" : "1G");
if (get_ref_clk() == 40)
- comphy_sgmii_phy_init(comphy_index, mode, sd_ip_addr);
+ comphy_sgmii_phy_init(sd_ip_addr, mode != COMPHY_2500BASEX_MODE);
/*
* 14. [Simulation Only] should not be used for real chip.
@@ -525,8 +544,10 @@ static int mvebu_a3700_comphy_sgmii_power_on(uint8_t comphy_index,
PHY_PLL_READY_TX_BIT | PHY_PLL_READY_RX_BIT,
PHY_PLL_READY_TX_BIT | PHY_PLL_READY_RX_BIT,
COMPHY_PLL_TIMEOUT, REG_32BIT);
- if (ret)
+ if (ret) {
ERROR("Failed to lock PLL for SGMII PHY %d\n", comphy_index);
+ return -ETIMEDOUT;
+ }
/*
* 19. Set COMPHY input port PIN_TX_IDLE=0
@@ -549,26 +570,29 @@ static int mvebu_a3700_comphy_sgmii_power_on(uint8_t comphy_index,
PHY_PLL_READY_TX_BIT | PHY_PLL_READY_RX_BIT,
PHY_PLL_READY_TX_BIT | PHY_PLL_READY_RX_BIT,
COMPHY_PLL_TIMEOUT, REG_32BIT);
- if (ret)
+ if (ret) {
ERROR("Failed to lock PLL for SGMII PHY %d\n", comphy_index);
-
+ return -ETIMEDOUT;
+ }
ret = polling_with_timeout(MVEBU_COMPHY_REG_BASE +
COMPHY_PHY_STATUS_OFFSET(comphy_index),
PHY_RX_INIT_DONE_BIT, PHY_RX_INIT_DONE_BIT,
COMPHY_PLL_TIMEOUT, REG_32BIT);
- if (ret)
+ if (ret) {
ERROR("Failed to init RX of SGMII PHY %d\n", comphy_index);
+ return -ETIMEDOUT;
+ }
debug_exit();
- return ret;
+ return 0;
}
static int mvebu_a3700_comphy_sgmii_power_off(uint8_t comphy_index)
{
- int ret = 0;
- uint32_t mask, data, offset;
+ uintptr_t offset;
+ uint32_t mask, data;
debug_enter();
@@ -579,28 +603,31 @@ static int mvebu_a3700_comphy_sgmii_power_off(uint8_t comphy_index)
debug_exit();
- return ret;
+ return 0;
}
static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index,
uint32_t comphy_mode)
{
- int ret = 0;
+ int ret;
uintptr_t reg_base = 0;
- uint32_t mask, data, addr, cfg, ref_clk;
+ uintptr_t addr;
+ uint32_t mask, data, cfg, ref_clk;
void (*usb3_reg_set)(uintptr_t addr, uint32_t reg_offset, uint16_t data,
- uint16_t mask, int mode);
- int mode = COMPHY_GET_MODE(comphy_mode);
+ uint16_t mask);
int invert = COMPHY_GET_POLARITY_INVERT(comphy_mode);
debug_enter();
/* Set phy seclector */
- mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode);
+ ret = mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode);
+ if (ret) {
+ return ret;
+ }
/* Set usb3 reg access func, Lane2 is indirect access */
if (comphy_index == COMPHY_LANE2) {
- usb3_reg_set = &comphy_set_indirect;
+ usb3_reg_set = &comphy_usb3_set_indirect;
reg_base = COMPHY_INDIRECT_REG;
} else {
/* Get the direct access register resource and map */
@@ -619,7 +646,7 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index,
mask = PRD_TXDEEMPH0_MASK | PRD_TXMARGIN_MASK | PRD_TXSWING_MASK |
CFG_TX_ALIGN_POS_MASK;
usb3_reg_set(reg_base, COMPHY_REG_LANE_CFG0_ADDR, PRD_TXDEEMPH0_MASK,
- mask, mode);
+ mask);
/*
* 2. Set BIT0: enable transmitter in high impedance mode
@@ -631,20 +658,20 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index,
mask = PRD_TXDEEMPH1_MASK | TX_DET_RX_MODE | GEN2_TX_DATA_DLY_MASK |
TX_ELEC_IDLE_MODE_EN;
data = TX_DET_RX_MODE | GEN2_TX_DATA_DLY_DEFT | TX_ELEC_IDLE_MODE_EN;
- usb3_reg_set(reg_base, COMPHY_REG_LANE_CFG1_ADDR, data, mask, mode);
+ usb3_reg_set(reg_base, COMPHY_REG_LANE_CFG1_ADDR, data, mask);
/*
* 3. Set Spread Spectrum Clock Enabled
*/
usb3_reg_set(reg_base, COMPHY_REG_LANE_CFG4_ADDR,
- SPREAD_SPECTRUM_CLK_EN, SPREAD_SPECTRUM_CLK_EN, mode);
+ SPREAD_SPECTRUM_CLK_EN, SPREAD_SPECTRUM_CLK_EN);
/*
* 4. Set Override Margining Controls From the MAC:
* Use margining signals from lane configuration
*/
usb3_reg_set(reg_base, COMPHY_REG_TEST_MODE_CTRL_ADDR,
- MODE_MARGIN_OVERRIDE, REG_16_BIT_MASK, mode);
+ MODE_MARGIN_OVERRIDE, REG_16_BIT_MASK);
/*
* 5. Set Lane-to-Lane Bundle Clock Sampling Period = per PCLK cycles
@@ -652,13 +679,13 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index,
*/
usb3_reg_set(reg_base, COMPHY_REG_GLOB_CLK_SRC_LO_ADDR, 0x0,
(MODE_CLK_SRC | BUNDLE_PERIOD_SEL | BUNDLE_PERIOD_SCALE |
- BUNDLE_SAMPLE_CTRL | PLL_READY_DLY), mode);
+ BUNDLE_SAMPLE_CTRL | PLL_READY_DLY));
/*
* 6. Set G2 Spread Spectrum Clock Amplitude at 4K
*/
usb3_reg_set(reg_base, COMPHY_REG_GEN2_SET_2,
- G2_TX_SSC_AMP_VALUE_20, G2_TX_SSC_AMP_MASK, mode);
+ G2_TX_SSC_AMP_VALUE_20, G2_TX_SSC_AMP_MASK);
/*
* 7. Unset G3 Spread Spectrum Clock Amplitude
@@ -667,7 +694,7 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index,
mask = G3_TX_SSC_AMP_MASK | G3_VREG_RXTX_MAS_ISET_MASK |
RSVD_PH03FH_6_0_MASK;
usb3_reg_set(reg_base, COMPHY_REG_GEN2_SET_3,
- G3_VREG_RXTX_MAS_ISET_60U, mask, mode);
+ G3_VREG_RXTX_MAS_ISET_60U, mask);
/*
* 8. Check crystal jumper setting and program the Power and PLL Control
@@ -688,39 +715,37 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index,
REF_FREF_SEL_MASK;
data = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT |
PU_TX_INTP_BIT | PU_DFE_BIT | PHY_MODE_USB3 | ref_clk;
- usb3_reg_set(reg_base, COMPHY_POWER_PLL_CTRL, data, mask, mode);
+ usb3_reg_set(reg_base, COMPHY_POWER_PLL_CTRL, data, mask);
mask = CFG_PM_OSCCLK_WAIT_MASK | CFG_PM_RXDEN_WAIT_MASK |
CFG_PM_RXDLOZ_WAIT_MASK;
data = CFG_PM_RXDEN_WAIT_1_UNIT | cfg;
- usb3_reg_set(reg_base, COMPHY_REG_PWR_MGM_TIM1_ADDR, data, mask, mode);
+ usb3_reg_set(reg_base, COMPHY_REG_PWR_MGM_TIM1_ADDR, data, mask);
/*
* 9. Enable idle sync
*/
data = UNIT_CTRL_DEFAULT_VALUE | IDLE_SYNC_EN;
- usb3_reg_set(reg_base, COMPHY_REG_UNIT_CTRL_ADDR, data, REG_16_BIT_MASK,
- mode);
+ usb3_reg_set(reg_base, COMPHY_REG_UNIT_CTRL_ADDR, data, REG_16_BIT_MASK);
/*
* 10. Enable the output of 500M clock
*/
data = MISC_REG0_DEFAULT_VALUE | CLK500M_EN;
- usb3_reg_set(reg_base, COMPHY_MISC_REG0_ADDR, data, REG_16_BIT_MASK,
- mode);
+ usb3_reg_set(reg_base, COMPHY_MISC_REG0_ADDR, data, REG_16_BIT_MASK);
/*
* 11. Set 20-bit data width
*/
usb3_reg_set(reg_base, COMPHY_LOOPBACK_REG0, DATA_WIDTH_20BIT,
- REG_16_BIT_MASK, mode);
+ REG_16_BIT_MASK);
/*
* 12. Override Speed_PLL value and use MAC PLL
*/
usb3_reg_set(reg_base, COMPHY_KVCO_CAL_CTRL,
(SPEED_PLL_VALUE_16 | USE_MAX_PLL_RATE_BIT),
- REG_16_BIT_MASK, mode);
+ REG_16_BIT_MASK);
/*
* 13. Check the Polarity invert bit
@@ -733,27 +758,26 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index,
data |= RXD_INVERT_BIT;
}
mask = TXD_INVERT_BIT | RXD_INVERT_BIT;
- usb3_reg_set(reg_base, COMPHY_SYNC_PATTERN_REG, data, mask, mode);
+ usb3_reg_set(reg_base, COMPHY_SYNC_PATTERN_REG, data, mask);
/*
* 14. Set max speed generation to USB3.0 5Gbps
*/
usb3_reg_set(reg_base, COMPHY_SYNC_MASK_GEN_REG, PHY_GEN_USB3_5G,
- PHY_GEN_MAX_MASK, mode);
+ PHY_GEN_MAX_MASK);
/*
* 15. Set capacitor value for FFE gain peaking to 0xF
*/
usb3_reg_set(reg_base, COMPHY_REG_GEN3_SETTINGS_3,
- COMPHY_GEN_FFE_CAP_SEL_VALUE, COMPHY_GEN_FFE_CAP_SEL_MASK,
- mode);
+ COMPHY_GEN_FFE_CAP_SEL_VALUE, COMPHY_GEN_FFE_CAP_SEL_MASK);
/*
* 16. Release SW reset
*/
data = MODE_CORE_CLK_FREQ_SEL | MODE_PIPE_WIDTH_32 | MODE_REFDIV_BY_4;
usb3_reg_set(reg_base, COMPHY_REG_GLOB_PHY_CTRL0_ADDR, data,
- REG_16_BIT_MASK, mode);
+ REG_16_BIT_MASK);
/* Wait for > 55 us to allow PCLK be enabled */
udelay(PLL_SET_DELAY_US);
@@ -771,12 +795,14 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index,
TXDCLK_PCLK_EN, TXDCLK_PCLK_EN,
COMPHY_PLL_TIMEOUT, REG_16BIT);
}
- if (ret)
+ if (ret) {
ERROR("Failed to lock USB3 PLL\n");
+ return -ETIMEDOUT;
+ }
debug_exit();
- return ret;
+ return 0;
}
static int mvebu_a3700_comphy_pcie_power_on(uint8_t comphy_index,
@@ -789,6 +815,12 @@ static int mvebu_a3700_comphy_pcie_power_on(uint8_t comphy_index,
debug_enter();
+ /* Configure phy selector for PCIe */
+ ret = mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode);
+ if (ret) {
+ return ret;
+ }
+
/* 1. Enable max PLL. */
reg_set16(LANE_CFG1_ADDR(PCIE) + COMPHY_SD_ADDR,
USE_MAX_PLL_RATE_EN, USE_MAX_PLL_RATE_EN);
@@ -862,12 +894,14 @@ static int mvebu_a3700_comphy_pcie_power_on(uint8_t comphy_index,
ret = polling_with_timeout(LANE_STATUS1_ADDR(PCIE) + COMPHY_SD_ADDR,
TXDCLK_PCLK_EN, TXDCLK_PCLK_EN,
COMPHY_PLL_TIMEOUT, REG_16BIT);
- if (ret)
+ if (ret) {
ERROR("Failed to lock PCIE PLL\n");
+ return -ETIMEDOUT;
+ }
debug_exit();
- return ret;
+ return 0;
}
int mvebu_3700_comphy_power_on(uint8_t comphy_index, uint32_t comphy_mode)
@@ -883,7 +917,7 @@ int mvebu_3700_comphy_power_on(uint8_t comphy_index, uint32_t comphy_mode)
comphy_mode);
break;
case(COMPHY_SGMII_MODE):
- case(COMPHY_HS_SGMII_MODE):
+ case(COMPHY_2500BASEX_MODE):
ret = mvebu_a3700_comphy_sgmii_power_on(comphy_index,
comphy_mode);
break;
@@ -919,23 +953,22 @@ static int mvebu_a3700_comphy_usb3_power_off(void)
return 0;
}
-static int mvebu_a3700_comphy_sata_power_off(uint32_t comphy_mode)
+static int mvebu_a3700_comphy_sata_power_off(void)
{
uintptr_t comphy_indir_regs = COMPHY_INDIRECT_REG;
- int mode = COMPHY_GET_MODE(comphy_mode);
uint32_t offset;
debug_enter();
/* Set phy isolation mode */
offset = COMPHY_ISOLATION_CTRL_REG + SATAPHY_LANE2_REG_BASE_OFFSET;
- comphy_set_indirect(comphy_indir_regs, offset, PHY_ISOLATE_MODE,
- PHY_ISOLATE_MODE, mode);
+ comphy_sata_set_indirect(comphy_indir_regs, offset, PHY_ISOLATE_MODE,
+ PHY_ISOLATE_MODE);
/* Power off PLL, Tx, Rx */
offset = COMPHY_POWER_PLL_CTRL + SATAPHY_LANE2_REG_BASE_OFFSET;
- comphy_set_indirect(comphy_indir_regs, offset, 0,
- PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT, mode);
+ comphy_sata_set_indirect(comphy_indir_regs, offset, 0,
+ PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT);
debug_exit();
@@ -960,7 +993,7 @@ int mvebu_3700_comphy_power_off(uint8_t comphy_index, uint32_t comphy_mode)
switch (mode) {
case(COMPHY_SGMII_MODE):
- case(COMPHY_HS_SGMII_MODE):
+ case(COMPHY_2500BASEX_MODE):
err = mvebu_a3700_comphy_sgmii_power_off(comphy_index);
break;
case (COMPHY_USB3_MODE):
@@ -968,7 +1001,7 @@ int mvebu_3700_comphy_power_off(uint8_t comphy_index, uint32_t comphy_mode)
err = mvebu_a3700_comphy_usb3_power_off();
break;
case (COMPHY_SATA_MODE):
- err = mvebu_a3700_comphy_sata_power_off(comphy_mode);
+ err = mvebu_a3700_comphy_sata_power_off();
break;
default:
diff --git a/drivers/marvell/comphy/phy-comphy-common.h b/drivers/marvell/comphy/phy-comphy-common.h
index e3b430a91..c599437a3 100644
--- a/drivers/marvell/comphy/phy-comphy-common.h
+++ b/drivers/marvell/comphy/phy-comphy-common.h
@@ -87,7 +87,7 @@
#define COMPHY_SATA_MODE 0x1
#define COMPHY_SGMII_MODE 0x2 /* SGMII 1G */
-#define COMPHY_HS_SGMII_MODE 0x3 /* SGMII 2.5G */
+#define COMPHY_2500BASEX_MODE 0x3 /* 2500Base-X */
#define COMPHY_USB3H_MODE 0x4
#define COMPHY_USB3D_MODE 0x5
#define COMPHY_PCIE_MODE 0x6
diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c
index 86f4c77c5..fa9fe4100 100644
--- a/drivers/marvell/comphy/phy-comphy-cp110.c
+++ b/drivers/marvell/comphy/phy-comphy-cp110.c
@@ -8,6 +8,8 @@
/* Marvell CP110 SoC COMPHY unit driver */
#include <errno.h>
+#include <inttypes.h>
+#include <stdint.h>
#include <common/debug.h>
#include <drivers/delay_timer.h>
@@ -30,7 +32,7 @@
/* COMPHY speed macro */
#define COMPHY_SPEED_1_25G 0 /* SGMII 1G */
#define COMPHY_SPEED_2_5G 1
-#define COMPHY_SPEED_3_125G 2 /* SGMII 2.5G */
+#define COMPHY_SPEED_3_125G 2 /* 2500Base-X */
#define COMPHY_SPEED_5G 3
#define COMPHY_SPEED_5_15625G 4 /* XFI 5G */
#define COMPHY_SPEED_6G 5
@@ -102,7 +104,7 @@ static void mvebu_cp110_get_ap_and_cp_nr(uint8_t *ap_nr, uint8_t *cp_nr,
*cp_nr = (((comphy_base & ~0xffffff) - MVEBU_AP_IO_BASE(*ap_nr)) /
MVEBU_CP_OFFSET);
- debug("cp_base 0x%llx, ap_io_base 0x%lx, cp_offset 0x%lx\n",
+ debug("cp_base 0x%" PRIx64 ", ap_io_base 0x%lx, cp_offset 0x%lx\n",
comphy_base, (unsigned long)MVEBU_AP_IO_BASE(*ap_nr),
(unsigned long)MVEBU_CP_OFFSET);
}
@@ -191,7 +193,7 @@ static void mvebu_cp110_comphy_set_phy_selector(uint64_t comphy_base,
case(3):
/* For comphy 3:
* 0x1 = RXAUI_Lane1
- * 0x2 = SGMII/HS-SGMII Port1
+ * 0x2 = SGMII/Base-X Port1
*/
if (mode == COMPHY_RXAUI_MODE)
reg |= COMMON_SELECTOR_COMPHY3_RXAUI <<
@@ -202,20 +204,20 @@ static void mvebu_cp110_comphy_set_phy_selector(uint64_t comphy_base,
break;
case(4):
/* For comphy 4:
- * 0x1 = SGMII/HS-SGMII Port1, XFI1/SFI1
- * 0x2 = SGMII/HS-SGMII Port0: XFI0/SFI0, RXAUI_Lane0
+ * 0x1 = SGMII/Base-X Port1, XFI1/SFI1
+ * 0x2 = SGMII/Base-X Port0: XFI0/SFI0, RXAUI_Lane0
*
- * We want to check if SGMII1/HS_SGMII1 is the
+ * We want to check if SGMII1 is the
* requested mode in order to determine which value
* should be set (all other modes use the same value)
* so we need to strip the mode, and check the ID
- * because we might handle SGMII0/HS_SGMII0 too.
+ * because we might handle SGMII0 too.
*/
/* TODO: need to distinguish between CP110 and CP115
* as SFI1/XFI1 available only for CP115.
*/
if ((mode == COMPHY_SGMII_MODE ||
- mode == COMPHY_HS_SGMII_MODE ||
+ mode == COMPHY_2500BASEX_MODE ||
mode == COMPHY_SFI_MODE ||
mode == COMPHY_XFI_MODE ||
mode == COMPHY_AP_MODE)
@@ -228,7 +230,7 @@ static void mvebu_cp110_comphy_set_phy_selector(uint64_t comphy_base,
break;
case(5):
/* For comphy 5:
- * 0x1 = SGMII/HS-SGMII Port2
+ * 0x1 = SGMII/Base-X Port2
* 0x2 = RXAUI Lane1
*/
if (mode == COMPHY_RXAUI_MODE)
@@ -713,7 +715,7 @@ static int mvebu_cp110_comphy_sgmii_power_on(uint64_t comphy_base,
data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
} else if (sgmii_speed == COMPHY_SPEED_3_125G) {
- /* HS SGMII (2.5G), SerDes speed 3.125G */
+ /* 2500Base-X, SerDes speed 3.125G */
data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
} else {
@@ -1730,11 +1732,13 @@ static int mvebu_cp110_comphy_pcie_power_on(uint64_t comphy_base,
HPIPE_LANE_STATUS1_REG;
data = HPIPE_LANE_STATUS1_PCLK_EN_MASK;
mask = data;
- ret = polling_with_timeout(addr, data, mask,
+ data = polling_with_timeout(addr, data, mask,
PLL_LOCK_TIMEOUT,
REG_32BIT);
- if (ret)
+ if (data) {
ERROR("Failed to lock PCIE PLL\n");
+ ret = -ETIMEDOUT;
+ }
}
}
@@ -2343,7 +2347,7 @@ int mvebu_cp110_comphy_digital_reset(uint64_t comphy_base,
switch (mode) {
case (COMPHY_SGMII_MODE):
- case (COMPHY_HS_SGMII_MODE):
+ case (COMPHY_2500BASEX_MODE):
case (COMPHY_XFI_MODE):
case (COMPHY_SFI_MODE):
case (COMPHY_RXAUI_MODE):
@@ -2378,7 +2382,7 @@ int mvebu_cp110_comphy_power_on(uint64_t comphy_base,
comphy_mode);
break;
case(COMPHY_SGMII_MODE):
- case(COMPHY_HS_SGMII_MODE):
+ case(COMPHY_2500BASEX_MODE):
err = mvebu_cp110_comphy_sgmii_power_on(comphy_base,
comphy_index,
comphy_mode);
diff --git a/drivers/marvell/gwin.c b/drivers/marvell/gwin.c
index 9d9430836..fa59cb033 100644
--- a/drivers/marvell/gwin.c
+++ b/drivers/marvell/gwin.c
@@ -7,6 +7,9 @@
/* GWIN unit device driver for Marvell AP810 SoC */
+#include <inttypes.h>
+#include <stdint.h>
+
#include <common/debug.h>
#include <drivers/marvell/gwin.h>
#include <lib/mmio.h>
@@ -49,14 +52,14 @@ static void gwin_check(struct addr_map_win *win)
/* The base is always 64M aligned */
if (IS_NOT_ALIGN(win->base_addr, GWIN_ALIGNMENT_64M)) {
win->base_addr &= ~(GWIN_ALIGNMENT_64M - 1);
- NOTICE("%s: Align the base address to 0x%llx\n",
+ NOTICE("%s: Align the base address to 0x%" PRIx64 "\n",
__func__, win->base_addr);
}
/* size parameter validity check */
if (IS_NOT_ALIGN(win->win_size, GWIN_ALIGNMENT_64M)) {
win->win_size = ALIGN_UP(win->win_size, GWIN_ALIGNMENT_64M);
- NOTICE("%s: Aligning window size to 0x%llx\n",
+ NOTICE("%s: Aligning window size to 0x%" PRIx64 "\n",
__func__, win->win_size);
}
}
@@ -167,7 +170,7 @@ static void dump_gwin(int ap_index)
alr = (alr >> ADDRESS_LSHIFT) << ADDRESS_RSHIFT;
ahr = mmio_read_32(GWIN_AHR_OFFSET(ap_index, win_num));
ahr = (ahr >> ADDRESS_LSHIFT) << ADDRESS_RSHIFT;
- printf("\tgwin %d 0x%016llx 0x%016llx\n",
+ printf("\tgwin %d 0x%016" PRIx64 " 0x%016" PRIx64 "\n",
(cr >> 8) & 0xF, alr, ahr);
}
}
diff --git a/drivers/marvell/io_win.c b/drivers/marvell/io_win.c
index c4257fa7c..124382ad9 100644
--- a/drivers/marvell/io_win.c
+++ b/drivers/marvell/io_win.c
@@ -7,6 +7,9 @@
/* IO Window unit device driver for Marvell AP807, AP807 and AP810 SoCs */
+#include <inttypes.h>
+#include <stdint.h>
+
#include <common/debug.h>
#include <drivers/marvell/io_win.h>
#include <lib/mmio.h>
@@ -44,14 +47,14 @@ static void io_win_check(struct addr_map_win *win)
/* check if address is aligned to 1M */
if (IS_NOT_ALIGN(win->base_addr, IO_WIN_ALIGNMENT_1M)) {
win->base_addr = ALIGN_UP(win->base_addr, IO_WIN_ALIGNMENT_1M);
- NOTICE("%s: Align up the base address to 0x%llx\n",
+ NOTICE("%s: Align up the base address to 0x%" PRIx64 "\n",
__func__, win->base_addr);
}
/* size parameter validity check */
if (IS_NOT_ALIGN(win->win_size, IO_WIN_ALIGNMENT_1M)) {
win->win_size = ALIGN_UP(win->win_size, IO_WIN_ALIGNMENT_1M);
- NOTICE("%s: Aligning size to 0x%llx\n",
+ NOTICE("%s: Aligning size to 0x%" PRIx64 "\n",
__func__, win->win_size);
}
}
@@ -170,7 +173,7 @@ static void dump_io_win(int ap_index)
win_id));
start = ((uint64_t)alr << ADDRESS_SHIFT);
end = (((uint64_t)ahr + 0x10) << ADDRESS_SHIFT);
- printf("\tio-win %d 0x%016llx 0x%016llx\n",
+ printf("\tio-win %d 0x%016" PRIx64 " 0x%016" PRIx64 "\n",
trgt_id, start, end);
}
}
diff --git a/drivers/marvell/iob.c b/drivers/marvell/iob.c
index 29088aa92..1f3939560 100644
--- a/drivers/marvell/iob.c
+++ b/drivers/marvell/iob.c
@@ -7,6 +7,9 @@
/* IOW unit device driver for Marvell CP110 and CP115 SoCs */
+#include <inttypes.h>
+#include <stdint.h>
+
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/marvell/iob.h>
@@ -57,7 +60,7 @@ static void iob_win_check(struct addr_map_win *win, uint32_t win_num)
win->base_addr = ALIGN_UP(win->base_addr, IOB_WIN_ALIGNMENT);
ERROR("Window %d: base address unaligned to 0x%x\n",
win_num, IOB_WIN_ALIGNMENT);
- printf("Align up the base address to 0x%llx\n",
+ printf("Align up the base address to 0x%" PRIx64 "\n",
win->base_addr);
}
@@ -66,7 +69,7 @@ static void iob_win_check(struct addr_map_win *win, uint32_t win_num)
win->win_size = ALIGN_UP(win->win_size, IOB_WIN_ALIGNMENT);
ERROR("Window %d: window size unaligned to 0x%x\n", win_num,
IOB_WIN_ALIGNMENT);
- printf("Aligning size to 0x%llx\n", win->win_size);
+ printf("Aligning size to 0x%" PRIx64 "\n", win->win_size);
}
}
@@ -130,7 +133,7 @@ static void dump_iob(void)
*/
end = start + (16 << 20);
}
- printf("iob %02d %s 0x%016llx 0x%016llx\n",
+ printf("iob %02d %s 0x%016" PRIx64 " 0x%016" PRIx64 "\n",
win_id, iob_target_name[target_id],
start, end);
}
diff --git a/drivers/marvell/mc_trustzone/mc_trustzone.c b/drivers/marvell/mc_trustzone/mc_trustzone.c
index 52b300676..648bd0e98 100644
--- a/drivers/marvell/mc_trustzone/mc_trustzone.c
+++ b/drivers/marvell/mc_trustzone/mc_trustzone.c
@@ -5,6 +5,9 @@
* https://spdx.org/licenses
*/
+#include <inttypes.h>
+#include <stdint.h>
+
#include <common/debug.h>
#include <drivers/marvell/addr_map.h>
#include <lib/mmio.h>
@@ -39,7 +42,7 @@ void tz_enable_win(int ap_index, const struct addr_map_win *win, int win_id)
/* map the window size to trustzone register convention */
tz_size = fls(TZ_SIZE(win->win_size));
- VERBOSE("%s: window size = 0x%llx maps to tz_size %d\n",
+ VERBOSE("%s: window size = 0x%" PRIx64 " maps to tz_size %d\n",
__func__, win->win_size, tz_size);
if (tz_size < 0 || tz_size > 31) {
ERROR("Using not allowed size for MC TrustZone window %d!\n",
@@ -49,7 +52,7 @@ void tz_enable_win(int ap_index, const struct addr_map_win *win, int win_id)
if (base & 0xfff) {
base = base & ~0xfff;
- WARN("Attempt to open MC TZ win. at 0x%llx, truncate to 0x%x\n",
+ WARN("Attempt to open MC TZ win. at 0x%" PRIx64 ", truncate to 0x%x\n",
win->base_addr, base);
}
diff --git a/drivers/measured_boot/event_log.c b/drivers/measured_boot/event_log/event_log.c
index 0157b0300..1755dd95e 100644
--- a/drivers/measured_boot/event_log.c
+++ b/drivers/measured_boot/event_log/event_log.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,27 +12,19 @@
#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/auth/crypto_mod.h>
-#include <drivers/measured_boot/event_log.h>
+#include <drivers/measured_boot/event_log/event_log.h>
#include <mbedtls/md.h>
#include <plat/common/platform.h>
-/* Event Log data */
-static uint8_t event_log[EVENT_LOG_SIZE];
+/* Running Event Log Pointer */
+static uint8_t *log_ptr;
-/* End of Event Log */
-#define EVENT_LOG_END ((uintptr_t)event_log + sizeof(event_log) - 1U)
+/* Pointer to the first byte past end of the Event Log buffer */
+static uintptr_t log_end;
-CASSERT(sizeof(event_log) >= LOG_MIN_SIZE, assert_event_log_size);
-
-/* Pointer in event_log[] */
-static uint8_t *log_ptr = event_log;
-
-/* Pointer to measured_boot_data_t */
-const static measured_boot_data_t *plat_data_ptr;
-
-static uintptr_t tos_fw_config_base;
-static uintptr_t nt_fw_config_base;
+/* Pointer to event_log_metadata_t */
+static const event_log_metadata_t *plat_metadata_ptr;
/* TCG_EfiSpecIdEvent */
static const id_event_headers_t id_event_header = {
@@ -80,26 +72,30 @@ static const event2_header_t locality_event_header = {
};
/*
- * Add TCG_PCR_EVENT2 event
+ * Record a measurement as a TCG_PCR_EVENT2 event
*
- * @param[in] hash Pointer to hash data of TCG_DIGEST_SIZE bytes
- * @param[in] image_ptr Pointer to image_data_t structure
+ * @param[in] hash Pointer to hash data of TCG_DIGEST_SIZE bytes
+ * @param[in] metadata_ptr Pointer to event_log_metadata_t structure
*
* There must be room for storing this new event into the event log buffer.
*/
-static void add_event2(const uint8_t *hash, const image_data_t *image_ptr)
+static void event_log_record(const uint8_t *hash,
+ const event_log_metadata_t *metadata_ptr)
{
void *ptr = log_ptr;
uint32_t name_len;
- assert(image_ptr != NULL);
- assert(image_ptr->name != NULL);
+ assert(hash != NULL);
+ assert(metadata_ptr != NULL);
+ assert(metadata_ptr->name != NULL);
+ /* event_log_init() must have been called prior to this. */
+ assert(log_ptr != NULL);
- name_len = (uint32_t)strlen(image_ptr->name) + 1U;
+ name_len = (uint32_t)strlen(metadata_ptr->name) + 1U;
/* Check for space in Event Log buffer */
- assert(((uintptr_t)ptr + (uint32_t)EVENT2_HDR_SIZE + name_len) <=
- EVENT_LOG_END);
+ assert(((uintptr_t)ptr + (uint32_t)EVENT2_HDR_SIZE + name_len) <
+ log_end);
/*
* As per TCG specifications, firmware components that are measured
@@ -107,7 +103,7 @@ static void add_event2(const uint8_t *hash, const image_data_t *image_ptr)
* EV_POST_CODE.
*/
/* TCG_PCR_EVENT2.PCRIndex */
- ((event2_header_t *)ptr)->pcr_index = image_ptr->pcr;
+ ((event2_header_t *)ptr)->pcr_index = metadata_ptr->pcr;
/* TCG_PCR_EVENT2.EventType */
((event2_header_t *)ptr)->event_type = EV_POST_CODE;
@@ -126,13 +122,8 @@ static void add_event2(const uint8_t *hash, const image_data_t *image_ptr)
/* TCG_PCR_EVENT2.Digests[].Digest[] */
ptr = (uint8_t *)((uintptr_t)ptr + offsetof(tpmt_ha, digest));
- if (hash == NULL) {
- /* Get BL2 hash from DTB */
- bl2_plat_get_hash(ptr);
- } else {
- /* Copy digest */
- (void)memcpy(ptr, (const void *)hash, TCG_DIGEST_SIZE);
- }
+ /* Copy digest */
+ (void)memcpy(ptr, (const void *)hash, TCG_DIGEST_SIZE);
/* TCG_PCR_EVENT2.EventSize */
ptr = (uint8_t *)((uintptr_t)ptr + TCG_DIGEST_SIZE);
@@ -140,7 +131,7 @@ static void add_event2(const uint8_t *hash, const image_data_t *image_ptr)
/* Copy event data to TCG_PCR_EVENT2.Event */
(void)memcpy((void *)(((event2_data_t *)ptr)->event),
- (const void *)image_ptr->name, name_len);
+ (const void *)metadata_ptr->name, name_len);
/* End of event data */
log_ptr = (uint8_t *)((uintptr_t)ptr +
@@ -148,18 +139,38 @@ static void add_event2(const uint8_t *hash, const image_data_t *image_ptr)
}
/*
- * Init Event Log
+ * Initialise Event Log global variables, used during the recording
+ * of various payload measurements into the Event Log buffer
*
+ * @param[in] event_log_start Base address of Event Log buffer
+ * @param[in] event_log_finish End address of Event Log buffer,
+ * it is a first byte past end of the
+ * buffer
+ */
+void event_log_init(uint8_t *event_log_start, uint8_t *event_log_finish)
+{
+ assert(event_log_start != NULL);
+ assert(event_log_finish > event_log_start);
+
+ log_ptr = event_log_start;
+ log_end = (uintptr_t)event_log_finish;
+
+ /* Get pointer to platform's event_log_metadata_t structure */
+ plat_metadata_ptr = plat_event_log_get_metadata();
+ assert(plat_metadata_ptr != NULL);
+}
+
+/*
* Initialises Event Log by writing Specification ID and
- * Startup Locality events.
+ * Startup Locality events
*/
-void event_log_init(void)
+void event_log_write_header(void)
{
const char locality_signature[] = TCG_STARTUP_LOCALITY_SIGNATURE;
- void *ptr = event_log;
+ void *ptr = log_ptr;
- /* Get pointer to platform's measured_boot_data_t structure */
- plat_data_ptr = plat_get_measured_boot_data();
+ /* event_log_init() must have been called prior to this. */
+ assert(log_ptr != NULL);
/*
* Add Specification ID Event first
@@ -217,12 +228,7 @@ void event_log_init(void)
* the platform's boot firmware
*/
((startup_locality_event_t *)ptr)->startup_locality = 0U;
- ptr = (uint8_t *)((uintptr_t)ptr + sizeof(startup_locality_event_t));
-
- log_ptr = (uint8_t *)ptr;
-
- /* Add BL2 event */
- add_event2(NULL, plat_data_ptr->images_data);
+ log_ptr = (uint8_t *)((uintptr_t)ptr + sizeof(startup_locality_event_t));
}
/*
@@ -236,26 +242,19 @@ void event_log_init(void)
* 0 = success
* < 0 = error
*/
-int tpm_record_measurement(uintptr_t data_base, uint32_t data_size,
- uint32_t data_id)
+int event_log_measure_and_record(uintptr_t data_base, uint32_t data_size,
+ uint32_t data_id)
{
- const image_data_t *data_ptr = plat_data_ptr->images_data;
unsigned char hash_data[MBEDTLS_MD_MAX_SIZE];
int rc;
+ const event_log_metadata_t *metadata_ptr = plat_metadata_ptr;
/* Get the metadata associated with this image. */
- while ((data_ptr->id != INVALID_ID) && (data_ptr->id != data_id)) {
- data_ptr++;
- }
- assert(data_ptr->id != INVALID_ID);
-
- if (data_id == TOS_FW_CONFIG_ID) {
- tos_fw_config_base = data_base;
- } else if (data_id == NT_FW_CONFIG_ID) {
- nt_fw_config_base = data_base;
- } else {
- /* No action */
+ while ((metadata_ptr->id != INVALID_ID) &&
+ (metadata_ptr->id != data_id)) {
+ metadata_ptr++;
}
+ assert(metadata_ptr->id != INVALID_ID);
/* Calculate hash */
rc = crypto_mod_calc_hash((unsigned int)MBEDTLS_MD_ID,
@@ -264,96 +263,22 @@ int tpm_record_measurement(uintptr_t data_base, uint32_t data_size,
return rc;
}
- add_event2(hash_data, data_ptr);
+ event_log_record(hash_data, metadata_ptr);
+
return 0;
}
/*
- * Finalise Event Log
+ * Get current Event Log buffer size i.e. used space of Event Log buffer
*
- * @param[out] log_addr Pointer to return Event Log address
- * @param[out] log_size Pointer to return Event Log size
- * @return:
- * 0 = success
- * < 0 = error code
+ * @param[in] event_log_start Base Pointer to Event Log buffer
+ *
+ * @return: current Size of Event Log buffer
*/
-int event_log_finalise(uint8_t **log_addr, size_t *log_size)
+size_t event_log_get_cur_size(uint8_t *event_log_start)
{
- /* Event Log size */
- size_t num_bytes = (uintptr_t)log_ptr - (uintptr_t)event_log;
- int rc;
-
- assert(log_addr != NULL);
- assert(log_size != NULL);
-
- if (nt_fw_config_base == 0UL) {
- ERROR("%s(): %s_FW_CONFIG not loaded\n", __func__, "NT");
- return -ENOENT;
- }
-
- /*
- * Set Event Log data in NT_FW_CONFIG and
- * get Event Log address in Non-Secure memory
- */
- if (plat_data_ptr->set_nt_fw_info != NULL) {
-
- /* Event Log address in Non-Secure memory */
- uintptr_t ns_log_addr;
-
- rc = plat_data_ptr->set_nt_fw_info(
- nt_fw_config_base,
-#ifdef SPD_opteed
- (uintptr_t)event_log,
-#endif
- num_bytes, &ns_log_addr);
- if (rc != 0) {
- ERROR("%s(): Unable to update %s_FW_CONFIG\n",
- __func__, "NT");
- return rc;
- }
-
- /* Copy Event Log to Non-secure memory */
- (void)memcpy((void *)ns_log_addr, (const void *)event_log,
- num_bytes);
-
- /* Ensure that the Event Log is visible in Non-secure memory */
- flush_dcache_range(ns_log_addr, num_bytes);
-
- /* Return Event Log address in Non-Secure memory */
- *log_addr = (uint8_t *)ns_log_addr;
-
- } else {
- INFO("%s(): set_%s_fw_info not set\n", __func__, "nt");
-
- /* Return Event Log address in Secure memory */
- *log_addr = event_log;
- }
-
- if (tos_fw_config_base != 0UL) {
- if (plat_data_ptr->set_tos_fw_info != NULL) {
-
- /* Set Event Log data in TOS_FW_CONFIG */
- rc = plat_data_ptr->set_tos_fw_info(
- tos_fw_config_base,
- (uintptr_t)event_log,
- num_bytes);
- if (rc != 0) {
- ERROR("%s(): Unable to update %s_FW_CONFIG\n",
- __func__, "TOS");
- return rc;
- }
- } else {
- INFO("%s(): set_%s_fw_info not set\n", __func__, "tos");
- }
- } else {
- INFO("%s(): %s_FW_CONFIG not loaded\n", __func__, "TOS");
- }
-
- /* Ensure that the Event Log is visible in Secure memory */
- flush_dcache_range((uintptr_t)event_log, num_bytes);
+ assert(event_log_start != NULL);
+ assert(log_ptr >= event_log_start);
- /* Return Event Log size */
- *log_size = num_bytes;
-
- return 0;
+ return (size_t)((uintptr_t)log_ptr - (uintptr_t)event_log_start);
}
diff --git a/drivers/measured_boot/measured_boot.mk b/drivers/measured_boot/event_log/event_log.mk
index 497fdbaae..37e5e291d 100644
--- a/drivers/measured_boot/measured_boot.mk
+++ b/drivers/measured_boot/event_log/event_log.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2020, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -7,7 +7,8 @@
# Default log level to dump the event log (LOG_LEVEL_INFO)
EVENT_LOG_LEVEL ?= 40
-# TPM hash algorithm
+# TPM hash algorithm.
+# SHA-256 (or stronger) is required for all devices that are TPM 2.0 compliant.
TPM_HASH_ALG := sha256
ifeq (${TPM_HASH_ALG}, sha512)
@@ -24,8 +25,6 @@ else
TCG_DIGEST_SIZE := 32U
endif
-# Event Log length in bytes
-EVENT_LOG_SIZE := 1024
# Set definitions for mbed TLS library and Measured Boot driver
$(eval $(call add_defines,\
@@ -33,20 +32,19 @@ $(eval $(call add_defines,\
MBEDTLS_MD_ID \
TPM_ALG_ID \
TCG_DIGEST_SIZE \
- EVENT_LOG_SIZE \
EVENT_LOG_LEVEL \
)))
ifeq (${HASH_ALG}, sha256)
-ifneq (${TPM_HASH_ALG}, sha256)
-$(eval $(call add_define,MBEDTLS_SHA512_C))
-endif
+ ifneq (${TPM_HASH_ALG}, sha256)
+ $(eval $(call add_define,MBEDTLS_SHA512_C))
+ endif
endif
-MEASURED_BOOT_SRC_DIR := drivers/measured_boot/
+MEASURED_BOOT_SRC_DIR := drivers/measured_boot/event_log/
-MEASURED_BOOT_SOURCES := ${MEASURED_BOOT_SRC_DIR}measured_boot.c \
- ${MEASURED_BOOT_SRC_DIR}event_log.c \
- ${MEASURED_BOOT_SRC_DIR}event_print.c
+MEASURED_BOOT_SOURCES := ${MEASURED_BOOT_SRC_DIR}event_log.c \
+ ${MEASURED_BOOT_SRC_DIR}event_print.c
BL2_SOURCES += ${MEASURED_BOOT_SOURCES}
+BL1_SOURCES += ${MEASURED_BOOT_SOURCES}
diff --git a/drivers/measured_boot/event_print.c b/drivers/measured_boot/event_log/event_print.c
index 84ed4b1cb..e2ba1744d 100644
--- a/drivers/measured_boot/event_print.c
+++ b/drivers/measured_boot/event_log/event_print.c
@@ -8,7 +8,7 @@
#include <string.h>
#include <common/debug.h>
-#include <drivers/measured_boot/event_log.h>
+#include <drivers/measured_boot/event_log/event_log.h>
#if LOG_LEVEL >= EVENT_LOG_LEVEL
diff --git a/drivers/measured_boot/measured_boot.c b/drivers/measured_boot/measured_boot.c
deleted file mode 100644
index 37fddfbdc..000000000
--- a/drivers/measured_boot/measured_boot.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-
-#include <common/debug.h>
-#include <drivers/measured_boot/measured_boot.h>
-
-/*
- * Init Measured Boot driver
- *
- * Initialises Event Log.
- */
-void measured_boot_init(void)
-{
- event_log_init();
-}
-
-/*
- * Finish Measured Boot driver
- *
- * Finalises Event Log and dumps the records to the debug console.
- */
-void measured_boot_finish(void)
-{
- uint8_t *log_addr;
- size_t log_size;
- int rc;
-
- rc = event_log_finalise(&log_addr, &log_size);
- if (rc != 0) {
- panic();
- }
-
- dump_event_log(log_addr, log_size);
-}
diff --git a/drivers/mtd/nand/spi_nand.c b/drivers/mtd/nand/spi_nand.c
index d01a11963..abb524d7f 100644
--- a/drivers/mtd/nand/spi_nand.c
+++ b/drivers/mtd/nand/spi_nand.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -286,6 +286,10 @@ int spi_nand_init(unsigned long long *size, unsigned int *erase_size)
return -EINVAL;
}
+ assert((spinand_dev.nand_dev->page_size != 0U) &&
+ (spinand_dev.nand_dev->block_size != 0U) &&
+ (spinand_dev.nand_dev->size != 0U));
+
ret = spi_nand_reset();
if (ret != 0) {
return ret;
@@ -301,12 +305,12 @@ int spi_nand_init(unsigned long long *size, unsigned int *erase_size)
return ret;
}
- ret = spi_nand_quad_enable(id[0]);
+ ret = spi_nand_quad_enable(id[1]);
if (ret != 0) {
return ret;
}
- VERBOSE("SPI_NAND Detected ID 0x%x 0x%x\n", id[0], id[1]);
+ VERBOSE("SPI_NAND Detected ID 0x%x\n", id[1]);
VERBOSE("Page size %i, Block size %i, size %lli\n",
spinand_dev.nand_dev->page_size,
diff --git a/drivers/mtd/spi-mem/spi_mem.c b/drivers/mtd/spi-mem/spi_mem.c
index 63ea7699b..010e8b62a 100644
--- a/drivers/mtd/spi-mem/spi_mem.c
+++ b/drivers/mtd/spi-mem/spi_mem.c
@@ -5,6 +5,8 @@
*/
#include <assert.h>
+#include <inttypes.h>
+#include <stdint.h>
#include <libfdt.h>
@@ -150,7 +152,7 @@ int spi_mem_exec_op(const struct spi_mem_op *op)
const struct spi_bus_ops *ops = spi_slave.ops;
int ret;
- VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addqr:%llx len:%x\n",
+ VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addqr:%" PRIx64 " len:%x\n",
__func__, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
op->dummy.buswidth, op->data.buswidth,
op->addr.val, op->data.nbytes);
diff --git a/drivers/nxp/ddr/nxp-ddr/ddr.c b/drivers/nxp/ddr/nxp-ddr/ddr.c
index 216e05c7c..c051b3b25 100644
--- a/drivers/nxp/ddr/nxp-ddr/ddr.c
+++ b/drivers/nxp/ddr/nxp-ddr/ddr.c
@@ -5,6 +5,7 @@
*/
#include <errno.h>
+#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -850,7 +851,7 @@ long long dram_init(struct ddr_info *priv
priv->ip_rev = ip_rev;
#ifndef CONFIG_STATIC_DDR
- INFO("time base %llu ms\n", time_base);
+ INFO("time base %" PRIu64 " ms\n", time_base);
debug("Parse DIMM SPD(s)\n");
valid_spd_mask = parse_spd(priv);
@@ -870,7 +871,7 @@ long long dram_init(struct ddr_info *priv
#endif
time = get_timer_val(time_base);
- INFO("Time after parsing SPD %llu ms\n", time);
+ INFO("Time after parsing SPD %" PRIu64 " ms\n", time);
debug("Synthesize configurations\n");
ret = synthesize_ctlr(priv);
if (ret != 0) {
@@ -911,7 +912,7 @@ long long dram_init(struct ddr_info *priv
}
time = get_timer_val(time_base);
- INFO("Time before programming controller %llu ms\n", time);
+ INFO("Time before programming controller %" PRIu64 " ms\n", time);
debug("Program controller registers\n");
ret = write_ddrc_regs(priv);
if (ret != 0) {
@@ -924,7 +925,7 @@ long long dram_init(struct ddr_info *priv
print_ddr_info(priv->ddr[0]);
time = get_timer_val(time_base);
- INFO("Time used by DDR driver %llu ms\n", time);
+ INFO("Time used by DDR driver %" PRIu64 " ms\n", time);
return dram_size;
}
diff --git a/drivers/nxp/sfp/fuse_prov.c b/drivers/nxp/sfp/fuse_prov.c
index 4d30f5f28..165474fb8 100644
--- a/drivers/nxp/sfp/fuse_prov.c
+++ b/drivers/nxp/sfp/fuse_prov.c
@@ -326,7 +326,7 @@ static int prog_ospr1(struct fuse_hdr_t *fuse_hdr,
struct sfp_ccsr_regs_t *sfp_ccsr_regs)
{
int ret;
- uint32_t mask;
+ uint32_t mask = 0;
#ifdef NXP_SFP_VER_3_4
if (((fuse_hdr->flags >> FLAG_MC_SHIFT) & 0x1) != 0) {
diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c
index 68133eaf4..fdea10dbd 100644
--- a/drivers/partition/partition.c
+++ b/drivers/partition/partition.c
@@ -5,6 +5,7 @@
*/
#include <assert.h>
+#include <inttypes.h>
#include <stdio.h>
#include <string.h>
@@ -31,7 +32,7 @@ static void dump_entries(int num)
name[len + j] = ' ';
}
name[EFI_NAMELEN - 1] = '\0';
- VERBOSE("%d: %s %llx-%llx\n", i + 1, name, list.list[i].start,
+ VERBOSE("%d: %s %" PRIx64 "-%" PRIx64 "\n", i + 1, name, list.list[i].start,
list.list[i].start + list.list[i].length - 4);
}
}
diff --git a/drivers/renesas/common/console/rcar_console.S b/drivers/renesas/common/console/rcar_console.S
index 29baa67a4..b683d7bfb 100644
--- a/drivers/renesas/common/console/rcar_console.S
+++ b/drivers/renesas/common/console/rcar_console.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2018-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -63,7 +63,7 @@ endfunc console_rcar_register
* ---------------------------------------------
*/
func console_rcar_init
- mov w0, #0
+ mov w0, #1
ret
endfunc console_rcar_init
diff --git a/drivers/renesas/common/ddr/ddr_a/ddr_init_d3.c b/drivers/renesas/common/ddr/ddr_a/ddr_init_d3.c
index a49510ed5..f0113f111 100644
--- a/drivers/renesas/common/ddr/ddr_a/ddr_init_d3.c
+++ b/drivers/renesas/common/ddr/ddr_a/ddr_init_d3.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation.
+ * Copyright (c) 2015-2021, Renesas Electronics Corporation.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -11,7 +11,11 @@
#include "rcar_def.h"
#include "../ddr_regs.h"
-#define RCAR_DDR_VERSION "rev.0.01"
+#define RCAR_DDR_VERSION "rev.0.02"
+
+/* Average periodic refresh interval[ns]. Support 3900,7800 */
+#define REFRESH_RATE 3900
+
#if RCAR_LSI != RCAR_D3
#error "Don't have DDR initialize routine."
@@ -44,7 +48,7 @@ static void init_ddr_d3_1866(void)
mmio_write_32(DBSC_DBTR16, 0x09210507);
mmio_write_32(DBSC_DBTR17, 0x040E0000);
mmio_write_32(DBSC_DBTR18, 0x00000200);
- mmio_write_32(DBSC_DBTR19, 0x012B004B);
+ mmio_write_32(DBSC_DBTR19, 0x0129004B);
mmio_write_32(DBSC_DBTR20, 0x020000FB);
mmio_write_32(DBSC_DBTR21, 0x00040004);
mmio_write_32(DBSC_DBBL, 0x00000000);
@@ -54,8 +58,8 @@ static void init_ddr_d3_1866(void)
mmio_write_32(DBSC_DBDFICNT_0, 0x00000010);
mmio_write_32(DBSC_DBBCAMDIS, 0x00000001);
mmio_write_32(DBSC_DBSCHRW1, 0x00000046);
- mmio_write_32(DBSC_SCFCTST0, 0x0D020D04);
- mmio_write_32(DBSC_SCFCTST1, 0x0306040C);
+ mmio_write_32(DBSC_SCFCTST0, 0x0C050B03);
+ mmio_write_32(DBSC_SCFCTST1, 0x0305030C);
mmio_write_32(DBSC_DBPDLK_0, 0x0000A55A);
mmio_write_32(DBSC_DBCMD, 0x01000001);
@@ -101,7 +105,9 @@ static void init_ddr_d3_1866(void)
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000004);
- mmio_write_32(DBSC_DBPDRGD_0, 0x0A206F89);
+ mmio_write_32(DBSC_DBPDRGD_0,
+ (uint32_t) (REFRESH_RATE * 928 / 125) - 400
+ + 0x0A300000);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000022);
mmio_write_32(DBSC_DBPDRGD_0, 0x1000040B);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000023);
@@ -117,7 +123,11 @@ static void init_ddr_d3_1866(void)
mmio_write_32(DBSC_DBPDRGA_0, 0x00000028);
mmio_write_32(DBSC_DBPDRGD_0, 0x00000046);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000029);
- mmio_write_32(DBSC_DBPDRGD_0, 0x000000A0);
+ if (REFRESH_RATE > 3900) {
+ mmio_write_32(DBSC_DBPDRGD_0, 0x00000020);
+ } else {
+ mmio_write_32(DBSC_DBPDRGD_0, 0x000000A0);
+ }
mmio_write_32(DBSC_DBPDRGA_0, 0x0000002C);
mmio_write_32(DBSC_DBPDRGD_0, 0x81003047);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000020);
@@ -225,8 +235,10 @@ static void init_ddr_d3_1866(void)
mmio_write_32(DBSC_DBPDRGA_0, 0x000000AF);
r2 = mmio_read_32(DBSC_DBPDRGD_0);
+ mmio_write_32(DBSC_DBPDRGA_0, 0x000000AF);
mmio_write_32(DBSC_DBPDRGD_0, ((r2 + 0x1) & 0xFF) | (r2 & 0xFFFFFF00));
mmio_write_32(DBSC_DBPDRGA_0, 0x000000CF);
+ mmio_write_32(DBSC_DBPDRGA_0, 0x000000CF);
r2 = mmio_read_32(DBSC_DBPDRGD_0);
mmio_write_32(DBSC_DBPDRGD_0, ((r2 + 0x1) & 0xFF) | (r2 & 0xFFFFFF00));
@@ -296,8 +308,10 @@ static void init_ddr_d3_1866(void)
mmio_write_32(DBSC_DBPDRGD_0, 0x0024643E);
mmio_write_32(DBSC_DBBUS0CNF1, 0x00000010);
- mmio_write_32(DBSC_DBCALCNF, 0x0100401B);
- mmio_write_32(DBSC_DBRFCNF1, 0x00080E23);
+ mmio_write_32(DBSC_DBCALCNF,
+ (uint32_t) (64000000 / REFRESH_RATE) + 0x01000000);
+ mmio_write_32(DBSC_DBRFCNF1,
+ (uint32_t) (REFRESH_RATE * 116 / 125) + 0x00080000);
mmio_write_32(DBSC_DBRFCNF2, 0x00010000);
mmio_write_32(DBSC_DBDFICUPDCNF, 0x40100001);
mmio_write_32(DBSC_DBRFEN, 0x00000001);
@@ -346,6 +360,19 @@ static void init_ddr_d3_1600(void)
{
uint32_t i, r2, r3, r5, r6, r7, r12;
+ mmio_write_32(CPG_CPGWPR, 0x5A5AFFFF);
+ mmio_write_32(CPG_CPGWPCR, 0xA5A50000);
+
+ mmio_write_32(CPG_SRCR4, 0x20000000);
+
+ mmio_write_32(0xE61500DC, 0xe2200000);
+ while (!(mmio_read_32(CPG_PLLECR) & BIT(11)))
+ ;
+
+ mmio_write_32(CPG_SRSTCLR4, 0x20000000);
+
+ mmio_write_32(CPG_CPGWPCR, 0xA5A50001);
+
mmio_write_32(DBSC_DBSYSCNT0, 0x00001234);
mmio_write_32(DBSC_DBKIND, 0x00000007);
mmio_write_32(DBSC_DBMEMCONF_0_0, 0x0f030a01);
@@ -363,14 +390,14 @@ static void init_ddr_d3_1600(void)
mmio_write_32(DBSC_DBTR10, 0x0000000C);
mmio_write_32(DBSC_DBTR11, 0x0000000A);
mmio_write_32(DBSC_DBTR12, 0x00120012);
- mmio_write_32(DBSC_DBTR13, 0x000000D0);
+ mmio_write_32(DBSC_DBTR13, 0x000000CE);
mmio_write_32(DBSC_DBTR14, 0x00140005);
mmio_write_32(DBSC_DBTR15, 0x00050004);
mmio_write_32(DBSC_DBTR16, 0x071F0305);
mmio_write_32(DBSC_DBTR17, 0x040C0000);
mmio_write_32(DBSC_DBTR18, 0x00000200);
mmio_write_32(DBSC_DBTR19, 0x01000040);
- mmio_write_32(DBSC_DBTR20, 0x020000D8);
+ mmio_write_32(DBSC_DBTR20, 0x020000D6);
mmio_write_32(DBSC_DBTR21, 0x00040004);
mmio_write_32(DBSC_DBBL, 0x00000000);
mmio_write_32(DBSC_DBODT0, 0x00000001);
@@ -379,8 +406,8 @@ static void init_ddr_d3_1600(void)
mmio_write_32(DBSC_DBDFICNT_0, 0x00000010);
mmio_write_32(DBSC_DBBCAMDIS, 0x00000001);
mmio_write_32(DBSC_DBSCHRW1, 0x00000046);
- mmio_write_32(DBSC_SCFCTST0, 0x0D020C04);
- mmio_write_32(DBSC_SCFCTST1, 0x0305040C);
+ mmio_write_32(DBSC_SCFCTST0, 0x0D050B03);
+ mmio_write_32(DBSC_SCFCTST1, 0x0306030C);
mmio_write_32(DBSC_DBPDLK_0, 0x0000A55A);
mmio_write_32(DBSC_DBCMD, 0x01000001);
@@ -426,13 +453,14 @@ static void init_ddr_d3_1600(void)
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000004);
- mmio_write_32(DBSC_DBPDRGD_0, 0x08C05FF0);
+ mmio_write_32(DBSC_DBPDRGD_0,
+ (uint32_t) (REFRESH_RATE * 792 / 125) - 400 + 0x08B00000);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000022);
mmio_write_32(DBSC_DBPDRGD_0, 0x1000040B);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000023);
mmio_write_32(DBSC_DBPDRGD_0, 0x2D9C0B66);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000024);
- mmio_write_32(DBSC_DBPDRGD_0, 0x2A88C400);
+ mmio_write_32(DBSC_DBPDRGD_0, 0x2A88B400);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000025);
mmio_write_32(DBSC_DBPDRGD_0, 0x30005200);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000026);
@@ -442,7 +470,11 @@ static void init_ddr_d3_1600(void)
mmio_write_32(DBSC_DBPDRGA_0, 0x00000028);
mmio_write_32(DBSC_DBPDRGD_0, 0x00000046);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000029);
- mmio_write_32(DBSC_DBPDRGD_0, 0x00000098);
+ if (REFRESH_RATE > 3900) {
+ mmio_write_32(DBSC_DBPDRGD_0, 0x00000018);
+ } else {
+ mmio_write_32(DBSC_DBPDRGD_0, 0x00000098);
+ }
mmio_write_32(DBSC_DBPDRGA_0, 0x0000002C);
mmio_write_32(DBSC_DBPDRGD_0, 0x81003047);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000020);
@@ -549,9 +581,11 @@ static void init_ddr_d3_1600(void)
mmio_write_32(DBSC_DBPDRGA_0, 0x000000AF);
r2 = mmio_read_32(DBSC_DBPDRGD_0);
+ mmio_write_32(DBSC_DBPDRGA_0, 0x000000AF);
mmio_write_32(DBSC_DBPDRGD_0, ((r2 + 0x1) & 0xFF) | (r2 & 0xFFFFFF00));
mmio_write_32(DBSC_DBPDRGA_0, 0x000000CF);
r2 = mmio_read_32(DBSC_DBPDRGD_0);
+ mmio_write_32(DBSC_DBPDRGA_0, 0x000000CF);
mmio_write_32(DBSC_DBPDRGD_0, ((r2 + 0x1) & 0xFF) | (r2 & 0xFFFFFF00));
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A0);
@@ -620,8 +654,10 @@ static void init_ddr_d3_1600(void)
mmio_write_32(DBSC_DBPDRGD_0, 0x0024643E);
mmio_write_32(DBSC_DBBUS0CNF1, 0x00000010);
- mmio_write_32(DBSC_DBCALCNF, 0x0100401B);
- mmio_write_32(DBSC_DBRFCNF1, 0x00080C30);
+ mmio_write_32(DBSC_DBCALCNF,
+ (uint32_t) (64000000 / REFRESH_RATE) + 0x01000000);
+ mmio_write_32(DBSC_DBRFCNF1,
+ (uint32_t) (REFRESH_RATE * 99 / 125) + 0x00080000);
mmio_write_32(DBSC_DBRFCNF2, 0x00010000);
mmio_write_32(DBSC_DBDFICUPDCNF, 0x40100001);
mmio_write_32(DBSC_DBRFEN, 0x00000001);
@@ -693,7 +729,7 @@ int32_t rcar_dram_init(void)
ddr_mbps = 1600;
}
- NOTICE("BL2: DDR%d\n", ddr_mbps);
+ NOTICE("BL2: DDR%d(%s)\n", ddr_mbps, RCAR_DDR_VERSION);
return 0;
}
diff --git a/drivers/renesas/common/io/io_rcar.c b/drivers/renesas/common/io/io_rcar.c
index c3e8319de..45ef386ae 100644
--- a/drivers/renesas/common/io/io_rcar.c
+++ b/drivers/renesas/common/io/io_rcar.c
@@ -151,6 +151,9 @@ int32_t rcar_get_certificate(const int32_t name, uint32_t *cert)
return -EINVAL;
}
+#define MFISBTSTSR (0xE6260604U)
+#define MFISBTSTSR_BOOT_PARTITION (0x00000010U)
+
static int32_t file_to_offset(const int32_t name, uintptr_t *offset,
uint32_t *cert, uint32_t *no_load,
uintptr_t *partition)
@@ -169,6 +172,9 @@ static int32_t file_to_offset(const int32_t name, uintptr_t *offset,
}
*offset = rcar_image_header[addr];
+
+ if (mmio_read_32(MFISBTSTSR) & MFISBTSTSR_BOOT_PARTITION)
+ *offset += 0x800000;
*cert = RCAR_CERT_SIZE;
*cert *= RCAR_ATTR_GET_CERTOFF(name_offset[i].attr);
*cert += RCAR_SDRAM_certESS;
@@ -374,7 +380,7 @@ static int32_t load_bl33x(void)
static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name)
{
- uint64_t header[64] __aligned(FLASH_TRANS_SIZE_UNIT) = {0UL};
+ static uint64_t header[64] __aligned(FLASH_TRANS_SIZE_UNIT) = {0UL};
uintptr_t handle;
ssize_t offset;
uint32_t i;
@@ -417,15 +423,17 @@ static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name)
WARN("Firmware Image Package header failed to seek\n");
goto error;
}
-#if RCAR_BL2_DCACHE == 1
- inv_dcache_range((uint64_t) header, sizeof(header));
-#endif
+
rc = io_read(handle, (uintptr_t) &header, sizeof(header), &cnt);
if (rc != IO_SUCCESS) {
WARN("Firmware Image Package header failed to read\n");
goto error;
}
+#if RCAR_BL2_DCACHE == 1
+ inv_dcache_range((uint64_t) header, sizeof(header));
+#endif
+
rcar_image_number = header[0];
for (i = 0; i < rcar_image_number + 2; i++) {
rcar_image_header[i] = header[i * 2 + 1];
@@ -434,6 +442,7 @@ static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name)
if (rcar_image_number == 0 || rcar_image_number > RCAR_MAX_BL3X_IMAGE) {
WARN("Firmware Image Package header check failed.\n");
+ rc = IO_FAIL;
goto error;
}
@@ -442,10 +451,7 @@ static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name)
WARN("Firmware Image Package header failed to seek cert\n");
goto error;
}
-#if RCAR_BL2_DCACHE == 1
- inv_dcache_range(RCAR_SDRAM_certESS,
- RCAR_CERT_SIZE * (2 + rcar_image_number));
-#endif
+
rc = io_read(handle, RCAR_SDRAM_certESS,
RCAR_CERT_SIZE * (2 + rcar_image_number), &cnt);
if (rc != IO_SUCCESS) {
@@ -453,6 +459,11 @@ static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name)
goto error;
}
+#if RCAR_BL2_DCACHE == 1
+ inv_dcache_range(RCAR_SDRAM_certESS,
+ RCAR_CERT_SIZE * (2 + rcar_image_number));
+#endif
+
rcar_cert_load = RCAR_CERT_LOAD;
error:
diff --git a/drivers/renesas/common/pwrc/pwrc.c b/drivers/renesas/common/pwrc/pwrc.c
index 3f60fe633..4e175eb97 100644
--- a/drivers/renesas/common/pwrc/pwrc.c
+++ b/drivers/renesas/common/pwrc/pwrc.c
@@ -44,6 +44,7 @@ RCAR_INSTANTIATE_LOCK
#define CPU_PWR_OFF (0x00000003U)
#define RCAR_PSTR_MASK (0x00000003U)
#define ST_ALL_STANDBY (0x00003333U)
+#define SYSCEXTMASK_EXTMSK0 (0x00000001U)
/* Suspend to ram */
#define DBSC4_REG_BASE (0xE6790000U)
#define DBSC4_REG_DBSYSCNT0 (DBSC4_REG_BASE + 0x0100U)
@@ -191,6 +192,8 @@ static void scu_power_up(uint64_t mpidr)
{
uintptr_t reg_pwrsr, reg_cpumcr, reg_pwron, reg_pwrer;
uint32_t c, sysc_reg_bit;
+ uint32_t lsi_product;
+ uint32_t lsi_cut;
c = rcar_pwrc_get_mpidr_cluster(mpidr);
reg_cpumcr = IS_CA57(c) ? RCAR_CA57CPUCMCR : RCAR_CA53CPUCMCR;
@@ -205,6 +208,17 @@ static void scu_power_up(uint64_t mpidr)
if (mmio_read_32(reg_cpumcr) != 0)
mmio_write_32(reg_cpumcr, 0);
+ lsi_product = mmio_read_32((uintptr_t)RCAR_PRR);
+ lsi_cut = lsi_product & PRR_CUT_MASK;
+ lsi_product &= PRR_PRODUCT_MASK;
+
+ if ((lsi_product == PRR_PRODUCT_M3 && lsi_cut >= PRR_PRODUCT_30) ||
+ lsi_product == PRR_PRODUCT_H3 ||
+ lsi_product == PRR_PRODUCT_M3N ||
+ lsi_product == PRR_PRODUCT_E3) {
+ mmio_setbits_32(RCAR_SYSCEXTMASK, SYSCEXTMASK_EXTMSK0);
+ }
+
mmio_setbits_32(RCAR_SYSCIER, sysc_reg_bit);
mmio_setbits_32(RCAR_SYSCIMR, sysc_reg_bit);
@@ -216,7 +230,15 @@ static void scu_power_up(uint64_t mpidr)
while ((mmio_read_32(RCAR_SYSCISR) & sysc_reg_bit) == 0)
;
- mmio_write_32(RCAR_SYSCISR, sysc_reg_bit);
+ mmio_write_32(RCAR_SYSCISCR, sysc_reg_bit);
+
+ if ((lsi_product == PRR_PRODUCT_M3 && lsi_cut >= PRR_PRODUCT_30) ||
+ lsi_product == PRR_PRODUCT_H3 ||
+ lsi_product == PRR_PRODUCT_M3N ||
+ lsi_product == PRR_PRODUCT_E3) {
+ mmio_clrbits_32(RCAR_SYSCEXTMASK, SYSCEXTMASK_EXTMSK0);
+ }
+
while ((mmio_read_32(reg_pwrsr) & STATUS_PWRUP) == 0)
;
}
@@ -754,14 +776,14 @@ void rcar_pwrc_code_copy_to_system_ram(void)
memcpy((void *)sram.base, code.base, code.len);
flush_dcache_range((uint64_t) sram.base, code.len);
+ attr = MT_MEMORY | MT_RO | MT_SECURE | MT_EXECUTE;
+ ret = xlat_change_mem_attributes(sram.base, sram.len, attr);
+ assert(ret == 0);
+
/* Invalidate instruction cache */
plat_invalidate_icache();
dsb();
isb();
-
- attr = MT_MEMORY | MT_RO | MT_SECURE | MT_EXECUTE;
- ret = xlat_change_mem_attributes(sram.base, sram.len, attr);
- assert(ret == 0);
}
uint32_t rcar_pwrc_get_cluster(void)
diff --git a/drivers/renesas/common/scif/scif.S b/drivers/renesas/common/scif/scif.S
index beb8dd838..72b5b4bea 100644
--- a/drivers/renesas/common/scif/scif.S
+++ b/drivers/renesas/common/scif/scif.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -79,7 +79,7 @@
SCSMR_STOP_1 + \
SCSMR_CKS_DIV1)
#define SCBRR_115200BPS (17)
-#define SCBRR_115200BPSON (16)
+#define SCBRR_115200BPS_D3_SSCG (16)
#define SCBRR_115200BPS_E3_SSCG (15)
#define SCBRR_230400BPS (8)
@@ -216,26 +216,38 @@ func console_rcar_init
and w1, w1, #PRR_PRODUCT_MASK
mov w2, #PRR_PRODUCT_D3
cmp w1, w2
- beq 4f
+ beq 5f
and w1, w1, #PRR_PRODUCT_MASK
mov w2, #PRR_PRODUCT_E3
cmp w1, w2
- bne 5f
+ bne 4f
+ /* When SSCG(MD12) on (E3) */
ldr x1, =RST_MODEMR
ldr w1, [x1]
and w1, w1, #MODEMR_MD12
mov w2, #MODEMR_MD12
cmp w1, w2
- bne 5f
+ bne 4f
+ /* When SSCG(MD12) on (E3) */
mov w1, #SCBRR_115200BPS_E3_SSCG
b 2f
5:
- mov w1, #SCBRR_115200BPS
+ /* In case of D3 */
+ ldr x1, =RST_MODEMR
+ ldr w1, [x1]
+ and w1, w1, #MODEMR_MD12
+ mov w2, #MODEMR_MD12
+ cmp w1, w2
+ bne 4f
+
+ /* When SSCG(MD12) on (D3) */
+ mov w1, #SCBRR_115200BPS_D3_SSCG
b 2f
4:
- mov w1, #SCBRR_115200BPSON
+ /* In case of H3/M3/M3N or when SSCG(MD12) is off in E3/D3 */
+ mov w1, #SCBRR_115200BPS
b 2f
3:
mov w1, #SCBRR_230400BPS
diff --git a/drivers/renesas/common/watchdog/swdt.c b/drivers/renesas/common/watchdog/swdt.c
index 1a351ca17..29ef6f430 100644
--- a/drivers/renesas/common/watchdog/swdt.c
+++ b/drivers/renesas/common/watchdog/swdt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -78,7 +78,7 @@ static void swdt_disable(void)
void rcar_swdt_init(void)
{
uint32_t rmsk, sr;
-#if (RCAR_LSI != RCAR_E3) && (RCAR_LSI != RZ_G2E)
+#if (RCAR_LSI != RCAR_E3) && (RCAR_LSI != RCAR_D3) && (RCAR_LSI != RZ_G2E)
uint32_t reg, val, product_cut, chk_data;
reg = mmio_read_32(RCAR_PRR);
@@ -96,6 +96,8 @@ void rcar_swdt_init(void)
#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RZ_G2E)
mmio_write_32(SWDT_WTCNT, WTCNT_UPPER_BYTE | WTCNT_COUNT_7p81k);
+#elif (RCAR_LSI == RCAR_D3)
+ mmio_write_32(SWDT_WTCNT, WTCNT_UPPER_BYTE | WTCNT_COUNT_8p13k);
#else
val = WTCNT_UPPER_BYTE;
diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c
index 6ada96a52..3ebc376cd 100644
--- a/drivers/st/clk/stm32mp1_clk.c
+++ b/drivers/st/clk/stm32mp1_clk.c
@@ -56,6 +56,7 @@ enum stm32mp1_parent_id {
_HSI_KER = NB_OSC,
_HSE_KER,
_HSE_KER_DIV2,
+ _HSE_RTC,
_CSI_KER,
_PLL1_P,
_PLL1_Q,
@@ -107,7 +108,7 @@ enum stm32mp1_parent_sel {
_USBPHY_SEL,
_USBO_SEL,
_MPU_SEL,
- _PER_SEL,
+ _CKPER_SEL,
_RTC_SEL,
_PARENT_SEL_NB,
_UNKNOWN_SEL = 0xff,
@@ -125,6 +126,7 @@ static const uint8_t parent_id_clock_id[_PARENT_NB] = {
[_HSI_KER] = CK_HSI,
[_HSE_KER] = CK_HSE,
[_HSE_KER_DIV2] = CK_HSE_DIV2,
+ [_HSE_RTC] = _UNKNOWN_ID,
[_CSI_KER] = CK_CSI,
[_PLL1_P] = PLL1_P,
[_PLL1_Q] = PLL1_Q,
@@ -465,12 +467,12 @@ static const uint8_t fmc_parents[] = {
_ACLK, _PLL3_R, _PLL4_P, _CK_PER
};
-static const uint8_t ass_parents[] = {
- _HSI, _HSE, _PLL2
+static const uint8_t axiss_parents[] = {
+ _HSI, _HSE, _PLL2_P
};
-static const uint8_t mss_parents[] = {
- _HSI, _HSE, _CSI, _PLL3
+static const uint8_t mcuss_parents[] = {
+ _HSI, _HSE, _CSI, _PLL3_P
};
static const uint8_t usbphy_parents[] = {
@@ -490,7 +492,7 @@ static const uint8_t per_parents[] = {
};
static const uint8_t rtc_parents[] = {
- _UNKNOWN_ID, _LSE, _LSI, _HSE
+ _UNKNOWN_ID, _LSE, _LSI, _HSE_RTC
};
static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = {
@@ -502,7 +504,7 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = {
_CLK_PARENT_SEL(UART1, RCC_UART1CKSELR, usart1_parents),
_CLK_PARENT_SEL(RNG1, RCC_RNG1CKSELR, rng1_parents),
_CLK_PARENT_SEL(MPU, RCC_MPCKSELR, mpu_parents),
- _CLK_PARENT_SEL(PER, RCC_CPERCKSELR, per_parents),
+ _CLK_PARENT_SEL(CKPER, RCC_CPERCKSELR, per_parents),
_CLK_PARENT_SEL(RTC, RCC_BDCR, rtc_parents),
_CLK_PARENT_SEL(UART6, RCC_UART6CKSELR, uart6_parents),
_CLK_PARENT_SEL(UART24, RCC_UART24CKSELR, uart234578_parents),
@@ -512,8 +514,8 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = {
_CLK_PARENT_SEL(SDMMC3, RCC_SDMMC3CKSELR, sdmmc3_parents),
_CLK_PARENT_SEL(QSPI, RCC_QSPICKSELR, qspi_parents),
_CLK_PARENT_SEL(FMC, RCC_FMCCKSELR, fmc_parents),
- _CLK_PARENT_SEL(AXIS, RCC_ASSCKSELR, ass_parents),
- _CLK_PARENT_SEL(MCUS, RCC_MSSCKSELR, mss_parents),
+ _CLK_PARENT_SEL(AXIS, RCC_ASSCKSELR, axiss_parents),
+ _CLK_PARENT_SEL(MCUS, RCC_MSSCKSELR, mcuss_parents),
_CLK_PARENT_SEL(USBPHY, RCC_USBCKSELR, usbphy_parents),
_CLK_PARENT_SEL(USBO, RCC_USBCKSELR, usbo_parents),
};
@@ -587,6 +589,7 @@ static const char * const stm32mp1_clk_parent_name[_PARENT_NB] __unused = {
[_HSI_KER] = "HSI_KER",
[_HSE_KER] = "HSE_KER",
[_HSE_KER_DIV2] = "HSE_KER_DIV2",
+ [_HSE_RTC] = "HSE_RTC",
[_CSI_KER] = "CSI_KER",
[_PLL1_P] = "PLL1_P",
[_PLL1_Q] = "PLL1_Q",
@@ -847,9 +850,7 @@ static unsigned long get_clock_rate(int p)
reg = mmio_read_32(rcc_base + RCC_MPCKDIVR);
clkdiv = reg & RCC_MPUDIV_MASK;
- if (clkdiv != 0U) {
- clock /= stm32mp1_mpu_div[clkdiv];
- }
+ clock >>= stm32mp1_mpu_div[clkdiv];
break;
default:
break;
@@ -969,6 +970,10 @@ static unsigned long get_clock_rate(int p)
case _HSE_KER_DIV2:
clock = stm32mp1_clk_get_fixed(_HSE) >> 1;
break;
+ case _HSE_RTC:
+ clock = stm32mp1_clk_get_fixed(_HSE);
+ clock /= (mmio_read_32(rcc_base + RCC_RTCDIVR) & RCC_DIVR_DIV_MASK) + 1U;
+ break;
case _LSI:
clock = stm32mp1_clk_get_fixed(_LSI);
break;
@@ -1086,6 +1091,10 @@ static bool clock_is_always_on(unsigned long id)
case PLL3_P:
case PLL3_Q:
case PLL3_R:
+ case CK_AXI:
+ case CK_MPU:
+ case CK_MCU:
+ case RTC:
return true;
default:
return false;
@@ -1652,7 +1661,7 @@ static void stm32mp1_set_rtcsrc(unsigned int clksrc, bool lse_css)
(clksrc != (uint32_t)CLK_RTC_DISABLED)) {
mmio_clrsetbits_32(address,
RCC_BDCR_RTCSRC_MASK,
- clksrc << RCC_BDCR_RTCSRC_SHIFT);
+ (clksrc & RCC_SELR_SRC_MASK) << RCC_BDCR_RTCSRC_SHIFT);
mmio_setbits_32(address, RCC_BDCR_RTCCKEN);
}
@@ -2152,6 +2161,7 @@ static void secure_parent_clocks(unsigned long parent_id)
case _HSE:
case _HSE_KER:
case _HSE_KER_DIV2:
+ case _HSE_RTC:
case _LSE:
break;
@@ -2210,6 +2220,7 @@ static void sync_earlyboot_clocks_state(void)
DDRC2, DDRC2LP,
DDRCAPB, DDRPHYCAPB, DDRPHYCAPBLP,
DDRPHYC, DDRPHYCLP,
+ RTCAPB,
TZC1, TZC2,
TZPC,
STGEN_K,
@@ -2218,10 +2229,6 @@ static void sync_earlyboot_clocks_state(void)
for (idx = 0U; idx < ARRAY_SIZE(secure_enable); idx++) {
stm32mp_clk_enable(secure_enable[idx]);
}
-
- if (!stm32mp_is_single_core()) {
- stm32mp1_clk_enable_secure(RTCAPB);
- }
}
int stm32mp1_clk_probe(void)
diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c
index 8333f6dfb..d57f120b9 100644
--- a/drivers/st/clk/stm32mp_clkfunc.c
+++ b/drivers/st/clk/stm32mp_clkfunc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -161,9 +161,15 @@ uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id,
* @param fdt: Device tree reference
* @return: Node offset or a negative value on error
*/
-int fdt_get_rcc_node(void *fdt)
+static int fdt_get_rcc_node(void *fdt)
{
- return fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+ static int node;
+
+ if (node <= 0) {
+ node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+ }
+
+ return node;
}
/*
diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c
index cff3a344f..d3adeab13 100644
--- a/drivers/st/mmc/stm32_sdmmc2.c
+++ b/drivers/st/mmc/stm32_sdmmc2.c
@@ -628,6 +628,7 @@ static int stm32_sdmmc2_dt_get_config(void)
int sdmmc_node;
void *fdt = NULL;
const fdt32_t *cuint;
+ struct dt_node_info dt_info;
if (fdt_get_address(&fdt) == 0) {
return -FDT_ERR_NOTFOUND;
@@ -637,27 +638,14 @@ static int stm32_sdmmc2_dt_get_config(void)
return -FDT_ERR_NOTFOUND;
}
- sdmmc_node = fdt_node_offset_by_compatible(fdt, -1, DT_SDMMC2_COMPAT);
-
- while (sdmmc_node != -FDT_ERR_NOTFOUND) {
- cuint = fdt_getprop(fdt, sdmmc_node, "reg", NULL);
- if (cuint == NULL) {
- continue;
- }
-
- if (fdt32_to_cpu(*cuint) == sdmmc2_params.reg_base) {
- break;
- }
-
- sdmmc_node = fdt_node_offset_by_compatible(fdt, sdmmc_node,
- DT_SDMMC2_COMPAT);
- }
-
+ sdmmc_node = dt_match_instance_by_compatible(DT_SDMMC2_COMPAT,
+ sdmmc2_params.reg_base);
if (sdmmc_node == -FDT_ERR_NOTFOUND) {
return -FDT_ERR_NOTFOUND;
}
- if (fdt_get_status(sdmmc_node) == DT_DISABLED) {
+ dt_fill_device_info(&dt_info, sdmmc_node);
+ if (dt_info.status == DT_DISABLED) {
return -FDT_ERR_NOTFOUND;
}
@@ -665,21 +653,8 @@ static int stm32_sdmmc2_dt_get_config(void)
return -FDT_ERR_BADVALUE;
}
- cuint = fdt_getprop(fdt, sdmmc_node, "clocks", NULL);
- if (cuint == NULL) {
- return -FDT_ERR_NOTFOUND;
- }
-
- cuint++;
- sdmmc2_params.clock_id = fdt32_to_cpu(*cuint);
-
- cuint = fdt_getprop(fdt, sdmmc_node, "resets", NULL);
- if (cuint == NULL) {
- return -FDT_ERR_NOTFOUND;
- }
-
- cuint++;
- sdmmc2_params.reset_id = fdt32_to_cpu(*cuint);
+ sdmmc2_params.clock_id = dt_info.clock;
+ sdmmc2_params.reset_id = dt_info.reset;
if ((fdt_getprop(fdt, sdmmc_node, "st,use-ckin", NULL)) != NULL) {
sdmmc2_params.pin_ckin = SDMMC_CLKCR_SELCLKRX_0;
diff --git a/drivers/st/pmic/stpmic1.c b/drivers/st/pmic/stpmic1.c
index 999963054..0a35df372 100644
--- a/drivers/st/pmic/stpmic1.c
+++ b/drivers/st/pmic/stpmic1.c
@@ -1,9 +1,10 @@
/*
- * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2021, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <errno.h>
#include <string.h>
#include <common/debug.h>
@@ -16,6 +17,7 @@ struct regul_struct {
const uint16_t *voltage_table;
uint8_t voltage_table_size;
uint8_t control_reg;
+ uint8_t enable_mask;
uint8_t low_power_reg;
uint8_t pull_down_reg;
uint8_t pull_down;
@@ -426,6 +428,7 @@ static const struct regul_struct regulators_table[] = {
.voltage_table = buck1_voltage_table,
.voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
.control_reg = BUCK1_CONTROL_REG,
+ .enable_mask = LDO_BUCK_ENABLE_MASK,
.low_power_reg = BUCK1_PWRCTRL_REG,
.pull_down_reg = BUCK_PULL_DOWN_REG,
.pull_down = BUCK1_PULL_DOWN_SHIFT,
@@ -437,6 +440,7 @@ static const struct regul_struct regulators_table[] = {
.voltage_table = buck2_voltage_table,
.voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
.control_reg = BUCK2_CONTROL_REG,
+ .enable_mask = LDO_BUCK_ENABLE_MASK,
.low_power_reg = BUCK2_PWRCTRL_REG,
.pull_down_reg = BUCK_PULL_DOWN_REG,
.pull_down = BUCK2_PULL_DOWN_SHIFT,
@@ -448,6 +452,7 @@ static const struct regul_struct regulators_table[] = {
.voltage_table = buck3_voltage_table,
.voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
.control_reg = BUCK3_CONTROL_REG,
+ .enable_mask = LDO_BUCK_ENABLE_MASK,
.low_power_reg = BUCK3_PWRCTRL_REG,
.pull_down_reg = BUCK_PULL_DOWN_REG,
.pull_down = BUCK3_PULL_DOWN_SHIFT,
@@ -459,6 +464,7 @@ static const struct regul_struct regulators_table[] = {
.voltage_table = buck4_voltage_table,
.voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
.control_reg = BUCK4_CONTROL_REG,
+ .enable_mask = LDO_BUCK_ENABLE_MASK,
.low_power_reg = BUCK4_PWRCTRL_REG,
.pull_down_reg = BUCK_PULL_DOWN_REG,
.pull_down = BUCK4_PULL_DOWN_SHIFT,
@@ -470,6 +476,7 @@ static const struct regul_struct regulators_table[] = {
.voltage_table = ldo1_voltage_table,
.voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
.control_reg = LDO1_CONTROL_REG,
+ .enable_mask = LDO_BUCK_ENABLE_MASK,
.low_power_reg = LDO1_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = LDO1_MASK_RESET,
@@ -479,6 +486,7 @@ static const struct regul_struct regulators_table[] = {
.voltage_table = ldo2_voltage_table,
.voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
.control_reg = LDO2_CONTROL_REG,
+ .enable_mask = LDO_BUCK_ENABLE_MASK,
.low_power_reg = LDO2_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = LDO2_MASK_RESET,
@@ -488,6 +496,7 @@ static const struct regul_struct regulators_table[] = {
.voltage_table = ldo3_voltage_table,
.voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
.control_reg = LDO3_CONTROL_REG,
+ .enable_mask = LDO_BUCK_ENABLE_MASK,
.low_power_reg = LDO3_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = LDO3_MASK_RESET,
@@ -497,6 +506,7 @@ static const struct regul_struct regulators_table[] = {
.voltage_table = ldo4_voltage_table,
.voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
.control_reg = LDO4_CONTROL_REG,
+ .enable_mask = LDO_BUCK_ENABLE_MASK,
.low_power_reg = LDO4_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = LDO4_MASK_RESET,
@@ -506,6 +516,7 @@ static const struct regul_struct regulators_table[] = {
.voltage_table = ldo5_voltage_table,
.voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
.control_reg = LDO5_CONTROL_REG,
+ .enable_mask = LDO_BUCK_ENABLE_MASK,
.low_power_reg = LDO5_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = LDO5_MASK_RESET,
@@ -515,6 +526,7 @@ static const struct regul_struct regulators_table[] = {
.voltage_table = ldo6_voltage_table,
.voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
.control_reg = LDO6_CONTROL_REG,
+ .enable_mask = LDO_BUCK_ENABLE_MASK,
.low_power_reg = LDO6_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = LDO6_MASK_RESET,
@@ -524,6 +536,7 @@ static const struct regul_struct regulators_table[] = {
.voltage_table = vref_ddr_voltage_table,
.voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
.control_reg = VREF_DDR_CONTROL_REG,
+ .enable_mask = LDO_BUCK_ENABLE_MASK,
.low_power_reg = VREF_DDR_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = VREF_DDR_MASK_RESET,
@@ -581,14 +594,16 @@ int stpmic1_regulator_enable(const char *name)
{
const struct regul_struct *regul = get_regulator_data(name);
- return stpmic1_register_update(regul->control_reg, BIT(0), BIT(0));
+ return stpmic1_register_update(regul->control_reg, regul->enable_mask,
+ regul->enable_mask);
}
int stpmic1_regulator_disable(const char *name)
{
const struct regul_struct *regul = get_regulator_data(name);
- return stpmic1_register_update(regul->control_reg, 0, BIT(0));
+ return stpmic1_register_update(regul->control_reg, 0,
+ regul->enable_mask);
}
uint8_t stpmic1_is_regulator_enabled(const char *name)
@@ -600,7 +615,7 @@ uint8_t stpmic1_is_regulator_enabled(const char *name)
panic();
}
- return (val & 0x1U);
+ return (val & regul->enable_mask);
}
int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
@@ -653,6 +668,7 @@ int stpmic1_regulator_voltage_get(const char *name)
const struct regul_struct *regul = get_regulator_data(name);
uint8_t value;
uint8_t mask;
+ int status;
/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
if (strncmp(name, "buck", 4) == 0) {
@@ -664,13 +680,16 @@ int stpmic1_regulator_voltage_get(const char *name)
return 0;
}
- if (stpmic1_register_read(regul->control_reg, &value))
- return -1;
+ status = stpmic1_register_read(regul->control_reg, &value);
+ if (status < 0) {
+ return status;
+ }
value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
- if (value > regul->voltage_table_size)
- return -1;
+ if (value > regul->voltage_table_size) {
+ return -ERANGE;
+ }
return (int)regul->voltage_table[value];
}
@@ -706,7 +725,7 @@ int stpmic1_register_write(uint8_t register_id, uint8_t value)
}
if (readval != value) {
- return -1;
+ return -EIO;
}
}
#endif
@@ -751,12 +770,12 @@ void stpmic1_dump_regulators(void)
int stpmic1_get_version(unsigned long *version)
{
- int rc;
uint8_t read_val;
+ int status;
- rc = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
- if (rc) {
- return -1;
+ status = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
+ if (status < 0) {
+ return status;
}
*version = (unsigned long)read_val;
diff --git a/drivers/st/spi/stm32_qspi.c b/drivers/st/spi/stm32_qspi.c
index d67f8313f..4b1a0296c 100644
--- a/drivers/st/spi/stm32_qspi.c
+++ b/drivers/st/spi/stm32_qspi.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
+#include <inttypes.h>
#include <libfdt.h>
#include <platform_def.h>
@@ -244,7 +245,7 @@ static int stm32_qspi_exec_op(const struct spi_mem_op *op)
uint8_t mode = QSPI_CCR_IND_WRITE;
int ret;
- VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addr:%llx len:%x\n",
+ VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addr:%" PRIx64 " len:%x\n",
__func__, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
op->dummy.buswidth, op->data.buswidth,
op->addr.val, op->data.nbytes);
diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S
index 686b18b96..2b8879a11 100644
--- a/drivers/st/uart/aarch32/stm32_console.S
+++ b/drivers/st/uart/aarch32/stm32_console.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -45,7 +45,12 @@ func console_stm32_core_init
/* Check the input base address */
cmp r0, #0
beq core_init_fail
-#if defined(IMAGE_BL2)
+#if !defined(IMAGE_BL2)
+ /* Skip UART initialization if it is already enabled */
+ ldr r3, [r0, #USART_CR1]
+ ands r3, r3, #USART_CR1_UE
+ bne 1f
+#endif /* IMAGE_BL2 */
/* Check baud rate and uart clock for sanity */
cmp r1, #0
beq core_init_fail
@@ -78,7 +83,7 @@ teack_loop:
ldr r3, [r0, #USART_ISR]
tst r3, #USART_ISR_TEACK
beq teack_loop
-#endif /* IMAGE_BL2 */
+1:
mov r0, #1
bx lr
core_init_fail:
diff --git a/drivers/st/usb/stm32mp1_usb.c b/drivers/st/usb/stm32mp1_usb.c
new file mode 100644
index 000000000..9a4969036
--- /dev/null
+++ b/drivers/st/usb/stm32mp1_usb.c
@@ -0,0 +1,1091 @@
+/*
+ * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/st/stm32mp1_usb.h>
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+#define USB_OTG_MODE_DEVICE 0U
+#define USB_OTG_MODE_HOST 1U
+#define USB_OTG_MODE_DRD 2U
+
+#define EP_TYPE_CTRL 0U
+#define EP_TYPE_ISOC 1U
+#define EP_TYPE_BULK 2U
+#define EP_TYPE_INTR 3U
+
+#define USBD_FIFO_FLUSH_TIMEOUT_US 1000U
+#define EP0_FIFO_SIZE 64U
+
+/* OTG registers offsets */
+#define OTG_GOTGINT 0x004U
+#define OTG_GAHBCFG 0x008U
+#define OTG_GUSBCFG 0x00CU
+#define OTG_GRSTCTL 0x010U
+#define OTG_GINTSTS 0x014U
+#define OTG_GINTMSK 0x018U
+#define OTG_GRXSTSP 0x020U
+#define OTG_GLPMCFG 0x054U
+#define OTG_DCFG 0x800U
+#define OTG_DCTL 0x804U
+#define OTG_DSTS 0x808U
+#define OTG_DIEPMSK 0x810U
+#define OTG_DOEPMSK 0x814U
+#define OTG_DAINT 0x818U
+#define OTG_DAINTMSK 0x81CU
+#define OTG_DIEPEMPMSK 0x834U
+
+/* Definitions for OTG_DIEPx registers */
+#define OTG_DIEP_BASE 0x900U
+#define OTG_DIEP_SIZE 0x20U
+#define OTG_DIEPCTL 0x00U
+#define OTG_DIEPINT 0x08U
+#define OTG_DIEPTSIZ 0x10U
+#define OTG_DIEPDMA 0x14U
+#define OTG_DTXFSTS 0x18U
+#define OTG_DIEP_MAX_NB 9U
+
+/* Definitions for OTG_DOEPx registers */
+#define OTG_DOEP_BASE 0xB00U
+#define OTG_DOEP_SIZE 0x20U
+#define OTG_DOEPCTL 0x00U
+#define OTG_DOEPINT 0x08U
+#define OTG_DOEPTSIZ 0x10U
+#define OTG_DOEPDMA 0x14U
+#define OTG_D0EP_MAX_NB 9U
+
+/* Definitions for OTG_DAINT registers */
+#define OTG_DAINT_OUT_MASK GENMASK(31, 16)
+#define OTG_DAINT_OUT_SHIFT 16U
+#define OTG_DAINT_IN_MASK GENMASK(15, 0)
+#define OTG_DAINT_IN_SHIFT 0U
+
+#define OTG_DAINT_EP0_IN BIT(16)
+#define OTG_DAINT_EP0_OUT BIT(0)
+
+/* Definitions for FIFOs */
+#define OTG_FIFO_BASE 0x1000U
+#define OTG_FIFO_SIZE 0x1000U
+
+/* Bit definitions for OTG_GOTGINT register */
+#define OTG_GOTGINT_SEDET BIT(2)
+
+/* Bit definitions for OTG_GAHBCFG register */
+#define OTG_GAHBCFG_GINT BIT(0)
+
+/* Bit definitions for OTG_GUSBCFG register */
+#define OTG_GUSBCFG_TRDT GENMASK(13, 10)
+#define OTG_GUSBCFG_TRDT_SHIFT 10U
+
+#define USBD_HS_TRDT_VALUE 9U
+
+/* Bit definitions for OTG_GRSTCTL register */
+#define OTG_GRSTCTL_RXFFLSH BIT(4)
+#define OTG_GRSTCTL_TXFFLSH BIT(5)
+#define OTG_GRSTCTL_TXFNUM_SHIFT 6U
+
+/* Bit definitions for OTG_GINTSTS register */
+#define OTG_GINTSTS_CMOD BIT(0)
+#define OTG_GINTSTS_MMIS BIT(1)
+#define OTG_GINTSTS_OTGINT BIT(2)
+#define OTG_GINTSTS_SOF BIT(3)
+#define OTG_GINTSTS_RXFLVL BIT(4)
+#define OTG_GINTSTS_USBSUSP BIT(11)
+#define OTG_GINTSTS_USBRST BIT(12)
+#define OTG_GINTSTS_ENUMDNE BIT(13)
+#define OTG_GINTSTS_IEPINT BIT(18)
+#define OTG_GINTSTS_OEPINT BIT(19)
+#define OTG_GINTSTS_IISOIXFR BIT(20)
+#define OTG_GINTSTS_IPXFR_INCOMPISOOUT BIT(21)
+#define OTG_GINTSTS_LPMINT BIT(27)
+#define OTG_GINTSTS_SRQINT BIT(30)
+#define OTG_GINTSTS_WKUPINT BIT(31)
+
+/* Bit definitions for OTG_GRXSTSP register */
+#define OTG_GRXSTSP_EPNUM GENMASK(3, 0)
+#define OTG_GRXSTSP_BCNT GENMASK(14, 4)
+#define OTG_GRXSTSP_BCNT_SHIFT 4U
+#define OTG_GRXSTSP_PKTSTS GENMASK(20, 17)
+#define OTG_GRXSTSP_PKTSTS_SHIFT 17U
+
+#define STS_GOUT_NAK 1U
+#define STS_DATA_UPDT 2U
+#define STS_XFER_COMP 3U
+#define STS_SETUP_COMP 4U
+#define STS_SETUP_UPDT 6U
+
+/* Bit definitions for OTG_GLPMCFG register */
+#define OTG_GLPMCFG_BESL GENMASK(5, 2)
+
+/* Bit definitions for OTG_DCFG register */
+#define OTG_DCFG_DAD GENMASK(10, 4)
+#define OTG_DCFG_DAD_SHIFT 4U
+
+/* Bit definitions for OTG_DCTL register */
+#define OTG_DCTL_RWUSIG BIT(0)
+#define OTG_DCTL_SDIS BIT(1)
+#define OTG_DCTL_CGINAK BIT(8)
+
+/* Bit definitions for OTG_DSTS register */
+#define OTG_DSTS_SUSPSTS BIT(0)
+#define OTG_DSTS_ENUMSPD_MASK GENMASK(2, 1)
+#define OTG_DSTS_FNSOF0 BIT(8)
+
+#define OTG_DSTS_ENUMSPD(val) ((val) << 1)
+#define OTG_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ OTG_DSTS_ENUMSPD(0U)
+#define OTG_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ OTG_DSTS_ENUMSPD(1U)
+#define OTG_DSTS_ENUMSPD_LS_PHY_6MHZ OTG_DSTS_ENUMSPD(2U)
+#define OTG_DSTS_ENUMSPD_FS_PHY_48MHZ OTG_DSTS_ENUMSPD(3U)
+
+/* Bit definitions for OTG_DIEPMSK register */
+#define OTG_DIEPMSK_XFRCM BIT(0)
+#define OTG_DIEPMSK_EPDM BIT(1)
+#define OTG_DIEPMSK_TOM BIT(3)
+
+/* Bit definitions for OTG_DOEPMSK register */
+#define OTG_DOEPMSK_XFRCM BIT(0)
+#define OTG_DOEPMSK_EPDM BIT(1)
+#define OTG_DOEPMSK_STUPM BIT(3)
+
+/* Bit definitions for OTG_DIEPCTLx registers */
+#define OTG_DIEPCTL_MPSIZ GENMASK(10, 0)
+#define OTG_DIEPCTL_STALL BIT(21)
+#define OTG_DIEPCTL_CNAK BIT(26)
+#define OTG_DIEPCTL_SD0PID_SEVNFRM BIT(28)
+#define OTG_DIEPCTL_SODDFRM BIT(29)
+#define OTG_DIEPCTL_EPDIS BIT(30)
+#define OTG_DIEPCTL_EPENA BIT(31)
+
+/* Bit definitions for OTG_DIEPINTx registers */
+#define OTG_DIEPINT_XFRC BIT(0)
+#define OTG_DIEPINT_EPDISD BIT(1)
+#define OTG_DIEPINT_TOC BIT(3)
+#define OTG_DIEPINT_ITTXFE BIT(4)
+#define OTG_DIEPINT_INEPNE BIT(6)
+#define OTG_DIEPINT_TXFE BIT(7)
+#define OTG_DIEPINT_TXFE_SHIFT 7U
+
+#define OTG_DIEPINT_MASK (BIT(13) | BIT(11) | GENMASK(9, 0))
+
+/* Bit definitions for OTG_DIEPTSIZx registers */
+#define OTG_DIEPTSIZ_XFRSIZ GENMASK(18, 0)
+#define OTG_DIEPTSIZ_PKTCNT GENMASK(28, 19)
+#define OTG_DIEPTSIZ_PKTCNT_SHIFT 19U
+#define OTG_DIEPTSIZ_MCNT_MASK GENMASK(30, 29)
+#define OTG_DIEPTSIZ_MCNT_DATA0 BIT(29)
+
+#define OTG_DIEPTSIZ_PKTCNT_1 BIT(19)
+
+/* Bit definitions for OTG_DTXFSTSx registers */
+#define OTG_DTXFSTS_INEPTFSAV GENMASK(15, 0)
+
+/* Bit definitions for OTG_DOEPCTLx registers */
+#define OTG_DOEPCTL_STALL BIT(21)
+#define OTG_DOEPCTL_CNAK BIT(26)
+#define OTG_DOEPCTL_SD0PID_SEVNFRM BIT(28) /* other than endpoint 0 */
+#define OTG_DOEPCTL_SD1PID_SODDFRM BIT(29) /* other than endpoint 0 */
+#define OTG_DOEPCTL_EPDIS BIT(30)
+#define OTG_DOEPCTL_EPENA BIT(31)
+
+/* Bit definitions for OTG_DOEPTSIZx registers */
+#define OTG_DOEPTSIZ_XFRSIZ GENMASK(18, 0)
+#define OTG_DOEPTSIZ_PKTCNT GENMASK(28, 19)
+#define OTG_DOEPTSIZ_RXDPID_STUPCNT GENMASK(30, 29)
+
+/* Bit definitions for OTG_DOEPINTx registers */
+#define OTG_DOEPINT_XFRC BIT(0)
+#define OTG_DOEPINT_STUP BIT(3)
+#define OTG_DOEPINT_OTEPDIS BIT(4)
+
+#define OTG_DOEPINT_MASK (GENMASK(15, 12) | GENMASK(9, 8) | GENMASK(6, 0))
+
+#define EP_NB 15U
+#define EP_ALL 0x10U
+
+/*
+ * Flush TX FIFO.
+ * handle: PCD handle.
+ * num: FIFO number.
+ * This parameter can be a value from 1 to 15 or EP_ALL.
+ * EP_ALL= 0x10 means Flush all TX FIFOs
+ * return: USB status.
+ */
+static enum usb_status usb_dwc2_flush_tx_fifo(void *handle, uint32_t num)
+{
+ uintptr_t usb_base_addr = (uintptr_t)handle;
+ uint64_t timeout = timeout_init_us(USBD_FIFO_FLUSH_TIMEOUT_US);
+
+ mmio_write_32(usb_base_addr + OTG_GRSTCTL,
+ OTG_GRSTCTL_TXFFLSH | (uint32_t)(num << OTG_GRSTCTL_TXFNUM_SHIFT));
+
+ while ((mmio_read_32(usb_base_addr + OTG_GRSTCTL) &
+ OTG_GRSTCTL_TXFFLSH) == OTG_GRSTCTL_TXFFLSH) {
+ if (timeout_elapsed(timeout)) {
+ return USBD_TIMEOUT;
+ }
+ }
+
+ return USBD_OK;
+}
+
+/*
+ * Flush RX FIFO.
+ * handle: PCD handle.
+ * return: USB status.
+ */
+static enum usb_status usb_dwc2_flush_rx_fifo(void *handle)
+{
+ uintptr_t usb_base_addr = (uintptr_t)handle;
+ uint64_t timeout = timeout_init_us(USBD_FIFO_FLUSH_TIMEOUT_US);
+
+ mmio_write_32(usb_base_addr + OTG_GRSTCTL, OTG_GRSTCTL_RXFFLSH);
+
+ while ((mmio_read_32(usb_base_addr + OTG_GRSTCTL) &
+ OTG_GRSTCTL_RXFFLSH) == OTG_GRSTCTL_RXFFLSH) {
+ if (timeout_elapsed(timeout)) {
+ return USBD_TIMEOUT;
+ }
+ }
+
+ return USBD_OK;
+}
+
+/*
+ * Return the global USB interrupt status.
+ * handle: PCD handle.
+ * return: Interrupt register value.
+ */
+static uint32_t usb_dwc2_read_int(void *handle)
+{
+ uintptr_t usb_base_addr = (uintptr_t)handle;
+
+ return mmio_read_32(usb_base_addr + OTG_GINTSTS) &
+ mmio_read_32(usb_base_addr + OTG_GINTMSK);
+}
+
+/*
+ * Return the USB device OUT endpoints interrupt.
+ * handle: PCD handle.
+ * return: Device OUT endpoint interrupts.
+ */
+static uint32_t usb_dwc2_all_out_ep_int(void *handle)
+{
+ uintptr_t usb_base_addr = (uintptr_t)handle;
+
+ return ((mmio_read_32(usb_base_addr + OTG_DAINT) &
+ mmio_read_32(usb_base_addr + OTG_DAINTMSK)) &
+ OTG_DAINT_OUT_MASK) >> OTG_DAINT_OUT_SHIFT;
+}
+
+/*
+ * Return the USB device IN endpoints interrupt.
+ * handle: PCD handle.
+ * return: Device IN endpoint interrupts.
+ */
+static uint32_t usb_dwc2_all_in_ep_int(void *handle)
+{
+ uintptr_t usb_base_addr = (uintptr_t)handle;
+
+ return ((mmio_read_32(usb_base_addr + OTG_DAINT) &
+ mmio_read_32(usb_base_addr + OTG_DAINTMSK)) &
+ OTG_DAINT_IN_MASK) >> OTG_DAINT_IN_SHIFT;
+}
+
+/*
+ * Return Device OUT EP interrupt register.
+ * handle: PCD handle.
+ * epnum: Endpoint number.
+ * This parameter can be a value from 0 to 15.
+ * return: Device OUT EP Interrupt register.
+ */
+static uint32_t usb_dwc2_out_ep_int(void *handle, uint8_t epnum)
+{
+ uintptr_t usb_base_addr = (uintptr_t)handle;
+
+ return mmio_read_32(usb_base_addr + OTG_DOEP_BASE +
+ (epnum * OTG_DOEP_SIZE) + OTG_DOEPINT) &
+ mmio_read_32(usb_base_addr + OTG_DOEPMSK);
+}
+
+/*
+ * Return Device IN EP interrupt register.
+ * handle: PCD handle.
+ * epnum: Endpoint number.
+ * This parameter can be a value from 0 to 15.
+ * return: Device IN EP Interrupt register.
+ */
+static uint32_t usb_dwc2_in_ep_int(void *handle, uint8_t epnum)
+{
+ uintptr_t usb_base_addr = (uintptr_t)handle;
+ uint32_t msk;
+ uint32_t emp;
+
+ msk = mmio_read_32(usb_base_addr + OTG_DIEPMSK);
+ emp = mmio_read_32(usb_base_addr + OTG_DIEPEMPMSK);
+ msk |= ((emp >> epnum) << OTG_DIEPINT_TXFE_SHIFT) & OTG_DIEPINT_TXFE;
+
+ return mmio_read_32(usb_base_addr + OTG_DIEP_BASE +
+ (epnum * OTG_DIEP_SIZE) + OTG_DIEPINT) & msk;
+}
+
+/*
+ * Return USB core mode.
+ * handle: PCD handle.
+ * return: Core mode.
+ * This parameter can be 0 (host) or 1 (device).
+ */
+static uint32_t usb_dwc2_get_mode(void *handle)
+{
+ uintptr_t usb_base_addr = (uintptr_t)handle;
+
+ return mmio_read_32(usb_base_addr + OTG_GINTSTS) & OTG_GINTSTS_CMOD;
+}
+
+/*
+ * Activate EP0 for detup transactions.
+ * handle: PCD handle.
+ * return: USB status.
+ */
+static enum usb_status usb_dwc2_activate_setup(void *handle)
+{
+ uintptr_t usb_base_addr = (uintptr_t)handle;
+ uintptr_t reg_offset = usb_base_addr + OTG_DIEP_BASE;
+
+ /* Set the MPS of the IN EP based on the enumeration speed */
+ mmio_clrbits_32(reg_offset + OTG_DIEPCTL, OTG_DIEPCTL_MPSIZ);
+
+ if ((mmio_read_32(usb_base_addr + OTG_DSTS) & OTG_DSTS_ENUMSPD_MASK) ==
+ OTG_DSTS_ENUMSPD_LS_PHY_6MHZ) {
+ mmio_setbits_32(reg_offset + OTG_DIEPCTL, 3U);
+ }
+
+ mmio_setbits_32(usb_base_addr + OTG_DCTL, OTG_DCTL_CGINAK);
+
+ return USBD_OK;
+}
+
+/*
+ * Prepare the EP0 to start the first control setup.
+ * handle: Selected device.
+ * return: USB status.
+ */
+static enum usb_status usb_dwc2_ep0_out_start(void *handle)
+{
+ uintptr_t usb_base_addr = (uintptr_t)handle;
+ uintptr_t reg_offset = usb_base_addr + OTG_DIEP_BASE + OTG_DIEPTSIZ;
+ uint32_t reg_value = 0U;
+
+ /* PKTCNT = 1 and XFRSIZ = 24 bytes for endpoint 0 */
+ reg_value |= OTG_DIEPTSIZ_PKTCNT_1;
+ reg_value |= (EP0_FIFO_SIZE & OTG_DIEPTSIZ_XFRSIZ);
+ reg_value |= OTG_DOEPTSIZ_RXDPID_STUPCNT;
+
+ mmio_write_32(reg_offset, reg_value);
+
+ return USBD_OK;
+}
+
+/*
+ * Write a packet into the TX FIFO associated with the EP/channel.
+ * handle: Selected device.
+ * src: Pointer to source buffer.
+ * ch_ep_num: Endpoint or host channel number.
+ * len: Number of bytes to write.
+ * return: USB status.
+ */
+static enum usb_status usb_dwc2_write_packet(void *handle, uint8_t *src,
+ uint8_t ch_ep_num, uint16_t len)
+{
+ uint32_t reg_offset;
+ uint32_t count32b = (len + 3U) / 4U;
+ uint32_t i;
+
+ reg_offset = (uintptr_t)handle + OTG_FIFO_BASE +
+ (ch_ep_num * OTG_FIFO_SIZE);
+
+ for (i = 0U; i < count32b; i++) {
+ uint32_t src_copy = 0U;
+ uint32_t j;
+
+ /* Data written to FIFO need to be 4 bytes aligned */
+ for (j = 0U; j < 4U; j++) {
+ src_copy += (*(src + j)) << (8U * j);
+ }
+
+ mmio_write_32(reg_offset, src_copy);
+ src += 4U;
+ }
+
+ return USBD_OK;
+}
+
+/*
+ * Read a packet from the RX FIFO associated with the EP/channel.
+ * handle: Selected device.
+ * dst: Destination pointer.
+ * len: Number of bytes to read.
+ * return: Pointer to destination buffer.
+ */
+static void *usb_dwc2_read_packet(void *handle, uint8_t *dest, uint16_t len)
+{
+ uint32_t reg_offset;
+ uint32_t count32b = (len + 3U) / 4U;
+ uint32_t i;
+
+ VERBOSE("read packet length %i to 0x%lx\n", len, (uintptr_t)dest);
+
+ reg_offset = (uintptr_t)handle + OTG_FIFO_BASE;
+
+ for (i = 0U; i < count32b; i++) {
+ *(uint32_t *)dest = mmio_read_32(reg_offset);
+ dest += 4U;
+ dsb();
+ }
+
+ return (void *)dest;
+}
+
+/*
+ * Setup and start a transfer over an EP.
+ * handle: Selected device
+ * ep: Pointer to endpoint structure.
+ * return: USB status.
+ */
+static enum usb_status usb_dwc2_ep_start_xfer(void *handle, struct usbd_ep *ep)
+{
+ uintptr_t usb_base_addr = (uintptr_t)handle;
+ uint32_t reg_offset;
+ uint32_t reg_value;
+ uint32_t clear_value;
+
+ if (ep->is_in) {
+ reg_offset = usb_base_addr + OTG_DIEP_BASE + (ep->num * OTG_DIEP_SIZE);
+ clear_value = OTG_DIEPTSIZ_PKTCNT | OTG_DIEPTSIZ_XFRSIZ;
+ if (ep->xfer_len == 0U) {
+ reg_value = OTG_DIEPTSIZ_PKTCNT_1;
+ } else {
+ /*
+ * Program the transfer size and packet count
+ * as follows:
+ * xfersize = N * maxpacket + short_packet
+ * pktcnt = N + (short_packet exist ? 1 : 0)
+ */
+ reg_value = (OTG_DIEPTSIZ_PKTCNT &
+ (((ep->xfer_len + ep->maxpacket - 1U) /
+ ep->maxpacket) << OTG_DIEPTSIZ_PKTCNT_SHIFT))
+ | ep->xfer_len;
+
+ if (ep->type == EP_TYPE_ISOC) {
+ clear_value |= OTG_DIEPTSIZ_MCNT_MASK;
+ reg_value |= OTG_DIEPTSIZ_MCNT_DATA0;
+ }
+ }
+
+ mmio_clrsetbits_32(reg_offset + OTG_DIEPTSIZ, clear_value, reg_value);
+
+ if ((ep->type != EP_TYPE_ISOC) && (ep->xfer_len > 0U)) {
+ /* Enable the TX FIFO empty interrupt for this EP */
+ mmio_setbits_32(usb_base_addr + OTG_DIEPEMPMSK, BIT(ep->num));
+ }
+
+ /* EP enable, IN data in FIFO */
+ reg_value = OTG_DIEPCTL_CNAK | OTG_DIEPCTL_EPENA;
+
+ if (ep->type == EP_TYPE_ISOC) {
+ if ((mmio_read_32(usb_base_addr + OTG_DSTS) & OTG_DSTS_FNSOF0) == 0U) {
+ reg_value |= OTG_DIEPCTL_SODDFRM;
+ } else {
+ reg_value |= OTG_DIEPCTL_SD0PID_SEVNFRM;
+ }
+ }
+
+ mmio_setbits_32(reg_offset + OTG_DIEPCTL, reg_value);
+
+ if (ep->type == EP_TYPE_ISOC) {
+ usb_dwc2_write_packet(handle, ep->xfer_buff, ep->num, ep->xfer_len);
+ }
+ } else {
+ reg_offset = usb_base_addr + OTG_DOEP_BASE + (ep->num * OTG_DOEP_SIZE);
+ /*
+ * Program the transfer size and packet count as follows:
+ * pktcnt = N
+ * xfersize = N * maxpacket
+ */
+ if (ep->xfer_len == 0U) {
+ reg_value = ep->maxpacket | OTG_DIEPTSIZ_PKTCNT_1;
+ } else {
+ uint16_t pktcnt = (ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket;
+
+ reg_value = (pktcnt << OTG_DIEPTSIZ_PKTCNT_SHIFT) |
+ (ep->maxpacket * pktcnt);
+ }
+
+ mmio_clrsetbits_32(reg_offset + OTG_DOEPTSIZ,
+ OTG_DOEPTSIZ_XFRSIZ & OTG_DOEPTSIZ_PKTCNT,
+ reg_value);
+
+ /* EP enable */
+ reg_value = OTG_DOEPCTL_CNAK | OTG_DOEPCTL_EPENA;
+
+ if (ep->type == EP_TYPE_ISOC) {
+ if ((mmio_read_32(usb_base_addr + OTG_DSTS) & OTG_DSTS_FNSOF0) == 0U) {
+ reg_value |= OTG_DOEPCTL_SD1PID_SODDFRM;
+ } else {
+ reg_value |= OTG_DOEPCTL_SD0PID_SEVNFRM;
+ }
+ }
+
+ mmio_setbits_32(reg_offset + OTG_DOEPCTL, reg_value);
+ }
+
+ return USBD_OK;
+}
+
+/*
+ * Setup and start a transfer over the EP0.
+ * handle: Selected device.
+ * ep: Pointer to endpoint structure.
+ * return: USB status.
+ */
+static enum usb_status usb_dwc2_ep0_start_xfer(void *handle, struct usbd_ep *ep)
+{
+ uintptr_t usb_base_addr = (uintptr_t)handle;
+ uint32_t reg_offset;
+ uint32_t reg_value;
+
+ if (ep->is_in) {
+ reg_offset = usb_base_addr + OTG_DIEP_BASE +
+ (ep->num * OTG_DIEP_SIZE);
+
+ if (ep->xfer_len == 0U) {
+ reg_value = OTG_DIEPTSIZ_PKTCNT_1;
+ } else {
+ /*
+ * Program the transfer size and packet count
+ * as follows:
+ * xfersize = N * maxpacket + short_packet
+ * pktcnt = N + (short_packet exist ? 1 : 0)
+ */
+
+ if (ep->xfer_len > ep->maxpacket) {
+ ep->xfer_len = ep->maxpacket;
+ }
+
+ reg_value = OTG_DIEPTSIZ_PKTCNT_1 | ep->xfer_len;
+ }
+
+ mmio_clrsetbits_32(reg_offset + OTG_DIEPTSIZ,
+ OTG_DIEPTSIZ_XFRSIZ | OTG_DIEPTSIZ_PKTCNT,
+ reg_value);
+
+ /* Enable the TX FIFO empty interrupt for this EP */
+ if (ep->xfer_len > 0U) {
+ mmio_setbits_32(usb_base_addr + OTG_DIEPEMPMSK,
+ BIT(ep->num));
+ }
+
+ /* EP enable, IN data in FIFO */
+ mmio_setbits_32(reg_offset + OTG_DIEPCTL,
+ OTG_DIEPCTL_CNAK | OTG_DIEPCTL_EPENA);
+ } else {
+ reg_offset = usb_base_addr + OTG_DOEP_BASE +
+ (ep->num * OTG_DOEP_SIZE);
+
+ /*
+ * Program the transfer size and packet count as follows:
+ * pktcnt = N
+ * xfersize = N * maxpacket
+ */
+ if (ep->xfer_len > 0U) {
+ ep->xfer_len = ep->maxpacket;
+ }
+
+ reg_value = OTG_DIEPTSIZ_PKTCNT_1 | ep->maxpacket;
+
+ mmio_clrsetbits_32(reg_offset + OTG_DIEPTSIZ,
+ OTG_DIEPTSIZ_XFRSIZ | OTG_DIEPTSIZ_PKTCNT,
+ reg_value);
+
+ /* EP enable */
+ mmio_setbits_32(reg_offset + OTG_DOEPCTL,
+ OTG_DOEPCTL_CNAK | OTG_DOEPCTL_EPENA);
+ }
+
+ return USBD_OK;
+}
+
+/*
+ * Set a stall condition over an EP.
+ * handle: Selected device.
+ * ep: Pointer to endpoint structure.
+ * return: USB status.
+ */
+static enum usb_status usb_dwc2_ep_set_stall(void *handle, struct usbd_ep *ep)
+{
+ uintptr_t usb_base_addr = (uintptr_t)handle;
+ uint32_t reg_offset;
+ uint32_t reg_value;
+
+ if (ep->is_in) {
+ reg_offset = usb_base_addr + OTG_DIEP_BASE +
+ (ep->num * OTG_DIEP_SIZE);
+ reg_value = mmio_read_32(reg_offset + OTG_DIEPCTL);
+
+ if ((reg_value & OTG_DIEPCTL_EPENA) == 0U) {
+ reg_value &= ~OTG_DIEPCTL_EPDIS;
+ }
+
+ reg_value |= OTG_DIEPCTL_STALL;
+
+ mmio_write_32(reg_offset + OTG_DIEPCTL, reg_value);
+ } else {
+ reg_offset = usb_base_addr + OTG_DOEP_BASE +
+ (ep->num * OTG_DOEP_SIZE);
+ reg_value = mmio_read_32(reg_offset + OTG_DOEPCTL);
+
+ if ((reg_value & OTG_DOEPCTL_EPENA) == 0U) {
+ reg_value &= ~OTG_DOEPCTL_EPDIS;
+ }
+
+ reg_value |= OTG_DOEPCTL_STALL;
+
+ mmio_write_32(reg_offset + OTG_DOEPCTL, reg_value);
+ }
+
+ return USBD_OK;
+}
+
+/*
+ * Stop the USB device mode.
+ * handle: Selected device.
+ * return: USB status.
+ */
+static enum usb_status usb_dwc2_stop_device(void *handle)
+{
+ uintptr_t usb_base_addr = (uintptr_t)handle;
+ uint32_t i;
+
+ /* Disable Int */
+ mmio_clrbits_32(usb_base_addr + OTG_GAHBCFG, OTG_GAHBCFG_GINT);
+
+ /* Clear pending interrupts */
+ for (i = 0U; i < EP_NB; i++) {
+ mmio_write_32(usb_base_addr + OTG_DIEP_BASE + (i * OTG_DIEP_SIZE) + OTG_DIEPINT,
+ OTG_DIEPINT_MASK);
+ mmio_write_32(usb_base_addr + OTG_DOEP_BASE + (i * OTG_DOEP_SIZE) + OTG_DOEPINT,
+ OTG_DOEPINT_MASK);
+ }
+
+ mmio_write_32(usb_base_addr + OTG_DAINT, OTG_DAINT_IN_MASK | OTG_DAINT_OUT_MASK);
+
+ /* Clear interrupt masks */
+ mmio_write_32(usb_base_addr + OTG_DIEPMSK, 0U);
+ mmio_write_32(usb_base_addr + OTG_DOEPMSK, 0U);
+ mmio_write_32(usb_base_addr + OTG_DAINTMSK, 0U);
+
+ /* Flush the FIFO */
+ usb_dwc2_flush_rx_fifo(handle);
+ usb_dwc2_flush_tx_fifo(handle, EP_ALL);
+
+ /* Disconnect the USB device by disabling the pull-up/pull-down */
+ mmio_setbits_32((uintptr_t)handle + OTG_DCTL, OTG_DCTL_SDIS);
+
+ return USBD_OK;
+}
+
+/*
+ * Stop the USB device mode.
+ * handle: Selected device.
+ * address: New device address to be assigned.
+ * This parameter can be a value from 0 to 255.
+ * return: USB status.
+ */
+static enum usb_status usb_dwc2_set_address(void *handle, uint8_t address)
+{
+ uintptr_t usb_base_addr = (uintptr_t)handle;
+
+ mmio_clrsetbits_32(usb_base_addr + OTG_DCFG,
+ OTG_DCFG_DAD,
+ address << OTG_DCFG_DAD_SHIFT);
+
+ return USBD_OK;
+}
+
+/*
+ * Check FIFO for the next packet to be loaded.
+ * handle: Selected device.
+ * epnum : Endpoint number.
+ * xfer_len: Block length.
+ * xfer_count: Number of blocks.
+ * maxpacket: Max packet length.
+ * xfer_buff: Buffer pointer.
+ * return: USB status.
+ */
+static enum usb_status usb_dwc2_write_empty_tx_fifo(void *handle,
+ uint32_t epnum,
+ uint32_t xfer_len,
+ uint32_t *xfer_count,
+ uint32_t maxpacket,
+ uint8_t **xfer_buff)
+{
+ uintptr_t usb_base_addr = (uintptr_t)handle;
+ uint32_t reg_offset;
+ int32_t len;
+ uint32_t len32b;
+ enum usb_status ret;
+
+ len = xfer_len - *xfer_count;
+
+ if ((len > 0) && ((uint32_t)len > maxpacket)) {
+ len = maxpacket;
+ }
+
+ len32b = (len + 3U) / 4U;
+
+ reg_offset = usb_base_addr + OTG_DIEP_BASE + (epnum * OTG_DIEP_SIZE);
+
+ while (((mmio_read_32(reg_offset + OTG_DTXFSTS) &
+ OTG_DTXFSTS_INEPTFSAV) > len32b) &&
+ (*xfer_count < xfer_len) && (xfer_len != 0U)) {
+ /* Write the FIFO */
+ len = xfer_len - *xfer_count;
+
+ if ((len > 0) && ((uint32_t)len > maxpacket)) {
+ len = maxpacket;
+ }
+
+ len32b = (len + 3U) / 4U;
+
+ ret = usb_dwc2_write_packet(handle, *xfer_buff, epnum, len);
+ if (ret != USBD_OK) {
+ return ret;
+ }
+
+ *xfer_buff += len;
+ *xfer_count += len;
+ }
+
+ if (len <= 0) {
+ mmio_clrbits_32(usb_base_addr + OTG_DIEPEMPMSK, BIT(epnum));
+ }
+
+ return USBD_OK;
+}
+
+/*
+ * Handle PCD interrupt request.
+ * handle: PCD handle.
+ * param: Pointer to information updated by the IT handling.
+ * return: Action to do after IT handling.
+ */
+static enum usb_action usb_dwc2_it_handler(void *handle, uint32_t *param)
+{
+ uintptr_t usb_base_addr = (uintptr_t)handle;
+ uint32_t ep_intr;
+ uint32_t epint;
+ uint32_t epnum;
+ uint32_t temp;
+ enum usb_status ret;
+
+ if (usb_dwc2_get_mode(handle) != USB_OTG_MODE_DEVICE) {
+ return USB_NOTHING;
+ }
+
+ /* Avoid spurious interrupt */
+ if (usb_dwc2_read_int(handle) == 0U) {
+ return USB_NOTHING;
+ }
+
+ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_MMIS) != 0U) {
+ /* Incorrect mode, acknowledge the interrupt */
+ mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_MMIS);
+ }
+
+ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_OEPINT) != 0U) {
+ uint32_t reg_offset;
+
+ /* Read in the device interrupt bits */
+ ep_intr = usb_dwc2_all_out_ep_int(handle);
+ epnum = 0U;
+ while ((ep_intr & BIT(0)) != BIT(0)) {
+ epnum++;
+ ep_intr >>= 1;
+ }
+
+ reg_offset = usb_base_addr + OTG_DOEP_BASE + (epnum * OTG_DOEP_SIZE) + OTG_DOEPINT;
+
+ epint = usb_dwc2_out_ep_int(handle, epnum);
+
+ if ((epint & OTG_DOEPINT_XFRC) == OTG_DOEPINT_XFRC) {
+ mmio_write_32(reg_offset, OTG_DOEPINT_XFRC);
+ *param = epnum;
+
+ return USB_DATA_OUT;
+ }
+
+ if ((epint & OTG_DOEPINT_STUP) == OTG_DOEPINT_STUP) {
+ /* Inform that a setup packet is available */
+ mmio_write_32(reg_offset, OTG_DOEPINT_STUP);
+
+ return USB_SETUP;
+ }
+
+ if ((epint & OTG_DOEPINT_OTEPDIS) == OTG_DOEPINT_OTEPDIS) {
+ mmio_write_32(reg_offset, OTG_DOEPINT_OTEPDIS);
+ }
+ }
+
+ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_IEPINT) != 0U) {
+ uint32_t reg_offset;
+
+ /* Read in the device interrupt bits */
+ ep_intr = usb_dwc2_all_in_ep_int(handle);
+ epnum = 0U;
+ while ((ep_intr & BIT(0)) != BIT(0)) {
+ epnum++;
+ ep_intr >>= 1;
+ }
+
+ reg_offset = usb_base_addr + OTG_DIEP_BASE + (epnum * OTG_DIEP_SIZE) + OTG_DIEPINT;
+
+ epint = usb_dwc2_in_ep_int(handle, epnum);
+
+ if ((epint & OTG_DIEPINT_XFRC) == OTG_DIEPINT_XFRC) {
+ mmio_clrbits_32(usb_base_addr + OTG_DIEPEMPMSK, BIT(epnum));
+ mmio_write_32(reg_offset, OTG_DIEPINT_XFRC);
+ *param = epnum;
+
+ return USB_DATA_IN;
+ }
+
+ if ((epint & OTG_DIEPINT_TOC) == OTG_DIEPINT_TOC) {
+ mmio_write_32(reg_offset, OTG_DIEPINT_TOC);
+ }
+
+ if ((epint & OTG_DIEPINT_ITTXFE) == OTG_DIEPINT_ITTXFE) {
+ mmio_write_32(reg_offset, OTG_DIEPINT_ITTXFE);
+ }
+
+ if ((epint & OTG_DIEPINT_INEPNE) == OTG_DIEPINT_INEPNE) {
+ mmio_write_32(reg_offset, OTG_DIEPINT_INEPNE);
+ }
+
+ if ((epint & OTG_DIEPINT_EPDISD) == OTG_DIEPINT_EPDISD) {
+ mmio_write_32(reg_offset, OTG_DIEPINT_EPDISD);
+ }
+
+ if ((epint & OTG_DIEPINT_TXFE) == OTG_DIEPINT_TXFE) {
+ *param = epnum;
+
+ return USB_WRITE_EMPTY;
+ }
+ }
+
+ /* Handle resume interrupt */
+ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_WKUPINT) != 0U) {
+ INFO("handle USB : Resume\n");
+
+ /* Clear the remote wake-up signaling */
+ mmio_clrbits_32(usb_base_addr + OTG_DCTL, OTG_DCTL_RWUSIG);
+ mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_WKUPINT);
+
+ return USB_RESUME;
+ }
+
+ /* Handle suspend interrupt */
+ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_USBSUSP) != 0U) {
+ INFO("handle USB : Suspend int\n");
+
+ mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_USBSUSP);
+
+ if ((mmio_read_32(usb_base_addr + OTG_DSTS) &
+ OTG_DSTS_SUSPSTS) == OTG_DSTS_SUSPSTS) {
+ return USB_SUSPEND;
+ }
+ }
+
+ /* Handle LPM interrupt */
+ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_LPMINT) != 0U) {
+ INFO("handle USB : LPM int enter in suspend\n");
+
+ mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_LPMINT);
+ *param = (mmio_read_32(usb_base_addr + OTG_GLPMCFG) &
+ OTG_GLPMCFG_BESL) >> 2;
+
+ return USB_LPM;
+ }
+
+ /* Handle reset interrupt */
+ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_USBRST) != 0U) {
+ INFO("handle USB : Reset\n");
+
+ mmio_clrbits_32(usb_base_addr + OTG_DCTL, OTG_DCTL_RWUSIG);
+
+ usb_dwc2_flush_tx_fifo(handle, 0U);
+
+ mmio_write_32(usb_base_addr + OTG_DAINT, OTG_DAINT_IN_MASK | OTG_DAINT_OUT_MASK);
+ mmio_setbits_32(usb_base_addr + OTG_DAINTMSK, OTG_DAINT_EP0_IN | OTG_DAINT_EP0_OUT);
+
+ mmio_setbits_32(usb_base_addr + OTG_DOEPMSK, OTG_DOEPMSK_STUPM |
+ OTG_DOEPMSK_XFRCM |
+ OTG_DOEPMSK_EPDM);
+ mmio_setbits_32(usb_base_addr + OTG_DIEPMSK, OTG_DIEPMSK_TOM |
+ OTG_DIEPMSK_XFRCM |
+ OTG_DIEPMSK_EPDM);
+
+ /* Set default address to 0 */
+ mmio_clrbits_32(usb_base_addr + OTG_DCFG, OTG_DCFG_DAD);
+
+ /* Setup EP0 to receive SETUP packets */
+ ret = usb_dwc2_ep0_out_start(handle);
+ if (ret != USBD_OK) {
+ return ret;
+ }
+
+ mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_USBRST);
+
+ return USB_RESET;
+ }
+
+ /* Handle enumeration done interrupt */
+ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_ENUMDNE) != 0U) {
+ ret = usb_dwc2_activate_setup(handle);
+ if (ret != USBD_OK) {
+ return ret;
+ }
+
+ mmio_clrbits_32(usb_base_addr + OTG_GUSBCFG, OTG_GUSBCFG_TRDT);
+
+ mmio_setbits_32(usb_base_addr + OTG_GUSBCFG,
+ (USBD_HS_TRDT_VALUE << OTG_GUSBCFG_TRDT_SHIFT) & OTG_GUSBCFG_TRDT);
+
+ mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_ENUMDNE);
+
+ return USB_ENUM_DONE;
+ }
+
+ /* Handle RXQLevel interrupt */
+ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_RXFLVL) != 0U) {
+ mmio_clrbits_32(usb_base_addr + OTG_GINTMSK,
+ OTG_GINTSTS_RXFLVL);
+
+ temp = mmio_read_32(usb_base_addr + OTG_GRXSTSP);
+
+ *param = temp & OTG_GRXSTSP_EPNUM;
+ *param |= (temp & OTG_GRXSTSP_BCNT) << (USBD_OUT_COUNT_SHIFT -
+ OTG_GRXSTSP_BCNT_SHIFT);
+
+ if (((temp & OTG_GRXSTSP_PKTSTS) >> OTG_GRXSTSP_PKTSTS_SHIFT) == STS_DATA_UPDT) {
+ if ((temp & OTG_GRXSTSP_BCNT) != 0U) {
+ mmio_setbits_32(usb_base_addr + OTG_GINTMSK, OTG_GINTSTS_RXFLVL);
+
+ return USB_READ_DATA_PACKET;
+ }
+ } else if (((temp & OTG_GRXSTSP_PKTSTS) >> OTG_GRXSTSP_PKTSTS_SHIFT) ==
+ STS_SETUP_UPDT) {
+ mmio_setbits_32(usb_base_addr + OTG_GINTMSK, OTG_GINTSTS_RXFLVL);
+
+ return USB_READ_SETUP_PACKET;
+ }
+
+ mmio_setbits_32(usb_base_addr + OTG_GINTMSK, OTG_GINTSTS_RXFLVL);
+ }
+
+ /* Handle SOF interrupt */
+ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_SOF) != 0U) {
+ INFO("handle USB : SOF\n");
+
+ mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_SOF);
+
+ return USB_SOF;
+ }
+
+ /* Handle incomplete ISO IN interrupt */
+ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_IISOIXFR) != 0U) {
+ INFO("handle USB : ISO IN\n");
+
+ mmio_write_32(usb_base_addr + OTG_GINTSTS,
+ OTG_GINTSTS_IISOIXFR);
+ }
+
+ /* Handle incomplete ISO OUT interrupt */
+ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_IPXFR_INCOMPISOOUT) !=
+ 0U) {
+ INFO("handle USB : ISO OUT\n");
+
+ mmio_write_32(usb_base_addr + OTG_GINTSTS,
+ OTG_GINTSTS_IPXFR_INCOMPISOOUT);
+ }
+
+ /* Handle connection event interrupt */
+ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_SRQINT) != 0U) {
+ INFO("handle USB : Connect\n");
+
+ mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_SRQINT);
+ }
+
+ /* Handle disconnection event interrupt */
+ if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_OTGINT) != 0U) {
+ INFO("handle USB : Disconnect\n");
+
+ temp = mmio_read_32(usb_base_addr + OTG_GOTGINT);
+
+ if ((temp & OTG_GOTGINT_SEDET) == OTG_GOTGINT_SEDET) {
+ return USB_DISCONNECT;
+ }
+ }
+
+ return USB_NOTHING;
+}
+
+/*
+ * Start the usb device mode
+ * usb_core_handle: USB core driver handle.
+ * return USB status.
+ */
+static enum usb_status usb_dwc2_start_device(void *handle)
+{
+ uintptr_t usb_base_addr = (uintptr_t)handle;
+
+ mmio_clrbits_32(usb_base_addr + OTG_DCTL, OTG_DCTL_SDIS);
+ mmio_setbits_32(usb_base_addr + OTG_GAHBCFG, OTG_GAHBCFG_GINT);
+
+ return USBD_OK;
+}
+
+static const struct usb_driver usb_dwc2driver = {
+ .ep0_out_start = usb_dwc2_ep0_out_start,
+ .ep_start_xfer = usb_dwc2_ep_start_xfer,
+ .ep0_start_xfer = usb_dwc2_ep0_start_xfer,
+ .write_packet = usb_dwc2_write_packet,
+ .read_packet = usb_dwc2_read_packet,
+ .ep_set_stall = usb_dwc2_ep_set_stall,
+ .start_device = usb_dwc2_start_device,
+ .stop_device = usb_dwc2_stop_device,
+ .set_address = usb_dwc2_set_address,
+ .write_empty_tx_fifo = usb_dwc2_write_empty_tx_fifo,
+ .it_handler = usb_dwc2_it_handler
+};
+
+/*
+ * Initialize USB DWC2 driver.
+ * usb_core_handle: USB core driver handle.
+ * pcd_handle: PCD handle.
+ * base_register: USB global register base address.
+ */
+void stm32mp1_usb_init_driver(struct usb_handle *usb_core_handle,
+ struct pcd_handle *pcd_handle,
+ void *base_register)
+{
+ register_usb_driver(usb_core_handle, pcd_handle, &usb_dwc2driver,
+ base_register);
+}
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index 6dbf37236..ae42e326f 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -34,6 +34,9 @@ int ufshc_send_uic_cmd(uintptr_t base, uic_cmd_t *cmd)
{
unsigned int data;
+ if (base == 0 || cmd == NULL)
+ return -EINVAL;
+
data = mmio_read_32(base + HCS);
if ((data & HCS_UCRDY) == 0)
return -EBUSY;
@@ -54,9 +57,13 @@ int ufshc_dme_get(unsigned int attr, unsigned int idx, unsigned int *val)
{
uintptr_t base;
unsigned int data;
- int retries;
+ int result, retries;
+ uic_cmd_t cmd;
+
+ assert(ufs_params.reg_base != 0);
- assert((ufs_params.reg_base != 0) && (val != NULL));
+ if (val == NULL)
+ return -EINVAL;
base = ufs_params.reg_base;
for (retries = 0; retries < 100; retries++) {
@@ -68,19 +75,20 @@ int ufshc_dme_get(unsigned int attr, unsigned int idx, unsigned int *val)
if (retries >= 100)
return -EBUSY;
- mmio_write_32(base + IS, ~0);
- mmio_write_32(base + UCMDARG1, (attr << 16) | GEN_SELECTOR_IDX(idx));
- mmio_write_32(base + UCMDARG2, 0);
- mmio_write_32(base + UCMDARG3, 0);
- mmio_write_32(base + UICCMD, DME_GET);
- do {
+ cmd.arg1 = (attr << 16) | GEN_SELECTOR_IDX(idx);
+ cmd.arg2 = 0;
+ cmd.arg3 = 0;
+ cmd.op = DME_GET;
+ for (retries = 0; retries < UFS_UIC_COMMAND_RETRIES; ++retries) {
+ result = ufshc_send_uic_cmd(base, &cmd);
+ if (result == 0)
+ break;
data = mmio_read_32(base + IS);
if (data & UFS_INT_UE)
return -EINVAL;
- } while ((data & UFS_INT_UCCS) == 0);
- mmio_write_32(base + IS, UFS_INT_UCCS);
- data = mmio_read_32(base + UCMDARG2) & CONFIG_RESULT_CODE_MASK;
- assert(data == 0);
+ }
+ if (retries >= UFS_UIC_COMMAND_RETRIES)
+ return -EIO;
*val = mmio_read_32(base + UCMDARG3);
return 0;
@@ -90,58 +98,101 @@ int ufshc_dme_set(unsigned int attr, unsigned int idx, unsigned int val)
{
uintptr_t base;
unsigned int data;
+ int result, retries;
+ uic_cmd_t cmd;
assert((ufs_params.reg_base != 0));
base = ufs_params.reg_base;
- data = mmio_read_32(base + HCS);
- if ((data & HCS_UCRDY) == 0)
- return -EBUSY;
- mmio_write_32(base + IS, ~0);
- mmio_write_32(base + UCMDARG1, (attr << 16) | GEN_SELECTOR_IDX(idx));
- mmio_write_32(base + UCMDARG2, 0);
- mmio_write_32(base + UCMDARG3, val);
- mmio_write_32(base + UICCMD, DME_SET);
- do {
+ cmd.arg1 = (attr << 16) | GEN_SELECTOR_IDX(idx);
+ cmd.arg2 = 0;
+ cmd.arg3 = val;
+ cmd.op = DME_SET;
+
+ for (retries = 0; retries < UFS_UIC_COMMAND_RETRIES; ++retries) {
+ result = ufshc_send_uic_cmd(base, &cmd);
+ if (result == 0)
+ break;
data = mmio_read_32(base + IS);
if (data & UFS_INT_UE)
return -EINVAL;
- } while ((data & UFS_INT_UCCS) == 0);
- mmio_write_32(base + IS, UFS_INT_UCCS);
- data = mmio_read_32(base + UCMDARG2) & CONFIG_RESULT_CODE_MASK;
- assert(data == 0);
+ }
+ if (retries >= UFS_UIC_COMMAND_RETRIES)
+ return -EIO;
+
return 0;
}
-static void ufshc_reset(uintptr_t base)
+static int ufshc_hce_enable(uintptr_t base)
{
unsigned int data;
+ int retries;
/* Enable Host Controller */
mmio_write_32(base + HCE, HCE_ENABLE);
+
/* Wait until basic initialization sequence completed */
- do {
+ for (retries = 0; retries < HCE_ENABLE_INNER_RETRIES; ++retries) {
data = mmio_read_32(base + HCE);
- } while ((data & HCE_ENABLE) == 0);
+ if (data & HCE_ENABLE) {
+ break;
+ }
+ udelay(HCE_ENABLE_TIMEOUT_US);
+ }
+ if (retries >= HCE_ENABLE_INNER_RETRIES) {
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int ufshc_reset(uintptr_t base)
+{
+ unsigned int data;
+ int retries, result;
+
+ for (retries = 0; retries < HCE_ENABLE_OUTER_RETRIES; ++retries) {
+ result = ufshc_hce_enable(base);
+ if (result == 0) {
+ break;
+ }
+ }
+ if (retries >= HCE_ENABLE_OUTER_RETRIES) {
+ return -EIO;
+ }
/* Enable Interrupts */
data = UFS_INT_UCCS | UFS_INT_ULSS | UFS_INT_UE | UFS_INT_UTPES |
UFS_INT_DFES | UFS_INT_HCFES | UFS_INT_SBFES;
mmio_write_32(base + IE, data);
+
+ return 0;
}
-static int ufshc_link_startup(uintptr_t base)
+static int ufshc_dme_link_startup(uintptr_t base)
{
uic_cmd_t cmd;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.op = DME_LINKSTARTUP;
+ return ufshc_send_uic_cmd(base, &cmd);
+}
+
+static int ufshc_link_startup(uintptr_t base)
+{
int data, result;
int retries;
- for (retries = 10; retries > 0; retries--) {
- memset(&cmd, 0, sizeof(cmd));
- cmd.op = DME_LINKSTARTUP;
- result = ufshc_send_uic_cmd(base, &cmd);
- if (result != 0)
+ for (retries = DME_LINKSTARTUP_RETRIES; retries > 0; retries--) {
+ result = ufshc_dme_link_startup(base);
+ if (result != 0) {
+ /* Reset controller before trying again */
+ result = ufshc_reset(base);
+ if (result != 0) {
+ return result;
+ }
continue;
+ }
while ((mmio_read_32(base + HCS) & HCS_DP) == 0)
;
data = mmio_read_32(base + IS);
@@ -772,7 +823,8 @@ int ufs_init(const ufs_ops_t *ops, ufs_params_t *params)
assert((ops != NULL) && (ops->phy_init != NULL) &&
(ops->phy_set_pwr_mode != NULL));
- ufshc_reset(ufs_params.reg_base);
+ result = ufshc_reset(ufs_params.reg_base);
+ assert(result == 0);
ops->phy_init(&ufs_params);
result = ufshc_link_startup(ufs_params.reg_base);
assert(result == 0);
diff --git a/drivers/usb/usb_device.c b/drivers/usb/usb_device.c
new file mode 100644
index 000000000..031e67846
--- /dev/null
+++ b/drivers/usb/usb_device.c
@@ -0,0 +1,845 @@
+/*
+ * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <drivers/usb_device.h>
+
+/* Define for EP address */
+#define EP_DIR_MASK BIT(7)
+#define EP_DIR_IN BIT(7)
+#define EP_NUM_MASK GENMASK(3, 0)
+
+#define EP0_IN (0U | EP_DIR_IN)
+#define EP0_OUT 0U
+
+/* USB address between 1 through 127 = 0x7F mask */
+#define ADDRESS_MASK GENMASK(6, 0)
+
+/*
+ * Set a STALL condition over an endpoint
+ * pdev: USB handle
+ * ep_addr: endpoint address
+ * return : status
+ */
+static enum usb_status usb_core_set_stall(struct usb_handle *pdev, uint8_t ep_addr)
+{
+ struct usbd_ep *ep;
+ struct pcd_handle *hpcd = (struct pcd_handle *)pdev->data;
+ uint8_t num;
+
+ num = ep_addr & EP_NUM_MASK;
+ if (num >= USBD_EP_NB) {
+ return USBD_FAIL;
+ }
+ if ((EP_DIR_MASK & ep_addr) == EP_DIR_IN) {
+ ep = &hpcd->in_ep[num];
+ ep->is_in = true;
+ } else {
+ ep = &hpcd->out_ep[num];
+ ep->is_in = false;
+ }
+ ep->num = num;
+
+ pdev->driver->ep_set_stall(hpcd->instance, ep);
+ if (num == 0U) {
+ pdev->driver->ep0_out_start(hpcd->instance);
+ }
+
+ return USBD_OK;
+}
+
+/*
+ * usb_core_get_desc
+ * Handle Get Descriptor requests
+ * pdev : device instance
+ * req : usb request
+ */
+static void usb_core_get_desc(struct usb_handle *pdev, struct usb_setup_req *req)
+{
+ uint16_t len;
+ uint8_t *pbuf;
+ uint8_t desc_type = HIBYTE(req->value);
+ uint8_t desc_idx = LOBYTE(req->value);
+
+ switch (desc_type) {
+ case USB_DESC_TYPE_DEVICE:
+ pbuf = pdev->desc->get_device_desc(&len);
+ break;
+
+ case USB_DESC_TYPE_CONFIGURATION:
+ pbuf = pdev->desc->get_config_desc(&len);
+ break;
+
+ case USB_DESC_TYPE_STRING:
+ switch (desc_idx) {
+ case USBD_IDX_LANGID_STR:
+ pbuf = pdev->desc->get_lang_id_desc(&len);
+ break;
+
+ case USBD_IDX_MFC_STR:
+ pbuf = pdev->desc->get_manufacturer_desc(&len);
+ break;
+
+ case USBD_IDX_PRODUCT_STR:
+ pbuf = pdev->desc->get_product_desc(&len);
+ break;
+
+ case USBD_IDX_SERIAL_STR:
+ pbuf = pdev->desc->get_serial_desc(&len);
+ break;
+
+ case USBD_IDX_CONFIG_STR:
+ pbuf = pdev->desc->get_configuration_desc(&len);
+ break;
+
+ case USBD_IDX_INTERFACE_STR:
+ pbuf = pdev->desc->get_interface_desc(&len);
+ break;
+
+ /* For all USER string */
+ case USBD_IDX_USER0_STR:
+ default:
+ pbuf = pdev->desc->get_usr_desc(desc_idx - USBD_IDX_USER0_STR, &len);
+ break;
+ }
+ break;
+
+ case USB_DESC_TYPE_DEVICE_QUALIFIER:
+ pbuf = pdev->desc->get_device_qualifier_desc(&len);
+ break;
+
+ case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
+ if (pdev->desc->get_other_speed_config_desc == NULL) {
+ usb_core_ctl_error(pdev);
+ return;
+ }
+ pbuf = pdev->desc->get_other_speed_config_desc(&len);
+ break;
+
+ default:
+ ERROR("Unknown request %i\n", desc_type);
+ usb_core_ctl_error(pdev);
+ return;
+ }
+
+ if ((len != 0U) && (req->length != 0U)) {
+ len = MIN(len, req->length);
+
+ /* Start the transfer */
+ usb_core_transmit_ep0(pdev, pbuf, len);
+ }
+}
+
+/*
+ * usb_core_set_config
+ * Handle Set device configuration request
+ * pdev : device instance
+ * req : usb request
+ */
+static void usb_core_set_config(struct usb_handle *pdev, struct usb_setup_req *req)
+{
+ static uint8_t cfgidx;
+
+ cfgidx = LOBYTE(req->value);
+
+ if (cfgidx > USBD_MAX_NUM_CONFIGURATION) {
+ usb_core_ctl_error(pdev);
+ return;
+ }
+
+ switch (pdev->dev_state) {
+ case USBD_STATE_ADDRESSED:
+ if (cfgidx != 0U) {
+ pdev->dev_config = cfgidx;
+ pdev->dev_state = USBD_STATE_CONFIGURED;
+ if (!pdev->class) {
+ usb_core_ctl_error(pdev);
+ return;
+ }
+ /* Set configuration and Start the Class */
+ if (pdev->class->init(pdev, cfgidx) != 0U) {
+ usb_core_ctl_error(pdev);
+ return;
+ }
+ }
+ break;
+
+ case USBD_STATE_CONFIGURED:
+ if (cfgidx == 0U) {
+ pdev->dev_state = USBD_STATE_ADDRESSED;
+ pdev->dev_config = cfgidx;
+ pdev->class->de_init(pdev, cfgidx);
+ } else if (cfgidx != pdev->dev_config) {
+ if (pdev->class == NULL) {
+ usb_core_ctl_error(pdev);
+ return;
+ }
+ /* Clear old configuration */
+ pdev->class->de_init(pdev, pdev->dev_config);
+ /* Set new configuration */
+ pdev->dev_config = cfgidx;
+ /* Set configuration and start the USB class */
+ if (pdev->class->init(pdev, cfgidx) != 0U) {
+ usb_core_ctl_error(pdev);
+ return;
+ }
+ }
+ break;
+
+ default:
+ usb_core_ctl_error(pdev);
+ return;
+ }
+
+ /* Send status */
+ usb_core_transmit_ep0(pdev, NULL, 0U);
+}
+
+/*
+ * usb_core_get_status
+ * Handle Get Status request
+ * pdev : device instance
+ * req : usb request
+ */
+static void usb_core_get_status(struct usb_handle *pdev,
+ struct usb_setup_req *req)
+{
+ if ((pdev->dev_state != USBD_STATE_ADDRESSED) &&
+ (pdev->dev_state != USBD_STATE_CONFIGURED)) {
+ usb_core_ctl_error(pdev);
+ return;
+ }
+
+ pdev->dev_config_status = USB_CONFIG_SELF_POWERED;
+
+ if (pdev->dev_remote_wakeup != 0U) {
+ pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP;
+ }
+
+ /* Start the transfer */
+ usb_core_transmit_ep0(pdev, (uint8_t *)&pdev->dev_config_status, 2U);
+}
+
+/*
+ * usb_core_set_address
+ * Set device address
+ * pdev : device instance
+ * req : usb request
+ */
+static void usb_core_set_address(struct usb_handle *pdev,
+ struct usb_setup_req *req)
+{
+ uint8_t dev_addr;
+
+ if ((req->index != 0U) || (req->length != 0U)) {
+ usb_core_ctl_error(pdev);
+ return;
+ }
+
+ dev_addr = req->value & ADDRESS_MASK;
+ if (pdev->dev_state != USBD_STATE_DEFAULT) {
+ usb_core_ctl_error(pdev);
+ return;
+ }
+
+ pdev->dev_address = dev_addr;
+ pdev->driver->set_address(((struct pcd_handle *)(pdev->data))->instance, dev_addr);
+
+ /* Send status */
+ usb_core_transmit_ep0(pdev, NULL, 0U);
+
+ if (dev_addr != 0U) {
+ pdev->dev_state = USBD_STATE_ADDRESSED;
+ } else {
+ pdev->dev_state = USBD_STATE_DEFAULT;
+ }
+}
+
+/*
+ * usb_core_dev_req
+ * Handle standard usb device requests
+ * pdev : device instance
+ * req : usb request
+ * return : status
+ */
+static enum usb_status usb_core_dev_req(struct usb_handle *pdev,
+ struct usb_setup_req *req)
+{
+ VERBOSE("receive request %i\n", req->b_request);
+ switch (req->b_request) {
+ case USB_REQ_GET_DESCRIPTOR:
+ usb_core_get_desc(pdev, req);
+ break;
+
+ case USB_REQ_SET_CONFIGURATION:
+ usb_core_set_config(pdev, req);
+ break;
+
+ case USB_REQ_GET_STATUS:
+ usb_core_get_status(pdev, req);
+ break;
+
+ case USB_REQ_SET_ADDRESS:
+ usb_core_set_address(pdev, req);
+ break;
+
+ case USB_REQ_GET_CONFIGURATION:
+ case USB_REQ_SET_FEATURE:
+ case USB_REQ_CLEAR_FEATURE:
+ default:
+ ERROR("NOT SUPPORTED %i\n", req->b_request);
+ usb_core_ctl_error(pdev);
+ break;
+ }
+
+ return USBD_OK;
+}
+
+/*
+ * usb_core_itf_req
+ * Handle standard usb interface requests
+ * pdev : device instance
+ * req : usb request
+ * return : status
+ */
+static enum usb_status usb_core_itf_req(struct usb_handle *pdev,
+ struct usb_setup_req *req)
+{
+ if (pdev->dev_state != USBD_STATE_CONFIGURED) {
+ usb_core_ctl_error(pdev);
+ return USBD_OK;
+ }
+
+ if (LOBYTE(req->index) <= USBD_MAX_NUM_INTERFACES) {
+ pdev->class->setup(pdev, req);
+
+ if (req->length == 0U) {
+ usb_core_transmit_ep0(pdev, NULL, 0U);
+ }
+ } else {
+ usb_core_ctl_error(pdev);
+ }
+
+ return USBD_OK;
+}
+
+/*
+ * usb_core_setup_stage
+ * Handle the setup stage
+ * pdev: device instance
+ * psetup : setup buffer
+ * return : status
+ */
+static enum usb_status usb_core_setup_stage(struct usb_handle *pdev,
+ uint8_t *psetup)
+{
+ struct usb_setup_req *req = &pdev->request;
+
+ /* Copy setup buffer into req structure */
+ req->bm_request = psetup[0];
+ req->b_request = psetup[1];
+ req->value = psetup[2] + (psetup[3] << 8);
+ req->index = psetup[4] + (psetup[5] << 8);
+ req->length = psetup[6] + (psetup[7] << 8);
+
+ pdev->ep0_state = USBD_EP0_SETUP;
+ pdev->ep0_data_len = pdev->request.length;
+
+ switch (pdev->request.bm_request & USB_REQ_RECIPIENT_MASK) {
+ case USB_REQ_RECIPIENT_DEVICE:
+ usb_core_dev_req(pdev, &pdev->request);
+ break;
+
+ case USB_REQ_RECIPIENT_INTERFACE:
+ usb_core_itf_req(pdev, &pdev->request);
+ break;
+
+ case USB_REQ_RECIPIENT_ENDPOINT:
+ default:
+ ERROR("receive unsupported request %i",
+ pdev->request.bm_request & USB_REQ_RECIPIENT_MASK);
+ usb_core_set_stall(pdev, pdev->request.bm_request & USB_REQ_DIRECTION);
+ return USBD_FAIL;
+ }
+
+ return USBD_OK;
+}
+
+/*
+ * usb_core_data_out
+ * Handle data OUT stage
+ * pdev: device instance
+ * epnum: endpoint index
+ * pdata: buffer to sent
+ * return : status
+ */
+static enum usb_status usb_core_data_out(struct usb_handle *pdev, uint8_t epnum,
+ uint8_t *pdata)
+{
+ struct usb_endpoint *pep;
+
+ if (epnum == 0U) {
+ pep = &pdev->ep_out[0];
+ if (pdev->ep0_state == USBD_EP0_DATA_OUT) {
+ if (pep->rem_length > pep->maxpacket) {
+ pep->rem_length -= pep->maxpacket;
+
+ usb_core_receive(pdev, 0U, pdata,
+ MIN(pep->rem_length,
+ pep->maxpacket));
+ } else {
+ if (pdev->class->ep0_rx_ready &&
+ (pdev->dev_state == USBD_STATE_CONFIGURED)) {
+ pdev->class->ep0_rx_ready(pdev);
+ }
+
+ usb_core_transmit_ep0(pdev, NULL, 0U);
+ }
+ }
+ } else if (pdev->class->data_out != NULL &&
+ (pdev->dev_state == USBD_STATE_CONFIGURED)) {
+ pdev->class->data_out(pdev, epnum);
+ }
+
+ return USBD_OK;
+}
+
+/*
+ * usb_core_data_in
+ * Handle data in stage
+ * pdev: device instance
+ * epnum: endpoint index
+ * pdata: buffer to fill
+ * return : status
+ */
+static enum usb_status usb_core_data_in(struct usb_handle *pdev, uint8_t epnum,
+ uint8_t *pdata)
+{
+ if (epnum == 0U) {
+ struct usb_endpoint *pep = &pdev->ep_in[0];
+
+ if (pdev->ep0_state == USBD_EP0_DATA_IN) {
+ if (pep->rem_length > pep->maxpacket) {
+ pep->rem_length -= pep->maxpacket;
+
+ usb_core_transmit(pdev, 0U, pdata,
+ pep->rem_length);
+
+ /* Prepare EP for premature end of transfer */
+ usb_core_receive(pdev, 0U, NULL, 0U);
+ } else {
+ /* Last packet is MPS multiple, send ZLP packet */
+ if ((pep->total_length % pep->maxpacket == 0U) &&
+ (pep->total_length >= pep->maxpacket) &&
+ (pep->total_length < pdev->ep0_data_len)) {
+ usb_core_transmit(pdev, 0U, NULL, 0U);
+
+ pdev->ep0_data_len = 0U;
+
+ /* Prepare endpoint for premature end of transfer */
+ usb_core_receive(pdev, 0U, NULL, 0U);
+ } else {
+ if (pdev->class->ep0_tx_sent != NULL &&
+ (pdev->dev_state ==
+ USBD_STATE_CONFIGURED)) {
+ pdev->class->ep0_tx_sent(pdev);
+ }
+ /* Start the transfer */
+ usb_core_receive_ep0(pdev, NULL, 0U);
+ }
+ }
+ }
+ } else if ((pdev->class->data_in != NULL) &&
+ (pdev->dev_state == USBD_STATE_CONFIGURED)) {
+ pdev->class->data_in(pdev, epnum);
+ }
+
+ return USBD_OK;
+}
+
+/*
+ * usb_core_suspend
+ * Handle suspend event
+ * pdev : device instance
+ * return : status
+ */
+static enum usb_status usb_core_suspend(struct usb_handle *pdev)
+{
+ INFO("USB Suspend mode\n");
+ pdev->dev_old_state = pdev->dev_state;
+ pdev->dev_state = USBD_STATE_SUSPENDED;
+
+ return USBD_OK;
+}
+
+/*
+ * usb_core_resume
+ * Handle resume event
+ * pdev : device instance
+ * return : status
+ */
+static enum usb_status usb_core_resume(struct usb_handle *pdev)
+{
+ INFO("USB Resume\n");
+ pdev->dev_state = pdev->dev_old_state;
+
+ return USBD_OK;
+}
+
+/*
+ * usb_core_sof
+ * Handle SOF event
+ * pdev : device instance
+ * return : status
+ */
+static enum usb_status usb_core_sof(struct usb_handle *pdev)
+{
+ if (pdev->dev_state == USBD_STATE_CONFIGURED) {
+ if (pdev->class->sof != NULL) {
+ pdev->class->sof(pdev);
+ }
+ }
+
+ return USBD_OK;
+}
+
+/*
+ * usb_core_disconnect
+ * Handle device disconnection event
+ * pdev : device instance
+ * return : status
+ */
+static enum usb_status usb_core_disconnect(struct usb_handle *pdev)
+{
+ /* Free class resources */
+ pdev->dev_state = USBD_STATE_DEFAULT;
+ pdev->class->de_init(pdev, pdev->dev_config);
+
+ return USBD_OK;
+}
+
+enum usb_status usb_core_handle_it(struct usb_handle *pdev)
+{
+ uint32_t param = 0U;
+ uint32_t len = 0U;
+ struct usbd_ep *ep;
+
+ switch (pdev->driver->it_handler(pdev->data->instance, &param)) {
+ case USB_DATA_OUT:
+ usb_core_data_out(pdev, param,
+ pdev->data->out_ep[param].xfer_buff);
+ break;
+
+ case USB_DATA_IN:
+ usb_core_data_in(pdev, param,
+ pdev->data->in_ep[param].xfer_buff);
+ break;
+
+ case USB_SETUP:
+ usb_core_setup_stage(pdev, (uint8_t *)pdev->data->setup);
+ break;
+
+ case USB_ENUM_DONE:
+ break;
+
+ case USB_READ_DATA_PACKET:
+ ep = &pdev->data->out_ep[param & USBD_OUT_EPNUM_MASK];
+ len = (param & USBD_OUT_COUNT_MASK) >> USBD_OUT_COUNT_SHIFT;
+ pdev->driver->read_packet(pdev->data->instance,
+ ep->xfer_buff, len);
+ ep->xfer_buff += len;
+ ep->xfer_count += len;
+ break;
+
+ case USB_READ_SETUP_PACKET:
+ ep = &pdev->data->out_ep[param & USBD_OUT_EPNUM_MASK];
+ len = (param & USBD_OUT_COUNT_MASK) >> 0x10;
+ pdev->driver->read_packet(pdev->data->instance,
+ (uint8_t *)pdev->data->setup, 8);
+ ep->xfer_count += len;
+ break;
+
+ case USB_RESET:
+ pdev->dev_state = USBD_STATE_DEFAULT;
+ break;
+
+ case USB_RESUME:
+ if (pdev->data->lpm_state == LPM_L1) {
+ pdev->data->lpm_state = LPM_L0;
+ } else {
+ usb_core_resume(pdev);
+ }
+ break;
+
+ case USB_SUSPEND:
+ usb_core_suspend(pdev);
+ break;
+
+ case USB_LPM:
+ if (pdev->data->lpm_state == LPM_L0) {
+ pdev->data->lpm_state = LPM_L1;
+ } else {
+ usb_core_suspend(pdev);
+ }
+ break;
+
+ case USB_SOF:
+ usb_core_sof(pdev);
+ break;
+
+ case USB_DISCONNECT:
+ usb_core_disconnect(pdev);
+ break;
+
+ case USB_WRITE_EMPTY:
+ pdev->driver->write_empty_tx_fifo(pdev->data->instance, param,
+ pdev->data->in_ep[param].xfer_len,
+ (uint32_t *)&pdev->data->in_ep[param].xfer_count,
+ pdev->data->in_ep[param].maxpacket,
+ &pdev->data->in_ep[param].xfer_buff);
+ break;
+
+ case USB_NOTHING:
+ default:
+ break;
+ }
+
+ return USBD_OK;
+}
+
+static void usb_core_start_xfer(struct usb_handle *pdev,
+ void *handle,
+ struct usbd_ep *ep)
+{
+ if (ep->num == 0U) {
+ pdev->driver->ep0_start_xfer(handle, ep);
+ } else {
+ pdev->driver->ep_start_xfer(handle, ep);
+ }
+}
+
+/*
+ * usb_core_receive
+ * Receive an amount of data
+ * pdev: USB handle
+ * ep_addr: endpoint address
+ * buf: pointer to the reception buffer
+ * len: amount of data to be received
+ * return : status
+ */
+enum usb_status usb_core_receive(struct usb_handle *pdev, uint8_t ep_addr,
+ uint8_t *buf, uint32_t len)
+{
+ struct usbd_ep *ep;
+ struct pcd_handle *hpcd = (struct pcd_handle *)pdev->data;
+ uint8_t num;
+
+ num = ep_addr & EP_NUM_MASK;
+ if (num >= USBD_EP_NB) {
+ return USBD_FAIL;
+ }
+ ep = &hpcd->out_ep[num];
+
+ /* Setup and start the Xfer */
+ ep->xfer_buff = buf;
+ ep->xfer_len = len;
+ ep->xfer_count = 0U;
+ ep->is_in = false;
+ ep->num = num;
+
+ usb_core_start_xfer(pdev, hpcd->instance, ep);
+
+ return USBD_OK;
+}
+
+/*
+ * usb_core_transmit
+ * Send an amount of data
+ * pdev: USB handle
+ * ep_addr: endpoint address
+ * buf: pointer to the transmission buffer
+ * len: amount of data to be sent
+ * return : status
+ */
+enum usb_status usb_core_transmit(struct usb_handle *pdev, uint8_t ep_addr,
+ uint8_t *buf, uint32_t len)
+{
+ struct usbd_ep *ep;
+ struct pcd_handle *hpcd = (struct pcd_handle *)pdev->data;
+ uint8_t num;
+
+ num = ep_addr & EP_NUM_MASK;
+ if (num >= USBD_EP_NB) {
+ return USBD_FAIL;
+ }
+ ep = &hpcd->in_ep[num];
+
+ /* Setup and start the Xfer */
+ ep->xfer_buff = buf;
+ ep->xfer_len = len;
+ ep->xfer_count = 0U;
+ ep->is_in = true;
+ ep->num = num;
+
+ usb_core_start_xfer(pdev, hpcd->instance, ep);
+
+ return USBD_OK;
+}
+
+/*
+ * usb_core_receive_ep0
+ * Receive an amount of data on ep0
+ * pdev: USB handle
+ * buf: pointer to the reception buffer
+ * len: amount of data to be received
+ * return : status
+ */
+enum usb_status usb_core_receive_ep0(struct usb_handle *pdev, uint8_t *buf,
+ uint32_t len)
+{
+ /* Prepare the reception of the buffer over EP0 */
+ if (len != 0U) {
+ pdev->ep0_state = USBD_EP0_DATA_OUT;
+ } else {
+ pdev->ep0_state = USBD_EP0_STATUS_OUT;
+ }
+
+ pdev->ep_out[0].total_length = len;
+ pdev->ep_out[0].rem_length = len;
+
+ /* Start the transfer */
+ return usb_core_receive(pdev, 0U, buf, len);
+}
+
+/*
+ * usb_core_transmit_ep0
+ * Send an amount of data on ep0
+ * pdev: USB handle
+ * buf: pointer to the transmission buffer
+ * len: amount of data to be sent
+ * return : status
+ */
+enum usb_status usb_core_transmit_ep0(struct usb_handle *pdev, uint8_t *buf,
+ uint32_t len)
+{
+ /* Set EP0 State */
+ if (len != 0U) {
+ pdev->ep0_state = USBD_EP0_DATA_IN;
+ } else {
+ pdev->ep0_state = USBD_EP0_STATUS_IN;
+ }
+
+ pdev->ep_in[0].total_length = len;
+ pdev->ep_in[0].rem_length = len;
+
+ /* Start the transfer */
+ return usb_core_transmit(pdev, 0U, buf, len);
+}
+
+/*
+ * usb_core_ctl_error
+ * Handle USB low level error
+ * pdev: device instance
+ * req: usb request
+ * return : None
+ */
+
+void usb_core_ctl_error(struct usb_handle *pdev)
+{
+ ERROR("%s : Send an ERROR\n", __func__);
+ usb_core_set_stall(pdev, EP0_IN);
+ usb_core_set_stall(pdev, EP0_OUT);
+}
+
+/*
+ * usb_core_start
+ * Start the USB device core.
+ * pdev: Device Handle
+ * return : USBD Status
+ */
+enum usb_status usb_core_start(struct usb_handle *pdev)
+{
+ /* Start the low level driver */
+ pdev->driver->start_device(pdev->data->instance);
+
+ return USBD_OK;
+}
+
+/*
+ * usb_core_stop
+ * Stop the USB device core.
+ * pdev: Device Handle
+ * return : USBD Status
+ */
+enum usb_status usb_core_stop(struct usb_handle *pdev)
+{
+ /* Free class resources */
+ pdev->class->de_init(pdev, pdev->dev_config);
+
+ /* Stop the low level driver */
+ pdev->driver->stop_device(pdev->data->instance);
+
+ return USBD_OK;
+}
+
+/*
+ * register_usb_driver
+ * Stop the USB device core.
+ * pdev: Device Handle
+ * pcd_handle: PCD handle
+ * driver: USB driver
+ * driver_handle: USB driver handle
+ * return : USBD Status
+ */
+enum usb_status register_usb_driver(struct usb_handle *pdev,
+ struct pcd_handle *pcd_handle,
+ const struct usb_driver *driver,
+ void *driver_handle)
+{
+ uint8_t i;
+
+ assert(pdev != NULL);
+ assert(pcd_handle != NULL);
+ assert(driver != NULL);
+ assert(driver_handle != NULL);
+
+ /* Free class resources */
+ pdev->driver = driver;
+ pdev->data = pcd_handle;
+ pdev->data->instance = driver_handle;
+ pdev->dev_state = USBD_STATE_DEFAULT;
+ pdev->ep0_state = USBD_EP0_IDLE;
+
+ /* Copy endpoint information */
+ for (i = 0U; i < USBD_EP_NB; i++) {
+ pdev->ep_in[i].maxpacket = pdev->data->in_ep[i].maxpacket;
+ pdev->ep_out[i].maxpacket = pdev->data->out_ep[i].maxpacket;
+ }
+
+ return USBD_OK;
+}
+
+/*
+ * register_platform
+ * Register the USB device core.
+ * pdev: Device Handle
+ * plat_call_back: callback
+ * return : USBD Status
+ */
+enum usb_status register_platform(struct usb_handle *pdev,
+ const struct usb_desc *plat_call_back)
+{
+ assert(pdev != NULL);
+ assert(plat_call_back != NULL);
+
+ /* Save platform info in class resources */
+ pdev->desc = plat_call_back;
+
+ return USBD_OK;
+}