Re: [spi-devel-general] [PATCH v1 3/4] max3100: adds console support for MAX3100

2010-03-29 Thread christian pellegrin
On Mon, Mar 29, 2010 at 4:48 AM, Feng Tang feng.t...@intel.com wrote:
 Hi,

Hi,


 I modified the code a little and run it on our HW platform, it really show
 some sigh of life: it can boots to console (the print format is not so good),
 I can input command and it execute correctly, but very slow, I type 3
 characters and it takes about 2 seconds to echo back on screen and start the
 execution, and after about 1 minute, the console hang there and input stopped
 to work.

never seen such a behavior. Which platform are you using? Which SPI
driver? Do you have a low level printk (printascii) that puts output
somewhere else so I can send you a patch with some debugging output?
Can you log in some other way (like via network) and see if the CPU
load is at 100% for some reason?

 This patch adds console support for the MAX3100 UART
 (console=ttyMAX0,11500). The SPI subsystem and an

 115200?


ack

 Does this imply to have to work with HW flow control? on my platform
 I have to remove the RTS bit to make it work.


no, I put RTS on  because it looks like a good default. I can make it
configurable. I just noticed on the data sheet that RTS is actually
inverted so a more sensible default would be to put it off. For
testing you should have flow control set to none on the machine you
are using as a terminal emulator.

 +             max3100_sr(s, tx, rx);

 It doesn't handle received characters here? If the console is printing out
 a bulk of message while user input some command, the command may be ignored.
 Myself have met the same problem in our driver.


yes but I think it's quite difficult to solve this problem in every
case. Console output is massively used only on boot when the user is
not supposed to type a lot.

 +     if (next != s-console_tail) {
 +             s-console_buf[next] = ch;
 +             s-console_head = next;
 +     }

 Also I saw max3100_sr() uses cpu_to_be16() and be16_to_cpu(), is it really
 necessary, our platform is little-endian(x86), and I have to disable them
 to make the code work. Is your test platform big-endian?


Have you configured your SPI controller as LSB first somehow, haven't
you? BTW my platform is a quite usual ARM9 S3C2440 which is little
endian.


-- 
Christian Pellegrin, see http://www.evolware.org/chri/
Real Programmers don't play tennis, or any other sport which requires
you to change clothes. Mountain climbing is OK, and Real Programmers
wear their climbing boots to work in case a mountain should suddenly
spring up in the middle of the computer room.

--
Download Intel#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
___
spi-devel-general mailing list
spi-devel-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spi-devel-general


Re: [spi-devel-general] [PATCH v1 3/4] max3100: adds console support for MAX3100

2010-03-29 Thread Feng Tang
On Mon, 29 Mar 2010 14:11:15 +0800
christian pellegrin chrip...@fsfe.org wrote:

  I modified the code a little and run it on our HW platform, it
  really show some sigh of life: it can boots to console (the print
  format is not so good), I can input command and it execute
  correctly, but very slow, I type 3 characters and it takes about 2
  seconds to echo back on screen and start the execution, and after
  about 1 minute, the console hang there and input stopped to work.
 
 never seen such a behavior. Which platform are you using? Which SPI
 driver? Do you have a low level printk (printascii) that puts output
 somewhere else so I can send you a patch with some debugging output?
 Can you log in some other way (like via network) and see if the CPU
 load is at 100% for some reason?

Hi,

Our platform is Intel Moorestown platform, and use a spi controller core
from Designware (drivers/spi/dw_*.c). I know the problem may probably be
caused by my setting, but the dw_spi driver works fine with our own
3110 driver.

For debug method, sadly I don't get another output port yet, but if you
have some debug patch, that's great, it will help when I find another debug
output than max3110.

 
  +             max3100_sr(s, tx, rx);
 
  It doesn't handle received characters here? If the console is
  printing out a bulk of message while user input some command, the
  command may be ignored. Myself have met the same problem in our
  driver.
 
 
 yes but I think it's quite difficult to solve this problem in every
 case. Console output is massively used only on boot when the user is
 not supposed to type a lot.

It's difficult but not impossible, actually our driver checks every word
read back and handle it if it contains a valid data

 
  +     if (next != s-console_tail) {
  +             s-console_buf[next] = ch;
  +             s-console_head = next;
  +     }
 
  Also I saw max3100_sr() uses cpu_to_be16() and be16_to_cpu(), is it
  really necessary, our platform is little-endian(x86), and I have to
  disable them to make the code work. Is your test platform
  big-endian?
 
 
 Have you configured your SPI controller as LSB first somehow, haven't
 you? BTW my platform is a quite usual ARM9 S3C2440 which is little
 endian.

yeah, you hit the point that our spi controller is LSB naturally (not
configured to), here may need a check for whether to do a swap


--
Download Intel#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
___
spi-devel-general mailing list
spi-devel-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spi-devel-general


Re: [spi-devel-general] [PATCH v1 3/4] max3100: adds console support for MAX3100

2010-03-29 Thread christian pellegrin
On Mon, Mar 29, 2010 at 9:06 AM, Feng Tang feng.t...@intel.com wrote:

 Our platform is Intel Moorestown platform, and use a spi controller core
 from Designware (drivers/spi/dw_*.c). I know the problem may probably be
 caused by my setting, but the dw_spi driver works fine with our own
 3110 driver.

