Skip to content

Commit c0a0a7a

Browse files
Danielmachonvinodkoul
authored andcommitted
phy: lan969x-serdes: add support for lan969x serdes driver
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>
1 parent c569905 commit c0a0a7a

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

drivers/phy/microchip/sparx5_serdes.c

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#define SPX5_SERDES_25G_START 25
2626
#define SPX5_SERDES_6G10G_CNT SPX5_SERDES_25G_START
2727

28+
#define LAN969X_SERDES_10G_CNT 10
29+
2830
/* Optimal power settings from GUC */
2931
#define SPX5_SERDES_QUIET_MODE_VAL 0x01ef4e0c
3032

@@ -36,6 +38,13 @@ const unsigned int sparx5_serdes_tsize[TSIZE_LAST] = {
3638
[TC_SD_LANE] = 25,
3739
};
3840

41+
const unsigned int lan969x_serdes_tsize[TSIZE_LAST] = {
42+
[TC_SD10G_LANE] = 10,
43+
[TC_SD_CMU] = 6,
44+
[TC_SD_CMU_CFG] = 6,
45+
[TC_SD_LANE] = 10,
46+
};
47+
3948
/* Pointer to the register target size table */
4049
const unsigned int *tsize;
4150

@@ -1096,6 +1105,24 @@ static int sparx5_serdes_cmu_get(enum sparx5_10g28cmu_mode mode, int sd_index)
10961105
return sparx5_serdes_cmu_map[mode][sd_index];
10971106
}
10981107

1108+
/* Map of 6G/10G serdes mode and index to CMU index. */
1109+
static const int
1110+
lan969x_serdes_cmu_map[SPX5_SD10G28_CMU_MAX][LAN969X_SERDES_10G_CNT] = {
1111+
[SPX5_SD10G28_CMU_MAIN] = { 2, 2, 2, 2, 2,
1112+
2, 2, 2, 5, 5 },
1113+
[SPX5_SD10G28_CMU_AUX1] = { 0, 0, 3, 3, 3,
1114+
3, 3, 3, 3, 3 },
1115+
[SPX5_SD10G28_CMU_AUX2] = { 1, 1, 1, 1, 4,
1116+
4, 4, 4, 4, 4 },
1117+
[SPX5_SD10G28_CMU_NONE] = { 1, 1, 1, 1, 4,
1118+
4, 4, 4, 4, 4 },
1119+
};
1120+
1121+
static int lan969x_serdes_cmu_get(enum sparx5_10g28cmu_mode mode, int sd_index)
1122+
{
1123+
return lan969x_serdes_cmu_map[mode][sd_index];
1124+
}
1125+
10991126
static void sparx5_serdes_cmu_power_off(struct sparx5_serdes_private *priv)
11001127
{
11011128
void __iomem *cmu_inst, *cmu_cfg_inst;
@@ -2184,6 +2211,10 @@ static int sparx5_serdes_clock_config(struct sparx5_serdes_macro *macro)
21842211
{
21852212
struct sparx5_serdes_private *priv = macro->priv;
21862213

2214+
/* Clock is auto-detected in 100Base-FX mode on lan969x */
2215+
if (priv->data->type == SPX5_TARGET_LAN969X)
2216+
return 0;
2217+
21872218
if (macro->serdesmode == SPX5_SD_MODE_100FX) {
21882219
u32 freq = priv->coreclock == 250000000 ? 2 :
21892220
priv->coreclock == 500000000 ? 1 : 0;
@@ -2395,6 +2426,12 @@ static void sparx5_serdes_type_set(struct sparx5_serdes_macro *macro, int sidx)
23952426
}
23962427
}
23972428

2429+
static void lan969x_serdes_type_set(struct sparx5_serdes_macro *macro, int sidx)
2430+
{
2431+
macro->serdestype = SPX5_SDT_10G;
2432+
macro->stpidx = macro->sidx;
2433+
}
2434+
23982435
static int sparx5_phy_create(struct sparx5_serdes_private *priv,
23992436
int idx, struct phy **phy)
24002437
{
@@ -2519,6 +2556,41 @@ static struct sparx5_serdes_io_resource sparx5_serdes_iomap[] = {
25192556
{ TARGET_SD_LANE_25G + 7, 0x5c8000 }, /* 0x610dd0000: sd_lane_25g_32 */
25202557
};
25212558

2559+
static const struct sparx5_serdes_io_resource lan969x_serdes_iomap[] = {
2560+
{ TARGET_SD_CMU, 0x0 }, /* 0xe3410000 */
2561+
{ TARGET_SD_CMU + 1, 0x8000 }, /* 0xe3418000 */
2562+
{ TARGET_SD_CMU + 2, 0x10000 }, /* 0xe3420000 */
2563+
{ TARGET_SD_CMU + 3, 0x18000 }, /* 0xe3428000 */
2564+
{ TARGET_SD_CMU + 4, 0x20000 }, /* 0xe3430000 */
2565+
{ TARGET_SD_CMU + 5, 0x28000 }, /* 0xe3438000 */
2566+
{ TARGET_SD_CMU_CFG, 0x30000 }, /* 0xe3440000 */
2567+
{ TARGET_SD_CMU_CFG + 1, 0x38000 }, /* 0xe3448000 */
2568+
{ TARGET_SD_CMU_CFG + 2, 0x40000 }, /* 0xe3450000 */
2569+
{ TARGET_SD_CMU_CFG + 3, 0x48000 }, /* 0xe3458000 */
2570+
{ TARGET_SD_CMU_CFG + 4, 0x50000 }, /* 0xe3460000 */
2571+
{ TARGET_SD_CMU_CFG + 5, 0x58000 }, /* 0xe3468000 */
2572+
{ TARGET_SD10G_LANE, 0x60000 }, /* 0xe3470000 */
2573+
{ TARGET_SD10G_LANE + 1, 0x68000 }, /* 0xe3478000 */
2574+
{ TARGET_SD10G_LANE + 2, 0x70000 }, /* 0xe3480000 */
2575+
{ TARGET_SD10G_LANE + 3, 0x78000 }, /* 0xe3488000 */
2576+
{ TARGET_SD10G_LANE + 4, 0x80000 }, /* 0xe3490000 */
2577+
{ TARGET_SD10G_LANE + 5, 0x88000 }, /* 0xe3498000 */
2578+
{ TARGET_SD10G_LANE + 6, 0x90000 }, /* 0xe34a0000 */
2579+
{ TARGET_SD10G_LANE + 7, 0x98000 }, /* 0xe34a8000 */
2580+
{ TARGET_SD10G_LANE + 8, 0xa0000 }, /* 0xe34b0000 */
2581+
{ TARGET_SD10G_LANE + 9, 0xa8000 }, /* 0xe34b8000 */
2582+
{ TARGET_SD_LANE, 0x100000 }, /* 0xe3510000 */
2583+
{ TARGET_SD_LANE + 1, 0x108000 }, /* 0xe3518000 */
2584+
{ TARGET_SD_LANE + 2, 0x110000 }, /* 0xe3520000 */
2585+
{ TARGET_SD_LANE + 3, 0x118000 }, /* 0xe3528000 */
2586+
{ TARGET_SD_LANE + 4, 0x120000 }, /* 0xe3530000 */
2587+
{ TARGET_SD_LANE + 5, 0x128000 }, /* 0xe3538000 */
2588+
{ TARGET_SD_LANE + 6, 0x130000 }, /* 0xe3540000 */
2589+
{ TARGET_SD_LANE + 7, 0x138000 }, /* 0xe3548000 */
2590+
{ TARGET_SD_LANE + 8, 0x140000 }, /* 0xe3550000 */
2591+
{ TARGET_SD_LANE + 9, 0x148000 }, /* 0xe3558000 */
2592+
};
2593+
25222594
static const struct sparx5_serdes_match_data sparx5_desc = {
25232595
.type = SPX5_TARGET_SPARX5,
25242596
.iomap = sparx5_serdes_iomap,
@@ -2534,6 +2606,21 @@ static const struct sparx5_serdes_match_data sparx5_desc = {
25342606
},
25352607
};
25362608

2609+
static const struct sparx5_serdes_match_data lan969x_desc = {
2610+
.type = SPX5_TARGET_LAN969X,
2611+
.iomap = lan969x_serdes_iomap,
2612+
.iomap_size = ARRAY_SIZE(lan969x_serdes_iomap),
2613+
.tsize = lan969x_serdes_tsize,
2614+
.consts = {
2615+
.sd_max = 10,
2616+
.cmu_max = 6,
2617+
},
2618+
.ops = {
2619+
.serdes_type_set = &lan969x_serdes_type_set,
2620+
.serdes_cmu_get = &lan969x_serdes_cmu_get,
2621+
}
2622+
};
2623+
25372624
/* Client lookup function, uses serdes index */
25382625
static struct phy *sparx5_serdes_xlate(struct device *dev,
25392626
const struct of_phandle_args *args)
@@ -2635,6 +2722,7 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
26352722

26362723
static const struct of_device_id sparx5_serdes_match[] = {
26372724
{ .compatible = "microchip,sparx5-serdes", .data = &sparx5_desc },
2725+
{ .compatible = "microchip,lan9691-serdes", .data = &lan969x_desc },
26382726
{ }
26392727
};
26402728
MODULE_DEVICE_TABLE(of, sparx5_serdes_match);

drivers/phy/microchip/sparx5_serdes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ enum sparx5_10g28cmu_mode {
3636

3737
enum sparx5_target {
3838
SPX5_TARGET_SPARX5,
39+
SPX5_TARGET_LAN969X,
40+
3941
};
4042

4143
struct sparx5_serdes_macro {

0 commit comments

Comments
 (0)