Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

media: venus: Add support for static video encoder/decoder declarations

Add resource structure data and probe() logic to support static
declarations of encoder and decoder.

Right now we rely on video encoder/decoder selection happening in the dtb
but, this goes against the remit of device tree which is supposed to
describe hardware, not select functional logic in Linux drivers.

Provide two strings in the venus resource structure enc_nodename and
dec_nodename.

When set the venus driver will create an OF entry in-memory consistent
with:

dec_nodename {
compat = "video-decoder";
};

and/or

enc_nodename {
compat = "video-encoder";
};

This will allow us to reuse the existing driver scheme of relying on compat
names maintaining compatibility with old dtb files.

dec_nodename can be "video-decoder" or "video0"
enc_nodename can be "video-encoder" or "video1"

This change relies on of_changeset() API as a result select OF_DYNAMIC will
be added to venus/Kconfig

Tested-by: Renjiang Han <quic_renjiang@quicinc.com>
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Stanimir Varbanov <stanimir.k.varbanov@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>

authored by

Bryan O'Donoghue and committed by
Hans Verkuil
687bfbba daa7031a

+99 -1
+1
drivers/media/platform/qcom/venus/Kconfig
··· 3 3 depends on V4L_MEM2MEM_DRIVERS 4 4 depends on VIDEO_DEV && QCOM_SMEM 5 5 depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST 6 + select OF_DYNAMIC if ARCH_QCOM 6 7 select QCOM_MDT_LOADER if ARCH_QCOM 7 8 select QCOM_SCM 8 9 select VIDEOBUF2_DMA_CONTIG
+94 -1
drivers/media/platform/qcom/venus/core.c
··· 286 286 return ret; 287 287 } 288 288 289 + #if defined(CONFIG_OF_DYNAMIC) 290 + static int venus_add_video_core(struct venus_core *core, const char *node_name, 291 + const char *compat) 292 + { 293 + struct of_changeset *ocs = core->ocs; 294 + struct device *dev = core->dev; 295 + struct device_node *np, *enp; 296 + int ret; 297 + 298 + if (!node_name) 299 + return 0; 300 + 301 + enp = of_find_node_by_name(dev->of_node, node_name); 302 + if (enp) { 303 + of_node_put(enp); 304 + return 0; 305 + } 306 + 307 + np = of_changeset_create_node(ocs, dev->of_node, node_name); 308 + if (!np) { 309 + dev_err(dev, "Unable to create new node\n"); 310 + return -ENODEV; 311 + } 312 + 313 + ret = of_changeset_add_prop_string(ocs, np, "compatible", compat); 314 + if (ret) 315 + dev_err(dev, "unable to add %s\n", compat); 316 + 317 + of_node_put(np); 318 + 319 + return ret; 320 + } 321 + 322 + static int venus_add_dynamic_nodes(struct venus_core *core) 323 + { 324 + struct device *dev = core->dev; 325 + int ret; 326 + 327 + core->ocs = kmalloc(sizeof(*core->ocs), GFP_KERNEL); 328 + if (!core->ocs) 329 + return -ENOMEM; 330 + 331 + of_changeset_init(core->ocs); 332 + 333 + ret = venus_add_video_core(core, core->res->dec_nodename, "venus-decoder"); 334 + if (ret) 335 + goto err; 336 + 337 + ret = venus_add_video_core(core, core->res->enc_nodename, "venus-encoder"); 338 + if (ret) 339 + goto err; 340 + 341 + ret = of_changeset_apply(core->ocs); 342 + if (ret) { 343 + dev_err(dev, "applying changeset fail ret %d\n", ret); 344 + goto err; 345 + } 346 + 347 + return 0; 348 + err: 349 + of_changeset_destroy(core->ocs); 350 + kfree(core->ocs); 351 + core->ocs = NULL; 352 + return ret; 353 + } 354 + 355 + static void venus_remove_dynamic_nodes(struct venus_core *core) 356 + { 357 + if (core->ocs) { 358 + of_changeset_revert(core->ocs); 359 + of_changeset_destroy(core->ocs); 360 + kfree(core->ocs); 361 + } 362 + } 363 + #else 364 + static int venus_add_dynamic_nodes(struct venus_core *core) 365 + { 366 + return 0; 367 + } 368 + 369 + static void venus_remove_dynamic_nodes(struct venus_core *core) {} 370 + #endif 371 + 289 372 static int venus_probe(struct platform_device *pdev) 290 373 { 291 374 struct device *dev = &pdev->dev; ··· 448 365 if (ret < 0) 449 366 goto err_runtime_disable; 450 367 368 + if (core->res->dec_nodename || core->res->enc_nodename) { 369 + ret = venus_add_dynamic_nodes(core); 370 + if (ret) 371 + goto err_runtime_disable; 372 + } 373 + 451 374 ret = of_platform_populate(dev->of_node, NULL, NULL, dev); 452 375 if (ret) 453 - goto err_runtime_disable; 376 + goto err_remove_dynamic_nodes; 454 377 455 378 ret = venus_firmware_init(core); 456 379 if (ret) ··· 500 411 venus_firmware_deinit(core); 501 412 err_of_depopulate: 502 413 of_platform_depopulate(dev); 414 + err_remove_dynamic_nodes: 415 + venus_remove_dynamic_nodes(core); 503 416 err_runtime_disable: 504 417 pm_runtime_put_noidle(dev); 505 418 pm_runtime_disable(dev); ··· 533 442 of_platform_depopulate(dev); 534 443 535 444 venus_firmware_deinit(core); 445 + 446 + venus_remove_dynamic_nodes(core); 536 447 537 448 pm_runtime_put_sync(dev); 538 449 pm_runtime_disable(dev);
+4
drivers/media/platform/qcom/venus/core.h
··· 90 90 u32 cp_nonpixel_start; 91 91 u32 cp_nonpixel_size; 92 92 const char *fwname; 93 + const char *enc_nodename; 94 + const char *dec_nodename; 93 95 }; 94 96 95 97 enum venus_fmt { ··· 171 169 * @root: debugfs root directory 172 170 * @venus_ver: the venus firmware version 173 171 * @dump_core: a flag indicating that a core dump is required 172 + * @ocs: OF changeset pointer 174 173 */ 175 174 struct venus_core { 176 175 void __iomem *base; ··· 234 231 u32 rev; 235 232 } venus_ver; 236 233 unsigned long dump_core; 234 + struct of_changeset *ocs; 237 235 }; 238 236 239 237 struct vdec_controls {