I had a look at the dw_spi driver. The spi_transfer path queues some
work to a worqueue that itself schedules a tasklet. I don't think this
is good for latency, I won't bet that such an architecture could
deliver good performance. Now I see why you needed to do only big fat
SPI transfers. Anyway this doesn't justify the 2 seconds delay between
chars coming in and going out through the max31x0 you are seeing. I
will try to analyze what's going on. BTW is only input slow or output
is sluggish too? The initial messages from the console are coming out
fast? If you disable the MAX3110 for console but you use just as a
normal terminal (set console=/dev/null in the kernel command line and
add getty 115200 /dev/ttyMAX0 in iniitab) is the interaction with the
system fine? Thanks for helping sorting out this.


 yes but I think it's quite difficult to solve this problem in every
 case. Console output is massively used only on boot when the user is
 not supposed to type a lot.

 It's difficult but not impossible, actually our driver checks every word
 read back and handle it if it contains a valid data


Of course it is possible, I just wanted to keep the max3100 a small
clean driver. Unfortunately console and serial drivers are two
different beings in the Linux kernel, but the max3100 implements the
tx-rx in one indivisible instruction (that is slow compared to
registers IO and has to be called in an preemptible contex for added
fun).  To implement what you are saying we need:

1) the console code has to check if the serial port associated to the
same physical max3100 is up (console driver start their life much
before serial ones).

2) if yes send data to the tty associated to the serial driver.
Locking is needed here.

I will implement this ASAP.

 Have you configured your SPI controller as LSB first somehow, haven't
 you? BTW my platform is a quite usual ARM9 S3C2440 which is little
 endian.

 yeah, you hit the point that our spi controller is LSB naturally (not
 configured to), here may need a check for whether to do a swap


ok, I think the dw_spi driver has to be fixed.


-- 
Christian Pellegrin, see http://www.evolware.org/chri/
Real Programmers don't play tennis, or any other sport which requires
you to change clothes. Mountain climbing is OK, and Real Programmers
wear their climbing boots to work in case a mountain should suddenly
spring up in the middle of the computer room.

--
Download Intel#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
___
spi-devel-general mailing list
spi-devel-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spi-devel-general


[spi-devel-general] [PATCH 0/5] ARM: PrimeCell DMA patches v4

2010-03-29 Thread Linus Walleij
This is a fourth iteration of the PrimeCell DMA API on top of the
generic DMA devices (sibling to the DMA engine). It's based on
the suggestion from Russell to try and define a specific extension
subset for DMA devices.

Since last iteration the changes are:

- Some necessary extensions to the DMA engine were folded into
  the generic DMA engine framework and are now pending in Dan's
  -next tree.

- I have now also implemented support for the PL022 PrimeCell.

PL011, PL022 and PL180 drivers were tested on the U300 with the
COH 901 318 DMA device.

The PL011 driver was also tested on the U8500 with the pending
DMA40 DMA device.

We're running huge and high-speed transfers on all peripherals.
It works.

Patches will be added to the patch tracker soonish, but if this
is eventually OK:ed by Russell I guess it will have to go in
through Dan's DMA tree. Also Grant has to OK it as maintainer of
the SPI subsystem.

Yours,
Linus Walleij
ST-Ericsson SA

--
Download Intel#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
___
spi-devel-general mailing list
spi-devel-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spi-devel-general


[spi-devel-general] [PATCH 1/6] ARM: define the PrimeCell DMA API

2010-03-29 Thread Linus Walleij
This patch extends the DMA engine with a PrimeCell superset with
three functions: configure DMA channel, stop channel, and one for
getting the number of bytes pending on a channel. These have been
identified as the basic extensions needed to drive DMA on top of
the PL011, PL022 and PL180 PrimeCells.

Signed-off-by: Linus Walleij linus.wall...@stericsson.com
---
Changes since last version:
- Two functions were moved into the DMA engine API instead
---
 include/linux/amba/dma.h |   50 ++
 1 files changed, 50 insertions(+), 0 deletions(-)
 create mode 100644 include/linux/amba/dma.h

diff --git a/include/linux/amba/dma.h b/include/linux/amba/dma.h
new file mode 100644
index 000..1adbcfc
--- /dev/null
+++ b/include/linux/amba/dma.h
@@ -0,0 +1,50 @@
+/*
+ *  linux/include/amba/dma.h
+ *
+ *  Copyright (C) 2010 ST-Ericsson AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#if !defined(AMBA_DMA_H)  defined(CONFIG_DMADEVICES)
+#define AMBA_DMA_H
+
+/**
+ * struct amba_dma_channel_request - this struct is passed in as
+ * configuration data to a DMA engine in order to set up a certain
+ * channel for DMA transport. Anything the DMA engine needs to
+ * know about the PrimeCell shall be passed through this struct.
+ * The DMA engine has to provide an additional function:
+ * dma_set_ambaconfig() in order for it to work with PrimeCells.
+ * @addr: this is the physical address where DMA data should be
+ * read (RX) or written (TX)
+ * @addr_width: this is the width of the source (RX) or target
+ * (TX) register where DMA data shall be read/written, in bytes.
+ * legal values: 1, 2, 4, 8.
+ * @direction: whether the data goes in or out on this channel,
+ * right now.
+ * @maxburst: the maximum number of words (note: words, not bytes)
+ * that can be sent in one burst to the device. Typically something
+ * like half the FIFO depth on I/O peripherals so you don't
+ * overflow it.
+ */
+struct amba_dma_channel_config {
+   dma_addr_t addr;
+   u8 addr_width:4;
+   enum dma_data_direction direction;
+   int maxburst;
+};
+
+/*
+ * The following are extensions to the DMA engine framework
+ * that are needed to use the engine with PrimeCells. We need
+ * to configure devices and be able to stop transfers and
+ * retrieve the number of bytes left on the channel for some
+ * RX transfers when we don't know where and how the transfer
+ * will occur.
+ */
+void dma_set_ambaconfig(struct dma_chan *chan,
+   struct amba_dma_channel_config *config);
+
+#endif /* AMBA_DMA_H */
-- 
1.6.3.3


