Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp1493906pxb; Mon, 22 Feb 2021 03:31:04 -0800 (PST) X-Google-Smtp-Source: ABdhPJzNmXSVLuPBh7FD1OskXINEC8WJjHu6bO+vuB4V4Q6A+a4akikUu4t3npiGLtbt7g7fcLXk X-Received: by 2002:a17:906:12db:: with SMTP id l27mr20219689ejb.500.1613993464412; Mon, 22 Feb 2021 03:31:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613993464; cv=none; d=google.com; s=arc-20160816; b=t0xC9j1O+lIhBOcDY9lHkGlqBjz198gFIznO4DKmqPPSjLF+I/ELvSwr5mMJV7BT3f JwZGW+01OWc33cVHj61dwY0UA2cDeCykMxqWyHQTqg1LJF/gI2tdm3WGAnsg0DRce4+z tlWpTK91cBKVjsLYJDNia01sGro8DRdg2OfnAtmMRPZCBj2fPRXShISXpVF7Y40NALV2 BrX7wr1utjcNWuXHssu/qk8Lpr4UT9mno3B7Z2PLo5mFZe+QRCA7FLJ6kO+k5vFxGaZW Vs0zY8mhHzjr4mxHg6CJ3wGsLDoFbD37ecChrVDMnfNoZz90+bh8XzLjYXoLYWWd25F3 l61g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=OJlIz+AWFMmzXGgsTjG9uyhtO88Ig4YJBS7ThBMgmDc=; b=iN/ywKhr6l2lS6986GbduvKp3d05IxaIX1roSJOsz/ARmETbEniO4+eM0eB+6f2XAI opkfGQ3STKmH8Z5iJszYqk75f5s7znRY/R/9PGOcjmjUChfGQYS5nnueAGZIGkoHhgPc /pllI5JVMa5G+l2qpFg+vhHLZ6sN79MSz/edqdeXSgkNH8saIGfq41wQltTN68FO/7Es bFHrBgAP3efrkggL1SWAbnHBFCeVkAxqfiLRMMRUiKTJ6Hry7kmceRG7UooE/oe4buJL k5KMxtgUqYqGFwwsbpp/+h5BBG3Q9VKsd57ZtcVlA6wXLHQESZ6zQsh8c2JtzHR2dMUO pQDw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=ryoE01jM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id zg3si11755796ejb.14.2021.02.22.03.30.41; Mon, 22 Feb 2021 03:31:04 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=ryoE01jM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230519AbhBVL15 (ORCPT + 99 others); Mon, 22 Feb 2021 06:27:57 -0500 Received: from fllv0016.ext.ti.com ([198.47.19.142]:57338 "EHLO fllv0016.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230470AbhBVLZp (ORCPT ); Mon, 22 Feb 2021 06:25:45 -0500 Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 11MBNu6J007166; Mon, 22 Feb 2021 05:23:56 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1613993036; bh=OJlIz+AWFMmzXGgsTjG9uyhtO88Ig4YJBS7ThBMgmDc=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=ryoE01jMhrMj/lGo1LnpzqTUFFxzd2S84RW1L1ntHube7O8tZdUdsG7qrb8JSNKej KYT5HgGZBq/SVU9MhcCTuFbs5LdIu1LS/qyikJgxXio9utP6YuqZ//VdLIM9Iz72IR XgEtbAYP3Flic1AviTHpjzLdvmZ94dDQJvmTb+jo= Received: from DLEE104.ent.ti.com (dlee104.ent.ti.com [157.170.170.34]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 11MBNulo117766 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 22 Feb 2021 05:23:56 -0600 Received: from DLEE110.ent.ti.com (157.170.170.21) by DLEE104.ent.ti.com (157.170.170.34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Mon, 22 Feb 2021 05:23:56 -0600 Received: from fllv0040.itg.ti.com (10.64.41.20) by DLEE110.ent.ti.com (157.170.170.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via Frontend Transport; Mon, 22 Feb 2021 05:23:56 -0600 Received: from a0393678-ssd.dhcp.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by fllv0040.itg.ti.com (8.15.2/8.15.2) with ESMTP id 11MBNFDg088010; Mon, 22 Feb 2021 05:23:53 -0600 From: Kishon Vijay Abraham I To: Kishon Vijay Abraham I , Vinod Koul , Rob Herring , Peter Rosin , Swapnil Jakhade CC: , , Subject: [PATCH v2 7/9] phy: ti: j721e-wiz: Model the internal clocks without device tree input Date: Mon, 22 Feb 2021 16:53:12 +0530 Message-ID: <20210222112314.10772-8-kishon@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210222112314.10772-1-kishon@ti.com> References: <20210222112314.10772-1-kishon@ti.com> MIME-Version: 1.0 Content-Type: text/plain X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org commit 091876cc355d ("phy: ti: j721e-wiz: Add support for WIZ module present in TI J721E SoC") modeled the internal clocks depending on the subnodes that are populated in device tree. However recent discussions in the mailing list [1] suggested to just add #clock cells in the parent DT node and model the clocks within the driver. Model the mux clocks without device tree input for AM64x SoC. Don't remove the earlier design since DT nodes for J7200 and J721e are already upstreamed. [1] -> http://lore.kernel.org/r/20210108025943.GA1790601@robh.at.kernel.org Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/ti/phy-j721e-wiz.c | 144 +++++++++++++++++++++++++++++++-- 1 file changed, 139 insertions(+), 5 deletions(-) diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c index 2706e7be0c28..f9299dcdbdb7 100644 --- a/drivers/phy/ti/phy-j721e-wiz.c +++ b/drivers/phy/ti/phy-j721e-wiz.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -27,6 +28,10 @@ #define WIZ_SERDES_TYPEC 0x410 #define WIZ_LANECTL(n) (0x480 + (0x40 * (n))) +#define WIZ_MAX_INPUT_CLOCKS 4 +/* To include mux clocks, divider clocks and gate clocks */ +#define WIZ_MAX_OUTPUT_CLOCKS 32 + #define WIZ_MAX_LANES 4 #define WIZ_MUX_NUM_CLOCKS 3 #define WIZ_DIV_NUM_CLOCKS_16G 2 @@ -52,6 +57,13 @@ enum wiz_refclk_div_sel { CMN_REFCLK1_DIG_DIV, }; +enum wiz_clock_input { + WIZ_CORE_REFCLK, + WIZ_EXT_REFCLK, + WIZ_CORE_REFCLK1, + WIZ_EXT_REFCLK1, +}; + 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 = @@ -70,6 +82,11 @@ 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 char * const output_clk_names[] = { + [TI_WIZ_PLL0_REFCLK] = "pll0-refclk", + [TI_WIZ_PLL1_REFCLK] = "pll1-refclk", + [TI_WIZ_REFCLK_DIG] = "refclk-dig", +}; static const struct reg_field p_enable[WIZ_MAX_LANES] = { REG_FIELD(WIZ_LANECTL(0), 30, 31), @@ -130,8 +147,10 @@ struct wiz_clk_divider { #define to_wiz_clk_div(_hw) container_of(_hw, struct wiz_clk_divider, hw) struct wiz_clk_mux_sel { - u32 table[4]; + u32 table[WIZ_MAX_INPUT_CLOCKS]; const char *node_name; + u32 num_parents; + u32 parents[WIZ_MAX_INPUT_CLOCKS]; }; struct wiz_clk_div_sel { @@ -164,14 +183,20 @@ static const struct wiz_clk_mux_sel clk_mux_sel_10g[] = { * Mux value to be configured for each of the input clocks * in the order populated in device tree */ + .num_parents = 2, + .parents = { WIZ_CORE_REFCLK, WIZ_EXT_REFCLK }, .table = { 1, 0 }, .node_name = "pll0-refclk", }, { + .num_parents = 2, + .parents = { WIZ_CORE_REFCLK, WIZ_EXT_REFCLK }, .table = { 1, 0 }, .node_name = "pll1-refclk", }, { + .num_parents = 2, + .parents = { WIZ_CORE_REFCLK, WIZ_EXT_REFCLK }, .table = { 1, 0 }, .node_name = "refclk-dig", }, @@ -232,6 +257,9 @@ struct wiz { struct gpio_desc *gpio_typec_dir; int typec_dir_delay; u32 lane_phy_type[WIZ_MAX_LANES]; + struct clk *input_clks[WIZ_MAX_INPUT_CLOCKS]; + struct clk *output_clks[WIZ_MAX_OUTPUT_CLOCKS]; + struct clk_onecell_data clk_data; }; static int wiz_reset(struct wiz *wiz) @@ -469,8 +497,69 @@ static const struct clk_ops wiz_clk_mux_ops = { .get_parent = wiz_clk_mux_get_parent, }; -static int wiz_mux_clk_register(struct wiz *wiz, struct device_node *node, - struct regmap_field *field, const u32 *table) +static int wiz_mux_clk_register(struct wiz *wiz, struct regmap_field *field, + const struct wiz_clk_mux_sel *mux_sel, int clk_index) +{ + struct device *dev = wiz->dev; + struct clk_init_data *init; + const char **parent_names; + unsigned int num_parents; + struct wiz_clk_mux *mux; + char clk_name[100]; + struct clk *clk; + int ret = 0, i; + + mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL); + if (!mux) + return -ENOMEM; + + num_parents = mux_sel->num_parents; + + parent_names = kzalloc((sizeof(char *) * num_parents), GFP_KERNEL); + if (!parent_names) + return -ENOMEM; + + for (i = 0; i < num_parents; i++) { + clk = wiz->input_clks[mux_sel->parents[i]]; + if (IS_ERR_OR_NULL(clk)) { + dev_err(dev, "Failed to get parent clk for %s\n", + output_clk_names[clk_index]); + ret = -EINVAL; + goto err; + } + parent_names[i] = __clk_get_name(clk); + } + + snprintf(clk_name, sizeof(clk_name), "%s_%s", dev_name(dev), output_clk_names[clk_index]); + + init = &mux->clk_data; + + init->ops = &wiz_clk_mux_ops; + init->flags = CLK_SET_RATE_NO_REPARENT; + init->parent_names = parent_names; + init->num_parents = num_parents; + init->name = clk_name; + + mux->field = field; + mux->table = mux_sel->table; + mux->hw.init = init; + + clk = devm_clk_register(dev, &mux->hw); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + goto err; + } + + wiz->output_clks[clk_index] = clk; + +err: + kfree(parent_names); + + return ret; +} + +static int wiz_mux_of_clk_register(struct wiz *wiz, struct device_node *node, + struct regmap_field *field, const u32 *table) { struct device *dev = wiz->dev; struct clk_init_data *init; @@ -615,9 +704,15 @@ static int wiz_div_clk_register(struct wiz *wiz, struct device_node *node, static void wiz_clock_cleanup(struct wiz *wiz, struct device_node *node) { const struct wiz_clk_mux_sel *clk_mux_sel = wiz->clk_mux_sel; + struct device *dev = wiz->dev; struct device_node *clk_node; int i; + if (wiz->type == AM64_WIZ_10G) { + of_clk_del_provider(dev->of_node); + return; + } + for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) { clk_node = of_get_child_by_name(node, clk_mux_sel[i].node_name); of_clk_del_provider(clk_node); @@ -631,6 +726,36 @@ static void wiz_clock_cleanup(struct wiz *wiz, struct device_node *node) } } +static int wiz_clock_register(struct wiz *wiz) +{ + const struct wiz_clk_mux_sel *clk_mux_sel = wiz->clk_mux_sel; + struct device *dev = wiz->dev; + struct device_node *node = dev->of_node; + int clk_index; + 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); + if (ret) { + dev_err(dev, "Failed to register clk: %s\n", output_clk_names[clk_index]); + return ret; + } + } + + wiz->clk_data.clks = wiz->output_clks; + wiz->clk_data.clk_num = WIZ_MAX_OUTPUT_CLOCKS; + ret = of_clk_add_provider(node, of_clk_src_onecell_get, &wiz->clk_data); + if (ret) + dev_err(dev, "Failed to add clock provider: %s\n", node->name); + + return ret; +} + static int wiz_clock_init(struct wiz *wiz, struct device_node *node) { const struct wiz_clk_mux_sel *clk_mux_sel = wiz->clk_mux_sel; @@ -648,6 +773,7 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node) ret = PTR_ERR(clk); return ret; } + wiz->input_clks[WIZ_CORE_REFCLK] = clk; rate = clk_get_rate(clk); if (rate >= 100000000) @@ -661,6 +787,7 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node) ret = PTR_ERR(clk); return ret; } + wiz->input_clks[WIZ_EXT_REFCLK] = clk; rate = clk_get_rate(clk); if (rate >= 100000000) @@ -668,6 +795,13 @@ 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) { + ret = wiz_clock_register(wiz); + if (ret) + dev_err(dev, "Failed to register wiz clocks\n"); + return ret; + } + for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) { node_name = clk_mux_sel[i].node_name; clk_node = of_get_child_by_name(node, node_name); @@ -677,8 +811,8 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node) goto err; } - ret = wiz_mux_clk_register(wiz, clk_node, wiz->mux_sel_field[i], - clk_mux_sel[i].table); + ret = wiz_mux_of_clk_register(wiz, clk_node, wiz->mux_sel_field[i], + clk_mux_sel[i].table); if (ret) { dev_err(dev, "Failed to register %s clock\n", node_name); -- 2.17.1