Re: [PATCH v5 0/5] Add memory mapped read support for ti-qspi

2016-01-04 Thread Vignesh R
Hi Brian,

On 12/11/2015 09:39 AM, Vignesh R wrote:
> Changes since v4:
> Use syscon to access system control module register in ti-qspi driver.
> 

Gentle ping...
Are you ok with MTD side changes of this patch series?

> Changes since v3:
> Rework to introduce spi_flash_read_message struct.
> Support different opcode/addr/data formats as per Brian's suggestion
> here: https://lkml.org/lkml/2015/11/11/454
> 
> Changes since v2:
> Remove mmap_lock_mutex.
> Optimize enable/disable of mmap mode.
> 
> Changes since v1:
> Introduce API in SPI core that MTD flash driver can call for mmap read
> instead of directly calling spi-master driver callback. This API makes
> sure that SPI core msg queue is locked during mmap transfers.
> v1: https://lkml.org/lkml/2015/9/4/103
> 
> 
> Cover letter:
> 
> This patch series adds support for memory mapped read port of ti-qspi.
> ti-qspi has a special memory mapped port through which SPI flash
> memories can be accessed directly via SoC specific memory region.
> 
> First patch adds a method to pass flash specific information like read
> opcode, dummy bytes etc and to request mmap read. Second patch
> implements mmap read method in ti-qspi driver. Patch 3 adapts m25p80 to
> use mmap read method before trying normal SPI transfer. Patch 4 and 5
> add memory map region DT entries for DRA7xx and AM43xx SoCs.
> 
> This patch series is based on the discussions here:
> http://www.spinics.net/lists/linux-spi/msg04796.html
> 
> Tested on DRA74 EVM and AM437x-SK.
> Read performance increases from ~100kB/s to ~2.5MB/s.
> 
> Vignesh R (5):
>   spi: introduce accelerated read support for spi flash devices
>   spi: spi-ti-qspi: add mmap mode read support
>   mtd: devices: m25p80: add support for mmap read request
>   ARM: dts: DRA7: add entry for qspi mmap region
>   ARM: dts: AM4372: add entry for qspi mmap region
> 
>  Documentation/devicetree/bindings/spi/ti_qspi.txt |  22 +++-
>  arch/arm/boot/dts/am4372.dtsi |   4 +-
>  arch/arm/boot/dts/dra7.dtsi   |   6 +-
>  drivers/mtd/devices/m25p80.c  |  20 
>  drivers/spi/spi-ti-qspi.c | 139 
> +-
>  drivers/spi/spi.c |  45 +++
>  include/linux/spi/spi.h   |  41 +++
>  7 files changed, 243 insertions(+), 34 deletions(-)
> 

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 0/5] Add memory mapped read support for ti-qspi

2015-12-21 Thread Vignesh R


On 12/11/2015 09:39 AM, Vignesh R wrote:
> Changes since v4:
> Use syscon to access system control module register in ti-qspi driver.
> 
> Changes since v3:
> Rework to introduce spi_flash_read_message struct.
> Support different opcode/addr/data formats as per Brian's suggestion
> here: https://lkml.org/lkml/2015/11/11/454
> 

Gentle Ping on the series...


> Changes since v2:
> Remove mmap_lock_mutex.
> Optimize enable/disable of mmap mode.
> 
> Changes since v1:
> Introduce API in SPI core that MTD flash driver can call for mmap read
> instead of directly calling spi-master driver callback. This API makes
> sure that SPI core msg queue is locked during mmap transfers.
> v1: https://lkml.org/lkml/2015/9/4/103
> 
> 
> Cover letter:
> 
> This patch series adds support for memory mapped read port of ti-qspi.
> ti-qspi has a special memory mapped port through which SPI flash
> memories can be accessed directly via SoC specific memory region.
> 
> First patch adds a method to pass flash specific information like read
> opcode, dummy bytes etc and to request mmap read. Second patch
> implements mmap read method in ti-qspi driver. Patch 3 adapts m25p80 to
> use mmap read method before trying normal SPI transfer. Patch 4 and 5
> add memory map region DT entries for DRA7xx and AM43xx SoCs.
> 
> This patch series is based on the discussions here:
> http://www.spinics.net/lists/linux-spi/msg04796.html
> 
> Tested on DRA74 EVM and AM437x-SK.
> Read performance increases from ~100kB/s to ~2.5MB/s.
> 
> Vignesh R (5):
>   spi: introduce accelerated read support for spi flash devices
>   spi: spi-ti-qspi: add mmap mode read support
>   mtd: devices: m25p80: add support for mmap read request
>   ARM: dts: DRA7: add entry for qspi mmap region
>   ARM: dts: AM4372: add entry for qspi mmap region
> 
>  Documentation/devicetree/bindings/spi/ti_qspi.txt |  22 +++-
>  arch/arm/boot/dts/am4372.dtsi |   4 +-
>  arch/arm/boot/dts/dra7.dtsi   |   6 +-
>  drivers/mtd/devices/m25p80.c  |  20 
>  drivers/spi/spi-ti-qspi.c | 139 
> +-
>  drivers/spi/spi.c |  45 +++
>  include/linux/spi/spi.h   |  41 +++
>  7 files changed, 243 insertions(+), 34 deletions(-)
> 

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 4/5] ARM: dts: DRA7: add entry for qspi mmap region

2015-12-17 Thread Vignesh R


On 12/18/2015 12:15 AM, Tony Lindgren wrote:
> * Rob Herring <r...@kernel.org> [151211 07:10]:
>> On Fri, Dec 11, 2015 at 09:39:59AM +0530, Vignesh R wrote:
>>> Add qspi memory mapped region entries for DRA7xx based SoCs. Also,
>>> update the binding documents for the controller to document this change.
>>>
>>> Signed-off-by: Vignesh R <vigne...@ti.com>
>>
>> Acked-by: Rob Herring <r...@kernel.org>
> 
> Vignes, are patches 4 and 5 safe to apply separately already or
> do things break if we do that?

Yes, 4 and 5 can be applied separately w/o driver changes.

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 2/5] spi: spi-ti-qspi: add mmap mode read support

2015-12-10 Thread Vignesh R
ti-qspi controller provides mmap port to read data from SPI flashes.
mmap port is enabled in QSPI_SPI_SWITCH_REG. ctrl module register may
also need to be accessed for some SoCs. The QSPI_SPI_SETUP_REGx needs to
be populated with flash specific information like read opcode, read
mode(quad, dual, normal), address width and dummy bytes. Once,
controller is in mmap mode, the whole flash memory is available as a
memory region at SoC specific address. This region can be accessed using
normal memcpy() (or mem-to-mem dma copy). The ti-qspi controller hardware
will internally communicate with SPI flash over SPI bus and get the
requested data.

Implement spi_flash_read() callback to support mmap read over SPI
flash devices. With this, the read throughput increases from ~100kB/s to
~2.5 MB/s.

Signed-off-by: Vignesh R <vigne...@ti.com>
---

v5:
 * use syscon to access ctrl_mod register.

 drivers/spi/spi-ti-qspi.c | 139 --
 1 file changed, 110 insertions(+), 29 deletions(-)

diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index 64318fcfacf2..eac3c960b2de 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -31,6 +31,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 
@@ -44,8 +46,9 @@ struct ti_qspi {
 
struct spi_master   *master;
void __iomem*base;
-   void __iomem*ctrl_base;
void __iomem*mmap_base;
+   struct regmap   *ctrl_base;
+   unsigned intctrl_reg;
struct clk  *fclk;
struct device   *dev;
 
@@ -55,7 +58,7 @@ struct ti_qspi {
u32 cmd;
u32 dc;
 
-   bool ctrl_mod;
+   bool mmap_enabled;
 };
 
 #define QSPI_PID   (0x0)
@@ -65,11 +68,8 @@ struct ti_qspi {
 #define QSPI_SPI_CMD_REG   (0x48)
 #define QSPI_SPI_STATUS_REG(0x4c)
 #define QSPI_SPI_DATA_REG  (0x50)
-#define QSPI_SPI_SETUP0_REG(0x54)
+#define QSPI_SPI_SETUP_REG(n)  ((0x54 + 4 * n))
 #define QSPI_SPI_SWITCH_REG(0x64)
-#define QSPI_SPI_SETUP1_REG(0x58)
-#define QSPI_SPI_SETUP2_REG(0x5c)
-#define QSPI_SPI_SETUP3_REG(0x60)
 #define QSPI_SPI_DATA_REG_1(0x68)
 #define QSPI_SPI_DATA_REG_2(0x6c)
 #define QSPI_SPI_DATA_REG_3(0x70)
@@ -109,6 +109,17 @@ struct ti_qspi {
 
 #define QSPI_AUTOSUSPEND_TIMEOUT 2000
 
+#define MEM_CS_EN(n)   ((n + 1) << 8)
+#define MEM_CS_MASK(7 << 8)
+
+#define MM_SWITCH  0x1
+
+#define QSPI_SETUP_RD_NORMAL   (0x0 << 12)
+#define QSPI_SETUP_RD_DUAL (0x1 << 12)
+#define QSPI_SETUP_RD_QUAD (0x3 << 12)
+#define QSPI_SETUP_ADDR_SHIFT  8
+#define QSPI_SETUP_DUMMY_SHIFT 10
+
 static inline unsigned long ti_qspi_read(struct ti_qspi *qspi,
unsigned long reg)
 {
@@ -366,6 +377,72 @@ static int qspi_transfer_msg(struct ti_qspi *qspi, struct 
spi_transfer *t)
return 0;
 }
 
+static void ti_qspi_enable_memory_map(struct spi_device *spi)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
+
+   ti_qspi_write(qspi, MM_SWITCH, QSPI_SPI_SWITCH_REG);
+   if (qspi->ctrl_base) {
+   regmap_update_bits(qspi->ctrl_base, qspi->ctrl_reg,
+  MEM_CS_EN(spi->chip_select),
+  MEM_CS_MASK);
+   }
+   qspi->mmap_enabled = true;
+}
+
+static void ti_qspi_disable_memory_map(struct spi_device *spi)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
+
+   ti_qspi_write(qspi, 0, QSPI_SPI_SWITCH_REG);
+   if (qspi->ctrl_base)
+   regmap_update_bits(qspi->ctrl_base, qspi->ctrl_reg,
+  0, MEM_CS_MASK);
+   qspi->mmap_enabled = false;
+}
+
+static void ti_qspi_setup_mmap_read(struct spi_device *spi,
+   struct spi_flash_read_message *msg)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
+   u32 memval = msg->read_opcode;
+
+   switch (msg->data_nbits) {
+   case SPI_NBITS_QUAD:
+   memval |= QSPI_SETUP_RD_QUAD;
+   break;
+   case SPI_NBITS_DUAL:
+   memval |= QSPI_SETUP_RD_DUAL;
+   break;
+   default:
+   memval |= QSPI_SETUP_RD_NORMAL;
+   break;
+   }
+   memval |= ((msg->addr_width - 1) << QSPI_SETUP_ADDR_SHIFT |
+  msg->dummy_bytes << QSPI_SETUP_DUMMY_SHIFT);
+   ti_qspi_write(qspi, memval,
+ QSPI_SPI_SETUP_REG(spi->chip_select));
+}
+
+static int ti_qspi_spi_flash_read(struct  spi_device *spi,
+ struc

[PATCH v5 3/5] mtd: devices: m25p80: add support for mmap read request

2015-12-10 Thread Vignesh R
Certain spi controllers may provide accelerated interface to read from
m25p80 type flash devices. This interface provides better read
performance than regular SPI interface.
Call spi_flash_read(), if supported, to make use of such interface.

Signed-off-by: Vignesh R <vigne...@ti.com>
---

v5: No changes

 drivers/mtd/devices/m25p80.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index fe9ceb7b5405..00094a668c62 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -131,6 +131,26 @@ static int m25p80_read(struct spi_nor *nor, loff_t from, 
size_t len,
/* convert the dummy cycles to the number of bytes */
dummy /= 8;
 
+   if (spi_flash_read_supported(spi)) {
+   struct spi_flash_read_message msg;
+   int ret;
+
+   msg.buf = buf;
+   msg.from = from;
+   msg.len = len;
+   msg.read_opcode = nor->read_opcode;
+   msg.addr_width = nor->addr_width;
+   msg.dummy_bytes = dummy;
+   /* TODO: Support other combinations */
+   msg.opcode_nbits = SPI_NBITS_SINGLE;
+   msg.addr_nbits = SPI_NBITS_SINGLE;
+   msg.data_nbits = m25p80_rx_nbits(nor);
+
+   ret = spi_flash_read(spi, );
+   *retlen = msg.retlen;
+   return ret;
+   }
+
spi_message_init();
memset(t, 0, (sizeof t));
 
-- 
2.6.3

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 0/5] Add memory mapped read support for ti-qspi

2015-12-10 Thread Vignesh R
Changes since v4:
Use syscon to access system control module register in ti-qspi driver.

Changes since v3:
Rework to introduce spi_flash_read_message struct.
Support different opcode/addr/data formats as per Brian's suggestion
here: https://lkml.org/lkml/2015/11/11/454

Changes since v2:
Remove mmap_lock_mutex.
Optimize enable/disable of mmap mode.

Changes since v1:
Introduce API in SPI core that MTD flash driver can call for mmap read
instead of directly calling spi-master driver callback. This API makes
sure that SPI core msg queue is locked during mmap transfers.
v1: https://lkml.org/lkml/2015/9/4/103


Cover letter:

This patch series adds support for memory mapped read port of ti-qspi.
ti-qspi has a special memory mapped port through which SPI flash
memories can be accessed directly via SoC specific memory region.

First patch adds a method to pass flash specific information like read
opcode, dummy bytes etc and to request mmap read. Second patch
implements mmap read method in ti-qspi driver. Patch 3 adapts m25p80 to
use mmap read method before trying normal SPI transfer. Patch 4 and 5
add memory map region DT entries for DRA7xx and AM43xx SoCs.

This patch series is based on the discussions here:
http://www.spinics.net/lists/linux-spi/msg04796.html

Tested on DRA74 EVM and AM437x-SK.
Read performance increases from ~100kB/s to ~2.5MB/s.

Vignesh R (5):
  spi: introduce accelerated read support for spi flash devices
  spi: spi-ti-qspi: add mmap mode read support
  mtd: devices: m25p80: add support for mmap read request
  ARM: dts: DRA7: add entry for qspi mmap region
  ARM: dts: AM4372: add entry for qspi mmap region

 Documentation/devicetree/bindings/spi/ti_qspi.txt |  22 +++-
 arch/arm/boot/dts/am4372.dtsi |   4 +-
 arch/arm/boot/dts/dra7.dtsi   |   6 +-
 drivers/mtd/devices/m25p80.c  |  20 
 drivers/spi/spi-ti-qspi.c | 139 +-
 drivers/spi/spi.c |  45 +++
 include/linux/spi/spi.h   |  41 +++
 7 files changed, 243 insertions(+), 34 deletions(-)

-- 
2.6.3

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 1/5] spi: introduce accelerated read support for spi flash devices

2015-12-10 Thread Vignesh R
In addition to providing direct access to SPI bus, some spi controller
hardwares (like ti-qspi) provide special port (like memory mapped port)
that are optimized to improve SPI flash read performance.
This means the controller can automatically send the SPI signals
required to read data from the SPI flash device.
For this, SPI controller needs to know flash specific information like
read command to use, dummy bytes and address width.

Introduce spi_flash_read() interface to support accelerated read
over SPI flash devices. SPI master drivers can implement this callback to
support interfaces such as memory mapped read etc. m25p80 flash driver
and other flash drivers can call this make use of such interfaces. The
interface should only be used with SPI flashes and cannot be used with
other SPI devices.

Signed-off-by: Vignesh R <vigne...@ti.com>
---

v5: No changes.

 drivers/spi/spi.c   | 45 +
 include/linux/spi/spi.h | 41 +
 2 files changed, 86 insertions(+)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index e2415be209d5..cc2b54139352 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1134,6 +1134,7 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
}
}
 
+   mutex_lock(>bus_lock_mutex);
trace_spi_message_start(master->cur_msg);
 
if (master->prepare_message) {
@@ -1143,6 +1144,7 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
"failed to prepare message: %d\n", ret);
master->cur_msg->status = ret;
spi_finalize_current_message(master);
+   mutex_unlock(>bus_lock_mutex);
return;
}
master->cur_msg_prepared = true;
@@ -1152,6 +1154,7 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
if (ret) {
master->cur_msg->status = ret;
spi_finalize_current_message(master);
+   mutex_unlock(>bus_lock_mutex);
return;
}
 
@@ -1159,8 +1162,10 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
if (ret) {
dev_err(>dev,
"failed to transfer one message from queue\n");
+   mutex_unlock(>bus_lock_mutex);
return;
}
+   mutex_unlock(>bus_lock_mutex);
 }
 
 /**
@@ -2327,6 +2332,46 @@ int spi_async_locked(struct spi_device *spi, struct 
spi_message *message)
 EXPORT_SYMBOL_GPL(spi_async_locked);
 
 
+int spi_flash_read(struct spi_device *spi,
+  struct spi_flash_read_message *msg)
+
+{
+   struct spi_master *master = spi->master;
+   int ret;
+
+   if ((msg->opcode_nbits == SPI_NBITS_DUAL ||
+msg->addr_nbits == SPI_NBITS_DUAL) &&
+   !(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD)))
+   return -EINVAL;
+   if ((msg->opcode_nbits == SPI_NBITS_QUAD ||
+msg->addr_nbits == SPI_NBITS_QUAD) &&
+   !(spi->mode & SPI_TX_QUAD))
+   return -EINVAL;
+   if (msg->data_nbits == SPI_NBITS_DUAL &&
+   !(spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD)))
+   return -EINVAL;
+   if (msg->data_nbits == SPI_NBITS_QUAD &&
+   !(spi->mode &  SPI_RX_QUAD))
+   return -EINVAL;
+
+   if (master->auto_runtime_pm) {
+   ret = pm_runtime_get_sync(master->dev.parent);
+   if (ret < 0) {
+   dev_err(>dev, "Failed to power device: %d\n",
+   ret);
+   return ret;
+   }
+   }
+   mutex_lock(>bus_lock_mutex);
+   ret = master->spi_flash_read(spi, msg);
+   mutex_unlock(>bus_lock_mutex);
+   if (master->auto_runtime_pm)
+   pm_runtime_put(master->dev.parent);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(spi_flash_read);
+
 /*-*/
 
 /* Utility methods for SPI master protocol drivers, layered on
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index cce80e6dc7d1..246d7d519f3f 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -25,6 +25,7 @@
 struct dma_chan;
 struct spi_master;
 struct spi_transfer;
+struct spi_flash_read_message;
 
 /*
  * INTERFACES between SPI master-side drivers and SPI infrastructure.
@@ -361,6 +362,8 @@ static inline void spi_unregister_driver(struct spi_driver 
*sdrv)
  * @handle_err: the subsystem calls the driver to handle an error that occurs
  * in the generic implementation of transfer_one_message().
  * @un

[PATCH v5 5/5] ARM: dts: AM4372: add entry for qspi mmap region

2015-12-10 Thread Vignesh R
Add qspi memory mapped region entries for AM43xx based SoCs. Also,
update the binding documents for the controller to document this change.

Acked-by: Rob Herring <r...@kernel.org>
Signed-off-by: Vignesh R <vigne...@ti.com>
---

v5: No changes.

 Documentation/devicetree/bindings/spi/ti_qspi.txt | 5 +++--
 arch/arm/boot/dts/am4372.dtsi | 4 +++-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/ti_qspi.txt 
b/Documentation/devicetree/bindings/spi/ti_qspi.txt
index 809c3f334316..cc8304aa64ac 100644
--- a/Documentation/devicetree/bindings/spi/ti_qspi.txt
+++ b/Documentation/devicetree/bindings/spi/ti_qspi.txt
@@ -21,9 +21,10 @@ Optional properties:
 
 Example:
 
+For am4372:
 qspi: qspi@4b30 {
-   compatible = "ti,dra7xxx-qspi";
-   reg = <0x4790 0x100>, <0x3000 0x3ff>;
+   compatible = "ti,am4372-qspi";
+   reg = <0x4790 0x100>, <0x3000 0x400>;
reg-names = "qspi_base", "qspi_mmap";
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index d83ff9c9701e..e32d164102d1 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -963,7 +963,9 @@
 
qspi: qspi@4790 {
compatible = "ti,am4372-qspi";
-   reg = <0x4790 0x100>;
+   reg = <0x4790 0x100>,
+ <0x3000 0x400>;
+   reg-names = "qspi_base", "qspi_mmap";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "qspi";
-- 
2.6.3

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 4/5] ARM: dts: DRA7: add entry for qspi mmap region

2015-12-10 Thread Vignesh R
Add qspi memory mapped region entries for DRA7xx based SoCs. Also,
update the binding documents for the controller to document this change.

Signed-off-by: Vignesh R <vigne...@ti.com>
---

v5: use syscon to access scm register.

 Documentation/devicetree/bindings/spi/ti_qspi.txt | 17 +
 arch/arm/boot/dts/dra7.dtsi   |  6 --
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/ti_qspi.txt 
b/Documentation/devicetree/bindings/spi/ti_qspi.txt
index 601a360531a5..809c3f334316 100644
--- a/Documentation/devicetree/bindings/spi/ti_qspi.txt
+++ b/Documentation/devicetree/bindings/spi/ti_qspi.txt
@@ -15,6 +15,10 @@ Recommended properties:
 - spi-max-frequency: Definition as per
  Documentation/devicetree/bindings/spi/spi-bus.txt
 
+Optional properties:
+- syscon-chipselects: Handle to system control region contains QSPI
+ chipselect register and offset of that register.
+
 Example:
 
 qspi: qspi@4b30 {
@@ -26,3 +30,16 @@ qspi: qspi@4b30 {
spi-max-frequency = <2500>;
ti,hwmods = "qspi";
 };
+
+For dra7xx:
+qspi: qspi@4b30 {
+   compatible = "ti,dra7xxx-qspi";
+   reg = <0x4b30 0x100>,
+ <0x5c00 0x400>,
+   reg-names = "qspi_base", "qspi_mmap";
+   syscon-chipselects = <_conf 0x558>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   spi-max-frequency = <4800>;
+   ti,hwmods = "qspi";
+};
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index fe99231cbde5..be91c7781c07 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1153,8 +1153,10 @@
 
qspi: qspi@4b30 {
compatible = "ti,dra7xxx-qspi";
-   reg = <0x4b30 0x100>;
-   reg-names = "qspi_base";
+   reg = <0x4b30 0x100>,
+ <0x5c00 0x400>;
+   reg-names = "qspi_base", "qspi_mmap";
+   syscon-chipselects = <_conf 0x558>;
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "qspi";
-- 
2.6.3

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 4/5] ARM: dts: DRA7: add entry for qspi mmap region

2015-12-09 Thread Vignesh R


On 12/03/2015 03:51 PM, Vignesh R wrote:
> 
> 
> On 12/01/2015 10:09 PM, Tony Lindgren wrote:
>> * Vignesh R <vigne...@ti.com> [151130 20:46]:
>>> On 12/01/2015 04:04 AM, Tony Lindgren wrote:
>>>>
...
>>
>> OK. They are both on L3 main so that won't cause any issues for separate
>> interconnect driver instances. As they are still separate targets flushing
>> a posted write to one area will not flush anything to the other.
>>
> 
> I didn't quite understand what you meant by interconnect driver instance.
> qspi_base and qspi_mmap region are tightly bound to each other and both
> needs to be accessed by ti-qspi driver (though different targets).
> Besides qspi_mmap region is only used to read data, there will not be
> any write accesses to this target. Are you saying this binding is not
> viable?
> 

As I stated above qspi_base and qspi_mmap region are tightly bound,
there is no way to use qspi_mmap region w/o accessing qspi_base. So I am
planning to keep them as it is. I will move qspi_ctrlmod to use syscon.
Something like:

qspi: qspi@4b30 {
   compatible = "ti,dra7xxx-qspi";
   reg = <0x4b30 0x100>,
 <0x5c00 0x400>,
   reg-names = "qspi_base", "qspi_mmap";
   syscon-chipselects = <_conf 0x558>;
   #address-cells = <1>;
   #size-cells = <0>;
   spi-max-frequency = <4800>;
   ti,hwmods = "qspi";
};

Do you think this is not viable in future?


-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 4/5] ARM: dts: DRA7: add entry for qspi mmap region

2015-12-03 Thread Vignesh R


On 12/01/2015 10:09 PM, Tony Lindgren wrote:
> * Vignesh R <vigne...@ti.com> [151130 20:46]:
>> On 12/01/2015 04:04 AM, Tony Lindgren wrote:
>>>
>>> Actually none of the IO areas above are within the same interconnect target:
>>>
>>> 0x4b30  QSPI0 address space in L3 main interconnect
>>> 0x5c00  QSPI1 address space in L3 main interconnect
>>
>>
>> First address range (configuration port: 0x4b30) corresponds to QSPI
>> registers space. These registers alone are sufficient for generic SPI
>> communication (serial flash as well as non-flash SPI devices).
> 
> OK
> 
>> In order to speed up SPI flash reads SFI_MM_IF(SPI memory mapped
>> interface) is provided by QSPI IP. This _cannot_ be used with non-flash
>> devices.
> 
> OK
> 
>> The second address range (0x5c00) corresponds to memory-mapped
>> region of SFI_MM_IF, through which SPI flash memories can be read as if
>> though they were RAM addresses (i.e using readl/memcpy). The SFI_MM_IF
>> block that takes care of communicating over SPI bus and getting the data
>> from flash device.
> 
> OK
> 
>> But SFI_MM_IF block needs to know some flash specific information(such
>> as read opcode, address bytes, dummy bytes, mode). This information must
>> first be populated in QSPI_SPI_SETUP*_REG(0x4B300054-60) before
>> accessing SFI_MM_IF address range via readl.
>> Both addresses space belong to same instance of the driver, one
>> corresponds to register space and other is memory-mapped region.
>> Therefore both regions are claimed by the same driver.
> 
> OK
> 
>>> 0x4a002558  CTRL_CORE_CONTROL_IO_2 in System Control Module (SCM) in L4_CFG
>>>
>>> The first two address spaces should be two separate instances of this 
>>> driver.
>>
>> Not actually two instances.
> 
> OK. They are both on L3 main so that won't cause any issues for separate
> interconnect driver instances. As they are still separate targets flushing
> a posted write to one area will not flush anything to the other.
> 

I didn't quite understand what you meant by interconnect driver instance.
qspi_base and qspi_mmap region are tightly bound to each other and both
needs to be accessed by ti-qspi driver (though different targets).
Besides qspi_mmap region is only used to read data, there will not be
any write accesses to this target. Are you saying this binding is not
viable?

>>> The CTRL_CORE_CONTROL_IO_2 needs seems like a shared clock register that
>>> needs to be accessed using the clock framework most likely.
>>>
>>
>> Not shared clock.
>> The CTRL_CORE_CONTROL_IO_2[10:8] QSPI_MEMMAPPED_CS bit fields provides a
>> functionality for remapping the previously described address space which
>> starts at 0x5C00 L3_MAIN address to one of the four supported chip
>> selects.
>> How about using syscon to access CTRL_CORE_CONTROL_IO_2?
> 
> A separate driver implementing some Linux generic framework would be idael :)
> 
> But if that does not fit, yeah then syscon makes sense as that IO range
> will be on separate interconnect driver (and clock and possibly power domain)
> instances eventually.
> 

I will go ahead with syscon for accessing CTRL_CORE_CONTROL_IO_2 register.

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 3/5] mtd: devices: m25p80: add support for mmap read request

2015-12-03 Thread Vignesh R
Hi,

On 12/03/2015 03:12 PM, Cyrille Pitchen wrote:
> Hi Vignesh,
> 
> Le 30/11/2015 06:15, Vignesh R a écrit :
>> Certain spi controllers may provide accelerated interface to read from
>> m25p80 type flash devices. This interface provides better read
>> performance than regular SPI interface.
>> Call spi_flash_read(), if supported, to make use of such interface.
>>
>> Signed-off-by: Vignesh R <vigne...@ti.com>
>> ---
>>
>> v4: 
>>  * Use spi_flash_read_message struct to pass args.
>>  * support passing of opcode/addr/data nbits.
>>
>>  drivers/mtd/devices/m25p80.c | 20 
>>  1 file changed, 20 insertions(+)
>>
>> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
>> index fe9ceb7b5405..00094a668c62 100644
>> --- a/drivers/mtd/devices/m25p80.c
>> +++ b/drivers/mtd/devices/m25p80.c
>> @@ -131,6 +131,26 @@ static int m25p80_read(struct spi_nor *nor, loff_t 
>> from, size_t len,
>>  /* convert the dummy cycles to the number of bytes */
>>  dummy /= 8;
>>  
>> +if (spi_flash_read_supported(spi)) {
>> +struct spi_flash_read_message msg;
>> +int ret;
>> +
>> +msg.buf = buf;
>> +msg.from = from;
>> +msg.len = len;
>> +msg.read_opcode = nor->read_opcode;
>> +msg.addr_width = nor->addr_width;
>> +msg.dummy_bytes = dummy;
>> +/* TODO: Support other combinations */
>> +msg.opcode_nbits = SPI_NBITS_SINGLE;
>> +msg.addr_nbits = SPI_NBITS_SINGLE;
>> +msg.data_nbits = m25p80_rx_nbits(nor);
> 
> I wanted to let you know that the support of other SPI protocols has already
> been implemented by this series:
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-September/371170.html
> 
> patches 2 & 3 handle the probing of the (Q)SPI memory in spi_nor_scan() and
> select the right protocols for register read/write, memory read, memory write,
> and memory erase operations. The choice is done according to both the memory
> and SPI controller capabilities.
> 
> patch 4 updates the m25p80 driver to take advantage of the bandwidth increase
> allowed by QSPI protocols. For instance, the Atmel QSPI controller, like TI
> one, maps the SPI NOR memory to the system bus. Yesterday I ran mtd_speedtest
> to compare Fast Read 1-1-1 (0x0b) and Fast Read 1-1-4 (0x6b). The SPI clock
> frequency was limited to 83MHz. The QSPI memory is a Micron n25q128a13.
> 
> I only had to change the mode argument of spi_nor_scan() from SPI_NOR_QUAD to
> SPI_NOR_FAST in the atmel_quadspi driver (based on fsl-quadspi driver from
> Freescale since Atmel's driver also uses the system bus mapping for memory
> write operations) to force the spi-nor framework to choose the SPI 1-1-1
> protocol instead of the SPI-1-1-4.
> 
> 1 - Fast Read 1-1-1
> 
> mtd_speedtest: testing eraseblock write speed
> mtd_speedtest: eraseblock read speed is 9319 KiB/s
> [...]
> mtd_speedtest: testing page read speed
> mtd_speedtest: page read speed is 6649 KiB/s
> [...]
> mtd_speedtest: testing 2 page read speed
> mtd_speedtest: 2 page read speed is 7757 KiB/s
> 
> 2 - Fast Read 1-1-4
> 
> mtd_speedtest: testing eraseblock read speed
> mtd_speedtest: eraseblock read speed is 30117 KiB/s
> [...]
> mtd_speedtest: testing page read speed
> mtd_speedtest: page read speed is 13096 KiB/s
> [...]
> mtd_speedtest: testing 2 page read speed
> mtd_speedtest: 2 page read speed is 18224 KiB/s
> 
> So the performance improvements are:
> eraseblock read speed (65536 bytes) : +223%
> page read speed (512 bytes) :  +97%
> 2 page read speed (1024 bytes)  : +135%
> 
> 
> That's why I believe that you could take advantage of these performance
> improvements in the TI (Q)SPI controller driver.
> 

Well, I based my patches on linux-next as per Brian's suggestion. If
patches to support other flash protocol modes are accepted, I would be
happy to rebase and make use of other modes. It would just be the matter
of populating msg.{opcode/addr}_n_bits correctly.


> 
> Also please note that you may have to add in the struct spi_flash_read_message
> two other fields for the number of option/mode cycles and their value.
> Option/mode cycles are sent between the address and dummy cycles. They are
> used by some memory manufacturers such as Spansion, Micron and Macronix to
> enter/leave their continuous read mode.
> So if uninitialized dummy cycles are interpreted by the QSPI memory as
> option/mode cycles, depending on the actual value, the memory may enter by
> mista

Re: [PATCH v4 4/5] ARM: dts: DRA7: add entry for qspi mmap region

2015-11-30 Thread Vignesh R


On 12/01/2015 04:04 AM, Tony Lindgren wrote:
> * Vignesh R <vigne...@ti.com> [151129 21:16]:
>> Add qspi memory mapped region entries for DRA7xx based SoCs. Also,
>> update the binding documents for the controller to document this change.
>>
>> Acked-by: Rob Herring <r...@kernel.org>
>> Signed-off-by: Vignesh R <vigne...@ti.com>
> ...
>> --- a/Documentation/devicetree/bindings/spi/ti_qspi.txt
>> +++ b/Documentation/devicetree/bindings/spi/ti_qspi.txt
>> @@ -26,3 +26,17 @@ qspi: qspi@4b30 {
>>  spi-max-frequency = <2500>;
>>  ti,hwmods = "qspi";
>>  };
>> +
>> +For dra7xx:
>> +qspi: qspi@4b30 {
>> +compatible = "ti,dra7xxx-qspi";
>> +reg = <0x4b30 0x100>,
>> +  <0x5c00 0x400>,
>> +  <0x4a002558 0x4>;
>> +reg-names = "qspi_base", "qspi_mmap",
>> +"qspi_ctrlmod";
>> +#address-cells = <1>;
>> +#size-cells = <0>;
>> +spi-max-frequency = <4800>;
>> +ti,hwmods = "qspi";
>> +};
> 
> Actually none of the IO areas above are within the same interconnect target:
> 
> 0x4b30  QSPI0 address space in L3 main interconnect
> 0x5c00  QSPI1 address space in L3 main interconnect


First address range (configuration port: 0x4b30) corresponds to QSPI
registers space. These registers alone are sufficient for generic SPI
communication (serial flash as well as non-flash SPI devices).

In order to speed up SPI flash reads SFI_MM_IF(SPI memory mapped
interface) is provided by QSPI IP. This _cannot_ be used with non-flash
devices.
The second address range (0x5c00) corresponds to memory-mapped
region of SFI_MM_IF, through which SPI flash memories can be read as if
though they were RAM addresses (i.e using readl/memcpy). The SFI_MM_IF
block that takes care of communicating over SPI bus and getting the data
from flash device.
But SFI_MM_IF block needs to know some flash specific information(such
as read opcode, address bytes, dummy bytes, mode). This information must
first be populated in QSPI_SPI_SETUP*_REG(0x4B300054-60) before
accessing SFI_MM_IF address range via readl.
Both addresses space belong to same instance of the driver, one
corresponds to register space and other is memory-mapped region.
Therefore both regions are claimed by the same driver.

> 0x4a002558  CTRL_CORE_CONTROL_IO_2 in System Control Module (SCM) in L4_CFG
> 
> The first two address spaces should be two separate instances of this driver.

Not actually two instances.

> The CTRL_CORE_CONTROL_IO_2 needs seems like a shared clock register that
> needs to be accessed using the clock framework most likely.
> 

Not shared clock.
The CTRL_CORE_CONTROL_IO_2[10:8] QSPI_MEMMAPPED_CS bit fields provides a
functionality for remapping the previously described address space which
starts at 0x5C00 L3_MAIN address to one of the four supported chip
selects.
How about using syscon to access CTRL_CORE_CONTROL_IO_2?

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 2/5] spi: spi-ti-qspi: add mmap mode read support