--
Download Intel#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
___
spi-devel-general mailing list
spi-devel-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spi-devel-general


[spi-devel-general] [PATCH 2/6] ARM: add generic PrimeCell interface to COH 901 318

2010-03-29 Thread Linus Walleij
This extends the DMA engine driver for the COH 901 318 used in the
U300 platform with the generic PrimeCell interface,

Signed-off-by: Linus Walleij linus.wall...@stericsson.com
---
 drivers/dma/coh901318.c |  146 +++
 drivers/dma/coh901318_lli.c |   78 ++-
 2 files changed, 221 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index 4233440..1d5ed16 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -21,6 +21,7 @@
 #include linux/uaccess.h
 #include linux/debugfs.h
 #include mach/coh901318.h
+#include linux/amba/dma.h
 
 #include coh901318_lli.h
 
@@ -72,6 +73,9 @@ struct coh901318_chan {
unsigned long nbr_active_done;
unsigned long busy;
 
+   u32 amba_addr;
+   u32 amba_ctrl;
+
struct coh901318_base *base;
 };
 
@@ -190,6 +194,9 @@ static inline struct coh901318_chan 
*to_coh901318_chan(struct dma_chan *chan)
 static inline dma_addr_t
 cohc_dev_addr(struct coh901318_chan *cohc)
 {
+   /* PrimeCell supplied address will take precedence */
+   if (cohc-amba_addr)
+   return cohc-amba_addr;
return cohc-base-platform-chan_conf[cohc-id].dev_addr;
 }
 
@@ -1055,6 +1062,14 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct 
scatterlist *sgl,
 
params = cohc_chan_param(cohc);
config = params-config;
+   /*
+* Add primecell-specific control on top, make
+* sure the bits you set per peripheral channel are
+* cleared in the default config from the platform.
+*/
+   ctrl_chained |= cohc-amba_ctrl;
+   ctrl_last |= cohc-amba_ctrl;
+   ctrl |= cohc-amba_ctrl;
 
if (direction == DMA_TO_DEVICE) {
u32 tx_flags = COH901318_CX_CTRL_PRDD_SOURCE |
@@ -1113,6 +1128,12 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct 
scatterlist *sgl,
if (ret)
goto err_lli_fill;
 
+   /*
+* Set the default ctrl for the channel to the one from the lli,
+* things may have changed due to odd buffer alignment etc.
+*/
+   coh901318_set_ctrl(cohc, lli-control);
+
COH_DBG(coh901318_list_print(cohc, lli));
 
/* Pick a descriptor to handle this transfer */
@@ -1239,6 +1260,131 @@ coh901318_control(struct dma_chan *chan, enum 
dma_ctrl_cmd cmd)
 
return 0;
 }
