msm: camera: isp: Add support for dual isp
Add support for dual ISP. Change allows for address sync,
external regupdate and image address configuraion for dual
case. Also adds csid test gen for dual isp.
Change-Id: Id3cb4b45c3562f7257007bc2b91436d07e26a368
Signed-off-by: Ravikishore Pampana <rpampana@codeaurora.org>
Signed-off-by: Karthik Anantha Ram <kartanan@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 71994b9..005d7e0 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
@@ -12,6 +12,7 @@
#include <linux/ratelimit.h>
#include <linux/slab.h>
+#include <uapi/media/cam_isp.h>
#include "cam_io_util.h"
#include "cam_debug_util.h"
#include "cam_cdm_util.h"
@@ -34,14 +35,18 @@
#define CAM_VFE_BUS_VER2_PAYLOAD_MAX 256
-#define CAM_VFE_RDI_BUS_DEFAULT_WIDTH 0xFF01
-#define CAM_VFE_RDI_BUS_DEFAULT_STRIDE 0xFF01
+#define CAM_VFE_RDI_BUS_DEFAULT_WIDTH 0xFF01
+#define CAM_VFE_RDI_BUS_DEFAULT_STRIDE 0xFF01
+#define CAM_VFE_BUS_INTRA_CLIENT_MASK 0x3
+#define CAM_VFE_BUS_ADDR_SYNC_INTRA_CLIENT_SHIFT 8
+#define CAM_VFE_BUS_ADDR_NO_SYNC_DEFAULT_VAL 0xFFFFF
#define ALIGNUP(value, alignment) \
((value + alignment - 1) / alignment * alignment)
#define MAX_BUF_UPDATE_REG_NUM \
- (sizeof(struct cam_vfe_bus_ver2_reg_offset_bus_client)/4)
+ ((sizeof(struct cam_vfe_bus_ver2_reg_offset_bus_client) + \
+ sizeof(struct cam_vfe_bus_ver2_reg_offset_ubwc_client))/4)
#define MAX_REG_VAL_PAIR_SIZE \
(MAX_BUF_UPDATE_REG_NUM * 2 * CAM_PACKET_MAX_PLANES)
@@ -97,6 +102,7 @@
struct mutex bus_mutex;
uint32_t secure_mode;
uint32_t num_sec_out;
+ uint32_t addr_no_sync;
};
struct cam_vfe_bus_ver2_wm_resource_data {
@@ -133,6 +139,7 @@
uint32_t framedrop_pattern;
uint32_t en_cfg;
+ uint32_t is_dual;
};
struct cam_vfe_bus_ver2_comp_grp_data {
@@ -148,6 +155,7 @@
uint32_t dual_slave_core;
uint32_t intra_client_mask;
uint32_t composite_mask;
+ uint32_t addr_sync_mode;
uint32_t acquire_dev_cnt;
uint32_t irq_trigger_cnt;
@@ -284,7 +292,7 @@
case CAM_VFE_BUS_VER2_VFE_CORE_0:
switch (dual_slave_core) {
case CAM_VFE_BUS_VER2_VFE_CORE_1:
- *intra_client_mask = 0x1;
+ *intra_client_mask = 0x3;
break;
case CAM_VFE_BUS_VER2_VFE_CORE_2:
*intra_client_mask = 0x2;
@@ -770,10 +778,10 @@
void *ctx,
enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id,
enum cam_vfe_bus_plane_type plane,
- enum cam_isp_hw_split_id split_id,
uint32_t subscribe_irq,
struct cam_isp_resource_node **wm_res,
- uint32_t *client_done_mask)
+ uint32_t *client_done_mask,
+ uint32_t is_dual)
{
uint32_t wm_idx = 0;
struct cam_isp_resource_node *wm_res_local = NULL;
@@ -802,6 +810,9 @@
rsrc_data->width = out_port_info->width;
rsrc_data->height = out_port_info->height;
+ rsrc_data->is_dual = is_dual;
+ /* Set WM offset value to default */
+ rsrc_data->offset = 0;
CAM_DBG(CAM_ISP, "WM %d width %d height %d", rsrc_data->index,
rsrc_data->width, rsrc_data->height);
@@ -987,6 +998,7 @@
rsrc_data->init_cfg_done = false;
rsrc_data->hfr_cfg_done = false;
rsrc_data->en_cfg = 0;
+ rsrc_data->is_dual = 0;
wm_res->tasklet_info = NULL;
wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
@@ -1277,6 +1289,7 @@
if (!comp_grp_local) {
/* First find a free group */
if (is_dual) {
+ CAM_DBG(CAM_ISP, "Acquire dual comp group");
if (list_empty(&ver2_bus_priv->free_dual_comp_grp)) {
CAM_ERR(CAM_ISP, "No Free Composite Group");
return -ENODEV;
@@ -1289,7 +1302,10 @@
dual_slave_core,
comp_grp_local->hw_intf->hw_idx,
&rsrc_data->intra_client_mask);
+ if (rc)
+ return rc;
} else {
+ CAM_DBG(CAM_ISP, "Acquire comp group");
if (list_empty(&ver2_bus_priv->free_comp_grp)) {
CAM_ERR(CAM_ISP, "No Free Composite Group");
return -ENODEV;
@@ -1309,6 +1325,11 @@
rsrc_data->unique_id = unique_id;
rsrc_data->comp_grp_local_idx = bus_comp_grp_id;
+ if (is_master)
+ rsrc_data->addr_sync_mode = 0;
+ else
+ rsrc_data->addr_sync_mode = 1;
+
list_add_tail(&comp_grp_local->list,
&ver2_bus_priv->used_comp_grp);
@@ -1324,6 +1345,8 @@
}
}
+ CAM_DBG(CAM_ISP, "Comp Grp type %u", rsrc_data->comp_grp_type);
+
rsrc_data->ctx = ctx;
rsrc_data->acquire_dev_cnt++;
*comp_grp = comp_grp_local;
@@ -1356,6 +1379,7 @@
}
in_rsrc_data = in_comp_grp->res_priv;
+ CAM_DBG(CAM_ISP, "Comp Grp type %u", in_rsrc_data->comp_grp_type);
list_for_each_entry(comp_grp, &ver2_bus_priv->used_comp_grp, list) {
if (comp_grp == in_comp_grp) {
@@ -1378,6 +1402,7 @@
in_rsrc_data->comp_grp_local_idx = CAM_VFE_BUS_COMP_GROUP_NONE;
in_rsrc_data->composite_mask = 0;
in_rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
+ in_rsrc_data->addr_sync_mode = 0;
comp_grp->tasklet_info = NULL;
comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
@@ -1402,55 +1427,103 @@
static int cam_vfe_bus_start_comp_grp(struct cam_isp_resource_node *comp_grp)
{
int rc = 0;
+ uint32_t addr_sync_cfg;
struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
comp_grp->res_priv;
struct cam_vfe_bus_ver2_common_data *common_data =
rsrc_data->common_data;
uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
+ CAM_DBG(CAM_ISP, "comp group id:%d streaming state:%d",
+ rsrc_data->comp_grp_type, comp_grp->res_state);
+
cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
rsrc_data->hw_regs->comp_mask);
+ if (comp_grp->res_state == CAM_ISP_RESOURCE_STATE_STREAMING)
+ return 0;
CAM_DBG(CAM_ISP, "composite_mask is 0x%x", rsrc_data->composite_mask);
CAM_DBG(CAM_ISP, "composite_mask addr 0x%x",
rsrc_data->hw_regs->comp_mask);
if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
- rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5 &&
- rsrc_data->is_master) {
+ rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5) {
int dual_comp_grp = (rsrc_data->comp_grp_type -
CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
- int intra_client_en = cam_io_r_mb(common_data->mem_base +
- common_data->common_reg->dual_master_comp_cfg);
- /* 2 Bits per comp_grp. Hence left shift by comp_grp * 2 */
- intra_client_en |=
- (rsrc_data->intra_client_mask << dual_comp_grp * 2);
+ if (rsrc_data->is_master) {
+ int intra_client_en = cam_io_r_mb(
+ common_data->mem_base +
+ common_data->common_reg->dual_master_comp_cfg);
- cam_io_w_mb(intra_client_en, common_data->mem_base +
- common_data->common_reg->dual_master_comp_cfg);
+ /*
+ * 2 Bits per comp_grp. Hence left shift by
+ * comp_grp * 2
+ */
+ intra_client_en |=
+ (rsrc_data->intra_client_mask <<
+ (dual_comp_grp * 2));
- bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG2] = (1 << dual_comp_grp);
+ cam_io_w_mb(intra_client_en, common_data->mem_base +
+ common_data->common_reg->dual_master_comp_cfg);
+
+ bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG2] =
+ (1 << dual_comp_grp);
+ }
+
+ CAM_DBG(CAM_ISP, "addr_sync_mask addr 0x%x",
+ rsrc_data->hw_regs->addr_sync_mask);
+ cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
+ rsrc_data->hw_regs->addr_sync_mask);
+
+ addr_sync_cfg = cam_io_r_mb(common_data->mem_base +
+ common_data->common_reg->addr_sync_cfg);
+ addr_sync_cfg |= (rsrc_data->addr_sync_mode << dual_comp_grp);
+ /*
+ * 2 Bits per dual_comp_grp. dual_comp_grp stats at bit number
+ * 8. Hence left shift cdual_comp_grp dual comp_grp * 2 and
+ * add 8
+ */
+ addr_sync_cfg |=
+ (rsrc_data->intra_client_mask <<
+ ((dual_comp_grp * 2) +
+ CAM_VFE_BUS_ADDR_SYNC_INTRA_CLIENT_SHIFT));
+ cam_io_w_mb(addr_sync_cfg, common_data->mem_base +
+ common_data->common_reg->addr_sync_cfg);
+
+ common_data->addr_no_sync &= ~(rsrc_data->composite_mask);
+ cam_io_w_mb(common_data->addr_no_sync, common_data->mem_base +
+ common_data->common_reg->addr_sync_no_sync);
+ CAM_DBG(CAM_ISP, "addr_sync_cfg: 0x%x addr_no_sync_cfg: 0x%x",
+ addr_sync_cfg, common_data->addr_no_sync);
} else {
/* IRQ bits for COMP GRP start at 5. So add 5 to the shift */
bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG0] =
(1 << (rsrc_data->comp_grp_type + 5));
}
- /* Subscribe IRQ */
+ /*
+ * For Dual composite subscribe IRQ only for master
+ * For regular composite, subscribe IRQ always
+ */
CAM_DBG(CAM_ISP, "Subscribe COMP_GRP%d IRQ", rsrc_data->comp_grp_type);
- comp_grp->irq_handle = cam_irq_controller_subscribe_irq(
- common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
- bus_irq_reg_mask, comp_grp,
- comp_grp->top_half_handler,
- cam_ife_mgr_do_tasklet_buf_done,
- comp_grp->tasklet_info, cam_tasklet_enqueue_cmd);
- if (comp_grp->irq_handle < 0) {
- CAM_ERR(CAM_ISP, "Subscribe IRQ failed for comp_grp %d",
- rsrc_data->comp_grp_type);
- return -EFAULT;
+ if (((rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
+ rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5) &&
+ (rsrc_data->is_master)) ||
+ (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_0 &&
+ rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_5)) {
+ comp_grp->irq_handle = cam_irq_controller_subscribe_irq(
+ common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
+ bus_irq_reg_mask, comp_grp,
+ comp_grp->top_half_handler,
+ cam_ife_mgr_do_tasklet_buf_done,
+ comp_grp->tasklet_info, cam_tasklet_enqueue_cmd);
+ if (comp_grp->irq_handle < 0) {
+ CAM_ERR(CAM_ISP, "Subscribe IRQ failed for comp_grp %d",
+ rsrc_data->comp_grp_type);
+ return -EFAULT;
+ }
}
-
comp_grp->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
return rc;
@@ -1459,32 +1532,65 @@
static int cam_vfe_bus_stop_comp_grp(struct cam_isp_resource_node *comp_grp)
{
int rc = 0;
+ uint32_t addr_sync_cfg;
struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
comp_grp->res_priv;
struct cam_vfe_bus_ver2_common_data *common_data =
rsrc_data->common_data;
/* Unsubscribe IRQ */
- rc = cam_irq_controller_unsubscribe_irq(
- common_data->bus_irq_controller,
- comp_grp->irq_handle);
+ if (((rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
+ rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5) &&
+ (rsrc_data->is_master)) ||
+ (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_0 &&
+ rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_5)) {
+ rc = cam_irq_controller_unsubscribe_irq(
+ common_data->bus_irq_controller,
+ comp_grp->irq_handle);
+ }
cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
rsrc_data->hw_regs->comp_mask);
if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
- rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5 &&
- rsrc_data->is_master) {
+ rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5) {
+
int dual_comp_grp = (rsrc_data->comp_grp_type -
CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
- int intra_client_en = cam_io_r_mb(common_data->mem_base +
- common_data->common_reg->dual_master_comp_cfg);
- /* 2 Bits per comp_grp. Hence left shift by comp_grp * 2 */
- intra_client_en &=
- ~(rsrc_data->intra_client_mask << dual_comp_grp * 2);
+ if (rsrc_data->is_master) {
+ int intra_client_en = cam_io_r_mb(
+ common_data->mem_base +
+ common_data->common_reg->dual_master_comp_cfg);
- cam_io_w_mb(intra_client_en, common_data->mem_base +
- common_data->common_reg->dual_master_comp_cfg);
+ /*
+ * 2 Bits per comp_grp. Hence left shift by
+ * comp_grp * 2
+ */
+ intra_client_en &=
+ ~(rsrc_data->intra_client_mask <<
+ dual_comp_grp * 2);
+
+ cam_io_w_mb(intra_client_en, common_data->mem_base +
+ common_data->common_reg->dual_master_comp_cfg);
+ }
+
+ addr_sync_cfg = cam_io_r_mb(common_data->mem_base +
+ common_data->common_reg->addr_sync_cfg);
+ addr_sync_cfg &= ~(1 << dual_comp_grp);
+ addr_sync_cfg &= ~(CAM_VFE_BUS_INTRA_CLIENT_MASK <<
+ ((dual_comp_grp * 2) +
+ CAM_VFE_BUS_ADDR_SYNC_INTRA_CLIENT_SHIFT));
+ cam_io_w_mb(addr_sync_cfg, common_data->mem_base +
+ common_data->common_reg->addr_sync_cfg);
+
+ cam_io_w_mb(0, common_data->mem_base +
+ rsrc_data->hw_regs->addr_sync_mask);
+ common_data->addr_no_sync |= rsrc_data->composite_mask;
+ cam_io_w_mb(common_data->addr_no_sync, common_data->mem_base +
+ common_data->common_reg->addr_sync_no_sync);
+ CAM_DBG(CAM_ISP, "addr_sync_cfg: 0x% addr_no_sync_cfg: 0x%x",
+ addr_sync_cfg, common_data->addr_no_sync);
+
}
comp_grp->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
@@ -1511,6 +1617,7 @@
CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
+ CAM_DBG(CAM_ISP, "IRQ status_2 = %x", th_payload->evt_status_arr[2]);
rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
if (rc) {
@@ -1633,7 +1740,7 @@
if (rsrc_data->irq_trigger_cnt ==
rsrc_data->acquire_dev_cnt) {
cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2] &=
- ~BIT(comp_grp_id + 5);
+ ~BIT(comp_grp_id);
rsrc_data->irq_trigger_cnt = 0;
}
rc = CAM_VFE_IRQ_STATUS_SUCCESS;
@@ -1815,10 +1922,12 @@
rsrc_data->cdm_util_ops = out_acquire_args->cdm_ops;
/* Reserve Composite Group */
- if (num_wm > 1 || (out_acquire_args->out_port_info->comp_grp_id >
- CAM_ISP_RES_COMP_GROUP_NONE &&
- out_acquire_args->out_port_info->comp_grp_id <
- CAM_ISP_RES_COMP_GROUP_ID_MAX)) {
+ if (num_wm > 1 || (out_acquire_args->is_dual) ||
+ (out_acquire_args->out_port_info->comp_grp_id >
+ CAM_ISP_RES_COMP_GROUP_NONE &&
+ out_acquire_args->out_port_info->comp_grp_id <
+ CAM_ISP_RES_COMP_GROUP_ID_MAX)) {
+
rc = cam_vfe_bus_acquire_comp_grp(ver2_bus_priv,
out_acquire_args->out_port_info,
acq_args->tasklet,
@@ -1849,10 +1958,10 @@
out_acquire_args->ctx,
vfe_out_res_id,
i,
- out_acquire_args->split_id,
subscribe_irq,
&rsrc_data->wm_res[i],
- &client_done_mask);
+ &client_done_mask,
+ out_acquire_args->is_dual);
if (rc) {
CAM_ERR(CAM_ISP,
"VFE%d WM acquire failed for Out %d rc=%d",
@@ -1977,28 +2086,6 @@
if (rsrc_data->comp_grp)
rc = cam_vfe_bus_start_comp_grp(rsrc_data->comp_grp);
- /* BUS_WR_INPUT_IF_ADDR_SYNC_CFG */
- cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000207C);
- /* BUS_WR_INPUT_IF_ADDR_SYNC_FRAME_HEADER */
- 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);
- /* 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);
- cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002090);
- cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002094);
- cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002098);
- cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000209c);
- 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);
-
vfe_out->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
return rc;
}
@@ -2027,7 +2114,6 @@
for (i = 0; i < rsrc_data->num_wm; i++)
rc = cam_vfe_bus_stop_wm(rsrc_data->wm_res[i]);
-
vfe_out->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
return rc;
}
@@ -2146,11 +2232,6 @@
uint32_t i, j, size = 0;
uint32_t frame_inc = 0;
- /*
- * Need the entire buf io config so we can get the stride info
- * for the wm.
- */
-
bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
update_buf = (struct cam_isp_hw_get_buf_update *) cmd_args;
@@ -2182,6 +2263,12 @@
wm_data = vfe_out_data->wm_res[i]->res_priv;
+ /* update width register */
+ CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
+ wm_data->hw_regs->buffer_width_cfg,
+ wm_data->width);
+ CAM_DBG(CAM_ISP, "image width 0x%x", wm_data->width);
+
/* For initial configuration program all bus registers */
if ((wm_data->stride != io_cfg->planes[i].plane_stride ||
!wm_data->init_cfg_done) && (wm_data->index >= 3)) {
@@ -2252,7 +2339,12 @@
CAM_DBG(CAM_ISP, "packer cfg 0x%x",
wm_data->packer_cfg);
- if (wm_data->tile_cfg != io_cfg->planes[i].tile_config
+ if (wm_data->is_dual) {
+ CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
+ wm_data->hw_regs->ubwc_regs->tile_cfg,
+ wm_data->tile_cfg);
+ } else if ((wm_data->tile_cfg !=
+ io_cfg->planes[i].tile_config)
|| !wm_data->init_cfg_done) {
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->ubwc_regs->tile_cfg,
@@ -2262,7 +2354,22 @@
}
CAM_DBG(CAM_ISP, "tile cfg 0x%x", wm_data->tile_cfg);
- if (wm_data->h_init != io_cfg->planes[i].h_init ||
+ if (wm_data->is_dual) {
+ if ((wm_data->h_init != wm_data->offset) ||
+ !wm_data->init_cfg_done) {
+ /*
+ * For dual ife h init value need to take from
+ * offset.Striping config update offset value
+ */
+ CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair,
+ j,
+ wm_data->hw_regs->ubwc_regs->
+ h_init,
+ wm_data->offset);
+ wm_data->h_init = wm_data->offset;
+ }
+ } else if (wm_data->h_init !=
+ io_cfg->planes[i].h_init ||
!wm_data->init_cfg_done) {
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
wm_data->hw_regs->ubwc_regs->h_init,
@@ -2334,8 +2441,9 @@
io_cfg->planes[i].meta_size));
else
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
- wm_data->hw_regs->image_addr,
- update_buf->image_buf[i]);
+ wm_data->hw_regs->image_addr,
+ update_buf->image_buf[i] +
+ wm_data->offset);
CAM_DBG(CAM_ISP, "image address 0x%x", reg_val_pair[j-1]);
@@ -2475,6 +2583,50 @@
return 0;
}
+static int cam_vfe_bus_update_stripe_cfg(void *priv, void *cmd_args,
+ uint32_t arg_size)
+{
+ struct cam_vfe_bus_ver2_priv *bus_priv;
+ struct cam_isp_hw_dual_isp_update_args *stripe_args;
+ struct cam_vfe_bus_ver2_vfe_out_data *vfe_out_data = NULL;
+ struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
+ struct cam_isp_dual_stripe_config *stripe_config;
+ uint32_t outport_id, ports_plane_idx, i;
+
+ bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
+ stripe_args = (struct cam_isp_hw_dual_isp_update_args *)cmd_args;
+
+ vfe_out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
+ stripe_args->res->res_priv;
+
+ if (!vfe_out_data) {
+ CAM_ERR(CAM_ISP, "Failed! Invalid data");
+ return -EINVAL;
+ }
+
+ outport_id = stripe_args->res->res_id & 0xFF;
+ if (stripe_args->res->res_id < CAM_ISP_IFE_OUT_RES_BASE ||
+ stripe_args->res->res_id >= CAM_ISP_IFE_OUT_RES_MAX)
+ return 0;
+
+ ports_plane_idx = (stripe_args->split_id *
+ (stripe_args->dual_cfg->num_ports * CAM_PACKET_MAX_PLANES)) +
+ (outport_id * CAM_PACKET_MAX_PLANES);
+ for (i = 0; i < vfe_out_data->num_wm; i++) {
+ wm_data = vfe_out_data->wm_res[i]->res_priv;
+ stripe_config = (struct cam_isp_dual_stripe_config *)
+ &stripe_args->dual_cfg->stripes[ports_plane_idx + i];
+ wm_data->width = stripe_config->width;
+ wm_data->offset = stripe_config->offset;
+ wm_data->tile_cfg = stripe_config->tileconfig;
+ CAM_DBG(CAM_ISP, "id:%x wm:%d width:0x%x offset:%x tilecfg:%x",
+ stripe_args->res->res_id, i, wm_data->width,
+ wm_data->offset, wm_data->tile_cfg);
+ }
+
+ return 0;
+}
+
static int cam_vfe_bus_start_hw(void *hw_priv,
void *start_hw_args, uint32_t arg_size)
{
@@ -2515,6 +2667,21 @@
return -EFAULT;
}
+ /* BUS_WR_INPUT_IF_ADDR_SYNC_FRAME_HEADER */
+ cam_io_w_mb(0x0, bus_priv->common_data.mem_base +
+ bus_priv->common_data.common_reg->addr_sync_frame_hdr);
+
+ /* no clock gating at bus input */
+ cam_io_w_mb(0xFFFFF, bus_priv->common_data.mem_base + 0x0000200C);
+
+ /* BUS_WR_TEST_BUS_CTRL */
+ cam_io_w_mb(0x0, bus_priv->common_data.mem_base + 0x0000211C);
+
+ /* if addr_no_sync has default value then config the addr no sync reg */
+ cam_io_w_mb(CAM_VFE_BUS_ADDR_NO_SYNC_DEFAULT_VAL,
+ bus_priv->common_data.mem_base +
+ bus_priv->common_data.common_reg->addr_sync_no_sync);
+
return 0;
}
@@ -2565,6 +2732,9 @@
case CAM_VFE_HW_CMD_GET_SECURE_MODE:
rc = cam_vfe_bus_get_secure_mode(priv, cmd_args, arg_size);
break;
+ case CAM_VFE_HW_CMD_STRIPE_UPDATE:
+ rc = cam_vfe_bus_update_stripe_cfg(priv, cmd_args, arg_size);
+ break;
default:
CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
cmd_type);
@@ -2621,6 +2791,9 @@
bus_priv->common_data.hw_intf = hw_intf;
bus_priv->common_data.vfe_irq_controller = vfe_irq_controller;
bus_priv->common_data.common_reg = &ver2_hw_info->common_reg;
+ bus_priv->common_data.addr_no_sync =
+ CAM_VFE_BUS_ADDR_NO_SYNC_DEFAULT_VAL;
+
mutex_init(&bus_priv->common_data.bus_mutex);
rc = cam_irq_controller_init(drv_name, bus_priv->common_data.mem_base,