intel_mid_ssp_spi: Moorestown and Medfield SPI for SSP devices
PATCH RESEND 1/1 intel_mid_ssp_spi: Moorestown and Medfield SPI for SSP devices
From: Mathieu SOULARD <[email protected]>
This driver is a fusion of various internal drivers into a single driver for the SPI slave/master on the Intel Moorestown and Medfield SSP devices.
---
drivers/spi/Kconfig | 8 drivers/spi/Makefile | 2 drivers/spi/spi-intel-mid-ssp.c | 1426 +++++++++++++++++++++++++++++++++++++++ drivers/spi/spi-intel-mid-ssp.h | 308 ++++++++ 4 files changed, 1743 insertions(+), 1 deletions(-) create mode 100644 drivers/spi/spi-intel-mid-ssp.c create mode 100644 drivers/spi/spi-intel-mid-ssp.h
drivers/spi/Kconfig +8 -0
@@ -163,6 +163,14 @@ config SPI_IMX This enables using the Freescale i.MX SPI controllers in master mode. +config SPI_INTEL_MID_SSP + tristate "SSP SPI controller driver for Intel MID platforms (EXPERIMENTAL)" + depends on SPI_MASTER && INTEL_MID_DMAC && EXPERIMENTAL + help + This is the unified SSP SPI slave controller driver for the Intel + MID platforms, handling Moorestown & Medfield, master & slave + clock mode. + config SPI_LM70_LLP tristate "Parallel port adapter for LM70 eval board (DEVELOPMENT)" depends on PARPORT && EXPERIMENTAL
drivers/spi/Makefile +1 -1
@@ -58,4 +58,4 @@ obj-$(CONFIG_SPI_TLE62X0) += spi-tle62x0.o obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o obj-$(CONFIG_SPI_TXX9) += spi-txx9.o obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o - +obj-$(CONFIG_SPI_INTEL_MID_SSP) += spi-intel-mid-ssp.o
drivers/spi/spi-intel-mid-ssp.c new file +1426 -0
1,426 lines not on this page · raw message
drivers/spi/spi-intel-mid-ssp.h new file +308 -0
308 lines not on this page · raw message
------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3, Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
A message that is not in the archive (sent off-list or not yet received): 20120208104059.23036.78003.stgit-Z/[email protected]
Quoted 11 lines · Alan Cox
From: Mathieu SOULARD <[email protected]>
This driver is a fusion of various internal drivers into a single driver for the SPI slave/master on the Intel Moorestown and Medfield SSP devices.
Signed-off-by Mathieu SOULARD <[email protected]>[Queueing and runtime pm added][Ported to the -next tree DMA engine]Signed-off-by Alan Cox <alan-VuQAYsv1563Yd54FQh9/[email protected]>
Quoted 6 lines
---
drivers/spi/Kconfig | 8 drivers/spi/Makefile | 2 drivers/spi/spi-intel-mid-ssp.c | 1426 +++++++++++++++++++++++++++++++++++++++ drivers/spi/spi-intel-mid-ssp.h | 308 ++++++++
If this is merging several of the drivers, what is the plan for the existing SPI_DESIGNWARE and SPI_TOPCLIFF_PCH drivers? Or are those for different devices?
...
drivers/spi/Makefile obj-$(CONFIG_SPI_TLE62X0) += spi-tle62x0.o · line 61
Quoted 10 lines
drivers/spi/Makefile +1
-1@@ -58,4 +58,4 @@ obj-$(CONFIG_SPI_TLE62X0) += spi-tle62x0.o obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o obj-$(CONFIG_SPI_TXX9) += spi-txx9.o obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o - +obj-$(CONFIG_SPI_INTEL_MID_SSP) += spi-intel-mid-ssp.o
I'm trying to keep this list alphabetized.
...
Quoted 14 lines
drivers/spi/Makefile +14
-0+#ifdef DUMP_RX +static void dump_trailer(const struct device *dev, char *buf, int len, int sz) +{ + int tlen1 = (len < sz ? len : sz); + int tlen2 = ((len - sz) > sz) ? sz : (len - sz); + unsigned char *p; + static char msg[MAX_SPI_TRANSFER_SIZE]; + + memset(msg, '\0', sizeof(msg)); + p = buf; + while (p < buf + tlen1) + sprintf(msg, "%s%02x", msg, (unsigned int)*p++); + + if (tlen2 > 0) {
drivers/spi/Makefile
Quoted 10 lines
drivers/spi/Makefile +10
-0+ sprintf(msg, "%s .....", msg); + p = (buf+len) - tlen2; + while (p < buf + len) + sprintf(msg, "%s%02x", msg, (unsigned int)*p++); + } + + dev_info(dev, "DUMP: %p[0:%d ... %d:%d]:%s", buf, tlen1 - 1, + len-tlen2, len - 1, msg); +} +#endif
Yet another hex dump debug utility function? What about lib/hexdump.c?
...
drivers/spi/spi-intel-mid-ssp.h
Quoted 5 lines
drivers/spi/spi-intel-mid-ssp.h new file +0
-0
How much of this stuff is actually needed in a .h file? If it is only used by the .c file, then I want it moved there.
Quoted 300 lines
drivers/spi/spi-intel-mid-ssp.h new file +298
-0@@ -0,0 +1,308 @@ +/* +* Copyright (C) Intel 2009 +* Ken Mills <[email protected]> +* Sylvain Centelles <[email protected]> +* +* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* +*/ +#ifndef SPI_INTEL_MID_SSP_H_ +#define SPI_INTEL_MID_SSP_H_ + +#define PCI_MRST_DMAC1_ID 0x0814 +#define PCI_MDFL_DMAC1_ID 0x0827 + +#define SSP_NOT_SYNC 0x400000 +#define MAX_SPI_TRANSFER_SIZE 8192 +#define MAX_BITBANGING_LOOP 10000 +#define SPI_FIFO_SIZE 16 + +/* PM QoS define */ +#define MIN_EXIT_LATENCY 20 + +/* SSP assignement configuration from PCI config */ +#define SSP_CFG_GET_MODE (ssp_cfg) ((ssp_cfg) & 0x07) +#define SSP_CFG_GET_SPI_BUS_NB (ssp_cfg) (((ssp_cfg) >> 3) & 0x07) +#define SSP_CFG_IS_SPI_SLAVE (ssp_cfg) ((ssp_cfg) & 0x40) +#define SSP_CFG_SPI_MODE_ID 1 +/* adid field offset is 6 inside the vendor specific capability */ +#define VNDR_CAPABILITY_ADID_OFFSET 6 + +/* Driver's quirk flags */ +/* This workarround bufferizes data in the audio fabric SDRAM from */ +/* where the DMA transfers will operate. Should be enabled only for */ +/* SPI slave mode. */ +#define QUIRKS_DMA_USE_NO_TRAIL 2 +/* If set, the driver will use PM_QOS to reduce the latency */ +/* introduced by the deeper C-states which may produce over/under */ +/* run issues. Must be used in slave mode. In master mode, the */ +/* latency is not critical, but setting this workarround may */ +/* improve the SPI throughput. */ +#define QUIRKS_USE_PM_QOS 4 +/* This quirks is set on Medfield */ +#define QUIRKS_PLATFORM_MDFL 16 +/* If set, SPI is in slave clock mode */ +#define QUIRKS_SPI_SLAVE_CLOCK_MODE 64 + +/* Uncomment to get RX and TX short dumps after each transfer */ +/* #define DUMP_RX 1 */ +#define MAX_TRAILING_BYTE_RETRY 16 +#define MAX_TRAILING_BYTE_LOOP 100 +#define DELAY_TO_GET_A_WORD 3 +#define DFLT_TIMEOUT_VAL 500 + +#define DEFINE_SSP_REG (reg, off) \ +static inline u32 read_##reg(void *p) { return __raw_readl(p + (off)); } \ +static inline void write_##reg(u32 v, void *p) { __raw_writel(v, p + (off)); } + +#define RX_DIRECTION 0 +#define TX_DIRECTION 1 + +#define I2C_ACCESS_USDELAY 10 + +#define DFLT_BITS_PER_WORD 16 +#define MIN_BITS_PER_WORD 4 +#define MAX_BITS_PER_WORD 32 +#define DFLT_FIFO_BURST_SIZE IMSS_FIFO_BURST_8 + +#define TRUNCATE (x, a) ((x) & ~((a)-1)) + +DEFINE_SSP_REG(SSCR0, 0x00) +DEFINE_SSP_REG(SSCR1, 0x04) +DEFINE_SSP_REG(SSSR, 0x08) +DEFINE_SSP_REG(SSITR, 0x0c) +DEFINE_SSP_REG(SSDR, 0x10) +DEFINE_SSP_REG(SSTO, 0x28) +DEFINE_SSP_REG(SSPSP, 0x2c) + +DEFINE_SSP_REG (I2CCTRL ,0x00 ); +DEFINE_SSP_REG (I2CDATA ,0x04 ); + +DEFINE_SSP_REG (GPLR1 ,0x04 ); +DEFINE_SSP_REG (GPDR1 ,0x0c ); +DEFINE_SSP_REG (GPSR1 ,0x14 ); +DEFINE_SSP_REG (GPCR1 ,0x1C ); +DEFINE_SSP_REG (GAFR1_U ,0x44 ); + +#define SYSCFG 0x20bc0 + +#define SRAM_BASE_ADDR 0xfffdc000 +#define SRAM_RX_ADDR SRAM_BASE_ADDR +#define SRAM_TX_ADDR (SRAM_BASE_ADDR + MAX_SPI_TRANSFER_SIZE) + +#define SSCR0_DSS (0x0000000f)/* Data Size Select (mask) */ +#define SSCR0_DataSize (x) ((x) - 1)/* Data Size Select [4..16] */ +#define SSCR0_FRF (0x00000030)/* FRame Format (mask) */ +#define SSCR0_Motorola (0x0 << 4)/* Motorola's SPI mode */ +#define SSCR0_ECS (1 << 6)/* External clock select */ +#define SSCR0_SSE (1 << 7)/* Synchronous Serial Port Enable */ + +#define SSCR0_SCR (0x000fff00)/* Serial Clock Rate (mask) */ +#define SSCR0_SerClkDiv (x) (((x) - 1) << 8)/* Divisor [1..4096] */ +#define SSCR0_EDSS (1 << 20)/* Extended data size select */ +#define SSCR0_NCS (1 << 21)/* Network clock select */ +#define SSCR0_RIM (1 << 22)/* Receive FIFO overrrun int mask */ +#define SSCR0_TUM (1 << 23)/* Transmit FIFO underrun int mask */ +#define SSCR0_FRDC (0x07000000)/* Frame rate divider control (mask) */ +#define SSCR0_SlotsPerFrm (x) (((x) - 1) << 24)/* Time slots per frame */ +#define SSCR0_ADC (1 << 30)/* Audio clock select */ +#define SSCR0_MOD (1 << 31)/* Mode (normal or network) */ + +#define SSCR1_RIE (1 << 0)/* Receive FIFO Interrupt Enable */ +#define SSCR1_TIE (1 << 1)/* Transmit FIFO Interrupt Enable */ +#define SSCR1_LBM (1 << 2)/* Loop-Back Mode */ +#define SSCR1_SPO (1 << 3)/* SSPSCLK polarity setting */ +#define SSCR1_SPH (1 << 4)/* Motorola SPI SSPSCLK phase setting */ +#define SSCR1_MWDS (1 << 5)/* Microwire Transmit Data Size */ +#define SSCR1_TFT (0x000003c0)/* Transmit FIFO Threshold (mask) */ +#define SSCR1_TxTresh (x) (((x) - 1) << 6)/* level [1..16] */ +#define SSCR1_RFT (0x00003c00)/* Receive FIFO Threshold (mask) */ +#define SSCR1_RxTresh (x) (((x) - 1) << 10)/* level [1..16] */ + +#define SSSR_TNF (1 << 2)/* Tx FIFO Not Full */ +#define SSSR_RNE (1 << 3)/* Rx FIFO Not Empty */ +#define SSSR_BSY (1 << 4)/* SSP Busy */ +#define SSSR_TFS (1 << 5)/* Tx FIFO Service Request */ +#define SSSR_RFS (1 << 6)/* Rx FIFO Service Request */ +#define SSSR_ROR (1 << 7)/* Rx FIFO Overrun */ +#define SSSR_TFL_MASK (0x0F << 8)/* Tx FIFO level field mask */ + +#define SSCR0_TIM (1 << 23)/* Transmit FIFO Under Run Int Mask */ +#define SSCR0_RIM (1 << 22)/* Receive FIFO Over Run int Mask */ +#define SSCR0_NCS (1 << 21)/* Network Clock Select */ +#define SSCR0_EDSS (1 << 20)/* Extended Data Size Select */ + +#define SSCR0_TISSP (1 << 4)/* TI Sync Serial Protocol */ +#define SSCR0_PSP (3 << 4)/* PSP - Programmable Serial Protocol */ +#define SSCR1_TTELP (1 << 31)/* TXD Tristate Enable Last Phase */ +#define SSCR1_TTE (1 << 30)/* TXD Tristate Enable */ +#define SSCR1_EBCEI (1 << 29)/* Enable Bit Count Error interrupt */ +#define SSCR1_SCFR (1 << 28)/* Slave Clock free Running */ +#define SSCR1_ECRA (1 << 27)/* Enable Clock Request A */ +#define SSCR1_ECRB (1 << 26)/* Enable Clock request B */ +#define SSCR1_SCLKDIR (1 << 25)/* Serial Bit Rate Clock Direction */ +#define SSCR1_SFRMDIR (1 << 24)/* Frame Direction */ +#define SSCR1_RWOT (1 << 23)/* Receive Without Transmit */ +#define SSCR1_TRAIL (1 << 22)/* Trailing Byte */ +#define SSCR1_TSRE (1 << 21)/* Transmit Service Request Enable */ +#define SSCR1_RSRE (1 << 20)/* Receive Service Request Enable */ +#define SSCR1_TINTE (1 << 19)/* Receiver Time-out Interrupt enable */ +#define SSCR1_PINTE (1 << 18)/* Trailing Byte Interupt Enable */ +#define SSCR1_STRF (1 << 15)/* Select FIFO or EFWR */ +#define SSCR1_EFWR (1 << 14)/* Enable FIFO Write/Read */ +#define SSCR1_IFS (1 << 16)/* Invert Frame Signal */ + +#define SSSR_BCE (1 << 23)/* Bit Count Error */ +#define SSSR_CSS (1 << 22)/* Clock Synchronisation Status */ +#define SSSR_TUR (1 << 21)/* Transmit FIFO Under Run */ +#define SSSR_EOC (1 << 20)/* End Of Chain */ +#define SSSR_TINT (1 << 19)/* Receiver Time-out Interrupt */ +#define SSSR_PINT (1 << 18)/* Peripheral Trailing Byte Interrupt */ + +#define SSPSP_FSRT (1 << 25)/* Frame Sync Relative Timing */ +#define SSPSP_DMYSTOP (x) ((x) << 23)/* Dummy Stop */ +#define SSPSP_SFRMWDTH (x)((x) << 16)/* Serial Frame Width */ +#define SSPSP_SFRMDLY (x) ((x) << 9)/* Serial Frame Delay */ +#define SSPSP_DMYSTRT (x) ((x) << 7)/* Dummy Start */ +#define SSPSP_STRTDLY (x) ((x) << 4)/* Start Delay */ +#define SSPSP_ETDS (1 << 3)/* End of Transfer data State */ +#define SSPSP_SFRMP (1 << 2)/* Serial Frame Polarity */ +#define SSPSP_SCMODE (x) ((x) << 0)/* Serial Bit Rate Clock Mode */ + +/* +* For testing SSCR1 changes that require SSP restart, basically +* everything except the service and interrupt enables +*/ + +#define SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_SCFR \ + | SSCR1_ECRA | SSCR1_ECRB | SSCR1_SCLKDIR \ + | SSCR1_SFRMDIR | SSCR1_RWOT | SSCR1_TRAIL \ + | SSCR1_IFS | SSCR1_STRF | SSCR1_EFWR \ + | SSCR1_RFT | SSCR1_TFT | SSCR1_MWDS \ + | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM) + +struct callback_param { +void *drv_context; +u32 direction; +}; + +struct ssp_driver_context { +/* Driver model hookup */ +struct pci_dev *pdev; + +/* SPI framework hookup */ +struct spi_master *master; + +/* SSP register addresses */ +unsigned long paddr; +void *ioaddr; +int irq; + +/* SSP masks*/ +u32 cr1_sig; +u32 cr1; +u32 clear_sr; +u32 mask_sr; + +struct tasklet_struct poll_transfer; + +spinlock_t lock; + +/* Current message transfer state info */ +struct spi_message *cur_msg; +size_t len; +size_t len_dma_rx; +size_t len_dma_tx; +void *tx; +void *tx_end; +void *rx; +void *rx_end; +bool dma_initialized; +int dma_mapped; +dma_addr_t rx_dma; +dma_addr_t tx_dma; +u8 n_bytes; +int (*write)(struct ssp_driver_context *drv_context); +int (*read)(struct ssp_driver_context *drv_context); + +struct intel_mid_dma_slave dmas_tx; +struct intel_mid_dma_slave dmas_rx; +struct dma_chan *txchan; +struct dma_chan *rxchan; +struct workqueue_struct *dma_wq; +struct work_struct complete_work; + +spinlock_t queue_lock; +struct list_head queue; +struct workqueue_struct *transfer_queue; +struct work_struct transfer_work; +bool running; + +int txdma_done; +int rxdma_done; +struct callback_param tx_param; +struct callback_param rx_param; +struct pci_dev *dmac1; + +unsigned long quirks; +u32 rx_fifo_threshold; +}; + +struct chip_data { +u32 cr0; +u32 cr1; +u32 timeout; +u8 n_bytes; +u8 dma_enabled; +u8 bits_per_word; +u32 speed_hz; +int (*write)(struct ssp_driver_context *drv_context); +int (*read)(struct ssp_driver_context *drv_context); +}; + + +enum intel_mid_ssp_spi_fifo_burst { +IMSS_FIFO_BURST_1 , +IMSS_FIFO_BURST_4 , +IMSS_FIFO_BURST_8 +}; + +/* spi_board_info.controller_data for SPI slave devices, +* copied to spi_device.platform_data ... mostly for dma tuning +*/ +struct intel_mid_ssp_spi_chip { +enum intel_mid_ssp_spi_fifo_burst burst_size; +u32 timeout; +u8 enable_loopback; +u8 dma_enabled; +}; + + +#define SPI_DIB_NAME_LEN 16 +#define SPI_DIB_SPEC_INFO_LEN 10
drivers/spi/spi-intel-mid-ssp.h line 308
Quoted 10 lines
drivers/spi/spi-intel-mid-ssp.h new file +10
-0+ +struct spi_dib_header { +u32 signature; +u32 length; +u8 rev; +u8 checksum; +u8 dib[0 ]; +} __attribute__((packed)); + +#endif /* SPI_INTEL_MID_SSP_H_*/
------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning Cloud computing makes use of virtualization - but cloud computing also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
A message that is not in the archive (sent off-list or not yet received): 20120209153121.GC11249-e0URQFbLeQY2iJbIjFUEsiwD8/[email protected]
Hi Grant,
Quoted 20 lines · On Thu, 9 Feb 2012 07:31:21 -0800 Grant Likely…
Quoted 11 lines · Alan Cox
From: Mathieu SOULARD <[email protected]>
This driver is a fusion of various internal drivers into a single driver for the SPI slave/master on the Intel Moorestown and Medfield SSP devices.
Signed-off-by Mathieu SOULARD <[email protected]>[Queueing and runtime pm added][Ported to the -next tree DMA engine]Signed-off-by Alan Cox <alan-VuQAYsv1563Yd54FQh9/[email protected]>Quoted 7 lines
---
drivers/spi/Kconfig | 8 drivers/spi/Makefile | 2 drivers/spi/spi-intel-mid-ssp.c | 1426+++++++++++++++++++++++++++++++++++++++
drivers/spi/spi-intel-mid-ssp.h| 308 ++++++++
Quoted 3 lines
If this is merging several of the drivers, what is the plan for the existing
SPI_DESIGNWAREandSPI_TOPCLIFF_PCHdrivers? Or are those for different devices?
The DESIGNWARE controller has a different HW IP core, so the 2 drivers can't be merged. And for the TOPCLIFF one, seems it also use a different HW IP than this one, so I guess it can't be merged either.
Thanks,
Feng
------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning Cloud computing makes use of virtualization - but cloud computing also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/