2015-11-30 Thread Vignesh R
Hi Felipe,

On 12/01/2015 04:05 AM, Balbi, Felipe wrote:
> 
> Hi,
> 
> Vignesh R <vigne...@ti.com> writes:
[...]
>> +}
>> +
>> +static int ti_qspi_spi_flash_read(struct  spi_device *spi,
>> +  struct spi_flash_read_message *msg)
>> +{
>> +struct ti_qspi *qspi = spi_master_get_devdata(spi->master);
>> +int ret = 0;
>> +
>> +mutex_lock(>list_lock);
>> +
>> +if (!qspi->mmap_enabled)
>> +ti_qspi_enable_memory_map(spi);
>> +ti_qspi_setup_mmap_read(spi, msg);
>> +memcpy_fromio(msg->buf, qspi->mmap_base + msg->from, msg->len);
>> +msg->retlen = msg->len;
> 
> the way I have always expected this to work was that spi controller
> would setup the mmap region (using ranges?) and pass the base address to
> the SPI NOR flash instead, so that could call standard
> write[bwl]/read[bwl] functions.
> 
> I mean, when we're dealing with AXI, AHB, PCI, OCP, whatever we
> completely ignore these details, why should SPI be different ? If it's
> memory mapped, the SW view of the thing is a piece of memory and that
> should be accessible with standard {read,write}[bwl]() calls.
> 

This is just an acceleration provided to improve flash read speeds.
Whenever there is an access to QSPI memory map region, there is a
SFI_MM_IF block in QSPI IP that generates SPI bus signals in order fetch
the data from flash. This SFI_MM_IF must first be configured with flash
specific information like read opcode, read mode, dummy bytes etc (which
may vary from flash to flash), by writing to QSPI_SPI_SETUP*_REG also,
SFI_MM_IF needs to be selected by writing to QSPI_SPI_SWITCH_REG.
IMO, there has to be a call from spi-nor to ti-qspi before using
standard {read,write}[bwl]() calls for populating flash info, power mgmt
and locking SPI bus.

> I really think $subject is not a good way forward because it gives too
> much responsibility to the SPI controller driver; note that this driver
> is the one actually accessing the memory map region, instead of simply
> setting it up and passing it along.
> 

How would you propose to setup mmap transfers while taking care of SPI
bus locking and passing of flash info to ti-qspi?


> So the way I see it, the DTS should be like so:
> 
> qspi@XYZ {
>  reg = ;
>  [...]
>  ranges = <0 0 0x3000 $size>;
> 
>  flash@0,0 {
>compatible = "mp2580";
>reg = <0 0 $flash_size>;
>  };
> };
> 
> 
> if you have more than one device sitting on this SPI bus using different
> chip selects, that's easy too, just change your ranges property:
> 
> qspi@XYZ {
>  reg = ;
>  [...]
>  ranges = <0 0 0x3000 0x1000
>1 0 0x30001000 0x1000
>2 0 0x30002000 0x1000>;
> 
>  flash@0,0 {
>  [...]
>  };
> 
>  flash@1,0 {
>[...]
>  };
> 
>  flash@2,0 {
>[...]
>   };
> };
> 

No, even if there are multiple slaves, all slaves map to the same start
address (0x3000 in above example). Based on the chip-select line
that is asserted (selected by writing to a particular CTRL_MODULE
register field), the corresponding slave responds. Different slaves
cannot be mapped to different address ranges inside mmap address space.
The ranges property will always be the same for all slaves and all
chip-selects.

> and so on. From ti-qspi perspective, you should just setup the memory
> map and from mp25p80 you would check if your reg property pointed to an
> address that looks like memory, then ioremap it and use tradicional
> {read,write}[bwl]() accessors. Any reasons why that wasn't done the way
> pointed out above ?
> 

There might be a SPI controller that provides accelerated interface for
SPI flash read not as a memory mapping but some-other way. Brian Norris
has pointed out that there is at least one other controller which
provides such acceleration w/o memory mapping[1] May be Brian can
explain that better?


[1]https://lkml.org/lkml/2015/11/10/618

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 1/5] spi: introduce accelerated read support for spi flash devices

2015-11-29 Thread Vignesh R
In addition to providing direct access to SPI bus, some spi controller
hardwares (like ti-qspi) provide special port (like memory mapped port)
that are optimized to improve SPI flash read performance.
This means the controller can automatically send the SPI signals
required to read data from the SPI flash device.
For this, SPI controller needs to know flash specific information like
read command to use, dummy bytes and address width.

Introduce spi_flash_read() interface to support accelerated read
over SPI flash devices. SPI master drivers can implement this callback to
support interfaces such as memory mapped read etc. m25p80 flash driver
and other flash drivers can call this make use of such interfaces. The
interface should only be used with SPI flashes and cannot be used with
other SPI devices.

Signed-off-by: Vignesh R <vigne...@ti.com>
---
 drivers/spi/spi.c   | 45 +
 include/linux/spi/spi.h | 41 +
 2 files changed, 86 insertions(+)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index e2415be209d5..cc2b54139352 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1134,6 +1134,7 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
}
}
 
+   mutex_lock(>bus_lock_mutex);
trace_spi_message_start(master->cur_msg);
 
if (master->prepare_message) {
@@ -1143,6 +1144,7 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
"failed to prepare message: %d\n", ret);
master->cur_msg->status = ret;
spi_finalize_current_message(master);
+   mutex_unlock(>bus_lock_mutex);
return;
}
master->cur_msg_prepared = true;
@@ -1152,6 +1154,7 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
if (ret) {
master->cur_msg->status = ret;
spi_finalize_current_message(master);
+   mutex_unlock(>bus_lock_mutex);
return;
}
 
@@ -1159,8 +1162,10 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
if (ret) {
dev_err(>dev,
"failed to transfer one message from queue\n");
+   mutex_unlock(>bus_lock_mutex);
return;
}
+   mutex_unlock(>bus_lock_mutex);
 }
 
 /**
@@ -2327,6 +2332,46 @@ int spi_async_locked(struct spi_device *spi, struct 
spi_message *message)
 EXPORT_SYMBOL_GPL(spi_async_locked);
 
 
+int spi_flash_read(struct spi_device *spi,
+  struct spi_flash_read_message *msg)
+
+{
+   struct spi_master *master = spi->master;
+   int ret;
+
+   if ((msg->opcode_nbits == SPI_NBITS_DUAL ||
+msg->addr_nbits == SPI_NBITS_DUAL) &&
+   !(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD)))
+   return -EINVAL;
+   if ((msg->opcode_nbits == SPI_NBITS_QUAD ||
+msg->addr_nbits == SPI_NBITS_QUAD) &&
+   !(spi->mode & SPI_TX_QUAD))
+   return -EINVAL;
+   if (msg->data_nbits == SPI_NBITS_DUAL &&
+   !(spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD)))
+   return -EINVAL;
+   if (msg->data_nbits == SPI_NBITS_QUAD &&
+   !(spi->mode &  SPI_RX_QUAD))
+   return -EINVAL;
+
+   if (master->auto_runtime_pm) {
+   ret = pm_runtime_get_sync(master->dev.parent);
+   if (ret < 0) {
+   dev_err(>dev, "Failed to power device: %d\n",
+   ret);
+   return ret;
+   }
+   }
+   mutex_lock(>bus_lock_mutex);
+   ret = master->spi_flash_read(spi, msg);
+   mutex_unlock(>bus_lock_mutex);
+   if (master->auto_runtime_pm)
+   pm_runtime_put(master->dev.parent);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(spi_flash_read);
+
 /*-*/
 
 /* Utility methods for SPI master protocol drivers, layered on
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index cce80e6dc7d1..246d7d519f3f 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -25,6 +25,7 @@
 struct dma_chan;
 struct spi_master;
 struct spi_transfer;
+struct spi_flash_read_message;
 
 /*
  * INTERFACES between SPI master-side drivers and SPI infrastructure.
@@ -361,6 +362,8 @@ static inline void spi_unregister_driver(struct spi_driver 
*sdrv)
  * @handle_err: the subsystem calls the driver to handle an error that occurs
  * in the generic implementation of transfer_one_message().
  * @unprepare_messag

[PATCH v4 0/5] Add memory mapped read support for ti-qspi

2015-11-29 Thread Vignesh R
Changes since v3:
Rework to introduce spi_flash_read_message struct.
Support different opcode/addr/data formats as per Brian's suggestion
here: https://lkml.org/lkml/2015/11/11/454

Changes since v2:
Remove mmap_lock_mutex.
Optimize enable/disable of mmap mode.

Changes since v1:
Introduce API in SPI core that MTD flash driver can call for mmap read
instead of directly calling spi-master driver callback. This API makes
sure that SPI core msg queue is locked during mmap transfers.
v1: https://lkml.org/lkml/2015/9/4/103


Cover letter:

This patch series adds support for memory mapped read port of ti-qspi.
ti-qspi has a special memory mapped port through which SPI flash
memories can be accessed directly via SoC specific memory region.

First patch adds a method to pass flash specific information like read
opcode, dummy bytes etc and to request mmap read. Second patch
implements mmap read method in ti-qspi driver. Patch 3 adapts m25p80 to
use mmap read method before trying normal SPI transfer. Patch 4 and 5
add memory map region DT entries for DRA7xx and AM43xx SoCs.

This patch series is based on the discussions here:
http://www.spinics.net/lists/linux-spi/msg04796.html

Tested on DRA74 EVM and AM437x-SK.
Read performance increases from ~100kB/s to ~2.5MB/s.


Vignesh R (5):
  spi: introduce accelerated read support for spi flash devices
  spi: spi-ti-qspi: add mmap mode read support
  mtd: devices: m25p80: add support for mmap read request
  ARM: dts: DRA7: add entry for qspi mmap region
  ARM: dts: AM4372: add entry for qspi mmap region

 Documentation/devicetree/bindings/spi/ti_qspi.txt |  19 +++-
 arch/arm/boot/dts/am4372.dtsi |   4 +-
 arch/arm/boot/dts/dra7.dtsi   |   7 +-
 drivers/mtd/devices/m25p80.c  |  20 +
 drivers/spi/spi-ti-qspi.c | 101 --
 drivers/spi/spi.c |  45 ++
 include/linux/spi/spi.h   |  41 +
 7 files changed, 225 insertions(+), 12 deletions(-)

-- 
2.6.3

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 3/5] mtd: devices: m25p80: add support for mmap read request

2015-11-29 Thread Vignesh R
Certain spi controllers may provide accelerated interface to read from
m25p80 type flash devices. This interface provides better read
performance than regular SPI interface.
Call spi_flash_read(), if supported, to make use of such interface.

Signed-off-by: Vignesh R <vigne...@ti.com>
---

v4: 
 * Use spi_flash_read_message struct to pass args.
 * support passing of opcode/addr/data nbits.

 drivers/mtd/devices/m25p80.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index fe9ceb7b5405..00094a668c62 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -131,6 +131,26 @@ static int m25p80_read(struct spi_nor *nor, loff_t from, 
size_t len,
/* convert the dummy cycles to the number of bytes */
dummy /= 8;
 
+   if (spi_flash_read_supported(spi)) {
+   struct spi_flash_read_message msg;
+   int ret;
+
+   msg.buf = buf;
+   msg.from = from;
+   msg.len = len;
+   msg.read_opcode = nor->read_opcode;
+   msg.addr_width = nor->addr_width;
+   msg.dummy_bytes = dummy;
+   /* TODO: Support other combinations */
+   msg.opcode_nbits = SPI_NBITS_SINGLE;
+   msg.addr_nbits = SPI_NBITS_SINGLE;
+   msg.data_nbits = m25p80_rx_nbits(nor);
+
+   ret = spi_flash_read(spi, );
+   *retlen = msg.retlen;
+   return ret;
+   }
+
spi_message_init();
memset(t, 0, (sizeof t));
 
-- 
2.6.3

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 2/5] spi: spi-ti-qspi: add mmap mode read support

2015-11-29 Thread Vignesh R
ti-qspi controller provides mmap port to read data from SPI flashes.
mmap port is enabled in QSPI_SPI_SWITCH_REG. ctrl module register may
also need to be accessed for some SoCs. The QSPI_SPI_SETUP_REGx needs to
be populated with flash specific information like read opcode, read
mode(quad, dual, normal), address width and dummy bytes. Once,
controller is in mmap mode, the whole flash memory is available as a
memory region at SoC specific address. This region can be accessed using
normal memcpy() (or mem-to-mem dma copy). The ti-qspi controller hardware
will internally communicate with SPI flash over SPI bus and get the
requested data.

Implement spi_flash_read() callback to support mmap read over SPI
flash devices. With this, the read throughput increases from ~100kB/s to
~2.5 MB/s.

Signed-off-by: Vignesh R <vigne...@ti.com>
---

 drivers/spi/spi-ti-qspi.c | 101 ++
 1 file changed, 94 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index 64318fcfacf2..cd4e63f45e65 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -56,6 +56,7 @@ struct ti_qspi {
u32 dc;
 
bool ctrl_mod;
+   bool mmap_enabled;
 };
 
 #define QSPI_PID   (0x0)
@@ -65,11 +66,8 @@ struct ti_qspi {
 #define QSPI_SPI_CMD_REG   (0x48)
 #define QSPI_SPI_STATUS_REG(0x4c)
 #define QSPI_SPI_DATA_REG  (0x50)
-#define QSPI_SPI_SETUP0_REG(0x54)
+#define QSPI_SPI_SETUP_REG(n)  ((0x54 + 4 * n))
 #define QSPI_SPI_SWITCH_REG(0x64)
-#define QSPI_SPI_SETUP1_REG(0x58)
-#define QSPI_SPI_SETUP2_REG(0x5c)
-#define QSPI_SPI_SETUP3_REG(0x60)
 #define QSPI_SPI_DATA_REG_1(0x68)
 #define QSPI_SPI_DATA_REG_2(0x6c)
 #define QSPI_SPI_DATA_REG_3(0x70)
@@ -109,6 +107,16 @@ struct ti_qspi {
 
 #define QSPI_AUTOSUSPEND_TIMEOUT 2000
 
+#define MEM_CS_EN(n)   ((n + 1) << 8)
+
+#define MM_SWITCH  0x1
+
+#define QSPI_SETUP_RD_NORMAL   (0x0 << 12)
+#define QSPI_SETUP_RD_DUAL (0x1 << 12)
+#define QSPI_SETUP_RD_QUAD (0x3 << 12)
+#define QSPI_SETUP_ADDR_SHIFT  8
+#define QSPI_SETUP_DUMMY_SHIFT 10
+
 static inline unsigned long ti_qspi_read(struct ti_qspi *qspi,
unsigned long reg)
 {
@@ -366,6 +374,78 @@ static int qspi_transfer_msg(struct ti_qspi *qspi, struct 
spi_transfer *t)
return 0;
 }
 
+static void ti_qspi_enable_memory_map(struct spi_device *spi)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
+   u32 val;
+
+   ti_qspi_write(qspi, MM_SWITCH, QSPI_SPI_SWITCH_REG);
+   if (qspi->ctrl_mod) {
+   val = readl(qspi->ctrl_base);
+   val |= MEM_CS_EN(spi->chip_select);
+   writel(val, qspi->ctrl_base);
+   /* dummy readl to ensure bus sync */
+   readl(qspi->ctrl_base);
+   }
+   qspi->mmap_enabled = true;
+}
+
+static void ti_qspi_disable_memory_map(struct spi_device *spi)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
+   u32 val;
+
+   ti_qspi_write(qspi, 0, QSPI_SPI_SWITCH_REG);
+   if (qspi->ctrl_mod) {
+   val = readl(qspi->ctrl_base);
+   val &= ~MEM_CS_EN(spi->chip_select);
+   writel(val, qspi->ctrl_base);
+   }
+   qspi->mmap_enabled = false;
+}
+
+static void ti_qspi_setup_mmap_read(struct spi_device *spi,
+   struct spi_flash_read_message *msg)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
+   u32 memval = msg->read_opcode;
+
+   switch (msg->data_nbits) {
+   case SPI_NBITS_QUAD:
+   memval |= QSPI_SETUP_RD_QUAD;
+   break;
+   case SPI_NBITS_DUAL:
+   memval |= QSPI_SETUP_RD_DUAL;
+   break;
+   default:
+   memval |= QSPI_SETUP_RD_NORMAL;
+   break;
+   }
+   memval |= ((msg->addr_width - 1) << QSPI_SETUP_ADDR_SHIFT |
+  msg->dummy_bytes << QSPI_SETUP_DUMMY_SHIFT);
+   ti_qspi_write(qspi, memval,
+ QSPI_SPI_SETUP_REG(spi->chip_select));
+}
+
+static int ti_qspi_spi_flash_read(struct  spi_device *spi,
+ struct spi_flash_read_message *msg)
+{
+   struct ti_qspi *qspi = spi_master_get_devdata(spi->master);
+   int ret = 0;
+
+   mutex_lock(>list_lock);
+
+   if (!qspi->mmap_enabled)
+   ti_qspi_enable_memory_map(spi);
+   ti_qspi_setup_mmap_read(spi, msg);
+   memcpy_fromio(msg->buf, qspi->mmap_base + msg->from, msg->len);
+   msg->retlen = msg->len;
+
+   mutex_unlock(>list_lock

[PATCH v4 5/5] ARM: dts: AM4372: add entry for qspi mmap region

2015-11-29 Thread Vignesh R
Add qspi memory mapped region entries for AM43xx based SoCs. Also,
update the binding documents for the controller to document this change.

Acked-by: Rob Herring <r...@kernel.org>
Signed-off-by: Vignesh R <vigne...@ti.com>
---

v4: No changes.

 Documentation/devicetree/bindings/spi/ti_qspi.txt | 5 +++--
 arch/arm/boot/dts/am4372.dtsi | 4 +++-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/ti_qspi.txt 
b/Documentation/devicetree/bindings/spi/ti_qspi.txt
index 334aa3f32cbc..5a1542eda387 100644
--- a/Documentation/devicetree/bindings/spi/ti_qspi.txt
+++ b/Documentation/devicetree/bindings/spi/ti_qspi.txt
@@ -17,9 +17,10 @@ Recommended properties:
 
 Example:
 
+For am4372:
 qspi: qspi@4b30 {
-   compatible = "ti,dra7xxx-qspi";
-   reg = <0x4790 0x100>, <0x3000 0x3ff>;
+   compatible = "ti,am4372-qspi";
+   reg = <0x4790 0x100>, <0x3000 0x400>;
reg-names = "qspi_base", "qspi_mmap";
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index d83ff9c9701e..e32d164102d1 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -963,7 +963,9 @@
 
qspi: qspi@4790 {
compatible = "ti,am4372-qspi";
-   reg = <0x4790 0x100>;
+   reg = <0x4790 0x100>,
+ <0x3000 0x400>;
+   reg-names = "qspi_base", "qspi_mmap";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "qspi";
-- 
2.6.3

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 4/5] ARM: dts: DRA7: add entry for qspi mmap region

2015-11-29 Thread Vignesh R
Add qspi memory mapped region entries for DRA7xx based SoCs. Also,
update the binding documents for the controller to document this change.

Acked-by: Rob Herring <r...@kernel.org>
Signed-off-by: Vignesh R <vigne...@ti.com>
---

v4: No changes.

 Documentation/devicetree/bindings/spi/ti_qspi.txt | 14 ++
 arch/arm/boot/dts/dra7.dtsi   |  7 +--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/ti_qspi.txt 
b/Documentation/devicetree/bindings/spi/ti_qspi.txt
index 601a360531a5..334aa3f32cbc 100644
--- a/Documentation/devicetree/bindings/spi/ti_qspi.txt
+++ b/Documentation/devicetree/bindings/spi/ti_qspi.txt
@@ -26,3 +26,17 @@ qspi: qspi@4b30 {
spi-max-frequency = <2500>;
ti,hwmods = "qspi";
 };
+
+For dra7xx:
+qspi: qspi@4b30 {
+   compatible = "ti,dra7xxx-qspi";
+   reg = <0x4b30 0x100>,
+ <0x5c00 0x400>,
+ <0x4a002558 0x4>;
+   reg-names = "qspi_base", "qspi_mmap",
+   "qspi_ctrlmod";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   spi-max-frequency = <4800>;
+   ti,hwmods = "qspi";
+};
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index fe99231cbde5..debe7523643d 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1153,8 +1153,11 @@
 
qspi: qspi@4b30 {
compatible = "ti,dra7xxx-qspi";
-   reg = <0x4b30 0x100>;
-   reg-names = "qspi_base";
+   reg = <0x4b30 0x100>,
+ <0x5c00 0x400>,
+ <0x4a002558 0x4>;
+   reg-names = "qspi_base", "qspi_mmap",
+   "qspi_ctrlmod";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "qspi";
-- 
2.6.3

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] ARM: dts: dra72-evm: Mark uart1 rxd as wakeup capable

2015-11-26 Thread Vignesh R
Uart1 rxd  is wakeup capable on DRA72 EVM. Hence, mark rxd line as
wakeup capable. This is similar to commit 66b0436977e2c ("ARM: dts:
dra7-evm: Mark uart1 rxd as wakeup capable") for DRA74 EVM.

Signed-off-by: Vignesh R <vigne...@ti.com>
---
 arch/arm/boot/dts/dra72-evm.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts
index d6104d5f0c01..8bf36b0b3c33 100644
--- a/arch/arm/boot/dts/dra72-evm.dts
+++ b/arch/arm/boot/dts/dra72-evm.dts
@@ -478,6 +478,8 @@
 
  {
status = "okay";
+   interrupts-extended = <_mpu GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+ <_pmx_core 0x3e0>;
 };
 
  {
-- 
2.6.3

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 1/5] spi: introduce mmap read support for spi flash devices

2015-11-16 Thread Vignesh R
Hi Brian,

On 11/13/2015 09:35 PM, Cyrille Pitchen wrote:

[...]

> 
> In September I've sent a series of patches to enhance the support of QSPI 
> flash
> memories. Patch 4 was dedicated to the m25p80 driver and set the
> rx_nbits / tx_nbits fields of spi_transfer struct(s) in order to configure the
> number of I/O lines independently for the opcode, address and data parts.
> The work was done for m25p80_read() but also for _read_reg(), _write_reg() and
> _write().
> The patched m25p80 driver was then tested with an at25 memory to check non-
> regression.
> 
> This series of patches also added 4 enum spi_protocol fields inside struct
> spi_nor so the spi-nor framework can tell the (Q)SPI controller driver what 
> SPI
> protocol should be use for erase, read, write and register read/write
> operations, depending on the memory manufacturer and the command opcode.
> This was done to better support Micron, Spansion and Macronix QSPI memories.
> 
> I have tested the series with Micron QSPI memories and Atmel QSPI controller
> and I guess Marek also tested it on his side with Spansion QSPI memories and
> another QSPI controller.
> 
> So if it can help other developers to develop QSPI controller drivers, the
> series is still available there:
> 
> for the whole series:
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-September/371170.html
> 
> for patch 4 (depends on patch 2 for enum spi_protocol):
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-September/371173.html
> 

Should I rebase my next version on top of above patches by Cyrille or
shall I post on top of 4.4-rc1?

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 1/5] spi: introduce mmap read support for spi flash devices

2015-11-11 Thread Vignesh R
Hi Brian,

On 11/12/2015 12:54 AM, Brian Norris wrote:
> In addition to my other comments:
> 

[...]

>> +int (*spi_mtd_mmap_read)(struct  spi_device *spi,
>> + loff_t from, size_t len,
>> + size_t *retlen, u_char *buf,
>> + u8 read_opcode, u8 addr_width,
>> + u8 dummy_bytes);
> 
> This is seeming to be a longer and longer list of arguments. I know MTD
> has a bad habit of long argument lists (which then cause a ton of
> unnecessary churn when things need changed in the API), but perhaps we
> can limit the damage to the SPI layer. Perhaps this deserves a struct to
> encapsulate all the flash read arguments? Like:
> 
> struct spi_flash_read_message {
>   loff_t from;
>   size_t len;
>   size_t *retlen;
>   void *buf;
>   u8 read_opcode;
>   u8 addr_width;
>   u8 dummy_bits;
>   // additional fields to describe rx_nbits for opcode/addr/data
> };
> 
> struct spi_master {
>   ...
>   int (*spi_flash_read)(struct spi_device *spi,
> struct spi_flash_message *msg);
> };


Yeah.. I think struct encapsulation helps, this can also be used to pass
sg lists for dma in future. I will rework the series with your
suggestion to include nbits for opcode/addr/data.
Also, will add validation logic (similar to __spi_validate()) to check
whether master supports dual/quad mode for opcode/addr/data. I am
planning to add this validation code to spi_flash_read_validate(in place
of spi_mmap_read_supported())
Thanks!


-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 2/5] spi: spi-ti-qspi: add mmap mode read support

2015-11-09 Thread Vignesh R
ti-qspi controller provides mmap port to read data from SPI flashes.
mmap port is enabled in QSPI_SPI_SWITCH_REG. ctrl module register may
also need to be accessed for some SoCs. The QSPI_SPI_SETUP_REGx needs to
be populated with flash specific information like read opcode, read
mode(quad, dual, normal), address width and dummy bytes. Once,
controller is in mmap mode, the whole flash memory is available as a
memory region at SoC specific address. This region can be accessed using
normal memcpy() (or mem-to-mem dma copy). The ti-qspi controller hardware
will internally communicate with SPI flash over SPI bus and get the
requested data.

Implement spi_mtd_mmap_read() callback to support mmap read over SPI
flash devices. With this, the read throughput increases from ~100kB/s to
~2.5 MB/s.

Signed-off-by: Vignesh R <vigne...@ti.com>
---

v3:
 * optimize enable/disable of mmap mode

 drivers/spi/spi-ti-qspi.c | 99 +--
 1 file changed, 95 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index 64318fcfacf2..295c11f48440 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -56,6 +56,7 @@ struct ti_qspi {
u32 dc;
 
bool ctrl_mod;
+   bool mmap_enabled;
 };
 
 #define QSPI_PID   (0x0)
@@ -65,11 +66,8 @@ struct ti_qspi {
 #define QSPI_SPI_CMD_REG   (0x48)
 #define QSPI_SPI_STATUS_REG(0x4c)
 #define QSPI_SPI_DATA_REG  (0x50)
-#define QSPI_SPI_SETUP0_REG(0x54)
+#define QSPI_SPI_SETUP_REG(n)  ((0x54 + 4 * n))
 #define QSPI_SPI_SWITCH_REG(0x64)
-#define QSPI_SPI_SETUP1_REG(0x58)
-#define QSPI_SPI_SETUP2_REG(0x5c)
-#define QSPI_SPI_SETUP3_REG(0x60)
 #define QSPI_SPI_DATA_REG_1(0x68)
 #define QSPI_SPI_DATA_REG_2(0x6c)
 #define QSPI_SPI_DATA_REG_3(0x70)
@@ -109,6 +107,16 @@ struct ti_qspi {
 
 #define QSPI_AUTOSUSPEND_TIMEOUT 2000
 
+#define MEM_CS_EN(n)   ((n + 1) << 8)
+
+#define MM_SWITCH  0x1
+
+#define QSPI_SETUP_RD_NORMAL   (0x0 << 12)
+#define QSPI_SETUP_RD_DUAL (0x1 << 12)
+#define QSPI_SETUP_RD_QUAD (0x3 << 12)
+#define QSPI_SETUP_ADDR_SHIFT  8
+#define QSPI_SETUP_DUMMY_SHIFT 10
+
 static inline unsigned long ti_qspi_read(struct ti_qspi *qspi,
unsigned long reg)
 {
@@ -366,6 +374,84 @@ static int qspi_transfer_msg(struct ti_qspi *qspi, struct 
spi_transfer *t)
return 0;
 }
 
+static void ti_qspi_enable_memory_map(struct spi_device *spi)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
+   u32 val;
+
+   ti_qspi_write(qspi, MM_SWITCH, QSPI_SPI_SWITCH_REG);
+   if (qspi->ctrl_mod) {
+   val = readl(qspi->ctrl_base);
+   val |= MEM_CS_EN(spi->chip_select);
+   writel(val, qspi->ctrl_base);
+   /* dummy readl to ensure bus sync */
+   readl(qspi->ctrl_base);
+   }
+   qspi->mmap_enabled = true;
+}
+
+static void ti_qspi_disable_memory_map(struct spi_device *spi)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
+   u32 val;
+
+   ti_qspi_write(qspi, 0, QSPI_SPI_SWITCH_REG);
+   if (qspi->ctrl_mod) {
+   val = readl(qspi->ctrl_base);
+   val &= ~MEM_CS_EN(spi->chip_select);
+   writel(val, qspi->ctrl_base);
+   }
+   qspi->mmap_enabled = false;
+}
+
+static void ti_qspi_setup_mmap_read(struct spi_device *spi,
+   u8 read_opcode, u8 addr_width,
+   u8 dummy_bytes)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
+   u32 mode = spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD);
+   u32 memval = read_opcode;
+
+   switch (mode) {
+   case SPI_RX_QUAD:
+   memval |= QSPI_SETUP_RD_QUAD;
+   break;
+   case SPI_RX_DUAL:
+   memval |= QSPI_SETUP_RD_DUAL;
+   break;
+   default:
+   memval |= QSPI_SETUP_RD_NORMAL;
+   break;
+   }
+   memval |= ((addr_width - 1) << QSPI_SETUP_ADDR_SHIFT |
+  dummy_bytes << QSPI_SETUP_DUMMY_SHIFT);
+   ti_qspi_write(qspi, memval,
+ QSPI_SPI_SETUP_REG(spi->chip_select));
+}
+
+static int ti_qspi_spi_mtd_mmap_read(struct  spi_device *spi,
+loff_t from, size_t len,
+size_t *retlen, u_char *buf,
+u8 read_opcode, u8 addr_width,
+u8 dummy_bytes)
+{
+   struct ti_qspi *qspi = spi_master_get_devdata(spi->master);
+   int ret = 0;
+
+   mut

[PATCH v3 1/5] spi: introduce mmap read support for spi flash devices

2015-11-09 Thread Vignesh R
In addition to providing direct access to SPI bus, some spi controller
hardwares (like ti-qspi) provide special memory mapped port
to accesses SPI flash devices in order to increase read performance.
This means the controller can automatically send the SPI signals
required to read data from the SPI flash device.
For this, spi controller needs to know flash specific information like
read command to use, dummy bytes and address width. Once these settings
are populated in hardware registers, any read accesses to flash's memory
map region(SoC specific) through memcpy (or mem-to mem DMA copy) will be
handled by controller hardware. The hardware will automatically generate
SPI signals required to read data from flash and present it to CPU/DMA.

Introduce spi_mtd_mmap_read() interface to support memory mapped read
over SPI flash devices. SPI master drivers can implement this callback to
support memory mapped read interfaces. m25p80 flash driver and other
flash drivers can call this to request memory mapped read. The interface
should only be used MTD flashes and cannot be used with other SPI devices.

Signed-off-by: Vignesh R <vigne...@ti.com>
---
v3:
 * Remove use of mmap_lock_mutex, use bus_lock_mutex instead.

 drivers/spi/spi.c   | 34 ++
 include/linux/spi/spi.h | 20 
 2 files changed, 54 insertions(+)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index e2415be209d5..0448d29fefc8 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1134,6 +1134,7 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
}
}
 
