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
89 changes: 89 additions & 0 deletions drivers/media/platform/qcom/iris/iris_ctrls.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@

#define CABAC_MAX_BITRATE 160000000
#define CAVLC_MAX_BITRATE 220000000
#define MAX_SLICES_PER_FRAME 10
#define MAX_SLICES_FRAME_RATE 60
#define MAX_MB_SLICE_WIDTH 4096
#define MAX_MB_SLICE_HEIGHT 2160
#define MAX_BYTES_SLICE_WIDTH 1920
#define MAX_BYTES_SLICE_HEIGHT 1088
#define MIN_HEVC_SLICE_WIDTH 384
#define MIN_AVC_SLICE_WIDTH 192
#define MIN_SLICE_HEIGHT 128

static inline bool iris_valid_cap_id(enum platform_inst_fw_cap_type cap_id)
{
Expand Down Expand Up @@ -112,6 +121,12 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
return IR_TYPE;
case V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD:
return IR_PERIOD;
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 @@ -213,6 +228,12 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
return V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE;
case IR_PERIOD:
return V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD;
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 @@ -996,6 +1017,74 @@ int iris_set_ir_period(struct iris_inst *inst, enum platform_inst_fw_cap_type ca
&ir_period, sizeof(u32));
}

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

if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) {
dev_dbg(inst->core->dev, "slice mode is: %u, ignore setting to fw\n", slice_mode);
return 0;
}
if (!fps) {
dev_err(inst->core->dev, "Invalid frame rate %d\n", fps);
return -EINVAL;
}
if (fps > MAX_SLICES_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) ?
MAX_MB_SLICE_WIDTH : MAX_BYTES_SLICE_WIDTH;
max_height = (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) ?
MAX_MB_SLICE_HEIGHT : MAX_BYTES_SLICE_HEIGHT;
min_width = (inst->codec == V4L2_PIX_FMT_HEVC) ?
MIN_HEVC_SLICE_WIDTH : MIN_AVC_SLICE_WIDTH;
min_height = 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, mbpf / 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 = ((bitrate / fps) / 8) / 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 @@ -35,6 +35,7 @@ int iris_set_qp_range(struct iris_inst *inst, enum platform_inst_fw_cap_type cap
int iris_set_rotation(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_flip(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_ir_period(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
31 changes: 31 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,8 @@

#define VIDEO_ARCH_LX 1
#define BITRATE_MAX 245000000
#define MAX_SLICE_MB_SIZE \
(((4096 + 15) >> 4) * ((2304 + 15) >> 4))

static const struct platform_inst_fw_cap inst_fw_cap_sm8550_dec[] = {
{
Expand Down Expand Up @@ -716,6 +718,35 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8550_enc[] = {
CAP_FLAG_DYNAMIC_ALLOWED,
.set = iris_set_ir_period,
},
{
.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
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 @@ -71,6 +71,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_TOTAL_BITRATE 0x0300013b
#define HFI_PROP_MAX_GOP_FRAMES 0x03000146
#define HFI_PROP_MAX_B_FRAMES 0x03000147
Expand Down
3 changes: 3 additions & 0 deletions drivers/media/platform/qcom/iris/iris_platform_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ enum platform_inst_fw_cap_type {
VFLIP,
IR_TYPE,
IR_PERIOD,
SLICE_MODE,
SLICE_MAX_BYTES,
SLICE_MAX_MB,
INST_FW_CAP_MAX,
};

Expand Down
31 changes: 31 additions & 0 deletions drivers/media/platform/qcom/iris/iris_platform_qcm2290.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#define BITRATE_MAX_AR50LT 100000000
#define BITRATE_DEFAULT_AR50LT 20000000
#define MIN_QP_8BIT_AR50LT 0
#define MAX_SLICE_MB_SIZE \
(((4096 + 15) >> 4) * ((2304 + 15) >> 4))

static const struct platform_inst_fw_cap inst_fw_cap_qcm2290_dec[] = {
{
Expand Down Expand Up @@ -566,6 +568,35 @@ static const struct platform_inst_fw_cap inst_fw_cap_qcm2290_enc[] = {
CAP_FLAG_DYNAMIC_ALLOWED,
.set = iris_set_ir_period,
},
{
.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,
.step_or_mask = 1,
.value = 1,
.hfi_id = HFI_PROP_MULTI_SLICE_MB_COUNT,
.flags = CAP_FLAG_OUTPUT_PORT,
},
};

static const u32 qcm2290_dec_ip_int_buf_tbl[] = {
Expand Down