summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTroy Kisky <troy.kisky@boundarydevices.com>2014-03-06 19:17:08 -0700
committerTroy Kisky <troy.kisky@boundarydevices.com>2014-04-24 18:59:50 -0700
commitf67cb7d3ecaeb24323115f8e00dc8813ea61f5fb (patch)
treed54e5b48c08fd74d59aab89e6f8b863572cf4536 /drivers
parente8571c40ffc6a22e31fa12445de5722cc88a0d44 (diff)
add new API ipu_channel_request/disable/free
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c10
-rw-r--r--drivers/media/platform/mxc/capture/ipu_csi_enc.c10
-rw-r--r--drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c10
-rw-r--r--drivers/media/platform/mxc/capture/ipu_prp_enc.c25
-rw-r--r--drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c28
-rw-r--r--drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c24
-rw-r--r--drivers/media/platform/mxc/capture/ipu_still.c11
-rw-r--r--drivers/media/platform/mxc/capture/mxc_v4l2_capture.h2
-rw-r--r--drivers/mxc/ipu3/ipu_common.c53
-rw-r--r--drivers/mxc/ipu3/ipu_prv.h10
10 files changed, 123 insertions, 60 deletions
diff --git a/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c b/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c
index 7b0b7346ef1a..8680f45981ea 100644
--- a/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c
+++ b/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c
@@ -230,9 +230,9 @@ static int csi_enc_setup(cam_data *cam)
}
pr_debug("vf_bufs %x %x\n", cam->vf_bufs[0], cam->vf_bufs[1]);
- err = ipu_init_channel(cam->ipu, CSI_MEM, &params);
- if (err != 0) {
- printk(KERN_ERR "ipu_init_channel %d\n", err);
+ err = ipu_channel_request(cam->ipu, CSI_MEM, &params, &cam->ipu_chan);
+ if (err) {
+ pr_err("%s:ipu_channel_request %d\n", __func__, err);
goto out_1;
}
@@ -389,9 +389,9 @@ static int bg_overlay_stop(void *private)
if (cam->overlay_active == false)
return 0;
- err = ipu_disable_channel(cam->ipu, CSI_MEM, true);
+ err = ipu_channel_disable(cam->ipu_chan, true);
- ipu_uninit_channel(cam->ipu, CSI_MEM);
+ ipu_channel_free(&cam->ipu_chan);
csi_buffer_num = 0;
diff --git a/drivers/media/platform/mxc/capture/ipu_csi_enc.c b/drivers/media/platform/mxc/capture/ipu_csi_enc.c
index fa0091630d00..ad9371567b50 100644
--- a/drivers/media/platform/mxc/capture/ipu_csi_enc.c
+++ b/drivers/media/platform/mxc/capture/ipu_csi_enc.c
@@ -160,9 +160,9 @@ static int csi_enc_setup(cam_data *cam)
}
#endif
- err = ipu_init_channel(cam->ipu, CSI_MEM, &params);
- if (err != 0) {
- printk(KERN_ERR "ipu_init_channel %d\n", err);
+ err = ipu_channel_request(cam->ipu, CSI_MEM, &params, &cam->ipu_chan);
+ if (err) {
+ pr_err("%s:ipu_channel_request %d\n", __func__, err);
return err;
}
@@ -282,9 +282,9 @@ static int csi_enc_disabling_tasks(void *private)
int csi_id;
#endif
- err = ipu_disable_channel(cam->ipu, CSI_MEM, true);
+ err = ipu_channel_disable(cam->ipu_chan, true);
- ipu_uninit_channel(cam->ipu, CSI_MEM);
+ ipu_channel_free(&cam->ipu_chan);
if (cam->dummy_frame.vaddress != 0) {
dma_free_coherent(0, cam->dummy_frame.buffer.length,
diff --git a/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c b/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c
index 012a9374385a..597ecb69b2c7 100644
--- a/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c
+++ b/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c
@@ -236,9 +236,9 @@ static int csi_enc_setup(cam_data *cam)
}
pr_debug("vf_bufs %x %x\n", cam->vf_bufs[0], cam->vf_bufs[1]);
- err = ipu_init_channel(cam->ipu, CSI_MEM, &params);
- if (err != 0) {
- printk(KERN_ERR "ipu_init_channel %d\n", err);
+ err = ipu_channel_request(cam->ipu, CSI_MEM, &params, &cam->ipu_chan);
+ if (err) {
+ pr_err("%s:ipu_channel_request %d\n", __func__, err);
goto out_1;
}
@@ -460,9 +460,9 @@ static int foreground_stop(void *private)
if (cam->overlay_active == false)
return 0;
- err = ipu_disable_channel(cam->ipu, CSI_MEM, true);
+ err = ipu_channel_disable(cam->ipu_chan, true);
- ipu_uninit_channel(cam->ipu, CSI_MEM);
+ ipu_channel_free(&cam->ipu_chan);
csi_buffer_num = 0;
buffer_num = 0;
diff --git a/drivers/media/platform/mxc/capture/ipu_prp_enc.c b/drivers/media/platform/mxc/capture/ipu_prp_enc.c
index 9de0f54190f9..5b4673ac92cc 100644
--- a/drivers/media/platform/mxc/capture/ipu_prp_enc.c
+++ b/drivers/media/platform/mxc/capture/ipu_prp_enc.c
@@ -164,9 +164,9 @@ static int prp_enc_setup(cam_data *cam)
}
#endif
- err = ipu_init_channel(cam->ipu, CSI_PRP_ENC_MEM, &enc);
- if (err != 0) {
- printk(KERN_ERR "ipu_init_channel %d\n", err);
+ err = ipu_channel_request(cam->ipu, CSI_PRP_ENC_MEM, &enc, &cam->ipu_chan);
+ if (err) {
+ pr_err("%s:ipu_channel_request %d\n", __func__, err);
return err;
}
@@ -222,9 +222,9 @@ static int prp_enc_setup(cam_data *cam)
return err;
}
- err = ipu_init_channel(cam->ipu, MEM_ROT_ENC_MEM, NULL);
- if (err != 0) {
- printk(KERN_ERR "MEM_ROT_ENC_MEM channel err\n");
+ err = ipu_channel_request(cam->ipu, MEM_ROT_ENC_MEM, NULL, &cam->ipu_chan_rot);
+ if (err) {
+ pr_err("%s:ipu_channel_request %d for rot\n", __func__, err);
return err;
}
@@ -427,6 +427,7 @@ static int prp_enc_disabling_tasks(void *private)
{
cam_data *cam = (cam_data *) private;
int err = 0;
+ int err2 = 0;
#ifdef CONFIG_MXC_MIPI_CSI2
void *mipi_csi2_info;
int ipu_id;
@@ -438,13 +439,11 @@ static int prp_enc_disabling_tasks(void *private)
ipu_unlink_channels(cam->ipu, CSI_PRP_ENC_MEM, MEM_ROT_ENC_MEM);
}
- err = ipu_disable_channel(cam->ipu, CSI_PRP_ENC_MEM, true);
- if (cam->rotation >= IPU_ROTATE_90_RIGHT)
- err |= ipu_disable_channel(cam->ipu, MEM_ROT_ENC_MEM, true);
+ err = ipu_channel_disable(cam->ipu_chan, true);
+ err2 = ipu_channel_disable(cam->ipu_chan_rot, true);
- ipu_uninit_channel(cam->ipu, CSI_PRP_ENC_MEM);
- if (cam->rotation >= IPU_ROTATE_90_RIGHT)
- ipu_uninit_channel(cam->ipu, MEM_ROT_ENC_MEM);
+ ipu_channel_free(&cam->ipu_chan);
+ ipu_channel_free(&cam->ipu_chan_rot);
if (cam->dummy_frame.vaddress != 0) {
dma_free_coherent(0, cam->dummy_frame.buffer.length,
@@ -468,7 +467,7 @@ static int prp_enc_disabling_tasks(void *private)
}
#endif
- return err;
+ return err ? err : err2;
}
/*!
diff --git a/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c b/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c
index 7a9a4313d8da..e9385ffd0ec8 100644
--- a/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c
+++ b/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c
@@ -199,9 +199,11 @@ static int prpvf_start(void *private)
}
#endif
- err = ipu_init_channel(cam->ipu, CSI_PRP_VF_MEM, &vf);
- if (err != 0)
+ err = ipu_channel_request(cam->ipu, CSI_PRP_VF_MEM, &vf, &cam->ipu_chan);
+ if (err) {
+ pr_err("%s:ipu_channel_request %d\n", __func__, err);
goto out_5;
+ }
if (cam->vf_bufs_vaddr[0]) {
dma_free_coherent(0, cam->vf_bufs_size[0],
@@ -252,9 +254,9 @@ static int prpvf_start(void *private)
if (err != 0)
goto out_3;
- err = ipu_init_channel(cam->ipu, MEM_ROT_VF_MEM, NULL);
- if (err != 0) {
- printk(KERN_ERR "Error MEM_ROT_VF_MEM channel\n");
+ err = ipu_channel_request(cam->ipu, MEM_ROT_VF_MEM, NULL, &cam->ipu_chan_rot);
+ if (err) {
+ pr_err("%s:ipu_channel_request %d for rot\n", __func__, err);
goto out_3;
}
@@ -359,8 +361,7 @@ static int prpvf_start(void *private)
out_1:
ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF, NULL);
out_2:
- if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP)
- ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
+ ipu_channel_free(&cam->ipu_chan_rot);
out_3:
if (cam->vf_bufs_vaddr[0]) {
dma_free_coherent(0, cam->vf_bufs_size[0],
@@ -377,7 +378,7 @@ out_3:
cam->vf_bufs[1] = 0;
}
out_4:
- ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
+ ipu_channel_free(&cam->ipu_chan);
out_5:
return err;
}
@@ -423,13 +424,10 @@ static int prpvf_stop(void *private)
}
buffer_num = 0;
- ipu_disable_channel(cam->ipu, CSI_PRP_VF_MEM, true);
-
- if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP) {
- ipu_disable_channel(cam->ipu, MEM_ROT_VF_MEM, true);
- ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
- }
- ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
+ ipu_channel_disable(cam->ipu_chan, true);
+ ipu_channel_disable(cam->ipu_chan_rot, true);
+ ipu_channel_free(&cam->ipu_chan_rot);
+ ipu_channel_free(&cam->ipu_chan);
console_lock();
fb_blank(fbi, FB_BLANK_POWERDOWN);
diff --git a/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c b/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c
index d22d214aa7ce..fc027b0f0753 100644
--- a/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c
+++ b/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c
@@ -184,9 +184,11 @@ static int prpvf_start(void *private)
}
#endif
- err = ipu_init_channel(cam->ipu, CSI_PRP_VF_MEM, &vf);
- if (err != 0)
+ err = ipu_channel_request(cam->ipu, CSI_PRP_VF_MEM, &vf, &cam->ipu_chan);
+ if (err) {
+ pr_err("%s:ipu_channel_request %d\n", __func__, err);
goto out_4;
+ }
if (cam->vf_bufs_vaddr[0]) {
dma_free_coherent(0, cam->vf_bufs_size[0],
@@ -232,9 +234,9 @@ static int prpvf_start(void *private)
printk(KERN_ERR "Error initializing CSI_PRP_VF_MEM\n");
goto out_3;
}
- err = ipu_init_channel(cam->ipu, MEM_ROT_VF_MEM, NULL);
- if (err != 0) {
- printk(KERN_ERR "Error MEM_ROT_VF_MEM channel\n");
+ err = ipu_channel_request(cam->ipu, MEM_ROT_VF_MEM, NULL, &cam->ipu_chan_rot);
+ if (err) {
+ pr_err("%s:ipu_channel_request %d for rot\n", __func__, err);
goto out_3;
}
@@ -313,9 +315,9 @@ static int prpvf_start(void *private)
out_1:
ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF, NULL);
out_2:
- ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
+ ipu_channel_free(&cam->ipu_chan_rot);
out_3:
- ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
+ ipu_channel_free(&cam->ipu_chan);
out_4:
if (cam->vf_bufs_vaddr[0]) {
dma_free_coherent(0, cam->vf_bufs_size[0],
@@ -366,10 +368,10 @@ static int prpvf_stop(void *private)
ipu_free_irq(disp_ipu, IPU_IRQ_BG_SF_END, cam);
- ipu_disable_channel(cam->ipu, CSI_PRP_VF_MEM, true);
- ipu_disable_channel(cam->ipu, MEM_ROT_VF_MEM, true);
- ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
- ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
+ ipu_channel_disable(cam->ipu_chan, true);
+ ipu_channel_disable(cam->ipu_chan_rot, true);
+ ipu_channel_free(&cam->ipu_chan);
+ ipu_channel_free(&cam->ipu_chan_rot);
#ifdef CONFIG_MXC_MIPI_CSI2
mipi_csi2_info = mipi_csi2_get_info();
diff --git a/drivers/media/platform/mxc/capture/ipu_still.c b/drivers/media/platform/mxc/capture/ipu_still.c
index 3a44be965eda..fd3e2210fb3a 100644
--- a/drivers/media/platform/mxc/capture/ipu_still.c
+++ b/drivers/media/platform/mxc/capture/ipu_still.c
@@ -123,9 +123,11 @@ static int prp_still_start(void *private)
}
memset(&params, 0, sizeof(params));
- err = ipu_init_channel(cam->ipu, CSI_MEM, &params);
- if (err != 0)
+ err = ipu_channel_request(cam->ipu, CSI_MEM, &params, &cam->ipu_chan);
+ if (err) {
+ pr_err("%s:ipu_channel_request %d\n", __func__, err);
return err;
+ }
err = ipu_init_channel_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
pixel_fmt, cam->v2f.fmt.pix.width,
@@ -193,9 +195,8 @@ static int prp_still_stop(void *private)
#endif
cam_ipu_disable_csi(cam);
- ipu_disable_channel(cam->ipu, CSI_MEM, true);
- ipu_uninit_channel(cam->ipu, CSI_MEM);
-
+ ipu_channel_disable(cam->ipu_chan, true);
+ ipu_channel_free(&cam->ipu_chan);
return err;
}
diff --git a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h
index 3c0b515e0abb..e9a1566d18e7 100644
--- a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h
+++ b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h
@@ -203,6 +203,8 @@ typedef struct _cam_data {
bool overlay_on;
bool capture_on;
bool ipu_enable_csi_called;
+ struct ipu_chan *ipu_chan;
+ struct ipu_chan *ipu_chan_rot;
int overlay_pid;
int capture_pid;
bool low_power;
diff --git a/drivers/mxc/ipu3/ipu_common.c b/drivers/mxc/ipu3/ipu_common.c
index 7e2ed9672273..74bd861dd7af 100644
--- a/drivers/mxc/ipu3/ipu_common.c
+++ b/drivers/mxc/ipu3/ipu_common.c
@@ -932,6 +932,38 @@ err:
}
EXPORT_SYMBOL(ipu_init_channel);
+int32_t ipu_channel_request(struct ipu_soc *ipu, ipu_channel_t channel,
+ ipu_channel_params_t *params, struct ipu_chan **p_ipu_chan)
+{
+ struct ipu_chan *ipu_chan;
+ unsigned channel_id = IPU_CHAN_ID(channel);
+ int32_t ret;
+
+ dev_dbg(ipu->dev, "init channel = %d\n", channel_id);
+ *p_ipu_chan = NULL;
+ if (channel_id >= ARRAY_SIZE(ipu->chan)) {
+ dev_err(ipu->dev, "%s: ch = %d is too big!\n", __func__,
+ channel_id);
+ return -ENODEV;
+ }
+ ipu_chan = &ipu->chan[channel_id];
+ if (ipu_chan->p_ipu_chan && (ipu_chan->p_ipu_chan != p_ipu_chan)) {
+ dev_err(ipu->dev, "%s: ch = %d is busy!\n", __func__,
+ channel_id);
+ return -EBUSY;
+ }
+ ipu_chan->p_ipu_chan = p_ipu_chan;
+ ipu_chan->ipu = ipu;
+ ipu_chan->channel = channel;
+ ret = ipu_init_channel(ipu, channel, params);
+ if (ret)
+ ipu_chan->p_ipu_chan = NULL;
+ else
+ *p_ipu_chan = ipu_chan;
+ return ret;
+}
+EXPORT_SYMBOL(ipu_channel_request);
+
/*!
* This function is called to uninitialize a logical IPU channel.
*
@@ -1170,6 +1202,18 @@ void ipu_uninit_channel(struct ipu_soc *ipu, ipu_channel_t channel)
}
EXPORT_SYMBOL(ipu_uninit_channel);
+void ipu_channel_free(struct ipu_chan **p_ipu_chan)
+{
+ struct ipu_chan *ipu_chan = *p_ipu_chan;
+
+ *p_ipu_chan = NULL;
+ if (ipu_chan) {
+ ipu_chan->p_ipu_chan = NULL;
+ ipu_uninit_channel(ipu_chan->ipu, ipu_chan->channel);
+ }
+}
+EXPORT_SYMBOL(ipu_channel_free);
+
/*!
* This function is called to initialize buffer(s) for logical IPU channel.
*
@@ -2472,6 +2516,15 @@ int32_t ipu_disable_channel(struct ipu_soc *ipu, ipu_channel_t channel, bool wai
}
EXPORT_SYMBOL(ipu_disable_channel);
+int32_t ipu_channel_disable(struct ipu_chan *ipu_chan, bool wait_for_stop)
+{
+ if (ipu_chan)
+ if (!IS_ERR(ipu_chan))
+ return ipu_disable_channel(ipu_chan->ipu, ipu_chan->channel, wait_for_stop);
+ return 0;
+}
+EXPORT_SYMBOL(ipu_channel_disable);
+
/*!
* This function enables CSI.
*
diff --git a/drivers/mxc/ipu3/ipu_prv.h b/drivers/mxc/ipu3/ipu_prv.h
index 076339813809..ff3fee55ae4b 100644
--- a/drivers/mxc/ipu3/ipu_prv.h
+++ b/drivers/mxc/ipu3/ipu_prv.h
@@ -62,6 +62,14 @@ struct ipu_pltfm_data {
bool bypass_reset;
};
+struct ipu_soc;
+
+struct ipu_chan {
+ struct ipu_soc *ipu;
+ ipu_channel_t channel;
+ struct ipu_chan **p_ipu_chan;
+};
+
struct ipu_soc {
bool online;
struct ipu_pltfm_data *pdata;
@@ -78,7 +86,7 @@ struct ipu_soc {
int irq_sync;
int irq_err;
struct ipu_irq_node irq_list[IPU_IRQ_COUNT];
-
+ struct ipu_chan chan[32];
/*reg*/
void __iomem *cm_reg;
void __iomem *idmac_reg;