[PATCH] clk: k210: Fix error calculation on 32bit
Sean Anderson
seanga2 at gmail.com
Sun Oct 16 16:19:43 CEST 2022
On 10/16/22 07:46, Heinrich Schuchardt wrote:
>
>
> On 10/16/22 09:51, Michal Suchánek wrote:
>> On Thu, Oct 13, 2022 at 10:34:29PM +0200, Michal Suchanek wrote:
>>> k210 is 64bit but the driver and tests are also built in sandbox, and
>>> that can be built 32bit.
>>>
>>> BIT(32) does not work on 32bit, shift before subtraction to fit into
>>> 32bit integer with BIT values.
>>
>>
>> Also see
>> https://patchwork.ozlabs.org/project/uboot/patch/20221016071035.461454-1-heinrich.schuchardt@canonical.com/
>>>
>>> Signed-off-by: Michal Suchanek <msuchanek at suse.de>
>>> ---
>>>
>>> drivers/clk/clk_k210.c | 2 +-
>>> test/dm/k210_pll.c | 2 +-
>>> 2 files changed, 2 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/clk/clk_k210.c b/drivers/clk/clk_k210.c
>>> index 1961efaa5e..e85f8ae14a 100644
>>> --- a/drivers/clk/clk_k210.c
>>> +++ b/drivers/clk/clk_k210.c
>>> @@ -846,7 +846,7 @@ again:
>>> error = DIV_ROUND_CLOSEST_ULL(f * inv_ratio, r * od);
>>> /* The lower 16 bits are spurious */
>>> - error = abs((error - BIT(32))) >> 16;
>>> + error = abs((error >> 16) - BIT(32 - 16));
>
>
> Your patch changes the results. Replacing BIT() by BIT_ULL() does not change the result:
>
> error = -1 = 0xffffffffffffffff
> before
> error - BIT(32) = -4294967297 = 0xfffffffeffffffff
> abs(error - BIT(32)) = 4294967297 = 0x100000001
> abs(error - BIT(32)) >> 16 = 65536 = 0x10000
> after
> error >> 16 = -1 = 0xffffffffffffffff
> (error >> 16) - BIT(32 - 16) = -65537 = 0xfffffffffffeffff
> abs((error >> 16) - BIT(32 - 16)) = 65537 = 0x10001
> using BIT_ULL
> abs(error - BIT_ULL(32)) >> 16 = 65536 = 0x10000
>
> error = 70000 = 0x11170
> before
> error - BIT(32) = -4294897296 = 0xffffffff00011170
> abs(error - BIT(32)) = 4294897296 = 0xfffeee90
> abs(error - BIT(32)) >> 16 = 65534 = 0xfffe
> after
> error >> 16 = 1 = 0x1
> (error >> 16) - BIT(32 - 16) = -65535 = 0xffffffffffff0001
> abs((error >> 16) - BIT(32 - 16)) = 65535 = 0xffff
> using BIT_ULL
> abs(error - BIT_ULL(32)) >> 16 = 65534 = 0xfffe
>
> I assume this change of results is unintended.
>
> We also replace abs() by abs64() to get correct results on a 32bit system:
>
> error = -1 = 0xffffffffffffffff
> abs(error - BIT_ULL(32)) >> 16 = 0 = 0x0
> abs64(error - BIT_ULL(32)) >> 16 = 65536 = 0x10000
> error = 70000 = 0x11170
> abs(error - BIT_ULL(32)) >> 16 = 1 = 0x1
> abs64(error - BIT_ULL(32)) >> 16 = 65534 = 0xfffe
>
> Best regards
>
> Heinrich
>
>>> if (error < best_error) {
>>> best->r = r;
>>> diff --git a/test/dm/k210_pll.c b/test/dm/k210_pll.c
>>> index a0cc84c396..622b1c9bef 100644
>>> --- a/test/dm/k210_pll.c
>>> +++ b/test/dm/k210_pll.c
>>> @@ -33,7 +33,7 @@ static int dm_test_k210_pll_calc_config(u32 rate, u32 rate_in,
>>> error = DIV_ROUND_CLOSEST_ULL(f * inv_ratio,
>>> r * od);
>>> /* The lower 16 bits are spurious */
>>> - error = abs((error - BIT(32))) >> 16;
>>> + error = abs((error >> 16) - BIT(32 - 16));
>>> if (error < best_error) {
>>> best->r = r;
>>> best->f = f;
>>> --
>>> 2.37.3
>>>
IMO the driver should just be changed to depend on 64-bit. The k210 is 64-bit,
and I didn't write anything with 32-bit in mind.
--Sean
More information about the U-Boot
mailing list