Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions drivers/media/platform/qcom/iris/iris_ctrls.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
return LAYER5_BITRATE_HEVC;
case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
return REQUEST_SYNC_FRAME;
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
return SLICE_MODE;
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
return SLICE_MAX_BYTES;
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
return SLICE_MAX_MB;
default:
return INST_FW_CAP_MAX;
}
Expand Down Expand Up @@ -301,6 +307,12 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR;
case REQUEST_SYNC_FRAME:
return V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME;
case SLICE_MODE:
return V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
case SLICE_MAX_BYTES:
return V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
case SLICE_MAX_MB:
return V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
default:
return 0;
}
Expand Down Expand Up @@ -523,8 +535,13 @@ int iris_set_stage(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id
if (inst->domain == DECODER) {
if (iris_res_is_less_than(width, height, 1280, 720))
work_mode = STAGE_1;
} else if (inst->domain == ENCODER) {
if (inst->fw_caps[BITRATE_MODE].value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
work_mode = STAGE_1;
}

inst->fw_caps[cap_id].value = work_mode;

return hfi_ops->session_set_property(inst, hfi_id,
HFI_HOST_FLAGS_NONE,
iris_get_port_info(inst, cap_id),
Expand Down Expand Up @@ -1521,6 +1538,80 @@ int iris_set_req_sync_frame(struct iris_inst *inst, enum platform_inst_fw_cap_ty
&hfi_val, sizeof(u32));
}

int iris_set_slice_count(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
{
const struct platform_inst_slice_caps *slice_caps =
inst->core->iris_platform_data->slice_caps;
const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
u32 output_height = inst->fmt_dst->fmt.pix_mp.height;
u32 output_width = inst->fmt_dst->fmt.pix_mp.width;
u32 mbpf = NUM_MBS_PER_FRAME(output_height, output_width);
u32 max_width, max_height, min_width, min_height;
u32 slice_mode = inst->fw_caps[cap_id].value;
u32 max_avg_slicesize, hfi_value, hfi_id;
u32 rc_type = inst->hfi_rc_type;
u32 fps = inst->frame_rate;

if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) {
dev_dbg(inst->core->dev, "slice mode is single slice, ignore setting to fw\n");
return 0;
}
if (fps > slice_caps->max_slice_frame_rate ||
(rc_type != HFI_RC_OFF && rc_type != HFI_RC_CBR_CFR &&
rc_type != HFI_RC_CBR_VFR)) {
dev_err(inst->core->dev, "slice unsupported, fps: %u, rc_type: %#x\n",
fps, rc_type);
return -EINVAL;
}

max_width = (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) ?
slice_caps->max_mb_slice_width : slice_caps->max_bytes_slice_width;
max_height = (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) ?
slice_caps->max_mb_slice_height : slice_caps->max_bytes_slice_height;
min_width = (inst->codec == V4L2_PIX_FMT_HEVC) ?
slice_caps->min_hevc_slice_width : slice_caps->min_avc_slice_width;
min_height = slice_caps->min_slice_height;

if (output_width < min_width || output_height < min_height ||
output_width > max_width || output_height > max_height) {
dev_err(inst->core->dev, "slice unsupported, codec: %#x wxh: [%dx%d]\n",
inst->codec, output_width, output_height);
return -EINVAL;
}

if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) {
hfi_value = inst->fw_caps[SLICE_MAX_MB].value;
hfi_value = max(hfi_value, DIV_ROUND_UP(mbpf, slice_caps->max_slices_per_frame));
if (inst->codec == V4L2_PIX_FMT_HEVC)
hfi_value = (hfi_value + 3) / 4;
hfi_id = inst->fw_caps[SLICE_MAX_MB].hfi_id;
} else if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES) {
hfi_value = inst->fw_caps[SLICE_MAX_BYTES].value;
if (rc_type != HFI_RC_OFF) {
max_avg_slicesize = DIV_ROUND_UP((inst->fw_caps[BITRATE].value / fps) / 8,
slice_caps->max_slices_per_frame);
} else {
/*
* No bitrate target exists under RC_OFF, so approximate a
* worst-case frame size the same way size_bin_bitstream_enc()
* does for buffer allocation, to keep the slice count bounded.
*/
max_avg_slicesize = DIV_ROUND_UP(output_width * output_height * 3,
slice_caps->max_slices_per_frame);
}
hfi_value = max(hfi_value, max_avg_slicesize);
hfi_id = inst->fw_caps[SLICE_MAX_BYTES].hfi_id;
} else {
return -EINVAL;
}

return hfi_ops->session_set_property(inst, hfi_id,
HFI_HOST_FLAGS_NONE,
iris_get_port_info(inst, cap_id),
HFI_PAYLOAD_U32,
&hfi_value, sizeof(u32));
}

