Re: [PATCH v4 0/2] powerpc/512x: add LocalPlus Bus FIFO device driver

2015-10-27 Thread Alexander Popov
On 27.10.2015 05:22, Vinod Koul wrote:
> On Thu, Oct 22, 2015 at 01:15:03AM +0300, Alexander Popov wrote:
>> On 12.10.2015 00:08, Alexander Popov wrote:
>>> This driver for Freescale MPC512x LocalPlus Bus FIFO (called SCLPC
>>> in the Reference Manual) allows Direct Memory Access transfers
>>> between RAM and peripheral devices on LocalPlus Bus.
>>
>>> Changes in v4:
>>>  - the race condition is fixed;
>>>  - plenty of style fixes are made;
>>>  - devm_* functions and EPROBE_DEFER are used in probe().
>>
>> Hello,
>>
>> I've done my best to fix the issues pointed by Timur Tabi and Vinod Koul.
>> Could I have a feedback please?
> 
> I dont see to have v4 in my list :( Can you please repost

Hello, Vinod

I'm sure I haven't miss your address in the list of the recipients.
Anyway I can repost.

Anatolij Gustschin wrote that he applied v4 with some fix to mpc5xxx/next
some time ago.

So should I repost v4 for everybody? How should I mark the reposted patches?

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v4 0/2] powerpc/512x: add LocalPlus Bus FIFO device driver

2015-10-21 Thread Alexander Popov
On 12.10.2015 00:08, Alexander Popov wrote:
> This driver for Freescale MPC512x LocalPlus Bus FIFO (called SCLPC
> in the Reference Manual) allows Direct Memory Access transfers
> between RAM and peripheral devices on LocalPlus Bus.

> Changes in v4:
>  - the race condition is fixed;
>  - plenty of style fixes are made;
>  - devm_* functions and EPROBE_DEFER are used in probe().

Hello,

I've done my best to fix the issues pointed by Timur Tabi and Vinod Koul.
Could I have a feedback please?

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v4 0/2] powerpc/512x: add LocalPlus Bus FIFO device driver

2015-10-11 Thread Alexander Popov
This driver for Freescale MPC512x LocalPlus Bus FIFO (called SCLPC
in the Reference Manual) allows Direct Memory Access transfers
between RAM and peripheral devices on LocalPlus Bus.

Changes in v3:
 - resource usage in probe() is fixed;
 - driver methods are made safe against remove();
 - dma_request_slave_channel() is used to get DMA channel number from
the device tree;
 - chip select number concerned with the DMA transaction is determined
from 'localbus' device tree node information;
 - register set is described as a structure;
 - symbolic names are given to shift counts to keep magic numbers
out of the code;
 - choosing values for LPBFIFO BPT (bytes per transfer) and DMA maxburst
is improved, so DMA transfer size has increased for some cases;
 - device tree binding for LPBFIFO is documented;
 - Kconfig and Makefile are improved;
 - email address "a13xp0p0...@gmail.com" is changed to a more pleasant
alias "alex.po...@linux.com".

Changes in v4:
 - the race condition is fixed;
 - plenty of style fixes are made;
 - devm_* functions and EPROBE_DEFER are used in probe().

Alexander Popov (2):
  powerpc/512x: add LocalPlus Bus FIFO device driver
  powerpc/512x: add a device tree binding for LocalPlus Bus FIFO

 .../bindings/powerpc/fsl/mpc512x_lpbfifo.txt   |  21 +
 arch/powerpc/boot/dts/mpc5121.dtsi |  11 +-
 arch/powerpc/boot/dts/mpc5125twr.dts   |  11 +-
 arch/powerpc/configs/mpc512x_defconfig |   1 +
 arch/powerpc/include/asm/mpc5121.h |  59 +++
 arch/powerpc/platforms/512x/Kconfig|   6 +
 arch/powerpc/platforms/512x/Makefile   |   1 +
 arch/powerpc/platforms/512x/mpc512x_lpbfifo.c  | 539 +
 8 files changed, 646 insertions(+), 3 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/powerpc/fsl/mpc512x_lpbfifo.txt
 create mode 100644 arch/powerpc/platforms/512x/mpc512x_lpbfifo.c

-- 
1.9.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v4 1/2] powerpc/512x: add LocalPlus Bus FIFO device driver

2015-10-11 Thread Alexander Popov
This driver for Freescale MPC512x LocalPlus Bus FIFO (called SCLPC
in the Reference Manual) allows Direct Memory Access transfers
between RAM and peripheral devices on LocalPlus Bus.

Signed-off-by: Alexander Popov <alex.po...@linux.com>
---
 arch/powerpc/configs/mpc512x_defconfig|   1 +
 arch/powerpc/include/asm/mpc5121.h|  59 +++
 arch/powerpc/platforms/512x/Kconfig   |   6 +
 arch/powerpc/platforms/512x/Makefile  |   1 +
 arch/powerpc/platforms/512x/mpc512x_lpbfifo.c | 539 ++
 5 files changed, 606 insertions(+)
 create mode 100644 arch/powerpc/platforms/512x/mpc512x_lpbfifo.c

diff --git a/arch/powerpc/configs/mpc512x_defconfig 
b/arch/powerpc/configs/mpc512x_defconfig
index 59b85cb..d16d6c5 100644
--- a/arch/powerpc/configs/mpc512x_defconfig
+++ b/arch/powerpc/configs/mpc512x_defconfig
@@ -112,6 +112,7 @@ CONFIG_RTC_DRV_M41T80=y
 CONFIG_RTC_DRV_MPC5121=y
 CONFIG_DMADEVICES=y
 CONFIG_MPC512X_DMA=y
+CONFIG_MPC512x_LPBFIFO=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XIP=y
 CONFIG_EXT3_FS=y
diff --git a/arch/powerpc/include/asm/mpc5121.h 
b/arch/powerpc/include/asm/mpc5121.h
index 4a69cd1..deaeb0b 100644
--- a/arch/powerpc/include/asm/mpc5121.h
+++ b/arch/powerpc/include/asm/mpc5121.h
@@ -60,4 +60,63 @@ struct mpc512x_lpc {
 
 int mpc512x_cs_config(unsigned int cs, u32 val);
 
+/*
+ * SCLPC Module (LPB FIFO)
+ */
+struct mpc512x_lpbfifo {
+   u32 pkt_size;   /* SCLPC Packet Size Register */
+   u32 start_addr; /* SCLPC Start Address Register */
+   u32 ctrl;   /* SCLPC Control Register */
+   u32 enable; /* SCLPC Enable Register */
+   u32 reserved1;
+   u32 status; /* SCLPC Status Register */
+   u32 bytes_done; /* SCLPC Bytes Done Register */
+   u32 emb_sc; /* EMB Share Counter Register */
+   u32 emb_pc; /* EMB Pause Control Register */
+   u32 reserved2[7];
+   u32 data_word;  /* LPC RX/TX FIFO Data Word Register */
+   u32 fifo_status;/* LPC RX/TX FIFO Status Register */
+   u32 fifo_ctrl;  /* LPC RX/TX FIFO Control Register */
+   u32 fifo_alarm; /* LPC RX/TX FIFO Alarm Register */
+};
+
+#define MPC512X_SCLPC_START(1 << 31)
+#define MPC512X_SCLPC_CS(x)(((x) & 0x7) << 24)
+#define MPC512X_SCLPC_FLUSH(1 << 17)
+#define MPC512X_SCLPC_READ (1 << 16)
+#define MPC512X_SCLPC_DAI  (1 << 8)
+#define MPC512X_SCLPC_BPT(x)   ((x) & 0x3f)
+#define MPC512X_SCLPC_RESET(1 << 24)
+#define MPC512X_SCLPC_FIFO_RESET   (1 << 16)
+#define MPC512X_SCLPC_ABORT_INT_ENABLE (1 << 9)
+#define MPC512X_SCLPC_NORM_INT_ENABLE  (1 << 8)
+#define MPC512X_SCLPC_ENABLE   (1 << 0)
+#define MPC512X_SCLPC_SUCCESS  (1 << 24)
+#define MPC512X_SCLPC_FIFO_CTRL(x) (((x) & 0x7) << 24)
+#define MPC512X_SCLPC_FIFO_ALARM(x)((x) & 0x3ff)
+
+enum lpb_dev_portsize {
+   LPB_DEV_PORTSIZE_UNDEFINED = 0,
+   LPB_DEV_PORTSIZE_1_BYTE = 1,
+   LPB_DEV_PORTSIZE_2_BYTES = 2,
+   LPB_DEV_PORTSIZE_4_BYTES = 4,
+   LPB_DEV_PORTSIZE_8_BYTES = 8
+};
+
+enum mpc512x_lpbfifo_req_dir {
+   MPC512X_LPBFIFO_REQ_DIR_READ,
+   MPC512X_LPBFIFO_REQ_DIR_WRITE
+};
+
+struct mpc512x_lpbfifo_request {
+   phys_addr_t dev_phys_addr; /* physical address of some device on LPB */
+   void *ram_virt_addr; /* virtual address of some region in RAM */
+   u32 size;
+   enum lpb_dev_portsize portsize;
+   enum mpc512x_lpbfifo_req_dir dir;
+   void (*callback)(struct mpc512x_lpbfifo_request *);
+};
+
+int mpc512x_lpbfifo_submit(struct mpc512x_lpbfifo_request *req);
+
 #endif /* __ASM_POWERPC_MPC5121_H__ */
diff --git a/arch/powerpc/platforms/512x/Kconfig 
b/arch/powerpc/platforms/512x/Kconfig
index 48bf38d..f09016f 100644
--- a/arch/powerpc/platforms/512x/Kconfig
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -10,6 +10,12 @@ config PPC_MPC512x
select USB_EHCI_BIG_ENDIAN_MMIO if USB_EHCI_HCD
select USB_EHCI_BIG_ENDIAN_DESC if USB_EHCI_HCD
 
+config MPC512x_LPBFIFO
+   tristate "MPC512x LocalPlus Bus FIFO driver"
+   depends on PPC_MPC512x && MPC512X_DMA
+   help
+ Enable support for Freescale MPC512x LocalPlus Bus FIFO (SCLPC).
+
 config MPC5121_ADS
bool "Freescale MPC5121E ADS"
depends on PPC_MPC512x
diff --git a/arch/powerpc/platforms/512x/Makefile 
b/arch/powerpc/platforms/512x/Makefile
index 0169312..f47d422 100644
--- a/arch/powerpc/platforms/512x/Makefile
+++ b/arch/powerpc/platforms/512x/Makefile
@@ -5,4 +5,5 @@ obj-$(CONFIG_COMMON_CLK)+= clock-commonclk.o
 obj-y  += mpc512x_shared.o
 obj-$(CONFIG_MPC5121_ADS)  += mpc5121_ads.o mpc5121_ads_cpld.o
 obj-$(CONFIG_MPC512x_GENERIC)  += mpc51

[PATCH v4 2/2] powerpc/512x: add a device tree binding for LocalPlus Bus FIFO

2015-10-11 Thread Alexander Popov
Add a device tree binding for Freescale MPC512x LocalPlus Bus FIFO and
introduce the document describing that binding.

Signed-off-by: Alexander Popov <alex.po...@linux.com>
---
 .../bindings/powerpc/fsl/mpc512x_lpbfifo.txt| 21 +
 arch/powerpc/boot/dts/mpc5121.dtsi  | 11 +--
 arch/powerpc/boot/dts/mpc5125twr.dts| 11 ++-
 3 files changed, 40 insertions(+), 3 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/powerpc/fsl/mpc512x_lpbfifo.txt

diff --git a/Documentation/devicetree/bindings/powerpc/fsl/mpc512x_lpbfifo.txt 
b/Documentation/devicetree/bindings/powerpc/fsl/mpc512x_lpbfifo.txt
new file mode 100644
index 000..b3b392f
--- /dev/null
+++ b/Documentation/devicetree/bindings/powerpc/fsl/mpc512x_lpbfifo.txt
@@ -0,0 +1,21 @@
+Freescale MPC512x LocalPlus Bus FIFO (called SCLPC in the Reference Manual)
+
+Required properties:
+- compatible: should be "fsl,mpc512x-lpbfifo";
+- reg: should contain the offset and length of SCLPC register set;
+- interrupts: should contain the interrupt specifier for SCLPC; syntax of an
+interrupt client node is described in interrupt-controller/interrupts.txt;
+- dmas: should contain the DMA specifier for SCLPC as described at
+dma/dma.txt and dma/mpc512x-dma.txt;
+- dma-names: should be "rx-tx";
+
+Example:
+
+   sclpc@10100 {
+   compatible = "fsl,mpc512x-lpbfifo";
+   reg = <0x10100 0x50>;
+   interrupts = <7 0x8>;
+   dmas = < 26>;
+   dma-names = "rx-tx";
+   };
+
diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi 
b/arch/powerpc/boot/dts/mpc5121.dtsi
index 7f9d14f..a015e45 100644
--- a/arch/powerpc/boot/dts/mpc5121.dtsi
+++ b/arch/powerpc/boot/dts/mpc5121.dtsi
@@ -77,7 +77,6 @@
#address-cells = <2>;
#size-cells = <1>;
reg = <0x8020 0x40>;
-   interrupts = <7 0x8>;
ranges = <0x0 0x0 0xfc00 0x0400>;
};
 
@@ -329,7 +328,15 @@
/* LocalPlus controller */
lpc@1 {
compatible = "fsl,mpc5121-lpc";
-   reg = <0x1 0x200>;
+   reg = <0x1 0x100>;
+   };
+
+   sclpc@10100 {
+   compatible = "fsl,mpc512x-lpbfifo";
+   reg = <0x10100 0x50>;
+   interrupts = <7 0x8>;
+   dmas = < 26>;
+   dma-names = "rx-tx";
};
 
pata@10200 {
diff --git a/arch/powerpc/boot/dts/mpc5125twr.dts 
b/arch/powerpc/boot/dts/mpc5125twr.dts
index e4f2974..898eb58 100644
--- a/arch/powerpc/boot/dts/mpc5125twr.dts
+++ b/arch/powerpc/boot/dts/mpc5125twr.dts
@@ -246,6 +246,14 @@
status = "disabled";
};
 
+   sclpc@10100 {
+   compatible = "fsl,mpc512x-lpbfifo";
+   reg = <0x10100 0x50>;
+   interrupts = <7 0x8>;
+   dmas = < 26>;
+   dma-names = "rx-tx";
+   };
+
// 5125 PSCs are not 52xx or 5121 PSC compatible
// PSC1 uart0 aka ttyPSC0
serial@11100 {
@@ -279,10 +287,11 @@
clock-names = "ipg";
};
 
-   dma@14000 {
+   dma0: dma@14000 {
compatible = "fsl,mpc5121-dma"; // BSP name: 
"mpc512x-dma2"
reg = <0x14000 0x1800>;
interrupts = <65 0x8>;
+   #dma-cells = <1>;
};
};
 };
-- 
1.9.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v3 3/3] dmaengine: mpc512x: initialize with subsys_initcall()

2015-10-07 Thread Alexander Popov
On 07.10.2015 17:17, Vinod Koul wrote:
> On Thu, Sep 24, 2015 at 08:28:57PM +0300, Alexander Popov wrote:
>> Initialize Freescale MPC512x DMA driver with subsys_initcall()
>> to allow the depending drivers to call dma_request_slave_channel()
>> during their probe.
> 
> Why can't we use defered probe ? I have been asking people to not move init
> levels and esnure we have right solutions using defered probe

Thanks, Vinod, I'll do it in v4.

Best regards,
Alexander

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v3 1/3] powerpc/512x: add LocalPlus Bus FIFO device driver

2015-10-05 Thread Alexander Popov
On 01.10.2015 20:11, Timur Tabi wrote:
> On 09/30/2015 04:24 PM, Alexander Popov wrote:
>>> Driver code that has to parse #address-cells or #size-cells
>>> is usually wrong.
>>
>> I would not call it "parsing", I just check whether the dts-file is good.
>> Anyway, could you give me a clue how to do better?
> 
> You should use of_n_size_cells() and of_n_addr_cells().

It seems that of_n_size_cells() and of_n_addr_cells() don't work well in
my case. These functions just help to get "#address-cells" and "#size-cells"
from a parent node of a given node.

"sclpc" device tree node is a child of "soc" node (not "localbus" node),
but the driver must use "ranges" property of "localbus" to determine
the chip select number of a client device which ordered the DMA transfer.

It seems that ns2_leds_get_of_pdata() from linux/drivers/leds/leds-ns2.c
or pnv_init_idle_states() from arch/powerpc/platforms/powernv/idle.c do
something similar to get_cs_ranges().
Is it OK?

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v3 1/3] powerpc/512x: add LocalPlus Bus FIFO device driver

2015-09-30 Thread Alexander Popov
Hello Timur, thanks again for your review.

On 25.09.2015 04:01, Timur Tabi wrote:
> Alexander Popov wrote:
>> +
>> +for (i = 0; i < lpbfifo.cs_n; i++) {
>> +phys_addr_t cs_start;
>> +phys_addr_t cs_end;
>> +
>> +cs_start = lpbfifo.cs_ranges[i].addr;
>> +cs_end = cs_start + lpbfifo.cs_ranges[i].size - 1;
>> +
>> +if (lpbfifo.req->bus_phys >= cs_start &&
>> +lpbfifo.req->bus_phys + lpbfifo.req->size - 1 <= cs_end) {
>> +cs = lpbfifo.cs_ranges[i].csnum;
>> +break;
>> +}
>> +}
>> +if (i == lpbfifo.cs_n) {
> 
> Can you test for "!cs" here instead?
> 
>> +e = -EFAULT;
>> +goto err_param;
>> +}

Unfortunately no: 0 is a valid value for Chip Select.
Is it OK to leave it like that?

>> +
>> +/* 2. Prepare DMA */
>> +dma_dev = lpbfifo.chan->device;
>> +
>> +sg_init_table(, 1);
>> +if (lpbfifo.req->dir == MPC512X_LPBFIFO_REQ_DIR_WRITE)
>> +dir = DMA_TO_DEVICE;
>> +else
>> +dir = DMA_FROM_DEVICE;
>> +sg_dma_address() = dma_map_single(dma_dev->dev,
>> +lpbfifo.req->ram_virt, lpbfifo.req->size, dir);
>> +if (dma_mapping_error(dma_dev->dev, sg_dma_address())) {
>> +e = -EFAULT;
>> +goto err_param;
>> +}
>> +lpbfifo.ram_bus_addr = sg_dma_address(); /* For freeing later */
>> +sg_dma_len() = lpbfifo.req->size;
> 
> I don't think sg_dma_len() is meant to be used as an lvalue.

I've double-checked and found many cases of such usage of this macro.
It seems that I can't avoid it too.

>> +/*
>> + * The node defined as compatible with 'fsl,mpc5121-localbus'
>> + * should have 2 address cells and 1 size cell.
>> + * One item of its ranges property should consist of:
>> + * - the first address cell which is the chipselect number;
>> + * - the second address cell which is the offset in the chipselect,
>> + *must be zero.
>> + * - CPU address of the beginning of an access window;
>> + * - the only size cell which is the size of an access window.
>> + */
>> +addr_cells_p = of_get_property(lb_node, "#address-cells", NULL);
>> +size_cells_p = of_get_property(lb_node, "#size-cells", NULL);
>> +if (addr_cells_p == NULL || *addr_cells_p != 2 ||
>> +size_cells_p == NULL ||*size_cells_p != 1) {
>> +goto end1;
>> +}
> 
> Is this really necessary?

I'm not sure.

I've found a device tree node compatible with "fsl,mpc5121-localbus"
and I just check the format of "ranges" property before parsing it
because devicetree/bindings/powerpc/fsl/lbc.txt doesn't have details
about it.

Should I blindly assume that this property has 2 address cells and 1 size
cell?

> Can't you use the built-in OF functions for
> parsing ranges? 

I don't see anything to use instead of of_property_count_u32_elems() and
of_property_read_u32_array().

> Driver code that has to parse #address-cells or #size-cells
> is usually wrong.

I would not call it "parsing", I just check whether the dts-file is good.
Anyway, could you give me a clue how to do better?

>> +
>> +proplen = of_property_count_u32_elems(lb_node, "ranges");
>> +if (proplen < 0 || proplen % 4 != 0)
>> +goto end1;
>> +
>> +lpbfifo.cs_n = proplen / 4;
>> +lpbfifo.cs_ranges = kcalloc(lpbfifo.cs_n, sizeof(struct cs_range),
>> +GFP_KERNEL);
>> +if (!lpbfifo.cs_ranges)
>> +goto end1;
>> +
>> +if (of_property_read_u32_array(lb_node, "ranges",
>> +(u32 *)lpbfifo.cs_ranges, proplen) != 0) {
>> +goto end2;
>> +}
>> +
>> +for (i = 0; i < lpbfifo.cs_n; i++) {
>> +if (lpbfifo.cs_ranges[i].base != 0)
>> +goto end2;
>> +}
>> +
>> +res = 0;
>> + end2:
>> +if (res != 0)
>> +kfree(lpbfifo.cs_ranges);
>> + end1:
>> +of_node_put(lb_node);
>> + end0:
>> +return res;
>> +}

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v3 2/3] powerpc/512x: add a device tree binding for LocalPlus Bus FIFO

2015-09-29 Thread Alexander Popov
On 28.09.2015 16:26, Timur Tabi wrote:
> Alexander Popov wrote:
>> I've just followed devicetree/bindings/dma/dma.txt...
>> This "rx-tx" doesn't mean much but it could show that LocalPlus Bus FIFO
>> uses a single DMA read-write channel. Should I really drop it?
> 
> Hmmm, I'm not sure.  Is there anything else (besides your driver) that
> parses this device tree node?

No, mpc512x_lpbfifo.c is the only piece of code which is going to use this
device tree node.

> dma.txt says this:
> 
> "The specific strings that can be used are defined in the binding of the
> DMA client device."
> 
> So this looks like it's driver-specific,

Yes.
MPC512x LocalPlus Bus FIFO uses the channel #26 of the DMA controller
both for reading and writing, and other DMA clients use other specific
DMA channels. This channel assignment is fixed in hardware and described
in the Reference Manual.

> but it is a required property.
> I guess you should keep it, but I think you should get a second opinion.

Ok, thanks.

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v3 1/3] powerpc/512x: add LocalPlus Bus FIFO device driver

2015-09-29 Thread Alexander Popov
On 28.09.2015 16:18, Timur Tabi wrote:
> Alexander Popov wrote:
>> The only question I have: why calling dma_unmap_single() from within
>> a spinlock is a bad practice?
> 
> I don't know, but usually functions that allocate or free memory cannot be
> called from within a spinlock.  You need to check that.  Since the MPC5121
> is a single-core CPU, you might not notice if you're doing something wrong.

I've double-checked the code and LDD and don't see any reason to avoid
calling dma_unmap_single() from interrupt context and within spinlock.

Please correct me if I'm wrong.
Thanks.

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v3 3/3] dmaengine: mpc512x: initialize with subsys_initcall()

2015-09-28 Thread Alexander Popov
On 25.09.2015 03:16, Timur Tabi wrote:
> Alexander Popov wrote:
>> Initialize Freescale MPC512x DMA driver with subsys_initcall()
>> to allow the depending drivers to call dma_request_slave_channel()
>> during their probe.
>>
>> Signed-off-by: Alexander Popov<alex.po...@linux.com>
> 
> Is there any way we can use -EPROBEDEFER instead?

Thanks Timur, I'll try.

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v3 2/3] powerpc/512x: add a device tree binding for LocalPlus Bus FIFO

2015-09-28 Thread Alexander Popov
On 25.09.2015 03:18, Timur Tabi wrote:
> Alexander Popov wrote:
>> +- dma-names: should be "rx-tx";
> 
> Why bother, if it can only be one value?

I've just followed devicetree/bindings/dma/dma.txt...
This "rx-tx" doesn't mean much but it could show that LocalPlus Bus FIFO
uses a single DMA read-write channel. Should I really drop it?

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v3 1/3] powerpc/512x: add LocalPlus Bus FIFO device driver

2015-09-28 Thread Alexander Popov
Hello, Timur, thanks a lot for your review.
I'll fix all the issues you pointed at and return with v4.

The only question I have: why calling dma_unmap_single() from within
a spinlock is a bad practice?

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3 1/3] powerpc/512x: add LocalPlus Bus FIFO device driver

2015-09-24 Thread Alexander Popov
This driver for Freescale MPC512x LocalPlus Bus FIFO (called SCLPC
in the Reference Manual) allows Direct Memory Access transfers
between RAM and peripheral devices on LocalPlus Bus.

Signed-off-by: Alexander Popov <alex.po...@linux.com>
---
 arch/powerpc/configs/mpc512x_defconfig|   1 +
 arch/powerpc/include/asm/mpc5121.h|  59 +++
 arch/powerpc/platforms/512x/Kconfig   |   6 +
 arch/powerpc/platforms/512x/Makefile  |   1 +
 arch/powerpc/platforms/512x/mpc512x_lpbfifo.c | 560 ++
 5 files changed, 627 insertions(+)
 create mode 100644 arch/powerpc/platforms/512x/mpc512x_lpbfifo.c

diff --git a/arch/powerpc/configs/mpc512x_defconfig 
b/arch/powerpc/configs/mpc512x_defconfig
index 59b85cb..d16d6c5 100644
--- a/arch/powerpc/configs/mpc512x_defconfig
+++ b/arch/powerpc/configs/mpc512x_defconfig
@@ -112,6 +112,7 @@ CONFIG_RTC_DRV_M41T80=y
 CONFIG_RTC_DRV_MPC5121=y
 CONFIG_DMADEVICES=y
 CONFIG_MPC512X_DMA=y
+CONFIG_MPC512x_LPBFIFO=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XIP=y
 CONFIG_EXT3_FS=y
diff --git a/arch/powerpc/include/asm/mpc5121.h 
b/arch/powerpc/include/asm/mpc5121.h
index 4a69cd1..a6e8225 100644
--- a/arch/powerpc/include/asm/mpc5121.h
+++ b/arch/powerpc/include/asm/mpc5121.h
@@ -60,4 +60,63 @@ struct mpc512x_lpc {
 
 int mpc512x_cs_config(unsigned int cs, u32 val);
 
+/*
+ * SCLPC Module (LPB FIFO)
+ */
+struct mpc512x_lpbfifo {
+   u32 pkt_size;   /* SCLPC Packet Size Register */
+   u32 start_addr; /* SCLPC Start Address Register */
+   u32 ctrl;   /* SCLPC Control Register */
+   u32 enable; /* SCLPC Enable Register */
+   u32 reserved1;
+   u32 status; /* SCLPC Status Register */
+   u32 bytes_done; /* SCLPC Bytes Done Register */
+   u32 emb_sc; /* EMB Share Counter Register */
+   u32 emb_pc; /* EMB Pause Control Register */
+   u32 reserved2[7];
+   u32 data_word;  /* LPC RX/TX FIFO Data Word Register */
+   u32 fifo_status;/* LPC RX/TX FIFO Status Register */
+   u32 fifo_ctrl;  /* LPC RX/TX FIFO Control Register */
+   u32 fifo_alarm; /* LPC RX/TX FIFO Alarm Register */
+};
+
+#define MPC512X_SCLPC_START(1 << 31)
+#define MPC512X_SCLPC_CS(x)(((x) & 0x7) << 24)
+#define MPC512X_SCLPC_FLUSH(1 << 17)
+#define MPC512X_SCLPC_READ (1 << 16)
+#define MPC512X_SCLPC_DAI  (1 << 8)
+#define MPC512X_SCLPC_BPT(x)   ((x) & 0x3f)
+#define MPC512X_SCLPC_RESET(1 << 24)
+#define MPC512X_SCLPC_FIFO_RESET   (1 << 16)
+#define MPC512X_SCLPC_ABORT_INT_ENABLE (1 << 9)
+#define MPC512X_SCLPC_NORM_INT_ENABLE  (1 << 8)
+#define MPC512X_SCLPC_ENABLE   (1 << 0)
+#define MPC512X_SCLPC_SUCCESS  (1 << 24)
+#define MPC512X_SCLPC_FIFO_CTRL(x) (((x) & 0x7) << 24)
+#define MPC512X_SCLPC_FIFO_ALARM(x)((x) & 0x3ff)
+
+enum lpb_dev_portsize {
+   LPB_DEV_PORTSIZE_UNDEFINED = 0,
+   LPB_DEV_PORTSIZE_1_BYTE = 1,
+   LPB_DEV_PORTSIZE_2_BYTES = 2,
+   LPB_DEV_PORTSIZE_4_BYTES = 4,
+   LPB_DEV_PORTSIZE_8_BYTES = 8
+};
+
+enum mpc512x_lpbfifo_req_dir {
+   MPC512X_LPBFIFO_REQ_DIR_READ,
+   MPC512X_LPBFIFO_REQ_DIR_WRITE
+};
+
+struct mpc512x_lpbfifo_request {
+   phys_addr_t bus_phys;   /* physical address of some device on LPB */
+   void *ram_virt; /* virtual address of some region in RAM */
+   u32 size;
+   enum lpb_dev_portsize portsize;
+   enum mpc512x_lpbfifo_req_dir dir;
+   void (*callback)(struct mpc512x_lpbfifo_request *);
+};
+
+int mpc512x_lpbfifo_submit(struct mpc512x_lpbfifo_request *req);
+
 #endif /* __ASM_POWERPC_MPC5121_H__ */
diff --git a/arch/powerpc/platforms/512x/Kconfig 
b/arch/powerpc/platforms/512x/Kconfig
index 48bf38d..f09016f 100644
--- a/arch/powerpc/platforms/512x/Kconfig
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -10,6 +10,12 @@ config PPC_MPC512x
select USB_EHCI_BIG_ENDIAN_MMIO if USB_EHCI_HCD
select USB_EHCI_BIG_ENDIAN_DESC if USB_EHCI_HCD
 
+config MPC512x_LPBFIFO
+   tristate "MPC512x LocalPlus Bus FIFO driver"
+   depends on PPC_MPC512x && MPC512X_DMA
+   help
+ Enable support for Freescale MPC512x LocalPlus Bus FIFO (SCLPC).
+
 config MPC5121_ADS
bool "Freescale MPC5121E ADS"
depends on PPC_MPC512x
diff --git a/arch/powerpc/platforms/512x/Makefile 
b/arch/powerpc/platforms/512x/Makefile
index 0169312..f47d422 100644
--- a/arch/powerpc/platforms/512x/Makefile
+++ b/arch/powerpc/platforms/512x/Makefile
@@ -5,4 +5,5 @@ obj-$(CONFIG_COMMON_CLK)+= clock-commonclk.o
 obj-y  += mpc512x_shared.o
 obj-$(CONFIG_MPC5121_ADS)  += mpc5121_ads.o mpc5121_ads_cpld.o
 obj-$(CONFIG_MPC512x_GENERIC)  += mpc51

[PATCH v3 0/3] powerpc/512x: add LocalPlus Bus FIFO device driver

2015-09-24 Thread Alexander Popov
This driver for Freescale MPC512x LocalPlus Bus FIFO (called SCLPC
in the Reference Manual) allows Direct Memory Access transfers
between RAM and peripheral devices on LocalPlus Bus.

Changes in v3:
 - resource usage in probe() is fixed;
 - driver methods are made safe against remove();
 - dma_request_slave_channel() is used to get DMA channel number from
the device tree;
 - chip select number concerned with the DMA transaction is determined
from 'localbus' device tree node information;
 - register set is described as a structure;
 - symbolic names are given to shift counts to keep magic numbers
out of the code;
 - choosing values for LPBFIFO BPT (bytes per transfer) and DMA maxburst
is improved, so DMA transfer size has increased for some cases;
 - device tree binding for LPBFIFO is documented;
 - Kconfig and Makefile are improved;
 - email address "a13xp0p0...@gmail.com" is changed to a more pleasant
alias "alex.po...@linux.com";

Alexander Popov (3):
  powerpc/512x: add LocalPlus Bus FIFO device driver
  powerpc/512x: add a device tree binding for LocalPlus Bus FIFO
  dmaengine: mpc512x: initialize with subsys_initcall()

 .../bindings/powerpc/fsl/mpc512x_lpbfifo.txt   |  21 +
 arch/powerpc/boot/dts/mpc5121.dtsi |  11 +-
 arch/powerpc/boot/dts/mpc5125twr.dts   |  11 +-
 arch/powerpc/configs/mpc512x_defconfig |   1 +
 arch/powerpc/include/asm/mpc5121.h |  59 +++
 arch/powerpc/platforms/512x/Kconfig|   6 +
 arch/powerpc/platforms/512x/Makefile   |   1 +
 arch/powerpc/platforms/512x/mpc512x_lpbfifo.c  | 560 +
 drivers/dma/mpc512x_dma.c  |  12 +-
 9 files changed, 678 insertions(+), 4 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/powerpc/fsl/mpc512x_lpbfifo.txt
 create mode 100644 arch/powerpc/platforms/512x/mpc512x_lpbfifo.c

-- 
1.9.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3 2/3] powerpc/512x: add a device tree binding for LocalPlus Bus FIFO

