diff options
author | Felix Fietkau <nbd@openwrt.org> | 2014-12-13 11:55:11 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2014-12-13 11:55:11 +0000 |
commit | 45380ebd1ab3d604ece3dd14a84f89fbc69ea7b1 (patch) | |
tree | 816e479975bb22e39e9cbdde8fdfb400f38f72a9 /target/linux/brcm2708/patches-3.10/0149-bcm2708_fb-use-IRQ-for-DMA-copies.patch | |
parent | 170ce2961703fe3c2c74e9aa3088df2905b3697e (diff) | |
download | upstream-45380ebd1ab3d604ece3dd14a84f89fbc69ea7b1.tar.gz upstream-45380ebd1ab3d604ece3dd14a84f89fbc69ea7b1.tar.bz2 upstream-45380ebd1ab3d604ece3dd14a84f89fbc69ea7b1.zip |
brcm2708: remove linux 3.10 support
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
SVN-Revision: 43687
Diffstat (limited to 'target/linux/brcm2708/patches-3.10/0149-bcm2708_fb-use-IRQ-for-DMA-copies.patch')
-rw-r--r-- | target/linux/brcm2708/patches-3.10/0149-bcm2708_fb-use-IRQ-for-DMA-copies.patch | 215 |
1 files changed, 0 insertions, 215 deletions
diff --git a/target/linux/brcm2708/patches-3.10/0149-bcm2708_fb-use-IRQ-for-DMA-copies.patch b/target/linux/brcm2708/patches-3.10/0149-bcm2708_fb-use-IRQ-for-DMA-copies.patch deleted file mode 100644 index 90cb5396b7..0000000000 --- a/target/linux/brcm2708/patches-3.10/0149-bcm2708_fb-use-IRQ-for-DMA-copies.patch +++ /dev/null @@ -1,215 +0,0 @@ -From 298c1744068079c5174e0c6023a89cb5ad3576c4 Mon Sep 17 00:00:00 2001 -From: Luke Diamand <luked@broadcom.com> -Date: Wed, 1 Jan 2014 00:45:29 +0000 -Subject: [PATCH 149/196] bcm2708_fb: use IRQ for DMA copies - -The copyarea ioctl() uses DMA to speed things along. This -was busy-waiting for completion. This change supports using -an interrupt instead for larger transfers. For small -transfers, busy-waiting is still likely to be faster. - -Signed-off-by: Luke Diamand <luke@diamand.org> ---- - arch/arm/mach-bcm2708/dma.c | 8 ++++ - arch/arm/mach-bcm2708/include/mach/dma.h | 2 + - drivers/video/bcm2708_fb.c | 64 ++++++++++++++++++++++++++++++-- - 3 files changed, 70 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/dma.c b/arch/arm/mach-bcm2708/dma.c -index 51d147a..1da2413 100644 ---- a/arch/arm/mach-bcm2708/dma.c -+++ b/arch/arm/mach-bcm2708/dma.c -@@ -83,6 +83,14 @@ extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) - - EXPORT_SYMBOL_GPL(bcm_dma_start); - -+extern bool bcm_dma_is_busy(void __iomem *dma_chan_base) -+{ -+ dsb(); -+ -+ return readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_is_busy); -+ - /* Complete an ongoing DMA (assuming its results are to be ignored) - Does nothing if there is no DMA in progress. - This routine waits for the current AXI transfer to complete before -diff --git a/arch/arm/mach-bcm2708/include/mach/dma.h b/arch/arm/mach-bcm2708/include/mach/dma.h -index f2568d4..a4aac4c 100644 ---- a/arch/arm/mach-bcm2708/include/mach/dma.h -+++ b/arch/arm/mach-bcm2708/include/mach/dma.h -@@ -64,11 +64,13 @@ struct bcm2708_dma_cb { - unsigned long next; - unsigned long pad[2]; - }; -+struct scatterlist; - - extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); - extern void bcm_dma_start(void __iomem *dma_chan_base, - dma_addr_t control_block); - extern void bcm_dma_wait_idle(void __iomem *dma_chan_base); -+extern bool bcm_dma_is_busy(void __iomem *dma_chan_base); - extern int /*rc*/ bcm_dma_abort(void __iomem *dma_chan_base); - - /* When listing features we can ask for when allocating DMA channels give -diff --git a/drivers/video/bcm2708_fb.c b/drivers/video/bcm2708_fb.c -index 4d7d963..5758146 100644 ---- a/drivers/video/bcm2708_fb.c -+++ b/drivers/video/bcm2708_fb.c -@@ -21,6 +21,7 @@ - #include <linux/mm.h> - #include <linux/fb.h> - #include <linux/init.h> -+#include <linux/interrupt.h> - #include <linux/ioport.h> - #include <linux/list.h> - #include <linux/platform_device.h> -@@ -48,6 +49,11 @@ static const char *bcm2708_name = "BCM2708 FB"; - - #define DRIVER_NAME "bcm2708_fb" - -+static u32 dma_busy_wait_threshold = 1<<15; -+module_param(dma_busy_wait_threshold, int, 0644); -+MODULE_PARM_DESC(dma_busy_wait_threshold, "Busy-wait for DMA completion below this area"); -+ -+ - /* this data structure describes each frame buffer device we find */ - - struct fbinfo_s { -@@ -77,6 +83,7 @@ struct bcm2708_fb { - void *cb_base; /* DMA control blocks */ - dma_addr_t cb_handle; - struct dentry *debugfs_dir; -+ wait_queue_head_t dma_waitq; - struct bcm2708_fb_stats stats; - }; - -@@ -95,6 +102,10 @@ static int bcm2708_fb_debugfs_init(struct bcm2708_fb *fb) - "dma_copies", - offsetof(struct bcm2708_fb_stats, dma_copies) - }, -+ { -+ "dma_irqs", -+ offsetof(struct bcm2708_fb_stats, dma_irqs) -+ }, - }; - - fb->debugfs_dir = debugfs_create_dir(DRIVER_NAME, NULL); -@@ -400,6 +411,7 @@ static void bcm2708_fb_copyarea(struct fb_info *info, - int bytes_per_pixel = (info->var.bits_per_pixel + 7) >> 3; - /* Channel 0 supports larger bursts and is a bit faster */ - int burst_size = (fb->dma_chan == 0) ? 8 : 2; -+ int pixels = region->width * region->height; - - /* Fallback to cfb_copyarea() if we don't like something */ - if (bytes_per_pixel > 4 || -@@ -492,8 +504,20 @@ static void bcm2708_fb_copyarea(struct fb_info *info, - cb->next = 0; - - -- bcm_dma_start(fb->dma_chan_base, fb->cb_handle); -- bcm_dma_wait_idle(fb->dma_chan_base); -+ if (pixels < dma_busy_wait_threshold) { -+ bcm_dma_start(fb->dma_chan_base, fb->cb_handle); -+ bcm_dma_wait_idle(fb->dma_chan_base); -+ } else { -+ void __iomem *dma_chan = fb->dma_chan_base; -+ cb->info |= BCM2708_DMA_INT_EN; -+ bcm_dma_start(fb->dma_chan_base, fb->cb_handle); -+ while (bcm_dma_is_busy(dma_chan)) { -+ wait_event_interruptible( -+ fb->dma_waitq, -+ !bcm_dma_is_busy(dma_chan)); -+ } -+ fb->stats.dma_irqs++; -+ } - fb->stats.dma_copies++; - } - -@@ -504,6 +528,24 @@ static void bcm2708_fb_imageblit(struct fb_info *info, - cfb_imageblit(info, image); - } - -+static irqreturn_t bcm2708_fb_dma_irq(int irq, void *cxt) -+{ -+ struct bcm2708_fb *fb = cxt; -+ -+ /* FIXME: should read status register to check if this is -+ * actually interrupting us or not, in case this interrupt -+ * ever becomes shared amongst several DMA channels -+ * -+ * readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_IRQ; -+ */ -+ -+ /* acknowledge the interrupt */ -+ writel(BCM2708_DMA_INT, fb->dma_chan_base + BCM2708_DMA_CS); -+ -+ wake_up(&fb->dma_waitq); -+ return IRQ_HANDLED; -+} -+ - static struct fb_ops bcm2708_fb_ops = { - .owner = THIS_MODULE, - .fb_check_var = bcm2708_fb_check_var, -@@ -568,6 +610,7 @@ static int bcm2708_fb_register(struct bcm2708_fb *fb) - fb->fb.monspecs.dclkmax = 100000000; - - bcm2708_fb_set_bitfields(&fb->fb.var); -+ init_waitqueue_head(&fb->dma_waitq); - - /* - * Allocate colourmap. -@@ -593,14 +636,15 @@ static int bcm2708_fb_probe(struct platform_device *dev) - struct bcm2708_fb *fb; - int ret; - -- fb = kmalloc(sizeof(struct bcm2708_fb), GFP_KERNEL); -+ fb = kzalloc(sizeof(struct bcm2708_fb), GFP_KERNEL); - if (!fb) { - dev_err(&dev->dev, - "could not allocate new bcm2708_fb struct\n"); - ret = -ENOMEM; - goto free_region; - } -- memset(fb, 0, sizeof(struct bcm2708_fb)); -+ -+ bcm2708_fb_debugfs_init(fb); - - - bcm2708_fb_debugfs_init(fb); -@@ -624,6 +668,14 @@ static int bcm2708_fb_probe(struct platform_device *dev) - } - fb->dma_chan = ret; - -+ ret = request_irq(fb->dma_irq, bcm2708_fb_dma_irq, -+ 0, "bcm2708_fb dma", fb); -+ if (ret) { -+ pr_err("%s: failed to request DMA irq\n", __func__); -+ goto free_dma_chan; -+ } -+ -+ - pr_info("BCM2708FB: allocated DMA channel %d @ %p\n", - fb->dma_chan, fb->dma_chan_base); - -@@ -635,6 +687,8 @@ static int bcm2708_fb_probe(struct platform_device *dev) - goto out; - } - -+free_dma_chan: -+ bcm_dma_chan_free(fb->dma_chan); - free_cb: - dma_free_writecombine(&dev->dev, SZ_64K, fb->cb_base, fb->cb_handle); - free_fb: -@@ -662,6 +716,8 @@ static int bcm2708_fb_remove(struct platform_device *dev) - fb->dma); - bcm2708_fb_debugfs_deinit(fb); - -+ free_irq(fb->dma_irq, fb); -+ - kfree(fb); - - return 0; --- -1.9.1 - |