+
+/*
+ * Here we wrap in the PrimeCell dma interface
+ */
+struct burst_table {
+   int burst_8bit;
+   int burst_16bit;
+   int burst_32bit;
+   u32 reg;
+};
+
+static const struct burst_table burst_sizes[] = {
+   {
+   .burst_8bit = 64,
+   .burst_16bit = 32,
+   .burst_32bit = 16,
+   .reg = COH901318_CX_CTRL_BURST_COUNT_64_BYTES,
+   },
+   {
+   .burst_8bit = 48,
+   .burst_16bit = 24,
+   .burst_32bit = 12,
+   .reg = COH901318_CX_CTRL_BURST_COUNT_48_BYTES,
+   },
+   {
+   .burst_8bit = 32,
+   .burst_16bit = 16,
+   .burst_32bit = 8,
+   .reg = COH901318_CX_CTRL_BURST_COUNT_32_BYTES,
+   },
+   {
+   .burst_8bit = 16,
+   .burst_16bit = 8,
+   .burst_32bit = 4,
+   .reg = COH901318_CX_CTRL_BURST_COUNT_16_BYTES,
+   },
+   {
+   .burst_8bit = 8,
+   .burst_16bit = 4,
+   .burst_32bit = 2,
+   .reg = COH901318_CX_CTRL_BURST_COUNT_8_BYTES,
+   },
+   {
+   .burst_8bit = 4,
+   .burst_16bit = 2,
+   .burst_32bit = 1,
+   .reg = COH901318_CX_CTRL_BURST_COUNT_4_BYTES,
+   },
+   {
+   .burst_8bit = 2,
+   .burst_16bit = 1,
+   .burst_32bit = 0,
+   .reg = COH901318_CX_CTRL_BURST_COUNT_2_BYTES,
+   },
+   {
+   .burst_8bit = 1,
+   .burst_16bit = 0,
+   .burst_32bit = 0,
+   .reg = COH901318_CX_CTRL_BURST_COUNT_1_BYTE,
+   },
+};
+
+void dma_set_ambaconfig(struct dma_chan *chan,
+   struct amba_dma_channel_config *config)
+{
+   struct coh901318_chan *cohc = to_coh901318_chan(chan);
+   int maxburst = config-maxburst;
+   u32 amba_ctrl = 0;
+   int i = 0;
+
+   dev_dbg(COHC_2_DEV(cohc), configure channel for %d byte transfers\n,
+   config-addr_width);
+   switch (config-addr_width)  {
+   case 1:
+   amba_ctrl |=
+   COH901318_CX_CTRL_SRC_BUS_SIZE_8_BITS |
+   COH901318_CX_CTRL_DST_BUS_SIZE_8_BITS;
+
+   while (i  ARRAY_SIZE(burst_sizes)) {
+   if (burst_sizes[i].burst_8bit = maxburst)
+   break;
+   i++;
+   }
+
+   break;
+   case 2:
+   

[spi-devel-general] [PATCH 6/6] ARM: config U300 PL180 PL011 PL022 for DMA

2010-03-29 Thread Linus Walleij
This will configure the platform data for the PL180, PL011 and
PL022 PrimeCells found in the U300 to use DMA with the generic
PrimeCell DMA engine.

Signed-off-by: Linus Walleij linus.wall...@stericsson.com
---
 arch/arm/mach-u300/core.c |  173 -
 arch/arm/mach-u300/mmc.c  |   13 +++-
 arch/arm/mach-u300/spi.c  |   21 --
 3 files changed, 181 insertions(+), 26 deletions(-)

diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index 5f34eb6..7f7e738 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -3,7 +3,7 @@
  * arch/arm/mach-u300/core.c
  *
  *
- * Copyright (C) 2007-2010 ST-Ericsson AB
+ * Copyright (C) 2007-2010 ST-Ericsson SA
  * License terms: GNU General Public License (GPL) version 2
  * Core platform support, IRQ handling and device definitions.
  * Author: Linus Walleij linus.wall...@stericsson.com
@@ -16,7 +16,9 @@
 #include linux/device.h
 #include linux/mm.h
 #include linux/termios.h
+#include linux/dmaengine.h
 #include linux/amba/bus.h
+#include linux/amba/serial.h
 #include linux/platform_device.h
 #include linux/gpio.h
 #include mach/coh901318.h
@@ -92,10 +94,20 @@ void __init u300_map_io(void)
  * Declaration of devices found on the U300 board and
  * their respective memory locations.
  */
+
+static struct amba_pl011_data uart0_plat_data = {
+#ifdef CONFIG_COH901318
+   .dma_filter = coh901318_filter_id,
+   .dma_rx_param = (void *) U300_DMA_UART0_RX,
+   .dma_tx_param = (void *) U300_DMA_UART0_TX,
+#endif
+};
+
 static struct amba_device uart0_device = {
.dev = {
+   .coherent_dma_mask = ~0,
.init_name = uart0, /* Slow device at 0x3000 offset */
-   .platform_data = NULL,
+   .platform_data = uart0_plat_data,
},
.res = {
.start = U300_UART0_BASE,
@@ -107,10 +119,19 @@ static struct amba_device uart0_device = {
 
 /* The U335 have an additional UART1 on the APP CPU */
 #ifdef CONFIG_MACH_U300_BS335
+static struct amba_pl011_data uart1_plat_data = {
+#ifdef CONFIG_COH901318
+   .dma_filter = coh901318_filter_id,
+   .dma_rx_param = (void *) U300_DMA_UART1_RX,
+   .dma_tx_param = (void *) U300_DMA_UART1_TX,
+#endif
+};
+
 static struct amba_device uart1_device = {
.dev = {
+   .coherent_dma_mask = ~0,
.init_name = uart1, /* Fast device at 0x7000 offset */
-   .platform_data = NULL,
+   .platform_data = uart1_plat_data,
},
.res = {
.start = U300_UART1_BASE,
@@ -949,20 +970,21 @@ const struct coh_dma_channel 
chan_config[U300_DMA_CHANNELS] = {
.priority_high = 0,
.dev_addr = U300_MSL_BASE + 6 * 0x40 + 0x220,
},
+   /*
+* Don't set up device address, burst count or size of src
+* or dst bus for this peripheral - handled by PrimeCell
+* DMA extension.
+*/
{
.number = U300_DMA_MMCSD_RX_TX,
.name = MMCSD RX TX,
.priority_high = 0,
-   .dev_addr =  U300_MMCSD_BASE + 0x080,
.param.config = COH901318_CX_CFG_CH_DISABLE |
COH901318_CX_CFG_LCR_DISABLE |
COH901318_CX_CFG_TC_IRQ_ENABLE |
COH901318_CX_CFG_BE_IRQ_ENABLE,
.param.ctrl_lli_chained = 0 |
COH901318_CX_CTRL_TC_ENABLE |
-   COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
-   COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
-   COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
COH901318_CX_CTRL_MASTER_MODE_M1RW |
COH901318_CX_CTRL_TCP_ENABLE |
COH901318_CX_CTRL_TC_IRQ_ENABLE |
@@ -971,9 +993,6 @@ const struct coh_dma_channel chan_config[U300_DMA_CHANNELS] 
= {
COH901318_CX_CTRL_DDMA_LEGACY,
.param.ctrl_lli = 0 |
COH901318_CX_CTRL_TC_ENABLE |
-   COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
-   COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
-   COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
COH901318_CX_CTRL_MASTER_MODE_M1RW |
COH901318_CX_CTRL_TCP_ENABLE |
COH901318_CX_CTRL_TC_IRQ_ENABLE |
@@ -982,9 +1001,6 @@ const struct coh_dma_channel 
chan_config[U300_DMA_CHANNELS] = {
COH901318_CX_CTRL_DDMA_LEGACY,
.param.ctrl_lli_last = 0 |
COH901318_CX_CTRL_TC_ENABLE |
-   COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
-   

[spi-devel-general] [PATCH 3/6] ARM: add PrimeCell generic DMA to MMCI/PL180

2010-03-29 Thread Linus Walleij
This extends the MMCI/PL180 driver with generic DMA engine support
using the PrimeCell DMA engine interface.

Signed-off-by: Linus Walleij linus.wall...@stericsson.com
---
Changes since last version:
- Folded in the new extensions to the DMA engine
---
 drivers/mmc/host/mmci.c   |  290 ++---
 drivers/mmc/host/mmci.h   |7 +-
 include/linux/amba/mmci.h |   16 +++
 3 files changed, 268 insertions(+), 45 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index ff115d9..37ab678 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -2,7 +2,7 @@
  *  linux/drivers/mmc/host/mmci.c - ARM PrimeCell MMCI PL180/1 driver
  *
  *  Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
- *  Copyright (C) 2010 ST-Ericsson AB.
+ *  Copyright (C) 2010 ST-Ericsson SA
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -23,8 +23,11 @@
 #include linux/clk.h
 #include linux/scatterlist.h
 #include linux/gpio.h
-#include linux/amba/mmci.h
 #include linux/regulator/consumer.h
+#include linux/dmaengine.h
+#include linux/dma-mapping.h
+#include linux/amba/dma.h
+#include linux/amba/mmci.h
 
 #include asm/cacheflush.h
 #include asm/div64.h
@@ -98,12 +101,209 @@ static void mmci_stop_data(struct mmci_host *host)
host-data = NULL;
 }
 
+static void
+mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c)
+{
+   void __iomem *base = host-base;
+
+   dev_dbg(mmc_dev(host-mmc), op %02x arg %08x flags %08x\n,
+   cmd-opcode, cmd-arg, cmd-flags);
+
+   if (readl(base + MMCICOMMAND)  MCI_CPSM_ENABLE) {
+   writel(0, base + MMCICOMMAND);
+   udelay(1);
+   }
+
+   c |= cmd-opcode | MCI_CPSM_ENABLE;
+   if (cmd-flags  MMC_RSP_PRESENT) {
+   if (cmd-flags  MMC_RSP_136)
+   c |= MCI_CPSM_LONGRSP;
+   c |= MCI_CPSM_RESPONSE;
+   }
+   if (/*interrupt*/0)
+   c |= MCI_CPSM_INTERRUPT;
+
+   host-cmd = cmd;
+
+   writel(cmd-arg, base + MMCIARGUMENT);
+   writel(c, base + MMCICOMMAND);
+}
+
+/*
+ * All the DMA operation mode stuff goes inside this ifdef.
+ * This assumes that you have a generic DMA device interface,
+ * no custom DMA interfaces are supported.
+ */
+#ifdef CONFIG_DMADEVICES
+static void __devinit mmci_setup_dma(struct mmci_host *host)
+{
+   struct mmci_platform_data *plat = host-plat;
+   dma_cap_mask_t mask;
+
+   /* Try to acquire a generic DMA engine slave channel */
+   dma_cap_zero(mask);
+   dma_cap_set(DMA_SLAVE, mask);
+   /*
+* If only an RX channel is specified, the driver will
+* attempt to use it bidirectionally, however if it is
+* is specified but cannot be located, DMA will be disabled.
+*/
+   host-dma_rx_channel = dma_request_channel(mask,
+   plat-dma_filter,
+   plat-dma_rx_param);
+   if (plat-dma_tx_param) {
+   host-dma_tx_channel = dma_request_channel(mask,
+  plat-dma_filter,
+  plat-dma_tx_param);
+   if (!host-dma_tx_channel) {
+   dma_release_channel(host-dma_rx_channel);
+   host-dma_rx_channel = NULL;
+   }
+   } else {
+   host-dma_tx_channel = host-dma_rx_channel;
+   }
+}
+
+static void __devexit mmci_disable_dma(struct mmci_host *host)
+{
+   if (host-dma_rx_channel)
+   dma_release_channel(host-dma_rx_channel);
+   if (host-dma_tx_channel)
+   dma_release_channel(host-dma_tx_channel);
+}
+
+static void mmci_dma_data_end(struct mmci_host *host)
+{
+   struct mmc_data *data = host-data;
+
+   dma_unmap_sg(mmc_dev(host-mmc), data-sg, data-sg_len,
+(data-flags  MMC_DATA_WRITE)
+? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+}
+
+static void mmci_dma_data_error(struct mmci_host *host)
+{
+   struct mmc_data *data = host-data;
+   struct dma_chan *chan;
+
+   dev_err(mmc_dev(host-mmc), error during DMA transfer!\n);
+   if (data-flags  MMC_DATA_READ)
+   chan = host-dma_rx_channel;
+   else
+   chan = host-dma_tx_channel;
+   dma_unmap_sg(mmc_dev(host-mmc), data-sg, data-sg_len,
+(data-flags  MMC_DATA_WRITE)
+? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+   chan-device-device_control(chan, DMA_TERMINATE_ALL);
+}
+
+/*
+ * This one gets called repeatedly to copy data using
+ * DMA until there is no more data left to copy.
+ */
+static int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl)
+{
+   struct amba_dma_channel_config 

[spi-devel-general] [PATCH 5/6] ARM: add PrimeCell generic DMA to PL022

2010-03-29 Thread Linus Walleij
This extends the PL022 UART driver with generic DMA engine support
using the PrimeCell DMA engine interface. Also fix up the test
code for the U300 platform.

Signed-off-by: Linus Walleij linus.wall...@stericsson.com
---
 arch/arm/mach-u300/dummyspichip.c |1 +
 drivers/spi/amba-pl022.c  |  517 +++--
 include/linux/amba/pl022.h|6 +
 3 files changed, 438 insertions(+), 86 deletions(-)

diff --git a/arch/arm/mach-u300/dummyspichip.c 
b/arch/arm/mach-u300/dummyspichip.c
index 5f55012..5672189 100644
--- a/arch/arm/mach-u300/dummyspichip.c
+++ b/arch/arm/mach-u300/dummyspichip.c
@@ -268,6 +268,7 @@ static struct spi_driver pl022_dummy_driver = {
.driver = {
.name   = spi-dummy,
.owner  = THIS_MODULE,
+   .bus = spi_bus_type,
},
.probe  = pl022_dummy_probe,
.remove = __devexit_p(pl022_dummy_remove),
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c
index e9aeee1..09a701c 100644
--- a/drivers/spi/amba-pl022.c
+++ b/drivers/spi/amba-pl022.c
@@ -27,7 +27,6 @@
 /*
  * TODO:
  * - add timeout on polled transfers
- * - add generic DMA framework support
  */
 
 #include linux/init.h
@@ -45,6 +44,10 @@
 #include linux/amba/pl022.h
 #include linux/io.h
 #include linux/slab.h
+#include linux/dmaengine.h
+#include linux/dma-mapping.h
+#include linux/scatterlist.h
+#include linux/amba/dma.h
 
 /*
  * This macro is used to define some register default values.
@@ -365,6 +368,14 @@ struct pl022 {
enum ssp_readingread;
enum ssp_writingwrite;
u32 exp_fifo_level;
+   /* DMA settings */
+#ifdef CONFIG_DMADEVICES
+   struct dma_chan *dma_rx_channel;
+   struct dma_chan *dma_tx_channel;
+   struct sg_table sgt_rx;
+   struct sg_table sgt_tx;
+   char*dummypage;
+#endif
 };
 
 /**
@@ -699,6 +710,367 @@ static void *next_transfer(struct pl022 *pl022)
}
return STATE_DONE;
 }
+
+/*
+ * This DMA functionality is only compiled in if we have
+ * access to the generic DMA devices/DMA engine.
+ */
+#ifdef CONFIG_DMADEVICES
+static void unmap_free_dma_scatter(struct pl022 *pl022)
+{
+   /* Unmap and free the SG tables */
+   dma_unmap_sg(pl022-adev-dev, pl022-sgt_tx.sgl,
+pl022-sgt_tx.nents, DMA_TO_DEVICE);
+   dma_unmap_sg(pl022-adev-dev, pl022-sgt_rx.sgl,
+pl022-sgt_rx.nents, DMA_FROM_DEVICE);
+   sg_free_table(pl022-sgt_rx);
+   sg_free_table(pl022-sgt_tx);
+}
+
+static void dma_callback(void *data)
+{
+   struct pl022 *pl022 = data;
+   struct spi_message *msg = pl022-cur_msg;
+
+   /* Sync in RX buffer to CPU */
+   BUG_ON(!pl022-sgt_rx.sgl);
+   dma_sync_sg_for_cpu(pl022-adev-dev,
+   pl022-sgt_rx.sgl,
+   pl022-sgt_rx.nents,
+   DMA_FROM_DEVICE);
+
+#ifdef VERBOSE_DEBUG
+   /*
+* Optionally dump out buffers to inspect contents, this is
+* good if you want to convince yourself that the loopback
+* read/write contents are the same, when adopting to a new
+* DMA engine.
+*/
+   {
+   struct scatterlist *sg;
+   unsigned int i;
+
+   for_each_sg(pl022-sgt_rx.sgl, sg, pl022-sgt_rx.nents, i) {
+   dev_dbg(pl022-adev-dev, SPI RX SG ENTRY: %d, i);
+   print_hex_dump(KERN_ERR, SPI RX: ,
+  DUMP_PREFIX_OFFSET,
+  16,
+  1,
+  sg_virt(sg),
+  sg_dma_len(sg),
+  1);
+   }
+   for_each_sg(pl022-sgt_tx.sgl, sg, pl022-sgt_tx.nents, i) {
+   dev_dbg(pl022-adev-dev, SPI TX SG ENTRY: %d, i);
+   print_hex_dump(KERN_ERR, SPI TX: ,
+  DUMP_PREFIX_OFFSET,
+  16,
+  1,
+  sg_virt(sg),
+  sg_dma_len(sg),
+  1);
+   }
+   }
+#endif
+
+   unmap_free_dma_scatter(pl022);
+
+   /* Update total bytes transfered */
+   msg-actual_length += pl022-cur_transfer-len;
+   if (pl022-cur_transfer-cs_change)
+   pl022-cur_chip-
+   cs_control(SSP_CHIP_DESELECT);
+
+   /* Move to next transfer */
+   msg-state = next_transfer(pl022);
+   tasklet_schedule(pl022-pump_transfers);
+}
+
+static void setup_dma_scatter(struct pl022 *pl022,
+ void *buffer,
+ 

[spi-devel-general] [PATCH 4/6] ARM: add PrimeCell generic DMA to PL011

2010-03-29 Thread Linus Walleij
This extends the PL011 UART driver with generic DMA engine support
using the PrimeCell DMA engine interface.

Signed-off-by: Linus Walleij linus.wall...@stericsson.com
---
Changes since last version:
- Fixed some bugs appearing under huge load, spinlock issues etc
- Adapted to the new generic DMA engine interface
---
 drivers/serial/amba-pl011.c |  713 ++-
 include/linux/amba/serial.h |6 +
 2 files changed, 712 insertions(+), 7 deletions(-)

diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index eb4cb48..086b777 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -7,6 +7,7 @@
  *
  *  Copyright 1999 ARM Limited
  *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *  Copyright (C) 2010 ST-Ericsson SA
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -48,6 +49,11 @@
 #include linux/amba/serial.h
 #include linux/clk.h
 #include linux/slab.h
+#include linux/dmaengine.h
+#include linux/dma-mapping.h
+#include linux/scatterlist.h
+#include linux/completion.h
+#include linux/amba/dma.h
 
 #include asm/io.h
 #include asm/sizes.h
@@ -63,6 +69,24 @@
 #define UART_DR_ERROR  
(UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE)
 #define UART_DUMMY_DR_RX   (1  16)
 
+/* Deals with DMA transactions */
+struct pl011_dma_rx_transaction {
+   struct completion complete;
+   bool use_buffer_b;
+   struct scatterlist scatter_a;
+   struct scatterlist scatter_b;
+   char *rx_dma_buf_a;
+   char *rx_dma_buf_b;
+   dma_cookie_t cookie;
+};
+
+struct pl011_dma_tx_transaction {
+   struct completion complete;
+   struct scatterlist scatter;
+   char *tx_dma_buf;
+   dma_cookie_t cookie;
+};
+
 /*
  * We wrap our port structure around the generic uart_port.
  */
@@ -73,6 +97,15 @@ struct uart_amba_port {
unsigned intold_status;
unsigned intifls;   /* vendor-specific */
boolautorts;
+   unsigned intfifosize;
+   /* DMA stuff */
+   booluse_dma;
+#ifdef CONFIG_DMADEVICES
+   struct dma_chan *dma_rx_channel;
+   struct dma_chan *dma_tx_channel;
+   struct pl011_dma_rx_transaction dmarx;
+   struct pl011_dma_tx_transaction dmatx;
+#endif
 };
 
 /* There is by now at least one vendor with differing details, so handle it */
@@ -91,18 +124,641 @@ static struct vendor_data vendor_st = {
.fifosize   = 64,
 };
 
+
+/*
+ * All the DMA operation mode stuff goes inside this ifdef.
+ * This assumes that you have a generic DMA device interface,
+ * no custom DMA interfaces are supported.
+ */
+#ifdef CONFIG_DMADEVICES
+
+#define PL011_DMA_BUFFER_SIZE PAGE_SIZE
+
+static void __init pl011_dma_probe_initcall(struct uart_amba_port *uap)
+{
+   /* DMA is the sole user of the platform data right now */
+   struct amba_pl011_data *plat = uap-port.dev-platform_data;
+   struct pl011_dma_rx_transaction *dmarx = uap-dmarx;
+   struct pl011_dma_tx_transaction *dmatx = uap-dmatx;
+   struct amba_dma_channel_config rx_conf = {
+   .addr = uap-port.mapbase + UART01x_DR,
+   .addr_width = 1,
+   .direction = DMA_FROM_DEVICE,
+   .maxburst = uap-port.fifosize  1,
+   };
+   struct amba_dma_channel_config tx_conf = {
+   .addr = uap-port.mapbase + UART01x_DR,
+   .addr_width = 1,
+   .direction = DMA_TO_DEVICE,
+   .maxburst = uap-port.fifosize  1,
+   };
+   dma_cap_mask_t mask;
+   int sglen;
+
+   /* We need platform data */
+   if (!plat) {
+   dev_err(uap-port.dev, no platform data!\n);
+   return;
+   }
+
+   /* Try to acquire a generic DMA engine slave channel */
+   dma_cap_zero(mask);
+   dma_cap_set(DMA_SLAVE, mask);
+   /*
+* We need both RX and TX channels to do DMA, else do none
+* of them.
+*/
+   uap-dma_rx_channel = dma_request_channel(mask,
+ plat-dma_filter,
+ plat-dma_rx_param);
+   if (!uap-dma_rx_channel) {
+   dev_err(uap-port.dev, no RX DMA channel!\n);
+   return;
+   }
+   dma_set_ambaconfig(uap-dma_rx_channel, rx_conf);
+
+   uap-dma_tx_channel = dma_request_channel(mask,
+ plat-dma_filter,
+ plat-dma_tx_param);
+   if (!uap-dma_tx_channel) {
+   dev_err(uap-port.dev, no TX DMA channel!\n);
+   goto err_no_txchan;
+   }
+   dma_set_ambaconfig(uap-dma_tx_channel, tx_conf);
+
+   /* Allocate DMA RX and TX buffers */
+   dmarx-rx_dma_buf_a = 

Re: [spi-devel-general] [PATCH v1 3/4] max3100: adds console support for MAX3100

2010-03-29 Thread Feng Tang
On Mon, 29 Mar 2010 20:55:51 +0800
christian pellegrin chrip...@fsfe.org wrote:

 On Mon, Mar 29, 2010 at 9:06 AM, Feng Tang feng.t...@intel.com
 wrote:
 
  Our platform is Intel Moorestown platform, and use a spi controller
  core from Designware (drivers/spi/dw_*.c). I know the problem may
  probably be caused by my setting, but the dw_spi driver works fine
  with our own 3110 driver.
 
 I had a look at the dw_spi driver. The spi_transfer path queues some
 work to a worqueue that itself schedules a tasklet. I don't think this
 is good for latency, I won't bet that such an architecture could
 deliver good performance. Now I see why you needed to do only big fat
 SPI transfers. Anyway this doesn't justify the 2 seconds delay between
Hi

DW controller driver don't need max3110 driver to use big spi transfer,
the early version of our max3110 is also one word per spi transfer mode,
and the 2 drivers work fine, though the rx performance is not good (copy
 paste a bulk message to console).

Let me use some example to explain why I use big spi transfer for 3110:

When the HW works at 230400 bps, when we copy bulk data to the console,
max3110 will probably receive about 20K characters, so the time for
handling each char is 50us. If you use one char per spi transfer, it
will have to execute 20K spi_transfer in one second, and each need be
done in 50us, in this 50us you'll have to deal with controller IRQ 
handler + spi system overhead + tty receiving overhead. Is it a little
over-killing to use one char per spi transfer? while the HW does
have a 8 words RX FIFO 

 chars coming in and going out through the max31x0 you are seeing. I
 will try to analyze what's going on. BTW is only input slow or output
 is sluggish too? The initial messages from the console are coming out
 fast? If you disable the MAX3110 for console but you use just as a
 normal terminal (set console=/dev/null in the kernel command line and
 add getty 115200 /dev/ttyMAX0 in iniitab) is the interaction with the
 system fine? Thanks for helping sorting out this.

The output is not so slow as input, if we set the console=/dev/ttyMAX0,
the output is sluggish, looks like below, but when enter command line
console the output is smooth, while the input is very slow.

--
   kernel print log of max3100 over Moorestown platform
--

0.00] Moorestown CPU Lincroft identified
[[..00  iiuu  eessoo  44rr11((eeggffnn--77  
ggccvvrriinn11((bbnnuu1144bbnnuu
[[..00  BBOO--8800  1100--8800  uuaall))


]]  IISSee22::00
11 - 0f200 (usabl))
   [ .000  BIOS-e822:: 
022000110
00((eserved)
[0.00]  BIISSe820:: ee0 --0fec01000 (reseree))

  
]]  IISSee200
[[..00  BBOO--8800  ff00--  rrssrree))

  
]]NNttcc::NN
[[..00  8800uuddtt  aagg::((ssbbee  
==  rrssrree))


  00
00]]ee22  eeooeerrnnee  00aa--0011  uuaall))


]]llss__ffxx
2200mmxxaacc__ffxx00

]]MMRR  eeaall  yyee  nnaahhbbee


]]MMRR  iiee  aa
[[..00--  rrtt--aakk

[[..00--  rrtt--aakk]]  AABBuuaall

]]MMRR  aaiibbeerrnnee  
nnbbee::




 1) the console code has to check if the serial port associated to the
 same physical max3100 is up (console driver start their life much
 before serial ones).
 
 2) if yes send data to the tty associated to the serial driver.
 Locking is needed here.
 
 I will implement this ASAP.

cool!


--
Download Intel#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
___
spi-devel-general mailing list
spi-devel-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spi-devel-general