Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi/pxa2xx: add support for Intel Low Power Subsystem SPI

Intel LPSS SPI is pretty much the same as the PXA27xx SPI except that it
has few additional features over the original:

o FIFO depth is 256 entries
o RX FIFO has one watermark
o TX FIFO has two watermarks, low and high
o chip select can be controlled by writing to a register

The new FIFO registers follow immediately the PXA27xx registers but then there
are some additional LPSS private registers at offset 1k or 2k from the base
address. For these private registers we add new accessors that take advantage
of drv_data->lpss_base once it is resolved.

We add a new type LPSS_SSP that can be used to distinguish the LPSS devices
from others.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Tested-by: Lu Cao <lucao@marvell.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

authored by

Mika Westerberg and committed by
Mark Brown
a0d2642e b833172f

+145 -4
+129 -4
drivers/spi/spi-pxa2xx.c
··· 1 1 /* 2 2 * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs 3 + * Copyright (C) 2013, Intel Corporation 3 4 * 4 5 * This program is free software; you can redistribute it and/or modify 5 6 * it under the terms of the GNU General Public License as published by ··· 62 61 | SSCR1_RFT | SSCR1_TFT | SSCR1_MWDS \ 63 62 | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM) 64 63 64 + #define LPSS_RX_THRESH_DFLT 64 65 + #define LPSS_TX_LOTHRESH_DFLT 160 66 + #define LPSS_TX_HITHRESH_DFLT 224 67 + 68 + /* Offset from drv_data->lpss_base */ 69 + #define SPI_CS_CONTROL 0x18 70 + #define SPI_CS_CONTROL_SW_MODE BIT(0) 71 + #define SPI_CS_CONTROL_CS_HIGH BIT(1) 72 + 73 + static bool is_lpss_ssp(const struct driver_data *drv_data) 74 + { 75 + return drv_data->ssp_type == LPSS_SSP; 76 + } 77 + 78 + /* 79 + * Read and write LPSS SSP private registers. Caller must first check that 80 + * is_lpss_ssp() returns true before these can be called. 81 + */ 82 + static u32 __lpss_ssp_read_priv(struct driver_data *drv_data, unsigned offset) 83 + { 84 + WARN_ON(!drv_data->lpss_base); 85 + return readl(drv_data->lpss_base + offset); 86 + } 87 + 88 + static void __lpss_ssp_write_priv(struct driver_data *drv_data, 89 + unsigned offset, u32 value) 90 + { 91 + WARN_ON(!drv_data->lpss_base); 92 + writel(value, drv_data->lpss_base + offset); 93 + } 94 + 95 + /* 96 + * lpss_ssp_setup - perform LPSS SSP specific setup 97 + * @drv_data: pointer to the driver private data 98 + * 99 + * Perform LPSS SSP specific setup. This function must be called first if 100 + * one is going to use LPSS SSP private registers. 101 + */ 102 + static void lpss_ssp_setup(struct driver_data *drv_data) 103 + { 104 + unsigned offset = 0x400; 105 + u32 value, orig; 106 + 107 + if (!is_lpss_ssp(drv_data)) 108 + return; 109 + 110 + /* 111 + * Perform auto-detection of the LPSS SSP private registers. They 112 + * can be either at 1k or 2k offset from the base address. 113 + */ 114 + orig = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL); 115 + 116 + value = orig | SPI_CS_CONTROL_SW_MODE; 117 + writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL); 118 + value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL); 119 + if (value != (orig | SPI_CS_CONTROL_SW_MODE)) { 120 + offset = 0x800; 121 + goto detection_done; 122 + } 123 + 124 + value &= ~SPI_CS_CONTROL_SW_MODE; 125 + writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL); 126 + value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL); 127 + if (value != orig) { 128 + offset = 0x800; 129 + goto detection_done; 130 + } 131 + 132 + detection_done: 133 + /* Now set the LPSS base */ 134 + drv_data->lpss_base = drv_data->ioaddr + offset; 135 + 136 + /* Enable software chip select control */ 137 + value = SPI_CS_CONTROL_SW_MODE | SPI_CS_CONTROL_CS_HIGH; 138 + __lpss_ssp_write_priv(drv_data, SPI_CS_CONTROL, value); 139 + } 140 + 141 + static void lpss_ssp_cs_control(struct driver_data *drv_data, bool enable) 142 + { 143 + u32 value; 144 + 145 + if (!is_lpss_ssp(drv_data)) 146 + return; 147 + 148 + value = __lpss_ssp_read_priv(drv_data, SPI_CS_CONTROL); 149 + if (enable) 150 + value &= ~SPI_CS_CONTROL_CS_HIGH; 151 + else 152 + value |= SPI_CS_CONTROL_CS_HIGH; 153 + __lpss_ssp_write_priv(drv_data, SPI_CS_CONTROL, value); 154 + } 155 + 65 156 static void cs_assert(struct driver_data *drv_data) 66 157 { 67 158 struct chip_data *chip = drv_data->cur_chip; ··· 168 75 return; 169 76 } 170 77 171 - if (gpio_is_valid(chip->gpio_cs)) 78 + if (gpio_is_valid(chip->gpio_cs)) { 172 79 gpio_set_value(chip->gpio_cs, chip->gpio_cs_inverted); 80 + return; 81 + } 82 + 83 + lpss_ssp_cs_control(drv_data, true); 173 84 } 174 85 175 86 static void cs_deassert(struct driver_data *drv_data) ··· 188 91 return; 189 92 } 190 93 191 - if (gpio_is_valid(chip->gpio_cs)) 94 + if (gpio_is_valid(chip->gpio_cs)) { 192 95 gpio_set_value(chip->gpio_cs, !chip->gpio_cs_inverted); 96 + return; 97 + } 98 + 99 + lpss_ssp_cs_control(drv_data, false); 193 100 } 194 101 195 102 int pxa2xx_spi_flush(struct driver_data *drv_data) ··· 743 642 write_SSSR_CS(drv_data, drv_data->clear_sr); 744 643 } 745 644 645 + if (is_lpss_ssp(drv_data)) { 646 + if ((read_SSIRF(reg) & 0xff) != chip->lpss_rx_threshold) 647 + write_SSIRF(chip->lpss_rx_threshold, reg); 648 + if ((read_SSITF(reg) & 0xffff) != chip->lpss_tx_threshold) 649 + write_SSITF(chip->lpss_tx_threshold, reg); 650 + } 651 + 746 652 /* see if we need to reload the config registers */ 747 653 if ((read_SSCR0(reg) != cr0) 748 654 || (read_SSCR1(reg) & SSCR1_CHANGE_MASK) != ··· 862 754 struct chip_data *chip; 863 755 struct driver_data *drv_data = spi_master_get_devdata(spi->master); 864 756 unsigned int clk_div; 865 - uint tx_thres = TX_THRESH_DFLT; 866 - uint rx_thres = RX_THRESH_DFLT; 757 + uint tx_thres, tx_hi_thres, rx_thres; 758 + 759 + if (is_lpss_ssp(drv_data)) { 760 + tx_thres = LPSS_TX_LOTHRESH_DFLT; 761 + tx_hi_thres = LPSS_TX_HITHRESH_DFLT; 762 + rx_thres = LPSS_RX_THRESH_DFLT; 763 + } else { 764 + tx_thres = TX_THRESH_DFLT; 765 + tx_hi_thres = 0; 766 + rx_thres = RX_THRESH_DFLT; 767 + } 867 768 868 769 if (!pxa25x_ssp_comp(drv_data) 869 770 && (spi->bits_per_word < 4 || spi->bits_per_word > 32)) { ··· 925 808 chip->timeout = chip_info->timeout; 926 809 if (chip_info->tx_threshold) 927 810 tx_thres = chip_info->tx_threshold; 811 + if (chip_info->tx_hi_threshold) 812 + tx_hi_thres = chip_info->tx_hi_threshold; 928 813 if (chip_info->rx_threshold) 929 814 rx_thres = chip_info->rx_threshold; 930 815 chip->enable_dma = drv_data->master_info->enable_dma; ··· 937 818 938 819 chip->threshold = (SSCR1_RxTresh(rx_thres) & SSCR1_RFT) | 939 820 (SSCR1_TxTresh(tx_thres) & SSCR1_TFT); 821 + 822 + chip->lpss_rx_threshold = SSIRF_RxThresh(rx_thres); 823 + chip->lpss_tx_threshold = SSITF_TxLoThresh(tx_thres) 824 + | SSITF_TxHiThresh(tx_hi_thres); 940 825 941 826 /* set dma burst and threshold outside of chip_info path so that if 942 827 * chip_info goes away after setting chip->enable_dma, the ··· 1128 1005 if (!pxa25x_ssp_comp(drv_data)) 1129 1006 write_SSTO(0, drv_data->ioaddr); 1130 1007 write_SSPSP(0, drv_data->ioaddr); 1008 + 1009 + lpss_ssp_setup(drv_data); 1131 1010 1132 1011 tasklet_init(&drv_data->pump_transfers, pump_transfers, 1133 1012 (unsigned long)drv_data);
+6
drivers/spi/spi-pxa2xx.h
··· 86 86 int (*read)(struct driver_data *drv_data); 87 87 irqreturn_t (*transfer_handler)(struct driver_data *drv_data); 88 88 void (*cs_control)(u32 command); 89 + 90 + void __iomem *lpss_base; 89 91 }; 90 92 91 93 struct chip_data { ··· 99 97 u32 dma_burst_size; 100 98 u32 threshold; 101 99 u32 dma_threshold; 100 + u16 lpss_rx_threshold; 101 + u16 lpss_tx_threshold; 102 102 u8 enable_dma; 103 103 u8 bits_per_word; 104 104 u32 speed_hz; ··· 128 124 DEFINE_SSP_REG(SSDR, 0x10) 129 125 DEFINE_SSP_REG(SSTO, 0x28) 130 126 DEFINE_SSP_REG(SSPSP, 0x2c) 127 + DEFINE_SSP_REG(SSITF, SSITF) 128 + DEFINE_SSP_REG(SSIRF, SSIRF) 131 129 132 130 #define START_STATE ((void *)0) 133 131 #define RUNNING_STATE ((void *)1)
+9
include/linux/pxa2xx_ssp.h
··· 155 155 #define SSACD_ACDS(x) ((x) << 0) /* Audio clock divider select */ 156 156 #define SSACD_SCDX8 (1 << 7) /* SYSCLK division ratio select */ 157 157 158 + /* LPSS SSP */ 159 + #define SSITF 0x44 /* TX FIFO trigger level */ 160 + #define SSITF_TxLoThresh(x) (((x) - 1) << 8) 161 + #define SSITF_TxHiThresh(x) ((x) - 1) 162 + 163 + #define SSIRF 0x48 /* RX FIFO trigger level */ 164 + #define SSIRF_RxThresh(x) ((x) - 1) 165 + 158 166 enum pxa_ssp_type { 159 167 SSP_UNDEFINED = 0, 160 168 PXA25x_SSP, /* pxa 210, 250, 255, 26x */ ··· 172 164 PXA168_SSP, 173 165 PXA910_SSP, 174 166 CE4100_SSP, 167 + LPSS_SSP, 175 168 }; 176 169 177 170 struct ssp_device {
+1
include/linux/spi/pxa2xx_spi.h
··· 44 44 */ 45 45 struct pxa2xx_spi_chip { 46 46 u8 tx_threshold; 47 + u8 tx_hi_threshold; 47 48 u8 rx_threshold; 48 49 u8 dma_burst_size; 49 50 u32 timeout;