int iris_set_properties(struct iris_inst *inst, u32 plane)
{
const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
Expand Down
1 change: 1 addition & 0 deletions drivers/media/platform/qcom/iris/iris_ctrls.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ int iris_set_layer_count_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_
int iris_set_layer_bitrate(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_time_delta_based_rc(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_req_sync_frame(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_slice_count(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_properties(struct iris_inst *inst, u32 plane);

#endif
86 changes: 86 additions & 0 deletions drivers/media/platform/qcom/iris/iris_hfi_gen2.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@

#define VIDEO_ARCH_LX 1
#define BITRATE_MAX 245000000
#define MAX_SLICE_MB_SIZE \
(((4096 + 15) >> 4) * ((2160 + 15) >> 4))
#define MAX_SLICE_MB_SIZE_AR50LT \
(((1920 + 15) >> 4) * ((1088 + 15) >> 4))


static const struct platform_inst_fw_cap inst_fw_cap_sm8550_dec[] = {
Expand Down Expand Up @@ -960,6 +964,35 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8550_enc[] = {
.flags = CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
.set = iris_set_req_sync_frame,
},
{
.cap_id = SLICE_MODE,
.min = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
.max = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES,
.step_or_mask = BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) |
BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) |
BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES),
.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
.flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
.set = iris_set_slice_count,
},
{
.cap_id = SLICE_MAX_BYTES,
.min = 512,
.max = BITRATE_MAX >> 3,
.step_or_mask = 1,
.value = 512,
.hfi_id = HFI_PROP_MULTI_SLICE_BYTES_COUNT,
.flags = CAP_FLAG_OUTPUT_PORT,
},
{
.cap_id = SLICE_MAX_MB,
.min = 1,
.max = MAX_SLICE_MB_SIZE,
.step_or_mask = 1,
.value = 1,
.hfi_id = HFI_PROP_MULTI_SLICE_MB_COUNT,
.flags = CAP_FLAG_OUTPUT_PORT,
}
};

static const u32 sm8550_vdec_input_config_params_default[] = {
Expand Down Expand Up @@ -1903,6 +1936,35 @@ static const struct platform_inst_fw_cap inst_fw_cap_gen2_ar50lt_enc[] = {
CAP_FLAG_DYNAMIC_ALLOWED,
.set = iris_set_layer_bitrate,
},
{
.cap_id = SLICE_MODE,
.min = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
.max = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES,
.step_or_mask = BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) |
BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) |
BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES),
.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
.flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
.set = iris_set_slice_count,
},
{
.cap_id = SLICE_MAX_BYTES,
.min = 512,
.max = BITRATE_MAX_AR50LT >> 3,
.step_or_mask = 1,
.value = 512,
.hfi_id = HFI_PROP_MULTI_SLICE_BYTES_COUNT,
.flags = CAP_FLAG_OUTPUT_PORT,
},
{
.cap_id = SLICE_MAX_MB,
.min = 1,
.max = MAX_SLICE_MB_SIZE_AR50LT,
.step_or_mask = 1,
.value = 1,
.hfi_id = HFI_PROP_MULTI_SLICE_MB_COUNT,
.flags = CAP_FLAG_OUTPUT_PORT,
},
};

static const u32 iris_hfi_gen2_ar50lt_dec_ip_int_buf_tbl[] = {
Expand Down Expand Up @@ -1965,3 +2027,27 @@ const struct iris_firmware_data iris_hfi_gen2_ar50lt_data = {
.enc_op_int_buf_tbl = sm8550_enc_op_int_buf_tbl,
.enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl),
};

const struct platform_inst_slice_caps iris_vpu2_vpu3x_slice_caps = {
.max_slices_per_frame = 128,
.max_slice_frame_rate = 60,
.max_mb_slice_width = 4096,
.max_mb_slice_height = 2160,
.max_bytes_slice_width = 1920,
.max_bytes_slice_height = 1088,
.min_hevc_slice_width = 384,
.min_avc_slice_width = 192,
.min_slice_height = 128,
};

