aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/intel_mid_ssp_spi.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/intel_mid_ssp_spi.h')
-rw-r--r--drivers/spi/intel_mid_ssp_spi.h321
1 files changed, 321 insertions, 0 deletions
diff --git a/drivers/spi/intel_mid_ssp_spi.h b/drivers/spi/intel_mid_ssp_spi.h
new file mode 100644
index 00000000000..aef2fa8973b
--- /dev/null
+++ b/drivers/spi/intel_mid_ssp_spi.h
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) Intel 2009
+ * Ken Mills <ken.k.mills@intel.com>
+ * Sylvain Centelles <sylvain.centelles@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * 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 INTEL_MID_SSP_SPI_H_
+#define INTEL_MID_SSP_SPI_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_SRAM_ADDITIONAL_CPY 1
+/* If set the trailing bytes won't be handled by the DMA. */
+/* Trailing byte feature not fully available. */
+#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 Moorestown */
+#define QUIRKS_PLATFORM_MRST 8
+/* This quirks is set on Medfield */
+#define QUIRKS_PLATFORM_MDFL 16
+/* If set, the driver will apply the bitbanging workarround needed */
+/* to enable defective Langwell stepping A SSP. The defective SSP */
+/* can be enabled only once, and should never be disabled. */
+#define QUIRKS_BIT_BANGING 32
+/* 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;
+
+ /* I2C registers */
+ dma_addr_t I2C_paddr;
+ void *I2C_ioaddr;
+
+ /* SSP masks*/
+ u32 cr1_sig;
+ u32 cr1;
+ u32 clear_sr;
+ u32 mask_sr;
+
+ /* PM_QOS request */
+ struct pm_qos_request_list pm_qos_req;
+
+ 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;
+
+ u8 __iomem *virt_addr_sram_tx;
+ u8 __iomem *virt_addr_sram_rx;
+
+ 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
+
+struct spi_dib_header {
+ u32 signature;
+ u32 length;
+ u8 rev;
+ u8 checksum;
+ u8 dib[0];
+} __attribute__((packed));
+
+#endif /*INTEL_MID_SSP_SPI_H_*/