Skip to content

Commit 37f071e

Browse files
Asmaa Mnebhiwsakernel
authored andcommitted
i2c: mlxbf: Fix frequency calculation
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: b5b5b32 (i2c: mlxbf: I2C SMBus driver for Mellanox BlueField SoC) Reviewed-by: Khalil Blaiech <kblaiech@nvidia.com> Signed-off-by: Asmaa Mnebhi <asmaa@nvidia.com> Signed-off-by: Wolfram Sang <wsa@kernel.org>
1 parent de24ace commit 37f071e

File tree

1 file changed

+23
-40
lines changed

1 file changed

+23
-40
lines changed

drivers/i2c/busses/i2c-mlxbf.c

Lines changed: 23 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#include <linux/acpi.h>
9+
#include <linux/bitfield.h>
910
#include <linux/delay.h>
1011
#include <linux/err.h>
1112
#include <linux/interrupt.h>
@@ -63,13 +64,14 @@
6364
*/
6465
#define MLXBF_I2C_TYU_PLL_OUT_FREQ (400 * 1000 * 1000)
6566
/* Reference clock for Bluefield - 156 MHz. */
66-
#define MLXBF_I2C_PLL_IN_FREQ (156 * 1000 * 1000)
67+
#define MLXBF_I2C_PLL_IN_FREQ 156250000ULL
6768

6869
/* Constant used to determine the PLL frequency. */
69-
#define MLNXBF_I2C_COREPLL_CONST 16384
70+
#define MLNXBF_I2C_COREPLL_CONST 16384ULL
71+
72+
#define MLXBF_I2C_FREQUENCY_1GHZ 1000000000ULL
7073

7174
/* PLL registers. */
72-
#define MLXBF_I2C_CORE_PLL_REG0 0x0
7375
#define MLXBF_I2C_CORE_PLL_REG1 0x4
7476
#define MLXBF_I2C_CORE_PLL_REG2 0x8
7577

@@ -181,22 +183,15 @@
181183
#define MLXBF_I2C_COREPLL_FREQ MLXBF_I2C_TYU_PLL_OUT_FREQ
182184

183185
/* Core PLL TYU configuration. */
184-
#define MLXBF_I2C_COREPLL_CORE_F_TYU_MASK GENMASK(12, 0)
185-
#define MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK GENMASK(3, 0)
186-
#define MLXBF_I2C_COREPLL_CORE_R_TYU_MASK GENMASK(5, 0)
187-
188-
#define MLXBF_I2C_COREPLL_CORE_F_TYU_SHIFT 3
189-
#define MLXBF_I2C_COREPLL_CORE_OD_TYU_SHIFT 16
190-
#define MLXBF_I2C_COREPLL_CORE_R_TYU_SHIFT 20
186+
#define MLXBF_I2C_COREPLL_CORE_F_TYU_MASK GENMASK(15, 3)
187+
#define MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK GENMASK(19, 16)
188+
#define MLXBF_I2C_COREPLL_CORE_R_TYU_MASK GENMASK(25, 20)
191189

192190
/* Core PLL YU configuration. */
193191
#define MLXBF_I2C_COREPLL_CORE_F_YU_MASK GENMASK(25, 0)
194192
#define MLXBF_I2C_COREPLL_CORE_OD_YU_MASK GENMASK(3, 0)
195-
#define MLXBF_I2C_COREPLL_CORE_R_YU_MASK GENMASK(5, 0)
193+
#define MLXBF_I2C_COREPLL_CORE_R_YU_MASK GENMASK(31, 26)
196194

197-
#define MLXBF_I2C_COREPLL_CORE_F_YU_SHIFT 0
198-
#define MLXBF_I2C_COREPLL_CORE_OD_YU_SHIFT 1
199-
#define MLXBF_I2C_COREPLL_CORE_R_YU_SHIFT 26
200195

201196
/* Core PLL frequency. */
202197
static u64 mlxbf_i2c_corepll_frequency;
@@ -479,8 +474,6 @@ static struct mutex mlxbf_i2c_bus_lock;
479474
#define MLXBF_I2C_MASK_8 GENMASK(7, 0)
480475
#define MLXBF_I2C_MASK_16 GENMASK(15, 0)
481476

482-
#define MLXBF_I2C_FREQUENCY_1GHZ 1000000000
483-
484477
/*
485478
* Function to poll a set of bits at a specific address; it checks whether
486479
* 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_device *pdev,
14101403
return 0;
14111404
}
14121405

1413-
static u64 mlxbf_calculate_freq_from_tyu(struct mlxbf_i2c_resource *corepll_res)
1406+
static u64 mlxbf_i2c_calculate_freq_from_tyu(struct mlxbf_i2c_resource *corepll_res)
14141407
{
1415-
u64 core_frequency, pad_frequency;
1408+
u64 core_frequency;
14161409
u8 core_od, core_r;
14171410
u32 corepll_val;
14181411
u16 core_f;
14191412

1420-
pad_frequency = MLXBF_I2C_PLL_IN_FREQ;
1421-
14221413
corepll_val = readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG1);
14231414

14241415
/* Get Core PLL configuration bits. */
1425-
core_f = rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_F_TYU_SHIFT) &
1426-
MLXBF_I2C_COREPLL_CORE_F_TYU_MASK;
1427-
core_od = rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_OD_TYU_SHIFT) &
1428-
MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK;
1429-
core_r = rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_R_TYU_SHIFT) &
1430-
MLXBF_I2C_COREPLL_CORE_R_TYU_MASK;
1416+
core_f = FIELD_GET(MLXBF_I2C_COREPLL_CORE_F_TYU_MASK, corepll_val);
1417+
core_od = FIELD_GET(MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK, corepll_val);
1418+
core_r = FIELD_GET(MLXBF_I2C_COREPLL_CORE_R_TYU_MASK, corepll_val);
14311419

