mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2] media: iris: add new rate control type MBR for encoder
@ 2026-07-20 17:14 Sachin Kumar Garg
  2026-07-20 21:14 ` Dmitry Baryshkov
  2026-09-11 17:31 ` Vikash Garodia
  0 siblings, 2 replies; 4+ messages in thread
From: Sachin Kumar Garg @ 2026-07-20 17:14 UTC (permalink / raw)
  To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
	Bryan O'Donoghue, Mauro Carvalho Chehab
  Cc: linux-media, linux-arm-msm, linux-kernel, Sachin Kumar Garg

Add support for the MBR rate-control mode on the encoder.
MBR has no corresponding V4L2-spec definition, it is exposed as a
Qualcomm IRIS vendor-specific control rather than a generic
bitrate-mode value.

Reserve V4L2_CID_USER_QCOM_IRIS_BASE for Qualcomm IRIS driver
specific controls and add a new boolean control,
V4L2_CID_QCOM_MBR_RATE_CONTROL, to enable it. When set, the driver
programs the firmware with HFI_RATE_CONTROL_MBR, taking priority
over V4L2_CID_MPEG_VIDEO_BITRATE_MODE when both are client-set.

MBR is currently supported only on sc7280. Rather than duplicating
the encoder capability table per platform, add a mbr_rc_supported
flag to struct iris_platform_data, and merge in a small
platform-specific capability table containing only the MBR cap for
platforms that support it.

Signed-off-by: Sachin Kumar Garg <sachin.garg@oss.qualcomm.com>
---
This patch adds support for the MBR rate-control mode in the Iris driver.

Changes in v2:
- Per upstream review feedback, convert MBR enablement from the
  generic V4L2_MPEG_VIDEO_BITRATE_MODE_MBR menu value to a new
  Qualcomm IRIS vendor-specific boolean control,
  V4L2_CID_QCOM_MBR_RATE_CONTROL.
- Drop the now-unneeded generic V4L2_MPEG_VIDEO_BITRATE_MODE_MBR
  enum, its "Maximum Bitrate" menu string, and its documentation
  (previously sent as a separate patch 1/2).
- Drop the separate inst_fw_cap_sc7280_enc[] table (a near-complete
  duplicate of inst_fw_cap_sm8250_enc[]); sc7280 now reuses the
  shared encoder cap table and layers in only the MBR-specific cap
  entry via the new mbr_rc_supported flag.
- Link to v1: https://lore.kernel.org/linux-media/20260213-b4-add_sc7280_mbr-v1-0-e8d95b4e4809@oss.qualcomm.com/
---
 drivers/media/platform/qcom/iris/iris_ctrls.c      | 101 +++++++++++++++++----
 drivers/media/platform/qcom/iris/iris_ctrls.h      |   4 +
 .../platform/qcom/iris/iris_hfi_gen1_defines.h     |   1 +
 .../platform/qcom/iris/iris_platform_common.h      |   2 +
 .../media/platform/qcom/iris/iris_platform_vpu2.c  |   1 +
 include/uapi/linux/v4l2-controls.h                 |   6 ++
 6 files changed, 98 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
index 10e33b8a73f6..0a979649663b 100644
--- a/drivers/media/platform/qcom/iris/iris_ctrls.c
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
@@ -154,6 +154,8 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
 		return LAYER4_BITRATE_HEVC;
 	case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR:
 		return LAYER5_BITRATE_HEVC;
+	case V4L2_CID_QCOM_MBR_RATE_CONTROL:
+		return MBR_RATE_CONTROL;
 	default:
 		return INST_FW_CAP_MAX;
 	}
@@ -297,6 +299,8 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
 		return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR;
 	case LAYER5_BITRATE_HEVC:
 		return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR;
+	case MBR_RATE_CONTROL:
+		return V4L2_CID_QCOM_MBR_RATE_CONTROL;
 	default:
 		return 0;
 	}
@@ -335,6 +339,17 @@ static const struct v4l2_ctrl_ops iris_ctrl_ops = {
 	.s_ctrl = iris_op_s_ctrl,
 };
 
+static const struct v4l2_ctrl_config iris_mbr_rate_control_ctrl_config = {
+	.ops = &iris_ctrl_ops,
+	.id = V4L2_CID_QCOM_MBR_RATE_CONTROL,
+	.name = "MBR Rate Control",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.min = 0,
+	.max = 1,
+	.step = 1,
+	.def = 0,
+};
+
 int iris_ctrls_init(struct iris_inst *inst)
 {
 	struct platform_inst_fw_cap *cap = &inst->fw_caps[0];
@@ -368,7 +383,11 @@ int iris_ctrls_init(struct iris_inst *inst)
 			goto error;
 		}
 
