Netgear Orbi Pro support-booting from MMC

[    1.887991] sdhci_msm 7824900.sdhci: No vreg data found for vdd
[    1.888021] sdhci_msm 7824900.sdhci: No vreg data found for vdd-io
[    1.892743] sdhci_msm 7824900.sdhci: Parsing Pinctrl failed with -19, falling back on GPIO lib

They all seem to be generated by the sdhci-msm2.c code and that driver seems to suffers from bit-rot.

Well, if you want to push forward: a "very nice" thing to do would be to get it working with the sdhci-msm.c driver. This will probably involve making patches (and putting in some effort in trying to upstream them too).
That said, I know that dealing with QCA is anything but fun.

But keep in mind, I don't have a unit with emmc... "so what do i know", right?!

Yeah, I would really like to get it working with the upstream driver since that will make everybody's life easier and its really making no sense that QCA sent a patch upstream to add sdhci node to the dk04.1.dtsi.

My C skills are not really driver level so if everything works I will try to get it merged in this state.
If it does not get accepted I will still use it for my own home AP since stock firmware tends to crash every 12 or so hours and wireless radio stops working

Ah, I misunderstood what you meant.

I think I can help you atleast a bit. In your original post, the upstream sdhci-msm driver didn't load because of

[    1.824205] sdhci_msm 7824900.sdhci: Get pwr_irq failed (-6)

this happen because the dts didn't have the:

interrupt-names = "hc_irq", "pwr_irq";

property set.

there was also:

[    1.810974] sdhci_msm 7824900.sdhci: TCXO clk not present (-2)
[    1.818299] sdhci_msm 7824900.sdhci: core clock boost failed

but these messages are not fatal.

By the way: Can you please tell me which major & minor version the sdhci controller has? The driver has dev_dbg(...) in place to print them out:

do you have this information somewhere? Thanks.

[    4.970098] sdhci_msm 7824900.sdhci: Host Version: 0x4202 Vendor Version 0x42
[    4.975318] sdhci_msm 7824900.sdhci: MCI Version: 0x10000042, major: 0x0001, minor: 0x42

(Does this match yours? - I might not have a IPQ40xx which uses emmc - but it's integrated in the SoC.)

Thanks for the suggestion,
I gotta test it out.

Hm,upstream driver did not print out any version info.

Johns driver prints out this debug table:

True, it doesn't show up on the console unless you mess with the debug level or replace dev_dbg with dev_info/warn/err. dev_dbg can show up in dmesg too (as long as the dynamic debug stuff doesn't disable it).

As for the sdhci-msm. The upstream driver does have some code for it in place. Maybe it was just related to the dts? I looked at the older dts definition again. Maybe it's just the clocks?

       sdhci: sdhci@7824000 {
              compatible = "qcom,sdhci-msm-v4";
              reg = <0x7824900 0x11c>, <0x7824000 0x800>;
              reg-names = "hc_mem", "core_mem";
              interrupts = <GIC_SPI 123 IRQ_TYPE_NONE>, <GIC_SPI 138 IRQ_TYPE_NONE>;
              interrupt-names = "hc_irq", "pwr_irq";
              bus-width = <8>;
              clocks = <&gcc GCC_SDCC1_APPS_CLK>, <&gcc GCC_SDCC1_AHB_CLK>, <&xo>;
              clock-names = "core", "iface", "xo";
     };

