This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit c34b9620db4e7b229e7afd7cdf5e78f65862e8d6 Author: Eero Nurkkala <[email protected]> AuthorDate: Thu Oct 7 12:16:05 2021 +0300 mpfs: clockconfig: add clock initialiation sequence Add clock initialization sequence especially for systems containing no bootloader. Signed-off-by: Eero Nurkkala <[email protected]> --- arch/risc-v/src/mpfs/mpfs_clockconfig.c | 593 +++++++++++++++++++++++++++++++- arch/risc-v/src/mpfs/mpfs_start.c | 4 +- 2 files changed, 586 insertions(+), 11 deletions(-) diff --git a/arch/risc-v/src/mpfs/mpfs_clockconfig.c b/arch/risc-v/src/mpfs/mpfs_clockconfig.c index 90aaee6..ea5bc19 100755 --- a/arch/risc-v/src/mpfs/mpfs_clockconfig.c +++ b/arch/risc-v/src/mpfs/mpfs_clockconfig.c @@ -30,9 +30,12 @@ #include <nuttx/arch.h> #include <arch/board/board.h> +#include <arch/board/board_liberodefs.h> #include "mpfs_clockconfig.h" #include "riscv_arch.h" +#include "hardware/mpfs_sysreg.h" +#include "hardware/mpfs_sgmii.h" /**************************************************************************** * Pre-processor Definitions @@ -40,17 +43,596 @@ #define OSC_FREQ 80000000UL +/* Read & Write Memory barrier */ + +#define RISCV_FENCE(p, s) \ + __asm__ __volatile__ ("fence " #p "," #s : : : "memory") + +#define mb() RISCV_FENCE(iorw, iorw) + +/* Module reset / clock enable defines */ + +#define MPFS_SYSREG_SOFT_RESET_CR (MPFS_SYSREG_BASE + \ + MPFS_SYSREG_SOFT_RESET_CR_OFFSET) +#define MPFS_SYSREG_SUBBLK_CLOCK_CR (MPFS_SYSREG_BASE + \ + MPFS_SYSREG_SUBBLK_CLOCK_CR_OFFSET) + +/* PLL bit defines */ + +#define PLL_CTRL_LOCK_BIT (1 << 25) +#define PLL_INIT_AND_OUT_OF_RESET 0x3 +#define PLL_CTRL_REG_POWERDOWN_B_MASK 0x1 + +/* eNVM clock frequency settled poll bit */ + +#define ENVM_CR_CLOCK_OKAY_MASK (1 << 6) + +/* Silicon version lookup bitmasks */ + +#define ARO_REF_PCODE_MASK 0x3f +#define ARO_REF_PCODE_REVC_THRESHOLD 0x40 +#define MIN_DLL_90_CODE_VALUE_INDICATING_TT_PART_REVB 13 + +#define MPFS_SCB_ACCESS_CONFIG ((160 << 8) | (0x80)) + +/* Poll loop default retries */ + +#define MPFS_DEFAULT_RETRIES 0xffff + +/* Eye width defines */ + +#define EARLY_EYE_WIDTH_PART_PART_NOT_DETERMINED 6 +#define EARLY_EYE_WIDTH_PART_REVC_OR_LATER 6 +#define EARLY_EYE_WIDTH_PART_REVC_OR_LATER_PRE_TEST 7 +#define EARLY_EYE_WIDTH_SS_PART_REVB 5 +#define EARLY_TT_PART_REVB 6 + +#define LATE_EYE_WIDTH_PART_NOT_DETERMINED 7 +#define LATE_EYE_WIDTH_PART_REVC_OR_LATER 7 +#define LATE_EYE_WIDTH_PART_REVC_OR_LATER_PRE_TEST 6 +#define LATE_EYE_WIDTH_SS_PART_REVB 6 +#define LATE_TT_PART_REVB 7 + +#define SHIFT_TO_REG_RX0_EYEWIDTH 21 +#define REG_RX0_EYEWIDTH_P_MASK (~(0x7 << SHIFT_TO_REG_RX0_EYEWIDTH)) + +#define SHIFT_TO_REG_RX1_EYEWIDTH 21 +#define REG_RX1_EYEWIDTH_P_MASK (~(0x7 << SHIFT_TO_REG_RX1_EYEWIDTH)) + +#define SHIFT_TO_CH0_N_EYE_VALUE 26 +#define SHIFT_TO_CH1_N_EYE_VALUE 29 +#define N_EYE_MASK 0x03ffffff + +#define REG_RX0_EN_FLAG_N (1 << 31) +#define REG_RX1_EN_FLAG_N (1 << 31) + +#define MSSIO_CONTROL_CR_MSS_IO_EN (1 << 13) +#define MSSIO_CONTROL_CR_MSS_FLASH_VALID (1 << 12) +#define MSSIO_CONTROL_CR_MSS_CORE_UP (1 << 11) +#define MSSIO_CONTROL_CR_MSS_DCE (0x7 << 8) + +#define SGMII_NV_MAP_DDR_PHY (1 << 0) +#define SGMII_ARO_PLL0_LOCK (1 << 7) + +/* MPFS_CFG_DDR_SGMII_PHY_DYN_CNTL bit defines */ + +#define SGMII_REG_LANE1_SOFT_RESET_PERIPH (1 << 14) +#define SGMII_REG_LANE0_SOFT_RESET_PERIPH (1 << 13) +#define SGMII_REG_PVT_SOFT_RESET_PERIPH (1 << 10) + +/* MPFS_IOSCB_CALIB_SGMII_IOC_REG0 */ + +#define SGMII_IOC_REG0_REG_CALIB_LOCK (1 << 14) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +enum part_type_e +{ + PART_NOT_DETERMINED = 0x00, + PART_REVC_OR_LATER = 0x01, + SS_PART_REVB = 0x02, + TT_PART_REVB = 0x03, + PART_TYPE_ARRAY_SIZE = 0x04, +}; + /**************************************************************************** * Private Data ****************************************************************************/ -static uint64_t g_cpu_clock = MPFS_MSS_COREPLEX_CPU_CLK; +static uint64_t g_cpu_clock = MPFS_MSS_EXT_SGMII_REF_CLK; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mpfs_wait_cycles + * + * Description: + * Wait n number of cycles. This mimics the vendor wait loops in the + * reference code. + * + * Parameters: + * n - number of cycles to loop + * + ****************************************************************************/ + +static void mpfs_wait_cycles(uint32_t n) +{ + volatile uint32_t count = n; + + while (--count); +} + +/**************************************************************************** + * Name: mpfs_set_rtc_divisor + * + * Description: + * Set the RTC divisor based on MSS Configurator setting. + * This will always be calculated so that RTC clock is 1MHz. + * + ****************************************************************************/ + +static void mpfs_set_rtc_divisor(void) +{ + /* Disable RTC clock */ + + modifyreg32(MPFS_SYSREG_RTC_CLOCK_CR, SYSREG_RTC_CLOCK_CR_ENABLE, 0); + + putreg32((LIBERO_SETTING_MSS_EXT_SGMII_REF_CLK / \ + LIBERO_SETTING_MSS_RTC_TOGGLE_CLK), + MPFS_SYSREG_RTC_CLOCK_CR); + + /* Enable RTC Clock */ + + modifyreg32(MPFS_SYSREG_RTC_CLOCK_CR, 0, SYSREG_RTC_CLOCK_CR_ENABLE); +} + +/**************************************************************************** + * Name: mpfs_sgmii_mux_config + * + * Description: + * Soft resets and loads RPC settings. + * + ****************************************************************************/ + +void mpfs_sgmii_mux_config(void) +{ + /* This will load the APB registers, set via SGMII TIP */ + + putreg32(1, MPFS_IOSCB_SGMII_MUX_SOFT_RESET); +} + +/**************************************************************************** + * Name: mpfs_sgmii_pll_config_scb + * + * Description: + * Soft resets and loads RPC settings + * + ****************************************************************************/ + +static void mpfs_sgmii_pll_config_scb(void) +{ + /* Set the NV map reset. This will load the APB registers, set + * via SGMII TIP. + */ + + putreg32(1, MPFS_IOSCB_SGMII_PLL_SOFT_RESET); +} + +/**************************************************************************** + * Name: mpfs_set_early_late_thresholds + * + * Description: + * Sets the N and P eye width values. + * + * Parameters: + * n_late_threshold - N eye width + * p_early_threshold - P eye width + * + ****************************************************************************/ + +static void mpfs_set_early_late_thresholds(uint8_t n_late_threshold, + uint8_t p_early_threshold) +{ + uint32_t n_eye_values; + uint32_t p_eye_value; + + /* Set the N eye width value, bits 31:29 for CH1, bits 28:26 + * for CH0 in spare control (N eye width value) + */ + + n_eye_values = (n_late_threshold << SHIFT_TO_CH0_N_EYE_VALUE); + n_eye_values |= (n_late_threshold << SHIFT_TO_CH1_N_EYE_VALUE); + + putreg32((LIBERO_SETTING_SPARE_CNTL & N_EYE_MASK) | n_eye_values, + MPFS_CFG_DDR_SGMII_PHY_SPARE_STAT); + + /* Set CH0/CH1 P values */ + + p_eye_value = (p_early_threshold << SHIFT_TO_REG_RX0_EYEWIDTH); + + putreg32(((LIBERO_SETTING_CH0_CNTL & REG_RX0_EYEWIDTH_P_MASK) | + p_eye_value) | REG_RX0_EN_FLAG_N, + MPFS_CFG_DDR_SGMII_PHY_CH0_CNTL); + putreg32(((LIBERO_SETTING_CH1_CNTL & REG_RX1_EYEWIDTH_P_MASK) | + p_eye_value) | REG_RX1_EN_FLAG_N, + MPFS_CFG_DDR_SGMII_PHY_CH1_CNTL); +} + +/**************************************************************************** + * Name: mss_mux_pre_mss_pll_config + * + * Description: + * Apply required reference clks to PLL, configure PLL and wait for lock. + * + ****************************************************************************/ + +static void mss_mux_pre_mss_pll_config(void) +{ + putreg32(LIBERO_SETTING_MSS_PLL_CKMUX, MPFS_IOSCB_MSS_MUX_PLL_CKMUX); + putreg32(LIBERO_SETTING_SGMII_CLK_XCVR, MPFS_IOSCB_SGMII_MUX_CLK_XCVR); + putreg32(LIBERO_SETTING_MSS_BCLKMUX, MPFS_IOSCB_MSS_MUX_BCLKMUX); + putreg32(LIBERO_SETTING_MSS_FMETER_ADDR, MPFS_IOSCB_MSS_MUX_FMETER_ADDR); + putreg32(LIBERO_SETTING_MSS_FMETER_DATAW, MPFS_IOSCB_MSS_MUX_FMETER_DATAW); + putreg32(LIBERO_SETTING_MSS_FMETER_DATAR, MPFS_IOSCB_MSS_MUX_FMETER_DATAR); + + mpfs_wait_cycles(400); +} + +/**************************************************************************** + * Name: mss_mux_pre_mss_pll_config + * + * Description: + * We must run this code from RAM, as we need to modify the clock of the + * eNVM. The first thing we do is change the eNVM clock, to prevent L1 + * cache accessing eNVM as it will do as we approach the return + * instruction. The mb() makes sure order of processing is not changed by + * the compiler + * + * Assumptions: + * This should be run outside of eNVM, although apparently it works even + * from eNVM. + * + ****************************************************************************/ + +__attribute__((section(".ram"))) void mpfs_mux_post_mss_pll_config(void) +{ + /* Modify the eNVM clock, so it matches the new MSS clock + * + * 7 will generate a 40ns period 25MHz clock if the AHB clock is 200MHz + * 11 will generate a 40ns period 25MHz clock if the AHB clock is 250MHz + * 15 will generate a 40ns period 25MHz clock if the AHB clock is 400MHz + */ + + putreg32(LIBERO_SETTING_MSS_ENVM_CR, MPFS_SYSREG_ENVM_CR); + + /* Make sure we change clock in eNVM first so all is ready by the time we + * leave. + */ + + mb(); + + /* When changing the eNVM clock frequency, there is a bit + * (ENVM_CR_clock_okay) in the eNVM_CR which can be polled to check that + * the frequency change has happened before bumping up the AHB frequency. + */ + + while ((getreg32(MPFS_SYSREG_ENVM_CR) & ENVM_CR_CLOCK_OKAY_MASK) != \ + ENVM_CR_CLOCK_OKAY_MASK); + + /* Change the MSS clock as required */ + + putreg32(LIBERO_SETTING_MSS_CLOCK_CONFIG_CR, MPFS_SYSREG_CLOCK_CONFIG_CR); + + /* Feed clock from MSS PLL to MSS, using glitchless mux */ + + putreg32(LIBERO_SETTING_MSS_MSSCLKMUX, MPFS_IOSCB_MSS_MUX_MSSCLKMUX); + + /* Change the RTC clock divisor, so RTC clock is 1MHz */ + + mpfs_set_rtc_divisor(); +} + +/**************************************************************************** + * Name: mpfs_pll_config + * + * Description: + * On startup, MSS is supplied with 80MHz SCB clock. + * Power on procedure for the MSS PLL clock: + * + * During POR: + * Keep PLL in power down mode. Powerdown_int_b = 0 + * + * After POR, Power-On steps: + * 1) mssclk_mux_sel_int = 0 & powerdown_int_b = 0 & clk_standby_sel = 0 + * MSS PLL is powered down and selects clk_standby = scb_clk + * 2) PFC Processor writes powerdown_int_b = 1 & divq0_int_en = 1 + * MSS PLL powers up, then lock asserts when locked. + * 3) PFC Processor switches mssclk_mux_sel_int = 1 + * MSS PLL clock is now sent to MSS. + * 4) When BOOT authentication is complete + * a. PFC processor writes mssclk_mux_sel_int = 0 to select + * clk_standby. + * b. PFC Processor writes powerdown_int_b = 0 to power down the PLL + * c. MSS Processor writes new parameters to the MSS PLL + * 5) MSS Processor writes powerdown_int_b = 1 + * Start up the PLL with new parameters. + * Wait for PLL to lock. + * 6) MSS Processor enables all 4 PLL outputs. + * 7) MSS Processor writes mssclk_mux_sel_int = 1 to select the MSS PLL + * clock. + * + ****************************************************************************/ + +static int mpfs_pll_config(void) +{ + uint32_t retries = MPFS_DEFAULT_RETRIES; + + putreg32(PLL_INIT_AND_OUT_OF_RESET, MPFS_IOSCB_MSS_PLL_SOFT_RESET); + putreg32(PLL_INIT_AND_OUT_OF_RESET, MPFS_IOSCB_DDR_PLL_SOFT_RESET); + + putreg32(LIBERO_SETTING_MSS_PLL_CTRL & ~(PLL_CTRL_REG_POWERDOWN_B_MASK), + MPFS_IOSCB_MSS_PLL_CTRL); + + putreg32(LIBERO_SETTING_MSS_PLL_REF_FB, MPFS_IOSCB_MSS_PLL_REF_FB); + + putreg32(LIBERO_SETTING_MSS_PLL_DIV_0_1, MPFS_IOSCB_MSS_PLL_DIV_0_1); + putreg32(LIBERO_SETTING_MSS_PLL_DIV_2_3, MPFS_IOSCB_MSS_PLL_DIV_2_3); + putreg32(LIBERO_SETTING_MSS_PLL_CTRL2, MPFS_IOSCB_MSS_PLL_CTRL2); + putreg32(LIBERO_SETTING_MSS_PLL_FRACN, MPFS_IOSCB_MSS_PLL_FRACN); + putreg32(LIBERO_SETTING_MSS_SSCG_REG_0, MPFS_IOSCB_MSS_PLL_SSCG_REG_0); + putreg32(LIBERO_SETTING_MSS_SSCG_REG_1, MPFS_IOSCB_MSS_PLL_SSCG_REG_1); + putreg32(LIBERO_SETTING_MSS_SSCG_REG_2, MPFS_IOSCB_MSS_PLL_SSCG_REG_2); + putreg32(LIBERO_SETTING_MSS_SSCG_REG_3, MPFS_IOSCB_MSS_PLL_SSCG_REG_3); + + /* PLL phase register */ + + putreg32(LIBERO_SETTING_MSS_PLL_PHADJ, MPFS_IOSCB_MSS_PLL_PHADJ); + + /* Write powerdown_int_b = 1, start up the PLL with new parameters + * and wait for it to lock. + */ + + mss_mux_pre_mss_pll_config(); + + putreg32(LIBERO_SETTING_MSS_PLL_CTRL | 0x01, MPFS_IOSCB_MSS_PLL_CTRL); + + /* Start up the PLL with new parameters. Wait for it to lock. */ + + while (!(getreg32(MPFS_IOSCB_MSS_PLL_CTRL) & PLL_CTRL_LOCK_BIT) && + --retries); + + DEBUGASSERT(retries > 0); + + /* Processor enables all 4 PLL outputs. Set mssclk_mux_sel_int = 1 to + * select the MSS PLL clock. + */ + + mpfs_mux_post_mss_pll_config(); + + return 0; +} + +/**************************************************************************** + * Name: mpfs_sgmii_setup + * + * Description: + * Setup the Serial Gigabit Media-Independent Interface (SGMII) + * + ****************************************************************************/ + +static void mpfs_sgmii_setup(void) +{ + putreg32(((0x01 << 8) | 0x1), MPFS_CFG_DDR_SGMII_PHY_SOFT_RESET_DDR_PHY); + putreg32(0x1, MPFS_CFG_DDR_SGMII_PHY_SOFT_RESET_DDR_PHY); + + putreg32(LIBERO_SETTING_SGMII_MODE & ~(1 << 22), + MPFS_CFG_DDR_SGMII_PHY_SGMII_MODE); + putreg32(LIBERO_SETTING_CH0_CNTL, MPFS_CFG_DDR_SGMII_PHY_CH0_CNTL); + putreg32(LIBERO_SETTING_CH1_CNTL, MPFS_CFG_DDR_SGMII_PHY_CH1_CNTL); + putreg32(LIBERO_SETTING_RECAL_CNTL, MPFS_CFG_DDR_SGMII_PHY_RECAL_CNTL); + putreg32(LIBERO_SETTING_CLK_CNTL, MPFS_CFG_DDR_SGMII_PHY_CLK_CNTL); + putreg32(LIBERO_SETTING_SPARE_CNTL, MPFS_CFG_DDR_SGMII_PHY_SPARE_CNTL); + putreg32(LIBERO_SETTING_PLL_CNTL, MPFS_CFG_DDR_SGMII_PHY_PLL_CNTL); + + /* Enable the Bank controller: + * - Set soft reset on IP to load RPC to SCB regs (dynamic mode) + * - Bring the sgmii bank controller out of reset =- ioscb_bank_ctrl_sgmii + */ + + putreg32(0x01, MPFS_IOSCB_BANK_CNTL_SGMII_SOFT_RESET); + + /* Check the IO_EN signal here. This is an output from the bank controller + * power detector, which are turned on using MSS_IO_EN. + */ + + while (!(getreg32(MPFS_CFG_DDR_SGMII_PHY_PVT_STAT) & (1 << 6))); + + /* IO power ramp wait time: after IOEN is received from power detectors + * DDR and SGMII, extra time is required for voltage to ramp. + */ + + mpfs_wait_cycles(10); + + putreg32(0, MPFS_SYSREGSCB_MSS_RESET_CR); + + /* Reset SGMII DLL */ + + putreg32(1 << 0, MPFS_IOSCB_DLL_SGMII_SOFT_RESET); + + /* SGMII Lane 01 and 23 soft-reset */ + + putreg32(1, MPFS_IOSCB_SGMII_LANE01_SOFT_RESET); + putreg32(1, MPFS_IOSCB_SGMII_LANE23_SOFT_RESET); + + putreg32(SGMII_REG_PVT_SOFT_RESET_PERIPH | 0x7f, + MPFS_CFG_DDR_SGMII_PHY_DYN_CNTL); + putreg32(0x7f, MPFS_CFG_DDR_SGMII_PHY_DYN_CNTL); + + putreg32(1, MPFS_IOSCB_CALIB_SGMII_SOFT_RESET); + putreg32(0, MPFS_IOSCB_CALIB_SGMII_SOFT_RESET); + + /* Verify calibration */ + + while (!(getreg32(MPFS_CFG_DDR_SGMII_PHY_PVT_STAT) & (1 << 14))); + + modifyreg32(MPFS_CFG_DDR_SGMII_PHY_PVT_STAT, 0, 0x40000000); + modifyreg32(MPFS_IOSCB_CALIB_SGMII_IOC_REG0, 0, + SGMII_IOC_REG0_REG_CALIB_LOCK); + + mpfs_sgmii_mux_config(); + mpfs_sgmii_pll_config_scb(); + + /* SGMII wait for MSS lock */ + + while (!((getreg32(MPFS_CFG_DDR_SGMII_PHY_PLL_CNTL) & + SGMII_ARO_PLL0_LOCK))); + + /* SGMII wait for DLL lock */ + + while (!((getreg32(MPFS_CFG_DDR_SGMII_PHY_RECAL_CNTL) & (1 << 23)))); + + modifyreg32(MPFS_SYSREG_SUBBLK_CLOCK_CR, 0, + SYSREG_SUBBLK_CLOCK_CR_MAC0 | SYSREG_SUBBLK_CLOCK_CR_MAC1); + + modifyreg32(MPFS_SYSREG_SOFT_RESET_CR, SYSREG_SOFT_RESET_CR_MAC0 | + SYSREG_SOFT_RESET_CR_MAC1, 0); + + /* SGMII gigabit mode enable */ + + putreg32((1 << 10) | (1 << 11), MPFS_GEM0_NETWORK_CONFIG); + putreg32((1 << 10) | (1 << 11), MPFS_GEM1_NETWORK_CONFIG); + + /* Determine silicon variant from generated sro_dll_90_code */ + + uint32_t sro_dll_90_code = ((getreg32(MPFS_CFG_DDR_SGMII_PHY_RECAL_CNTL) \ + >> 16) & 0x7f); + uint32_t silicon_variant; + + /* Post rev B silicon */ + + if (getreg32(MPFS_CFG_DDR_SGMII_PHY_SPARE_STAT) & (1 << 31)) + { + silicon_variant = PART_REVC_OR_LATER; + mpfs_set_early_late_thresholds( + LATE_EYE_WIDTH_PART_REVC_OR_LATER_PRE_TEST, + EARLY_EYE_WIDTH_PART_REVC_OR_LATER_PRE_TEST); + } + else + { + if (sro_dll_90_code < MIN_DLL_90_CODE_VALUE_INDICATING_TT_PART_REVB) + { + silicon_variant = SS_PART_REVB; + mpfs_set_early_late_thresholds(LATE_EYE_WIDTH_SS_PART_REVB, + EARLY_EYE_WIDTH_SS_PART_REVB); + } + else + { + silicon_variant = TT_PART_REVB; + mpfs_set_early_late_thresholds(LATE_TT_PART_REVB, + EARLY_TT_PART_REVB); + } + } + + /* DLL soft reset - Already configured + * PVT soft reset - Already configured + * Bank controller soft reset - Already configured + * CLKMUX soft reset - Already configured + * Lane0 soft reset - must be soft reset here + * Lane1 soft reset - must be soft reset here + */ + + putreg32(SGMII_REG_LANE1_SOFT_RESET_PERIPH | + SGMII_REG_LANE0_SOFT_RESET_PERIPH | 0x7f, + MPFS_CFG_DDR_SGMII_PHY_DYN_CNTL); + putreg32(0x7f, MPFS_CFG_DDR_SGMII_PHY_DYN_CNTL); + + if (silicon_variant == PART_REVC_OR_LATER) + { + mpfs_wait_cycles(0xfff); + + if ((getreg32(MPFS_CFG_DDR_SGMII_PHY_SPARE_STAT) & ARO_REF_PCODE_MASK) + <= ARO_REF_PCODE_REVC_THRESHOLD) + { + /* Need to adjust eye values */ + + mpfs_set_early_late_thresholds(LATE_EYE_WIDTH_PART_REVC_OR_LATER, + EARLY_EYE_WIDTH_PART_REVC_OR_LATER); + + /* Now reset the channels */ + + putreg32(SGMII_REG_LANE1_SOFT_RESET_PERIPH | + SGMII_REG_LANE0_SOFT_RESET_PERIPH | 0x7f, + MPFS_CFG_DDR_SGMII_PHY_DYN_CNTL); + putreg32(0x7f, MPFS_CFG_DDR_SGMII_PHY_DYN_CNTL); + } + } + + mpfs_pll_config(); +} /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** + * Name: mpfs_clock_init + * + * Description: + * Setup the system clocks + * + ****************************************************************************/ + +void mpfs_clockconfig(void) +{ + mpfs_set_rtc_divisor(); + + putreg32(MPFS_SCB_ACCESS_CONFIG, MPFS_IOSCBCFG_TIMER); + + putreg32(0x01, MPFS_SYSREG_DFIAPB_CR); + + putreg32((0x3f << 16) | (0x1f << 8), MPFS_CFG_DDR_SGMII_PHY_STARTUP); + putreg32(SGMII_REG_PVT_SOFT_RESET_PERIPH | 0x7f, + MPFS_CFG_DDR_SGMII_PHY_DYN_CNTL); + + /* DCE:111, CORE_UP:1, FLASH_VALID:0, mss_io_en:0 */ + + putreg32(MSSIO_CONTROL_CR_MSS_DCE | MSSIO_CONTROL_CR_MSS_CORE_UP, + MPFS_SYSREGSCB_MSSIO_CONTROL_CR); + + mpfs_wait_cycles(10); + + /* DCE:000, CORE_UP:1, FLASH_VALID:0, mss_io_en:0 */ + + putreg32(MSSIO_CONTROL_CR_MSS_CORE_UP, MPFS_SYSREGSCB_MSSIO_CONTROL_CR); + + mpfs_wait_cycles(10); + + /* DCE:000, CORE_UP:1, FLASH_VALID:1, mss_io_en:0 */ + + putreg32(MSSIO_CONTROL_CR_MSS_CORE_UP | MSSIO_CONTROL_CR_MSS_FLASH_VALID, + MPFS_SYSREGSCB_MSSIO_CONTROL_CR); + + mpfs_wait_cycles(10); + + /* DCE:000, CORE_UP:1, FLASH_VALID:1, mss_io_en:1 */ + + putreg32(MSSIO_CONTROL_CR_MSS_CORE_UP | MSSIO_CONTROL_CR_MSS_FLASH_VALID | + MSSIO_CONTROL_CR_MSS_IO_EN, MPFS_SYSREGSCB_MSSIO_CONTROL_CR); + + /* Setup SGMII */ + + mpfs_sgmii_setup(); + + /* Setup the MSS PLL */ + + mpfs_pll_config(); +} + +/**************************************************************************** * Name: mpfs_get_cpuclk ****************************************************************************/ @@ -69,12 +651,3 @@ uint64_t mpfs_get_pll0clk(void) return 0; } #endif - -/**************************************************************************** - * Name: mpfs_clockconfig - ****************************************************************************/ - -void mpfs_clockconfig(void) -{ - /* All is currently done in bootloader HSS */ -} diff --git a/arch/risc-v/src/mpfs/mpfs_start.c b/arch/risc-v/src/mpfs/mpfs_start.c index ce646cb..7080793 100755 --- a/arch/risc-v/src/mpfs/mpfs_start.c +++ b/arch/risc-v/src/mpfs/mpfs_start.c @@ -97,9 +97,11 @@ void __mpfs_start(uint32_t mhartid) *dest++ = *src++; } - /* Setup PLL */ + /* Setup PLL if not already provided */ +#ifdef CONFIG_MPFS_BOOTLOADER mpfs_clockconfig(); +#endif /* Configure the UART so we can get debug output */
