msm: camera: isp: Enable RDI and DS4/DS16 support in VFE
This change enables VFE HW driver to output RDI raw data and
DS4/DS16 streams.
Change-Id: I039da313cbda1cf64667470cf77abf0dd8e7a99b
Signed-off-by: Harsh Shah <harshs@codeaurora.org>
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
index 48b0363..21494b5 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
@@ -26,6 +26,8 @@
#undef CDBG
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+#define FRAME_BASED_EN 0
+
static uint32_t irq_reg_offset[CAM_IFE_BUS_IRQ_REGISTERS_MAX] = {
0x0000205C,
0x00002060,
@@ -649,6 +651,11 @@
wm_res->res_priv;
struct cam_vfe_bus_ver2_common_data *common_data =
rsrc_data->common_data;
+ uint32_t width;
+ uint32_t height;
+ uint32_t pack_fmt;
+ uint32_t stride;
+ uint32_t en_cfg;
CDBG("WM res %d width = %d, height = %d\n", rsrc_data->index,
rsrc_data->width, rsrc_data->height);
@@ -657,22 +664,39 @@
CDBG("WM res %d stride = %d, burst len = %d\n",
rsrc_data->index, rsrc_data->width, 0xf);
- cam_io_w_mb(0,
- common_data->mem_base + rsrc_data->hw_regs->header_addr);
- cam_io_w_mb(0,
- common_data->mem_base + rsrc_data->hw_regs->header_cfg);
- cam_io_w_mb(0,
- common_data->mem_base + rsrc_data->hw_regs->frame_inc);
- cam_io_w_mb(rsrc_data->width,
+ cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_addr);
+ cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_cfg);
+ cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->frame_inc);
+ cam_io_w(0xf, common_data->mem_base + rsrc_data->hw_regs->burst_limit);
+
+ if (rsrc_data->index < 3) {
+ width = rsrc_data->width * 5/4;
+ height = 1;
+ pack_fmt = 0x0;
+ stride = rsrc_data->width * 5/4;
+ en_cfg = 0x3;
+ } else if (rsrc_data->index < 5) {
+ width = rsrc_data->width;
+ height = rsrc_data->height;
+ pack_fmt = 0xE;
+ stride = rsrc_data->width;
+ en_cfg = 0x1;
+ } else {
+ width = rsrc_data->width * 4;
+ height = rsrc_data->height / 2;
+ pack_fmt = 0x0;
+ stride = rsrc_data->width * 4;
+ en_cfg = 0x1;
+ }
+
+ cam_io_w_mb(width,
common_data->mem_base + rsrc_data->hw_regs->buffer_width_cfg);
- cam_io_w(rsrc_data->height,
+ cam_io_w(height,
common_data->mem_base + rsrc_data->hw_regs->buffer_height_cfg);
- cam_io_w(0xe,
+ cam_io_w(pack_fmt,
common_data->mem_base + rsrc_data->hw_regs->packer_cfg);
- cam_io_w(rsrc_data->width,
+ cam_io_w(stride,
common_data->mem_base + rsrc_data->hw_regs->stride);
- cam_io_w(0xf,
- common_data->mem_base + rsrc_data->hw_regs->burst_limit);
cam_io_w(0xFFFFFFFF, common_data->mem_base +
rsrc_data->hw_regs->irq_subsample_pattern);
@@ -680,9 +704,9 @@
rsrc_data->hw_regs->irq_subsample_period);
cam_io_w(0xFFFFFFFF,
- common_data->mem_base + rsrc_data->hw_regs->framedrop_pattern);
+ common_data->mem_base + rsrc_data->hw_regs->framedrop_pattern);
cam_io_w(0x0,
- common_data->mem_base + rsrc_data->hw_regs->framedrop_period);
+ common_data->mem_base + rsrc_data->hw_regs->framedrop_period);
/* UBWC registers */
switch (rsrc_data->format) {
@@ -702,10 +726,16 @@
}
/* Enable WM */
- cam_io_w_mb(0x1,
- common_data->mem_base + rsrc_data->hw_regs->cfg);
- CDBG("enable WM red %d offset 0x%x val 0x%x\n", rsrc_data->index,
- (uint32_t) rsrc_data->hw_regs->cfg, 0x1);
+ cam_io_w_mb(en_cfg, common_data->mem_base + rsrc_data->hw_regs->cfg);
+
+ CDBG("WM res %d width = %d, height = %d\n", rsrc_data->index,
+ width, height);
+ CDBG("WM res %d pk_fmt = %d\n", rsrc_data->index,
+ pack_fmt & PACKER_FMT_MAX);
+ CDBG("WM res %d stride = %d, burst len = %d\n",
+ rsrc_data->index, stride, 0xf);
+ CDBG("enable WM res %d offset 0x%x val 0x%x\n", rsrc_data->index,
+ (uint32_t) rsrc_data->hw_regs->cfg, en_cfg);
wm_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
@@ -754,14 +784,22 @@
int rc = CAM_VFE_IRQ_STATUS_ERR;
struct cam_isp_resource_node *wm_res = wm_node;
struct cam_vfe_bus_irq_evt_payload *evt_payload = evt_payload_priv;
- struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data = wm_res->res_priv;
- uint32_t *cam_ife_irq_regs = evt_payload->irq_reg_val;
+ struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
+ (wm_res == NULL) ? NULL : wm_res->res_priv;
+ uint32_t *cam_ife_irq_regs;
uint32_t status_reg;
- status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0];
+ if (!evt_payload || !rsrc_data)
+ return rc;
- if (status_reg & BIT(rsrc_data->index))
+ cam_ife_irq_regs = evt_payload->irq_reg_val;
+ status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1];
+
+ if (status_reg & BIT(rsrc_data->index)) {
+ cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1] &=
+ ~BIT(rsrc_data->index);
rc = CAM_VFE_IRQ_STATUS_SUCCESS;
+ }
if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
cam_vfe_bus_put_evt_payload(evt_payload->core_info,
@@ -974,9 +1012,6 @@
* Individual Comp_Grp Subscribe IRQ can be done here once
* dynamic IRQ enable support is added.
*/
- cam_io_w_mb(0x00001F70, common_data->mem_base + 0x2044);
- cam_io_w_mb(0x000FFFE7, common_data->mem_base + 0x2048);
- cam_io_w_mb(0x000000FF, common_data->mem_base + 0x204c);
cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
rsrc_data->hw_regs->comp_mask);
@@ -1051,10 +1086,15 @@
struct cam_isp_resource_node *comp_grp = handler_priv;
struct cam_vfe_bus_irq_evt_payload *evt_payload = evt_payload_priv;
struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = comp_grp->res_priv;
- uint32_t *cam_ife_irq_regs = evt_payload->irq_reg_val;
- uint32_t status_reg;
- uint32_t comp_err_reg;
- uint32_t dual_comp_grp;
+ uint32_t *cam_ife_irq_regs;
+ uint32_t status_reg;
+ uint32_t comp_err_reg;
+ uint32_t comp_grp_id;
+
+ if (!evt_payload)
+ return rc;
+
+ cam_ife_irq_regs = evt_payload->irq_reg_val;
CDBG("comp grp type %d\n", rsrc_data->comp_grp_type);
switch (rsrc_data->comp_grp_type) {
@@ -1064,7 +1104,7 @@
case CAM_VFE_BUS_VER2_COMP_GRP_3:
case CAM_VFE_BUS_VER2_COMP_GRP_4:
case CAM_VFE_BUS_VER2_COMP_GRP_5:
- dual_comp_grp = (rsrc_data->comp_grp_type -
+ comp_grp_id = (rsrc_data->comp_grp_type -
CAM_VFE_BUS_VER2_COMP_GRP_0);
/* Check for Regular composite error */
@@ -1086,12 +1126,15 @@
break;
}
- /* Regular Composite SUCCESS*/
- if (status_reg & BIT(dual_comp_grp + 5))
+ /* Regular Composite SUCCESS */
+ if (status_reg & BIT(comp_grp_id + 5)) {
+ cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0] &=
+ ~BIT(comp_grp_id + 5);
rc = CAM_VFE_IRQ_STATUS_SUCCESS;
+ }
CDBG("status reg = 0x%x, bit index = %d\n",
- status_reg, (dual_comp_grp + 5));
+ status_reg, (comp_grp_id + 5));
break;
case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0:
@@ -1100,7 +1143,7 @@
case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_3:
case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_4:
case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5:
- dual_comp_grp = (rsrc_data->comp_grp_type -
+ comp_grp_id = (rsrc_data->comp_grp_type -
CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
/* Check for DUAL composite error */
@@ -1122,12 +1165,14 @@
break;
}
- /* DUAL Composite SUCCESS*/
- if (status_reg & BIT(dual_comp_grp))
+ /* DUAL Composite SUCCESS */
+ if (status_reg & BIT(comp_grp_id)) {
+ cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2] &=
+ ~BIT(comp_grp_id + 5);
rc = CAM_VFE_IRQ_STATUS_SUCCESS;
+ }
break;
-
default:
rc = CAM_VFE_IRQ_STATUS_ERR;
break;
@@ -1302,7 +1347,9 @@
static int cam_vfe_bus_start_vfe_out(struct cam_isp_resource_node *vfe_out)
{
int rc = 0, i;
- struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
+ struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
+ struct cam_vfe_bus_ver2_common_data *common_data =
+ rsrc_data->common_data;
CDBG("Start resource index %d\n", rsrc_data->out_type);
@@ -1312,6 +1359,11 @@
return -EACCES;
}
+ /* Enable IRQ Mask */
+ cam_io_w_mb(0x00001F70, common_data->mem_base + 0x2044);
+ cam_io_w_mb(0x000FFFE7, common_data->mem_base + 0x2048);
+ cam_io_w_mb(0x000000FF, common_data->mem_base + 0x204c);
+
for (i = 0; i < rsrc_data->num_wm; i++)
rc = cam_vfe_bus_start_wm(rsrc_data->wm_res[i]);
@@ -1335,12 +1387,6 @@
cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002080);
/* BUS_WR_INPUT_IF_ADDR_SYNC_NO_SYNC */
cam_io_w_mb(0xFFFFF, rsrc_data->common_data->mem_base + 0x00002084);
- /* no clock gating at bus input */
- cam_io_w_mb(0xFFFFF, rsrc_data->common_data->mem_base + 0x0000200C);
- /* BUS_WR_PWR_ISO_CFG */
- cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x000020CC);
- /* BUS_WR_TEST_BUS_CTRL */
- cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000211C);
/* BUS_WR_INPUT_IF_ADDR_SYNC_0 */
cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002088);
cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000208c);
@@ -1351,6 +1397,12 @@
cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x000020a0);
cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x000020a4);
+ /* no clock gating at bus input */
+ cam_io_w_mb(0xFFFFF, rsrc_data->common_data->mem_base + 0x0000200C);
+
+ /* BUS_WR_TEST_BUS_CTRL */
+ cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000211C);
+
return rc;
}
@@ -1400,7 +1452,7 @@
rsrc_data->comp_grp, evt_payload_priv);
} else {
rc = rsrc_data->wm_res[0]->bottom_half_handler(
- rsrc_data->comp_grp, evt_payload_priv);
+ rsrc_data->wm_res[0], evt_payload_priv);
}
return rc;
@@ -1449,6 +1501,7 @@
struct cam_vfe_bus_irq_evt_payload **evt_payload)
{
if (list_empty(&bus_priv->free_payload_list)) {
+ *evt_payload = NULL;
pr_err("No free payload\n");
return -ENODEV;
}
@@ -1463,6 +1516,16 @@
struct cam_vfe_bus_irq_evt_payload **evt_payload)
{
struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
+ uint32_t *cam_ife_irq_regs = (*evt_payload)->irq_reg_val;
+ uint32_t status_reg0, status_reg1;
+
+ status_reg0 = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0];
+ status_reg1 = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1];
+
+ if (status_reg0 || status_reg1) {
+ CDBG("status0 0x%x status1 0x%x\n", status_reg0, status_reg1);
+ return 0;
+ }
if (!core_info) {
pr_err("Invalid param core_info NULL");
@@ -1489,6 +1552,7 @@
struct cam_vfe_bus *bus_info;
struct cam_vfe_bus_ver2_priv *bus_priv;
struct cam_irq_controller_reg_info *reg_info;
+ uint32_t irq_mask;
handler_priv = th_payload->handler_priv;
core_info = handler_priv->core_info;
@@ -1517,8 +1581,10 @@
(uint64_t)handler_priv->core_info);
for (i = 0; i < CAM_IFE_BUS_IRQ_REGISTERS_MAX; i++) {
- evt_payload->irq_reg_val[i] = cam_io_r(handler_priv->mem_base +
- irq_reg_offset[i]);
+ irq_mask = cam_io_r(handler_priv->mem_base +
+ irq_reg_offset[i] - (0xC * 2));
+ evt_payload->irq_reg_val[i] = irq_mask &
+ cam_io_r(handler_priv->mem_base + irq_reg_offset[i]);
CDBG("irq_status%d = 0x%x\n", i, evt_payload->irq_reg_val[i]);
}
for (i = 0; i <= CAM_IFE_IRQ_BUS_REG_STATUS2; i++) {
@@ -1546,7 +1612,7 @@
struct cam_isp_hw_get_buf_update *update_buf;
struct cam_vfe_bus_ver2_vfe_out_data *vfe_out_data = NULL;
struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
- uint32_t reg_val_pair[6];
+ uint32_t reg_val_pair[8];
uint32_t i, size = 0;
/*