Merge "msm: camera: isp: Enable RDI and DS4/DS16 support in VFE" into msm-4.9
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
index 366ac8a..bf4d174 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
@@ -106,6 +106,7 @@
struct list_head th_list_head[CAM_IRQ_PRIORITY_MAX];
uint32_t hdl_idx;
rwlock_t rw_lock;
+ struct cam_irq_th_payload th_payload;
};
int cam_irq_controller_deinit(void **irq_controller)
@@ -118,11 +119,13 @@
&controller->evt_handler_list_head,
struct cam_irq_evt_handler, list_node);
list_del_init(&evt_handler->list_node);
+ kfree(evt_handler->evt_bit_mask_arr);
kfree(evt_handler);
}
- kfree(controller->irq_register_arr);
+ kfree(controller->th_payload.evt_status_arr);
kfree(controller->irq_status_arr);
+ kfree(controller->irq_register_arr);
kfree(controller);
*irq_controller = NULL;
return 0;
@@ -166,6 +169,16 @@
rc = -ENOMEM;
goto status_alloc_error;
}
+
+ controller->th_payload.evt_status_arr =
+ kzalloc(register_info->num_registers * sizeof(uint32_t),
+ GFP_KERNEL);
+ if (!controller->th_payload.evt_status_arr) {
+ CDBG("Failed to allocate BH payload bit mask Arr\n");
+ rc = -ENOMEM;
+ goto evt_mask_alloc_error;
+ }
+
controller->name = name;
CDBG("num_registers: %d\n", register_info->num_registers);
@@ -206,6 +219,8 @@
return rc;
+evt_mask_alloc_error:
+ kfree(controller->irq_status_arr);
status_alloc_error:
kfree(controller->irq_register_arr);
reg_alloc_error:
@@ -415,9 +430,10 @@
struct list_head *th_list_head)
{
struct cam_irq_evt_handler *evt_handler = NULL;
- struct cam_irq_th_payload th_payload;
+ struct cam_irq_th_payload *th_payload = &controller->th_payload;
bool is_irq_match;
int rc = -EINVAL;
+ int i;
CDBG("Enter\n");
@@ -433,10 +449,14 @@
CDBG("match found\n");
- cam_irq_th_payload_init(&th_payload);
- th_payload.handler_priv = evt_handler->handler_priv;
- th_payload.num_registers = controller->num_registers;
- th_payload.evt_status_arr = controller->irq_status_arr;
+ cam_irq_th_payload_init(th_payload);
+ th_payload->handler_priv = evt_handler->handler_priv;
+ th_payload->num_registers = controller->num_registers;
+ for (i = 0; i < controller->num_registers; i++) {
+ th_payload->evt_status_arr[i] =
+ controller->irq_status_arr[i] &
+ evt_handler->evt_bit_mask_arr[i];
+ }
/*
* irq_status_arr[0] is dummy argument passed. the entire
@@ -445,8 +465,7 @@
if (evt_handler->top_half_handler)
rc = evt_handler->top_half_handler(
controller->irq_status_arr[0],
- (void *)&th_payload);
-
+ (void *)th_payload);
if (!rc && evt_handler->bottom_half_handler) {
CDBG("Enqueuing bottom half\n");
@@ -454,7 +473,7 @@
evt_handler->bottom_half_enqueue_func(
evt_handler->bottom_half,
evt_handler->handler_priv,
- th_payload.evt_payload_priv,
+ th_payload->evt_payload_priv,
evt_handler->bottom_half_handler);
}
}
@@ -465,9 +484,10 @@
irqreturn_t cam_irq_controller_handle_irq(int irq_num, void *priv)
{
- struct cam_irq_controller *controller = priv;
- int i, j;
- bool need_th_processing[CAM_IRQ_PRIORITY_MAX] = {false};
+ struct cam_irq_controller *controller = priv;
+ bool need_th_processing[CAM_IRQ_PRIORITY_MAX] = {false};
+ int i;
+ int j;
if (!controller)
return IRQ_NONE;
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.h
index 2f88a8b..1990c51 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.h
@@ -103,7 +103,6 @@
struct cam_irq_th_payload *th_payload) {
th_payload->handler_priv = NULL;
th_payload->evt_payload_priv = NULL;
- th_payload->evt_status_arr = NULL;
}
typedef int (*CAM_IRQ_HANDLER_TOP_HALF)(uint32_t evt_id,
@@ -215,4 +214,4 @@
*/
irqreturn_t cam_irq_controller_handle_irq(int irq_num, void *priv);
-#endif /*_CAM_IRQ_CONTROLLER_H_ */
+#endif /* _CAM_IRQ_CONTROLLER_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
index 488a00b..739a1e7 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
@@ -23,6 +23,7 @@
#include "cam_vfe_core.h"
#include "cam_vfe_bus.h"
#include "cam_vfe_top.h"
+#include "cam_ife_hw_mgr.h"
#undef CDBG
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
@@ -35,11 +36,16 @@
0x0000007C,
};
-static uint32_t top_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
- 0x7803FDFF,
+static uint32_t camif_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
+ 0x0003FD1F,
0x0FFF7EB3,
};
+static uint32_t rdi_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
+ 0x780000e0,
+ 0x00000000,
+};
+
static uint32_t top_reset_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
0x80000000,
0x00000000,
@@ -440,11 +446,21 @@
mutex_lock(&vfe_hw->hw_mutex);
if (isp_res->res_type == CAM_ISP_RESOURCE_VFE_IN) {
- isp_res->irq_handle = cam_irq_controller_subscribe_irq(
- core_info->vfe_irq_controller, CAM_IRQ_PRIORITY_2,
- top_irq_reg_mask, &core_info->irq_payload,
- cam_vfe_irq_top_half, NULL,
- isp_res->tasklet_info, cam_tasklet_enqueue_cmd);
+ if (isp_res->res_id == CAM_ISP_HW_VFE_IN_CAMIF)
+ isp_res->irq_handle = cam_irq_controller_subscribe_irq(
+ core_info->vfe_irq_controller,
+ CAM_IRQ_PRIORITY_2,
+ camif_irq_reg_mask, &core_info->irq_payload,
+ cam_vfe_irq_top_half, cam_ife_mgr_do_tasklet,
+ isp_res->tasklet_info, cam_tasklet_enqueue_cmd);
+ else
+ isp_res->irq_handle = cam_irq_controller_subscribe_irq(
+ core_info->vfe_irq_controller,
+ CAM_IRQ_PRIORITY_2,
+ rdi_irq_reg_mask, &core_info->irq_payload,
+ cam_vfe_irq_top_half, cam_ife_mgr_do_tasklet,
+ isp_res->tasklet_info, cam_tasklet_enqueue_cmd);
+
if (isp_res->irq_handle > 0)
rc = core_info->vfe_top->hw_ops.start(
core_info->vfe_top->top_priv, isp_res,
@@ -456,7 +472,7 @@
core_info->vfe_irq_controller, CAM_IRQ_PRIORITY_1,
bus_irq_reg_mask, &core_info->irq_payload,
core_info->vfe_bus->top_half_handler,
- NULL,
+ cam_ife_mgr_do_tasklet_buf_done,
isp_res->tasklet_info, cam_tasklet_enqueue_cmd);
if (isp_res->irq_handle > 0)
rc = core_info->vfe_bus->start_resource(isp_res);
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.h
index 92e322b..94b4cf0 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.h
@@ -43,7 +43,7 @@
struct cam_isp_reg_val_pair *vbif_settings;
};
-#define CAM_VFE_EVT_MAX 128
+#define CAM_VFE_EVT_MAX 256
struct cam_vfe_hw_core_info {
struct cam_vfe_hw_info *vfe_hw_info;
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;
/*
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/Makefile b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/Makefile
index 56dc513..0a94746 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/Makefile
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/Makefile
@@ -7,4 +7,4 @@
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/include
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/include
-obj-$(CONFIG_SPECTRA_CAMERA) += cam_vfe_top.o cam_vfe_top_ver2.o cam_vfe_camif_ver2.o
+obj-$(CONFIG_SPECTRA_CAMERA) += cam_vfe_top.o cam_vfe_top_ver2.o cam_vfe_camif_ver2.o cam_vfe_rdi.o
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
index ff56115..3f3c2a3 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
@@ -124,7 +124,7 @@
cam_io_w_mb(0x1, rsrc_data->mem_base +
rsrc_data->camif_reg->irq_subsample_pattern);
- /* epoch config with 20 line */
+ /* epoch config with 20 line */
cam_io_w_mb(0x00140014,
rsrc_data->mem_base + rsrc_data->camif_reg->epoch_irq);
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.c
new file mode 100644
index 0000000..5f77a7c
--- /dev/null
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.c
@@ -0,0 +1,189 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
+
+#include <linux/slab.h>
+#include "cam_vfe_rdi.h"
+#include "cam_isp_hw_mgr_intf.h"
+#include "cam_vfe_hw_intf.h"
+#include "cam_io_util.h"
+
+#undef CDBG
+#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+
+struct cam_vfe_mux_rdi_data {
+ void __iomem *mem_base;
+ struct cam_hw_intf *hw_intf;
+ struct cam_vfe_top_ver2_reg_offset_common *common_reg;
+
+ enum cam_isp_hw_sync_mode sync_mode;
+};
+
+int cam_vfe_rdi_ver2_acquire_resource(
+ struct cam_isp_resource_node *rdi_res,
+ void *acquire_param)
+{
+ struct cam_vfe_mux_rdi_data *rdi_data;
+ struct cam_vfe_acquire_args *acquire_data;
+
+ rdi_data = (struct cam_vfe_mux_rdi_data *)rdi_res->res_priv;
+ acquire_data = (struct cam_vfe_acquire_args *)acquire_param;
+
+ rdi_data->sync_mode = acquire_data->vfe_in.sync_mode;
+
+ return 0;
+}
+
+static int cam_vfe_rdi_resource_start(
+ struct cam_isp_resource_node *rdi_res)
+{
+ struct cam_vfe_mux_rdi_data *rsrc_data;
+ int rc = 0;
+
+ if (!rdi_res) {
+ pr_err("Error! Invalid input arguments\n");
+ return -EINVAL;
+ }
+
+ if (rdi_res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
+ pr_err("Error! Invalid rdi res res_state:%d\n",
+ rdi_res->res_state);
+ return -EINVAL;
+ }
+
+ rsrc_data = (struct cam_vfe_mux_rdi_data *)rdi_res->res_priv;
+ rdi_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
+
+ /* Reg Update */
+ cam_io_w_mb(0x2, rsrc_data->mem_base + 0x4AC);
+
+ CDBG("Exit\n");
+
+ return rc;
+}
+
+
+static int cam_vfe_rdi_resource_stop(
+ struct cam_isp_resource_node *rdi_res)
+{
+ struct cam_vfe_mux_rdi_data *rdi_priv;
+ int rc = 0;
+
+ if (!rdi_res) {
+ pr_err("Error! Invalid input arguments\n");
+ return -EINVAL;
+ }
+
+ if (rdi_res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED ||
+ rdi_res->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE)
+ return 0;
+
+ rdi_priv = (struct cam_vfe_mux_rdi_data *)rdi_res->res_priv;
+
+ if (rdi_res->res_state == CAM_ISP_RESOURCE_STATE_STREAMING)
+ rdi_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
+
+
+ return rc;
+}
+
+int cam_vfe_rdi_process_cmd(void *priv,
+ uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
+{
+ int rc = -EINVAL;
+
+ if (!priv || !cmd_args) {
+ pr_err("Error! Invalid input arguments\n");
+ return -EINVAL;
+ }
+
+ switch (cmd_type) {
+ default:
+ pr_err("Error! unsupported RDI process command:%d\n", cmd_type);
+ break;
+ }
+
+ return rc;
+}
+
+static int cam_vfe_rdi_handle_irq_top_half(uint32_t evt_id,
+ struct cam_irq_th_payload *th_payload)
+{
+ return -EPERM;
+}
+
+static int cam_vfe_rdi_handle_irq_bottom_half(void *handler_priv,
+ void *evt_payload_priv)
+{
+ int ret = CAM_VFE_IRQ_STATUS_ERR;
+ struct cam_isp_resource_node *rdi_node;
+ struct cam_vfe_mux_rdi_data *rdi_priv;
+ struct cam_vfe_top_irq_evt_payload *payload;
+ uint32_t irq_status0;
+
+ if (!handler_priv || !evt_payload_priv)
+ return ret;
+
+ rdi_node = handler_priv;
+ rdi_priv = rdi_node->res_priv;
+ payload = evt_payload_priv;
+ irq_status0 = payload->irq_reg_val[CAM_IFE_IRQ_CAMIF_REG_STATUS0];
+
+ CDBG("event ID:%d\n", payload->evt_id);
+ CDBG("irq_status_0 = %x\n", irq_status0);
+
+ switch (payload->evt_id) {
+ case CAM_ISP_HW_EVENT_SOF:
+ if (irq_status0 & 0x8000000)
+ ret = CAM_VFE_IRQ_STATUS_SUCCESS;
+ break;
+ case CAM_ISP_HW_EVENT_REG_UPDATE:
+ if (irq_status0 & 0x20)
+ ret = CAM_VFE_IRQ_STATUS_SUCCESS;
+ break;
+ default:
+ break;
+ }
+
+ CDBG("returing status = %d\n", ret);
+ return ret;
+}
+
+int cam_vfe_rdi_ver2_init(
+ struct cam_hw_intf *hw_intf,
+ struct cam_hw_soc_info *soc_info,
+ void *rdi_hw_info,
+ struct cam_isp_resource_node *rdi_node)
+{
+ struct cam_vfe_mux_rdi_data *rdi_priv = NULL;
+
+ rdi_priv = kzalloc(sizeof(struct cam_vfe_mux_rdi_data),
+ GFP_KERNEL);
+ if (!rdi_priv) {
+ CDBG("Error! Failed to alloc for rdi_priv\n");
+ return -ENOMEM;
+ }
+
+ rdi_node->res_priv = rdi_priv;
+
+ rdi_priv->mem_base = soc_info->reg_map[VFE_CORE_BASE_IDX].mem_base;
+ rdi_priv->hw_intf = hw_intf;
+
+ rdi_node->start = cam_vfe_rdi_resource_start;
+ rdi_node->stop = cam_vfe_rdi_resource_stop;
+ rdi_node->top_half_handler = cam_vfe_rdi_handle_irq_top_half;
+ rdi_node->bottom_half_handler = cam_vfe_rdi_handle_irq_bottom_half;
+
+ return 0;
+}
+
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.h
new file mode 100644
index 0000000..967cec3
--- /dev/null
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.h
@@ -0,0 +1,46 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CAM_VFE_RDI_H_
+#define _CAM_VFE_RDI_H_
+
+#include "cam_isp_hw.h"
+#include "cam_vfe_top.h"
+
+struct cam_vfe_rdi_ver2_reg {
+ uint32_t reg_update_cmd;
+};
+
+struct cam_vfe_rdi_reg_data {
+ uint32_t reg_update_irq_mask;
+};
+
+struct cam_vfe_rdi_ver2_hw_info {
+ struct cam_vfe_top_ver2_reg_offset_common *common_reg;
+ struct cam_vfe_rdi_ver2_reg *rdi_reg;
+ struct cam_vfe_rdi_reg_data *reg_data;
+};
+
+int cam_vfe_rdi_ver2_acquire_resource(
+ struct cam_isp_resource_node *rdi_res,
+ void *acquire_param);
+
+int cam_vfe_rdi_process_cmd(void *priv,
+ uint32_t cmd_type, void *cmd_args, uint32_t arg_size);
+
+int cam_vfe_rdi_ver2_init(
+ struct cam_hw_intf *hw_intf,
+ struct cam_hw_soc_info *soc_info,
+ void *rdi_hw_info,
+ struct cam_isp_resource_node *rdi_node);
+
+#endif /* _CAM_VFE_RDI_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
index 4fa5e98..cbddf01 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
@@ -118,8 +118,12 @@
if (cdm_args->res->res_id == CAM_ISP_HW_VFE_IN_CAMIF)
reg_val_pair[1] = BIT(0);
- else
- reg_val_pair[1] = BIT(cdm_args->res->res_id + 1);
+ else {
+ uint32_t rdi_num = cdm_args->res->res_id -
+ CAM_ISP_HW_VFE_IN_RDI0;
+ /* RDI reg_update starts at BIT 1, so add 1 */
+ reg_val_pair[1] = BIT(rdi_num + 1);
+ }
cdm_util_ops->cdm_write_regrandom(cdm_args->cmd_buf_addr,
1, reg_val_pair);
@@ -132,13 +136,13 @@
int cam_vfe_top_get_hw_caps(void *device_priv,
void *get_hw_cap_args, uint32_t arg_size)
{
- return 0;
+ return -EPERM;
}
int cam_vfe_top_init_hw(void *device_priv,
void *init_hw_args, uint32_t arg_size)
{
- return 0;
+ return -EPERM;
}
int cam_vfe_top_reset(void *device_priv,
@@ -304,13 +308,13 @@
int cam_vfe_top_read(void *device_priv,
void *read_args, uint32_t arg_size)
{
- return -ENODEV;
+ return -EPERM;
}
int cam_vfe_top_write(void *device_priv,
void *write_args, uint32_t arg_size)
{
- return -ENODEV;
+ return -EPERM;
}
int cam_vfe_top_process_cmd(void *device_priv, uint32_t cmd_type,
@@ -387,7 +391,10 @@
/* set the RDI resource id */
top_priv->mux_rsrc[i].res_id =
CAM_ISP_HW_VFE_IN_RDI0 + j;
- top_priv->mux_rsrc[i].res_priv = NULL;
+ rc = cam_vfe_rdi_ver2_init(hw_intf, soc_info,
+ NULL, &top_priv->mux_rsrc[i]);
+ if (rc)
+ goto deinit_resources;
j++;
}
}
@@ -410,6 +417,7 @@
return rc;
+deinit_resources:
err_mux_init:
kfree(vfe_top->top_priv);
err_alloc_priv:
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.h
index 24301d7..1038721 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.h
@@ -14,6 +14,7 @@
#define _CAM_VFE_TOP_VER2_H_
#include "cam_vfe_camif_ver2.h"
+#include "cam_vfe_rdi.h"
#define CAM_VFE_TOP_VER2_MUX_MAX 4