Skip to content

Commit a41461b

Browse files
committed
Merge tag 'imx-ecspi-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into arm/drivers
i.MX eCSPI errata handling for 5.15: It includes all required changes for handling i.MX6/7 eCSPI errata ERR009165, which causes FIFO transfer to be sent twice in DMA mode. Both SPI and DMA maintainers agree to merge it through arm-soc tree. * tag 'imx-ecspi-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux: dmaengine: imx-sdma: add terminated list for freed descriptor in worker dmaengine: imx-sdma: add uart rom script dma: imx-sdma: add i.mx6ul compatible name dmaengine: imx-sdma: remove ERR009165 on i.mx6ul spi: imx: remove ERR009165 workaround on i.mx6ul spi: imx: fix ERR009165 dmaengine: imx-sdma: add mcu_2_ecspi script dmaengine: dma: imx-sdma: add fw_loaded and is_ram_script dmaengine: imx-sdma: remove duplicated sdma_load_context Revert "dmaengine: imx-sdma: refine to load context only once" Revert "ARM: dts: imx6: Use correct SDMA script for SPI cores" Revert "ARM: dts: imx6q: Use correct SDMA script for SPI5 core" Link: https://lore.kernel.org/r/20210809071838.GF30984@dragon Signed-off-by: Arnd Bergmann <[email protected]>
2 parents d2c334f + 4e2b10b commit a41461b

File tree

5 files changed

+111
-34
lines changed

5 files changed

+111
-34
lines changed

Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Required properties:
99
"fsl,imx53-sdma"
1010
"fsl,imx6q-sdma"
1111
"fsl,imx7d-sdma"
12+
"fsl,imx6ul-sdma"
1213
"fsl,imx8mq-sdma"
1314
"fsl,imx8mm-sdma"
1415
"fsl,imx8mn-sdma"

arch/arm/boot/dts/imx6q.dtsi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@
177177
clocks = <&clks IMX6Q_CLK_ECSPI5>,
178178
<&clks IMX6Q_CLK_ECSPI5>;
179179
clock-names = "ipg", "per";
180-
dmas = <&sdma 11 8 1>, <&sdma 12 8 2>;
180+
dmas = <&sdma 11 7 1>, <&sdma 12 7 2>;
181181
dma-names = "rx", "tx";
182182
status = "disabled";
183183
};

arch/arm/boot/dts/imx6qdl.dtsi

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@
334334
clocks = <&clks IMX6QDL_CLK_ECSPI1>,
335335
<&clks IMX6QDL_CLK_ECSPI1>;
336336
clock-names = "ipg", "per";
337-
dmas = <&sdma 3 8 1>, <&sdma 4 8 2>;
337+
dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
338338
dma-names = "rx", "tx";
339339
status = "disabled";
340340
};
@@ -348,7 +348,7 @@
348348
clocks = <&clks IMX6QDL_CLK_ECSPI2>,
349349
<&clks IMX6QDL_CLK_ECSPI2>;
350350
clock-names = "ipg", "per";
351-
dmas = <&sdma 5 8 1>, <&sdma 6 8 2>;
351+
dmas = <&sdma 5 7 1>, <&sdma 6 7 2>;
352352
dma-names = "rx", "tx";
353353
status = "disabled";
354354
};
@@ -362,7 +362,7 @@
362362
clocks = <&clks IMX6QDL_CLK_ECSPI3>,
363363
<&clks IMX6QDL_CLK_ECSPI3>;
364364
clock-names = "ipg", "per";
365-
dmas = <&sdma 7 8 1>, <&sdma 8 8 2>;
365+
dmas = <&sdma 7 7 1>, <&sdma 8 7 2>;
366366
dma-names = "rx", "tx";
367367
status = "disabled";
368368
};
@@ -376,7 +376,7 @@
376376
clocks = <&clks IMX6QDL_CLK_ECSPI4>,
377377
<&clks IMX6QDL_CLK_ECSPI4>;
378378
clock-names = "ipg", "per";
379-
dmas = <&sdma 9 8 1>, <&sdma 10 8 2>;
379+
dmas = <&sdma 9 7 1>, <&sdma 10 7 2>;
380380
dma-names = "rx", "tx";
381381
status = "disabled";
382382
};

drivers/dma/imx-sdma.c

