]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
staging: apf: Enable MPSoC SG-DMA and removed clock control
authorMichael Gill <michael.gill@xilinx.com>
Fri, 20 May 2016 19:40:05 +0000 (12:40 -0700)
committerMichal Simek <michal.simek@xilinx.com>
Wed, 1 Jun 2016 11:34:39 +0000 (13:34 +0200)
This patch enables preliminary scatter-gather support for the
apf DMA driver.  This extends only to memory allocated by a call
to sds_alloc, and dma_buf shared buffers.  Zynq support is
unchanged.  Additionally, control over clocks has been removed
due to clocks being correctly configured during petalinux
boot. There is no impact of this on a user.

Signed-off-by: Michael Gill <gill@xilinx.com>
Tested-by : Radhey Shyam Pandey <radheys@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/staging/apf/xilinx-dma-apf.c
drivers/staging/apf/xlnk-sysdef.h
drivers/staging/apf/xlnk.c
drivers/staging/apf/xlnk.h

index 708cdc91fd3738b0198b190eed98d64a1800883a..740d97022a440b8b58ee12f33c264c079a10c97b 100644 (file)
@@ -371,7 +371,7 @@ static void xdma_start_transfer(struct xdma_chan *chan,
                DMA_OUT(&chan->regs->tdr, tail_phys);
 #else
                DMA_OUT(&chan->regs->tdr, GET_LOW(tail_phys));
-               DMA_OUT(&chan->regs->tdr_hi, GET_HI(tail_phys));
+/*             DMA_OUT(&chan->regs->tdr_hi, GET_HI(tail_phys));*/
 #endif
                return;
        }
