MFD: Added Timberdale driver
PATCH 7/9 MFD: Added Timberdale driver
MFD driver for the Timberdale FPGA The FPGA can be found on the Intel Atom development board, Russellville for in-vechicle infotainment
The FPGA is connected via PCIe
The driver basically exposes a lot of platform devices for the different IPs within the FPGA, and doing IRQ multiplexing
---
drivers/mfd/Kconfig +10 -0
@@ -241,6 +241,16 @@ Say yes here if you want to include support GPIO for pins on the PCF50633 chip. +config MFD_TIMBERDALE + bool "Support for the Timberdale FPGA" + select MFD_CORE + ---help--- + This is the core driver for the timberdale FPGA. This device is a + multifunctioanl device which may provide numerous interfaces. + + The timberdale FPGA can be found on the Intel Atom development board + for automotive in-vehicle infontainment board called Russellville. + config MFD_TIMBERDALE_DMA tristate "Support for timberdale DMA" depends on MFD_TIMBERDALE
drivers/mfd/timberdale.c +686 -0
686 lines not on this page · raw message
drivers/mfd/timberdale.h +123 -0
123 lines not on this page · raw message
drivers/mfd/Makefile +1 -0
@@ -42,4 +42,5 @@ obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o +obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o obj-$(CONFIG_MFD_TIMBERDALE_DMA) += timbdma.o
Hi Richard,
Quoted 9 lines · Richard Röjfors
MFD driver for the Timberdale FPGA The FPGA can be found on the Intel Atom development board, Russellville for in-vechicle infotainment
The FPGA is connected via PCIe
The driver basically exposes a lot of platform devices for the different IPs within the FPGA, and doing IRQ multiplexing
Signed-off-by Richard Röjfors <[email protected]>
patch #4 of this serie is an mfd driver too, so I guess I should have been cc'ed on it too.
So, if I understand this thread correctly, we should proceed like that:
1) Richard comes up with an updated xilinx patch (patch #2).
2) Andrew sends all patches but patch 7 to the relevant maintainers.
3) When all patches but 7 are in Linus tree, I take patch 7 and include it in my pull request to Linus.
Andrew, does that make sense to you? Do you want me to take patch #4 as well?
Cheers,
Samuel.
Quoted 852 lines
---
Index: linux-2.6.30-rc7/drivers/mfd/Kconfig
===================================================================drivers/mfd/Kconfig +10
-0@@ -241,6 +241,16 @@ Say yes here if you want to include support GPIO for pins on the PCF50633 chip. +config MFD_TIMBERDALE + bool "Support for the Timberdale FPGA" + select MFD_CORE + ---help--- + This is the core driver for the timberdale FPGA. This device is a + multifunctioanl device which may provide numerous interfaces. + + The timberdale FPGA can be found on the Intel Atom development board + for automotive in-vehicle infontainment board called Russellville. + config MFD_TIMBERDALE_DMA tristate "Support for timberdale DMA" depends on MFD_TIMBERDALEIndex:
linux-2.6.30-rc7/drivers/mfd/timberdale.c
===================================================================drivers/mfd/timberdale.c +686
-0@@ -0,0 +1,686 @@ +/* +* timberdale.c timberdale FPGA mfd shim driver +* Copyright (c) 2009 Intel Corporation +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +* 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* Supports: +* Timberdale FPGA +*/ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/msi.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/mfd/core.h> +#include <linux/irq.h> + +#include <linux/i2c.h> +#include <linux/i2c-ocores.h> +#include <linux/i2c/tsc2007.h> + +#include <linux/spi/spi.h> +#include <linux/spi/xilinx_spi.h> +#include <linux/spi/max7301.h> +#include <linux/spi/mc33880.h> + +#include <media/timb_video.h> + +#include "timberdale.h" + +struct timberdale_device { +resource_size_t intc_mapbase; +resource_size_t ctl_mapbase; +unsigned char __iomem *intc_membase; +unsigned char __iomem *ctl_membase; +int irq_base; +u32 irq_ack_mask; +/* locking from interrupts while modifiying registers */ +spinlock_t lock; +}; + +/*--------------------------------------------------------------------------*/ + +struct tsc2007_platform_data timberdale_tsc2007_platform_data = { + .model =2003 , + .x_plate_ohms =100 +}; + +struct i2c_board_info timberdale_i2c_board_info[] = { + { +I2C_BOARD_INFO ("tsc2003" ,0x48 ), + .platform_data = &timberdale_tsc2007_platform_data, + .irq =IRQ_TIMBERDALE_TSC_INT + }, + { +/* Requires jumper JP9 to be off */ +I2C_BOARD_INFO ("adv7180" ,0x42 >>1 ), + .irq =IRQ_TIMBERDALE_ADV7180 + } +}; + +static __devinitdata struct ocores_i2c_platform_data +timberdale_i2c_platform_data = { + .regstep =4 , + .clock_khz =62500 , + .devices = timberdale_i2c_board_info, + .num_devices =ARRAY_SIZE (timberdale_i2c_board_info) +}; + +const static __devinitconst struct resource timberdale_i2c_resources[] = { + { + .start =I2COFFSET , + .end =I2CEND , + .flags =IORESOURCE_MEM , + }, + { + .start =IRQ_TIMBERDALE_I2C , + .end =IRQ_TIMBERDALE_I2C , + .flags =IORESOURCE_IRQ , + }, +}; + +const struct max7301_platform_data timberdale_max7301_platform_data = { + .base =-1 +}; + +const struct mc33880_platform_data timberdale_mc33880_platform_data = { + .base =-1 +}; + +struct spi_board_info timberdale_spi_16bit_board_info[] = { + { + .modalias ="max7301" , + .max_speed_hz =26000 , + .chip_select =2 , + .mode =SPI_MODE_0 , + .platform_data = &timberdale_max7301_platform_data + }, +}; + +struct spi_board_info timberdale_spi_8bit_board_info[] = { + { + .modalias ="mc33880" , + .max_speed_hz =4000 , + .chip_select =1 , + .mode =SPI_MODE_1 , + .platform_data = &timberdale_mc33880_platform_data + }, +}; + +static __devinitdata struct xspi_platform_data timberdale_xspi_platform_data = { + .bus_num =-1 , +/* Current(2009-03-06) revision of +* Timberdale we can handle 3 chip selects +*/ + .num_chipselect =3 , + .model =XILINX_SPI_MODEL_DS570 , +/* bits per word and devices will be filled in runtime depending +* on the HW config +*/ +}; + +const static __devinitconst struct resource timberdale_spi_resources[] = { + { + .start =SPIOFFSET , + .end =SPIEND , + .flags =IORESOURCE_MEM , + }, + { + .start =IRQ_TIMBERDALE_SPI , + .end =IRQ_TIMBERDALE_SPI , + .flags =IORESOURCE_IRQ , + }, +}; + +const static __devinitconst struct resource timberdale_eth_resources[] = { + { + .start =ETHOFFSET , + .end =ETHEND , + .flags =IORESOURCE_MEM , + }, + { + .start =IRQ_TIMBERDALE_ETHSW_IF , + .end =IRQ_TIMBERDALE_ETHSW_IF , + .flags =IORESOURCE_IRQ , + }, +}; + +const static __devinitconst struct resource timberdale_gpio_resources[] = { + { + .start =GPIOOFFSET , + .end =GPIOEND , + .flags =IORESOURCE_MEM , + }, + { + .start =IRQ_TIMBERDALE_GPIO , + .end =IRQ_TIMBERDALE_GPIO , + .flags =IORESOURCE_IRQ , + }, +}; + +const static __devinitconst struct resource timberdale_most_resources[] = { + { + .start =MOSTOFFSET , + .end =MOSTEND , + .flags =IORESOURCE_MEM , + }, + { + .start =IRQ_TIMBERDALE_MLB , + .end =IRQ_TIMBERDALE_MLB , + .flags =IORESOURCE_IRQ , + }, +}; + +const static __devinitconst struct resource timberdale_uart_resources[] = { + { + .start =UARTOFFSET , + .end =UARTEND , + .flags =IORESOURCE_MEM , + }, + { + .start =IRQ_TIMBERDALE_UART , + .end =IRQ_TIMBERDALE_UART , + .flags =IORESOURCE_IRQ , + }, +}; + +const static __devinitconst struct resource timberdale_i2s_resources[] = { + { + .start =I2SOFFSET , + .end =I2SEND , + .flags =IORESOURCE_MEM , + }, + { + .start =IRQ_TIMBERDALE_I2S , + .end =IRQ_TIMBERDALE_I2S , + .flags =IORESOURCE_IRQ , + }, +}; + +static __devinitdata struct timb_video_platform_data + timberdale_video_platform_data = { + .i2c_adapter =0 , + .encoder ="adv7180" +}; + +const static __devinitconst struct resource timberdale_video_resources[] = { + { + .start =LOGIWOFFSET , + .end =LOGIWEND , + .flags =IORESOURCE_MEM , + }, +/* +note that the "frame buffer" is located in DMA area +starting at 0x1200000 +*/ +}; + +const static __devinitconst struct resource timberdale_dma_resources[] = { + { + .start =DMAOFFSET , + .end =DMAEND , + .flags =IORESOURCE_MEM , + }, + { + .start =IRQ_TIMBERDALE_DMA , + .end =IRQ_TIMBERDALE_DMA , + .flags =IORESOURCE_IRQ , + }, +}; + +static __devinitdata struct mfd_cell timberdale_cells_bar0[] = { + { + .name ="timb-uart" , + .num_resources =ARRAY_SIZE (timberdale_uart_resources), + .resources = timberdale_uart_resources, + }, + { + .name ="ocores-i2c" , + .num_resources =ARRAY_SIZE (timberdale_i2c_resources), + .resources = timberdale_i2c_resources, + .platform_data = &timberdale_i2c_platform_data, + .data_size =sizeof (timberdale_i2c_platform_data), + }, + { + .name ="timb-gpio" , + .num_resources =ARRAY_SIZE (timberdale_gpio_resources), + .resources = timberdale_gpio_resources, + }, + { + .name ="timb-i2s" , + .num_resources =ARRAY_SIZE (timberdale_i2s_resources), + .resources = timberdale_i2s_resources, + }, + { + .name ="timb-most" , + .num_resources =ARRAY_SIZE (timberdale_most_resources), + .resources = timberdale_most_resources, + }, + { + .name ="timb-video" , + .num_resources =ARRAY_SIZE (timberdale_video_resources), + .resources = timberdale_video_resources, + .platform_data = &timberdale_video_platform_data, + .data_size =sizeof (timberdale_video_platform_data), + }, + { + .name ="xilinx_spi" , + .num_resources =ARRAY_SIZE (timberdale_spi_resources), + .resources = timberdale_spi_resources, + .platform_data = &timberdale_xspi_platform_data, + .data_size =sizeof (timberdale_xspi_platform_data), + }, + { + .name ="ks8842" , + .num_resources =ARRAY_SIZE (timberdale_eth_resources), + .resources = timberdale_eth_resources, + }, + { + .name ="timb-dma" , + .num_resources =ARRAY_SIZE (timberdale_dma_resources), + .resources = timberdale_dma_resources, + }, +}; + +static const __devinitconst struct resource timberdale_sdhc_resources[] = { +/* located in bar 1 and bar 2 */ + { + .start =SDHC0OFFSET , + .end =SDHC0END , + .flags =IORESOURCE_MEM , + }, + { + .start =IRQ_TIMBERDALE_SDHC , + .end =IRQ_TIMBERDALE_SDHC , + .flags =IORESOURCE_IRQ , + }, +}; + +static __devinitdata struct mfd_cell timberdale_cells_bar1[] = { + { + .name ="sdhci" , + .num_resources =ARRAY_SIZE (timberdale_sdhc_resources), + .resources = timberdale_sdhc_resources, + }, +}; + +static __devinitdata struct mfd_cell timberdale_cells_bar2[] = { + { + .name ="sdhci" , + .num_resources =ARRAY_SIZE (timberdale_sdhc_resources), + .resources = timberdale_sdhc_resources, + }, +}; + +/*--------------------------------------------------------------------------*/ + + +/* Handle the timberdale interrupt mux */ +static void timberdale_irq (unsigned int irq,struct irq_desc *desc) +{ +struct timberdale_device *priv =get_irq_data (irq); +unsigned int i, ipr; + + desc->chip->ack (irq); + +while ((ipr =ioread32 (priv->intc_membase +IPR ))) { +for (i =0 ; i <TIMBERDALE_NR_IRQS ; i++) +if (ipr & (1 << i)) { + priv->irq_ack_mask =0 ; +generic_handle_irq (priv->irq_base + i); +if (priv->irq_ack_mask) +iowrite32 (priv->irq_ack_mask, + priv->intc_membase +IAR ); + } + } +} + +static void timberdale_irq_mask (unsigned int irq) +{ +struct timberdale_device *priv =get_irq_chip_data (irq); +unsigned long flags; + +spin_lock_irqsave (&priv->lock, flags); +iowrite32 (1 << (irq - priv->irq_base), priv->intc_membase +CIE ); +spin_unlock_irqrestore (&priv->lock, flags); +} + +static void timberdale_irq_unmask (unsigned int irq) +{ +struct timberdale_device *priv =get_irq_chip_data (irq); +unsigned long flags; + +spin_lock_irqsave (&priv->lock, flags); +iowrite32 (1 << (irq - priv->irq_base), priv->intc_membase +SIE ); +spin_unlock_irqrestore (&priv->lock, flags); +} + +static void timberdale_irq_ack (unsigned int irq) +{ +struct timberdale_device *priv =get_irq_chip_data (irq); +unsigned long flags; +u32 ack_mask =1 << (irq - priv->irq_base); + +spin_lock_irqsave (&priv->lock, flags); +/* if edge triggered, ack directly. Otherwhise ack in the end of +* irq handler +*/ +if (ack_mask &IRQ_TIMBERDALE_EDGE_MASK ) +iowrite32 (ack_mask, priv->intc_membase +IAR ); +else + priv->irq_ack_mask |= ack_mask; +spin_unlock_irqrestore (&priv->lock, flags); +} + +static struct irq_chip timberdale_chip = { + .name ="timberdale" , + .ack = timberdale_irq_ack, + .mask = timberdale_irq_mask, + .unmask = timberdale_irq_unmask, + .disable = timberdale_irq_mask, + .enable = timberdale_irq_unmask, +}; + +/*--------------------------------------------------------------------------*/ + +/* Install the IRQ handler */ +static void timberdale_attach_irq (struct pci_dev *dev) +{ +struct timberdale_device *priv =pci_get_drvdata (dev); +unsigned int irq, irq_base; + + irq_base = priv->irq_base; +for (irq = irq_base; irq < irq_base +TIMBERDALE_NR_IRQS ; irq++) { +set_irq_chip_and_handler_name (irq, &timberdale_chip, + handle_edge_irq,"mux" ); + +set_irq_chip_data (irq, priv); + +#ifdef CONFIG_ARM +set_irq_flags (irq,IRQF_VALID |IRQF_PROBE ); +#endif + } + +set_irq_data (dev->irq, priv); +set_irq_chained_handler (dev->irq, timberdale_irq); +} + +static void timberdale_detach_irq (struct pci_dev *dev) +{ +struct timberdale_device *priv =pci_get_drvdata (dev); +unsigned int irq, irq_base; + + irq_base = priv->irq_base; + +set_irq_chained_handler (dev->irq,NULL ); +set_irq_data (dev->irq,NULL ); + +for (irq = irq_base; irq < irq_base +TIMBERDALE_NR_IRQS ; irq++) { +#ifdef CONFIG_ARM +set_irq_flags (irq,0 ); +#endif +set_irq_chip (irq,NULL ); +set_irq_chip_data (irq,NULL ); + } +} + +static int irq_range_free (int irq_start,int num_irq) +{ +int i; + +for (i =0 ; i < num_irq; i++) +if (get_irq_chip (irq_start + i) != &no_irq_chip) +return 0 ; + +return 1 ; +} + +static int __devinit timb_probe (struct pci_dev *dev, +const struct pci_device_id *id) +{ +struct timberdale_device *priv; +int err, i; +resource_size_t mapbase; +u32 hw_config; + + priv =kzalloc (sizeof (*priv),GFP_KERNEL ); +if (!priv) +return -ENOMEM ; + +spin_lock_init (&priv->lock); +pci_set_drvdata (dev, priv); + + err =pci_enable_device (dev); +if (err) + goto err_enable; + + mapbase =pci_resource_start (dev,0 ); +if (!mapbase) { +printk (KERN_ERR "timberdale: No resource\n" ); + goto err_start; + } + +/* create a resource for the Interrupt controller registers */ + priv->intc_mapbase = mapbase +INTCOFFSET ; +if (!request_mem_region (priv->intc_mapbase,INTCSIZE ,"timb-intc" )) { +printk (KERN_ERR "timberdale: Failed to request intc mem\n" ); + goto err_request; + } + +/* create a resource for the PCI master register */ + priv->ctl_mapbase = mapbase +CHIPCTLOFFSET ; +if (!request_mem_region (priv->ctl_mapbase,CHIPCTLSIZE ,"timb-intc" )) { +printk (KERN_ERR "timberdale: Failed to request ctl mem\n" ); + goto err_request_ctl; + } + + priv->intc_membase =ioremap (priv->intc_mapbase,INTCSIZE ); +if (!priv->intc_membase) { +printk (KERN_ALERT "timberdale: Map error, intc\n" ); + goto err_ioremap; + } + + priv->ctl_membase =ioremap (priv->ctl_mapbase,CHIPCTLSIZE ); +if (!priv->ctl_membase) { +printk (KERN_ALERT "timberdale: Map error, ctl\n" ); + goto err_ioremap_ctl; + } + + err =pci_enable_msi (dev); +if (err) { +printk (KERN_WARNING "timberdale: MSI init failed: %d\n" , err); + goto err_msi; + } + +/* Reset all FPGA PLB peripherals */ +iowrite32 (0x1 , priv->ctl_membase +MAYSVILLERST ); + +/* read the HW config */ + hw_config =ioread32 (priv->ctl_membase +TIMB_HW_CONFIG ); + +/* at this stage the FPGA does not generate a +* unique interrupt per function, to emulate real interrupts +* we assign them a faked interrupt which we issue in the +* interrupt handler. For now just hard code a base number +*/ + priv->irq_base =NR_IRQS -TIMBERDALE_NR_IRQS -1 ; +while (priv->irq_base >=0 ) +if (irq_range_free (priv->irq_base,TIMBERDALE_NR_IRQS )) +break ; +else + priv->irq_base -=TIMBERDALE_NR_IRQS ; + +if (priv->irq_base <0 ) + goto err_msi; + +timberdale_attach_irq (dev); + +/* update IRQ offsets in I2C board info */ +for (i =0 ; i <ARRAY_SIZE (timberdale_i2c_board_info); i++) + timberdale_i2c_board_info[i].irq += priv->irq_base; + +/* Update the SPI configuration depending on the HW (8 or 16 bit) */ +if (hw_config &TIMB_HW_CONFIG_SPI_8BIT ) { + timberdale_xspi_platform_data.bits_per_word =8 ; + timberdale_xspi_platform_data.devices = + timberdale_spi_8bit_board_info; + timberdale_xspi_platform_data.num_devices = +ARRAY_SIZE (timberdale_spi_8bit_board_info); + }else { + timberdale_xspi_platform_data.bits_per_word =16 ; + timberdale_xspi_platform_data.devices = + timberdale_spi_16bit_board_info; + timberdale_xspi_platform_data.num_devices = +ARRAY_SIZE (timberdale_spi_16bit_board_info); + } + + err =mfd_add_devices (&dev->dev,0 , + timberdale_cells_bar0,ARRAY_SIZE (timberdale_cells_bar0), + &dev->resource[0 ], priv->irq_base); +if (err) { +printk (KERN_WARNING +"timberdale: mfd_add_devices failed: %d\n" , err); + goto err_mfd; + } + + err =mfd_add_devices (&dev->dev,1 , + timberdale_cells_bar1,ARRAY_SIZE (timberdale_cells_bar1), + &dev->resource[1 ], priv->irq_base); +if (err) { +printk (KERN_WARNING +"timberdale: mfd_add_devices failed: %d\n" , err); + goto err_mfd2; + } + + err =mfd_add_devices (&dev->dev,2 , + timberdale_cells_bar2,ARRAY_SIZE (timberdale_cells_bar2), + &dev->resource[2 ], priv->irq_base); +if (err) { +printk (KERN_WARNING +"timberdale: mfd_add_devices failed: %d\n" , err); + goto err_mfd2; + } + +printk (KERN_INFO +"Found Timberdale Card. Rev: %d.%d, HW config: 0x%02x\n" , +ioread32 (priv->ctl_membase +TIMB_REV_MAJOR ), +ioread32 (priv->ctl_membase +TIMB_REV_MINOR ), hw_config); + +/* Enable interrupts and wire the hardware interrupts */ +iowrite32 (0x3 , priv->intc_membase +MER ); + +return 0 ; + +err_mfd2: +mfd_remove_devices (&dev->dev); +err_mfd: +timberdale_detach_irq (dev); +pci_disable_msi (dev); +err_msi: +iounmap (priv->ctl_membase); +err_ioremap_ctl: +iounmap (priv->intc_membase); +err_ioremap: +release_mem_region (priv->ctl_mapbase,CHIPCTLSIZE ); +err_request_ctl: +release_mem_region (priv->intc_mapbase,INTCSIZE ); +err_request: +pci_set_drvdata (dev,NULL ); +err_start: +pci_disable_device (dev); +err_enable: +kfree (priv); +pci_set_drvdata (dev,NULL ); +return -ENODEV ; +} + +static void __devexit timb_remove(struct pci_dev *dev) +{ +/* clean up any allocated resources and stuff here. +* like call release_region(); +*/ +struct timberdale_device *priv; + + priv =pci_get_drvdata (dev); + +mfd_remove_devices (&dev->dev); + +timberdale_detach_irq (dev); + +iowrite32 (0xffffffff , priv->intc_membase +IAR ); +iowrite32 (0 , priv->intc_membase +MER ); +iowrite32 (0 , priv->intc_membase +IER ); + +iounmap (priv->ctl_membase); +iounmap (priv->intc_membase); +release_mem_region (priv->ctl_mapbase,CHIPCTLSIZE ); +release_mem_region (priv->intc_mapbase,INTCSIZE ); + +pci_disable_msi (dev); +pci_disable_device (dev); +pci_set_drvdata (dev,NULL ); +kfree (priv); +} + +static struct pci_device_id timberdale_pci_tbl[] = { + {PCI_DEVICE (PCI_VENDOR_ID_TIMB ,PCI_DEVICE_ID_TIMB ) }, + {0 } +}; +MODULE_DEVICE_TABLE (pci, timberdale_pci_tbl); + +static struct pci_driver timberdale_pci_driver = { + .name ="timberdale" , + .id_table = timberdale_pci_tbl, + .probe = timb_probe, + .remove = timb_remove, +}; + +static int __init timberdale_init (void ) +{ +int err; + + err =pci_register_driver (&timberdale_pci_driver); +if (err <0 ) { +printk (KERN_ERR +"Failed to register PCI driver for %s device.\n" , + timberdale_pci_driver.name); +return -ENODEV ; + } + +printk (KERN_INFO "Driver for %s has been successfully registered.\n" , + timberdale_pci_driver.name); + +return 0 ; +} + +static void __exit timberdale_exit(void) +{ +pci_unregister_driver (&timberdale_pci_driver); + +printk (KERN_INFO "Driver for %s has been successfully unregistered.\n" , + timberdale_pci_driver.name); +} + +module_init (timberdale_init); +module_exit (timberdale_exit); + +MODULE_AUTHOR ("Mocean Laboratories <[email protected]>" ); +MODULE_VERSION (DRV_VERSION ); +MODULE_LICENSE ("GPL v2" ); +Index:
linux-2.6.30-rc7/drivers/mfd/timberdale.h
===================================================================drivers/mfd/timberdale.h +123
-0@@ -0,0 +1,123 @@ +/* +* timberdale.h timberdale FPGA mfd shim driver defines +* Copyright (c) 2009 Intel Corporation +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +* 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* Supports: +* Timberdale FPGA +*/ + +#ifndef MFD_TIMBERDALE_H +#define MFD_TIMBERDALE_H + +/* Registers of the interrupt controller */ +#define ISR 0x00 +#define IPR 0x04 +#define IER 0x08 +#define IAR 0x0c +#define SIE 0x10 +#define CIE 0x14 +#define MER 0x1c + +/* Registers of the control area */ +#define TIMB_REV_MAJOR 0x00 +#define TIMB_REV_MINOR 0x04 +#define TIMB_HW_CONFIG 0x08 +#define MAYSVILLERST 0x40 + +/* bits in the TIMB_HW_CONFIG register */ +#define TIMB_HW_CONFIG_SPI_8BIT 0x80 + +#define I2COFFSET 0x0 +#define I2CEND 0x1f + +#define SPIOFFSET 0x80 +#define SPIEND 0xff + +#define ETHOFFSET 0x300 +#define ETHEND 0x3ff + +#define GPIOOFFSET 0x400 +#define GPIOEND 0x7ff + +#define CHIPCTLOFFSET 0x800 +#define CHIPCTLEND 0x8ff +#define CHIPCTLSIZE (CHIPCTLEND - CHIPCTLOFFSET) + +#define INTCOFFSET 0xc00 +#define INTCEND 0xfff +#define INTCSIZE (INTCEND - INTCOFFSET) + +#define MOSTOFFSET 0x1000 +#define MOSTEND 0x13ff + +#define UARTOFFSET 0x1400 +#define UARTEND 0x17ff + +#define I2SOFFSET 0x1C00 +#define I2SEND 0x1fff + +#define LOGIWOFFSET 0x30000 +#define LOGIWEND 0x37fff + +#define DMAOFFSET 0x01000000 +#define DMAEND 0x013fffff + +/* SDHC0 is placed in PCI bar 1 */ +#define SDHC0OFFSET 0x00 +#define SDHC0END 0xff + +/* SDHC1 is placed in PCI bar 2 */ +#define SDHC1OFFSET 0x00 +#define SDHC1END 0xff + +#define PCI_VENDOR_ID_TIMB 0x10ee +#define PCI_DEVICE_ID_TIMB 0xa123 +#define DRV_VERSION "0.1" + + +#define IRQ_TIMBERDALE_INIC 0 +#define IRQ_TIMBERDALE_MLB 1 +#define IRQ_TIMBERDALE_GPIO 2 +#define IRQ_TIMBERDALE_I2C 3 +#define IRQ_TIMBERDALE_UART 4 +#define IRQ_TIMBERDALE_DMA 5 +#define IRQ_TIMBERDALE_I2S 6 +#define IRQ_TIMBERDALE_TSC_INT 7 +#define IRQ_TIMBERDALE_SDHC 8 +#define IRQ_TIMBERDALE_ADV7180 9 +#define IRQ_TIMBERDALE_ETHSW_IF 10 +#define IRQ_TIMBERDALE_SPI 11 + +#define TIMBERDALE_NR_IRQS 12 + +/* Some of the interrupts are level triggered, some are edge triggered */ +#define IRQ_TIMBERDALE_EDGE_MASK ((1 << IRQ_TIMBERDALE_ADV7180) | \ + (1 << IRQ_TIMBERDALE_TSC_INT) | \ + (1 << IRQ_TIMBERDALE_MLB) | (1 << IRQ_TIMBERDALE_INIC)) + +#define IRQ_TIMBERDALE_LEVEL_MASK ((1 << IRQ_TIMBERDALE_SPI) | \ + (1 << IRQ_TIMBERDALE_ETHSW_IF) | (1 << IRQ_TIMBERDALE_SDHC) | \ + (1 << IRQ_TIMBERDALE_I2S) | (1 << IRQ_TIMBERDALE_UART) | \ + (1 << IRQ_TIMBERDALE_I2C) | (1 << IRQ_TIMBERDALE_GPIO) | \ + (1 << IRQ_TIMBERDALE_DMA)) + +#define GPIO_PIN_INIC_RST 14 +#define GPIO_PIN_BT_RST 15 + + +#endif +Index: linux-2.6.30-rc7/drivers/mfd/Makefile
===================================================================drivers/mfd/Makefile +1
-0@@ -42,4 +42,5 @@ obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o +obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o obj-$(CONFIG_MFD_TIMBERDALE_DMA) += timbdma.o
Signature · 2 lines
Intel Open Source Technology Centre http://oss.intel.com/
Quoted 14 lines · On Mon, 15 Jun 2009 12:11:19 +0200 Samuel Ortiz <[email protected]> wrote:
Quoted 9 lines · Richard R__jfors
MFD driver for the Timberdale FPGA The FPGA can be found on the Intel Atom development board, Russellville for in-vechicle infotainment
The FPGA is connected via PCIe
The driver basically exposes a lot of platform devices for the different IPs within the FPGA, and doing IRQ multiplexing
Signed-off-by Richard R__jfors <[email protected]>patch #4 of this serie is an mfd driver too, so I guess I should have been cc'ed on it too.
So, if I understand this thread correctly, we should proceed like that:
Quoted 6 lines
1) Richard comes up with an updated xilinx patch (patch #2).
2) Andrew sends all patches but patch 7 to the relevant maintainers.
3) When all patches but 7 are in Linus tree, I take patch 7 and include it in my pull request to Linus.Andrew, does that make sense to you? Do you want me to take patch #4 as well?
We could do it that way. Or maintainers could just review-and-ack the relevant patches and I could merge them.
Samuel Ortiz
Acked-byQuoted 21 lines · Andrew Morton
Quoted 19 lines · On Mon, 15 Jun 2009 12:11:19 +0200 Samuel Ortiz <[email protected]> wrote:
Quoted 9 lines · Richard R__jfors
MFD driver for the Timberdale FPGA The FPGA can be found on the Intel Atom development board, Russellville for in-vechicle infotainment
The FPGA is connected via PCIe
The driver basically exposes a lot of platform devices for the different IPs within the FPGA, and doing IRQ multiplexing
Signed-off-by Richard R__jfors <[email protected]>patch #4 of this serie is an mfd driver too, so I guess I should have been cc'ed on it too.
So, if I understand this thread correctly, we should proceed like that:1) Richard comes up with an updated xilinx patch (patch #2).
2) Andrew sends all patches but patch 7 to the relevant maintainers.
3) When all patches but 7 are in Linus tree, I take patch 7 and include it in my pull request to Linus.
Quoted 4 lines
Quoted 1 line
Andrew, does that make sense to you? Do you want me to take patch #4 as well?
We could do it that way. Or maintainers could just review-and-ack the relevant patches and I could merge them.
If the latter is more convenient to you, then feel free to add my
Cheers,
Samuel.
Signature · 2 lines
Intel Open Source Technology Centre http://oss.intel.com/