From nobody Tue Dec 16 08:58:32 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 85A31C07E9D for ; Mon, 26 Sep 2022 11:51:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238574AbiIZLvt (ORCPT ); Mon, 26 Sep 2022 07:51:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46098 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238236AbiIZLvQ (ORCPT ); Mon, 26 Sep 2022 07:51:16 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 97F62760D5; Mon, 26 Sep 2022 03:48:34 -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 dfw.source.kernel.org (Postfix) with ESMTPS id 356E960CA3; Mon, 26 Sep 2022 10:33:18 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 402FAC433D6; Mon, 26 Sep 2022 10:33:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1664188397; bh=/C0jym3W36LqzFLJ72W++uwV3/cKZ208I2ml3w1Xx0M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vIF6zym5uor3jX1wMhQXS7NdJHKfPa1bOqw1E6HCMIO4H3CTA2+s4EW/+OvGxysIM OdjcN37vp450MQsihk2v8oXIZNC3jwcaZQRMerj3qC3hXNvPm48Zq1/t9plx3oPKDP CxJ+cMxQIuETDE4IH53jaf5rniUTAxHonnLbzO1w= 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.10 137/141] i2c: mlxbf: Fix frequency calculation Date: Mon, 26 Sep 2022 12:12:43 +0200 Message-Id: <20220926100759.418516202@linuxfoundation.org> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220926100754.639112000@linuxfoundation.org> References: <20220926100754.639112000@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 d78fb24d5588..bea82a787b4f 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 @@ -187,22 +189,15 @@ enum { #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; @@ -485,8 +480,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 @@ -1416,24 +1409,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: @@ -1445,31 +1433,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: @@ -1481,7 +1464,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; @@ -2189,14 +2172,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