i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2008
|
|
|
|
* Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
|
|
|
|
*
|
|
|
|
* Copyright (C) 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/platform_device.h>
|
|
|
|
#include <linux/err.h>
|
|
|
|
#include <linux/spinlock.h>
|
|
|
|
#include <linux/delay.h>
|
|
|
|
#include <linux/list.h>
|
|
|
|
#include <linux/clk.h>
|
|
|
|
#include <linux/vmalloc.h>
|
|
|
|
#include <linux/string.h>
|
|
|
|
#include <linux/interrupt.h>
|
|
|
|
#include <linux/io.h>
|
|
|
|
|
|
|
|
#include <mach/ipu.h>
|
|
|
|
|
|
|
|
#include "ipu_intern.h"
|
|
|
|
|
|
|
|
#define FS_VF_IN_VALID 0x00000002
|
|
|
|
#define FS_ENC_IN_VALID 0x00000001
|
|
|
|
|
2009-03-26 00:13:24 +08:00
|
|
|
static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
|
|
|
|
bool wait_for_stop);
|
|
|
|
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
/*
|
|
|
|
* There can be only one, we could allocate it dynamically, but then we'd have
|
|
|
|
* to add an extra parameter to some functions, and use something as ugly as
|
|
|
|
* struct ipu *ipu = to_ipu(to_idmac(ichan->dma_chan.device));
|
|
|
|
* in the ISR
|
|
|
|
*/
|
|
|
|
static struct ipu ipu_data;
|
|
|
|
|
|
|
|
#define to_ipu(id) container_of(id, struct ipu, idmac)
|
|
|
|
|
|
|
|
static u32 __idmac_read_icreg(struct ipu *ipu, unsigned long reg)
|
|
|
|
{
|
|
|
|
return __raw_readl(ipu->reg_ic + reg);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define idmac_read_icreg(ipu, reg) __idmac_read_icreg(ipu, reg - IC_CONF)
|
|
|
|
|
|
|
|
static void __idmac_write_icreg(struct ipu *ipu, u32 value, unsigned long reg)
|
|
|
|
{
|
|
|
|
__raw_writel(value, ipu->reg_ic + reg);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define idmac_write_icreg(ipu, v, reg) __idmac_write_icreg(ipu, v, reg - IC_CONF)
|
|
|
|
|
|
|
|
static u32 idmac_read_ipureg(struct ipu *ipu, unsigned long reg)
|
|
|
|
{
|
|
|
|
return __raw_readl(ipu->reg_ipu + reg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void idmac_write_ipureg(struct ipu *ipu, u32 value, unsigned long reg)
|
|
|
|
{
|
|
|
|
__raw_writel(value, ipu->reg_ipu + reg);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* IPU / IC common functions
|
|
|
|
*/
|
|
|
|
static void dump_idmac_reg(struct ipu *ipu)
|
|
|
|
{
|
|
|
|
dev_dbg(ipu->dev, "IDMAC_CONF 0x%x, IC_CONF 0x%x, IDMAC_CHA_EN 0x%x, "
|
|
|
|
"IDMAC_CHA_PRI 0x%x, IDMAC_CHA_BUSY 0x%x\n",
|
|
|
|
idmac_read_icreg(ipu, IDMAC_CONF),
|
|
|
|
idmac_read_icreg(ipu, IC_CONF),
|
|
|
|
idmac_read_icreg(ipu, IDMAC_CHA_EN),
|
|
|
|
idmac_read_icreg(ipu, IDMAC_CHA_PRI),
|
|
|
|
idmac_read_icreg(ipu, IDMAC_CHA_BUSY));
|
|
|
|
dev_dbg(ipu->dev, "BUF0_RDY 0x%x, BUF1_RDY 0x%x, CUR_BUF 0x%x, "
|
|
|
|
"DB_MODE 0x%x, TASKS_STAT 0x%x\n",
|
|
|
|
idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY),
|
|
|
|
idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY),
|
|
|
|
idmac_read_ipureg(ipu, IPU_CHA_CUR_BUF),
|
|
|
|
idmac_read_ipureg(ipu, IPU_CHA_DB_MODE_SEL),
|
|
|
|
idmac_read_ipureg(ipu, IPU_TASKS_STAT));
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint32_t bytes_per_pixel(enum pixel_fmt fmt)
|
|
|
|
{
|
|
|
|
switch (fmt) {
|
|
|
|
case IPU_PIX_FMT_GENERIC: /* generic data */
|
|
|
|
case IPU_PIX_FMT_RGB332:
|
|
|
|
case IPU_PIX_FMT_YUV420P:
|
|
|
|
case IPU_PIX_FMT_YUV422P:
|
|
|
|
default:
|
|
|
|
return 1;
|
|
|
|
case IPU_PIX_FMT_RGB565:
|
|
|
|
case IPU_PIX_FMT_YUYV:
|
|
|
|
case IPU_PIX_FMT_UYVY:
|
|
|
|
return 2;
|
|
|
|
case IPU_PIX_FMT_BGR24:
|
|
|
|
case IPU_PIX_FMT_RGB24:
|
|
|
|
return 3;
|
|
|
|
case IPU_PIX_FMT_GENERIC_32: /* generic data */
|
|
|
|
case IPU_PIX_FMT_BGR32:
|
|
|
|
case IPU_PIX_FMT_RGB32:
|
|
|
|
case IPU_PIX_FMT_ABGR32:
|
|
|
|
return 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-26 00:13:23 +08:00
|
|
|
/* Enable direct write to memory by the Camera Sensor Interface */
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
static void ipu_ic_enable_task(struct ipu *ipu, enum ipu_channel channel)
|
|
|
|
{
|
|
|
|
uint32_t ic_conf, mask;
|
|
|
|
|
|
|
|
switch (channel) {
|
|
|
|
case IDMAC_IC_0:
|
|
|
|
mask = IC_CONF_PRPENC_EN;
|
|
|
|
break;
|
|
|
|
case IDMAC_IC_7:
|
|
|
|
mask = IC_CONF_RWS_EN | IC_CONF_PRPENC_EN;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ic_conf = idmac_read_icreg(ipu, IC_CONF) | mask;
|
|
|
|
idmac_write_icreg(ipu, ic_conf, IC_CONF);
|
|
|
|
}
|
|
|
|
|
2009-03-26 00:13:23 +08:00
|
|
|
/* Called under spin_lock_irqsave(&ipu_data.lock) */
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
static void ipu_ic_disable_task(struct ipu *ipu, enum ipu_channel channel)
|
|
|
|
{
|
|
|
|
uint32_t ic_conf, mask;
|
|
|
|
|
|
|
|
switch (channel) {
|
|
|
|
case IDMAC_IC_0:
|
|
|
|
mask = IC_CONF_PRPENC_EN;
|
|
|
|
break;
|
|
|
|
case IDMAC_IC_7:
|
|
|
|
mask = IC_CONF_RWS_EN | IC_CONF_PRPENC_EN;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ic_conf = idmac_read_icreg(ipu, IC_CONF) & ~mask;
|
|
|
|
idmac_write_icreg(ipu, ic_conf, IC_CONF);
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint32_t ipu_channel_status(struct ipu *ipu, enum ipu_channel channel)
|
|
|
|
{
|
|
|
|
uint32_t stat = TASK_STAT_IDLE;
|
|
|
|
uint32_t task_stat_reg = idmac_read_ipureg(ipu, IPU_TASKS_STAT);
|
|
|
|
|
|
|
|
switch (channel) {
|
|
|
|
case IDMAC_IC_7:
|
|
|
|
stat = (task_stat_reg & TSTAT_CSI2MEM_MASK) >>
|
|
|
|
TSTAT_CSI2MEM_OFFSET;
|
|
|
|
break;
|
|
|
|
case IDMAC_IC_0:
|
|
|
|
case IDMAC_SDC_0:
|
|
|
|
case IDMAC_SDC_1:
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return stat;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct chan_param_mem_planar {
|
|
|
|
/* Word 0 */
|
|
|
|
u32 xv:10;
|
|
|
|
u32 yv:10;
|
|
|
|
u32 xb:12;
|
|
|
|
|
|
|
|
u32 yb:12;
|
|
|
|
u32 res1:2;
|
|
|
|
u32 nsb:1;
|
|
|
|
u32 lnpb:6;
|
|
|
|
u32 ubo_l:11;
|
|
|
|
|
|
|
|
u32 ubo_h:15;
|
|
|
|
u32 vbo_l:17;
|
|
|
|
|
|
|
|
u32 vbo_h:9;
|
|
|
|
u32 res2:3;
|
|
|
|
u32 fw:12;
|
|
|
|
u32 fh_l:8;
|
|
|
|
|
|
|
|
u32 fh_h:4;
|
|
|
|
u32 res3:28;
|
|
|
|
|
|
|
|
/* Word 1 */
|
|
|
|
u32 eba0;
|
|
|
|
|
|
|
|
u32 eba1;
|
|
|
|
|
|
|
|
u32 bpp:3;
|
|
|
|
u32 sl:14;
|
|
|
|
u32 pfs:3;
|
|
|
|
u32 bam:3;
|
|
|
|
u32 res4:2;
|
|
|
|
u32 npb:6;
|
|
|
|
u32 res5:1;
|
|
|
|
|
|
|
|
u32 sat:2;
|
|
|
|
u32 res6:30;
|
|
|
|
} __attribute__ ((packed));
|
|
|
|
|
|
|
|
struct chan_param_mem_interleaved {
|
|
|
|
/* Word 0 */
|
|
|
|
u32 xv:10;
|
|
|
|
u32 yv:10;
|
|
|
|
u32 xb:12;
|
|
|
|
|
|
|
|
u32 yb:12;
|
|
|
|
u32 sce:1;
|
|
|
|
u32 res1:1;
|
|
|
|
u32 nsb:1;
|
|
|
|
u32 lnpb:6;
|
|
|
|
u32 sx:10;
|
|
|
|
u32 sy_l:1;
|
|
|
|
|
|
|
|
u32 sy_h:9;
|
|
|
|
u32 ns:10;
|
|
|
|
u32 sm:10;
|
|
|
|
u32 sdx_l:3;
|
|
|
|
|
|
|
|
u32 sdx_h:2;
|
|
|
|
u32 sdy:5;
|
|
|
|
u32 sdrx:1;
|
|
|
|
u32 sdry:1;
|
|
|
|
u32 sdr1:1;
|
|
|
|
u32 res2:2;
|
|
|
|
u32 fw:12;
|
|
|
|
u32 fh_l:8;
|
|
|
|
|
|
|
|
u32 fh_h:4;
|
|
|
|
u32 res3:28;
|
|
|
|
|
|
|
|
/* Word 1 */
|
|
|
|
u32 eba0;
|
|
|
|
|
|
|
|
u32 eba1;
|
|
|
|
|
|
|
|
u32 bpp:3;
|
|
|
|
u32 sl:14;
|
|
|
|
u32 pfs:3;
|
|
|
|
u32 bam:3;
|
|
|
|
u32 res4:2;
|
|
|
|
u32 npb:6;
|
|
|
|
u32 res5:1;
|
|
|
|
|
|
|
|
u32 sat:2;
|
|
|
|
u32 scc:1;
|
|
|
|
u32 ofs0:5;
|
|
|
|
u32 ofs1:5;
|
|
|
|
u32 ofs2:5;
|
|
|
|
u32 ofs3:5;
|
|
|
|
u32 wid0:3;
|
|
|
|
u32 wid1:3;
|
|
|
|
u32 wid2:3;
|
|
|
|
|
|
|
|
u32 wid3:3;
|
|
|
|
u32 dec_sel:1;
|
|
|
|
u32 res6:28;
|
|
|
|
} __attribute__ ((packed));
|
|
|
|
|
|
|
|
union chan_param_mem {
|
|
|
|
struct chan_param_mem_planar pp;
|
|
|
|
struct chan_param_mem_interleaved ip;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void ipu_ch_param_set_plane_offset(union chan_param_mem *params,
|
|
|
|
u32 u_offset, u32 v_offset)
|
|
|
|
{
|
|
|
|
params->pp.ubo_l = u_offset & 0x7ff;
|
|
|
|
params->pp.ubo_h = u_offset >> 11;
|
|
|
|
params->pp.vbo_l = v_offset & 0x1ffff;
|
|
|
|
params->pp.vbo_h = v_offset >> 17;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ipu_ch_param_set_size(union chan_param_mem *params,
|
|
|
|
uint32_t pixel_fmt, uint16_t width,
|
|
|
|
uint16_t height, uint16_t stride)
|
|
|
|
{
|
|
|
|
u32 u_offset;
|
|
|
|
u32 v_offset;
|
|
|
|
|
|
|
|
params->pp.fw = width - 1;
|
|
|
|
params->pp.fh_l = height - 1;
|
|
|
|
params->pp.fh_h = (height - 1) >> 8;
|
|
|
|
params->pp.sl = stride - 1;
|
|
|
|
|
|
|
|
switch (pixel_fmt) {
|
|
|
|
case IPU_PIX_FMT_GENERIC:
|
|
|
|
/*Represents 8-bit Generic data */
|
|
|
|
params->pp.bpp = 3;
|
|
|
|
params->pp.pfs = 7;
|
|
|
|
params->pp.npb = 31;
|
|
|
|
params->pp.sat = 2; /* SAT = use 32-bit access */
|
|
|
|
break;
|
|
|
|
case IPU_PIX_FMT_GENERIC_32:
|
|
|
|
/*Represents 32-bit Generic data */
|
|
|
|
params->pp.bpp = 0;
|
|
|
|
params->pp.pfs = 7;
|
|
|
|
params->pp.npb = 7;
|
|
|
|
params->pp.sat = 2; /* SAT = use 32-bit access */
|
|
|
|
break;
|
|
|
|
case IPU_PIX_FMT_RGB565:
|
|
|
|
params->ip.bpp = 2;
|
|
|
|
params->ip.pfs = 4;
|
|
|
|
params->ip.npb = 7;
|
|
|
|
params->ip.sat = 2; /* SAT = 32-bit access */
|
|
|
|
params->ip.ofs0 = 0; /* Red bit offset */
|
|
|
|
params->ip.ofs1 = 5; /* Green bit offset */
|
|
|
|
params->ip.ofs2 = 11; /* Blue bit offset */
|
|
|
|
params->ip.ofs3 = 16; /* Alpha bit offset */
|
|
|
|
params->ip.wid0 = 4; /* Red bit width - 1 */
|
|
|
|
params->ip.wid1 = 5; /* Green bit width - 1 */
|
|
|
|
params->ip.wid2 = 4; /* Blue bit width - 1 */
|
|
|
|
break;
|
|
|
|
case IPU_PIX_FMT_BGR24:
|
|
|
|
params->ip.bpp = 1; /* 24 BPP & RGB PFS */
|
|
|
|
params->ip.pfs = 4;
|
|
|
|
params->ip.npb = 7;
|
|
|
|
params->ip.sat = 2; /* SAT = 32-bit access */
|
|
|
|
params->ip.ofs0 = 0; /* Red bit offset */
|
|
|
|
params->ip.ofs1 = 8; /* Green bit offset */
|
|
|
|
params->ip.ofs2 = 16; /* Blue bit offset */
|
|
|
|
params->ip.ofs3 = 24; /* Alpha bit offset */
|
|
|
|
params->ip.wid0 = 7; /* Red bit width - 1 */
|
|
|
|
params->ip.wid1 = 7; /* Green bit width - 1 */
|
|
|
|
params->ip.wid2 = 7; /* Blue bit width - 1 */
|
|
|
|
break;
|
|
|
|
case IPU_PIX_FMT_RGB24:
|
|
|
|
params->ip.bpp = 1; /* 24 BPP & RGB PFS */
|
|
|
|
params->ip.pfs = 4;
|
|
|
|
params->ip.npb = 7;
|
|
|
|
params->ip.sat = 2; /* SAT = 32-bit access */
|
|
|
|
params->ip.ofs0 = 16; /* Red bit offset */
|
|
|
|
params->ip.ofs1 = 8; /* Green bit offset */
|
|
|
|
params->ip.ofs2 = 0; /* Blue bit offset */
|
|
|
|
params->ip.ofs3 = 24; /* Alpha bit offset */
|
|
|
|
params->ip.wid0 = 7; /* Red bit width - 1 */
|
|
|
|
params->ip.wid1 = 7; /* Green bit width - 1 */
|
|
|
|
params->ip.wid2 = 7; /* Blue bit width - 1 */
|
|
|
|
break;
|
|
|
|
case IPU_PIX_FMT_BGRA32:
|
|
|
|
case IPU_PIX_FMT_BGR32:
|
2010-01-20 08:25:56 +08:00
|
|
|
case IPU_PIX_FMT_ABGR32:
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
params->ip.bpp = 0;
|
|
|
|
params->ip.pfs = 4;
|
|
|
|
params->ip.npb = 7;
|
|
|
|
params->ip.sat = 2; /* SAT = 32-bit access */
|
|
|
|
params->ip.ofs0 = 8; /* Red bit offset */
|
|
|
|
params->ip.ofs1 = 16; /* Green bit offset */
|
|
|
|
params->ip.ofs2 = 24; /* Blue bit offset */
|
|
|
|
params->ip.ofs3 = 0; /* Alpha bit offset */
|
|
|
|
params->ip.wid0 = 7; /* Red bit width - 1 */
|
|
|
|
params->ip.wid1 = 7; /* Green bit width - 1 */
|
|
|
|
params->ip.wid2 = 7; /* Blue bit width - 1 */
|
|
|
|
params->ip.wid3 = 7; /* Alpha bit width - 1 */
|
|
|
|
break;
|
|
|
|
case IPU_PIX_FMT_RGBA32:
|
|
|
|
case IPU_PIX_FMT_RGB32:
|
|
|
|
params->ip.bpp = 0;
|
|
|
|
params->ip.pfs = 4;
|
|
|
|
params->ip.npb = 7;
|
|
|
|
params->ip.sat = 2; /* SAT = 32-bit access */
|
|
|
|
params->ip.ofs0 = 24; /* Red bit offset */
|
|
|
|
params->ip.ofs1 = 16; /* Green bit offset */
|
|
|
|
params->ip.ofs2 = 8; /* Blue bit offset */
|
|
|
|
params->ip.ofs3 = 0; /* Alpha bit offset */
|
|
|
|
params->ip.wid0 = 7; /* Red bit width - 1 */
|
|
|
|
params->ip.wid1 = 7; /* Green bit width - 1 */
|
|
|
|
params->ip.wid2 = 7; /* Blue bit width - 1 */
|
|
|
|
params->ip.wid3 = 7; /* Alpha bit width - 1 */
|
|
|
|
break;
|
|
|
|
case IPU_PIX_FMT_UYVY:
|
|
|
|
params->ip.bpp = 2;
|
|
|
|
params->ip.pfs = 6;
|
|
|
|
params->ip.npb = 7;
|
|
|
|
params->ip.sat = 2; /* SAT = 32-bit access */
|
|
|
|
break;
|
|
|
|
case IPU_PIX_FMT_YUV420P2:
|
|
|
|
case IPU_PIX_FMT_YUV420P:
|
|
|
|
params->ip.bpp = 3;
|
|
|
|
params->ip.pfs = 3;
|
|
|
|
params->ip.npb = 7;
|
|
|
|
params->ip.sat = 2; /* SAT = 32-bit access */
|
|
|
|
u_offset = stride * height;
|
|
|
|
v_offset = u_offset + u_offset / 4;
|
|
|
|
ipu_ch_param_set_plane_offset(params, u_offset, v_offset);
|
|
|
|
break;
|
|
|
|
case IPU_PIX_FMT_YVU422P:
|
|
|
|
params->ip.bpp = 3;
|
|
|
|
params->ip.pfs = 2;
|
|
|
|
params->ip.npb = 7;
|
|
|
|
params->ip.sat = 2; /* SAT = 32-bit access */
|
|
|
|
v_offset = stride * height;
|
|
|
|
u_offset = v_offset + v_offset / 2;
|
|
|
|
ipu_ch_param_set_plane_offset(params, u_offset, v_offset);
|
|
|
|
break;
|
|
|
|
case IPU_PIX_FMT_YUV422P:
|
|
|
|
params->ip.bpp = 3;
|
|
|
|
params->ip.pfs = 2;
|
|
|
|
params->ip.npb = 7;
|
|
|
|
params->ip.sat = 2; /* SAT = 32-bit access */
|
|
|
|
u_offset = stride * height;
|
|
|
|
v_offset = u_offset + u_offset / 2;
|
|
|
|
ipu_ch_param_set_plane_offset(params, u_offset, v_offset);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
dev_err(ipu_data.dev,
|
2009-03-26 00:13:23 +08:00
|
|
|
"mx3 ipu: unimplemented pixel format %d\n", pixel_fmt);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
params->pp.nsb = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ipu_ch_param_set_burst_size(union chan_param_mem *params,
|
|
|
|
uint16_t burst_pixels)
|
|
|
|
{
|
|
|
|
params->pp.npb = burst_pixels - 1;
|
2009-03-26 00:13:23 +08:00
|
|
|
}
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
|
|
|
|
static void ipu_ch_param_set_buffer(union chan_param_mem *params,
|
|
|
|
dma_addr_t buf0, dma_addr_t buf1)
|
|
|
|
{
|
|
|
|
params->pp.eba0 = buf0;
|
|
|
|
params->pp.eba1 = buf1;
|
2009-03-26 00:13:23 +08:00
|
|
|
}
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
|
|
|
|
static void ipu_ch_param_set_rotation(union chan_param_mem *params,
|
|
|
|
enum ipu_rotate_mode rotate)
|
|
|
|
{
|
|
|
|
params->pp.bam = rotate;
|
2009-03-26 00:13:23 +08:00
|
|
|
}
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
|
|
|
|
static void ipu_write_param_mem(uint32_t addr, uint32_t *data,
|
|
|
|
uint32_t num_words)
|
|
|
|
{
|
|
|
|
for (; num_words > 0; num_words--) {
|
|
|
|
dev_dbg(ipu_data.dev,
|
|
|
|
"write param mem - addr = 0x%08X, data = 0x%08X\n",
|
|
|
|
addr, *data);
|
|
|
|
idmac_write_ipureg(&ipu_data, addr, IPU_IMA_ADDR);
|
|
|
|
idmac_write_ipureg(&ipu_data, *data++, IPU_IMA_DATA);
|
|
|
|
addr++;
|
|
|
|
if ((addr & 0x7) == 5) {
|
|
|
|
addr &= ~0x7; /* set to word 0 */
|
|
|
|
addr += 8; /* increment to next row */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int calc_resize_coeffs(uint32_t in_size, uint32_t out_size,
|
|
|
|
uint32_t *resize_coeff,
|
|
|
|
uint32_t *downsize_coeff)
|
|
|
|
{
|
|
|
|
uint32_t temp_size;
|
|
|
|
uint32_t temp_downsize;
|
|
|
|
|
|
|
|
*resize_coeff = 1 << 13;
|
|
|
|
*downsize_coeff = 1 << 13;
|
|
|
|
|
|
|
|
/* Cannot downsize more than 8:1 */
|
|
|
|
if (out_size << 3 < in_size)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
/* compute downsizing coefficient */
|
|
|
|
temp_downsize = 0;
|
|
|
|
temp_size = in_size;
|
|
|
|
while (temp_size >= out_size * 2 && temp_downsize < 2) {
|
|
|
|
temp_size >>= 1;
|
|
|
|
temp_downsize++;
|
|
|
|
}
|
|
|
|
*downsize_coeff = temp_downsize;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* compute resizing coefficient using the following formula:
|
|
|
|
* resize_coeff = M*(SI -1)/(SO - 1)
|
|
|
|
* where M = 2^13, SI - input size, SO - output size
|
|
|
|
*/
|
|
|
|
*resize_coeff = (8192L * (temp_size - 1)) / (out_size - 1);
|
|
|
|
if (*resize_coeff >= 16384L) {
|
|
|
|
dev_err(ipu_data.dev, "Warning! Overflow on resize coeff.\n");
|
|
|
|
*resize_coeff = 0x3FFF;
|
|
|
|
}
|
|
|
|
|
|
|
|
dev_dbg(ipu_data.dev, "resizing from %u -> %u pixels, "
|
|
|
|
"downsize=%u, resize=%u.%lu (reg=%u)\n", in_size, out_size,
|
|
|
|
*downsize_coeff, *resize_coeff >= 8192L ? 1 : 0,
|
|
|
|
((*resize_coeff & 0x1FFF) * 10000L) / 8192L, *resize_coeff);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static enum ipu_color_space format_to_colorspace(enum pixel_fmt fmt)
|
|
|
|
{
|
|
|
|
switch (fmt) {
|
|
|
|
case IPU_PIX_FMT_RGB565:
|
|
|
|
case IPU_PIX_FMT_BGR24:
|
|
|
|
case IPU_PIX_FMT_RGB24:
|
|
|
|
case IPU_PIX_FMT_BGR32:
|
|
|
|
case IPU_PIX_FMT_RGB32:
|
|
|
|
return IPU_COLORSPACE_RGB;
|
|
|
|
default:
|
|
|
|
return IPU_COLORSPACE_YCBCR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ipu_ic_init_prpenc(struct ipu *ipu,
|
|
|
|
union ipu_channel_param *params, bool src_is_csi)
|
|
|
|
{
|
|
|
|
uint32_t reg, ic_conf;
|
|
|
|
uint32_t downsize_coeff, resize_coeff;
|
|
|
|
enum ipu_color_space in_fmt, out_fmt;
|
|
|
|
|
|
|
|
/* Setup vertical resizing */
|
|
|
|
calc_resize_coeffs(params->video.in_height,
|
|
|
|
params->video.out_height,
|
|
|
|
&resize_coeff, &downsize_coeff);
|
|
|
|
reg = (downsize_coeff << 30) | (resize_coeff << 16);
|
|
|
|
|
|
|
|
/* Setup horizontal resizing */
|
|
|
|
calc_resize_coeffs(params->video.in_width,
|
|
|
|
params->video.out_width,
|
|
|
|
&resize_coeff, &downsize_coeff);
|
|
|
|
reg |= (downsize_coeff << 14) | resize_coeff;
|
|
|
|
|
|
|
|
/* Setup color space conversion */
|
|
|
|
in_fmt = format_to_colorspace(params->video.in_pixel_fmt);
|
|
|
|
out_fmt = format_to_colorspace(params->video.out_pixel_fmt);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Colourspace conversion unsupported yet - see _init_csc() in
|
|
|
|
* Freescale sources
|
|
|
|
*/
|
|
|
|
if (in_fmt != out_fmt) {
|
|
|
|
dev_err(ipu->dev, "Colourspace conversion unsupported!\n");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
|
|
|
idmac_write_icreg(ipu, reg, IC_PRP_ENC_RSC);
|
|
|
|
|
|
|
|
ic_conf = idmac_read_icreg(ipu, IC_CONF);
|
|
|
|
|
|
|
|
if (src_is_csi)
|
|
|
|
ic_conf &= ~IC_CONF_RWS_EN;
|
|
|
|
else
|
|
|
|
ic_conf |= IC_CONF_RWS_EN;
|
|
|
|
|
|
|
|
idmac_write_icreg(ipu, ic_conf, IC_CONF);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint32_t dma_param_addr(uint32_t dma_ch)
|
|
|
|
{
|
|
|
|
/* Channel Parameter Memory */
|
|
|
|
return 0x10000 | (dma_ch << 4);
|
2009-03-26 00:13:23 +08:00
|
|
|
}
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
|
|
|
|
static void ipu_channel_set_priority(struct ipu *ipu, enum ipu_channel channel,
|
|
|
|
bool prio)
|
|
|
|
{
|
|
|
|
u32 reg = idmac_read_icreg(ipu, IDMAC_CHA_PRI);
|
|
|
|
|
|
|
|
if (prio)
|
|
|
|
reg |= 1UL << channel;
|
|
|
|
else
|
|
|
|
reg &= ~(1UL << channel);
|
|
|
|
|
|
|
|
idmac_write_icreg(ipu, reg, IDMAC_CHA_PRI);
|
|
|
|
|
|
|
|
dump_idmac_reg(ipu);
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint32_t ipu_channel_conf_mask(enum ipu_channel channel)
|
|
|
|
{
|
|
|
|
uint32_t mask;
|
|
|
|
|
|
|
|
switch (channel) {
|
|
|
|
case IDMAC_IC_0:
|
|
|
|
case IDMAC_IC_7:
|
|
|
|
mask = IPU_CONF_CSI_EN | IPU_CONF_IC_EN;
|
|
|
|
break;
|
|
|
|
case IDMAC_SDC_0:
|
|
|
|
case IDMAC_SDC_1:
|
|
|
|
mask = IPU_CONF_SDC_EN | IPU_CONF_DI_EN;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
mask = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mask;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ipu_enable_channel() - enable an IPU channel.
|
2009-03-26 00:13:23 +08:00
|
|
|
* @idmac: IPU DMAC context.
|
|
|
|
* @ichan: IDMAC channel.
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
* @return: 0 on success or negative error code on failure.
|
|
|
|
*/
|
|
|
|
static int ipu_enable_channel(struct idmac *idmac, struct idmac_channel *ichan)
|
|
|
|
{
|
|
|
|
struct ipu *ipu = to_ipu(idmac);
|
|
|
|
enum ipu_channel channel = ichan->dma_chan.chan_id;
|
|
|
|
uint32_t reg;
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
spin_lock_irqsave(&ipu->lock, flags);
|
|
|
|
|
|
|
|
/* Reset to buffer 0 */
|
|
|
|
idmac_write_ipureg(ipu, 1UL << channel, IPU_CHA_CUR_BUF);
|
|
|
|
ichan->active_buffer = 0;
|
|
|
|
ichan->status = IPU_CHANNEL_ENABLED;
|
|
|
|
|
|
|
|
switch (channel) {
|
|
|
|
case IDMAC_SDC_0:
|
|
|
|
case IDMAC_SDC_1:
|
|
|
|
case IDMAC_IC_7:
|
|
|
|
ipu_channel_set_priority(ipu, channel, true);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
reg = idmac_read_icreg(ipu, IDMAC_CHA_EN);
|
|
|
|
|
|
|
|
idmac_write_icreg(ipu, reg | (1UL << channel), IDMAC_CHA_EN);
|
|
|
|
|
|
|
|
ipu_ic_enable_task(ipu, channel);
|
|
|
|
|
|
|
|
spin_unlock_irqrestore(&ipu->lock, flags);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ipu_init_channel_buffer() - initialize a buffer for logical IPU channel.
|
2009-03-26 00:13:23 +08:00
|
|
|
* @ichan: IDMAC channel.
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
* @pixel_fmt: pixel format of buffer. Pixel format is a FOURCC ASCII code.
|
|
|
|
* @width: width of buffer in pixels.
|
|
|
|
* @height: height of buffer in pixels.
|
|
|
|
* @stride: stride length of buffer in pixels.
|
|
|
|
* @rot_mode: rotation mode of buffer. A rotation setting other than
|
|
|
|
* IPU_ROTATE_VERT_FLIP should only be used for input buffers of
|
|
|
|
* rotation channels.
|
|
|
|
* @phyaddr_0: buffer 0 physical address.
|
|
|
|
* @phyaddr_1: buffer 1 physical address. Setting this to a value other than
|
|
|
|
* NULL enables double buffering mode.
|
|
|
|
* @return: 0 on success or negative error code on failure.
|
|
|
|
*/
|
|
|
|
static int ipu_init_channel_buffer(struct idmac_channel *ichan,
|
|
|
|
enum pixel_fmt pixel_fmt,
|
|
|
|
uint16_t width, uint16_t height,
|
|
|
|
uint32_t stride,
|
|
|
|
enum ipu_rotate_mode rot_mode,
|
|
|
|
dma_addr_t phyaddr_0, dma_addr_t phyaddr_1)
|
|
|
|
{
|
|
|
|
enum ipu_channel channel = ichan->dma_chan.chan_id;
|
|
|
|
struct idmac *idmac = to_idmac(ichan->dma_chan.device);
|
|
|
|
struct ipu *ipu = to_ipu(idmac);
|
|
|
|
union chan_param_mem params = {};
|
|
|
|
unsigned long flags;
|
|
|
|
uint32_t reg;
|
|
|
|
uint32_t stride_bytes;
|
|
|
|
|
|
|
|
stride_bytes = stride * bytes_per_pixel(pixel_fmt);
|
|
|
|
|
|
|
|
if (stride_bytes % 4) {
|
|
|
|
dev_err(ipu->dev,
|
|
|
|
"Stride length must be 32-bit aligned, stride = %d, bytes = %d\n",
|
|
|
|
stride, stride_bytes);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* IC channel's stride must be a multiple of 8 pixels */
|
2009-03-26 00:13:23 +08:00
|
|
|
if ((channel <= IDMAC_IC_13) && (stride % 8)) {
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
dev_err(ipu->dev, "Stride must be 8 pixel multiple\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Build parameter memory data for DMA channel */
|
|
|
|
ipu_ch_param_set_size(¶ms, pixel_fmt, width, height, stride_bytes);
|
|
|
|
ipu_ch_param_set_buffer(¶ms, phyaddr_0, phyaddr_1);
|
|
|
|
ipu_ch_param_set_rotation(¶ms, rot_mode);
|
|
|
|
/* Some channels (rotation) have restriction on burst length */
|
|
|
|
switch (channel) {
|
|
|
|
case IDMAC_IC_7: /* Hangs with burst 8, 16, other values
|
|
|
|
invalid - Table 44-30 */
|
|
|
|
/*
|
|
|
|
ipu_ch_param_set_burst_size(¶ms, 8);
|
|
|
|
*/
|
|
|
|
break;
|
|
|
|
case IDMAC_SDC_0:
|
|
|
|
case IDMAC_SDC_1:
|
|
|
|
/* In original code only IPU_PIX_FMT_RGB565 was setting burst */
|
|
|
|
ipu_ch_param_set_burst_size(¶ms, 16);
|
|
|
|
break;
|
|
|
|
case IDMAC_IC_0:
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
spin_lock_irqsave(&ipu->lock, flags);
|
|
|
|
|
|
|
|
ipu_write_param_mem(dma_param_addr(channel), (uint32_t *)¶ms, 10);
|
|
|
|
|
|
|
|
reg = idmac_read_ipureg(ipu, IPU_CHA_DB_MODE_SEL);
|
|
|
|
|
|
|
|
if (phyaddr_1)
|
|
|
|
reg |= 1UL << channel;
|
|
|
|
else
|
|
|
|
reg &= ~(1UL << channel);
|
|
|
|
|
|
|
|
idmac_write_ipureg(ipu, reg, IPU_CHA_DB_MODE_SEL);
|
|
|
|
|
|
|
|
ichan->status = IPU_CHANNEL_READY;
|
|
|
|
|
2009-02-26 19:29:20 +08:00
|
|
|
spin_unlock_irqrestore(&ipu->lock, flags);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ipu_select_buffer() - mark a channel's buffer as ready.
|
|
|
|
* @channel: channel ID.
|
|
|
|
* @buffer_n: buffer number to mark ready.
|
|
|
|
*/
|
|
|
|
static void ipu_select_buffer(enum ipu_channel channel, int buffer_n)
|
|
|
|
{
|
|
|
|
/* No locking - this is a write-one-to-set register, cleared by IPU */
|
|
|
|
if (buffer_n == 0)
|
|
|
|
/* Mark buffer 0 as ready. */
|
|
|
|
idmac_write_ipureg(&ipu_data, 1UL << channel, IPU_CHA_BUF0_RDY);
|
|
|
|
else
|
|
|
|
/* Mark buffer 1 as ready. */
|
|
|
|
idmac_write_ipureg(&ipu_data, 1UL << channel, IPU_CHA_BUF1_RDY);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ipu_update_channel_buffer() - update physical address of a channel buffer.
|
2009-03-26 00:13:23 +08:00
|
|
|
* @ichan: IDMAC channel.
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
* @buffer_n: buffer number to update.
|
|
|
|
* 0 or 1 are the only valid values.
|
|
|
|
* @phyaddr: buffer physical address.
|
|
|
|
*/
|
|
|
|
/* Called under spin_lock(_irqsave)(&ichan->lock) */
|
2010-02-11 00:32:38 +08:00
|
|
|
static void ipu_update_channel_buffer(struct idmac_channel *ichan,
|
|
|
|
int buffer_n, dma_addr_t phyaddr)
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
{
|
2009-03-26 00:13:24 +08:00
|
|
|
enum ipu_channel channel = ichan->dma_chan.chan_id;
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
uint32_t reg;
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
spin_lock_irqsave(&ipu_data.lock, flags);
|
|
|
|
|
|
|
|
if (buffer_n == 0) {
|
|
|
|
reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY);
|
|
|
|
if (reg & (1UL << channel)) {
|
2009-03-26 00:13:24 +08:00
|
|
|
ipu_ic_disable_task(&ipu_data, channel);
|
|
|
|
ichan->status = IPU_CHANNEL_READY;
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 44.3.3.1.9 - Row Number 1 (WORD1, offset 0) */
|
|
|
|
idmac_write_ipureg(&ipu_data, dma_param_addr(channel) +
|
|
|
|
0x0008UL, IPU_IMA_ADDR);
|
|
|
|
idmac_write_ipureg(&ipu_data, phyaddr, IPU_IMA_DATA);
|
|
|
|
} else {
|
|
|
|
reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY);
|
|
|
|
if (reg & (1UL << channel)) {
|
2009-03-26 00:13:24 +08:00
|
|
|
ipu_ic_disable_task(&ipu_data, channel);
|
|
|
|
ichan->status = IPU_CHANNEL_READY;
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if double-buffering is already enabled */
|
|
|
|
reg = idmac_read_ipureg(&ipu_data, IPU_CHA_DB_MODE_SEL);
|
|
|
|
|
|
|
|
if (!(reg & (1UL << channel)))
|
|
|
|
idmac_write_ipureg(&ipu_data, reg | (1UL << channel),
|
|
|
|
IPU_CHA_DB_MODE_SEL);
|
|
|
|
|
|
|
|
/* 44.3.3.1.9 - Row Number 1 (WORD1, offset 1) */
|
|
|
|
idmac_write_ipureg(&ipu_data, dma_param_addr(channel) +
|
|
|
|
0x0009UL, IPU_IMA_ADDR);
|
|
|
|
idmac_write_ipureg(&ipu_data, phyaddr, IPU_IMA_DATA);
|
|
|
|
}
|
|
|
|
|
|
|
|
spin_unlock_irqrestore(&ipu_data.lock, flags);
|
|
|
|
}
|
|
|
|
|
2009-03-26 00:13:24 +08:00
|
|
|
/* Called under spin_lock_irqsave(&ichan->lock) */
|
|
|
|
static int ipu_submit_buffer(struct idmac_channel *ichan,
|
|
|
|
struct idmac_tx_desc *desc, struct scatterlist *sg, int buf_idx)
|
|
|
|
{
|
|
|
|
unsigned int chan_id = ichan->dma_chan.chan_id;
|
|
|
|
struct device *dev = &ichan->dma_chan.dev->device;
|
|
|
|
|
|
|
|
if (async_tx_test_ack(&desc->txd))
|
|
|
|
return -EINTR;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* On first invocation this shouldn't be necessary, the call to
|
|
|
|
* ipu_init_channel_buffer() above will set addresses for us, so we
|
|
|
|
* could make it conditional on status >= IPU_CHANNEL_ENABLED, but
|
|
|
|
* doing it again shouldn't hurt either.
|
|
|
|
*/
|
2010-02-11 00:32:38 +08:00
|
|
|
ipu_update_channel_buffer(ichan, buf_idx, sg_dma_address(sg));
|
2009-03-26 00:13:24 +08:00
|
|
|
|
|
|
|
ipu_select_buffer(chan_id, buf_idx);
|
|
|
|
dev_dbg(dev, "Updated sg %p on channel 0x%x buffer %d\n",
|
|
|
|
sg, chan_id, buf_idx);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
/* Called under spin_lock_irqsave(&ichan->lock) */
|
|
|
|
static int ipu_submit_channel_buffers(struct idmac_channel *ichan,
|
|
|
|
struct idmac_tx_desc *desc)
|
|
|
|
{
|
|
|
|
struct scatterlist *sg;
|
|
|
|
int i, ret = 0;
|
|
|
|
|
|
|
|
for (i = 0, sg = desc->sg; i < 2 && sg; i++) {
|
|
|
|
if (!ichan->sg[i]) {
|
|
|
|
ichan->sg[i] = sg;
|
|
|
|
|
2009-03-26 00:13:24 +08:00
|
|
|
ret = ipu_submit_buffer(ichan, desc, sg, i);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
sg = sg_next(sg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static dma_cookie_t idmac_tx_submit(struct dma_async_tx_descriptor *tx)
|
|
|
|
{
|
|
|
|
struct idmac_tx_desc *desc = to_tx_desc(tx);
|
|
|
|
struct idmac_channel *ichan = to_idmac_chan(tx->chan);
|
|
|
|
struct idmac *idmac = to_idmac(tx->chan->device);
|
|
|
|
struct ipu *ipu = to_ipu(idmac);
|
2009-03-26 00:13:24 +08:00
|
|
|
struct device *dev = &ichan->dma_chan.dev->device;
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
dma_cookie_t cookie;
|
|
|
|
unsigned long flags;
|
2009-03-26 00:13:24 +08:00
|
|
|
int ret;
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
|
|
|
|
/* Sanity check */
|
|
|
|
if (!list_empty(&desc->list)) {
|
|
|
|
/* The descriptor doesn't belong to client */
|
2009-03-26 00:13:24 +08:00
|
|
|
dev_err(dev, "Descriptor %p not prepared!\n", tx);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
return -EBUSY;
|
|
|
|
}
|
|
|
|
|
|
|
|
mutex_lock(&ichan->chan_mutex);
|
|
|
|
|
2009-03-26 00:13:24 +08:00
|
|
|
async_tx_clear_ack(tx);
|
|
|
|
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
if (ichan->status < IPU_CHANNEL_READY) {
|
|
|
|
struct idmac_video_param *video = &ichan->params.video;
|
|
|
|
/*
|
|
|
|
* Initial buffer assignment - the first two sg-entries from
|
|
|
|
* the descriptor will end up in the IDMAC buffers
|
|
|
|
*/
|
|
|
|
dma_addr_t dma_1 = sg_is_last(desc->sg) ? 0 :
|
|
|
|
sg_dma_address(&desc->sg[1]);
|
|
|
|
|
|
|
|
WARN_ON(ichan->sg[0] || ichan->sg[1]);
|
|
|
|
|
|
|
|
cookie = ipu_init_channel_buffer(ichan,
|
|
|
|
video->out_pixel_fmt,
|
|
|
|
video->out_width,
|
|
|
|
video->out_height,
|
|
|
|
video->out_stride,
|
|
|
|
IPU_ROTATE_NONE,
|
|
|
|
sg_dma_address(&desc->sg[0]),
|
|
|
|
dma_1);
|
|
|
|
if (cookie < 0)
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2009-03-26 00:13:24 +08:00
|
|
|
dev_dbg(dev, "Submitting sg %p\n", &desc->sg[0]);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
|
|
|
|
cookie = ichan->dma_chan.cookie;
|
|
|
|
|
|
|
|
if (++cookie < 0)
|
|
|
|
cookie = 1;
|
|
|
|
|
|
|
|
/* from dmaengine.h: "last cookie value returned to client" */
|
|
|
|
ichan->dma_chan.cookie = cookie;
|
|
|
|
tx->cookie = cookie;
|
2009-03-26 00:13:24 +08:00
|
|
|
|
|
|
|
/* ipu->lock can be taken under ichan->lock, but not v.v. */
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
spin_lock_irqsave(&ichan->lock, flags);
|
2009-03-26 00:13:24 +08:00
|
|
|
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
list_add_tail(&desc->list, &ichan->queue);
|
2009-03-26 00:13:24 +08:00
|
|
|
/* submit_buffers() atomically verifies and fills empty sg slots */
|
|
|
|
ret = ipu_submit_channel_buffers(ichan, desc);
|
|
|
|
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
spin_unlock_irqrestore(&ichan->lock, flags);
|
|
|
|
|
2009-03-26 00:13:24 +08:00
|
|
|
if (ret < 0) {
|
|
|
|
cookie = ret;
|
|
|
|
goto dequeue;
|
|
|
|
}
|
|
|
|
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
if (ichan->status < IPU_CHANNEL_ENABLED) {
|
2009-03-26 00:13:24 +08:00
|
|
|
ret = ipu_enable_channel(idmac, ichan);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
if (ret < 0) {
|
|
|
|
cookie = ret;
|
2009-03-26 00:13:24 +08:00
|
|
|
goto dequeue;
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dump_idmac_reg(ipu);
|
|
|
|
|
2009-03-26 00:13:24 +08:00
|
|
|
dequeue:
|
|
|
|
if (cookie < 0) {
|
|
|
|
spin_lock_irqsave(&ichan->lock, flags);
|
|
|
|
list_del_init(&desc->list);
|
|
|
|
spin_unlock_irqrestore(&ichan->lock, flags);
|
|
|
|
tx->cookie = cookie;
|
|
|
|
ichan->dma_chan.cookie = cookie;
|
|
|
|
}
|
|
|
|
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
out:
|
|
|
|
mutex_unlock(&ichan->chan_mutex);
|
|
|
|
|
|
|
|
return cookie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Called with ichan->chan_mutex held */
|
|
|
|
static int idmac_desc_alloc(struct idmac_channel *ichan, int n)
|
|
|
|
{
|
|
|
|
struct idmac_tx_desc *desc = vmalloc(n * sizeof(struct idmac_tx_desc));
|
|
|
|
struct idmac *idmac = to_idmac(ichan->dma_chan.device);
|
|
|
|
|
|
|
|
if (!desc)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
/* No interrupts, just disable the tasklet for a moment */
|
|
|
|
tasklet_disable(&to_ipu(idmac)->tasklet);
|
|
|
|
|
|
|
|
ichan->n_tx_desc = n;
|
|
|
|
ichan->desc = desc;
|
|
|
|
INIT_LIST_HEAD(&ichan->queue);
|
|
|
|
INIT_LIST_HEAD(&ichan->free_list);
|
|
|
|
|
|
|
|
while (n--) {
|
|
|
|
struct dma_async_tx_descriptor *txd = &desc->txd;
|
|
|
|
|
|
|
|
memset(txd, 0, sizeof(*txd));
|
|
|
|
dma_async_tx_descriptor_init(txd, &ichan->dma_chan);
|
|
|
|
txd->tx_submit = idmac_tx_submit;
|
|
|
|
|
|
|
|
list_add(&desc->list, &ichan->free_list);
|
|
|
|
|
|
|
|
desc++;
|
|
|
|
}
|
|
|
|
|
|
|
|
tasklet_enable(&to_ipu(idmac)->tasklet);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ipu_init_channel() - initialize an IPU channel.
|
|
|
|
* @idmac: IPU DMAC context.
|
|
|
|
* @ichan: pointer to the channel object.
|
|
|
|
* @return 0 on success or negative error code on failure.
|
|
|
|
*/
|
|
|
|
static int ipu_init_channel(struct idmac *idmac, struct idmac_channel *ichan)
|
|
|
|
{
|
|
|
|
union ipu_channel_param *params = &ichan->params;
|
|
|
|
uint32_t ipu_conf;
|
|
|
|
enum ipu_channel channel = ichan->dma_chan.chan_id;
|
|
|
|
unsigned long flags;
|
|
|
|
uint32_t reg;
|
|
|
|
struct ipu *ipu = to_ipu(idmac);
|
|
|
|
int ret = 0, n_desc = 0;
|
|
|
|
|
|
|
|
dev_dbg(ipu->dev, "init channel = %d\n", channel);
|
|
|
|
|
|
|
|
if (channel != IDMAC_SDC_0 && channel != IDMAC_SDC_1 &&
|
|
|
|
channel != IDMAC_IC_7)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
spin_lock_irqsave(&ipu->lock, flags);
|
|
|
|
|
|
|
|
switch (channel) {
|
|
|
|
case IDMAC_IC_7:
|
|
|
|
n_desc = 16;
|
|
|
|
reg = idmac_read_icreg(ipu, IC_CONF);
|
|
|
|
idmac_write_icreg(ipu, reg & ~IC_CONF_CSI_MEM_WR_EN, IC_CONF);
|
|
|
|
break;
|
|
|
|
case IDMAC_IC_0:
|
|
|
|
n_desc = 16;
|
|
|
|
reg = idmac_read_ipureg(ipu, IPU_FS_PROC_FLOW);
|
|
|
|
idmac_write_ipureg(ipu, reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW);
|
|
|
|
ret = ipu_ic_init_prpenc(ipu, params, true);
|
|
|
|
break;
|
|
|
|
case IDMAC_SDC_0:
|
|
|
|
case IDMAC_SDC_1:
|
|
|
|
n_desc = 4;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ipu->channel_init_mask |= 1L << channel;
|
|
|
|
|
|
|
|
/* Enable IPU sub module */
|
|
|
|
ipu_conf = idmac_read_ipureg(ipu, IPU_CONF) |
|
|
|
|
ipu_channel_conf_mask(channel);
|
|
|
|
idmac_write_ipureg(ipu, ipu_conf, IPU_CONF);
|
|
|
|
|
|
|
|
spin_unlock_irqrestore(&ipu->lock, flags);
|
|
|
|
|
|
|
|
if (n_desc && !ichan->desc)
|
|
|
|
ret = idmac_desc_alloc(ichan, n_desc);
|
|
|
|
|
|
|
|
dump_idmac_reg(ipu);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ipu_uninit_channel() - uninitialize an IPU channel.
|
|
|
|
* @idmac: IPU DMAC context.
|
|
|
|
* @ichan: pointer to the channel object.
|
|
|
|
*/
|
|
|
|
static void ipu_uninit_channel(struct idmac *idmac, struct idmac_channel *ichan)
|
|
|
|
{
|
|
|
|
enum ipu_channel channel = ichan->dma_chan.chan_id;
|
|
|
|
unsigned long flags;
|
|
|
|
uint32_t reg;
|
|
|
|
unsigned long chan_mask = 1UL << channel;
|
|
|
|
uint32_t ipu_conf;
|
|
|
|
struct ipu *ipu = to_ipu(idmac);
|
|
|
|
|
|
|
|
spin_lock_irqsave(&ipu->lock, flags);
|
|
|
|
|
|
|
|
if (!(ipu->channel_init_mask & chan_mask)) {
|
|
|
|
dev_err(ipu->dev, "Channel already uninitialized %d\n",
|
|
|
|
channel);
|
|
|
|
spin_unlock_irqrestore(&ipu->lock, flags);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Reset the double buffer */
|
|
|
|
reg = idmac_read_ipureg(ipu, IPU_CHA_DB_MODE_SEL);
|
|
|
|
idmac_write_ipureg(ipu, reg & ~chan_mask, IPU_CHA_DB_MODE_SEL);
|
|
|
|
|
|
|
|
ichan->sec_chan_en = false;
|
|
|
|
|
|
|
|
switch (channel) {
|
|
|
|
case IDMAC_IC_7:
|
|
|
|
reg = idmac_read_icreg(ipu, IC_CONF);
|
|
|
|
idmac_write_icreg(ipu, reg & ~(IC_CONF_RWS_EN | IC_CONF_PRPENC_EN),
|
|
|
|
IC_CONF);
|
|
|
|
break;
|
|
|
|
case IDMAC_IC_0:
|
|
|
|
reg = idmac_read_icreg(ipu, IC_CONF);
|
|
|
|
idmac_write_icreg(ipu, reg & ~(IC_CONF_PRPENC_EN | IC_CONF_PRPENC_CSC1),
|
|
|
|
IC_CONF);
|
|
|
|
break;
|
|
|
|
case IDMAC_SDC_0:
|
|
|
|
case IDMAC_SDC_1:
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ipu->channel_init_mask &= ~(1L << channel);
|
|
|
|
|
|
|
|
ipu_conf = idmac_read_ipureg(ipu, IPU_CONF) &
|
|
|
|
~ipu_channel_conf_mask(channel);
|
|
|
|
idmac_write_ipureg(ipu, ipu_conf, IPU_CONF);
|
|
|
|
|
|
|
|
spin_unlock_irqrestore(&ipu->lock, flags);
|
|
|
|
|
|
|
|
ichan->n_tx_desc = 0;
|
|
|
|
vfree(ichan->desc);
|
|
|
|
ichan->desc = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ipu_disable_channel() - disable an IPU channel.
|
|
|
|
* @idmac: IPU DMAC context.
|
|
|
|
* @ichan: channel object pointer.
|
|
|
|
* @wait_for_stop: flag to set whether to wait for channel end of frame or
|
|
|
|
* return immediately.
|
|
|
|
* @return: 0 on success or negative error code on failure.
|
|
|
|
*/
|
|
|
|
static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
|
|
|
|
bool wait_for_stop)
|
|
|
|
{
|
|
|
|
enum ipu_channel channel = ichan->dma_chan.chan_id;
|
|
|
|
struct ipu *ipu = to_ipu(idmac);
|
|
|
|
uint32_t reg;
|
|
|
|
unsigned long flags;
|
|
|
|
unsigned long chan_mask = 1UL << channel;
|
|
|
|
unsigned int timeout;
|
|
|
|
|
|
|
|
if (wait_for_stop && channel != IDMAC_SDC_1 && channel != IDMAC_SDC_0) {
|
|
|
|
timeout = 40;
|
|
|
|
/* This waiting always fails. Related to spurious irq problem */
|
|
|
|
while ((idmac_read_icreg(ipu, IDMAC_CHA_BUSY) & chan_mask) ||
|
|
|
|
(ipu_channel_status(ipu, channel) == TASK_STAT_ACTIVE)) {
|
|
|
|
timeout--;
|
|
|
|
msleep(10);
|
|
|
|
|
|
|
|
if (!timeout) {
|
|
|
|
dev_dbg(ipu->dev,
|
|
|
|
"Warning: timeout waiting for channel %u to "
|
|
|
|
"stop: buf0_rdy = 0x%08X, buf1_rdy = 0x%08X, "
|
|
|
|
"busy = 0x%08X, tstat = 0x%08X\n", channel,
|
|
|
|
idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY),
|
|
|
|
idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY),
|
|
|
|
idmac_read_icreg(ipu, IDMAC_CHA_BUSY),
|
|
|
|
idmac_read_ipureg(ipu, IPU_TASKS_STAT));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dev_dbg(ipu->dev, "timeout = %d * 10ms\n", 40 - timeout);
|
|
|
|
}
|
|
|
|
/* SDC BG and FG must be disabled before DMA is disabled */
|
|
|
|
if (wait_for_stop && (channel == IDMAC_SDC_0 ||
|
|
|
|
channel == IDMAC_SDC_1)) {
|
|
|
|
for (timeout = 5;
|
|
|
|
timeout && !ipu_irq_status(ichan->eof_irq); timeout--)
|
|
|
|
msleep(5);
|
|
|
|
}
|
|
|
|
|
|
|
|
spin_lock_irqsave(&ipu->lock, flags);
|
|
|
|
|
|
|
|
/* Disable IC task */
|
|
|
|
ipu_ic_disable_task(ipu, channel);
|
|
|
|
|
|
|
|
/* Disable DMA channel(s) */
|
|
|
|
reg = idmac_read_icreg(ipu, IDMAC_CHA_EN);
|
|
|
|
idmac_write_icreg(ipu, reg & ~chan_mask, IDMAC_CHA_EN);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Problem (observed with channel DMAIC_7): after enabling the channel
|
|
|
|
* and initialising buffers, there comes an interrupt with current still
|
|
|
|
* pointing at buffer 0, whereas it should use buffer 0 first and only
|
|
|
|
* generate an interrupt when it is done, then current should already
|
|
|
|
* point to buffer 1. This spurious interrupt also comes on channel
|
|
|
|
* DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the
|
|
|
|
* first interrupt, there comes the second with current correctly
|
|
|
|
* pointing to buffer 1 this time. But sometimes this second interrupt
|
|
|
|
* doesn't come and the channel hangs. Clearing BUFx_RDY when disabling
|
|
|
|
* the channel seems to prevent the channel from hanging, but it doesn't
|
|
|
|
* prevent the spurious interrupt. This might also be unsafe. Think
|
|
|
|
* about the IDMAC controller trying to switch to a buffer, when we
|
|
|
|
* clear the ready bit, and re-enable it a moment later.
|
|
|
|
*/
|
|
|
|
reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY);
|
|
|
|
idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY);
|
|
|
|
idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF0_RDY);
|
|
|
|
|
|
|
|
reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY);
|
|
|
|
idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY);
|
|
|
|
idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF1_RDY);
|
|
|
|
|
|
|
|
spin_unlock_irqrestore(&ipu->lock, flags);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-03-26 00:13:24 +08:00
|
|
|
static struct scatterlist *idmac_sg_next(struct idmac_channel *ichan,
|
|
|
|
struct idmac_tx_desc **desc, struct scatterlist *sg)
|
|
|
|
{
|
|
|
|
struct scatterlist *sgnew = sg ? sg_next(sg) : NULL;
|
|
|
|
|
|
|
|
if (sgnew)
|
|
|
|
/* next sg-element in this list */
|
|
|
|
return sgnew;
|
|
|
|
|
|
|
|
if ((*desc)->list.next == &ichan->queue)
|
|
|
|
/* No more descriptors on the queue */
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* Fetch next descriptor */
|
|
|
|
*desc = list_entry((*desc)->list.next, struct idmac_tx_desc, list);
|
|
|
|
return (*desc)->sg;
|
|
|
|
}
|
|
|
|
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
/*
|
|
|
|
* We have several possibilities here:
|
|
|
|
* current BUF next BUF
|
|
|
|
*
|
|
|
|
* not last sg next not last sg
|
|
|
|
* not last sg next last sg
|
|
|
|
* last sg first sg from next descriptor
|
|
|
|
* last sg NULL
|
|
|
|
*
|
|
|
|
* Besides, the descriptor queue might be empty or not. We process all these
|
|
|
|
* cases carefully.
|
|
|
|
*/
|
|
|
|
static irqreturn_t idmac_interrupt(int irq, void *dev_id)
|
|
|
|
{
|
|
|
|
struct idmac_channel *ichan = dev_id;
|
2009-03-26 00:13:24 +08:00
|
|
|
struct device *dev = &ichan->dma_chan.dev->device;
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
unsigned int chan_id = ichan->dma_chan.chan_id;
|
|
|
|
struct scatterlist **sg, *sgnext, *sgnew = NULL;
|
|
|
|
/* Next transfer descriptor */
|
2009-03-26 00:13:24 +08:00
|
|
|
struct idmac_tx_desc *desc, *descnew;
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
dma_async_tx_callback callback;
|
|
|
|
void *callback_param;
|
|
|
|
bool done = false;
|
2009-03-26 00:13:24 +08:00
|
|
|
u32 ready0, ready1, curbuf, err;
|
|
|
|
unsigned long flags;
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
|
|
|
|
/* IDMAC has cleared the respective BUFx_RDY bit, we manage the buffer */
|
|
|
|
|
2009-03-26 00:13:24 +08:00
|
|
|
dev_dbg(dev, "IDMAC irq %d, buf %d\n", irq, ichan->active_buffer);
|
|
|
|
|
|
|
|
spin_lock_irqsave(&ipu_data.lock, flags);
|
|
|
|
|
|
|
|
ready0 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY);
|
|
|
|
ready1 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY);
|
|
|
|
curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
|
|
|
|
err = idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4);
|
|
|
|
|
|
|
|
if (err & (1 << chan_id)) {
|
|
|
|
idmac_write_ipureg(&ipu_data, 1 << chan_id, IPU_INT_STAT_4);
|
|
|
|
spin_unlock_irqrestore(&ipu_data.lock, flags);
|
|
|
|
/*
|
|
|
|
* Doing this
|
|
|
|
* ichan->sg[0] = ichan->sg[1] = NULL;
|
|
|
|
* you can force channel re-enable on the next tx_submit(), but
|
|
|
|
* this is dirty - think about descriptors with multiple
|
|
|
|
* sg elements.
|
|
|
|
*/
|
|
|
|
dev_warn(dev, "NFB4EOF on channel %d, ready %x, %x, cur %x\n",
|
|
|
|
chan_id, ready0, ready1, curbuf);
|
|
|
|
return IRQ_HANDLED;
|
|
|
|
}
|
|
|
|
spin_unlock_irqrestore(&ipu_data.lock, flags);
|
|
|
|
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
/* Other interrupts do not interfere with this channel */
|
|
|
|
spin_lock(&ichan->lock);
|
|
|
|
if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 &&
|
2009-05-12 15:16:29 +08:00
|
|
|
((curbuf >> chan_id) & 1) == ichan->active_buffer &&
|
|
|
|
!list_is_last(ichan->queue.next, &ichan->queue))) {
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
int i = 100;
|
|
|
|
|
|
|
|
/* This doesn't help. See comment in ipu_disable_channel() */
|
|
|
|
while (--i) {
|
|
|
|
curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
|
|
|
|
if (((curbuf >> chan_id) & 1) != ichan->active_buffer)
|
|
|
|
break;
|
|
|
|
cpu_relax();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!i) {
|
|
|
|
spin_unlock(&ichan->lock);
|
2009-03-26 00:13:24 +08:00
|
|
|
dev_dbg(dev,
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
"IRQ on active buffer on channel %x, active "
|
|
|
|
"%d, ready %x, %x, current %x!\n", chan_id,
|
|
|
|
ichan->active_buffer, ready0, ready1, curbuf);
|
|
|
|
return IRQ_NONE;
|
2009-03-26 00:13:24 +08:00
|
|
|
} else
|
|
|
|
dev_dbg(dev,
|
|
|
|
"Buffer deactivated on channel %x, active "
|
|
|
|
"%d, ready %x, %x, current %x, rest %d!\n", chan_id,
|
|
|
|
ichan->active_buffer, ready0, ready1, curbuf, i);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) ||
|
|
|
|
(!ichan->active_buffer && (ready0 >> chan_id) & 1)
|
|
|
|
)) {
|
|
|
|
spin_unlock(&ichan->lock);
|
2009-03-26 00:13:24 +08:00
|
|
|
dev_dbg(dev,
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
"IRQ with active buffer still ready on channel %x, "
|
|
|
|
"active %d, ready %x, %x!\n", chan_id,
|
|
|
|
ichan->active_buffer, ready0, ready1);
|
|
|
|
return IRQ_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (unlikely(list_empty(&ichan->queue))) {
|
2009-03-26 00:13:24 +08:00
|
|
|
ichan->sg[ichan->active_buffer] = NULL;
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
spin_unlock(&ichan->lock);
|
2009-03-26 00:13:24 +08:00
|
|
|
dev_err(dev,
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
"IRQ without queued buffers on channel %x, active %d, "
|
|
|
|
"ready %x, %x!\n", chan_id,
|
|
|
|
ichan->active_buffer, ready0, ready1);
|
|
|
|
return IRQ_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* active_buffer is a software flag, it shows which buffer we are
|
|
|
|
* currently expecting back from the hardware, IDMAC should be
|
|
|
|
* processing the other buffer already
|
|
|
|
*/
|
|
|
|
sg = &ichan->sg[ichan->active_buffer];
|
|
|
|
sgnext = ichan->sg[!ichan->active_buffer];
|
|
|
|
|
2009-03-26 00:13:24 +08:00
|
|
|
if (!*sg) {
|
|
|
|
spin_unlock(&ichan->lock);
|
|
|
|
return IRQ_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
desc = list_entry(ichan->queue.next, struct idmac_tx_desc, list);
|
|
|
|
descnew = desc;
|
|
|
|
|
|
|
|
dev_dbg(dev, "IDMAC irq %d, dma 0x%08x, next dma 0x%08x, current %d, curbuf 0x%08x\n",
|
|
|
|
irq, sg_dma_address(*sg), sgnext ? sg_dma_address(sgnext) : 0, ichan->active_buffer, curbuf);
|
|
|
|
|
|
|
|
/* Find the descriptor of sgnext */
|
|
|
|
sgnew = idmac_sg_next(ichan, &descnew, *sg);
|
|
|
|
if (sgnext != sgnew)
|
|
|
|
dev_err(dev, "Submitted buffer %p, next buffer %p\n", sgnext, sgnew);
|
|
|
|
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
/*
|
|
|
|
* if sgnext == NULL sg must be the last element in a scatterlist and
|
|
|
|
* queue must be empty
|
|
|
|
*/
|
|
|
|
if (unlikely(!sgnext)) {
|
2009-03-26 00:13:24 +08:00
|
|
|
if (!WARN_ON(sg_next(*sg)))
|
|
|
|
dev_dbg(dev, "Underrun on channel %x\n", chan_id);
|
|
|
|
ichan->sg[!ichan->active_buffer] = sgnew;
|
|
|
|
|
|
|
|
if (unlikely(sgnew)) {
|
|
|
|
ipu_submit_buffer(ichan, descnew, sgnew, !ichan->active_buffer);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
} else {
|
2009-03-26 00:13:24 +08:00
|
|
|
spin_lock_irqsave(&ipu_data.lock, flags);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
ipu_ic_disable_task(&ipu_data, chan_id);
|
2009-03-26 00:13:24 +08:00
|
|
|
spin_unlock_irqrestore(&ipu_data.lock, flags);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
ichan->status = IPU_CHANNEL_READY;
|
|
|
|
/* Continue to check for complete descriptor */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-26 00:13:24 +08:00
|
|
|
/* Calculate and submit the next sg element */
|
|
|
|
sgnew = idmac_sg_next(ichan, &descnew, sgnew);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
|
|
|
|
if (unlikely(!sg_next(*sg)) || !sgnext) {
|
|
|
|
/*
|
|
|
|
* Last element in scatterlist done, remove from the queue,
|
|
|
|
* _init for debugging
|
|
|
|
*/
|
|
|
|
list_del_init(&desc->list);
|
|
|
|
done = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
*sg = sgnew;
|
|
|
|
|
2009-03-26 00:13:24 +08:00
|
|
|
if (likely(sgnew) &&
|
|
|
|
ipu_submit_buffer(ichan, descnew, sgnew, ichan->active_buffer) < 0) {
|
2010-02-11 00:32:38 +08:00
|
|
|
callback = descnew->txd.callback;
|
|
|
|
callback_param = descnew->txd.callback_param;
|
2009-03-26 00:13:24 +08:00
|
|
|
spin_unlock(&ichan->lock);
|
2010-02-11 00:32:38 +08:00
|
|
|
if (callback)
|
|
|
|
callback(callback_param);
|
2009-03-26 00:13:24 +08:00
|
|
|
spin_lock(&ichan->lock);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Flip the active buffer - even if update above failed */
|
|
|
|
ichan->active_buffer = !ichan->active_buffer;
|
|
|
|
if (done)
|
|
|
|
ichan->completed = desc->txd.cookie;
|
|
|
|
|
|
|
|
callback = desc->txd.callback;
|
|
|
|
callback_param = desc->txd.callback_param;
|
|
|
|
|
|
|
|
spin_unlock(&ichan->lock);
|
|
|
|
|
|
|
|
if (done && (desc->txd.flags & DMA_PREP_INTERRUPT) && callback)
|
|
|
|
callback(callback_param);
|
|
|
|
|
|
|
|
return IRQ_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ipu_gc_tasklet(unsigned long arg)
|
|
|
|
{
|
|
|
|
struct ipu *ipu = (struct ipu *)arg;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < IPU_CHANNELS_NUM; i++) {
|
|
|
|
struct idmac_channel *ichan = ipu->channel + i;
|
|
|
|
struct idmac_tx_desc *desc;
|
|
|
|
unsigned long flags;
|
2009-03-26 00:13:24 +08:00
|
|
|
struct scatterlist *sg;
|
|
|
|
int j, k;
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
|
|
|
|
for (j = 0; j < ichan->n_tx_desc; j++) {
|
|
|
|
desc = ichan->desc + j;
|
|
|
|
spin_lock_irqsave(&ichan->lock, flags);
|
|
|
|
if (async_tx_test_ack(&desc->txd)) {
|
|
|
|
list_move(&desc->list, &ichan->free_list);
|
2009-03-26 00:13:24 +08:00
|
|
|
for_each_sg(desc->sg, sg, desc->sg_len, k) {
|
|
|
|
if (ichan->sg[0] == sg)
|
|
|
|
ichan->sg[0] = NULL;
|
|
|
|
else if (ichan->sg[1] == sg)
|
|
|
|
ichan->sg[1] = NULL;
|
|
|
|
}
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
async_tx_clear_ack(&desc->txd);
|
|
|
|
}
|
|
|
|
spin_unlock_irqrestore(&ichan->lock, flags);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-26 00:13:23 +08:00
|
|
|
/* Allocate and initialise a transfer descriptor. */
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
static struct dma_async_tx_descriptor *idmac_prep_slave_sg(struct dma_chan *chan,
|
|
|
|
struct scatterlist *sgl, unsigned int sg_len,
|
|
|
|
enum dma_data_direction direction, unsigned long tx_flags)
|
|
|
|
{
|
|
|
|
struct idmac_channel *ichan = to_idmac_chan(chan);
|
|
|
|
struct idmac_tx_desc *desc = NULL;
|
|
|
|
struct dma_async_tx_descriptor *txd = NULL;
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
/* We only can handle these three channels so far */
|
2009-04-02 17:36:58 +08:00
|
|
|
if (chan->chan_id != IDMAC_SDC_0 && chan->chan_id != IDMAC_SDC_1 &&
|
|
|
|
chan->chan_id != IDMAC_IC_7)
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (direction != DMA_FROM_DEVICE && direction != DMA_TO_DEVICE) {
|
|
|
|
dev_err(chan->device->dev, "Invalid DMA direction %d!\n", direction);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
mutex_lock(&ichan->chan_mutex);
|
|
|
|
|
|
|
|
spin_lock_irqsave(&ichan->lock, flags);
|
|
|
|
if (!list_empty(&ichan->free_list)) {
|
|
|
|
desc = list_entry(ichan->free_list.next,
|
|
|
|
struct idmac_tx_desc, list);
|
|
|
|
|
|
|
|
list_del_init(&desc->list);
|
|
|
|
|
|
|
|
desc->sg_len = sg_len;
|
|
|
|
desc->sg = sgl;
|
|
|
|
txd = &desc->txd;
|
|
|
|
txd->flags = tx_flags;
|
|
|
|
}
|
|
|
|
spin_unlock_irqrestore(&ichan->lock, flags);
|
|
|
|
|
|
|
|
mutex_unlock(&ichan->chan_mutex);
|
|
|
|
|
|
|
|
tasklet_schedule(&to_ipu(to_idmac(chan->device))->tasklet);
|
|
|
|
|
|
|
|
return txd;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Re-select the current buffer and re-activate the channel */
|
|
|
|
static void idmac_issue_pending(struct dma_chan *chan)
|
|
|
|
{
|
|
|
|
struct idmac_channel *ichan = to_idmac_chan(chan);
|
|
|
|
struct idmac *idmac = to_idmac(chan->device);
|
|
|
|
struct ipu *ipu = to_ipu(idmac);
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
/* This is not always needed, but doesn't hurt either */
|
|
|
|
spin_lock_irqsave(&ipu->lock, flags);
|
2009-04-02 17:36:58 +08:00
|
|
|
ipu_select_buffer(chan->chan_id, ichan->active_buffer);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
spin_unlock_irqrestore(&ipu->lock, flags);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Might need to perform some parts of initialisation from
|
|
|
|
* ipu_enable_channel(), but not all, we do not want to reset to buffer
|
|
|
|
* 0, don't need to set priority again either, but re-enabling the task
|
|
|
|
* and the channel might be a good idea.
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
static void __idmac_terminate_all(struct dma_chan *chan)
|
|
|
|
{
|
|
|
|
struct idmac_channel *ichan = to_idmac_chan(chan);
|
|
|
|
struct idmac *idmac = to_idmac(chan->device);
|
|
|
|
unsigned long flags;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
ipu_disable_channel(idmac, ichan,
|
|
|
|
ichan->status >= IPU_CHANNEL_ENABLED);
|
|
|
|
|
|
|
|
tasklet_disable(&to_ipu(idmac)->tasklet);
|
|
|
|
|
|
|
|
/* ichan->queue is modified in ISR, have to spinlock */
|
|
|
|
spin_lock_irqsave(&ichan->lock, flags);
|
|
|
|
list_splice_init(&ichan->queue, &ichan->free_list);
|
|
|
|
|
|
|
|
if (ichan->desc)
|
|
|
|
for (i = 0; i < ichan->n_tx_desc; i++) {
|
|
|
|
struct idmac_tx_desc *desc = ichan->desc + i;
|
|
|
|
if (list_empty(&desc->list))
|
|
|
|
/* Descriptor was prepared, but not submitted */
|
2009-03-26 00:13:23 +08:00
|
|
|
list_add(&desc->list, &ichan->free_list);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
|
|
|
|
async_tx_clear_ack(&desc->txd);
|
|
|
|
}
|
|
|
|
|
|
|
|
ichan->sg[0] = NULL;
|
|
|
|
ichan->sg[1] = NULL;
|
|
|
|
spin_unlock_irqrestore(&ichan->lock, flags);
|
|
|
|
|
|
|
|
tasklet_enable(&to_ipu(idmac)->tasklet);
|
|
|
|
|
|
|
|
ichan->status = IPU_CHANNEL_INITIALIZED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void idmac_terminate_all(struct dma_chan *chan)
|
|
|
|
{
|
|
|
|
struct idmac_channel *ichan = to_idmac_chan(chan);
|
|
|
|
|
|
|
|
mutex_lock(&ichan->chan_mutex);
|
|
|
|
|
|
|
|
__idmac_terminate_all(chan);
|
|
|
|
|
|
|
|
mutex_unlock(&ichan->chan_mutex);
|
|
|
|
}
|
|
|
|
|
2009-04-02 17:36:58 +08:00
|
|
|
#ifdef DEBUG
|
|
|
|
static irqreturn_t ic_sof_irq(int irq, void *dev_id)
|
|
|
|
{
|
|
|
|
struct idmac_channel *ichan = dev_id;
|
|
|
|
printk(KERN_DEBUG "Got SOF IRQ %d on Channel %d\n",
|
|
|
|
irq, ichan->dma_chan.chan_id);
|
2009-04-16 03:54:12 +08:00
|
|
|
disable_irq_nosync(irq);
|
2009-04-02 17:36:58 +08:00
|
|
|
return IRQ_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static irqreturn_t ic_eof_irq(int irq, void *dev_id)
|
|
|
|
{
|
|
|
|
struct idmac_channel *ichan = dev_id;
|
|
|
|
printk(KERN_DEBUG "Got EOF IRQ %d on Channel %d\n",
|
|
|
|
irq, ichan->dma_chan.chan_id);
|
2009-04-16 03:54:12 +08:00
|
|
|
disable_irq_nosync(irq);
|
2009-04-02 17:36:58 +08:00
|
|
|
return IRQ_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ic_sof = -EINVAL, ic_eof = -EINVAL;
|
|
|
|
#endif
|
|
|
|
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
static int idmac_alloc_chan_resources(struct dma_chan *chan)
|
|
|
|
{
|
|
|
|
struct idmac_channel *ichan = to_idmac_chan(chan);
|
|
|
|
struct idmac *idmac = to_idmac(chan->device);
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
/* dmaengine.c now guarantees to only offer free channels */
|
|
|
|
BUG_ON(chan->client_count > 1);
|
|
|
|
WARN_ON(ichan->status != IPU_CHANNEL_FREE);
|
|
|
|
|
|
|
|
chan->cookie = 1;
|
|
|
|
ichan->completed = -ENXIO;
|
|
|
|
|
2009-04-02 17:36:58 +08:00
|
|
|
ret = ipu_irq_map(chan->chan_id);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
if (ret < 0)
|
|
|
|
goto eimap;
|
|
|
|
|
|
|
|
ichan->eof_irq = ret;
|
2009-03-26 00:13:24 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Important to first disable the channel, because maybe someone
|
|
|
|
* used it before us, e.g., the bootloader
|
|
|
|
*/
|
|
|
|
ipu_disable_channel(idmac, ichan, true);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
|
|
|
|
ret = ipu_init_channel(idmac, ichan);
|
|
|
|
if (ret < 0)
|
|
|
|
goto eichan;
|
|
|
|
|
|
|
|
ret = request_irq(ichan->eof_irq, idmac_interrupt, 0,
|
|
|
|
ichan->eof_name, ichan);
|
|
|
|
if (ret < 0)
|
|
|
|
goto erirq;
|
|
|
|
|
2009-04-02 17:36:58 +08:00
|
|
|
#ifdef DEBUG
|
|
|
|
if (chan->chan_id == IDMAC_IC_7) {
|
|
|
|
ic_sof = ipu_irq_map(69);
|
|
|
|
if (ic_sof > 0)
|
|
|
|
request_irq(ic_sof, ic_sof_irq, 0, "IC SOF", ichan);
|
|
|
|
ic_eof = ipu_irq_map(70);
|
|
|
|
if (ic_eof > 0)
|
|
|
|
request_irq(ic_eof, ic_eof_irq, 0, "IC EOF", ichan);
|
|
|
|
}
|
|
|
|
#endif
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
|
|
|
|
ichan->status = IPU_CHANNEL_INITIALIZED;
|
|
|
|
|
2009-04-02 17:36:58 +08:00
|
|
|
dev_dbg(&chan->dev->device, "Found channel 0x%x, irq %d\n",
|
|
|
|
chan->chan_id, ichan->eof_irq);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
erirq:
|
2009-03-26 00:13:24 +08:00
|
|
|
ipu_uninit_channel(idmac, ichan);
|
|
|
|
eichan:
|
2009-04-02 17:36:58 +08:00
|
|
|
ipu_irq_unmap(chan->chan_id);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
eimap:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void idmac_free_chan_resources(struct dma_chan *chan)
|
|
|
|
{
|
|
|
|
struct idmac_channel *ichan = to_idmac_chan(chan);
|
|
|
|
struct idmac *idmac = to_idmac(chan->device);
|
|
|
|
|
|
|
|
mutex_lock(&ichan->chan_mutex);
|
|
|
|
|
|
|
|
__idmac_terminate_all(chan);
|
|
|
|
|
|
|
|
if (ichan->status > IPU_CHANNEL_FREE) {
|
2009-04-02 17:36:58 +08:00
|
|
|
#ifdef DEBUG
|
|
|
|
if (chan->chan_id == IDMAC_IC_7) {
|
|
|
|
if (ic_sof > 0) {
|
|
|
|
free_irq(ic_sof, ichan);
|
|
|
|
ipu_irq_unmap(69);
|
|
|
|
ic_sof = -EINVAL;
|
|
|
|
}
|
|
|
|
if (ic_eof > 0) {
|
|
|
|
free_irq(ic_eof, ichan);
|
|
|
|
ipu_irq_unmap(70);
|
|
|
|
ic_eof = -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
free_irq(ichan->eof_irq, ichan);
|
2009-04-02 17:36:58 +08:00
|
|
|
ipu_irq_unmap(chan->chan_id);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
ichan->status = IPU_CHANNEL_FREE;
|
|
|
|
|
|
|
|
ipu_uninit_channel(idmac, ichan);
|
|
|
|
|
|
|
|
mutex_unlock(&ichan->chan_mutex);
|
|
|
|
|
|
|
|
tasklet_schedule(&to_ipu(idmac)->tasklet);
|
|
|
|
}
|
|
|
|
|
|
|
|
static enum dma_status idmac_is_tx_complete(struct dma_chan *chan,
|
|
|
|
dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used)
|
|
|
|
{
|
|
|
|
struct idmac_channel *ichan = to_idmac_chan(chan);
|
|
|
|
|
|
|
|
if (done)
|
|
|
|
*done = ichan->completed;
|
|
|
|
if (used)
|
|
|
|
*used = chan->cookie;
|
|
|
|
if (cookie != chan->cookie)
|
|
|
|
return DMA_ERROR;
|
|
|
|
return DMA_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int __init ipu_idmac_init(struct ipu *ipu)
|
|
|
|
{
|
|
|
|
struct idmac *idmac = &ipu->idmac;
|
|
|
|
struct dma_device *dma = &idmac->dma;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
dma_cap_set(DMA_SLAVE, dma->cap_mask);
|
|
|
|
dma_cap_set(DMA_PRIVATE, dma->cap_mask);
|
|
|
|
|
|
|
|
/* Compulsory common fields */
|
|
|
|
dma->dev = ipu->dev;
|
|
|
|
dma->device_alloc_chan_resources = idmac_alloc_chan_resources;
|
|
|
|
dma->device_free_chan_resources = idmac_free_chan_resources;
|
|
|
|
dma->device_is_tx_complete = idmac_is_tx_complete;
|
|
|
|
dma->device_issue_pending = idmac_issue_pending;
|
|
|
|
|
|
|
|
/* Compulsory for DMA_SLAVE fields */
|
|
|
|
dma->device_prep_slave_sg = idmac_prep_slave_sg;
|
|
|
|
dma->device_terminate_all = idmac_terminate_all;
|
|
|
|
|
|
|
|
INIT_LIST_HEAD(&dma->channels);
|
|
|
|
for (i = 0; i < IPU_CHANNELS_NUM; i++) {
|
|
|
|
struct idmac_channel *ichan = ipu->channel + i;
|
|
|
|
struct dma_chan *dma_chan = &ichan->dma_chan;
|
|
|
|
|
|
|
|
spin_lock_init(&ichan->lock);
|
|
|
|
mutex_init(&ichan->chan_mutex);
|
|
|
|
|
|
|
|
ichan->status = IPU_CHANNEL_FREE;
|
|
|
|
ichan->sec_chan_en = false;
|
|
|
|
ichan->completed = -ENXIO;
|
|
|
|
snprintf(ichan->eof_name, sizeof(ichan->eof_name), "IDMAC EOF %d", i);
|
|
|
|
|
|
|
|
dma_chan->device = &idmac->dma;
|
|
|
|
dma_chan->cookie = 1;
|
|
|
|
dma_chan->chan_id = i;
|
2009-04-02 17:36:58 +08:00
|
|
|
list_add_tail(&dma_chan->device_node, &dma->channels);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
idmac_write_icreg(ipu, 0x00000070, IDMAC_CONF);
|
|
|
|
|
|
|
|
return dma_async_device_register(&idmac->dma);
|
|
|
|
}
|
|
|
|
|
2009-03-26 00:13:24 +08:00
|
|
|
static void __exit ipu_idmac_exit(struct ipu *ipu)
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct idmac *idmac = &ipu->idmac;
|
|
|
|
|
|
|
|
for (i = 0; i < IPU_CHANNELS_NUM; i++) {
|
|
|
|
struct idmac_channel *ichan = ipu->channel + i;
|
|
|
|
|
|
|
|
idmac_terminate_all(&ichan->dma_chan);
|
|
|
|
idmac_prep_slave_sg(&ichan->dma_chan, NULL, 0, DMA_NONE, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
dma_async_device_unregister(&idmac->dma);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* IPU common probe / remove
|
|
|
|
*/
|
|
|
|
|
2009-03-26 00:13:24 +08:00
|
|
|
static int __init ipu_probe(struct platform_device *pdev)
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
{
|
|
|
|
struct ipu_platform_data *pdata = pdev->dev.platform_data;
|
|
|
|
struct resource *mem_ipu, *mem_ic;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
spin_lock_init(&ipu_data.lock);
|
|
|
|
|
|
|
|
mem_ipu = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
|
|
mem_ic = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
|
|
|
if (!pdata || !mem_ipu || !mem_ic)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
ipu_data.dev = &pdev->dev;
|
|
|
|
|
|
|
|
platform_set_drvdata(pdev, &ipu_data);
|
|
|
|
|
|
|
|
ret = platform_get_irq(pdev, 0);
|
|
|
|
if (ret < 0)
|
|
|
|
goto err_noirq;
|
|
|
|
|
|
|
|
ipu_data.irq_fn = ret;
|
|
|
|
ret = platform_get_irq(pdev, 1);
|
|
|
|
if (ret < 0)
|
|
|
|
goto err_noirq;
|
|
|
|
|
|
|
|
ipu_data.irq_err = ret;
|
|
|
|
ipu_data.irq_base = pdata->irq_base;
|
|
|
|
|
|
|
|
dev_dbg(&pdev->dev, "fn irq %u, err irq %u, irq-base %u\n",
|
|
|
|
ipu_data.irq_fn, ipu_data.irq_err, ipu_data.irq_base);
|
|
|
|
|
|
|
|
/* Remap IPU common registers */
|
|
|
|
ipu_data.reg_ipu = ioremap(mem_ipu->start,
|
|
|
|
mem_ipu->end - mem_ipu->start + 1);
|
|
|
|
if (!ipu_data.reg_ipu) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto err_ioremap_ipu;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Remap Image Converter and Image DMA Controller registers */
|
|
|
|
ipu_data.reg_ic = ioremap(mem_ic->start,
|
|
|
|
mem_ic->end - mem_ic->start + 1);
|
|
|
|
if (!ipu_data.reg_ic) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto err_ioremap_ic;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get IPU clock */
|
2009-02-18 18:55:33 +08:00
|
|
|
ipu_data.ipu_clk = clk_get(&pdev->dev, NULL);
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
if (IS_ERR(ipu_data.ipu_clk)) {
|
|
|
|
ret = PTR_ERR(ipu_data.ipu_clk);
|
|
|
|
goto err_clk_get;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make sure IPU HSP clock is running */
|
|
|
|
clk_enable(ipu_data.ipu_clk);
|
|
|
|
|
|
|
|
/* Disable all interrupts */
|
|
|
|
idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_1);
|
|
|
|
idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_2);
|
|
|
|
idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_3);
|
|
|
|
idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_4);
|
|
|
|
idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_5);
|
|
|
|
|
|
|
|
dev_dbg(&pdev->dev, "%s @ 0x%08lx, fn irq %u, err irq %u\n", pdev->name,
|
|
|
|
(unsigned long)mem_ipu->start, ipu_data.irq_fn, ipu_data.irq_err);
|
|
|
|
|
|
|
|
ret = ipu_irq_attach_irq(&ipu_data, pdev);
|
|
|
|
if (ret < 0)
|
|
|
|
goto err_attach_irq;
|
|
|
|
|
|
|
|
/* Initialize DMA engine */
|
|
|
|
ret = ipu_idmac_init(&ipu_data);
|
|
|
|
if (ret < 0)
|
|
|
|
goto err_idmac_init;
|
|
|
|
|
|
|
|
tasklet_init(&ipu_data.tasklet, ipu_gc_tasklet, (unsigned long)&ipu_data);
|
|
|
|
|
|
|
|
ipu_data.dev = &pdev->dev;
|
|
|
|
|
|
|
|
dev_dbg(ipu_data.dev, "IPU initialized\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
err_idmac_init:
|
|
|
|
err_attach_irq:
|
|
|
|
ipu_irq_detach_irq(&ipu_data, pdev);
|
|
|
|
clk_disable(ipu_data.ipu_clk);
|
|
|
|
clk_put(ipu_data.ipu_clk);
|
|
|
|
err_clk_get:
|
|
|
|
iounmap(ipu_data.reg_ic);
|
|
|
|
err_ioremap_ic:
|
|
|
|
iounmap(ipu_data.reg_ipu);
|
|
|
|
err_ioremap_ipu:
|
|
|
|
err_noirq:
|
|
|
|
dev_err(&pdev->dev, "Failed to probe IPU: %d\n", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-03-26 00:13:24 +08:00
|
|
|
static int __exit ipu_remove(struct platform_device *pdev)
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
{
|
|
|
|
struct ipu *ipu = platform_get_drvdata(pdev);
|
|
|
|
|
|
|
|
ipu_idmac_exit(ipu);
|
|
|
|
ipu_irq_detach_irq(ipu, pdev);
|
|
|
|
clk_disable(ipu->ipu_clk);
|
|
|
|
clk_put(ipu->ipu_clk);
|
|
|
|
iounmap(ipu->reg_ic);
|
|
|
|
iounmap(ipu->reg_ipu);
|
|
|
|
tasklet_kill(&ipu->tasklet);
|
|
|
|
platform_set_drvdata(pdev, NULL);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We need two MEM resources - with IPU-common and Image Converter registers,
|
|
|
|
* including PF_CONF and IDMAC_* registers, and two IRQs - function and error
|
|
|
|
*/
|
|
|
|
static struct platform_driver ipu_platform_driver = {
|
|
|
|
.driver = {
|
|
|
|
.name = "ipu-core",
|
|
|
|
.owner = THIS_MODULE,
|
|
|
|
},
|
2009-03-26 00:13:24 +08:00
|
|
|
.remove = __exit_p(ipu_remove),
|
i.MX31: Image Processing Unit DMA and IRQ drivers
i.MX3x SoCs contain an Image Processing Unit, consisting of a Control
Module (CM), Display Interface (DI), Synchronous Display Controller (SDC),
Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter
(PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC).
CM contains, among other blocks, an Interrupt Generator (IG) and a Clock
and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are
supported over dmaengine and irq-chip APIs respectively.
IDMAC is a specialised DMA controller, its DMA channels cannot be used for
general-purpose operations, even though it might be possible to configure
a memory-to-memory channel for memcpy operation. This driver will not work
with generic dmaengine clients, clients, wishing to use it must use
respective wrapper structures, they also must specify which channels they
require, as channels are hard-wired to specific IPU functions.
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2009-01-20 06:36:21 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static int __init ipu_init(void)
|
|
|
|
{
|
|
|
|
return platform_driver_probe(&ipu_platform_driver, ipu_probe);
|
|
|
|
}
|
|
|
|
subsys_initcall(ipu_init);
|
|
|
|
|
|
|
|
MODULE_DESCRIPTION("IPU core driver");
|
|
|
|
MODULE_LICENSE("GPL v2");
|
|
|
|
MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
|
|
|
|
MODULE_ALIAS("platform:ipu-core");
|