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 */
 

Reply via email to