2015-09-24 Thread Alexander Popov
Add a device tree binding for Freescale MPC512x LocalPlus Bus FIFO and
introduce the document describing that binding.

Signed-off-by: Alexander Popov <alex.po...@linux.com>
---
 .../bindings/powerpc/fsl/mpc512x_lpbfifo.txt| 21 +
 arch/powerpc/boot/dts/mpc5121.dtsi  | 11 +--
 arch/powerpc/boot/dts/mpc5125twr.dts| 11 ++-
 3 files changed, 40 insertions(+), 3 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/powerpc/fsl/mpc512x_lpbfifo.txt

diff --git a/Documentation/devicetree/bindings/powerpc/fsl/mpc512x_lpbfifo.txt 
b/Documentation/devicetree/bindings/powerpc/fsl/mpc512x_lpbfifo.txt
new file mode 100644
index 000..b3b392f
--- /dev/null
+++ b/Documentation/devicetree/bindings/powerpc/fsl/mpc512x_lpbfifo.txt
@@ -0,0 +1,21 @@
+Freescale MPC512x LocalPlus Bus FIFO (called SCLPC in the Reference Manual)
+
+Required properties:
+- compatible: should be "fsl,mpc512x-lpbfifo";
+- reg: should contain the offset and length of SCLPC register set;
+- interrupts: should contain the interrupt specifier for SCLPC; syntax of an
+interrupt client node is described in interrupt-controller/interrupts.txt;
+- dmas: should contain the DMA specifier for SCLPC as described at
+dma/dma.txt and dma/mpc512x-dma.txt;
+- dma-names: should be "rx-tx";
+
+Example:
+
+   sclpc@10100 {
+   compatible = "fsl,mpc512x-lpbfifo";
+   reg = <0x10100 0x50>;
+   interrupts = <7 0x8>;
+   dmas = < 26>;
+   dma-names = "rx-tx";
+   };
+
diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi 
b/arch/powerpc/boot/dts/mpc5121.dtsi
index 7f9d14f..a015e45 100644
--- a/arch/powerpc/boot/dts/mpc5121.dtsi
+++ b/arch/powerpc/boot/dts/mpc5121.dtsi
@@ -77,7 +77,6 @@
#address-cells = <2>;
#size-cells = <1>;
reg = <0x8020 0x40>;
-   interrupts = <7 0x8>;
ranges = <0x0 0x0 0xfc00 0x0400>;
};
 
@@ -329,7 +328,15 @@
/* LocalPlus controller */
lpc@1 {
compatible = "fsl,mpc5121-lpc";
-   reg = <0x1 0x200>;
+   reg = <0x1 0x100>;
+   };
+
+   sclpc@10100 {
+   compatible = "fsl,mpc512x-lpbfifo";
+   reg = <0x10100 0x50>;
+   interrupts = <7 0x8>;
+   dmas = < 26>;
+   dma-names = "rx-tx";
};
 
pata@10200 {
diff --git a/arch/powerpc/boot/dts/mpc5125twr.dts 
b/arch/powerpc/boot/dts/mpc5125twr.dts
index e4f2974..898eb58 100644
--- a/arch/powerpc/boot/dts/mpc5125twr.dts
+++ b/arch/powerpc/boot/dts/mpc5125twr.dts
@@ -246,6 +246,14 @@
status = "disabled";
};
 
+   sclpc@10100 {
+   compatible = "fsl,mpc512x-lpbfifo";
+   reg = <0x10100 0x50>;
+   interrupts = <7 0x8>;
+   dmas = < 26>;
+   dma-names = "rx-tx";
+   };
+
// 5125 PSCs are not 52xx or 5121 PSC compatible
// PSC1 uart0 aka ttyPSC0
serial@11100 {
@@ -279,10 +287,11 @@
clock-names = "ipg";
};
 
-   dma@14000 {
+   dma0: dma@14000 {
compatible = "fsl,mpc5121-dma"; // BSP name: 
"mpc512x-dma2"
reg = <0x14000 0x1800>;
interrupts = <65 0x8>;
+   #dma-cells = <1>;
};
};
 };
-- 
1.9.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3 3/3] dmaengine: mpc512x: initialize with subsys_initcall()

2015-09-24 Thread Alexander Popov
Initialize Freescale MPC512x DMA driver with subsys_initcall()
to allow the depending drivers to call dma_request_slave_channel()
during their probe.

Signed-off-by: Alexander Popov <alex.po...@linux.com>
---
 drivers/dma/mpc512x_dma.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index e6281e7..4f29d7c 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -1083,7 +1083,17 @@ static struct platform_driver mpc_dma_driver = {
},
 };
 
-module_platform_driver(mpc_dma_driver);
+static int __init mpc_dma_driver_init(void)
+{
+   return platform_driver_register(_dma_driver);
+}
+subsys_initcall(mpc_dma_driver_init);
+
+static void __exit mpc_dma_driver_exit(void)
+{
+   platform_driver_unregister(_dma_driver);
+}
+module_exit(mpc_dma_driver_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Piotr Ziecik <ko...@semihalf.com>");
-- 
1.9.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 1/1] net: fs_enet: Fix NETIF_F_SG feature for Freescale MPC5121

2015-06-20 Thread Alexander Popov
Commit 4fc9b87bae25 (net: fs_enet: Implement NETIF_F_SG feature)
brings a trouble to Freescale MPC512x: a kernel oops happens
during sending non-linear sk_buff with .data not aligned by 4.

Log quotation:

Unable to handle kernel paging request for data at address 0xe467c000
Faulting instruction address: 0xc000cd44
Oops: Kernel access of bad area, sig: 11 [#1]
MPC512x generic
Modules linked in:
CPU: 0 PID: 984 Comm: kworker/0:1H Not tainted 4.1.0-rc8-00024-gbb16140 #2
Workqueue: rpciod rpc_async_schedule
task: cf364a50 ti: cf362000 task.ti: cf362000
NIP: c000cd44 LR: c000c720 CTR: 0206
REGS: cf363ac0 TRAP: 0300   Not tainted  (4.1.0-rc8-00024-gbb16140)
MSR: 9032 EE,ME,IR,DR,RI  CR: 42004082  XER: 
DAR: e467c000 DSISR: 2000
GPR00: c0279e24 cf363b70 cf364a50 e467c000 0206 001f 0001 0001
GPR08:  e467c000 e46800be 000139a6 82002082  c002e46c cf3c3680
GPR16: c044cb30 c04b cf363c48  0001 fde0315c  000b
GPR24: 002c 40be cf339aa0 000b 0001 cf873210 00282f85 
NIP [c000cd44] clean_dcache_range+0x1c/0x30
LR [c000c720] dma_direct_map_page+0x40/0x94
Call Trace:
[cf363b70] [cf339b60] 0xcf339b60 (unreliable)
[cf363b90] [c0279e24] fs_enet_start_xmit+0x1c8/0x42c
[cf363bd0] [c02ff710] dev_hard_start_xmit+0x2dc/0x3d4
[cf363c40] [c0319c60] sch_direct_xmit+0xcc/0x1cc
[cf363c70] [c02ff9c0] __dev_queue_xmit+0x1b8/0x47c
[cf363ca0] [c032a3e8] ip_finish_output+0x1fc/0x9a8
[cf363ce0] [c032c31c] ip_send_skb+0x1c/0xa4
[cf363cf0] [c035112c] udp_send_skb+0xe4/0x2e8
[cf363d10] [c0351368] udp_push_pending_frames+0x38/0x84
[cf363d20] [c03537b8] udp_sendpage+0x134/0x174
[cf363d70] [c0384fd4] xs_sendpages+0x21c/0x250
[cf363db0] [c03852bc] xs_udp_send_request+0x50/0xf8
[cf363de0] [c0382f08] xprt_transmit+0x64/0x280
[cf363e20] [c038017c] call_transmit+0x168/0x234
[cf363e40] [c0387918] __rpc_execute+0x88/0x2b0
[cf363e80] [c00296f8] process_one_work+0x124/0x2fc
[cf363ea0] [c0029a00] worker_thread+0x130/0x480
[cf363ef0] [c002e528] kthread+0xbc/0xd0
[cf363f40] [c000e4a8] ret_from_kernel_thread+0x5c/0x64
Instruction dump:
7c70faa6 60630800 7c70fba6 4c00012c 4e800020 38a0001f 7c632878 7c832050
7c842a14 5484d97f 4d820020 7c8903a6 7c00186c 38630020 4200fff8 7c0004ac
---[ end trace c846c1eceb513c85 ]---

The reason:

MPC5121 FEC requires 4-byte alignment for TX data buffer and calls
tx_skb_align_workaround() for copying sk_buff with not aligned .data to a new
sk_buff with aligned one. But tx_skb_align_workaround() uses
skb_copy_from_linear_data() which doesn't work for non-linear sk_buff:
a new sk_buff has non-zero nr_frags and zero .data_len.

So improve the condition of calling tx_skb_align_workaround() and use
skb_linearize() in it.

Signed-off-by: Alexander Popov alex.po...@linux.com
---
 .../net/ethernet/freescale/fs_enet/fs_enet-main.c  | 26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c 
b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
index 9b3639e..d92802b 100644
--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
@@ -490,6 +490,9 @@ static struct sk_buff *tx_skb_align_workaround(struct 
net_device *dev,
 {
struct sk_buff *new_skb;
 
+   if (skb_linearize(skb))
+   return NULL;
+
/* Alloc new skb */
new_skb = netdev_alloc_skb(dev, skb-len + 4);
if (!new_skb)
@@ -515,12 +518,27 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct 
net_device *dev)
cbd_t __iomem *bdp;
int curidx;
u16 sc;
-   int nr_frags = skb_shinfo(skb)-nr_frags;
+   int nr_frags;
skb_frag_t *frag;
int len;
-
 #ifdef CONFIG_FS_ENET_MPC5121_FEC
-   if (((unsigned long)skb-data)  0x3) {
+   int is_aligned = 1;
+   int i;
+
+   if (!IS_ALIGNED((unsigned long)skb-data, 4)) {
+   is_aligned = 0;
+   } else {
+   nr_frags = skb_shinfo(skb)-nr_frags;
+   frag = skb_shinfo(skb)-frags;
+   for (i = 0; i  nr_frags; i++, frag++) {
+   if (!IS_ALIGNED(frag-page_offset, 4)) {
+   is_aligned = 0;
+   break;
+   }
+   }
+   }
+
+   if (!is_aligned) {
skb = tx_skb_align_workaround(dev, skb);
if (!skb) {
/*
@@ -532,6 +550,7 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct 
net_device *dev)
}
}
 #endif
+
spin_lock(fep-tx_lock);
 
/*
@@ -539,6 +558,7 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct 
net_device *dev)
 */
bdp = fep-cur_tx;
 
+   nr_frags = skb_shinfo(skb)-nr_frags;
if (fep-tx_free = nr_frags || (CBDR_SC(bdp)  BD_ENET_TX_READY)) {
netif_stop_queue(dev

Re: [PATCH 1/1] net: fs_enet: Disable NETIF_F_SG feature for Freescale MPC5121

2015-06-14 Thread Alexander Popov

10.06.2015 03:14, David Miller пишет:

From: Alexander Popov alex.po...@linux.com
Date: Wed, 10 Jun 2015 02:57:42 +0300


skb_copy_from_linear_data() which doesn't work well for non-linear sk_buff:


The correct fix is to use an SKB copy routine which can
handle non-linear data.


Thanks, David.
I'll prepare the second version of the patch.

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 1/1] net: fs_enet: Disable NETIF_F_SG feature for Freescale MPC5121

2015-06-09 Thread Alexander Popov
Commit 4fc9b87bae25 (net: fs_enet: Implement NETIF_F_SG feature)
brings a trouble to Freescale MPC512x: a kernel oops happens
during sending non-linear sk_buff with .data not aligned by 4.

Log quotation:

Unable to handle kernel paging request for data at address 0xd067c000
Faulting instruction address: 0xc000cd44
Oops: Kernel access of bad area, sig: 11 [#1]
MPC512x generic
Modules linked in:
CPU: 0 PID: 983 Comm: kworker/0:1H Not tainted 4.1.0-rc7-00047-g5879ae5 #1
Workqueue: rpciod rpc_async_schedule
task: cf3415b0 ti: cf33 task.ti: cf33
NIP: c000cd44 LR: c000c720 CTR: 020d
REGS: cf331ac0 TRAP: 0300   Not tainted  (4.1.0-rc7-00047-g5879ae5)
MSR: 9032 EE,ME,IR,DR,RI  CR: 42004082  XER: 
DAR: d067c000 DSISR: 2000
GPR00: c0279d70 cf331b70 cf3415b0 d067c000 020d 001f 0001 0001
GPR08:  d067c000 d068019e 00013b36 82002082  c002e46c cf3405e0
GPR16: c044cb10 c04b cf331c48  0001 fde03164  000c
GPR24: 0030 419e cf99d6e0 000c 0001 cf873210 2f99 
NIP [c000cd44] clean_dcache_range+0x1c/0x30
LR [c000c720] dma_direct_map_page+0x40/0x94
Call Trace:
[cf331b70] [cf99db60] 0xcf99db60 (unreliable)
[cf331b90] [c0279d70] fs_enet_start_xmit+0x1c8/0x42c
[cf331bd0] [c02ff660] dev_hard_start_xmit+0x2dc/0x3d4
[cf331c40] [c0319bb0] sch_direct_xmit+0xcc/0x1cc
[cf331c70] [c02ff910] __dev_queue_xmit+0x1b8/0x47c
[cf331ca0] [c032a338] ip_finish_output+0x1fc/0x9a8
[cf331ce0] [c032c26c] ip_send_skb+0x1c/0xa4
[cf331cf0] [c035107c] udp_send_skb+0xe4/0x2e8
[cf331d10] [c03512b8] udp_push_pending_frames+0x38/0x84
[cf331d20] [c0353708] udp_sendpage+0x134/0x174
[cf331d70] [c0384f24] xs_sendpages+0x21c/0x250
[cf331db0] [c038520c] xs_udp_send_request+0x50/0xf8
[cf331de0] [c0382e58] xprt_transmit+0x64/0x280
[cf331e20] [c03800cc] call_transmit+0x168/0x234
[cf331e40] [c0387868] __rpc_execute+0x88/0x2b0
[cf331e80] [c00296f8] process_one_work+0x124/0x2fc
[cf331ea0] [c0029a00] worker_thread+0x130/0x480
[cf331ef0] [c002e528] kthread+0xbc/0xd0
[cf331f40] [c000e4a8] ret_from_kernel_thread+0x5c/0x64
Instruction dump:
7c70faa6 60630800 7c70fba6 4c00012c 4e800020 38a0001f 7c632878 7c832050
7c842a14 5484d97f 4d820020 7c8903a6 7c00186c 38630020 4200fff8 7c0004ac
---[ end trace 08fef9a8ee013f63 ]---

The reason:

MPC5121 FEC requires 4-byte alignment for TX data buffer and calls
tx_skb_align_workaround() for copying sk_buff with not aligned .data to a new
sk_buff with aligned one. But tx_skb_align_workaround() uses
skb_copy_from_linear_data() which doesn't work well for non-linear sk_buff:
a new sk_buff has non-zero nr_frags and zero .data_len.

So disabling NETIF_F_SG for Freescale MPC5121 might be better than handling
improper alignment for sk_buff.data and all the fragments.

Signed-off-by: Alexander Popov alex.po...@linux.com
---
 drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c 
b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
index 9b3639e..1450477 100644
--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
@@ -1040,7 +1040,9 @@ static int fs_enet_probe(struct platform_device *ofdev)
 
netif_carrier_off(ndev);
 
+#ifndef CONFIG_FS_ENET_MPC5121_FEC
ndev-features |= NETIF_F_SG;
+#endif
 
ret = register_netdev(ndev);
if (ret)
-- 
1.9.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: Disabled LocalPlus Controller (LPC) clock on MPC512x

2015-02-10 Thread Alexander Popov

Hello Matteo,
sorry for such a long delay in replying, now I have my board back again.

19.12.2014 12:38, Matteo Facchinetti пишет:

On 16/12/2014 13:00, Alexander Popov wrote:

In fact clk_ignore_unused bootparam helps to avoid disabling NFC clock.
The board crash is reproduced again if I perform the following steps:
1. disable NFC clock in uboot by clearing NFC_EN bit in SCCR1 register,
2. boot Linux with clk_ignore_unused,
3. touch any LPB address.


Could you see the Reset Status Register (RSR) after board crash?
When boad reset, you may stop uboot in console and then print the value
of this register.

This could be help to see what happen internally to the microcontroller.


I've reproduced TWR-MPC5125 crash without Linux only in uboot.
This is the annotated procedure:

= md.l 0x8e10  /* Reset Status Register */
8e10: 6000  /* All flags are cleared (just powered on) */

= md.l 0x8f04  /* System Clock Control Register 1 */
8f04: e404b600  /* NFC clock is enabled */

= md.l 0xfff0  /* Reading from MRAM living at LPB CS0 */
fff0: cafea134  /* Works fine */

= mw.l 0x8f04 0xc404b600 1 /* Disable NFC clock */

= md.l 0x8f04
8f04: c404b600  /* NFC clock is disabled now */

= md.l 0xfff0  /* Reading from MRAM again */
fff0:

/* The board has just reset */

U-Boot 2009.03-4-gd37ab38 (Apr 14 2010 - 10:48:22) MPC512X
CPU:   MPC5125 rev. 1.0, Core e300c4 at 393.216 MHz, CSB at 196.608 MHz
...

= md.l 0x8e10  /* Read RSR */
8e10: 6040  /* Only external HRESET1 event has occurred */

But rising of EXT1HRS flag is not special for this crash.
EXT1HRS is similarly set if I execute 'reset' command in uboot
or call 'reboot' from Linux.

Thanks.

Best regards,
Alexander

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: Disabled LocalPlus Controller (LPC) clock on MPC512x

2014-12-16 Thread Alexander Popov

02.12.2014 13:47, Matteo Facchinetti пишет:

On 26/11/2014 12:49, Alexander Popov wrote:

Hello.

Hi.


Thanks for your reply, Matteo.
I've looked deeper and have more information about the crash.


My Freescale TWR-MPC5125 board instantly reboots if I touch
any physical address on the LocalPlus Bus (LPB) for the first time
when Linux has already booted.

This effect is reproduced by using /dev/mem or loading a kernel module
which works with any peripherals on LPB.

It took me some time to find out that such crash is caused by
clk_disable_unused() in drivers/clk/clk.c, which disables
LocalPlus Controller (LPC) clock if I don't touch LPB addresses in the
previous initcalls.


My first diagnosis was not correct: clk_disable_unused() doesn't disable
LPC clock because in arch/powerpc/platforms/512x/clock-commonclk.c
we call:
clk_prepare_enable(clks[MPC512x_CLK_LPC]);

But clk_disable_unused() disables NFC clock as unused which seems to be
a real reason of board crash.


So starting Linux with clk_ignore_unused bootparam
or inserting dummy LPB reading to some initcall is a temporary fix.


In fact clk_ignore_unused bootparam helps to avoid disabling NFC clock.
The board crash is reproduced again if I perform the following steps:
1. disable NFC clock in uboot by clearing NFC_EN bit in SCCR1 register,
2. boot Linux with clk_ignore_unused,
3. touch any LPB address.

At the same time disabling NFC clock and reading from LPB certainly
in uboot doesn't make MPC5125 reset instantly. So I can't reproduce
the crash in uboot. It looks like we do something wrong in Linux.


   - may be good to enable MPC512x_CLK_LPC only when localbus is enabled
by the dts
   - if enabled, MPC512x_CLK_LPC have to setup with CLK_IGNORE_UNUSED
flag because never get claimed by any driver.


This approach didn't help to fix the crash because in fact
clk_disable_unused() doesn't disable LPC clock as I wrote above.


I put in CC Gerhard Sittig also beacuse it might be interesting to
know his point of view as the author of mpc512x common clock driver.


Surely. Thanks.

Best regards,
Alexander

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Disabled LocalPlus Controller (LPC) clock on MPC512x

2014-11-26 Thread Alexander Popov

Hello.

My Freescale TWR-MPC5125 board instantly reboots if I touch
any physical address on the LocalPlus Bus (LPB) for the first time
when Linux has already booted.

This effect is reproduced by using /dev/mem or loading a kernel module
which works with any peripherals on LPB.

It took me some time to find out that such crash is caused by
clk_disable_unused() in drivers/clk/clk.c, which disables
LocalPlus Controller (LPC) clock if I don't touch LPB addresses in the
previous initcalls. So starting Linux with clk_ignore_unused bootparam
or inserting dummy LPB reading to some initcall is a temporary fix.

Is it correct to gate LPC clock? If yes, how to avoid the mentioned
crashes properly?

There's a piece of code in arch/powerpc/platforms/512x/clock-commonclk.c
which is doubtful for me:

/*
 * pre-enable those internal clock items which never get
 * claimed by any peripheral driver, to not have the clock
 * subsystem disable them late at startup
 */
clk_prepare_enable(clks[MPC512x_CLK_DUMMY]);
clk_prepare_enable(clks[MPC512x_CLK_E300]);/* PowerPC CPU */
clk_prepare_enable(clks[MPC512x_CLK_DDR]);/* DRAM */
clk_prepare_enable(clks[MPC512x_CLK_MEM]);/* SRAM */
clk_prepare_enable(clks[MPC512x_CLK_IPS]);/* SoC periph */
clk_prepare_enable(clks[MPC512x_CLK_LPC]);/* boot media */

Does it mean that these clocks should be registered with
CLK_IGNORE_UNUSED flag?

Thanks a lot.
Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v3 0/3] dmaengine: mpc512x: add device tree binding document and DMA channel lookup

2014-07-20 Thread Alexander Popov
Hello!

2014-06-25 14:52 GMT+04:00 Alexander Popov a13xp0p0...@gmail.com:
 This patch series introduces a device tree binding document for
 the MPC512x DMA controller and adds device tree based DMA channel lookup
 for it.

 This version contains the improved device tree binding document:
 #dma-cells is made a required property, as it must be according
 dma/dma.txt document.

Could I have a feedback, please?
Thanks!

 Alexander Popov (3):
   dmaengine: mpc512x: add device tree binding document
   dmaengine: of: add common xlate function for matching by channel id
   dmaengine: mpc512x: register for device tree channel lookup

  .../devicetree/bindings/dma/mpc512x-dma.txt| 29 ++
  arch/powerpc/boot/dts/mpc5121.dtsi |  1 +
  drivers/dma/mpc512x_dma.c  | 13 +++-
  drivers/dma/of-dma.c   | 35 
 ++
  include/linux/of_dma.h |  4 +++
  5 files changed, 81 insertions(+), 1 deletion(-)
  create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

 --
 1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3 0/3] dmaengine: mpc512x: add device tree binding document and DMA channel lookup

2014-06-25 Thread Alexander Popov
This patch series introduces a device tree binding document for
the MPC512x DMA controller and adds device tree based DMA channel lookup
for it.

This version contains the improved device tree binding document:
#dma-cells is made a required property, as it must be according
dma/dma.txt document.

Alexander Popov (3):
  dmaengine: mpc512x: add device tree binding document
  dmaengine: of: add common xlate function for matching by channel id
  dmaengine: mpc512x: register for device tree channel lookup

 .../devicetree/bindings/dma/mpc512x-dma.txt| 29 ++
 arch/powerpc/boot/dts/mpc5121.dtsi |  1 +
 drivers/dma/mpc512x_dma.c  | 13 +++-
 drivers/dma/of-dma.c   | 35 ++
 include/linux/of_dma.h |  4 +++
 5 files changed, 81 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3 1/3] dmaengine: mpc512x: add device tree binding document

2014-06-25 Thread Alexander Popov
Introduce a device tree binding document for the MPC512x DMA controller

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 .../devicetree/bindings/dma/mpc512x-dma.txt| 29 ++
 1 file changed, 29 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

diff --git a/Documentation/devicetree/bindings/dma/mpc512x-dma.txt 
b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
new file mode 100644
index 000..a6511df
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
@@ -0,0 +1,29 @@
+* Freescale MPC512x and MPC8308 DMA Controller
+
+The DMA controller in Freescale MPC512x and MPC8308 SoCs can move
+blocks of memory contents between memory and peripherals or
+from memory to memory.
+
+Refer to Generic DMA Controller and DMA request bindings in
+the dma/dma.txt file for a more detailed description of binding.
+
+Required properties:
+- compatible: should be fsl,mpc5121-dma or fsl,mpc8308-dma;
+- reg: should contain the DMA controller registers location and length;
+- interrupt for the DMA controller: syntax of interrupt client node
+   is described in interrupt-controller/interrupts.txt file.
+- #dma-cells: the length of the DMA specifier, must be 1.
+   Each channel of this DMA controller has a peripheral request line,
+   the assignment is fixed in hardware. This one cell
+   in dmas property of a client device represents the channel number.
+
+Example:
+
+   dma0: dma@14000 {
+   compatible = fsl,mpc5121-dma;
+   reg = 0x14000 0x1800;
+   interrupts = 65 0x8;
+   #dma-cells = 1;
+   };
+
+DMA clients must use the format described in dma/dma.txt file.
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3 2/3] dmaengine: of: add common xlate function for matching by channel id

2014-06-25 Thread Alexander Popov
This patch adds a new common OF dma xlate callback function which will match a
channel by it's id. The binding expects one integer argument which it will use 
to
lookup the channel by the id.

Unlike of_dma_simple_xlate this function is able to handle a system with
multiple DMA controllers. When registering the of dma provider with
of_dma_controller_register a pointer to the dma_device struct which is
associated with the dt node needs to passed as the data parameter.
New function will use this pointer to match only channels which belong to the
specified DMA controller.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/of-dma.c   | 35 +++
 include/linux/of_dma.h |  4 
 2 files changed, 39 insertions(+)

diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index e8fe9dc..d5fbeaa 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -218,3 +218,38 @@ struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_spec,
dma_spec-args[0]);
 }
 EXPORT_SYMBOL_GPL(of_dma_simple_xlate);
+
+/**
+ * of_dma_xlate_by_chan_id - Translate dt property to DMA channel by channel id
+ * @dma_spec:  pointer to DMA specifier as found in the device tree
+ * @of_dma:pointer to DMA controller data
+ *
+ * This function can be used as the of xlate callback for DMA driver which 
wants
+ * to match the channel based on the channel id. When using this xlate function
+ * the #dma-cells propety of the DMA controller dt node needs to be set to 1.
+ * The data parameter of of_dma_controller_register must be a pointer to the
+ * dma_device struct the function should match upon.
+ *
+ * Returns pointer to appropriate dma channel on success or NULL on error.
+ */
+struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
+struct of_dma *ofdma)
+{
+   struct dma_device *dev = ofdma-of_dma_data;
+   struct dma_chan *chan, *candidate = NULL;
+
+   if (!dev || dma_spec-args_count != 1)
+   return NULL;
+
+   list_for_each_entry(chan, dev-channels, device_node)
+   if (chan-chan_id == dma_spec-args[0]) {
+   candidate = chan;
+   break;
+   }
+
+   if (!candidate)
+   return NULL;
+
+   return dma_get_slave_channel(candidate);
+}
+EXPORT_SYMBOL_GPL(of_dma_xlate_by_chan_id);
diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
index ae36298..56bc026 100644
--- a/include/linux/of_dma.h
+++ b/include/linux/of_dma.h
@@ -41,6 +41,8 @@ extern struct dma_chan *of_dma_request_slave_channel(struct 
device_node *np,
 const char *name);
 extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma);
+extern struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args 
*dma_spec,
+   struct of_dma *ofdma);
 #else
 static inline int of_dma_controller_register(struct device_node *np,
struct dma_chan *(*of_dma_xlate)
@@ -66,6 +68,8 @@ static inline struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_s
return NULL;
 }
 
+#define of_dma_xlate_by_chan_id NULL
+
 #endif
 
 #endif /* __LINUX_OF_DMA_H */
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3 3/3] dmaengine: mpc512x: register for device tree channel lookup

2014-06-25 Thread Alexander Popov
Register the controller for device tree based lookup of DMA channels
(non-fatal for backwards compatibility with older device trees) and
provide the '#dma-cells' property in the shared mpc5121.dtsi file

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 arch/powerpc/boot/dts/mpc5121.dtsi |  1 +
 drivers/dma/mpc512x_dma.c  | 13 -
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi 
b/arch/powerpc/boot/dts/mpc5121.dtsi
index 2c0e155..7f9d14f 100644
--- a/arch/powerpc/boot/dts/mpc5121.dtsi
+++ b/arch/powerpc/boot/dts/mpc5121.dtsi
@@ -498,6 +498,7 @@
compatible = fsl,mpc5121-dma;
reg = 0x14000 0x1800;
interrupts = 65 0x8;
+   #dma-cells = 1;
};
};
 
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 2ad4373..881db2b 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -53,6 +53,7 @@
 #include linux/of_address.h
 #include linux/of_device.h
 #include linux/of_irq.h
+#include linux/of_dma.h
 #include linux/of_platform.h
 
 #include linux/random.h
@@ -1036,7 +1037,15 @@ static int mpc_dma_probe(struct platform_device *op)
if (retval)
goto err_free2;
 
-   return retval;
+   /* Register with OF helpers for DMA lookups (nonfatal) */
+   if (dev-of_node) {
+   retval = of_dma_controller_register(dev-of_node,
+   of_dma_xlate_by_chan_id, mdma);
+   if (retval)
+   dev_warn(dev, Could not register for OF lookup\n);
+   }
+
+   return 0;
 
 err_free2:
if (mdma-is_mpc8308)
@@ -1057,6 +1066,8 @@ static int mpc_dma_remove(struct platform_device *op)
struct device *dev = op-dev;
struct mpc_dma *mdma = dev_get_drvdata(dev);
 
+   if (dev-of_node)
+   of_dma_controller_free(dev-of_node);
dma_async_device_unregister(mdma-dma);
if (mdma-is_mpc8308) {
free_irq(mdma-irq2, mdma);
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v2 1/3] dmaengine: mpc512x: add device tree binding document

2014-06-19 Thread Alexander Popov
2014-06-18 18:56 GMT+04:00 Alexander Popov a13xp0p0...@gmail.com:
 2014-06-18 17:37 GMT+04:00 Mark Rutland mark.rutl...@arm.com:
 On Wed, Jun 18, 2014 at 11:48:10AM +0100, Alexander Popov wrote:
 Introduce a device tree binding document for the MPC512x DMA controller
 +Optional properties:
 +- #dma-cells: the length of the DMA specifier, must be 1.
 + Each channel of this DMA controller has a peripheral request line,
 + the assignment is fixed in hardware. This one cell
 + in dmas property of a client device represents the channel number.

 Surely this is required to be able to refer to DMA channels on the
 device?

 Excuse me, I didn't understand your question.
 Do you inquire about the reason of making #dma-cells an optional property?
 It's optional because device tree based lookup support is made
 optional (part 3/3).

Mark, did I answer your question?
Should I fix anything in this patch series?

Hope for the reply.
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 0/3] dmaengine: mpc512x: add device tree binding document and DMA channel lookup

2014-06-18 Thread Alexander Popov
This patch series introduces a device tree binding document for
the MPC512x DMA controller and adds device tree based DMA channel lookup
for it.

This version has improved device tree binding document.

