Hello,
I am trying to work out how to configure wake from WiFi module via GPIO. We have a Murata 1ZM (NXP 88W8987) connected to an i.MX8M Mini via SDIO. The following definition is in our device tree for the SDIO interface:
&usdhc1 {
assigned-clocks = <&clk IMX8MM_CLK_USDHC1>;
assigned-clock-rates = <200000000>;
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc1>;
pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
bus-width = <4>;
mmc-pwrseq = <&usdhc1_pwrseq>;
status = "okay";
broken-cd;
keep-power-in-suspend;
wakeup-source;
fsl,sdio-async-interrupt-enabled;
wifi_wake_host {
compatible = "nxp,wifi-wake-host";
interrupt-parent = <&gpio3>;
interrupts = <22 IRQ_TYPE_LEVEL_LOW>;
interrupt-names = "host-wake";
};
};
Once we are booted up and connected to WiFi, we can cause the host to enter sleep using
echo enabled > /sys/bus/platform/devices/30b40000.mmc/power/wakeup && \
/usr/share/nxp_wireless/mlanutl mlan0 hssetpara 2 0x3 0xc8 3 400 && \
echo mem > /sys/power/state
This works fine to get the host to sleep. However the card never wakes the host up, presumably because of an issue with either the parameters after hssetpara, or the definition in the wifi_wake_host node of our devicetree. The GPIO wake pin from the 1ZM is connected to pad AC14 on the i.MX8MM, which should be GPIO3[22]. The pin is defined in iomuxc in the devicetree (abbreviated to show only the relevant pin definition:
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog>;
pinctrl_hog: hoggrp {
fsl,pins = <
MX8MM_IOMUXC_SAI5_RXD1_GPIO3_IO22 0x16 /* -I WIFI.WL_MCU_WAKE_OD - Drive strength x6 / Fast slew rate / */
>;
};
What are we doing wrong here?
Hi,
Thank you for your interest in NXP Semiconductor products,
What is the firmware downloaded? I can see that the interface does exist, but could you send your modprobe log?
Have you probed that wifi_wake_host does change?
Regards
Hi @JosephAtNXP
Thanks for getting back to me.
>> What is the firmware downloaded?
[ 128.395426] fw_name=nxp/sdiouart8987_combo_v0.bin
[ 129.746858] wlan: version = SD8987----16.92.21.p41.4-MM5X16344.p3-GPL-(FP92)
>> could you send your modprobe log?
Here is the dmesg output after running modprobe moal mod_para=nxp/wifi_mod_para.conf
[ 128.332547] mmc0: new ultra high speed SDR104 SDIO card at address 0001
[ 128.354400] vendor=0x02DF device=0x9149 class=0 function=1
[ 128.360992] Attach moal handle ops, card interface type: 0x105
[ 128.368644] SD8987: init module param from usr cfg
[ 128.373953] card_type: SD8987, config block: 0
[ 128.378575] cfg80211_wext=0xf
[ 128.381609] max_vir_bss=1
[ 128.384287] cal_data_cfg=none
[ 128.387339] ps_mode = 1
[ 128.389897] auto_ds = 1
[ 128.392407] host_mlme=enable
[ 128.395426] fw_name=nxp/sdiouart8987_combo_v0.bin
[ 128.400479] SDIO: max_segs=128 max_seg_size=65535
[ 128.405260] rx_work=1 cpu_num=4
[ 128.408745] Attach mlan adapter operations.card_type is 0x105.
[ 128.417871] wlan: Enable TX SG mode
[ 128.421579] wlan: Enable RX SG mode
[ 128.429942] Request firmware: nxp/sdiouart8987_combo_v0.bin
[ 128.723507] Wlan: FW download over, firmwarelen=595300 downloaded 595300
[ 129.590965] WLAN FW is active
[ 129.594210] on_time is 129476898875
[ 129.661700] fw_cap_info=0x181d7f03, dev_cap_mask=0xffffffff
[ 129.667761] max_p2p_conn = 8, max_sta_conn = 8
[ 129.673097] SDIO rx aggr: 1 block_size=512
[ 129.677877] wlan: Enable RX SG mode
[ 129.681527] mpa_rx_buf_size=65280
[ 129.746858] wlan: version = SD8987----16.92.21.p41.4-MM5X16344.p3-GPL-(FP92)
There is nothing in /var/log/ksymoops after running the above command, so I hope the dmesg log is adequate.
>> Have you probed that wifi_wake_host does change?
I have run gpiomon gpiochip3 22 whilst in a second terminal executing /usr/share/nxp_wireless/mlanutl mlan0 hssetpara 2 0x3 0xc8 3 400 but see no activity on the gpiomon console. I verified network connectivity before calling mlanutl.
I am wondering if the syntax I am passing to mlanutl hssetpara is incorrect, and this is why I am not seeing any activity on gpiomon.
Regards,
Tom
Hi,
Are you able to physically probe the pin?
I think that the interface hasn't access to the pin, could you try this in your DTS?
pinctrl-0 = <&pinctrl_usdhc1>, <&pinctrl_wlan>;
pinctrl-1 = <&pinctrl_usdhc1_100mhz>, <&pinctrl_wlan>;
pinctrl-2 = <&pinctrl_usdhc1_200mhz>, <&pinctrl_wlan>;
...
pinctrl_wlan: wlangrp {
fsl,pins = <
MX8MM_IOMUXC_SAI5_RXD1_GPIO3_IO22 0x116
>;
};
Regards,
Hi @JosephAtNXP
Thanks for your further suggestions. I made the devicetree changes you suggested. On probing the pin being used for GPIO wake I could at that point not see any activity on the pin, although wakeup was now working on ping from an external device.
I then changed the pinmux definition from 0x116 to 0x16 (disable the pad control register Pull Resistors Enable bit). After this I could see the pin momentarily dropping low after powering up the 1ZM module, but still no activity on the GPIO line during wake events, although wakeup on ping was still working. I suspect the change to 0x16 is required because our hardware has an external pullup and the GPIO goes through a voltage level converter as well.
I then took another look at my parameters passed to hssetpara, and realised I had misunderstood the documentation where it talks about the GPIO
where GPIO is the pin number of GPIO used to wakeup the host. It could be any valid
GPIO pin# (e.g. 0-7) or 0xff (interface, e.g. SDIO will be used instead).
The default is 0xff.
I had been passing 0x56 as this parameter as I thought this was referencing host GPIO pin, in fact I realise now it is the GPIO pin # on the 1ZM, as the WLAN_WAKEUP_HOST signal only defaults to pin 27 which is also GPIO1, but can in fact be specified to be on any GPIO pin. Changing this parameter to 0x1 resulted in the pin 27 pulsing as expected on wakeup events. I presume that 0x56 is a large enough number that there is no GPIO that corresponds to it, so it is treated as SDIO wake by the card in the same way as 0xFF. I think this is why wake worked initially but without the pin pulsing when expected. For reference, the complete command that works is:
echo enabled > /sys/bus/platform/devices/30b40000.mmc/power/wakeup && \
/usr/share/nxp_wireless/mlanutl mlan0 hssetpara 2 1 0xc8 3 400 && echo freeze > /sys/power/state
I have one remaining issue however - the SDIO interface does not appear to power down when wake is configured to use the GPIO pin, the power consumption for the "freeze" state when waking via SDIO and wake via GPIO is about the same, circa 120mA on our hardware. How can I configure the devicetree to allow the SDIO interface to suspend during sleep but without preventing sleep in the first place?
I attempted to remove the keep-power-in-suspend node from the usdhc1 section of the devicetree, but this prevents sleep entirely as you then can't write to /sys/bus/platform/devices/30b40000.mmc/power/wakeup (it doesn't exist) and echo freeze > /sys/power/state errors with "Function not implemented". My understanding was the the reason for using GPIO wake is to allow SDIO power savings during sleep, but at the moment I'm not seeing any.
Thank you.
Hi @JosephAtNXP
Do you have any further update on my issue mentioned in my last post about not seeing any SDIO power savings using GPIO wake?
Thank you,
Tom Gibson