+   mutex_lock(>bus_lock_mutex);
trace_spi_message_start(master->cur_msg);
 
if (master->prepare_message) {
@@ -1143,6 +1144,7 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
"failed to prepare message: %d\n", ret);
master->cur_msg->status = ret;
spi_finalize_current_message(master);
+   mutex_unlock(>bus_lock_mutex);
return;
}
master->cur_msg_prepared = true;
@@ -1152,6 +1154,7 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
if (ret) {
master->cur_msg->status = ret;
spi_finalize_current_message(master);
+   mutex_unlock(>bus_lock_mutex);
return;
}
 
@@ -1159,8 +1162,10 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
if (ret) {
dev_err(>dev,
"failed to transfer one message from queue\n");
+   mutex_unlock(>bus_lock_mutex);
return;
}
+   mutex_unlock(>bus_lock_mutex);
 }
 
 /**
@@ -2327,6 +2332,35 @@ int spi_async_locked(struct spi_device *spi, struct 
spi_message *message)
 EXPORT_SYMBOL_GPL(spi_async_locked);
 
 
+int spi_mtd_mmap_read(struct spi_device *spi, loff_t from, size_t len,
+ size_t *retlen, u_char *buf, u8 read_opcode,
+ u8 addr_width, u8 dummy_bytes)
+
+{
+   struct spi_master *master = spi->master;
+   int ret;
+
+   if (master->auto_runtime_pm) {
+   ret = pm_runtime_get_sync(master->dev.parent);
+   if (ret < 0) {
+   dev_err(>dev, "Failed to power device: %d\n",
+   ret);
+   goto err;
+   }
+   }
+   mutex_lock(>bus_lock_mutex);
+   ret = master->spi_mtd_mmap_read(spi, from, len, retlen, buf,
+   read_opcode, addr_width,
+   dummy_bytes);
+   mutex_unlock(>bus_lock_mutex);
+   if (master->auto_runtime_pm)
+   pm_runtime_put(master->dev.parent);
+
+err:
+   return ret;
+}
+EXPORT_SYMBOL_GPL(spi_mtd_mmap_read);
+
 /*-*/
 
 /* Utility methods for SPI master protocol drivers, layered on
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index cce80e6dc7d1..2f2c431b8917 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -361,6 +361,11 @@ static inline void spi_unregister_driver(struct spi_driver 
*sdrv)
  * @handle_err: the subsystem calls the driver to handle an error that occurs
  * in the generic implementation of transfer_one_message().
  * @unprepare_message: undo any work done by prepare_message().
+ * @spi_mtd_mmap_read: some spi-controller hardwares provide memory.
+ * Flash drivers (like m25p80) can request memory
+ * mapped read via this method. This interface
+ * should only be used by mtd flashes and 

[PATCH v3 3/5] mtd: devices: m25p80: add support for mmap read request

2015-11-09 Thread Vignesh R
Certain spi controllers may support memory mapped interface to read from
m25p80 type flash devices. This interface provides better read
performance than regular SPI interface.
Call spi_mtd_mmap_read() interface, if supported, to make use of
memory-mapped interface.

Signed-off-by: Vignesh R <vigne...@ti.com>
---
 drivers/mtd/devices/m25p80.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index fe9ceb7b5405..7ef0c5009ead 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -131,6 +131,11 @@ static int m25p80_read(struct spi_nor *nor, loff_t from, 
size_t len,
/* convert the dummy cycles to the number of bytes */
dummy /= 8;
 
+   if (spi_mmap_read_supported(spi))
+   return spi_mtd_mmap_read(spi, from, len, retlen, buf,
+nor->read_opcode,
+nor->addr_width, dummy);
+
spi_message_init();
memset(t, 0, (sizeof t));
 
-- 
2.6.3

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 0/5] Add memory mapped read support for ti-qspi

2015-11-09 Thread Vignesh R

Changes since v2:
Remove mmap_lock_mutex.
Optimize enable/disable of mmap mode.

Changes since v1:
Introduce API in SPI core that MTD flash driver can call for mmap read
instead of directly calling spi-master driver callback. This API makes
sure that SPI core msg queue is locked during mmap transfers.
v1: https://lkml.org/lkml/2015/9/4/103


Cover letter:

This patch series adds support for memory mapped read port of ti-qspi.
ti-qspi has a special memory mapped port through which SPI flash
memories can be accessed directly via SoC specific memory region.

First patch adds a method to pass flash specific information like read
opcode, dummy bytes etc and to request mmap read. Second patch
implements mmap read method in ti-qspi driver. Patch 3 adapts m25p80 to
use mmap read method before trying normal SPI transfer. Patch 4 and 5
add memory map region DT entries for DRA7xx and AM43xx SoCs.

This patch series is based on the discussions here:
http://www.spinics.net/lists/linux-spi/msg04796.html

Tested on DRA74 EVM and AM437x-SK.
Read performance increases from ~100kB/s to ~2.5MB/s.

Vignesh R (5):
  spi: introduce mmap read support for spi flash devices
  spi: spi-ti-qspi: add mmap mode read support
  mtd: devices: m25p80: add support for mmap read request
  ARM: dts: DRA7: add entry for qspi mmap region
  ARM: dts: AM4372: add entry for qspi mmap region

 Documentation/devicetree/bindings/spi/ti_qspi.txt | 19 -
 arch/arm/boot/dts/am4372.dtsi |  4 +-
 arch/arm/boot/dts/dra7.dtsi   |  7 +-
 drivers/mtd/devices/m25p80.c  |  5 ++
 drivers/spi/spi-ti-qspi.c | 99 ++-
 drivers/spi/spi.c | 34 
 include/linux/spi/spi.h   | 20 +
 7 files changed, 179 insertions(+), 9 deletions(-)

-- 
2.6.3

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 5/5] ARM: dts: AM4372: add entry for qspi mmap region

2015-11-09 Thread Vignesh R
Add qspi memory mapped region entries for AM43xx based SoCs. Also,
update the binding documents for the controller to document this change.

Signed-off-by: Vignesh R <vigne...@ti.com>
Acked-by: Rob Herring <r...@kernel.org>
---
 Documentation/devicetree/bindings/spi/ti_qspi.txt | 5 +++--
 arch/arm/boot/dts/am4372.dtsi | 4 +++-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/ti_qspi.txt 
b/Documentation/devicetree/bindings/spi/ti_qspi.txt
index 334aa3f32cbc..5a1542eda387 100644
--- a/Documentation/devicetree/bindings/spi/ti_qspi.txt
+++ b/Documentation/devicetree/bindings/spi/ti_qspi.txt
@@ -17,9 +17,10 @@ Recommended properties:
 
 Example:
 
+For am4372:
 qspi: qspi@4b30 {
-   compatible = "ti,dra7xxx-qspi";
-   reg = <0x4790 0x100>, <0x3000 0x3ff>;
+   compatible = "ti,am4372-qspi";
+   reg = <0x4790 0x100>, <0x3000 0x400>;
reg-names = "qspi_base", "qspi_mmap";
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index d83ff9c9701e..e32d164102d1 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -963,7 +963,9 @@
 
qspi: qspi@4790 {
compatible = "ti,am4372-qspi";
-   reg = <0x4790 0x100>;
+   reg = <0x4790 0x100>,
+ <0x3000 0x400>;
+   reg-names = "qspi_base", "qspi_mmap";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "qspi";
-- 
2.6.3

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 4/5] ARM: dts: DRA7: add entry for qspi mmap region

2015-11-09 Thread Vignesh R
Add qspi memory mapped region entries for DRA7xx based SoCs. Also,
update the binding documents for the controller to document this change.

Signed-off-by: Vignesh R <vigne...@ti.com>
Acked-by: Rob Herring <r...@kernel.org>
---
 Documentation/devicetree/bindings/spi/ti_qspi.txt | 14 ++
 arch/arm/boot/dts/dra7.dtsi   |  7 +--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/ti_qspi.txt 
b/Documentation/devicetree/bindings/spi/ti_qspi.txt
index 601a360531a5..334aa3f32cbc 100644
--- a/Documentation/devicetree/bindings/spi/ti_qspi.txt
+++ b/Documentation/devicetree/bindings/spi/ti_qspi.txt
@@ -26,3 +26,17 @@ qspi: qspi@4b30 {
spi-max-frequency = <2500>;
ti,hwmods = "qspi";
 };
+
+For dra7xx:
+qspi: qspi@4b30 {
+   compatible = "ti,dra7xxx-qspi";
+   reg = <0x4b30 0x100>,
+ <0x5c00 0x400>,
+ <0x4a002558 0x4>;
+   reg-names = "qspi_base", "qspi_mmap",
+   "qspi_ctrlmod";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   spi-max-frequency = <4800>;
+   ti,hwmods = "qspi";
+};
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 8fedddc35999..ad93fe2ccab8 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1108,8 +1108,11 @@
 
qspi: qspi@4b30 {
compatible = "ti,dra7xxx-qspi";
-   reg = <0x4b30 0x100>;
-   reg-names = "qspi_base";
+   reg = <0x4b30 0x100>,
+ <0x5c00 0x400>,
+ <0x4a002558 0x4>;
+   reg-names = "qspi_base", "qspi_mmap",
+   "qspi_ctrlmod";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "qspi";
-- 
2.6.3

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 5/5] ARM: dts: AM4372: add entry for qspi mmap region

2015-11-06 Thread Vignesh R


On 11/06/2015 10:44 AM, Felipe Balbi wrote:
> 
> Hi,
> 
> Rob Herring <r...@kernel.org> writes:
>> On Tue, Nov 03, 2015 at 03:36:14PM +0530, Vignesh R wrote:
>>> Add qspi memory mapped region entries for AM43xx based SoCs. Also,
>>> update the binding documents for the controller to document this change.
>>>
>>> Signed-off-by: Vignesh R <vigne...@ti.com>
>>
>> Acked-by: Rob Herring <r...@kernel.org>
>>
>>> ---
>>>  Documentation/devicetree/bindings/spi/ti_qspi.txt | 5 +++--
>>>  arch/arm/boot/dts/am4372.dtsi | 4 +++-
>>>  2 files changed, 6 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/spi/ti_qspi.txt 
>>> b/Documentation/devicetree/bindings/spi/ti_qspi.txt
>>> index f05dd631bef1..05488970060b 100644
>>> --- a/Documentation/devicetree/bindings/spi/ti_qspi.txt
>>> +++ b/Documentation/devicetree/bindings/spi/ti_qspi.txt
>>> @@ -17,9 +17,10 @@ Recommended properties:
>>>  
>>>  Example:
>>>  
>>> +For am4372:
>>>  qspi: qspi@4b30 {
>>> -   compatible = "ti,dra7xxx-qspi";
>>> -   reg = <0x4790 0x100>, <0x3000 0x3ff>;
>>> +   compatible = "ti,am4372-qspi";
>>> +   reg = <0x4790 0x100>, <0x3000 0x400>;
>>> reg-names = "qspi_base", "qspi_mmap";
>>> #address-cells = <1>;
>>> #size-cells = <0>;
> 
> and how does the user for this look like ? Don't you need to give this a
> proper 'ranges' binding ?
> 


There are no other users of qspi_mmap region except ti-qspi driver itself:
In probe:
res_mmap = platform_get_resource_byname(pdev,
IORESOURCE_MEM, "qspi_mmap");
qspi->mmap_base = devm_ioremap_resource(>dev, res_mmap);

and for reading from mmap region:
memcpy_fromio(buf, qspi->mmap_base + from, len);

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/5] spi: introduce mmap read support for spi flash devices

2015-11-05 Thread Vignesh R


On 11/04/2015 08:09 PM, Mark Brown wrote:
> On Tue, Nov 03, 2015 at 03:36:10PM +0530, Vignesh R wrote:
> 
>> +}
>> +mutex_lock(>mmap_lock_mutex);
>> +ret = master->spi_mtd_mmap_read(spi, from, len, retlen, buf,
>> +read_opcode, addr_width,
>> +dummy_bytes);
>> +mutex_unlock(>mmap_lock_mutex);
>> +if (master->auto_runtime_pm)
>> +pm_runtime_put(master->dev.parent);
> 
> It's a bit worrying that this doesn't sync with the message queue except
> via the mutex: this means that we might be out of order with respect to
> any asynchronous transfers that are happening on the device.  I'm not
> sure that this is a practical problem, though there is some risk of
> unfair scheduling that would have to be under extreme load and it might
> make sense to prioritise reads anyway.
> 

Since mmap interface is used only by mtd flash drivers and since almost
all mtd flash devices use synchronous transfers (spi_sync()), IMO, there
wont be out of order problem wrt mtd flashes.
But mmap read might delay transfers queued for non mtd flash devices. It
is difficult to wait for all transfers already queued to be pumped out
by __spi_pump_messages() and then do the mmap transfer. Do you have any
thoughts on how to sync with message queue?

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/5] spi: spi-ti-qspi: add mmap mode read support

2015-11-04 Thread Vignesh R


On 11/04/2015 08:11 PM, Mark Brown wrote:
> On Tue, Nov 03, 2015 at 03:36:11PM +0530, Vignesh R wrote:
> 
>> +ti_qspi_enable_memory_map(spi);
>> +ti_qspi_setup_mmap_read(spi, read_opcode, addr_width,
>> +dummy_bytes);
>> +memcpy_fromio(buf, qspi->mmap_base + from, len);
>> +*retlen = len;
>> +ti_qspi_disable_memory_map(spi);
> 
> We'll be constantly enabling and disabling memory mapping with this.
> I'm not sure that's a meaningful cost given that it doesn't actually
> remap anything but rather just switches hardware modes, we can always
> optimise it later if it is.
> 

Hmm, I will move the ti_qspi_disable_memory_map() call to
ti_qspi_start_transfer_one(), so that mmap mode is disabled only when
normal SPI bus transfer is requested. Further, "mmap_enabled" status
flag can be used to determine whether mode switch is required or not.
This should help to overcome enabling and disabling memory mapping
between successive mmap read requests.

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/5] spi: introduce mmap read support for spi flash devices

2015-11-03 Thread Vignesh R
In addition to providing direct access to SPI bus, some spi controller
hardwares (like ti-qspi) provide special memory mapped port
to accesses SPI flash devices in order to increase read performance.
This means the controller can automatically send the SPI signals
required to read data from the SPI flash device.
For this, spi controller needs to know flash specific information like
read command to use, dummy bytes and address width. Once these settings
are populated in hardware registers, any read accesses to flash's memory
map region(SoC specific) through memcpy (or mem-to mem DMA copy) will be
handled by controller hardware. The hardware will automatically generate
SPI signals required to read data from flash and present it to CPU/DMA.

Introduce spi_mtd_mmap_read() interface to support memory mapped read
over SPI flash devices. SPI master drivers can implement this callback to
support memory mapped read interfaces. m25p80 flash driver and other
flash drivers can call this to request memory mapped read. The interface
should only be used MTD flashes and cannot be used with other SPI devices.

Signed-off-by: Vignesh R <vigne...@ti.com>
---
 drivers/spi/spi.c   | 35 +++
 include/linux/spi/spi.h | 23 +++
 2 files changed, 58 insertions(+)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index a5f53de813d3..5a5c7a7d47f2 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1059,6 +1059,7 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
}
}
 
+   mutex_lock(>mmap_lock_mutex);
trace_spi_message_start(master->cur_msg);
 
if (master->prepare_message) {
@@ -1068,6 +1069,7 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
"failed to prepare message: %d\n", ret);
master->cur_msg->status = ret;
spi_finalize_current_message(master);
+   mutex_unlock(>mmap_lock_mutex);
return;
}
master->cur_msg_prepared = true;
@@ -1077,6 +1079,7 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
if (ret) {
master->cur_msg->status = ret;
spi_finalize_current_message(master);
+   mutex_unlock(>mmap_lock_mutex);
return;
}
 
@@ -1084,8 +1087,10 @@ static void __spi_pump_messages(struct spi_master 
*master, bool in_kthread)
if (ret) {
dev_err(>dev,
"failed to transfer one message from queue\n");
+   mutex_unlock(>mmap_lock_mutex);
return;
}
+   mutex_unlock(>mmap_lock_mutex);
 }
 
 /**
@@ -1732,6 +1737,7 @@ int spi_register_master(struct spi_master *master)
spin_lock_init(>queue_lock);
spin_lock_init(>bus_lock_spinlock);
mutex_init(>bus_lock_mutex);
+   mutex_init(>mmap_lock_mutex);
master->bus_lock_flag = 0;
init_completion(>xfer_completion);
if (!master->max_dma_len)
@@ -2237,6 +2243,35 @@ int spi_async_locked(struct spi_device *spi, struct 
spi_message *message)
 EXPORT_SYMBOL_GPL(spi_async_locked);
 
 
+int spi_mtd_mmap_read(struct spi_device *spi, loff_t from, size_t len,
+ size_t *retlen, u_char *buf, u8 read_opcode,
+ u8 addr_width, u8 dummy_bytes)
+
+{
+   struct spi_master *master = spi->master;
+   int ret;
+
+   if (master->auto_runtime_pm) {
+   ret = pm_runtime_get_sync(master->dev.parent);
+   if (ret < 0) {
+   dev_err(>dev, "Failed to power device: %d\n",
+   ret);
+   goto err;
+   }
+   }
+   mutex_lock(>mmap_lock_mutex);
+   ret = master->spi_mtd_mmap_read(spi, from, len, retlen, buf,
+   read_opcode, addr_width,
+   dummy_bytes);
+   mutex_unlock(>mmap_lock_mutex);
+   if (master->auto_runtime_pm)
+   pm_runtime_put(master->dev.parent);
+
+err:
+   return ret;
+}
+EXPORT_SYMBOL_GPL(spi_mtd_mmap_read);
+
 /*-*/
 
 /* Utility methods for SPI master protocol drivers, layered on
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 6b00f18f5e6b..0a6d8ad57357 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -297,6 +297,7 @@ static inline void spi_unregister_driver(struct spi_driver 
*sdrv)
  * @flags: other constraints relevant to this driver
  * @bus_lock_spinlock: spinlock for SPI bus locking
  * @bus_lock_mutex: mutex for SPI bus locking
+ * @mmap_lock_mutex: mutex for l

[PATCH v2 4/5] ARM: dts: DRA7: add entry for qspi mmap region

2015-11-03 Thread Vignesh R
Add qspi memory mapped region entries for DRA7xx based SoCs. Also,
update the binding documents for the controller to document this change.

Signed-off-by: Vignesh R <vigne...@ti.com>
---
 Documentation/devicetree/bindings/spi/ti_qspi.txt | 13 +
 arch/arm/boot/dts/dra7.dtsi   |  6 --
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/ti_qspi.txt 
b/Documentation/devicetree/bindings/spi/ti_qspi.txt
index 601a360531a5..f05dd631bef1 100644
--- a/Documentation/devicetree/bindings/spi/ti_qspi.txt
+++ b/Documentation/devicetree/bindings/spi/ti_qspi.txt
@@ -26,3 +26,16 @@ qspi: qspi@4b30 {
spi-max-frequency = <2500>;
ti,hwmods = "qspi";
 };
+
+For dra7xx:
+qspi: qspi@4b30 {
+   compatible = "ti,dra7xxx-qspi";
+   reg = <0x4b30 0x100>, <0x4a002558 0x4>,
+ <0x5c00 0x400>;
+   reg-names = "qspi_base", "qspi_ctrlmod",
+   "qspi_mmap";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   spi-max-frequency = <4800>;
+   ti,hwmods = "qspi";
+};
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index e289c706d27d..13c2f10ec217 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1108,8 +1108,10 @@
 
qspi: qspi@4b30 {
compatible = "ti,dra7xxx-qspi";
-   reg = <0x4b30 0x100>;
-   reg-names = "qspi_base";
+   reg = <0x4b30 0x100>, <0x4a002558 0x4>,
+ <0x5c00 0x400>;
+   reg-names = "qspi_base", "qspi_ctrlmod",
+   "qspi_mmap";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "qspi";
-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 3/5] mtd: devices: m25p80: add support for mmap read request

2015-11-03 Thread Vignesh R
Certain spi controllers may support memory mapped interface to read from
m25p80 type flash devices. This interface provides better read
performance than regular SPI interface.
Call spi_mtd_mmap_read() interface, if supported, to make use of
memory-mapped interface.

Signed-off-by: Vignesh R <vigne...@ti.com>
---
 drivers/mtd/devices/m25p80.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 9cd3631170ef..3978bcb513b9 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -133,6 +133,11 @@ static int m25p80_read(struct spi_nor *nor, loff_t from, 
size_t len,
/* convert the dummy cycles to the number of bytes */
dummy /= 8;
 
