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: rkvdec: Disable multicore support

Similarly to what is done in Hantro, avoid exposing equal video codecs to
userspace. Equal video codecs allow scheduling work between the cores.
For that kernel support is required, which does not yet exist.
Until that is implemented, avoid exposing each core separately to
userspace so that multicore can be added in the future without breaking
userspace ABI.

This currently applies only to RK3588 which has 2 equal VDPU381 decoders,
but will be applied for all SoC supported by rkvdec that has multiple DTS
nodes with the same compatible.

Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>

authored by

Detlev Casanova and committed by
Hans Verkuil
e570307a 6a846f7d

+47
+47
drivers/media/platform/rockchip/rkvdec/rkvdec.c
··· 1269 1269 } 1270 1270 } 1271 1271 1272 + /* 1273 + * Some SoCs, like RK3588 have multiple identical VDPU cores, but the 1274 + * kernel is currently missing support for multi-core handling. Exposing 1275 + * separate devices for each core to userspace is bad, since that does 1276 + * not allow scheduling tasks properly (and creates ABI). With this workaround 1277 + * the driver will only probe for the first core and early exit for the other 1278 + * cores. Once the driver gains multi-core support, the same technique 1279 + * for detecting the first core can be used to cluster all cores together. 1280 + */ 1281 + static int rkvdec_disable_multicore(struct rkvdec_dev *rkvdec) 1282 + { 1283 + struct device_node *node = NULL; 1284 + const char *compatible; 1285 + bool is_first_core; 1286 + int ret; 1287 + 1288 + /* Intentionally ignores the fallback strings */ 1289 + ret = of_property_read_string(rkvdec->dev->of_node, "compatible", &compatible); 1290 + if (ret) 1291 + return ret; 1292 + 1293 + /* The first compatible and available node found is considered the main core */ 1294 + do { 1295 + node = of_find_compatible_node(node, NULL, compatible); 1296 + if (of_device_is_available(node)) 1297 + break; 1298 + } while (node); 1299 + 1300 + if (!node) 1301 + return -EINVAL; 1302 + 1303 + is_first_core = (rkvdec->dev->of_node == node); 1304 + 1305 + of_node_put(node); 1306 + 1307 + if (!is_first_core) { 1308 + dev_info(rkvdec->dev, "missing multi-core support, ignoring this instance\n"); 1309 + return -ENODEV; 1310 + } 1311 + 1312 + return 0; 1313 + } 1314 + 1272 1315 static const struct rkvdec_variant_ops rk3399_variant_ops = { 1273 1316 .irq_handler = rk3399_irq_handler, 1274 1317 }; ··· 1374 1331 rkvdec->variant = variant; 1375 1332 mutex_init(&rkvdec->vdev_lock); 1376 1333 INIT_DELAYED_WORK(&rkvdec->watchdog_work, rkvdec_watchdog_func); 1334 + 1335 + ret = rkvdec_disable_multicore(rkvdec); 1336 + if (ret) 1337 + return ret; 1377 1338 1378 1339 ret = devm_clk_bulk_get_all_enabled(&pdev->dev, &rkvdec->clocks); 1379 1340 if (ret < 0)