diff options
Diffstat (limited to 'plat/intel/soc')
25 files changed, 873 insertions, 349 deletions
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c index 9587d4859..f00294706 100644 --- a/plat/intel/soc/agilex/bl2_plat_setup.c +++ b/plat/intel/soc/agilex/bl2_plat_setup.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2019, Intel Corporation. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,11 +15,13 @@ #include <drivers/ti/uart/uart_16550.h> #include <lib/xlat_tables/xlat_tables.h> +#include "agilex_mmc.h" #include "agilex_clock_manager.h" #include "agilex_memory_controller.h" #include "agilex_pinmux.h" #include "ccu/ncore_ccu.h" #include "qspi/cadence_qspi.h" +#include "socfpga_emac.h" #include "socfpga_handoff.h" #include "socfpga_mailbox.h" #include "socfpga_private.h" @@ -46,12 +48,12 @@ const mmap_region_t agilex_plat_mmap[] = { {0}, }; -boot_source_type boot_source; +boot_source_type boot_source = BOOT_SOURCE; void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, u_register_t x2, u_register_t x4) { - static console_16550_t console; + static console_t console; handoff reverse_handoff_ptr; generic_delay_timer_init(); @@ -59,7 +61,6 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, if (socfpga_get_handoff(&reverse_handoff_ptr)) return; config_pinmux(&reverse_handoff_ptr); - boot_source = reverse_handoff_ptr.boot_source; config_clkmgr_handoff(&reverse_handoff_ptr); enable_nonsecure_access(); @@ -73,8 +74,10 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, socfpga_delay_timer_init(); init_ncore_ccu(); + socfpga_emac_init(); init_hard_memory_controller(); mailbox_init(); + agx_mmc_init(); if (!intel_mailbox_is_fpga_not_ready()) socfpga_bridges_enable(); diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c index 375483dd4..168236b64 100644 --- a/plat/intel/soc/agilex/bl31_plat_setup.c +++ b/plat/intel/soc/agilex/bl31_plat_setup.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2019, Intel Corporation. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,8 +11,11 @@ #include <common/bl_common.h> #include <drivers/arm/gicv2.h> #include <drivers/ti/uart/uart_16550.h> +#include <lib/mmio.h> #include <lib/xlat_tables/xlat_tables.h> +#include "socfpga_mailbox.h" +#include "socfpga_private.h" static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; @@ -34,7 +37,9 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { - static console_16550_t console; + static console_t console; + + mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY); console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE, &console); @@ -44,23 +49,33 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, void *from_bl2 = (void *) arg0; bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2; - assert(params_from_bl2 != NULL); - assert(params_from_bl2->h.type == PARAM_BL_PARAMS); - assert(params_from_bl2->h.version >= VERSION_2); /* * Copy BL32 (if populated by BL31) and BL33 entry point information. * They are stored in Secure RAM, in BL31's address space. */ - bl_params_node_t *bl_params = params_from_bl2->head; + if (params_from_bl2->h.type == PARAM_BL_PARAMS && + params_from_bl2->h.version >= VERSION_2) { + + bl_params_node_t *bl_params = params_from_bl2->head; + + while (bl_params) { + if (bl_params->image_id == BL33_IMAGE_ID) + bl33_image_ep_info = *bl_params->ep_info; - while (bl_params) { - if (bl_params->image_id == BL33_IMAGE_ID) - bl33_image_ep_info = *bl_params->ep_info; + bl_params = bl_params->next_params_info; + } + } else { + struct socfpga_bl31_params *arg_from_bl2 = + (struct socfpga_bl31_params *) from_bl2; - bl_params = bl_params->next_params_info; + assert(arg_from_bl2->h.type == PARAM_BL31); + assert(arg_from_bl2->h.version >= VERSION_1); + + bl32_image_ep_info = *arg_from_bl2->bl32_ep_info; + bl33_image_ep_info = *arg_from_bl2->bl33_ep_info; } SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); } @@ -86,11 +101,19 @@ static const gicv2_driver_data_t plat_gicv2_gic_data = { ******************************************************************************/ void bl31_platform_setup(void) { + socfpga_delay_timer_init(); + /* Initialize the gic cpu and distributor interfaces */ gicv2_driver_init(&plat_gicv2_gic_data); gicv2_distif_init(); gicv2_pcpu_distif_init(); gicv2_cpuif_enable(); + + /* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */ + mmio_write_64(PLAT_CPU_RELEASE_ADDR, + (uint64_t)plat_secondary_cpus_bl31_entry); + + mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL); } const mmap_region_t plat_agilex_mmap[] = { diff --git a/plat/intel/soc/agilex/include/agilex_clock_manager.h b/plat/intel/soc/agilex/include/agilex_clock_manager.h index 8af6a60bc..20667f014 100644 --- a/plat/intel/soc/agilex/include/agilex_clock_manager.h +++ b/plat/intel/soc/agilex/include/agilex_clock_manager.h @@ -89,6 +89,7 @@ /* Peripheral PLL Macros */ #define CLKMGR_PERPLL_EN_RESET 0x00000fff +#define CLKMGR_PERPLL_EN_SDMMCCLK BIT(5) #define CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(x) (((x) << 0) & 0x0000ffff) /* Altera Macros */ diff --git a/plat/intel/soc/agilex/include/agilex_mmc.h b/plat/intel/soc/agilex/include/agilex_mmc.h new file mode 100644 index 000000000..00f4ca5a8 --- /dev/null +++ b/plat/intel/soc/agilex/include/agilex_mmc.h @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2020, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +void agx_mmc_init(void); diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h index b4e09210f..6c9d81ceb 100644 --- a/plat/intel/soc/agilex/include/socfpga_plat_def.h +++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h @@ -12,6 +12,7 @@ /* Platform Setting */ #define PLATFORM_MODEL PLAT_SOCFPGA_AGILEX +#define BOOT_SOURCE BOOT_SOURCE_SDMMC /* Register Mapping */ #define SOCFPGA_MMC_REG_BASE 0xff808000 diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk index f47c3f113..bf5cc1445 100644 --- a/plat/intel/soc/agilex/platform.mk +++ b/plat/intel/soc/agilex/platform.mk @@ -1,6 +1,6 @@ # -# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. -# Copyright (c) 2019, Intel Corporation. All rights reserved. +# Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2019-2020, Intel Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -10,18 +10,23 @@ PLAT_INCLUDES := \ -Iplat/intel/soc/common/drivers/ \ -Iplat/intel/soc/common/include/ +# Include GICv2 driver files +include drivers/arm/gic/v2/gicv2.mk +AGX_GICv2_SOURCES := \ + ${GICV2_SOURCES} \ + plat/common/plat_gicv2.c + + PLAT_BL_COMMON_SOURCES := \ - drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ + ${AGX_GICv2_SOURCES} \ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ drivers/ti/uart/aarch64/16550_console.S \ lib/xlat_tables/aarch64/xlat_tables.c \ lib/xlat_tables/xlat_tables_common.c \ - plat/common/plat_gicv2.c \ plat/intel/soc/common/aarch64/platform_common.c \ - plat/intel/soc/common/aarch64/plat_helpers.S + plat/intel/soc/common/aarch64/plat_helpers.S \ + plat/intel/soc/common/socfpga_delay_timer.c BL2_SOURCES += \ common/desc_image_load.c \ @@ -37,11 +42,12 @@ BL2_SOURCES += \ plat/intel/soc/agilex/bl2_plat_setup.c \ plat/intel/soc/agilex/soc/agilex_clock_manager.c \ plat/intel/soc/agilex/soc/agilex_memory_controller.c \ + plat/intel/soc/agilex/soc/agilex_mmc.c \ plat/intel/soc/agilex/soc/agilex_pinmux.c \ plat/intel/soc/common/bl2_plat_mem_params_desc.c \ - plat/intel/soc/common/socfpga_delay_timer.c \ plat/intel/soc/common/socfpga_image_load.c \ plat/intel/soc/common/socfpga_storage.c \ + plat/intel/soc/common/soc/socfpga_emac.c \ plat/intel/soc/common/soc/socfpga_handoff.c \ plat/intel/soc/common/soc/socfpga_mailbox.c \ plat/intel/soc/common/soc/socfpga_reset_manager.c \ diff --git a/plat/intel/soc/agilex/soc/agilex_clock_manager.c b/plat/intel/soc/agilex/soc/agilex_clock_manager.c index c6c48baea..4efd7131d 100644 --- a/plat/intel/soc/agilex/soc/agilex_clock_manager.c +++ b/plat/intel/soc/agilex/soc/agilex_clock_manager.c @@ -47,14 +47,14 @@ uint32_t wait_fsm(void) return 0; } -uint32_t pll_source_sync_config(uint32_t pll_mem_offset) +uint32_t pll_source_sync_config(uint32_t pll_mem_offset, uint32_t data) { uint32_t val = 0; uint32_t count = 0; uint32_t req_status = 0; val = (CLKMGR_MEM_WR | CLKMGR_MEM_REQ | - CLKMGR_MEM_WDAT << CLKMGR_MEM_WDAT_OFFSET | CLKMGR_MEM_ADDR); + (data << CLKMGR_MEM_WDAT_OFFSET) | CLKMGR_MEM_ADDR); mmio_write_32(pll_mem_offset, val); do { @@ -89,14 +89,17 @@ uint32_t pll_source_sync_read(uint32_t pll_mem_offset) rdata = mmio_read_32(pll_mem_offset + 0x4); INFO("rdata (%x) = %x\n", pll_mem_offset + 0x4, rdata); - return 0; + return rdata; } void config_clkmgr_handoff(handoff *hoff_ptr) { uint32_t mdiv, mscnt, hscnt; - uint32_t arefclk_div, drefclk_div; + uint32_t drefclk_div, refclk_div, rdata; + /* Set clock maanger into boot mode before running configuration */ + mmio_setbits_32(CLKMGR_OFFSET + CLKMGR_CTRL, + CLKMGR_CTRL_BOOTMODE_SET_MSK); /* Bypass all mainpllgrp's clocks */ mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_BYPASS, 0x7); wait_fsm(); @@ -116,26 +119,24 @@ void config_clkmgr_handoff(handoff *hoff_ptr) /* Setup main PLL dividers */ mdiv = CLKMGR_PLLM_MDIV(hoff_ptr->main_pll_pllm); - arefclk_div = CLKMGR_PLLGLOB_AREFCLKDIV( - hoff_ptr->main_pll_pllglob); drefclk_div = CLKMGR_PLLGLOB_DREFCLKDIV( hoff_ptr->main_pll_pllglob); + refclk_div = CLKMGR_PLLGLOB_REFCLKDIV( + hoff_ptr->main_pll_pllglob); - mscnt = 100 / (mdiv / BIT(drefclk_div)); + mscnt = 100 / (mdiv * BIT(drefclk_div)); if (!mscnt) mscnt = 1; - hscnt = (mdiv * mscnt * BIT(drefclk_div) / arefclk_div) - 4; + hscnt = (mdiv * mscnt * BIT(drefclk_div) / refclk_div) - 4; - mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_VCOCALIB, - CLKMGR_VCOCALIB_HSCNT_SET(hscnt) | - CLKMGR_VCOCALIB_MSCNT_SET(mscnt)); - - mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCDIV, - hoff_ptr->main_pll_nocdiv); mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB, - hoff_ptr->main_pll_pllglob); + hoff_ptr->main_pll_pllglob & + ~CLKMGR_PLLGLOB_RST_SET_MSK); mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_FDBCK, hoff_ptr->main_pll_fdbck); + mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_VCOCALIB, + CLKMGR_VCOCALIB_HSCNT_SET(hscnt) | + CLKMGR_VCOCALIB_MSCNT_SET(mscnt)); mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLC0, hoff_ptr->main_pll_pllc0); mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLC1, @@ -150,33 +151,33 @@ void config_clkmgr_handoff(handoff *hoff_ptr) hoff_ptr->main_pll_mpuclk); mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCCLK, hoff_ptr->main_pll_nocclk); + mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCDIV, + hoff_ptr->main_pll_nocdiv); /* Setup peripheral PLL dividers */ mdiv = CLKMGR_PLLM_MDIV(hoff_ptr->per_pll_pllm); - arefclk_div = CLKMGR_PLLGLOB_AREFCLKDIV( - hoff_ptr->per_pll_pllglob); drefclk_div = CLKMGR_PLLGLOB_DREFCLKDIV( hoff_ptr->per_pll_pllglob); + refclk_div = CLKMGR_PLLGLOB_REFCLKDIV( + hoff_ptr->per_pll_pllglob); - mscnt = 100 / (mdiv / BIT(drefclk_div)); + + mscnt = 100 / (mdiv * BIT(drefclk_div)); if (!mscnt) mscnt = 1; - hscnt = (mdiv * mscnt * BIT(drefclk_div) / arefclk_div) - 4; + hscnt = (mdiv * mscnt * BIT(drefclk_div) / refclk_div) - 4; + + mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB, + hoff_ptr->per_pll_pllglob & + ~CLKMGR_PLLGLOB_RST_SET_MSK); + mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_FDBCK, + hoff_ptr->per_pll_fdbck); mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_VCOCALIB, CLKMGR_VCOCALIB_HSCNT_SET(hscnt) | CLKMGR_VCOCALIB_MSCNT_SET(mscnt)); - mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EMACCTL, - hoff_ptr->per_pll_emacctl); - mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_GPIODIV, - CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET( - hoff_ptr->per_pll_gpiodiv)); - mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB, - hoff_ptr->per_pll_pllglob); - mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_FDBCK, - hoff_ptr->per_pll_fdbck); mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLC0, hoff_ptr->per_pll_pllc0); mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLC1, @@ -187,6 +188,10 @@ void config_clkmgr_handoff(handoff *hoff_ptr) hoff_ptr->per_pll_pllc3); mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLM, hoff_ptr->per_pll_pllm); + mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EMACCTL, + hoff_ptr->per_pll_emacctl); + mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_GPIODIV, + hoff_ptr->per_pll_gpiodiv); /* Take both PLL out of reset and power up */ mmio_setbits_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB, @@ -196,13 +201,16 @@ void config_clkmgr_handoff(handoff *hoff_ptr) CLKMGR_PLLGLOB_PD_SET_MSK | CLKMGR_PLLGLOB_RST_SET_MSK); - wait_pll_lock(); + rdata = pll_source_sync_read(CLKMGR_MAINPLL + + CLKMGR_MAINPLL_MEM); + pll_source_sync_config(CLKMGR_MAINPLL + CLKMGR_MAINPLL_MEM, + rdata | 0x80); - pll_source_sync_config(CLKMGR_MAINPLL + CLKMGR_MAINPLL_MEM); - pll_source_sync_read(CLKMGR_MAINPLL + CLKMGR_MAINPLL_MEM); + rdata = pll_source_sync_read(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM); + pll_source_sync_config(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM, + rdata | 0x80); - pll_source_sync_config(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM); - pll_source_sync_read(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM); + wait_pll_lock(); /*Configure Ping Pong counters in altera group */ mmio_write_32(CLKMGR_ALTERA + CLKMGR_ALTERA_EMACACTR, @@ -241,7 +249,7 @@ void config_clkmgr_handoff(handoff *hoff_ptr) /* Clear loss lock interrupt status register that */ /* might be set during configuration */ - mmio_setbits_32(CLKMGR_OFFSET + CLKMGR_INTRCLR, + mmio_clrbits_32(CLKMGR_OFFSET + CLKMGR_INTRCLR, CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK | CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK); diff --git a/plat/intel/soc/agilex/soc/agilex_mmc.c b/plat/intel/soc/agilex/soc/agilex_mmc.c new file mode 100644 index 000000000..e05d92a03 --- /dev/null +++ b/plat/intel/soc/agilex/soc/agilex_mmc.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2020, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include <lib/mmio.h> + +#include "socfpga_system_manager.h" +#include "agilex_clock_manager.h" + +void agx_mmc_init(void) +{ + mmio_clrbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EN, + CLKMGR_PERPLL_EN_SDMMCCLK); + mmio_write_32(SOCFPGA_SYSMGR(SDMMC), + SYSMGR_SDMMC_SMPLSEL(0) | SYSMGR_SDMMC_DRVSEL(3)); + mmio_setbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EN, + CLKMGR_PERPLL_EN_SDMMCCLK); +} diff --git a/plat/intel/soc/agilex/soc/agilex_pinmux.c b/plat/intel/soc/agilex/soc/agilex_pinmux.c index eff19473c..0b908cfa3 100644 --- a/plat/intel/soc/agilex/soc/agilex_pinmux.c +++ b/plat/intel/soc/agilex/soc/agilex_pinmux.c @@ -7,6 +7,7 @@ #include <lib/mmio.h> #include "agilex_pinmux.h" +#include "socfpga_system_manager.h" const uint32_t sysmgr_pinmux_array_sel[] = { 0x00000000, 0x00000001, /* usb */ @@ -185,6 +186,12 @@ const uint32_t sysmgr_pinmux_array_iodelay[] = { 0x0000011c, 0x00000000 }; +void config_fpgaintf_mod(void) +{ + mmio_write_32(SOCFPGA_SYSMGR(FPGAINTF_EN_2), 1<<8); +} + + void config_pinmux(handoff *hoff_ptr) { unsigned int i; @@ -213,5 +220,6 @@ void config_pinmux(handoff *hoff_ptr) hoff_ptr->pinmux_iodelay_array[i+1]); } + config_fpgaintf_mod(); } diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c index fce816b65..b4fce7b40 100644 --- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c +++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c @@ -35,14 +35,12 @@ uint32_t directory_init(void) uint32_t dir, sf, ret; for (dir = 0; dir < subsystem_id.num_directory; dir++) { - - dir_sf_mtn = DIRECTORY_UNIT(dir, NCORE_DIRUSFMCR); - dir_sf_en = DIRECTORY_UNIT(dir, NCORE_DIRUSFER); - for (sf = 0; sf < subsystem_id.num_snoop_filter; sf++) { + dir_sf_mtn = DIRECTORY_UNIT(dir, NCORE_DIRUSFMCR); + dir_sf_en = DIRECTORY_UNIT(dir, NCORE_DIRUSFER); /* Initialize All Entries */ - mmio_write_32(dir_sf_mtn, SNOOP_FILTER_ID(sf)); + mmio_write_32(dir_sf_mtn, SNOOP_FILTER_ID(dir)); /* Poll Active Bit */ ret = poll_active_bit(dir); @@ -52,7 +50,7 @@ uint32_t directory_init(void) } /* Snoope Filter Enable */ - mmio_write_32(dir_sf_en, BIT(sf)); + mmio_setbits_32(dir_sf_en, BIT(sf)); } } @@ -64,11 +62,8 @@ uint32_t coherent_agent_intfc_init(void) uint32_t dir, ca, ca_id, ca_type, ca_snoop_en; for (dir = 0; dir < subsystem_id.num_directory; dir++) { - - ca_snoop_en = DIRECTORY_UNIT(dir, NCORE_DIRUCASER0); - for (ca = 0; ca < subsystem_id.num_coh_agent; ca++) { - + ca_snoop_en = DIRECTORY_UNIT(ca, NCORE_DIRUCASER0); ca_id = mmio_read_32(COH_AGENT_UNIT(ca, NCORE_CAIUIDR)); /* Coh Agent Snoop Enable */ diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h index 8a681e69d..55600ee69 100644 --- a/plat/intel/soc/common/include/platform_def.h +++ b/plat/intel/soc/common/include/platform_def.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2019, Intel Corporation. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -134,6 +134,8 @@ #define PLAT_CPUID_RELEASE (BL_DATA_LIMIT - 16) #define PLAT_SEC_ENTRY (BL_DATA_LIMIT - 8) +#define PLAT_SEC_WARM_ENTRY 0 + /******************************************************************************* * Platform specific page table and MMU setup constants ******************************************************************************/ @@ -169,6 +171,14 @@ #define PLAT_UART_CLOCK (100000000) /******************************************************************************* + * PHY related constants + ******************************************************************************/ + +#define EMAC0_PHY_MODE PHY_INTERFACE_MODE_RGMII +#define EMAC1_PHY_MODE PHY_INTERFACE_MODE_RGMII +#define EMAC2_PHY_MODE PHY_INTERFACE_MODE_RGMII + +/******************************************************************************* * System counter frequency related constants ******************************************************************************/ #define PLAT_SYS_COUNTER_FREQ_IN_TICKS (400000000) diff --git a/plat/intel/soc/common/include/socfpga_emac.h b/plat/intel/soc/common/include/socfpga_emac.h new file mode 100644 index 000000000..5b98006a3 --- /dev/null +++ b/plat/intel/soc/common/include/socfpga_emac.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2020, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SOCFPGA_EMAC_H +#define SOCFPGA_EMAC_H + +/* EMAC PHY Mode */ + +#define PHY_INTERFACE_MODE_GMII_MII 0 +#define PHY_INTERFACE_MODE_RGMII 1 +#define PHY_INTERFACE_MODE_RMII 2 +#define PHY_INTERFACE_MODE_RESET 3 + +/* Mask Definitions */ + +#define PHY_INTF_SEL_MSK 0x3 +#define FPGAINTF_EN_3_EMAC_MSK(x) (1 << (x * 8)) + +void socfpga_emac_init(void); + +#endif /* SOCFPGA_EMAC_H */ diff --git a/plat/intel/soc/common/include/socfpga_handoff.h b/plat/intel/soc/common/include/socfpga_handoff.h index 889d13767..ba0f7f377 100644 --- a/plat/intel/soc/common/include/socfpga_handoff.h +++ b/plat/intel/soc/common/include/socfpga_handoff.h @@ -125,7 +125,6 @@ typedef struct handoff_t { uint32_t misc_magic; uint32_t misc_length; uint32_t _pad_0x618_0x620[2]; - uint32_t boot_source; } handoff; int verify_handoff_image(handoff *hoff_ptr, handoff *reverse_hoff_ptr); diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index c4b9e5967..923c4f154 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Intel Corporation. All rights reserved. + * Copyright (c) 2019-2020, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,35 +9,16 @@ #include <lib/utils_def.h> -#define MBOX_OFFSET 0xffa30000 -#define MBOX_MAX_JOB_ID 0xf -#define MBOX_ATF_CLIENT_ID 0x1 -#define MBOX_JOB_ID 0x1 +#define MBOX_OFFSET 0xffa30000 -/* Mailbox interrupt flags and masks */ -#define MBOX_INT_FLAG_COE 0x1 -#define MBOX_INT_FLAG_RIE 0x2 -#define MBOX_INT_FLAG_UAE 0x100 -#define MBOX_COE_BIT(INTERRUPT) ((INTERRUPT) & 0x3) -#define MBOX_UAE_BIT(INTERRUPT) (((INTERRUPT) & (1<<8))) +#define MBOX_ATF_CLIENT_ID 0x1U +#define MBOX_MAX_JOB_ID 0xFU +#define MBOX_MAX_IND_JOB_ID (MBOX_MAX_JOB_ID - 1U) +#define MBOX_JOB_ID MBOX_MAX_JOB_ID -/* Mailbox response and status */ -#define MBOX_RESP_BUFFER_SIZE 16 -#define MBOX_RESP_ERR(BUFFER) ((BUFFER) & 0x00000fff) -#define MBOX_RESP_LEN(BUFFER) (((BUFFER) & 0x007ff000) >> 12) -#define MBOX_RESP_CLIENT_ID(BUFFER) (((BUFFER) & 0xf0000000) >> 28) -#define MBOX_RESP_JOB_ID(BUFFER) (((BUFFER) & 0x0f000000) >> 24) -#define MBOX_STATUS_UA_MASK (1<<8) -/* Mailbox command and response */ -#define MBOX_CMD_FREE_OFFSET 0x14 -#define MBOX_CMD_BUFFER_SIZE 32 -#define MBOX_CLIENT_ID_CMD(CLIENT_ID) ((CLIENT_ID) << 28) -#define MBOX_JOB_ID_CMD(JOB_ID) (JOB_ID<<24) -#define MBOX_CMD_LEN_CMD(CMD_LEN) ((CMD_LEN) << 12) -#define MBOX_INDIRECT (1 << 11) -#define MBOX_INSUFFICIENT_BUFFER -2 +/* Mailbox Shared Memory Register Map */ #define MBOX_CIN 0x00 #define MBOX_ROUT 0x04 #define MBOX_URG 0x08 @@ -48,37 +29,63 @@ #define MBOX_CMD_BUFFER 0x40 #define MBOX_RESP_BUFFER 0xC0 -#define MBOX_RESP_BUFFER_SIZE 16 -#define MBOX_RESP_OK 0 -#define MBOX_RESP_INVALID_CMD 1 -#define MBOX_RESP_UNKNOWN_BR 2 -#define MBOX_RESP_UNKNOWN 3 -#define MBOX_RESP_NOT_CONFIGURED 256 - /* Mailbox SDM doorbell */ #define MBOX_DOORBELL_TO_SDM 0x400 #define MBOX_DOORBELL_FROM_SDM 0x480 -/* Mailbox QSPI commands */ -#define MBOX_CMD_RESTART 2 -#define MBOX_CMD_QSPI_OPEN 50 -#define MBOX_CMD_QSPI_CLOSE 51 -#define MBOX_CMD_QSPI_DIRECT 59 -#define MBOX_CMD_GET_IDCODE 16 -#define MBOX_CMD_QSPI_SET_CS 52 -/* Mailbox CANCEL command */ -#define MBOX_CMD_CANCEL 0x3 +/* Mailbox commands */ -/* Mailbox REBOOT commands */ -#define MBOX_CMD_REBOOT_HPS 71 +#define MBOX_CMD_NOOP 0x00 +#define MBOX_CMD_SYNC 0x01 +#define MBOX_CMD_RESTART 0x02 +#define MBOX_CMD_CANCEL 0x03 +#define MBOX_CMD_GET_IDCODE 0x10 +#define MBOX_CMD_REBOOT_HPS 0x47 -/* Generic error handling */ -#define MBOX_TIMEOUT -2047 +/* Reconfiguration Commands */ +#define MBOX_CONFIG_STATUS 0x04 +#define MBOX_RECONFIG 0x06 +#define MBOX_RECONFIG_DATA 0x08 +#define MBOX_RECONFIG_STATUS 0x09 + +/* QSPI Commands */ +#define MBOX_CMD_QSPI_OPEN 0x32 +#define MBOX_CMD_QSPI_CLOSE 0x33 +#define MBOX_CMD_QSPI_SET_CS 0x34 +#define MBOX_CMD_QSPI_DIRECT 0x3B + +/* RSU Commands */ +#define MBOX_GET_SUBPARTITION_TABLE 0x5A +#define MBOX_RSU_STATUS 0x5B +#define MBOX_RSU_UPDATE 0x5C +#define MBOX_HPS_STAGE_NOTIFY 0x5D + + +/* Mailbox Definitions */ + +#define CMD_DIRECT 0 +#define CMD_INDIRECT 1 +#define CMD_CASUAL 0 +#define CMD_URGENT 1 + +#define MBOX_RESP_BUFFER_SIZE 16 +#define MBOX_CMD_BUFFER_SIZE 32 + +/* Execution states for HPS_STAGE_NOTIFY */ +#define HPS_EXECUTION_STATE_FSBL 0 +#define HPS_EXECUTION_STATE_SSBL 1 +#define HPS_EXECUTION_STATE_OS 2 + +/* Status Response */ +#define MBOX_RET_OK 0 +#define MBOX_RET_ERROR -1 #define MBOX_NO_RESPONSE -2 #define MBOX_WRONG_ID -3 +#define MBOX_BUFFER_FULL -4 +#define MBOX_TIMEOUT -2047 -/* Mailbox status */ +/* Reconfig Status Response */ #define RECONFIG_STATUS_STATE 0 #define RECONFIG_STATUS_PIN_STATUS 2 #define RECONFIG_STATUS_SOFTFUNC_STATUS 3 @@ -98,28 +105,62 @@ #define MBOX_CFGSTAT_STATE_ERROR_BOOT_INFO 0xf0000007 #define MBOX_CFGSTAT_STATE_ERROR_QSPI_ERROR 0xf0000008 -/* Mailbox reconfiguration commands */ -#define MBOX_CONFIG_STATUS 4 -#define MBOX_RECONFIG 6 -#define MBOX_RECONFIG_DATA 8 -#define MBOX_RECONFIG_STATUS 9 +/* Mailbox Macros */ -void mailbox_set_int(int interrupt_input); +/* Mailbox interrupt flags and masks */ +#define MBOX_INT_FLAG_COE 0x1 +#define MBOX_INT_FLAG_RIE 0x2 +#define MBOX_INT_FLAG_UAE 0x100 +#define MBOX_COE_BIT(INTERRUPT) ((INTERRUPT) & 0x3) +#define MBOX_UAE_BIT(INTERRUPT) (((INTERRUPT) & (1<<8))) + +/* Mailbox response and status */ +#define MBOX_RESP_ERR(BUFFER) ((BUFFER) & 0x00000fff) +#define MBOX_RESP_LEN(BUFFER) (((BUFFER) & 0x007ff000) >> 12) +#define MBOX_RESP_CLIENT_ID(BUFFER) (((BUFFER) & 0xf0000000) >> 28) +#define MBOX_RESP_JOB_ID(BUFFER) (((BUFFER) & 0x0f000000) >> 24) +#define MBOX_STATUS_UA_MASK (1<<8) + +/* Mailbox command and response */ +#define MBOX_CLIENT_ID_CMD(CLIENT_ID) ((CLIENT_ID) << 28) +#define MBOX_JOB_ID_CMD(JOB_ID) (JOB_ID<<24) +#define MBOX_CMD_LEN_CMD(CMD_LEN) ((CMD_LEN) << 12) +#define MBOX_INDIRECT(val) ((val) << 11) +#define MBOX_CMD_MASK(header) ((header) & 0x7ff) + +/* RSU Macros */ +#define RSU_VERSION_ACMF BIT(8) +#define RSU_VERSION_ACMF_MASK 0xff00 + + +/* Mailbox Function Definitions */ + +void mailbox_set_int(uint32_t interrupt_input); int mailbox_init(void); void mailbox_set_qspi_close(void); void mailbox_set_qspi_open(void); void mailbox_set_qspi_direct(void); -int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args, - int len, int urgent, uint32_t *response, int resp_len); -int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, - int len, int urgent); -int mailbox_read_response(int job_id, uint32_t *response, int resp_len); -int mailbox_get_qspi_clock(void); + +int mailbox_send_cmd(uint32_t job_id, uint32_t cmd, uint32_t *args, + unsigned int len, uint32_t urgent, uint32_t *response, + unsigned int resp_len); +int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args, + unsigned int len, unsigned int indirect); +int mailbox_read_response(uint32_t *job_id, uint32_t *response, + unsigned int resp_len); +unsigned int iterate_resp(uint32_t mbox_resp_len, uint32_t *resp_buf, + unsigned int resp_len); + void mailbox_reset_cold(void); void mailbox_clear_response(void); -uint32_t intel_mailbox_get_config_status(uint32_t cmd); +int intel_mailbox_get_config_status(uint32_t cmd); int intel_mailbox_is_fpga_not_ready(void); +int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len); +int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len); +int mailbox_rsu_update(uint32_t *flash_offset); +int mailbox_hps_stage_notify(uint32_t execution_stage); + #endif /* SOCFPGA_MBOX_H */ diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 6bb41f31b..92adfa3a7 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Intel Corporation. All rights reserved. + * Copyright (c) 2019-2020, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,28 +10,41 @@ /* SiP status response */ #define INTEL_SIP_SMC_STATUS_OK 0 -#define INTEL_SIP_SMC_STATUS_ERROR 0x4 #define INTEL_SIP_SMC_STATUS_BUSY 0x1 #define INTEL_SIP_SMC_STATUS_REJECTED 0x2 +#define INTEL_SIP_SMC_STATUS_ERROR 0x4 +#define INTEL_SIP_SMC_RSU_ERROR 0x7 + /* SMC SiP service function identifier */ + +/* FPGA Reconfig */ #define INTEL_SIP_SMC_FPGA_CONFIG_START 0xC2000001 #define INTEL_SIP_SMC_FPGA_CONFIG_WRITE 0x42000002 #define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE 0xC2000003 #define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE 0xC2000004 #define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM 0xC2000005 + +/* Secure Register Access */ #define INTEL_SIP_SMC_REG_READ 0xC2000007 #define INTEL_SIP_SMC_REG_WRITE 0xC2000008 #define INTEL_SIP_SMC_REG_UPDATE 0xC2000009 + +/* Remote System Update */ #define INTEL_SIP_SMC_RSU_STATUS 0xC200000B #define INTEL_SIP_SMC_RSU_UPDATE 0xC200000C -#define INTEL_SIP_LEGACY_SMC_ECC_DBE 0xC200000D #define INTEL_SIP_SMC_RSU_NOTIFY 0xC200000E #define INTEL_SIP_SMC_RSU_RETRY_COUNTER 0xC200000F +/* Send Mailbox Command */ +#define INTEL_SIP_SMC_MBOX_SEND_CMD 0xC200001E + + +/* SiP Definitions */ + /* FPGA config helpers */ #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x400000 -#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 16777216 +#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 0x2000000 /* SMC function IDs for SiP Service queries */ #define SIP_SVC_CALL_COUNT 0x8200ff00 @@ -42,4 +55,19 @@ #define SIP_SVC_VERSION_MAJOR 0 #define SIP_SVC_VERSION_MINOR 1 + +/* Structure Definitions */ +struct fpga_config_info { + uint32_t addr; + int size; + int size_written; + uint32_t write_requested; + int subblocks_sent; + int block_number; +}; + +/* Function Definitions */ + +bool is_address_in_ddr_range(uint64_t addr, uint64_t size); + #endif /* SOCFPGA_SIP_SVC_H */ diff --git a/plat/intel/soc/common/include/socfpga_system_manager.h b/plat/intel/soc/common/include/socfpga_system_manager.h index 68e30b894..8b42d47af 100644 --- a/plat/intel/soc/common/include/socfpga_system_manager.h +++ b/plat/intel/soc/common/include/socfpga_system_manager.h @@ -13,6 +13,13 @@ #define SOCFPGA_SYSMGR_SDMMC 0x28 +#define SOCFPGA_SYSMGR_FPGAINTF_EN_2 0x6c + +#define SOCFPGA_SYSMGR_EMAC_0 0x44 +#define SOCFPGA_SYSMGR_EMAC_1 0x48 +#define SOCFPGA_SYSMGR_EMAC_2 0x4c +#define SOCFPGA_SYSMGR_FPGAINTF_EN_3 0x70 + #define SOCFPGA_SYSMGR_NOC_TIMEOUT 0xc0 #define SOCFPGA_SYSMGR_NOC_IDLEREQ_SET 0xc4 #define SOCFPGA_SYSMGR_NOC_IDLEREQ_CLR 0xc8 @@ -27,6 +34,7 @@ /* Field Masking */ #define SYSMGR_SDMMC_DRVSEL(x) (((x) & 0x7) << 0) +#define SYSMGR_SDMMC_SMPLSEL(x) (((x) & 0x7) << 4) #define IDLE_DATA_LWSOC2FPGA BIT(0) #define IDLE_DATA_SOC2FPGA BIT(4) diff --git a/plat/intel/soc/common/soc/socfpga_emac.c b/plat/intel/soc/common/soc/socfpga_emac.c new file mode 100644 index 000000000..cacfd53c4 --- /dev/null +++ b/plat/intel/soc/common/soc/socfpga_emac.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <lib/mmio.h> +#include <platform_def.h> + +#include "socfpga_emac.h" +#include "socfpga_reset_manager.h" +#include "socfpga_system_manager.h" + +void socfpga_emac_init(void) +{ + mmio_setbits_32(SOCFPGA_RSTMGR(PER0MODRST), + RSTMGR_PER0MODRST_EMAC0 | + RSTMGR_PER0MODRST_EMAC1 | + RSTMGR_PER0MODRST_EMAC2); + + mmio_clrsetbits_32(SOCFPGA_SYSMGR(EMAC_0), + PHY_INTF_SEL_MSK, EMAC0_PHY_MODE); + mmio_clrsetbits_32(SOCFPGA_SYSMGR(EMAC_1), + PHY_INTF_SEL_MSK, EMAC1_PHY_MODE); + mmio_clrsetbits_32(SOCFPGA_SYSMGR(EMAC_2), + PHY_INTF_SEL_MSK, EMAC2_PHY_MODE); + + mmio_clrbits_32(SOCFPGA_SYSMGR(FPGAINTF_EN_3), + FPGAINTF_EN_3_EMAC_MSK(0) | + FPGAINTF_EN_3_EMAC_MSK(1) | + FPGAINTF_EN_3_EMAC_MSK(2)); + + mmio_clrbits_32(SOCFPGA_RSTMGR(PER0MODRST), + RSTMGR_PER0MODRST_EMAC0 | + RSTMGR_PER0MODRST_EMAC1 | + RSTMGR_PER0MODRST_EMAC2); +} + diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index 8d7c1d663..aec94af94 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Intel Corporation. All rights reserved. + * Copyright (c) 2020, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,188 +11,324 @@ #include "socfpga_mailbox.h" #include "socfpga_sip_svc.h" + +static bool is_mailbox_cmdbuf_full(uint32_t cin) +{ + uint32_t cout = mmio_read_32(MBOX_OFFSET + MBOX_COUT); + + return (((cin + 1U) % MBOX_CMD_BUFFER_SIZE) == cout); +} + +static bool is_mailbox_cmdbuf_empty(uint32_t cin) +{ + uint32_t cout = mmio_read_32(MBOX_OFFSET + MBOX_COUT); + + return (((cout + 1U) % MBOX_CMD_BUFFER_SIZE) == cin); +} + +static int wait_for_mailbox_cmdbuf_empty(uint32_t cin) +{ + unsigned int timeout = 200U; + + do { + if (is_mailbox_cmdbuf_empty(cin)) { + break; + } + mdelay(10U); + } while (--timeout != 0U); + + if (timeout == 0U) { + return MBOX_TIMEOUT; + } + + return MBOX_RET_OK; +} + +static int write_mailbox_cmd_buffer(uint32_t *cin, uint32_t cout, + uint32_t data, + bool *is_doorbell_triggered) +{ + unsigned int timeout = 100U; + + do { + if (is_mailbox_cmdbuf_full(*cin)) { + if (!(*is_doorbell_triggered)) { + mmio_write_32(MBOX_OFFSET + + MBOX_DOORBELL_TO_SDM, 1U); + *is_doorbell_triggered = true; + } + mdelay(10U); + } else { + mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER + + (*cin * 4), data); + (*cin)++; + *cin %= MBOX_CMD_BUFFER_SIZE; + mmio_write_32(MBOX_OFFSET + MBOX_CIN, *cin); + break; + } + } while (--timeout != 0U); + + if (timeout == 0U) { + return MBOX_TIMEOUT; + } + + if (*is_doorbell_triggered) { + int ret = wait_for_mailbox_cmdbuf_empty(*cin); + return ret; + } + + return MBOX_RET_OK; +} + static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args, - int len) + unsigned int len) { - uint32_t cmd_free_offset; - int i; + uint32_t sdm_read_offset, cmd_free_offset; + unsigned int i; + int ret; + bool is_doorbell_triggered = false; cmd_free_offset = mmio_read_32(MBOX_OFFSET + MBOX_CIN); + sdm_read_offset = mmio_read_32(MBOX_OFFSET + MBOX_COUT); - mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER + (cmd_free_offset++ * 4), - header_cmd); + ret = write_mailbox_cmd_buffer(&cmd_free_offset, sdm_read_offset, + header_cmd, &is_doorbell_triggered); + if (ret != 0) { + goto restart_mailbox; + } + for (i = 0U; i < len; i++) { + is_doorbell_triggered = false; + ret = write_mailbox_cmd_buffer(&cmd_free_offset, + sdm_read_offset, args[i], + &is_doorbell_triggered); + if (ret != 0) { + goto restart_mailbox; + } + } - for (i = 0; i < len; i++) { - cmd_free_offset %= MBOX_CMD_BUFFER_SIZE; - mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER + - (cmd_free_offset++ * 4), args[i]); + if (!is_doorbell_triggered) { + mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U); } - cmd_free_offset %= MBOX_CMD_BUFFER_SIZE; - mmio_write_32(MBOX_OFFSET + MBOX_CIN, cmd_free_offset); + return MBOX_RET_OK; - return 0; +restart_mailbox: + /* + * Attempt to restart mailbox if the driver not able to write + * into mailbox command buffer + */ + if (MBOX_CMD_MASK(header_cmd) != MBOX_CMD_RESTART) { + INFO("Mailbox timed out: Attempting mailbox reset\n"); + ret = mailbox_init(); + + if (ret == MBOX_TIMEOUT) { + INFO("Error: Mailbox fail to restart\n"); + } + } + + return MBOX_TIMEOUT; } -int mailbox_read_response(int job_id, uint32_t *response, int resp_len) +int mailbox_read_response(unsigned int *job_id, uint32_t *response, + unsigned int resp_len) { - int rin = 0; - int rout = 0; - int response_length = 0; - int resp = 0; - int total_resp_len = 0; + uint32_t rin; + uint32_t rout; + uint32_t resp_data; + unsigned int ret_resp_len; - if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM)) - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0); + if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U) { + mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U); + } rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN); rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT); if (rout != rin) { - resp = mmio_read_32(MBOX_OFFSET + - MBOX_RESP_BUFFER + ((rout++)*4)); + resp_data = mmio_read_32(MBOX_OFFSET + + MBOX_RESP_BUFFER + ((rout++)*4U)); rout %= MBOX_RESP_BUFFER_SIZE; mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); - if (MBOX_RESP_CLIENT_ID(resp) != MBOX_ATF_CLIENT_ID || - MBOX_RESP_JOB_ID(resp) != job_id) { + + if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID) { return MBOX_WRONG_ID; } - if (MBOX_RESP_ERR(resp) > 0) { - INFO("Error in response: %x\n", resp); - return -resp; + *job_id = MBOX_RESP_JOB_ID(resp_data); + + ret_resp_len = MBOX_RESP_LEN(resp_data); + + if (ret_resp_len != 0U) { + ret_resp_len = iterate_resp(ret_resp_len, response, + resp_len); } - response_length = MBOX_RESP_LEN(resp); - - while (response_length) { - - response_length--; - resp = mmio_read_32(MBOX_OFFSET + - MBOX_RESP_BUFFER + - (rout)*4); - if (response && resp_len) { - *(response + total_resp_len) = resp; - resp_len--; - total_resp_len++; - } - rout++; - rout %= MBOX_RESP_BUFFER_SIZE; - mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); + + if (MBOX_RESP_ERR(resp_data) > 0U) { + INFO("Error in response: %x\n", resp_data); + return -MBOX_RESP_ERR(resp_data); } - return total_resp_len; - } + return ret_resp_len; + } return MBOX_NO_RESPONSE; } -int mailbox_poll_response(int job_id, int urgent, uint32_t *response, - int resp_len) +int mailbox_poll_response(uint32_t job_id, uint32_t urgent, uint32_t *response, + unsigned int resp_len) { - int timeout = 0xFFFFFF; - int rin = 0; - int rout = 0; - int response_length = 0; - int resp = 0; - int total_resp_len = 0; - - while (1) { - - while (timeout > 0 && - !(mmio_read_32(MBOX_OFFSET + - MBOX_DOORBELL_FROM_SDM) & 1)) { - timeout--; - } + unsigned int timeout = 40U; + unsigned int sdm_loop = 255U; + unsigned int ret_resp_len; + uint32_t rin; + uint32_t rout; + uint32_t resp_data; + + while (sdm_loop != 0U) { + + do { + if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) + == 1U) { + break; + } + mdelay(10U); + } while (--timeout != 0U); - if (!timeout) { - INFO("Timed out waiting for SDM"); - return MBOX_TIMEOUT; + if (timeout == 0U) { + break; } - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0); + mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U); - if (urgent & 1) { - mdelay(5); + if ((urgent & 1U) != 0U) { + mdelay(5U); if ((mmio_read_32(MBOX_OFFSET + MBOX_STATUS) & MBOX_STATUS_UA_MASK) ^ (urgent & MBOX_STATUS_UA_MASK)) { - mmio_write_32(MBOX_OFFSET + MBOX_URG, 0); - return 0; + mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U); + return MBOX_RET_OK; } - mmio_write_32(MBOX_OFFSET + MBOX_URG, 0); + mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U); INFO("Error: Mailbox did not get UA"); - return -1; + return MBOX_RET_ERROR; } rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN); rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT); while (rout != rin) { - resp = mmio_read_32(MBOX_OFFSET + - MBOX_RESP_BUFFER + ((rout++)*4)); + resp_data = mmio_read_32(MBOX_OFFSET + + MBOX_RESP_BUFFER + ((rout++)*4U)); rout %= MBOX_RESP_BUFFER_SIZE; mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); - if (MBOX_RESP_CLIENT_ID(resp) != MBOX_ATF_CLIENT_ID || - MBOX_RESP_JOB_ID(resp) != job_id) + if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID + || MBOX_RESP_JOB_ID(resp_data) != job_id) { continue; + } + + ret_resp_len = MBOX_RESP_LEN(resp_data); - if (MBOX_RESP_ERR(resp) > 0) { - INFO("Error in response: %x\n", resp); - return -MBOX_RESP_ERR(resp); + if (ret_resp_len != 0U) { + ret_resp_len = iterate_resp(ret_resp_len, + response, + resp_len); } - response_length = MBOX_RESP_LEN(resp); - - while (response_length) { - response_length--; - resp = mmio_read_32(MBOX_OFFSET + - MBOX_RESP_BUFFER + - (rout)*4); - if (response && resp_len) { - *(response + total_resp_len) = resp; - resp_len--; - total_resp_len++; - } - rout++; - rout %= MBOX_RESP_BUFFER_SIZE; - mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); + + if (MBOX_RESP_ERR(resp_data) > 0U) { + INFO("Error in response: %x\n", resp_data); + return -MBOX_RESP_ERR(resp_data); } - return total_resp_len; + + return ret_resp_len; } + + sdm_loop--; } + + INFO("Timed out waiting for SDM\n"); + return MBOX_TIMEOUT; } -int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, - int len, int urgent) +unsigned int iterate_resp(uint32_t mbox_resp_len, uint32_t *resp_buf, + unsigned int resp_len) { - if (urgent) - mmio_write_32(MBOX_OFFSET + MBOX_URG, 1); + unsigned int timeout, total_resp_len = 0U; + uint32_t resp_data; + uint32_t rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN); + uint32_t rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT); + + while (mbox_resp_len > 0U) { + timeout = 100U; + mbox_resp_len--; + resp_data = mmio_read_32(MBOX_OFFSET + + MBOX_RESP_BUFFER + + (rout)*4U); + + if ((resp_buf != NULL) && (resp_len != 0U)) { + *(resp_buf + total_resp_len) + = resp_data; + resp_len--; + total_resp_len++; + } + rout++; + rout %= MBOX_RESP_BUFFER_SIZE; + mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); + + do { + rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN); + if (rout == rin) { + mdelay(10U); + } else { + break; + } + timeout--; + } while ((mbox_resp_len > 0U) && (timeout != 0U)); + + if (timeout == 0U) { + INFO("Timed out waiting for SDM\n"); + return MBOX_TIMEOUT; + } + } + return total_resp_len; +} - fill_mailbox_circular_buffer(MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) | - MBOX_JOB_ID_CMD(job_id) | - MBOX_CMD_LEN_CMD(len) | - MBOX_INDIRECT | - cmd, args, len); +int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args, + unsigned int len, unsigned int indirect) +{ + int status; + + status = fill_mailbox_circular_buffer( + MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) | + MBOX_JOB_ID_CMD(*job_id) | + MBOX_CMD_LEN_CMD(len) | + MBOX_INDIRECT(indirect) | + cmd, args, len); + if (status < 0) { + return status; + } - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1); + *job_id = (*job_id + 1U) % MBOX_MAX_IND_JOB_ID; - return 0; + return MBOX_RET_OK; } -int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args, - int len, int urgent, uint32_t *response, int resp_len) +int mailbox_send_cmd(uint32_t job_id, uint32_t cmd, uint32_t *args, + unsigned int len, uint32_t urgent, uint32_t *response, + unsigned int resp_len) { int status = 0; - if (urgent) { + if (urgent != 0U) { urgent |= mmio_read_32(MBOX_OFFSET + MBOX_STATUS) & MBOX_STATUS_UA_MASK; mmio_write_32(MBOX_OFFSET + MBOX_URG, cmd); + mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U); } else { @@ -203,10 +339,10 @@ int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args, cmd, args, len); } - if (status) + if (status != 0) { return status; + } - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1); status = mailbox_poll_response(job_id, urgent, response, resp_len); return status; @@ -218,7 +354,7 @@ void mailbox_clear_response(void) mmio_read_32(MBOX_OFFSET + MBOX_RIN)); } -void mailbox_set_int(int interrupt) +void mailbox_set_int(uint32_t interrupt) { mmio_write_32(MBOX_OFFSET+MBOX_INT, MBOX_COE_BIT(interrupt) | @@ -229,90 +365,149 @@ void mailbox_set_int(int interrupt) void mailbox_set_qspi_open(void) { mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, 0, 0, 0, NULL, 0); + mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, NULL, 0U, + CMD_CASUAL, NULL, 0U); } void mailbox_set_qspi_direct(void) { - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, NULL, 0); + mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, NULL, 0U, + CMD_CASUAL, NULL, 0U); } void mailbox_set_qspi_close(void) { mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, 0, 0, 0, NULL, 0); + mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, NULL, 0U, + CMD_CASUAL, NULL, 0U); } -int mailbox_get_qspi_clock(void) +void mailbox_qspi_set_cs(uint32_t device_select) { - mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, - NULL, 0); -} - -void mailbox_qspi_set_cs(int device_select) -{ - uint32_t cs_setting = device_select; + uint32_t cs_setting; /* QSPI device select settings at 31:28 */ - cs_setting = (cs_setting << 28); + cs_setting = (device_select << 28); mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_SET_CS, &cs_setting, - 1, 0, NULL, 0); + 1U, CMD_CASUAL, NULL, 0U); } void mailbox_reset_cold(void) { mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0, 0, 0, NULL, 0); + mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, NULL, 0U, + CMD_CASUAL, NULL, 0U); +} + +int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, unsigned int resp_buf_len) +{ + return mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_SUBPARTITION_TABLE, + NULL, 0U, CMD_CASUAL, resp_buf, + resp_buf_len); +} + +struct rsu_status_info { + uint64_t current_image; + uint64_t fail_image; + uint32_t state; + uint32_t version; + uint32_t error_location; + uint32_t error_details; + uint32_t retry_counter; +}; + +int mailbox_rsu_status(uint32_t *resp_buf, unsigned int resp_buf_len) +{ + int ret; + struct rsu_status_info *info = (struct rsu_status_info *)resp_buf; + + info->retry_counter = ~0U; + + ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_STATUS, NULL, 0U, + CMD_CASUAL, resp_buf, + resp_buf_len); + + if (ret < 0) { + return ret; + } + + if (info->retry_counter != ~0U) { + if ((info->version & RSU_VERSION_ACMF_MASK) == 0U) { + info->version |= RSU_VERSION_ACMF; + } + } + + return ret; +} + +int mailbox_rsu_update(uint32_t *flash_offset) +{ + return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE, + flash_offset, 2U, + CMD_CASUAL, NULL, 0U); +} + +int mailbox_hps_stage_notify(uint32_t execution_stage) +{ + return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HPS_STAGE_NOTIFY, + &execution_stage, 1U, CMD_CASUAL, + NULL, 0U); } int mailbox_init(void) { - int status = 0; + int status; mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE | MBOX_INT_FLAG_UAE); - mmio_write_32(MBOX_OFFSET + MBOX_URG, 0); - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0); + mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U); + mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U); - status = mailbox_send_cmd(0, MBOX_CMD_RESTART, 0, 0, 1, NULL, 0); + status = mailbox_send_cmd(0U, MBOX_CMD_RESTART, NULL, 0U, + CMD_URGENT, NULL, 0U); - if (status) + if (status != 0) { return status; + } mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE | MBOX_INT_FLAG_UAE); - return 0; + return MBOX_RET_OK; } -uint32_t intel_mailbox_get_config_status(uint32_t cmd) +int intel_mailbox_get_config_status(uint32_t cmd) { - uint32_t status, res; - uint32_t response[6]; + int status; + uint32_t res, response[6]; - status = mailbox_send_cmd(1, cmd, NULL, 0, 0, response, - sizeof(response) / sizeof(response[0])); + status = mailbox_send_cmd(MBOX_JOB_ID, cmd, NULL, 0U, CMD_CASUAL, + response, ARRAY_SIZE(response)); - if (status < 0) + if (status < 0) { return status; + } res = response[RECONFIG_STATUS_STATE]; - if (res && res != MBOX_CFGSTAT_STATE_CONFIG) + if ((res != 0U) && (res != MBOX_CFGSTAT_STATE_CONFIG)) { return res; + } res = response[RECONFIG_STATUS_PIN_STATUS]; - if (!(res & PIN_STATUS_NSTATUS)) + if ((res & PIN_STATUS_NSTATUS) == 0U) { return MBOX_CFGSTAT_STATE_ERROR_HARDWARE; + } res = response[RECONFIG_STATUS_SOFTFUNC_STATUS]; - if (res & SOFTFUNC_STATUS_SEU_ERROR) + if ((res & SOFTFUNC_STATUS_SEU_ERROR) != 0U) { return MBOX_CFGSTAT_STATE_ERROR_HARDWARE; + } - if ((res & SOFTFUNC_STATUS_CONF_DONE) && - (res & SOFTFUNC_STATUS_INIT_DONE)) - return 0; + if ((res & SOFTFUNC_STATUS_CONF_DONE) != 0U && + (res & SOFTFUNC_STATUS_INIT_DONE) != 0U) { + return MBOX_RET_OK; + } return MBOX_CFGSTAT_STATE_CONFIG; } @@ -321,8 +516,9 @@ int intel_mailbox_is_fpga_not_ready(void) { int ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS); - if (ret && ret != MBOX_CFGSTAT_STATE_CONFIG) + if ((ret != MBOX_RET_OK) && (ret != MBOX_CFGSTAT_STATE_CONFIG)) { ret = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS); + } return ret; } diff --git a/plat/intel/soc/common/socfpga_delay_timer.c b/plat/intel/soc/common/socfpga_delay_timer.c index ff8a556cf..c55cc9da6 100644 --- a/plat/intel/soc/common/socfpga_delay_timer.c +++ b/plat/intel/soc/common/socfpga_delay_timer.c @@ -36,4 +36,8 @@ void socfpga_delay_timer_init(void) { timer_init(&plat_timer_ops); mmio_write_32(SOCFPGA_GLOBAL_TIMER, SOCFPGA_GLOBAL_TIMER_EN); + + asm volatile("msr cntp_ctl_el0, %0" : : "r" (SOCFPGA_GLOBAL_TIMER_EN)); + asm volatile("msr cntp_tval_el0, %0" : : "r" (~0)); + } diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c index d8a6c1980..4b57b8f31 100644 --- a/plat/intel/soc/common/socfpga_psci.c +++ b/plat/intel/soc/common/socfpga_psci.c @@ -130,9 +130,19 @@ static void __dead2 socfpga_system_off(void) panic(); } +extern uint64_t intel_rsu_update_address; + static void __dead2 socfpga_system_reset(void) { - mailbox_reset_cold(); + uint32_t addr_buf[2]; + + memcpy(addr_buf, &intel_rsu_update_address, + sizeof(intel_rsu_update_address)); + + if (intel_rsu_update_address) + mailbox_rsu_update(addr_buf); + else + mailbox_reset_cold(); while (1) wfi(); diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 41dae9e76..86a44556a 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,30 +14,15 @@ #include "socfpga_reset_manager.h" #include "socfpga_sip_svc.h" -/* Number of SiP Calls implemented */ -#define SIP_NUM_CALLS 0x3 /* Total buffer the driver can hold */ #define FPGA_CONFIG_BUFFER_SIZE 4 -static int current_block; -static int read_block; -static int current_buffer; -static int send_id; -static int rcv_id; -static int max_blocks; -static uint32_t bytes_per_block; -static uint32_t blocks_submitted; -static int is_partial_reconfig; - -struct fpga_config_info { - uint32_t addr; - int size; - int size_written; - uint32_t write_requested; - int subblocks_sent; - int block_number; -}; +static int current_block, current_buffer; +static int read_block, max_blocks, is_partial_reconfig; +static uint32_t send_id, rcv_id; +static uint32_t bytes_per_block, blocks_submitted; + /* SiP Service UUID */ DEFINE_SVC_UUID2(intl_svc_uid, @@ -74,10 +59,8 @@ static int intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer) args[2] = bytes_per_block; buffer->size_written += args[2]; - mailbox_send_cmd_async( - send_id++ % MBOX_MAX_JOB_ID, - MBOX_RECONFIG_DATA, - args, 3, 0); + mailbox_send_cmd_async(&send_id, MBOX_RECONFIG_DATA, args, + 3U, CMD_INDIRECT); buffer->subblocks_sent++; max_blocks--; @@ -143,7 +126,7 @@ static int mark_last_buffer_xfer_completed(uint32_t *buffer_addr_completed) } static int intel_fpga_config_completed_write(uint32_t *completed_addr, - uint32_t *count) + uint32_t *count, uint32_t *job_id) { uint32_t status = INTEL_SIP_SMC_STATUS_OK; *count = 0; @@ -153,14 +136,13 @@ static int intel_fpga_config_completed_write(uint32_t *completed_addr, while (*count < 3) { - resp_len = mailbox_read_response(rcv_id % MBOX_MAX_JOB_ID, - resp, sizeof(resp) / sizeof(resp[0])); + resp_len = mailbox_read_response(job_id, + resp, ARRAY_SIZE(resp)); if (resp_len < 0) break; max_blocks++; - rcv_id++; if (mark_last_buffer_xfer_completed( &completed_addr[*count]) == 0) @@ -208,10 +190,10 @@ static int intel_fpga_config_start(uint32_t config_type) mailbox_clear_response(); - mailbox_send_cmd(1, MBOX_CMD_CANCEL, 0, 0, 0, NULL, 0); + mailbox_send_cmd(1U, MBOX_CMD_CANCEL, NULL, 0U, CMD_CASUAL, NULL, 0U); - status = mailbox_send_cmd(1, MBOX_RECONFIG, 0, 0, 0, - response, sizeof(response) / sizeof(response[0])); + status = mailbox_send_cmd(1U, MBOX_RECONFIG, NULL, 0U, CMD_CASUAL, + response, ARRAY_SIZE(response)); if (status < 0) return status; @@ -232,8 +214,6 @@ static int intel_fpga_config_start(uint32_t config_type) current_block = 0; read_block = 0; current_buffer = 0; - send_id = 0; - rcv_id = 0; /* full reconfiguration */ if (!is_partial_reconfig) { @@ -252,12 +232,16 @@ static bool is_fpga_config_buffer_full(void) return true; } -static bool is_address_in_ddr_range(uint64_t addr) +bool is_address_in_ddr_range(uint64_t addr, uint64_t size) { - if (addr >= DRAM_BASE && addr <= DRAM_BASE + DRAM_SIZE) - return true; + if (size > (UINT64_MAX - addr)) + return false; + if (addr < BL31_LIMIT) + return false; + if (addr + size > DRAM_BASE + DRAM_SIZE) + return false; - return false; + return true; } static uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size) @@ -266,8 +250,7 @@ static uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size) intel_fpga_sdm_write_all(); - if (!is_address_in_ddr_range(mem) || - !is_address_in_ddr_range(mem + size) || + if (!is_address_in_ddr_range(mem, size) || is_fpga_config_buffer_full()) return INTEL_SIP_SMC_STATUS_REJECTED; @@ -365,6 +348,66 @@ uint32_t intel_secure_reg_update(uint64_t reg_addr, uint32_t mask, return INTEL_SIP_SMC_STATUS_ERROR; } +/* Intel Remote System Update (RSU) services */ +uint64_t intel_rsu_update_address; + +static uint32_t intel_rsu_status(uint64_t *respbuf, unsigned int respbuf_sz) +{ + if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) + return INTEL_SIP_SMC_RSU_ERROR; + + return INTEL_SIP_SMC_STATUS_OK; +} + +static uint32_t intel_rsu_update(uint64_t update_address) +{ + intel_rsu_update_address = update_address; + return INTEL_SIP_SMC_STATUS_OK; +} + +static uint32_t intel_rsu_notify(uint32_t execution_stage) +{ + if (mailbox_hps_stage_notify(execution_stage) < 0) + return INTEL_SIP_SMC_RSU_ERROR; + + return INTEL_SIP_SMC_STATUS_OK; +} + +static uint32_t intel_rsu_retry_counter(uint32_t *respbuf, uint32_t respbuf_sz, + uint32_t *ret_stat) +{ + if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) + return INTEL_SIP_SMC_RSU_ERROR; + + *ret_stat = respbuf[8]; + return INTEL_SIP_SMC_STATUS_OK; +} + +/* Mailbox services */ +static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args, uint32_t len, + uint32_t urgent, uint32_t *response, + uint32_t resp_len, int *mbox_status, + int *len_in_resp) +{ + *len_in_resp = 0; + *mbox_status = 0; + + if (!is_address_in_ddr_range((uint64_t)args, sizeof(uint32_t) * len)) + return INTEL_SIP_SMC_STATUS_REJECTED; + + int status = mailbox_send_cmd(MBOX_JOB_ID, cmd, args, len, urgent, + response, resp_len); + + if (status < 0) { + *mbox_status = -status; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + *mbox_status = 0; + *len_in_resp = status; + return INTEL_SIP_SMC_STATUS_OK; +} + /* * This function is responsible for handling all SiP calls from the NS world */ @@ -378,10 +421,13 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, void *handle, u_register_t flags) { - uint32_t val = 0; + uint32_t retval = 0; uint32_t status = INTEL_SIP_SMC_STATUS_OK; uint32_t completed_addr[3]; - uint32_t count = 0; + uint64_t rsu_respbuf[9]; + u_register_t x5, x6; + int mbox_status, len_in_resp; + switch (smc_fid) { case SIP_SVC_UID: @@ -408,8 +454,8 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, case INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE: status = intel_fpga_config_completed_write(completed_addr, - &count); - switch (count) { + &retval, &rcv_id); + switch (retval) { case 1: SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, completed_addr[0], 0, 0); @@ -434,17 +480,52 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, } case INTEL_SIP_SMC_REG_READ: - status = intel_secure_reg_read(x1, &val); - SMC_RET3(handle, status, val, x1); + status = intel_secure_reg_read(x1, &retval); + SMC_RET3(handle, status, retval, x1); case INTEL_SIP_SMC_REG_WRITE: - status = intel_secure_reg_write(x1, (uint32_t)x2, &val); - SMC_RET3(handle, status, val, x1); + status = intel_secure_reg_write(x1, (uint32_t)x2, &retval); + SMC_RET3(handle, status, retval, x1); case INTEL_SIP_SMC_REG_UPDATE: status = intel_secure_reg_update(x1, (uint32_t)x2, - (uint32_t)x3, &val); - SMC_RET3(handle, status, val, x1); + (uint32_t)x3, &retval); + SMC_RET3(handle, status, retval, x1); + + case INTEL_SIP_SMC_RSU_STATUS: + status = intel_rsu_status(rsu_respbuf, + ARRAY_SIZE(rsu_respbuf)); + if (status) { + SMC_RET1(handle, status); + } else { + SMC_RET4(handle, rsu_respbuf[0], rsu_respbuf[1], + rsu_respbuf[2], rsu_respbuf[3]); + } + + case INTEL_SIP_SMC_RSU_UPDATE: + status = intel_rsu_update(x1); + SMC_RET1(handle, status); + + case INTEL_SIP_SMC_RSU_NOTIFY: + status = intel_rsu_notify(x1); + SMC_RET1(handle, status); + + case INTEL_SIP_SMC_RSU_RETRY_COUNTER: + status = intel_rsu_retry_counter((uint32_t *)rsu_respbuf, + ARRAY_SIZE(rsu_respbuf), &retval); + if (status) { + SMC_RET1(handle, status); + } else { + SMC_RET2(handle, status, retval); + } + + case INTEL_SIP_SMC_MBOX_SEND_CMD: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + x6 = SMC_GET_GP(handle, CTX_GPREG_X6); + status = intel_mbox_send_cmd(x1, (uint32_t *)x2, x3, x4, + (uint32_t *)x5, x6, &mbox_status, + &len_in_resp); + SMC_RET4(handle, status, mbox_status, x5, len_in_resp); default: return socfpga_sip_handler(smc_fid, x1, x2, x3, x4, diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c index 7d183db0d..721a6903c 100644 --- a/plat/intel/soc/stratix10/bl2_plat_setup.c +++ b/plat/intel/soc/stratix10/bl2_plat_setup.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2019, Intel Corporation. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,6 +16,7 @@ #include <lib/xlat_tables/xlat_tables.h> #include "qspi/cadence_qspi.h" +#include "socfpga_emac.h" #include "socfpga_handoff.h" #include "socfpga_mailbox.h" #include "socfpga_private.h" @@ -45,12 +46,12 @@ const mmap_region_t plat_stratix10_mmap[] = { {0}, }; -boot_source_type boot_source; +boot_source_type boot_source = BOOT_SOURCE; void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, u_register_t x2, u_register_t x4) { - static console_16550_t console; + static console_t console; handoff reverse_handoff_ptr; generic_delay_timer_init(); @@ -58,7 +59,6 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, if (socfpga_get_handoff(&reverse_handoff_ptr)) return; config_pinmux(&reverse_handoff_ptr); - boot_source = reverse_handoff_ptr.boot_source; config_clkmgr_handoff(&reverse_handoff_ptr); enable_nonsecure_access(); @@ -70,6 +70,7 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, console_16550_register(PLAT_UART0_BASE, get_uart_clk(), PLAT_BAUDRATE, &console); + socfpga_emac_init(); socfpga_delay_timer_init(); init_hard_memory_controller(); mailbox_init(); diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c index 29f57c467..128a8080d 100644 --- a/plat/intel/soc/stratix10/bl31_plat_setup.c +++ b/plat/intel/soc/stratix10/bl31_plat_setup.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2019, Intel Corporation. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,6 +16,7 @@ #include <plat/common/platform.h> #include <platform_def.h> +#include "socfpga_mailbox.h" #include "socfpga_private.h" #include "socfpga_reset_manager.h" #include "socfpga_system_manager.h" @@ -44,7 +45,9 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { - static console_16550_t console; + static console_t console; + + mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY); console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE, &console); @@ -106,6 +109,8 @@ static const gicv2_driver_data_t plat_gicv2_gic_data = { ******************************************************************************/ void bl31_platform_setup(void) { + socfpga_delay_timer_init(); + /* Initialize the gic cpu and distributor interfaces */ gicv2_driver_init(&plat_gicv2_gic_data); gicv2_distif_init(); @@ -115,6 +120,8 @@ void bl31_platform_setup(void) /* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */ mmio_write_64(PLAT_CPU_RELEASE_ADDR, (uint64_t)plat_secondary_cpus_bl31_entry); + + mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL); } const mmap_region_t plat_stratix10_mmap[] = { diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h index 9dc51514c..a2bd57b08 100644 --- a/plat/intel/soc/stratix10/include/socfpga_plat_def.h +++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h @@ -10,7 +10,8 @@ #include <platform_def.h> /* Platform Setting */ -#define PLATFORM_MODEL PLAT_SOCFPGA_STRATIX10 +#define PLATFORM_MODEL PLAT_SOCFPGA_STRATIX10 +#define BOOT_SOURCE BOOT_SOURCE_SDMMC /* Register Mapping */ #define SOCFPGA_MMC_REG_BASE 0xff808000 diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk index efbab24b3..8bbd01027 100644 --- a/plat/intel/soc/stratix10/platform.mk +++ b/plat/intel/soc/stratix10/platform.mk @@ -1,6 +1,6 @@ # -# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. -# Copyright (c) 2019, Intel Corporation. All rights reserved. +# Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2019-2020, Intel Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -10,18 +10,23 @@ PLAT_INCLUDES := \ -Iplat/intel/soc/common/drivers/ \ -Iplat/intel/soc/common/include/ +# Include GICv2 driver files +include drivers/arm/gic/v2/gicv2.mk +AGX_GICv2_SOURCES := \ + ${GICV2_SOURCES} \ + plat/common/plat_gicv2.c + + PLAT_BL_COMMON_SOURCES := \ - drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ + ${AGX_GICv2_SOURCES} \ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ drivers/ti/uart/aarch64/16550_console.S \ lib/xlat_tables/aarch64/xlat_tables.c \ lib/xlat_tables/xlat_tables_common.c \ - plat/common/plat_gicv2.c \ plat/intel/soc/common/aarch64/platform_common.c \ - plat/intel/soc/common/aarch64/plat_helpers.S + plat/intel/soc/common/aarch64/plat_helpers.S \ + plat/intel/soc/common/socfpga_delay_timer.c BL2_SOURCES += \ common/desc_image_load.c \ @@ -39,9 +44,9 @@ BL2_SOURCES += \ plat/intel/soc/stratix10/soc/s10_memory_controller.c \ plat/intel/soc/stratix10/soc/s10_pinmux.c \ plat/intel/soc/common/bl2_plat_mem_params_desc.c \ - plat/intel/soc/common/socfpga_delay_timer.c \ plat/intel/soc/common/socfpga_image_load.c \ plat/intel/soc/common/socfpga_storage.c \ + plat/intel/soc/common/soc/socfpga_emac.c \ plat/intel/soc/common/soc/socfpga_handoff.c \ plat/intel/soc/common/soc/socfpga_mailbox.c \ plat/intel/soc/common/soc/socfpga_reset_manager.c \ |