14321420
/*
14331421
* Compute PLL output frequency as follow:
@@ -1439,31 +1427,26 @@ static u64 mlxbf_calculate_freq_from_tyu(struct mlxbf_i2c_resource *corepll_res)
14391427
* Where PLL_OUT_FREQ and PLL_IN_FREQ refer to CoreFrequency
14401428
* and PadFrequency, respectively.
14411429
*/
1442-
core_frequency = pad_frequency * (++core_f);
1430+
core_frequency = MLXBF_I2C_PLL_IN_FREQ * (++core_f);
14431431
core_frequency /= (++core_r) * (++core_od);
14441432

14451433
return core_frequency;
14461434
}
14471435

1448-
static u64 mlxbf_calculate_freq_from_yu(struct mlxbf_i2c_resource *corepll_res)
1436+
static u64 mlxbf_i2c_calculate_freq_from_yu(struct mlxbf_i2c_resource *corepll_res)
14491437
{
14501438
u32 corepll_reg1_val, corepll_reg2_val;
1451-
u64 corepll_frequency, pad_frequency;
1439+
u64 corepll_frequency;
14521440
u8 core_od, core_r;
14531441
u32 core_f;
14541442

1455-
pad_frequency = MLXBF_I2C_PLL_IN_FREQ;
1456-
14571443
corepll_reg1_val = readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG1);
14581444
corepll_reg2_val = readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG2);
14591445

14601446
/* Get Core PLL configuration bits */
1461-
core_f = rol32(corepll_reg1_val, MLXBF_I2C_COREPLL_CORE_F_YU_SHIFT) &
1462-
MLXBF_I2C_COREPLL_CORE_F_YU_MASK;
1463-
core_r = rol32(corepll_reg1_val, MLXBF_I2C_COREPLL_CORE_R_YU_SHIFT) &
1464-
MLXBF_I2C_COREPLL_CORE_R_YU_MASK;
1465-
core_od = rol32(corepll_reg2_val, MLXBF_I2C_COREPLL_CORE_OD_YU_SHIFT) &
1466-
MLXBF_I2C_COREPLL_CORE_OD_YU_MASK;
1447+
core_f = FIELD_GET(MLXBF_I2C_COREPLL_CORE_F_YU_MASK, corepll_reg1_val);
1448+
core_r = FIELD_GET(MLXBF_I2C_COREPLL_CORE_R_YU_MASK, corepll_reg1_val);
1449+
core_od = FIELD_GET(MLXBF_I2C_COREPLL_CORE_OD_YU_MASK, corepll_reg2_val);
14671450

14681451
/*
14691452
* Compute PLL output frequency as follow:
@@ -1475,7 +1458,7 @@ static u64 mlxbf_calculate_freq_from_yu(struct mlxbf_i2c_resource *corepll_res)
14751458
* Where PLL_OUT_FREQ and PLL_IN_FREQ refer to CoreFrequency
14761459
* and PadFrequency, respectively.
14771460
*/
1478-
corepll_frequency = (pad_frequency * core_f) / MLNXBF_I2C_COREPLL_CONST;
1461+
corepll_frequency = (MLXBF_I2C_PLL_IN_FREQ * core_f) / MLNXBF_I2C_COREPLL_CONST;
14791462
corepll_frequency /= (++core_r) * (++core_od);
14801463

14811464
return corepll_frequency;
@@ -2183,14 +2166,14 @@ static struct mlxbf_i2c_chip_info mlxbf_i2c_chip[] = {
21832166
[1] = &mlxbf_i2c_corepll_res[MLXBF_I2C_CHIP_TYPE_1],
21842167
[2] = &mlxbf_i2c_gpio_res[MLXBF_I2C_CHIP_TYPE_1]
21852168
},
2186-
.calculate_freq = mlxbf_calculate_freq_from_tyu
2169+
.calculate_freq = mlxbf_i2c_calculate_freq_from_tyu
21872170
},
21882171
[MLXBF_I2C_CHIP_TYPE_2] = {
21892172
.type = MLXBF_I2C_CHIP_TYPE_2,
21902173
.shared_res = {
21912174
[0] = &mlxbf_i2c_corepll_res[MLXBF_I2C_CHIP_TYPE_2]
21922175
},
2193-
.calculate_freq = mlxbf_calculate_freq_from_yu
2176+
.calculate_freq = mlxbf_i2c_calculate_freq_from_yu
21942177
}
21952178
};
21962179

0 commit comments

Comments
 (0)