Loading Documentation/devicetree/bindings/media/video/msm-cam-isp.txt +5 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,11 @@ First Level Node - CAM ISP device Value type: <string> Definition: Should be "vfe" or "ife". - ubwc-static-cfg Usage: optional Value type: <u32> Definition: IFE UBWC static configuration based on DDR device type. Example: qcom,cam-isp { Loading arch/arm64/boot/dts/qcom/kona-camera.dtsi +2 −0 Original line number Diff line number Diff line Loading @@ -830,6 +830,7 @@ clock-names-option = "ife_dsp_clk"; clocks-option = <&clock_camcc CAM_CC_IFE_0_DSP_CLK>; clock-rates-option = <720000000>; ubwc-static-cfg = <0x1026 0x1036>; status = "ok"; }; Loading Loading @@ -910,6 +911,7 @@ clock-names-option = "ife_dsp_clk"; clocks-option = <&clock_camcc CAM_CC_IFE_1_DSP_CLK>; clock-rates-option = <720000000>; ubwc-static-cfg = <0x1026 0x1036>; status = "ok"; }; Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +179 −1 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_FE_CONFIG + 1) (CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG_V2 + 1) static uint32_t blob_type_hw_cmd_map[CAM_ISP_GENERIC_BLOB_TYPE_MAX] = { CAM_ISP_HW_CMD_GET_HFR_UPDATE, Loading @@ -45,6 +45,7 @@ static uint32_t blob_type_hw_cmd_map[CAM_ISP_GENERIC_BLOB_TYPE_MAX] = { CAM_ISP_HW_CMD_UBWC_UPDATE, CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE, CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG, CAM_ISP_HW_CMD_UBWC_UPDATE_V2, }; static struct cam_ife_hw_mgr g_ife_hw_mgr; Loading Loading @@ -3238,6 +3239,172 @@ static int cam_isp_blob_ubwc_update( return rc; } static int cam_isp_get_generic_ubwc_data_v2( struct cam_ubwc_plane_cfg_v2 *ubwc_cfg, uint32_t version, struct cam_vfe_generic_ubwc_config *generic_ubwc_cfg) { int i = 0; generic_ubwc_cfg->api_version = version; for (i = 0; i < CAM_PACKET_MAX_PLANES - 1; i++) { generic_ubwc_cfg->ubwc_plane_cfg[i].port_type = ubwc_cfg[i].port_type; generic_ubwc_cfg->ubwc_plane_cfg[i].meta_stride = ubwc_cfg[i].meta_stride; generic_ubwc_cfg->ubwc_plane_cfg[i].meta_size = ubwc_cfg[i].meta_size; generic_ubwc_cfg->ubwc_plane_cfg[i].meta_offset = ubwc_cfg[i].meta_offset; generic_ubwc_cfg->ubwc_plane_cfg[i].packer_config = ubwc_cfg[i].packer_config; generic_ubwc_cfg->ubwc_plane_cfg[i].mode_config_0 = ubwc_cfg[i].mode_config_0; generic_ubwc_cfg->ubwc_plane_cfg[i].mode_config_1 = ubwc_cfg[i].mode_config_1; generic_ubwc_cfg->ubwc_plane_cfg[i].tile_config = ubwc_cfg[i].tile_config; generic_ubwc_cfg->ubwc_plane_cfg[i].h_init = ubwc_cfg[i].h_init; generic_ubwc_cfg->ubwc_plane_cfg[i].v_init = ubwc_cfg[i].v_init; generic_ubwc_cfg->ubwc_plane_cfg[i].static_ctrl = ubwc_cfg[i].static_ctrl; generic_ubwc_cfg->ubwc_plane_cfg[i].ctrl_2 = ubwc_cfg[i].ctrl_2; generic_ubwc_cfg->ubwc_plane_cfg[i].stats_ctrl_2 = ubwc_cfg[i].stats_ctrl_2; generic_ubwc_cfg->ubwc_plane_cfg[i].lossy_threshold_0 = ubwc_cfg[i].lossy_threshold_0; generic_ubwc_cfg->ubwc_plane_cfg[i].lossy_threshold_1 = ubwc_cfg[i].lossy_threshold_1; generic_ubwc_cfg->ubwc_plane_cfg[i].lossy_var_offset = ubwc_cfg[i].lossy_var_offset; generic_ubwc_cfg->ubwc_plane_cfg[i].bandwidth_limit = ubwc_cfg[i].bandwidth_limit; } return 0; } static int cam_isp_blob_ubwc_update_v2( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_ubwc_config_v2 *ubwc_config, struct cam_hw_prepare_update_args *prepare) { struct cam_ubwc_plane_cfg_v2 *ubwc_plane_cfg; struct cam_kmd_buf_info *kmd_buf_info; struct cam_ife_hw_mgr_ctx *ctx = NULL; struct cam_ife_hw_mgr_res *hw_mgr_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; struct cam_vfe_generic_ubwc_config generic_ubwc_cfg; ctx = prepare->ctxt_to_hw_map; if (!ctx) { CAM_ERR(CAM_ISP, "Invalid ctx"); rc = -EINVAL; goto end; } 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); rc = -EINVAL; goto end; } CAM_DBG(CAM_ISP, "num_ports= %d", ubwc_config->num_ports); kmd_buf_info = blob_info->kmd_buf_info; for (i = 0; i < ubwc_config->num_ports; i++) { ubwc_plane_cfg = &ubwc_config->ubwc_plane_cfg[i][0]; res_id_out = ubwc_plane_cfg->port_type & 0xFF; CAM_DBG(CAM_ISP, "UBWC config idx %d, port_type=%d", i, ubwc_plane_cfg->port_type); if (res_id_out >= CAM_IFE_HW_OUT_RES_MAX) { CAM_ERR(CAM_ISP, "Invalid port type:%x", ubwc_plane_cfg->port_type); rc = -EINVAL; goto end; } 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=%d bytes_used=%u buf_size=%u", blob_info->base_info->idx, bytes_used, kmd_buf_info->size); rc = -ENOMEM; goto end; } cmd_buf_addr = kmd_buf_info->cpu_addr + kmd_buf_info->used_bytes/4 + total_used_bytes/4; hw_mgr_res = &ctx->res_list_ife_out[res_id_out]; if (!hw_mgr_res) { CAM_ERR(CAM_ISP, "Invalid hw_mgr_res"); rc = -EINVAL; goto end; } rc = cam_isp_get_generic_ubwc_data_v2(ubwc_plane_cfg, ubwc_config->api_version, &generic_ubwc_cfg); rc = cam_isp_add_cmd_buf_update( hw_mgr_res, blob_type, blob_type_hw_cmd_map[blob_type], blob_info->base_info->idx, (void *)cmd_buf_addr, kmd_buf_remain_size, (void *)&generic_ubwc_cfg, &bytes_used); if (rc < 0) { CAM_ERR(CAM_ISP, "Failed cmd_update, base_idx=%d, bytes_used=%u, res_id_out=0x%x", blob_info->base_info->idx, bytes_used, res_id_out); goto end; } total_used_bytes += bytes_used; } if (total_used_bytes) { /* Update the HW entries */ 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; } end: return rc; } static int cam_isp_blob_hfr_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, Loading Loading @@ -3570,6 +3737,17 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, CAM_ERR(CAM_ISP, "UBWC Update Failed rc: %d", rc); } break; case CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG_V2: { struct cam_ubwc_config_v2 *ubwc_config = (struct cam_ubwc_config_v2 *)blob_data; rc = cam_isp_blob_ubwc_update_v2(blob_type, blob_info, ubwc_config, prepare); if (rc) CAM_ERR(CAM_ISP, "UBWC Update Failed rc: %d", rc); } break; case CAM_ISP_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG: { struct cam_isp_csid_clock_config *clock_config = (struct cam_isp_csid_clock_config *)blob_data; Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +3 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. */ #ifndef _CAM_ISP_HW_H_ Loading Loading @@ -97,6 +97,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE, CAM_ISP_HW_CMD_FE_UPDATE_IN_RD, CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD, CAM_ISP_HW_CMD_UBWC_UPDATE_V2, CAM_ISP_HW_CMD_MAX, }; Loading Loading @@ -206,6 +207,7 @@ struct cam_isp_hw_get_cmd_update { struct cam_isp_bw_config *bw_update; struct cam_ubwc_plane_cfg_v1 *ubwc_update; struct cam_fe_config *fe_update; struct cam_vfe_generic_ubwc_config *ubwc_config; }; }; Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h +52 −0 Original line number Diff line number Diff line Loading @@ -299,6 +299,58 @@ struct cam_vfe_irq_handler_priv { uint32_t hw_version; }; /** * struct cam_ubwc_generic_plane_config - UBWC Plane configuration info * * @port_type: Port Type * @meta_stride: UBWC metadata stride * @meta_size: UBWC metadata plane size * @meta_offset: UBWC metadata offset * @packer_config: UBWC packer config * @mode_config: UBWC mode config * @static ctrl: UBWC static ctrl * @ctrl_2: UBWC ctrl 2 * @tile_config: UBWC tile config * @h_init: UBWC horizontal initial coordinate in pixels * @v_init: UBWC vertical initial coordinate in lines * @stats_ctrl_2: UBWC stats control * @lossy_threshold0 UBWC lossy threshold 0 * @lossy_threshold1 UBWC lossy threshold 1 * @lossy_var_offset UBWC offset variance threshold * @bandwidth limit UBWC bandwidth limit */ struct cam_vfe_generic_ubwc_plane_config { uint32_t port_type; uint32_t meta_stride; uint32_t meta_size; uint32_t meta_offset; uint32_t packer_config; uint32_t mode_config_0; uint32_t mode_config_1; uint32_t tile_config; uint32_t h_init; uint32_t v_init; uint32_t static_ctrl; uint32_t ctrl_2; uint32_t stats_ctrl_2; uint32_t lossy_threshold_0; uint32_t lossy_threshold_1; uint32_t lossy_var_offset; uint32_t bandwidth_limit; }; /** * struct cam_ubwc_generic_config - UBWC Configuration Payload * * @api_version: UBWC config api version * @ubwc_plane_config: Array of UBWC configurations per plane */ struct cam_vfe_generic_ubwc_config { uint32_t api_version; struct cam_vfe_generic_ubwc_plane_config ubwc_plane_cfg[CAM_PACKET_MAX_PLANES - 1]; }; /* * cam_vfe_hw_init() * Loading Loading
Documentation/devicetree/bindings/media/video/msm-cam-isp.txt +5 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,11 @@ First Level Node - CAM ISP device Value type: <string> Definition: Should be "vfe" or "ife". - ubwc-static-cfg Usage: optional Value type: <u32> Definition: IFE UBWC static configuration based on DDR device type. Example: qcom,cam-isp { Loading
arch/arm64/boot/dts/qcom/kona-camera.dtsi +2 −0 Original line number Diff line number Diff line Loading @@ -830,6 +830,7 @@ clock-names-option = "ife_dsp_clk"; clocks-option = <&clock_camcc CAM_CC_IFE_0_DSP_CLK>; clock-rates-option = <720000000>; ubwc-static-cfg = <0x1026 0x1036>; status = "ok"; }; Loading Loading @@ -910,6 +911,7 @@ clock-names-option = "ife_dsp_clk"; clocks-option = <&clock_camcc CAM_CC_IFE_1_DSP_CLK>; clock-rates-option = <720000000>; ubwc-static-cfg = <0x1026 0x1036>; status = "ok"; }; Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +179 −1 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_FE_CONFIG + 1) (CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG_V2 + 1) static uint32_t blob_type_hw_cmd_map[CAM_ISP_GENERIC_BLOB_TYPE_MAX] = { CAM_ISP_HW_CMD_GET_HFR_UPDATE, Loading @@ -45,6 +45,7 @@ static uint32_t blob_type_hw_cmd_map[CAM_ISP_GENERIC_BLOB_TYPE_MAX] = { CAM_ISP_HW_CMD_UBWC_UPDATE, CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE, CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG, CAM_ISP_HW_CMD_UBWC_UPDATE_V2, }; static struct cam_ife_hw_mgr g_ife_hw_mgr; Loading Loading @@ -3238,6 +3239,172 @@ static int cam_isp_blob_ubwc_update( return rc; } static int cam_isp_get_generic_ubwc_data_v2( struct cam_ubwc_plane_cfg_v2 *ubwc_cfg, uint32_t version, struct cam_vfe_generic_ubwc_config *generic_ubwc_cfg) { int i = 0; generic_ubwc_cfg->api_version = version; for (i = 0; i < CAM_PACKET_MAX_PLANES - 1; i++) { generic_ubwc_cfg->ubwc_plane_cfg[i].port_type = ubwc_cfg[i].port_type; generic_ubwc_cfg->ubwc_plane_cfg[i].meta_stride = ubwc_cfg[i].meta_stride; generic_ubwc_cfg->ubwc_plane_cfg[i].meta_size = ubwc_cfg[i].meta_size; generic_ubwc_cfg->ubwc_plane_cfg[i].meta_offset = ubwc_cfg[i].meta_offset; generic_ubwc_cfg->ubwc_plane_cfg[i].packer_config = ubwc_cfg[i].packer_config; generic_ubwc_cfg->ubwc_plane_cfg[i].mode_config_0 = ubwc_cfg[i].mode_config_0; generic_ubwc_cfg->ubwc_plane_cfg[i].mode_config_1 = ubwc_cfg[i].mode_config_1; generic_ubwc_cfg->ubwc_plane_cfg[i].tile_config = ubwc_cfg[i].tile_config; generic_ubwc_cfg->ubwc_plane_cfg[i].h_init = ubwc_cfg[i].h_init; generic_ubwc_cfg->ubwc_plane_cfg[i].v_init = ubwc_cfg[i].v_init; generic_ubwc_cfg->ubwc_plane_cfg[i].static_ctrl = ubwc_cfg[i].static_ctrl; generic_ubwc_cfg->ubwc_plane_cfg[i].ctrl_2 = ubwc_cfg[i].ctrl_2; generic_ubwc_cfg->ubwc_plane_cfg[i].stats_ctrl_2 = ubwc_cfg[i].stats_ctrl_2; generic_ubwc_cfg->ubwc_plane_cfg[i].lossy_threshold_0 = ubwc_cfg[i].lossy_threshold_0; generic_ubwc_cfg->ubwc_plane_cfg[i].lossy_threshold_1 = ubwc_cfg[i].lossy_threshold_1; generic_ubwc_cfg->ubwc_plane_cfg[i].lossy_var_offset = ubwc_cfg[i].lossy_var_offset; generic_ubwc_cfg->ubwc_plane_cfg[i].bandwidth_limit = ubwc_cfg[i].bandwidth_limit; } return 0; } static int cam_isp_blob_ubwc_update_v2( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, struct cam_ubwc_config_v2 *ubwc_config, struct cam_hw_prepare_update_args *prepare) { struct cam_ubwc_plane_cfg_v2 *ubwc_plane_cfg; struct cam_kmd_buf_info *kmd_buf_info; struct cam_ife_hw_mgr_ctx *ctx = NULL; struct cam_ife_hw_mgr_res *hw_mgr_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; struct cam_vfe_generic_ubwc_config generic_ubwc_cfg; ctx = prepare->ctxt_to_hw_map; if (!ctx) { CAM_ERR(CAM_ISP, "Invalid ctx"); rc = -EINVAL; goto end; } 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); rc = -EINVAL; goto end; } CAM_DBG(CAM_ISP, "num_ports= %d", ubwc_config->num_ports); kmd_buf_info = blob_info->kmd_buf_info; for (i = 0; i < ubwc_config->num_ports; i++) { ubwc_plane_cfg = &ubwc_config->ubwc_plane_cfg[i][0]; res_id_out = ubwc_plane_cfg->port_type & 0xFF; CAM_DBG(CAM_ISP, "UBWC config idx %d, port_type=%d", i, ubwc_plane_cfg->port_type); if (res_id_out >= CAM_IFE_HW_OUT_RES_MAX) { CAM_ERR(CAM_ISP, "Invalid port type:%x", ubwc_plane_cfg->port_type); rc = -EINVAL; goto end; } 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=%d bytes_used=%u buf_size=%u", blob_info->base_info->idx, bytes_used, kmd_buf_info->size); rc = -ENOMEM; goto end; } cmd_buf_addr = kmd_buf_info->cpu_addr + kmd_buf_info->used_bytes/4 + total_used_bytes/4; hw_mgr_res = &ctx->res_list_ife_out[res_id_out]; if (!hw_mgr_res) { CAM_ERR(CAM_ISP, "Invalid hw_mgr_res"); rc = -EINVAL; goto end; } rc = cam_isp_get_generic_ubwc_data_v2(ubwc_plane_cfg, ubwc_config->api_version, &generic_ubwc_cfg); rc = cam_isp_add_cmd_buf_update( hw_mgr_res, blob_type, blob_type_hw_cmd_map[blob_type], blob_info->base_info->idx, (void *)cmd_buf_addr, kmd_buf_remain_size, (void *)&generic_ubwc_cfg, &bytes_used); if (rc < 0) { CAM_ERR(CAM_ISP, "Failed cmd_update, base_idx=%d, bytes_used=%u, res_id_out=0x%x", blob_info->base_info->idx, bytes_used, res_id_out); goto end; } total_used_bytes += bytes_used; } if (total_used_bytes) { /* Update the HW entries */ 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; } end: return rc; } static int cam_isp_blob_hfr_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, Loading Loading @@ -3570,6 +3737,17 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, CAM_ERR(CAM_ISP, "UBWC Update Failed rc: %d", rc); } break; case CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG_V2: { struct cam_ubwc_config_v2 *ubwc_config = (struct cam_ubwc_config_v2 *)blob_data; rc = cam_isp_blob_ubwc_update_v2(blob_type, blob_info, ubwc_config, prepare); if (rc) CAM_ERR(CAM_ISP, "UBWC Update Failed rc: %d", rc); } break; case CAM_ISP_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG: { struct cam_isp_csid_clock_config *clock_config = (struct cam_isp_csid_clock_config *)blob_data; Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +3 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. */ #ifndef _CAM_ISP_HW_H_ Loading Loading @@ -97,6 +97,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE, CAM_ISP_HW_CMD_FE_UPDATE_IN_RD, CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD, CAM_ISP_HW_CMD_UBWC_UPDATE_V2, CAM_ISP_HW_CMD_MAX, }; Loading Loading @@ -206,6 +207,7 @@ struct cam_isp_hw_get_cmd_update { struct cam_isp_bw_config *bw_update; struct cam_ubwc_plane_cfg_v1 *ubwc_update; struct cam_fe_config *fe_update; struct cam_vfe_generic_ubwc_config *ubwc_config; }; }; Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h +52 −0 Original line number Diff line number Diff line Loading @@ -299,6 +299,58 @@ struct cam_vfe_irq_handler_priv { uint32_t hw_version; }; /** * struct cam_ubwc_generic_plane_config - UBWC Plane configuration info * * @port_type: Port Type * @meta_stride: UBWC metadata stride * @meta_size: UBWC metadata plane size * @meta_offset: UBWC metadata offset * @packer_config: UBWC packer config * @mode_config: UBWC mode config * @static ctrl: UBWC static ctrl * @ctrl_2: UBWC ctrl 2 * @tile_config: UBWC tile config * @h_init: UBWC horizontal initial coordinate in pixels * @v_init: UBWC vertical initial coordinate in lines * @stats_ctrl_2: UBWC stats control * @lossy_threshold0 UBWC lossy threshold 0 * @lossy_threshold1 UBWC lossy threshold 1 * @lossy_var_offset UBWC offset variance threshold * @bandwidth limit UBWC bandwidth limit */ struct cam_vfe_generic_ubwc_plane_config { uint32_t port_type; uint32_t meta_stride; uint32_t meta_size; uint32_t meta_offset; uint32_t packer_config; uint32_t mode_config_0; uint32_t mode_config_1; uint32_t tile_config; uint32_t h_init; uint32_t v_init; uint32_t static_ctrl; uint32_t ctrl_2; uint32_t stats_ctrl_2; uint32_t lossy_threshold_0; uint32_t lossy_threshold_1; uint32_t lossy_var_offset; uint32_t bandwidth_limit; }; /** * struct cam_ubwc_generic_config - UBWC Configuration Payload * * @api_version: UBWC config api version * @ubwc_plane_config: Array of UBWC configurations per plane */ struct cam_vfe_generic_ubwc_config { uint32_t api_version; struct cam_vfe_generic_ubwc_plane_config ubwc_plane_cfg[CAM_PACKET_MAX_PLANES - 1]; }; /* * cam_vfe_hw_init() * Loading