+   if (spi_mmap_read_supported(spi))
+   return spi_mtd_mmap_read(spi, from, len, retlen, buf,
+nor->read_opcode,
+nor->addr_width, dummy);
+
spi_message_init();
memset(t, 0, (sizeof t));
 
-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/5] spi: spi-ti-qspi: add mmap mode read support

2015-11-03 Thread Vignesh R
ti-qspi controller provides mmap port to read data from SPI flashes.
mmap port is enabled in QSPI_SPI_SWITCH_REG. ctrl module register may
also need to be accessed for some SoCs. The QSPI_SPI_SETUP_REGx needs to
be populated with flash specific information like read opcode, read
mode(quad, dual, normal), address width and dummy bytes. Once,
controller is in mmap mode, the whole flash memory is available as a
memory region at SoC specific address. This region can be accessed using
normal memcpy() (or mem-to-mem dma copy). The ti-qspi controller hardware
will internally communicate with SPI flash over SPI bus and get the
requested data.

Implement spi_mtd_mmap_read() callback to support mmap read over SPI
flash devices. With this, the read throughput increases from ~100kB/s to
~2.5 MB/s.

Signed-off-by: Vignesh R <vigne...@ti.com>
---
 drivers/spi/spi-ti-qspi.c | 92 ---
 1 file changed, 88 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index 69c1a95b0615..2f58fb7eb410 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -65,11 +65,8 @@ struct ti_qspi {
 #define QSPI_SPI_CMD_REG   (0x48)
 #define QSPI_SPI_STATUS_REG(0x4c)
 #define QSPI_SPI_DATA_REG  (0x50)
-#define QSPI_SPI_SETUP0_REG(0x54)
+#define QSPI_SPI_SETUP_REG(n)  ((0x54 + 4 * n))
 #define QSPI_SPI_SWITCH_REG(0x64)
-#define QSPI_SPI_SETUP1_REG(0x58)
-#define QSPI_SPI_SETUP2_REG(0x5c)
-#define QSPI_SPI_SETUP3_REG(0x60)
 #define QSPI_SPI_DATA_REG_1(0x68)
 #define QSPI_SPI_DATA_REG_2(0x6c)
 #define QSPI_SPI_DATA_REG_3(0x70)
@@ -109,6 +106,16 @@ struct ti_qspi {
 
 #define QSPI_AUTOSUSPEND_TIMEOUT 2000
 
+#define MEM_CS_EN(n)   ((n + 1) << 8)
+
+#define MM_SWITCH  0x1
+
+#define QSPI_SETUP_RD_NORMAL   (0x0 << 12)
+#define QSPI_SETUP_RD_DUAL (0x1 << 12)
+#define QSPI_SETUP_RD_QUAD (0x3 << 12)
+#define QSPI_SETUP_ADDR_SHIFT  8
+#define QSPI_SETUP_DUMMY_SHIFT 10
+
 static inline unsigned long ti_qspi_read(struct ti_qspi *qspi,
unsigned long reg)
 {
@@ -366,6 +373,82 @@ static int qspi_transfer_msg(struct ti_qspi *qspi, struct 
spi_transfer *t)
return 0;
 }
 
+static void ti_qspi_enable_memory_map(struct spi_device *spi)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
+   u32 val;
+
+   ti_qspi_write(qspi, MM_SWITCH, QSPI_SPI_SWITCH_REG);
+   if (qspi->ctrl_mod) {
+   val = readl(qspi->ctrl_base);
+   val |= MEM_CS_EN(spi->chip_select);
+   writel(val, qspi->ctrl_base);
+   /* dummy readl to ensure bus sync */
+   readl(qspi->ctrl_base);
+   }
+}
+
+static void ti_qspi_disable_memory_map(struct spi_device *spi)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
+   u32 val;
+
+   ti_qspi_write(qspi, 0, QSPI_SPI_SWITCH_REG);
+   if (qspi->ctrl_mod) {
+   val = readl(qspi->ctrl_base);
+   val &= ~MEM_CS_EN(spi->chip_select);
+   writel(val, qspi->ctrl_base);
+   }
+}
+
+static void ti_qspi_setup_mmap_read(struct spi_device *spi,
+   u8 read_opcode, u8 addr_width,
+   u8 dummy_bytes)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
+   u32 mode = spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD);
+   u32 memval = read_opcode;
+
+   switch (mode) {
+   case SPI_RX_QUAD:
+   memval |= QSPI_SETUP_RD_QUAD;
+   break;
+   case SPI_RX_DUAL:
+   memval |= QSPI_SETUP_RD_DUAL;
+   break;
+   default:
+   memval |= QSPI_SETUP_RD_NORMAL;
+   break;
+   }
+   memval |= ((addr_width - 1) << QSPI_SETUP_ADDR_SHIFT |
+  dummy_bytes << QSPI_SETUP_DUMMY_SHIFT);
+   ti_qspi_write(qspi, memval,
+ QSPI_SPI_SETUP_REG(spi->chip_select));
+}
+
+static int ti_qspi_spi_mtd_mmap_read(struct  spi_device *spi,
+loff_t from, size_t len,
+size_t *retlen, u_char *buf,
+u8 read_opcode, u8 addr_width,
+u8 dummy_bytes)
+{
+   struct ti_qspi *qspi = spi_master_get_devdata(spi->master);
+   int ret = 0;
+
+   mutex_lock(>list_lock);
+
+   ti_qspi_enable_memory_map(spi);
+   ti_qspi_setup_mmap_read(spi, read_opcode, addr_width,
+   dummy_bytes);
+   memcpy_fromio(buf, qspi->mmap_base + from, len);
+   *retlen = len;
+   ti_qsp

[PATCH v2 5/5] ARM: dts: AM4372: add entry for qspi mmap region

2015-11-03 Thread Vignesh R
Add qspi memory mapped region entries for AM43xx based SoCs. Also,
update the binding documents for the controller to document this change.

Signed-off-by: Vignesh R <vigne...@ti.com>
---
 Documentation/devicetree/bindings/spi/ti_qspi.txt | 5 +++--
 arch/arm/boot/dts/am4372.dtsi | 4 +++-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/ti_qspi.txt 
b/Documentation/devicetree/bindings/spi/ti_qspi.txt
index f05dd631bef1..05488970060b 100644
--- a/Documentation/devicetree/bindings/spi/ti_qspi.txt
+++ b/Documentation/devicetree/bindings/spi/ti_qspi.txt
@@ -17,9 +17,10 @@ Recommended properties:
 
 Example:
 
+For am4372:
 qspi: qspi@4b30 {
-   compatible = "ti,dra7xxx-qspi";
-   reg = <0x4790 0x100>, <0x3000 0x3ff>;
+   compatible = "ti,am4372-qspi";
+   reg = <0x4790 0x100>, <0x3000 0x400>;
reg-names = "qspi_base", "qspi_mmap";
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index 0447c04a40cc..1b2c545f3f2c 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -962,7 +962,9 @@
 
qspi: qspi@4790 {
compatible = "ti,am4372-qspi";
-   reg = <0x4790 0x100>;
+   reg = <0x4790 0x100>,
+ <0x3000 0x400>;
+   reg-names = "qspi_base", "qspi_mmap";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "qspi";
-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/5] Add memory mapped read support for ti-qspi

2015-11-03 Thread Vignesh R

Changes since v1:
Introduce API in SPI core that MTD flash driver can call for mmap read
instead of directly calling spi-master driver callback. This API makes
sure that SPI core msg queue is locked during mmap transfers.
v1: https://lkml.org/lkml/2015/9/4/103


Cover letter:

This patch series adds support for memory mapped read port of ti-qspi.
ti-qspi has a special memory mapped port through which SPI flash
memories can be accessed directly via SoC specific memory region.

First patch adds a method to pass flash specific information like read
opcode, dummy bytes etc and to request mmap read. Second patch
implements mmap read method in ti-qspi driver. Patch 3 adapts m25p80 to
use mmap read method before trying normal SPI transfer. Patch 4 and 5
add memory map region DT entries for DRA7xx and AM43xx SoCs.

This patch series is based on the discussions here:
http://www.spinics.net/lists/linux-spi/msg04796.html

Tested on DRA74 EVM and AM437x-SK.
Read performance increases from ~100kB/s to ~2.5MB/s.


Vignesh R (5):
  spi: introduce mmap read support for spi flash devices
  spi: spi-ti-qspi: add mmap mode read support
  mtd: devices: m25p80: add support for mmap read request
  ARM: dts: DRA7: add entry for qspi mmap region
  ARM: dts: AM4372: add entry for qspi mmap region

 Documentation/devicetree/bindings/spi/ti_qspi.txt | 18 -
 arch/arm/boot/dts/am4372.dtsi |  4 +-
 arch/arm/boot/dts/dra7.dtsi   |  6 +-
 drivers/mtd/devices/m25p80.c  |  5 ++
 drivers/spi/spi-ti-qspi.c | 92 ++-
 drivers/spi/spi.c | 35 +
 include/linux/spi/spi.h   | 23 ++
 7 files changed, 174 insertions(+), 9 deletions(-)

-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/5] spi: introduce mmap read support for spi flash devices

2015-11-03 Thread Vignesh R
Hi,

On 11/03/2015 04:49 PM, Michal Suchanek wrote:
> On 3 November 2015 at 11:06, Vignesh R <vigne...@ti.com> wrote:
>> In addition to providing direct access to SPI bus, some spi controller
>> hardwares (like ti-qspi) provide special memory mapped port
>> to accesses SPI flash devices in order to increase read performance.
>> This means the controller can automatically send the SPI signals
>> required to read data from the SPI flash device.
>> For this, spi controller needs to know flash specific information like
>> read command to use, dummy bytes and address width. Once these settings
>> are populated in hardware registers, any read accesses to flash's memory
>> map region(SoC specific) through memcpy (or mem-to mem DMA copy) will be
>> handled by controller hardware. The hardware will automatically generate
>> SPI signals required to read data from flash and present it to CPU/DMA.
>>
>> Introduce spi_mtd_mmap_read() interface to support memory mapped read
>> over SPI flash devices. SPI master drivers can implement this callback to
>> support memory mapped read interfaces. m25p80 flash driver and other
>> flash drivers can call this to request memory mapped read. The interface
>> should only be used MTD flashes and cannot be used with other SPI devices.
>>
>> Signed-off-by: Vignesh R <vigne...@ti.com>
>> ---
>>  drivers/spi/spi.c   | 35 +++
>>  include/linux/spi/spi.h | 23 +++
>>  2 files changed, 58 insertions(+)
>>
>> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
>> index a5f53de813d3..5a5c7a7d47f2 100644
>> --- a/drivers/spi/spi.c
>> +++ b/drivers/spi/spi.c
>> @@ -1059,6 +1059,7 @@ static void __spi_pump_messages(struct spi_master 
>> *master, bool in_kthread)
>> }
>> }
>>
>> +   mutex_lock(>mmap_lock_mutex);
>> trace_spi_message_start(master->cur_msg);
>>
>> if (master->prepare_message) {
>> @@ -1068,6 +1069,7 @@ static void __spi_pump_messages(struct spi_master 
>> *master, bool in_kthread)
>> "failed to prepare message: %d\n", ret);
>> master->cur_msg->status = ret;
>> spi_finalize_current_message(master);
>> +   mutex_unlock(>mmap_lock_mutex);
>> return;
>> }
>> master->cur_msg_prepared = true;
>> @@ -1077,6 +1079,7 @@ static void __spi_pump_messages(struct spi_master 
>> *master, bool in_kthread)
>> if (ret) {
>> master->cur_msg->status = ret;
>> spi_finalize_current_message(master);
>> +   mutex_unlock(>mmap_lock_mutex);
>> return;
>> }
>>
>> @@ -1084,8 +1087,10 @@ static void __spi_pump_messages(struct spi_master 
>> *master, bool in_kthread)
>> if (ret) {
>> dev_err(>dev,
>> "failed to transfer one message from queue\n");
>> +   mutex_unlock(>mmap_lock_mutex);
>> return;
>> }
>> +   mutex_unlock(>mmap_lock_mutex);
>>  }
>>
>>  /**
>> @@ -1732,6 +1737,7 @@ int spi_register_master(struct spi_master *master)
>> spin_lock_init(>queue_lock);
>> spin_lock_init(>bus_lock_spinlock);
>> mutex_init(>bus_lock_mutex);
>> +   mutex_init(>mmap_lock_mutex);
>> master->bus_lock_flag = 0;
>> init_completion(>xfer_completion);
>> if (!master->max_dma_len)
>> @@ -2237,6 +2243,35 @@ int spi_async_locked(struct spi_device *spi, struct 
>> spi_message *message)
>>  EXPORT_SYMBOL_GPL(spi_async_locked);
>>
>>
>> +int spi_mtd_mmap_read(struct spi_device *spi, loff_t from, size_t len,
>> + size_t *retlen, u_char *buf, u8 read_opcode,
>> + u8 addr_width, u8 dummy_bytes)
>> +
>> +{
>> +   struct spi_master *master = spi->master;
>> +   int ret;
>> +
>> +   if (master->auto_runtime_pm) {
>> +   ret = pm_runtime_get_sync(master->dev.parent);
>> +   if (ret < 0) {
>> +   dev_err(>dev, "Failed to power device: %d\n",
>> +   ret);
>> +   goto err;
>> +   }
>> +   }
>> +   mutex_lock(>mmap_lock_mutex);
&

Re: [PATCH] ARM: dts: am437x-gp-evm: Add wakeup interrupt source for pixcir_i2c_ts

2015-10-14 Thread Vignesh R


On 10/14/2015 02:16 PM, Roger Quadros wrote:

> 
> On 14/10/15 08:52, Vignesh R wrote:
>> On am437x-gp-evm, pixcir_i2c_ts can wakeup the system from lower power
>> state via pinctrl and IO daisy chain using generic wakeirq framework.
>> With commit 3fffd1283927 ("i2c: allow specifying separate wakeup
>> interrupt in device tree") i2c core allows optional wakeirq to be
>> specified via device tree. Add wakeup irq entry to enable pixcir_i2c_ts
>> to wake the system from low power state.
>>
>> Signed-off-by: Vignesh R <vigne...@ti.com>
>> ---
>>  arch/arm/boot/dts/am437x-gp-evm.dts | 5 +
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts 
>> b/arch/arm/boot/dts/am437x-gp-evm.dts
>> index 22038f21f228..69e93af7df0d 100644
>> --- a/arch/arm/boot/dts/am437x-gp-evm.dts
>> +++ b/arch/arm/boot/dts/am437x-gp-evm.dts
>> @@ -581,8 +581,13 @@
>>  
>>  attb-gpio = < 22 GPIO_ACTIVE_HIGH>;
>>  
>> +interrupts-extended = < 22 GPIO_ACTIVE_HIGH>,
>> +  <_pinmux 0x264>;
> 
> How does this work?
> 
> interrupts-extended property must have
> 1) interrupt parent
> 2) interrupt number
> 3) interrupt flags
> 
> Your change doesn't seem to comply with those requirements.

AFAIU, interrupts-extended has two parts: interrupt parent phandle and
interrupt specifier.
The number of cells in interrupt specifier is determined by
interrupt-cells property of interrupt parent node.
In above case, gpio3 has interrupt-cells = 2 hence interrupt specifier
has interrupt number and interrupt flag field.
But in case am43xx_pinmux node, interrupt-cells is 1 hence has no
interrupt flag field.

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] ARM: dts: am437x-gp-evm: Add wakeup interrupt source for pixcir_i2c_ts

2015-10-14 Thread Vignesh R


On 10/14/2015 04:34 PM, Roger Quadros wrote:
> Vignesh,
> 
> On 14/10/15 12:12, Vignesh R wrote:
>>
>>
>> On 10/14/2015 02:16 PM, Roger Quadros wrote:
>>
>>>
>>> On 14/10/15 08:52, Vignesh R wrote:
>>>> On am437x-gp-evm, pixcir_i2c_ts can wakeup the system from lower power
>>>> state via pinctrl and IO daisy chain using generic wakeirq framework.
>>>> With commit 3fffd1283927 ("i2c: allow specifying separate wakeup
>>>> interrupt in device tree") i2c core allows optional wakeirq to be
>>>> specified via device tree. Add wakeup irq entry to enable pixcir_i2c_ts
>>>> to wake the system from low power state.
>>>>
>>>> Signed-off-by: Vignesh R <vigne...@ti.com>
>>>> ---
>>>>  arch/arm/boot/dts/am437x-gp-evm.dts | 5 +
>>>>  1 file changed, 5 insertions(+)
>>>>
>>>> diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts 
>>>> b/arch/arm/boot/dts/am437x-gp-evm.dts
>>>> index 22038f21f228..69e93af7df0d 100644
>>>> --- a/arch/arm/boot/dts/am437x-gp-evm.dts
>>>> +++ b/arch/arm/boot/dts/am437x-gp-evm.dts
>>>> @@ -581,8 +581,13 @@
>>>>  
>>>>attb-gpio = < 22 GPIO_ACTIVE_HIGH>;
>>>>  
>>>> +  interrupts-extended = < 22 GPIO_ACTIVE_HIGH>,
>>>> +<_pinmux 0x264>;
>>>
>>> How does this work?
>>>
>>> interrupts-extended property must have
>>> 1) interrupt parent
>>> 2) interrupt number
>>> 3) interrupt flags
>>>
>>> Your change doesn't seem to comply with those requirements.
>>
>> AFAIU, interrupts-extended has two parts: interrupt parent phandle and
>> interrupt specifier.
>> The number of cells in interrupt specifier is determined by
>> interrupt-cells property of interrupt parent node.
> 
> Got it.
> 
>> In above case, gpio3 has interrupt-cells = 2 hence interrupt specifier
>> has interrupt number and interrupt flag field.
> 
> But is GPIO_ACTIVE_HIGH an interrupt flag?

Oops.. I will change it to IRQ_TYPE_NONE as represented in interrupts
property.

> 
>> But in case am43xx_pinmux node, interrupt-cells is 1 hence has no
>> interrupt flag field.
>>
> Understood, thanks. Might be worth adding a comment as to what 0x264 means 
> though.
> 

Will add a one line comment indicating its the offset of gpio3_22
padconf register from am43xx_pinmux base.

> cheers,
> -roger
> 

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] ARM: dts: am437x-gp-evm: Add wakeup interrupt source for pixcir_i2c_ts

2015-10-14 Thread Vignesh R
On am437x-gp-evm, pixcir_i2c_ts can wakeup the system from low power
state via pinctrl and IO daisy chain using generic wakeirq framework.
With commit 3fffd1283927 ("i2c: allow specifying separate wakeup
interrupt in device tree") i2c core allows optional wakeirq to be
specified via device tree. Add wakeup irq entry to enable pixcir_i2c_ts
to wake the system from low power state.

Signed-off-by: Vignesh R <vigne...@ti.com>
---

Since v1:
 - correct interrupt flag.
 - add comment wrt wakeup interrupt.

 arch/arm/boot/dts/am437x-gp-evm.dts | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts 
b/arch/arm/boot/dts/am437x-gp-evm.dts
index 22038f21f228..9c324b5f09ac 100644
--- a/arch/arm/boot/dts/am437x-gp-evm.dts
+++ b/arch/arm/boot/dts/am437x-gp-evm.dts
@@ -581,8 +581,17 @@
 
attb-gpio = < 22 GPIO_ACTIVE_HIGH>;
 
+   /*
+* 0x264 represents the offset of padconf register of
+* gpio3_22 from am43xx_pinmux base.
+*/
+   interrupts-extended = < 22 IRQ_TYPE_NONE>,
+ <_pinmux 0x264>;
+   interrupt-names = "tsc", "wakeup";
+
touchscreen-size-x = <1024>;
touchscreen-size-y = <600>;
+   wakeup-source;
};
 
ov2659@30 {
-- 
2.6.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] ARM: dts: am437x-gp-evm: Add wakeup interrupt source for pixcir_i2c_ts

2015-10-13 Thread Vignesh R
On am437x-gp-evm, pixcir_i2c_ts can wakeup the system from lower power
state via pinctrl and IO daisy chain using generic wakeirq framework.
With commit 3fffd1283927 ("i2c: allow specifying separate wakeup
interrupt in device tree") i2c core allows optional wakeirq to be
specified via device tree. Add wakeup irq entry to enable pixcir_i2c_ts
to wake the system from low power state.

Signed-off-by: Vignesh R <vigne...@ti.com>
---
 arch/arm/boot/dts/am437x-gp-evm.dts | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts 
b/arch/arm/boot/dts/am437x-gp-evm.dts
index 22038f21f228..69e93af7df0d 100644
--- a/arch/arm/boot/dts/am437x-gp-evm.dts
+++ b/arch/arm/boot/dts/am437x-gp-evm.dts
@@ -581,8 +581,13 @@
 
attb-gpio = < 22 GPIO_ACTIVE_HIGH>;
 
+   interrupts-extended = < 22 GPIO_ACTIVE_HIGH>,
+ <_pinmux 0x264>;
+   interrupt-names = "tsc", "wakeup";
+
touchscreen-size-x = <1024>;
touchscreen-size-y = <600>;
+   wakeup-source;
};
 
ov2659@30 {
-- 
2.6.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] spi: spi-ti-qspi: switch to polling mode for better r/w performance

2015-10-13 Thread Vignesh R
Currently word completion interrupt is fired for transfer of every
word(8bit to 128bit in size). This adds a lot of overhead, and decreases
r/w throughput. It hardly takes 3us(@48MHz) for 128bit r/w to complete,
hence its better to poll on word complete bit to be set in
QSPI_SPI_STATUS_REG instead of using interrupts.
This increases the throughput by 30% in both read and write case.

So, switch to polling mode instead of interrupts to determine completion
of word transfer.

Signed-off-by: Vignesh R <vigne...@ti.com>
---

Tested on DRA74 Rev G EVM.

 drivers/spi/spi-ti-qspi.c | 74 +--
 1 file changed, 20 insertions(+), 54 deletions(-)

diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index 81b84858cfee..69c1a95b0615 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -39,8 +39,6 @@ struct ti_qspi_regs {
 };
 
 struct ti_qspi {
-   struct completion   transfer_complete;
-
/* list synchronization */
struct mutexlist_lock;
 
@@ -62,10 +60,6 @@ struct ti_qspi {
 
 #define QSPI_PID   (0x0)
 #define QSPI_SYSCONFIG (0x10)
-#define QSPI_INTR_STATUS_RAW_SET   (0x20)
-#define QSPI_INTR_STATUS_ENABLED_CLEAR (0x24)
-#define QSPI_INTR_ENABLE_SET_REG   (0x28)
-#define QSPI_INTR_ENABLE_CLEAR_REG (0x2c)
 #define QSPI_SPI_CLOCK_CNTRL_REG   (0x40)
 #define QSPI_SPI_DC_REG(0x44)
 #define QSPI_SPI_CMD_REG   (0x48)
@@ -97,7 +91,6 @@ struct ti_qspi {
 #define QSPI_RD_DUAL   (3 << 16)
 #define QSPI_RD_QUAD   (7 << 16)
 #define QSPI_INVAL (4 << 16)
-#define QSPI_WC_CMD_INT_EN (1 << 14)
 #define QSPI_FLEN(n)   ((n - 1) << 0)
 #define QSPI_WLEN_MAX_BITS 128
 #define QSPI_WLEN_MAX_BYTES16
@@ -106,10 +99,6 @@ struct ti_qspi {
 #define BUSY   0x01
 #define WC 0x02
 
-/* INTERRUPT REGISTER */
-#define QSPI_WC_INT_EN (1 << 1)
-#define QSPI_WC_INT_DISABLE(1 << 1)
-
 /* Device Control */
 #define QSPI_DD(m, n)  (m << (3 + n * 8))
 #define QSPI_CKPHA(n)  (1 << (2 + n * 8))
@@ -217,6 +206,24 @@ static inline u32 qspi_is_busy(struct ti_qspi *qspi)
return stat & BUSY;
 }
 
+static inline int ti_qspi_poll_wc(struct ti_qspi *qspi)
+{
+   u32 stat;
+   unsigned long timeout = jiffies + QSPI_COMPLETION_TIMEOUT;
+
+   do {
+   stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG);
+   if (stat & WC)
+   return 0;
+   cpu_relax();
+   } while (time_after(timeout, jiffies));
+
+   stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG);
+   if (stat & WC)
+   return 0;
+   return  -ETIMEDOUT;
+}
+
 static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t)
 {
int wlen, count, xfer_len;
@@ -275,8 +282,7 @@ static int qspi_write_msg(struct ti_qspi *qspi, struct 
spi_transfer *t)
}
 
ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG);
-   if (!wait_for_completion_timeout(>transfer_complete,
-QSPI_COMPLETION_TIMEOUT)) {
+   if (ti_qspi_poll_wc(qspi)) {
dev_err(qspi->dev, "write timed out\n");
return -ETIMEDOUT;
}
@@ -315,8 +321,7 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct 
spi_transfer *t)
return -EBUSY;
 
ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG);
-   if (!wait_for_completion_timeout(>transfer_complete,
-QSPI_COMPLETION_TIMEOUT)) {
+   if (ti_qspi_poll_wc(qspi)) {
dev_err(qspi->dev, "read timed out\n");
return -ETIMEDOUT;
}
@@ -388,9 +393,7 @@ static int ti_qspi_start_transfer_one(struct spi_master 
*master,
qspi->cmd = 0;
qspi->cmd |= QSPI_EN_CS(spi->chip_select);
qspi->cmd |= QSPI_FLEN(frame_length);
-   qspi->cmd |= QSPI_WC_CMD_INT_EN;
 
-   ti_qspi_write(qspi, QSPI_WC_INT_EN, QSPI_INTR_ENABLE_SET_REG);
ti_qspi_write(qspi, qspi->dc, QSPI_SPI_DC_REG);
 
mutex_lock(>list_lock);
@@ -417,31 +420,6 @@ static int ti_qspi_start_transfer_one(struct spi_master 
*master,
return status;
 }
 
-static irqreturn_t ti_qspi_isr(int irq, void *dev_id)
-{
-   struct ti_qspi *qspi = dev_id;
-   u16 int_stat;
-   u32 stat;
-
-   irqreturn_t ret = IRQ_HANDLED;
-
-   int_stat = ti_qspi_read(qspi, QSPI_INTR_STATUS_ENABLED_CLEAR);
-   stat = ti_qspi_read(qspi, QSPI_SPI_STA

[PATCH] spi: ti-qspi: Fix data corruption seen on r/w stress test

2015-10-12 Thread Vignesh R
Writing invalid command to QSPI_SPI_CMD_REG will terminate current
transfer and de-assert the chip select. This has to be done before
calling spi_finalize_current_message(). Because
spi_finalize_current_message() will mark the end of current message
transfer and schedule the next transfer. If the chipselect is not
de-asserted before calling spi_finalize_current_message() then the next
transfer will overlap with the previous transfer leading to data
corruption.
__spi_pump_message() can be called either from kthread worker context or
directly from the calling process's context. It is possible that these
two calls can race against each other. But race is serialized by
checking whether master->cur_msg == NULL (pointer to msg being handled
by transfer_one() at present). The master->cur_msg is set to NULL when
spi_finalize_current_message() is called on that message, which means
calling spi_finalize_current_message() allows __spi_sync() to pump next
message in calling process context.
Now if spi-ti-qspi calls spi_finalize_current_message() before we
terminate transfer at hardware side, if __spi_pump_message() is called
from process context then the successive transactions can overlap.

Fix this by moving writing invalid command to QSPI_SPI_CMD_REG to
before calling spi_finalize_current_message() call.

Cc: sta...@vger.kernel.org # v3.12+
Signed-off-by: Vignesh R <vigne...@ti.com>
---
 drivers/spi/spi-ti-qspi.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index aa6d284131e0..81b84858cfee 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -410,11 +410,10 @@ static int ti_qspi_start_transfer_one(struct spi_master 
*master,
 
mutex_unlock(>list_lock);
 
+   ti_qspi_write(qspi, qspi->cmd | QSPI_INVAL, QSPI_SPI_CMD_REG);
m->status = status;
spi_finalize_current_message(master);
 
-   ti_qspi_write(qspi, qspi->cmd | QSPI_INVAL, QSPI_SPI_CMD_REG);
-
return status;
 }
 
-- 
2.6.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/5] spi: introduce mmap read support for spi flash devices

2015-09-18 Thread Vignesh R


On 09/16/2015 04:26 PM, Mark Brown wrote:
> On Wed, Sep 16, 2015 at 03:38:09PM +0530, Vignesh R wrote:
> 
>> But, I didn't get how to integrate with existing message queue. Memory
>> mapped read by-passes message queue of SPI core. Could you please
>> explain a bit more on integrating with message queue? Did you mean
>> locking the existing message queue when memory mapped read is being
>> requested?
> 
> Yes, and also making sure that we don't everything gets processed in
> order so memory mapped requests come after any commands needed to set
> them up and don't starve other work.
> 

Ok, thanks for the clarification!

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/5] mtd: devices: m25p80: add support for mmap read request

2015-09-16 Thread Vignesh R


On 09/14/2015 11:57 PM, Mark Brown wrote:
> On Fri, Sep 04, 2015 at 02:00:00PM +0530, Vignesh R wrote:
> 
>> +if (spi->master->spi_mtd_mmap_read) {
>> +return  spi->master->spi_mtd_mmap_read(spi, from, len,
>> +   retlen, buf,
>> +   nor->read_opcode,
>> +   nor->addr_width,
>> +   dummy);
>> +}
> 
> We should be calling some API provided by the SPI core here, not peering
> directly into the ops struture.
> 

Ok..
-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/5] spi: introduce mmap read support for spi flash devices

2015-09-16 Thread Vignesh R


On 09/15/2015 12:07 AM, Mark Brown wrote:
> On Fri, Sep 04, 2015 at 01:59:58PM +0530, Vignesh R wrote:
>> In addition to providing direct access to SPI bus, some spi controller
>> hardwares (like ti-qspi) provide special memory mapped port
>> to accesses SPI flash devices in order to increase read performance.
>> This means the controller can automatically send the SPI signals
>> required to read data from the SPI flash device.
> 
> Sorry, also meant to say here: as I kind of indicated in response to the
> flash patch I'd expect to see the SPI core know something about this and
> export an API for this which is integrated with things like the existing
> message queue.
> 


Adding an API to SPI core makes sense to me. This can take care of spi
bus locking and runtime pm.
But, I didn't get how to integrate with existing message queue. Memory
mapped read by-passes message queue of SPI core. Could you please
explain a bit more on integrating with message queue? Did you mean
locking the existing message queue when memory mapped read is being
requested?


Thanks,
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/5] spi: introduce mmap read support for spi flash devices

