Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
ac5a6f1
BACKPORT: media: Use of_reserved_mem_region_to_resource() for "memory…
robherring Aug 13, 2025
6667589
BACKPORT: media: iris: Cast iris_hfi_gen2_get_instance() allocation type
kees Apr 26, 2025
dcb7149
BACKPORT: media: iris: Document difference in size during allocation
ribalda Dec 23, 2025
10186fd
BACKPORT: media: iris: Change psc properties message to debug level
Nov 10, 2025
d7e6ead
BACKPORT: media: qcom: iris: Improve crop_offset handling for encoder
Nov 14, 2025
4e77259
BACKPORT: media: qcom: iris: Improve format alignment for encoder
Nov 14, 2025
bea760a
BACKPORT: media: qcom: iris: Add scale support for encoder
Nov 14, 2025
867f704
BACKPORT: media: qcom: iris: Add rotation support for encoder
Nov 14, 2025
6e9d65a
BACKPORT: media: qcom: iris: Add flip support for encoder
Nov 14, 2025
ce28e3d
BACKPORT: media: qcom: iris: Add intra refresh support for encoder
Nov 14, 2025
c01caa2
BACKPORT: media: iris: Add support for multiple clock sources
Dec 10, 2025
5e633ce
BACKPORT: media: iris: Add support for multiple TZ content protection…
Dec 10, 2025
1fbfb19
BACKPORT: media: iris: Introduce buffer size calculations for vpu4
Dec 10, 2025
422f3a6
BACKPORT: media: iris: Move vpu register defines to common header file
Dec 10, 2025
72cbe7f
BACKPORT: media: iris: Move vpu35 specific api to common to use for vpu4
Dec 10, 2025
214d94e
BACKPORT: media: iris: Introduce vpu ops for vpu4 with necessary hooks
Dec 10, 2025
7297ff8
BACKPORT: media: venus: drop bogus probe deferrals
jhovold Oct 17, 2025
39ef4f7
BACKPORT: media: venus: drop unused module aliases
jhovold Oct 17, 2025
5a245d3
BACKPORT: media: venus: assign unique bus_info strings for encoder an…
ldts Apr 1, 2026
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
40 changes: 10 additions & 30 deletions drivers/media/platform/amphion/vpu_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/types.h>
Expand Down Expand Up @@ -542,47 +542,30 @@ const struct vpu_core_resources *vpu_get_resource(struct vpu_inst *inst)

static int vpu_core_parse_dt(struct vpu_core *core, struct device_node *np)
{
struct device_node *node;
struct resource res;
int ret;

if (of_count_phandle_with_args(np, "memory-region", NULL) < 2) {
dev_err(core->dev, "need 2 memory-region for boot and rpc\n");
return -ENODEV;
ret = of_reserved_mem_region_to_resource(np, 0, &res);
if (ret) {
dev_err(core->dev, "Cannot get boot-region\n");
return ret;
}

node = of_parse_phandle(np, "memory-region", 0);
if (!node) {
dev_err(core->dev, "boot-region of_parse_phandle error\n");
return -ENODEV;
}
if (of_address_to_resource(node, 0, &res)) {
dev_err(core->dev, "boot-region of_address_to_resource error\n");
of_node_put(node);
return -EINVAL;
}
core->fw.phys = res.start;
core->fw.length = resource_size(&res);

of_node_put(node);

node = of_parse_phandle(np, "memory-region", 1);
if (!node) {
dev_err(core->dev, "rpc-region of_parse_phandle error\n");
return -ENODEV;
}
if (of_address_to_resource(node, 0, &res)) {
dev_err(core->dev, "rpc-region of_address_to_resource error\n");
of_node_put(node);
return -EINVAL;
ret = of_reserved_mem_region_to_resource(np, 1, &res);
if (ret) {
dev_err(core->dev, "Cannot get rpc-region\n");
return ret;
}

core->rpc.phys = res.start;
core->rpc.length = resource_size(&res);

if (core->rpc.length < core->res->rpc_size + core->res->fwlog_size) {
dev_err(core->dev, "the rpc-region <%pad, 0x%x> is not enough\n",
&core->rpc.phys, core->rpc.length);
of_node_put(node);
return -EINVAL;
}

Expand All @@ -594,7 +577,6 @@ static int vpu_core_parse_dt(struct vpu_core *core, struct device_node *np)
if (ret != VPU_CORE_MEMORY_UNCACHED) {
dev_err(core->dev, "rpc region<%pad, 0x%x> isn't uncached\n",
&core->rpc.phys, core->rpc.length);
of_node_put(node);
return -EINVAL;
}

Expand All @@ -606,8 +588,6 @@ static int vpu_core_parse_dt(struct vpu_core *core, struct device_node *np)
core->act.length = core->rpc.length - core->res->rpc_size - core->log.length;
core->rpc.length = core->res->rpc_size;

of_node_put(node);

return 0;
}

Expand Down
1 change: 1 addition & 0 deletions drivers/media/platform/qcom/iris/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ qcom-iris-objs += iris_buffer.o \
iris_venc.o \
iris_vpu2.o \
iris_vpu3x.o \
iris_vpu4x.o \
iris_vpu_buffer.o \
iris_vpu_common.o \

Expand Down
95 changes: 95 additions & 0 deletions drivers/media/platform/qcom/iris/iris_ctrls.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,16 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
return PROFILE_AV1;
case V4L2_CID_MPEG_VIDEO_AV1_LEVEL:
return LEVEL_AV1;
case V4L2_CID_ROTATE:
return ROTATION;
case V4L2_CID_HFLIP:
return HFLIP;
case V4L2_CID_VFLIP:
return VFLIP;
case V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE:
return IR_TYPE;
case V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD:
return IR_PERIOD;
default:
return INST_FW_CAP_MAX;
}
Expand Down Expand Up @@ -193,6 +203,16 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
return V4L2_CID_MPEG_VIDEO_AV1_PROFILE;
case LEVEL_AV1:
return V4L2_CID_MPEG_VIDEO_AV1_LEVEL;
case ROTATION:
return V4L2_CID_ROTATE;
case HFLIP:
return V4L2_CID_HFLIP;
case VFLIP:
return V4L2_CID_VFLIP;
case IR_TYPE:
return V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE;
case IR_PERIOD:
return V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD;
default:
return 0;
}
Expand Down Expand Up @@ -901,6 +921,81 @@ int iris_set_qp_range(struct iris_inst *inst, enum platform_inst_fw_cap_type cap
&range, sizeof(range));
}

