linux icon indicating copy to clipboard operation
linux copied to clipboard

wrong calculation of divf

Open maximus21 opened this issue 11 years ago • 5 comments

too large shift of dividend happens before division by target frequency. this leads to divf >=1024 in certain cases, for instance when target frequency is 1024000. divf should be calculated as a remainder from division by 1024 as it was done in the old version.

maximus21 avatar Dec 17 '13 12:12 maximus21

You are right that this has changed, but intentionally because there was a bug in the old version - the factor 1024 was wrong and should have been 4096: The goal is to do this calculation (in your example case): 500000000 / 1024000 = 488.28125 The binary representation is this: 111101000.01001 We have 12 bits in the fractional part, therefore the correct value of the register (without the leading password and bits) would be 111101000010010000000

Old version: dividend = 500000000 dividend = 500000000*1024 = 512000000000 dividend = 512000000000 / 1024000 = 500000 divi = 500000 / 1024 = 488 divf = 500000 % 1024 = 288 Value of register: 111101000000100100000

New version: dividend = 500000000 dividend = 500000000 << 12 = 2048000000000 dividend = 2048000000000 / 1024000 = 2000000 divi = 2000000 >> 12 = 488 divf = 2000000 & 0xFFF = 1152 Value of register: 111101000010010000000

koalo avatar Dec 17 '13 13:12 koalo

Florian, the formula for average frequency in mash module is source/(divi+divf/1024). The fact that 12 bits are used to store the value doesn't mean that all 12 bits are used. What is your source of information regarding division by 4096? It might be invisible in most setups, but in my setup codec and soc don't have connection for bit clock and that's where the difference is visible. 3.8 works perfectly, the new driver fails to produce 1.024Mhz.

koalo [email protected] wrote:

You are right that this has changed, but intentionally because there was a bug in the old version - the factor 1024 was wrong and should have been 4096: The goal is to do this calculation (in your example case): 500000000 / 1024000 = 488.28125 The binary representation is this: 111101000.01001 We have 12 bits in the fractional part, therefore the correct value of the register (without the leading password and bits) would be 111101000010010000000

Old version: dividend = 500000000 dividend = 500000000*1024 = 512000000000 dividend = 512000000000 / 1024000 = 500000 divi = 500000 / 1024 = 488 divf = 500000 % 1024 = 288 Value of register: 111101000000100100000

New version: dividend = 500000000 dividend = 500000000 << 12 = 2048000000000 dividend = 2048000000000 / 1024000 = 2000000 divi = 2000000 >> 12 = 488 divf = 2000000 & 0xFFF = 1152 Value of register: 111101000010010000000


Reply to this email directly or view it on GitHub: https://github.com/koalo/linux/issues/28#issuecomment-30749523

maximus21 avatar Dec 17 '13 13:12 maximus21

It is kind of strange to store a 1023 max value in 12 bits, but ok - I attached more importance to the bit field than to the formula. What is the frequency you measure now?

koalo avatar Dec 17 '13 13:12 koalo

I can't measure the frequency reliably. Maybe we should request clarification from the foundation people.

koalo [email protected] wrote:

It is kind of strange to store a 1023 max value in 12 bits, but ok - I attached more importance to the bit field than to the formula. What is the frequency you measure now?


Reply to this email directly or view it on GitHub: https://github.com/koalo/linux/issues/28#issuecomment-30751691

maximus21 avatar Dec 17 '13 13:12 maximus21

If we assume the 1024 is right, the frequency is now: 1022234 Hz If we assume the 4096 is right, the frequency was before: 1024443 Hz How have you noticed that?

koalo avatar Dec 17 '13 14:12 koalo