2015-09-16 Thread Vignesh R


On 09/15/2015 12:05 AM, Mark Brown wrote:
> On Fri, Sep 04, 2015 at 04:55:33PM +0530, Jagan Teki wrote:
>> On 4 September 2015 at 13:59, Vignesh R <vigne...@ti.com> wrote:
> 
>>> + * @spi_mtd_mmap_read: some spi-controller hardwares provide memory
>>> + * mapped interface to communicate with mtd flashes.
>>> + * For this, spi  controller needs to know flash
>>> + * memory settings like read command to use, dummy
>>> + * bytes and address width. Once these settings are
>>> + * populated in hardware registers, any read
>>> + * accesses to flash's memory map region(as defined
>>> + * by SoC) through memcpy or mem-to-mem DMA copy
>>> + * will be handled by controller hardware. The
>>> + * hardware will automatically generate spi signals
>>> + * required to read data from flash and present it
>>> + * to CPU or DMA. SPI master drivers can use this
>>> + * callback to implement memory mapped read
>>> + * interface. Flash driver (like m25p80) requests
>>> + * memory mapped read via this method. The interface
>>> + * should  only be used mtd flashes and cannot be
>>> + * used with other spi devices.
> 
> This comment is *way* too verbose - probably you just need up to the
> "Once" here.
> 

Ok, I will move the extra text to commit log.


-- 
Thanks,
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/5] spi: spi-ti-qspi: add mmap mode read support

2015-09-16 Thread Vignesh R


On 09/14/2015 11:56 PM, Mark Brown wrote:
> On Fri, Sep 04, 2015 at 01:59:59PM +0530, Vignesh R wrote:
> 
>> +static int ti_qspi_spi_mtd_mmap_read(struct  spi_device *spi,
>> + loff_t from, size_t len,
>> + size_t *retlen, u_char *buf,
>> + u8 read_opcode, u8 addr_width,
>> + u8 dummy_bytes)
>> +{
>> +struct ti_qspi *qspi = spi_master_get_devdata(spi->master);
>> +int ret = 0;
>> +
>> +spi_bus_lock(qspi->master);
> 
> I suspect I'm going to see the answer to this in another patch but the
> fact that we're having to take this lock in a driver when it's an op the
> core should be calling.
>

Agree..

>> +ret = pm_runtime_get_sync(qspi->dev);
>> +if (ret < 0) {
>> +dev_err(qspi->dev, "pm_runtime_get_sync() failed\n");
>> +return ret;
>> +}
> 
> This would be better outside the lock, there's no need to have the lock
> before we power on and this fixes the fact that you don't release the
> lock here.

Will take care of this in SPI core API

> 
>> +memcpy(buf, (__force void *)(qspi->mmap_base + from), len);
> 
> The fact that you're having to cast here should be a warning that
> there's someting wrong here.  I think you're looking for
> memcpy_fromio().

Ok, will change to memcpy_fromio()

> 
>> @@ -479,6 +576,7 @@ static int ti_qspi_probe(struct platform_device *pdev)
>>  master->setup = ti_qspi_setup;
>>  master->auto_runtime_pm = true;
>>  master->transfer_one_message = ti_qspi_start_transfer_one;
>> +master->spi_mtd_mmap_read = ti_qspi_spi_mtd_mmap_read;
>>  master->dev.of_node = pdev->dev.of_node;
>>  master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) |
>>   SPI_BPW_MASK(8);
> 
> Don't we need to map a resource somewhere?
> 

The current driver code already does the resource mapping:

res_mmap = platform_get_resource_byname(pdev,
IORESOURCE_MEM, "qspi_mmap");


-- 
Thanks,
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/5] ARM: dts: AM4372: add entry for qspi mmap region

2015-09-04 Thread Vignesh R
Add qspi memory mapped region entries for AM43xx based SoCs. Also,
update the binding documents for the controller to document this change.

Signed-off-by: Vignesh R <vigne...@ti.com>
---
 Documentation/devicetree/bindings/spi/ti_qspi.txt | 5 +++--
 arch/arm/boot/dts/am4372.dtsi | 4 +++-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/ti_qspi.txt 
b/Documentation/devicetree/bindings/spi/ti_qspi.txt
index f05dd631bef1..05488970060b 100644
--- a/Documentation/devicetree/bindings/spi/ti_qspi.txt
+++ b/Documentation/devicetree/bindings/spi/ti_qspi.txt
@@ -17,9 +17,10 @@ Recommended properties:
 
 Example:
 
+For am4372:
 qspi: qspi@4b30 {
-   compatible = "ti,dra7xxx-qspi";
-   reg = <0x4790 0x100>, <0x3000 0x3ff>;
+   compatible = "ti,am4372-qspi";
+   reg = <0x4790 0x100>, <0x3000 0x400>;
reg-names = "qspi_base", "qspi_mmap";
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index ade28c790f4b..52cf4846b8e1 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -902,7 +902,9 @@
 
qspi: qspi@4790 {
compatible = "ti,am4372-qspi";
-   reg = <0x4790 0x100>;
+   reg = <0x4790 0x100>,
+ <0x3000 0x400>;
+   reg-names = "qspi_base", "qspi_mmap";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "qspi";
-- 
2.5.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/5] mtd: devices: m25p80: add support for mmap read request

2015-09-04 Thread Vignesh R
Certain spi controllers may support memory mapped interface to read from
m25p80 type flash devices. This interface provides better read
performance than regular SPI interface.
Call spi_mtd_mmap_read() function, if available, to make use of
memory-mapped interface.

Signed-off-by: Vignesh R <vigne...@ti.com>
---
 drivers/mtd/devices/m25p80.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index d313f948b96c..b8b391aab331 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -133,6 +133,14 @@ static int m25p80_read(struct spi_nor *nor, loff_t from, 
size_t len,
/* convert the dummy cycles to the number of bytes */
dummy /= 8;
 
+   if (spi->master->spi_mtd_mmap_read) {
+   return  spi->master->spi_mtd_mmap_read(spi, from, len,
+  retlen, buf,
+  nor->read_opcode,
+  nor->addr_width,
+  dummy);
+   }
+
spi_message_init();
memset(t, 0, (sizeof t));
 
-- 
2.5.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/5] ARM: dts: DRA7: add entry for qspi mmap region

2015-09-04 Thread Vignesh R
Add qspi memory mapped region entries for DRA7xx based SoCs. Also,
update the binding documents for the controller to document this change.

Signed-off-by: Vignesh R <vigne...@ti.com>
---
 Documentation/devicetree/bindings/spi/ti_qspi.txt | 13 +
 arch/arm/boot/dts/dra7.dtsi   |  6 --
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/ti_qspi.txt 
b/Documentation/devicetree/bindings/spi/ti_qspi.txt
index 601a360531a5..f05dd631bef1 100644
--- a/Documentation/devicetree/bindings/spi/ti_qspi.txt
+++ b/Documentation/devicetree/bindings/spi/ti_qspi.txt
@@ -26,3 +26,16 @@ qspi: qspi@4b30 {
spi-max-frequency = <2500>;
ti,hwmods = "qspi";
 };
+
+For dra7xx:
+qspi: qspi@4b30 {
+   compatible = "ti,dra7xxx-qspi";
+   reg = <0x4b30 0x100>, <0x4a002558 0x4>,
+ <0x5c00 0x400>;
+   reg-names = "qspi_base", "qspi_ctrlmod",
+   "qspi_mmap";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   spi-max-frequency = <4800>;
+   ti,hwmods = "qspi";
+};
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 1e29ccf77ea2..f6798d6ecd60 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1103,8 +1103,10 @@
 
qspi: qspi@4b30 {
compatible = "ti,dra7xxx-qspi";
-   reg = <0x4b30 0x100>;
-   reg-names = "qspi_base";
+   reg = <0x4b30 0x100>, <0x4a002558 0x4>,
+ <0x5c00 0x400>;
+   reg-names = "qspi_base", "qspi_ctrlmod",
+   "qspi_mmap";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "qspi";
-- 
2.5.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/5] spi: introduce mmap read support for spi flash devices

2015-09-04 Thread Vignesh R
In addition to providing direct access to SPI bus, some spi controller
hardwares (like ti-qspi) provide special memory mapped port
to accesses SPI flash devices in order to increase read performance.
This means the controller can automatically send the SPI signals
required to read data from the SPI flash device.
For this, spi controller needs to know flash specific information like
read command to use, dummy bytes and address width. Once these settings
are populated in hardware registers, any read accesses to flash's memory
map region(SoC specific) through memcpy or mem-to-mem DMA copy will be
handled by controller hardware. The hardware will automatically generate
spi signals required to read data from flash and present it to CPU or
DMA engine.

Introduce spi_mtd_mmap_read() method to support memory mapped read
over SPI flash devices. SPI master drivers can implement this method to
support memory mapped read interfaces. m25p80 flash driver and other
flash drivers can call this to request memory mapped read. The interface
should only be used mtd flashes and cannot be used with other spi devices.

Signed-off-by: Vignesh R <vigne...@ti.com>
---
 include/linux/spi/spi.h | 21 +
 1 file changed, 21 insertions(+)

diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index d673072346f2..b74a3f169fc2 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -293,6 +293,23 @@ static inline void spi_unregister_driver(struct spi_driver 
*sdrv)
  * @handle_err: the subsystem calls the driver to handle an error that occurs
  * in the generic implementation of transfer_one_message().
  * @unprepare_message: undo any work done by prepare_message().
+ * @spi_mtd_mmap_read: some spi-controller hardwares provide memory
+ * mapped interface to communicate with mtd flashes.
+ * For this, spi  controller needs to know flash
+ * memory settings like read command to use, dummy
+ * bytes and address width. Once these settings are
+ * populated in hardware registers, any read
+ * accesses to flash's memory map region(as defined
+ * by SoC) through memcpy or mem-to-mem DMA copy
+ * will be handled by controller hardware. The
+ * hardware will automatically generate spi signals
+ * required to read data from flash and present it
+ * to CPU or DMA. SPI master drivers can use this
+ * callback to implement memory mapped read
+ * interface. Flash driver (like m25p80) requests
+ * memory mapped read via this method. The interface
+ * should  only be used mtd flashes and cannot be
+ * used with other spi devices.
  * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
  * number. Any individual value may be -ENOENT for CS lines that
  * are not GPIOs (driven by the SPI controller itself).
@@ -438,6 +455,10 @@ struct spi_master {
   struct spi_message *message);
int (*unprepare_message)(struct spi_master *master,
 struct spi_message *message);
+   int (*spi_mtd_mmap_read)(struct  spi_device *spi,
+loff_t from, size_t len, size_t *retlen,
+u_char *buf, u8 read_opcode,
+u8 addr_width, u8 dummy_bytes);
 
/*
 * These hooks are for drivers that use a generic implementation
-- 
2.5.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/5] spi: spi-ti-qspi: add mmap mode read support

2015-09-04 Thread Vignesh R
ti-qspi controller provides mmap port to read data from SPI flashes.
mmap port is enabled in QSPI_SPI_SWITCH_REG (ctrl module bits may
also need to be updated for some SoCs). The QSPI_SPI_SETUP_REGx needs to
be populated with flash specific information like read opcode, read
mode(quad, dual, normal), address width and dummy bytes. Once,
controller is in mmap mode, the whole flash memory is available as a
memory region at SoC specific address. This region can be accessed using
normal memcpy() or mem-to-mem dma copy. The ti-qspi controller hardware
will internally communicate with SPI flash over SPI bus and get the
requested data.

Implement spi_mtd_mmap_read() method to support mmap read over SPI
flash devices. With this, the read throughput increases from ~100kB/s to
~2.5 MB/s.

Signed-off-by: Vignesh R <vigne...@ti.com>
---
 drivers/spi/spi-ti-qspi.c | 106 --
 1 file changed, 102 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index aa6d284131e0..a07610b84bc9 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -71,11 +71,8 @@ struct ti_qspi {
 #define QSPI_SPI_CMD_REG   (0x48)
 #define QSPI_SPI_STATUS_REG(0x4c)
 #define QSPI_SPI_DATA_REG  (0x50)
-#define QSPI_SPI_SETUP0_REG(0x54)
+#define QSPI_SPI_SETUP_REG(n)  ((0x54 + 4 * n))
 #define QSPI_SPI_SWITCH_REG(0x64)
-#define QSPI_SPI_SETUP1_REG(0x58)
-#define QSPI_SPI_SETUP2_REG(0x5c)
-#define QSPI_SPI_SETUP3_REG(0x60)
 #define QSPI_SPI_DATA_REG_1(0x68)
 #define QSPI_SPI_DATA_REG_2(0x6c)
 #define QSPI_SPI_DATA_REG_3(0x70)
@@ -120,6 +117,16 @@ struct ti_qspi {
 
 #define QSPI_AUTOSUSPEND_TIMEOUT 2000
 
+#define MEM_CS_EN(n)   ((n + 1) << 8)
+
+#define MM_SWITCH  0x1
+
+#define QSPI_SETUP_RD_NORMAL   (0x0 << 12)
+#define QSPI_SETUP_RD_DUAL (0x1 << 12)
+#define QSPI_SETUP_RD_QUAD (0x3 << 12)
+#define QSPI_SETUP_ADDR_SHIFT  8
+#define QSPI_SETUP_DUMMY_SHIFT 10
+
 static inline unsigned long ti_qspi_read(struct ti_qspi *qspi,
unsigned long reg)
 {
@@ -361,6 +368,96 @@ static int qspi_transfer_msg(struct ti_qspi *qspi, struct 
spi_transfer *t)
return 0;
 }
 
+static void ti_qspi_enable_memory_map(struct spi_device *spi)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
+   u32 val;
+
+   ti_qspi_write(qspi, MM_SWITCH, QSPI_SPI_SWITCH_REG);
+   if (qspi->ctrl_mod) {
+   val = readl(qspi->ctrl_base);
+   val |= MEM_CS_EN(spi->chip_select);
+   writel(val, qspi->ctrl_base);
+   }
+}
+
+static void ti_qspi_disable_memory_map(struct spi_device *spi)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
+   u32 val;
+
+   ti_qspi_write(qspi, 0, QSPI_SPI_SWITCH_REG);
+   if (qspi->ctrl_mod) {
+   val = readl(qspi->ctrl_base);
+   val &= ~MEM_CS_EN(spi->chip_select);
+   writel(val, qspi->ctrl_base);
+   }
+}
+
+static void ti_qspi_setup_mmap_read(struct spi_device *spi,
+   u8 read_opcode, u8 addr_width,
+   u8 dummy_bytes)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
+   u32 mode = spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD);
+   u32 memval = read_opcode;
+
+   switch (mode) {
+   case SPI_RX_QUAD:
+   memval |= QSPI_SETUP_RD_QUAD;
+   break;
+   case SPI_RX_DUAL:
+   memval |= QSPI_SETUP_RD_DUAL;
+   break;
+   default:
+   memval |= QSPI_SETUP_RD_NORMAL;
+   break;
+   }
+   memval |= ((addr_width - 1) << QSPI_SETUP_ADDR_SHIFT |
+  dummy_bytes << QSPI_SETUP_DUMMY_SHIFT);
+   ti_qspi_write(qspi, memval,
+ QSPI_SPI_SETUP_REG(spi->chip_select));
+}
+
+static int ti_qspi_spi_mtd_mmap_read(struct  spi_device *spi,
+loff_t from, size_t len,
+size_t *retlen, u_char *buf,
+u8 read_opcode, u8 addr_width,
+u8 dummy_bytes)
+{
+   struct ti_qspi *qspi = spi_master_get_devdata(spi->master);
+   int ret = 0;
+
+   spi_bus_lock(qspi->master);
+   mutex_lock(>list_lock);
+   ret = pm_runtime_get_sync(qspi->dev);
+   if (ret < 0) {
+   dev_err(qspi->dev, "pm_runtime_get_sync() failed\n");
+   return ret;
+   }
+
+   /* disable WC interrupt during memcpy */
+   ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_EN

[PATCH 0/5] Add memory mapped read support for ti-qspi

2015-09-04 Thread Vignesh R

Hi,

This patch series adds support for memory mapped read port of ti-qspi.
ti-qspi has a special memory mapped port through which SPI flash
memories can be accessed directly via SoC specific memory region.

First patch adds a method to pass flash specific information like read
opcode, dummy bytes etc and to request mmap read. Second patch
implements mmap read method in ti-qspi driver. Patch 3 adapts m25p80 to
use mmap read method before trying normal SPI transfer. Patch 4 and 5
add memory map region DT entries for DRA7xx and AM43xx SoCs.

This patch series is based on the discussions here:
http://www.spinics.net/lists/linux-spi/msg04796.html

Tested on DRA74 EVM and AM437x-SK.
Read performance increases from ~100kB/s to ~2.5MB/s.


Vignesh R (5):
  spi: introduce mmap read support for spi flash devices
  spi: spi-ti-qspi: add mmap mode read support
  mtd: devices: m25p80: add support for mmap read request
  ARM: dts: DRA7: add entry for qspi mmap region
  ARM: dts: AM4372: add entry for qspi mmap region

 Documentation/devicetree/bindings/spi/ti_qspi.txt |  18 +++-
 arch/arm/boot/dts/am4372.dtsi |   4 +-
 arch/arm/boot/dts/dra7.dtsi   |   6 +-
 drivers/mtd/devices/m25p80.c  |   8 ++
 drivers/spi/spi-ti-qspi.c | 106 +-
 include/linux/spi/spi.h   |  21 +
 6 files changed, 154 insertions(+), 9 deletions(-)

-- 
2.5.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] spi: ti-qspi: use 128 bit transfer mode for writing to flash

2015-08-25 Thread Vignesh R


On 08/20/2015 11:25 PM, Mark Brown wrote:
 On Thu, Aug 20, 2015 at 04:00:59PM +0530, Vignesh R wrote:
 
 -writeb(*txbuf, qspi-base + QSPI_SPI_DATA_REG);
 +if (count = QSPI_WLEN_MAX_BYTES) {
 +u32 *txp = (u32 *)txbuf;
 +
 +data = cpu_to_be32(*txp++);
 +writel(data, qspi-base +
 +   QSPI_SPI_DATA_REG_3);
 +data = cpu_to_be32(*txp++);
 +writel(data, qspi-base +
 +   QSPI_SPI_DATA_REG_2);
 +data = cpu_to_be32(*txp++);
 +writel(data, qspi-base +
 +   QSPI_SPI_DATA_REG_1);
 +data = cpu_to_be32(*txp++);
 +writel(data, qspi-base +
 +   QSPI_SPI_DATA_REG);
 +xfer_len = QSPI_WLEN_MAX_BYTES;
 +cmd |= QSPI_WLEN(QSPI_WLEN_MAX_BITS);
 +} else {
 +writeb(*txbuf, qspi-base + QSPI_SPI_DATA_REG);
 +cmd = qspi-cmd | QSPI_WR_SNGL;
 +xfer_len = wlen;
 +cmd |= QSPI_WLEN(wlen);
 +}
 
 It's a bit sad that this isn't able to do a Duff's device type thing and
 only kicks in for the full 128 bit FIFO size, it looks like it could do
 any number of words.
 

Yes, any number of bytes can be transfered (max 16 bytes).
I will try to work on your suggestion. Thanks!

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] spi: ti-qspi: use 128 bit transfer mode for writing to flash

2015-08-20 Thread Vignesh R
TI QSPI has four 32 bit data regsiters which can be used to transfer 16
bytes of data at once. The register group QSPI_SPI_DATA_REG_3,
QSPI_SPI_DATA_REG_2, QSPI_SPI_DATA_REG_1 and QSPI_SPI_DATA_REG is
treated as a single 128-bit word for shifting data in and out. The bit
at QSPI_SPI_DATA_REG_3[31] position is the first bit to be shifted out
in case of 128 bit transfer mode. Therefore the first byte to be written
to flash should be at QSPI_SPI_DATA_REG_3[31-25] position.
Instead of writing 1 byte at a time when interacting with spi-nor flash,
make use of all the four registers so that 16 bytes can be transferred
in one go. This reduces number of register writes and Word Complete
interrupts for a given transfer message size, thereby increasing the
write performance.

Without this patch the raw flash write speed is ~100KB/s, with this
patch the write speed increases to ~400 kB/s on DRA74 EVM.

Signed-off-by: Vignesh R vigne...@ti.com
---
 drivers/spi/spi-ti-qspi.c | 34 ++
 1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index 45844a227c5e..f4cea6834fad 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -96,6 +96,8 @@ struct ti_qspi {
 #define QSPI_INVAL (4  16)
 #define QSPI_WC_CMD_INT_EN (1  14)
 #define QSPI_FLEN(n)   ((n - 1)  0)
+#define QSPI_WLEN_MAX_BITS 128
+#define QSPI_WLEN_MAX_BYTES16
 
 /* STATUS REGISTER */
 #define BUSY   0x01
@@ -224,14 +226,16 @@ static inline u32 qspi_is_busy(struct ti_qspi *qspi)
 
 static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t)
 {
-   int wlen, count;
+   int wlen, count, xfer_len;
unsigned int cmd;
const u8 *txbuf;
+   u32 data;
 
txbuf = t-tx_buf;
cmd = qspi-cmd | QSPI_WR_SNGL;
count = t-len;
wlen = t-bits_per_word  3;   /* in bytes */
+   xfer_len = wlen;
 
while (count) {
if (qspi_is_busy(qspi))
@@ -241,7 +245,29 @@ static int qspi_write_msg(struct ti_qspi *qspi, struct 
spi_transfer *t)
case 1:
dev_dbg(qspi-dev, tx cmd %08x dc %08x data %02x\n,
cmd, qspi-dc, *txbuf);
-   writeb(*txbuf, qspi-base + QSPI_SPI_DATA_REG);
+   if (count = QSPI_WLEN_MAX_BYTES) {
+   u32 *txp = (u32 *)txbuf;
+
+   data = cpu_to_be32(*txp++);
+   writel(data, qspi-base +
+  QSPI_SPI_DATA_REG_3);
+   data = cpu_to_be32(*txp++);
+   writel(data, qspi-base +
+  QSPI_SPI_DATA_REG_2);
+   data = cpu_to_be32(*txp++);
+   writel(data, qspi-base +
+  QSPI_SPI_DATA_REG_1);
+   data = cpu_to_be32(*txp++);
+   writel(data, qspi-base +
+  QSPI_SPI_DATA_REG);
+   xfer_len = QSPI_WLEN_MAX_BYTES;
+   cmd |= QSPI_WLEN(QSPI_WLEN_MAX_BITS);
+   } else {
+   writeb(*txbuf, qspi-base + QSPI_SPI_DATA_REG);
+   cmd = qspi-cmd | QSPI_WR_SNGL;
+   xfer_len = wlen;
+   cmd |= QSPI_WLEN(wlen);
+   }
break;
case 2:
dev_dbg(qspi-dev, tx cmd %08x dc %08x data %04x\n,
@@ -261,8 +287,8 @@ static int qspi_write_msg(struct ti_qspi *qspi, struct 
spi_transfer *t)
dev_err(qspi-dev, write timed out\n);
return -ETIMEDOUT;
}
-   txbuf += wlen;
-   count -= wlen;
+   txbuf += xfer_len;
+   count -= xfer_len;
}
 
return 0;
-- 
2.5.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 1/5] spi: introduce flag for memory mapped read

2015-08-12 Thread Vignesh R


On 08/07/2015 03:46 PM, Michal Suchanek wrote:
[snip]
 On 7 August 2015 at 10:35, Vignesh R vigne...@ti.com wrote:


 On 08/07/2015 01:08 PM, Michal Suchanek wrote:

 Now since the description is clearer it's obvious that ti-qspi cannot
 work fully mmapped as fsl-qspi does because the setup has to be done
 over normal spi access and using non-m25p80 devices on the same bus is
 a requirement.

 The place where it is known if a transfer can use the mmap access is 
 m25p80.c

 So my suggestion is

  - add a new method for spi master that gets the read opcode, dummy
 length, address, address length, buffer, buffer length and performs
 read from the flash memory in a hardware-specific way

 - add a check in m25p80.c that the master supports this feature and if
 so use it (eg check that the method is non-null)

 Presumably if some new SPI controllers with similar feature are
 supported in the future they can use the same inteface because you
 pass on everything the m25p80 read knows.


 Ok... Do you mean something like this?

 I will take m25p80 as example but can be expanded for any flash.

 In include/linux/mtd.h:
 struct spi_mtd_config_info {
 struct spi_device   *spi;
 u32 page_size;
 u8  addr_width;
 u8  erase_opcode;
 u8  read_opcode;
 u8  read_dummy;
 u8  program_opcode;
 enum read_mode  flash_read;

 } /* subset of struct spi_nor */

 
 I would just pass these as separate arguments to the function but whatver.
 
 In m25p80.c:

 static int m25p80_read(struct spi_nor *nor, loff_t from,
 size_t len, size_t *retlen,
 u_char *buf)
 {
 struct spi_mtd_config_info info;
 struct spi_device *spi;

 if (spi-master-spi_mtd_mmap_read) {
   /* Populate spi_mtd_config_info */
   spi-master-spi_mtd_mmap_read(info, from, len,
  retlen, buf);
 }
 else {
 /* no mtd specific acceleration supported try normal
  * SPI way of communicating with flash
  * continue with current code
  * set up spi_message and call spi_sync()
  */
 }

   }

 In spi-ti-qspi.c:
 Implement spi_mtd_mmap_read while holding master-bus_lock mutex.

 

I will re-submit patches based on the above idea, if there are no
further comments..

-- 
Thanks
Vignesh
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 1/5] spi: introduce flag for memory mapped read

2015-08-07 Thread Vignesh R


On 08/07/2015 01:08 PM, Michal Suchanek wrote:

 Now since the description is clearer it's obvious that ti-qspi cannot
 work fully mmapped as fsl-qspi does because the setup has to be done
 over normal spi access and using non-m25p80 devices on the same bus is
 a requirement.
 
 The place where it is known if a transfer can use the mmap access is m25p80.c
 
 So my suggestion is
 
  - add a new method for spi master that gets the read opcode, dummy
 length, address, address length, buffer, buffer length and performs
 read from the flash memory in a hardware-specific way
 
 - add a check in m25p80.c that the master supports this feature and if
 so use it (eg check that the method is non-null)
 
 Presumably if some new SPI controllers with similar feature are
 supported in the future they can use the same inteface because you
 pass on everything the m25p80 read knows.
 

Ok... Do you mean something like this?

I will take m25p80 as example but can be expanded for any flash.

