board: lx2160aqds: implement board_fit_config_name_match
authorIoana Ciornei <ioana.ciornei@nxp.com>
Mon, 27 Apr 2020 12:21:16 +0000 (15:21 +0300)
committerPriyanka Jain <priyanka.jain@nxp.com>
Tue, 19 May 2020 03:52:07 +0000 (09:22 +0530)
In case CONFIG_DM_ETH and CONFIG_MULTI_DTB_FIT are enabled implement the
board_fit_config_name_match() function in order to choose the
appropriate DTS for the current SERDES protocol configuration.

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Reviewed-by: Razvan Ionut Cirjan <razvanionut.cirjan@nxp.com>
Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com>
board/freescale/lx2160a/eth_lx2160aqds.c

index 3b7830343d1e2c074cb79caed4d9b1dde070b535..d90b5c3e3a2f6c5a028ddd31814493ad80433ae7 100644 (file)
@@ -848,3 +848,112 @@ int fdt_fixup_board_phy(void *fdt)
 }
 #endif // CONFIG_FSL_MC_ENET
 #endif
 }
 #endif // CONFIG_FSL_MC_ENET
 #endif
+
+#if defined(CONFIG_DM_ETH) && defined(CONFIG_MULTI_DTB_FIT)
+
+/* Structure to hold SERDES protocols supported in case of
+ * CONFIG_DM_ETH enabled (network interfaces are described in the DTS).
+ *
+ * @serdes_block: the index of the SERDES block
+ * @serdes_protocol: the decimal value of the protocol supported
+ * @dts_needed: DTS notes describing the current configuration are needed
+ *
+ * When dts_needed is true, the board_fit_config_name_match() function
+ * will try to exactly match the current configuration of the block with a DTS
+ * name provided.
+ */
+static struct serdes_configuration {
+       u8 serdes_block;
+       u32 serdes_protocol;
+       bool dts_needed;
+} supported_protocols[] = {
+       /* Serdes block #1 */
+       {1, 3, true},
+       {1, 7, true},
+       {1, 19, true},
+       {1, 20, true},
+
+       /* Serdes block #2 */
+       {2, 2, false},
+       {2, 3, false},
+       {2, 5, false},
+       {2, 11, true},
+
+       /* Serdes block #3 */
+       {3, 2, false},
+       {3, 3, false},
+};
+
+#define SUPPORTED_SERDES_PROTOCOLS ARRAY_SIZE(supported_protocols)
+
+static bool protocol_supported(u8 serdes_block, u32 protocol)
+{
+       struct serdes_configuration serdes_conf;
+       int i;
+
+       for (i = 0; i < SUPPORTED_SERDES_PROTOCOLS; i++) {
+               serdes_conf = supported_protocols[i];
+               if (serdes_conf.serdes_block == serdes_block &&
+                   serdes_conf.serdes_protocol == protocol)
+                       return true;
+       }
+
+       return false;
+}
+
+static void get_str_protocol(u8 serdes_block, u32 protocol, char *str)
+{
+       struct serdes_configuration serdes_conf;
+       int i;
+
+       for (i = 0; i < SUPPORTED_SERDES_PROTOCOLS; i++) {
+               serdes_conf = supported_protocols[i];
+               if (serdes_conf.serdes_block == serdes_block &&
+                   serdes_conf.serdes_protocol == protocol) {
+                       if (serdes_conf.dts_needed == true)
+                               sprintf(str, "%u", protocol);
+                       else
+                               sprintf(str, "x");
+                       return;
+               }
+       }
+}
+
+int board_fit_config_name_match(const char *name)
+{
+       struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+       u32 rcw_status = in_le32(&gur->rcwsr[28]);
+       char srds_s1_str[2], srds_s2_str[2], srds_s3_str[2];
+       u32 srds_s1, srds_s2, srds_s3;
+       char expected_dts[100];
+
+       srds_s1 = rcw_status & FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK;
+       srds_s1 >>= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
+
+       srds_s2 = rcw_status & FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK;
+       srds_s2 >>= FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
+
+       srds_s3 = rcw_status & FSL_CHASSIS3_RCWSR28_SRDS3_PRTCL_MASK;
+       srds_s3 >>= FSL_CHASSIS3_RCWSR28_SRDS3_PRTCL_SHIFT;
+
+       /* Check for supported protocols. The default DTS will be used
+        * in this case
+        */
+       if (!protocol_supported(1, srds_s1) ||
+           !protocol_supported(2, srds_s2) ||
+           !protocol_supported(3, srds_s3))
+               return -1;
+
+       get_str_protocol(1, srds_s1, srds_s1_str);
+       get_str_protocol(2, srds_s2, srds_s2_str);
+       get_str_protocol(3, srds_s3, srds_s3_str);
+
+       sprintf(expected_dts, "fsl-lx2160a-qds-%s-%s-%s",
+               srds_s1_str, srds_s2_str, srds_s3_str);
+
+       if (!strcmp(name, expected_dts))
+               return 0;
+
+       return -1;
+}
+#endif