From 10c159cd54bfab386f662943f8a3a46b2904c22c Mon Sep 17 00:00:00 2001 From: Pawel Szyszuk Date: Thu, 7 Jul 2011 15:16:33 +0100 Subject: 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 Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/32180 Reviewed-by: Yann GAUTIER Reviewed-by: Andrew LYNN --- arch/arm/mach-ux500/devices-db8500.c | 4 +-- arch/arm/mach-ux500/include/mach/hsi.h | 5 +++- drivers/hsi/controllers/ste_hsi.c | 51 ++++++++++++++++++++++++++++------ 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; } -- cgit v1.2.3