Я использую TI AM5728 с ядром 4.1.13 и пытаюсь выполнить DMA с периферийного устройства GPMC в буфер, выделенный в моем драйвере.Я изо всех сил пытался понять, почему ничего не происходит, и это из-за моего непонимания «подходящих» адресов, которые необходимо указывать при настройке DMA.
Я настроил свой DTS таким образом, чтобы мое устройство было дочерним узлом консоли управления групповыми политиками:
&gpmc {
pinctrl-names="default";
pinctrl-0 = <&fpga_pins_default>;
ranges = <3 0 0x3000000 0x0100000>; /* fpga */
hs_gpmc: fpga@3,0 {
reg = <3 0 0x100000>;
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&gpio1>;
interrupts = <29 IRQ_TYPE_EDGE_FALLING>;
dmas = <&edma_xbar 4>;
dma-names = "rxtx";
compatible = "lgs,hs-fpga";
bank-width = <2>;
.
.
.
Я считаю, что правильно делаю следующее, поскольку беру виртуальное ядроадрес и сопоставление его с адресом DMA:
/* Set up my buffer to store data FROM the GPMC*/
buf = devm_kzalloc(&pdev->dev, HS_GPMC_FPGA_LEN, (GFP_DMA | GFP_KERNEL));
/* Get a DMA address */
data->dma_start = dma_map_single(&pdev->dev, buf, HS_GPMC_FPGA_LEN, DMA_FROM_DEVICE);
Теперь я проверяю, получил ли я контроллер eDMA, запрашивая канал, который соответствует имени "rxtx", используемому общим узлом GPMC:
data->chan = dma_request_slave_channel(&pdev->dev, "rxtx");
и вот узел GPMC в DTS:
gpmc: gpmc@50000000 {
compatible = "ti,am3352-gpmc";
ti,hwmods = "gpmc";
reg = <0x50000000 0x2000>; /* device IO registers */
interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&edma_xbar 4>;
dma-names = "rxtx";
gpmc,num-cs = <8>;
gpmc,num-waitpins = <2>;
#address-cells = <2>;
#size-cells = <1>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
status = "disabled";
};
Наконец, я настроил eDMA:
memset(&data->cfg, 0, sizeof(data->cfg));
data->cfg.direction = DMA_DEV_TO_MEM;
data->cfg.src_addr = HS_GPMC_FPGA_DMA_START_ADDRESS;
data->cfg.src_maxburst = 2;
dmaengine_slave_config(data->chan, &data->cfg);
, где HS_GPMC_FPGA_DMA_START_ADDRESS установлен в 0x3000000 (начальный адресфизическая память моего устройства).
Однако, когда прерывание запускает мой драйвер для запуска транзакции DMA, я вижу, что базовые функции вызываются в драйвере edma, но транзакция GPMC никогда не выполняется и не выполняется.Вызван обратный вызов DMA.
Является ли 0x3000000 действительным адресом для передачи в механизм DMA?