Date:2013-04-28 12:04:29 (7 years 1 month ago)
Author:Lars C.
Commit:183f6918cae831be5bb693ccebcaa5a907cd6932
Message:slcd: Use generic dmaengine interface

Files: drivers/video/fbdev/jz4740_slcd.h (2 diffs)
drivers/video/fbdev/jz4740_slcd_fb.c (5 diffs)

Change Details

drivers/video/fbdev/jz4740_slcd.h
1818#include <linux/gpio.h>
1919#include <linux/mutex.h>
2020#include <linux/workqueue.h>
21#include <linux/dmaengine.h>
2122
2223/*************************************************************************
2324 * SLCD (Smart LCD Controller)
...... 
9899    struct jzfb_framedesc (*framedesc)[3];
99100    dma_addr_t framedesc_phys;
100101
101    struct jz4740_dma_chan *dma;
102    struct dma_chan *dma;
102103    struct completion dma_completion;
103104    unsigned refresh_on_pan:1;
104105
drivers/video/fbdev/jz4740_slcd_fb.c
224224    return 0;
225225}
226226
227static void jzfb_refresh_work_complete(void *param)
228{
229    struct jzfb *jzfb = param;
230    complete_all(&jzfb->dma_completion);
231}
232
227233static void jzfb_disable_dma(struct jzfb *jzfb)
228234{
229    jz4740_dma_disable(jzfb->dma);
235    dmaengine_terminate_all(jzfb->dma);
230236    while (readb(jzfb->base + JZ_REG_SLCD_STATE) & SLCD_STATE_BUSY);
231237    writeb(readb(jzfb->base + JZ_REG_SLCD_CTRL) & ~SLCD_CTRL_DMA_EN,
232238        jzfb->base + JZ_REG_SLCD_CTRL);
233239}
234240
235static struct jz4740_dma_config jzfb_slcd_dma_config = {
236    .src_width = JZ4740_DMA_WIDTH_32BIT,
237    .dst_width = JZ4740_DMA_WIDTH_16BIT,
238    .transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE,
239    .request_type = JZ4740_DMA_TYPE_SLCD,
240    .flags = JZ4740_DMA_SRC_AUTOINC,
241    .mode = JZ4740_DMA_MODE_BLOCK,
242};
243
244241static void jzfb_upload_frame_dma(struct jzfb *jzfb)
245242{
246243    struct fb_info *fb = jzfb->fb;
247244    struct fb_videomode *mode = fb->mode;
248245    __u32 offset = fb->fix.line_length * fb->var.yoffset;
249246    __u32 size = fb->fix.line_length * mode->yres;
247    struct dma_async_tx_descriptor *desc;
250248
251249    /* Ensure that the data to be uploaded is in memory. */
252250    dma_cache_sync(fb->device, jzfb->vidmem + offset, size,
253251               DMA_TO_DEVICE);
254252
255    jz4740_dma_set_src_addr(jzfb->dma, jzfb->vidmem_phys + offset);
256    jz4740_dma_set_dst_addr(jzfb->dma,
257                CPHYSADDR(jzfb->base + JZ_REG_SLCD_FIFO));
258    jz4740_dma_set_transfer_count(jzfb->dma, size);
253    desc = dmaengine_prep_slave_single(jzfb->dma, DMA_MEM_TO_DEV,
254        jzfb->vidmem_phys + offset, size, DMA_PREP_INTERRUPT);
255    if (!desc)
256        return;
257
258    desc->callback = jzfb_refresh_work_complete;
259    desc->callback_param = jzfb;
260    dmaengine_submit(desc);
259261
260262    while (readb(jzfb->base + JZ_REG_SLCD_STATE) & SLCD_STATE_BUSY);
261263    writeb(readb(jzfb->base + JZ_REG_SLCD_CTRL) | SLCD_CTRL_DMA_EN,
262264        jzfb->base + JZ_REG_SLCD_CTRL);
263    jz4740_dma_enable(jzfb->dma);
265    dma_async_issue_pending(jzfb->dma);
264266}
265267
266268static void jzfb_upload_frame_cpu(struct jzfb *jzfb)
...... 
847849    struct jzfb *jzfb;
848850    struct fb_info *fb;
849851    struct jz4740_fb_platform_data *pdata = pdev->dev.platform_data;
852    struct dma_slave_config config;
850853    struct resource *mem;
854    dma_cap_mask_t dma_mask;
851855
852856    if (!pdata) {
853857        dev_err(&pdev->dev, "Missing platform data\n");
...... 
881885    init_completion(&jzfb->dma_completion);
882886    complete_all(&jzfb->dma_completion);
883887
884    jzfb->dma = jz4740_dma_request(&pdev->dev, dev_name(&pdev->dev), 0);
888    dma_cap_zero(dma_mask);
889    dma_cap_set(DMA_SLAVE, dma_mask);
890
891    jzfb->dma = dma_request_channel(dma_mask, NULL, NULL);
885892    if (!jzfb->dma) {
886893        dev_err(&pdev->dev, "Failed to get DMA channel\n");
887894        ret = -EBUSY;
888895        goto err_framebuffer_release;
889896    }
890    jz4740_dma_configure(jzfb->dma, &jzfb_slcd_dma_config);
891    jz4740_dma_set_complete_cb(jzfb->dma, &jzfb_refresh_work_complete);
897
898    config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
899    config.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
900    config.dst_maxburst = 16;
901    config.slave_id = JZ4740_DMA_TYPE_SLCD;
902    config.dst_addr = mem->start + JZ_REG_SLCD_FIFO;
903
904    dmaengine_slave_config(jzfb->dma, &config);
892905
893906    jzfb->ldclk = clk_get(&pdev->dev, "lcd");
894907    if (IS_ERR(jzfb->ldclk)) {
...... 
10121025err_put_ldclk:
10131026    clk_put(jzfb->ldclk);
10141027err_free_dma:
1015    jz4740_dma_free(jzfb->dma);
1028    dma_release_channel(jzfb->dma);
10161029err_framebuffer_release:
10171030    framebuffer_release(fb);
10181031    return ret;
...... 
10371050
10381051    jzfb_free_gpio_pins(jzfb);
10391052
1040    jz4740_dma_free(jzfb->dma);
1053    dma_release_channel(jzfb->dma);
10411054
10421055    fb_dealloc_cmap(&jzfb->fb->cmap);
10431056    jzfb_free_devmem(jzfb);

Archive Download the corresponding diff file



interactive