Merge branch 'topic/edma' into for-linus
Signed-off-by: Vinod Koul <vinod.koul@intel.com> Conflicts: drivers/dma/edma.c
This commit is contained in:
commit
7d9d43ace2
|
@ -2,9 +2,10 @@ Texas Instruments DMA Crossbar (DMA request router)
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible: "ti,dra7-dma-crossbar" for DRA7xx DMA crossbar
|
- compatible: "ti,dra7-dma-crossbar" for DRA7xx DMA crossbar
|
||||||
|
"ti,am335x-edma-crossbar" for AM335x and AM437x
|
||||||
- reg: Memory map for accessing module
|
- reg: Memory map for accessing module
|
||||||
- #dma-cells: Should be set to <1>.
|
- #dma-cells: Should be set to to match with the DMA controller's dma-cells
|
||||||
Clients should use the crossbar request number (input)
|
for ti,dra7-dma-crossbar and <3> for ti,am335x-edma-crossbar.
|
||||||
- dma-requests: Number of DMA requests the crossbar can receive
|
- dma-requests: Number of DMA requests the crossbar can receive
|
||||||
- dma-masters: phandle pointing to the DMA controller
|
- dma-masters: phandle pointing to the DMA controller
|
||||||
|
|
||||||
|
@ -14,6 +15,15 @@ The DMA controller node need to have the following poroperties:
|
||||||
Optional properties:
|
Optional properties:
|
||||||
- ti,dma-safe-map: Safe routing value for unused request lines
|
- ti,dma-safe-map: Safe routing value for unused request lines
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
When requesting channel via ti,dra7-dma-crossbar, the DMA clinet must request
|
||||||
|
the DMA event number as crossbar ID (input to the DMA crossbar).
|
||||||
|
|
||||||
|
For ti,am335x-edma-crossbar: the meaning of parameters of dmas for clients:
|
||||||
|
dmas = <&edma_xbar 12 0 1>; where <12> is the DMA request number, <0> is the TC
|
||||||
|
the event should be assigned and <1> is the mux selection for in the crossbar.
|
||||||
|
When mux 0 is used the DMA channel can be requested directly from edma node.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
/* DMA controller */
|
/* DMA controller */
|
||||||
|
@ -47,6 +57,7 @@ uart1: serial@4806a000 {
|
||||||
ti,hwmods = "uart1";
|
ti,hwmods = "uart1";
|
||||||
clock-frequency = <48000000>;
|
clock-frequency = <48000000>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
|
/* Requesting crossbar input 49 and 50 */
|
||||||
dmas = <&sdma_xbar 49>, <&sdma_xbar 50>;
|
dmas = <&sdma_xbar 49>, <&sdma_xbar 50>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,119 @@
|
||||||
TI EDMA
|
Texas Instruments eDMA
|
||||||
|
|
||||||
|
The eDMA3 consists of two components: Channel controller (CC) and Transfer
|
||||||
|
Controller(s) (TC). The CC is the main entry for DMA users since it is
|
||||||
|
responsible for the DMA channel handling, while the TCs are responsible to
|
||||||
|
execute the actual DMA tansfer.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
eDMA3 Channel Controller
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: "ti,edma3-tpcc" for the channel controller(s)
|
||||||
|
- #dma-cells: Should be set to <2>. The first number is the DMA request
|
||||||
|
number and the second is the TC the channel is serviced on.
|
||||||
|
- reg: Memory map of eDMA CC
|
||||||
|
- reg-names: "edma3_cc"
|
||||||
|
- interrupts: Interrupt lines for CCINT, MPERR and CCERRINT.
|
||||||
|
- interrupt-names: "edma3_ccint", "emda3_mperr" and "edma3_ccerrint"
|
||||||
|
- ti,tptcs: List of TPTCs associated with the eDMA in the following form:
|
||||||
|
<&tptc_phandle TC_priority_number>. The highest priority is 0.
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
- ti,hwmods: Name of the hwmods associated to the eDMA CC
|
||||||
|
- ti,edma-memcpy-channels: List of channels allocated to be used for memcpy, iow
|
||||||
|
these channels will be SW triggered channels. The list must
|
||||||
|
contain 16 bits numbers, see example.
|
||||||
|
- ti,edma-reserved-slot-ranges: PaRAM slot ranges which should not be used by
|
||||||
|
the driver, they are allocated to be used by for example the
|
||||||
|
DSP. See example.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
eDMA3 Transfer Controller
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: "ti,edma3-tptc" for the transfer controller(s)
|
||||||
|
- reg: Memory map of eDMA TC
|
||||||
|
- interrupts: Interrupt number for TCerrint.
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
- ti,hwmods: Name of the hwmods associated to the given eDMA TC
|
||||||
|
- interrupt-names: "edma3_tcerrint"
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Example:
|
||||||
|
|
||||||
|
edma: edma@49000000 {
|
||||||
|
compatible = "ti,edma3-tpcc";
|
||||||
|
ti,hwmods = "tpcc";
|
||||||
|
reg = <0x49000000 0x10000>;
|
||||||
|
reg-names = "edma3_cc";
|
||||||
|
interrupts = <12 13 14>;
|
||||||
|
interrupt-names = "edma3_ccint", "emda3_mperr", "edma3_ccerrint";
|
||||||
|
dma-requests = <64>;
|
||||||
|
#dma-cells = <2>;
|
||||||
|
|
||||||
|
ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 7>, <&edma_tptc2 0>;
|
||||||
|
|
||||||
|
/* Channel 20 and 21 is allocated for memcpy */
|
||||||
|
ti,edma-memcpy-channels = /bits/ 16 <20 21>;
|
||||||
|
/* The following PaRAM slots are reserved: 35-45 and 100-110 */
|
||||||
|
ti,edma-reserved-slot-ranges = /bits/ 16 <35 10>,
|
||||||
|
/bits/ 16 <100 10>;
|
||||||
|
};
|
||||||
|
|
||||||
|
edma_tptc0: tptc@49800000 {
|
||||||
|
compatible = "ti,edma3-tptc";
|
||||||
|
ti,hwmods = "tptc0";
|
||||||
|
reg = <0x49800000 0x100000>;
|
||||||
|
interrupts = <112>;
|
||||||
|
interrupt-names = "edm3_tcerrint";
|
||||||
|
};
|
||||||
|
|
||||||
|
edma_tptc1: tptc@49900000 {
|
||||||
|
compatible = "ti,edma3-tptc";
|
||||||
|
ti,hwmods = "tptc1";
|
||||||
|
reg = <0x49900000 0x100000>;
|
||||||
|
interrupts = <113>;
|
||||||
|
interrupt-names = "edm3_tcerrint";
|
||||||
|
};
|
||||||
|
|
||||||
|
edma_tptc2: tptc@49a00000 {
|
||||||
|
compatible = "ti,edma3-tptc";
|
||||||
|
ti,hwmods = "tptc2";
|
||||||
|
reg = <0x49a00000 0x100000>;
|
||||||
|
interrupts = <114>;
|
||||||
|
interrupt-names = "edm3_tcerrint";
|
||||||
|
};
|
||||||
|
|
||||||
|
sham: sham@53100000 {
|
||||||
|
compatible = "ti,omap4-sham";
|
||||||
|
ti,hwmods = "sham";
|
||||||
|
reg = <0x53100000 0x200>;
|
||||||
|
interrupts = <109>;
|
||||||
|
/* DMA channel 36 executed on eDMA TC0 - low priority queue */
|
||||||
|
dmas = <&edma 36 0>;
|
||||||
|
dma-names = "rx";
|
||||||
|
};
|
||||||
|
|
||||||
|
mcasp0: mcasp@48038000 {
|
||||||
|
compatible = "ti,am33xx-mcasp-audio";
|
||||||
|
ti,hwmods = "mcasp0";
|
||||||
|
reg = <0x48038000 0x2000>,
|
||||||
|
<0x46000000 0x400000>;
|
||||||
|
reg-names = "mpu", "dat";
|
||||||
|
interrupts = <80>, <81>;
|
||||||
|
interrupt-names = "tx", "rx";
|
||||||
|
status = "disabled";
|
||||||
|
/* DMA channels 8 and 9 executed on eDMA TC2 - high priority queue */
|
||||||
|
dmas = <&edma 8 2>,
|
||||||
|
<&edma 9 2>;
|
||||||
|
dma-names = "tx", "rx";
|
||||||
|
};
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
DEPRECATED binding, new DTS files must use the ti,edma3-tpcc/ti,edma3-tptc
|
||||||
|
binding.
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible : "ti,edma3"
|
- compatible : "ti,edma3"
|
||||||
|
|
|
@ -736,7 +736,6 @@ config ARCH_DAVINCI
|
||||||
select GENERIC_CLOCKEVENTS
|
select GENERIC_CLOCKEVENTS
|
||||||
select GENERIC_IRQ_CHIP
|
select GENERIC_IRQ_CHIP
|
||||||
select HAVE_IDE
|
select HAVE_IDE
|
||||||
select TI_PRIV_EDMA
|
|
||||||
select USE_OF
|
select USE_OF
|
||||||
select ZONE_DMA
|
select ZONE_DMA
|
||||||
help
|
help
|
||||||
|
|
|
@ -743,8 +743,8 @@ &mmc1 {
|
||||||
&mmc3 {
|
&mmc3 {
|
||||||
/* these are on the crossbar and are outlined in the
|
/* these are on the crossbar and are outlined in the
|
||||||
xbar-event-map element */
|
xbar-event-map element */
|
||||||
dmas = <&edma 12
|
dmas = <&edma_xbar 12 0 1
|
||||||
&edma 13>;
|
&edma_xbar 13 0 2>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
status = "okay";
|
status = "okay";
|
||||||
vmmc-supply = <&wlan_en_reg>;
|
vmmc-supply = <&wlan_en_reg>;
|
||||||
|
@ -766,11 +766,6 @@ wlcore: wlcore@0 {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
&edma {
|
|
||||||
ti,edma-xbar-event-map = /bits/ 16 <1 12
|
|
||||||
2 13>;
|
|
||||||
};
|
|
||||||
|
|
||||||
&sham {
|
&sham {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
|
@ -339,13 +339,6 @@ &mmc2 {
|
||||||
ti,non-removable;
|
ti,non-removable;
|
||||||
};
|
};
|
||||||
|
|
||||||
&edma {
|
|
||||||
/* Map eDMA MMC2 Events from Crossbar */
|
|
||||||
ti,edma-xbar-event-map = /bits/ 16 <1 12
|
|
||||||
2 13>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
&mmc3 {
|
&mmc3 {
|
||||||
/* Wifi & Bluetooth on MMC #3 */
|
/* Wifi & Bluetooth on MMC #3 */
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
@ -354,8 +347,8 @@ &mmc3 {
|
||||||
vmmmc-supply = <&v3v3c_reg>;
|
vmmmc-supply = <&v3v3c_reg>;
|
||||||
bus-width = <4>;
|
bus-width = <4>;
|
||||||
ti,non-removable;
|
ti,non-removable;
|
||||||
dmas = <&edma 12
|
dmas = <&edma_xbar 12 0 1
|
||||||
&edma 13>;
|
&edma_xbar 13 0 2>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -174,12 +174,54 @@ intc: interrupt-controller@48200000 {
|
||||||
};
|
};
|
||||||
|
|
||||||
edma: edma@49000000 {
|
edma: edma@49000000 {
|
||||||
compatible = "ti,edma3";
|
compatible = "ti,edma3-tpcc";
|
||||||
ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
|
ti,hwmods = "tpcc";
|
||||||
reg = <0x49000000 0x10000>,
|
reg = <0x49000000 0x10000>;
|
||||||
<0x44e10f90 0x40>;
|
reg-names = "edma3_cc";
|
||||||
interrupts = <12 13 14>;
|
interrupts = <12 13 14>;
|
||||||
#dma-cells = <1>;
|
interrupt-names = "edma3_ccint", "emda3_mperr",
|
||||||
|
"edma3_ccerrint";
|
||||||
|
dma-requests = <64>;
|
||||||
|
#dma-cells = <2>;
|
||||||
|
|
||||||
|
ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>,
|
||||||
|
<&edma_tptc2 0>;
|
||||||
|
|
||||||
|
ti,edma-memcpy-channels = /bits/ 16 <20 21>;
|
||||||
|
};
|
||||||
|
|
||||||
|
edma_tptc0: tptc@49800000 {
|
||||||
|
compatible = "ti,edma3-tptc";
|
||||||
|
ti,hwmods = "tptc0";
|
||||||
|
reg = <0x49800000 0x100000>;
|
||||||
|
interrupts = <112>;
|
||||||
|
interrupt-names = "edma3_tcerrint";
|
||||||
|
};
|
||||||
|
|
||||||
|
edma_tptc1: tptc@49900000 {
|
||||||
|
compatible = "ti,edma3-tptc";
|
||||||
|
ti,hwmods = "tptc1";
|
||||||
|
reg = <0x49900000 0x100000>;
|
||||||
|
interrupts = <113>;
|
||||||
|
interrupt-names = "edma3_tcerrint";
|
||||||
|
};
|
||||||
|
|
||||||
|
edma_tptc2: tptc@49a00000 {
|
||||||
|
compatible = "ti,edma3-tptc";
|
||||||
|
ti,hwmods = "tptc2";
|
||||||
|
reg = <0x49a00000 0x100000>;
|
||||||
|
interrupts = <114>;
|
||||||
|
interrupt-names = "edma3_tcerrint";
|
||||||
|
};
|
||||||
|
|
||||||
|
edma_xbar: dma-router@44e10f90 {
|
||||||
|
compatible = "ti,am335x-edma-crossbar";
|
||||||
|
reg = <0x44e10f90 0x40>;
|
||||||
|
|
||||||
|
#dma-cells = <3>;
|
||||||
|
dma-requests = <32>;
|
||||||
|
|
||||||
|
dma-masters = <&edma>;
|
||||||
};
|
};
|
||||||
|
|
||||||
gpio0: gpio@44e07000 {
|
gpio0: gpio@44e07000 {
|
||||||
|
@ -233,7 +275,7 @@ uart0: serial@44e09000 {
|
||||||
reg = <0x44e09000 0x2000>;
|
reg = <0x44e09000 0x2000>;
|
||||||
interrupts = <72>;
|
interrupts = <72>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
dmas = <&edma 26>, <&edma 27>;
|
dmas = <&edma 26 0>, <&edma 27 0>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -244,7 +286,7 @@ uart1: serial@48022000 {
|
||||||
reg = <0x48022000 0x2000>;
|
reg = <0x48022000 0x2000>;
|
||||||
interrupts = <73>;
|
interrupts = <73>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
dmas = <&edma 28>, <&edma 29>;
|
dmas = <&edma 28 0>, <&edma 29 0>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -255,7 +297,7 @@ uart2: serial@48024000 {
|
||||||
reg = <0x48024000 0x2000>;
|
reg = <0x48024000 0x2000>;
|
||||||
interrupts = <74>;
|
interrupts = <74>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
dmas = <&edma 30>, <&edma 31>;
|
dmas = <&edma 30 0>, <&edma 31 0>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -322,8 +364,8 @@ mmc1: mmc@48060000 {
|
||||||
ti,dual-volt;
|
ti,dual-volt;
|
||||||
ti,needs-special-reset;
|
ti,needs-special-reset;
|
||||||
ti,needs-special-hs-handling;
|
ti,needs-special-hs-handling;
|
||||||
dmas = <&edma 24
|
dmas = <&edma_xbar 24 0 0
|
||||||
&edma 25>;
|
&edma_xbar 25 0 0>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
interrupts = <64>;
|
interrupts = <64>;
|
||||||
interrupt-parent = <&intc>;
|
interrupt-parent = <&intc>;
|
||||||
|
@ -335,8 +377,8 @@ mmc2: mmc@481d8000 {
|
||||||
compatible = "ti,omap4-hsmmc";
|
compatible = "ti,omap4-hsmmc";
|
||||||
ti,hwmods = "mmc2";
|
ti,hwmods = "mmc2";
|
||||||
ti,needs-special-reset;
|
ti,needs-special-reset;
|
||||||
dmas = <&edma 2
|
dmas = <&edma 2 0
|
||||||
&edma 3>;
|
&edma 3 0>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
interrupts = <28>;
|
interrupts = <28>;
|
||||||
interrupt-parent = <&intc>;
|
interrupt-parent = <&intc>;
|
||||||
|
@ -474,10 +516,10 @@ spi0: spi@48030000 {
|
||||||
interrupts = <65>;
|
interrupts = <65>;
|
||||||
ti,spi-num-cs = <2>;
|
ti,spi-num-cs = <2>;
|
||||||
ti,hwmods = "spi0";
|
ti,hwmods = "spi0";
|
||||||
dmas = <&edma 16
|
dmas = <&edma 16 0
|
||||||
&edma 17
|
&edma 17 0
|
||||||
&edma 18
|
&edma 18 0
|
||||||
&edma 19>;
|
&edma 19 0>;
|
||||||
dma-names = "tx0", "rx0", "tx1", "rx1";
|
dma-names = "tx0", "rx0", "tx1", "rx1";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
@ -490,10 +532,10 @@ spi1: spi@481a0000 {
|
||||||
interrupts = <125>;
|
interrupts = <125>;
|
||||||
ti,spi-num-cs = <2>;
|
ti,spi-num-cs = <2>;
|
||||||
ti,hwmods = "spi1";
|
ti,hwmods = "spi1";
|
||||||
dmas = <&edma 42
|
dmas = <&edma 42 0
|
||||||
&edma 43
|
&edma 43 0
|
||||||
&edma 44
|
&edma 44 0
|
||||||
&edma 45>;
|
&edma 45 0>;
|
||||||
dma-names = "tx0", "rx0", "tx1", "rx1";
|
dma-names = "tx0", "rx0", "tx1", "rx1";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
@ -831,7 +873,7 @@ sham: sham@53100000 {
|
||||||
ti,hwmods = "sham";
|
ti,hwmods = "sham";
|
||||||
reg = <0x53100000 0x200>;
|
reg = <0x53100000 0x200>;
|
||||||
interrupts = <109>;
|
interrupts = <109>;
|
||||||
dmas = <&edma 36>;
|
dmas = <&edma 36 0>;
|
||||||
dma-names = "rx";
|
dma-names = "rx";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -840,8 +882,8 @@ aes: aes@53500000 {
|
||||||
ti,hwmods = "aes";
|
ti,hwmods = "aes";
|
||||||
reg = <0x53500000 0xa0>;
|
reg = <0x53500000 0xa0>;
|
||||||
interrupts = <103>;
|
interrupts = <103>;
|
||||||
dmas = <&edma 6>,
|
dmas = <&edma 6 0>,
|
||||||
<&edma 5>;
|
<&edma 5 0>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -854,8 +896,8 @@ mcasp0: mcasp@48038000 {
|
||||||
interrupts = <80>, <81>;
|
interrupts = <80>, <81>;
|
||||||
interrupt-names = "tx", "rx";
|
interrupt-names = "tx", "rx";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
dmas = <&edma 8>,
|
dmas = <&edma 8 2>,
|
||||||
<&edma 9>;
|
<&edma 9 2>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -868,8 +910,8 @@ mcasp1: mcasp@4803C000 {
|
||||||
interrupts = <82>, <83>;
|
interrupts = <82>, <83>;
|
||||||
interrupt-names = "tx", "rx";
|
interrupt-names = "tx", "rx";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
dmas = <&edma 10>,
|
dmas = <&edma 10 2>,
|
||||||
<&edma 11>;
|
<&edma 11 2>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -183,14 +183,56 @@ emif: emif@4c000000 {
|
||||||
};
|
};
|
||||||
|
|
||||||
edma: edma@49000000 {
|
edma: edma@49000000 {
|
||||||
compatible = "ti,edma3";
|
compatible = "ti,edma3-tpcc";
|
||||||
ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
|
ti,hwmods = "tpcc";
|
||||||
reg = <0x49000000 0x10000>,
|
reg = <0x49000000 0x10000>;
|
||||||
<0x44e10f90 0x10>;
|
reg-names = "edma3_cc";
|
||||||
interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
|
interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
<GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
|
<GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
<GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
|
<GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
#dma-cells = <1>;
|
interrupt-names = "edma3_ccint", "emda3_mperr",
|
||||||
|
"edma3_ccerrint";
|
||||||
|
dma-requests = <64>;
|
||||||
|
#dma-cells = <2>;
|
||||||
|
|
||||||
|
ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>,
|
||||||
|
<&edma_tptc2 0>;
|
||||||
|
|
||||||
|
ti,edma-memcpy-channels = /bits/ 16 <32 33>;
|
||||||
|
};
|
||||||
|
|
||||||
|
edma_tptc0: tptc@49800000 {
|
||||||
|
compatible = "ti,edma3-tptc";
|
||||||
|
ti,hwmods = "tptc0";
|
||||||
|
reg = <0x49800000 0x100000>;
|
||||||
|
interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
interrupt-names = "edma3_tcerrint";
|
||||||
|
};
|
||||||
|
|
||||||
|
edma_tptc1: tptc@49900000 {
|
||||||
|
compatible = "ti,edma3-tptc";
|
||||||
|
ti,hwmods = "tptc1";
|
||||||
|
reg = <0x49900000 0x100000>;
|
||||||
|
interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
interrupt-names = "edma3_tcerrint";
|
||||||
|
};
|
||||||
|
|
||||||
|
edma_tptc2: tptc@49a00000 {
|
||||||
|
compatible = "ti,edma3-tptc";
|
||||||
|
ti,hwmods = "tptc2";
|
||||||
|
reg = <0x49a00000 0x100000>;
|
||||||
|
interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
interrupt-names = "edma3_tcerrint";
|
||||||
|
};
|
||||||
|
|
||||||
|
edma_xbar: dma-router@44e10f90 {
|
||||||
|
compatible = "ti,am335x-edma-crossbar";
|
||||||
|
reg = <0x44e10f90 0x40>;
|
||||||
|
|
||||||
|
#dma-cells = <3>;
|
||||||
|
dma-requests = <64>;
|
||||||
|
|
||||||
|
dma-masters = <&edma>;
|
||||||
};
|
};
|
||||||
|
|
||||||
uart0: serial@44e09000 {
|
uart0: serial@44e09000 {
|
||||||
|
@ -495,8 +537,8 @@ mmc1: mmc@48060000 {
|
||||||
ti,hwmods = "mmc1";
|
ti,hwmods = "mmc1";
|
||||||
ti,dual-volt;
|
ti,dual-volt;
|
||||||
ti,needs-special-reset;
|
ti,needs-special-reset;
|
||||||
dmas = <&edma 24
|
dmas = <&edma 24 0>,
|
||||||
&edma 25>;
|
<&edma 25 0>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
|
@ -507,8 +549,8 @@ mmc2: mmc@481d8000 {
|
||||||
reg = <0x481d8000 0x1000>;
|
reg = <0x481d8000 0x1000>;
|
||||||
ti,hwmods = "mmc2";
|
ti,hwmods = "mmc2";
|
||||||
ti,needs-special-reset;
|
ti,needs-special-reset;
|
||||||
dmas = <&edma 2
|
dmas = <&edma 2 0>,
|
||||||
&edma 3>;
|
<&edma 3 0>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
|
@ -775,7 +817,7 @@ sham: sham@53100000 {
|
||||||
compatible = "ti,omap5-sham";
|
compatible = "ti,omap5-sham";
|
||||||
ti,hwmods = "sham";
|
ti,hwmods = "sham";
|
||||||
reg = <0x53100000 0x300>;
|
reg = <0x53100000 0x300>;
|
||||||
dmas = <&edma 36>;
|
dmas = <&edma 36 0>;
|
||||||
dma-names = "rx";
|
dma-names = "rx";
|
||||||
interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
};
|
};
|
||||||
|
@ -785,8 +827,8 @@ aes: aes@53501000 {
|
||||||
ti,hwmods = "aes";
|
ti,hwmods = "aes";
|
||||||
reg = <0x53501000 0xa0>;
|
reg = <0x53501000 0xa0>;
|
||||||
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
dmas = <&edma 6
|
dmas = <&edma 6 0>,
|
||||||
&edma 5>;
|
<&edma 5 0>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -795,8 +837,8 @@ des: des@53701000 {
|
||||||
ti,hwmods = "des";
|
ti,hwmods = "des";
|
||||||
reg = <0x53701000 0xa0>;
|
reg = <0x53701000 0xa0>;
|
||||||
interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
dmas = <&edma 34
|
dmas = <&edma 34 0>,
|
||||||
&edma 33>;
|
<&edma 33 0>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -809,8 +851,8 @@ mcasp0: mcasp@48038000 {
|
||||||
interrupts = <80>, <81>;
|
interrupts = <80>, <81>;
|
||||||
interrupt-names = "tx", "rx";
|
interrupt-names = "tx", "rx";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
dmas = <&edma 8>,
|
dmas = <&edma 8 2>,
|
||||||
<&edma 9>;
|
<&edma 9 2>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -823,8 +865,8 @@ mcasp1: mcasp@4803C000 {
|
||||||
interrupts = <82>, <83>;
|
interrupts = <82>, <83>;
|
||||||
interrupt-names = "tx", "rx";
|
interrupt-names = "tx", "rx";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
dmas = <&edma 10>,
|
dmas = <&edma 10 2>,
|
||||||
<&edma 11>;
|
<&edma 11 2>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -711,8 +711,8 @@ &mmc3 {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
/* these are on the crossbar and are outlined in the
|
/* these are on the crossbar and are outlined in the
|
||||||
xbar-event-map element */
|
xbar-event-map element */
|
||||||
dmas = <&edma 30
|
dmas = <&edma_xbar 30 0 1>,
|
||||||
&edma 31>;
|
<&edma_xbar 31 0 2>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
vmmc-supply = <&vmmcwl_fixed>;
|
vmmc-supply = <&vmmcwl_fixed>;
|
||||||
bus-width = <4>;
|
bus-width = <4>;
|
||||||
|
@ -733,11 +733,6 @@ wlcore: wlcore@0 {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
&edma {
|
|
||||||
ti,edma-xbar-event-map = /bits/ 16 <1 30
|
|
||||||
2 31>;
|
|
||||||
};
|
|
||||||
|
|
||||||
&uart3 {
|
&uart3 {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
|
|
|
@ -17,6 +17,3 @@ config SHARP_PARAM
|
||||||
|
|
||||||
config SHARP_SCOOP
|
config SHARP_SCOOP
|
||||||
bool
|
bool
|
||||||
|
|
||||||
config TI_PRIV_EDMA
|
|
||||||
bool
|
|
||||||
|
|
|
@ -15,6 +15,5 @@ obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o mcpm_platsmp.o vlock.o
|
||||||
CFLAGS_REMOVE_mcpm_entry.o = -pg
|
CFLAGS_REMOVE_mcpm_entry.o = -pg
|
||||||
AFLAGS_mcpm_head.o := -march=armv7-a
|
AFLAGS_mcpm_head.o := -march=armv7-a
|
||||||
AFLAGS_vlock.o := -march=armv7-a
|
AFLAGS_vlock.o := -march=armv7-a
|
||||||
obj-$(CONFIG_TI_PRIV_EDMA) += edma.o
|
|
||||||
obj-$(CONFIG_BL_SWITCHER) += bL_switcher.o
|
obj-$(CONFIG_BL_SWITCHER) += bL_switcher.o
|
||||||
obj-$(CONFIG_BL_SWITCHER_DUMMY_IF) += bL_switcher_dummy_if.o
|
obj-$(CONFIG_BL_SWITCHER_DUMMY_IF) += bL_switcher_dummy_if.o
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -147,150 +147,118 @@ static s8 da850_queue_priority_mapping[][2] = {
|
||||||
{-1, -1}
|
{-1, -1}
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct edma_soc_info da830_edma_cc0_info = {
|
static struct edma_soc_info da8xx_edma0_pdata = {
|
||||||
.queue_priority_mapping = da8xx_queue_priority_mapping,
|
.queue_priority_mapping = da8xx_queue_priority_mapping,
|
||||||
.default_queue = EVENTQ_1,
|
.default_queue = EVENTQ_1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct edma_soc_info *da830_edma_info[EDMA_MAX_CC] = {
|
static struct edma_soc_info da850_edma1_pdata = {
|
||||||
&da830_edma_cc0_info,
|
.queue_priority_mapping = da850_queue_priority_mapping,
|
||||||
|
.default_queue = EVENTQ_0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct edma_soc_info da850_edma_cc_info[] = {
|
static struct resource da8xx_edma0_resources[] = {
|
||||||
{
|
{
|
||||||
.queue_priority_mapping = da8xx_queue_priority_mapping,
|
.name = "edma3_cc",
|
||||||
.default_queue = EVENTQ_1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.queue_priority_mapping = da850_queue_priority_mapping,
|
|
||||||
.default_queue = EVENTQ_0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct edma_soc_info *da850_edma_info[EDMA_MAX_CC] = {
|
|
||||||
&da850_edma_cc_info[0],
|
|
||||||
&da850_edma_cc_info[1],
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource da830_edma_resources[] = {
|
|
||||||
{
|
|
||||||
.name = "edma_cc0",
|
|
||||||
.start = DA8XX_TPCC_BASE,
|
.start = DA8XX_TPCC_BASE,
|
||||||
.end = DA8XX_TPCC_BASE + SZ_32K - 1,
|
.end = DA8XX_TPCC_BASE + SZ_32K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma_tc0",
|
.name = "edma3_tc0",
|
||||||
.start = DA8XX_TPTC0_BASE,
|
.start = DA8XX_TPTC0_BASE,
|
||||||
.end = DA8XX_TPTC0_BASE + SZ_1K - 1,
|
.end = DA8XX_TPTC0_BASE + SZ_1K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma_tc1",
|
.name = "edma3_tc1",
|
||||||
.start = DA8XX_TPTC1_BASE,
|
.start = DA8XX_TPTC1_BASE,
|
||||||
.end = DA8XX_TPTC1_BASE + SZ_1K - 1,
|
.end = DA8XX_TPTC1_BASE + SZ_1K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma0",
|
.name = "edma3_ccint",
|
||||||
.start = IRQ_DA8XX_CCINT0,
|
.start = IRQ_DA8XX_CCINT0,
|
||||||
.flags = IORESOURCE_IRQ,
|
.flags = IORESOURCE_IRQ,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma0_err",
|
.name = "edma3_ccerrint",
|
||||||
.start = IRQ_DA8XX_CCERRINT,
|
.start = IRQ_DA8XX_CCERRINT,
|
||||||
.flags = IORESOURCE_IRQ,
|
.flags = IORESOURCE_IRQ,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct resource da850_edma_resources[] = {
|
static struct resource da850_edma1_resources[] = {
|
||||||
{
|
{
|
||||||
.name = "edma_cc0",
|
.name = "edma3_cc",
|
||||||
.start = DA8XX_TPCC_BASE,
|
|
||||||
.end = DA8XX_TPCC_BASE + SZ_32K - 1,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "edma_tc0",
|
|
||||||
.start = DA8XX_TPTC0_BASE,
|
|
||||||
.end = DA8XX_TPTC0_BASE + SZ_1K - 1,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "edma_tc1",
|
|
||||||
.start = DA8XX_TPTC1_BASE,
|
|
||||||
.end = DA8XX_TPTC1_BASE + SZ_1K - 1,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "edma_cc1",
|
|
||||||
.start = DA850_TPCC1_BASE,
|
.start = DA850_TPCC1_BASE,
|
||||||
.end = DA850_TPCC1_BASE + SZ_32K - 1,
|
.end = DA850_TPCC1_BASE + SZ_32K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma_tc2",
|
.name = "edma3_tc0",
|
||||||
.start = DA850_TPTC2_BASE,
|
.start = DA850_TPTC2_BASE,
|
||||||
.end = DA850_TPTC2_BASE + SZ_1K - 1,
|
.end = DA850_TPTC2_BASE + SZ_1K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma0",
|
.name = "edma3_ccint",
|
||||||
.start = IRQ_DA8XX_CCINT0,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "edma0_err",
|
|
||||||
.start = IRQ_DA8XX_CCERRINT,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "edma1",
|
|
||||||
.start = IRQ_DA850_CCINT1,
|
.start = IRQ_DA850_CCINT1,
|
||||||
.flags = IORESOURCE_IRQ,
|
.flags = IORESOURCE_IRQ,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma1_err",
|
.name = "edma3_ccerrint",
|
||||||
.start = IRQ_DA850_CCERRINT1,
|
.start = IRQ_DA850_CCERRINT1,
|
||||||
.flags = IORESOURCE_IRQ,
|
.flags = IORESOURCE_IRQ,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device da830_edma_device = {
|
static const struct platform_device_info da8xx_edma0_device __initconst = {
|
||||||
.name = "edma",
|
.name = "edma",
|
||||||
.id = -1,
|
.id = 0,
|
||||||
.dev = {
|
.dma_mask = DMA_BIT_MASK(32),
|
||||||
.platform_data = da830_edma_info,
|
.res = da8xx_edma0_resources,
|
||||||
},
|
.num_res = ARRAY_SIZE(da8xx_edma0_resources),
|
||||||
.num_resources = ARRAY_SIZE(da830_edma_resources),
|
.data = &da8xx_edma0_pdata,
|
||||||
.resource = da830_edma_resources,
|
.size_data = sizeof(da8xx_edma0_pdata),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device da850_edma_device = {
|
static const struct platform_device_info da850_edma1_device __initconst = {
|
||||||
.name = "edma",
|
.name = "edma",
|
||||||
.id = -1,
|
.id = 1,
|
||||||
.dev = {
|
.dma_mask = DMA_BIT_MASK(32),
|
||||||
.platform_data = da850_edma_info,
|
.res = da850_edma1_resources,
|
||||||
},
|
.num_res = ARRAY_SIZE(da850_edma1_resources),
|
||||||
.num_resources = ARRAY_SIZE(da850_edma_resources),
|
.data = &da850_edma1_pdata,
|
||||||
.resource = da850_edma_resources,
|
.size_data = sizeof(da850_edma1_pdata),
|
||||||
};
|
};
|
||||||
|
|
||||||
int __init da830_register_edma(struct edma_rsv_info *rsv)
|
int __init da830_register_edma(struct edma_rsv_info *rsv)
|
||||||
{
|
{
|
||||||
da830_edma_cc0_info.rsv = rsv;
|
struct platform_device *edma_pdev;
|
||||||
|
|
||||||
return platform_device_register(&da830_edma_device);
|
da8xx_edma0_pdata.rsv = rsv;
|
||||||
|
|
||||||
|
edma_pdev = platform_device_register_full(&da8xx_edma0_device);
|
||||||
|
return IS_ERR(edma_pdev) ? PTR_ERR(edma_pdev) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int __init da850_register_edma(struct edma_rsv_info *rsv[2])
|
int __init da850_register_edma(struct edma_rsv_info *rsv[2])
|
||||||
{
|
{
|
||||||
|
struct platform_device *edma_pdev;
|
||||||
|
|
||||||
if (rsv) {
|
if (rsv) {
|
||||||
da850_edma_cc_info[0].rsv = rsv[0];
|
da8xx_edma0_pdata.rsv = rsv[0];
|
||||||
da850_edma_cc_info[1].rsv = rsv[1];
|
da850_edma1_pdata.rsv = rsv[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return platform_device_register(&da850_edma_device);
|
edma_pdev = platform_device_register_full(&da8xx_edma0_device);
|
||||||
|
if (IS_ERR(edma_pdev)) {
|
||||||
|
pr_warn("%s: Failed to register eDMA0\n", __func__);
|
||||||
|
return PTR_ERR(edma_pdev);
|
||||||
|
}
|
||||||
|
edma_pdev = platform_device_register_full(&da850_edma1_device);
|
||||||
|
return IS_ERR(edma_pdev) ? PTR_ERR(edma_pdev) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct resource da8xx_i2c_resources0[] = {
|
static struct resource da8xx_i2c_resources0[] = {
|
||||||
|
|
|
@ -569,61 +569,58 @@ static u8 dm355_default_priorities[DAVINCI_N_AINTC_IRQ] = {
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
|
|
||||||
static s8
|
static s8 queue_priority_mapping[][2] = {
|
||||||
queue_priority_mapping[][2] = {
|
|
||||||
/* {event queue no, Priority} */
|
/* {event queue no, Priority} */
|
||||||
{0, 3},
|
{0, 3},
|
||||||
{1, 7},
|
{1, 7},
|
||||||
{-1, -1},
|
{-1, -1},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct edma_soc_info edma_cc0_info = {
|
static struct edma_soc_info dm355_edma_pdata = {
|
||||||
.queue_priority_mapping = queue_priority_mapping,
|
.queue_priority_mapping = queue_priority_mapping,
|
||||||
.default_queue = EVENTQ_1,
|
.default_queue = EVENTQ_1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct edma_soc_info *dm355_edma_info[EDMA_MAX_CC] = {
|
|
||||||
&edma_cc0_info,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource edma_resources[] = {
|
static struct resource edma_resources[] = {
|
||||||
{
|
{
|
||||||
.name = "edma_cc0",
|
.name = "edma3_cc",
|
||||||
.start = 0x01c00000,
|
.start = 0x01c00000,
|
||||||
.end = 0x01c00000 + SZ_64K - 1,
|
.end = 0x01c00000 + SZ_64K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma_tc0",
|
.name = "edma3_tc0",
|
||||||
.start = 0x01c10000,
|
.start = 0x01c10000,
|
||||||
.end = 0x01c10000 + SZ_1K - 1,
|
.end = 0x01c10000 + SZ_1K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma_tc1",
|
.name = "edma3_tc1",
|
||||||
.start = 0x01c10400,
|
.start = 0x01c10400,
|
||||||
.end = 0x01c10400 + SZ_1K - 1,
|
.end = 0x01c10400 + SZ_1K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma0",
|
.name = "edma3_ccint",
|
||||||
.start = IRQ_CCINT0,
|
.start = IRQ_CCINT0,
|
||||||
.flags = IORESOURCE_IRQ,
|
.flags = IORESOURCE_IRQ,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma0_err",
|
.name = "edma3_ccerrint",
|
||||||
.start = IRQ_CCERRINT,
|
.start = IRQ_CCERRINT,
|
||||||
.flags = IORESOURCE_IRQ,
|
.flags = IORESOURCE_IRQ,
|
||||||
},
|
},
|
||||||
/* not using (or muxing) TC*_ERR */
|
/* not using (or muxing) TC*_ERR */
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device dm355_edma_device = {
|
static const struct platform_device_info dm355_edma_device __initconst = {
|
||||||
.name = "edma",
|
.name = "edma",
|
||||||
.id = 0,
|
.id = 0,
|
||||||
.dev.platform_data = dm355_edma_info,
|
.dma_mask = DMA_BIT_MASK(32),
|
||||||
.num_resources = ARRAY_SIZE(edma_resources),
|
.res = edma_resources,
|
||||||
.resource = edma_resources,
|
.num_res = ARRAY_SIZE(edma_resources),
|
||||||
|
.data = &dm355_edma_pdata,
|
||||||
|
.size_data = sizeof(dm355_edma_pdata),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct resource dm355_asp1_resources[] = {
|
static struct resource dm355_asp1_resources[] = {
|
||||||
|
@ -1062,13 +1059,18 @@ int __init dm355_init_video(struct vpfe_config *vpfe_cfg,
|
||||||
|
|
||||||
static int __init dm355_init_devices(void)
|
static int __init dm355_init_devices(void)
|
||||||
{
|
{
|
||||||
|
struct platform_device *edma_pdev;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!cpu_is_davinci_dm355())
|
if (!cpu_is_davinci_dm355())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
davinci_cfg_reg(DM355_INT_EDMA_CC);
|
davinci_cfg_reg(DM355_INT_EDMA_CC);
|
||||||
platform_device_register(&dm355_edma_device);
|
edma_pdev = platform_device_register_full(&dm355_edma_device);
|
||||||
|
if (IS_ERR(edma_pdev)) {
|
||||||
|
pr_warn("%s: Failed to register eDMA\n", __func__);
|
||||||
|
return PTR_ERR(edma_pdev);
|
||||||
|
}
|
||||||
|
|
||||||
ret = davinci_init_wdt();
|
ret = davinci_init_wdt();
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -853,8 +853,7 @@ static u8 dm365_default_priorities[DAVINCI_N_AINTC_IRQ] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Four Transfer Controllers on DM365 */
|
/* Four Transfer Controllers on DM365 */
|
||||||
static s8
|
static s8 dm365_queue_priority_mapping[][2] = {
|
||||||
dm365_queue_priority_mapping[][2] = {
|
|
||||||
/* {event queue no, Priority} */
|
/* {event queue no, Priority} */
|
||||||
{0, 7},
|
{0, 7},
|
||||||
{1, 7},
|
{1, 7},
|
||||||
|
@ -863,53 +862,49 @@ dm365_queue_priority_mapping[][2] = {
|
||||||
{-1, -1},
|
{-1, -1},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct edma_soc_info edma_cc0_info = {
|
static struct edma_soc_info dm365_edma_pdata = {
|
||||||
.queue_priority_mapping = dm365_queue_priority_mapping,
|
.queue_priority_mapping = dm365_queue_priority_mapping,
|
||||||
.default_queue = EVENTQ_3,
|
.default_queue = EVENTQ_3,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct edma_soc_info *dm365_edma_info[EDMA_MAX_CC] = {
|
|
||||||
&edma_cc0_info,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource edma_resources[] = {
|
static struct resource edma_resources[] = {
|
||||||
{
|
{
|
||||||
.name = "edma_cc0",
|
.name = "edma3_cc",
|
||||||
.start = 0x01c00000,
|
.start = 0x01c00000,
|
||||||
.end = 0x01c00000 + SZ_64K - 1,
|
.end = 0x01c00000 + SZ_64K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma_tc0",
|
.name = "edma3_tc0",
|
||||||
.start = 0x01c10000,
|
.start = 0x01c10000,
|
||||||
.end = 0x01c10000 + SZ_1K - 1,
|
.end = 0x01c10000 + SZ_1K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma_tc1",
|
.name = "edma3_tc1",
|
||||||
.start = 0x01c10400,
|
.start = 0x01c10400,
|
||||||
.end = 0x01c10400 + SZ_1K - 1,
|
.end = 0x01c10400 + SZ_1K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma_tc2",
|
.name = "edma3_tc2",
|
||||||
.start = 0x01c10800,
|
.start = 0x01c10800,
|
||||||
.end = 0x01c10800 + SZ_1K - 1,
|
.end = 0x01c10800 + SZ_1K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma_tc3",
|
.name = "edma3_tc3",
|
||||||
.start = 0x01c10c00,
|
.start = 0x01c10c00,
|
||||||
.end = 0x01c10c00 + SZ_1K - 1,
|
.end = 0x01c10c00 + SZ_1K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma0",
|
.name = "edma3_ccint",
|
||||||
.start = IRQ_CCINT0,
|
.start = IRQ_CCINT0,
|
||||||
.flags = IORESOURCE_IRQ,
|
.flags = IORESOURCE_IRQ,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma0_err",
|
.name = "edma3_ccerrint",
|
||||||
.start = IRQ_CCERRINT,
|
.start = IRQ_CCERRINT,
|
||||||
.flags = IORESOURCE_IRQ,
|
.flags = IORESOURCE_IRQ,
|
||||||
},
|
},
|
||||||
|
@ -919,7 +914,7 @@ static struct resource edma_resources[] = {
|
||||||
static struct platform_device dm365_edma_device = {
|
static struct platform_device dm365_edma_device = {
|
||||||
.name = "edma",
|
.name = "edma",
|
||||||
.id = 0,
|
.id = 0,
|
||||||
.dev.platform_data = dm365_edma_info,
|
.dev.platform_data = &dm365_edma_pdata,
|
||||||
.num_resources = ARRAY_SIZE(edma_resources),
|
.num_resources = ARRAY_SIZE(edma_resources),
|
||||||
.resource = edma_resources,
|
.resource = edma_resources,
|
||||||
};
|
};
|
||||||
|
|
|
@ -498,61 +498,58 @@ static u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
|
|
||||||
static s8
|
static s8 queue_priority_mapping[][2] = {
|
||||||
queue_priority_mapping[][2] = {
|
|
||||||
/* {event queue no, Priority} */
|
/* {event queue no, Priority} */
|
||||||
{0, 3},
|
{0, 3},
|
||||||
{1, 7},
|
{1, 7},
|
||||||
{-1, -1},
|
{-1, -1},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct edma_soc_info edma_cc0_info = {
|
static struct edma_soc_info dm644x_edma_pdata = {
|
||||||
.queue_priority_mapping = queue_priority_mapping,
|
.queue_priority_mapping = queue_priority_mapping,
|
||||||
.default_queue = EVENTQ_1,
|
.default_queue = EVENTQ_1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct edma_soc_info *dm644x_edma_info[EDMA_MAX_CC] = {
|
|
||||||
&edma_cc0_info,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource edma_resources[] = {
|
static struct resource edma_resources[] = {
|
||||||
{
|
{
|
||||||
.name = "edma_cc0",
|
.name = "edma3_cc",
|
||||||
.start = 0x01c00000,
|
.start = 0x01c00000,
|
||||||
.end = 0x01c00000 + SZ_64K - 1,
|
.end = 0x01c00000 + SZ_64K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma_tc0",
|
.name = "edma3_tc0",
|
||||||
.start = 0x01c10000,
|
.start = 0x01c10000,
|
||||||
.end = 0x01c10000 + SZ_1K - 1,
|
.end = 0x01c10000 + SZ_1K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma_tc1",
|
.name = "edma3_tc1",
|
||||||
.start = 0x01c10400,
|
.start = 0x01c10400,
|
||||||
.end = 0x01c10400 + SZ_1K - 1,
|
.end = 0x01c10400 + SZ_1K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma0",
|
.name = "edma3_ccint",
|
||||||
.start = IRQ_CCINT0,
|
.start = IRQ_CCINT0,
|
||||||
.flags = IORESOURCE_IRQ,
|
.flags = IORESOURCE_IRQ,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma0_err",
|
.name = "edma3_ccerrint",
|
||||||
.start = IRQ_CCERRINT,
|
.start = IRQ_CCERRINT,
|
||||||
.flags = IORESOURCE_IRQ,
|
.flags = IORESOURCE_IRQ,
|
||||||
},
|
},
|
||||||
/* not using TC*_ERR */
|
/* not using TC*_ERR */
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device dm644x_edma_device = {
|
static const struct platform_device_info dm644x_edma_device __initconst = {
|
||||||
.name = "edma",
|
.name = "edma",
|
||||||
.id = 0,
|
.id = 0,
|
||||||
.dev.platform_data = dm644x_edma_info,
|
.dma_mask = DMA_BIT_MASK(32),
|
||||||
.num_resources = ARRAY_SIZE(edma_resources),
|
.res = edma_resources,
|
||||||
.resource = edma_resources,
|
.num_res = ARRAY_SIZE(edma_resources),
|
||||||
|
.data = &dm644x_edma_pdata,
|
||||||
|
.size_data = sizeof(dm644x_edma_pdata),
|
||||||
};
|
};
|
||||||
|
|
||||||
/* DM6446 EVM uses ASP0; line-out is a pair of RCA jacks */
|
/* DM6446 EVM uses ASP0; line-out is a pair of RCA jacks */
|
||||||
|
@ -950,12 +947,17 @@ int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
|
||||||
|
|
||||||
static int __init dm644x_init_devices(void)
|
static int __init dm644x_init_devices(void)
|
||||||
{
|
{
|
||||||
|
struct platform_device *edma_pdev;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!cpu_is_davinci_dm644x())
|
if (!cpu_is_davinci_dm644x())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
platform_device_register(&dm644x_edma_device);
|
edma_pdev = platform_device_register_full(&dm644x_edma_device);
|
||||||
|
if (IS_ERR(edma_pdev)) {
|
||||||
|
pr_warn("%s: Failed to register eDMA\n", __func__);
|
||||||
|
return PTR_ERR(edma_pdev);
|
||||||
|
}
|
||||||
|
|
||||||
platform_device_register(&dm644x_mdio_device);
|
platform_device_register(&dm644x_mdio_device);
|
||||||
platform_device_register(&dm644x_emac_device);
|
platform_device_register(&dm644x_emac_device);
|
||||||
|
|
|
@ -531,8 +531,7 @@ static u8 dm646x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* Four Transfer Controllers on DM646x */
|
/* Four Transfer Controllers on DM646x */
|
||||||
static s8
|
static s8 dm646x_queue_priority_mapping[][2] = {
|
||||||
dm646x_queue_priority_mapping[][2] = {
|
|
||||||
/* {event queue no, Priority} */
|
/* {event queue no, Priority} */
|
||||||
{0, 4},
|
{0, 4},
|
||||||
{1, 0},
|
{1, 0},
|
||||||
|
@ -541,65 +540,63 @@ dm646x_queue_priority_mapping[][2] = {
|
||||||
{-1, -1},
|
{-1, -1},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct edma_soc_info edma_cc0_info = {
|
static struct edma_soc_info dm646x_edma_pdata = {
|
||||||
.queue_priority_mapping = dm646x_queue_priority_mapping,
|
.queue_priority_mapping = dm646x_queue_priority_mapping,
|
||||||
.default_queue = EVENTQ_1,
|
.default_queue = EVENTQ_1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct edma_soc_info *dm646x_edma_info[EDMA_MAX_CC] = {
|
|
||||||
&edma_cc0_info,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource edma_resources[] = {
|
static struct resource edma_resources[] = {
|
||||||
{
|
{
|
||||||
.name = "edma_cc0",
|
.name = "edma3_cc",
|
||||||
.start = 0x01c00000,
|
.start = 0x01c00000,
|
||||||
.end = 0x01c00000 + SZ_64K - 1,
|
.end = 0x01c00000 + SZ_64K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma_tc0",
|
.name = "edma3_tc0",
|
||||||
.start = 0x01c10000,
|
.start = 0x01c10000,
|
||||||
.end = 0x01c10000 + SZ_1K - 1,
|
.end = 0x01c10000 + SZ_1K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma_tc1",
|
.name = "edma3_tc1",
|
||||||
.start = 0x01c10400,
|
.start = 0x01c10400,
|
||||||
.end = 0x01c10400 + SZ_1K - 1,
|
.end = 0x01c10400 + SZ_1K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma_tc2",
|
.name = "edma3_tc2",
|
||||||
.start = 0x01c10800,
|
.start = 0x01c10800,
|
||||||
.end = 0x01c10800 + SZ_1K - 1,
|
.end = 0x01c10800 + SZ_1K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma_tc3",
|
.name = "edma3_tc3",
|
||||||
.start = 0x01c10c00,
|
.start = 0x01c10c00,
|
||||||
.end = 0x01c10c00 + SZ_1K - 1,
|
.end = 0x01c10c00 + SZ_1K - 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma0",
|
.name = "edma3_ccint",
|
||||||
.start = IRQ_CCINT0,
|
.start = IRQ_CCINT0,
|
||||||
.flags = IORESOURCE_IRQ,
|
.flags = IORESOURCE_IRQ,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "edma0_err",
|
.name = "edma3_ccerrint",
|
||||||
.start = IRQ_CCERRINT,
|
.start = IRQ_CCERRINT,
|
||||||
.flags = IORESOURCE_IRQ,
|
.flags = IORESOURCE_IRQ,
|
||||||
},
|
},
|
||||||
/* not using TC*_ERR */
|
/* not using TC*_ERR */
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device dm646x_edma_device = {
|
static const struct platform_device_info dm646x_edma_device __initconst = {
|
||||||
.name = "edma",
|
.name = "edma",
|
||||||
.id = 0,
|
.id = 0,
|
||||||
.dev.platform_data = dm646x_edma_info,
|
.dma_mask = DMA_BIT_MASK(32),
|
||||||
.num_resources = ARRAY_SIZE(edma_resources),
|
.res = edma_resources,
|
||||||
.resource = edma_resources,
|
.num_res = ARRAY_SIZE(edma_resources),
|
||||||
|
.data = &dm646x_edma_pdata,
|
||||||
|
.size_data = sizeof(dm646x_edma_pdata),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct resource dm646x_mcasp0_resources[] = {
|
static struct resource dm646x_mcasp0_resources[] = {
|
||||||
|
@ -936,9 +933,12 @@ void dm646x_setup_vpif(struct vpif_display_config *display_config,
|
||||||
|
|
||||||
int __init dm646x_init_edma(struct edma_rsv_info *rsv)
|
int __init dm646x_init_edma(struct edma_rsv_info *rsv)
|
||||||
{
|
{
|
||||||
edma_cc0_info.rsv = rsv;
|
struct platform_device *edma_pdev;
|
||||||
|
|
||||||
return platform_device_register(&dm646x_edma_device);
|
dm646x_edma_pdata.rsv = rsv;
|
||||||
|
|
||||||
|
edma_pdev = platform_device_register_full(&dm646x_edma_device);
|
||||||
|
return IS_ERR(edma_pdev) ? PTR_ERR(edma_pdev) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init dm646x_init(void)
|
void __init dm646x_init(void)
|
||||||
|
|
|
@ -90,7 +90,6 @@ config ARCH_OMAP2PLUS
|
||||||
select OMAP_GPMC
|
select OMAP_GPMC
|
||||||
select PINCTRL
|
select PINCTRL
|
||||||
select SOC_BUS
|
select SOC_BUS
|
||||||
select TI_PRIV_EDMA
|
|
||||||
select OMAP_IRQCHIP
|
select OMAP_IRQCHIP
|
||||||
help
|
help
|
||||||
Systems based on OMAP2, OMAP3, OMAP4 or OMAP5
|
Systems based on OMAP2, OMAP3, OMAP4 or OMAP5
|
||||||
|
|
|
@ -486,7 +486,7 @@ config TI_EDMA
|
||||||
depends on ARCH_DAVINCI || ARCH_OMAP || ARCH_KEYSTONE
|
depends on ARCH_DAVINCI || ARCH_OMAP || ARCH_KEYSTONE
|
||||||
select DMA_ENGINE
|
select DMA_ENGINE
|
||||||
select DMA_VIRTUAL_CHANNELS
|
select DMA_VIRTUAL_CHANNELS
|
||||||
select TI_PRIV_EDMA
|
select TI_DMA_CROSSBAR if ARCH_OMAP
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
Enable support for the TI EDMA controller. This DMA
|
Enable support for the TI EDMA controller. This DMA
|
||||||
|
|
1857
drivers/dma/edma.c
1857
drivers/dma/edma.c
File diff suppressed because it is too large
Load Diff
|
@ -17,13 +17,184 @@
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/of_dma.h>
|
#include <linux/of_dma.h>
|
||||||
|
|
||||||
#define TI_XBAR_OUTPUTS 127
|
#define TI_XBAR_DRA7 0
|
||||||
#define TI_XBAR_INPUTS 256
|
#define TI_XBAR_AM335X 1
|
||||||
|
|
||||||
|
static const struct of_device_id ti_dma_xbar_match[] = {
|
||||||
|
{
|
||||||
|
.compatible = "ti,dra7-dma-crossbar",
|
||||||
|
.data = (void *)TI_XBAR_DRA7,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.compatible = "ti,am335x-edma-crossbar",
|
||||||
|
.data = (void *)TI_XBAR_AM335X,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Crossbar on AM335x/AM437x family */
|
||||||
|
#define TI_AM335X_XBAR_LINES 64
|
||||||
|
|
||||||
|
struct ti_am335x_xbar_data {
|
||||||
|
void __iomem *iomem;
|
||||||
|
|
||||||
|
struct dma_router dmarouter;
|
||||||
|
|
||||||
|
u32 xbar_events; /* maximum number of events to select in xbar */
|
||||||
|
u32 dma_requests; /* number of DMA requests on eDMA */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ti_am335x_xbar_map {
|
||||||
|
u16 dma_line;
|
||||||
|
u16 mux_val;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void ti_am335x_xbar_write(void __iomem *iomem, int event, u16 val)
|
||||||
|
{
|
||||||
|
writeb_relaxed(val & 0x1f, iomem + event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ti_am335x_xbar_free(struct device *dev, void *route_data)
|
||||||
|
{
|
||||||
|
struct ti_am335x_xbar_data *xbar = dev_get_drvdata(dev);
|
||||||
|
struct ti_am335x_xbar_map *map = route_data;
|
||||||
|
|
||||||
|
dev_dbg(dev, "Unmapping XBAR event %u on channel %u\n",
|
||||||
|
map->mux_val, map->dma_line);
|
||||||
|
|
||||||
|
ti_am335x_xbar_write(xbar->iomem, map->dma_line, 0);
|
||||||
|
kfree(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *ti_am335x_xbar_route_allocate(struct of_phandle_args *dma_spec,
|
||||||
|
struct of_dma *ofdma)
|
||||||
|
{
|
||||||
|
struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
|
||||||
|
struct ti_am335x_xbar_data *xbar = platform_get_drvdata(pdev);
|
||||||
|
struct ti_am335x_xbar_map *map;
|
||||||
|
|
||||||
|
if (dma_spec->args_count != 3)
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
|
if (dma_spec->args[2] >= xbar->xbar_events) {
|
||||||
|
dev_err(&pdev->dev, "Invalid XBAR event number: %d\n",
|
||||||
|
dma_spec->args[2]);
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dma_spec->args[0] >= xbar->dma_requests) {
|
||||||
|
dev_err(&pdev->dev, "Invalid DMA request line number: %d\n",
|
||||||
|
dma_spec->args[0]);
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The of_node_put() will be done in the core for the node */
|
||||||
|
dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
|
||||||
|
if (!dma_spec->np) {
|
||||||
|
dev_err(&pdev->dev, "Can't get DMA master\n");
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
map = kzalloc(sizeof(*map), GFP_KERNEL);
|
||||||
|
if (!map) {
|
||||||
|
of_node_put(dma_spec->np);
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
map->dma_line = (u16)dma_spec->args[0];
|
||||||
|
map->mux_val = (u16)dma_spec->args[2];
|
||||||
|
|
||||||
|
dma_spec->args[2] = 0;
|
||||||
|
dma_spec->args_count = 2;
|
||||||
|
|
||||||
|
dev_dbg(&pdev->dev, "Mapping XBAR event%u to DMA%u\n",
|
||||||
|
map->mux_val, map->dma_line);
|
||||||
|
|
||||||
|
ti_am335x_xbar_write(xbar->iomem, map->dma_line, map->mux_val);
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id ti_am335x_master_match[] = {
|
||||||
|
{ .compatible = "ti,edma3-tpcc", },
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int ti_am335x_xbar_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
const struct of_device_id *match;
|
||||||
|
struct device_node *dma_node;
|
||||||
|
struct ti_am335x_xbar_data *xbar;
|
||||||
|
struct resource *res;
|
||||||
|
void __iomem *iomem;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
if (!node)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
xbar = devm_kzalloc(&pdev->dev, sizeof(*xbar), GFP_KERNEL);
|
||||||
|
if (!xbar)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
dma_node = of_parse_phandle(node, "dma-masters", 0);
|
||||||
|
if (!dma_node) {
|
||||||
|
dev_err(&pdev->dev, "Can't get DMA master node\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
match = of_match_node(ti_am335x_master_match, dma_node);
|
||||||
|
if (!match) {
|
||||||
|
dev_err(&pdev->dev, "DMA master is not supported\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (of_property_read_u32(dma_node, "dma-requests",
|
||||||
|
&xbar->dma_requests)) {
|
||||||
|
dev_info(&pdev->dev,
|
||||||
|
"Missing XBAR output information, using %u.\n",
|
||||||
|
TI_AM335X_XBAR_LINES);
|
||||||
|
xbar->dma_requests = TI_AM335X_XBAR_LINES;
|
||||||
|
}
|
||||||
|
of_node_put(dma_node);
|
||||||
|
|
||||||
|
if (of_property_read_u32(node, "dma-requests", &xbar->xbar_events)) {
|
||||||
|
dev_info(&pdev->dev,
|
||||||
|
"Missing XBAR input information, using %u.\n",
|
||||||
|
TI_AM335X_XBAR_LINES);
|
||||||
|
xbar->xbar_events = TI_AM335X_XBAR_LINES;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
iomem = devm_ioremap_resource(&pdev->dev, res);
|
||||||
|
if (IS_ERR(iomem))
|
||||||
|
return PTR_ERR(iomem);
|
||||||
|
|
||||||
|
xbar->iomem = iomem;
|
||||||
|
|
||||||
|
xbar->dmarouter.dev = &pdev->dev;
|
||||||
|
xbar->dmarouter.route_free = ti_am335x_xbar_free;
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, xbar);
|
||||||
|
|
||||||
|
/* Reset the crossbar */
|
||||||
|
for (i = 0; i < xbar->dma_requests; i++)
|
||||||
|
ti_am335x_xbar_write(xbar->iomem, i, 0);
|
||||||
|
|
||||||
|
ret = of_dma_router_register(node, ti_am335x_xbar_route_allocate,
|
||||||
|
&xbar->dmarouter);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Crossbar on DRA7xx family */
|
||||||
|
#define TI_DRA7_XBAR_OUTPUTS 127
|
||||||
|
#define TI_DRA7_XBAR_INPUTS 256
|
||||||
|
|
||||||
#define TI_XBAR_EDMA_OFFSET 0
|
#define TI_XBAR_EDMA_OFFSET 0
|
||||||
#define TI_XBAR_SDMA_OFFSET 1
|
#define TI_XBAR_SDMA_OFFSET 1
|
||||||
|
|
||||||
struct ti_dma_xbar_data {
|
struct ti_dra7_xbar_data {
|
||||||
void __iomem *iomem;
|
void __iomem *iomem;
|
||||||
|
|
||||||
struct dma_router dmarouter;
|
struct dma_router dmarouter;
|
||||||
|
@ -35,35 +206,35 @@ struct ti_dma_xbar_data {
|
||||||
u32 dma_offset;
|
u32 dma_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ti_dma_xbar_map {
|
struct ti_dra7_xbar_map {
|
||||||
u16 xbar_in;
|
u16 xbar_in;
|
||||||
int xbar_out;
|
int xbar_out;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void ti_dma_xbar_write(void __iomem *iomem, int xbar, u16 val)
|
static inline void ti_dra7_xbar_write(void __iomem *iomem, int xbar, u16 val)
|
||||||
{
|
{
|
||||||
writew_relaxed(val, iomem + (xbar * 2));
|
writew_relaxed(val, iomem + (xbar * 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ti_dma_xbar_free(struct device *dev, void *route_data)
|
static void ti_dra7_xbar_free(struct device *dev, void *route_data)
|
||||||
{
|
{
|
||||||
struct ti_dma_xbar_data *xbar = dev_get_drvdata(dev);
|
struct ti_dra7_xbar_data *xbar = dev_get_drvdata(dev);
|
||||||
struct ti_dma_xbar_map *map = route_data;
|
struct ti_dra7_xbar_map *map = route_data;
|
||||||
|
|
||||||
dev_dbg(dev, "Unmapping XBAR%u (was routed to %d)\n",
|
dev_dbg(dev, "Unmapping XBAR%u (was routed to %d)\n",
|
||||||
map->xbar_in, map->xbar_out);
|
map->xbar_in, map->xbar_out);
|
||||||
|
|
||||||
ti_dma_xbar_write(xbar->iomem, map->xbar_out, xbar->safe_val);
|
ti_dra7_xbar_write(xbar->iomem, map->xbar_out, xbar->safe_val);
|
||||||
idr_remove(&xbar->map_idr, map->xbar_out);
|
idr_remove(&xbar->map_idr, map->xbar_out);
|
||||||
kfree(map);
|
kfree(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *ti_dma_xbar_route_allocate(struct of_phandle_args *dma_spec,
|
static void *ti_dra7_xbar_route_allocate(struct of_phandle_args *dma_spec,
|
||||||
struct of_dma *ofdma)
|
struct of_dma *ofdma)
|
||||||
{
|
{
|
||||||
struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
|
struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
|
||||||
struct ti_dma_xbar_data *xbar = platform_get_drvdata(pdev);
|
struct ti_dra7_xbar_data *xbar = platform_get_drvdata(pdev);
|
||||||
struct ti_dma_xbar_map *map;
|
struct ti_dra7_xbar_map *map;
|
||||||
|
|
||||||
if (dma_spec->args[0] >= xbar->xbar_requests) {
|
if (dma_spec->args[0] >= xbar->xbar_requests) {
|
||||||
dev_err(&pdev->dev, "Invalid XBAR request number: %d\n",
|
dev_err(&pdev->dev, "Invalid XBAR request number: %d\n",
|
||||||
|
@ -93,12 +264,12 @@ static void *ti_dma_xbar_route_allocate(struct of_phandle_args *dma_spec,
|
||||||
dev_dbg(&pdev->dev, "Mapping XBAR%u to DMA%d\n",
|
dev_dbg(&pdev->dev, "Mapping XBAR%u to DMA%d\n",
|
||||||
map->xbar_in, map->xbar_out);
|
map->xbar_in, map->xbar_out);
|
||||||
|
|
||||||
ti_dma_xbar_write(xbar->iomem, map->xbar_out, map->xbar_in);
|
ti_dra7_xbar_write(xbar->iomem, map->xbar_out, map->xbar_in);
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id ti_dma_master_match[] = {
|
static const struct of_device_id ti_dra7_master_match[] = {
|
||||||
{
|
{
|
||||||
.compatible = "ti,omap4430-sdma",
|
.compatible = "ti,omap4430-sdma",
|
||||||
.data = (void *)TI_XBAR_SDMA_OFFSET,
|
.data = (void *)TI_XBAR_SDMA_OFFSET,
|
||||||
|
@ -110,12 +281,12 @@ static const struct of_device_id ti_dma_master_match[] = {
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int ti_dma_xbar_probe(struct platform_device *pdev)
|
static int ti_dra7_xbar_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
const struct of_device_id *match;
|
const struct of_device_id *match;
|
||||||
struct device_node *dma_node;
|
struct device_node *dma_node;
|
||||||
struct ti_dma_xbar_data *xbar;
|
struct ti_dra7_xbar_data *xbar;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
u32 safe_val;
|
u32 safe_val;
|
||||||
void __iomem *iomem;
|
void __iomem *iomem;
|
||||||
|
@ -136,7 +307,7 @@ static int ti_dma_xbar_probe(struct platform_device *pdev)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
match = of_match_node(ti_dma_master_match, dma_node);
|
match = of_match_node(ti_dra7_master_match, dma_node);
|
||||||
if (!match) {
|
if (!match) {
|
||||||
dev_err(&pdev->dev, "DMA master is not supported\n");
|
dev_err(&pdev->dev, "DMA master is not supported\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -146,16 +317,16 @@ static int ti_dma_xbar_probe(struct platform_device *pdev)
|
||||||
&xbar->dma_requests)) {
|
&xbar->dma_requests)) {
|
||||||
dev_info(&pdev->dev,
|
dev_info(&pdev->dev,
|
||||||
"Missing XBAR output information, using %u.\n",
|
"Missing XBAR output information, using %u.\n",
|
||||||
TI_XBAR_OUTPUTS);
|
TI_DRA7_XBAR_OUTPUTS);
|
||||||
xbar->dma_requests = TI_XBAR_OUTPUTS;
|
xbar->dma_requests = TI_DRA7_XBAR_OUTPUTS;
|
||||||
}
|
}
|
||||||
of_node_put(dma_node);
|
of_node_put(dma_node);
|
||||||
|
|
||||||
if (of_property_read_u32(node, "dma-requests", &xbar->xbar_requests)) {
|
if (of_property_read_u32(node, "dma-requests", &xbar->xbar_requests)) {
|
||||||
dev_info(&pdev->dev,
|
dev_info(&pdev->dev,
|
||||||
"Missing XBAR input information, using %u.\n",
|
"Missing XBAR input information, using %u.\n",
|
||||||
TI_XBAR_INPUTS);
|
TI_DRA7_XBAR_INPUTS);
|
||||||
xbar->xbar_requests = TI_XBAR_INPUTS;
|
xbar->xbar_requests = TI_DRA7_XBAR_INPUTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!of_property_read_u32(node, "ti,dma-safe-map", &safe_val))
|
if (!of_property_read_u32(node, "ti,dma-safe-map", &safe_val))
|
||||||
|
@ -169,30 +340,50 @@ static int ti_dma_xbar_probe(struct platform_device *pdev)
|
||||||
xbar->iomem = iomem;
|
xbar->iomem = iomem;
|
||||||
|
|
||||||
xbar->dmarouter.dev = &pdev->dev;
|
xbar->dmarouter.dev = &pdev->dev;
|
||||||
xbar->dmarouter.route_free = ti_dma_xbar_free;
|
xbar->dmarouter.route_free = ti_dra7_xbar_free;
|
||||||
xbar->dma_offset = (u32)match->data;
|
xbar->dma_offset = (u32)match->data;
|
||||||
|
|
||||||
platform_set_drvdata(pdev, xbar);
|
platform_set_drvdata(pdev, xbar);
|
||||||
|
|
||||||
/* Reset the crossbar */
|
/* Reset the crossbar */
|
||||||
for (i = 0; i < xbar->dma_requests; i++)
|
for (i = 0; i < xbar->dma_requests; i++)
|
||||||
ti_dma_xbar_write(xbar->iomem, i, xbar->safe_val);
|
ti_dra7_xbar_write(xbar->iomem, i, xbar->safe_val);
|
||||||
|
|
||||||
ret = of_dma_router_register(node, ti_dma_xbar_route_allocate,
|
ret = of_dma_router_register(node, ti_dra7_xbar_route_allocate,
|
||||||
&xbar->dmarouter);
|
&xbar->dmarouter);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
/* Restore the defaults for the crossbar */
|
/* Restore the defaults for the crossbar */
|
||||||
for (i = 0; i < xbar->dma_requests; i++)
|
for (i = 0; i < xbar->dma_requests; i++)
|
||||||
ti_dma_xbar_write(xbar->iomem, i, i);
|
ti_dra7_xbar_write(xbar->iomem, i, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id ti_dma_xbar_match[] = {
|
static int ti_dma_xbar_probe(struct platform_device *pdev)
|
||||||
{ .compatible = "ti,dra7-dma-crossbar" },
|
{
|
||||||
{},
|
const struct of_device_id *match;
|
||||||
};
|
int ret;
|
||||||
|
|
||||||
|
match = of_match_node(ti_dma_xbar_match, pdev->dev.of_node);
|
||||||
|
if (unlikely(!match))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
switch ((u32)match->data) {
|
||||||
|
case TI_XBAR_DRA7:
|
||||||
|
ret = ti_dra7_xbar_probe(pdev);
|
||||||
|
break;
|
||||||
|
case TI_XBAR_AM335X:
|
||||||
|
ret = ti_am335x_xbar_probe(pdev);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_err(&pdev->dev, "Unsupported crossbar\n");
|
||||||
|
ret = -ENODEV;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static struct platform_driver ti_dma_xbar_driver = {
|
static struct platform_driver ti_dma_xbar_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
|
|
|
@ -41,51 +41,6 @@
|
||||||
#ifndef EDMA_H_
|
#ifndef EDMA_H_
|
||||||
#define EDMA_H_
|
#define EDMA_H_
|
||||||
|
|
||||||
/* PaRAM slots are laid out like this */
|
|
||||||
struct edmacc_param {
|
|
||||||
u32 opt;
|
|
||||||
u32 src;
|
|
||||||
u32 a_b_cnt;
|
|
||||||
u32 dst;
|
|
||||||
u32 src_dst_bidx;
|
|
||||||
u32 link_bcntrld;
|
|
||||||
u32 src_dst_cidx;
|
|
||||||
u32 ccnt;
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
/* fields in edmacc_param.opt */
|
|
||||||
#define SAM BIT(0)
|
|
||||||
#define DAM BIT(1)
|
|
||||||
#define SYNCDIM BIT(2)
|
|
||||||
#define STATIC BIT(3)
|
|
||||||
#define EDMA_FWID (0x07 << 8)
|
|
||||||
#define TCCMODE BIT(11)
|
|
||||||
#define EDMA_TCC(t) ((t) << 12)
|
|
||||||
#define TCINTEN BIT(20)
|
|
||||||
#define ITCINTEN BIT(21)
|
|
||||||
#define TCCHEN BIT(22)
|
|
||||||
#define ITCCHEN BIT(23)
|
|
||||||
|
|
||||||
/*ch_status paramater of callback function possible values*/
|
|
||||||
#define EDMA_DMA_COMPLETE 1
|
|
||||||
#define EDMA_DMA_CC_ERROR 2
|
|
||||||
#define EDMA_DMA_TC1_ERROR 3
|
|
||||||
#define EDMA_DMA_TC2_ERROR 4
|
|
||||||
|
|
||||||
enum address_mode {
|
|
||||||
INCR = 0,
|
|
||||||
FIFO = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
enum fifo_width {
|
|
||||||
W8BIT = 0,
|
|
||||||
W16BIT = 1,
|
|
||||||
W32BIT = 2,
|
|
||||||
W64BIT = 3,
|
|
||||||
W128BIT = 4,
|
|
||||||
W256BIT = 5
|
|
||||||
};
|
|
||||||
|
|
||||||
enum dma_event_q {
|
enum dma_event_q {
|
||||||
EVENTQ_0 = 0,
|
EVENTQ_0 = 0,
|
||||||
EVENTQ_1 = 1,
|
EVENTQ_1 = 1,
|
||||||
|
@ -94,64 +49,10 @@ enum dma_event_q {
|
||||||
EVENTQ_DEFAULT = -1
|
EVENTQ_DEFAULT = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
enum sync_dimension {
|
|
||||||
ASYNC = 0,
|
|
||||||
ABSYNC = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
#define EDMA_CTLR_CHAN(ctlr, chan) (((ctlr) << 16) | (chan))
|
#define EDMA_CTLR_CHAN(ctlr, chan) (((ctlr) << 16) | (chan))
|
||||||
#define EDMA_CTLR(i) ((i) >> 16)
|
#define EDMA_CTLR(i) ((i) >> 16)
|
||||||
#define EDMA_CHAN_SLOT(i) ((i) & 0xffff)
|
#define EDMA_CHAN_SLOT(i) ((i) & 0xffff)
|
||||||
|
|
||||||
#define EDMA_CHANNEL_ANY -1 /* for edma_alloc_channel() */
|
|
||||||
#define EDMA_SLOT_ANY -1 /* for edma_alloc_slot() */
|
|
||||||
#define EDMA_CONT_PARAMS_ANY 1001
|
|
||||||
#define EDMA_CONT_PARAMS_FIXED_EXACT 1002
|
|
||||||
#define EDMA_CONT_PARAMS_FIXED_NOT_EXACT 1003
|
|
||||||
|
|
||||||
#define EDMA_MAX_CC 2
|
|
||||||
|
|
||||||
/* alloc/free DMA channels and their dedicated parameter RAM slots */
|
|
||||||
int edma_alloc_channel(int channel,
|
|
||||||
void (*callback)(unsigned channel, u16 ch_status, void *data),
|
|
||||||
void *data, enum dma_event_q);
|
|
||||||
void edma_free_channel(unsigned channel);
|
|
||||||
|
|
||||||
/* alloc/free parameter RAM slots */
|
|
||||||
int edma_alloc_slot(unsigned ctlr, int slot);
|
|
||||||
void edma_free_slot(unsigned slot);
|
|
||||||
|
|
||||||
/* alloc/free a set of contiguous parameter RAM slots */
|
|
||||||
int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count);
|
|
||||||
int edma_free_cont_slots(unsigned slot, int count);
|
|
||||||
|
|
||||||
/* calls that operate on part of a parameter RAM slot */
|
|
||||||
void edma_set_src(unsigned slot, dma_addr_t src_port,
|
|
||||||
enum address_mode mode, enum fifo_width);
|
|
||||||
void edma_set_dest(unsigned slot, dma_addr_t dest_port,
|
|
||||||
enum address_mode mode, enum fifo_width);
|
|
||||||
dma_addr_t edma_get_position(unsigned slot, bool dst);
|
|
||||||
void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx);
|
|
||||||
void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx);
|
|
||||||
void edma_set_transfer_params(unsigned slot, u16 acnt, u16 bcnt, u16 ccnt,
|
|
||||||
u16 bcnt_rld, enum sync_dimension sync_mode);
|
|
||||||
void edma_link(unsigned from, unsigned to);
|
|
||||||
void edma_unlink(unsigned from);
|
|
||||||
|
|
||||||
/* calls that operate on an entire parameter RAM slot */
|
|
||||||
void edma_write_slot(unsigned slot, const struct edmacc_param *params);
|
|
||||||
void edma_read_slot(unsigned slot, struct edmacc_param *params);
|
|
||||||
|
|
||||||
/* channel control operations */
|
|
||||||
int edma_start(unsigned channel);
|
|
||||||
void edma_stop(unsigned channel);
|
|
||||||
void edma_clean_channel(unsigned channel);
|
|
||||||
void edma_clear_event(unsigned channel);
|
|
||||||
void edma_pause(unsigned channel);
|
|
||||||
void edma_resume(unsigned channel);
|
|
||||||
|
|
||||||
void edma_assign_channel_eventq(unsigned channel, enum dma_event_q eventq_no);
|
|
||||||
|
|
||||||
struct edma_rsv_info {
|
struct edma_rsv_info {
|
||||||
|
|
||||||
const s16 (*rsv_chans)[2];
|
const s16 (*rsv_chans)[2];
|
||||||
|
@ -170,10 +71,11 @@ struct edma_soc_info {
|
||||||
/* Resource reservation for other cores */
|
/* Resource reservation for other cores */
|
||||||
struct edma_rsv_info *rsv;
|
struct edma_rsv_info *rsv;
|
||||||
|
|
||||||
|
/* List of channels allocated for memcpy, terminated with -1 */
|
||||||
|
s16 *memcpy_channels;
|
||||||
|
|
||||||
s8 (*queue_priority_mapping)[2];
|
s8 (*queue_priority_mapping)[2];
|
||||||
const s16 (*xbar_chans)[2];
|
const s16 (*xbar_chans)[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
int edma_trigger_channel(unsigned);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue