summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPawel Szyszuk <pawel.szyszuk@stericsson.com>2011-07-07 15:16:33 +0100
committerAndrew LYNN <andrew.lynn@stericsson.com>2011-09-28 17:22:44 +0200
commit10c159cd54bfab386f662943f8a3a46b2904c22c (patch)
tree203a2824448c183fa77f2214f68263078bd1665f
parent83e66e8bf85b9a65eb803fe1be464c83d20eec3e (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/devices-db8500.c4
-rw-r--r--arch/arm/mach-ux500/include/mach/hsi.h5
-rw-r--r--drivers/hsi/controllers/ste_hsi.c51
3 files changed, 49 insertions, 11 deletions
diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c
index 014945ade4e..5578d1f612b 100644
--- a/arch/arm/mach-ux500/devices-db8500.c
+++ b/arch/arm/mach-ux500/devices-db8500.c
@@ -316,7 +316,7 @@ struct platform_device ux500_prcmu_wdt_device = {
#define STE_HSI_PORT0_TX_CHANNEL_CFG(n) { \
.dir = STEDMA40_MEM_TO_PERIPH, \
- .high_priority = false, \
+ .high_priority = true, \
.mode = STEDMA40_MODE_LOGICAL, \
.mode_opt = STEDMA40_LCHAN_SRC_LOG_DST_LOG, \
.src_dev_type = STEDMA40_DEV_SRC_MEMORY, \
@@ -329,7 +329,7 @@ struct platform_device ux500_prcmu_wdt_device = {
#define STE_HSI_PORT0_RX_CHANNEL_CFG(n) { \
.dir = STEDMA40_PERIPH_TO_MEM, \
- .high_priority = false, \
+ .high_priority = true, \
.mode = STEDMA40_MODE_LOGICAL, \
.mode_opt = STEDMA40_LCHAN_SRC_LOG_DST_LOG, \
.src_dev_type = n,\
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;
}