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

H. Nikolaus Schaller hns at goldelico.com
Sat Feb 10 13:25:04 CET 2024


Here some first analysis

> Am 09.02.2024 um 19:27 schrieb H. Nikolaus Schaller <hns at goldelico.com>:
> 
> 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

0x1f are the pin states for CMD and D3..D0, obviously pulled up
0x40 is the DATA_FIFO_EMPTY

===> looks good.

> [    0.000206]     JZ_REG_MMC_CLKRT: b3450008 = 00000000

0 means undivided DEV_CLK
===> U-Boot uses a different divider (but was probably initialized
to high speed mode)

> [    0.000206]     JZ_REG_MMC_CMDAT: b345000c = 00000409

This must be remaining from U-Boot setup.
4 means 4-bit operation
9 means DATA_EN and response format R2.

===> This is reset later.

> [    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

all register above are related to data transfer

> [    0.000206]     JZ_REG_MMC_IMASK: b3450024 = ffffffff

no interrupt masked (default)

> [    0.000206]      JZ_REG_MMC_IREG: b3450028 = 00002000

DATA_FIFO_EMP detected

> [    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

all registers above are FIFO related

> [    0.000206]       JZ_REG_MMC_LPM: b3450040 = 80000001

bit 31:30 0: CMD and data are driven by MSC_CLK falling edge
bit 29 0: CMD and data are sampled by MSC_CLK rising edge

===> this makes me wonder if CMD is bidirectional?
Could explain the strange signals seen with scope, if MSC and
µSD are fighting who can write a bit...

bit 0: 1: Enable low power mode

Note from PM:
Clock will stop when card in idle (should be normally set to only MMC
and SD cards. For SDIO cards, if interrupts must be detected, clock
should not be stopped)
When software sets the bit, MSC clock can auto be stopped.
NOTE: when set the bit, the clock start and stop can be not use.

===> MSC is in LPM by U-Boot

driver code will change this ONLY in jz4740_mmc_set_clock_rate
if real_rate > 2500000 (which we did not see yet). Otherwise
it remains unchanged

> [    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

all registers above are DMA related

> [    0.000206]     JZ_REG_MMC_CTRL2: b3450058 = 00800000

default speed

> [    0.000206]     JZ_REG_MMC_RTCNT: b345005c = 00000000

FIFO empty.

> [    0.000206] MSC reset did timeout!!!
> [    0.000206] jz4740_mmc_reset after (timeout = 0)

this is strange that we see a timeout.

> [    0.000206]    JZ_REG_MMC_STRPCL: b3450000 = 00000000
> [    0.000206]    JZ_REG_MMC_STATUS: b3450004 = 1f008040

here, IS_RESETTING is still active.

> [    0.000206]     JZ_REG_MMC_CLKRT: b3450008 = 00000000
> [    0.000206]     JZ_REG_MMC_CMDAT: b345000c = 00005000

has been reset to default

> [    0.000206]     JZ_REG_MMC_RESTO: b3450010 = 00000100
> [    0.000206]      JZ_REG_MMC_RDTO: b3450014 = 00ffffff

has been reset to default

> [    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

"Contains the response to the command that is sent by the MMC/SD controller."

> [    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

no changes or reset to default

> [    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

no idea why the MSC is being reset twice. First one was from
inside jz4740_mmc_probe()

> [    0.000206]    JZ_REG_MMC_STRPCL: b3450000 = 00000000
> [    0.000206]    JZ_REG_MMC_STATUS: b3450004 = 1f000040

here the MSC reports IS_RESETTING being finished now.
But that was not during the first reset attempt.

> [    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

no other register did change since after the first reset.

> [    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

here it still times out and status is still resetting.

> [    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

now we set the clock rate

> [    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

no register changed since second reset

> [    0.000206] jz4740_mmc_set_clock_rate: clk_set_rate(50000000)
> [    0.000206] jz4740_mmc_set_clock_rate: real_rate=35000000

this is too low to modify LPM mode setting

> [    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

again, IS_RESETTING did end now

> [    0.000206]     JZ_REG_MMC_CLKRT: b3450008 = 00000007

here, the new clock divider was written.

> [    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

no change in any other register

> [    0.000206] jz4740_mmc_set_ios: MMC_POWER_ON
> 
> Now the buffet is opened for interpretations :)

Well, such strange effects like the RESET could happen if
the MSC state engine is running at wrong clock rate.

But I already had tried to make the loop for IS_RESETTING
end after 10 seconds. It waits but the bit is still active.

So some other activity triggers a reset of this bit.

Otherwise I could try to trace if clock is being enabled
and if this changes the CLK_EN bit in JZ_REG_MMC_STATUS.

BR,
Nikolaus



More information about the Letux-kernel mailing list