From 28ba10074bc9ede42bdc3f717d1c6b1f85a6790d Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Wed, 5 Oct 2022 13:51:30 -0700 Subject: [PATCH] phy: ti: j721e-wiz: add j784s4-wiz-10g module support Add support for j784s4-wiz-10g device which has two core reference clocks (e.g core_ref_clk, core_ref1_clk) which requires an additional mux selection option. Signed-off-by: Matt Ranostay --- drivers/phy/ti/phy-j721e-wiz.c | 75 ++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 3 deletions(-) diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c index fb6b6cf3ff..6646b15d41 100644 --- a/drivers/phy/ti/phy-j721e-wiz.c +++ b/drivers/phy/ti/phy-j721e-wiz.c @@ -69,14 +69,20 @@ static const struct reg_field por_en = REG_FIELD(WIZ_SERDES_CTRL, 31, 31); static const struct reg_field phy_reset_n = REG_FIELD(WIZ_SERDES_RST, 31, 31); static const struct reg_field pll1_refclk_mux_sel = REG_FIELD(WIZ_SERDES_RST, 29, 29); +static const struct reg_field pll1_refclk_mux_sel_2 = + REG_FIELD(WIZ_SERDES_RST, 22, 23); static const struct reg_field pll0_refclk_mux_sel = REG_FIELD(WIZ_SERDES_RST, 28, 28); +static const struct reg_field pll0_refclk_mux_sel_2 = + REG_FIELD(WIZ_SERDES_RST, 28, 29); static const struct reg_field refclk_dig_sel_16g = REG_FIELD(WIZ_SERDES_RST, 24, 25); static const struct reg_field refclk_dig_sel_10g = REG_FIELD(WIZ_SERDES_RST, 24, 24); static const struct reg_field pma_cmn_refclk_int_mode = REG_FIELD(WIZ_SERDES_TOP_CTRL, 28, 29); +static const struct reg_field pma_cmn_refclk1_int_mode = + REG_FIELD(WIZ_SERDES_TOP_CTRL, 20, 21); static const struct reg_field pma_cmn_refclk_mode = REG_FIELD(WIZ_SERDES_TOP_CTRL, 30, 31); static const struct reg_field pma_cmn_refclk_dig_div = @@ -204,6 +210,27 @@ static struct wiz_clk_mux_sel clk_mux_sel_10g[] = { }, }; +static const struct wiz_clk_mux_sel clk_mux_sel_10g_2_refclk[] = { + { + .num_parents = 3, + .parents = { WIZ_CORE_REFCLK, WIZ_CORE_REFCLK1, WIZ_EXT_REFCLK }, + .table = { 2, 3, 0 }, + .node_name = "pll0-refclk", + }, + { + .num_parents = 3, + .parents = { WIZ_CORE_REFCLK, WIZ_CORE_REFCLK1, WIZ_EXT_REFCLK }, + .table = { 2, 3, 0 }, + .node_name = "pll1-refclk", + }, + { + .num_parents = 3, + .parents = { WIZ_CORE_REFCLK, WIZ_CORE_REFCLK1, WIZ_EXT_REFCLK }, + .table = { 2, 3, 0 }, + .node_name = "refclk-dig", + }, +}; + static struct wiz_clk_div_sel clk_div_sel[] = { { .div_sel = CMN_REFCLK, @@ -219,6 +246,7 @@ enum wiz_type { J721E_WIZ_16G, J721E_WIZ_10G, AM64_WIZ_10G, + J784S4_WIZ_10G, }; struct wiz_data { @@ -227,6 +255,7 @@ struct wiz_data { const struct reg_field *pll1_refclk_mux_sel; const struct reg_field *refclk_dig_sel; const struct reg_field *pma_cmn_refclk1_dig_div; + const struct reg_field *pma_cmn_refclk1_int_mode; const struct wiz_clk_mux_sel *clk_mux_sel; unsigned int clk_div_sel_num; }; @@ -259,6 +288,16 @@ static struct wiz_data am64_10g_data = { .clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_10G, }; +static struct wiz_data j784s4_wiz_10g = { + .type = J784S4_WIZ_10G, + .pll0_refclk_mux_sel = &pll0_refclk_mux_sel_2, + .pll1_refclk_mux_sel = &pll1_refclk_mux_sel_2, + .refclk_dig_sel = &refclk_dig_sel_16g, + .pma_cmn_refclk1_int_mode = &pma_cmn_refclk1_int_mode, + .clk_mux_sel = clk_mux_sel_10g_2_refclk, + .clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_10G, +}; + #define WIZ_TYPEC_DIR_DEBOUNCE_MIN 100 /* ms */ #define WIZ_TYPEC_DIR_DEBOUNCE_MAX 1000 @@ -279,6 +318,7 @@ struct wiz { struct regmap_field *p_mac_div_sel1[WIZ_MAX_LANES]; struct regmap_field *p0_fullrt_div[WIZ_MAX_LANES]; struct regmap_field *pma_cmn_refclk_int_mode; + struct regmap_field *pma_cmn_refclk1_int_mode; struct regmap_field *pma_cmn_refclk_mode; struct regmap_field *pma_cmn_refclk_dig_div; struct regmap_field *pma_cmn_refclk1_dig_div; @@ -729,6 +769,15 @@ static int wiz_regfield_init(struct wiz *wiz) return PTR_ERR(wiz->pma_cmn_refclk_int_mode); } + if (data->pma_cmn_refclk1_int_mode) { + wiz->pma_cmn_refclk1_int_mode = + devm_regmap_field_alloc(dev, regmap, *data->pma_cmn_refclk1_int_mode); + if (IS_ERR(wiz->pma_cmn_refclk1_int_mode)) { + dev_err(dev, "PMA_CMN_REFCLK1_INT_MODE reg field init failed\n"); + return PTR_ERR(wiz->pma_cmn_refclk1_int_mode); + } + } + wiz->pma_cmn_refclk_mode = devm_regmap_field_alloc(dev, regmap, pma_cmn_refclk_mode); if (IS_ERR(wiz->pma_cmn_refclk_mode)) { @@ -844,8 +893,6 @@ static int wiz_clock_init(struct wiz *wiz) return ret; } wiz->input_clks[WIZ_CORE_REFCLK] = clk; - /* Initialize CORE_REFCLK1 to the same clock reference to maintain old DT compatibility */ - wiz->input_clks[WIZ_CORE_REFCLK1] = clk; rate = clk_get_rate(clk); if (rate >= 100000000) @@ -853,6 +900,25 @@ static int wiz_clock_init(struct wiz *wiz) else regmap_field_write(wiz->pma_cmn_refclk_int_mode, 0x3); + if (wiz->data->pma_cmn_refclk1_int_mode) { + clk = devm_clk_get(dev, "core_ref1_clk"); + if (IS_ERR(clk)) { + dev_err(dev, "core_ref1_clk clock not found\n"); + ret = PTR_ERR(clk); + return ret; + } + wiz->input_clks[WIZ_CORE_REFCLK1] = clk; + + rate = clk_get_rate(clk); + if (rate >= 100000000) + regmap_field_write(wiz->pma_cmn_refclk1_int_mode, 0x1); + else + regmap_field_write(wiz->pma_cmn_refclk1_int_mode, 0x3); + } else { + /* Initialize CORE_REFCLK1 to the same clock reference to maintain old DT compatibility */ + wiz->input_clks[WIZ_CORE_REFCLK1] = clk; + } + clk = devm_clk_get(dev, "ext_ref_clk"); if (IS_ERR(clk)) { dev_err(dev, "ext_ref_clk clock not found\n"); @@ -933,7 +999,7 @@ static int j721e_wiz_bind_of_clocks(struct wiz *wiz) ofnode node; int i, rc; - if (type == AM64_WIZ_10G) + if (type == AM64_WIZ_10G || type == J784S4_WIZ_10G) return j721e_wiz_bind_clocks(wiz); div_clk_drv = lists_driver_lookup_name("wiz_div_clk"); @@ -1173,6 +1239,9 @@ static const struct udevice_id j721e_wiz_ids[] = { { .compatible = "ti,am64-wiz-10g", .data = (ulong)&am64_10g_data, }, + { + .compatible = "ti,j784s4-wiz-10g", .data = (ulong)&j784s4_wiz_10g, + }, {} }; -- 2.39.5