Alexander Popov (3):
  dmaengine: mpc512x: add device tree binding document
  dmaengine: of: add common xlate function for matching by channel id
  dmaengine: mpc512x: register for device tree channel lookup

 .../devicetree/bindings/dma/mpc512x-dma.txt| 31 +++
 arch/powerpc/boot/dts/mpc5121.dtsi |  1 +
 drivers/dma/mpc512x_dma.c  | 13 +++-
 drivers/dma/of-dma.c   | 35 ++
 include/linux/of_dma.h |  4 +++
 5 files changed, 83 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 1/3] dmaengine: mpc512x: add device tree binding document

2014-06-18 Thread Alexander Popov
Introduce a device tree binding document for the MPC512x DMA controller

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 .../devicetree/bindings/dma/mpc512x-dma.txt| 31 ++
 1 file changed, 31 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

diff --git a/Documentation/devicetree/bindings/dma/mpc512x-dma.txt 
b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
new file mode 100644
index 000..95e2ca0
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
@@ -0,0 +1,31 @@
+* Freescale MPC512x and MPC8308 DMA Controller
+
+The DMA controller in Freescale MPC512x and MPC8308 SoCs can move
+blocks of memory contents between memory and peripherals or
+from memory to memory.
+
+Refer to Generic DMA Controller and DMA request bindings in
+the dma/dma.txt file for a more detailed description of binding.
+
+Required properties:
+- compatible: should be fsl,mpc5121-dma or fsl,mpc8308-dma;
+- reg: should contain the DMA controller registers location and length;
+- interrupt for the DMA controller: syntax of interrupt client node
+   is described in interrupt-controller/interrupts.txt file.
+
+Optional properties:
+- #dma-cells: the length of the DMA specifier, must be 1.
+   Each channel of this DMA controller has a peripheral request line,
+   the assignment is fixed in hardware. This one cell
+   in dmas property of a client device represents the channel number.
+
+Example:
+
+   dma0: dma@14000 {
+   compatible = fsl,mpc5121-dma;
+   reg = 0x14000 0x1800;
+   interrupts = 65 0x8;
+   #dma-cells = 1;
+   };
+
+DMA clients must use the format described in dma/dma.txt file.
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 2/3] dmaengine: of: add common xlate function for matching by channel id

2014-06-18 Thread Alexander Popov
This patch adds a new common OF dma xlate callback function which will match a
channel by it's id. The binding expects one integer argument which it will use 
to
lookup the channel by the id.

Unlike of_dma_simple_xlate this function is able to handle a system with
multiple DMA controllers. When registering the of dma provider with
of_dma_controller_register a pointer to the dma_device struct which is
associated with the dt node needs to passed as the data parameter.
New function will use this pointer to match only channels which belong to the
specified DMA controller.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/of-dma.c   | 35 +++
 include/linux/of_dma.h |  4 
 2 files changed, 39 insertions(+)

diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index e8fe9dc..d5fbeaa 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -218,3 +218,38 @@ struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_spec,
dma_spec-args[0]);
 }
 EXPORT_SYMBOL_GPL(of_dma_simple_xlate);
+
+/**
+ * of_dma_xlate_by_chan_id - Translate dt property to DMA channel by channel id
+ * @dma_spec:  pointer to DMA specifier as found in the device tree
+ * @of_dma:pointer to DMA controller data
+ *
+ * This function can be used as the of xlate callback for DMA driver which 
wants
+ * to match the channel based on the channel id. When using this xlate function
+ * the #dma-cells propety of the DMA controller dt node needs to be set to 1.
+ * The data parameter of of_dma_controller_register must be a pointer to the
+ * dma_device struct the function should match upon.
+ *
+ * Returns pointer to appropriate dma channel on success or NULL on error.
+ */
+struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
+struct of_dma *ofdma)
+{
+   struct dma_device *dev = ofdma-of_dma_data;
+   struct dma_chan *chan, *candidate = NULL;
+
+   if (!dev || dma_spec-args_count != 1)
+   return NULL;
+
+   list_for_each_entry(chan, dev-channels, device_node)
+   if (chan-chan_id == dma_spec-args[0]) {
+   candidate = chan;
+   break;
+   }
+
+   if (!candidate)
+   return NULL;
+
+   return dma_get_slave_channel(candidate);
+}
+EXPORT_SYMBOL_GPL(of_dma_xlate_by_chan_id);
diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
index ae36298..56bc026 100644
--- a/include/linux/of_dma.h
+++ b/include/linux/of_dma.h
@@ -41,6 +41,8 @@ extern struct dma_chan *of_dma_request_slave_channel(struct 
device_node *np,
 const char *name);
 extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma);
+extern struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args 
*dma_spec,
+   struct of_dma *ofdma);
 #else
 static inline int of_dma_controller_register(struct device_node *np,
struct dma_chan *(*of_dma_xlate)
@@ -66,6 +68,8 @@ static inline struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_s
return NULL;
 }
 
+#define of_dma_xlate_by_chan_id NULL
+
 #endif
 
 #endif /* __LINUX_OF_DMA_H */
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 3/3] dmaengine: mpc512x: register for device tree channel lookup

2014-06-18 Thread Alexander Popov
Register the controller for device tree based lookup of DMA channels
(non-fatal for backwards compatibility with older device trees) and
provide the '#dma-cells' property in the shared mpc5121.dtsi file

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 arch/powerpc/boot/dts/mpc5121.dtsi |  1 +
 drivers/dma/mpc512x_dma.c  | 13 -
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi 
b/arch/powerpc/boot/dts/mpc5121.dtsi
index 2c0e155..7f9d14f 100644
--- a/arch/powerpc/boot/dts/mpc5121.dtsi
+++ b/arch/powerpc/boot/dts/mpc5121.dtsi
@@ -498,6 +498,7 @@
compatible = fsl,mpc5121-dma;
reg = 0x14000 0x1800;
interrupts = 65 0x8;
+   #dma-cells = 1;
};
};
 
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 2ad4373..881db2b 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -53,6 +53,7 @@
 #include linux/of_address.h
 #include linux/of_device.h
 #include linux/of_irq.h
+#include linux/of_dma.h
 #include linux/of_platform.h
 
 #include linux/random.h
@@ -1036,7 +1037,15 @@ static int mpc_dma_probe(struct platform_device *op)
if (retval)
goto err_free2;
 
-   return retval;
+   /* Register with OF helpers for DMA lookups (nonfatal) */
+   if (dev-of_node) {
+   retval = of_dma_controller_register(dev-of_node,
+   of_dma_xlate_by_chan_id, mdma);
+   if (retval)
+   dev_warn(dev, Could not register for OF lookup\n);
+   }
+
+   return 0;
 
 err_free2:
if (mdma-is_mpc8308)
@@ -1057,6 +1066,8 @@ static int mpc_dma_remove(struct platform_device *op)
struct device *dev = op-dev;
struct mpc_dma *mdma = dev_get_drvdata(dev);
 
+   if (dev-of_node)
+   of_dma_controller_free(dev-of_node);
dma_async_device_unregister(mdma-dma);
if (mdma-is_mpc8308) {
free_irq(mdma-irq2, mdma);
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v2 1/3] dmaengine: mpc512x: add device tree binding document

2014-06-18 Thread Alexander Popov
Hello Mark, thanks for your reply!

2014-06-18 17:37 GMT+04:00 Mark Rutland mark.rutl...@arm.com:
 On Wed, Jun 18, 2014 at 11:48:10AM +0100, Alexander Popov wrote:
 Introduce a device tree binding document for the MPC512x DMA controller

 Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
 ---
  .../devicetree/bindings/dma/mpc512x-dma.txt| 31 
 ++
  1 file changed, 31 insertions(+)
  create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

 diff --git a/Documentation/devicetree/bindings/dma/mpc512x-dma.txt 
 b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
 new file mode 100644
 index 000..95e2ca0
 --- /dev/null
 +++ b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
 @@ -0,0 +1,31 @@
 +* Freescale MPC512x and MPC8308 DMA Controller
 +
 +The DMA controller in Freescale MPC512x and MPC8308 SoCs can move
 +blocks of memory contents between memory and peripherals or
 +from memory to memory.
 +
 +Refer to Generic DMA Controller and DMA request bindings in
 +the dma/dma.txt file for a more detailed description of binding.
 +
 +Required properties:
 +- compatible: should be fsl,mpc5121-dma or fsl,mpc8308-dma;
 +- reg: should contain the DMA controller registers location and length;
 +- interrupt for the DMA controller: syntax of interrupt client node
 + is described in interrupt-controller/interrupts.txt file.
 +
 +Optional properties:
 +- #dma-cells: the length of the DMA specifier, must be 1.
 + Each channel of this DMA controller has a peripheral request line,
 + the assignment is fixed in hardware. This one cell
 + in dmas property of a client device represents the channel number.

 Surely this is required to be able to refer to DMA channels on the
 device?

Excuse me, I didn't understand your question.
Do you inquire about the reason of making #dma-cells an optional property?
It's optional because device tree based lookup support is made
optional (part 3/3).

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH 0/3] dmaengine: mpc512x: add device tree binding document and DMA channel lookup

2014-06-08 Thread Alexander Popov
2014-05-24 13:33 GMT+04:00 Alexander Popov a13xp0p0...@gmail.com:
 This patch series introduces a device tree binding document for
 the MPC512x DMA controller and adds device tree based DMA channel lookup
 for it.

Hello, excuse me, could I have a feedback?
Should I fix anything?

Thanks a lot!
Alexander

 Alexander Popov (3):
   dmaengine: mpc512x: add device tree binding document
   dmaengine: of: add common xlate function for matching by channel id
   dmaengine: mpc512x: register for device tree channel lookup

  .../devicetree/bindings/dma/mpc512x-dma.txt| 40 
 ++
  arch/powerpc/boot/dts/mpc5121.dtsi |  1 +
  drivers/dma/mpc512x_dma.c  | 13 ++-
  drivers/dma/of-dma.c   | 35 +++
  include/linux/of_dma.h |  4 +++
  5 files changed, 92 insertions(+), 1 deletion(-)
  create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

 --
 1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH RFC v13 0/5] MPC512x DMA slave s/g support, OF DMA lookup

2014-05-24 Thread Alexander Popov
Thank you, Vinod

2014-05-22 9:10 GMT+04:00 Vinod Koul vinod.k...@intel.com:
 On Thu, May 15, 2014 at 06:15:30PM +0400, Alexander Popov wrote:
 Changes in v13:
  A new patch (part 1/5) is added to this series.
  Part 2/5:
  - fix style issue;
  - improve comments;

 You need to cc DT- list for 3 to 5 patches. Need ack before we can apply.
In this v13 series parts 0/5, 3/5, 4/5 and 5/5 do have Cc:
devicet...@vger.kernel.org.

 I suspect 4/5 should come first out of these 3.
Ok. I'll send v14 soon.

 Also in future pls use right subsystem name dmaengine. Also why are these
 tagged as RFC still?
Ok, thanks.

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 0/3] dmaengine: mpc512x: add device tree binding document and DMA channel lookup

2014-05-24 Thread Alexander Popov
This patch series introduces a device tree binding document for
the MPC512x DMA controller and adds device tree based DMA channel lookup
for it.

Alexander Popov (3):
  dmaengine: mpc512x: add device tree binding document
  dmaengine: of: add common xlate function for matching by channel id
  dmaengine: mpc512x: register for device tree channel lookup

 .../devicetree/bindings/dma/mpc512x-dma.txt| 40 ++
 arch/powerpc/boot/dts/mpc5121.dtsi |  1 +
 drivers/dma/mpc512x_dma.c  | 13 ++-
 drivers/dma/of-dma.c   | 35 +++
 include/linux/of_dma.h |  4 +++
 5 files changed, 92 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 2/3] dmaengine: of: add common xlate function for matching by channel id

2014-05-24 Thread Alexander Popov
This patch adds a new common OF dma xlate callback function which will match a
channel by it's id. The binding expects one integer argument which it will use 
to
lookup the channel by the id.

Unlike of_dma_simple_xlate this function is able to handle a system with
multiple DMA controllers. When registering the of dma provider with
of_dma_controller_register a pointer to the dma_device struct which is
associated with the dt node needs to passed as the data parameter.
New function will use this pointer to match only channels which belong to the
specified DMA controller.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/of-dma.c   | 35 +++
 include/linux/of_dma.h |  4 
 2 files changed, 39 insertions(+)

diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index e8fe9dc..d5fbeaa 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -218,3 +218,38 @@ struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_spec,
dma_spec-args[0]);
 }
 EXPORT_SYMBOL_GPL(of_dma_simple_xlate);
+
+/**
+ * of_dma_xlate_by_chan_id - Translate dt property to DMA channel by channel id
+ * @dma_spec:  pointer to DMA specifier as found in the device tree
+ * @of_dma:pointer to DMA controller data
+ *
+ * This function can be used as the of xlate callback for DMA driver which 
wants
+ * to match the channel based on the channel id. When using this xlate function
+ * the #dma-cells propety of the DMA controller dt node needs to be set to 1.
+ * The data parameter of of_dma_controller_register must be a pointer to the
+ * dma_device struct the function should match upon.
+ *
+ * Returns pointer to appropriate dma channel on success or NULL on error.
+ */
+struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
+struct of_dma *ofdma)
+{
+   struct dma_device *dev = ofdma-of_dma_data;
+   struct dma_chan *chan, *candidate = NULL;
+
+   if (!dev || dma_spec-args_count != 1)
+   return NULL;
+
+   list_for_each_entry(chan, dev-channels, device_node)
+   if (chan-chan_id == dma_spec-args[0]) {
+   candidate = chan;
+   break;
+   }
+
+   if (!candidate)
+   return NULL;
+
+   return dma_get_slave_channel(candidate);
+}
+EXPORT_SYMBOL_GPL(of_dma_xlate_by_chan_id);
diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
index ae36298..56bc026 100644
--- a/include/linux/of_dma.h
+++ b/include/linux/of_dma.h
@@ -41,6 +41,8 @@ extern struct dma_chan *of_dma_request_slave_channel(struct 
device_node *np,
 const char *name);
 extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma);
+extern struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args 
*dma_spec,
+   struct of_dma *ofdma);
 #else
 static inline int of_dma_controller_register(struct device_node *np,
struct dma_chan *(*of_dma_xlate)
@@ -66,6 +68,8 @@ static inline struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_s
return NULL;
 }
 
+#define of_dma_xlate_by_chan_id NULL
+
 #endif
 
 #endif /* __LINUX_OF_DMA_H */
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 1/3] dmaengine: mpc512x: add device tree binding document

2014-05-24 Thread Alexander Popov
Introduce a device tree binding document for the MPC512x DMA controller

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 .../devicetree/bindings/dma/mpc512x-dma.txt| 40 ++
 1 file changed, 40 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

diff --git a/Documentation/devicetree/bindings/dma/mpc512x-dma.txt 
b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
new file mode 100644
index 000..b1cbc3f
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
@@ -0,0 +1,40 @@
+* Freescale MPC512x and MPC8308 DMA Controller
+
+The DMA controller in Freescale MPC512x and MPC8308 SoCs can move
+blocks of memory contents between memory and peripherals or
+from memory to memory.
+
+Refer to Generic DMA Controller and DMA request bindings in
+the dma/dma.txt file for a more detailed description of binding.
+
+Required properties:
+- compatible: Should be fsl,mpc5121-dma or fsl,mpc8308-dma
+- reg: Address and size of the DMA controller's register set
+- Interrupt for the DMA controller. Syntax of interrupt client node
+   is described in interrupt-controller/interrupts.txt
+
+Optional properties:
+- #dma-cells: The length of the DMA specifier, must be 1.
+   Each channel of this DMA controller has a peripheral request line,
+   this assignment is fixed in hardware. The cell in dmas property
+   of a client device represents the channel number
+
+Example:
+
+   dma0: dma@14000 {
+   compatible = fsl,mpc5121-dma;
+   reg = 0x14000 0x1800;
+   interrupts = 65 0x8;
+   #dma-cells = 1;
+   };
+
+DMA clients must use the format described in dma/dma.txt
+
+Example:
+
+   sdhc@1500 {
+   compatible = fsl,mpc5121-sdhc;
+   /* ... */
+   dmas = dma0 30;
+   dma-names = rx-tx;
+   };
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 3/3] dmaengine: mpc512x: register for device tree channel lookup

2014-05-24 Thread Alexander Popov
Register the controller for device tree based lookup of DMA channels
(non-fatal for backwards compatibility with older device trees) and
provide the '#dma-cells' property in the shared mpc5121.dtsi file

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 arch/powerpc/boot/dts/mpc5121.dtsi |  1 +
 drivers/dma/mpc512x_dma.c  | 13 -
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi 
b/arch/powerpc/boot/dts/mpc5121.dtsi
index 2c0e155..7f9d14f 100644
--- a/arch/powerpc/boot/dts/mpc5121.dtsi
+++ b/arch/powerpc/boot/dts/mpc5121.dtsi
@@ -498,6 +498,7 @@
compatible = fsl,mpc5121-dma;
reg = 0x14000 0x1800;
interrupts = 65 0x8;
+   #dma-cells = 1;
};
};
 
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 2ad4373..881db2b 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -53,6 +53,7 @@
 #include linux/of_address.h
 #include linux/of_device.h
 #include linux/of_irq.h
+#include linux/of_dma.h
 #include linux/of_platform.h
 
 #include linux/random.h
@@ -1036,7 +1037,15 @@ static int mpc_dma_probe(struct platform_device *op)
if (retval)
goto err_free2;
 
-   return retval;
+   /* Register with OF helpers for DMA lookups (nonfatal) */
+   if (dev-of_node) {
+   retval = of_dma_controller_register(dev-of_node,
+   of_dma_xlate_by_chan_id, mdma);
+   if (retval)
+   dev_warn(dev, Could not register for OF lookup\n);
+   }
+
+   return 0;
 
 err_free2:
if (mdma-is_mpc8308)
@@ -1057,6 +1066,8 @@ static int mpc_dma_remove(struct platform_device *op)
struct device *dev = op-dev;
struct mpc_dma *mdma = dev_get_drvdata(dev);
 
+   if (dev-of_node)
+   of_dma_controller_free(dev-of_node);
dma_async_device_unregister(mdma-dma);
if (mdma-is_mpc8308) {
free_irq(mdma-irq2, mdma);
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v13 0/5] MPC512x DMA slave s/g support, OF DMA lookup

2014-05-15 Thread Alexander Popov
2013/7/14 Gerhard Sittig g...@denx.de:
 this series
 - introduces slave s/g support (that's support for DMA transfers which
involve peripherals in contrast to mem-to-mem transfers)
 - adds device tree based lookup support for DMA channels
 - combines floating patches and related feedback which already covered
several aspects of what the suggested LPB driver needs, to demonstrate
how integration might be done

...

Changes in v12:
 A new patch (part 2/7) is added to this series.
 Part 6/7:
 - change the description of 'compatible' property according part 2/7;
 - improve the document according Gerhard's feedback;

Parts 1/7, 2/7 and 4/7 have been applied by Vinod Koul and
are excluded from v13.

Changes in v13:
 A new patch (part 1/5) is added to this series.
 Part 2/5:
 - fix style issue;
 - improve comments;

 known issues:
 - it's yet to get confirmed whether MPC8308 can use slave support or
whether the DMA controller's driver shall actively reject it, the
information that's available so far suggests that peripheral transfers
to IP bus attached I/O is useful and shall not get blocked right away


Alexander Popov (5):
  dmaengine: fix comment typo
  dma: mpc512x: add support for peripheral transfers
  dma: of: add common xlate function for matching by channel id
  dma: mpc512x: add device tree binding document
  dma: mpc512x: register for device tree channel lookup

 .../devicetree/bindings/dma/mpc512x-dma.txt|  40 
 arch/powerpc/boot/dts/mpc5121.dtsi |   1 +
 drivers/dma/mpc512x_dma.c  | 257 -
 drivers/dma/of-dma.c   |  35 +++
 include/linux/dmaengine.h  |   2 +-
 include/linux/of_dma.h |   4 +
 6 files changed, 332 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v13 1/5] dmaengine: fix comment typo

2014-05-15 Thread Alexander Popov
Fix comment typo.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 include/linux/dmaengine.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 8300fb8..cbb168e 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -292,7 +292,7 @@ struct dma_chan_dev {
 };
 
 /**
- * enum dma_slave_buswidth - defines bus with of the DMA slave
+ * enum dma_slave_buswidth - defines bus width of the DMA slave
  * device, source or target buses
  */
 enum dma_slave_buswidth {
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v13 2/5] dma: mpc512x: add support for peripheral transfers

2014-05-15 Thread Alexander Popov
Introduce support for slave s/g transfer preparation and the associated
device control callback in the MPC512x DMA controller driver, which adds
support for data transfers between memory and peripheral I/O to the
previously supported mem-to-mem transfers.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/mpc512x_dma.c | 244 +-
 1 file changed, 239 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 96104f4..2ad4373 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -2,6 +2,7 @@
  * Copyright (C) Freescale Semicondutor, Inc. 2007, 2008.
  * Copyright (C) Semihalf 2009
  * Copyright (C) Ilya Yanok, Emcraft Systems 2010
+ * Copyright (C) Alexander Popov, Promcontroller 2014
  *
  * Written by Piotr Ziecik ko...@semihalf.com. Hardware description
  * (defines, structures and comments) was taken from MPC5121 DMA driver
@@ -29,8 +30,18 @@
  */
 
 /*
- * This is initial version of MPC5121 DMA driver. Only memory to memory
- * transfers are supported (tested using dmatest module).
+ * MPC512x and MPC8308 DMA driver. It supports
+ * memory to memory data transfers (tested using dmatest module) and
+ * data transfers between memory and peripheral I/O memory
+ * by means of slave scatter/gather with these limitations:
+ *  - chunked transfers (described by s/g lists with more than one item)
+ * are refused as long as proper support for scatter/gather is missing;
+ *  - transfers on MPC8308 always start from software as this SoC appears
+ * not to have external request lines for peripheral flow control;
+ *  - only peripheral devices with 4-byte FIFO access register are supported;
+ *  - minimal memory - I/O memory transfer chunk is 4 bytes and consequently
+ * source and destination addresses must be 4-byte aligned
+ * and transfer size must be aligned on (4 * maxburst) boundary;
  */
 
 #include linux/module.h
@@ -189,6 +200,7 @@ struct mpc_dma_desc {
dma_addr_t  tcd_paddr;
int error;
struct list_headnode;
+   int will_access_peripheral;
 };
 
 struct mpc_dma_chan {
@@ -201,6 +213,12 @@ struct mpc_dma_chan {
struct mpc_dma_tcd  *tcd;
dma_addr_t  tcd_paddr;
 
+   /* Settings for access to peripheral FIFO */
+   dma_addr_t  src_per_paddr;
+   u32 src_tcd_nunits;
+   dma_addr_t  dst_per_paddr;
+   u32 dst_tcd_nunits;
+
/* Lock for this structure */
spinlock_t  lock;
 };
@@ -251,8 +269,23 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)
struct mpc_dma_desc *mdesc;
int cid = mchan-chan.chan_id;
 
-   /* Move all queued descriptors to active list */
-   list_splice_tail_init(mchan-queued, mchan-active);
+   while (!list_empty(mchan-queued)) {
+   mdesc = list_first_entry(mchan-queued,
+   struct mpc_dma_desc, node);
+   /*
+* Grab either several mem-to-mem transfer descriptors
+* or one peripheral transfer descriptor,
+* don't mix mem-to-mem and peripheral transfer descriptors
+* within the same 'active' list.
+*/
+   if (mdesc-will_access_peripheral) {
+   if (list_empty(mchan-active))
+   list_move_tail(mdesc-node, mchan-active);
+   break;
+   } else {
+   list_move_tail(mdesc-node, mchan-active);
+   }
+   }
 
/* Chain descriptors into one transaction */
list_for_each_entry(mdesc, mchan-active, node) {
@@ -278,7 +311,17 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)
 
if (first != prev)
mdma-tcd[cid].e_sg = 1;
-   out_8(mdma-regs-dmassrt, cid);
+
+   if (mdma-is_mpc8308) {
+   /* MPC8308, no request lines, software initiated start */
+   out_8(mdma-regs-dmassrt, cid);
+   } else if (first-will_access_peripheral) {
+   /* Peripherals involved, start by external request signal */
+   out_8(mdma-regs-dmaserq, cid);
+   } else {
+   /* Memory to memory transfer, software initiated start */
+   out_8(mdma-regs-dmassrt, cid);
+   }
 }
 
 /* Handle interrupt on one half of DMA controller (32 channels) */
@@ -596,6 +639,7 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, 
dma_addr_t src,
}
 
mdesc-error = 0;
+   mdesc-will_access_peripheral = 0;
tcd = mdesc-tcd;
 
/* Prepare Transfer Control Descriptor for this transaction */
@@ -643,6 +687,193

[PATCH RFC v13 3/5] dma: of: add common xlate function for matching by channel id

2014-05-15 Thread Alexander Popov
This patch adds a new common OF dma xlate callback function which will match a
channel by it's id. The binding expects one integer argument which it will use 
to
lookup the channel by the id.

Unlike of_dma_simple_xlate this function is able to handle a system with
multiple DMA controllers. When registering the of dma provider with
of_dma_controller_register a pointer to the dma_device struct which is
associated with the dt node needs to passed as the data parameter.
New function will use this pointer to match only channels which belong to the
specified DMA controller.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/of-dma.c   | 35 +++
 include/linux/of_dma.h |  4 
 2 files changed, 39 insertions(+)

diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index e8fe9dc..d5fbeaa 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -218,3 +218,38 @@ struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_spec,
dma_spec-args[0]);
 }
 EXPORT_SYMBOL_GPL(of_dma_simple_xlate);
+
+/**
+ * of_dma_xlate_by_chan_id - Translate dt property to DMA channel by channel id
+ * @dma_spec:  pointer to DMA specifier as found in the device tree
+ * @of_dma:pointer to DMA controller data
+ *
+ * This function can be used as the of xlate callback for DMA driver which 
wants
+ * to match the channel based on the channel id. When using this xlate function
+ * the #dma-cells propety of the DMA controller dt node needs to be set to 1.
+ * The data parameter of of_dma_controller_register must be a pointer to the
+ * dma_device struct the function should match upon.
+ *
+ * Returns pointer to appropriate dma channel on success or NULL on error.
+ */
+struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
+struct of_dma *ofdma)
+{
+   struct dma_device *dev = ofdma-of_dma_data;
+   struct dma_chan *chan, *candidate = NULL;
+
+   if (!dev || dma_spec-args_count != 1)
+   return NULL;
+
+   list_for_each_entry(chan, dev-channels, device_node)
+   if (chan-chan_id == dma_spec-args[0]) {
+   candidate = chan;
+   break;
+   }
+
+   if (!candidate)
+   return NULL;
+
+   return dma_get_slave_channel(candidate);
+}
+EXPORT_SYMBOL_GPL(of_dma_xlate_by_chan_id);
diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
index ae36298..56bc026 100644
--- a/include/linux/of_dma.h
+++ b/include/linux/of_dma.h
@@ -41,6 +41,8 @@ extern struct dma_chan *of_dma_request_slave_channel(struct 
device_node *np,
 const char *name);
 extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma);
+extern struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args 
*dma_spec,
+   struct of_dma *ofdma);
 #else
 static inline int of_dma_controller_register(struct device_node *np,
struct dma_chan *(*of_dma_xlate)
@@ -66,6 +68,8 @@ static inline struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_s
return NULL;
 }
 
+#define of_dma_xlate_by_chan_id NULL
+
 #endif
 
 #endif /* __LINUX_OF_DMA_H */
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v13 4/5] dma: mpc512x: add device tree binding document

2014-05-15 Thread Alexander Popov
Introduce a device tree binding document for the MPC512x DMA controller

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 .../devicetree/bindings/dma/mpc512x-dma.txt| 40 ++
 1 file changed, 40 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

diff --git a/Documentation/devicetree/bindings/dma/mpc512x-dma.txt 
b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
new file mode 100644
index 000..b1cbc3f
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
@@ -0,0 +1,40 @@
+* Freescale MPC512x and MPC8308 DMA Controller
+
+The DMA controller in Freescale MPC512x and MPC8308 SoCs can move
+blocks of memory contents between memory and peripherals or
+from memory to memory.
+
+Refer to Generic DMA Controller and DMA request bindings in
+the dma/dma.txt file for a more detailed description of binding.
+
+Required properties:
+- compatible: Should be fsl,mpc5121-dma or fsl,mpc8308-dma
+- reg: Address and size of the DMA controller's register set
+- Interrupt for the DMA controller. Syntax of interrupt client node
+   is described in interrupt-controller/interrupts.txt
+
+Optional properties:
+- #dma-cells: The length of the DMA specifier, must be 1.
+   Each channel of this DMA controller has a peripheral request line,
+   this assignment is fixed in hardware. The cell in dmas property
+   of a client device represents the channel number
+
+Example:
+
+   dma0: dma@14000 {
+   compatible = fsl,mpc5121-dma;
+   reg = 0x14000 0x1800;
+   interrupts = 65 0x8;
+   #dma-cells = 1;
+   };
+
+DMA clients must use the format described in dma/dma.txt
+
+Example:
+
+   sdhc@1500 {
+   compatible = fsl,mpc5121-sdhc;
+   /* ... */
+   dmas = dma0 30;
+   dma-names = rx-tx;
+   };
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v13 5/5] dma: mpc512x: register for device tree channel lookup

2014-05-15 Thread Alexander Popov
Register the controller for device tree based lookup of DMA channels
(non-fatal for backwards compatibility with older device trees) and
provide the '#dma-cells' property in the shared mpc5121.dtsi file

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 arch/powerpc/boot/dts/mpc5121.dtsi |  1 +
 drivers/dma/mpc512x_dma.c  | 13 -
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi 
b/arch/powerpc/boot/dts/mpc5121.dtsi
index 2c0e155..7f9d14f 100644
--- a/arch/powerpc/boot/dts/mpc5121.dtsi
+++ b/arch/powerpc/boot/dts/mpc5121.dtsi
@@ -498,6 +498,7 @@
compatible = fsl,mpc5121-dma;
reg = 0x14000 0x1800;
interrupts = 65 0x8;
+   #dma-cells = 1;
};
};
 
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 2ad4373..881db2b 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -53,6 +53,7 @@
 #include linux/of_address.h
 #include linux/of_device.h
 #include linux/of_irq.h
+#include linux/of_dma.h
 #include linux/of_platform.h
 
 #include linux/random.h
@@ -1036,7 +1037,15 @@ static int mpc_dma_probe(struct platform_device *op)
if (retval)
goto err_free2;
 
-   return retval;
+   /* Register with OF helpers for DMA lookups (nonfatal) */
+   if (dev-of_node) {
+   retval = of_dma_controller_register(dev-of_node,
+   of_dma_xlate_by_chan_id, mdma);
+   if (retval)
+   dev_warn(dev, Could not register for OF lookup\n);
+   }
+
+   return 0;
 
 err_free2:
if (mdma-is_mpc8308)
@@ -1057,6 +1066,8 @@ static int mpc_dma_remove(struct platform_device *op)
struct device *dev = op-dev;
struct mpc_dma *mdma = dev_get_drvdata(dev);
 
+   if (dev-of_node)
+   of_dma_controller_free(dev-of_node);
dma_async_device_unregister(mdma-dma);
if (mdma-is_mpc8308) {
free_irq(mdma-irq2, mdma);
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH RFC v12 3/7] dma: mpc512x: add support for peripheral transfers

2014-05-08 Thread Alexander Popov
Hello, Vinod.
Thanks for your feedback.

2014-05-02 21:03 GMT+04:00 Vinod Koul vinod.k...@intel.com:
 On Wed, Apr 23, 2014 at 05:53:25PM +0400, Alexander Popov wrote:
 +static struct dma_async_tx_descriptor *
 +mpc_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 + unsigned int sg_len, enum dma_transfer_direction direction,
 + unsigned long flags, void *context)
 +{
 + struct mpc_dma *mdma = dma_chan_to_mpc_dma(chan);
 + struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan);
 + struct mpc_dma_desc *mdesc = NULL;
 + dma_addr_t per_paddr;
 + u32 tcd_nunits;
 + struct mpc_dma_tcd *tcd;
 + unsigned long iflags;
 + struct scatterlist *sg;
 + size_t len;
 + int iter, i;
 +
 + /* Currently there is no proper support for scatter/gather */
 Why? Is this HW or SW limitation?
This is the software limitation.

As Gerhard noticed, unfortunately the Linux DMA API combines
peripheral access with scatter/gather function.