In include/linux/mtd.h:
struct spi_mtd_config_info {
struct spi_device   *spi;
u32 page_size;
u8  addr_width;
u8  erase_opcode;
u8  read_opcode;
u8  read_dummy;
u8  program_opcode;
enum read_mode  flash_read;

} /* subset of struct spi_nor */


In m25p80.c:

static int m25p80_read(struct spi_nor *nor, loff_t from,
size_t len, size_t *retlen,
u_char *buf)
{
struct spi_mtd_config_info info;
struct spi_device *spi;

if (spi-master-spi_mtd_mmap_read) {
  /* Populate spi_mtd_config_info */
  spi-master-spi_mtd_mmap_read(info, from, len,
 retlen, buf);
}
else {
/* no mtd specific acceleration supported try normal
 * SPI way of communicating with flash
 * continue with current code
 * set up spi_message and call spi_sync()
 */
}

  }

In spi-ti-qspi.c:
Implement spi_mtd_mmap_read while holding master-bus_lock mutex.


-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 1/5] spi: introduce flag for memory mapped read

2015-08-06 Thread Vignesh R


On 08/06/2015 03:52 PM, Russell King - ARM Linux wrote:
 On Thu, Aug 06, 2015 at 12:01:37PM +0200, Michal Suchanek wrote:
 Disclaimer: I am not familiar with the hardware for which this patch
 adds support.

 However, I am familiar m25p80.c and as I understand it the controller
 is basically supposed to implement m25p80.c in hardware when this flag
 is set.
 
 That, to me, sounds like what you have is:
 
 ---m25p80 specific interface---SPI bus---m25p80 device
 
 Where the m25p80 specific interface does not expose direct access to the
 SPI bus?
 

Let me give overview of ti-qspi controller:

There are two interfaces in the controller, one exposes direct access to
SPI bus and the other doesn't. It is possible to dynamically switch
between these ports by writing to QSPI_SPI_SWITCH_REG.

The two interface are [1]:
1) Generic SPI interface: (config port): with this interface, ti-qspi
controller can communicate with *any* spi device (flash and non-flash).
This interface is provides direct access to SPI bus.

2) SPI memory mapped interface (memory mapped port): This is m25p80
specific interface which can be use to read data from flash.
But if the flash has to be configured to some particular mode like QUAD
READ MODE, then the controller needs to be put in to config port to read
and modify serial flash's config register and then switch to memory
mapped port in order to read data stored on flash.

For example on DRA74 evm, if a 64 MB flash is connected as a slave,
entire flash memory is visible from 0x5C00 to 0x5FFF L3_MAIN
address. In order to read using memory mapped port following will be the
sequence:

1.Write to flash config register via config port to switch to QUAD MODE
(or any mode that flash supports).
2. Populate QSPI_SPI_SETUP_REGx with flash read command, number of
address bytes to use and dummy bytes required.
3. Switch to memory mapped port by writing to QSPI_SPI_SWITCH_REG.
4. Now, its possible to perform read from 0x5C00 to 0x5FFF using
memcpy. The qspi controller hardware will communicate over SPI bus and
get the data. This data is directly sent to RAM via SoC's interconnect.

Advantages of memory mapped port are: improved read performance,
MEM_TO_MEM DMA support can be added (ti-qspi hardware as such does not
provide DMA events).

Advantages of config port: can be used to communicate with *any* SPI
device, provides direct read/write access to SPI bus.

On the whole following are my requirements:
1. to be able to communicate with non -flash SPI devices via config port
( this functionality is supported by current driver, I dont want to
break it). Or pump any spi_message on to SPI bus directly.
2. take advantage of memory mapped port in order to increase read
throughput( and use dma in future) when the slave is a m25p80 type flash.
3. handle m25p80 as well as other slave on multiple chipselects.

I just need to know whether the user that requested the transfer is
m25p80 driver. If yes, ti-qspi driver can take advantage of memory
mapped interface, else just use config port to access SPI bus directly.

Writing separate driver based on spi-nor framework to interface with
m25p80 is not an option because, I would lose the ability to interface
with non-flash devices.

The spi_message that is received in transfer_one_message() is too
generic to imply the slave device that is on the other side of the wire.
IMO, the read command does not imply that the slave is m25p80 flash
(besides the read opcodes vary across vendors of m25p80 and across modes).

As Michal suggested, adding a flag to spi_device to distinguish whether
the slave is a m25p80 flash type will help spi master to handle
optimizations specific to m25p80s while being generic enough to handle
all other spi devices. Is that ok? Is there any other way to imply what
slave as at the other end?

[1] TRM: http://www.ti.com/lit/ug/spruhz6/spruhz6.pdf 24.5.4 QSPI
Functional Description
-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 1/5] spi: introduce flag for memory mapped read

2015-08-04 Thread Vignesh R


On 08/05/2015 10:51 AM, Michal Suchanek wrote:
 Hello,
 
 On 4 August 2015 at 19:59, R, Vignesh vigne...@ti.com wrote:


 On 8/4/2015 9:21 PM, Mark Brown wrote:
 On Mon, Aug 03, 2015 at 10:27:19AM +0530, Vignesh R wrote:

 @use_mmap_mode: Some SPI controller chips are optimized for interacting
 with serial flash memories. These chips have memory mapped interface,
 through which entire serial flash memory slave can be read/written as if
 though they are physical memories (like RAM). Using this interface,
 flash can be accessed using memcpy() function and the spi controller
 hardware will take care of communicating with serial flash over SPI.
 Setting this flag will indicate the SPI controller driver that the
 spi_message is from mtd layer to read from/write to flash. The SPI
 master driver can then appropriately switch the controller to memory
 mapped interface to read from/write to flash, based on this flag (See
 drivers/spi/spi-ti-qspi.c for example).
 NOTE: If the SPI controller chip lacks memory mapped interface, then the
 driver will ignore this flag and use normal SPI protocol to read
 from/write to flash. Communication with non-flash SPI devices is not
 possible using the memory mapped interface.

 I still can't tell from the above what this interface is supposed to do.
 It sounds like the use of memory mapped mode is supposed to be
 transparent to users, it should just affect how the controller interacts
 with the hardware, but if that's the case why do we need to expose it to
 users at all?  Shouldn't the driver just use memory mapped mode if it's
 faster?


 TI QSPI controller has two blocks:
 1. SPI_CORE: This is generic(normal) spi mode. This can be used to
 communicate with any SPI devices (serial flashes as well as non-flash
 devices like touchscreen).
 2. SFI_MM_IF(SPI memory mapped interface): The SFI_MM_IF block only
 allows reading and writing to an SPI flash device only. Used to speed up
 flash reads. It _cannot_ be used to communicate with non flash devices.
 Now, the spi_message that ti-qspi receives in transfer_one() callback
 can be from mtd device(in which case SFI_MM_IF can be used) or from any
 other non flash SPI device (in which case SFI_MM_IF must not be used
 instead SPI_CORE is to be used) but there is no way(is there?) to
 distinguish where spi_message is from. Therefore I introduced flag
 (use_mmap_mode) to struct spi_message. mtd driver will set flag to true,
 this helps the ti-qspi driver to determine that the user is flash device
 and thus can do read via SFI_MM_IF. If this flag is not set then the
 user is assumed to be non flash SPI driver and will use SPI_CORE block
 to communicate.

 On the whole, I just need a way to determine that the user is a flash
 device in order to switch to memory mapped interface.

 
 Maybe it can be set on the SPI slave rather than each message.

You mean to add flag to spi_device struct? That's ok for me.

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 1/5] spi: introduce flag for memory mapped read

2015-08-02 Thread Vignesh R
Hi,

On 7/31/2015 11:47 PM, Mark Brown wrote:
 On Tue, Jul 28, 2015 at 02:11:12PM +0530, Vignesh R wrote:
 
 Introduce use_mmap_read field in spi_message struct. This can be set by
 mtd devices (m25p80) to indicate to spi-master (ti-qspi) to perform
 memory mapped read. This helps to distinguish whether the spi-message is
 from mtd layer(hence mmap read is possible) or by other spi devices.
 
 Based on this description and...
 
 + * @use_mmap_mode: Indicate to spi master to perform memory mapped
 + *  read if possible.
 
 ...the internal documentation I unable to tell what is meant by perform
 a memory mapped read, at least to the extent where it is visible
 outside of the driver.  This means we can't really use this as a generic
 API since other people won't be able to tell what it does.
 


Will the following documentation provide better idea regarding the flag:

@use_mmap_mode: Some SPI controller chips are optimized for interacting
with serial flash memories. These chips have memory mapped interface,
through which entire serial flash memory slave can be read/written as if
though they are physical memories (like RAM). Using this interface,
flash can be accessed using memcpy() function and the spi controller
hardware will take care of communicating with serial flash over SPI.
Setting this flag will indicate the SPI controller driver that the
spi_message is from mtd layer to read from/write to flash. The SPI
master driver can then appropriately switch the controller to memory
mapped interface to read from/write to flash, based on this flag (See
drivers/spi/spi-ti-qspi.c for example).
NOTE: If the SPI controller chip lacks memory mapped interface, then the
driver will ignore this flag and use normal SPI protocol to read
from/write to flash. Communication with non-flash SPI devices is not
possible using the memory mapped interface.

I can update the patch commit message and documentation accordingly?

Regards
Vignesh
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 4/5] ARM: dts: DRA7: Add memory map region entries for qspi

2015-08-02 Thread Vignesh R


On 07/31/2015 11:49 PM, Mark Brown wrote:
 On Tue, Jul 28, 2015 at 02:11:15PM +0530, Vignesh R wrote:
 Add qspi memory mapped region entries for DRA7xx based SoCs.

 Signed-off-by: Vignesh R vigne...@ti.com
 
  qspi: qspi@4790 {
  compatible = ti,am4372-qspi;
 -reg = 0x4790 0x100;
 +reg = 0x4790 0x100,
 +  0x3000 0x3ff;
 +reg-names = qspi_base, qspi_mmap;
 
 The DT binding document for the controller needs to be extended to
 document this change in the binding.
 

DT bindings are already documented at
Documentation/devicetree/bindings/spi/ti_qspi.txt. Did you mean to add
this node as an example in that file?

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 4/5] ARM: dts: DRA7: Add memory map region entries for qspi

2015-08-02 Thread Vignesh R


On 08/01/2015 02:58 AM, Brian Norris wrote:
 On Tue, Jul 28, 2015 at 02:11:15PM +0530, Vignesh R wrote:
 Add qspi memory mapped region entries for DRA7xx based SoCs.

 Signed-off-by: Vignesh R vigne...@ti.com
 ---
  arch/arm/boot/dts/am4372.dtsi | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

 diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
 index ade28c790f4b..5317a0f24ab9 100644
 --- a/arch/arm/boot/dts/am4372.dtsi
 +++ b/arch/arm/boot/dts/am4372.dtsi
 @@ -902,7 +902,9 @@
  
  qspi: qspi@4790 {
  compatible = ti,am4372-qspi;
 -reg = 0x4790 0x100;
 +reg = 0x4790 0x100,
 +  0x3000 0x3ff;
 
 Are you sure this region is 1 byte shy of 64MB in length? Same question
 for patch 5.
 

Oops, my bad... Its 64MB in length, I entered offset of last byte
instead of length. Will correct this in the actual patch.

 +reg-names = qspi_base, qspi_mmap;
  #address-cells = 1;
  #size-cells = 0;
  ti,hwmods = qspi;
 -- 
 2.4.6


-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 4/5] ARM: dts: DRA7: Add memory map region entries for qspi

2015-08-02 Thread Vignesh R


On 07/31/2015 07:18 PM, Sekhar Nori wrote:
 On Tuesday 28 July 2015 02:11 PM, Vignesh R wrote:
 Add qspi memory mapped region entries for DRA7xx based SoCs.

 Signed-off-by: Vignesh R vigne...@ti.com
 ---
  arch/arm/boot/dts/am4372.dtsi | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

 diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
 index ade28c790f4b..5317a0f24ab9 100644
 --- a/arch/arm/boot/dts/am4372.dtsi
 +++ b/arch/arm/boot/dts/am4372.dtsi
 
 The patch talks about DRA7x in subject and description but you modify
 AM437x here. You have got commit text mixed up between 4/5 and 5/5.
 
 Probably not the kind of feedback you are looking for an RFC, but since
 I noticed it..

Oh, my bad.. I will correct $subject when I submit actual patch series.

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/5] ARM: OMAP2+: DRA7: Add hwmod entries for PWMSS

2015-07-29 Thread Vignesh R


On 07/23/2015 09:05 PM, R, Vignesh wrote:
 
 
 On 7/16/2015 9:01 PM, R, Vignesh wrote:
 Hi,

 On 07/16/2015 03:24 AM, Paul Walmsley wrote:
 Hi,

 some comments.

 On Wed, 3 Jun 2015, Vignesh R wrote:

 Add hwmod entries for the PWMSS on DRA7.

 Set l4_root_clk_div as the main_clk of PWMSS. It is fixed-factored clock
 equal to L4PER2_L3_GICLK/2(l3_iclk_div/2).
 As per AM57x TRM SPRUHZ6[1], October 2014, Section 29.1.3 Table 29-4,
 clock source to PWMSS is L4PER2_L3_GICLK. But it is actually
 L4PER2_L3_GICLK/2. The TRM does not show the division by 2.

 Is the divide-by-two coming from PWMSS_EPWM.EPWM_TBCTL[HSPCLKDIV]?  Or is 
 HSPCLKDIV a separate divider after the divide-by-2 you mention above?

 No, it not related to HSPCLKDIV. The TRM wrongly states L4PER2_L3_GICLK
 as clock input for PWMSS. But actually  L4PER2_L4_GICLK(=L3_GICLK/2) is
 the clock input for PWMSS. This will be updated in TRM soon.


 [1] www.ti.com/lit/ug/spruhz6/spruhz6.pdf

 Signed-off-by: Vignesh R vigne...@ti.com
 ---

 v2:
  * add TRM references.

  arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 239 
 ++
  1 file changed, 239 insertions(+)

 diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c 
 b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
 index 0e64c2fac0b5..86a7ac9a3138 100644
 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
 +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
 @@ -362,6 +362,149 @@ static struct omap_hwmod dra7xx_dcan2_hwmod = {
},
  };
  
 +/* pwmss  */
 +static struct omap_hwmod_class_sysconfig dra7xx_epwmss_sysc = {
 +  .rev_offs   = 0x0,
 +  .sysc_offs  = 0x4,
 +  .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_RESET_STATUS,

 This doesn't match SPRUHZ6 Table 29-13 PWMSS_SYSCONFIG.  There's no 
 RESETSTATUS bit.  There is a SOFTRESET bit. 

 Could you please confirm whether this is intentional?

 sorry my bad... I will change this in v3.


 +  .idlemodes  = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
 +  .sysc_fields= omap_hwmod_sysc_type2,
 +};
 +
 +struct omap_hwmod_class dra7xx_epwmss_hwmod_class = {
 +  .name   = epwmss,
 +  .sysc   = dra7xx_epwmss_sysc,
 +};
 +
 +static struct omap_hwmod_class dra7xx_ecap_hwmod_class = {
 +  .name   = ecap,
 +};
 +
 +static struct omap_hwmod_class dra7xx_eqep_hwmod_class = {
 +  .name   = eqep,
 +};
 +
 +struct omap_hwmod_class dra7xx_ehrpwm_hwmod_class = {
 +  .name   = ehrpwm,
 +};
 +
 +/* epwmss0 */
 +struct omap_hwmod dra7xx_epwmss0_hwmod = {
 +  .name   = epwmss0,
 +  .class  = dra7xx_epwmss_hwmod_class,
 +  .clkdm_name = l4per2_clkdm,
 +  .main_clk   = l4_root_clk_div,
 +  .prcm   = {
 +  .omap4  = {
 +  .modulemode = MODULEMODE_SWCTRL,
 +  .clkctrl_offs   = 
 DRA7XX_CM_L4PER2_PWMSS1_CLKCTRL_OFFSET,
 +  .context_offs   = 
 DRA7XX_RM_L4PER2_PWMSS1_CONTEXT_OFFSET,
 +  },
 +  },

 Per my comment on the previous patch, sounds like it might be better to 
 mark this as HWMOD_SWSUP_SIDLE?  Then again, see the next comment below 
 re: main_clk.

 +};
 +
 +/* ecap0 */
 +struct omap_hwmod dra7xx_ecap0_hwmod = {
 +  .name   = ecap0,
 +  .class  = dra7xx_ecap_hwmod_class,
 +  .clkdm_name = l4per2_clkdm,
 +  .main_clk   = l4_root_clk_div,

 Looking at SPRUHZ6 Section 29.1.4.2 PWMSS Modules Local Clock Gating, 
 there appears to be a local mini-PRCM for the PWMSS which implements 
 clock gating and reports back on the status of what I'd guess is the local 
 clock gating FSM.

 So from that point of view, you should probably create a clock driver that 
 manages both the clock gate request bit and the FSM status bit.  It should 
 be something that can be reused for the other PWMSS IP blocks.  Then 
 you'd create per-IP block clock nodes and set the main_clk to point to 
 that node.


 Since, this register is within the config space of PWMSS, the individual
 gating and reporting for the modules within PWMSS
 (PWMSS_CLKCONFIG) is currently being taken care by pwm-tipwmss.c(almost
 the sole function this driver is doing). It has been the same since
 am335x. Adding new clock nodes will result in driver changes and also
 changes to am335x, am437x (and other platforms) hwmod files. It also
 involves adding new nodes to clocks.dtsi and it will be difficult to
 maintain backward compatibility for older platforms. Is it not better to
 keep this as is, in order to maintain consistency (with am335x, am437x
 etc) and also that these clock bits are within IP's config space?

 ping...
 

I really want PWMSS support to go into v4.3... I see two options:

1. Drop pwm-tipwmss.c that is currently managing PWMSS Modules Local
Clock Gating and change am335x, am437x and dra7 to use new main_clk and
update clocks.dtsi (Breaks DT backward compatibility for am335x, am437x)
2. Or stick with $subject approach to maintain consistency.

I prefer second option, Shall I send a v3 fixing other comments

[RFC PATCH 5/5] ARM: dts: AM4372: Add memory map region entries for qspi

2015-07-28 Thread Vignesh R
Add qspi memory mapped region entries for AM43xx based SoCs.

Signed-off-by: Vignesh R vigne...@ti.com
---
 arch/arm/boot/dts/dra7.dtsi | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 8f1e25bcecbd..75a17c78b0ad 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1103,8 +1103,10 @@
 
qspi: qspi@4b30 {
compatible = ti,dra7xxx-qspi;
-   reg = 0x4b30 0x100;
-   reg-names = qspi_base;
+   reg = 0x4b30 0x100, 0x4a002558 0x4,
+ 0x5c00 0x3ff;
+   reg-names = qspi_base, qspi_ctrlmod,
+   qspi_mmap;
#address-cells = 1;
#size-cells = 0;
ti,hwmods = qspi;
-- 
2.4.6

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 3/5] mtd: devices: m25p80: set flag to request memory mapped read

2015-07-28 Thread Vignesh R
Set use_mmap_read flag to true, to indicate to spi-master that the
spi-message is from mtd layer. This helps spi-master to do memory
mapped reads over SPI flash memories, when hardware support is
available.

Signed-off-by: Vignesh R vigne...@ti.com
---
 drivers/mtd/devices/m25p80.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index d313f948b96c..aac2121c5454 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -148,6 +148,9 @@ static int m25p80_read(struct spi_nor *nor, loff_t from, 
size_t len,
t[1].len = len;
spi_message_add_tail(t[1], m);
 
+   m.spi = spi;
+   m.use_mmap_mode = true;
+
spi_sync(spi, m);
 
*retlen = m.actual_length - m25p_cmdsz(nor) - dummy;
-- 
2.4.6

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 0/5] Add memory mapped read support for TI QSPI.

2015-07-28 Thread Vignesh R

This patch series adds support for memory mapped reads for TI QSPI
driver.

TI QSPI controller has memory mapped port (SFI translator interface [1])
through which SPI flash memories can be read using memcpy call. SFI
translator takes care of generating appropriate SPI signals to read data
from flash. This interface works only with SPI flash memories and cannot
be used with other SPI devices. To use memory mapped port, the
controller is switched to memory mapped interface by writing to
QSPI_SPI_SWITCH_REG. The read_opcode, read mode, dummy bytes are set in
QSPI_SPI_SETUPx_REG. Once switched, the SPI flash is available to SoC to
read at specific address. This interface is disabled once memory mapped
read is complete. For write, erase and interaction with non-flash SPI
devices normal SPI interface is used. 

The m25p80 driver sets use_mmap_read flag in spi-message struct passed
to spi-ti-qspi so as to indicate the read request is from mtd layer.
spi-ti-qspi driver switches to memory mapped mode and does memcpy based
on use_mmap_read flag.

The read performace increased from ~100kB/s to ~2.5MB/s on DRA74 EVM.

Tested on DRA74 EVM with spansion S25FL256S flash.
Tested on AM437x sk evm with macronix MX66l51235l flash.

[1] http://www.ti.com/lit/ug/spruhz6/spruhz6.pdf Section 24.5.4 QSPI
Functional Description

Vignesh R (5):
  spi: introduce flag for memory mapped read
  spi: spi-ti-qspi: Add memory mapped read support
  mtd: devices: m25p80: set flag to request memory mapped read
  ARM: dts: DRA7: Add memory map region entries for qspi
  ARM: dts: AM4372: Add memory map region entries for qspi

 arch/arm/boot/dts/am4372.dtsi |   4 +-
 arch/arm/boot/dts/dra7.dtsi   |   6 +-
 drivers/mtd/devices/m25p80.c  |   3 +
 drivers/spi/spi-ti-qspi.c | 129 --
 include/linux/spi/spi.h   |   3 +
 5 files changed, 138 insertions(+), 7 deletions(-)

-- 
2.4.6

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 4/5] ARM: dts: DRA7: Add memory map region entries for qspi

2015-07-28 Thread Vignesh R
Add qspi memory mapped region entries for DRA7xx based SoCs.

Signed-off-by: Vignesh R vigne...@ti.com
---
 arch/arm/boot/dts/am4372.dtsi | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index ade28c790f4b..5317a0f24ab9 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -902,7 +902,9 @@
 
qspi: qspi@4790 {
compatible = ti,am4372-qspi;
-   reg = 0x4790 0x100;
+   reg = 0x4790 0x100,
+ 0x3000 0x3ff;
+   reg-names = qspi_base, qspi_mmap;
#address-cells = 1;
#size-cells = 0;
ti,hwmods = qspi;
-- 
2.4.6

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 2/5] spi: spi-ti-qspi: Add memory mapped read support

2015-07-28 Thread Vignesh R
TI QSPI controller has memory mapped port through which SPI flash
memories can be read using memcpy call. This patch adds support for
memory mapped read based on use_mmap_read flag.
When use_mmap_read flag is set, the controller is switched to memory
mapped interface by writing to QSPI_SPI_SWITCH_REG. The read_opcode,
read mode, dummy bytes are configured in QSPI_SPI_SETUPx_REG, then
memcpy is called to copy the requested data from flash to the rx_buf.
With this patch, the read speed increased from ~100kB/s to ~2.5MB/s on
DRA74 EVM.