const struct platform_inst_slice_caps iris_ar50lt_slice_caps = {
.max_slices_per_frame = 128,
.max_slice_frame_rate = 60,
.max_mb_slice_width = 1920,
.max_mb_slice_height = 1088,
.max_bytes_slice_width = 1920,
.max_bytes_slice_height = 1088,
.min_hevc_slice_width = 384,
.min_avc_slice_width = 192,
.min_slice_height = 128,
};
2 changes: 2 additions & 0 deletions drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ enum hfi_rate_control {
#define HFI_PROP_MIN_QP_PACKED 0x0300012f
#define HFI_PROP_MAX_QP_PACKED 0x03000130
#define HFI_PROP_IR_RANDOM_PERIOD 0x03000131
#define HFI_PROP_MULTI_SLICE_MB_COUNT 0x03000132
#define HFI_PROP_MULTI_SLICE_BYTES_COUNT 0x03000133
#define HFI_PROP_LTR_COUNT 0x03000134
#define HFI_PROP_LTR_MARK 0x03000135
#define HFI_PROP_LTR_USE 0x03000136
Expand Down
18 changes: 18 additions & 0 deletions drivers/media/platform/qcom/iris/iris_platform_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ extern const struct iris_firmware_data iris_hfi_gen1_data;
extern const struct iris_firmware_data iris_hfi_gen1_ar50lt_data;
extern const struct iris_firmware_data iris_hfi_gen2_data;
extern const struct iris_firmware_data iris_hfi_gen2_ar50lt_data;
extern const struct platform_inst_slice_caps iris_vpu2_vpu3x_slice_caps;
extern const struct platform_inst_slice_caps iris_ar50lt_slice_caps;

extern const struct iris_platform_data qcm2290_data;
extern const struct iris_platform_data qcs8300_data;
Expand Down Expand Up @@ -96,6 +98,18 @@ struct tz_cp_config {
u32 cp_nonpixel_size;
};

struct platform_inst_slice_caps {
u32 max_slices_per_frame;
u32 max_slice_frame_rate;
u32 max_mb_slice_width;
u32 max_mb_slice_height;
u32 max_bytes_slice_width;
u32 max_bytes_slice_height;
u32 min_hevc_slice_width;
u32 min_avc_slice_width;
u32 min_slice_height;
};

struct platform_inst_caps {
u32 min_frame_width;
u32 max_frame_width;
Expand Down Expand Up @@ -192,6 +206,9 @@ enum platform_inst_fw_cap_type {
LAYER5_BITRATE_HEVC,
TIME_DELTA_BASED_RC,
REQUEST_SYNC_FRAME,
SLICE_MODE,
SLICE_MAX_BYTES,
SLICE_MAX_MB,
INST_FW_CAP_MAX,
};

Expand Down Expand Up @@ -322,6 +339,7 @@ struct iris_platform_data {
const u32 *inst_iris_fmts;
u32 inst_iris_fmts_size;
struct platform_inst_caps *inst_caps;
const struct platform_inst_slice_caps *slice_caps;
const struct tz_cp_config *tz_cp_config_data;
u32 tz_cp_config_data_size;
u32 num_vpp_pipe;
Expand Down
3 changes: 2 additions & 1 deletion drivers/media/platform/qcom/iris/iris_platform_vpu2.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ const struct iris_platform_data sc7280_data = {
.inst_iris_fmts = iris_fmts_vpu2_dec,
.inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu2_dec),
.inst_caps = &platform_inst_cap_vpu2,
.slice_caps = &iris_vpu2_vpu3x_slice_caps,
.tz_cp_config_data = tz_cp_config_vpu2,
.tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu2),
.num_vpp_pipe = 1,
Expand Down Expand Up @@ -133,4 +134,4 @@ const struct iris_platform_data sm8250_data = {
.max_session_count = 16,
.max_core_mbpf = NUM_MBS_8K,
.max_core_mbps = ((7680 * 4320) / 256) * 60,
};
};
5 changes: 5 additions & 0 deletions drivers/media/platform/qcom/iris/iris_platform_vpu3x.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ const struct iris_platform_data qcs8300_data = {
.inst_iris_fmts = iris_fmts_vpu3x_dec,
.inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec),
.inst_caps = &platform_inst_cap_qcs8300,
.slice_caps = &iris_vpu2_vpu3x_slice_caps,
.tz_cp_config_data = tz_cp_config_vpu3,
.tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3),
.num_vpp_pipe = 2,
Expand Down Expand Up @@ -180,6 +181,7 @@ const struct iris_platform_data sm8550_data = {
.inst_iris_fmts = iris_fmts_vpu3x_dec,
.inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec),
.inst_caps = &platform_inst_cap_sm8550,
.slice_caps = &iris_vpu2_vpu3x_slice_caps,
.tz_cp_config_data = tz_cp_config_vpu3,
.tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3),
.num_vpp_pipe = 4,
Expand Down Expand Up @@ -219,6 +221,7 @@ const struct iris_platform_data sm8650_data = {
.inst_iris_fmts = iris_fmts_vpu3x_dec,
.inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec),
.inst_caps = &platform_inst_cap_sm8550,
.slice_caps = &iris_vpu2_vpu3x_slice_caps,
.tz_cp_config_data = tz_cp_config_vpu3,
.tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3),
.num_vpp_pipe = 4,
Expand Down Expand Up @@ -250,6 +253,7 @@ const struct iris_platform_data sm8750_data = {
.inst_iris_fmts = iris_fmts_vpu3x_dec,
.inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec),
.inst_caps = &platform_inst_cap_sm8550,
.slice_caps = &iris_vpu2_vpu3x_slice_caps,
.tz_cp_config_data = tz_cp_config_vpu3,
.tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3),
.num_vpp_pipe = 4,
Expand Down Expand Up @@ -289,6 +293,7 @@ const struct iris_platform_data x1p42100_data = {
.inst_iris_fmts = iris_fmts_vpu3x_dec,
.inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec),
.inst_caps = &platform_inst_cap_sm8550,
.slice_caps = &iris_vpu2_vpu3x_slice_caps,
.tz_cp_config_data = tz_cp_config_vpu3,
.tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3),
.num_vpp_pipe = 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ const struct iris_platform_data qcm2290_data = {
.inst_iris_fmts = iris_fmts_ar50lt_dec,
.inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_ar50lt_dec),
.inst_caps = &platform_inst_cap_ar50lt,
.slice_caps = &iris_ar50lt_slice_caps,
.tz_cp_config_data = tz_cp_config_ar50lt,
.tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_ar50lt),
.num_vpp_pipe = 1,
Expand Down