On Fri Feb 7 13:24:58 2025 +0530, Vedang Nagar wrote:
> For hfi_gen2, subscribe different bitstream parameters on to firmware,
> to get notified of a change in any of the subscribed parameters.
> 
> Signed-off-by: Vedang Nagar <quic_vna...@quicinc.com>
> Tested-by: Stefan Schmidt <stefan.schm...@linaro.org> # x1e80100 (Dell XPS 13 
> 9345)
> Reviewed-by: Stefan Schmidt <stefan.schm...@linaro.org>
> Tested-by: Neil Armstrong <neil.armstr...@linaro.org> # on SM8550-QRD
> Tested-by: Neil Armstrong <neil.armstr...@linaro.org> # on SM8550-HDK
> Signed-off-by: Dikshita Agarwal <quic_diksh...@quicinc.com>
> Signed-off-by: Hans Verkuil <hverk...@xs4all.nl>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/platform/qcom/iris/iris_hfi_gen2.h   |   6 +
 .../platform/qcom/iris/iris_hfi_gen2_command.c     | 174 +++++++++++++++++++++
 .../platform/qcom/iris/iris_hfi_gen2_defines.h     |   9 ++
 .../platform/qcom/iris/iris_platform_common.h      |   4 +
 .../platform/qcom/iris/iris_platform_sm8550.c      |  13 ++
 5 files changed, 206 insertions(+)

---

diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h 
b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h
index 676bcb3dc81f..0a946c1e3a4c 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h
@@ -18,12 +18,18 @@ struct iris_core;
  *
  * @inst: pointer to iris_instance structure
  * @packet: HFI packet
+ * @ipsc_properties_set: boolean to set ipsc properties to fw
+ * @opsc_properties_set: boolean to set opsc properties to fw
  * @src_subcr_params: subscription params to fw on input port
+ * @dst_subcr_params: subscription params to fw on output port
  */
 struct iris_inst_hfi_gen2 {
        struct iris_inst                inst;
        struct iris_hfi_header          *packet;
+       bool                            ipsc_properties_set;
+       bool                            opsc_properties_set;
        struct hfi_subscription_params  src_subcr_params;
+       struct hfi_subscription_params  dst_subcr_params;
 };
 
 void iris_hfi_gen2_command_ops_init(struct iris_core *core);
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c 
b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
index 0845b75aafe9..dddaa074cae1 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
@@ -437,6 +437,9 @@ static int iris_hfi_gen2_session_open(struct iris_inst 
*inst)
        if (inst->state != IRIS_INST_DEINIT)
                return -EALREADY;
 
+       inst_hfi_gen2->ipsc_properties_set = false;
+       inst_hfi_gen2->opsc_properties_set = false;
+
        inst_hfi_gen2->packet = kzalloc(4096, GFP_KERNEL);
        if (!inst_hfi_gen2->packet)
                return -ENOMEM;
@@ -501,9 +504,180 @@ static int iris_hfi_gen2_session_close(struct iris_inst 
*inst)
        return ret;
 }
 