Signed-off-by: Vignesh R vigne...@ti.com
---
 drivers/spi/spi-ti-qspi.c | 129 --
 1 file changed, 125 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index 5c0616870358..45844a227c5e 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -71,11 +71,8 @@ struct ti_qspi {
 #define QSPI_SPI_CMD_REG   (0x48)
 #define QSPI_SPI_STATUS_REG(0x4c)
 #define QSPI_SPI_DATA_REG  (0x50)
-#define QSPI_SPI_SETUP0_REG(0x54)
+#define QSPI_SPI_SETUP_REG(n)  (0x54 + 4 * n)
 #define QSPI_SPI_SWITCH_REG(0x64)
-#define QSPI_SPI_SETUP1_REG(0x58)
-#define QSPI_SPI_SETUP2_REG(0x5c)
-#define QSPI_SPI_SETUP3_REG(0x60)
 #define QSPI_SPI_DATA_REG_1(0x68)
 #define QSPI_SPI_DATA_REG_2(0x6c)
 #define QSPI_SPI_DATA_REG_3(0x70)
@@ -118,6 +115,16 @@ struct ti_qspi {
 
 #define QSPI_AUTOSUSPEND_TIMEOUT 2000
 
+#define MEM_CS_EN(n)   ((n + 1)  8)
+
+#define MM_SWITCH  0x1
+
+#define QSPI_SETUP_RD_NORMAL   (0x0  12)
+#define QSPI_SETUP_RD_DUAL (0x1  12)
+#define QSPI_SETUP_RD_QUAD (0x3  12)
+#define QSPI_SETUP_ADDR_SHIFT  8
+#define QSPI_SETUP_DUMMY_SHIFT 10
+
 static inline unsigned long ti_qspi_read(struct ti_qspi *qspi,
unsigned long reg)
 {
@@ -335,6 +342,117 @@ static int qspi_transfer_msg(struct ti_qspi *qspi, struct 
spi_transfer *t)
return 0;
 }
 
+static void ti_qspi_enable_memory_map(struct spi_device *spi)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi-master);
+   u32 val;
+
+   ti_qspi_write(qspi, MM_SWITCH, QSPI_SPI_SWITCH_REG);
+   if (qspi-ctrl_mod) {
+   val = readl(qspi-ctrl_base);
+   val |= MEM_CS_EN(spi-chip_select);
+   writel(val, qspi-ctrl_base);
+   }
+}
+
+static void ti_qspi_disable_memory_map(struct spi_device *spi)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi-master);
+   u32 val;
+
+   ti_qspi_write(qspi, 0, QSPI_SPI_SWITCH_REG);
+   if (qspi-ctrl_mod) {
+   val = readl(qspi-ctrl_base);
+   val = ~MEM_CS_EN(spi-chip_select);
+   writel(val, qspi-ctrl_base);
+   }
+}
+
+static void ti_qspi_setup_mmap_read(struct spi_device *spi, u8
+   read_opcode, u8 addr_width,
+   u8 dummy_bytes)
+{
+   struct ti_qspi  *qspi = spi_master_get_devdata(spi-master);
+   u32 mode = spi-mode  (SPI_RX_DUAL | SPI_RX_QUAD);
+   u32 memval = read_opcode;
+
+   switch (mode) {
+   case SPI_RX_QUAD:
+   memval |= QSPI_SETUP_RD_QUAD;
+   break;
+   case SPI_RX_DUAL:
+   memval |= QSPI_SETUP_RD_DUAL;
+   break;
+   default:
+   memval |= QSPI_SETUP_RD_NORMAL;
+   break;
+   }
+   memval |= ((addr_width - 1)  QSPI_SETUP_ADDR_SHIFT |
+  dummy_bytes  QSPI_SETUP_DUMMY_SHIFT);
+   ti_qspi_write(qspi, memval,
+ QSPI_SPI_SETUP_REG(spi-chip_select));
+}
+
+static unsigned int ti_qspi_cmd2addr(u8 *cmd, u8 addr_width)
+{
+   u32 addr;
+
+   /* cmd[0] is read opcode */
+   addr = cmd[1]  ((addr_width - 1) * 8);
+   addr |= cmd[2]  ((addr_width - 2) * 8);
+   addr |= cmd[3]  ((addr_width - 3) * 8);
+   addr |= cmd[4]  ((addr_width - 4) * 8);
+
+   return addr;
+}
+
+static int ti_qspi_mmap_read(struct spi_master *master,
+struct spi_message *m)
+{
+   struct ti_qspi *qspi = spi_master_get_devdata(master);
+   struct spi_device *spi = m-spi;
+   struct spi_transfer *t;
+   u8 read_opcode = 0x3;   /* Default normal read */
+   void *to = NULL;
+   u8 addr_width = 4, dummy_bytes = 0;
+   unsigned int len = 0, from = 0;
+   int status = 0;
+
+   mutex_lock(qspi-list_lock);
+
+   /* disable WC interrupt during memcpy */
+   ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG);
+   ti_qspi_enable_memory_map(spi);
+   list_for_each_entry(t, m-transfers, transfer_list) {
+   if (t-tx_buf) {
+   read_opcode = *((u8 *)t-tx_buf);
+   dummy_bytes = t-len

[RFC PATCH 1/5] spi: introduce flag for memory mapped read

2015-07-28 Thread Vignesh R
TI QSPI controller has SFI translator which exposes entire flash memory
as memory mapped region for read. With this interface, the CPU
can copy data from flash using normal memcpy call. SFI translator
takes care of generating appropriate SPI signals to read data from
flash. This interface works only with SPI flash memories and cannot be
used with other SPI devices.
Introduce use_mmap_read field in spi_message struct. This can be set by
mtd devices (m25p80) to indicate to spi-master (ti-qspi) to perform
memory mapped read. This helps to distinguish whether the spi-message is
from mtd layer(hence mmap read is possible) or by other spi devices.

Signed-off-by: Vignesh R vigne...@ti.com
---
 include/linux/spi/spi.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index d673072346f2..f1a0329ee63f 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -640,6 +640,8 @@ struct spi_transfer {
  * @actual_length: the total number of bytes that were transferred in all
  * successful segments
  * @status: zero for success, else negative errno
+ * @use_mmap_mode: Indicate to spi master to perform memory mapped
+ * read if possible.
  * @queue: for use by whichever driver currently owns the message
  * @state: for use by whichever driver currently owns the message
  *
@@ -681,6 +683,7 @@ struct spi_message {
unsignedframe_length;
unsignedactual_length;
int status;
+   booluse_mmap_mode;
 
/* for optional use by whatever driver currently owns the
 * spi_message ...  between calls to spi_async and then later
-- 
2.4.6

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 1/2] input: touchscreen: pixcir_i2c_ts: Add support for optional wakeup interrupt

2015-07-27 Thread Vignesh R


On 07/27/2015 04:19 PM, Roger Quadros wrote:
 Hi,
 
 On 23/07/15 17:54, Vignesh R wrote:
 On am437x-gp-evm, pixcir touchscreen can wake the system from low power
 state by generating wake-up interrupt via pinctrl and IO daisy chain.
 Add support for optional wakeup interrupt source by regsitering to
 automated wake IRQ framework introduced by commit 4990d4fe327b (PM /
 Wakeirq: Add automated device wake IRQ handling).
 This is similar in approach to commit 2a0b965cfb6e (serial: omap: Add
 support for optional wake-up)

 Signed-off-by: Vignesh R vigne...@ti.com
 ---

 v3:
  * handle error code returned by of_irq_get_byname()

 v2:
  * use of_irq_get_byname()
  * remove enable/disable_wake_irq()

  drivers/input/touchscreen/pixcir_i2c_ts.c | 22 ++
  include/linux/input/pixcir_ts.h   |  1 +
  2 files changed, 19 insertions(+), 4 deletions(-)

 diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c 
 b/drivers/input/touchscreen/pixcir_i2c_ts.c
 index 8f3e243a62bf..3a4ab358bf52 100644
 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c
 +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
 @@ -29,6 +29,8 @@
  #include linux/of.h
  #include linux/of_gpio.h
  #include linux/of_device.h
 +#include linux/of_irq.h
 +#include linux/pm_wakeirq.h
  
  #define PIXCIR_MAX_SLOTS   5 /* Max fingers supported by driver */
  
 @@ -364,8 +366,6 @@ static int __maybe_unused pixcir_i2c_ts_suspend(struct 
 device *dev)
  goto unlock;
  }
  }
 -
 -enable_irq_wake(client-irq);
  } else if (input-users) {
  ret = pixcir_stop(ts);
  }
 @@ -386,8 +386,6 @@ static int __maybe_unused pixcir_i2c_ts_resume(struct 
 device *dev)
  mutex_lock(input-mutex);
  
  if (device_may_wakeup(client-dev)) {
 -disable_irq_wake(client-irq);
 -
  if (!input-users) {
  ret = pixcir_stop(ts);
  if (ret) {
 @@ -445,6 +443,13 @@ static struct pixcir_ts_platform_data 
 *pixcir_parse_dt(struct device *dev)
  dev_dbg(dev, %s: x %d, y %d, gpio %d\n, __func__,
  pdata-x_max + 1, pdata-y_max + 1, pdata-gpio_attb);
  
 +pdata-wakeirq = of_irq_get_byname(dev-of_node, wakeup);
 +if (pdata-wakeirq  0  pdata-wakeirq != -ENODATA 
 +pdata-wakeirq != -EINVAL) {
 +dev_err(dev, Failed to get wakeirq\n);
 +return ERR_PTR(pdata-wakeirq);
 +}
 +
  return pdata;
  }
  #else
 @@ -564,11 +569,20 @@ static int pixcir_i2c_ts_probe(struct i2c_client 
 *client,
  i2c_set_clientdata(client, tsdata);
  device_init_wakeup(client-dev, 1);
  
 +/* Register wakeirq */
 +error = (pdata-wakeirq  0) ?
 +dev_pm_set_dedicated_wake_irq(dev, pdata-wakeirq) :
 +dev_pm_set_wake_irq(dev, client-irq);
 
 Can 0 be a valid wakeirq or client-irq?
 If yes then this logic is broken.
 

AFAIK, IRQ 0 is always assigned to system timer interrupt (cannot find
reliable source to quote).

 I would set wakeirq to -EINVAL or something if it is not available
 during probe and check for that condition.
 

Not sure, if I understand you correctly
pdata-wakeirq will have -ENODATA or -EINVAL(as returned by
of_irq_get_byname()), if wakeirq is not available. Do you want me to
check for these two conditions specifically rather than
(pdata-wakeirq  0) ?

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 1/2] input: touchscreen: pixcir_i2c_ts: Add support for optional wakeup interrupt

2015-07-23 Thread Vignesh R
On am437x-gp-evm, pixcir touchscreen can wake the system from low power
state by generating wake-up interrupt via pinctrl and IO daisy chain.
Add support for optional wakeup interrupt source by regsitering to
automated wake IRQ framework introduced by commit 4990d4fe327b (PM /
Wakeirq: Add automated device wake IRQ handling).
This is similar in approach to commit 2a0b965cfb6e (serial: omap: Add
support for optional wake-up)

Signed-off-by: Vignesh R vigne...@ti.com
---

v3:
 * handle error code returned by of_irq_get_byname()

v2:
 * use of_irq_get_byname()
 * remove enable/disable_wake_irq()

 drivers/input/touchscreen/pixcir_i2c_ts.c | 22 ++
 include/linux/input/pixcir_ts.h   |  1 +
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c 
b/drivers/input/touchscreen/pixcir_i2c_ts.c
index 8f3e243a62bf..3a4ab358bf52 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -29,6 +29,8 @@
 #include linux/of.h
 #include linux/of_gpio.h
 #include linux/of_device.h
+#include linux/of_irq.h
+#include linux/pm_wakeirq.h
 
 #define PIXCIR_MAX_SLOTS   5 /* Max fingers supported by driver */
 
@@ -364,8 +366,6 @@ static int __maybe_unused pixcir_i2c_ts_suspend(struct 
device *dev)
goto unlock;
}
}
-
-   enable_irq_wake(client-irq);
} else if (input-users) {
ret = pixcir_stop(ts);
}
@@ -386,8 +386,6 @@ static int __maybe_unused pixcir_i2c_ts_resume(struct 
device *dev)
mutex_lock(input-mutex);
 
if (device_may_wakeup(client-dev)) {
-   disable_irq_wake(client-irq);
-
if (!input-users) {
ret = pixcir_stop(ts);
if (ret) {
@@ -445,6 +443,13 @@ static struct pixcir_ts_platform_data 
*pixcir_parse_dt(struct device *dev)
dev_dbg(dev, %s: x %d, y %d, gpio %d\n, __func__,
pdata-x_max + 1, pdata-y_max + 1, pdata-gpio_attb);
 
+   pdata-wakeirq = of_irq_get_byname(dev-of_node, wakeup);
+   if (pdata-wakeirq  0  pdata-wakeirq != -ENODATA 
+   pdata-wakeirq != -EINVAL) {
+   dev_err(dev, Failed to get wakeirq\n);
+   return ERR_PTR(pdata-wakeirq);
+   }
+
return pdata;
 }
 #else
@@ -564,11 +569,20 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
i2c_set_clientdata(client, tsdata);
device_init_wakeup(client-dev, 1);
 
+   /* Register wakeirq */
+   error = (pdata-wakeirq  0) ?
+   dev_pm_set_dedicated_wake_irq(dev, pdata-wakeirq) :
+   dev_pm_set_wake_irq(dev, client-irq);
+   if (error)
+   dev_info(dev, unable to setup wakeirq %d\n,
+error);
+
return 0;
 }
 
 static int pixcir_i2c_ts_remove(struct i2c_client *client)
 {
+   dev_pm_clear_wake_irq(client-dev);
device_init_wakeup(client-dev, 0);
 
return 0;
diff --git a/include/linux/input/pixcir_ts.h b/include/linux/input/pixcir_ts.h
index 7bae83b7c396..da573de5a5ee 100644
--- a/include/linux/input/pixcir_ts.h
+++ b/include/linux/input/pixcir_ts.h
@@ -58,6 +58,7 @@ struct pixcir_ts_platform_data {
int x_max;
int y_max;
int gpio_attb;  /* GPIO connected to ATTB line */
+   int wakeirq;
struct pixcir_i2c_chip_data chip;
 };
 
-- 
2.4.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 2/2] ARM: dts: am437x-gp-evm: Add wakeup interrupt source for pixcir_i2c_tsc

2015-07-23 Thread Vignesh R
Pixcir_i2c_tsc driver can now wakeup the system from lower power state
via pinctrl and IO daisy chain using generic wakeirq framwework. Add
optional wakeup irq entry to allow pixcir_i2c_tsc to wake system from
low power state.

Signed-off-by: Vignesh R vigne...@ti.com
---

v3:
 * Drop irq suffix from interrupt-names.

v2:
 * Add interrupt-names property.

 arch/arm/boot/dts/am437x-gp-evm.dts | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts 
b/arch/arm/boot/dts/am437x-gp-evm.dts
index 84aa30c3235a..99209a137c63 100644
--- a/arch/arm/boot/dts/am437x-gp-evm.dts
+++ b/arch/arm/boot/dts/am437x-gp-evm.dts
@@ -503,6 +503,10 @@
 
attb-gpio = gpio3 22 GPIO_ACTIVE_HIGH;
 
+   interrupts-extended = gpio3 22 GPIO_ACTIVE_HIGH,
+ am43xx_pinmux 0x264;
+   interrupt-names = tsc, wakeup;
+
touchscreen-size-x = 1024;
touchscreen-size-y = 600;
};
-- 
2.4.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 0/2] pixcir_i2c_ts: Add optional wakeup irq support

2015-07-23 Thread Vignesh R


This is the v3 of the patch series to add optional wake irq support for
pixcir_i2c_tsc.

Tested on am437x-gp-evm, with some out of tree patches to support
suspend/resume on am437x.


Vignesh R (2):
  input: touchscreen: pixcir_i2c_ts: Add support for optional wakeup
interrupt
  ARM: dts: am437x-gp-evm: Add wakeup interrupt source for
pixcir_i2c_tsc

 arch/arm/boot/dts/am437x-gp-evm.dts   |  4 
 drivers/input/touchscreen/pixcir_i2c_ts.c | 22 ++
 include/linux/input/pixcir_ts.h   |  1 +
 3 files changed, 23 insertions(+), 4 deletions(-)

-- 
2.4.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] mmc: host: omap_hsmmc: Add custom card detect irq handler

2015-07-22 Thread Vignesh R
Hi Andreas,

On 07/21/2015 01:46 PM, Andreas Fenkart wrote:
 Hi Vignesh,
 
 Generally I don't like this patch, it will make it harder, not easier,
 to maintain the omap hsmmc driver. Also given that the bug occurs
 rarely, people will be reluctant to clean it up later or accept
 patches.
 
 see also comments below
 
[snip]
 2015-06-22 15:18 GMT+02:00 Vignesh R vigne...@ti.com:

 
 But calls to omap_hsmmc_card_init or omap_hsmmc_get_cd are in the same
 mmc_rescan thread. Hence, moving the recovery code to init_card does not
 help.
 
 what about clearing any pending transfer in
 - mmc_gpio_cd_irqt, or
 - mmc_detect_change
 
 e.g. trigger the later mentioned .card_event callback from those
 functions, instead mmc_rescan? Then you can install your
 omap_hsmmc_request_clear as the card_event callback. This makes your
 custom isr handler redundant, actually your isr handler became
 standard.
 

I looked  at the commit fa372a51cb5f93800f711473e5a36e0e0c9a8f00 which
moved .card_event out of mmc_gpio_cd_irqt. It points to two threads
where discussion to move .card_event to mmc_rescan happened[1][2]. The
concern there was this callback was being called from atomic context
but, I don't understand how threaded irq is atomic context. (I am not
sure, if this is because those drivers have irqs disabled till threaded
irq is complete) But, I believe moving card_event callback back to
mmc_gpio_cd_irqt may break some drivers.
I will look into this further.
Do you have any insight on this commit? Thanks!

[1]https://lkml.org/lkml/2014/3/19/79
[2]https://lkml.org/lkml/2013/8/19/539

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/2] input: touchscreen: pixcir_i2c_ts: Add support for optional wakeup interrupt

2015-07-21 Thread Vignesh R
Hi Dmitry,

On 07/20/2015 11:54 AM, Dmitry Torokhov wrote:
 On Sun, Jul 19, 2015 at 11:09:30PM -0700, Tony Lindgren wrote:
 * Vignesh R vigne...@ti.com [150719 21:53]:
 @@ -445,6 +443,8 @@ static struct pixcir_ts_platform_data 
 *pixcir_parse_dt(struct device *dev)
 dev_dbg(dev, %s: x %d, y %d, gpio %d\n, __func__,
 pdata-x_max + 1, pdata-y_max + 1, pdata-gpio_attb);
  
 +   pdata-wakeirq = of_irq_get_byname(dev-of_node, wakeupirq);
 +
 return pdata;

 What about handling -EPROVE_DEFER here? At least pinctrl-single can be
 be a loadable module for the dedicated wakeirqs.
 
 Right. I think we should only allow -ENODATA to continue and return
 error in all other cases.

-EINVAL will be returned if interrupt-names is not specified. I will
make execption for -ENODATA  -EINVAL, and return error in all other cases?

 
 Also, I think irq suffix on name is redundant.

Ok, will drop irq suffix:

+   interrupt-names = tsc, wakeup;

 
 Thanks.
 

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/2] input: touchscreen: pixcir_i2c_ts: Add support for optional wakeup interrupt

2015-07-19 Thread Vignesh R
On am437x-gp-evm, pixcir touchscreen can wake the system from low power
state by generating wake-up interrupt via pinctrl and IO daisy chain.
Add support for optional wakeup interrupt source by regsitering to
automated wake IRQ framework introduced by commit 4990d4fe327b (PM /
Wakeirq: Add automated device wake IRQ handling).
This is similar in approach to commit 2a0b965cfb6e (serial: omap: Add
support for optional wake-up)

Signed-off-by: Vignesh R vigne...@ti.com
---
v2:
 * use of_irq_get_byname()
 * remove enable/disable_wake_irq()

 drivers/input/touchscreen/pixcir_i2c_ts.c | 17 +
 include/linux/input/pixcir_ts.h   |  1 +
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c 
b/drivers/input/touchscreen/pixcir_i2c_ts.c
index 8f3e243a62bf..b9cebf274678 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -29,6 +29,8 @@
 #include linux/of.h
 #include linux/of_gpio.h
 #include linux/of_device.h
+#include linux/of_irq.h
+#include linux/pm_wakeirq.h
 
 #define PIXCIR_MAX_SLOTS   5 /* Max fingers supported by driver */
 
@@ -364,8 +366,6 @@ static int __maybe_unused pixcir_i2c_ts_suspend(struct 
device *dev)
goto unlock;
}
}
-
-   enable_irq_wake(client-irq);
} else if (input-users) {
ret = pixcir_stop(ts);
}
@@ -386,8 +386,6 @@ static int __maybe_unused pixcir_i2c_ts_resume(struct 
device *dev)
mutex_lock(input-mutex);
 
if (device_may_wakeup(client-dev)) {
-   disable_irq_wake(client-irq);
-
if (!input-users) {
ret = pixcir_stop(ts);
if (ret) {
@@ -445,6 +443,8 @@ static struct pixcir_ts_platform_data 
*pixcir_parse_dt(struct device *dev)
dev_dbg(dev, %s: x %d, y %d, gpio %d\n, __func__,
pdata-x_max + 1, pdata-y_max + 1, pdata-gpio_attb);
 
+   pdata-wakeirq = of_irq_get_byname(dev-of_node, wakeupirq);
+
return pdata;
 }
 #else
@@ -564,11 +564,20 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
i2c_set_clientdata(client, tsdata);
device_init_wakeup(client-dev, 1);
 
+   /* Register wakeirq */
+   error = pdata-wakeirq ?
+   dev_pm_set_dedicated_wake_irq(dev, pdata-wakeirq) :
+   dev_pm_set_wake_irq(dev, client-irq);
+   if (error)
+   dev_info(dev, unable to get wakeirq %d\n,
+error);
+
return 0;
 }
 
 static int pixcir_i2c_ts_remove(struct i2c_client *client)
 {
+   dev_pm_clear_wake_irq(client-dev);
device_init_wakeup(client-dev, 0);
 
return 0;
diff --git a/include/linux/input/pixcir_ts.h b/include/linux/input/pixcir_ts.h
index 7bae83b7c396..da573de5a5ee 100644
--- a/include/linux/input/pixcir_ts.h
+++ b/include/linux/input/pixcir_ts.h
@@ -58,6 +58,7 @@ struct pixcir_ts_platform_data {
int x_max;
int y_max;
int gpio_attb;  /* GPIO connected to ATTB line */
+   int wakeirq;
struct pixcir_i2c_chip_data chip;
 };
 
-- 
2.4.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/2] ARM: dts: AM437x-gp-evm: Add wakeup interrupt source for pixcir_i2c_tsc

2015-07-19 Thread Vignesh R
Pixcir_i2c_tsc driver can now wakeup the system from lower power state
via pinctrl and IO daisy chain using generic wakeirq framwework. Add
optional wakeup irq entry to allow pixcir_i2c_tsc to wake system from
low power state.

Signed-off-by: Vignesh R vigne...@ti.com
---

v2: 
 * Add interrupt-names property

 arch/arm/boot/dts/am437x-gp-evm.dts | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts 
b/arch/arm/boot/dts/am437x-gp-evm.dts
index 84aa30c3235a..2184ac5426cd 100644
--- a/arch/arm/boot/dts/am437x-gp-evm.dts
+++ b/arch/arm/boot/dts/am437x-gp-evm.dts
@@ -503,6 +503,10 @@
 
attb-gpio = gpio3 22 GPIO_ACTIVE_HIGH;
 
+   interrupts-extended = gpio3 22 GPIO_ACTIVE_HIGH,
+ am43xx_pinmux 0x264;
+   interrupt-names = tscirq, wakeupirq;
+
touchscreen-size-x = 1024;
touchscreen-size-y = 600;
};
-- 
2.4.5
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/2] pixcir_i2c_ts: Add optional wakeup irq support

2015-07-19 Thread Vignesh R

On am437x-gp-evm, pixcir_i2c_tsc can wake-up system from low power
state via pinctrl and IO daisy chain mechanism. This patch series add
support for such optional wake up interrupt to be handled via recently
introduced generic wake irq handling framework.

Tested on am437x-gp-evm, with some out of tree patches to support
suspend/resume on am437x.


Vignesh R (2):
  input: touchscreen: pixcir_i2c_ts: Add support for optional wakeup
interrupt
  ARM: dts: AM437x-gp-evm: Add wakeup interrupt source for
pixcir_i2c_tsc

 arch/arm/boot/dts/am437x-gp-evm.dts   |  4 
 drivers/input/touchscreen/pixcir_i2c_ts.c | 17 +
 include/linux/input/pixcir_ts.h   |  1 +
 3 files changed, 18 insertions(+), 4 deletions(-)

-- 
2.4.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] input: touchscreen: pixcir_i2c_ts: Add support for optional wakeup interrupt

2015-07-19 Thread Vignesh R
Hi Dmitry,

On 7/18/2015 3:21 AM, Dmitry Torokhov wrote:
 Hi Vignesh,
 
 On Fri, Jul 17, 2015 at 12:10:40PM +0530, Vignesh R wrote:
 On am437x-gp-evm, pixcir touchscreen can wake the system from low power
 state by generating wake-up interrupt via pinctrl and IO daisy chain.
 Add support for optional wakeup interrupt source by regsitering to
 automated wake IRQ framework introduced by commit 4990d4fe327b (PM /
 Wakeirq: Add automated device wake IRQ handling).
 This is similar in approach to commit 2a0b965cfb6e (serial: omap: Add
 support for optional wake-up)

 Signed-off-by: Vignesh R vigne...@ti.com
 ---
  drivers/input/touchscreen/pixcir_i2c_ts.c | 14 ++
  1 file changed, 14 insertions(+)

 diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c 
 b/drivers/input/touchscreen/pixcir_i2c_ts.c
 index 8f3e243a62bf..f7c602027fbd 100644
 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c
 +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
 @@ -29,6 +29,8 @@
  #include linux/of.h
  #include linux/of_gpio.h
  #include linux/of_device.h
 +#include linux/of_irq.h
 +#include linux/pm_wakeirq.h
  
  #define PIXCIR_MAX_SLOTS   5 /* Max fingers supported by driver */
  
 @@ -38,6 +40,7 @@ struct pixcir_i2c_ts_data {
  const struct pixcir_ts_platform_data *pdata;
  bool running;
  int max_fingers;/* Max fingers supported in this instance */
 +int wakeirq;
  };
  
  struct pixcir_touch {
 @@ -564,11 +567,22 @@ static int pixcir_i2c_ts_probe(struct i2c_client 
 *client,
  i2c_set_clientdata(client, tsdata);
  device_init_wakeup(client-dev, 1);
  
 +/* Register wakeirq, if available */
 +tsdata-wakeirq = of_irq_get(dev-of_node, 1);
 
 Can we put this in platform data and parse in pixcir_parse_dt() please?
 Also, why not of_irq_get_byname()?


Ok.

 +if (tsdata-wakeirq) {
 +error = dev_pm_set_dedicated_wake_irq(dev,
 +  tsdata-wakeirq);
 +if (error)
 +dev_dbg(dev, unable to get wakeirq %d\n,
 +error);
 +}
 
 Shouldn't his actually be:
 
   error = tsdata-wakeirq ?
   dev_pm_set_dedicated_wake_irq(dev, tsdata-wakeirq) :
   dev_pm_set_wake_irq(dev, client-irq);
   if (error) {
   ...
   }
 
 and then we can get rid of enable_irq_wake()/disable_irq_wake() in
 pixcir_i2c_ts_suspend() and pixcir_i2c_ts_resume().
 

Yes, I will do this in v2.

 +
  return 0;
  }
  
  static int pixcir_i2c_ts_remove(struct i2c_client *client)
  {
 +dev_pm_clear_wake_irq(client-dev);
  device_init_wakeup(client-dev, 0);
 
 I wonder if driver core should be responsible for clearing wake irq and
 also for clearing wakeup flag.
 

AFAICU, wakeup flag is deleted when struct device is deleted, hence,
device_init_wakeup() call may not be required in .remove(). But,
dev_pm_clear_wake_irq() can be moved to driver core.

Regards
Vignesh
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] input: touchscreen: pixcir_i2c_ts: Add support for optional wakeup interrupt

2015-07-17 Thread Vignesh R
On am437x-gp-evm, pixcir touchscreen can wake the system from low power
state by generating wake-up interrupt via pinctrl and IO daisy chain.
Add support for optional wakeup interrupt source by regsitering to
automated wake IRQ framework introduced by commit 4990d4fe327b (PM /
Wakeirq: Add automated device wake IRQ handling).
This is similar in approach to commit 2a0b965cfb6e (serial: omap: Add
support for optional wake-up)

Signed-off-by: Vignesh R vigne...@ti.com
---
 drivers/input/touchscreen/pixcir_i2c_ts.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c 
b/drivers/input/touchscreen/pixcir_i2c_ts.c
index 8f3e243a62bf..f7c602027fbd 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -29,6 +29,8 @@
 #include linux/of.h
 #include linux/of_gpio.h
 #include linux/of_device.h
+#include linux/of_irq.h
+#include linux/pm_wakeirq.h
 
 #define PIXCIR_MAX_SLOTS   5 /* Max fingers supported by driver */
 
@@ -38,6 +40,7 @@ struct pixcir_i2c_ts_data {
const struct pixcir_ts_platform_data *pdata;
bool running;
int max_fingers;/* Max fingers supported in this instance */
+   int wakeirq;
 };
 
 struct pixcir_touch {
@@ -564,11 +567,22 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
i2c_set_clientdata(client, tsdata);
device_init_wakeup(client-dev, 1);
 
+   /* Register wakeirq, if available */
+   tsdata-wakeirq = of_irq_get(dev-of_node, 1);
+   if (tsdata-wakeirq) {
+   error = dev_pm_set_dedicated_wake_irq(dev,
+ tsdata-wakeirq);
+   if (error)
+   dev_dbg(dev, unable to get wakeirq %d\n,
+   error);
+   }
+
return 0;
 }
 
 static int pixcir_i2c_ts_remove(struct i2c_client *client)
 {
+   dev_pm_clear_wake_irq(client-dev);
device_init_wakeup(client-dev, 0);
 
return 0;
-- 
2.4.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/2] pixcir_i2c_ts: Add optional wakeup irq support

2015-07-17 Thread Vignesh R

On am437x-gp-evm, pixcir_i2c_tsc can wake-up system from low power
state via pinctrl and IO daisy chain mechanism. This patch series add
support for such optional wake up interrupt to be handled via recently
introduced generic wake irq handling framework.

Tested on am437x-gp-evm, with some out of tree patches to support
suspend/resume on am437x.


Vignesh R (2):
  input: touchscreen: pixcir_i2c_ts: Add support for optional wakeup
interrupt
  ARM: dts: AM437x-gp-evm: Add wakeup interrupt source for
pixcir_i2c_tsc

 arch/arm/boot/dts/am437x-gp-evm.dts   |  3 +++
 drivers/input/touchscreen/pixcir_i2c_ts.c | 14 ++
 2 files changed, 17 insertions(+)

-- 
2.4.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] ARM: dts: am437x-gp-evm: Add wakeup interrupt source for pixcir_i2c_tsc

2015-07-17 Thread Vignesh R
Pixcir_i2c_tsc driver can now wakeup the system from lower power state
via pinctrl and IO daisy chain using generic wakeirq framwework. Add
optional wakeup irq entry to allow pixcir_i2c_tsc to wake system from
low power state.

Signed-off-by: Vignesh R vigne...@ti.com
---
 arch/arm/boot/dts/am437x-gp-evm.dts | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts 
b/arch/arm/boot/dts/am437x-gp-evm.dts
index 84aa30c3235a..04f7667c604e 100644
--- a/arch/arm/boot/dts/am437x-gp-evm.dts
+++ b/arch/arm/boot/dts/am437x-gp-evm.dts
@@ -503,6 +503,9 @@
 
attb-gpio = gpio3 22 GPIO_ACTIVE_HIGH;
 
+   interrupts-extended = gpio3 22 GPIO_ACTIVE_HIGH,
+ am43xx_pinmux 0x264;
+
touchscreen-size-x = 1024;
touchscreen-size-y = 600;
};
-- 
2.4.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH] i2c: busses: i2c-omap: Increase timeout for i2c interrupt

2015-07-10 Thread Vignesh R
Hi,

On 07/10/2015 06:56 PM, Alexander Sverdlin wrote:
 Hi!
 
 On 10/07/15 15:17, ext Vignesh R wrote:
 I would propose you to throw away spinlocks. Convert threaded IRQ to
 just one hardirq handler. And continue debugging. You will reduce the
 load of the system with the above measures, maybe it will not happen
 any more, maybe you'll figure out that problem is somewhere else.

 Or this.
 I am not convinced with moving entire code at hardirq context. I believe
 its better to keep hardirq as small as possible.
 
 How deep is the controller's FIFO? 1 byte? 2 bytes? 

As per AM57x TRM[1] section 24.1.4.8 max FIFO depth can be 64bytes.

[1] http://www.ti.com/lit/ug/spruhz6/spruhz6.pdf
-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH] i2c: busses: i2c-omap: Increase timeout for i2c interrupt

2015-07-10 Thread Vignesh R


On 07/10/2015 02:39 PM, Wolfram Sang wrote:
 
 60 s sounds way too much and actually I simply don't believe this is
 the root cause. If I take a look into the driver, then I see, that
 
 I agree, this is just a workaround.
 

Yes, this is a workaround. I thought this is simpler change and can go
into -rc while I work on the better fix. As you can see, the other
suggestions need quite a significant change to the isr code.

 the design is not really the best. The whole IRQ handling could be
 actually performed in hard IRQ handler, without threading overhead.
 Putting even 2 bytes in the controller FIFO should not be too heavy
 for the hard IRQ handler. Then these ridiculous spin_lock()s. What
 is the reason behind? The IRQ is flagged with ONESHOT, so thread and
 hardirq handler are anyway mutually excluded. But if this thread
 ever runs longer than it's allowed in IRQ context, then it anyway
 produces this IRQ latency because it locks spin_lock_irqsave() for
 the whole time! So the whole point of threaded interrupt is missing.
 
 Furthermore, this combination of threaded_irq and struct completion seems
 bogus to me. If you just want to ensure the irq happened before timeout,
 you just complete when the irq happened and do the bottom half after the
 completion returned?

