We are using the NXP i.MX8MM processor with the 5.15.71 kernel and have ported Murata’s cyw-fmac backported driver(kirkstone Godzilla release) for Murata's Wi-Fi chip module (LBEE5XV2EA). Here, I want to discuss the issue of SDIO clock gating. Specifically, the SDIO clock for the Wi-Fi chip remains enabled continuously even when there is no communication happening over Wi-Fi. I want to enable software clock gating support for the Wi-Fi SDIO interface.
Interestingly, on another SDIO interface where an eMMC is connected, clock gating is already functioning as expected.
Debugging Steps Performed
- Driver and Function Analysis:
- The Murata Wi-Fi brcmfmac driver uses sdio_readl/writel APIs from “mmc/core/sdio_io.c” for read/write operations with the SDIO interface. Which directly reads/writes from the address space of a given SDIO.
- The i.MX8MM’s SDIO driver (“mmc/host/sdhci-esdhc-imx.c”) performs these operations using readl() which uses IOMEM address with some offset.
- Kernel Patch Impact:
There is a specific patch in the kernel where SDIO clock gating support was removed from the SDIO. Here is the commit:
https://patchwork.kernel.org/project/linux-mmc/patch/1443776171-7127-1-git-send-email-ulf.hansson@li...
- I attempted to re-implement clock hold and clock release functionality to gate the clock before every read/write operation from the above commit. However, the Wi-Fi module failed to operate correctly with this implementation.
Attempted Approaches
- Clock Gating via mmc_set_ios Operations
To manage the clock gating, I implemented the following functions in clock_hold and clock_release:
void mmc_gate_clock(struct mmc_host *host) {
unsigned long flags;
spin_lock_irqsave(&host->clk_lock, flags);
host->clk_old = host->ios.clock;
host->ios.clock = 0;
host->clk_gated = true;
spin_unlock_irqrestore(&host->clk_lock, flags);
mmc_set_ios(host);
}
void mmc_ungate_clock(struct mmc_host *host) {
if (host->clk_old) {
BUG_ON(host->ios.clock);
__mmc_set_clock(host, host->clk_old);
}
}
- Description:
- The mmc_gate_clock() function gates the clock by setting the ios.clock value to 0.
- The mmc_ungate_clock() function restores the clock using a cached clock value (clk_old).
- Challenges:
- These functions rely on ios operations of the host driver.
- In the i.MX MMC driver (mmc/host/sdhci-esdhc-imx.c), ios operations are not fully implemented. However, there is a mmc_host_ops struct in the driver that allows set_ios partial implementation, which made this approach partially functional.
- Despite these adjustments, the WiFi module failed to operate correctly.
Question:
- Is there any alternative approach to enable software clock gating on the WiFi SDIO interface?