But the original MPC512x DMA driver already uses scatter/gather feature
of the hardware for chaining together individual mpc_dma_desc's
in mpc_dma_execute() while mpc_dma_desc itself cannot use
scatter/gather feature, because each mpc_dma_desc is associated
with exactly one mpc_dma_tcd.

 + if (direction == DMA_DEV_TO_MEM) {
 + tcd-saddr = per_paddr;
 + tcd-daddr = sg_dma_address(sg);
 + tcd-soff = 0;
 + tcd-doff = 4;
 what are these?
SOFF is source address signed offset. It is applied to the current
source address to form the next-state value as each source read is completed.
DOFF is destination address signed offset.

 + case DMA_TERMINATE_ALL:
 + /* Disable channel requests */
 + mdma = dma_chan_to_mpc_dma(chan);
 +
 + spin_lock_irqsave(mchan-lock, flags);
 +
 + out_8(mdma-regs-dmacerq, chan-chan_id);
 + list_splice_tail_init(mchan-prepared, mchan-free);
 + list_splice_tail_init(mchan-queued, mchan-free);
 + list_splice_tail_init(mchan-active, mchan-free);
 +
 + spin_unlock_irqrestore(mchan-lock, flags);
 +
 + return 0;
 empty line after this pls
ok

 + case DMA_SLAVE_CONFIG:
 + /*
 +  * Constraints:
 +  *  - only transfers between a peripheral device and
 +  * memory are supported;
 +  *  - minimal transfer chunk is 4 bytes and consequently
 +  * source and destination addresses must be 4-byte aligned
 +  * and transfer size must be aligned on (4 * maxburst)
 +  * boundary;
 +  *  - during the transfer RAM address is being incremented by
 +  * the size of minimal transfer chunk;
 +  *  - peripheral port's address is constant during the 
 transfer.
 +  */
 +
 + cfg = (void *)arg;
 +
 + if (cfg-src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES ||
 + cfg-dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES ||
 and why this limtation, doesnt seem covered above?
I created this limitation because FIFO registers of LPC and SDHC
support _only_ 4-byte access.

I tried to cover this limitation in the statement minimal transfer chunk
is 4 bytes. Should I make it more explicit?

 + !IS_ALIGNED(cfg-src_addr, 4) ||
 + !IS_ALIGNED(cfg-dst_addr, 4)) {
 + return -EINVAL;
 + }
 +
 + spin_lock_irqsave(mchan-lock, flags);
 +
 + mchan-src_per_paddr = cfg-src_addr;
 + mchan-src_tcd_nunits = cfg-src_maxburst;
 + mchan-dst_per_paddr = cfg-dst_addr;
 + mchan-dst_tcd_nunits = cfg-dst_maxburst;
 +
 + /* Apply defaults */
 + if (mchan-src_tcd_nunits == 0)
 + mchan-src_tcd_nunits = 1;
 + if (mchan-dst_tcd_nunits == 0)
 + mchan-dst_tcd_nunits = 1;
 +
 + spin_unlock_irqrestore(mchan-lock, flags);
 +
 + return 0;
 empty line here too
ok

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH RFC v12 0/7] MPC512x DMA slave s/g support, OF DMA lookup

2014-04-29 Thread Alexander Popov
Hello

2014-04-23 17:53 GMT+04:00 Alexander Popov a13xp0p0...@gmail.com:
 Changes in v12:
  A new patch (part 2/7) is added to this series.
  Part 6/7:
  - change the description of 'compatible' property according part 2/7;
  - improve the document according Gerhard's feedback;

Could I have a feedback? Is the binding document fine now?
Thanks!

 Alexander Popov (7):
   dma: mpc512x: reorder mpc8308 specific instructions
   dma: mpc512x: separate 'compatible' values for MPC512x and MPC8308
   dma: mpc512x: add support for peripheral transfers
   dma: mpc512x: fix freeing resources in mpc_dma_probe() and
 mpc_dma_remove()
   dma: of: add common xlate function for matching by channel id
   dma: mpc512x: add device tree binding document
   dma: mpc512x: register for device tree channel lookup

  .../devicetree/bindings/dma/mpc512x-dma.txt|  40 +++
  arch/powerpc/boot/dts/mpc5121.dtsi |   1 +
  arch/powerpc/boot/dts/mpc8308_p1m.dts  |   2 +-
  arch/powerpc/boot/dts/mpc8308rdb.dts   |   2 +-
  drivers/dma/mpc512x_dma.c  | 346 
 ++---
  drivers/dma/of-dma.c   |  35 +++
  include/linux/of_dma.h |   4 +
  7 files changed, 390 insertions(+), 40 deletions(-)
  create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

 --
 1.8.4.2


Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v12 1/7] dma: mpc512x: reorder mpc8308 specific instructions

2014-04-23 Thread Alexander Popov
Concentrate the specific code for MPC8308 in the 'if' branch
and handle MPC512x in the 'else' branch.
This modification only reorders instructions but doesn't change behaviour.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
Acked-by: Anatolij Gustschin ag...@denx.de
---
 drivers/dma/mpc512x_dma.c | 42 +-
 1 file changed, 25 insertions(+), 17 deletions(-)

diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 448750d..2ce248b 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -52,9 +52,17 @@
 #define MPC_DMA_DESCRIPTORS64
 
 /* Macro definitions */
-#define MPC_DMA_CHANNELS   64
 #define MPC_DMA_TCD_OFFSET 0x1000
 
+/*
+ * Maximum channel counts for individual hardware variants
+ * and the maximum channel count over all supported controllers,
+ * used for data structure size
+ */
+#define MPC8308_DMACHAN_MAX16
+#define MPC512x_DMACHAN_MAX64
+#define MPC_DMA_CHANNELS   64
+
 /* Arbitration mode of group and channel */
 #define MPC_DMA_DMACR_EDCG (1  31)
 #define MPC_DMA_DMACR_ERGA (1  3)
@@ -710,10 +718,10 @@ static int mpc_dma_probe(struct platform_device *op)
 
dma = mdma-dma;
dma-dev = dev;
-   if (!mdma-is_mpc8308)
-   dma-chancnt = MPC_DMA_CHANNELS;
+   if (mdma-is_mpc8308)
+   dma-chancnt = MPC8308_DMACHAN_MAX;
else
-   dma-chancnt = 16; /* MPC8308 DMA has only 16 channels */
+   dma-chancnt = MPC512x_DMACHAN_MAX;
dma-device_alloc_chan_resources = mpc_dma_alloc_chan_resources;
dma-device_free_chan_resources = mpc_dma_free_chan_resources;
dma-device_issue_pending = mpc_dma_issue_pending;
@@ -747,7 +755,19 @@ static int mpc_dma_probe(struct platform_device *op)
 * - Round-robin group arbitration,
 * - Round-robin channel arbitration.
 */
-   if (!mdma-is_mpc8308) {
+   if (mdma-is_mpc8308) {
+   /* MPC8308 has 16 channels and lacks some registers */
+   out_be32(mdma-regs-dmacr, MPC_DMA_DMACR_ERCA);
+
+   /* enable snooping */
+   out_be32(mdma-regs-dmagpor, MPC_DMA_DMAGPOR_SNOOP_ENABLE);
+   /* Disable error interrupts */
+   out_be32(mdma-regs-dmaeeil, 0);
+
+   /* Clear interrupts status */
+   out_be32(mdma-regs-dmaintl, 0x);
+   out_be32(mdma-regs-dmaerrl, 0x);
+   } else {
out_be32(mdma-regs-dmacr, MPC_DMA_DMACR_EDCG |
MPC_DMA_DMACR_ERGA | 
MPC_DMA_DMACR_ERCA);
 
@@ -768,18 +788,6 @@ static int mpc_dma_probe(struct platform_device *op)
/* Route interrupts to IPIC */
out_be32(mdma-regs-dmaihsa, 0);
out_be32(mdma-regs-dmailsa, 0);
-   } else {
-   /* MPC8308 has 16 channels and lacks some registers */
-   out_be32(mdma-regs-dmacr, MPC_DMA_DMACR_ERCA);
-
-   /* enable snooping */
-   out_be32(mdma-regs-dmagpor, MPC_DMA_DMAGPOR_SNOOP_ENABLE);
-   /* Disable error interrupts */
-   out_be32(mdma-regs-dmaeeil, 0);
-
-   /* Clear interrupts status */
-   out_be32(mdma-regs-dmaintl, 0x);
-   out_be32(mdma-regs-dmaerrl, 0x);
}
 
/* Register DMA engine */
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v12 2/7] dma: mpc512x: separate 'compatible' values for MPC512x and MPC8308

2014-04-23 Thread Alexander Popov
MPC512x and MPC8308 have similar DMA controllers, but are independent SoCs.
DMA controller driver should have separate 'compatible' values for these SoCs.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 arch/powerpc/boot/dts/mpc8308_p1m.dts | 2 +-
 arch/powerpc/boot/dts/mpc8308rdb.dts  | 2 +-
 drivers/dma/mpc512x_dma.c | 1 +
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc8308_p1m.dts 
b/arch/powerpc/boot/dts/mpc8308_p1m.dts
index 651e4f5..57f86cd 100644
--- a/arch/powerpc/boot/dts/mpc8308_p1m.dts
+++ b/arch/powerpc/boot/dts/mpc8308_p1m.dts
@@ -296,7 +296,7 @@
};
 
dma@2c000 {
-   compatible = fsl,mpc8308-dma, fsl,mpc5121-dma;
+   compatible = fsl,mpc8308-dma;
reg = 0x2c000 0x1800;
interrupts = 3 0x8
94 0x8;
diff --git a/arch/powerpc/boot/dts/mpc8308rdb.dts 
b/arch/powerpc/boot/dts/mpc8308rdb.dts
index 9ce45f2..d0211f0 100644
--- a/arch/powerpc/boot/dts/mpc8308rdb.dts
+++ b/arch/powerpc/boot/dts/mpc8308rdb.dts
@@ -265,7 +265,7 @@
};
 
dma@2c000 {
-   compatible = fsl,mpc8308-dma, fsl,mpc5121-dma;
+   compatible = fsl,mpc8308-dma;
reg = 0x2c000 0x1800;
interrupts = 3 0x8
94 0x8;
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 2ce248b..0b17f4d 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -815,6 +815,7 @@ static int mpc_dma_remove(struct platform_device *op)
 
 static struct of_device_id mpc_dma_match[] = {
{ .compatible = fsl,mpc5121-dma, },
+   { .compatible = fsl,mpc8308-dma, },
{},
 };
 
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v12 3/7] dma: mpc512x: add support for peripheral transfers

2014-04-23 Thread Alexander Popov
Introduce support for slave s/g transfer preparation and the associated
device control callback in the MPC512x DMA controller driver, which adds
support for data transfers between memory and peripheral I/O to the
previously supported mem-to-mem transfers.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/mpc512x_dma.c | 239 +-
 1 file changed, 234 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 0b17f4d..ca2fe03 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -2,6 +2,7 @@
  * Copyright (C) Freescale Semicondutor, Inc. 2007, 2008.
  * Copyright (C) Semihalf 2009
  * Copyright (C) Ilya Yanok, Emcraft Systems 2010
+ * Copyright (C) Alexander Popov, Promcontroller 2014
  *
  * Written by Piotr Ziecik ko...@semihalf.com. Hardware description
  * (defines, structures and comments) was taken from MPC5121 DMA driver
@@ -29,8 +30,17 @@
  */
 
 /*
- * This is initial version of MPC5121 DMA driver. Only memory to memory
- * transfers are supported (tested using dmatest module).
+ * MPC512x and MPC8308 DMA driver. It supports
+ * memory to memory data transfers (tested using dmatest module) and
+ * data transfers between memory and peripheral I/O memory
+ * by means of slave s/g with these limitations:
+ *  - chunked transfers (transfers with more than one part) are refused
+ * as long as proper support for scatter/gather is missing;
+ *  - transfers on MPC8308 always start from software as this SoC appears
+ * not to have external request lines for peripheral flow control;
+ *  - minimal memory - I/O memory transfer chunk is 4 bytes and consequently
+ * source and destination addresses must be 4-byte aligned
+ * and transfer size must be aligned on (4 * maxburst) boundary;
  */
 
 #include linux/module.h
@@ -189,6 +199,7 @@ struct mpc_dma_desc {
dma_addr_t  tcd_paddr;
int error;
struct list_headnode;
+   int will_access_peripheral;
 };
 
 struct mpc_dma_chan {
@@ -201,6 +212,12 @@ struct mpc_dma_chan {
struct mpc_dma_tcd  *tcd;
dma_addr_t  tcd_paddr;
 
+   /* Settings for access to peripheral FIFO */
+   dma_addr_t  src_per_paddr;
+   u32 src_tcd_nunits;
+   dma_addr_t  dst_per_paddr;
+   u32 dst_tcd_nunits;
+
/* Lock for this structure */
spinlock_t  lock;
 };
@@ -251,8 +268,23 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)
struct mpc_dma_desc *mdesc;
int cid = mchan-chan.chan_id;
 
-   /* Move all queued descriptors to active list */
-   list_splice_tail_init(mchan-queued, mchan-active);
+   while (!list_empty(mchan-queued)) {
+   mdesc = list_first_entry(mchan-queued,
+   struct mpc_dma_desc, node);
+   /*
+* Grab either several mem-to-mem transfer descriptors
+* or one peripheral transfer descriptor,
+* don't mix mem-to-mem and peripheral transfer descriptors
+* within the same 'active' list.
+*/
+   if (mdesc-will_access_peripheral) {
+   if (list_empty(mchan-active))
+   list_move_tail(mdesc-node, mchan-active);
+   break;
+   } else {
+   list_move_tail(mdesc-node, mchan-active);
+   }
+   }
 
/* Chain descriptors into one transaction */
list_for_each_entry(mdesc, mchan-active, node) {
@@ -278,7 +310,17 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)
 
if (first != prev)
mdma-tcd[cid].e_sg = 1;
-   out_8(mdma-regs-dmassrt, cid);
+
+   if (mdma-is_mpc8308) {
+   /* MPC8308, no request lines, software initiated start */
+   out_8(mdma-regs-dmassrt, cid);
+   } else if (first-will_access_peripheral) {
+   /* Peripherals involved, start by external request signal */
+   out_8(mdma-regs-dmaserq, cid);
+   } else {
+   /* Memory to memory transfer, software initiated start */
+   out_8(mdma-regs-dmassrt, cid);
+   }
 }
 
 /* Handle interrupt on one half of DMA controller (32 channels) */
@@ -596,6 +638,7 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, 
dma_addr_t src,
}
 
mdesc-error = 0;
+   mdesc-will_access_peripheral = 0;
tcd = mdesc-tcd;
 
/* Prepare Transfer Control Descriptor for this transaction */
@@ -643,6 +686,189 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t 
dst, dma_addr_t src,
return mdesc-desc;
 }
 
+static

[PATCH RFC v12 4/7] dma: mpc512x: fix freeing resources in mpc_dma_probe() and mpc_dma_remove()

2014-04-23 Thread Alexander Popov
Fix mpc_dma_probe() error path and mpc_dma_remove(): manually free IRQs and
dispose IRQ mappings before devm_* takes care of other resources.
Moreover replace devm_request_irq() with request_irq() since there is no need
to use it because the original code always frees IRQ manually with
devm_free_irq(). Replace devm_free_irq() with free_irq() accordingly.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/mpc512x_dma.c | 55 ---
 1 file changed, 38 insertions(+), 17 deletions(-)

diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index ca2fe03..d2c5f79 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -883,13 +883,15 @@ static int mpc_dma_probe(struct platform_device *op)
mdma = devm_kzalloc(dev, sizeof(struct mpc_dma), GFP_KERNEL);
if (!mdma) {
dev_err(dev, Memory exhausted!\n);
-   return -ENOMEM;
+   retval = -ENOMEM;
+   goto err;
}
 
mdma-irq = irq_of_parse_and_map(dn, 0);
if (mdma-irq == NO_IRQ) {
dev_err(dev, Error mapping IRQ!\n);
-   return -EINVAL;
+   retval = -EINVAL;
+   goto err;
}
 
if (of_device_is_compatible(dn, fsl,mpc8308-dma)) {
@@ -897,14 +899,15 @@ static int mpc_dma_probe(struct platform_device *op)
mdma-irq2 = irq_of_parse_and_map(dn, 1);
if (mdma-irq2 == NO_IRQ) {
dev_err(dev, Error mapping IRQ!\n);
-   return -EINVAL;
+   retval = -EINVAL;
+   goto err_dispose1;
}
}
 
retval = of_address_to_resource(dn, 0, res);
if (retval) {
dev_err(dev, Error parsing memory region!\n);
-   return retval;
+   goto err_dispose2;
}
 
regs_start = res.start;
@@ -912,31 +915,34 @@ static int mpc_dma_probe(struct platform_device *op)
 
if (!devm_request_mem_region(dev, regs_start, regs_size, DRV_NAME)) {
dev_err(dev, Error requesting memory region!\n);
-   return -EBUSY;
+   retval = -EBUSY;
+   goto err_dispose2;
}
 
mdma-regs = devm_ioremap(dev, regs_start, regs_size);
if (!mdma-regs) {
dev_err(dev, Error mapping memory region!\n);
-   return -ENOMEM;
+   retval = -ENOMEM;
+   goto err_dispose2;
}
 
mdma-tcd = (struct mpc_dma_tcd *)((u8 *)(mdma-regs)
+ MPC_DMA_TCD_OFFSET);
 
-   retval = devm_request_irq(dev, mdma-irq, mpc_dma_irq, 0, DRV_NAME,
-   mdma);
+   retval = request_irq(mdma-irq, mpc_dma_irq, 0, DRV_NAME, mdma);
if (retval) {
dev_err(dev, Error requesting IRQ!\n);
-   return -EINVAL;
+   retval = -EINVAL;
+   goto err_dispose2;
}
 
if (mdma-is_mpc8308) {
-   retval = devm_request_irq(dev, mdma-irq2, mpc_dma_irq, 0,
-   DRV_NAME, mdma);
+   retval = request_irq(mdma-irq2, mpc_dma_irq, 0,
+   DRV_NAME, mdma);
if (retval) {
dev_err(dev, Error requesting IRQ2!\n);
-   return -EINVAL;
+   retval = -EINVAL;
+   goto err_free1;
}
}
 
@@ -1022,12 +1028,23 @@ static int mpc_dma_probe(struct platform_device *op)
/* Register DMA engine */
dev_set_drvdata(dev, mdma);
retval = dma_async_device_register(dma);
-   if (retval) {
-   devm_free_irq(dev, mdma-irq, mdma);
-   irq_dispose_mapping(mdma-irq);
-   }
+   if (retval)
+   goto err_free2;
 
return retval;
+
+err_free2:
+   if (mdma-is_mpc8308)
+   free_irq(mdma-irq2, mdma);
+err_free1:
+   free_irq(mdma-irq, mdma);
+err_dispose2:
+   if (mdma-is_mpc8308)
+   irq_dispose_mapping(mdma-irq2);
+err_dispose1:
+   irq_dispose_mapping(mdma-irq);
+err:
+   return retval;
 }
 
 static int mpc_dma_remove(struct platform_device *op)
@@ -1036,7 +1053,11 @@ static int mpc_dma_remove(struct platform_device *op)
struct mpc_dma *mdma = dev_get_drvdata(dev);
 
dma_async_device_unregister(mdma-dma);
-   devm_free_irq(dev, mdma-irq, mdma);
+   if (mdma-is_mpc8308) {
+   free_irq(mdma-irq2, mdma);
+   irq_dispose_mapping(mdma-irq2);
+   }
+   free_irq(mdma-irq, mdma);
irq_dispose_mapping(mdma-irq);
 
return 0;
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https

[PATCH RFC v12 5/7] dma: of: add common xlate function for matching by channel id

2014-04-23 Thread Alexander Popov
This patch adds a new common OF dma xlate callback function which will match a
channel by it's id. The binding expects one integer argument which it will use 
to
lookup the channel by the id.

Unlike of_dma_simple_xlate this function is able to handle a system with
multiple DMA controllers. When registering the of dma provider with
of_dma_controller_register a pointer to the dma_device struct which is
associated with the dt node needs to passed as the data parameter.
New function will use this pointer to match only channels which belong to the
specified DMA controller.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/of-dma.c   | 35 +++
 include/linux/of_dma.h |  4 
 2 files changed, 39 insertions(+)

diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index e8fe9dc..d5fbeaa 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -218,3 +218,38 @@ struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_spec,
dma_spec-args[0]);
 }
 EXPORT_SYMBOL_GPL(of_dma_simple_xlate);
+
+/**
+ * of_dma_xlate_by_chan_id - Translate dt property to DMA channel by channel id
+ * @dma_spec:  pointer to DMA specifier as found in the device tree
+ * @of_dma:pointer to DMA controller data
+ *
+ * This function can be used as the of xlate callback for DMA driver which 
wants
+ * to match the channel based on the channel id. When using this xlate function
+ * the #dma-cells propety of the DMA controller dt node needs to be set to 1.
+ * The data parameter of of_dma_controller_register must be a pointer to the
+ * dma_device struct the function should match upon.
+ *
+ * Returns pointer to appropriate dma channel on success or NULL on error.
+ */
+struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
+struct of_dma *ofdma)
+{
+   struct dma_device *dev = ofdma-of_dma_data;
+   struct dma_chan *chan, *candidate = NULL;
+
+   if (!dev || dma_spec-args_count != 1)
+   return NULL;
+
+   list_for_each_entry(chan, dev-channels, device_node)
+   if (chan-chan_id == dma_spec-args[0]) {
+   candidate = chan;
+   break;
+   }
+
+   if (!candidate)
+   return NULL;
+
+   return dma_get_slave_channel(candidate);
+}
+EXPORT_SYMBOL_GPL(of_dma_xlate_by_chan_id);
diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
index ae36298..56bc026 100644
--- a/include/linux/of_dma.h
+++ b/include/linux/of_dma.h
@@ -41,6 +41,8 @@ extern struct dma_chan *of_dma_request_slave_channel(struct 
device_node *np,
 const char *name);
 extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma);
+extern struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args 
*dma_spec,
+   struct of_dma *ofdma);
 #else
 static inline int of_dma_controller_register(struct device_node *np,
struct dma_chan *(*of_dma_xlate)
@@ -66,6 +68,8 @@ static inline struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_s
return NULL;
 }
 
+#define of_dma_xlate_by_chan_id NULL
+
 #endif
 
 #endif /* __LINUX_OF_DMA_H */
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v12 6/7] dma: mpc512x: add device tree binding document

2014-04-23 Thread Alexander Popov
Introduce a device tree binding document for the MPC512x DMA controller

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 .../devicetree/bindings/dma/mpc512x-dma.txt| 40 ++
 1 file changed, 40 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

diff --git a/Documentation/devicetree/bindings/dma/mpc512x-dma.txt 
b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
new file mode 100644
index 000..b1cbc3f
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
@@ -0,0 +1,40 @@
+* Freescale MPC512x and MPC8308 DMA Controller
+
+The DMA controller in Freescale MPC512x and MPC8308 SoCs can move
+blocks of memory contents between memory and peripherals or
+from memory to memory.
+
+Refer to Generic DMA Controller and DMA request bindings in
+the dma/dma.txt file for a more detailed description of binding.
+
+Required properties:
+- compatible: Should be fsl,mpc5121-dma or fsl,mpc8308-dma
+- reg: Address and size of the DMA controller's register set
+- Interrupt for the DMA controller. Syntax of interrupt client node
+   is described in interrupt-controller/interrupts.txt
+
+Optional properties:
+- #dma-cells: The length of the DMA specifier, must be 1.
+   Each channel of this DMA controller has a peripheral request line,
+   this assignment is fixed in hardware. The cell in dmas property
+   of a client device represents the channel number
+
+Example:
+
+   dma0: dma@14000 {
+   compatible = fsl,mpc5121-dma;
+   reg = 0x14000 0x1800;
+   interrupts = 65 0x8;
+   #dma-cells = 1;
+   };
+
+DMA clients must use the format described in dma/dma.txt
+
+Example:
+
+   sdhc@1500 {
+   compatible = fsl,mpc5121-sdhc;
+   /* ... */
+   dmas = dma0 30;
+   dma-names = rx-tx;
+   };
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v12 7/7] dma: mpc512x: register for device tree channel lookup

2014-04-23 Thread Alexander Popov
Register the controller for device tree based lookup of DMA channels
(non-fatal for backwards compatibility with older device trees) and
provide the '#dma-cells' property in the shared mpc5121.dtsi file

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 arch/powerpc/boot/dts/mpc5121.dtsi |  1 +
 drivers/dma/mpc512x_dma.c  | 13 -
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi 
b/arch/powerpc/boot/dts/mpc5121.dtsi
index 2c0e155..7f9d14f 100644
--- a/arch/powerpc/boot/dts/mpc5121.dtsi
+++ b/arch/powerpc/boot/dts/mpc5121.dtsi
@@ -498,6 +498,7 @@
compatible = fsl,mpc5121-dma;
reg = 0x14000 0x1800;
interrupts = 65 0x8;
+   #dma-cells = 1;
};
};
 
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index d2c5f79..fa0614e 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -52,6 +52,7 @@
 #include linux/of_address.h
 #include linux/of_device.h
 #include linux/of_irq.h
+#include linux/of_dma.h
 #include linux/of_platform.h
 
 #include linux/random.h
@@ -1031,7 +1032,15 @@ static int mpc_dma_probe(struct platform_device *op)
if (retval)
goto err_free2;
 
-   return retval;
+   /* Register with OF helpers for DMA lookups (nonfatal) */
+   if (dev-of_node) {
+   retval = of_dma_controller_register(dev-of_node,
+   of_dma_xlate_by_chan_id, mdma);
+   if (retval)
+   dev_warn(dev, Could not register for OF lookup\n);
+   }
+
+   return 0;
 
 err_free2:
if (mdma-is_mpc8308)
@@ -1052,6 +1061,8 @@ static int mpc_dma_remove(struct platform_device *op)
struct device *dev = op-dev;
struct mpc_dma *mdma = dev_get_drvdata(dev);
 
+   if (dev-of_node)
+   of_dma_controller_free(dev-of_node);
dma_async_device_unregister(mdma-dma);
if (mdma-is_mpc8308) {
free_irq(mdma-irq2, mdma);
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v12 0/7] MPC512x DMA slave s/g support, OF DMA lookup

2014-04-23 Thread Alexander Popov
/O is useful and shall not get blocked right away
 - adding support for transfers which don't increment the RAM address or
do increment the peripheral port's address is easy with
this implementation; but which options of the common API
should be used for specifying such transfers?


Alexander Popov (7):
  dma: mpc512x: reorder mpc8308 specific instructions
  dma: mpc512x: separate 'compatible' values for MPC512x and MPC8308
  dma: mpc512x: add support for peripheral transfers
  dma: mpc512x: fix freeing resources in mpc_dma_probe() and
mpc_dma_remove()
  dma: of: add common xlate function for matching by channel id
  dma: mpc512x: add device tree binding document
  dma: mpc512x: register for device tree channel lookup

 .../devicetree/bindings/dma/mpc512x-dma.txt|  40 +++
 arch/powerpc/boot/dts/mpc5121.dtsi |   1 +
 arch/powerpc/boot/dts/mpc8308_p1m.dts  |   2 +-
 arch/powerpc/boot/dts/mpc8308rdb.dts   |   2 +-
 drivers/dma/mpc512x_dma.c  | 346 ++---
 drivers/dma/of-dma.c   |  35 +++
 include/linux/of_dma.h |   4 +
 7 files changed, 390 insertions(+), 40 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH RFC v11 5/6] dma: mpc512x: add device tree binding document

2014-04-18 Thread Alexander Popov
Thanks for your reply, Gerhard

2014-04-17 0:44 GMT+04:00 Gerhard Sittig g...@denx.de:
 On Tue, 2014-04-15 at 14:54 +0400, Alexander Popov wrote:

 Introduce a device tree binding document for the MPC512x DMA controller

 Signed-off-by: Gerhard Sittig g...@denx.de
 Signed-off-by: Alexander Popov a13xp0p0...@gmail.com

 I'm not certain whether the attribution is right.  Is the S-o-b
 appropriate when the patch is not from me? As I've stated
 before, it's OK if you pick up and extend what I provide, but
 please don't pretend that I wrote what you did,
Thanks. I've read the corresponding part of
Documentation/SubmittingPatches once again and now I see
my mistake.

 and don't pretend
 that I ACKed or passed along your submission when I didn't.
I didn't have any malicious intent.

 This binding certainly needs further improvement to become a good
 one.  As I've communicated in the past, I was rather ignorant
 back then when I wrote v1 and v2 of the RFC.  We have learned
 something in the meantime.  Though I admit having gone silent
 after several review iterations.  Assumed you would pick up
 information that showed up several times on public lists.

 --- /dev/null
 +++ b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
 @@ -0,0 +1,51 @@
 +* Freescale MPC512x and MPC8308 DMA Controller
 +
 +The DMA controller in the Freescale MPC512x and MPC8308 SoCs can move
 +blocks of memory contents between memory and peripherals or
 +from memory to memory.
 +
 +Refer to the Generic DMA Controller and DMA request bindings in
 +the dma/dma.txt file for a more detailed description of binding.
 +
 +* DMA controller
 +
 +Required properties:
 +- compatible: Should be one of
 + fsl,mpc5121-dma
 + fsl,mpc8308-dma, fsl,mpc5121-dma

 is this a duplicate?  looks funny, needs a fix

 or is it a requirement that for MPC8308 you need to provide both
 compatible strings?  that would be wrong, as MPC8308 certainly is
 not an MPC5121

 a quick search reveals: the drivers/dma/mpc512x_dma.c Linux
 driver implementation is wrong, it should match on both strings;
 expecting the MPC8308 to disguise as an MPC5121 when it's not is
 inappropriate (and only went unnoticed because of missing
 bindings, I guess)
I can try to fix that and add a new patch to the series.

 +- reg: Address and size of the DMA controller's register set
 +- interrupts: Interrupt for the DMA controller. Generic interrupt client 
 node
 + is described in interrupt-controller/interrupts.txt

 'interrupts' only works in combinations with 'interrupt-parent',
 that actual .dts files don't have the latter in the nodes is an
 implementation detail but not a binding's requirement
Excuse me, I didn't understand your point.

 and an alternative method of specifying interrupts was introduced
 recently, a reference to the common binding without naming one
 specific property name could be most appropriate
Excuse me, I haven't found such an example.

 +
 +Optional properties:
 +- #dma-cells: The length of the DMA specifier, must be 1 since
 + the DMA controller uses a fixed assignment of request lines
 + per channel. Refer to dma/dma.txt for the detailed description
 + of this property

 I'm afraid that a generic/common document does not and cannot
 describe the specific semantics of this provider's cells
Ok, I see.

 this binding should explicitly mention that the number of cells
 needs to be one, and that this one cell is the DMA channel (which
 translates to peripheral request line), because these
 assigments are fixed in hardware
Ok.

 +
 +Example:
 +
 + dma0: dma@14000 {
 + compatible = fsl,mpc5121-dma;
 + reg = 0x14000 0x1800;
 + interrupts = 65 0x8;
 + #dma-cells = 1;
 + };
 +
 +* DMA client

 the DMA provider's binding probably need not discuss client
 specs, a reference to the common binding should suffice if it's
 appropriate at all
Ok.

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v11 0/6] MPC512x DMA slave s/g support, OF DMA lookup

2014-04-15 Thread Alexander Popov
 with
this implementation; but which options of the common API
should be used for specifying such transfers?


Alexander Popov (6):
  dma: mpc512x: reorder mpc8308 specific instructions
  dma: mpc512x: add support for peripheral transfers
  dma: mpc512x: fix freeing resources in mpc_dma_probe() and
mpc_dma_remove()
  dma: of: Add common xlate function for matching by channel id
  dma: mpc512x: add device tree binding document
  dma: mpc512x: register for device tree channel lookup

 .../devicetree/bindings/dma/mpc512x-dma.txt|  51 +++
 arch/powerpc/boot/dts/mpc5121.dtsi |   1 +
 drivers/dma/mpc512x_dma.c  | 345 ++---
 drivers/dma/of-dma.c   |  35 +++
 include/linux/of_dma.h |   4 +
 5 files changed, 398 insertions(+), 38 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v11 2/6] dma: mpc512x: add support for peripheral transfers