This sounds good to me. I will try to implement this option.
Thanks for the suggestion.

 
 I would propose you to throw away spinlocks. Convert threaded IRQ to
 just one hardirq handler. And continue debugging. You will reduce the
 load of the system with the above measures, maybe it will not happen
 any more, maybe you'll figure out that problem is somewhere else.
 
 Or this.

I am not convinced with moving entire code at hardirq context. I believe
its better to keep hardirq as small as possible.

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH] i2c: busses: i2c-omap: Increase timeout for i2c interrupt

2015-07-09 Thread Vignesh R
When system is under load and there is an i2c transaction running
following warning appears on the console:

[  730.003617] omap_i2c 4807.i2c: controller timed out
[  731.023643] omap_i2c 4807.i2c: controller timed out

This is because, the completion() call, which is done in bottom half of
the interrupt handler, happens after the timeout period(1s) has elapsed
for the wait_for_completion_timeout() in omap_i2c_xfer_msg(). The
interrupt is raised within a second but due to system load (or other
interrupts), the bottom half does not get scheduled within a second.
Hence even though the interrupt has happened within required time frame,
due to delayed scheduling of bottom half, spurious timeout errors are
reported on the console and i2c controller is reset.

i2c timeout is a rare condition, hence increase timeout to 60s in order
to avoid reporting false timeout events under load.

Signed-off-by: Vignesh R vigne...@ti.com
---

I reproduced this while running i2cdump in a loop and reading from flash
using dd command.

 drivers/i2c/busses/i2c-omap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index d1c22e3fdd14..fa7758f0302c 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -50,7 +50,7 @@
 #define OMAP_I2C_REV_ON_4430_PLUS  0x5042
 
 /* timeout waiting for the controller to respond */
-#define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
+#define OMAP_I2C_TIMEOUT (msecs_to_jiffies(60 * 1000))
 
 /* timeout for pm runtime autosuspend */
 #define OMAP_I2C_PM_TIMEOUT1000/* ms */
-- 
2.4.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/3] omap_hsmmc: Fix card enumeration failure on

2015-07-06 Thread Vignesh R


On Tuesday 16 June 2015 04:07 PM, Vignesh R wrote:
 
 Hi,
 
 When using omap_hsmmc driver, if sd-card repeatedly plug unplugged
 multiple times quickly, card enumeration stops after few iterations.
 This can be easily reproduced on DRA74X EVM which uses omap_hsmmc driver.
 This patch series addresses the above problem. The first patch fixes irq
 handler to report all DTOs to mmc-core. Second patch adds handling for
 BADA, DEB and CEB interrupts. The last patch introduces driver specific
 card detect irq handler to cleanup pending requests before card removal.
 
 Tested on DRA74X amd DRA72X and AM437X-GP EVMs, by repeated intense
 plug/unplug iterations.

Gentle ping...

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 0/5] Add support for PWMSS on DRA7

2015-07-06 Thread Vignesh R


On Wednesday 03 June 2015 05:21 PM, Vignesh R wrote:
 
 Hi,
 
 This patch series adds support for PWMSS on DRA7. The IP is same as that
 present in AM33XX and AM43XX.
 The first patch changes clock domain in which PWMSS is present
 (l4per2_7xx_clkdm) to SW_WKUP. This is because legacy IPs like PWM
 does'nt support HW_AUTO prorperly. Hence, switch clock domain to
 SW_WKUP. This is based on the input from the hardware team.
 The rest of the patches add hwmod and dt entries and enable PWMSS on
 DRA7 based SoCs.

Gentle ping...


-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] mmc: host: omap_hsmmc: Add custom card detect irq handler

2015-06-22 Thread Vignesh R
Hi Andreas,


Thanks for testing out these patches.

On Sunday 21 June 2015 04:15 AM, Andreas Fenkart wrote:
 I haven't managed to produce a hang without this patch

Reproducing this hang is not straight forward. It takes 40-50 card
insertion/removal to see this case (sometimes even 100 tries).

 
 see also comments below
 
 2015-06-16 12:37 GMT+02:00 Vignesh R vigne...@ti.com:
 Usually when there is an error in transfer, DTO/CTO or other error
 interrupts are raised. But if the card is unplugged in the middle of a
 data transfer, it is observed that, neither completion(success) or
 timeout(error) interrupts are raised. Hence, the mmc-core is waiting
 for-ever for the transfer to complete. This results failure to recognise
 sd card on the next insertion.
 The only way to solve this is to introduce code to detect this condition
 and recover on card insertion (in hsmmc specific cd_irq). Hence,
 introduce cd_irq and add code to clear mmc_request that is pending from
 the failed transaction.

 Signed-off-by: Vignesh R vigne...@ti.com
 ---
  drivers/mmc/host/omap_hsmmc.c | 73 ++-
  1 file changed, 72 insertions(+), 1 deletion(-)

 diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
 index fb4bfefd9250..ec1fff3c0c9c 100644
 --- a/drivers/mmc/host/omap_hsmmc.c
 +++ b/drivers/mmc/host/omap_hsmmc.c
 @@ -221,6 +221,12 @@ struct omap_hsmmc_host {
  #define HSMMC_WAKE_IRQ_ENABLED (1  2)
 struct omap_hsmmc_next  next_data;
 struct  omap_hsmmc_platform_data*pdata;
 +   /*
 +* flag to determine whether card was removed during data
 +* transfer
 +*/
 +   booltransfer_incomplete;
 +

 /* return MMC cover switch state, can be NULL if not supported.
  *
 @@ -867,6 +873,26 @@ static void omap_hsmmc_request_done(struct 
 omap_hsmmc_host *host, struct mmc_req
  }

  /*
 + * Cleanup incomplete card removal sequence. This will make sure the
 + * next card enumeration is clean.
 + */
 +static void omap_hsmmc_request_clear(struct omap_hsmmc_host *host,
 +struct mmc_request *mrq)
 +{
 +   unsigned long flags;
 +
 +   spin_lock_irqsave(host-irq_lock, flags);
 +   host-req_in_progress = 0;
 +   host-dma_ch = -1;
 +   spin_unlock_irqrestore(host-irq_lock, flags);
 +
 +   mmc_request_done(host-mmc, mrq);
 +   if (host-mmc-card)
 +   mmc_card_set_removed(host-mmc-card);
 +   host-mrq = NULL;
 +}
 +
 +/*
   * Notify the transfer complete to MMC core
   */
  static void
 @@ -1248,6 +1274,47 @@ static irqreturn_t omap_hsmmc_cover_irq(int irq, void 
 *dev_id)
 return IRQ_HANDLED;
  }

 +/*
 + * irq handler to notify the core about card insertion/removal
 + */
 +static irqreturn_t omap_hsmmc_cd_irq(int irq, void *dev_id)
 +{
 
 Move this code to 'omap_hsmmc_get_cd' function. Or rather clear
 any pending transfer upon '.init_card/omap_hsmmc_init_card'

I tried using omap_hsmmc_init initially, but here is the problem:

card inserted -- cd_irq_isr-- schedule mmc_rescan()
--- after some time ---
mmc_rescan() --
mmc_sd_alive() --
-- card removed ---
mmc_send_status --
mmc_wait_for_req()--
wait_for_completion()
^^^ Here the mmc_rescan thread waits forever because, it doesn't get
timeout interrupt for the cmd/req it sent (because card was removed).

But calls to omap_hsmmc_card_init or omap_hsmmc_get_cd are in the same
mmc_rescan thread. Hence, moving the recovery code to init_card does not
help.

 
 I guess other hosts also have some housekeeping upon unexpected
 card removals. So I guess there is some generic code to this problem.
 Did you check?

I did try to find generic code in mmc-core, but couldn't find any.
However, I did see some driver specific cleanups related to unexpected
card removal in sdhci.c. sdhci handles this in .card_event call back.
This does not help in my case as .card_event  is also called from
mmc_rescan. I think cleanup code (in sdhci driver) for unexpected card
removal was introduced when .card_event call was outside mmc_rescan.

 
 +   struct omap_hsmmc_host *host = mmc_priv(dev_id);
 +   int carddetect = mmc_gpio_get_cd(host-mmc);
 +   struct mmc_request *mrq = host-mrq;
 +
 +   /*
 +* If the card was removed in the middle of data transfer last
 +* time, the TC/CC/timeout interrupt is not raised due to which
 +* mmc_request is not cleared. Hence, this card insertion will
 +* still see pending mmc_request. Clear the request to make sure
 +* that this card enumeration is successful.
 +*/
 +   if (!carddetect  mrq  host-transfer_incomplete) {
 +   omap_hsmmc_disable_irq(host);
 +   dev_info(host-dev,
 +card removed during transfer last time\n);
 +   hsmmc_command_incomplete(host, -ENOMEDIUM, 1);
 +   omap_hsmmc_request_clear(host, host-mrq

[PATCH 1/3] mmc: host: omap_hsmmc: Fix DTO and DCRC handling

2015-06-16 Thread Vignesh R
From: Kishon Vijay Abraham I kis...@ti.com

DTO/DCRC errors were not being informed to the mmc core since
commit ae4bf788ee9b (mmc: omap_hsmmc: consolidate error report handling of
HSMMC IRQ). This commit made sure 'end_trans' is never set on DTO/DCRC
errors. This is because after this commit 'host-data' is checked after
it has been cleared to NULL by omap_hsmmc_dma_cleanup().

Because 'end_trans' is never set, omap_hsmmc_xfer_done() is never invoked
making core layer not to be aware of DTO/DCRC errors. Because of this
any command invoked after DTO/DCRC error leads to a hang.

Fix this by checking for 'host-data' before it is actually cleared.

Fixes: ae4bf788ee9b (mmc: omap_hsmmc: consolidate error report handling of
HSMMC IRQ)

CC: sta...@vger.kernel.org
Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
Signed-off-by: Vignesh R vigne...@ti.com
---
 drivers/mmc/host/omap_hsmmc.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 9df2b6801f76..d0abdffb0d7c 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1062,6 +1062,10 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host 
*host, int status)
 
if (status  (CTO_EN | CCRC_EN))
end_cmd = 1;
+   if (host-data || host-response_busy) {
+   end_trans = !end_cmd;
+   host-response_busy = 0;
+   }
if (status  (CTO_EN | DTO_EN))
hsmmc_command_incomplete(host, -ETIMEDOUT, end_cmd);
else if (status  (CCRC_EN | DCRC_EN))
@@ -1081,10 +1085,6 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host 
*host, int status)
}
dev_dbg(mmc_dev(host-mmc), AC12 err: 0x%x\n, ac12);
}
-   if (host-data || host-response_busy) {
-   end_trans = !end_cmd;
-   host-response_busy = 0;
-   }
}
 
OMAP_HSMMC_WRITE(host-base, STAT, status);
-- 
2.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/3] omap_hsmmc: Fix card enumeration failure on

2015-06-16 Thread Vignesh R

Hi,

When using omap_hsmmc driver, if sd-card repeatedly plug unplugged
multiple times quickly, card enumeration stops after few iterations.
This can be easily reproduced on DRA74X EVM which uses omap_hsmmc driver.
This patch series addresses the above problem. The first patch fixes irq
handler to report all DTOs to mmc-core. Second patch adds handling for
BADA, DEB and CEB interrupts. The last patch introduces driver specific
card detect irq handler to cleanup pending requests before card removal.

Tested on DRA74X amd DRA72X and AM437X-GP EVMs, by repeated intense
plug/unplug iterations.


Kishon Vijay Abraham I (1):
  mmc: host: omap_hsmmc: Fix DTO and DCRC handling

Vignesh R (2):
  mmc: host: omap_hsmmc: Handle BADA, DEB and CEB interrupts
  mmc: host: omap_hsmmc: Add custom card detect irq handler

 drivers/mmc/host/omap_hsmmc.c | 84 ---
 1 file changed, 78 insertions(+), 6 deletions(-)

-- 
2.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] mmc: host: omap_hsmmc: Add custom card detect irq handler

2015-06-16 Thread Vignesh R
Usually when there is an error in transfer, DTO/CTO or other error
interrupts are raised. But if the card is unplugged in the middle of a
data transfer, it is observed that, neither completion(success) or
timeout(error) interrupts are raised. Hence, the mmc-core is waiting
for-ever for the transfer to complete. This results failure to recognise
sd card on the next insertion.
The only way to solve this is to introduce code to detect this condition
and recover on card insertion (in hsmmc specific cd_irq). Hence,
introduce cd_irq and add code to clear mmc_request that is pending from
the failed transaction.

Signed-off-by: Vignesh R vigne...@ti.com
---
 drivers/mmc/host/omap_hsmmc.c | 73 ++-
 1 file changed, 72 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index fb4bfefd9250..ec1fff3c0c9c 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -221,6 +221,12 @@ struct omap_hsmmc_host {
 #define HSMMC_WAKE_IRQ_ENABLED (1  2)
struct omap_hsmmc_next  next_data;
struct  omap_hsmmc_platform_data*pdata;
+   /*
+* flag to determine whether card was removed during data
+* transfer
+*/
+   booltransfer_incomplete;
+
 
/* return MMC cover switch state, can be NULL if not supported.
 *
@@ -867,6 +873,26 @@ static void omap_hsmmc_request_done(struct omap_hsmmc_host 
*host, struct mmc_req
 }
 
 /*
+ * Cleanup incomplete card removal sequence. This will make sure the
+ * next card enumeration is clean.
+ */
+static void omap_hsmmc_request_clear(struct omap_hsmmc_host *host,
+struct mmc_request *mrq)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(host-irq_lock, flags);
+   host-req_in_progress = 0;
+   host-dma_ch = -1;
+   spin_unlock_irqrestore(host-irq_lock, flags);
+
+   mmc_request_done(host-mmc, mrq);
+   if (host-mmc-card)
+   mmc_card_set_removed(host-mmc-card);
+   host-mrq = NULL;
+}
+
+/*
  * Notify the transfer complete to MMC core
  */
 static void
@@ -1248,6 +1274,47 @@ static irqreturn_t omap_hsmmc_cover_irq(int irq, void 
*dev_id)
return IRQ_HANDLED;
 }
 
+/*
+ * irq handler to notify the core about card insertion/removal
+ */
+static irqreturn_t omap_hsmmc_cd_irq(int irq, void *dev_id)
+{
+   struct omap_hsmmc_host *host = mmc_priv(dev_id);
+   int carddetect = mmc_gpio_get_cd(host-mmc);
+   struct mmc_request *mrq = host-mrq;
+
+   /*
+* If the card was removed in the middle of data transfer last
+* time, the TC/CC/timeout interrupt is not raised due to which
+* mmc_request is not cleared. Hence, this card insertion will
+* still see pending mmc_request. Clear the request to make sure
+* that this card enumeration is successful.
+*/
+   if (!carddetect  mrq  host-transfer_incomplete) {
+   omap_hsmmc_disable_irq(host);
+   dev_info(host-dev,
+card removed during transfer last time\n);
+   hsmmc_command_incomplete(host, -ENOMEDIUM, 1);
+   omap_hsmmc_request_clear(host, host-mrq);
+   dev_info(host-dev, recovery done\n);
+   }
+   host-transfer_incomplete = false;
+
+   mmc_detect_change(host-mmc, (HZ * 200) / 1000);
+
+   /*
+* The current mmc_request is usually null before card removal
+* sequence is complete. It may not be null if TC/CC interrupt
+* never happens due to removal of card during a data
+* transfer. Set a flag to indicate mmc_request was not null
+* in order to do cleanup on next card insertion.
+*/
+   if (carddetect  mrq)
+   host-transfer_incomplete = true;
+
+   return IRQ_HANDLED;
+}
+
 static void omap_hsmmc_dma_callback(void *param)
 {
struct omap_hsmmc_host *host = param;
@@ -1918,7 +1985,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
struct mmc_host *mmc;
struct omap_hsmmc_host *host = NULL;
struct resource *res;
-   int ret, irq;
+   int ret, irq, len;
const struct of_device_id *match;
dma_cap_mask_t mask;
unsigned tx_req, rx_req;
@@ -1980,6 +2047,10 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
if (ret)
goto err_gpio;
 
+   /* register cd_irq, if cd-gpios property is specified in dt */
+   if (of_find_property(host-dev-of_node, cd-gpios, len))
+   mmc_gpio_set_cd_isr(mmc, omap_hsmmc_cd_irq);
+
platform_set_drvdata(pdev, host);
 
if (pdev-dev.of_node)
-- 
2.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] mmc: host: omap_hsmmc: Handle BADA, DEB and CEB interrupts

2015-06-16 Thread Vignesh R
Sometimes BADA, DEB or CEB error interrupts occur when sd card is
unplugged during data transfer. These interrupts are currently ignored
by the interrupt handler. But, this results in card not being
recognised on subsequent insertion. This is because mmcqd is waiting
forever for the data transfer(for which error occurred) to complete.
Fix this, by reporting BADA, DEB, CEB errors to mmc-core as -EILSEQ, so
that the core can do appropriate handling.

Signed-off-by: Vignesh R vigne...@ti.com
---
 drivers/mmc/host/omap_hsmmc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index d0abdffb0d7c..fb4bfefd9250 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1068,7 +1068,8 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host 
*host, int status)
}
if (status  (CTO_EN | DTO_EN))
hsmmc_command_incomplete(host, -ETIMEDOUT, end_cmd);
-   else if (status  (CCRC_EN | DCRC_EN))
+   else if (status  (CCRC_EN | DCRC_EN | DEB_EN | CEB_EN |
+  BADA_EN))
hsmmc_command_incomplete(host, -EILSEQ, end_cmd);
 
if (status  ACE_EN) {
-- 
2.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/5] ARM: OMAP2+: DRA7: Add hwmod entries for PWMSS

2015-06-03 Thread Vignesh R
Add hwmod entries for the PWMSS on DRA7.

Set l4_root_clk_div as the main_clk of PWMSS. It is fixed-factored clock
equal to L4PER2_L3_GICLK/2(l3_iclk_div/2).
As per AM57x TRM SPRUHZ6[1], October 2014, Section 29.1.3 Table 29-4,
clock source to PWMSS is L4PER2_L3_GICLK. But it is actually
L4PER2_L3_GICLK/2. The TRM does not show the division by 2.

[1] www.ti.com/lit/ug/spruhz6/spruhz6.pdf

Signed-off-by: Vignesh R vigne...@ti.com
---

v2:
 * add TRM references.

 arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 239 ++
 1 file changed, 239 insertions(+)

diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
index 0e64c2fac0b5..86a7ac9a3138 100644
--- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
@@ -362,6 +362,149 @@ static struct omap_hwmod dra7xx_dcan2_hwmod = {
},
 };
 
+/* pwmss  */
+static struct omap_hwmod_class_sysconfig dra7xx_epwmss_sysc = {
+   .rev_offs   = 0x0,
+   .sysc_offs  = 0x4,
+   .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_RESET_STATUS,
+   .idlemodes  = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+   .sysc_fields= omap_hwmod_sysc_type2,
+};
+
+struct omap_hwmod_class dra7xx_epwmss_hwmod_class = {
+   .name   = epwmss,
+   .sysc   = dra7xx_epwmss_sysc,
+};
+
+static struct omap_hwmod_class dra7xx_ecap_hwmod_class = {
+   .name   = ecap,
+};
+
+static struct omap_hwmod_class dra7xx_eqep_hwmod_class = {
+   .name   = eqep,
+};
+
+struct omap_hwmod_class dra7xx_ehrpwm_hwmod_class = {
+   .name   = ehrpwm,
+};
+
+/* epwmss0 */
+struct omap_hwmod dra7xx_epwmss0_hwmod = {
+   .name   = epwmss0,
+   .class  = dra7xx_epwmss_hwmod_class,
+   .clkdm_name = l4per2_clkdm,
+   .main_clk   = l4_root_clk_div,
+   .prcm   = {
+   .omap4  = {
+   .modulemode = MODULEMODE_SWCTRL,
+   .clkctrl_offs   = 
DRA7XX_CM_L4PER2_PWMSS1_CLKCTRL_OFFSET,
+   .context_offs   = 
DRA7XX_RM_L4PER2_PWMSS1_CONTEXT_OFFSET,
+   },
+   },
+};
+
+/* ecap0 */
+struct omap_hwmod dra7xx_ecap0_hwmod = {
+   .name   = ecap0,
+   .class  = dra7xx_ecap_hwmod_class,
+   .clkdm_name = l4per2_clkdm,
+   .main_clk   = l4_root_clk_div,
+};
+
+/* eqep0 */
+struct omap_hwmod dra7xx_eqep0_hwmod = {
+   .name   = eqep0,
+   .class  = dra7xx_eqep_hwmod_class,
+   .clkdm_name = l4per2_clkdm,
+   .main_clk   = l4_root_clk_div,
+};
+
+/* ehrpwm0 */
+struct omap_hwmod dra7xx_ehrpwm0_hwmod = {
+   .name   = ehrpwm0,
+   .class  = dra7xx_ehrpwm_hwmod_class,
+   .clkdm_name = l4per2_clkdm,
+   .main_clk   = l4_root_clk_div,
+};
+
+/* epwmss1 */
+struct omap_hwmod dra7xx_epwmss1_hwmod = {
+   .name   = epwmss1,
+   .class  = dra7xx_epwmss_hwmod_class,
+   .clkdm_name = l4per2_clkdm,
+   .main_clk   = l4_root_clk_div,
+   .prcm   = {
+   .omap4  = {
+   .modulemode = MODULEMODE_SWCTRL,
+   .clkctrl_offs   = 
DRA7XX_CM_L4PER2_PWMSS2_CLKCTRL_OFFSET,
+   .context_offs   = 
DRA7XX_RM_L4PER2_PWMSS2_CONTEXT_OFFSET,
+   },
+   },
+};
+
+/* ecap1 */
+struct omap_hwmod dra7xx_ecap1_hwmod = {
+   .name   = ecap1,
+   .class  = dra7xx_ecap_hwmod_class,
+   .clkdm_name = l4per2_clkdm,
+   .main_clk   = l4_root_clk_div,
+};
+
+/* eqep1 */
+struct omap_hwmod dra7xx_eqep1_hwmod = {
+   .name   = eqep1,
+   .class  = dra7xx_eqep_hwmod_class,
+   .clkdm_name = l4per2_clkdm,
+   .main_clk   = l4_root_clk_div,
+};
+
+/* ehrpwm1 */
+struct omap_hwmod dra7xx_ehrpwm1_hwmod = {
+   .name   = ehrpwm1,
+   .class  = dra7xx_ehrpwm_hwmod_class,
+   .clkdm_name = l4per2_clkdm,
+   .main_clk   = l4_root_clk_div,
+};
+
+/* epwmss2 */
+struct omap_hwmod dra7xx_epwmss2_hwmod = {
+   .name   = epwmss2,
+   .class  = dra7xx_epwmss_hwmod_class,
+   .clkdm_name = l4per2_clkdm,
+   .main_clk   = l4_root_clk_div,
+   .prcm   = {
+   .omap4  = {
+   .modulemode = MODULEMODE_SWCTRL,
+   .clkctrl_offs   = 
DRA7XX_CM_L4PER2_PWMSS3_CLKCTRL_OFFSET,
+   .context_offs   = 
DRA7XX_RM_L4PER2_PWMSS3_CONTEXT_OFFSET,
+   },
+   },
+};
+
+/* ecap2 */
+struct omap_hwmod dra7xx_ecap2_hwmod = {
+   .name   = ecap2,
+   .class  = dra7xx_ecap_hwmod_class,
+   .clkdm_name = l4per2_clkdm,
+   .main_clk   = l4_root_clk_div,
+};
+
+/* eqep2 */
+struct omap_hwmod dra7xx_eqep2_hwmod = {
+   .name

[PATCH v2 1/5] ARM: OMAP2+: DRA7: clockdomain: change l4per2_7xx_clkdm to SW_WKUP

2015-06-03 Thread Vignesh R
Legacy IPs like PWMSS, present under l4per2_7xx_clkdm, cannot support
smart-idle when its clock domain is in HW_AUTO on DRA7 SoCs. Hence,
program clock domain to SW_WKUP.

Signed-off-by: Vignesh R vigne...@ti.com
---
 arch/arm/mach-omap2/clockdomains7xx_data.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/clockdomains7xx_data.c 
b/arch/arm/mach-omap2/clockdomains7xx_data.c
index 57d5df0c1fbd..7581e036bda6 100644
--- a/arch/arm/mach-omap2/clockdomains7xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains7xx_data.c
@@ -331,7 +331,7 @@ static struct clockdomain l4per2_7xx_clkdm = {
.dep_bit  = DRA7XX_L4PER2_STATDEP_SHIFT,
.wkdep_srcs   = l4per2_wkup_sleep_deps,
.sleepdep_srcs= l4per2_wkup_sleep_deps,
-   .flags= CLKDM_CAN_HWSUP_SWSUP,
+   .flags= CLKDM_CAN_SWSUP,
 };
 
 static struct clockdomain mpu0_7xx_clkdm = {
-- 
2.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/5] Add support for PWMSS on DRA7

2015-06-03 Thread Vignesh R

Hi,

This patch series adds support for PWMSS on DRA7. The IP is same as that
present in AM33XX and AM43XX.
The first patch changes clock domain in which PWMSS is present
(l4per2_7xx_clkdm) to SW_WKUP. This is because legacy IPs like PWM
does'nt support HW_AUTO prorperly. Hence, switch clock domain to
SW_WKUP. This is based on the input from the hardware team.
The rest of the patches add hwmod and dt entries and enable PWMSS on
DRA7 based SoCs.

Vignesh R (5):
  ARM: OMAP2+: DRA7: clockdomain: change l4per2_7xx_clkdm to SW_WKUP
  ARM: OMAP2+: DRA7: Add hwmod entries for PWMSS
  ARM: dts: DRA7: Add TBCLK for PWMSS
  clk: ti: DRA7: Add tbclk data for ehrpwm
  ARM: dts: DRA7: Add dt nodes for PWMSS

 .../devicetree/bindings/pwm/pwm-tiehrpwm.txt   |   8 +
 .../devicetree/bindings/pwm/pwm-tipwmss.txt|  17 +-
 arch/arm/boot/dts/dra7.dtsi|  69 ++
 arch/arm/boot/dts/dra7xx-clocks.dtsi   |  26 +++
 arch/arm/mach-omap2/clockdomains7xx_data.c |   2 +-
 arch/arm/mach-omap2/omap_hwmod_7xx_data.c  | 239 +++
 drivers/clk/ti/clk-7xx.c   |   3 +
 7 files changed, 362 insertions(+), 2 deletions(-)

-- 
2.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 3/5] ARM: dts: DRA7: Add TBCLK for PWMSS

2015-06-03 Thread Vignesh R
tbclk is used by ehrpwm to generate PWM waveform on DRA7 SoC. Add Linux
clock to control ehrpwm tbclk.
The TRM says, tbclk is derived from SYSCLKOUT. SYSCLKOUT is nothing but
ehrpwm functional clock derived from the gateable interface and
functional clock of PWMSS(l4_root_clk_div).
Refer AM57x TRM SPRUHZ6[1], October 2014, Table 29-4 and Section 29.2.2.1,
Table 29-19 and the NOTE at the end of the table.

[1] www.ti.com/lit/ug/spruhz6/spruhz6.pdf

Signed-off-by: Vignesh R vigne...@ti.com
---

v2:
 * add TRM references.

 arch/arm/boot/dts/dra7.dtsi  |  5 +
 arch/arm/boot/dts/dra7xx-clocks.dtsi | 26 ++
 2 files changed, 31 insertions(+)

diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index f03a091cd076..387c76ca41f9 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -131,6 +131,11 @@
regulator-max-microvolt 
= 300;
};
};
+
+   scm_conf_clocks: clocks {
+   #address-cells = 1;
+   #size-cells = 0;
+   };
};
 
dra7_pmx_core: pinmux@1400 {
diff --git a/arch/arm/boot/dts/dra7xx-clocks.dtsi 
b/arch/arm/boot/dts/dra7xx-clocks.dtsi
index 3b933f74d000..92452d61cf58 100644
--- a/arch/arm/boot/dts/dra7xx-clocks.dtsi
+++ b/arch/arm/boot/dts/dra7xx-clocks.dtsi
@@ -2136,3 +2136,29 @@
clocks = dpll_usb_ck;
};
 };
+
+scm_conf_clocks {
+   ehrpwm0_tbclk: ehrpwm0_tbclk {
+   #clock-cells = 0;
+   compatible = ti,gate-clock;
+   clocks = l4_root_clk_div;
+   ti,bit-shift = 20;
+   reg = 0x0558;
+   };
+
+   ehrpwm1_tbclk: ehrpwm1_tbclk {
+   #clock-cells = 0;
+   compatible = ti,gate-clock;
+   clocks = l4_root_clk_div;
+   ti,bit-shift = 21;
+   reg = 0x0558;
+   };
+
+   ehrpwm2_tbclk: ehrpwm2_tbclk {
+   #clock-cells = 0;
+   compatible = ti,gate-clock;
+   clocks = l4_root_clk_div;
+   ti,bit-shift = 22;
+   reg = 0x0558;
+   };
+};
-- 
2.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


  1   2   3   >