[PATCH] intel_mid_ssp_spi: Moorestown and Medfield SPI for SSP devices
From: Mathieu SOULARD mathieux.soul...@intel.com 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 mathieux.soul...@intel.com [Queueing and runtime pm added] Signed-off-by: Kristen Carlson Accardi kris...@linux.intel.com [Ported to the -next tree DMA engine, stripped Moorestown, further cleanup] Signed-off-by: Alan Cox a...@linux.intel.com --- 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 diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 3f9a47e..ed8363e 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -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 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 diff --git a/drivers/spi/spi-intel-mid-ssp.c b/drivers/spi/spi-intel-mid-ssp.c new file mode 100644 index 000..77bff9f --- /dev/null +++ b/drivers/spi/spi-intel-mid-ssp.c @@ -0,0 +1,1426 @@ +/* + * This driver supports Bulverde SSP core used on Intel MID platforms + * It supports the SSP of Medfield platforms and handles clock + * slave master modes. + * + * Copyright (c) 2010, Intel Corporation. + * Ken Mills ken.k.mi...@intel.com + * Sylvain Centelles sylvain.centel...@intel.com + * Mathieu SOULARD + * Kristen Carlson Accardi kris...@linux.intel.com + * Alan Cox a...@linux.intel.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* + * Note: + * + * Supports DMA and non-interrupt polled transfers. + * + */ + +#include linux/module.h +#include linux/delay.h +#include linux/interrupt.h +#include linux/highmem.h +#include linux/pci.h +#include linux/init.h +#include linux/interrupt.h +#include linux/dma-mapping.h +#include linux/intel_mid_dma.h +#include linux/pm_qos.h +#include linux/pm_runtime.h + +#include linux/spi/spi.h +#include spi-intel-mid-ssp.h + +#define DRIVER_NAME spi-intel-mid-ssp + +MODULE_AUTHOR(Ken Mills); +MODULE_DESCRIPTION(Bulverde SSP core SPI contoller); +MODULE_LICENSE(GPL); + +static const struct pci_device_id pci_ids[]; + +#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 + +static inline u32 is_tx_fifo_empty(struct ssp_driver_context *drv_context) +{ + u32 sssr; + sssr = read_SSSR(drv_context-ioaddr); + if ((sssr SSSR_TFL_MASK) || (sssr SSSR_TNF) == 0) + return 0; + else
Re: [PATCH] intel_mid_ssp_spi: Moorestown and Medfield SPI for SSP devices
On Thu, Jan 26, 2012 at 10:57 AM, Alan Cox a...@lxorguk.ukuu.org.uk wrote: From: Mathieu SOULARD mathieux.soul...@intel.com 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 mathieux.soul...@intel.com [Queueing and runtime pm added] Signed-off-by: Kristen Carlson Accardi kris...@linux.intel.com [Ported to the -next tree DMA engine, stripped Moorestown, further cleanup] Signed-off-by: Alan Cox a...@linux.intel.com --- drivers/spi/Kconfig | 8 drivers/spi/Makefile | 2 drivers/spi/spi-intel-mid-ssp.c | 1426 +++ drivers/spi/spi-intel-mid-ssp.h | 308 Haven't reviewed the patch yet, but I've got a question on this. Are there any other users of this header file? Can I just roll it into the .c file if I pick up the patch? g. -- 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 ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [PATCH] intel_mid_ssp_spi: Moorestown and Medfield SPI for SSP devices
On Thu, 26 Jan 2012 12:18:41 -0700 Grant Likely grant.lik...@secretlab.ca wrote: On Thu, Jan 26, 2012 at 10:57 AM, Alan Cox a...@lxorguk.ukuu.org.uk wrote: From: Mathieu SOULARD mathieux.soul...@intel.com 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 mathieux.soul...@intel.com [Queueing and runtime pm added] Signed-off-by: Kristen Carlson Accardi kris...@linux.intel.com [Ported to the -next tree DMA engine, stripped Moorestown, further cleanup] Signed-off-by: Alan Cox a...@linux.intel.com --- drivers/spi/Kconfig | 8 drivers/spi/Makefile | 2 drivers/spi/spi-intel-mid-ssp.c | 1426 +++ drivers/spi/spi-intel-mid-ssp.h | 308 Haven't reviewed the patch yet, but I've got a question on this. Are there any other users of this header file? Can I just roll it into the .c file if I pick up the patch? They can be rolled together. There is a driver pending for the device in I²S mode but there isn't anything in common. Alan -- 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 ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [PATCH] intel_mid_ssp_spi: Moorestown and Medfield SPI for SSP devices
2010/10/22 Alan Cox a...@lxorguk.ukuu.org.uk: From: Mathieu SOULARD mathieux.soul...@intel.com (...) +/** + * intel_mid_ssp_spi_dma_init() - Initialize DMA + * @drv_context: Pointer to the private driver context + * + * This function is called at driver setup phase to allocate DMA + * ressources. + */ +static void intel_mid_ssp_spi_dma_init(struct ssp_driver_context *drv_context) +{ + struct intel_mid_dma_slave *rxs, *txs; + struct dma_slave_config *ds; Hey, I really like this :-) But where are you actually using this config? It looks like you're in some transition phase to the generic API. + dma_cap_mask_t mask; + struct device *dev = drv_context-pdev-dev; + unsigned int device_id; + + /* Configure RX channel parameters */ + rxs = drv_context-dmas_rx; + ds = rxs-dma_slave; + + ds-direction = DMA_FROM_DEVICE; + rxs-hs_mode = LNW_DMA_HW_HS; + rxs-cfg_mode = LNW_DMA_PER_TO_MEM; + ds-dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + ds-src_addr_width = drv_context-n_bytes; + + /* Use a DMA burst according to the FIFO thresholds */ + if (drv_context-rx_fifo_threshold == 8) { + ds-src_maxburst = 8; + ds-dst_maxburst = 8; + } else if (drv_context-rx_fifo_threshold == 4) { + ds-src_maxburst = 4; + ds-dst_maxburst = 4; + } else { + ds-src_maxburst = 1; + ds-dst_maxburst = 1; + } + + /* Configure TX channel parameters */ + txs = drv_context-dmas_tx; + ds = txs-dma_slave; + + ds-direction = DMA_TO_DEVICE; + txs-hs_mode = LNW_DMA_HW_HS; + txs-cfg_mode = LNW_DMA_MEM_TO_PER; What I cannot wrap my head around is why your DMA controller cannot figure these things out from the data passed in to the + ds-src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + ds-dst_addr_width = drv_context-n_bytes; You also want to se ds-src_addr and ds-dst_addr instead of passing that through an artificial memcpy() call. + /* Use a DMA burst according to the FIFO thresholds */ + if (drv_context-rx_fifo_threshold == 8) { + ds-src_maxburst = 8; + ds-dst_maxburst = 8; + } else if (drv_context-rx_fifo_threshold == 4) { + ds-src_maxburst = 4; + ds-dst_maxburst = 4; + } else { + ds-src_maxburst = 1; + ds-dst_maxburst = 1; + } + + /* Nothing more to do if already initialized */ There isn't? You need to call rxchan-device-device_control(rxchan, DMA_SLAVE_CONFIG, (unsigned long) ds); To use that config you've set. + if (drv_context-dma_initialized) + return; + + /* Use DMAC1 */ + if (drv_context-quirks QUIRKS_PLATFORM_MRST) + device_id = PCI_MRST_DMAC1_ID; + else + device_id = PCI_MDFL_DMAC1_ID; + + drv_context-dmac1 = pci_get_device(PCI_VENDOR_ID_INTEL, + device_id, NULL); + + if (!drv_context-dmac1) { + dev_err(dev, Can't find DMAC1); + return; + } + + if (drv_context-quirks QUIRKS_SRAM_ADDITIONAL_CPY) { + drv_context-virt_addr_sram_rx = ioremap_nocache(SRAM_BASE_ADDR, + 2 * MAX_SPI_TRANSFER_SIZE); + if (drv_context-virt_addr_sram_rx) + drv_context-virt_addr_sram_tx = + drv_context-virt_addr_sram_rx + + MAX_SPI_TRANSFER_SIZE; + else + dev_err(dev, Virt_addr_sram_rx is null\n); + } + + /* 1. Allocate rx channel */ + dma_cap_zero(mask); + dma_cap_set(DMA_MEMCPY, mask); + dma_cap_set(DMA_SLAVE, mask); You only want to request DMA_SLAVE really. + + drv_context-rxchan = dma_request_channel(mask, chan_filter, + drv_context); + if (!drv_context-rxchan) + goto err_exit; + + drv_context-rxchan-private = rxs; + + /* 2. Allocate tx channel */ + dma_cap_set(DMA_SLAVE, mask); + dma_cap_set(DMA_MEMCPY, mask); + + drv_context-txchan = dma_request_channel(mask, chan_filter, + drv_context); + + if (!drv_context-txchan) + goto free_rxchan; + else + drv_context-txchan-private = txs; rxchan-device-device_control(rxchan, DMA_SLAVE_CONFIG, (unsigned long) ds); txchan-device-device_control(txchan, DMA_SLAVE_CONFIG, (unsigned long) ds); + /* set the dma done bit to 1 */ + drv_context-txdma_done = 1; + drv_context-rxdma_done = 1; + +
[PATCH] intel_mid_ssp_spi: Moorestown and Medfield SPI for SSP devices
This is a first pass submit of the SSP SPI driver for the Intel MID platforms (Moorestown and Medfield). From: Mathieu SOULARD mathieux.soul...@intel.com 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 mathieux.soul...@intel.com [Ported to the -next tree DMA engine] Signed-off-by: Alan Cox a...@linux.intel.com --- drivers/spi/Kconfig |8 drivers/spi/Makefile|1 drivers/spi/intel_mid_ssp_spi.c | 1403 +++ drivers/spi/intel_mid_ssp_spi.h | 321 + 4 files changed, 1733 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/intel_mid_ssp_spi.c create mode 100644 drivers/spi/intel_mid_ssp_spi.h diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 78f9fd0..82e45cf 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -167,6 +167,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 diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 8bc1a5a..b427c2e 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_SPI_DW_MMIO) += dw_spi_mmio.o obj-$(CONFIG_SPI_EP93XX) += ep93xx_spi.o obj-$(CONFIG_SPI_GPIO) += spi_gpio.o obj-$(CONFIG_SPI_IMX) += spi_imx.o +obj-$(CONFIG_SPI_INTEL_MID_SSP)+= intel_mid_ssp_spi.o obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o diff --git a/drivers/spi/intel_mid_ssp_spi.c b/drivers/spi/intel_mid_ssp_spi.c new file mode 100644 index 000..2d6d881 --- /dev/null +++ b/drivers/spi/intel_mid_ssp_spi.c @@ -0,0 +1,1403 @@ +/* + * intel_mid_ssp_spi.c + * This driver supports Bulverde SSP core used on Intel MID platforms + * It supports SSP of Moorestown Medfield platforms and handles clock + * slave master modes. + * + * Copyright (c) 2010, Intel Corporation. + * Ken Mills ken.k.mi...@intel.com + * Sylvain Centelles sylvain.centel...@intel.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* + * Note: + * + * Supports DMA and non-interrupt polled transfers. + * + */ + +#include linux/delay.h +#include linux/interrupt.h +#include linux/highmem.h +#include linux/pci.h +#include linux/init.h +#include linux/interrupt.h +#include linux/dma-mapping.h +#include linux/intel_mid_dma.h +#include linux/pm_qos_params.h + +#include linux/spi/spi.h +#include intel_mid_ssp_spi.h + +#define DRIVER_NAME intel_mid_ssp_spi_unified + +MODULE_AUTHOR(Ken Mills); +MODULE_DESCRIPTION(Bulverde SSP core SPI contoller); +MODULE_LICENSE(GPL); + +static const struct pci_device_id pci_ids[]; + +#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 + +static inline u32 is_tx_fifo_empty(struct ssp_driver_context *drv_context) +{ + u32 sssr; + sssr = read_SSSR(drv_context-ioaddr); + if ((sssr SSSR_TFL_MASK) || (sssr SSSR_TNF) == 0) + return