@@ -380,7 +380,7 @@ static void xdma_start_transfer(struct xdma_chan *chan,
        DMA_OUT(&chan->regs->cdr, cur_phys);
 #else
        DMA_OUT(&chan->regs->cdr, GET_LOW(cur_phys));
-       DMA_OUT(&chan->regs->cdr_hi, GET_HI(cur_phys));
+/*     DMA_OUT(&chan->regs->cdr_hi, GET_HI(cur_phys));*/
 #endif
 
        dma_start(chan);
@@ -396,7 +396,7 @@ static void xdma_start_transfer(struct xdma_chan *chan,
        DMA_OUT(&chan->regs->tdr, tail_phys);
 #else
        DMA_OUT(&chan->regs->tdr, GET_LOW(tail_phys));
-       DMA_OUT(&chan->regs->tdr_hi, GET_HI(tail_phys));
+/*     DMA_OUT(&chan->regs->tdr_hi, GET_HI(tail_phys));*/
 #endif
 }
 
@@ -417,7 +417,6 @@ static int xdma_setup_hw_desc(struct xdma_chan *chan,
        int status;
        unsigned long flags;
        unsigned int bd_used_saved;
-
        if (!chan)
                return -ENODEV;
 
@@ -509,7 +508,6 @@ static int xdma_setup_hw_desc(struct xdma_chan *chan,
        xdma_start_transfer(chan, start_index, end_index2);
 
        spin_unlock_irqrestore(&chan->lock, flags);
-
        return 0;
 
 out_clean:
@@ -800,7 +798,6 @@ int xdma_submit(struct xdma_chan *chan,
        int status;
        DEFINE_DMA_ATTRS(attrs);
 
-
        dmahead = kzalloc(sizeof(struct xdma_head), GFP_KERNEL);
        if (!dmahead)
                return -ENOMEM;
@@ -813,10 +810,6 @@ int xdma_submit(struct xdma_chan *chan,
        dmadir = chan->direction;
        if (dp) {
                if (!dp->is_mapped) {
-#if XLNK_SYS_BIT_WIDTH == 64
-                       return -EINVAL;
-#else
-
                        dp->dbuf_attach = dma_buf_attach(dp->dbuf, chan->dev);
                        dp->dbuf_sg_table = dma_buf_map_attachment(
                                dp->dbuf_attach, chan->direction);
@@ -827,7 +820,6 @@ int xdma_submit(struct xdma_chan *chan,
                                return -EINVAL;
                        }
                        dp->is_mapped = 1;
-#endif
                }
 
                sglist_dma = dp->dbuf_sg_table->sgl;
@@ -863,6 +855,10 @@ int xdma_submit(struct xdma_chan *chan,
 #endif
                }
        } else {
+#if XLNK_SYS_BIT_WIDTH == 64
+               pr_err("ERROR: MPSoC SG-DMA does not support malloc\n");
+               return -EFAULT;
+#else
                /* pin user pages is monitored separately */
                status = pin_user_pages((unsigned long)userbuf, size,
                                        dmadir != DMA_TO_DEVICE,
@@ -890,6 +886,7 @@ int xdma_submit(struct xdma_chan *chan,
                        unpin_user_pages(sglist, sgcnt);
                        return -ENOMEM;
                }
+#endif
        }
        dmahead->sglist = sglist;
        dmahead->sgcnt = sgcnt;
@@ -914,12 +911,10 @@ int xdma_submit(struct xdma_chan *chan,
                                                         sgcnt, dmadir, &attrs);
                        unpin_user_pages(sglist, sgcnt);
                }
-
                return -ENOMEM;
        }
 
        *dmaheadpp = dmahead;
-
        return 0;
 }
 EXPORT_SYMBOL(xdma_submit);
@@ -928,7 +923,6 @@ int xdma_wait(struct xdma_head *dmahead, unsigned int user_flags)
 {
        struct xdma_chan *chan = dmahead->chan;
        DEFINE_DMA_ATTRS(attrs);
-
        if (chan->poll_mode)
                xilinx_chan_desc_cleanup(chan);
        else
@@ -1002,7 +996,11 @@ unsigned int xlate_irq(unsigned int hwirq)
        irq_data.np = gic_node;
        irq_data.args_count = 3;
        irq_data.args[0] = 0;
+#if XLNK_SYS_BIT_WIDTH == 32
        irq_data.args[1] = hwirq - 32; /* GIC SPI offset */
+#else
+       irq_data.args[1] = hwirq;
+#endif
        irq_data.args[2] = IRQ_TYPE_LEVEL_HIGH;
 
        irq = irq_create_of_mapping(&irq_data);
index 5a6b512cd2622096c655e29d0b38b01014852b1b..b6334be3b9c45e06f3a4ad84c85a7803837df662 100644 (file)
 
 #if XLNK_SYS_BIT_WIDTH == 32
 
-       typedef __aligned(4) u32 xlnk_intptr_type;
-       typedef __aligned(4) s32 xlnk_int_type;
-       typedef __aligned(4) u32 xlnk_uint_type;
+       typedef u32 xlnk_intptr_type;
+       typedef s32 xlnk_int_type;
+       typedef u32 xlnk_uint_type;
        typedef u8 xlnk_byte_type;
        typedef s8 xlnk_char_type;
-       #define xlnk_enum_type __aligned(4) s32
+       #define xlnk_enum_type s32
 
 #elif XLNK_SYS_BIT_WIDTH == 64
 
-       typedef __aligned(8) u64 xlnk_intptr_type;
-       typedef __aligned(4) s32 xlnk_int_type;
-       typedef __aligned(4) u32 xlnk_uint_type;
+       typedef u64 xlnk_intptr_type;
+       typedef s32 xlnk_int_type;
+       typedef u32 xlnk_uint_type;
        typedef u8 xlnk_byte_type;
        typedef s8 xlnk_char_type;
-       #define xlnk_enum_type __aligned(4) s32
+       #define xlnk_enum_type s32
 
 #else
        #error "Please define application bit width and system bit width"
index 35f75e3fd04869a5a95cd1e98e94ac23393a25d9..3cb9b7307ce21335500bdba7e49bedc195017abd 100644 (file)
@@ -43,7 +43,6 @@
 #include <linux/pagemap.h>
 #include <linux/errno.h>       /* error codes */
 #include <linux/dma-mapping.h>  /* dma */
-#include <linux/clk.h>
 #include <linux/of.h>
 #include <linux/list.h>
 #include <linux/dma/xilinx_dma.h>
@@ -178,7 +177,7 @@ static void xlnk_devpacks_add(struct xlnk_device_pack *devpack)
        }
 }
 
-static struct xlnk_device_pack *xlnk_devpacks_find(unsigned long base)
+static struct xlnk_device_pack *xlnk_devpacks_find(xlnk_intptr_type base)
 {
        unsigned int i;
 
@@ -190,7 +189,7 @@ static struct xlnk_device_pack *xlnk_devpacks_find(unsigned long base)
        return NULL;
 }
 
-static void xlnk_devpacks_free(unsigned long base)
+static void xlnk_devpacks_free(xlnk_intptr_type base)
 {
        struct xlnk_device_pack *devpack;
 
@@ -229,41 +228,6 @@ static void xlnk_devpacks_free_all(void)
        }
 }
 
-/**
- * struct xlnk_data - data specific to xlnk
- * @numxclks:  number of clocks available
- * @clks:      pointer to array of clocks
- *
- * This struct should contain all the data specific to xlnk
- */
-struct xlnk_data {
-       int numxclks;
-       struct clk **clks;
-};
-
-/**
- * xlnk_clk_control() - turn all xlnk clocks on or off
- * @turn_on:   false - turn off (disable), true - turn on (enable)
- *
- * This function obtains a list of available clocks from the driver data
- * and enables or disables all of them based on the value of turn_on
- */
-static void xlnk_clk_control(bool turn_on)
-{
-       struct xlnk_data *xlnk_dat;
-       int i;
-
-       xlnk_dat = platform_get_drvdata(xlnk_pdev);
-       for (i = 0; i < xlnk_dat->numxclks; i++) {
-               if (IS_ERR(xlnk_dat->clks[i]))
-                       continue;
-               if (turn_on)
-                       clk_prepare_enable(xlnk_dat->clks[i]);
-               else
-                       clk_disable_unprepare(xlnk_dat->clks[i]);
-       }
-}
-
 static void xlnk_load_config_from_dt(struct platform_device *pdev)
 {
        const char *dma_name = NULL;
@@ -291,9 +255,6 @@ static void xlnk_load_config_from_dt(struct platform_device *pdev)
 static int xlnk_probe(struct platform_device *pdev)
 {
        int err, i;
-       const char *clkname;
-       struct clk **clks;
-       struct xlnk_data *xlnk_dat;
        dev_t dev = 0;
 
        xlnk_dev_buf = NULL;
@@ -347,40 +308,9 @@ static int xlnk_probe(struct platform_device *pdev)
 
        xlnk_pdev = pdev;
        xlnk_dev = &pdev->dev;
-       xlnk_dat = devm_kzalloc(xlnk_dev,
-                               sizeof(*xlnk_dat),
-                               GFP_KERNEL);
-       if (!xlnk_dat)
-               return -ENOMEM;
 
        xlnk_load_config_from_dt(pdev);
 
-       xlnk_dat->numxclks = of_property_count_strings(xlnk_dev->of_node,
-                                                       "clock-names");
-       if (xlnk_dat->numxclks > 0) {
-               clks = devm_kmalloc_array(xlnk_dev,
-                                       xlnk_dat->numxclks,
-                                       sizeof(struct clk *),
-                                       GFP_KERNEL);
-               if (!clks)
-                       return -ENOMEM;
-
-               xlnk_dat->clks = clks;
-               for (i = 0; i < xlnk_dat->numxclks; i++) {
-                       of_property_read_string_index(xlnk_dev->of_node,
-                                               "clock-names",
-                                               i,
-                                               &clkname);
-                       if (clkname) {
-                               clks[i] = devm_clk_get(xlnk_dev, clkname);
-                               if (IS_ERR(clks[i]))
-                                       dev_warn(xlnk_dev,
-                                               "Unable to get clk\n");
-                       } else
-                               dev_warn(xlnk_dev, "Unable to get clock\n");
-               }
-       }
-       platform_set_drvdata(xlnk_pdev, xlnk_dat);
        if (xlnk_pdev)
                dev_info(&pdev->dev, "xlnk_pdev is not null\n");
        else
@@ -410,7 +340,7 @@ static int xlnk_buf_findnull(void)
        return 0;
 }
 
-static int xlnk_buf_find_by_phys_addr(unsigned long addr)
+static int xlnk_buf_find_by_phys_addr(xlnk_intptr_type addr)
 {
        int i;
 
@@ -527,7 +457,6 @@ static int xlnk_open(struct inode *ip, struct file *filp)
 
        if ((filp->f_flags & O_ACCMODE) == O_WRONLY)
                xlnk_dev_size = 0;
-       xlnk_clk_control(true);
 
        return status;
 }
@@ -583,13 +512,12 @@ static ssize_t xlnk_write(struct file *filp, const char __user *buf,
  */
 static int xlnk_release(struct inode *ip, struct file *filp)
 {
-       xlnk_clk_control(false);
        return 0;
 }
 
 
 static int xlnk_devregister(char *name, unsigned int id,
-                               unsigned long base, unsigned int size,
+                               xlnk_intptr_type base, unsigned int size,
                                unsigned int *irqs,
                                xlnk_intptr_type *handle)
 {
@@ -654,7 +582,7 @@ static int xlnk_devregister(char *name, unsigned int id,
 }
 
 static int xlnk_dmaregister(char *name, unsigned int id,
-                               unsigned long base, unsigned int size,
+                               xlnk_intptr_type base, unsigned int size,
                                unsigned int chan_num,
                                unsigned int chan0_dir,
                                unsigned int chan0_irq,
@@ -764,7 +692,7 @@ static int xlnk_dmaregister(char *name, unsigned int id,
 }
 
 static int xlnk_mcdmaregister(char *name, unsigned int id,
-                             unsigned long base, unsigned int size,
+                             xlnk_intptr_type base, unsigned int size,
                              unsigned int mm2s_chan_num,
                              unsigned int mm2s_chan_irq,
                              unsigned int s2mm_chan_num,
@@ -907,28 +835,25 @@ static int xlnk_freebuf_ioctl(struct file *filp, unsigned int code,
 static int xlnk_adddmabuf_ioctl(struct file *filp, unsigned int code,
                        unsigned long args)
 {
-#if XLNK_SYS_BIT_WIDTH == 64
-       return -EINVAL;
-#else
-       struct dmabuf_args db_args;
+       union xlnk_args temp_args;
        struct xlnk_dmabuf_reg *db;
        int status;
 
-       status = copy_from_user(&db_args, (void __user *)args,
-                       sizeof(struct dmabuf_args));
+       status = copy_from_user(&temp_args, (void __user *)args,
+                               sizeof(union xlnk_args));
 
        if (status)
                return -ENOMEM;
 
        dev_dbg(xlnk_dev, "Registering dmabuf fd %d for virtual address %p\n",
-               db_args.dmabuf_fd, db_args.user_vaddr);
+               temp_args.dmabuf.dmabuf_fd, temp_args.dmabuf.user_addr);
 
        db = kzalloc(sizeof(struct xlnk_dmabuf_reg), GFP_KERNEL);
        if (!db)
                return -ENOMEM;
 
-       db->dmabuf_fd = db_args.dmabuf_fd;
-       db->user_vaddr = db_args.user_vaddr;
+       db->dmabuf_fd = temp_args.dmabuf.dmabuf_fd;
+       db->user_vaddr = temp_args.dmabuf.user_addr;
 
        db->dbuf = dma_buf_get(db->dmabuf_fd);
        if (IS_ERR_OR_NULL(db->dbuf)) {
@@ -942,27 +867,23 @@ static int xlnk_adddmabuf_ioctl(struct file *filp, unsigned int code,
        list_add_tail(&db->list, &xlnk_dmabuf_list);
 
        return 0;
-#endif
 }
 
 static int xlnk_cleardmabuf_ioctl(struct file *filp, unsigned int code,
                                unsigned long args)
 {
-#if XLNK_SYS_BIT_WIDTH == 64
-       return -EINVAL;
-#else
-       struct dmabuf_args db_args;
+       union xlnk_args temp_args;
        struct xlnk_dmabuf_reg *dp, *dp_temp;
        int status;
 
-       status = copy_from_user(&db_args, (void __user *)args,
-                       sizeof(struct dmabuf_args));
+       status = copy_from_user(&temp_args, (void __user *)args,
+                               sizeof(union xlnk_args));
 
        if (status)
                return -ENOMEM;
 
        list_for_each_entry_safe(dp, dp_temp, &xlnk_dmabuf_list, list) {
-               if (dp->user_vaddr == db_args.user_vaddr) {
+               if (dp->user_vaddr == temp_args.dmabuf.user_addr) {
                        if (dp->is_mapped) {
                                dma_buf_unmap_attachment(dp->dbuf_attach,
                                        dp->dbuf_sg_table, dp->dma_direction);
@@ -975,7 +896,6 @@ static int xlnk_cleardmabuf_ioctl(struct file *filp, unsigned int code,
                }
        }
        return 1;
-#endif
 }
 
 static int xlnk_dmarequest_ioctl(struct file *filp, unsigned int code,
@@ -1044,7 +964,6 @@ static void xlnk_complete_dma_callback(void *args)
 static int xlnk_dmasubmit_ioctl(struct file *filp, unsigned int code,
                                unsigned long args)
 {
-
 #ifdef CONFIG_XILINX_DMA_APF
        union xlnk_args temp_args;
        struct xdma_head *dmahead;
@@ -1238,8 +1157,8 @@ static int xlnk_dmasubmit_ioctl(struct file *filp, unsigned int code,
                if (copy_to_user((void __user *)args, &temp_args,
                                sizeof(union xlnk_args)))
                        return -EFAULT;
-               return 0;
        }
+       return status;
 #endif
        return -ENOMEM;
 }
index 9bf9a1b8e592fe1aeaed2bea5879e87fa2e1aa4c..9edb3479e79eb866843391674945f2344becb782 100644 (file)
@@ -23,11 +23,6 @@ enum xlnk_dma_direction {
        XLNK_DMA_NONE = 3,
 };
 
-struct __attribute__ ((__packed__)) dmabuf_args {
-       xlnk_int_type dmabuf_fd;
-       xlnk_intptr_type user_vaddr;
-};
-
 struct xlnk_dma_transfer_handle {
        dma_addr_t dma_addr;
        unsigned long transfer_length;