Merge "defconfig: 8974: Disable DCC TTY"
diff --git a/arch/arm/boot/dts/msm8974_pm.dtsi b/arch/arm/boot/dts/msm8974_pm.dtsi
index 9c932d0..79de997 100644
--- a/arch/arm/boot/dts/msm8974_pm.dtsi
+++ b/arch/arm/boot/dts/msm8974_pm.dtsi
@@ -116,7 +116,7 @@
qcom,vctl-timeout-us = <50>;
qcom,vctl-port = <0x0>;
qcom,phase-port = <0x1>;
- qcom,saw2-spm-cmd-ret = [0b 00 20 03 22 00 0f];
+ qcom,saw2-spm-cmd-ret = [00 20 03 22 00 0f];
qcom,saw2-spm-cmd-gdhs = [00 20 32 0b 42 07 44 22 50 02 32 50
0f];
qcom,saw2-spm-cmd-pc = [00 10 32 b0 11 0b 42 07 01 b0 12 44 a0
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index de09083..20425e27 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -86,6 +86,7 @@
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_WAKELOCK=y
CONFIG_PM_RUNTIME=y
CONFIG_NET=y
CONFIG_PACKET=y
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index 722b8ea..bc1eded 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -323,6 +323,40 @@
},
};
+static struct msm_bus_vectors cam_dual_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VFE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 348192000,
+ .ib = 1208286720,
+ },
+ {
+ .src = MSM_BUS_MASTER_VPE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 206807040,
+ .ib = 488816640,
+ },
+ {
+ .src = MSM_BUS_MASTER_JPEG_ENC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 540000000,
+ .ib = 1350000000,
+ },
+ {
+ .src = MSM_BUS_MASTER_JPEG_ENC,
+ .dst = MSM_BUS_SLAVE_MM_IMEM,
+ .ab = 43200000,
+ .ib = 69120000,
+ },
+ {
+ .src = MSM_BUS_MASTER_VFE,
+ .dst = MSM_BUS_SLAVE_MM_IMEM,
+ .ab = 43200000,
+ .ib = 69120000,
+ },
+};
+
+
static struct msm_bus_paths cam_bus_client_config[] = {
{
ARRAY_SIZE(cam_init_vectors),
@@ -348,6 +382,10 @@
ARRAY_SIZE(cam_video_ls_vectors),
cam_video_ls_vectors,
},
+ {
+ ARRAY_SIZE(cam_dual_vectors),
+ cam_dual_vectors,
+ },
};
static struct msm_bus_scale_pdata cam_bus_client_pdata = {
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index 04326aa..3c3293d 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -126,7 +126,7 @@
PM8921_GPIO_INPUT(35, PM_GPIO_PULL_UP_30),
PM8921_GPIO_INPUT(38, PM_GPIO_PULL_UP_30),
/* TABLA CODEC RESET */
- PM8921_GPIO_OUTPUT(34, 0, MED),
+ PM8921_GPIO_OUTPUT(34, 1, HIGH),
PM8921_GPIO_OUTPUT(13, 0, HIGH), /* PCIE_CLK_PWR_EN */
PM8921_GPIO_INPUT(12, PM_GPIO_PULL_UP_30), /* PCIE_WAKE_N */
};
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index 1a5924d..d41eef3 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -33,6 +33,8 @@
REGULATOR_SUPPLY("mipi_csi_vdd", "msm_csid.2"),
REGULATOR_SUPPLY("lvds_pll_vdda", "lvds.0"),
REGULATOR_SUPPLY("dsi1_pll_vdda", "mipi_dsi.1"),
+ REGULATOR_SUPPLY("HRD_VDDD_CDC_D", "tabla2x-slim"),
+ REGULATOR_SUPPLY("HRD_CDC_VDDA_A_1P2V", "tabla2x-slim"),
};
VREG_CONSUMERS(L3) = {
REGULATOR_SUPPLY("8921_l3", NULL),
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index f1143de..852a138 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1222,6 +1222,74 @@
},
};
+static struct wcd9xxx_pdata mpq8064_ashiko20_platform_data = {
+ .slimbus_slave_device = {
+ .name = "tabla-slave",
+ .e_addr = {0, 0, 0x60, 0, 0x17, 2},
+ },
+ .irq = MSM_GPIO_TO_INT(42),
+ .irq_base = TABLA_INTERRUPT_BASE,
+ .num_irqs = NR_WCD9XXX_IRQS,
+ .reset_gpio = PM8921_GPIO_PM_TO_SYS(34),
+ .micbias = {
+ .ldoh_v = TABLA_LDOH_2P85_V,
+ .cfilt1_mv = 1800,
+ .cfilt2_mv = 1800,
+ .cfilt3_mv = 1800,
+ .bias1_cfilt_sel = TABLA_CFILT1_SEL,
+ .bias2_cfilt_sel = TABLA_CFILT2_SEL,
+ .bias3_cfilt_sel = TABLA_CFILT3_SEL,
+ .bias4_cfilt_sel = TABLA_CFILT3_SEL,
+ },
+ .regulator = {
+ {
+ .name = "CDC_VDD_CP",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .optimum_uA = WCD9XXX_CDC_VDDA_CP_CUR_MAX,
+ },
+ {
+ .name = "CDC_VDDA_RX",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .optimum_uA = WCD9XXX_CDC_VDDA_RX_CUR_MAX,
+ },
+ {
+ .name = "CDC_VDDA_TX",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .optimum_uA = WCD9XXX_CDC_VDDA_TX_CUR_MAX,
+ },
+ {
+ .name = "VDDIO_CDC",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .optimum_uA = WCD9XXX_VDDIO_CDC_CUR_MAX,
+ },
+ {
+ .name = "HRD_VDDD_CDC_D",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .optimum_uA = WCD9XXX_VDDD_CDC_D_CUR_MAX,
+ },
+ {
+ .name = "HRD_CDC_VDDA_A_1P2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .optimum_uA = WCD9XXX_VDDD_CDC_A_CUR_MAX,
+ },
+ },
+};
+
+static struct slim_device mpq8064_slim_ashiko20 = {
+ .name = "tabla2x-slim",
+ .e_addr = {0, 1, 0x60, 0, 0x17, 2},
+ .dev = {
+ .platform_data = &mpq8064_ashiko20_platform_data,
+ },
+};
+
+
/* enable the level shifter for cs8427 to make sure the I2C
* clock is running at 100KHz and voltage levels are at 3.3
* and 5 volts
@@ -2537,7 +2605,9 @@
static int rf4ce_gpio_init(void)
{
- if (!machine_is_mpq8064_cdp())
+ if (!machine_is_mpq8064_cdp() &&
+ !machine_is_mpq8064_hrd() &&
+ !machine_is_mpq8064_dtv())
return -EINVAL;
/* CC2533 SRDY Input */
@@ -3285,6 +3355,10 @@
}
}
platform_device_register(&apq8064_slim_ctrl);
+ if (machine_is_mpq8064_hrd() || machine_is_mpq8064_dtv()) {
+ apq8064_slim_devices[ARRAY_SIZE(apq8064_slim_devices) - 1].\
+ slim_slave = &mpq8064_slim_ashiko20;
+ }
slim_register_board_info(apq8064_slim_devices,
ARRAY_SIZE(apq8064_slim_devices));
if (!PLATFORM_IS_MPQ8064()) {
diff --git a/arch/arm/mach-msm/board-8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
index 1352928..883e04d 100644
--- a/arch/arm/mach-msm/board-8930-camera.c
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -331,6 +331,28 @@
},
};
+static struct msm_bus_vectors cam_dual_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VFE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 302071680,
+ .ib = 1208286720,
+ },
+ {
+ .src = MSM_BUS_MASTER_VPE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 206807040,
+ .ib = 488816640,
+ },
+ {
+ .src = MSM_BUS_MASTER_JPEG_ENC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 540000000,
+ .ib = 1350000000,
+ },
+};
+
+
static struct msm_bus_paths cam_bus_client_config[] = {
{
ARRAY_SIZE(cam_init_vectors),
@@ -356,6 +378,10 @@
ARRAY_SIZE(cam_video_ls_vectors),
cam_video_ls_vectors,
},
+ {
+ ARRAY_SIZE(cam_dual_vectors),
+ cam_dual_vectors,
+ },
};
static struct msm_bus_scale_pdata cam_bus_client_pdata = {
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index c00535b..792eea4 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -400,6 +400,40 @@
},
};
+static struct msm_bus_vectors cam_dual_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VFE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 348192000,
+ .ib = 1208286720,
+ },
+ {
+ .src = MSM_BUS_MASTER_VPE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 206807040,
+ .ib = 488816640,
+ },
+ {
+ .src = MSM_BUS_MASTER_JPEG_ENC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 540000000,
+ .ib = 1350000000,
+ },
+ {
+ .src = MSM_BUS_MASTER_JPEG_ENC,
+ .dst = MSM_BUS_SLAVE_MM_IMEM,
+ .ab = 43200000,
+ .ib = 69120000,
+ },
+ {
+ .src = MSM_BUS_MASTER_VFE,
+ .dst = MSM_BUS_SLAVE_MM_IMEM,
+ .ab = 43200000,
+ .ib = 69120000,
+ },
+};
+
+
static struct msm_bus_paths cam_bus_client_config[] = {
{
@@ -426,6 +460,10 @@
ARRAY_SIZE(cam_video_ls_vectors),
cam_video_ls_vectors,
},
+ {
+ ARRAY_SIZE(cam_dual_vectors),
+ cam_dual_vectors,
+ },
};
static struct msm_bus_scale_pdata cam_bus_client_pdata = {
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 6298d94..60ccded 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -632,6 +632,7 @@
S_STEREO_CAPTURE,
S_DEFAULT,
S_LIVESHOT,
+ S_DUAL,
S_EXIT
};
diff --git a/arch/arm/mach-msm/modem-8960.c b/arch/arm/mach-msm/modem-8960.c
index 844a78b..f0a123b 100644
--- a/arch/arm/mach-msm/modem-8960.c
+++ b/arch/arm/mach-msm/modem-8960.c
@@ -258,8 +258,7 @@
{
int ret;
- if (!cpu_is_msm8960() && !cpu_is_msm8930() && !cpu_is_msm8930aa() &&
- !cpu_is_msm9615() && !cpu_is_msm8627())
+ if (cpu_is_apq8064())
return -ENODEV;
ret = smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_RESET,
diff --git a/arch/arm/mach-msm/rpm-smd.c b/arch/arm/mach-msm/rpm-smd.c
index b112c90..a190342 100644
--- a/arch/arm/mach-msm/rpm-smd.c
+++ b/arch/arm/mach-msm/rpm-smd.c
@@ -823,7 +823,6 @@
unsigned long flags;
int rc = 0;
uint32_t id = 0;
- int count = 0;
if (!msg_id) {
pr_err("%s(): Invalid msg id\n", __func__);
@@ -853,7 +852,7 @@
goto wait_ack_cleanup;
}
- while ((id != msg_id) && (count++ < 10)) {
+ while (id != msg_id) {
if (smd_is_pkt_avail(msm_rpm_data.ch_info)) {
int errno;
char buf[MAX_ERR_BUFFER_SIZE] = {};
@@ -862,17 +861,11 @@
id = msm_rpm_get_msg_id_from_ack(buf);
errno = msm_rpm_get_error_from_ack(buf);
msm_rpm_process_ack(id, errno);
- } else
- udelay(100);
+ }
}
- if (count == 10) {
- rc = -ETIMEDOUT;
- pr_warn("%s(): Timed out after 1ms\n", __func__);
- } else {
- rc = elem->errno;
- msm_rpm_free_list_entry(elem);
- }
+ rc = elem->errno;
+ msm_rpm_free_list_entry(elem);
wait_ack_cleanup:
irq_process = false;
spin_unlock_irqrestore(&msm_rpm_data.smd_lock_read, flags);
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 7618e68..739dcb5 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -459,6 +459,15 @@
clk_unprepare(pwr->grp_clks[i]);
}
kgsl_pwrctrl_busy_time(device, true);
+ } else if (requested_state == KGSL_STATE_SLEEP) {
+ /* High latency clock maintenance. */
+ if ((pwr->pwrlevels[0].gpu_freq > 0))
+ clk_set_rate(pwr->grp_clks[0],
+ pwr->pwrlevels[pwr->num_pwrlevels - 1].
+ gpu_freq);
+ for (i = KGSL_MAX_CLKS - 1; i > 0; i--)
+ if (pwr->grp_clks[i])
+ clk_unprepare(pwr->grp_clks[i]);
}
} else if (state == KGSL_PWRFLAGS_ON) {
if (!test_and_set_bit(KGSL_PWRFLAGS_CLK_ON,
@@ -851,7 +860,6 @@
static int
_sleep(struct kgsl_device *device)
{
- struct kgsl_pwrctrl *pwr = &device->pwrctrl;
switch (device->state) {
case KGSL_STATE_ACTIVE:
if (!device->ftbl->isidle(device)) {
@@ -862,10 +870,6 @@
case KGSL_STATE_NAP:
kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_OFF);
- if (pwr->pwrlevels[0].gpu_freq > 0)
- clk_set_rate(pwr->grp_clks[0],
- pwr->pwrlevels[pwr->num_pwrlevels - 1].
- gpu_freq);
_sleep_accounting(device);
kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF, KGSL_STATE_SLEEP);
kgsl_pwrctrl_set_state(device, KGSL_STATE_SLEEP);
diff --git a/drivers/media/video/msm/csi/msm_csid.c b/drivers/media/video/msm/csi/msm_csid.c
index 6274a20..535ea0a 100644
--- a/drivers/media/video/msm/csi/msm_csid.c
+++ b/drivers/media/video/msm/csi/msm_csid.c
@@ -61,6 +61,7 @@
((csid_lut_params->vc_cfg[i].cid % 4) * 8));
msm_camera_io_w(val, csidbase + CSID_CID_LUT_VC_0_ADDR +
(csid_lut_params->vc_cfg[i].cid >> 2) * 4);
+
val = (csid_lut_params->vc_cfg[i].decode_format << 4) | 0x3;
msm_camera_io_w(val, csidbase + CSID_CID_n_CFG_ADDR +
(csid_lut_params->vc_cfg[i].cid * 4));
diff --git a/drivers/media/video/msm/csi/msm_ispif.c b/drivers/media/video/msm/csi/msm_ispif.c
index e3f1ebe..62858a8 100644
--- a/drivers/media/video/msm/csi/msm_ispif.c
+++ b/drivers/media/video/msm/csi/msm_ispif.c
@@ -29,7 +29,6 @@
static atomic_t ispif_irq_cnt;
static spinlock_t ispif_tasklet_lock;
-static spinlock_t ispif_sof_lock;
static struct list_head ispif_tasklet_q;
static int msm_ispif_intf_reset(struct ispif_device *ispif,
@@ -343,10 +342,9 @@
static void msm_ispif_intf_cmd(struct ispif_device *ispif, uint16_t intfmask,
uint8_t intf_cmd_mask, uint8_t vfe_intf)
{
- uint8_t vc = 0;
+ uint8_t vc = 0, val = 0;
uint16_t mask = intfmask, intfnum = 0;
uint32_t cid_mask = 0;
- uint32_t global_intf_cmd_mask = 0xFFFFFFFF;
uint32_t global_intf_cmd_mask1 = 0xFFFFFFFF;
while (mask != 0) {
if (!(intfmask & (0x1 << intfnum))) {
@@ -360,12 +358,15 @@
while (cid_mask != 0) {
if ((cid_mask & 0xf) != 0x0) {
- if (intfnum != RDI2)
- global_intf_cmd_mask &=
- ~((0x3 & ~intf_cmd_mask)
- << ((vc * 2) +
+ if (intfnum != RDI2) {
+ val = (intf_cmd_mask>>(vc*2)) & 0x3;
+ ispif->global_intf_cmd_mask |=
+ (0x3 << ((vc * 2) +
(intfnum * 8)));
- else
+ ispif->global_intf_cmd_mask &=
+ ~((0x3 & ~val) << ((vc * 2) +
+ (intfnum * 8)));
+ } else
global_intf_cmd_mask1 &=
~((0x3 & ~intf_cmd_mask)
<< ((vc * 2) + 8));
@@ -376,7 +377,7 @@
mask >>= 1;
intfnum++;
}
- msm_camera_io_w(global_intf_cmd_mask,
+ msm_camera_io_w(ispif->global_intf_cmd_mask,
ispif->base + ISPIF_INTF_CMD_ADDR + (0x200 * vfe_intf));
if (global_intf_cmd_mask1 != 0xFFFFFFFF)
msm_camera_io_w(global_intf_cmd_mask1,
@@ -388,11 +389,20 @@
uint16_t intfmask, uint8_t vfe_intf)
{
int rc = 0;
- uint8_t intf_cmd_mask = 0x02;
+ uint8_t intf_cmd_mask = 0xAA;
+ uint16_t intfnum = 0, mask = intfmask;
mutex_lock(&ispif->mutex);
CDBG("%s intfmask %x intf_cmd_mask %x\n", __func__, intfmask,
intf_cmd_mask);
msm_ispif_intf_cmd(ispif, intfmask, intf_cmd_mask, vfe_intf);
+ while (mask != 0) {
+ if (intfmask & (0x1 << intfnum))
+ ispif->global_intf_cmd_mask |= (0xFF << (intfnum * 8));
+ mask >>= 1;
+ intfnum++;
+ if (intfnum == RDI2)
+ break;
+ }
mutex_unlock(&ispif->mutex);
return rc;
}
@@ -400,11 +410,11 @@
static int msm_ispif_start_intf_transfer(struct ispif_device *ispif,
uint16_t intfmask, uint8_t vfe_intf)
{
- uint8_t intf_cmd_mask = 0x01;
+ uint8_t intf_cmd_mask = 0x55;
int rc = 0;
mutex_lock(&ispif->mutex);
rc = msm_ispif_intf_reset(ispif, intfmask, vfe_intf);
- CDBG("%s intfmask %x intf_cmd_mask %x\n", __func__, intfmask,
+ CDBG("%s intfmask start after%x intf_cmd_mask %x\n", __func__, intfmask,
intf_cmd_mask);
msm_ispif_intf_cmd(ispif, intfmask, intf_cmd_mask, vfe_intf);
mutex_unlock(&ispif->mutex);
@@ -472,6 +482,9 @@
default:
break;
}
+ if (intfnum != RDI2)
+ ispif->global_intf_cmd_mask |= (0xFF <<
+ (intfnum * 8));
}
mask >>= 1;
intfnum++;
@@ -547,26 +560,6 @@
spin_unlock_irqrestore(&ispif_tasklet_lock,
flags);
- spin_lock_irqsave(&ispif_sof_lock, flags);
- if (qcmd->ispifInterruptStatus0 &
- ISPIF_IRQ_STATUS_RDI0_SOF_MASK) {
- CDBG("%s: ispif RDI0 irq status", __func__);
- ispif->rdi0_sof_count++;
- send_rdi_sof(ispif, RDI_0, ispif->rdi0_sof_count);
- }
- if (qcmd->ispifInterruptStatus1 &
- ISPIF_IRQ_STATUS_RDI1_SOF_MASK) {
- CDBG("%s: ispif RDI1 irq status", __func__);
- ispif->rdi1_sof_count++;
- send_rdi_sof(ispif, RDI_1, ispif->rdi1_sof_count);
- }
- if (qcmd->ispifInterruptStatus2 &
- ISPIF_IRQ_STATUS_RDI2_SOF_MASK) {
- CDBG("%s: ispif RDI2 irq status", __func__);
- ispif->rdi2_sof_count++;
- send_rdi_sof(ispif, RDI_2, ispif->rdi2_sof_count);
- }
- spin_unlock_irqrestore(&ispif_sof_lock, flags);
kfree(qcmd);
}
}
@@ -586,6 +579,7 @@
qcmd->ispifInterruptStatus0 = out->ispifIrqStatus0;
qcmd->ispifInterruptStatus1 = out->ispifIrqStatus1;
qcmd->ispifInterruptStatus2 = out->ispifIrqStatus2;
+
if (qcmd->ispifInterruptStatus0 &
ISPIF_IRQ_STATUS_PIX_SOF_MASK) {
CDBG("%s: ispif PIX irq status", __func__);
@@ -595,6 +589,25 @@
(void *)&ispif->pix_sof_count);
}
+ if (qcmd->ispifInterruptStatus0 &
+ ISPIF_IRQ_STATUS_RDI0_SOF_MASK) {
+ CDBG("%s: ispif RDI0 irq status", __func__);
+ ispif->rdi0_sof_count++;
+ send_rdi_sof(ispif, RDI_0, ispif->rdi0_sof_count);
+ }
+ if (qcmd->ispifInterruptStatus1 &
+ ISPIF_IRQ_STATUS_RDI1_SOF_MASK) {
+ CDBG("%s: ispif RDI1 irq status", __func__);
+ ispif->rdi1_sof_count++;
+ send_rdi_sof(ispif, RDI_1, ispif->rdi1_sof_count);
+ }
+ if (qcmd->ispifInterruptStatus2 &
+ ISPIF_IRQ_STATUS_RDI2_SOF_MASK) {
+ CDBG("%s: ispif RDI2 irq status", __func__);
+ ispif->rdi2_sof_count++;
+ send_rdi_sof(ispif, RDI_2, ispif->rdi2_sof_count);
+ }
+
spin_lock_irqsave(&ispif_tasklet_lock, flags);
list_add_tail(&qcmd->list, &ispif_tasklet_q);
@@ -693,6 +706,7 @@
INIT_LIST_HEAD(&ispif_tasklet_q);
rc = request_irq(ispif->irq->start, msm_io_ispif_irq,
IRQF_TRIGGER_RISING, "ispif", ispif);
+ ispif->global_intf_cmd_mask = 0xFFFFFFFF;
init_completion(&ispif->reset_complete);
tasklet_init(&ispif->ispif_tasklet,
diff --git a/drivers/media/video/msm/csi/msm_ispif.h b/drivers/media/video/msm/csi/msm_ispif.h
index ea69959..d4ca864 100644
--- a/drivers/media/video/msm/csi/msm_ispif.h
+++ b/drivers/media/video/msm/csi/msm_ispif.h
@@ -44,6 +44,7 @@
uint32_t rdi0_sof_count;
uint32_t rdi1_sof_count;
uint32_t rdi2_sof_count;
+ uint32_t global_intf_cmd_mask;
struct tasklet_struct ispif_tasklet;
enum msm_ispif_state_t ispif_state;
};
diff --git a/drivers/media/video/msm/io/msm_io_8960.c b/drivers/media/video/msm/io/msm_io_8960.c
index 699425a..808cc32 100644
--- a/drivers/media/video/msm/io/msm_io_8960.c
+++ b/drivers/media/video/msm/io/msm_io_8960.c
@@ -95,6 +95,14 @@
} else
CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
break;
+ case S_DUAL:
+ if (bus_perf_client) {
+ rc = msm_bus_scale_client_update_request(
+ bus_perf_client, 6);
+ CDBG("%s: S_DUAL rc = %d\n", __func__, rc);
+ } else
+ CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
+ break;
case S_DEFAULT:
break;
default:
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 83f762c..2613986 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -640,6 +640,7 @@
{
struct msm_vfe_cfg_cmd cfgcmd;
int rc = 0;
+ v4l2_set_subdev_hostdata(sd, mctl);
switch (cmd) {
case MSM_CAM_IOCTL_STATS_REQBUF: {
struct msm_stats_reqbuf reqbuf;
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index 1897ee4..c94da2a 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -449,10 +449,11 @@
break;
/* ISFIF config*/
case MSM_CAM_IOCTL_AXI_CONFIG:
- if (p_mctl->axi_sdev)
+ if (p_mctl->axi_sdev) {
+ v4l2_set_subdev_hostdata(p_mctl->axi_sdev, p_mctl);
rc = v4l2_subdev_call(p_mctl->axi_sdev, core, ioctl,
VIDIOC_MSM_AXI_CFG, (void __user *)arg);
- else
+ } else
rc = p_mctl->isp_config(p_mctl, cmd, arg);
break;
case MSM_CAM_IOCTL_ISPIF_IO_CFG:
@@ -478,6 +479,22 @@
core, ioctl, VIDIOC_MSM_CSID_CFG, argp);
break;
+ case MSM_CAM_IOCTL_AXI_INIT:
+ if (p_mctl->axi_sdev) {
+ v4l2_set_subdev_hostdata(p_mctl->axi_sdev, p_mctl);
+ rc = v4l2_subdev_call(p_mctl->axi_sdev, core, ioctl,
+ VIDIOC_MSM_AXI_INIT, (void __user *)arg);
+ }
+ break;
+
+ case MSM_CAM_IOCTL_AXI_RELEASE:
+ if (p_mctl->axi_sdev) {
+ v4l2_set_subdev_hostdata(p_mctl->axi_sdev, p_mctl);
+ rc = v4l2_subdev_call(p_mctl->axi_sdev, core, ioctl,
+ VIDIOC_MSM_AXI_RELEASE, NULL);
+ }
+ break;
+
default:
/* ISP config*/
D("%s:%d: go to default. Calling msm_isp_config\n",
@@ -575,7 +592,6 @@
struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(p_mctl->sensor_sdev);
struct msm_camera_sensor_info *sinfo =
(struct msm_camera_sensor_info *) s_ctrl->sensordata;
-
v4l2_subdev_call(p_mctl->sensor_sdev, core, ioctl,
VIDIOC_MSM_SENSOR_RELEASE, NULL);
@@ -590,6 +606,7 @@
}
if (p_mctl->axi_sdev) {
+ v4l2_set_subdev_hostdata(p_mctl->axi_sdev, p_mctl);
v4l2_subdev_call(p_mctl->axi_sdev, core, ioctl,
VIDIOC_MSM_AXI_RELEASE, NULL);
}
diff --git a/drivers/media/video/msm/vfe/msm_vfe32.c b/drivers/media/video/msm/vfe/msm_vfe32.c
index 2a9c186..6e22388 100644
--- a/drivers/media/video/msm/vfe/msm_vfe32.c
+++ b/drivers/media/video/msm/vfe/msm_vfe32.c
@@ -412,28 +412,166 @@
}
}
+static void axi_enable_wm_irq(struct vfe_share_ctrl_t *share_ctrl)
+{
+ uint32_t irq_mask, irq_comp_mask = 0;
+ uint16_t vfe_output_mode =
+ share_ctrl->outpath.output_mode &
+ ~(VFE32_OUTPUT_MODE_TERTIARY1|
+ VFE32_OUTPUT_MODE_TERTIARY2);
+
+ if (vfe_output_mode)
+ irq_comp_mask =
+ msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_COMP_MASK);
+ irq_mask = msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+
+ if (share_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY) {
+ if (share_ctrl->current_mode == VFE_OUTPUTS_RAW)
+ irq_comp_mask |= (
+ 0x1 << share_ctrl->outpath.out0.ch0);
+ else
+ irq_comp_mask |= (
+ 0x1 << share_ctrl->outpath.out0.ch0 |
+ 0x1 << share_ctrl->outpath.out0.ch1);
+ irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+ } else if (share_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+ irq_comp_mask |= (
+ 0x1 << share_ctrl->outpath.out0.ch0 |
+ 0x1 << share_ctrl->outpath.out0.ch1 |
+ 0x1 << share_ctrl->outpath.out0.ch2);
+ irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+ }
+ if (share_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY) {
+ irq_comp_mask |= (
+ 0x1 << (share_ctrl->outpath.out1.ch0 + 8) |
+ 0x1 << (share_ctrl->outpath.out1.ch1 + 8));
+ irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+ } else if (share_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ irq_comp_mask |= (
+ 0x1 << (share_ctrl->outpath.out1.ch0 + 8) |
+ 0x1 << (share_ctrl->outpath.out1.ch1 + 8) |
+ 0x1 << (share_ctrl->outpath.out1.ch2 + 8));
+ irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+ }
+
+ if (share_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_TERTIARY1) {
+ irq_mask |= (0x1 << (share_ctrl->outpath.out2.ch0 +
+ VFE_WM_OFFSET));
+ }
+
+ if (share_ctrl->outpath.output_mode &
+ VFE32_OUTPUT_MODE_TERTIARY2) {
+ irq_mask |= (0x1 << (share_ctrl->outpath.out3.ch0 +
+ VFE_WM_OFFSET));
+ }
+
+ msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+ if (vfe_output_mode)
+ msm_camera_io_w(irq_comp_mask,
+ share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+}
+
+static void axi_disable_wm_irq(struct vfe_share_ctrl_t *share_ctrl,
+ uint16_t output_mode)
+{
+ uint32_t irq_mask, irq_comp_mask = 0;
+ uint16_t vfe_output_mode =
+ output_mode &
+ ~(VFE32_OUTPUT_MODE_TERTIARY1|
+ VFE32_OUTPUT_MODE_TERTIARY2);
+ if (vfe_output_mode)
+ irq_comp_mask =
+ msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_COMP_MASK);
+ irq_mask = msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+
+ if (output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY) {
+ irq_comp_mask &= ~(
+ 0x1 << share_ctrl->outpath.out0.ch0 |
+ 0x1 << share_ctrl->outpath.out0.ch1);
+ irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+ } else if (output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+ irq_comp_mask &= ~(
+ 0x1 << share_ctrl->outpath.out0.ch0 |
+ 0x1 << share_ctrl->outpath.out0.ch1 |
+ 0x1 << share_ctrl->outpath.out0.ch2);
+ irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+ }
+ if (output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY) {
+ irq_comp_mask &= ~(
+ 0x1 << (share_ctrl->outpath.out1.ch0 + 8) |
+ 0x1 << (share_ctrl->outpath.out1.ch1 + 8));
+ irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+ } else if (output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ irq_comp_mask &= ~(
+ 0x1 << (share_ctrl->outpath.out1.ch0 + 8) |
+ 0x1 << (share_ctrl->outpath.out1.ch1 + 8) |
+ 0x1 << (share_ctrl->outpath.out1.ch2 + 8));
+ irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+ }
+ if (output_mode &
+ VFE32_OUTPUT_MODE_TERTIARY1) {
+ irq_mask &= ~(0x1 << (share_ctrl->outpath.out2.ch0 +
+ VFE_WM_OFFSET));
+ }
+ if (output_mode &
+ VFE32_OUTPUT_MODE_TERTIARY2) {
+ irq_mask &= ~(0x1 << (share_ctrl->outpath.out3.ch0 +
+ VFE_WM_OFFSET));
+ }
+ msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+ if (vfe_output_mode)
+ msm_camera_io_w(irq_comp_mask,
+ share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+}
+
static void axi_enable_irq(struct vfe_share_ctrl_t *share_ctrl)
{
uint32_t irq_mask, irq_mask1;
- uint16_t vfe_operation_mode =
+ uint32_t vfe_mode =
share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
VFE_OUTPUTS_RDI1);
- irq_mask1 =
- msm_camera_io_r(share_ctrl->vfebase +
+
+ if (share_ctrl->axi_ref_cnt == 1) {
+ irq_mask1 =
+ msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_1);
+
+ irq_mask1 |= VFE_IMASK_WHILE_STOPPING_1;
+ msm_camera_io_w(irq_mask1, share_ctrl->vfebase +
+ VFE_IRQ_MASK_1);
+ }
+
+ if (share_ctrl->current_mode & (VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1)) {
+ irq_mask1 =
+ msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_1);
+
+ if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0)
+ irq_mask1 |= VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK;
+
+ if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1)
+ irq_mask1 |= VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK;
+
+ msm_camera_io_w(irq_mask1, share_ctrl->vfebase +
VFE_IRQ_MASK_1);
+ }
- irq_mask1 |= VFE_IMASK_WHILE_STOPPING_1;
-
- if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0)
- irq_mask1 |= VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK;
-
- if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1)
- irq_mask1 |= VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK;
-
- msm_camera_io_w(irq_mask1, share_ctrl->vfebase +
- VFE_IRQ_MASK_1);
-
- if (vfe_operation_mode) {
+ if (vfe_mode) {
irq_mask =
msm_camera_io_r(share_ctrl->vfebase +
VFE_IRQ_MASK_0);
@@ -449,37 +587,39 @@
atomic_set(&share_ctrl->handle_common_irq, 1);
}
-static void axi_disable_irq(struct vfe_share_ctrl_t *share_ctrl)
+static void axi_disable_irq(struct vfe_share_ctrl_t *share_ctrl,
+ uint32_t mode)
{
/* disable all interrupts. */
- uint32_t irq_mask, irq_mask1;
- uint16_t vfe_operation_mode =
- share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
- VFE_OUTPUTS_RDI1);
+ uint32_t irq_mask = 0, irq_mask1 = 0, clear_mask1 = 0;
+ uint32_t vfe_mode =
+ (mode & ~(VFE_OUTPUTS_RDI0|
+ VFE_OUTPUTS_RDI1));
- if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+ if (mode & (VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1)) {
irq_mask1 =
- msm_camera_io_r(share_ctrl->vfebase +
- VFE_IRQ_MASK_1);
- irq_mask1 &= ~(VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK);
+ msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_1);
+
+ if (mode & VFE_OUTPUTS_RDI0) {
+ irq_mask1 &= ~(VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK);
+ clear_mask1 |= VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK;
+ }
+
+ if (mode & VFE_OUTPUTS_RDI1) {
+ irq_mask1 &= ~(VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK);
+ clear_mask1 |= VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK;
+ }
+
msm_camera_io_w(irq_mask1, share_ctrl->vfebase +
VFE_IRQ_MASK_1);
- msm_camera_io_w(VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK,
+ msm_camera_io_w(clear_mask1,
share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
}
- if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
- irq_mask1 =
- msm_camera_io_r(share_ctrl->vfebase +
- VFE_IRQ_MASK_1);
- irq_mask1 &= ~(VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK);
- msm_camera_io_w(irq_mask1, share_ctrl->vfebase +
- VFE_IRQ_MASK_1);
- msm_camera_io_w(VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK,
- share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
- }
- if (vfe_operation_mode) {
+
+ if (vfe_mode) {
atomic_set(&share_ctrl->vstate, 0);
irq_mask =
msm_camera_io_r(share_ctrl->vfebase +
@@ -492,7 +632,7 @@
msm_camera_io_w(irq_mask, share_ctrl->vfebase +
VFE_IRQ_MASK_0);
}
-
+ /*Dont Disable for concurrent*/
if (share_ctrl->axi_ref_cnt == 1) {
atomic_set(&share_ctrl->handle_common_irq, 0);
msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
@@ -517,11 +657,14 @@
/* in either continuous or snapshot mode, stop command can be issued
* at any time. stop camif immediately. */
- msm_camera_io_w(CAMIF_COMMAND_STOP_IMMEDIATELY,
- vfe32_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
+ if (!vfe32_ctrl->share_ctrl->dual_enabled)
+ msm_camera_io_w_mb(CAMIF_COMMAND_STOP_IMMEDIATELY,
+ vfe32_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
+ else
+ msm_camera_io_w(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+ vfe32_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
vfe32_ctrl->share_ctrl->operation_mode &=
- ~(vfe32_ctrl->share_ctrl->current_mode);
- vfe32_ctrl->share_ctrl->current_mode = 0;
+ (VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1);
}
static void vfe32_subdev_notify(int id, int path, uint32_t inst_handle,
@@ -630,8 +773,6 @@
V32_AXI_BUS_CFG_LEN);
axi_cfg += V32_AXI_BUS_CFG_LEN/4;
for (i = 0; i < ARRAY_SIZE(vfe32_AXI_WM_CFG); i++) {
- msm_camera_io_w(*axi_cfg,
- axi_ctrl->share_ctrl->vfebase+vfe32_AXI_WM_CFG[i]);
axi_cfg += 3;
msm_camera_io_memcpy(
axi_ctrl->share_ctrl->vfebase+vfe32_AXI_WM_CFG[i]+12,
@@ -654,6 +795,33 @@
}
static void axi_reset_internal_variables(
+ struct axi_ctrl_t *axi_ctrl,
+ struct msm_camera_vfe_params_t vfe_params)
+{
+ if (vfe_params.operation_mode & VFE_OUTPUTS_RDI0) {
+ atomic_set(&axi_ctrl->share_ctrl->rdi0_update_ack_pending, 0);
+ axi_ctrl->share_ctrl->rdi0_capture_count = -1;
+ axi_ctrl->share_ctrl->outpath.out2.capture_cnt = -1;
+ axi_ctrl->share_ctrl->rdi0FrameId = 0;
+ axi_ctrl->share_ctrl->comp_output_mode &=
+ ~VFE32_OUTPUT_MODE_TERTIARY1;
+ axi_ctrl->share_ctrl->operation_mode &=
+ ~(VFE_OUTPUTS_RDI0);
+ }
+
+ if (vfe_params.operation_mode & VFE_OUTPUTS_RDI1) {
+ atomic_set(&axi_ctrl->share_ctrl->rdi1_update_ack_pending, 0);
+ axi_ctrl->share_ctrl->rdi1_capture_count = -1;
+ axi_ctrl->share_ctrl->outpath.out3.capture_cnt = -1;
+ axi_ctrl->share_ctrl->rdi1FrameId = 0;
+ axi_ctrl->share_ctrl->comp_output_mode &=
+ ~VFE32_OUTPUT_MODE_TERTIARY2;
+ axi_ctrl->share_ctrl->operation_mode &=
+ ~(VFE_OUTPUTS_RDI1);
+ }
+}
+
+static void axi_global_reset_internal_variables(
struct axi_ctrl_t *axi_ctrl)
{
unsigned long flags;
@@ -687,6 +855,12 @@
axi_ctrl->share_ctrl->outpath.output_mode = 0;
axi_ctrl->share_ctrl->comp_output_mode = 0;
axi_ctrl->share_ctrl->vfe_capture_count = 0;
+ axi_ctrl->share_ctrl->rdi0_capture_count = -1;
+ axi_ctrl->share_ctrl->rdi1_capture_count = -1;
+ axi_ctrl->share_ctrl->outpath.out0.capture_cnt = -1;
+ axi_ctrl->share_ctrl->outpath.out1.capture_cnt = -1;
+ axi_ctrl->share_ctrl->outpath.out2.capture_cnt = -1;
+ axi_ctrl->share_ctrl->outpath.out3.capture_cnt = -1;
/* this is unsigned 32 bit integer. */
axi_ctrl->share_ctrl->vfeFrameId = 0;
@@ -695,6 +869,7 @@
axi_ctrl->share_ctrl->rdi2FrameId = 0;
}
+
static void vfe32_program_dmi_cfg(
enum VFE32_DMI_RAM_SEL bankSel,
struct vfe32_ctrl_type *vfe32_ctrl)
@@ -833,6 +1008,17 @@
static void vfe32_reset_internal_variables(
struct vfe32_ctrl_type *vfe32_ctrl)
{
+ unsigned long flags;
+ spin_lock_irqsave(&vfe32_ctrl->share_ctrl->update_ack_lock,
+ flags);
+ vfe32_ctrl->share_ctrl->update_ack_pending = FALSE;
+ spin_unlock_irqrestore(&vfe32_ctrl->share_ctrl->update_ack_lock,
+ flags);
+ vfe32_ctrl->share_ctrl->vfe_capture_count = 0;
+ /* this is unsigned 32 bit integer. */
+ vfe32_ctrl->share_ctrl->vfeFrameId = 0;
+ vfe32_ctrl->share_ctrl->update_counter = 0;
+
/* Stats control variables. */
memset(&(vfe32_ctrl->afbfStatsControl), 0,
sizeof(struct vfe_stats_control));
@@ -854,6 +1040,13 @@
memset(&(vfe32_ctrl->csStatsControl), 0,
sizeof(struct vfe_stats_control));
+ vfe32_ctrl->share_ctrl->outpath.out0.capture_cnt = -1;
+ vfe32_ctrl->share_ctrl->outpath.out1.capture_cnt = -1;
+ vfe32_ctrl->share_ctrl->recording_state = VFE_STATE_IDLE;
+ vfe32_ctrl->share_ctrl->liveshot_state = VFE_STATE_IDLE;
+
+ atomic_set(&vfe32_ctrl->share_ctrl->vstate, 0);
+ atomic_set(&vfe32_ctrl->share_ctrl->pix0_update_ack_pending, 0);
vfe32_ctrl->frame_skip_cnt = 31;
vfe32_ctrl->frame_skip_pattern = 0xffffffff;
@@ -878,6 +1071,11 @@
msm_camera_io_w(irq_mask, vfe32_ctrl->share_ctrl->vfebase +
VFE_IRQ_MASK_0);
+ vfe32_ctrl->share_ctrl->operation_mode &=
+ (VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1);
+ vfe32_ctrl->share_ctrl->comp_output_mode &=
+ (VFE32_OUTPUT_MODE_TERTIARY1|
+ VFE32_OUTPUT_MODE_TERTIARY2);
/* enable reset_ack interrupt. */
irq_mask1 = msm_camera_io_r(
@@ -892,9 +1090,15 @@
&vfe32_ctrl->share_ctrl->reset_complete);
}
-static int axi_reset(struct axi_ctrl_t *axi_ctrl)
+static int axi_reset(struct axi_ctrl_t *axi_ctrl,
+ struct msm_camera_vfe_params_t vfe_params)
{
- axi_reset_internal_variables(axi_ctrl);
+ int rc = 0;
+ if (vfe_params.skip_reset) {
+ axi_reset_internal_variables(axi_ctrl, vfe_params);
+ return rc;
+ }
+ axi_global_reset_internal_variables(axi_ctrl);
/* disable all interrupts. vfeImaskLocal is also reset to 0
* to begin with. */
msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
@@ -1256,17 +1460,11 @@
static void vfe32_start_common(struct vfe32_ctrl_type *vfe32_ctrl)
{
- uint16_t vfe_operation_mode =
- vfe32_ctrl->share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
- VFE_OUTPUTS_RDI1);
CDBG("VFE opertaion mode = 0x%x, output mode = 0x%x\n",
- vfe32_ctrl->share_ctrl->current_mode,
+ vfe32_ctrl->share_ctrl->operation_mode,
vfe32_ctrl->share_ctrl->outpath.output_mode);
-
- if (vfe_operation_mode) {
msm_camera_io_w_mb(1, vfe32_ctrl->share_ctrl->vfebase +
VFE_CAMIF_COMMAND);
- }
}
static int vfe32_start_recording(
@@ -2792,8 +2990,6 @@
goto proc_general_done;
}
- vfe32_ctrl->share_ctrl->current_mode =
- vfe_params.operation_mode;
vfe32_stop(vfe32_ctrl);
break;
@@ -3168,23 +3364,17 @@
}
-void axi_stop_pix(struct vfe_share_ctrl_t *share_ctrl)
+void axi_stop_pix(struct vfe_share_ctrl_t *share_ctrl,
+ uint32_t vfe_mode, uint8_t cmd_type)
{
- uint32_t operation_mode =
- share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
- VFE_OUTPUTS_RDI1);
- uint32_t irq_comp_mask, irq_mask;
uint32_t reg_update = 0x1;
-
- irq_comp_mask =
- msm_camera_io_r(share_ctrl->vfebase +
- VFE_IRQ_COMP_MASK);
- irq_mask = msm_camera_io_r(share_ctrl->vfebase +
- VFE_IRQ_MASK_0);
-
- switch (share_ctrl->cmd_type) {
+ switch (cmd_type) {
+ case AXI_CMD_RAW_CAPTURE:
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe32_AXI_WM_CFG[share_ctrl->outpath.out0.ch0]);
+ break;
case AXI_CMD_PREVIEW: {
- switch (operation_mode) {
+ switch (vfe_mode) {
case VFE_OUTPUTS_PREVIEW:
case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
if (share_ctrl->comp_output_mode &
@@ -3195,11 +3385,6 @@
msm_camera_io_w(0, share_ctrl->vfebase
+ vfe32_AXI_WM_CFG[share_ctrl->
outpath.out0.ch1]);
- irq_comp_mask &= ~(
- 0x1 << share_ctrl->outpath.out0.ch0 |
- 0x1 << share_ctrl->outpath.out0.ch1);
- share_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_PRIMARY;
} else if (share_ctrl->comp_output_mode &
VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
msm_camera_io_w(0, share_ctrl->vfebase
@@ -3211,14 +3396,7 @@
msm_camera_io_w(0, share_ctrl->vfebase
+ vfe32_AXI_WM_CFG[share_ctrl->
outpath.out0.ch2]);
- irq_comp_mask &= ~(
- 0x1 << share_ctrl->outpath.out0.ch0 |
- 0x1 << share_ctrl->outpath.out0.ch1 |
- 0x1 << share_ctrl->outpath.out0.ch2);
- share_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
}
- irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
break;
default:
if (share_ctrl->comp_output_mode &
@@ -3229,11 +3407,6 @@
msm_camera_io_w(0, share_ctrl->vfebase
+ vfe32_AXI_WM_CFG[share_ctrl->
outpath.out1.ch1]);
- irq_comp_mask &= ~(
- 0x1 << share_ctrl->outpath.out1.ch0 |
- 0x1 << share_ctrl->outpath.out1.ch1);
- share_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_SECONDARY;
} else if (share_ctrl->comp_output_mode &
VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
msm_camera_io_w(0, share_ctrl->vfebase
@@ -3245,14 +3418,7 @@
msm_camera_io_w(0, share_ctrl->vfebase
+ vfe32_AXI_WM_CFG[share_ctrl->
outpath.out1.ch2]);
- irq_comp_mask &= ~(
- 0x1 << share_ctrl->outpath.out1.ch0 |
- 0x1 << share_ctrl->outpath.out1.ch1 |
- 0x1 << share_ctrl->outpath.out1.ch2);
- share_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
}
- irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
break;
}
}
@@ -3266,12 +3432,6 @@
msm_camera_io_w(0, share_ctrl->vfebase +
vfe32_AXI_WM_CFG[share_ctrl->
outpath.out0.ch1]);
- irq_comp_mask &= ~(
- 0x1 << share_ctrl->outpath.out0.ch0 |
- 0x1 << share_ctrl->outpath.out0.ch1);
- irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
- share_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_PRIMARY;
} else if (share_ctrl->comp_output_mode &
VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
msm_camera_io_w(0, share_ctrl->vfebase +
@@ -3283,13 +3443,6 @@
msm_camera_io_w(0, share_ctrl->vfebase +
vfe32_AXI_WM_CFG[share_ctrl->
outpath.out0.ch2]);
- irq_comp_mask &= ~(
- 0x1 << share_ctrl->outpath.out0.ch0 |
- 0x1 << share_ctrl->outpath.out0.ch1 |
- 0x1 << share_ctrl->outpath.out0.ch2);
- irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
- share_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
}
if (share_ctrl->comp_output_mode &
@@ -3299,12 +3452,6 @@
outpath.out1.ch0]);
msm_camera_io_w(0, share_ctrl->vfebase +
vfe32_AXI_WM_CFG[share_ctrl->outpath.out1.ch1]);
- irq_comp_mask &= ~(
- 0x1 << share_ctrl->outpath.out1.ch0 |
- 0x1 << share_ctrl->outpath.out1.ch1);
- irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
- share_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_SECONDARY;
} else if (share_ctrl->comp_output_mode &
VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
msm_camera_io_w(0, share_ctrl->vfebase +
@@ -3313,82 +3460,63 @@
vfe32_AXI_WM_CFG[share_ctrl->outpath.out1.ch1]);
msm_camera_io_w(0, share_ctrl->vfebase +
vfe32_AXI_WM_CFG[share_ctrl->outpath.out1.ch2]);
- irq_comp_mask &= ~(
- 0x1 << share_ctrl->outpath.out1.ch0 |
- 0x1 << share_ctrl->outpath.out1.ch1 |
- 0x1 << share_ctrl->outpath.out1.ch2);
- irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
- share_ctrl->outpath.output_mode |=
- VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
}
break;
}
msm_camera_io_w_mb(reg_update,
share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
- msm_camera_io_w(irq_comp_mask,
- share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
- msm_camera_io_w(irq_mask, share_ctrl->vfebase +
- VFE_IRQ_MASK_0);
}
void axi_stop_rdi0(struct vfe_share_ctrl_t *share_ctrl)
{
uint32_t reg_update = 0x2;
- uint32_t irq_mask;
- irq_mask = msm_camera_io_r(share_ctrl->vfebase +
- VFE_IRQ_MASK_0);
-
- if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
- msm_camera_io_w(0, share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[share_ctrl->outpath.out2.ch0]);
- irq_mask &= ~(0x1 << (share_ctrl->outpath.out2.ch0 +
- VFE_WM_OFFSET));
- }
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[share_ctrl->outpath.out2.ch0]);
msm_camera_io_w_mb(reg_update,
share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
- msm_camera_io_w(irq_mask, share_ctrl->vfebase +
- VFE_IRQ_MASK_0);
}
void axi_stop_rdi1(struct vfe_share_ctrl_t *share_ctrl)
{
uint32_t reg_update = 0x4;
- uint32_t irq_mask;
- irq_mask = msm_camera_io_r(share_ctrl->vfebase +
- VFE_IRQ_MASK_0);
-
- if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
- msm_camera_io_w(1, share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[share_ctrl->outpath.out3.ch0]);
- irq_mask &= ~(0x1 << (share_ctrl->outpath.out3.ch0 +
- VFE_WM_OFFSET));
- }
-
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[share_ctrl->outpath.out3.ch0]);
msm_camera_io_w_mb(reg_update,
share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
- msm_camera_io_w(irq_mask, share_ctrl->vfebase +
- VFE_IRQ_MASK_0);
}
void axi_stop_process(struct vfe_share_ctrl_t *share_ctrl)
{
- uint32_t operation_mode =
+ uint32_t vfe_mode =
share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
VFE_OUTPUTS_RDI1);
if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
axi_stop_rdi0(share_ctrl);
+ axi_disable_wm_irq(share_ctrl,
+ VFE32_OUTPUT_MODE_TERTIARY1);
share_ctrl->comp_output_mode &= ~VFE32_OUTPUT_MODE_TERTIARY1;
+ share_ctrl->operation_mode &=
+ ~(VFE_OUTPUTS_RDI0);
}
if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
axi_stop_rdi1(share_ctrl);
+ axi_disable_wm_irq(share_ctrl,
+ VFE32_OUTPUT_MODE_TERTIARY2);
share_ctrl->comp_output_mode &= ~VFE32_OUTPUT_MODE_TERTIARY2;
+ share_ctrl->operation_mode &=
+ ~(VFE_OUTPUTS_RDI1);
}
- if (operation_mode) {
- axi_stop_pix(share_ctrl);
+ if (vfe_mode) {
+ uint16_t mode = share_ctrl->comp_output_mode &
+ ~(VFE32_OUTPUT_MODE_TERTIARY1|
+ VFE32_OUTPUT_MODE_TERTIARY2);
+ axi_stop_pix(share_ctrl, vfe_mode, share_ctrl->cmd_type);
+ axi_disable_wm_irq(share_ctrl, mode);
share_ctrl->comp_output_mode &=
- ~(share_ctrl->outpath.output_mode);
+ (VFE32_OUTPUT_MODE_TERTIARY1|
+ VFE32_OUTPUT_MODE_TERTIARY2);
}
}
@@ -3397,25 +3525,47 @@
{
unsigned long flags;
struct vfe_share_ctrl_t *share_ctrl = vfe32_ctrl->share_ctrl;
+ if (atomic_read(
+ &share_ctrl->pix0_update_ack_pending) == 2) {
+ uint32_t vfe_mode =
+ share_ctrl->operation_mode & ~(VFE_OUTPUTS_RDI0|
+ VFE_OUTPUTS_RDI1);
- if (atomic_cmpxchg(
- &share_ctrl->pix0_update_ack_pending, 2, 0) == 2) {
- axi_stop_pix(share_ctrl);
- msm_camera_io_w_mb(
- CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
- share_ctrl->vfebase + VFE_CAMIF_COMMAND);
- axi_disable_irq(share_ctrl);
- vfe32_send_isp_msg(&vfe32_ctrl->subdev,
- share_ctrl->vfeFrameId,
- MSG_ID_PIX0_UPDATE_ACK);
- share_ctrl->comp_output_mode &=
- ~(share_ctrl->outpath.output_mode);
- share_ctrl->current_mode &=
- (VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI0);
+ if (share_ctrl->dual_enabled && !share_ctrl->update_counter) {
+ axi_stop_pix(share_ctrl, vfe_mode,
+ share_ctrl->cmd_type);
+ share_ctrl->update_counter++;
+ } else {
+ uint16_t output_mode =
+ share_ctrl->comp_output_mode &
+ ~(VFE32_OUTPUT_MODE_TERTIARY1|
+ VFE32_OUTPUT_MODE_TERTIARY2);
+ share_ctrl->update_counter = 0;
+ if (!share_ctrl->dual_enabled)
+ axi_stop_pix(share_ctrl, vfe_mode,
+ share_ctrl->cmd_type);
+ axi_disable_wm_irq(share_ctrl, output_mode);
+ axi_disable_irq(share_ctrl, vfe_mode);
+ atomic_set(&share_ctrl->pix0_update_ack_pending, 0);
+ msm_camera_io_w_mb(
+ CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+ share_ctrl->vfebase +
+ VFE_CAMIF_COMMAND);
+ vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+ share_ctrl->vfeFrameId,
+ MSG_ID_PIX0_UPDATE_ACK);
+ share_ctrl->comp_output_mode &=
+ (VFE32_OUTPUT_MODE_TERTIARY1|
+ VFE32_OUTPUT_MODE_TERTIARY2);
+ }
} else {
if (share_ctrl->recording_state == VFE_STATE_START_REQUESTED) {
if (share_ctrl->operation_mode &
VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+ msm_camera_io_w((
+ 0x1 << share_ctrl->outpath.out0.ch0 |
+ 0x1 << share_ctrl->outpath.out0.ch1),
+ share_ctrl->vfebase + VFE_BUS_CMD);
msm_camera_io_w(1,
share_ctrl->vfebase + vfe32_AXI_WM_CFG[
share_ctrl->outpath.out0.ch0]);
@@ -3424,6 +3574,10 @@
share_ctrl->outpath.out0.ch1]);
} else if (share_ctrl->operation_mode &
VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+ msm_camera_io_w((
+ 0x1 << share_ctrl->outpath.out1.ch0 |
+ 0x1 << share_ctrl->outpath.out1.ch1),
+ share_ctrl->vfebase + VFE_BUS_CMD);
msm_camera_io_w(1,
share_ctrl->vfebase + vfe32_AXI_WM_CFG[
share_ctrl->outpath.out1.ch0]);
@@ -3465,8 +3619,6 @@
VFE32_OUTPUT_MODE_TERTIARY2));
vfe32_send_isp_msg(&vfe32_ctrl->subdev,
share_ctrl->vfeFrameId, MSG_ID_PIX0_UPDATE_ACK);
- share_ctrl->current_mode &=
- (VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI0);
} else {
if (share_ctrl->recording_state ==
VFE_STATE_STOP_REQUESTED) {
@@ -3504,6 +3656,10 @@
CDBG("%s enabling liveshot output\n", __func__);
if (share_ctrl->comp_output_mode &
VFE32_OUTPUT_MODE_PRIMARY) {
+ msm_camera_io_w((
+ 0x1 << share_ctrl->outpath.out0.ch0 |
+ 0x1 << share_ctrl->outpath.out0.ch1),
+ share_ctrl->vfebase + VFE_BUS_CMD);
msm_camera_io_w(1, share_ctrl->vfebase +
vfe32_AXI_WM_CFG[
share_ctrl->outpath.out0.ch0]);
@@ -3572,32 +3728,12 @@
/* if last frame to be captured: */
if (share_ctrl->vfe_capture_count == 0) {
/* stop the bus output: */
- if (share_ctrl->comp_output_mode
- & VFE32_OUTPUT_MODE_PRIMARY) {
- msm_camera_io_w(0,
- share_ctrl->vfebase+
- vfe32_AXI_WM_CFG[
- share_ctrl->
- outpath.out0.ch0]);
- msm_camera_io_w(0,
- share_ctrl->vfebase+
- vfe32_AXI_WM_CFG[
- share_ctrl->
- outpath.out0.ch1]);
- }
- if (share_ctrl->comp_output_mode &
- VFE32_OUTPUT_MODE_SECONDARY) {
- msm_camera_io_w(0,
- share_ctrl->vfebase+
- vfe32_AXI_WM_CFG[
- share_ctrl->
- outpath.out1.ch0]);
- msm_camera_io_w(0,
- share_ctrl->vfebase+
- vfe32_AXI_WM_CFG[
- share_ctrl->
- outpath.out1.ch1]);
- }
+ uint32_t vfe_mode =
+ share_ctrl->operation_mode &
+ ~(VFE_OUTPUTS_RDI0|
+ VFE_OUTPUTS_RDI1);
+ axi_stop_pix(share_ctrl, vfe_mode,
+ AXI_CMD_CAPTURE);
msm_camera_io_w_mb
(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
share_ctrl->vfebase +
@@ -3620,56 +3756,84 @@
struct vfe32_ctrl_type *vfe32_ctrl)
{
if (atomic_cmpxchg(
- &vfe32_ctrl->share_ctrl->rdi0_update_ack_pending, 2, 0) == 2) {
- axi_stop_rdi0(vfe32_ctrl->share_ctrl);
- axi_disable_irq(vfe32_ctrl->share_ctrl);
- vfe32_send_isp_msg(&vfe32_ctrl->subdev,
- vfe32_ctrl->share_ctrl->vfeFrameId,
- MSG_ID_RDI0_UPDATE_ACK);
- vfe32_ctrl->share_ctrl->comp_output_mode &=
- ~VFE32_OUTPUT_MODE_TERTIARY1;
- vfe32_ctrl->share_ctrl->current_mode &=
- ~(VFE_OUTPUTS_RDI0);
- }
-
- if (atomic_cmpxchg(
&vfe32_ctrl->share_ctrl->rdi0_update_ack_pending, 1, 0) == 1) {
vfe32_ctrl->share_ctrl->comp_output_mode |=
VFE32_OUTPUT_MODE_TERTIARY1;
vfe32_send_isp_msg(&vfe32_ctrl->subdev,
- vfe32_ctrl->share_ctrl->vfeFrameId,
+ vfe32_ctrl->share_ctrl->rdi0FrameId,
MSG_ID_RDI0_UPDATE_ACK);
- vfe32_ctrl->share_ctrl->current_mode &=
+ }
+
+ if ((atomic_read(
+ &vfe32_ctrl->share_ctrl->rdi0_update_ack_pending) == 2)
+ || (vfe32_ctrl->share_ctrl->rdi0_capture_count == 0)) {
+ axi_disable_wm_irq(vfe32_ctrl->share_ctrl,
+ VFE32_OUTPUT_MODE_TERTIARY1);
+ axi_disable_irq(vfe32_ctrl->share_ctrl, VFE_OUTPUTS_RDI0);
+ atomic_set(&vfe32_ctrl->share_ctrl->rdi0_update_ack_pending, 0);
+ vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+ vfe32_ctrl->share_ctrl->rdi0FrameId,
+ MSG_ID_RDI0_UPDATE_ACK);
+
+ if (vfe32_ctrl->share_ctrl->rdi0_capture_count == 0)
+ vfe32_ctrl->share_ctrl->rdi0_capture_count = -1;
+ if (vfe32_ctrl->share_ctrl->outpath.out2.capture_cnt
+ == 0)
+ vfe32_ctrl->share_ctrl->outpath.out2.capture_cnt = -1;
+ vfe32_ctrl->share_ctrl->comp_output_mode &=
+ ~VFE32_OUTPUT_MODE_TERTIARY1;
+ vfe32_ctrl->share_ctrl->operation_mode &=
~(VFE_OUTPUTS_RDI0);
}
+
+ if (vfe32_ctrl->share_ctrl->rdi0_capture_count > 0) {
+ vfe32_ctrl->share_ctrl->rdi0_capture_count--;
+ if (!vfe32_ctrl->share_ctrl->rdi0_capture_count)
+ axi_stop_rdi0(vfe32_ctrl->share_ctrl);
+ }
}
static void vfe32_process_rdi1_reg_update_irq(
struct vfe32_ctrl_type *vfe32_ctrl)
{
- if (atomic_cmpxchg(
- &vfe32_ctrl->share_ctrl->rdi1_update_ack_pending, 2, 0) == 2) {
- axi_stop_rdi1(vfe32_ctrl->share_ctrl);
- axi_disable_irq(vfe32_ctrl->share_ctrl);
- vfe32_send_isp_msg(&vfe32_ctrl->subdev,
- vfe32_ctrl->share_ctrl->vfeFrameId,
- MSG_ID_RDI1_UPDATE_ACK);
- vfe32_ctrl->share_ctrl->comp_output_mode &=
- ~VFE32_OUTPUT_MODE_TERTIARY2;
- vfe32_ctrl->share_ctrl->current_mode &=
- ~(VFE_OUTPUTS_RDI1);
- }
if (atomic_cmpxchg(
- &vfe32_ctrl->share_ctrl->rdi1_update_ack_pending, 1, 0) == 1) {
+ &vfe32_ctrl->share_ctrl->rdi1_update_ack_pending, 1, 0)
+ == 1) {
vfe32_ctrl->share_ctrl->comp_output_mode |=
VFE32_OUTPUT_MODE_TERTIARY2;
vfe32_send_isp_msg(&vfe32_ctrl->subdev,
- vfe32_ctrl->share_ctrl->vfeFrameId,
+ vfe32_ctrl->share_ctrl->rdi1FrameId,
MSG_ID_RDI1_UPDATE_ACK);
- vfe32_ctrl->share_ctrl->current_mode &=
+ }
+
+ if ((atomic_read(
+ &vfe32_ctrl->share_ctrl->rdi1_update_ack_pending) == 2)
+ || (vfe32_ctrl->share_ctrl->rdi1_capture_count == 0)) {
+ axi_disable_wm_irq(vfe32_ctrl->share_ctrl,
+ VFE32_OUTPUT_MODE_TERTIARY2);
+ axi_disable_irq(vfe32_ctrl->share_ctrl, VFE_OUTPUTS_RDI1);
+ atomic_set(&vfe32_ctrl->share_ctrl->rdi1_update_ack_pending, 0);
+ vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+ vfe32_ctrl->share_ctrl->rdi1FrameId,
+ MSG_ID_RDI1_UPDATE_ACK);
+
+ if (vfe32_ctrl->share_ctrl->rdi1_capture_count == 0)
+ vfe32_ctrl->share_ctrl->rdi1_capture_count = -1;
+ if (vfe32_ctrl->share_ctrl->outpath.out3.capture_cnt
+ == 0)
+ vfe32_ctrl->share_ctrl->outpath.out3.capture_cnt = -1;
+ vfe32_ctrl->share_ctrl->comp_output_mode &=
+ ~VFE32_OUTPUT_MODE_TERTIARY2;
+ vfe32_ctrl->share_ctrl->operation_mode &=
~(VFE_OUTPUTS_RDI1);
}
+
+ if (vfe32_ctrl->share_ctrl->rdi1_capture_count > 0) {
+ vfe32_ctrl->share_ctrl->rdi1_capture_count--;
+ if (!vfe32_ctrl->share_ctrl->rdi1_capture_count)
+ axi_stop_rdi1(vfe32_ctrl->share_ctrl);
+ }
}
static void vfe32_process_reset_irq(
@@ -3714,9 +3878,18 @@
{
if (vfe32_ctrl->share_ctrl->operation_mode ==
VFE_OUTPUTS_RAW) {
- if (vfe32_ctrl->share_ctrl->start_ack_pending) {
- vfe32_ctrl->share_ctrl->start_ack_pending = FALSE;
+ if (atomic_cmpxchg(
+ &vfe32_ctrl->share_ctrl->pix0_update_ack_pending,
+ 1, 0) == 1) {
+ vfe32_ctrl->share_ctrl->comp_output_mode |=
+ (vfe32_ctrl->share_ctrl->outpath.output_mode
+ & ~(VFE32_OUTPUT_MODE_TERTIARY1|
+ VFE32_OUTPUT_MODE_TERTIARY2));
+ vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+ vfe32_ctrl->share_ctrl->vfeFrameId,
+ MSG_ID_PIX0_UPDATE_ACK);
}
+
vfe32_ctrl->share_ctrl->vfe_capture_count--;
/* if last frame to be captured: */
if (vfe32_ctrl->share_ctrl->vfe_capture_count == 0) {
@@ -3881,7 +4054,6 @@
uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
uint8_t out_bool = 0;
struct msm_free_buf *free_buf = NULL;
-
free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
@@ -4058,10 +4230,12 @@
/* this must be rdi image output. */
struct msm_free_buf *free_buf = NULL;
/*RDI0*/
+ CDBG("rdi0 out irq\n");
if (axi_ctrl->share_ctrl->operation_mode & VFE_OUTPUTS_RDI0) {
free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
VFE_MSG_OUTPUT_TERTIARY1, axi_ctrl);
- if (free_buf) {
+ if (axi_ctrl->share_ctrl->outpath.out2.capture_cnt > 0 ||
+ free_buf) {
ping_pong = msm_camera_io_r(axi_ctrl->
share_ctrl->vfebase +
VFE_BUS_PING_PONG_STATUS);
@@ -4074,11 +4248,14 @@
pr_debug("%s ch0 = 0x%x\n",
__func__, ch0_paddr);
- /* Y channel */
- vfe32_put_ch_addr(ping_pong,
- axi_ctrl->share_ctrl->vfebase,
- axi_ctrl->share_ctrl->outpath.out2.ch0,
- free_buf->ch_paddr[0]);
+ if (free_buf)
+ vfe32_put_ch_addr(ping_pong,
+ axi_ctrl->share_ctrl->vfebase,
+ axi_ctrl->share_ctrl->outpath.out2.ch0,
+ free_buf->ch_paddr[0]);
+ if (axi_ctrl->share_ctrl->outpath.out2.capture_cnt == 1)
+ axi_ctrl->share_ctrl->
+ outpath.out2.capture_cnt = 0;
vfe_send_outmsg(axi_ctrl,
MSG_ID_OUTPUT_TERTIARY1, ch0_paddr,
@@ -4103,7 +4280,8 @@
if (axi_ctrl->share_ctrl->operation_mode & VFE_OUTPUTS_RDI1) {
free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
VFE_MSG_OUTPUT_TERTIARY2, axi_ctrl);
- if (free_buf) {
+ if (axi_ctrl->share_ctrl->outpath.out3.capture_cnt > 0 ||
+ free_buf) {
ping_pong = msm_camera_io_r(axi_ctrl->
share_ctrl->vfebase +
VFE_BUS_PING_PONG_STATUS);
@@ -4115,11 +4293,15 @@
pr_debug("%s ch0 = 0x%x\n",
__func__, ch0_paddr);
- /* Y channel */
- vfe32_put_ch_addr(ping_pong,
- axi_ctrl->share_ctrl->vfebase,
- axi_ctrl->share_ctrl->outpath.out3.ch0,
- free_buf->ch_paddr[0]);
+ if (free_buf)
+ vfe32_put_ch_addr(ping_pong,
+ axi_ctrl->share_ctrl->vfebase,
+ axi_ctrl->share_ctrl->outpath.out3.ch0,
+ free_buf->ch_paddr[0]);
+ if (axi_ctrl->share_ctrl->
+ outpath.out3.capture_cnt == 1)
+ axi_ctrl->share_ctrl->
+ outpath.out3.capture_cnt = 0;
vfe_send_outmsg(axi_ctrl,
MSG_ID_OUTPUT_TERTIARY2, ch0_paddr,
@@ -5209,6 +5391,9 @@
int round_rate;
struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+ if (axi_ctrl->share_ctrl->dual_enabled)
+ return rc;
+
round_rate = clk_round_rate(axi_ctrl->vfe_clk[0], freq);
if (rc < 0) {
pr_err("%s: clk_round_rate failed %d\n",
@@ -5233,21 +5418,22 @@
.core = &msm_vfe_subdev_core_ops,
};
-int msm_axi_subdev_init(struct v4l2_subdev *sd)
+int msm_axi_subdev_init(struct v4l2_subdev *sd,
+ uint8_t dual_enabled)
{
int rc = 0;
struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
- struct msm_cam_media_controller *mctl;
- mctl = v4l2_get_subdev_hostdata(sd);
+ struct msm_cam_media_controller *mctl =
+ v4l2_get_subdev_hostdata(sd);
if (mctl == NULL) {
- pr_err("%s: mctl is NULL\n", __func__);
rc = -EINVAL;
goto mctl_failed;
}
+
axi_ctrl->share_ctrl->axi_ref_cnt++;
if (axi_ctrl->share_ctrl->axi_ref_cnt > 1)
return rc;
-
+ axi_ctrl->share_ctrl->dual_enabled = dual_enabled;
spin_lock_init(&axi_ctrl->tasklet_lock);
INIT_LIST_HEAD(&axi_ctrl->tasklet_q);
spin_lock_init(&axi_ctrl->share_ctrl->sd_notify_lock);
@@ -5290,8 +5476,13 @@
msm_camio_bus_scale_cfg(
mctl->sdata->pdata->cam_bus_scale_table, S_INIT);
- msm_camio_bus_scale_cfg(
- mctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+
+ if (axi_ctrl->share_ctrl->dual_enabled)
+ msm_camio_bus_scale_cfg(
+ mctl->sdata->pdata->cam_bus_scale_table, S_DUAL);
+ else
+ msm_camio_bus_scale_cfg(
+ mctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
if (msm_camera_io_r(
axi_ctrl->share_ctrl->vfebase + V32_GET_HW_VERSION_OFF) ==
@@ -5351,18 +5542,19 @@
void msm_axi_subdev_release(struct v4l2_subdev *sd)
{
- struct msm_cam_media_controller *pmctl =
- (struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+ struct msm_cam_media_controller *pmctl =
+ v4l2_get_subdev_hostdata(sd);
+
if (!axi_ctrl->share_ctrl->vfebase) {
pr_err("%s: base address unmapped\n", __func__);
return;
}
- CDBG("%s, free_irq\n", __func__);
axi_ctrl->share_ctrl->axi_ref_cnt--;
if (axi_ctrl->share_ctrl->axi_ref_cnt > 0)
return;
+ axi_ctrl->share_ctrl->dual_enabled = 0;
disable_irq(axi_ctrl->vfeirq->start);
tasklet_kill(&axi_ctrl->vfe32_tasklet);
#ifdef CONFIG_MSM_IOMMU
@@ -5534,39 +5726,53 @@
}
break;
case AXI_CMD_CAPTURE:
- if (axi_ctrl->share_ctrl->current_mode ==
- VFE_OUTPUTS_JPEG_AND_THUMB ||
- axi_ctrl->share_ctrl->current_mode ==
- VFE_OUTPUTS_THUMB_AND_JPEG) {
+ if (vfe_mode) {
+ if (axi_ctrl->share_ctrl->current_mode ==
+ VFE_OUTPUTS_JPEG_AND_THUMB ||
+ axi_ctrl->share_ctrl->current_mode ==
+ VFE_OUTPUTS_THUMB_AND_JPEG) {
- /* Configure primary channel for JPEG */
+ /* Configure primary channel for JPEG */
+ rc = configure_pingpong_buffers(
+ VFE_MSG_JPEG_CAPTURE,
+ VFE_MSG_OUTPUT_PRIMARY,
+ axi_ctrl);
+ } else {
+ /* Configure primary channel */
+ rc = configure_pingpong_buffers(
+ VFE_MSG_CAPTURE,
+ VFE_MSG_OUTPUT_PRIMARY,
+ axi_ctrl);
+ }
+ if (rc < 0) {
+ pr_err("%s error configuring pingpong buffers for primary output",
+ __func__);
+ rc = -EINVAL;
+ goto config_done;
+ }
+ /* Configure secondary channel */
rc = configure_pingpong_buffers(
- VFE_MSG_JPEG_CAPTURE,
- VFE_MSG_OUTPUT_PRIMARY,
- axi_ctrl);
- } else {
- /* Configure primary channel */
+ VFE_MSG_CAPTURE,
+ VFE_MSG_OUTPUT_SECONDARY,
+ axi_ctrl);
+ if (rc < 0) {
+ pr_err("%s error configuring pingpong buffers for secondary output",
+ __func__);
+ rc = -EINVAL;
+ goto config_done;
+ }
+ }
+
+ if (axi_ctrl->share_ctrl->current_mode &
+ VFE_OUTPUTS_RDI0)
rc = configure_pingpong_buffers(
- VFE_MSG_CAPTURE,
- VFE_MSG_OUTPUT_PRIMARY,
+ VFE_MSG_CAPTURE, VFE_MSG_OUTPUT_TERTIARY1,
axi_ctrl);
- }
- if (rc < 0) {
- pr_err("%s error configuring pingpong buffers for primary output",
- __func__);
- rc = -EINVAL;
- goto config_done;
- }
- /* Configure secondary channel */
- rc = configure_pingpong_buffers(
- VFE_MSG_CAPTURE, VFE_MSG_OUTPUT_SECONDARY,
+ if (axi_ctrl->share_ctrl->current_mode &
+ VFE_OUTPUTS_RDI1)
+ rc = configure_pingpong_buffers(
+ VFE_MSG_CAPTURE, VFE_MSG_OUTPUT_TERTIARY2,
axi_ctrl);
- if (rc < 0) {
- pr_err("%s error configuring pingpong buffers for secondary output",
- __func__);
- rc = -EINVAL;
- goto config_done;
- }
break;
default:
rc = -EINVAL;
@@ -5580,10 +5786,9 @@
void axi_start(struct msm_cam_media_controller *pmctl,
struct axi_ctrl_t *axi_ctrl, struct msm_camera_vfe_params_t vfe_params)
{
- uint32_t irq_comp_mask = 0, irq_mask = 0, irq_mask1 = 0;
int rc = 0;
uint32_t reg_update = 0;
- uint16_t operation_mode =
+ uint32_t vfe_mode =
(axi_ctrl->share_ctrl->current_mode &
~(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1));
rc = axi_config_buffers(axi_ctrl, vfe_params);
@@ -5592,99 +5797,77 @@
switch (vfe_params.cmd_type) {
case AXI_CMD_PREVIEW:
- msm_camio_bus_scale_cfg(
- pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+ if (!axi_ctrl->share_ctrl->dual_enabled)
+ msm_camio_bus_scale_cfg(
+ pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
break;
case AXI_CMD_CAPTURE:
case AXI_CMD_RAW_CAPTURE:
- msm_camio_bus_scale_cfg(
- pmctl->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
+ if (!axi_ctrl->share_ctrl->dual_enabled)
+ msm_camio_bus_scale_cfg(
+ pmctl->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
break;
case AXI_CMD_RECORD:
- msm_camio_bus_scale_cfg(
- pmctl->sdata->pdata->cam_bus_scale_table, S_VIDEO);
+ if (!axi_ctrl->share_ctrl->dual_enabled)
+ msm_camio_bus_scale_cfg(
+ pmctl->sdata->pdata->cam_bus_scale_table, S_VIDEO);
return;
case AXI_CMD_ZSL:
- msm_camio_bus_scale_cfg(
- pmctl->sdata->pdata->cam_bus_scale_table, S_ZSL);
+ if (!axi_ctrl->share_ctrl->dual_enabled)
+ msm_camio_bus_scale_cfg(
+ pmctl->sdata->pdata->cam_bus_scale_table, S_ZSL);
break;
case AXI_CMD_LIVESHOT:
- msm_camio_bus_scale_cfg(
- pmctl->sdata->pdata->cam_bus_scale_table, S_LIVESHOT);
+ if (!axi_ctrl->share_ctrl->dual_enabled)
+ msm_camio_bus_scale_cfg(
+ pmctl->sdata->pdata->cam_bus_scale_table, S_LIVESHOT);
return;
default:
return;
}
-
- irq_comp_mask =
- msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
- VFE_IRQ_COMP_MASK);
- irq_mask = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
- VFE_IRQ_MASK_0);
-
- if (axi_ctrl->share_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_PRIMARY) {
- if (vfe_params.cmd_type == AXI_CMD_RAW_CAPTURE)
- irq_comp_mask |= (
- 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0);
- else
- irq_comp_mask |= (
- 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
- 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1);
- irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
- } else if (axi_ctrl->share_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
- irq_comp_mask |= (
- 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
- 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1 |
- 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch2);
- irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
- }
- if (axi_ctrl->share_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_SECONDARY) {
- irq_comp_mask |= (
- 0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch0 + 8) |
- 0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch1 + 8));
- irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
- } else if (axi_ctrl->share_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
- irq_comp_mask |= (
- 0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch0 + 8) |
- 0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch1 + 8) |
- 0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch2 + 8));
- irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
- }
- if (axi_ctrl->share_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_TERTIARY1) {
- irq_mask |= (0x1 << (axi_ctrl->share_ctrl->outpath.out2.ch0 +
- VFE_WM_OFFSET));
- }
- if (axi_ctrl->share_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_TERTIARY2) {
- irq_mask |= (0x1 << (axi_ctrl->share_ctrl->outpath.out3.ch0 +
- VFE_WM_OFFSET));
- }
-
- msm_camera_io_w(irq_comp_mask,
- axi_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
- msm_camera_io_w(irq_mask, axi_ctrl->share_ctrl->vfebase +
- VFE_IRQ_MASK_0);
+ axi_enable_wm_irq(axi_ctrl->share_ctrl);
switch (vfe_params.cmd_type) {
+ case AXI_CMD_RAW_CAPTURE:
+ msm_camera_io_w((
+ 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0),
+ axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+ + vfe32_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out0.ch0]);
+ break;
case AXI_CMD_PREVIEW: {
- switch (operation_mode) {
+ switch (vfe_mode) {
case VFE_OUTPUTS_PREVIEW:
case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
if (axi_ctrl->share_ctrl->outpath.output_mode &
VFE32_OUTPUT_MODE_PRIMARY) {
+ msm_camera_io_w((
+ 0x1 << axi_ctrl->share_ctrl->
+ outpath.out0.ch0 |
+ 0x1 << axi_ctrl->share_ctrl->
+ outpath.out0.ch1),
+ axi_ctrl->share_ctrl->vfebase +
+ VFE_BUS_CMD);
msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+ vfe32_AXI_WM_CFG[axi_ctrl->
share_ctrl->outpath.out0.ch0]);
msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+ vfe32_AXI_WM_CFG[axi_ctrl->
share_ctrl->outpath.out0.ch1]);
+
+
} else if (axi_ctrl->share_ctrl->outpath.output_mode &
VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+ msm_camera_io_w((
+ 0x1 << axi_ctrl->share_ctrl->
+ outpath.out0.ch0 |
+ 0x1 << axi_ctrl->share_ctrl->
+ outpath.out0.ch1 |
+ 0x1 << axi_ctrl->share_ctrl->
+ outpath.out0.ch2),
+ axi_ctrl->share_ctrl->vfebase +
+ VFE_BUS_CMD);
msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+ vfe32_AXI_WM_CFG[axi_ctrl->
share_ctrl->outpath.out0.ch0]);
@@ -5699,6 +5882,13 @@
default:
if (axi_ctrl->share_ctrl->outpath.output_mode &
VFE32_OUTPUT_MODE_SECONDARY) {
+ msm_camera_io_w((
+ 0x1 << axi_ctrl->share_ctrl->
+ outpath.out1.ch0 |
+ 0x1 << axi_ctrl->share_ctrl->
+ outpath.out1.ch1),
+ axi_ctrl->share_ctrl->vfebase +
+ VFE_BUS_CMD);
msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+ vfe32_AXI_WM_CFG[axi_ctrl->
share_ctrl->outpath.out1.ch0]);
@@ -5707,6 +5897,15 @@
share_ctrl->outpath.out1.ch1]);
} else if (axi_ctrl->share_ctrl->outpath.output_mode &
VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ msm_camera_io_w((
+ 0x1 << axi_ctrl->share_ctrl->
+ outpath.out1.ch0 |
+ 0x1 << axi_ctrl->share_ctrl->
+ outpath.out1.ch1 |
+ 0x1 << axi_ctrl->share_ctrl->
+ outpath.out1.ch2),
+ axi_ctrl->share_ctrl->vfebase +
+ VFE_BUS_CMD);
msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+ vfe32_AXI_WM_CFG[axi_ctrl->
share_ctrl->outpath.out1.ch0]);
@@ -5724,6 +5923,10 @@
default:
if (axi_ctrl->share_ctrl->outpath.output_mode &
VFE32_OUTPUT_MODE_PRIMARY) {
+ msm_camera_io_w((
+ 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
+ 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1),
+ axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
vfe32_AXI_WM_CFG[axi_ctrl->
share_ctrl->outpath.out0.ch0]);
@@ -5732,6 +5935,11 @@
share_ctrl->outpath.out0.ch1]);
} else if (axi_ctrl->share_ctrl->outpath.output_mode &
VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+ msm_camera_io_w((
+ 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
+ 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1 |
+ 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch2),
+ axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
vfe32_AXI_WM_CFG[axi_ctrl->
share_ctrl->outpath.out0.ch0]);
@@ -5745,6 +5953,10 @@
if (axi_ctrl->share_ctrl->outpath.output_mode &
VFE32_OUTPUT_MODE_SECONDARY) {
+ msm_camera_io_w((
+ 0x1 << axi_ctrl->share_ctrl->outpath.out1.ch0 |
+ 0x1 << axi_ctrl->share_ctrl->outpath.out1.ch1),
+ axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
vfe32_AXI_WM_CFG[axi_ctrl->
share_ctrl->outpath.out1.ch0]);
@@ -5753,6 +5965,11 @@
share_ctrl->outpath.out1.ch1]);
} else if (axi_ctrl->share_ctrl->outpath.output_mode &
VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ msm_camera_io_w((
+ 0x1 << axi_ctrl->share_ctrl->outpath.out1.ch0 |
+ 0x1 << axi_ctrl->share_ctrl->outpath.out1.ch1 |
+ 0x1 << axi_ctrl->share_ctrl->outpath.out1.ch2),
+ axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
vfe32_AXI_WM_CFG[axi_ctrl->
share_ctrl->outpath.out1.ch0]);
@@ -5765,36 +5982,47 @@
}
break;
}
- if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0)
+ if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+ axi_ctrl->share_ctrl->outpath.out2.capture_cnt =
+ vfe_params.capture_count;
+ axi_ctrl->share_ctrl->rdi0_capture_count =
+ vfe_params.capture_count;
+ msm_camera_io_w((
+ 0x1 << axi_ctrl->share_ctrl->outpath.out2.ch0),
+ axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
vfe32_AXI_WM_CFG[axi_ctrl->share_ctrl->
outpath.out2.ch0]);
- if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1)
+ }
+ if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+ axi_ctrl->share_ctrl->outpath.out3.capture_cnt =
+ vfe_params.capture_count;
+ axi_ctrl->share_ctrl->rdi1_capture_count =
+ vfe_params.capture_count;
+ msm_camera_io_w((
+ 0x1 << axi_ctrl->share_ctrl->outpath.out3.ch0),
+ axi_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
vfe32_AXI_WM_CFG[axi_ctrl->share_ctrl->
outpath.out3.ch0]);
+ }
- irq_mask1 =
- msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
- VFE_IRQ_MASK_1);
+ axi_enable_irq(axi_ctrl->share_ctrl);
if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
- irq_mask1 |= VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK;
if (!atomic_cmpxchg(
&axi_ctrl->share_ctrl->rdi0_update_ack_pending,
0, 1))
reg_update |= 0x2;
}
if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
- irq_mask1 |= VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK;
if (!atomic_cmpxchg(
&axi_ctrl->share_ctrl->rdi1_update_ack_pending,
0, 1))
reg_update |= 0x4;
}
- msm_camera_io_w(irq_mask1, axi_ctrl->share_ctrl->vfebase +
- VFE_IRQ_MASK_1);
- if (operation_mode) {
+
+ if (vfe_mode) {
if (!atomic_cmpxchg(
&axi_ctrl->share_ctrl->pix0_update_ack_pending,
0, 1))
@@ -5806,54 +6034,62 @@
VFE_REG_UPDATE_CMD);
axi_ctrl->share_ctrl->operation_mode |=
axi_ctrl->share_ctrl->current_mode;
- axi_enable_irq(axi_ctrl->share_ctrl);
}
void axi_stop(struct msm_cam_media_controller *pmctl,
struct axi_ctrl_t *axi_ctrl, struct msm_camera_vfe_params_t vfe_params)
{
uint32_t reg_update = 0;
- uint32_t operation_mode =
+ uint32_t vfe_mode =
axi_ctrl->share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
VFE_OUTPUTS_RDI1);
-
switch (vfe_params.cmd_type) {
case AXI_CMD_PREVIEW:
case AXI_CMD_CAPTURE:
case AXI_CMD_RAW_CAPTURE:
case AXI_CMD_ZSL:
+ axi_ctrl->share_ctrl->cmd_type = vfe_params.cmd_type;
break;
case AXI_CMD_RECORD:
- msm_camio_bus_scale_cfg(
- pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
+ if (!axi_ctrl->share_ctrl->dual_enabled)
+ msm_camio_bus_scale_cfg(
+ pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
return;
case AXI_CMD_LIVESHOT:
- msm_camio_bus_scale_cfg(
- pmctl->sdata->pdata->cam_bus_scale_table, S_VIDEO);
+ if (!axi_ctrl->share_ctrl->dual_enabled)
+ msm_camio_bus_scale_cfg(
+ pmctl->sdata->pdata->cam_bus_scale_table, S_VIDEO);
return;
default:
return;
}
if (axi_ctrl->share_ctrl->stop_immediately) {
- axi_disable_irq(axi_ctrl->share_ctrl);
+ axi_disable_irq(axi_ctrl->share_ctrl,
+ axi_ctrl->share_ctrl->current_mode);
axi_stop_process(axi_ctrl->share_ctrl);
return;
}
if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+ msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[axi_ctrl->share_ctrl->
+ outpath.out2.ch0]);
if (!atomic_cmpxchg(
&axi_ctrl->share_ctrl->rdi0_update_ack_pending,
0, 2))
reg_update |= 0x2;
}
if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+ msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[axi_ctrl->share_ctrl->
+ outpath.out3.ch0]);
if (!atomic_cmpxchg(
&axi_ctrl->share_ctrl->rdi1_update_ack_pending,
0, 2))
reg_update |= 0x4;
}
- if (operation_mode) {
+ if (vfe_mode) {
if (!atomic_cmpxchg(
&axi_ctrl->share_ctrl->pix0_update_ack_pending,
0, 2))
@@ -6083,8 +6319,15 @@
axi_stop(pmctl, axi_ctrl, vfe_params);
}
break;
- case CMD_AXI_RESET:
- axi_reset(axi_ctrl);
+ case CMD_AXI_RESET: {
+ struct msm_camera_vfe_params_t vfe_params;
+ if (copy_from_user(&vfe_params,
+ (void __user *)(vfecmd.value),
+ sizeof(struct msm_camera_vfe_params_t))) {
+ return -EFAULT;
+ }
+ axi_reset(axi_ctrl, vfe_params);
+ }
break;
case CMD_AXI_ABORT:
if (copy_from_user(&axi_ctrl->share_ctrl->sync_abort,
@@ -6151,19 +6394,44 @@
if ((axi_ctrl->share_ctrl->outpath.out0.capture_cnt == 0)
&& (axi_ctrl->share_ctrl->outpath.out1.
capture_cnt == 0)) {
- msm_camera_io_w_mb(
- CAMIF_COMMAND_STOP_IMMEDIATELY,
- axi_ctrl->share_ctrl->vfebase +
- VFE_CAMIF_COMMAND);
- axi_disable_irq(axi_ctrl->share_ctrl);
+ uint32_t mode =
+ (axi_ctrl->share_ctrl->operation_mode &
+ ~(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1));
+ uint16_t output_mode =
+ axi_ctrl->share_ctrl->comp_output_mode &
+ ~(VFE32_OUTPUT_MODE_TERTIARY1|
+ VFE32_OUTPUT_MODE_TERTIARY2);
+ if (!axi_ctrl->share_ctrl->dual_enabled)
+ msm_camera_io_w_mb(
+ CAMIF_COMMAND_STOP_IMMEDIATELY,
+ axi_ctrl->share_ctrl->vfebase +
+ VFE_CAMIF_COMMAND);
+ axi_disable_wm_irq(axi_ctrl->share_ctrl, output_mode);
+ axi_disable_irq(axi_ctrl->share_ctrl, mode);
vfe32_send_isp_msg(&axi_ctrl->subdev,
axi_ctrl->share_ctrl->vfeFrameId,
MSG_ID_PIX0_UPDATE_ACK);
- vfe32_send_isp_msg(&axi_ctrl->subdev,
- axi_ctrl->share_ctrl->vfeFrameId,
- MSG_ID_SNAPSHOT_DONE);
+ axi_ctrl->share_ctrl->outpath.out0.
+ capture_cnt = -1;
+ axi_ctrl->share_ctrl->outpath.out1.
+ capture_cnt = -1;
+ axi_ctrl->share_ctrl->comp_output_mode &=
+ (VFE32_OUTPUT_MODE_TERTIARY1|
+ VFE32_OUTPUT_MODE_TERTIARY2);
}
}
+
+ if (axi_ctrl->share_ctrl->outpath.out2.capture_cnt == 0) {
+ axi_ctrl->share_ctrl->comp_output_mode &=
+ ~VFE32_OUTPUT_MODE_TERTIARY1;
+ axi_ctrl->share_ctrl->outpath.out2.capture_cnt = -1;
+ }
+
+ if (axi_ctrl->share_ctrl->outpath.out3.capture_cnt == 0) {
+ axi_ctrl->share_ctrl->comp_output_mode &=
+ ~VFE32_OUTPUT_MODE_TERTIARY2;
+ axi_ctrl->share_ctrl->outpath.out3.capture_cnt = -1;
+ }
}
static int msm_axi_buf_cfg(struct v4l2_subdev *sd, void __user *arg)
@@ -6218,8 +6486,16 @@
{
int rc = -ENOIOCTLCMD;
switch (cmd) {
- case VIDIOC_MSM_AXI_INIT:
- rc = msm_axi_subdev_init(sd);
+ case VIDIOC_MSM_AXI_INIT: {
+ uint8_t dual_enabled;
+ if (copy_from_user(&dual_enabled,
+ (void __user *)(arg),
+ sizeof(uint8_t))) {
+ rc = -EFAULT;
+ break;
+ }
+ rc = msm_axi_subdev_init(sd, dual_enabled);
+ }
break;
case VIDIOC_MSM_AXI_CFG:
rc = msm_axi_config(sd, arg);
diff --git a/drivers/media/video/msm/vfe/msm_vfe32.h b/drivers/media/video/msm/vfe/msm_vfe32.h
index 985493e..f985221 100644
--- a/drivers/media/video/msm/vfe/msm_vfe32.h
+++ b/drivers/media/video/msm/vfe/msm_vfe32.h
@@ -782,7 +782,7 @@
int8_t ch0;
int8_t ch1;
int8_t ch2;
- uint32_t capture_cnt;
+ int32_t capture_cnt;
uint32_t frame_drop_cnt;
struct msm_free_buf ping;
struct msm_free_buf pong;
@@ -959,6 +959,9 @@
int8_t stop_ack_pending;
enum vfe_output_state liveshot_state;
uint32_t vfe_capture_count;
+ int32_t rdi0_capture_count;
+ int32_t rdi1_capture_count;
+ uint8_t update_counter;
uint32_t operation_mode; /* streaming or snapshot */
uint32_t current_mode;
@@ -969,6 +972,7 @@
uint8_t sync_abort;
uint16_t cmd_type;
uint8_t vfe_reset_flag;
+ uint8_t dual_enabled;
uint8_t axi_ref_cnt;
uint16_t comp_output_mode;
diff --git a/drivers/media/video/msm_vidc/vidc_hal.h b/drivers/media/video/msm_vidc/vidc_hal.h
index 8e7c3d3..c586172 100644
--- a/drivers/media/video/msm_vidc/vidc_hal.h
+++ b/drivers/media/video/msm_vidc/vidc_hal.h
@@ -20,20 +20,6 @@
#include "msm_smem.h"
#include "vidc_hal_helper.h"
-#ifdef HAL_MSG_LOG
-#define HAL_MSG_LOW(x...) pr_info(KERN_INFO x)
-#define HAL_MSG_MEDIUM(x...) pr_info(KERN_INFO x)
-#define HAL_MSG_HIGH(x...) pr_info(KERN_INFO x)
-#else
-#define HAL_MSG_LOW(x...)
-#define HAL_MSG_MEDIUM(x...)
-#define HAL_MSG_HIGH(x...)
-#endif
-
-#define HAL_MSG_ERROR(x...) pr_err(KERN_INFO x)
-#define HAL_MSG_FATAL(x...) pr_err(KERN_INFO x)
-#define HAL_MSG_INFO(x...) pr_info(KERN_INFO x)
-
#define HFI_MASK_QHDR_TX_TYPE 0xFF000000
#define HFI_MASK_QHDR_RX_TYPE 0x00FF0000
#define HFI_MASK_QHDR_PRI_TYPE 0x0000FF00
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 1248789..0ace67a 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -229,6 +229,12 @@
#define MSM_CAM_IOCTL_OEM \
_IOW(MSM_CAM_IOCTL_MAGIC, 65, struct sensor_cfg_data *)
+#define MSM_CAM_IOCTL_AXI_INIT \
+ _IOWR(MSM_CAM_IOCTL_MAGIC, 66, uint8_t *)
+
+#define MSM_CAM_IOCTL_AXI_RELEASE \
+ _IO(MSM_CAM_IOCTL_MAGIC, 67)
+
struct v4l2_event_and_payload {
struct v4l2_event evt;
uint32_t payload_length;
@@ -2011,7 +2017,7 @@
_IOWR('V', BASE_VIDIOC_PRIVATE + 17, struct msm_mctl_pp_params *)
#define VIDIOC_MSM_AXI_INIT \
- _IO('V', BASE_VIDIOC_PRIVATE + 18)
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 18, uint8_t *)
#define VIDIOC_MSM_AXI_RELEASE \
_IO('V', BASE_VIDIOC_PRIVATE + 19)
@@ -2044,7 +2050,7 @@
struct msm_camera_vfe_params_t {
uint32_t operation_mode;
uint32_t capture_count;
- uint32_t skip_abort;
+ uint8_t skip_reset;
uint8_t stop_immediately;
uint16_t port_info;
uint32_t inst_handle;
diff --git a/include/sound/q6afe-v2.h b/include/sound/q6afe-v2.h
index b1ed9a4..8ccc9f4 100644
--- a/include/sound/q6afe-v2.h
+++ b/include/sound/q6afe-v2.h
@@ -92,7 +92,7 @@
int afe_unregister_get_events(u16 port_id);
int afe_rt_proxy_port_write(u32 buf_addr_p, u32 mem_map_handle, int bytes);
int afe_rt_proxy_port_read(u32 buf_addr_p, u32 mem_map_handle, int bytes);
-int afe_port_start_nowait(u16 port_id, union afe_port_config *afe_config,
+int afe_port_start(u16 port_id, union afe_port_config *afe_config,
u32 rate);
int afe_port_stop_nowait(int port_id);
int afe_apply_gain(u16 port_id, u16 gain);
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 947bd85..b11118f 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2523,7 +2523,7 @@
runtime->tstamp_type = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC;
return 0;
}
-
+
static int snd_pcm_common_ioctl1(struct file *file,
struct snd_pcm_substream *substream,
unsigned int cmd, void __user *arg)
@@ -2592,6 +2592,7 @@
case SNDRV_COMPRESS_SET_PARAMS:
case SNDRV_COMPRESS_GET_PARAMS:
case SNDRV_COMPRESS_TSTAMP:
+ case SNDRV_COMPRESS_DRAIN:
return snd_compressed_ioctl(substream, cmd, arg);
}
snd_printd("unknown ioctl = 0x%x\n", cmd);
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index 5ccf8ed..b76160e 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -42,6 +42,7 @@
#define COMPRE_CAPTURE_PERIOD_SIZE ((COMPRE_CAPTURE_MAX_FRAME_SIZE + \
COMPRE_CAPTURE_HEADER_SIZE) * \
MAX_NUM_FRAMES_PER_BUFFER)
+#define COMPRE_OUTPUT_METADATA_SIZE (sizeof(struct output_meta_data_st))
struct snd_msm {
struct msm_audio *prtd;
@@ -113,8 +114,11 @@
struct audio_aio_write_param param;
struct audio_aio_read_param read_param;
struct audio_buffer *buf = NULL;
+ struct output_meta_data_st output_meta_data;
uint32_t *ptrmem = (uint32_t *)payload;
int i = 0;
+ int time_stamp_flag = 0;
+ int buffer_length = 0;
pr_debug("%s opcode =%08x\n", __func__, opcode);
switch (opcode) {
@@ -143,14 +147,35 @@
((unsigned int)buf[0].phys
+ (prtd->out_head * prtd->pcm_count)));
+ if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
+ time_stamp_flag = SET_TIMESTAMP;
+ else
+ time_stamp_flag = NO_TIMESTAMP;
+ memcpy(&output_meta_data, (char *)(buf->data +
+ prtd->out_head * prtd->pcm_count),
+ COMPRE_OUTPUT_METADATA_SIZE);
+
+ buffer_length = output_meta_data.frame_size;
+ pr_debug("meta_data_length: %d, frame_length: %d\n",
+ output_meta_data.meta_data_length,
+ output_meta_data.frame_size);
+ pr_debug("timestamp_msw: %d, timestamp_lsw: %d\n",
+ output_meta_data.timestamp_msw,
+ output_meta_data.timestamp_lsw);
+ if (buffer_length == 0) {
+ pr_debug("Recieved a zero length buffer-break out");
+ break;
+ }
param.paddr = (unsigned long)buf[0].phys
- + (prtd->out_head * prtd->pcm_count);
- param.len = prtd->pcm_count;
- param.msw_ts = 0;
- param.lsw_ts = 0;
- param.flags = NO_TIMESTAMP;
+ + (prtd->out_head * prtd->pcm_count)
+ + output_meta_data.meta_data_length;
+ param.len = buffer_length;
+ param.msw_ts = output_meta_data.timestamp_msw;
+ param.lsw_ts = output_meta_data.timestamp_lsw;
+ param.flags = time_stamp_flag;
param.uid = (unsigned long)buf[0].phys
- + (prtd->out_head * prtd->pcm_count);
+ + (prtd->out_head * prtd->pcm_count
+ + output_meta_data.meta_data_length);
for (i = 0; i < sizeof(struct audio_aio_write_param)/4;
i++, ++ptrmem)
pr_debug("cmd[%d]=0x%08x\n", i, *ptrmem);
@@ -165,8 +190,12 @@
}
case ASM_DATA_CMDRSP_EOS:
pr_debug("ASM_DATA_CMDRSP_EOS\n");
- prtd->cmd_ack = 1;
- wake_up(&the_locks.eos_wait);
+ if (atomic_read(&prtd->eos)) {
+ pr_debug("ASM_DATA_CMDRSP_EOS wake up\n");
+ prtd->cmd_ack = 1;
+ wake_up(&the_locks.eos_wait);
+ atomic_set(&prtd->eos, 0);
+ }
break;
case ASM_DATA_EVENT_READ_DONE: {
pr_debug("ASM_DATA_EVENT_READ_DONE\n");
@@ -250,12 +279,28 @@
__func__, prtd->out_head,
((unsigned int)buf[0].phys
+ (prtd->out_head * prtd->pcm_count)));
- param.paddr = (unsigned long)buf[prtd->out_head].phys;
- param.len = prtd->pcm_count;
- param.msw_ts = 0;
- param.lsw_ts = 0;
- param.flags = NO_TIMESTAMP;
- param.uid = (unsigned long)buf[prtd->out_head].phys;
+ if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
+ time_stamp_flag = SET_TIMESTAMP;
+ else
+ time_stamp_flag = NO_TIMESTAMP;
+ memcpy(&output_meta_data, (char *)(buf->data +
+ prtd->out_head * prtd->pcm_count),
+ COMPRE_OUTPUT_METADATA_SIZE);
+ buffer_length = output_meta_data.frame_size;
+ pr_debug("meta_data_length: %d, frame_length: %d\n",
+ output_meta_data.meta_data_length,
+ output_meta_data.frame_size);
+ pr_debug("timestamp_msw: %d, timestamp_lsw: %d\n",
+ output_meta_data.timestamp_msw,
+ output_meta_data.timestamp_lsw);
+ param.paddr = (unsigned long)buf[prtd->out_head].phys
+ + output_meta_data.meta_data_length;
+ param.len = buffer_length;
+ param.msw_ts = output_meta_data.timestamp_msw;
+ param.lsw_ts = output_meta_data.timestamp_lsw;
+ param.flags = time_stamp_flag;
+ param.uid = (unsigned long)buf[prtd->out_head].phys
+ + output_meta_data.meta_data_length;
if (q6asm_async_write(prtd->audio_client,
¶m) < 0)
pr_err("%s:q6asm_async_write failed\n",
@@ -270,7 +315,7 @@
case ASM_STREAM_CMD_FLUSH:
pr_debug("ASM_STREAM_CMD_FLUSH\n");
prtd->cmd_ack = 1;
- wake_up(&the_locks.eos_wait);
+ wake_up(&the_locks.flush_wait);
break;
default:
break;
@@ -653,6 +698,7 @@
compr->codec = FORMAT_MP3;
populate_codec_list(compr, runtime);
runtime->private_data = compr;
+ atomic_set(&prtd->eos, 0);
compressed_audio.prtd = &compr->prtd;
ret = compressed_set_volume(compressed_audio.volume);
if (ret < 0)
@@ -699,6 +745,7 @@
dir = IN;
atomic_set(&prtd->pending_buffer, 0);
+ prtd->pcm_irq_pos = 0;
q6asm_cmd(prtd->audio_client, CMD_CLOSE);
compressed_audio.prtd = NULL;
q6asm_audio_client_buf_free_contiguous(dir,
@@ -1027,18 +1074,41 @@
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
(substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
atomic_read(&prtd->start))) {
+ if (atomic_read(&prtd->eos)) {
+ prtd->cmd_ack = 1;
+ wake_up(&the_locks.eos_wait);
+ atomic_set(&prtd->eos, 0);
+ }
+
+ /* A unlikely race condition possible with FLUSH
+ DRAIN if ack is set by flush and reset by drain */
prtd->cmd_ack = 0;
rc = q6asm_cmd(prtd->audio_client, CMD_FLUSH);
- if (rc < 0)
+ if (rc < 0) {
pr_err("%s: flush cmd failed rc=%d\n",
- __func__, rc);
- rc = wait_event_timeout(the_locks.eos_wait,
- prtd->cmd_ack, 5 * HZ);
+ __func__, rc);
+ return rc;
+ }
+ rc = wait_event_timeout(the_locks.flush_wait,
+ prtd->cmd_ack, 5 * HZ);
if (rc < 0)
pr_err("Flush cmd timeout\n");
prtd->pcm_irq_pos = 0;
}
break;
+ case SNDRV_COMPRESS_DRAIN:
+ pr_debug("%s: SNDRV_COMPRESS_DRAIN\n", __func__);
+ atomic_set(&prtd->eos, 1);
+ atomic_set(&prtd->pending_buffer, 0);
+ prtd->cmd_ack = 0;
+ q6asm_cmd_nowait(prtd->audio_client, CMD_EOS);
+ /* Wait indefinitely for DRAIN. Flush can also signal this*/
+ rc = wait_event_interruptible(the_locks.eos_wait,
+ prtd->cmd_ack);
+ if (rc < 0)
+ pr_err("EOS cmd interrupted\n");
+ pr_debug("%s: SNDRV_COMPRESS_DRAIN out of wait\n", __func__);
+ return 0;
default:
break;
}
@@ -1099,6 +1169,7 @@
init_waitqueue_head(&the_locks.eos_wait);
init_waitqueue_head(&the_locks.write_wait);
init_waitqueue_head(&the_locks.read_wait);
+ init_waitqueue_head(&the_locks.flush_wait);
return platform_driver_register(&msm_compr_driver);
}
diff --git a/sound/soc/msm/msm-pcm-q6.h b/sound/soc/msm/msm-pcm-q6.h
index 9e743a7..f1af99a 100644
--- a/sound/soc/msm/msm-pcm-q6.h
+++ b/sound/soc/msm/msm-pcm-q6.h
@@ -48,6 +48,7 @@
wait_queue_head_t write_wait;
wait_queue_head_t eos_wait;
wait_queue_head_t enable_wait;
+ wait_queue_head_t flush_wait;
};
struct msm_audio {
@@ -75,10 +76,19 @@
atomic_t out_count;
atomic_t in_count;
atomic_t out_needed;
+ atomic_t eos;
int out_head;
int periods;
int mmap_flag;
atomic_t pending_buffer;
};
+struct output_meta_data_st {
+ uint32_t meta_data_length;
+ uint32_t frame_size;
+ uint32_t timestamp_lsw;
+ uint32_t timestamp_msw;
+ uint32_t reserved[12];
+};
+
#endif /*_MSM_PCM_H*/
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index 485569b..3eab972 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -400,70 +400,23 @@
int rc = 0;
if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
- /* PORT START should be set if prepare called in active state */
- rc = afe_q6_interface_prepare();
+ switch (dai->id) {
+ case VOICE_PLAYBACK_TX:
+ case VOICE_RECORD_TX:
+ case VOICE_RECORD_RX:
+ rc = afe_start_pseudo_port(dai->id);
+ default:
+ rc = afe_port_start(dai->id, &dai_data->port_config,
+ dai_data->rate);
+ }
+
if (IS_ERR_VALUE(rc))
- dev_err(dai->dev, "fail to open AFE APR\n");
- }
- return rc;
-}
-
-static int msm_dai_q6_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
- int rc = 0;
-
- /*
- * Start/stop port without waiting for Q6 AFE response. Need to have
- * native q6 AFE driver propagates AFE response in order to handle
- * port start/stop command error properly if error does arise.
- */
- pr_debug("%s:port:%d cmd:%d dai_data->status_mask = %ld",
- __func__, dai->id, cmd, *dai_data->status_mask);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
- switch (dai->id) {
- case VOICE_PLAYBACK_TX:
- case VOICE_RECORD_TX:
- case VOICE_RECORD_RX:
- afe_pseudo_port_start_nowait(dai->id);
- break;
- default:
- afe_port_start_nowait(dai->id,
- &dai_data->port_config, dai_data->rate);
- break;
- }
+ dev_err(dai->dev, "fail to open AFE port %x\n",
+ dai->id);
+ else
set_bit(STATUS_PORT_STARTED,
dai_data->status_mask);
- }
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
- switch (dai->id) {
- case VOICE_PLAYBACK_TX:
- case VOICE_RECORD_TX:
- case VOICE_RECORD_RX:
- afe_pseudo_port_stop_nowait(dai->id);
- break;
- default:
- afe_port_stop_nowait(dai->id);
- break;
- }
- clear_bit(STATUS_PORT_STARTED,
- dai_data->status_mask);
- }
- break;
-
- default:
- rc = -EINVAL;
}
-
return rc;
}
@@ -799,7 +752,6 @@
static struct snd_soc_dai_ops msm_dai_q6_ops = {
.prepare = msm_dai_q6_prepare,
- .trigger = msm_dai_q6_trigger,
.hw_params = msm_dai_q6_hw_params,
.shutdown = msm_dai_q6_shutdown,
.set_fmt = msm_dai_q6_set_fmt,
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index 2e58e1b..0b25545 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -30,6 +30,7 @@
atomic_t state;
atomic_t status;
wait_queue_head_t wait[AFE_MAX_PORTS];
+ struct task_struct *task;
void (*tx_cb) (uint32_t opcode,
uint32_t token, uint32_t *payload, void *priv);
void (*rx_cb) (uint32_t opcode,
@@ -58,6 +59,9 @@
atomic_set(&this_afe.state, 0);
this_afe.apr = NULL;
}
+ /* send info to user */
+ pr_debug("task_name = %s pid = %d\n",
+ this_afe.task->comm, this_afe.task->pid);
return 0;
}
pr_debug("%s:opcode = 0x%x cmd = 0x%x status = 0x%x\n",
@@ -248,7 +252,7 @@
afe_send_cal_block(RX_CAL, port_id);
}
-int afe_port_start_nowait(u16 port_id, union afe_port_config *afe_config,
+int afe_port_start(u16 port_id, union afe_port_config *afe_config,
u32 rate) /* This function is no blocking */
{
struct afe_port_cmd_device_start start;
@@ -274,8 +278,9 @@
port_id = VIRTUAL_ID_TO_PORTID(port_id);
ret = afe_q6_interface_prepare();
- if (ret != 0)
+ if (IS_ERR_VALUE(ret))
return ret;
+
if (q6audio_validate_port(port_id) < 0) {
pr_err("%s: Failed : Invalid Port id = %d\n", __func__,
port_id);
@@ -338,6 +343,8 @@
config.port = *afe_config;
+ atomic_set(&this_afe.state, 1);
+ atomic_set(&this_afe.status, 0);
ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config);
if (ret < 0) {
pr_err("%s: AFE enable for port %d failed\n", __func__,
@@ -345,7 +352,20 @@
ret = -EINVAL;
goto fail_cmd;
}
+ ret = wait_event_timeout(this_afe.wait[index],
+ (atomic_read(&this_afe.state) == 0),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: wait_event timeout IF CONFIG\n", __func__);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
+ if (atomic_read(&this_afe.status) != 0) {
+ pr_err("%s: config cmd failed\n", __func__);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
/* send AFE cal */
afe_send_cal(port_id);
@@ -360,6 +380,7 @@
pr_debug("%s: cmd device start opcode[0x%x] port id[0x%x]\n",
__func__, start.hdr.opcode, start.port_id);
+ atomic_set(&this_afe.state, 1);
ret = apr_send_pkt(this_afe.apr, (uint32_t *) &start);
if (IS_ERR_VALUE(ret)) {
@@ -369,6 +390,21 @@
goto fail_cmd;
}
+ ret = wait_event_timeout(this_afe.wait[index],
+ (atomic_read(&this_afe.state) == 0),
+ msecs_to_jiffies(TIMEOUT_MS));
+
+ if (!ret) {
+ pr_err("%s: wait_event timeout PORT START\n", __func__);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
+ if (this_afe.task != current)
+ this_afe.task = current;
+
+ pr_debug("task_name = %s pid = %d\n",
+ this_afe.task->comm, this_afe.task->pid);
+
return 0;
fail_cmd:
@@ -506,8 +542,7 @@
config.pdata.param_size = sizeof(config.port);
config.port = *afe_config;
- pr_debug("%s: param PL size=%d iparam_size[%d][%d %d %d %d]"
- " param_id[%x]\n",
+ pr_debug("%s: param PL size=%d iparam_size[%d][%d %d %d %d] param_id[%x]\n",
__func__, config.param.payload_size, config.pdata.param_size,
sizeof(config), sizeof(config.param), sizeof(config.port),
sizeof(struct apr_hdr), config.pdata.param_id);
@@ -653,8 +688,8 @@
/* RX ports numbers are even .TX ports numbers are odd. */
if (port_id % 2 == 0) {
- pr_err("%s: Failed : afe loopback gain only for TX ports."
- " port_id %d\n", __func__, port_id);
+ pr_err("%s: Failed : afe loopback gain only for TX ports. port_id %d\n",
+ __func__, port_id);
ret = -EINVAL;
goto fail_cmd;
}
@@ -1319,7 +1354,7 @@
else
base = 10;
- if (strict_strtoul(token, base, ¶m1[cnt]) != 0)
+ if (kstrtoul(token, base, ¶m1[cnt]) != 0)
return -EINVAL;
token = strsep(&buf, " ");
@@ -1389,8 +1424,7 @@
}
if (param[1] < 0 || param[1] > 100) {
- pr_err("%s: Error, volume shoud be 0 to 100"
- " percentage param = %lu\n",
+ pr_err("%s: Error, volume shoud be 0 to 100 percentage param = %lu\n",
__func__, param[1]);
rc = -EINVAL;
goto afe_error;