int iris_set_rotation(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
{
const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
u32 hfi_val;

switch (inst->fw_caps[cap_id].value) {
case 0:
hfi_val = HFI_ROTATION_NONE;
return 0;
case 90:
hfi_val = HFI_ROTATION_90;
break;
case 180:
hfi_val = HFI_ROTATION_180;
break;
case 270:
hfi_val = HFI_ROTATION_270;
break;
default:
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_val, sizeof(u32));
}

int iris_set_flip(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
{
const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
u32 hfi_val = HFI_DISABLE_FLIP;

if (inst->fw_caps[HFLIP].value)
hfi_val |= HFI_HORIZONTAL_FLIP;

if (inst->fw_caps[VFLIP].value)
hfi_val |= HFI_VERTICAL_FLIP;

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

int iris_set_ir_period(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
{
const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
struct vb2_queue *q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
u32 ir_period = inst->fw_caps[cap_id].value;
u32 ir_type = 0;

if (inst->fw_caps[IR_TYPE].value ==
V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM) {
if (vb2_is_streaming(q))
return 0;
ir_type = HFI_PROP_IR_RANDOM_PERIOD;
} else if (inst->fw_caps[IR_TYPE].value ==
V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC) {
ir_type = HFI_PROP_IR_CYCLIC_PERIOD;
} else {
return -EINVAL;
}

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

int iris_set_properties(struct iris_inst *inst, u32 plane)
{
const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
Expand Down
3 changes: 3 additions & 0 deletions drivers/media/platform/qcom/iris/iris_ctrls.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ int iris_set_min_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_i
int iris_set_max_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_frame_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_qp_range(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
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_properties(struct iris_inst *inst, u32 plane);

#endif
41 changes: 19 additions & 22 deletions drivers/media/platform/qcom/iris/iris_firmware.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
struct qcom_scm_pas_context *ctx;
const struct firmware *firmware = NULL;
struct device *dev = core->dev;
struct reserved_mem *rmem;
struct device_node *node;
struct resource res;
phys_addr_t mem_phys;
size_t res_size;
ssize_t fw_size;
Expand All @@ -36,17 +35,12 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
if (strlen(fw_name) >= MAX_FIRMWARE_NAME_SIZE - 4)
return -EINVAL;

node = of_parse_phandle(dev->of_node, "memory-region", 0);
if (!node)
return -EINVAL;

rmem = of_reserved_mem_lookup(node);
of_node_put(node);
if (!rmem)
return -EINVAL;
ret = of_reserved_mem_region_to_resource(dev->of_node, 0, &res);
if (ret)
return ret;

mem_phys = rmem->base;
res_size = rmem->size;
mem_phys = res.start;
res_size = resource_size(&res);

dev = core->fw.dev ? : core->dev;

Expand Down Expand Up @@ -104,9 +98,9 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)

int iris_fw_load(struct iris_core *core)
{
struct tz_cp_config *cp_config = core->iris_platform_data->tz_cp_config_data;
const struct tz_cp_config *cp_config;
const char *fwpath = NULL;
int ret;
int i, ret;

ret = of_property_read_string_index(core->dev->of_node, "firmware-name", 0,
&fwpath);
Expand All @@ -119,14 +113,17 @@ int iris_fw_load(struct iris_core *core)
return -ENOMEM;
}

ret = qcom_scm_mem_protect_video_var(cp_config->cp_start,
cp_config->cp_size,
cp_config->cp_nonpixel_start,
cp_config->cp_nonpixel_size);
if (ret) {
dev_err(core->dev, "protect memory failed\n");
iris_fw_unload(core);
return ret;
for (i = 0; i < core->iris_platform_data->tz_cp_config_data_size; i++) {
cp_config = &core->iris_platform_data->tz_cp_config_data[i];
ret = qcom_scm_mem_protect_video_var(cp_config->cp_start,
cp_config->cp_size,
cp_config->cp_nonpixel_start,
cp_config->cp_nonpixel_size);
if (ret) {
dev_err(core->dev, "qcom_scm_mem_protect_video_var failed: %d\n", ret);
iris_fw_unload(core);
return ret;
}
}

return ret;
Expand Down
Loading