]> Git Repo - J-linux.git/commitdiff
phy: lan969x-serdes: add support for lan969x serdes driver
authorDaniel Machon <[email protected]>
Mon, 9 Sep 2024 15:14:49 +0000 (17:14 +0200)
committerVinod Koul <[email protected]>
Mon, 21 Oct 2024 18:32:04 +0000 (00:02 +0530)
Add support for lan969x SERDES driver. Lan969x has ten 10G SERDES'es
which share the same features and data rates as the Sparx5 SERDES'es.

Signed-off-by: Daniel Machon <[email protected]>
Reviewed-by: Steen Hegelund <[email protected]>
Link: https://lore.kernel.org/r/20240909-sparx5-lan969x-serdes-driver-v2-9-d695bcb57b84@microchip.com
Signed-off-by: Vinod Koul <[email protected]>
drivers/phy/microchip/sparx5_serdes.c
drivers/phy/microchip/sparx5_serdes.h

index 05fdf225ff43fd0ec619a4f14e3e9f28f23716cc..320cf5b50a8cc394308a556a1d5894ac0ea1e047 100644 (file)
@@ -25,6 +25,8 @@
 #define SPX5_SERDES_25G_START 25
 #define SPX5_SERDES_6G10G_CNT SPX5_SERDES_25G_START
 
+#define LAN969X_SERDES_10G_CNT 10
+
 /* Optimal power settings from GUC */
 #define SPX5_SERDES_QUIET_MODE_VAL 0x01ef4e0c
 
@@ -36,6 +38,13 @@ const unsigned int sparx5_serdes_tsize[TSIZE_LAST] = {
        [TC_SD_LANE] = 25,
 };
 
+const unsigned int lan969x_serdes_tsize[TSIZE_LAST] = {
+       [TC_SD10G_LANE] = 10,
+       [TC_SD_CMU] = 6,
+       [TC_SD_CMU_CFG] = 6,
+       [TC_SD_LANE] = 10,
+};
+
 /* Pointer to the register target size table */
 const unsigned int *tsize;
 
@@ -1096,6 +1105,24 @@ static int sparx5_serdes_cmu_get(enum sparx5_10g28cmu_mode mode, int sd_index)
        return sparx5_serdes_cmu_map[mode][sd_index];
 }
 
