On Wed, Feb 08, 2012 at 10:41:10AM +0000, Alan Cox wrote:
> 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]
> Signed-off-by: Kristen Carlson Accardi <[email protected]>
> [Ported to the -next tree DMA engine]
> Signed-off-by: Alan Cox <[email protected]>
> ---
> 
>  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?

...
> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> index 61c3261..e81757a 100644
> --- a/drivers/spi/Makefile
> +++ b/drivers/spi/Makefile
> @@ -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.

...
> +#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) {
> +             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?

...
> diff --git a/drivers/spi/spi-intel-mid-ssp.h b/drivers/spi/spi-intel-mid-ssp.h
> new file mode 100644
> index 0000000..11fad57
> --- /dev/null
> +++ b/drivers/spi/spi-intel-mid-ssp.h

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.

> @@ -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
> +
> +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/
_______________________________________________
spi-devel-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spi-devel-general

Reply via email to