[Letux-kernel] [PATCH 00/20] A bunch of JZ4730 fixups for letux-kernel
H. Nikolaus Schaller
hns at goldelico.com
Sun Dec 20 23:13:17 CET 2020
> Am 20.12.2020 um 22:17 schrieb Paul Boddie <paul at boddie.org.uk>:
>
> On Sunday, 20 December 2020 21:26:48 CET H. Nikolaus Schaller wrote:
>>
>> I have tried and now I have
>>
>> [ 0.183531] reg: 10010004: 08200200
>>
>> instead of e.g.
>>
>> [ 0.197738] reg: 10010004: 08000200
>>
>> And now I can see the VDD of the SD card jump to 3.3V for a short moment.
>> But the mmc driver is still waiting for the SD card.
>>
>> So our problem is the GPIO direction register. Maybe it is a general
>> problem...
>>
>> I have now tried to understand, and yes it is very different from OMAP.
>> I had expected some drivers/gpio/ingenic or similar. But it uses
>> pinctrl/pinctrl-ingenic.c
>>
>> There we have a mix of pinmux and gpio control. But all things are in
>> place like ingenic_gpio_direction_output(), ingenic_gpio_get(),
>> ingenic_gpio_set().
>
> One thing that occurs to me is that in the ingenic_pinmux_set_pin_fn function
> in pinctrl-ingenic.c, I shouldn't be changing the port direction:
>
> } else if (jzpc->info->version == ID_JZ4730) {
> ingenic_config_pin(jzpc, pin, JZ4730_GPIO_GPIER, false);
> ingenic_config_pin(jzpc, pin, JZ4730_GPIO_GPDIR, false);
> ingenic_config_pin_function(jzpc, pin, JZ4730_GPIO_GPAUR,
> JZ4730_GPIO_GPALR, func & 0x3);
>
> Here, the JZ4730_GPIO_GPDIR bit clearing operation is largely irrelevant to
> the broader operation. And it occurs to me that even if something is setting
> the function to zero (GPIO), they might have set the direction before setting
> the function, even though that wouldn't make much sense.
>
> So, by clearing the direction bit for the pin (making it an input), although
> this resets the default state of the pin, it might disrupt some configuration
> attempts which set the direction before the function. And a remedy for this
> might be to just remove that statement and see what happens.
>
> The JZ4740 code only changes the function, trigger and select registers. The
> JZ4730 combines the function and select registers into the GPAUR and GPALR
> registers, distributing the pins across those registers instead of having one
> register (function) to indicate whether the pin uses an alternate function or
> not, and another register (select) to indicate which function. And the JZ4730
> equivalent to the trigger register is GPIER. So, the direction isn't changed
> in the JZ4740 code.
Yes,
I was just writing a longer mail with my findings but here is the important
part.
[ 0.047556] vcc: 3300 mV, enabled
[ 0.052047] reg-fixed-voltage regulator at 0: vcc supplying 3300000uV
[ 0.059335] ingenic_gpio_set: off=21, val=1
[ 0.046211] ingenic_gpio_set_value: offset=15, value=1
[ 0.051614] pinctrl-ingenic 10010000.pin-controller: set pin PA21 to output
[ 0.058831] ingenic_config_pin: pin=21, reg=20 set=0
[ 0.046447] ingenic_config_pin: idx=15, offt=0
[ 0.051098] ingenic_config_pin: regmap update roff=20, bits=00200000 val=00000000
[ 0.058932] ingenic_config_pin: pin=21, reg=4 set=1
[ 0.064003] ingenic_config_pin: idx=15, offt=0
[ 0.051087] ingenic_config_pin: regmap update roff=4, bits=00200000 val=00200000
[ 0.058856] ingenic_config_pin_function: pin=21, reg=14:10 value=0
[ 0.065394] vmmc: 3300 mV, disabled
[ 0.052437] reg-fixed-voltage regulator at 1: vmmc supplying 3300000uV
ingenic_config_pin is firstly setting the registers 0x20 and 0x04 and then
setting the pin_function. If that one resets the direction we will not see
it...
But - there is something else:
I have also added (not yet in the snippet above) an ioremap and printk before
and after updating in ingenic_pinmux_gpio_set_direction().
This is the initial value from U-Boot.
[ 0.059224] reg: 10010004 28200200
It is not even changed by initializing the regulator.
But then it is suddenly reset:
[ 0.435235] ingenic_gpio_get_value: offset=0
[ 0.439918] pinctrl-ingenic 10010000.pin-controller: set pin PA1 to input
[ 0.429403] reg: 10010004 28200200
[ 0.433025] ingenic_config_pin: pin=1, reg=20 set=0
[ 0.438105] ingenic_config_pin: idx=1, offt=0
[ 0.442667] ingenic_config_pin: regmap update roff=20, bits=00000002 val=00000000
[ 0.432912] ingenic_config_pin: pin=1, reg=4 set=0
[ 0.437924] ingenic_config_pin: idx=1, offt=0
[ 0.442486] ingenic_config_pin: regmap update roff=4, bits=00000002 val=00000000
[ 0.450202] ingenic_config_pin_function: pin=1, reg=14:10 value=0
[ 0.438978] reg: 10010004 28200200
[ 0.442621] ingenic_gpio_get_value: offset=1
[ 0.447325] pinctrl-ingenic 10010000.pin-controller: set pin PA2 to input
[ 0.454352] reg: 10010004 00000000
[ 0.440416] ingenic_config_pin: pin=2, reg=20 set=0
[ 0.445517] ingenic_config_pin: idx=2, offt=0
[ 0.450079] ingenic_config_pin: regmap update roff=20, bits=00000004 val=00000000
[ 0.457878] ingenic_config_pin: pin=2, reg=4 set=0
[ 0.445321] ingenic_config_pin: idx=2, offt=0
[ 0.449903] ingenic_config_pin: regmap update roff=4, bits=00000004 val=00000000
[ 0.457623] ingenic_config_pin_function: pin=2, reg=14:10 value=0
[ 0.446383] reg: 10010004 00000000
[ 0.450025] ingenic_gpio_get_value: offset=2
[ 0.454760] pinctrl-ingenic 10010000.pin-controller: set pin PA3 to input
[ 0.461791] reg: 10010004 00000000
After a while it builds up again to
[ 0.197738] reg: 10010004: 08000200
Maybe the regmap is broken...
Or some parallel process is writing to the wrong address.
If it is something else it should show itself by different timing.
But that will really be hard to find without JTAG.
A first check makes it appear to be reproducible between PA1 and PA2.
I'll try to confirm in the next days.
BR,
Nikolaus
More information about the Letux-kernel
mailing list