diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:13:47 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:13:47 +0000 |
commit | 102b0d2daa97dae68d3eed54d8fe37a9cc38a892 (patch) | |
tree | bcf648efac40ca6139842707f0eba5a4496a6dd2 /plat/intel/soc/stratix10 | |
parent | Initial commit. (diff) | |
download | arm-trusted-firmware-upstream/2.8.0+dfsg.tar.xz arm-trusted-firmware-upstream/2.8.0+dfsg.zip |
Adding upstream version 2.8.0+dfsg.upstream/2.8.0+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'plat/intel/soc/stratix10')
-rw-r--r-- | plat/intel/soc/stratix10/bl2_plat_setup.c | 188 | ||||
-rw-r--r-- | plat/intel/soc/stratix10/bl31_plat_setup.c | 173 | ||||
-rw-r--r-- | plat/intel/soc/stratix10/include/s10_clock_manager.h | 99 | ||||
-rw-r--r-- | plat/intel/soc/stratix10/include/s10_memory_controller.h | 160 | ||||
-rw-r--r-- | plat/intel/soc/stratix10/include/s10_mmc.h | 12 | ||||
-rw-r--r-- | plat/intel/soc/stratix10/include/s10_pinmux.h | 20 | ||||
-rw-r--r-- | plat/intel/soc/stratix10/include/socfpga_plat_def.h | 40 | ||||
-rw-r--r-- | plat/intel/soc/stratix10/platform.mk | 80 | ||||
-rw-r--r-- | plat/intel/soc/stratix10/soc/s10_clock_manager.c | 322 | ||||
-rw-r--r-- | plat/intel/soc/stratix10/soc/s10_memory_controller.c | 412 | ||||
-rw-r--r-- | plat/intel/soc/stratix10/soc/s10_mmc.c | 19 | ||||
-rw-r--r-- | plat/intel/soc/stratix10/soc/s10_pinmux.c | 217 |
12 files changed, 1742 insertions, 0 deletions
diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c new file mode 100644 index 0000000..73e3216 --- /dev/null +++ b/plat/intel/soc/stratix10/bl2_plat_setup.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2022, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <arch_helpers.h> +#include <assert.h> +#include <common/bl_common.h> +#include <common/debug.h> +#include <common/desc_image_load.h> +#include <drivers/generic_delay_timer.h> +#include <drivers/synopsys/dw_mmc.h> +#include <drivers/ti/uart/uart_16550.h> +#include <lib/xlat_tables/xlat_tables.h> + +#include "qspi/cadence_qspi.h" +#include "socfpga_emac.h" +#include "socfpga_f2sdram_manager.h" +#include "socfpga_handoff.h" +#include "socfpga_mailbox.h" +#include "socfpga_private.h" +#include "socfpga_reset_manager.h" +#include "socfpga_system_manager.h" +#include "s10_clock_manager.h" +#include "s10_memory_controller.h" +#include "s10_mmc.h" +#include "s10_pinmux.h" +#include "wdt/watchdog.h" + +static struct mmc_device_info mmc_info; + +const mmap_region_t plat_stratix10_mmap[] = { + MAP_REGION_FLAT(DRAM_BASE, DRAM_SIZE, + MT_MEMORY | MT_RW | MT_NS), + MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, + MT_DEVICE | MT_RW | MT_NS), + MAP_REGION_FLAT(DEVICE2_BASE, DEVICE2_SIZE, + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(OCRAM_BASE, OCRAM_SIZE, + MT_NON_CACHEABLE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(DEVICE3_BASE, DEVICE3_SIZE, + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(MEM64_BASE, MEM64_SIZE, + MT_DEVICE | MT_RW | MT_NS), + MAP_REGION_FLAT(DEVICE4_BASE, DEVICE4_SIZE, + MT_DEVICE | MT_RW | MT_NS), + {0}, +}; + +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_t console; + handoff reverse_handoff_ptr; + + generic_delay_timer_init(); + + if (socfpga_get_handoff(&reverse_handoff_ptr)) + return; + config_pinmux(&reverse_handoff_ptr); + + config_clkmgr_handoff(&reverse_handoff_ptr); + enable_nonsecure_access(); + deassert_peripheral_reset(); + config_hps_hs_before_warm_reset(); + + watchdog_init(get_wdt_clk()); + + console_16550_register(PLAT_INTEL_UART_BASE, get_uart_clk(), + PLAT_BAUDRATE, &console); + + socfpga_emac_init(); + socfpga_delay_timer_init(); + init_hard_memory_controller(); + mailbox_init(); + s10_mmc_init(); + + if (!intel_mailbox_is_fpga_not_ready()) { + socfpga_bridges_enable(SOC2FPGA_MASK | LWHPS2FPGA_MASK | + FPGA2SOC_MASK | F2SDRAM0_MASK | F2SDRAM1_MASK | + F2SDRAM2_MASK); + } +} + + +void bl2_el3_plat_arch_setup(void) +{ + + const mmap_region_t bl_regions[] = { + MAP_REGION_FLAT(BL2_BASE, BL2_END - BL2_BASE, + MT_MEMORY | MT_RW | MT_SECURE), + MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, + MT_CODE | MT_SECURE), + MAP_REGION_FLAT(BL_RO_DATA_BASE, + BL_RO_DATA_END - BL_RO_DATA_BASE, + MT_RO_DATA | MT_SECURE), +#if USE_COHERENT_MEM_BAR + MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, + MT_DEVICE | MT_RW | MT_SECURE), +#endif + {0}, + }; + + setup_page_tables(bl_regions, plat_stratix10_mmap); + + enable_mmu_el3(0); + + dw_mmc_params_t params = EMMC_INIT_PARAMS(0x100000, get_mmc_clk()); + + mmc_info.mmc_dev_type = MMC_IS_SD; + mmc_info.ocr_voltage = OCR_3_3_3_4 | OCR_3_2_3_3; + + /* Request ownership and direct access to QSPI */ + mailbox_hps_qspi_enable(); + + switch (boot_source) { + case BOOT_SOURCE_SDMMC: + dw_mmc_init(¶ms, &mmc_info); + socfpga_io_setup(boot_source); + break; + + case BOOT_SOURCE_QSPI: + cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL, + QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS, + QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0); + socfpga_io_setup(boot_source); + break; + + default: + ERROR("Unsupported boot source\n"); + panic(); + break; + } +} + +uint32_t get_spsr_for_bl33_entry(void) +{ + unsigned long el_status; + unsigned int mode; + uint32_t spsr; + + /* Figure out what mode we enter the non-secure world in */ + el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; + el_status &= ID_AA64PFR0_ELX_MASK; + + mode = (el_status) ? MODE_EL2 : MODE_EL1; + + /* + * TODO: Consider the possibility of specifying the SPSR in + * the FIP ToC and allowing the platform to have a say as + * well. + */ + spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + return spsr; +} + + +int bl2_plat_handle_post_image_load(unsigned int image_id) +{ + bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); + + assert(bl_mem_params); + + switch (image_id) { + case BL33_IMAGE_ID: + bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); + bl_mem_params->ep_info.spsr = get_spsr_for_bl33_entry(); + break; + default: + break; + } + + return 0; +} + +/******************************************************************************* + * Perform any BL3-1 platform setup code + ******************************************************************************/ +void bl2_platform_setup(void) +{ +} + diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c new file mode 100644 index 0000000..be0fae5 --- /dev/null +++ b/plat/intel/soc/stratix10/bl31_plat_setup.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2022, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <arch_helpers.h> +#include <assert.h> +#include <common/bl_common.h> +#include <drivers/arm/gicv2.h> +#include <drivers/ti/uart/uart_16550.h> +#include <lib/xlat_tables/xlat_tables.h> +#include <lib/mmio.h> +#include <plat/common/platform.h> +#include <platform_def.h> + +#include "socfpga_mailbox.h" +#include "socfpga_noc.h" +#include "socfpga_private.h" +#include "socfpga_reset_manager.h" +#include "socfpga_system_manager.h" +#include "s10_memory_controller.h" +#include "s10_pinmux.h" +#include "s10_clock_manager.h" + + +static entry_point_info_t bl32_image_ep_info; +static entry_point_info_t bl33_image_ep_info; + +entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) +{ + entry_point_info_t *next_image_info; + + next_image_info = (type == NON_SECURE) ? + &bl33_image_ep_info : &bl32_image_ep_info; + + /* None of the images on this platform can have 0x0 as the entrypoint */ + if (next_image_info->pc) + return next_image_info; + else + return NULL; +} + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + static console_t console; + + mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY); + + console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK, + PLAT_BAUDRATE, &console); + /* + * Check params passed from BL31 should not be NULL, + */ + void *from_bl2 = (void *) arg0; + + bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2; + assert(params_from_bl2 != NULL); + + /* + * Copy BL32 (if populated by BL31) and BL33 entry point information. + * They are stored in Secure RAM, in BL31's address space. + */ + + 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; + + bl_params = bl_params->next_params_info; + } + } else { + struct socfpga_bl31_params *arg_from_bl2 = + (struct socfpga_bl31_params *) from_bl2; + + 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); +} + +static const interrupt_prop_t s10_interrupt_props[] = { + PLAT_INTEL_SOCFPGA_G1S_IRQ_PROPS(GICV2_INTR_GROUP0), + PLAT_INTEL_SOCFPGA_G0_IRQ_PROPS(GICV2_INTR_GROUP0) +}; + +static unsigned int target_mask_array[PLATFORM_CORE_COUNT]; + +static const gicv2_driver_data_t plat_gicv2_gic_data = { + .gicd_base = PLAT_INTEL_SOCFPGA_GICD_BASE, + .gicc_base = PLAT_INTEL_SOCFPGA_GICC_BASE, + .interrupt_props = s10_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(s10_interrupt_props), + .target_masks = target_mask_array, + .target_masks_num = ARRAY_SIZE(target_mask_array), +}; + +/******************************************************************************* + * Perform any BL3-1 platform setup code + ******************************************************************************/ +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); + + enable_ocram_firewall(); +} + +const mmap_region_t plat_stratix10_mmap[] = { + MAP_REGION_FLAT(DRAM_BASE, DRAM_SIZE, + MT_MEMORY | MT_RW | MT_NS), + MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, + MT_DEVICE | MT_RW | MT_NS), + MAP_REGION_FLAT(DEVICE2_BASE, DEVICE2_SIZE, + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(OCRAM_BASE, OCRAM_SIZE, + MT_NON_CACHEABLE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(DEVICE3_BASE, DEVICE3_SIZE, + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(MEM64_BASE, MEM64_SIZE, + MT_DEVICE | MT_RW | MT_NS), + MAP_REGION_FLAT(DEVICE4_BASE, DEVICE4_SIZE, + MT_DEVICE | MT_RW | MT_NS), + {0} +}; + +/******************************************************************************* + * Perform the very early platform specific architectural setup here. At the + * moment this is only intializes the mmu in a quick and dirty way. + ******************************************************************************/ +void bl31_plat_arch_setup(void) +{ + const mmap_region_t bl_regions[] = { + MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE, + MT_MEMORY | MT_RW | MT_SECURE), + MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, + MT_CODE | MT_SECURE), + MAP_REGION_FLAT(BL_RO_DATA_BASE, + BL_RO_DATA_END - BL_RO_DATA_BASE, + MT_RO_DATA | MT_SECURE), +#if USE_COHERENT_MEM + MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, + MT_DEVICE | MT_RW | MT_SECURE), +#endif + {0} + }; + + setup_page_tables(bl_regions, plat_stratix10_mmap); + enable_mmu_el3(0); +} + diff --git a/plat/intel/soc/stratix10/include/s10_clock_manager.h b/plat/intel/soc/stratix10/include/s10_clock_manager.h new file mode 100644 index 0000000..cf57df3 --- /dev/null +++ b/plat/intel/soc/stratix10/include/s10_clock_manager.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2019-2022, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __CLOCKMANAGER_H__ +#define __CLOCKMANAGER_H__ + +#include "socfpga_handoff.h" + +#define ALT_CLKMGR 0xffd10000 + +#define ALT_CLKMGR_CTRL 0x0 +#define ALT_CLKMGR_STAT 0x4 +#define ALT_CLKMGR_INTRCLR 0x14 +#define ALT_CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK 0x00000004 +#define ALT_CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK 0x00000008 + +#define ALT_CLKMGR_CTRL_BOOTMODE_SET_MSK 0x00000001 +#define ALT_CLKMGR_STAT_BUSY_E_BUSY 0x1 +#define ALT_CLKMGR_STAT_BUSY(x) (((x) & 0x00000001) >> 0) +#define ALT_CLKMGR_STAT_MAINPLLLOCKED(x) (((x) & 0x00000100) >> 8) +#define ALT_CLKMGR_STAT_PERPLLLOCKED(x) (((x) & 0x00000200) >> 9) + +#define ALT_CLKMGR_MAINPLL 0xffd10030 +#define ALT_CLKMGR_MAINPLL_EN 0x0 +#define ALT_CLKMGR_MAINPLL_BYPASS 0xc +#define ALT_CLKMGR_MAINPLL_MPUCLK 0x18 +#define ALT_CLKMGR_MAINPLL_NOCCLK 0x1c +#define ALT_CLKMGR_MAINPLL_CNTR2CLK 0x20 +#define ALT_CLKMGR_MAINPLL_CNTR3CLK 0x24 +#define ALT_CLKMGR_MAINPLL_CNTR4CLK 0x28 +#define ALT_CLKMGR_MAINPLL_CNTR5CLK 0x2c +#define ALT_CLKMGR_MAINPLL_CNTR6CLK 0x30 +#define ALT_CLKMGR_MAINPLL_CNTR7CLK 0x34 +#define ALT_CLKMGR_MAINPLL_CNTR8CLK 0x38 +#define ALT_CLKMGR_MAINPLL_CNTR9CLK 0x3c +#define ALT_CLKMGR_MAINPLL_NOCDIV 0x40 +#define ALT_CLKMGR_MAINPLL_PLLGLOB 0x44 +#define ALT_CLKMGR_MAINPLL_FDBCK 0x48 +#define ALT_CLKMGR_MAINPLL_PLLC0 0x54 +#define ALT_CLKMGR_MAINPLL_PLLC1 0x58 +#define ALT_CLKMGR_MAINPLL_VCOCALIB 0x5c +#define ALT_CLKMGR_MAINPLL_EN_RESET 0x000000ff +#define ALT_CLKMGR_MAINPLL_FDBCK_MDIV(x) (((x) & 0xff000000) >> 24) +#define ALT_CLKMGR_MAINPLL_PLLGLOB_PD_SET_MSK 0x00000001 +#define ALT_CLKMGR_MAINPLL_PLLGLOB_REFCLKDIV(x) (((x) & 0x00003f00) >> 8) +#define ALT_CLKMGR_MAINPLL_PLLGLOB_RST_SET_MSK 0x00000002 +#define ALT_CLKMGR_MAINPLL_VCOCALIB_HSCNT_SET(x) (((x) << 0) & 0x000000ff) +#define ALT_CLKMGR_MAINPLL_VCOCALIB_MSCNT_SET(x) (((x) << 9) & 0x0001fe00) + +#define ALT_CLKMGR_PSRC(x) (((x) & 0x00030000) >> 16) +#define ALT_CLKMGR_SRC_MAIN 0 +#define ALT_CLKMGR_SRC_PER 1 + +#define ALT_CLKMGR_PLLGLOB_PSRC_EOSC1 0x0 +#define ALT_CLKMGR_PLLGLOB_PSRC_INTOSC 0x1 +#define ALT_CLKMGR_PLLGLOB_PSRC_F2S 0x2 + +#define ALT_CLKMGR_PERPLL 0xffd100a4 +#define ALT_CLKMGR_PERPLL_EN 0x0 +#define ALT_CLKMGR_PERPLL_EN_SDMMCCLK BIT(5) +#define ALT_CLKMGR_PERPLL_BYPASS 0xc +#define ALT_CLKMGR_PERPLL_CNTR2CLK 0x18 +#define ALT_CLKMGR_PERPLL_CNTR3CLK 0x1c +#define ALT_CLKMGR_PERPLL_CNTR4CLK 0x20 +#define ALT_CLKMGR_PERPLL_CNTR5CLK 0x24 +#define ALT_CLKMGR_PERPLL_CNTR6CLK 0x28 +#define ALT_CLKMGR_PERPLL_CNTR7CLK 0x2c +#define ALT_CLKMGR_PERPLL_CNTR8CLK 0x30 +#define ALT_CLKMGR_PERPLL_CNTR9CLK 0x34 +#define ALT_CLKMGR_PERPLL_GPIODIV 0x3c +#define ALT_CLKMGR_PERPLL_EMACCTL 0x38 +#define ALT_CLKMGR_PERPLL_PLLGLOB 0x40 +#define ALT_CLKMGR_PERPLL_FDBCK 0x44 +#define ALT_CLKMGR_PERPLL_PLLC0 0x50 +#define ALT_CLKMGR_PERPLL_PLLC1 0x54 +#define ALT_CLKMGR_PERPLL_EN_RESET 0x00000fff +#define ALT_CLKMGR_PERPLL_FDBCK_MDIV(x) (((x) & 0xff000000) >> 24) +#define ALT_CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(x) (((x) << 0) & 0x0000ffff) +#define ALT_CLKMGR_PERPLL_PLLGLOB_PD_SET_MSK 0x00000001 +#define ALT_CLKMGR_PERPLL_PLLGLOB_REFCLKDIV(x) (((x) & 0x00003f00) >> 8) +#define ALT_CLKMGR_PERPLL_PLLGLOB_REFCLKDIV_SET(x) (((x) << 8) & 0x00003f00) +#define ALT_CLKMGR_PERPLL_PLLGLOB_RST_SET_MSK 0x00000002 +#define ALT_CLKMGR_PERPLL_VCOCALIB_HSCNT_SET(x) (((x) << 0) & 0x000000ff) +#define ALT_CLKMGR_PERPLL_VCOCALIB_MSCNT_SET(x) (((x) << 9) & 0x0001fe00) +#define ALT_CLKMGR_PERPLL_VCOCALIB 0x58 + +#define ALT_CLKMGR_INTOSC_HZ 460000000 + +void config_clkmgr_handoff(handoff *hoff_ptr); +uint32_t get_wdt_clk(void); +uint32_t get_uart_clk(void); +uint32_t get_mmc_clk(void); +uint32_t get_l3_clk(uint32_t ref_clk); +uint32_t get_ref_clk(uint32_t pllglob); + +#endif diff --git a/plat/intel/soc/stratix10/include/s10_memory_controller.h b/plat/intel/soc/stratix10/include/s10_memory_controller.h new file mode 100644 index 0000000..155b279 --- /dev/null +++ b/plat/intel/soc/stratix10/include/s10_memory_controller.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2019, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __S10_MEMORYCONTROLLER_H__ +#define __S10_MEMORYCONTROLLER_H__ + +#define S10_MPFE_IOHMC_REG_DRAMADDRW 0xf80100a8 +#define S10_MPFE_IOHMC_CTRLCFG0 0xf8010028 +#define S10_MPFE_IOHMC_CTRLCFG1 0xf801002c +#define S10_MPFE_IOHMC_DRAMADDRW 0xf80100a8 +#define S10_MPFE_IOHMC_DRAMTIMING0 0xf8010050 +#define S10_MPFE_IOHMC_CALTIMING0 0xf801007c +#define S10_MPFE_IOHMC_CALTIMING1 0xf8010080 +#define S10_MPFE_IOHMC_CALTIMING2 0xf8010084 +#define S10_MPFE_IOHMC_CALTIMING3 0xf8010088 +#define S10_MPFE_IOHMC_CALTIMING4 0xf801008c +#define S10_MPFE_IOHMC_CALTIMING9 0xf80100a0 +#define S10_MPFE_IOHMC_CALTIMING9_ACT_TO_ACT(x) (((x) & 0x000000ff) >> 0) +#define S10_MPFE_IOHMC_CTRLCFG1_CFG_ADDR_ORDER(value) \ + (((value) & 0x00000060) >> 5) + + +#define S10_MPFE_HMC_ADP_ECCCTRL1 0xf8011100 +#define S10_MPFE_HMC_ADP_ECCCTRL2 0xf8011104 +#define S10_MPFE_HMC_ADP_RSTHANDSHAKESTAT 0xf8011218 +#define S10_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE 0x000000ff +#define S10_MPFE_HMC_ADP_RSTHANDSHAKECTRL 0xf8011214 + + +#define S10_MPFE_IOHMC_REG_CTRLCFG1 0xf801002c + +#define S10_MPFE_IOHMC_REG_NIOSRESERVE0_OFST 0xf8010110 + +#define IOHMC_DRAMADDRW_COL_ADDR_WIDTH(x) (((x) & 0x0000001f) >> 0) +#define IOHMC_DRAMADDRW_ROW_ADDR_WIDTH(x) (((x) & 0x000003e0) >> 5) +#define IOHMC_DRAMADDRW_CS_ADDR_WIDTH(x) (((x) & 0x00070000) >> 16) +#define IOHMC_DRAMADDRW_BANK_GRP_ADDR_WIDTH(x) (((x) & 0x0000c000) >> 14) +#define IOHMC_DRAMADDRW_BANK_ADDR_WIDTH(x) (((x) & 0x00003c00) >> 10) + +#define S10_MPFE_DDR(x) (0xf8000000 + x) +#define S10_MPFE_HMC_ADP_DDRCALSTAT 0xf801100c +#define S10_MPFE_DDR_MAIN_SCHED 0xf8000400 +#define S10_MPFE_DDR_MAIN_SCHED_DDRCONF 0xf8000408 +#define S10_MPFE_DDR_MAIN_SCHED_DDRTIMING 0xf800040c +#define S10_MPFE_DDR_MAIN_SCHED_DDRCONF_SET_MSK 0x0000001f +#define S10_MPFE_DDR_MAIN_SCHED_DDRMODE 0xf8000410 +#define S10_MPFE_DDR_MAIN_SCHED_DEVTODEV 0xf800043c +#define S10_MPFE_DDR_MAIN_SCHED_READLATENCY 0xf8000414 +#define S10_MPFE_DDR_MAIN_SCHED_ACTIVATE 0xf8000438 +#define S10_MPFE_DDR_MAIN_SCHED_ACTIVATE_FAWBANK_OFST 10 +#define S10_MPFE_DDR_MAIN_SCHED_ACTIVATE_FAW_OFST 4 +#define S10_MPFE_DDR_MAIN_SCHED_ACTIVATE_RRD_OFST 0 +#define S10_MPFE_DDR_MAIN_SCHED_DDRCONF_SET(x) (((x) << 0) & 0x0000001f) +#define S10_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTORD_OFST 0 +#define S10_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTORD_MSK (BIT(0) | BIT(1)) +#define S10_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTOWR_OFST 2 +#define S10_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTOWR_MSK (BIT(2) | BIT(3)) +#define S10_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSWRTORD_OFST 4 +#define S10_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSWRTORD_MSK (BIT(4) | BIT(5)) + +#define S10_MPFE_HMC_ADP(x) (0xf8011000 + (x)) +#define S10_MPFE_HMC_ADP_HPSINTFCSEL 0xf8011210 +#define S10_MPFE_HMC_ADP_DDRIOCTRL 0xf8011008 +#define HMC_ADP_DDRIOCTRL 0x8 +#define HMC_ADP_DDRIOCTRL_IO_SIZE(x) (((x) & 0x00000003) >> 0) +#define HMC_ADP_DDRIOCTRL_CTRL_BURST_LENGTH(x) (((x) & 0x00003e00) >> 9) +#define ADP_DRAMADDRWIDTH 0xe0 + +#define ACT_TO_ACT_DIFF_BANK(value) (((value) & 0x00fc0000) >> 18) +#define ACT_TO_ACT(value) (((value) & 0x0003f000) >> 12) +#define ACT_TO_RDWR(value) (((value) & 0x0000003f) >> 0) +#define ACT_TO_ACT(value) (((value) & 0x0003f000) >> 12) + +/* timing 2 */ +#define RD_TO_RD_DIFF_CHIP(value) (((value) & 0x00000fc0) >> 6) +#define RD_TO_WR_DIFF_CHIP(value) (((value) & 0x3f000000) >> 24) +#define RD_TO_WR(value) (((value) & 0x00fc0000) >> 18) +#define RD_TO_PCH(value) (((value) & 0x00000fc0) >> 6) + +/* timing 3 */ +#define CALTIMING3_WR_TO_RD_DIFF_CHIP(value) (((value) & 0x0003f000) >> 12) +#define CALTIMING3_WR_TO_RD(value) (((value) & 0x00000fc0) >> 6) + +/* timing 4 */ +#define PCH_TO_VALID(value) (((value) & 0x00000fc0) >> 6) + +#define DDRTIMING_BWRATIO_OFST 31 +#define DDRTIMING_WRTORD_OFST 26 +#define DDRTIMING_RDTOWR_OFST 21 +#define DDRTIMING_BURSTLEN_OFST 18 +#define DDRTIMING_WRTOMISS_OFST 12 +#define DDRTIMING_RDTOMISS_OFST 6 +#define DDRTIMING_ACTTOACT_OFST 0 + +#define ADP_DDRIOCTRL_IO_SIZE(x) (((x) & 0x00000003) >> 0) + +#define DDRMODE_AUTOPRECHARGE_OFST 1 +#define DDRMODE_BWRATIOEXTENDED_OFST 0 + + +#define S10_MPFE_IOHMC_REG_DRAMTIMING0_CFG_TCL(x) (((x) & 0x0000007f) >> 0) +#define S10_MPFE_IOHMC_REG_CTRLCFG0_CFG_MEM_TYPE(x) (((x) & 0x0000000f) >> 0) + +#define S10_CCU_CPU0_MPRT_DDR 0xf7004400 +#define S10_CCU_CPU0_MPRT_MEM0 0xf70045c0 +#define S10_CCU_CPU0_MPRT_MEM1A 0xf70045e0 +#define S10_CCU_CPU0_MPRT_MEM1B 0xf7004600 +#define S10_CCU_CPU0_MPRT_MEM1C 0xf7004620 +#define S10_CCU_CPU0_MPRT_MEM1D 0xf7004640 +#define S10_CCU_CPU0_MPRT_MEM1E 0xf7004660 +#define S10_CCU_IOM_MPRT_MEM0 0xf7018560 +#define S10_CCU_IOM_MPRT_MEM1A 0xf7018580 +#define S10_CCU_IOM_MPRT_MEM1B 0xf70185a0 +#define S10_CCU_IOM_MPRT_MEM1C 0xf70185c0 +#define S10_CCU_IOM_MPRT_MEM1D 0xf70185e0 +#define S10_CCU_IOM_MPRT_MEM1E 0xf7018600 + +#define S10_NOC_FW_DDR_SCR 0xf8020100 +#define S10_NOC_FW_DDR_SCR_MPUREGION0ADDR_LIMITEXT 0xf802011c +#define S10_NOC_FW_DDR_SCR_MPUREGION0ADDR_LIMIT 0xf8020118 +#define S10_NOC_FW_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT 0xf802019c +#define S10_NOC_FW_DDR_SCR_NONMPUREGION0ADDR_LIMIT 0xf8020198 + +#define S10_SOC_NOC_FW_DDR_SCR_ENABLE 0xf8020100 +#define S10_CCU_NOC_DI_SET_MSK 0x10 + +#define S10_SYSMGR_CORE_HMC_CLK 0xffd120b4 +#define S10_SYSMGR_CORE_HMC_CLK_STATUS 0x00000001 + +#define S10_MPFE_IOHMC_NIOSRESERVE0_NIOS_RESERVE0(x) (((x) & 0x0000ffff) >> 0) +#define S10_MPFE_HMC_ADP_DDRIOCTRL_IO_SIZE_MSK 0x00000003 +#define S10_MPFE_HMC_ADP_DDRIOCTRL_IO_SIZE_OFST 0 +#define S10_MPFE_HMC_ADP_HPSINTFCSEL_ENABLE 0x001f1f1f +#define S10_IOHMC_CTRLCFG1_ENABLE_ECC_OFST 7 + +#define S10_MPFE_HMC_ADP_ECCCTRL1_AUTOWB_CNT_RST_SET_MSK 0x00010000 +#define S10_MPFE_HMC_ADP_ECCCTRL1_CNT_RST_SET_MSK 0x00000100 +#define S10_MPFE_HMC_ADP_ECCCTRL1_ECC_EN_SET_MSK 0x00000001 + +#define S10_MPFE_HMC_ADP_ECCCTRL2_AUTOWB_EN_SET_MSK 0x00000001 +#define S10_MPFE_HMC_ADP_ECCCTRL2_OVRW_RB_ECC_EN_SET_MSK 0x00010000 +#define S10_MPFE_HMC_ADP_ECCCTRL2_RMW_EN_SET_MSK 0x00000100 +#define S10_MPFE_HMC_ADP_DDRCALSTAT_CAL(value) (((value) & 0x00000001) >> 0) + + +#define S10_MPFE_HMC_ADP_DDRIOCTRL_IO_SIZE(x) (((x) & 0x00000003) >> 0) +#define IOHMC_DRAMADDRW_CFG_BANK_ADDR_WIDTH(x) (((x) & 0x00003c00) >> 10) +#define IOHMC_DRAMADDRW_CFG_BANK_GROUP_ADDR_WIDTH(x) (((x) & 0x0000c000) >> 14) +#define IOHMC_DRAMADDRW_CFG_COL_ADDR_WIDTH(x) (((x) & 0x0000001f) >> 0) +#define IOHMC_DRAMADDRW_CFG_CS_ADDR_WIDTH(x) (((x) & 0x00070000) >> 16) +#define IOHMC_DRAMADDRW_CFG_ROW_ADDR_WIDTH(x) (((x) & 0x000003e0) >> 5) + +#define S10_SDRAM_0_LB_ADDR 0x0 + +int init_hard_memory_controller(void); + +#endif diff --git a/plat/intel/soc/stratix10/include/s10_mmc.h b/plat/intel/soc/stratix10/include/s10_mmc.h new file mode 100644 index 0000000..99f86f5 --- /dev/null +++ b/plat/intel/soc/stratix10/include/s10_mmc.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2022, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __S10_MMC_H__ +#define __S10_MMC_H__ + +void s10_mmc_init(void); + +#endif /* S10_MMC_H */ diff --git a/plat/intel/soc/stratix10/include/s10_pinmux.h b/plat/intel/soc/stratix10/include/s10_pinmux.h new file mode 100644 index 0000000..82367d7 --- /dev/null +++ b/plat/intel/soc/stratix10/include/s10_pinmux.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2019, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __S10_PINMUX_H__ +#define __S10_PINMUX_H__ + +#define S10_PINMUX_PIN0SEL 0xffd13000 +#define S10_PINMUX_IO0CTRL 0xffd13130 +#define S10_PINMUX_PINMUX_EMAC0_USEFPGA 0xffd13300 +#define S10_PINMUX_IO0_DELAY 0xffd13400 + +#include "socfpga_handoff.h" + +void config_pinmux(handoff *handoff); + +#endif + diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h new file mode 100644 index 0000000..516cc75 --- /dev/null +++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_SOCFPGA_DEF_H +#define PLAT_SOCFPGA_DEF_H + +#include <platform_def.h> + +/* Platform Setting */ +#define PLATFORM_MODEL PLAT_SOCFPGA_STRATIX10 +#define BOOT_SOURCE BOOT_SOURCE_SDMMC + +/* FPGA config helpers */ +#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x400000 +#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 0x1000000 + +/* Register Mapping */ +#define SOCFPGA_CCU_NOC_REG_BASE 0xf7000000 +#define SOCFPGA_F2SDRAMMGR_REG_BASE U(0xf8024000) + +#define SOCFPGA_MMC_REG_BASE 0xff808000 + +#define SOCFPGA_RSTMGR_REG_BASE 0xffd11000 +#define SOCFPGA_SYSMGR_REG_BASE 0xffd12000 + +#define SOCFPGA_L4_PER_SCR_REG_BASE 0xffd21000 +#define SOCFPGA_L4_SYS_SCR_REG_BASE 0xffd21100 +#define SOCFPGA_SOC2FPGA_SCR_REG_BASE 0xffd21200 +#define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE 0xffd21300 + +/* Platform specific system counter */ +#define PLAT_SYS_COUNTER_FREQ_IN_MHZ get_cpu_clk() + +uint32_t get_cpu_clk(void); + +#endif /* PLATSOCFPGA_DEF_H */ + diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk new file mode 100644 index 0000000..b7eb4bd --- /dev/null +++ b/plat/intel/soc/stratix10/platform.mk @@ -0,0 +1,80 @@ +# +# Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2019-2022, Intel Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +PLAT_INCLUDES := \ + -Iplat/intel/soc/stratix10/include/ \ + -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 := \ + ${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/intel/soc/common/aarch64/platform_common.c \ + plat/intel/soc/common/aarch64/plat_helpers.S \ + plat/intel/soc/common/socfpga_delay_timer.c \ + plat/intel/soc/common/soc/socfpga_firewall.c + +BL2_SOURCES += \ + common/desc_image_load.c \ + drivers/mmc/mmc.c \ + drivers/intel/soc/stratix10/io/s10_memmap_qspi.c \ + drivers/io/io_storage.c \ + drivers/io/io_block.c \ + drivers/io/io_fip.c \ + drivers/partition/partition.c \ + drivers/partition/gpt.c \ + drivers/synopsys/emmc/dw_mmc.c \ + lib/cpus/aarch64/cortex_a53.S \ + plat/intel/soc/stratix10/bl2_plat_setup.c \ + plat/intel/soc/stratix10/soc/s10_clock_manager.c \ + plat/intel/soc/stratix10/soc/s10_memory_controller.c \ + plat/intel/soc/stratix10/soc/s10_mmc.c \ + plat/intel/soc/stratix10/soc/s10_pinmux.c \ + plat/intel/soc/common/bl2_plat_mem_params_desc.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 \ + plat/intel/soc/common/drivers/qspi/cadence_qspi.c \ + plat/intel/soc/common/drivers/wdt/watchdog.c + +include lib/zlib/zlib.mk +PLAT_INCLUDES += -Ilib/zlib +BL2_SOURCES += $(ZLIB_SOURCES) + +BL31_SOURCES += \ + drivers/arm/cci/cci.c \ + lib/cpus/aarch64/aem_generic.S \ + lib/cpus/aarch64/cortex_a53.S \ + plat/common/plat_psci_common.c \ + plat/intel/soc/stratix10/soc/s10_clock_manager.c \ + plat/intel/soc/stratix10/bl31_plat_setup.c \ + plat/intel/soc/common/socfpga_psci.c \ + plat/intel/soc/common/socfpga_sip_svc.c \ + plat/intel/soc/common/socfpga_sip_svc_v2.c \ + plat/intel/soc/common/socfpga_topology.c \ + plat/intel/soc/common/sip/socfpga_sip_ecc.c \ + plat/intel/soc/common/sip/socfpga_sip_fcs.c \ + plat/intel/soc/common/soc/socfpga_mailbox.c \ + plat/intel/soc/common/soc/socfpga_reset_manager.c + +PROGRAMMABLE_RESET_ADDRESS := 0 +BL2_AT_EL3 := 1 +USE_COHERENT_MEM := 1 diff --git a/plat/intel/soc/stratix10/soc/s10_clock_manager.c b/plat/intel/soc/stratix10/soc/s10_clock_manager.c new file mode 100644 index 0000000..30009f7 --- /dev/null +++ b/plat/intel/soc/stratix10/soc/s10_clock_manager.c @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2019-2022, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <arch_helpers.h> +#include <assert.h> +#include <drivers/delay_timer.h> +#include <lib/mmio.h> +#include <platform_def.h> + +#include "s10_clock_manager.h" +#include "socfpga_handoff.h" +#include "socfpga_system_manager.h" + + +void wait_pll_lock(void) +{ + uint32_t data; + + do { + data = mmio_read_32(ALT_CLKMGR + ALT_CLKMGR_STAT); + } while ((ALT_CLKMGR_STAT_MAINPLLLOCKED(data) == 0) || + (ALT_CLKMGR_STAT_PERPLLLOCKED(data) == 0)); +} + +void wait_fsm(void) +{ + uint32_t data; + + do { + data = mmio_read_32(ALT_CLKMGR + ALT_CLKMGR_STAT); + } while (ALT_CLKMGR_STAT_BUSY(data) == ALT_CLKMGR_STAT_BUSY_E_BUSY); +} + +void config_clkmgr_handoff(handoff *hoff_ptr) +{ + uint32_t m_div, refclk_div, mscnt, hscnt; + + /* Bypass all mainpllgrp's clocks */ + mmio_write_32(ALT_CLKMGR_MAINPLL + + ALT_CLKMGR_MAINPLL_BYPASS, + 0x7); + wait_fsm(); + /* Bypass all perpllgrp's clocks */ + mmio_write_32(ALT_CLKMGR_PERPLL + + ALT_CLKMGR_PERPLL_BYPASS, + 0x7f); + wait_fsm(); + + /* Setup main PLL dividers */ + m_div = ALT_CLKMGR_MAINPLL_FDBCK_MDIV(hoff_ptr->main_pll_fdbck); + refclk_div = ALT_CLKMGR_MAINPLL_PLLGLOB_REFCLKDIV( + hoff_ptr->main_pll_pllglob); + mscnt = 200 / ((6 + m_div) / refclk_div); + hscnt = (m_div + 6) * mscnt / refclk_div - 9; + + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB, + hoff_ptr->main_pll_pllglob); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_FDBCK, + hoff_ptr->main_pll_fdbck); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_VCOCALIB, + ALT_CLKMGR_MAINPLL_VCOCALIB_HSCNT_SET(hscnt) | + ALT_CLKMGR_MAINPLL_VCOCALIB_MSCNT_SET(mscnt)); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLC0, + hoff_ptr->main_pll_pllc0); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLC1, + hoff_ptr->main_pll_pllc1); + + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCDIV, + hoff_ptr->main_pll_nocdiv); + + /* Setup peripheral PLL dividers */ + m_div = ALT_CLKMGR_PERPLL_FDBCK_MDIV(hoff_ptr->per_pll_fdbck); + refclk_div = ALT_CLKMGR_PERPLL_PLLGLOB_REFCLKDIV( + hoff_ptr->per_pll_pllglob); + mscnt = 200 / ((6 + m_div) / refclk_div); + hscnt = (m_div + 6) * mscnt / refclk_div - 9; + + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLGLOB, + hoff_ptr->per_pll_pllglob); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_FDBCK, + hoff_ptr->per_pll_fdbck); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_VCOCALIB, + ALT_CLKMGR_PERPLL_VCOCALIB_HSCNT_SET(hscnt) | + ALT_CLKMGR_PERPLL_VCOCALIB_MSCNT_SET(mscnt)); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLC0, + hoff_ptr->per_pll_pllc0); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLC1, + hoff_ptr->per_pll_pllc1); + + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_GPIODIV, + ALT_CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET( + hoff_ptr->per_pll_gpiodiv)); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_EMACCTL, + hoff_ptr->per_pll_emacctl); + + + /* Take both PLL out of reset and power up */ + mmio_setbits_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB, + ALT_CLKMGR_MAINPLL_PLLGLOB_PD_SET_MSK | + ALT_CLKMGR_MAINPLL_PLLGLOB_RST_SET_MSK); + mmio_setbits_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLGLOB, + ALT_CLKMGR_PERPLL_PLLGLOB_PD_SET_MSK | + ALT_CLKMGR_PERPLL_PLLGLOB_RST_SET_MSK); + + wait_pll_lock(); + + /* Dividers for C2 to C9 only init after PLLs are lock. */ + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_MPUCLK, 0xff); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCCLK, 0xff); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR2CLK, 0xff); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR3CLK, 0xff); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR4CLK, 0xff); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR5CLK, 0xff); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR6CLK, 0xff); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR7CLK, 0xff); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR8CLK, 0xff); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR9CLK, 0xff); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR2CLK, 0xff); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR3CLK, 0xff); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR4CLK, 0xff); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR5CLK, 0xff); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR6CLK, 0xff); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR7CLK, 0xff); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR8CLK, 0xff); + + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_MPUCLK, + hoff_ptr->main_pll_mpuclk); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCCLK, + hoff_ptr->main_pll_nocclk); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR2CLK, + hoff_ptr->main_pll_cntr2clk); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR3CLK, + hoff_ptr->main_pll_cntr3clk); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR4CLK, + hoff_ptr->main_pll_cntr4clk); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR5CLK, + hoff_ptr->main_pll_cntr5clk); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR6CLK, + hoff_ptr->main_pll_cntr6clk); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR7CLK, + hoff_ptr->main_pll_cntr7clk); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR8CLK, + hoff_ptr->main_pll_cntr8clk); + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR9CLK, + hoff_ptr->main_pll_cntr9clk); + + /* Peripheral PLL Clock Source and Counters/Divider */ + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR2CLK, + hoff_ptr->per_pll_cntr2clk); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR3CLK, + hoff_ptr->per_pll_cntr3clk); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR4CLK, + hoff_ptr->per_pll_cntr4clk); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR5CLK, + hoff_ptr->per_pll_cntr5clk); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR6CLK, + hoff_ptr->per_pll_cntr6clk); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR7CLK, + hoff_ptr->per_pll_cntr7clk); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR8CLK, + hoff_ptr->per_pll_cntr8clk); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR9CLK, + hoff_ptr->per_pll_cntr9clk); + + /* Take all PLLs out of bypass */ + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_BYPASS, 0); + wait_fsm(); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_BYPASS, 0); + wait_fsm(); + + /* Set safe mode/ out of boot mode */ + mmio_clrbits_32(ALT_CLKMGR + ALT_CLKMGR_CTRL, + ALT_CLKMGR_CTRL_BOOTMODE_SET_MSK); + wait_fsm(); + + /* 10 Enable mainpllgrp's software-managed clock */ + mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_EN, + ALT_CLKMGR_MAINPLL_EN_RESET); + mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_EN, + ALT_CLKMGR_PERPLL_EN_RESET); + + /* Clear loss lock interrupt status register that */ + /* might be set during configuration */ + mmio_write_32(ALT_CLKMGR + ALT_CLKMGR_INTRCLR, + ALT_CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK | + ALT_CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK); + + /* Pass clock source frequency into scratch register */ + mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1), + hoff_ptr->hps_osc_clk_h); + mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2), + hoff_ptr->fpga_clk_hz); + +} + +/* Extract reference clock from platform clock source */ +uint32_t get_ref_clk(uint32_t pllglob) +{ + uint32_t data32, mdiv, refclkdiv, ref_clk; + uint32_t scr_reg; + + switch (ALT_CLKMGR_PSRC(pllglob)) { + case ALT_CLKMGR_PLLGLOB_PSRC_EOSC1: + scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1); + ref_clk = mmio_read_32(scr_reg); + break; + case ALT_CLKMGR_PLLGLOB_PSRC_INTOSC: + ref_clk = ALT_CLKMGR_INTOSC_HZ; + break; + case ALT_CLKMGR_PLLGLOB_PSRC_F2S: + scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2); + ref_clk = mmio_read_32(scr_reg); + break; + default: + ref_clk = 0; + assert(0); + break; + } + + refclkdiv = ALT_CLKMGR_MAINPLL_PLLGLOB_REFCLKDIV(pllglob); + data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_FDBCK); + mdiv = ALT_CLKMGR_MAINPLL_FDBCK_MDIV(data32); + + ref_clk = (ref_clk / refclkdiv) * (6 + mdiv); + + return ref_clk; +} + +/* Calculate L3 interconnect main clock */ +uint32_t get_l3_clk(uint32_t ref_clk) +{ + uint32_t noc_base_clk, l3_clk, noc_clk, data32; + uint32_t pllc1_reg; + + noc_clk = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCCLK); + + switch (ALT_CLKMGR_PSRC(noc_clk)) { + case ALT_CLKMGR_SRC_MAIN: + pllc1_reg = ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLC1; + break; + case ALT_CLKMGR_SRC_PER: + pllc1_reg = ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLC1; + break; + default: + pllc1_reg = 0; + assert(0); + break; + } + + data32 = mmio_read_32(pllc1_reg); + noc_base_clk = ref_clk / (data32 & 0xff); + l3_clk = noc_base_clk / (noc_clk + 1); + + return l3_clk; +} + +/* Calculate clock frequency to be used for watchdog timer */ +uint32_t get_wdt_clk(void) +{ + uint32_t data32, ref_clk, l3_clk, l4_sys_clk; + + data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB); + ref_clk = get_ref_clk(data32); + + l3_clk = get_l3_clk(ref_clk); + + l4_sys_clk = l3_clk / 4; + + return l4_sys_clk; +} + +/* Calculate clock frequency to be used for UART driver */ +uint32_t get_uart_clk(void) +{ + uint32_t data32, ref_clk, l3_clk, l4_sp_clk; + + data32 = mmio_read_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLGLOB); + ref_clk = get_ref_clk(data32); + + l3_clk = get_l3_clk(ref_clk); + + data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCDIV); + data32 = (data32 >> 16) & 0x3; + data32 = 1 << data32; + + l4_sp_clk = (l3_clk / data32); + + return l4_sp_clk; +} + +/* Calculate clock frequency to be used for SDMMC driver */ +uint32_t get_mmc_clk(void) +{ + uint32_t data32, ref_clk, l3_clk, mmc_clk; + + data32 = mmio_read_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLGLOB); + ref_clk = get_ref_clk(data32); + + l3_clk = get_l3_clk(ref_clk); + + data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR6CLK); + mmc_clk = (l3_clk / (data32 + 1)) / 4; + + return mmc_clk; +} + +/* Get cpu freq clock */ +uint32_t get_cpu_clk(void) +{ + uint32_t data32, ref_clk, cpu_clk; + + data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB); + ref_clk = get_ref_clk(data32); + + cpu_clk = get_l3_clk(ref_clk)/PLAT_SYS_COUNTER_CONVERT_TO_MHZ; + + return cpu_clk; +} diff --git a/plat/intel/soc/stratix10/soc/s10_memory_controller.c b/plat/intel/soc/stratix10/soc/s10_memory_controller.c new file mode 100644 index 0000000..ac756ab --- /dev/null +++ b/plat/intel/soc/stratix10/soc/s10_memory_controller.c @@ -0,0 +1,412 @@ +/* + * Copyright (c) 2019, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <arch_helpers.h> +#include <errno.h> +#include <lib/mmio.h> +#include <lib/utils.h> +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <platform_def.h> +#include <string.h> + +#include "s10_memory_controller.h" +#include "socfpga_reset_manager.h" + +#define ALT_CCU_NOC_DI_SET_MSK 0x10 + +#define DDR_READ_LATENCY_DELAY 40 +#define MAX_MEM_CAL_RETRY 3 +#define PRE_CALIBRATION_DELAY 1 +#define POST_CALIBRATION_DELAY 1 +#define TIMEOUT_EMIF_CALIBRATION 1000 +#define CLEAR_EMIF_DELAY 1000 +#define CLEAR_EMIF_TIMEOUT 1000 + +#define DDR_CONFIG(A, B, C, R) (((A) << 24) | ((B) << 16) | ((C) << 8) | (R)) +#define DDR_CONFIG_ELEMENTS (sizeof(ddr_config)/sizeof(uint32_t)) + +/* tWR = Min. 15ns constant, see JEDEC standard eg. DDR4 is JESD79-4.pdf */ +#define tWR_IN_NS 15 + +void configure_hmc_adaptor_regs(void); +void configure_ddr_sched_ctrl_regs(void); + +/* The followring are the supported configurations */ +uint32_t ddr_config[] = { + /* DDR_CONFIG(Address order,Bank,Column,Row) */ + /* List for DDR3 or LPDDR3 (pinout order > chip, row, bank, column) */ + DDR_CONFIG(0, 3, 10, 12), + DDR_CONFIG(0, 3, 9, 13), + DDR_CONFIG(0, 3, 10, 13), + DDR_CONFIG(0, 3, 9, 14), + DDR_CONFIG(0, 3, 10, 14), + DDR_CONFIG(0, 3, 10, 15), + DDR_CONFIG(0, 3, 11, 14), + DDR_CONFIG(0, 3, 11, 15), + DDR_CONFIG(0, 3, 10, 16), + DDR_CONFIG(0, 3, 11, 16), + DDR_CONFIG(0, 3, 12, 15), /* 0xa */ + /* List for DDR4 only (pinout order > chip, bank, row, column) */ + DDR_CONFIG(1, 3, 10, 14), + DDR_CONFIG(1, 4, 10, 14), + DDR_CONFIG(1, 3, 10, 15), + DDR_CONFIG(1, 4, 10, 15), + DDR_CONFIG(1, 3, 10, 16), + DDR_CONFIG(1, 4, 10, 16), + DDR_CONFIG(1, 3, 10, 17), + DDR_CONFIG(1, 4, 10, 17), +}; + +static int match_ddr_conf(uint32_t ddr_conf) +{ + int i; + + for (i = 0; i < DDR_CONFIG_ELEMENTS; i++) { + if (ddr_conf == ddr_config[i]) + return i; + } + return 0; +} + +static int check_hmc_clk(void) +{ + unsigned long timeout = 0; + uint32_t hmc_clk; + + do { + hmc_clk = mmio_read_32(S10_SYSMGR_CORE_HMC_CLK); + if (hmc_clk & S10_SYSMGR_CORE_HMC_CLK_STATUS) + break; + udelay(1); + } while (++timeout < 1000); + if (timeout >= 1000) + return -ETIMEDOUT; + + return 0; +} + +static int clear_emif(void) +{ + uint32_t data; + unsigned long timeout; + + mmio_write_32(S10_MPFE_HMC_ADP_RSTHANDSHAKECTRL, 0); + + timeout = 0; + do { + data = mmio_read_32(S10_MPFE_HMC_ADP_RSTHANDSHAKESTAT); + if ((data & S10_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE) == 0) + break; + udelay(CLEAR_EMIF_DELAY); + } while (++timeout < CLEAR_EMIF_TIMEOUT); + if (timeout >= CLEAR_EMIF_TIMEOUT) + return -ETIMEDOUT; + + return 0; +} + +static int mem_calibration(void) +{ + int status = 0; + uint32_t data; + unsigned long timeout; + unsigned long retry = 0; + + udelay(PRE_CALIBRATION_DELAY); + + do { + if (retry != 0) + INFO("DDR: Retrying DRAM calibration\n"); + + timeout = 0; + do { + data = mmio_read_32(S10_MPFE_HMC_ADP_DDRCALSTAT); + if (S10_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 1) + break; + udelay(500); + } while (++timeout < TIMEOUT_EMIF_CALIBRATION); + + if (S10_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 0) { + status = clear_emif(); + if (status) + ERROR("Failed to clear Emif\n"); + } else { + break; + } + } while (++retry < MAX_MEM_CAL_RETRY); + + if (S10_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 0) { + ERROR("DDR: DRAM calibration failed.\n"); + status = -EIO; + } else { + INFO("DDR: DRAM calibration success.\n"); + status = 0; + } + + udelay(POST_CALIBRATION_DELAY); + + return status; +} + +int init_hard_memory_controller(void) +{ + int status; + + mmio_clrbits_32(S10_CCU_CPU0_MPRT_DDR, S10_CCU_NOC_DI_SET_MSK); + mmio_clrbits_32(S10_CCU_CPU0_MPRT_MEM0, S10_CCU_NOC_DI_SET_MSK); + mmio_clrbits_32(S10_CCU_CPU0_MPRT_MEM1A, S10_CCU_NOC_DI_SET_MSK); + mmio_clrbits_32(S10_CCU_CPU0_MPRT_MEM1B, S10_CCU_NOC_DI_SET_MSK); + mmio_clrbits_32(S10_CCU_CPU0_MPRT_MEM1C, S10_CCU_NOC_DI_SET_MSK); + mmio_clrbits_32(S10_CCU_CPU0_MPRT_MEM1D, S10_CCU_NOC_DI_SET_MSK); + mmio_clrbits_32(S10_CCU_CPU0_MPRT_MEM1E, S10_CCU_NOC_DI_SET_MSK); + + mmio_clrbits_32(S10_CCU_IOM_MPRT_MEM0, S10_CCU_NOC_DI_SET_MSK); + mmio_clrbits_32(S10_CCU_IOM_MPRT_MEM1A, S10_CCU_NOC_DI_SET_MSK); + mmio_clrbits_32(S10_CCU_IOM_MPRT_MEM1B, S10_CCU_NOC_DI_SET_MSK); + mmio_clrbits_32(S10_CCU_IOM_MPRT_MEM1C, S10_CCU_NOC_DI_SET_MSK); + mmio_clrbits_32(S10_CCU_IOM_MPRT_MEM1D, S10_CCU_NOC_DI_SET_MSK); + mmio_clrbits_32(S10_CCU_IOM_MPRT_MEM1E, S10_CCU_NOC_DI_SET_MSK); + + mmio_write_32(S10_NOC_FW_DDR_SCR_MPUREGION0ADDR_LIMIT, 0xFFFF0000); + mmio_write_32(S10_NOC_FW_DDR_SCR_MPUREGION0ADDR_LIMITEXT, 0x1F); + + mmio_write_32(S10_NOC_FW_DDR_SCR_NONMPUREGION0ADDR_LIMIT, 0xFFFF0000); + mmio_write_32(S10_NOC_FW_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT, 0x1F); + mmio_write_32(S10_SOC_NOC_FW_DDR_SCR_ENABLE, BIT(0) | BIT(8)); + + status = check_hmc_clk(); + if (status) { + ERROR("DDR: Error, HMC clock not running\n"); + return status; + } + + mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), RSTMGR_FIELD(BRG, DDRSCH)); + + status = mem_calibration(); + if (status) { + ERROR("DDR: Memory Calibration Failed\n"); + return status; + } + + configure_hmc_adaptor_regs(); + configure_ddr_sched_ctrl_regs(); + + return 0; +} + +void configure_ddr_sched_ctrl_regs(void) +{ + uint32_t data, dram_addr_order, ddr_conf, bank, row, col, + rd_to_miss, wr_to_miss, burst_len, burst_len_ddr_clk, + burst_len_sched_clk, act_to_act, rd_to_wr, wr_to_rd, bw_ratio, + t_rtp, t_rp, t_rcd, rd_latency, tw_rin_clk_cycles, + bw_ratio_extended, auto_precharge = 0, act_to_act_bank, faw, + faw_bank, bus_rd_to_rd, bus_rd_to_wr, bus_wr_to_rd; + + INFO("Init HPS NOC's DDR Scheduler.\n"); + + data = mmio_read_32(S10_MPFE_IOHMC_CTRLCFG1); + dram_addr_order = S10_MPFE_IOHMC_CTRLCFG1_CFG_ADDR_ORDER(data); + + data = mmio_read_32(S10_MPFE_IOHMC_DRAMADDRW); + + col = IOHMC_DRAMADDRW_COL_ADDR_WIDTH(data); + row = IOHMC_DRAMADDRW_ROW_ADDR_WIDTH(data); + bank = IOHMC_DRAMADDRW_BANK_ADDR_WIDTH(data) + + IOHMC_DRAMADDRW_BANK_GRP_ADDR_WIDTH(data); + + ddr_conf = match_ddr_conf(DDR_CONFIG(dram_addr_order, bank, col, row)); + + if (ddr_conf) { + mmio_clrsetbits_32( + S10_MPFE_DDR_MAIN_SCHED_DDRCONF, + S10_MPFE_DDR_MAIN_SCHED_DDRCONF_SET_MSK, + S10_MPFE_DDR_MAIN_SCHED_DDRCONF_SET(ddr_conf)); + } else { + ERROR("DDR: Cannot find predefined ddrConf configuration.\n"); + } + + mmio_write_32(S10_MPFE_HMC_ADP(ADP_DRAMADDRWIDTH), data); + + data = mmio_read_32(S10_MPFE_IOHMC_DRAMTIMING0); + rd_latency = S10_MPFE_IOHMC_REG_DRAMTIMING0_CFG_TCL(data); + + data = mmio_read_32(S10_MPFE_IOHMC_CALTIMING0); + act_to_act = ACT_TO_ACT(data); + t_rcd = ACT_TO_RDWR(data); + act_to_act_bank = ACT_TO_ACT_DIFF_BANK(data); + + data = mmio_read_32(S10_MPFE_IOHMC_CALTIMING1); + rd_to_wr = RD_TO_WR(data); + bus_rd_to_rd = RD_TO_RD_DIFF_CHIP(data); + bus_rd_to_wr = RD_TO_WR_DIFF_CHIP(data); + + data = mmio_read_32(S10_MPFE_IOHMC_CALTIMING2); + t_rtp = RD_TO_PCH(data); + + data = mmio_read_32(S10_MPFE_IOHMC_CALTIMING3); + wr_to_rd = CALTIMING3_WR_TO_RD(data); + bus_wr_to_rd = CALTIMING3_WR_TO_RD_DIFF_CHIP(data); + + data = mmio_read_32(S10_MPFE_IOHMC_CALTIMING4); + t_rp = PCH_TO_VALID(data); + + data = mmio_read_32(S10_MPFE_HMC_ADP(HMC_ADP_DDRIOCTRL)); + bw_ratio = ((HMC_ADP_DDRIOCTRL_IO_SIZE(data) == 0) ? 0 : 1); + + data = mmio_read_32(S10_MPFE_IOHMC_CTRLCFG0); + burst_len = HMC_ADP_DDRIOCTRL_CTRL_BURST_LENGTH(data); + burst_len_ddr_clk = burst_len / 2; + burst_len_sched_clk = ((burst_len/2) / 2); + + data = mmio_read_32(S10_MPFE_IOHMC_CTRLCFG0); + switch (S10_MPFE_IOHMC_REG_CTRLCFG0_CFG_MEM_TYPE(data)) { + case 1: + /* DDR4 - 1333MHz */ + /* 20 (19.995) clock cycles = 15ns */ + /* Calculate with rounding */ + tw_rin_clk_cycles = (((tWR_IN_NS * 1333) % 1000) >= 500) ? + ((tWR_IN_NS * 1333) / 1000) + 1 : + ((tWR_IN_NS * 1333) / 1000); + break; + default: + /* Others - 1066MHz or slower */ + /* 16 (15.990) clock cycles = 15ns */ + /* Calculate with rounding */ + tw_rin_clk_cycles = (((tWR_IN_NS * 1066) % 1000) >= 500) ? + ((tWR_IN_NS * 1066) / 1000) + 1 : + ((tWR_IN_NS * 1066) / 1000); + break; + } + + rd_to_miss = t_rtp + t_rp + t_rcd - burst_len_sched_clk; + wr_to_miss = ((rd_latency + burst_len_ddr_clk + 2 + tw_rin_clk_cycles) + / 2) - rd_to_wr + t_rp + t_rcd; + + mmio_write_32(S10_MPFE_DDR_MAIN_SCHED_DDRTIMING, + bw_ratio << DDRTIMING_BWRATIO_OFST | + wr_to_rd << DDRTIMING_WRTORD_OFST| + rd_to_wr << DDRTIMING_RDTOWR_OFST | + burst_len_sched_clk << DDRTIMING_BURSTLEN_OFST | + wr_to_miss << DDRTIMING_WRTOMISS_OFST | + rd_to_miss << DDRTIMING_RDTOMISS_OFST | + act_to_act << DDRTIMING_ACTTOACT_OFST); + + data = mmio_read_32(S10_MPFE_HMC_ADP(HMC_ADP_DDRIOCTRL)); + bw_ratio_extended = ((ADP_DDRIOCTRL_IO_SIZE(data) == 0) ? 1 : 0); + + mmio_write_32(S10_MPFE_DDR_MAIN_SCHED_DDRMODE, + bw_ratio_extended << DDRMODE_BWRATIOEXTENDED_OFST | + auto_precharge << DDRMODE_AUTOPRECHARGE_OFST); + + mmio_write_32(S10_MPFE_DDR_MAIN_SCHED_READLATENCY, + (rd_latency / 2) + DDR_READ_LATENCY_DELAY); + + data = mmio_read_32(S10_MPFE_IOHMC_CALTIMING9); + faw = S10_MPFE_IOHMC_CALTIMING9_ACT_TO_ACT(data); + + faw_bank = 1; // always 1 because we always have 4 bank DDR. + + mmio_write_32(S10_MPFE_DDR_MAIN_SCHED_ACTIVATE, + faw_bank << S10_MPFE_DDR_MAIN_SCHED_ACTIVATE_FAWBANK_OFST | + faw << S10_MPFE_DDR_MAIN_SCHED_ACTIVATE_FAW_OFST | + act_to_act_bank << S10_MPFE_DDR_MAIN_SCHED_ACTIVATE_RRD_OFST); + + mmio_write_32(S10_MPFE_DDR_MAIN_SCHED_DEVTODEV, + ((bus_rd_to_rd + << S10_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTORD_OFST) + & S10_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTORD_MSK) | + ((bus_rd_to_wr + << S10_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTOWR_OFST) + & S10_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTOWR_MSK) | + ((bus_wr_to_rd + << S10_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSWRTORD_OFST) + & S10_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSWRTORD_MSK)); + +} + +unsigned long get_physical_dram_size(void) +{ + uint32_t data; + unsigned long ram_addr_width, ram_ext_if_io_width; + + data = mmio_read_32(S10_MPFE_HMC_ADP_DDRIOCTRL); + switch (S10_MPFE_HMC_ADP_DDRIOCTRL_IO_SIZE(data)) { + case 0: + ram_ext_if_io_width = 16; + break; + case 1: + ram_ext_if_io_width = 32; + break; + case 2: + ram_ext_if_io_width = 64; + break; + default: + ram_ext_if_io_width = 0; + break; + } + + data = mmio_read_32(S10_MPFE_IOHMC_REG_DRAMADDRW); + ram_addr_width = IOHMC_DRAMADDRW_CFG_COL_ADDR_WIDTH(data) + + IOHMC_DRAMADDRW_CFG_ROW_ADDR_WIDTH(data) + + IOHMC_DRAMADDRW_CFG_BANK_ADDR_WIDTH(data) + + IOHMC_DRAMADDRW_CFG_BANK_GROUP_ADDR_WIDTH(data) + + IOHMC_DRAMADDRW_CFG_CS_ADDR_WIDTH(data); + + return (1 << ram_addr_width) * (ram_ext_if_io_width / 8); +} + + + +void configure_hmc_adaptor_regs(void) +{ + uint32_t data; + uint32_t dram_io_width; + + dram_io_width = S10_MPFE_IOHMC_NIOSRESERVE0_NIOS_RESERVE0( + mmio_read_32(S10_MPFE_IOHMC_REG_NIOSRESERVE0_OFST)); + + dram_io_width = (dram_io_width & 0xFF) >> 5; + + mmio_clrsetbits_32(S10_MPFE_HMC_ADP_DDRIOCTRL, + S10_MPFE_HMC_ADP_DDRIOCTRL_IO_SIZE_MSK, + dram_io_width << S10_MPFE_HMC_ADP_DDRIOCTRL_IO_SIZE_OFST); + + mmio_write_32(S10_MPFE_HMC_ADP_HPSINTFCSEL, + S10_MPFE_HMC_ADP_HPSINTFCSEL_ENABLE); + + data = mmio_read_32(S10_MPFE_IOHMC_REG_CTRLCFG1); + if (data & (1 << S10_IOHMC_CTRLCFG1_ENABLE_ECC_OFST)) { + mmio_clrsetbits_32(S10_MPFE_HMC_ADP_ECCCTRL1, + S10_MPFE_HMC_ADP_ECCCTRL1_AUTOWB_CNT_RST_SET_MSK | + S10_MPFE_HMC_ADP_ECCCTRL1_CNT_RST_SET_MSK | + S10_MPFE_HMC_ADP_ECCCTRL1_ECC_EN_SET_MSK, + S10_MPFE_HMC_ADP_ECCCTRL1_AUTOWB_CNT_RST_SET_MSK | + S10_MPFE_HMC_ADP_ECCCTRL1_CNT_RST_SET_MSK); + + mmio_clrsetbits_32(S10_MPFE_HMC_ADP_ECCCTRL2, + S10_MPFE_HMC_ADP_ECCCTRL2_OVRW_RB_ECC_EN_SET_MSK | + S10_MPFE_HMC_ADP_ECCCTRL2_RMW_EN_SET_MSK | + S10_MPFE_HMC_ADP_ECCCTRL2_AUTOWB_EN_SET_MSK, + S10_MPFE_HMC_ADP_ECCCTRL2_RMW_EN_SET_MSK | + S10_MPFE_HMC_ADP_ECCCTRL2_AUTOWB_EN_SET_MSK); + + mmio_clrsetbits_32(S10_MPFE_HMC_ADP_ECCCTRL1, + S10_MPFE_HMC_ADP_ECCCTRL1_AUTOWB_CNT_RST_SET_MSK | + S10_MPFE_HMC_ADP_ECCCTRL1_CNT_RST_SET_MSK | + S10_MPFE_HMC_ADP_ECCCTRL1_ECC_EN_SET_MSK, + S10_MPFE_HMC_ADP_ECCCTRL1_ECC_EN_SET_MSK); + INFO("Scrubbing ECC\n"); + + /* ECC Scrubbing */ + zeromem(DRAM_BASE, DRAM_SIZE); + } else { + INFO("ECC is disabled.\n"); + } +} + diff --git a/plat/intel/soc/stratix10/soc/s10_mmc.c b/plat/intel/soc/stratix10/soc/s10_mmc.c new file mode 100644 index 0000000..333bdd6 --- /dev/null +++ b/plat/intel/soc/stratix10/soc/s10_mmc.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2022, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include <lib/mmio.h> + +#include "s10_clock_manager.h" +#include "socfpga_system_manager.h" + +void s10_mmc_init(void) +{ + mmio_clrbits_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_EN, + ALT_CLKMGR_PERPLL_EN_SDMMCCLK); + mmio_write_32(SOCFPGA_SYSMGR(SDMMC), + SYSMGR_SDMMC_SMPLSEL(2) | SYSMGR_SDMMC_DRVSEL(3)); + mmio_setbits_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_EN, + ALT_CLKMGR_PERPLL_EN_SDMMCCLK); +} diff --git a/plat/intel/soc/stratix10/soc/s10_pinmux.c b/plat/intel/soc/stratix10/soc/s10_pinmux.c new file mode 100644 index 0000000..7fb4711 --- /dev/null +++ b/plat/intel/soc/stratix10/soc/s10_pinmux.c @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2019, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <lib/mmio.h> + +#include "s10_pinmux.h" + +const uint32_t sysmgr_pinmux_array_sel[] = { + 0x00000000, 0x00000001, /* usb */ + 0x00000004, 0x00000001, + 0x00000008, 0x00000001, + 0x0000000c, 0x00000001, + 0x00000010, 0x00000001, + 0x00000014, 0x00000001, + 0x00000018, 0x00000001, + 0x0000001c, 0x00000001, + 0x00000020, 0x00000001, + 0x00000024, 0x00000001, + 0x00000028, 0x00000001, + 0x0000002c, 0x00000001, + 0x00000030, 0x00000000, /* emac0 */ + 0x00000034, 0x00000000, + 0x00000038, 0x00000000, + 0x0000003c, 0x00000000, + 0x00000040, 0x00000000, + 0x00000044, 0x00000000, + 0x00000048, 0x00000000, + 0x0000004c, 0x00000000, + 0x00000050, 0x00000000, + 0x00000054, 0x00000000, + 0x00000058, 0x00000000, + 0x0000005c, 0x00000000, + 0x00000060, 0x00000008, /* gpio1 */ + 0x00000064, 0x00000008, + 0x00000068, 0x00000005, /* uart0 tx */ + 0x0000006c, 0x00000005, /* uart 0 rx */ + 0x00000070, 0x00000008, /* gpio */ + 0x00000074, 0x00000008, + 0x00000078, 0x00000004, /* i2c1 */ + 0x0000007c, 0x00000004, + 0x00000080, 0x00000007, /* jtag */ + 0x00000084, 0x00000007, + 0x00000088, 0x00000007, + 0x0000008c, 0x00000007, + 0x00000090, 0x00000001, /* sdmmc data0 */ + 0x00000094, 0x00000001, + 0x00000098, 0x00000001, + 0x0000009c, 0x00000001, + 0x00000100, 0x00000001, + 0x00000104, 0x00000001, /* sdmmc.data3 */ + 0x00000108, 0x00000008, /* loan */ + 0x0000010c, 0x00000008, /* gpio */ + 0x00000110, 0x00000008, + 0x00000114, 0x00000008, /* gpio1.io21 */ + 0x00000118, 0x00000005, /* mdio0.mdio */ + 0x0000011c, 0x00000005 /* mdio0.mdc */ +}; + +const uint32_t sysmgr_pinmux_array_ctrl[] = { + 0x00000000, 0x00502c38, /* Q1_1 */ + 0x00000004, 0x00102c38, + 0x00000008, 0x00502c38, + 0x0000000c, 0x00502c38, + 0x00000010, 0x00502c38, + 0x00000014, 0x00502c38, + 0x00000018, 0x00502c38, + 0x0000001c, 0x00502c38, + 0x00000020, 0x00502c38, + 0x00000024, 0x00502c38, + 0x00000028, 0x00502c38, + 0x0000002c, 0x00502c38, + 0x00000030, 0x00102c38, /* Q2_1 */ + 0x00000034, 0x00102c38, + 0x00000038, 0x00502c38, + 0x0000003c, 0x00502c38, + 0x00000040, 0x00102c38, + 0x00000044, 0x00102c38, + 0x00000048, 0x00502c38, + 0x0000004c, 0x00502c38, + 0x00000050, 0x00102c38, + 0x00000054, 0x00102c38, + 0x00000058, 0x00502c38, + 0x0000005c, 0x00502c38, + 0x00000060, 0x00502c38, /* Q3_1 */ + 0x00000064, 0x00502c38, + 0x00000068, 0x00102c38, + 0x0000006c, 0x00502c38, + 0x000000d0, 0x00502c38, + 0x000000d4, 0x00502c38, + 0x000000d8, 0x00542c38, + 0x000000dc, 0x00542c38, + 0x000000e0, 0x00502c38, + 0x000000e4, 0x00502c38, + 0x000000e8, 0x00102c38, + 0x000000ec, 0x00502c38, + 0x000000f0, 0x00502c38, /* Q4_1 */ + 0x000000f4, 0x00502c38, + 0x000000f8, 0x00102c38, + 0x000000fc, 0x00502c38, + 0x00000100, 0x00502c38, + 0x00000104, 0x00502c38, + 0x00000108, 0x00102c38, + 0x0000010c, 0x00502c38, + 0x00000110, 0x00502c38, + 0x00000114, 0x00502c38, + 0x00000118, 0x00542c38, + 0x0000011c, 0x00102c38 +}; + +const uint32_t sysmgr_pinmux_array_fpga[] = { + 0x00000000, 0x00000000, + 0x00000004, 0x00000000, + 0x00000008, 0x00000000, + 0x0000000c, 0x00000000, + 0x00000010, 0x00000000, + 0x00000014, 0x00000000, + 0x00000018, 0x00000000, + 0x0000001c, 0x00000000, + 0x00000020, 0x00000000, + 0x00000028, 0x00000000, + 0x0000002c, 0x00000000, + 0x00000030, 0x00000000, + 0x00000034, 0x00000000, + 0x00000038, 0x00000000, + 0x0000003c, 0x00000000, + 0x00000040, 0x00000000, + 0x00000044, 0x00000000, + 0x00000048, 0x00000000, + 0x00000050, 0x00000000, + 0x00000054, 0x00000000, + 0x00000058, 0x0000002a +}; + +const uint32_t sysmgr_pinmux_array_iodelay[] = { + 0x00000000, 0x00000000, + 0x00000004, 0x00000000, + 0x00000008, 0x00000000, + 0x0000000c, 0x00000000, + 0x00000010, 0x00000000, + 0x00000014, 0x00000000, + 0x00000018, 0x00000000, + 0x0000001c, 0x00000000, + 0x00000020, 0x00000000, + 0x00000024, 0x00000000, + 0x00000028, 0x00000000, + 0x0000002c, 0x00000000, + 0x00000030, 0x00000000, + 0x00000034, 0x00000000, + 0x00000038, 0x00000000, + 0x0000003c, 0x00000000, + 0x00000040, 0x00000000, + 0x00000044, 0x00000000, + 0x00000048, 0x00000000, + 0x0000004c, 0x00000000, + 0x00000050, 0x00000000, + 0x00000054, 0x00000000, + 0x00000058, 0x00000000, + 0x0000005c, 0x00000000, + 0x00000060, 0x00000000, + 0x00000064, 0x00000000, + 0x00000068, 0x00000000, + 0x0000006c, 0x00000000, + 0x00000070, 0x00000000, + 0x00000074, 0x00000000, + 0x00000078, 0x00000000, + 0x0000007c, 0x00000000, + 0x00000080, 0x00000000, + 0x00000084, 0x00000000, + 0x00000088, 0x00000000, + 0x0000008c, 0x00000000, + 0x00000090, 0x00000000, + 0x00000094, 0x00000000, + 0x00000098, 0x00000000, + 0x0000009c, 0x00000000, + 0x00000100, 0x00000000, + 0x00000104, 0x00000000, + 0x00000108, 0x00000000, + 0x0000010c, 0x00000000, + 0x00000110, 0x00000000, + 0x00000114, 0x00000000, + 0x00000118, 0x00000000, + 0x0000011c, 0x00000000 +}; + +void config_pinmux(handoff *hoff_ptr) +{ + unsigned int i; + + for (i = 0; i < 96; i += 2) { + mmio_write_32(S10_PINMUX_PIN0SEL + + hoff_ptr->pinmux_sel_array[i], + hoff_ptr->pinmux_sel_array[i+1]); + } + + for (i = 0; i < 96; i += 2) { + mmio_write_32(S10_PINMUX_IO0CTRL + + hoff_ptr->pinmux_io_array[i], + hoff_ptr->pinmux_io_array[i+1]); + } + + for (i = 0; i < 42; i += 2) { + mmio_write_32(S10_PINMUX_PINMUX_EMAC0_USEFPGA + + hoff_ptr->pinmux_fpga_array[i], + hoff_ptr->pinmux_fpga_array[i+1]); + } + + for (i = 0; i < 96; i += 2) { + mmio_write_32(S10_PINMUX_IO0_DELAY + + hoff_ptr->pinmux_iodelay_array[i], + hoff_ptr->pinmux_iodelay_array[i+1]); + } + +} + |