+/* Map of 6G/10G serdes mode and index to CMU index. */
+static const int
+lan969x_serdes_cmu_map[SPX5_SD10G28_CMU_MAX][LAN969X_SERDES_10G_CNT] = {
+       [SPX5_SD10G28_CMU_MAIN] = { 2, 2, 2, 2, 2,
+                                   2, 2, 2, 5, 5 },
+       [SPX5_SD10G28_CMU_AUX1] = { 0, 0, 3, 3, 3,
+                                   3, 3, 3, 3, 3 },
+       [SPX5_SD10G28_CMU_AUX2] = { 1, 1, 1, 1, 4,
+                                   4, 4, 4, 4, 4 },
+       [SPX5_SD10G28_CMU_NONE] = { 1, 1, 1, 1, 4,
+                                   4, 4, 4, 4, 4 },
+};
+
+static int lan969x_serdes_cmu_get(enum sparx5_10g28cmu_mode mode, int sd_index)
+{
+       return lan969x_serdes_cmu_map[mode][sd_index];
+}
+
 static void sparx5_serdes_cmu_power_off(struct sparx5_serdes_private *priv)
 {
        void __iomem *cmu_inst, *cmu_cfg_inst;
@@ -2184,6 +2211,10 @@ static int sparx5_serdes_clock_config(struct sparx5_serdes_macro *macro)
 {
        struct sparx5_serdes_private *priv = macro->priv;
 
+       /* Clock is auto-detected in 100Base-FX mode on lan969x */
+       if (priv->data->type == SPX5_TARGET_LAN969X)
+               return 0;
+
        if (macro->serdesmode == SPX5_SD_MODE_100FX) {
                u32 freq = priv->coreclock == 250000000 ? 2 :
                        priv->coreclock == 500000000 ? 1 : 0;
@@ -2395,6 +2426,12 @@ static void sparx5_serdes_type_set(struct sparx5_serdes_macro *macro, int sidx)
        }
 }
 
+static void lan969x_serdes_type_set(struct sparx5_serdes_macro *macro, int sidx)
+{
+       macro->serdestype = SPX5_SDT_10G;
+       macro->stpidx = macro->sidx;
+}
+
 static int sparx5_phy_create(struct sparx5_serdes_private *priv,
                           int idx, struct phy **phy)
 {
@@ -2519,6 +2556,41 @@ static struct sparx5_serdes_io_resource sparx5_serdes_iomap[] =  {
        { TARGET_SD_LANE_25G + 7, 0x5c8000 }, /* 0x610dd0000: sd_lane_25g_32 */
 };
 
+static const struct sparx5_serdes_io_resource lan969x_serdes_iomap[] =  {
+       { TARGET_SD_CMU,               0x0     }, /* 0xe3410000 */
+       { TARGET_SD_CMU +  1,          0x8000  }, /* 0xe3418000 */
+       { TARGET_SD_CMU +  2,          0x10000 }, /* 0xe3420000 */
+       { TARGET_SD_CMU +  3,          0x18000 }, /* 0xe3428000 */
+       { TARGET_SD_CMU +  4,          0x20000 }, /* 0xe3430000 */
+       { TARGET_SD_CMU +  5,          0x28000 }, /* 0xe3438000 */
+       { TARGET_SD_CMU_CFG,           0x30000 }, /* 0xe3440000 */
+       { TARGET_SD_CMU_CFG +  1,      0x38000 }, /* 0xe3448000 */
+       { TARGET_SD_CMU_CFG +  2,      0x40000 }, /* 0xe3450000 */
+       { TARGET_SD_CMU_CFG +  3,      0x48000 }, /* 0xe3458000 */
+       { TARGET_SD_CMU_CFG +  4,      0x50000 }, /* 0xe3460000 */
+       { TARGET_SD_CMU_CFG +  5,      0x58000 }, /* 0xe3468000 */
+       { TARGET_SD10G_LANE,           0x60000 }, /* 0xe3470000 */
+       { TARGET_SD10G_LANE +  1,      0x68000 }, /* 0xe3478000 */
+       { TARGET_SD10G_LANE +  2,      0x70000 }, /* 0xe3480000 */
+       { TARGET_SD10G_LANE +  3,      0x78000 }, /* 0xe3488000 */
+       { TARGET_SD10G_LANE +  4,      0x80000 }, /* 0xe3490000 */
+       { TARGET_SD10G_LANE +  5,      0x88000 }, /* 0xe3498000 */
+       { TARGET_SD10G_LANE +  6,      0x90000 }, /* 0xe34a0000 */
+       { TARGET_SD10G_LANE +  7,      0x98000 }, /* 0xe34a8000 */
+       { TARGET_SD10G_LANE +  8,      0xa0000 }, /* 0xe34b0000 */
+       { TARGET_SD10G_LANE +  9,      0xa8000 }, /* 0xe34b8000 */
+       { TARGET_SD_LANE,             0x100000 }, /* 0xe3510000 */
+       { TARGET_SD_LANE +  1,        0x108000 }, /* 0xe3518000 */
+       { TARGET_SD_LANE +  2,        0x110000 }, /* 0xe3520000 */
+       { TARGET_SD_LANE +  3,        0x118000 }, /* 0xe3528000 */
+       { TARGET_SD_LANE +  4,        0x120000 }, /* 0xe3530000 */
+       { TARGET_SD_LANE +  5,        0x128000 }, /* 0xe3538000 */
+       { TARGET_SD_LANE +  6,        0x130000 }, /* 0xe3540000 */
+       { TARGET_SD_LANE +  7,        0x138000 }, /* 0xe3548000 */
+       { TARGET_SD_LANE +  8,        0x140000 }, /* 0xe3550000 */
+       { TARGET_SD_LANE +  9,        0x148000 }, /* 0xe3558000 */
+};
+
 static const struct sparx5_serdes_match_data sparx5_desc = {
        .type = SPX5_TARGET_SPARX5,
        .iomap = sparx5_serdes_iomap,
@@ -2534,6 +2606,21 @@ static const struct sparx5_serdes_match_data sparx5_desc = {
        },
 };
 
+static const struct sparx5_serdes_match_data lan969x_desc = {
+       .type = SPX5_TARGET_LAN969X,
+       .iomap = lan969x_serdes_iomap,
+       .iomap_size = ARRAY_SIZE(lan969x_serdes_iomap),
+       .tsize = lan969x_serdes_tsize,
+       .consts = {
+               .sd_max       = 10,
+               .cmu_max      = 6,
+       },
+       .ops = {
+               .serdes_type_set      = &lan969x_serdes_type_set,
+               .serdes_cmu_get       = &lan969x_serdes_cmu_get,
+       }
+};
+
 /* Client lookup function, uses serdes index */
 static struct phy *sparx5_serdes_xlate(struct device *dev,
                                     const struct of_phandle_args *args)
@@ -2635,6 +2722,7 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
 
 static const struct of_device_id sparx5_serdes_match[] = {
        { .compatible = "microchip,sparx5-serdes", .data = &sparx5_desc },
+       { .compatible = "microchip,lan9691-serdes", .data = &lan969x_desc },
        { }
 };
 MODULE_DEVICE_TABLE(of, sparx5_serdes_match);
index 1beaa3d05a5d528653f311f4ed5e4f24a5d1fcfc..d7093d0b09c0ca743a8140910a198bc816129156 100644 (file)
@@ -36,6 +36,8 @@ enum sparx5_10g28cmu_mode {
 
 enum sparx5_target {
        SPX5_TARGET_SPARX5,
+       SPX5_TARGET_LAN969X,
+
 };
 
 struct sparx5_serdes_macro {
This page took 0.053135 seconds and 4 git commands to generate.