msm: Seperate VFE/AXI register programming from start and stop func.
Decouple AXI and VFE. This will help to control/program VFE and AXI
independently.
Change-Id: Ic892f1ebe1ce0ac29bd95f0852a74de6cfbabcc5
Signed-off-by: Azam Sadiq Pasha Kapatrala Syed <akapatra@codeaurora.org>
diff --git a/drivers/media/video/msm/msm_vfe31_v4l2.c b/drivers/media/video/msm/msm_vfe31_v4l2.c
index 89615ec..d5f37dc 100644
--- a/drivers/media/video/msm/msm_vfe31_v4l2.c
+++ b/drivers/media/video/msm/msm_vfe31_v4l2.c
@@ -367,7 +367,6 @@
static void vfe31_stop(void)
{
- uint8_t axiBusyFlag = true;
unsigned long flags;
atomic_set(&vfe31_ctrl->vstate, 0);
@@ -397,7 +396,52 @@
* at any time. stop camif immediately. */
msm_camera_io_w_mb(CAMIF_COMMAND_STOP_IMMEDIATELY,
vfe31_ctrl->vfebase + VFE_CAMIF_COMMAND);
+}
+void axi_start(void)
+{
+ switch (vfe31_ctrl->operation_mode) {
+ case VFE_OUTPUTS_PREVIEW:
+ case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+ if (vfe31_ctrl->outpath.output_mode &
+ VFE31_OUTPUT_MODE_PRIMARY) {
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+ } else if (vfe31_ctrl->outpath.output_mode &
+ VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
+ }
+ break;
+ default:
+ if (vfe31_ctrl->outpath.output_mode &
+ VFE31_OUTPUT_MODE_SECONDARY) {
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+ } else if (vfe31_ctrl->outpath.output_mode &
+ VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
+ msm_camera_io_w(1, vfe31_ctrl->vfebase +
+ vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch2]);
+ }
+ break;
+ }
+}
+
+void axi_stop(void)
+{
+ uint8_t axiBusyFlag = true;
/* axi halt command. */
msm_camera_io_w(AXI_HALT,
vfe31_ctrl->vfebase + VFE_AXI_CMD);
@@ -954,43 +998,6 @@
}
msm_camera_io_w(irq_comp_mask, vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
- switch (vfe31_ctrl->operation_mode) {
- case VFE_OUTPUTS_PREVIEW:
- case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
- if (vfe31_ctrl->outpath.output_mode &
- VFE31_OUTPUT_MODE_PRIMARY) {
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
- } else if (vfe31_ctrl->outpath.output_mode &
- VFE31_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
- }
- break;
- default:
- if (vfe31_ctrl->outpath.output_mode &
- VFE31_OUTPUT_MODE_SECONDARY) {
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
- } else if (vfe31_ctrl->outpath.output_mode &
- VFE31_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch1]);
- msm_camera_io_w(1, vfe31_ctrl->vfebase +
- vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out1.ch2]);
- }
- break;
- }
msm_camio_bus_scale_cfg(
pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
vfe31_start_common();
@@ -3325,12 +3332,14 @@
cmd->cmd_type != CMD_STATS_RS_BUF_RELEASE &&
cmd->cmd_type != CMD_STATS_CS_BUF_RELEASE &&
cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
- if (copy_from_user(&vfecmd,
- (void __user *)(cmd->value),
- sizeof(vfecmd))) {
- pr_err("%s %d: copy_from_user failed\n", __func__,
- __LINE__);
- return -EFAULT;
+ if (NULL != cmd->value) {
+ if (copy_from_user(&vfecmd,
+ (void __user *)(cmd->value),
+ sizeof(vfecmd))) {
+ pr_err("%s %d: copy_from_user failed\n",
+ __func__, __LINE__);
+ return -EFAULT;
+ }
}
} else {
/* here eith stats release or frame release. */
@@ -3571,6 +3580,14 @@
}
break;
+ case CMD_AXI_START:
+ axi_start();
+ break;
+
+ case CMD_AXI_STOP:
+ axi_stop();
+ break;
+
default:
pr_err("%s Unsupported AXI configuration %x ", __func__,
cmd->cmd_type);
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index d50b778..220752a 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -358,7 +358,6 @@
static void vfe32_stop(void)
{
- uint8_t axiBusyFlag = true;
unsigned long flags;
atomic_set(&vfe32_ctrl->vstate, 0);
@@ -389,31 +388,6 @@
msm_camera_io_w(CAMIF_COMMAND_STOP_IMMEDIATELY,
vfe32_ctrl->vfebase + VFE_CAMIF_COMMAND);
- /* axi halt command. */
- msm_camera_io_w(AXI_HALT,
- vfe32_ctrl->vfebase + VFE_AXI_CMD);
- wmb();
- while (axiBusyFlag) {
- if (msm_camera_io_r(vfe32_ctrl->vfebase + VFE_AXI_STATUS) & 0x1)
- axiBusyFlag = false;
- }
- /* Ensure the write order while writing
- to the command register using the barrier */
- msm_camera_io_w_mb(AXI_HALT_CLEAR,
- vfe32_ctrl->vfebase + VFE_AXI_CMD);
-
- /* after axi halt, then ok to apply global reset. */
- /* enable reset_ack and async timer interrupt only while
- stopping the pipeline.*/
- msm_camera_io_w(0xf0000000,
- vfe32_ctrl->vfebase + VFE_IRQ_MASK_0);
- msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
- vfe32_ctrl->vfebase + VFE_IRQ_MASK_1);
-
- /* Ensure the write order while writing
- to the command register using the barrier */
- msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
- vfe32_ctrl->vfebase + VFE_GLOBAL_RESET);
}
static void vfe32_subdev_notify(int id, int path)
@@ -910,7 +884,6 @@
static int vfe32_start(struct msm_cam_media_controller *pmctl)
{
uint32_t irq_comp_mask = 0;
-
irq_comp_mask =
msm_camera_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
@@ -934,44 +907,6 @@
}
msm_camera_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
- switch (vfe32_ctrl->operation_mode) {
- case VFE_OUTPUTS_PREVIEW:
- case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
- if (vfe32_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_PRIMARY) {
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
- } else if (vfe32_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch2]);
- }
- break;
- default:
- if (vfe32_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_SECONDARY) {
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
- } else if (vfe32_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
- msm_camera_io_w(1, vfe32_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch2]);
- }
- break;
- }
-
msm_camio_bus_scale_cfg(
pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
vfe32_start_common();
@@ -3998,23 +3933,97 @@
vfe32_ctrl->vfebase = 0;
}
+void axi_start(void)
+{
+ switch (vfe32_ctrl->operation_mode) {
+ case VFE_OUTPUTS_PREVIEW:
+ case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+ if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY) {
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
+ } else if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch1]);
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch2]);
+ }
+ break;
+ default:
+ if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY) {
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
+ } else if (vfe32_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch0]);
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
+ msm_camera_io_w(1, vfe32_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch2]);
+ }
+ break;
+ }
+}
+
+void axi_stop(void)
+{
+ uint8_t axiBusyFlag = true;
+ /* axi halt command. */
+ msm_camera_io_w(AXI_HALT,
+ vfe32_ctrl->vfebase + VFE_AXI_CMD);
+ wmb();
+ while (axiBusyFlag) {
+ if (msm_camera_io_r(vfe32_ctrl->vfebase + VFE_AXI_STATUS) & 0x1)
+ axiBusyFlag = false;
+ }
+ /* Ensure the write order while writing
+ to the command register using the barrier */
+ msm_camera_io_w_mb(AXI_HALT_CLEAR,
+ vfe32_ctrl->vfebase + VFE_AXI_CMD);
+
+ /* after axi halt, then ok to apply global reset. */
+ /* enable reset_ack and async timer interrupt only while
+ stopping the pipeline.*/
+ msm_camera_io_w(0xf0000000,
+ vfe32_ctrl->vfebase + VFE_IRQ_MASK_0);
+ msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
+ vfe32_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+ /* Ensure the write order while writing
+ to the command register using the barrier */
+ msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
+ vfe32_ctrl->vfebase + VFE_GLOBAL_RESET);
+}
+
static int msm_axi_config(struct v4l2_subdev *sd, void __user *arg)
{
struct msm_vfe_cfg_cmd cfgcmd;
struct msm_isp_cmd vfecmd;
int rc = 0;
- if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
- ERR_COPY_FROM_USER();
- return -EFAULT;
+ if (NULL != arg) {
+ if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
+ ERR_COPY_FROM_USER();
+ return -EFAULT;
+ }
}
-
- if (copy_from_user(&vfecmd,
- (void __user *)(cfgcmd.value),
- sizeof(vfecmd))) {
- pr_err("%s %d: copy_from_user failed\n", __func__,
- __LINE__);
- return -EFAULT;
+ if (NULL != cfgcmd.value) {
+ if (copy_from_user(&vfecmd,
+ (void __user *)(cfgcmd.value),
+ sizeof(vfecmd))) {
+ pr_err("%s %d: copy_from_user failed\n", __func__,
+ __LINE__);
+ return -EFAULT;
+ }
}
switch (cfgcmd.cmd_type) {
@@ -4117,6 +4126,12 @@
pr_err("%s Invalid/Unsupported AXI configuration %x",
__func__, cfgcmd.cmd_type);
break;
+ case CMD_AXI_START:
+ axi_start();
+ break;
+ case CMD_AXI_STOP:
+ axi_stop();
+ break;
default:
pr_err("%s Unsupported AXI configuration %x ", __func__,
cfgcmd.cmd_type);
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index d4cf1d2..8222b67 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -448,6 +448,9 @@
#define CMD_AXI_CFG_SEC 0xF4
#define CMD_AXI_CFG_SEC_ALL_CHNLS 0xF8
+#define CMD_AXI_START 0xE1
+#define CMD_AXI_STOP 0xE2
+
/* vfe config command: config command(from config thread)*/
struct msm_vfe_cfg_cmd {
int cmd_type;