Merge "msm: camera: isp: Add support for BW limiter" into camera-kernel.lnx.5.0
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
80f937e481
@@ -8035,6 +8035,161 @@ static int cam_isp_blob_sensor_blanking_config(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cam_isp_blob_bw_limit_update(
|
||||||
|
uint32_t blob_type,
|
||||||
|
struct cam_isp_generic_blob_info *blob_info,
|
||||||
|
struct cam_isp_out_rsrc_bw_limiter_config *bw_limit_cfg,
|
||||||
|
struct cam_hw_prepare_update_args *prepare,
|
||||||
|
enum cam_isp_hw_type hw_type)
|
||||||
|
{
|
||||||
|
struct cam_isp_wm_bw_limiter_config *wm_bw_limit_cfg;
|
||||||
|
struct cam_kmd_buf_info *kmd_buf_info;
|
||||||
|
struct cam_ife_hw_mgr_ctx *ctx = NULL;
|
||||||
|
struct cam_isp_hw_mgr_res *isp_out_res;
|
||||||
|
uint32_t res_id_out, i;
|
||||||
|
uint32_t total_used_bytes = 0;
|
||||||
|
uint32_t kmd_buf_remain_size;
|
||||||
|
uint32_t *cmd_buf_addr;
|
||||||
|
uint32_t bytes_used = 0;
|
||||||
|
int num_ent, rc = 0;
|
||||||
|
|
||||||
|
ctx = prepare->ctxt_to_hw_map;
|
||||||
|
|
||||||
|
if ((prepare->num_hw_update_entries + 1) >=
|
||||||
|
prepare->max_hw_update_entries) {
|
||||||
|
CAM_ERR(CAM_ISP, "Insufficient HW entries: %d max: %d",
|
||||||
|
prepare->num_hw_update_entries,
|
||||||
|
prepare->max_hw_update_entries);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
kmd_buf_info = blob_info->kmd_buf_info;
|
||||||
|
for (i = 0; i < bw_limit_cfg->num_ports; i++) {
|
||||||
|
wm_bw_limit_cfg = &bw_limit_cfg->bw_limiter_config[i];
|
||||||
|
res_id_out = wm_bw_limit_cfg->res_type & 0xFF;
|
||||||
|
|
||||||
|
if ((hw_type == CAM_ISP_HW_TYPE_SFE) &&
|
||||||
|
!((wm_bw_limit_cfg->res_type >=
|
||||||
|
CAM_ISP_SFE_OUT_RES_BASE) &&
|
||||||
|
(wm_bw_limit_cfg->res_type <
|
||||||
|
CAM_ISP_SFE_OUT_RES_MAX)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((hw_type == CAM_ISP_HW_TYPE_VFE) &&
|
||||||
|
!((wm_bw_limit_cfg->res_type >=
|
||||||
|
CAM_ISP_IFE_OUT_RES_BASE) &&
|
||||||
|
(wm_bw_limit_cfg->res_type <
|
||||||
|
(CAM_ISP_IFE_OUT_RES_BASE + max_ife_out_res))))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "%s BW limit config idx: %d port: 0x%x enable: %d [0x%x:0x%x]",
|
||||||
|
(hw_type == CAM_ISP_HW_TYPE_SFE ? "SFE" : "VFE"),
|
||||||
|
i, wm_bw_limit_cfg->res_type,
|
||||||
|
wm_bw_limit_cfg->enable_limiter,
|
||||||
|
wm_bw_limit_cfg->counter_limit[0],
|
||||||
|
wm_bw_limit_cfg->counter_limit[1]);
|
||||||
|
|
||||||
|
if ((kmd_buf_info->used_bytes
|
||||||
|
+ total_used_bytes) < kmd_buf_info->size) {
|
||||||
|
kmd_buf_remain_size = kmd_buf_info->size -
|
||||||
|
(kmd_buf_info->used_bytes +
|
||||||
|
total_used_bytes);
|
||||||
|
} else {
|
||||||
|
CAM_ERR(CAM_ISP,
|
||||||
|
"No free kmd memory for base idx: %d",
|
||||||
|
blob_info->base_info->idx);
|
||||||
|
rc = -ENOMEM;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_buf_addr = kmd_buf_info->cpu_addr +
|
||||||
|
(kmd_buf_info->used_bytes / 4) +
|
||||||
|
(total_used_bytes / 4);
|
||||||
|
|
||||||
|
if (hw_type == CAM_ISP_HW_TYPE_SFE)
|
||||||
|
isp_out_res = &ctx->res_list_sfe_out[res_id_out];
|
||||||
|
else
|
||||||
|
isp_out_res = &ctx->res_list_ife_out[res_id_out];
|
||||||
|
|
||||||
|
rc = cam_isp_add_cmd_buf_update(
|
||||||
|
isp_out_res, blob_type,
|
||||||
|
CAM_ISP_HW_CMD_WM_BW_LIMIT_CONFIG,
|
||||||
|
blob_info->base_info->idx,
|
||||||
|
(void *)cmd_buf_addr,
|
||||||
|
kmd_buf_remain_size,
|
||||||
|
(void *)wm_bw_limit_cfg,
|
||||||
|
&bytes_used);
|
||||||
|
if (rc < 0) {
|
||||||
|
CAM_ERR(CAM_ISP,
|
||||||
|
"Failed to update %s BW limiter config for res:0x%x enable:%d [0x%x:0x%x] base_idx:%d bytes_used:%u rc:%d",
|
||||||
|
((hw_type == CAM_ISP_HW_TYPE_SFE) ?
|
||||||
|
"SFE" : "VFE"),
|
||||||
|
wm_bw_limit_cfg->res_type,
|
||||||
|
wm_bw_limit_cfg->enable_limiter,
|
||||||
|
wm_bw_limit_cfg->counter_limit[0],
|
||||||
|
wm_bw_limit_cfg->counter_limit[1],
|
||||||
|
blob_info->base_info->idx, bytes_used, rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_used_bytes += bytes_used;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (total_used_bytes) {
|
||||||
|
num_ent = prepare->num_hw_update_entries;
|
||||||
|
prepare->hw_update_entries[num_ent].handle =
|
||||||
|
kmd_buf_info->handle;
|
||||||
|
prepare->hw_update_entries[num_ent].len = total_used_bytes;
|
||||||
|
prepare->hw_update_entries[num_ent].offset =
|
||||||
|
kmd_buf_info->offset;
|
||||||
|
num_ent++;
|
||||||
|
kmd_buf_info->used_bytes += total_used_bytes;
|
||||||
|
kmd_buf_info->offset += total_used_bytes;
|
||||||
|
prepare->num_hw_update_entries = num_ent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int cam_isp_validate_bw_limiter_blob(
|
||||||
|
uint32_t blob_size,
|
||||||
|
struct cam_isp_out_rsrc_bw_limiter_config *bw_limit_config)
|
||||||
|
{
|
||||||
|
if ((bw_limit_config->num_ports > (max_ife_out_res +
|
||||||
|
g_ife_hw_mgr.isp_bus_caps.max_sfe_out_res_type)) ||
|
||||||
|
(bw_limit_config->num_ports == 0)) {
|
||||||
|
CAM_ERR(CAM_ISP,
|
||||||
|
"Invalid num_ports:%u in bw limit config",
|
||||||
|
bw_limit_config->num_ports);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for integer overflow */
|
||||||
|
if (bw_limit_config->num_ports != 1) {
|
||||||
|
if (sizeof(struct cam_isp_wm_bw_limiter_config) > ((UINT_MAX -
|
||||||
|
sizeof(struct cam_isp_out_rsrc_bw_limiter_config)) /
|
||||||
|
(bw_limit_config->num_ports - 1))) {
|
||||||
|
CAM_ERR(CAM_ISP,
|
||||||
|
"Max size exceeded in bw limit config num_ports:%u size per port:%lu",
|
||||||
|
bw_limit_config->num_ports,
|
||||||
|
sizeof(struct cam_isp_wm_bw_limiter_config));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blob_size < (sizeof(struct cam_isp_out_rsrc_bw_limiter_config) +
|
||||||
|
(bw_limit_config->num_ports - 1) *
|
||||||
|
sizeof(struct cam_isp_wm_bw_limiter_config))) {
|
||||||
|
CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu",
|
||||||
|
blob_size, sizeof(struct cam_isp_out_rsrc_bw_limiter_config)
|
||||||
|
+ (bw_limit_config->num_ports - 1) *
|
||||||
|
sizeof(struct cam_isp_wm_bw_limiter_config));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int cam_isp_packet_generic_blob_handler(void *user_data,
|
static int cam_isp_packet_generic_blob_handler(void *user_data,
|
||||||
uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data)
|
uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data)
|
||||||
{
|
{
|
||||||
@@ -8586,6 +8741,32 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
|
|||||||
CAM_ERR(CAM_ISP, "MUP Update Failed");
|
CAM_ERR(CAM_ISP, "MUP Update Failed");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CAM_ISP_GENERIC_BLOB_TYPE_BW_LIMITER_CFG: {
|
||||||
|
struct cam_isp_out_rsrc_bw_limiter_config *bw_limit_config;
|
||||||
|
|
||||||
|
if (blob_size <
|
||||||
|
sizeof(struct cam_isp_out_rsrc_bw_limiter_config)) {
|
||||||
|
CAM_ERR(CAM_ISP, "Invalid blob size %u",
|
||||||
|
blob_size,
|
||||||
|
sizeof(struct cam_isp_out_rsrc_bw_limiter_config));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bw_limit_config =
|
||||||
|
(struct cam_isp_out_rsrc_bw_limiter_config *)blob_data;
|
||||||
|
|
||||||
|
rc = cam_isp_validate_bw_limiter_blob(blob_size,
|
||||||
|
bw_limit_config);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
rc = cam_isp_blob_bw_limit_update(blob_type, blob_info,
|
||||||
|
bw_limit_config, prepare, CAM_ISP_HW_TYPE_VFE);
|
||||||
|
if (rc)
|
||||||
|
CAM_ERR(CAM_ISP,
|
||||||
|
"BW limit update failed for IFE rc: %d", rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type);
|
CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type);
|
||||||
break;
|
break;
|
||||||
@@ -8984,6 +9165,32 @@ static int cam_sfe_packet_generic_blob_handler(void *user_data,
|
|||||||
CAM_ERR(CAM_ISP, "SFE exp order update failed");
|
CAM_ERR(CAM_ISP, "SFE exp order update failed");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CAM_ISP_GENERIC_BLOB_TYPE_BW_LIMITER_CFG: {
|
||||||
|
struct cam_isp_out_rsrc_bw_limiter_config *bw_limit_config;
|
||||||
|
|
||||||
|
if (blob_size <
|
||||||
|
sizeof(struct cam_isp_out_rsrc_bw_limiter_config)) {
|
||||||
|
CAM_ERR(CAM_ISP, "Invalid blob size %u",
|
||||||
|
blob_size,
|
||||||
|
sizeof(struct cam_isp_out_rsrc_bw_limiter_config));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bw_limit_config =
|
||||||
|
(struct cam_isp_out_rsrc_bw_limiter_config *)blob_data;
|
||||||
|
|
||||||
|
rc = cam_isp_validate_bw_limiter_blob(blob_size,
|
||||||
|
bw_limit_config);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
rc = cam_isp_blob_bw_limit_update(blob_type, blob_info,
|
||||||
|
bw_limit_config, prepare, CAM_ISP_HW_TYPE_SFE);
|
||||||
|
if (rc)
|
||||||
|
CAM_ERR(CAM_ISP,
|
||||||
|
"BW limit update failed for SFE rc: %d", rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case CAM_ISP_GENERIC_BLOB_TYPE_HFR_CONFIG:
|
case CAM_ISP_GENERIC_BLOB_TYPE_HFR_CONFIG:
|
||||||
case CAM_ISP_GENERIC_BLOB_TYPE_CLOCK_CONFIG:
|
case CAM_ISP_GENERIC_BLOB_TYPE_CLOCK_CONFIG:
|
||||||
case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG:
|
case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG:
|
||||||
|
@@ -160,6 +160,7 @@ enum cam_isp_hw_cmd_type {
|
|||||||
CAM_ISP_HW_CMD_IFE_BUS_DEBUG_CFG,
|
CAM_ISP_HW_CMD_IFE_BUS_DEBUG_CFG,
|
||||||
CAM_ISP_HW_SFE_SYS_CACHE_WM_CONFIG,
|
CAM_ISP_HW_SFE_SYS_CACHE_WM_CONFIG,
|
||||||
CAM_ISP_HW_SFE_SYS_CACHE_RM_CONFIG,
|
CAM_ISP_HW_SFE_SYS_CACHE_RM_CONFIG,
|
||||||
|
CAM_ISP_HW_CMD_WM_BW_LIMIT_CONFIG,
|
||||||
CAM_ISP_HW_CMD_MAX,
|
CAM_ISP_HW_CMD_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -425,6 +425,7 @@ static struct cam_sfe_bus_wr_hw_info sfe680_bus_wr_hw_info = {
|
|||||||
.debug_status_1 = 0x00000A88,
|
.debug_status_1 = 0x00000A88,
|
||||||
.mmu_prefetch_cfg = 0x00000A60,
|
.mmu_prefetch_cfg = 0x00000A60,
|
||||||
.mmu_prefetch_max_offset = 0x00000A64,
|
.mmu_prefetch_max_offset = 0x00000A64,
|
||||||
|
.bw_limiter_addr = 0x00000A1C,
|
||||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_0,
|
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_0,
|
||||||
},
|
},
|
||||||
/* BUS Client 1 LCR */
|
/* BUS Client 1 LCR */
|
||||||
@@ -454,6 +455,7 @@ static struct cam_sfe_bus_wr_hw_info sfe680_bus_wr_hw_info = {
|
|||||||
.debug_status_1 = 0x00000B88,
|
.debug_status_1 = 0x00000B88,
|
||||||
.mmu_prefetch_cfg = 0x00000B60,
|
.mmu_prefetch_cfg = 0x00000B60,
|
||||||
.mmu_prefetch_max_offset = 0x00000B64,
|
.mmu_prefetch_max_offset = 0x00000B64,
|
||||||
|
.bw_limiter_addr = 0x00000B1C,
|
||||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_1,
|
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_1,
|
||||||
},
|
},
|
||||||
/* BUS Client 2 STATS_BE_0 */
|
/* BUS Client 2 STATS_BE_0 */
|
||||||
@@ -483,6 +485,7 @@ static struct cam_sfe_bus_wr_hw_info sfe680_bus_wr_hw_info = {
|
|||||||
.debug_status_1 = 0x00000C88,
|
.debug_status_1 = 0x00000C88,
|
||||||
.mmu_prefetch_cfg = 0x00000C60,
|
.mmu_prefetch_cfg = 0x00000C60,
|
||||||
.mmu_prefetch_max_offset = 0x00000C64,
|
.mmu_prefetch_max_offset = 0x00000C64,
|
||||||
|
.bw_limiter_addr = 0x00000C1C,
|
||||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_2,
|
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_2,
|
||||||
},
|
},
|
||||||
/* BUS Client 3 STATS_BHIST_0 */
|
/* BUS Client 3 STATS_BHIST_0 */
|
||||||
@@ -512,6 +515,7 @@ static struct cam_sfe_bus_wr_hw_info sfe680_bus_wr_hw_info = {
|
|||||||
.debug_status_1 = 0x00000D88,
|
.debug_status_1 = 0x00000D88,
|
||||||
.mmu_prefetch_cfg = 0x00000D60,
|
.mmu_prefetch_cfg = 0x00000D60,
|
||||||
.mmu_prefetch_max_offset = 0x00000D64,
|
.mmu_prefetch_max_offset = 0x00000D64,
|
||||||
|
.bw_limiter_addr = 0x00000D1C,
|
||||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_2,
|
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_2,
|
||||||
},
|
},
|
||||||
/* BUS Client 4 STATS_BE_1 */
|
/* BUS Client 4 STATS_BE_1 */
|
||||||
@@ -541,6 +545,7 @@ static struct cam_sfe_bus_wr_hw_info sfe680_bus_wr_hw_info = {
|
|||||||
.debug_status_1 = 0x00000E88,
|
.debug_status_1 = 0x00000E88,
|
||||||
.mmu_prefetch_cfg = 0x00000E60,
|
.mmu_prefetch_cfg = 0x00000E60,
|
||||||
.mmu_prefetch_max_offset = 0x00000E64,
|
.mmu_prefetch_max_offset = 0x00000E64,
|
||||||
|
.bw_limiter_addr = 0x00000E1C,
|
||||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_3,
|
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_3,
|
||||||
},
|
},
|
||||||
/* BUS Client 5 STATS_BHIST_1 */
|
/* BUS Client 5 STATS_BHIST_1 */
|
||||||
@@ -570,6 +575,7 @@ static struct cam_sfe_bus_wr_hw_info sfe680_bus_wr_hw_info = {
|
|||||||
.debug_status_1 = 0x00000F88,
|
.debug_status_1 = 0x00000F88,
|
||||||
.mmu_prefetch_cfg = 0x00000F60,
|
.mmu_prefetch_cfg = 0x00000F60,
|
||||||
.mmu_prefetch_max_offset = 0x00000F64,
|
.mmu_prefetch_max_offset = 0x00000F64,
|
||||||
|
.bw_limiter_addr = 0x00000F1C,
|
||||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_3,
|
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_3,
|
||||||
},
|
},
|
||||||
/* BUS Client 6 STATS_BE_2 */
|
/* BUS Client 6 STATS_BE_2 */
|
||||||
@@ -599,6 +605,7 @@ static struct cam_sfe_bus_wr_hw_info sfe680_bus_wr_hw_info = {
|
|||||||
.debug_status_1 = 0x00001088,
|
.debug_status_1 = 0x00001088,
|
||||||
.mmu_prefetch_cfg = 0x00001060,
|
.mmu_prefetch_cfg = 0x00001060,
|
||||||
.mmu_prefetch_max_offset = 0x00001064,
|
.mmu_prefetch_max_offset = 0x00001064,
|
||||||
|
.bw_limiter_addr = 0x0000101C,
|
||||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_4,
|
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_4,
|
||||||
},
|
},
|
||||||
/* BUS Client 7 STATS_BHIST_2 */
|
/* BUS Client 7 STATS_BHIST_2 */
|
||||||
@@ -628,6 +635,7 @@ static struct cam_sfe_bus_wr_hw_info sfe680_bus_wr_hw_info = {
|
|||||||
.debug_status_1 = 0x00001188,
|
.debug_status_1 = 0x00001188,
|
||||||
.mmu_prefetch_cfg = 0x00001160,
|
.mmu_prefetch_cfg = 0x00001160,
|
||||||
.mmu_prefetch_max_offset = 0x00001164,
|
.mmu_prefetch_max_offset = 0x00001164,
|
||||||
|
.bw_limiter_addr = 0x0000111C,
|
||||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_4,
|
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_4,
|
||||||
},
|
},
|
||||||
/* BUS Client 8 RDI0 */
|
/* BUS Client 8 RDI0 */
|
||||||
@@ -657,6 +665,7 @@ static struct cam_sfe_bus_wr_hw_info sfe680_bus_wr_hw_info = {
|
|||||||
.debug_status_1 = 0x00001288,
|
.debug_status_1 = 0x00001288,
|
||||||
.mmu_prefetch_cfg = 0x00001260,
|
.mmu_prefetch_cfg = 0x00001260,
|
||||||
.mmu_prefetch_max_offset = 0x00001264,
|
.mmu_prefetch_max_offset = 0x00001264,
|
||||||
|
.bw_limiter_addr = 0x0000121C,
|
||||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_5,
|
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_5,
|
||||||
},
|
},
|
||||||
/* BUS Client 9 RDI1 */
|
/* BUS Client 9 RDI1 */
|
||||||
@@ -686,6 +695,7 @@ static struct cam_sfe_bus_wr_hw_info sfe680_bus_wr_hw_info = {
|
|||||||
.debug_status_1 = 0x00001388,
|
.debug_status_1 = 0x00001388,
|
||||||
.mmu_prefetch_cfg = 0x00001360,
|
.mmu_prefetch_cfg = 0x00001360,
|
||||||
.mmu_prefetch_max_offset = 0x00001364,
|
.mmu_prefetch_max_offset = 0x00001364,
|
||||||
|
.bw_limiter_addr = 0x0000131C,
|
||||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_6,
|
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_6,
|
||||||
},
|
},
|
||||||
/* BUS Client 10 RDI2 */
|
/* BUS Client 10 RDI2 */
|
||||||
@@ -715,6 +725,7 @@ static struct cam_sfe_bus_wr_hw_info sfe680_bus_wr_hw_info = {
|
|||||||
.debug_status_1 = 0x00001488,
|
.debug_status_1 = 0x00001488,
|
||||||
.mmu_prefetch_cfg = 0x00001460,
|
.mmu_prefetch_cfg = 0x00001460,
|
||||||
.mmu_prefetch_max_offset = 0x00001464,
|
.mmu_prefetch_max_offset = 0x00001464,
|
||||||
|
.bw_limiter_addr = 0x0000141C,
|
||||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_7,
|
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_7,
|
||||||
},
|
},
|
||||||
/* BUS Client 11 RDI3 */
|
/* BUS Client 11 RDI3 */
|
||||||
@@ -744,6 +755,7 @@ static struct cam_sfe_bus_wr_hw_info sfe680_bus_wr_hw_info = {
|
|||||||
.debug_status_1 = 0x00001588,
|
.debug_status_1 = 0x00001588,
|
||||||
.mmu_prefetch_cfg = 0x00001560,
|
.mmu_prefetch_cfg = 0x00001560,
|
||||||
.mmu_prefetch_max_offset = 0x00001564,
|
.mmu_prefetch_max_offset = 0x00001564,
|
||||||
|
.bw_limiter_addr = 0x0000151C,
|
||||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_8,
|
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_8,
|
||||||
},
|
},
|
||||||
/* BUS Client 12 RDI4 */
|
/* BUS Client 12 RDI4 */
|
||||||
@@ -773,6 +785,7 @@ static struct cam_sfe_bus_wr_hw_info sfe680_bus_wr_hw_info = {
|
|||||||
.debug_status_1 = 0x00001688,
|
.debug_status_1 = 0x00001688,
|
||||||
.mmu_prefetch_cfg = 0x00001660,
|
.mmu_prefetch_cfg = 0x00001660,
|
||||||
.mmu_prefetch_max_offset = 0x00001664,
|
.mmu_prefetch_max_offset = 0x00001664,
|
||||||
|
.bw_limiter_addr = 0x0000161C,
|
||||||
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_9,
|
.comp_group = CAM_SFE_BUS_WR_COMP_GRP_9,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -980,10 +993,11 @@ static struct cam_sfe_bus_wr_hw_info sfe680_bus_wr_hw_info = {
|
|||||||
.error_description = "Meta Stride unalign"
|
.error_description = "Meta Stride unalign"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.num_comp_grp = 10,
|
.num_comp_grp = 10,
|
||||||
.comp_done_shift = 17,
|
.comp_done_shift = 17,
|
||||||
.line_done_cfg = 0x11,
|
.line_done_cfg = 0x11,
|
||||||
.top_irq_shift = 0x0,
|
.top_irq_shift = 0x0,
|
||||||
|
.max_bw_counter_limit = 0xFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct cam_irq_register_set sfe680_top_irq_reg_set[1] = {
|
static struct cam_irq_register_set sfe680_top_irq_reg_set[1] = {
|
||||||
|
@@ -335,6 +335,7 @@ int cam_sfe_process_cmd(void *hw_priv, uint32_t cmd_type,
|
|||||||
case CAM_ISP_HW_CMD_GET_SECURE_MODE:
|
case CAM_ISP_HW_CMD_GET_SECURE_MODE:
|
||||||
case CAM_ISP_HW_CMD_QUERY_BUS_CAP:
|
case CAM_ISP_HW_CMD_QUERY_BUS_CAP:
|
||||||
case CAM_ISP_HW_SFE_SYS_CACHE_WM_CONFIG:
|
case CAM_ISP_HW_SFE_SYS_CACHE_WM_CONFIG:
|
||||||
|
case CAM_ISP_HW_CMD_WM_BW_LIMIT_CONFIG:
|
||||||
rc = core_info->sfe_bus_wr->hw_ops.process_cmd(
|
rc = core_info->sfe_bus_wr->hw_ops.process_cmd(
|
||||||
core_info->sfe_bus_wr->bus_priv, cmd_type,
|
core_info->sfe_bus_wr->bus_priv, cmd_type,
|
||||||
cmd_args, arg_size);
|
cmd_args, arg_size);
|
||||||
|
@@ -89,6 +89,7 @@ struct cam_sfe_bus_wr_common_data {
|
|||||||
uint32_t addr_no_sync;
|
uint32_t addr_no_sync;
|
||||||
uint32_t comp_done_shift;
|
uint32_t comp_done_shift;
|
||||||
uint32_t line_done_cfg;
|
uint32_t line_done_cfg;
|
||||||
|
uint32_t max_bw_counter_limit;
|
||||||
bool err_irq_subscribe;
|
bool err_irq_subscribe;
|
||||||
cam_hw_mgr_event_cb_func event_cb;
|
cam_hw_mgr_event_cb_func event_cb;
|
||||||
|
|
||||||
@@ -2626,6 +2627,119 @@ static int cam_sfe_bus_wr_update_wm_config(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cam_sfe_bus_wr_update_bw_limiter(
|
||||||
|
void *priv, void *cmd_args, uint32_t arg_size)
|
||||||
|
{
|
||||||
|
struct cam_sfe_bus_wr_priv *bus_priv;
|
||||||
|
struct cam_isp_hw_get_cmd_update *wm_config_update;
|
||||||
|
struct cam_sfe_bus_wr_out_data *sfe_out_data = NULL;
|
||||||
|
struct cam_cdm_utils_ops *cdm_util_ops;
|
||||||
|
struct cam_sfe_bus_wr_wm_resource_data *wm_data = NULL;
|
||||||
|
struct cam_isp_wm_bw_limiter_config *wm_bw_limit_cfg = NULL;
|
||||||
|
uint32_t counter_limit = 0, reg_val = 0;
|
||||||
|
uint32_t *reg_val_pair, num_regval_pairs = 0;
|
||||||
|
uint32_t i, j, size = 0;
|
||||||
|
|
||||||
|
bus_priv = (struct cam_sfe_bus_wr_priv *) priv;
|
||||||
|
wm_config_update = (struct cam_isp_hw_get_cmd_update *) cmd_args;
|
||||||
|
wm_bw_limit_cfg = (struct cam_isp_wm_bw_limiter_config *)
|
||||||
|
wm_config_update->data;
|
||||||
|
|
||||||
|
sfe_out_data = (struct cam_sfe_bus_wr_out_data *)
|
||||||
|
wm_config_update->res->res_priv;
|
||||||
|
|
||||||
|
cdm_util_ops = sfe_out_data->cdm_util_ops;
|
||||||
|
|
||||||
|
if (!sfe_out_data || !cdm_util_ops) {
|
||||||
|
CAM_ERR(CAM_SFE,
|
||||||
|
"Failed invalid data out_data: %pK cdm_utils_ops: %pK",
|
||||||
|
sfe_out_data, cdm_util_ops);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg_val_pair = &sfe_out_data->common_data->io_buf_update[0];
|
||||||
|
for (i = 0, j = 0; i < sfe_out_data->num_wm; i++) {
|
||||||
|
if (j >= (MAX_REG_VAL_PAIR_SIZE - (MAX_BUF_UPDATE_REG_NUM * 2))) {
|
||||||
|
CAM_ERR(CAM_SFE,
|
||||||
|
"reg_val_pair %d exceeds the array limit %zu for WM idx %d",
|
||||||
|
j, MAX_REG_VAL_PAIR_SIZE, i);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Num WMs needs to match max planes */
|
||||||
|
if (i >= CAM_PACKET_MAX_PLANES) {
|
||||||
|
CAM_WARN(CAM_SFE,
|
||||||
|
"Num of WMs: %d exceeded max planes", i);
|
||||||
|
goto add_reg_pair;
|
||||||
|
}
|
||||||
|
|
||||||
|
wm_data = (struct cam_sfe_bus_wr_wm_resource_data *)
|
||||||
|
sfe_out_data->wm_res[i].res_priv;
|
||||||
|
if (!wm_data->hw_regs->bw_limiter_addr) {
|
||||||
|
CAM_ERR(CAM_SFE,
|
||||||
|
"WM: %d %s has no support for bw limiter",
|
||||||
|
wm_data->index, sfe_out_data->wm_res[i].res_name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
counter_limit = wm_bw_limit_cfg->counter_limit[i];
|
||||||
|
|
||||||
|
/* Validate max counter limit */
|
||||||
|
if (counter_limit >
|
||||||
|
wm_data->common_data->max_bw_counter_limit) {
|
||||||
|
CAM_WARN(CAM_SFE,
|
||||||
|
"Invalid counter limit: 0x%x capping to max: 0x%x",
|
||||||
|
wm_bw_limit_cfg->counter_limit[i],
|
||||||
|
wm_data->common_data->max_bw_counter_limit);
|
||||||
|
counter_limit = wm_data->common_data->max_bw_counter_limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wm_bw_limit_cfg->enable_limiter && counter_limit) {
|
||||||
|
reg_val = 1;
|
||||||
|
reg_val |= (counter_limit << 1);
|
||||||
|
} else {
|
||||||
|
reg_val = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAM_SFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||||
|
wm_data->hw_regs->bw_limiter_addr, reg_val);
|
||||||
|
CAM_DBG(CAM_SFE, "WM: %d %s bw_limter: 0x%x",
|
||||||
|
wm_data->index, sfe_out_data->wm_res[i].res_name,
|
||||||
|
reg_val_pair[j-1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
add_reg_pair:
|
||||||
|
|
||||||
|
num_regval_pairs = j / 2;
|
||||||
|
|
||||||
|
if (num_regval_pairs) {
|
||||||
|
size = cdm_util_ops->cdm_required_size_reg_random(
|
||||||
|
num_regval_pairs);
|
||||||
|
|
||||||
|
/* cdm util returns dwords, need to convert to bytes */
|
||||||
|
if ((size * 4) > wm_config_update->cmd.size) {
|
||||||
|
CAM_ERR(CAM_SFE,
|
||||||
|
"Failed! Buf size:%d insufficient, expected size:%d",
|
||||||
|
wm_config_update->cmd.size, size);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
cdm_util_ops->cdm_write_regrandom(
|
||||||
|
wm_config_update->cmd.cmd_buf_addr, num_regval_pairs,
|
||||||
|
reg_val_pair);
|
||||||
|
|
||||||
|
/* cdm util returns dwords, need to convert to bytes */
|
||||||
|
wm_config_update->cmd.used_bytes = size * 4;
|
||||||
|
} else {
|
||||||
|
CAM_DBG(CAM_SFE,
|
||||||
|
"No reg val pairs. num_wms: %u",
|
||||||
|
sfe_out_data->num_wm);
|
||||||
|
wm_config_update->cmd.used_bytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int cam_sfe_bus_wr_start_hw(void *hw_priv,
|
static int cam_sfe_bus_wr_start_hw(void *hw_priv,
|
||||||
void *start_hw_args, uint32_t arg_size)
|
void *start_hw_args, uint32_t arg_size)
|
||||||
{
|
{
|
||||||
@@ -2783,6 +2897,9 @@ static int cam_sfe_bus_wr_process_cmd(
|
|||||||
case CAM_ISP_HW_CMD_SET_SFE_DEBUG_CFG:
|
case CAM_ISP_HW_CMD_SET_SFE_DEBUG_CFG:
|
||||||
rc = cam_sfe_bus_wr_set_debug_cfg(priv, cmd_args);
|
rc = cam_sfe_bus_wr_set_debug_cfg(priv, cmd_args);
|
||||||
break;
|
break;
|
||||||
|
case CAM_ISP_HW_CMD_WM_BW_LIMIT_CONFIG:
|
||||||
|
rc = cam_sfe_bus_wr_update_bw_limiter(priv, cmd_args, arg_size);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
CAM_ERR_RATE_LIMIT(CAM_SFE, "Invalid HW command type:%d",
|
CAM_ERR_RATE_LIMIT(CAM_SFE, "Invalid HW command type:%d",
|
||||||
cmd_type);
|
cmd_type);
|
||||||
@@ -2832,21 +2949,22 @@ int cam_sfe_bus_wr_init(
|
|||||||
}
|
}
|
||||||
sfe_bus_local->bus_priv = bus_priv;
|
sfe_bus_local->bus_priv = bus_priv;
|
||||||
|
|
||||||
bus_priv->num_client = hw_info->num_client;
|
bus_priv->num_client = hw_info->num_client;
|
||||||
bus_priv->num_out = hw_info->num_out;
|
bus_priv->num_out = hw_info->num_out;
|
||||||
bus_priv->num_comp_grp = hw_info->num_comp_grp;
|
bus_priv->num_comp_grp = hw_info->num_comp_grp;
|
||||||
bus_priv->top_irq_shift = hw_info->top_irq_shift;
|
bus_priv->top_irq_shift = hw_info->top_irq_shift;
|
||||||
bus_priv->common_data.num_sec_out = 0;
|
bus_priv->common_data.num_sec_out = 0;
|
||||||
bus_priv->common_data.secure_mode = CAM_SECURE_MODE_NON_SECURE;
|
bus_priv->common_data.secure_mode = CAM_SECURE_MODE_NON_SECURE;
|
||||||
bus_priv->common_data.core_index = soc_info->index;
|
bus_priv->common_data.core_index = soc_info->index;
|
||||||
bus_priv->common_data.mem_base =
|
bus_priv->common_data.mem_base =
|
||||||
CAM_SOC_GET_REG_MAP_START(soc_info, SFE_CORE_BASE_IDX);
|
CAM_SOC_GET_REG_MAP_START(soc_info, SFE_CORE_BASE_IDX);
|
||||||
bus_priv->common_data.hw_intf = hw_intf;
|
bus_priv->common_data.hw_intf = hw_intf;
|
||||||
bus_priv->common_data.common_reg = &hw_info->common_reg;
|
bus_priv->common_data.common_reg = &hw_info->common_reg;
|
||||||
bus_priv->common_data.comp_done_shift = hw_info->comp_done_shift;
|
bus_priv->common_data.comp_done_shift = hw_info->comp_done_shift;
|
||||||
bus_priv->common_data.line_done_cfg = hw_info->line_done_cfg;
|
bus_priv->common_data.line_done_cfg = hw_info->line_done_cfg;
|
||||||
bus_priv->common_data.err_irq_subscribe = false;
|
bus_priv->common_data.max_bw_counter_limit = hw_info->max_bw_counter_limit;
|
||||||
bus_priv->common_data.sfe_irq_controller = sfe_irq_controller;
|
bus_priv->common_data.err_irq_subscribe = false;
|
||||||
|
bus_priv->common_data.sfe_irq_controller = sfe_irq_controller;
|
||||||
bus_priv->constraint_error_list = hw_info->constraint_error_list;
|
bus_priv->constraint_error_list = hw_info->constraint_error_list;
|
||||||
rc = cam_cpas_get_cpas_hw_version(&bus_priv->common_data.hw_version);
|
rc = cam_cpas_get_cpas_hw_version(&bus_priv->common_data.hw_version);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@@ -116,6 +116,7 @@ struct cam_sfe_bus_reg_offset_bus_client {
|
|||||||
uint32_t debug_status_1;
|
uint32_t debug_status_1;
|
||||||
uint32_t mmu_prefetch_cfg;
|
uint32_t mmu_prefetch_cfg;
|
||||||
uint32_t mmu_prefetch_max_offset;
|
uint32_t mmu_prefetch_max_offset;
|
||||||
|
uint32_t bw_limiter_addr;
|
||||||
uint32_t comp_group;
|
uint32_t comp_group;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -140,15 +141,16 @@ struct cam_sfe_bus_sfe_out_hw_info {
|
|||||||
*
|
*
|
||||||
* @Brief: HW register info for entire Bus
|
* @Brief: HW register info for entire Bus
|
||||||
*
|
*
|
||||||
* @common_reg: Common register details
|
* @common_reg: Common register details
|
||||||
* @num_client: Total number of write clients
|
* @num_client: Total number of write clients
|
||||||
* @bus_client_reg: Bus client register info
|
* @bus_client_reg: Bus client register info
|
||||||
* @sfe_out_hw_info: SFE output capability
|
* @sfe_out_hw_info: SFE output capability
|
||||||
* @constraint_error_list: Static list of all constraint errors
|
* @constraint_error_list: Static list of all constraint errors
|
||||||
* @num_comp_grp: Number of composite groups
|
* @num_comp_grp: Number of composite groups
|
||||||
* @comp_done_shift: Mask shift for comp done mask
|
* @comp_done_shift: Mask shift for comp done mask
|
||||||
* @line_done_cfg: Line done cfg for wr/rd sync
|
* @line_done_cfg: Line done cfg for wr/rd sync
|
||||||
* @top_irq_shift: Mask shift for top level BUS WR irq
|
* @top_irq_shift: Mask shift for top level BUS WR irq
|
||||||
|
* @max_bw_counter_limit: Max BW counter limit
|
||||||
*/
|
*/
|
||||||
struct cam_sfe_bus_wr_hw_info {
|
struct cam_sfe_bus_wr_hw_info {
|
||||||
struct cam_sfe_bus_reg_offset_common common_reg;
|
struct cam_sfe_bus_reg_offset_common common_reg;
|
||||||
@@ -164,6 +166,7 @@ struct cam_sfe_bus_wr_hw_info {
|
|||||||
uint32_t comp_done_shift;
|
uint32_t comp_done_shift;
|
||||||
uint32_t line_done_cfg;
|
uint32_t line_done_cfg;
|
||||||
uint32_t top_irq_shift;
|
uint32_t top_irq_shift;
|
||||||
|
uint32_t max_bw_counter_limit;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -532,6 +532,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,
|
|||||||
case CAM_ISP_HW_CMD_GET_RES_FOR_MID:
|
case CAM_ISP_HW_CMD_GET_RES_FOR_MID:
|
||||||
case CAM_ISP_HW_CMD_QUERY_BUS_CAP:
|
case CAM_ISP_HW_CMD_QUERY_BUS_CAP:
|
||||||
case CAM_ISP_HW_CMD_IFE_BUS_DEBUG_CFG:
|
case CAM_ISP_HW_CMD_IFE_BUS_DEBUG_CFG:
|
||||||
|
case CAM_ISP_HW_CMD_WM_BW_LIMIT_CONFIG:
|
||||||
rc = core_info->vfe_bus->hw_ops.process_cmd(
|
rc = core_info->vfe_bus->hw_ops.process_cmd(
|
||||||
core_info->vfe_bus->bus_priv, cmd_type, cmd_args,
|
core_info->vfe_bus->bus_priv, cmd_type, cmd_args,
|
||||||
arg_size);
|
arg_size);
|
||||||
|
@@ -676,6 +676,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00000E80,
|
.debug_status_cfg = 0x00000E80,
|
||||||
.debug_status_0 = 0x00000E84,
|
.debug_status_0 = 0x00000E84,
|
||||||
.debug_status_1 = 0x00000E88,
|
.debug_status_1 = 0x00000E88,
|
||||||
|
.bw_limiter_addr = 0x00000E1C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_0,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_0,
|
||||||
.ubwc_regs = &vfe680_ubwc_regs_client_0,
|
.ubwc_regs = &vfe680_ubwc_regs_client_0,
|
||||||
},
|
},
|
||||||
@@ -705,6 +706,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00000F80,
|
.debug_status_cfg = 0x00000F80,
|
||||||
.debug_status_0 = 0x00000F84,
|
.debug_status_0 = 0x00000F84,
|
||||||
.debug_status_1 = 0x00000F88,
|
.debug_status_1 = 0x00000F88,
|
||||||
|
.bw_limiter_addr = 0x00000F1C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_0,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_0,
|
||||||
.ubwc_regs = &vfe680_ubwc_regs_client_1,
|
.ubwc_regs = &vfe680_ubwc_regs_client_1,
|
||||||
},
|
},
|
||||||
@@ -731,6 +733,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00001080,
|
.debug_status_cfg = 0x00001080,
|
||||||
.debug_status_0 = 0x00001084,
|
.debug_status_0 = 0x00001084,
|
||||||
.debug_status_1 = 0x00001088,
|
.debug_status_1 = 0x00001088,
|
||||||
|
.bw_limiter_addr = 0x0000101C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_0,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_0,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -757,6 +760,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00001180,
|
.debug_status_cfg = 0x00001180,
|
||||||
.debug_status_0 = 0x00001184,
|
.debug_status_0 = 0x00001184,
|
||||||
.debug_status_1 = 0x00001188,
|
.debug_status_1 = 0x00001188,
|
||||||
|
.bw_limiter_addr = 0x0000111C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_0,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_0,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -786,6 +790,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00001280,
|
.debug_status_cfg = 0x00001280,
|
||||||
.debug_status_0 = 0x00001284,
|
.debug_status_0 = 0x00001284,
|
||||||
.debug_status_1 = 0x00001288,
|
.debug_status_1 = 0x00001288,
|
||||||
|
.bw_limiter_addr = 0x0000121C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_1,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_1,
|
||||||
.ubwc_regs = &vfe680_ubwc_regs_client_4,
|
.ubwc_regs = &vfe680_ubwc_regs_client_4,
|
||||||
},
|
},
|
||||||
@@ -815,6 +820,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00001380,
|
.debug_status_cfg = 0x00001380,
|
||||||
.debug_status_0 = 0x00001384,
|
.debug_status_0 = 0x00001384,
|
||||||
.debug_status_1 = 0x00001388,
|
.debug_status_1 = 0x00001388,
|
||||||
|
.bw_limiter_addr = 0x0000131C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_1,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_1,
|
||||||
.ubwc_regs = &vfe680_ubwc_regs_client_5,
|
.ubwc_regs = &vfe680_ubwc_regs_client_5,
|
||||||
},
|
},
|
||||||
@@ -841,6 +847,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00001480,
|
.debug_status_cfg = 0x00001480,
|
||||||
.debug_status_0 = 0x00001484,
|
.debug_status_0 = 0x00001484,
|
||||||
.debug_status_1 = 0x00001488,
|
.debug_status_1 = 0x00001488,
|
||||||
|
.bw_limiter_addr = 0x0000141C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_1,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_1,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -867,6 +874,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00001580,
|
.debug_status_cfg = 0x00001580,
|
||||||
.debug_status_0 = 0x00001584,
|
.debug_status_0 = 0x00001584,
|
||||||
.debug_status_1 = 0x00001588,
|
.debug_status_1 = 0x00001588,
|
||||||
|
.bw_limiter_addr = 0x0000151C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_1,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_1,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -896,6 +904,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00001680,
|
.debug_status_cfg = 0x00001680,
|
||||||
.debug_status_0 = 0x00001684,
|
.debug_status_0 = 0x00001684,
|
||||||
.debug_status_1 = 0x00001688,
|
.debug_status_1 = 0x00001688,
|
||||||
|
.bw_limiter_addr = 0x0000161C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_2,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_2,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -922,6 +931,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00001780,
|
.debug_status_cfg = 0x00001780,
|
||||||
.debug_status_0 = 0x00001784,
|
.debug_status_0 = 0x00001784,
|
||||||
.debug_status_1 = 0x00001788,
|
.debug_status_1 = 0x00001788,
|
||||||
|
.bw_limiter_addr = 0x0000171C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_2,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_2,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -951,6 +961,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00001880,
|
.debug_status_cfg = 0x00001880,
|
||||||
.debug_status_0 = 0x00001884,
|
.debug_status_0 = 0x00001884,
|
||||||
.debug_status_1 = 0x00001888,
|
.debug_status_1 = 0x00001888,
|
||||||
|
.bw_limiter_addr = 0x0000181C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_3,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_3,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -980,6 +991,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00001980,
|
.debug_status_cfg = 0x00001980,
|
||||||
.debug_status_0 = 0x00001984,
|
.debug_status_0 = 0x00001984,
|
||||||
.debug_status_1 = 0x00001988,
|
.debug_status_1 = 0x00001988,
|
||||||
|
.bw_limiter_addr = 0x0000191C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_4,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_4,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -1009,6 +1021,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00001A80,
|
.debug_status_cfg = 0x00001A80,
|
||||||
.debug_status_0 = 0x00001A84,
|
.debug_status_0 = 0x00001A84,
|
||||||
.debug_status_1 = 0x00001A88,
|
.debug_status_1 = 0x00001A88,
|
||||||
|
.bw_limiter_addr = 0x00001A1C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_4,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_4,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -1038,6 +1051,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00001B80,
|
.debug_status_cfg = 0x00001B80,
|
||||||
.debug_status_0 = 0x00001B84,
|
.debug_status_0 = 0x00001B84,
|
||||||
.debug_status_1 = 0x00001B88,
|
.debug_status_1 = 0x00001B88,
|
||||||
|
.bw_limiter_addr = 0x00001B1C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_5,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_5,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -1067,6 +1081,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00001C80,
|
.debug_status_cfg = 0x00001C80,
|
||||||
.debug_status_0 = 0x00001C84,
|
.debug_status_0 = 0x00001C84,
|
||||||
.debug_status_1 = 0x00001C88,
|
.debug_status_1 = 0x00001C88,
|
||||||
|
.bw_limiter_addr = 0x00001C1C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_6,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_6,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -1096,6 +1111,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00001D80,
|
.debug_status_cfg = 0x00001D80,
|
||||||
.debug_status_0 = 0x00001D84,
|
.debug_status_0 = 0x00001D84,
|
||||||
.debug_status_1 = 0x00001D88,
|
.debug_status_1 = 0x00001D88,
|
||||||
|
.bw_limiter_addr = 0x00001D1C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_6,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_6,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -1125,6 +1141,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00001E80,
|
.debug_status_cfg = 0x00001E80,
|
||||||
.debug_status_0 = 0x00001E84,
|
.debug_status_0 = 0x00001E84,
|
||||||
.debug_status_1 = 0x00001E88,
|
.debug_status_1 = 0x00001E88,
|
||||||
|
.bw_limiter_addr = 0x00001E1C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_7,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_7,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -1154,6 +1171,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00001F80,
|
.debug_status_cfg = 0x00001F80,
|
||||||
.debug_status_0 = 0x00001F84,
|
.debug_status_0 = 0x00001F84,
|
||||||
.debug_status_1 = 0x00001F88,
|
.debug_status_1 = 0x00001F88,
|
||||||
|
.bw_limiter_addr = 0x00001F1C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_8,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_8,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -1183,6 +1201,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00002080,
|
.debug_status_cfg = 0x00002080,
|
||||||
.debug_status_0 = 0x00002084,
|
.debug_status_0 = 0x00002084,
|
||||||
.debug_status_1 = 0x00002088,
|
.debug_status_1 = 0x00002088,
|
||||||
|
.bw_limiter_addr = 0x0000201C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_9,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_9,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -1212,6 +1231,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00002180,
|
.debug_status_cfg = 0x00002180,
|
||||||
.debug_status_0 = 0x00002184,
|
.debug_status_0 = 0x00002184,
|
||||||
.debug_status_1 = 0x00002188,
|
.debug_status_1 = 0x00002188,
|
||||||
|
.bw_limiter_addr = 0x0000211C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_10,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_10,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -1241,6 +1261,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00002280,
|
.debug_status_cfg = 0x00002280,
|
||||||
.debug_status_0 = 0x00002284,
|
.debug_status_0 = 0x00002284,
|
||||||
.debug_status_1 = 0x00002288,
|
.debug_status_1 = 0x00002288,
|
||||||
|
.bw_limiter_addr = 0x0000221C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_12,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_12,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -1270,6 +1291,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00002380,
|
.debug_status_cfg = 0x00002380,
|
||||||
.debug_status_0 = 0x00002384,
|
.debug_status_0 = 0x00002384,
|
||||||
.debug_status_1 = 0x00002388,
|
.debug_status_1 = 0x00002388,
|
||||||
|
.bw_limiter_addr = 0x0000231C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_13,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_13,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -1299,6 +1321,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00002480,
|
.debug_status_cfg = 0x00002480,
|
||||||
.debug_status_0 = 0x00002484,
|
.debug_status_0 = 0x00002484,
|
||||||
.debug_status_1 = 0x00002488,
|
.debug_status_1 = 0x00002488,
|
||||||
|
.bw_limiter_addr = 0x0000241C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_13,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_13,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -1328,6 +1351,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00002580,
|
.debug_status_cfg = 0x00002580,
|
||||||
.debug_status_0 = 0x00002584,
|
.debug_status_0 = 0x00002584,
|
||||||
.debug_status_1 = 0x00002588,
|
.debug_status_1 = 0x00002588,
|
||||||
|
.bw_limiter_addr = 0x0000251C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_11,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_11,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -1357,6 +1381,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00002680,
|
.debug_status_cfg = 0x00002680,
|
||||||
.debug_status_0 = 0x00002684,
|
.debug_status_0 = 0x00002684,
|
||||||
.debug_status_1 = 0x00002688,
|
.debug_status_1 = 0x00002688,
|
||||||
|
.bw_limiter_addr = 0x0000261C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_14,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_14,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -1386,6 +1411,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00002780,
|
.debug_status_cfg = 0x00002780,
|
||||||
.debug_status_0 = 0x00002784,
|
.debug_status_0 = 0x00002784,
|
||||||
.debug_status_1 = 0x00002788,
|
.debug_status_1 = 0x00002788,
|
||||||
|
.bw_limiter_addr = 0x0000271C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_15,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_15,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -1415,6 +1441,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00002880,
|
.debug_status_cfg = 0x00002880,
|
||||||
.debug_status_0 = 0x00002884,
|
.debug_status_0 = 0x00002884,
|
||||||
.debug_status_1 = 0x00002888,
|
.debug_status_1 = 0x00002888,
|
||||||
|
.bw_limiter_addr = 0x0000281C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_16,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_16,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -1444,6 +1471,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.debug_status_cfg = 0x00002980,
|
.debug_status_cfg = 0x00002980,
|
||||||
.debug_status_0 = 0x00002984,
|
.debug_status_0 = 0x00002984,
|
||||||
.debug_status_1 = 0x00002988,
|
.debug_status_1 = 0x00002988,
|
||||||
|
.bw_limiter_addr = 0x0000291C,
|
||||||
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_3,
|
.comp_group = CAM_VFE_BUS_VER3_COMP_GRP_3,
|
||||||
.ubwc_regs = NULL,
|
.ubwc_regs = NULL,
|
||||||
},
|
},
|
||||||
@@ -1909,12 +1937,13 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
|
|||||||
.error_description = "Meta Stride unalign"
|
.error_description = "Meta Stride unalign"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.num_comp_grp = 17,
|
.num_comp_grp = 17,
|
||||||
.support_consumed_addr = true,
|
.support_consumed_addr = true,
|
||||||
.comp_done_shift = 0,
|
.comp_done_shift = 0,
|
||||||
.top_irq_shift = 1,
|
.top_irq_shift = 1,
|
||||||
.max_out_res = CAM_ISP_IFE_OUT_RES_BASE + 33,
|
.max_out_res = CAM_ISP_IFE_OUT_RES_BASE + 33,
|
||||||
.pack_align_shift = 5,
|
.pack_align_shift = 5,
|
||||||
|
.max_bw_counter_limit = 0xFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct cam_vfe_irq_hw_info vfe680_irq_hw_info = {
|
static struct cam_vfe_irq_hw_info vfe680_irq_hw_info = {
|
||||||
|
@@ -104,6 +104,7 @@ struct cam_vfe_bus_ver3_common_data {
|
|||||||
cam_hw_mgr_event_cb_func event_cb;
|
cam_hw_mgr_event_cb_func event_cb;
|
||||||
int rup_irq_handle[CAM_VFE_BUS_VER3_SRC_GRP_MAX];
|
int rup_irq_handle[CAM_VFE_BUS_VER3_SRC_GRP_MAX];
|
||||||
uint32_t pack_align_shift;
|
uint32_t pack_align_shift;
|
||||||
|
uint32_t max_bw_counter_limit;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cam_vfe_bus_ver3_wm_resource_data {
|
struct cam_vfe_bus_ver3_wm_resource_data {
|
||||||
@@ -2948,7 +2949,11 @@ static int cam_vfe_bus_ver3_update_ubwc_regs(
|
|||||||
CAM_DBG(CAM_ISP, "WM:%d off_lossy_var 0x%X",
|
CAM_DBG(CAM_ISP, "WM:%d off_lossy_var 0x%X",
|
||||||
wm_data->index, reg_val_pair[*j-1]);
|
wm_data->index, reg_val_pair[*j-1]);
|
||||||
|
|
||||||
if (wm_data->ubwc_bandwidth_limit) {
|
/*
|
||||||
|
* If limit value >= 0xFFFF, limit configured by
|
||||||
|
* generic limiter blob
|
||||||
|
*/
|
||||||
|
if (wm_data->ubwc_bandwidth_limit < 0xFFFF) {
|
||||||
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, *j,
|
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, *j,
|
||||||
ubwc_regs->bw_limit, wm_data->ubwc_bandwidth_limit);
|
ubwc_regs->bw_limit, wm_data->ubwc_bandwidth_limit);
|
||||||
CAM_DBG(CAM_ISP, "WM:%d ubwc bw limit 0x%X",
|
CAM_DBG(CAM_ISP, "WM:%d ubwc bw limit 0x%X",
|
||||||
@@ -3540,6 +3545,120 @@ static int cam_vfe_bus_ver3_update_wm_config(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cam_vfe_bus_update_bw_limiter(
|
||||||
|
void *priv, void *cmd_args, uint32_t arg_size)
|
||||||
|
{
|
||||||
|
struct cam_vfe_bus_ver3_priv *bus_priv;
|
||||||
|
struct cam_isp_hw_get_cmd_update *wm_config_update;
|
||||||
|
struct cam_vfe_bus_ver3_vfe_out_data *vfe_out_data = NULL;
|
||||||
|
struct cam_cdm_utils_ops *cdm_util_ops;
|
||||||
|
struct cam_vfe_bus_ver3_wm_resource_data *wm_data = NULL;
|
||||||
|
struct cam_isp_wm_bw_limiter_config *wm_bw_limit_cfg = NULL;
|
||||||
|
uint32_t counter_limit = 0, reg_val = 0;
|
||||||
|
uint32_t *reg_val_pair, num_regval_pairs = 0;
|
||||||
|
uint32_t i, j, size = 0;
|
||||||
|
|
||||||
|
bus_priv = (struct cam_vfe_bus_ver3_priv *) priv;
|
||||||
|
wm_config_update = (struct cam_isp_hw_get_cmd_update *) cmd_args;
|
||||||
|
wm_bw_limit_cfg = (struct cam_isp_wm_bw_limiter_config *)
|
||||||
|
wm_config_update->data;
|
||||||
|
|
||||||
|
vfe_out_data = (struct cam_vfe_bus_ver3_vfe_out_data *)
|
||||||
|
wm_config_update->res->res_priv;
|
||||||
|
|
||||||
|
cdm_util_ops = vfe_out_data->cdm_util_ops;
|
||||||
|
|
||||||
|
if (!vfe_out_data || !cdm_util_ops) {
|
||||||
|
CAM_ERR(CAM_ISP,
|
||||||
|
"Failed invalid data out_data: %pK cdm_utils_ops: %pK",
|
||||||
|
vfe_out_data, cdm_util_ops);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg_val_pair = &vfe_out_data->common_data->io_buf_update[0];
|
||||||
|
for (i = 0, j = 0; i < vfe_out_data->num_wm; i++) {
|
||||||
|
if (j >= (MAX_REG_VAL_PAIR_SIZE - (MAX_BUF_UPDATE_REG_NUM * 2))) {
|
||||||
|
CAM_ERR(CAM_ISP,
|
||||||
|
"reg_val_pair %d exceeds the array limit %zu for WM idx %d",
|
||||||
|
j, MAX_REG_VAL_PAIR_SIZE, i);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Num WMs needs to match max planes */
|
||||||
|
if (i >= CAM_PACKET_MAX_PLANES) {
|
||||||
|
CAM_WARN(CAM_ISP,
|
||||||
|
"Num of WMs: %d exceeded max planes", i);
|
||||||
|
goto add_reg_pair;
|
||||||
|
}
|
||||||
|
|
||||||
|
wm_data = (struct cam_vfe_bus_ver3_wm_resource_data *)
|
||||||
|
vfe_out_data->wm_res[i].res_priv;
|
||||||
|
if (!wm_data->hw_regs->bw_limiter_addr) {
|
||||||
|
CAM_ERR(CAM_ISP,
|
||||||
|
"WM: %d %s has no support for bw limiter",
|
||||||
|
wm_data->index, vfe_out_data->wm_res[i].res_name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
counter_limit = wm_bw_limit_cfg->counter_limit[i];
|
||||||
|
|
||||||
|
/* Validate max counter limit */
|
||||||
|
if (counter_limit >
|
||||||
|
wm_data->common_data->max_bw_counter_limit) {
|
||||||
|
CAM_WARN(CAM_ISP,
|
||||||
|
"Invalid counter limit: 0x%x capping to max: 0x%x",
|
||||||
|
wm_bw_limit_cfg->counter_limit[i],
|
||||||
|
wm_data->common_data->max_bw_counter_limit);
|
||||||
|
counter_limit =
|
||||||
|
wm_data->common_data->max_bw_counter_limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wm_bw_limit_cfg->enable_limiter && counter_limit) {
|
||||||
|
reg_val = 1;
|
||||||
|
reg_val |= (counter_limit << 1);
|
||||||
|
} else {
|
||||||
|
reg_val = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||||
|
wm_data->hw_regs->bw_limiter_addr, reg_val);
|
||||||
|
CAM_DBG(CAM_ISP, "WM: %d for %s bw_limter: 0x%x",
|
||||||
|
wm_data->index, vfe_out_data->wm_res[i].res_name,
|
||||||
|
reg_val_pair[j-1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
add_reg_pair:
|
||||||
|
|
||||||
|
num_regval_pairs = j / 2;
|
||||||
|
|
||||||
|
if (num_regval_pairs) {
|
||||||
|
size = cdm_util_ops->cdm_required_size_reg_random(
|
||||||
|
num_regval_pairs);
|
||||||
|
|
||||||
|
/* cdm util returns dwords, need to convert to bytes */
|
||||||
|
if ((size * 4) > wm_config_update->cmd.size) {
|
||||||
|
CAM_ERR(CAM_ISP,
|
||||||
|
"Failed! Buf size:%d insufficient, expected size:%d",
|
||||||
|
wm_config_update->cmd.size, size);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
cdm_util_ops->cdm_write_regrandom(
|
||||||
|
wm_config_update->cmd.cmd_buf_addr, num_regval_pairs,
|
||||||
|
reg_val_pair);
|
||||||
|
|
||||||
|
/* cdm util returns dwords, need to convert to bytes */
|
||||||
|
wm_config_update->cmd.used_bytes = size * 4;
|
||||||
|
} else {
|
||||||
|
CAM_DBG(CAM_ISP,
|
||||||
|
"No reg val pairs. num_wms: %u",
|
||||||
|
vfe_out_data->num_wm);
|
||||||
|
wm_config_update->cmd.used_bytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int cam_vfe_bus_ver3_start_hw(void *hw_priv,
|
static int cam_vfe_bus_ver3_start_hw(void *hw_priv,
|
||||||
void *start_hw_args, uint32_t arg_size)
|
void *start_hw_args, uint32_t arg_size)
|
||||||
{
|
{
|
||||||
@@ -3739,6 +3858,9 @@ static int cam_vfe_bus_ver3_process_cmd(
|
|||||||
"disabled" : "enabled");
|
"disabled" : "enabled");
|
||||||
rc = 0;
|
rc = 0;
|
||||||
break;
|
break;
|
||||||
|
case CAM_ISP_HW_CMD_WM_BW_LIMIT_CONFIG:
|
||||||
|
rc = cam_vfe_bus_update_bw_limiter(priv, cmd_args, arg_size);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
|
CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
|
||||||
cmd_type);
|
cmd_type);
|
||||||
@@ -3823,6 +3945,8 @@ int cam_vfe_bus_ver3_init(
|
|||||||
bus_priv->common_data.disable_mmu_prefetch = false;
|
bus_priv->common_data.disable_mmu_prefetch = false;
|
||||||
bus_priv->common_data.pack_align_shift =
|
bus_priv->common_data.pack_align_shift =
|
||||||
ver3_hw_info->pack_align_shift;
|
ver3_hw_info->pack_align_shift;
|
||||||
|
bus_priv->common_data.max_bw_counter_limit =
|
||||||
|
ver3_hw_info->max_bw_counter_limit;
|
||||||
bus_priv->constraint_error_list = ver3_hw_info->constraint_error_list;
|
bus_priv->constraint_error_list = ver3_hw_info->constraint_error_list;
|
||||||
|
|
||||||
if (bus_priv->num_out >= CAM_VFE_BUS_VER3_VFE_OUT_MAX) {
|
if (bus_priv->num_out >= CAM_VFE_BUS_VER3_VFE_OUT_MAX) {
|
||||||
|
@@ -174,6 +174,7 @@ struct cam_vfe_bus_ver3_reg_offset_bus_client {
|
|||||||
uint32_t debug_status_cfg;
|
uint32_t debug_status_cfg;
|
||||||
uint32_t debug_status_0;
|
uint32_t debug_status_0;
|
||||||
uint32_t debug_status_1;
|
uint32_t debug_status_1;
|
||||||
|
uint32_t bw_limiter_addr;
|
||||||
uint32_t comp_group;
|
uint32_t comp_group;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -212,6 +213,7 @@ struct cam_vfe_bus_ver3_vfe_out_hw_info {
|
|||||||
* @supported_irq: Mask to indicate the IRQ supported
|
* @supported_irq: Mask to indicate the IRQ supported
|
||||||
* @comp_cfg_needed: Composite group config is needed for hw
|
* @comp_cfg_needed: Composite group config is needed for hw
|
||||||
* @pack_align_shift: Shift value for alignment of packer format
|
* @pack_align_shift: Shift value for alignment of packer format
|
||||||
|
* @max_bw_counter_limit: Max BW counter limit
|
||||||
*/
|
*/
|
||||||
struct cam_vfe_bus_ver3_hw_info {
|
struct cam_vfe_bus_ver3_hw_info {
|
||||||
struct cam_vfe_bus_ver3_reg_offset_common common_reg;
|
struct cam_vfe_bus_ver3_reg_offset_common common_reg;
|
||||||
@@ -231,6 +233,7 @@ struct cam_vfe_bus_ver3_hw_info {
|
|||||||
uint32_t supported_irq;
|
uint32_t supported_irq;
|
||||||
bool comp_cfg_needed;
|
bool comp_cfg_needed;
|
||||||
uint32_t pack_align_shift;
|
uint32_t pack_align_shift;
|
||||||
|
uint32_t max_bw_counter_limit;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -333,6 +333,10 @@ struct cam_ubwc_plane_cfg_v1 {
|
|||||||
* @lossy_threshold0 UBWC lossy threshold 0
|
* @lossy_threshold0 UBWC lossy threshold 0
|
||||||
* @lossy_threshold1 UBWC lossy threshold 1
|
* @lossy_threshold1 UBWC lossy threshold 1
|
||||||
* @lossy_var_offset UBWC offset variance thrshold
|
* @lossy_var_offset UBWC offset variance thrshold
|
||||||
|
* @bandwidth_limit: BW counter limit
|
||||||
|
* BW limiter config skipped if value is 0xFFFF or more
|
||||||
|
* If skipped here, use generic BW limiter blob to
|
||||||
|
* configure the appropriate value.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct cam_ubwc_plane_cfg_v2 {
|
struct cam_ubwc_plane_cfg_v2 {
|
||||||
|
@@ -121,6 +121,7 @@
|
|||||||
#define CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_BLANKING_CONFIG 13
|
#define CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_BLANKING_CONFIG 13
|
||||||
#define CAM_ISP_GENERIC_BLOB_TYPE_TPG_CORE_CONFIG 14
|
#define CAM_ISP_GENERIC_BLOB_TYPE_TPG_CORE_CONFIG 14
|
||||||
#define CAM_ISP_GENERIC_BLOB_TYPE_DYNAMIC_MODE_SWITCH 15
|
#define CAM_ISP_GENERIC_BLOB_TYPE_DYNAMIC_MODE_SWITCH 15
|
||||||
|
#define CAM_ISP_GENERIC_BLOB_TYPE_BW_LIMITER_CFG 16
|
||||||
#define CAM_ISP_GENERIC_BLOB_TYPE_SFE_CLOCK_CONFIG 21
|
#define CAM_ISP_GENERIC_BLOB_TYPE_SFE_CLOCK_CONFIG 21
|
||||||
#define CAM_ISP_GENERIC_BLOB_TYPE_SFE_CORE_CONFIG 22
|
#define CAM_ISP_GENERIC_BLOB_TYPE_SFE_CORE_CONFIG 22
|
||||||
#define CAM_ISP_GENERIC_BLOB_TYPE_SFE_OUT_CONFIG 23
|
#define CAM_ISP_GENERIC_BLOB_TYPE_SFE_OUT_CONFIG 23
|
||||||
@@ -932,6 +933,39 @@ struct cam_isp_discard_initial_frames {
|
|||||||
__u32 discard_params[5];
|
__u32 discard_params[5];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct cam_isp_wm_bw_limiter_config - ISP write master
|
||||||
|
* BW limter config
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @res_type : output resource type defined in file
|
||||||
|
* cam_isp_sfe.h or cam_isp_ife.h
|
||||||
|
* @enable_limiter : 0 for disable else enabled
|
||||||
|
* @counter_limit : Max counter value
|
||||||
|
* @additional_params : Params for future use
|
||||||
|
*/
|
||||||
|
struct cam_isp_wm_bw_limiter_config {
|
||||||
|
__u32 res_type;
|
||||||
|
__u32 enable_limiter;
|
||||||
|
__u32 counter_limit[CAM_PACKET_MAX_PLANES];
|
||||||
|
__u32 additional_params[5];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct cam_isp_out_rsrc_bw_limiter_config - ISP out rsrc BW limiter config
|
||||||
|
*
|
||||||
|
* Configure BW limiter for ISP WMs
|
||||||
|
*
|
||||||
|
* @num_ports : Number of ports
|
||||||
|
* @reserved : Reserved field
|
||||||
|
* @bw_limit_config : WM BW limiter config
|
||||||
|
*/
|
||||||
|
struct cam_isp_out_rsrc_bw_limiter_config {
|
||||||
|
__u32 num_ports;
|
||||||
|
__u32 reserved;
|
||||||
|
struct cam_isp_wm_bw_limiter_config bw_limiter_config[1];
|
||||||
|
};
|
||||||
|
|
||||||
#define CAM_ISP_ACQUIRE_COMMON_VER0 0x1000
|
#define CAM_ISP_ACQUIRE_COMMON_VER0 0x1000
|
||||||
|
|
||||||
#define CAM_ISP_ACQUIRE_COMMON_SIZE_VER0 0x0
|
#define CAM_ISP_ACQUIRE_COMMON_SIZE_VER0 0x0
|
||||||
|
Reference in New Issue
Block a user