+static int iris_hfi_gen2_session_subscribe_mode(struct iris_inst *inst,
+                                               u32 cmd, u32 plane, u32 
payload_type,
+                                               void *payload, u32 payload_size)
+{
+       struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
+
+       iris_hfi_gen2_packet_session_command(inst,
+                                            cmd,
+                                            (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+                                            HFI_HOST_FLAGS_INTR_REQUIRED),
+                                            iris_hfi_gen2_get_port(plane),
+                                            inst->session_id,
+                                            payload_type,
+                                            payload,
+                                            payload_size);
+
+       return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
+                                       inst_hfi_gen2->packet->size);
+}
+
+static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 
plane)
+{
+       struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
+       struct hfi_subscription_params subsc_params;
+       u32 prop_type, payload_size, payload_type;
+       struct iris_core *core = inst->core;
+       const u32 *change_param;
+       u32 change_param_size;
+       u32 payload[32] = {0};
+       u32 hfi_port = 0, i;
+       int ret;
+
+       if ((V4L2_TYPE_IS_OUTPUT(plane) && inst_hfi_gen2->ipsc_properties_set) 
||
+           (V4L2_TYPE_IS_CAPTURE(plane) && 
inst_hfi_gen2->opsc_properties_set)) {
+               dev_err(core->dev, "invalid plane\n");
+               return 0;
+       }
+
+       change_param = core->iris_platform_data->input_config_params;
+       change_param_size = core->iris_platform_data->input_config_params_size;
+
+       payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE;
+
+       for (i = 0; i < change_param_size; i++)
+               payload[i + 1] = change_param[i];
+
+       ret = iris_hfi_gen2_session_subscribe_mode(inst,
+                                                  HFI_CMD_SUBSCRIBE_MODE,
+                                                  plane,
+                                                  HFI_PAYLOAD_U32_ARRAY,
+                                                  &payload[0],
+                                                  ((change_param_size + 1) * 
sizeof(u32)));
+       if (ret)
+               return ret;
+
+       if (V4L2_TYPE_IS_OUTPUT(plane)) {
+               inst_hfi_gen2->ipsc_properties_set = true;
+       } else {
+               hfi_port = 
iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+               memcpy(&inst_hfi_gen2->dst_subcr_params,
+                      &inst_hfi_gen2->src_subcr_params,
+                      sizeof(inst_hfi_gen2->src_subcr_params));
+               subsc_params = inst_hfi_gen2->dst_subcr_params;
+               for (i = 0; i < change_param_size; i++) {
+                       payload[0] = 0;
+                       payload[1] = 0;
+                       payload_size = 0;
+                       payload_type = 0;
+                       prop_type = change_param[i];
+                       switch (prop_type) {
+                       case HFI_PROP_BITSTREAM_RESOLUTION:
+                               payload[0] = subsc_params.bitstream_resolution;
+                               payload_size = sizeof(u32);
+                               payload_type = HFI_PAYLOAD_U32;
+                               break;
+                       case HFI_PROP_CROP_OFFSETS:
+                               payload[0] = subsc_params.crop_offsets[0];
+                               payload[1] = subsc_params.crop_offsets[1];
+                               payload_size = sizeof(u64);
+                               payload_type = HFI_PAYLOAD_64_PACKED;
+                               break;
+                       case HFI_PROP_CODED_FRAMES:
+                               payload[0] = subsc_params.coded_frames;
+                               payload_size = sizeof(u32);
+                               payload_type = HFI_PAYLOAD_U32;
+                               break;
+                       case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT:
+                               payload[0] = subsc_params.fw_min_count;
+                               payload_size = sizeof(u32);
+                               payload_type = HFI_PAYLOAD_U32;
+                               break;
+                       case HFI_PROP_PIC_ORDER_CNT_TYPE:
+                               payload[0] = subsc_params.pic_order_cnt;
+                               payload_size = sizeof(u32);
+                               payload_type = HFI_PAYLOAD_U32;
+                               break;
+                       case HFI_PROP_SIGNAL_COLOR_INFO:
+                               payload[0] = subsc_params.color_info;
+                               payload_size = sizeof(u32);
+                               payload_type = HFI_PAYLOAD_U32;
+                               break;
+                       case HFI_PROP_PROFILE:
+                               payload[0] = subsc_params.profile;
+                               payload_size = sizeof(u32);
+                               payload_type = HFI_PAYLOAD_U32;
+                               break;
+                       case HFI_PROP_LEVEL:
+                               payload[0] = subsc_params.level;
+                               payload_size = sizeof(u32);
+                               payload_type = HFI_PAYLOAD_U32;
+                               break;
+                       default:
+                               prop_type = 0;
+                               ret = -EINVAL;
+                               break;
+                       }
+                       if (prop_type) {
+                               ret = iris_hfi_gen2_session_set_property(inst,
+                                                                        
prop_type,
+                                                                        
HFI_HOST_FLAGS_NONE,
+                                                                        
hfi_port,
+                                                                        
payload_type,
+                                                                        
&payload,
+                                                                        
payload_size);
+                               if (ret)
+                                       return ret;
+                       }
+               }
+               inst_hfi_gen2->opsc_properties_set = true;
+       }
+
+       return 0;
+}
+
+static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane)
+{
+       struct iris_core *core = inst->core;
+       u32 subscribe_prop_size, i;
+       const u32 *subcribe_prop;
+       u32 payload[32] = {0};
+
+       payload[0] = HFI_MODE_PROPERTY;
+
+       if (V4L2_TYPE_IS_OUTPUT(plane)) {
+               subscribe_prop_size = 
core->iris_platform_data->dec_input_prop_size;
+               subcribe_prop = core->iris_platform_data->dec_input_prop;
+       } else {
+               subscribe_prop_size = 
core->iris_platform_data->dec_output_prop_size;
+               subcribe_prop = core->iris_platform_data->dec_output_prop;
+       }
+
+       for (i = 0; i < subscribe_prop_size; i++)
+               payload[i + 1] = subcribe_prop[i];
+
+       return iris_hfi_gen2_session_subscribe_mode(inst,
+                                                   HFI_CMD_SUBSCRIBE_MODE,
+                                                   plane,
+                                                   HFI_PAYLOAD_U32_ARRAY,
+                                                   &payload[0],
+                                                   (subscribe_prop_size + 1) * 
sizeof(u32));
+}
+
 static int iris_hfi_gen2_session_start(struct iris_inst *inst, u32 plane)
 {
        struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
+       int ret = 0;
+
+       ret = iris_hfi_gen2_subscribe_change_param(inst, plane);
+       if (ret)
+               return ret;
+
+       ret = iris_hfi_gen2_subscribe_property(inst, plane);
+       if (ret)
+               return ret;
 
        iris_hfi_gen2_packet_session_command(inst,
                                             HFI_CMD_START,
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h 
b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
index 4c9604b05034..4fb7a4e4604d 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
@@ -17,6 +17,7 @@
 #define HFI_CMD_CLOSE                          0x01000004
 #define HFI_CMD_START                          0x01000005
 #define HFI_CMD_STOP                           0x01000006
+#define HFI_CMD_SUBSCRIBE_MODE                 0x0100000B
 #define HFI_CMD_END                            0x01FFFFFF
 
 #define HFI_BITMASK_FRAME_MBS_ONLY_FLAG                0x00000001
@@ -42,13 +43,16 @@
 #define HFI_PROP_PIPE                          0x0300010b
 #define HFI_PROP_LUMA_CHROMA_BIT_DEPTH         0x0300010f
 #define HFI_PROP_CODED_FRAMES                  0x03000120
+#define HFI_PROP_CABAC_SESSION                 0x03000121
 #define HFI_PROP_BUFFER_HOST_MAX_COUNT         0x03000123
 #define HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT    0x03000124
 #define HFI_PROP_PIC_ORDER_CNT_TYPE            0x03000128
 #define HFI_PROP_QUALITY_MODE                  0x03000148
 #define HFI_PROP_SIGNAL_COLOR_INFO             0x03000155
+#define HFI_PROP_PICTURE_TYPE                  0x03000162
 #define HFI_PROP_DEC_DEFAULT_HEADER            0x03000168
 #define HFI_PROP_DEC_START_FROM_RAP_FRAME      0x03000169
+#define HFI_PROP_NO_OUTPUT                     0x0300016a
 #define HFI_PROP_END                           0x03FFFFFF
 
 #define HFI_SESSION_ERROR_BEGIN                        0x04000000
@@ -65,6 +69,11 @@
 #define HFI_SYS_ERROR_WD_TIMEOUT               0x05000001
 #define HFI_SYSTEM_ERROR_END                   0x05FFFFFF
 
+enum hfi_property_mode_type {
+       HFI_MODE_PORT_SETTINGS_CHANGE           = 0x00000001,
+       HFI_MODE_PROPERTY                       = 0x00000002,
+};
+
 enum hfi_color_format {
        HFI_COLOR_FMT_OPAQUE                    = 0,
        HFI_COLOR_FMT_NV12                      = 1,
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h 
b/drivers/media/platform/qcom/iris/iris_platform_common.h
index 5643fb55b09e..50965450cbb9 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -147,6 +147,10 @@ struct iris_platform_data {
        unsigned int input_config_params_size;
        const u32 *output_config_params;
        unsigned int output_config_params_size;
+       const u32 *dec_input_prop;
+       unsigned int dec_input_prop_size;
+       const u32 *dec_output_prop;
+       unsigned int dec_output_prop_size;
 };
 
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c 
b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
index 8a55c1f731c0..703e48802795 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
@@ -183,6 +183,15 @@ static const u32 sm8550_vdec_output_config_params[] = {
        HFI_PROP_LINEAR_STRIDE_SCANLINE,
 };
 
+static const u32 sm8550_vdec_subscribe_input_properties[] = {
+       HFI_PROP_NO_OUTPUT,
+};
+
+static const u32 sm8550_vdec_subscribe_output_properties[] = {
+       HFI_PROP_PICTURE_TYPE,
+       HFI_PROP_CABAC_SESSION,
+};
+
 struct iris_platform_data sm8550_data = {
        .get_instance = iris_hfi_gen2_get_instance,
        .init_hfi_command_ops = iris_hfi_gen2_command_ops_init,
@@ -220,4 +229,8 @@ struct iris_platform_data sm8550_data = {
                sm8550_vdec_output_config_params,
        .output_config_params_size =
                ARRAY_SIZE(sm8550_vdec_output_config_params),
+       .dec_input_prop = sm8550_vdec_subscribe_input_properties,
+       .dec_input_prop_size = 
ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
+       .dec_output_prop = sm8550_vdec_subscribe_output_properties,
+       .dec_output_prop_size = 
ARRAY_SIZE(sm8550_vdec_subscribe_output_properties),
 };

Reply via email to