2014-04-15 Thread Alexander Popov
Introduce support for slave s/g transfer preparation and the associated
device control callback in the MPC512x DMA controller driver, which adds
support for data transfers between memory and peripheral I/O to the
previously supported mem-to-mem transfers.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/mpc512x_dma.c | 239 +-
 1 file changed, 234 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 2ce248b..68231d9 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -2,6 +2,7 @@
  * Copyright (C) Freescale Semicondutor, Inc. 2007, 2008.
  * Copyright (C) Semihalf 2009
  * Copyright (C) Ilya Yanok, Emcraft Systems 2010
+ * Copyright (C) Alexander Popov, Promcontroller 2014
  *
  * Written by Piotr Ziecik ko...@semihalf.com. Hardware description
  * (defines, structures and comments) was taken from MPC5121 DMA driver
@@ -29,8 +30,17 @@
  */
 
 /*
- * This is initial version of MPC5121 DMA driver. Only memory to memory
- * transfers are supported (tested using dmatest module).
+ * MPC512x and MPC8308 DMA driver. It supports
+ * memory to memory data transfers (tested using dmatest module) and
+ * data transfers between memory and peripheral I/O memory
+ * by means of slave s/g with these limitations:
+ *  - chunked transfers (transfers with more than one part) are refused
+ * as long as proper support for scatter/gather is missing;
+ *  - transfers on MPC8308 always start from software as this SoC appears
+ * not to have external request lines for peripheral flow control;
+ *  - minimal memory - I/O memory transfer chunk is 4 bytes and consequently
+ * source and destination addresses must be 4-byte aligned
+ * and transfer size must be aligned on (4 * maxburst) boundary;
  */
 
 #include linux/module.h
@@ -189,6 +199,7 @@ struct mpc_dma_desc {
dma_addr_t  tcd_paddr;
int error;
struct list_headnode;
+   int will_access_peripheral;
 };
 
 struct mpc_dma_chan {
@@ -201,6 +212,12 @@ struct mpc_dma_chan {
struct mpc_dma_tcd  *tcd;
dma_addr_t  tcd_paddr;
 
+   /* Settings for access to peripheral FIFO */
+   dma_addr_t  src_per_paddr;
+   u32 src_tcd_nunits;
+   dma_addr_t  dst_per_paddr;
+   u32 dst_tcd_nunits;
+
/* Lock for this structure */
spinlock_t  lock;
 };
@@ -251,8 +268,23 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)
struct mpc_dma_desc *mdesc;
int cid = mchan-chan.chan_id;
 
-   /* Move all queued descriptors to active list */
-   list_splice_tail_init(mchan-queued, mchan-active);
+   while (!list_empty(mchan-queued)) {
+   mdesc = list_first_entry(mchan-queued,
+   struct mpc_dma_desc, node);
+   /*
+* Grab either several mem-to-mem transfer descriptors
+* or one peripheral transfer descriptor,
+* don't mix mem-to-mem and peripheral transfer descriptors
+* within the same 'active' list.
+*/
+   if (mdesc-will_access_peripheral) {
+   if (list_empty(mchan-active))
+   list_move_tail(mdesc-node, mchan-active);
+   break;
+   } else {
+   list_move_tail(mdesc-node, mchan-active);
+   }
+   }
 
/* Chain descriptors into one transaction */
list_for_each_entry(mdesc, mchan-active, node) {
@@ -278,7 +310,17 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)
 
if (first != prev)
mdma-tcd[cid].e_sg = 1;
-   out_8(mdma-regs-dmassrt, cid);
+
+   if (mdma-is_mpc8308) {
+   /* MPC8308, no request lines, software initiated start */
+   out_8(mdma-regs-dmassrt, cid);
+   } else if (first-will_access_peripheral) {
+   /* Peripherals involved, start by external request signal */
+   out_8(mdma-regs-dmaserq, cid);
+   } else {
+   /* Memory to memory transfer, software initiated start */
+   out_8(mdma-regs-dmassrt, cid);
+   }
 }
 
 /* Handle interrupt on one half of DMA controller (32 channels) */
@@ -596,6 +638,7 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, 
dma_addr_t src,
}
 
mdesc-error = 0;
+   mdesc-will_access_peripheral = 0;
tcd = mdesc-tcd;
 
/* Prepare Transfer Control Descriptor for this transaction */
@@ -643,6 +686,189 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t 
dst, dma_addr_t src,
return mdesc-desc;
 }
 
+static

[PATCH RFC v11 1/6] dma: mpc512x: reorder mpc8308 specific instructions

2014-04-15 Thread Alexander Popov
Concentrate the specific code for MPC8308 in the 'if' branch
and handle MPC512x in the 'else' branch.
This modification only reorders instructions but doesn't change behaviour.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
Acked-by: Anatolij Gustschin ag...@denx.de
Acked-by: Gerhard Sittig g...@denx.de
---
 drivers/dma/mpc512x_dma.c | 42 +-
 1 file changed, 25 insertions(+), 17 deletions(-)

diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 448750d..2ce248b 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -52,9 +52,17 @@
 #define MPC_DMA_DESCRIPTORS64
 
 /* Macro definitions */
-#define MPC_DMA_CHANNELS   64
 #define MPC_DMA_TCD_OFFSET 0x1000
 
+/*
+ * Maximum channel counts for individual hardware variants
+ * and the maximum channel count over all supported controllers,
+ * used for data structure size
+ */
+#define MPC8308_DMACHAN_MAX16
+#define MPC512x_DMACHAN_MAX64
+#define MPC_DMA_CHANNELS   64
+
 /* Arbitration mode of group and channel */
 #define MPC_DMA_DMACR_EDCG (1  31)
 #define MPC_DMA_DMACR_ERGA (1  3)
@@ -710,10 +718,10 @@ static int mpc_dma_probe(struct platform_device *op)
 
dma = mdma-dma;
dma-dev = dev;
-   if (!mdma-is_mpc8308)
-   dma-chancnt = MPC_DMA_CHANNELS;
+   if (mdma-is_mpc8308)
+   dma-chancnt = MPC8308_DMACHAN_MAX;
else
-   dma-chancnt = 16; /* MPC8308 DMA has only 16 channels */
+   dma-chancnt = MPC512x_DMACHAN_MAX;
dma-device_alloc_chan_resources = mpc_dma_alloc_chan_resources;
dma-device_free_chan_resources = mpc_dma_free_chan_resources;
dma-device_issue_pending = mpc_dma_issue_pending;
@@ -747,7 +755,19 @@ static int mpc_dma_probe(struct platform_device *op)
 * - Round-robin group arbitration,
 * - Round-robin channel arbitration.
 */
-   if (!mdma-is_mpc8308) {
+   if (mdma-is_mpc8308) {
+   /* MPC8308 has 16 channels and lacks some registers */
+   out_be32(mdma-regs-dmacr, MPC_DMA_DMACR_ERCA);
+
+   /* enable snooping */
+   out_be32(mdma-regs-dmagpor, MPC_DMA_DMAGPOR_SNOOP_ENABLE);
+   /* Disable error interrupts */
+   out_be32(mdma-regs-dmaeeil, 0);
+
+   /* Clear interrupts status */
+   out_be32(mdma-regs-dmaintl, 0x);
+   out_be32(mdma-regs-dmaerrl, 0x);
+   } else {
out_be32(mdma-regs-dmacr, MPC_DMA_DMACR_EDCG |
MPC_DMA_DMACR_ERGA | 
MPC_DMA_DMACR_ERCA);
 
@@ -768,18 +788,6 @@ static int mpc_dma_probe(struct platform_device *op)
/* Route interrupts to IPIC */
out_be32(mdma-regs-dmaihsa, 0);
out_be32(mdma-regs-dmailsa, 0);
-   } else {
-   /* MPC8308 has 16 channels and lacks some registers */
-   out_be32(mdma-regs-dmacr, MPC_DMA_DMACR_ERCA);
-
-   /* enable snooping */
-   out_be32(mdma-regs-dmagpor, MPC_DMA_DMAGPOR_SNOOP_ENABLE);
-   /* Disable error interrupts */
-   out_be32(mdma-regs-dmaeeil, 0);
-
-   /* Clear interrupts status */
-   out_be32(mdma-regs-dmaintl, 0x);
-   out_be32(mdma-regs-dmaerrl, 0x);
}
 
/* Register DMA engine */
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v11 3/6] dma: mpc512x: fix freeing resources in mpc_dma_probe() and mpc_dma_remove()

2014-04-15 Thread Alexander Popov
Fix mpc_dma_probe() error path and mpc_dma_remove(): manually free IRQs and
dispose IRQ mappings before devm_* takes care of other resources.
Moreover replace devm_request_irq() with request_irq() since there is no need
to use it because the original code always frees IRQ manually with
devm_free_irq(). Replace devm_free_irq() with free_irq() accordingly.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/mpc512x_dma.c | 55 ---
 1 file changed, 38 insertions(+), 17 deletions(-)

diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 68231d9..1b90b3b 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -883,13 +883,15 @@ static int mpc_dma_probe(struct platform_device *op)
mdma = devm_kzalloc(dev, sizeof(struct mpc_dma), GFP_KERNEL);
if (!mdma) {
dev_err(dev, Memory exhausted!\n);
-   return -ENOMEM;
+   retval = -ENOMEM;
+   goto err;
}
 
mdma-irq = irq_of_parse_and_map(dn, 0);
if (mdma-irq == NO_IRQ) {
dev_err(dev, Error mapping IRQ!\n);
-   return -EINVAL;
+   retval = -EINVAL;
+   goto err;
}
 
if (of_device_is_compatible(dn, fsl,mpc8308-dma)) {
@@ -897,14 +899,15 @@ static int mpc_dma_probe(struct platform_device *op)
mdma-irq2 = irq_of_parse_and_map(dn, 1);
if (mdma-irq2 == NO_IRQ) {
dev_err(dev, Error mapping IRQ!\n);
-   return -EINVAL;
+   retval = -EINVAL;
+   goto err_dispose1;
}
}
 
retval = of_address_to_resource(dn, 0, res);
if (retval) {
dev_err(dev, Error parsing memory region!\n);
-   return retval;
+   goto err_dispose2;
}
 
regs_start = res.start;
@@ -912,31 +915,34 @@ static int mpc_dma_probe(struct platform_device *op)
 
if (!devm_request_mem_region(dev, regs_start, regs_size, DRV_NAME)) {
dev_err(dev, Error requesting memory region!\n);
-   return -EBUSY;
+   retval = -EBUSY;
+   goto err_dispose2;
}
 
mdma-regs = devm_ioremap(dev, regs_start, regs_size);
if (!mdma-regs) {
dev_err(dev, Error mapping memory region!\n);
-   return -ENOMEM;
+   retval = -ENOMEM;
+   goto err_dispose2;
}
 
mdma-tcd = (struct mpc_dma_tcd *)((u8 *)(mdma-regs)
+ MPC_DMA_TCD_OFFSET);
 
-   retval = devm_request_irq(dev, mdma-irq, mpc_dma_irq, 0, DRV_NAME,
-   mdma);
+   retval = request_irq(mdma-irq, mpc_dma_irq, 0, DRV_NAME, mdma);
if (retval) {
dev_err(dev, Error requesting IRQ!\n);
-   return -EINVAL;
+   retval = -EINVAL;
+   goto err_dispose2;
}
 
if (mdma-is_mpc8308) {
-   retval = devm_request_irq(dev, mdma-irq2, mpc_dma_irq, 0,
-   DRV_NAME, mdma);
+   retval = request_irq(mdma-irq2, mpc_dma_irq, 0,
+   DRV_NAME, mdma);
if (retval) {
dev_err(dev, Error requesting IRQ2!\n);
-   return -EINVAL;
+   retval = -EINVAL;
+   goto err_free1;
}
}
 
@@ -1022,12 +1028,23 @@ static int mpc_dma_probe(struct platform_device *op)
/* Register DMA engine */
dev_set_drvdata(dev, mdma);
retval = dma_async_device_register(dma);
-   if (retval) {
-   devm_free_irq(dev, mdma-irq, mdma);
-   irq_dispose_mapping(mdma-irq);
-   }
+   if (retval)
+   goto err_free2;
 
return retval;
+
+err_free2:
+   if (mdma-is_mpc8308)
+   free_irq(mdma-irq2, mdma);
+err_free1:
+   free_irq(mdma-irq, mdma);
+err_dispose2:
+   if (mdma-is_mpc8308)
+   irq_dispose_mapping(mdma-irq2);
+err_dispose1:
+   irq_dispose_mapping(mdma-irq);
+err:
+   return retval;
 }
 
 static int mpc_dma_remove(struct platform_device *op)
@@ -1036,7 +1053,11 @@ static int mpc_dma_remove(struct platform_device *op)
struct mpc_dma *mdma = dev_get_drvdata(dev);
 
dma_async_device_unregister(mdma-dma);
-   devm_free_irq(dev, mdma-irq, mdma);
+   if (mdma-is_mpc8308) {
+   free_irq(mdma-irq2, mdma);
+   irq_dispose_mapping(mdma-irq2);
+   }
+   free_irq(mdma-irq, mdma);
irq_dispose_mapping(mdma-irq);
 
return 0;
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https

[PATCH RFC v11 4/6] dma: of: Add common xlate function for matching by channel id

2014-04-15 Thread Alexander Popov
This patch adds a new common OF dma xlate callback function which will match a
channel by it's id. The binding expects one integer argument which it will use 
to
lookup the channel by the id.

Unlike of_dma_simple_xlate this function is able to handle a system with
multiple DMA controllers. When registering the of dma provider with
of_dma_controller_register a pointer to the dma_device struct which is
associated with the dt node needs to passed as the data parameter.
New function will use this pointer to match only channels which belong to the
specified DMA controller.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/of-dma.c   | 35 +++
 include/linux/of_dma.h |  4 
 2 files changed, 39 insertions(+)

diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index e8fe9dc..d5fbeaa 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -218,3 +218,38 @@ struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_spec,
dma_spec-args[0]);
 }
 EXPORT_SYMBOL_GPL(of_dma_simple_xlate);
+
+/**
+ * of_dma_xlate_by_chan_id - Translate dt property to DMA channel by channel id
+ * @dma_spec:  pointer to DMA specifier as found in the device tree
+ * @of_dma:pointer to DMA controller data
+ *
+ * This function can be used as the of xlate callback for DMA driver which 
wants
+ * to match the channel based on the channel id. When using this xlate function
+ * the #dma-cells propety of the DMA controller dt node needs to be set to 1.
+ * The data parameter of of_dma_controller_register must be a pointer to the
+ * dma_device struct the function should match upon.
+ *
+ * Returns pointer to appropriate dma channel on success or NULL on error.
+ */
+struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
+struct of_dma *ofdma)
+{
+   struct dma_device *dev = ofdma-of_dma_data;
+   struct dma_chan *chan, *candidate = NULL;
+
+   if (!dev || dma_spec-args_count != 1)
+   return NULL;
+
+   list_for_each_entry(chan, dev-channels, device_node)
+   if (chan-chan_id == dma_spec-args[0]) {
+   candidate = chan;
+   break;
+   }
+
+   if (!candidate)
+   return NULL;
+
+   return dma_get_slave_channel(candidate);
+}
+EXPORT_SYMBOL_GPL(of_dma_xlate_by_chan_id);
diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
index ae36298..56bc026 100644
--- a/include/linux/of_dma.h
+++ b/include/linux/of_dma.h
@@ -41,6 +41,8 @@ extern struct dma_chan *of_dma_request_slave_channel(struct 
device_node *np,
 const char *name);
 extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma);
+extern struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args 
*dma_spec,
+   struct of_dma *ofdma);
 #else
 static inline int of_dma_controller_register(struct device_node *np,
struct dma_chan *(*of_dma_xlate)
@@ -66,6 +68,8 @@ static inline struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_s
return NULL;
 }
 
+#define of_dma_xlate_by_chan_id NULL
+
 #endif
 
 #endif /* __LINUX_OF_DMA_H */
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v11 5/6] dma: mpc512x: add device tree binding document

2014-04-15 Thread Alexander Popov
Introduce a device tree binding document for the MPC512x DMA controller

Signed-off-by: Gerhard Sittig g...@denx.de
Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 .../devicetree/bindings/dma/mpc512x-dma.txt| 51 ++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

diff --git a/Documentation/devicetree/bindings/dma/mpc512x-dma.txt 
b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
new file mode 100644
index 000..92eb0d9
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
@@ -0,0 +1,51 @@
+* Freescale MPC512x and MPC8308 DMA Controller
+
+The DMA controller in the Freescale MPC512x and MPC8308 SoCs can move
+blocks of memory contents between memory and peripherals or
+from memory to memory.
+
+Refer to the Generic DMA Controller and DMA request bindings in
+the dma/dma.txt file for a more detailed description of binding.
+
+* DMA controller
+
+Required properties:
+- compatible: Should be one of
+   fsl,mpc5121-dma
+   fsl,mpc8308-dma, fsl,mpc5121-dma
+- reg: Address and size of the DMA controller's register set
+- interrupts: Interrupt for the DMA controller. Generic interrupt client node
+   is described in interrupt-controller/interrupts.txt
+
+Optional properties:
+- #dma-cells: The length of the DMA specifier, must be 1 since
+   the DMA controller uses a fixed assignment of request lines
+   per channel. Refer to dma/dma.txt for the detailed description
+   of this property
+
+Example:
+
+   dma0: dma@14000 {
+   compatible = fsl,mpc5121-dma;
+   reg = 0x14000 0x1800;
+   interrupts = 65 0x8;
+   #dma-cells = 1;
+   };
+
+* DMA client
+
+Required properties:
+- dmas: List of one or more DMA request specifiers. One DMA request specifier
+   consists of a phandle to the DMA controller node followed by
+   the integer specifying the request line
+- dma-names: Contains an identifier string for each DMA request specifier.
+   Refer to dma/dma.txt for the description of this property
+
+Example:
+
+   sdhc@1500 {
+   compatible = fsl,mpc5121-sdhc;
+   /* ... */
+   dmas = dma0 30;
+   dma-names = rx-tx;
+   };
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v11 6/6] dma: mpc512x: register for device tree channel lookup

2014-04-15 Thread Alexander Popov
Register the controller for device tree based lookup of DMA channels
(non-fatal for backwards compatibility with older device trees) and
provide the '#dma-cells' property in the shared mpc5121.dtsi file

Signed-off-by: Gerhard Sittig g...@denx.de
Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 arch/powerpc/boot/dts/mpc5121.dtsi |  1 +
 drivers/dma/mpc512x_dma.c  | 13 -
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi 
b/arch/powerpc/boot/dts/mpc5121.dtsi
index 2c0e155..7f9d14f 100644
--- a/arch/powerpc/boot/dts/mpc5121.dtsi
+++ b/arch/powerpc/boot/dts/mpc5121.dtsi
@@ -498,6 +498,7 @@
compatible = fsl,mpc5121-dma;
reg = 0x14000 0x1800;
interrupts = 65 0x8;
+   #dma-cells = 1;
};
};
 
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 1b90b3b..ab70012 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -52,6 +52,7 @@
 #include linux/of_address.h
 #include linux/of_device.h
 #include linux/of_irq.h
+#include linux/of_dma.h
 #include linux/of_platform.h
 
 #include linux/random.h
@@ -1031,7 +1032,15 @@ static int mpc_dma_probe(struct platform_device *op)
if (retval)
goto err_free2;
 
-   return retval;
+   /* Register with OF helpers for DMA lookups (nonfatal) */
+   if (dev-of_node) {
+   retval = of_dma_controller_register(dev-of_node,
+   of_dma_xlate_by_chan_id, mdma);
+   if (retval)
+   dev_warn(dev, Could not register for OF lookup\n);
+   }
+
+   return 0;
 
 err_free2:
if (mdma-is_mpc8308)
@@ -1052,6 +1061,8 @@ static int mpc_dma_remove(struct platform_device *op)
struct device *dev = op-dev;
struct mpc_dma *mdma = dev_get_drvdata(dev);
 
+   if (dev-of_node)
+   of_dma_controller_free(dev-of_node);
dma_async_device_unregister(mdma-dma);
if (mdma-is_mpc8308) {
free_irq(mdma-irq2, mdma);
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH RFC v10 0/6] MPC512x DMA slave s/g support, OF DMA lookup

2014-04-03 Thread Alexander Popov
Hello,

2014-03-20 18:47 GMT+04:00 Alexander Popov a13xp0p0...@gmail.com:
 Changes in v10:
  Part 2/6:
  - don't use direction field of dma_slave_config in mpc_dma_device_control()
 but store settings in mpc_dma_chan for both DMA_DEV_TO_MEM and
 DMA_MEM_TO_DEV cases; then retrieve the needed values in
 mpc_dma_prep_slave_sg();
  - fix style issue and put 2014 instead of 2013;
  Part 3/6:
  - fix mpc_dma_probe() error path and mpc_dma_remove(): manually free IRQs and
 dispose IRQ mappings before devm_* takes care of other resources;
  Part 6/6:
  - change according the new part 3/6;
  - fix style issue;

Excuse me, could I have a feedback?
Thanks!

 Alexander Popov (5):
   dma: mpc512x: reorder mpc8308 specific instructions
   dma: mpc512x: add support for peripheral transfers
   dma: mpc512x: fix freeing resources in mpc_dma_probe() and
 mpc_dma_remove()
   dma: of: Add common xlate function for matching by channel id
   dma: mpc512x: register for device tree channel lookup

 Gerhard Sittig (1):
   dma: mpc512x: add device tree binding document

  .../devicetree/bindings/dma/mpc512x-dma.txt|  55 
  arch/powerpc/boot/dts/mpc5121.dtsi |   1 +
  drivers/dma/mpc512x_dma.c  | 345 
 ++---
  drivers/dma/of-dma.c   |  35 +++
  include/linux/of_dma.h |   4 +
  5 files changed, 402 insertions(+), 38 deletions(-)
  create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

 --
 1.8.4.2

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH RFC v10 0/6] MPC512x DMA slave s/g support, OF DMA lookup

2014-04-02 Thread Alexander Popov
Hello

20.03.2014 18:48 Alexander Popov a13xp0p0...@gmail.com wrote:
 Changes in v10:
  Part 2/6:
  - don't use direction field of dma_slave_config in
mpc_dma_device_control()
 but store settings in mpc_dma_chan for both DMA_DEV_TO_MEM and
 DMA_MEM_TO_DEV cases; then retrieve the needed values in
 mpc_dma_prep_slave_sg();
  - fix style issue and put 2014 instead of 2013;
  Part 3/6:
  - fix mpc_dma_probe() error path and mpc_dma_remove(): manually free
IRQs and
 dispose IRQ mappings before devm_* takes care of other resources;
  Part 6/6:
  - change according the new part 3/6;
  - fix style issue;

Could I have a feedback?
Thanks!

 Alexander Popov (5):
   dma: mpc512x: reorder mpc8308 specific instructions
   dma: mpc512x: add support for peripheral transfers
   dma: mpc512x: fix freeing resources in mpc_dma_probe() and
 mpc_dma_remove()
   dma: of: Add common xlate function for matching by channel id
   dma: mpc512x: register for device tree channel lookup

 Gerhard Sittig (1):
   dma: mpc512x: add device tree binding document

  .../devicetree/bindings/dma/mpc512x-dma.txt|  55 
  arch/powerpc/boot/dts/mpc5121.dtsi |   1 +
  drivers/dma/mpc512x_dma.c  | 345
++---
  drivers/dma/of-dma.c   |  35 +++
  include/linux/of_dma.h |   4 +
  5 files changed, 402 insertions(+), 38 deletions(-)
  create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

 --
 1.8.4.2


Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v10 0/6] MPC512x DMA slave s/g support, OF DMA lookup

2014-03-20 Thread Alexander Popov
 completely lacks a binding document, so one
should get added.
 - The MPC8308 hardware is similar and can re-use the MPC512x
binding, which should be stated.
 - The Linux implementation currently has no OF based channel
lookup support, so '#dma-cells' is a future feature.  I guess
the binding can and should already discuss the feature,
regardless of whether all implementations support it.


Alexander Popov (5):
  dma: mpc512x: reorder mpc8308 specific instructions
  dma: mpc512x: add support for peripheral transfers
  dma: mpc512x: fix freeing resources in mpc_dma_probe() and
mpc_dma_remove()
  dma: of: Add common xlate function for matching by channel id
  dma: mpc512x: register for device tree channel lookup

Gerhard Sittig (1):
  dma: mpc512x: add device tree binding document

 .../devicetree/bindings/dma/mpc512x-dma.txt|  55 
 arch/powerpc/boot/dts/mpc5121.dtsi |   1 +
 drivers/dma/mpc512x_dma.c  | 345 ++---
 drivers/dma/of-dma.c   |  35 +++
 include/linux/of_dma.h |   4 +
 5 files changed, 402 insertions(+), 38 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v10 1/6] dma: mpc512x: reorder mpc8308 specific instructions

2014-03-20 Thread Alexander Popov
Concentrate the specific code for MPC8308 in the 'if' branch
and handle MPC512x in the 'else' branch.
This modification only reorders instructions but doesn't change behaviour.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
Acked-by: Anatolij Gustschin ag...@denx.de
Acked-by: Gerhard Sittig g...@denx.de
---
 drivers/dma/mpc512x_dma.c | 42 +-
 1 file changed, 25 insertions(+), 17 deletions(-)

diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 448750d..2ce248b 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -52,9 +52,17 @@
 #define MPC_DMA_DESCRIPTORS64
 
 /* Macro definitions */
-#define MPC_DMA_CHANNELS   64
 #define MPC_DMA_TCD_OFFSET 0x1000
 
+/*
+ * Maximum channel counts for individual hardware variants
+ * and the maximum channel count over all supported controllers,
+ * used for data structure size
+ */
+#define MPC8308_DMACHAN_MAX16
+#define MPC512x_DMACHAN_MAX64
+#define MPC_DMA_CHANNELS   64
+
 /* Arbitration mode of group and channel */
 #define MPC_DMA_DMACR_EDCG (1  31)
 #define MPC_DMA_DMACR_ERGA (1  3)
@@ -710,10 +718,10 @@ static int mpc_dma_probe(struct platform_device *op)
 
dma = mdma-dma;
dma-dev = dev;
-   if (!mdma-is_mpc8308)
-   dma-chancnt = MPC_DMA_CHANNELS;
+   if (mdma-is_mpc8308)
+   dma-chancnt = MPC8308_DMACHAN_MAX;
else
-   dma-chancnt = 16; /* MPC8308 DMA has only 16 channels */
+   dma-chancnt = MPC512x_DMACHAN_MAX;
dma-device_alloc_chan_resources = mpc_dma_alloc_chan_resources;
dma-device_free_chan_resources = mpc_dma_free_chan_resources;
dma-device_issue_pending = mpc_dma_issue_pending;
@@ -747,7 +755,19 @@ static int mpc_dma_probe(struct platform_device *op)
 * - Round-robin group arbitration,
 * - Round-robin channel arbitration.
 */
-   if (!mdma-is_mpc8308) {
+   if (mdma-is_mpc8308) {
+   /* MPC8308 has 16 channels and lacks some registers */
+   out_be32(mdma-regs-dmacr, MPC_DMA_DMACR_ERCA);
+
+   /* enable snooping */
+   out_be32(mdma-regs-dmagpor, MPC_DMA_DMAGPOR_SNOOP_ENABLE);
+   /* Disable error interrupts */
+   out_be32(mdma-regs-dmaeeil, 0);
+
+   /* Clear interrupts status */
+   out_be32(mdma-regs-dmaintl, 0x);
+   out_be32(mdma-regs-dmaerrl, 0x);
+   } else {
out_be32(mdma-regs-dmacr, MPC_DMA_DMACR_EDCG |
MPC_DMA_DMACR_ERGA | 
MPC_DMA_DMACR_ERCA);
 
@@ -768,18 +788,6 @@ static int mpc_dma_probe(struct platform_device *op)
/* Route interrupts to IPIC */
out_be32(mdma-regs-dmaihsa, 0);
out_be32(mdma-regs-dmailsa, 0);
-   } else {
-   /* MPC8308 has 16 channels and lacks some registers */
-   out_be32(mdma-regs-dmacr, MPC_DMA_DMACR_ERCA);
-
-   /* enable snooping */
-   out_be32(mdma-regs-dmagpor, MPC_DMA_DMAGPOR_SNOOP_ENABLE);
-   /* Disable error interrupts */
-   out_be32(mdma-regs-dmaeeil, 0);
-
-   /* Clear interrupts status */
-   out_be32(mdma-regs-dmaintl, 0x);
-   out_be32(mdma-regs-dmaerrl, 0x);
}
 
/* Register DMA engine */
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v10 2/6] dma: mpc512x: add support for peripheral transfers

2014-03-20 Thread Alexander Popov
Introduce support for slave s/g transfer preparation and the associated
device control callback in the MPC512x DMA controller driver, which adds
support for data transfers between memory and peripheral I/O to the
previously supported mem-to-mem transfers.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/mpc512x_dma.c | 239 +-
 1 file changed, 234 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 2ce248b..68231d9 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -2,6 +2,7 @@
  * Copyright (C) Freescale Semicondutor, Inc. 2007, 2008.
  * Copyright (C) Semihalf 2009
  * Copyright (C) Ilya Yanok, Emcraft Systems 2010
+ * Copyright (C) Alexander Popov, Promcontroller 2014
  *
  * Written by Piotr Ziecik ko...@semihalf.com. Hardware description
  * (defines, structures and comments) was taken from MPC5121 DMA driver
@@ -29,8 +30,17 @@
  */
 
 /*
- * This is initial version of MPC5121 DMA driver. Only memory to memory
- * transfers are supported (tested using dmatest module).
+ * MPC512x and MPC8308 DMA driver. It supports
+ * memory to memory data transfers (tested using dmatest module) and
+ * data transfers between memory and peripheral I/O memory
+ * by means of slave s/g with these limitations:
+ *  - chunked transfers (transfers with more than one part) are refused
+ * as long as proper support for scatter/gather is missing;
+ *  - transfers on MPC8308 always start from software as this SoC appears
+ * not to have external request lines for peripheral flow control;
+ *  - minimal memory - I/O memory transfer chunk is 4 bytes and consequently
+ * source and destination addresses must be 4-byte aligned
+ * and transfer size must be aligned on (4 * maxburst) boundary;
  */
 
 #include linux/module.h
@@ -189,6 +199,7 @@ struct mpc_dma_desc {
dma_addr_t  tcd_paddr;
int error;
struct list_headnode;
+   int will_access_peripheral;
 };
 
 struct mpc_dma_chan {
@@ -201,6 +212,12 @@ struct mpc_dma_chan {
struct mpc_dma_tcd  *tcd;
dma_addr_t  tcd_paddr;
 
+   /* Settings for access to peripheral FIFO */
+   dma_addr_t  src_per_paddr;
+   u32 src_tcd_nunits;
+   dma_addr_t  dst_per_paddr;
+   u32 dst_tcd_nunits;
+
/* Lock for this structure */
spinlock_t  lock;
 };
@@ -251,8 +268,23 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)
struct mpc_dma_desc *mdesc;
int cid = mchan-chan.chan_id;
 
-   /* Move all queued descriptors to active list */
-   list_splice_tail_init(mchan-queued, mchan-active);
+   while (!list_empty(mchan-queued)) {
+   mdesc = list_first_entry(mchan-queued,
+   struct mpc_dma_desc, node);
+   /*
+* Grab either several mem-to-mem transfer descriptors
+* or one peripheral transfer descriptor,
+* don't mix mem-to-mem and peripheral transfer descriptors
+* within the same 'active' list.
+*/
+   if (mdesc-will_access_peripheral) {
+   if (list_empty(mchan-active))
+   list_move_tail(mdesc-node, mchan-active);
+   break;
+   } else {
+   list_move_tail(mdesc-node, mchan-active);
+   }
+   }
 
/* Chain descriptors into one transaction */
list_for_each_entry(mdesc, mchan-active, node) {
@@ -278,7 +310,17 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)
 
