[Letux-kernel] X1600 / LX16 support - here: adding MMC

H. Nikolaus Schaller hns at goldelico.com
Fri Feb 9 19:27:02 CET 2024



> Am 09.02.2024 um 18:35 schrieb H. Nikolaus Schaller <hns at goldelico.com>:
> 
> 
> 
>> Am 09.02.2024 um 18:20 schrieb H. Nikolaus Schaller <hns at goldelico.com>:
>> 
>>>> So it will indeed be interesting to see how the MSC registers are
>>>> initialized. And clock dividers and registers. And pinctrl. Will just need
>>>> a little time for hacking this into the kernel code.
>> 
> 
> Test result of hacking jz4740_mmc_set_clock_rate()

> We strangely see that clock 400000Hz is translated into 50 MHz which is limited
> by the clock to a lower rate.

There is a default of 24 MHz in the jz4740 mmc driver but we overwrite by 50 MHz
in DTS.

> 
> Well, there is real magic going on. The clock rate of 400 kHz is just used to
> calculate a new divisor. The clock itself is running at its max rate.
> 
> Which means we tell the MSC to divide the 35 MHz clock by 7. Because it is limited
> to 7.This wold mean 5 MHz. But where do the 3.5 MHz come from I have seen?
> Or is div some 2^ divider factor?
> 
> Yes, CLKRT:
> 
> 000: DEV_CLK
> 001: 1/2 of DEV_CLK
> 010: 1/4 of DEV_CLK
> 011: 1/8 of DEV_CLK
> 100: 1/16 of DEV_CLK
> 101: 1/32 of DEV_CLK
> 110: 1/64 of DEV_CLK
> 111: 1/128 of DEV_CLK
> This field must be set to 0 when the controller works during normal
> writing or reading.
> 
> So the 7 means 1/128 which would be ~273 kHz.
> 
> 1. can we find out what U-Boot assumes for this divisor?
> (probably yes: read 0x13460008 = JZ_REG_MMC_CLKRT)

As far as I can see, there is only one writel()/readl() to the MSC controller
during probe, doing a jz4740_mmc_reset().

Then the next call should be jz4740_mmc_set_clock_rate().

So I added the printk for the next item also to jz4740_mmc_reset() before
and after doing a reset.

> 
> 2. this strengthens the theory that the MSC is in low power mode
> Which register can we read to get the status?
> jz4740_mmc_set_clock_rate() is a good location for printing
> all registers w/o ioremap (the MSC base address is known!)

Here is a dump of all MSC registers, before/after jz4740_mmc_reset()
and before/after jz4740_mmc_set_clock_rate():

