Path: blob/master/drivers/misc/carma/carma-fpga-program.c
15111 views
/*1* CARMA Board DATA-FPGA Programmer2*3* Copyright (c) 2009-2011 Ira W. Snyder <[email protected]>4*5* This program is free software; you can redistribute it and/or modify it6* under the terms of the GNU General Public License as published by the7* Free Software Foundation; either version 2 of the License, or (at your8* option) any later version.9*/1011#include <linux/dma-mapping.h>12#include <linux/of_platform.h>13#include <linux/completion.h>14#include <linux/miscdevice.h>15#include <linux/dmaengine.h>16#include <linux/interrupt.h>17#include <linux/highmem.h>18#include <linux/kernel.h>19#include <linux/module.h>20#include <linux/mutex.h>21#include <linux/delay.h>22#include <linux/init.h>23#include <linux/leds.h>24#include <linux/slab.h>25#include <linux/kref.h>26#include <linux/fs.h>27#include <linux/io.h>2829#include <media/videobuf-dma-sg.h>3031/* MPC8349EMDS specific get_immrbase() */32#include <sysdev/fsl_soc.h>3334static const char drv_name[] = "carma-fpga-program";3536/*37* Firmware images are always this exact size38*39* 12849552 bytes for a CARMA Digitizer Board (EP2S90 FPGAs)40* 18662880 bytes for a CARMA Correlator Board (EP2S130 FPGAs)41*/42#define FW_SIZE_EP2S90 1284955243#define FW_SIZE_EP2S130 186628804445struct fpga_dev {46struct miscdevice miscdev;4748/* Reference count */49struct kref ref;5051/* Device Registers */52struct device *dev;53void __iomem *regs;54void __iomem *immr;5556/* Freescale DMA Device */57struct dma_chan *chan;5859/* Interrupts */60int irq, status;61struct completion completion;6263/* FPGA Bitfile */64struct mutex lock;6566struct videobuf_dmabuf vb;67bool vb_allocated;6869/* max size and written bytes */70size_t fw_size;71size_t bytes;72};7374/*75* FPGA Bitfile Helpers76*/7778/**79* fpga_drop_firmware_data() - drop the bitfile image from memory80* @priv: the driver's private data structure81*82* LOCKING: must hold priv->lock83*/84static void fpga_drop_firmware_data(struct fpga_dev *priv)85{86videobuf_dma_free(&priv->vb);87priv->vb_allocated = false;88priv->bytes = 0;89}9091/*92* Private Data Reference Count93*/9495static void fpga_dev_remove(struct kref *ref)96{97struct fpga_dev *priv = container_of(ref, struct fpga_dev, ref);9899/* free any firmware image that was not programmed */100fpga_drop_firmware_data(priv);101102mutex_destroy(&priv->lock);103kfree(priv);104}105106/*107* LED Trigger (could be a seperate module)108*/109110/*111* NOTE: this whole thing does have the problem that whenever the led's are112* NOTE: first set to use the fpga trigger, they could be in the wrong state113*/114115DEFINE_LED_TRIGGER(ledtrig_fpga);116117static void ledtrig_fpga_programmed(bool enabled)118{119if (enabled)120led_trigger_event(ledtrig_fpga, LED_FULL);121else122led_trigger_event(ledtrig_fpga, LED_OFF);123}124125/*126* FPGA Register Helpers127*/128129/* Register Definitions */130#define FPGA_CONFIG_CONTROL 0x40131#define FPGA_CONFIG_STATUS 0x44132#define FPGA_CONFIG_FIFO_SIZE 0x48133#define FPGA_CONFIG_FIFO_USED 0x4C134#define FPGA_CONFIG_TOTAL_BYTE_COUNT 0x50135#define FPGA_CONFIG_CUR_BYTE_COUNT 0x54136137#define FPGA_FIFO_ADDRESS 0x3000138139static int fpga_fifo_size(void __iomem *regs)140{141return ioread32be(regs + FPGA_CONFIG_FIFO_SIZE);142}143144#define CFG_STATUS_ERR_MASK 0xfffe145146static int fpga_config_error(void __iomem *regs)147{148return ioread32be(regs + FPGA_CONFIG_STATUS) & CFG_STATUS_ERR_MASK;149}150151static int fpga_fifo_empty(void __iomem *regs)152{153return ioread32be(regs + FPGA_CONFIG_FIFO_USED) == 0;154}155156static void fpga_fifo_write(void __iomem *regs, u32 val)157{158iowrite32be(val, regs + FPGA_FIFO_ADDRESS);159}160161static void fpga_set_byte_count(void __iomem *regs, u32 count)162{163iowrite32be(count, regs + FPGA_CONFIG_TOTAL_BYTE_COUNT);164}165166#define CFG_CTL_ENABLE (1 << 0)167#define CFG_CTL_RESET (1 << 1)168#define CFG_CTL_DMA (1 << 2)169170static void fpga_programmer_enable(struct fpga_dev *priv, bool dma)171{172u32 val;173174val = (dma) ? (CFG_CTL_ENABLE | CFG_CTL_DMA) : CFG_CTL_ENABLE;175iowrite32be(val, priv->regs + FPGA_CONFIG_CONTROL);176}177178static void fpga_programmer_disable(struct fpga_dev *priv)179{180iowrite32be(0x0, priv->regs + FPGA_CONFIG_CONTROL);181}182183static void fpga_dump_registers(struct fpga_dev *priv)184{185u32 control, status, size, used, total, curr;186187/* good status: do nothing */188if (priv->status == 0)189return;190191/* Dump all status registers */192control = ioread32be(priv->regs + FPGA_CONFIG_CONTROL);193status = ioread32be(priv->regs + FPGA_CONFIG_STATUS);194size = ioread32be(priv->regs + FPGA_CONFIG_FIFO_SIZE);195used = ioread32be(priv->regs + FPGA_CONFIG_FIFO_USED);196total = ioread32be(priv->regs + FPGA_CONFIG_TOTAL_BYTE_COUNT);197curr = ioread32be(priv->regs + FPGA_CONFIG_CUR_BYTE_COUNT);198199dev_err(priv->dev, "Configuration failed, dumping status registers\n");200dev_err(priv->dev, "Control: 0x%.8x\n", control);201dev_err(priv->dev, "Status: 0x%.8x\n", status);202dev_err(priv->dev, "FIFO Size: 0x%.8x\n", size);203dev_err(priv->dev, "FIFO Used: 0x%.8x\n", used);204dev_err(priv->dev, "FIFO Total: 0x%.8x\n", total);205dev_err(priv->dev, "FIFO Curr: 0x%.8x\n", curr);206}207208/*209* FPGA Power Supply Code210*/211212#define CTL_PWR_CONTROL 0x2006213#define CTL_PWR_STATUS 0x200A214#define CTL_PWR_FAIL 0x200B215216#define PWR_CONTROL_ENABLE 0x01217218#define PWR_STATUS_ERROR_MASK 0x10219#define PWR_STATUS_GOOD 0x0f220221/*222* Determine if the FPGA power is good for all supplies223*/224static bool fpga_power_good(struct fpga_dev *priv)225{226u8 val;227228val = ioread8(priv->regs + CTL_PWR_STATUS);229if (val & PWR_STATUS_ERROR_MASK)230return false;231232return val == PWR_STATUS_GOOD;233}234235/*236* Disable the FPGA power supplies237*/238static void fpga_disable_power_supplies(struct fpga_dev *priv)239{240unsigned long start;241u8 val;242243iowrite8(0x0, priv->regs + CTL_PWR_CONTROL);244245/*246* Wait 500ms for the power rails to discharge247*248* Without this delay, the CTL-CPLD state machine can get into a249* state where it is waiting for the power-goods to assert, but they250* never do. This only happens when enabling and disabling the251* power sequencer very rapidly.252*253* The loop below will also wait for the power goods to de-assert,254* but testing has shown that they are always disabled by the time255* the sleep completes. However, omitting the sleep and only waiting256* for the power-goods to de-assert was not sufficient to ensure257* that the power sequencer would not wedge itself.258*/259msleep(500);260261start = jiffies;262while (time_before(jiffies, start + HZ)) {263val = ioread8(priv->regs + CTL_PWR_STATUS);264if (!(val & PWR_STATUS_GOOD))265break;266267usleep_range(5000, 10000);268}269270val = ioread8(priv->regs + CTL_PWR_STATUS);271if (val & PWR_STATUS_GOOD) {272dev_err(priv->dev, "power disable failed: "273"power goods: status 0x%.2x\n", val);274}275276if (val & PWR_STATUS_ERROR_MASK) {277dev_err(priv->dev, "power disable failed: "278"alarm bit set: status 0x%.2x\n", val);279}280}281282/**283* fpga_enable_power_supplies() - enable the DATA-FPGA power supplies284* @priv: the driver's private data structure285*286* Enable the DATA-FPGA power supplies, waiting up to 1 second for287* them to enable successfully.288*289* Returns 0 on success, -ERRNO otherwise290*/291static int fpga_enable_power_supplies(struct fpga_dev *priv)292{293unsigned long start = jiffies;294295if (fpga_power_good(priv)) {296dev_dbg(priv->dev, "power was already good\n");297return 0;298}299300iowrite8(PWR_CONTROL_ENABLE, priv->regs + CTL_PWR_CONTROL);301while (time_before(jiffies, start + HZ)) {302if (fpga_power_good(priv))303return 0;304305usleep_range(5000, 10000);306}307308return fpga_power_good(priv) ? 0 : -ETIMEDOUT;309}310311/*312* Determine if the FPGA power supplies are all enabled313*/314static bool fpga_power_enabled(struct fpga_dev *priv)315{316u8 val;317318val = ioread8(priv->regs + CTL_PWR_CONTROL);319if (val & PWR_CONTROL_ENABLE)320return true;321322return false;323}324325/*326* Determine if the FPGA's are programmed and running correctly327*/328static bool fpga_running(struct fpga_dev *priv)329{330if (!fpga_power_good(priv))331return false;332333/* Check the config done bit */334return ioread32be(priv->regs + FPGA_CONFIG_STATUS) & (1 << 18);335}336337/*338* FPGA Programming Code339*/340341/**342* fpga_program_block() - put a block of data into the programmer's FIFO343* @priv: the driver's private data structure344* @buf: the data to program345* @count: the length of data to program (must be a multiple of 4 bytes)346*347* Returns 0 on success, -ERRNO otherwise348*/349static int fpga_program_block(struct fpga_dev *priv, void *buf, size_t count)350{351u32 *data = buf;352int size = fpga_fifo_size(priv->regs);353int i, len;354unsigned long timeout;355356/* enforce correct data length for the FIFO */357BUG_ON(count % 4 != 0);358359while (count > 0) {360361/* Get the size of the block to write (maximum is FIFO_SIZE) */362len = min_t(size_t, count, size);363timeout = jiffies + HZ / 4;364365/* Write the block */366for (i = 0; i < len / 4; i++)367fpga_fifo_write(priv->regs, data[i]);368369/* Update the amounts left */370count -= len;371data += len / 4;372373/* Wait for the fifo to empty */374while (true) {375376if (fpga_fifo_empty(priv->regs)) {377break;378} else {379dev_dbg(priv->dev, "Fifo not empty\n");380cpu_relax();381}382383if (fpga_config_error(priv->regs)) {384dev_err(priv->dev, "Error detected\n");385return -EIO;386}387388if (time_after(jiffies, timeout)) {389dev_err(priv->dev, "Fifo drain timeout\n");390return -ETIMEDOUT;391}392393usleep_range(5000, 10000);394}395}396397return 0;398}399400/**401* fpga_program_cpu() - program the DATA-FPGA's using the CPU402* @priv: the driver's private data structure403*404* This is useful when the DMA programming method fails. It is possible to405* wedge the Freescale DMA controller such that the DMA programming method406* always fails. This method has always succeeded.407*408* Returns 0 on success, -ERRNO otherwise409*/410static noinline int fpga_program_cpu(struct fpga_dev *priv)411{412int ret;413414/* Disable the programmer */415fpga_programmer_disable(priv);416417/* Set the total byte count */418fpga_set_byte_count(priv->regs, priv->bytes);419dev_dbg(priv->dev, "total byte count %u bytes\n", priv->bytes);420421/* Enable the controller for programming */422fpga_programmer_enable(priv, false);423dev_dbg(priv->dev, "enabled the controller\n");424425/* Write each chunk of the FPGA bitfile to FPGA programmer */426ret = fpga_program_block(priv, priv->vb.vaddr, priv->bytes);427if (ret)428goto out_disable_controller;429430/* Wait for the interrupt handler to signal that programming finished */431ret = wait_for_completion_timeout(&priv->completion, 2 * HZ);432if (!ret) {433dev_err(priv->dev, "Timed out waiting for completion\n");434ret = -ETIMEDOUT;435goto out_disable_controller;436}437438/* Retrieve the status from the interrupt handler */439ret = priv->status;440441out_disable_controller:442fpga_programmer_disable(priv);443return ret;444}445446#define FIFO_DMA_ADDRESS 0xf0003000447#define FIFO_MAX_LEN 4096448449/**450* fpga_program_dma() - program the DATA-FPGA's using the DMA engine451* @priv: the driver's private data structure452*453* Program the DATA-FPGA's using the Freescale DMA engine. This requires that454* the engine is programmed such that the hardware DMA request lines can455* control the entire DMA transaction. The system controller FPGA then456* completely offloads the programming from the CPU.457*458* Returns 0 on success, -ERRNO otherwise459*/460static noinline int fpga_program_dma(struct fpga_dev *priv)461{462struct videobuf_dmabuf *vb = &priv->vb;463struct dma_chan *chan = priv->chan;464struct dma_async_tx_descriptor *tx;465size_t num_pages, len, avail = 0;466struct dma_slave_config config;467struct scatterlist *sg;468struct sg_table table;469dma_cookie_t cookie;470int ret, i;471472/* Disable the programmer */473fpga_programmer_disable(priv);474475/* Allocate a scatterlist for the DMA destination */476num_pages = DIV_ROUND_UP(priv->bytes, FIFO_MAX_LEN);477ret = sg_alloc_table(&table, num_pages, GFP_KERNEL);478if (ret) {479dev_err(priv->dev, "Unable to allocate dst scatterlist\n");480ret = -ENOMEM;481goto out_return;482}483484/*485* This is an ugly hack486*487* We fill in a scatterlist as if it were mapped for DMA. This is488* necessary because there exists no better structure for this489* inside the kernel code.490*491* As an added bonus, we can use the DMAEngine API for all of this,492* rather than inventing another extremely similar API.493*/494avail = priv->bytes;495for_each_sg(table.sgl, sg, num_pages, i) {496len = min_t(size_t, avail, FIFO_MAX_LEN);497sg_dma_address(sg) = FIFO_DMA_ADDRESS;498sg_dma_len(sg) = len;499500avail -= len;501}502503/* Map the buffer for DMA */504ret = videobuf_dma_map(priv->dev, &priv->vb);505if (ret) {506dev_err(priv->dev, "Unable to map buffer for DMA\n");507goto out_free_table;508}509510/*511* Configure the DMA channel to transfer FIFO_SIZE / 2 bytes per512* transaction, and then put it under external control513*/514memset(&config, 0, sizeof(config));515config.direction = DMA_TO_DEVICE;516config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;517config.dst_maxburst = fpga_fifo_size(priv->regs) / 2 / 4;518ret = chan->device->device_control(chan, DMA_SLAVE_CONFIG,519(unsigned long)&config);520if (ret) {521dev_err(priv->dev, "DMA slave configuration failed\n");522goto out_dma_unmap;523}524525ret = chan->device->device_control(chan, FSLDMA_EXTERNAL_START, 1);526if (ret) {527dev_err(priv->dev, "DMA external control setup failed\n");528goto out_dma_unmap;529}530531/* setup and submit the DMA transaction */532tx = chan->device->device_prep_dma_sg(chan,533table.sgl, num_pages,534vb->sglist, vb->sglen, 0);535if (!tx) {536dev_err(priv->dev, "Unable to prep DMA transaction\n");537ret = -ENOMEM;538goto out_dma_unmap;539}540541cookie = tx->tx_submit(tx);542if (dma_submit_error(cookie)) {543dev_err(priv->dev, "Unable to submit DMA transaction\n");544ret = -ENOMEM;545goto out_dma_unmap;546}547548dma_async_memcpy_issue_pending(chan);549550/* Set the total byte count */551fpga_set_byte_count(priv->regs, priv->bytes);552dev_dbg(priv->dev, "total byte count %u bytes\n", priv->bytes);553554/* Enable the controller for DMA programming */555fpga_programmer_enable(priv, true);556dev_dbg(priv->dev, "enabled the controller\n");557558/* Wait for the interrupt handler to signal that programming finished */559ret = wait_for_completion_timeout(&priv->completion, 2 * HZ);560if (!ret) {561dev_err(priv->dev, "Timed out waiting for completion\n");562ret = -ETIMEDOUT;563goto out_disable_controller;564}565566/* Retrieve the status from the interrupt handler */567ret = priv->status;568569out_disable_controller:570fpga_programmer_disable(priv);571out_dma_unmap:572videobuf_dma_unmap(priv->dev, vb);573out_free_table:574sg_free_table(&table);575out_return:576return ret;577}578579/*580* Interrupt Handling581*/582583static irqreturn_t fpga_irq(int irq, void *dev_id)584{585struct fpga_dev *priv = dev_id;586587/* Save the status */588priv->status = fpga_config_error(priv->regs) ? -EIO : 0;589dev_dbg(priv->dev, "INTERRUPT status %d\n", priv->status);590fpga_dump_registers(priv);591592/* Disabling the programmer clears the interrupt */593fpga_programmer_disable(priv);594595/* Notify any waiters */596complete(&priv->completion);597598return IRQ_HANDLED;599}600601/*602* SYSFS Helpers603*/604605/**606* fpga_do_stop() - deconfigure (reset) the DATA-FPGA's607* @priv: the driver's private data structure608*609* LOCKING: must hold priv->lock610*/611static int fpga_do_stop(struct fpga_dev *priv)612{613u32 val;614615/* Set the led to unprogrammed */616ledtrig_fpga_programmed(false);617618/* Pulse the config line to reset the FPGA's */619val = CFG_CTL_ENABLE | CFG_CTL_RESET;620iowrite32be(val, priv->regs + FPGA_CONFIG_CONTROL);621iowrite32be(0x0, priv->regs + FPGA_CONFIG_CONTROL);622623return 0;624}625626static noinline int fpga_do_program(struct fpga_dev *priv)627{628int ret;629630if (priv->bytes != priv->fw_size) {631dev_err(priv->dev, "Incorrect bitfile size: got %zu bytes, "632"should be %zu bytes\n",633priv->bytes, priv->fw_size);634return -EINVAL;635}636637if (!fpga_power_enabled(priv)) {638dev_err(priv->dev, "Power not enabled\n");639return -EINVAL;640}641642if (!fpga_power_good(priv)) {643dev_err(priv->dev, "Power not good\n");644return -EINVAL;645}646647/* Set the LED to unprogrammed */648ledtrig_fpga_programmed(false);649650/* Try to program the FPGA's using DMA */651ret = fpga_program_dma(priv);652653/* If DMA failed or doesn't exist, try with CPU */654if (ret) {655dev_warn(priv->dev, "Falling back to CPU programming\n");656ret = fpga_program_cpu(priv);657}658659if (ret) {660dev_err(priv->dev, "Unable to program FPGA's\n");661return ret;662}663664/* Drop the firmware bitfile from memory */665fpga_drop_firmware_data(priv);666667dev_dbg(priv->dev, "FPGA programming successful\n");668ledtrig_fpga_programmed(true);669670return 0;671}672673/*674* File Operations675*/676677static int fpga_open(struct inode *inode, struct file *filp)678{679/*680* The miscdevice layer puts our struct miscdevice into the681* filp->private_data field. We use this to find our private682* data and then overwrite it with our own private structure.683*/684struct fpga_dev *priv = container_of(filp->private_data,685struct fpga_dev, miscdev);686unsigned int nr_pages;687int ret;688689/* We only allow one process at a time */690ret = mutex_lock_interruptible(&priv->lock);691if (ret)692return ret;693694filp->private_data = priv;695kref_get(&priv->ref);696697/* Truncation: drop any existing data */698if (filp->f_flags & O_TRUNC)699priv->bytes = 0;700701/* Check if we have already allocated a buffer */702if (priv->vb_allocated)703return 0;704705/* Allocate a buffer to hold enough data for the bitfile */706nr_pages = DIV_ROUND_UP(priv->fw_size, PAGE_SIZE);707ret = videobuf_dma_init_kernel(&priv->vb, DMA_TO_DEVICE, nr_pages);708if (ret) {709dev_err(priv->dev, "unable to allocate data buffer\n");710mutex_unlock(&priv->lock);711kref_put(&priv->ref, fpga_dev_remove);712return ret;713}714715priv->vb_allocated = true;716return 0;717}718719static int fpga_release(struct inode *inode, struct file *filp)720{721struct fpga_dev *priv = filp->private_data;722723mutex_unlock(&priv->lock);724kref_put(&priv->ref, fpga_dev_remove);725return 0;726}727728static ssize_t fpga_write(struct file *filp, const char __user *buf,729size_t count, loff_t *f_pos)730{731struct fpga_dev *priv = filp->private_data;732733/* FPGA bitfiles have an exact size: disallow anything else */734if (priv->bytes >= priv->fw_size)735return -ENOSPC;736737count = min_t(size_t, priv->fw_size - priv->bytes, count);738if (copy_from_user(priv->vb.vaddr + priv->bytes, buf, count))739return -EFAULT;740741priv->bytes += count;742return count;743}744745static ssize_t fpga_read(struct file *filp, char __user *buf, size_t count,746loff_t *f_pos)747{748struct fpga_dev *priv = filp->private_data;749750count = min_t(size_t, priv->bytes - *f_pos, count);751if (copy_to_user(buf, priv->vb.vaddr + *f_pos, count))752return -EFAULT;753754*f_pos += count;755return count;756}757758static loff_t fpga_llseek(struct file *filp, loff_t offset, int origin)759{760struct fpga_dev *priv = filp->private_data;761loff_t newpos;762763/* only read-only opens are allowed to seek */764if ((filp->f_flags & O_ACCMODE) != O_RDONLY)765return -EINVAL;766767switch (origin) {768case SEEK_SET: /* seek relative to the beginning of the file */769newpos = offset;770break;771case SEEK_CUR: /* seek relative to current position in the file */772newpos = filp->f_pos + offset;773break;774case SEEK_END: /* seek relative to the end of the file */775newpos = priv->fw_size - offset;776break;777default:778return -EINVAL;779}780781/* check for sanity */782if (newpos > priv->fw_size)783return -EINVAL;784785filp->f_pos = newpos;786return newpos;787}788789static const struct file_operations fpga_fops = {790.open = fpga_open,791.release = fpga_release,792.write = fpga_write,793.read = fpga_read,794.llseek = fpga_llseek,795};796797/*798* Device Attributes799*/800801static ssize_t pfail_show(struct device *dev, struct device_attribute *attr,802char *buf)803{804struct fpga_dev *priv = dev_get_drvdata(dev);805u8 val;806807val = ioread8(priv->regs + CTL_PWR_FAIL);808return snprintf(buf, PAGE_SIZE, "0x%.2x\n", val);809}810811static ssize_t pgood_show(struct device *dev, struct device_attribute *attr,812char *buf)813{814struct fpga_dev *priv = dev_get_drvdata(dev);815return snprintf(buf, PAGE_SIZE, "%d\n", fpga_power_good(priv));816}817818static ssize_t penable_show(struct device *dev, struct device_attribute *attr,819char *buf)820{821struct fpga_dev *priv = dev_get_drvdata(dev);822return snprintf(buf, PAGE_SIZE, "%d\n", fpga_power_enabled(priv));823}824825static ssize_t penable_store(struct device *dev, struct device_attribute *attr,826const char *buf, size_t count)827{828struct fpga_dev *priv = dev_get_drvdata(dev);829unsigned long val;830int ret;831832if (strict_strtoul(buf, 0, &val))833return -EINVAL;834835if (val) {836ret = fpga_enable_power_supplies(priv);837if (ret)838return ret;839} else {840fpga_do_stop(priv);841fpga_disable_power_supplies(priv);842}843844return count;845}846847static ssize_t program_show(struct device *dev, struct device_attribute *attr,848char *buf)849{850struct fpga_dev *priv = dev_get_drvdata(dev);851return snprintf(buf, PAGE_SIZE, "%d\n", fpga_running(priv));852}853854static ssize_t program_store(struct device *dev, struct device_attribute *attr,855const char *buf, size_t count)856{857struct fpga_dev *priv = dev_get_drvdata(dev);858unsigned long val;859int ret;860861if (strict_strtoul(buf, 0, &val))862return -EINVAL;863864/* We can't have an image writer and be programming simultaneously */865if (mutex_lock_interruptible(&priv->lock))866return -ERESTARTSYS;867868/* Program or Reset the FPGA's */869ret = val ? fpga_do_program(priv) : fpga_do_stop(priv);870if (ret)871goto out_unlock;872873/* Success */874ret = count;875876out_unlock:877mutex_unlock(&priv->lock);878return ret;879}880881static DEVICE_ATTR(power_fail, S_IRUGO, pfail_show, NULL);882static DEVICE_ATTR(power_good, S_IRUGO, pgood_show, NULL);883static DEVICE_ATTR(power_enable, S_IRUGO | S_IWUSR,884penable_show, penable_store);885886static DEVICE_ATTR(program, S_IRUGO | S_IWUSR,887program_show, program_store);888889static struct attribute *fpga_attributes[] = {890&dev_attr_power_fail.attr,891&dev_attr_power_good.attr,892&dev_attr_power_enable.attr,893&dev_attr_program.attr,894NULL,895};896897static const struct attribute_group fpga_attr_group = {898.attrs = fpga_attributes,899};900901/*902* OpenFirmware Device Subsystem903*/904905#define SYS_REG_VERSION 0x00906#define SYS_REG_GEOGRAPHIC 0x10907908static bool dma_filter(struct dma_chan *chan, void *data)909{910/*911* DMA Channel #0 is the only acceptable device912*913* This probably won't survive an unload/load cycle of the Freescale914* DMAEngine driver, but that won't be a problem915*/916return chan->chan_id == 0 && chan->device->dev_id == 0;917}918919static int fpga_of_remove(struct platform_device *op)920{921struct fpga_dev *priv = dev_get_drvdata(&op->dev);922struct device *this_device = priv->miscdev.this_device;923924sysfs_remove_group(&this_device->kobj, &fpga_attr_group);925misc_deregister(&priv->miscdev);926927free_irq(priv->irq, priv);928irq_dispose_mapping(priv->irq);929930/* make sure the power supplies are off */931fpga_disable_power_supplies(priv);932933/* unmap registers */934iounmap(priv->immr);935iounmap(priv->regs);936937dma_release_channel(priv->chan);938939/* drop our reference to the private data structure */940kref_put(&priv->ref, fpga_dev_remove);941return 0;942}943944/* CTL-CPLD Version Register */945#define CTL_CPLD_VERSION 0x2000946947static int fpga_of_probe(struct platform_device *op,948const struct of_device_id *match)949{950struct device_node *of_node = op->dev.of_node;951struct device *this_device;952struct fpga_dev *priv;953dma_cap_mask_t mask;954u32 ver;955int ret;956957/* Allocate private data */958priv = kzalloc(sizeof(*priv), GFP_KERNEL);959if (!priv) {960dev_err(&op->dev, "Unable to allocate private data\n");961ret = -ENOMEM;962goto out_return;963}964965/* Setup the miscdevice */966priv->miscdev.minor = MISC_DYNAMIC_MINOR;967priv->miscdev.name = drv_name;968priv->miscdev.fops = &fpga_fops;969970kref_init(&priv->ref);971972dev_set_drvdata(&op->dev, priv);973priv->dev = &op->dev;974mutex_init(&priv->lock);975init_completion(&priv->completion);976videobuf_dma_init(&priv->vb);977978dev_set_drvdata(priv->dev, priv);979dma_cap_zero(mask);980dma_cap_set(DMA_MEMCPY, mask);981dma_cap_set(DMA_INTERRUPT, mask);982dma_cap_set(DMA_SLAVE, mask);983dma_cap_set(DMA_SG, mask);984985/* Get control of DMA channel #0 */986priv->chan = dma_request_channel(mask, dma_filter, NULL);987if (!priv->chan) {988dev_err(&op->dev, "Unable to acquire DMA channel #0\n");989ret = -ENODEV;990goto out_free_priv;991}992993/* Remap the registers for use */994priv->regs = of_iomap(of_node, 0);995if (!priv->regs) {996dev_err(&op->dev, "Unable to ioremap registers\n");997ret = -ENOMEM;998goto out_dma_release_channel;999}10001001/* Remap the IMMR for use */1002priv->immr = ioremap(get_immrbase(), 0x100000);1003if (!priv->immr) {1004dev_err(&op->dev, "Unable to ioremap IMMR\n");1005ret = -ENOMEM;1006goto out_unmap_regs;1007}10081009/*1010* Check that external DMA is configured1011*1012* U-Boot does this for us, but we should check it and bail out if1013* there is a problem. Failing to have this register setup correctly1014* will cause the DMA controller to transfer a single cacheline1015* worth of data, then wedge itself.1016*/1017if ((ioread32be(priv->immr + 0x114) & 0xE00) != 0xE00) {1018dev_err(&op->dev, "External DMA control not configured\n");1019ret = -ENODEV;1020goto out_unmap_immr;1021}10221023/*1024* Check the CTL-CPLD version1025*1026* This driver uses the CTL-CPLD DATA-FPGA power sequencer, and we1027* don't want to run on any version of the CTL-CPLD that does not use1028* a compatible register layout.1029*1030* v2: changed register layout, added power sequencer1031* v3: added glitch filter on the i2c overcurrent/overtemp outputs1032*/1033ver = ioread8(priv->regs + CTL_CPLD_VERSION);1034if (ver != 0x02 && ver != 0x03) {1035dev_err(&op->dev, "CTL-CPLD is not version 0x02 or 0x03!\n");1036ret = -ENODEV;1037goto out_unmap_immr;1038}10391040/* Set the exact size that the firmware image should be */1041ver = ioread32be(priv->regs + SYS_REG_VERSION);1042priv->fw_size = (ver & (1 << 18)) ? FW_SIZE_EP2S130 : FW_SIZE_EP2S90;10431044/* Find the correct IRQ number */1045priv->irq = irq_of_parse_and_map(of_node, 0);1046if (priv->irq == NO_IRQ) {1047dev_err(&op->dev, "Unable to find IRQ line\n");1048ret = -ENODEV;1049goto out_unmap_immr;1050}10511052/* Request the IRQ */1053ret = request_irq(priv->irq, fpga_irq, IRQF_SHARED, drv_name, priv);1054if (ret) {1055dev_err(&op->dev, "Unable to request IRQ %d\n", priv->irq);1056ret = -ENODEV;1057goto out_irq_dispose_mapping;1058}10591060/* Reset and stop the FPGA's, just in case */1061fpga_do_stop(priv);10621063/* Register the miscdevice */1064ret = misc_register(&priv->miscdev);1065if (ret) {1066dev_err(&op->dev, "Unable to register miscdevice\n");1067goto out_free_irq;1068}10691070/* Create the sysfs files */1071this_device = priv->miscdev.this_device;1072dev_set_drvdata(this_device, priv);1073ret = sysfs_create_group(&this_device->kobj, &fpga_attr_group);1074if (ret) {1075dev_err(&op->dev, "Unable to create sysfs files\n");1076goto out_misc_deregister;1077}10781079dev_info(priv->dev, "CARMA FPGA Programmer: %s rev%s with %s FPGAs\n",1080(ver & (1 << 17)) ? "Correlator" : "Digitizer",1081(ver & (1 << 16)) ? "B" : "A",1082(ver & (1 << 18)) ? "EP2S130" : "EP2S90");10831084return 0;10851086out_misc_deregister:1087misc_deregister(&priv->miscdev);1088out_free_irq:1089free_irq(priv->irq, priv);1090out_irq_dispose_mapping:1091irq_dispose_mapping(priv->irq);1092out_unmap_immr:1093iounmap(priv->immr);1094out_unmap_regs:1095iounmap(priv->regs);1096out_dma_release_channel:1097dma_release_channel(priv->chan);1098out_free_priv:1099kref_put(&priv->ref, fpga_dev_remove);1100out_return:1101return ret;1102}11031104static struct of_device_id fpga_of_match[] = {1105{ .compatible = "carma,fpga-programmer", },1106{},1107};11081109static struct of_platform_driver fpga_of_driver = {1110.probe = fpga_of_probe,1111.remove = fpga_of_remove,1112.driver = {1113.name = drv_name,1114.of_match_table = fpga_of_match,1115.owner = THIS_MODULE,1116},1117};11181119/*1120* Module Init / Exit1121*/11221123static int __init fpga_init(void)1124{1125led_trigger_register_simple("fpga", &ledtrig_fpga);1126return of_register_platform_driver(&fpga_of_driver);1127}11281129static void __exit fpga_exit(void)1130{1131of_unregister_platform_driver(&fpga_of_driver);1132led_trigger_unregister_simple(ledtrig_fpga);1133}11341135MODULE_AUTHOR("Ira W. Snyder <[email protected]>");1136MODULE_DESCRIPTION("CARMA Board DATA-FPGA Programmer");1137MODULE_LICENSE("GPL");11381139module_init(fpga_init);1140module_exit(fpga_exit);114111421143