if (first != prev)
mdma-tcd[cid].e_sg = 1;
-   out_8(mdma-regs-dmassrt, cid);
+
+   if (mdma-is_mpc8308) {
+   /* MPC8308, no request lines, software initiated start */
+   out_8(mdma-regs-dmassrt, cid);
+   } else if (first-will_access_peripheral) {
+   /* Peripherals involved, start by external request signal */
+   out_8(mdma-regs-dmaserq, cid);
+   } else {
+   /* Memory to memory transfer, software initiated start */
+   out_8(mdma-regs-dmassrt, cid);
+   }
 }
 
 /* Handle interrupt on one half of DMA controller (32 channels) */
@@ -596,6 +638,7 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, 
dma_addr_t src,
}
 
mdesc-error = 0;
+   mdesc-will_access_peripheral = 0;
tcd = mdesc-tcd;
 
/* Prepare Transfer Control Descriptor for this transaction */
@@ -643,6 +686,189 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t 
dst, dma_addr_t src,
return mdesc-desc;
 }
 
+static

[PATCH RFC v10 3/6] dma: mpc512x: fix freeing resources in mpc_dma_probe() and mpc_dma_remove()

2014-03-20 Thread Alexander Popov
Fix mpc_dma_probe() error path and mpc_dma_remove(): manually free IRQs and
dispose IRQ mappings before devm_* takes care of other resources.
Moreover replace devm_request_irq() with request_irq() since there is no need
to use it because the original code always frees IRQ manually with
devm_free_irq(). Replace devm_free_irq() with free_irq() accordingly.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/mpc512x_dma.c | 55 ---
 1 file changed, 38 insertions(+), 17 deletions(-)

diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 68231d9..1b90b3b 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -883,13 +883,15 @@ static int mpc_dma_probe(struct platform_device *op)
mdma = devm_kzalloc(dev, sizeof(struct mpc_dma), GFP_KERNEL);
if (!mdma) {
dev_err(dev, Memory exhausted!\n);
-   return -ENOMEM;
+   retval = -ENOMEM;
+   goto err;
}
 
mdma-irq = irq_of_parse_and_map(dn, 0);
if (mdma-irq == NO_IRQ) {
dev_err(dev, Error mapping IRQ!\n);
-   return -EINVAL;
+   retval = -EINVAL;
+   goto err;
}
 
if (of_device_is_compatible(dn, fsl,mpc8308-dma)) {
@@ -897,14 +899,15 @@ static int mpc_dma_probe(struct platform_device *op)
mdma-irq2 = irq_of_parse_and_map(dn, 1);
if (mdma-irq2 == NO_IRQ) {
dev_err(dev, Error mapping IRQ!\n);
-   return -EINVAL;
+   retval = -EINVAL;
+   goto err_dispose1;
}
}
 
retval = of_address_to_resource(dn, 0, res);
if (retval) {
dev_err(dev, Error parsing memory region!\n);
-   return retval;
+   goto err_dispose2;
}
 
regs_start = res.start;
@@ -912,31 +915,34 @@ static int mpc_dma_probe(struct platform_device *op)
 
if (!devm_request_mem_region(dev, regs_start, regs_size, DRV_NAME)) {
dev_err(dev, Error requesting memory region!\n);
-   return -EBUSY;
+   retval = -EBUSY;
+   goto err_dispose2;
}
 
mdma-regs = devm_ioremap(dev, regs_start, regs_size);
if (!mdma-regs) {
dev_err(dev, Error mapping memory region!\n);
-   return -ENOMEM;
+   retval = -ENOMEM;
+   goto err_dispose2;
}
 
mdma-tcd = (struct mpc_dma_tcd *)((u8 *)(mdma-regs)
+ MPC_DMA_TCD_OFFSET);
 
-   retval = devm_request_irq(dev, mdma-irq, mpc_dma_irq, 0, DRV_NAME,
-   mdma);
+   retval = request_irq(mdma-irq, mpc_dma_irq, 0, DRV_NAME, mdma);
if (retval) {
dev_err(dev, Error requesting IRQ!\n);
-   return -EINVAL;
+   retval = -EINVAL;
+   goto err_dispose2;
}
 
if (mdma-is_mpc8308) {
-   retval = devm_request_irq(dev, mdma-irq2, mpc_dma_irq, 0,
-   DRV_NAME, mdma);
+   retval = request_irq(mdma-irq2, mpc_dma_irq, 0,
+   DRV_NAME, mdma);
if (retval) {
dev_err(dev, Error requesting IRQ2!\n);
-   return -EINVAL;
+   retval = -EINVAL;
+   goto err_free1;
}
}
 
@@ -1022,12 +1028,23 @@ static int mpc_dma_probe(struct platform_device *op)
/* Register DMA engine */
dev_set_drvdata(dev, mdma);
retval = dma_async_device_register(dma);
-   if (retval) {
-   devm_free_irq(dev, mdma-irq, mdma);
-   irq_dispose_mapping(mdma-irq);
-   }
+   if (retval)
+   goto err_free2;
 
return retval;
+
+err_free2:
+   if (mdma-is_mpc8308)
+   free_irq(mdma-irq2, mdma);
+err_free1:
+   free_irq(mdma-irq, mdma);
+err_dispose2:
+   if (mdma-is_mpc8308)
+   irq_dispose_mapping(mdma-irq2);
+err_dispose1:
+   irq_dispose_mapping(mdma-irq);
+err:
+   return retval;
 }
 
 static int mpc_dma_remove(struct platform_device *op)
@@ -1036,7 +1053,11 @@ static int mpc_dma_remove(struct platform_device *op)
struct mpc_dma *mdma = dev_get_drvdata(dev);
 
dma_async_device_unregister(mdma-dma);
-   devm_free_irq(dev, mdma-irq, mdma);
+   if (mdma-is_mpc8308) {
+   free_irq(mdma-irq2, mdma);
+   irq_dispose_mapping(mdma-irq2);
+   }
+   free_irq(mdma-irq, mdma);
irq_dispose_mapping(mdma-irq);
 
return 0;
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https

[PATCH RFC v10 4/6] dma: of: Add common xlate function for matching by channel id

2014-03-20 Thread Alexander Popov
This patch adds a new common OF dma xlate callback function which will match a
channel by it's id. The binding expects one integer argument which it will use 
to
lookup the channel by the id.

Unlike of_dma_simple_xlate this function is able to handle a system with
multiple DMA controllers. When registering the of dma provider with
of_dma_controller_register a pointer to the dma_device struct which is
associated with the dt node needs to passed as the data parameter.
New function will use this pointer to match only channels which belong to the
specified DMA controller.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/of-dma.c   | 35 +++
 include/linux/of_dma.h |  4 
 2 files changed, 39 insertions(+)

diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index e8fe9dc..d5fbeaa 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -218,3 +218,38 @@ struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_spec,
dma_spec-args[0]);
 }
 EXPORT_SYMBOL_GPL(of_dma_simple_xlate);
+
+/**
+ * of_dma_xlate_by_chan_id - Translate dt property to DMA channel by channel id
+ * @dma_spec:  pointer to DMA specifier as found in the device tree
+ * @of_dma:pointer to DMA controller data
+ *
+ * This function can be used as the of xlate callback for DMA driver which 
wants
+ * to match the channel based on the channel id. When using this xlate function
+ * the #dma-cells propety of the DMA controller dt node needs to be set to 1.
+ * The data parameter of of_dma_controller_register must be a pointer to the
+ * dma_device struct the function should match upon.
+ *
+ * Returns pointer to appropriate dma channel on success or NULL on error.
+ */
+struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
+struct of_dma *ofdma)
+{
+   struct dma_device *dev = ofdma-of_dma_data;
+   struct dma_chan *chan, *candidate = NULL;
+
+   if (!dev || dma_spec-args_count != 1)
+   return NULL;
+
+   list_for_each_entry(chan, dev-channels, device_node)
+   if (chan-chan_id == dma_spec-args[0]) {
+   candidate = chan;
+   break;
+   }
+
+   if (!candidate)
+   return NULL;
+
+   return dma_get_slave_channel(candidate);
+}
+EXPORT_SYMBOL_GPL(of_dma_xlate_by_chan_id);
diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
index ae36298..56bc026 100644
--- a/include/linux/of_dma.h
+++ b/include/linux/of_dma.h
@@ -41,6 +41,8 @@ extern struct dma_chan *of_dma_request_slave_channel(struct 
device_node *np,
 const char *name);
 extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma);
+extern struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args 
*dma_spec,
+   struct of_dma *ofdma);
 #else
 static inline int of_dma_controller_register(struct device_node *np,
struct dma_chan *(*of_dma_xlate)
@@ -66,6 +68,8 @@ static inline struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_s
return NULL;
 }
 
+#define of_dma_xlate_by_chan_id NULL
+
 #endif
 
 #endif /* __LINUX_OF_DMA_H */
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v10 5/6] dma: mpc512x: add device tree binding document

2014-03-20 Thread Alexander Popov
From: Gerhard Sittig g...@denx.de

introduce a device tree binding document for the MPC512x DMA controller

Signed-off-by: Gerhard Sittig g...@denx.de
[ a13xp0p0...@gmail.com: turn this into a separate patch ]
---
 .../devicetree/bindings/dma/mpc512x-dma.txt| 55 ++
 1 file changed, 55 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

diff --git a/Documentation/devicetree/bindings/dma/mpc512x-dma.txt 
b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
new file mode 100644
index 000..a4867d5
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
@@ -0,0 +1,55 @@
+* Freescale MPC512x DMA Controller
+
+The DMA controller in the Freescale MPC512x SoC can move blocks of
+memory contents between memory and peripherals or memory to memory.
+
+Refer to the Generic DMA Controller and DMA request bindings description
+in the dma.txt file for a more detailled discussion of the binding.  The
+MPC512x DMA engine binding follows the common scheme, but doesn't provide
+support for the optional channels and requests counters (those values are
+derived from the detected hardware features) and has a fixed client
+specifier length of 1 integer cell (the value is the DMA channel, since
+the DMA controller uses a fixed assignment of request lines per channel).
+
+
+DMA controller node properties:
+
+Required properties:
+- compatible:  should be fsl,mpc5121-dma
+- reg: address and size of the DMA controller's register set
+- interrupts:  interrupt spec for the DMA controller
+
+Optional properties:
+- #dma-cells:  must be 1, describes the number of integer cells
+   needed to specify the 'dmas' property in client nodes,
+   strongly recommended since common client helper code
+   uses this property
+
+Example:
+
+   dma0: dma@14000 {
+   compatible = fsl,mpc5121-dma;
+   reg = 0x14000 0x1800;
+   interrupts = 65 0x8;
+   #dma-cells = 1;
+   };
+
+
+Client node properties:
+
+Required properties:
+- dmas:list of DMA specifiers, consisting each of a 
handle
+   for the DMA controller and integer cells to specify
+   the channel used within the DMA controller
+- dma-names:   list of identifier strings for the DMA specifiers,
+   client device driver code uses these strings to
+   have DMA channels looked up at the controller
+
+Example:
+
+   sdhc@1500 {
+   compatible = fsl,mpc5121-sdhc;
+   /* ... */
+   dmas = dma0 30;
+   dma-names = rx-tx;
+   };
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v10 6/6] dma: mpc512x: register for device tree channel lookup

2014-03-20 Thread Alexander Popov
Register the controller for device tree based lookup of DMA channels
(non-fatal for backwards compatibility with older device trees) and
provide the '#dma-cells' property in the shared mpc5121.dtsi file

Signed-off-by: Gerhard Sittig g...@denx.de
Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 arch/powerpc/boot/dts/mpc5121.dtsi |  1 +
 drivers/dma/mpc512x_dma.c  | 13 -
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi 
b/arch/powerpc/boot/dts/mpc5121.dtsi
index 2c0e155..7f9d14f 100644
--- a/arch/powerpc/boot/dts/mpc5121.dtsi
+++ b/arch/powerpc/boot/dts/mpc5121.dtsi
@@ -498,6 +498,7 @@
compatible = fsl,mpc5121-dma;
reg = 0x14000 0x1800;
interrupts = 65 0x8;
+   #dma-cells = 1;
};
};
 
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 1b90b3b..ab70012 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -52,6 +52,7 @@
 #include linux/of_address.h
 #include linux/of_device.h
 #include linux/of_irq.h
+#include linux/of_dma.h
 #include linux/of_platform.h
 
 #include linux/random.h
@@ -1031,7 +1032,15 @@ static int mpc_dma_probe(struct platform_device *op)
if (retval)
goto err_free2;
 
-   return retval;
+   /* Register with OF helpers for DMA lookups (nonfatal) */
+   if (dev-of_node) {
+   retval = of_dma_controller_register(dev-of_node,
+   of_dma_xlate_by_chan_id, mdma);
+   if (retval)
+   dev_warn(dev, Could not register for OF lookup\n);
+   }
+
+   return 0;
 
 err_free2:
if (mdma-is_mpc8308)
@@ -1052,6 +1061,8 @@ static int mpc_dma_remove(struct platform_device *op)
struct device *dev = op-dev;
struct mpc_dma *mdma = dev_get_drvdata(dev);
 
+   if (dev-of_node)
+   of_dma_controller_free(dev-of_node);
dma_async_device_unregister(mdma-dma);
if (mdma-is_mpc8308) {
free_irq(mdma-irq2, mdma);
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH RFC v9 2/6] dma: mpc512x: add support for peripheral transfers

2014-03-19 Thread Alexander Popov
Hello Andy

2014-03-14 13:47 GMT+04:00 Andy Shevchenko andriy.shevche...@linux.intel.com:
 On Wed, 2014-03-12 at 15:47 +0400, Alexander Popov wrote:
 + case DMA_SLAVE_CONFIG:
 + /* Constraints:
 +  *  - only transfers between a peripheral device and
 +  * memory are supported;
 +  *  - minimal transfer chunk is 4 bytes and consequently
 +  * source and destination addresses must be 4-byte aligned
 +  * and transfer size must be aligned on (4 * maxburst)
 +  * boundary;
 +  *  - during the transfer RAM address is being incremented by
 +  * the size of minimal transfer chunk;
 +  *  - peripheral port's address is constant during the 
 transfer.
 +  */
 +
 + cfg = (void *)arg;
 +
 + if (!is_slave_direction(cfg-direction))
 + return -EINVAL;

 As far as I understand the intention you have not to use direction field
 in the dma_slave_config. It will be removed once.

 +
 + if (cfg-src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES 
 + cfg-dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
 + return -EINVAL;
 +
 + spin_lock_irqsave(mchan-lock, flags);
 +
 + if (cfg-direction == DMA_DEV_TO_MEM) {
 + mchan-per_paddr = cfg-src_addr;
 + mchan-tcd_nunits = cfg-src_maxburst;
 + } else {
 + mchan-per_paddr = cfg-dst_addr;
 + mchan-tcd_nunits = cfg-dst_maxburst;
 + }

 Ditto.

Excuse me, I don't understand this point.
I have to use cfg-direction because in case of DMA_DEV_TO_MEM
I use cfg-SRC_addr and cfg-SRC_maxburst and in case of
DMA_MEM_TO_DEV I use cfg-DST_addr and cfg-DST_maxburst.
Is it correct?

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v9 0/6] MPC512x DMA slave s/g support, OF DMA lookup

2014-03-12 Thread Alexander Popov
2013/7/14 Gerhard Sittig g...@denx.de:
 this series
 - introduces slave s/g support (that's support for DMA transfers which
involve peripherals in contrast to mem-to-mem transfers)
 - adds device tree based lookup support for DMA channels
 - combines floating patches and related feedback which already covered
several aspects of what the suggested LPB driver needs, to demonstrate
how integration might be done
 - carries QD SD card support to enable another DMA client during test,
while this patch needs to get dropped upon pickup

Changes in v2:
 - re-order mpc8308 related code paths for improved readability, no
change in behaviour, introduction of symbolic channel names here
already
 - squash 'execute() start condition' and 'terminate all' into the
introduction of 'slave s/g prep' and 'device control' support; refuse
s/g lists with more than one item since slave support is operational
yet proper s/g support is missing (can get addressed later)
 - always start transfers from software on MPC8308 as there are no
external request lines for peripheral flow control
 - drop dt-bindings header file and symbolic channel names in OF nodes

Changes in v3 and v4:
 Part 1/5:
 - use #define instead of enum since individual channels don't require
special handling.
 Part 2/5:
 - add a flag will_access_peripheral to DMA transfer descriptor
according recommendations of Gerhard Sittig.
This flag is set in mpc_dma_prep_memcpy() and mpc_dma_prep_slave_sg()
and is evaluated in mpc_dma_execute() to choose a type of start for
the transfer.
 - prevent descriptors of transfers which involve peripherals from
being chained together;
each of such transfers needs hardware initiated start.
 - add locking while working with struct mpc_dma_chan
according recommendations of Lars-Peter Clausen.
 - remove default nbytes value. Client kernel modules must set
src_maxburst and dst_maxburst fields of struct dma_slave_config 
(dmaengine.h).

Changes in v5:
 Part 2/5:
 - add and improve comments;
 - improve the code moving transfer descriptors from 'queued' to 'active' list
in mpc_dma_execute();
 - allow mpc_dma_prep_slave_sg() to run with non-empty 'active' list;
 - take 'mdesc' back to 'free' list in case of error in mpc_dma_prep_slave_sg();
 - improve checks of the transfer parameters;
 - provide the default value for 'maxburst' in mpc_dma_device_control().

Changes in v6:
 Part 2/5:
 - remove doubtful comment;
 - fix coding style issues;
 - set default value for 'maxburst' to 1 which applies to most cases;
 Part 3/5:
 - use dma_get_slave_channel() instead of dma_request_channel()
in new function of_dma_xlate_by_chan_id() according recommendations of
Arnd Bergmann;
 Part 4/5:
 - set DMA_PRIVATE flag for MPC512x DMA controller since its driver relies on
of_dma_xlate_by_chan_id() which doesn't use dma_request_channel()
any more; (removed in v7)
 - resolve little patch conflict;
 Part 5/5:
 - resolve little patch conflict;

Changes in v7:
 Part 2:
 - improve comment;
 Part 4:
 - split in two separate patches. Part 4/6 contains device tree
binding document and in part 5/6 MPC512x DMA controller is registered
for device tree channel lookup;
 - remove setting DMA_PRIVATE flag for MPC512x DMA controller from part 5/6;

Changes in v8:
 Part 2:
 - improve comments;
 - fix style issues;
 Part 6:
 - remove since it has become obsolete;

Changes in v9:
 A new patch (part 3/6) is added to this series according the
   feedback of Andy Shevchenko.
 Part 2/6:
 - keep style of the comments;
 - use is_slave_direction() instead of manual checks;
 - remove redundant else branches of the conditions;
 - make mpc_dma_device_control() return -ENXIO for unknown command;
 Part 6/6:
 - change according the new part 3/6;
 - fix style issues;

 known issues:
 - it's yet to get confirmed whether MPC8308 can use slave support or
whether the DMA controller's driver shall actively reject it, the
information that's available so far suggests that peripheral transfers
to IP bus attached I/O is useful and shall not get blocked right away
 - adding support for transfers which don't increment the RAM address or
do increment the peripheral port's address is easy with
this implementation; but which options of the common API
should be used for specifying such transfers?
2014/02/13 Gerhard Sittig g...@denx.de:
 - The MPC512x DMA completely lacks a binding document, so one
should get added.
 - The MPC8308 hardware is similar and can re-use the MPC512x
binding, which should be stated.
 - The Linux implementation currently has no OF based channel
lookup support, so '#dma-cells' is a future feature.  I guess
the binding can and should already discuss the feature,
regardless of whether all implementations support it.


Alexander Popov (5):
  dma: mpc512x: reorder mpc8308 specific instructions
  dma: mpc512x: add support for peripheral transfers

[PATCH RFC v9 1/6] dma: mpc512x: reorder mpc8308 specific instructions

2014-03-12 Thread Alexander Popov
Concentrate the specific code for MPC8308 in the 'if' branch
and handle MPC512x in the 'else' branch.
This modification only reorders instructions but doesn't change behaviour.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
Acked-by: Anatolij Gustschin ag...@denx.de
Acked-by: Gerhard Sittig g...@denx.de
---
 drivers/dma/mpc512x_dma.c | 42 +-
 1 file changed, 25 insertions(+), 17 deletions(-)

diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 448750d..2ce248b 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -52,9 +52,17 @@
 #define MPC_DMA_DESCRIPTORS64
 
 /* Macro definitions */
-#define MPC_DMA_CHANNELS   64
 #define MPC_DMA_TCD_OFFSET 0x1000
 
+/*
+ * Maximum channel counts for individual hardware variants
+ * and the maximum channel count over all supported controllers,
+ * used for data structure size
+ */
+#define MPC8308_DMACHAN_MAX16
+#define MPC512x_DMACHAN_MAX64
+#define MPC_DMA_CHANNELS   64
+
 /* Arbitration mode of group and channel */
 #define MPC_DMA_DMACR_EDCG (1  31)
 #define MPC_DMA_DMACR_ERGA (1  3)
@@ -710,10 +718,10 @@ static int mpc_dma_probe(struct platform_device *op)
 
dma = mdma-dma;
dma-dev = dev;
-   if (!mdma-is_mpc8308)
-   dma-chancnt = MPC_DMA_CHANNELS;
+   if (mdma-is_mpc8308)
+   dma-chancnt = MPC8308_DMACHAN_MAX;
else
-   dma-chancnt = 16; /* MPC8308 DMA has only 16 channels */
+   dma-chancnt = MPC512x_DMACHAN_MAX;
dma-device_alloc_chan_resources = mpc_dma_alloc_chan_resources;
dma-device_free_chan_resources = mpc_dma_free_chan_resources;
dma-device_issue_pending = mpc_dma_issue_pending;
@@ -747,7 +755,19 @@ static int mpc_dma_probe(struct platform_device *op)
 * - Round-robin group arbitration,
 * - Round-robin channel arbitration.
 */
-   if (!mdma-is_mpc8308) {
+   if (mdma-is_mpc8308) {
+   /* MPC8308 has 16 channels and lacks some registers */
+   out_be32(mdma-regs-dmacr, MPC_DMA_DMACR_ERCA);
+
+   /* enable snooping */
+   out_be32(mdma-regs-dmagpor, MPC_DMA_DMAGPOR_SNOOP_ENABLE);
+   /* Disable error interrupts */
+   out_be32(mdma-regs-dmaeeil, 0);
+
+   /* Clear interrupts status */
+   out_be32(mdma-regs-dmaintl, 0x);
+   out_be32(mdma-regs-dmaerrl, 0x);
+   } else {
out_be32(mdma-regs-dmacr, MPC_DMA_DMACR_EDCG |
MPC_DMA_DMACR_ERGA | 
MPC_DMA_DMACR_ERCA);
 
@@ -768,18 +788,6 @@ static int mpc_dma_probe(struct platform_device *op)
/* Route interrupts to IPIC */
out_be32(mdma-regs-dmaihsa, 0);
out_be32(mdma-regs-dmailsa, 0);
-   } else {
-   /* MPC8308 has 16 channels and lacks some registers */
-   out_be32(mdma-regs-dmacr, MPC_DMA_DMACR_ERCA);
-
-   /* enable snooping */
-   out_be32(mdma-regs-dmagpor, MPC_DMA_DMAGPOR_SNOOP_ENABLE);
-   /* Disable error interrupts */
-   out_be32(mdma-regs-dmaeeil, 0);
-
-   /* Clear interrupts status */
-   out_be32(mdma-regs-dmaintl, 0x);
-   out_be32(mdma-regs-dmaerrl, 0x);
}
 
/* Register DMA engine */
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v9 2/6] dma: mpc512x: add support for peripheral transfers

2014-03-12 Thread Alexander Popov
Introduce support for slave s/g transfer preparation and the associated
device control callback in the MPC512x DMA controller driver, which adds
support for data transfers between memory and peripheral I/O to the
previously supported mem-to-mem transfers.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/mpc512x_dma.c | 236 +-
 1 file changed, 231 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 2ce248b..b1e430c 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -2,6 +2,7 @@
  * Copyright (C) Freescale Semicondutor, Inc. 2007, 2008.
  * Copyright (C) Semihalf 2009
  * Copyright (C) Ilya Yanok, Emcraft Systems 2010
+ * Copyright (C) Alexander Popov, Promcontroller 2013
  *
  * Written by Piotr Ziecik ko...@semihalf.com. Hardware description
  * (defines, structures and comments) was taken from MPC5121 DMA driver
@@ -29,8 +30,17 @@
  */
 
 /*
- * This is initial version of MPC5121 DMA driver. Only memory to memory
- * transfers are supported (tested using dmatest module).
+ * MPC512x and MPC8308 DMA driver. It supports
+ * memory to memory data transfers (tested using dmatest module) and
+ * data transfers between memory and peripheral I/O memory
+ * by means of slave s/g with these limitations:
+ *  - chunked transfers (transfers with more than one part) are refused
+ * as long as proper support for scatter/gather is missing;
+ *  - transfers on MPC8308 always start from software as this SoC appears
+ * not to have external request lines for peripheral flow control;
+ *  - minimal memory - I/O memory transfer chunk is 4 bytes and consequently
+ * source and destination addresses must be 4-byte aligned
+ * and transfer size must be aligned on (4 * maxburst) boundary;
  */
 
 #include linux/module.h
@@ -189,6 +199,7 @@ struct mpc_dma_desc {
dma_addr_t  tcd_paddr;
int error;
struct list_headnode;
+   int will_access_peripheral;
 };
 
 struct mpc_dma_chan {
@@ -201,6 +212,10 @@ struct mpc_dma_chan {
struct mpc_dma_tcd  *tcd;
dma_addr_t  tcd_paddr;
 
+   /* Settings for access to peripheral FIFO */
+   dma_addr_t  per_paddr;  /* FIFO address */
+   u32 tcd_nunits;
+
/* Lock for this structure */
spinlock_t  lock;
 };
@@ -251,8 +266,23 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)
struct mpc_dma_desc *mdesc;
int cid = mchan-chan.chan_id;
 
-   /* Move all queued descriptors to active list */
-   list_splice_tail_init(mchan-queued, mchan-active);
+   while (!list_empty(mchan-queued)) {
+   mdesc = list_first_entry(mchan-queued,
+   struct mpc_dma_desc, node);
+   /*
+* Grab either several mem-to-mem transfer descriptors
+* or one peripheral transfer descriptor,
+* don't mix mem-to-mem and peripheral transfer descriptors
+* within the same 'active' list.
+*/
+   if (mdesc-will_access_peripheral) {
+   if (list_empty(mchan-active))
+   list_move_tail(mdesc-node, mchan-active);
+   break;
+   } else {
+   list_move_tail(mdesc-node, mchan-active);
+   }
+   }
 
/* Chain descriptors into one transaction */
list_for_each_entry(mdesc, mchan-active, node) {
@@ -278,7 +308,17 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)
 
if (first != prev)
mdma-tcd[cid].e_sg = 1;
-   out_8(mdma-regs-dmassrt, cid);
+
+   if (mdma-is_mpc8308) {
+   /* MPC8308, no request lines, software initiated start */
+   out_8(mdma-regs-dmassrt, cid);
+   } else if (first-will_access_peripheral) {
+   /* Peripherals involved, start by external request signal */
+   out_8(mdma-regs-dmaserq, cid);
+   } else {
+   /* Memory to memory transfer, software initiated start */
+   out_8(mdma-regs-dmassrt, cid);
+   }
 }
 
 /* Handle interrupt on one half of DMA controller (32 channels) */
@@ -596,6 +636,7 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, 
dma_addr_t src,
}
 
mdesc-error = 0;
+   mdesc-will_access_peripheral = 0;
tcd = mdesc-tcd;
 
/* Prepare Transfer Control Descriptor for this transaction */
@@ -643,6 +684,188 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t 
dst, dma_addr_t src,
return mdesc-desc;
 }
 
+static struct dma_async_tx_descriptor *
+mpc_dma_prep_slave_sg(struct dma_chan *chan, struct

[PATCH RFC v9 3/6] dma: mpc512x: replace devm_request_irq() with request_irq()

2014-03-12 Thread Alexander Popov
Replace devm_request_irq() with request_irq() since there is no need
to use it because the original code always frees IRQ manually with
devm_free_irq(). Replace devm_free_irq() with free_irq() accordingly.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/mpc512x_dma.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index b1e430c..ff7f678 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -921,16 +921,15 @@ static int mpc_dma_probe(struct platform_device *op)
mdma-tcd = (struct mpc_dma_tcd *)((u8 *)(mdma-regs)
+ MPC_DMA_TCD_OFFSET);
 
-   retval = devm_request_irq(dev, mdma-irq, mpc_dma_irq, 0, DRV_NAME,
-   mdma);
+   retval = request_irq(mdma-irq, mpc_dma_irq, 0, DRV_NAME, mdma);
if (retval) {
dev_err(dev, Error requesting IRQ!\n);
return -EINVAL;
}
 
if (mdma-is_mpc8308) {
-   retval = devm_request_irq(dev, mdma-irq2, mpc_dma_irq, 0,
-   DRV_NAME, mdma);
+   retval = request_irq(mdma-irq2, mpc_dma_irq, 0,
+   DRV_NAME, mdma);
if (retval) {
dev_err(dev, Error requesting IRQ2!\n);
return -EINVAL;
@@ -1020,7 +1019,7 @@ static int mpc_dma_probe(struct platform_device *op)
dev_set_drvdata(dev, mdma);
retval = dma_async_device_register(dma);
if (retval) {
-   devm_free_irq(dev, mdma-irq, mdma);
+   free_irq(mdma-irq, mdma);
irq_dispose_mapping(mdma-irq);
}
 
@@ -1033,7 +1032,7 @@ static int mpc_dma_remove(struct platform_device *op)
struct mpc_dma *mdma = dev_get_drvdata(dev);
 
dma_async_device_unregister(mdma-dma);
-   devm_free_irq(dev, mdma-irq, mdma);
+   free_irq(mdma-irq, mdma);
irq_dispose_mapping(mdma-irq);
 
return 0;
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v9 4/6] dma: of: Add common xlate function for matching by channel id

2014-03-12 Thread Alexander Popov
This patch adds a new common OF dma xlate callback function which will match a
channel by it's id. The binding expects one integer argument which it will use 
to
lookup the channel by the id.

Unlike of_dma_simple_xlate this function is able to handle a system with
multiple DMA controllers. When registering the of dma provider with
of_dma_controller_register a pointer to the dma_device struct which is
associated with the dt node needs to passed as the data parameter.
New function will use this pointer to match only channels which belong to the
specified DMA controller.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/of-dma.c   | 35 +++
 include/linux/of_dma.h |  4 
 2 files changed, 39 insertions(+)

diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index e8fe9dc..d5fbeaa 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -218,3 +218,38 @@ struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_spec,
dma_spec-args[0]);
 }
 EXPORT_SYMBOL_GPL(of_dma_simple_xlate);
+
+/**
+ * of_dma_xlate_by_chan_id - Translate dt property to DMA channel by channel id
+ * @dma_spec:  pointer to DMA specifier as found in the device tree
+ * @of_dma:pointer to DMA controller data
+ *
+ * This function can be used as the of xlate callback for DMA driver which 
wants
+ * to match the channel based on the channel id. When using this xlate function
+ * the #dma-cells propety of the DMA controller dt node needs to be set to 1.
+ * The data parameter of of_dma_controller_register must be a pointer to the
+ * dma_device struct the function should match upon.
+ *
+ * Returns pointer to appropriate dma channel on success or NULL on error.
+ */
+struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
+struct of_dma *ofdma)
+{
+   struct dma_device *dev = ofdma-of_dma_data;
+   struct dma_chan *chan, *candidate = NULL;
+
+   if (!dev || dma_spec-args_count != 1)
+   return NULL;
+
+   list_for_each_entry(chan, dev-channels, device_node)
+   if (chan-chan_id == dma_spec-args[0]) {
+   candidate = chan;
+   break;
+   }
+
+   if (!candidate)
+   return NULL;
+
+   return dma_get_slave_channel(candidate);
+}
+EXPORT_SYMBOL_GPL(of_dma_xlate_by_chan_id);
diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
index ae36298..56bc026 100644
--- a/include/linux/of_dma.h
+++ b/include/linux/of_dma.h
@@ -41,6 +41,8 @@ extern struct dma_chan *of_dma_request_slave_channel(struct 
device_node *np,
 const char *name);
 extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma);
+extern struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args 
*dma_spec,
+   struct of_dma *ofdma);
 #else
 static inline int of_dma_controller_register(struct device_node *np,
struct dma_chan *(*of_dma_xlate)
@@ -66,6 +68,8 @@ static inline struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_s
return NULL;
 }
 
