From patchwork Mon May 19 15:41:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Nuno_S=C3=A1_via_B4_Relay?= X-Patchwork-Id: 891499 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BF30528643F; Mon, 19 May 2025 15:50:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747669827; cv=none; b=tgrhZDCcKMd9ra2wJsfTArq11Vxqzgw6y+CMolrZl408gWFhH6SnOijtEa2OUIM1GJutV88hntV9itRfErOud52ttULf5tigPuAOvgJzx4BXXu3cNgcDpruUWZ8sCS7SbNmv1ldc7qPwfRaYb6GSd2BbNjhC3vknkMdXiMFKfuc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747669827; c=relaxed/simple; bh=+cK0fBqHccIiGa9CGO2qeuLfPzALRqohpfOHgcdKD4c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=etwFfBqL6u4oVjynWpCk/pwZ3woGeDvR/nkUT7wkabbyaj6eLWGIAAFa4pPzDvRJ79NE2l8SW/xDlQO6AZXrU4XucL+3RIQ/5fCWGhYSZSO1xbTbzLhHUY9Pf55IutsRVaf/FMSfr+qBx/7IjHC1tNjfva9ygOJ6wTROaIQhht8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=AHFink7z; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="AHFink7z" Received: by smtp.kernel.org (Postfix) with ESMTPS id 35E0AC4CEF9; Mon, 19 May 2025 15:50:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1747669827; bh=+cK0fBqHccIiGa9CGO2qeuLfPzALRqohpfOHgcdKD4c=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=AHFink7zK8PdU07hXd212oDs5RDlqwTyz1jheSNzuH03EZFrIzOifHzV+lGjR17ng gKTISFTBKZWrKoU0HJRiEjagA63iHNYjtlVdbjN80LSupA7umU50uYytXxswqxhlQL FMXgieVF8qtxNsXQuqp2h7K5sKJ4x6oyno5eI+PkcSerz3SwOtP3ZsocBpXVIuRvjX GCj0fBiq5xSeIt3IJVrLJP2ICSXXIxYX9LphOuQP4256iB2Vq+S/gLXguvAQevSMB1 4jXKsxJXB5NqsG8WEuXJG3JhOnC2jpBf695BoE3qUVspMD9u+ee3q0mDtWnMce+c/Z 4rK9PTZfm6+0A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2B059C2D0CD; Mon, 19 May 2025 15:50:27 +0000 (UTC) From: =?utf-8?q?Nuno_S=C3=A1_via_B4_Relay?= Date: Mon, 19 May 2025 16:41:10 +0100 Subject: [PATCH v6 5/7] clk: clk-axi-clkgen: detect axi_clkgen_limits at runtime Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250519-dev-axi-clkgen-limits-v6-5-bc4b3b61d1d4@analog.com> References: <20250519-dev-axi-clkgen-limits-v6-0-bc4b3b61d1d4@analog.com> In-Reply-To: <20250519-dev-axi-clkgen-limits-v6-0-bc4b3b61d1d4@analog.com> To: linux-clk@vger.kernel.org, linux-fpga@vger.kernel.org, dmaengine@vger.kernel.org, linux-hwmon@vger.kernel.org, linux-iio@vger.kernel.org, linux-pwm@vger.kernel.org, linux-spi@vger.kernel.org Cc: Stephen Boyd , Michael Turquette , Moritz Fischer , Wu Hao , Xu Yilun , Tom Rix , Vinod Koul , Jean Delvare , Guenter Roeck , Michael Hennerich , Jonathan Cameron , Trevor Gamblin , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , David Lechner , Mark Brown , Mike Turquette X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1747669828; l=3981; i=nuno.sa@analog.com; s=20231116; h=from:subject:message-id; bh=nuqSxH2DcFb0n5Cp5hJrZPhnAul6ayJrJavTFUfm6W8=; b=EP72A+xNs6i9+2wLrCQGiIpOvsX6aWdoj+MYtyGoxio5Ru2sYulayB6MJJdLSXy0TxcM37Oyf QpmRecRdZ82AshSfJiWGNzP3hAwy9LTVbc3BNjswZeYAyoKJUWe6Av9 X-Developer-Key: i=nuno.sa@analog.com; a=ed25519; pk=3NQwYA013OUYZsmDFBf8rmyyr5iQlxV/9H4/Df83o1E= X-Endpoint-Received: by B4 Relay for nuno.sa@analog.com/20231116 with auth_id=100 X-Original-From: =?utf-8?q?Nuno_S=C3=A1?= Reply-To: nuno.sa@analog.com From: Nuno Sá This patch adds support for setting the limits in struct axi_clkgen_limits in accordance with fpga speed grade, voltage, technology and family. This new information is extracted from two new registers implemented in the ip core that are only available for core versions higher or equal to 4. Signed-off-by: Nuno Sá --- drivers/clk/clk-axi-clkgen.c | 65 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c index 2a95f9b220234a1245024a821c50e1eb9c104ac9..f4e96394e9c25c817b09ee0c08751147083f19b7 100644 --- a/drivers/clk/clk-axi-clkgen.c +++ b/drivers/clk/clk-axi-clkgen.c @@ -6,6 +6,8 @@ * Author: Lars-Peter Clausen */ +#include +#include #include #include #include @@ -29,6 +31,9 @@ #define AXI_CLKGEN_V2_DRP_STATUS_BUSY BIT(16) +#define ADI_CLKGEN_REG_FPGA_VOLTAGE 0x0140 +#define ADI_CLKGEN_INFO_FPGA_VOLTAGE(val) ((val) & GENMASK(15, 0)) + #define MMCM_REG_CLKOUT5_2 0x07 #define MMCM_REG_CLKOUT0_1 0x08 #define MMCM_REG_CLKOUT0_2 0x09 @@ -497,6 +502,54 @@ static u8 axi_clkgen_get_parent(struct clk_hw *clk_hw) return parent; } +static int axi_clkgen_setup_limits(struct axi_clkgen *axi_clkgen, + struct device *dev) +{ + unsigned int tech, family, speed_grade, reg_value; + + axi_clkgen_read(axi_clkgen, ADI_AXI_REG_FPGA_INFO, ®_value); + tech = ADI_AXI_INFO_FPGA_TECH(reg_value); + family = ADI_AXI_INFO_FPGA_FAMILY(reg_value); + speed_grade = ADI_AXI_INFO_FPGA_SPEED_GRADE(reg_value); + + axi_clkgen->limits.fpfd_min = 10000; + axi_clkgen->limits.fvco_min = 600000; + + switch (speed_grade) { + case ADI_AXI_FPGA_SPEED_1 ... ADI_AXI_FPGA_SPEED_1LV: + axi_clkgen->limits.fvco_max = 1200000; + axi_clkgen->limits.fpfd_max = 450000; + break; + case ADI_AXI_FPGA_SPEED_2 ... ADI_AXI_FPGA_SPEED_2LV: + axi_clkgen->limits.fvco_max = 1440000; + axi_clkgen->limits.fpfd_max = 500000; + if (family == ADI_AXI_FPGA_FAMILY_KINTEX || family == ADI_AXI_FPGA_FAMILY_ARTIX) { + axi_clkgen_read(axi_clkgen, ADI_CLKGEN_REG_FPGA_VOLTAGE, + ®_value); + if (ADI_CLKGEN_INFO_FPGA_VOLTAGE(reg_value) < 950) { + axi_clkgen->limits.fvco_max = 1200000; + axi_clkgen->limits.fpfd_max = 450000; + } + } + break; + case ADI_AXI_FPGA_SPEED_3: + axi_clkgen->limits.fvco_max = 1600000; + axi_clkgen->limits.fpfd_max = 550000; + break; + default: + return dev_err_probe(dev, -ENODEV, "Unknown speed grade %d\n", + speed_grade); + }; + + /* Overwrite vco limits for ultrascale+ */ + if (tech == ADI_AXI_FPGA_TECH_ULTRASCALE_PLUS) { + axi_clkgen->limits.fvco_max = 1600000; + axi_clkgen->limits.fvco_min = 800000; + } + + return 0; +} + static const struct clk_ops axi_clkgen_ops = { .recalc_rate = axi_clkgen_recalc_rate, .determine_rate = axi_clkgen_determine_rate, @@ -511,6 +564,7 @@ static int axi_clkgen_probe(struct platform_device *pdev) { const struct axi_clkgen_limits *dflt_limits; struct axi_clkgen *axi_clkgen; + unsigned int pcore_version; struct clk_init_data init; const char *parent_names[2]; const char *clk_name; @@ -556,7 +610,16 @@ static int axi_clkgen_probe(struct platform_device *pdev) return -EINVAL; } - memcpy(&axi_clkgen->limits, dflt_limits, sizeof(axi_clkgen->limits)); + axi_clkgen_read(axi_clkgen, ADI_AXI_REG_VERSION, &pcore_version); + + if (ADI_AXI_PCORE_VER_MAJOR(pcore_version) > 0x04) { + ret = axi_clkgen_setup_limits(axi_clkgen, &pdev->dev); + if (ret) + return ret; + } else { + memcpy(&axi_clkgen->limits, dflt_limits, + sizeof(axi_clkgen->limits)); + } clk_name = pdev->dev.of_node->name; of_property_read_string(pdev->dev.of_node, "clock-output-names",