25
25
#define SPX5_SERDES_25G_START 25
26
26
#define SPX5_SERDES_6G10G_CNT SPX5_SERDES_25G_START
27
27
28
+ #define LAN969X_SERDES_10G_CNT 10
29
+
28
30
/* Optimal power settings from GUC */
29
31
#define SPX5_SERDES_QUIET_MODE_VAL 0x01ef4e0c
30
32
@@ -36,6 +38,13 @@ const unsigned int sparx5_serdes_tsize[TSIZE_LAST] = {
36
38
[TC_SD_LANE ] = 25 ,
37
39
};
38
40
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
+
39
48
/* Pointer to the register target size table */
40
49
const unsigned int * tsize ;
41
50
@@ -1096,6 +1105,24 @@ static int sparx5_serdes_cmu_get(enum sparx5_10g28cmu_mode mode, int sd_index)
1096
1105
return sparx5_serdes_cmu_map [mode ][sd_index ];
1097
1106
}
1098
1107
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
+
1099
1126
static void sparx5_serdes_cmu_power_off (struct sparx5_serdes_private * priv )
1100
1127
{
1101
1128
void __iomem * cmu_inst , * cmu_cfg_inst ;
@@ -2184,6 +2211,10 @@ static int sparx5_serdes_clock_config(struct sparx5_serdes_macro *macro)
2184
2211
{
2185
2212
struct sparx5_serdes_private * priv = macro -> priv ;
2186
2213
2214
+ /* Clock is auto-detected in 100Base-FX mode on lan969x */
2215
+ if (priv -> data -> type == SPX5_TARGET_LAN969X )
2216
+ return 0 ;
2217
+
2187
2218
if (macro -> serdesmode == SPX5_SD_MODE_100FX ) {
2188
2219
u32 freq = priv -> coreclock == 250000000 ? 2 :
2189
2220
priv -> coreclock == 500000000 ? 1 : 0 ;
@@ -2395,6 +2426,12 @@ static void sparx5_serdes_type_set(struct sparx5_serdes_macro *macro, int sidx)
2395
2426
}
2396
2427
}
2397
2428
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
+
2398
2435
static int sparx5_phy_create (struct sparx5_serdes_private * priv ,
2399
2436
int idx , struct phy * * phy )
2400
2437
{
@@ -2519,6 +2556,41 @@ static struct sparx5_serdes_io_resource sparx5_serdes_iomap[] = {
2519
2556
{ TARGET_SD_LANE_25G + 7 , 0x5c8000 }, /* 0x610dd0000: sd_lane_25g_32 */
2520
2557
};
2521
2558
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
+
2522
2594
static const struct sparx5_serdes_match_data sparx5_desc = {
2523
2595
.type = SPX5_TARGET_SPARX5 ,
2524
2596
.iomap = sparx5_serdes_iomap ,
@@ -2534,6 +2606,21 @@ static const struct sparx5_serdes_match_data sparx5_desc = {
2534
2606
},
2535
2607
};
2536
2608
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
+
2537
2624
/* Client lookup function, uses serdes index */
2538
2625
static struct phy * sparx5_serdes_xlate (struct device * dev ,
2539
2626
const struct of_phandle_args * args )
@@ -2635,6 +2722,7 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
2635
2722
2636
2723
static const struct of_device_id sparx5_serdes_match [] = {
2637
2724
{ .compatible = "microchip,sparx5-serdes" , .data = & sparx5_desc },
2725
+ { .compatible = "microchip,lan9691-serdes" , .data = & lan969x_desc },
2638
2726
{ }
2639
2727
};
2640
2728
MODULE_DEVICE_TABLE (of , sparx5_serdes_match );
0 commit comments