+#define of_dma_xlate_by_chan_id NULL
+
 #endif
 
 #endif /* __LINUX_OF_DMA_H */
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v9 5/6] dma: mpc512x: add device tree binding document

2014-03-12 Thread Alexander Popov
From: Gerhard Sittig g...@denx.de

introduce a device tree binding document for the MPC512x DMA controller

Signed-off-by: Gerhard Sittig g...@denx.de
[ a13xp0p0...@gmail.com: turn this into a separate patch ]
---
 .../devicetree/bindings/dma/mpc512x-dma.txt| 55 ++
 1 file changed, 55 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

diff --git a/Documentation/devicetree/bindings/dma/mpc512x-dma.txt 
b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
new file mode 100644
index 000..a4867d5
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
@@ -0,0 +1,55 @@
+* Freescale MPC512x DMA Controller
+
+The DMA controller in the Freescale MPC512x SoC can move blocks of
+memory contents between memory and peripherals or memory to memory.
+
+Refer to the Generic DMA Controller and DMA request bindings description
+in the dma.txt file for a more detailled discussion of the binding.  The
+MPC512x DMA engine binding follows the common scheme, but doesn't provide
+support for the optional channels and requests counters (those values are
+derived from the detected hardware features) and has a fixed client
+specifier length of 1 integer cell (the value is the DMA channel, since
+the DMA controller uses a fixed assignment of request lines per channel).
+
+
+DMA controller node properties:
+
+Required properties:
+- compatible:  should be fsl,mpc5121-dma
+- reg: address and size of the DMA controller's register set
+- interrupts:  interrupt spec for the DMA controller
+
+Optional properties:
+- #dma-cells:  must be 1, describes the number of integer cells
+   needed to specify the 'dmas' property in client nodes,
+   strongly recommended since common client helper code
+   uses this property
+
+Example:
+
+   dma0: dma@14000 {
+   compatible = fsl,mpc5121-dma;
+   reg = 0x14000 0x1800;
+   interrupts = 65 0x8;
+   #dma-cells = 1;
+   };
+
+
+Client node properties:
+
+Required properties:
+- dmas:list of DMA specifiers, consisting each of a 
handle
+   for the DMA controller and integer cells to specify
+   the channel used within the DMA controller
+- dma-names:   list of identifier strings for the DMA specifiers,
+   client device driver code uses these strings to
+   have DMA channels looked up at the controller
+
+Example:
+
+   sdhc@1500 {
+   compatible = fsl,mpc5121-sdhc;
+   /* ... */
+   dmas = dma0 30;
+   dma-names = rx-tx;
+   };
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v9 6/6] dma: mpc512x: register for device tree channel lookup

2014-03-12 Thread Alexander Popov
Register the controller for device tree based lookup of DMA channels
(non-fatal for backwards compatibility with older device trees) and
provide the '#dma-cells' property in the shared mpc5121.dtsi file

Signed-off-by: Gerhard Sittig g...@denx.de
Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 arch/powerpc/boot/dts/mpc5121.dtsi |  1 +
 drivers/dma/mpc512x_dma.c  | 21 ++---
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi 
b/arch/powerpc/boot/dts/mpc5121.dtsi
index 2c0e155..7f9d14f 100644
--- a/arch/powerpc/boot/dts/mpc5121.dtsi
+++ b/arch/powerpc/boot/dts/mpc5121.dtsi
@@ -498,6 +498,7 @@
compatible = fsl,mpc5121-dma;
reg = 0x14000 0x1800;
interrupts = 65 0x8;
+   #dma-cells = 1;
};
};
 
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index ff7f678..453b1cb 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -52,6 +52,7 @@
 #include linux/of_address.h
 #include linux/of_device.h
 #include linux/of_irq.h
+#include linux/of_dma.h
 #include linux/of_platform.h
 
 #include linux/random.h
@@ -1018,11 +1019,23 @@ static int mpc_dma_probe(struct platform_device *op)
/* Register DMA engine */
dev_set_drvdata(dev, mdma);
retval = dma_async_device_register(dma);
-   if (retval) {
-   free_irq(mdma-irq, mdma);
-   irq_dispose_mapping(mdma-irq);
+   if (retval)
+   goto out_irq;
+
+   /* Register with OF helpers for DMA lookups (nonfatal) */
+   if (dev-of_node) {
+   retval = of_dma_controller_register(dev-of_node,
+   of_dma_xlate_by_chan_id, mdma);
+   if (retval)
+   dev_warn(dev, could not register for OF lookup\n);
}
 
+   return 0;
+
+out_irq:
+   free_irq(mdma-irq, mdma);
+   irq_dispose_mapping(mdma-irq);
+
return retval;
 }
 
@@ -1031,6 +1044,8 @@ static int mpc_dma_remove(struct platform_device *op)
struct device *dev = op-dev;
struct mpc_dma *mdma = dev_get_drvdata(dev);
 
+   if (dev-of_node)
+   of_dma_controller_free(dev-of_node);
dma_async_device_unregister(mdma-dma);
free_irq(mdma-irq, mdma);
irq_dispose_mapping(mdma-irq);
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH RFC v8 5/5] dma: mpc512x: register for device tree channel lookup

2014-03-06 Thread Alexander Popov
Hello Andy.

2014-02-24 17:08 GMT+04:00 Andy Shevchenko andriy.shevche...@linux.intel.com:
 On Mon, 2014-02-24 at 15:09 +0400, Alexander Popov wrote:
 @@ -1018,11 +1019,23 @@ static int mpc_dma_probe(struct platform_device *op)
   /* Register DMA engine */
   dev_set_drvdata(dev, mdma);
   retval = dma_async_device_register(dma);
 - if (retval) {
 - devm_free_irq(dev, mdma-irq, mdma);
 - irq_dispose_mapping(mdma-irq);
 + if (retval)
 + goto out_irq;
 +
 + /* register with OF helpers for DMA lookups (nonfatal) */
 + if (dev-of_node) {
 + retval = of_dma_controller_register(dev-of_node,
 + of_dma_xlate_by_chan_id,
 + mdma);
 + if (retval)
 + dev_warn(dev, could not register for OF lookup\n);
   }

 + return 0;
 +
 +out_irq:
 + devm_free_irq(dev, mdma-irq, mdma);

 Something wrong either with devm_request_irq() or you don't need to call
 devm_free_irq() explicitly. Once we already try to discuss this earlier
 in this mailing list with Lars-Peter(?), though there were no solution
 how to keep devm_*_irq usability.

Thanks, I've read this discussion. It seems that the current code doesn't do
anything bad, though devm_request_irq() and devm_free_irq() can be changed
to request_irq() and free_irq() accordingly. Do you think it's worth being done
in a separate patch in this series?

 + irq_dispose_mapping(mdma-irq);
   return retval;
  }

 @@ -1031,6 +1044,8 @@ static int mpc_dma_remove(struct platform_device *op)
   struct device *dev = op-dev;
   struct mpc_dma *mdma = dev_get_drvdata(dev);

 + if (dev-of_node)
 + of_dma_controller_free(dev-of_node);
   dma_async_device_unregister(mdma-dma);
   devm_free_irq(dev, mdma-irq, mdma);
   irq_dispose_mapping(mdma-irq);

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH RFC v8 2/5] dma: mpc512x: add support for peripheral transfers

2014-03-01 Thread Alexander Popov
Hello Andy.

2014-02-24 17:03 GMT+04:00 Andy Shevchenko andriy.shevche...@linux.intel.com:
 On Mon, 2014-02-24 at 15:09 +0400, Alexander Popov wrote:
 Introduce support for slave s/g transfer preparation and the associated
 device control callback in the MPC512x DMA controller driver, which adds
 support for data transfers between memory and peripheral I/O to the
 previously supported mem-to-mem transfers.


 Few comments below.

Thanks for your feedback. I agree with your points and will fix my code.

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v8 1/5] dma: mpc512x: reorder mpc8308 specific instructions

2014-02-24 Thread Alexander Popov
Concentrate the specific code for MPC8308 in the 'if' branch
and handle MPC512x in the 'else' branch.
This modification only reorders instructions but doesn't change behaviour.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
Acked-by: Anatolij Gustschin ag...@denx.de
Acked-by: Gerhard Sittig g...@denx.de
---
 drivers/dma/mpc512x_dma.c | 42 +-
 1 file changed, 25 insertions(+), 17 deletions(-)

diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 448750d..2ce248b 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -52,9 +52,17 @@
 #define MPC_DMA_DESCRIPTORS64
 
 /* Macro definitions */
-#define MPC_DMA_CHANNELS   64
 #define MPC_DMA_TCD_OFFSET 0x1000
 
+/*
+ * Maximum channel counts for individual hardware variants
+ * and the maximum channel count over all supported controllers,
+ * used for data structure size
+ */
+#define MPC8308_DMACHAN_MAX16
+#define MPC512x_DMACHAN_MAX64
+#define MPC_DMA_CHANNELS   64
+
 /* Arbitration mode of group and channel */
 #define MPC_DMA_DMACR_EDCG (1  31)
 #define MPC_DMA_DMACR_ERGA (1  3)
@@ -710,10 +718,10 @@ static int mpc_dma_probe(struct platform_device *op)
 
dma = mdma-dma;
dma-dev = dev;
-   if (!mdma-is_mpc8308)
-   dma-chancnt = MPC_DMA_CHANNELS;
+   if (mdma-is_mpc8308)
+   dma-chancnt = MPC8308_DMACHAN_MAX;
else
-   dma-chancnt = 16; /* MPC8308 DMA has only 16 channels */
+   dma-chancnt = MPC512x_DMACHAN_MAX;
dma-device_alloc_chan_resources = mpc_dma_alloc_chan_resources;
dma-device_free_chan_resources = mpc_dma_free_chan_resources;
dma-device_issue_pending = mpc_dma_issue_pending;
@@ -747,7 +755,19 @@ static int mpc_dma_probe(struct platform_device *op)
 * - Round-robin group arbitration,
 * - Round-robin channel arbitration.
 */
-   if (!mdma-is_mpc8308) {
+   if (mdma-is_mpc8308) {
+   /* MPC8308 has 16 channels and lacks some registers */
+   out_be32(mdma-regs-dmacr, MPC_DMA_DMACR_ERCA);
+
+   /* enable snooping */
+   out_be32(mdma-regs-dmagpor, MPC_DMA_DMAGPOR_SNOOP_ENABLE);
+   /* Disable error interrupts */
+   out_be32(mdma-regs-dmaeeil, 0);
+
+   /* Clear interrupts status */
+   out_be32(mdma-regs-dmaintl, 0x);
+   out_be32(mdma-regs-dmaerrl, 0x);
+   } else {
out_be32(mdma-regs-dmacr, MPC_DMA_DMACR_EDCG |
MPC_DMA_DMACR_ERGA | 
MPC_DMA_DMACR_ERCA);
 
@@ -768,18 +788,6 @@ static int mpc_dma_probe(struct platform_device *op)
/* Route interrupts to IPIC */
out_be32(mdma-regs-dmaihsa, 0);
out_be32(mdma-regs-dmailsa, 0);
-   } else {
-   /* MPC8308 has 16 channels and lacks some registers */
-   out_be32(mdma-regs-dmacr, MPC_DMA_DMACR_ERCA);
-
-   /* enable snooping */
-   out_be32(mdma-regs-dmagpor, MPC_DMA_DMAGPOR_SNOOP_ENABLE);
-   /* Disable error interrupts */
-   out_be32(mdma-regs-dmaeeil, 0);
-
-   /* Clear interrupts status */
-   out_be32(mdma-regs-dmaintl, 0x);
-   out_be32(mdma-regs-dmaerrl, 0x);
}
 
/* Register DMA engine */
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v8 0/5] MPC512x DMA slave s/g support, OF DMA lookup

2014-02-24 Thread Alexander Popov
2013/7/14 Gerhard Sittig g...@denx.de:
 this series
 - introduces slave s/g support (that's support for DMA transfers which
involve peripherals in contrast to mem-to-mem transfers)
 - adds device tree based lookup support for DMA channels
 - combines floating patches and related feedback which already covered
several aspects of what the suggested LPB driver needs, to demonstrate
how integration might be done
 - carries QD SD card support to enable another DMA client during test,
while this patch needs to get dropped upon pickup

Changes in v2:
 - re-order mpc8308 related code paths for improved readability, no
change in behaviour, introduction of symbolic channel names here
already
 - squash 'execute() start condition' and 'terminate all' into the
introduction of 'slave s/g prep' and 'device control' support; refuse
s/g lists with more than one item since slave support is operational
yet proper s/g support is missing (can get addressed later)
 - always start transfers from software on MPC8308 as there are no
external request lines for peripheral flow control
 - drop dt-bindings header file and symbolic channel names in OF nodes

Changes in v3 and v4:
 Part 1/5:
 - use #define instead of enum since individual channels don't require
special handling.
 Part 2/5:
 - add a flag will_access_peripheral to DMA transfer descriptor
according recommendations of Gerhard Sittig.
This flag is set in mpc_dma_prep_memcpy() and mpc_dma_prep_slave_sg()
and is evaluated in mpc_dma_execute() to choose a type of start for
the transfer.
 - prevent descriptors of transfers which involve peripherals from
being chained together;
each of such transfers needs hardware initiated start.
 - add locking while working with struct mpc_dma_chan
according recommendations of Lars-Peter Clausen.
 - remove default nbytes value. Client kernel modules must set
src_maxburst and dst_maxburst fields of struct dma_slave_config 
(dmaengine.h).

Changes in v5:
 Part 2/5:
 - add and improve comments;
 - improve the code moving transfer descriptors from 'queued' to 'active' list
in mpc_dma_execute();
 - allow mpc_dma_prep_slave_sg() to run with non-empty 'active' list;
 - take 'mdesc' back to 'free' list in case of error in mpc_dma_prep_slave_sg();
 - improve checks of the transfer parameters;
 - provide the default value for 'maxburst' in mpc_dma_device_control().

Changes in v6:
 Part 2/5:
 - remove doubtful comment;
 - fix coding style issues;
 - set default value for 'maxburst' to 1 which applies to most cases;
 Part 3/5:
 - use dma_get_slave_channel() instead of dma_request_channel()
in new function of_dma_xlate_by_chan_id() according recommendations of
Arnd Bergmann;
 Part 4/5:
 - set DMA_PRIVATE flag for MPC512x DMA controller since its driver relies on
of_dma_xlate_by_chan_id() which doesn't use dma_request_channel()
any more; (removed in v7)
 - resolve little patch conflict;
 Part 5/5:
 - resolve little patch conflict;

Changes in v7:
 Part 2:
 - improve comment;
 Part 4:
 - split in two separate patches. Part 4/6 contains device tree
binding document and in part 5/6 MPC512x DMA controller is registered
for device tree channel lookup;
 - remove setting DMA_PRIVATE flag for MPC512x DMA controller from part 5/6;

Changes in v8:
 Part 2:
 - improve comments;
 - fix style issues;
 Part 6:
 - remove since it has become obsolete;

 known issues:
 - it's yet to get confirmed whether MPC8308 can use slave support or
whether the DMA controller's driver shall actively reject it, the
information that's available so far suggests that peripheral transfers
to IP bus attached I/O is useful and shall not get blocked right away
 - adding support for transfers which don't increment the RAM address or
do increment the peripheral port's address is easy with
this implementation; but which options of the common API
should be used for specifying such transfers?
2014/02/13 Gerhard Sittig g...@denx.de:
 - The MPC512x DMA completely lacks a binding document, so one
should get added.
 - The MPC8308 hardware is similar and can re-use the MPC512x
binding, which should be stated.
 - The Linux implementation currently has no OF based channel
lookup support, so '#dma-cells' is a future feature.  I guess
the binding can and should already discuss the feature,
regardless of whether all implementations support it.


Alexander Popov (3):
  dma: mpc512x: reorder mpc8308 specific instructions
  dma: mpc512x: add support for peripheral transfers
  dma: of: Add common xlate function for matching by channel id

Gerhard Sittig (2):
  dma: mpc512x: add device tree binding document
  dma: mpc512x: register for device tree channel lookup

 .../devicetree/bindings/dma/mpc512x-dma.txt|  55 
 arch/powerpc/boot/dts/mpc5121.dtsi |   1 +
 drivers/dma/mpc512x_dma.c  | 298

[PATCH RFC v8 2/5] dma: mpc512x: add support for peripheral transfers

2014-02-24 Thread Alexander Popov
Introduce support for slave s/g transfer preparation and the associated
device control callback in the MPC512x DMA controller driver, which adds
support for data transfers between memory and peripheral I/O to the
previously supported mem-to-mem transfers.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/mpc512x_dma.c | 235 +-
 1 file changed, 230 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 2ce248b..8f504cb 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -2,6 +2,7 @@
  * Copyright (C) Freescale Semicondutor, Inc. 2007, 2008.
  * Copyright (C) Semihalf 2009
  * Copyright (C) Ilya Yanok, Emcraft Systems 2010
+ * Copyright (C) Alexander Popov, Promcontroller 2013
  *
  * Written by Piotr Ziecik ko...@semihalf.com. Hardware description
  * (defines, structures and comments) was taken from MPC5121 DMA driver
@@ -29,8 +30,17 @@
  */
 
 /*
- * This is initial version of MPC5121 DMA driver. Only memory to memory
- * transfers are supported (tested using dmatest module).
+ * MPC512x and MPC8308 DMA driver. It supports
+ * memory to memory data transfers (tested using dmatest module) and
+ * data transfers between memory and peripheral I/O memory
+ * by means of slave s/g with these limitations:
+ *  - chunked transfers (transfers with more than one part) are refused
+ * as long as proper support for scatter/gather is missing;
+ *  - transfers on MPC8308 always start from software as this SoC appears
+ * not to have external request lines for peripheral flow control;
+ *  - minimal memory - I/O memory transfer chunk is 4 bytes and consequently
+ * source and destination addresses must be 4-byte aligned
+ * and transfer size must be aligned on (4 * maxburst) boundary;
  */
 
 #include linux/module.h
@@ -189,6 +199,7 @@ struct mpc_dma_desc {
dma_addr_t  tcd_paddr;
int error;
struct list_headnode;
+   int will_access_peripheral;
 };
 
 struct mpc_dma_chan {
@@ -201,6 +212,10 @@ struct mpc_dma_chan {
struct mpc_dma_tcd  *tcd;
dma_addr_t  tcd_paddr;
 
+   /* Settings for access to peripheral FIFO */
+   dma_addr_t  per_paddr;  /* FIFO address */
+   u32 tcd_nunits;
+
/* Lock for this structure */
spinlock_t  lock;
 };
@@ -251,8 +266,23 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)
struct mpc_dma_desc *mdesc;
int cid = mchan-chan.chan_id;
 
-   /* Move all queued descriptors to active list */
-   list_splice_tail_init(mchan-queued, mchan-active);
+   while (!list_empty(mchan-queued)) {
+   mdesc = list_first_entry(mchan-queued,
+   struct mpc_dma_desc, node);
+   /*
+* Grab either several mem-to-mem transfer descriptors
+* or one peripheral transfer descriptor,
+* don't mix mem-to-mem and peripheral transfer descriptors
+* within the same 'active' list.
+*/
+   if (mdesc-will_access_peripheral) {
+   if (list_empty(mchan-active))
+   list_move_tail(mdesc-node, mchan-active);
+   break;
+   } else {
+   list_move_tail(mdesc-node, mchan-active);
+   }
+   }
 
/* Chain descriptors into one transaction */
list_for_each_entry(mdesc, mchan-active, node) {
@@ -278,7 +308,17 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)
 
if (first != prev)
mdma-tcd[cid].e_sg = 1;
-   out_8(mdma-regs-dmassrt, cid);
+
+   if (mdma-is_mpc8308) {
+   /* MPC8308, no request lines, software initiated start */
+   out_8(mdma-regs-dmassrt, cid);
+   } else if (first-will_access_peripheral) {
+   /* peripherals involved, start by external request signal */
+   out_8(mdma-regs-dmaserq, cid);
+   } else {
+   /* memory to memory transfer, software initiated start */
+   out_8(mdma-regs-dmassrt, cid);
+   }
 }
 
 /* Handle interrupt on one half of DMA controller (32 channels) */
@@ -596,6 +636,7 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, 
dma_addr_t src,
}
 
mdesc-error = 0;
+   mdesc-will_access_peripheral = 0;
tcd = mdesc-tcd;
 
/* Prepare Transfer Control Descriptor for this transaction */
@@ -643,6 +684,187 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t 
dst, dma_addr_t src,
return mdesc-desc;
 }
 
+static struct dma_async_tx_descriptor *
+mpc_dma_prep_slave_sg(struct dma_chan *chan, struct

[PATCH RFC v8 3/5] dma: of: Add common xlate function for matching by channel id

2014-02-24 Thread Alexander Popov
This patch adds a new common OF dma xlate callback function which will match a
channel by it's id. The binding expects one integer argument which it will use 
to
lookup the channel by the id.

Unlike of_dma_simple_xlate this function is able to handle a system with
multiple DMA controllers. When registering the of dma provider with
of_dma_controller_register a pointer to the dma_device struct which is
associated with the dt node needs to passed as the data parameter.
New function will use this pointer to match only channels which belong to the
specified DMA controller.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/of-dma.c   | 35 +++
 include/linux/of_dma.h |  4 
 2 files changed, 39 insertions(+)

diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index e8fe9dc..d5fbeaa 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -218,3 +218,38 @@ struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_spec,
dma_spec-args[0]);
 }
 EXPORT_SYMBOL_GPL(of_dma_simple_xlate);
+
+/**
+ * of_dma_xlate_by_chan_id - Translate dt property to DMA channel by channel id
+ * @dma_spec:  pointer to DMA specifier as found in the device tree
+ * @of_dma:pointer to DMA controller data
+ *
+ * This function can be used as the of xlate callback for DMA driver which 
wants
+ * to match the channel based on the channel id. When using this xlate function
+ * the #dma-cells propety of the DMA controller dt node needs to be set to 1.
+ * The data parameter of of_dma_controller_register must be a pointer to the
+ * dma_device struct the function should match upon.
+ *
+ * Returns pointer to appropriate dma channel on success or NULL on error.
+ */
+struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
+struct of_dma *ofdma)
+{
+   struct dma_device *dev = ofdma-of_dma_data;
+   struct dma_chan *chan, *candidate = NULL;
+
+   if (!dev || dma_spec-args_count != 1)
+   return NULL;
+
+   list_for_each_entry(chan, dev-channels, device_node)
+   if (chan-chan_id == dma_spec-args[0]) {
+   candidate = chan;
+   break;
+   }
+
+   if (!candidate)
+   return NULL;
+
+   return dma_get_slave_channel(candidate);
+}
+EXPORT_SYMBOL_GPL(of_dma_xlate_by_chan_id);
diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
index ae36298..56bc026 100644
--- a/include/linux/of_dma.h
+++ b/include/linux/of_dma.h
@@ -41,6 +41,8 @@ extern struct dma_chan *of_dma_request_slave_channel(struct 
device_node *np,
 const char *name);
 extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma);
+extern struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args 
*dma_spec,
+   struct of_dma *ofdma);
 #else
 static inline int of_dma_controller_register(struct device_node *np,
struct dma_chan *(*of_dma_xlate)
@@ -66,6 +68,8 @@ static inline struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_s
return NULL;
 }
 
+#define of_dma_xlate_by_chan_id NULL
+
 #endif
 
 #endif /* __LINUX_OF_DMA_H */
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v8 4/5] dma: mpc512x: add device tree binding document

2014-02-24 Thread Alexander Popov
From: Gerhard Sittig g...@denx.de

introduce a device tree binding document for the MPC512x DMA controller

Signed-off-by: Gerhard Sittig g...@denx.de
[ a13xp0p0...@gmail.com: turn this into a separate patch ]
---
 .../devicetree/bindings/dma/mpc512x-dma.txt| 55 ++
 1 file changed, 55 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

diff --git a/Documentation/devicetree/bindings/dma/mpc512x-dma.txt 
b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
new file mode 100644
index 000..a4867d5
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
@@ -0,0 +1,55 @@
+* Freescale MPC512x DMA Controller
+
+The DMA controller in the Freescale MPC512x SoC can move blocks of
+memory contents between memory and peripherals or memory to memory.
+
+Refer to the Generic DMA Controller and DMA request bindings description
+in the dma.txt file for a more detailled discussion of the binding.  The
+MPC512x DMA engine binding follows the common scheme, but doesn't provide
+support for the optional channels and requests counters (those values are
+derived from the detected hardware features) and has a fixed client
+specifier length of 1 integer cell (the value is the DMA channel, since
+the DMA controller uses a fixed assignment of request lines per channel).
+
+
+DMA controller node properties:
+
+Required properties:
+- compatible:  should be fsl,mpc5121-dma
+- reg: address and size of the DMA controller's register set
+- interrupts:  interrupt spec for the DMA controller
+
+Optional properties:
+- #dma-cells:  must be 1, describes the number of integer cells
+   needed to specify the 'dmas' property in client nodes,
+   strongly recommended since common client helper code
+   uses this property
+
+Example:
+
+   dma0: dma@14000 {
+   compatible = fsl,mpc5121-dma;
+   reg = 0x14000 0x1800;
+   interrupts = 65 0x8;
+   #dma-cells = 1;
+   };
+
+
+Client node properties:
+
+Required properties:
+- dmas:list of DMA specifiers, consisting each of a 
handle
+   for the DMA controller and integer cells to specify
+   the channel used within the DMA controller
+- dma-names:   list of identifier strings for the DMA specifiers,
+   client device driver code uses these strings to
+   have DMA channels looked up at the controller
+
+Example:
+
+   sdhc@1500 {
+   compatible = fsl,mpc5121-sdhc;
+   /* ... */
+   dmas = dma0 30;
+   dma-names = rx-tx;
+   };
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH RFC v8 5/5] dma: mpc512x: register for device tree channel lookup

2014-02-24 Thread Alexander Popov
From: Gerhard Sittig g...@denx.de

register the controller for device tree based lookup of DMA channels
(non-fatal for backwards compatibility with older device trees) and
provide the '#dma-cells' property in the shared mpc5121.dtsi file

Signed-off-by: Gerhard Sittig g...@denx.de
[ a13xp0p0...@gmail.com: resolve little patch conflict and put
  MPC512x DMA controller bindings document to a separate patch ]
---
 arch/powerpc/boot/dts/mpc5121.dtsi |  1 +
 drivers/dma/mpc512x_dma.c  | 21 ++---
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi 
b/arch/powerpc/boot/dts/mpc5121.dtsi
index 2c0e155..7f9d14f 100644
--- a/arch/powerpc/boot/dts/mpc5121.dtsi
+++ b/arch/powerpc/boot/dts/mpc5121.dtsi
@@ -498,6 +498,7 @@
compatible = fsl,mpc5121-dma;
reg = 0x14000 0x1800;
interrupts = 65 0x8;
+   #dma-cells = 1;
};
};
 
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 8f504cb..d9f8740 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -52,6 +52,7 @@
 #include linux/of_address.h
 #include linux/of_device.h
 #include linux/of_irq.h
+#include linux/of_dma.h
 #include linux/of_platform.h
 
 #include linux/random.h
@@ -1018,11 +1019,23 @@ static int mpc_dma_probe(struct platform_device *op)
/* Register DMA engine */
dev_set_drvdata(dev, mdma);
retval = dma_async_device_register(dma);
-   if (retval) {
-   devm_free_irq(dev, mdma-irq, mdma);
-   irq_dispose_mapping(mdma-irq);
+   if (retval)
+   goto out_irq;
+
+   /* register with OF helpers for DMA lookups (nonfatal) */
+   if (dev-of_node) {
+   retval = of_dma_controller_register(dev-of_node,
+   of_dma_xlate_by_chan_id,
+   mdma);
+   if (retval)
+   dev_warn(dev, could not register for OF lookup\n);
}
 
+   return 0;
+
+out_irq:
+   devm_free_irq(dev, mdma-irq, mdma);
+   irq_dispose_mapping(mdma-irq);
return retval;
 }
 
@@ -1031,6 +1044,8 @@ static int mpc_dma_remove(struct platform_device *op)
struct device *dev = op-dev;
struct mpc_dma *mdma = dev_get_drvdata(dev);
 
+   if (dev-of_node)
+   of_dma_controller_free(dev-of_node);
dma_async_device_unregister(mdma-dma);
devm_free_irq(dev, mdma-irq, mdma);
irq_dispose_mapping(mdma-irq);
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH RFC v7 0/6] MPC512x DMA slave s/g support, OF DMA lookup

2014-02-19 Thread Alexander Popov
Hello, Gerhard

2014-02-13 4:32 GMT+04:00 Gerhard Sittig g...@denx.de:
 For some reason you have kept the DMA maintainers, but dropped
 the dmaengine ML from Cc: -- was this intentional, given that the
 series is specifically about DMA and you want to get feedback?
No, it was not done by intention, I'll fix that in the new version of the
series.

 And you may want to help DT people by not sending purely Linux
 implementation related stuff to them (they already are drinking
 from the firehose).  DT reviewers are foremost interested in
 bindings and policy and remaining OS agnostic, and leave
 mechanical .dts file updates to subsystem maintainers.
Do you mean I should better Cc to devicet...@vger.kernel.org
only parts 3, 4 and 5 of this series? How about cover letter?

Thank you.

Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH RFC v7 2/6] dma: mpc512x: add support for peripheral transfers

2014-02-19 Thread Alexander Popov
[ adding dmaengine ML to Cc: ]

Thanks for your feedback, Gerhard

2014-02-13 4:07 GMT+04:00 Gerhard Sittig g...@denx.de:
 On Wed, Feb 12, 2014 at 17:25 +0400, Alexander Popov wrote:
  /*
 - * This is initial version of MPC5121 DMA driver. Only memory to memory
 - * transfers are supported (tested using dmatest module).
 + * MPC512x and MPC8308 DMA driver. It supports
 + * memory to memory data transfers (tested using dmatest module) and
 + * data transfers between memory and peripheral I/O memory
 + * by means of slave s/g with these limitations:
 + * - chunked transfers (transfers with more than one part) are refused
 + * as long as proper support for scatter/gather is missing;
 + * - transfers on MPC8308 always start from software as this SoC appears
 + * not to have external request lines for peripheral flow control;
 + * - minimal memory - I/O memory transfer size is 4 bytes.
   */

 Often I assume people would notice themselves, and apparently I'm
 wrong. :)  Can you adjust the formatting such (here and
 elsewhere) that the bullet list is clearly visible as such?
 Flowing text like above obfuscates the fact that the content may
 have a structure ...
Ok, thanks :)

 There are known limitations which are not listed here, minimal
 transfer size is incomplete.  It appears that you assume
 constraints on start addresses as well as sizes/lengths.  Can you
 update the documentation to match the implementation?
Ok, I see. How about that?
* - minimal memory - I/O memory transfer chunk is 4 bytes and consequently
* source and destination addresses must be 4-byte aligned
* and transfer size must be aligned on (4 * maxburst) boundary;

 + /* Grab either several mem-to-mem transfer descriptors
 +  * or one peripheral transfer descriptor,
 +  * don't mix mem-to-mem and peripheral transfer descriptors
 +  * within the same 'active' list. */
 + if (mdesc-will_access_peripheral) {
 + if (list_empty(mchan-active))
 + list_move_tail(mdesc-node, mchan-active);
 + break;
 + } else
 + list_move_tail(mdesc-node, mchan-active);
 + }
 There are style issues.  Both in multi line comments, and in the
 braces of the if/else block.
Ah, thanks! I'll fix that.

 + struct mpc_dma *mdma = dma_chan_to_mpc_dma(chan);
 + struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan);
 + struct mpc_dma_desc *mdesc = NULL;
 + dma_addr_t per_paddr;
 + u32 tcd_nunits;
 + struct mpc_dma_tcd *tcd;
 + unsigned long iflags;
 + struct scatterlist *sg;
 + size_t len;
 + int iter, i;
 Personally I much dislike this style of mixing declarations and
 instructions.  But others may disagree, and strongly so.
Excuse me, I would like to keep it similar to other parts of this driver
and not to change that style.

 + mdesc = list_first_entry(mchan-free, struct mpc_dma_desc,
 + node);
 style (continuation and indentation)
