Tool/software:
Dear colleagues,
On this moment I'm working for porting source code from 3.2 linux kernel to 6.12 (Yes it's quite big jump :) ).
The kernel I use from: git.ti.com/.../
In my device I use GPMC bus for communicate with FPGA. For speed up transfer process I use DMA.
Below presented code snippet from 3.2 kernel:
dma_ch = edma_alloc_channel(EDMA_CHANNEL_ANY, dma_complete_callback, NULL, EVENTQ_DEFAULT);
edma_set_src (dma_ch, (dma_addr_t)(FPGA_BASE_DMA), INCR, W16BIT);
edma_set_dest(dma_ch, dmaphysdest + (bufnum * frame_size) +
(portion * dma_transfer_size), INCR, W16BIT);
edma_set_src_index(dma_ch, dma_transfer_size, dma_transfer_size);
edma_set_dest_index(dma_ch, dma_transfer_size, dma_transfer_size);
// Use A-Sync Transfer Mode
edma_set_transfer_params(dma_ch, dma_transfer_size,
dma_bcount,
dma_ccount,
dma_bcount_reload, ASYNC);
edma_read_slot(dma_ch, ¶m_set);
// disable the Intermediate Int's
param_set.opt &= ~(ITCINTEN);
if ((dma_bcount > 1) || (dma_ccount > 1)){
// enable the Intermediate Int's
//param_set.opt |= (ITCINTEN);
// enable chaining
param_set.opt |= (ITCCHEN);
}else{
// disable the Intermediate Int's
param_set.opt &= ~(ITCINTEN);
// disble chaining
param_set.opt &= ~(ITCCHEN);
}
// enable the final int tc
param_set.opt |= (TCINTEN);
param_set.opt |= EDMA_TCC((dma_ch & 0x3f));
param_set.opt |= EDMA_TCC(EDMA_CHAN_SLOT(dma_ch));
edma_write_slot(dma_ch, ¶m_set);
edma_start(dma_ch);
The code on 3.2 works well.
On the 6.12 I have to use dmaengine.
My device tree related gpmc look like:
&gpmc {
pinctrl-names = "default";
pinctrl-0 = <&gpmc_pins>;
compatible = "test,fpga";
interrupts = <100>;
gpmc,num-cs = <2>;
gpmc,num-waitpins = <2>;
status = "okay";
dmas = <&edma 52 0>;
dma-names = "rx";
interrupt-controller;
#interrupt-cells = <2>;
#address-cells = <2>;
#size-cells = <1>;
ranges = <0 0 0x08000000 0x01000000 /* CS0 @addr 0x08000000, size 0x1000000 */
1 0 0x09000000 0x01000000>; /* CS1 @addr 0x09000000, size 0x1000000 */
fpga_control@0,0 {
status = "okay";
#address-cells = <1>;
#size-cells = <1>;
reg = <0 0 0x01000000>;
rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
};
fpga_stream@1,0 {
status = "okay";
#address-cells = <1>;
#size-cells = <1>;
reg = <1 0 0x01000000>;
rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
};
};
I'm configure GPMC registers from source code like it was before on 3.2 and it looks like:
CS[0] GPMC_CONFIG1 0xA9401001 CS[0] GPMC_CONFIG2 0x00060800 CS[0] GPMC_CONFIG3 0x00020200 CS[0] GPMC_CONFIG4 0x04020600 CS[0] GPMC_CONFIG5 0x0204080A CS[0] GPMC_CONFIG6 0x040702C0 CS[0] GPMC_CONFIG7 0x00000F48 CS[1] GPMC_CONFIG1 0xE9401001 CS[1] GPMC_CONFIG2 0x00060800 CS[1] GPMC_CONFIG3 0x00020200 CS[1] GPMC_CONFIG4 0x04020600 CS[1] GPMC_CONFIG5 0x0204080A CS[1] GPMC_CONFIG6 0x040702C0 CS[1] GPMC_CONFIG7 0x00000F49
The source code responsible for launch DMA:
void __iomem* dma_virt_addr = dma_alloc_coherent(dev->parent, 1024*1024, &dma_addr, GFP_KERNEL);
memset(&dma_cfg, 0, sizeof(dma_cfg));
dma_cfg.direction = DMA_DEV_TO_MEM;
dma_cfg.src_addr = fpga_stream.gpmc_base.start; //0x09000000
dma_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
dma_cfg.src_maxburst = 16;
ret = dmaengine_slave_config(fpga_stream.dma_ch, &dma_cfg);
if (ret) {
DRV_MSG("DMA engine slave config failed: %d\n", ret);
return -1;
}
dma_desc = dmaengine_prep_slave_single(fpga_stream.dma_ch, dma_addr, 1024, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!dma_desc)
{
DRV_MSG("DMA busy\n");
return -1;
}
dma_desc->callback = dma_complete_callback;
dma_desc->callback_param = NULL;
dma_cookie = dmaengine_submit(dma_desc);
if (dma_submit_error(dma_cookie)) {
DRV_MSG("DMA transaction submission FAILED\n");
return -1;
}
DRV_MSG("DMA transaction submission SUCCESS\n");
dma_async_issue_pending(fpga_stream.dma_ch);
DRV_MSG("DMA start\n");
On the dmesg I see that DMA channel has configured:
[ 67.974832] edma 49000000.dma: Got eDMA channel 52 for virt channel 50 (HW trigger) [ 68.056257] edma 49000000.dma: vchan a74ee4d7: txd fd8f725f[2]: submitted [ 68.062970] edma 49000000.dma: [ 68.062970] pset[0]: [ 68.062970] chnum 52 [ 68.062970] slot 49 [ 68.062970] opt 00134004 [ 68.062970] src 09000000 [ 68.062970] dst 95100000 [ 68.062970] abcnt 00100004 [ 68.062970] ccnt 00000010 [ 68.062970] bidx 00040000 [ 68.062970] cidx 00400000 [ 68.062970] lkrld ffffffff [ 68.062995] edma 49000000.dma: first transfer starting on channel 52 [ 68.063008] edma 49000000.dma: ER1 00000000 [ 68.063021] edma 49000000.dma: EER1 00100000
My problem that I don't see DMA complete callback. On the 3.2 kernel callback executed properly without any issues.
I will be appreciate for any advice about the reason of this behavior.
Thanks in advance!
