diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-30 00:29:58 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-30 00:29:58 +0300 |
commit | 134bf98c5596605af90f104716ef912e8f7eb56b (patch) | |
tree | b41d585cc432100933e790ad8cab21e970e6d8f6 /drivers/media/platform | |
parent | 044ee890286153a1aefb40cb8b6659921aecb38b (diff) | |
parent | 3b796aa60af087f5fec75aee9b17f2130f2b9adc (diff) | |
download | linux-134bf98c5596605af90f104716ef912e8f7eb56b.tar.xz |
Merge tag 'media/v4.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
- new dvb frontend driver: lnbh29
- new sensor drivers: imx319 and imx 355
- some old soc_camera driver renames to avoid conflict with new
drivers
- new i.MX Pixel Pipeline (PXP) mem-to-mem platform driver
- a new V4L2 frontend for the FWHT codec
- several other improvements, bug fixes, code cleanups, etc
* tag 'media/v4.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (289 commits)
media: rename soc_camera I2C drivers
media: cec: forgot to cancel delayed work
media: vivid: Support 480p for webcam capture
media: v4l2-tpg: fix kernel oops when enabling HFLIP and OSD
media: vivid: Add 16-bit bayer to format list
media: v4l2-tpg-core: Add 16-bit bayer
media: pvrusb2: replace `printk` with `pr_*`
media: venus: vdec: fix decoded data size
media: cx231xx: fix potential sign-extension overflow on large shift
media: dt-bindings: media: rcar_vin: add device tree support for r8a7744
media: isif: fix a NULL pointer dereference bug
media: exynos4-is: make const array config_ids static
media: cx23885: make const array addr_list static
media: ivtv: make const array addr_list static
media: bttv-input: make const array addr_list static
media: cx18: Don't check for address of video_dev
media: dw9807-vcm: Fix probe error handling
media: dw9714: Remove useless error message
media: dw9714: Fix error handling in probe function
media: cec: name for RC passthrough device does not need 'RC for'
...
Diffstat (limited to 'drivers/media/platform')
122 files changed, 5075 insertions, 1042 deletions
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 54fe90acb5b2..70c4f6c54881 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -58,6 +58,7 @@ config VIDEO_MUX select MULTIPLEXER depends on VIDEO_V4L2 && OF && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER select REGMAP + select V4L2_FWNODE help This driver provides support for N:1 video bus multiplexers. @@ -181,6 +182,15 @@ config VIDEO_CODA config VIDEO_IMX_VDOA def_tristate VIDEO_CODA if SOC_IMX6Q || COMPILE_TEST +config VIDEO_IMX_PXP + tristate "i.MX Pixel Pipeline (PXP)" + depends on VIDEO_DEV && VIDEO_V4L2 && (ARCH_MXC || COMPILE_TEST) + select VIDEOBUF2_DMA_CONTIG + select V4L2_MEM2MEM_DEV + help + The i.MX Pixel Pipeline is a memory-to-memory engine for scaling, + color space conversion, and rotation. + config VIDEO_MEDIATEK_JPEG tristate "Mediatek JPEG Codec driver" depends on MTK_IOMMU_V1 || COMPILE_TEST diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 41322ab65802..6ab6200dd9c9 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -25,6 +25,8 @@ obj-$(CONFIG_VIDEO_TI_CAL) += ti-vpe/ obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o obj-$(CONFIG_VIDEO_CODA) += coda/ +obj-$(CONFIG_VIDEO_IMX_PXP) += imx-pxp.o + obj-$(CONFIG_VIDEO_SH_VEU) += sh_veu.o obj-$(CONFIG_CEC_GPIO) += cec-gpio/ diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c index b05738a95e55..e13d2b3a7168 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.c +++ b/drivers/media/platform/am437x/am437x-vpfe.c @@ -1408,8 +1408,8 @@ static int vpfe_querycap(struct file *file, void *priv, vpfe_dbg(2, vpfe, "vpfe_querycap\n"); - strlcpy(cap->driver, VPFE_MODULE_NAME, sizeof(cap->driver)); - strlcpy(cap->card, "TI AM437x VPFE", sizeof(cap->card)); + strscpy(cap->driver, VPFE_MODULE_NAME, sizeof(cap->driver)); + strscpy(cap->card, "TI AM437x VPFE", sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", vpfe->v4l2_dev.name); cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | @@ -2386,7 +2386,7 @@ static int vpfe_probe_complete(struct vpfe_device *vpfe) INIT_LIST_HEAD(&vpfe->dma_queue); vdev = &vpfe->video_dev; - strlcpy(vdev->name, VPFE_MODULE_NAME, sizeof(vdev->name)); + strscpy(vdev->name, VPFE_MODULE_NAME, sizeof(vdev->name)); vdev->release = video_device_release_empty; vdev->fops = &vpfe_fops; vdev->ioctl_ops = &vpfe_ioctl_ops; @@ -2423,30 +2423,32 @@ static const struct v4l2_async_notifier_operations vpfe_async_ops = { }; static struct vpfe_config * -vpfe_get_pdata(struct platform_device *pdev) +vpfe_get_pdata(struct vpfe_device *vpfe) { struct device_node *endpoint = NULL; - struct v4l2_fwnode_endpoint bus_cfg; + struct device *dev = vpfe->pdev; struct vpfe_subdev_info *sdinfo; struct vpfe_config *pdata; unsigned int flags; unsigned int i; int err; - dev_dbg(&pdev->dev, "vpfe_get_pdata\n"); + dev_dbg(dev, "vpfe_get_pdata\n"); - if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node) - return pdev->dev.platform_data; + v4l2_async_notifier_init(&vpfe->notifier); - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!IS_ENABLED(CONFIG_OF) || !dev->of_node) + return dev->platform_data; + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return NULL; for (i = 0; ; i++) { + struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; struct device_node *rem; - endpoint = of_graph_get_next_endpoint(pdev->dev.of_node, - endpoint); + endpoint = of_graph_get_next_endpoint(dev->of_node, endpoint); if (!endpoint) break; @@ -2455,7 +2457,8 @@ vpfe_get_pdata(struct platform_device *pdev) /* we only support camera */ sdinfo->inputs[0].index = i; - strcpy(sdinfo->inputs[0].name, "Camera"); + strscpy(sdinfo->inputs[0].name, "Camera", + sizeof(sdinfo->inputs[0].name)); sdinfo->inputs[0].type = V4L2_INPUT_TYPE_CAMERA; sdinfo->inputs[0].std = V4L2_STD_ALL; sdinfo->inputs[0].capabilities = V4L2_IN_CAP_STD; @@ -2473,16 +2476,16 @@ vpfe_get_pdata(struct platform_device *pdev) err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), &bus_cfg); if (err) { - dev_err(&pdev->dev, "Could not parse the endpoint\n"); - goto done; + dev_err(dev, "Could not parse the endpoint\n"); + goto cleanup; } sdinfo->vpfe_param.bus_width = bus_cfg.bus.parallel.bus_width; if (sdinfo->vpfe_param.bus_width < 8 || sdinfo->vpfe_param.bus_width > 16) { - dev_err(&pdev->dev, "Invalid bus width.\n"); - goto done; + dev_err(dev, "Invalid bus width.\n"); + goto cleanup; } flags = bus_cfg.bus.parallel.flags; @@ -2495,29 +2498,25 @@ vpfe_get_pdata(struct platform_device *pdev) rem = of_graph_get_remote_port_parent(endpoint); if (!rem) { - dev_err(&pdev->dev, "Remote device at %pOF not found\n", + dev_err(dev, "Remote device at %pOF not found\n", endpoint); - goto done; + goto cleanup; } - pdata->asd[i] = devm_kzalloc(&pdev->dev, - sizeof(struct v4l2_async_subdev), - GFP_KERNEL); - if (!pdata->asd[i]) { + pdata->asd[i] = v4l2_async_notifier_add_fwnode_subdev( + &vpfe->notifier, of_fwnode_handle(rem), + sizeof(struct v4l2_async_subdev)); + if (IS_ERR(pdata->asd[i])) { of_node_put(rem); - pdata = NULL; - goto done; + goto cleanup; } - - pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_FWNODE; - pdata->asd[i]->match.fwnode = of_fwnode_handle(rem); - of_node_put(rem); } of_node_put(endpoint); return pdata; -done: +cleanup: + v4l2_async_notifier_cleanup(&vpfe->notifier); of_node_put(endpoint); return NULL; } @@ -2529,34 +2528,39 @@ done: */ static int vpfe_probe(struct platform_device *pdev) { - struct vpfe_config *vpfe_cfg = vpfe_get_pdata(pdev); + struct vpfe_config *vpfe_cfg; struct vpfe_device *vpfe; struct vpfe_ccdc *ccdc; struct resource *res; int ret; - if (!vpfe_cfg) { - dev_err(&pdev->dev, "No platform data\n"); - return -EINVAL; - } - vpfe = devm_kzalloc(&pdev->dev, sizeof(*vpfe), GFP_KERNEL); if (!vpfe) return -ENOMEM; vpfe->pdev = &pdev->dev; + + vpfe_cfg = vpfe_get_pdata(vpfe); + if (!vpfe_cfg) { + dev_err(&pdev->dev, "No platform data\n"); + return -EINVAL; + } + vpfe->cfg = vpfe_cfg; ccdc = &vpfe->ccdc; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ccdc->ccdc_cfg.base_addr = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(ccdc->ccdc_cfg.base_addr)) - return PTR_ERR(ccdc->ccdc_cfg.base_addr); + if (IS_ERR(ccdc->ccdc_cfg.base_addr)) { + ret = PTR_ERR(ccdc->ccdc_cfg.base_addr); + goto probe_out_cleanup; + } ret = platform_get_irq(pdev, 0); if (ret <= 0) { dev_err(&pdev->dev, "No IRQ resource\n"); - return -ENODEV; + ret = -ENODEV; + goto probe_out_cleanup; } vpfe->irq = ret; @@ -2564,14 +2568,15 @@ static int vpfe_probe(struct platform_device *pdev) "vpfe_capture0", vpfe); if (ret) { dev_err(&pdev->dev, "Unable to request interrupt\n"); - return -EINVAL; + ret = -EINVAL; + goto probe_out_cleanup; } ret = v4l2_device_register(&pdev->dev, &vpfe->v4l2_dev); if (ret) { vpfe_err(vpfe, "Unable to register v4l2 device.\n"); - return ret; + goto probe_out_cleanup; } /* set the driver data in platform device */ @@ -2595,11 +2600,8 @@ static int vpfe_probe(struct platform_device *pdev) goto probe_out_v4l2_unregister; } - vpfe->notifier.subdevs = vpfe->cfg->asd; - vpfe->notifier.num_subdevs = ARRAY_SIZE(vpfe->cfg->asd); vpfe->notifier.ops = &vpfe_async_ops; - ret = v4l2_async_notifier_register(&vpfe->v4l2_dev, - &vpfe->notifier); + ret = v4l2_async_notifier_register(&vpfe->v4l2_dev, &vpfe->notifier); if (ret) { vpfe_err(vpfe, "Error registering async notifier\n"); ret = -EINVAL; @@ -2610,6 +2612,8 @@ static int vpfe_probe(struct platform_device *pdev) probe_out_v4l2_unregister: v4l2_device_unregister(&vpfe->v4l2_dev); +probe_out_cleanup: + v4l2_async_notifier_cleanup(&vpfe->notifier); return ret; } @@ -2625,6 +2629,7 @@ static int vpfe_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); v4l2_async_notifier_unregister(&vpfe->notifier); + v4l2_async_notifier_cleanup(&vpfe->notifier); v4l2_device_unregister(&vpfe->v4l2_dev); video_unregister_device(&vpfe->video_dev); diff --git a/drivers/media/platform/atmel/atmel-isc.c b/drivers/media/platform/atmel/atmel-isc.c index d89e14524d42..50178968b8a6 100644 --- a/drivers/media/platform/atmel/atmel-isc.c +++ b/drivers/media/platform/atmel/atmel-isc.c @@ -1238,8 +1238,8 @@ static int isc_querycap(struct file *file, void *priv, { struct isc_device *isc = video_drvdata(file); - strcpy(cap->driver, ATMEL_ISC_NAME); - strcpy(cap->card, "Atmel Image Sensor Controller"); + strscpy(cap->driver, ATMEL_ISC_NAME, sizeof(cap->driver)); + strscpy(cap->card, "Atmel Image Sensor Controller", sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", isc->v4l2_dev.name); @@ -1393,7 +1393,7 @@ static int isc_enum_input(struct file *file, void *priv, inp->type = V4L2_INPUT_TYPE_CAMERA; inp->std = 0; - strcpy(inp->name, "Camera"); + strscpy(inp->name, "Camera", sizeof(inp->name)); return 0; } @@ -1951,7 +1951,7 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier) INIT_WORK(&isc->awb_work, isc_awb_work); /* Register video device */ - strlcpy(vdev->name, ATMEL_ISC_NAME, sizeof(vdev->name)); + strscpy(vdev->name, ATMEL_ISC_NAME, sizeof(vdev->name)); vdev->release = video_device_release_empty; vdev->fops = &isc_fops; vdev->ioctl_ops = &isc_ioctl_ops; @@ -1983,8 +1983,10 @@ static void isc_subdev_cleanup(struct isc_device *isc) { struct isc_subdev_entity *subdev_entity; - list_for_each_entry(subdev_entity, &isc->subdev_entities, list) + list_for_each_entry(subdev_entity, &isc->subdev_entities, list) { v4l2_async_notifier_unregister(&subdev_entity->notifier); + v4l2_async_notifier_cleanup(&subdev_entity->notifier); + } INIT_LIST_HEAD(&isc->subdev_entities); } @@ -2026,7 +2028,6 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc) { struct device_node *np = dev->of_node; struct device_node *epn = NULL, *rem; - struct v4l2_fwnode_endpoint v4l2_epn; struct isc_subdev_entity *subdev_entity; unsigned int flags; int ret; @@ -2034,6 +2035,8 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc) INIT_LIST_HEAD(&isc->subdev_entities); while (1) { + struct v4l2_fwnode_endpoint v4l2_epn = { .bus_type = 0 }; + epn = of_graph_get_next_endpoint(np, epn); if (!epn) return 0; @@ -2201,8 +2204,15 @@ static int atmel_isc_probe(struct platform_device *pdev) } list_for_each_entry(subdev_entity, &isc->subdev_entities, list) { - subdev_entity->notifier.subdevs = &subdev_entity->asd; - subdev_entity->notifier.num_subdevs = 1; + v4l2_async_notifier_init(&subdev_entity->notifier); + + ret = v4l2_async_notifier_add_subdev(&subdev_entity->notifier, + subdev_entity->asd); + if (ret) { + fwnode_handle_put(subdev_entity->asd->match.fwnode); + goto cleanup_subdev; + } + subdev_entity->notifier.ops = &isc_async_ops; ret = v4l2_async_notifier_register(&isc->v4l2_dev, diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c index e8db4df1e7c4..fdb255e4a956 100644 --- a/drivers/media/platform/atmel/atmel-isi.c +++ b/drivers/media/platform/atmel/atmel-isi.c @@ -655,9 +655,9 @@ static int isi_enum_fmt_vid_cap(struct file *file, void *priv, static int isi_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - strlcpy(cap->driver, "atmel-isi", sizeof(cap->driver)); - strlcpy(cap->card, "Atmel Image Sensor Interface", sizeof(cap->card)); - strlcpy(cap->bus_info, "platform:isi", sizeof(cap->bus_info)); + strscpy(cap->driver, "atmel-isi", sizeof(cap->driver)); + strscpy(cap->card, "Atmel Image Sensor Interface", sizeof(cap->card)); + strscpy(cap->bus_info, "platform:isi", sizeof(cap->bus_info)); return 0; } @@ -668,7 +668,7 @@ static int isi_enum_input(struct file *file, void *priv, return -EINVAL; i->type = V4L2_INPUT_TYPE_CAMERA; - strlcpy(i->name, "Camera", sizeof(i->name)); + strscpy(i->name, "Camera", sizeof(i->name)); return 0; } @@ -790,7 +790,7 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi, struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; - struct v4l2_fwnode_endpoint ep; + struct v4l2_fwnode_endpoint ep = { .bus_type = 0 }; int err; /* Default settings for ISI */ @@ -1124,7 +1124,6 @@ static int isi_graph_parse(struct atmel_isi *isi, struct device_node *node) static int isi_graph_init(struct atmel_isi *isi) { - struct v4l2_async_subdev **subdevs = NULL; int ret; /* Parse the graph to extract a list of subdevice DT nodes. */ @@ -1134,23 +1133,20 @@ static int isi_graph_init(struct atmel_isi *isi) return ret; } - /* Register the subdevices notifier. */ - subdevs = devm_kzalloc(isi->dev, sizeof(*subdevs), GFP_KERNEL); - if (!subdevs) { + v4l2_async_notifier_init(&isi->notifier); + + ret = v4l2_async_notifier_add_subdev(&isi->notifier, &isi->entity.asd); + if (ret) { of_node_put(isi->entity.node); - return -ENOMEM; + return ret; } - subdevs[0] = &isi->entity.asd; - - isi->notifier.subdevs = subdevs; - isi->notifier.num_subdevs = 1; isi->notifier.ops = &isi_graph_notify_ops; ret = v4l2_async_notifier_register(&isi->v4l2_dev, &isi->notifier); if (ret < 0) { dev_err(isi->dev, "Notifier registration failed\n"); - of_node_put(isi->entity.node); + v4l2_async_notifier_cleanup(&isi->notifier); return ret; } @@ -1202,7 +1198,7 @@ static int atmel_isi_probe(struct platform_device *pdev) isi->vdev->fops = &isi_fops; isi->vdev->v4l2_dev = &isi->v4l2_dev; isi->vdev->queue = &isi->queue; - strlcpy(isi->vdev->name, KBUILD_MODNAME, sizeof(isi->vdev->name)); + strscpy(isi->vdev->name, KBUILD_MODNAME, sizeof(isi->vdev->name)); isi->vdev->release = video_device_release; isi->vdev->ioctl_ops = &isi_ioctl_ops; isi->vdev->lock = &isi->lock; @@ -1303,6 +1299,7 @@ static int atmel_isi_remove(struct platform_device *pdev) isi->fb_descriptors_phys); pm_runtime_disable(&pdev->dev); v4l2_async_notifier_unregister(&isi->notifier); + v4l2_async_notifier_cleanup(&isi->notifier); v4l2_device_unregister(&isi->v4l2_dev); return 0; diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c index 43e43c7b3e98..31ace114eda1 100644 --- a/drivers/media/platform/cadence/cdns-csi2rx.c +++ b/drivers/media/platform/cadence/cdns-csi2rx.c @@ -361,7 +361,7 @@ static int csi2rx_get_resources(struct csi2rx_priv *csi2rx, static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx) { - struct v4l2_fwnode_endpoint v4l2_ep; + struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 }; struct fwnode_handle *fwh; struct device_node *ep; int ret; @@ -378,7 +378,7 @@ static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx) return ret; } - if (v4l2_ep.bus_type != V4L2_MBUS_CSI2) { + if (v4l2_ep.bus_type != V4L2_MBUS_CSI2_DPHY) { dev_err(csi2rx->dev, "Unsupported media bus type: 0x%x\n", v4l2_ep.bus_type); of_node_put(ep); @@ -399,18 +399,22 @@ static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx) csi2rx->asd.match_type = V4L2_ASYNC_MATCH_FWNODE; of_node_put(ep); - csi2rx->notifier.subdevs = devm_kzalloc(csi2rx->dev, - sizeof(*csi2rx->notifier.subdevs), - GFP_KERNEL); - if (!csi2rx->notifier.subdevs) - return -ENOMEM; + v4l2_async_notifier_init(&csi2rx->notifier); + + ret = v4l2_async_notifier_add_subdev(&csi2rx->notifier, &csi2rx->asd); + if (ret) { + fwnode_handle_put(csi2rx->asd.match.fwnode); + return ret; + } - csi2rx->notifier.subdevs[0] = &csi2rx->asd; - csi2rx->notifier.num_subdevs = 1; csi2rx->notifier.ops = &csi2rx_notifier_ops; - return v4l2_async_subdev_notifier_register(&csi2rx->subdev, - &csi2rx->notifier); + ret = v4l2_async_subdev_notifier_register(&csi2rx->subdev, + &csi2rx->notifier); + if (ret) + v4l2_async_notifier_cleanup(&csi2rx->notifier); + + return ret; } static int csi2rx_probe(struct platform_device *pdev) @@ -450,11 +454,11 @@ static int csi2rx_probe(struct platform_device *pdev) ret = media_entity_pads_init(&csi2rx->subdev.entity, CSI2RX_PAD_MAX, csi2rx->pads); if (ret) - goto err_free_priv; + goto err_cleanup; ret = v4l2_async_register_subdev(&csi2rx->subdev); if (ret < 0) - goto err_free_priv; + goto err_cleanup; dev_info(&pdev->dev, "Probed CSI2RX with %u/%u lanes, %u streams, %s D-PHY\n", @@ -463,6 +467,8 @@ static int csi2rx_probe(struct platform_device *pdev) return 0; +err_cleanup: + v4l2_async_notifier_cleanup(&csi2rx->notifier); err_free_priv: kfree(csi2rx); return ret; diff --git a/drivers/media/platform/cadence/cdns-csi2tx.c b/drivers/media/platform/cadence/cdns-csi2tx.c index 40d0de690ff4..5042d053b94e 100644 --- a/drivers/media/platform/cadence/cdns-csi2tx.c +++ b/drivers/media/platform/cadence/cdns-csi2tx.c @@ -432,7 +432,7 @@ static int csi2tx_get_resources(struct csi2tx_priv *csi2tx, static int csi2tx_check_lanes(struct csi2tx_priv *csi2tx) { - struct v4l2_fwnode_endpoint v4l2_ep; + struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 }; struct device_node *ep; int ret; @@ -446,7 +446,7 @@ static int csi2tx_check_lanes(struct csi2tx_priv *csi2tx) goto out; } - if (v4l2_ep.bus_type != V4L2_MBUS_CSI2) { + if (v4l2_ep.bus_type != V4L2_MBUS_CSI2_DPHY) { dev_err(csi2tx->dev, "Unsupported media bus type: 0x%x\n", v4l2_ep.bus_type); ret = -EINVAL; diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 726b3b93a486..2848ea5f464d 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -376,8 +376,7 @@ static struct vdoa_data *coda_get_vdoa_data(void) vdoa_data = ERR_PTR(-EPROBE_DEFER); out: - if (vdoa_node) - of_node_put(vdoa_node); + of_node_put(vdoa_node); return vdoa_data; } @@ -390,10 +389,10 @@ static int coda_querycap(struct file *file, void *priv, { struct coda_ctx *ctx = fh_to_ctx(priv); - strlcpy(cap->driver, CODA_NAME, sizeof(cap->driver)); - strlcpy(cap->card, coda_product_name(ctx->dev->devtype->product), + strscpy(cap->driver, CODA_NAME, sizeof(cap->driver)); + strscpy(cap->card, coda_product_name(ctx->dev->devtype->product), sizeof(cap->card)); - strlcpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info)); + strscpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info)); cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; @@ -1804,7 +1803,8 @@ static int coda_s_ctrl(struct v4l2_ctrl *ctrl) break; case V4L2_CID_MPEG_VIDEO_H264_PROFILE: /* TODO: switch between baseline and constrained baseline */ - ctx->params.h264_profile_idc = 66; + if (ctx->inst_type == CODA_INST_ENCODER) + ctx->params.h264_profile_idc = 66; break; case V4L2_CID_MPEG_VIDEO_H264_LEVEL: /* nothing to do, this is set by the encoder */ @@ -2408,7 +2408,7 @@ static int coda_register_device(struct coda_dev *dev, int i) if (i >= dev->devtype->num_vdevs) return -EINVAL; - strlcpy(vfd->name, dev->devtype->vdevs[i]->name, sizeof(vfd->name)); + strscpy(vfd->name, dev->devtype->vdevs[i]->name, sizeof(vfd->name)); vfd->fops = &coda_fops; vfd->ioctl_ops = &coda_ioctl_ops; vfd->release = video_device_release_empty, diff --git a/drivers/media/platform/davinci/isif.c b/drivers/media/platform/davinci/isif.c index f924e76e2fbf..340f8218f54d 100644 --- a/drivers/media/platform/davinci/isif.c +++ b/drivers/media/platform/davinci/isif.c @@ -1100,7 +1100,8 @@ fail_nobase_res: while (i >= 0) { res = platform_get_resource(pdev, IORESOURCE_MEM, i); - release_mem_region(res->start, resource_size(res)); + if (res) + release_mem_region(res->start, resource_size(res)); i--; } vpfe_unregister_ccdc_device(&isif_hw_dev); diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index b0eb3d899eb4..5c235898af7b 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -521,7 +521,7 @@ vpbe_disp_calculate_scale_factor(struct vpbe_display *disp_dev, else if (v_scale == 4) layer_info->v_zoom = ZOOM_X4; if (v_exp) - layer_info->h_exp = V_EXP_6_OVER_5; + layer_info->v_exp = V_EXP_6_OVER_5; } else { /* no scaling, only cropping. Set display area to crop area */ cfg->ysize = expected_ysize; @@ -647,7 +647,7 @@ static int vpbe_display_querycap(struct file *file, void *priv, dev_name(vpbe_dev->pdev)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(vpbe_dev->pdev)); - strlcpy(cap->card, vpbe_dev->cfg->module_name, sizeof(cap->card)); + strscpy(cap->card, vpbe_dev->cfg->module_name, sizeof(cap->card)); return 0; } @@ -816,10 +816,12 @@ static int vpbe_display_enum_fmt(struct file *file, void *priv, fmt->index = index; fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; if (index == 0) { - strcpy(fmt->description, "YUV 4:2:2 - UYVY"); + strscpy(fmt->description, "YUV 4:2:2 - UYVY", + sizeof(fmt->description)); fmt->pixelformat = V4L2_PIX_FMT_UYVY; } else { - strcpy(fmt->description, "Y/CbCr 4:2:0"); + strscpy(fmt->description, "Y/CbCr 4:2:0", + sizeof(fmt->description)); fmt->pixelformat = V4L2_PIX_FMT_NV12; } diff --git a/drivers/media/platform/davinci/vpbe_venc.c b/drivers/media/platform/davinci/vpbe_venc.c index ddcad7b3e76c..ca78eb29641a 100644 --- a/drivers/media/platform/davinci/vpbe_venc.c +++ b/drivers/media/platform/davinci/vpbe_venc.c @@ -616,7 +616,7 @@ struct v4l2_subdev *venc_sub_dev_init(struct v4l2_device *v4l2_dev, v4l2_subdev_init(&venc->sd, &venc_ops); - strcpy(venc->sd.name, venc_name); + strscpy(venc->sd.name, venc_name, sizeof(venc->sd.name)); if (v4l2_device_register_subdev(v4l2_dev, &venc->sd) < 0) { v4l2_err(v4l2_dev, "vpbe unable to register venc sub device\n"); diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 8613358ed245..ea3ddd5a42bd 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -889,9 +889,9 @@ static int vpfe_querycap(struct file *file, void *priv, cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; - strlcpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver)); - strlcpy(cap->bus_info, "VPFE", sizeof(cap->bus_info)); - strlcpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card)); + strscpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver)); + strscpy(cap->bus_info, "VPFE", sizeof(cap->bus_info)); + strscpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card)); return 0; } diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index a96f53ce8088..6216b7ac6875 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -949,11 +949,13 @@ static int vpif_enum_fmt_vid_cap(struct file *file, void *priv, /* Fill in the information about format */ if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER) { fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - strcpy(fmt->description, "Raw Mode -Bayer Pattern GrRBGb"); + strscpy(fmt->description, "Raw Mode -Bayer Pattern GrRBGb", + sizeof(fmt->description)); fmt->pixelformat = V4L2_PIX_FMT_SBGGR8; } else { fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - strcpy(fmt->description, "YCbCr4:2:2 Semi-Planar"); + strscpy(fmt->description, "YCbCr4:2:2 Semi-Planar", + sizeof(fmt->description)); fmt->pixelformat = V4L2_PIX_FMT_NV16; } return 0; @@ -1094,10 +1096,10 @@ static int vpif_querycap(struct file *file, void *priv, cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; - strlcpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver)); + strscpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(vpif_dev)); - strlcpy(cap->card, config->card_name, sizeof(cap->card)); + strscpy(cap->card, config->card_name, sizeof(cap->card)); return 0; } @@ -1463,7 +1465,7 @@ static int vpif_probe_complete(void) /* Initialize the video_device structure */ vdev = &ch->video_dev; - strlcpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name)); + strscpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name)); vdev->release = video_device_release_empty; vdev->fops = &vpif_fops; vdev->ioctl_ops = &vpif_ioctl_ops; @@ -1509,12 +1511,13 @@ static struct vpif_capture_config * vpif_capture_get_pdata(struct platform_device *pdev) { struct device_node *endpoint = NULL; - struct v4l2_fwnode_endpoint bus_cfg; struct vpif_capture_config *pdata; struct vpif_subdev_info *sdinfo; struct vpif_capture_chan_config *chan; unsigned int i; + v4l2_async_notifier_init(&vpif_obj.notifier); + /* * DT boot: OF node from parent device contains * video ports & endpoints data. @@ -1537,6 +1540,7 @@ vpif_capture_get_pdata(struct platform_device *pdev) return NULL; for (i = 0; i < VPIF_CAPTURE_NUM_CHANNELS; i++) { + struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; struct device_node *rem; unsigned int flags; int err; @@ -1546,14 +1550,25 @@ vpif_capture_get_pdata(struct platform_device *pdev) if (!endpoint) break; + rem = of_graph_get_remote_port_parent(endpoint); + if (!rem) { + dev_dbg(&pdev->dev, "Remote device at %pOF not found\n", + endpoint); + of_node_put(endpoint); + goto done; + } + sdinfo = &pdata->subdev_info[i]; chan = &pdata->chan_config[i]; chan->inputs = devm_kcalloc(&pdev->dev, VPIF_CAPTURE_NUM_CHANNELS, sizeof(*chan->inputs), GFP_KERNEL); - if (!chan->inputs) - return NULL; + if (!chan->inputs) { + of_node_put(rem); + of_node_put(endpoint); + goto err_cleanup; + } chan->input_count++; chan->inputs[i].input.type = V4L2_INPUT_TYPE_CAMERA; @@ -1562,12 +1577,16 @@ vpif_capture_get_pdata(struct platform_device *pdev) err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), &bus_cfg); + of_node_put(endpoint); if (err) { dev_err(&pdev->dev, "Could not parse the endpoint\n"); + of_node_put(rem); goto done; } + dev_dbg(&pdev->dev, "Endpoint %pOF, bus_width = %d\n", endpoint, bus_cfg.bus.parallel.bus_width); + flags = bus_cfg.bus.parallel.flags; if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) @@ -1576,39 +1595,29 @@ vpif_capture_get_pdata(struct platform_device *pdev) if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) chan->vpif_if.vd_pol = 1; - rem = of_graph_get_remote_port_parent(endpoint); - if (!rem) { - dev_dbg(&pdev->dev, "Remote device at %pOF not found\n", - endpoint); - goto done; - } - - dev_dbg(&pdev->dev, "Remote device %s, %pOF found\n", - rem->name, rem); + dev_dbg(&pdev->dev, "Remote device %pOF found\n", rem); sdinfo->name = rem->full_name; - pdata->asd[i] = devm_kzalloc(&pdev->dev, - sizeof(struct v4l2_async_subdev), - GFP_KERNEL); - if (!pdata->asd[i]) { + pdata->asd[i] = v4l2_async_notifier_add_fwnode_subdev( + &vpif_obj.notifier, of_fwnode_handle(rem), + sizeof(struct v4l2_async_subdev)); + if (IS_ERR(pdata->asd[i])) { of_node_put(rem); - pdata = NULL; - goto done; + goto err_cleanup; } - - pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_FWNODE; - pdata->asd[i]->match.fwnode = of_fwnode_handle(rem); - of_node_put(rem); } done: - if (pdata) { - pdata->asd_sizes[0] = i; - pdata->subdev_count = i; - pdata->card_name = "DA850/OMAP-L138 Video Capture"; - } + pdata->asd_sizes[0] = i; + pdata->subdev_count = i; + pdata->card_name = "DA850/OMAP-L138 Video Capture"; return pdata; + +err_cleanup: + v4l2_async_notifier_cleanup(&vpif_obj.notifier); + + return NULL; } /** @@ -1633,23 +1642,18 @@ static __init int vpif_probe(struct platform_device *pdev) return -EINVAL; } - if (!pdev->dev.platform_data) { - dev_warn(&pdev->dev, "Missing platform data. Giving up.\n"); - return -EINVAL; - } - vpif_dev = &pdev->dev; err = initialize_vpif(); if (err) { v4l2_err(vpif_dev->driver, "Error initializing vpif\n"); - return err; + goto cleanup; } err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev); if (err) { v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n"); - return err; + goto cleanup; } while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) { @@ -1698,8 +1702,6 @@ static __init int vpif_probe(struct platform_device *pdev) } vpif_probe_complete(); } else { - vpif_obj.notifier.subdevs = vpif_obj.config->asd; - vpif_obj.notifier.num_subdevs = vpif_obj.config->asd_sizes[0]; vpif_obj.notifier.ops = &vpif_async_ops; err = v4l2_async_notifier_register(&vpif_obj.v4l2_dev, &vpif_obj.notifier); @@ -1717,6 +1719,8 @@ probe_subdev_out: kfree(vpif_obj.sd); vpif_unregister: v4l2_device_unregister(&vpif_obj.v4l2_dev); +cleanup: + v4l2_async_notifier_cleanup(&vpif_obj.notifier); return err; } @@ -1732,6 +1736,8 @@ static int vpif_remove(struct platform_device *device) struct channel_obj *ch; int i; + v4l2_async_notifier_unregister(&vpif_obj.notifier); + v4l2_async_notifier_cleanup(&vpif_obj.notifier); v4l2_device_unregister(&vpif_obj.v4l2_dev); kfree(vpif_obj.sd); diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index 0f324055cc9f..3517487d9760 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c @@ -586,10 +586,10 @@ static int vpif_querycap(struct file *file, void *priv, cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; - strlcpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver)); + strscpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(vpif_dev)); - strlcpy(cap->card, config->card_name, sizeof(cap->card)); + strscpy(cap->card, config->card_name, sizeof(cap->card)); return 0; } @@ -602,7 +602,8 @@ static int vpif_enum_fmt_vid_out(struct file *file, void *priv, /* Fill in the information about format */ fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - strcpy(fmt->description, "YCbCr4:2:2 YC Planar"); + strscpy(fmt->description, "YCbCr4:2:2 YC Planar", + sizeof(fmt->description)); fmt->pixelformat = V4L2_PIX_FMT_YUV422P; fmt->flags = 0; return 0; @@ -1209,7 +1210,7 @@ static int vpif_probe_complete(void) /* Initialize the video_device structure */ vdev = &ch->video_dev; - strlcpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name)); + strscpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name)); vdev->release = video_device_release_empty; vdev->fops = &vpif_fops; vdev->ioctl_ops = &vpif_ioctl_ops; @@ -1299,6 +1300,8 @@ static __init int vpif_probe(struct platform_device *pdev) goto vpif_unregister; } + v4l2_async_notifier_init(&vpif_obj.notifier); + if (!vpif_obj.config->asd_sizes) { i2c_adap = i2c_get_adapter(vpif_obj.config->i2c_adapter_id); for (i = 0; i < subdev_count; i++) { @@ -1322,20 +1325,27 @@ static __init int vpif_probe(struct platform_device *pdev) goto probe_subdev_out; } } else { - vpif_obj.notifier.subdevs = vpif_obj.config->asd; - vpif_obj.notifier.num_subdevs = vpif_obj.config->asd_sizes[0]; + for (i = 0; i < vpif_obj.config->asd_sizes[0]; i++) { + err = v4l2_async_notifier_add_subdev( + &vpif_obj.notifier, vpif_obj.config->asd[i]); + if (err) + goto probe_cleanup; + } + vpif_obj.notifier.ops = &vpif_async_ops; err = v4l2_async_notifier_register(&vpif_obj.v4l2_dev, &vpif_obj.notifier); if (err) { vpif_err("Error registering async notifier\n"); err = -EINVAL; - goto probe_subdev_out; + goto probe_cleanup; } } return 0; +probe_cleanup: + v4l2_async_notifier_cleanup(&vpif_obj.notifier); probe_subdev_out: kfree(vpif_obj.sd); vpif_unregister: @@ -1354,6 +1364,11 @@ static int vpif_remove(struct platform_device *device) struct channel_obj *ch; int i; + if (vpif_obj.config->asd_sizes) { + v4l2_async_notifier_unregister(&vpif_obj.notifier); + v4l2_async_notifier_cleanup(&vpif_obj.notifier); + } + v4l2_device_unregister(&vpif_obj.v4l2_dev); kfree(vpif_obj.sd); diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index 17854a379243..838c5c53de37 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -339,7 +339,7 @@ int gsc_enum_fmt_mplane(struct v4l2_fmtdesc *f) if (!fmt) return -EINVAL; - strlcpy(f->description, fmt->name, sizeof(f->description)); + strscpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->pixelformat; return 0; diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c index c9d2f6c5311a..cc5d690818e1 100644 --- a/drivers/media/platform/exynos-gsc/gsc-m2m.c +++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c @@ -294,8 +294,8 @@ static int gsc_m2m_querycap(struct file *file, void *fh, struct gsc_ctx *ctx = fh_to_ctx(fh); struct gsc_dev *gsc = ctx->gsc_dev; - strlcpy(cap->driver, GSC_MODULE_NAME, sizeof(cap->driver)); - strlcpy(cap->card, GSC_MODULE_NAME " gscaler", sizeof(cap->card)); + strscpy(cap->driver, GSC_MODULE_NAME, sizeof(cap->driver)); + strscpy(cap->card, GSC_MODULE_NAME " gscaler", sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(&gsc->pdev->dev)); cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE; diff --git a/drivers/media/platform/exynos4-is/common.c b/drivers/media/platform/exynos4-is/common.c index b90f5bb15517..76f557548dfc 100644 --- a/drivers/media/platform/exynos4-is/common.c +++ b/drivers/media/platform/exynos4-is/common.c @@ -40,8 +40,8 @@ EXPORT_SYMBOL(fimc_find_remote_sensor); void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap, unsigned int caps) { - strlcpy(cap->driver, dev->driver->name, sizeof(cap->driver)); - strlcpy(cap->card, dev->driver->name, sizeof(cap->card)); + strscpy(cap->driver, dev->driver->name, sizeof(cap->driver)); + strscpy(cap->card, dev->driver->name, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(dev)); cap->device_caps = caps; diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c index a3cdac188190..f56220e549bb 100644 --- a/drivers/media/platform/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/exynos4-is/fimc-capture.c @@ -1087,7 +1087,7 @@ static int fimc_cap_enum_input(struct file *file, void *priv, fimc_md_graph_unlock(ve); if (sd) - strlcpy(i->name, sd->name, sizeof(i->name)); + strscpy(i->name, sd->name, sizeof(i->name)); return 0; } diff --git a/drivers/media/platform/exynos4-is/fimc-is-i2c.c b/drivers/media/platform/exynos4-is/fimc-is-i2c.c index 70dd4852b2b9..be937caf7645 100644 --- a/drivers/media/platform/exynos4-is/fimc-is-i2c.c +++ b/drivers/media/platform/exynos4-is/fimc-is-i2c.c @@ -57,7 +57,7 @@ static int fimc_is_i2c_probe(struct platform_device *pdev) i2c_adap = &isp_i2c->adapter; i2c_adap->dev.of_node = node; i2c_adap->dev.parent = &pdev->dev; - strlcpy(i2c_adap->name, "exynos4x12-isp-i2c", sizeof(i2c_adap->name)); + strscpy(i2c_adap->name, "exynos4x12-isp-i2c", sizeof(i2c_adap->name)); i2c_adap->owner = THIS_MODULE; i2c_adap->algo = &fimc_is_i2c_algorithm; i2c_adap->class = I2C_CLASS_SPD; diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c index 5ddb2321e9e4..f5fc54de19da 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.c +++ b/drivers/media/platform/exynos4-is/fimc-is.c @@ -656,7 +656,7 @@ static int fimc_is_hw_open_sensor(struct fimc_is *is, int fimc_is_hw_initialize(struct fimc_is *is) { - const int config_ids[] = { + static const int config_ids[] = { IS_SC_PREVIEW_STILL, IS_SC_PREVIEW_VIDEO, IS_SC_CAPTURE_STILL, IS_SC_CAPTURE_VIDEO }; diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c index a920164f53f1..de6bd28f7e31 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp-video.c +++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c @@ -365,7 +365,7 @@ static int isp_video_enum_fmt_mplane(struct file *file, void *priv, if (WARN_ON(fmt == NULL)) return -EINVAL; - strlcpy(f->description, fmt->name, sizeof(f->description)); + strscpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->fourcc; return 0; diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index 70d5f5586a5d..96f0a8a0dcae 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c @@ -654,8 +654,8 @@ static int fimc_lite_querycap(struct file *file, void *priv, { struct fimc_lite *fimc = video_drvdata(file); - strlcpy(cap->driver, FIMC_LITE_DRV_NAME, sizeof(cap->driver)); - strlcpy(cap->card, FIMC_LITE_DRV_NAME, sizeof(cap->card)); + strscpy(cap->driver, FIMC_LITE_DRV_NAME, sizeof(cap->driver)); + strscpy(cap->card, FIMC_LITE_DRV_NAME, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(&fimc->pdev->dev)); @@ -673,7 +673,7 @@ static int fimc_lite_enum_fmt_mplane(struct file *file, void *priv, return -EINVAL; fmt = &fimc_lite_formats[f->index]; - strlcpy(f->description, fmt->name, sizeof(f->description)); + strscpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->fourcc; return 0; diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index deb499f76412..870501b0f351 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -390,7 +390,7 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd, { struct fimc_source_info *pd = &fmd->sensor[index].pdata; struct device_node *rem, *ep, *np; - struct v4l2_fwnode_endpoint endpoint; + struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 }; int ret; /* Assume here a port node can have only one endpoint node. */ @@ -457,11 +457,16 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd, fmd->sensor[index].asd.match_type = V4L2_ASYNC_MATCH_FWNODE; fmd->sensor[index].asd.match.fwnode = of_fwnode_handle(rem); - fmd->async_subdevs[index] = &fmd->sensor[index].asd; + + ret = v4l2_async_notifier_add_subdev(&fmd->subdev_notifier, + &fmd->sensor[index].asd); + if (ret) { + of_node_put(rem); + return ret; + } fmd->num_sensors++; - of_node_put(rem); return 0; } @@ -500,7 +505,7 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) ret = fimc_md_parse_port_node(fmd, port, index); if (ret < 0) { of_node_put(node); - goto rpm_put; + goto cleanup; } index++; } @@ -514,12 +519,18 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) ret = fimc_md_parse_port_node(fmd, node, index); if (ret < 0) { of_node_put(node); - break; + goto cleanup; } index++; } + rpm_put: pm_runtime_put(fmd->pmf); + return 0; + +cleanup: + v4l2_async_notifier_cleanup(&fmd->subdev_notifier); + pm_runtime_put(fmd->pmf); return ret; } @@ -1204,9 +1215,9 @@ static ssize_t fimc_md_sysfs_show(struct device *dev, struct fimc_md *fmd = dev_get_drvdata(dev); if (fmd->user_subdev_api) - return strlcpy(buf, "Sub-device API (sub-dev)\n", PAGE_SIZE); + return strscpy(buf, "Sub-device API (sub-dev)\n", PAGE_SIZE); - return strlcpy(buf, "V4L2 video node only API (vid-dev)\n", PAGE_SIZE); + return strscpy(buf, "V4L2 video node only API (vid-dev)\n", PAGE_SIZE); } static ssize_t fimc_md_sysfs_store(struct device *dev, @@ -1426,7 +1437,7 @@ static int fimc_md_probe(struct platform_device *pdev) INIT_LIST_HEAD(&fmd->pipelines); fmd->pdev = pdev; - strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC", + strscpy(fmd->media_dev.model, "SAMSUNG S5P FIMC", sizeof(fmd->media_dev.model)); fmd->media_dev.ops = &fimc_md_ops; fmd->media_dev.dev = dev; @@ -1434,7 +1445,7 @@ static int fimc_md_probe(struct platform_device *pdev) v4l2_dev = &fmd->v4l2_dev; v4l2_dev->mdev = &fmd->media_dev; v4l2_dev->notify = fimc_sensor_notify; - strlcpy(v4l2_dev->name, "s5p-fimc-md", sizeof(v4l2_dev->name)); + strscpy(v4l2_dev->name, "s5p-fimc-md", sizeof(v4l2_dev->name)); fmd->use_isp = fimc_md_is_isp_available(dev->of_node); fmd->user_subdev_api = true; @@ -1460,6 +1471,8 @@ static int fimc_md_probe(struct platform_device *pdev) platform_set_drvdata(pdev, fmd); + v4l2_async_notifier_init(&fmd->subdev_notifier); + ret = fimc_md_register_platform_entities(fmd, dev->of_node); if (ret) goto err_clk; @@ -1470,7 +1483,7 @@ static int fimc_md_probe(struct platform_device *pdev) ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode); if (ret) - goto err_m_ent; + goto err_cleanup; /* * FIMC platform devices need to be registered before the sclk_cam * clocks provider, as one of these devices needs to be activated @@ -1483,8 +1496,6 @@ static int fimc_md_probe(struct platform_device *pdev) } if (fmd->num_sensors > 0) { - fmd->subdev_notifier.subdevs = fmd->async_subdevs; - fmd->subdev_notifier.num_subdevs = fmd->num_sensors; fmd->subdev_notifier.ops = &subdev_notifier_ops; fmd->num_sensors = 0; @@ -1500,10 +1511,12 @@ err_clk_p: fimc_md_unregister_clk_provider(fmd); err_attr: device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode); -err_clk: - fimc_md_put_clocks(fmd); +err_cleanup: + v4l2_async_notifier_cleanup(&fmd->subdev_notifier); err_m_ent: fimc_md_unregister_entities(fmd); +err_clk: + fimc_md_put_clocks(fmd); err_md: media_device_cleanup(&fmd->media_dev); v4l2_device_unregister(&fmd->v4l2_dev); @@ -1519,6 +1532,7 @@ static int fimc_md_remove(struct platform_device *pdev) fimc_md_unregister_clk_provider(fmd); v4l2_async_notifier_unregister(&fmd->subdev_notifier); + v4l2_async_notifier_cleanup(&fmd->subdev_notifier); v4l2_device_unregister(&fmd->v4l2_dev); device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode); diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h index 957787a2f480..9f527670395a 100644 --- a/drivers/media/platform/exynos4-is/media-dev.h +++ b/drivers/media/platform/exynos4-is/media-dev.h @@ -149,7 +149,6 @@ struct fimc_md { } clk_provider; struct v4l2_async_notifier subdev_notifier; - struct v4l2_async_subdev *async_subdevs[FIMC_MAX_SENSORS]; bool user_subdev_api; spinlock_t slock; diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index b4e28a299e26..35cb0162085b 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c @@ -718,7 +718,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev, struct csis_state *state) { struct device_node *node = pdev->dev.of_node; - struct v4l2_fwnode_endpoint endpoint; + struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 }; int ret; if (of_property_read_u32(node, "clock-frequency", diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c index 0273302aa741..ca6d0317ab42 100644 --- a/drivers/media/platform/fsl-viu.c +++ b/drivers/media/platform/fsl-viu.c @@ -565,9 +565,9 @@ static const struct videobuf_queue_ops viu_video_qops = { static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - strcpy(cap->driver, "viu"); - strcpy(cap->card, "viu"); - strcpy(cap->bus_info, "platform:viu"); + strscpy(cap->driver, "viu", sizeof(cap->driver)); + strscpy(cap->card, "viu", sizeof(cap->card)); + strscpy(cap->bus_info, "platform:viu", sizeof(cap->bus_info)); cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OVERLAY | @@ -941,7 +941,7 @@ static int vidioc_enum_input(struct file *file, void *priv, inp->type = V4L2_INPUT_TYPE_CAMERA; inp->std = fh->dev->vdev->tvnorms; - strcpy(inp->name, "Camera"); + strscpy(inp->name, "Camera", sizeof(inp->name)); return 0; } diff --git a/drivers/media/platform/imx-pxp.c b/drivers/media/platform/imx-pxp.c new file mode 100644 index 000000000000..b76cd0e8313c --- /dev/null +++ b/drivers/media/platform/imx-pxp.c @@ -0,0 +1,1754 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * i.MX Pixel Pipeline (PXP) mem-to-mem scaler/CSC/rotator driver + * + * Copyright (c) 2018 Pengutronix, Philipp Zabel + * + * based on vim2m + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * Pawel Osciak, <pawel@osciak.com> + * Marek Szyprowski, <m.szyprowski@samsung.com> + */ +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/dma-mapping.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/sched.h> +#include <linux/slab.h> + +#include <linux/platform_device.h> +#include <media/v4l2-mem2mem.h> +#include <media/v4l2-device.h> +#include <media/v4l2-ioctl.h> +#include <media/v4l2-ctrls.h> +#include <media/v4l2-event.h> +#include <media/videobuf2-dma-contig.h> + +#include "imx-pxp.h" + +static unsigned int debug; +module_param(debug, uint, 0644); +MODULE_PARM_DESC(debug, "activates debug info"); + +#define MIN_W 8 +#define MIN_H 8 +#define MAX_W 4096 +#define MAX_H 4096 +#define ALIGN_W 3 /* 8x8 pixel blocks */ +#define ALIGN_H 3 + +/* Flags that indicate a format can be used for capture/output */ +#define MEM2MEM_CAPTURE (1 << 0) +#define MEM2MEM_OUTPUT (1 << 1) + +#define MEM2MEM_NAME "pxp" + +/* Flags that indicate processing mode */ +#define MEM2MEM_HFLIP (1 << 0) +#define MEM2MEM_VFLIP (1 << 1) + +#define dprintk(dev, fmt, arg...) \ + v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg) + +struct pxp_fmt { + u32 fourcc; + int depth; + /* Types the format can be used for */ + u32 types; +}; + +static struct pxp_fmt formats[] = { + { + .fourcc = V4L2_PIX_FMT_XBGR32, + .depth = 32, + /* Both capture and output format */ + .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT, + }, { + .fourcc = V4L2_PIX_FMT_ABGR32, + .depth = 32, + /* Capture-only format */ + .types = MEM2MEM_CAPTURE, + }, { + .fourcc = V4L2_PIX_FMT_BGR24, + .depth = 24, + .types = MEM2MEM_CAPTURE, + }, { + .fourcc = V4L2_PIX_FMT_RGB565, + .depth = 16, + .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT, + }, { + .fourcc = V4L2_PIX_FMT_RGB555, + .depth = 16, + .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT, + }, { + .fourcc = V4L2_PIX_FMT_RGB444, + .depth = 16, + .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT, + }, { + .fourcc = V4L2_PIX_FMT_YUV32, + .depth = 32, + .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT, + }, { + .fourcc = V4L2_PIX_FMT_UYVY, + .depth = 16, + .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT, + }, { + .fourcc = V4L2_PIX_FMT_YUYV, + .depth = 16, + /* Output-only format */ + .types = MEM2MEM_OUTPUT, + }, { + .fourcc = V4L2_PIX_FMT_VYUY, + .depth = 16, + .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT, + }, { + .fourcc = V4L2_PIX_FMT_YVYU, + .depth = 16, + .types = MEM2MEM_OUTPUT, + }, { + .fourcc = V4L2_PIX_FMT_GREY, + .depth = 8, + .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT, + }, { + .fourcc = V4L2_PIX_FMT_Y4, + .depth = 4, + .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT, + }, { + .fourcc = V4L2_PIX_FMT_NV16, + .depth = 16, + .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT, + }, { + .fourcc = V4L2_PIX_FMT_NV12, + .depth = 12, + .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT, + }, { + .fourcc = V4L2_PIX_FMT_NV21, + .depth = 12, + .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT, + }, { + .fourcc = V4L2_PIX_FMT_NV61, + .depth = 16, + .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT, + }, { + .fourcc = V4L2_PIX_FMT_YUV422P, + .depth = 16, + .types = MEM2MEM_OUTPUT, + }, { + .fourcc = V4L2_PIX_FMT_YUV420, + .depth = 12, + .types = MEM2MEM_OUTPUT, + }, +}; + +#define NUM_FORMATS ARRAY_SIZE(formats) + +/* Per-queue, driver-specific private data */ +struct pxp_q_data { + unsigned int width; + unsigned int height; + unsigned int bytesperline; + unsigned int sizeimage; + unsigned int sequence; + struct pxp_fmt *fmt; + enum v4l2_ycbcr_encoding ycbcr_enc; + enum v4l2_quantization quant; +}; + +enum { + V4L2_M2M_SRC = 0, + V4L2_M2M_DST = 1, +}; + +static struct pxp_fmt *find_format(struct v4l2_format *f) +{ + struct pxp_fmt *fmt; + unsigned int k; + + for (k = 0; k < NUM_FORMATS; k++) { + fmt = &formats[k]; + if (fmt->fourcc == f->fmt.pix.pixelformat) + break; + } + + if (k == NUM_FORMATS) + return NULL; + + return &formats[k]; +} + +struct pxp_dev { + struct v4l2_device v4l2_dev; + struct video_device vfd; + + struct clk *clk; + void __iomem *mmio; + + atomic_t num_inst; + struct mutex dev_mutex; + spinlock_t irqlock; + + struct v4l2_m2m_dev *m2m_dev; +}; + +struct pxp_ctx { + struct v4l2_fh fh; + struct pxp_dev *dev; + + struct v4l2_ctrl_handler hdl; + + /* Abort requested by m2m */ + int aborting; + + /* Processing mode */ + int mode; + u8 alpha_component; + + enum v4l2_colorspace colorspace; + enum v4l2_xfer_func xfer_func; + + /* Source and destination queue data */ + struct pxp_q_data q_data[2]; +}; + +static inline struct pxp_ctx *file2ctx(struct file *file) +{ + return container_of(file->private_data, struct pxp_ctx, fh); +} + +static struct pxp_q_data *get_q_data(struct pxp_ctx *ctx, + enum v4l2_buf_type type) +{ + if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT) + return &ctx->q_data[V4L2_M2M_SRC]; + else + return &ctx->q_data[V4L2_M2M_DST]; +} + +static u32 pxp_v4l2_pix_fmt_to_ps_format(u32 v4l2_pix_fmt) +{ + switch (v4l2_pix_fmt) { + case V4L2_PIX_FMT_XBGR32: return BV_PXP_PS_CTRL_FORMAT__RGB888; + case V4L2_PIX_FMT_RGB555: return BV_PXP_PS_CTRL_FORMAT__RGB555; + case V4L2_PIX_FMT_RGB444: return BV_PXP_PS_CTRL_FORMAT__RGB444; + case V4L2_PIX_FMT_RGB565: return BV_PXP_PS_CTRL_FORMAT__RGB565; + case V4L2_PIX_FMT_YUV32: return BV_PXP_PS_CTRL_FORMAT__YUV1P444; + case V4L2_PIX_FMT_UYVY: return BV_PXP_PS_CTRL_FORMAT__UYVY1P422; + case V4L2_PIX_FMT_YUYV: return BM_PXP_PS_CTRL_WB_SWAP | + BV_PXP_PS_CTRL_FORMAT__UYVY1P422; + case V4L2_PIX_FMT_VYUY: return BV_PXP_PS_CTRL_FORMAT__VYUY1P422; + case V4L2_PIX_FMT_YVYU: return BM_PXP_PS_CTRL_WB_SWAP | + BV_PXP_PS_CTRL_FORMAT__VYUY1P422; + case V4L2_PIX_FMT_GREY: return BV_PXP_PS_CTRL_FORMAT__Y8; + default: + case V4L2_PIX_FMT_Y4: return BV_PXP_PS_CTRL_FORMAT__Y4; + case V4L2_PIX_FMT_NV16: return BV_PXP_PS_CTRL_FORMAT__YUV2P422; + case V4L2_PIX_FMT_NV12: return BV_PXP_PS_CTRL_FORMAT__YUV2P420; + case V4L2_PIX_FMT_NV21: return BV_PXP_PS_CTRL_FORMAT__YVU2P420; + case V4L2_PIX_FMT_NV61: return BV_PXP_PS_CTRL_FORMAT__YVU2P422; + case V4L2_PIX_FMT_YUV422P: return BV_PXP_PS_CTRL_FORMAT__YUV422; + case V4L2_PIX_FMT_YUV420: return BV_PXP_PS_CTRL_FORMAT__YUV420; + } +} + +static u32 pxp_v4l2_pix_fmt_to_out_format(u32 v4l2_pix_fmt) +{ + switch (v4l2_pix_fmt) { + case V4L2_PIX_FMT_XBGR32: return BV_PXP_OUT_CTRL_FORMAT__RGB888; + case V4L2_PIX_FMT_ABGR32: return BV_PXP_OUT_CTRL_FORMAT__ARGB8888; + case V4L2_PIX_FMT_BGR24: return BV_PXP_OUT_CTRL_FORMAT__RGB888P; + /* Missing V4L2 pixel formats for ARGB1555 and ARGB4444 */ + case V4L2_PIX_FMT_RGB555: return BV_PXP_OUT_CTRL_FORMAT__RGB555; + case V4L2_PIX_FMT_RGB444: return BV_PXP_OUT_CTRL_FORMAT__RGB444; + case V4L2_PIX_FMT_RGB565: return BV_PXP_OUT_CTRL_FORMAT__RGB565; + case V4L2_PIX_FMT_YUV32: return BV_PXP_OUT_CTRL_FORMAT__YUV1P444; + case V4L2_PIX_FMT_UYVY: return BV_PXP_OUT_CTRL_FORMAT__UYVY1P422; + case V4L2_PIX_FMT_VYUY: return BV_PXP_OUT_CTRL_FORMAT__VYUY1P422; + case V4L2_PIX_FMT_GREY: return BV_PXP_OUT_CTRL_FORMAT__Y8; + default: + case V4L2_PIX_FMT_Y4: return BV_PXP_OUT_CTRL_FORMAT__Y4; + case V4L2_PIX_FMT_NV16: return BV_PXP_OUT_CTRL_FORMAT__YUV2P422; + case V4L2_PIX_FMT_NV12: return BV_PXP_OUT_CTRL_FORMAT__YUV2P420; + case V4L2_PIX_FMT_NV61: return BV_PXP_OUT_CTRL_FORMAT__YVU2P422; + case V4L2_PIX_FMT_NV21: return BV_PXP_OUT_CTRL_FORMAT__YVU2P420; + } +} + +static bool pxp_v4l2_pix_fmt_is_yuv(u32 v4l2_pix_fmt) +{ + switch (v4l2_pix_fmt) { + case V4L2_PIX_FMT_YUV32: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_VYUY: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YUV422P: + case V4L2_PIX_FMT_GREY: + case V4L2_PIX_FMT_Y4: + return true; + default: + return false; + } +} + +static void pxp_setup_csc(struct pxp_ctx *ctx) +{ + struct pxp_dev *dev = ctx->dev; + enum v4l2_ycbcr_encoding ycbcr_enc; + enum v4l2_quantization quantization; + + if (pxp_v4l2_pix_fmt_is_yuv(ctx->q_data[V4L2_M2M_SRC].fmt->fourcc) && + !pxp_v4l2_pix_fmt_is_yuv(ctx->q_data[V4L2_M2M_DST].fmt->fourcc)) { + /* + * CSC1 YUV/YCbCr to RGB conversion is implemented as follows: + * + * |R| |C0 0 C1| |Y + Yoffset | + * |G| = |C0 C3 C2| * |Cb + UVoffset| + * |B| |C0 C4 0 | |Cr + UVoffset| + * + * Results are clamped to 0..255. + * + * BT.601 limited range: + * + * |R| |1.1644 0.0000 1.5960| |Y - 16 | + * |G| = |1.1644 -0.3917 -0.8129| * |Cb - 128| + * |B| |1.1644 2.0172 0.0000| |Cr - 128| + */ + static const u32 csc1_coef_bt601_lim[3] = { + BM_PXP_CSC1_COEF0_YCBCR_MODE | + BF_PXP_CSC1_COEF0_C0(0x12a) | /* 1.1641 (-0.03 %) */ + BF_PXP_CSC1_COEF0_UV_OFFSET(-128) | + BF_PXP_CSC1_COEF0_Y_OFFSET(-16), + BF_PXP_CSC1_COEF1_C1(0x198) | /* 1.5938 (-0.23 %) */ + BF_PXP_CSC1_COEF1_C4(0x204), /* 2.0156 (-0.16 %) */ + BF_PXP_CSC1_COEF2_C2(0x730) | /* -0.8125 (+0.04 %) */ + BF_PXP_CSC1_COEF2_C3(0x79c), /* -0.3906 (+0.11 %) */ + }; + /* + * BT.601 full range: + * + * |R| |1.0000 0.0000 1.4020| |Y + 0 | + * |G| = |1.0000 -0.3441 -0.7141| * |Cb - 128| + * |B| |1.0000 1.7720 0.0000| |Cr - 128| + */ + static const u32 csc1_coef_bt601_full[3] = { + BM_PXP_CSC1_COEF0_YCBCR_MODE | + BF_PXP_CSC1_COEF0_C0(0x100) | /* 1.0000 (+0.00 %) */ + BF_PXP_CSC1_COEF0_UV_OFFSET(-128) | + BF_PXP_CSC1_COEF0_Y_OFFSET(0), + BF_PXP_CSC1_COEF1_C1(0x166) | /* 1.3984 (-0.36 %) */ + BF_PXP_CSC1_COEF1_C4(0x1c5), /* 1.7695 (-0.25 %) */ + BF_PXP_CSC1_COEF2_C2(0x74a) | /* -0.7109 (+0.32 %) */ + BF_PXP_CSC1_COEF2_C3(0x7a8), /* -0.3438 (+0.04 %) */ + }; + /* + * Rec.709 limited range: + * + * |R| |1.1644 0.0000 1.7927| |Y - 16 | + * |G| = |1.1644 -0.2132 -0.5329| * |Cb - 128| + * |B| |1.1644 2.1124 0.0000| |Cr - 128| + */ + static const u32 csc1_coef_rec709_lim[3] = { + BM_PXP_CSC1_COEF0_YCBCR_MODE | + BF_PXP_CSC1_COEF0_C0(0x12a) | /* 1.1641 (-0.03 %) */ + BF_PXP_CSC1_COEF0_UV_OFFSET(-128) | + BF_PXP_CSC1_COEF0_Y_OFFSET(-16), + BF_PXP_CSC1_COEF1_C1(0x1ca) | /* 1.7891 (-0.37 %) */ + BF_PXP_CSC1_COEF1_C4(0x21c), /* 2.1094 (-0.30 %) */ + BF_PXP_CSC1_COEF2_C2(0x778) | /* -0.5312 (+0.16 %) */ + BF_PXP_CSC1_COEF2_C3(0x7ca), /* -0.2109 (+0.23 %) */ + }; + /* + * Rec.709 full range: + * + * |R| |1.0000 0.0000 1.5748| |Y + 0 | + * |G| = |1.0000 -0.1873 -0.4681| * |Cb - 128| + * |B| |1.0000 1.8556 0.0000| |Cr - 128| + */ + static const u32 csc1_coef_rec709_full[3] = { + BM_PXP_CSC1_COEF0_YCBCR_MODE | + BF_PXP_CSC1_COEF0_C0(0x100) | /* 1.0000 (+0.00 %) */ + BF_PXP_CSC1_COEF0_UV_OFFSET(-128) | + BF_PXP_CSC1_COEF0_Y_OFFSET(0), + BF_PXP_CSC1_COEF1_C1(0x193) | /* 1.5742 (-0.06 %) */ + BF_PXP_CSC1_COEF1_C4(0x1db), /* 1.8555 (-0.01 %) */ + BF_PXP_CSC1_COEF2_C2(0x789) | /* -0.4648 (+0.33 %) */ + BF_PXP_CSC1_COEF2_C3(0x7d1), /* -0.1836 (+0.37 %) */ + }; + /* + * BT.2020 limited range: + * + * |R| |1.1644 0.0000 1.6787| |Y - 16 | + * |G| = |1.1644 -0.1874 -0.6505| * |Cb - 128| + * |B| |1.1644 2.1418 0.0000| |Cr - 128| + */ + static const u32 csc1_coef_bt2020_lim[3] = { + BM_PXP_CSC1_COEF0_YCBCR_MODE | + BF_PXP_CSC1_COEF0_C0(0x12a) | /* 1.1641 (-0.03 %) */ + BF_PXP_CSC1_COEF0_UV_OFFSET(-128) | + BF_PXP_CSC1_COEF0_Y_OFFSET(-16), + BF_PXP_CSC1_COEF1_C1(0x1ad) | /* 1.6758 (-0.29 %) */ + BF_PXP_CSC1_COEF1_C4(0x224), /* 2.1406 (-0.11 %) */ + BF_PXP_CSC1_COEF2_C2(0x75a) | /* -0.6484 (+0.20 %) */ + BF_PXP_CSC1_COEF2_C3(0x7d1), /* -0.1836 (+0.38 %) */ + }; + /* + * BT.2020 full range: + * + * |R| |1.0000 0.0000 1.4746| |Y + 0 | + * |G| = |1.0000 -0.1646 -0.5714| * |Cb - 128| + * |B| |1.0000 1.8814 0.0000| |Cr - 128| + */ + static const u32 csc1_coef_bt2020_full[3] = { + BM_PXP_CSC1_COEF0_YCBCR_MODE | + BF_PXP_CSC1_COEF0_C0(0x100) | /* 1.0000 (+0.00 %) */ + BF_PXP_CSC1_COEF0_UV_OFFSET(-128) | + BF_PXP_CSC1_COEF0_Y_OFFSET(0), + BF_PXP_CSC1_COEF1_C1(0x179) | /* 1.4727 (-0.19 %) */ + BF_PXP_CSC1_COEF1_C4(0x1e1), /* 1.8789 (-0.25 %) */ + BF_PXP_CSC1_COEF2_C2(0x76e) | /* -0.5703 (+0.11 %) */ + BF_PXP_CSC1_COEF2_C3(0x7d6), /* -0.1641 (+0.05 %) */ + }; + /* + * SMPTE 240m limited range: + * + * |R| |1.1644 0.0000 1.7937| |Y - 16 | + * |G| = |1.1644 -0.2565 -0.5427| * |Cb - 128| + * |B| |1.1644 2.0798 0.0000| |Cr - 128| + */ + static const u32 csc1_coef_smpte240m_lim[3] = { + BM_PXP_CSC1_COEF0_YCBCR_MODE | + BF_PXP_CSC1_COEF0_C0(0x12a) | /* 1.1641 (-0.03 %) */ + BF_PXP_CSC1_COEF0_UV_OFFSET(-128) | + BF_PXP_CSC1_COEF0_Y_OFFSET(-16), + BF_PXP_CSC1_COEF1_C1(0x1cb) | /* 1.7930 (-0.07 %) */ + BF_PXP_CSC1_COEF1_C4(0x214), /* 2.0781 (-0.17 %) */ + BF_PXP_CSC1_COEF2_C2(0x776) | /* -0.5391 (+0.36 %) */ + BF_PXP_CSC1_COEF2_C3(0x7bf), /* -0.2539 (+0.26 %) */ + }; + /* + * SMPTE 240m full range: + * + * |R| |1.0000 0.0000 1.5756| |Y + 0 | + * |G| = |1.0000 -0.2253 -0.4767| * |Cb - 128| + * |B| |1.0000 1.8270 0.0000| |Cr - 128| + */ + static const u32 csc1_coef_smpte240m_full[3] = { + BM_PXP_CSC1_COEF0_YCBCR_MODE | + BF_PXP_CSC1_COEF0_C0(0x100) | /* 1.0000 (+0.00 %) */ + BF_PXP_CSC1_COEF0_UV_OFFSET(-128) | + BF_PXP_CSC1_COEF0_Y_OFFSET(0), + BF_PXP_CSC1_COEF1_C1(0x193) | /* 1.5742 (-0.14 %) */ + BF_PXP_CSC1_COEF1_C4(0x1d3), /* 1.8242 (-0.28 %) */ + BF_PXP_CSC1_COEF2_C2(0x786) | /* -0.4766 (+0.01 %) */ + BF_PXP_CSC1_COEF2_C3(0x7c7), /* -0.2227 (+0.26 %) */ + }; + const u32 *csc1_coef; + + ycbcr_enc = ctx->q_data[V4L2_M2M_SRC].ycbcr_enc; + quantization = ctx->q_data[V4L2_M2M_SRC].quant; + + if (ycbcr_enc == V4L2_YCBCR_ENC_601) { + if (quantization == V4L2_QUANTIZATION_FULL_RANGE) + csc1_coef = csc1_coef_bt601_full; + else + csc1_coef = csc1_coef_bt601_lim; + } else if (ycbcr_enc == V4L2_YCBCR_ENC_709) { + if (quantization == V4L2_QUANTIZATION_FULL_RANGE) + csc1_coef = csc1_coef_rec709_full; + else + csc1_coef = csc1_coef_rec709_lim; + } else if (ycbcr_enc == V4L2_YCBCR_ENC_BT2020) { + if (quantization == V4L2_QUANTIZATION_FULL_RANGE) + csc1_coef = csc1_coef_bt2020_full; + else + csc1_coef = csc1_coef_bt2020_lim; + } else { + if (quantization == V4L2_QUANTIZATION_FULL_RANGE) + csc1_coef = csc1_coef_smpte240m_full; + else + csc1_coef = csc1_coef_smpte240m_lim; + } + + writel(csc1_coef[0], dev->mmio + HW_PXP_CSC1_COEF0); + writel(csc1_coef[1], dev->mmio + HW_PXP_CSC1_COEF1); + writel(csc1_coef[2], dev->mmio + HW_PXP_CSC1_COEF2); + } else { + writel(BM_PXP_CSC1_COEF0_BYPASS, dev->mmio + HW_PXP_CSC1_COEF0); + } + + if (!pxp_v4l2_pix_fmt_is_yuv(ctx->q_data[V4L2_M2M_SRC].fmt->fourcc) && + pxp_v4l2_pix_fmt_is_yuv(ctx->q_data[V4L2_M2M_DST].fmt->fourcc)) { + /* + * CSC2 RGB to YUV/YCbCr conversion is implemented as follows: + * + * |Y | |A1 A2 A3| |R| |D1| + * |Cb| = |B1 B2 B3| * |G| + |D2| + * |Cr| |C1 C2 C3| |B| |D3| + * + * Results are clamped to 0..255. + * + * BT.601 limited range: + * + * |Y | | 0.2568 0.5041 0.0979| |R| |16 | + * |Cb| = |-0.1482 -0.2910 0.4392| * |G| + |128| + * |Cr| | 0.4392 0.4392 -0.3678| |B| |128| + */ + static const u32 csc2_coef_bt601_lim[6] = { + BF_PXP_CSC2_COEF0_A2(0x081) | /* 0.5039 (-0.02 %) */ + BF_PXP_CSC2_COEF0_A1(0x041), /* 0.2539 (-0.29 %) */ + BF_PXP_CSC2_COEF1_B1(0x7db) | /* -0.1445 (+0.37 %) */ + BF_PXP_CSC2_COEF1_A3(0x019), /* 0.0977 (-0.02 %) */ + BF_PXP_CSC2_COEF2_B3(0x070) | /* 0.4375 (-0.17 %) */ + BF_PXP_CSC2_COEF2_B2(0x7b6), /* -0.2891 (+0.20 %) */ + BF_PXP_CSC2_COEF3_C2(0x7a2) | /* -0.3672 (+0.06 %) */ + BF_PXP_CSC2_COEF3_C1(0x070), /* 0.4375 (-0.17 %) */ + BF_PXP_CSC2_COEF4_D1(16) | + BF_PXP_CSC2_COEF4_C3(0x7ee), /* -0.0703 (+0.11 %) */ + BF_PXP_CSC2_COEF5_D3(128) | + BF_PXP_CSC2_COEF5_D2(128), + }; + /* + * BT.601 full range: + * + * |Y | | 0.2990 0.5870 0.1140| |R| |0 | + * |Cb| = |-0.1687 -0.3313 0.5000| * |G| + |128| + * |Cr| | 0.5000 0.5000 -0.4187| |B| |128| + */ + static const u32 csc2_coef_bt601_full[6] = { + BF_PXP_CSC2_COEF0_A2(0x096) | /* 0.5859 (-0.11 %) */ + BF_PXP_CSC2_COEF0_A1(0x04c), /* 0.2969 (-0.21 %) */ + BF_PXP_CSC2_COEF1_B1(0x7d5) | /* -0.1680 (+0.07 %) */ + BF_PXP_CSC2_COEF1_A3(0x01d), /* 0.1133 (-0.07 %) */ + BF_PXP_CSC2_COEF2_B3(0x080) | /* 0.5000 (+0.00 %) */ + BF_PXP_CSC2_COEF2_B2(0x7ac), /* -0.3281 (+0.32 %) */ + BF_PXP_CSC2_COEF3_C2(0x795) | /* -0.4180 (+0.07 %) */ + BF_PXP_CSC2_COEF3_C1(0x080), /* 0.5000 (+0.00 %) */ + BF_PXP_CSC2_COEF4_D1(0) | + BF_PXP_CSC2_COEF4_C3(0x7ec), /* -0.0781 (+0.32 %) */ + BF_PXP_CSC2_COEF5_D3(128) | + BF_PXP_CSC2_COEF5_D2(128), + }; + /* + * Rec.709 limited range: + * + * |Y | | 0.1826 0.6142 0.0620| |R| |16 | + * |Cb| = |-0.1007 -0.3385 0.4392| * |G| + |128| + * |Cr| | 0.4392 0.4392 -0.3990| |B| |128| + */ + static const u32 csc2_coef_rec709_lim[6] = { + BF_PXP_CSC2_COEF0_A2(0x09d) | /* 0.6133 (-0.09 %) */ + BF_PXP_CSC2_COEF0_A1(0x02e), /* 0.1797 (-0.29 %) */ + BF_PXP_CSC2_COEF1_B1(0x7e7) | /* -0.0977 (+0.30 %) */ + BF_PXP_CSC2_COEF1_A3(0x00f), /* 0.0586 (-0.34 %) */ + BF_PXP_CSC2_COEF2_B3(0x070) | /* 0.4375 (-0.17 %) */ + BF_PXP_CSC2_COEF2_B2(0x7aa), /* -0.3359 (+0.26 %) */ + BF_PXP_CSC2_COEF3_C2(0x79a) | /* -0.3984 (+0.05 %) */ + BF_PXP_CSC2_COEF3_C1(0x070), /* 0.4375 (-0.17 %) */ + BF_PXP_CSC2_COEF4_D1(16) | + BF_PXP_CSC2_COEF4_C3(0x7f6), /* -0.0391 (+0.12 %) */ + BF_PXP_CSC2_COEF5_D3(128) | + BF_PXP_CSC2_COEF5_D2(128), + }; + /* + * Rec.709 full range: + * + * |Y | | 0.2126 0.7152 0.0722| |R| |0 | + * |Cb| = |-0.1146 -0.3854 0.5000| * |G| + |128| + * |Cr| | 0.5000 0.5000 -0.4542| |B| |128| + */ + static const u32 csc2_coef_rec709_full[6] = { + BF_PXP_CSC2_COEF0_A2(0x0b7) | /* 0.7148 (-0.04 %) */ + BF_PXP_CSC2_COEF0_A1(0x036), /* 0.2109 (-0.17 %) */ + BF_PXP_CSC2_COEF1_B1(0x7e3) | /* -0.1133 (+0.13 %) */ + BF_PXP_CSC2_COEF1_A3(0x012), /* 0.0703 (-0.19 %) */ + BF_PXP_CSC2_COEF2_B3(0x080) | /* 0.5000 (+0.00 %) */ + BF_PXP_CSC2_COEF2_B2(0x79e), /* -0.3828 (+0.26 %) */ + BF_PXP_CSC2_COEF3_C2(0x78c) | /* -0.4531 (+0.11 %) */ + BF_PXP_CSC2_COEF3_C1(0x080), /* 0.5000 (+0.00 %) */ + BF_PXP_CSC2_COEF4_D1(0) | + BF_PXP_CSC2_COEF4_C3(0x7f5), /* -0.0430 (+0.28 %) */ + BF_PXP_CSC2_COEF5_D3(128) | + BF_PXP_CSC2_COEF5_D2(128), + }; + /* + * BT.2020 limited range: + * + * |Y | | 0.2256 0.5823 0.0509| |R| |16 | + * |Cb| = |-0.1226 -0.3166 0.4392| * |G| + |128| + * |Cr| | 0.4392 0.4392 -0.4039| |B| |128| + */ + static const u32 csc2_coef_bt2020_lim[6] = { + BF_PXP_CSC2_COEF0_A2(0x095) | /* 0.5820 (-0.03 %) */ + BF_PXP_CSC2_COEF0_A1(0x039), /* 0.2227 (-0.30 %) */ + BF_PXP_CSC2_COEF1_B1(0x7e1) | /* -0.1211 (+0.15 %) */ + BF_PXP_CSC2_COEF1_A3(0x00d), /* 0.0508 (-0.01 %) */ + BF_PXP_CSC2_COEF2_B3(0x070) | /* 0.4375 (-0.17 %) */ + BF_PXP_CSC2_COEF2_B2(0x7af), /* -0.3164 (+0.02 %) */ + BF_PXP_CSC2_COEF3_C2(0x799) | /* -0.4023 (+0.16 %) */ + BF_PXP_CSC2_COEF3_C1(0x070), /* 0.4375 (-0.17 %) */ + BF_PXP_CSC2_COEF4_D1(16) | + BF_PXP_CSC2_COEF4_C3(0x7f7), /* -0.0352 (+0.02 %) */ + BF_PXP_CSC2_COEF5_D3(128) | + BF_PXP_CSC2_COEF5_D2(128), + }; + /* + * BT.2020 full range: + * + * |Y | | 0.2627 0.6780 0.0593| |R| |0 | + * |Cb| = |-0.1396 -0.3604 0.5000| * |G| + |128| + * |Cr| | 0.5000 0.5000 -0.4598| |B| |128| + */ + static const u32 csc2_coef_bt2020_full[6] = { + BF_PXP_CSC2_COEF0_A2(0x0ad) | /* 0.6758 (-0.22 %) */ + BF_PXP_CSC2_COEF0_A1(0x043), /* 0.2617 (-0.10 %) */ + BF_PXP_CSC2_COEF1_B1(0x7dd) | /* -0.1367 (+0.29 %) */ + BF_PXP_CSC2_COEF1_A3(0x00f), /* 0.0586 (-0.07 %) */ + BF_PXP_CSC2_COEF2_B3(0x080) | /* 0.5000 (+0.00 %) */ + BF_PXP_CSC2_COEF2_B2(0x7a4), /* -0.3594 (+0.10 %) */ + BF_PXP_CSC2_COEF3_C2(0x78b) | /* -0.4570 (+0.28 %) */ + BF_PXP_CSC2_COEF3_C1(0x080), /* 0.5000 (+0.00 %) */ + BF_PXP_CSC2_COEF4_D1(0) | + BF_PXP_CSC2_COEF4_C3(0x7f6), /* -0.0391 (+0.11 %) */ + BF_PXP_CSC2_COEF5_D3(128) | + BF_PXP_CSC2_COEF5_D2(128), + }; + /* + * SMPTE 240m limited range: + * + * |Y | | 0.1821 0.6020 0.0747| |R| |16 | + * |Cb| = |-0.1019 -0.3373 0.4392| * |G| + |128| + * |Cr| | 0.4392 0.4392 -0.3909| |B| |128| + */ + static const u32 csc2_coef_smpte240m_lim[6] = { + BF_PXP_CSC2_COEF0_A2(0x09a) | /* 0.6016 (-0.05 %) */ + BF_PXP_CSC2_COEF0_A1(0x02e), /* 0.1797 (-0.24 %) */ + BF_PXP_CSC2_COEF1_B1(0x7e6) | /* -0.1016 (+0.03 %) */ + BF_PXP_CSC2_COEF1_A3(0x013), /* 0.0742 (-0.05 %) */ + BF_PXP_CSC2_COEF2_B3(0x070) | /* 0.4375 (-0.17 %) */ + BF_PXP_CSC2_COEF2_B2(0x7aa), /* -0.3359 (+0.14 %) */ + BF_PXP_CSC2_COEF3_C2(0x79c) | /* -0.3906 (+0.03 %) */ + BF_PXP_CSC2_COEF3_C1(0x070), /* 0.4375 (-0.17 %) */ + BF_PXP_CSC2_COEF4_D1(16) | + BF_PXP_CSC2_COEF4_C3(0x7f4), /* -0.0469 (+0.14 %) */ + BF_PXP_CSC2_COEF5_D3(128) | + BF_PXP_CSC2_COEF5_D2(128), + }; + /* + * SMPTE 240m full range: + * + * |Y | | 0.2120 0.7010 0.0870| |R| |0 | + * |Cb| = |-0.1160 -0.3840 0.5000| * |G| + |128| + * |Cr| | 0.5000 0.5000 -0.4450| |B| |128| + */ + static const u32 csc2_coef_smpte240m_full[6] = { + BF_PXP_CSC2_COEF0_A2(0x0b3) | /* 0.6992 (-0.18 %) */ + BF_PXP_CSC2_COEF0_A1(0x036), /* 0.2109 (-0.11 %) */ + BF_PXP_CSC2_COEF1_B1(0x7e3) | /* -0.1133 (+0.27 %) */ + BF_PXP_CSC2_COEF1_A3(0x016), /* 0.0859 (-0.11 %) */ + BF_PXP_CSC2_COEF2_B3(0x080) | /* 0.5000 (+0.00 %) */ + BF_PXP_CSC2_COEF2_B2(0x79e), /* -0.3828 (+0.12 %) */ + BF_PXP_CSC2_COEF3_C2(0x78f) | /* -0.4414 (+0.36 %) */ + BF_PXP_CSC2_COEF3_C1(0x080), /* 0.5000 (+0.00 %) */ + BF_PXP_CSC2_COEF4_D1(0) | + BF_PXP_CSC2_COEF4_C3(0x7f2), /* -0.0547 (+0.03 %) */ + BF_PXP_CSC2_COEF5_D3(128) | + BF_PXP_CSC2_COEF5_D2(128), + }; + const u32 *csc2_coef; + u32 csc2_ctrl; + + ycbcr_enc = ctx->q_data[V4L2_M2M_DST].ycbcr_enc; + quantization = ctx->q_data[V4L2_M2M_DST].quant; + + if (ycbcr_enc == V4L2_YCBCR_ENC_601) { + if (quantization == V4L2_QUANTIZATION_FULL_RANGE) + csc2_coef = csc2_coef_bt601_full; + else + csc2_coef = csc2_coef_bt601_lim; + } else if (ycbcr_enc == V4L2_YCBCR_ENC_709) { + if (quantization == V4L2_QUANTIZATION_FULL_RANGE) + csc2_coef = csc2_coef_rec709_full; + else + csc2_coef = csc2_coef_rec709_lim; + } else if (ycbcr_enc == V4L2_YCBCR_ENC_709) { + if (quantization == V4L2_QUANTIZATION_FULL_RANGE) + csc2_coef = csc2_coef_bt2020_full; + else + csc2_coef = csc2_coef_bt2020_lim; + } else { + if (quantization == V4L2_QUANTIZATION_FULL_RANGE) + csc2_coef = csc2_coef_smpte240m_full; + else + csc2_coef = csc2_coef_smpte240m_lim; + } + if (quantization == V4L2_QUANTIZATION_FULL_RANGE) { + csc2_ctrl = BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YUV << + BP_PXP_CSC2_CTRL_CSC_MODE; + } else { + csc2_ctrl = BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YCbCr << + BP_PXP_CSC2_CTRL_CSC_MODE; + } + + writel(csc2_ctrl, dev->mmio + HW_PXP_CSC2_CTRL); + writel(csc2_coef[0], dev->mmio + HW_PXP_CSC2_COEF0); + writel(csc2_coef[1], dev->mmio + HW_PXP_CSC2_COEF1); + writel(csc2_coef[2], dev->mmio + HW_PXP_CSC2_COEF2); + writel(csc2_coef[3], dev->mmio + HW_PXP_CSC2_COEF3); + writel(csc2_coef[4], dev->mmio + HW_PXP_CSC2_COEF4); + writel(csc2_coef[5], dev->mmio + HW_PXP_CSC2_COEF5); + } else { + writel(BM_PXP_CSC2_CTRL_BYPASS, dev->mmio + HW_PXP_CSC2_CTRL); + } +} + +static int pxp_start(struct pxp_ctx *ctx, struct vb2_v4l2_buffer *in_vb, + struct vb2_v4l2_buffer *out_vb) +{ + struct pxp_dev *dev = ctx->dev; + struct pxp_q_data *q_data; + u32 src_width, src_height, src_stride, src_fourcc; + u32 dst_width, dst_height, dst_stride, dst_fourcc; + dma_addr_t p_in, p_out; + u32 ctrl, out_ctrl, out_buf, out_buf2, out_pitch, out_lrc, out_ps_ulc; + u32 out_ps_lrc; + u32 ps_ctrl, ps_buf, ps_ubuf, ps_vbuf, ps_pitch, ps_scale, ps_offset; + u32 as_ulc, as_lrc; + u32 y_size; + u32 decx, decy, xscale, yscale; + + q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); + + src_width = ctx->q_data[V4L2_M2M_SRC].width; + dst_width = ctx->q_data[V4L2_M2M_DST].width; + src_height = ctx->q_data[V4L2_M2M_SRC].height; + dst_height = ctx->q_data[V4L2_M2M_DST].height; + src_stride = ctx->q_data[V4L2_M2M_SRC].bytesperline; + dst_stride = ctx->q_data[V4L2_M2M_DST].bytesperline; + src_fourcc = ctx->q_data[V4L2_M2M_SRC].fmt->fourcc; + dst_fourcc = ctx->q_data[V4L2_M2M_DST].fmt->fourcc; + + p_in = vb2_dma_contig_plane_dma_addr(&in_vb->vb2_buf, 0); + p_out = vb2_dma_contig_plane_dma_addr(&out_vb->vb2_buf, 0); + + if (!p_in || !p_out) { + v4l2_err(&dev->v4l2_dev, + "Acquiring DMA addresses of buffers failed\n"); + return -EFAULT; + } + + out_vb->sequence = + get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE)->sequence++; + in_vb->sequence = q_data->sequence++; + out_vb->vb2_buf.timestamp = in_vb->vb2_buf.timestamp; + + if (in_vb->flags & V4L2_BUF_FLAG_TIMECODE) + out_vb->timecode = in_vb->timecode; + out_vb->field = in_vb->field; + out_vb->flags = in_vb->flags & + (V4L2_BUF_FLAG_TIMECODE | + V4L2_BUF_FLAG_KEYFRAME | + V4L2_BUF_FLAG_PFRAME | + V4L2_BUF_FLAG_BFRAME | + V4L2_BUF_FLAG_TSTAMP_SRC_MASK); + + /* Rotation disabled, 8x8 block size */ + ctrl = BF_PXP_CTRL_VFLIP0(!!(ctx->mode & MEM2MEM_VFLIP)) | + BF_PXP_CTRL_HFLIP0(!!(ctx->mode & MEM2MEM_HFLIP)); + /* Always write alpha value as V4L2_CID_ALPHA_COMPONENT */ + out_ctrl = BF_PXP_OUT_CTRL_ALPHA(ctx->alpha_component) | + BF_PXP_OUT_CTRL_ALPHA_OUTPUT(1) | + pxp_v4l2_pix_fmt_to_out_format(dst_fourcc); + out_buf = p_out; + switch (dst_fourcc) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + out_buf2 = out_buf + dst_stride * dst_height; + break; + default: + out_buf2 = 0; + } + + out_pitch = BF_PXP_OUT_PITCH_PITCH(dst_stride); + out_lrc = BF_PXP_OUT_LRC_X(dst_width - 1) | + BF_PXP_OUT_LRC_Y(dst_height - 1); + /* PS covers whole output */ + out_ps_ulc = BF_PXP_OUT_PS_ULC_X(0) | BF_PXP_OUT_PS_ULC_Y(0); + out_ps_lrc = BF_PXP_OUT_PS_LRC_X(dst_width - 1) | + BF_PXP_OUT_PS_LRC_Y(dst_height - 1); + /* no AS */ + as_ulc = BF_PXP_OUT_AS_ULC_X(1) | BF_PXP_OUT_AS_ULC_Y(1); + as_lrc = BF_PXP_OUT_AS_LRC_X(0) | BF_PXP_OUT_AS_LRC_Y(0); + + decx = (src_width <= dst_width) ? 0 : ilog2(src_width / dst_width); + decy = (src_height <= dst_height) ? 0 : ilog2(src_height / dst_height); + ps_ctrl = BF_PXP_PS_CTRL_DECX(decx) | BF_PXP_PS_CTRL_DECY(decy) | + pxp_v4l2_pix_fmt_to_ps_format(src_fourcc); + ps_buf = p_in; + y_size = src_stride * src_height; + switch (src_fourcc) { + case V4L2_PIX_FMT_YUV420: + ps_ubuf = ps_buf + y_size; + ps_vbuf = ps_ubuf + y_size / 4; + break; + case V4L2_PIX_FMT_YUV422P: + ps_ubuf = ps_buf + y_size; + ps_vbuf = ps_ubuf + y_size / 2; + break; + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + ps_ubuf = ps_buf + y_size; + ps_vbuf = 0; + break; + case V4L2_PIX_FMT_GREY: + case V4L2_PIX_FMT_Y4: + ps_ubuf = 0; + /* In grayscale mode, ps_vbuf contents are reused as CbCr */ + ps_vbuf = 0x8080; + break; + default: + ps_ubuf = 0; + ps_vbuf = 0; + break; + } + ps_pitch = BF_PXP_PS_PITCH_PITCH(src_stride); + if (decx) { + xscale = (src_width >> decx) * 0x1000 / dst_width; + } else { + switch (src_fourcc) { + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_VYUY: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_YUV422P: + case V4L2_PIX_FMT_YUV420: + /* + * This avoids sampling past the right edge for + * horizontally chroma subsampled formats. + */ + xscale = (src_width - 2) * 0x1000 / (dst_width - 1); + break; + default: + xscale = (src_width - 1) * 0x1000 / (dst_width - 1); + break; + } + } + if (decy) + yscale = (src_height >> decy) * 0x1000 / dst_height; + else + yscale = (src_height - 1) * 0x1000 / (dst_height - 1); + ps_scale = BF_PXP_PS_SCALE_YSCALE(yscale) | + BF_PXP_PS_SCALE_XSCALE(xscale); + ps_offset = BF_PXP_PS_OFFSET_YOFFSET(0) | BF_PXP_PS_OFFSET_XOFFSET(0); + + writel(ctrl, dev->mmio + HW_PXP_CTRL); + /* skip STAT */ + writel(out_ctrl, dev->mmio + HW_PXP_OUT_CTRL); + writel(out_buf, dev->mmio + HW_PXP_OUT_BUF); + writel(out_buf2, dev->mmio + HW_PXP_OUT_BUF2); + writel(out_pitch, dev->mmio + HW_PXP_OUT_PITCH); + writel(out_lrc, dev->mmio + HW_PXP_OUT_LRC); + writel(out_ps_ulc, dev->mmio + HW_PXP_OUT_PS_ULC); + writel(out_ps_lrc, dev->mmio + HW_PXP_OUT_PS_LRC); + writel(as_ulc, dev->mmio + HW_PXP_OUT_AS_ULC); + writel(as_lrc, dev->mmio + HW_PXP_OUT_AS_LRC); + writel(ps_ctrl, dev->mmio + HW_PXP_PS_CTRL); + writel(ps_buf, dev->mmio + HW_PXP_PS_BUF); + writel(ps_ubuf, dev->mmio + HW_PXP_PS_UBUF); + writel(ps_vbuf, dev->mmio + HW_PXP_PS_VBUF); + writel(ps_pitch, dev->mmio + HW_PXP_PS_PITCH); + writel(0x00ffffff, dev->mmio + HW_PXP_PS_BACKGROUND_0); + writel(ps_scale, dev->mmio + HW_PXP_PS_SCALE); + writel(ps_offset, dev->mmio + HW_PXP_PS_OFFSET); + /* disable processed surface color keying */ + writel(0x00ffffff, dev->mmio + HW_PXP_PS_CLRKEYLOW_0); + writel(0x00000000, dev->mmio + HW_PXP_PS_CLRKEYHIGH_0); + + /* disable alpha surface color keying */ + writel(0x00ffffff, dev->mmio + HW_PXP_AS_CLRKEYLOW_0); + writel(0x00000000, dev->mmio + HW_PXP_AS_CLRKEYHIGH_0); + + /* setup CSC */ + pxp_setup_csc(ctx); + + /* bypass LUT */ + writel(BM_PXP_LUT_CTRL_BYPASS, dev->mmio + HW_PXP_LUT_CTRL); + + writel(BF_PXP_DATA_PATH_CTRL0_MUX15_SEL(0)| + BF_PXP_DATA_PATH_CTRL0_MUX14_SEL(1)| + BF_PXP_DATA_PATH_CTRL0_MUX13_SEL(0)| + BF_PXP_DATA_PATH_CTRL0_MUX12_SEL(0)| + BF_PXP_DATA_PATH_CTRL0_MUX11_SEL(0)| + BF_PXP_DATA_PATH_CTRL0_MUX10_SEL(0)| + BF_PXP_DATA_PATH_CTRL0_MUX9_SEL(1)| + BF_PXP_DATA_PATH_CTRL0_MUX8_SEL(0)| + BF_PXP_DATA_PATH_CTRL0_MUX7_SEL(0)| + BF_PXP_DATA_PATH_CTRL0_MUX6_SEL(0)| + BF_PXP_DATA_PATH_CTRL0_MUX5_SEL(0)| + BF_PXP_DATA_PATH_CTRL0_MUX4_SEL(0)| + BF_PXP_DATA_PATH_CTRL0_MUX3_SEL(0)| + BF_PXP_DATA_PATH_CTRL0_MUX2_SEL(0)| + BF_PXP_DATA_PATH_CTRL0_MUX1_SEL(0)| + BF_PXP_DATA_PATH_CTRL0_MUX0_SEL(0), + dev->mmio + HW_PXP_DATA_PATH_CTRL0); + writel(BF_PXP_DATA_PATH_CTRL1_MUX17_SEL(1) | + BF_PXP_DATA_PATH_CTRL1_MUX16_SEL(1), + dev->mmio + HW_PXP_DATA_PATH_CTRL1); + + writel(0xffff, dev->mmio + HW_PXP_IRQ_MASK); + + /* ungate, enable PS/AS/OUT and PXP operation */ + writel(BM_PXP_CTRL_IRQ_ENABLE, dev->mmio + HW_PXP_CTRL_SET); + writel(BM_PXP_CTRL_ENABLE | BM_PXP_CTRL_ENABLE_CSC2 | + BM_PXP_CTRL_ENABLE_LUT | BM_PXP_CTRL_ENABLE_ROTATE0 | + BM_PXP_CTRL_ENABLE_PS_AS_OUT, dev->mmio + HW_PXP_CTRL_SET); + + return 0; +} + +static void pxp_job_finish(struct pxp_dev *dev) +{ + struct pxp_ctx *curr_ctx; + struct vb2_v4l2_buffer *src_vb, *dst_vb; + unsigned long flags; + + curr_ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev); + + if (curr_ctx == NULL) { + pr_err("Instance released before the end of transaction\n"); + return; + } + + src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx); + dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx); + + spin_lock_irqsave(&dev->irqlock, flags); + v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE); + v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE); + spin_unlock_irqrestore(&dev->irqlock, flags); + + dprintk(curr_ctx->dev, "Finishing transaction\n"); + v4l2_m2m_job_finish(dev->m2m_dev, curr_ctx->fh.m2m_ctx); +} + +/* + * mem2mem callbacks + */ +static void pxp_device_run(void *priv) +{ + struct pxp_ctx *ctx = priv; + struct vb2_v4l2_buffer *src_buf, *dst_buf; + + src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); + + pxp_start(ctx, src_buf, dst_buf); +} + +static int pxp_job_ready(void *priv) +{ + struct pxp_ctx *ctx = priv; + + if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) < 1 || + v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) < 1) { + dprintk(ctx->dev, "Not enough buffers available\n"); + return 0; + } + + return 1; +} + +static void pxp_job_abort(void *priv) +{ + struct pxp_ctx *ctx = priv; + + /* Will cancel the transaction in the next interrupt handler */ + ctx->aborting = 1; +} + +/* + * interrupt handler + */ +static irqreturn_t pxp_irq_handler(int irq, void *dev_id) +{ + struct pxp_dev *dev = dev_id; + u32 stat; + + stat = readl(dev->mmio + HW_PXP_STAT); + + if (stat & BM_PXP_STAT_IRQ0) { + /* we expect x = 0, y = height, irq0 = 1 */ + if (stat & ~(BM_PXP_STAT_BLOCKX | BM_PXP_STAT_BLOCKY | + BM_PXP_STAT_IRQ0)) + dprintk(dev, "%s: stat = 0x%08x\n", __func__, stat); + writel(BM_PXP_STAT_IRQ0, dev->mmio + HW_PXP_STAT_CLR); + + pxp_job_finish(dev); + } else { + u32 irq = readl(dev->mmio + HW_PXP_IRQ); + + dprintk(dev, "%s: stat = 0x%08x\n", __func__, stat); + dprintk(dev, "%s: irq = 0x%08x\n", __func__, irq); + + writel(irq, dev->mmio + HW_PXP_IRQ_CLR); + } + + return IRQ_HANDLED; +} + +/* + * video ioctls + */ +static int pxp_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + strlcpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver)); + strlcpy(cap->card, MEM2MEM_NAME, sizeof(cap->card)); + snprintf(cap->bus_info, sizeof(cap->bus_info), + "platform:%s", MEM2MEM_NAME); + return 0; +} + +static int pxp_enum_fmt(struct v4l2_fmtdesc *f, u32 type) +{ + int i, num; + struct pxp_fmt *fmt; + + num = 0; + + for (i = 0; i < NUM_FORMATS; ++i) { + if (formats[i].types & type) { + /* index-th format of type type found ? */ + if (num == f->index) + break; + /* + * Correct type but haven't reached our index yet, + * just increment per-type index + */ + ++num; + } + } + + if (i < NUM_FORMATS) { + /* Format found */ + fmt = &formats[i]; + f->pixelformat = fmt->fourcc; + return 0; + } + + /* Format not found */ + return -EINVAL; +} + +static int pxp_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + return pxp_enum_fmt(f, MEM2MEM_CAPTURE); +} + +static int pxp_enum_fmt_vid_out(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + return pxp_enum_fmt(f, MEM2MEM_OUTPUT); +} + +static int pxp_g_fmt(struct pxp_ctx *ctx, struct v4l2_format *f) +{ + struct vb2_queue *vq; + struct pxp_q_data *q_data; + + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); + if (!vq) + return -EINVAL; + + q_data = get_q_data(ctx, f->type); + + f->fmt.pix.width = q_data->width; + f->fmt.pix.height = q_data->height; + f->fmt.pix.field = V4L2_FIELD_NONE; + f->fmt.pix.pixelformat = q_data->fmt->fourcc; + f->fmt.pix.bytesperline = q_data->bytesperline; + f->fmt.pix.sizeimage = q_data->sizeimage; + f->fmt.pix.colorspace = ctx->colorspace; + f->fmt.pix.xfer_func = ctx->xfer_func; + f->fmt.pix.ycbcr_enc = q_data->ycbcr_enc; + f->fmt.pix.quantization = q_data->quant; + + return 0; +} + +static int pxp_g_fmt_vid_out(struct file *file, void *priv, + struct v4l2_format *f) +{ + return pxp_g_fmt(file2ctx(file), f); +} + +static int pxp_g_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + return pxp_g_fmt(file2ctx(file), f); +} + +static inline u32 pxp_bytesperline(struct pxp_fmt *fmt, u32 width) +{ + switch (fmt->fourcc) { + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_YUV422P: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + return width; + default: + return (width * fmt->depth) >> 3; + } +} + +static inline u32 pxp_sizeimage(struct pxp_fmt *fmt, u32 width, u32 height) +{ + return (fmt->depth * width * height) >> 3; +} + +static int pxp_try_fmt(struct v4l2_format *f, struct pxp_fmt *fmt) +{ + v4l_bound_align_image(&f->fmt.pix.width, MIN_W, MAX_W, ALIGN_W, + &f->fmt.pix.height, MIN_H, MAX_H, ALIGN_H, 0); + + f->fmt.pix.bytesperline = pxp_bytesperline(fmt, f->fmt.pix.width); + f->fmt.pix.sizeimage = pxp_sizeimage(fmt, f->fmt.pix.width, + f->fmt.pix.height); + f->fmt.pix.field = V4L2_FIELD_NONE; + + return 0; +} + +static void +pxp_fixup_colorimetry_cap(struct pxp_ctx *ctx, u32 dst_fourcc, + enum v4l2_ycbcr_encoding *ycbcr_enc, + enum v4l2_quantization *quantization) +{ + bool dst_is_yuv = pxp_v4l2_pix_fmt_is_yuv(dst_fourcc); + + if (pxp_v4l2_pix_fmt_is_yuv(ctx->q_data[V4L2_M2M_SRC].fmt->fourcc) == + dst_is_yuv) { + /* + * There is no support for conversion between different YCbCr + * encodings or between RGB limited and full range. + */ + *ycbcr_enc = ctx->q_data[V4L2_M2M_SRC].ycbcr_enc; + *quantization = ctx->q_data[V4L2_M2M_SRC].quant; + } else { + *ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(ctx->colorspace); + *quantization = V4L2_MAP_QUANTIZATION_DEFAULT(!dst_is_yuv, + ctx->colorspace, + *ycbcr_enc); + } +} + +static int pxp_try_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct pxp_fmt *fmt; + struct pxp_ctx *ctx = file2ctx(file); + + fmt = find_format(f); + if (!fmt) { + f->fmt.pix.pixelformat = formats[0].fourcc; + fmt = find_format(f); + } + if (!(fmt->types & MEM2MEM_CAPTURE)) { + v4l2_err(&ctx->dev->v4l2_dev, + "Fourcc format (0x%08x) invalid.\n", + f->fmt.pix.pixelformat); + return -EINVAL; + } + + f->fmt.pix.colorspace = ctx->colorspace; + f->fmt.pix.xfer_func = ctx->xfer_func; + + pxp_fixup_colorimetry_cap(ctx, fmt->fourcc, + &f->fmt.pix.ycbcr_enc, + &f->fmt.pix.quantization); + + return pxp_try_fmt(f, fmt); +} + +static int pxp_try_fmt_vid_out(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct pxp_fmt *fmt; + struct pxp_ctx *ctx = file2ctx(file); + + fmt = find_format(f); + if (!fmt) { + f->fmt.pix.pixelformat = formats[0].fourcc; + fmt = find_format(f); + } + if (!(fmt->types & MEM2MEM_OUTPUT)) { + v4l2_err(&ctx->dev->v4l2_dev, + "Fourcc format (0x%08x) invalid.\n", + f->fmt.pix.pixelformat); + return -EINVAL; + } + + if (!f->fmt.pix.colorspace) + f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709; + + return pxp_try_fmt(f, fmt); +} + +static int pxp_s_fmt(struct pxp_ctx *ctx, struct v4l2_format *f) +{ + struct pxp_q_data *q_data; + struct vb2_queue *vq; + + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); + if (!vq) + return -EINVAL; + + q_data = get_q_data(ctx, f->type); + if (!q_data) + return -EINVAL; + + if (vb2_is_busy(vq)) { + v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__); + return -EBUSY; + } + + q_data->fmt = find_format(f); + q_data->width = f->fmt.pix.width; + q_data->height = f->fmt.pix.height; + q_data->bytesperline = f->fmt.pix.bytesperline; + q_data->sizeimage = f->fmt.pix.sizeimage; + + dprintk(ctx->dev, + "Setting format for type %d, wxh: %dx%d, fmt: %d\n", + f->type, q_data->width, q_data->height, q_data->fmt->fourcc); + + return 0; +} + +static int pxp_s_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct pxp_ctx *ctx = file2ctx(file); + int ret; + + ret = pxp_try_fmt_vid_cap(file, priv, f); + if (ret) + return ret; + + ret = pxp_s_fmt(file2ctx(file), f); + if (ret) + return ret; + + ctx->q_data[V4L2_M2M_DST].ycbcr_enc = f->fmt.pix.ycbcr_enc; + ctx->q_data[V4L2_M2M_DST].quant = f->fmt.pix.quantization; + + return 0; +} + +static int pxp_s_fmt_vid_out(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct pxp_ctx *ctx = file2ctx(file); + int ret; + + ret = pxp_try_fmt_vid_out(file, priv, f); + if (ret) + return ret; + + ret = pxp_s_fmt(file2ctx(file), f); + if (ret) + return ret; + + ctx->colorspace = f->fmt.pix.colorspace; + ctx->xfer_func = f->fmt.pix.xfer_func; + ctx->q_data[V4L2_M2M_SRC].ycbcr_enc = f->fmt.pix.ycbcr_enc; + ctx->q_data[V4L2_M2M_SRC].quant = f->fmt.pix.quantization; + + pxp_fixup_colorimetry_cap(ctx, ctx->q_data[V4L2_M2M_DST].fmt->fourcc, + &ctx->q_data[V4L2_M2M_DST].ycbcr_enc, + &ctx->q_data[V4L2_M2M_DST].quant); + + return 0; +} + +static int pxp_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct pxp_ctx *ctx = + container_of(ctrl->handler, struct pxp_ctx, hdl); + + switch (ctrl->id) { + case V4L2_CID_HFLIP: + if (ctrl->val) + ctx->mode |= MEM2MEM_HFLIP; + else + ctx->mode &= ~MEM2MEM_HFLIP; + break; + + case V4L2_CID_VFLIP: + if (ctrl->val) + ctx->mode |= MEM2MEM_VFLIP; + else + ctx->mode &= ~MEM2MEM_VFLIP; + break; + + case V4L2_CID_ALPHA_COMPONENT: + ctx->alpha_component = ctrl->val; + break; + + default: + v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n"); + return -EINVAL; + } + + return 0; +} + +static const struct v4l2_ctrl_ops pxp_ctrl_ops = { + .s_ctrl = pxp_s_ctrl, +}; + +static const struct v4l2_ioctl_ops pxp_ioctl_ops = { + .vidioc_querycap = pxp_querycap, + + .vidioc_enum_fmt_vid_cap = pxp_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = pxp_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = pxp_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = pxp_s_fmt_vid_cap, + + .vidioc_enum_fmt_vid_out = pxp_enum_fmt_vid_out, + .vidioc_g_fmt_vid_out = pxp_g_fmt_vid_out, + .vidioc_try_fmt_vid_out = pxp_try_fmt_vid_out, + .vidioc_s_fmt_vid_out = pxp_s_fmt_vid_out, + + .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, + .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, + .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, + .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, + .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, + .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, + + .vidioc_streamon = v4l2_m2m_ioctl_streamon, + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, + + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, +}; + +/* + * Queue operations + */ +static int pxp_queue_setup(struct vb2_queue *vq, + unsigned int *nbuffers, unsigned int *nplanes, + unsigned int sizes[], struct device *alloc_devs[]) +{ + struct pxp_ctx *ctx = vb2_get_drv_priv(vq); + struct pxp_q_data *q_data; + unsigned int size, count = *nbuffers; + + q_data = get_q_data(ctx, vq->type); + + size = q_data->sizeimage; + + *nbuffers = count; + + if (*nplanes) + return sizes[0] < size ? -EINVAL : 0; + + *nplanes = 1; + sizes[0] = size; + + dprintk(ctx->dev, "get %d buffer(s) of size %d each.\n", count, size); + + return 0; +} + +static int pxp_buf_prepare(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct pxp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct pxp_dev *dev = ctx->dev; + struct pxp_q_data *q_data; + + dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type); + + q_data = get_q_data(ctx, vb->vb2_queue->type); + if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { + if (vbuf->field == V4L2_FIELD_ANY) + vbuf->field = V4L2_FIELD_NONE; + if (vbuf->field != V4L2_FIELD_NONE) { + dprintk(dev, "%s field isn't supported\n", __func__); + return -EINVAL; + } + } + + if (vb2_plane_size(vb, 0) < q_data->sizeimage) { + dprintk(dev, "%s data will not fit into plane (%lu < %lu)\n", + __func__, vb2_plane_size(vb, 0), + (long)q_data->sizeimage); + return -EINVAL; + } + + vb2_set_plane_payload(vb, 0, q_data->sizeimage); + + return 0; +} + +static void pxp_buf_queue(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct pxp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + + v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); +} + +static int pxp_start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct pxp_ctx *ctx = vb2_get_drv_priv(q); + struct pxp_q_data *q_data = get_q_data(ctx, q->type); + + q_data->sequence = 0; + return 0; +} + +static void pxp_stop_streaming(struct vb2_queue *q) +{ + struct pxp_ctx *ctx = vb2_get_drv_priv(q); + struct vb2_v4l2_buffer *vbuf; + unsigned long flags; + + for (;;) { + if (V4L2_TYPE_IS_OUTPUT(q->type)) + vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + else + vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + if (vbuf == NULL) + return; + spin_lock_irqsave(&ctx->dev->irqlock, flags); + v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); + spin_unlock_irqrestore(&ctx->dev->irqlock, flags); + } +} + +static const struct vb2_ops pxp_qops = { + .queue_setup = pxp_queue_setup, + .buf_prepare = pxp_buf_prepare, + .buf_queue = pxp_buf_queue, + .start_streaming = pxp_start_streaming, + .stop_streaming = pxp_stop_streaming, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, +}; + +static int queue_init(void *priv, struct vb2_queue *src_vq, + struct vb2_queue *dst_vq) +{ + struct pxp_ctx *ctx = priv; + int ret; + + src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + src_vq->io_modes = VB2_MMAP | VB2_DMABUF; + src_vq->drv_priv = ctx; + src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + src_vq->ops = &pxp_qops; + src_vq->mem_ops = &vb2_dma_contig_memops; + src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + src_vq->lock = &ctx->dev->dev_mutex; + src_vq->dev = ctx->dev->v4l2_dev.dev; + + ret = vb2_queue_init(src_vq); + if (ret) + return ret; + + dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; + dst_vq->drv_priv = ctx; + dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + dst_vq->ops = &pxp_qops; + dst_vq->mem_ops = &vb2_dma_contig_memops; + dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + dst_vq->lock = &ctx->dev->dev_mutex; + dst_vq->dev = ctx->dev->v4l2_dev.dev; + + return vb2_queue_init(dst_vq); +} + +/* + * File operations + */ +static int pxp_open(struct file *file) +{ + struct pxp_dev *dev = video_drvdata(file); + struct pxp_ctx *ctx = NULL; + struct v4l2_ctrl_handler *hdl; + int rc = 0; + + if (mutex_lock_interruptible(&dev->dev_mutex)) + return -ERESTARTSYS; + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) { + rc = -ENOMEM; + goto open_unlock; + } + + v4l2_fh_init(&ctx->fh, video_devdata(file)); + file->private_data = &ctx->fh; + ctx->dev = dev; + hdl = &ctx->hdl; + v4l2_ctrl_handler_init(hdl, 4); + v4l2_ctrl_new_std(hdl, &pxp_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(hdl, &pxp_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(hdl, &pxp_ctrl_ops, V4L2_CID_ALPHA_COMPONENT, + 0, 255, 1, 255); + if (hdl->error) { + rc = hdl->error; + v4l2_ctrl_handler_free(hdl); + kfree(ctx); + goto open_unlock; + } + ctx->fh.ctrl_handler = hdl; + v4l2_ctrl_handler_setup(hdl); + + ctx->q_data[V4L2_M2M_SRC].fmt = &formats[0]; + ctx->q_data[V4L2_M2M_SRC].width = 640; + ctx->q_data[V4L2_M2M_SRC].height = 480; + ctx->q_data[V4L2_M2M_SRC].bytesperline = + pxp_bytesperline(&formats[0], 640); + ctx->q_data[V4L2_M2M_SRC].sizeimage = + pxp_sizeimage(&formats[0], 640, 480); + ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC]; + ctx->colorspace = V4L2_COLORSPACE_REC709; + + ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init); + + if (IS_ERR(ctx->fh.m2m_ctx)) { + rc = PTR_ERR(ctx->fh.m2m_ctx); + + v4l2_ctrl_handler_free(hdl); + v4l2_fh_exit(&ctx->fh); + kfree(ctx); + goto open_unlock; + } + + v4l2_fh_add(&ctx->fh); + atomic_inc(&dev->num_inst); + + dprintk(dev, "Created instance: %p, m2m_ctx: %p\n", + ctx, ctx->fh.m2m_ctx); + +open_unlock: + mutex_unlock(&dev->dev_mutex); + return rc; +} + +static int pxp_release(struct file *file) +{ + struct pxp_dev *dev = video_drvdata(file); + struct pxp_ctx *ctx = file2ctx(file); + + dprintk(dev, "Releasing instance %p\n", ctx); + + v4l2_fh_del(&ctx->fh); + v4l2_fh_exit(&ctx->fh); + v4l2_ctrl_handler_free(&ctx->hdl); + mutex_lock(&dev->dev_mutex); + v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); + mutex_unlock(&dev->dev_mutex); + kfree(ctx); + + atomic_dec(&dev->num_inst); + + return 0; +} + +static const struct v4l2_file_operations pxp_fops = { + .owner = THIS_MODULE, + .open = pxp_open, + .release = pxp_release, + .poll = v4l2_m2m_fop_poll, + .unlocked_ioctl = video_ioctl2, + .mmap = v4l2_m2m_fop_mmap, +}; + +static const struct video_device pxp_videodev = { + .name = MEM2MEM_NAME, + .vfl_dir = VFL_DIR_M2M, + .fops = &pxp_fops, + .device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING, + .ioctl_ops = &pxp_ioctl_ops, + .minor = -1, + .release = video_device_release_empty, +}; + +static const struct v4l2_m2m_ops m2m_ops = { + .device_run = pxp_device_run, + .job_ready = pxp_job_ready, + .job_abort = pxp_job_abort, +}; + +static void pxp_soft_reset(struct pxp_dev *dev) +{ + int ret; + u32 val; + + writel(BM_PXP_CTRL_SFTRST, dev->mmio + HW_PXP_CTRL_CLR); + writel(BM_PXP_CTRL_CLKGATE, dev->mmio + HW_PXP_CTRL_CLR); + + writel(BM_PXP_CTRL_SFTRST, dev->mmio + HW_PXP_CTRL_SET); + + ret = readl_poll_timeout(dev->mmio + HW_PXP_CTRL, val, + val & BM_PXP_CTRL_CLKGATE, 0, 100); + if (ret < 0) + pr_err("PXP reset timeout\n"); + + writel(BM_PXP_CTRL_SFTRST, dev->mmio + HW_PXP_CTRL_CLR); + writel(BM_PXP_CTRL_CLKGATE, dev->mmio + HW_PXP_CTRL_CLR); +} + +static int pxp_probe(struct platform_device *pdev) +{ + struct pxp_dev *dev; + struct resource *res; + struct video_device *vfd; + int irq; + int ret; + + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + + dev->clk = devm_clk_get(&pdev->dev, "axi"); + if (IS_ERR(dev->clk)) { + ret = PTR_ERR(dev->clk); + dev_err(&pdev->dev, "Failed to get clk: %d\n", ret); + return ret; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + dev->mmio = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(dev->mmio)) { + ret = PTR_ERR(dev->mmio); + dev_err(&pdev->dev, "Failed to map register space: %d\n", ret); + return ret; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "Failed to get irq resource: %d\n", irq); + return irq; + } + + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, pxp_irq_handler, + IRQF_ONESHOT, dev_name(&pdev->dev), dev); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to request irq: %d\n", ret); + return ret; + } + + clk_prepare_enable(dev->clk); + pxp_soft_reset(dev); + + spin_lock_init(&dev->irqlock); + + ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); + if (ret) + goto err_clk; + + atomic_set(&dev->num_inst, 0); + mutex_init(&dev->dev_mutex); + + dev->vfd = pxp_videodev; + vfd = &dev->vfd; + vfd->lock = &dev->dev_mutex; + vfd->v4l2_dev = &dev->v4l2_dev; + + video_set_drvdata(vfd, dev); + snprintf(vfd->name, sizeof(vfd->name), "%s", pxp_videodev.name); + v4l2_info(&dev->v4l2_dev, + "Device registered as /dev/video%d\n", vfd->num); + + platform_set_drvdata(pdev, dev); + + dev->m2m_dev = v4l2_m2m_init(&m2m_ops); + if (IS_ERR(dev->m2m_dev)) { + v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n"); + ret = PTR_ERR(dev->m2m_dev); + goto err_v4l2; + } + + ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); + if (ret) { + v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); + goto err_m2m; + } + + return 0; + +err_m2m: + v4l2_m2m_release(dev->m2m_dev); +err_v4l2: + v4l2_device_unregister(&dev->v4l2_dev); +err_clk: + clk_disable_unprepare(dev->clk); + + return ret; +} + +static int pxp_remove(struct platform_device *pdev) +{ + struct pxp_dev *dev = platform_get_drvdata(pdev); + + writel(BM_PXP_CTRL_CLKGATE, dev->mmio + HW_PXP_CTRL_SET); + writel(BM_PXP_CTRL_SFTRST, dev->mmio + HW_PXP_CTRL_SET); + + clk_disable_unprepare(dev->clk); + + v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME); + video_unregister_device(&dev->vfd); + v4l2_m2m_release(dev->m2m_dev); + v4l2_device_unregister(&dev->v4l2_dev); + + return 0; +} + +static const struct of_device_id pxp_dt_ids[] = { + { .compatible = "fsl,imx6ull-pxp", .data = NULL }, + { }, +}; +MODULE_DEVICE_TABLE(of, pxp_dt_ids); + +static struct platform_driver pxp_driver = { + .probe = pxp_probe, + .remove = pxp_remove, + .driver = { + .name = MEM2MEM_NAME, + .of_match_table = of_match_ptr(pxp_dt_ids), + }, +}; + +module_platform_driver(pxp_driver); + +MODULE_DESCRIPTION("i.MX PXP mem2mem scaler/CSC/rotator"); +MODULE_AUTHOR("Philipp Zabel <kernel@pengutronix.de>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/platform/imx-pxp.h b/drivers/media/platform/imx-pxp.h new file mode 100644 index 000000000000..44f95c749d2e --- /dev/null +++ b/drivers/media/platform/imx-pxp.h @@ -0,0 +1,1685 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Freescale PXP Register Definitions + * + * based on pxp_dma_v3.h, Xml Revision: 1.77, Template Revision: 1.3 + * + * Copyright 2014-2015 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +#ifndef __IMX_PXP_H__ +#define __IMX_PXP_H__ + +#define HW_PXP_CTRL (0x00000000) +#define HW_PXP_CTRL_SET (0x00000004) +#define HW_PXP_CTRL_CLR (0x00000008) +#define HW_PXP_CTRL_TOG (0x0000000c) + +#define BM_PXP_CTRL_SFTRST 0x80000000 +#define BF_PXP_CTRL_SFTRST(v) \ + (((v) << 31) & BM_PXP_CTRL_SFTRST) +#define BM_PXP_CTRL_CLKGATE 0x40000000 +#define BF_PXP_CTRL_CLKGATE(v) \ + (((v) << 30) & BM_PXP_CTRL_CLKGATE) +#define BM_PXP_CTRL_RSVD4 0x20000000 +#define BF_PXP_CTRL_RSVD4(v) \ + (((v) << 29) & BM_PXP_CTRL_RSVD4) +#define BM_PXP_CTRL_EN_REPEAT 0x10000000 +#define BF_PXP_CTRL_EN_REPEAT(v) \ + (((v) << 28) & BM_PXP_CTRL_EN_REPEAT) +#define BM_PXP_CTRL_ENABLE_ROTATE1 0x08000000 +#define BF_PXP_CTRL_ENABLE_ROTATE1(v) \ + (((v) << 27) & BM_PXP_CTRL_ENABLE_ROTATE1) +#define BM_PXP_CTRL_ENABLE_ROTATE0 0x04000000 +#define BF_PXP_CTRL_ENABLE_ROTATE0(v) \ + (((v) << 26) & BM_PXP_CTRL_ENABLE_ROTATE0) +#define BM_PXP_CTRL_ENABLE_LUT 0x02000000 +#define BF_PXP_CTRL_ENABLE_LUT(v) \ + (((v) << 25) & BM_PXP_CTRL_ENABLE_LUT) +#define BM_PXP_CTRL_ENABLE_CSC2 0x01000000 +#define BF_PXP_CTRL_ENABLE_CSC2(v) \ + (((v) << 24) & BM_PXP_CTRL_ENABLE_CSC2) +#define BM_PXP_CTRL_BLOCK_SIZE 0x00800000 +#define BF_PXP_CTRL_BLOCK_SIZE(v) \ + (((v) << 23) & BM_PXP_CTRL_BLOCK_SIZE) +#define BV_PXP_CTRL_BLOCK_SIZE__8X8 0x0 +#define BV_PXP_CTRL_BLOCK_SIZE__16X16 0x1 +#define BM_PXP_CTRL_RSVD1 0x00400000 +#define BF_PXP_CTRL_RSVD1(v) \ + (((v) << 22) & BM_PXP_CTRL_RSVD1) +#define BM_PXP_CTRL_ENABLE_ALPHA_B 0x00200000 +#define BF_PXP_CTRL_ENABLE_ALPHA_B(v) \ + (((v) << 21) & BM_PXP_CTRL_ENABLE_ALPHA_B) +#define BM_PXP_CTRL_ENABLE_INPUT_FETCH_STORE 0x00100000 +#define BF_PXP_CTRL_ENABLE_INPUT_FETCH_STORE(v) \ + (((v) << 20) & BM_PXP_CTRL_ENABLE_INPUT_FETCH_STORE) +#define BM_PXP_CTRL_ENABLE_WFE_B 0x00080000 +#define BF_PXP_CTRL_ENABLE_WFE_B(v) \ + (((v) << 19) & BM_PXP_CTRL_ENABLE_WFE_B) +#define BM_PXP_CTRL_ENABLE_WFE_A 0x00040000 +#define BF_PXP_CTRL_ENABLE_WFE_A(v) \ + (((v) << 18) & BM_PXP_CTRL_ENABLE_WFE_A) +#define BM_PXP_CTRL_ENABLE_DITHER 0x00020000 +#define BF_PXP_CTRL_ENABLE_DITHER(v) \ + (((v) << 17) & BM_PXP_CTRL_ENABLE_DITHER) +#define BM_PXP_CTRL_ENABLE_PS_AS_OUT 0x00010000 +#define BF_PXP_CTRL_ENABLE_PS_AS_OUT(v) \ + (((v) << 16) & BM_PXP_CTRL_ENABLE_PS_AS_OUT) +#define BM_PXP_CTRL_VFLIP1 0x00008000 +#define BF_PXP_CTRL_VFLIP1(v) \ + (((v) << 15) & BM_PXP_CTRL_VFLIP1) +#define BM_PXP_CTRL_HFLIP1 0x00004000 +#define BF_PXP_CTRL_HFLIP1(v) \ + (((v) << 14) & BM_PXP_CTRL_HFLIP1) +#define BP_PXP_CTRL_ROTATE1 12 +#define BM_PXP_CTRL_ROTATE1 0x00003000 +#define BF_PXP_CTRL_ROTATE1(v) \ + (((v) << 12) & BM_PXP_CTRL_ROTATE1) +#define BV_PXP_CTRL_ROTATE1__ROT_0 0x0 +#define BV_PXP_CTRL_ROTATE1__ROT_90 0x1 +#define BV_PXP_CTRL_ROTATE1__ROT_180 0x2 +#define BV_PXP_CTRL_ROTATE1__ROT_270 0x3 +#define BM_PXP_CTRL_VFLIP0 0x00000800 +#define BF_PXP_CTRL_VFLIP0(v) \ + (((v) << 11) & BM_PXP_CTRL_VFLIP0) +#define BM_PXP_CTRL_HFLIP0 0x00000400 +#define BF_PXP_CTRL_HFLIP0(v) \ + (((v) << 10) & BM_PXP_CTRL_HFLIP0) +#define BP_PXP_CTRL_ROTATE0 8 +#define BM_PXP_CTRL_ROTATE0 0x00000300 +#define BF_PXP_CTRL_ROTATE0(v) \ + (((v) << 8) & BM_PXP_CTRL_ROTATE0) +#define BV_PXP_CTRL_ROTATE0__ROT_0 0x0 +#define BV_PXP_CTRL_ROTATE0__ROT_90 0x1 +#define BV_PXP_CTRL_ROTATE0__ROT_180 0x2 +#define BV_PXP_CTRL_ROTATE0__ROT_270 0x3 +#define BP_PXP_CTRL_RSVD0 6 +#define BM_PXP_CTRL_RSVD0 0x000000C0 +#define BF_PXP_CTRL_RSVD0(v) \ + (((v) << 6) & BM_PXP_CTRL_RSVD0) +#define BM_PXP_CTRL_HANDSHAKE_ABORT_SKIP 0x00000020 +#define BF_PXP_CTRL_HANDSHAKE_ABORT_SKIP(v) \ + (((v) << 5) & BM_PXP_CTRL_HANDSHAKE_ABORT_SKIP) +#define BM_PXP_CTRL_ENABLE_LCD0_HANDSHAKE 0x00000010 +#define BF_PXP_CTRL_ENABLE_LCD0_HANDSHAKE(v) \ + (((v) << 4) & BM_PXP_CTRL_ENABLE_LCD0_HANDSHAKE) +#define BM_PXP_CTRL_LUT_DMA_IRQ_ENABLE 0x00000008 +#define BF_PXP_CTRL_LUT_DMA_IRQ_ENABLE(v) \ + (((v) << 3) & BM_PXP_CTRL_LUT_DMA_IRQ_ENABLE) +#define BM_PXP_CTRL_NEXT_IRQ_ENABLE 0x00000004 +#define BF_PXP_CTRL_NEXT_IRQ_ENABLE(v) \ + (((v) << 2) & BM_PXP_CTRL_NEXT_IRQ_ENABLE) +#define BM_PXP_CTRL_IRQ_ENABLE 0x00000002 +#define BF_PXP_CTRL_IRQ_ENABLE(v) \ + (((v) << 1) & BM_PXP_CTRL_IRQ_ENABLE) +#define BM_PXP_CTRL_ENABLE 0x00000001 +#define BF_PXP_CTRL_ENABLE(v) \ + (((v) << 0) & BM_PXP_CTRL_ENABLE) + +#define HW_PXP_STAT (0x00000010) +#define HW_PXP_STAT_SET (0x00000014) +#define HW_PXP_STAT_CLR (0x00000018) +#define HW_PXP_STAT_TOG (0x0000001c) + +#define BP_PXP_STAT_BLOCKX 24 +#define BM_PXP_STAT_BLOCKX 0xFF000000 +#define BF_PXP_STAT_BLOCKX(v) \ + (((v) << 24) & BM_PXP_STAT_BLOCKX) +#define BP_PXP_STAT_BLOCKY 16 +#define BM_PXP_STAT_BLOCKY 0x00FF0000 +#define BF_PXP_STAT_BLOCKY(v) \ + (((v) << 16) & BM_PXP_STAT_BLOCKY) +#define BP_PXP_STAT_AXI_ERROR_ID_1 12 +#define BM_PXP_STAT_AXI_ERROR_ID_1 0x0000F000 +#define BF_PXP_STAT_AXI_ERROR_ID_1(v) \ + (((v) << 12) & BM_PXP_STAT_AXI_ERROR_ID_1) +#define BM_PXP_STAT_RSVD2 0x00000800 +#define BF_PXP_STAT_RSVD2(v) \ + (((v) << 11) & BM_PXP_STAT_RSVD2) +#define BM_PXP_STAT_AXI_READ_ERROR_1 0x00000400 +#define BF_PXP_STAT_AXI_READ_ERROR_1(v) \ + (((v) << 10) & BM_PXP_STAT_AXI_READ_ERROR_1) +#define BM_PXP_STAT_AXI_WRITE_ERROR_1 0x00000200 +#define BF_PXP_STAT_AXI_WRITE_ERROR_1(v) \ + (((v) << 9) & BM_PXP_STAT_AXI_WRITE_ERROR_1) +#define BM_PXP_STAT_LUT_DMA_LOAD_DONE_IRQ 0x00000100 +#define BF_PXP_STAT_LUT_DMA_LOAD_DONE_IRQ(v) \ + (((v) << 8) & BM_PXP_STAT_LUT_DMA_LOAD_DONE_IRQ) +#define BP_PXP_STAT_AXI_ERROR_ID_0 4 +#define BM_PXP_STAT_AXI_ERROR_ID_0 0x000000F0 +#define BF_PXP_STAT_AXI_ERROR_ID_0(v) \ + (((v) << 4) & BM_PXP_STAT_AXI_ERROR_ID_0) +#define BM_PXP_STAT_NEXT_IRQ 0x00000008 +#define BF_PXP_STAT_NEXT_IRQ(v) \ + (((v) << 3) & BM_PXP_STAT_NEXT_IRQ) +#define BM_PXP_STAT_AXI_READ_ERROR_0 0x00000004 +#define BF_PXP_STAT_AXI_READ_ERROR_0(v) \ + (((v) << 2) & BM_PXP_STAT_AXI_READ_ERROR_0) +#define BM_PXP_STAT_AXI_WRITE_ERROR_0 0x00000002 +#define BF_PXP_STAT_AXI_WRITE_ERROR_0(v) \ + (((v) << 1) & BM_PXP_STAT_AXI_WRITE_ERROR_0) +#define BM_PXP_STAT_IRQ0 0x00000001 +#define BF_PXP_STAT_IRQ0(v) \ + (((v) << 0) & BM_PXP_STAT_IRQ0) + +#define HW_PXP_OUT_CTRL (0x00000020) +#define HW_PXP_OUT_CTRL_SET (0x00000024) +#define HW_PXP_OUT_CTRL_CLR (0x00000028) +#define HW_PXP_OUT_CTRL_TOG (0x0000002c) + +#define BP_PXP_OUT_CTRL_ALPHA 24 +#define BM_PXP_OUT_CTRL_ALPHA 0xFF000000 +#define BF_PXP_OUT_CTRL_ALPHA(v) \ + (((v) << 24) & BM_PXP_OUT_CTRL_ALPHA) +#define BM_PXP_OUT_CTRL_ALPHA_OUTPUT 0x00800000 +#define BF_PXP_OUT_CTRL_ALPHA_OUTPUT(v) \ + (((v) << 23) & BM_PXP_OUT_CTRL_ALPHA_OUTPUT) +#define BP_PXP_OUT_CTRL_RSVD1 10 +#define BM_PXP_OUT_CTRL_RSVD1 0x007FFC00 +#define BF_PXP_OUT_CTRL_RSVD1(v) \ + (((v) << 10) & BM_PXP_OUT_CTRL_RSVD1) +#define BP_PXP_OUT_CTRL_INTERLACED_OUTPUT 8 +#define BM_PXP_OUT_CTRL_INTERLACED_OUTPUT 0x00000300 +#define BF_PXP_OUT_CTRL_INTERLACED_OUTPUT(v) \ + (((v) << 8) & BM_PXP_OUT_CTRL_INTERLACED_OUTPUT) +#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__PROGRESSIVE 0x0 +#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__FIELD0 0x1 +#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__FIELD1 0x2 +#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__INTERLACED 0x3 +#define BP_PXP_OUT_CTRL_RSVD0 5 +#define BM_PXP_OUT_CTRL_RSVD0 0x000000E0 +#define BF_PXP_OUT_CTRL_RSVD0(v) \ + (((v) << 5) & BM_PXP_OUT_CTRL_RSVD0) +#define BP_PXP_OUT_CTRL_FORMAT 0 +#define BM_PXP_OUT_CTRL_FORMAT 0x0000001F +#define BF_PXP_OUT_CTRL_FORMAT(v) \ + (((v) << 0) & BM_PXP_OUT_CTRL_FORMAT) +#define BV_PXP_OUT_CTRL_FORMAT__ARGB8888 0x0 +#define BV_PXP_OUT_CTRL_FORMAT__RGB888 0x4 +#define BV_PXP_OUT_CTRL_FORMAT__RGB888P 0x5 +#define BV_PXP_OUT_CTRL_FORMAT__ARGB1555 0x8 +#define BV_PXP_OUT_CTRL_FORMAT__ARGB4444 0x9 +#define BV_PXP_OUT_CTRL_FORMAT__RGB555 0xC +#define BV_PXP_OUT_CTRL_FORMAT__RGB444 0xD +#define BV_PXP_OUT_CTRL_FORMAT__RGB565 0xE +#define BV_PXP_OUT_CTRL_FORMAT__YUV1P444 0x10 +#define BV_PXP_OUT_CTRL_FORMAT__UYVY1P422 0x12 +#define BV_PXP_OUT_CTRL_FORMAT__VYUY1P422 0x13 +#define BV_PXP_OUT_CTRL_FORMAT__Y8 0x14 +#define BV_PXP_OUT_CTRL_FORMAT__Y4 0x15 +#define BV_PXP_OUT_CTRL_FORMAT__YUV2P422 0x18 +#define BV_PXP_OUT_CTRL_FORMAT__YUV2P420 0x19 +#define BV_PXP_OUT_CTRL_FORMAT__YVU2P422 0x1A +#define BV_PXP_OUT_CTRL_FORMAT__YVU2P420 0x1B + +#define HW_PXP_OUT_BUF (0x00000030) + +#define BP_PXP_OUT_BUF_ADDR 0 +#define BM_PXP_OUT_BUF_ADDR 0xFFFFFFFF +#define BF_PXP_OUT_BUF_ADDR(v) (v) + +#define HW_PXP_OUT_BUF2 (0x00000040) + +#define BP_PXP_OUT_BUF2_ADDR 0 +#define BM_PXP_OUT_BUF2_ADDR 0xFFFFFFFF +#define BF_PXP_OUT_BUF2_ADDR(v) (v) + +#define HW_PXP_OUT_PITCH (0x00000050) + +#define BP_PXP_OUT_PITCH_RSVD 16 +#define BM_PXP_OUT_PITCH_RSVD 0xFFFF0000 +#define BF_PXP_OUT_PITCH_RSVD(v) \ + (((v) << 16) & BM_PXP_OUT_PITCH_RSVD) +#define BP_PXP_OUT_PITCH_PITCH 0 +#define BM_PXP_OUT_PITCH_PITCH 0x0000FFFF +#define BF_PXP_OUT_PITCH_PITCH(v) \ + (((v) << 0) & BM_PXP_OUT_PITCH_PITCH) + +#define HW_PXP_OUT_LRC (0x00000060) + +#define BP_PXP_OUT_LRC_RSVD1 30 +#define BM_PXP_OUT_LRC_RSVD1 0xC0000000 +#define BF_PXP_OUT_LRC_RSVD1(v) \ + (((v) << 30) & BM_PXP_OUT_LRC_RSVD1) +#define BP_PXP_OUT_LRC_X 16 +#define BM_PXP_OUT_LRC_X 0x3FFF0000 +#define BF_PXP_OUT_LRC_X(v) \ + (((v) << 16) & BM_PXP_OUT_LRC_X) +#define BP_PXP_OUT_LRC_RSVD0 14 +#define BM_PXP_OUT_LRC_RSVD0 0x0000C000 +#define BF_PXP_OUT_LRC_RSVD0(v) \ + (((v) << 14) & BM_PXP_OUT_LRC_RSVD0) +#define BP_PXP_OUT_LRC_Y 0 +#define BM_PXP_OUT_LRC_Y 0x00003FFF +#define BF_PXP_OUT_LRC_Y(v) \ + (((v) << 0) & BM_PXP_OUT_LRC_Y) + +#define HW_PXP_OUT_PS_ULC (0x00000070) + +#define BP_PXP_OUT_PS_ULC_RSVD1 30 +#define BM_PXP_OUT_PS_ULC_RSVD1 0xC0000000 +#define BF_PXP_OUT_PS_ULC_RSVD1(v) \ + (((v) << 30) & BM_PXP_OUT_PS_ULC_RSVD1) +#define BP_PXP_OUT_PS_ULC_X 16 +#define BM_PXP_OUT_PS_ULC_X 0x3FFF0000 +#define BF_PXP_OUT_PS_ULC_X(v) \ + (((v) << 16) & BM_PXP_OUT_PS_ULC_X) +#define BP_PXP_OUT_PS_ULC_RSVD0 14 +#define BM_PXP_OUT_PS_ULC_RSVD0 0x0000C000 +#define BF_PXP_OUT_PS_ULC_RSVD0(v) \ + (((v) << 14) & BM_PXP_OUT_PS_ULC_RSVD0) +#define BP_PXP_OUT_PS_ULC_Y 0 +#define BM_PXP_OUT_PS_ULC_Y 0x00003FFF +#define BF_PXP_OUT_PS_ULC_Y(v) \ + (((v) << 0) & BM_PXP_OUT_PS_ULC_Y) + +#define HW_PXP_OUT_PS_LRC (0x00000080) + +#define BP_PXP_OUT_PS_LRC_RSVD1 30 +#define BM_PXP_OUT_PS_LRC_RSVD1 0xC0000000 +#define BF_PXP_OUT_PS_LRC_RSVD1(v) \ + (((v) << 30) & BM_PXP_OUT_PS_LRC_RSVD1) +#define BP_PXP_OUT_PS_LRC_X 16 +#define BM_PXP_OUT_PS_LRC_X 0x3FFF0000 +#define BF_PXP_OUT_PS_LRC_X(v) \ + (((v) << 16) & BM_PXP_OUT_PS_LRC_X) +#define BP_PXP_OUT_PS_LRC_RSVD0 14 +#define BM_PXP_OUT_PS_LRC_RSVD0 0x0000C000 +#define BF_PXP_OUT_PS_LRC_RSVD0(v) \ + (((v) << 14) & BM_PXP_OUT_PS_LRC_RSVD0) +#define BP_PXP_OUT_PS_LRC_Y 0 +#define BM_PXP_OUT_PS_LRC_Y 0x00003FFF +#define BF_PXP_OUT_PS_LRC_Y(v) \ + (((v) << 0) & BM_PXP_OUT_PS_LRC_Y) + +#define HW_PXP_OUT_AS_ULC (0x00000090) + +#define BP_PXP_OUT_AS_ULC_RSVD1 30 +#define BM_PXP_OUT_AS_ULC_RSVD1 0xC0000000 +#define BF_PXP_OUT_AS_ULC_RSVD1(v) \ + (((v) << 30) & BM_PXP_OUT_AS_ULC_RSVD1) +#define BP_PXP_OUT_AS_ULC_X 16 +#define BM_PXP_OUT_AS_ULC_X 0x3FFF0000 +#define BF_PXP_OUT_AS_ULC_X(v) \ + (((v) << 16) & BM_PXP_OUT_AS_ULC_X) +#define BP_PXP_OUT_AS_ULC_RSVD0 14 +#define BM_PXP_OUT_AS_ULC_RSVD0 0x0000C000 +#define BF_PXP_OUT_AS_ULC_RSVD0(v) \ + (((v) << 14) & BM_PXP_OUT_AS_ULC_RSVD0) +#define BP_PXP_OUT_AS_ULC_Y 0 +#define BM_PXP_OUT_AS_ULC_Y 0x00003FFF +#define BF_PXP_OUT_AS_ULC_Y(v) \ + (((v) << 0) & BM_PXP_OUT_AS_ULC_Y) + +#define HW_PXP_OUT_AS_LRC (0x000000a0) + +#define BP_PXP_OUT_AS_LRC_RSVD1 30 +#define BM_PXP_OUT_AS_LRC_RSVD1 0xC0000000 +#define BF_PXP_OUT_AS_LRC_RSVD1(v) \ + (((v) << 30) & BM_PXP_OUT_AS_LRC_RSVD1) +#define BP_PXP_OUT_AS_LRC_X 16 +#define BM_PXP_OUT_AS_LRC_X 0x3FFF0000 +#define BF_PXP_OUT_AS_LRC_X(v) \ + (((v) << 16) & BM_PXP_OUT_AS_LRC_X) +#define BP_PXP_OUT_AS_LRC_RSVD0 14 +#define BM_PXP_OUT_AS_LRC_RSVD0 0x0000C000 +#define BF_PXP_OUT_AS_LRC_RSVD0(v) \ + (((v) << 14) & BM_PXP_OUT_AS_LRC_RSVD0) +#define BP_PXP_OUT_AS_LRC_Y 0 +#define BM_PXP_OUT_AS_LRC_Y 0x00003FFF +#define BF_PXP_OUT_AS_LRC_Y(v) \ + (((v) << 0) & BM_PXP_OUT_AS_LRC_Y) + +#define HW_PXP_PS_CTRL (0x000000b0) +#define HW_PXP_PS_CTRL_SET (0x000000b4) +#define HW_PXP_PS_CTRL_CLR (0x000000b8) +#define HW_PXP_PS_CTRL_TOG (0x000000bc) + +#define BP_PXP_PS_CTRL_RSVD1 12 +#define BM_PXP_PS_CTRL_RSVD1 0xFFFFF000 +#define BF_PXP_PS_CTRL_RSVD1(v) \ + (((v) << 12) & BM_PXP_PS_CTRL_RSVD1) +#define BP_PXP_PS_CTRL_DECX 10 +#define BM_PXP_PS_CTRL_DECX 0x00000C00 +#define BF_PXP_PS_CTRL_DECX(v) \ + (((v) << 10) & BM_PXP_PS_CTRL_DECX) +#define BV_PXP_PS_CTRL_DECX__DISABLE 0x0 +#define BV_PXP_PS_CTRL_DECX__DECX2 0x1 +#define BV_PXP_PS_CTRL_DECX__DECX4 0x2 +#define BV_PXP_PS_CTRL_DECX__DECX8 0x3 +#define BP_PXP_PS_CTRL_DECY 8 +#define BM_PXP_PS_CTRL_DECY 0x00000300 +#define BF_PXP_PS_CTRL_DECY(v) \ + (((v) << 8) & BM_PXP_PS_CTRL_DECY) +#define BV_PXP_PS_CTRL_DECY__DISABLE 0x0 +#define BV_PXP_PS_CTRL_DECY__DECY2 0x1 +#define BV_PXP_PS_CTRL_DECY__DECY4 0x2 +#define BV_PXP_PS_CTRL_DECY__DECY8 0x3 +#define BM_PXP_PS_CTRL_RSVD0 0x00000080 +#define BF_PXP_PS_CTRL_RSVD0(v) \ + (((v) << 7) & BM_PXP_PS_CTRL_RSVD0) +#define BM_PXP_PS_CTRL_WB_SWAP 0x00000040 +#define BF_PXP_PS_CTRL_WB_SWAP(v) \ + (((v) << 6) & BM_PXP_PS_CTRL_WB_SWAP) +#define BP_PXP_PS_CTRL_FORMAT 0 +#define BM_PXP_PS_CTRL_FORMAT 0x0000003F +#define BF_PXP_PS_CTRL_FORMAT(v) \ + (((v) << 0) & BM_PXP_PS_CTRL_FORMAT) +#define BV_PXP_PS_CTRL_FORMAT__RGB888 0x4 +#define BV_PXP_PS_CTRL_FORMAT__RGB555 0xC +#define BV_PXP_PS_CTRL_FORMAT__RGB444 0xD +#define BV_PXP_PS_CTRL_FORMAT__RGB565 0xE +#define BV_PXP_PS_CTRL_FORMAT__YUV1P444 0x10 +#define BV_PXP_PS_CTRL_FORMAT__UYVY1P422 0x12 +#define BV_PXP_PS_CTRL_FORMAT__VYUY1P422 0x13 +#define BV_PXP_PS_CTRL_FORMAT__Y8 0x14 +#define BV_PXP_PS_CTRL_FORMAT__Y4 0x15 +#define BV_PXP_PS_CTRL_FORMAT__YUV2P422 0x18 +#define BV_PXP_PS_CTRL_FORMAT__YUV2P420 0x19 +#define BV_PXP_PS_CTRL_FORMAT__YVU2P422 0x1A +#define BV_PXP_PS_CTRL_FORMAT__YVU2P420 0x1B +#define BV_PXP_PS_CTRL_FORMAT__YUV422 0x1E +#define BV_PXP_PS_CTRL_FORMAT__YUV420 0x1F + +#define HW_PXP_PS_BUF (0x000000c0) + +#define BP_PXP_PS_BUF_ADDR 0 +#define BM_PXP_PS_BUF_ADDR 0xFFFFFFFF +#define BF_PXP_PS_BUF_ADDR(v) (v) + +#define HW_PXP_PS_UBUF (0x000000d0) + +#define BP_PXP_PS_UBUF_ADDR 0 +#define BM_PXP_PS_UBUF_ADDR 0xFFFFFFFF +#define BF_PXP_PS_UBUF_ADDR(v) (v) + +#define HW_PXP_PS_VBUF (0x000000e0) + +#define BP_PXP_PS_VBUF_ADDR 0 +#define BM_PXP_PS_VBUF_ADDR 0xFFFFFFFF +#define BF_PXP_PS_VBUF_ADDR(v) (v) + +#define HW_PXP_PS_PITCH (0x000000f0) + +#define BP_PXP_PS_PITCH_RSVD 16 +#define BM_PXP_PS_PITCH_RSVD 0xFFFF0000 +#define BF_PXP_PS_PITCH_RSVD(v) \ + (((v) << 16) & BM_PXP_PS_PITCH_RSVD) +#define BP_PXP_PS_PITCH_PITCH 0 +#define BM_PXP_PS_PITCH_PITCH 0x0000FFFF +#define BF_PXP_PS_PITCH_PITCH(v) \ + (((v) << 0) & BM_PXP_PS_PITCH_PITCH) + +#define HW_PXP_PS_BACKGROUND_0 (0x00000100) + +#define BP_PXP_PS_BACKGROUND_0_RSVD 24 +#define BM_PXP_PS_BACKGROUND_0_RSVD 0xFF000000 +#define BF_PXP_PS_BACKGROUND_0_RSVD(v) \ + (((v) << 24) & BM_PXP_PS_BACKGROUND_0_RSVD) +#define BP_PXP_PS_BACKGROUND_0_COLOR 0 +#define BM_PXP_PS_BACKGROUND_0_COLOR 0x00FFFFFF +#define BF_PXP_PS_BACKGROUND_0_COLOR(v) \ + (((v) << 0) & BM_PXP_PS_BACKGROUND_0_COLOR) + +#define HW_PXP_PS_SCALE (0x00000110) + +#define BM_PXP_PS_SCALE_RSVD2 0x80000000 +#define BF_PXP_PS_SCALE_RSVD2(v) \ + (((v) << 31) & BM_PXP_PS_SCALE_RSVD2) +#define BP_PXP_PS_SCALE_YSCALE 16 +#define BM_PXP_PS_SCALE_YSCALE 0x7FFF0000 +#define BF_PXP_PS_SCALE_YSCALE(v) \ + (((v) << 16) & BM_PXP_PS_SCALE_YSCALE) +#define BM_PXP_PS_SCALE_RSVD1 0x00008000 +#define BF_PXP_PS_SCALE_RSVD1(v) \ + (((v) << 15) & BM_PXP_PS_SCALE_RSVD1) +#define BP_PXP_PS_SCALE_XSCALE 0 +#define BM_PXP_PS_SCALE_XSCALE 0x00007FFF +#define BF_PXP_PS_SCALE_XSCALE(v) \ + (((v) << 0) & BM_PXP_PS_SCALE_XSCALE) + +#define HW_PXP_PS_OFFSET (0x00000120) + +#define BP_PXP_PS_OFFSET_RSVD2 28 +#define BM_PXP_PS_OFFSET_RSVD2 0xF0000000 +#define BF_PXP_PS_OFFSET_RSVD2(v) \ + (((v) << 28) & BM_PXP_PS_OFFSET_RSVD2) +#define BP_PXP_PS_OFFSET_YOFFSET 16 +#define BM_PXP_PS_OFFSET_YOFFSET 0x0FFF0000 +#define BF_PXP_PS_OFFSET_YOFFSET(v) \ + (((v) << 16) & BM_PXP_PS_OFFSET_YOFFSET) +#define BP_PXP_PS_OFFSET_RSVD1 12 +#define BM_PXP_PS_OFFSET_RSVD1 0x0000F000 +#define BF_PXP_PS_OFFSET_RSVD1(v) \ + (((v) << 12) & BM_PXP_PS_OFFSET_RSVD1) +#define BP_PXP_PS_OFFSET_XOFFSET 0 +#define BM_PXP_PS_OFFSET_XOFFSET 0x00000FFF +#define BF_PXP_PS_OFFSET_XOFFSET(v) \ + (((v) << 0) & BM_PXP_PS_OFFSET_XOFFSET) + +#define HW_PXP_PS_CLRKEYLOW_0 (0x00000130) + +#define BP_PXP_PS_CLRKEYLOW_0_RSVD1 24 +#define BM_PXP_PS_CLRKEYLOW_0_RSVD1 0xFF000000 +#define BF_PXP_PS_CLRKEYLOW_0_RSVD1(v) \ + (((v) << 24) & BM_PXP_PS_CLRKEYLOW_0_RSVD1) +#define BP_PXP_PS_CLRKEYLOW_0_PIXEL 0 +#define BM_PXP_PS_CLRKEYLOW_0_PIXEL 0x00FFFFFF +#define BF_PXP_PS_CLRKEYLOW_0_PIXEL(v) \ + (((v) << 0) & BM_PXP_PS_CLRKEYLOW_0_PIXEL) + +#define HW_PXP_PS_CLRKEYHIGH_0 (0x00000140) + +#define BP_PXP_PS_CLRKEYHIGH_0_RSVD1 24 +#define BM_PXP_PS_CLRKEYHIGH_0_RSVD1 0xFF000000 +#define BF_PXP_PS_CLRKEYHIGH_0_RSVD1(v) \ + (((v) << 24) & BM_PXP_PS_CLRKEYHIGH_0_RSVD1) +#define BP_PXP_PS_CLRKEYHIGH_0_PIXEL 0 +#define BM_PXP_PS_CLRKEYHIGH_0_PIXEL 0x00FFFFFF +#define BF_PXP_PS_CLRKEYHIGH_0_PIXEL(v) \ + (((v) << 0) & BM_PXP_PS_CLRKEYHIGH_0_PIXEL) + +#define HW_PXP_AS_CTRL (0x00000150) + +#define BP_PXP_AS_CTRL_RSVD1 22 +#define BM_PXP_AS_CTRL_RSVD1 0xFFC00000 +#define BF_PXP_AS_CTRL_RSVD1(v) \ + (((v) << 22) & BM_PXP_AS_CTRL_RSVD1) +#define BM_PXP_AS_CTRL_ALPHA1_INVERT 0x00200000 +#define BF_PXP_AS_CTRL_ALPHA1_INVERT(v) \ + (((v) << 21) & BM_PXP_AS_CTRL_ALPHA1_INVERT) +#define BM_PXP_AS_CTRL_ALPHA0_INVERT 0x00100000 +#define BF_PXP_AS_CTRL_ALPHA0_INVERT(v) \ + (((v) << 20) & BM_PXP_AS_CTRL_ALPHA0_INVERT) +#define BP_PXP_AS_CTRL_ROP 16 +#define BM_PXP_AS_CTRL_ROP 0x000F0000 +#define BF_PXP_AS_CTRL_ROP(v) \ + (((v) << 16) & BM_PXP_AS_CTRL_ROP) +#define BV_PXP_AS_CTRL_ROP__MASKAS 0x0 +#define BV_PXP_AS_CTRL_ROP__MASKNOTAS 0x1 +#define BV_PXP_AS_CTRL_ROP__MASKASNOT 0x2 +#define BV_PXP_AS_CTRL_ROP__MERGEAS 0x3 +#define BV_PXP_AS_CTRL_ROP__MERGENOTAS 0x4 +#define BV_PXP_AS_CTRL_ROP__MERGEASNOT 0x5 +#define BV_PXP_AS_CTRL_ROP__NOTCOPYAS 0x6 +#define BV_PXP_AS_CTRL_ROP__NOT 0x7 +#define BV_PXP_AS_CTRL_ROP__NOTMASKAS 0x8 +#define BV_PXP_AS_CTRL_ROP__NOTMERGEAS 0x9 +#define BV_PXP_AS_CTRL_ROP__XORAS 0xA +#define BV_PXP_AS_CTRL_ROP__NOTXORAS 0xB +#define BP_PXP_AS_CTRL_ALPHA 8 +#define BM_PXP_AS_CTRL_ALPHA 0x0000FF00 +#define BF_PXP_AS_CTRL_ALPHA(v) \ + (((v) << 8) & BM_PXP_AS_CTRL_ALPHA) +#define BP_PXP_AS_CTRL_FORMAT 4 +#define BM_PXP_AS_CTRL_FORMAT 0x000000F0 +#define BF_PXP_AS_CTRL_FORMAT(v) \ + (((v) << 4) & BM_PXP_AS_CTRL_FORMAT) +#define BV_PXP_AS_CTRL_FORMAT__ARGB8888 0x0 +#define BV_PXP_AS_CTRL_FORMAT__RGBA8888 0x1 +#define BV_PXP_AS_CTRL_FORMAT__RGB888 0x4 +#define BV_PXP_AS_CTRL_FORMAT__ARGB1555 0x8 +#define BV_PXP_AS_CTRL_FORMAT__ARGB4444 0x9 +#define BV_PXP_AS_CTRL_FORMAT__RGB555 0xC +#define BV_PXP_AS_CTRL_FORMAT__RGB444 0xD +#define BV_PXP_AS_CTRL_FORMAT__RGB565 0xE +#define BM_PXP_AS_CTRL_ENABLE_COLORKEY 0x00000008 +#define BF_PXP_AS_CTRL_ENABLE_COLORKEY(v) \ + (((v) << 3) & BM_PXP_AS_CTRL_ENABLE_COLORKEY) +#define BP_PXP_AS_CTRL_ALPHA_CTRL 1 +#define BM_PXP_AS_CTRL_ALPHA_CTRL 0x00000006 +#define BF_PXP_AS_CTRL_ALPHA_CTRL(v) \ + (((v) << 1) & BM_PXP_AS_CTRL_ALPHA_CTRL) +#define BV_PXP_AS_CTRL_ALPHA_CTRL__Embedded 0x0 +#define BV_PXP_AS_CTRL_ALPHA_CTRL__Override 0x1 +#define BV_PXP_AS_CTRL_ALPHA_CTRL__Multiply 0x2 +#define BV_PXP_AS_CTRL_ALPHA_CTRL__ROPs 0x3 +#define BM_PXP_AS_CTRL_RSVD0 0x00000001 +#define BF_PXP_AS_CTRL_RSVD0(v) \ + (((v) << 0) & BM_PXP_AS_CTRL_RSVD0) + +#define HW_PXP_AS_BUF (0x00000160) + +#define BP_PXP_AS_BUF_ADDR 0 +#define BM_PXP_AS_BUF_ADDR 0xFFFFFFFF +#define BF_PXP_AS_BUF_ADDR(v) (v) + +#define HW_PXP_AS_PITCH (0x00000170) + +#define BP_PXP_AS_PITCH_RSVD 16 +#define BM_PXP_AS_PITCH_RSVD 0xFFFF0000 +#define BF_PXP_AS_PITCH_RSVD(v) \ + (((v) << 16) & BM_PXP_AS_PITCH_RSVD) +#define BP_PXP_AS_PITCH_PITCH 0 +#define BM_PXP_AS_PITCH_PITCH 0x0000FFFF +#define BF_PXP_AS_PITCH_PITCH(v) \ + (((v) << 0) & BM_PXP_AS_PITCH_PITCH) + +#define HW_PXP_AS_CLRKEYLOW_0 (0x00000180) + +#define BP_PXP_AS_CLRKEYLOW_0_RSVD1 24 +#define BM_PXP_AS_CLRKEYLOW_0_RSVD1 0xFF000000 +#define BF_PXP_AS_CLRKEYLOW_0_RSVD1(v) \ + (((v) << 24) & BM_PXP_AS_CLRKEYLOW_0_RSVD1) +#define BP_PXP_AS_CLRKEYLOW_0_PIXEL 0 +#define BM_PXP_AS_CLRKEYLOW_0_PIXEL 0x00FFFFFF +#define BF_PXP_AS_CLRKEYLOW_0_PIXEL(v) \ + (((v) << 0) & BM_PXP_AS_CLRKEYLOW_0_PIXEL) + +#define HW_PXP_AS_CLRKEYHIGH_0 (0x00000190) + +#define BP_PXP_AS_CLRKEYHIGH_0_RSVD1 24 +#define BM_PXP_AS_CLRKEYHIGH_0_RSVD1 0xFF000000 +#define BF_PXP_AS_CLRKEYHIGH_0_RSVD1(v) \ + (((v) << 24) & BM_PXP_AS_CLRKEYHIGH_0_RSVD1) +#define BP_PXP_AS_CLRKEYHIGH_0_PIXEL 0 +#define BM_PXP_AS_CLRKEYHIGH_0_PIXEL 0x00FFFFFF +#define BF_PXP_AS_CLRKEYHIGH_0_PIXEL(v) \ + (((v) << 0) & BM_PXP_AS_CLRKEYHIGH_0_PIXEL) + +#define HW_PXP_CSC1_COEF0 (0x000001a0) + +#define BM_PXP_CSC1_COEF0_YCBCR_MODE 0x80000000 +#define BF_PXP_CSC1_COEF0_YCBCR_MODE(v) \ + (((v) << 31) & BM_PXP_CSC1_COEF0_YCBCR_MODE) +#define BM_PXP_CSC1_COEF0_BYPASS 0x40000000 +#define BF_PXP_CSC1_COEF0_BYPASS(v) \ + (((v) << 30) & BM_PXP_CSC1_COEF0_BYPASS) +#define BM_PXP_CSC1_COEF0_RSVD1 0x20000000 +#define BF_PXP_CSC1_COEF0_RSVD1(v) \ + (((v) << 29) & BM_PXP_CSC1_COEF0_RSVD1) +#define BP_PXP_CSC1_COEF0_C0 18 +#define BM_PXP_CSC1_COEF0_C0 0x1FFC0000 +#define BF_PXP_CSC1_COEF0_C0(v) \ + (((v) << 18) & BM_PXP_CSC1_COEF0_C0) +#define BP_PXP_CSC1_COEF0_UV_OFFSET 9 +#define BM_PXP_CSC1_COEF0_UV_OFFSET 0x0003FE00 +#define BF_PXP_CSC1_COEF0_UV_OFFSET(v) \ + (((v) << 9) & BM_PXP_CSC1_COEF0_UV_OFFSET) +#define BP_PXP_CSC1_COEF0_Y_OFFSET 0 +#define BM_PXP_CSC1_COEF0_Y_OFFSET 0x000001FF +#define BF_PXP_CSC1_COEF0_Y_OFFSET(v) \ + (((v) << 0) & BM_PXP_CSC1_COEF0_Y_OFFSET) + +#define HW_PXP_CSC1_COEF1 (0x000001b0) + +#define BP_PXP_CSC1_COEF1_RSVD1 27 +#define BM_PXP_CSC1_COEF1_RSVD1 0xF8000000 +#define BF_PXP_CSC1_COEF1_RSVD1(v) \ + (((v) << 27) & BM_PXP_CSC1_COEF1_RSVD1) +#define BP_PXP_CSC1_COEF1_C1 16 +#define BM_PXP_CSC1_COEF1_C1 0x07FF0000 +#define BF_PXP_CSC1_COEF1_C1(v) \ + (((v) << 16) & BM_PXP_CSC1_COEF1_C1) +#define BP_PXP_CSC1_COEF1_RSVD0 11 +#define BM_PXP_CSC1_COEF1_RSVD0 0x0000F800 +#define BF_PXP_CSC1_COEF1_RSVD0(v) \ + (((v) << 11) & BM_PXP_CSC1_COEF1_RSVD0) +#define BP_PXP_CSC1_COEF1_C4 0 +#define BM_PXP_CSC1_COEF1_C4 0x000007FF +#define BF_PXP_CSC1_COEF1_C4(v) \ + (((v) << 0) & BM_PXP_CSC1_COEF1_C4) + +#define HW_PXP_CSC1_COEF2 (0x000001c0) + +#define BP_PXP_CSC1_COEF2_RSVD1 27 +#define BM_PXP_CSC1_COEF2_RSVD1 0xF8000000 +#define BF_PXP_CSC1_COEF2_RSVD1(v) \ + (((v) << 27) & BM_PXP_CSC1_COEF2_RSVD1) +#define BP_PXP_CSC1_COEF2_C2 16 +#define BM_PXP_CSC1_COEF2_C2 0x07FF0000 +#define BF_PXP_CSC1_COEF2_C2(v) \ + (((v) << 16) & BM_PXP_CSC1_COEF2_C2) +#define BP_PXP_CSC1_COEF2_RSVD0 11 +#define BM_PXP_CSC1_COEF2_RSVD0 0x0000F800 +#define BF_PXP_CSC1_COEF2_RSVD0(v) \ + (((v) << 11) & BM_PXP_CSC1_COEF2_RSVD0) +#define BP_PXP_CSC1_COEF2_C3 0 +#define BM_PXP_CSC1_COEF2_C3 0x000007FF +#define BF_PXP_CSC1_COEF2_C3(v) \ + (((v) << 0) & BM_PXP_CSC1_COEF2_C3) + +#define HW_PXP_CSC2_CTRL (0x000001d0) + +#define BP_PXP_CSC2_CTRL_RSVD 3 +#define BM_PXP_CSC2_CTRL_RSVD 0xFFFFFFF8 +#define BF_PXP_CSC2_CTRL_RSVD(v) \ + (((v) << 3) & BM_PXP_CSC2_CTRL_RSVD) +#define BP_PXP_CSC2_CTRL_CSC_MODE 1 +#define BM_PXP_CSC2_CTRL_CSC_MODE 0x00000006 +#define BF_PXP_CSC2_CTRL_CSC_MODE(v) \ + (((v) << 1) & BM_PXP_CSC2_CTRL_CSC_MODE) +#define BV_PXP_CSC2_CTRL_CSC_MODE__YUV2RGB 0x0 +#define BV_PXP_CSC2_CTRL_CSC_MODE__YCbCr2RGB 0x1 +#define BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YUV 0x2 +#define BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YCbCr 0x3 +#define BM_PXP_CSC2_CTRL_BYPASS 0x00000001 +#define BF_PXP_CSC2_CTRL_BYPASS(v) \ + (((v) << 0) & BM_PXP_CSC2_CTRL_BYPASS) + +#define HW_PXP_CSC2_COEF0 (0x000001e0) + +#define BP_PXP_CSC2_COEF0_RSVD1 27 +#define BM_PXP_CSC2_COEF0_RSVD1 0xF8000000 +#define BF_PXP_CSC2_COEF0_RSVD1(v) \ + (((v) << 27) & BM_PXP_CSC2_COEF0_RSVD1) +#define BP_PXP_CSC2_COEF0_A2 16 +#define BM_PXP_CSC2_COEF0_A2 0x07FF0000 +#define BF_PXP_CSC2_COEF0_A2(v) \ + (((v) << 16) & BM_PXP_CSC2_COEF0_A2) +#define BP_PXP_CSC2_COEF0_RSVD0 11 +#define BM_PXP_CSC2_COEF0_RSVD0 0x0000F800 +#define BF_PXP_CSC2_COEF0_RSVD0(v) \ + (((v) << 11) & BM_PXP_CSC2_COEF0_RSVD0) +#define BP_PXP_CSC2_COEF0_A1 0 +#define BM_PXP_CSC2_COEF0_A1 0x000007FF +#define BF_PXP_CSC2_COEF0_A1(v) \ + (((v) << 0) & BM_PXP_CSC2_COEF0_A1) + +#define HW_PXP_CSC2_COEF1 (0x000001f0) + +#define BP_PXP_CSC2_COEF1_RSVD1 27 +#define BM_PXP_CSC2_COEF1_RSVD1 0xF8000000 +#define BF_PXP_CSC2_COEF1_RSVD1(v) \ + (((v) << 27) & BM_PXP_CSC2_COEF1_RSVD1) +#define BP_PXP_CSC2_COEF1_B1 16 +#define BM_PXP_CSC2_COEF1_B1 0x07FF0000 +#define BF_PXP_CSC2_COEF1_B1(v) \ + (((v) << 16) & BM_PXP_CSC2_COEF1_B1) +#define BP_PXP_CSC2_COEF1_RSVD0 11 +#define BM_PXP_CSC2_COEF1_RSVD0 0x0000F800 +#define BF_PXP_CSC2_COEF1_RSVD0(v) \ + (((v) << 11) & BM_PXP_CSC2_COEF1_RSVD0) +#define BP_PXP_CSC2_COEF1_A3 0 +#define BM_PXP_CSC2_COEF1_A3 0x000007FF +#define BF_PXP_CSC2_COEF1_A3(v) \ + (((v) << 0) & BM_PXP_CSC2_COEF1_A3) + +#define HW_PXP_CSC2_COEF2 (0x00000200) + +#define BP_PXP_CSC2_COEF2_RSVD1 27 +#define BM_PXP_CSC2_COEF2_RSVD1 0xF8000000 +#define BF_PXP_CSC2_COEF2_RSVD1(v) \ + (((v) << 27) & BM_PXP_CSC2_COEF2_RSVD1) +#define BP_PXP_CSC2_COEF2_B3 16 +#define BM_PXP_CSC2_COEF2_B3 0x07FF0000 +#define BF_PXP_CSC2_COEF2_B3(v) \ + (((v) << 16) & BM_PXP_CSC2_COEF2_B3) +#define BP_PXP_CSC2_COEF2_RSVD0 11 +#define BM_PXP_CSC2_COEF2_RSVD0 0x0000F800 +#define BF_PXP_CSC2_COEF2_RSVD0(v) \ + (((v) << 11) & BM_PXP_CSC2_COEF2_RSVD0) +#define BP_PXP_CSC2_COEF2_B2 0 +#define BM_PXP_CSC2_COEF2_B2 0x000007FF +#define BF_PXP_CSC2_COEF2_B2(v) \ + (((v) << 0) & BM_PXP_CSC2_COEF2_B2) + +#define HW_PXP_CSC2_COEF3 (0x00000210) + +#define BP_PXP_CSC2_COEF3_RSVD1 27 +#define BM_PXP_CSC2_COEF3_RSVD1 0xF8000000 +#define BF_PXP_CSC2_COEF3_RSVD1(v) \ + (((v) << 27) & BM_PXP_CSC2_COEF3_RSVD1) +#define BP_PXP_CSC2_COEF3_C2 16 +#define BM_PXP_CSC2_COEF3_C2 0x07FF0000 +#define BF_PXP_CSC2_COEF3_C2(v) \ + (((v) << 16) & BM_PXP_CSC2_COEF3_C2) +#define BP_PXP_CSC2_COEF3_RSVD0 11 +#define BM_PXP_CSC2_COEF3_RSVD0 0x0000F800 +#define BF_PXP_CSC2_COEF3_RSVD0(v) \ + (((v) << 11) & BM_PXP_CSC2_COEF3_RSVD0) +#define BP_PXP_CSC2_COEF3_C1 0 +#define BM_PXP_CSC2_COEF3_C1 0x000007FF +#define BF_PXP_CSC2_COEF3_C1(v) \ + (((v) << 0) & BM_PXP_CSC2_COEF3_C1) + +#define HW_PXP_CSC2_COEF4 (0x00000220) + +#define BP_PXP_CSC2_COEF4_RSVD1 25 +#define BM_PXP_CSC2_COEF4_RSVD1 0xFE000000 +#define BF_PXP_CSC2_COEF4_RSVD1(v) \ + (((v) << 25) & BM_PXP_CSC2_COEF4_RSVD1) +#define BP_PXP_CSC2_COEF4_D1 16 +#define BM_PXP_CSC2_COEF4_D1 0x01FF0000 +#define BF_PXP_CSC2_COEF4_D1(v) \ + (((v) << 16) & BM_PXP_CSC2_COEF4_D1) +#define BP_PXP_CSC2_COEF4_RSVD0 11 +#define BM_PXP_CSC2_COEF4_RSVD0 0x0000F800 +#define BF_PXP_CSC2_COEF4_RSVD0(v) \ + (((v) << 11) & BM_PXP_CSC2_COEF4_RSVD0) +#define BP_PXP_CSC2_COEF4_C3 0 +#define BM_PXP_CSC2_COEF4_C3 0x000007FF +#define BF_PXP_CSC2_COEF4_C3(v) \ + (((v) << 0) & BM_PXP_CSC2_COEF4_C3) + +#define HW_PXP_CSC2_COEF5 (0x00000230) + +#define BP_PXP_CSC2_COEF5_RSVD1 25 +#define BM_PXP_CSC2_COEF5_RSVD1 0xFE000000 +#define BF_PXP_CSC2_COEF5_RSVD1(v) \ + (((v) << 25) & BM_PXP_CSC2_COEF5_RSVD1) +#define BP_PXP_CSC2_COEF5_D3 16 +#define BM_PXP_CSC2_COEF5_D3 0x01FF0000 +#define BF_PXP_CSC2_COEF5_D3(v) \ + (((v) << 16) & BM_PXP_CSC2_COEF5_D3) +#define BP_PXP_CSC2_COEF5_RSVD0 9 +#define BM_PXP_CSC2_COEF5_RSVD0 0x0000FE00 +#define BF_PXP_CSC2_COEF5_RSVD0(v) \ + (((v) << 9) & BM_PXP_CSC2_COEF5_RSVD0) +#define BP_PXP_CSC2_COEF5_D2 0 +#define BM_PXP_CSC2_COEF5_D2 0x000001FF +#define BF_PXP_CSC2_COEF5_D2(v) \ + (((v) << 0) & BM_PXP_CSC2_COEF5_D2) + +#define HW_PXP_LUT_CTRL (0x00000240) + +#define BM_PXP_LUT_CTRL_BYPASS 0x80000000 +#define BF_PXP_LUT_CTRL_BYPASS(v) \ + (((v) << 31) & BM_PXP_LUT_CTRL_BYPASS) +#define BP_PXP_LUT_CTRL_RSVD3 26 +#define BM_PXP_LUT_CTRL_RSVD3 0x7C000000 +#define BF_PXP_LUT_CTRL_RSVD3(v) \ + (((v) << 26) & BM_PXP_LUT_CTRL_RSVD3) +#define BP_PXP_LUT_CTRL_LOOKUP_MODE 24 +#define BM_PXP_LUT_CTRL_LOOKUP_MODE 0x03000000 +#define BF_PXP_LUT_CTRL_LOOKUP_MODE(v) \ + (((v) << 24) & BM_PXP_LUT_CTRL_LOOKUP_MODE) +#define BV_PXP_LUT_CTRL_LOOKUP_MODE__CACHE_RGB565 0x0 +#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8 0x1 +#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_RGB444 0x2 +#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_RGB454 0x3 +#define BP_PXP_LUT_CTRL_RSVD2 18 +#define BM_PXP_LUT_CTRL_RSVD2 0x00FC0000 +#define BF_PXP_LUT_CTRL_RSVD2(v) \ + (((v) << 18) & BM_PXP_LUT_CTRL_RSVD2) +#define BP_PXP_LUT_CTRL_OUT_MODE 16 +#define BM_PXP_LUT_CTRL_OUT_MODE 0x00030000 +#define BF_PXP_LUT_CTRL_OUT_MODE(v) \ + (((v) << 16) & BM_PXP_LUT_CTRL_OUT_MODE) +#define BV_PXP_LUT_CTRL_OUT_MODE__RESERVED 0x0 +#define BV_PXP_LUT_CTRL_OUT_MODE__Y8 0x1 +#define BV_PXP_LUT_CTRL_OUT_MODE__RGBW4444CFA 0x2 +#define BV_PXP_LUT_CTRL_OUT_MODE__RGB888 0x3 +#define BP_PXP_LUT_CTRL_RSVD1 11 +#define BM_PXP_LUT_CTRL_RSVD1 0x0000F800 +#define BF_PXP_LUT_CTRL_RSVD1(v) \ + (((v) << 11) & BM_PXP_LUT_CTRL_RSVD1) +#define BM_PXP_LUT_CTRL_SEL_8KB 0x00000400 +#define BF_PXP_LUT_CTRL_SEL_8KB(v) \ + (((v) << 10) & BM_PXP_LUT_CTRL_SEL_8KB) +#define BM_PXP_LUT_CTRL_LRU_UPD 0x00000200 +#define BF_PXP_LUT_CTRL_LRU_UPD(v) \ + (((v) << 9) & BM_PXP_LUT_CTRL_LRU_UPD) +#define BM_PXP_LUT_CTRL_INVALID 0x00000100 +#define BF_PXP_LUT_CTRL_INVALID(v) \ + (((v) << 8) & BM_PXP_LUT_CTRL_INVALID) +#define BP_PXP_LUT_CTRL_RSVD0 1 +#define BM_PXP_LUT_CTRL_RSVD0 0x000000FE +#define BF_PXP_LUT_CTRL_RSVD0(v) \ + (((v) << 1) & BM_PXP_LUT_CTRL_RSVD0) +#define BM_PXP_LUT_CTRL_DMA_START 0x00000001 +#define BF_PXP_LUT_CTRL_DMA_START(v) \ + (((v) << 0) & BM_PXP_LUT_CTRL_DMA_START) + +#define HW_PXP_LUT_ADDR (0x00000250) + +#define BM_PXP_LUT_ADDR_RSVD2 0x80000000 +#define BF_PXP_LUT_ADDR_RSVD2(v) \ + (((v) << 31) & BM_PXP_LUT_ADDR_RSVD2) +#define BP_PXP_LUT_ADDR_NUM_BYTES 16 +#define BM_PXP_LUT_ADDR_NUM_BYTES 0x7FFF0000 +#define BF_PXP_LUT_ADDR_NUM_BYTES(v) \ + (((v) << 16) & BM_PXP_LUT_ADDR_NUM_BYTES) +#define BP_PXP_LUT_ADDR_RSVD1 14 +#define BM_PXP_LUT_ADDR_RSVD1 0x0000C000 +#define BF_PXP_LUT_ADDR_RSVD1(v) \ + (((v) << 14) & BM_PXP_LUT_ADDR_RSVD1) +#define BP_PXP_LUT_ADDR_ADDR 0 +#define BM_PXP_LUT_ADDR_ADDR 0x00003FFF +#define BF_PXP_LUT_ADDR_ADDR(v) \ + (((v) << 0) & BM_PXP_LUT_ADDR_ADDR) + +#define HW_PXP_LUT_DATA (0x00000260) + +#define BP_PXP_LUT_DATA_DATA 0 +#define BM_PXP_LUT_DATA_DATA 0xFFFFFFFF +#define BF_PXP_LUT_DATA_DATA(v) (v) + +#define HW_PXP_LUT_EXTMEM (0x00000270) + +#define BP_PXP_LUT_EXTMEM_ADDR 0 +#define BM_PXP_LUT_EXTMEM_ADDR 0xFFFFFFFF +#define BF_PXP_LUT_EXTMEM_ADDR(v) (v) + +#define HW_PXP_CFA (0x00000280) + +#define BP_PXP_CFA_DATA 0 +#define BM_PXP_CFA_DATA 0xFFFFFFFF +#define BF_PXP_CFA_DATA(v) (v) + +#define HW_PXP_ALPHA_A_CTRL (0x00000290) + +#define BP_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA 24 +#define BM_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA 0xFF000000 +#define BF_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA(v) \ + (((v) << 24) & BM_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA) +#define BP_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA 16 +#define BM_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA 0x00FF0000 +#define BF_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA(v) \ + (((v) << 16) & BM_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA) +#define BP_PXP_ALPHA_A_CTRL_RSVD0 14 +#define BM_PXP_ALPHA_A_CTRL_RSVD0 0x0000C000 +#define BF_PXP_ALPHA_A_CTRL_RSVD0(v) \ + (((v) << 14) & BM_PXP_ALPHA_A_CTRL_RSVD0) +#define BM_PXP_ALPHA_A_CTRL_S1_COLOR_MODE 0x00002000 +#define BF_PXP_ALPHA_A_CTRL_S1_COLOR_MODE(v) \ + (((v) << 13) & BM_PXP_ALPHA_A_CTRL_S1_COLOR_MODE) +#define BV_PXP_ALPHA_A_CTRL_S1_COLOR_MODE__0 0x0 +#define BV_PXP_ALPHA_A_CTRL_S1_COLOR_MODE__1 0x1 +#define BM_PXP_ALPHA_A_CTRL_S1_ALPHA_MODE 0x00001000 +#define BF_PXP_ALPHA_A_CTRL_S1_ALPHA_MODE(v) \ + (((v) << 12) & BM_PXP_ALPHA_A_CTRL_S1_ALPHA_MODE) +#define BV_PXP_ALPHA_A_CTRL_S1_ALPHA_MODE__0 0x0 +#define BV_PXP_ALPHA_A_CTRL_S1_ALPHA_MODE__1 0x1 +#define BP_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE 10 +#define BM_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE 0x00000C00 +#define BF_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE(v) \ + (((v) << 10) & BM_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE) +#define BV_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE__0 0x0 +#define BV_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE__1 0x0 +#define BV_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE__2 0x0 +#define BV_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE__3 0x0 +#define BP_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE 8 +#define BM_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE 0x00000300 +#define BF_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE(v) \ + (((v) << 8) & BM_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE) +#define BV_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE__0 0x0 +#define BV_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE__1 0x1 +#define BV_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE__2 0x2 +#define BV_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE__3 0x3 +#define BM_PXP_ALPHA_A_CTRL_RSVD1 0x00000080 +#define BF_PXP_ALPHA_A_CTRL_RSVD1(v) \ + (((v) << 7) & BM_PXP_ALPHA_A_CTRL_RSVD1) +#define BM_PXP_ALPHA_A_CTRL_S0_COLOR_MODE 0x00000040 +#define BF_PXP_ALPHA_A_CTRL_S0_COLOR_MODE(v) \ + (((v) << 6) & BM_PXP_ALPHA_A_CTRL_S0_COLOR_MODE) +#define BV_PXP_ALPHA_A_CTRL_S0_COLOR_MODE__0 0x0 +#define BV_PXP_ALPHA_A_CTRL_S0_COLOR_MODE__1 0x1 +#define BM_PXP_ALPHA_A_CTRL_S0_ALPHA_MODE 0x00000020 +#define BF_PXP_ALPHA_A_CTRL_S0_ALPHA_MODE(v) \ + (((v) << 5) & BM_PXP_ALPHA_A_CTRL_S0_ALPHA_MODE) +#define BV_PXP_ALPHA_A_CTRL_S0_ALPHA_MODE__0 0x0 +#define BV_PXP_ALPHA_A_CTRL_S0_ALPHA_MODE__1 0x1 +#define BP_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE 3 +#define BM_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE 0x00000018 +#define BF_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE(v) \ + (((v) << 3) & BM_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE) +#define BV_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE__0 0x0 +#define BV_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE__1 0x1 +#define BV_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE__2 0x2 +#define BV_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE__3 0x3 +#define BP_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE 1 +#define BM_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE 0x00000006 +#define BF_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE(v) \ + (((v) << 1) & BM_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE) +#define BV_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE__0 0x0 +#define BV_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE__1 0x1 +#define BV_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE__2 0x2 +#define BV_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE__3 0x3 +#define BM_PXP_ALPHA_A_CTRL_POTER_DUFF_ENABLE 0x00000001 +#define BF_PXP_ALPHA_A_CTRL_POTER_DUFF_ENABLE(v) \ + (((v) << 0) & BM_PXP_ALPHA_A_CTRL_POTER_DUFF_ENABLE) +#define BV_PXP_ALPHA_A_CTRL_POTER_DUFF_ENABLE__0 0x0 +#define BV_PXP_ALPHA_A_CTRL_POTER_DUFF_ENABLE__1 0x1 + +#define HW_PXP_ALPHA_B_CTRL (0x000002a0) + +#define BP_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA 24 +#define BM_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA 0xFF000000 +#define BF_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA(v) \ + (((v) << 24) & BM_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA) +#define BP_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA 16 +#define BM_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA 0x00FF0000 +#define BF_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA(v) \ + (((v) << 16) & BM_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA) +#define BP_PXP_ALPHA_B_CTRL_RSVD0 14 +#define BM_PXP_ALPHA_B_CTRL_RSVD0 0x0000C000 +#define BF_PXP_ALPHA_B_CTRL_RSVD0(v) \ + (((v) << 14) & BM_PXP_ALPHA_B_CTRL_RSVD0) +#define BM_PXP_ALPHA_B_CTRL_S1_COLOR_MODE 0x00002000 +#define BF_PXP_ALPHA_B_CTRL_S1_COLOR_MODE(v) \ + (((v) << 13) & BM_PXP_ALPHA_B_CTRL_S1_COLOR_MODE) +#define BV_PXP_ALPHA_B_CTRL_S1_COLOR_MODE__0 0x0 +#define BV_PXP_ALPHA_B_CTRL_S1_COLOR_MODE__1 0x1 +#define BM_PXP_ALPHA_B_CTRL_S1_ALPHA_MODE 0x00001000 +#define BF_PXP_ALPHA_B_CTRL_S1_ALPHA_MODE(v) \ + (((v) << 12) & BM_PXP_ALPHA_B_CTRL_S1_ALPHA_MODE) +#define BV_PXP_ALPHA_B_CTRL_S1_ALPHA_MODE__0 0x0 +#define BV_PXP_ALPHA_B_CTRL_S1_ALPHA_MODE__1 0x1 +#define BP_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE 10 +#define BM_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE 0x00000C00 +#define BF_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE(v) \ + (((v) << 10) & BM_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE) +#define BV_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE__0 0x0 +#define BV_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE__1 0x1 +#define BV_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE__2 0x2 +#define BV_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE__3 0x3 +#define BP_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE 8 +#define BM_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE 0x00000300 +#define BF_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE(v) \ + (((v) << 8) & BM_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE) +#define BV_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE__0 0x0 +#define BV_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE__1 0x1 +#define BV_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE__2 0x2 +#define BV_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE__3 0x3 +#define BM_PXP_ALPHA_B_CTRL_RSVD1 0x00000080 +#define BF_PXP_ALPHA_B_CTRL_RSVD1(v) \ + (((v) << 7) & BM_PXP_ALPHA_B_CTRL_RSVD1) +#define BM_PXP_ALPHA_B_CTRL_S0_COLOR_MODE 0x00000040 +#define BF_PXP_ALPHA_B_CTRL_S0_COLOR_MODE(v) \ + (((v) << 6) & BM_PXP_ALPHA_B_CTRL_S0_COLOR_MODE) +#define BV_PXP_ALPHA_B_CTRL_S0_COLOR_MODE__0 0x0 +#define BV_PXP_ALPHA_B_CTRL_S0_COLOR_MODE__1 0x1 +#define BM_PXP_ALPHA_B_CTRL_S0_ALPHA_MODE 0x00000020 +#define BF_PXP_ALPHA_B_CTRL_S0_ALPHA_MODE(v) \ + (((v) << 5) & BM_PXP_ALPHA_B_CTRL_S0_ALPHA_MODE) +#define BV_PXP_ALPHA_B_CTRL_S0_ALPHA_MODE__0 0x0 +#define BV_PXP_ALPHA_B_CTRL_S0_ALPHA_MODE__1 0x1 +#define BP_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE 3 +#define BM_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE 0x00000018 +#define BF_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE(v) \ + (((v) << 3) & BM_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE) +#define BV_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE__0 0x0 +#define BV_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE__1 0x1 +#define BV_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE__2 0x2 +#define BV_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE__3 0x3 +#define BP_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE 1 +#define BM_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE 0x00000006 +#define BF_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE(v) \ + (((v) << 1) & BM_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE) +#define BV_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE__0 0x0 +#define BV_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE__1 0x1 +#define BV_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE__2 0x2 +#define BV_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE__3 0x3 +#define BM_PXP_ALPHA_B_CTRL_POTER_DUFF_ENABLE 0x00000001 +#define BF_PXP_ALPHA_B_CTRL_POTER_DUFF_ENABLE(v) \ + (((v) << 0) & BM_PXP_ALPHA_B_CTRL_POTER_DUFF_ENABLE) +#define BV_PXP_ALPHA_B_CTRL_POTER_DUFF_ENABLE__0 0x0 +#define BV_PXP_ALPHA_B_CTRL_POTER_DUFF_ENABLE__1 0x1 + +#define HW_PXP_ALPHA_B_CTRL_1 (0x000002b0) + +#define BP_PXP_ALPHA_B_CTRL_1_RSVD0 8 +#define BM_PXP_ALPHA_B_CTRL_1_RSVD0 0xFFFFFF00 +#define BF_PXP_ALPHA_B_CTRL_1_RSVD0(v) \ + (((v) << 8) & BM_PXP_ALPHA_B_CTRL_1_RSVD0) +#define BP_PXP_ALPHA_B_CTRL_1_ROP 4 +#define BM_PXP_ALPHA_B_CTRL_1_ROP 0x000000F0 +#define BF_PXP_ALPHA_B_CTRL_1_ROP(v) \ + (((v) << 4) & BM_PXP_ALPHA_B_CTRL_1_ROP) +#define BV_PXP_ALPHA_B_CTRL_1_ROP__MASKAS 0x0 +#define BV_PXP_ALPHA_B_CTRL_1_ROP__MASKNOTAS 0x1 +#define BV_PXP_ALPHA_B_CTRL_1_ROP__MASKASNOT 0x2 +#define BV_PXP_ALPHA_B_CTRL_1_ROP__MERGEAS 0x3 +#define BV_PXP_ALPHA_B_CTRL_1_ROP__MERGENOTAS 0x4 +#define BV_PXP_ALPHA_B_CTRL_1_ROP__MERGEASNOT 0x5 +#define BV_PXP_ALPHA_B_CTRL_1_ROP__NOTCOPYAS 0x6 +#define BV_PXP_ALPHA_B_CTRL_1_ROP__NOT 0x7 +#define BV_PXP_ALPHA_B_CTRL_1_ROP__NOTMASKAS 0x8 +#define BV_PXP_ALPHA_B_CTRL_1_ROP__NOTMERGEAS 0x9 +#define BV_PXP_ALPHA_B_CTRL_1_ROP__XORAS 0xA +#define BV_PXP_ALPHA_B_CTRL_1_ROP__NOTXORAS 0xB +#define BP_PXP_ALPHA_B_CTRL_1_RSVD1 2 +#define BM_PXP_ALPHA_B_CTRL_1_RSVD1 0x0000000C +#define BF_PXP_ALPHA_B_CTRL_1_RSVD1(v) \ + (((v) << 2) & BM_PXP_ALPHA_B_CTRL_1_RSVD1) +#define BM_PXP_ALPHA_B_CTRL_1_OL_CLRKEY_ENABLE 0x00000002 +#define BF_PXP_ALPHA_B_CTRL_1_OL_CLRKEY_ENABLE(v) \ + (((v) << 1) & BM_PXP_ALPHA_B_CTRL_1_OL_CLRKEY_ENABLE) +#define BM_PXP_ALPHA_B_CTRL_1_ROP_ENABLE 0x00000001 +#define BF_PXP_ALPHA_B_CTRL_1_ROP_ENABLE(v) \ + (((v) << 0) & BM_PXP_ALPHA_B_CTRL_1_ROP_ENABLE) + +#define HW_PXP_PS_BACKGROUND_1 (0x000002c0) + +#define BP_PXP_PS_BACKGROUND_1_RSVD 24 +#define BM_PXP_PS_BACKGROUND_1_RSVD 0xFF000000 +#define BF_PXP_PS_BACKGROUND_1_RSVD(v) \ + (((v) << 24) & BM_PXP_PS_BACKGROUND_1_RSVD) +#define BP_PXP_PS_BACKGROUND_1_COLOR 0 +#define BM_PXP_PS_BACKGROUND_1_COLOR 0x00FFFFFF +#define BF_PXP_PS_BACKGROUND_1_COLOR(v) \ + (((v) << 0) & BM_PXP_PS_BACKGROUND_1_COLOR) + +#define HW_PXP_PS_CLRKEYLOW_1 (0x000002d0) + +#define BP_PXP_PS_CLRKEYLOW_1_RSVD1 24 +#define BM_PXP_PS_CLRKEYLOW_1_RSVD1 0xFF000000 +#define BF_PXP_PS_CLRKEYLOW_1_RSVD1(v) \ + (((v) << 24) & BM_PXP_PS_CLRKEYLOW_1_RSVD1) +#define BP_PXP_PS_CLRKEYLOW_1_PIXEL 0 +#define BM_PXP_PS_CLRKEYLOW_1_PIXEL 0x00FFFFFF +#define BF_PXP_PS_CLRKEYLOW_1_PIXEL(v) \ + (((v) << 0) & BM_PXP_PS_CLRKEYLOW_1_PIXEL) + +#define HW_PXP_PS_CLRKEYHIGH_1 (0x000002e0) + +#define BP_PXP_PS_CLRKEYHIGH_1_RSVD1 24 +#define BM_PXP_PS_CLRKEYHIGH_1_RSVD1 0xFF000000 +#define BF_PXP_PS_CLRKEYHIGH_1_RSVD1(v) \ + (((v) << 24) & BM_PXP_PS_CLRKEYHIGH_1_RSVD1) +#define BP_PXP_PS_CLRKEYHIGH_1_PIXEL 0 +#define BM_PXP_PS_CLRKEYHIGH_1_PIXEL 0x00FFFFFF +#define BF_PXP_PS_CLRKEYHIGH_1_PIXEL(v) \ + (((v) << 0) & BM_PXP_PS_CLRKEYHIGH_1_PIXEL) + +#define HW_PXP_AS_CLRKEYLOW_1 (0x000002f0) + +#define BP_PXP_AS_CLRKEYLOW_1_RSVD1 24 +#define BM_PXP_AS_CLRKEYLOW_1_RSVD1 0xFF000000 +#define BF_PXP_AS_CLRKEYLOW_1_RSVD1(v) \ + (((v) << 24) & BM_PXP_AS_CLRKEYLOW_1_RSVD1) +#define BP_PXP_AS_CLRKEYLOW_1_PIXEL 0 +#define BM_PXP_AS_CLRKEYLOW_1_PIXEL 0x00FFFFFF +#define BF_PXP_AS_CLRKEYLOW_1_PIXEL(v) \ + (((v) << 0) & BM_PXP_AS_CLRKEYLOW_1_PIXEL) + +#define HW_PXP_AS_CLRKEYHIGH_1 (0x00000300) + +#define BP_PXP_AS_CLRKEYHIGH_1_RSVD1 24 +#define BM_PXP_AS_CLRKEYHIGH_1_RSVD1 0xFF000000 +#define BF_PXP_AS_CLRKEYHIGH_1_RSVD1(v) \ + (((v) << 24) & BM_PXP_AS_CLRKEYHIGH_1_RSVD1) +#define BP_PXP_AS_CLRKEYHIGH_1_PIXEL 0 +#define BM_PXP_AS_CLRKEYHIGH_1_PIXEL 0x00FFFFFF +#define BF_PXP_AS_CLRKEYHIGH_1_PIXEL(v) \ + (((v) << 0) & BM_PXP_AS_CLRKEYHIGH_1_PIXEL) + +#define HW_PXP_CTRL2 (0x00000310) +#define HW_PXP_CTRL2_SET (0x00000314) +#define HW_PXP_CTRL2_CLR (0x00000318) +#define HW_PXP_CTRL2_TOG (0x0000031c) + +#define BP_PXP_CTRL2_RSVD3 28 +#define BM_PXP_CTRL2_RSVD3 0xF0000000 +#define BF_PXP_CTRL2_RSVD3(v) \ + (((v) << 28) & BM_PXP_CTRL2_RSVD3) +#define BM_PXP_CTRL2_ENABLE_ROTATE1 0x08000000 +#define BF_PXP_CTRL2_ENABLE_ROTATE1(v) \ + (((v) << 27) & BM_PXP_CTRL2_ENABLE_ROTATE1) +#define BM_PXP_CTRL2_ENABLE_ROTATE0 0x04000000 +#define BF_PXP_CTRL2_ENABLE_ROTATE0(v) \ + (((v) << 26) & BM_PXP_CTRL2_ENABLE_ROTATE0) +#define BM_PXP_CTRL2_ENABLE_LUT 0x02000000 +#define BF_PXP_CTRL2_ENABLE_LUT(v) \ + (((v) << 25) & BM_PXP_CTRL2_ENABLE_LUT) +#define BM_PXP_CTRL2_ENABLE_CSC2 0x01000000 +#define BF_PXP_CTRL2_ENABLE_CSC2(v) \ + (((v) << 24) & BM_PXP_CTRL2_ENABLE_CSC2) +#define BM_PXP_CTRL2_BLOCK_SIZE 0x00800000 +#define BF_PXP_CTRL2_BLOCK_SIZE(v) \ + (((v) << 23) & BM_PXP_CTRL2_BLOCK_SIZE) +#define BV_PXP_CTRL2_BLOCK_SIZE__8X8 0x0 +#define BV_PXP_CTRL2_BLOCK_SIZE__16X16 0x1 +#define BM_PXP_CTRL2_RSVD2 0x00400000 +#define BF_PXP_CTRL2_RSVD2(v) \ + (((v) << 22) & BM_PXP_CTRL2_RSVD2) +#define BM_PXP_CTRL2_ENABLE_ALPHA_B 0x00200000 +#define BF_PXP_CTRL2_ENABLE_ALPHA_B(v) \ + (((v) << 21) & BM_PXP_CTRL2_ENABLE_ALPHA_B) +#define BM_PXP_CTRL2_ENABLE_INPUT_FETCH_STORE 0x00100000 +#define BF_PXP_CTRL2_ENABLE_INPUT_FETCH_STORE(v) \ + (((v) << 20) & BM_PXP_CTRL2_ENABLE_INPUT_FETCH_STORE) +#define BM_PXP_CTRL2_ENABLE_WFE_B 0x00080000 +#define BF_PXP_CTRL2_ENABLE_WFE_B(v) \ + (((v) << 19) & BM_PXP_CTRL2_ENABLE_WFE_B) +#define BM_PXP_CTRL2_ENABLE_WFE_A 0x00040000 +#define BF_PXP_CTRL2_ENABLE_WFE_A(v) \ + (((v) << 18) & BM_PXP_CTRL2_ENABLE_WFE_A) +#define BM_PXP_CTRL2_ENABLE_DITHER 0x00020000 +#define BF_PXP_CTRL2_ENABLE_DITHER(v) \ + (((v) << 17) & BM_PXP_CTRL2_ENABLE_DITHER) +#define BM_PXP_CTRL2_RSVD1 0x00010000 +#define BF_PXP_CTRL2_RSVD1(v) \ + (((v) << 16) & BM_PXP_CTRL2_RSVD1) +#define BM_PXP_CTRL2_VFLIP1 0x00008000 +#define BF_PXP_CTRL2_VFLIP1(v) \ + (((v) << 15) & BM_PXP_CTRL2_VFLIP1) +#define BM_PXP_CTRL2_HFLIP1 0x00004000 +#define BF_PXP_CTRL2_HFLIP1(v) \ + (((v) << 14) & BM_PXP_CTRL2_HFLIP1) +#define BP_PXP_CTRL2_ROTATE1 12 +#define BM_PXP_CTRL2_ROTATE1 0x00003000 +#define BF_PXP_CTRL2_ROTATE1(v) \ + (((v) << 12) & BM_PXP_CTRL2_ROTATE1) +#define BV_PXP_CTRL2_ROTATE1__ROT_0 0x0 +#define BV_PXP_CTRL2_ROTATE1__ROT_90 0x1 +#define BV_PXP_CTRL2_ROTATE1__ROT_180 0x2 +#define BV_PXP_CTRL2_ROTATE1__ROT_270 0x3 +#define BM_PXP_CTRL2_VFLIP0 0x00000800 +#define BF_PXP_CTRL2_VFLIP0(v) \ + (((v) << 11) & BM_PXP_CTRL2_VFLIP0) +#define BM_PXP_CTRL2_HFLIP0 0x00000400 +#define BF_PXP_CTRL2_HFLIP0(v) \ + (((v) << 10) & BM_PXP_CTRL2_HFLIP0) +#define BP_PXP_CTRL2_ROTATE0 8 +#define BM_PXP_CTRL2_ROTATE0 0x00000300 +#define BF_PXP_CTRL2_ROTATE0(v) \ + (((v) << 8) & BM_PXP_CTRL2_ROTATE0) +#define BV_PXP_CTRL2_ROTATE0__ROT_0 0x0 +#define BV_PXP_CTRL2_ROTATE0__ROT_90 0x1 +#define BV_PXP_CTRL2_ROTATE0__ROT_180 0x2 +#define BV_PXP_CTRL2_ROTATE0__ROT_270 0x3 +#define BP_PXP_CTRL2_RSVD0 1 +#define BM_PXP_CTRL2_RSVD0 0x000000FE +#define BF_PXP_CTRL2_RSVD0(v) \ + (((v) << 1) & BM_PXP_CTRL2_RSVD0) +#define BM_PXP_CTRL2_ENABLE 0x00000001 +#define BF_PXP_CTRL2_ENABLE(v) \ + (((v) << 0) & BM_PXP_CTRL2_ENABLE) + +#define HW_PXP_POWER_REG0 (0x00000320) + +#define BP_PXP_POWER_REG0_CTRL 12 +#define BM_PXP_POWER_REG0_CTRL 0xFFFFF000 +#define BF_PXP_POWER_REG0_CTRL(v) \ + (((v) << 12) & BM_PXP_POWER_REG0_CTRL) +#define BP_PXP_POWER_REG0_ROT0_MEM_LP_STATE 9 +#define BM_PXP_POWER_REG0_ROT0_MEM_LP_STATE 0x00000E00 +#define BF_PXP_POWER_REG0_ROT0_MEM_LP_STATE(v) \ + (((v) << 9) & BM_PXP_POWER_REG0_ROT0_MEM_LP_STATE) +#define BV_PXP_POWER_REG0_ROT0_MEM_LP_STATE__NONE 0x0 +#define BV_PXP_POWER_REG0_ROT0_MEM_LP_STATE__LS 0x1 +#define BV_PXP_POWER_REG0_ROT0_MEM_LP_STATE__DS 0x2 +#define BV_PXP_POWER_REG0_ROT0_MEM_LP_STATE__SD 0x4 +#define BP_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN 6 +#define BM_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN 0x000001C0 +#define BF_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN(v) \ + (((v) << 6) & BM_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN) +#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN__NONE 0x0 +#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN__LS 0x1 +#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN__DS 0x2 +#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN__SD 0x4 +#define BP_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN 3 +#define BM_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN 0x00000038 +#define BF_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN(v) \ + (((v) << 3) & BM_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN) +#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN__NONE 0x0 +#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN__LS 0x1 +#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN__DS 0x2 +#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN__SD 0x4 +#define BP_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0 0 +#define BM_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0 0x00000007 +#define BF_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0(v) \ + (((v) << 0) & BM_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0) +#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0__NONE 0x0 +#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0__LS 0x1 +#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0__DS 0x2 +#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0__SD 0x4 + +#define HW_PXP_POWER_REG1 (0x00000330) + +#define BP_PXP_POWER_REG1_RSVD0 24 +#define BM_PXP_POWER_REG1_RSVD0 0xFF000000 +#define BF_PXP_POWER_REG1_RSVD0(v) \ + (((v) << 24) & BM_PXP_POWER_REG1_RSVD0) +#define BP_PXP_POWER_REG1_ALU_B_MEM_LP_STATE 21 +#define BM_PXP_POWER_REG1_ALU_B_MEM_LP_STATE 0x00E00000 +#define BF_PXP_POWER_REG1_ALU_B_MEM_LP_STATE(v) \ + (((v) << 21) & BM_PXP_POWER_REG1_ALU_B_MEM_LP_STATE) +#define BV_PXP_POWER_REG1_ALU_B_MEM_LP_STATE__NONE 0x0 +#define BV_PXP_POWER_REG1_ALU_B_MEM_LP_STATE__LS 0x1 +#define BV_PXP_POWER_REG1_ALU_B_MEM_LP_STATE__DS 0x2 +#define BV_PXP_POWER_REG1_ALU_B_MEM_LP_STATE__SD 0x4 +#define BP_PXP_POWER_REG1_ALU_A_MEM_LP_STATE 18 +#define BM_PXP_POWER_REG1_ALU_A_MEM_LP_STATE 0x001C0000 +#define BF_PXP_POWER_REG1_ALU_A_MEM_LP_STATE(v) \ + (((v) << 18) & BM_PXP_POWER_REG1_ALU_A_MEM_LP_STATE) +#define BV_PXP_POWER_REG1_ALU_A_MEM_LP_STATE__NONE 0x0 +#define BV_PXP_POWER_REG1_ALU_A_MEM_LP_STATE__LS 0x1 +#define BV_PXP_POWER_REG1_ALU_A_MEM_LP_STATE__DS 0x2 +#define BV_PXP_POWER_REG1_ALU_A_MEM_LP_STATE__SD 0x4 +#define BP_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE 15 +#define BM_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE 0x00038000 +#define BF_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE(v) \ + (((v) << 15) & BM_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE) +#define BV_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE__NONE 0x0 +#define BV_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE__LS 0x1 +#define BV_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE__DS 0x2 +#define BV_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE__SD 0x4 +#define BP_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE 12 +#define BM_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE 0x00007000 +#define BF_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE(v) \ + (((v) << 12) & BM_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE) +#define BV_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE__NONE 0x0 +#define BV_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE__LS 0x1 +#define BV_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE__DS 0x2 +#define BV_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE__SD 0x4 +#define BP_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE 9 +#define BM_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE 0x00000E00 +#define BF_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE(v) \ + (((v) << 9) & BM_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE) +#define BV_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE__NONE 0x0 +#define BV_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE__LS 0x1 +#define BV_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE__DS 0x2 +#define BV_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE__SD 0x4 +#define BP_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE 6 +#define BM_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE 0x000001C0 +#define BF_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE(v) \ + (((v) << 6) & BM_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE) +#define BV_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE__NONE 0x0 +#define BV_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE__LS 0x1 +#define BV_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE__DS 0x2 +#define BV_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE__SD 0x4 +#define BP_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE 3 +#define BM_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE 0x00000038 +#define BF_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE(v) \ + (((v) << 3) & BM_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE) +#define BV_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE__NONE 0x0 +#define BV_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE__LS 0x1 +#define BV_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE__DS 0x2 +#define BV_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE__SD 0x4 +#define BP_PXP_POWER_REG1_ROT1_MEM_LP_STATE 0 +#define BM_PXP_POWER_REG1_ROT1_MEM_LP_STATE 0x00000007 +#define BF_PXP_POWER_REG1_ROT1_MEM_LP_STATE(v) \ + (((v) << 0) & BM_PXP_POWER_REG1_ROT1_MEM_LP_STATE) +#define BV_PXP_POWER_REG1_ROT1_MEM_LP_STATE__NONE 0x0 +#define BV_PXP_POWER_REG1_ROT1_MEM_LP_STATE__LS 0x1 +#define BV_PXP_POWER_REG1_ROT1_MEM_LP_STATE__DS 0x2 +#define BV_PXP_POWER_REG1_ROT1_MEM_LP_STATE__SD 0x4 + +#define HW_PXP_DATA_PATH_CTRL0 (0x00000340) +#define HW_PXP_DATA_PATH_CTRL0_SET (0x00000344) +#define HW_PXP_DATA_PATH_CTRL0_CLR (0x00000348) +#define HW_PXP_DATA_PATH_CTRL0_TOG (0x0000034c) + +#define BP_PXP_DATA_PATH_CTRL0_MUX15_SEL 30 +#define BM_PXP_DATA_PATH_CTRL0_MUX15_SEL 0xC0000000 +#define BF_PXP_DATA_PATH_CTRL0_MUX15_SEL(v) \ + (((v) << 30) & BM_PXP_DATA_PATH_CTRL0_MUX15_SEL) +#define BV_PXP_DATA_PATH_CTRL0_MUX15_SEL__0 0x0 +#define BV_PXP_DATA_PATH_CTRL0_MUX15_SEL__1 0x1 +#define BV_PXP_DATA_PATH_CTRL0_MUX15_SEL__2 0x2 +#define BV_PXP_DATA_PATH_CTRL0_MUX15_SEL__3 0x3 +#define BP_PXP_DATA_PATH_CTRL0_MUX14_SEL 28 +#define BM_PXP_DATA_PATH_CTRL0_MUX14_SEL 0x30000000 +#define BF_PXP_DATA_PATH_CTRL0_MUX14_SEL(v) \ + (((v) << 28) & BM_PXP_DATA_PATH_CTRL0_MUX14_SEL) +#define BV_PXP_DATA_PATH_CTRL0_MUX14_SEL__0 0x0 +#define BV_PXP_DATA_PATH_CTRL0_MUX14_SEL__1 0x1 +#define BV_PXP_DATA_PATH_CTRL0_MUX14_SEL__2 0x2 +#define BV_PXP_DATA_PATH_CTRL0_MUX14_SEL__3 0x3 +#define BP_PXP_DATA_PATH_CTRL0_MUX13_SEL 26 +#define BM_PXP_DATA_PATH_CTRL0_MUX13_SEL 0x0C000000 +#define BF_PXP_DATA_PATH_CTRL0_MUX13_SEL(v) \ + (((v) << 26) & BM_PXP_DATA_PATH_CTRL0_MUX13_SEL) +#define BV_PXP_DATA_PATH_CTRL0_MUX13_SEL__0 0x0 +#define BV_PXP_DATA_PATH_CTRL0_MUX13_SEL__1 0x1 +#define BV_PXP_DATA_PATH_CTRL0_MUX13_SEL__2 0x2 +#define BV_PXP_DATA_PATH_CTRL0_MUX13_SEL__3 0x3 +#define BP_PXP_DATA_PATH_CTRL0_MUX12_SEL 24 +#define BM_PXP_DATA_PATH_CTRL0_MUX12_SEL 0x03000000 +#define BF_PXP_DATA_PATH_CTRL0_MUX12_SEL(v) \ + (((v) << 24) & BM_PXP_DATA_PATH_CTRL0_MUX12_SEL) +#define BV_PXP_DATA_PATH_CTRL0_MUX12_SEL__0 0x0 +#define BV_PXP_DATA_PATH_CTRL0_MUX12_SEL__1 0x1 +#define BV_PXP_DATA_PATH_CTRL0_MUX12_SEL__2 0x2 +#define BV_PXP_DATA_PATH_CTRL0_MUX12_SEL__3 0x3 +#define BP_PXP_DATA_PATH_CTRL0_MUX11_SEL 22 +#define BM_PXP_DATA_PATH_CTRL0_MUX11_SEL 0x00C00000 +#define BF_PXP_DATA_PATH_CTRL0_MUX11_SEL(v) \ + (((v) << 22) & BM_PXP_DATA_PATH_CTRL0_MUX11_SEL) +#define BV_PXP_DATA_PATH_CTRL0_MUX11_SEL__0 0x0 +#define BV_PXP_DATA_PATH_CTRL0_MUX11_SEL__1 0x1 +#define BV_PXP_DATA_PATH_CTRL0_MUX11_SEL__2 0x2 +#define BV_PXP_DATA_PATH_CTRL0_MUX11_SEL__3 0x3 +#define BP_PXP_DATA_PATH_CTRL0_MUX10_SEL 20 +#define BM_PXP_DATA_PATH_CTRL0_MUX10_SEL 0x00300000 +#define BF_PXP_DATA_PATH_CTRL0_MUX10_SEL(v) \ + (((v) << 20) & BM_PXP_DATA_PATH_CTRL0_MUX10_SEL) +#define BV_PXP_DATA_PATH_CTRL0_MUX10_SEL__0 0x0 +#define BV_PXP_DATA_PATH_CTRL0_MUX10_SEL__1 0x1 +#define BV_PXP_DATA_PATH_CTRL0_MUX10_SEL__2 0x2 +#define BV_PXP_DATA_PATH_CTRL0_MUX10_SEL__3 0x3 +#define BP_PXP_DATA_PATH_CTRL0_MUX9_SEL 18 +#define BM_PXP_DATA_PATH_CTRL0_MUX9_SEL 0x000C0000 +#define BF_PXP_DATA_PATH_CTRL0_MUX9_SEL(v) \ + (((v) << 18) & BM_PXP_DATA_PATH_CTRL0_MUX9_SEL) +#define BV_PXP_DATA_PATH_CTRL0_MUX9_SEL__0 0x0 +#define BV_PXP_DATA_PATH_CTRL0_MUX9_SEL__1 0x1 +#define BV_PXP_DATA_PATH_CTRL0_MUX9_SEL__2 0x2 +#define BV_PXP_DATA_PATH_CTRL0_MUX9_SEL__3 0x3 +#define BP_PXP_DATA_PATH_CTRL0_MUX8_SEL 16 +#define BM_PXP_DATA_PATH_CTRL0_MUX8_SEL 0x00030000 +#define BF_PXP_DATA_PATH_CTRL0_MUX8_SEL(v) \ + (((v) << 16) & BM_PXP_DATA_PATH_CTRL0_MUX8_SEL) +#define BV_PXP_DATA_PATH_CTRL0_MUX8_SEL__0 0x0 +#define BV_PXP_DATA_PATH_CTRL0_MUX8_SEL__1 0x1 +#define BV_PXP_DATA_PATH_CTRL0_MUX8_SEL__2 0x2 +#define BV_PXP_DATA_PATH_CTRL0_MUX8_SEL__3 0x3 +#define BP_PXP_DATA_PATH_CTRL0_MUX7_SEL 14 +#define BM_PXP_DATA_PATH_CTRL0_MUX7_SEL 0x0000C000 +#define BF_PXP_DATA_PATH_CTRL0_MUX7_SEL(v) \ + (((v) << 14) & BM_PXP_DATA_PATH_CTRL0_MUX7_SEL) +#define BV_PXP_DATA_PATH_CTRL0_MUX7_SEL__0 0x0 +#define BV_PXP_DATA_PATH_CTRL0_MUX7_SEL__1 0x1 +#define BV_PXP_DATA_PATH_CTRL0_MUX7_SEL__2 0x2 +#define BV_PXP_DATA_PATH_CTRL0_MUX7_SEL__3 0x3 +#define BP_PXP_DATA_PATH_CTRL0_MUX6_SEL 12 +#define BM_PXP_DATA_PATH_CTRL0_MUX6_SEL 0x00003000 +#define BF_PXP_DATA_PATH_CTRL0_MUX6_SEL(v) \ + (((v) << 12) & BM_PXP_DATA_PATH_CTRL0_MUX6_SEL) +#define BV_PXP_DATA_PATH_CTRL0_MUX6_SEL__0 0x0 +#define BV_PXP_DATA_PATH_CTRL0_MUX6_SEL__1 0x1 +#define BV_PXP_DATA_PATH_CTRL0_MUX6_SEL__2 0x2 +#define BV_PXP_DATA_PATH_CTRL0_MUX6_SEL__3 0x3 +#define BP_PXP_DATA_PATH_CTRL0_MUX5_SEL 10 +#define BM_PXP_DATA_PATH_CTRL0_MUX5_SEL 0x00000C00 +#define BF_PXP_DATA_PATH_CTRL0_MUX5_SEL(v) \ + (((v) << 10) & BM_PXP_DATA_PATH_CTRL0_MUX5_SEL) +#define BV_PXP_DATA_PATH_CTRL0_MUX5_SEL__0 0x0 +#define BV_PXP_DATA_PATH_CTRL0_MUX5_SEL__1 0x1 +#define BV_PXP_DATA_PATH_CTRL0_MUX5_SEL__2 0x2 +#define BV_PXP_DATA_PATH_CTRL0_MUX5_SEL__3 0x3 +#define BP_PXP_DATA_PATH_CTRL0_MUX4_SEL 8 +#define BM_PXP_DATA_PATH_CTRL0_MUX4_SEL 0x00000300 +#define BF_PXP_DATA_PATH_CTRL0_MUX4_SEL(v) \ + (((v) << 8) & BM_PXP_DATA_PATH_CTRL0_MUX4_SEL) +#define BV_PXP_DATA_PATH_CTRL0_MUX4_SEL__0 0x0 +#define BV_PXP_DATA_PATH_CTRL0_MUX4_SEL__1 0x1 +#define BV_PXP_DATA_PATH_CTRL0_MUX4_SEL__2 0x2 +#define BV_PXP_DATA_PATH_CTRL0_MUX4_SEL__3 0x3 +#define BP_PXP_DATA_PATH_CTRL0_MUX3_SEL 6 +#define BM_PXP_DATA_PATH_CTRL0_MUX3_SEL 0x000000C0 +#define BF_PXP_DATA_PATH_CTRL0_MUX3_SEL(v) \ + (((v) << 6) & BM_PXP_DATA_PATH_CTRL0_MUX3_SEL) +#define BV_PXP_DATA_PATH_CTRL0_MUX3_SEL__0 0x0 +#define BV_PXP_DATA_PATH_CTRL0_MUX3_SEL__1 0x1 +#define BV_PXP_DATA_PATH_CTRL0_MUX3_SEL__2 0x2 +#define BV_PXP_DATA_PATH_CTRL0_MUX3_SEL__3 0x3 +#define BP_PXP_DATA_PATH_CTRL0_MUX2_SEL 4 +#define BM_PXP_DATA_PATH_CTRL0_MUX2_SEL 0x00000030 +#define BF_PXP_DATA_PATH_CTRL0_MUX2_SEL(v) \ + (((v) << 4) & BM_PXP_DATA_PATH_CTRL0_MUX2_SEL) +#define BV_PXP_DATA_PATH_CTRL0_MUX2_SEL__0 0x0 +#define BV_PXP_DATA_PATH_CTRL0_MUX2_SEL__1 0x1 +#define BV_PXP_DATA_PATH_CTRL0_MUX2_SEL__2 0x2 +#define BV_PXP_DATA_PATH_CTRL0_MUX2_SEL__3 0x3 +#define BP_PXP_DATA_PATH_CTRL0_MUX1_SEL 2 +#define BM_PXP_DATA_PATH_CTRL0_MUX1_SEL 0x0000000C +#define BF_PXP_DATA_PATH_CTRL0_MUX1_SEL(v) \ + (((v) << 2) & BM_PXP_DATA_PATH_CTRL0_MUX1_SEL) +#define BV_PXP_DATA_PATH_CTRL0_MUX1_SEL__0 0x0 +#define BV_PXP_DATA_PATH_CTRL0_MUX1_SEL__1 0x1 +#define BV_PXP_DATA_PATH_CTRL0_MUX1_SEL__2 0x2 +#define BV_PXP_DATA_PATH_CTRL0_MUX1_SEL__3 0x3 +#define BP_PXP_DATA_PATH_CTRL0_MUX0_SEL 0 +#define BM_PXP_DATA_PATH_CTRL0_MUX0_SEL 0x00000003 +#define BF_PXP_DATA_PATH_CTRL0_MUX0_SEL(v) \ + (((v) << 0) & BM_PXP_DATA_PATH_CTRL0_MUX0_SEL) +#define BV_PXP_DATA_PATH_CTRL0_MUX0_SEL__0 0x0 +#define BV_PXP_DATA_PATH_CTRL0_MUX0_SEL__1 0x1 +#define BV_PXP_DATA_PATH_CTRL0_MUX0_SEL__2 0x2 +#define BV_PXP_DATA_PATH_CTRL0_MUX0_SEL__3 0x3 + +#define HW_PXP_DATA_PATH_CTRL1 (0x00000350) +#define HW_PXP_DATA_PATH_CTRL1_SET (0x00000354) +#define HW_PXP_DATA_PATH_CTRL1_CLR (0x00000358) +#define HW_PXP_DATA_PATH_CTRL1_TOG (0x0000035c) + +#define BP_PXP_DATA_PATH_CTRL1_RSVD0 4 +#define BM_PXP_DATA_PATH_CTRL1_RSVD0 0xFFFFFFF0 +#define BF_PXP_DATA_PATH_CTRL1_RSVD0(v) \ + (((v) << 4) & BM_PXP_DATA_PATH_CTRL1_RSVD0) +#define BP_PXP_DATA_PATH_CTRL1_MUX17_SEL 2 +#define BM_PXP_DATA_PATH_CTRL1_MUX17_SEL 0x0000000C +#define BF_PXP_DATA_PATH_CTRL1_MUX17_SEL(v) \ + (((v) << 2) & BM_PXP_DATA_PATH_CTRL1_MUX17_SEL) +#define BV_PXP_DATA_PATH_CTRL1_MUX17_SEL__0 0x0 +#define BV_PXP_DATA_PATH_CTRL1_MUX17_SEL__1 0x1 +#define BV_PXP_DATA_PATH_CTRL1_MUX17_SEL__2 0x2 +#define BV_PXP_DATA_PATH_CTRL1_MUX17_SEL__3 0x3 +#define BP_PXP_DATA_PATH_CTRL1_MUX16_SEL 0 +#define BM_PXP_DATA_PATH_CTRL1_MUX16_SEL 0x00000003 +#define BF_PXP_DATA_PATH_CTRL1_MUX16_SEL(v) \ + (((v) << 0) & BM_PXP_DATA_PATH_CTRL1_MUX16_SEL) +#define BV_PXP_DATA_PATH_CTRL1_MUX16_SEL__0 0x0 +#define BV_PXP_DATA_PATH_CTRL1_MUX16_SEL__1 0x1 +#define BV_PXP_DATA_PATH_CTRL1_MUX16_SEL__2 0x2 +#define BV_PXP_DATA_PATH_CTRL1_MUX16_SEL__3 0x3 + +#define HW_PXP_INIT_MEM_CTRL (0x00000360) +#define HW_PXP_INIT_MEM_CTRL_SET (0x00000364) +#define HW_PXP_INIT_MEM_CTRL_CLR (0x00000368) +#define HW_PXP_INIT_MEM_CTRL_TOG (0x0000036c) + +#define BM_PXP_INIT_MEM_CTRL_START 0x80000000 +#define BF_PXP_INIT_MEM_CTRL_START(v) \ + (((v) << 31) & BM_PXP_INIT_MEM_CTRL_START) +#define BP_PXP_INIT_MEM_CTRL_SELECT 27 +#define BM_PXP_INIT_MEM_CTRL_SELECT 0x78000000 +#define BF_PXP_INIT_MEM_CTRL_SELECT(v) \ + (((v) << 27) & BM_PXP_INIT_MEM_CTRL_SELECT) +#define BV_PXP_INIT_MEM_CTRL_SELECT__DITHER0_LUT 0x0 +#define BV_PXP_INIT_MEM_CTRL_SELECT__DITHER0_ERR0 0x1 +#define BV_PXP_INIT_MEM_CTRL_SELECT__DITHER0_ERR1 0x2 +#define BV_PXP_INIT_MEM_CTRL_SELECT__DITHER1_LUT 0x3 +#define BV_PXP_INIT_MEM_CTRL_SELECT__DITHER2_LUT 0x4 +#define BV_PXP_INIT_MEM_CTRL_SELECT__ALU_A 0x5 +#define BV_PXP_INIT_MEM_CTRL_SELECT__ALU_B 0x6 +#define BV_PXP_INIT_MEM_CTRL_SELECT__WFE_A_FETCH 0x7 +#define BV_PXP_INIT_MEM_CTRL_SELECT__WFE_B_FETCH 0x8 +#define BV_PXP_INIT_MEM_CTRL_SELECT__RESERVED 0x15 +#define BP_PXP_INIT_MEM_CTRL_RSVD0 16 +#define BM_PXP_INIT_MEM_CTRL_RSVD0 0x07FF0000 +#define BF_PXP_INIT_MEM_CTRL_RSVD0(v) \ + (((v) << 16) & BM_PXP_INIT_MEM_CTRL_RSVD0) +#define BP_PXP_INIT_MEM_CTRL_ADDR 0 +#define BM_PXP_INIT_MEM_CTRL_ADDR 0x0000FFFF +#define BF_PXP_INIT_MEM_CTRL_ADDR(v) \ + (((v) << 0) & BM_PXP_INIT_MEM_CTRL_ADDR) + +#define HW_PXP_INIT_MEM_DATA (0x00000370) + +#define BP_PXP_INIT_MEM_DATA_DATA 0 +#define BM_PXP_INIT_MEM_DATA_DATA 0xFFFFFFFF +#define BF_PXP_INIT_MEM_DATA_DATA(v) (v) + +#define HW_PXP_INIT_MEM_DATA_HIGH (0x00000380) + +#define BP_PXP_INIT_MEM_DATA_HIGH_DATA 0 +#define BM_PXP_INIT_MEM_DATA_HIGH_DATA 0xFFFFFFFF +#define BF_PXP_INIT_MEM_DATA_HIGH_DATA(v) (v) + +#define HW_PXP_IRQ_MASK (0x00000390) +#define HW_PXP_IRQ_MASK_SET (0x00000394) +#define HW_PXP_IRQ_MASK_CLR (0x00000398) +#define HW_PXP_IRQ_MASK_TOG (0x0000039c) + +#define BM_PXP_IRQ_MASK_COMPRESS_DONE_IRQ_EN 0x80000000 +#define BF_PXP_IRQ_MASK_COMPRESS_DONE_IRQ_EN(v) \ + (((v) << 31) & BM_PXP_IRQ_MASK_COMPRESS_DONE_IRQ_EN) +#define BP_PXP_IRQ_MASK_RSVD1 16 +#define BM_PXP_IRQ_MASK_RSVD1 0x7FFF0000 +#define BF_PXP_IRQ_MASK_RSVD1(v) \ + (((v) << 16) & BM_PXP_IRQ_MASK_RSVD1) +#define BM_PXP_IRQ_MASK_WFE_B_STORE_IRQ_EN 0x00008000 +#define BF_PXP_IRQ_MASK_WFE_B_STORE_IRQ_EN(v) \ + (((v) << 15) & BM_PXP_IRQ_MASK_WFE_B_STORE_IRQ_EN) +#define BM_PXP_IRQ_MASK_WFE_A_STORE_IRQ_EN 0x00004000 +#define BF_PXP_IRQ_MASK_WFE_A_STORE_IRQ_EN(v) \ + (((v) << 14) & BM_PXP_IRQ_MASK_WFE_A_STORE_IRQ_EN) +#define BM_PXP_IRQ_MASK_DITHER_STORE_IRQ_EN 0x00002000 +#define BF_PXP_IRQ_MASK_DITHER_STORE_IRQ_EN(v) \ + (((v) << 13) & BM_PXP_IRQ_MASK_DITHER_STORE_IRQ_EN) +#define BM_PXP_IRQ_MASK_FIRST_STORE_IRQ_EN 0x00001000 +#define BF_PXP_IRQ_MASK_FIRST_STORE_IRQ_EN(v) \ + (((v) << 12) & BM_PXP_IRQ_MASK_FIRST_STORE_IRQ_EN) +#define BM_PXP_IRQ_MASK_WFE_B_CH1_STORE_IRQ_EN 0x00000800 +#define BF_PXP_IRQ_MASK_WFE_B_CH1_STORE_IRQ_EN(v) \ + (((v) << 11) & BM_PXP_IRQ_MASK_WFE_B_CH1_STORE_IRQ_EN) +#define BM_PXP_IRQ_MASK_WFE_B_CH0_STORE_IRQ_EN 0x00000400 +#define BF_PXP_IRQ_MASK_WFE_B_CH0_STORE_IRQ_EN(v) \ + (((v) << 10) & BM_PXP_IRQ_MASK_WFE_B_CH0_STORE_IRQ_EN) +#define BM_PXP_IRQ_MASK_WFE_A_CH1_STORE_IRQ_EN 0x00000200 +#define BF_PXP_IRQ_MASK_WFE_A_CH1_STORE_IRQ_EN(v) \ + (((v) << 9) & BM_PXP_IRQ_MASK_WFE_A_CH1_STORE_IRQ_EN) +#define BM_PXP_IRQ_MASK_WFE_A_CH0_STORE_IRQ_EN 0x00000100 +#define BF_PXP_IRQ_MASK_WFE_A_CH0_STORE_IRQ_EN(v) \ + (((v) << 8) & BM_PXP_IRQ_MASK_WFE_A_CH0_STORE_IRQ_EN) +#define BM_PXP_IRQ_MASK_DITHER_CH1_STORE_IRQ_EN 0x00000080 +#define BF_PXP_IRQ_MASK_DITHER_CH1_STORE_IRQ_EN(v) \ + (((v) << 7) & BM_PXP_IRQ_MASK_DITHER_CH1_STORE_IRQ_EN) +#define BM_PXP_IRQ_MASK_DITHER_CH0_STORE_IRQ_EN 0x00000040 +#define BF_PXP_IRQ_MASK_DITHER_CH0_STORE_IRQ_EN(v) \ + (((v) << 6) & BM_PXP_IRQ_MASK_DITHER_CH0_STORE_IRQ_EN) +#define BM_PXP_IRQ_MASK_DITHER_CH1_PREFETCH_IRQ_EN 0x00000020 +#define BF_PXP_IRQ_MASK_DITHER_CH1_PREFETCH_IRQ_EN(v) \ + (((v) << 5) & BM_PXP_IRQ_MASK_DITHER_CH1_PREFETCH_IRQ_EN) +#define BM_PXP_IRQ_MASK_DITHER_CH0_PREFETCH_IRQ_EN 0x00000010 +#define BF_PXP_IRQ_MASK_DITHER_CH0_PREFETCH_IRQ_EN(v) \ + (((v) << 4) & BM_PXP_IRQ_MASK_DITHER_CH0_PREFETCH_IRQ_EN) +#define BM_PXP_IRQ_MASK_FIRST_CH1_STORE_IRQ_EN 0x00000008 +#define BF_PXP_IRQ_MASK_FIRST_CH1_STORE_IRQ_EN(v) \ + (((v) << 3) & BM_PXP_IRQ_MASK_FIRST_CH1_STORE_IRQ_EN) +#define BM_PXP_IRQ_MASK_FIRST_CH0_STORE_IRQ_EN 0x00000004 +#define BF_PXP_IRQ_MASK_FIRST_CH0_STORE_IRQ_EN(v) \ + (((v) << 2) & BM_PXP_IRQ_MASK_FIRST_CH0_STORE_IRQ_EN) +#define BM_PXP_IRQ_MASK_FIRST_CH1_PREFETCH_IRQ_EN 0x00000002 +#define BF_PXP_IRQ_MASK_FIRST_CH1_PREFETCH_IRQ_EN(v) \ + (((v) << 1) & BM_PXP_IRQ_MASK_FIRST_CH1_PREFETCH_IRQ_EN) +#define BM_PXP_IRQ_MASK_FIRST_CH0_PREFETCH_IRQ_EN 0x00000001 +#define BF_PXP_IRQ_MASK_FIRST_CH0_PREFETCH_IRQ_EN(v) \ + (((v) << 0) & BM_PXP_IRQ_MASK_FIRST_CH0_PREFETCH_IRQ_EN) + +#define HW_PXP_IRQ (0x000003a0) +#define HW_PXP_IRQ_SET (0x000003a4) +#define HW_PXP_IRQ_CLR (0x000003a8) +#define HW_PXP_IRQ_TOG (0x000003ac) + +#define BM_PXP_IRQ_COMPRESS_DONE_IRQ 0x80000000 +#define BF_PXP_IRQ_COMPRESS_DONE_IRQ(v) \ + (((v) << 31) & BM_PXP_IRQ_COMPRESS_DONE_IRQ) +#define BP_PXP_IRQ_RSVD1 16 +#define BM_PXP_IRQ_RSVD1 0x7FFF0000 +#define BF_PXP_IRQ_RSVD1(v) \ + (((v) << 16) & BM_PXP_IRQ_RSVD1) +#define BM_PXP_IRQ_WFE_B_STORE_IRQ 0x00008000 +#define BF_PXP_IRQ_WFE_B_STORE_IRQ(v) \ + (((v) << 15) & BM_PXP_IRQ_WFE_B_STORE_IRQ) +#define BM_PXP_IRQ_WFE_A_STORE_IRQ 0x00004000 +#define BF_PXP_IRQ_WFE_A_STORE_IRQ(v) \ + (((v) << 14) & BM_PXP_IRQ_WFE_A_STORE_IRQ) +#define BM_PXP_IRQ_DITHER_STORE_IRQ 0x00002000 +#define BF_PXP_IRQ_DITHER_STORE_IRQ(v) \ + (((v) << 13) & BM_PXP_IRQ_DITHER_STORE_IRQ) +#define BM_PXP_IRQ_FIRST_STORE_IRQ 0x00001000 +#define BF_PXP_IRQ_FIRST_STORE_IRQ(v) \ + (((v) << 12) & BM_PXP_IRQ_FIRST_STORE_IRQ) +#define BM_PXP_IRQ_WFE_B_CH1_STORE_IRQ 0x00000800 +#define BF_PXP_IRQ_WFE_B_CH1_STORE_IRQ(v) \ + (((v) << 11) & BM_PXP_IRQ_WFE_B_CH1_STORE_IRQ) +#define BM_PXP_IRQ_WFE_B_CH0_STORE_IRQ 0x00000400 +#define BF_PXP_IRQ_WFE_B_CH0_STORE_IRQ(v) \ + (((v) << 10) & BM_PXP_IRQ_WFE_B_CH0_STORE_IRQ) +#define BM_PXP_IRQ_WFE_A_CH1_STORE_IRQ 0x00000200 +#define BF_PXP_IRQ_WFE_A_CH1_STORE_IRQ(v) \ + (((v) << 9) & BM_PXP_IRQ_WFE_A_CH1_STORE_IRQ) +#define BM_PXP_IRQ_WFE_A_CH0_STORE_IRQ 0x00000100 +#define BF_PXP_IRQ_WFE_A_CH0_STORE_IRQ(v) \ + (((v) << 8) & BM_PXP_IRQ_WFE_A_CH0_STORE_IRQ) +#define BM_PXP_IRQ_DITHER_CH1_STORE_IRQ 0x00000080 +#define BF_PXP_IRQ_DITHER_CH1_STORE_IRQ(v) \ + (((v) << 7) & BM_PXP_IRQ_DITHER_CH1_STORE_IRQ) +#define BM_PXP_IRQ_DITHER_CH0_STORE_IRQ 0x00000040 +#define BF_PXP_IRQ_DITHER_CH0_STORE_IRQ(v) \ + (((v) << 6) & BM_PXP_IRQ_DITHER_CH0_STORE_IRQ) +#define BM_PXP_IRQ_DITHER_CH1_PREFETCH_IRQ 0x00000020 +#define BF_PXP_IRQ_DITHER_CH1_PREFETCH_IRQ(v) \ + (((v) << 5) & BM_PXP_IRQ_DITHER_CH1_PREFETCH_IRQ) +#define BM_PXP_IRQ_DITHER_CH0_PREFETCH_IRQ 0x00000010 +#define BF_PXP_IRQ_DITHER_CH0_PREFETCH_IRQ(v) \ + (((v) << 4) & BM_PXP_IRQ_DITHER_CH0_PREFETCH_IRQ) +#define BM_PXP_IRQ_FIRST_CH1_STORE_IRQ 0x00000008 +#define BF_PXP_IRQ_FIRST_CH1_STORE_IRQ(v) \ + (((v) << 3) & BM_PXP_IRQ_FIRST_CH1_STORE_IRQ) +#define BM_PXP_IRQ_FIRST_CH0_STORE_IRQ 0x00000004 +#define BF_PXP_IRQ_FIRST_CH0_STORE_IRQ(v) \ + (((v) << 2) & BM_PXP_IRQ_FIRST_CH0_STORE_IRQ) +#define BM_PXP_IRQ_FIRST_CH1_PREFETCH_IRQ 0x00000002 +#define BF_PXP_IRQ_FIRST_CH1_PREFETCH_IRQ(v) \ + (((v) << 1) & BM_PXP_IRQ_FIRST_CH1_PREFETCH_IRQ) +#define BM_PXP_IRQ_FIRST_CH0_PREFETCH_IRQ 0x00000001 +#define BF_PXP_IRQ_FIRST_CH0_PREFETCH_IRQ(v) \ + (((v) << 0) & BM_PXP_IRQ_FIRST_CH0_PREFETCH_IRQ) + +#define HW_PXP_NEXT (0x00000400) + +#define BP_PXP_NEXT_POINTER 2 +#define BM_PXP_NEXT_POINTER 0xFFFFFFFC +#define BF_PXP_NEXT_POINTER(v) \ + (((v) << 2) & BM_PXP_NEXT_POINTER) +#define BM_PXP_NEXT_RSVD 0x00000002 +#define BF_PXP_NEXT_RSVD(v) \ + (((v) << 1) & BM_PXP_NEXT_RSVD) +#define BM_PXP_NEXT_ENABLED 0x00000001 +#define BF_PXP_NEXT_ENABLED(v) \ + (((v) << 0) & BM_PXP_NEXT_ENABLED) + +#define HW_PXP_DEBUGCTRL (0x00000410) + +#define BP_PXP_DEBUGCTRL_RSVD 12 +#define BM_PXP_DEBUGCTRL_RSVD 0xFFFFF000 +#define BF_PXP_DEBUGCTRL_RSVD(v) \ + (((v) << 12) & BM_PXP_DEBUGCTRL_RSVD) +#define BP_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT 8 +#define BM_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT 0x00000F00 +#define BF_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT(v) \ + (((v) << 8) & BM_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT) +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__NONE 0x0 +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__MISS_CNT 0x1 +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__HIT_CNT 0x2 +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__LAT_CNT 0x4 +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__MAX_LAT 0x8 +#define BP_PXP_DEBUGCTRL_SELECT 0 +#define BM_PXP_DEBUGCTRL_SELECT 0x000000FF +#define BF_PXP_DEBUGCTRL_SELECT(v) \ + (((v) << 0) & BM_PXP_DEBUGCTRL_SELECT) +#define BV_PXP_DEBUGCTRL_SELECT__NONE 0x0 +#define BV_PXP_DEBUGCTRL_SELECT__CTRL 0x1 +#define BV_PXP_DEBUGCTRL_SELECT__PSBUF 0x2 +#define BV_PXP_DEBUGCTRL_SELECT__PSBAX 0x3 +#define BV_PXP_DEBUGCTRL_SELECT__PSBAY 0x4 +#define BV_PXP_DEBUGCTRL_SELECT__ASBUF 0x5 +#define BV_PXP_DEBUGCTRL_SELECT__ROTATION 0x6 +#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF0 0x7 +#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF1 0x8 +#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF2 0x9 +#define BV_PXP_DEBUGCTRL_SELECT__LUT_STAT 0x10 +#define BV_PXP_DEBUGCTRL_SELECT__LUT_MISS 0x11 +#define BV_PXP_DEBUGCTRL_SELECT__LUT_HIT 0x12 +#define BV_PXP_DEBUGCTRL_SELECT__LUT_LAT 0x13 +#define BV_PXP_DEBUGCTRL_SELECT__LUT_MAX_LAT 0x14 + +#define HW_PXP_DEBUG (0x00000420) + +#define BP_PXP_DEBUG_DATA 0 +#define BM_PXP_DEBUG_DATA 0xFFFFFFFF +#define BF_PXP_DEBUG_DATA(v) (v) + +#define HW_PXP_VERSION (0x00000430) + +#define BP_PXP_VERSION_MAJOR 24 +#define BM_PXP_VERSION_MAJOR 0xFF000000 +#define BF_PXP_VERSION_MAJOR(v) \ + (((v) << 24) & BM_PXP_VERSION_MAJOR) +#define BP_PXP_VERSION_MINOR 16 +#define BM_PXP_VERSION_MINOR 0x00FF0000 +#define BF_PXP_VERSION_MINOR(v) \ + (((v) << 16) & BM_PXP_VERSION_MINOR) +#define BP_PXP_VERSION_STEP 0 +#define BM_PXP_VERSION_STEP 0x0000FFFF +#define BF_PXP_VERSION_STEP(v) \ + (((v) << 0) & BM_PXP_VERSION_STEP) + +#endif /* __IMX_PXP_H__ */ diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c index 5f84d2aa47ab..c62e598ee7d0 100644 --- a/drivers/media/platform/m2m-deinterlace.c +++ b/drivers/media/platform/m2m-deinterlace.c @@ -438,9 +438,9 @@ static void deinterlace_device_run(void *priv) static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - strlcpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver)); - strlcpy(cap->card, MEM2MEM_NAME, sizeof(cap->card)); - strlcpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->card)); + strscpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver)); + strscpy(cap->card, MEM2MEM_NAME, sizeof(cap->card)); + strscpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->card)); /* * This is only a mem-to-mem video device. The capture and output * device capability flags are left only for backward compatibility @@ -474,7 +474,7 @@ static int enum_fmt(struct v4l2_fmtdesc *f, u32 type) if (i < NUM_FORMATS) { /* Format found */ fmt = &formats[i]; - strlcpy(f->description, fmt->name, sizeof(f->description)); + strscpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->fourcc; return 0; } diff --git a/drivers/media/platform/marvell-ccic/cafe-driver.c b/drivers/media/platform/marvell-ccic/cafe-driver.c index 57d2c483ad09..2986cb4b88d0 100644 --- a/drivers/media/platform/marvell-ccic/cafe-driver.c +++ b/drivers/media/platform/marvell-ccic/cafe-driver.c @@ -341,7 +341,7 @@ static int cafe_smbus_setup(struct cafe_camera *cam) return -ENOMEM; adap->owner = THIS_MODULE; adap->algo = &cafe_smbus_algo; - strcpy(adap->name, "cafe_ccic"); + strscpy(adap->name, "cafe_ccic", sizeof(adap->name)); adap->dev.parent = &cam->pdev->dev; i2c_set_adapdata(adap, cam); ret = i2c_add_adapter(adap); diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index dfdbd4354b74..f1b301810260 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -794,7 +794,7 @@ static void mcam_ctlr_image(struct mcam_camera *cam) /* * This field controls the generation of EOF(DVP only) */ - if (cam->bus_type != V4L2_MBUS_CSI2) + if (cam->bus_type != V4L2_MBUS_CSI2_DPHY) mcam_reg_set_bit(cam, REG_CTRL0, C0_EOF_VSYNC | C0_VEDGE_CTRL); } @@ -1023,7 +1023,7 @@ static int mcam_read_setup(struct mcam_camera *cam) cam->calc_dphy(cam); cam_dbg(cam, "camera: DPHY sets: dphy3=0x%x, dphy5=0x%x, dphy6=0x%x\n", cam->dphy[0], cam->dphy[1], cam->dphy[2]); - if (cam->bus_type == V4L2_MBUS_CSI2) + if (cam->bus_type == V4L2_MBUS_CSI2_DPHY) mcam_enable_mipi(cam); else mcam_disable_mipi(cam); @@ -1303,9 +1303,9 @@ static int mcam_vidioc_querycap(struct file *file, void *priv, { struct mcam_camera *cam = video_drvdata(file); - strcpy(cap->driver, "marvell_ccic"); - strcpy(cap->card, "marvell_ccic"); - strlcpy(cap->bus_info, cam->bus_info, sizeof(cap->bus_info)); + strscpy(cap->driver, "marvell_ccic", sizeof(cap->driver)); + strscpy(cap->card, "marvell_ccic", sizeof(cap->card)); + strscpy(cap->bus_info, cam->bus_info, sizeof(cap->bus_info)); cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; @@ -1318,8 +1318,8 @@ static int mcam_vidioc_enum_fmt_vid_cap(struct file *filp, { if (fmt->index >= N_MCAM_FMTS) return -EINVAL; - strlcpy(fmt->description, mcam_formats[fmt->index].desc, - sizeof(fmt->description)); + strscpy(fmt->description, mcam_formats[fmt->index].desc, + sizeof(fmt->description)); fmt->pixelformat = mcam_formats[fmt->index].pixelformat; return 0; } @@ -1421,7 +1421,7 @@ static int mcam_vidioc_enum_input(struct file *filp, void *priv, return -EINVAL; input->type = V4L2_INPUT_TYPE_CAMERA; - strcpy(input->name, "Camera"); + strscpy(input->name, "Camera", sizeof(input->name)); return 0; } diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c index 6d9f0abb2660..70a2833db0d1 100644 --- a/drivers/media/platform/marvell-ccic/mmp-driver.c +++ b/drivers/media/platform/marvell-ccic/mmp-driver.c @@ -362,7 +362,7 @@ static int mmpcam_probe(struct platform_device *pdev) mcam->mclk_div = pdata->mclk_div; mcam->bus_type = pdata->bus_type; mcam->dphy = pdata->dphy; - if (mcam->bus_type == V4L2_MBUS_CSI2) { + if (mcam->bus_type == V4L2_MBUS_CSI2_DPHY) { cam->mipi_clk = devm_clk_get(mcam->dev, "mipi"); if ((IS_ERR(cam->mipi_clk) && mcam->dphy[2] == 0)) return PTR_ERR(cam->mipi_clk); @@ -371,7 +371,7 @@ static int mmpcam_probe(struct platform_device *pdev) mcam->lane = pdata->lane; mcam->chip_id = MCAM_ARMADA610; mcam->buffer_mode = B_DMA_sg; - strlcpy(mcam->bus_info, "platform:mmp-camera", sizeof(mcam->bus_info)); + strscpy(mcam->bus_info, "platform:mmp-camera", sizeof(mcam->bus_info)); spin_lock_init(&mcam->dev_lock); /* * Get our I/O memory. diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c index 4f24da8afecc..2a5d5002c27e 100644 --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c @@ -94,8 +94,8 @@ static int mtk_jpeg_querycap(struct file *file, void *priv, { struct mtk_jpeg_dev *jpeg = video_drvdata(file); - strlcpy(cap->driver, MTK_JPEG_NAME " decoder", sizeof(cap->driver)); - strlcpy(cap->card, MTK_JPEG_NAME " decoder", sizeof(cap->card)); + strscpy(cap->driver, MTK_JPEG_NAME " decoder", sizeof(cap->driver)); + strscpy(cap->card, MTK_JPEG_NAME " decoder", sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(jpeg->dev)); diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c index ceffc31cc6eb..51a13466261e 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c @@ -619,9 +619,9 @@ static int mtk_mdp_m2m_querycap(struct file *file, void *fh, struct mtk_mdp_ctx *ctx = fh_to_ctx(fh); struct mtk_mdp_dev *mdp = ctx->mdp_dev; - strlcpy(cap->driver, MTK_MDP_MODULE_NAME, sizeof(cap->driver)); - strlcpy(cap->card, mdp->pdev->name, sizeof(cap->card)); - strlcpy(cap->bus_info, "platform:mt8173", sizeof(cap->bus_info)); + strscpy(cap->driver, MTK_MDP_MODULE_NAME, sizeof(cap->driver)); + strscpy(cap->card, mdp->pdev->name, sizeof(cap->card)); + strscpy(cap->bus_info, "platform:mt8173", sizeof(cap->bus_info)); return 0; } diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index 0c8a8b4c4e1c..ba619647bc10 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -613,9 +613,9 @@ static int vidioc_vdec_dqbuf(struct file *file, void *priv, static int vidioc_vdec_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - strlcpy(cap->driver, MTK_VCODEC_DEC_NAME, sizeof(cap->driver)); - strlcpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info)); - strlcpy(cap->card, MTK_PLATFORM_STR, sizeof(cap->card)); + strscpy(cap->driver, MTK_VCODEC_DEC_NAME, sizeof(cap->driver)); + strscpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info)); + strscpy(cap->card, MTK_PLATFORM_STR, sizeof(cap->card)); return 0; } diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c index 6ad408514a99..54631ad1c71e 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c @@ -222,9 +222,9 @@ static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *prov, static int vidioc_venc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - strlcpy(cap->driver, MTK_VCODEC_ENC_NAME, sizeof(cap->driver)); - strlcpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info)); - strlcpy(cap->card, MTK_PLATFORM_STR, sizeof(cap->card)); + strscpy(cap->driver, MTK_VCODEC_ENC_NAME, sizeof(cap->driver)); + strscpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info)); + strscpy(cap->card, MTK_PLATFORM_STR, sizeof(cap->card)); return 0; } diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c index 0c28d0b995cc..e80123cba406 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c @@ -49,16 +49,13 @@ int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data, struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)data; struct device *dev = &ctx->dev->plat_dev->dev; - mem->va = dma_alloc_coherent(dev, size, &mem->dma_addr, GFP_KERNEL); - + mem->va = dma_zalloc_coherent(dev, size, &mem->dma_addr, GFP_KERNEL); if (!mem->va) { mtk_v4l2_err("%s dma_alloc size=%ld failed!", dev_name(dev), size); return -ENOMEM; } - memset(mem->va, 0, size); - mtk_v4l2_debug(3, "[%d] - va = %p", ctx->id, mem->va); mtk_v4l2_debug(3, "[%d] - dma = 0x%lx", ctx->id, (unsigned long)mem->dma_addr); diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c b/drivers/media/platform/mtk-vpu/mtk_vpu.c index f8d35e3ac1dc..616f78b24a79 100644 --- a/drivers/media/platform/mtk-vpu/mtk_vpu.c +++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c @@ -480,12 +480,12 @@ EXPORT_SYMBOL_GPL(vpu_get_plat_device); /* load vpu program/data memory */ static int load_requested_vpu(struct mtk_vpu *vpu, - const struct firmware *vpu_fw, u8 fw_type) { size_t tcm_size = fw_type ? VPU_DTCM_SIZE : VPU_PTCM_SIZE; size_t fw_size = fw_type ? VPU_D_FW_SIZE : VPU_P_FW_SIZE; char *fw_name = fw_type ? VPU_D_FW : VPU_P_FW; + const struct firmware *vpu_fw; size_t dl_size = 0; size_t extra_fw_size = 0; void *dest; @@ -539,7 +539,6 @@ int vpu_load_firmware(struct platform_device *pdev) struct mtk_vpu *vpu; struct device *dev = &pdev->dev; struct vpu_run *run; - const struct firmware *vpu_fw = NULL; int ret; if (!pdev) { @@ -568,14 +567,14 @@ int vpu_load_firmware(struct platform_device *pdev) run->signaled = false; dev_dbg(vpu->dev, "firmware request\n"); /* Downloading program firmware to device*/ - ret = load_requested_vpu(vpu, vpu_fw, P_FW); + ret = load_requested_vpu(vpu, P_FW); if (ret < 0) { dev_err(dev, "Failed to request %s, %d\n", VPU_P_FW, ret); goto OUT_LOAD_FW; } /* Downloading data firmware to device */ - ret = load_requested_vpu(vpu, vpu_fw, D_FW); + ret = load_requested_vpu(vpu, D_FW); if (ret < 0) { dev_err(dev, "Failed to request %s, %d\n", VPU_D_FW, ret); goto OUT_LOAD_FW; diff --git a/drivers/media/platform/mx2_emmaprp.c b/drivers/media/platform/mx2_emmaprp.c index 64195c4ddeaf..27b078cf98e3 100644 --- a/drivers/media/platform/mx2_emmaprp.c +++ b/drivers/media/platform/mx2_emmaprp.c @@ -413,7 +413,7 @@ static int enum_fmt(struct v4l2_fmtdesc *f, u32 type) if (i < NUM_FORMATS) { /* Format found */ fmt = &formats[i]; - strlcpy(f->description, fmt->name, sizeof(f->description) - 1); + strscpy(f->description, fmt->name, sizeof(f->description) - 1); f->pixelformat = fmt->fourcc; return 0; } diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c index 5700b7818621..f447ae3bb465 100644 --- a/drivers/media/platform/omap/omap_vout.c +++ b/drivers/media/platform/omap/omap_vout.c @@ -1041,8 +1041,8 @@ static int vidioc_querycap(struct file *file, void *fh, { struct omap_vout_device *vout = fh; - strlcpy(cap->driver, VOUT_NAME, sizeof(cap->driver)); - strlcpy(cap->card, vout->vfd->name, sizeof(cap->card)); + strscpy(cap->driver, VOUT_NAME, sizeof(cap->driver)); + strscpy(cap->card, vout->vfd->name, sizeof(cap->card)); cap->bus_info[0] = '\0'; cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY; @@ -1060,8 +1060,8 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *fh, return -EINVAL; fmt->flags = omap_formats[index].flags; - strlcpy(fmt->description, omap_formats[index].description, - sizeof(fmt->description)); + strscpy(fmt->description, omap_formats[index].description, + sizeof(fmt->description)); fmt->pixelformat = omap_formats[index].pixelformat; return 0; @@ -1868,7 +1868,7 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout) vfd->release = video_device_release; vfd->ioctl_ops = &vout_ioctl_ops; - strlcpy(vfd->name, VOUT_NAME, sizeof(vfd->name)); + strscpy(vfd->name, VOUT_NAME, sizeof(vfd->name)); vfd->fops = &omap_vout_fops; vfd->v4l2_dev = &vout->vid_dev->v4l2_dev; diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 842e2235047d..77fb7987b42f 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -1677,7 +1677,7 @@ static int isp_register_entities(struct isp_device *isp) int ret; isp->media_dev.dev = isp->dev; - strlcpy(isp->media_dev.model, "TI OMAP3 ISP", + strscpy(isp->media_dev.model, "TI OMAP3 ISP", sizeof(isp->media_dev.model)); isp->media_dev.hw_revision = isp->revision; isp->media_dev.ops = &isp_media_ops; @@ -2054,7 +2054,7 @@ static int isp_fwnode_parse(struct device *dev, dev_dbg(dev, "CSI-1/CCP-2 configuration\n"); csi1 = true; break; - case V4L2_MBUS_CSI2: + case V4L2_MBUS_CSI2_DPHY: dev_dbg(dev, "CSI-2 configuration\n"); csi1 = false; break; @@ -2220,6 +2220,7 @@ static int isp_probe(struct platform_device *pdev) mutex_init(&isp->isp_mutex); spin_lock_init(&isp->stat_lock); + v4l2_async_notifier_init(&isp->notifier); ret = v4l2_async_notifier_parse_fwnode_endpoints( &pdev->dev, &isp->notifier, sizeof(struct isp_async_subdev), diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 77b73e27a274..14a1c24037c4 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -2641,7 +2641,7 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc) v4l2_subdev_init(sd, &ccdc_v4l2_ops); sd->internal_ops = &ccdc_v4l2_internal_ops; - strlcpy(sd->name, "OMAP3 ISP CCDC", sizeof(sd->name)); + strscpy(sd->name, "OMAP3 ISP CCDC", sizeof(sd->name)); sd->grp_id = 1 << 16; /* group ID for isp subdevs */ v4l2_set_subdevdata(sd, ccdc); sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE; diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index e062939d0d05..2dea423ffc0e 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -1070,7 +1070,7 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2) v4l2_subdev_init(sd, &ccp2_sd_ops); sd->internal_ops = &ccp2_sd_internal_ops; - strlcpy(sd->name, "OMAP3 ISP CCP2", sizeof(sd->name)); + strscpy(sd->name, "OMAP3 ISP CCP2", sizeof(sd->name)); sd->grp_id = 1 << 16; /* group ID for isp subdevs */ v4l2_set_subdevdata(sd, ccp2); sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index a4d3d030e81e..9c180f607bcb 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c @@ -1234,7 +1234,7 @@ static int csi2_init_entities(struct isp_csi2_device *csi2) v4l2_subdev_init(sd, &csi2_ops); sd->internal_ops = &csi2_internal_ops; - strlcpy(sd->name, "OMAP3 ISP CSI2a", sizeof(sd->name)); + strscpy(sd->name, "OMAP3 ISP CSI2a", sizeof(sd->name)); sd->grp_id = 1 << 16; /* group ID for isp subdevs */ v4l2_set_subdevdata(sd, csi2); diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c index 3195f7c8b8b7..6ea6aeafd751 100644 --- a/drivers/media/platform/omap3isp/isppreview.c +++ b/drivers/media/platform/omap3isp/isppreview.c @@ -2267,7 +2267,7 @@ static int preview_init_entities(struct isp_prev_device *prev) v4l2_subdev_init(sd, &preview_v4l2_ops); sd->internal_ops = &preview_v4l2_internal_ops; - strlcpy(sd->name, "OMAP3 ISP preview", sizeof(sd->name)); + strscpy(sd->name, "OMAP3 ISP preview", sizeof(sd->name)); sd->grp_id = 1 << 16; /* group ID for isp subdevs */ v4l2_set_subdevdata(sd, prev); sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c index 0b6a87508584..b281cae036b3 100644 --- a/drivers/media/platform/omap3isp/ispresizer.c +++ b/drivers/media/platform/omap3isp/ispresizer.c @@ -1723,7 +1723,7 @@ static int resizer_init_entities(struct isp_res_device *res) v4l2_subdev_init(sd, &resizer_v4l2_ops); sd->internal_ops = &resizer_v4l2_internal_ops; - strlcpy(sd->name, "OMAP3 ISP resizer", sizeof(sd->name)); + strscpy(sd->name, "OMAP3 ISP resizer", sizeof(sd->name)); sd->grp_id = 1 << 16; /* group ID for isp subdevs */ v4l2_set_subdevdata(sd, res); sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index 9d228eac24ea..5658f6a326f7 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -654,9 +654,9 @@ isp_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap) { struct isp_video *video = video_drvdata(file); - strlcpy(cap->driver, ISP_VIDEO_DRIVER_NAME, sizeof(cap->driver)); - strlcpy(cap->card, video->video.name, sizeof(cap->card)); - strlcpy(cap->bus_info, "media", sizeof(cap->bus_info)); + strscpy(cap->driver, ISP_VIDEO_DRIVER_NAME, sizeof(cap->driver)); + strscpy(cap->card, video->video.name, sizeof(cap->card)); + strscpy(cap->bus_info, "media", sizeof(cap->bus_info)); cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS; @@ -1251,7 +1251,7 @@ isp_video_enum_input(struct file *file, void *fh, struct v4l2_input *input) if (input->index > 0) return -EINVAL; - strlcpy(input->name, "camera", sizeof(input->name)); + strscpy(input->name, "camera", sizeof(input->name)); input->type = V4L2_INPUT_TYPE_CAMERA; return 0; diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c index b6e9e93bde7a..5f930560eb30 100644 --- a/drivers/media/platform/pxa_camera.c +++ b/drivers/media/platform/pxa_camera.c @@ -633,7 +633,7 @@ static unsigned int pxa_mbus_config_compatible(const struct v4l2_mbus_config *cf mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE); return (!hsync || !vsync || !pclk || !data || !mode) ? 0 : common_flags; - case V4L2_MBUS_CSI2: + case V4L2_MBUS_CSI2_DPHY: mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES; mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK | V4L2_MBUS_CSI2_CONTINUOUS_CLOCK); @@ -697,7 +697,6 @@ struct pxa_camera_dev { struct v4l2_pix_format current_pix; struct v4l2_async_subdev asd; - struct v4l2_async_subdev *asds[1]; /* * PXA27x is only supposed to handle one camera on its Quick Capture @@ -1994,9 +1993,9 @@ static int pxac_vidioc_s_fmt_vid_cap(struct file *filp, void *priv, static int pxac_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - strlcpy(cap->bus_info, "platform:pxa-camera", sizeof(cap->bus_info)); - strlcpy(cap->driver, PXA_CAM_DRV_NAME, sizeof(cap->driver)); - strlcpy(cap->card, pxa_cam_driver_description, sizeof(cap->card)); + strscpy(cap->bus_info, "platform:pxa-camera", sizeof(cap->bus_info)); + strscpy(cap->driver, PXA_CAM_DRV_NAME, sizeof(cap->driver)); + strscpy(cap->card, pxa_cam_driver_description, sizeof(cap->card)); cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; @@ -2010,7 +2009,7 @@ static int pxac_vidioc_enum_input(struct file *file, void *priv, return -EINVAL; i->type = V4L2_INPUT_TYPE_CAMERA; - strlcpy(i->name, "Camera", sizeof(i->name)); + strscpy(i->name, "Camera", sizeof(i->name)); return 0; } @@ -2299,7 +2298,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev, { u32 mclk_rate; struct device_node *remote, *np = dev->of_node; - struct v4l2_fwnode_endpoint ep; + struct v4l2_fwnode_endpoint ep = { .bus_type = 0 }; int err = of_property_read_u32(np, "clock-frequency", &mclk_rate); if (!err) { @@ -2352,12 +2351,10 @@ static int pxa_camera_pdata_from_dt(struct device *dev, asd->match_type = V4L2_ASYNC_MATCH_FWNODE; remote = of_graph_get_remote_port(np); - if (remote) { + if (remote) asd->match.fwnode = of_fwnode_handle(remote); - of_node_put(remote); - } else { + else dev_notice(dev, "no remote for %pOF\n", np); - } out: of_node_put(np); @@ -2397,7 +2394,7 @@ static int pxa_camera_probe(struct platform_device *pdev) pcdev->res = res; pcdev->pdata = pdev->dev.platform_data; - if (&pdev->dev.of_node && !pcdev->pdata) { + if (pdev->dev.of_node && !pcdev->pdata) { err = pxa_camera_pdata_from_dt(&pdev->dev, pcdev, &pcdev->asd); } else { pcdev->platform_flags = pcdev->pdata->flags; @@ -2495,9 +2492,14 @@ static int pxa_camera_probe(struct platform_device *pdev) if (err) goto exit_deactivate; - pcdev->asds[0] = &pcdev->asd; - pcdev->notifier.subdevs = pcdev->asds; - pcdev->notifier.num_subdevs = 1; + v4l2_async_notifier_init(&pcdev->notifier); + + err = v4l2_async_notifier_add_subdev(&pcdev->notifier, &pcdev->asd); + if (err) { + fwnode_handle_put(pcdev->asd.match.fwnode); + goto exit_free_v4l2dev; + } + pcdev->notifier.ops = &pxa_camera_sensor_ops; if (!of_have_populated_dt()) @@ -2505,7 +2507,7 @@ static int pxa_camera_probe(struct platform_device *pdev) err = pxa_camera_init_videobuf2(pcdev); if (err) - goto exit_free_v4l2dev; + goto exit_notifier_cleanup; if (pcdev->mclk) { v4l2_clk_name_i2c(clk_name, sizeof(clk_name), @@ -2516,7 +2518,7 @@ static int pxa_camera_probe(struct platform_device *pdev) clk_name, NULL); if (IS_ERR(pcdev->mclk_clk)) { err = PTR_ERR(pcdev->mclk_clk); - goto exit_free_v4l2dev; + goto exit_notifier_cleanup; } } @@ -2527,6 +2529,8 @@ static int pxa_camera_probe(struct platform_device *pdev) return 0; exit_free_clk: v4l2_clk_unregister(pcdev->mclk_clk); +exit_notifier_cleanup: + v4l2_async_notifier_cleanup(&pcdev->notifier); exit_free_v4l2dev: v4l2_device_unregister(&pcdev->v4l2_dev); exit_deactivate: @@ -2550,6 +2554,7 @@ static int pxa_camera_remove(struct platform_device *pdev) dma_release_channel(pcdev->dma_chans[2]); v4l2_async_notifier_unregister(&pcdev->notifier); + v4l2_async_notifier_cleanup(&pcdev->notifier); if (pcdev->mclk_clk) { v4l2_clk_unregister(pcdev->mclk_clk); diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c index c9bb0d023db4..58aebe7114cd 100644 --- a/drivers/media/platform/qcom/camss/camss-video.c +++ b/drivers/media/platform/qcom/camss/camss-video.c @@ -521,8 +521,8 @@ static int video_querycap(struct file *file, void *fh, { struct camss_video *video = video_drvdata(file); - strlcpy(cap->driver, "qcom-camss", sizeof(cap->driver)); - strlcpy(cap->card, "Qualcomm Camera Subsystem", sizeof(cap->card)); + strscpy(cap->driver, "qcom-camss", sizeof(cap->driver)); + strscpy(cap->card, "Qualcomm Camera Subsystem", sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(video->camss->dev)); @@ -683,7 +683,7 @@ static int video_enum_input(struct file *file, void *fh, if (input->index > 0) return -EINVAL; - strlcpy(input->name, "camera", sizeof(input->name)); + strscpy(input->name, "camera", sizeof(input->name)); input->type = V4L2_INPUT_TYPE_CAMERA; return 0; @@ -919,7 +919,7 @@ int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev, vdev->vfl_dir = VFL_DIR_RX; vdev->queue = &video->vb2_q; vdev->lock = &video->lock; - strlcpy(vdev->name, name, sizeof(vdev->name)); + strscpy(vdev->name, name, sizeof(vdev->name)); ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); if (ret < 0) { diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 669615fff6a0..45978db3b0be 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -462,61 +462,51 @@ static int camss_of_parse_endpoint_node(struct device *dev, * * Return number of "port" nodes found in "ports" node */ -static int camss_of_parse_ports(struct device *dev, - struct v4l2_async_notifier *notifier) +static int camss_of_parse_ports(struct camss *camss) { + struct device *dev = camss->dev; struct device_node *node = NULL; struct device_node *remote = NULL; - unsigned int size, i; - int ret; - - while ((node = of_graph_get_next_endpoint(dev->of_node, node))) - if (of_device_is_available(node)) - notifier->num_subdevs++; - - of_node_put(node); - size = sizeof(*notifier->subdevs) * notifier->num_subdevs; - notifier->subdevs = devm_kzalloc(dev, size, GFP_KERNEL); - if (!notifier->subdevs) { - dev_err(dev, "Failed to allocate memory\n"); - return -ENOMEM; - } + int ret, num_subdevs = 0; - i = 0; - while ((node = of_graph_get_next_endpoint(dev->of_node, node))) { + for_each_endpoint_of_node(dev->of_node, node) { struct camss_async_subdev *csd; + struct v4l2_async_subdev *asd; if (!of_device_is_available(node)) continue; - csd = devm_kzalloc(dev, sizeof(*csd), GFP_KERNEL); - if (!csd) { - of_node_put(node); - dev_err(dev, "Failed to allocate memory\n"); - return -ENOMEM; - } - - notifier->subdevs[i++] = &csd->asd; - - ret = camss_of_parse_endpoint_node(dev, node, csd); - if (ret < 0) { - of_node_put(node); - return ret; - } - remote = of_graph_get_remote_port_parent(node); if (!remote) { dev_err(dev, "Cannot get remote parent\n"); - of_node_put(node); - return -EINVAL; + ret = -EINVAL; + goto err_cleanup; } - csd->asd.match_type = V4L2_ASYNC_MATCH_FWNODE; - csd->asd.match.fwnode = of_fwnode_handle(remote); + asd = v4l2_async_notifier_add_fwnode_subdev( + &camss->notifier, of_fwnode_handle(remote), + sizeof(*csd)); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); + of_node_put(remote); + goto err_cleanup; + } + + csd = container_of(asd, struct camss_async_subdev, asd); + + ret = camss_of_parse_endpoint_node(dev, node, csd); + if (ret < 0) + goto err_cleanup; + + num_subdevs++; } - of_node_put(node); - return notifier->num_subdevs; + return num_subdevs; + +err_cleanup: + v4l2_async_notifier_cleanup(&camss->notifier); + of_node_put(node); + return ret; } /* @@ -823,7 +813,7 @@ static int camss_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct camss *camss; - int ret; + int num_subdevs, ret; camss = kzalloc(sizeof(*camss), GFP_KERNEL); if (!camss) @@ -863,20 +853,22 @@ static int camss_probe(struct platform_device *pdev) if (!camss->vfe) return -ENOMEM; - ret = camss_of_parse_ports(dev, &camss->notifier); - if (ret < 0) - return ret; + v4l2_async_notifier_init(&camss->notifier); + + num_subdevs = camss_of_parse_ports(camss); + if (num_subdevs < 0) + return num_subdevs; ret = camss_init_subdevices(camss); if (ret < 0) - return ret; + goto err_cleanup; ret = dma_set_mask_and_coherent(dev, 0xffffffff); if (ret) - return ret; + goto err_cleanup; camss->media_dev.dev = camss->dev; - strlcpy(camss->media_dev.model, "Qualcomm Camera Subsystem", + strscpy(camss->media_dev.model, "Qualcomm Camera Subsystem", sizeof(camss->media_dev.model)); camss->media_dev.ops = &camss_media_ops; media_device_init(&camss->media_dev); @@ -885,14 +877,14 @@ static int camss_probe(struct platform_device *pdev) ret = v4l2_device_register(camss->dev, &camss->v4l2_dev); if (ret < 0) { dev_err(dev, "Failed to register V4L2 device: %d\n", ret); - return ret; + goto err_cleanup; } ret = camss_register_entities(camss); if (ret < 0) goto err_register_entities; - if (camss->notifier.num_subdevs) { + if (num_subdevs) { camss->notifier.ops = &camss_subdev_notifier_ops; ret = v4l2_async_notifier_register(&camss->v4l2_dev, @@ -942,6 +934,8 @@ err_register_subdevs: camss_unregister_entities(camss); err_register_entities: v4l2_device_unregister(&camss->v4l2_dev); +err_cleanup: + v4l2_async_notifier_cleanup(&camss->notifier); return ret; } @@ -978,6 +972,7 @@ static int camss_remove(struct platform_device *pdev) msm_vfe_stop_streaming(&camss->vfe[i]); v4l2_async_notifier_unregister(&camss->notifier); + v4l2_async_notifier_cleanup(&camss->notifier); camss_unregister_entities(camss); if (atomic_read(&camss->ref_count) == 0) diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h index 418996d8dad8..57b269ca93fd 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -17,7 +17,6 @@ #include <media/v4l2-subdev.h> #include <media/media-device.h> #include <media/media-entity.h> -#include <linux/device.h> #include "camss-csid.h" #include "camss-csiphy.h" @@ -92,8 +91,8 @@ struct camss_camera_interface { }; struct camss_async_subdev { + struct v4l2_async_subdev asd; /* must be first */ struct camss_camera_interface interface; - struct v4l2_async_subdev asd; }; struct camss_clock { diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index cd3b96e6f24b..e436385bc5ab 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -472,7 +472,7 @@ static bool is_dynamic_bufmode(struct venus_inst *inst) caps = venus_caps_by_codec(core, inst->hfi_codec, inst->session_type); if (!caps) - return 0; + return false; return caps->cap_bufs_mode_dynamic; } diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index dfbbbf0f746f..189ec975c6bb 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -341,9 +341,9 @@ vdec_g_selection(struct file *file, void *fh, struct v4l2_selection *s) static int vdec_querycap(struct file *file, void *fh, struct v4l2_capability *cap) { - strlcpy(cap->driver, "qcom-venus", sizeof(cap->driver)); - strlcpy(cap->card, "Qualcomm Venus video decoder", sizeof(cap->card)); - strlcpy(cap->bus_info, "platform:qcom-venus", sizeof(cap->bus_info)); + strscpy(cap->driver, "qcom-venus", sizeof(cap->driver)); + strscpy(cap->card, "Qualcomm Venus video decoder", sizeof(cap->card)); + strscpy(cap->bus_info, "platform:qcom-venus", sizeof(cap->bus_info)); return 0; } @@ -888,8 +888,7 @@ static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type, unsigned int opb_sz = venus_helper_get_opb_size(inst); vb = &vbuf->vb2_buf; - vb->planes[0].bytesused = - max_t(unsigned int, opb_sz, bytesused); + vb2_set_plane_payload(vb, 0, bytesused ? : opb_sz); vb->planes[0].data_offset = data_offset; vb->timestamp = timestamp_us * NSEC_PER_USEC; vbuf->sequence = inst->sequence_cap++; @@ -1153,7 +1152,7 @@ static int vdec_probe(struct platform_device *pdev) if (!vdev) return -ENOMEM; - strlcpy(vdev->name, "qcom-venus-decoder", sizeof(vdev->name)); + strscpy(vdev->name, "qcom-venus-decoder", sizeof(vdev->name)); vdev->release = video_device_release; vdev->fops = &vdec_fops; vdev->ioctl_ops = &vdec_ioctl_ops; diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 41249d1443fa..ce85962b6adc 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -273,9 +273,9 @@ static int venc_v4l2_to_hfi(int id, int value) static int venc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) { - strlcpy(cap->driver, "qcom-venus", sizeof(cap->driver)); - strlcpy(cap->card, "Qualcomm Venus video encoder", sizeof(cap->card)); - strlcpy(cap->bus_info, "platform:qcom-venus", sizeof(cap->bus_info)); + strscpy(cap->driver, "qcom-venus", sizeof(cap->driver)); + strscpy(cap->card, "Qualcomm Venus video encoder", sizeof(cap->card)); + strscpy(cap->bus_info, "platform:qcom-venus", sizeof(cap->bus_info)); return 0; } @@ -1257,7 +1257,7 @@ static int venc_probe(struct platform_device *pdev) if (!vdev) return -ENOMEM; - strlcpy(vdev->name, "qcom-venus-encoder", sizeof(vdev->name)); + strscpy(vdev->name, "qcom-venus-encoder", sizeof(vdev->name)); vdev->release = video_device_release; vdev->fops = &venc_fops; vdev->ioctl_ops = &venc_ioctl_ops; diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index ce09799976ef..a3f135364474 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -170,7 +170,6 @@ static int rvin_group_link_notify(struct media_link *link, u32 flags, if (csi_id == -ENODEV) { struct v4l2_subdev *sd; - unsigned int i; /* * Make sure the source entity subdevice is registered as @@ -268,8 +267,8 @@ static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin) match = of_match_node(vin->dev->driver->of_match_table, vin->dev->of_node); - strlcpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name)); - strlcpy(mdev->model, match->compatible, sizeof(mdev->model)); + strscpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name)); + strscpy(mdev->model, match->compatible, sizeof(mdev->model)); snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s", dev_name(mdev->dev)); @@ -611,6 +610,8 @@ static int rvin_parallel_init(struct rvin_dev *vin) { int ret; + v4l2_async_notifier_init(&vin->notifier); + ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port( vin->dev, &vin->notifier, sizeof(struct rvin_parallel_entity), 0, rvin_parallel_parse_v4l2); @@ -803,6 +804,8 @@ static int rvin_mc_parse_of_graph(struct rvin_dev *vin) return 0; } + v4l2_async_notifier_init(&vin->group->notifier); + /* * Have all VIN's look for CSI-2 subdevices. Some subdevices will * overlap but the parser function can handle it, so each subdevice @@ -824,7 +827,7 @@ static int rvin_mc_parse_of_graph(struct rvin_dev *vin) mutex_unlock(&vin->group->lock); - if (!vin->group->notifier.num_subdevs) + if (list_empty(&vin->group->notifier.asd_list)) return 0; vin->group->notifier.ops = &rvin_group_notify_ops; diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c index dc5ae8025832..b0044a08e71e 100644 --- a/drivers/media/platform/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c @@ -714,7 +714,7 @@ static int rcsi2_parse_v4l2(struct rcar_csi2 *priv, if (vep->base.port || vep->base.id) return -ENOTCONN; - if (vep->bus_type != V4L2_MBUS_CSI2) { + if (vep->bus_type != V4L2_MBUS_CSI2_DPHY) { dev_err(priv->dev, "Unsupported bus: %u\n", vep->bus_type); return -EINVAL; } @@ -743,7 +743,7 @@ static int rcsi2_parse_v4l2(struct rcar_csi2 *priv, static int rcsi2_parse_dt(struct rcar_csi2 *priv) { struct device_node *ep; - struct v4l2_fwnode_endpoint v4l2_ep; + struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 }; int ret; ep = of_graph_get_endpoint_by_regs(priv->dev->of_node, 0, 0); @@ -771,21 +771,25 @@ static int rcsi2_parse_dt(struct rcar_csi2 *priv) of_node_put(ep); - priv->notifier.subdevs = devm_kzalloc(priv->dev, - sizeof(*priv->notifier.subdevs), - GFP_KERNEL); - if (!priv->notifier.subdevs) - return -ENOMEM; + v4l2_async_notifier_init(&priv->notifier); + + ret = v4l2_async_notifier_add_subdev(&priv->notifier, &priv->asd); + if (ret) { + fwnode_handle_put(priv->asd.match.fwnode); + return ret; + } - priv->notifier.num_subdevs = 1; - priv->notifier.subdevs[0] = &priv->asd; priv->notifier.ops = &rcar_csi2_notify_ops; dev_dbg(priv->dev, "Found '%pOF'\n", to_of_node(priv->asd.match.fwnode)); - return v4l2_async_subdev_notifier_register(&priv->subdev, - &priv->notifier); + ret = v4l2_async_subdev_notifier_register(&priv->subdev, + &priv->notifier); + if (ret) + v4l2_async_notifier_cleanup(&priv->notifier); + + return ret; } /* ----------------------------------------------------------------------------- diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 5a54779cfc27..dc77682b4785 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -238,8 +238,8 @@ static int rvin_querycap(struct file *file, void *priv, { struct rvin_dev *vin = video_drvdata(file); - strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver)); - strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card)); + strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver)); + strscpy(cap->card, "R_Car_VIN", sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(vin->dev)); return 0; @@ -440,7 +440,7 @@ static int rvin_enum_input(struct file *file, void *priv, i->std = vin->vdev.tvnorms; } - strlcpy(i->name, "Camera", sizeof(i->name)); + strscpy(i->name, "Camera", sizeof(i->name)); return 0; } @@ -714,7 +714,7 @@ static int rvin_mc_enum_input(struct file *file, void *priv, return -EINVAL; i->type = V4L2_INPUT_TYPE_CAMERA; - strlcpy(i->name, "Camera", sizeof(i->name)); + strscpy(i->name, "Camera", sizeof(i->name)); return 0; } diff --git a/drivers/media/platform/rcar_drif.c b/drivers/media/platform/rcar_drif.c index 81413ab52475..8483dc36715d 100644 --- a/drivers/media/platform/rcar_drif.c +++ b/drivers/media/platform/rcar_drif.c @@ -870,8 +870,8 @@ static int rcar_drif_querycap(struct file *file, void *fh, { struct rcar_drif_sdr *sdr = video_drvdata(file); - strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver)); - strlcpy(cap->card, sdr->vdev->name, sizeof(cap->card)); + strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver)); + strscpy(cap->card, sdr->vdev->name, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", sdr->vdev->name); @@ -1213,18 +1213,15 @@ static int rcar_drif_parse_subdevs(struct rcar_drif_sdr *sdr) { struct v4l2_async_notifier *notifier = &sdr->notifier; struct fwnode_handle *fwnode, *ep; + int ret; - notifier->subdevs = devm_kzalloc(sdr->dev, sizeof(*notifier->subdevs), - GFP_KERNEL); - if (!notifier->subdevs) - return -ENOMEM; + v4l2_async_notifier_init(notifier); ep = fwnode_graph_get_next_endpoint(of_fwnode_handle(sdr->dev->of_node), NULL); if (!ep) return 0; - notifier->subdevs[notifier->num_subdevs] = &sdr->ep.asd; fwnode = fwnode_graph_get_remote_port_parent(ep); if (!fwnode) { dev_warn(sdr->dev, "bad remote port parent\n"); @@ -1234,7 +1231,11 @@ static int rcar_drif_parse_subdevs(struct rcar_drif_sdr *sdr) sdr->ep.asd.match.fwnode = fwnode; sdr->ep.asd.match_type = V4L2_ASYNC_MATCH_FWNODE; - notifier->num_subdevs++; + ret = v4l2_async_notifier_add_subdev(notifier, &sdr->ep.asd); + if (ret) { + fwnode_handle_put(fwnode); + return ret; + } /* Get the endpoint properties */ rcar_drif_get_ep_properties(sdr, ep); @@ -1356,11 +1357,13 @@ static int rcar_drif_sdr_probe(struct rcar_drif_sdr *sdr) ret = v4l2_async_notifier_register(&sdr->v4l2_dev, &sdr->notifier); if (ret < 0) { dev_err(sdr->dev, "failed: notifier register ret %d\n", ret); - goto error; + goto cleanup; } return ret; +cleanup: + v4l2_async_notifier_cleanup(&sdr->notifier); error: v4l2_device_unregister(&sdr->v4l2_dev); @@ -1371,6 +1374,7 @@ error: static void rcar_drif_sdr_remove(struct rcar_drif_sdr *sdr) { v4l2_async_notifier_unregister(&sdr->notifier); + v4l2_async_notifier_cleanup(&sdr->notifier); v4l2_device_unregister(&sdr->v4l2_dev); } diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c index 2a15b7cca338..6bda1eee9170 100644 --- a/drivers/media/platform/rcar_fdp1.c +++ b/drivers/media/platform/rcar_fdp1.c @@ -1359,8 +1359,8 @@ static void device_frame_end(struct fdp1_dev *fdp1, static int fdp1_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - strlcpy(cap->driver, DRIVER_NAME, sizeof(cap->driver)); - strlcpy(cap->card, DRIVER_NAME, sizeof(cap->card)); + strscpy(cap->driver, DRIVER_NAME, sizeof(cap->driver)); + strscpy(cap->card, DRIVER_NAME, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", DRIVER_NAME); return 0; @@ -2339,7 +2339,7 @@ static int fdp1_probe(struct platform_device *pdev) vfd->lock = &fdp1->dev_mutex; vfd->v4l2_dev = &fdp1->v4l2_dev; video_set_drvdata(vfd, fdp1); - strlcpy(vfd->name, fdp1_videodev.name, sizeof(vfd->name)); + strscpy(vfd->name, fdp1_videodev.name, sizeof(vfd->name)); ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); if (ret) { diff --git a/drivers/media/platform/rcar_jpu.c b/drivers/media/platform/rcar_jpu.c index e5c882423f57..1dfd2eb65920 100644 --- a/drivers/media/platform/rcar_jpu.c +++ b/drivers/media/platform/rcar_jpu.c @@ -664,11 +664,11 @@ static int jpu_querycap(struct file *file, void *priv, struct jpu_ctx *ctx = fh_to_ctx(priv); if (ctx->encoder) - strlcpy(cap->card, DRV_NAME " encoder", sizeof(cap->card)); + strscpy(cap->card, DRV_NAME " encoder", sizeof(cap->card)); else - strlcpy(cap->card, DRV_NAME " decoder", sizeof(cap->card)); + strscpy(cap->card, DRV_NAME " decoder", sizeof(cap->card)); - strlcpy(cap->driver, DRV_NAME, sizeof(cap->driver)); + strscpy(cap->driver, DRV_NAME, sizeof(cap->driver)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(ctx->jpu->dev)); cap->device_caps |= V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE; @@ -1654,7 +1654,7 @@ static int jpu_probe(struct platform_device *pdev) for (i = 0; i < JPU_MAX_QUALITY; i++) jpu_generate_hdr(i, (unsigned char *)jpeg_hdrs[i]); - strlcpy(jpu->vfd_encoder.name, DRV_NAME, sizeof(jpu->vfd_encoder.name)); + strscpy(jpu->vfd_encoder.name, DRV_NAME, sizeof(jpu->vfd_encoder.name)); jpu->vfd_encoder.fops = &jpu_fops; jpu->vfd_encoder.ioctl_ops = &jpu_ioctl_ops; jpu->vfd_encoder.minor = -1; @@ -1671,7 +1671,7 @@ static int jpu_probe(struct platform_device *pdev) video_set_drvdata(&jpu->vfd_encoder, jpu); - strlcpy(jpu->vfd_decoder.name, DRV_NAME, sizeof(jpu->vfd_decoder.name)); + strscpy(jpu->vfd_decoder.name, DRV_NAME, sizeof(jpu->vfd_decoder.name)); jpu->vfd_decoder.fops = &jpu_fops; jpu->vfd_decoder.ioctl_ops = &jpu_ioctl_ops; jpu->vfd_decoder.minor = -1; diff --git a/drivers/media/platform/renesas-ceu.c b/drivers/media/platform/renesas-ceu.c index ad782901cd7a..150196f7cf96 100644 --- a/drivers/media/platform/renesas-ceu.c +++ b/drivers/media/platform/renesas-ceu.c @@ -189,8 +189,6 @@ struct ceu_device { /* async subdev notification helpers */ struct v4l2_async_notifier notifier; - /* pointers to "struct ceu_subdevice -> asd" */ - struct v4l2_async_subdev **asds; /* vb2 queue, capture buffer list and active buffer pointer */ struct vb2_queue vb2_vq; @@ -1137,8 +1135,8 @@ static int ceu_querycap(struct file *file, void *priv, { struct ceu_device *ceudev = video_drvdata(file); - strlcpy(cap->card, "Renesas CEU", sizeof(cap->card)); - strlcpy(cap->driver, DRIVER_NAME, sizeof(cap->driver)); + strscpy(cap->card, "Renesas CEU", sizeof(cap->card)); + strscpy(cap->driver, DRIVER_NAME, sizeof(cap->driver)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:renesas-ceu-%s", dev_name(ceudev->dev)); @@ -1440,7 +1438,7 @@ static int ceu_notify_complete(struct v4l2_async_notifier *notifier) return ret; /* Register the video device. */ - strlcpy(vdev->name, DRIVER_NAME, sizeof(vdev->name)); + strscpy(vdev->name, DRIVER_NAME, sizeof(vdev->name)); vdev->v4l2_dev = v4l2_dev; vdev->lock = &ceudev->mlock; vdev->queue = &ceudev->vb2_vq; @@ -1482,15 +1480,6 @@ static int ceu_init_async_subdevs(struct ceu_device *ceudev, unsigned int n_sd) if (!ceudev->subdevs) return -ENOMEM; - /* - * Reserve memory for 'n_sd' pointers to async_subdevices. - * ceudev->asds members will point to &ceu_subdev.asd - */ - ceudev->asds = devm_kcalloc(ceudev->dev, n_sd, - sizeof(*ceudev->asds), GFP_KERNEL); - if (!ceudev->asds) - return -ENOMEM; - ceudev->sd = NULL; ceudev->sd_index = 0; ceudev->num_sd = 0; @@ -1518,6 +1507,7 @@ static int ceu_parse_platform_data(struct ceu_device *ceudev, return ret; for (i = 0; i < pdata->num_subdevs; i++) { + /* Setup the ceu subdevice and the async subdevice. */ async_sd = &pdata->subdevs[i]; ceu_sd = &ceudev->subdevs[i]; @@ -1529,7 +1519,12 @@ static int ceu_parse_platform_data(struct ceu_device *ceudev, ceu_sd->asd.match.i2c.adapter_id = async_sd->i2c_adapter_id; ceu_sd->asd.match.i2c.address = async_sd->i2c_address; - ceudev->asds[i] = &ceu_sd->asd; + ret = v4l2_async_notifier_add_subdev(&ceudev->notifier, + &ceu_sd->asd); + if (ret) { + v4l2_async_notifier_cleanup(&ceudev->notifier); + return ret; + } } return pdata->num_subdevs; @@ -1541,9 +1536,8 @@ static int ceu_parse_platform_data(struct ceu_device *ceudev, static int ceu_parse_dt(struct ceu_device *ceudev) { struct device_node *of = ceudev->dev->of_node; - struct v4l2_fwnode_endpoint fw_ep; + struct device_node *ep, *remote; struct ceu_subdev *ceu_sd; - struct device_node *ep; unsigned int i; int num_ep; int ret; @@ -1557,45 +1551,55 @@ static int ceu_parse_dt(struct ceu_device *ceudev) return ret; for (i = 0; i < num_ep; i++) { + struct v4l2_fwnode_endpoint fw_ep = { + .bus_type = V4L2_MBUS_PARALLEL, + .bus = { + .parallel = { + .flags = V4L2_MBUS_HSYNC_ACTIVE_HIGH | + V4L2_MBUS_VSYNC_ACTIVE_HIGH, + .bus_width = 8, + }, + }, + }; + ep = of_graph_get_endpoint_by_regs(of, 0, i); if (!ep) { dev_err(ceudev->dev, "No subdevice connected on endpoint %u.\n", i); ret = -ENODEV; - goto error_put_node; + goto error_cleanup; } ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &fw_ep); if (ret) { dev_err(ceudev->dev, - "Unable to parse endpoint #%u.\n", i); - goto error_put_node; - } - - if (fw_ep.bus_type != V4L2_MBUS_PARALLEL) { - dev_err(ceudev->dev, - "Only parallel input supported.\n"); - ret = -EINVAL; - goto error_put_node; + "Unable to parse endpoint #%u: %d.\n", i, ret); + goto error_cleanup; } /* Setup the ceu subdevice and the async subdevice. */ ceu_sd = &ceudev->subdevs[i]; INIT_LIST_HEAD(&ceu_sd->asd.list); + remote = of_graph_get_remote_port_parent(ep); ceu_sd->mbus_flags = fw_ep.bus.parallel.flags; ceu_sd->asd.match_type = V4L2_ASYNC_MATCH_FWNODE; - ceu_sd->asd.match.fwnode = - fwnode_graph_get_remote_port_parent( - of_fwnode_handle(ep)); + ceu_sd->asd.match.fwnode = of_fwnode_handle(remote); + + ret = v4l2_async_notifier_add_subdev(&ceudev->notifier, + &ceu_sd->asd); + if (ret) { + of_node_put(remote); + goto error_cleanup; + } - ceudev->asds[i] = &ceu_sd->asd; of_node_put(ep); } return num_ep; -error_put_node: +error_cleanup: + v4l2_async_notifier_cleanup(&ceudev->notifier); of_node_put(ep); return ret; } @@ -1674,6 +1678,8 @@ static int ceu_probe(struct platform_device *pdev) if (ret) goto error_pm_disable; + v4l2_async_notifier_init(&ceudev->notifier); + if (IS_ENABLED(CONFIG_OF) && dev->of_node) { ceu_data = of_match_device(ceu_of_match, dev)->data; num_subdevs = ceu_parse_dt(ceudev); @@ -1693,18 +1699,18 @@ static int ceu_probe(struct platform_device *pdev) ceudev->irq_mask = ceu_data->irq_mask; ceudev->notifier.v4l2_dev = &ceudev->v4l2_dev; - ceudev->notifier.subdevs = ceudev->asds; - ceudev->notifier.num_subdevs = num_subdevs; ceudev->notifier.ops = &ceu_notify_ops; ret = v4l2_async_notifier_register(&ceudev->v4l2_dev, &ceudev->notifier); if (ret) - goto error_v4l2_unregister; + goto error_cleanup; dev_info(dev, "Renesas Capture Engine Unit %s\n", dev_name(dev)); return 0; +error_cleanup: + v4l2_async_notifier_cleanup(&ceudev->notifier); error_v4l2_unregister: v4l2_device_unregister(&ceudev->v4l2_dev); error_pm_disable: @@ -1723,6 +1729,8 @@ static int ceu_remove(struct platform_device *pdev) v4l2_async_notifier_unregister(&ceudev->notifier); + v4l2_async_notifier_cleanup(&ceudev->notifier); + v4l2_device_unregister(&ceudev->v4l2_dev); video_unregister_device(&ceudev->vdev); diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c index ab5a6f95044a..9cc9db083870 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -447,9 +447,9 @@ static const struct v4l2_file_operations rga_fops = { static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - strlcpy(cap->driver, RGA_NAME, sizeof(cap->driver)); - strlcpy(cap->card, "rockchip-rga", sizeof(cap->card)); - strlcpy(cap->bus_info, "platform:rga", sizeof(cap->bus_info)); + strscpy(cap->driver, RGA_NAME, sizeof(cap->driver)); + strscpy(cap->card, "rockchip-rga", sizeof(cap->card)); + strscpy(cap->bus_info, "platform:rga", sizeof(cap->bus_info)); return 0; } diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c index c02dce8b4c6c..23b008d1a47b 100644 --- a/drivers/media/platform/s3c-camif/camif-capture.c +++ b/drivers/media/platform/s3c-camif/camif-capture.c @@ -640,8 +640,8 @@ static int s3c_camif_vidioc_querycap(struct file *file, void *priv, { struct camif_vp *vp = video_drvdata(file); - strlcpy(cap->driver, S3C_CAMIF_DRIVER_NAME, sizeof(cap->driver)); - strlcpy(cap->card, S3C_CAMIF_DRIVER_NAME, sizeof(cap->card)); + strscpy(cap->driver, S3C_CAMIF_DRIVER_NAME, sizeof(cap->driver)); + strscpy(cap->card, S3C_CAMIF_DRIVER_NAME, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s.%d", dev_name(vp->camif->dev), vp->id); @@ -661,7 +661,7 @@ static int s3c_camif_vidioc_enum_input(struct file *file, void *priv, return -EINVAL; input->type = V4L2_INPUT_TYPE_CAMERA; - strlcpy(input->name, sensor->name, sizeof(input->name)); + strscpy(input->name, sensor->name, sizeof(input->name)); return 0; } @@ -688,7 +688,7 @@ static int s3c_camif_vidioc_enum_fmt(struct file *file, void *priv, if (!fmt) return -EINVAL; - strlcpy(f->description, fmt->name, sizeof(f->description)); + strscpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->fourcc; pr_debug("fmt(%d): %s\n", f->index, f->description); @@ -1555,7 +1555,7 @@ int s3c_camif_create_subdev(struct camif_dev *camif) v4l2_subdev_init(sd, &s3c_camif_subdev_ops); sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - strlcpy(sd->name, "S3C-CAMIF", sizeof(sd->name)); + strscpy(sd->name, "S3C-CAMIF", sizeof(sd->name)); camif->pads[CAMIF_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK; camif->pads[CAMIF_SD_PAD_SOURCE_C].flags = MEDIA_PAD_FL_SOURCE; diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c index 79bc0ef6bb41..31759f16458e 100644 --- a/drivers/media/platform/s3c-camif/camif-core.c +++ b/drivers/media/platform/s3c-camif/camif-core.c @@ -316,12 +316,12 @@ static int camif_media_dev_init(struct camif_dev *camif) memset(md, 0, sizeof(*md)); snprintf(md->model, sizeof(md->model), "SAMSUNG S3C%s CAMIF", ip_rev == S3C6410_CAMIF_IP_REV ? "6410" : "244X"); - strlcpy(md->bus_info, "platform", sizeof(md->bus_info)); + strscpy(md->bus_info, "platform", sizeof(md->bus_info)); md->hw_revision = ip_rev; md->dev = camif->dev; - strlcpy(v4l2_dev->name, "s3c-camif", sizeof(v4l2_dev->name)); + strscpy(v4l2_dev->name, "s3c-camif", sizeof(v4l2_dev->name)); v4l2_dev->mdev = md; media_device_init(md); diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 04fd2e0493c0..3f9000b70385 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -1276,14 +1276,14 @@ static int s5p_jpeg_querycap(struct file *file, void *priv, struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); if (ctx->mode == S5P_JPEG_ENCODE) { - strlcpy(cap->driver, S5P_JPEG_M2M_NAME, + strscpy(cap->driver, S5P_JPEG_M2M_NAME, sizeof(cap->driver)); - strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder", + strscpy(cap->card, S5P_JPEG_M2M_NAME " encoder", sizeof(cap->card)); } else { - strlcpy(cap->driver, S5P_JPEG_M2M_NAME, + strscpy(cap->driver, S5P_JPEG_M2M_NAME, sizeof(cap->driver)); - strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder", + strscpy(cap->card, S5P_JPEG_M2M_NAME " decoder", sizeof(cap->card)); } snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", @@ -1314,7 +1314,7 @@ static int enum_fmt(struct s5p_jpeg_fmt *sjpeg_formats, int n, if (i >= n) return -EINVAL; - strlcpy(f->description, sjpeg_formats[i].name, sizeof(f->description)); + strscpy(f->description, sjpeg_formats[i].name, sizeof(f->description)); f->pixelformat = sjpeg_formats[i].fourcc; return 0; diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index 6a3cc4f86c5d..670ca869babb 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c @@ -271,8 +271,8 @@ static int vidioc_querycap(struct file *file, void *priv, { struct s5p_mfc_dev *dev = video_drvdata(file); - strlcpy(cap->driver, S5P_MFC_NAME, sizeof(cap->driver)); - strlcpy(cap->card, dev->vfd_dec->name, sizeof(cap->card)); + strscpy(cap->driver, S5P_MFC_NAME, sizeof(cap->driver)); + strscpy(cap->card, dev->vfd_dec->name, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(&dev->plat_dev->dev)); /* @@ -308,7 +308,7 @@ static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f, if (i == ARRAY_SIZE(formats)) return -EINVAL; fmt = &formats[i]; - strlcpy(f->description, fmt->name, sizeof(f->description)); + strscpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->fourcc; return 0; } diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index 3ad4f5073002..7037d48bdc2c 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c @@ -1313,8 +1313,8 @@ static int vidioc_querycap(struct file *file, void *priv, { struct s5p_mfc_dev *dev = video_drvdata(file); - strlcpy(cap->driver, S5P_MFC_NAME, sizeof(cap->driver)); - strlcpy(cap->card, dev->vfd_enc->name, sizeof(cap->card)); + strscpy(cap->driver, S5P_MFC_NAME, sizeof(cap->driver)); + strscpy(cap->card, dev->vfd_enc->name, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(&dev->plat_dev->dev)); /* @@ -1344,7 +1344,7 @@ static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f, if (j == f->index) { fmt = &formats[i]; - strlcpy(f->description, fmt->name, + strscpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->fourcc; return 0; diff --git a/drivers/media/platform/sh_veu.c b/drivers/media/platform/sh_veu.c index 1d274c64de09..09ae64a0004c 100644 --- a/drivers/media/platform/sh_veu.c +++ b/drivers/media/platform/sh_veu.c @@ -345,9 +345,9 @@ static int sh_veu_context_init(struct sh_veu_dev *veu) static int sh_veu_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - strlcpy(cap->driver, "sh-veu", sizeof(cap->driver)); - strlcpy(cap->card, "sh-mobile VEU", sizeof(cap->card)); - strlcpy(cap->bus_info, "platform:sh-veu", sizeof(cap->bus_info)); + strscpy(cap->driver, "sh-veu", sizeof(cap->driver)); + strscpy(cap->card, "sh-mobile VEU", sizeof(cap->card)); + strscpy(cap->bus_info, "platform:sh-veu", sizeof(cap->bus_info)); cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; @@ -359,7 +359,8 @@ static int sh_veu_enum_fmt(struct v4l2_fmtdesc *f, const int *fmt, int fmt_num) if (f->index >= fmt_num) return -EINVAL; - strlcpy(f->description, sh_veu_fmt[fmt[f->index]].name, sizeof(f->description)); + strscpy(f->description, sh_veu_fmt[fmt[f->index]].name, + sizeof(f->description)); f->pixelformat = sh_veu_fmt[fmt[f->index]].fourcc; return 0; } diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c index 6135e13e24d4..cee58b125548 100644 --- a/drivers/media/platform/sh_vou.c +++ b/drivers/media/platform/sh_vou.c @@ -378,9 +378,9 @@ static int sh_vou_querycap(struct file *file, void *priv, dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__); - strlcpy(cap->card, "SuperH VOU", sizeof(cap->card)); - strlcpy(cap->driver, "sh-vou", sizeof(cap->driver)); - strlcpy(cap->bus_info, "platform:sh-vou", sizeof(cap->bus_info)); + strscpy(cap->card, "SuperH VOU", sizeof(cap->card)); + strscpy(cap->driver, "sh-vou", sizeof(cap->driver)); + strscpy(cap->bus_info, "platform:sh-vou", sizeof(cap->bus_info)); cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; @@ -399,7 +399,7 @@ static int sh_vou_enum_fmt_vid_out(struct file *file, void *priv, dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__); fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - strlcpy(fmt->description, vou_fmt[fmt->index].desc, + strscpy(fmt->description, vou_fmt[fmt->index].desc, sizeof(fmt->description)); fmt->pixelformat = vou_fmt[fmt->index].pfmt; @@ -790,7 +790,7 @@ static int sh_vou_enum_output(struct file *file, void *fh, if (a->index) return -EINVAL; - strlcpy(a->name, "Video Out", sizeof(a->name)); + strscpy(a->name, "Video Out", sizeof(a->name)); a->type = V4L2_OUTPUT_TYPE_ANALOG; a->std = vou_dev->vdev.tvnorms; return 0; diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 0a2c0daaffef..6803f744e307 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -1564,9 +1564,9 @@ static __poll_t sh_mobile_ceu_poll(struct file *file, poll_table *pt) static int sh_mobile_ceu_querycap(struct soc_camera_host *ici, struct v4l2_capability *cap) { - strlcpy(cap->card, "SuperH_Mobile_CEU", sizeof(cap->card)); - strlcpy(cap->driver, "sh_mobile_ceu", sizeof(cap->driver)); - strlcpy(cap->bus_info, "platform:sh_mobile_ceu", sizeof(cap->bus_info)); + strscpy(cap->card, "SuperH_Mobile_CEU", sizeof(cap->card)); + strscpy(cap->driver, "sh_mobile_ceu", sizeof(cap->driver)); + strscpy(cap->bus_info, "platform:sh_mobile_ceu", sizeof(cap->bus_info)); cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 66d613629167..0a70fb67c401 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -312,7 +312,7 @@ static int soc_camera_enum_input(struct file *file, void *priv, /* default is camera */ inp->type = V4L2_INPUT_TYPE_CAMERA; inp->std = icd->vdev->tvnorms; - strcpy(inp->name, "Camera"); + strscpy(inp->name, "Camera", sizeof(inp->name)); return 0; } @@ -874,7 +874,7 @@ static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv, format = icd->user_formats[f->index].host_fmt; if (format->name) - strlcpy(f->description, format->name, sizeof(f->description)); + strscpy(f->description, format->name, sizeof(f->description)); f->pixelformat = format->fourcc; return 0; } @@ -910,7 +910,7 @@ static int soc_camera_querycap(struct file *file, void *priv, WARN_ON(priv != file->private_data); - strlcpy(cap->driver, ici->drv_name, sizeof(cap->driver)); + strscpy(cap->driver, ici->drv_name, sizeof(cap->driver)); return ici->ops->querycap(ici, cap); } @@ -1442,8 +1442,14 @@ static int scan_async_group(struct soc_camera_host *ici, goto eaddpdev; } - sasc->notifier.subdevs = asd; - sasc->notifier.num_subdevs = size; + v4l2_async_notifier_init(&sasc->notifier); + + for (i = 0; i < size; i++) { + ret = v4l2_async_notifier_add_subdev(&sasc->notifier, asd[i]); + if (ret) + goto eaddasd; + } + sasc->notifier.ops = &soc_camera_async_ops; icd->sasc = sasc; @@ -1466,6 +1472,8 @@ static int scan_async_group(struct soc_camera_host *ici, v4l2_clk_unregister(icd->clk); eclkreg: icd->clk = NULL; +eaddasd: + v4l2_async_notifier_cleanup(&sasc->notifier); platform_device_del(sasc->pdev); eaddpdev: platform_device_put(sasc->pdev); @@ -1540,8 +1548,14 @@ static int soc_of_bind(struct soc_camera_host *ici, goto eaddpdev; } - sasc->notifier.subdevs = &info->subdev; - sasc->notifier.num_subdevs = 1; + v4l2_async_notifier_init(&sasc->notifier); + + ret = v4l2_async_notifier_add_subdev(&sasc->notifier, info->subdev); + if (ret) { + of_node_put(remote); + goto eaddasd; + } + sasc->notifier.ops = &soc_camera_async_ops; icd->sasc = sasc; @@ -1568,6 +1582,8 @@ static int soc_of_bind(struct soc_camera_host *ici, v4l2_clk_unregister(icd->clk); eclkreg: icd->clk = NULL; +eaddasd: + v4l2_async_notifier_cleanup(&sasc->notifier); platform_device_del(sasc->pdev); eaddpdev: platform_device_put(sasc->pdev); @@ -1582,7 +1598,7 @@ static void scan_of_host(struct soc_camera_host *ici) { struct device *dev = ici->v4l2_dev.dev; struct device_node *np = dev->of_node; - struct device_node *epn = NULL, *ren; + struct device_node *epn = NULL, *rem; unsigned int i; for (i = 0; ; i++) { @@ -1590,17 +1606,15 @@ static void scan_of_host(struct soc_camera_host *ici) if (!epn) break; - ren = of_graph_get_remote_port(epn); - if (!ren) { + rem = of_graph_get_remote_port_parent(epn); + if (!rem) { dev_notice(dev, "no remote for %pOF\n", epn); continue; } /* so we now have a remote node to connect */ if (!i) - soc_of_bind(ici, epn, ren->parent); - - of_node_put(ren); + soc_of_bind(ici, epn, rem); if (i) { dev_err(dev, "multiple subdevices aren't supported yet!\n"); @@ -1926,6 +1940,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici) list_for_each_entry(sasc, ¬ifiers, list) { /* Must call unlocked to avoid AB-BA dead-lock */ v4l2_async_notifier_unregister(&sasc->notifier); + v4l2_async_notifier_cleanup(&sasc->notifier); put_device(&sasc->pdev->dev); } @@ -2026,7 +2041,7 @@ static int video_dev_create(struct soc_camera_device *icd) if (!vdev) return -ENOMEM; - strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); + strscpy(vdev->name, ici->drv_name, sizeof(vdev->name)); vdev->v4l2_dev = &ici->v4l2_dev; vdev->fops = &soc_camera_fops; diff --git a/drivers/media/platform/soc_camera/soc_camera_platform.c b/drivers/media/platform/soc_camera/soc_camera_platform.c index 6745a6e3f464..79fbe1fea95f 100644 --- a/drivers/media/platform/soc_camera/soc_camera_platform.c +++ b/drivers/media/platform/soc_camera/soc_camera_platform.c @@ -156,7 +156,7 @@ static int soc_camera_platform_probe(struct platform_device *pdev) v4l2_subdev_init(&priv->subdev, &platform_subdev_ops); v4l2_set_subdevdata(&priv->subdev, p); - strlcpy(priv->subdev.name, dev_name(&pdev->dev), + strscpy(priv->subdev.name, dev_name(&pdev->dev), sizeof(priv->subdev.name)); return v4l2_device_register_subdev(&ici->v4l2_dev, &priv->subdev); diff --git a/drivers/media/platform/soc_camera/soc_mediabus.c b/drivers/media/platform/soc_camera/soc_mediabus.c index 0ad4b28266e4..be74008ec0ca 100644 --- a/drivers/media/platform/soc_camera/soc_mediabus.c +++ b/drivers/media/platform/soc_camera/soc_mediabus.c @@ -503,7 +503,7 @@ unsigned int soc_mbus_config_compatible(const struct v4l2_mbus_config *cfg, mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE); return (!hsync || !vsync || !pclk || !data || !mode) ? 0 : common_flags; - case V4L2_MBUS_CSI2: + case V4L2_MBUS_CSI2_DPHY: mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES; mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK | V4L2_MBUS_CSI2_CONTINUOUS_CLOCK); diff --git a/drivers/media/platform/soc_camera/soc_scale_crop.c b/drivers/media/platform/soc_camera/soc_scale_crop.c index 6164102e6f9f..8d25ca0490f7 100644 --- a/drivers/media/platform/soc_camera/soc_scale_crop.c +++ b/drivers/media/platform/soc_camera/soc_scale_crop.c @@ -52,7 +52,7 @@ int soc_camera_client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect) return ret; } - sdsel.target = V4L2_SEL_TGT_CROP_DEFAULT; + sdsel.target = V4L2_SEL_TGT_CROP_BOUNDS; ret = v4l2_subdev_call(sd, pad, get_selection, NULL, &sdsel); if (!ret) *rect = sdsel.r; diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c index 66b64096f5de..79f7db1a9d18 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c +++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c @@ -688,8 +688,8 @@ static int bdisp_querycap(struct file *file, void *fh, struct bdisp_ctx *ctx = fh_to_ctx(fh); struct bdisp_dev *bdisp = ctx->bdisp_dev; - strlcpy(cap->driver, bdisp->pdev->name, sizeof(cap->driver)); - strlcpy(cap->card, bdisp->pdev->name, sizeof(cap->card)); + strscpy(cap->driver, bdisp->pdev->name, sizeof(cap->driver)); + strscpy(cap->card, bdisp->pdev->name, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s%d", BDISP_NAME, bdisp->id); diff --git a/drivers/media/platform/sti/delta/delta-v4l2.c b/drivers/media/platform/sti/delta/delta-v4l2.c index 0b42acd4e3a6..91369fb3ffaa 100644 --- a/drivers/media/platform/sti/delta/delta-v4l2.c +++ b/drivers/media/platform/sti/delta/delta-v4l2.c @@ -385,8 +385,8 @@ static int delta_querycap(struct file *file, void *priv, struct delta_ctx *ctx = to_ctx(file->private_data); struct delta_dev *delta = ctx->dev; - strlcpy(cap->driver, DELTA_NAME, sizeof(cap->driver)); - strlcpy(cap->card, delta->vdev->name, sizeof(cap->card)); + strscpy(cap->driver, DELTA_NAME, sizeof(cap->driver)); + strscpy(cap->card, delta->vdev->name, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", delta->pdev->name); diff --git a/drivers/media/platform/sti/hva/hva-v4l2.c b/drivers/media/platform/sti/hva/hva-v4l2.c index 5a807c7c5e79..c42623dccfd6 100644 --- a/drivers/media/platform/sti/hva/hva-v4l2.c +++ b/drivers/media/platform/sti/hva/hva-v4l2.c @@ -257,8 +257,8 @@ static int hva_querycap(struct file *file, void *priv, struct hva_ctx *ctx = fh_to_ctx(file->private_data); struct hva_dev *hva = ctx_to_hdev(ctx); - strlcpy(cap->driver, HVA_NAME, sizeof(cap->driver)); - strlcpy(cap->card, hva->vdev->name, sizeof(cap->card)); + strscpy(cap->driver, HVA_NAME, sizeof(cap->driver)); + strscpy(cap->card, hva->vdev->name, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", hva->pdev->name); diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index 721564176d8c..6732874114cf 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -659,7 +659,10 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) } /* Enable interruptions */ - reg_set(dcmi->regs, DCMI_IER, IT_FRAME | IT_OVR | IT_ERR); + if (dcmi->sd_format->fourcc == V4L2_PIX_FMT_JPEG) + reg_set(dcmi->regs, DCMI_IER, IT_FRAME | IT_OVR | IT_ERR); + else + reg_set(dcmi->regs, DCMI_IER, IT_OVR | IT_ERR); return 0; @@ -1147,10 +1150,10 @@ static int dcmi_s_selection(struct file *file, void *priv, static int dcmi_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - strlcpy(cap->driver, DRV_NAME, sizeof(cap->driver)); - strlcpy(cap->card, "STM32 Camera Memory Interface", + strscpy(cap->driver, DRV_NAME, sizeof(cap->driver)); + strscpy(cap->card, "STM32 Camera Memory Interface", sizeof(cap->card)); - strlcpy(cap->bus_info, "platform:dcmi", sizeof(cap->bus_info)); + strscpy(cap->bus_info, "platform:dcmi", sizeof(cap->bus_info)); return 0; } @@ -1161,7 +1164,7 @@ static int dcmi_enum_input(struct file *file, void *priv, return -EINVAL; i->type = V4L2_INPUT_TYPE_CAMERA; - strlcpy(i->name, "Camera", sizeof(i->name)); + strscpy(i->name, "Camera", sizeof(i->name)); return 0; } @@ -1587,7 +1590,6 @@ static int dcmi_graph_parse(struct stm32_dcmi *dcmi, struct device_node *node) static int dcmi_graph_init(struct stm32_dcmi *dcmi) { - struct v4l2_async_subdev **subdevs = NULL; int ret; /* Parse the graph to extract a list of subdevice DT nodes. */ @@ -1597,23 +1599,21 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi) return ret; } - /* Register the subdevices notifier. */ - subdevs = devm_kzalloc(dcmi->dev, sizeof(*subdevs), GFP_KERNEL); - if (!subdevs) { + v4l2_async_notifier_init(&dcmi->notifier); + + ret = v4l2_async_notifier_add_subdev(&dcmi->notifier, + &dcmi->entity.asd); + if (ret) { of_node_put(dcmi->entity.node); - return -ENOMEM; + return ret; } - subdevs[0] = &dcmi->entity.asd; - - dcmi->notifier.subdevs = subdevs; - dcmi->notifier.num_subdevs = 1; dcmi->notifier.ops = &dcmi_graph_notify_ops; ret = v4l2_async_notifier_register(&dcmi->v4l2_dev, &dcmi->notifier); if (ret < 0) { dev_err(dcmi->dev, "Notifier registration failed\n"); - of_node_put(dcmi->entity.node); + v4l2_async_notifier_cleanup(&dcmi->notifier); return ret; } @@ -1624,7 +1624,7 @@ static int dcmi_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; const struct of_device_id *match = NULL; - struct v4l2_fwnode_endpoint ep; + struct v4l2_fwnode_endpoint ep = { .bus_type = 0 }; struct stm32_dcmi *dcmi; struct vb2_queue *q; struct dma_chan *chan; @@ -1663,7 +1663,7 @@ static int dcmi_probe(struct platform_device *pdev) return -ENODEV; } - if (ep.bus_type == V4L2_MBUS_CSI2) { + if (ep.bus_type == V4L2_MBUS_CSI2_DPHY) { dev_err(&pdev->dev, "CSI bus not supported\n"); return -ENODEV; } @@ -1736,7 +1736,7 @@ static int dcmi_probe(struct platform_device *pdev) dcmi->vdev->fops = &dcmi_fops; dcmi->vdev->v4l2_dev = &dcmi->v4l2_dev; dcmi->vdev->queue = &dcmi->queue; - strlcpy(dcmi->vdev->name, KBUILD_MODNAME, sizeof(dcmi->vdev->name)); + strscpy(dcmi->vdev->name, KBUILD_MODNAME, sizeof(dcmi->vdev->name)); dcmi->vdev->release = video_device_release; dcmi->vdev->ioctl_ops = &dcmi_ioctl_ops; dcmi->vdev->lock = &dcmi->lock; @@ -1770,7 +1770,7 @@ static int dcmi_probe(struct platform_device *pdev) ret = reset_control_assert(dcmi->rstc); if (ret) { dev_err(&pdev->dev, "Failed to assert the reset line\n"); - goto err_device_release; + goto err_cleanup; } usleep_range(3000, 5000); @@ -1778,7 +1778,7 @@ static int dcmi_probe(struct platform_device *pdev) ret = reset_control_deassert(dcmi->rstc); if (ret) { dev_err(&pdev->dev, "Failed to deassert the reset line\n"); - goto err_device_release; + goto err_cleanup; } dev_info(&pdev->dev, "Probe done\n"); @@ -1789,6 +1789,8 @@ static int dcmi_probe(struct platform_device *pdev) return 0; +err_cleanup: + v4l2_async_notifier_cleanup(&dcmi->notifier); err_device_release: video_device_release(dcmi->vdev); err_device_unregister: @@ -1806,6 +1808,7 @@ static int dcmi_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); v4l2_async_notifier_unregister(&dcmi->notifier); + v4l2_async_notifier_cleanup(&dcmi->notifier); v4l2_device_unregister(&dcmi->v4l2_dev); dma_release_channel(dcmi->dma_chan); diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c index d1febe5baa6d..95a093f41905 100644 --- a/drivers/media/platform/ti-vpe/cal.c +++ b/drivers/media/platform/ti-vpe/cal.c @@ -270,7 +270,6 @@ struct cal_ctx { struct v4l2_fwnode_endpoint endpoint; struct v4l2_async_subdev asd; - struct v4l2_async_subdev *asd_list[1]; struct v4l2_fh fh; struct cal_dev *dev; @@ -912,8 +911,8 @@ static int cal_querycap(struct file *file, void *priv, { struct cal_ctx *ctx = video_drvdata(file); - strlcpy(cap->driver, CAL_MODULE_NAME, sizeof(cap->driver)); - strlcpy(cap->card, CAL_MODULE_NAME, sizeof(cap->card)); + strscpy(cap->driver, CAL_MODULE_NAME, sizeof(cap->driver)); + strscpy(cap->card, CAL_MODULE_NAME, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", ctx->v4l2_dev.name); @@ -1711,9 +1710,9 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst) } v4l2_fwnode_endpoint_parse(of_fwnode_handle(remote_ep), endpoint); - if (endpoint->bus_type != V4L2_MBUS_CSI2) { - ctx_err(ctx, "Port:%d sub-device %s is not a CSI2 device\n", - inst, sensor_node->name); + if (endpoint->bus_type != V4L2_MBUS_CSI2_DPHY) { + ctx_err(ctx, "Port:%d sub-device %pOFn is not a CSI2 device\n", + inst, sensor_node); goto cleanup_exit; } @@ -1732,29 +1731,38 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst) endpoint->bus.mipi_csi2.data_lanes[lane]); ctx_dbg(3, ctx, "\t>\n"); - ctx_dbg(1, ctx, "Port: %d found sub-device %s\n", - inst, sensor_node->name); + ctx_dbg(1, ctx, "Port: %d found sub-device %pOFn\n", + inst, sensor_node); + + v4l2_async_notifier_init(&ctx->notifier); + + ret = v4l2_async_notifier_add_subdev(&ctx->notifier, asd); + if (ret) { + ctx_err(ctx, "Error adding asd\n"); + goto cleanup_exit; + } - ctx->asd_list[0] = asd; - ctx->notifier.subdevs = ctx->asd_list; - ctx->notifier.num_subdevs = 1; ctx->notifier.ops = &cal_async_ops; ret = v4l2_async_notifier_register(&ctx->v4l2_dev, &ctx->notifier); if (ret) { ctx_err(ctx, "Error registering async notifier\n"); + v4l2_async_notifier_cleanup(&ctx->notifier); ret = -EINVAL; } + /* + * On success we need to keep reference on sensor_node, or + * if notifier_cleanup was called above, sensor_node was + * already put. + */ + sensor_node = NULL; + cleanup_exit: - if (remote_ep) - of_node_put(remote_ep); - if (sensor_node) - of_node_put(sensor_node); - if (ep_node) - of_node_put(ep_node); - if (port) - of_node_put(port); + of_node_put(remote_ep); + of_node_put(sensor_node); + of_node_put(ep_node); + of_node_put(port); return ret; } @@ -1810,15 +1818,17 @@ err_exit: static int cal_probe(struct platform_device *pdev) { struct cal_dev *dev; + struct cal_ctx *ctx; int ret; int irq; + int i; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; /* set pseudo v4l2 device name so we can use v4l2_printk */ - strlcpy(dev->v4l2_dev.name, CAL_MODULE_NAME, + strscpy(dev->v4l2_dev.name, CAL_MODULE_NAME, sizeof(dev->v4l2_dev.name)); /* save pdev pointer */ @@ -1879,6 +1889,16 @@ static int cal_probe(struct platform_device *pdev) runtime_disable: pm_runtime_disable(&pdev->dev); + for (i = 0; i < CAL_NUM_CONTEXT; i++) { + ctx = dev->ctx[i]; + if (ctx) { + v4l2_async_notifier_unregister(&ctx->notifier); + v4l2_async_notifier_cleanup(&ctx->notifier); + v4l2_ctrl_handler_free(&ctx->ctrl_handler); + v4l2_device_unregister(&ctx->v4l2_dev); + } + } + return ret; } @@ -1900,6 +1920,7 @@ static int cal_remove(struct platform_device *pdev) video_device_node_name(&ctx->vdev)); camerarx_phy_disable(ctx); v4l2_async_notifier_unregister(&ctx->notifier); + v4l2_async_notifier_cleanup(&ctx->notifier); v4l2_ctrl_handler_free(&ctx->ctrl_handler); v4l2_device_unregister(&ctx->v4l2_dev); video_unregister_device(&ctx->vdev); diff --git a/drivers/media/platform/via-camera.c b/drivers/media/platform/via-camera.c index c8bb82fe0b9d..24d5759501a5 100644 --- a/drivers/media/platform/via-camera.c +++ b/drivers/media/platform/via-camera.c @@ -812,7 +812,7 @@ static int viacam_enum_input(struct file *filp, void *priv, input->type = V4L2_INPUT_TYPE_CAMERA; input->std = V4L2_STD_ALL; /* Not sure what should go here */ - strcpy(input->name, "Camera"); + strscpy(input->name, "Camera", sizeof(input->name)); return 0; } @@ -860,8 +860,8 @@ static int viacam_enum_fmt_vid_cap(struct file *filp, void *priv, { if (fmt->index >= N_VIA_FMTS) return -EINVAL; - strlcpy(fmt->description, via_formats[fmt->index].desc, - sizeof(fmt->description)); + strscpy(fmt->description, via_formats[fmt->index].desc, + sizeof(fmt->description)); fmt->pixelformat = via_formats[fmt->index].pixelformat; return 0; } @@ -990,8 +990,8 @@ out: static int viacam_querycap(struct file *filp, void *priv, struct v4l2_capability *cap) { - strcpy(cap->driver, "via-camera"); - strcpy(cap->card, "via-camera"); + strscpy(cap->driver, "via-camera", sizeof(cap->driver)); + strscpy(cap->card, "via-camera", sizeof(cap->card)); cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; diff --git a/drivers/media/platform/vicodec/Kconfig b/drivers/media/platform/vicodec/Kconfig index 2503bcb1529f..ad13329e3461 100644 --- a/drivers/media/platform/vicodec/Kconfig +++ b/drivers/media/platform/vicodec/Kconfig @@ -1,6 +1,6 @@ config VIDEO_VICODEC tristate "Virtual Codec Driver" - depends on VIDEO_DEV && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + depends on VIDEO_DEV && VIDEO_V4L2 select VIDEOBUF2_VMALLOC select V4L2_MEM2MEM_DEV default n diff --git a/drivers/media/platform/vicodec/Makefile b/drivers/media/platform/vicodec/Makefile index 197229428953..01bf7e9308a6 100644 --- a/drivers/media/platform/vicodec/Makefile +++ b/drivers/media/platform/vicodec/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -vicodec-objs := vicodec-core.o vicodec-codec.o +vicodec-objs := vicodec-core.o codec-fwht.o codec-v4l2-fwht.o obj-$(CONFIG_VIDEO_VICODEC) += vicodec.o diff --git a/drivers/media/platform/vicodec/vicodec-codec.c b/drivers/media/platform/vicodec/codec-fwht.c index 2d047646f614..36656031b295 100644 --- a/drivers/media/platform/vicodec/vicodec-codec.c +++ b/drivers/media/platform/vicodec/codec-fwht.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +// SPDX-License-Identifier: LGPL-2.1+ /* * Copyright 2016 Tom aan de Wiel * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved. @@ -10,10 +10,20 @@ */ #include <linux/string.h> -#include "vicodec-codec.h" +#include "codec-fwht.h" + +/* + * Note: bit 0 of the header must always be 0. Otherwise it cannot + * be guaranteed that the magic 8 byte sequence (see below) can + * never occur in the rlc output. + */ +#define PFRAME_BIT BIT(15) +#define DUPS_MASK 0x1ffe + +#define PBLOCK 0 +#define IBLOCK 1 #define ALL_ZEROS 15 -#define DEADZONE_WIDTH 20 static const uint8_t zigzag[64] = { 0, @@ -164,7 +174,7 @@ static const int quant_table_p[] = { 3, 3, 3, 6, 6, 9, 9, 10, }; -static void quantize_intra(s16 *coeff, s16 *de_coeff) +static void quantize_intra(s16 *coeff, s16 *de_coeff, u16 qp) { const int *quant = quant_table; int i, j; @@ -172,8 +182,7 @@ static void quantize_intra(s16 *coeff, s16 *de_coeff) for (j = 0; j < 8; j++) { for (i = 0; i < 8; i++, quant++, coeff++, de_coeff++) { *coeff >>= *quant; - if (*coeff >= -DEADZONE_WIDTH && - *coeff <= DEADZONE_WIDTH) + if (*coeff >= -qp && *coeff <= qp) *coeff = *de_coeff = 0; else *de_coeff = *coeff << *quant; @@ -191,7 +200,7 @@ static void dequantize_intra(s16 *coeff) *coeff <<= *quant; } -static void quantize_inter(s16 *coeff, s16 *de_coeff) +static void quantize_inter(s16 *coeff, s16 *de_coeff, u16 qp) { const int *quant = quant_table_p; int i, j; @@ -199,8 +208,7 @@ static void quantize_inter(s16 *coeff, s16 *de_coeff) for (j = 0; j < 8; j++) { for (i = 0; i < 8; i++, quant++, coeff++, de_coeff++) { *coeff >>= *quant; - if (*coeff >= -DEADZONE_WIDTH && - *coeff <= DEADZONE_WIDTH) + if (*coeff >= -qp && *coeff <= qp) *coeff = *de_coeff = 0; else *de_coeff = *coeff << *quant; @@ -232,7 +240,8 @@ static void fwht(const u8 *block, s16 *output_block, unsigned int stride, stride *= input_step; for (i = 0; i < 8; i++, tmp += stride, out += 8) { - if (input_step == 1) { + switch (input_step) { + case 1: workspace1[0] = tmp[0] + tmp[1] - add; workspace1[1] = tmp[0] - tmp[1]; @@ -244,7 +253,8 @@ static void fwht(const u8 *block, s16 *output_block, unsigned int stride, workspace1[6] = tmp[6] + tmp[7] - add; workspace1[7] = tmp[6] - tmp[7]; - } else { + break; + case 2: workspace1[0] = tmp[0] + tmp[2] - add; workspace1[1] = tmp[0] - tmp[2]; @@ -256,6 +266,33 @@ static void fwht(const u8 *block, s16 *output_block, unsigned int stride, workspace1[6] = tmp[12] + tmp[14] - add; workspace1[7] = tmp[12] - tmp[14]; + break; + case 3: + workspace1[0] = tmp[0] + tmp[3] - add; + workspace1[1] = tmp[0] - tmp[3]; + + workspace1[2] = tmp[6] + tmp[9] - add; + workspace1[3] = tmp[6] - tmp[9]; + + workspace1[4] = tmp[12] + tmp[15] - add; + workspace1[5] = tmp[12] - tmp[15]; + + workspace1[6] = tmp[18] + tmp[21] - add; + workspace1[7] = tmp[18] - tmp[21]; + break; + default: + workspace1[0] = tmp[0] + tmp[4] - add; + workspace1[1] = tmp[0] - tmp[4]; + + workspace1[2] = tmp[8] + tmp[12] - add; + workspace1[3] = tmp[8] - tmp[12]; + + workspace1[4] = tmp[16] + tmp[20] - add; + workspace1[5] = tmp[16] - tmp[20]; + + workspace1[6] = tmp[24] + tmp[28] - add; + workspace1[7] = tmp[24] - tmp[28]; + break; } /* stage 2 */ @@ -588,8 +625,14 @@ static void fill_decoder_block(u8 *dst, const s16 *input, int stride) int i, j; for (i = 0; i < 8; i++) { - for (j = 0; j < 8; j++) - *dst++ = *input++; + for (j = 0; j < 8; j++, input++, dst++) { + if (*input < 0) + *dst = 0; + else if (*input > 255) + *dst = 255; + else + *dst = *input; + } dst += stride - 8; } } @@ -616,7 +659,7 @@ static void add_deltas(s16 *deltas, const u8 *ref, int stride) } static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max, - struct cframe *cf, u32 height, u32 width, + struct fwht_cframe *cf, u32 height, u32 width, unsigned int input_step, bool is_intra, bool next_is_intra) { @@ -637,15 +680,16 @@ static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max, if (!is_intra) blocktype = decide_blocktype(input, refp, deltablock, width, input_step); - if (is_intra || blocktype == IBLOCK) { + if (blocktype == IBLOCK) { fwht(input, cf->coeffs, width, input_step, 1); - quantize_intra(cf->coeffs, cf->de_coeffs); - blocktype = IBLOCK; + quantize_intra(cf->coeffs, cf->de_coeffs, + cf->i_frame_qp); } else { /* inter code */ - encoding |= FRAME_PCODED; + encoding |= FWHT_FRAME_PCODED; fwht16(deltablock, cf->coeffs, 8, 0); - quantize_inter(cf->coeffs, cf->de_coeffs); + quantize_inter(cf->coeffs, cf->de_coeffs, + cf->p_frame_qp); } if (!next_is_intra) { ifwht(cf->de_coeffs, cf->de_fwht, blocktype); @@ -658,9 +702,6 @@ static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max, input += 8 * input_step; refp += 8 * 8; - if (encoding & FRAME_UNENCODED) - continue; - size = rlc(cf->coeffs, *rlco, blocktype); if (last_size == size && !memcmp(*rlco + 1, *rlco - size + 1, 2 * size - 2)) { @@ -675,13 +716,17 @@ static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max, } else { *rlco += size; } - if (*rlco >= rlco_max) - encoding |= FRAME_UNENCODED; + if (*rlco >= rlco_max) { + encoding |= FWHT_FRAME_UNENCODED; + goto exit_loop; + } last_size = size; } input += width * 7 * input_step; } - if (encoding & FRAME_UNENCODED) { + +exit_loop: + if (encoding & FWHT_FRAME_UNENCODED) { u8 *out = (u8 *)rlco_start; input = input_start; @@ -694,44 +739,50 @@ static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max, for (i = 0; i < height * width; i++, input += input_step) *out++ = (*input == 0xff) ? 0xfe : *input; *rlco = (__be16 *)out; + encoding &= ~FWHT_FRAME_PCODED; } return encoding; } -u32 encode_frame(struct raw_frame *frm, struct raw_frame *ref_frm, - struct cframe *cf, bool is_intra, bool next_is_intra) +u32 fwht_encode_frame(struct fwht_raw_frame *frm, + struct fwht_raw_frame *ref_frm, + struct fwht_cframe *cf, + bool is_intra, bool next_is_intra) { unsigned int size = frm->height * frm->width; __be16 *rlco = cf->rlc_data; __be16 *rlco_max; u32 encoding; + u32 chroma_h = frm->height / frm->height_div; + u32 chroma_w = frm->width / frm->width_div; + unsigned int chroma_size = chroma_h * chroma_w; rlco_max = rlco + size / 2 - 256; encoding = encode_plane(frm->luma, ref_frm->luma, &rlco, rlco_max, cf, - frm->height, frm->width, - 1, is_intra, next_is_intra); - if (encoding & FRAME_UNENCODED) - encoding |= LUMA_UNENCODED; - encoding &= ~FRAME_UNENCODED; - rlco_max = rlco + size / 8 - 256; + frm->height, frm->width, + frm->luma_step, is_intra, next_is_intra); + if (encoding & FWHT_FRAME_UNENCODED) + encoding |= FWHT_LUMA_UNENCODED; + encoding &= ~FWHT_FRAME_UNENCODED; + rlco_max = rlco + chroma_size / 2 - 256; encoding |= encode_plane(frm->cb, ref_frm->cb, &rlco, rlco_max, cf, - frm->height / 2, frm->width / 2, - frm->chroma_step, is_intra, next_is_intra); - if (encoding & FRAME_UNENCODED) - encoding |= CB_UNENCODED; - encoding &= ~FRAME_UNENCODED; - rlco_max = rlco + size / 8 - 256; + chroma_h, chroma_w, + frm->chroma_step, is_intra, next_is_intra); + if (encoding & FWHT_FRAME_UNENCODED) + encoding |= FWHT_CB_UNENCODED; + encoding &= ~FWHT_FRAME_UNENCODED; + rlco_max = rlco + chroma_size / 2 - 256; encoding |= encode_plane(frm->cr, ref_frm->cr, &rlco, rlco_max, cf, - frm->height / 2, frm->width / 2, - frm->chroma_step, is_intra, next_is_intra); - if (encoding & FRAME_UNENCODED) - encoding |= CR_UNENCODED; - encoding &= ~FRAME_UNENCODED; + chroma_h, chroma_w, + frm->chroma_step, is_intra, next_is_intra); + if (encoding & FWHT_FRAME_UNENCODED) + encoding |= FWHT_CR_UNENCODED; + encoding &= ~FWHT_FRAME_UNENCODED; cf->size = (rlco - cf->rlc_data) * sizeof(*rlco); return encoding; } -static void decode_plane(struct cframe *cf, const __be16 **rlco, u8 *ref, +static void decode_plane(struct fwht_cframe *cf, const __be16 **rlco, u8 *ref, u32 height, u32 width, bool uncompressed) { unsigned int copies = 0; @@ -784,14 +835,21 @@ static void decode_plane(struct cframe *cf, const __be16 **rlco, u8 *ref, } } -void decode_frame(struct cframe *cf, struct raw_frame *ref, u32 hdr_flags) +void fwht_decode_frame(struct fwht_cframe *cf, struct fwht_raw_frame *ref, + u32 hdr_flags) { const __be16 *rlco = cf->rlc_data; + u32 h = cf->height / 2; + u32 w = cf->width / 2; + if (hdr_flags & FWHT_FL_CHROMA_FULL_HEIGHT) + h *= 2; + if (hdr_flags & FWHT_FL_CHROMA_FULL_WIDTH) + w *= 2; decode_plane(cf, &rlco, ref->luma, cf->height, cf->width, - hdr_flags & VICODEC_FL_LUMA_IS_UNCOMPRESSED); - decode_plane(cf, &rlco, ref->cb, cf->height / 2, cf->width / 2, - hdr_flags & VICODEC_FL_CB_IS_UNCOMPRESSED); - decode_plane(cf, &rlco, ref->cr, cf->height / 2, cf->width / 2, - hdr_flags & VICODEC_FL_CR_IS_UNCOMPRESSED); + hdr_flags & FWHT_FL_LUMA_IS_UNCOMPRESSED); + decode_plane(cf, &rlco, ref->cb, h, w, + hdr_flags & FWHT_FL_CB_IS_UNCOMPRESSED); + decode_plane(cf, &rlco, ref->cr, h, w, + hdr_flags & FWHT_FL_CR_IS_UNCOMPRESSED); } diff --git a/drivers/media/platform/vicodec/vicodec-codec.h b/drivers/media/platform/vicodec/codec-fwht.h index cdfad1332a3e..3e9391fec5fe 100644 --- a/drivers/media/platform/vicodec/vicodec-codec.h +++ b/drivers/media/platform/vicodec/codec-fwht.h @@ -1,18 +1,18 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright 2016 Tom aan de Wiel * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved. */ -#ifndef VICODEC_RLC_H -#define VICODEC_RLC_H +#ifndef CODEC_FWHT_H +#define CODEC_FWHT_H #include <linux/types.h> #include <linux/bitops.h> #include <asm/byteorder.h> /* - * The compressed format consists of a cframe_hdr struct followed by the + * The compressed format consists of a fwht_cframe_hdr struct followed by the * compressed frame data. The header contains the size of that data. * Each Y, Cb and Cr plane is compressed separately. If the compressed * size of each plane becomes larger than the uncompressed size, then @@ -35,7 +35,7 @@ * * All 16 and 32 bit values are stored in big-endian (network) order. * - * Each cframe_hdr starts with an 8 byte magic header that is + * Each fwht_cframe_hdr starts with an 8 byte magic header that is * guaranteed not to occur in the compressed frame data. This header * can be used to sync to the next frame. * @@ -47,48 +47,36 @@ */ /* - * Note: bit 0 of the header must always be 0. Otherwise it cannot - * be guaranteed that the magic 8 byte sequence (see below) can - * never occur in the rlc output. - */ -#define PFRAME_BIT (1 << 15) -#define DUPS_MASK 0x1ffe - -/* * This is a sequence of 8 bytes with the low 4 bits set to 0xf. * * This sequence cannot occur in the encoded data + * + * Note that these two magic values are symmetrical so endian issues here. */ -#define VICODEC_MAGIC1 0x4f4f4f4f -#define VICODEC_MAGIC2 0xffffffff - -#define VICODEC_VERSION 1 - -#define VICODEC_MAX_WIDTH 3840 -#define VICODEC_MAX_HEIGHT 2160 -#define VICODEC_MIN_WIDTH 640 -#define VICODEC_MIN_HEIGHT 480 +#define FWHT_MAGIC1 0x4f4f4f4f +#define FWHT_MAGIC2 0xffffffff -#define PBLOCK 0 -#define IBLOCK 1 +#define FWHT_VERSION 1 /* Set if this is an interlaced format */ -#define VICODEC_FL_IS_INTERLACED BIT(0) +#define FWHT_FL_IS_INTERLACED BIT(0) /* Set if this is a bottom-first (NTSC) interlaced format */ -#define VICODEC_FL_IS_BOTTOM_FIRST BIT(1) +#define FWHT_FL_IS_BOTTOM_FIRST BIT(1) /* Set if each 'frame' contains just one field */ -#define VICODEC_FL_IS_ALTERNATE BIT(2) +#define FWHT_FL_IS_ALTERNATE BIT(2) /* - * If VICODEC_FL_IS_ALTERNATE was set, then this is set if this + * If FWHT_FL_IS_ALTERNATE was set, then this is set if this * 'frame' is the bottom field, else it is the top field. */ -#define VICODEC_FL_IS_BOTTOM_FIELD BIT(3) +#define FWHT_FL_IS_BOTTOM_FIELD BIT(3) /* Set if this frame is uncompressed */ -#define VICODEC_FL_LUMA_IS_UNCOMPRESSED BIT(4) -#define VICODEC_FL_CB_IS_UNCOMPRESSED BIT(5) -#define VICODEC_FL_CR_IS_UNCOMPRESSED BIT(6) +#define FWHT_FL_LUMA_IS_UNCOMPRESSED BIT(4) +#define FWHT_FL_CB_IS_UNCOMPRESSED BIT(5) +#define FWHT_FL_CR_IS_UNCOMPRESSED BIT(6) +#define FWHT_FL_CHROMA_FULL_HEIGHT BIT(7) +#define FWHT_FL_CHROMA_FULL_WIDTH BIT(8) -struct cframe_hdr { +struct fwht_cframe_hdr { u32 magic1; u32 magic2; __be32 version; @@ -101,8 +89,10 @@ struct cframe_hdr { __be32 size; }; -struct cframe { +struct fwht_cframe { unsigned int width, height; + u16 i_frame_qp; + u16 p_frame_qp; __be16 *rlc_data; s16 coeffs[8 * 8]; s16 de_coeffs[8 * 8]; @@ -110,20 +100,26 @@ struct cframe { u32 size; }; -struct raw_frame { +struct fwht_raw_frame { unsigned int width, height; + unsigned int width_div; + unsigned int height_div; + unsigned int luma_step; unsigned int chroma_step; u8 *luma, *cb, *cr; }; -#define FRAME_PCODED BIT(0) -#define FRAME_UNENCODED BIT(1) -#define LUMA_UNENCODED BIT(2) -#define CB_UNENCODED BIT(3) -#define CR_UNENCODED BIT(4) +#define FWHT_FRAME_PCODED BIT(0) +#define FWHT_FRAME_UNENCODED BIT(1) +#define FWHT_LUMA_UNENCODED BIT(2) +#define FWHT_CB_UNENCODED BIT(3) +#define FWHT_CR_UNENCODED BIT(4) -u32 encode_frame(struct raw_frame *frm, struct raw_frame *ref_frm, - struct cframe *cf, bool is_intra, bool next_is_intra); -void decode_frame(struct cframe *cf, struct raw_frame *ref, u32 hdr_flags); +u32 fwht_encode_frame(struct fwht_raw_frame *frm, + struct fwht_raw_frame *ref_frm, + struct fwht_cframe *cf, + bool is_intra, bool next_is_intra); +void fwht_decode_frame(struct fwht_cframe *cf, struct fwht_raw_frame *ref, + u32 hdr_flags); #endif diff --git a/drivers/media/platform/vicodec/codec-v4l2-fwht.c b/drivers/media/platform/vicodec/codec-v4l2-fwht.c new file mode 100644 index 000000000000..e5b68fb38aac --- /dev/null +++ b/drivers/media/platform/vicodec/codec-v4l2-fwht.c @@ -0,0 +1,332 @@ +// SPDX-License-Identifier: LGPL-2.1 +/* + * A V4L2 frontend for the FWHT codec + * + * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + */ + +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/videodev2.h> +#include "codec-v4l2-fwht.h" + +static const struct v4l2_fwht_pixfmt_info v4l2_fwht_pixfmts[] = { + { V4L2_PIX_FMT_YUV420, 1, 3, 2, 1, 1, 2, 2 }, + { V4L2_PIX_FMT_YVU420, 1, 3, 2, 1, 1, 2, 2 }, + { V4L2_PIX_FMT_YUV422P, 1, 2, 1, 1, 1, 2, 1 }, + { V4L2_PIX_FMT_NV12, 1, 3, 2, 1, 2, 2, 2 }, + { V4L2_PIX_FMT_NV21, 1, 3, 2, 1, 2, 2, 2 }, + { V4L2_PIX_FMT_NV16, 1, 2, 1, 1, 2, 2, 1 }, + { V4L2_PIX_FMT_NV61, 1, 2, 1, 1, 2, 2, 1 }, + { V4L2_PIX_FMT_NV24, 1, 3, 1, 1, 2, 1, 1 }, + { V4L2_PIX_FMT_NV42, 1, 3, 1, 1, 2, 1, 1 }, + { V4L2_PIX_FMT_YUYV, 2, 2, 1, 2, 4, 2, 1 }, + { V4L2_PIX_FMT_YVYU, 2, 2, 1, 2, 4, 2, 1 }, + { V4L2_PIX_FMT_UYVY, 2, 2, 1, 2, 4, 2, 1 }, + { V4L2_PIX_FMT_VYUY, 2, 2, 1, 2, 4, 2, 1 }, + { V4L2_PIX_FMT_BGR24, 3, 3, 1, 3, 3, 1, 1 }, + { V4L2_PIX_FMT_RGB24, 3, 3, 1, 3, 3, 1, 1 }, + { V4L2_PIX_FMT_HSV24, 3, 3, 1, 3, 3, 1, 1 }, + { V4L2_PIX_FMT_BGR32, 4, 4, 1, 4, 4, 1, 1 }, + { V4L2_PIX_FMT_XBGR32, 4, 4, 1, 4, 4, 1, 1 }, + { V4L2_PIX_FMT_RGB32, 4, 4, 1, 4, 4, 1, 1 }, + { V4L2_PIX_FMT_XRGB32, 4, 4, 1, 4, 4, 1, 1 }, + { V4L2_PIX_FMT_HSV32, 4, 4, 1, 4, 4, 1, 1 }, +}; + +const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_pixfmt(u32 pixelformat) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(v4l2_fwht_pixfmts); i++) + if (v4l2_fwht_pixfmts[i].id == pixelformat) + return v4l2_fwht_pixfmts + i; + return NULL; +} + +const struct v4l2_fwht_pixfmt_info *v4l2_fwht_get_pixfmt(u32 idx) +{ + if (idx >= ARRAY_SIZE(v4l2_fwht_pixfmts)) + return NULL; + return v4l2_fwht_pixfmts + idx; +} + +int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) +{ + unsigned int size = state->width * state->height; + const struct v4l2_fwht_pixfmt_info *info = state->info; + struct fwht_cframe_hdr *p_hdr; + struct fwht_cframe cf; + struct fwht_raw_frame rf; + u32 encoding; + u32 flags = 0; + + if (!info) + return -EINVAL; + rf.width = state->width; + rf.height = state->height; + rf.luma = p_in; + rf.width_div = info->width_div; + rf.height_div = info->height_div; + rf.luma_step = info->luma_step; + rf.chroma_step = info->chroma_step; + + switch (info->id) { + case V4L2_PIX_FMT_YUV420: + rf.cb = rf.luma + size; + rf.cr = rf.cb + size / 4; + break; + case V4L2_PIX_FMT_YVU420: + rf.cr = rf.luma + size; + rf.cb = rf.cr + size / 4; + break; + case V4L2_PIX_FMT_YUV422P: + rf.cb = rf.luma + size; + rf.cr = rf.cb + size / 2; + break; + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV24: + rf.cb = rf.luma + size; + rf.cr = rf.cb + 1; + break; + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_NV42: + rf.cr = rf.luma + size; + rf.cb = rf.cr + 1; + break; + case V4L2_PIX_FMT_YUYV: + rf.cb = rf.luma + 1; + rf.cr = rf.cb + 2; + break; + case V4L2_PIX_FMT_YVYU: + rf.cr = rf.luma + 1; + rf.cb = rf.cr + 2; + break; + case V4L2_PIX_FMT_UYVY: + rf.cb = rf.luma; + rf.cr = rf.cb + 2; + rf.luma++; + break; + case V4L2_PIX_FMT_VYUY: + rf.cr = rf.luma; + rf.cb = rf.cr + 2; + rf.luma++; + break; + case V4L2_PIX_FMT_RGB24: + case V4L2_PIX_FMT_HSV24: + rf.cr = rf.luma; + rf.cb = rf.cr + 2; + rf.luma++; + break; + case V4L2_PIX_FMT_BGR24: + rf.cb = rf.luma; + rf.cr = rf.cb + 2; + rf.luma++; + break; + case V4L2_PIX_FMT_RGB32: + case V4L2_PIX_FMT_XRGB32: + case V4L2_PIX_FMT_HSV32: + rf.cr = rf.luma + 1; + rf.cb = rf.cr + 2; + rf.luma += 2; + break; + case V4L2_PIX_FMT_BGR32: + case V4L2_PIX_FMT_XBGR32: + rf.cb = rf.luma; + rf.cr = rf.cb + 2; + rf.luma++; + break; + default: + return -EINVAL; + } + + cf.width = state->width; + cf.height = state->height; + cf.i_frame_qp = state->i_frame_qp; + cf.p_frame_qp = state->p_frame_qp; + cf.rlc_data = (__be16 *)(p_out + sizeof(*p_hdr)); + + encoding = fwht_encode_frame(&rf, &state->ref_frame, &cf, + !state->gop_cnt, + state->gop_cnt == state->gop_size - 1); + if (!(encoding & FWHT_FRAME_PCODED)) + state->gop_cnt = 0; + if (++state->gop_cnt >= state->gop_size) + state->gop_cnt = 0; + + p_hdr = (struct fwht_cframe_hdr *)p_out; + p_hdr->magic1 = FWHT_MAGIC1; + p_hdr->magic2 = FWHT_MAGIC2; + p_hdr->version = htonl(FWHT_VERSION); + p_hdr->width = htonl(cf.width); + p_hdr->height = htonl(cf.height); + if (encoding & FWHT_LUMA_UNENCODED) + flags |= FWHT_FL_LUMA_IS_UNCOMPRESSED; + if (encoding & FWHT_CB_UNENCODED) + flags |= FWHT_FL_CB_IS_UNCOMPRESSED; + if (encoding & FWHT_CR_UNENCODED) + flags |= FWHT_FL_CR_IS_UNCOMPRESSED; + if (rf.height_div == 1) + flags |= FWHT_FL_CHROMA_FULL_HEIGHT; + if (rf.width_div == 1) + flags |= FWHT_FL_CHROMA_FULL_WIDTH; + p_hdr->flags = htonl(flags); + p_hdr->colorspace = htonl(state->colorspace); + p_hdr->xfer_func = htonl(state->xfer_func); + p_hdr->ycbcr_enc = htonl(state->ycbcr_enc); + p_hdr->quantization = htonl(state->quantization); + p_hdr->size = htonl(cf.size); + state->ref_frame.width = cf.width; + state->ref_frame.height = cf.height; + return cf.size + sizeof(*p_hdr); +} + +int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) +{ + unsigned int size = state->width * state->height; + unsigned int chroma_size = size; + unsigned int i; + u32 flags; + struct fwht_cframe_hdr *p_hdr; + struct fwht_cframe cf; + u8 *p; + + if (!state->info) + return -EINVAL; + + p_hdr = (struct fwht_cframe_hdr *)p_in; + cf.width = ntohl(p_hdr->width); + cf.height = ntohl(p_hdr->height); + flags = ntohl(p_hdr->flags); + state->colorspace = ntohl(p_hdr->colorspace); + state->xfer_func = ntohl(p_hdr->xfer_func); + state->ycbcr_enc = ntohl(p_hdr->ycbcr_enc); + state->quantization = ntohl(p_hdr->quantization); + cf.rlc_data = (__be16 *)(p_in + sizeof(*p_hdr)); + + if (p_hdr->magic1 != FWHT_MAGIC1 || + p_hdr->magic2 != FWHT_MAGIC2 || + ntohl(p_hdr->version) != FWHT_VERSION || + (cf.width & 7) || (cf.height & 7)) + return -EINVAL; + + /* TODO: support resolution changes */ + if (cf.width != state->width || cf.height != state->height) + return -EINVAL; + + if (!(flags & FWHT_FL_CHROMA_FULL_WIDTH)) + chroma_size /= 2; + if (!(flags & FWHT_FL_CHROMA_FULL_HEIGHT)) + chroma_size /= 2; + + fwht_decode_frame(&cf, &state->ref_frame, flags); + + switch (state->info->id) { + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YUV422P: + memcpy(p_out, state->ref_frame.luma, size); + p_out += size; + memcpy(p_out, state->ref_frame.cb, chroma_size); + p_out += chroma_size; + memcpy(p_out, state->ref_frame.cr, chroma_size); + break; + case V4L2_PIX_FMT_YVU420: + memcpy(p_out, state->ref_frame.luma, size); + p_out += size; + memcpy(p_out, state->ref_frame.cr, chroma_size); + p_out += chroma_size; + memcpy(p_out, state->ref_frame.cb, chroma_size); + break; + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV24: + memcpy(p_out, state->ref_frame.luma, size); + p_out += size; + for (i = 0, p = p_out; i < chroma_size; i++) { + *p++ = state->ref_frame.cb[i]; + *p++ = state->ref_frame.cr[i]; + } + break; + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_NV42: + memcpy(p_out, state->ref_frame.luma, size); + p_out += size; + for (i = 0, p = p_out; i < chroma_size; i++) { + *p++ = state->ref_frame.cr[i]; + *p++ = state->ref_frame.cb[i]; + } + break; + case V4L2_PIX_FMT_YUYV: + for (i = 0, p = p_out; i < size; i += 2) { + *p++ = state->ref_frame.luma[i]; + *p++ = state->ref_frame.cb[i / 2]; + *p++ = state->ref_frame.luma[i + 1]; + *p++ = state->ref_frame.cr[i / 2]; + } + break; + case V4L2_PIX_FMT_YVYU: + for (i = 0, p = p_out; i < size; i += 2) { + *p++ = state->ref_frame.luma[i]; + *p++ = state->ref_frame.cr[i / 2]; + *p++ = state->ref_frame.luma[i + 1]; + *p++ = state->ref_frame.cb[i / 2]; + } + break; + case V4L2_PIX_FMT_UYVY: + for (i = 0, p = p_out; i < size; i += 2) { + *p++ = state->ref_frame.cb[i / 2]; + *p++ = state->ref_frame.luma[i]; + *p++ = state->ref_frame.cr[i / 2]; + *p++ = state->ref_frame.luma[i + 1]; + } + break; + case V4L2_PIX_FMT_VYUY: + for (i = 0, p = p_out; i < size; i += 2) { + *p++ = state->ref_frame.cr[i / 2]; + *p++ = state->ref_frame.luma[i]; + *p++ = state->ref_frame.cb[i / 2]; + *p++ = state->ref_frame.luma[i + 1]; + } + break; + case V4L2_PIX_FMT_RGB24: + case V4L2_PIX_FMT_HSV24: + for (i = 0, p = p_out; i < size; i++) { + *p++ = state->ref_frame.cr[i]; + *p++ = state->ref_frame.luma[i]; + *p++ = state->ref_frame.cb[i]; + } + break; + case V4L2_PIX_FMT_BGR24: + for (i = 0, p = p_out; i < size; i++) { + *p++ = state->ref_frame.cb[i]; + *p++ = state->ref_frame.luma[i]; + *p++ = state->ref_frame.cr[i]; + } + break; + case V4L2_PIX_FMT_RGB32: + case V4L2_PIX_FMT_XRGB32: + case V4L2_PIX_FMT_HSV32: + for (i = 0, p = p_out; i < size; i++) { + *p++ = 0; + *p++ = state->ref_frame.cr[i]; + *p++ = state->ref_frame.luma[i]; + *p++ = state->ref_frame.cb[i]; + } + break; + case V4L2_PIX_FMT_BGR32: + case V4L2_PIX_FMT_XBGR32: + for (i = 0, p = p_out; i < size; i++) { + *p++ = state->ref_frame.cb[i]; + *p++ = state->ref_frame.luma[i]; + *p++ = state->ref_frame.cr[i]; + *p++ = 0; + } + break; + default: + return -EINVAL; + } + return 0; +} diff --git a/drivers/media/platform/vicodec/codec-v4l2-fwht.h b/drivers/media/platform/vicodec/codec-v4l2-fwht.h new file mode 100644 index 000000000000..162465b78067 --- /dev/null +++ b/drivers/media/platform/vicodec/codec-v4l2-fwht.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: LGPL-2.1 */ +/* + * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + */ + +#ifndef CODEC_V4L2_FWHT_H +#define CODEC_V4L2_FWHT_H + +#include "codec-fwht.h" + +struct v4l2_fwht_pixfmt_info { + u32 id; + unsigned int bytesperline_mult; + unsigned int sizeimage_mult; + unsigned int sizeimage_div; + unsigned int luma_step; + unsigned int chroma_step; + /* Chroma plane subsampling */ + unsigned int width_div; + unsigned int height_div; +}; + +struct v4l2_fwht_state { + const struct v4l2_fwht_pixfmt_info *info; + unsigned int width; + unsigned int height; + unsigned int gop_size; + unsigned int gop_cnt; + u16 i_frame_qp; + u16 p_frame_qp; + + enum v4l2_colorspace colorspace; + enum v4l2_ycbcr_encoding ycbcr_enc; + enum v4l2_xfer_func xfer_func; + enum v4l2_quantization quantization; + + struct fwht_raw_frame ref_frame; + u8 *compressed_frame; +}; + +const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_pixfmt(u32 pixelformat); +const struct v4l2_fwht_pixfmt_info *v4l2_fwht_get_pixfmt(u32 idx); + +int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out); +int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out); + +#endif diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c index 408cd55d3580..1eb9132bfc85 100644 --- a/drivers/media/platform/vicodec/vicodec-core.c +++ b/drivers/media/platform/vicodec/vicodec-core.c @@ -23,7 +23,7 @@ #include <media/v4l2-event.h> #include <media/videobuf2-vmalloc.h> -#include "vicodec-codec.h" +#include "codec-v4l2-fwht.h" MODULE_DESCRIPTION("Virtual codec device"); MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>"); @@ -48,6 +48,22 @@ MODULE_PARM_DESC(debug, " activates debug info"); v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg) +struct pixfmt_info { + u32 id; + unsigned int bytesperline_mult; + unsigned int sizeimage_mult; + unsigned int sizeimage_div; + unsigned int luma_step; + unsigned int chroma_step; + /* Chroma plane subsampling */ + unsigned int width_div; + unsigned int height_div; +}; + +static const struct v4l2_fwht_pixfmt_info pixfmt_fwht = { + V4L2_PIX_FMT_FWHT, 0, 3, 1, 1, 1, 1, 1 +}; + static void vicodec_dev_release(struct device *dev) { } @@ -61,10 +77,9 @@ static struct platform_device vicodec_pdev = { struct vicodec_q_data { unsigned int width; unsigned int height; - unsigned int flags; unsigned int sizeimage; unsigned int sequence; - u32 fourcc; + const struct v4l2_fwht_pixfmt_info *info; }; enum { @@ -96,24 +111,14 @@ struct vicodec_ctx { spinlock_t *lock; struct v4l2_ctrl_handler hdl; - struct v4l2_ctrl *ctrl_gop_size; - unsigned int gop_size; - unsigned int gop_cnt; - /* Abort requested by m2m */ - int aborting; struct vb2_v4l2_buffer *last_src_buf; struct vb2_v4l2_buffer *last_dst_buf; - enum v4l2_colorspace colorspace; - enum v4l2_ycbcr_encoding ycbcr_enc; - enum v4l2_xfer_func xfer_func; - enum v4l2_quantization quantization; - /* Source and destination queue data */ struct vicodec_q_data q_data[2]; - struct raw_frame ref_frame; - u8 *compressed_frame; + struct v4l2_fwht_state state; + u32 cur_buf_offset; u32 comp_max_size; u32 comp_size; @@ -123,13 +128,6 @@ struct vicodec_ctx { bool comp_has_next_frame; }; -static const u32 pixfmts_yuv[] = { - V4L2_PIX_FMT_YUV420, - V4L2_PIX_FMT_YVU420, - V4L2_PIX_FMT_NV12, - V4L2_PIX_FMT_NV21, -}; - static inline struct vicodec_ctx *file2ctx(struct file *file) { return container_of(file->private_data, struct vicodec_ctx, fh); @@ -152,156 +150,21 @@ static struct vicodec_q_data *get_q_data(struct vicodec_ctx *ctx, return NULL; } -static void encode(struct vicodec_ctx *ctx, - struct vicodec_q_data *q_data, - u8 *p_in, u8 *p_out) -{ - unsigned int size = q_data->width * q_data->height; - struct cframe_hdr *p_hdr; - struct cframe cf; - struct raw_frame rf; - u32 encoding; - - rf.width = q_data->width; - rf.height = q_data->height; - rf.luma = p_in; - - switch (q_data->fourcc) { - case V4L2_PIX_FMT_YUV420: - rf.cb = rf.luma + size; - rf.cr = rf.cb + size / 4; - rf.chroma_step = 1; - break; - case V4L2_PIX_FMT_YVU420: - rf.cr = rf.luma + size; - rf.cb = rf.cr + size / 4; - rf.chroma_step = 1; - break; - case V4L2_PIX_FMT_NV12: - rf.cb = rf.luma + size; - rf.cr = rf.cb + 1; - rf.chroma_step = 2; - break; - case V4L2_PIX_FMT_NV21: - rf.cr = rf.luma + size; - rf.cb = rf.cr + 1; - rf.chroma_step = 2; - break; - } - - cf.width = q_data->width; - cf.height = q_data->height; - cf.rlc_data = (__be16 *)(p_out + sizeof(*p_hdr)); - - encoding = encode_frame(&rf, &ctx->ref_frame, &cf, !ctx->gop_cnt, - ctx->gop_cnt == ctx->gop_size - 1); - if (encoding != FRAME_PCODED) - ctx->gop_cnt = 0; - if (++ctx->gop_cnt == ctx->gop_size) - ctx->gop_cnt = 0; - - p_hdr = (struct cframe_hdr *)p_out; - p_hdr->magic1 = VICODEC_MAGIC1; - p_hdr->magic2 = VICODEC_MAGIC2; - p_hdr->version = htonl(VICODEC_VERSION); - p_hdr->width = htonl(cf.width); - p_hdr->height = htonl(cf.height); - p_hdr->flags = htonl(q_data->flags); - if (encoding & LUMA_UNENCODED) - p_hdr->flags |= htonl(VICODEC_FL_LUMA_IS_UNCOMPRESSED); - if (encoding & CB_UNENCODED) - p_hdr->flags |= htonl(VICODEC_FL_CB_IS_UNCOMPRESSED); - if (encoding & CR_UNENCODED) - p_hdr->flags |= htonl(VICODEC_FL_CR_IS_UNCOMPRESSED); - p_hdr->colorspace = htonl(ctx->colorspace); - p_hdr->xfer_func = htonl(ctx->xfer_func); - p_hdr->ycbcr_enc = htonl(ctx->ycbcr_enc); - p_hdr->quantization = htonl(ctx->quantization); - p_hdr->size = htonl(cf.size); - ctx->ref_frame.width = cf.width; - ctx->ref_frame.height = cf.height; -} - -static int decode(struct vicodec_ctx *ctx, - struct vicodec_q_data *q_data, - u8 *p_in, u8 *p_out) -{ - unsigned int size = q_data->width * q_data->height; - unsigned int i; - struct cframe_hdr *p_hdr; - struct cframe cf; - u8 *p; - - p_hdr = (struct cframe_hdr *)p_in; - cf.width = ntohl(p_hdr->width); - cf.height = ntohl(p_hdr->height); - q_data->flags = ntohl(p_hdr->flags); - ctx->colorspace = ntohl(p_hdr->colorspace); - ctx->xfer_func = ntohl(p_hdr->xfer_func); - ctx->ycbcr_enc = ntohl(p_hdr->ycbcr_enc); - ctx->quantization = ntohl(p_hdr->quantization); - cf.rlc_data = (__be16 *)(p_in + sizeof(*p_hdr)); - - if (p_hdr->magic1 != VICODEC_MAGIC1 || - p_hdr->magic2 != VICODEC_MAGIC2 || - ntohl(p_hdr->version) != VICODEC_VERSION || - cf.width < VICODEC_MIN_WIDTH || - cf.width > VICODEC_MAX_WIDTH || - cf.height < VICODEC_MIN_HEIGHT || - cf.height > VICODEC_MAX_HEIGHT || - (cf.width & 7) || (cf.height & 7)) - return -EINVAL; - - /* TODO: support resolution changes */ - if (cf.width != q_data->width || cf.height != q_data->height) - return -EINVAL; - - decode_frame(&cf, &ctx->ref_frame, q_data->flags); - memcpy(p_out, ctx->ref_frame.luma, size); - p_out += size; - - switch (q_data->fourcc) { - case V4L2_PIX_FMT_YUV420: - memcpy(p_out, ctx->ref_frame.cb, size / 4); - p_out += size / 4; - memcpy(p_out, ctx->ref_frame.cr, size / 4); - break; - case V4L2_PIX_FMT_YVU420: - memcpy(p_out, ctx->ref_frame.cr, size / 4); - p_out += size / 4; - memcpy(p_out, ctx->ref_frame.cb, size / 4); - break; - case V4L2_PIX_FMT_NV12: - for (i = 0, p = p_out; i < size / 4; i++, p += 2) - *p = ctx->ref_frame.cb[i]; - for (i = 0, p = p_out + 1; i < size / 4; i++, p += 2) - *p = ctx->ref_frame.cr[i]; - break; - case V4L2_PIX_FMT_NV21: - for (i = 0, p = p_out; i < size / 4; i++, p += 2) - *p = ctx->ref_frame.cr[i]; - for (i = 0, p = p_out + 1; i < size / 4; i++, p += 2) - *p = ctx->ref_frame.cb[i]; - break; - } - return 0; -} - static int device_process(struct vicodec_ctx *ctx, struct vb2_v4l2_buffer *in_vb, struct vb2_v4l2_buffer *out_vb) { struct vicodec_dev *dev = ctx->dev; - struct vicodec_q_data *q_out, *q_cap; + struct vicodec_q_data *q_cap; + struct v4l2_fwht_state *state = &ctx->state; u8 *p_in, *p_out; int ret; - q_out = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); q_cap = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); if (ctx->is_enc) p_in = vb2_plane_vaddr(&in_vb->vb2_buf, 0); else - p_in = ctx->compressed_frame; + p_in = state->compressed_frame; p_out = vb2_plane_vaddr(&out_vb->vb2_buf, 0); if (!p_in || !p_out) { v4l2_err(&dev->v4l2_dev, @@ -310,17 +173,20 @@ static int device_process(struct vicodec_ctx *ctx, } if (ctx->is_enc) { - struct cframe_hdr *p_hdr = (struct cframe_hdr *)p_out; + struct vicodec_q_data *q_out; - encode(ctx, q_out, p_in, p_out); - vb2_set_plane_payload(&out_vb->vb2_buf, 0, - sizeof(*p_hdr) + ntohl(p_hdr->size)); + q_out = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); + state->info = q_out->info; + ret = v4l2_fwht_encode(state, p_in, p_out); + if (ret < 0) + return ret; + vb2_set_plane_payload(&out_vb->vb2_buf, 0, ret); } else { - ret = decode(ctx, q_cap, p_in, p_out); - if (ret) + state->info = q_cap->info; + ret = v4l2_fwht_decode(state, p_in, p_out); + if (ret < 0) return ret; - vb2_set_plane_payload(&out_vb->vb2_buf, 0, - q_cap->width * q_cap->height * 3 / 2); + vb2_set_plane_payload(&out_vb->vb2_buf, 0, q_cap->sizeimage); } out_vb->sequence = q_cap->sequence++; @@ -446,10 +312,11 @@ restart: copy = sizeof(magic) - ctx->comp_magic_cnt; if (p_out + sz - p < copy) copy = p_out + sz - p; - memcpy(ctx->compressed_frame + ctx->comp_magic_cnt, + memcpy(ctx->state.compressed_frame + ctx->comp_magic_cnt, p, copy); ctx->comp_magic_cnt += copy; - if (!memcmp(ctx->compressed_frame, magic, ctx->comp_magic_cnt)) { + if (!memcmp(ctx->state.compressed_frame, magic, + ctx->comp_magic_cnt)) { p += copy; state = VB2_BUF_STATE_DONE; break; @@ -462,17 +329,18 @@ restart: } ctx->comp_size = sizeof(magic); } - if (ctx->comp_size < sizeof(struct cframe_hdr)) { - struct cframe_hdr *p_hdr = (struct cframe_hdr *)ctx->compressed_frame; - u32 copy = sizeof(struct cframe_hdr) - ctx->comp_size; + if (ctx->comp_size < sizeof(struct fwht_cframe_hdr)) { + struct fwht_cframe_hdr *p_hdr = + (struct fwht_cframe_hdr *)ctx->state.compressed_frame; + u32 copy = sizeof(struct fwht_cframe_hdr) - ctx->comp_size; if (copy > p_out + sz - p) copy = p_out + sz - p; - memcpy(ctx->compressed_frame + ctx->comp_size, + memcpy(ctx->state.compressed_frame + ctx->comp_size, p, copy); p += copy; ctx->comp_size += copy; - if (ctx->comp_size < sizeof(struct cframe_hdr)) { + if (ctx->comp_size < sizeof(struct fwht_cframe_hdr)) { job_remove_out_buf(ctx, state); goto restart; } @@ -485,7 +353,7 @@ restart: if (copy > p_out + sz - p) copy = p_out + sz - p; - memcpy(ctx->compressed_frame + ctx->comp_size, + memcpy(ctx->state.compressed_frame + ctx->comp_size, p, copy); p += copy; ctx->comp_size += copy; @@ -497,8 +365,8 @@ restart: ctx->cur_buf_offset = p - p_out; ctx->comp_has_frame = true; ctx->comp_has_next_frame = false; - if (sz - ctx->cur_buf_offset >= sizeof(struct cframe_hdr)) { - struct cframe_hdr *p_hdr = (struct cframe_hdr *)p; + if (sz - ctx->cur_buf_offset >= sizeof(struct fwht_cframe_hdr)) { + struct fwht_cframe_hdr *p_hdr = (struct fwht_cframe_hdr *)p; u32 frame_size = ntohl(p_hdr->size); u32 remaining = sz - ctx->cur_buf_offset - sizeof(*p_hdr); @@ -508,26 +376,18 @@ restart: return 1; } -static void job_abort(void *priv) -{ - struct vicodec_ctx *ctx = priv; - - /* Will cancel the transaction in the next interrupt handler */ - ctx->aborting = 1; -} - /* * video ioctls */ -static u32 find_fmt(u32 fmt) +static const struct v4l2_fwht_pixfmt_info *find_fmt(u32 fmt) { - unsigned int i; + const struct v4l2_fwht_pixfmt_info *info = + v4l2_fwht_find_pixfmt(fmt); - for (i = 0; i < ARRAY_SIZE(pixfmts_yuv); i++) - if (pixfmts_yuv[i] == fmt) - return fmt; - return pixfmts_yuv[0]; + if (!info) + info = v4l2_fwht_get_pixfmt(0); + return info; } static int vidioc_querycap(struct file *file, void *priv, @@ -547,19 +407,25 @@ static int vidioc_querycap(struct file *file, void *priv, static int enum_fmt(struct v4l2_fmtdesc *f, bool is_enc, bool is_out) { - bool is_yuv = (is_enc && is_out) || (!is_enc && !is_out); + bool is_uncomp = (is_enc && is_out) || (!is_enc && !is_out); if (V4L2_TYPE_IS_MULTIPLANAR(f->type) && !multiplanar) return -EINVAL; if (!V4L2_TYPE_IS_MULTIPLANAR(f->type) && multiplanar) return -EINVAL; - if (f->index >= (is_yuv ? ARRAY_SIZE(pixfmts_yuv) : 1)) - return -EINVAL; - if (is_yuv) - f->pixelformat = pixfmts_yuv[f->index]; - else + if (is_uncomp) { + const struct v4l2_fwht_pixfmt_info *info = + v4l2_fwht_get_pixfmt(f->index); + + if (!info) + return -EINVAL; + f->pixelformat = info->id; + } else { + if (f->index) + return -EINVAL; f->pixelformat = V4L2_PIX_FMT_FWHT; + } return 0; } @@ -585,12 +451,14 @@ static int vidioc_g_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f) struct vicodec_q_data *q_data; struct v4l2_pix_format_mplane *pix_mp; struct v4l2_pix_format *pix; + const struct v4l2_fwht_pixfmt_info *info; vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); if (!vq) return -EINVAL; q_data = get_q_data(ctx, f->type); + info = q_data->info; switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: @@ -601,16 +469,13 @@ static int vidioc_g_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f) pix->width = q_data->width; pix->height = q_data->height; pix->field = V4L2_FIELD_NONE; - pix->pixelformat = q_data->fourcc; - if (q_data->fourcc == V4L2_PIX_FMT_FWHT) - pix->bytesperline = 0; - else - pix->bytesperline = q_data->width; + pix->pixelformat = info->id; + pix->bytesperline = q_data->width * info->bytesperline_mult; pix->sizeimage = q_data->sizeimage; - pix->colorspace = ctx->colorspace; - pix->xfer_func = ctx->xfer_func; - pix->ycbcr_enc = ctx->ycbcr_enc; - pix->quantization = ctx->quantization; + pix->colorspace = ctx->state.colorspace; + pix->xfer_func = ctx->state.xfer_func; + pix->ycbcr_enc = ctx->state.ycbcr_enc; + pix->quantization = ctx->state.quantization; break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: @@ -621,17 +486,15 @@ static int vidioc_g_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f) pix_mp->width = q_data->width; pix_mp->height = q_data->height; pix_mp->field = V4L2_FIELD_NONE; - pix_mp->pixelformat = q_data->fourcc; + pix_mp->pixelformat = info->id; pix_mp->num_planes = 1; - if (q_data->fourcc == V4L2_PIX_FMT_FWHT) - pix_mp->plane_fmt[0].bytesperline = 0; - else - pix_mp->plane_fmt[0].bytesperline = q_data->width; + pix_mp->plane_fmt[0].bytesperline = + q_data->width * info->bytesperline_mult; pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage; - pix_mp->colorspace = ctx->colorspace; - pix_mp->xfer_func = ctx->xfer_func; - pix_mp->ycbcr_enc = ctx->ycbcr_enc; - pix_mp->quantization = ctx->quantization; + pix_mp->colorspace = ctx->state.colorspace; + pix_mp->xfer_func = ctx->state.xfer_func; + pix_mp->ycbcr_enc = ctx->state.ycbcr_enc; + pix_mp->quantization = ctx->state.quantization; memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved)); memset(pix_mp->plane_fmt[0].reserved, 0, sizeof(pix_mp->plane_fmt[0].reserved)); @@ -658,40 +521,44 @@ static int vidioc_try_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f) { struct v4l2_pix_format_mplane *pix_mp; struct v4l2_pix_format *pix; + struct v4l2_plane_pix_format *plane; + const struct v4l2_fwht_pixfmt_info *info = &pixfmt_fwht; switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_OUTPUT: pix = &f->fmt.pix; + if (pix->pixelformat != V4L2_PIX_FMT_FWHT) + info = find_fmt(pix->pixelformat); pix->width = clamp(pix->width, MIN_WIDTH, MAX_WIDTH) & ~7; pix->height = clamp(pix->height, MIN_HEIGHT, MAX_HEIGHT) & ~7; - pix->bytesperline = pix->width; - pix->sizeimage = pix->width * pix->height * 3 / 2; pix->field = V4L2_FIELD_NONE; - if (pix->pixelformat == V4L2_PIX_FMT_FWHT) { - pix->bytesperline = 0; - pix->sizeimage += sizeof(struct cframe_hdr); - } + pix->bytesperline = + pix->width * info->bytesperline_mult; + pix->sizeimage = pix->width * pix->height * + info->sizeimage_mult / info->sizeimage_div; + if (pix->pixelformat == V4L2_PIX_FMT_FWHT) + pix->sizeimage += sizeof(struct fwht_cframe_hdr); break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: pix_mp = &f->fmt.pix_mp; + plane = pix_mp->plane_fmt; + if (pix_mp->pixelformat != V4L2_PIX_FMT_FWHT) + info = find_fmt(pix_mp->pixelformat); + pix_mp->num_planes = 1; pix_mp->width = clamp(pix_mp->width, MIN_WIDTH, MAX_WIDTH) & ~7; pix_mp->height = clamp(pix_mp->height, MIN_HEIGHT, MAX_HEIGHT) & ~7; - pix_mp->plane_fmt[0].bytesperline = pix_mp->width; - pix_mp->plane_fmt[0].sizeimage = - pix_mp->width * pix_mp->height * 3 / 2; pix_mp->field = V4L2_FIELD_NONE; - pix_mp->num_planes = 1; - if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT) { - pix_mp->plane_fmt[0].bytesperline = 0; - pix_mp->plane_fmt[0].sizeimage += - sizeof(struct cframe_hdr); - } + plane->bytesperline = + pix_mp->width * info->bytesperline_mult; + plane->sizeimage = pix_mp->width * pix_mp->height * + info->sizeimage_mult / info->sizeimage_div; + if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT) + plane->sizeimage += sizeof(struct fwht_cframe_hdr); memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved)); - memset(pix_mp->plane_fmt[0].reserved, 0, - sizeof(pix_mp->plane_fmt[0].reserved)); + memset(plane->reserved, 0, sizeof(plane->reserved)); break; default: return -EINVAL; @@ -713,25 +580,22 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, return -EINVAL; pix = &f->fmt.pix; pix->pixelformat = ctx->is_enc ? V4L2_PIX_FMT_FWHT : - find_fmt(f->fmt.pix.pixelformat); - pix->colorspace = ctx->colorspace; - pix->xfer_func = ctx->xfer_func; - pix->ycbcr_enc = ctx->ycbcr_enc; - pix->quantization = ctx->quantization; + find_fmt(f->fmt.pix.pixelformat)->id; + pix->colorspace = ctx->state.colorspace; + pix->xfer_func = ctx->state.xfer_func; + pix->ycbcr_enc = ctx->state.ycbcr_enc; + pix->quantization = ctx->state.quantization; break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: if (!multiplanar) return -EINVAL; pix_mp = &f->fmt.pix_mp; pix_mp->pixelformat = ctx->is_enc ? V4L2_PIX_FMT_FWHT : - find_fmt(pix_mp->pixelformat); - pix_mp->colorspace = ctx->colorspace; - pix_mp->xfer_func = ctx->xfer_func; - pix_mp->ycbcr_enc = ctx->ycbcr_enc; - pix_mp->quantization = ctx->quantization; - memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved)); - memset(pix_mp->plane_fmt[0].reserved, 0, - sizeof(pix_mp->plane_fmt[0].reserved)); + find_fmt(pix_mp->pixelformat)->id; + pix_mp->colorspace = ctx->state.colorspace; + pix_mp->xfer_func = ctx->state.xfer_func; + pix_mp->ycbcr_enc = ctx->state.ycbcr_enc; + pix_mp->quantization = ctx->state.quantization; break; default: return -EINVAL; @@ -753,7 +617,7 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *priv, return -EINVAL; pix = &f->fmt.pix; pix->pixelformat = !ctx->is_enc ? V4L2_PIX_FMT_FWHT : - find_fmt(pix->pixelformat); + find_fmt(pix->pixelformat)->id; if (!pix->colorspace) pix->colorspace = V4L2_COLORSPACE_REC709; break; @@ -762,7 +626,7 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *priv, return -EINVAL; pix_mp = &f->fmt.pix_mp; pix_mp->pixelformat = !ctx->is_enc ? V4L2_PIX_FMT_FWHT : - find_fmt(pix_mp->pixelformat); + find_fmt(pix_mp->pixelformat)->id; if (!pix_mp->colorspace) pix_mp->colorspace = V4L2_COLORSPACE_REC709; break; @@ -795,14 +659,17 @@ static int vidioc_s_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f) pix = &f->fmt.pix; if (ctx->is_enc && V4L2_TYPE_IS_OUTPUT(f->type)) fmt_changed = - q_data->fourcc != pix->pixelformat || + q_data->info->id != pix->pixelformat || q_data->width != pix->width || q_data->height != pix->height; if (vb2_is_busy(vq) && fmt_changed) return -EBUSY; - q_data->fourcc = pix->pixelformat; + if (pix->pixelformat == V4L2_PIX_FMT_FWHT) + q_data->info = &pixfmt_fwht; + else + q_data->info = find_fmt(pix->pixelformat); q_data->width = pix->width; q_data->height = pix->height; q_data->sizeimage = pix->sizeimage; @@ -812,14 +679,17 @@ static int vidioc_s_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f) pix_mp = &f->fmt.pix_mp; if (ctx->is_enc && V4L2_TYPE_IS_OUTPUT(f->type)) fmt_changed = - q_data->fourcc != pix_mp->pixelformat || + q_data->info->id != pix_mp->pixelformat || q_data->width != pix_mp->width || q_data->height != pix_mp->height; if (vb2_is_busy(vq) && fmt_changed) return -EBUSY; - q_data->fourcc = pix_mp->pixelformat; + if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT) + q_data->info = &pixfmt_fwht; + else + q_data->info = find_fmt(pix_mp->pixelformat); q_data->width = pix_mp->width; q_data->height = pix_mp->height; q_data->sizeimage = pix_mp->plane_fmt[0].sizeimage; @@ -830,7 +700,7 @@ static int vidioc_s_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f) dprintk(ctx->dev, "Setting format for type %d, wxh: %dx%d, fourcc: %08x\n", - f->type, q_data->width, q_data->height, q_data->fourcc); + f->type, q_data->width, q_data->height, q_data->info->id); return 0; } @@ -865,18 +735,18 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *priv, case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_OUTPUT: pix = &f->fmt.pix; - ctx->colorspace = pix->colorspace; - ctx->xfer_func = pix->xfer_func; - ctx->ycbcr_enc = pix->ycbcr_enc; - ctx->quantization = pix->quantization; + ctx->state.colorspace = pix->colorspace; + ctx->state.xfer_func = pix->xfer_func; + ctx->state.ycbcr_enc = pix->ycbcr_enc; + ctx->state.quantization = pix->quantization; break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: pix_mp = &f->fmt.pix_mp; - ctx->colorspace = pix_mp->colorspace; - ctx->xfer_func = pix_mp->xfer_func; - ctx->ycbcr_enc = pix_mp->ycbcr_enc; - ctx->quantization = pix_mp->quantization; + ctx->state.colorspace = pix_mp->colorspace; + ctx->state.xfer_func = pix_mp->xfer_func; + ctx->state.ycbcr_enc = pix_mp->ycbcr_enc; + ctx->state.quantization = pix_mp->quantization; break; default: break; @@ -962,7 +832,7 @@ static int vicodec_enum_framesizes(struct file *file, void *fh, case V4L2_PIX_FMT_FWHT: break; default: - if (find_fmt(fsize->pixel_format) == fsize->pixel_format) + if (find_fmt(fsize->pixel_format)->id == fsize->pixel_format) break; return -EINVAL; } @@ -1119,30 +989,35 @@ static int vicodec_start_streaming(struct vb2_queue *q, { struct vicodec_ctx *ctx = vb2_get_drv_priv(q); struct vicodec_q_data *q_data = get_q_data(ctx, q->type); + struct v4l2_fwht_state *state = &ctx->state; unsigned int size = q_data->width * q_data->height; + const struct v4l2_fwht_pixfmt_info *info = q_data->info; + unsigned int chroma_div = info->width_div * info->height_div; q_data->sequence = 0; if (!V4L2_TYPE_IS_OUTPUT(q->type)) return 0; - ctx->ref_frame.width = ctx->ref_frame.height = 0; - ctx->ref_frame.luma = kvmalloc(size * 3 / 2, GFP_KERNEL); - ctx->comp_max_size = size * 3 / 2 + sizeof(struct cframe_hdr); - ctx->compressed_frame = kvmalloc(ctx->comp_max_size, GFP_KERNEL); - if (!ctx->ref_frame.luma || !ctx->compressed_frame) { - kvfree(ctx->ref_frame.luma); - kvfree(ctx->compressed_frame); + state->width = q_data->width; + state->height = q_data->height; + state->ref_frame.width = state->ref_frame.height = 0; + state->ref_frame.luma = kvmalloc(size + 2 * size / chroma_div, + GFP_KERNEL); + ctx->comp_max_size = size + 2 * size / chroma_div + + sizeof(struct fwht_cframe_hdr); + state->compressed_frame = kvmalloc(ctx->comp_max_size, GFP_KERNEL); + if (!state->ref_frame.luma || !state->compressed_frame) { + kvfree(state->ref_frame.luma); + kvfree(state->compressed_frame); vicodec_return_bufs(q, VB2_BUF_STATE_QUEUED); return -ENOMEM; } - ctx->ref_frame.cb = ctx->ref_frame.luma + size; - ctx->ref_frame.cr = ctx->ref_frame.cb + size / 4; + state->ref_frame.cb = state->ref_frame.luma + size; + state->ref_frame.cr = state->ref_frame.cb + size / chroma_div; ctx->last_src_buf = NULL; ctx->last_dst_buf = NULL; - v4l2_ctrl_grab(ctx->ctrl_gop_size, true); - ctx->gop_size = v4l2_ctrl_g_ctrl(ctx->ctrl_gop_size); - ctx->gop_cnt = 0; + state->gop_cnt = 0; ctx->cur_buf_offset = 0; ctx->comp_size = 0; ctx->comp_magic_cnt = 0; @@ -1160,9 +1035,8 @@ static void vicodec_stop_streaming(struct vb2_queue *q) if (!V4L2_TYPE_IS_OUTPUT(q->type)) return; - kvfree(ctx->ref_frame.luma); - kvfree(ctx->compressed_frame); - v4l2_ctrl_grab(ctx->ctrl_gop_size, false); + kvfree(ctx->state.ref_frame.luma); + kvfree(ctx->state.compressed_frame); } static const struct vb2_ops vicodec_qops = { @@ -1211,6 +1085,55 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, return vb2_queue_init(dst_vq); } +#define VICODEC_CID_CUSTOM_BASE (V4L2_CID_MPEG_BASE | 0xf000) +#define VICODEC_CID_I_FRAME_QP (VICODEC_CID_CUSTOM_BASE + 0) +#define VICODEC_CID_P_FRAME_QP (VICODEC_CID_CUSTOM_BASE + 1) + +static int vicodec_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct vicodec_ctx *ctx = container_of(ctrl->handler, + struct vicodec_ctx, hdl); + + switch (ctrl->id) { + case V4L2_CID_MPEG_VIDEO_GOP_SIZE: + ctx->state.gop_size = ctrl->val; + return 0; + case VICODEC_CID_I_FRAME_QP: + ctx->state.i_frame_qp = ctrl->val; + return 0; + case VICODEC_CID_P_FRAME_QP: + ctx->state.p_frame_qp = ctrl->val; + return 0; + } + return -EINVAL; +} + +static struct v4l2_ctrl_ops vicodec_ctrl_ops = { + .s_ctrl = vicodec_s_ctrl, +}; + +static const struct v4l2_ctrl_config vicodec_ctrl_i_frame = { + .ops = &vicodec_ctrl_ops, + .id = VICODEC_CID_I_FRAME_QP, + .name = "FWHT I-Frame QP Value", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 1, + .max = 31, + .def = 20, + .step = 1, +}; + +static const struct v4l2_ctrl_config vicodec_ctrl_p_frame = { + .ops = &vicodec_ctrl_ops, + .id = VICODEC_CID_P_FRAME_QP, + .name = "FWHT P-Frame QP Value", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 1, + .max = 31, + .def = 20, + .step = 1, +}; + /* * File operations */ @@ -1239,9 +1162,10 @@ static int vicodec_open(struct file *file) ctx->dev = dev; hdl = &ctx->hdl; v4l2_ctrl_handler_init(hdl, 4); - ctx->ctrl_gop_size = v4l2_ctrl_new_std(hdl, NULL, - V4L2_CID_MPEG_VIDEO_GOP_SIZE, - 1, 16, 1, 10); + v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_MPEG_VIDEO_GOP_SIZE, + 1, 16, 1, 10); + v4l2_ctrl_new_custom(hdl, &vicodec_ctrl_i_frame, NULL); + v4l2_ctrl_new_custom(hdl, &vicodec_ctrl_p_frame, NULL); if (hdl->error) { rc = hdl->error; v4l2_ctrl_handler_free(hdl); @@ -1251,25 +1175,34 @@ static int vicodec_open(struct file *file) ctx->fh.ctrl_handler = hdl; v4l2_ctrl_handler_setup(hdl); - ctx->q_data[V4L2_M2M_SRC].fourcc = - ctx->is_enc ? V4L2_PIX_FMT_YUV420 : V4L2_PIX_FMT_FWHT; + ctx->q_data[V4L2_M2M_SRC].info = + ctx->is_enc ? v4l2_fwht_get_pixfmt(0) : &pixfmt_fwht; ctx->q_data[V4L2_M2M_SRC].width = 1280; ctx->q_data[V4L2_M2M_SRC].height = 720; - size = 1280 * 720 * 3 / 2; - ctx->q_data[V4L2_M2M_SRC].sizeimage = size; + size = 1280 * 720 * ctx->q_data[V4L2_M2M_SRC].info->sizeimage_mult / + ctx->q_data[V4L2_M2M_SRC].info->sizeimage_div; + if (ctx->is_enc) + ctx->q_data[V4L2_M2M_SRC].sizeimage = size; + else + ctx->q_data[V4L2_M2M_SRC].sizeimage = + size + sizeof(struct fwht_cframe_hdr); ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC]; - ctx->q_data[V4L2_M2M_DST].fourcc = - ctx->is_enc ? V4L2_PIX_FMT_FWHT : V4L2_PIX_FMT_YUV420; - ctx->colorspace = V4L2_COLORSPACE_REC709; + ctx->q_data[V4L2_M2M_DST].info = + ctx->is_enc ? &pixfmt_fwht : v4l2_fwht_get_pixfmt(0); + size = 1280 * 720 * ctx->q_data[V4L2_M2M_DST].info->sizeimage_mult / + ctx->q_data[V4L2_M2M_DST].info->sizeimage_div; + if (ctx->is_enc) + ctx->q_data[V4L2_M2M_DST].sizeimage = + size + sizeof(struct fwht_cframe_hdr); + else + ctx->q_data[V4L2_M2M_DST].sizeimage = size; + ctx->state.colorspace = V4L2_COLORSPACE_REC709; - size += sizeof(struct cframe_hdr); if (ctx->is_enc) { - ctx->q_data[V4L2_M2M_DST].sizeimage = size; ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->enc_dev, ctx, &queue_init); ctx->lock = &dev->enc_lock; } else { - ctx->q_data[V4L2_M2M_SRC].sizeimage = size; ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->dec_dev, ctx, &queue_init); ctx->lock = &dev->dec_lock; @@ -1327,7 +1260,6 @@ static const struct video_device vicodec_videodev = { static const struct v4l2_m2m_ops m2m_ops = { .device_run = device_run, - .job_abort = job_abort, .job_ready = job_ready, }; @@ -1350,7 +1282,7 @@ static int vicodec_probe(struct platform_device *pdev) #ifdef CONFIG_MEDIA_CONTROLLER dev->mdev.dev = &pdev->dev; - strlcpy(dev->mdev.model, "vicodec", sizeof(dev->mdev.model)); + strscpy(dev->mdev.model, "vicodec", sizeof(dev->mdev.model)); media_device_init(&dev->mdev); dev->v4l2_dev.mdev = &dev->mdev; #endif @@ -1378,7 +1310,7 @@ static int vicodec_probe(struct platform_device *pdev) vfd = &dev->enc_vfd; vfd->lock = &dev->enc_mutex; vfd->v4l2_dev = &dev->v4l2_dev; - strlcpy(vfd->name, "vicodec-enc", sizeof(vfd->name)); + strscpy(vfd->name, "vicodec-enc", sizeof(vfd->name)); v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD); v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD); video_set_drvdata(vfd, dev); @@ -1395,7 +1327,7 @@ static int vicodec_probe(struct platform_device *pdev) vfd = &dev->dec_vfd; vfd->lock = &dev->dec_mutex; vfd->v4l2_dev = &dev->v4l2_dev; - strlcpy(vfd->name, "vicodec-dec", sizeof(vfd->name)); + strscpy(vfd->name, "vicodec-dec", sizeof(vfd->name)); v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD); v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); video_set_drvdata(vfd, dev); diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c index c01e1592ad0a..c33900e3c23e 100644 --- a/drivers/media/platform/video-mux.c +++ b/drivers/media/platform/video-mux.c @@ -21,8 +21,10 @@ #include <linux/of.h> #include <linux/of_graph.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <media/v4l2-async.h> #include <media/v4l2-device.h> +#include <media/v4l2-fwnode.h> #include <media/v4l2-subdev.h> struct video_mux { @@ -316,6 +318,38 @@ static const struct v4l2_subdev_ops video_mux_subdev_ops = { .video = &video_mux_subdev_video_ops, }; +static int video_mux_parse_endpoint(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct v4l2_async_subdev *asd) +{ + /* + * it's not an error if remote is missing on a video-mux + * input port, return -ENOTCONN to skip this endpoint with + * no error. + */ + return fwnode_device_is_available(asd->match.fwnode) ? 0 : -ENOTCONN; +} + +static int video_mux_async_register(struct video_mux *vmux, + unsigned int num_input_pads) +{ + unsigned int i, *ports; + int ret; + + ports = kcalloc(num_input_pads, sizeof(*ports), GFP_KERNEL); + if (!ports) + return -ENOMEM; + for (i = 0; i < num_input_pads; i++) + ports[i] = i; + + ret = v4l2_async_register_fwnode_subdev( + &vmux->subdev, sizeof(struct v4l2_async_subdev), + ports, num_input_pads, video_mux_parse_endpoint); + + kfree(ports); + return ret; +} + static int video_mux_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -333,7 +367,7 @@ static int video_mux_probe(struct platform_device *pdev) platform_set_drvdata(pdev, vmux); v4l2_subdev_init(&vmux->subdev, &video_mux_subdev_ops); - snprintf(vmux->subdev.name, sizeof(vmux->subdev.name), "%s", np->name); + snprintf(vmux->subdev.name, sizeof(vmux->subdev.name), "%pOFn", np); vmux->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; vmux->subdev.dev = dev; @@ -383,7 +417,7 @@ static int video_mux_probe(struct platform_device *pdev) vmux->subdev.entity.ops = &video_mux_ops; - return v4l2_async_register_subdev(&vmux->subdev); + return video_mux_async_register(vmux, num_pads - 1); } static int video_mux_remove(struct platform_device *pdev) diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c index 462099a141e4..60c522ee2e03 100644 --- a/drivers/media/platform/vim2m.c +++ b/drivers/media/platform/vim2m.c @@ -1038,7 +1038,7 @@ static int vim2m_probe(struct platform_device *pdev) #ifdef CONFIG_MEDIA_CONTROLLER dev->mdev.dev = &pdev->dev; - strlcpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model)); + strscpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model)); media_device_init(&dev->mdev); dev->v4l2_dev.mdev = &dev->mdev; diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c index ec68feaac378..3f7e9ed56633 100644 --- a/drivers/media/platform/vimc/vimc-capture.c +++ b/drivers/media/platform/vimc/vimc-capture.c @@ -71,8 +71,8 @@ static int vimc_cap_querycap(struct file *file, void *priv, { struct vimc_cap_device *vcap = video_drvdata(file); - strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver)); - strlcpy(cap->card, KBUILD_MODNAME, sizeof(cap->card)); + strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver)); + strscpy(cap->card, KBUILD_MODNAME, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", vcap->vdev.v4l2_dev->name); @@ -476,7 +476,7 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master, vdev->queue = q; vdev->v4l2_dev = v4l2_dev; vdev->vfl_dir = VFL_DIR_RX; - strlcpy(vdev->name, pdata->entity_name, sizeof(vdev->name)); + strscpy(vdev->name, pdata->entity_name, sizeof(vdev->name)); video_set_drvdata(vdev, &vcap->ved); /* Register the video_device with the v4l2 and the media framework */ diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c index 617415c224fe..dee1b9dfc4f6 100644 --- a/drivers/media/platform/vimc/vimc-common.c +++ b/drivers/media/platform/vimc/vimc-common.c @@ -430,7 +430,7 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved, sd->entity.function = function; sd->entity.ops = &vimc_ent_sd_mops; sd->owner = THIS_MODULE; - strlcpy(sd->name, name, sizeof(sd->name)); + strscpy(sd->name, name, sizeof(sd->name)); v4l2_set_subdevdata(sd, ved); /* Expose this subdev to user space */ diff --git a/drivers/media/platform/vimc/vimc-core.c b/drivers/media/platform/vimc/vimc-core.c index 9246f265de31..ce809d2e3d53 100644 --- a/drivers/media/platform/vimc/vimc-core.c +++ b/drivers/media/platform/vimc/vimc-core.c @@ -259,7 +259,7 @@ static struct component_match *vimc_add_subdevs(struct vimc_device *vimc) dev_dbg(&vimc->pdev.dev, "new pdev for %s\n", vimc->pipe_cfg->ents[i].drv); - strlcpy(pdata.entity_name, vimc->pipe_cfg->ents[i].name, + strscpy(pdata.entity_name, vimc->pipe_cfg->ents[i].name, sizeof(pdata.entity_name)); vimc->subdevs[i] = platform_device_register_data(&vimc->pdev.dev, @@ -317,7 +317,7 @@ static int vimc_probe(struct platform_device *pdev) vimc->v4l2_dev.mdev = &vimc->mdev; /* Initialize media device */ - strlcpy(vimc->mdev.model, VIMC_MDEV_MODEL_NAME, + strscpy(vimc->mdev.model, VIMC_MDEV_MODEL_NAME, sizeof(vimc->mdev.model)); vimc->mdev.dev = &pdev->dev; media_device_init(&vimc->mdev); diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c index b2b89315e7ba..edf4c85ae63d 100644 --- a/drivers/media/platform/vimc/vimc-sensor.c +++ b/drivers/media/platform/vimc/vimc-sensor.c @@ -317,6 +317,18 @@ static int vimc_sen_s_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_VFLIP: tpg_s_vflip(&vsen->tpg, ctrl->val); break; + case V4L2_CID_BRIGHTNESS: + tpg_s_brightness(&vsen->tpg, ctrl->val); + break; + case V4L2_CID_CONTRAST: + tpg_s_contrast(&vsen->tpg, ctrl->val); + break; + case V4L2_CID_HUE: + tpg_s_hue(&vsen->tpg, ctrl->val); + break; + case V4L2_CID_SATURATION: + tpg_s_saturation(&vsen->tpg, ctrl->val); + break; default: return -EINVAL; } @@ -378,6 +390,14 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master, V4L2_CID_VFLIP, 0, 1, 1, 0); v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops, + V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); + v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops, + V4L2_CID_CONTRAST, 0, 255, 1, 128); + v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops, + V4L2_CID_HUE, -128, 127, 1, 0); + v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops, + V4L2_CID_SATURATION, 0, 255, 1, 128); vsen->sd.ctrl_handler = &vsen->hdl; if (vsen->hdl.error) { ret = vsen->hdl.error; diff --git a/drivers/media/platform/vivid/vivid-cec.c b/drivers/media/platform/vivid/vivid-cec.c index 71105fa4c5f9..4d822dbed972 100644 --- a/drivers/media/platform/vivid/vivid-cec.c +++ b/drivers/media/platform/vivid/vivid-cec.c @@ -241,11 +241,11 @@ static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg) cec_ops_set_osd_string(msg, &disp_ctl, osd); switch (disp_ctl) { case CEC_OP_DISP_CTL_DEFAULT: - strcpy(dev->osd, osd); + strscpy(dev->osd, osd, sizeof(dev->osd)); dev->osd_jiffies = jiffies; break; case CEC_OP_DISP_CTL_UNTIL_CLEARED: - strcpy(dev->osd, osd); + strscpy(dev->osd, osd, sizeof(dev->osd)); dev->osd_jiffies = 0; break; case CEC_OP_DISP_CTL_CLEAR: diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c index 31db363602e5..06961e7d8036 100644 --- a/drivers/media/platform/vivid/vivid-core.c +++ b/drivers/media/platform/vivid/vivid-core.c @@ -197,8 +197,8 @@ static int vidioc_querycap(struct file *file, void *priv, { struct vivid_dev *dev = video_drvdata(file); - strcpy(cap->driver, "vivid"); - strcpy(cap->card, "vivid"); + strscpy(cap->driver, "vivid", sizeof(cap->driver)); + strscpy(cap->card, "vivid", sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev->v4l2_dev.name); diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h index 477c80a4d44c..cd4c8230563c 100644 --- a/drivers/media/platform/vivid/vivid-core.h +++ b/drivers/media/platform/vivid/vivid-core.h @@ -111,7 +111,7 @@ enum vivid_colorspace { VIVID_CS_170M, VIVID_CS_709, VIVID_CS_SRGB, - VIVID_CS_ADOBERGB, + VIVID_CS_OPRGB, VIVID_CS_2020, VIVID_CS_DCI_P3, VIVID_CS_240M, diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c index 5429193fbb91..999aa101b150 100644 --- a/drivers/media/platform/vivid/vivid-ctrls.c +++ b/drivers/media/platform/vivid/vivid-ctrls.c @@ -348,7 +348,7 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) V4L2_COLORSPACE_SMPTE170M, V4L2_COLORSPACE_REC709, V4L2_COLORSPACE_SRGB, - V4L2_COLORSPACE_ADOBERGB, + V4L2_COLORSPACE_OPRGB, V4L2_COLORSPACE_BT2020, V4L2_COLORSPACE_DCI_P3, V4L2_COLORSPACE_SMPTE240M, @@ -729,7 +729,7 @@ static const char * const vivid_ctrl_colorspace_strings[] = { "SMPTE 170M", "Rec. 709", "sRGB", - "AdobeRGB", + "opRGB", "BT.2020", "DCI-P3", "SMPTE 240M", @@ -752,7 +752,7 @@ static const char * const vivid_ctrl_xfer_func_strings[] = { "Default", "Rec. 709", "sRGB", - "AdobeRGB", + "opRGB", "SMPTE 240M", "None", "DCI-P3", diff --git a/drivers/media/platform/vivid/vivid-osd.c b/drivers/media/platform/vivid/vivid-osd.c index bbbc1b6938a5..1a89593b0c86 100644 --- a/drivers/media/platform/vivid/vivid-osd.c +++ b/drivers/media/platform/vivid/vivid-osd.c @@ -110,7 +110,7 @@ static int vivid_fb_get_fix(struct vivid_dev *dev, struct fb_fix_screeninfo *fix { dprintk(dev, 1, "vivid_fb_get_fix\n"); memset(fix, 0, sizeof(struct fb_fix_screeninfo)); - strlcpy(fix->id, "vioverlay fb", sizeof(fix->id)); + strscpy(fix->id, "vioverlay fb", sizeof(fix->id)); fix->smem_start = dev->video_pbase; fix->smem_len = dev->video_buffer_size; fix->type = FB_TYPE_PACKED_PIXELS; diff --git a/drivers/media/platform/vivid/vivid-radio-common.c b/drivers/media/platform/vivid/vivid-radio-common.c index 7c8efe38ff5b..138c7bce68b1 100644 --- a/drivers/media/platform/vivid/vivid-radio-common.c +++ b/drivers/media/platform/vivid/vivid-radio-common.c @@ -76,10 +76,10 @@ void vivid_radio_rds_init(struct vivid_dev *dev) rds->ta = dev->radio_tx_rds_ta->cur.val; rds->tp = dev->radio_tx_rds_tp->cur.val; rds->ms = dev->radio_tx_rds_ms->cur.val; - strlcpy(rds->psname, + strscpy(rds->psname, dev->radio_tx_rds_psname->p_cur.p_char, sizeof(rds->psname)); - strlcpy(rds->radiotext, + strscpy(rds->radiotext, dev->radio_tx_rds_radiotext->p_cur.p_char + alt * 64, sizeof(rds->radiotext)); v4l2_ctrl_unlock(dev->radio_tx_rds_pi); diff --git a/drivers/media/platform/vivid/vivid-radio-rx.c b/drivers/media/platform/vivid/vivid-radio-rx.c index 1f86d7d4f72f..232cab508f48 100644 --- a/drivers/media/platform/vivid/vivid-radio-rx.c +++ b/drivers/media/platform/vivid/vivid-radio-rx.c @@ -223,7 +223,7 @@ int vivid_radio_rx_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) if (vt->index > 0) return -EINVAL; - strlcpy(vt->name, "AM/FM/SW Receiver", sizeof(vt->name)); + strscpy(vt->name, "AM/FM/SW Receiver", sizeof(vt->name)); vt->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_FREQ_BANDS | V4L2_TUNER_CAP_RDS | (dev->radio_rx_rds_controls ? diff --git a/drivers/media/platform/vivid/vivid-radio-tx.c b/drivers/media/platform/vivid/vivid-radio-tx.c index 1a3749ba5e7e..049d40b948bb 100644 --- a/drivers/media/platform/vivid/vivid-radio-tx.c +++ b/drivers/media/platform/vivid/vivid-radio-tx.c @@ -103,7 +103,7 @@ int vidioc_g_modulator(struct file *file, void *fh, struct v4l2_modulator *a) if (a->index > 0) return -EINVAL; - strlcpy(a->name, "AM/FM/SW Transmitter", sizeof(a->name)); + strscpy(a->name, "AM/FM/SW Transmitter", sizeof(a->name)); a->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_FREQ_BANDS | V4L2_TUNER_CAP_RDS | (dev->radio_tx_rds_controls ? diff --git a/drivers/media/platform/vivid/vivid-rds-gen.c b/drivers/media/platform/vivid/vivid-rds-gen.c index 39ca9a56448c..b5b104ee64c9 100644 --- a/drivers/media/platform/vivid/vivid-rds-gen.c +++ b/drivers/media/platform/vivid/vivid-rds-gen.c @@ -147,11 +147,11 @@ void vivid_rds_gen_fill(struct vivid_rds_gen *rds, unsigned freq, snprintf(rds->psname, sizeof(rds->psname), "%6d.%1d", freq / 16, ((freq & 0xf) * 10) / 16); if (alt) - strlcpy(rds->radiotext, + strscpy(rds->radiotext, " The Radio Data System can switch between different Radio Texts ", sizeof(rds->radiotext)); else - strlcpy(rds->radiotext, + strscpy(rds->radiotext, "An example of Radio Text as transmitted by the Radio Data System", sizeof(rds->radiotext)); } diff --git a/drivers/media/platform/vivid/vivid-sdr-cap.c b/drivers/media/platform/vivid/vivid-sdr-cap.c index cfb7cb4d37a8..200b789a3f21 100644 --- a/drivers/media/platform/vivid/vivid-sdr-cap.c +++ b/drivers/media/platform/vivid/vivid-sdr-cap.c @@ -396,7 +396,7 @@ int vivid_sdr_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) { switch (vt->index) { case 0: - strlcpy(vt->name, "ADC", sizeof(vt->name)); + strscpy(vt->name, "ADC", sizeof(vt->name)); vt->type = V4L2_TUNER_ADC; vt->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS; @@ -404,7 +404,7 @@ int vivid_sdr_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) vt->rangehigh = bands_adc[2].rangehigh; return 0; case 1: - strlcpy(vt->name, "RF", sizeof(vt->name)); + strscpy(vt->name, "RF", sizeof(vt->name)); vt->type = V4L2_TUNER_RF; vt->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS; diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c index 1599159f2574..6cf910a60ecf 100644 --- a/drivers/media/platform/vivid/vivid-vid-cap.c +++ b/drivers/media/platform/vivid/vivid-vid-cap.c @@ -51,7 +51,7 @@ static const struct vivid_fmt formats_ovl[] = { }; /* The number of discrete webcam framesizes */ -#define VIVID_WEBCAM_SIZES 5 +#define VIVID_WEBCAM_SIZES 6 /* The number of discrete webcam frameintervals */ #define VIVID_WEBCAM_IVALS (VIVID_WEBCAM_SIZES * 2) @@ -59,6 +59,7 @@ static const struct vivid_fmt formats_ovl[] = { static const struct v4l2_frmsize_discrete webcam_sizes[VIVID_WEBCAM_SIZES] = { { 320, 180 }, { 640, 360 }, + { 640, 480 }, { 1280, 720 }, { 1920, 1080 }, { 3840, 2160 }, @@ -74,9 +75,11 @@ static const struct v4l2_fract webcam_intervals[VIVID_WEBCAM_IVALS] = { { 1, 4 }, { 1, 5 }, { 1, 10 }, + { 2, 25 }, { 1, 15 }, { 1, 25 }, { 1, 30 }, + { 1, 40 }, { 1, 50 }, { 1, 60 }, }; @@ -1505,7 +1508,7 @@ int vivid_video_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) break; } } - strlcpy(vt->name, "TV Tuner", sizeof(vt->name)); + strscpy(vt->name, "TV Tuner", sizeof(vt->name)); return 0; } @@ -1722,7 +1725,7 @@ int vidioc_s_edid(struct file *file, void *_fh, return -E2BIG; } phys_addr = cec_get_edid_phys_addr(edid->edid, edid->blocks * 128, NULL); - ret = cec_phys_addr_validate(phys_addr, &phys_addr, NULL); + ret = v4l2_phys_addr_validate(phys_addr, &phys_addr, NULL); if (ret) return ret; @@ -1738,7 +1741,7 @@ set_phys_addr: for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++) cec_s_phys_addr(dev->cec_tx_adap[i], - cec_phys_addr_for_input(phys_addr, i + 1), + v4l2_phys_addr_for_input(phys_addr, i + 1), false); return 0; } diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c index be531caa2cdf..9645a91b8782 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c @@ -450,6 +450,34 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { + .fourcc = V4L2_PIX_FMT_SBGGR16, /* Bayer BG/GR */ + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .planes = 1, + .buffers = 1, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG16, /* Bayer GB/RG */ + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .planes = 1, + .buffers = 1, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG16, /* Bayer GR/BG */ + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .planes = 1, + .buffers = 1, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB16, /* Bayer RG/GB */ + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .planes = 1, + .buffers = 1, + }, + { .fourcc = V4L2_PIX_FMT_HSV24, /* HSV 24bits */ .color_enc = TGP_COLOR_ENC_HSV, .vdownsampling = { 1 }, @@ -863,7 +891,7 @@ int vidioc_g_edid(struct file *file, void *_fh, if (edid->blocks > dev->edid_blocks - edid->start_block) edid->blocks = dev->edid_blocks - edid->start_block; if (adap) - cec_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr); + v4l2_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr); memcpy(edid->edid, dev->edid + edid->start_block * 128, edid->blocks * 128); return 0; } diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c index 51fec66d8d45..50248e2176a0 100644 --- a/drivers/media/platform/vivid/vivid-vid-out.c +++ b/drivers/media/platform/vivid/vivid-vid-out.c @@ -413,7 +413,7 @@ int vivid_try_fmt_vid_out(struct file *file, void *priv, mp->colorspace = V4L2_COLORSPACE_SMPTE170M; } else if (mp->colorspace != V4L2_COLORSPACE_SMPTE170M && mp->colorspace != V4L2_COLORSPACE_REC709 && - mp->colorspace != V4L2_COLORSPACE_ADOBERGB && + mp->colorspace != V4L2_COLORSPACE_OPRGB && mp->colorspace != V4L2_COLORSPACE_BT2020 && mp->colorspace != V4L2_COLORSPACE_SRGB) { mp->colorspace = V4L2_COLORSPACE_REC709; diff --git a/drivers/media/platform/vsp1/vsp1_brx.c b/drivers/media/platform/vsp1/vsp1_brx.c index 359917b5d842..5e50178b057d 100644 --- a/drivers/media/platform/vsp1/vsp1_brx.c +++ b/drivers/media/platform/vsp1/vsp1_brx.c @@ -153,7 +153,7 @@ static int brx_set_format(struct v4l2_subdev *subdev, format = vsp1_entity_get_pad_format(&brx->entity, config, fmt->pad); *format = fmt->format; - /* Reset the compose rectangle */ + /* Reset the compose rectangle. */ if (fmt->pad != brx->entity.source_pad) { struct v4l2_rect *compose; @@ -164,7 +164,7 @@ static int brx_set_format(struct v4l2_subdev *subdev, compose->height = format->height; } - /* Propagate the format code to all pads */ + /* Propagate the format code to all pads. */ if (fmt->pad == BRX_PAD_SINK(0)) { unsigned int i; diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index b9c0f695d002..8d86f618ec77 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -770,6 +770,7 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index, struct vsp1_device *vsp1 = dev_get_drvdata(dev); struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index]; const struct vsp1_format_info *fmtinfo; + unsigned int chroma_hsub; struct vsp1_rwpf *rpf; if (rpf_index >= vsp1->info->rpf_count) @@ -810,10 +811,18 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index, return -EINVAL; } + /* + * Only formats with three planes can affect the chroma planes pitch. + * All formats with two planes have a horizontal subsampling value of 2, + * but combine U and V in a single chroma plane, which thus results in + * the luma plane and chroma plane having the same pitch. + */ + chroma_hsub = (fmtinfo->planes == 3) ? fmtinfo->hsub : 1; + rpf->fmtinfo = fmtinfo; rpf->format.num_planes = fmtinfo->planes; rpf->format.plane_fmt[0].bytesperline = cfg->pitch; - rpf->format.plane_fmt[1].bytesperline = cfg->pitch; + rpf->format.plane_fmt[1].bytesperline = cfg->pitch / chroma_hsub; rpf->alpha = cfg->alpha; rpf->mem.addr[0] = cfg->mem[0]; diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index b6619c9c18bb..c650e45bb0ad 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -242,7 +242,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) mdev->dev = vsp1->dev; mdev->hw_revision = vsp1->version; - strlcpy(mdev->model, vsp1->info->model, sizeof(mdev->model)); + strscpy(mdev->model, vsp1->info->model, sizeof(mdev->model)); snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s", dev_name(mdev->dev)); media_device_init(mdev); @@ -802,7 +802,7 @@ static int vsp1_probe(struct platform_device *pdev) platform_set_drvdata(pdev, vsp1); - /* I/O and IRQ resources (clock managed by the clock PM domain) */ + /* I/O and IRQ resources (clock managed by the clock PM domain). */ io = platform_get_resource(pdev, IORESOURCE_MEM, 0); vsp1->mmio = devm_ioremap_resource(&pdev->dev, io); if (IS_ERR(vsp1->mmio)) @@ -821,7 +821,7 @@ static int vsp1_probe(struct platform_device *pdev) return ret; } - /* FCP (optional) */ + /* FCP (optional). */ fcp_node = of_parse_phandle(pdev->dev.of_node, "renesas,fcp", 0); if (fcp_node) { vsp1->fcp = rcar_fcp_get(fcp_node); @@ -869,7 +869,7 @@ static int vsp1_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "IP version 0x%08x\n", vsp1->version); - /* Instanciate entities */ + /* Instantiate entities. */ ret = vsp1_create_entities(vsp1); if (ret < 0) { dev_err(&pdev->dev, "failed to create entities\n"); diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c index 36a29e13109e..a54ab528b060 100644 --- a/drivers/media/platform/vsp1/vsp1_entity.c +++ b/drivers/media/platform/vsp1/vsp1_entity.c @@ -404,7 +404,7 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev, format = vsp1_entity_get_pad_format(entity, config, entity->source_pad); *format = fmt->format; - /* Reset the crop and compose rectangles */ + /* Reset the crop and compose rectangles. */ selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad, V4L2_SEL_TGT_CROP); selection->left = 0; diff --git a/drivers/media/platform/vsp1/vsp1_histo.c b/drivers/media/platform/vsp1/vsp1_histo.c index 5e15c8ff88d9..8b01e99acd20 100644 --- a/drivers/media/platform/vsp1/vsp1_histo.c +++ b/drivers/media/platform/vsp1/vsp1_histo.c @@ -429,8 +429,8 @@ static int histo_v4l2_querycap(struct file *file, void *fh, cap->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING; - strlcpy(cap->driver, "vsp1", sizeof(cap->driver)); - strlcpy(cap->card, histo->video.name, sizeof(cap->card)); + strscpy(cap->driver, "vsp1", sizeof(cap->driver)); + strscpy(cap->card, histo->video.name, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(histo->entity.vsp1->dev)); diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c index 0cb63244b21a..0b18f0bd7419 100644 --- a/drivers/media/platform/vsp1/vsp1_lif.c +++ b/drivers/media/platform/vsp1/vsp1_lif.c @@ -88,14 +88,35 @@ static void lif_configure_stream(struct vsp1_entity *entity, { const struct v4l2_mbus_framefmt *format; struct vsp1_lif *lif = to_lif(&entity->subdev); - unsigned int hbth = 1300; - unsigned int obth = 400; - unsigned int lbth = 200; + unsigned int hbth; + unsigned int obth; + unsigned int lbth; format = vsp1_entity_get_pad_format(&lif->entity, lif->entity.config, LIF_PAD_SOURCE); - obth = min(obth, (format->width + 1) / 2 * format->height - 4); + switch (entity->vsp1->version & VI6_IP_VERSION_SOC_MASK) { + case VI6_IP_VERSION_MODEL_VSPD_GEN2: + case VI6_IP_VERSION_MODEL_VSPD_V2H: + hbth = 1536; + obth = min(128U, (format->width + 1) / 2 * format->height - 4); + lbth = 1520; + break; + + case VI6_IP_VERSION_MODEL_VSPDL_GEN3: + case VI6_IP_VERSION_MODEL_VSPD_V3: + hbth = 0; + obth = 1500; + lbth = 0; + break; + + case VI6_IP_VERSION_MODEL_VSPD_GEN3: + default: + hbth = 0; + obth = 3000; + lbth = 0; + break; + } vsp1_lif_write(lif, dlb, VI6_LIF_CSBTH, (hbth << VI6_LIF_CSBTH_HBTH_SHIFT) | diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h index 3738ff2f7b85..f6e4157095cc 100644 --- a/drivers/media/platform/vsp1/vsp1_regs.h +++ b/drivers/media/platform/vsp1/vsp1_regs.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * vsp1_regs.h -- R-Car VSP1 Registers Definitions * diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c index f8005b60b9d2..616afa7e165f 100644 --- a/drivers/media/platform/vsp1/vsp1_rpf.c +++ b/drivers/media/platform/vsp1/vsp1_rpf.c @@ -108,7 +108,7 @@ static void rpf_configure_stream(struct vsp1_entity *entity, vsp1_rpf_write(rpf, dlb, VI6_RPF_INFMT, infmt); vsp1_rpf_write(rpf, dlb, VI6_RPF_DSWAP, fmtinfo->swap); - /* Output location */ + /* Output location. */ if (pipe->brx) { const struct v4l2_rect *compose; @@ -309,7 +309,7 @@ static void rpf_configure_partition(struct vsp1_entity *entity, /* * Interlaced pipelines will use the extended pre-cmd to process - * SRCM_ADDR_{Y,C0,C1} + * SRCM_ADDR_{Y,C0,C1}. */ if (pipe->interlaced) { vsp1_rpf_configure_autofld(rpf, dl); diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c index 04e4e05af6ae..b1617cb1f2b9 100644 --- a/drivers/media/platform/vsp1/vsp1_sru.c +++ b/drivers/media/platform/vsp1/vsp1_sru.c @@ -312,6 +312,11 @@ static unsigned int sru_max_width(struct vsp1_entity *entity, output = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config, SRU_PAD_SOURCE); + /* + * The maximum input width of the SRU is 288 input pixels, but 32 + * pixels are reserved to support overlapping partition windows when + * scaling. + */ if (input->width != output->width) return 512; else @@ -333,7 +338,7 @@ static void sru_partition(struct vsp1_entity *entity, output = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config, SRU_PAD_SOURCE); - /* Adapt if SRUx2 is enabled */ + /* Adapt if SRUx2 is enabled. */ if (input->width != output->width) { window->width /= 2; window->left /= 2; diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c index c20c84b54936..27012af973b2 100644 --- a/drivers/media/platform/vsp1/vsp1_uds.c +++ b/drivers/media/platform/vsp1/vsp1_uds.c @@ -314,13 +314,13 @@ static void uds_configure_partition(struct vsp1_entity *entity, output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config, UDS_PAD_SOURCE); - /* Input size clipping */ + /* Input size clipping. */ vsp1_uds_write(uds, dlb, VI6_UDS_HSZCLIP, VI6_UDS_HSZCLIP_HCEN | (0 << VI6_UDS_HSZCLIP_HCL_OFST_SHIFT) | (partition->uds_sink.width << VI6_UDS_HSZCLIP_HCL_SIZE_SHIFT)); - /* Output size clipping */ + /* Output size clipping. */ vsp1_uds_write(uds, dlb, VI6_UDS_CLIP_SIZE, (partition->uds_source.width << VI6_UDS_CLIP_SIZE_HSIZE_SHIFT) | @@ -342,6 +342,14 @@ static unsigned int uds_max_width(struct vsp1_entity *entity, UDS_PAD_SOURCE); hscale = output->width / input->width; + /* + * The maximum width of the UDS is 304 pixels. These are input pixels + * in the event of up-scaling, and output pixels in the event of + * downscaling. + * + * To support overlapping partition windows we clamp at units of 256 and + * the remaining pixels are reserved. + */ if (hscale <= 2) return 256; else if (hscale <= 4) @@ -366,7 +374,7 @@ static void uds_partition(struct vsp1_entity *entity, const struct v4l2_mbus_framefmt *output; const struct v4l2_mbus_framefmt *input; - /* Initialise the partition state */ + /* Initialise the partition state. */ partition->uds_sink = *window; partition->uds_source = *window; diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 81d47a09d7bc..771dfe1f7c20 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -38,9 +38,7 @@ #define VSP1_VIDEO_DEF_WIDTH 1024 #define VSP1_VIDEO_DEF_HEIGHT 768 -#define VSP1_VIDEO_MIN_WIDTH 2U #define VSP1_VIDEO_MAX_WIDTH 8190U -#define VSP1_VIDEO_MIN_HEIGHT 2U #define VSP1_VIDEO_MAX_HEIGHT 8190U /* ----------------------------------------------------------------------------- @@ -136,9 +134,8 @@ static int __vsp1_video_try_format(struct vsp1_video *video, height = round_down(height, info->vsub); /* Clamp the width and height. */ - pix->width = clamp(width, VSP1_VIDEO_MIN_WIDTH, VSP1_VIDEO_MAX_WIDTH); - pix->height = clamp(height, VSP1_VIDEO_MIN_HEIGHT, - VSP1_VIDEO_MAX_HEIGHT); + pix->width = clamp(width, info->hsub, VSP1_VIDEO_MAX_WIDTH); + pix->height = clamp(height, info->vsub, VSP1_VIDEO_MAX_HEIGHT); /* * Compute and clamp the stride and image size. While not documented in @@ -867,7 +864,7 @@ static void vsp1_video_cleanup_pipeline(struct vsp1_pipeline *pipe) pipe->stream_config = NULL; pipe->configured = false; - /* Release our partition table allocation */ + /* Release our partition table allocation. */ kfree(pipe->part_table); pipe->part_table = NULL; } @@ -976,8 +973,8 @@ vsp1_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap) cap->device_caps = V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_STREAMING; - strlcpy(cap->driver, "vsp1", sizeof(cap->driver)); - strlcpy(cap->card, video->video.name, sizeof(cap->card)); + strscpy(cap->driver, "vsp1", sizeof(cap->driver)); + strscpy(cap->card, video->video.name, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(video->vsp1->dev)); diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c index c2a1a7f97e26..32bb207b2007 100644 --- a/drivers/media/platform/vsp1/vsp1_wpf.c +++ b/drivers/media/platform/vsp1/vsp1_wpf.c @@ -317,7 +317,7 @@ static void wpf_configure_stream(struct vsp1_entity *entity, vsp1_wpf_write(wpf, dlb, VI6_WPF_SRCRPF, srcrpf); - /* Enable interrupts */ + /* Enable interrupts. */ vsp1_dl_body_write(dlb, VI6_WPF_IRQ_STA(wpf->entity.index), 0); vsp1_dl_body_write(dlb, VI6_WPF_IRQ_ENB(wpf->entity.index), VI6_WFP_IRQ_ENB_DFEE); diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index d041f94be832..4ae9d38c9433 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -504,10 +504,10 @@ xvip_dma_querycap(struct file *file, void *fh, struct v4l2_capability *cap) cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS | dma->xdev->v4l2_caps; - strlcpy(cap->driver, "xilinx-vipp", sizeof(cap->driver)); - strlcpy(cap->card, dma->video.name, sizeof(cap->card)); - snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s:%u", - dma->xdev->dev->of_node->name, dma->port); + strscpy(cap->driver, "xilinx-vipp", sizeof(cap->driver)); + strscpy(cap->card, dma->video.name, sizeof(cap->card)); + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%pOFn:%u", + dma->xdev->dev->of_node, dma->port); return 0; } @@ -527,7 +527,7 @@ xvip_dma_enum_format(struct file *file, void *fh, struct v4l2_fmtdesc *f) return -EINVAL; f->pixelformat = dma->format.pixelformat; - strlcpy(f->description, dma->fmtinfo->description, + strscpy(f->description, dma->fmtinfo->description, sizeof(f->description)); return 0; @@ -693,8 +693,8 @@ int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma, dma->video.fops = &xvip_dma_fops; dma->video.v4l2_dev = &xdev->v4l2_dev; dma->video.queue = &dma->queue; - snprintf(dma->video.name, sizeof(dma->video.name), "%s %s %u", - xdev->dev->of_node->name, + snprintf(dma->video.name, sizeof(dma->video.name), "%pOFn %s %u", + xdev->dev->of_node, type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? "output" : "input", port); dma->video.vfl_type = VFL_TYPE_GRABBER; diff --git a/drivers/media/platform/xilinx/xilinx-tpg.c b/drivers/media/platform/xilinx/xilinx-tpg.c index 9c49d1d10bee..851d20dcd550 100644 --- a/drivers/media/platform/xilinx/xilinx-tpg.c +++ b/drivers/media/platform/xilinx/xilinx-tpg.c @@ -833,7 +833,7 @@ static int xtpg_probe(struct platform_device *pdev) v4l2_subdev_init(subdev, &xtpg_ops); subdev->dev = &pdev->dev; subdev->internal_ops = &xtpg_internal_ops; - strlcpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name)); + strscpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name)); v4l2_set_subdevdata(subdev, xtpg); subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; subdev->entity.ops = &xtpg_media_ops; diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c index 6d95ec1e9a6b..99e016d35d91 100644 --- a/drivers/media/platform/xilinx/xilinx-vipp.c +++ b/drivers/media/platform/xilinx/xilinx-vipp.c @@ -32,33 +32,36 @@ /** * struct xvip_graph_entity - Entity in the video graph - * @list: list entry in a graph entities list - * @node: the entity's DT node - * @entity: media entity, from the corresponding V4L2 subdev * @asd: subdev asynchronous registration information + * @entity: media entity, from the corresponding V4L2 subdev * @subdev: V4L2 subdev */ struct xvip_graph_entity { - struct list_head list; - struct device_node *node; + struct v4l2_async_subdev asd; /* must be first */ struct media_entity *entity; - - struct v4l2_async_subdev asd; struct v4l2_subdev *subdev; }; +static inline struct xvip_graph_entity * +to_xvip_entity(struct v4l2_async_subdev *asd) +{ + return container_of(asd, struct xvip_graph_entity, asd); +} + /* ----------------------------------------------------------------------------- * Graph Management */ static struct xvip_graph_entity * xvip_graph_find_entity(struct xvip_composite_device *xdev, - const struct device_node *node) + const struct fwnode_handle *fwnode) { struct xvip_graph_entity *entity; + struct v4l2_async_subdev *asd; - list_for_each_entry(entity, &xdev->entities, list) { - if (entity->node == node) + list_for_each_entry(asd, &xdev->notifier.asd_list, asd_list) { + entity = to_xvip_entity(asd); + if (entity->asd.match.fwnode == fwnode) return entity; } @@ -75,22 +78,23 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev, struct media_pad *remote_pad; struct xvip_graph_entity *ent; struct v4l2_fwnode_link link; - struct device_node *ep = NULL; + struct fwnode_handle *ep = NULL; int ret = 0; dev_dbg(xdev->dev, "creating links for entity %s\n", local->name); while (1) { /* Get the next endpoint and parse its link. */ - ep = of_graph_get_next_endpoint(entity->node, ep); + ep = fwnode_graph_get_next_endpoint(entity->asd.match.fwnode, + ep); if (ep == NULL) break; - dev_dbg(xdev->dev, "processing endpoint %pOF\n", ep); + dev_dbg(xdev->dev, "processing endpoint %p\n", ep); - ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link); + ret = v4l2_fwnode_parse_link(ep, &link); if (ret < 0) { - dev_err(xdev->dev, "failed to parse link for %pOF\n", + dev_err(xdev->dev, "failed to parse link for %p\n", ep); continue; } @@ -99,9 +103,8 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev, * the link. */ if (link.local_port >= local->num_pads) { - dev_err(xdev->dev, "invalid port number %u for %pOF\n", - link.local_port, - to_of_node(link.local_node)); + dev_err(xdev->dev, "invalid port number %u for %p\n", + link.local_port, link.local_node); v4l2_fwnode_put_link(&link); ret = -EINVAL; break; @@ -110,28 +113,25 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev, local_pad = &local->pads[link.local_port]; if (local_pad->flags & MEDIA_PAD_FL_SINK) { - dev_dbg(xdev->dev, "skipping sink port %pOF:%u\n", - to_of_node(link.local_node), - link.local_port); + dev_dbg(xdev->dev, "skipping sink port %p:%u\n", + link.local_node, link.local_port); v4l2_fwnode_put_link(&link); continue; } /* Skip DMA engines, they will be processed separately. */ if (link.remote_node == of_fwnode_handle(xdev->dev->of_node)) { - dev_dbg(xdev->dev, "skipping DMA port %pOF:%u\n", - to_of_node(link.local_node), - link.local_port); + dev_dbg(xdev->dev, "skipping DMA port %p:%u\n", + link.local_node, link.local_port); v4l2_fwnode_put_link(&link); continue; } /* Find the remote entity. */ - ent = xvip_graph_find_entity(xdev, - to_of_node(link.remote_node)); + ent = xvip_graph_find_entity(xdev, link.remote_node); if (ent == NULL) { - dev_err(xdev->dev, "no entity found for %pOF\n", - to_of_node(link.remote_node)); + dev_err(xdev->dev, "no entity found for %p\n", + link.remote_node); v4l2_fwnode_put_link(&link); ret = -ENODEV; break; @@ -140,8 +140,8 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev, remote = ent->entity; if (link.remote_port >= remote->num_pads) { - dev_err(xdev->dev, "invalid port number %u on %pOF\n", - link.remote_port, to_of_node(link.remote_node)); + dev_err(xdev->dev, "invalid port number %u on %p\n", + link.remote_port, link.remote_node); v4l2_fwnode_put_link(&link); ret = -EINVAL; break; @@ -168,7 +168,7 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev, } } - of_node_put(ep); + fwnode_handle_put(ep); return ret; } @@ -230,8 +230,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev) dma->video.name); /* Find the remote entity. */ - ent = xvip_graph_find_entity(xdev, - to_of_node(link.remote_node)); + ent = xvip_graph_find_entity(xdev, link.remote_node); if (ent == NULL) { dev_err(xdev->dev, "no entity found for %pOF\n", to_of_node(link.remote_node)); @@ -289,12 +288,14 @@ static int xvip_graph_notify_complete(struct v4l2_async_notifier *notifier) struct xvip_composite_device *xdev = container_of(notifier, struct xvip_composite_device, notifier); struct xvip_graph_entity *entity; + struct v4l2_async_subdev *asd; int ret; dev_dbg(xdev->dev, "notify complete, all subdevs registered\n"); /* Create links for every entity. */ - list_for_each_entry(entity, &xdev->entities, list) { + list_for_each_entry(asd, &xdev->notifier.asd_list, asd_list) { + entity = to_xvip_entity(asd); ret = xvip_graph_build_one(xdev, entity); if (ret < 0) return ret; @@ -314,22 +315,25 @@ static int xvip_graph_notify_complete(struct v4l2_async_notifier *notifier) static int xvip_graph_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) + struct v4l2_async_subdev *unused) { struct xvip_composite_device *xdev = container_of(notifier, struct xvip_composite_device, notifier); struct xvip_graph_entity *entity; + struct v4l2_async_subdev *asd; /* Locate the entity corresponding to the bound subdev and store the * subdev pointer. */ - list_for_each_entry(entity, &xdev->entities, list) { - if (entity->node != subdev->dev->of_node) + list_for_each_entry(asd, &xdev->notifier.asd_list, asd_list) { + entity = to_xvip_entity(asd); + + if (entity->asd.match.fwnode != subdev->fwnode) continue; if (entity->subdev) { - dev_err(xdev->dev, "duplicate subdev for node %pOF\n", - entity->node); + dev_err(xdev->dev, "duplicate subdev for node %p\n", + entity->asd.match.fwnode); return -EINVAL; } @@ -349,56 +353,60 @@ static const struct v4l2_async_notifier_operations xvip_graph_notify_ops = { }; static int xvip_graph_parse_one(struct xvip_composite_device *xdev, - struct device_node *node) + struct fwnode_handle *fwnode) { - struct xvip_graph_entity *entity; - struct device_node *remote; - struct device_node *ep = NULL; + struct fwnode_handle *remote; + struct fwnode_handle *ep = NULL; int ret = 0; - dev_dbg(xdev->dev, "parsing node %pOF\n", node); + dev_dbg(xdev->dev, "parsing node %p\n", fwnode); while (1) { - ep = of_graph_get_next_endpoint(node, ep); + struct v4l2_async_subdev *asd; + + ep = fwnode_graph_get_next_endpoint(fwnode, ep); if (ep == NULL) break; - dev_dbg(xdev->dev, "handling endpoint %pOF\n", ep); + dev_dbg(xdev->dev, "handling endpoint %p\n", ep); - remote = of_graph_get_remote_port_parent(ep); + remote = fwnode_graph_get_remote_port_parent(ep); if (remote == NULL) { ret = -EINVAL; - break; + goto err_notifier_cleanup; } + fwnode_handle_put(ep); + /* Skip entities that we have already processed. */ - if (remote == xdev->dev->of_node || + if (remote == of_fwnode_handle(xdev->dev->of_node) || xvip_graph_find_entity(xdev, remote)) { - of_node_put(remote); + fwnode_handle_put(remote); continue; } - entity = devm_kzalloc(xdev->dev, sizeof(*entity), GFP_KERNEL); - if (entity == NULL) { - of_node_put(remote); - ret = -ENOMEM; - break; + asd = v4l2_async_notifier_add_fwnode_subdev( + &xdev->notifier, remote, + sizeof(struct xvip_graph_entity)); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); + fwnode_handle_put(remote); + goto err_notifier_cleanup; } - - entity->node = remote; - entity->asd.match_type = V4L2_ASYNC_MATCH_FWNODE; - entity->asd.match.fwnode = of_fwnode_handle(remote); - list_add_tail(&entity->list, &xdev->entities); - xdev->num_subdevs++; } - of_node_put(ep); + return 0; + +err_notifier_cleanup: + v4l2_async_notifier_cleanup(&xdev->notifier); + fwnode_handle_put(ep); return ret; } static int xvip_graph_parse(struct xvip_composite_device *xdev) { struct xvip_graph_entity *entity; + struct v4l2_async_subdev *asd; int ret; /* @@ -407,14 +415,17 @@ static int xvip_graph_parse(struct xvip_composite_device *xdev) * loop will handle entities added at the end of the list while walking * the links. */ - ret = xvip_graph_parse_one(xdev, xdev->dev->of_node); + ret = xvip_graph_parse_one(xdev, of_fwnode_handle(xdev->dev->of_node)); if (ret < 0) return 0; - list_for_each_entry(entity, &xdev->entities, list) { - ret = xvip_graph_parse_one(xdev, entity->node); - if (ret < 0) + list_for_each_entry(asd, &xdev->notifier.asd_list, asd_list) { + entity = to_xvip_entity(asd); + ret = xvip_graph_parse_one(xdev, entity->asd.match.fwnode); + if (ret < 0) { + v4l2_async_notifier_cleanup(&xdev->notifier); break; + } } return ret; @@ -485,17 +496,11 @@ static int xvip_graph_dma_init(struct xvip_composite_device *xdev) static void xvip_graph_cleanup(struct xvip_composite_device *xdev) { - struct xvip_graph_entity *entityp; - struct xvip_graph_entity *entity; struct xvip_dma *dmap; struct xvip_dma *dma; v4l2_async_notifier_unregister(&xdev->notifier); - - list_for_each_entry_safe(entity, entityp, &xdev->entities, list) { - of_node_put(entity->node); - list_del(&entity->list); - } + v4l2_async_notifier_cleanup(&xdev->notifier); list_for_each_entry_safe(dma, dmap, &xdev->dmas, list) { xvip_dma_cleanup(dma); @@ -505,10 +510,6 @@ static void xvip_graph_cleanup(struct xvip_composite_device *xdev) static int xvip_graph_init(struct xvip_composite_device *xdev) { - struct xvip_graph_entity *entity; - struct v4l2_async_subdev **subdevs = NULL; - unsigned int num_subdevs; - unsigned int i; int ret; /* Init the DMA channels. */ @@ -525,26 +526,12 @@ static int xvip_graph_init(struct xvip_composite_device *xdev) goto done; } - if (!xdev->num_subdevs) { + if (list_empty(&xdev->notifier.asd_list)) { dev_err(xdev->dev, "no subdev found in graph\n"); goto done; } /* Register the subdevices notifier. */ - num_subdevs = xdev->num_subdevs; - subdevs = devm_kcalloc(xdev->dev, num_subdevs, sizeof(*subdevs), - GFP_KERNEL); - if (subdevs == NULL) { - ret = -ENOMEM; - goto done; - } - - i = 0; - list_for_each_entry(entity, &xdev->entities, list) - subdevs[i++] = &entity->asd; - - xdev->notifier.subdevs = subdevs; - xdev->notifier.num_subdevs = num_subdevs; xdev->notifier.ops = &xvip_graph_notify_ops; ret = v4l2_async_notifier_register(&xdev->v4l2_dev, &xdev->notifier); @@ -578,7 +565,7 @@ static int xvip_composite_v4l2_init(struct xvip_composite_device *xdev) int ret; xdev->media_dev.dev = xdev->dev; - strlcpy(xdev->media_dev.model, "Xilinx Video Composite Device", + strscpy(xdev->media_dev.model, "Xilinx Video Composite Device", sizeof(xdev->media_dev.model)); xdev->media_dev.hw_revision = 0; @@ -610,8 +597,8 @@ static int xvip_composite_probe(struct platform_device *pdev) return -ENOMEM; xdev->dev = &pdev->dev; - INIT_LIST_HEAD(&xdev->entities); INIT_LIST_HEAD(&xdev->dmas); + v4l2_async_notifier_init(&xdev->notifier); ret = xvip_composite_v4l2_init(xdev); if (ret < 0) diff --git a/drivers/media/platform/xilinx/xilinx-vipp.h b/drivers/media/platform/xilinx/xilinx-vipp.h index faf6b6e80b3b..7e9c4cff33b4 100644 --- a/drivers/media/platform/xilinx/xilinx-vipp.h +++ b/drivers/media/platform/xilinx/xilinx-vipp.h @@ -28,8 +28,6 @@ * @media_dev: media device * @dev: (OF) device * @notifier: V4L2 asynchronous subdevs notifier - * @entities: entities in the graph as a list of xvip_graph_entity - * @num_subdevs: number of subdevs in the pipeline * @dmas: list of DMA channels at the pipeline output and input * @v4l2_caps: V4L2 capabilities of the whole device (see VIDIOC_QUERYCAP) */ @@ -39,8 +37,6 @@ struct xvip_composite_device { struct device *dev; struct v4l2_async_notifier notifier; - struct list_head entities; - unsigned int num_subdevs; struct list_head dmas; u32 v4l2_caps; |