Skip to content

Commit

Permalink
phy: lan969x-serdes: add support for lan969x serdes driver
Browse files Browse the repository at this point in the history
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 <daniel.machon@microchip.com>
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
Link: https://lore.kernel.org/r/20240909-sparx5-lan969x-serdes-driver-v2-9-d695bcb57b84@microchip.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
  • Loading branch information
Daniel Machon authored and Vinod Koul committed Oct 21, 2024
1 parent c569905 commit c0a0a7a
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 0 deletions.
88 changes: 88 additions & 0 deletions drivers/phy/microchip/sparx5_serdes.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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,
Expand All @@ -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)
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions drivers/phy/microchip/sparx5_serdes.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ enum sparx5_10g28cmu_mode {

enum sparx5_target {
SPX5_TARGET_SPARX5,
SPX5_TARGET_LAN969X,

};

struct sparx5_serdes_macro {
Expand Down

0 comments on commit c0a0a7a

Please sign in to comment.