summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPawel Szyszuk <pawel.szyszuk@stericsson.com>2011-07-07 15:16:33 +0100
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:07:29 +0200
commit34b45698157f41b89227c4043e97f05aeb520bb7 (patch)
tree96f18695626aacf6bbdc4d3d310e6e9750ac1cbc
parent5be556d75c33d54f45a6766e7a4b8c1926e55a47 (diff)
ARM: U8500: ST-E HSI: DMA burst and PIPE support
Added support for HSIR PIPELINED mode (also in drivers/hsi) Added DMA max burst (in DMA words) as a parameter in hsi.h DMA channel high priority set to TRUE for HSI ST-Ericsson ID: 356625 ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: Trivial Change-Id: Id842e61343ce5013992337db085fcbe91dd5b9f7 Signed-off-by: Pawel Szyszuk <pawel.szyszuk@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/32180 Reviewed-by: Yann GAUTIER <yann.gautier@stericsson.com> Reviewed-by: Andrew LYNN <andrew.lynn@stericsson.com>
-rw-r--r--arch/arm/mach-ux500/include/mach/hsi.h5
-rw-r--r--drivers/hsi/controllers/ste_hsi.c51
2 files changed, 47 insertions, 9 deletions
diff --git a/arch/arm/mach-ux500/include/mach/hsi.h b/arch/arm/mach-ux500/include/mach/hsi.h
index 030e35e729b..1d2ab206e27 100644
--- a/arch/arm/mach-ux500/include/mach/hsi.h
+++ b/arch/arm/mach-ux500/include/mach/hsi.h
@@ -63,6 +63,7 @@
#define STE_HSI_RX_SPANX 0x140
#define STE_HSI_RX_GAUGEX 0x180
#define STE_HSI_RX_WATERMARKX 0x1C0
+#define STE_HSI_RX_FRAMEBURSTCNT 0x1E0
#define STE_HSI_RX_DMAEN 0x200
#define STE_HSI_RX_WATERMARKIS 0x204
#define STE_HSI_RX_WATERMARKIM 0x208
@@ -101,7 +102,9 @@
#define STE_HSI_MAX_BUFFERS 32
/* Max channels of STE HSI controller */
-#define STE_HSI_MAX_CHANNELS 4
+#define STE_HSI_MAX_CHANNELS 2
+
+#define STE_HSI_DMA_MAX_BURST 1
struct stedma40_chan_cfg;
diff --git a/drivers/hsi/controllers/ste_hsi.c b/drivers/hsi/controllers/ste_hsi.c
index 8ac1363c14c..a9cd343fd53 100644
--- a/drivers/hsi/controllers/ste_hsi.c
+++ b/drivers/hsi/controllers/ste_hsi.c
@@ -198,9 +198,19 @@ static void ste_hsi_setup_registers(struct ste_hsi_controller *ste_hsi)
ste_hsi->tx_base + STE_HSI_TX_BASEX + 4 * i);
writel(buffers - 1,
ste_hsi->tx_base + STE_HSI_TX_SPANX + 4 * i);
- writel(buffers - 1,
- ste_hsi->tx_base + STE_HSI_TX_WATERMARKX + 4 * i);
+
+ /*
+ * The DMA burst request and the buffer occupation interrupt are
+ * asserted when the free space in the corresponding channel buffer
+ * is greater than the value programmed in TX_WATERMARKX field.
+ * The field value must be less than the corresponding SPAN value.
+ */
+#ifdef CONFIG_STE_DMA40
+ writel(STE_HSI_DMA_MAX_BURST-1,
+ ste_hsi->tx_base + STE_HSI_TX_WATERMARKX + 4 * i);
+#else /* IRQ mode */
writel(0, ste_hsi->tx_base + STE_HSI_TX_WATERMARKX + 4 * i);
+#endif
}
/*
@@ -215,7 +225,16 @@ static void ste_hsi_setup_registers(struct ste_hsi_controller *ste_hsi)
* Configure RX
*/
writel(pcontext->rx_mode, ste_hsi->rx_base + STE_HSI_RX_MODE);
- writel(0, ste_hsi->rx_base + STE_HSI_RX_PARITY);
+
+ if (STE_HSI_MODE_PIPELINED == pcontext->rx_mode)
+ /*
+ * 0x0F: The READY line is negated after the start of the
+ * 16th frame reception in PIPELINED mode.
+ */
+ writel(0x0F, ste_hsi->rx_base + STE_HSI_RX_FRAMEBURSTCNT);
+ else
+ writel(0, ste_hsi->rx_base + STE_HSI_RX_FRAMEBURSTCNT);
+
writel(pcontext->rx_channels, ste_hsi->rx_base + STE_HSI_RX_CHANNELS);
/* Calculate buffers number per channel */
buffers = STE_HSI_MAX_BUFFERS / pcontext->rx_channels;
@@ -226,9 +245,19 @@ static void ste_hsi_setup_registers(struct ste_hsi_controller *ste_hsi)
ste_hsi->rx_base + STE_HSI_RX_BASEX + 4 * i);
writel(buffers - 1,
ste_hsi->rx_base + STE_HSI_RX_SPANX + 4 * i);
- writel(buffers - 1,
- ste_hsi->rx_base + STE_HSI_RX_WATERMARKX + 4 * i);
+
+ /*
+ * The DMA burst request and the buffer occupation interrupt are
+ * asserted when the busy space in the corresponding channel buffer
+ * is greater than the value programmed in RX_WATERMARKX field.
+ * The field value must be less than the corresponding SPAN value.
+ */
+#ifdef CONFIG_STE_DMA40
+ writel(STE_HSI_DMA_MAX_BURST-1,
+ ste_hsi->rx_base + STE_HSI_RX_WATERMARKX + 4 * i);
+#else /* IRQ mode */
writel(0, ste_hsi->rx_base + STE_HSI_RX_WATERMARKX + 4 * i);
+#endif
}
/*
@@ -642,13 +671,13 @@ static int ste_hsi_setup_dma(struct hsi_client *cl)
.src_addr = 0, /* dynamic data */
.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
.direction = DMA_FROM_DEVICE,
- .src_maxburst = 1,
+ .src_maxburst = STE_HSI_DMA_MAX_BURST,
};
struct dma_slave_config tx_conf = {
.dst_addr = 0, /* dynamic data */
.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
.direction = DMA_TO_DEVICE,
- .dst_maxburst = 1,
+ .dst_maxburst = STE_HSI_DMA_MAX_BURST,
};
if (!ste_hsi->use_dma)
@@ -1279,7 +1308,13 @@ static int ste_hsi_setup(struct hsi_client *cl)
ste_hsi->context->tx_mode = cl->tx_cfg.mode;
ste_hsi->context->tx_divisor = div;
ste_hsi->context->tx_channels = cl->tx_cfg.channels;
- ste_hsi->context->rx_mode = cl->rx_cfg.mode;
+
+ if ((HSI_FLOW_PIPE == cl->rx_cfg.flow) &&
+ (HSI_MODE_FRAME == cl->rx_cfg.mode))
+ ste_hsi->context->rx_mode = STE_HSI_MODE_PIPELINED;
+ else
+ ste_hsi->context->rx_mode = cl->rx_cfg.mode;
+
ste_hsi->context->rx_channels = cl->rx_cfg.channels;
}