diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/arm/gic/v3/gicv3_helpers.c | 64 | ||||
-rw-r--r-- | drivers/arm/gic/v3/gicv3_main.c | 56 | ||||
-rw-r--r-- | drivers/arm/gic/v3/gicv3_private.h | 2 | ||||
-rw-r--r-- | drivers/marvell/comphy/phy-comphy-3700.c | 24 | ||||
-rw-r--r-- | drivers/marvell/comphy/phy-comphy-cp110.c | 22 | ||||
-rw-r--r-- | drivers/mmc/mmc.c | 76 | ||||
-rw-r--r-- | drivers/st/io/io_mmc.c | 13 |
7 files changed, 148 insertions, 109 deletions
diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c index 6bb66a02b6..a0f44e9666 100644 --- a/drivers/arm/gic/v3/gicv3_helpers.c +++ b/drivers/arm/gic/v3/gicv3_helpers.c @@ -92,6 +92,47 @@ void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs, } /******************************************************************************* + * Helper function to get the maximum SPI INTID + 1. + ******************************************************************************/ +unsigned int gicv3_get_spi_limit(uintptr_t gicd_base) +{ + unsigned int spi_limit; + unsigned int typer_reg = gicd_read_typer(gicd_base); + + /* (maximum SPI INTID + 1) is equal to 32 * (GICD_TYPER.ITLinesNumber+1) */ + spi_limit = ((typer_reg & TYPER_IT_LINES_NO_MASK) + 1U) << 5; + + /* Filter out special INTIDs 1020-1023 */ + if (spi_limit > (MAX_SPI_ID + 1U)) { + return MAX_SPI_ID + 1U; + } + + return spi_limit; +} + +#if GIC_EXT_INTID +/******************************************************************************* + * Helper function to get the maximum ESPI INTID + 1. + ******************************************************************************/ +unsigned int gicv3_get_espi_limit(uintptr_t gicd_base) +{ + unsigned int typer_reg = gicd_read_typer(gicd_base); + + /* Check if extended SPI range is implemented */ + if ((typer_reg & TYPER_ESPI) != 0U) { + /* + * (maximum ESPI INTID + 1) is equal to + * 32 * (GICD_TYPER.ESPI_range + 1) + 4096 + */ + return ((((typer_reg >> TYPER_ESPI_RANGE_SHIFT) & + TYPER_ESPI_RANGE_MASK) + 1U) << 5) + MIN_ESPI_ID; + } + + return 0U; +} +#endif /* GIC_EXT_INTID */ + +/******************************************************************************* * Helper function to configure the default attributes of (E)SPIs. ******************************************************************************/ void gicv3_spis_config_defaults(uintptr_t gicd_base) @@ -100,19 +141,8 @@ void gicv3_spis_config_defaults(uintptr_t gicd_base) #if GIC_EXT_INTID unsigned int num_eints; #endif - unsigned int typer_reg = gicd_read_typer(gicd_base); - - /* Maximum SPI INTID is 32 * (GICD_TYPER.ITLinesNumber + 1) - 1 */ - num_ints = ((typer_reg & TYPER_IT_LINES_NO_MASK) + 1U) << 5; - /* - * The GICv3 architecture allows GICD_TYPER.ITLinesNumber to be 31, so - * the maximum possible value for num_ints is 1024. Limit the value to - * MAX_SPI_ID + 1 to avoid getting wrong address in GICD_OFFSET() macro. - */ - if (num_ints > MAX_SPI_ID + 1U) { - num_ints = MAX_SPI_ID + 1U; - } + num_ints = gicv3_get_spi_limit(gicd_base); INFO("Maximum SPI INTID supported: %u\n", num_ints - 1); /* Treat all (E)SPIs as G1NS by default. We do 32 at a time. */ @@ -121,13 +151,8 @@ void gicv3_spis_config_defaults(uintptr_t gicd_base) } #if GIC_EXT_INTID - /* Check if extended SPI range is implemented */ - if ((typer_reg & TYPER_ESPI) != 0U) { - /* - * Maximum ESPI INTID is 32 * (GICD_TYPER.ESPI_range + 1) + 4095 - */ - num_eints = ((((typer_reg >> TYPER_ESPI_RANGE_SHIFT) & - TYPER_ESPI_RANGE_MASK) + 1U) << 5) + MIN_ESPI_ID; + num_eints = gicv3_get_espi_limit(gicd_base); + if (num_eints != 0U) { INFO("Maximum ESPI INTID supported: %u\n", num_eints - 1); for (i = MIN_ESPI_ID; i < num_eints; @@ -135,7 +160,6 @@ void gicv3_spis_config_defaults(uintptr_t gicd_base) gicd_write_igroupr(gicd_base, i, ~0U); } } else { - num_eints = 0U; INFO("ESPI range is not implemented.\n"); } #endif diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index 5a49b4f5ed..668416cb59 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -728,40 +728,17 @@ void gicv3_rdistif_init_restore(unsigned int proc_num, *****************************************************************************/ void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx) { - unsigned int typer_reg, num_ints; -#if GIC_EXT_INTID - unsigned int num_eints; -#endif - assert(gicv3_driver_data != NULL); assert(gicv3_driver_data->gicd_base != 0U); assert(IS_IN_EL3()); assert(dist_ctx != NULL); uintptr_t gicd_base = gicv3_driver_data->gicd_base; - - typer_reg = gicd_read_typer(gicd_base); - - /* Maximum SPI INTID is 32 * (GICD_TYPER.ITLinesNumber + 1) - 1 */ - num_ints = ((typer_reg & TYPER_IT_LINES_NO_MASK) + 1U) << 5; - - /* Filter out special INTIDs 1020-1023 */ - if (num_ints > (MAX_SPI_ID + 1U)) { - num_ints = MAX_SPI_ID + 1U; - } - + unsigned int num_ints = gicv3_get_spi_limit(gicd_base); #if GIC_EXT_INTID - /* Check if extended SPI range is implemented */ - if ((typer_reg & TYPER_ESPI) != 0U) { - /* - * Maximum ESPI INTID is 32 * (GICD_TYPER.ESPI_range + 1) + 4095 - */ - num_eints = ((((typer_reg >> TYPER_ESPI_RANGE_SHIFT) & - TYPER_ESPI_RANGE_MASK) + 1U) << 5) + MIN_ESPI_ID; - } else { - num_eints = 0U; - } + unsigned int num_eints = gicv3_get_espi_limit(gicd_base); #endif + /* Wait for pending write to complete */ gicd_wait_for_pending_write(gicd_base); @@ -838,11 +815,6 @@ void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx) *****************************************************************************/ void gicv3_distif_init_restore(const gicv3_dist_ctx_t * const dist_ctx) { - unsigned int typer_reg, num_ints; -#if GIC_EXT_INTID - unsigned int num_eints; -#endif - assert(gicv3_driver_data != NULL); assert(gicv3_driver_data->gicd_base != 0U); assert(IS_IN_EL3()); @@ -864,27 +836,9 @@ void gicv3_distif_init_restore(const gicv3_dist_ctx_t * const dist_ctx) /* Set the ARE_S and ARE_NS bit now that interrupts have been disabled */ gicd_set_ctlr(gicd_base, CTLR_ARE_S_BIT | CTLR_ARE_NS_BIT, RWP_TRUE); - typer_reg = gicd_read_typer(gicd_base); - - /* Maximum SPI INTID is 32 * (GICD_TYPER.ITLinesNumber + 1) - 1 */ - num_ints = ((typer_reg & TYPER_IT_LINES_NO_MASK) + 1U) << 5; - - /* Filter out special INTIDs 1020-1023 */ - if (num_ints > (MAX_SPI_ID + 1U)) { - num_ints = MAX_SPI_ID + 1U; - } - + unsigned int num_ints = gicv3_get_spi_limit(gicd_base); #if GIC_EXT_INTID - /* Check if extended SPI range is implemented */ - if ((typer_reg & TYPER_ESPI) != 0U) { - /* - * Maximum ESPI INTID is 32 * (GICD_TYPER.ESPI_range + 1) + 4095 - */ - num_eints = ((((typer_reg >> TYPER_ESPI_RANGE_SHIFT) & - TYPER_ESPI_RANGE_MASK) + 1U) << 5) + MIN_ESPI_ID; - } else { - num_eints = 0U; - } + unsigned int num_eints = gicv3_get_espi_limit(gicd_base); #endif /* Restore GICD_IGROUPR for INTIDs 32 - 1019 */ RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, igroupr, IGROUP); diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h index 416cdd0183..93ee1a18de 100644 --- a/drivers/arm/gic/v3/gicv3_private.h +++ b/drivers/arm/gic/v3/gicv3_private.h @@ -233,6 +233,8 @@ void gicr_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg); /******************************************************************************* * Private GICv3 helper function prototypes ******************************************************************************/ +unsigned int gicv3_get_spi_limit(uintptr_t gicd_base); +unsigned int gicv3_get_espi_limit(uintptr_t gicd_base); void gicv3_spis_config_defaults(uintptr_t gicd_base); void gicv3_ppi_sgi_config_defaults(uintptr_t gicr_base); unsigned int gicv3_secure_ppi_sgi_config_props(uintptr_t gicr_base, diff --git a/drivers/marvell/comphy/phy-comphy-3700.c b/drivers/marvell/comphy/phy-comphy-3700.c index 02fe97c2ad..7377e5e3d9 100644 --- a/drivers/marvell/comphy/phy-comphy-3700.c +++ b/drivers/marvell/comphy/phy-comphy-3700.c @@ -14,6 +14,7 @@ #include <mvebu.h> #include <mvebu_def.h> +#include <plat_marvell.h> #include "phy-comphy-3700.h" #include "phy-comphy-common.h" @@ -29,15 +30,6 @@ #define USB3_GBE1_PHY (MVEBU_REGS_BASE + 0x5C000) #define COMPHY_SD_ADDR (MVEBU_REGS_BASE + 0x1F000) -/* - * Below address in used only for reading, therefore no problem with concurrent - * Linux access. - */ -#define MVEBU_TEST_PIN_LATCH_N (MVEBU_NB_GPIO_REG_BASE + 0x8) - #define MVEBU_XTAL_MODE_MASK BIT(9) - #define MVEBU_XTAL_MODE_OFFS 9 - #define MVEBU_XTAL_CLOCK_25MHZ 0x0 - struct sgmii_phy_init_data_fix { uint16_t addr; uint16_t value; @@ -125,20 +117,6 @@ static uint16_t sgmii_phy_init[512] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /*1F8 */ }; -/* returns reference clock in MHz (25 or 40) */ -static uint32_t get_ref_clk(void) -{ - uint32_t val; - - val = (mmio_read_32(MVEBU_TEST_PIN_LATCH_N) & MVEBU_XTAL_MODE_MASK) >> - MVEBU_XTAL_MODE_OFFS; - - if (val == MVEBU_XTAL_CLOCK_25MHZ) - return 25; - else - return 40; -} - /* PHY selector configures with corresponding modes */ static void mvebu_a3700_comphy_set_phy_selector(uint8_t comphy_index, uint32_t comphy_mode) diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c index c8ba9b8d34..86f4c77c5e 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.c +++ b/drivers/marvell/comphy/phy-comphy-cp110.c @@ -53,13 +53,13 @@ #define SYS_CTRL_FROM_COMPHY_ADDR(x) ((x & ~0xffffff) + 0x440000) /* DFX register spaces */ -#define SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET (0) -#define SAR_RST_PCIE0_CLOCK_CONFIG_CP1_MASK (0x1 << \ - SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET) -#define SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET (1) -#define SAR_RST_PCIE1_CLOCK_CONFIG_CP1_MASK (0x1 << \ - SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET) -#define SAR_STATUS_0_REG 200 +#define SAR_RST_PCIE0_CLOCK_CONFIG_CP0_OFFSET (30) +#define SAR_RST_PCIE0_CLOCK_CONFIG_CP0_MASK (0x1UL << \ + SAR_RST_PCIE0_CLOCK_CONFIG_CP0_OFFSET) +#define SAR_RST_PCIE1_CLOCK_CONFIG_CP0_OFFSET (31) +#define SAR_RST_PCIE1_CLOCK_CONFIG_CP0_MASK (0x1UL << \ + SAR_RST_PCIE1_CLOCK_CONFIG_CP0_OFFSET) +#define SAR_STATUS_0_REG 0x40600 #define DFX_FROM_COMPHY_ADDR(x) ((x & ~0xffffff) + DFX_BASE) /* Common Phy training */ #define COMPHY_TRX_TRAIN_COMPHY_OFFS 0x1000 @@ -1318,11 +1318,11 @@ static int mvebu_cp110_comphy_pcie_power_on(uint64_t comphy_base, reg = mmio_read_32(DFX_FROM_COMPHY_ADDR(comphy_base) + SAR_STATUS_0_REG); if (comphy_index == COMPHY_LANE4 || comphy_index == COMPHY_LANE5) - clk_dir = (reg & SAR_RST_PCIE1_CLOCK_CONFIG_CP1_MASK) >> - SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET; + clk_dir = (reg & SAR_RST_PCIE1_CLOCK_CONFIG_CP0_MASK) >> + SAR_RST_PCIE1_CLOCK_CONFIG_CP0_OFFSET; else - clk_dir = (reg & SAR_RST_PCIE0_CLOCK_CONFIG_CP1_MASK) >> - SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET; + clk_dir = (reg & SAR_RST_PCIE0_CLOCK_CONFIG_CP0_MASK) >> + SAR_RST_PCIE0_CLOCK_CONFIG_CP0_OFFSET; debug("On lane %d\n", comphy_index); debug("PCIe clock direction = %x\n", clk_dir); diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index e288d47edb..c327e71d20 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -105,6 +105,36 @@ static int mmc_device_state(void) return MMC_GET_STATE(resp_data[0]); } +static int mmc_send_part_switch_cmd(unsigned int part_config) +{ + int ret; + unsigned int part_time = 0; + + ret = mmc_send_cmd(MMC_CMD(6), + EXTCSD_WRITE_BYTES | + EXTCSD_CMD(CMD_EXTCSD_PARTITION_CONFIG) | + EXTCSD_VALUE(part_config) | + EXTCSD_CMD_SET_NORMAL, + MMC_RESPONSE_R1B, NULL); + if (ret != 0) { + return ret; + } + + /* Partition switch timing is in 10ms units */ + part_time = mmc_ext_csd[CMD_EXTCSD_PART_SWITCH_TIME] * 10; + + mdelay(part_time); + + do { + ret = mmc_device_state(); + if (ret < 0) { + return ret; + } + } while (ret == MMC_STATE_PRG); + + return 0; +} + static int mmc_set_ext_csd(unsigned int ext_cmd, unsigned int value) { int ret; @@ -668,7 +698,7 @@ static inline void mmc_rpmb_enable(void) { mmc_set_ext_csd(CMD_EXTCSD_PARTITION_CONFIG, PART_CFG_BOOT_PARTITION1_ENABLE | - PART_CFG_PARTITION1_ACCESS); + PART_CFG_BOOT_PARTITION1_ACCESS); } static inline void mmc_rpmb_disable(void) @@ -710,6 +740,50 @@ size_t mmc_rpmb_erase_blocks(int lba, size_t size) return size_erased; } +static int mmc_part_switch(unsigned int part_type) +{ + uint8_t part_config = mmc_ext_csd[CMD_EXTCSD_PARTITION_CONFIG]; + + part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK; + part_config |= part_type; + + return mmc_send_part_switch_cmd(part_config); +} + +static unsigned char mmc_current_boot_part(void) +{ + return PART_CFG_CURRENT_BOOT_PARTITION(mmc_ext_csd[CMD_EXTCSD_PARTITION_CONFIG]); +} + +size_t mmc_boot_part_read_blocks(int lba, uintptr_t buf, size_t size) +{ + size_t size_read; + int ret; + unsigned char current_boot_part = mmc_current_boot_part(); + + if (current_boot_part != 1U && + current_boot_part != 2U) { + ERROR("Got unexpected value for active boot partition, %u\n", current_boot_part); + return 0; + } + + ret = mmc_part_switch(current_boot_part); + if (ret < 0) { + ERROR("Failed to switch to boot partition, %d\n", ret); + return 0; + } + + size_read = mmc_read_blocks(lba, buf, size); + + ret = mmc_part_switch(0); + if (ret < 0) { + ERROR("Failed to switch back to user partition, %d\n", ret); + return 0; + } + + return size_read; +} + int mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk, unsigned int width, unsigned int flags, struct mmc_device_info *device_info) diff --git a/drivers/st/io/io_mmc.c b/drivers/st/io/io_mmc.c index 0ed71540c3..2bf88e6f75 100644 --- a/drivers/st/io/io_mmc.c +++ b/drivers/st/io/io_mmc.c @@ -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 */ @@ -29,6 +29,7 @@ static int mmc_dev_close(io_dev_info_t *dev_info); static io_type_t device_type_mmc(void); static signed long long seek_offset; +static size_t (*_read_blocks)(int lba, uintptr_t buf, size_t size); static const io_dev_connector_t mmc_dev_connector = { .dev_open = mmc_dev_open @@ -60,9 +61,15 @@ static io_type_t device_type_mmc(void) /* Open a connection to the mmc device */ static int mmc_dev_open(const uintptr_t init_params, io_dev_info_t **dev_info) { + struct io_mmc_dev_spec *device_spec = + (struct io_mmc_dev_spec *)init_params; + assert(dev_info != NULL); *dev_info = (io_dev_info_t *)&mmc_dev_info; + _read_blocks = !device_spec->use_boot_part ? + mmc_read_blocks : mmc_boot_part_read_blocks; + return 0; } @@ -100,8 +107,8 @@ static int mmc_block_read(io_entity_t *entity, uintptr_t buffer, uint8_t retries; for (retries = 0U; retries < 3U; retries++) { - *length_read = mmc_read_blocks(seek_offset / MMC_BLOCK_SIZE, - buffer, length); + *length_read = _read_blocks(seek_offset / MMC_BLOCK_SIZE, + buffer, length); if (*length_read == length) { return 0; |