Re: [PATCH v3 1/6] dt-bindings: arm: mediatek: mmsys: change compatible for MT8195
Hi Krzysztof, Thanks for the reviews. On Tue, 2022-09-20 at 17:25 +0200, Krzysztof Kozlowski wrote: > On 20/09/2022 16:01, Jason-JH.Lin wrote: > > For previous MediaTek SoCs, such as MT8173, there are 2 display HW > > pipelines binding to 1 mmsys with the same power domain, the same > > clock driver and the same mediatek-drm driver. > > > > For MT8195, VDOSYS0 and VDOSYS1 are 2 display HW pipelines binding > > to > > 2 different power domains, different clock drivers and different > > mediatek-drm drivers. > > > > Moreover, Hardware pipeline of VDOSYS0 has these components: COLOR, > > CCORR, AAL, GAMMA, DITHER. They are related to the PQ (Picture > > Quality) > > and they makes VDOSYS0 supports PQ function while they are not > > including in VDOSYS1. > > > > Hardware pipeline of VDOSYS1 has the component ETHDR (HDR related > > component). It makes VDOSYS1 supports the HDR function while it's > > not > > including in VDOSYS0. > > > > To summarize0: > > Only VDOSYS0 can support PQ adjustment. > > Only VDOSYS1 can support HDR adjustment. > > > > Therefore, we need to separate these two different mmsys hardwares > > to > > 2 different compatibles for MT8195. > > > > Fixes: 81c5a41d10b9 ("dt-bindings: arm: mediatek: mmsys: add mt8195 > > SoC binding") > > Signed-off-by: Jason-JH.Lin > > Signed-off-by: Bo-Chen Chen > > --- > > .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml | 4 > > > > 1 file changed, 4 insertions(+) > > > > diff --git > > a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yam > > l > > b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yam > > l > > index 6ad023eec193..df9184b6772c 100644 > > --- > > a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yam > > l > > +++ > > b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yam > > l > > @@ -38,6 +38,10 @@ properties: > >- const: mediatek,mt7623-mmsys > >- const: mediatek,mt2701-mmsys > >- const: syscon > > + - items: > > + - const: mediatek,mt8195-vdosys0 > > + - const: mediatek,mt8195-mmsys > > + - const: syscon > > and why mediatek,mt8195-mmsys is kept as non-deprecated? Shouldn't we keep this for fallback compatible? I think this items could support the device node like: foo { compatible = "mediatek,mt8195-vdosys0", "mediatek,mt8195-mmsys", "syscon"; } Or should I change the items like this? - items: - const: mediatek,mt8195-vdosys0 - enum: - mediatek,mt8195-mmsys - const: syscon Regards, Jason-JH.Lin > > Best regards, > Krzysztof > -- Jason-JH Lin
[PATCH] drm/hisilicon/kirin: Fix typo in kirin_drm_drv.c
'config_max_height' should be used for 'max_height'. Signed-off-by: Jammy Huang --- drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c index 2af51df6dca7..b23ad03157e1 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c @@ -165,7 +165,7 @@ static int kirin_drm_kms_init(struct drm_device *dev, dev->mode_config.min_width = 0; dev->mode_config.min_height = 0; dev->mode_config.max_width = driver_data->config_max_width; - dev->mode_config.max_height = driver_data->config_max_width; + dev->mode_config.max_height = driver_data->config_max_height; dev->mode_config.funcs = driver_data->mode_config_funcs; /* display controller init */ -- 2.25.1
[PATCH v4 15/15] vfio: Add struct device to vfio_device
From: Yi Liu and replace kref. With it a 'vfio-dev/vfioX' node is created under the sysfs path of the parent, indicating the device is bound to a vfio driver, e.g.: /sys/devices/pci\:6f/\:6f\:01.0/vfio-dev/vfio0 It is also a preparatory step toward adding cdev for supporting future device-oriented uAPI. Add Documentation/ABI/testing/sysfs-devices-vfio-dev. Suggested-by: Jason Gunthorpe Signed-off-by: Yi Liu Signed-off-by: Kevin Tian Reviewed-by: Jason Gunthorpe --- .../ABI/testing/sysfs-devices-vfio-dev| 8 +++ MAINTAINERS | 1 + drivers/vfio/vfio_main.c | 64 +++ include/linux/vfio.h | 6 +- 4 files changed, 65 insertions(+), 14 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-devices-vfio-dev diff --git a/Documentation/ABI/testing/sysfs-devices-vfio-dev b/Documentation/ABI/testing/sysfs-devices-vfio-dev new file mode 100644 index ..e21424fd9666 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-devices-vfio-dev @@ -0,0 +1,8 @@ +What: /sys/...//vfio-dev/vfioX/ +Date: September 2022 +Contact:Yi Liu +Description: +This directory is created when the device is bound to a +vfio driver. The layout under this directory matches what +exists for a standard 'struct device'. 'X' is a unique +index marking this device in vfio. diff --git a/MAINTAINERS b/MAINTAINERS index d30f26e07cd3..02c8f11b1c17 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -21312,6 +21312,7 @@ R: Cornelia Huck L: k...@vger.kernel.org S: Maintained T: git git://github.com/awilliam/linux-vfio.git +F: Documentation/ABI/testing/sysfs-devices-vfio-dev F: Documentation/driver-api/vfio.rst F: drivers/vfio/ F: include/linux/vfio.h diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index c27449613a1d..f9d10dbcf3e6 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -49,6 +49,8 @@ static struct vfio { struct mutexgroup_lock; /* locks group_list */ struct ida group_ida; dev_t group_devt; + struct class*device_class; + struct ida device_ida; } vfio; struct vfio_iommu_driver { @@ -485,12 +487,13 @@ static struct vfio_device *vfio_group_get_device(struct vfio_group *group, * VFIO driver API */ /* Release helper called by vfio_put_device() */ -void vfio_device_release(struct kref *kref) +static void vfio_device_release(struct device *dev) { struct vfio_device *device = - container_of(kref, struct vfio_device, kref); + container_of(dev, struct vfio_device, device); vfio_release_device_set(device); + ida_free(_ida, device->index); /* * kvfree() cannot be done here due to a life cycle mess in @@ -500,7 +503,6 @@ void vfio_device_release(struct kref *kref) */ device->ops->release(device); } -EXPORT_SYMBOL_GPL(vfio_device_release); /* * Allocate and initialize vfio_device so it can be registered to vfio @@ -548,6 +550,13 @@ int vfio_init_device(struct vfio_device *device, struct device *dev, { int ret; + ret = ida_alloc_max(_ida, MINORMASK, GFP_KERNEL); + if (ret < 0) { + dev_dbg(dev, "Error to alloc index\n"); + return ret; + } + + device->index = ret; init_completion(>comp); device->dev = dev; device->ops = ops; @@ -558,11 +567,15 @@ int vfio_init_device(struct vfio_device *device, struct device *dev, goto out_uninit; } - kref_init(>kref); + device_initialize(>device); + device->device.release = vfio_device_release; + device->device.class = vfio.device_class; + device->device.parent = device->dev; return 0; out_uninit: vfio_release_device_set(device); + ida_free(_ida, device->index); return ret; } EXPORT_SYMBOL_GPL(vfio_init_device); @@ -659,6 +672,7 @@ static int __vfio_register_dev(struct vfio_device *device, struct vfio_group *group) { struct vfio_device *existing_device; + int ret; if (IS_ERR(group)) return PTR_ERR(group); @@ -675,16 +689,21 @@ static int __vfio_register_dev(struct vfio_device *device, dev_WARN(device->dev, "Device already exists on group %d\n", iommu_group_id(group->iommu_group)); vfio_device_put_registration(existing_device); - if (group->type == VFIO_NO_IOMMU || - group->type == VFIO_EMULATED_IOMMU) - iommu_group_remove_device(device->dev); - vfio_group_put(group); - return -EBUSY; +
[PATCH v4 14/15] vfio: Rename vfio_device_put() and vfio_device_try_get()
With the addition of vfio_put_device() now the names become confusing. vfio_put_device() is clear from object life cycle p.o.v given kref. vfio_device_put()/vfio_device_try_get() are helpers for tracking users on a registered device. Now rename them: - vfio_device_put() -> vfio_device_put_registration() - vfio_device_try_get() -> vfio_device_try_get_registration() Signed-off-by: Kevin Tian Reviewed-by: Jason Gunthorpe Reviewed-by: Eric Auger --- drivers/vfio/vfio_main.c | 17 + 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index 12952858d903..c27449613a1d 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -453,13 +453,13 @@ static void vfio_group_get(struct vfio_group *group) * Device objects - create, release, get, put, search */ /* Device reference always implies a group reference */ -static void vfio_device_put(struct vfio_device *device) +static void vfio_device_put_registration(struct vfio_device *device) { if (refcount_dec_and_test(>refcount)) complete(>comp); } -static bool vfio_device_try_get(struct vfio_device *device) +static bool vfio_device_try_get_registration(struct vfio_device *device) { return refcount_inc_not_zero(>refcount); } @@ -471,7 +471,8 @@ static struct vfio_device *vfio_group_get_device(struct vfio_group *group, mutex_lock(>device_lock); list_for_each_entry(device, >device_list, group_next) { - if (device->dev == dev && vfio_device_try_get(device)) { + if (device->dev == dev && + vfio_device_try_get_registration(device)) { mutex_unlock(>device_lock); return device; } @@ -673,7 +674,7 @@ static int __vfio_register_dev(struct vfio_device *device, if (existing_device) { dev_WARN(device->dev, "Device already exists on group %d\n", iommu_group_id(group->iommu_group)); - vfio_device_put(existing_device); + vfio_device_put_registration(existing_device); if (group->type == VFIO_NO_IOMMU || group->type == VFIO_EMULATED_IOMMU) iommu_group_remove_device(device->dev); @@ -731,7 +732,7 @@ static struct vfio_device *vfio_device_get_from_name(struct vfio_group *group, ret = !strcmp(dev_name(it->dev), buf); } - if (ret && vfio_device_try_get(it)) { + if (ret && vfio_device_try_get_registration(it)) { device = it; break; } @@ -751,7 +752,7 @@ void vfio_unregister_group_dev(struct vfio_device *device) bool interrupted = false; long rc; - vfio_device_put(device); + vfio_device_put_registration(device); rc = try_wait_for_completion(>comp); while (rc <= 0) { if (device->ops->request) @@ -1311,7 +1312,7 @@ static int vfio_group_ioctl_get_device_fd(struct vfio_group *group, err_put_fdno: put_unused_fd(fdno); err_put_device: - vfio_device_put(device); + vfio_device_put_registration(device); return ret; } @@ -1493,7 +1494,7 @@ static int vfio_device_fops_release(struct inode *inode, struct file *filep) vfio_device_unassign_container(device); - vfio_device_put(device); + vfio_device_put_registration(device); return 0; } -- 2.21.3
[PATCH v4 13/15] vfio/ccw: Use the new device life cycle helpers
ccw is the only exception which cannot use vfio_alloc_device() because its private device structure is designed to serve both mdev and parent. Life cycle of the parent is managed by css_driver so vfio_ccw_private must be allocated/freed in css_driver probe/remove path instead of conforming to vfio core life cycle for mdev. Given that use a wait/completion scheme so the mdev remove path waits after vfio_put_device() until receiving a completion notification from @release. The completion indicates that all active references on vfio_device have been released. After that point although free of vfio_ccw_private is delayed to css_driver it's at least guaranteed to have no parallel reference on released vfio device part from other code paths. memset() in @probe is removed. vfio_device is either already cleared when probed for the first time or cleared in @release from last probe. The right fix is to introduce separate structures for mdev and parent, but this won't happen in short term per prior discussions. Remove vfio_init/uninit_group_dev() as no user now. Suggested-by: Jason Gunthorpe Signed-off-by: Kevin Tian Reviewed-by: Jason Gunthorpe Reviewed-by: Eric Farman --- drivers/s390/cio/vfio_ccw_ops.c | 52 + drivers/s390/cio/vfio_ccw_private.h | 3 ++ drivers/vfio/vfio_main.c| 23 +++-- include/linux/vfio.h| 3 -- 4 files changed, 53 insertions(+), 28 deletions(-) diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index 4a806a2273b5..9f8486c0d3d3 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -87,6 +87,15 @@ static struct attribute_group *mdev_type_groups[] = { NULL, }; +static int vfio_ccw_mdev_init_dev(struct vfio_device *vdev) +{ + struct vfio_ccw_private *private = + container_of(vdev, struct vfio_ccw_private, vdev); + + init_completion(>release_comp); + return 0; +} + static int vfio_ccw_mdev_probe(struct mdev_device *mdev) { struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent); @@ -98,9 +107,9 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev) if (atomic_dec_if_positive(>avail) < 0) return -EPERM; - memset(>vdev, 0, sizeof(private->vdev)); - vfio_init_group_dev(>vdev, >dev, - _ccw_dev_ops); + ret = vfio_init_device(>vdev, >dev, _ccw_dev_ops); + if (ret) + return ret; VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: create\n", private->sch->schid.cssid, @@ -109,16 +118,33 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev) ret = vfio_register_emulated_iommu_dev(>vdev); if (ret) - goto err_atomic; + goto err_put_vdev; dev_set_drvdata(>dev, private); return 0; -err_atomic: - vfio_uninit_group_dev(>vdev); +err_put_vdev: + vfio_put_device(>vdev); atomic_inc(>avail); return ret; } +static void vfio_ccw_mdev_release_dev(struct vfio_device *vdev) +{ + struct vfio_ccw_private *private = + container_of(vdev, struct vfio_ccw_private, vdev); + + /* +* We cannot free vfio_ccw_private here because it includes +* parent info which must be free'ed by css driver. +* +* Use a workaround by memset'ing the core device part and +* then notifying the remove path that all active references +* to this device have been released. +*/ + memset(vdev, 0, sizeof(*vdev)); + complete(>release_comp); +} + static void vfio_ccw_mdev_remove(struct mdev_device *mdev) { struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent); @@ -130,7 +156,17 @@ static void vfio_ccw_mdev_remove(struct mdev_device *mdev) vfio_unregister_group_dev(>vdev); - vfio_uninit_group_dev(>vdev); + vfio_put_device(>vdev); + /* +* Wait for all active references on mdev are released so it +* is safe to defer kfree() to a later point. +* +* TODO: the clean fix is to split parent/mdev info from ccw +* private structure so each can be managed in its own life +* cycle. +*/ + wait_for_completion(>release_comp); + atomic_inc(>avail); } @@ -592,6 +628,8 @@ static void vfio_ccw_mdev_request(struct vfio_device *vdev, unsigned int count) } static const struct vfio_device_ops vfio_ccw_dev_ops = { + .init = vfio_ccw_mdev_init_dev, + .release = vfio_ccw_mdev_release_dev, .open_device = vfio_ccw_mdev_open_device, .close_device = vfio_ccw_mdev_close_device, .read = vfio_ccw_mdev_read, diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h index cd24b7fada91..63d9202b29c7 100644 --- a/drivers/s390/cio/vfio_ccw_private.h +++ b/drivers/s390/cio/vfio_ccw_private.h
[PATCH v4 12/15] vfio/amba: Use the new device life cycle helpers
Implement amba's own vfio_device_ops. Remove vfio_platform_probe/remove_common() given no user now. Signed-off-by: Kevin Tian Reviewed-by: Jason Gunthorpe Reviewed-by: Eric Auger --- drivers/vfio/platform/vfio_amba.c | 72 ++- drivers/vfio/platform/vfio_platform_common.c | 60 drivers/vfio/platform/vfio_platform_private.h | 3 - 3 files changed, 55 insertions(+), 80 deletions(-) diff --git a/drivers/vfio/platform/vfio_amba.c b/drivers/vfio/platform/vfio_amba.c index 1aaa4f721bd2..eaea63e5294c 100644 --- a/drivers/vfio/platform/vfio_amba.c +++ b/drivers/vfio/platform/vfio_amba.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "vfio_platform_private.h" @@ -40,20 +41,16 @@ static int get_amba_irq(struct vfio_platform_device *vdev, int i) return ret ? ret : -ENXIO; } -static int vfio_amba_probe(struct amba_device *adev, const struct amba_id *id) +static int vfio_amba_init_dev(struct vfio_device *core_vdev) { - struct vfio_platform_device *vdev; + struct vfio_platform_device *vdev = + container_of(core_vdev, struct vfio_platform_device, vdev); + struct amba_device *adev = to_amba_device(core_vdev->dev); int ret; - vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); - if (!vdev) - return -ENOMEM; - vdev->name = kasprintf(GFP_KERNEL, "vfio-amba-%08x", adev->periphid); - if (!vdev->name) { - kfree(vdev); + if (!vdev->name) return -ENOMEM; - } vdev->opaque = (void *) adev; vdev->flags = VFIO_DEVICE_FLAGS_AMBA; @@ -61,26 +58,67 @@ static int vfio_amba_probe(struct amba_device *adev, const struct amba_id *id) vdev->get_irq = get_amba_irq; vdev->reset_required = false; - ret = vfio_platform_probe_common(vdev, >dev); - if (ret) { + ret = vfio_platform_init_common(vdev); + if (ret) kfree(vdev->name); - kfree(vdev); - return ret; - } + return ret; +} + +static const struct vfio_device_ops vfio_amba_ops; +static int vfio_amba_probe(struct amba_device *adev, const struct amba_id *id) +{ + struct vfio_platform_device *vdev; + int ret; + + vdev = vfio_alloc_device(vfio_platform_device, vdev, >dev, +_amba_ops); + if (IS_ERR(vdev)) + return PTR_ERR(vdev); + ret = vfio_register_group_dev(>vdev); + if (ret) + goto out_put_vdev; + + pm_runtime_enable(>dev); dev_set_drvdata(>dev, vdev); return 0; + +out_put_vdev: + vfio_put_device(>vdev); + return ret; +} + +static void vfio_amba_release_dev(struct vfio_device *core_vdev) +{ + struct vfio_platform_device *vdev = + container_of(core_vdev, struct vfio_platform_device, vdev); + + vfio_platform_release_common(vdev); + kfree(vdev->name); + vfio_free_device(core_vdev); } static void vfio_amba_remove(struct amba_device *adev) { struct vfio_platform_device *vdev = dev_get_drvdata(>dev); - vfio_platform_remove_common(vdev); - kfree(vdev->name); - kfree(vdev); + vfio_unregister_group_dev(>vdev); + pm_runtime_disable(vdev->device); + vfio_put_device(>vdev); } +static const struct vfio_device_ops vfio_amba_ops = { + .name = "vfio-amba", + .init = vfio_amba_init_dev, + .release= vfio_amba_release_dev, + .open_device= vfio_platform_open_device, + .close_device = vfio_platform_close_device, + .ioctl = vfio_platform_ioctl, + .read = vfio_platform_read, + .write = vfio_platform_write, + .mmap = vfio_platform_mmap, +}; + static const struct amba_id pl330_ids[] = { { 0, 0 }, }; diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c index 4c01bf0adebb..55dc4f43c31e 100644 --- a/drivers/vfio/platform/vfio_platform_common.c +++ b/drivers/vfio/platform/vfio_platform_common.c @@ -605,16 +605,6 @@ int vfio_platform_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma } EXPORT_SYMBOL_GPL(vfio_platform_mmap); -static const struct vfio_device_ops vfio_platform_ops = { - .name = "vfio-platform", - .open_device= vfio_platform_open_device, - .close_device = vfio_platform_close_device, - .ioctl = vfio_platform_ioctl, - .read = vfio_platform_read, - .write = vfio_platform_write, - .mmap = vfio_platform_mmap, -}; - static int vfio_platform_of_probe(struct vfio_platform_device *vdev, struct device *dev) { @@ -674,56 +664,6 @@ void vfio_platform_release_common(struct vfio_platform_device *vdev) }
[PATCH v4 11/15] vfio/platform: Use the new device life cycle helpers
Move vfio_device_ops from platform core to platform drivers so device specific init/cleanup can be added. Introduce two new helpers vfio_platform_init/release_common() for the use in driver @init/@release. vfio_platform_probe/remove_common() will be deprecated. Signed-off-by: Kevin Tian Reviewed-by: Jason Gunthorpe Reviewed-by: Eric Auger Tested-by: Eric Auger --- drivers/vfio/platform/vfio_platform.c | 66 +++ drivers/vfio/platform/vfio_platform_common.c | 53 --- drivers/vfio/platform/vfio_platform_private.h | 15 + 3 files changed, 111 insertions(+), 23 deletions(-) diff --git a/drivers/vfio/platform/vfio_platform.c b/drivers/vfio/platform/vfio_platform.c index 04f40c5acfd6..82cedcebfd90 100644 --- a/drivers/vfio/platform/vfio_platform.c +++ b/drivers/vfio/platform/vfio_platform.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "vfio_platform_private.h" @@ -36,14 +37,11 @@ static int get_platform_irq(struct vfio_platform_device *vdev, int i) return platform_get_irq_optional(pdev, i); } -static int vfio_platform_probe(struct platform_device *pdev) +static int vfio_platform_init_dev(struct vfio_device *core_vdev) { - struct vfio_platform_device *vdev; - int ret; - - vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); - if (!vdev) - return -ENOMEM; + struct vfio_platform_device *vdev = + container_of(core_vdev, struct vfio_platform_device, vdev); + struct platform_device *pdev = to_platform_device(core_vdev->dev); vdev->opaque = (void *) pdev; vdev->name = pdev->name; @@ -52,24 +50,64 @@ static int vfio_platform_probe(struct platform_device *pdev) vdev->get_irq = get_platform_irq; vdev->reset_required = reset_required; - ret = vfio_platform_probe_common(vdev, >dev); - if (ret) { - kfree(vdev); - return ret; - } + return vfio_platform_init_common(vdev); +} + +static const struct vfio_device_ops vfio_platform_ops; +static int vfio_platform_probe(struct platform_device *pdev) +{ + struct vfio_platform_device *vdev; + int ret; + + vdev = vfio_alloc_device(vfio_platform_device, vdev, >dev, +_platform_ops); + if (IS_ERR(vdev)) + return PTR_ERR(vdev); + + ret = vfio_register_group_dev(>vdev); + if (ret) + goto out_put_vdev; + + pm_runtime_enable(>dev); dev_set_drvdata(>dev, vdev); return 0; + +out_put_vdev: + vfio_put_device(>vdev); + return ret; +} + +static void vfio_platform_release_dev(struct vfio_device *core_vdev) +{ + struct vfio_platform_device *vdev = + container_of(core_vdev, struct vfio_platform_device, vdev); + + vfio_platform_release_common(vdev); + vfio_free_device(core_vdev); } static int vfio_platform_remove(struct platform_device *pdev) { struct vfio_platform_device *vdev = dev_get_drvdata(>dev); - vfio_platform_remove_common(vdev); - kfree(vdev); + vfio_unregister_group_dev(>vdev); + pm_runtime_disable(vdev->device); + vfio_put_device(>vdev); return 0; } +static const struct vfio_device_ops vfio_platform_ops = { + .name = "vfio-platform", + .init = vfio_platform_init_dev, + .release= vfio_platform_release_dev, + .open_device= vfio_platform_open_device, + .close_device = vfio_platform_close_device, + .ioctl = vfio_platform_ioctl, + .read = vfio_platform_read, + .write = vfio_platform_write, + .mmap = vfio_platform_mmap, +}; + static struct platform_driver vfio_platform_driver = { .probe = vfio_platform_probe, .remove = vfio_platform_remove, diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c index 256f55b84e70..4c01bf0adebb 100644 --- a/drivers/vfio/platform/vfio_platform_common.c +++ b/drivers/vfio/platform/vfio_platform_common.c @@ -218,7 +218,7 @@ static int vfio_platform_call_reset(struct vfio_platform_device *vdev, return -EINVAL; } -static void vfio_platform_close_device(struct vfio_device *core_vdev) +void vfio_platform_close_device(struct vfio_device *core_vdev) { struct vfio_platform_device *vdev = container_of(core_vdev, struct vfio_platform_device, vdev); @@ -236,8 +236,9 @@ static void vfio_platform_close_device(struct vfio_device *core_vdev) vfio_platform_regions_cleanup(vdev); vfio_platform_irq_cleanup(vdev); } +EXPORT_SYMBOL_GPL(vfio_platform_close_device); -static int vfio_platform_open_device(struct vfio_device *core_vdev) +int vfio_platform_open_device(struct vfio_device *core_vdev) { struct vfio_platform_device *vdev =
[PATCH v4 10/15] vfio/fsl-mc: Use the new device life cycle helpers
From: Yi Liu Also add a comment to mark that vfio core releases device_set if @init fails. Signed-off-by: Yi Liu Signed-off-by: Kevin Tian Reviewed-by: Jason Gunthorpe --- drivers/vfio/fsl-mc/vfio_fsl_mc.c | 85 ++- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c b/drivers/vfio/fsl-mc/vfio_fsl_mc.c index 42b344bd7cd5..b16874e913e4 100644 --- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c @@ -418,16 +418,7 @@ static int vfio_fsl_mc_mmap(struct vfio_device *core_vdev, return vfio_fsl_mc_mmap_mmio(vdev->regions[index], vma); } -static const struct vfio_device_ops vfio_fsl_mc_ops = { - .name = "vfio-fsl-mc", - .open_device= vfio_fsl_mc_open_device, - .close_device = vfio_fsl_mc_close_device, - .ioctl = vfio_fsl_mc_ioctl, - .read = vfio_fsl_mc_read, - .write = vfio_fsl_mc_write, - .mmap = vfio_fsl_mc_mmap, -}; - +static const struct vfio_device_ops vfio_fsl_mc_ops; static int vfio_fsl_mc_bus_notifier(struct notifier_block *nb, unsigned long action, void *data) { @@ -518,35 +509,43 @@ static void vfio_fsl_uninit_device(struct vfio_fsl_mc_device *vdev) bus_unregister_notifier(_mc_bus_type, >nb); } -static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev) +static int vfio_fsl_mc_init_dev(struct vfio_device *core_vdev) { - struct vfio_fsl_mc_device *vdev; - struct device *dev = _dev->dev; + struct vfio_fsl_mc_device *vdev = + container_of(core_vdev, struct vfio_fsl_mc_device, vdev); + struct fsl_mc_device *mc_dev = to_fsl_mc_device(core_vdev->dev); int ret; - vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); - if (!vdev) - return -ENOMEM; - - vfio_init_group_dev(>vdev, dev, _fsl_mc_ops); vdev->mc_dev = mc_dev; mutex_init(>igate); if (is_fsl_mc_bus_dprc(mc_dev)) - ret = vfio_assign_device_set(>vdev, _dev->dev); + ret = vfio_assign_device_set(core_vdev, _dev->dev); else - ret = vfio_assign_device_set(>vdev, mc_dev->dev.parent); - if (ret) - goto out_uninit; + ret = vfio_assign_device_set(core_vdev, mc_dev->dev.parent); - ret = vfio_fsl_mc_init_device(vdev); if (ret) - goto out_uninit; + return ret; + + /* device_set is released by vfio core if @init fails */ + return vfio_fsl_mc_init_device(vdev); +} + +static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev) +{ + struct vfio_fsl_mc_device *vdev; + struct device *dev = _dev->dev; + int ret; + + vdev = vfio_alloc_device(vfio_fsl_mc_device, vdev, dev, +_fsl_mc_ops); + if (IS_ERR(vdev)) + return PTR_ERR(vdev); ret = vfio_register_group_dev(>vdev); if (ret) { dev_err(dev, "VFIO_FSL_MC: Failed to add to vfio group\n"); - goto out_device; + goto out_put_vdev; } ret = vfio_fsl_mc_scan_container(mc_dev); @@ -557,30 +556,44 @@ static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev) out_group_dev: vfio_unregister_group_dev(>vdev); -out_device: - vfio_fsl_uninit_device(vdev); -out_uninit: - vfio_uninit_group_dev(>vdev); - kfree(vdev); +out_put_vdev: + vfio_put_device(>vdev); return ret; } +static void vfio_fsl_mc_release_dev(struct vfio_device *core_vdev) +{ + struct vfio_fsl_mc_device *vdev = + container_of(core_vdev, struct vfio_fsl_mc_device, vdev); + + vfio_fsl_uninit_device(vdev); + mutex_destroy(>igate); + vfio_free_device(core_vdev); +} + static int vfio_fsl_mc_remove(struct fsl_mc_device *mc_dev) { struct device *dev = _dev->dev; struct vfio_fsl_mc_device *vdev = dev_get_drvdata(dev); vfio_unregister_group_dev(>vdev); - mutex_destroy(>igate); - dprc_remove_devices(mc_dev, NULL, 0); - vfio_fsl_uninit_device(vdev); - - vfio_uninit_group_dev(>vdev); - kfree(vdev); + vfio_put_device(>vdev); return 0; } +static const struct vfio_device_ops vfio_fsl_mc_ops = { + .name = "vfio-fsl-mc", + .init = vfio_fsl_mc_init_dev, + .release= vfio_fsl_mc_release_dev, + .open_device= vfio_fsl_mc_open_device, + .close_device = vfio_fsl_mc_close_device, + .ioctl = vfio_fsl_mc_ioctl, + .read = vfio_fsl_mc_read, + .write = vfio_fsl_mc_write, + .mmap = vfio_fsl_mc_mmap, +}; + static struct fsl_mc_driver vfio_fsl_mc_driver = { .probe = vfio_fsl_mc_probe, .remove = vfio_fsl_mc_remove, -- 2.21.3
[PATCH v4 09/15] vfio/ap: Use the new device life cycle helpers
From: Yi Liu and manage available_instances inside @init/@release. Signed-off-by: Yi Liu Signed-off-by: Kevin Tian Reviewed-by: Tony Krowiak Reviewed-by: Jason Gunthorpe --- drivers/s390/crypto/vfio_ap_ops.c | 50 ++- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 6c8c41fac4e1..161597357a64 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -684,42 +684,44 @@ static bool vfio_ap_mdev_filter_matrix(unsigned long *apm, unsigned long *aqm, AP_DOMAINS); } -static int vfio_ap_mdev_probe(struct mdev_device *mdev) +static int vfio_ap_mdev_init_dev(struct vfio_device *vdev) { - struct ap_matrix_mdev *matrix_mdev; - int ret; + struct ap_matrix_mdev *matrix_mdev = + container_of(vdev, struct ap_matrix_mdev, vdev); if ((atomic_dec_if_positive(_dev->available_instances) < 0)) return -EPERM; - matrix_mdev = kzalloc(sizeof(*matrix_mdev), GFP_KERNEL); - if (!matrix_mdev) { - ret = -ENOMEM; - goto err_dec_available; - } - vfio_init_group_dev(_mdev->vdev, >dev, - _ap_matrix_dev_ops); - - matrix_mdev->mdev = mdev; + matrix_mdev->mdev = to_mdev_device(vdev->dev); vfio_ap_matrix_init(_dev->info, _mdev->matrix); matrix_mdev->pqap_hook = handle_pqap; vfio_ap_matrix_init(_dev->info, _mdev->shadow_apcb); hash_init(matrix_mdev->qtable.queues); + return 0; +} + +static int vfio_ap_mdev_probe(struct mdev_device *mdev) +{ + struct ap_matrix_mdev *matrix_mdev; + int ret; + + matrix_mdev = vfio_alloc_device(ap_matrix_mdev, vdev, >dev, + _ap_matrix_dev_ops); + if (IS_ERR(matrix_mdev)) + return PTR_ERR(matrix_mdev); + ret = vfio_register_emulated_iommu_dev(_mdev->vdev); if (ret) - goto err_list; + goto err_put_vdev; dev_set_drvdata(>dev, matrix_mdev); mutex_lock(_dev->mdevs_lock); list_add(_mdev->node, _dev->mdev_list); mutex_unlock(_dev->mdevs_lock); return 0; -err_list: - vfio_uninit_group_dev(_mdev->vdev); - kfree(matrix_mdev); -err_dec_available: - atomic_inc(_dev->available_instances); +err_put_vdev: + vfio_put_device(_mdev->vdev); return ret; } @@ -766,6 +768,12 @@ static void vfio_ap_mdev_unlink_fr_queues(struct ap_matrix_mdev *matrix_mdev) } } +static void vfio_ap_mdev_release_dev(struct vfio_device *vdev) +{ + atomic_inc(_dev->available_instances); + vfio_free_device(vdev); +} + static void vfio_ap_mdev_remove(struct mdev_device *mdev) { struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(>dev); @@ -779,9 +787,7 @@ static void vfio_ap_mdev_remove(struct mdev_device *mdev) list_del(_mdev->node); mutex_unlock(_dev->mdevs_lock); mutex_unlock(_dev->guests_lock); - vfio_uninit_group_dev(_mdev->vdev); - kfree(matrix_mdev); - atomic_inc(_dev->available_instances); + vfio_put_device(_mdev->vdev); } static ssize_t name_show(struct mdev_type *mtype, @@ -1794,6 +1800,8 @@ static const struct attribute_group vfio_queue_attr_group = { }; static const struct vfio_device_ops vfio_ap_matrix_dev_ops = { + .init = vfio_ap_mdev_init_dev, + .release = vfio_ap_mdev_release_dev, .open_device = vfio_ap_mdev_open_device, .close_device = vfio_ap_mdev_close_device, .ioctl = vfio_ap_mdev_ioctl, -- 2.21.3
[PATCH v4 08/15] drm/i915/gvt: Use the new device life cycle helpers
Move vfio_device to the start of intel_vgpu as required by the new helpers. Change intel_gvt_create_vgpu() to use intel_vgpu as the first param as other vgpu helpers do. Signed-off-by: Kevin Tian Reviewed-by: Jason Gunthorpe Reviewed-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/gvt.h | 5 ++- drivers/gpu/drm/i915/gvt/kvmgt.c | 52 ++-- drivers/gpu/drm/i915/gvt/vgpu.c | 33 3 files changed, 50 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 705689e64011..89fab7896fc6 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -172,6 +172,7 @@ struct intel_vgpu_submission { #define KVMGT_DEBUGFS_FILENAME "kvmgt_nr_cache_entries" struct intel_vgpu { + struct vfio_device vfio_device; struct intel_gvt *gvt; struct mutex vgpu_lock; int id; @@ -211,7 +212,6 @@ struct intel_vgpu { u32 scan_nonprivbb; - struct vfio_device vfio_device; struct vfio_region *region; int num_regions; struct eventfd_ctx *intx_trigger; @@ -494,8 +494,7 @@ void intel_gvt_clean_vgpu_types(struct intel_gvt *gvt); struct intel_vgpu *intel_gvt_create_idle_vgpu(struct intel_gvt *gvt); void intel_gvt_destroy_idle_vgpu(struct intel_vgpu *vgpu); -struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt, -struct intel_vgpu_type *type); +int intel_gvt_create_vgpu(struct intel_vgpu *vgpu, struct intel_vgpu_type *type); void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu); void intel_gvt_release_vgpu(struct intel_vgpu *vgpu); void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr, diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index e3cd58946477..41bba40feef8 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -1546,7 +1546,33 @@ static const struct attribute_group *intel_vgpu_groups[] = { NULL, }; +static int intel_vgpu_init_dev(struct vfio_device *vfio_dev) +{ + struct mdev_device *mdev = to_mdev_device(vfio_dev->dev); + struct device *pdev = mdev_parent_dev(mdev); + struct intel_gvt *gvt = kdev_to_i915(pdev)->gvt; + struct intel_vgpu_type *type; + struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev); + + type = >types[mdev_get_type_group_id(mdev)]; + if (!type) + return -EINVAL; + + vgpu->gvt = gvt; + return intel_gvt_create_vgpu(vgpu, type); +} + +static void intel_vgpu_release_dev(struct vfio_device *vfio_dev) +{ + struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev); + + intel_gvt_destroy_vgpu(vgpu); + vfio_free_device(vfio_dev); +} + static const struct vfio_device_ops intel_vgpu_dev_ops = { + .init = intel_vgpu_init_dev, + .release= intel_vgpu_release_dev, .open_device= intel_vgpu_open_device, .close_device = intel_vgpu_close_device, .read = intel_vgpu_read, @@ -1558,35 +1584,28 @@ static const struct vfio_device_ops intel_vgpu_dev_ops = { static int intel_vgpu_probe(struct mdev_device *mdev) { - struct device *pdev = mdev_parent_dev(mdev); - struct intel_gvt *gvt = kdev_to_i915(pdev)->gvt; - struct intel_vgpu_type *type; struct intel_vgpu *vgpu; int ret; - type = >types[mdev_get_type_group_id(mdev)]; - if (!type) - return -EINVAL; - - vgpu = intel_gvt_create_vgpu(gvt, type); + vgpu = vfio_alloc_device(intel_vgpu, vfio_device, >dev, +_vgpu_dev_ops); if (IS_ERR(vgpu)) { gvt_err("failed to create intel vgpu: %ld\n", PTR_ERR(vgpu)); return PTR_ERR(vgpu); } - vfio_init_group_dev(>vfio_device, >dev, - _vgpu_dev_ops); - dev_set_drvdata(>dev, vgpu); ret = vfio_register_emulated_iommu_dev(>vfio_device); - if (ret) { - intel_gvt_destroy_vgpu(vgpu); - return ret; - } + if (ret) + goto out_put_vdev; gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n", dev_name(mdev_dev(mdev))); return 0; + +out_put_vdev: + vfio_put_device(>vfio_device); + return ret; } static void intel_vgpu_remove(struct mdev_device *mdev) @@ -1595,7 +1614,8 @@ static void intel_vgpu_remove(struct mdev_device *mdev) if (WARN_ON_ONCE(vgpu->attached)) return; - intel_gvt_destroy_vgpu(vgpu); + + vfio_put_device(>vfio_device); } static struct mdev_driver intel_vgpu_mdev_driver = { diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c index 46da19b3225d..5c533fbc2c8d 100644 --- a/drivers/gpu/drm/i915/gvt/vgpu.c +++ b/drivers/gpu/drm/i915/gvt/vgpu.c @@ -302,8 +302,6 @@
[PATCH v4 07/15] vfio/mbochs: Use the new device life cycle helpers
From: Yi Liu and manage avail_mbytes inside @init/@release. Signed-off-by: Yi Liu Signed-off-by: Kevin Tian Reviewed-by: Jason Gunthorpe --- samples/vfio-mdev/mbochs.c | 73 -- 1 file changed, 46 insertions(+), 27 deletions(-) diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c index 344c2901a82b..6901947e27d2 100644 --- a/samples/vfio-mdev/mbochs.c +++ b/samples/vfio-mdev/mbochs.c @@ -505,13 +505,14 @@ static int mbochs_reset(struct mdev_state *mdev_state) return 0; } -static int mbochs_probe(struct mdev_device *mdev) +static int mbochs_init_dev(struct vfio_device *vdev) { - int avail_mbytes = atomic_read(_avail_mbytes); + struct mdev_state *mdev_state = + container_of(vdev, struct mdev_state, vdev); + struct mdev_device *mdev = to_mdev_device(vdev->dev); const struct mbochs_type *type = _types[mdev_get_type_group_id(mdev)]; - struct device *dev = mdev_dev(mdev); - struct mdev_state *mdev_state; + int avail_mbytes = atomic_read(_avail_mbytes); int ret = -ENOMEM; do { @@ -520,14 +521,9 @@ static int mbochs_probe(struct mdev_device *mdev) } while (!atomic_try_cmpxchg(_avail_mbytes, _mbytes, avail_mbytes - type->mbytes)); - mdev_state = kzalloc(sizeof(struct mdev_state), GFP_KERNEL); - if (mdev_state == NULL) - goto err_avail; - vfio_init_group_dev(_state->vdev, >dev, _dev_ops); - mdev_state->vconfig = kzalloc(MBOCHS_CONFIG_SPACE_SIZE, GFP_KERNEL); - if (mdev_state->vconfig == NULL) - goto err_mem; + if (!mdev_state->vconfig) + goto err_avail; mdev_state->memsize = type->mbytes * 1024 * 1024; mdev_state->pagecount = mdev_state->memsize >> PAGE_SHIFT; @@ -535,10 +531,7 @@ static int mbochs_probe(struct mdev_device *mdev) sizeof(struct page *), GFP_KERNEL); if (!mdev_state->pages) - goto err_mem; - - dev_info(dev, "%s: %s, %d MB, %ld pages\n", __func__, -type->name, type->mbytes, mdev_state->pagecount); + goto err_vconfig; mutex_init(_state->ops_lock); mdev_state->mdev = mdev; @@ -553,19 +546,47 @@ static int mbochs_probe(struct mdev_device *mdev) mbochs_create_config_space(mdev_state); mbochs_reset(mdev_state); + dev_info(vdev->dev, "%s: %s, %d MB, %ld pages\n", __func__, +type->name, type->mbytes, mdev_state->pagecount); + return 0; + +err_vconfig: + kfree(mdev_state->vconfig); +err_avail: + atomic_add(type->mbytes, _avail_mbytes); + return ret; +} + +static int mbochs_probe(struct mdev_device *mdev) +{ + struct mdev_state *mdev_state; + int ret = -ENOMEM; + + mdev_state = vfio_alloc_device(mdev_state, vdev, >dev, + _dev_ops); + if (IS_ERR(mdev_state)) + return PTR_ERR(mdev_state); + ret = vfio_register_emulated_iommu_dev(_state->vdev); if (ret) - goto err_mem; + goto err_put_vdev; dev_set_drvdata(>dev, mdev_state); return 0; -err_mem: - vfio_uninit_group_dev(_state->vdev); + +err_put_vdev: + vfio_put_device(_state->vdev); + return ret; +} + +static void mbochs_release_dev(struct vfio_device *vdev) +{ + struct mdev_state *mdev_state = + container_of(vdev, struct mdev_state, vdev); + + atomic_add(mdev_state->type->mbytes, _avail_mbytes); kfree(mdev_state->pages); kfree(mdev_state->vconfig); - kfree(mdev_state); -err_avail: - atomic_add(type->mbytes, _avail_mbytes); - return ret; + vfio_free_device(vdev); } static void mbochs_remove(struct mdev_device *mdev) @@ -573,11 +594,7 @@ static void mbochs_remove(struct mdev_device *mdev) struct mdev_state *mdev_state = dev_get_drvdata(>dev); vfio_unregister_group_dev(_state->vdev); - vfio_uninit_group_dev(_state->vdev); - atomic_add(mdev_state->type->mbytes, _avail_mbytes); - kfree(mdev_state->pages); - kfree(mdev_state->vconfig); - kfree(mdev_state); + vfio_put_device(_state->vdev); } static ssize_t mbochs_read(struct vfio_device *vdev, char __user *buf, @@ -1397,6 +1414,8 @@ static struct attribute_group *mdev_type_groups[] = { static const struct vfio_device_ops mbochs_dev_ops = { .close_device = mbochs_close_device, + .init = mbochs_init_dev, + .release = mbochs_release_dev, .read = mbochs_read, .write = mbochs_write, .ioctl = mbochs_ioctl, -- 2.21.3
[PATCH v4 06/15] vfio/mtty: Use the new device life cycle helpers
From: Yi Liu and manage available ports inside @init/@release. Signed-off-by: Yi Liu Signed-off-by: Kevin Tian Reviewed-by: Jason Gunthorpe --- samples/vfio-mdev/mtty.c | 67 +++- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c index f42a59ed2e3f..d151928e4f21 100644 --- a/samples/vfio-mdev/mtty.c +++ b/samples/vfio-mdev/mtty.c @@ -703,9 +703,11 @@ static ssize_t mdev_access(struct mdev_state *mdev_state, u8 *buf, size_t count, return ret; } -static int mtty_probe(struct mdev_device *mdev) +static int mtty_init_dev(struct vfio_device *vdev) { - struct mdev_state *mdev_state; + struct mdev_state *mdev_state = + container_of(vdev, struct mdev_state, vdev); + struct mdev_device *mdev = to_mdev_device(vdev->dev); int nr_ports = mdev_get_type_group_id(mdev) + 1; int avail_ports = atomic_read(_avail_ports); int ret; @@ -716,58 +718,65 @@ static int mtty_probe(struct mdev_device *mdev) } while (!atomic_try_cmpxchg(_avail_ports, _ports, avail_ports - nr_ports)); - mdev_state = kzalloc(sizeof(struct mdev_state), GFP_KERNEL); - if (mdev_state == NULL) { - ret = -ENOMEM; - goto err_nr_ports; - } - - vfio_init_group_dev(_state->vdev, >dev, _dev_ops); - mdev_state->nr_ports = nr_ports; mdev_state->irq_index = -1; mdev_state->s[0].max_fifo_size = MAX_FIFO_SIZE; mdev_state->s[1].max_fifo_size = MAX_FIFO_SIZE; mutex_init(_state->rxtx_lock); - mdev_state->vconfig = kzalloc(MTTY_CONFIG_SPACE_SIZE, GFP_KERNEL); - if (mdev_state->vconfig == NULL) { + mdev_state->vconfig = kzalloc(MTTY_CONFIG_SPACE_SIZE, GFP_KERNEL); + if (!mdev_state->vconfig) { ret = -ENOMEM; - goto err_state; + goto err_nr_ports; } mutex_init(_state->ops_lock); mdev_state->mdev = mdev; - mtty_create_config_space(mdev_state); + return 0; + +err_nr_ports: + atomic_add(nr_ports, _avail_ports); + return ret; +} + +static int mtty_probe(struct mdev_device *mdev) +{ + struct mdev_state *mdev_state; + int ret; + + mdev_state = vfio_alloc_device(mdev_state, vdev, >dev, + _dev_ops); + if (IS_ERR(mdev_state)) + return PTR_ERR(mdev_state); ret = vfio_register_emulated_iommu_dev(_state->vdev); if (ret) - goto err_vconfig; + goto err_put_vdev; dev_set_drvdata(>dev, mdev_state); return 0; -err_vconfig: - kfree(mdev_state->vconfig); -err_state: - vfio_uninit_group_dev(_state->vdev); - kfree(mdev_state); -err_nr_ports: - atomic_add(nr_ports, _avail_ports); +err_put_vdev: + vfio_put_device(_state->vdev); return ret; } +static void mtty_release_dev(struct vfio_device *vdev) +{ + struct mdev_state *mdev_state = + container_of(vdev, struct mdev_state, vdev); + + atomic_add(mdev_state->nr_ports, _avail_ports); + kfree(mdev_state->vconfig); + vfio_free_device(vdev); +} + static void mtty_remove(struct mdev_device *mdev) { struct mdev_state *mdev_state = dev_get_drvdata(>dev); - int nr_ports = mdev_state->nr_ports; vfio_unregister_group_dev(_state->vdev); - - kfree(mdev_state->vconfig); - vfio_uninit_group_dev(_state->vdev); - kfree(mdev_state); - atomic_add(nr_ports, _avail_ports); + vfio_put_device(_state->vdev); } static int mtty_reset(struct mdev_state *mdev_state) @@ -1287,6 +1296,8 @@ static struct attribute_group *mdev_type_groups[] = { static const struct vfio_device_ops mtty_dev_ops = { .name = "vfio-mtty", + .init = mtty_init_dev, + .release = mtty_release_dev, .read = mtty_read, .write = mtty_write, .ioctl = mtty_ioctl, -- 2.21.3
[PATCH v4 05/15] vfio/mdpy: Use the new device life cycle helpers
From: Yi Liu and manage mdpy_count inside @init/@release. Signed-off-by: Yi Liu Signed-off-by: Kevin Tian Reviewed-by: Jason Gunthorpe --- samples/vfio-mdev/mdpy.c | 81 +++- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c index e8c46eb2e246..bb2af1ec0f7c 100644 --- a/samples/vfio-mdev/mdpy.c +++ b/samples/vfio-mdev/mdpy.c @@ -216,61 +216,77 @@ static int mdpy_reset(struct mdev_state *mdev_state) return 0; } -static int mdpy_probe(struct mdev_device *mdev) +static int mdpy_init_dev(struct vfio_device *vdev) { + struct mdev_state *mdev_state = + container_of(vdev, struct mdev_state, vdev); + struct mdev_device *mdev = to_mdev_device(vdev->dev); const struct mdpy_type *type = _types[mdev_get_type_group_id(mdev)]; - struct device *dev = mdev_dev(mdev); - struct mdev_state *mdev_state; u32 fbsize; - int ret; + int ret = -ENOMEM; if (mdpy_count >= max_devices) - return -ENOMEM; - - mdev_state = kzalloc(sizeof(struct mdev_state), GFP_KERNEL); - if (mdev_state == NULL) - return -ENOMEM; - vfio_init_group_dev(_state->vdev, >dev, _dev_ops); + return ret; mdev_state->vconfig = kzalloc(MDPY_CONFIG_SPACE_SIZE, GFP_KERNEL); - if (mdev_state->vconfig == NULL) { - ret = -ENOMEM; - goto err_state; - } + if (!mdev_state->vconfig) + return ret; fbsize = roundup_pow_of_two(type->width * type->height * type->bytepp); mdev_state->memblk = vmalloc_user(fbsize); - if (!mdev_state->memblk) { - ret = -ENOMEM; - goto err_vconfig; - } - dev_info(dev, "%s: %s (%dx%d)\n", __func__, type->name, type->width, -type->height); + if (!mdev_state->memblk) + goto out_vconfig; mutex_init(_state->ops_lock); mdev_state->mdev = mdev; - mdev_state->type= type; + mdev_state->type = type; mdev_state->memsize = fbsize; mdpy_create_config_space(mdev_state); mdpy_reset(mdev_state); + dev_info(vdev->dev, "%s: %s (%dx%d)\n", __func__, type->name, type->width, +type->height); + mdpy_count++; + return 0; + +out_vconfig: + kfree(mdev_state->vconfig); + return ret; +} + +static int mdpy_probe(struct mdev_device *mdev) +{ + struct mdev_state *mdev_state; + int ret; + + mdev_state = vfio_alloc_device(mdev_state, vdev, >dev, + _dev_ops); + if (IS_ERR(mdev_state)) + return PTR_ERR(mdev_state); ret = vfio_register_emulated_iommu_dev(_state->vdev); if (ret) - goto err_mem; + goto err_put_vdev; dev_set_drvdata(>dev, mdev_state); return 0; -err_mem: + +err_put_vdev: + vfio_put_device(_state->vdev); + return ret; +} + +static void mdpy_release_dev(struct vfio_device *vdev) +{ + struct mdev_state *mdev_state = + container_of(vdev, struct mdev_state, vdev); + + mdpy_count--; vfree(mdev_state->memblk); -err_vconfig: kfree(mdev_state->vconfig); -err_state: - vfio_uninit_group_dev(_state->vdev); - kfree(mdev_state); - return ret; + vfio_free_device(vdev); } static void mdpy_remove(struct mdev_device *mdev) @@ -280,12 +296,7 @@ static void mdpy_remove(struct mdev_device *mdev) dev_info(>dev, "%s\n", __func__); vfio_unregister_group_dev(_state->vdev); - vfree(mdev_state->memblk); - kfree(mdev_state->vconfig); - vfio_uninit_group_dev(_state->vdev); - kfree(mdev_state); - - mdpy_count--; + vfio_put_device(_state->vdev); } static ssize_t mdpy_read(struct vfio_device *vdev, char __user *buf, @@ -708,6 +719,8 @@ static struct attribute_group *mdev_type_groups[] = { }; static const struct vfio_device_ops mdpy_dev_ops = { + .init = mdpy_init_dev, + .release = mdpy_release_dev, .read = mdpy_read, .write = mdpy_write, .ioctl = mdpy_ioctl, -- 2.21.3
[PATCH v4 04/15] vfio/hisi_acc: Use the new device life cycle helpers
From: Yi Liu Tidy up @probe so all migration specific initialization logic is moved to migration specific @init callback. Remove vfio_pci_core_{un}init_device() given no user now. Signed-off-by: Yi Liu Signed-off-by: Kevin Tian Reviewed-by: Jason Gunthorpe Reviewed-by: Shameer Kolothum --- .../vfio/pci/hisilicon/hisi_acc_vfio_pci.c| 80 +-- drivers/vfio/pci/vfio_pci_core.c | 30 --- include/linux/vfio_pci_core.h | 4 - 3 files changed, 37 insertions(+), 77 deletions(-) diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c index 258cae0863ea..47174e2b61bd 100644 --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c @@ -1213,8 +1213,28 @@ static const struct vfio_migration_ops hisi_acc_vfio_pci_migrn_state_ops = { .migration_get_state = hisi_acc_vfio_pci_get_device_state, }; +static int hisi_acc_vfio_pci_migrn_init_dev(struct vfio_device *core_vdev) +{ + struct hisi_acc_vf_core_device *hisi_acc_vdev = container_of(core_vdev, + struct hisi_acc_vf_core_device, core_device.vdev); + struct pci_dev *pdev = to_pci_dev(core_vdev->dev); + struct hisi_qm *pf_qm = hisi_acc_get_pf_qm(pdev); + + hisi_acc_vdev->vf_id = pci_iov_vf_id(pdev) + 1; + hisi_acc_vdev->pf_qm = pf_qm; + hisi_acc_vdev->vf_dev = pdev; + mutex_init(_acc_vdev->state_mutex); + + core_vdev->migration_flags = VFIO_MIGRATION_STOP_COPY; + core_vdev->mig_ops = _acc_vfio_pci_migrn_state_ops; + + return vfio_pci_core_init_dev(core_vdev); +} + static const struct vfio_device_ops hisi_acc_vfio_pci_migrn_ops = { .name = "hisi-acc-vfio-pci-migration", + .init = hisi_acc_vfio_pci_migrn_init_dev, + .release = vfio_pci_core_release_dev, .open_device = hisi_acc_vfio_pci_open_device, .close_device = hisi_acc_vfio_pci_close_device, .ioctl = hisi_acc_vfio_pci_ioctl, @@ -1228,6 +1248,8 @@ static const struct vfio_device_ops hisi_acc_vfio_pci_migrn_ops = { static const struct vfio_device_ops hisi_acc_vfio_pci_ops = { .name = "hisi-acc-vfio-pci", + .init = vfio_pci_core_init_dev, + .release = vfio_pci_core_release_dev, .open_device = hisi_acc_vfio_pci_open_device, .close_device = vfio_pci_core_close_device, .ioctl = vfio_pci_core_ioctl, @@ -1239,63 +1261,36 @@ static const struct vfio_device_ops hisi_acc_vfio_pci_ops = { .match = vfio_pci_core_match, }; -static int -hisi_acc_vfio_pci_migrn_init(struct hisi_acc_vf_core_device *hisi_acc_vdev, -struct pci_dev *pdev, struct hisi_qm *pf_qm) -{ - int vf_id; - - vf_id = pci_iov_vf_id(pdev); - if (vf_id < 0) - return vf_id; - - hisi_acc_vdev->vf_id = vf_id + 1; - hisi_acc_vdev->core_device.vdev.migration_flags = - VFIO_MIGRATION_STOP_COPY; - hisi_acc_vdev->pf_qm = pf_qm; - hisi_acc_vdev->vf_dev = pdev; - mutex_init(_acc_vdev->state_mutex); - - return 0; -} - static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct hisi_acc_vf_core_device *hisi_acc_vdev; + const struct vfio_device_ops *ops = _acc_vfio_pci_ops; struct hisi_qm *pf_qm; + int vf_id; int ret; - hisi_acc_vdev = kzalloc(sizeof(*hisi_acc_vdev), GFP_KERNEL); - if (!hisi_acc_vdev) - return -ENOMEM; - pf_qm = hisi_acc_get_pf_qm(pdev); if (pf_qm && pf_qm->ver >= QM_HW_V3) { - ret = hisi_acc_vfio_pci_migrn_init(hisi_acc_vdev, pdev, pf_qm); - if (!ret) { - vfio_pci_core_init_device(_acc_vdev->core_device, pdev, - _acc_vfio_pci_migrn_ops); - hisi_acc_vdev->core_device.vdev.mig_ops = - _acc_vfio_pci_migrn_state_ops; - } else { + vf_id = pci_iov_vf_id(pdev); + if (vf_id >= 0) + ops = _acc_vfio_pci_migrn_ops; + else pci_warn(pdev, "migration support failed, continue with generic interface\n"); - vfio_pci_core_init_device(_acc_vdev->core_device, pdev, - _acc_vfio_pci_ops); - } - } else { - vfio_pci_core_init_device(_acc_vdev->core_device, pdev, - _acc_vfio_pci_ops); } + hisi_acc_vdev = vfio_alloc_device(hisi_acc_vf_core_device, + core_device.vdev, >dev, ops); + if (IS_ERR(hisi_acc_vdev)) + return PTR_ERR(hisi_acc_vdev); + dev_set_drvdata(>dev, _acc_vdev->core_device); ret =
[PATCH v4 03/15] vfio/mlx5: Use the new device life cycle helpers
From: Yi Liu mlx5 has its own @init/@release for handling migration cap. Signed-off-by: Yi Liu Signed-off-by: Kevin Tian Reviewed-by: Jason Gunthorpe --- drivers/vfio/pci/mlx5/main.c | 50 ++-- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index 759a5f5f7b3f..fd6ccb8454a2 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -585,8 +585,35 @@ static const struct vfio_log_ops mlx5vf_pci_log_ops = { .log_read_and_clear = mlx5vf_tracker_read_and_clear, }; +static int mlx5vf_pci_init_dev(struct vfio_device *core_vdev) +{ + struct mlx5vf_pci_core_device *mvdev = container_of(core_vdev, + struct mlx5vf_pci_core_device, core_device.vdev); + int ret; + + ret = vfio_pci_core_init_dev(core_vdev); + if (ret) + return ret; + + mlx5vf_cmd_set_migratable(mvdev, _pci_mig_ops, + _pci_log_ops); + + return 0; +} + +static void mlx5vf_pci_release_dev(struct vfio_device *core_vdev) +{ + struct mlx5vf_pci_core_device *mvdev = container_of(core_vdev, + struct mlx5vf_pci_core_device, core_device.vdev); + + mlx5vf_cmd_remove_migratable(mvdev); + vfio_pci_core_release_dev(core_vdev); +} + static const struct vfio_device_ops mlx5vf_pci_ops = { .name = "mlx5-vfio-pci", + .init = mlx5vf_pci_init_dev, + .release = mlx5vf_pci_release_dev, .open_device = mlx5vf_pci_open_device, .close_device = mlx5vf_pci_close_device, .ioctl = vfio_pci_core_ioctl, @@ -604,22 +631,19 @@ static int mlx5vf_pci_probe(struct pci_dev *pdev, struct mlx5vf_pci_core_device *mvdev; int ret; - mvdev = kzalloc(sizeof(*mvdev), GFP_KERNEL); - if (!mvdev) - return -ENOMEM; - vfio_pci_core_init_device(>core_device, pdev, _pci_ops); - mlx5vf_cmd_set_migratable(mvdev, _pci_mig_ops, - _pci_log_ops); + mvdev = vfio_alloc_device(mlx5vf_pci_core_device, core_device.vdev, + >dev, _pci_ops); + if (IS_ERR(mvdev)) + return PTR_ERR(mvdev); + dev_set_drvdata(>dev, >core_device); ret = vfio_pci_core_register_device(>core_device); if (ret) - goto out_free; + goto out_put_vdev; return 0; -out_free: - mlx5vf_cmd_remove_migratable(mvdev); - vfio_pci_core_uninit_device(>core_device); - kfree(mvdev); +out_put_vdev: + vfio_put_device(>core_device.vdev); return ret; } @@ -628,9 +652,7 @@ static void mlx5vf_pci_remove(struct pci_dev *pdev) struct mlx5vf_pci_core_device *mvdev = mlx5vf_drvdata(pdev); vfio_pci_core_unregister_device(>core_device); - mlx5vf_cmd_remove_migratable(mvdev); - vfio_pci_core_uninit_device(>core_device); - kfree(mvdev); + vfio_put_device(>core_device.vdev); } static const struct pci_device_id mlx5vf_pci_table[] = { -- 2.21.3
[PATCH v4 02/15] vfio/pci: Use the new device life cycle helpers
From: Yi Liu Also introduce two pci core helpers as @init/@release for pci drivers: - vfio_pci_core_init_dev() - vfio_pci_core_release_dev() Signed-off-by: Yi Liu Signed-off-by: Kevin Tian Reviewed-by: Jason Gunthorpe --- drivers/vfio/pci/vfio_pci.c | 20 +- drivers/vfio/pci/vfio_pci_core.c | 35 include/linux/vfio_pci_core.h| 2 ++ 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index d9b5c03f8d5b..1d4919edfbde 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -127,6 +127,8 @@ static int vfio_pci_open_device(struct vfio_device *core_vdev) static const struct vfio_device_ops vfio_pci_ops = { .name = "vfio-pci", + .init = vfio_pci_core_init_dev, + .release= vfio_pci_core_release_dev, .open_device= vfio_pci_open_device, .close_device = vfio_pci_core_close_device, .ioctl = vfio_pci_core_ioctl, @@ -146,20 +148,19 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (vfio_pci_is_denylisted(pdev)) return -EINVAL; - vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); - if (!vdev) - return -ENOMEM; - vfio_pci_core_init_device(vdev, pdev, _pci_ops); + vdev = vfio_alloc_device(vfio_pci_core_device, vdev, >dev, +_pci_ops); + if (IS_ERR(vdev)) + return PTR_ERR(vdev); dev_set_drvdata(>dev, vdev); ret = vfio_pci_core_register_device(vdev); if (ret) - goto out_free; + goto out_put_vdev; return 0; -out_free: - vfio_pci_core_uninit_device(vdev); - kfree(vdev); +out_put_vdev: + vfio_put_device(>vdev); return ret; } @@ -168,8 +169,7 @@ static void vfio_pci_remove(struct pci_dev *pdev) struct vfio_pci_core_device *vdev = dev_get_drvdata(>dev); vfio_pci_core_unregister_device(vdev); - vfio_pci_core_uninit_device(vdev); - kfree(vdev); + vfio_put_device(>vdev); } static int vfio_pci_sriov_configure(struct pci_dev *pdev, int nr_virtfn) diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c index 0a801aee2f2d..77d33739c6e8 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -2078,6 +2078,41 @@ static void vfio_pci_vga_uninit(struct vfio_pci_core_device *vdev) VGA_RSRC_LEGACY_MEM); } +int vfio_pci_core_init_dev(struct vfio_device *core_vdev) +{ + struct vfio_pci_core_device *vdev = + container_of(core_vdev, struct vfio_pci_core_device, vdev); + + vdev->pdev = to_pci_dev(core_vdev->dev); + vdev->irq_type = VFIO_PCI_NUM_IRQS; + mutex_init(>igate); + spin_lock_init(>irqlock); + mutex_init(>ioeventfds_lock); + INIT_LIST_HEAD(>dummy_resources_list); + INIT_LIST_HEAD(>ioeventfds_list); + mutex_init(>vma_lock); + INIT_LIST_HEAD(>vma_list); + INIT_LIST_HEAD(>sriov_pfs_item); + init_rwsem(>memory_lock); + + return 0; +} +EXPORT_SYMBOL_GPL(vfio_pci_core_init_dev); + +void vfio_pci_core_release_dev(struct vfio_device *core_vdev) +{ + struct vfio_pci_core_device *vdev = + container_of(core_vdev, struct vfio_pci_core_device, vdev); + + mutex_destroy(>igate); + mutex_destroy(>ioeventfds_lock); + mutex_destroy(>vma_lock); + kfree(vdev->region); + kfree(vdev->pm_save); + vfio_free_device(core_vdev); +} +EXPORT_SYMBOL_GPL(vfio_pci_core_release_dev); + void vfio_pci_core_init_device(struct vfio_pci_core_device *vdev, struct pci_dev *pdev, const struct vfio_device_ops *vfio_pci_ops) diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h index 089b603bcfdc..0499ea836058 100644 --- a/include/linux/vfio_pci_core.h +++ b/include/linux/vfio_pci_core.h @@ -109,6 +109,8 @@ void vfio_pci_core_close_device(struct vfio_device *core_vdev); void vfio_pci_core_init_device(struct vfio_pci_core_device *vdev, struct pci_dev *pdev, const struct vfio_device_ops *vfio_pci_ops); +int vfio_pci_core_init_dev(struct vfio_device *core_vdev); +void vfio_pci_core_release_dev(struct vfio_device *core_vdev); int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev); void vfio_pci_core_uninit_device(struct vfio_pci_core_device *vdev); void vfio_pci_core_unregister_device(struct vfio_pci_core_device *vdev); -- 2.21.3
[PATCH v4 01/15] vfio: Add helpers for unifying vfio_device life cycle
The idea is to let vfio core manage the vfio_device life cycle instead of duplicating the logic cross drivers. This is also a preparatory step for adding struct device into vfio_device. New pair of helpers together with a kref in vfio_device: - vfio_alloc_device() - vfio_put_device() Drivers can register @init/@release callbacks to manage any private state wrapping the vfio_device. However vfio-ccw doesn't fit this model due to a life cycle mess that its private structure mixes both parent and mdev info hence must be allocated/freed outside of the life cycle of vfio device. Per prior discussions this won't be fixed in short term by IBM folks. Instead of waiting for those modifications introduce another helper vfio_init_device() so ccw can call it to initialize a pre-allocated vfio_device. Further implication of the ccw trick is that vfio_device cannot be freed uniformly in vfio core. Instead, require *EVERY* driver to implement @release and free vfio_device inside. Then ccw can choose to delay the free at its own discretion. Another trick down the road is that kvzalloc() is used to accommodate the need of gvt which uses vzalloc() while all others use kzalloc(). So drivers should call a helper vfio_free_device() to free the vfio_device instead of assuming that kfree() or vfree() is appliable. Later once the ccw mess is fixed we can remove those tricks and fully handle structure alloc/free in vfio core. Existing vfio_{un}init_group_dev() will be deprecated after all existing usages are converted to the new model. Suggested-by: Jason Gunthorpe Co-developed-by: Yi Liu Signed-off-by: Yi Liu Signed-off-by: Kevin Tian Reviewed-by: Tony Krowiak Reviewed-by: Jason Gunthorpe Reviewed-by: Eric Auger --- drivers/vfio/vfio_main.c | 92 include/linux/vfio.h | 25 ++- 2 files changed, 116 insertions(+), 1 deletion(-) diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index 27d9186f35d5..b9c6a97d647a 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -498,6 +498,98 @@ void vfio_uninit_group_dev(struct vfio_device *device) } EXPORT_SYMBOL_GPL(vfio_uninit_group_dev); +/* Release helper called by vfio_put_device() */ +void vfio_device_release(struct kref *kref) +{ + struct vfio_device *device = + container_of(kref, struct vfio_device, kref); + + vfio_uninit_group_dev(device); + + /* +* kvfree() cannot be done here due to a life cycle mess in +* vfio-ccw. Before the ccw part is fixed all drivers are +* required to support @release and call vfio_free_device() +* from there. +*/ + device->ops->release(device); +} +EXPORT_SYMBOL_GPL(vfio_device_release); + +/* + * Allocate and initialize vfio_device so it can be registered to vfio + * core. + * + * Drivers should use the wrapper vfio_alloc_device() for allocation. + * @size is the size of the structure to be allocated, including any + * private data used by the driver. + * + * Driver may provide an @init callback to cover device private data. + * + * Use vfio_put_device() to release the structure after success return. + */ +struct vfio_device *_vfio_alloc_device(size_t size, struct device *dev, + const struct vfio_device_ops *ops) +{ + struct vfio_device *device; + int ret; + + if (WARN_ON(size < sizeof(struct vfio_device))) + return ERR_PTR(-EINVAL); + + device = kvzalloc(size, GFP_KERNEL); + if (!device) + return ERR_PTR(-ENOMEM); + + ret = vfio_init_device(device, dev, ops); + if (ret) + goto out_free; + return device; + +out_free: + kvfree(device); + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(_vfio_alloc_device); + +/* + * Initialize a vfio_device so it can be registered to vfio core. + * + * Only vfio-ccw driver should call this interface. + */ +int vfio_init_device(struct vfio_device *device, struct device *dev, +const struct vfio_device_ops *ops) +{ + int ret; + + vfio_init_group_dev(device, dev, ops); + + if (ops->init) { + ret = ops->init(device); + if (ret) + goto out_uninit; + } + + kref_init(>kref); + return 0; + +out_uninit: + vfio_uninit_group_dev(device); + return ret; +} +EXPORT_SYMBOL_GPL(vfio_init_device); + +/* + * The helper called by driver @release callback to free the device + * structure. Drivers which don't have private data to clean can + * simply use this helper as its @release. + */ +void vfio_free_device(struct vfio_device *device) +{ + kvfree(device); +} +EXPORT_SYMBOL_GPL(vfio_free_device); + static struct vfio_group *vfio_noiommu_group_alloc(struct device *dev, enum vfio_group_type type) { diff --git a/include/linux/vfio.h b/include/linux/vfio.h index
[PATCH v4 00/15] Tidy up vfio_device life cycle
The idea is to let vfio core manage the vfio_device life cycle instead of duplicating the logic cross drivers. Besides cleaner code in driver side this also allows adding struct device to vfio_device as the first step toward adding cdev uAPI in the future. Another benefit is that user can now look at sysfs to decide whether a device is bound to vfio [1], e.g.: /sys/devices/pci\:6f/\:6f\:01.0/vfio-dev/vfio0 Though most drivers can fit the new model naturally: - vfio_alloc_device() to allocate and initialize vfio_device - vfio_put_device() to release vfio_device - dev_ops->init() for driver private initialization - dev_ops->release() for driver private cleanup vfio-ccw is the only exception due to a life cycle mess that its private structure mixes both parent and mdev info hence must be alloc/freed outside of the life cycle of vfio device. Per prior discussions this won't be fixed in short term by IBM folks [2]. Instead of waiting this series introduces a few tricks to move forward: - vfio_init_device() to initialize a pre-allocated device structure; - require *EVERY* driver to implement @release and free vfio_device inside. Then vfio-ccw can use a completion mechanism to delay the free to css driver; The second trick is not a real burden to other drivers because they all require a @release for private cleanup anyway. Later once the ccw mess is fixed a simple cleanup can be done by moving free from @release to vfio core. Thanks Kevin [1] https://listman.redhat.com/archives/libvir-list/2022-August/233482.html [2] https://lore.kernel.org/all/0ee29bd6583f17f0ee4ec0769fa50e8ea6703623.ca...@linux.ibm.com/ v4: - fix use-after-free issue in @release of mtty/mbochs and also change mdpy/ap to free vfio-device as the last thing in @release (Alex) - revert the rename from 'vfio' to 'vfio_group' in procfs (Alex) v3: - https://lore.kernel.org/lkml/20220909102247.67324-1-kevin.t...@intel.com/ - rebase to vfio-next after resolving conflicts with Yishai's series - add missing fixes for two checkpatch errors - fix grammar issues (Eric Auger) - add more r-b's v2: - https://lore.kernel.org/lkml/20220901143747.32858-1-kevin.t...@intel.com/ - rebase to 6.0-rc3 - fix build warnings (lkp) - patch1: remove unnecessary forward reference (Jason) - patch10: leave device_set released by vfio core (Jason) - patch13: add Suggested-by - patch15: add ABI file sysfs-devices-vfio-dev (Alex) - patch15: rename 'vfio' to 'vfio_group' in procfs (Jason) v1: https://lore.kernel.org/lkml/20220827171037.30297-1-kevin.t...@intel.com/ Kevin Tian (6): vfio: Add helpers for unifying vfio_device life cycle drm/i915/gvt: Use the new device life cycle helpers vfio/platform: Use the new device life cycle helpers vfio/amba: Use the new device life cycle helpers vfio/ccw: Use the new device life cycle helpers vfio: Rename vfio_device_put() and vfio_device_try_get() Yi Liu (9): vfio/pci: Use the new device life cycle helpers vfio/mlx5: Use the new device life cycle helpers vfio/hisi_acc: Use the new device life cycle helpers vfio/mdpy: Use the new device life cycle helpers vfio/mtty: Use the new device life cycle helpers vfio/mbochs: Use the new device life cycle helpers vfio/ap: Use the new device life cycle helpers vfio/fsl-mc: Use the new device life cycle helpers vfio: Add struct device to vfio_device .../ABI/testing/sysfs-devices-vfio-dev| 8 + MAINTAINERS | 1 + drivers/gpu/drm/i915/gvt/gvt.h| 5 +- drivers/gpu/drm/i915/gvt/kvmgt.c | 52 -- drivers/gpu/drm/i915/gvt/vgpu.c | 33 ++-- drivers/s390/cio/vfio_ccw_ops.c | 52 +- drivers/s390/cio/vfio_ccw_private.h | 3 + drivers/s390/crypto/vfio_ap_ops.c | 50 +++--- drivers/vfio/fsl-mc/vfio_fsl_mc.c | 85 + .../vfio/pci/hisilicon/hisi_acc_vfio_pci.c| 80 - drivers/vfio/pci/mlx5/main.c | 50 -- drivers/vfio/pci/vfio_pci.c | 20 +-- drivers/vfio/pci/vfio_pci_core.c | 23 ++- drivers/vfio/platform/vfio_amba.c | 72 ++-- drivers/vfio/platform/vfio_platform.c | 66 +-- drivers/vfio/platform/vfio_platform_common.c | 71 +++- drivers/vfio/platform/vfio_platform_private.h | 18 +- drivers/vfio/vfio_main.c | 164 +++--- include/linux/vfio.h | 28 ++- include/linux/vfio_pci_core.h | 6 +- samples/vfio-mdev/mbochs.c| 73 +--- samples/vfio-mdev/mdpy.c | 81 + samples/vfio-mdev/mtty.c | 67 --- 23 files changed, 728 insertions(+), 380 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-devices-vfio-dev base-commit: f39856aacb078c1c93acef011a37121b17d54fe0 -- 2.21.3
Re: [PATCH v1 01/17] dt-bindings: clk: mediatek: Add MT8195 DPI clocks
On Mon, 2022-09-19 at 18:55 +0200, Guillaume Ranquet wrote: > From: Pablo Sun > > Expand dt-bindings slot for VDOSYS1 of MT8195. > This clock is required by the DPI1 hardware > and is a downstream of the HDMI pixel clock. > > Signed-off-by: Pablo Sun > Signed-off-by: Guillaume Ranquet > Reviewed-by: Mattijs Korpershoek > > diff --git a/include/dt-bindings/clock/mt8195-clk.h b/include/dt- > bindings/clock/mt8195-clk.h > index 95cf812a0b37..d70d017ad69c 100644 > --- a/include/dt-bindings/clock/mt8195-clk.h > +++ b/include/dt-bindings/clock/mt8195-clk.h > @@ -859,6 +859,8 @@ > #define CLK_VDO1_DPINTF 47 > #define CLK_VDO1_DISP_MONITOR_DPINTF 48 > #define CLK_VDO1_26M_SLOW49 > -#define CLK_VDO1_NR_CLK 50 > +#define CLK_VDO1_DPI1_HDMI 50 > +#define CLK_VDO1_NR_CLK 51 > + > > #endif /* _DT_BINDINGS_CLK_MT8195_H */ Hello Guillaume, I am not sure the reason, but it seems patches in this series lack of something like this for whole series: --- Documentation/devicetree/bindings/watchdog/mtk-wdt.txt | 1 + 1 file changed, 1 insertion(+) BRs, Bo-Chen
Re: [PATCH v9 09/10] leds: flash: mt6370: Add MediaTek MT6370 flashlight support
On Sun, Sep 18, 2022 at 3:22 AM Han Jingoo wrote: > > On Mon, Aug 29, 2022 ChiaEn Wu wrote: ... > > +#define MT6370_ITORCH_MIN_uA 25000 > > +#define MT6370_ITORCH_STEP_uA 12500 > > +#define MT6370_ITORCH_MAX_uA 40 > > +#define MT6370_ITORCH_DOUBLE_MAX_uA80 > > +#define MT6370_ISTRB_MIN_uA5 > > +#define MT6370_ISTRB_STEP_uA 12500 > > +#define MT6370_ISTRB_MAX_uA150 > > +#define MT6370_ISTRB_DOUBLE_MAX_uA 300 > > Use upper letters as below: > > #define MT6370_ITORCH_MIN_UA 25000 > #define MT6370_ITORCH_STEP_UA 12500 > #define MT6370_ITORCH_MAX_UA 40 > #define MT6370_ITORCH_DOUBLE_MAX_UA80 > #define MT6370_ISTRB_MIN_UA5 > #define MT6370_ISTRB_STEP_UA 12500 > #define MT6370_ISTRB_MAX_UA150 > #define MT6370_ISTRB_DOUBLE_MAX_UA 300 > > > > +#define MT6370_STRBTO_MIN_US 64000 > > +#define MT6370_STRBTO_STEP_US 32000 > > +#define MT6370_STRBTO_MAX_US 2432000 > > + Hi Jingoo, This coding style is in accordance with Andy's opinion in this mail: https://lore.kernel.org/linux-arm-kernel/CAHp75Vciq4M4kVrabNV9vTLLcd1vR=bme8jledaf9mkrtpc...@mail.gmail.com/ And I will revise other parts in v12. Thanks for your review! -- Best Regards, ChiaEn Wu
Re: [PATCH v6,3/3] drm: mediatek: Add mt8186 dpi compatible to mtk_dpi.c
Hi, Xinlei: On Wed, 2022-09-14 at 21:21 +0800, xinlei@mediatek.com wrote: > From: Xinlei Lee > > Add the compatible because use edge_cfg_in_mmsys in mt8186. > > Signed-off-by: Xinlei Lee > --- > drivers/gpu/drm/mediatek/mtk_dpi.c | 21 + > drivers/gpu/drm/mediatek/mtk_drm_drv.c | 2 ++ > 2 files changed, 23 insertions(+) > > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c > b/drivers/gpu/drm/mediatek/mtk_dpi.c > index 6e02f02f163c..52bcc4114afd 100644 > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c > @@ -942,6 +942,24 @@ static const struct mtk_dpi_conf mt8183_conf = { > .csc_enable_bit = CSC_ENABLE, > }; > > +static const struct mtk_dpi_conf mt8186_conf = { > + .cal_factor = mt8183_calculate_factor, > + .reg_h_fre_con = 0xe0, > + .max_clock_khz = 15, > + .output_fmts = mt8183_output_fmts, > + .num_output_fmts = ARRAY_SIZE(mt8183_output_fmts), > + .edge_cfg_in_mmsys = true, According to the previous review, edge_cfg_in_mmsys is not necessary, so mt8186_conf is identical to mt8192_conf. Regards, CK > + .pixels_per_iter = 1, > + .is_ck_de_pol = true, > + .swap_input_support = true, > + .support_direct_pin = true, > + .dimension_mask = HPW_MASK, > + .hvsize_mask = HSIZE_MASK, > + .channel_swap_shift = CH_SWAP, > + .yuv422_en_bit = YUV422_EN, > + .csc_enable_bit = CSC_ENABLE, > +}; > + > static const struct mtk_dpi_conf mt8192_conf = { > .cal_factor = mt8183_calculate_factor, > .reg_h_fre_con = 0xe0, > @@ -1092,6 +1110,9 @@ static const struct of_device_id > mtk_dpi_of_ids[] = { > { .compatible = "mediatek,mt8183-dpi", > .data = _conf, > }, > + { .compatible = "mediatek,mt8186-dpi", > + .data = _conf, > + }, > { .compatible = "mediatek,mt8192-dpi", > .data = _conf, > }, > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c > index 546b79412815..3d32fbc66ac1 100644 > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c > @@ -646,6 +646,8 @@ static const struct of_device_id > mtk_ddp_comp_dt_ids[] = { > .data = (void *)MTK_DPI }, > { .compatible = "mediatek,mt8183-dpi", > .data = (void *)MTK_DPI }, > + { .compatible = "mediatek,mt8186-dpi", > + .data = (void *)MTK_DPI }, > { .compatible = "mediatek,mt8192-dpi", > .data = (void *)MTK_DPI }, > { .compatible = "mediatek,mt8195-dp-intf",
Re: [PATCH v6,2/3] drm: mediatek: Adjust the dpi output format to MT8186
Hi, Xinlei: On Wed, 2022-09-14 at 21:21 +0800, xinlei@mediatek.com wrote: > From: Xinlei Lee > > Dpi output needs to adjust the output format to dual edge for MT8186. > The bridge ic on MT8186 uses the output format of RGB888_dual_edge. I think different sink ic may support different output format, so query the sink information to decide which outout format. > Due > to hardware changes, we need to modify the output format > corresponding > to the mmsys register. > > Co-developed-by: Jitao Shi > Signed-off-by: Jitao Shi > Signed-off-by: Xinlei Lee > Reviewed-by: AngeloGioacchino Del Regno < > angelogioacchino.delre...@collabora.com> > Reviewed-by: Nís F. R. A. Prado > --- > drivers/gpu/drm/mediatek/mtk_dpi.c | 14 ++ > 1 file changed, 14 insertions(+) > > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c > b/drivers/gpu/drm/mediatek/mtk_dpi.c > index fb0b79704636..6e02f02f163c 100644 > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c > @@ -14,6 +14,7 @@ > #include > #include > #include > +#include > #include > > #include > @@ -28,6 +29,7 @@ > #include "mtk_disp_drv.h" > #include "mtk_dpi_regs.h" > #include "mtk_drm_ddp_comp.h" > +#include "mtk_drm_drv.h" > > enum mtk_dpi_out_bit_num { > MTK_DPI_OUT_BIT_NUM_8BITS, > @@ -58,6 +60,11 @@ enum mtk_dpi_out_color_format { > MTK_DPI_COLOR_FORMAT_YCBCR_422 > }; > > +enum mtk_dpi_out_format_con { > + MTK_DPI_RGB888_DDR_CON, > + MTK_DPI_RGB565_SDR_CON > +}; > + > struct mtk_dpi { > struct drm_encoder encoder; > struct drm_bridge bridge; > @@ -80,6 +87,7 @@ struct mtk_dpi { > struct pinctrl_state *pins_dpi; > u32 output_fmt; > int refcount; > + struct device *mmsys_dev; > }; > > static inline struct mtk_dpi *bridge_to_dpi(struct drm_bridge *b) > @@ -133,6 +141,7 @@ struct mtk_dpi_yc_limit { > * @yuv422_en_bit: Enable bit of yuv422. > * @csc_enable_bit: Enable bit of CSC. > * @pixels_per_iter: Quantity of transferred pixels per iteration. > + * @edge_cfg_in_mmsys: If the edge configuration for DPI's output > needs to be set in MMSYS. > */ > struct mtk_dpi_conf { > unsigned int (*cal_factor)(int clock); > @@ -151,6 +160,7 @@ struct mtk_dpi_conf { > u32 yuv422_en_bit; > u32 csc_enable_bit; > u32 pixels_per_iter; > + bool edge_cfg_in_mmsys; > }; > > static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, > u32 mask) > @@ -447,6 +457,8 @@ static void mtk_dpi_dual_edge(struct mtk_dpi > *dpi) > mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, >dpi->output_fmt == > MEDIA_BUS_FMT_RGB888_2X12_LE ? >EDGE_SEL : 0, EDGE_SEL); > + if (dpi->conf->edge_cfg_in_mmsys) > + mtk_mmsys_ddp_dpi_fmt_config(dpi->mmsys_dev, > MTK_DPI_RGB888_DDR_CON); Why do you set a DPI driver defined value MTK_DPI_RGB888_DDR_CON into mmsys driver? I think you should set a value which mmsys driver understand. Regards, CK > } else { > mtk_dpi_mask(dpi, DPI_DDR_SETTING, DDR_EN | DDR_4PHASE, > 0); > } > @@ -776,8 +788,10 @@ static int mtk_dpi_bind(struct device *dev, > struct device *master, void *data) > { > struct mtk_dpi *dpi = dev_get_drvdata(dev); > struct drm_device *drm_dev = data; > + struct mtk_drm_private *priv = drm_dev->dev_private; > int ret; > > + dpi->mmsys_dev = priv->mmsys_dev; > ret = drm_simple_encoder_init(drm_dev, >encoder, > DRM_MODE_ENCODER_TMDS); > if (ret) {
[PATCH -next] drm/amd/display: clean up one inconsistent indenting
clean up one inconsistent indenting https://bugzilla.openanolis.cn/show_bug.cgi?id=2238 Reported-by: Abaci Robot Signed-off-by: Yang Li --- drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c index c772ef962194..0f977d14f927 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c @@ -1653,7 +1653,7 @@ static bool dcn321_resource_construct( #undef REG_STRUCT #define REG_STRUCT dccg_regs - dccg_regs_init(); + dccg_regs_init(); ctx->dc_bios->regs = _regs; -- 2.20.1.7.g153144c
Re: [PATCH 1/2] drm/amd/display: Reduce number of arguments of dml314's CalculateWatermarksAndDRAMSpeedChangeSupport()
On Tue, Sep 20, 2022 at 7:48 PM Nathan Chancellor wrote: > > On Tue, Sep 20, 2022 at 12:06:46PM -0400, Alex Deucher wrote: > > Applied the series. Thanks! > > Great, thank you so much! Hopefully these could also be applied to the > 6.0 branch so that this error can be resolved there as well. No worries > on timeline if that was already the plan but I just want to keep -Werror > on for arm64 and x86_64 allmodconfig for this release. Yes, that is the plan. Alex > > Cheers, > Nathan > > > On Sat, Sep 17, 2022 at 8:38 AM Maíra Canal wrote: > > > > > > Hi Nathan, > > > > > > On 9/16/22 18:06, Nathan Chancellor wrote: > > > > Most of the arguments are identical between the two call sites and they > > > > can be accessed through the 'struct vba_vars_st' pointer. This reduces > > > > the total amount of stack space that > > > > dml314_ModeSupportAndSystemConfigurationFull() uses by 240 bytes with > > > > LLVM 16 (2216 -> 1976), helping clear up the following clang warning: > > > > > > > > > > > > drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn314/display_mode_vba_314.c:4020:6: > > > > error: stack frame size (2216) exceeds limit (2048) in > > > > 'dml314_ModeSupportAndSystemConfigurationFull' > > > > [-Werror,-Wframe-larger-than] > > > > void dml314_ModeSupportAndSystemConfigurationFull(struct > > > > display_mode_lib *mode_lib) > > > >^ > > > > 1 error generated. > > > > > > > > Link: https://github.com/ClangBuiltLinux/linux/issues/1710 > > > > Reported-by: "kernelci.org bot" > > > > Signed-off-by: Nathan Chancellor > > > > > > I have built-tested the whole series with clang 14.0.5 (Fedora > > > 14.0.5-1.fc36), using: > > > > > > $ make -kj"$(nproc)" ARCH=x86_64 LLVM=1 mrproper allmodconfig > > > drivers/gpu/drm/amd/amdgpu/ > > > > > > Another great patch to the DML! As Tom, I also would like to see this > > > expand to all display_mode_vba files, but so far this is great to > > > unbreak the build. > > > > > > To the whole series: > > > > > > Tested-by: Maíra Canal > > > > > > Best Regards, > > > - Maíra Canal > > > > > > > --- > > > > > > > > This is just commit ab2ac59c32db ("drm/amd/display: Reduce number of > > > > arguments of dml31's CalculateWatermarksAndDRAMSpeedChangeSupport()") > > > > applied to dml314. > > > > > > > > .../dc/dml/dcn314/display_mode_vba_314.c | 248 -- > > > > 1 file changed, 52 insertions(+), 196 deletions(-) > > > > > > > > diff --git > > > > a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c > > > > b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c > > > > index 2829f179f982..32ceb72f7a14 100644 > > > > --- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c > > > > +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c > > > > @@ -325,64 +325,28 @@ static void > > > > CalculateVupdateAndDynamicMetadataParameters( > > > > static void CalculateWatermarksAndDRAMSpeedChangeSupport( > > > > struct display_mode_lib *mode_lib, > > > > unsigned int PrefetchMode, > > > > - unsigned int NumberOfActivePlanes, > > > > - unsigned int MaxLineBufferLines, > > > > - unsigned int LineBufferSize, > > > > - unsigned int WritebackInterfaceBufferSize, > > > > double DCFCLK, > > > > double ReturnBW, > > > > - bool SynchronizedVBlank, > > > > - unsigned int dpte_group_bytes[], > > > > - unsigned int MetaChunkSize, > > > > double UrgentLatency, > > > > double ExtraLatency, > > > > - double WritebackLatency, > > > > - double WritebackChunkSize, > > > > double SOCCLK, > > > > - double DRAMClockChangeLatency, > > > > - double SRExitTime, > > > > - double SREnterPlusExitTime, > > > > - double SRExitZ8Time, > > > > - double SREnterPlusExitZ8Time, > > > > double DCFCLKDeepSleep, > > > > unsigned int DETBufferSizeY[], > > > > unsigned int DETBufferSizeC[], > > > > unsigned int SwathHeightY[], > > > > unsigned int SwathHeightC[], > > > > - unsigned int LBBitPerPixel[], > > > > double SwathWidthY[], > > > > double SwathWidthC[], > > > > - double HRatio[], > > > > - double HRatioChroma[], > > > > - unsigned int vtaps[], > > > > - unsigned int VTAPsChroma[], > > > > - double VRatio[], > > > > - double VRatioChroma[], > > > > - unsigned int HTotal[], > > > > - double PixelClock[], > > > > - unsigned int BlendingAndTiming[], > > > > unsigned int DPPPerPlane[], > > > > double BytePerPixelDETY[], > > > > double BytePerPixelDETC[], > > > > - double DSTXAfterScaler[], > > > >
Re: [PATCH 3/7] drm/i915/hwmon: Power PL1 limit and TDP setting
On Fri, 16 Sep 2022 08:00:50 -0700, Badal Nilawar wrote: > > diff --git a/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon > b/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon > index e2974f928e58..bc061238e35c 100644 > --- a/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon > +++ b/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon > @@ -5,3 +5,23 @@ Contact: dri-devel@lists.freedesktop.org > Description: RO. Current Voltage in millivolt. > > Only supported for particular Intel i915 graphics platforms. > + > +What:/sys/devices/.../hwmon/hwmon/power1_max > +Date:September 2022 > +KernelVersion: 6 Maybe we should ask someone but even if we merge this today to drm-tip this will appear in kernel.org Linus' version only in 6.2. So I think we should set this as 6.2 on all patches. Except for this, thanks for making the changes, this is: Reviewed-by: Ashutosh Dixit
Re: [PATCH 1/2] drm/amd/display: Reduce number of arguments of dml314's CalculateWatermarksAndDRAMSpeedChangeSupport()
On Tue, Sep 20, 2022 at 12:06:46PM -0400, Alex Deucher wrote: > Applied the series. Thanks! Great, thank you so much! Hopefully these could also be applied to the 6.0 branch so that this error can be resolved there as well. No worries on timeline if that was already the plan but I just want to keep -Werror on for arm64 and x86_64 allmodconfig for this release. Cheers, Nathan > On Sat, Sep 17, 2022 at 8:38 AM Maíra Canal wrote: > > > > Hi Nathan, > > > > On 9/16/22 18:06, Nathan Chancellor wrote: > > > Most of the arguments are identical between the two call sites and they > > > can be accessed through the 'struct vba_vars_st' pointer. This reduces > > > the total amount of stack space that > > > dml314_ModeSupportAndSystemConfigurationFull() uses by 240 bytes with > > > LLVM 16 (2216 -> 1976), helping clear up the following clang warning: > > > > > > > > > drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn314/display_mode_vba_314.c:4020:6: > > > error: stack frame size (2216) exceeds limit (2048) in > > > 'dml314_ModeSupportAndSystemConfigurationFull' > > > [-Werror,-Wframe-larger-than] > > > void dml314_ModeSupportAndSystemConfigurationFull(struct > > > display_mode_lib *mode_lib) > > >^ > > > 1 error generated. > > > > > > Link: https://github.com/ClangBuiltLinux/linux/issues/1710 > > > Reported-by: "kernelci.org bot" > > > Signed-off-by: Nathan Chancellor > > > > I have built-tested the whole series with clang 14.0.5 (Fedora > > 14.0.5-1.fc36), using: > > > > $ make -kj"$(nproc)" ARCH=x86_64 LLVM=1 mrproper allmodconfig > > drivers/gpu/drm/amd/amdgpu/ > > > > Another great patch to the DML! As Tom, I also would like to see this > > expand to all display_mode_vba files, but so far this is great to > > unbreak the build. > > > > To the whole series: > > > > Tested-by: Maíra Canal > > > > Best Regards, > > - Maíra Canal > > > > > --- > > > > > > This is just commit ab2ac59c32db ("drm/amd/display: Reduce number of > > > arguments of dml31's CalculateWatermarksAndDRAMSpeedChangeSupport()") > > > applied to dml314. > > > > > > .../dc/dml/dcn314/display_mode_vba_314.c | 248 -- > > > 1 file changed, 52 insertions(+), 196 deletions(-) > > > > > > diff --git > > > a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c > > > b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c > > > index 2829f179f982..32ceb72f7a14 100644 > > > --- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c > > > +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c > > > @@ -325,64 +325,28 @@ static void > > > CalculateVupdateAndDynamicMetadataParameters( > > > static void CalculateWatermarksAndDRAMSpeedChangeSupport( > > > struct display_mode_lib *mode_lib, > > > unsigned int PrefetchMode, > > > - unsigned int NumberOfActivePlanes, > > > - unsigned int MaxLineBufferLines, > > > - unsigned int LineBufferSize, > > > - unsigned int WritebackInterfaceBufferSize, > > > double DCFCLK, > > > double ReturnBW, > > > - bool SynchronizedVBlank, > > > - unsigned int dpte_group_bytes[], > > > - unsigned int MetaChunkSize, > > > double UrgentLatency, > > > double ExtraLatency, > > > - double WritebackLatency, > > > - double WritebackChunkSize, > > > double SOCCLK, > > > - double DRAMClockChangeLatency, > > > - double SRExitTime, > > > - double SREnterPlusExitTime, > > > - double SRExitZ8Time, > > > - double SREnterPlusExitZ8Time, > > > double DCFCLKDeepSleep, > > > unsigned int DETBufferSizeY[], > > > unsigned int DETBufferSizeC[], > > > unsigned int SwathHeightY[], > > > unsigned int SwathHeightC[], > > > - unsigned int LBBitPerPixel[], > > > double SwathWidthY[], > > > double SwathWidthC[], > > > - double HRatio[], > > > - double HRatioChroma[], > > > - unsigned int vtaps[], > > > - unsigned int VTAPsChroma[], > > > - double VRatio[], > > > - double VRatioChroma[], > > > - unsigned int HTotal[], > > > - double PixelClock[], > > > - unsigned int BlendingAndTiming[], > > > unsigned int DPPPerPlane[], > > > double BytePerPixelDETY[], > > > double BytePerPixelDETC[], > > > - double DSTXAfterScaler[], > > > - double DSTYAfterScaler[], > > > - bool WritebackEnable[], > > > - enum source_format_class WritebackPixelFormat[], > > > - double WritebackDestinationWidth[], > > > - double WritebackDestinationHeight[], > > > - double
Re: [PATCH v4] drm/msm/dp: add atomic_check to bridge ops
On 9/20/2022 3:25 PM, Kuogee Hsieh wrote: DRM commit_tails() will disable downstream crtc/encoder/bridge if both disable crtc is required and crtc->active is set before pushing a new frame downstream. There is a rare case that user space display manager issue an extra screen update immediately followed by close DRM device while down stream display interface is disabled. This extra screen update will timeout due to the downstream interface is disabled but will cause crtc->active be set. Hence the followed commit_tails() called by drm_release() will pass the disable downstream crtc/encoder/bridge conditions checking even downstream interface is disabled. This cause the crash to happen at dp_bridge_disable() due to it trying to access the main link register to push the idle pattern out while main link clocks is disabled. This patch adds atomic_check to prevent the extra frame will not be pushed down if display interface is down so that crtc->active will not be set neither. This will fail the conditions checking of disabling down stream crtc/encoder/bridge which prevent drm_release() from calling dp_bridge_disable() so that crash at dp_bridge_disable() prevented. There is no protection in the DRM framework to check if the display pipeline has been already disabled before trying again. The only check is the crtc_state->active but this is controlled by usermode using UAPI. Hence if the usermode sets this and then crashes, the driver needs to protect against double disable" SError Interrupt on CPU7, code 0xbe000411 -- SError CPU: 7 PID: 3878 Comm: Xorg Not tainted 5.19.0-stb-cbq #19 Hardware name: Google Lazor (rev3 - 8) (DT) pstate: a04000c9 (NzCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : __cmpxchg_case_acq_32+0x14/0x2c lr : do_raw_spin_lock+0xa4/0xdc sp : ffc01092b6a0 x29: ffc01092b6a0 x28: 0028 x27: 0038 x26: 0004 x25: ffd2973dce48 x24: x23: x22: x21: ffd2978d0008 x20: ffd2978d0008 x19: ff80ff759fc0 x18: x17: 004800a501260460 x16: 0441043b04600438 x15: 0438089807d0 x14: 07b0089807800780 x13: x12: x11: 0438 x10: 07d0 x9 : ffd2973e09e4 x8 : ff8092d53300 x7 : ff808902e8b8 x6 : 0001 x5 : ff808902e880 x4 : x3 : ff80ff759fc0 x2 : 0001 x1 : x0 : ff80ff759fc0 Kernel panic - not syncing: Asynchronous SError Interrupt CPU: 7 PID: 3878 Comm: Xorg Not tainted 5.19.0-stb-cbq #19 Hardware name: Google Lazor (rev3 - 8) (DT) Call trace: dump_backtrace.part.0+0xbc/0xe4 show_stack+0x24/0x70 dump_stack_lvl+0x68/0x84 dump_stack+0x18/0x34 panic+0x14c/0x32c nmi_panic+0x58/0x7c arm64_serror_panic+0x78/0x84 do_serror+0x40/0x64 el1h_64_error_handler+0x30/0x48 el1h_64_error+0x68/0x6c __cmpxchg_case_acq_32+0x14/0x2c _raw_spin_lock_irqsave+0x38/0x4c lock_timer_base+0x40/0x78 __mod_timer+0xf4/0x25c schedule_timeout+0xd4/0xfc __wait_for_common+0xac/0x140 wait_for_completion_timeout+0x2c/0x54 dp_ctrl_push_idle+0x40/0x88 dp_bridge_disable+0x24/0x30 drm_atomic_bridge_chain_disable+0x90/0xbc drm_atomic_helper_commit_modeset_disables+0x198/0x444 msm_atomic_commit_tail+0x1d0/0x374 commit_tail+0x80/0x108 drm_atomic_helper_commit+0x118/0x11c drm_atomic_commit+0xb4/0xe0 drm_client_modeset_commit_atomic+0x184/0x224 drm_client_modeset_commit_locked+0x58/0x160 drm_client_modeset_commit+0x3c/0x64 __drm_fb_helper_restore_fbdev_mode_unlocked+0x98/0xac drm_fb_helper_set_par+0x74/0x80 drm_fb_helper_hotplug_event+0xdc/0xe0 __drm_fb_helper_restore_fbdev_mode_unlocked+0x7c/0xac drm_fb_helper_restore_fbdev_mode_unlocked+0x20/0x2c drm_fb_helper_lastclose+0x20/0x2c drm_lastclose+0x44/0x6c drm_release+0x88/0xd4 __fput+0x104/0x220 fput+0x1c/0x28 task_work_run+0x8c/0x100 do_exit+0x450/0x8d0 do_group_exit+0x40/0xac __wake_up_parent+0x0/0x38 invoke_syscall+0x84/0x11c el0_svc_common.constprop.0+0xb8/0xe4 do_el0_svc+0x8c/0xb8 el0_svc+0x2c/0x54 el0t_64_sync_handler+0x120/0x1c0 el0t_64_sync+0x190/0x194 SMP: stopping secondary CPUs Kernel Offset: 0x128e80 from 0xffc00800 PHYS_OFFSET: 0x8000 CPU features: 0x800,00c2a015,19801c82 Memory Limit: none Changes in v2: -- add more commit text Changes in v3: -- add comments into dp_bridge_atomic_check() Changes in v4: -- rewording the comment into dp_bridge_atomic_check() Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display enable and disable") Reported-by: Leonard Lausen Suggested-by: Rob Clark Closes: https://gitlab.freedesktop.org/drm/msm/-/issues/17 Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/dp/dp_drm.c | 34 ++ 1 file changed, 34 insertions(+) diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c index 6df25f7..2e8e8ce 100644 ---
Re: [BUG] ls1046a: eDMA does not transfer data from I2C
On 9/20/22 6:49 PM, Leo Li wrote: > > >> -Original Message- >> From: Sean Anderson >> Sent: Tuesday, September 20, 2022 11:21 AM >> To: Robin Murphy ; Oleksij Rempel >> ; Pengutronix Kernel Team >> ; linux-...@vger.kernel.org; linux-arm-kernel >> ; Vinod Koul ; >> dmaeng...@vger.kernel.org; Leo Li ; Laurentiu Tudor >> >> Cc: Linux Kernel Mailing List ; dri- >> de...@lists.freedesktop.org; Christian König ; >> linaro-mm-...@lists.linaro.org; Shawn Guo ; Sumit >> Semwal ; Joy Zou ; linux- >> me...@vger.kernel.org >> Subject: Re: [BUG] ls1046a: eDMA does not transfer data from I2C >> >> >> >> On 9/20/22 11:44 AM, Sean Anderson wrote: >> > >> > >> > On 9/20/22 11:24 AM, Sean Anderson wrote: >> >> >> >> >> >> On 9/20/22 6:07 AM, Robin Murphy wrote: >> >>> On 2022-09-19 23:24, Sean Anderson wrote: >> Hi all, >> >> I discovered a bug in either imx_i2c or fsl-edma on the LS1046A >> where no data is read in i2c_imx_dma_read except for the last two >> bytes (which are not read using DMA). This is perhaps best >> illustrated with the following example: >> >> # hexdump -C /sys/bus/nvmem/devices/0-00540/nvmem >> [ 308.914884] i2c i2c-0: 00080938 0x00088938 >> 0xf5401000 75401000 >> [ 308.923529] src= 2180004 dst=f5401000 attr= 0 soff= 0 nbytes=1 >> slast= 0 >> [ 308.923529] citer= 7e biter= 7e doff= 1 dlast_sga= 0 >> [ 308.923529] major_int=1 disable_req=1 enable_sg=0 [ 308.942113] >> fsl-edma 2c0.edma: vchan 1b4371fc: txd >> d9dd26c5[4]: submitted [ 308.974049] fsl-edma >> 2c0.edma: txd d9dd26c5[4]: marked complete [ >> 308.981339] i2c i2c-0: 00080938 = [2e 2e 2f 2e 2e 2f 2e 2e >> 2f 64 65 76 69 63 65 73 2f 70 6c 61 74 66 6f 72 6d 2f 73 6f 63 2f 32 31 >> 38 30 >> 30 30 30 2e 69 32 63 2f 69 32 63 2d 30 2f 30 2d 30 30 35 34 2f 30 2d 30 30 >> 35 34 >> 30 00 00] [ 309.002226] i2c i2c-0: 75401000 = [2e 2e 2f 2e 2e 2f 2e >> 2e 2f >> 64 65 76 69 63 65 73 2f 70 6c 61 74 66 6f 72 6d 2f 73 6f 63 2f 32 31 38 30 >> 30 30 30 >> 2e 69 32 63 2f 69 32 63 2d 30 2f 30 2d 30 30 35 34 2f 30 2d 30 30 35 34 30 >> 00 00] >> [ 309.024649] i2c i2c-0: 000809380080 0x000889380080 >> 0xf5401800 75401800 >> [ 309.033270] src= 2180004 dst=f5401800 attr= 0 soff= 0 nbytes=1 >> slast= 0 >> [ 309.033270] citer= 7e biter= 7e doff= 1 dlast_sga= 0 >> [ 309.033270] major_int=1 disable_req=1 enable_sg=0 [ 309.051633] >> fsl-edma 2c0.edma: vchan 1b4371fc: txd >> d9dd26c5[5]: submitted [ 309.083526] fsl-edma >> 2c0.edma: txd d9dd26c5[5]: marked complete [ >> 309.090807] i2c i2c-0: 000809380080 = [00 00 00 00 00 00 00 00 >> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >> 00 00 00 00 00 00 00 00 00 00 00 00] [ 309.111694] i2c i2c-0: >> 75401800 = [00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >> 00 00 00 00] >> 2e 2e 2f 2e 2e 2f 2e 2e 2f 64 65 76 69 63 65 73 >> |../../../devices| >> 0010 2f 70 6c 61 74 66 6f 72 6d 2f 73 6f 63 2f 32 31 >> |/platform/soc/21| >> 0020 38 30 30 30 30 2e 69 32 63 2f 69 32 63 2d 30 2f >> |8.i2c/i2c-0/| >> 0030 30 2d 30 30 35 34 2f 30 2d 30 30 35 34 30 00 00 >> |0-0054/0-00540..| >> 0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >> || >> * >> 0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff >> || >> 0080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >> || >> * >> 00f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 5b >> |...[| >> 0100 >> >> (patch with my debug prints appended below) >> >> Despite the DMA completing successfully, no data was copied into >> the buffer, leaving the original (now junk) contents. I probed the >> I2C bus with an oscilloscope, and I verified that the transfer did >> indeed >> occur. >> The timing between submission and completion seems reasonable for >> the bus speed (50 kHz for whatever reason). >> >> I had a look over the I2C driver, and nothing looked obviously >> incorrect. If anyone has ideas on what to try, I'm more than willing. >> >>> >> >>> Is the DMA controller cache-coherent? I see the mainline LS1046A DT >> doesn't have a "dma-coherent" property for it, but the behaviour is entirely >> consistent with that being wrong - dma_map_single() cleans the cache, >> coherent DMA write hits the still-present cache
RE: [BUG] ls1046a: eDMA does not transfer data from I2C
> > > > Despite the DMA completing successfully, no data was copied into the > > buffer, leaving the original (now junk) contents. I probed the I2C bus > > with an oscilloscope, and I verified that the transfer did indeed occur. > > The timing between submission and completion seems reasonable for the > > bus speed (50 kHz for whatever reason). > > > > I had a look over the I2C driver, and nothing looked obviously > > incorrect. If anyone has ideas on what to try, I'm more than willing. > > Is the DMA controller cache-coherent? I see the mainline LS1046A DT doesn't > have a "dma-coherent" property for it, but the behaviour is entirely > consistent with that being wrong - dma_map_single() cleans the cache, > coherent DMA write hits the still-present cache lines, So the coherent DMA write only gets data into the cache not also the DRAM? Otherwise a read back would get the updated data too. - Leo > dma_unmap_single() invalidates the cache, and boom, the data is gone and > you read back the previous content of the buffer that was cleaned out to > DRAM beforehand. > > Robin. > > > --Sean
RE: [PATCH v3 15/15] vfio: Add struct device to vfio_device
> From: Alex Williamson > Sent: Wednesday, September 21, 2022 4:27 AM > > On Fri, 9 Sep 2022 18:22:47 +0800 > Kevin Tian wrote: > > > From: Yi Liu > > > > and replace kref. With it a 'vfio-dev/vfioX' node is created under the > > sysfs path of the parent, indicating the device is bound to a vfio > > driver, e.g.: > > > > /sys/devices/pci\:6f/\:6f\:01.0/vfio-dev/vfio0 > > > > It is also a preparatory step toward adding cdev for supporting future > > device-oriented uAPI. > > > > Add Documentation/ABI/testing/sysfs-devices-vfio-dev. > > > > Also take this chance to rename chardev 'vfio' to 'vfio-group' in > > /proc/devices. > > What's the risk/reward here, is this just more aesthetically pleasing > symmetry vs 'vfio-dev'? The char major number to name association in > /proc/devices seems pretty obscure, but what due diligence have we done > to make sure this doesn't break anyone? Thanks, > I'm not sure whether the content of /proc/devices is considered as ABI. @Jason? But to be safe I can remove this change in next version. If it's the right thing to do such change after discussion then it can be done in a separate patch after.
RE: [PATCH v3 06/15] vfio/mtty: Use the new device life cycle helpers
> From: Alex Williamson > Sent: Wednesday, September 21, 2022 3:17 AM > > On Fri, 9 Sep 2022 18:22:38 +0800 > Kevin Tian wrote: > > > From: Yi Liu > > > > and manage available ports inside @init/@release. > > > > Signed-off-by: Yi Liu > > Signed-off-by: Kevin Tian > > Reviewed-by: Jason Gunthorpe > > --- > > samples/vfio-mdev/mtty.c | 67 +++- > > 1 file changed, 39 insertions(+), 28 deletions(-) > > > > diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c > > index f42a59ed2e3f..41301d50b247 100644 > > --- a/samples/vfio-mdev/mtty.c > > +++ b/samples/vfio-mdev/mtty.c > ... > > +static int mtty_probe(struct mdev_device *mdev) > > +{ > > + struct mdev_state *mdev_state; > > + int ret; > > + > > + mdev_state = vfio_alloc_device(mdev_state, vdev, >dev, > > + _dev_ops); > > + if (IS_ERR(mdev_state)) > > + return PTR_ERR(mdev_state); > > > > ret = vfio_register_emulated_iommu_dev(_state->vdev); > > if (ret) > > - goto err_vconfig; > > + goto err_put_vdev; > > dev_set_drvdata(>dev, mdev_state); > > return 0; > > > > -err_vconfig: > > - kfree(mdev_state->vconfig); > > -err_state: > > - vfio_uninit_group_dev(_state->vdev); > > - kfree(mdev_state); > > -err_nr_ports: > > - atomic_add(nr_ports, _avail_ports); > > +err_put_vdev: > > + vfio_put_device(_state->vdev); > > return ret; > > } > > > > +static void mtty_release_dev(struct vfio_device *vdev) > > +{ > > + struct mdev_state *mdev_state = > > + container_of(vdev, struct mdev_state, vdev); > > + > > + kfree(mdev_state->vconfig); > > + vfio_free_device(vdev); > > + atomic_add(mdev_state->nr_ports, _avail_ports); > > I must be missing something, isn't this a use-after-free? Yes, it's a use-after-free indeed. Thanks for catching it! > > mdev_state is allocated via vfio_alloc_device(), where vdev is the > first entry in that structure, so this is equivalent to > kvfree(mdev_state). mbochs has the same issue. mdpy and vfio-ap > adjust global counters after vfio_free_device(), which I think muddies > the situation. Shouldn't we look suspiciously at any .release callback > where vfio_free_device() isn't the last thing executed? Thanks, > Yes. I'll scrutinize it again. To be consistent I'll make sure the free is the last line in all .release callbacks though not required for some (e.g. mdpy and vfio-ap).
RE: [BUG] ls1046a: eDMA does not transfer data from I2C
> -Original Message- > From: Sean Anderson > Sent: Tuesday, September 20, 2022 11:21 AM > To: Robin Murphy ; Oleksij Rempel > ; Pengutronix Kernel Team > ; linux-...@vger.kernel.org; linux-arm-kernel > ; Vinod Koul ; > dmaeng...@vger.kernel.org; Leo Li ; Laurentiu Tudor > > Cc: Linux Kernel Mailing List ; dri- > de...@lists.freedesktop.org; Christian König ; > linaro-mm-...@lists.linaro.org; Shawn Guo ; Sumit > Semwal ; Joy Zou ; linux- > me...@vger.kernel.org > Subject: Re: [BUG] ls1046a: eDMA does not transfer data from I2C > > > > On 9/20/22 11:44 AM, Sean Anderson wrote: > > > > > > On 9/20/22 11:24 AM, Sean Anderson wrote: > >> > >> > >> On 9/20/22 6:07 AM, Robin Murphy wrote: > >>> On 2022-09-19 23:24, Sean Anderson wrote: > Hi all, > > I discovered a bug in either imx_i2c or fsl-edma on the LS1046A > where no data is read in i2c_imx_dma_read except for the last two > bytes (which are not read using DMA). This is perhaps best > illustrated with the following example: > > # hexdump -C /sys/bus/nvmem/devices/0-00540/nvmem > [ 308.914884] i2c i2c-0: 00080938 0x00088938 > 0xf5401000 75401000 > [ 308.923529] src= 2180004 dst=f5401000 attr= 0 soff= 0 nbytes=1 > slast= 0 > [ 308.923529] citer= 7e biter= 7e doff= 1 dlast_sga= 0 > [ 308.923529] major_int=1 disable_req=1 enable_sg=0 [ 308.942113] > fsl-edma 2c0.edma: vchan 1b4371fc: txd > d9dd26c5[4]: submitted [ 308.974049] fsl-edma > 2c0.edma: txd d9dd26c5[4]: marked complete [ > 308.981339] i2c i2c-0: 00080938 = [2e 2e 2f 2e 2e 2f 2e 2e > 2f 64 65 76 69 63 65 73 2f 70 6c 61 74 66 6f 72 6d 2f 73 6f 63 2f 32 31 > 38 30 > 30 30 30 2e 69 32 63 2f 69 32 63 2d 30 2f 30 2d 30 30 35 34 2f 30 2d 30 30 35 > 34 > 30 00 00] [ 309.002226] i2c i2c-0: 75401000 = [2e 2e 2f 2e 2e 2f 2e > 2e 2f > 64 65 76 69 63 65 73 2f 70 6c 61 74 66 6f 72 6d 2f 73 6f 63 2f 32 31 38 30 30 > 30 30 > 2e 69 32 63 2f 69 32 63 2d 30 2f 30 2d 30 30 35 34 2f 30 2d 30 30 35 34 30 00 > 00] > [ 309.024649] i2c i2c-0: 000809380080 0x000889380080 > 0xf5401800 75401800 > [ 309.033270] src= 2180004 dst=f5401800 attr= 0 soff= 0 nbytes=1 > slast= 0 > [ 309.033270] citer= 7e biter= 7e doff= 1 dlast_sga= 0 > [ 309.033270] major_int=1 disable_req=1 enable_sg=0 [ 309.051633] > fsl-edma 2c0.edma: vchan 1b4371fc: txd > d9dd26c5[5]: submitted [ 309.083526] fsl-edma > 2c0.edma: txd d9dd26c5[5]: marked complete [ > 309.090807] i2c i2c-0: 000809380080 = [00 00 00 00 00 00 00 00 > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 00 00 00 00 00 00 00 00 00 00 00 00] [ 309.111694] i2c i2c-0: > 75401800 = [00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 00 00 00 00] > 2e 2e 2f 2e 2e 2f 2e 2e 2f 64 65 76 69 63 65 73 > |../../../devices| > 0010 2f 70 6c 61 74 66 6f 72 6d 2f 73 6f 63 2f 32 31 > |/platform/soc/21| > 0020 38 30 30 30 30 2e 69 32 63 2f 69 32 63 2d 30 2f > |8.i2c/i2c-0/| > 0030 30 2d 30 30 35 34 2f 30 2d 30 30 35 34 30 00 00 > |0-0054/0-00540..| > 0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > || > * > 0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff > || > 0080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > || > * > 00f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 5b > |...[| > 0100 > > (patch with my debug prints appended below) > > Despite the DMA completing successfully, no data was copied into > the buffer, leaving the original (now junk) contents. I probed the > I2C bus with an oscilloscope, and I verified that the transfer did indeed > occur. > The timing between submission and completion seems reasonable for > the bus speed (50 kHz for whatever reason). > > I had a look over the I2C driver, and nothing looked obviously > incorrect. If anyone has ideas on what to try, I'm more than willing. > >>> > >>> Is the DMA controller cache-coherent? I see the mainline LS1046A DT > doesn't have a "dma-coherent" property for it, but the behaviour is entirely > consistent with that being wrong - dma_map_single() cleans the cache, > coherent DMA write hits the still-present cache lines, dma_unmap_single() > invalidates the cache, and boom, the data is gone and you read back the > previous content of the buffer that was cleaned out to DRAM
Re: [Intel-gfx] [PATCH 1/1] drm/i915/mtl: enable local stolen memory
Hi Matt, Lucas, thanks for your feedback, > > > + switch (gms) { > > > + case 0x0 ... 0x10: > > > + return gms * 32; > > > + case 0x20: > > > + return 1024; > > > + case 0x30: > > > + return 1536; > > > + case 0x40: > > > + return 2048; > > > + case 0xf0 ... 0xfe: > > > > just a bit puzzled by the fact that case ranges are not standard > > and are supported only by GCC, unless, of course, I miss > > something. Do we still want to use them as they are widely used > > around the kernel? > > i915 already has 17 other uses of this notation and the DRM subsystem in > general has about 50 today. So it's not super common, but I think it > should be okay to use. I believe clang supports this language extension > as well and the coding style doc doesn't say anything one way or the > other. I thought clang supports it for C++ rather than C, but I'm not a clang expert, so that I might be wrong. The fact that it is widely used is never a convincing argument and if gcc supports it, then it does it against the standard, both C11 and C17 (this is what puzzles me everytime I see these C tricks offered by gcc). Anyway, I'm not against it (nor in favour) as the ellipsis is becoming very commonly used. My comment, by the way, did not mean to block the patch, I just wanted to check what other people think about. Thanks, Andi
[PATCH v2 3/3] drm/meson: remove drm bridges at aggregate driver unbind time
drm bridges added by meson_encoder_hdmi_init and meson_encoder_cvbs_init were not manually removed at module unload time, which caused dangling references to freed memory to remain linked in the global bridge_list. When loading the driver modules back in, the same functions would again call drm_bridge_add, and when traversing the global bridge_list, would end up peeking into freed memory. Once again KASAN revealed the problem: [ +0.95] = [ +0.08] BUG: KASAN: use-after-free in __list_add_valid+0x9c/0x120 [ +0.18] Read of size 8 at addr 3da291f0 by task modprobe/2483 [ +0.18] CPU: 3 PID: 2483 Comm: modprobe Tainted: G C O 5.19.0-rc6-lrmbkasan+ #1 [ +0.11] Hardware name: Hardkernel ODROID-N2Plus (DT) [ +0.08] Call trace: [ +0.06] dump_backtrace+0x1ec/0x280 [ +0.12] show_stack+0x24/0x80 [ +0.08] dump_stack_lvl+0x98/0xd4 [ +0.11] print_address_description.constprop.0+0x80/0x520 [ +0.11] print_report+0x128/0x260 [ +0.08] kasan_report+0xb8/0xfc [ +0.08] __asan_report_load8_noabort+0x3c/0x50 [ +0.09] __list_add_valid+0x9c/0x120 [ +0.09] drm_bridge_add+0x6c/0x104 [drm] [ +0.000165] dw_hdmi_probe+0x1900/0x2360 [dw_hdmi] [ +0.22] meson_dw_hdmi_bind+0x520/0x814 [meson_dw_hdmi] [ +0.14] component_bind+0x174/0x520 [ +0.12] component_bind_all+0x1a8/0x38c [ +0.10] meson_drv_bind_master+0x5e8/0xb74 [meson_drm] [ +0.32] meson_drv_bind+0x20/0x2c [meson_drm] [ +0.27] try_to_bring_up_aggregate_device+0x19c/0x390 [ +0.10] component_master_add_with_match+0x1c8/0x284 [ +0.09] meson_drv_probe+0x274/0x280 [meson_drm] [ +0.26] platform_probe+0xd0/0x220 [ +0.09] really_probe+0x3ac/0xa80 [ +0.09] __driver_probe_device+0x1f8/0x400 [ +0.09] driver_probe_device+0x68/0x1b0 [ +0.09] __driver_attach+0x20c/0x480 [ +0.08] bus_for_each_dev+0x114/0x1b0 [ +0.09] driver_attach+0x48/0x64 [ +0.08] bus_add_driver+0x390/0x564 [ +0.09] driver_register+0x1a8/0x3e4 [ +0.09] __platform_driver_register+0x6c/0x94 [ +0.08] meson_drm_platform_driver_init+0x3c/0x1000 [meson_drm] [ +0.27] do_one_initcall+0xc4/0x2b0 [ +0.11] do_init_module+0x154/0x570 [ +0.11] load_module+0x1a78/0x1ea4 [ +0.08] __do_sys_init_module+0x184/0x1cc [ +0.09] __arm64_sys_init_module+0x78/0xb0 [ +0.09] invoke_syscall+0x74/0x260 [ +0.09] el0_svc_common.constprop.0+0xcc/0x260 [ +0.08] do_el0_svc+0x50/0x70 [ +0.07] el0_svc+0x68/0x1a0 [ +0.12] el0t_64_sync_handler+0x11c/0x150 [ +0.08] el0t_64_sync+0x18c/0x190 [ +0.16] Allocated by task 879: [ +0.08] kasan_save_stack+0x2c/0x5c [ +0.11] __kasan_kmalloc+0x90/0xd0 [ +0.07] __kmalloc+0x278/0x4a0 [ +0.11] mpi_resize+0x13c/0x1d0 [ +0.11] mpi_powm+0xd24/0x1570 [ +0.09] rsa_enc+0x1a4/0x30c [ +0.09] pkcs1pad_verify+0x3f0/0x580 [ +0.09] public_key_verify_signature+0x7a8/0xba4 [ +0.10] public_key_verify_signature_2+0x40/0x60 [ +0.08] verify_signature+0xb4/0x114 [ +0.08] pkcs7_validate_trust_one.constprop.0+0x3b8/0x574 [ +0.09] pkcs7_validate_trust+0xb8/0x15c [ +0.08] verify_pkcs7_message_sig+0xec/0x1b0 [ +0.12] verify_pkcs7_signature+0x78/0xac [ +0.07] mod_verify_sig+0x110/0x190 [ +0.09] module_sig_check+0x114/0x1e0 [ +0.09] load_module+0xa0/0x1ea4 [ +0.08] __do_sys_init_module+0x184/0x1cc [ +0.08] __arm64_sys_init_module+0x78/0xb0 [ +0.08] invoke_syscall+0x74/0x260 [ +0.09] el0_svc_common.constprop.0+0x1a8/0x260 [ +0.08] do_el0_svc+0x50/0x70 [ +0.07] el0_svc+0x68/0x1a0 [ +0.09] el0t_64_sync_handler+0x11c/0x150 [ +0.09] el0t_64_sync+0x18c/0x190 [ +0.13] Freed by task 2422: [ +0.08] kasan_save_stack+0x2c/0x5c [ +0.09] kasan_set_track+0x2c/0x40 [ +0.07] kasan_set_free_info+0x28/0x50 [ +0.09] kasan_slab_free+0x128/0x1d4 [ +0.08] __kasan_slab_free+0x18/0x24 [ +0.07] slab_free_freelist_hook+0x108/0x230 [ +0.10] kfree+0x110/0x35c [ +0.08] release_nodes+0xf0/0x16c [ +0.09] devres_release_group+0x180/0x270 [ +0.08] take_down_aggregate_device+0xcc/0x160 [ +0.10] component_del+0x18c/0x360 [ +0.09] meson_dw_hdmi_remove+0x28/0x40 [meson_dw_hdmi] [ +0.13] platform_remove+0x64/0xb0 [ +0.08] device_remove+0xb8/0x154 [ +0.09] device_release_driver_internal+0x398/0x5b0 [ +0.09] driver_detach+0xac/0x1b0 [ +0.09] bus_remove_driver+0x158/0x29c [ +0.08] driver_unregister+0x70/0xb0 [ +0.09] platform_driver_unregister+0x20/0x2c [ +0.07] meson_dw_hdmi_platform_driver_exit+0x1c/0x30 [meson_dw_hdmi] [ +0.12] __do_sys_delete_module+0x288/0x400 [ +0.09] __arm64_sys_delete_module+0x5c/0x80 [ +0.09] invoke_syscall+0x74/0x260 [
[PATCH v4] drm/msm/dp: add atomic_check to bridge ops
DRM commit_tails() will disable downstream crtc/encoder/bridge if both disable crtc is required and crtc->active is set before pushing a new frame downstream. There is a rare case that user space display manager issue an extra screen update immediately followed by close DRM device while down stream display interface is disabled. This extra screen update will timeout due to the downstream interface is disabled but will cause crtc->active be set. Hence the followed commit_tails() called by drm_release() will pass the disable downstream crtc/encoder/bridge conditions checking even downstream interface is disabled. This cause the crash to happen at dp_bridge_disable() due to it trying to access the main link register to push the idle pattern out while main link clocks is disabled. This patch adds atomic_check to prevent the extra frame will not be pushed down if display interface is down so that crtc->active will not be set neither. This will fail the conditions checking of disabling down stream crtc/encoder/bridge which prevent drm_release() from calling dp_bridge_disable() so that crash at dp_bridge_disable() prevented. There is no protection in the DRM framework to check if the display pipeline has been already disabled before trying again. The only check is the crtc_state->active but this is controlled by usermode using UAPI. Hence if the usermode sets this and then crashes, the driver needs to protect against double disable" SError Interrupt on CPU7, code 0xbe000411 -- SError CPU: 7 PID: 3878 Comm: Xorg Not tainted 5.19.0-stb-cbq #19 Hardware name: Google Lazor (rev3 - 8) (DT) pstate: a04000c9 (NzCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : __cmpxchg_case_acq_32+0x14/0x2c lr : do_raw_spin_lock+0xa4/0xdc sp : ffc01092b6a0 x29: ffc01092b6a0 x28: 0028 x27: 0038 x26: 0004 x25: ffd2973dce48 x24: x23: x22: x21: ffd2978d0008 x20: ffd2978d0008 x19: ff80ff759fc0 x18: x17: 004800a501260460 x16: 0441043b04600438 x15: 0438089807d0 x14: 07b0089807800780 x13: x12: x11: 0438 x10: 07d0 x9 : ffd2973e09e4 x8 : ff8092d53300 x7 : ff808902e8b8 x6 : 0001 x5 : ff808902e880 x4 : x3 : ff80ff759fc0 x2 : 0001 x1 : x0 : ff80ff759fc0 Kernel panic - not syncing: Asynchronous SError Interrupt CPU: 7 PID: 3878 Comm: Xorg Not tainted 5.19.0-stb-cbq #19 Hardware name: Google Lazor (rev3 - 8) (DT) Call trace: dump_backtrace.part.0+0xbc/0xe4 show_stack+0x24/0x70 dump_stack_lvl+0x68/0x84 dump_stack+0x18/0x34 panic+0x14c/0x32c nmi_panic+0x58/0x7c arm64_serror_panic+0x78/0x84 do_serror+0x40/0x64 el1h_64_error_handler+0x30/0x48 el1h_64_error+0x68/0x6c __cmpxchg_case_acq_32+0x14/0x2c _raw_spin_lock_irqsave+0x38/0x4c lock_timer_base+0x40/0x78 __mod_timer+0xf4/0x25c schedule_timeout+0xd4/0xfc __wait_for_common+0xac/0x140 wait_for_completion_timeout+0x2c/0x54 dp_ctrl_push_idle+0x40/0x88 dp_bridge_disable+0x24/0x30 drm_atomic_bridge_chain_disable+0x90/0xbc drm_atomic_helper_commit_modeset_disables+0x198/0x444 msm_atomic_commit_tail+0x1d0/0x374 commit_tail+0x80/0x108 drm_atomic_helper_commit+0x118/0x11c drm_atomic_commit+0xb4/0xe0 drm_client_modeset_commit_atomic+0x184/0x224 drm_client_modeset_commit_locked+0x58/0x160 drm_client_modeset_commit+0x3c/0x64 __drm_fb_helper_restore_fbdev_mode_unlocked+0x98/0xac drm_fb_helper_set_par+0x74/0x80 drm_fb_helper_hotplug_event+0xdc/0xe0 __drm_fb_helper_restore_fbdev_mode_unlocked+0x7c/0xac drm_fb_helper_restore_fbdev_mode_unlocked+0x20/0x2c drm_fb_helper_lastclose+0x20/0x2c drm_lastclose+0x44/0x6c drm_release+0x88/0xd4 __fput+0x104/0x220 fput+0x1c/0x28 task_work_run+0x8c/0x100 do_exit+0x450/0x8d0 do_group_exit+0x40/0xac __wake_up_parent+0x0/0x38 invoke_syscall+0x84/0x11c el0_svc_common.constprop.0+0xb8/0xe4 do_el0_svc+0x8c/0xb8 el0_svc+0x2c/0x54 el0t_64_sync_handler+0x120/0x1c0 el0t_64_sync+0x190/0x194 SMP: stopping secondary CPUs Kernel Offset: 0x128e80 from 0xffc00800 PHYS_OFFSET: 0x8000 CPU features: 0x800,00c2a015,19801c82 Memory Limit: none Changes in v2: -- add more commit text Changes in v3: -- add comments into dp_bridge_atomic_check() Changes in v4: -- rewording the comment into dp_bridge_atomic_check() Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display enable and disable") Reported-by: Leonard Lausen Suggested-by: Rob Clark Closes: https://gitlab.freedesktop.org/drm/msm/-/issues/17 Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/dp/dp_drm.c | 34 ++ 1 file changed, 34 insertions(+) diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c index 6df25f7..2e8e8ce 100644 --- a/drivers/gpu/drm/msm/dp/dp_drm.c +++ b/drivers/gpu/drm/msm/dp/dp_drm.c @@ -31,6 +31,36 @@ static
Re: [PATCH 2/2] drm/panfrost: replace endian-specific types with generic ones
Tentative r-b, but we *do* need to make a decision on how we want to handle endianness. I don't have strong feelings but the results of that discussion should go in the commit message. On Tue, Sep 20, 2022 at 10:15:45PM +0100, Adri??n Larumbe wrote: > __le32 and __l64 endian-specific types aren't portable and not available on > FreeBSD, for which there's a uAPI compatible reimplementation of Panfrost. > > Replace these specific types with more generic unsigned ones, to prevent > FreeBSD Mesa build errors. > > Bug: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7252 > Fixes: 730c2bf4ad39 ("drm/panfrost: Add support for devcoredump") > Signed-off-by: Adri??n Larumbe > --- > include/uapi/drm/panfrost_drm.h | 30 +++--- > 1 file changed, 15 insertions(+), 15 deletions(-) > > diff --git a/include/uapi/drm/panfrost_drm.h b/include/uapi/drm/panfrost_drm.h > index bd77254be121..c1a10a9366a9 100644 > --- a/include/uapi/drm/panfrost_drm.h > +++ b/include/uapi/drm/panfrost_drm.h > @@ -236,24 +236,24 @@ struct drm_panfrost_madvise { > #define PANFROSTDUMP_BUF_TRAILER (PANFROSTDUMP_BUF_BO + 1) > > struct panfrost_dump_object_header { > - __le32 magic; > - __le32 type; > - __le32 file_size; > - __le32 file_offset; > + __u32 magic; > + __u32 type; > + __u32 file_size; > + __u32 file_offset; > > union { > struct { > - __le64 jc; > - __le32 gpu_id; > - __le32 major; > - __le32 minor; > - __le64 nbos; > + __u64 jc; > + __u32 gpu_id; > + __u32 major; > + __u32 minor; > + __u64 nbos; > } reghdr; > > struct { > - __le32 valid; > - __le64 iova; > - __le32 data[2]; > + __u32 valid; > + __u64 iova; > + __u32 data[2]; > } bomap; > > /* > @@ -261,14 +261,14 @@ struct panfrost_dump_object_header { >* with new fields and also keep it 512-byte aligned >*/ > > - __le32 sizer[496]; > + __u32 sizer[496]; > }; > }; > > /* Registers object, an array of these */ > struct panfrost_dump_registers { > - __le32 reg; > - __le32 value; > + __u32 reg; > + __u32 value; > }; > > #if defined(__cplusplus) > -- > 2.37.0 >
[linux-next:master] BUILD REGRESSION ef08d387bbbc20df740ced8caee0ffac835869ac
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master branch HEAD: ef08d387bbbc20df740ced8caee0ffac835869ac Add linux-next specific files for 20220920 Error/Warning reports: https://lore.kernel.org/linux-mm/202209150141.wgbakqmx-...@intel.com https://lore.kernel.org/linux-mm/202209200603.hpvoa8ii-...@intel.com https://lore.kernel.org/llvm/202209201854.m9mhizpx-...@intel.com Error/Warning: (recently discovered and may have been fixed) ERROR: modpost: "devm_ioremap_resource" [drivers/dma/fsl-edma.ko] undefined! ERROR: modpost: "devm_ioremap_resource" [drivers/dma/idma64.ko] undefined! ERROR: modpost: "devm_ioremap_resource" [drivers/dma/qcom/hdma.ko] undefined! ERROR: modpost: "devm_memremap" [drivers/misc/open-dice.ko] undefined! ERROR: modpost: "devm_memunmap" [drivers/misc/open-dice.ko] undefined! ERROR: modpost: "devm_platform_ioremap_resource" [drivers/char/xillybus/xillybus_of.ko] undefined! ERROR: modpost: "devm_platform_ioremap_resource" [drivers/clk/xilinx/clk-xlnx-clock-wizard.ko] undefined! ERROR: modpost: "ioremap" [drivers/tty/ipwireless/ipwireless.ko] undefined! ERROR: modpost: "iounmap" [drivers/net/ethernet/8390/pcnet_cs.ko] undefined! ERROR: modpost: "iounmap" [drivers/tty/ipwireless/ipwireless.ko] undefined! arch/arm64/kernel/alternative.c:199:6: warning: no previous prototype for 'apply_alternatives_vdso' [-Wmissing-prototypes] arch/arm64/kernel/alternative.c:295:14: warning: no previous prototype for 'alt_cb_patch_nops' [-Wmissing-prototypes] arch/parisc/lib/iomap.c:363:5: warning: no previous prototype for 'ioread64_lo_hi' [-Wmissing-prototypes] arch/parisc/lib/iomap.c:373:5: warning: no previous prototype for 'ioread64_hi_lo' [-Wmissing-prototypes] arch/parisc/lib/iomap.c:448:6: warning: no previous prototype for 'iowrite64_lo_hi' [-Wmissing-prototypes] arch/parisc/lib/iomap.c:454:6: warning: no previous prototype for 'iowrite64_hi_lo' [-Wmissing-prototypes] drivers/gpu/drm/drm_atomic_helper.c:802: warning: expecting prototype for drm_atomic_helper_check_wb_connector_state(). Prototype was for drm_atomic_helper_check_wb_encoder_state() instead drivers/net/ethernet/freescale/fman/fman_memac.c:1286 memac_initialization() error: uninitialized symbol 'fixed_link'. drivers/scsi/qla2xxx/qla_os.c:2854:23: warning: assignment to 'struct trace_array *' from 'int' makes pointer from integer without a cast [-Wint-conversion] drivers/scsi/qla2xxx/qla_os.c:2854:25: error: implicit declaration of function 'trace_array_get_by_name'; did you mean 'trace_array_set_clr_event'? [-Werror=implicit-function-declaration] drivers/scsi/qla2xxx/qla_os.c:2869:9: error: implicit declaration of function 'trace_array_put' [-Werror=implicit-function-declaration] mm/hugetlb.c:5539:14: warning: variable 'reserve_alloc' set but not used [-Wunused-but-set-variable] Unverified Error/Warning (likely false positive, please contact us if interested): ERROR: modpost: "devm_ioremap" [drivers/net/ethernet/altera/altera_tse.ko] undefined! Error/Warning ids grouped by kconfigs: gcc_recent_errors |-- alpha-allyesconfig | |-- drivers-gpu-drm-drm_atomic_helper.c:warning:expecting-prototype-for-drm_atomic_helper_check_wb_connector_state().-Prototype-was-for-drm_atomic_helper_check_wb_encoder_state()-instead | |-- drivers-scsi-qla2xxx-qla_os.c:error:implicit-declaration-of-function-trace_array_get_by_name | |-- drivers-scsi-qla2xxx-qla_os.c:error:implicit-declaration-of-function-trace_array_put | `-- drivers-scsi-qla2xxx-qla_os.c:warning:assignment-to-struct-trace_array-from-int-makes-pointer-from-integer-without-a-cast |-- arc-allyesconfig | `-- drivers-gpu-drm-drm_atomic_helper.c:warning:expecting-prototype-for-drm_atomic_helper_check_wb_connector_state().-Prototype-was-for-drm_atomic_helper_check_wb_encoder_state()-instead |-- arm-allyesconfig | `-- drivers-gpu-drm-drm_atomic_helper.c:warning:expecting-prototype-for-drm_atomic_helper_check_wb_connector_state().-Prototype-was-for-drm_atomic_helper_check_wb_encoder_state()-instead |-- arm-defconfig | `-- drivers-gpu-drm-drm_atomic_helper.c:warning:expecting-prototype-for-drm_atomic_helper_check_wb_connector_state().-Prototype-was-for-drm_atomic_helper_check_wb_encoder_state()-instead |-- arm-exynos_defconfig | `-- drivers-gpu-drm-drm_atomic_helper.c:warning:expecting-prototype-for-drm_atomic_helper_check_wb_connector_state().-Prototype-was-for-drm_atomic_helper_check_wb_encoder_state()-instead |-- arm-gemini_defconfig | `-- drivers-gpu-drm-drm_atomic_helper.c:warning:expecting-prototype-for-drm_atomic_helper_check_wb_connector_state().-Prototype-was-for-drm_atomic_helper_check_wb_encoder_state()-instead |-- arm-nhk8815_defconfig | `-- drivers-gpu-drm-drm_atomic_helper.c:warning:expecting-prototype-for-drm_atomic_helper_check_wb_connector_state().-Prototype-was-for-drm_atomic_help
Re: [PATCH] drm/i915: Perf_limit_reasons are only available for Gen11+
On Mon, Sep 19, 2022 at 09:24:01AM -0700, Ashutosh Dixit wrote: > Register GT0_PERF_LIMIT_REASONS (0x1381a8) is available only for > Gen11+. Therefore ensure perf_limit_reasons sysfs/debugfs files are created > only for Gen11+. Otherwise on Gen < 5 accessing these files results in the > following oops: > > <1> [88.829420] BUG: unable to handle page fault for address: c9bb81a8 > <1> [88.829438] #PF: supervisor read access in kernel mode > <1> [88.829447] #PF: error_code(0x) - not-present page > > Bspec: 20008 > Bug: https://gitlab.freedesktop.org/drm/intel/-/issues/6863 > Fixes: fe5979665f64 ("drm/i915/debugfs: Add perf_limit_reasons in debugfs") > Fixes: fa68bff7cf27 ("drm/i915/gt: Add sysfs throttle frequency interfaces") > Signed-off-by: Ashutosh Dixit Reviewed-by: Rodrigo Vivi > --- > drivers/gpu/drm/i915/gt/intel_gt.c| 4 > drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c | 10 +- > drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c | 15 +++ > 3 files changed, 24 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c > b/drivers/gpu/drm/i915/gt/intel_gt.c > index 5ddae95d4886..b367cfff48d5 100644 > --- a/drivers/gpu/drm/i915/gt/intel_gt.c > +++ b/drivers/gpu/drm/i915/gt/intel_gt.c > @@ -233,6 +233,10 @@ static void gen6_clear_engine_error_register(struct > intel_engine_cs *engine) > > i915_reg_t intel_gt_perf_limit_reasons_reg(struct intel_gt *gt) > { > + /* GT0_PERF_LIMIT_REASONS is available only for Gen11+ */ > + if (GRAPHICS_VER(gt->i915) < 11) > + return INVALID_MMIO_REG; > + > return gt->type == GT_MEDIA ? > MTL_MEDIA_PERF_LIMIT_REASONS : GT0_PERF_LIMIT_REASONS; > } > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c > b/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c > index 68310881a793..10f680dbd7b6 100644 > --- a/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c > +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c > @@ -682,6 +682,14 @@ static int perf_limit_reasons_clear(void *data, u64 val) > > return 0; > } > + > +static bool perf_limit_reasons_eval(void *data) > +{ > + struct intel_gt *gt = data; > + > + return i915_mmio_reg_valid(intel_gt_perf_limit_reasons_reg(gt)); > +} > + > DEFINE_SIMPLE_ATTRIBUTE(perf_limit_reasons_fops, perf_limit_reasons_get, > perf_limit_reasons_clear, "%llu\n"); > > @@ -694,7 +702,7 @@ void intel_gt_pm_debugfs_register(struct intel_gt *gt, > struct dentry *root) > { "forcewake_user", _user_fops, NULL}, > { "llc", _fops, llc_eval }, > { "rps_boost", _boost_fops, rps_eval }, > - { "perf_limit_reasons", _limit_reasons_fops, NULL }, > + { "perf_limit_reasons", _limit_reasons_fops, > perf_limit_reasons_eval }, > }; > > intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), gt); > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c > b/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c > index 54deae45d81f..904160952369 100644 > --- a/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c > +++ b/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c > @@ -545,8 +545,7 @@ static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_ratl, > RATL_MASK); > static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_vr_thermalert, > VR_THERMALERT_MASK); > static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_vr_tdc, VR_TDC_MASK); > > -static const struct attribute *freq_attrs[] = { > - _attr_punit_req_freq_mhz.attr, > +static const struct attribute *throttle_reason_attrs[] = { > _throttle_reason_status.attr, > _throttle_reason_pl1.attr, > _throttle_reason_pl2.attr, > @@ -791,12 +790,20 @@ void intel_gt_sysfs_pm_init(struct intel_gt *gt, struct > kobject *kobj) > if (!is_object_gt(kobj)) > return; > > - ret = sysfs_create_files(kobj, freq_attrs); > + ret = sysfs_create_file(kobj, _attr_punit_req_freq_mhz.attr); > if (ret) > drm_warn(>i915->drm, > - "failed to create gt%u throttle sysfs files (%pe)", > + "failed to create gt%u punit_req_freq_mhz sysfs (%pe)", >gt->info.id, ERR_PTR(ret)); > > + if (i915_mmio_reg_valid(intel_gt_perf_limit_reasons_reg(gt))) { > + ret = sysfs_create_files(kobj, throttle_reason_attrs); > + if (ret) > + drm_warn(>i915->drm, > + "failed to create gt%u throttle sysfs files > (%pe)", > + gt->info.id, ERR_PTR(ret)); > + } > + > if (HAS_MEDIA_RATIO_MODE(gt->i915) && intel_uc_uses_guc_slpc(>uc)) { > ret = sysfs_create_files(kobj, media_perf_power_attrs); > if (ret) > -- > 2.34.1 >
[PATCH 1/2] drm/panfrost: Remove type name from internal structs
From: Steven Price The two structs internal to struct panfrost_dump_object_header were named, but sadly that is incompatible with C++, causing an error: "an anonymous union may only have public non-static data members". However nothing refers to struct pan_reg_hdr and struct pan_bomap_hdr and there's no need to export these definitions, so lets drop them. This fixes the C++ build error with the minimum change in userspace API. Bug: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7195 Fixes: 730c2bf4ad39 ("drm/panfrost: Add support for devcoredump") Signed-off-by: Steven Price --- include/uapi/drm/panfrost_drm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/uapi/drm/panfrost_drm.h b/include/uapi/drm/panfrost_drm.h index eac87310b348..bd77254be121 100644 --- a/include/uapi/drm/panfrost_drm.h +++ b/include/uapi/drm/panfrost_drm.h @@ -242,7 +242,7 @@ struct panfrost_dump_object_header { __le32 file_offset; union { - struct pan_reg_hdr { + struct { __le64 jc; __le32 gpu_id; __le32 major; @@ -250,7 +250,7 @@ struct panfrost_dump_object_header { __le64 nbos; } reghdr; - struct pan_bomap_hdr { + struct { __le32 valid; __le64 iova; __le32 data[2]; -- 2.37.0
[PATCH 2/2] drm/panfrost: replace endian-specific types with generic ones
__le32 and __l64 endian-specific types aren't portable and not available on FreeBSD, for which there's a uAPI compatible reimplementation of Panfrost. Replace these specific types with more generic unsigned ones, to prevent FreeBSD Mesa build errors. Bug: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7252 Fixes: 730c2bf4ad39 ("drm/panfrost: Add support for devcoredump") Signed-off-by: Adrián Larumbe --- include/uapi/drm/panfrost_drm.h | 30 +++--- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/include/uapi/drm/panfrost_drm.h b/include/uapi/drm/panfrost_drm.h index bd77254be121..c1a10a9366a9 100644 --- a/include/uapi/drm/panfrost_drm.h +++ b/include/uapi/drm/panfrost_drm.h @@ -236,24 +236,24 @@ struct drm_panfrost_madvise { #define PANFROSTDUMP_BUF_TRAILER (PANFROSTDUMP_BUF_BO + 1) struct panfrost_dump_object_header { - __le32 magic; - __le32 type; - __le32 file_size; - __le32 file_offset; + __u32 magic; + __u32 type; + __u32 file_size; + __u32 file_offset; union { struct { - __le64 jc; - __le32 gpu_id; - __le32 major; - __le32 minor; - __le64 nbos; + __u64 jc; + __u32 gpu_id; + __u32 major; + __u32 minor; + __u64 nbos; } reghdr; struct { - __le32 valid; - __le64 iova; - __le32 data[2]; + __u32 valid; + __u64 iova; + __u32 data[2]; } bomap; /* @@ -261,14 +261,14 @@ struct panfrost_dump_object_header { * with new fields and also keep it 512-byte aligned */ - __le32 sizer[496]; + __u32 sizer[496]; }; }; /* Registers object, an array of these */ struct panfrost_dump_registers { - __le32 reg; - __le32 value; + __u32 reg; + __u32 value; }; #if defined(__cplusplus) -- 2.37.0
Re: [PATCH V2 2/2] drm/panel: Add Samsung AMS495QA01 MIPI-DSI LCD panel
On Tue, Sep 20, 2022 at 07:33:00PM +0200, Maya Matuszczyk wrote: > Hi Chris, > Thanks for this patch, > > wt., 20 wrz 2022 o 19:10 Chris Morgan napisał(a): > > > > From: Chris Morgan > > > > Support Samsung AMS495QA01 panel as found on the Anbernic RG503. Note > > This panel receives video signals via DSI, however it receives > > commands via 3-wire SPI. > > > > Signed-off-by: Chris Morgan > > --- > > drivers/gpu/drm/panel/Kconfig | 10 + > > drivers/gpu/drm/panel/Makefile| 1 + > > .../gpu/drm/panel/panel-samsung-ams495qa01.c | 505 ++ > > 3 files changed, 516 insertions(+) > > create mode 100644 drivers/gpu/drm/panel/panel-samsung-ams495qa01.c > > > > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig > > index a9043eacce97..954b66a2adee 100644 > > --- a/drivers/gpu/drm/panel/Kconfig > > +++ b/drivers/gpu/drm/panel/Kconfig > > @@ -444,6 +444,16 @@ config DRM_PANEL_RONBO_RB070D30 > > Say Y here if you want to enable support for Ronbo Electronics > > RB070D30 1024x600 DSI panel. > > > > +config DRM_PANEL_SAMSUNG_AMS495QA01 > > + tristate "Samsung AMS495QA01 DSI panel" > > + depends on OF && SPI > > + depends on DRM_MIPI_DSI > > + select DRM_MIPI_DBI > > + help > > + DRM panel driver for the Samsung AMS495QA01 panel. This panel > > + receives video data via DSI but commands via 3-Wire 9-bit > > + SPI. > > + > > config DRM_PANEL_SAMSUNG_ATNA33XC20 > > tristate "Samsung ATNA33XC20 eDP panel" > > depends on OF > > diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile > > index 34e717382dbb..de0b57baf851 100644 > > --- a/drivers/gpu/drm/panel/Makefile > > +++ b/drivers/gpu/drm/panel/Makefile > > @@ -42,6 +42,7 @@ obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += > > panel-raspberrypi-touchscreen > > obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM67191) += panel-raydium-rm67191.o > > obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o > > obj-$(CONFIG_DRM_PANEL_RONBO_RB070D30) += panel-ronbo-rb070d30.o > > +obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMS495QA01) += panel-samsung-ams495qa01.o > > obj-$(CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20) += panel-samsung-atna33xc20.o > > obj-$(CONFIG_DRM_PANEL_SAMSUNG_DB7430) += panel-samsung-db7430.o > > obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o > > diff --git a/drivers/gpu/drm/panel/panel-samsung-ams495qa01.c > > b/drivers/gpu/drm/panel/panel-samsung-ams495qa01.c > > new file mode 100644 > > index ..d693ba5f20c9 > > --- /dev/null > > +++ b/drivers/gpu/drm/panel/panel-samsung-ams495qa01.c > > @@ -0,0 +1,505 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Samsung ams495qa01 MIPI-DSI panel driver > > + * Copyright (C) 2022 Chris Morgan > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include > > + > > +struct ams495qa01 { > > + /** @dev: the container device */ > > + struct device *dev; > > + /** @dbi: the DBI bus abstraction handle */ > > + struct mipi_dbi dbi; > > + /** @panel: the DRM panel instance for this device */ > > + struct drm_panel panel; > > + /** @reset: reset GPIO line */ > > + struct gpio_desc *reset; > > + /** @enable: enable GPIO line */ > > + struct gpio_desc *enable; > > + /** @reg_vdd: VDD supply regulator for panel logic */ > > + struct regulator *reg_vdd; > > + /** @reg_elvdd: ELVDD supply regulator for panel display */ > > + struct regulator *reg_elvdd; > > + /** @dsi_dev: DSI child device (panel) */ > > + struct mipi_dsi_device *dsi_dev; > > + /** @bl_dev: pseudo-backlight device for oled panel */ > > + struct backlight_device *bl_dev; > > + /** @prepared: value tracking panel prepare status */ > > + bool prepared; > > +}; > > + > > +static const struct drm_display_mode ams495qa01_mode = { > > + .clock = 33500, > > + .hdisplay = 960, > > + .hsync_start = 960 + 10, > > + .hsync_end = 960 + 10 + 2, > > + .htotal = 960 + 10 + 2 + 10, > > + .vdisplay = 544, > > + .vsync_start = 544 + 10, > > + .vsync_end = 544 + 10 + 2, > > + .vtotal = 544 + 10 + 2 + 10, > > + .width_mm = 117, > > + .height_mm = 74, > > + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, > > +}; > > + > > +#define NUM_GAMMA_LEVELS 16 > > +#define GAMMA_TABLE_COUNT 23 > > +#define MAX_BRIGHTNESS (NUM_GAMMA_LEVELS - 1) > > + > > +/* Table of gamma values provided in datasheet */ > > +static u8 ams495qa01_gamma[NUM_GAMMA_LEVELS][GAMMA_TABLE_COUNT] = { > > + {0x01, 0x79, 0x78, 0x8d, 0xd9, 0xdf, 0xd5, 0xcb, 0xcf, 0xc5, > > +0xe5,
Re: [Intel-gfx] [PATCH 1/1] drm/i915/mtl: enable local stolen memory
On Tue, Sep 20, 2022 at 06:57:46PM +0200, Andi Shyti wrote: > Hi Aravind, > > > +static int get_mtl_gms_size(struct intel_uncore *uncore) > > +{ > > + u16 ggc, gms; > > + > > + ggc = intel_uncore_read16(uncore, _MMIO(0x108040)); > > + > > + /* check GGMS, should be fixed 0x3 (8MB) */ > > + if ((ggc & 0xc0) != 0xc0) > > + return -EIO; > > + > > + /* return valid GMS value, -EIO if invalid */ > > + gms = ggc >> 8; > > + switch (gms) { > > + case 0x0 ... 0x10: > > + return gms * 32; > > + case 0x20: > > + return 1024; > > + case 0x30: > > + return 1536; > > + case 0x40: > > + return 2048; > > + case 0xf0 ... 0xfe: > > just a bit puzzled by the fact that case ranges are not standard > and are supported only by GCC, unless, of course, I miss > something. Do we still want to use them as they are widely used > around the kernel? i915 already has 17 other uses of this notation and the DRM subsystem in general has about 50 today. So it's not super common, but I think it should be okay to use. I believe clang supports this language extension as well and the coding style doc doesn't say anything one way or the other. Matt > > Andi > > > + return (gms - 0xf0 + 1) * 4; > > + default: > > + return -EIO; > > + } > > +} -- Matt Roper Graphics Software Engineer VTT-OSGC Platform Enablement Intel Corporation
Re: [PATCH v3 15/15] vfio: Add struct device to vfio_device
On Fri, 9 Sep 2022 18:22:47 +0800 Kevin Tian wrote: > From: Yi Liu > > and replace kref. With it a 'vfio-dev/vfioX' node is created under the > sysfs path of the parent, indicating the device is bound to a vfio > driver, e.g.: > > /sys/devices/pci\:6f/\:6f\:01.0/vfio-dev/vfio0 > > It is also a preparatory step toward adding cdev for supporting future > device-oriented uAPI. > > Add Documentation/ABI/testing/sysfs-devices-vfio-dev. > > Also take this chance to rename chardev 'vfio' to 'vfio-group' in > /proc/devices. What's the risk/reward here, is this just more aesthetically pleasing symmetry vs 'vfio-dev'? The char major number to name association in /proc/devices seems pretty obscure, but what due diligence have we done to make sure this doesn't break anyone? Thanks, Alex
Re: [Intel-gfx] [PATCH 1/1] drm/i915/mtl: enable local stolen memory
On Tue, Sep 20, 2022 at 01:31:49AM -0700, Lucas De Marchi wrote: On Tue, Sep 20, 2022 at 12:49:40PM +0530, Aravind Iddamsetty wrote: As an integrated GPU, MTL does not have local memory and HAS_LMEM() returns false. However the platform's stolen memory is presented via BAR2 (i.e., the BAR we traditionally consider to be the LMEM BAR) and should be managed by the driver the same way that local memory is on dgpu platforms (which includes setting the "lmem" bit on page table entries). We use the term "local stolen memory" to refer to this model. Cc: Matt Roper Cc: Lucas De Marchi Signed-off-by: CQ Tang Signed-off-by: Aravind Iddamsetty Original-author: CQ Tang --- drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 113 + drivers/gpu/drm/i915/gt/intel_ggtt.c | 2 +- drivers/gpu/drm/i915/i915_drv.h| 3 + 3 files changed, 100 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c index acc561c0f0aa..bad5250fb764 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c @@ -77,6 +77,19 @@ void i915_gem_stolen_remove_node(struct drm_i915_private *i915, mutex_unlock(>mm.stolen_lock); } +static bool is_dsm_invalid(struct drm_i915_private *i915, struct resource *dsm) +{ + if (!HAS_BAR2_SMEM_STOLEN(i915)) { I called a similar function as is_dsm_valid() in https://patchwork.freedesktop.org/series/108620/ sounds weird with "invalid" and the double negation on return early style. + if (dsm->start == 0) + return true; + } + + if (dsm->end <= dsm->start) + return true; + + return false; +} + static int i915_adjust_stolen(struct drm_i915_private *i915, struct resource *dsm) { @@ -84,7 +97,7 @@ static int i915_adjust_stolen(struct drm_i915_private *i915, struct intel_uncore *uncore = ggtt->vm.gt->uncore; struct resource *r; - if (dsm->start == 0 || dsm->end <= dsm->start) + if (is_dsm_invalid(i915, dsm)) return -EINVAL; /* @@ -136,7 +149,7 @@ static int i915_adjust_stolen(struct drm_i915_private *i915, * overlaps with the non-stolen system memory range, since lmem is local * to the gpu. */ - if (HAS_LMEM(i915)) + if (HAS_LMEM(i915) || HAS_BAR2_SMEM_STOLEN(i915)) comment above makes no sense when you add this. For this specific case it's still system memory, reserved by the BIOS and that we access by mapping the lmembar return 0; /* @@ -371,8 +384,6 @@ static void icl_get_stolen_reserved(struct drm_i915_private *i915, drm_dbg(>drm, "GEN6_STOLEN_RESERVED = 0x%016llx\n", reg_val); - *base = reg_val & GEN11_STOLEN_RESERVED_ADDR_MASK; - switch (reg_val & GEN8_STOLEN_RESERVED_SIZE_MASK) { case GEN8_STOLEN_RESERVED_1M: *size = 1024 * 1024; @@ -390,6 +401,12 @@ static void icl_get_stolen_reserved(struct drm_i915_private *i915, *size = 8 * 1024 * 1024; MISSING_CASE(reg_val & GEN8_STOLEN_RESERVED_SIZE_MASK); } + + if ((GRAPHICS_VER_FULL(i915) >= IP_VER(12, 70)) && !IS_DGFX(i915)) + /* the base is initialized to stolen top so subtract size to get base */ + *base -= *size; that doesn't necessarily holds true. According to the spec the wopcm base is 1MB aligned so even if it is "at the top", it may not mean it is at the very very top that we can just subtract the size. + else + *base = reg_val & GEN11_STOLEN_RESERVED_ADDR_MASK; } static int i915_gem_init_stolen(struct intel_memory_region *mem) @@ -423,8 +440,7 @@ static int i915_gem_init_stolen(struct intel_memory_region *mem) if (i915_adjust_stolen(i915, >dsm)) return 0; - GEM_BUG_ON(i915->dsm.start == 0); - GEM_BUG_ON(i915->dsm.end <= i915->dsm.start); + GEM_BUG_ON(is_dsm_invalid(i915, >dsm)); stolen_top = i915->dsm.end + 1; reserved_base = stolen_top; @@ -796,6 +812,46 @@ static const struct intel_memory_region_ops i915_region_stolen_lmem_ops = { .init_object = _i915_gem_object_stolen_init, }; +static int get_mtl_gms_size(struct intel_uncore *uncore) +{ + u16 ggc, gms; + + ggc = intel_uncore_read16(uncore, _MMIO(0x108040)); ?? + + /* check GGMS, should be fixed 0x3 (8MB) */ + if ((ggc & 0xc0) != 0xc0) + return -EIO; + + /* return valid GMS value, -EIO if invalid */ + gms = ggc >> 8; + switch (gms) { + case 0x0 ... 0x10: + return gms * 32; + case 0x20: + return 1024; + case 0x30: + return 1536; + case 0x40: + return 2048; + case 0xf0 ... 0xfe: + return (gms - 0xf0 + 1) * 4; + default: +
Re: [Intel-gfx] [PATCH 1/1] drm/i915/mtl: enable local stolen memory
On Tue, Sep 20, 2022 at 06:57:46PM +0200, Andi Shyti wrote: Hi Aravind, +static int get_mtl_gms_size(struct intel_uncore *uncore) +{ + u16 ggc, gms; + + ggc = intel_uncore_read16(uncore, _MMIO(0x108040)); + + /* check GGMS, should be fixed 0x3 (8MB) */ + if ((ggc & 0xc0) != 0xc0) + return -EIO; + + /* return valid GMS value, -EIO if invalid */ + gms = ggc >> 8; + switch (gms) { + case 0x0 ... 0x10: + return gms * 32; + case 0x20: + return 1024; + case 0x30: + return 1536; + case 0x40: + return 2048; + case 0xf0 ... 0xfe: just a bit puzzled by the fact that case ranges are not standard and are supported only by GCC, unless, of course, I miss clang also supports it and can build the kernel (or a great portion of it). Lucas De Marchi
Re: [Intel-gfx] [PATCH v2 3/3] drm/i915/dgfx: Make failure to setup stolen non-fatal
On 9/16/22 10:36 AM, Lucas De Marchi wrote: There is no reason to consider the setup of Data Stolen Memory fatal on dgfx and non-fatal on integrated. Move the debug and error propagation around so both have the same behavior: non-fatal. Before this change, loading i915 on a system with TGL + DG2 would result in just TGL succeeding the initialization (without stolen). Now loading i915 on the same system with an injected failure in i915_gem_init_stolen(): $ dmesg | grep stolen i915 :00:02.0: [drm] Injected failure, disabling use of stolen memory i915 :00:02.0: [drm:init_stolen_smem [i915]] Skip stolen region: failed to setup i915 :03:00.0: [drm] Injected failure, disabling use of stolen memory i915 :03:00.0: [drm:init_stolen_lmem [i915]] Skip stolen region: failed to setup Both GPUs are still available: $ sudo build/tools/lsgpu card1Intel Dg2 (Gen12) drm:/dev/dri/card1 └─renderD129 drm:/dev/dri/renderD129 card0Intel Tigerlake (Gen12) drm:/dev/dri/card0 └─renderD128 drm:/dev/dri/renderD128 Signed-off-by: Lucas De Marchi Reviewed-by: Wayne Boyer diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c index 6edf4e374f54..c5a4035c99cd 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c @@ -494,26 +494,26 @@ static int i915_gem_init_stolen(struct intel_memory_region *mem) drm_notice(>drm, "%s, disabling use of stolen memory\n", "iGVT-g active"); - return 0; + return -ENOSPC; } if (i915_vtd_active(i915) && GRAPHICS_VER(i915) < 8) { drm_notice(>drm, "%s, disabling use of stolen memory\n", "DMAR active"); - return 0; + return -ENOSPC; } if (adjust_stolen(i915, >region)) - return 0; + return -ENOSPC; if (request_smem_stolen(i915, >region)) - return 0; + return -ENOSPC; i915->dsm = mem->region; if (init_reserved_stolen(i915)) - return 0; + return -ENOSPC; /* Exclude the reserved region from driver use */ mem->region.end = i915->dsm_reserved.start - 1; @@ -527,7 +527,7 @@ static int i915_gem_init_stolen(struct intel_memory_region *mem) (u64)i915->stolen_usable_size >> 10); if (i915->stolen_usable_size == 0) - return 0; + return -ENOSPC; /* Basic memrange allocator for stolen space. */ drm_mm_init(>mm.stolen, 0, i915->stolen_usable_size); @@ -765,11 +765,17 @@ i915_gem_object_create_stolen(struct drm_i915_private *i915, static int init_stolen_smem(struct intel_memory_region *mem) { + int err; + /* * Initialise stolen early so that we may reserve preallocated * objects for the BIOS to KMS transition. */ - return i915_gem_init_stolen(mem); + err = i915_gem_init_stolen(mem); + if (err) + drm_dbg(>i915->drm, "Skip stolen region: failed to setup\n"); + + return 0; } static int release_stolen_smem(struct intel_memory_region *mem) @@ -786,21 +792,25 @@ static const struct intel_memory_region_ops i915_region_stolen_smem_ops = { static int init_stolen_lmem(struct intel_memory_region *mem) { + struct drm_i915_private *i915 = mem->i915; int err; if (GEM_WARN_ON(resource_size(>region) == 0)) - return -ENODEV; + return 0; err = i915_gem_init_stolen(mem); - if (err) - return err; + if (err) { + drm_dbg(>i915->drm, "Skip stolen region: failed to setup\n"); + return 0; + } - if (mem->io_size && !io_mapping_init_wc(>iomap, - mem->io_start, - mem->io_size)) { - err = -EIO; + if (mem->io_size && + !io_mapping_init_wc(>iomap, mem->io_start, mem->io_size)) goto err_cleanup; - } + + drm_dbg(>drm, "Stolen Local memory IO start: %pa\n", + >io_start); + drm_dbg(>drm, "Stolen Local DSM base: %pa\n", >region.start); return 0; @@ -874,16 +884,6 @@ i915_gem_stolen_lmem_setup(struct drm_i915_private *i915, u16 type, if (IS_ERR(mem)) return mem; - /* -* TODO: consider creating common helper to just print all the -* interesting stuff from intel_memory_region, which we can use for all -* our probed regions. -*/ - -
Re: [PATCH v3 06/15] vfio/mtty: Use the new device life cycle helpers
On Fri, 9 Sep 2022 18:22:38 +0800 Kevin Tian wrote: > From: Yi Liu > > and manage available ports inside @init/@release. > > Signed-off-by: Yi Liu > Signed-off-by: Kevin Tian > Reviewed-by: Jason Gunthorpe > --- > samples/vfio-mdev/mtty.c | 67 +++- > 1 file changed, 39 insertions(+), 28 deletions(-) > > diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c > index f42a59ed2e3f..41301d50b247 100644 > --- a/samples/vfio-mdev/mtty.c > +++ b/samples/vfio-mdev/mtty.c ... > +static int mtty_probe(struct mdev_device *mdev) > +{ > + struct mdev_state *mdev_state; > + int ret; > + > + mdev_state = vfio_alloc_device(mdev_state, vdev, >dev, > +_dev_ops); > + if (IS_ERR(mdev_state)) > + return PTR_ERR(mdev_state); > > ret = vfio_register_emulated_iommu_dev(_state->vdev); > if (ret) > - goto err_vconfig; > + goto err_put_vdev; > dev_set_drvdata(>dev, mdev_state); > return 0; > > -err_vconfig: > - kfree(mdev_state->vconfig); > -err_state: > - vfio_uninit_group_dev(_state->vdev); > - kfree(mdev_state); > -err_nr_ports: > - atomic_add(nr_ports, _avail_ports); > +err_put_vdev: > + vfio_put_device(_state->vdev); > return ret; > } > > +static void mtty_release_dev(struct vfio_device *vdev) > +{ > + struct mdev_state *mdev_state = > + container_of(vdev, struct mdev_state, vdev); > + > + kfree(mdev_state->vconfig); > + vfio_free_device(vdev); > + atomic_add(mdev_state->nr_ports, _avail_ports); I must be missing something, isn't this a use-after-free? mdev_state is allocated via vfio_alloc_device(), where vdev is the first entry in that structure, so this is equivalent to kvfree(mdev_state). mbochs has the same issue. mdpy and vfio-ap adjust global counters after vfio_free_device(), which I think muddies the situation. Shouldn't we look suspiciously at any .release callback where vfio_free_device() isn't the last thing executed? Thanks, Alex
Re: [PATCH v2 2/3] drm/i915: Split i915_gem_init_stolen()
On 9/16/22 10:36 AM, Lucas De Marchi wrote: Add some helpers: adjust_stolen(), request_smem_stolen_() and init_reserved_stolen() that are now called by i915_gem_init_stolen() to initialize each part of the Data Stolen Memory region. Main goal is to split the reserved part within the stolen, also known as WOPCM, as its calculation changes often per platform and is a big source of confusion when handling stolen memory. Signed-off-by: Lucas De Marchi diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c index 3665f9b035bb..6edf4e374f54 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c @@ -77,22 +77,26 @@ void i915_gem_stolen_remove_node(struct drm_i915_private *i915, mutex_unlock(>mm.stolen_lock); } -static int i915_adjust_stolen(struct drm_i915_private *i915, - struct resource *dsm) +static bool valid_stolen_size(struct resource *dsm) +{ + return dsm->start != 0 && dsm->end > dsm->start; +} + +static int adjust_stolen(struct drm_i915_private *i915, +struct resource *dsm) { struct i915_ggtt *ggtt = to_gt(i915)->ggtt; struct intel_uncore *uncore = ggtt->vm.gt->uncore; - struct resource *r; - if (dsm->start == 0 || dsm->end <= dsm->start) + if (!valid_stolen_size(dsm)) return -EINVAL; /* +* Make sure we don't clobber the GTT if it's within stolen memory +* * TODO: We have yet too encounter the case where the GTT wasn't at the nit: as long as you're updating this comment block, s/too/to/ Otherwise, Reviewed-by: Wayne Boyer * end of stolen. With that assumption we could simplify this. */ - - /* Make sure we don't clobber the GTT if it's within stolen memory */ if (GRAPHICS_VER(i915) <= 4 && !IS_G33(i915) && !IS_PINEVIEW(i915) && !IS_G4X(i915)) { struct resource stolen[2] = {*dsm, *dsm}; @@ -131,10 +135,20 @@ static int i915_adjust_stolen(struct drm_i915_private *i915, } } + if (!valid_stolen_size(dsm)) + return -EINVAL; + + return 0; +} + +static int request_smem_stolen(struct drm_i915_private *i915, + struct resource *dsm) +{ + struct resource *r; + /* -* With stolen lmem, we don't need to check if the address range -* overlaps with the non-stolen system memory range, since lmem is local -* to the gpu. +* With stolen lmem, we don't need to request system memory for the +* address range since it's local to the gpu. */ if (HAS_LMEM(i915)) return 0; @@ -392,39 +406,22 @@ static void icl_get_stolen_reserved(struct drm_i915_private *i915, } } -static int i915_gem_init_stolen(struct intel_memory_region *mem) +/* + * Initialize i915->dsm_reserved to contain the reserved space within the Data + * Stolen Memory. This is a range on the top of DSM that is reserved, not to + * be used by driver, so must be excluded from the region passed to the + * allocator later. In the spec this is also called as WOPCM. + * + * Our expectation is that the reserved space is at the top of the stolen + * region, as it has been the case for every platform, and *never* at the + * bottom, so the calculation here can be simplified. + */ +static int init_reserved_stolen(struct drm_i915_private *i915) { - struct drm_i915_private *i915 = mem->i915; struct intel_uncore *uncore = >uncore; resource_size_t reserved_base, stolen_top; - resource_size_t reserved_total, reserved_size; - - mutex_init(>mm.stolen_lock); - - if (intel_vgpu_active(i915)) { - drm_notice(>drm, - "%s, disabling use of stolen memory\n", - "iGVT-g active"); - return 0; - } - - if (i915_vtd_active(i915) && GRAPHICS_VER(i915) < 8) { - drm_notice(>drm, - "%s, disabling use of stolen memory\n", - "DMAR active"); - return 0; - } - - if (resource_size(>region) == 0) - return 0; - - i915->dsm = mem->region; - - if (i915_adjust_stolen(i915, >dsm)) - return 0; - - GEM_BUG_ON(i915->dsm.start == 0); - GEM_BUG_ON(i915->dsm.end <= i915->dsm.start); + resource_size_t reserved_size; + int ret = 0; stolen_top = i915->dsm.end + 1; reserved_base = stolen_top; @@ -455,17 +452,16 @@ static int i915_gem_init_stolen(struct intel_memory_region *mem) _base, _size); } - /* -* Our expectation is that the reserved space is at the top of the -* stolen region and *never* at the bottom. If we see !reserved_base, -* it likely means we
Re: [Intel-gfx] [PATCH v2 1/3] drm/i915: Add missing mask when reading GEN12_DSMBASE
On 9/16/22 10:36 AM, Lucas De Marchi wrote: DSMBASE register is defined so BDSM bitfield contains the bits 63 to 20 of the base address of stolen. For the supported platforms bits 0-19 are zero but that may not be true in future. Add the missing mask. v2: Use REG_GENMASK64() Acked-by: Aravind Iddamsetty Reviewed-by: Caz Yokoyama Signed-off-by: Lucas De Marchi Reviewed-by: Wayne Boyer diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c index acc561c0f0aa..3665f9b035bb 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c @@ -814,7 +814,7 @@ i915_gem_stolen_lmem_setup(struct drm_i915_private *i915, u16 type, return ERR_PTR(-ENXIO); /* Use DSM base address instead for stolen memory */ - dsm_base = intel_uncore_read64(uncore, GEN12_DSMBASE); + dsm_base = intel_uncore_read64(uncore, GEN12_DSMBASE) & GEN12_BDSM_MASK; if (IS_DG1(uncore->i915)) { lmem_size = pci_resource_len(pdev, GEN12_LMEM_BAR); if (WARN_ON(lmem_size < dsm_base)) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 1a9bd829fc7e..9584a50ed612 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7953,6 +7953,7 @@ enum skl_power_gate { #define GEN12_GSMBASE _MMIO(0x108100) #define GEN12_DSMBASE _MMIO(0x1080C0) +#define GEN12_BDSM_MASK REG_GENMASK64(63, 20) #define XEHP_CLOCK_GATE_DIS _MMIO(0x101014) #define SGSI_SIDECLK_DISREG_BIT(17) -- -- Wayne Boyer Graphics Software Engineer VTT-OSGC Platform Enablement
Re: [PATCH v3] drm/sched: Add FIFO sched policy to run queue v3
On 2022-09-19 23:11, Luben Tuikov wrote: Please run this patch through checkpatch.pl, as it shows 12 warnings with it. Use these command line options: "--strict --show-types". Inlined: On 2022-09-13 16:40, Andrey Grodzovsky wrote: Given many entities competing for same run queue on the same scheduler and unacceptably long wait time for some jobs waiting stuck in the run queue before being picked up are observed (seen using GPUVis). Since the second part of this sentence is the result of the first, I'd say something like "When many entities ... we see unacceptably long ...". The issue is due to the Round Robin policy used by schedulers to pick up the next entity's job queue for execution. Under stress of many entities and long job queus within entity some Spelling: "queues". jobs could be stack for very long time in it's entity's "stuck", not "stack". queue before being popped from the queue and executed while for other entities with smaller job queues a job might execute earlier even though that job arrived later then the job in the long queue. "than". Fix: Add FIFO selection policy to entities in run queue, chose next entity on run queue in such order that if job on one entity arrived earlier then job on another entity the first job will start executing earlier regardless of the length of the entity's job queue. v2: Switch to rb tree structure for entities based on TS of oldest job waiting in the job queue of an entity. Improves next entity extraction to O(1). Entity TS update O(log N) where N is the number of entities in the run-queue Drop default option in module control parameter. v3: Various cosmetical fixes and minor refactoring of fifo update function. Signed-off-by: Andrey Grodzovsky Tested-by: Li Yunxiang (Teddy) --- drivers/gpu/drm/scheduler/sched_entity.c | 26 - drivers/gpu/drm/scheduler/sched_main.c | 132 ++- include/drm/gpu_scheduler.h | 35 ++ 3 files changed, 187 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index 6b25b2f4f5a3..f3ffce3c9304 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -73,6 +73,7 @@ int drm_sched_entity_init(struct drm_sched_entity *entity, entity->priority = priority; entity->sched_list = num_sched_list > 1 ? sched_list : NULL; entity->last_scheduled = NULL; + RB_CLEAR_NODE(>rb_tree_node); if(num_sched_list) entity->rq = _list[0]->sched_rq[entity->priority]; @@ -417,14 +418,16 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity) sched_job = to_drm_sched_job(spsc_queue_peek(>job_queue)); if (!sched_job) - return NULL; + goto skip; while ((entity->dependency = drm_sched_job_dependency(sched_job, entity))) { trace_drm_sched_job_wait_dep(sched_job, entity->dependency); - if (drm_sched_entity_add_dependency_cb(entity)) - return NULL; + if (drm_sched_entity_add_dependency_cb(entity)) { + sched_job = NULL; + goto skip; + } } /* skip jobs from entity that marked guilty */ @@ -443,6 +446,16 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity) smp_wmb(); spsc_queue_pop(>job_queue); + + /* +* It's when head job is extracted we can access the next job (or empty) +* queue and update the entity location in the min heap accordingly. +*/ +skip: + if (drm_sched_policy == DRM_SCHED_POLICY_FIFO) + drm_sched_rq_update_fifo(entity, +(sched_job ? sched_job->submit_ts : ktime_get())); + return sched_job; } @@ -502,11 +515,13 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) { struct drm_sched_entity *entity = sched_job->entity; bool first; + ktime_t ts = ktime_get(); trace_drm_sched_job(sched_job, entity); atomic_inc(entity->rq->sched->score); WRITE_ONCE(entity->last_user, current->group_leader); first = spsc_queue_push(>job_queue, _job->queue_node); + sched_job->submit_ts = ts; /* first job wakes up scheduler */ if (first) { @@ -518,8 +533,13 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) DRM_ERROR("Trying to push to a killed entity\n"); return; } + drm_sched_rq_add_entity(entity->rq, entity); spin_unlock(>rq_lock); + + if (drm_sched_policy == DRM_SCHED_POLICY_FIFO) + drm_sched_rq_update_fifo(entity, ts); + drm_sched_wakeup(entity->rq->sched); } } diff --git
Re: [PATCH V2 1/2] dt-bindings: display: panel: Add Samsung AMS495QA01 bindings
Hello, Thanks for the patch, It's so nice seeing more pieces of RG503 being upstreamed. wt., 20 wrz 2022 o 19:10 Chris Morgan napisał(a): > > From: Chris Morgan > > Add documentation for the Samsung AMS495QA01 panel. > > Signed-off-by: Chris Morgan > --- > .../display/panel/samsung,ams495qa01.yaml | 46 +++ > 1 file changed, 46 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/panel/samsung,ams495qa01.yaml > > diff --git > a/Documentation/devicetree/bindings/display/panel/samsung,ams495qa01.yaml > b/Documentation/devicetree/bindings/display/panel/samsung,ams495qa01.yaml > new file mode 100644 > index ..08358cdad19c > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/panel/samsung,ams495qa01.yaml > @@ -0,0 +1,46 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/display/panel/samsung,ams495qa01.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Samsung AMS495QA01 4.95in 960x544 DSI/SPI panel > + > +maintainers: > + - Chris Morgan > + > +allOf: > + - $ref: panel-common.yaml# > + > +properties: > + compatible: > +const: samsung,ams495qa01 > + reg: true > + reset-gpios: true > + elvdd-supply: > +description: regulator that supplies voltage to the panel display Datasheet says about that pin: "Power pin for module analog", maybe in description that could be accounted for? > + enable-gpios: true > + port: true > + vdd-supply: > +description: regulator that supplies voltage to panel logic Maybe change that to "panel's logic"? > + > +required: > + - compatible > + - reg > + - vdd-supply > + > +additionalProperties: false > + > +examples: > + - | > +spi { > +#address-cells = <1>; > +#size-cells = <0>; > +panel@0 { > +compatible = "samsung,ams495qa01"; > +reg = <0>; > +vdd-supply = <_lcd0_n>; > +}; Where's the node of DSI controller the panel's attached to? > +}; > + > +... > -- > 2.25.1 > Best Regards, Maya Matuszczyk
Re: [PATCH V2 2/2] drm/panel: Add Samsung AMS495QA01 MIPI-DSI LCD panel
Hi Chris, Thanks for this patch, wt., 20 wrz 2022 o 19:10 Chris Morgan napisał(a): > > From: Chris Morgan > > Support Samsung AMS495QA01 panel as found on the Anbernic RG503. Note > This panel receives video signals via DSI, however it receives > commands via 3-wire SPI. > > Signed-off-by: Chris Morgan > --- > drivers/gpu/drm/panel/Kconfig | 10 + > drivers/gpu/drm/panel/Makefile| 1 + > .../gpu/drm/panel/panel-samsung-ams495qa01.c | 505 ++ > 3 files changed, 516 insertions(+) > create mode 100644 drivers/gpu/drm/panel/panel-samsung-ams495qa01.c > > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig > index a9043eacce97..954b66a2adee 100644 > --- a/drivers/gpu/drm/panel/Kconfig > +++ b/drivers/gpu/drm/panel/Kconfig > @@ -444,6 +444,16 @@ config DRM_PANEL_RONBO_RB070D30 > Say Y here if you want to enable support for Ronbo Electronics > RB070D30 1024x600 DSI panel. > > +config DRM_PANEL_SAMSUNG_AMS495QA01 > + tristate "Samsung AMS495QA01 DSI panel" > + depends on OF && SPI > + depends on DRM_MIPI_DSI > + select DRM_MIPI_DBI > + help > + DRM panel driver for the Samsung AMS495QA01 panel. This panel > + receives video data via DSI but commands via 3-Wire 9-bit > + SPI. > + > config DRM_PANEL_SAMSUNG_ATNA33XC20 > tristate "Samsung ATNA33XC20 eDP panel" > depends on OF > diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile > index 34e717382dbb..de0b57baf851 100644 > --- a/drivers/gpu/drm/panel/Makefile > +++ b/drivers/gpu/drm/panel/Makefile > @@ -42,6 +42,7 @@ obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += > panel-raspberrypi-touchscreen > obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM67191) += panel-raydium-rm67191.o > obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o > obj-$(CONFIG_DRM_PANEL_RONBO_RB070D30) += panel-ronbo-rb070d30.o > +obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMS495QA01) += panel-samsung-ams495qa01.o > obj-$(CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20) += panel-samsung-atna33xc20.o > obj-$(CONFIG_DRM_PANEL_SAMSUNG_DB7430) += panel-samsung-db7430.o > obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o > diff --git a/drivers/gpu/drm/panel/panel-samsung-ams495qa01.c > b/drivers/gpu/drm/panel/panel-samsung-ams495qa01.c > new file mode 100644 > index ..d693ba5f20c9 > --- /dev/null > +++ b/drivers/gpu/drm/panel/panel-samsung-ams495qa01.c > @@ -0,0 +1,505 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Samsung ams495qa01 MIPI-DSI panel driver > + * Copyright (C) 2022 Chris Morgan > + */ > + > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +struct ams495qa01 { > + /** @dev: the container device */ > + struct device *dev; > + /** @dbi: the DBI bus abstraction handle */ > + struct mipi_dbi dbi; > + /** @panel: the DRM panel instance for this device */ > + struct drm_panel panel; > + /** @reset: reset GPIO line */ > + struct gpio_desc *reset; > + /** @enable: enable GPIO line */ > + struct gpio_desc *enable; > + /** @reg_vdd: VDD supply regulator for panel logic */ > + struct regulator *reg_vdd; > + /** @reg_elvdd: ELVDD supply regulator for panel display */ > + struct regulator *reg_elvdd; > + /** @dsi_dev: DSI child device (panel) */ > + struct mipi_dsi_device *dsi_dev; > + /** @bl_dev: pseudo-backlight device for oled panel */ > + struct backlight_device *bl_dev; > + /** @prepared: value tracking panel prepare status */ > + bool prepared; > +}; > + > +static const struct drm_display_mode ams495qa01_mode = { > + .clock = 33500, > + .hdisplay = 960, > + .hsync_start = 960 + 10, > + .hsync_end = 960 + 10 + 2, > + .htotal = 960 + 10 + 2 + 10, > + .vdisplay = 544, > + .vsync_start = 544 + 10, > + .vsync_end = 544 + 10 + 2, > + .vtotal = 544 + 10 + 2 + 10, > + .width_mm = 117, > + .height_mm = 74, > + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, > +}; > + > +#define NUM_GAMMA_LEVELS 16 > +#define GAMMA_TABLE_COUNT 23 > +#define MAX_BRIGHTNESS (NUM_GAMMA_LEVELS - 1) > + > +/* Table of gamma values provided in datasheet */ > +static u8 ams495qa01_gamma[NUM_GAMMA_LEVELS][GAMMA_TABLE_COUNT] = { > + {0x01, 0x79, 0x78, 0x8d, 0xd9, 0xdf, 0xd5, 0xcb, 0xcf, 0xc5, > +0xe5, 0xe0, 0xe4, 0xdc, 0xb8, 0xd4, 0xfa, 0xed, 0xe6, 0x2f, > +0x00, 0x2f}, > + {0x01, 0x7d, 0x7c, 0x92, 0xd7, 0xdd, 0xd2, 0xcb, 0xd0, 0xc6, > +0xe5, 0xe1, 0xe3, 0xda, 0xbd, 0xd3, 0xfa, 0xed, 0xe6, 0x2f, > +0x00, 0x2f}, > + {0x01, 0x7f, 0x7e, 0x95, 0xd7, 0xde, 0xd2, 0xcb, 0xcf, 0xc5, > +
[PATCH v7 3/5] drm/bridge: cdns-dsi: Move to drm/bridge/cadence
Move the cadence dsi bridge under drm/bridge/cadence directory, to prepare for adding j721e wrapper support Signed-off-by: Rahul T R --- drivers/gpu/drm/bridge/Kconfig| 11 --- drivers/gpu/drm/bridge/Makefile | 1 - drivers/gpu/drm/bridge/cadence/Kconfig| 11 +++ drivers/gpu/drm/bridge/cadence/Makefile | 2 ++ .../bridge/{cdns-dsi.c => cadence/cdns-dsi-core.c}| 0 5 files changed, 13 insertions(+), 12 deletions(-) rename drivers/gpu/drm/bridge/{cdns-dsi.c => cadence/cdns-dsi-core.c} (100%) diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 57946d80b02d..8b2226f72b24 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -15,17 +15,6 @@ config DRM_PANEL_BRIDGE menu "Display Interface Bridges" depends on DRM && DRM_BRIDGE -config DRM_CDNS_DSI - tristate "Cadence DPI/DSI bridge" - select DRM_KMS_HELPER - select DRM_MIPI_DSI - select DRM_PANEL_BRIDGE - select GENERIC_PHY_MIPI_DPHY - depends on OF - help - Support Cadence DPI to DSI bridge. This is an internal - bridge and is meant to be directly embedded in a SoC. - config DRM_CHIPONE_ICN6211 tristate "Chipone ICN6211 MIPI-DSI/RGB Converter bridge" depends on OF diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index 1884803c6860..52f6e8b4a821 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,5 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig b/drivers/gpu/drm/bridge/cadence/Kconfig index 1d06182bea71..8fbb46c66094 100644 --- a/drivers/gpu/drm/bridge/cadence/Kconfig +++ b/drivers/gpu/drm/bridge/cadence/Kconfig @@ -25,3 +25,14 @@ config DRM_CDNS_MHDP8546_J721E initializes the J721E Display Port and sets up the clock and data muxes. endif + +config DRM_CDNS_DSI + tristate "Cadence DPI/DSI bridge" + select DRM_KMS_HELPER + select DRM_MIPI_DSI + select DRM_PANEL_BRIDGE + select GENERIC_PHY_MIPI_DPHY + depends on OF + help + Support Cadence DPI to DSI bridge. This is an internal + bridge and is meant to be directly embedded in a SoC. diff --git a/drivers/gpu/drm/bridge/cadence/Makefile b/drivers/gpu/drm/bridge/cadence/Makefile index 4d2db8df1bc6..e3d8e9a40784 100644 --- a/drivers/gpu/drm/bridge/cadence/Makefile +++ b/drivers/gpu/drm/bridge/cadence/Makefile @@ -2,3 +2,5 @@ obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o +obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o +cdns-dsi-y := cdns-dsi-core.o diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c similarity index 100% rename from drivers/gpu/drm/bridge/cdns-dsi.c rename to drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c -- 2.37.3
Re: [PATCH] drm/i915: Do not cleanup obj with NULL bo->resource
On 20/09/2022 18:06, Nirmoy Das wrote: For delayed BO release i915_ttm_delete_mem_notify() gets called twice, once with proper bo->resource and another time with NULL. We shouldn't do anything for the 2nd time as we already cleanedup the obj once. References: https://gitlab.freedesktop.org/drm/intel/-/issues/6850 Signed-off-by: Nirmoy Das Reviewed-by: Matthew Auld Christian, as per above it looks like ttm calls into the delete_mem_notify() hook twice if the object ends up on the delayed destroy list, is that expected/normal? --- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index 0544b0a4a43a..e3fc38dd5db0 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -511,7 +511,7 @@ static void i915_ttm_delete_mem_notify(struct ttm_buffer_object *bo) struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo); intel_wakeref_t wakeref = 0; - if (likely(obj)) { + if (bo->resource && likely(obj)) { /* ttm_bo_release() already has dma_resv_lock */ if (i915_ttm_cpu_maps_iomem(bo->resource)) wakeref = intel_runtime_pm_get(_i915(obj->base.dev)->runtime_pm);
[PATCH V2 1/2] dt-bindings: display: panel: Add Samsung AMS495QA01 bindings
From: Chris Morgan Add documentation for the Samsung AMS495QA01 panel. Signed-off-by: Chris Morgan --- .../display/panel/samsung,ams495qa01.yaml | 46 +++ 1 file changed, 46 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,ams495qa01.yaml diff --git a/Documentation/devicetree/bindings/display/panel/samsung,ams495qa01.yaml b/Documentation/devicetree/bindings/display/panel/samsung,ams495qa01.yaml new file mode 100644 index ..08358cdad19c --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/samsung,ams495qa01.yaml @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/samsung,ams495qa01.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung AMS495QA01 4.95in 960x544 DSI/SPI panel + +maintainers: + - Chris Morgan + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: +const: samsung,ams495qa01 + reg: true + reset-gpios: true + elvdd-supply: +description: regulator that supplies voltage to the panel display + enable-gpios: true + port: true + vdd-supply: +description: regulator that supplies voltage to panel logic + +required: + - compatible + - reg + - vdd-supply + +additionalProperties: false + +examples: + - | +spi { +#address-cells = <1>; +#size-cells = <0>; +panel@0 { +compatible = "samsung,ams495qa01"; +reg = <0>; +vdd-supply = <_lcd0_n>; +}; +}; + +... -- 2.25.1
[PATCH V2 2/2] drm/panel: Add Samsung AMS495QA01 MIPI-DSI LCD panel
From: Chris Morgan Support Samsung AMS495QA01 panel as found on the Anbernic RG503. Note This panel receives video signals via DSI, however it receives commands via 3-wire SPI. Signed-off-by: Chris Morgan --- drivers/gpu/drm/panel/Kconfig | 10 + drivers/gpu/drm/panel/Makefile| 1 + .../gpu/drm/panel/panel-samsung-ams495qa01.c | 505 ++ 3 files changed, 516 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-samsung-ams495qa01.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index a9043eacce97..954b66a2adee 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -444,6 +444,16 @@ config DRM_PANEL_RONBO_RB070D30 Say Y here if you want to enable support for Ronbo Electronics RB070D30 1024x600 DSI panel. +config DRM_PANEL_SAMSUNG_AMS495QA01 + tristate "Samsung AMS495QA01 DSI panel" + depends on OF && SPI + depends on DRM_MIPI_DSI + select DRM_MIPI_DBI + help + DRM panel driver for the Samsung AMS495QA01 panel. This panel + receives video data via DSI but commands via 3-Wire 9-bit + SPI. + config DRM_PANEL_SAMSUNG_ATNA33XC20 tristate "Samsung ATNA33XC20 eDP panel" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 34e717382dbb..de0b57baf851 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM67191) += panel-raydium-rm67191.o obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o obj-$(CONFIG_DRM_PANEL_RONBO_RB070D30) += panel-ronbo-rb070d30.o +obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMS495QA01) += panel-samsung-ams495qa01.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20) += panel-samsung-atna33xc20.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_DB7430) += panel-samsung-db7430.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o diff --git a/drivers/gpu/drm/panel/panel-samsung-ams495qa01.c b/drivers/gpu/drm/panel/panel-samsung-ams495qa01.c new file mode 100644 index ..d693ba5f20c9 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-samsung-ams495qa01.c @@ -0,0 +1,505 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Samsung ams495qa01 MIPI-DSI panel driver + * Copyright (C) 2022 Chris Morgan + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct ams495qa01 { + /** @dev: the container device */ + struct device *dev; + /** @dbi: the DBI bus abstraction handle */ + struct mipi_dbi dbi; + /** @panel: the DRM panel instance for this device */ + struct drm_panel panel; + /** @reset: reset GPIO line */ + struct gpio_desc *reset; + /** @enable: enable GPIO line */ + struct gpio_desc *enable; + /** @reg_vdd: VDD supply regulator for panel logic */ + struct regulator *reg_vdd; + /** @reg_elvdd: ELVDD supply regulator for panel display */ + struct regulator *reg_elvdd; + /** @dsi_dev: DSI child device (panel) */ + struct mipi_dsi_device *dsi_dev; + /** @bl_dev: pseudo-backlight device for oled panel */ + struct backlight_device *bl_dev; + /** @prepared: value tracking panel prepare status */ + bool prepared; +}; + +static const struct drm_display_mode ams495qa01_mode = { + .clock = 33500, + .hdisplay = 960, + .hsync_start = 960 + 10, + .hsync_end = 960 + 10 + 2, + .htotal = 960 + 10 + 2 + 10, + .vdisplay = 544, + .vsync_start = 544 + 10, + .vsync_end = 544 + 10 + 2, + .vtotal = 544 + 10 + 2 + 10, + .width_mm = 117, + .height_mm = 74, + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, +}; + +#define NUM_GAMMA_LEVELS 16 +#define GAMMA_TABLE_COUNT 23 +#define MAX_BRIGHTNESS (NUM_GAMMA_LEVELS - 1) + +/* Table of gamma values provided in datasheet */ +static u8 ams495qa01_gamma[NUM_GAMMA_LEVELS][GAMMA_TABLE_COUNT] = { + {0x01, 0x79, 0x78, 0x8d, 0xd9, 0xdf, 0xd5, 0xcb, 0xcf, 0xc5, +0xe5, 0xe0, 0xe4, 0xdc, 0xb8, 0xd4, 0xfa, 0xed, 0xe6, 0x2f, +0x00, 0x2f}, + {0x01, 0x7d, 0x7c, 0x92, 0xd7, 0xdd, 0xd2, 0xcb, 0xd0, 0xc6, +0xe5, 0xe1, 0xe3, 0xda, 0xbd, 0xd3, 0xfa, 0xed, 0xe6, 0x2f, +0x00, 0x2f}, + {0x01, 0x7f, 0x7e, 0x95, 0xd7, 0xde, 0xd2, 0xcb, 0xcf, 0xc5, +0xe5, 0xe3, 0xe3, 0xda, 0xbf, 0xd3, 0xfa, 0xed, 0xe6, 0x2f, +0x00, 0x2f}, + {0x01, 0x82, 0x81, 0x99, 0xd6, 0xdd, 0xd1, 0xca, 0xcf, 0xc3, +0xe4, 0xe3, 0xe3, 0xda, 0xc2, 0xd3, 0xfa, 0xed, 0xe6, 0x2f, +0x00, 0x2f}, + {0x01, 0x84, 0x83, 0x9b, 0xd7, 0xde, 0xd2, 0xc8, 0xce, 0xc2, +0xe4, 0xe3, 0xe2, 0xd9,
[PATCH V2 0/2] drm/panel: Add Samsung AMS495QA01 Panel
From: Chris Morgan Add the Samsung AMS495QA01 panel as found on the Anbernic RG503. This panel uses DSI to receive video signals, but 3-wire SPI to receive command signals. Changes since V1: - Removed errant reference to backlight in documentation. This is an OLED panel. - Made elvss regulator optional. In my case its hard wired and not controllable. - Added "prepared" enum to track panel status to prevent unbalanced regulator enable/disable. Chris Morgan (2): dt-bindings: display: panel: Add Samsung AMS495QA01 bindings drm/panel: Add Samsung AMS495QA01 MIPI-DSI LCD panel .../display/panel/samsung,ams495qa01.yaml | 46 ++ drivers/gpu/drm/panel/Kconfig | 10 + drivers/gpu/drm/panel/Makefile| 1 + .../gpu/drm/panel/panel-samsung-ams495qa01.c | 505 ++ 4 files changed, 562 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,ams495qa01.yaml create mode 100644 drivers/gpu/drm/panel/panel-samsung-ams495qa01.c -- 2.25.1
[PATCH] drm/i915: Do not cleanup obj with NULL bo->resource
For delayed BO release i915_ttm_delete_mem_notify() gets called twice, once with proper bo->resource and another time with NULL. We shouldn't do anything for the 2nd time as we already cleanedup the obj once. References: https://gitlab.freedesktop.org/drm/intel/-/issues/6850 Signed-off-by: Nirmoy Das --- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index 0544b0a4a43a..e3fc38dd5db0 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -511,7 +511,7 @@ static void i915_ttm_delete_mem_notify(struct ttm_buffer_object *bo) struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo); intel_wakeref_t wakeref = 0; - if (likely(obj)) { + if (bo->resource && likely(obj)) { /* ttm_bo_release() already has dma_resv_lock */ if (i915_ttm_cpu_maps_iomem(bo->resource)) wakeref = intel_runtime_pm_get(_i915(obj->base.dev)->runtime_pm); -- 2.37.3
Re: [PATCH v2] A simple doc fix
After rebasing to latest drm-misc-next to latest I actually see someone else already fixed this and other kerneldoc warnings so we can skip this patch. Andrey On 2022-09-20 02:46, Anup K Parikh wrote: Fix two warnings during doc build which also results in corresponding additions in generated docs Warnings Fixed: 1. include/drm/gpu_scheduler.h:462: warning: Function parameter or member 'dev' not described in 'drm_gpu_scheduler' 2. drivers/gpu/drm/scheduler/sched_main.c:1005: warning: Function parameter or member 'dev' not described in 'drm_sched_init' Signed-off-by: Anup K Parikh --- Changes in v2: Correct the doc strings according to Link: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2Fall%2Ff528a8e4-5162-66d5-09da-5252076882b8%40amd.com%2Fdata=05%7C01%7Candrey.grodzovsky%40amd.com%7Ccbef53d3f32845465ce908da9ad3f29b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637992532358603366%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7Csdata=PnHCvtDFVWnb25YkDfjHcmy9MBpLCA462xco799rjJs%3Dreserved=0 drivers/gpu/drm/scheduler/sched_main.c | 2 ++ include/drm/gpu_scheduler.h| 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index 68317d3a7a27..979685830671 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -994,6 +994,8 @@ static int drm_sched_main(void *param) *used * @score: optional score atomic shared with other schedulers * @name: name used for debugging + * @dev: A device pointer - primarily useful for printing standardized + * messages with DRM_DEV_ERROR(). * * Return 0 on success, otherwise error code. */ diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index addb135eeea6..80a525dd19bd 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -435,6 +435,8 @@ struct drm_sched_backend_ops { * @_score: score used when the driver doesn't provide one * @ready: marks if the underlying HW is ready to work * @free_guilty: A hit to time out handler to free the guilty job. + * @dev: A device pointer - primarily useful for printing standardized + * messages with DRM_DEV_ERROR(). * * One scheduler is implemented for each hardware ring. */
Re: [Intel-gfx] [PATCH 1/1] drm/i915/mtl: enable local stolen memory
Hi Aravind, > +static int get_mtl_gms_size(struct intel_uncore *uncore) > +{ > + u16 ggc, gms; > + > + ggc = intel_uncore_read16(uncore, _MMIO(0x108040)); > + > + /* check GGMS, should be fixed 0x3 (8MB) */ > + if ((ggc & 0xc0) != 0xc0) > + return -EIO; > + > + /* return valid GMS value, -EIO if invalid */ > + gms = ggc >> 8; > + switch (gms) { > + case 0x0 ... 0x10: > + return gms * 32; > + case 0x20: > + return 1024; > + case 0x30: > + return 1536; > + case 0x40: > + return 2048; > + case 0xf0 ... 0xfe: just a bit puzzled by the fact that case ranges are not standard and are supported only by GCC, unless, of course, I miss something. Do we still want to use them as they are widely used around the kernel? Andi > + return (gms - 0xf0 + 1) * 4; > + default: > + return -EIO; > + } > +}
[PATCH v7 4/5] drm/bridge: cdns-dsi: Create a header file
Create a header file for cdns dsi and move register offsets and structure to header, to prepare for adding j721e wrapper support Signed-off-by: Rahul T R --- .../gpu/drm/bridge/cadence/cdns-dsi-core.c| 446 + .../gpu/drm/bridge/cadence/cdns-dsi-core.h| 458 ++ 2 files changed, 459 insertions(+), 445 deletions(-) create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index 20bece84ff8c..cba91247ab26 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -6,10 +6,7 @@ */ #include -#include #include -#include -#include #include #include @@ -23,448 +20,7 @@ #include #include -#include -#include - -#define IP_CONF0x0 -#define SP_HS_FIFO_DEPTH(x)(((x) & GENMASK(30, 26)) >> 26) -#define SP_LP_FIFO_DEPTH(x)(((x) & GENMASK(25, 21)) >> 21) -#define VRS_FIFO_DEPTH(x) (((x) & GENMASK(20, 16)) >> 16) -#define DIRCMD_FIFO_DEPTH(x) (((x) & GENMASK(15, 13)) >> 13) -#define SDI_IFACE_32 BIT(12) -#define INTERNAL_DATAPATH_32 (0 << 10) -#define INTERNAL_DATAPATH_16 (1 << 10) -#define INTERNAL_DATAPATH_8(3 << 10) -#define INTERNAL_DATAPATH_SIZE ((x) & GENMASK(11, 10)) -#define NUM_IFACE(x) x) & GENMASK(9, 8)) >> 8) + 1) -#define MAX_LANE_NB(x) (((x) & GENMASK(7, 6)) >> 6) -#define RX_FIFO_DEPTH(x) ((x) & GENMASK(5, 0)) - -#define MCTL_MAIN_DATA_CTL 0x4 -#define TE_MIPI_POLLING_EN BIT(25) -#define TE_HW_POLLING_EN BIT(24) -#define DISP_EOT_GEN BIT(18) -#define HOST_EOT_GEN BIT(17) -#define DISP_GEN_CHECKSUM BIT(16) -#define DISP_GEN_ECC BIT(15) -#define BTA_EN BIT(14) -#define READ_ENBIT(13) -#define REG_TE_EN BIT(12) -#define IF_TE_EN(x)BIT(8 + (x)) -#define TVG_SELBIT(6) -#define VID_EN BIT(5) -#define IF_VID_SELECT(x) ((x) << 2) -#define IF_VID_SELECT_MASK GENMASK(3, 2) -#define IF_VID_MODEBIT(1) -#define LINK_ENBIT(0) - -#define MCTL_MAIN_PHY_CTL 0x8 -#define HS_INVERT_DAT(x) BIT(19 + ((x) * 2)) -#define SWAP_PINS_DAT(x) BIT(18 + ((x) * 2)) -#define HS_INVERT_CLK BIT(17) -#define SWAP_PINS_CLK BIT(16) -#define HS_SKEWCAL_EN BIT(15) -#define WAIT_BURST_TIME(x) ((x) << 10) -#define DATA_ULPM_EN(x)BIT(6 + (x)) -#define CLK_ULPM_ENBIT(5) -#define CLK_CONTINUOUS BIT(4) -#define DATA_LANE_EN(x)BIT((x) - 1) - -#define MCTL_MAIN_EN 0xc -#define DATA_FORCE_STOPBIT(17) -#define CLK_FORCE_STOP BIT(16) -#define IF_EN(x) BIT(13 + (x)) -#define DATA_LANE_ULPM_REQ(l) BIT(9 + (l)) -#define CLK_LANE_ULPM_REQ BIT(8) -#define DATA_LANE_START(x) BIT(4 + (x)) -#define CLK_LANE_ENBIT(3) -#define PLL_START BIT(0) - -#define MCTL_DPHY_CFG0 0x10 -#define DPHY_C_RSTBBIT(20) -#define DPHY_D_RSTB(x) GENMASK(15 + (x), 16) -#define DPHY_PLL_PDN BIT(10) -#define DPHY_CMN_PDN BIT(9) -#define DPHY_C_PDN BIT(8) -#define DPHY_D_PDN(x) GENMASK(3 + (x), 4) -#define DPHY_ALL_D_PDN GENMASK(7, 4) -#define DPHY_PLL_PSO BIT(1) -#define DPHY_CMN_PSO BIT(0) - -#define MCTL_DPHY_TIMEOUT1 0x14 -#define HSTX_TIMEOUT(x)((x) << 4) -#define HSTX_TIMEOUT_MAX GENMASK(17, 0) -#define CLK_DIV(x) (x) -#define CLK_DIV_MAXGENMASK(3, 0) - -#define MCTL_DPHY_TIMEOUT2 0x18 -#define LPRX_TIMEOUT(x)(x) - -#define MCTL_ULPOUT_TIME 0x1c -#define DATA_LANE_ULPOUT_TIME(x) ((x) << 9) -#define CLK_LANE_ULPOUT_TIME(x)(x) - -#define MCTL_3DVIDEO_CTL 0x20 -#define VID_VSYNC_3D_ENBIT(7) -#define VID_VSYNC_3D_LRBIT(5) -#define VID_VSYNC_3D_SECOND_EN BIT(4) -#define VID_VSYNC_3DFORMAT_LINE(0 << 2) -#define VID_VSYNC_3DFORMAT_FRAME (1 << 2) -#define VID_VSYNC_3DFORMAT_PIXEL (2 << 2) -#define VID_VSYNC_3DMODE_OFF 0 -#define VID_VSYNC_3DMODE_PORTRAIT 1
Re: [PATCH v2] A simple doc fix
Reviewed-by: Andrey Grodzovsky Will push it to drm-misc-next Thanks, Andrey On 2022-09-20 02:46, Anup K Parikh wrote: Fix two warnings during doc build which also results in corresponding additions in generated docs Warnings Fixed: 1. include/drm/gpu_scheduler.h:462: warning: Function parameter or member 'dev' not described in 'drm_gpu_scheduler' 2. drivers/gpu/drm/scheduler/sched_main.c:1005: warning: Function parameter or member 'dev' not described in 'drm_sched_init' Signed-off-by: Anup K Parikh --- Changes in v2: Correct the doc strings according to Link: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2Fall%2Ff528a8e4-5162-66d5-09da-5252076882b8%40amd.com%2Fdata=05%7C01%7Candrey.grodzovsky%40amd.com%7Ccbef53d3f32845465ce908da9ad3f29b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637992532358603366%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7Csdata=PnHCvtDFVWnb25YkDfjHcmy9MBpLCA462xco799rjJs%3Dreserved=0 drivers/gpu/drm/scheduler/sched_main.c | 2 ++ include/drm/gpu_scheduler.h| 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index 68317d3a7a27..979685830671 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -994,6 +994,8 @@ static int drm_sched_main(void *param) *used * @score: optional score atomic shared with other schedulers * @name: name used for debugging + * @dev: A device pointer - primarily useful for printing standardized + * messages with DRM_DEV_ERROR(). * * Return 0 on success, otherwise error code. */ diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index addb135eeea6..80a525dd19bd 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -435,6 +435,8 @@ struct drm_sched_backend_ops { * @_score: score used when the driver doesn't provide one * @ready: marks if the underlying HW is ready to work * @free_guilty: A hit to time out handler to free the guilty job. + * @dev: A device pointer - primarily useful for printing standardized + * messages with DRM_DEV_ERROR(). * * One scheduler is implemented for each hardware ring. */
Re: [BUG] ls1046a: eDMA does not transfer data from I2C
On 9/20/22 11:44 AM, Sean Anderson wrote: > > > On 9/20/22 11:24 AM, Sean Anderson wrote: >> >> >> On 9/20/22 6:07 AM, Robin Murphy wrote: >>> On 2022-09-19 23:24, Sean Anderson wrote: Hi all, I discovered a bug in either imx_i2c or fsl-edma on the LS1046A where no data is read in i2c_imx_dma_read except for the last two bytes (which are not read using DMA). This is perhaps best illustrated with the following example: # hexdump -C /sys/bus/nvmem/devices/0-00540/nvmem [ 308.914884] i2c i2c-0: 00080938 0x00088938 0xf5401000 75401000 [ 308.923529] src= 2180004 dst=f5401000 attr= 0 soff= 0 nbytes=1 slast= 0 [ 308.923529] citer= 7e biter= 7e doff= 1 dlast_sga= 0 [ 308.923529] major_int=1 disable_req=1 enable_sg=0 [ 308.942113] fsl-edma 2c0.edma: vchan 1b4371fc: txd d9dd26c5[4]: submitted [ 308.974049] fsl-edma 2c0.edma: txd d9dd26c5[4]: marked complete [ 308.981339] i2c i2c-0: 00080938 = [2e 2e 2f 2e 2e 2f 2e 2e 2f 64 65 76 69 63 65 73 2f 70 6c 61 74 66 6f 72 6d 2f 73 6f 63 2f 32 31 38 30 30 30 30 2e 69 32 63 2f 69 32 63 2d 30 2f 30 2d 30 30 35 34 2f 30 2d 30 30 35 34 30 00 00] [ 309.002226] i2c i2c-0: 75401000 = [2e 2e 2f 2e 2e 2f 2e 2e 2f 64 65 76 69 63 65 73 2f 70 6c 61 74 66 6f 72 6d 2f 73 6f 63 2f 32 31 38 30 30 30 30 2e 69 32 63 2f 69 32 63 2d 30 2f 30 2d 30 30 35 34 2f 30 2d 30 30 35 34 30 00 00] [ 309.024649] i2c i2c-0: 000809380080 0x000889380080 0xf5401800 75401800 [ 309.033270] src= 2180004 dst=f5401800 attr= 0 soff= 0 nbytes=1 slast= 0 [ 309.033270] citer= 7e biter= 7e doff= 1 dlast_sga= 0 [ 309.033270] major_int=1 disable_req=1 enable_sg=0 [ 309.051633] fsl-edma 2c0.edma: vchan 1b4371fc: txd d9dd26c5[5]: submitted [ 309.083526] fsl-edma 2c0.edma: txd d9dd26c5[5]: marked complete [ 309.090807] i2c i2c-0: 000809380080 = [00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00] [ 309.111694] i2c i2c-0: 75401800 = [00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00] 2e 2e 2f 2e 2e 2f 2e 2e 2f 64 65 76 69 63 65 73 |../../../devices| 0010 2f 70 6c 61 74 66 6f 72 6d 2f 73 6f 63 2f 32 31 |/platform/soc/21| 0020 38 30 30 30 30 2e 69 32 63 2f 69 32 63 2d 30 2f |8.i2c/i2c-0/| 0030 30 2d 30 30 35 34 2f 30 2d 30 30 35 34 30 00 00 |0-0054/0-00540..| 0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 || * 0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff || 0080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 || * 00f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 5b |...[| 0100 (patch with my debug prints appended below) Despite the DMA completing successfully, no data was copied into the buffer, leaving the original (now junk) contents. I probed the I2C bus with an oscilloscope, and I verified that the transfer did indeed occur. The timing between submission and completion seems reasonable for the bus speed (50 kHz for whatever reason). I had a look over the I2C driver, and nothing looked obviously incorrect. If anyone has ideas on what to try, I'm more than willing. >>> >>> Is the DMA controller cache-coherent? I see the mainline LS1046A DT doesn't >>> have a "dma-coherent" property for it, but the behaviour is entirely >>> consistent with that being wrong - dma_map_single() cleans the cache, >>> coherent DMA write hits the still-present cache lines, dma_unmap_single() >>> invalidates the cache, and boom, the data is gone and you read back the >>> previous content of the buffer that was cleaned out to DRAM beforehand. >> >> I've tried both with and without [1] applied. I also tried removing the >> call to dma_unmap_single, but to no effect. > > Actually, I wasn't updating my device tree like I thought... > > Turns out I2C works only *without* this patch. > > So maybe the eDMA is not coherent? It seems like this might be the case. From the reference manual: > All transactions from eDMA are tagged as snoop configuration if the > SCFG_SNPCNFGCR[eDMASNP] bit is set. Refer Snoop Configuration Register > (SCFG_SNPCNFGCR) for details. But there is no such bit in this register on the LS1046A. On the
Re: [PATCH linux-next] drm/amd/pm: Remove unneeded result variable
Applied. Thanks! On Tue, Sep 20, 2022 at 2:36 AM wrote: > > From: ye xingchen > > Return the value atomctrl_initialize_mc_reg_table_v2_2() directly instead > of storing it in another redundant variable. > > Reported-by: Zeal Robot > Signed-off-by: ye xingchen > --- > drivers/gpu/drm/amd/pm/powerplay/smumgr/polaris10_smumgr.c | 4 +--- > 1 file changed, 1 insertion(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/polaris10_smumgr.c > b/drivers/gpu/drm/amd/pm/powerplay/smumgr/polaris10_smumgr.c > index 45214a364baa..e7ed2a7adf8f 100644 > --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/polaris10_smumgr.c > +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/polaris10_smumgr.c > @@ -2567,15 +2567,13 @@ static uint8_t > polaris10_get_memory_modile_index(struct pp_hwmgr *hwmgr) > > static int polaris10_initialize_mc_reg_table(struct pp_hwmgr *hwmgr) > { > - int result; > struct polaris10_smumgr *smu_data = (struct polaris10_smumgr > *)(hwmgr->smu_backend); > pp_atomctrl_mc_reg_table *mc_reg_table = _data->mc_reg_table; > uint8_t module_index = polaris10_get_memory_modile_index(hwmgr); > > memset(mc_reg_table, 0, sizeof(pp_atomctrl_mc_reg_table)); > - result = atomctrl_initialize_mc_reg_table_v2_2(hwmgr, module_index, > mc_reg_table); > > - return result; > + return atomctrl_initialize_mc_reg_table_v2_2(hwmgr, module_index, > mc_reg_table); > } > > static bool polaris10_is_dpm_running(struct pp_hwmgr *hwmgr) > -- > 2.25.1
Re: [PATCH linux-next] drm/amd/pm: Remove the unneeded result variable
Applied. Thanks. On Tue, Sep 20, 2022 at 2:35 AM wrote: > > From: ye xingchen > > Return the value append_vbios_pptable() directly instead of storing it in > another redundant variable. > > Reported-by: Zeal Robot > Signed-off-by: ye xingchen > --- > .../gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c | 5 + > 1 file changed, 1 insertion(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c > b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c > index 1e79baab753e..bd54fbd393b9 100644 > --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c > +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c > @@ -195,7 +195,6 @@ static int init_powerplay_table_information( > struct phm_ppt_v3_information *pptable_information = > (struct phm_ppt_v3_information *)hwmgr->pptable; > uint32_t disable_power_control = 0; > - int result; > > hwmgr->thermal_controller.ucType = > powerplay_table->ucThermalControllerType; > pptable_information->uc_thermal_controller_type = > powerplay_table->ucThermalControllerType; > @@ -257,9 +256,7 @@ static int init_powerplay_table_information( > if (pptable_information->smc_pptable == NULL) > return -ENOMEM; > > - result = append_vbios_pptable(hwmgr, > (pptable_information->smc_pptable)); > - > - return result; > + return append_vbios_pptable(hwmgr, > (pptable_information->smc_pptable)); > } > > static int vega12_pp_tables_initialize(struct pp_hwmgr *hwmgr) > -- > 2.25.1
Re: [PATCH] drm/amdgpu: fix initial connector audio value
Applied. Thanks! Alex On Tue, Sep 20, 2022 at 6:34 AM hongao wrote: > > This got lost somewhere along the way, This fixes > audio not working until set_property was called. > > Signed-off-by: hongao > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > index e4054e10a2c2..5d2e3328dd83 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > @@ -1655,10 +1655,12 @@ amdgpu_connector_add(struct amdgpu_device *adev, > > adev->mode_info.dither_property, >AMDGPU_FMT_DITHER_DISABLE); > > - if (amdgpu_audio != 0) > + if (amdgpu_audio != 0) { > > drm_object_attach_property(_connector->base.base, > > adev->mode_info.audio_property, >AMDGPU_AUDIO_AUTO); > + amdgpu_connector->audio = AMDGPU_AUDIO_AUTO; > + } > > subpixel_order = SubPixelHorizontalRGB; > connector->interlace_allowed = true; > @@ -1763,6 +1765,7 @@ amdgpu_connector_add(struct amdgpu_device *adev, > > drm_object_attach_property(_connector->base.base, > > adev->mode_info.audio_property, >AMDGPU_AUDIO_AUTO); > + amdgpu_connector->audio = AMDGPU_AUDIO_AUTO; > } > > drm_object_attach_property(_connector->base.base, > > adev->mode_info.dither_property, > @@ -1811,6 +1814,7 @@ amdgpu_connector_add(struct amdgpu_device *adev, > > drm_object_attach_property(_connector->base.base, > > adev->mode_info.audio_property, >AMDGPU_AUDIO_AUTO); > + amdgpu_connector->audio = AMDGPU_AUDIO_AUTO; > } > > drm_object_attach_property(_connector->base.base, > > adev->mode_info.dither_property, > @@ -1856,6 +1860,7 @@ amdgpu_connector_add(struct amdgpu_device *adev, > > drm_object_attach_property(_connector->base.base, > > adev->mode_info.audio_property, >AMDGPU_AUDIO_AUTO); > + amdgpu_connector->audio = AMDGPU_AUDIO_AUTO; > } > > drm_object_attach_property(_connector->base.base, > > adev->mode_info.dither_property, > -- > 2.20.1 >
Re: [PATCH 1/2] drm/amd/display: Reduce number of arguments of dml314's CalculateWatermarksAndDRAMSpeedChangeSupport()
Applied the series. Thanks! Alex On Sat, Sep 17, 2022 at 8:38 AM Maíra Canal wrote: > > Hi Nathan, > > On 9/16/22 18:06, Nathan Chancellor wrote: > > Most of the arguments are identical between the two call sites and they > > can be accessed through the 'struct vba_vars_st' pointer. This reduces > > the total amount of stack space that > > dml314_ModeSupportAndSystemConfigurationFull() uses by 240 bytes with > > LLVM 16 (2216 -> 1976), helping clear up the following clang warning: > > > > > > drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn314/display_mode_vba_314.c:4020:6: > > error: stack frame size (2216) exceeds limit (2048) in > > 'dml314_ModeSupportAndSystemConfigurationFull' [-Werror,-Wframe-larger-than] > > void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib > > *mode_lib) > >^ > > 1 error generated. > > > > Link: https://github.com/ClangBuiltLinux/linux/issues/1710 > > Reported-by: "kernelci.org bot" > > Signed-off-by: Nathan Chancellor > > I have built-tested the whole series with clang 14.0.5 (Fedora > 14.0.5-1.fc36), using: > > $ make -kj"$(nproc)" ARCH=x86_64 LLVM=1 mrproper allmodconfig > drivers/gpu/drm/amd/amdgpu/ > > Another great patch to the DML! As Tom, I also would like to see this > expand to all display_mode_vba files, but so far this is great to > unbreak the build. > > To the whole series: > > Tested-by: Maíra Canal > > Best Regards, > - Maíra Canal > > > --- > > > > This is just commit ab2ac59c32db ("drm/amd/display: Reduce number of > > arguments of dml31's CalculateWatermarksAndDRAMSpeedChangeSupport()") > > applied to dml314. > > > > .../dc/dml/dcn314/display_mode_vba_314.c | 248 -- > > 1 file changed, 52 insertions(+), 196 deletions(-) > > > > diff --git > > a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c > > b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c > > index 2829f179f982..32ceb72f7a14 100644 > > --- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c > > +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c > > @@ -325,64 +325,28 @@ static void > > CalculateVupdateAndDynamicMetadataParameters( > > static void CalculateWatermarksAndDRAMSpeedChangeSupport( > > struct display_mode_lib *mode_lib, > > unsigned int PrefetchMode, > > - unsigned int NumberOfActivePlanes, > > - unsigned int MaxLineBufferLines, > > - unsigned int LineBufferSize, > > - unsigned int WritebackInterfaceBufferSize, > > double DCFCLK, > > double ReturnBW, > > - bool SynchronizedVBlank, > > - unsigned int dpte_group_bytes[], > > - unsigned int MetaChunkSize, > > double UrgentLatency, > > double ExtraLatency, > > - double WritebackLatency, > > - double WritebackChunkSize, > > double SOCCLK, > > - double DRAMClockChangeLatency, > > - double SRExitTime, > > - double SREnterPlusExitTime, > > - double SRExitZ8Time, > > - double SREnterPlusExitZ8Time, > > double DCFCLKDeepSleep, > > unsigned int DETBufferSizeY[], > > unsigned int DETBufferSizeC[], > > unsigned int SwathHeightY[], > > unsigned int SwathHeightC[], > > - unsigned int LBBitPerPixel[], > > double SwathWidthY[], > > double SwathWidthC[], > > - double HRatio[], > > - double HRatioChroma[], > > - unsigned int vtaps[], > > - unsigned int VTAPsChroma[], > > - double VRatio[], > > - double VRatioChroma[], > > - unsigned int HTotal[], > > - double PixelClock[], > > - unsigned int BlendingAndTiming[], > > unsigned int DPPPerPlane[], > > double BytePerPixelDETY[], > > double BytePerPixelDETC[], > > - double DSTXAfterScaler[], > > - double DSTYAfterScaler[], > > - bool WritebackEnable[], > > - enum source_format_class WritebackPixelFormat[], > > - double WritebackDestinationWidth[], > > - double WritebackDestinationHeight[], > > - double WritebackSourceHeight[], > > bool UnboundedRequestEnabled, > > unsigned int CompressedBufferSizeInkByte, > > enum clock_change_support *DRAMClockChangeSupport, > > - double *UrgentWatermark, > > - double *WritebackUrgentWatermark, > > - double *DRAMClockChangeWatermark, > > - double *WritebackDRAMClockChangeWatermark, > > double *StutterExitWatermark, > > double *StutterEnterPlusExitWatermark, > > double *Z8StutterExitWatermark, > > - double
Re: [PATCH 4/5] drm/damage-helper: Do partial updates if framebuffer has not been changed
On Tue, Sep 20, 2022 at 03:47:39PM +0100, Daniel Stone wrote: > Hi, > > On Tue, 20 Sept 2022 at 15:31, Ville Syrjälä > wrote: > > > On Tue, Sep 20, 2022 at 03:56:18PM +0200, Thomas Zimmermann wrote: > > > Set partial updates on a plane if the framebuffer has not been changed > > > on an atomic commit. If such a plane has damage clips, the driver will > > > use them; otherwise the update is effectively empty. Planes that change > > > their framebuffer still perform a full update. > > > > I have a feeling you're sort of papering over some inefficient > > userspace that's asking updates on planes that don't actually > > need them. I'm not sure adding more code for that is a particularly > > great idea. Wouldn't it be better to just fix the userspace code? > > > > I'm not sure why it would need to be 'fixed', when it's never been a > property of the atomic API that you must minimise updates. Weston does this > (dumps the full state in every time), and I know we're not the only ones. Well, we've never tried to minimize in the kernel either, except for a few special cases that have one of these ad-hoc "foo_changed" flags. And I think those are more due to "I felt like adding one" rather than any real overall design goal. We even have one that is not used at all, except after this patch series (or at least I think I saw it in there). We could of course scan a lot more in the kernel to minimize stuff, but at least I always end up wondering how many joules are being wasted rescanning things when userspace might have already done the same thing. Also at some point it just might be cheaper to blast the hw with the stuff than to meticulously scan through it all. At least as long as we can't to the 100% short circuit. Side rant: I'm also not a huge fan of those current foo_changed flags because their granularity is a bit weird, and dictated by the core code rather than by the driver specific cost of updating each property. Eg. color_mgmt_changed cover all of crtc level color management, but at least for i915 there are both cheap and expensive things in there. So not sure the current flag really helps with anything. We do currently use it in i915, but maybe we should not and just try to look at each property separately instead. > > 'Fixing' it would require doing a bunch of diffing in userspace, because > maintaining a delta and trying to unwind that delta across multiple > TEST_ONLY runs, isn't much fun. It's certainly a far bigger diff than this > patch. OK. If userspace doesn't want to do it at all, then maybe the kernel should do at least a bit of it. I wonder how far we should take that. In the olden pre-atomic days i915 even automagically turned off the primary plane when fully covered by an opaque sprite plane. I presume modern userspace should at least try to use the available planes efficiently and that kind of optimizations would be a waste of time? > > > Any property change on the plane could need a full plane > > update as well (eg. some color mangement stuff etc.). So you'd > > have to keep adding exceptions to that list whenever new > > properties are added. > > > > Eh, it's just a blob ID comparison. Or some other integer, yes, but someone must remember to add it. This patch series certainly seems to have forgotten most of it, so perhaps a slightly shaky start :) OK, sorry bad pun, moving along... If we do this in some common code near the uapi level, then the driver might still have to repeat a bunch of it due to interactions with other stuff. But I already ranted about color_mgmt_changed earlier in the mail, I guess this is more of the same really. What would make this sort of discussion really interesting would be actual power and/or performance figures given some typical fixed workloads. But that sounds like a lot of work... > > > > And I think the semantics of the ioctl(s) has so far been that > > basically any page flip (whether or not it actually changes > > the fb) still ends up doing whatever flushing is needed to > > guarantee the fb contents are up to date on the screen (if > > someone sneaked in some front buffer rendering in between). > > Ie. you could even use basically a nop page flip in place > > of dirtyfb. > > > > Another thing the ioctls have always done is actually perform > > the commit whether anything changed or nor. That is, they > > still do all the same the same vblanky stuff and the commit > > takes the same amount of time. Not sure if your idea is > > to potentially short circuit the entire thing and make it > > take no time at all? > > > > I would expect it to always perform a commit, though. > > Cheers, > Daniel -- Ville Syrjälä Intel
Re: [PATCH v2 2/7] firmware: raspberrypi: Move the clock IDs to the firmware header
Hi Maxime, Am 20.09.22 um 14:50 schrieb Maxime Ripard: We'll need the clock IDs in more drivers than just the clock driver from now on, so let's move them in the firmware header. recently as i reviewed the clk-raspberrypi i noticed this, too. But from my point of view the clock ids should go to include/dt-bindings/clock (like bcm2835.h) because these clock ids are actually referenced in the DTS files and we need to make sure they are in sync. AFAIR this would also result in change from enum to defines. Sorry, i didn't had the time to send a patch for this. Signed-off-by: Maxime Ripard diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c index 876b37b8683c..1f5e6a1554e6 100644 --- a/drivers/clk/bcm/clk-raspberrypi.c +++ b/drivers/clk/bcm/clk-raspberrypi.c @@ -18,24 +18,6 @@ #include -enum rpi_firmware_clk_id { - RPI_FIRMWARE_EMMC_CLK_ID = 1, - RPI_FIRMWARE_UART_CLK_ID, - RPI_FIRMWARE_ARM_CLK_ID, - RPI_FIRMWARE_CORE_CLK_ID, - RPI_FIRMWARE_V3D_CLK_ID, - RPI_FIRMWARE_H264_CLK_ID, - RPI_FIRMWARE_ISP_CLK_ID, - RPI_FIRMWARE_SDRAM_CLK_ID, - RPI_FIRMWARE_PIXEL_CLK_ID, - RPI_FIRMWARE_PWM_CLK_ID, - RPI_FIRMWARE_HEVC_CLK_ID, - RPI_FIRMWARE_EMMC2_CLK_ID, - RPI_FIRMWARE_M2MC_CLK_ID, - RPI_FIRMWARE_PIXEL_BVB_CLK_ID, - RPI_FIRMWARE_NUM_CLK_ID, -}; - static char *rpi_firmware_clk_names[] = { [RPI_FIRMWARE_EMMC_CLK_ID] = "emmc", [RPI_FIRMWARE_UART_CLK_ID] = "uart", diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h index 63426082bcb9..74c7bcc1ac2a 100644 --- a/include/soc/bcm2835/raspberrypi-firmware.h +++ b/include/soc/bcm2835/raspberrypi-firmware.h @@ -136,6 +136,24 @@ enum rpi_firmware_property_tag { RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, }; +enum rpi_firmware_clk_id { + RPI_FIRMWARE_EMMC_CLK_ID = 1, + RPI_FIRMWARE_UART_CLK_ID, + RPI_FIRMWARE_ARM_CLK_ID, + RPI_FIRMWARE_CORE_CLK_ID, + RPI_FIRMWARE_V3D_CLK_ID, + RPI_FIRMWARE_H264_CLK_ID, + RPI_FIRMWARE_ISP_CLK_ID, + RPI_FIRMWARE_SDRAM_CLK_ID, + RPI_FIRMWARE_PIXEL_CLK_ID, + RPI_FIRMWARE_PWM_CLK_ID, + RPI_FIRMWARE_HEVC_CLK_ID, + RPI_FIRMWARE_EMMC2_CLK_ID, + RPI_FIRMWARE_M2MC_CLK_ID, + RPI_FIRMWARE_PIXEL_BVB_CLK_ID, + RPI_FIRMWARE_NUM_CLK_ID, +}; + #if IS_ENABLED(CONFIG_RASPBERRYPI_FIRMWARE) int rpi_firmware_property(struct rpi_firmware *fw, u32 tag, void *data, size_t len);
Re: [BUG] ls1046a: eDMA does not transfer data from I2C
On 9/20/22 11:24 AM, Sean Anderson wrote: > > > On 9/20/22 6:07 AM, Robin Murphy wrote: >> On 2022-09-19 23:24, Sean Anderson wrote: >>> Hi all, >>> >>> I discovered a bug in either imx_i2c or fsl-edma on the LS1046A where no >>> data is read in i2c_imx_dma_read except for the last two bytes (which >>> are not read using DMA). This is perhaps best illustrated with the >>> following example: >>> >>> # hexdump -C /sys/bus/nvmem/devices/0-00540/nvmem >>> [ 308.914884] i2c i2c-0: 00080938 0x00088938 >>> 0xf5401000 75401000 >>> [ 308.923529] src= 2180004 dst=f5401000 attr= 0 soff= 0 nbytes=1 >>> slast= 0 >>> [ 308.923529] citer= 7e biter= 7e doff= 1 dlast_sga= 0 >>> [ 308.923529] major_int=1 disable_req=1 enable_sg=0 >>> [ 308.942113] fsl-edma 2c0.edma: vchan 1b4371fc: txd >>> d9dd26c5[4]: submitted >>> [ 308.974049] fsl-edma 2c0.edma: txd d9dd26c5[4]: marked >>> complete >>> [ 308.981339] i2c i2c-0: 00080938 = [2e 2e 2f 2e 2e 2f 2e 2e 2f 64 >>> 65 76 69 63 65 73 2f 70 6c 61 74 66 6f 72 6d 2f 73 6f 63 2f 32 31 38 30 30 >>> 30 30 2e 69 32 63 2f 69 32 63 2d 30 2f 30 2d 30 30 35 34 2f 30 2d 30 30 35 >>> 34 30 00 00] >>> [ 309.002226] i2c i2c-0: 75401000 = [2e 2e 2f 2e 2e 2f 2e 2e 2f 64 >>> 65 76 69 63 65 73 2f 70 6c 61 74 66 6f 72 6d 2f 73 6f 63 2f 32 31 38 30 30 >>> 30 30 2e 69 32 63 2f 69 32 63 2d 30 2f 30 2d 30 30 35 34 2f 30 2d 30 30 35 >>> 34 30 00 00] >>> [ 309.024649] i2c i2c-0: 000809380080 0x000889380080 >>> 0xf5401800 75401800 >>> [ 309.033270] src= 2180004 dst=f5401800 attr= 0 soff= 0 nbytes=1 >>> slast= 0 >>> [ 309.033270] citer= 7e biter= 7e doff= 1 dlast_sga= 0 >>> [ 309.033270] major_int=1 disable_req=1 enable_sg=0 >>> [ 309.051633] fsl-edma 2c0.edma: vchan 1b4371fc: txd >>> d9dd26c5[5]: submitted >>> [ 309.083526] fsl-edma 2c0.edma: txd d9dd26c5[5]: marked >>> complete >>> [ 309.090807] i2c i2c-0: 000809380080 = [00 00 00 00 00 00 00 00 00 00 >>> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >>> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >>> 00 00 00 00] >>> [ 309.111694] i2c i2c-0: 75401800 = [00 00 00 00 00 00 00 00 00 00 >>> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >>> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >>> 00 00 00 00] >>> 2e 2e 2f 2e 2e 2f 2e 2e 2f 64 65 76 69 63 65 73 >>> |../../../devices| >>> 0010 2f 70 6c 61 74 66 6f 72 6d 2f 73 6f 63 2f 32 31 >>> |/platform/soc/21| >>> 0020 38 30 30 30 30 2e 69 32 63 2f 69 32 63 2d 30 2f >>> |8.i2c/i2c-0/| >>> 0030 30 2d 30 30 35 34 2f 30 2d 30 30 35 34 30 00 00 >>> |0-0054/0-00540..| >>> 0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >>> || >>> * >>> 0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff >>> || >>> 0080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >>> || >>> * >>> 00f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 5b >>> |...[| >>> 0100 >>> >>> (patch with my debug prints appended below) >>> >>> Despite the DMA completing successfully, no data was copied into the >>> buffer, leaving the original (now junk) contents. I probed the I2C bus >>> with an oscilloscope, and I verified that the transfer did indeed occur. >>> The timing between submission and completion seems reasonable for the >>> bus speed (50 kHz for whatever reason). >>> >>> I had a look over the I2C driver, and nothing looked obviously >>> incorrect. If anyone has ideas on what to try, I'm more than willing. >> >> Is the DMA controller cache-coherent? I see the mainline LS1046A DT doesn't >> have a "dma-coherent" property for it, but the behaviour is entirely >> consistent with that being wrong - dma_map_single() cleans the cache, >> coherent DMA write hits the still-present cache lines, dma_unmap_single() >> invalidates the cache, and boom, the data is gone and you read back the >> previous content of the buffer that was cleaned out to DRAM beforehand. > > I've tried both with and without [1] applied. I also tried removing the > call to dma_unmap_single, but to no effect. Actually, I wasn't updating my device tree like I thought... Turns out I2C works only *without* this patch. So maybe the eDMA is not coherent? --Sean > --Sean > > [1] > https://lore.kernel.org/linux-arm-kernel/20220915233432.31660-6-leoyang...@nxp.com/ > >>> --Sean >>> >>> diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c >>> index 15896e2413c4..1d9d4a55d2af 100644 >>> --- a/drivers/dma/fsl-edma-common.c >>> +++ b/drivers/dma/fsl-edma-common.c >>> @@ -391,6 +391,12 @@ void fsl_edma_fill_tcd(struct fsl_edma_hw_tcd *tcd, >>> u32 src, u32 dst, >>> { >>> u16 csr
[PATCH v7 1/5] dt-bindings: display: bridge: Convert cdns, dsi.txt to yaml
Convert cdns,dsi.txt binding to yaml format Signed-off-by: Rahul T R Reviewed-by: Rob Herring --- .../bindings/display/bridge/cdns,dsi.txt | 112 - .../bindings/display/bridge/cdns,dsi.yaml | 157 ++ 2 files changed, 157 insertions(+), 112 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,dsi.txt create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,dsi.yaml diff --git a/Documentation/devicetree/bindings/display/bridge/cdns,dsi.txt b/Documentation/devicetree/bindings/display/bridge/cdns,dsi.txt deleted file mode 100644 index 525a4bfd8634.. --- a/Documentation/devicetree/bindings/display/bridge/cdns,dsi.txt +++ /dev/null @@ -1,112 +0,0 @@ -Cadence DSI bridge -== - -The Cadence DSI bridge is a DPI to DSI bridge supporting up to 4 DSI lanes. - -Required properties: -- compatible: should be set to "cdns,dsi". -- reg: physical base address and length of the controller's registers. -- interrupts: interrupt line connected to the DSI bridge. -- clocks: DSI bridge clocks. -- clock-names: must contain "dsi_p_clk" and "dsi_sys_clk". -- phys: phandle link to the MIPI D-PHY controller. -- phy-names: must contain "dphy". -- #address-cells: must be set to 1. -- #size-cells: must be set to 0. - -Optional properties: -- resets: DSI reset lines. -- reset-names: can contain "dsi_p_rst". - -Required subnodes: -- ports: Ports as described in Documentation/devicetree/bindings/graph.txt. - 2 ports are available: - * port 0: this port is only needed if some of your DSI devices are - controlled through an external bus like I2C or SPI. Can have at - most 4 endpoints. The endpoint number is directly encoding the - DSI virtual channel used by this device. - * port 1: represents the DPI input. - Other ports will be added later to support the new kind of inputs. - -- one subnode per DSI device connected on the DSI bus. Each DSI device should - contain a reg property encoding its virtual channel. - -Example: - dsi0: dsi@fd0c { - compatible = "cdns,dsi"; - reg = <0x0 0xfd0c 0x0 0x1000>; - clocks = <>, <>; - clock-names = "dsi_p_clk", "dsi_sys_clk"; - interrupts = <1>; - phys = <>; - phy-names = "dphy"; - #address-cells = <1>; - #size-cells = <0>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@1 { - reg = <1>; - dsi0_dpi_input: endpoint { - remote-endpoint = <_dpi_output>; - }; - }; - }; - - panel: dsi-dev@0 { - compatible = ""; - reg = <0>; - }; - }; - -or - - dsi0: dsi@fd0c { - compatible = "cdns,dsi"; - reg = <0x0 0xfd0c 0x0 0x1000>; - clocks = <>, <>; - clock-names = "dsi_p_clk", "dsi_sys_clk"; - interrupts = <1>; - phys = <>; - phy-names = "dphy"; - #address-cells = <1>; - #size-cells = <0>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - #address-cells = <1>; - #size-cells = <0>; - - dsi0_output: endpoint@0 { - reg = <0>; - remote-endpoint = <_panel_input>; - }; - }; - - port@1 { - reg = <1>; - dsi0_dpi_input: endpoint { - remote-endpoint = <_dpi_output>; - }; - }; - }; - }; - - i2c@xxx { - panel: panel@59 { - compatible = ""; - reg = <0x59>; - - port { - dsi_panel_input: endpoint { - remote-endpoint = <_output>; - }; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/display/bridge/cdns,dsi.yaml b/Documentation/devicetree/bindings/display/bridge/cdns,dsi.yaml new file mode 100644 index ..3161c33093c1 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/cdns,dsi.yaml @@ -0,0 +1,157 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +---
[PATCH v7 2/5] dt-bindings: display: bridge: cdns, dsi: Add compatible for dsi on j721e
Add compatible to support dsi bridge on j721e Signed-off-by: Rahul T R Reviewed-by: Rob Herring --- .../bindings/display/bridge/cdns,dsi.yaml | 25 ++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/bridge/cdns,dsi.yaml b/Documentation/devicetree/bindings/display/bridge/cdns,dsi.yaml index 3161c33093c1..23060324d16e 100644 --- a/Documentation/devicetree/bindings/display/bridge/cdns,dsi.yaml +++ b/Documentation/devicetree/bindings/display/bridge/cdns,dsi.yaml @@ -16,9 +16,15 @@ properties: compatible: enum: - cdns,dsi + - ti,j721e-dsi reg: -maxItems: 1 +minItems: 1 +items: + - description: + Register block for controller's registers. + - description: + Register block for wrapper settings registers in case of TI J7 SoCs. clocks: items: @@ -67,6 +73,23 @@ properties: allOf: - $ref: ../dsi-controller.yaml# + - if: + properties: +compatible: + contains: +const: ti,j721e-dsi +then: + properties: +reg: + minItems: 2 + maxItems: 2 +power-domains: + maxItems: 1 +else: + properties: +reg: + maxItems: 1 + required: - compatible - reg -- 2.37.3
[PATCH v7 5/5] drm/bridge: cdns-dsi: Add support for J721E wrapper
Add support for wrapper settings for DSI bridge on j721e. Also set the DPI input to DPI0 Signed-off-by: Rahul T R --- drivers/gpu/drm/bridge/cadence/Kconfig| 10 drivers/gpu/drm/bridge/cadence/Makefile | 1 + .../gpu/drm/bridge/cadence/cdns-dsi-core.c| 37 +- .../gpu/drm/bridge/cadence/cdns-dsi-core.h| 13 + .../gpu/drm/bridge/cadence/cdns-dsi-j721e.c | 51 +++ .../gpu/drm/bridge/cadence/cdns-dsi-j721e.h | 18 +++ 6 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-dsi-j721e.c create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-dsi-j721e.h diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig b/drivers/gpu/drm/bridge/cadence/Kconfig index 8fbb46c66094..663a02d96420 100644 --- a/drivers/gpu/drm/bridge/cadence/Kconfig +++ b/drivers/gpu/drm/bridge/cadence/Kconfig @@ -36,3 +36,13 @@ config DRM_CDNS_DSI help Support Cadence DPI to DSI bridge. This is an internal bridge and is meant to be directly embedded in a SoC. + +if DRM_CDNS_DSI + +config DRM_CDNS_DSI_J721E + bool "J721E Cadence DPI/DSI wrapper support" + default y + help + Support J721E Cadence DPI/DSI wrapper. This wrapper adds + support to select which DPI input to use for the bridge. +endif diff --git a/drivers/gpu/drm/bridge/cadence/Makefile b/drivers/gpu/drm/bridge/cadence/Makefile index e3d8e9a40784..4cffc8ff71c4 100644 --- a/drivers/gpu/drm/bridge/cadence/Makefile +++ b/drivers/gpu/drm/bridge/cadence/Makefile @@ -4,3 +4,4 @@ cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o cdns-dsi-y := cdns-dsi-core.o +cdns-dsi-$(CONFIG_DRM_CDNS_DSI_J721E) += cdns-dsi-j721e.o diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index cba91247ab26..4b7de38ef1b0 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -15,12 +15,16 @@ #include #include #include +#include #include #include #include #include #include "cdns-dsi-core.h" +#ifdef CONFIG_DRM_CDNS_DSI_J721E +#include "cdns-dsi-j721e.h" +#endif static inline struct cdns_dsi *input_to_dsi(struct cdns_dsi_input *input) { @@ -265,6 +269,10 @@ static void cdns_dsi_bridge_disable(struct drm_bridge *bridge) val = readl(dsi->regs + MCTL_MAIN_EN) & ~IF_EN(input->id); writel(val, dsi->regs + MCTL_MAIN_EN); + + if (dsi->platform_ops && dsi->platform_ops->disable) + dsi->platform_ops->disable(dsi); + pm_runtime_put(dsi->base.dev); } @@ -360,6 +368,9 @@ static void cdns_dsi_bridge_enable(struct drm_bridge *bridge) if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0)) return; + if (dsi->platform_ops && dsi->platform_ops->enable) + dsi->platform_ops->enable(dsi); + mode = >encoder->crtc->state->adjusted_mode; nlanes = output->dev->lanes; @@ -800,6 +811,8 @@ static int cdns_dsi_drm_probe(struct platform_device *pdev) goto err_disable_pclk; } + dsi->platform_ops = of_device_get_match_data(>dev); + val = readl(dsi->regs + IP_CONF); dsi->direct_cmd_fifo_depth = 1 << (DIRCMD_FIFO_DEPTH(val) + 2); dsi->rx_fifo_depth = RX_FIFO_DEPTH(val); @@ -835,14 +848,27 @@ static int cdns_dsi_drm_probe(struct platform_device *pdev) dsi->base.dev = >dev; dsi->base.ops = _dsi_ops; + if (dsi->platform_ops && dsi->platform_ops->init) { + ret = dsi->platform_ops->init(dsi); + if (ret != 0) { + dev_err(>dev, "platform initialization failed: %d\n", + ret); + goto err_disable_runtime_pm; + } + } + ret = mipi_dsi_host_register(>base); if (ret) - goto err_disable_runtime_pm; + goto err_deinit_platform; clk_disable_unprepare(dsi->dsi_p_clk); return 0; +err_deinit_platform: + if (dsi->platform_ops && dsi->platform_ops->exit) + dsi->platform_ops->exit(dsi); + err_disable_runtime_pm: pm_runtime_disable(>dev); @@ -857,6 +883,10 @@ static int cdns_dsi_drm_remove(struct platform_device *pdev) struct cdns_dsi *dsi = platform_get_drvdata(pdev); mipi_dsi_host_unregister(>base); + + if (dsi->platform_ops && dsi->platform_ops->exit) + dsi->platform_ops->exit(dsi); + pm_runtime_disable(>dev); return 0; @@ -864,6 +894,11 @@ static int cdns_dsi_drm_remove(struct platform_device *pdev) static const struct of_device_id cdns_dsi_of_match[] = { { .compatible = "cdns,dsi" }, +#ifdef CONFIG_DRM_CDNS_DSI_J721E + { .compatible =
[PATCH v7 0/5] Add support for CDNS DSI J721E wrapper
Following series of patches adds supports for CDNS DSI bridge on j721e. v7: - Rebased to next-20220920 - Accumulated the Reviewed-by acks v6: - Dropped generic definations for properties like reg, resets etc.. - Fixed the defination for port@0 and port@1 - removed the ti,sn65dsi86 node from the example, which is not related v5: - Remove power-domain property in the conversion commit - Add power-domain only for j721e compatible - Fix white space error in one of the commit v4: - split conversion txt to yaml - seperate commit for addinig new compatible - conditionally limit the items for reg property, based on the compatible v3: - Convert cdns-dsi.txt binding to yaml - Move the bridge under display/bridge/cadence - Add new compatible to enable the wrapper module v2: - Moved setting DPI0 to bridge_enable, since it should be done after pm_runtime_get Rahul T R (5): dt-bindings: display: bridge: Convert cdns,dsi.txt to yaml dt-bindings: display: bridge: cdns,dsi: Add compatible for dsi on j721e drm/bridge: cdns-dsi: Move to drm/bridge/cadence drm/bridge: cdns-dsi: Create a header file drm/bridge: cdns-dsi: Add support for J721E wrapper .../bindings/display/bridge/cdns,dsi.txt | 112 .../bindings/display/bridge/cdns,dsi.yaml | 180 +++ drivers/gpu/drm/bridge/Kconfig| 11 - drivers/gpu/drm/bridge/Makefile | 1 - drivers/gpu/drm/bridge/cadence/Kconfig| 21 + drivers/gpu/drm/bridge/cadence/Makefile | 3 + .../{cdns-dsi.c => cadence/cdns-dsi-core.c} | 483 ++ .../gpu/drm/bridge/cadence/cdns-dsi-core.h| 471 + .../gpu/drm/bridge/cadence/cdns-dsi-j721e.c | 51 ++ .../gpu/drm/bridge/cadence/cdns-dsi-j721e.h | 18 + 10 files changed, 781 insertions(+), 570 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,dsi.txt create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,dsi.yaml rename drivers/gpu/drm/bridge/{cdns-dsi.c => cadence/cdns-dsi-core.c} (65%) create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-dsi-j721e.c create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-dsi-j721e.h -- 2.37.3
Re: [PATCH v3 1/6] dt-bindings: arm: mediatek: mmsys: change compatible for MT8195
On 20/09/2022 16:01, Jason-JH.Lin wrote: > For previous MediaTek SoCs, such as MT8173, there are 2 display HW > pipelines binding to 1 mmsys with the same power domain, the same > clock driver and the same mediatek-drm driver. > > For MT8195, VDOSYS0 and VDOSYS1 are 2 display HW pipelines binding to > 2 different power domains, different clock drivers and different > mediatek-drm drivers. > > Moreover, Hardware pipeline of VDOSYS0 has these components: COLOR, > CCORR, AAL, GAMMA, DITHER. They are related to the PQ (Picture Quality) > and they makes VDOSYS0 supports PQ function while they are not > including in VDOSYS1. > > Hardware pipeline of VDOSYS1 has the component ETHDR (HDR related > component). It makes VDOSYS1 supports the HDR function while it's not > including in VDOSYS0. > > To summarize0: > Only VDOSYS0 can support PQ adjustment. > Only VDOSYS1 can support HDR adjustment. > > Therefore, we need to separate these two different mmsys hardwares to > 2 different compatibles for MT8195. > > Fixes: 81c5a41d10b9 ("dt-bindings: arm: mediatek: mmsys: add mt8195 SoC > binding") > Signed-off-by: Jason-JH.Lin > Signed-off-by: Bo-Chen Chen > --- > .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml | 4 > 1 file changed, 4 insertions(+) > > diff --git > a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml > b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml > index 6ad023eec193..df9184b6772c 100644 > --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml > +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml > @@ -38,6 +38,10 @@ properties: >- const: mediatek,mt7623-mmsys >- const: mediatek,mt2701-mmsys >- const: syscon > + - items: > + - const: mediatek,mt8195-vdosys0 > + - const: mediatek,mt8195-mmsys > + - const: syscon and why mediatek,mt8195-mmsys is kept as non-deprecated? Best regards, Krzysztof
Re: [BUG] ls1046a: eDMA does not transfer data from I2C
On 9/20/22 6:07 AM, Robin Murphy wrote: > On 2022-09-19 23:24, Sean Anderson wrote: >> Hi all, >> >> I discovered a bug in either imx_i2c or fsl-edma on the LS1046A where no >> data is read in i2c_imx_dma_read except for the last two bytes (which >> are not read using DMA). This is perhaps best illustrated with the >> following example: >> >> # hexdump -C /sys/bus/nvmem/devices/0-00540/nvmem >> [ 308.914884] i2c i2c-0: 00080938 0x00088938 >> 0xf5401000 75401000 >> [ 308.923529] src= 2180004 dst=f5401000 attr= 0 soff= 0 nbytes=1 slast= >> 0 >> [ 308.923529] citer= 7e biter= 7e doff= 1 dlast_sga= 0 >> [ 308.923529] major_int=1 disable_req=1 enable_sg=0 >> [ 308.942113] fsl-edma 2c0.edma: vchan 1b4371fc: txd >> d9dd26c5[4]: submitted >> [ 308.974049] fsl-edma 2c0.edma: txd d9dd26c5[4]: marked >> complete >> [ 308.981339] i2c i2c-0: 00080938 = [2e 2e 2f 2e 2e 2f 2e 2e 2f 64 >> 65 76 69 63 65 73 2f 70 6c 61 74 66 6f 72 6d 2f 73 6f 63 2f 32 31 38 30 30 >> 30 30 2e 69 32 63 2f 69 32 63 2d 30 2f 30 2d 30 30 35 34 2f 30 2d 30 30 35 >> 34 30 00 00] >> [ 309.002226] i2c i2c-0: 75401000 = [2e 2e 2f 2e 2e 2f 2e 2e 2f 64 >> 65 76 69 63 65 73 2f 70 6c 61 74 66 6f 72 6d 2f 73 6f 63 2f 32 31 38 30 30 >> 30 30 2e 69 32 63 2f 69 32 63 2d 30 2f 30 2d 30 30 35 34 2f 30 2d 30 30 35 >> 34 30 00 00] >> [ 309.024649] i2c i2c-0: 000809380080 0x000889380080 >> 0xf5401800 75401800 >> [ 309.033270] src= 2180004 dst=f5401800 attr= 0 soff= 0 nbytes=1 slast= >> 0 >> [ 309.033270] citer= 7e biter= 7e doff= 1 dlast_sga= 0 >> [ 309.033270] major_int=1 disable_req=1 enable_sg=0 >> [ 309.051633] fsl-edma 2c0.edma: vchan 1b4371fc: txd >> d9dd26c5[5]: submitted >> [ 309.083526] fsl-edma 2c0.edma: txd d9dd26c5[5]: marked >> complete >> [ 309.090807] i2c i2c-0: 000809380080 = [00 00 00 00 00 00 00 00 00 00 >> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >> 00 00 00 00] >> [ 309.111694] i2c i2c-0: 75401800 = [00 00 00 00 00 00 00 00 00 00 >> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >> 00 00 00 00] >> 2e 2e 2f 2e 2e 2f 2e 2e 2f 64 65 76 69 63 65 73 >> |../../../devices| >> 0010 2f 70 6c 61 74 66 6f 72 6d 2f 73 6f 63 2f 32 31 >> |/platform/soc/21| >> 0020 38 30 30 30 30 2e 69 32 63 2f 69 32 63 2d 30 2f >> |8.i2c/i2c-0/| >> 0030 30 2d 30 30 35 34 2f 30 2d 30 30 35 34 30 00 00 >> |0-0054/0-00540..| >> 0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >> || >> * >> 0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff >> || >> 0080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >> || >> * >> 00f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 5b >> |...[| >> 0100 >> >> (patch with my debug prints appended below) >> >> Despite the DMA completing successfully, no data was copied into the >> buffer, leaving the original (now junk) contents. I probed the I2C bus >> with an oscilloscope, and I verified that the transfer did indeed occur. >> The timing between submission and completion seems reasonable for the >> bus speed (50 kHz for whatever reason). >> >> I had a look over the I2C driver, and nothing looked obviously >> incorrect. If anyone has ideas on what to try, I'm more than willing. > > Is the DMA controller cache-coherent? I see the mainline LS1046A DT doesn't > have a "dma-coherent" property for it, but the behaviour is entirely > consistent with that being wrong - dma_map_single() cleans the cache, > coherent DMA write hits the still-present cache lines, dma_unmap_single() > invalidates the cache, and boom, the data is gone and you read back the > previous content of the buffer that was cleaned out to DRAM beforehand. I've tried both with and without [1] applied. I also tried removing the call to dma_unmap_single, but to no effect. --Sean [1] https://lore.kernel.org/linux-arm-kernel/20220915233432.31660-6-leoyang...@nxp.com/ >> --Sean >> >> diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c >> index 15896e2413c4..1d9d4a55d2af 100644 >> --- a/drivers/dma/fsl-edma-common.c >> +++ b/drivers/dma/fsl-edma-common.c >> @@ -391,6 +391,12 @@ void fsl_edma_fill_tcd(struct fsl_edma_hw_tcd *tcd, u32 >> src, u32 dst, >> { >> u16 csr = 0; >> + pr_info("src=%8x dst=%8x attr=%4x soff=%4x nbytes=%u slast=%8x\n" >> + "citer=%4x biter=%4x doff=%4x dlast_sga=%8x\n" >> + "major_int=%d disable_req=%d enable_sg=%d\n", >> + src, dst, attr, soff, nbytes, slast, citer, biter, doff, >> +
[PATCH V2 1/3] dt-bindings: vendor-prefixes: add NewVision vendor prefix
From: Chris Morgan NewVision (also sometimes written as New Vision) is a company based in Shenzen that manufactures ICs for controlling LCD panels. https://www.newvisiondisplay.com/ Signed-off-by: Chris Morgan --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 2f0151e9f6be..d9c38e214863 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -873,6 +873,8 @@ patternProperties: description: Shenzhen Netxeon Technology CO., LTD "^neweast,.*": description: Guangdong Neweast Optoelectronics CO., LTD + "^newvision,.*": +description: New Vision Display (Shenzhen) Co., Ltd. "^nexbox,.*": description: Nexbox "^nextthing,.*": -- 2.25.1
[PATCH V2 3/3] drm/panel: Add NewVision NV3051D MIPI-DSI LCD panel
From: Chris Morgan Add NewVision NV3051D MIPI-DSI LCD panel Support NewVision NV3051D panels as found on the Anbernic RG353P and RG353V. The underlying LCD part number for the RG353x devices is unknown, so the device name and a fallback for the driver IC is used instead. Signed-off-by: Chris Morgan --- drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile| 1 + .../gpu/drm/panel/panel-newvision-nv3051d.c | 513 ++ 3 files changed, 523 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-newvision-nv3051d.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index a9043eacce97..7258d28dda2f 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -296,6 +296,15 @@ config DRM_PANEL_NEC_NL8048HL11 panel (found on the Zoom2/3/3630 SDP boards). To compile this driver as a module, choose M here. +config DRM_PANEL_NEWVISION_NV3051D + tristate "NewVision NV3051D DSI panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + This driver supports the NV3051D based panel found on the Anbernic + RG353P and RG353V. + config DRM_PANEL_NEWVISION_NV3052C tristate "NewVision NV3052C RGB/SPI panel" depends on OF && SPI diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 34e717382dbb..cb03b3a82738 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += panel-leadtek-ltk500hd1829.o obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o +obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3051D) += panel-newvision-nv3051d.o obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3052C) += panel-newvision-nv3052c.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35510) += panel-novatek-nt35510.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35560) += panel-novatek-nt35560.o diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3051d.c b/drivers/gpu/drm/panel/panel-newvision-nv3051d.c new file mode 100644 index ..be57b3579bd5 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-newvision-nv3051d.c @@ -0,0 +1,513 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * NV3051D MIPI-DSI panel driver for Anbernic RG353x + * Copyright (C) 2022 Chris Morgan + * + * based on + * + * Elida kd35t133 3.5" MIPI-DSI panel driver + * Copyright (C) Theobroma Systems 2020 + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +struct nv3051d_panel_info { + const struct drm_display_mode *display_modes; + unsigned int num_modes; + u16 width_mm, height_mm; + u32 bus_flags; +}; + +struct panel_nv3051d { + struct device *dev; + struct drm_panel panel; + struct gpio_desc *reset_gpio; + const struct nv3051d_panel_info *panel_info; + struct regulator *vdd; + bool prepared; +}; + +static inline struct panel_nv3051d *panel_to_panelnv3051d(struct drm_panel *panel) +{ + return container_of(panel, struct panel_nv3051d, panel); +} + +#define dsi_dcs_write_seq(dsi, cmd, seq...) do { \ + static const u8 b[] = { cmd, seq }; \ + int ret;\ + ret = mipi_dsi_dcs_write_buffer(dsi, b, ARRAY_SIZE(b)); \ + if (ret < 0)\ + return ret; \ + } while (0) + +static int panel_nv3051d_init_sequence(struct panel_nv3051d *ctx) +{ + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); + + /* +* Init sequence was supplied by device vendor with no +* documentation. +*/ + + dsi_dcs_write_seq(dsi, 0xFF, 0x30); + dsi_dcs_write_seq(dsi, 0xFF, 0x52); + dsi_dcs_write_seq(dsi, 0xFF, 0x01); + dsi_dcs_write_seq(dsi, 0xE3, 0x00); + dsi_dcs_write_seq(dsi, 0x03, 0x40); + dsi_dcs_write_seq(dsi, 0x04, 0x00); + dsi_dcs_write_seq(dsi, 0x05, 0x03); + dsi_dcs_write_seq(dsi, 0x24, 0x12); + dsi_dcs_write_seq(dsi, 0x25, 0x1E); + dsi_dcs_write_seq(dsi, 0x26, 0x28); + dsi_dcs_write_seq(dsi, 0x27, 0x52); + dsi_dcs_write_seq(dsi, 0x28, 0x57); + dsi_dcs_write_seq(dsi, 0x29, 0x01); + dsi_dcs_write_seq(dsi, 0x2A, 0xDF); + dsi_dcs_write_seq(dsi, 0x38, 0x9C); + dsi_dcs_write_seq(dsi, 0x39, 0xA7); + dsi_dcs_write_seq(dsi, 0x3A, 0x53); + dsi_dcs_write_seq(dsi, 0x44, 0x00); + dsi_dcs_write_seq(dsi, 0x49, 0x3C); + dsi_dcs_write_seq(dsi, 0x59, 0xFE); + dsi_dcs_write_seq(dsi, 0x5C, 0x00); + dsi_dcs_write_seq(dsi, 0x91,
[PATCH V2 2/3] dt-bindings: display: panel: Add NewVision NV3051D bindings
From: Chris Morgan Add documentation for the NewVision NV3051D panel bindings. Note that for the two expected consumers of this panel binding the underlying LCD model is unknown. Name "anbernic,rg353p-panel" is used because the hardware itself is known as "anbernic,rg353p". Signed-off-by: Chris Morgan --- .../display/panel/newvision,nv3051d.yaml | 55 +++ 1 file changed, 55 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/newvision,nv3051d.yaml diff --git a/Documentation/devicetree/bindings/display/panel/newvision,nv3051d.yaml b/Documentation/devicetree/bindings/display/panel/newvision,nv3051d.yaml new file mode 100644 index ..d90bca4171c2 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/newvision,nv3051d.yaml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/newvision,nv3051d.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NewVision NV3051D based LCD panel + +description: | + The NewVision NV3051D is a driver chip used to drive DSI panels. For now, + this driver only supports the 640x480 panels found in the Anbernic RG353 + based devices. + +maintainers: + - Chris Morgan + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: +items: + - enum: + - anbernic,rg353p-panel + - anbernic,rg353v-panel + - const: newvision,nv3051d + reg: true + backlight: true + port: true + reset-gpios: true + vdd-supply: +description: regulator that supplies the vdd voltage + +required: + - compatible + - reg + - backlight + - vdd-supply + +additionalProperties: false + +examples: + - | +dsi { +#address-cells = <1>; +#size-cells = <0>; +panel@0 { +compatible = "anbernic,rg353p-panel"; +reg = <0>; +backlight = <>; +vdd-supply = <_lcd>; +}; +}; + +... -- 2.25.1
[PATCH V2 0/3] drm/panel: Add NewVision NV3051D Panels
From: Chris Morgan Add the NewVision NV3051D panel as found on the Anbernic RG353P and RG353V. The underlying LCD panel itself is unknown (the NV3051D is the controller), so the device name is used for the panel with a fallback to the driver IC. Changes from V1: - Changed compatible string to the driver IC. - Updated documentation to use new compatible string with board name. - Refactored somewhat to make it easier to support other LCD panels with this kernel module. - Added support for 60hz mode. Adjusted pixel clock to ensure proper 60hz and 120hz (previously was running at 124hz). - Added vendor prefix for NewVision. Anbernic vendor prefix added in https://lore.kernel.org/linux-devicetree/20220906210324.28986-2-macroalph...@gmail.com Chris Morgan (3): dt-bindings: vendor-prefixes: add NewVision vendor prefix dt-bindings: display: panel: Add NewVision NV3051D bindings drm/panel: Add NewVision NV3051D MIPI-DSI LCD panel .../display/panel/newvision,nv3051d.yaml | 55 ++ .../devicetree/bindings/vendor-prefixes.yaml | 2 + drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile| 1 + .../gpu/drm/panel/panel-newvision-nv3051d.c | 513 ++ 5 files changed, 580 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/newvision,nv3051d.yaml create mode 100644 drivers/gpu/drm/panel/panel-newvision-nv3051d.c -- 2.25.1
Re: [PATCH] drm/panfrost: Give name to anonymous coredump object union
On Tue, Sep 20, 2022 at 02:26:52PM +0100, Steven Price wrote: > On 19/09/2022 07:44, Adri??n Larumbe wrote: > > Hi Steven, > > > > On 13.09.2022 09:45, Steven Price wrote: > >> On 12/09/2022 17:44, Adri??n Larumbe wrote: > >>> Building Mesa's Perfetto requires including the panfrost drm uAPI header > >>> in > >>> C++ code, but the C++ compiler requires anonymous unions to have only > >>> public non-static data members. > >>> > >>> Commit 730c2bf4ad39 ("drm/panfrost: Add support for devcoredump") > >>> introduces one such union, breaking the Mesa build. > >>> > >>> Give it a name, and also rename pan_reg_hdr structure because it will > >>> always be prefixed by the union name. > >>> > >>> Bug: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7195 > >>> > >>> Signed-off-by: Adri??n Larumbe > > > >> Ouch! It's frustrating how C++ isn't quite a superset of C. However I > >> think we can solve this with a simpler patch, I'd appreciate testing > >> that this does indeed fix the build issues with Mesa with all supported > >> compilers (I'm not so familiar with C++): > > > > I just tested your changes on Mesa and they do fix the build. > > Thanks Adri??n! > > Alyssa: Could you give your R-b if you're happy with this change? It > would be good to get this fixed before it hits -rc1. R-b, however the issue isn't totally gone: in a separate but related issue, apparently the __le types aren't portable and the devcoredump support has now broken the panfrost (mesa) build for FreeBSD, which has a UAPI-compatible reimplementation of panfrost.ko ... Do we maybe want to change all the __le to u at the same time? If we have to break UAPI, better do it before the UAPI is actually merged. Panfrost is probably broken in far worse ways on big endian anyway. Or maybe we want to keep doing little-endian but in u32 containers and have conversions in the kernel for big-endian CPUs. Or maybe we want to just "we don't care about big endian, because you'll have worse problems", at a GPU level Mali hasn't supported big endian since Midgard so I doubt the recent DDKs would work on BE either. Anyway, ideally we'd solve both at once, and soon, so we don't have to revert the devcoredump stuff from mesa. Thanks, Alyssa
Re: [PATCH 4/5] drm/damage-helper: Do partial updates if framebuffer has not been changed
Hi, On Tue, 20 Sept 2022 at 15:31, Ville Syrjälä wrote: > On Tue, Sep 20, 2022 at 03:56:18PM +0200, Thomas Zimmermann wrote: > > Set partial updates on a plane if the framebuffer has not been changed > > on an atomic commit. If such a plane has damage clips, the driver will > > use them; otherwise the update is effectively empty. Planes that change > > their framebuffer still perform a full update. > > I have a feeling you're sort of papering over some inefficient > userspace that's asking updates on planes that don't actually > need them. I'm not sure adding more code for that is a particularly > great idea. Wouldn't it be better to just fix the userspace code? > I'm not sure why it would need to be 'fixed', when it's never been a property of the atomic API that you must minimise updates. Weston does this (dumps the full state in every time), and I know we're not the only ones. 'Fixing' it would require doing a bunch of diffing in userspace, because maintaining a delta and trying to unwind that delta across multiple TEST_ONLY runs, isn't much fun. It's certainly a far bigger diff than this patch. > Any property change on the plane could need a full plane > update as well (eg. some color mangement stuff etc.). So you'd > have to keep adding exceptions to that list whenever new > properties are added. > Eh, it's just a blob ID comparison. > And I think the semantics of the ioctl(s) has so far been that > basically any page flip (whether or not it actually changes > the fb) still ends up doing whatever flushing is needed to > guarantee the fb contents are up to date on the screen (if > someone sneaked in some front buffer rendering in between). > Ie. you could even use basically a nop page flip in place > of dirtyfb. > > Another thing the ioctls have always done is actually perform > the commit whether anything changed or nor. That is, they > still do all the same the same vblanky stuff and the commit > takes the same amount of time. Not sure if your idea is > to potentially short circuit the entire thing and make it > take no time at all? > I would expect it to always perform a commit, though. Cheers, Daniel
Re: [PATCH 4/5] drm/damage-helper: Do partial updates if framebuffer has not been changed
On Tue, Sep 20, 2022 at 03:56:18PM +0200, Thomas Zimmermann wrote: > Set partial updates on a plane if the framebuffer has not been changed > on an atomic commit. If such a plane has damage clips, the driver will > use them; otherwise the update is effectively empty. Planes that change > their framebuffer still perform a full update. I have a feeling you're sort of papering over some inefficient userspace that's asking updates on planes that don't actually need them. I'm not sure adding more code for that is a particularly great idea. Wouldn't it be better to just fix the userspace code? Any property change on the plane could need a full plane update as well (eg. some color mangement stuff etc.). So you'd have to keep adding exceptions to that list whenever new properties are added. And I think the semantics of the ioctl(s) has so far been that basically any page flip (whether or not it actually changes the fb) still ends up doing whatever flushing is needed to guarantee the fb contents are up to date on the screen (if someone sneaked in some front buffer rendering in between). Ie. you could even use basically a nop page flip in place of dirtyfb. Another thing the ioctls have always done is actually perform the commit whether anything changed or nor. That is, they still do all the same the same vblanky stuff and the commit takes the same amount of time. Not sure if your idea is to potentially short circuit the entire thing and make it take no time at all? -- Ville Syrjälä Intel
Re: [PATCH v5 00/21] Move all drivers to a common dma-buf locking convention
Hi Dmitry, On Wed, 14 Sept 2022 at 00:58, Dmitry Osipenko wrote: > > Hello, > > This series moves all drivers to a dynamic dma-buf locking specification. > From now on all dma-buf importers are made responsible for holding > dma-buf's reservation lock around all operations performed over dma-bufs > in accordance to the locking specification. This allows us to utilize > reservation lock more broadly around kernel without fearing of a potential > deadlocks. Thank you for the excellent work on this series - apart from a minor nit in patch 15, please feel free to add my: Acked-by: Sumit Semwal for the relevant dma-buf patches (1, 2, 15-19, 21). Best regards, Sumit. > > This patchset passes all i915 selftests. It was also tested using VirtIO, > Panfrost, Lima, Tegra, udmabuf, AMDGPU and Nouveau drivers. I tested cases > of display+GPU, display+V4L and GPU+V4L dma-buf sharing (where appropriate), > which covers majority of kernel drivers since rest of the drivers share > same or similar code paths. > > Changelog: > > v5: - Added acks and r-bs that were given to v4. > > - Changed i915 preparation patch like was suggested by Michael Ruhl. > The scope of reservation locking is smaller now. > > v4: - Added dma_buf_mmap() to the "locking convention" documentation, > which was missed by accident in v3. > > - Added acks from Christian König, Tomasz Figa and Hans Verkuil that > they gave to couple v3 patches. > > - Dropped the "_unlocked" postfix from function names that don't have > the locked variant, as was requested by Christian König. > > - Factored out the per-driver preparations into separate patches > to ease reviewing of the changes, which is now doable without the > global dma-buf functions renaming. > > - Factored out the dynamic locking convention enforcements into separate > patches which add the final dma_resv_assert_held(dmabuf->resv) to the > dma-buf API functions. > > v3: - Factored out dma_buf_mmap_unlocked() and attachment functions > into aseparate patches, like was suggested by Christian König. > > - Corrected and factored out dma-buf locking documentation into > a separate patch, like was suggested by Christian König. > > - Intel driver dropped the reservation locking fews days ago from > its BO-release code path, but we need that locking for the imported > GEMs because in the end that code path unmaps the imported GEM. > So I added back the locking needed by the imported GEMs, updating > the "dma-buf attachment locking specification" patch appropriately. > > - Tested Nouveau+Intel dma-buf import/export combo. > > - Tested udmabuf import to i915/Nouveau/AMDGPU. > > - Fixed few places in Etnaviv, Panfrost and Lima drivers that I missed > to switch to locked dma-buf vmapping in the drm/gem: Take reservation > lock for vmap/vunmap operations" patch. In a result invalidated the > Christian's r-b that he gave to v2. > > - Added locked dma-buf vmap/vunmap functions that are needed for fixing > vmappping of Etnaviv, Panfrost and Lima drivers mentioned above. > I actually had this change stashed for the drm-shmem shrinker patchset, > but then realized that it's already needed by the dma-buf patches. > Also improved my tests to better cover these code paths. > > v2: - Changed locking specification to avoid problems with a cross-driver > ww locking, like was suggested by Christian König. Now the attach/detach > callbacks are invoked without the held lock and exporter should take the > lock. > > - Added "locking convention" documentation that explains which dma-buf > functions and callbacks are locked/unlocked for importers and exporters, > which was requested by Christian König. > > - Added ack from Tomasz Figa to the V4L patches that he gave to v1. > > Dmitry Osipenko (21): > dma-buf: Add unlocked variant of vmapping functions > dma-buf: Add unlocked variant of attachment-mapping functions > drm/gem: Take reservation lock for vmap/vunmap operations > drm/prime: Prepare to dynamic dma-buf locking specification > drm/armada: Prepare to dynamic dma-buf locking specification > drm/i915: Prepare to dynamic dma-buf locking specification > drm/omapdrm: Prepare to dynamic dma-buf locking specification > drm/tegra: Prepare to dynamic dma-buf locking specification > drm/etnaviv: Prepare to dynamic dma-buf locking specification > RDMA/umem: Prepare to dynamic dma-buf locking specification > misc: fastrpc: Prepare to dynamic dma-buf locking specification > xen/gntdev: Prepare to dynamic dma-buf locking specification > media: videobuf2: Prepare to dynamic dma-buf locking specification > media: tegra-vde: Prepare to dynamic dma-buf locking specification > dma-buf: Move dma_buf_vmap() to dynamic locking specification > dma-buf: Move dma_buf_attach() to dynamic locking
Re: [PATCH v5 15/21] dma-buf: Move dma_buf_vmap() to dynamic locking specification
Hi Dmitry, Thanks very much for the series. On Wed, 14 Sept 2022 at 00:59, Dmitry Osipenko wrote: > > Move dma_buf_vmap/vunmap_unlocked() functions to the dynamic locking > specification by asserting that the reservation lock is held. Thanks for the patch; just a minor nit - I think you mean dma_buf_vmap / vunmap() here, and not _unlocked? Best, Sumit. > > Acked-by: Christian König > Signed-off-by: Dmitry Osipenko > --- > drivers/dma-buf/dma-buf.c | 4 > 1 file changed, 4 insertions(+) > > diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c > index 50db7571dc4b..80fd6ccc88c6 100644 > --- a/drivers/dma-buf/dma-buf.c > +++ b/drivers/dma-buf/dma-buf.c > @@ -1450,6 +1450,8 @@ int dma_buf_vmap(struct dma_buf *dmabuf, struct > iosys_map *map) > if (WARN_ON(!dmabuf)) > return -EINVAL; > > + dma_resv_assert_held(dmabuf->resv); > + > if (!dmabuf->ops->vmap) > return -EINVAL; > > @@ -1510,6 +1512,8 @@ void dma_buf_vunmap(struct dma_buf *dmabuf, struct > iosys_map *map) > if (WARN_ON(!dmabuf)) > return; > > + dma_resv_assert_held(dmabuf->resv); > + > BUG_ON(iosys_map_is_null(>vmap_ptr)); > BUG_ON(dmabuf->vmapping_counter == 0); > BUG_ON(!iosys_map_is_equal(>vmap_ptr, map)); > -- > 2.37.3 > -- Thanks and regards, Sumit Semwal (he / him) Tech Lead - LCG, Vertical Technologies Linaro.org │ Open source software for ARM SoCs
[PATCH v3 4/6] Revert "drm/mediatek: Add mediatek-drm of vdosys0 support for mt8195"
This reverts commit 7266e90a51a32722a94daa3cb5b8fa278059e49e. Due to the compatible changing of mt8195 from "mediatek,mt8195-mmsys" to "mediatek,mt8195-vdosys0", we have to revert this patch and send a new patch with the new compatible. Signed-off-by: Jason-JH.Lin --- drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 8 +- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 150 ++- drivers/gpu/drm/mediatek/mtk_drm_drv.h | 6 - 3 files changed, 14 insertions(+), 150 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c index 0ec2e4049e07..2cb90466798c 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c @@ -370,8 +370,8 @@ static const struct mtk_disp_rdma_data mt8183_rdma_driver_data = { .fifo_size = 5 * SZ_1K, }; -static const struct mtk_disp_rdma_data mt8195_rdma_driver_data = { - .fifo_size = 1920, +static const struct mtk_disp_rdma_data mt8192_rdma_driver_data = { + .fifo_size = 5 * SZ_1K, }; static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = { @@ -381,8 +381,8 @@ static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = { .data = _rdma_driver_data}, { .compatible = "mediatek,mt8183-disp-rdma", .data = _rdma_driver_data}, - { .compatible = "mediatek,mt8195-disp-rdma", - .data = _rdma_driver_data}, + { .compatible = "mediatek,mt8192-disp-rdma", + .data = _rdma_driver_data}, {}, }; MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match); diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 5f02f8d0e4fc..adc9a4f4085b 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -4,8 +4,6 @@ * Author: YT SHEN */ -#include -#include #include #include #include @@ -197,19 +195,6 @@ static const enum mtk_ddp_comp_id mt8192_mtk_ddp_ext[] = { DDP_COMPONENT_DPI0, }; -static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = { - DDP_COMPONENT_OVL0, - DDP_COMPONENT_RDMA0, - DDP_COMPONENT_COLOR0, - DDP_COMPONENT_CCORR, - DDP_COMPONENT_AAL0, - DDP_COMPONENT_GAMMA, - DDP_COMPONENT_DITHER0, - DDP_COMPONENT_DSC0, - DDP_COMPONENT_MERGE0, - DDP_COMPONENT_DP_INTF0, -}; - static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = { .main_path = mt2701_mtk_ddp_main, .main_len = ARRAY_SIZE(mt2701_mtk_ddp_main), @@ -218,13 +203,6 @@ static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = { .shadow_register = true, }; -static const struct mtk_mmsys_match_data mt2701_mmsys_match_data = { - .num_drv_data = 1, - .drv_data = { - _mmsys_driver_data, - }, -}; - static const struct mtk_mmsys_driver_data mt7623_mmsys_driver_data = { .main_path = mt7623_mtk_ddp_main, .main_len = ARRAY_SIZE(mt7623_mtk_ddp_main), @@ -233,13 +211,6 @@ static const struct mtk_mmsys_driver_data mt7623_mmsys_driver_data = { .shadow_register = true, }; -static const struct mtk_mmsys_match_data mt7623_mmsys_match_data = { - .num_drv_data = 1, - .drv_data = { - _mmsys_driver_data, - }, -}; - static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = { .main_path = mt2712_mtk_ddp_main, .main_len = ARRAY_SIZE(mt2712_mtk_ddp_main), @@ -249,25 +220,11 @@ static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = { .third_len = ARRAY_SIZE(mt2712_mtk_ddp_third), }; -static const struct mtk_mmsys_match_data mt2712_mmsys_match_data = { - .num_drv_data = 1, - .drv_data = { - _mmsys_driver_data, - }, -}; - static const struct mtk_mmsys_driver_data mt8167_mmsys_driver_data = { .main_path = mt8167_mtk_ddp_main, .main_len = ARRAY_SIZE(mt8167_mtk_ddp_main), }; -static const struct mtk_mmsys_match_data mt8167_mmsys_match_data = { - .num_drv_data = 1, - .drv_data = { - _mmsys_driver_data, - }, -}; - static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = { .main_path = mt8173_mtk_ddp_main, .main_len = ARRAY_SIZE(mt8173_mtk_ddp_main), @@ -275,13 +232,6 @@ static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = { .ext_len = ARRAY_SIZE(mt8173_mtk_ddp_ext), }; -static const struct mtk_mmsys_match_data mt8173_mmsys_match_data = { - .num_drv_data = 1, - .drv_data = { - _mmsys_driver_data, - }, -}; - static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = { .main_path = mt8183_mtk_ddp_main, .main_len = ARRAY_SIZE(mt8183_mtk_ddp_main), @@ -289,13 +239,6 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = { .ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext), }; -static
[PATCH v3 3/6] soc: mediatek: add mtk-mmsys support for mt8195 vdosys0
1. Add mt8195 driver data with compatible "mediatek-mt8195-vdosys0". 2. Add mt8195 routing table settings of vdosys0. Signed-off-by: Jason-JH.Lin --- drivers/soc/mediatek/mt8195-mmsys.h | 370 drivers/soc/mediatek/mtk-mmsys.c| 11 + 2 files changed, 381 insertions(+) create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h new file mode 100644 index ..abfe94a30248 --- /dev/null +++ b/drivers/soc/mediatek/mt8195-mmsys.h @@ -0,0 +1,370 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_MEDIATEK_MT8195_MMSYS_H +#define __SOC_MEDIATEK_MT8195_MMSYS_H + +#define MT8195_VDO0_OVL_MOUT_EN0xf14 +#define MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0BIT(0) +#define MT8195_MOUT_DISP_OVL0_TO_DISP_WDMA0BIT(1) +#define MT8195_MOUT_DISP_OVL0_TO_DISP_OVL1 BIT(2) +#define MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1BIT(4) +#define MT8195_MOUT_DISP_OVL1_TO_DISP_WDMA1BIT(5) +#define MT8195_MOUT_DISP_OVL1_TO_DISP_OVL0 BIT(6) + +#define MT8195_VDO0_SEL_IN 0xf34 +#define MT8195_SEL_IN_VPP_MERGE_FROM_MASK GENMASK(1, 0) +#define MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT (0 << 0) +#define MT8195_SEL_IN_VPP_MERGE_FROM_DISP_DITHER1 (1 << 0) +#define MT8195_SEL_IN_VPP_MERGE_FROM_VDO1_VIRTUAL0 (2 << 0) +#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_MASK GENMASK(4, 4) +#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0 (0 << 4) +#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_VPP_MERGE (1 << 4) +#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_MASK GENMASK(5, 5) +#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_DISP_DITHER1 (0 << 5) +#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_VPP_MERGE (1 << 5) +#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_MASK GENMASK(8, 8) +#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_VPP_MERGE (0 << 8) +#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_DSC_WRAP1_OUT (1 << 8) +#define MT8195_SEL_IN_SINB_VIRTUAL0_FROM_MASK GENMASK(9, 9) +#define MT8195_SEL_IN_SINB_VIRTUAL0_FROM_DSC_WRAP0_OUT (0 << 9) +#define MT8195_SEL_IN_DP_INTF0_FROM_MASK GENMASK(13, 12) +#define MT8195_SEL_IN_DP_INTF0_FROM_DSC_WRAP1_OUT (0 << 0) +#define MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE (1 << 12) +#define MT8195_SEL_IN_DP_INTF0_FROM_VDO1_VIRTUAL0 (2 << 12) +#define MT8195_SEL_IN_DSI0_FROM_MASK GENMASK(16, 16) +#define MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT (0 << 16) +#define MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0 (1 << 16) +#define MT8195_SEL_IN_DSI1_FROM_MASK GENMASK(17, 17) +#define MT8195_SEL_IN_DSI1_FROM_DSC_WRAP1_OUT (0 << 17) +#define MT8195_SEL_IN_DSI1_FROM_VPP_MERGE (1 << 17) +#define MT8195_SEL_IN_DISP_WDMA1_FROM_MASK GENMASK(20, 20) +#define MT8195_SEL_IN_DISP_WDMA1_FROM_DISP_OVL1(0 << 20) +#define MT8195_SEL_IN_DISP_WDMA1_FROM_VPP_MERGE(1 << 20) +#define MT8195_SEL_IN_DSC_WRAP1_FROM_MASK GENMASK(21, 21) +#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DSC_WRAP1_IN (0 << 21) +#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DISP_DITHER1 (1 << 21) +#define MT8195_SEL_IN_DISP_WDMA0_FROM_MASK GENMASK(22, 22) +#define MT8195_SEL_IN_DISP_WDMA0_FROM_DISP_OVL0(0 << 22) + +#define MT8195_VDO0_SEL_OUT0xf38 +#define MT8195_SOUT_DISP_DITHER0_TO_MASK BIT(0) +#define MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN (0 << 0) +#define MT8195_SOUT_DISP_DITHER0_TO_DSI0 (1 << 0) +#define MT8195_SOUT_DISP_DITHER1_TO_MASK GENMASK(2, 1) +#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_IN (0 << 1) +#define MT8195_SOUT_DISP_DITHER1_TO_VPP_MERGE (1 << 1) +#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_OUT (2 << 1) +#define MT8195_SOUT_VDO1_VIRTUAL0_TO_MASK GENMASK(4, 4) +#define MT8195_SOUT_VDO1_VIRTUAL0_TO_VPP_MERGE (0 << 4) +#define MT8195_SOUT_VDO1_VIRTUAL0_TO_DP_INTF0 (1 << 4) +#define MT8195_SOUT_VPP_MERGE_TO_MASK GENMASK(10, 8) +#define MT8195_SOUT_VPP_MERGE_TO_DSI1 (0 << 8) +#define MT8195_SOUT_VPP_MERGE_TO_DP_INTF0 (1 << 8) +#define MT8195_SOUT_VPP_MERGE_TO_SINA_VIRTUAL0 (2 << 8) +#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA1(3 << 8) +#define
[PATCH v3 5/6] drm/mediatek: add mediatek-drm of vdosys0 support for mt8195
Add driver data of mt8195 vdosys0 to mediatek-drm and the sub driver. Signed-off-by: Jason-JH.Lin --- drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 6 + drivers/gpu/drm/mediatek/mtk_drm_drv.c | 28 2 files changed, 34 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c index 2cb90466798c..66cdd0bc1311 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c @@ -374,6 +374,10 @@ static const struct mtk_disp_rdma_data mt8192_rdma_driver_data = { .fifo_size = 5 * SZ_1K, }; +static const struct mtk_disp_rdma_data mt8195_rdma_driver_data = { + .fifo_size = 1920, +}; + static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = { { .compatible = "mediatek,mt2701-disp-rdma", .data = _rdma_driver_data}, @@ -383,6 +387,8 @@ static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = { .data = _rdma_driver_data}, { .compatible = "mediatek,mt8192-disp-rdma", .data = _rdma_driver_data}, + { .compatible = "mediatek,mt8195-disp-rdma", + .data = _rdma_driver_data}, {}, }; MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match); diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index adc9a4f4085b..9b5a7a7ddde0 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -195,6 +195,19 @@ static const enum mtk_ddp_comp_id mt8192_mtk_ddp_ext[] = { DDP_COMPONENT_DPI0, }; +static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = { + DDP_COMPONENT_OVL0, + DDP_COMPONENT_RDMA0, + DDP_COMPONENT_COLOR0, + DDP_COMPONENT_CCORR, + DDP_COMPONENT_AAL0, + DDP_COMPONENT_GAMMA, + DDP_COMPONENT_DITHER0, + DDP_COMPONENT_DSC0, + DDP_COMPONENT_MERGE0, + DDP_COMPONENT_DP_INTF0, +}; + static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = { .main_path = mt2701_mtk_ddp_main, .main_len = ARRAY_SIZE(mt2701_mtk_ddp_main), @@ -253,6 +266,11 @@ static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = { .ext_len = ARRAY_SIZE(mt8192_mtk_ddp_ext), }; +static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = { + .main_path = mt8195_mtk_ddp_main, + .main_len = ARRAY_SIZE(mt8195_mtk_ddp_main), +}; + static int mtk_drm_kms_init(struct drm_device *drm) { struct mtk_drm_private *private = drm->dev_private; @@ -470,12 +488,16 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { .data = (void *)MTK_DISP_DITHER }, { .compatible = "mediatek,mt8183-disp-dither", .data = (void *)MTK_DISP_DITHER }, + { .compatible = "mediatek,mt8195-disp-dsc", + .data = (void *)MTK_DISP_DSC }, { .compatible = "mediatek,mt8167-disp-gamma", .data = (void *)MTK_DISP_GAMMA, }, { .compatible = "mediatek,mt8173-disp-gamma", .data = (void *)MTK_DISP_GAMMA, }, { .compatible = "mediatek,mt8183-disp-gamma", .data = (void *)MTK_DISP_GAMMA, }, + { .compatible = "mediatek,mt8195-disp-merge", + .data = (void *)MTK_DISP_MERGE }, { .compatible = "mediatek,mt2701-disp-mutex", .data = (void *)MTK_DISP_MUTEX }, { .compatible = "mediatek,mt2712-disp-mutex", @@ -490,6 +512,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { .data = (void *)MTK_DISP_MUTEX }, { .compatible = "mediatek,mt8192-disp-mutex", .data = (void *)MTK_DISP_MUTEX }, + { .compatible = "mediatek,mt8195-disp-mutex", + .data = (void *)MTK_DISP_MUTEX }, { .compatible = "mediatek,mt8173-disp-od", .data = (void *)MTK_DISP_OD }, { .compatible = "mediatek,mt2701-disp-ovl", @@ -524,6 +548,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { .data = (void *)MTK_DISP_RDMA }, { .compatible = "mediatek,mt8192-disp-rdma", .data = (void *)MTK_DISP_RDMA }, + { .compatible = "mediatek,mt8195-disp-rdma", + .data = (void *)MTK_DISP_RDMA }, { .compatible = "mediatek,mt8173-disp-ufoe", .data = (void *)MTK_DISP_UFOE }, { .compatible = "mediatek,mt8173-disp-wdma", @@ -568,6 +594,8 @@ static const struct of_device_id mtk_drm_of_ids[] = { .data = _mmsys_driver_data}, { .compatible = "mediatek,mt8192-mmsys", .data = _mmsys_driver_data}, + { .compatible = "mediatek,mt8195-vdosys0", + .data = _vdosys0_driver_data}, { } }; MODULE_DEVICE_TABLE(of, mtk_drm_of_ids); -- 2.18.0
[PATCH v3 2/6] Revert "soc: mediatek: add mtk-mmsys support for mt8195 vdosys0"
This reverts commit b804923b7ccb9c9629703364e927b48cd02a9254. Due to the compatible changing of mt8195 from "mediatek,mt8195-mmsys" to "mediatek,mt8195-vdosys0", we have to revert this patch and send a new patch with the new compatible. Signed-off-by: Jason-JH.Lin --- drivers/soc/mediatek/mt8195-mmsys.h | 370 drivers/soc/mediatek/mtk-mmsys.c| 152 +--- drivers/soc/mediatek/mtk-mmsys.h| 6 - 3 files changed, 11 insertions(+), 517 deletions(-) delete mode 100644 drivers/soc/mediatek/mt8195-mmsys.h diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h deleted file mode 100644 index abfe94a30248.. --- a/drivers/soc/mediatek/mt8195-mmsys.h +++ /dev/null @@ -1,370 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef __SOC_MEDIATEK_MT8195_MMSYS_H -#define __SOC_MEDIATEK_MT8195_MMSYS_H - -#define MT8195_VDO0_OVL_MOUT_EN0xf14 -#define MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0BIT(0) -#define MT8195_MOUT_DISP_OVL0_TO_DISP_WDMA0BIT(1) -#define MT8195_MOUT_DISP_OVL0_TO_DISP_OVL1 BIT(2) -#define MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1BIT(4) -#define MT8195_MOUT_DISP_OVL1_TO_DISP_WDMA1BIT(5) -#define MT8195_MOUT_DISP_OVL1_TO_DISP_OVL0 BIT(6) - -#define MT8195_VDO0_SEL_IN 0xf34 -#define MT8195_SEL_IN_VPP_MERGE_FROM_MASK GENMASK(1, 0) -#define MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT (0 << 0) -#define MT8195_SEL_IN_VPP_MERGE_FROM_DISP_DITHER1 (1 << 0) -#define MT8195_SEL_IN_VPP_MERGE_FROM_VDO1_VIRTUAL0 (2 << 0) -#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_MASK GENMASK(4, 4) -#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0 (0 << 4) -#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_VPP_MERGE (1 << 4) -#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_MASK GENMASK(5, 5) -#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_DISP_DITHER1 (0 << 5) -#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_VPP_MERGE (1 << 5) -#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_MASK GENMASK(8, 8) -#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_VPP_MERGE (0 << 8) -#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_DSC_WRAP1_OUT (1 << 8) -#define MT8195_SEL_IN_SINB_VIRTUAL0_FROM_MASK GENMASK(9, 9) -#define MT8195_SEL_IN_SINB_VIRTUAL0_FROM_DSC_WRAP0_OUT (0 << 9) -#define MT8195_SEL_IN_DP_INTF0_FROM_MASK GENMASK(13, 12) -#define MT8195_SEL_IN_DP_INTF0_FROM_DSC_WRAP1_OUT (0 << 0) -#define MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE (1 << 12) -#define MT8195_SEL_IN_DP_INTF0_FROM_VDO1_VIRTUAL0 (2 << 12) -#define MT8195_SEL_IN_DSI0_FROM_MASK GENMASK(16, 16) -#define MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT (0 << 16) -#define MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0 (1 << 16) -#define MT8195_SEL_IN_DSI1_FROM_MASK GENMASK(17, 17) -#define MT8195_SEL_IN_DSI1_FROM_DSC_WRAP1_OUT (0 << 17) -#define MT8195_SEL_IN_DSI1_FROM_VPP_MERGE (1 << 17) -#define MT8195_SEL_IN_DISP_WDMA1_FROM_MASK GENMASK(20, 20) -#define MT8195_SEL_IN_DISP_WDMA1_FROM_DISP_OVL1(0 << 20) -#define MT8195_SEL_IN_DISP_WDMA1_FROM_VPP_MERGE(1 << 20) -#define MT8195_SEL_IN_DSC_WRAP1_FROM_MASK GENMASK(21, 21) -#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DSC_WRAP1_IN (0 << 21) -#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DISP_DITHER1 (1 << 21) -#define MT8195_SEL_IN_DISP_WDMA0_FROM_MASK GENMASK(22, 22) -#define MT8195_SEL_IN_DISP_WDMA0_FROM_DISP_OVL0(0 << 22) - -#define MT8195_VDO0_SEL_OUT0xf38 -#define MT8195_SOUT_DISP_DITHER0_TO_MASK BIT(0) -#define MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN (0 << 0) -#define MT8195_SOUT_DISP_DITHER0_TO_DSI0 (1 << 0) -#define MT8195_SOUT_DISP_DITHER1_TO_MASK GENMASK(2, 1) -#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_IN (0 << 1) -#define MT8195_SOUT_DISP_DITHER1_TO_VPP_MERGE (1 << 1) -#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_OUT (2 << 1) -#define MT8195_SOUT_VDO1_VIRTUAL0_TO_MASK GENMASK(4, 4) -#define MT8195_SOUT_VDO1_VIRTUAL0_TO_VPP_MERGE (0 << 4) -#define MT8195_SOUT_VDO1_VIRTUAL0_TO_DP_INTF0 (1 << 4) -#define MT8195_SOUT_VPP_MERGE_TO_MASK GENMASK(10, 8) -#define MT8195_SOUT_VPP_MERGE_TO_DSI1 (0 << 8) -#define MT8195_SOUT_VPP_MERGE_TO_DP_INTF0
[PATCH v3 1/6] dt-bindings: arm: mediatek: mmsys: change compatible for MT8195
For previous MediaTek SoCs, such as MT8173, there are 2 display HW pipelines binding to 1 mmsys with the same power domain, the same clock driver and the same mediatek-drm driver. For MT8195, VDOSYS0 and VDOSYS1 are 2 display HW pipelines binding to 2 different power domains, different clock drivers and different mediatek-drm drivers. Moreover, Hardware pipeline of VDOSYS0 has these components: COLOR, CCORR, AAL, GAMMA, DITHER. They are related to the PQ (Picture Quality) and they makes VDOSYS0 supports PQ function while they are not including in VDOSYS1. Hardware pipeline of VDOSYS1 has the component ETHDR (HDR related component). It makes VDOSYS1 supports the HDR function while it's not including in VDOSYS0. To summarize0: Only VDOSYS0 can support PQ adjustment. Only VDOSYS1 can support HDR adjustment. Therefore, we need to separate these two different mmsys hardwares to 2 different compatibles for MT8195. Fixes: 81c5a41d10b9 ("dt-bindings: arm: mediatek: mmsys: add mt8195 SoC binding") Signed-off-by: Jason-JH.Lin Signed-off-by: Bo-Chen Chen --- .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml | 4 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml index 6ad023eec193..df9184b6772c 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml @@ -38,6 +38,10 @@ properties: - const: mediatek,mt7623-mmsys - const: mediatek,mt2701-mmsys - const: syscon + - items: + - const: mediatek,mt8195-vdosys0 + - const: mediatek,mt8195-mmsys + - const: syscon reg: maxItems: 1 -- 2.18.0
[PATCH v3 6/6] soc: mediatek: remove DDP_DOMPONENT_DITHER from enum
After mmsys and drm change DITHER enum to DDP_COMPONENT_DITHER0, mmsys header can remove the useless DDP_COMPONENT_DITHER enum. Signed-off-by: Jason-JH.Lin Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Rex-BC Chen Acked-by: Matthias Brugger --- include/linux/soc/mediatek/mtk-mmsys.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h index d2b02bb43768..16ac0e5847f0 100644 --- a/include/linux/soc/mediatek/mtk-mmsys.h +++ b/include/linux/soc/mediatek/mtk-mmsys.h @@ -16,8 +16,7 @@ enum mtk_ddp_comp_id { DDP_COMPONENT_CCORR, DDP_COMPONENT_COLOR0, DDP_COMPONENT_COLOR1, - DDP_COMPONENT_DITHER, - DDP_COMPONENT_DITHER0 = DDP_COMPONENT_DITHER, + DDP_COMPONENT_DITHER0, DDP_COMPONENT_DITHER1, DDP_COMPONENT_DP_INTF0, DDP_COMPONENT_DP_INTF1, -- 2.18.0
[PATCH v3 0/6] Change mmsys compatible for mt8195 mediatek-drm
For previous MediaTek SoCs, such as MT8173, there are 2 display HW pipelines binding to 1 mmsys with the same power domain, the same clock driver and the same mediatek-drm driver. For MT8195, VDOSYS0 and VDOSYS1 are 2 display HW pipelines binding to 2 different power domains, different clock drivers and different mediatek-drm drivers. Moreover, Hardware pipeline of VDOSYS0 has these components: COLOR, CCORR, AAL, GAMMA, DITHER. They are related to the PQ (Picture Quality) and they makes VDOSYS0 supports PQ function while they are not including in VDOSYS1. Hardware pipeline of VDOSYS1 has the component ETHDR (HDR related component). It makes VDOSYS1 supports the HDR function while it's not including in VDOSYS0. To summarize0: Only VDOSYS0 can support PQ adjustment. Only VDOSYS1 can support HDR adjustment. Therefore, we need to separate these two different mmsys hardwares to 2 different compatibles for MT8195. --- Change in v3: 1. Keep the original compatible "mediatek,mt8195-mmsys" and add "mediatek,mt8195-vdosys0" into the same item to make the tree fallback compatible. Change in v2: 1. Remove Ack tag in the first patch 2. Change the compatible name changing patch to one revert patch and one add vdosys0 support patch. --- Jason-JH.Lin (6): dt-bindings: arm: mediatek: mmsys: change compatible for MT8195 Revert "soc: mediatek: add mtk-mmsys support for mt8195 vdosys0" soc: mediatek: add mtk-mmsys support for mt8195 vdosys0 Revert "drm/mediatek: Add mediatek-drm of vdosys0 support for mt8195" drm/mediatek: add mediatek-drm of vdosys0 support for mt8195 soc: mediatek: remove DDP_DOMPONENT_DITHER from enum .../bindings/arm/mediatek/mediatek,mmsys.yaml | 4 + drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 6 + drivers/gpu/drm/mediatek/mtk_drm_drv.c| 128 ++-- drivers/gpu/drm/mediatek/mtk_drm_drv.h| 6 - drivers/soc/mediatek/mtk-mmsys.c | 145 ++ drivers/soc/mediatek/mtk-mmsys.h | 6 - include/linux/soc/mediatek/mtk-mmsys.h| 3 +- 7 files changed, 37 insertions(+), 261 deletions(-) -- 2.18.0
[PATCH 4/5] drm/damage-helper: Do partial updates if framebuffer has not been changed
Set partial updates on a plane if the framebuffer has not been changed on an atomic commit. If such a plane has damage clips, the driver will use them; otherwise the update is effectively empty. Planes that change their framebuffer still perform a full update. This heuristic optimizes the case of setting a new framebuffer on a plane. This would trigger a full update of all other planes. With the new optimization, only the changed plane performs an update. The commit adds the flag fb_changed to struct plane_state. Besides the damage-handling code, drivers can look at the flag to determine if they need to commit a plane's framebuffer settings. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_atomic_helper.c | 3 +++ drivers/gpu/drm/drm_atomic_state_helper.c | 1 + drivers/gpu/drm/drm_damage_helper.c | 19 +++ include/drm/drm_plane.h | 6 ++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index ee5fea48b5cb..f19405fbee14 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -99,6 +99,9 @@ drm_atomic_helper_plane_changed(struct drm_atomic_state *state, crtc_state->planes_changed = true; } + + if (old_plane_state->fb != plane_state->fb) + plane_state->fb_changed = true; } static int handle_conflicting_encoders(struct drm_atomic_state *state, diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 85b13c221bd8..94818fd4dd8f 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -339,6 +339,7 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, state->commit = NULL; state->fb_damage_clips = NULL; state->fb_damage_partial_update = false; + state->fb_changed = false; } EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state); diff --git a/drivers/gpu/drm/drm_damage_helper.c b/drivers/gpu/drm/drm_damage_helper.c index a603a3563c03..f43abf02df5b 100644 --- a/drivers/gpu/drm/drm_damage_helper.c +++ b/drivers/gpu/drm/drm_damage_helper.c @@ -97,11 +97,22 @@ void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, } } - /* -* Damage clips are a good indicator for partial updates. -*/ - if (new_plane_state->fb_damage_clips) + if (new_plane_state->fb_damage_clips) { + /* +* Damage clips are a good indicator for partial updates. +*/ partial_update = true; + } else if (!new_plane_state->fb_changed) { + /* +* Also set a partial update if the framebuffer did not +* change. Without damage clips set, this will effectively +* not update the plane. The exception is with full modeset +* operations, where we do full plane update even if the +* framebuffer did not change. We already handled this case +* earlier in the function. +*/ + partial_update = true; + } out: new_plane_state->fb_damage_partial_update = partial_update; diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 3ba91349d799..8c2d0a2eb760 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -229,6 +229,12 @@ struct drm_plane_state { */ bool visible; + /** +* @fb_changed: @fb has been changed. Used by the atomic helpers and +* drivers to steer the atomic commit control flow. +*/ + bool fb_changed : 1; + /** * @scaling_filter: * -- 2.37.3
[PATCH 2/5] drm/damage-helper: Decouple partial plane updates from damage clipping
Introduce a distinct flag fb_damage_partial_update in plane state to signal the option for a partial plane update. Replaces the semantics of having no damaged areas to trigger a full update. Decoupling the existence of damage clipping from partial plane updates will allow to sometimes avoid plane updates at all. By default the new flag is cleared, which triggers a full update. We also keep doing a full update on modesetting operations or if the framebuffer has been moved within the plane. Installing damage clipping areas on a plane state sets the new flag and triggers a partial update of the given areas. Userspace that does not support damage clipping continues to work as before. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_atomic_state_helper.c | 1 + drivers/gpu/drm/drm_damage_helper.c | 68 --- include/drm/drm_plane.h | 9 +++ 3 files changed, 59 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index bf31b9d92094..85b13c221bd8 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -338,6 +338,7 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, state->fence = NULL; state->commit = NULL; state->fb_damage_clips = NULL; + state->fb_damage_partial_update = false; } EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state); diff --git a/drivers/gpu/drm/drm_damage_helper.c b/drivers/gpu/drm/drm_damage_helper.c index 4b1f26ef119f..16f0d5a97ee3 100644 --- a/drivers/gpu/drm/drm_damage_helper.c +++ b/drivers/gpu/drm/drm_damage_helper.c @@ -55,30 +55,48 @@ static void convert_clip_rect_to_rect(const struct drm_clip_rect *src, * @state: The driver state object. * @new_plane_state: Plane state for which to verify damage. * - * This helper function makes sure that damage from plane state is discarded - * for full modeset. If there are more reasons a driver would want to do a full - * plane update rather than processing individual damage regions, then those - * cases should be taken care of here. + * This helper function makes sure that damage from plane state is set up + * for full plane updates if necessary. This happens for full modesets on the + * plane's CRTC, and for pageflips without damage. If there are more reasons + * a driver would want to do a full plane update rather than processing + * individual damage regions, then those cases should be taken care of here. * - * Note that _plane_state.fb_damage_clips == NULL in plane state means that - * full plane update should happen. It also ensure helper iterator will return - * _plane_state.src as damage. + * Note that _plane_state.fb_damage_partial_update == false in plane state + * means that a full plane update should happen. It also ensures the helper + * iterator will return _plane_state.src as damage. */ void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, struct drm_plane_state *new_plane_state) { struct drm_crtc_state *new_crtc_state; + struct drm_crtc *new_crtc = new_plane_state->crtc; + bool partial_update = false; - if (new_plane_state->crtc) { - new_crtc_state = drm_atomic_get_new_crtc_state(state, new_plane_state->crtc); + if (new_crtc) { + new_crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc); if (WARN_ON(!new_crtc_state)) - return; + goto out; - if (drm_atomic_crtc_needs_modeset(new_crtc_state)) { - drm_property_blob_put(new_plane_state->fb_damage_clips); - new_plane_state->fb_damage_clips = NULL; - } + /* +* The plane's CRTC does a modeset; always do full update. +*/ + if (drm_atomic_crtc_needs_modeset(new_crtc_state)) + goto out; + } + + /* +* Damage clips are a good indicator for partial updates. +*/ + if (new_plane_state->fb_damage_clips) + partial_update = true; + +out: + new_plane_state->fb_damage_partial_update = partial_update; + + if (!new_plane_state->fb_damage_partial_update) { + drm_property_blob_put(new_plane_state->fb_damage_clips); + new_plane_state->fb_damage_clips = NULL; } } EXPORT_SYMBOL(drm_atomic_helper_check_plane_damage); @@ -224,13 +242,24 @@ drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter *iter, const struct drm_plane_state *state) { struct drm_rect src; + bool partial_update; + memset(iter, 0, sizeof(*iter)); if (!state || !state->crtc || !state->fb || !state->visible) return; - iter->clips = (struct
[PATCH 3/5] drm/damage-helper: Do partial updates on legacy cursor changes
In the case of a legacy cursor update, only update the cursor plane. Keep other planes clear from changes. Setting the 'partial_update' flag when these planes don't have damage-clipping areas acts as if no update will be performed. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_damage_helper.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/drm_damage_helper.c b/drivers/gpu/drm/drm_damage_helper.c index 16f0d5a97ee3..a603a3563c03 100644 --- a/drivers/gpu/drm/drm_damage_helper.c +++ b/drivers/gpu/drm/drm_damage_helper.c @@ -69,6 +69,7 @@ void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, struct drm_plane_state *new_plane_state) { struct drm_crtc_state *new_crtc_state; + struct drm_plane *plane = new_plane_state->plane; struct drm_crtc *new_crtc = new_plane_state->crtc; bool partial_update = false; @@ -83,6 +84,17 @@ void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, */ if (drm_atomic_crtc_needs_modeset(new_crtc_state)) goto out; + + /* +* On a legacy cursor update, only update the affected cursor +* plane, but ignore all other planes. The non-cursor planes +* won't have damage-clipping areas, so setting the flag for +* a partial update acts like not doing any update. +*/ + if (state->legacy_cursor_update) { + if (plane != new_crtc->cursor) + partial_update = true; + } } /* -- 2.37.3
[PATCH 1/5] drm/damage-helper: Style changes
Rename several variables in the damage-helper code to better reflect the use of old and new state. No functional changes. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_damage_helper.c | 19 +-- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/drm_damage_helper.c b/drivers/gpu/drm/drm_damage_helper.c index d8b2955e88fd..4b1f26ef119f 100644 --- a/drivers/gpu/drm/drm_damage_helper.c +++ b/drivers/gpu/drm/drm_damage_helper.c @@ -53,7 +53,7 @@ static void convert_clip_rect_to_rect(const struct drm_clip_rect *src, /** * drm_atomic_helper_check_plane_damage - Verify plane damage on atomic_check. * @state: The driver state object. - * @plane_state: Plane state for which to verify damage. + * @new_plane_state: Plane state for which to verify damage. * * This helper function makes sure that damage from plane state is discarded * for full modeset. If there are more reasons a driver would want to do a full @@ -65,20 +65,19 @@ static void convert_clip_rect_to_rect(const struct drm_clip_rect *src, * _plane_state.src as damage. */ void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, - struct drm_plane_state *plane_state) + struct drm_plane_state *new_plane_state) { - struct drm_crtc_state *crtc_state; + struct drm_crtc_state *new_crtc_state; - if (plane_state->crtc) { - crtc_state = drm_atomic_get_new_crtc_state(state, - plane_state->crtc); + if (new_plane_state->crtc) { + new_crtc_state = drm_atomic_get_new_crtc_state(state, new_plane_state->crtc); - if (WARN_ON(!crtc_state)) + if (WARN_ON(!new_crtc_state)) return; - if (drm_atomic_crtc_needs_modeset(crtc_state)) { - drm_property_blob_put(plane_state->fb_damage_clips); - plane_state->fb_damage_clips = NULL; + if (drm_atomic_crtc_needs_modeset(new_crtc_state)) { + drm_property_blob_put(new_plane_state->fb_damage_clips); + new_plane_state->fb_damage_clips = NULL; } } } -- 2.37.3
[PATCH 5/5] drm/damage-helper: Avoid partial updates for DIRTYFB without damage
Always do a full plane update when userspace sends a DIRTYFB ioctl without damage information. Userspace not changing the framebuffer or marking changed regions can easily be interpreted as if there was no change at all. Therefore set the new fb_dirty flag on all plane's with a dirty framebuffer and fallback to a full plane update if necessary. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_atomic_state_helper.c | 1 + drivers/gpu/drm/drm_damage_helper.c | 7 --- include/drm/drm_plane.h | 8 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 94818fd4dd8f..b7523d56b06f 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -340,6 +340,7 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, state->fb_damage_clips = NULL; state->fb_damage_partial_update = false; state->fb_changed = false; + state->fb_dirty = false; } EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state); diff --git a/drivers/gpu/drm/drm_damage_helper.c b/drivers/gpu/drm/drm_damage_helper.c index f43abf02df5b..e884987a944c 100644 --- a/drivers/gpu/drm/drm_damage_helper.c +++ b/drivers/gpu/drm/drm_damage_helper.c @@ -102,10 +102,10 @@ void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, * Damage clips are a good indicator for partial updates. */ partial_update = true; - } else if (!new_plane_state->fb_changed) { + } else if (!new_plane_state->fb_changed && !new_plane_state->fb_dirty) { /* -* Also set a partial update if the framebuffer did not -* change. Without damage clips set, this will effectively +* Also set a partial update if the framebuffer or its content +* did not change. Without damage clips set, this will effectively * not update the plane. The exception is with full modeset * operations, where we do full plane update even if the * framebuffer did not change. We already handled this case @@ -214,6 +214,7 @@ int drm_atomic_helper_dirtyfb(struct drm_framebuffer *fb, goto out; } + plane_state->fb_dirty = true; drm_property_replace_blob(_state->fb_damage_clips, damage); } diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 8c2d0a2eb760..2b22707eb116 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -235,6 +235,14 @@ struct drm_plane_state { */ bool fb_changed : 1; + /** +* @fb_dirty: @fb's content has been marked as dirty. Used by the +* atomic helpers and drivers to steer the atomic commit control flow. +* The flag signals that the frambuffer's content has been changed even +* if no damage clips have been installed. +*/ + bool fb_dirty : 1; + /** * @scaling_filter: * -- 2.37.3
[PATCH 0/5] drm/damage-helper: Improve damage-clipping heuristics
DRM Drivers can minimize a plane update by looking at damage clipping information provided by userspace. So far, not having damage information starts a full-plane update. Improve the heuristics for detecting partial and full-plane updates by looking at the various state variables of a plane update. The current scheme of interpreting 'no damage information' as 'do full update' works for hardware with a single primary plane. For hardware with multiple planes, missing damage information can generate significant overhead. For example, ast supports a primary plane and a cursor plane. DRM performs an atomic update when the cursor plane is being updated in some way (e.g., moved). The lack of damage information on the primary plane results in a full-plane update of the primary plane as well. Using shadow planes that need to be memcpy'd to video memory creates a full redraw of the entire primary plane whenever the user moves the mouse cursor. The patchset improves the current heuristics by looking at various state variables to detect whether a full update is necessary. Patch #2 decouples full-plane updates from the (non-)existence of damage information. Full-plane updates are still the default, but the dedicated flag in the plane state allows for more fine-grained control. Patches #3 to #5 enable partial plane updates on various conditions. The patchset has been tested by converting ast to SHMEM and running Gnome on X11, Gnome in Wayland mode, and Weston. The new heuristics reduce each environment's unnecessary updates of the primary plane to no-ops: DRM still invokes the primary plane's atomic_update, but the costly memcpy to video memory is being avoided. Thomas Zimmermann (5): drm/damage-helper: Style changes drm/damage-helper: Decouple partial plane updates from damage clipping drm/damage-helper: Do partial updates on legacy cursor changes drm/damage-helper: Do partial updates if framebuffer has not been changed drm/damage-helper: Avoid partial updates for DIRTYFB without damage drivers/gpu/drm/drm_atomic_helper.c | 3 + drivers/gpu/drm/drm_atomic_state_helper.c | 3 + drivers/gpu/drm/drm_damage_helper.c | 99 +-- include/drm/drm_plane.h | 23 ++ 4 files changed, 105 insertions(+), 23 deletions(-) base-commit: d8deedaa0fcd8192715a052a0239bee3f74a8fb1 -- 2.37.3
Re: [PATCH] drm/panfrost: Give name to anonymous coredump object union
On 19/09/2022 07:44, Adrián Larumbe wrote: > Hi Steven, > > On 13.09.2022 09:45, Steven Price wrote: >> On 12/09/2022 17:44, Adrián Larumbe wrote: >>> Building Mesa's Perfetto requires including the panfrost drm uAPI header in >>> C++ code, but the C++ compiler requires anonymous unions to have only >>> public non-static data members. >>> >>> Commit 730c2bf4ad39 ("drm/panfrost: Add support for devcoredump") >>> introduces one such union, breaking the Mesa build. >>> >>> Give it a name, and also rename pan_reg_hdr structure because it will >>> always be prefixed by the union name. >>> >>> Bug: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7195 >>> >>> Signed-off-by: Adrián Larumbe > >> Ouch! It's frustrating how C++ isn't quite a superset of C. However I >> think we can solve this with a simpler patch, I'd appreciate testing >> that this does indeed fix the build issues with Mesa with all supported >> compilers (I'm not so familiar with C++): > > I just tested your changes on Mesa and they do fix the build. Thanks Adrián! Alyssa: Could you give your R-b if you're happy with this change? It would be good to get this fixed before it hits -rc1. Thanks, Steve > >> 8< >>From 492714a7dff0710ac5b8b457bcfe9ae52b458565 Mon Sep 17 00:00:00 2001 >> From: Steven Price >> Date: Tue, 13 Sep 2022 09:37:55 +0100 >> Subject: [PATCH] drm/panfrost: Remove type name from internal structs >> >> The two structs internal to struct panfrost_dump_object_header were >> named, but sadly that is incompatible with C++, causing an error: "an >> anonymous union may only have public non-static data members". >> >> However nothing refers to struct pan_reg_hdr and struct pan_bomap_hdr >> and there's no need to export these definitions, so lets drop them. This >> fixes the C++ build error with the minimum change in userspace API. >> >> Bug: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7195 >> Fixes: 730c2bf4ad39 ("drm/panfrost: Add support for devcoredump") >> Signed-off-by: Steven Price >> --- >> include/uapi/drm/panfrost_drm.h | 4 ++-- >> 1 file changed, 2 insertions(+), 2 deletions(-) >> >> diff --git a/include/uapi/drm/panfrost_drm.h >> b/include/uapi/drm/panfrost_drm.h >> index eac87310b348..bd77254be121 100644 >> --- a/include/uapi/drm/panfrost_drm.h >> +++ b/include/uapi/drm/panfrost_drm.h >> @@ -242,7 +242,7 @@ struct panfrost_dump_object_header { >> __le32 file_offset; >> >> union { >> -struct pan_reg_hdr { >> +struct { >> __le64 jc; >> __le32 gpu_id; >> __le32 major; >> @@ -250,7 +250,7 @@ struct panfrost_dump_object_header { >> __le64 nbos; >> } reghdr; >> >> -struct pan_bomap_hdr { >> +struct { >> __le32 valid; >> __le64 iova; >> __le32 data[2]; >> -- >> 2.34.1
Re: [PATCH] drm/amdgpu: initialize r variable into amdgpu_cs_submit function
Am 20.09.22 um 14:32 schrieb Tommaso Merciai: Hi Christian, On Tue, Sep 20, 2022 at 02:23:58PM +0200, Christian König wrote: Am 20.09.22 um 14:22 schrieb Tommaso Merciai: The builds of arm64 allmodconfig with clang failed to build next-20220920 with the following result: 1190:3: error: variable 'r' is uninitialized when used here [-Werror,-Wuninitialized] note: initialize the variable 'r' to silence this warning This fix compilation error I've already send a patch to fix this to the mailing list 7 Minutes ago :) Please review or ack that one. Sorry, my bad. Don't see your patch :) No problem, already reviewed and pushed :) It probably takes a moment for the mailing list to deliver the patch to everybody. Cheers, Christian. Cheers, Tommaso Thanks, Christian. Signed-off-by: Tommaso Merciai --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 58088c663125..efa3dc9b69fd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -1168,7 +1168,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, struct amdgpu_bo_list_entry *e; struct amdgpu_job *job; uint64_t seq; - int r; + int r = 0; job = p->job; p->job = NULL;