Hi Ard,
Thanks for the review comments. Please see my replies inline.
From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org] Sent: Tuesday, October 18, 2016 3:22 PM
On 17 October 2016 at 21:04, Bhupesh Sharma bhupesh.sharma@freescale.com wrote:
From: Sakar Arora Sakar.Arora@nxp.com
This patch adds the functions that initialize the following IPs on
the
SoC:
- Central Security Unit (CSU) - Acts as a gatekeeper for secure and non-secure accesses via SW.
- TrustZone Address Space Controller (TZC-380).
- Interconnect (CCI-400).
- PLLs and Clocks.
- ARM Generic Timer.
In addition it also provides functions that print the following
useful
information:
- CPU Info
- SoC Personality.
- Board Personality.
- Reset Configuration Word (RCW).
- SerDes selection.
This looks like a mixed bag of functionality. Could you split this up please?
Ok.
Also, please elaborate in the commit log how you manage to configure these secure world peripherals from EL2,
Sure, it's because of the flaky flow we have currently where we start the UEFI firmware in EL3 exception level and then execute the platform and run-time security agent (PPA).
I will add this description in the commit log in detail.
Signed-off-by: Bhupesh Sharma bhupesh.sharma@nxp.com
.../Nxp/LS1043aRdb/Include/Library/Ls1043aSerDes.h | 89 +++ Platforms/Nxp/LS1043aRdb/Include/Library/SocLib.h | 203 ++++++- .../LS1043aRdb/Library/LS1043aRdbLib/LS1043aRdb.c | 2 + .../Library/LS1043aSocLib/LS1043aSocLib.c | 674
++++++++++++++++++++-
.../Library/LS1043aSocLib/LS1043aSocLib.inf | 13 + .../LS1043aRdb/Library/LS1043aSocLib/LsSerDes.c | 195 ++++++ 6 files changed, 1169 insertions(+), 7 deletions(-) create mode 100644 Platforms/Nxp/LS1043aRdb/Include/Library/Ls1043aSerDes.h create mode 100644 Platforms/Nxp/LS1043aRdb/Library/LS1043aSocLib/LsSerDes.c
diff --git a/Platforms/Nxp/LS1043aRdb/Include/Library/Ls1043aSerDes.h b/Platforms/Nxp/LS1043aRdb/Include/Library/Ls1043aSerDes.h new file mode 100644 index 0000000..181c268 --- /dev/null +++ b/Platforms/Nxp/LS1043aRdb/Include/Library/Ls1043aSerDes.h
is this an internal header? If so, please keep it with the .c files
Yes this is an internal header. I will keep it with the .c files.
@@ -0,0 +1,89 @@ +/** Ls1043aSerDes.h
- The Header file of SerDes Module
- Copyright (c) 2016, Freescale Semiconductor, Inc. All rights
reserved.
- This program and the accompanying materials are licensed and made
- available under the terms and conditions of the BSD License which
- accompanies this distribution. The full text of the license may be
- found http://opensource.org/licenses/bsd-license.php
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
- BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
EXPRESS OR IMPLIED.
+**/
+#ifndef __LS1043A_SERDES_H +#define __LS1043A_SERDES_H
+#define SRDS_MAX_LANES 4
+#define LS1043_RCWSR4_SRDS1_PRTCL_MASK 0xFFFF0000 #define +LS1043_RCWSR4_SRDS1_PRTCL_SHIFT 16
+typedef enum {
NONE = 0,
PCIE1,
PCIE2,
PCIE3,
SATA1,
XFI1,
XFI2,
SGMII1,
SGMII2,
SGMII3,
SGMII4,
SGMII5,
SGMII6,
SGMII7,
SGMII8,
SGMII9,
QSGMII1,
QSGMII2,
SERDES_PRCTL_COUNT
+} SrdsPrtcl;
+enum Srds {
FSL_SRDS_1 = 0,
FSL_SRDS_2 = 1
+};
+struct SerDesConfig {
UINT16 Protocol;
UINT8 SrdsLane[SRDS_MAX_LANES]; };
+struct SerDesConfig SerDes1ConfigTbl[] = {
/* SerDes 1 */
{0x1555, {XFI1, PCIE1, PCIE2, PCIE3 } },
{0x1560, {XFI1, PCIE1, PCIE3, PCIE3 } },
{0x1460, {XFI1, QSGMII1, PCIE3, PCIE3 } },
{0x1360, {XFI1, SGMII2, PCIE3, PCIE3 } },
{0x2555, {SGMII9, PCIE1, PCIE2, PCIE3 } },
{0x4555, {QSGMII1, PCIE1, PCIE2, PCIE3 } },
{0x4558, {QSGMII1, PCIE1, PCIE2, SATA1 } },
{0x1355, {XFI1, SGMII2, PCIE2, PCIE3 } },
{0x1335, {XFI1, SGMII2, SGMII5, PCIE3 } },
{0x1333, {XFI1, SGMII2, SGMII5, SGMII6 } },
{0x2355, {SGMII9, SGMII2, PCIE2, PCIE3 } },
{0x2260, {SGMII9, SGMII2, PCIE3, PCIE3 } },
{0x2235, {SGMII9, SGMII2, SGMII5, PCIE3 } },
{0x2233, {SGMII9, SGMII2, SGMII5, SGMII6 } },
{0x3335, {SGMII9, SGMII2, SGMII5, PCIE3 } },
{0x3355, {SGMII9, SGMII2, PCIE2, PCIE3 } },
{0x3358, {SGMII9, SGMII2, PCIE2, SATA1 } },
{0x3360, {SGMII9, SGMII2, PCIE3, PCIE3 } },
{0x3560, {SGMII9, PCIE1, PCIE3, PCIE3 } },
{0x3555, {SGMII9, PCIE1, PCIE2, PCIE3 } },
{0x7000, {PCIE1, PCIE1, PCIE1, PCIE1 } },
{0x9998, {PCIE1, PCIE2, PCIE3, SATA1 } },
{0x6058, {PCIE1, PCIE1, PCIE2, SATA1 } },
{0x1455, {XFI1, QSGMII1, PCIE2, PCIE3 } },
{0x2455, {SGMII9, QSGMII1, PCIE2, PCIE3 } },
{0x2255, {SGMII9, SGMII2, PCIE2, PCIE3 } },
{0x3333, {SGMII9, SGMII2, SGMII5, SGMII6 } },
{0x3338, {SGMII9, SGMII2, SGMII5, SATA1 } },
{}
+};
+#endif /* __LS1043A_SERDES_H */ diff --git a/Platforms/Nxp/LS1043aRdb/Include/Library/SocLib.h b/Platforms/Nxp/LS1043aRdb/Include/Library/SocLib.h index d1655d5..dc798b3 100644 --- a/Platforms/Nxp/LS1043aRdb/Include/Library/SocLib.h +++ b/Platforms/Nxp/LS1043aRdb/Include/Library/SocLib.h @@ -22,14 +22,72 @@ #define HWA_CGA_M2_CLK_SEL 0x00000007 #define HWA_CGA_M2_CLK_SHIFT 0
+#define TP_ITYP_AV 0x00000001 /* Initiator
available */
+#define TP_ITYP_TYPE(x) (((x) & 0x6) >> 1) /*
Initiator Type */
+#define TP_ITYP_TYPE_ARM 0x0 +#define TP_ITYP_TYPE_PPC 0x1 /* PowerPC */ +#define TP_ITYP_TYPE_OTHER 0x2 /* StarCore DSP */ +#define TP_ITYP_TYPE_HA 0x3 /* HW
Accelerator */
+#define TP_ITYP_THDS(x) (((x) & 0x18) >> 3)
/* # threads */
+#define TP_ITYP_VER(x) (((x) & 0xe0) >> 5) /*
Initiator Version */
+#define TY_ITYP_VER_A53 0x2
+#define TP_CLUSTER_EOC_MASK 0xc0000000 /* end of clusters
mask */
+#define TP_CLUSTER_INIT_MASK 0x0000003f /* initiator mask */ +#define TP_INIT_PER_CLUSTER 4
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define LS1043A_CLK_FREQ 100000000 #define LS1043A_DDR_CLK_FREQ 100000000
#define LS1043A_MAX_CPUS 4 +#define LS1043A_FMAN_V3 #define LS1043A_NUM_FMAN 1 +#define LS1043A_NUM_FM1_DTSEC 7 +#define LS1043A_NUM_FM1_10GEC 1
+/*
- Divide positive or negative dividend by positive divisor and
round
- to closest UINTNeger. Result is undefined for negative divisors
+and
- for negative dividends if the divisor variable type is unsigned.
- */
+#define DIV_ROUND_CLOSEST(x, divisor)( \ +{ \
typeof(x) __x = x; \
typeof(divisor) __d = divisor; \
(((typeof(x))-1) > 0 || \
((typeof(divisor))-1) > 0 || (__x) > 0) ? \
(((__x) + ((__d) / 2)) / (__d)) : \
(((__x) - ((__d) / 2)) / (__d)); \
+} \ +)
+/*
- HammingWeight32: returns the hamming weight (i.e. the number
- of bits set) of a 32-bit word
- */
+static inline UINTN HammingWeight32(UINTN w) {
UINTN Res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
Res = (Res & 0x33333333) + ((Res >> 2) & 0x33333333);
Res = (Res & 0x0F0F0F0F) + ((Res >> 4) & 0x0F0F0F0F);
Res = (Res & 0x00FF00FF) + ((Res >> 8) & 0x00FF00FF);
return (Res & 0x0000FFFF) + ((Res >> 16) & 0x0000FFFF); }
+static inline UINTN CpuMaskNext(UINTN Cpu, UINTN Mask) {
for (Cpu++; !((1 << Cpu) & Mask); Cpu++)
;
return Cpu;
+}
+#define ForEachCpu(iter, cpu, num_cpus, mask) \
for (iter = 0, cpu = CpuMaskNext(-1, mask); \
iter < num_cpus; \
iter++, cpu = CpuMaskNext(cpu, mask)) \
struct SysInfo { UINTN FreqProcessor[LS1043A_MAX_CPUS]; @@ -41,9 +99,122 @@ struct SysInfo { UINTN FreqQman; };
+typedef struct SocClocks {
UINTN CpuClk; /* CPU clock in Hz! */
UINTN BusClk;
UINTN MemClk;
UINTN PciClk;
UINTN SdhcClk;
+} SocClockInfo;
+enum PeriphClock {
ARM_CLK = 0,
BUS_CLK,
UART_CLK,
ESDHC_CLK,
I2C_CLK,
DSPI_CLK,
+};
+enum CsuCslxAccess {
SEC_UNIT_NS_SUP_R = 0x08,
SEC_UNIT_NS_SUP_W = 0x80,
SEC_UNIT_NS_SUP_RW = 0x88,
SEC_UNIT_NS_USER_R = 0x04,
SEC_UNIT_NS_USER_W = 0x40,
SEC_UNIT_NS_USER_RW = 0x44,
SEC_UNIT_S_SUP_R = 0x02,
SEC_UNIT_S_SUP_W = 0x20,
SEC_UNIT_S_SUP_RW = 0x22,
SEC_UNIT_S_USER_R = 0x01,
SEC_UNIT_S_USER_W = 0x10,
SEC_UNIT_S_USER_RW = 0x11,
SEC_UNIT_ALL_RW = 0xff,
+};
+enum CsuCslxInd {
SEC_UNIT_CSLX_PCIE2_IO = 0,
SEC_UNIT_CSLX_PCIE1_IO,
SEC_UNIT_CSLX_MG2TPR_IP,
SEC_UNIT_CSLX_IFC_MEM,
SEC_UNIT_CSLX_OCRAM,
SEC_UNIT_CSLX_GIC,
SEC_UNIT_CSLX_PCIE1,
SEC_UNIT_CSLX_OCRAM2,
SEC_UNIT_CSLX_QSPI_MEM,
SEC_UNIT_CSLX_PCIE2,
SEC_UNIT_CSLX_SATA,
SEC_UNIT_CSLX_USB1,
SEC_UNIT_CSLX_QM_BM_SWPORTAL,
SEC_UNIT_CSLX_PCIE3 = 16,
SEC_UNIT_CSLX_PCIE3_IO,
SEC_UNIT_CSLX_USB3 = 20,
SEC_UNIT_CSLX_USB2,
SEC_UNIT_CSLX_SERDES = 32,
SEC_UNIT_CSLX_QDMA,
SEC_UNIT_CSLX_LPUART2,
SEC_UNIT_CSLX_LPUART1,
SEC_UNIT_CSLX_LPUART4,
SEC_UNIT_CSLX_LPUART3,
SEC_UNIT_CSLX_LPUART6,
SEC_UNIT_CSLX_LPUART5,
SEC_UNIT_CSLX_DSPI1 = 41,
SEC_UNIT_CSLX_QSPI,
SEC_UNIT_CSLX_ESDHC,
SEC_UNIT_CSLX_IFC = 45,
SEC_UNIT_CSLX_I2C1,
SEC_UNIT_CSLX_I2C3 = 48,
SEC_UNIT_CSLX_I2C2,
SEC_UNIT_CSLX_DUART2 = 50,
SEC_UNIT_CSLX_DUART1,
SEC_UNIT_CSLX_WDT2,
SEC_UNIT_CSLX_WDT1,
SEC_UNIT_CSLX_EDMA,
SEC_UNIT_CSLX_SYS_CNT,
SEC_UNIT_CSLX_DMA_MUX2,
SEC_UNIT_CSLX_DMA_MUX1,
SEC_UNIT_CSLX_DDR,
SEC_UNIT_CSLX_QUICC,
SEC_UNIT_CSLX_DCFG_CCU_RCPM = 60,
SEC_UNIT_CSLX_SECURE_BOOTROM,
SEC_UNIT_CSLX_SFP,
SEC_UNIT_CSLX_TMU,
SEC_UNIT_CSLX_SECURE_MONITOR,
SEC_UNIT_CSLX_SCFG,
SEC_UNIT_CSLX_FM = 66,
SEC_UNIT_CSLX_SEC5_5,
SEC_UNIT_CSLX_BM,
SEC_UNIT_CSLX_QM,
SEC_UNIT_CSLX_GPIO2 = 70,
SEC_UNIT_CSLX_GPIO1,
SEC_UNIT_CSLX_GPIO4,
SEC_UNIT_CSLX_GPIO3,
SEC_UNIT_CSLX_PLATFORM_CONT,
SEC_UNIT_CSLX_SEC_UNIT,
SEC_UNIT_CSLX_IIC4 = 77,
SEC_UNIT_CSLX_WDT4,
SEC_UNIT_CSLX_WDT3,
SEC_UNIT_CSLX_WDT5 = 81,
SEC_UNIT_CSLX_FTM2 = 86,
SEC_UNIT_CSLX_FTM1,
SEC_UNIT_CSLX_FTM4,
SEC_UNIT_CSLX_FTM3,
SEC_UNIT_CSLX_FTM6 = 90,
SEC_UNIT_CSLX_FTM5,
SEC_UNIT_CSLX_FTM8,
SEC_UNIT_CSLX_FTM7,
SEC_UNIT_CSLX_DSCR = 120,
+};
+struct CsuNsDev {
UINTN Ind;
UINT32 Val;
+};
/* Device Configuration and Pin Control */ struct CcsrGur { UINT32 porsr1; /* POR status 1 */ +#define FSL_CHASSIS2_CCSR_PORSR1_RCW_MASK 0xFF800000 UINT32 porsr2; /* POR status 2 */ UINT8 res_008[0x20-0x8]; UINT32 gpporcr1; /* General-purpose POR
configuration */
@@ -51,6 +222,18 @@ struct CcsrGur { UINT32 dcfg_fusesr; /* Fuse status register */ UINT8 res_02c[0x70-0x2c]; UINT32 devdisr; /* Device disable control */ +#define FSL_CHASSIS2_DEVDISR2_DTSEC1_1 0x80000000 #define +FSL_CHASSIS2_DEVDISR2_DTSEC1_2 0x40000000 #define +FSL_CHASSIS2_DEVDISR2_DTSEC1_3 0x20000000 #define +FSL_CHASSIS2_DEVDISR2_DTSEC1_4 0x10000000 #define +FSL_CHASSIS2_DEVDISR2_DTSEC1_5 0x08000000 #define +FSL_CHASSIS2_DEVDISR2_DTSEC1_6 0x04000000 #define +FSL_CHASSIS2_DEVDISR2_DTSEC1_9 0x00800000 +#define FSL_CHASSIS2_DEVDISR2_DTSEC1_10 0x00400000 +#define FSL_CHASSIS2_DEVDISR2_10GEC1_1 0x00800000 #define +FSL_CHASSIS2_DEVDISR2_10GEC1_2 0x00400000 #define +FSL_CHASSIS2_DEVDISR2_10GEC1_3 0x80000000 #define +FSL_CHASSIS2_DEVDISR2_10GEC1_4 0x40000000 UINT32 devdisr2; /* Device disable control 2 */ UINT32 devdisr3; /* Device disable control 3 */ UINT32 devdisr4; /* Device disable control 4 */ @@ -83,6 +266,8 @@ struct CcsrGur { #define FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_MASK 0x1f #define FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_SHIFT 16 #define FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_MASK 0x3f +#define FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK 0xffff0000 +#define FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT 16 UINT8 res_140[0x200-0x140]; UINT32 scratchrw[4]; /* Scratch Read/Write */ UINT8 res_210[0x300-0x210]; @@ -259,6 +444,12 @@ struct CcsrClk { UINT8 res_c24[0x3dc]; };
+#define CCI400_CTRLORD_TERM_BARRIER 0x00000008 +#define CCI400_CTRLORD_EN_BARRIER 0 +#define CCI400_SHAORD_NON_SHAREABLE 0x00000002 +#define CCI400_DVM_MESSAGE_REQ_EN 0x00000002 +#define CCI400_SNOOP_REQ_EN 0x00000001
/* CCI-400 registers */ struct CcsrCci400 { UINT32 ctrl_ord; /* Control Override
*/
@@ -301,8 +492,18 @@ struct CcsrCci400 { UINT8 res_e004[0x10000 - 0xe004]; };
+VOID EnableDevicesNsAccess(struct CsuNsDev *NonSecureDevices, UINT32 +Num);
+VOID GetSysInfo(struct SysInfo *PtrSysInfo);
+VOID SocInit(VOID);
+VOID SerDesInit(VOID);
+VOID FdtCpuSetup(VOID *Blob);
UINT32 CalculateBaudDivisor(OUT UINT64 *BaudRate); -UINT32 CalculateI2cClockRate(VOID);
+UINT32 CalculateI2cClockRate(VOID);
#endif /* __LS1043A_SOC_H__ */ diff --git a/Platforms/Nxp/LS1043aRdb/Library/LS1043aRdbLib/LS1043aRdb.c b/Platforms/Nxp/LS1043aRdb/Library/LS1043aRdbLib/LS1043aRdb.c index 4fcb8a3..7c64709 100644 --- a/Platforms/Nxp/LS1043aRdb/Library/LS1043aRdbLib/LS1043aRdb.c +++ b/Platforms/Nxp/LS1043aRdb/Library/LS1043aRdbLib/LS1043aRdb.c @@ -24,6 +24,7 @@ #include <Library/PcdLib.h> #include <Ppi/ArmMpCoreInfo.h> #include <Library/PlatformLib.h> +#include <Library/SocLib.h>
/** Return the current Boot Mode @@ -47,6 +48,7 @@ ArmPlatformInitialize ( IN UINTN MpId ) {
- SocInit(); return RETURN_SUCCESS;
}
diff --git a/Platforms/Nxp/LS1043aRdb/Library/LS1043aSocLib/LS1043aSocLib.c b/Platforms/Nxp/LS1043aRdb/Library/LS1043aSocLib/LS1043aSocLib.c index fdeae08..2a7cb38 100644 --- a/Platforms/Nxp/LS1043aRdb/Library/LS1043aSocLib/LS1043aSocLib.c +++ b/Platforms/Nxp/LS1043aRdb/Library/LS1043aSocLib/LS1043aSocLib.c @@ -26,20 +26,227 @@ #include <Library/DebugAgentLib.h> #include <Library/IoLib.h> #include <Library/PrintLib.h> +#include <Library/SerialPortLib.h> +#include <Library/FslIfc.h>
+#include <Drivers/ArmTrustzone.h>
#include <Library/PlatformLib.h> #include <Library/SocLib.h> #include <Library/CpldLib.h>
+#include <libfdt.h>
+/* Global Clock Information pointer */ static SocClockInfo gClkInfo;
+static struct CsuNsDev NonSecureDevices[] = {
{SEC_UNIT_CSLX_PCIE2_IO, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_PCIE1_IO, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_MG2TPR_IP, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_IFC_MEM, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_OCRAM, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_GIC, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_PCIE1, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_OCRAM2, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_QSPI_MEM, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_PCIE2, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_SATA, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_USB1, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_QM_BM_SWPORTAL, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_PCIE3, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_PCIE3_IO, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_USB3, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_USB2, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_SERDES, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_QDMA, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_LPUART2, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_LPUART1, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_LPUART4, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_LPUART3, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_LPUART6, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_LPUART5, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_DSPI1, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_QSPI, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_ESDHC, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_IFC, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_I2C1, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_I2C3, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_I2C2, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_DUART2, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_DUART1, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_WDT2, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_WDT1, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_EDMA, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_SYS_CNT, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_DMA_MUX2, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_DMA_MUX1, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_DDR, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_QUICC, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_DCFG_CCU_RCPM, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_SECURE_BOOTROM, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_SFP, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_TMU, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_SECURE_MONITOR, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_SCFG, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_FM, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_SEC5_5, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_BM, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_QM, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_GPIO2, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_GPIO1, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_GPIO4, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_GPIO3, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_PLATFORM_CONT, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_SEC_UNIT, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_IIC4, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_WDT4, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_WDT3, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_WDT5, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_FTM2, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_FTM1, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_FTM4, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_FTM3, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_FTM6, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_FTM5, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_FTM8, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_FTM7, SEC_UNIT_ALL_RW},
{SEC_UNIT_CSLX_DSCR, SEC_UNIT_ALL_RW}, };
+char *StringToMHz (
- char *Buf,
- unsigned long Hz
- )
+{
long l, m, n;
n = DIV_ROUND_CLOSEST(Hz, 1000) / 1000L;
l = AsciiSPrint (Buf, sizeof(Buf), "%ld", n);
Hz -= n * 1000000L;
m = DIV_ROUND_CLOSEST(Hz, 1000L);
if (m != 0)
AsciiSPrint (Buf + l, sizeof(Buf), ".%03ld", m);
return (Buf);
+}
+VOID +CciConfigureSnoopDvm (
- struct CcsrCci400 *CciBase
- )
+{
// Enable snoop requests and DVM message requests for
// Slave insterface S4 (A53 core cluster)
MmioWrite32((UINTN)&CciBase->slave[4].snoop_ctrl,
CCI400_DVM_MESSAGE_REQ_EN |
+CCI400_SNOOP_REQ_EN); }
+VOID IfcNorInit(VOID) {
- MmioWriteBe32((UINTN)
+&(FSL_IFC_REGS_BASE)->cspr_cs[FSL_IFC_CS0].cspr_ext, +FSL_IFC_NOR_CSPR_EXT);
- MmioWriteBe32((UINTN)
- &(FSL_IFC_REGS_BASE)->ftim_cs[FSL_IFC_CS0].ftim[FSL_IFC_FTIM0],
- FSL_IFC_NOR_FTIM0);
- MmioWriteBe32((UINTN)
- &(FSL_IFC_REGS_BASE)->ftim_cs[FSL_IFC_CS0].ftim[FSL_IFC_FTIM1],
- FSL_IFC_NOR_FTIM1);
- MmioWriteBe32((UINTN)
- &(FSL_IFC_REGS_BASE)->ftim_cs[FSL_IFC_CS0].ftim[FSL_IFC_FTIM2],
- FSL_IFC_NOR_FTIM2);
- MmioWriteBe32((UINTN)
- &(FSL_IFC_REGS_BASE)->ftim_cs[FSL_IFC_CS0].ftim[FSL_IFC_FTIM3],
- FSL_IFC_NOR_FTIM3);
- MmioWriteBe32((UINTN)
+&(FSL_IFC_REGS_BASE)->cspr_cs[FSL_IFC_CS0].cspr, FSL_IFC_NOR_CSPR0);
- MmioWriteBe32((UINTN)
+&(FSL_IFC_REGS_BASE)->amask_cs[FSL_IFC_CS0].amask, +FSL_IFC_NOR_AMASK0);
- MmioWriteBe32((UINTN)
+&(FSL_IFC_REGS_BASE)->csor_cs[FSL_IFC_CS0].csor, FSL_IFC_NOR_CSOR0); +}
+VOID +CciConfigureQos (
- struct CcsrCci400 *CciBase
- )
+{
// FIXME: Empty for now. Populate if required later.
return;
+}
+VOID +Cci400Init (
- VOID
- )
+{
struct CcsrCci400 *Base = (struct CcsrCci400
+*)LS1043A_CCI400_ADDR;
/* Set CCI-400 control override register to enable barrier
transaction */
MmioWrite32((UINTN)&Base->ctrl_ord,
- CCI400_CTRLORD_EN_BARRIER);
CciConfigureSnoopDvm(Base);
CciConfigureQos(Base);
+}
+/**
- Initialize the Secure peripherals and memory regions
- If Trustzone is supported by your platform then this function
makes
- the required initialization of the secure peripherals and memory
regions.
+**/ +VOID +Tzc380Init (
- VOID
- )
+{
- // Setup TZ Address Space Controller.
- // Assumption: We have 2GB DDR mounted on the DIMMs.
- //
- // Since, we need ONE secure DDR region which will be used for
+keeping
- // the PPA (EL3 platform security fw) code and the rest of the
+regions
- // would be non-secure regions which can be accessed via NS
+software as
- // well - so we create one TZASC region of 2GB and divided it into
- // 8 equal su-regions. Now, we keep the 1st sub-regions for
housing
- // the PPA and use the rest of the sub-regions to allow NS
accesses.
- // Note: Your OS Kernel must be aware of the secure regions before
+to
- // enable this region
- TZASCSetRegion(LS1043A_TZASC380_ADDR, 1, TZASC_REGION_ENABLED,
LS1043A_DRAM1_BASE_ADDR, 0,
TZASC_REGION_SIZE_2GB, TZASC_REGION_SECURITY_SRW,
+0x7F); }
+VOID +EnableDevicesNsAccess (
- OUT struct CsuNsDev *NonSecureDevices,
- IN UINT32 Num
- )
+{
UINT32 *Base = (UINT32 *)LS1043A_CSU_ADDR;
UINT32 *Reg;
UINT32 Val;
UINT32 Count;
for (Count = 0; Count < Num; Count++) {
Reg = Base + NonSecureDevices[Count].Ind / 2;
Val = MmioReadBe32((UINTN)Reg);
if (NonSecureDevices[Count].Ind % 2 == 0) {
Val &= 0x0000ffff;
Val |= NonSecureDevices[Count].Val << 16;
} else {
Val &= 0xffff0000;
Val |= NonSecureDevices[Count].Val;
}
MmioWriteBe32((UINTN)Reg, Val);
}
+}
+VOID +CsuInit (
- VOID
- )
+{
EnableDevicesNsAccess(NonSecureDevices,
+ARRAY_SIZE(NonSecureDevices)); }
VOID GetSysInfo ( OUT struct SysInfo *PtrSysInfo ) {
struct CcsrGur *GurBase = (void *)(LS1043A_FSL_GUTS_ADDR);
struct CcsrClk *ClkBase = (void *)(LS1043A_FSL_CLK_ADDR);
struct CcsrGur *GurBase = (void *)(LS1043A_GUTS_ADDR);
struct CcsrClk *ClkBase = (void *)(LS1043A_CLK_ADDR); UINTN CpuIndex; UINT32 TempRcw; const UINT8 CoreCplxPll[8] = { @@ -57,8 +264,8 @@ GetSysInfo
(
}; UINTN PllCount;
UINTN FreqCPll[LS1043A_FSL_NUM_CC_PLLS];
UINTN PllRatio[LS1043A_FSL_NUM_CC_PLLS];
UINTN FreqCPll[LS1043A_NUM_CC_PLLS];
UINTN PllRatio[LS1043A_NUM_CC_PLLS]; UINTN SysClk = LS1043A_CLK_FREQ; PtrSysInfo->FreqSystemBus = SysClk; @@ -71,7 +278,7 @@
GetSysInfo ( FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_SHIFT) & FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_MASK;
for (PllCount = 0; PllCount < LS1043A_FSL_NUM_CC_PLLS;
PllCount++) {
for (PllCount = 0; PllCount < LS1043A_NUM_CC_PLLS;
PllCount++)
- { PllRatio[PllCount] = (MmioReadBe32((UINTN)&ClkBase-
pllcgsr[PllCount].pllcngsr) >> 1) & 0xff; if (PllRatio[PllCount] > 4) FreqCPll[PllCount] = SysClk * PllRatio[PllCount]; @@ -112,6 +319,461 @@ GetSysInfo ( PtrSysInfo->FreqQman = PtrSysInfo->FreqSystemBus / 2; }
+VOID +ClockInit (
- VOID
- )
+{
struct SysInfo SocSysInfo;
GetSysInfo(&SocSysInfo);
gClkInfo.CpuClk = SocSysInfo.FreqProcessor[0];
gClkInfo.BusClk = SocSysInfo.FreqSystemBus;
gClkInfo.MemClk = SocSysInfo.FreqDdrBus;
gClkInfo.SdhcClk = SocSysInfo.FreqSdhc; }
+INTN +TimerInit (
- VOID
- )
+{
UINT32 *TimerBase = (UINT32 *)LS1043A_TIMER_ADDR;
if (PcdGetBool(PcdCounterFrequencyReal)) {
UINTN cntfrq = PcdGet32(PcdCounterFrequency);
/* Update with accurate clock frequency */
asm volatile("msr cntfrq_el0, %0" : : "r" (cntfrq) :
"memory");
}
/* Enable clock for timer. This is a global setting. */
MmioWrite32((UINTN)TimerBase, 0x1);
return 0;
+}
+static inline +UINT32 +InitiatorType (
- IN UINT32 Cluster,
- IN UINTN InitId
- )
+{
struct CcsrGur *GurBase = (void *)(LS1043A_GUTS_ADDR);
UINT32 Idx = (Cluster >> (InitId * 8)) &
TP_CLUSTER_INIT_MASK;
UINT32 Type = MmioReadBe32((UINTN)&GurBase->tp_ityp[Idx]);
if (Type & TP_ITYP_AV)
return Type;
return 0;
+}
+UINT32 +CpuMask (
- VOID
- )
+{
struct CcsrGur *GurBase = (void *)(LS1043A_GUTS_ADDR);
UINTN ClusterIndex = 0, Count = 0;
UINT32 Cluster, Type, Mask = 0;
do {
UINTN InitiatorIndex;
Cluster = MmioReadBe32((UINTN)&GurBase-
tp_cluster[ClusterIndex].lower);
for (InitiatorIndex = 0; InitiatorIndex <
TP_INIT_PER_CLUSTER; InitiatorIndex++) {
Type = InitiatorType(Cluster,
InitiatorIndex);
if (Type) {
if (TP_ITYP_TYPE(Type) ==
TP_ITYP_TYPE_ARM)
Mask |= 1 << Count;
Count++;
}
}
ClusterIndex++;
} while ((Cluster & TP_CLUSTER_EOC_MASK) == 0x0);
return Mask;
+}
+/*
- Return the number of cores on this SOC.
- */
+UINTN +CpuNumCores (
- VOID
- )
+{
return HammingWeight32(CpuMask()); }
+UINT32 +QoriqCoreToType (
- IN UINTN Core
- )
+{
struct CcsrGur *GurBase = (VOID *)(LS1043A_GUTS_ADDR);
UINTN ClusterIndex = 0, Count = 0;
UINT32 Cluster, Type;
do {
UINTN InitiatorIndex;
Cluster = MmioReadBe32((UINTN)&GurBase-
tp_cluster[ClusterIndex].lower);
for (InitiatorIndex = 0; InitiatorIndex <
TP_INIT_PER_CLUSTER; InitiatorIndex++) {
Type = InitiatorType(Cluster,
InitiatorIndex);
if (Type) {
if (Count == Core)
return Type;
Count++;
}
}
ClusterIndex++;
} while ((Cluster & TP_CLUSTER_EOC_MASK) == 0x0);
return -1; /* cannot identify the cluster */
+}
+VOID +PrintCpuInfo (
- VOID
- )
+{
struct SysInfo SysInfo;
UINTN CoreIndex, Core;
UINT32 Type;
CHAR8 Buf[32];
CHAR8 Buffer[100];
UINTN CharCount;
GetSysInfo(&SysInfo);
CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "Clock
Configuration:");
SerialPortWrite ((UINT8 *) Buffer, CharCount);
ForEachCpu(CoreIndex, Core, CpuNumCores(), CpuMask()) {
if (!(CoreIndex % 3))
DEBUG((EFI_D_INFO, "\n "));
Type = TP_ITYP_VER(QoriqCoreToType(Core));
CharCount = AsciiSPrint (Buffer, sizeof (Buffer),
"CPU%d(%a):%-4a MHz ", Core,
Type == TY_ITYP_VER_A53 ? "A53" : "Unknown
Core",
StringToMHz(Buf,
SysInfo.FreqProcessor[Core]));
SerialPortWrite ((UINT8 *) Buffer, CharCount);
}
CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "\n
Bus: %-4a MHz ",
StringToMHz(Buf, SysInfo.FreqSystemBus));
SerialPortWrite ((UINT8 *) Buffer, CharCount);
CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "DDR:
%-4a MHz", StringToMHz(Buf, SysInfo.FreqDdrBus));
SerialPortWrite ((UINT8 *) Buffer, CharCount);
CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "\n");
SerialPortWrite ((UINT8 *) Buffer, CharCount); }
+VOID +PrintSocPersonality (
- VOID
- )
+{ +}
+VOID +IfcInit (
- VOID
- )
+{
/* NOR Init */
IfcNorInit();
/* CPLD Init */
CpldInit();
+}
+VOID +PrintBoardPersonality (
- VOID
- )
+{
static const char *Freq[3] = {"100.00MHZ", "156.25MHZ"};
UINT8 RcwSrc1, RcwSrc2;
UINT32 RcwSrc;
UINT32 sd1refclk_sel;
DEBUG((EFI_D_INFO, "Board: LS1043ARDB, boot from "));
RcwSrc1 = CPLD_READ(RcwSource1);
RcwSrc2 = CPLD_READ(RcwSource1);
CpldRevBit(&RcwSrc1);
RcwSrc = RcwSrc1;
RcwSrc = (RcwSrc << 1) | RcwSrc2;
if (RcwSrc == 0x25)
DEBUG((EFI_D_INFO, "vBank %d\n", CPLD_READ(Vbank)));
else if (RcwSrc == 0x106)
DEBUG((EFI_D_INFO, "NAND\n"));
else
DEBUG((EFI_D_INFO, "Invalid setting of SW4\n"));
DEBUG((EFI_D_INFO, "CPLD: V%x.%x\nPCBA: V%x.0\n",
CPLD_READ(CpldVersionMajor),
CPLD_READ(CpldVersionMinor),
CPLD_READ(PcbaVersion)));
DEBUG((EFI_D_INFO, "SERDES Reference Clocks:\n"));
sd1refclk_sel = CPLD_READ(Sd1RefClkSel);
DEBUG((EFI_D_INFO, "SD1_CLK1 = %a, SD1_CLK2 = %a\n",
+Freq[sd1refclk_sel], Freq[0])); }
+VOID +PrintRCW (
- VOID
- )
+{
struct CcsrGur *Base = (void *)(LS1043A_GUTS_ADDR);
UINTN Count;
CHAR8 Buffer[100];
UINTN CharCount;
/*
* Display the RCW, so that no one gets confused as to what
RCW
* we're actually using for this boot.
*/
CharCount = AsciiSPrint (Buffer, sizeof (Buffer),
"Reset Configuration Word (RCW):");
SerialPortWrite ((UINT8 *) Buffer, CharCount);
for (Count = 0; Count < ARRAY_SIZE(Base->rcwsr); Count++) {
UINT32 Rcw = MmioReadBe32((UINTN)&Base-
rcwsr[Count]);
if ((Count % 4) == 0) {
CharCount = AsciiSPrint (Buffer, sizeof
(Buffer),
"\n %08x:",
Count * 4);
SerialPortWrite ((UINT8 *) Buffer,
CharCount);
}
CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "
%08x", Rcw);
SerialPortWrite ((UINT8 *) Buffer, CharCount);
}
CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "\n");
SerialPortWrite ((UINT8 *) Buffer, CharCount); }
+VOID +SmmuInit (
- VOID
- )
+{
UINT32 Value;
/* set pagesize as 64K and ssmu-500 in bypass mode */
Value = (MmioRead32((UINTN)SMMU_REG_SACR) |
SACR_PAGESIZE_MASK);
MmioWrite32((UINTN)SMMU_REG_SACR, Value);
Value = (MmioRead32((UINTN)SMMU_REG_SCR0) |
SCR0_CLIENTPD_MASK) & ~(SCR0_USFCFG_MASK);
MmioWrite32((UINTN)SMMU_REG_SCR0, Value);
Value = (MmioRead32((UINTN)SMMU_REG_NSCR0) |
SCR0_CLIENTPD_MASK) & ~(SCR0_USFCFG_MASK);
MmioWrite32((UINTN)SMMU_REG_NSCR0, Value); }
+/**
- Function to initialize SoC specific constructs
- // CSU
- // TZC-380
- // CCI-400
- // ClockInit
- // TimerInit
- // CPU Info
- // SoC Personality
- // Board Personality
- // RCW prints
- // SerDes support
- **/
+VOID +SocInit (
- VOID
- )
+{
- CHAR8 Buffer[100];
- UINTN CharCount;
- // LS1043A SoC has a CSU (Central Security Unit) if
- (PcdGetBool(PcdCsuInitialize))
CsuInit();
- if (PcdGetBool(PcdTzc380Initialize))
Tzc380Init();
- if (PcdGetBool(PcdCci400Initialize))
Cci400Init();
- if (PcdGetBool(PcdClockInitialize))
ClockInit();
- SmmuInit();
- TimerInit();
- // Initialize the Serial Port
- SerialPortInitialize ();
- CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "\nUEFI firmware
(version %s built at %a on %a)\n\r",
- (CHAR16*)PcdGetPtr(PcdFirmwareVersionString), __TIME__,
- __DATE__); SerialPortWrite ((UINT8 *) Buffer, CharCount);
- PrintCpuInfo();
- PrintRCW();
- PrintSocPersonality();
- IfcInit();
- PrintBoardPersonality();
- SerDesInit();
- return;
+}
+/* fdt fixup for LS1043A */
+VOID +FixupByCompatibleField (
- VOID *Fdt,
- CONST char *Compat,
- CONST char *Prop,
- CONST VOID *Val,
- INTN Len,
- INTN Create
- )
+{
INTN Offset = -1;
Offset = fdt_node_offset_by_compatible(Fdt, -1, Compat);
while (Offset != -FDT_ERR_NOTFOUND) {
if (Create || (fdt_get_property(Fdt, Offset, Prop,
NULL) != NULL))
fdt_setprop(Fdt, Offset, Prop, Val, Len);
Offset = fdt_node_offset_by_compatible(Fdt, Offset,
Compat);
}
+}
+VOID +FixupByCompatibleField32 (
- VOID *Fdt,
- CONST char *Compat,
- CONST char *Prop,
- UINT32 Val,
- INTN Create
- )
+{
fdt32_t Tmp = cpu_to_fdt32(Val);
FixupByCompatibleField(Fdt, Compat, Prop, &Tmp, 4, Create); }
+#define BMAN_IP_REV_1 0xBF8 +#define BMAN_IP_REV_2 0xBFC +VOID +FdtFixupBmanPortals (
- VOID *Blob
- )
+{
UINTN Off, Err;
UINTN Maj, Min;
UINTN IpCfg;
UINT32 BmanRev1 = MmioReadBe32(LS1043A_BMAN_ADDR +
BMAN_IP_REV_1);
UINT32 BmanRev2 = MmioReadBe32(LS1043A_BMAN_ADDR +
BMAN_IP_REV_2);
char Compatible[64];
INTN CompatibleLength;
Maj = (BmanRev1 >> 8) & 0xff;
Min = BmanRev1 & 0xff;
IpCfg = BmanRev2 & 0xff;
CompatibleLength = AsciiSPrint(Compatible,
sizeof(Compatible),
"fsl,bman-portal-%u.%u.%u",
Maj, Min, IpCfg) + 1;
CompatibleLength += AsciiSPrint(Compatible +
CompatibleLength,
sizeof(Compatible),
"fsl,bman-portal")
+ 1;
Off = fdt_node_offset_by_compatible(Blob, -1, "fsl,bman-
portal");
while (Off != -FDT_ERR_NOTFOUND) {
Err = fdt_setprop(Blob, Off, "compatible",
Compatible,
CompatibleLength);
if (Err < 0) {
DEBUG((EFI_D_ERROR, "ERROR: unable to create
props for %a: %s\n",
fdt_get_name(Blob, Off, NULL),
fdt_strerror(Err)));
return;
}
Off = fdt_node_offset_by_compatible(Blob, Off,
"fsl,bman-portal");
}
+}
+#define QMAN_IP_REV_1 0xBF8 +#define QMAN_IP_REV_2 0xBFC +VOID +FdtFixupQmanPortals (
- VOID *Blob
- )
+{
INTN Off, Err;
UINTN Maj, Min;
UINTN IpCfg;
UINT32 QmanRev1 = MmioReadBe32(LS1043A_QMAN_ADDR +
QMAN_IP_REV_1);
UINT32 QmanRev2 = MmioReadBe32(LS1043A_QMAN_ADDR +
QMAN_IP_REV_2);
char Compatible[64];
INTN CompatLength;
Maj = (QmanRev1 >> 8) & 0xff;
Min = QmanRev1 & 0xff;
IpCfg = QmanRev2 & 0xff;
CompatLength = AsciiSPrint(Compatible, sizeof(Compatible),
"fsl,qman-portal-%u.%u.%u",
Maj, Min, IpCfg) + 1;
CompatLength += AsciiSPrint(Compatible + CompatLength,
sizeof(Compatible),
- "fsl,qman-portal") + 1;
Off = fdt_node_offset_by_compatible(Blob, -1, "fsl,qman-
portal");
while (Off != -FDT_ERR_NOTFOUND) {
Err = fdt_setprop(Blob, Off, "compatible",
Compatible,
CompatLength);
if (Err < 0) {
DEBUG((EFI_D_ERROR, "ERROR: unable to create
props for %a: %a\n",
fdt_get_name(Blob, Off, NULL),
fdt_strerror(Err)));
return;
}
Off = fdt_node_offset_by_compatible(Blob, Off,
"fsl,qman-portal");
}
+}
+VOID +FdtFixupSdhc (
- VOID *Blob,
- UINTN SdhcClk
- )
+{
const char *Compatible = "fsl,esdhc";
FixupByCompatibleField32(Blob, Compatible, "clock-frequency",
- SdhcClk, 1);
FixupByCompatibleField(Blob, Compatible, "status", "okay", 4
+1, 1); }
+VOID FdtCpuSetup(VOID *blob) +{
struct SysInfo SocSysInfo;
GetSysInfo(&SocSysInfo);
FixupByCompatibleField32(blob, "fsl,ns16550",
"clock-frequency",
- SocSysInfo.FreqSystemBus, 1);
FdtFixupSdhc(blob, SocSysInfo.FreqSdhc);
FdtFixupBmanPortals(blob);
FdtFixupQmanPortals(blob);
FixupByCompatibleField32(blob, "fsl,qman",
"clock-frequency", SocSysInfo.FreqQman, 1); }
UINT32 CalculateBaudDivisor ( @@ -135,6 +797,6 @@ CalculateI2cClockRate( struct SysInfo SocSysInfo;
GetSysInfo(&SocSysInfo);
return SocSysInfo.FreqSystemBus;
return SocSysInfo.FreqSystemBus;
} diff --git a/Platforms/Nxp/LS1043aRdb/Library/LS1043aSocLib/LS1043aSocLib.inf b/Platforms/Nxp/LS1043aRdb/Library/LS1043aSocLib/LS1043aSocLib.inf index 322fe34..307cf21 100644
a/Platforms/Nxp/LS1043aRdb/Library/LS1043aSocLib/LS1043aSocLib.inf
+++
b/Platforms/Nxp/LS1043aRdb/Library/LS1043aSocLib/LS1043aSocLib.inf
@@ -29,12 +29,25 @@ OpenPlatformPkg/Chips/Nxp/QoriqLs/NxpQoriqLs.dec
[LibraryClasses]
- ArmTrustZoneLib BaseLib CpldLib DebugLib DebugAgentLib IoLib ArmLib
- MemoryAllocationLib
- SerialPortLib
[Sources.common] LS1043aSocLib.c
- LsSerDes.c
+[FixedPcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
- gArmPlatformTokenSpaceGuid.PcdCounterFrequencyReal
- gArmPlatformTokenSpaceGuid.PcdCsuInitialize
- gArmPlatformTokenSpaceGuid.PcdTzc380Initialize
- gArmPlatformTokenSpaceGuid.PcdCci400Initialize
- gArmPlatformTokenSpaceGuid.PcdClockInitialize
- gArmPlatformTokenSpaceGuid.PcdCounterFrequency
diff --git
a/Platforms/Nxp/LS1043aRdb/Library/LS1043aSocLib/LsSerDes.c
b/Platforms/Nxp/LS1043aRdb/Library/LS1043aSocLib/LsSerDes.c new file mode 100644 index 0000000..3312e9b --- /dev/null +++ b/Platforms/Nxp/LS1043aRdb/Library/LS1043aSocLib/LsSerDes.c @@ -0,0 +1,195 @@ +/** LsSerDes.c
- Provides the basic interfaces for SerDes Module
- Copyright (c) 2016, Freescale Semiconductor, Inc. All rights
reserved.
- This program and the accompanying materials are licensed and made
- available under the terms and conditions of the BSD License which
- accompanies this distribution. The full text of the license may be
- found http://opensource.org/licenses/bsd-license.php
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
- BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h> +#include <Library/PlatformLib.h> +#include <Library/SocLib.h> +#include <Library/DebugLib.h> +#include <Library/DebugAgentLib.h> +#include <Library/IoLib.h> +#include <Library/Ls1043aSerDes.h>
+#ifdef LS1043A_SRDS_1 +static UINT16 SerDes1PrtclMap[SERDES_PRCTL_COUNT]; +#endif
+static struct SerDesConfig *SerDesConfigTbl[] = {
SerDes1ConfigTbl
+};
+SrdsPrtcl +GetSerDesPrtcl +(
- IN INTN SerDes,
- IN INTN Cfg,
- IN INTN Lane
+) +{
- struct SerDesConfig *Config;
- if (SerDes >= ARRAY_SIZE(SerDesConfigTbl))
- return 0;
- Config = SerDesConfigTbl[SerDes];
- while (Config->Protocol) {
- if (Config->Protocol == Cfg) {
return Config->SrdsLane[Lane];
- }
- Config++;
- }
- return EFI_SUCCESS;
+}
+EFI_STATUS +CheckSerDesPrtclValid +(
- IN INTN SerDes,
- IN UINT32 Prtcl
+) +{
- INTN Cnt;
- struct SerDesConfig *Config;
- if (SerDes >= ARRAY_SIZE(SerDesConfigTbl))
- return 0;
- Config = SerDesConfigTbl[SerDes];
- while (Config->Protocol) {
- if (Config->Protocol == Prtcl) {
DEBUG((EFI_D_INFO, "Protocol: %x Matched with the one in
Table\n", Prtcl));
break;
- }
- Config++;
- }
- if (!Config->Protocol)
- return 0;
- for (Cnt = 0; Cnt < SRDS_MAX_LANES; Cnt++) {
- if (Config->SrdsLane[Cnt] != NONE)
return 1;
- }
- return 0;
+}
+EFI_STATUS +IsSerDesConfigured +(
- IN SrdsPrtcl Device
+) +{
- INTN Ret = 0;
+#ifdef LS1043A_SRDS_1
- Ret |= SerDes1PrtclMap[Device];
+#endif
- return !!Ret;
+}
+INTN +GetSerDesFirstLane +(
- IN UINT32 Sd,
- IN SrdsPrtcl Device
+) +{
- struct CcsrGur *Gur = (void *)(LS1043A_GUTS_ADDR);
- UINT32 Cfg = MmioReadBe32((UINTN)&Gur->rcwsr[4]);
- INTN Cnt;
- switch (Sd) {
+#ifdef LS1043A_SRDS_1
- case FSL_SRDS_1:
- Cfg &= LS1043_RCWSR4_SRDS1_PRTCL_MASK;
- Cfg >>= LS1043_RCWSR4_SRDS1_PRTCL_SHIFT;
- break;
+#endif
- default:
- DEBUG((EFI_D_INFO, "Invalid SerDes%d, Only one SerDes is
there.\n", Sd));
- break;
- }
- /* Is serdes enabled at all? */
- if (Cfg == 0)
- return EFI_DEVICE_ERROR;
- for (Cnt = 0; Cnt < SRDS_MAX_LANES; Cnt++) {
- if (GetSerDesPrtcl(Sd, Cfg, Cnt) == Device)
return Cnt;
- }
- return EFI_DEVICE_ERROR;
+}
+VOID +LSSerDesInit +(
- UINT32 Srds,
- UINT32 SrdsAddr,
- UINT32 SrdsPrtclMask,
- UINT32 SrdsPrtclShift,
- UINT16 SerDesPrtclMap[SERDES_PRCTL_COUNT]
+) +{
- struct CcsrGur *Gur = (VOID *)(LS1043A_GUTS_ADDR);
- UINT32 SrdsProt;
- INTN Lane;
- UINT32 Flag = 0;
- SrdsProt = MmioReadBe32((UINTN)&Gur->rcwsr[4]) & SrdsPrtclMask;
- SrdsProt >>= SrdsPrtclShift;
- DEBUG((EFI_D_INFO, "Using SERDES%d Protocol: %d (0x%x)\n", Srds +
- 1, SrdsProt, SrdsProt));
- if (!CheckSerDesPrtclValid(Srds, SrdsProt)) {
- DEBUG((EFI_D_ERROR, "SERDES%d[PRTCL] = 0x%x is not valid\n",
Srds + 1, SrdsProt));
- Flag++;
- }
- for (Lane = 0; Lane < SRDS_MAX_LANES; Lane++) {
- SrdsPrtcl LanePrtcl = GetSerDesPrtcl(Srds, SrdsProt, Lane);
- if (LanePrtcl >= SERDES_PRCTL_COUNT) {
DEBUG((EFI_D_ERROR, "Unknown SerDes lane protocol %d\n",
LanePrtcl));
Flag++;
- } else {
SerDesPrtclMap[LanePrtcl] = 1;
- }
- }
- if (Flag)
- DEBUG((EFI_D_ERROR, "Could not configure SerDes module!!\n"));
- else
- DEBUG((EFI_D_INFO, "Successfully configured SerDes
module!!\n"));
+}
+VOID +SerDesInit +(
- VOID
+) +{
- DEBUG((EFI_D_INFO, "Initializing SerDes....\n")); #ifdef
+LS1043A_SRDS_1
- LSSerDesInit(FSL_SRDS_1,
LS1043A_SERDES_ADDR,
LS1043_RCWSR4_SRDS1_PRTCL_MASK,
LS1043_RCWSR4_SRDS1_PRTCL_SHIFT,
SerDes1PrtclMap);
+#endif
+}
1.9.1
Regards, Bhupesh