Thanks! I'll fix that.


 + if (!mdesc) {
 + spin_unlock_irqrestore(mchan-lock, iflags);
 + /* try to free completed descriptors */
 + mpc_dma_process_completed(mdma);
 + return NULL;
 + }
 +
 + list_del(mdesc-node);
 +
 + per_paddr = mchan-per_paddr;
 + tcd_nunits = mchan-tcd_nunits;
 +
 + spin_unlock_irqrestore(mchan-lock, iflags);
 +
 + if (per_paddr == 0 || tcd_nunits == 0)
 + goto err_prep;
 +
 + mdesc-error = 0;
 + mdesc-will_access_peripheral = 1;
 + tcd = mdesc-tcd;
 +
 + /* Prepare Transfer Control Descriptor for this transaction */
 +
 + memset(tcd, 0, sizeof(struct mpc_dma_tcd));
 +
 + if (!IS_ALIGNED(sg_dma_address(sg), 4))
 + goto err_prep;

 You found multiple ways of encoding the 4 byte alignment, using
 both the fixed number as well as (several) symbolic identifiers.
 Can you look into making them use the same condition if the same
 motivation is behind the test?
Gerhard, I don't see checks which can be kind of merged
since they have different motivation behind:
1) src_addr_width and dst_addr_width have type enum dma_slave_buswidth
and are compared with DMA_SLAVE_BUSWIDTH_4_BYTES which has
the same type;
2) source and destination addresses are checked to be 4-byte aligned;
3) transfer size is checked to be aligned on nbytes boundary
which is (4 * maxburst).

I think the code provides good readability. What do you think?

Thank you!

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH RFC v7 1/6] dma: mpc512x: reorder mpc8308 specific instructions

2014-02-12 Thread Alexander Popov
Concentrate the specific code for MPC8308 in the 'if' branch
and handle MPC512x in the 'else' branch.
This modification only reorders instructions but doesn't change behaviour.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
Acked-by: Anatolij Gustschin ag...@denx.de
Acked-by: Gerhard Sittig g...@denx.de
---
 drivers/dma/mpc512x_dma.c | 42 +-
 1 file changed, 25 insertions(+), 17 deletions(-)

diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 448750d..2ce248b 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -52,9 +52,17 @@
 #define MPC_DMA_DESCRIPTORS64
 
 /* Macro definitions */
-#define MPC_DMA_CHANNELS   64
 #define MPC_DMA_TCD_OFFSET 0x1000
 
+/*
+ * Maximum channel counts for individual hardware variants
+ * and the maximum channel count over all supported controllers,
+ * used for data structure size
+ */
+#define MPC8308_DMACHAN_MAX16
+#define MPC512x_DMACHAN_MAX64
+#define MPC_DMA_CHANNELS   64
+
 /* Arbitration mode of group and channel */
 #define MPC_DMA_DMACR_EDCG (1  31)
 #define MPC_DMA_DMACR_ERGA (1  3)
@@ -710,10 +718,10 @@ static int mpc_dma_probe(struct platform_device *op)
 
dma = mdma-dma;
dma-dev = dev;
-   if (!mdma-is_mpc8308)
-   dma-chancnt = MPC_DMA_CHANNELS;
+   if (mdma-is_mpc8308)
+   dma-chancnt = MPC8308_DMACHAN_MAX;
else
-   dma-chancnt = 16; /* MPC8308 DMA has only 16 channels */
+   dma-chancnt = MPC512x_DMACHAN_MAX;
dma-device_alloc_chan_resources = mpc_dma_alloc_chan_resources;
dma-device_free_chan_resources = mpc_dma_free_chan_resources;
dma-device_issue_pending = mpc_dma_issue_pending;
@@ -747,7 +755,19 @@ static int mpc_dma_probe(struct platform_device *op)
 * - Round-robin group arbitration,
 * - Round-robin channel arbitration.
 */
-   if (!mdma-is_mpc8308) {
+   if (mdma-is_mpc8308) {
+   /* MPC8308 has 16 channels and lacks some registers */
+   out_be32(mdma-regs-dmacr, MPC_DMA_DMACR_ERCA);
+
+   /* enable snooping */
+   out_be32(mdma-regs-dmagpor, MPC_DMA_DMAGPOR_SNOOP_ENABLE);
+   /* Disable error interrupts */
+   out_be32(mdma-regs-dmaeeil, 0);
+
+   /* Clear interrupts status */
+   out_be32(mdma-regs-dmaintl, 0x);
+   out_be32(mdma-regs-dmaerrl, 0x);
+   } else {
out_be32(mdma-regs-dmacr, MPC_DMA_DMACR_EDCG |
MPC_DMA_DMACR_ERGA | 
MPC_DMA_DMACR_ERCA);
 
@@ -768,18 +788,6 @@ static int mpc_dma_probe(struct platform_device *op)
/* Route interrupts to IPIC */
out_be32(mdma-regs-dmaihsa, 0);
out_be32(mdma-regs-dmailsa, 0);
-   } else {
-   /* MPC8308 has 16 channels and lacks some registers */
-   out_be32(mdma-regs-dmacr, MPC_DMA_DMACR_ERCA);
-
-   /* enable snooping */
-   out_be32(mdma-regs-dmagpor, MPC_DMA_DMAGPOR_SNOOP_ENABLE);
-   /* Disable error interrupts */
-   out_be32(mdma-regs-dmaeeil, 0);
-
-   /* Clear interrupts status */
-   out_be32(mdma-regs-dmaintl, 0x);
-   out_be32(mdma-regs-dmaerrl, 0x);
}
 
/* Register DMA engine */
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH RFC v7 0/6] MPC512x DMA slave s/g support, OF DMA lookup

2014-02-12 Thread Alexander Popov
v2013/7/14 Gerhard Sittig g...@denx.de:
 this series
 - introduces slave s/g support (that's support for DMA transfers which
involve peripherals in contrast to mem-to-mem transfers)
 - adds device tree based lookup support for DMA channels
 - combines floating patches and related feedback which already covered
several aspects of what the suggested LPB driver needs, to demonstrate
how integration might be done
 - carries QD SD card support to enable another DMA client during test,
while this patch needs to get dropped upon pickup

Changes in v2:
 - re-order mpc8308 related code paths for improved readability, no
change in behaviour, introduction of symbolic channel names here
already
 - squash 'execute() start condition' and 'terminate all' into the
introduction of 'slave s/g prep' and 'device control' support; refuse
s/g lists with more than one item since slave support is operational
yet proper s/g support is missing (can get addressed later)
 - always start transfers from software on MPC8308 as there are no
external request lines for peripheral flow control
 - drop dt-bindings header file and symbolic channel names in OF nodes

Changes in v3 and v4:
 Part 1/5:
 - use #define instead of enum since individual channels don't require
special handling.
 Part 2/5:
 - add a flag will_access_peripheral to DMA transfer descriptor
according recommendations of Gerhard Sittig.
This flag is set in mpc_dma_prep_memcpy() and mpc_dma_prep_slave_sg()
and is evaluated in mpc_dma_execute() to choose a type of start for
the transfer.
 - prevent descriptors of transfers which involve peripherals from
being chained together;
each of such transfers needs hardware initiated start.
 - add locking while working with struct mpc_dma_chan
according recommendations of Lars-Peter Clausen.
 - remove default nbytes value. Client kernel modules must set
src_maxburst and dst_maxburst fields of struct dma_slave_config 
(dmaengine.h).

Changes in v5:
 Part 2/5:
 - add and improve comments;
 - improve the code moving transfer descriptors from 'queued' to 'active' list
in mpc_dma_execute();
 - allow mpc_dma_prep_slave_sg() to run with non-empty 'active' list;
 - take 'mdesc' back to 'free' list in case of error in mpc_dma_prep_slave_sg();
 - improve checks of the transfer parameters;
 - provide the default value for 'maxburst' in mpc_dma_device_control().

Changes in v6:
 Part 2/5:
 - remove doubtful comment;
 - fix coding style issues;
 - set default value for 'maxburst' to 1 which applies to most cases;
 Part 3/5:
 - use dma_get_slave_channel() instead of dma_request_channel()
in new function of_dma_xlate_by_chan_id() according recommendations of
Arnd Bergmann;
 Part 4/5:
 - set DMA_PRIVATE flag for MPC512x DMA controller since its driver relies on
of_dma_xlate_by_chan_id() which doesn't use dma_request_channel()
any more; (removed in v7)
 - resolve little patch conflict;
 Part 5/5:
 - resolve little patch conflict;

Changes in v7:
 Part 2:
 - improve comment;
 Part 4:
 - split in two separate patches. Part 4/6 contains device tree
binding document and in part 5/6 MPC512x DMA controller is registered
for device tree channel lookup;
 - remove setting DMA_PRIVATE flag for MPC512x DMA controller from part 5/6;

 known issues:
 - it's yet to get confirmed whether MPC8308 can use slave support or
whether the DMA controller's driver shall actively reject it, the
information that's available so far suggests that peripheral transfers
to IP bus attached I/O is useful and shall not get blocked right away
 - adding support for transfers which don't increment the RAM address or
do increment the peripheral port's address is easy with
this implementation; but which options of the common API
should be used for specifying such transfers?
 - device tree binding document for the MPC512x DMA controller needs
to be improved.


Alexander Popov (3):
  dma: mpc512x: reorder mpc8308 specific instructions
  dma: mpc512x: add support for peripheral transfers
  dma: of: Add common xlate function for matching by channel id

Gerhard Sittig (3):
  dma: mpc512x: add device tree binding document
  dma: mpc512x: register for device tree channel lookup
  HACK mmc: mxcmmc: enable clocks for the MPC512x

 .../devicetree/bindings/dma/mpc512x-dma.txt|  55 
 arch/powerpc/boot/dts/mpc5121.dtsi |   1 +
 drivers/dma/mpc512x_dma.c  | 293 +++--
 drivers/dma/of-dma.c   |  35 +++
 drivers/mmc/host/mxcmmc.c  |  42 ++-
 include/linux/of_dma.h |   4 +
 6 files changed, 391 insertions(+), 39 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https

[PATCH RFC v7 2/6] dma: mpc512x: add support for peripheral transfers

2014-02-12 Thread Alexander Popov
Introduce support for slave s/g transfer preparation and the associated
device control callback in the MPC512x DMA controller driver, which adds
support for data transfers between memory and peripheral I/O to the
previously supported mem-to-mem transfers.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/mpc512x_dma.c | 230 +-
 1 file changed, 225 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 2ce248b..b978ef1 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -2,6 +2,7 @@
  * Copyright (C) Freescale Semicondutor, Inc. 2007, 2008.
  * Copyright (C) Semihalf 2009
  * Copyright (C) Ilya Yanok, Emcraft Systems 2010
+ * Copyright (C) Alexander Popov, Promcontroller 2013
  *
  * Written by Piotr Ziecik ko...@semihalf.com. Hardware description
  * (defines, structures and comments) was taken from MPC5121 DMA driver
@@ -29,8 +30,15 @@
  */
 
 /*
- * This is initial version of MPC5121 DMA driver. Only memory to memory
- * transfers are supported (tested using dmatest module).
+ * MPC512x and MPC8308 DMA driver. It supports
+ * memory to memory data transfers (tested using dmatest module) and
+ * data transfers between memory and peripheral I/O memory
+ * by means of slave s/g with these limitations:
+ * - chunked transfers (transfers with more than one part) are refused
+ * as long as proper support for scatter/gather is missing;
+ * - transfers on MPC8308 always start from software as this SoC appears
+ * not to have external request lines for peripheral flow control;
+ * - minimal memory - I/O memory transfer size is 4 bytes.
  */
 
 #include linux/module.h
@@ -189,6 +197,7 @@ struct mpc_dma_desc {
dma_addr_t  tcd_paddr;
int error;
struct list_headnode;
+   int will_access_peripheral;
 };
 
 struct mpc_dma_chan {
@@ -201,6 +210,10 @@ struct mpc_dma_chan {
struct mpc_dma_tcd  *tcd;
dma_addr_t  tcd_paddr;
 
+   /* Settings for access to peripheral FIFO */
+   dma_addr_t  per_paddr;  /* FIFO address */
+   u32 tcd_nunits;
+
/* Lock for this structure */
spinlock_t  lock;
 };
@@ -251,8 +264,21 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)
struct mpc_dma_desc *mdesc;
int cid = mchan-chan.chan_id;
 
-   /* Move all queued descriptors to active list */
-   list_splice_tail_init(mchan-queued, mchan-active);
+   while (!list_empty(mchan-queued)) {
+   mdesc = list_first_entry(mchan-queued,
+   struct mpc_dma_desc, node);
+
+   /* Grab either several mem-to-mem transfer descriptors
+* or one peripheral transfer descriptor,
+* don't mix mem-to-mem and peripheral transfer descriptors
+* within the same 'active' list. */
+   if (mdesc-will_access_peripheral) {
+   if (list_empty(mchan-active))
+   list_move_tail(mdesc-node, mchan-active);
+   break;
+   } else
+   list_move_tail(mdesc-node, mchan-active);
+   }
 
/* Chain descriptors into one transaction */
list_for_each_entry(mdesc, mchan-active, node) {
@@ -278,7 +304,17 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)
 
if (first != prev)
mdma-tcd[cid].e_sg = 1;
-   out_8(mdma-regs-dmassrt, cid);
+
+   if (mdma-is_mpc8308) {
+   /* MPC8308, no request lines, software initiated start */
+   out_8(mdma-regs-dmassrt, cid);
+   } else if (first-will_access_peripheral) {
+   /* peripherals involved, start by external request signal */
+   out_8(mdma-regs-dmaserq, cid);
+   } else {
+   /* memory to memory transfer, software initiated start */
+   out_8(mdma-regs-dmassrt, cid);
+   }
 }
 
 /* Handle interrupt on one half of DMA controller (32 channels) */
@@ -596,6 +632,7 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, 
dma_addr_t src,
}
 
mdesc-error = 0;
+   mdesc-will_access_peripheral = 0;
tcd = mdesc-tcd;
 
/* Prepare Transfer Control Descriptor for this transaction */
@@ -643,6 +680,186 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t 
dst, dma_addr_t src,
return mdesc-desc;
 }
 
+static struct dma_async_tx_descriptor *
+mpc_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+   unsigned int sg_len, enum dma_transfer_direction direction,
+   unsigned long flags, void *context)
+{
+   struct mpc_dma *mdma = dma_chan_to_mpc_dma(chan);
+   struct

[PATCH RFC v7 3/6] dma: of: Add common xlate function for matching by channel id

2014-02-12 Thread Alexander Popov
This patch adds a new common OF dma xlate callback function which will match a
channel by it's id. The binding expects one integer argument which it will use 
to
lookup the channel by the id.

Unlike of_dma_simple_xlate this function is able to handle a system with
multiple DMA controllers. When registering the of dma provider with
of_dma_controller_register a pointer to the dma_device struct which is
associated with the dt node needs to passed as the data parameter.
New function will use this pointer to match only channels which belong to the
specified DMA controller.

Signed-off-by: Alexander Popov a13xp0p0...@gmail.com
---
 drivers/dma/of-dma.c   | 35 +++
 include/linux/of_dma.h |  4 
 2 files changed, 39 insertions(+)

diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index e8fe9dc..d5fbeaa 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -218,3 +218,38 @@ struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_spec,
dma_spec-args[0]);
 }
 EXPORT_SYMBOL_GPL(of_dma_simple_xlate);
+
+/**
+ * of_dma_xlate_by_chan_id - Translate dt property to DMA channel by channel id
+ * @dma_spec:  pointer to DMA specifier as found in the device tree
+ * @of_dma:pointer to DMA controller data
+ *
+ * This function can be used as the of xlate callback for DMA driver which 
wants
+ * to match the channel based on the channel id. When using this xlate function
+ * the #dma-cells propety of the DMA controller dt node needs to be set to 1.
+ * The data parameter of of_dma_controller_register must be a pointer to the
+ * dma_device struct the function should match upon.
+ *
+ * Returns pointer to appropriate dma channel on success or NULL on error.
+ */
+struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
+struct of_dma *ofdma)
+{
+   struct dma_device *dev = ofdma-of_dma_data;
+   struct dma_chan *chan, *candidate = NULL;
+
+   if (!dev || dma_spec-args_count != 1)
+   return NULL;
+
+   list_for_each_entry(chan, dev-channels, device_node)
+   if (chan-chan_id == dma_spec-args[0]) {
+   candidate = chan;
+   break;
+   }
+
+   if (!candidate)
+   return NULL;
+
+   return dma_get_slave_channel(candidate);
+}
+EXPORT_SYMBOL_GPL(of_dma_xlate_by_chan_id);
diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
index ae36298..56bc026 100644
--- a/include/linux/of_dma.h
+++ b/include/linux/of_dma.h
@@ -41,6 +41,8 @@ extern struct dma_chan *of_dma_request_slave_channel(struct 
device_node *np,
 const char *name);
 extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma);
+extern struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args 
*dma_spec,
+   struct of_dma *ofdma);
 #else
 static inline int of_dma_controller_register(struct device_node *np,
struct dma_chan *(*of_dma_xlate)
@@ -66,6 +68,8 @@ static inline struct dma_chan *of_dma_simple_xlate(struct 
of_phandle_args *dma_s
return NULL;
 }
 
+#define of_dma_xlate_by_chan_id NULL
+
 #endif
 
 #endif /* __LINUX_OF_DMA_H */
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH RFC v7 4/6] dma: mpc512x: add device tree binding document

2014-02-12 Thread Alexander Popov
From: Gerhard Sittig g...@denx.de

introduce a device tree binding document for the MPC512x DMA controller

Signed-off-by: Gerhard Sittig g...@denx.de
[ a13xp0p0...@gmail.com: turn this into a separate patch ]
---
 .../devicetree/bindings/dma/mpc512x-dma.txt| 55 ++
 1 file changed, 55 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt

diff --git a/Documentation/devicetree/bindings/dma/mpc512x-dma.txt 
b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
new file mode 100644
index 000..a4867d5
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
@@ -0,0 +1,55 @@
+* Freescale MPC512x DMA Controller
+
+The DMA controller in the Freescale MPC512x SoC can move blocks of
+memory contents between memory and peripherals or memory to memory.
+
+Refer to the Generic DMA Controller and DMA request bindings description
+in the dma.txt file for a more detailled discussion of the binding.  The
+MPC512x DMA engine binding follows the common scheme, but doesn't provide
+support for the optional channels and requests counters (those values are
+derived from the detected hardware features) and has a fixed client
+specifier length of 1 integer cell (the value is the DMA channel, since
+the DMA controller uses a fixed assignment of request lines per channel).
+
+
+DMA controller node properties:
+
+Required properties:
+- compatible:  should be fsl,mpc5121-dma
+- reg: address and size of the DMA controller's register set
+- interrupts:  interrupt spec for the DMA controller
+
+Optional properties:
+- #dma-cells:  must be 1, describes the number of integer cells
+   needed to specify the 'dmas' property in client nodes,
+   strongly recommended since common client helper code
+   uses this property
+
+Example:
+
+   dma0: dma@14000 {
+   compatible = fsl,mpc5121-dma;
+   reg = 0x14000 0x1800;
+   interrupts = 65 0x8;
+   #dma-cells = 1;
+   };
+
+
+Client node properties:
+
+Required properties:
+- dmas:list of DMA specifiers, consisting each of a 
handle
+   for the DMA controller and integer cells to specify
+   the channel used within the DMA controller
+- dma-names:   list of identifier strings for the DMA specifiers,
+   client device driver code uses these strings to
+   have DMA channels looked up at the controller
+
+Example:
+
+   sdhc@1500 {
+   compatible = fsl,mpc5121-sdhc;
+   /* ... */
+   dmas = dma0 30;
+   dma-names = rx-tx;
+   };
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH RFC v7 5/6] dma: mpc512x: register for device tree channel lookup

2014-02-12 Thread Alexander Popov
From: Gerhard Sittig g...@denx.de

register the controller for device tree based lookup of DMA channels
(non-fatal for backwards compatibility with older device trees) and
provide the '#dma-cells' property in the shared mpc5121.dtsi file

Signed-off-by: Gerhard Sittig g...@denx.de
[ a13xp0p0...@gmail.com: resolve little patch conflict and put
  MPC512x DMA controller bindings document to a separate patch ]
---
 arch/powerpc/boot/dts/mpc5121.dtsi |  1 +
 drivers/dma/mpc512x_dma.c  | 21 ++---
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi 
b/arch/powerpc/boot/dts/mpc5121.dtsi
index 2c0e155..7f9d14f 100644
--- a/arch/powerpc/boot/dts/mpc5121.dtsi
+++ b/arch/powerpc/boot/dts/mpc5121.dtsi
@@ -498,6 +498,7 @@
compatible = fsl,mpc5121-dma;
reg = 0x14000 0x1800;
interrupts = 65 0x8;
+   #dma-cells = 1;
};
};
 
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index b978ef1..1e0b8cf 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -50,6 +50,7 @@
 #include linux/of_address.h
 #include linux/of_device.h
 #include linux/of_irq.h
+#include linux/of_dma.h
 #include linux/of_platform.h
 
 #include linux/random.h
@@ -1013,11 +1014,23 @@ static int mpc_dma_probe(struct platform_device *op)
/* Register DMA engine */
dev_set_drvdata(dev, mdma);
retval = dma_async_device_register(dma);
-   if (retval) {
-   devm_free_irq(dev, mdma-irq, mdma);
-   irq_dispose_mapping(mdma-irq);
+   if (retval)
+   goto out_irq;
+
+   /* register with OF helpers for DMA lookups (nonfatal) */
+   if (dev-of_node) {
+   retval = of_dma_controller_register(dev-of_node,
+   of_dma_xlate_by_chan_id,
+   mdma);
+   if (retval)
+   dev_warn(dev, could not register for OF lookup\n);
}
 
+   return 0;
+
+out_irq:
+   devm_free_irq(dev, mdma-irq, mdma);
+   irq_dispose_mapping(mdma-irq);
return retval;
 }
 
@@ -1026,6 +1039,8 @@ static int mpc_dma_remove(struct platform_device *op)
struct device *dev = op-dev;
struct mpc_dma *mdma = dev_get_drvdata(dev);
 
+   if (dev-of_node)
+   of_dma_controller_free(dev-of_node);
dma_async_device_unregister(mdma-dma);
devm_free_irq(dev, mdma-irq, mdma);
irq_dispose_mapping(mdma-irq);
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH RFC v7 6/6] HACK mmc: mxcmmc: enable clocks for the MPC512x

2014-02-12 Thread Alexander Popov
From: Gerhard Sittig g...@denx.de

QD HACK to enable SD card support without correct COMMON_CLK support,
best viewed with 'git diff -w -b', NOT acceptable for mainline (NAKed)

Signed-off-by: Gerhard Sittig g...@denx.de
[ a13xp0p0...@gmail.com: resolve little patch conflict ]
---
 drivers/mmc/host/mxcmmc.c | 42 --
 1 file changed, 28 insertions(+), 14 deletions(-)

diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index f7199c8..ddefa60 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -1123,20 +1123,29 @@ static int mxcmci_probe(struct platform_device *pdev)
host-res = r;
host-irq = irq;
 
-   host-clk_ipg = devm_clk_get(pdev-dev, ipg);
-   if (IS_ERR(host-clk_ipg)) {
-   ret = PTR_ERR(host-clk_ipg);
-   goto out_iounmap;
-   }
+   if (!is_mpc512x_mmc(host)) {
+   host-clk_ipg = devm_clk_get(pdev-dev, ipg);
+   if (IS_ERR(host-clk_ipg)) {
+   ret = PTR_ERR(host-clk_ipg);
+   goto out_iounmap;
+   }
 
-   host-clk_per = devm_clk_get(pdev-dev, per);
-   if (IS_ERR(host-clk_per)) {
-   ret = PTR_ERR(host-clk_per);
-   goto out_iounmap;
+   host-clk_per = devm_clk_get(pdev-dev, per);
+   if (IS_ERR(host-clk_per)) {
+   ret = PTR_ERR(host-clk_per);
+   goto out_iounmap;
+   }
+   } else {
+   host-clk_per = devm_clk_get(pdev-dev, sdhc_clk);
+   if (IS_ERR(host-clk_per)) {
+   ret = PTR_ERR(host-clk_per);
+   goto out_iounmap;
+   }
}
 
clk_prepare_enable(host-clk_per);
-   clk_prepare_enable(host-clk_ipg);
+   if (host-clk_ipg)
+   clk_prepare_enable(host-clk_ipg);
 
mxcmci_softreset(host);
 
@@ -1206,7 +1215,8 @@ out_free_dma:
dma_release_channel(host-dma);
 out_clk_put:
clk_disable_unprepare(host-clk_per);
-   clk_disable_unprepare(host-clk_ipg);
+   if (host-clk_ipg)
+   clk_disable_unprepare(host-clk_ipg);
 out_iounmap:
iounmap(host-base);
 out_free:
@@ -1236,7 +1246,8 @@ static int mxcmci_remove(struct platform_device *pdev)
dma_release_channel(host-dma);
 
clk_disable_unprepare(host-clk_per);
-   clk_disable_unprepare(host-clk_ipg);
+   if (host-clk_ipg)
+   clk_disable_unprepare(host-clk_ipg);
 
release_mem_region(host-res-start, resource_size(host-res));
 
@@ -1252,7 +1263,9 @@ static int mxcmci_suspend(struct device *dev)
struct mxcmci_host *host = mmc_priv(mmc);
 
clk_disable_unprepare(host-clk_per);
-   clk_disable_unprepare(host-clk_ipg);
+   if (host-clk_ipg)
+   clk_disable_unprepare(host-clk_ipg);
+
return 0;
 }
 
@@ -1262,7 +1275,8 @@ static int mxcmci_resume(struct device *dev)
struct mxcmci_host *host = mmc_priv(mmc);
 
clk_prepare_enable(host-clk_per);
-   clk_prepare_enable(host-clk_ipg);
+   if (host-clk_ipg)
+   clk_prepare_enable(host-clk_ipg);
return 0;
 }
 
-- 
1.8.4.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH RFC v6 4/5] dma: mpc512x: register for device tree channel lookup

2014-01-13 Thread Alexander Popov
Thanks for your replies, Gerhard and Vinod.

2014/1/9 Vinod Koul vinod.k...@intel.com:
 On Wed, Jan 08, 2014 at 05:47:19PM +0100, Gerhard Sittig wrote:
 [ what is the semantics of DMA_PRIVATE capability flag?
   is documentation available beyond the initial commit message?
   need individual channels be handled instead of controllers? ]

 The DMA_PRIVATE means that your channels are not to be used for global memcpy,
 as one can do in async cases (this is hwere DMAengine came into existence)

 If the device has the capablity of doing genric memcpy then it should not set
 this. For slave dma usage the dam channel can transfer data to a specfic
 slave device(s), hence we should use this is geric fashion so setting
 DMA_PRIVATE makes sense in those cases.

Each DMA channel of MPC512x DMA controller can do _both_
mem-to-mem transfers and transfers between mem and some slave peripheral
(only one DMA channel is fully dedicated to DDR).
All DMA channels of MPC512x DMA controller belong to one dma_device.
So we _don't_ need setting DMA_PRIVATE flag for this dma_device at all, do we?

 On Sat, Jan 04, 2014 at 00:54 +0400, Alexander Popov wrote:
  I've involved DMA_PRIVATE flag because new of_dma_xlate_by_chan_id()
  uses dma_get_slave_channel() instead of dma_request_channel()
  (PATCH RFC v6 3/5). This flag is implicitly set in dma_request_channel(),
  but is not set in dma_get_slave_channel().
 Which makes me thing you are targetting slave usages. Do you intend to use for
 mempcy too on all controllers you support. in that case you should set it
 selectively.

Vinod, please correct me if I'm wrong.
As I could understand from your comments and the code,
DMA_PRIVATE flag is needed for dma_devices with DMA channels
which _can_ work with slave peripheral but _can't_ do mem-to-mem transfers.
If DMA_PRIVATE flag is set for some dma_device before
dma_async_device_register()
then its DMA channels are not published in tables for kernel slab allocator
(because these channels are simply useless for memcpy).

 Still I see a difference in the lookup approaches:  Yours applies
 DMA_PRIVATE globally and in advance, preventing _any_ use of DMA
 for memory transfers.  While the __dma_request_channel() routine
 only applies it _temporarily_ around a dma_chan_get() operation.
 Allowing for use of DMA channels by both individual peripherals
 as well as memory transfers.

 No it doesnt prevent. You can still use it for memcpy once you have the 
 channel.

Excuse me, I don't completely understand why dma_request_channel()
needs to set DMA_PRIVATE flag.
If dma_request_channel() for some dma_device without DMA_PRIVATE
is called before the first dmaengine_get()
then no DMA channels of this dma_device will become available for memcpy
by slab allocator.
Could you give me a clue?

   Consider the fact that this driver
   handles both MPC5121 as well as MPC8308 hardware.
 
  Ah, yes, sorry. I should certainly fix this, if setting of DMA_PRIVATE flag
  is needed at all.

 What I meant here is that implications for all affected platforms
 should be considered.  There is one driver source, but the driver
 applies to more than one platform (another issue of the driver is
 that this is not apparent from the doc nor the compat strings).

I'll add a comment with information about the supported platforms to
mpc512x_dma.c
in RFC PATCH 1/5. Ok?

 So blocking memory transfers in mpc512x_dma.c is a total breakage
 for MPC8308 (removes the only previous feature and adds nothing),
 and is a regression for MPC512x (removes the previously supported
 memory transfers, while it may add peripheral supports with very
 few users).

Yes, I see. MPC512x and MPC8308 should be treated differently.

Thanks!
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH RFC v6 4/5] dma: mpc512x: register for device tree channel lookup

2014-01-03 Thread Alexander Popov
Hello Gerhard.
Thanks for your review.

2013/12/26 Gerhard Sittig g...@denx.de:
 [ dropping devicetree, we're DMA specific here ]

 On Tue, Dec 24, 2013 at 16:06 +0400, Alexander Popov wrote:

 --- a/drivers/dma/mpc512x_dma.c
 +++ b/drivers/dma/mpc512x_dma.c
 [ ... ]
 @@ -950,6 +951,7 @@ static int mpc_dma_probe(struct platform_device *op)
   INIT_LIST_HEAD(dma-channels);
   dma_cap_set(DMA_MEMCPY, dma-cap_mask);
   dma_cap_set(DMA_SLAVE, dma-cap_mask);
 + dma_cap_set(DMA_PRIVATE, dma-cap_mask);

   for (i = 0; i  dma-chancnt; i++) {
   mchan = mdma-channels[i];

 What are the implications of this?  Is a comment due?

I've involved DMA_PRIVATE flag because new of_dma_xlate_by_chan_id()
uses dma_get_slave_channel() instead of dma_request_channel()
(PATCH RFC v6 3/5). This flag is implicitly set in dma_request_channel(),
but is not set in dma_get_slave_channel().

There are only two places in the mainline kernel, where
dma_get_slave_channel() is used. I've picked up the idea
at one of these places. Please look at this patch:
http://www.spinics.net/lists/arm-kernel/msg268718.html

 I haven't found documentation about the DMA_PRIVATE flag, only
 saw commit 59b5ec21446b9 dmaengine: introduce
 dma_request_channel and private channels.

Unfortunately I didn't find any description of DMA_PRIVATE flag too.
But the comment at the beginning of drivers/dma/dmaengine.c
may give a clue. Quotation:
  * subsystem can get access to a channel by calling dmaengine_get() followed
  * by dma_find_channel(), or if it has need for an exclusive channel
it can call
  * dma_request_channel().  Once a channel is allocated a reference is taken
  * against its corresponding driver to disable removal.

DMA_PRIVATE capability flag might indicate that the DMA controller
can provide exclusive channels to its clients. Please correct me if I'm wrong.

 Alex, unless I'm
 missing something this one-line change is quite a change in
 semantics, and has dramatic influence on the code's behaviour
 (ignores the DMA controller when looking for channels that can do
 mem-to-mem transfers)

Excuse me, Gerhard, I don't see what you mean.
Could you point to the corresponding code?

 Consider the fact that this driver
 handles both MPC5121 as well as MPC8308 hardware.

Ah, yes, sorry. I should certainly fix this, if setting of DMA_PRIVATE flag
is needed at all.

Thanks!

Best regards,
Alexander
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


  1   2   >