-		if (cap[idx].flags & CAP_FLAG_MENU) {
+		if (v4l2_id == V4L2_CID_QCOM_MBR_RATE_CONTROL) {
+			ctrl = v4l2_ctrl_new_custom(&inst->ctrl_handler,
+						    &iris_mbr_rate_control_ctrl_config,
+						    NULL);
+		} else if (cap[idx].flags & CAP_FLAG_MENU) {
 			ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler,
 						      &iris_ctrl_ops,
 						      v4l2_id,
@@ -411,6 +430,39 @@ int iris_ctrls_init(struct iris_inst *inst)
 	return ret;
 }
 
+static const struct platform_inst_fw_cap inst_fw_cap_sc7280_only_enc[] = {
+	{
+		.cap_id = MBR_RATE_CONTROL,
+		.min = 0,
+		.max = 1,
+		.step_or_mask = 1,
+		.value = 0,
+		.flags = CAP_FLAG_OUTPUT_PORT,
+		.set = iris_set_mbr_rate_control,
+	},
+};
+
+static void iris_copy_enc_caps(struct iris_core *core, const struct platform_inst_fw_cap *caps,
+			       u32 num_cap)
+{
+	u32 i, cap_id;
+
+	for (i = 0; i < num_cap; i++) {
+		cap_id = caps[i].cap_id;
+		if (!iris_valid_cap_id(cap_id))
+			continue;
+
+		core->inst_fw_caps_enc[cap_id].cap_id = caps[i].cap_id;
+		core->inst_fw_caps_enc[cap_id].min = caps[i].min;
+		core->inst_fw_caps_enc[cap_id].max = caps[i].max;
+		core->inst_fw_caps_enc[cap_id].step_or_mask = caps[i].step_or_mask;
+		core->inst_fw_caps_enc[cap_id].value = caps[i].value;
+		core->inst_fw_caps_enc[cap_id].flags = caps[i].flags;
+		core->inst_fw_caps_enc[cap_id].hfi_id = caps[i].hfi_id;
+		core->inst_fw_caps_enc[cap_id].set = caps[i].set;
+	}
+}
+
 void iris_session_init_caps(struct iris_core *core)
 {
 	const struct platform_inst_fw_cap *caps;
@@ -444,23 +496,12 @@ void iris_session_init_caps(struct iris_core *core)
 		}
 	}
 
-	caps = core->iris_firmware_data->inst_fw_caps_enc;
-	num_cap = core->iris_firmware_data->inst_fw_caps_enc_size;
-
-	for (i = 0; i < num_cap; i++) {
-		cap_id = caps[i].cap_id;
-		if (!iris_valid_cap_id(cap_id))
-			continue;
+	iris_copy_enc_caps(core, core->iris_firmware_data->inst_fw_caps_enc,
+			   core->iris_firmware_data->inst_fw_caps_enc_size);
 
-		core->inst_fw_caps_enc[cap_id].cap_id = caps[i].cap_id;
-		core->inst_fw_caps_enc[cap_id].min = caps[i].min;
-		core->inst_fw_caps_enc[cap_id].max = caps[i].max;
-		core->inst_fw_caps_enc[cap_id].step_or_mask = caps[i].step_or_mask;
-		core->inst_fw_caps_enc[cap_id].value = caps[i].value;
-		core->inst_fw_caps_enc[cap_id].flags = caps[i].flags;
-		core->inst_fw_caps_enc[cap_id].hfi_id = caps[i].hfi_id;
-		core->inst_fw_caps_enc[cap_id].set = caps[i].set;
-	}
+	if (core->iris_platform_data->mbr_rc_supported)
+		iris_copy_enc_caps(core, inst_fw_cap_sc7280_only_enc,
+				   ARRAY_SIZE(inst_fw_cap_sc7280_only_enc));
 }
 
 static u32 iris_get_port_info(struct iris_inst *inst,
@@ -761,6 +802,11 @@ int iris_set_bitrate_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap
 	u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
 	u32 rc_mode = 0;
 
+	/* MBR_RATE_CONTROL takes priority over BITRATE_MODE when both are client-set */
+	if ((inst->fw_caps[MBR_RATE_CONTROL].flags & CAP_FLAG_CLIENT_SET) &&
+	    inst->fw_caps[MBR_RATE_CONTROL].value)
+		return iris_set_mbr_rate_control(inst, MBR_RATE_CONTROL);
+
 	if (!frame_rc)
 		rc_mode = HFI_RATE_CONTROL_OFF;
 	else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
@@ -779,6 +825,27 @@ int iris_set_bitrate_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap
 				     &rc_mode, sizeof(u32));
 }
 
