Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

phy: ti: phy-j721e-wiz: add support for j7200-wiz-10g

j7200-wiz-10g supports 2 reference clocks. However, the
control bits for these clocks is in a separate register that
sits in the System Control register space. Handle that register.

Signed-off-by: Roger Quadros <rogerq@kernel.org>
Link: https://lore.kernel.org/r/20220628122255.24265-7-rogerq@kernel.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Roger Quadros and committed by
Vinod Koul
edd473d4 d5f2e747

+129 -9
+129 -9
drivers/phy/ti/phy-j721e-wiz.c
··· 15 15 #include <linux/gpio/consumer.h> 16 16 #include <linux/io.h> 17 17 #include <linux/module.h> 18 + #include <linux/mfd/syscon.h> 18 19 #include <linux/mux/consumer.h> 19 20 #include <linux/of_address.h> 20 21 #include <linux/of_platform.h> ··· 24 23 #include <linux/regmap.h> 25 24 #include <linux/reset-controller.h> 26 25 26 + /* SCM offsets */ 27 + #define SERDES_SUP_CTRL 0x4400 28 + 29 + /* SERDES offsets */ 27 30 #define WIZ_SERDES_CTRL 0x404 28 31 #define WIZ_SERDES_TOP_CTRL 0x408 29 32 #define WIZ_SERDES_RST 0x40c ··· 90 85 REG_FIELD(WIZ_SERDES_TOP_CTRL, 26, 27); 91 86 static const struct reg_field pma_cmn_refclk1_dig_div = 92 87 REG_FIELD(WIZ_SERDES_TOP_CTRL, 24, 25); 88 + 89 + static const struct reg_field sup_pll0_refclk_mux_sel = 90 + REG_FIELD(SERDES_SUP_CTRL, 0, 1); 91 + static const struct reg_field sup_pll1_refclk_mux_sel = 92 + REG_FIELD(SERDES_SUP_CTRL, 2, 3); 93 + static const struct reg_field sup_pma_cmn_refclk1_int_mode = 94 + REG_FIELD(SERDES_SUP_CTRL, 4, 5); 95 + static const struct reg_field sup_refclk_dig_sel_10g = 96 + REG_FIELD(SERDES_SUP_CTRL, 6, 7); 97 + static const struct reg_field sup_legacy_clk_override = 98 + REG_FIELD(SERDES_SUP_CTRL, 8, 8); 99 + 93 100 static const char * const output_clk_names[] = { 94 101 [TI_WIZ_PLL0_REFCLK] = "pll0-refclk", 95 102 [TI_WIZ_PLL1_REFCLK] = "pll1-refclk", ··· 265 248 }, 266 249 }; 267 250 251 + static const struct wiz_clk_mux_sel clk_mux_sel_10g_2_refclk[] = { 252 + { 253 + .num_parents = 3, 254 + .parents = { WIZ_CORE_REFCLK, WIZ_CORE_REFCLK1, WIZ_EXT_REFCLK }, 255 + .table = { 2, 3, 0 }, 256 + .node_name = "pll0-refclk", 257 + }, 258 + { 259 + .num_parents = 3, 260 + .parents = { WIZ_CORE_REFCLK, WIZ_CORE_REFCLK1, WIZ_EXT_REFCLK }, 261 + .table = { 2, 3, 0 }, 262 + .node_name = "pll1-refclk", 263 + }, 264 + { 265 + .num_parents = 3, 266 + .parents = { WIZ_CORE_REFCLK, WIZ_CORE_REFCLK1, WIZ_EXT_REFCLK }, 267 + .table = { 2, 3, 0 }, 268 + .node_name = "refclk-dig", 269 + }, 270 + }; 271 + 268 272 static const struct clk_div_table clk_div_table[] = { 269 273 { .val = 0, .div = 1, }, 270 274 { .val = 1, .div = 2, }, ··· 307 269 308 270 enum wiz_type { 309 271 J721E_WIZ_16G, 310 - J721E_WIZ_10G, 272 + J721E_WIZ_10G, /* Also for J7200 SR1.0 */ 311 273 AM64_WIZ_10G, 274 + J7200_WIZ_10G, /* J7200 SR2.0 */ 312 275 }; 313 276 314 277 struct wiz_data { 315 278 enum wiz_type type; 279 + const struct reg_field *pll0_refclk_mux_sel; 280 + const struct reg_field *pll1_refclk_mux_sel; 316 281 const struct reg_field *refclk_dig_sel; 317 282 const struct reg_field *pma_cmn_refclk1_dig_div; 283 + const struct reg_field *pma_cmn_refclk1_int_mode; 318 284 const struct wiz_clk_mux_sel *clk_mux_sel; 319 285 unsigned int clk_div_sel_num; 320 286 }; ··· 328 286 329 287 struct wiz { 330 288 struct regmap *regmap; 289 + struct regmap *scm_regmap; 331 290 enum wiz_type type; 332 291 const struct wiz_clk_mux_sel *clk_mux_sel; 333 292 const struct wiz_clk_div_sel *clk_div_sel; ··· 347 304 struct regmap_field *p0_rxfclk_sel[WIZ_MAX_LANES]; 348 305 struct regmap_field *p0_refclk_sel[WIZ_MAX_LANES]; 349 306 struct regmap_field *pma_cmn_refclk_int_mode; 307 + struct regmap_field *pma_cmn_refclk1_int_mode; 350 308 struct regmap_field *pma_cmn_refclk_mode; 351 309 struct regmap_field *pma_cmn_refclk_dig_div; 352 310 struct regmap_field *pma_cmn_refclk1_dig_div; 353 311 struct regmap_field *mux_sel_field[WIZ_MUX_NUM_CLOCKS]; 354 312 struct regmap_field *div_sel_field[WIZ_DIV_NUM_CLOCKS_16G]; 355 313 struct regmap_field *typec_ln10_swap; 314 + struct regmap_field *sup_legacy_clk_override; 356 315 357 316 struct device *dev; 358 317 u32 num_lanes; ··· 493 448 static int wiz_regfield_init(struct wiz *wiz) 494 449 { 495 450 struct regmap *regmap = wiz->regmap; 451 + struct regmap *scm_regmap = wiz->regmap; /* updated later to scm_regmap if applicable */ 496 452 int num_lanes = wiz->num_lanes; 497 453 struct device *dev = wiz->dev; 498 454 const struct wiz_data *data = wiz->data; ··· 543 497 } 544 498 } 545 499 500 + if (wiz->scm_regmap) { 501 + scm_regmap = wiz->scm_regmap; 502 + wiz->sup_legacy_clk_override = 503 + devm_regmap_field_alloc(dev, scm_regmap, sup_legacy_clk_override); 504 + if (IS_ERR(wiz->sup_legacy_clk_override)) { 505 + dev_err(dev, "SUP_LEGACY_CLK_OVERRIDE reg field init failed\n"); 506 + return PTR_ERR(wiz->sup_legacy_clk_override); 507 + } 508 + } 509 + 546 510 wiz->mux_sel_field[PLL0_REFCLK] = 547 - devm_regmap_field_alloc(dev, regmap, pll0_refclk_mux_sel); 511 + devm_regmap_field_alloc(dev, scm_regmap, *data->pll0_refclk_mux_sel); 548 512 if (IS_ERR(wiz->mux_sel_field[PLL0_REFCLK])) { 549 513 dev_err(dev, "PLL0_REFCLK_SEL reg field init failed\n"); 550 514 return PTR_ERR(wiz->mux_sel_field[PLL0_REFCLK]); 551 515 } 552 516 553 517 wiz->mux_sel_field[PLL1_REFCLK] = 554 - devm_regmap_field_alloc(dev, regmap, pll1_refclk_mux_sel); 518 + devm_regmap_field_alloc(dev, scm_regmap, *data->pll1_refclk_mux_sel); 555 519 if (IS_ERR(wiz->mux_sel_field[PLL1_REFCLK])) { 556 520 dev_err(dev, "PLL1_REFCLK_SEL reg field init failed\n"); 557 521 return PTR_ERR(wiz->mux_sel_field[PLL1_REFCLK]); 558 522 } 559 523 560 - wiz->mux_sel_field[REFCLK_DIG] = devm_regmap_field_alloc(dev, regmap, 524 + wiz->mux_sel_field[REFCLK_DIG] = devm_regmap_field_alloc(dev, scm_regmap, 561 525 *data->refclk_dig_sel); 562 526 if (IS_ERR(wiz->mux_sel_field[REFCLK_DIG])) { 563 527 dev_err(dev, "REFCLK_DIG_SEL reg field init failed\n"); 564 528 return PTR_ERR(wiz->mux_sel_field[REFCLK_DIG]); 529 + } 530 + 531 + if (data->pma_cmn_refclk1_int_mode) { 532 + wiz->pma_cmn_refclk1_int_mode = 533 + devm_regmap_field_alloc(dev, scm_regmap, *data->pma_cmn_refclk1_int_mode); 534 + if (IS_ERR(wiz->pma_cmn_refclk1_int_mode)) { 535 + dev_err(dev, "PMA_CMN_REFCLK1_INT_MODE reg field init failed\n"); 536 + return PTR_ERR(wiz->pma_cmn_refclk1_int_mode); 537 + } 565 538 } 566 539 567 540 for (i = 0; i < num_lanes; i++) { ··· 971 906 struct device_node *clk_node; 972 907 int i; 973 908 974 - if (wiz->type == AM64_WIZ_10G) { 909 + switch (wiz->type) { 910 + case AM64_WIZ_10G: 911 + case J7200_WIZ_10G: 975 912 of_clk_del_provider(dev->of_node); 976 913 return; 914 + default: 915 + break; 977 916 } 978 917 979 918 for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) { ··· 1003 934 int clk_index; 1004 935 int ret; 1005 936 int i; 1006 - 1007 - if (wiz->type != AM64_WIZ_10G) 1008 - return 0; 1009 937 1010 938 clk_index = TI_WIZ_PLL0_REFCLK; 1011 939 for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++, clk_index++) { ··· 1053 987 else 1054 988 regmap_field_write(wiz->pma_cmn_refclk_int_mode, 0x3); 1055 989 990 + if (wiz->data->pma_cmn_refclk1_int_mode) { 991 + clk = devm_clk_get(dev, "core_ref1_clk"); 992 + if (IS_ERR(clk)) { 993 + dev_err(dev, "core_ref1_clk clock not found\n"); 994 + ret = PTR_ERR(clk); 995 + return ret; 996 + } 997 + wiz->input_clks[WIZ_CORE_REFCLK1] = clk; 998 + 999 + rate = clk_get_rate(clk); 1000 + if (rate >= 100000000) 1001 + regmap_field_write(wiz->pma_cmn_refclk1_int_mode, 0x1); 1002 + else 1003 + regmap_field_write(wiz->pma_cmn_refclk1_int_mode, 0x3); 1004 + } 1005 + 1056 1006 clk = devm_clk_get(dev, "ext_ref_clk"); 1057 1007 if (IS_ERR(clk)) { 1058 1008 dev_err(dev, "ext_ref_clk clock not found\n"); ··· 1083 1001 else 1084 1002 regmap_field_write(wiz->pma_cmn_refclk_mode, 0x2); 1085 1003 1086 - if (wiz->type == AM64_WIZ_10G) { 1004 + switch (wiz->type) { 1005 + case AM64_WIZ_10G: 1006 + case J7200_WIZ_10G: 1087 1007 ret = wiz_clock_register(wiz); 1088 1008 if (ret) 1089 1009 dev_err(dev, "Failed to register wiz clocks\n"); 1090 1010 return ret; 1011 + default: 1012 + break; 1091 1013 } 1092 1014 1093 1015 for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) { ··· 1167 1081 return regmap_field_write(wiz->p0_fullrt_div[lane], 0x1); 1168 1082 break; 1169 1083 case J721E_WIZ_10G: 1084 + case J7200_WIZ_10G: 1170 1085 if (wiz->lane_phy_type[lane] == PHY_TYPE_SGMII) 1171 1086 return regmap_field_write(wiz->p0_fullrt_div[lane], 0x2); 1172 1087 break; ··· 1226 1139 1227 1140 static struct wiz_data j721e_16g_data = { 1228 1141 .type = J721E_WIZ_16G, 1142 + .pll0_refclk_mux_sel = &pll0_refclk_mux_sel, 1143 + .pll1_refclk_mux_sel = &pll1_refclk_mux_sel, 1229 1144 .refclk_dig_sel = &refclk_dig_sel_16g, 1230 1145 .pma_cmn_refclk1_dig_div = &pma_cmn_refclk1_dig_div, 1231 1146 .clk_mux_sel = clk_mux_sel_16g, ··· 1236 1147 1237 1148 static struct wiz_data j721e_10g_data = { 1238 1149 .type = J721E_WIZ_10G, 1150 + .pll0_refclk_mux_sel = &pll0_refclk_mux_sel, 1151 + .pll1_refclk_mux_sel = &pll1_refclk_mux_sel, 1239 1152 .refclk_dig_sel = &refclk_dig_sel_10g, 1240 1153 .clk_mux_sel = clk_mux_sel_10g, 1241 1154 .clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_10G, ··· 1245 1154 1246 1155 static struct wiz_data am64_10g_data = { 1247 1156 .type = AM64_WIZ_10G, 1157 + .pll0_refclk_mux_sel = &pll0_refclk_mux_sel, 1158 + .pll1_refclk_mux_sel = &pll1_refclk_mux_sel, 1248 1159 .refclk_dig_sel = &refclk_dig_sel_10g, 1249 1160 .clk_mux_sel = clk_mux_sel_10g, 1161 + .clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_10G, 1162 + }; 1163 + 1164 + static struct wiz_data j7200_pg2_10g_data = { 1165 + .type = J7200_WIZ_10G, 1166 + .pll0_refclk_mux_sel = &sup_pll0_refclk_mux_sel, 1167 + .pll1_refclk_mux_sel = &sup_pll1_refclk_mux_sel, 1168 + .refclk_dig_sel = &sup_refclk_dig_sel_10g, 1169 + .pma_cmn_refclk1_int_mode = &sup_pma_cmn_refclk1_int_mode, 1170 + .clk_mux_sel = clk_mux_sel_10g_2_refclk, 1250 1171 .clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_10G, 1251 1172 }; 1252 1173 ··· 1271 1168 }, 1272 1169 { 1273 1170 .compatible = "ti,am64-wiz-10g", .data = &am64_10g_data, 1171 + }, 1172 + { 1173 + .compatible = "ti,j7200-wiz-10g", .data = &j7200_pg2_10g_data, 1274 1174 }, 1275 1175 {} 1276 1176 }; ··· 1372 1266 goto err_addr_to_resource; 1373 1267 } 1374 1268 1269 + wiz->scm_regmap = syscon_regmap_lookup_by_phandle(node, "ti,scm"); 1270 + if (IS_ERR(wiz->scm_regmap)) { 1271 + if (wiz->type == J7200_WIZ_10G) { 1272 + dev_err(dev, "Couldn't get ti,scm regmap\n"); 1273 + return -ENODEV; 1274 + } 1275 + 1276 + wiz->scm_regmap = NULL; 1277 + } 1278 + 1375 1279 ret = of_property_read_u32(node, "num-lanes", &num_lanes); 1376 1280 if (ret) { 1377 1281 dev_err(dev, "Failed to read num-lanes property\n"); ··· 1442 1326 dev_err(dev, "Failed to initialize regfields\n"); 1443 1327 goto err_addr_to_resource; 1444 1328 } 1329 + 1330 + /* Enable supplemental Control override if available */ 1331 + if (wiz->scm_regmap) 1332 + regmap_field_write(wiz->sup_legacy_clk_override, 1); 1445 1333 1446 1334 phy_reset_dev = &wiz->wiz_phy_reset_dev; 1447 1335 phy_reset_dev->dev = dev;