From nobody Thu Dec 18 04:13:47 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 55226C07E9D for ; Mon, 26 Sep 2022 12:00:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239145AbiIZMAc (ORCPT ); Mon, 26 Sep 2022 08:00:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59916 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238949AbiIZL46 (ORCPT ); Mon, 26 Sep 2022 07:56:58 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 02E817A537; Mon, 26 Sep 2022 03:51:37 -0700 (PDT) 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 079F8B8077B; Mon, 26 Sep 2022 10:50:55 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 50CDEC433D7; Mon, 26 Sep 2022 10:50:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1664189453; bh=uqwQ4xFumLZK7vILotRgOAeVPu/TjUochUrYMphEC4Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Sdfj52MJdeG/ayb5ZBAG3NnjgzxYrRfju71D76Lf7JaMnHTt1PuuFTUbONcvWkHPs jfUB4ph3mOhM+/+uAQ8a37o6ff0LeTer+Yuwo3kUxp9G+1W6yzlW3TRgU5smHRhnV7 58b80alCaAYMcD6pbXVoRELuiAfyxzOAQQPcRdOs= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Khalil Blaiech , Asmaa Mnebhi , Wolfram Sang , Sasha Levin Subject: [PATCH 5.19 193/207] i2c: mlxbf: Fix frequency calculation Date: Mon, 26 Sep 2022 12:13:02 +0200 Message-Id: <20220926100815.243440257@linuxfoundation.org> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220926100806.522017616@linuxfoundation.org> References: <20220926100806.522017616@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Asmaa Mnebhi [ Upstream commit 37f071ec327b04c83d47637c5e5c2199b39899ca ] The i2c-mlxbf.c driver is currently broken because there is a bug in the calculation of the frequency. core_f, core_r and core_od are components read from hardware registers and are used to compute the frequency used to compute different timing parameters. The shifting mechanism used to get core_f, core_r and core_od is wrong. Use FIELD_GET to mask and shift the bitfields properly. Fixes: b5b5b32081cd206b (i2c: mlxbf: I2C SMBus driver for Mellanox BlueFiel= d SoC) Reviewed-by: Khalil Blaiech Signed-off-by: Asmaa Mnebhi Signed-off-by: Wolfram Sang Signed-off-by: Sasha Levin --- drivers/i2c/busses/i2c-mlxbf.c | 63 +++++++++++++--------------------- 1 file changed, 23 insertions(+), 40 deletions(-) diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c index ac93c0ccf53c..ad5efd7497d1 100644 --- a/drivers/i2c/busses/i2c-mlxbf.c +++ b/drivers/i2c/busses/i2c-mlxbf.c @@ -6,6 +6,7 @@ */ =20 #include +#include #include #include #include @@ -63,13 +64,14 @@ */ #define MLXBF_I2C_TYU_PLL_OUT_FREQ (400 * 1000 * 1000) /* Reference clock for Bluefield - 156 MHz. */ -#define MLXBF_I2C_PLL_IN_FREQ (156 * 1000 * 1000) +#define MLXBF_I2C_PLL_IN_FREQ 156250000ULL =20 /* Constant used to determine the PLL frequency. */ -#define MLNXBF_I2C_COREPLL_CONST 16384 +#define MLNXBF_I2C_COREPLL_CONST 16384ULL + +#define MLXBF_I2C_FREQUENCY_1GHZ 1000000000ULL =20 /* PLL registers. */ -#define MLXBF_I2C_CORE_PLL_REG0 0x0 #define MLXBF_I2C_CORE_PLL_REG1 0x4 #define MLXBF_I2C_CORE_PLL_REG2 0x8 =20 @@ -181,22 +183,15 @@ #define MLXBF_I2C_COREPLL_FREQ MLXBF_I2C_TYU_PLL_OUT_FREQ =20 /* Core PLL TYU configuration. */ -#define MLXBF_I2C_COREPLL_CORE_F_TYU_MASK GENMASK(12, 0) -#define MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK GENMASK(3, 0) -#define MLXBF_I2C_COREPLL_CORE_R_TYU_MASK GENMASK(5, 0) - -#define MLXBF_I2C_COREPLL_CORE_F_TYU_SHIFT 3 -#define MLXBF_I2C_COREPLL_CORE_OD_TYU_SHIFT 16 -#define MLXBF_I2C_COREPLL_CORE_R_TYU_SHIFT 20 +#define MLXBF_I2C_COREPLL_CORE_F_TYU_MASK GENMASK(15, 3) +#define MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK GENMASK(19, 16) +#define MLXBF_I2C_COREPLL_CORE_R_TYU_MASK GENMASK(25, 20) =20 /* Core PLL YU configuration. */ #define MLXBF_I2C_COREPLL_CORE_F_YU_MASK GENMASK(25, 0) #define MLXBF_I2C_COREPLL_CORE_OD_YU_MASK GENMASK(3, 0) -#define MLXBF_I2C_COREPLL_CORE_R_YU_MASK GENMASK(5, 0) +#define MLXBF_I2C_COREPLL_CORE_R_YU_MASK GENMASK(31, 26) =20 -#define MLXBF_I2C_COREPLL_CORE_F_YU_SHIFT 0 -#define MLXBF_I2C_COREPLL_CORE_OD_YU_SHIFT 1 -#define MLXBF_I2C_COREPLL_CORE_R_YU_SHIFT 26 =20 /* Core PLL frequency. */ static u64 mlxbf_i2c_corepll_frequency; @@ -479,8 +474,6 @@ static struct mutex mlxbf_i2c_bus_lock; #define MLXBF_I2C_MASK_8 GENMASK(7, 0) #define MLXBF_I2C_MASK_16 GENMASK(15, 0) =20 -#define MLXBF_I2C_FREQUENCY_1GHZ 1000000000 - /* * Function to poll a set of bits at a specific address; it checks whether * the bits are equal to zero when eq_zero is set to 'true', and not equal @@ -1410,24 +1403,19 @@ static int mlxbf_i2c_init_master(struct platform_de= vice *pdev, return 0; } =20 -static u64 mlxbf_calculate_freq_from_tyu(struct mlxbf_i2c_resource *corepl= l_res) +static u64 mlxbf_i2c_calculate_freq_from_tyu(struct mlxbf_i2c_resource *co= repll_res) { - u64 core_frequency, pad_frequency; + u64 core_frequency; u8 core_od, core_r; u32 corepll_val; u16 core_f; =20 - pad_frequency =3D MLXBF_I2C_PLL_IN_FREQ; - corepll_val =3D readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG1); =20 /* Get Core PLL configuration bits. */ - core_f =3D rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_F_TYU_SHIFT) & - MLXBF_I2C_COREPLL_CORE_F_TYU_MASK; - core_od =3D rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_OD_TYU_SHIFT) & - MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK; - core_r =3D rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_R_TYU_SHIFT) & - MLXBF_I2C_COREPLL_CORE_R_TYU_MASK; + core_f =3D FIELD_GET(MLXBF_I2C_COREPLL_CORE_F_TYU_MASK, corepll_val); + core_od =3D FIELD_GET(MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK, corepll_val); + core_r =3D FIELD_GET(MLXBF_I2C_COREPLL_CORE_R_TYU_MASK, corepll_val); =20 /* * Compute PLL output frequency as follow: @@ -1439,31 +1427,26 @@ static u64 mlxbf_calculate_freq_from_tyu(struct mlx= bf_i2c_resource *corepll_res) * Where PLL_OUT_FREQ and PLL_IN_FREQ refer to CoreFrequency * and PadFrequency, respectively. */ - core_frequency =3D pad_frequency * (++core_f); + core_frequency =3D MLXBF_I2C_PLL_IN_FREQ * (++core_f); core_frequency /=3D (++core_r) * (++core_od); =20 return core_frequency; } =20 -static u64 mlxbf_calculate_freq_from_yu(struct mlxbf_i2c_resource *corepll= _res) +static u64 mlxbf_i2c_calculate_freq_from_yu(struct mlxbf_i2c_resource *cor= epll_res) { u32 corepll_reg1_val, corepll_reg2_val; - u64 corepll_frequency, pad_frequency; + u64 corepll_frequency; u8 core_od, core_r; u32 core_f; =20 - pad_frequency =3D MLXBF_I2C_PLL_IN_FREQ; - corepll_reg1_val =3D readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG1); corepll_reg2_val =3D readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG2); =20 /* Get Core PLL configuration bits */ - core_f =3D rol32(corepll_reg1_val, MLXBF_I2C_COREPLL_CORE_F_YU_SHIFT) & - MLXBF_I2C_COREPLL_CORE_F_YU_MASK; - core_r =3D rol32(corepll_reg1_val, MLXBF_I2C_COREPLL_CORE_R_YU_SHIFT) & - MLXBF_I2C_COREPLL_CORE_R_YU_MASK; - core_od =3D rol32(corepll_reg2_val, MLXBF_I2C_COREPLL_CORE_OD_YU_SHIFT) & - MLXBF_I2C_COREPLL_CORE_OD_YU_MASK; + core_f =3D FIELD_GET(MLXBF_I2C_COREPLL_CORE_F_YU_MASK, corepll_reg1_val); + core_r =3D FIELD_GET(MLXBF_I2C_COREPLL_CORE_R_YU_MASK, corepll_reg1_val); + core_od =3D FIELD_GET(MLXBF_I2C_COREPLL_CORE_OD_YU_MASK, corepll_reg2_val= ); =20 /* * Compute PLL output frequency as follow: @@ -1475,7 +1458,7 @@ static u64 mlxbf_calculate_freq_from_yu(struct mlxbf_= i2c_resource *corepll_res) * Where PLL_OUT_FREQ and PLL_IN_FREQ refer to CoreFrequency * and PadFrequency, respectively. */ - corepll_frequency =3D (pad_frequency * core_f) / MLNXBF_I2C_COREPLL_CONST; + corepll_frequency =3D (MLXBF_I2C_PLL_IN_FREQ * core_f) / MLNXBF_I2C_COREP= LL_CONST; corepll_frequency /=3D (++core_r) * (++core_od); =20 return corepll_frequency; @@ -2183,14 +2166,14 @@ static struct mlxbf_i2c_chip_info mlxbf_i2c_chip[] = =3D { [1] =3D &mlxbf_i2c_corepll_res[MLXBF_I2C_CHIP_TYPE_1], [2] =3D &mlxbf_i2c_gpio_res[MLXBF_I2C_CHIP_TYPE_1] }, - .calculate_freq =3D mlxbf_calculate_freq_from_tyu + .calculate_freq =3D mlxbf_i2c_calculate_freq_from_tyu }, [MLXBF_I2C_CHIP_TYPE_2] =3D { .type =3D MLXBF_I2C_CHIP_TYPE_2, .shared_res =3D { [0] =3D &mlxbf_i2c_corepll_res[MLXBF_I2C_CHIP_TYPE_2] }, - .calculate_freq =3D mlxbf_calculate_freq_from_yu + .calculate_freq =3D mlxbf_i2c_calculate_freq_from_yu } }; =20 --=20 2.35.1