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

H. Nikolaus Schaller hns at goldelico.com
Sun Feb 11 17:55:59 CET 2024


Paul,

> Am 11.02.2024 um 17:40 schrieb Paul Boddie <paul at boddie.org.uk>:
> 
> On Sunday, 11 February 2024 17:26:34 CET H. Nikolaus Schaller wrote:
>> 
>> What I assume is that 1-bit mode may run generally slower or some cards
>> may be more robust to overclocking in 1-bit mode than in 4 bit mode (where
>> e.g. alignment of 4 data bits to a clock line must be guaranteed).
>> 
>> Since I have everything working well in 4 bit mode just with slower clock we
>> can IMHO focus on the clock setup now.
> 
> Well, I just managed to fix a mistake I had made sending application-specific 
> commands to the card, so I can now select 4-bit mode. This is in my own 
> software framework that I am using for testing and investigation.
> 
> What I can report is that since I am not changing the clock configuration for 
> MSC0, thus leaving it as U-Boot left it, it is supposedly running at 50MHz. 
> For initialisation, I divide the device clock by 128 to yield 390.625kHz for 
> the bus clock, which is close to the recommended 400kHz. Then, for transfers I 
> have been testing with a divider of 2, which is the suggested 25MHz for a card 
> of the type you sent me.

This is the divisor "7" (for ~400kHz) calculated by jz4740_mmc_set_clock_rate():

https://elixir.bootlin.com/linux/v6.8-rc3/source/drivers/mmc/host/jz4740_mmc.c#L893

400 kHz is the first low-speed real_rate which is tried (then 200 and then 100 kHz).

If mmc->f_max is 50 MHz, this ends up in a divisor of 7 which should be /128.
And once I got a readback of 

[    0.000201] mmc0: mmc_rescan_try_freq: trying to init card at 390625 Hz

But I did see something like 3.5 MHz with the scope.

So I guess the jz4740_mmc driver is doing the right thing.

But we don't know if clk_set_rate() is physically doing the right thing. We just
ask the CGU driver for clk_get_rate() and it might tell us fairy tales.

This leads to an interesting idea. I could just print all relevant CGU registers for
MSC0 *before* and *after* the clk_set_rate() call (in the broken setup).

Then we can verify the divisor calculations and gate switches and what this
clk_set_rate() is doing.

Could you easily find out which CGU registers are to be looked at for MSC0?

> 
> So, in principle, all of this should work in Linux, but I imagine that I need 
> to review the CGU code and make sure it works as it should.

I think the mmc driver itself is fine. It is somewhere in clock setup not
doing what told and just doing the inverse mistake if asked.

BR,
Nikolaus



More information about the Letux-kernel mailing list