blob: 9abf056c89a4ef9d9722e4826b64b4a14fa9c91d [file] [log] [blame]
/*
* 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_
#include <linux/intel_mid_dma.h>
#include <linux/pm_qos.h>
#include <linux/spi/spi.h>
#include <linux/interrupt.h>
#include <linux/wakelock.h>
#include <linux/completion.h>
#define PCI_MRST_DMAC1_ID 0x0814
#define PCI_MDFL_DMAC1_ID 0x0827
#define PCI_BYT_DMAC1_ID 0x0f06
#define PCI_MRFL_DMAC_ID 0x11A2
#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_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
/* Add more platform here. */
/* This quirks is set on Baytrail. */
#define QUIRKS_PLATFORM_BYT 128
#define QUIRKS_PLATFORM_MRFL 256
/* 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(SSFS, 0x44)
DEFINE_SSP_REG(SFIFOL, 0x68)
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 SSSR_RFL_SHIFT 12 /* Rx FIFO MASK shift */
#define SSSR_RFL_MASK (0x0F << SSSR_RFL_SHIFT)/* RxFIFOlevel 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)
/* add CS control call back feature to give user capability
to control CS signal by themselves*/
#define CS_DEASSERT 0
#define CS_ASSERT 1
struct callback_param {
void *drv_context;
u32 direction;
};
struct ssp_drv_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 pm_qos_req;
struct tasklet_struct poll_transfer;
spinlock_t lock;
struct wake_lock stay_awake;
struct workqueue_struct *workqueue;
struct work_struct pump_messages;
struct list_head queue;
struct completion msg_done;
int suspended;
/* 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_drv_context *sspc);
int (*read)(struct ssp_drv_context *sspc);
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;
int cs_change;
void (*cs_control)(u32 command);
};
struct chip_data {
u32 cr0;
u32 cr1;
u32 timeout;
u8 chip_select;
u8 n_bytes;
u8 dma_enabled;
u8 bits_per_word;
u32 speed_hz;
int (*write)(struct ssp_drv_context *sspc);
int (*read)(struct ssp_drv_context *sspc);
void (*cs_control)(u32 command);
};
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;
void (*cs_control)(u32 command);
};
#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];
} __packed;
#endif /*INTEL_MID_SSP_SPI_H_*/