From patchwork Tue Jun 28 12:22:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roger Quadros X-Patchwork-Id: 12898193 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 20666C43334 for ; Tue, 28 Jun 2022 12:23:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=z6pw2Wj1HMxJM/Fx5t2x4d+ZK/mJxVDAzi1azx+mZ9M=; b=Xdm47dr8pUnOKE UakChqXy5HXV7FNYGM951KY8I52CzwS2v6BOPrhpm7s5Tn6CKBB1oW2sccv8sZhDYQREdVCE9s1iz 8k+46KSJNVmNn0xoyjVXwzFbdLDaQ8A+2TMfMdKWUuCG82sHMoUkvwjduMW8YZrB7g8SI7dLWw4Ks EivNRD99Q1Rk7EK709qHJz6UmwWepeRAaFLm/L0IABiRk3GTBUZ1mT1JSG7k2wQqGZCx+9vQ2VqLG 740zf8e8LNPhvx+MCUQmrTGPM2A2++6R3XfPYYQoZfF6XsuCgJJXKU3oS7LURbQwKxCt+x5pqTK8f RcwpnSPHDcdhtFBCC7Hg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1o6AFi-0069fn-Hk; Tue, 28 Jun 2022 12:23:34 +0000 Received: from ams.source.kernel.org ([2604:1380:4601:e00::1]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1o6AFf-0069dv-Nn for linux-phy@lists.infradead.org; Tue, 28 Jun 2022 12:23:33 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 1477DB81E04; Tue, 28 Jun 2022 12:23:30 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 657A5C341CC; Tue, 28 Jun 2022 12:23:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1656419008; bh=P7SAAWwCSzVlv2T9lWvUXnEH8devzfc90nldG8hymZU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ggl+R4ju6XZHFHZ0r+RjFHmBt3UGrTgx6aD9lYF3HVGfajARwqUF6blJDFx3twM71 Cg2ohyndHYbRv8ldihz0kEmV7CFiHCBiXW2bBMM4OYY5T8obPbImjHyfHERnSWOJ4H pLQ6hxUPsgCNxiyjf2ux+Zl3ssZY5ydzmOao6cM4dVCeg6F7gIIc5ZE2suFyrDqUe3 Z/L/3doCKxVguNRv7+Jj2hAOX2UkIemNlM6J+8bD5fNSHqq4oolJA99RZjM2ELH0Ps kvyfH5Bb4fWq/PEsZaf2UYEgK59R5ahKnniAZpScBCVOGHp5QtWCNZ2MlkUJ//L+OK j9AMpHceAp0zQ== From: Roger Quadros To: kishon@ti.com, vkoul@kernel.org Cc: vigneshr@ti.com, t-patil@ti.com, sjakhade@cadence.com, s-vadapalli@ti.com, linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Roger Quadros Subject: [PATCH 6/7] phy: ti: phy-j721e-wiz: add support for j7200-wiz-10g Date: Tue, 28 Jun 2022 15:22:54 +0300 Message-Id: <20220628122255.24265-7-rogerq@kernel.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220628122255.24265-1-rogerq@kernel.org> References: <20220628122255.24265-1-rogerq@kernel.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220628_052332_104007_4D6F6DFE X-CRM114-Status: GOOD ( 25.08 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org 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 --- drivers/phy/ti/phy-j721e-wiz.c | 138 ++++++++++++++++++++++++++++++--- 1 file changed, 129 insertions(+), 9 deletions(-) diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c index 77accea6ec2f..cc2ab5152f07 100644 --- a/drivers/phy/ti/phy-j721e-wiz.c +++ b/drivers/phy/ti/phy-j721e-wiz.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,10 @@ #include #include +/* SCM offsets */ +#define SERDES_SUP_CTRL 0x4400 + +/* SERDES offsets */ #define WIZ_SERDES_CTRL 0x404 #define WIZ_SERDES_TOP_CTRL 0x408 #define WIZ_SERDES_RST 0x40c @@ -85,6 +90,18 @@ static const struct reg_field pma_cmn_refclk_dig_div = REG_FIELD(WIZ_SERDES_TOP_CTRL, 26, 27); static const struct reg_field pma_cmn_refclk1_dig_div = REG_FIELD(WIZ_SERDES_TOP_CTRL, 24, 25); + +static const struct reg_field sup_pll0_refclk_mux_sel = + REG_FIELD(SERDES_SUP_CTRL, 0, 1); +static const struct reg_field sup_pll1_refclk_mux_sel = + REG_FIELD(SERDES_SUP_CTRL, 2, 3); +static const struct reg_field sup_pma_cmn_refclk1_int_mode = + REG_FIELD(SERDES_SUP_CTRL, 4, 5); +static const struct reg_field sup_refclk_dig_sel_10g = + REG_FIELD(SERDES_SUP_CTRL, 6, 7); +static const struct reg_field sup_legacy_clk_override = + REG_FIELD(SERDES_SUP_CTRL, 8, 8); + static const char * const output_clk_names[] = { [TI_WIZ_PLL0_REFCLK] = "pll0-refclk", [TI_WIZ_PLL1_REFCLK] = "pll1-refclk", @@ -248,6 +265,27 @@ static const 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 const struct clk_div_table clk_div_table[] = { { .val = 0, .div = 1, }, { .val = 1, .div = 2, }, @@ -269,14 +307,18 @@ static const struct wiz_clk_div_sel clk_div_sel[] = { enum wiz_type { J721E_WIZ_16G, - J721E_WIZ_10G, + J721E_WIZ_10G, /* Also for J7200 SR1.0 */ AM64_WIZ_10G, + J7200_WIZ_10G, /* J7200 SR2.0 */ }; struct wiz_data { enum wiz_type type; + const struct reg_field *pll0_refclk_mux_sel; + 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; }; @@ -286,6 +328,7 @@ struct wiz_data { struct wiz { struct regmap *regmap; + struct regmap *scm_regmap; enum wiz_type type; const struct wiz_clk_mux_sel *clk_mux_sel; const struct wiz_clk_div_sel *clk_div_sel; @@ -304,12 +347,14 @@ struct wiz { struct regmap_field *p0_rxfclk_sel[WIZ_MAX_LANES]; struct regmap_field *p0_refclk_sel[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; struct regmap_field *mux_sel_field[WIZ_MUX_NUM_CLOCKS]; struct regmap_field *div_sel_field[WIZ_DIV_NUM_CLOCKS_16G]; struct regmap_field *typec_ln10_swap; + struct regmap_field *sup_legacy_clk_override; struct device *dev; u32 num_lanes; @@ -448,6 +493,7 @@ static int wiz_init(struct wiz *wiz) static int wiz_regfield_init(struct wiz *wiz) { struct regmap *regmap = wiz->regmap; + struct regmap *scm_regmap = wiz->regmap; /* updated later to scm_regmap if applicable */ int num_lanes = wiz->num_lanes; struct device *dev = wiz->dev; const struct wiz_data *data = wiz->data; @@ -497,27 +543,46 @@ static int wiz_regfield_init(struct wiz *wiz) } } + if (wiz->scm_regmap) { + scm_regmap = wiz->scm_regmap; + wiz->sup_legacy_clk_override = + devm_regmap_field_alloc(dev, scm_regmap, sup_legacy_clk_override); + if (IS_ERR(wiz->sup_legacy_clk_override)) { + dev_err(dev, "SUP_LEGACY_CLK_OVERRIDE reg field init failed\n"); + return PTR_ERR(wiz->sup_legacy_clk_override); + } + } + wiz->mux_sel_field[PLL0_REFCLK] = - devm_regmap_field_alloc(dev, regmap, pll0_refclk_mux_sel); + devm_regmap_field_alloc(dev, scm_regmap, *data->pll0_refclk_mux_sel); if (IS_ERR(wiz->mux_sel_field[PLL0_REFCLK])) { dev_err(dev, "PLL0_REFCLK_SEL reg field init failed\n"); return PTR_ERR(wiz->mux_sel_field[PLL0_REFCLK]); } wiz->mux_sel_field[PLL1_REFCLK] = - devm_regmap_field_alloc(dev, regmap, pll1_refclk_mux_sel); + devm_regmap_field_alloc(dev, scm_regmap, *data->pll1_refclk_mux_sel); if (IS_ERR(wiz->mux_sel_field[PLL1_REFCLK])) { dev_err(dev, "PLL1_REFCLK_SEL reg field init failed\n"); return PTR_ERR(wiz->mux_sel_field[PLL1_REFCLK]); } - wiz->mux_sel_field[REFCLK_DIG] = devm_regmap_field_alloc(dev, regmap, + wiz->mux_sel_field[REFCLK_DIG] = devm_regmap_field_alloc(dev, scm_regmap, *data->refclk_dig_sel); if (IS_ERR(wiz->mux_sel_field[REFCLK_DIG])) { dev_err(dev, "REFCLK_DIG_SEL reg field init failed\n"); return PTR_ERR(wiz->mux_sel_field[REFCLK_DIG]); } + if (data->pma_cmn_refclk1_int_mode) { + wiz->pma_cmn_refclk1_int_mode = + devm_regmap_field_alloc(dev, scm_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); + } + } + for (i = 0; i < num_lanes; i++) { wiz->p_enable[i] = devm_regmap_field_alloc(dev, regmap, p_enable[i]); @@ -906,9 +971,13 @@ static void wiz_clock_cleanup(struct wiz *wiz, struct device_node *node) struct device_node *clk_node; int i; - if (wiz->type == AM64_WIZ_10G) { + switch (wiz->type) { + case AM64_WIZ_10G: + case J7200_WIZ_10G: of_clk_del_provider(dev->of_node); return; + default: + break; } for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) { @@ -935,9 +1004,6 @@ static int wiz_clock_register(struct wiz *wiz) int ret; int i; - if (wiz->type != AM64_WIZ_10G) - return 0; - clk_index = TI_WIZ_PLL0_REFCLK; for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++, clk_index++) { ret = wiz_mux_clk_register(wiz, wiz->mux_sel_field[i], &clk_mux_sel[i], clk_index); @@ -987,6 +1053,22 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node) 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); + } + clk = devm_clk_get(dev, "ext_ref_clk"); if (IS_ERR(clk)) { dev_err(dev, "ext_ref_clk clock not found\n"); @@ -1001,11 +1083,15 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node) else regmap_field_write(wiz->pma_cmn_refclk_mode, 0x2); - if (wiz->type == AM64_WIZ_10G) { + switch (wiz->type) { + case AM64_WIZ_10G: + case J7200_WIZ_10G: ret = wiz_clock_register(wiz); if (ret) dev_err(dev, "Failed to register wiz clocks\n"); return ret; + default: + break; } for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) { @@ -1081,6 +1167,7 @@ static int wiz_phy_fullrt_div(struct wiz *wiz, int lane) return regmap_field_write(wiz->p0_fullrt_div[lane], 0x1); break; case J721E_WIZ_10G: + case J7200_WIZ_10G: if (wiz->lane_phy_type[lane] == PHY_TYPE_SGMII) return regmap_field_write(wiz->p0_fullrt_div[lane], 0x2); break; @@ -1139,6 +1226,8 @@ static const struct regmap_config wiz_regmap_config = { static struct wiz_data j721e_16g_data = { .type = J721E_WIZ_16G, + .pll0_refclk_mux_sel = &pll0_refclk_mux_sel, + .pll1_refclk_mux_sel = &pll1_refclk_mux_sel, .refclk_dig_sel = &refclk_dig_sel_16g, .pma_cmn_refclk1_dig_div = &pma_cmn_refclk1_dig_div, .clk_mux_sel = clk_mux_sel_16g, @@ -1147,6 +1236,8 @@ static struct wiz_data j721e_16g_data = { static struct wiz_data j721e_10g_data = { .type = J721E_WIZ_10G, + .pll0_refclk_mux_sel = &pll0_refclk_mux_sel, + .pll1_refclk_mux_sel = &pll1_refclk_mux_sel, .refclk_dig_sel = &refclk_dig_sel_10g, .clk_mux_sel = clk_mux_sel_10g, .clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_10G, @@ -1154,11 +1245,23 @@ static struct wiz_data j721e_10g_data = { static struct wiz_data am64_10g_data = { .type = AM64_WIZ_10G, + .pll0_refclk_mux_sel = &pll0_refclk_mux_sel, + .pll1_refclk_mux_sel = &pll1_refclk_mux_sel, .refclk_dig_sel = &refclk_dig_sel_10g, .clk_mux_sel = clk_mux_sel_10g, .clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_10G, }; +static struct wiz_data j7200_pg2_10g_data = { + .type = J7200_WIZ_10G, + .pll0_refclk_mux_sel = &sup_pll0_refclk_mux_sel, + .pll1_refclk_mux_sel = &sup_pll1_refclk_mux_sel, + .refclk_dig_sel = &sup_refclk_dig_sel_10g, + .pma_cmn_refclk1_int_mode = &sup_pma_cmn_refclk1_int_mode, + .clk_mux_sel = clk_mux_sel_10g_2_refclk, + .clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_10G, +}; + static const struct of_device_id wiz_id_table[] = { { .compatible = "ti,j721e-wiz-16g", .data = &j721e_16g_data, @@ -1169,6 +1272,9 @@ static const struct of_device_id wiz_id_table[] = { { .compatible = "ti,am64-wiz-10g", .data = &am64_10g_data, }, + { + .compatible = "ti,j7200-wiz-10g", .data = &j7200_pg2_10g_data, + }, {} }; MODULE_DEVICE_TABLE(of, wiz_id_table); @@ -1266,6 +1372,16 @@ static int wiz_probe(struct platform_device *pdev) goto err_addr_to_resource; } + wiz->scm_regmap = syscon_regmap_lookup_by_phandle(node, "ti,scm"); + if (IS_ERR(wiz->scm_regmap)) { + if (wiz->type == J7200_WIZ_10G) { + dev_err(dev, "Couldn't get ti,scm regmap\n"); + return -ENODEV; + } + + wiz->scm_regmap = NULL; + } + ret = of_property_read_u32(node, "num-lanes", &num_lanes); if (ret) { dev_err(dev, "Failed to read num-lanes property\n"); @@ -1327,6 +1443,10 @@ static int wiz_probe(struct platform_device *pdev) goto err_addr_to_resource; } + /* Enable supplemental Control override if available */ + if (wiz->scm_regmap) + regmap_field_write(wiz->sup_legacy_clk_override, 1); + phy_reset_dev = &wiz->wiz_phy_reset_dev; phy_reset_dev->dev = dev; phy_reset_dev->ops = &wiz_phy_reset_ops,