Lines changed: 70 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -198,12 +198,12 @@ struct sdma_script_start_addrs {
198198
s32 per_2_firi_addr;
199199
s32 mcu_2_firi_addr;
200200
s32 uart_2_per_addr;
201-
s32 uart_2_mcu_addr;
201+
s32 uart_2_mcu_ram_addr;
202202
s32 per_2_app_addr;
203203
s32 mcu_2_app_addr;
204204
s32 per_2_per_addr;
205205
s32 uartsh_2_per_addr;
206-
s32 uartsh_2_mcu_addr;
206+
s32 uartsh_2_mcu_ram_addr;
207207
s32 per_2_shp_addr;
208208
s32 mcu_2_shp_addr;
209209
s32 ata_2_mcu_addr;
@@ -230,6 +230,10 @@ struct sdma_script_start_addrs {
230230
s32 zcanfd_2_mcu_addr;
231231
s32 zqspi_2_mcu_addr;
232232
s32 mcu_2_ecspi_addr;
233+
s32 mcu_2_sai_addr;
234+
s32 sai_2_mcu_addr;
235+
s32 uart_2_mcu_addr;
236+
s32 uartsh_2_mcu_addr;
233237
/* End of v3 array */
234238
s32 mcu_2_zqspi_addr;
235239
/* End of v4 array */
@@ -433,9 +437,10 @@ struct sdma_channel {
433437
unsigned long watermark_level;
434438
u32 shp_addr, per_addr;
435439
enum dma_status status;
436-
bool context_loaded;
437440
struct imx_dma_data data;
438441
struct work_struct terminate_worker;
442+
struct list_head terminated;
443+
bool is_ram_script;
439444
};
440445

441446
#define IMX_DMA_SG_LOOP BIT(0)
@@ -476,6 +481,13 @@ struct sdma_driver_data {
476481
int num_events;
477482
struct sdma_script_start_addrs *script_addrs;
478483
bool check_ratio;
484+
/*
485+
* ecspi ERR009165 fixed should be done in sdma script
486+
* and it has been fixed in soc from i.mx6ul.
487+
* please get more information from the below link:
488+
* https://www.nxp.com/docs/en/errata/IMX6DQCE.pdf
489+
*/
490+
bool ecspi_fixed;
479491
};
480492

481493
struct sdma_engine {
@@ -499,6 +511,7 @@ struct sdma_engine {
499511
struct sdma_buffer_descriptor *bd0;
500512
/* clock ratio for AHB:SDMA core. 1:1 is 1, 2:1 is 0*/
501513
bool clk_ratio;
514+
bool fw_loaded;
502515
};
503516

504517
static int sdma_config_write(struct dma_chan *chan,
@@ -595,6 +608,13 @@ static struct sdma_driver_data sdma_imx6q = {
595608
.script_addrs = &sdma_script_imx6q,
596609
};
597610

611+
static struct sdma_driver_data sdma_imx6ul = {
612+
.chnenbl0 = SDMA_CHNENBL0_IMX35,
613+
.num_events = 48,
614+
.script_addrs = &sdma_script_imx6q,
615+
.ecspi_fixed = true,
616+
};
617+
598618
static struct sdma_script_start_addrs sdma_script_imx7d = {
599619
.ap_2_ap_addr = 644,
600620
.uart_2_mcu_addr = 819,
@@ -628,6 +648,7 @@ static const struct of_device_id sdma_dt_ids[] = {
628648
{ .compatible = "fsl,imx31-sdma", .data = &sdma_imx31, },
629649
{ .compatible = "fsl,imx25-sdma", .data = &sdma_imx25, },
630650
{ .compatible = "fsl,imx7d-sdma", .data = &sdma_imx7d, },
651+
{ .compatible = "fsl,imx6ul-sdma", .data = &sdma_imx6ul, },
631652
{ .compatible = "fsl,imx8mq-sdma", .data = &sdma_imx8mq, },
632653
{ /* sentinel */ }
633654
};
@@ -919,6 +940,7 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
919940
sdmac->pc_to_device = 0;
920941
sdmac->device_to_device = 0;
921942
sdmac->pc_to_pc = 0;
943+
sdmac->is_ram_script = false;
922944

923945
switch (peripheral_type) {
924946
case IMX_DMATYPE_MEMORY:
@@ -945,6 +967,17 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
945967
emi_2_per = sdma->script_addrs->mcu_2_ata_addr;
946968
break;
947969
case IMX_DMATYPE_CSPI:
970+
per_2_emi = sdma->script_addrs->app_2_mcu_addr;
971+
972+
/* Use rom script mcu_2_app if ERR009165 fixed */
973+
if (sdmac->sdma->drvdata->ecspi_fixed) {
974+
emi_2_per = sdma->script_addrs->mcu_2_app_addr;
975+
} else {
976+
emi_2_per = sdma->script_addrs->mcu_2_ecspi_addr;
977+
sdmac->is_ram_script = true;
978+
}
979+
980+
break;
948981
case IMX_DMATYPE_EXT:
949982
case IMX_DMATYPE_SSI:
950983
case IMX_DMATYPE_SAI:
@@ -954,6 +987,7 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
954987
case IMX_DMATYPE_SSI_DUAL:
955988
per_2_emi = sdma->script_addrs->ssish_2_mcu_addr;
956989
emi_2_per = sdma->script_addrs->mcu_2_ssish_addr;
990+
sdmac->is_ram_script = true;
957991
break;
958992
case IMX_DMATYPE_SSI_SP:
959993
case IMX_DMATYPE_MMC:
@@ -968,6 +1002,7 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
9681002
per_2_emi = sdma->script_addrs->asrc_2_mcu_addr;
9691003
emi_2_per = sdma->script_addrs->asrc_2_mcu_addr;
9701004
per_2_per = sdma->script_addrs->per_2_per_addr;
1005+
sdmac->is_ram_script = true;
9711006
break;
9721007
case IMX_DMATYPE_ASRC_SP:
9731008
per_2_emi = sdma->script_addrs->shp_2_mcu_addr;
@@ -1008,9 +1043,6 @@ static int sdma_load_context(struct sdma_channel *sdmac)
10081043
int ret;
10091044
unsigned long flags;
10101045

1011-
if (sdmac->context_loaded)
1012-
return 0;
1013-
10141046
if (sdmac->direction == DMA_DEV_TO_MEM)
10151047
load_address = sdmac->pc_from_device;
10161048
else if (sdmac->direction == DMA_DEV_TO_DEV)
@@ -1053,8 +1085,6 @@ static int sdma_load_context(struct sdma_channel *sdmac)
10531085

10541086
spin_unlock_irqrestore(&sdma->channel_0_lock, flags);
10551087

1056-
sdmac->context_loaded = true;
1057-
10581088
return ret;
10591089
}
10601090

@@ -1078,9 +1108,6 @@ static void sdma_channel_terminate_work(struct work_struct *work)
10781108
{
10791109
struct sdma_channel *sdmac = container_of(work, struct sdma_channel,
10801110
terminate_worker);
1081-
unsigned long flags;
1082-
LIST_HEAD(head);
1083-
10841111
/*
10851112
* According to NXP R&D team a delay of one BD SDMA cost time
10861113
* (maximum is 1ms) should be added after disable of the channel
@@ -1089,11 +1116,7 @@ static void sdma_channel_terminate_work(struct work_struct *work)
10891116
*/
10901117
usleep_range(1000, 2000);
10911118

1092-
spin_lock_irqsave(&sdmac->vc.lock, flags);
1093-
vchan_get_all_descriptors(&sdmac->vc, &head);
1094-
spin_unlock_irqrestore(&sdmac->vc.lock, flags);
1095-
vchan_dma_desc_free_list(&sdmac->vc, &head);
1096-
sdmac->context_loaded = false;
1119+
vchan_dma_desc_free_list(&sdmac->vc, &sdmac->terminated);
10971120
}
10981121

10991122
static int sdma_terminate_all(struct dma_chan *chan)
@@ -1107,6 +1130,13 @@ static int sdma_terminate_all(struct dma_chan *chan)
11071130

11081131
if (sdmac->desc) {
11091132
vchan_terminate_vdesc(&sdmac->desc->vd);
1133+
/*
1134+
* move out current descriptor into terminated list so that
1135+
* it could be free in sdma_channel_terminate_work alone
1136+
* later without potential involving next descriptor raised
1137+
* up before the last descriptor terminated.
1138+
*/
1139+
vchan_get_all_descriptors(&sdmac->vc, &sdmac->terminated);
11101140
sdmac->desc = NULL;
11111141
schedule_work(&sdmac->terminate_worker);
11121142
}
@@ -1168,7 +1198,6 @@ static void sdma_set_watermarklevel_for_p2p(struct sdma_channel *sdmac)
11681198
static int sdma_config_channel(struct dma_chan *chan)
11691199
{
11701200
struct sdma_channel *sdmac = to_sdma_chan(chan);
1171-
int ret;
11721201

11731202
sdma_disable_channel(chan);
11741203

@@ -1208,9 +1237,7 @@ static int sdma_config_channel(struct dma_chan *chan)
12081237
sdmac->watermark_level = 0; /* FIXME: M3_BASE_ADDRESS */
12091238
}
12101239

1211-
ret = sdma_load_context(sdmac);
1212-
1213-
return ret;
1240+
return 0;
12141241
}
12151242

12161243
static int sdma_set_channel_priority(struct sdma_channel *sdmac,
@@ -1361,7 +1388,6 @@ static void sdma_free_chan_resources(struct dma_chan *chan)
13611388

13621389
sdmac->event_id0 = 0;
13631390
sdmac->event_id1 = 0;
1364-
sdmac->context_loaded = false;
13651391

13661392
sdma_set_channel_priority(sdmac, 0);
13671393

@@ -1374,6 +1400,11 @@ static struct sdma_desc *sdma_transfer_init(struct sdma_channel *sdmac,
13741400
{
13751401
struct sdma_desc *desc;
13761402

1403+
if (!sdmac->sdma->fw_loaded && sdmac->is_ram_script) {
1404+
dev_warn_once(sdmac->sdma->dev, "sdma firmware not ready!\n");
1405+
goto err_out;
1406+
}
1407+
13771408
desc = kzalloc((sizeof(*desc)), GFP_NOWAIT);
13781409
if (!desc)
13791410
goto err_out;
@@ -1722,8 +1753,8 @@ static void sdma_issue_pending(struct dma_chan *chan)
17221753

17231754
#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1 34
17241755
#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2 38
1725-
#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V3 41
1726-
#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V4 42
1756+
#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V3 45
1757+
#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V4 46
17271758

17281759
static void sdma_add_scripts(struct sdma_engine *sdma,
17291760
const struct sdma_script_start_addrs *addr)
@@ -1747,6 +1778,19 @@ static void sdma_add_scripts(struct sdma_engine *sdma,
17471778
for (i = 0; i < sdma->script_number; i++)
17481779
if (addr_arr[i] > 0)
17491780
saddr_arr[i] = addr_arr[i];
1781+
1782+
/*
1783+
* get uart_2_mcu_addr/uartsh_2_mcu_addr rom script specially because
1784+
* they are now replaced by uart_2_mcu_ram_addr/uartsh_2_mcu_ram_addr
1785+
* to be compatible with legacy freescale/nxp sdma firmware, and they
1786+
* are located in the bottom part of sdma_script_start_addrs which are
1787+
* beyond the SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1.
1788+
*/
1789+
if (addr->uart_2_mcu_addr)
1790+
sdma->script_addrs->uart_2_mcu_addr = addr->uart_2_mcu_addr;
1791+
if (addr->uartsh_2_mcu_addr)
1792+
sdma->script_addrs->uartsh_2_mcu_addr = addr->uartsh_2_mcu_addr;
1793+
17501794
}
17511795

17521796
static void sdma_load_firmware(const struct firmware *fw, void *context)
@@ -1803,6 +1847,8 @@ static void sdma_load_firmware(const struct firmware *fw, void *context)
18031847

18041848
sdma_add_scripts(sdma, addr);
18051849

1850+
sdma->fw_loaded = true;
1851+
18061852
dev_info(sdma->dev, "loaded firmware %d.%d\n",
18071853
header->version_major,
18081854
header->version_minor);
@@ -2086,6 +2132,7 @@ static int sdma_probe(struct platform_device *pdev)
20862132

20872133
sdmac->channel = i;
20882134
sdmac->vc.desc_free = sdma_desc_free;
2135+
INIT_LIST_HEAD(&sdmac->terminated);
20892136
INIT_WORK(&sdmac->terminate_worker,
20902137
sdma_channel_terminate_work);
20912138
/*

0 commit comments

Comments
 (0)