Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +153 −5 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ (CAM_ISP_PACKET_META_GENERIC_BLOB_COMMON + 1) #define CAM_ISP_GENERIC_BLOB_TYPE_MAX \ (CAM_ISP_GENERIC_BLOB_TYPE_IFE_CORE_CONFIG + 1) (CAM_ISP_GENERIC_BLOB_TYPE_VFE_OUT_CONFIG + 1) static uint32_t blob_type_hw_cmd_map[CAM_ISP_GENERIC_BLOB_TYPE_MAX] = { CAM_ISP_HW_CMD_GET_HFR_UPDATE, Loading @@ -46,6 +46,8 @@ static uint32_t blob_type_hw_cmd_map[CAM_ISP_GENERIC_BLOB_TYPE_MAX] = { CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE, CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG, CAM_ISP_HW_CMD_UBWC_UPDATE_V2, CAM_ISP_HW_CMD_CORE_CONFIG, CAM_ISP_HW_CMD_WM_CONFIG_UPDATE, }; static struct cam_ife_hw_mgr g_ife_hw_mgr; Loading Loading @@ -4171,6 +4173,100 @@ static int cam_isp_blob_clock_update( return rc; } static int cam_isp_blob_vfe_out_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_isp_vfe_out_config *vfe_out_config, struct cam_hw_prepare_update_args *prepare) { struct cam_isp_vfe_wm_config *wm_config; struct cam_kmd_buf_info *kmd_buf_info; struct cam_ife_hw_mgr_ctx *ctx = NULL; struct cam_ife_hw_mgr_res *ife_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 %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 < vfe_out_config->num_ports; i++) { wm_config = &vfe_out_config->wm_config[i]; res_id_out = wm_config->port_type & 0xFF; CAM_DBG(CAM_ISP, "VFE out config idx: %d port: 0x%x", i, wm_config->port_type); if (res_id_out >= CAM_IFE_HW_OUT_RES_MAX) { CAM_ERR(CAM_ISP, "Invalid out port:0x%x", wm_config->port_type); return -EINVAL; } 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); ife_out_res = &ctx->res_list_ife_out[res_id_out]; rc = cam_isp_add_cmd_buf_update( ife_out_res, blob_type, blob_type_hw_cmd_map[blob_type], blob_info->base_info->idx, (void *)cmd_buf_addr, kmd_buf_remain_size, (void *)wm_config, &bytes_used); if (rc < 0) { CAM_ERR(CAM_ISP, "Failed to update VFE out base_idx: %d rc: %d", blob_info->base_info->idx, bytes_used); 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 int cam_isp_packet_generic_blob_handler(void *user_data, uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data) { Loading @@ -4197,7 +4293,6 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, return -EINVAL; } CAM_DBG(CAM_ISP, "FS2: BLOB Type: %d", blob_type); switch (blob_type) { case CAM_ISP_GENERIC_BLOB_TYPE_HFR_CONFIG: { struct cam_isp_resource_hfr_config *hfr_config; Loading Loading @@ -4402,8 +4497,15 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, } break; case CAM_ISP_GENERIC_BLOB_TYPE_IFE_CORE_CONFIG: { struct cam_isp_core_config *core_config = (struct cam_isp_core_config *)blob_data; struct cam_isp_core_config *core_config; if (blob_size < sizeof(struct cam_isp_core_config)) { CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu", blob_size, sizeof(struct cam_isp_core_config)); return -EINVAL; } core_config = (struct cam_isp_core_config *)blob_data; rc = cam_isp_blob_core_cfg_update(blob_type, blob_info, core_config, prepare); Loading @@ -4411,6 +4513,52 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, CAM_ERR(CAM_ISP, "Core cfg update fail: %d", rc); } break; case CAM_ISP_GENERIC_BLOB_TYPE_VFE_OUT_CONFIG: { struct cam_isp_vfe_out_config *vfe_out_config; if (blob_size < sizeof(struct cam_isp_vfe_out_config)) { CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size, sizeof(struct cam_isp_vfe_out_config)); return -EINVAL; } vfe_out_config = (struct cam_isp_vfe_out_config *)blob_data; if (vfe_out_config->num_ports >= CAM_IFE_HW_OUT_RES_MAX) { CAM_ERR(CAM_ISP, "num_ports %u exceeds max ports %u", vfe_out_config->num_ports, CAM_IFE_HW_OUT_RES_MAX); return -EINVAL; } /* Check for integer overflow */ if (sizeof(struct cam_isp_vfe_wm_config) > ((UINT_MAX - sizeof(struct cam_isp_vfe_out_config)) / (vfe_out_config->num_ports - 1))) { CAM_ERR(CAM_ISP, "Size exceeds limit ports:%u size per port:%lu", vfe_out_config->num_ports - 1, sizeof(struct cam_isp_vfe_wm_config)); return -EINVAL; } if (blob_size < (sizeof(struct cam_isp_vfe_out_config) + (vfe_out_config->num_ports - 1) * sizeof(struct cam_isp_vfe_wm_config))) { CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu", blob_size, sizeof(uint32_t) * 2 + vfe_out_config->num_ports * sizeof(struct cam_isp_vfe_wm_config)); return -EINVAL; } rc = cam_isp_blob_vfe_out_update(blob_type, blob_info, vfe_out_config, prepare); if (rc) CAM_ERR(CAM_ISP, "VFE out update failed rc: %d", rc); } break; default: CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type); Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +2 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD, CAM_ISP_HW_CMD_UBWC_UPDATE_V2, CAM_ISP_HW_CMD_CORE_CONFIG, CAM_ISP_HW_CMD_WM_CONFIG_UPDATE, CAM_ISP_HW_CMD_MAX, }; Loading Loading @@ -227,6 +228,7 @@ struct cam_isp_hw_get_cmd_update { struct cam_ubwc_plane_cfg_v1 *ubwc_update; struct cam_fe_config *fe_update; struct cam_vfe_generic_ubwc_config *ubwc_config; struct cam_isp_vfe_wm_config *wm_config; }; }; Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c +1 −0 Original line number Diff line number Diff line Loading @@ -592,6 +592,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_STOP_BUS_ERR_IRQ: case CAM_ISP_HW_CMD_UBWC_UPDATE: case CAM_ISP_HW_CMD_UBWC_UPDATE_V2: case CAM_ISP_HW_CMD_WM_CONFIG_UPDATE: rc = core_info->vfe_bus->hw_ops.process_cmd( core_info->vfe_bus->bus_priv, cmd_type, cmd_args, arg_size); Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c +90 −29 Original line number Diff line number Diff line Loading @@ -1230,9 +1230,6 @@ static int cam_vfe_bus_ver3_acquire_wm( rsrc_data->en_cfg = 0x1; } else if (rsrc_data->index == 20) { /* WM 20 stats BAF */ rsrc_data->width = 0; rsrc_data->height = 0; rsrc_data->stride = 1; rsrc_data->en_cfg = (0x1 << 16) | 0x1; } else if (rsrc_data->index > 11 && rsrc_data->index < 20) { /* WM 12-19 stats */ Loading Loading @@ -2725,16 +2722,6 @@ static int cam_vfe_bus_ver3_update_ubwc_regs( CAM_DBG(CAM_ISP, "WM:%d packer cfg 0x%x", wm_data->index, reg_val_pair[*j-1]); if (wm_data->is_dual) { CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, *j, wm_data->hw_regs->image_cfg_1, wm_data->offset); } else { CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, *j, wm_data->hw_regs->image_cfg_1, wm_data->h_init); CAM_DBG(CAM_ISP, "WM:%d h_init 0x%x", wm_data->index, reg_val_pair[*j-1]); } CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, *j, ubwc_regs->meta_cfg, wm_data->ubwc_meta_cfg); CAM_DBG(CAM_ISP, "WM:%d meta stride 0x%x", Loading Loading @@ -2821,12 +2808,13 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args, wm_data = vfe_out_data->wm_res[i]->res_priv; ubwc_client = wm_data->hw_regs->ubwc_regs; /* update width register */ val = cam_io_r_mb(wm_data->common_data->mem_base + wm_data->hw_regs->image_cfg_0); /* mask previously written width but preserve height */ val = val & 0xFFFF0000; val |= wm_data->width; CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j, wm_data->hw_regs->cfg, wm_data->en_cfg); CAM_DBG(CAM_ISP, "WM:%d en_cfg 0x%x", wm_data->index, reg_val_pair[j-1]); val = (wm_data->height << 16) | wm_data->width; CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j, wm_data->hw_regs->image_cfg_0, val); CAM_DBG(CAM_ISP, "WM:%d image height and width 0x%x", Loading @@ -2849,7 +2837,7 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args, wm_data->hw_regs->image_cfg_2, io_cfg->planes[i].plane_stride); wm_data->stride = val; CAM_DBG(CAM_ISP, "WM %d image stride 0x%x", CAM_DBG(CAM_ISP, "WM:%d image stride 0x%x", wm_data->index, reg_val_pair[j-1]); } Loading @@ -2870,7 +2858,7 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args, reg_val_pair, &j, wm_data->hw_regs->ubwc_regs, update_buf->wm_update->image_buf[i]); CAM_DBG(CAM_ISP, "WM %d ubwc meta addr 0x%llx", CAM_DBG(CAM_ISP, "WM:%d ubwc meta addr 0x%llx", wm_data->index, update_buf->wm_update->image_buf[i]); } Loading @@ -2880,7 +2868,7 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args, io_cfg->planes[i].slice_height, 4096); frame_inc += io_cfg->planes[i].meta_size; CAM_DBG(CAM_ISP, "WM %d frm %d: ht: %d stride %d meta: %d", "WM:%d frm %d: ht: %d stride %d meta: %d", wm_data->index, frame_inc, io_cfg->planes[i].slice_height, io_cfg->planes[i].plane_stride, Loading @@ -2890,6 +2878,13 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args, io_cfg->planes[i].slice_height; } if (!(wm_data->en_cfg & (0x3 << 16))) { CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j, wm_data->hw_regs->image_cfg_1, wm_data->h_init); CAM_DBG(CAM_ISP, "WM:%d h_init 0x%x", wm_data->index, reg_val_pair[j-1]); } if ((!bus_priv->common_data.is_lite && wm_data->index > 22) || bus_priv->common_data.is_lite) loop_size = wm_data->irq_subsample_period + 1; Loading @@ -2904,18 +2899,24 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args, update_buf->wm_update->image_buf[i] + io_cfg->planes[i].meta_size + k * frame_inc); else if (wm_data->en_cfg & (0x3 << 16)) CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j, wm_data->hw_regs->image_addr, (update_buf->wm_update->image_buf[i] + wm_data->offset + k * frame_inc)); else CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j, wm_data->hw_regs->image_addr, update_buf->wm_update->image_buf[i] + wm_data->offset + k * frame_inc); CAM_DBG(CAM_ISP, "WM %d image address 0x%x", (update_buf->wm_update->image_buf[i] + k * frame_inc)); CAM_DBG(CAM_ISP, "WM:%d image address 0x%x", wm_data->index, reg_val_pair[j-1]); } CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j, wm_data->hw_regs->frame_incr, frame_inc); CAM_DBG(CAM_ISP, "WM %d frame_inc %d", CAM_DBG(CAM_ISP, "WM:%d frame_inc %d", wm_data->index, reg_val_pair[j-1]); Loading Loading @@ -3219,10 +3220,67 @@ static int cam_vfe_bus_ver3_update_stripe_cfg(void *priv, void *cmd_args, stripe_config = (struct cam_isp_dual_stripe_config *) &stripe_args->dual_cfg->stripes[ports_plane_idx + i]; wm_data->width = stripe_config->width; /* * UMD sends buffer offset address as offset for clients * programmed to operate in frame/index based mode and h_init * value as offset for clients programmed to operate in line * based mode. */ if (wm_data->en_cfg & (0x3 << 16)) wm_data->offset = stripe_config->offset; CAM_DBG(CAM_ISP, "id:%x WM:%d width:0x%x offset:%x", else wm_data->h_init = stripe_config->offset; CAM_DBG(CAM_ISP, "id:%x WM:%d width:%d offset:0x%x h_init:%d", stripe_args->res->res_id, wm_data->index, wm_data->width, wm_data->offset); wm_data->width, wm_data->offset, wm_data->h_init); } return 0; } static int cam_vfe_bus_ver3_update_wm_config( void *cmd_args) { int i; struct cam_isp_hw_get_cmd_update *wm_config_update; struct cam_vfe_bus_ver3_vfe_out_data *vfe_out_data = NULL; struct cam_vfe_bus_ver3_wm_resource_data *wm_data = NULL; struct cam_isp_vfe_wm_config *wm_config = NULL; if (!cmd_args) { CAM_ERR(CAM_ISP, "Invalid args"); return -EINVAL; } wm_config_update = cmd_args; vfe_out_data = wm_config_update->res->res_priv; wm_config = wm_config_update->wm_config; if (!vfe_out_data || !vfe_out_data->cdm_util_ops || !wm_config) { CAM_ERR(CAM_ISP, "Invalid data"); return -EINVAL; } for (i = 0; i < vfe_out_data->num_wm; i++) { wm_data = vfe_out_data->wm_res[i]->res_priv; if (wm_config->wm_mode > 0x2) { CAM_ERR(CAM_ISP, "Invalid wm_mode: 0x%x", wm_config->wm_mode); return -EINVAL; } wm_data->en_cfg = (wm_config->wm_mode << 16) | 0x1; wm_data->height = wm_config->height; wm_data->width = wm_config->width; CAM_DBG(CAM_ISP, "WM:%d en_cfg:0x%x height:%d width:%d", wm_data->index, wm_data->en_cfg, wm_data->height, wm_data->width); } return 0; Loading Loading @@ -3379,6 +3437,9 @@ static int cam_vfe_bus_ver3_process_cmd( case CAM_ISP_HW_CMD_UBWC_UPDATE_V2: rc = cam_vfe_bus_ver3_update_ubwc_config_v2(cmd_args); break; case CAM_ISP_HW_CMD_WM_CONFIG_UPDATE: rc = cam_vfe_bus_ver3_update_wm_config(cmd_args); break; default: CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d", cmd_type); Loading include/uapi/media/cam_isp.h +50 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ #define CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG 5 #define CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG_V2 6 #define CAM_ISP_GENERIC_BLOB_TYPE_IFE_CORE_CONFIG 7 #define CAM_ISP_GENERIC_BLOB_TYPE_VFE_OUT_CONFIG 8 #define CAM_ISP_VC_DT_CFG 4 Loading Loading @@ -610,6 +611,55 @@ struct cam_isp_acquire_hw_info { uint64_t data; }; /** * struct cam_isp_vfe_wm_config - VFE write master config per port * * @port_type : Unique ID of output port * @wm_mode : Write master mode * 0x0 - Line based mode * 0x1 - Frame based mode * 0x2 - Index based mode, valid for BAF only * @h_init : Horizontal starting coordinate in pixels. Must be a * multiple of 3 for TP10 format * @height : Height in pixels * @width : Width in pixels * @virtual_frame_en : Enabling virtual frame will prevent actual request from * being sent to NOC * @stride : Write master stride * @offset : Write master offset * @reserved_1 : Reserved field for Write master config * @reserved_2 : Reserved field for Write master config * @reserved_3 : Reserved field for Write master config * @reserved_4 : Reserved field for Write master config */ struct cam_isp_vfe_wm_config { uint32_t port_type; uint32_t wm_mode; uint32_t h_init; uint32_t height; uint32_t width; uint32_t virtual_frame_en; uint32_t stride; uint32_t offset; uint32_t reserved_1; uint32_t reserved_2; uint32_t reserved_3; uint32_t reserved_4; }; /** * struct cam_isp_vfe_out_config - VFE write master config * * @num_ports : Number of ports * @reserved : Reserved field * @wm_config : VFE out config */ struct cam_isp_vfe_out_config { uint32_t num_ports; uint32_t reserved; struct cam_isp_vfe_wm_config wm_config[1]; }; #define CAM_ISP_ACQUIRE_COMMON_VER0 0x1000 #define CAM_ISP_ACQUIRE_COMMON_SIZE_VER0 0x0 Loading Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +153 −5 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ (CAM_ISP_PACKET_META_GENERIC_BLOB_COMMON + 1) #define CAM_ISP_GENERIC_BLOB_TYPE_MAX \ (CAM_ISP_GENERIC_BLOB_TYPE_IFE_CORE_CONFIG + 1) (CAM_ISP_GENERIC_BLOB_TYPE_VFE_OUT_CONFIG + 1) static uint32_t blob_type_hw_cmd_map[CAM_ISP_GENERIC_BLOB_TYPE_MAX] = { CAM_ISP_HW_CMD_GET_HFR_UPDATE, Loading @@ -46,6 +46,8 @@ static uint32_t blob_type_hw_cmd_map[CAM_ISP_GENERIC_BLOB_TYPE_MAX] = { CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE, CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG, CAM_ISP_HW_CMD_UBWC_UPDATE_V2, CAM_ISP_HW_CMD_CORE_CONFIG, CAM_ISP_HW_CMD_WM_CONFIG_UPDATE, }; static struct cam_ife_hw_mgr g_ife_hw_mgr; Loading Loading @@ -4171,6 +4173,100 @@ static int cam_isp_blob_clock_update( return rc; } static int cam_isp_blob_vfe_out_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_isp_vfe_out_config *vfe_out_config, struct cam_hw_prepare_update_args *prepare) { struct cam_isp_vfe_wm_config *wm_config; struct cam_kmd_buf_info *kmd_buf_info; struct cam_ife_hw_mgr_ctx *ctx = NULL; struct cam_ife_hw_mgr_res *ife_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 %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 < vfe_out_config->num_ports; i++) { wm_config = &vfe_out_config->wm_config[i]; res_id_out = wm_config->port_type & 0xFF; CAM_DBG(CAM_ISP, "VFE out config idx: %d port: 0x%x", i, wm_config->port_type); if (res_id_out >= CAM_IFE_HW_OUT_RES_MAX) { CAM_ERR(CAM_ISP, "Invalid out port:0x%x", wm_config->port_type); return -EINVAL; } 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); ife_out_res = &ctx->res_list_ife_out[res_id_out]; rc = cam_isp_add_cmd_buf_update( ife_out_res, blob_type, blob_type_hw_cmd_map[blob_type], blob_info->base_info->idx, (void *)cmd_buf_addr, kmd_buf_remain_size, (void *)wm_config, &bytes_used); if (rc < 0) { CAM_ERR(CAM_ISP, "Failed to update VFE out base_idx: %d rc: %d", blob_info->base_info->idx, bytes_used); 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 int cam_isp_packet_generic_blob_handler(void *user_data, uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data) { Loading @@ -4197,7 +4293,6 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, return -EINVAL; } CAM_DBG(CAM_ISP, "FS2: BLOB Type: %d", blob_type); switch (blob_type) { case CAM_ISP_GENERIC_BLOB_TYPE_HFR_CONFIG: { struct cam_isp_resource_hfr_config *hfr_config; Loading Loading @@ -4402,8 +4497,15 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, } break; case CAM_ISP_GENERIC_BLOB_TYPE_IFE_CORE_CONFIG: { struct cam_isp_core_config *core_config = (struct cam_isp_core_config *)blob_data; struct cam_isp_core_config *core_config; if (blob_size < sizeof(struct cam_isp_core_config)) { CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu", blob_size, sizeof(struct cam_isp_core_config)); return -EINVAL; } core_config = (struct cam_isp_core_config *)blob_data; rc = cam_isp_blob_core_cfg_update(blob_type, blob_info, core_config, prepare); Loading @@ -4411,6 +4513,52 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, CAM_ERR(CAM_ISP, "Core cfg update fail: %d", rc); } break; case CAM_ISP_GENERIC_BLOB_TYPE_VFE_OUT_CONFIG: { struct cam_isp_vfe_out_config *vfe_out_config; if (blob_size < sizeof(struct cam_isp_vfe_out_config)) { CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size, sizeof(struct cam_isp_vfe_out_config)); return -EINVAL; } vfe_out_config = (struct cam_isp_vfe_out_config *)blob_data; if (vfe_out_config->num_ports >= CAM_IFE_HW_OUT_RES_MAX) { CAM_ERR(CAM_ISP, "num_ports %u exceeds max ports %u", vfe_out_config->num_ports, CAM_IFE_HW_OUT_RES_MAX); return -EINVAL; } /* Check for integer overflow */ if (sizeof(struct cam_isp_vfe_wm_config) > ((UINT_MAX - sizeof(struct cam_isp_vfe_out_config)) / (vfe_out_config->num_ports - 1))) { CAM_ERR(CAM_ISP, "Size exceeds limit ports:%u size per port:%lu", vfe_out_config->num_ports - 1, sizeof(struct cam_isp_vfe_wm_config)); return -EINVAL; } if (blob_size < (sizeof(struct cam_isp_vfe_out_config) + (vfe_out_config->num_ports - 1) * sizeof(struct cam_isp_vfe_wm_config))) { CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu", blob_size, sizeof(uint32_t) * 2 + vfe_out_config->num_ports * sizeof(struct cam_isp_vfe_wm_config)); return -EINVAL; } rc = cam_isp_blob_vfe_out_update(blob_type, blob_info, vfe_out_config, prepare); if (rc) CAM_ERR(CAM_ISP, "VFE out update failed rc: %d", rc); } break; default: CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type); Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +2 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD, CAM_ISP_HW_CMD_UBWC_UPDATE_V2, CAM_ISP_HW_CMD_CORE_CONFIG, CAM_ISP_HW_CMD_WM_CONFIG_UPDATE, CAM_ISP_HW_CMD_MAX, }; Loading Loading @@ -227,6 +228,7 @@ struct cam_isp_hw_get_cmd_update { struct cam_ubwc_plane_cfg_v1 *ubwc_update; struct cam_fe_config *fe_update; struct cam_vfe_generic_ubwc_config *ubwc_config; struct cam_isp_vfe_wm_config *wm_config; }; }; Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c +1 −0 Original line number Diff line number Diff line Loading @@ -592,6 +592,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_STOP_BUS_ERR_IRQ: case CAM_ISP_HW_CMD_UBWC_UPDATE: case CAM_ISP_HW_CMD_UBWC_UPDATE_V2: case CAM_ISP_HW_CMD_WM_CONFIG_UPDATE: rc = core_info->vfe_bus->hw_ops.process_cmd( core_info->vfe_bus->bus_priv, cmd_type, cmd_args, arg_size); Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c +90 −29 Original line number Diff line number Diff line Loading @@ -1230,9 +1230,6 @@ static int cam_vfe_bus_ver3_acquire_wm( rsrc_data->en_cfg = 0x1; } else if (rsrc_data->index == 20) { /* WM 20 stats BAF */ rsrc_data->width = 0; rsrc_data->height = 0; rsrc_data->stride = 1; rsrc_data->en_cfg = (0x1 << 16) | 0x1; } else if (rsrc_data->index > 11 && rsrc_data->index < 20) { /* WM 12-19 stats */ Loading Loading @@ -2725,16 +2722,6 @@ static int cam_vfe_bus_ver3_update_ubwc_regs( CAM_DBG(CAM_ISP, "WM:%d packer cfg 0x%x", wm_data->index, reg_val_pair[*j-1]); if (wm_data->is_dual) { CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, *j, wm_data->hw_regs->image_cfg_1, wm_data->offset); } else { CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, *j, wm_data->hw_regs->image_cfg_1, wm_data->h_init); CAM_DBG(CAM_ISP, "WM:%d h_init 0x%x", wm_data->index, reg_val_pair[*j-1]); } CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, *j, ubwc_regs->meta_cfg, wm_data->ubwc_meta_cfg); CAM_DBG(CAM_ISP, "WM:%d meta stride 0x%x", Loading Loading @@ -2821,12 +2808,13 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args, wm_data = vfe_out_data->wm_res[i]->res_priv; ubwc_client = wm_data->hw_regs->ubwc_regs; /* update width register */ val = cam_io_r_mb(wm_data->common_data->mem_base + wm_data->hw_regs->image_cfg_0); /* mask previously written width but preserve height */ val = val & 0xFFFF0000; val |= wm_data->width; CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j, wm_data->hw_regs->cfg, wm_data->en_cfg); CAM_DBG(CAM_ISP, "WM:%d en_cfg 0x%x", wm_data->index, reg_val_pair[j-1]); val = (wm_data->height << 16) | wm_data->width; CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j, wm_data->hw_regs->image_cfg_0, val); CAM_DBG(CAM_ISP, "WM:%d image height and width 0x%x", Loading @@ -2849,7 +2837,7 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args, wm_data->hw_regs->image_cfg_2, io_cfg->planes[i].plane_stride); wm_data->stride = val; CAM_DBG(CAM_ISP, "WM %d image stride 0x%x", CAM_DBG(CAM_ISP, "WM:%d image stride 0x%x", wm_data->index, reg_val_pair[j-1]); } Loading @@ -2870,7 +2858,7 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args, reg_val_pair, &j, wm_data->hw_regs->ubwc_regs, update_buf->wm_update->image_buf[i]); CAM_DBG(CAM_ISP, "WM %d ubwc meta addr 0x%llx", CAM_DBG(CAM_ISP, "WM:%d ubwc meta addr 0x%llx", wm_data->index, update_buf->wm_update->image_buf[i]); } Loading @@ -2880,7 +2868,7 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args, io_cfg->planes[i].slice_height, 4096); frame_inc += io_cfg->planes[i].meta_size; CAM_DBG(CAM_ISP, "WM %d frm %d: ht: %d stride %d meta: %d", "WM:%d frm %d: ht: %d stride %d meta: %d", wm_data->index, frame_inc, io_cfg->planes[i].slice_height, io_cfg->planes[i].plane_stride, Loading @@ -2890,6 +2878,13 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args, io_cfg->planes[i].slice_height; } if (!(wm_data->en_cfg & (0x3 << 16))) { CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j, wm_data->hw_regs->image_cfg_1, wm_data->h_init); CAM_DBG(CAM_ISP, "WM:%d h_init 0x%x", wm_data->index, reg_val_pair[j-1]); } if ((!bus_priv->common_data.is_lite && wm_data->index > 22) || bus_priv->common_data.is_lite) loop_size = wm_data->irq_subsample_period + 1; Loading @@ -2904,18 +2899,24 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args, update_buf->wm_update->image_buf[i] + io_cfg->planes[i].meta_size + k * frame_inc); else if (wm_data->en_cfg & (0x3 << 16)) CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j, wm_data->hw_regs->image_addr, (update_buf->wm_update->image_buf[i] + wm_data->offset + k * frame_inc)); else CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j, wm_data->hw_regs->image_addr, update_buf->wm_update->image_buf[i] + wm_data->offset + k * frame_inc); CAM_DBG(CAM_ISP, "WM %d image address 0x%x", (update_buf->wm_update->image_buf[i] + k * frame_inc)); CAM_DBG(CAM_ISP, "WM:%d image address 0x%x", wm_data->index, reg_val_pair[j-1]); } CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j, wm_data->hw_regs->frame_incr, frame_inc); CAM_DBG(CAM_ISP, "WM %d frame_inc %d", CAM_DBG(CAM_ISP, "WM:%d frame_inc %d", wm_data->index, reg_val_pair[j-1]); Loading Loading @@ -3219,10 +3220,67 @@ static int cam_vfe_bus_ver3_update_stripe_cfg(void *priv, void *cmd_args, stripe_config = (struct cam_isp_dual_stripe_config *) &stripe_args->dual_cfg->stripes[ports_plane_idx + i]; wm_data->width = stripe_config->width; /* * UMD sends buffer offset address as offset for clients * programmed to operate in frame/index based mode and h_init * value as offset for clients programmed to operate in line * based mode. */ if (wm_data->en_cfg & (0x3 << 16)) wm_data->offset = stripe_config->offset; CAM_DBG(CAM_ISP, "id:%x WM:%d width:0x%x offset:%x", else wm_data->h_init = stripe_config->offset; CAM_DBG(CAM_ISP, "id:%x WM:%d width:%d offset:0x%x h_init:%d", stripe_args->res->res_id, wm_data->index, wm_data->width, wm_data->offset); wm_data->width, wm_data->offset, wm_data->h_init); } return 0; } static int cam_vfe_bus_ver3_update_wm_config( void *cmd_args) { int i; struct cam_isp_hw_get_cmd_update *wm_config_update; struct cam_vfe_bus_ver3_vfe_out_data *vfe_out_data = NULL; struct cam_vfe_bus_ver3_wm_resource_data *wm_data = NULL; struct cam_isp_vfe_wm_config *wm_config = NULL; if (!cmd_args) { CAM_ERR(CAM_ISP, "Invalid args"); return -EINVAL; } wm_config_update = cmd_args; vfe_out_data = wm_config_update->res->res_priv; wm_config = wm_config_update->wm_config; if (!vfe_out_data || !vfe_out_data->cdm_util_ops || !wm_config) { CAM_ERR(CAM_ISP, "Invalid data"); return -EINVAL; } for (i = 0; i < vfe_out_data->num_wm; i++) { wm_data = vfe_out_data->wm_res[i]->res_priv; if (wm_config->wm_mode > 0x2) { CAM_ERR(CAM_ISP, "Invalid wm_mode: 0x%x", wm_config->wm_mode); return -EINVAL; } wm_data->en_cfg = (wm_config->wm_mode << 16) | 0x1; wm_data->height = wm_config->height; wm_data->width = wm_config->width; CAM_DBG(CAM_ISP, "WM:%d en_cfg:0x%x height:%d width:%d", wm_data->index, wm_data->en_cfg, wm_data->height, wm_data->width); } return 0; Loading Loading @@ -3379,6 +3437,9 @@ static int cam_vfe_bus_ver3_process_cmd( case CAM_ISP_HW_CMD_UBWC_UPDATE_V2: rc = cam_vfe_bus_ver3_update_ubwc_config_v2(cmd_args); break; case CAM_ISP_HW_CMD_WM_CONFIG_UPDATE: rc = cam_vfe_bus_ver3_update_wm_config(cmd_args); break; default: CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d", cmd_type); Loading
include/uapi/media/cam_isp.h +50 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ #define CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG 5 #define CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG_V2 6 #define CAM_ISP_GENERIC_BLOB_TYPE_IFE_CORE_CONFIG 7 #define CAM_ISP_GENERIC_BLOB_TYPE_VFE_OUT_CONFIG 8 #define CAM_ISP_VC_DT_CFG 4 Loading Loading @@ -610,6 +611,55 @@ struct cam_isp_acquire_hw_info { uint64_t data; }; /** * struct cam_isp_vfe_wm_config - VFE write master config per port * * @port_type : Unique ID of output port * @wm_mode : Write master mode * 0x0 - Line based mode * 0x1 - Frame based mode * 0x2 - Index based mode, valid for BAF only * @h_init : Horizontal starting coordinate in pixels. Must be a * multiple of 3 for TP10 format * @height : Height in pixels * @width : Width in pixels * @virtual_frame_en : Enabling virtual frame will prevent actual request from * being sent to NOC * @stride : Write master stride * @offset : Write master offset * @reserved_1 : Reserved field for Write master config * @reserved_2 : Reserved field for Write master config * @reserved_3 : Reserved field for Write master config * @reserved_4 : Reserved field for Write master config */ struct cam_isp_vfe_wm_config { uint32_t port_type; uint32_t wm_mode; uint32_t h_init; uint32_t height; uint32_t width; uint32_t virtual_frame_en; uint32_t stride; uint32_t offset; uint32_t reserved_1; uint32_t reserved_2; uint32_t reserved_3; uint32_t reserved_4; }; /** * struct cam_isp_vfe_out_config - VFE write master config * * @num_ports : Number of ports * @reserved : Reserved field * @wm_config : VFE out config */ struct cam_isp_vfe_out_config { uint32_t num_ports; uint32_t reserved; struct cam_isp_vfe_wm_config wm_config[1]; }; #define CAM_ISP_ACQUIRE_COMMON_VER0 0x1000 #define CAM_ISP_ACQUIRE_COMMON_SIZE_VER0 0x0 Loading