(Not sure, what to do with the regulator though. That said, u-boot might already sets it up properly, so you could get away with it as long as you don't touch it).

Hm,I will test out the upstream driver and try couple of combinations with the DTS definition.
I think it is mainly crashing due to hc_ir and pwr_irq.

Bootloader does not set the regulator as the GPL source also has regulator node.

Qualcomm attempted to push upstream patch to add sdhci node to qcom-ipq4019-ap.dk04.1.dtsi
And their definition is surely not working.
https://patchwork.kernel.org/patch/8748561/

New errors this time:
sdhci_msm 7824900.sdhci: Peripheral clk setup failed (-2)
sdhci_msm: probe of 7824900.sdhci failed with error -2

I think that that is due to clock naming in the node

With this sdhci node in dtsi:

sdhc_1: sdhci@7824000 {
compatible = "qcom,sdhci-msm-v4";
reg = <0x7824900 0x11c>, <0x7824000 0x800>;
reg-names = "hc_mem", "core_mem";
interrupts = <0 123 0>, <0 138 0>;
interrupt-names = "hc_irq", "pwr_irq";
qcom,bus-width = <8>;
qcom,max_clk = <192000000>;
clocks = <&gcc GCC_SDCC1_APPS_CLK>,
<&gcc GCC_SDCC1_AHB_CLK>;
clock-names = "core_clk", "iface_clk";
qcom,large-address-bus;
status = "disabled";
};

And now some now errors:
[ 1.758189] sdhci: Secure Digital Host Controller Interface driver
[ 1.762496] sdhci: Copyright(c) Pierre Ossman
[ 1.769064] sdhci-pltfm: SDHCI platform and OF driver helper
[ 1.779300] sdhci_msm 7824900.sdhci: Got CD GPIO
[ 1.780586] sdhci_msm 7824900.sdhci: TCXO clk not present (-2)
[ 1.784521] sdhci_msm 7824900.sdhci: core clock boost failed
[ 1.832999] mmc0: Failed to set clock at rate 400000 at timing 0
[ 1.833219] mmc0: Failed to set clock at rate 400000 at timing 0
[ 1.865668] mmc0: SDHCI controller on 7824900.sdhci [7824900.sdhci] using ADMA 64-bit
[ 1.871679] mmc0: Failed to set clock at rate 400000 at timing 0
[ 1.875282] mmc0: Failed to set clock at rate 400000 at timing 0
[ 1.882324] mmc0: Failed to set clock at rate 400000 at timing 0
[ 1.884092] NET: Registered protocol family 10
[ 1.885919] Segment Routing with IPv6
[ 1.886031] NET: Registered protocol family 17
[ 1.886525] 8021q: 802.1Q VLAN Support v1.8
[ 1.886571] Registering SWP/SWPB emulation handler
[ 1.892041] hctosys: unable to open rtc dev�[ 1.917079] mmc0: Failed to set clock at rate 400000 at timing 0
[ 1.917144] mmc0: Failed to set clock at rate 400000 at timing 0
[ 1.925407] mmc0: Failed to set clock at rate 400000 at timing 0
[ 1.936386] Freeing unused kernel memory: 10240K
[ 1.945241] init: Console is alive
[ 1.945451] init: - watchdog -
[ 1.953155] mmc0: error -110 whilst initialising MMC card

Those are after changing clock names to following per bindings
clock-names = “core”, “iface”;

I suspect that we now I am missing advertising speed rates as qcom,bus and qcom,rates are not in the upstream driver.

And the latest bootlog:

As per this branch:https://github.com/robimarko/openwrt/tree/Netgear-Orbi-Pro-upstream-sdhci

I have run of the ideas for today.
Feel free to throw some as I can feel that we are close to getting it work.

Yeah, can confirm that for whatever reason this happens alot. As I wrote above: the NAND was also not working. But we managed to get hold of QCA back then and they were able to fix it.

Weird, isn't the Orbi's kernel image stored on the emmc? If so, how can u-boot manage to load the kernel from the emmc without initializing the sdhci + regulator?

As for the "easy" fixes:

At least this should be fixed with the clocks + clock-name definition above. At least it wasn't showing them anymore in my bootlog.

[    5.389582] sdhci-pltfm: SDHCI platform and OF driver helper
[    5.397116] sdhci_msm 7824900.sdhci: Host Version: 0x4202 Vendor Version 0x42
[    5.399772] sdhci_msm 7824900.sdhci: MCI Version: 0x10000042, major: 0x0001, minor: 0x42
[    5.410294] sdhci_msm 7824900.sdhci: mmc0: clock=0 uhs=0 ctrl_2=0x0
[    5.459569] mmc0: Failed to set clock at rate 400000 at timing 0
[    5.459926] sdhci_msm 7824900.sdhci: mmc0: clock=400000 uhs=0 ctrl_2=0x0

The "core clock boost failed" message:

[    4.966980] sdhci_msm 7824900.sdhci: core clock boost failed

is generated because the sdhci-msm.c driver tries to set the frequency to INT_MAX:

You could try to set this to 192000000 (192 MHz) instead of INT_MAX. This should silence the message as well. But I have no idea if this is enough.

Ok,added the xo clock and that error is gone.
As for the core boost I already had maximum frequency at 192 Mhz and the same error is present.
sdhci_msm 7824900.sdhci: card claims to support voltages below defined range is a weird error as I advertised the same speed and voltage as John did,but just in a upstream property.
Yes,bootloader has to set it.
I can try without the regulator but I doubt that it will change anything

[    1.758504] sdhci: Secure Digital Host Controller Interface driver
[    1.762832] sdhci: Copyright(c) Pierre Ossman
[    1.768986] sdhci-pltfm: SDHCI platform and OF driver helper
[    1.773963] sdhci_msm 7824900.sdhci: core clock boost failed
[    1.823720] mmc0: Failed to set clock at rate 400000 at timing 0
[    1.824041] mmc0: Failed to set clock at rate 400000 at timing 0
[    1.853984] mmc0: SDHCI controller on 7824900.sdhci [7824900.sdhci] using ADMA 64-bit
[    1.859788] mmc0: Failed to set clock at rate 400000 at timing 0
[    1.863628] mmc0: Failed to set clock at rate 400000 at timing 0
[    1.869425] mmc0: Failed to set clock at rate 400000 at timing 0
[    1.873544] sdhci_msm 7824900.sdhci: card claims to support voltages below defined range
[    1.879170] mmc0: Failed to set clock at rate 400000 at timing 0
[    1.887534] mmc0: Failed to set clock at rate 400000 at timing 0
[    1.896909] mmc0: Failed to set clock at rate 400000 at timing 0
[    1.904853] NET: Registered protocol family 10
[    1.906335] Segment Routing with IPv6
[    1.909324] NET: Registered protocol family 17
[    1.913417] 8021q: 802.1Q VLAN Support v1.8
[    1.917354] Registering SWP/SWPB emulation handler
[    1.925560] mmc0: error -110 whilst initialising MMC card

Yeah, sadly setting the max-frequency = <1920000000>; won't do it. The sdhci's core/host.c parses the property and just sets host->f_max.

However, the sdhci-msm.c driver does not do anything with the value. Instead tries INT_MAX:

which is why it fails.

if this was wired up correctly it could(but doesn't have to) look like:

ret = clk_set_rate(clk, host->mmc->f_max);

or (this will retain compatibility in case the max-frequency property wasn't set).

ret = clk_set_rate(clk, host->mmc->f_max ? : INT_MAX);

(or a longer version that might be preferred by the maintainers)

ret = clk_set_rate(clk, (host->mmc->f_max > 0) ? host->mmc->f_max : INT_MAX);

If you look in John's emmc the driver does it like this:

   u32 max_clk;
   [...]
   np = pdev->dev.of_node;
   if (of_property_read_u32(np, "qcom,max_clk", &max_clk))
           max_clk = sdhci_msm_get_min_clock(host);

   /* Set to the maximum supported clock frequency */
   ret = clk_set_rate(msm_host->clk, max_clk);

https://git.openwrt.org/?p=openwrt/staging/blogic.git;a=blob;f=target/linux/ipq806x/patches-4.9/314-ipq4019-emmc.patch;h=2799ac8c202df7b78894def62dd5cbfa771ece9e;hb=6a64b4b056175c9e2cc5397240b38b188d674240#l2510

And yes, this is a bug/problem in the upstream driver. The question is: is this the deal breaker or not.

I would need some actual ipq40xx hardware with a emmc to look into this. All I can say from afar is: It might need some sort of vqmmc supply property. If you have John's regulator patched in and dts definition around, you could try to
add the

vqmmc-supply = <&vccq_sd0>;

property to sdhci node. Maybe it helps, maybe not.

Edit:
Another possibility for the regulators would be to define a dummy-regulator via the fixed-regulator binding and set it to whatever you need. (this will work as long as something has setup the regulator hardware correctly and the driver does not need to change it).

Hm,I then gotta try patching the upstream driver to actually use max clock.
To me that looks like a real issue as it is critical bug.

Johns driver honors max frequency.

Johns ipq40xx voltage regulator driver is already patched in and added as vqmmc-supply in the dts node as it works fine with Johns emmc driver.

Forcing max clock was added in this patch
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/commit/drivers/mmc/host/sdhci-msm.c?h=v4.14.40&id=951b8c875ac905aa9d348c825c380e7ce66c0f62

I dont think that anybody actually tested it on a working hardware

Even they were arguing that max-frequency is needed as only MSM8947Pro actually supports 400MHz clock.

Dummy regulator could work since the voltage is known,but I want to make this really generic.
We are really close now.

Update:
GCC not really liking your proposals.
I tried simply removing the boost part of the code but the errors:
mmc0: Failed to set clock at rate 400000 at timing 0
and
sdhci_msm 7824900.sdhci: card claims to support voltages below defined range
are still present.

Tried couple of ways to migrate both places where INT_MAX was used to passed f_max property.
But GCC is not really liking anything

This are common errors:
drivers/mmc/host/sdhci-msm.c: In function 'sdhci_msm_probe':
drivers/mmc/host/sdhci-msm.c:1154:33: error: 'f_max' undeclared (first use in this function); did you mean '__max'?
ret = clk_set_rate(host->mmc, f_max);
^~~~~
__max
drivers/mmc/host/sdhci-msm.c:1154:33: note: each undeclared identifier is reported only once for each function it appears in
drivers/mmc/host/sdhci-msm.c:1154:22: error: passing argument 1 of 'clk_set_rate' from incompatible pointer type [-Werror=incompatible-pointer-types]
ret = clk_set_rate(host->mmc, f_max);
^~~~
In file included from drivers/mmc/host/sdhci-pltfm.h:14:0,
from drivers/mmc/host/sdhci-msm.c:25:
./include/linux/clk.h:473:5: note: expected 'struct clk *' but argument is of type 'struct mmc_host *'
int clk_set_rate(struct clk *clk, unsigned long rate);
^~~~~~~~~~~~
drivers/mmc/host/sdhci-msm.c:1193:21: error: 'clk' undeclared (first use in this function)
ret = clk_set_rate(clk, host->mmc->f_max);

It suggest using clk and after using clk error is that clk is not declared

Patched both INT_MAX to 192 MHz and the error is same.
Error: mmc0: Failed to set clock at rate 400000 at timing 0
Is caused at the beggining by:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/tree/drivers/mmc/host/sdhci-msm.c?h=v4.14.40#n172

You were looking at the current driver,that one is in much better shape as a lot of power_irq and other issues have been fixed.
I tried backporting the driver from 4.16.8 but there are couple of critical errors during compilation which are caused most likely by something I forgot to backport.

Even fixing all clock settings manually to 192MHz still caused the same card below defined error and there is no attempt to load the card.

So upstream driver is severely broken

I didn't see that you have updated the old post as well. Sorry!

Was this mangled (i.e. do you read the post over email or did you visit the forum?), was this a c&p error? Because it doesn't look like the versions I posted in post #32. :man_shrugging: (or is somebody/something editing my posts? :ghost::artificial_satellite:)

or did try to apply same line to the other locations as well?
It was only meant as a drop-in replacement for

(and it assumed that you had the max-frequency property set to 192 Mhz).

I don't know, it happens from time to time that something else (like in the clk framework) got changed in the process it silently broke the driver... and nobody noticed and nobody cared.

Now, you could try to contact the mailing-list. But since it looks like the driver is
maintained by linux-arm-msm group, I don't have much hope that they listen, you can try but :money_mouth_face: ...

Anyway, you might as well not bother with upstream (since it starts to become a big waste of time) and just stick with the driver John provided. Maybe someone sends me a sample or somebody else figures out what needs to be done.

Thanks for giving it a fair shot.

I dont read replies in email.
I tried the versions you posted and posted that error caused by them is:
In file included from drivers/mmc/host/sdhci-pltfm.h:14:0,
from drivers/mmc/host/sdhci-msm.c:25:
./include/linux/clk.h:473:5: note: expected ‘struct clk *’ but argument is of type ‘struct mmc_host *’
int clk_set_rate(struct clk *clk, unsigned long rate);
^~~~~~~~~~~~
drivers/mmc/host/sdhci-msm.c:1193:21: error: ‘clk’ undeclared (first use in this function)
ret = clk_set_rate(clk, host->mmc->f_max);

I gave up today on the upstream driver as manually setting all clocks to 192MHz removes all of errors besides:
sdhci_msm 7824900.sdhci: card claims to support voltages below defined range

And that is where the driver stops.
It most likely got broken in the process and nobody noticed as it is rarely used in never kernel versions as both Android and other distros use old kernel versions or non upstreamed sdhci-msm drivers.

Now I am patching in the driver for TLC59208F I2C LED driver used in Orbi Pro from the GPL.
It is really badly written with lots of errors,they even wrote deafult instead of default.
I dont know how GCC even compiles that for stock.

GCC7.3 was throving a lot of errors related to suspend,resume and shutdown functions so for now I just commented those out.
I2C bus is registered but i2cdetect cant scan it,so I am looking at that now.
Without the driver we cant stop the LED ring from constantly flashing.

Well,after registering it under I2C device is registered and driver is loaded.
Gotta figure out how to use the driver as Netgear made sure to only include the binary blob as led control app

Hm, this reminds me of the Netgear WNDR4700... Even back then, Netgear was having a go at random i2c-chips. This must be a Netgear specialty :smiley: .

The WNDR4700 has a fan-controller chip TC654 and a lm87-compatible temperature sensor. The Netgear Firmware uses a userspace shell script (i2cset and i2cget) which polls the temperature sensor and sets the PWM of the fan-controller. However this was no good since the linux kernel has a much better way to do it:
thermal-zones binding in the DeviceTree.

But this required support for both chips. The lm87-compatible chip had a fully working driver that was ready to go. But there was no driver for the tc654 controller. I searched for a driver for a bit... But in the end I just grabbed the PDF from the vendors site and wrote a driver for the tc654 controller:

I ended up not upstreaming the tc654 since by the time linux 4.14 rolled around, the kernel had a driver for the tc65x that only needed the new thermal_ interface support

As for your tlc59208f driver... It looks like this driver only has exposes a private/non-led-subsystem sysfs interface :frowning: . Maybe you are lucky this time and can
adapt the existing driver from the tcl59108 to your tcl59208:

have fun! :slight_smile:

Yeah,looks like Netgear just loves using stuff with no driver support.
TLC59108 wont be easy to add support for TLC59208F since F designates I2C.
There is even TLC59108F and those are not supported as everything is different.

Their driver probed and registered itself as a driver for TLC59208F.
Just gotta figure out how to interact with it.
I think that there is gonna be some editing of the driver.

Also,I gotta figure out a way either how to package the custom firmware to get it accepted in WEB UI because I dont think that DniImage with suffice.

Bootloader loads the Fit and dtb configuration from the second partition and then uses that dtb to boot the kernel.

I gotta figure out a way to generate Fit tree separately

@chunkeey I cant get the damn web ui to accept image.
Their blobed fw-upgrade always spits out:
dev_name_tag:device:Orbi

incorrect language table file, cannot find the region name.

[FW UPGRADE][2018-05-14 11:50:51]:Not match open srouce product id: NETGEAR

getc time> 5 seconds in get_postfile 903

FILE: /tmp/uhttp-upgrade.img is download failed!

[FW UPGRADE][2018-05-14 11:50:59]:start verify image
[FW UPGRADE][2018-05-14 11:50:59]:can't open image file

I have had a look at the header and device and hw_id do match ones in stock.

@robimarko
Oh, from what I know Moritz ( = he had a RBR50) exclusively used the firmware recovery mechanism to flash the generated factory.img and he reported is was working for him.