[    0.000206] jz4740_mmc_probe
[    0.000206] jz4740_mmc_reset before
[    0.000206]    JZ_REG_MMC_STRPCL: b3450000 = 00000000
[    0.000206]    JZ_REG_MMC_STATUS: b3450004 = 1f000040
[    0.000206]     JZ_REG_MMC_CLKRT: b3450008 = 00000000
[    0.000206]     JZ_REG_MMC_CMDAT: b345000c = 00000409
[    0.000206]     JZ_REG_MMC_RESTO: b3450010 = 00000100
[    0.000206]      JZ_REG_MMC_RDTO: b3450014 = ffffffff
[    0.000206]    JZ_REG_MMC_BLKLEN: b3450018 = 00000200
[    0.000206]       JZ_REG_MMC_NOB: b345001c = 00000001
[    0.000206]      JZ_REG_MMC_SNOB: b3450020 = 00000001
[    0.000206]     JZ_REG_MMC_IMASK: b3450024 = ffffffff
[    0.000206]      JZ_REG_MMC_IREG: b3450028 = 00002000
[    0.000206]       JZ_REG_MMC_ARG: b3450030 = 0000678d
[    0.000206] JZ_REG_MMC_RESP_FIFO: b3450034 = 00005900
[    0.000206]    JZ_REG_MMC_RXFIFO: b3450038 = 00000000
[    0.000206]    JZ_REG_MMC_TXFIFO: b345003c = 00000000
[    0.000206]       JZ_REG_MMC_LPM: b3450040 = 80000001
[    0.000206]      JZ_REG_MMC_DMAC: b3450044 = 00000000
[    0.000206]     JZ_REG_MMC_DMADA: b345004c = 00000000
[    0.000206]    JZ_REG_MMC_DMALEN: b3450050 = 00000000
[    0.000206]    JZ_REG_MMC_DMACMD: b3450054 = 00000000
[    0.000206]     JZ_REG_MMC_CTRL2: b3450058 = 00800000
[    0.000206]     JZ_REG_MMC_RTCNT: b345005c = 00000000
[    0.000206] MSC reset did timeout!!!
[    0.000206] jz4740_mmc_reset after (timeout = 0)
[    0.000206]    JZ_REG_MMC_STRPCL: b3450000 = 00000000
[    0.000206]    JZ_REG_MMC_STATUS: b3450004 = 1f008040
[    0.000206]     JZ_REG_MMC_CLKRT: b3450008 = 00000000
[    0.000206]     JZ_REG_MMC_CMDAT: b345000c = 00005000
[    0.000206]     JZ_REG_MMC_RESTO: b3450010 = 00000100
[    0.000206]      JZ_REG_MMC_RDTO: b3450014 = 00ffffff
[    0.000206]    JZ_REG_MMC_BLKLEN: b3450018 = 00000000
[    0.000206]       JZ_REG_MMC_NOB: b345001c = 00000000
[    0.000206]      JZ_REG_MMC_SNOB: b3450020 = 00000001
[    0.000206]     JZ_REG_MMC_IMASK: b3450024 = ffffffff
[    0.000206]      JZ_REG_MMC_IREG: b3450028 = 00002000
[    0.000206]       JZ_REG_MMC_ARG: b3450030 = 00000000
[    0.000206] JZ_REG_MMC_RESP_FIFO: b3450034 = 00001100
[    0.000206]    JZ_REG_MMC_RXFIFO: b3450038 = 00000000
[    0.000206]    JZ_REG_MMC_TXFIFO: b345003c = 00000000
[    0.000206]       JZ_REG_MMC_LPM: b3450040 = 00000000
[    0.000206]      JZ_REG_MMC_DMAC: b3450044 = 00000000
[    0.000206]     JZ_REG_MMC_DMADA: b345004c = 00000000
[    0.000206]    JZ_REG_MMC_DMALEN: b3450050 = 00000000
[    0.000206]    JZ_REG_MMC_DMACMD: b3450054 = 00000000
[    0.000206]     JZ_REG_MMC_CTRL2: b3450058 = 00800000
[    0.000206]     JZ_REG_MMC_RTCNT: b345005c = 00000000
[    0.000206] mmc0: clock 0Hz busmode 2 powermode 1 cs 0 Vdd 21 width 1 timing 0
[    0.000206] jz4740_mmc_set_ios
[    0.000206] jz4740_mmc_set_ios: MMC_POWER_UP
[    0.000206] jz4740_mmc_reset before
[    0.000206]    JZ_REG_MMC_STRPCL: b3450000 = 00000000
[    0.000206]    JZ_REG_MMC_STATUS: b3450004 = 1f000040
[    0.000206]     JZ_REG_MMC_CLKRT: b3450008 = 00000000
[    0.000206]     JZ_REG_MMC_CMDAT: b345000c = 00005000
[    0.000206]     JZ_REG_MMC_RESTO: b3450010 = 00000100
[    0.000206]      JZ_REG_MMC_RDTO: b3450014 = 00ffffff
[    0.000206]    JZ_REG_MMC_BLKLEN: b3450018 = 00000000
[    0.000206]       JZ_REG_MMC_NOB: b345001c = 00000000
[    0.000206]      JZ_REG_MMC_SNOB: b3450020 = 00000001
[    0.000206]     JZ_REG_MMC_IMASK: b3450024 = ffffffff
[    0.000206]      JZ_REG_MMC_IREG: b3450028 = 00002000
[    0.000206]       JZ_REG_MMC_ARG: b3450030 = 00000000
[    0.000206] JZ_REG_MMC_RESP_FIFO: b3450034 = 00001100
[    0.000206]    JZ_REG_MMC_RXFIFO: b3450038 = 00000000
[    0.000206]    JZ_REG_MMC_TXFIFO: b345003c = 00000000
[    0.000206]       JZ_REG_MMC_LPM: b3450040 = 00000000
[    0.000206]      JZ_REG_MMC_DMAC: b3450044 = 00000000
[    0.000206]     JZ_REG_MMC_DMADA: b345004c = 00000000
[    0.000206]    JZ_REG_MMC_DMALEN: b3450050 = 00000000
[    0.000206]    JZ_REG_MMC_DMACMD: b3450054 = 00000000
[    0.000206]     JZ_REG_MMC_CTRL2: b3450058 = 00800000
[    0.000206]     JZ_REG_MMC_RTCNT: b345005c = 00000000
[    0.000206] MSC reset did timeout!!!
[    0.000206] jz4740_mmc_reset after (timeout = 0)
[    0.000206]    JZ_REG_MMC_STRPCL: b3450000 = 00000000
[    0.000206]    JZ_REG_MMC_STATUS: b3450004 = 1f008040
[    0.000206]     JZ_REG_MMC_CLKRT: b3450008 = 00000000
[    0.000206]     JZ_REG_MMC_CMDAT: b345000c = 00005000
[    0.000206]     JZ_REG_MMC_RESTO: b3450010 = 00000100
[    0.000206]      JZ_REG_MMC_RDTO: b3450014 = 00ffffff
[    0.000206]    JZ_REG_MMC_BLKLEN: b3450018 = 00000000
[    0.000206]       JZ_REG_MMC_NOB: b345001c = 00000000
[    0.000206]      JZ_REG_MMC_SNOB: b3450020 = 00000001
[    0.000206]     JZ_REG_MMC_IMASK: b3450024 = ffffffff
[    0.000206]      JZ_REG_MMC_IREG: b3450028 = 00002000
[    0.000206]       JZ_REG_MMC_ARG: b3450030 = 00000000
[    0.000206] JZ_REG_MMC_RESP_FIFO: b3450034 = 00001100
[    0.000206]    JZ_REG_MMC_RXFIFO: b3450038 = 00000000
[    0.000206]    JZ_REG_MMC_TXFIFO: b345003c = 00000000
[    0.000206]       JZ_REG_MMC_LPM: b3450040 = 00000000
[    0.000206]      JZ_REG_MMC_DMAC: b3450044 = 00000000
[    0.000206]     JZ_REG_MMC_DMADA: b345004c = 00000000
[    0.000206]    JZ_REG_MMC_DMALEN: b3450050 = 00000000
[    0.000206]    JZ_REG_MMC_DMACMD: b3450054 = 00000000
[    0.000206]     JZ_REG_MMC_CTRL2: b3450058 = 00800000
[    0.000206]     JZ_REG_MMC_RTCNT: b345005c = 00000000
[    0.000206] mmc0: clock 400000Hz busmode 2 powermode 2 cs 0 Vdd 21 width 1 timing 0
[    0.000206] jz4740_mmc_set_ios
[    0.000206] jz4740_mmc_set_clock_rate: registers before
[    0.000206]    JZ_REG_MMC_STRPCL: b3450000 = 00000000
[    0.000206]    JZ_REG_MMC_STATUS: b3450004 = 1f008040
[    0.000206]     JZ_REG_MMC_CLKRT: b3450008 = 00000000
[    0.000206]     JZ_REG_MMC_CMDAT: b345000c = 00005000
[    0.000206]     JZ_REG_MMC_RESTO: b3450010 = 00000100
[    0.000206]      JZ_REG_MMC_RDTO: b3450014 = 00ffffff
[    0.000206]    JZ_REG_MMC_BLKLEN: b3450018 = 00000000
[    0.000206]       JZ_REG_MMC_NOB: b345001c = 00000000
[    0.000206]      JZ_REG_MMC_SNOB: b3450020 = 00000001
[    0.000206]     JZ_REG_MMC_IMASK: b3450024 = ffffffff
[    0.000206]      JZ_REG_MMC_IREG: b3450028 = 00002000
[    0.000206]       JZ_REG_MMC_ARG: b3450030 = 00000000
[    0.000206] JZ_REG_MMC_RESP_FIFO: b3450034 = 00001100
[    0.000206]    JZ_REG_MMC_RXFIFO: b3450038 = 00000000
[    0.000206]    JZ_REG_MMC_TXFIFO: b345003c = 00000000
[    0.000206]       JZ_REG_MMC_LPM: b3450040 = 00000000
[    0.000206]      JZ_REG_MMC_DMAC: b3450044 = 00000000
[    0.000206]     JZ_REG_MMC_DMADA: b345004c = 00000000
[    0.000206]    JZ_REG_MMC_DMALEN: b3450050 = 00000000
[    0.000206]    JZ_REG_MMC_DMACMD: b3450054 = 00000000
[    0.000206]     JZ_REG_MMC_CTRL2: b3450058 = 00800000
[    0.000206]     JZ_REG_MMC_RTCNT: b345005c = 00000000
[    0.000206] jz4740_mmc_set_clock_rate: clk_set_rate(50000000)
[    0.000206] jz4740_mmc_set_clock_rate: real_rate=35000000
[    0.000206] jz4740_mmc_set_clock_rate: writew(00000007, JZ_REG_MMC_CLKRT)
[    0.000206] jz4740_mmc_set_clock_rate: registers after
[    0.000206]    JZ_REG_MMC_STRPCL: b3450000 = 00000000
[    0.000206]    JZ_REG_MMC_STATUS: b3450004 = 1f000040
[    0.000206]     JZ_REG_MMC_CLKRT: b3450008 = 00000007
[    0.000206]     JZ_REG_MMC_CMDAT: b345000c = 00005000
[    0.000206]     JZ_REG_MMC_RESTO: b3450010 = 00000100
[    0.000206]      JZ_REG_MMC_RDTO: b3450014 = 00ffffff
[    0.000206]    JZ_REG_MMC_BLKLEN: b3450018 = 00000000
[    0.000206]       JZ_REG_MMC_NOB: b345001c = 00000000
[    0.000206]      JZ_REG_MMC_SNOB: b3450020 = 00000001
[    0.000206]     JZ_REG_MMC_IMASK: b3450024 = ffffffff
[    0.000206]      JZ_REG_MMC_IREG: b3450028 = 00002000
[    0.000206]       JZ_REG_MMC_ARG: b3450030 = 00000000
[    0.000206] JZ_REG_MMC_RESP_FIFO: b3450034 = 00001100
[    0.000206]    JZ_REG_MMC_RXFIFO: b3450038 = 00000000
[    0.000206]    JZ_REG_MMC_TXFIFO: b345003c = 00000000
[    0.000206]       JZ_REG_MMC_LPM: b3450040 = 00000000
[    0.000206]      JZ_REG_MMC_DMAC: b3450044 = 00000000
[    0.000206]     JZ_REG_MMC_DMADA: b345004c = 00000000
[    0.000206]    JZ_REG_MMC_DMALEN: b3450050 = 00000000
[    0.000206]    JZ_REG_MMC_DMACMD: b3450054 = 00000000
[    0.000206]     JZ_REG_MMC_CTRL2: b3450058 = 00800000
[    0.000206]     JZ_REG_MMC_RTCNT: b345005c = 00000000
[    0.000206] jz4740_mmc_set_ios: MMC_POWER_ON

Now the buffet is opened for interpretations :)

BR,
Nikolaus

PS: an important observation is that the reset times out...
The IS_RESETTING bit (BIT(15) @ b3450004) is still "1".
But before the next run it is "0".

IMHO the udelay(10) should be inside the waiting loop.
Or the timeout speed depends heavily on the processor type.

This bug was right from the beginning in 61bfbdb856879c
Maybe I'll post a Fixes: patch...



More information about the Letux-kernel mailing list