[PATCH v10 05/12] dmaengine: dma: imx-sdma: add fw_loaded and is_ram_script

Frieder Schrempf frieder.schrempf at kontron.de
Thu Jul 23 05:03:37 EDT 2020


Hi Robin,

On 30.06.20 15:31, Robin Gong wrote:
> Add 'fw_loaded' and 'is_ram_script' to check if the script used by channel
> is ram script and it's loaded or not, so that could prevent meaningless
> following malloc dma descriptor and bd allocate in sdma_transfer_init(),
> otherwise memory may be consumed out potentially without free in case
> that spi fallback into pio while dma transfer failed by sdma firmware not
> ready(next ERR009165 patch depends on sdma RAM scripts/firmware).
> 
> Signed-off-by: Robin Gong <yibin.gong at nxp.com>
> Acked-By: Vinod Koul <vkoul at kernel.org>
> ---
>   drivers/dma/imx-sdma.c | 13 +++++++++++++
>   1 file changed, 13 insertions(+)
> 
> diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
> index 5411e01e..ce1c83e 100644
> --- a/drivers/dma/imx-sdma.c
> +++ b/drivers/dma/imx-sdma.c
> @@ -379,6 +379,7 @@ struct sdma_channel {
>   	enum dma_status			status;
>   	struct imx_dma_data		data;
>   	struct work_struct		terminate_worker;
> +	bool				is_ram_script;
>   };
>   
>   #define IMX_DMA_SG_LOOP		BIT(0)
> @@ -443,6 +444,7 @@ struct sdma_engine {
>   	struct sdma_buffer_descriptor	*bd0;
>   	/* clock ratio for AHB:SDMA core. 1:1 is 1, 2:1 is 0*/
>   	bool				clk_ratio;
> +	bool                            fw_loaded;
>   };
>   
>   static int sdma_config_write(struct dma_chan *chan,
> @@ -929,6 +931,7 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
>   	case IMX_DMATYPE_SSI_DUAL:
>   		per_2_emi = sdma->script_addrs->ssish_2_mcu_addr;
>   		emi_2_per = sdma->script_addrs->mcu_2_ssish_addr;
> +		sdmac->is_ram_script = true;
>   		break;
>   	case IMX_DMATYPE_SSI_SP:
>   	case IMX_DMATYPE_MMC:
> @@ -943,6 +946,7 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
>   		per_2_emi = sdma->script_addrs->asrc_2_mcu_addr;
>   		emi_2_per = sdma->script_addrs->asrc_2_mcu_addr;
>   		per_2_per = sdma->script_addrs->per_2_per_addr;
> +		sdmac->is_ram_script = true;
>   		break;
>   	case IMX_DMATYPE_ASRC_SP:
>   		per_2_emi = sdma->script_addrs->shp_2_mcu_addr;
> @@ -1339,6 +1343,11 @@ static struct sdma_desc *sdma_transfer_init(struct sdma_channel *sdmac,
>   {
>   	struct sdma_desc *desc;
>   
> +	if (!sdmac->sdma->fw_loaded && sdmac->is_ram_script) {
> +		dev_err(sdmac->sdma->dev, "sdma firmware not ready!\n");
> +		goto err_out;
> +	}

I tried your v10 patches on next-20200722 with i.MX8MM and it mostly 
seems to work fine.

When I tried first, I had the imx-sdma driver compiled into the kernel, 
so it didn't load the firmware and fell back to the ROM scripts.
With this, SPI transactions work just fine, but I got the above error 
message printed continuously when sending data in SPI3 via spidev.

When I build imx-sdma as a module, the firmware is loaded correctly and 
everything works as expected.

Can you have a look at this and provide a fix?

Thanks,
Frieder

> +
>   	desc = kzalloc((sizeof(*desc)), GFP_NOWAIT);
>   	if (!desc)
>   		goto err_out;
> @@ -1589,6 +1598,8 @@ static int sdma_config_write(struct dma_chan *chan,
>   {
>   	struct sdma_channel *sdmac = to_sdma_chan(chan);
>   
> +	sdmac->is_ram_script = false;
> +
>   	if (direction == DMA_DEV_TO_MEM) {
>   		sdmac->per_address = dmaengine_cfg->src_addr;
>   		sdmac->watermark_level = dmaengine_cfg->src_maxburst *
> @@ -1768,6 +1779,8 @@ static void sdma_load_firmware(const struct firmware *fw, void *context)
>   
>   	sdma_add_scripts(sdma, addr);
>   
> +	sdma->fw_loaded = true;
> +
>   	dev_info(sdma->dev, "loaded firmware %d.%d\n",
>   			header->version_major,
>   			header->version_minor);
> 



More information about the linux-arm-kernel mailing list