/** @Soc.c SoC specific Library containg functions to initialize various SoC components Copyright 2017-2020 NXP SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include /** Return the input clock frequency to an IP Module. This function reads the RCW bits and calculates the PLL multiplier/divider values to be applied to various IP modules. If a module is disabled or doesn't exist on platform, then return zero. @param[in] BaseClock Base clock to which PLL multiplier/divider values is to be applied. @param[in] ClockType Variable of Type NXP_IP_CLOCK. Indicates which IP clock is to be retrieved. @param[in] Args Variable argument list which is parsed based on ClockType. e.g. if the ClockType is NXP_I2C_CLOCK, then the second argument will be interpreted as controller number. e.g. if there are four i2c controllers in SOC, then this value can be 0, 1, 2, 3 e.g. if ClockType is NXP_CORE_CLOCK, then second argument is interpreted as cluster number and third argument is interpreted as core number (within the cluster) @return Actual Clock Frequency. Return value 0 should be interpreted as clock not being provided to IP. **/ UINT64 SocGetClock ( IN UINT64 BaseClock, IN NXP_IP_CLOCK ClockType, IN VA_LIST Args ) { LS1046A_DEVICE_CONFIG *Dcfg; UINT32 RcwSr; UINT64 ReturnValue; ReturnValue = 0; Dcfg = (LS1046A_DEVICE_CONFIG *)LS1046A_DCFG_ADDRESS; switch (ClockType) { case NXP_UART_CLOCK: case NXP_I2C_CLOCK: RcwSr = DcfgRead32 ((UINTN)&Dcfg->RcwSr[0]); ReturnValue = BaseClock * SYS_PLL_RAT (RcwSr); ReturnValue >>= 1; // 1/2 Platform Clock break; default: break; } return ReturnValue; } /** Function to select pins depending upon pcd using supplemental configuration unit(SCFG) extended RCW controlled pinmux control register which contains the bits to provide pin multiplexing control. This register is reset on HRESET. **/ STATIC VOID ConfigScfgMux (VOID) { LS1046A_SUPPLEMENTAL_CONFIG *Scfg; UINT32 UsbPwrFault; Scfg = (LS1046A_SUPPLEMENTAL_CONFIG *)LS1046A_SCFG_ADDRESS; // Configures functionality of the IIC3_SCL to USB2_DRVVBUS // Configures functionality of the IIC3_SDA to USB2_PWRFAULT // USB3 is not used, configure mux to IIC4_SCL/IIC4_SDA ScfgWrite32 ((UINTN)&Scfg->RcwPMuxCr0, SCFG_RCWPMUXCRO_NOT_SELCR_USB); ScfgWrite32 ((UINTN)&Scfg->UsbDrvVBusSelCr, SCFG_USBDRVVBUS_SELCR_USB1); UsbPwrFault = (SCFG_USBPWRFAULT_DEDICATED << SCFG_USBPWRFAULT_USB3_SHIFT) | (SCFG_USBPWRFAULT_DEDICATED << SCFG_USBPWRFAULT_USB2_SHIFT) | (SCFG_USBPWRFAULT_SHARED << SCFG_USBPWRFAULT_USB1_SHIFT); ScfgWrite32 ((UINTN)&Scfg->UsbPwrFaultSelCr, UsbPwrFault); ScfgWrite32 ((UINTN)&Scfg->UsbPwrFaultSelCr, UsbPwrFault); } STATIC VOID ApplyErrata ( VOID ) { ErratumA008997 (); ErratumA009007 (); ErratumA009008 (); ErratumA009798 (); } /** Function to initialize SoC specific constructs **/ VOID SocInit ( VOID ) { LS1046A_SUPPLEMENTAL_CONFIG *Scfg; Scfg = (LS1046A_SUPPLEMENTAL_CONFIG *)LS1046A_SCFG_ADDRESS; /* Make SEC, SATA and USB reads and writes snoopable */ ScfgOr32((UINTN)&Scfg->SnpCnfgCr, SCFG_SNPCNFGCR_SECRDSNP | SCFG_SNPCNFGCR_SECWRSNP | SCFG_SNPCNFGCR_USB1RDSNP | SCFG_SNPCNFGCR_USB1WRSNP | SCFG_SNPCNFGCR_USB2RDSNP | SCFG_SNPCNFGCR_USB2WRSNP | SCFG_SNPCNFGCR_USB3RDSNP | SCFG_SNPCNFGCR_USB3WRSNP | SCFG_SNPCNFGCR_SATARDSNP | SCFG_SNPCNFGCR_SATAWRSNP); ApplyErrata (); ChassisInit (); // // Due to the extensive functionality present on the chip and the limited number of external // signals available, several functional blocks share signal resources through multiplexing. // In this case when there is alternate functionality between multiple functional blocks, // the signal's function is determined at the chip level (rather than at the block level) // typically by a reset configuration word (RCW) option. Some of the signals' function are // determined externel to RCW at Power-on Reset Sequence. // ConfigScfgMux (); return; }