phy: stm32: Fix constant-value overflow assertion
Rework the workaround as the lookup tables always fits into the bitfield,
and the default values are defined by the hardware and cannot be 0:
Guard against false positive with a WARN_ON check to make the compiler
happy: The offset range is pre-checked against the sorted imp_lookup_table
values and overflow should not happen and would be caught by a warning and
return in error.
Also guard against a true positive found during the max_vswing lookup, as a
max vswing value can be 802000 or 803000 microvolt depending on the current
impedance. Therefore set the default impedence index.
Fixes: 2de679ecd7
("phy: stm32: work around constant-value overflow assertion")
Signed-off-by: Christian Bruel <christian.bruel@foss.st.com>
Link: https://lore.kernel.org/r/20250210103515.2598377-1-christian.bruel@foss.st.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
3126ea9be6
commit
fd75f371f3
1 changed files with 18 additions and 20 deletions
|
@ -111,6 +111,7 @@ static const struct clk_impedance imp_lookup[] = {
|
|||
{ 4204000, { 511000, 609000, 706000, 802000 } },
|
||||
{ 3999000, { 571000, 648000, 726000, 803000 } }
|
||||
};
|
||||
#define DEFAULT_IMP_INDEX 3 /* Default impedance is 50 Ohm */
|
||||
|
||||
static int stm32_impedance_tune(struct stm32_combophy *combophy)
|
||||
{
|
||||
|
@ -119,10 +120,9 @@ static int stm32_impedance_tune(struct stm32_combophy *combophy)
|
|||
u8 imp_of, vswing_of;
|
||||
u32 max_imp = imp_lookup[0].microohm;
|
||||
u32 min_imp = imp_lookup[imp_size - 1].microohm;
|
||||
u32 max_vswing = imp_lookup[imp_size - 1].vswing[vswing_size - 1];
|
||||
u32 max_vswing;
|
||||
u32 min_vswing = imp_lookup[0].vswing[0];
|
||||
u32 val;
|
||||
u32 regval;
|
||||
|
||||
if (!of_property_read_u32(combophy->dev->of_node, "st,output-micro-ohms", &val)) {
|
||||
if (val < min_imp || val > max_imp) {
|
||||
|
@ -130,45 +130,43 @@ static int stm32_impedance_tune(struct stm32_combophy *combophy)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
regval = 0;
|
||||
for (imp_of = 0; imp_of < ARRAY_SIZE(imp_lookup); imp_of++) {
|
||||
if (imp_lookup[imp_of].microohm <= val) {
|
||||
regval = FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_OHM, imp_of);
|
||||
for (imp_of = 0; imp_of < ARRAY_SIZE(imp_lookup); imp_of++)
|
||||
if (imp_lookup[imp_of].microohm <= val)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (WARN_ON(imp_of == ARRAY_SIZE(imp_lookup)))
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(combophy->dev, "Set %u micro-ohms output impedance\n",
|
||||
imp_lookup[imp_of].microohm);
|
||||
|
||||
regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
|
||||
STM32MP25_PCIEPRG_IMPCTRL_OHM,
|
||||
regval);
|
||||
} else {
|
||||
regmap_read(combophy->regmap, SYSCFG_PCIEPRGCR, &val);
|
||||
imp_of = FIELD_GET(STM32MP25_PCIEPRG_IMPCTRL_OHM, val);
|
||||
}
|
||||
FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_OHM, imp_of));
|
||||
} else
|
||||
imp_of = DEFAULT_IMP_INDEX;
|
||||
|
||||
if (!of_property_read_u32(combophy->dev->of_node, "st,output-vswing-microvolt", &val)) {
|
||||
max_vswing = imp_lookup[imp_of].vswing[vswing_size - 1];
|
||||
|
||||
if (val < min_vswing || val > max_vswing) {
|
||||
dev_err(combophy->dev, "Invalid value %u for output vswing\n", val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
regval = 0;
|
||||
for (vswing_of = 0; vswing_of < ARRAY_SIZE(imp_lookup[imp_of].vswing); vswing_of++) {
|
||||
if (imp_lookup[imp_of].vswing[vswing_of] >= val) {
|
||||
regval = FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_VSWING, vswing_of);
|
||||
for (vswing_of = 0; vswing_of < ARRAY_SIZE(imp_lookup[imp_of].vswing); vswing_of++)
|
||||
if (imp_lookup[imp_of].vswing[vswing_of] >= val)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (WARN_ON(vswing_of == ARRAY_SIZE(imp_lookup[imp_of].vswing)))
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(combophy->dev, "Set %u microvolt swing\n",
|
||||
imp_lookup[imp_of].vswing[vswing_of]);
|
||||
|
||||
regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
|
||||
STM32MP25_PCIEPRG_IMPCTRL_VSWING,
|
||||
regval);
|
||||
FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_VSWING, vswing_of));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue