On Mon, Jun 10, 2019 at 5:09 AM Robin Gong <yibin.gong@xxxxxxx> wrote: > > I can reproduce once enable your config to build firmware in kernel, but no such issue > if load sdma firmware from rootfs as imx_v6_v7_defconfig. Maybe firmware built in function > broken by some patches. Could you try with the default firmware loading way which is from > rootfs(/lib/firmware/imx/sdma/sdma-imx6q.bin)? This is it ! If I add the firmware to the kernel directly, I see the crash. But if I use the firmware fall-back mechanism, there is no crash. And if I build imx-sdma as a module, and insmod it later, there is also no crash. I patched imx-sdma so it logs the adler32 checksum of the firmware it's loading (I tried using the kernel crypto API, but it doesn't work this early in the boot). I notice that the firmware is always the same, crash or no crash: firmware in-kernel (crash): [ 1.370424] imx-sdma 20ec000.sdma: firmware hash: 69BC0F09 firmware fallback (no crash): [ 6.466394] imx-sdma 20ec000.sdma: firmware hash: 69BC0F09 My guess: this could be a timing issue. If the sdma driver loads 'too early', the boot crash will happen. Maybe the driver needs to check for a missing dependency on boot, and -EPROBE_DEFER ? Robin, should I make a bug report? If so, who do I send this to? Code used to print the firmware hash on imx-sdma: #define MOD_ADLER 65521 static u32 adler32(const unsigned char *data, size_t len) { u32 a = 1, b = 0; size_t index; for (index = 0; index < len; ++index) { a = (a + data[index]) % MOD_ADLER; b = (b + a) % MOD_ADLER; } return (b << 16) | a; } static void log_fw_hash(struct device *dev, const struct firmware *fw) { dev_info(dev, "firmware hash: %08X", adler32(fw->data, fw->size)); } static void sdma_load_firmware(const struct firmware *fw, void *context) { struct sdma_engine *sdma = context; const struct sdma_firmware_header *header; const struct sdma_script_start_addrs *addr; unsigned short *ram_code; if (!fw) { dev_info(sdma->dev, "external firmware not found, using ROM firmware\n"); /* In this case we just use the ROM firmware. */ return; } log_fw_hash(sdma->dev, fw);