+int iris_set_mbr_rate_control(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 mbr_enable = inst->fw_caps[cap_id].value;
+	u32 hfi_id = inst->fw_caps[BITRATE_MODE].hfi_id;
+	u32 rc_mode;
+
+	if (mbr_enable)
+		rc_mode = HFI_RATE_CONTROL_MBR;
+	else
+		return iris_set_bitrate_mode_gen1(inst, BITRATE_MODE);
+
+	inst->hfi_rc_type = rc_mode;
+
+	return hfi_ops->session_set_property(inst, hfi_id,
+					 HFI_HOST_FLAGS_NONE,
+				     iris_get_port_info(inst, BITRATE_MODE),
+				     HFI_PAYLOAD_U32_ENUM,
+				     &rc_mode, sizeof(u32));
+}
+
 int iris_set_bitrate_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
 {
 	const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.h b/drivers/media/platform/qcom/iris/iris_ctrls.h
index 3c462ec9190b..730d2d66ae2c 100644
--- a/drivers/media/platform/qcom/iris/iris_ctrls.h
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.h
@@ -7,6 +7,9 @@
 #define __IRIS_CTRLS_H__
 
 #include "iris_platform_common.h"
+#include <linux/videodev2.h>
+
+#define V4L2_CID_QCOM_MBR_RATE_CONTROL (V4L2_CID_USER_QCOM_IRIS_BASE + 0)
 
 struct iris_core;
 struct iris_inst;
@@ -27,6 +30,7 @@ int iris_set_bitrate_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type
 int iris_set_peak_bitrate(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
 int iris_set_bitrate_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
 int iris_set_bitrate_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_mbr_rate_control(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
 int iris_set_entropy_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
 int iris_set_entropy_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
 int iris_set_min_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
index 0e4dee192384..d737d3aba0aa 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -130,6 +130,7 @@
 #define HFI_RATE_CONTROL_VBR_CFR		0x1000003
 #define HFI_RATE_CONTROL_CBR_VFR		0x1000004
 #define HFI_RATE_CONTROL_CBR_CFR		0x1000005
+#define HFI_RATE_CONTROL_MBR			0x1000006
 #define HFI_RATE_CONTROL_CQ				0x1000008
 
 #define HFI_H264_ENTROPY_CAVLC			0x1
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
index c9256f2323dc..08b660d3285c 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -183,6 +183,7 @@ enum platform_inst_fw_cap_type {
 	LAYER3_BITRATE_HEVC,
 	LAYER4_BITRATE_HEVC,
 	LAYER5_BITRATE_HEVC,
+	MBR_RATE_CONTROL,
 	INST_FW_CAP_MAX,
 };
 
@@ -319,6 +320,7 @@ struct iris_platform_data {
 	u32 tz_cp_config_data_size;
 	u32 num_vpp_pipe;
 	bool no_aon;
+	bool mbr_rc_supported;
 	u32 max_session_count;
 	/* max number of macroblocks per frame supported */
 	u32 max_core_mbpf;
diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c
index 6e06a32822bb..2e160710d6af 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c
@@ -87,6 +87,7 @@ const struct iris_platform_data sc7280_data = {
 	.tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu2),
 	.num_vpp_pipe = 1,
 	.no_aon = true,
+	.mbr_rc_supported = true,
 	.max_session_count = 16,
 	.max_core_mbpf = 4096 * 2176 / 256 * 2 + 1920 * 1088 / 256,
 	/* max spec for SC7280 is 4096x2176@60fps */
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index affec0ab4781..04ac1c6532f7 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -234,6 +234,12 @@ enum v4l2_colorfx {
  */
 #define V4L2_CID_USER_MALI_C55_BASE		(V4L2_CID_USER_BASE + 0x1230)
 
+/*
+ * The base for the Qualcomm iris driver controls.
+ * We reserve 16 controls for this driver.
+ */
+#define V4L2_CID_USER_QCOM_IRIS_BASE		(V4L2_CID_USER_BASE + 0x1240)
+
 /* MPEG-class control IDs */
 /* The MPEG controls are applicable to all codec controls
  * and the 'MPEG' part of the define is historical */

---
base-commit: a52e6f7923c17a672135b485ffd96fbd72f46267
change-id: 20260212-b4-add_sc7280_mbr-597ac615b931

Best regards,
-- 
Sachin Kumar Garg <sachin.garg@oss.qualcomm.com>


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] media: iris: add new rate control type MBR for encoder
  2026-07-20 17:14 [PATCH v2] media: iris: add new rate control type MBR for encoder Sachin Kumar Garg
@ 2026-07-20 21:14 ` Dmitry Baryshkov
  2026-08-03  8:42   ` Sachin Kumar Garg
  2026-09-11 17:31 ` Vikash Garodia
  1 sibling, 1 reply; 4+ messages in thread
From: Dmitry Baryshkov @ 2026-07-20 21:14 UTC (permalink / raw)
  To: Sachin Kumar Garg
  Cc: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
	Bryan O'Donoghue, Mauro Carvalho Chehab, linux-media,
	linux-arm-msm, linux-kernel

On Mon, Jul 20, 2026 at 10:44:19PM +0530, Sachin Kumar Garg wrote:
> Add support for the MBR rate-control mode on the encoder.
> MBR has no corresponding V4L2-spec definition, it is exposed as a
> Qualcomm IRIS vendor-specific control rather than a generic
> bitrate-mode value.
> 
> Reserve V4L2_CID_USER_QCOM_IRIS_BASE for Qualcomm IRIS driver
> specific controls and add a new boolean control,
> V4L2_CID_QCOM_MBR_RATE_CONTROL, to enable it. When set, the driver
> programs the firmware with HFI_RATE_CONTROL_MBR, taking priority
> over V4L2_CID_MPEG_VIDEO_BITRATE_MODE when both are client-set.
> 
> MBR is currently supported only on sc7280. Rather than duplicating
> the encoder capability table per platform, add a mbr_rc_supported
> flag to struct iris_platform_data, and merge in a small
> platform-specific capability table containing only the MBR cap for
> platforms that support it.
> 
> Signed-off-by: Sachin Kumar Garg <sachin.garg@oss.qualcomm.com>
> ---
> This patch adds support for the MBR rate-control mode in the Iris driver.
> 
> Changes in v2:
> - Per upstream review feedback, convert MBR enablement from the
>   generic V4L2_MPEG_VIDEO_BITRATE_MODE_MBR menu value to a new
>   Qualcomm IRIS vendor-specific boolean control,
>   V4L2_CID_QCOM_MBR_RATE_CONTROL.
> - Drop the now-unneeded generic V4L2_MPEG_VIDEO_BITRATE_MODE_MBR
>   enum, its "Maximum Bitrate" menu string, and its documentation
>   (previously sent as a separate patch 1/2).
> - Drop the separate inst_fw_cap_sc7280_enc[] table (a near-complete
>   duplicate of inst_fw_cap_sm8250_enc[]); sc7280 now reuses the
>   shared encoder cap table and layers in only the MBR-specific cap
>   entry via the new mbr_rc_supported flag.

No. If we have capabiltiy arrays, please extend them. Does SM8250
firmware support MBR mode? Is it supported by AR50LT firmware?

Another option is to rework other entries in the caps array. Describe
logical platform flags (describing possible modes, profiles, etc.,
etc.), generating V4L2 controls on the fly.

> - Link to v1: https://lore.kernel.org/linux-media/20260213-b4-add_sc7280_mbr-v1-0-e8d95b4e4809@oss.qualcomm.com/
> ---
>  drivers/media/platform/qcom/iris/iris_ctrls.c      | 101 +++++++++++++++++----
>  drivers/media/platform/qcom/iris/iris_ctrls.h      |   4 +
>  .../platform/qcom/iris/iris_hfi_gen1_defines.h     |   1 +
>  .../platform/qcom/iris/iris_platform_common.h      |   2 +
>  .../media/platform/qcom/iris/iris_platform_vpu2.c  |   1 +
>  include/uapi/linux/v4l2-controls.h                 |   6 ++
>  6 files changed, 98 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
> index 10e33b8a73f6..0a979649663b 100644
> --- a/drivers/media/platform/qcom/iris/iris_ctrls.c
> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
> @@ -154,6 +154,8 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
>  		return LAYER4_BITRATE_HEVC;
>  	case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR:
>  		return LAYER5_BITRATE_HEVC;
> +	case V4L2_CID_QCOM_MBR_RATE_CONTROL:
> +		return MBR_RATE_CONTROL;
>  	default:
>  		return INST_FW_CAP_MAX;
>  	}
> @@ -297,6 +299,8 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
>  		return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR;
>  	case LAYER5_BITRATE_HEVC:
>  		return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR;
> +	case MBR_RATE_CONTROL:
> +		return V4L2_CID_QCOM_MBR_RATE_CONTROL;
>  	default:
>  		return 0;
>  	}
> @@ -335,6 +339,17 @@ static const struct v4l2_ctrl_ops iris_ctrl_ops = {
>  	.s_ctrl = iris_op_s_ctrl,
>  };
>  
> +static const struct v4l2_ctrl_config iris_mbr_rate_control_ctrl_config = {
> +	.ops = &iris_ctrl_ops,
> +	.id = V4L2_CID_QCOM_MBR_RATE_CONTROL,
> +	.name = "MBR Rate Control",
> +	.type = V4L2_CTRL_TYPE_BOOLEAN,
> +	.min = 0,
> +	.max = 1,
> +	.step = 1,
> +	.def = 0,

How does this play with other rate control mechanisms? Will it allow
user to select multiple?

> +};
> +
>  int iris_ctrls_init(struct iris_inst *inst)
>  {
>  	struct platform_inst_fw_cap *cap = &inst->fw_caps[0];

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] media: iris: add new rate control type MBR for encoder
  2026-07-20 21:14 ` Dmitry Baryshkov
@ 2026-08-03  8:42   ` Sachin Kumar Garg
  0 siblings, 0 replies; 4+ messages in thread
From: Sachin Kumar Garg @ 2026-08-03  8:42 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
	Bryan O'Donoghue, Mauro Carvalho Chehab, linux-media,
	linux-arm-msm, linux-kernel



On 7/21/2026 2:44 AM, Dmitry Baryshkov wrote:
> On Mon, Jul 20, 2026 at 10:44:19PM +0530, Sachin Kumar Garg wrote:
>> Add support for the MBR rate-control mode on the encoder.
>> MBR has no corresponding V4L2-spec definition, it is exposed as a
>> Qualcomm IRIS vendor-specific control rather than a generic
>> bitrate-mode value.
>>
>> Reserve V4L2_CID_USER_QCOM_IRIS_BASE for Qualcomm IRIS driver
>> specific controls and add a new boolean control,
>> V4L2_CID_QCOM_MBR_RATE_CONTROL, to enable it. When set, the driver
>> programs the firmware with HFI_RATE_CONTROL_MBR, taking priority
>> over V4L2_CID_MPEG_VIDEO_BITRATE_MODE when both are client-set.
>>
>> MBR is currently supported only on sc7280. Rather than duplicating
>> the encoder capability table per platform, add a mbr_rc_supported
>> flag to struct iris_platform_data, and merge in a small
>> platform-specific capability table containing only the MBR cap for
>> platforms that support it.
>>
>> Signed-off-by: Sachin Kumar Garg <sachin.garg@oss.qualcomm.com>
>> ---
>> This patch adds support for the MBR rate-control mode in the Iris driver.
>>
>> Changes in v2:
>> - Per upstream review feedback, convert MBR enablement from the
>>    generic V4L2_MPEG_VIDEO_BITRATE_MODE_MBR menu value to a new
>>    Qualcomm IRIS vendor-specific boolean control,
>>    V4L2_CID_QCOM_MBR_RATE_CONTROL.
>> - Drop the now-unneeded generic V4L2_MPEG_VIDEO_BITRATE_MODE_MBR
>>    enum, its "Maximum Bitrate" menu string, and its documentation
>>    (previously sent as a separate patch 1/2).
>> - Drop the separate inst_fw_cap_sc7280_enc[] table (a near-complete
>>    duplicate of inst_fw_cap_sm8250_enc[]); sc7280 now reuses the
>>    shared encoder cap table and layers in only the MBR-specific cap
>>    entry via the new mbr_rc_supported flag.
> 
> No. If we have capabiltiy arrays, please extend them. Does SM8250
> firmware support MBR mode? Is it supported by AR50LT firmware?
> 
> Another option is to rework other entries in the caps array. Describe
> logical platform flags (describing possible modes, profiles, etc.,
> etc.), generating V4L2 controls on the fly.
> 

SM8250 or AR50LT firmware does not implement HFI_RATE_CONTROL_MBR. This 
is sc7280-only enabled feature. sc7280 and sm8250 currently share same 
array (inst_fw_cap_sm8250_enc) via iris_hfi_gen1_data. Adding 
MBR_RATE_CONTROL there would register the control on sm8250 as well, 
which is wrong on its own. Also, every sm8250 stream-on would also 
invoke iris_set_mbr_rate_control() via .set() function and attempt to 
program a rate-control mode that firmware doesn't support.  That means 
some form of platform gating is required.
In the current change: mbr_rc_supported + a small overlay table keeps 
that gate in exactly one place (iris_session_init_caps()), rather than 
adding a platform check inside iris_set_properties()/iris_ctrls_init()'s 
generic loops. It's the same idea as other platform capability bits 
already in iris_platform_data (e.g. no_aon), applied to a cap-table 
entry instead of a runtime branch. Hence idea is not to duplicate the 
other ~25 shared gen1 encoder cap entries into per-SoC tables just to 
append one MBR entry to sc7280's copy.

>> - Link to v1: https://lore.kernel.org/linux-media/20260213-b4-add_sc7280_mbr-v1-0-e8d95b4e4809@oss.qualcomm.com/
>> ---
>>   drivers/media/platform/qcom/iris/iris_ctrls.c      | 101 +++++++++++++++++----
>>   drivers/media/platform/qcom/iris/iris_ctrls.h      |   4 +
>>   .../platform/qcom/iris/iris_hfi_gen1_defines.h     |   1 +
>>   .../platform/qcom/iris/iris_platform_common.h      |   2 +
>>   .../media/platform/qcom/iris/iris_platform_vpu2.c  |   1 +
>>   include/uapi/linux/v4l2-controls.h                 |   6 ++
>>   6 files changed, 98 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
>> index 10e33b8a73f6..0a979649663b 100644
>> --- a/drivers/media/platform/qcom/iris/iris_ctrls.c
>> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
>> @@ -154,6 +154,8 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
>>   		return LAYER4_BITRATE_HEVC;
>>   	case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR:
>>   		return LAYER5_BITRATE_HEVC;
>> +	case V4L2_CID_QCOM_MBR_RATE_CONTROL:
>> +		return MBR_RATE_CONTROL;
>>   	default:
>>   		return INST_FW_CAP_MAX;
>>   	}
>> @@ -297,6 +299,8 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
>>   		return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR;
>>   	case LAYER5_BITRATE_HEVC:
>>   		return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR;
>> +	case MBR_RATE_CONTROL:
>> +		return V4L2_CID_QCOM_MBR_RATE_CONTROL;
>>   	default:
>>   		return 0;
>>   	}
>> @@ -335,6 +339,17 @@ static const struct v4l2_ctrl_ops iris_ctrl_ops = {
>>   	.s_ctrl = iris_op_s_ctrl,
>>   };
>>   
>> +static const struct v4l2_ctrl_config iris_mbr_rate_control_ctrl_config = {
>> +	.ops = &iris_ctrl_ops,
>> +	.id = V4L2_CID_QCOM_MBR_RATE_CONTROL,
>> +	.name = "MBR Rate Control",
>> +	.type = V4L2_CTRL_TYPE_BOOLEAN,
>> +	.min = 0,
>> +	.max = 1,
>> +	.step = 1,
>> +	.def = 0,
> 
> How does this play with other rate control mechanisms? Will it allow
> user to select multiple?
> 

Both V4L2_CID_QCOM_MBR_RATE_CONTROL and V4L2_CID_MPEG_VIDEO_BITRATE_MODE 
can be set by the client — the control framework doesn't prevent it. At 
apply time, iris_set_bitrate_mode_gen1() checks whether MBR_RATE_CONTROL 
is client-set and enabled; if so, it takes priority and programs 
HFI_RATE_CONTROL_MBR, and BITRATE_MODE's value has no effect for that 
session. This is intentional and mentioned in the commit message.

>> +};
>> +
>>   int iris_ctrls_init(struct iris_inst *inst)
>>   {
>>   	struct platform_inst_fw_cap *cap = &inst->fw_caps[0];
> 


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] media: iris: add new rate control type MBR for encoder
  2026-07-20 17:14 [PATCH v2] media: iris: add new rate control type MBR for encoder Sachin Kumar Garg
  2026-07-20 21:14 ` Dmitry Baryshkov
@ 2026-09-11 17:31 ` Vikash Garodia
  1 sibling, 0 replies; 4+ messages in thread
From: Vikash Garodia @ 2026-09-11 17:31 UTC (permalink / raw)
  To: Sachin Kumar Garg, Dikshita Agarwal, Abhinav Kumar,
	Bryan O'Donoghue, Mauro Carvalho Chehab
  Cc: linux-media, linux-arm-msm, linux-kernel



On 7/20/2026 10:44 PM, Sachin Kumar Garg wrote:
> Add support for the MBR rate-control mode on the encoder.
> MBR has no corresponding V4L2-spec definition, it is exposed as a
> Qualcomm IRIS vendor-specific control rather than a generic
> bitrate-mode value.
> 
> Reserve V4L2_CID_USER_QCOM_IRIS_BASE for Qualcomm IRIS driver
> specific controls and add a new boolean control,
> V4L2_CID_QCOM_MBR_RATE_CONTROL, to enable it. When set, the driver
> programs the firmware with HFI_RATE_CONTROL_MBR, taking priority
> over V4L2_CID_MPEG_VIDEO_BITRATE_MODE when both are client-set.
> 
> MBR is currently supported only on sc7280. Rather than duplicating
> the encoder capability table per platform, add a mbr_rc_supported
> flag to struct iris_platform_data, and merge in a small
> platform-specific capability table containing only the MBR cap for
> platforms that support it.
> 
> Signed-off-by: Sachin Kumar Garg <sachin.garg@oss.qualcomm.com>
> ---
> This patch adds support for the MBR rate-control mode in the Iris driver.
> 
> Changes in v2:
> - Per upstream review feedback, convert MBR enablement from the
>    generic V4L2_MPEG_VIDEO_BITRATE_MODE_MBR menu value to a new
>    Qualcomm IRIS vendor-specific boolean control,
>    V4L2_CID_QCOM_MBR_RATE_CONTROL.
> - Drop the now-unneeded generic V4L2_MPEG_VIDEO_BITRATE_MODE_MBR
>    enum, its "Maximum Bitrate" menu string, and its documentation
>    (previously sent as a separate patch 1/2).
> - Drop the separate inst_fw_cap_sc7280_enc[] table (a near-complete
>    duplicate of inst_fw_cap_sm8250_enc[]); sc7280 now reuses the
>    shared encoder cap table and layers in only the MBR-specific cap
>    entry via the new mbr_rc_supported flag.
> - Link to v1: https://lore.kernel.org/linux-media/20260213-b4-add_sc7280_mbr-v1-0-e8d95b4e4809@oss.qualcomm.com/
> ---
>   drivers/media/platform/qcom/iris/iris_ctrls.c      | 101 +++++++++++++++++----
>   drivers/media/platform/qcom/iris/iris_ctrls.h      |   4 +
>   .../platform/qcom/iris/iris_hfi_gen1_defines.h     |   1 +
>   .../platform/qcom/iris/iris_platform_common.h      |   2 +
>   .../media/platform/qcom/iris/iris_platform_vpu2.c  |   1 +
>   include/uapi/linux/v4l2-controls.h                 |   6 ++
>   6 files changed, 98 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
> index 10e33b8a73f6..0a979649663b 100644
> --- a/drivers/media/platform/qcom/iris/iris_ctrls.c
> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
> @@ -154,6 +154,8 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
>   		return LAYER4_BITRATE_HEVC;
>   	case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR:
>   		return LAYER5_BITRATE_HEVC;
> +	case V4L2_CID_QCOM_MBR_RATE_CONTROL:
> +		return MBR_RATE_CONTROL;
>   	default:
>   		return INST_FW_CAP_MAX;
>   	}
> @@ -297,6 +299,8 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
>   		return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR;
>   	case LAYER5_BITRATE_HEVC:
>   		return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR;
> +	case MBR_RATE_CONTROL:
> +		return V4L2_CID_QCOM_MBR_RATE_CONTROL;
>   	default:
>   		return 0;
>   	}
> @@ -335,6 +339,17 @@ static const struct v4l2_ctrl_ops iris_ctrl_ops = {
>   	.s_ctrl = iris_op_s_ctrl,
>   };
>   
> +static const struct v4l2_ctrl_config iris_mbr_rate_control_ctrl_config = {
> +	.ops = &iris_ctrl_ops,
> +	.id = V4L2_CID_QCOM_MBR_RATE_CONTROL,
> +	.name = "MBR Rate Control",
> +	.type = V4L2_CTRL_TYPE_BOOLEAN,
> +	.min = 0,
> +	.max = 1,
> +	.step = 1,
> +	.def = 0,
> +};
> +
>   int iris_ctrls_init(struct iris_inst *inst)
>   {
>   	struct platform_inst_fw_cap *cap = &inst->fw_caps[0];
> @@ -368,7 +383,11 @@ int iris_ctrls_init(struct iris_inst *inst)
>   			goto error;
>   		}
>   
> -		if (cap[idx].flags & CAP_FLAG_MENU) {
> +		if (v4l2_id == V4L2_CID_QCOM_MBR_RATE_CONTROL) {
> +			ctrl = v4l2_ctrl_new_custom(&inst->ctrl_handler,
> +						    &iris_mbr_rate_control_ctrl_config,
> +						    NULL);
> +		} else if (cap[idx].flags & CAP_FLAG_MENU) {
>   			ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler,
>   						      &iris_ctrl_ops,
>   						      v4l2_id,
> @@ -411,6 +430,39 @@ int iris_ctrls_init(struct iris_inst *inst)
>   	return ret;
>   }
>   
> +static const struct platform_inst_fw_cap inst_fw_cap_sc7280_only_enc[] = {
> +	{
> +		.cap_id = MBR_RATE_CONTROL,
> +		.min = 0,
> +		.max = 1,
> +		.step_or_mask = 1,
> +		.value = 0,
> +		.flags = CAP_FLAG_OUTPUT_PORT,
> +		.set = iris_set_mbr_rate_control,
> +	},
> +};
> +
> +static void iris_copy_enc_caps(struct iris_core *core, const struct platform_inst_fw_cap *caps,
> +			       u32 num_cap)
> +{
> +	u32 i, cap_id;
> +
> +	for (i = 0; i < num_cap; i++) {
> +		cap_id = caps[i].cap_id;
> +		if (!iris_valid_cap_id(cap_id))
> +			continue;
> +
> +		core->inst_fw_caps_enc[cap_id].cap_id = caps[i].cap_id;
> +		core->inst_fw_caps_enc[cap_id].min = caps[i].min;
> +		core->inst_fw_caps_enc[cap_id].max = caps[i].max;
> +		core->inst_fw_caps_enc[cap_id].step_or_mask = caps[i].step_or_mask;
> +		core->inst_fw_caps_enc[cap_id].value = caps[i].value;
> +		core->inst_fw_caps_enc[cap_id].flags = caps[i].flags;
> +		core->inst_fw_caps_enc[cap_id].hfi_id = caps[i].hfi_id;
> +		core->inst_fw_caps_enc[cap_id].set = caps[i].set;
> +	}
> +}
> +
>   void iris_session_init_caps(struct iris_core *core)
>   {
>   	const struct platform_inst_fw_cap *caps;
> @@ -444,23 +496,12 @@ void iris_session_init_caps(struct iris_core *core)
>   		}
>   	}
>   
> -	caps = core->iris_firmware_data->inst_fw_caps_enc;
> -	num_cap = core->iris_firmware_data->inst_fw_caps_enc_size;
> -
> -	for (i = 0; i < num_cap; i++) {
> -		cap_id = caps[i].cap_id;
> -		if (!iris_valid_cap_id(cap_id))
> -			continue;
> +	iris_copy_enc_caps(core, core->iris_firmware_data->inst_fw_caps_enc,
> +			   core->iris_firmware_data->inst_fw_caps_enc_size);
>   
> -		core->inst_fw_caps_enc[cap_id].cap_id = caps[i].cap_id;
> -		core->inst_fw_caps_enc[cap_id].min = caps[i].min;
> -		core->inst_fw_caps_enc[cap_id].max = caps[i].max;
> -		core->inst_fw_caps_enc[cap_id].step_or_mask = caps[i].step_or_mask;
> -		core->inst_fw_caps_enc[cap_id].value = caps[i].value;
> -		core->inst_fw_caps_enc[cap_id].flags = caps[i].flags;
> -		core->inst_fw_caps_enc[cap_id].hfi_id = caps[i].hfi_id;
> -		core->inst_fw_caps_enc[cap_id].set = caps[i].set;
> -	}
> +	if (core->iris_platform_data->mbr_rc_supported)
> +		iris_copy_enc_caps(core, inst_fw_cap_sc7280_only_enc,
> +				   ARRAY_SIZE(inst_fw_cap_sc7280_only_enc));
>   }
>   
>   static u32 iris_get_port_info(struct iris_inst *inst,
> @@ -761,6 +802,11 @@ int iris_set_bitrate_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap
>   	u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
>   	u32 rc_mode = 0;
>   
> +	/* MBR_RATE_CONTROL takes priority over BITRATE_MODE when both are client-set */
> +	if ((inst->fw_caps[MBR_RATE_CONTROL].flags & CAP_FLAG_CLIENT_SET) &&
> +	    inst->fw_caps[MBR_RATE_CONTROL].value)
> +		return iris_set_mbr_rate_control(inst, MBR_RATE_CONTROL);
> +
>   	if (!frame_rc)
>   		rc_mode = HFI_RATE_CONTROL_OFF;
>   	else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
> @@ -779,6 +825,27 @@ int iris_set_bitrate_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap
>   				     &rc_mode, sizeof(u32));
>   }
>   
> +int iris_set_mbr_rate_control(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 mbr_enable = inst->fw_caps[cap_id].value;
> +	u32 hfi_id = inst->fw_caps[BITRATE_MODE].hfi_id;
> +	u32 rc_mode;
> +
> +	if (mbr_enable)
> +		rc_mode = HFI_RATE_CONTROL_MBR;
> +	else
> +		return iris_set_bitrate_mode_gen1(inst, BITRATE_MODE);
> +
> +	inst->hfi_rc_type = rc_mode;
> +
> +	return hfi_ops->session_set_property(inst, hfi_id,
> +					 HFI_HOST_FLAGS_NONE,
> +				     iris_get_port_info(inst, BITRATE_MODE),
> +				     HFI_PAYLOAD_U32_ENUM,
> +				     &rc_mode, sizeof(u32));
> +}
> +
>   int iris_set_bitrate_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
>   {
>   	const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
> diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.h b/drivers/media/platform/qcom/iris/iris_ctrls.h
> index 3c462ec9190b..730d2d66ae2c 100644
> --- a/drivers/media/platform/qcom/iris/iris_ctrls.h
> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.h
> @@ -7,6 +7,9 @@
>   #define __IRIS_CTRLS_H__
>   
>   #include "iris_platform_common.h"
> +#include <linux/videodev2.h>
> +
> +#define V4L2_CID_QCOM_MBR_RATE_CONTROL (V4L2_CID_USER_QCOM_IRIS_BASE + 0)
>   
>   struct iris_core;
>   struct iris_inst;
> @@ -27,6 +30,7 @@ int iris_set_bitrate_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type
>   int iris_set_peak_bitrate(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
>   int iris_set_bitrate_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
>   int iris_set_bitrate_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> +int iris_set_mbr_rate_control(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
>   int iris_set_entropy_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
>   int iris_set_entropy_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
>   int iris_set_min_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> index 0e4dee192384..d737d3aba0aa 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> @@ -130,6 +130,7 @@
>   #define HFI_RATE_CONTROL_VBR_CFR		0x1000003
>   #define HFI_RATE_CONTROL_CBR_VFR		0x1000004
>   #define HFI_RATE_CONTROL_CBR_CFR		0x1000005
> +#define HFI_RATE_CONTROL_MBR			0x1000006
>   #define HFI_RATE_CONTROL_CQ				0x1000008
>   
>   #define HFI_H264_ENTROPY_CAVLC			0x1
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
> index c9256f2323dc..08b660d3285c 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
> @@ -183,6 +183,7 @@ enum platform_inst_fw_cap_type {
>   	LAYER3_BITRATE_HEVC,
>   	LAYER4_BITRATE_HEVC,
>   	LAYER5_BITRATE_HEVC,
> +	MBR_RATE_CONTROL,
>   	INST_FW_CAP_MAX,
>   };
>   
> @@ -319,6 +320,7 @@ struct iris_platform_data {
>   	u32 tz_cp_config_data_size;
>   	u32 num_vpp_pipe;
>   	bool no_aon;
> +	bool mbr_rc_supported;
>   	u32 max_session_count;
>   	/* max number of macroblocks per frame supported */
>   	u32 max_core_mbpf;
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c
> index 6e06a32822bb..2e160710d6af 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c
> +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c
> @@ -87,6 +87,7 @@ const struct iris_platform_data sc7280_data = {
>   	.tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu2),
>   	.num_vpp_pipe = 1,
>   	.no_aon = true,
> +	.mbr_rc_supported = true,
>   	.max_session_count = 16,
>   	.max_core_mbpf = 4096 * 2176 / 256 * 2 + 1920 * 1088 / 256,
>   	/* max spec for SC7280 is 4096x2176@60fps */
> diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h

separate patch

> index affec0ab4781..04ac1c6532f7 100644
> --- a/include/uapi/linux/v4l2-controls.h
> +++ b/include/uapi/linux/v4l2-controls.h
> @@ -234,6 +234,12 @@ enum v4l2_colorfx {
>    */
>   #define V4L2_CID_USER_MALI_C55_BASE		(V4L2_CID_USER_BASE + 0x1230)
>   
> +/*
> + * The base for the Qualcomm iris driver controls.
> + * We reserve 16 controls for this driver.

please keep reserve for 64 controls

> + */
> +#define V4L2_CID_USER_QCOM_IRIS_BASE		(V4L2_CID_USER_BASE + 0x1240)
> +
>   /* MPEG-class control IDs */
>   /* The MPEG controls are applicable to all codec controls
>    * and the 'MPEG' part of the define is historical */
> 
> ---
> base-commit: a52e6f7923c17a672135b485ffd96fbd72f46267
> change-id: 20260212-b4-add_sc7280_mbr-597ac615b931
> 
> Best regards,


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-09-11 17:31 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-20 17:14 [PATCH v2] media: iris: add new rate control type MBR for encoder Sachin Kumar Garg
2026-07-20 21:14 ` Dmitry Baryshkov
2026-08-03  8:42   ` Sachin Kumar Garg
2026-09-11 17:31 ` Vikash Garodia

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®