1 /** @Soc.c
2   SoC specific Library containg functions to initialize various SoC components
3 
4   Copyright 2017-2020 NXP
5 
6   SPDX-License-Identifier: BSD-2-Clause-Patent
7 
8 **/
9 
10 #include <Base.h>
11 #include <Library/ChassisLib.h>
12 #include <Library/DebugLib.h>
13 #include <Library/SocLib.h>
14 #include <Soc.h>
15 
16 /**
17   Return the input clock frequency to an IP Module.
18   This function reads the RCW bits and calculates the  PLL multiplier/divider
19   values to be applied to various IP modules.
20   If a module is disabled or doesn't exist on platform, then return zero.
21 
22   @param[in]  BaseClock  Base clock to which PLL multiplier/divider values is
23                          to be applied.
24   @param[in]  ClockType  Variable of Type NXP_IP_CLOCK. Indicates which IP clock
25                          is to be retrieved.
26   @param[in]  Args       Variable argument list which is parsed based on
27                          ClockType. e.g. if the ClockType is NXP_I2C_CLOCK, then
28                          the second argument will be interpreted as controller
29                          number. e.g. if there are four i2c controllers in SOC,
30                          then this value can be 0, 1, 2, 3
31                          e.g. if ClockType is NXP_CORE_CLOCK, then second
32                          argument is interpreted as cluster number and third
33                          argument is interpreted as core number (within the
34                          cluster)
35 
36   @return                Actual Clock Frequency. Return value 0 should be
37                          interpreted as clock not being provided to IP.
38 **/
39 UINT64
SocGetClock(IN UINT64 BaseClock,IN NXP_IP_CLOCK ClockType,IN VA_LIST Args)40 SocGetClock (
41   IN  UINT64        BaseClock,
42   IN  NXP_IP_CLOCK  ClockType,
43   IN  VA_LIST       Args
44   )
45 {
46   LS1046A_DEVICE_CONFIG  *Dcfg;
47   UINT32                 RcwSr;
48   UINT64                 ReturnValue;
49 
50   ReturnValue = 0;
51   Dcfg = (LS1046A_DEVICE_CONFIG  *)LS1046A_DCFG_ADDRESS;
52 
53   switch (ClockType) {
54   case NXP_UART_CLOCK:
55   case NXP_I2C_CLOCK:
56     RcwSr = DcfgRead32 ((UINTN)&Dcfg->RcwSr[0]);
57     ReturnValue = BaseClock * SYS_PLL_RAT (RcwSr);
58     ReturnValue >>= 1; // 1/2 Platform Clock
59     break;
60   default:
61     break;
62   }
63 
64   return ReturnValue;
65 }
66 
67 /**
68    Function to select pins depending upon pcd using supplemental
69    configuration unit(SCFG) extended RCW controlled pinmux control
70    register which contains the bits to provide pin multiplexing control.
71    This register is reset on HRESET.
72  **/
73 STATIC
74 VOID
ConfigScfgMux(VOID)75 ConfigScfgMux (VOID)
76 {
77   LS1046A_SUPPLEMENTAL_CONFIG  *Scfg;
78   UINT32 UsbPwrFault;
79 
80   Scfg = (LS1046A_SUPPLEMENTAL_CONFIG *)LS1046A_SCFG_ADDRESS;
81   // Configures functionality of the IIC3_SCL to USB2_DRVVBUS
82   // Configures functionality of the IIC3_SDA to USB2_PWRFAULT
83   // USB3 is not used, configure mux to IIC4_SCL/IIC4_SDA
84   ScfgWrite32 ((UINTN)&Scfg->RcwPMuxCr0, SCFG_RCWPMUXCRO_NOT_SELCR_USB);
85 
86   ScfgWrite32 ((UINTN)&Scfg->UsbDrvVBusSelCr, SCFG_USBDRVVBUS_SELCR_USB1);
87   UsbPwrFault = (SCFG_USBPWRFAULT_DEDICATED << SCFG_USBPWRFAULT_USB3_SHIFT) |
88                 (SCFG_USBPWRFAULT_DEDICATED << SCFG_USBPWRFAULT_USB2_SHIFT) |
89                 (SCFG_USBPWRFAULT_SHARED << SCFG_USBPWRFAULT_USB1_SHIFT);
90   ScfgWrite32 ((UINTN)&Scfg->UsbPwrFaultSelCr, UsbPwrFault);
91   ScfgWrite32 ((UINTN)&Scfg->UsbPwrFaultSelCr, UsbPwrFault);
92 }
93 
94 STATIC
95 VOID
ApplyErrata(VOID)96 ApplyErrata (
97   VOID
98   )
99 {
100   ErratumA008997 ();
101   ErratumA009007 ();
102   ErratumA009008 ();
103   ErratumA009798 ();
104 }
105 
106 
107 
108 /**
109   Function to initialize SoC specific constructs
110  **/
111 VOID
SocInit(VOID)112 SocInit (
113   VOID
114   )
115 {
116   LS1046A_SUPPLEMENTAL_CONFIG  *Scfg;
117 
118   Scfg = (LS1046A_SUPPLEMENTAL_CONFIG *)LS1046A_SCFG_ADDRESS;
119 
120   /* Make SEC, SATA and USB reads and writes snoopable */
121   ScfgOr32((UINTN)&Scfg->SnpCnfgCr, SCFG_SNPCNFGCR_SECRDSNP |
122     SCFG_SNPCNFGCR_SECWRSNP | SCFG_SNPCNFGCR_USB1RDSNP |
123     SCFG_SNPCNFGCR_USB1WRSNP | SCFG_SNPCNFGCR_USB2RDSNP |
124     SCFG_SNPCNFGCR_USB2WRSNP | SCFG_SNPCNFGCR_USB3RDSNP |
125     SCFG_SNPCNFGCR_USB3WRSNP | SCFG_SNPCNFGCR_SATARDSNP |
126     SCFG_SNPCNFGCR_SATAWRSNP);
127 
128   ApplyErrata ();
129   ChassisInit ();
130 
131   //
132   // Due to the extensive functionality present on the chip and the limited number of external
133   // signals available, several functional blocks share signal resources through multiplexing.
134   // In this case when there is alternate functionality between multiple functional blocks,
135   // the signal's function is determined at the chip level (rather than at the block level)
136   // typically by a reset configuration word (RCW) option. Some of the signals' function are
137   // determined externel to RCW at Power-on Reset Sequence.
138   //
139   ConfigScfgMux ();
140 
141   return;
142 }
143